/* PSRAM driver for IPS6404 */ #include "psram_t.h" #include #include #define SPI SPI2 //#define SPICLOCK 104000000 #define SPICLOCK 70000000 //#define SPICLOCK 144e6 //Just a number..max speed #define SPI_MODE SPI_MODE0 #define RAM_READ 0xB //#define RAM_READ 0x3 #define RAM_WRITE 0x2 uint8_t PSRAM_T::_cs, PSRAM_T::_miso, PSRAM_T::_mosi, PSRAM_T::_sclk; Page PSRAM_T::pages[MAX_PAGES]; uint8_t PSRAM_T::nbPages=0; int8_t PSRAM_T::top=0; int8_t PSRAM_T::last=0; PSRAM_T::PSRAM_T(uint8_t cs, uint8_t mosi, uint8_t sclk, uint8_t miso) { _cs = cs; _mosi = mosi; _sclk = sclk; _miso = miso; pinMode(_cs, OUTPUT); digitalWrite(_cs, 1); } void PSRAM_T::begin(void) { SPI.setMOSI(_mosi); SPI.setMISO(_miso); SPI.setSCK(_sclk); SPI.begin(); delay(1); digitalWrite(_cs, 0); SPI.beginTransaction(SPISettings(SPICLOCK, MSBFIRST, SPI_MODE)); SPI.transfer(0x66); digitalWrite(_cs, 1); SPI.endTransaction(); SPI.beginTransaction(SPISettings(SPICLOCK, MSBFIRST, SPI_MODE)); digitalWrite(_cs, 0); SPI.transfer(0x99); SPI.endTransaction(); digitalWrite(_cs, 1); delayMicroseconds(20); } uint8_t PSRAM_T::psram_read(uint32_t addr) { uint8_t val=0; digitalWrite(_cs, 0); SPI.beginTransaction(SPISettings(SPICLOCK, MSBFIRST, SPI_MODE)); SPI.transfer(RAM_READ); SPI.transfer((addr>>16)&0xff); SPI.transfer((addr>>8)&0xff); SPI.transfer(addr&0xff); #if RAM_READ == 0xB SPI.transfer(0xFF); #endif val = SPI.transfer(0xFF); SPI.endTransaction(); digitalWrite(_cs, 1); return val; } void PSRAM_T::psram_read_n(uint32_t addr, uint8_t * val, int n) { digitalWrite(_cs, 0); SPI.beginTransaction(SPISettings(SPICLOCK, MSBFIRST, SPI_MODE)); SPI.transfer(RAM_READ); SPI.transfer((addr>>16)&0xff); SPI.transfer((addr>>8)&0xff); SPI.transfer(addr&0xff); #if RAM_READ == 0xB SPI.transfer(0xFF); #endif /* while (n > 0) { *val++ = SPI.transfer(0xFF); n--; } */ SPI.transfer(val,n); SPI.endTransaction(); digitalWrite(_cs, 1); } void PSRAM_T::psram_write(uint32_t addr, uint8_t val) { digitalWrite(_cs, 0); SPI.beginTransaction(SPISettings(SPICLOCK, MSBFIRST, SPI_MODE)); SPI.transfer(RAM_WRITE); SPI.transfer((addr>>16)&0xff); SPI.transfer((addr>>8)&0xff); SPI.transfer(addr&0xff); SPI.transfer(val); SPI.endTransaction(); digitalWrite(_cs, 1); } static uint8_t resp[PAGE_SIZE]; void PSRAM_T::psram_write_n(uint32_t addr, uint8_t * val, int n) { digitalWrite(_cs, 0); SPI.beginTransaction(SPISettings(SPICLOCK, MSBFIRST, SPI_MODE)); SPI.transfer(RAM_WRITE); SPI.transfer((addr>>16)&0xff); SPI.transfer((addr>>8)&0xff); SPI.transfer(addr&0xff); /* while (n > 0) { SPI.transfer(*val++); n--; } */ SPI.transfer(val,&resp[0],n); SPI.endTransaction(); digitalWrite(_cs, 1); } #ifdef DMATRY #include DMAMEM static uint8_t src[PAGE_SIZE+4]; DMAMEM static uint8_t dst[PAGE_SIZE+4]; static DMASetting dmasettings[8]; static DMAChannel dmatx; static volatile uint8_t rstop = 0; #define DMASPI_PRINT(x) do {Serial.printf(x) ; Serial.flush();} while (0); static void dmaInterrupt() { dmatx.clearInterrupt(); rstop = 1; //DMASPI_PRINT("irq"); } void PSRAM_T::psram_write_n_dma(uint32_t addr, uint8_t * val, int n) { uint8_t * dstPt = &dst[0]; //*dstPt++ = RAM_WRITE; //*dstPt++ = (addr>>16)&0xff; //*dstPt++ = (addr>>8)&0xff; //*dstPt++ = addr&0xff; int cnt = n; while (cnt > 0) { *dstPt++ = *val++; cnt--; } arm_dcache_flush(&dst[0], n); rstop = 0; dmatx.disable(); dmatx.attachInterrupt(dmaInterrupt); dmasettings[0].sourceBuffer(&dst[0], n); //dmasettings[0].destination((uint8_t &) LPSPI4_TDR); dmasettings[0].destination((uint8_t &) IMXRT_LPSPI1_S.TDR); dmasettings[0].TCD->ATTR_DST = 1; dmasettings[0].interruptAtCompletion(); Serial.printf("A") ; Serial.flush(); digitalWrite(_cs, HIGH); // SPI.begin(); SPI.beginTransaction(SPISettings(SPICLOCK, MSBFIRST, SPI_MODE)); digitalWrite(_cs, 0); SPI.transfer(RAM_WRITE); SPI.transfer((addr>>16)&0xff); SPI.transfer((addr>>8)&0xff); SPI.transfer(addr&0xff); //SPI.transfer(0); //SPI.transfer(1); Serial.printf("B") ; Serial.flush(); #ifdef XXX LPSPI4_CR &= ~LPSPI_CR_MEN;//disable LPSPI: LPSPI4_CFGR1 |= LPSPI_CFGR1_NOSTALL; //prevent stall from RX //LPSPI4_TCR = 15; // Framesize 16 Bits IMXRT_LPSPI4_S.TCR = (IMXRT_LPSPI4_S.TCR & ~(LPSPI_TCR_FRAMESZ(31))) | LPSPI_TCR_FRAMESZ(7); LPSPI4_DER = LPSPI_DER_TDDE; //TX DMA Request Enable // IMXRT_LPSPI4_S.DER = LPSPI_DER_TDDE; // | LPSPI_DER_RDDE; //enable DMA on both TX and RX LPSPI4_CR |= LPSPI_CR_MEN; //enable LPSPI: //IMXRT_LPSPI4_S.TCR = (IMXRT_LPSPI4_S.TCR & ~(LPSPI_TCR_FRAMESZ(31))) | LPSPI_TCR_FRAMESZ(7); // IMXRT_LPSPI4_S.FCR = 0; // Lets try to output the first byte to make sure that we are in 8 bit mode... // IMXRT_LPSPI4_S.SR = 0x3f00; // clear out all of the other status... dmatx.triggerAtHardwareEvent( DMAMUX_SOURCE_LPSPI4_TX ); #endif IMXRT_LPSPI1_S.CR &= ~LPSPI_CR_MEN;//disable LPSPI: IMXRT_LPSPI1_S.CFGR1 |= LPSPI_CFGR1_NOSTALL; //prevent stall from RX IMXRT_LPSPI1_S.TCR = (IMXRT_LPSPI4_S.TCR & ~(LPSPI_TCR_FRAMESZ(31))) | LPSPI_TCR_FRAMESZ(7); IMXRT_LPSPI1_S.DER = LPSPI_DER_TDDE; //TX DMA Request Enable IMXRT_LPSPI1_S.CR |= LPSPI_CR_MEN; //enable LPSPI: dmatx.triggerAtHardwareEvent( DMAMUX_SOURCE_LPSPI1_TX ); Serial.printf("C") ; Serial.flush(); // SPI.initDMAChannels(); dmatx = dmasettings[0]; dmatx.enable(); Serial.printf("D") ; Serial.flush(); while (rstop == 0) {}; Serial.printf("E") ; Serial.flush(); digitalWrite(_cs, 1); } #endif void PSRAM_T::pswrite(uint32_t addr, uint8_t val) { psram_write(addr, val); //return; uint32_t curPage=addr&(~(PAGE_SIZE-1)); for (int i=0; i