SPI RAM 23LC1024 (Microchip) with DMA

Dependencies:   mbed

Fork of SPIRAM_23LC1024 by Suga koubou

Committer:
okini3939
Date:
Wed Dec 05 07:56:09 2012 +0000
Revision:
2:a3e0f7f37ac9
Parent:
1:a7b1803dfa44
DMX

Who changed what in which revision?

UserRevisionLine numberNew contents of line
okini3939 0:c5ba7d914282 1 /*
okini3939 0:c5ba7d914282 2 * SPI RAM 23LC1024 (Microchip)
okini3939 1:a7b1803dfa44 3 * 1Mbit
okini3939 2:a3e0f7f37ac9 4 * with DMA ( http://mbed.org/users/AjK/code/MODDMA/ )
okini3939 0:c5ba7d914282 5 */
okini3939 0:c5ba7d914282 6 #include "mbed.h"
okini3939 2:a3e0f7f37ac9 7 #include "MODDMA.h"
okini3939 2:a3e0f7f37ac9 8
okini3939 2:a3e0f7f37ac9 9 #define ENABLE_DMA
okini3939 0:c5ba7d914282 10
okini3939 0:c5ba7d914282 11 #define CMD_READ 0x03
okini3939 0:c5ba7d914282 12 #define CMD_WRITE 0x02
okini3939 0:c5ba7d914282 13 #define CMD_RDMR 0x05
okini3939 0:c5ba7d914282 14 #define CMD_WRMR 0x01
okini3939 0:c5ba7d914282 15
okini3939 0:c5ba7d914282 16 DigitalOut myled(LED1);
okini3939 0:c5ba7d914282 17 Serial pc(USBTX, USBRX);
okini3939 0:c5ba7d914282 18
okini3939 0:c5ba7d914282 19 SPI spi(p11, p12, p13); // mosi, miso, sclk
okini3939 2:a3e0f7f37ac9 20 DigitalOut cs(p14);
okini3939 2:a3e0f7f37ac9 21
okini3939 2:a3e0f7f37ac9 22 MODDMA dma;
okini3939 2:a3e0f7f37ac9 23 MODDMA_Config *dmacfg0 = NULL, *dmacfg1 = NULL;
okini3939 2:a3e0f7f37ac9 24 DigitalOut led2(LED2), led3(LED3), led4(LED4);
okini3939 2:a3e0f7f37ac9 25 volatile int dmaexit;
okini3939 2:a3e0f7f37ac9 26
okini3939 2:a3e0f7f37ac9 27 extern "C" void HardFault_Handler() {
okini3939 2:a3e0f7f37ac9 28 register unsigned int _msp __asm("msp");
okini3939 2:a3e0f7f37ac9 29 printf("Hard Fault! address: %08x\r\n", *((unsigned int *)(_msp + 24)));
okini3939 2:a3e0f7f37ac9 30 exit(-1);
okini3939 2:a3e0f7f37ac9 31 }
okini3939 2:a3e0f7f37ac9 32
okini3939 2:a3e0f7f37ac9 33 void tc0_callback () {
okini3939 2:a3e0f7f37ac9 34 led2 = 1;
okini3939 2:a3e0f7f37ac9 35
okini3939 2:a3e0f7f37ac9 36 MODDMA_Config *config = dma.getConfig();
okini3939 2:a3e0f7f37ac9 37 dma.Disable( (MODDMA::CHANNELS)config->channelNum() );
okini3939 2:a3e0f7f37ac9 38
okini3939 2:a3e0f7f37ac9 39 // Clear DMA IRQ flags.
okini3939 2:a3e0f7f37ac9 40 if (dma.irqType() == MODDMA::TcIrq) dma.clearTcIrq();
okini3939 2:a3e0f7f37ac9 41 if (dma.irqType() == MODDMA::ErrIrq) dma.clearErrIrq();
okini3939 2:a3e0f7f37ac9 42 }
okini3939 2:a3e0f7f37ac9 43
okini3939 2:a3e0f7f37ac9 44 void tc1_callback () {
okini3939 2:a3e0f7f37ac9 45 dmaexit = 1;
okini3939 2:a3e0f7f37ac9 46 led3 = 1;
okini3939 2:a3e0f7f37ac9 47
okini3939 2:a3e0f7f37ac9 48 MODDMA_Config *config = dma.getConfig();
okini3939 2:a3e0f7f37ac9 49 dma.Disable( (MODDMA::CHANNELS)config->channelNum() );
okini3939 2:a3e0f7f37ac9 50
okini3939 2:a3e0f7f37ac9 51 // Clear DMA IRQ flags.
okini3939 2:a3e0f7f37ac9 52 if (dma.irqType() == MODDMA::TcIrq) dma.clearTcIrq();
okini3939 2:a3e0f7f37ac9 53 if (dma.irqType() == MODDMA::ErrIrq) dma.clearErrIrq();
okini3939 2:a3e0f7f37ac9 54 }
okini3939 2:a3e0f7f37ac9 55
okini3939 2:a3e0f7f37ac9 56 void err_callback () {
okini3939 2:a3e0f7f37ac9 57 dmaexit = 1;
okini3939 2:a3e0f7f37ac9 58 led4 = 1;
okini3939 2:a3e0f7f37ac9 59 printf("err\r\n");
okini3939 2:a3e0f7f37ac9 60 }
okini3939 0:c5ba7d914282 61
okini3939 0:c5ba7d914282 62 int ram_write (int addr, char *buf, int len) {
okini3939 0:c5ba7d914282 63 int i;
okini3939 2:a3e0f7f37ac9 64 char dummy[len];
okini3939 0:c5ba7d914282 65
okini3939 0:c5ba7d914282 66 cs = 0;
okini3939 0:c5ba7d914282 67 spi.write(CMD_WRITE);
okini3939 0:c5ba7d914282 68 spi.write((addr >> 16) & 0xff);
okini3939 0:c5ba7d914282 69 spi.write((addr >> 8) & 0xff);
okini3939 0:c5ba7d914282 70 spi.write(addr & 0xff);
okini3939 2:a3e0f7f37ac9 71
okini3939 2:a3e0f7f37ac9 72 #ifdef ENABLE_DMA
okini3939 2:a3e0f7f37ac9 73 dmacfg0
okini3939 2:a3e0f7f37ac9 74 ->channelNum ( MODDMA::Channel_0 )
okini3939 2:a3e0f7f37ac9 75 ->srcMemAddr ( (uint32_t)buf )
okini3939 2:a3e0f7f37ac9 76 ->dstMemAddr ( MODDMA::SSP0_Tx )
okini3939 2:a3e0f7f37ac9 77 ->transferSize ( len )
okini3939 2:a3e0f7f37ac9 78 ->transferType ( MODDMA::m2p )
okini3939 2:a3e0f7f37ac9 79 ->dstConn ( MODDMA::SSP0_Tx )
okini3939 2:a3e0f7f37ac9 80 ->attach_tc ( &tc0_callback )
okini3939 2:a3e0f7f37ac9 81 ->attach_err ( &err_callback )
okini3939 2:a3e0f7f37ac9 82 ; // config end
okini3939 0:c5ba7d914282 83
okini3939 2:a3e0f7f37ac9 84 dmacfg1
okini3939 2:a3e0f7f37ac9 85 ->channelNum ( MODDMA::Channel_1 )
okini3939 2:a3e0f7f37ac9 86 ->srcMemAddr ( MODDMA::SSP0_Rx )
okini3939 2:a3e0f7f37ac9 87 ->dstMemAddr ( (uint32_t)dummy )
okini3939 2:a3e0f7f37ac9 88 ->transferSize ( len )
okini3939 2:a3e0f7f37ac9 89 ->transferType ( MODDMA::p2m )
okini3939 2:a3e0f7f37ac9 90 ->srcConn ( MODDMA::SSP0_Rx )
okini3939 2:a3e0f7f37ac9 91 ->attach_tc ( &tc1_callback )
okini3939 2:a3e0f7f37ac9 92 ->attach_err ( &err_callback )
okini3939 2:a3e0f7f37ac9 93 ; // config end
okini3939 2:a3e0f7f37ac9 94
okini3939 2:a3e0f7f37ac9 95 if (dma.Setup( dmacfg0 ) && dma.Setup( dmacfg1 )) {
okini3939 2:a3e0f7f37ac9 96 dmaexit = 0;
okini3939 2:a3e0f7f37ac9 97 LPC_SSP0->DMACR = (1<<1)|(1<<0); // TX,RXDMAE
okini3939 2:a3e0f7f37ac9 98 dma.Enable( dmacfg0 );
okini3939 2:a3e0f7f37ac9 99 dma.Enable( dmacfg1 );
okini3939 2:a3e0f7f37ac9 100 while (! dmaexit);
okini3939 2:a3e0f7f37ac9 101 } else {
okini3939 2:a3e0f7f37ac9 102 printf("error\r\n");
okini3939 2:a3e0f7f37ac9 103 }
okini3939 2:a3e0f7f37ac9 104 LPC_SSP0->DMACR = 0;
okini3939 2:a3e0f7f37ac9 105 #else
okini3939 0:c5ba7d914282 106 for (i = 0; i < len; i ++) {
okini3939 0:c5ba7d914282 107 spi.write(buf[i]);
okini3939 0:c5ba7d914282 108 }
okini3939 2:a3e0f7f37ac9 109 #endif
okini3939 0:c5ba7d914282 110 cs = 1;
okini3939 0:c5ba7d914282 111 return i;
okini3939 0:c5ba7d914282 112 }
okini3939 0:c5ba7d914282 113
okini3939 0:c5ba7d914282 114 int ram_read (int addr, char *buf, int len) {
okini3939 0:c5ba7d914282 115 int i;
okini3939 0:c5ba7d914282 116
okini3939 0:c5ba7d914282 117 cs = 0;
okini3939 0:c5ba7d914282 118 spi.write(CMD_READ);
okini3939 0:c5ba7d914282 119 spi.write((addr >> 16) & 0xff);
okini3939 0:c5ba7d914282 120 spi.write((addr >> 8) & 0xff);
okini3939 0:c5ba7d914282 121 spi.write(addr & 0xff);
okini3939 0:c5ba7d914282 122
okini3939 2:a3e0f7f37ac9 123 #ifdef ENABLE_DMA
okini3939 2:a3e0f7f37ac9 124 dmacfg0
okini3939 2:a3e0f7f37ac9 125 ->channelNum ( MODDMA::Channel_0 )
okini3939 2:a3e0f7f37ac9 126 ->srcMemAddr ( (uint32_t)buf )
okini3939 2:a3e0f7f37ac9 127 ->dstMemAddr ( MODDMA::SSP0_Tx )
okini3939 2:a3e0f7f37ac9 128 ->transferSize ( len )
okini3939 2:a3e0f7f37ac9 129 ->transferType ( MODDMA::m2p )
okini3939 2:a3e0f7f37ac9 130 ->dstConn ( MODDMA::SSP0_Tx )
okini3939 2:a3e0f7f37ac9 131 ->attach_tc ( &tc0_callback )
okini3939 2:a3e0f7f37ac9 132 ->attach_err ( &err_callback )
okini3939 2:a3e0f7f37ac9 133 ; // config end
okini3939 2:a3e0f7f37ac9 134
okini3939 2:a3e0f7f37ac9 135 dmacfg1
okini3939 2:a3e0f7f37ac9 136 ->channelNum ( MODDMA::Channel_1 )
okini3939 2:a3e0f7f37ac9 137 ->srcMemAddr ( MODDMA::SSP0_Rx )
okini3939 2:a3e0f7f37ac9 138 ->dstMemAddr ( (uint32_t)buf )
okini3939 2:a3e0f7f37ac9 139 ->transferSize ( len )
okini3939 2:a3e0f7f37ac9 140 ->transferType ( MODDMA::p2m )
okini3939 2:a3e0f7f37ac9 141 ->srcConn ( MODDMA::SSP0_Rx )
okini3939 2:a3e0f7f37ac9 142 ->attach_tc ( &tc1_callback )
okini3939 2:a3e0f7f37ac9 143 ->attach_err ( &err_callback )
okini3939 2:a3e0f7f37ac9 144 ; // config end
okini3939 2:a3e0f7f37ac9 145
okini3939 2:a3e0f7f37ac9 146 if (dma.Setup( dmacfg0 ) && dma.Setup( dmacfg1 )) {
okini3939 2:a3e0f7f37ac9 147 dmaexit = 0;
okini3939 2:a3e0f7f37ac9 148 LPC_SSP0->DMACR = (1<<1)|(1<<0); // TX,RXDMAE
okini3939 2:a3e0f7f37ac9 149 dma.Enable( dmacfg0 );
okini3939 2:a3e0f7f37ac9 150 dma.Enable( dmacfg1 );
okini3939 2:a3e0f7f37ac9 151 while (! dmaexit);
okini3939 2:a3e0f7f37ac9 152 } else {
okini3939 2:a3e0f7f37ac9 153 printf("error\r\n");
okini3939 2:a3e0f7f37ac9 154 }
okini3939 2:a3e0f7f37ac9 155 LPC_SSP0->DMACR = 0;
okini3939 2:a3e0f7f37ac9 156 #else
okini3939 0:c5ba7d914282 157 for (i = 0; i < len; i ++) {
okini3939 0:c5ba7d914282 158 buf[i] = spi.write(0);
okini3939 0:c5ba7d914282 159 }
okini3939 2:a3e0f7f37ac9 160 #endif
okini3939 0:c5ba7d914282 161 cs = 1;
okini3939 0:c5ba7d914282 162 return i;
okini3939 0:c5ba7d914282 163 }
okini3939 0:c5ba7d914282 164
okini3939 0:c5ba7d914282 165 int main() {
okini3939 0:c5ba7d914282 166 int i;
okini3939 0:c5ba7d914282 167 char buf[256];
okini3939 1:a7b1803dfa44 168 Timer t;
okini3939 0:c5ba7d914282 169
okini3939 0:c5ba7d914282 170 cs = 1;
okini3939 2:a3e0f7f37ac9 171 #ifdef ENABLE_DMA
okini3939 2:a3e0f7f37ac9 172 dmacfg0 = new MODDMA_Config;
okini3939 2:a3e0f7f37ac9 173 dmacfg1 = new MODDMA_Config;
okini3939 2:a3e0f7f37ac9 174 #endif
okini3939 0:c5ba7d914282 175 pc.baud(115200);
okini3939 1:a7b1803dfa44 176 spi.frequency(16000000);
okini3939 0:c5ba7d914282 177 wait_ms(500);
okini3939 2:a3e0f7f37ac9 178
okini3939 0:c5ba7d914282 179 cs = 0;
okini3939 0:c5ba7d914282 180 spi.write(CMD_RDMR);
okini3939 0:c5ba7d914282 181 printf("RAM mode: %02x\r\n", spi.write(0));
okini3939 0:c5ba7d914282 182 cs = 1;
okini3939 0:c5ba7d914282 183
okini3939 1:a7b1803dfa44 184 printf("\r\nHELLO test\r\n");
okini3939 1:a7b1803dfa44 185
okini3939 0:c5ba7d914282 186 printf("RAM write\r\n");
okini3939 0:c5ba7d914282 187 strcpy(buf, "Hello!");
okini3939 0:c5ba7d914282 188 ram_write(0, buf, 6);
okini3939 0:c5ba7d914282 189
okini3939 0:c5ba7d914282 190 for (i = 0; i < 256; i ++) {
okini3939 0:c5ba7d914282 191 buf[i] = i;
okini3939 0:c5ba7d914282 192 }
okini3939 2:a3e0f7f37ac9 193 ram_write(8, buf, 200);
okini3939 0:c5ba7d914282 194
okini3939 1:a7b1803dfa44 195 wait(1);
okini3939 0:c5ba7d914282 196 memset(buf, 0, 256);
okini3939 0:c5ba7d914282 197
okini3939 0:c5ba7d914282 198 printf("RAM read\r\n");
okini3939 0:c5ba7d914282 199 ram_read(0, buf, 256);
okini3939 0:c5ba7d914282 200 for (i = 0; i < 256; i ++) {
okini3939 0:c5ba7d914282 201 printf(" %02x", buf[i]);
okini3939 0:c5ba7d914282 202 if ((i & 0x0f) == 0x0f)
okini3939 0:c5ba7d914282 203 printf("\r\n");
okini3939 0:c5ba7d914282 204 }
okini3939 0:c5ba7d914282 205
okini3939 1:a7b1803dfa44 206 wait(1);
okini3939 1:a7b1803dfa44 207
okini3939 1:a7b1803dfa44 208 printf("\r\nWrite/Read time\r\n");
okini3939 1:a7b1803dfa44 209
okini3939 1:a7b1803dfa44 210 printf("RAM write\r\n");
okini3939 1:a7b1803dfa44 211 t.reset();
okini3939 1:a7b1803dfa44 212 t.start();
okini3939 1:a7b1803dfa44 213 for (i = 0; i < 0x20000; i += 256) {
okini3939 1:a7b1803dfa44 214 buf[0] = (i >> 8) & 0xff;
okini3939 1:a7b1803dfa44 215 ram_write(i, buf, 256);
okini3939 1:a7b1803dfa44 216 if ((i & 0x0fff) == 0) printf(".");
okini3939 0:c5ba7d914282 217 }
okini3939 1:a7b1803dfa44 218 t.stop();
okini3939 1:a7b1803dfa44 219 printf("\r\ntime %f, %f KBytes/sec\r\n", t.read(), (float)0x20000 / 1024 / t.read());
okini3939 1:a7b1803dfa44 220
okini3939 1:a7b1803dfa44 221 wait(1);
okini3939 1:a7b1803dfa44 222
okini3939 1:a7b1803dfa44 223 printf("RAM read\r\n");
okini3939 1:a7b1803dfa44 224 t.reset();
okini3939 1:a7b1803dfa44 225 t.start();
okini3939 1:a7b1803dfa44 226 for (i = 0; i < 0x20000; i += 256) {
okini3939 1:a7b1803dfa44 227 ram_read(i, buf, 256);
okini3939 1:a7b1803dfa44 228 if (buf[0] != ((i >> 8) & 0xff)) {
okini3939 1:a7b1803dfa44 229 printf("error %d\r\n", i);
okini3939 1:a7b1803dfa44 230 break;
okini3939 1:a7b1803dfa44 231 }
okini3939 1:a7b1803dfa44 232 if ((i & 0x0fff) == 0) printf(".");
okini3939 1:a7b1803dfa44 233 }
okini3939 1:a7b1803dfa44 234 t.stop();
okini3939 1:a7b1803dfa44 235 printf("\r\ntime %f, %f KBytes/sec\r\n", t.read(), 0x20000 / 1024 / t.read());
okini3939 1:a7b1803dfa44 236
okini3939 0:c5ba7d914282 237 }