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

Dependents:   SPIRAM_23LC1024_FIFO

Committer:
okini3939
Date:
Mon Jan 07 14:30:06 2013 +0000
Revision:
0:69ea2af1d9af
Child:
1:5a261b6a88af
1st build

Who changed what in which revision?

UserRevisionLine numberNew contents of line
okini3939 0:69ea2af1d9af 1 /*
okini3939 0:69ea2af1d9af 2 * Serial RAM (SPI SRAM) library
okini3939 0:69ea2af1d9af 3 * Copyright (c) 2013 Hiroshi Suga
okini3939 0:69ea2af1d9af 4 * Released under the MIT License: http://mbed.org/license/mit
okini3939 0:69ea2af1d9af 5 */
okini3939 0:69ea2af1d9af 6
okini3939 0:69ea2af1d9af 7 /** @file
okini3939 0:69ea2af1d9af 8 * @brief Serial RAM (SPI SRAM) library
okini3939 0:69ea2af1d9af 9 * 23K256, 23LC1024 (Microchip)
okini3939 0:69ea2af1d9af 10 * support FIFO
okini3939 0:69ea2af1d9af 11 * support DMA http://mbed.org/users/AjK/code/MODDMA/
okini3939 0:69ea2af1d9af 12 */
okini3939 0:69ea2af1d9af 13
okini3939 0:69ea2af1d9af 14 #include "mbed.h"
okini3939 0:69ea2af1d9af 15 #include "SerRAM.h"
okini3939 0:69ea2af1d9af 16
okini3939 0:69ea2af1d9af 17 #define DBG(...)
okini3939 0:69ea2af1d9af 18 //#define DBG(...) printf("" __VA_ARGS__)
okini3939 0:69ea2af1d9af 19
okini3939 0:69ea2af1d9af 20 #define CMD_READ 0x03
okini3939 0:69ea2af1d9af 21 #define CMD_WRITE 0x02
okini3939 0:69ea2af1d9af 22 #define CMD_RDMR 0x05
okini3939 0:69ea2af1d9af 23 #define CMD_WRMR 0x01
okini3939 0:69ea2af1d9af 24
okini3939 0:69ea2af1d9af 25 #define MODE_BYTE 0x00
okini3939 0:69ea2af1d9af 26 #define MODE_SEQ 0x40
okini3939 0:69ea2af1d9af 27
okini3939 0:69ea2af1d9af 28
okini3939 0:69ea2af1d9af 29 SerRAM::SerRAM (SPI& spi, PinName cs, int size) : _spi(spi), _cs(cs) {
okini3939 0:69ea2af1d9af 30 _spi.frequency(16000000);
okini3939 0:69ea2af1d9af 31 _cs = 1;
okini3939 0:69ea2af1d9af 32 _size = size;
okini3939 0:69ea2af1d9af 33 _alloc = 0;
okini3939 0:69ea2af1d9af 34
okini3939 0:69ea2af1d9af 35 #ifdef RAM_USE_DMA
okini3939 0:69ea2af1d9af 36 dmacfg0 = new MODDMA_Config;
okini3939 0:69ea2af1d9af 37 dmacfg1 = new MODDMA_Config;
okini3939 0:69ea2af1d9af 38 ssp_dmacr = &LPC_SSP1->DMACR;
okini3939 0:69ea2af1d9af 39 dmacon0 = MODDMA::SSP1_Tx;
okini3939 0:69ea2af1d9af 40 dmacon1 = MODDMA::SSP1_Rx;
okini3939 0:69ea2af1d9af 41 dmaexit = 1;
okini3939 0:69ea2af1d9af 42 #endif
okini3939 0:69ea2af1d9af 43
okini3939 0:69ea2af1d9af 44 #ifdef RAM_USE_FIFO
okini3939 0:69ea2af1d9af 45 fifo_num = 0;
okini3939 0:69ea2af1d9af 46 #endif
okini3939 0:69ea2af1d9af 47 }
okini3939 0:69ea2af1d9af 48
okini3939 0:69ea2af1d9af 49 SerRAM::SerRAM (PinName mosi, PinName miso, PinName sck, PinName cs, int size) : _spi(mosi, miso, sck), _cs(cs) {
okini3939 0:69ea2af1d9af 50 _spi.frequency(16000000);
okini3939 0:69ea2af1d9af 51 _cs = 1;
okini3939 0:69ea2af1d9af 52 _size = size;
okini3939 0:69ea2af1d9af 53 _alloc = 0;
okini3939 0:69ea2af1d9af 54
okini3939 0:69ea2af1d9af 55 #ifdef RAM_USE_DMA
okini3939 0:69ea2af1d9af 56 dmacfg0 = new MODDMA_Config;
okini3939 0:69ea2af1d9af 57 dmacfg1 = new MODDMA_Config;
okini3939 0:69ea2af1d9af 58 if (mosi == p5) {
okini3939 0:69ea2af1d9af 59 ssp_dmacr = &LPC_SSP1->DMACR;
okini3939 0:69ea2af1d9af 60 dmacon0 = MODDMA::SSP1_Tx;
okini3939 0:69ea2af1d9af 61 dmacon1 = MODDMA::SSP1_Rx;
okini3939 0:69ea2af1d9af 62 } else
okini3939 0:69ea2af1d9af 63 if (mosi == p11) {
okini3939 0:69ea2af1d9af 64 ssp_dmacr = &LPC_SSP0->DMACR;
okini3939 0:69ea2af1d9af 65 dmacon0 = MODDMA::SSP0_Tx;
okini3939 0:69ea2af1d9af 66 dmacon1 = MODDMA::SSP0_Rx;
okini3939 0:69ea2af1d9af 67 }
okini3939 0:69ea2af1d9af 68 dmaexit = 1;
okini3939 0:69ea2af1d9af 69 #endif
okini3939 0:69ea2af1d9af 70
okini3939 0:69ea2af1d9af 71 #ifdef RAM_USE_FIFO
okini3939 0:69ea2af1d9af 72 fifo_num = 0;
okini3939 0:69ea2af1d9af 73 #endif
okini3939 0:69ea2af1d9af 74 }
okini3939 0:69ea2af1d9af 75
okini3939 0:69ea2af1d9af 76 int SerRAM::write (int addr, int dat) {
okini3939 0:69ea2af1d9af 77
okini3939 0:69ea2af1d9af 78 _cs = 0;
okini3939 0:69ea2af1d9af 79 _spi.write(CMD_WRITE);
okini3939 0:69ea2af1d9af 80 if (_size > 512) {
okini3939 0:69ea2af1d9af 81 _spi.write((addr >> 16) & 0xff);
okini3939 0:69ea2af1d9af 82 }
okini3939 0:69ea2af1d9af 83 _spi.write((addr >> 8) & 0xff);
okini3939 0:69ea2af1d9af 84 _spi.write(addr & 0xff);
okini3939 0:69ea2af1d9af 85 _spi.write(dat);
okini3939 0:69ea2af1d9af 86 _cs = 1;
okini3939 0:69ea2af1d9af 87 return 0;
okini3939 0:69ea2af1d9af 88 }
okini3939 0:69ea2af1d9af 89
okini3939 0:69ea2af1d9af 90 int SerRAM::write (int addr, char *buf, int len, int async) {
okini3939 0:69ea2af1d9af 91 int i;
okini3939 0:69ea2af1d9af 92 #ifdef RAM_USE_DMA
okini3939 0:69ea2af1d9af 93 static char dummy[RAM_DMA_SIZE];
okini3939 0:69ea2af1d9af 94 #endif
okini3939 0:69ea2af1d9af 95
okini3939 0:69ea2af1d9af 96 DBG("DMA write %04x %d\r\n", addr, len);
okini3939 0:69ea2af1d9af 97 #ifdef RAM_USE_DMA
okini3939 0:69ea2af1d9af 98 while (! dmaexit);
okini3939 0:69ea2af1d9af 99 #endif
okini3939 0:69ea2af1d9af 100 _cs = 0;
okini3939 0:69ea2af1d9af 101 _spi.write(CMD_WRITE);
okini3939 0:69ea2af1d9af 102 if (_size > 512) {
okini3939 0:69ea2af1d9af 103 _spi.write((addr >> 16) & 0xff);
okini3939 0:69ea2af1d9af 104 }
okini3939 0:69ea2af1d9af 105 _spi.write((addr >> 8) & 0xff);
okini3939 0:69ea2af1d9af 106 _spi.write(addr & 0xff);
okini3939 0:69ea2af1d9af 107
okini3939 0:69ea2af1d9af 108 #ifdef RAM_USE_DMA
okini3939 0:69ea2af1d9af 109 if (len > RAM_DMA_SIZE) len = RAM_DMA_SIZE;
okini3939 0:69ea2af1d9af 110
okini3939 0:69ea2af1d9af 111 dmacfg0
okini3939 0:69ea2af1d9af 112 ->channelNum ( MODDMA::Channel_0 )
okini3939 0:69ea2af1d9af 113 ->srcMemAddr ( (uint32_t)buf )
okini3939 0:69ea2af1d9af 114 ->dstMemAddr ( dmacon0 )
okini3939 0:69ea2af1d9af 115 ->transferSize ( len )
okini3939 0:69ea2af1d9af 116 ->transferType ( MODDMA::m2p )
okini3939 0:69ea2af1d9af 117 ->dstConn ( dmacon0 )
okini3939 0:69ea2af1d9af 118 ->attach_tc ( this, &SerRAM::tc0_callback )
okini3939 0:69ea2af1d9af 119 ->attach_err ( this, &SerRAM::err_callback )
okini3939 0:69ea2af1d9af 120 ; // config end
okini3939 0:69ea2af1d9af 121
okini3939 0:69ea2af1d9af 122 dmacfg1
okini3939 0:69ea2af1d9af 123 ->channelNum ( MODDMA::Channel_1 )
okini3939 0:69ea2af1d9af 124 ->srcMemAddr ( dmacon1 )
okini3939 0:69ea2af1d9af 125 ->dstMemAddr ( (uint32_t)dummy )
okini3939 0:69ea2af1d9af 126 ->transferSize ( len )
okini3939 0:69ea2af1d9af 127 ->transferType ( MODDMA::p2m )
okini3939 0:69ea2af1d9af 128 ->srcConn ( dmacon1 )
okini3939 0:69ea2af1d9af 129 ->attach_tc ( this, &SerRAM::tc1_callback )
okini3939 0:69ea2af1d9af 130 ->attach_err ( this, &SerRAM::err_callback )
okini3939 0:69ea2af1d9af 131 ; // config end
okini3939 0:69ea2af1d9af 132
okini3939 0:69ea2af1d9af 133 dmaexit = 0;
okini3939 0:69ea2af1d9af 134 if (dma.Setup( dmacfg0 ) && dma.Setup( dmacfg1 )) {
okini3939 0:69ea2af1d9af 135 DBG("DMA setup\r\n");
okini3939 0:69ea2af1d9af 136 *ssp_dmacr = (1<<1)|(1<<0); // TX,RXDMAE
okini3939 0:69ea2af1d9af 137 dma.Enable( dmacfg0 );
okini3939 0:69ea2af1d9af 138 dma.Enable( dmacfg1 );
okini3939 0:69ea2af1d9af 139 DBG("DMA enable\r\n");
okini3939 0:69ea2af1d9af 140 i = 0;
okini3939 0:69ea2af1d9af 141 } else {
okini3939 0:69ea2af1d9af 142 DBG("DMA error\r\n");
okini3939 0:69ea2af1d9af 143 i = -1;
okini3939 0:69ea2af1d9af 144 }
okini3939 0:69ea2af1d9af 145
okini3939 0:69ea2af1d9af 146 if (async == 0) {
okini3939 0:69ea2af1d9af 147 while (! dmaexit);
okini3939 0:69ea2af1d9af 148 DBG("DMA done\r\n");
okini3939 0:69ea2af1d9af 149 }
okini3939 0:69ea2af1d9af 150 #else
okini3939 0:69ea2af1d9af 151 for (i = 0; i < len; i ++) {
okini3939 0:69ea2af1d9af 152 _spi.write(buf[i]);
okini3939 0:69ea2af1d9af 153 }
okini3939 0:69ea2af1d9af 154 _cs = 1;
okini3939 0:69ea2af1d9af 155 #endif
okini3939 0:69ea2af1d9af 156 return i;
okini3939 0:69ea2af1d9af 157 }
okini3939 0:69ea2af1d9af 158
okini3939 0:69ea2af1d9af 159 int SerRAM::read (int addr) {
okini3939 0:69ea2af1d9af 160 int dat;
okini3939 0:69ea2af1d9af 161
okini3939 0:69ea2af1d9af 162 _cs = 0;
okini3939 0:69ea2af1d9af 163 _spi.write(CMD_READ);
okini3939 0:69ea2af1d9af 164 if (_size > 512) {
okini3939 0:69ea2af1d9af 165 _spi.write((addr >> 16) & 0xff);
okini3939 0:69ea2af1d9af 166 }
okini3939 0:69ea2af1d9af 167 _spi.write((addr >> 8) & 0xff);
okini3939 0:69ea2af1d9af 168 _spi.write(addr & 0xff);
okini3939 0:69ea2af1d9af 169 dat = _spi.write(0);
okini3939 0:69ea2af1d9af 170 _cs = 1;
okini3939 0:69ea2af1d9af 171 return dat;
okini3939 0:69ea2af1d9af 172 }
okini3939 0:69ea2af1d9af 173
okini3939 0:69ea2af1d9af 174 int SerRAM::read (int addr, char *buf, int len, int async) {
okini3939 0:69ea2af1d9af 175 int i;
okini3939 0:69ea2af1d9af 176
okini3939 0:69ea2af1d9af 177 DBG("DMA read %04x %d\r\n", addr, len);
okini3939 0:69ea2af1d9af 178 #ifdef RAM_USE_DMA
okini3939 0:69ea2af1d9af 179 while (! dmaexit);
okini3939 0:69ea2af1d9af 180 #endif
okini3939 0:69ea2af1d9af 181 _cs = 0;
okini3939 0:69ea2af1d9af 182 _spi.write(CMD_READ);
okini3939 0:69ea2af1d9af 183 if (_size > 512) {
okini3939 0:69ea2af1d9af 184 _spi.write((addr >> 16) & 0xff);
okini3939 0:69ea2af1d9af 185 }
okini3939 0:69ea2af1d9af 186 _spi.write((addr >> 8) & 0xff);
okini3939 0:69ea2af1d9af 187 _spi.write(addr & 0xff);
okini3939 0:69ea2af1d9af 188
okini3939 0:69ea2af1d9af 189 #ifdef RAM_USE_DMA
okini3939 0:69ea2af1d9af 190 dmacfg0
okini3939 0:69ea2af1d9af 191 ->channelNum ( MODDMA::Channel_0 )
okini3939 0:69ea2af1d9af 192 ->srcMemAddr ( (uint32_t)buf )
okini3939 0:69ea2af1d9af 193 ->dstMemAddr ( dmacon0 )
okini3939 0:69ea2af1d9af 194 ->transferSize ( len )
okini3939 0:69ea2af1d9af 195 ->transferType ( MODDMA::m2p )
okini3939 0:69ea2af1d9af 196 ->dstConn ( dmacon0 )
okini3939 0:69ea2af1d9af 197 ->attach_tc ( this, &SerRAM::tc0_callback )
okini3939 0:69ea2af1d9af 198 ->attach_err ( this, &SerRAM::err_callback )
okini3939 0:69ea2af1d9af 199 ; // config end
okini3939 0:69ea2af1d9af 200
okini3939 0:69ea2af1d9af 201 dmacfg1
okini3939 0:69ea2af1d9af 202 ->channelNum ( MODDMA::Channel_1 )
okini3939 0:69ea2af1d9af 203 ->srcMemAddr ( dmacon1 )
okini3939 0:69ea2af1d9af 204 ->dstMemAddr ( (uint32_t)buf )
okini3939 0:69ea2af1d9af 205 ->transferSize ( len )
okini3939 0:69ea2af1d9af 206 ->transferType ( MODDMA::p2m )
okini3939 0:69ea2af1d9af 207 ->srcConn ( dmacon1 )
okini3939 0:69ea2af1d9af 208 ->attach_tc ( this, &SerRAM::tc1_callback )
okini3939 0:69ea2af1d9af 209 ->attach_err ( this, &SerRAM::err_callback )
okini3939 0:69ea2af1d9af 210 ; // config end
okini3939 0:69ea2af1d9af 211
okini3939 0:69ea2af1d9af 212 dmaexit = 0;
okini3939 0:69ea2af1d9af 213 if (dma.Setup( dmacfg0 ) && dma.Setup( dmacfg1 )) {
okini3939 0:69ea2af1d9af 214 *ssp_dmacr = (1<<1)|(1<<0); // TX,RXDMAE
okini3939 0:69ea2af1d9af 215 dma.Enable( dmacfg0 );
okini3939 0:69ea2af1d9af 216 dma.Enable( dmacfg1 );
okini3939 0:69ea2af1d9af 217 i = 0;
okini3939 0:69ea2af1d9af 218 } else {
okini3939 0:69ea2af1d9af 219 DBG("DMA error\r\n");
okini3939 0:69ea2af1d9af 220 i = -1;
okini3939 0:69ea2af1d9af 221 }
okini3939 0:69ea2af1d9af 222
okini3939 0:69ea2af1d9af 223 if (async == 0) {
okini3939 0:69ea2af1d9af 224 while (! dmaexit);
okini3939 0:69ea2af1d9af 225 }
okini3939 0:69ea2af1d9af 226 #else
okini3939 0:69ea2af1d9af 227 for (i = 0; i < len; i ++) {
okini3939 0:69ea2af1d9af 228 buf[i] = _spi.write(0);
okini3939 0:69ea2af1d9af 229 }
okini3939 0:69ea2af1d9af 230 _cs = 1;
okini3939 0:69ea2af1d9af 231 #endif
okini3939 0:69ea2af1d9af 232 return i;
okini3939 0:69ea2af1d9af 233 }
okini3939 0:69ea2af1d9af 234
okini3939 0:69ea2af1d9af 235 int SerRAM::setStatus (int status) {
okini3939 0:69ea2af1d9af 236
okini3939 0:69ea2af1d9af 237 _cs = 0;
okini3939 0:69ea2af1d9af 238 _spi.write(CMD_WRMR);
okini3939 0:69ea2af1d9af 239 _spi.write(status);
okini3939 0:69ea2af1d9af 240 _cs = 1;
okini3939 0:69ea2af1d9af 241 return 0;
okini3939 0:69ea2af1d9af 242 }
okini3939 0:69ea2af1d9af 243
okini3939 0:69ea2af1d9af 244 int SerRAM::getStatus () {
okini3939 0:69ea2af1d9af 245 int r;
okini3939 0:69ea2af1d9af 246
okini3939 0:69ea2af1d9af 247 _cs = 0;
okini3939 0:69ea2af1d9af 248 _spi.write(CMD_RDMR);
okini3939 0:69ea2af1d9af 249 r = _spi.write(0);
okini3939 0:69ea2af1d9af 250 _cs = 1;
okini3939 0:69ea2af1d9af 251 return r;
okini3939 0:69ea2af1d9af 252 }
okini3939 0:69ea2af1d9af 253
okini3939 0:69ea2af1d9af 254 #ifdef RAM_USE_DMA
okini3939 0:69ea2af1d9af 255 void SerRAM::tc0_callback () {
okini3939 0:69ea2af1d9af 256
okini3939 0:69ea2af1d9af 257 MODDMA_Config *config = dma.getConfig();
okini3939 0:69ea2af1d9af 258 dma.Disable( (MODDMA::CHANNELS)config->channelNum() );
okini3939 0:69ea2af1d9af 259
okini3939 0:69ea2af1d9af 260 // Clear DMA IRQ flags.
okini3939 0:69ea2af1d9af 261 if (dma.irqType() == MODDMA::TcIrq) dma.clearTcIrq();
okini3939 0:69ea2af1d9af 262 if (dma.irqType() == MODDMA::ErrIrq) dma.clearErrIrq();
okini3939 0:69ea2af1d9af 263 DBG("tc0_callback\r\n");
okini3939 0:69ea2af1d9af 264 }
okini3939 0:69ea2af1d9af 265
okini3939 0:69ea2af1d9af 266 void SerRAM::tc1_callback () {
okini3939 0:69ea2af1d9af 267
okini3939 0:69ea2af1d9af 268 dmaexit = 1;
okini3939 0:69ea2af1d9af 269 _cs = 1;
okini3939 0:69ea2af1d9af 270 *ssp_dmacr = 0;
okini3939 0:69ea2af1d9af 271
okini3939 0:69ea2af1d9af 272 MODDMA_Config *config = dma.getConfig();
okini3939 0:69ea2af1d9af 273 dma.Disable( (MODDMA::CHANNELS)config->channelNum() );
okini3939 0:69ea2af1d9af 274
okini3939 0:69ea2af1d9af 275 // Clear DMA IRQ flags.
okini3939 0:69ea2af1d9af 276 if (dma.irqType() == MODDMA::TcIrq) dma.clearTcIrq();
okini3939 0:69ea2af1d9af 277 if (dma.irqType() == MODDMA::ErrIrq) dma.clearErrIrq();
okini3939 0:69ea2af1d9af 278 DBG("tc1_callback\r\n");
okini3939 0:69ea2af1d9af 279 }
okini3939 0:69ea2af1d9af 280
okini3939 0:69ea2af1d9af 281 void SerRAM::err_callback () {
okini3939 0:69ea2af1d9af 282 dmaexit = -1;
okini3939 0:69ea2af1d9af 283 _cs = 1;
okini3939 0:69ea2af1d9af 284 DBG("err_callback\r\n");
okini3939 0:69ea2af1d9af 285 }
okini3939 0:69ea2af1d9af 286 #endif
okini3939 0:69ea2af1d9af 287
okini3939 0:69ea2af1d9af 288 #ifdef RAM_USE_FIFO
okini3939 0:69ea2af1d9af 289 int SerRAM::fifoAlloc (int size) {
okini3939 0:69ea2af1d9af 290 int n, s;
okini3939 0:69ea2af1d9af 291
okini3939 0:69ea2af1d9af 292 s = ((size + 1) / RAM_DMA_SIZE + 1) * RAM_DMA_SIZE;
okini3939 0:69ea2af1d9af 293 if (fifo_num >= RAM_FIFO_NUM || (_size * 1024 - _alloc) < s) return -1;
okini3939 0:69ea2af1d9af 294
okini3939 0:69ea2af1d9af 295 n = fifo_num;
okini3939 0:69ea2af1d9af 296 fifo[n].size = size + 1;
okini3939 0:69ea2af1d9af 297 fifo[n].buf_w = new char[RAM_DMA_SIZE];
okini3939 0:69ea2af1d9af 298 fifo[n].buf_r = new char[RAM_DMA_SIZE];
okini3939 0:69ea2af1d9af 299 fifo[n].ram = _alloc;
okini3939 0:69ea2af1d9af 300 fifoClear(n);
okini3939 0:69ea2af1d9af 301
okini3939 0:69ea2af1d9af 302 fifo_num ++;
okini3939 0:69ea2af1d9af 303 _alloc += s;
okini3939 0:69ea2af1d9af 304 DBG("alloc %d + %d (%d)\r\n", fifo[n].ram, fifo[n].size, _alloc);
okini3939 0:69ea2af1d9af 305 return n;
okini3939 0:69ea2af1d9af 306 }
okini3939 0:69ea2af1d9af 307
okini3939 0:69ea2af1d9af 308 int SerRAM::fifoPut (int n, char dat) {
okini3939 0:69ea2af1d9af 309 int next, next2;
okini3939 0:69ea2af1d9af 310
okini3939 0:69ea2af1d9af 311 next = fifo[n].addr_w + 1;
okini3939 0:69ea2af1d9af 312 next2 = fifo[n].addr2_w + 1;
okini3939 0:69ea2af1d9af 313 if (next >= fifo[n].size) {
okini3939 0:69ea2af1d9af 314 // last of fifo
okini3939 0:69ea2af1d9af 315 next = 0;
okini3939 0:69ea2af1d9af 316 next2 = 0;
okini3939 0:69ea2af1d9af 317 }
okini3939 0:69ea2af1d9af 318 if (next2 >= RAM_DMA_SIZE) {
okini3939 0:69ea2af1d9af 319 // last of buffer
okini3939 0:69ea2af1d9af 320 next2 = 0;
okini3939 0:69ea2af1d9af 321 }
okini3939 0:69ea2af1d9af 322
okini3939 0:69ea2af1d9af 323 if (next == fifo[n].addr_r) {
okini3939 0:69ea2af1d9af 324 // no data
okini3939 0:69ea2af1d9af 325 return -1;
okini3939 0:69ea2af1d9af 326 }
okini3939 0:69ea2af1d9af 327 #ifdef RAM_USE_DMA
okini3939 0:69ea2af1d9af 328 while (! dmaexit); // busy DMA
okini3939 0:69ea2af1d9af 329 #endif
okini3939 0:69ea2af1d9af 330 fifo[n].buf_w[fifo[n].addr2_w] = dat;
okini3939 0:69ea2af1d9af 331
okini3939 0:69ea2af1d9af 332 if (next2 == 0) {
okini3939 0:69ea2af1d9af 333 // ring
okini3939 0:69ea2af1d9af 334 write(fifo[n].ram + fifo[n].ram_w, fifo[n].buf_w, RAM_DMA_SIZE, 1);
okini3939 0:69ea2af1d9af 335 if (fifo[n].ram_w == fifo[n].ram_r) {
okini3939 0:69ea2af1d9af 336 // w = r
okini3939 0:69ea2af1d9af 337 memcpy(fifo[n].buf_r, fifo[n].buf_w, RAM_DMA_SIZE);
okini3939 0:69ea2af1d9af 338 }
okini3939 0:69ea2af1d9af 339
okini3939 0:69ea2af1d9af 340 fifo[n].ram_w += RAM_DMA_SIZE;
okini3939 0:69ea2af1d9af 341 if (next == 0) {
okini3939 0:69ea2af1d9af 342 fifo[n].ram_w = 0;
okini3939 0:69ea2af1d9af 343 }
okini3939 0:69ea2af1d9af 344 }
okini3939 0:69ea2af1d9af 345 fifo[n].addr_w = next;
okini3939 0:69ea2af1d9af 346 fifo[n].addr2_w = next2;
okini3939 0:69ea2af1d9af 347 return 0;
okini3939 0:69ea2af1d9af 348 }
okini3939 0:69ea2af1d9af 349
okini3939 0:69ea2af1d9af 350 int SerRAM::fifoPut (int n, char *buf, int len) {
okini3939 0:69ea2af1d9af 351 int i;
okini3939 0:69ea2af1d9af 352
okini3939 0:69ea2af1d9af 353 for (i = 0; i < len; i ++) {
okini3939 0:69ea2af1d9af 354 if (fifoPut(n, buf[i])) return -1;
okini3939 0:69ea2af1d9af 355 }
okini3939 0:69ea2af1d9af 356 return 0;
okini3939 0:69ea2af1d9af 357 }
okini3939 0:69ea2af1d9af 358
okini3939 0:69ea2af1d9af 359 int SerRAM::fifoGet (int n, char *dat) {
okini3939 0:69ea2af1d9af 360
okini3939 0:69ea2af1d9af 361 if (fifo[n].addr_r == fifo[n].addr_w) {
okini3939 0:69ea2af1d9af 362 // no data
okini3939 0:69ea2af1d9af 363 return -1;
okini3939 0:69ea2af1d9af 364 }
okini3939 0:69ea2af1d9af 365 #ifdef RAM_USE_DMA
okini3939 0:69ea2af1d9af 366 while (! dmaexit); // busy DMA
okini3939 0:69ea2af1d9af 367 #endif
okini3939 0:69ea2af1d9af 368 if (fifo[n].ram_r != fifo[n].ram_w) {
okini3939 0:69ea2af1d9af 369 *dat = fifo[n].buf_r[fifo[n].addr2_r];
okini3939 0:69ea2af1d9af 370 } else
okini3939 0:69ea2af1d9af 371 if (fifo[n].addr_w < fifo[n].addr_r) {
okini3939 0:69ea2af1d9af 372 *dat = fifo[n].buf_r[fifo[n].addr2_r];
okini3939 0:69ea2af1d9af 373 } else {
okini3939 0:69ea2af1d9af 374 // w = r and w > r
okini3939 0:69ea2af1d9af 375 *dat = fifo[n].buf_w[fifo[n].addr2_r];
okini3939 0:69ea2af1d9af 376 }
okini3939 0:69ea2af1d9af 377
okini3939 0:69ea2af1d9af 378 fifo[n].addr_r += 1;
okini3939 0:69ea2af1d9af 379 fifo[n].addr2_r += 1;
okini3939 0:69ea2af1d9af 380 if (fifo[n].addr_r >= fifo[n].size) {
okini3939 0:69ea2af1d9af 381 // last of fifo
okini3939 0:69ea2af1d9af 382 fifo[n].addr_r = 0;
okini3939 0:69ea2af1d9af 383 fifo[n].addr2_r = 0;
okini3939 0:69ea2af1d9af 384 }
okini3939 0:69ea2af1d9af 385 if (fifo[n].addr2_r >= RAM_DMA_SIZE) {
okini3939 0:69ea2af1d9af 386 // last of buffer
okini3939 0:69ea2af1d9af 387 fifo[n].addr2_r = 0;
okini3939 0:69ea2af1d9af 388 }
okini3939 0:69ea2af1d9af 389 if (fifo[n].addr2_r == 0) {
okini3939 0:69ea2af1d9af 390 // ring
okini3939 0:69ea2af1d9af 391 fifo[n].ram_r += RAM_DMA_SIZE;
okini3939 0:69ea2af1d9af 392 if (fifo[n].addr_r == 0) {
okini3939 0:69ea2af1d9af 393 fifo[n].ram_r = 0;
okini3939 0:69ea2af1d9af 394 }
okini3939 0:69ea2af1d9af 395 read(fifo[n].ram + fifo[n].ram_r, fifo[n].buf_r, RAM_DMA_SIZE);
okini3939 0:69ea2af1d9af 396 }
okini3939 0:69ea2af1d9af 397 return 0;
okini3939 0:69ea2af1d9af 398 }
okini3939 0:69ea2af1d9af 399
okini3939 0:69ea2af1d9af 400 int SerRAM::fifoGet (int n, char *buf, int len) {
okini3939 0:69ea2af1d9af 401 int i;
okini3939 0:69ea2af1d9af 402
okini3939 0:69ea2af1d9af 403 for (i = 0; i < len; i ++) {
okini3939 0:69ea2af1d9af 404 if (fifoGet(n, &buf[i])) return -1;
okini3939 0:69ea2af1d9af 405 }
okini3939 0:69ea2af1d9af 406 return 0;
okini3939 0:69ea2af1d9af 407 }
okini3939 0:69ea2af1d9af 408
okini3939 0:69ea2af1d9af 409 int SerRAM::fifoAvailable (int n) {
okini3939 0:69ea2af1d9af 410 if (fifo[n].addr_w < fifo[n].addr_r) {
okini3939 0:69ea2af1d9af 411 return fifo[n].addr_r - fifo[n].addr_w - 1;
okini3939 0:69ea2af1d9af 412 } else {
okini3939 0:69ea2af1d9af 413 return (fifo[n].size - fifo[n].addr_w) + fifo[n].addr_r - 1;
okini3939 0:69ea2af1d9af 414 }
okini3939 0:69ea2af1d9af 415 }
okini3939 0:69ea2af1d9af 416
okini3939 0:69ea2af1d9af 417 int SerRAM::fifoUse (int n) {
okini3939 0:69ea2af1d9af 418 return fifo[n].size - fifoAvailable(n) - 1;
okini3939 0:69ea2af1d9af 419 }
okini3939 0:69ea2af1d9af 420
okini3939 0:69ea2af1d9af 421 void SerRAM::fifoClear (int n) {
okini3939 0:69ea2af1d9af 422 fifo[n].addr_w = 0;
okini3939 0:69ea2af1d9af 423 fifo[n].addr_r = 0;
okini3939 0:69ea2af1d9af 424 fifo[n].addr2_w = 0;
okini3939 0:69ea2af1d9af 425 fifo[n].addr2_r = 0;
okini3939 0:69ea2af1d9af 426 fifo[n].ram_w = 0;
okini3939 0:69ea2af1d9af 427 fifo[n].ram_r = 0;
okini3939 0:69ea2af1d9af 428
okini3939 0:69ea2af1d9af 429 read(fifo[n].ram + fifo[n].ram_r, fifo[n].buf_r, RAM_DMA_SIZE);
okini3939 0:69ea2af1d9af 430 }
okini3939 0:69ea2af1d9af 431 #endif