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
00001 /* 00002 * Demonstrates sending a buffer repeatedly to the DAC using DMA. 00003 * Connect an oscilloscope to Mbed pin 18. This example doesn't 00004 * output anything else (nothing on any serial ports). 00005 */ 00006 #include "mbed.h" 00007 #include "MODDMA.h" 00008 00009 // Make the buffer size match the number of degrees 00010 // in a circle since we are going to output a sinewave. 00011 #define BUFFER_SIZE 360 00012 00013 // Set DAC output power mode. 00014 #define DAC_POWER_MODE (1 << 16) 00015 00016 DigitalOut led1(LED1); 00017 DigitalOut led3(LED3); 00018 DigitalOut led4(LED4); 00019 00020 int buffer[2][BUFFER_SIZE]; 00021 00022 AnalogOut signal(p18); 00023 00024 MODDMA dma; 00025 MODDMA_Config *conf0, *conf1; 00026 00027 void TC0_callback(void); 00028 void ERR0_callback(void); 00029 00030 void TC1_callback(void); 00031 void ERR1_callback(void); 00032 00033 int main() { 00034 volatile int life_counter = 0; 00035 00036 // Create a sinewave buffer for testing. 00037 for (int i = 0; i <= 90; i++) buffer[0][i] = (512 * sin(3.14159/180.0 * i)) + 512; 00038 for (int i = 91; i <= 180; i++) buffer[0][i] = buffer[0][180 - i]; 00039 for (int i = 181; i <= 270; i++) buffer[0][i] = 512 - (buffer[0][i - 180] - 512); 00040 for (int i = 271; i < 360; i++) buffer[0][i] = 512 - (buffer[0][360 - i] - 512); 00041 00042 // Adjust the sinewave buffer for use with DAC hardware. 00043 for (int i = 0; i < 360; i++) { 00044 buffer[0][i] = DAC_POWER_MODE | ((buffer[0][i] << 6) & 0xFFC0); 00045 buffer[1][i] = buffer[0][i]; // Just create a copy of buffer0 to continue sinewave. 00046 } 00047 00048 // Prepare the GPDMA system for buffer0. 00049 conf0 = new MODDMA_Config; 00050 conf0 00051 ->channelNum ( MODDMA::Channel_0 ) 00052 ->srcMemAddr ( (uint32_t) &buffer[0] ) 00053 ->dstMemAddr ( MODDMA::DAC ) 00054 ->transferSize ( 360 ) 00055 ->transferType ( MODDMA::m2p ) 00056 ->dstConn ( MODDMA::DAC ) 00057 ->attach_tc ( &TC0_callback ) 00058 ->attach_err ( &ERR0_callback ) 00059 ; // config end 00060 00061 00062 // Prepare the GPDMA system for buffer1. 00063 conf1 = new MODDMA_Config; 00064 conf1 00065 ->channelNum ( MODDMA::Channel_1 ) 00066 ->srcMemAddr ( (uint32_t) &buffer[1] ) 00067 ->dstMemAddr ( MODDMA::DAC ) 00068 ->transferSize ( 360 ) 00069 ->transferType ( MODDMA::m2p ) 00070 ->dstConn ( MODDMA::DAC ) 00071 ->attach_tc ( &TC1_callback ) 00072 ->attach_err ( &ERR1_callback ) 00073 ; // config end 00074 00075 00076 // Calculating the transfer frequency: 00077 // By default, the Mbed library sets the PCLK_DAC clock value 00078 // to 24MHz. One complete sinewave cycle in each buffer is 360 00079 // points long. So, for a 1Hz wave we would need to transfer 360 00080 // values per second. That would be 24000000/360 which is approx 00081 // 66,666. But that's no good! The count val is only 16bits in size 00082 // so bare this in mind. If you need to go slower you will need to 00083 // alter PCLK_DAC from CCLK/4 to CCLK/8. 00084 // For our demo we are going to have the sinewave run at 1kHz. 00085 // That's 24000000/360000 which is approx 66. Experimentation 00086 // however showed 65 to get closer to 1kHz (on my Mbed and scope 00087 // at least). 00088 LPC_DAC->DACCNTVAL = 65; // 6500 for 10Hz 00089 00090 // Prepare first configuration. 00091 if (!dma.Prepare( conf0 )) { 00092 error("Doh!"); 00093 } 00094 00095 // Begin (enable DMA and counter). Note, don't enable 00096 // DBLBUF_ENA as we are using DMA double buffering. 00097 LPC_DAC->DACCTRL |= (3UL << 2); 00098 00099 while (1) { 00100 // There's not a lot to do as DMA and interrupts are 00101 // now handling the buffer transfers. So we'll just 00102 // flash led1 to show the Mbed is alive and kicking. 00103 if (life_counter++ > 1000000) { 00104 led1 = !led1; // Show some sort of life. 00105 life_counter = 0; 00106 } 00107 } 00108 } 00109 00110 // Configuration callback on TC 00111 void TC0_callback(void) { 00112 00113 // Just show sending buffer0 complete. 00114 led3 = !led3; 00115 00116 // Get configuration pointer. 00117 MODDMA_Config *config = dma.getConfig(); 00118 00119 // Finish the DMA cycle by shutting down the channel. 00120 dma.Disable( (MODDMA::CHANNELS)config->channelNum() ); 00121 00122 // Swap to buffer1 00123 dma.Prepare( conf1 ); 00124 00125 // Clear DMA IRQ flags. 00126 if (dma.irqType() == MODDMA::TcIrq) dma.clearTcIrq(); 00127 } 00128 00129 // Configuration callback on Error 00130 void ERR0_callback(void) { 00131 error("Oh no! My Mbed EXPLODED! :( Only kidding, go find the problem"); 00132 } 00133 00134 // Configuration callback on TC 00135 void TC1_callback(void) { 00136 00137 // Just show sending buffer1 complete. 00138 led4 = !led4; 00139 00140 // Get configuration pointer. 00141 MODDMA_Config *config = dma.getConfig(); 00142 00143 // Finish the DMA cycle by shutting down the channel. 00144 dma.Disable( (MODDMA::CHANNELS)config->channelNum() ); 00145 00146 // Swap to buffer0 00147 dma.Prepare( conf0 ); 00148 00149 // Clear DMA IRQ flags. 00150 if (dma.irqType() == MODDMA::TcIrq) dma.clearTcIrq(); 00151 } 00152 00153 // Configuration callback on Error 00154 void ERR1_callback(void) { 00155 error("Oh no! My Mbed EXPLODED! :( Only kidding, go find the problem"); 00156 }
Generated on Sun Jul 17 2022 00:13:08 by
1.7.2