Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
example4.h@1:b6ae9e61d764, 2014-12-06 (annotated)
- Committer:
- tohu
- Date:
- Sat Dec 06 10:45:10 2014 +0000
- Revision:
- 1:b6ae9e61d764
Ickefungerande f?rstaversion
Who changed what in which revision?
User | Revision | Line number | New 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 | } |