http://http://diytec.web.fc2.com/mark2r2/

Dependencies:   EthernetNetIf NTPClient_NetServices mbed ConfigFile

Committer:
mark2r2
Date:
Tue Sep 20 12:46:26 2011 +0000
Revision:
0:08a4d61cd84c
V1.0

Who changed what in which revision?

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