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

Dependents:   SPIRAM_23LC1024_FIFO

Committer:
okini3939
Date:
Fri Mar 08 14:00:38 2013 +0000
Revision:
1:5a261b6a88af
add CircBuffer

Who changed what in which revision?

UserRevisionLine numberNew contents of line
okini3939 1:5a261b6a88af 1 /* Copyright (C) 2012 mbed.org, MIT License
okini3939 1:5a261b6a88af 2 *
okini3939 1:5a261b6a88af 3 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
okini3939 1:5a261b6a88af 4 * and associated documentation files (the "Software"), to deal in the Software without restriction,
okini3939 1:5a261b6a88af 5 * including without limitation the rights to use, copy, modify, merge, publish, distribute,
okini3939 1:5a261b6a88af 6 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
okini3939 1:5a261b6a88af 7 * furnished to do so, subject to the following conditions:
okini3939 1:5a261b6a88af 8 *
okini3939 1:5a261b6a88af 9 * The above copyright notice and this permission notice shall be included in all copies or
okini3939 1:5a261b6a88af 10 * substantial portions of the Software.
okini3939 1:5a261b6a88af 11 *
okini3939 1:5a261b6a88af 12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
okini3939 1:5a261b6a88af 13 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
okini3939 1:5a261b6a88af 14 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
okini3939 1:5a261b6a88af 15 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
okini3939 1:5a261b6a88af 16 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
okini3939 1:5a261b6a88af 17 */
okini3939 1:5a261b6a88af 18 /*
okini3939 1:5a261b6a88af 19 * Modified by 2013 Hiroshi Suga, MIT License
okini3939 1:5a261b6a88af 20 */
okini3939 1:5a261b6a88af 21
okini3939 1:5a261b6a88af 22 #include "CBuffer_SRAM.h"
okini3939 1:5a261b6a88af 23
okini3939 1:5a261b6a88af 24 #define DBG(...)
okini3939 1:5a261b6a88af 25 //#define DBG(...) printf("" __VA_ARGS__)
okini3939 1:5a261b6a88af 26
okini3939 1:5a261b6a88af 27 CircBuffer::CircBuffer(int length) {
okini3939 1:5a261b6a88af 28 _ram = SerRAM::getInstance();
okini3939 1:5a261b6a88af 29 write = 0;
okini3939 1:5a261b6a88af 30 read = 0;
okini3939 1:5a261b6a88af 31 ram_addr = xalloc(length + 1);
okini3939 1:5a261b6a88af 32 size = length + 1;
okini3939 1:5a261b6a88af 33 };
okini3939 1:5a261b6a88af 34
okini3939 1:5a261b6a88af 35 int CircBuffer::xalloc(int n) {
okini3939 1:5a261b6a88af 36 static uint32_t ram_alloc = 0;
okini3939 1:5a261b6a88af 37 uint32_t a;
okini3939 1:5a261b6a88af 38
okini3939 1:5a261b6a88af 39 a = ram_alloc;
okini3939 1:5a261b6a88af 40 ram_alloc += (n + WINDOW_SIZE - 1) & ~WINDOW_MASK;
okini3939 1:5a261b6a88af 41 DBG("alloc %x ,next %x\r\n", a, ram_alloc);
okini3939 1:5a261b6a88af 42 return a;
okini3939 1:5a261b6a88af 43 }
okini3939 1:5a261b6a88af 44
okini3939 1:5a261b6a88af 45 bool CircBuffer::isFull() {
okini3939 1:5a261b6a88af 46 return (((write + 1) % size) == read);
okini3939 1:5a261b6a88af 47 };
okini3939 1:5a261b6a88af 48
okini3939 1:5a261b6a88af 49 bool CircBuffer::isEmpty() {
okini3939 1:5a261b6a88af 50 return (read == write);
okini3939 1:5a261b6a88af 51 };
okini3939 1:5a261b6a88af 52
okini3939 1:5a261b6a88af 53 bool CircBuffer::queue(char k) {
okini3939 1:5a261b6a88af 54 if (isFull()) {
okini3939 1:5a261b6a88af 55 return false;
okini3939 1:5a261b6a88af 56 }
okini3939 1:5a261b6a88af 57 #ifdef RAM_USE_DMA
okini3939 1:5a261b6a88af 58 while (_ram->isBusy()) DBG("busy\r\n");
okini3939 1:5a261b6a88af 59 #endif
okini3939 1:5a261b6a88af 60 uint32_t w = write;
okini3939 1:5a261b6a88af 61 buf_w[w & WINDOW_MASK] = k;
okini3939 1:5a261b6a88af 62 w = (w + 1) % size;
okini3939 1:5a261b6a88af 63 if ((w & WINDOW_MASK) == 0) {
okini3939 1:5a261b6a88af 64 _ram->write(ram_addr + (write & ~WINDOW_MASK), buf_w, WINDOW_SIZE, true);
okini3939 1:5a261b6a88af 65 DBG("(W %x)\r\n", ram_addr + (write & ~WINDOW_MASK));
okini3939 1:5a261b6a88af 66 if ((write & ~WINDOW_MASK) == (read & ~WINDOW_MASK)) {
okini3939 1:5a261b6a88af 67 // w = r
okini3939 1:5a261b6a88af 68 memcpy(buf_r, buf_w, WINDOW_SIZE);
okini3939 1:5a261b6a88af 69 DBG("memcpy\r\n");
okini3939 1:5a261b6a88af 70 }
okini3939 1:5a261b6a88af 71 }
okini3939 1:5a261b6a88af 72 write = w;
okini3939 1:5a261b6a88af 73 return true;
okini3939 1:5a261b6a88af 74 }
okini3939 1:5a261b6a88af 75
okini3939 1:5a261b6a88af 76 void CircBuffer::flush() {
okini3939 1:5a261b6a88af 77 _ram->write(ram_addr + (write & ~WINDOW_MASK), buf_w, WINDOW_SIZE, true);
okini3939 1:5a261b6a88af 78 read = 0;
okini3939 1:5a261b6a88af 79 write = 0;
okini3939 1:5a261b6a88af 80 }
okini3939 1:5a261b6a88af 81
okini3939 1:5a261b6a88af 82 uint32_t CircBuffer::available() {
okini3939 1:5a261b6a88af 83 return (write >= read) ? write - read : size - read + write;
okini3939 1:5a261b6a88af 84 };
okini3939 1:5a261b6a88af 85
okini3939 1:5a261b6a88af 86 uint32_t CircBuffer::use() {
okini3939 1:5a261b6a88af 87 return size - available() - 1;
okini3939 1:5a261b6a88af 88 };
okini3939 1:5a261b6a88af 89
okini3939 1:5a261b6a88af 90 bool CircBuffer::dequeue(char * c) {
okini3939 1:5a261b6a88af 91 bool empty = isEmpty();
okini3939 1:5a261b6a88af 92 if (!empty) {
okini3939 1:5a261b6a88af 93 #ifdef RAM_USE_DMA
okini3939 1:5a261b6a88af 94 while (_ram->isBusy()) DBG("busy\r\n");
okini3939 1:5a261b6a88af 95 #endif
okini3939 1:5a261b6a88af 96 uint32_t w = write, r = read;
okini3939 1:5a261b6a88af 97 if ((w & ~WINDOW_MASK) == (r & ~WINDOW_MASK) && w > r) {
okini3939 1:5a261b6a88af 98 *c = buf_w[r & WINDOW_MASK];
okini3939 1:5a261b6a88af 99 } else {
okini3939 1:5a261b6a88af 100 *c = buf_r[r & WINDOW_MASK];
okini3939 1:5a261b6a88af 101 }
okini3939 1:5a261b6a88af 102 r = (r + 1) % size;
okini3939 1:5a261b6a88af 103 if ((r & WINDOW_MASK) == 0) {
okini3939 1:5a261b6a88af 104 _ram->read(ram_addr + (r & ~WINDOW_MASK), buf_r, WINDOW_SIZE, true);
okini3939 1:5a261b6a88af 105 DBG("(R %x)\r\n", (r & ~WINDOW_MASK));
okini3939 1:5a261b6a88af 106 }
okini3939 1:5a261b6a88af 107 read = r;
okini3939 1:5a261b6a88af 108 }
okini3939 1:5a261b6a88af 109 return (!empty);
okini3939 1:5a261b6a88af 110 };
okini3939 1:5a261b6a88af 111
okini3939 1:5a261b6a88af 112 void CircBuffer::dump() {
okini3939 1:5a261b6a88af 113 int i;
okini3939 1:5a261b6a88af 114 printf("buf_w\r\n");
okini3939 1:5a261b6a88af 115 for (i = 0; i < WINDOW_SIZE; i ++) {
okini3939 1:5a261b6a88af 116 printf(" %02x", buf_w[i]);
okini3939 1:5a261b6a88af 117 if ((i & 0x0f) == 0x0f) printf("\r\n");
okini3939 1:5a261b6a88af 118 }
okini3939 1:5a261b6a88af 119 printf("buf_r\r\n");
okini3939 1:5a261b6a88af 120 for (i = 0; i < WINDOW_SIZE; i ++) {
okini3939 1:5a261b6a88af 121 printf(" %02x", buf_r[i]);
okini3939 1:5a261b6a88af 122 if ((i & 0x0f) == 0x0f) printf("\r\n");
okini3939 1:5a261b6a88af 123 }
okini3939 1:5a261b6a88af 124 }