Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: SPIRAM_23LC1024_FIFO
Revision 1:5a261b6a88af, committed 2013-03-08
- Comitter:
- okini3939
- Date:
- Fri Mar 08 14:00:38 2013 +0000
- Parent:
- 0:69ea2af1d9af
- Commit message:
- add CircBuffer
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/CBuffer_SRAM.cpp Fri Mar 08 14:00:38 2013 +0000
@@ -0,0 +1,124 @@
+/* Copyright (C) 2012 mbed.org, MIT License
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+ * and associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * Modified by 2013 Hiroshi Suga, MIT License
+ */
+
+#include "CBuffer_SRAM.h"
+
+#define DBG(...)
+//#define DBG(...) printf("" __VA_ARGS__)
+
+CircBuffer::CircBuffer(int length) {
+ _ram = SerRAM::getInstance();
+ write = 0;
+ read = 0;
+ ram_addr = xalloc(length + 1);
+ size = length + 1;
+};
+
+int CircBuffer::xalloc(int n) {
+ static uint32_t ram_alloc = 0;
+ uint32_t a;
+
+ a = ram_alloc;
+ ram_alloc += (n + WINDOW_SIZE - 1) & ~WINDOW_MASK;
+ DBG("alloc %x ,next %x\r\n", a, ram_alloc);
+ return a;
+}
+
+bool CircBuffer::isFull() {
+ return (((write + 1) % size) == read);
+};
+
+bool CircBuffer::isEmpty() {
+ return (read == write);
+};
+
+bool CircBuffer::queue(char k) {
+ if (isFull()) {
+ return false;
+ }
+#ifdef RAM_USE_DMA
+ while (_ram->isBusy()) DBG("busy\r\n");
+#endif
+ uint32_t w = write;
+ buf_w[w & WINDOW_MASK] = k;
+ w = (w + 1) % size;
+ if ((w & WINDOW_MASK) == 0) {
+ _ram->write(ram_addr + (write & ~WINDOW_MASK), buf_w, WINDOW_SIZE, true);
+ DBG("(W %x)\r\n", ram_addr + (write & ~WINDOW_MASK));
+ if ((write & ~WINDOW_MASK) == (read & ~WINDOW_MASK)) {
+ // w = r
+ memcpy(buf_r, buf_w, WINDOW_SIZE);
+ DBG("memcpy\r\n");
+ }
+ }
+ write = w;
+ return true;
+}
+
+void CircBuffer::flush() {
+ _ram->write(ram_addr + (write & ~WINDOW_MASK), buf_w, WINDOW_SIZE, true);
+ read = 0;
+ write = 0;
+}
+
+uint32_t CircBuffer::available() {
+ return (write >= read) ? write - read : size - read + write;
+};
+
+uint32_t CircBuffer::use() {
+ return size - available() - 1;
+};
+
+bool CircBuffer::dequeue(char * c) {
+ bool empty = isEmpty();
+ if (!empty) {
+#ifdef RAM_USE_DMA
+ while (_ram->isBusy()) DBG("busy\r\n");
+#endif
+ uint32_t w = write, r = read;
+ if ((w & ~WINDOW_MASK) == (r & ~WINDOW_MASK) && w > r) {
+ *c = buf_w[r & WINDOW_MASK];
+ } else {
+ *c = buf_r[r & WINDOW_MASK];
+ }
+ r = (r + 1) % size;
+ if ((r & WINDOW_MASK) == 0) {
+ _ram->read(ram_addr + (r & ~WINDOW_MASK), buf_r, WINDOW_SIZE, true);
+ DBG("(R %x)\r\n", (r & ~WINDOW_MASK));
+ }
+ read = r;
+ }
+ return (!empty);
+};
+
+void CircBuffer::dump() {
+ int i;
+ printf("buf_w\r\n");
+ for (i = 0; i < WINDOW_SIZE; i ++) {
+ printf(" %02x", buf_w[i]);
+ if ((i & 0x0f) == 0x0f) printf("\r\n");
+ }
+ printf("buf_r\r\n");
+ for (i = 0; i < WINDOW_SIZE; i ++) {
+ printf(" %02x", buf_r[i]);
+ if ((i & 0x0f) == 0x0f) printf("\r\n");
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/CBuffer_SRAM.h Fri Mar 08 14:00:38 2013 +0000
@@ -0,0 +1,65 @@
+/* Copyright (C) 2012 mbed.org, MIT License
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+ * and associated documentation files (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all copies or
+ * substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+/*
+ * Modified by 2013 Hiroshi Suga, MIT License
+ */
+
+#ifndef CIRCBUFFER_H_
+#define CIRCBUFFER_H_
+
+#define WINDOW_SIZE 64
+#define WINDOW_MASK 0x3f
+
+#include "SerRAM.h"
+
+class CircBuffer {
+public:
+ CircBuffer(int length);
+
+ bool isFull();
+
+ bool isEmpty();
+
+ bool queue(char k);
+
+ void flush();
+
+
+ uint32_t available();
+
+ uint32_t use();
+
+ bool dequeue(char * c);
+
+ void dump();
+
+private:
+ volatile uint32_t write;
+ volatile uint32_t read;
+ uint32_t size;
+ char buf_w[WINDOW_SIZE];
+ char buf_r[WINDOW_SIZE];
+
+ SerRAM * _ram;
+ uint32_t ram_addr;
+ uint32_t ram_w, ram_r;
+
+ static int xalloc(int size);
+};
+
+#endif
--- 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
--- a/SerRAM.h Mon Jan 07 14:30:06 2013 +0000
+++ b/SerRAM.h Fri Mar 08 14:00:38 2013 +0000
@@ -8,20 +8,17 @@
* @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/
*/
#ifndef __SerRAM_h__
#define __SerRAM_h__
#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
-//#define RAM_USE_DMA
+#define RAM_USE_DMA
#define RAM_DMA_SIZE 64
#endif
-#define RAM_USE_FIFO
-#define RAM_FIFO_NUM 20
-
#include "mbed.h"
#ifdef RAM_USE_DMA
@@ -53,7 +50,7 @@
* @param async block (DMA)
* @return >=0:success, -1:failure
*/
- int write (int addr, char *buf, int len, int async = 0);
+ int write (int addr, char *buf, int len, bool async = false);
/**
* @param addr address
* @return data
@@ -66,20 +63,19 @@
* @param async block (DMA)
* @return 0:success, -1:failure
*/
- int read (int addr, char *buf, int len, int async = 0);
+ int read (int addr, char *buf, int len, bool async = false);
int setStatus (int status);
int getStatus ();
-#ifdef RAM_USE_FIFO
- int fifoAlloc (int size);
- int fifoPut (int n, char dat);
- int fifoPut (int n, char *buf, int len);
- int fifoGet (int n, char *dat);
- int fifoGet (int n, char *buf, int len);
- int fifoAvailable (int n);
- int fifoUse (int n);
- void fifoClear (int n);
+ static SerRAM * getInstance() {
+ return _inst;
+ };
+
+#ifdef RAM_USE_DMA
+ bool isBusy () {
+ return dmabusy;
+ };
#endif
private:
@@ -87,29 +83,18 @@
DigitalOut _cs;
int _size;
int _alloc;
+ static SerRAM * _inst;
#ifdef RAM_USE_DMA
void tc0_callback ();
void tc1_callback ();
void err_callback ();
- __IO uint32_t *ssp_dmacr;
+ LPC_SSP_TypeDef *_ssp;
MODDMA dma;
MODDMA_Config *dmacfg0, *dmacfg1;
MODDMA::GPDMA_CONNECTION dmacon0, dmacon1;
- volatile int dmaexit;
-#endif
-
-#ifdef RAM_USE_FIFO
- int fifo_num;
- struct {
- char *buf_w, *buf_r;
- int size;
- int addr_w, addr_r;
- int addr2_w, addr2_r;
- int ram;
- int ram_w, ram_r;
- } fifo[RAM_FIFO_NUM];
+ volatile bool dmabusy;
#endif
};