SPI RAM 23LC1024 (Microchip) with DMA and FIFO
Fork of SPIRAM_23LC1024_DMA by
Diff: main.cpp
- Revision:
- 2:a3e0f7f37ac9
- Parent:
- 1:a7b1803dfa44
- Child:
- 3:cc45604ca53f
--- a/main.cpp Fri Nov 09 06:23:54 2012 +0000 +++ b/main.cpp Wed Dec 05 07:56:09 2012 +0000 @@ -1,8 +1,12 @@ /* * SPI RAM 23LC1024 (Microchip) * 1Mbit + * with DMA ( http://mbed.org/users/AjK/code/MODDMA/ ) */ #include "mbed.h" +#include "MODDMA.h" + +#define ENABLE_DMA #define CMD_READ 0x03 #define CMD_WRITE 0x02 @@ -13,20 +17,96 @@ Serial pc(USBTX, USBRX); SPI spi(p11, p12, p13); // mosi, miso, sclk -DigitalOut cs(p17), hold(p18); +DigitalOut cs(p14); + +MODDMA dma; +MODDMA_Config *dmacfg0 = NULL, *dmacfg1 = NULL; +DigitalOut led2(LED2), led3(LED3), led4(LED4); +volatile int dmaexit; + +extern "C" void HardFault_Handler() { + register unsigned int _msp __asm("msp"); + printf("Hard Fault! address: %08x\r\n", *((unsigned int *)(_msp + 24))); + exit(-1); +} + +void tc0_callback () { + led2 = 1; + + 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(); +} + +void tc1_callback () { + dmaexit = 1; + led3 = 1; + + 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(); +} + +void err_callback () { + dmaexit = 1; + led4 = 1; + printf("err\r\n"); +} int ram_write (int addr, char *buf, int len) { int i; + char dummy[len]; cs = 0; spi.write(CMD_WRITE); spi.write((addr >> 16) & 0xff); spi.write((addr >> 8) & 0xff); spi.write(addr & 0xff); + +#ifdef ENABLE_DMA + dmacfg0 + ->channelNum ( MODDMA::Channel_0 ) + ->srcMemAddr ( (uint32_t)buf ) + ->dstMemAddr ( MODDMA::SSP0_Tx ) + ->transferSize ( len ) + ->transferType ( MODDMA::m2p ) + ->dstConn ( MODDMA::SSP0_Tx ) + ->attach_tc ( &tc0_callback ) + ->attach_err ( &err_callback ) + ; // config end + dmacfg1 + ->channelNum ( MODDMA::Channel_1 ) + ->srcMemAddr ( MODDMA::SSP0_Rx ) + ->dstMemAddr ( (uint32_t)dummy ) + ->transferSize ( len ) + ->transferType ( MODDMA::p2m ) + ->srcConn ( MODDMA::SSP0_Rx ) + ->attach_tc ( &tc1_callback ) + ->attach_err ( &err_callback ) + ; // config end + + if (dma.Setup( dmacfg0 ) && dma.Setup( dmacfg1 )) { + dmaexit = 0; + LPC_SSP0->DMACR = (1<<1)|(1<<0); // TX,RXDMAE + dma.Enable( dmacfg0 ); + dma.Enable( dmacfg1 ); + while (! dmaexit); + } else { + printf("error\r\n"); + } + LPC_SSP0->DMACR = 0; +#else for (i = 0; i < len; i ++) { spi.write(buf[i]); } +#endif cs = 1; return i; } @@ -40,9 +120,44 @@ spi.write((addr >> 8) & 0xff); spi.write(addr & 0xff); +#ifdef ENABLE_DMA + dmacfg0 + ->channelNum ( MODDMA::Channel_0 ) + ->srcMemAddr ( (uint32_t)buf ) + ->dstMemAddr ( MODDMA::SSP0_Tx ) + ->transferSize ( len ) + ->transferType ( MODDMA::m2p ) + ->dstConn ( MODDMA::SSP0_Tx ) + ->attach_tc ( &tc0_callback ) + ->attach_err ( &err_callback ) + ; // config end + + dmacfg1 + ->channelNum ( MODDMA::Channel_1 ) + ->srcMemAddr ( MODDMA::SSP0_Rx ) + ->dstMemAddr ( (uint32_t)buf ) + ->transferSize ( len ) + ->transferType ( MODDMA::p2m ) + ->srcConn ( MODDMA::SSP0_Rx ) + ->attach_tc ( &tc1_callback ) + ->attach_err ( &err_callback ) + ; // config end + + if (dma.Setup( dmacfg0 ) && dma.Setup( dmacfg1 )) { + dmaexit = 0; + LPC_SSP0->DMACR = (1<<1)|(1<<0); // TX,RXDMAE + dma.Enable( dmacfg0 ); + dma.Enable( dmacfg1 ); + while (! dmaexit); + } else { + printf("error\r\n"); + } + LPC_SSP0->DMACR = 0; +#else for (i = 0; i < len; i ++) { buf[i] = spi.write(0); } +#endif cs = 1; return i; } @@ -53,11 +168,14 @@ Timer t; cs = 1; - hold = 1; +#ifdef ENABLE_DMA + dmacfg0 = new MODDMA_Config; + dmacfg1 = new MODDMA_Config; +#endif pc.baud(115200); spi.frequency(16000000); wait_ms(500); - + cs = 0; spi.write(CMD_RDMR); printf("RAM mode: %02x\r\n", spi.write(0)); @@ -72,7 +190,7 @@ for (i = 0; i < 256; i ++) { buf[i] = i; } - ram_write(6, buf, 256); + ram_write(8, buf, 200); wait(1); memset(buf, 0, 256);