Serial RAM (SPI SRAM) library 23K256, 23LC1024 (Microchip) see: http://mbed.org/users/okini3939/notebook/extend-memory/

Dependents:   SPIRAM_23LC1024_FIFO

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