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
DMX

Who changed what in which revision?

UserRevisionLine numberNew contents of line
okini3939 2:a3e0f7f37ac9 1 /*
okini3939 2:a3e0f7f37ac9 2 * Demonstrates capturing the GPIO P0.4 to P0.7 "nibble" to memory
okini3939 2:a3e0f7f37ac9 3 * using GPDMA. The transfers from port pins to memory buffer are
okini3939 2:a3e0f7f37ac9 4 * triggered using Timer1 MAT1.0 match compare.
okini3939 2:a3e0f7f37ac9 5 *
okini3939 2:a3e0f7f37ac9 6 * In this example all inputs have pullups. So with nothing connected
okini3939 2:a3e0f7f37ac9 7 * the P0.4/7 reads as 0xF. Connecting a wire from one or more of the four
okini3939 2:a3e0f7f37ac9 8 * inputs to ground will show up in the captured buffer sequence.
okini3939 2:a3e0f7f37ac9 9 */
okini3939 2:a3e0f7f37ac9 10
okini3939 2:a3e0f7f37ac9 11 #include "mbed.h"
okini3939 2:a3e0f7f37ac9 12 #include "MODDMA.h"
okini3939 2:a3e0f7f37ac9 13 #include "iomacros.h" // within MODDMA library.
okini3939 2:a3e0f7f37ac9 14
okini3939 2:a3e0f7f37ac9 15 // How long between grabbing GPIO FIO0PIN register.
okini3939 2:a3e0f7f37ac9 16 // Value is in microseconds. (500000 is half a second).
okini3939 2:a3e0f7f37ac9 17 #define SAMPLE_PERIOD 500000
okini3939 2:a3e0f7f37ac9 18
okini3939 2:a3e0f7f37ac9 19 #define NUM_OF_SAMPLES 5
okini3939 2:a3e0f7f37ac9 20
okini3939 2:a3e0f7f37ac9 21 Serial pc(USBTX, USBRX);
okini3939 2:a3e0f7f37ac9 22
okini3939 2:a3e0f7f37ac9 23 DigitalOut led1(LED1);
okini3939 2:a3e0f7f37ac9 24 DigitalOut led2(LED2);
okini3939 2:a3e0f7f37ac9 25 DigitalOut led3(LED3);
okini3939 2:a3e0f7f37ac9 26
okini3939 2:a3e0f7f37ac9 27 uint32_t buffer[NUM_OF_SAMPLES];
okini3939 2:a3e0f7f37ac9 28
okini3939 2:a3e0f7f37ac9 29 bool dmaTransferComplete;
okini3939 2:a3e0f7f37ac9 30
okini3939 2:a3e0f7f37ac9 31 MODDMA dma;
okini3939 2:a3e0f7f37ac9 32 MODDMA_Config *conf;
okini3939 2:a3e0f7f37ac9 33
okini3939 2:a3e0f7f37ac9 34 void TC0_callback(void);
okini3939 2:a3e0f7f37ac9 35 void ERR0_callback(void);
okini3939 2:a3e0f7f37ac9 36
okini3939 2:a3e0f7f37ac9 37 int main() {
okini3939 2:a3e0f7f37ac9 38 volatile int life_counter = 0;
okini3939 2:a3e0f7f37ac9 39
okini3939 2:a3e0f7f37ac9 40 // Macros defined in iomacros.h, saves messing with DigitalIn
okini3939 2:a3e0f7f37ac9 41 p30_AS_INPUT; p30_MODE( PIN_PULLUP ); // P0.4
okini3939 2:a3e0f7f37ac9 42 p29_AS_INPUT; p29_MODE( PIN_PULLUP ); // P0.5
okini3939 2:a3e0f7f37ac9 43 p8_AS_INPUT; p8_MODE( PIN_PULLUP ); // P0.6
okini3939 2:a3e0f7f37ac9 44 p7_AS_INPUT; p7_MODE( PIN_PULLUP ); // P0.7
okini3939 2:a3e0f7f37ac9 45
okini3939 2:a3e0f7f37ac9 46 // Clear the buffer.
okini3939 2:a3e0f7f37ac9 47 memset(buffer, 0, sizeof(buffer));
okini3939 2:a3e0f7f37ac9 48
okini3939 2:a3e0f7f37ac9 49 // Setup the serial port to print out results.
okini3939 2:a3e0f7f37ac9 50 pc.baud(115200);
okini3939 2:a3e0f7f37ac9 51 pc.printf("Starting up...\n");
okini3939 2:a3e0f7f37ac9 52
okini3939 2:a3e0f7f37ac9 53 // Set-up timer1 as a periodic timer.
okini3939 2:a3e0f7f37ac9 54 LPC_SC->PCONP |= (1UL << 2); // TIM1 On
okini3939 2:a3e0f7f37ac9 55 LPC_SC->PCLKSEL0 |= (3UL << 4); // CCLK/8 = 12MHz
okini3939 2:a3e0f7f37ac9 56 LPC_TIM1->PR = 11; // TC clocks at 1MHz.
okini3939 2:a3e0f7f37ac9 57 LPC_TIM1->MCR = 2; // Reset TCR to zero on match.
okini3939 2:a3e0f7f37ac9 58 LPC_TIM1->MR0 = SAMPLE_PERIOD;
okini3939 2:a3e0f7f37ac9 59
okini3939 2:a3e0f7f37ac9 60 // Prepare the GPDMA system.
okini3939 2:a3e0f7f37ac9 61 conf = new MODDMA_Config;
okini3939 2:a3e0f7f37ac9 62 conf
okini3939 2:a3e0f7f37ac9 63 ->channelNum ( MODDMA::Channel_0 )
okini3939 2:a3e0f7f37ac9 64 ->srcMemAddr ( (uint32_t)&LPC_GPIO0->FIOPIN )
okini3939 2:a3e0f7f37ac9 65 ->dstMemAddr ( (uint32_t)&buffer[0] )
okini3939 2:a3e0f7f37ac9 66 ->transferSize ( NUM_OF_SAMPLES )
okini3939 2:a3e0f7f37ac9 67 ->transferType ( MODDMA::g2m ) // pseudo transfer code MODDMA understands.
okini3939 2:a3e0f7f37ac9 68 ->transferWidth ( MODDMA::word )
okini3939 2:a3e0f7f37ac9 69 ->srcConn ( MODDMA::MAT1_0 )
okini3939 2:a3e0f7f37ac9 70 ->dmacSync ( MODDMA::MAT1_0 )
okini3939 2:a3e0f7f37ac9 71 ->attach_tc ( TC0_callback )
okini3939 2:a3e0f7f37ac9 72 ->attach_err ( ERR0_callback )
okini3939 2:a3e0f7f37ac9 73 ; // end conf.
okini3939 2:a3e0f7f37ac9 74
okini3939 2:a3e0f7f37ac9 75 // Prepare configuration.
okini3939 2:a3e0f7f37ac9 76 if (!dma.Setup( conf )) {
okini3939 2:a3e0f7f37ac9 77 error("Doh!");
okini3939 2:a3e0f7f37ac9 78 }
okini3939 2:a3e0f7f37ac9 79
okini3939 2:a3e0f7f37ac9 80 // Enable GPDMA to be ready for the TIM1 "ticks".
okini3939 2:a3e0f7f37ac9 81 dma.Enable( conf );
okini3939 2:a3e0f7f37ac9 82
okini3939 2:a3e0f7f37ac9 83 // Begin.
okini3939 2:a3e0f7f37ac9 84 LPC_TIM1->TCR = 1;
okini3939 2:a3e0f7f37ac9 85
okini3939 2:a3e0f7f37ac9 86 while (1) {
okini3939 2:a3e0f7f37ac9 87 if (life_counter++ > 1000000) {
okini3939 2:a3e0f7f37ac9 88 led1 = !led1; // Show some sort of life.
okini3939 2:a3e0f7f37ac9 89 life_counter = 0;
okini3939 2:a3e0f7f37ac9 90 }
okini3939 2:a3e0f7f37ac9 91
okini3939 2:a3e0f7f37ac9 92 if (dmaTransferComplete) {
okini3939 2:a3e0f7f37ac9 93 dmaTransferComplete = false;
okini3939 2:a3e0f7f37ac9 94 for (int i = 0; i < NUM_OF_SAMPLES; i++) {
okini3939 2:a3e0f7f37ac9 95 int val = (buffer[i] >> 4) & 0xF;
okini3939 2:a3e0f7f37ac9 96 pc.printf("Buffer index %d = 0x%x\n", i, val);
okini3939 2:a3e0f7f37ac9 97 }
okini3939 2:a3e0f7f37ac9 98 pc.printf("Done.\n");
okini3939 2:a3e0f7f37ac9 99
okini3939 2:a3e0f7f37ac9 100 // Schedule another grab.
okini3939 2:a3e0f7f37ac9 101 if (dma.Setup( conf )) {
okini3939 2:a3e0f7f37ac9 102 dma.Enable( conf );
okini3939 2:a3e0f7f37ac9 103 }
okini3939 2:a3e0f7f37ac9 104 }
okini3939 2:a3e0f7f37ac9 105 }
okini3939 2:a3e0f7f37ac9 106 }
okini3939 2:a3e0f7f37ac9 107
okini3939 2:a3e0f7f37ac9 108 // Configuration callback on TC
okini3939 2:a3e0f7f37ac9 109 void TC0_callback(void) {
okini3939 2:a3e0f7f37ac9 110
okini3939 2:a3e0f7f37ac9 111 // Just show sample sequence grab complete.
okini3939 2:a3e0f7f37ac9 112 led3 = !led3;
okini3939 2:a3e0f7f37ac9 113
okini3939 2:a3e0f7f37ac9 114 // Get configuration pointer.
okini3939 2:a3e0f7f37ac9 115 MODDMA_Config *config = dma.getConfig();
okini3939 2:a3e0f7f37ac9 116
okini3939 2:a3e0f7f37ac9 117 // Finish the DMA cycle by shutting down the channel.
okini3939 2:a3e0f7f37ac9 118 dma.Disable( (MODDMA::CHANNELS)config->channelNum() );
okini3939 2:a3e0f7f37ac9 119
okini3939 2:a3e0f7f37ac9 120 // Tell main() while(1) loop to print the results.
okini3939 2:a3e0f7f37ac9 121 dmaTransferComplete = true;
okini3939 2:a3e0f7f37ac9 122
okini3939 2:a3e0f7f37ac9 123 // Clear DMA IRQ flags.
okini3939 2:a3e0f7f37ac9 124 if (dma.irqType() == MODDMA::TcIrq) dma.clearTcIrq();
okini3939 2:a3e0f7f37ac9 125 if (dma.irqType() == MODDMA::ErrIrq) dma.clearErrIrq();
okini3939 2:a3e0f7f37ac9 126 }
okini3939 2:a3e0f7f37ac9 127
okini3939 2:a3e0f7f37ac9 128 // Configuration callback on Error
okini3939 2:a3e0f7f37ac9 129 void ERR0_callback(void) {
okini3939 2:a3e0f7f37ac9 130 error("Oh no! My Mbed EXPLODED! :( Only kidding, go find the problem");
okini3939 2:a3e0f7f37ac9 131 }