Tomas Hübner / Mbed 2 deprecated DMANeoPixel

Dependencies:   MODDMA mbed

Committer:
tohu
Date:
Sat Dec 06 10:45:10 2014 +0000
Revision:
1:b6ae9e61d764
Ickefungerande f?rstaversion

Who changed what in which revision?

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