Serial RAM (SPI SRAM) library 23K256, 23LC1024 (Microchip) see: http://mbed.org/users/okini3939/notebook/extend-memory/
Dependents: SPIRAM_23LC1024_FIFO
CBuffer_SRAM.cpp@1:5a261b6a88af, 2013-03-08 (annotated)
- Committer:
- okini3939
- Date:
- Fri Mar 08 14:00:38 2013 +0000
- Revision:
- 1:5a261b6a88af
add CircBuffer
Who changed what in which revision?
User | Revision | Line number | New 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 | } |