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 sending a buffer repeatedly to the DAC using DMA.
okini3939 2:a3e0f7f37ac9 3 * Connect an oscilloscope to Mbed pin 18. This example doesn't
okini3939 2:a3e0f7f37ac9 4 * output anything else (nothing on any serial ports).
okini3939 2:a3e0f7f37ac9 5 */
okini3939 2:a3e0f7f37ac9 6 #include "mbed.h"
okini3939 2:a3e0f7f37ac9 7 #include "MODDMA.h"
okini3939 2:a3e0f7f37ac9 8
okini3939 2:a3e0f7f37ac9 9 // Make the buffer size match the number of degrees
okini3939 2:a3e0f7f37ac9 10 // in a circle since we are going to output a sinewave.
okini3939 2:a3e0f7f37ac9 11 #define BUFFER_SIZE 360
okini3939 2:a3e0f7f37ac9 12
okini3939 2:a3e0f7f37ac9 13 // Set DAC output power mode.
okini3939 2:a3e0f7f37ac9 14 #define DAC_POWER_MODE (1 << 16)
okini3939 2:a3e0f7f37ac9 15
okini3939 2:a3e0f7f37ac9 16 DigitalOut led1(LED1);
okini3939 2:a3e0f7f37ac9 17 DigitalOut led3(LED3);
okini3939 2:a3e0f7f37ac9 18 DigitalOut led4(LED4);
okini3939 2:a3e0f7f37ac9 19
okini3939 2:a3e0f7f37ac9 20 int buffer[2][BUFFER_SIZE];
okini3939 2:a3e0f7f37ac9 21
okini3939 2:a3e0f7f37ac9 22 AnalogOut signal(p18);
okini3939 2:a3e0f7f37ac9 23
okini3939 2:a3e0f7f37ac9 24 MODDMA dma;
okini3939 2:a3e0f7f37ac9 25 MODDMA_Config *conf0, *conf1;
okini3939 2:a3e0f7f37ac9 26
okini3939 2:a3e0f7f37ac9 27 void TC0_callback(void);
okini3939 2:a3e0f7f37ac9 28 void ERR0_callback(void);
okini3939 2:a3e0f7f37ac9 29
okini3939 2:a3e0f7f37ac9 30 void TC1_callback(void);
okini3939 2:a3e0f7f37ac9 31 void ERR1_callback(void);
okini3939 2:a3e0f7f37ac9 32
okini3939 2:a3e0f7f37ac9 33 int main() {
okini3939 2:a3e0f7f37ac9 34 volatile int life_counter = 0;
okini3939 2:a3e0f7f37ac9 35
okini3939 2:a3e0f7f37ac9 36 // Create a sinewave buffer for testing.
okini3939 2:a3e0f7f37ac9 37 for (int i = 0; i <= 90; i++) buffer[0][i] = (512 * sin(3.14159/180.0 * i)) + 512;
okini3939 2:a3e0f7f37ac9 38 for (int i = 91; i <= 180; i++) buffer[0][i] = buffer[0][180 - i];
okini3939 2:a3e0f7f37ac9 39 for (int i = 181; i <= 270; i++) buffer[0][i] = 512 - (buffer[0][i - 180] - 512);
okini3939 2:a3e0f7f37ac9 40 for (int i = 271; i < 360; i++) buffer[0][i] = 512 - (buffer[0][360 - i] - 512);
okini3939 2:a3e0f7f37ac9 41
okini3939 2:a3e0f7f37ac9 42 // Adjust the sinewave buffer for use with DAC hardware.
okini3939 2:a3e0f7f37ac9 43 for (int i = 0; i < 360; i++) {
okini3939 2:a3e0f7f37ac9 44 buffer[0][i] = DAC_POWER_MODE | ((buffer[0][i] << 6) & 0xFFC0);
okini3939 2:a3e0f7f37ac9 45 buffer[1][i] = buffer[0][i]; // Just create a copy of buffer0 to continue sinewave.
okini3939 2:a3e0f7f37ac9 46 }
okini3939 2:a3e0f7f37ac9 47
okini3939 2:a3e0f7f37ac9 48 // Prepare the GPDMA system for buffer0.
okini3939 2:a3e0f7f37ac9 49 conf0 = new MODDMA_Config;
okini3939 2:a3e0f7f37ac9 50 conf0
okini3939 2:a3e0f7f37ac9 51 ->channelNum ( MODDMA::Channel_0 )
okini3939 2:a3e0f7f37ac9 52 ->srcMemAddr ( (uint32_t) &buffer[0] )
okini3939 2:a3e0f7f37ac9 53 ->dstMemAddr ( MODDMA::DAC )
okini3939 2:a3e0f7f37ac9 54 ->transferSize ( 360 )
okini3939 2:a3e0f7f37ac9 55 ->transferType ( MODDMA::m2p )
okini3939 2:a3e0f7f37ac9 56 ->dstConn ( MODDMA::DAC )
okini3939 2:a3e0f7f37ac9 57 ->attach_tc ( &TC0_callback )
okini3939 2:a3e0f7f37ac9 58 ->attach_err ( &ERR0_callback )
okini3939 2:a3e0f7f37ac9 59 ; // config end
okini3939 2:a3e0f7f37ac9 60
okini3939 2:a3e0f7f37ac9 61
okini3939 2:a3e0f7f37ac9 62 // Prepare the GPDMA system for buffer1.
okini3939 2:a3e0f7f37ac9 63 conf1 = new MODDMA_Config;
okini3939 2:a3e0f7f37ac9 64 conf1
okini3939 2:a3e0f7f37ac9 65 ->channelNum ( MODDMA::Channel_1 )
okini3939 2:a3e0f7f37ac9 66 ->srcMemAddr ( (uint32_t) &buffer[1] )
okini3939 2:a3e0f7f37ac9 67 ->dstMemAddr ( MODDMA::DAC )
okini3939 2:a3e0f7f37ac9 68 ->transferSize ( 360 )
okini3939 2:a3e0f7f37ac9 69 ->transferType ( MODDMA::m2p )
okini3939 2:a3e0f7f37ac9 70 ->dstConn ( MODDMA::DAC )
okini3939 2:a3e0f7f37ac9 71 ->attach_tc ( &TC1_callback )
okini3939 2:a3e0f7f37ac9 72 ->attach_err ( &ERR1_callback )
okini3939 2:a3e0f7f37ac9 73 ; // config end
okini3939 2:a3e0f7f37ac9 74
okini3939 2:a3e0f7f37ac9 75
okini3939 2:a3e0f7f37ac9 76 // Calculating the transfer frequency:
okini3939 2:a3e0f7f37ac9 77 // By default, the Mbed library sets the PCLK_DAC clock value
okini3939 2:a3e0f7f37ac9 78 // to 24MHz. One complete sinewave cycle in each buffer is 360
okini3939 2:a3e0f7f37ac9 79 // points long. So, for a 1Hz wave we would need to transfer 360
okini3939 2:a3e0f7f37ac9 80 // values per second. That would be 24000000/360 which is approx
okini3939 2:a3e0f7f37ac9 81 // 66,666. But that's no good! The count val is only 16bits in size
okini3939 2:a3e0f7f37ac9 82 // so bare this in mind. If you need to go slower you will need to
okini3939 2:a3e0f7f37ac9 83 // alter PCLK_DAC from CCLK/4 to CCLK/8.
okini3939 2:a3e0f7f37ac9 84 // For our demo we are going to have the sinewave run at 1kHz.
okini3939 2:a3e0f7f37ac9 85 // That's 24000000/360000 which is approx 66. Experimentation
okini3939 2:a3e0f7f37ac9 86 // however showed 65 to get closer to 1kHz (on my Mbed and scope
okini3939 2:a3e0f7f37ac9 87 // at least).
okini3939 2:a3e0f7f37ac9 88 LPC_DAC->DACCNTVAL = 65; // 6500 for 10Hz
okini3939 2:a3e0f7f37ac9 89
okini3939 2:a3e0f7f37ac9 90 // Prepare first configuration.
okini3939 2:a3e0f7f37ac9 91 if (!dma.Prepare( conf0 )) {
okini3939 2:a3e0f7f37ac9 92 error("Doh!");
okini3939 2:a3e0f7f37ac9 93 }
okini3939 2:a3e0f7f37ac9 94
okini3939 2:a3e0f7f37ac9 95 // Begin (enable DMA and counter). Note, don't enable
okini3939 2:a3e0f7f37ac9 96 // DBLBUF_ENA as we are using DMA double buffering.
okini3939 2:a3e0f7f37ac9 97 LPC_DAC->DACCTRL |= (3UL << 2);
okini3939 2:a3e0f7f37ac9 98
okini3939 2:a3e0f7f37ac9 99 while (1) {
okini3939 2:a3e0f7f37ac9 100 // There's not a lot to do as DMA and interrupts are
okini3939 2:a3e0f7f37ac9 101 // now handling the buffer transfers. So we'll just
okini3939 2:a3e0f7f37ac9 102 // flash led1 to show the Mbed is alive and kicking.
okini3939 2:a3e0f7f37ac9 103 if (life_counter++ > 1000000) {
okini3939 2:a3e0f7f37ac9 104 led1 = !led1; // Show some sort of life.
okini3939 2:a3e0f7f37ac9 105 life_counter = 0;
okini3939 2:a3e0f7f37ac9 106 }
okini3939 2:a3e0f7f37ac9 107 }
okini3939 2:a3e0f7f37ac9 108 }
okini3939 2:a3e0f7f37ac9 109
okini3939 2:a3e0f7f37ac9 110 // Configuration callback on TC
okini3939 2:a3e0f7f37ac9 111 void TC0_callback(void) {
okini3939 2:a3e0f7f37ac9 112
okini3939 2:a3e0f7f37ac9 113 // Just show sending buffer0 complete.
okini3939 2:a3e0f7f37ac9 114 led3 = !led3;
okini3939 2:a3e0f7f37ac9 115
okini3939 2:a3e0f7f37ac9 116 // Get configuration pointer.
okini3939 2:a3e0f7f37ac9 117 MODDMA_Config *config = dma.getConfig();
okini3939 2:a3e0f7f37ac9 118
okini3939 2:a3e0f7f37ac9 119 // Finish the DMA cycle by shutting down the channel.
okini3939 2:a3e0f7f37ac9 120 dma.Disable( (MODDMA::CHANNELS)config->channelNum() );
okini3939 2:a3e0f7f37ac9 121
okini3939 2:a3e0f7f37ac9 122 // Swap to buffer1
okini3939 2:a3e0f7f37ac9 123 dma.Prepare( conf1 );
okini3939 2:a3e0f7f37ac9 124
okini3939 2:a3e0f7f37ac9 125 // Clear DMA IRQ flags.
okini3939 2:a3e0f7f37ac9 126 if (dma.irqType() == MODDMA::TcIrq) dma.clearTcIrq();
okini3939 2:a3e0f7f37ac9 127 }
okini3939 2:a3e0f7f37ac9 128
okini3939 2:a3e0f7f37ac9 129 // Configuration callback on Error
okini3939 2:a3e0f7f37ac9 130 void ERR0_callback(void) {
okini3939 2:a3e0f7f37ac9 131 error("Oh no! My Mbed EXPLODED! :( Only kidding, go find the problem");
okini3939 2:a3e0f7f37ac9 132 }
okini3939 2:a3e0f7f37ac9 133
okini3939 2:a3e0f7f37ac9 134 // Configuration callback on TC
okini3939 2:a3e0f7f37ac9 135 void TC1_callback(void) {
okini3939 2:a3e0f7f37ac9 136
okini3939 2:a3e0f7f37ac9 137 // Just show sending buffer1 complete.
okini3939 2:a3e0f7f37ac9 138 led4 = !led4;
okini3939 2:a3e0f7f37ac9 139
okini3939 2:a3e0f7f37ac9 140 // Get configuration pointer.
okini3939 2:a3e0f7f37ac9 141 MODDMA_Config *config = dma.getConfig();
okini3939 2:a3e0f7f37ac9 142
okini3939 2:a3e0f7f37ac9 143 // Finish the DMA cycle by shutting down the channel.
okini3939 2:a3e0f7f37ac9 144 dma.Disable( (MODDMA::CHANNELS)config->channelNum() );
okini3939 2:a3e0f7f37ac9 145
okini3939 2:a3e0f7f37ac9 146 // Swap to buffer0
okini3939 2:a3e0f7f37ac9 147 dma.Prepare( conf0 );
okini3939 2:a3e0f7f37ac9 148
okini3939 2:a3e0f7f37ac9 149 // Clear DMA IRQ flags.
okini3939 2:a3e0f7f37ac9 150 if (dma.irqType() == MODDMA::TcIrq) dma.clearTcIrq();
okini3939 2:a3e0f7f37ac9 151 }
okini3939 2:a3e0f7f37ac9 152
okini3939 2:a3e0f7f37ac9 153 // Configuration callback on Error
okini3939 2:a3e0f7f37ac9 154 void ERR1_callback(void) {
okini3939 2:a3e0f7f37ac9 155 error("Oh no! My Mbed EXPLODED! :( Only kidding, go find the problem");
okini3939 2:a3e0f7f37ac9 156 }