Serial RAM (SPI SRAM) library 23K256, 23LC1024 (Microchip) see: http://mbed.org/users/okini3939/notebook/extend-memory/
Dependents: SPIRAM_23LC1024_FIFO
Diff: SerRAM.cpp
- Revision:
- 1:5a261b6a88af
- Parent:
- 0:69ea2af1d9af
--- a/SerRAM.cpp Mon Jan 07 14:30:06 2013 +0000 +++ b/SerRAM.cpp Fri Mar 08 14:00:38 2013 +0000 @@ -8,7 +8,7 @@ * @brief Serial RAM (SPI SRAM) library * 23K256, 23LC1024 (Microchip) * support FIFO - * support DMA http://mbed.org/users/AjK/code/MODDMA/ + * support DMA need http://mbed.org/users/AjK/code/MODDMA/ */ #include "mbed.h" @@ -25,20 +25,22 @@ #define MODE_BYTE 0x00 #define MODE_SEQ 0x40 +SerRAM * SerRAM::_inst; SerRAM::SerRAM (SPI& spi, PinName cs, int size) : _spi(spi), _cs(cs) { _spi.frequency(16000000); _cs = 1; _size = size; _alloc = 0; + _inst = this; #ifdef RAM_USE_DMA dmacfg0 = new MODDMA_Config; dmacfg1 = new MODDMA_Config; - ssp_dmacr = &LPC_SSP1->DMACR; + _ssp = LPC_SSP1; // ??? dmacon0 = MODDMA::SSP1_Tx; dmacon1 = MODDMA::SSP1_Rx; - dmaexit = 1; + dmabusy = false; #endif #ifdef RAM_USE_FIFO @@ -51,21 +53,22 @@ _cs = 1; _size = size; _alloc = 0; + _inst = this; #ifdef RAM_USE_DMA dmacfg0 = new MODDMA_Config; dmacfg1 = new MODDMA_Config; if (mosi == p5) { - ssp_dmacr = &LPC_SSP1->DMACR; + _ssp = LPC_SSP1; dmacon0 = MODDMA::SSP1_Tx; dmacon1 = MODDMA::SSP1_Rx; } else if (mosi == p11) { - ssp_dmacr = &LPC_SSP0->DMACR; + _ssp = LPC_SSP0; dmacon0 = MODDMA::SSP0_Tx; dmacon1 = MODDMA::SSP0_Rx; } - dmaexit = 1; + dmabusy = false; #endif #ifdef RAM_USE_FIFO @@ -75,6 +78,9 @@ int SerRAM::write (int addr, int dat) { +#ifdef RAM_USE_DMA + while (dmabusy); +#endif _cs = 0; _spi.write(CMD_WRITE); if (_size > 512) { @@ -87,15 +93,15 @@ return 0; } -int SerRAM::write (int addr, char *buf, int len, int async) { +int SerRAM::write (int addr, char *buf, int len, bool async) { int i; #ifdef RAM_USE_DMA static char dummy[RAM_DMA_SIZE]; #endif - DBG("DMA write %04x %d\r\n", addr, len); + DBG("write %04x %d\r\n", addr, len); #ifdef RAM_USE_DMA - while (! dmaexit); + while (dmabusy); #endif _cs = 0; _spi.write(CMD_WRITE); @@ -130,10 +136,10 @@ ->attach_err ( this, &SerRAM::err_callback ) ; // config end - dmaexit = 0; + dmabusy = true; if (dma.Setup( dmacfg0 ) && dma.Setup( dmacfg1 )) { DBG("DMA setup\r\n"); - *ssp_dmacr = (1<<1)|(1<<0); // TX,RXDMAE + _ssp->DMACR = (1<<1)|(1<<0); // TX,RXDMAE dma.Enable( dmacfg0 ); dma.Enable( dmacfg1 ); DBG("DMA enable\r\n"); @@ -143,8 +149,8 @@ i = -1; } - if (async == 0) { - while (! dmaexit); + if (async == false) { + while (dmabusy); DBG("DMA done\r\n"); } #else @@ -159,6 +165,9 @@ int SerRAM::read (int addr) { int dat; +#ifdef RAM_USE_DMA + while (dmabusy); +#endif _cs = 0; _spi.write(CMD_READ); if (_size > 512) { @@ -171,12 +180,12 @@ return dat; } -int SerRAM::read (int addr, char *buf, int len, int async) { +int SerRAM::read (int addr, char *buf, int len, bool async) { int i; - DBG("DMA read %04x %d\r\n", addr, len); + DBG("read %04x %d\r\n", addr, len); #ifdef RAM_USE_DMA - while (! dmaexit); + while (dmabusy); #endif _cs = 0; _spi.write(CMD_READ); @@ -209,9 +218,9 @@ ->attach_err ( this, &SerRAM::err_callback ) ; // config end - dmaexit = 0; + dmabusy = true; if (dma.Setup( dmacfg0 ) && dma.Setup( dmacfg1 )) { - *ssp_dmacr = (1<<1)|(1<<0); // TX,RXDMAE + _ssp->DMACR = (1<<1)|(1<<0); // TX,RXDMAE dma.Enable( dmacfg0 ); dma.Enable( dmacfg1 ); i = 0; @@ -220,8 +229,8 @@ i = -1; } - if (async == 0) { - while (! dmaexit); + if (async == false) { + while (dmabusy); } #else for (i = 0; i < len; i ++) { @@ -234,6 +243,9 @@ int SerRAM::setStatus (int status) { +#ifdef RAM_USE_DMA + while (dmabusy); +#endif _cs = 0; _spi.write(CMD_WRMR); _spi.write(status); @@ -244,6 +256,9 @@ int SerRAM::getStatus () { int r; +#ifdef RAM_USE_DMA + while (dmabusy); +#endif _cs = 0; _spi.write(CMD_RDMR); r = _spi.write(0); @@ -265,167 +280,22 @@ void SerRAM::tc1_callback () { - dmaexit = 1; + dmabusy = false; _cs = 1; - *ssp_dmacr = 0; + _ssp->DMACR = 0; MODDMA_Config *config = dma.getConfig(); dma.Disable( (MODDMA::CHANNELS)config->channelNum() ); // Clear DMA IRQ flags. - if (dma.irqType() == MODDMA::TcIrq) dma.clearTcIrq(); - if (dma.irqType() == MODDMA::ErrIrq) dma.clearErrIrq(); + if (dma.irqType() == MODDMA::TcIrq) dma.clearTcIrq(); + if (dma.irqType() == MODDMA::ErrIrq) dma.clearErrIrq(); DBG("tc1_callback\r\n"); } void SerRAM::err_callback () { - dmaexit = -1; + dmabusy = false; _cs = 1; DBG("err_callback\r\n"); } #endif - -#ifdef RAM_USE_FIFO -int SerRAM::fifoAlloc (int size) { - int n, s; - - s = ((size + 1) / RAM_DMA_SIZE + 1) * RAM_DMA_SIZE; - if (fifo_num >= RAM_FIFO_NUM || (_size * 1024 - _alloc) < s) return -1; - - n = fifo_num; - fifo[n].size = size + 1; - fifo[n].buf_w = new char[RAM_DMA_SIZE]; - fifo[n].buf_r = new char[RAM_DMA_SIZE]; - fifo[n].ram = _alloc; - fifoClear(n); - - fifo_num ++; - _alloc += s; - DBG("alloc %d + %d (%d)\r\n", fifo[n].ram, fifo[n].size, _alloc); - return n; -} - -int SerRAM::fifoPut (int n, char dat) { - int next, next2; - - next = fifo[n].addr_w + 1; - next2 = fifo[n].addr2_w + 1; - if (next >= fifo[n].size) { - // last of fifo - next = 0; - next2 = 0; - } - if (next2 >= RAM_DMA_SIZE) { - // last of buffer - next2 = 0; - } - - if (next == fifo[n].addr_r) { - // no data - return -1; - } -#ifdef RAM_USE_DMA - while (! dmaexit); // busy DMA -#endif - fifo[n].buf_w[fifo[n].addr2_w] = dat; - - if (next2 == 0) { - // ring - write(fifo[n].ram + fifo[n].ram_w, fifo[n].buf_w, RAM_DMA_SIZE, 1); - if (fifo[n].ram_w == fifo[n].ram_r) { - // w = r - memcpy(fifo[n].buf_r, fifo[n].buf_w, RAM_DMA_SIZE); - } - - fifo[n].ram_w += RAM_DMA_SIZE; - if (next == 0) { - fifo[n].ram_w = 0; - } - } - fifo[n].addr_w = next; - fifo[n].addr2_w = next2; - return 0; -} - -int SerRAM::fifoPut (int n, char *buf, int len) { - int i; - - for (i = 0; i < len; i ++) { - if (fifoPut(n, buf[i])) return -1; - } - return 0; -} - -int SerRAM::fifoGet (int n, char *dat) { - - if (fifo[n].addr_r == fifo[n].addr_w) { - // no data - return -1; - } -#ifdef RAM_USE_DMA - while (! dmaexit); // busy DMA -#endif - if (fifo[n].ram_r != fifo[n].ram_w) { - *dat = fifo[n].buf_r[fifo[n].addr2_r]; - } else - if (fifo[n].addr_w < fifo[n].addr_r) { - *dat = fifo[n].buf_r[fifo[n].addr2_r]; - } else { - // w = r and w > r - *dat = fifo[n].buf_w[fifo[n].addr2_r]; - } - - fifo[n].addr_r += 1; - fifo[n].addr2_r += 1; - if (fifo[n].addr_r >= fifo[n].size) { - // last of fifo - fifo[n].addr_r = 0; - fifo[n].addr2_r = 0; - } - if (fifo[n].addr2_r >= RAM_DMA_SIZE) { - // last of buffer - fifo[n].addr2_r = 0; - } - if (fifo[n].addr2_r == 0) { - // ring - fifo[n].ram_r += RAM_DMA_SIZE; - if (fifo[n].addr_r == 0) { - fifo[n].ram_r = 0; - } - read(fifo[n].ram + fifo[n].ram_r, fifo[n].buf_r, RAM_DMA_SIZE); - } - return 0; -} - -int SerRAM::fifoGet (int n, char *buf, int len) { - int i; - - for (i = 0; i < len; i ++) { - if (fifoGet(n, &buf[i])) return -1; - } - return 0; -} - -int SerRAM::fifoAvailable (int n) { - if (fifo[n].addr_w < fifo[n].addr_r) { - return fifo[n].addr_r - fifo[n].addr_w - 1; - } else { - return (fifo[n].size - fifo[n].addr_w) + fifo[n].addr_r - 1; - } -} - -int SerRAM::fifoUse (int n) { - return fifo[n].size - fifoAvailable(n) - 1; -} - -void SerRAM::fifoClear (int n) { - fifo[n].addr_w = 0; - fifo[n].addr_r = 0; - fifo[n].addr2_w = 0; - fifo[n].addr2_r = 0; - fifo[n].ram_w = 0; - fifo[n].ram_r = 0; - - read(fifo[n].ram + fifo[n].ram_r, fifo[n].buf_r, RAM_DMA_SIZE); -} -#endif