MODDMA GPDMA Controller New features: transfer pins to memory buffer under periodic timer control and send double buffers to DAC
Dependents: FirstTest WaveSim IO-dma-memmem DACDMAfuncgenlib ... more
example2.h
00001 /* 00002 * This example was provided to support Mbed forum thread:- 00003 * http://mbed.org/forum/mbed/topic/1798 00004 */ 00005 00006 #include "mbed.h" 00007 #include "MODDMA.h" 00008 00009 #define SAMPLE_BUFFER_LENGTH 32 00010 00011 DigitalOut led1(LED1); 00012 DigitalOut led2(LED2); 00013 00014 MODDMA dma; 00015 Serial pc(USBTX, USBRX); 00016 00017 // ISR set's this when transfer complete. 00018 bool dmaTransferComplete = false; 00019 00020 // Function prototypes for IRQ callbacks. 00021 // See definitions following main() below. 00022 void TC0_callback(void); 00023 void ERR0_callback(void); 00024 00025 int main() { 00026 00027 // Create a buffer to hold the ADC samples and clear it. 00028 // Note, we are going to sample two ADC inputs so they 00029 // end up in this buffer "interleaved". So you will want 00030 // a buffer twice this size to a real life given sample 00031 // frequency. See the printf() output for details. 00032 uint32_t adcInputBuffer[SAMPLE_BUFFER_LENGTH]; 00033 memset(adcInputBuffer, 0, sizeof(adcInputBuffer)); 00034 00035 // We use the ADC irq to trigger DMA and the manual says 00036 // that in this case the NVIC for ADC must be disabled. 00037 NVIC_DisableIRQ(ADC_IRQn); 00038 00039 // Power up the ADC and set PCLK 00040 LPC_SC->PCONP |= (1UL << 12); 00041 LPC_SC->PCLKSEL0 &= ~(3UL << 24); // PCLK = CCLK/4 96M/4 = 24MHz 00042 00043 // Enable the ADC, 12MHz, ADC0.0 & .1 00044 LPC_ADC->ADCR = (1UL << 21) | (1UL << 8) | (3UL << 0); 00045 00046 // Set the pin functions to ADC 00047 LPC_PINCON->PINSEL1 &= ~(3UL << 14); /* P0.23, Mbed p15. */ 00048 LPC_PINCON->PINSEL1 |= (1UL << 14); 00049 LPC_PINCON->PINSEL1 &= ~(3UL << 16); /* P0.24, Mbed p16. */ 00050 LPC_PINCON->PINSEL1 |= (1UL << 16); 00051 00052 // Setup the serial port to print out results. 00053 pc.baud(115200); 00054 pc.printf("ADC with DMA example\n"); 00055 pc.printf("====================\n"); 00056 00057 // Prepare an ADC configuration. 00058 MODDMA_Config *conf = new MODDMA_Config; 00059 conf 00060 ->channelNum ( MODDMA::Channel_0 ) 00061 ->srcMemAddr ( 0 ) 00062 ->dstMemAddr ( (uint32_t)adcInputBuffer ) 00063 ->transferSize ( SAMPLE_BUFFER_LENGTH ) 00064 ->transferType ( MODDMA::p2m ) 00065 ->transferWidth ( MODDMA::word ) 00066 ->srcConn ( MODDMA::ADC ) 00067 ->dstConn ( 0 ) 00068 ->dmaLLI ( 0 ) 00069 ->attach_tc ( &TC0_callback ) 00070 ->attach_err ( &ERR0_callback ) 00071 ; // end conf. 00072 00073 // Prepare configuration. 00074 dma.Setup( conf ); 00075 00076 // Enable configuration. 00077 dma.Enable( conf ); 00078 00079 // Enable ADC irq flag (to DMA). 00080 // Note, don't set the individual flags, 00081 // just set the global flag. 00082 LPC_ADC->ADINTEN = 0x100; 00083 00084 // Enable burst mode on inputs 0 and 1. 00085 LPC_ADC->ADCR |= (1UL << 16); 00086 00087 while (1) { 00088 // When transfer complete do this block. 00089 if (dmaTransferComplete) { 00090 delete conf; // No memory leaks, delete the configuration. 00091 dmaTransferComplete = false; 00092 for (int i = 0; i < SAMPLE_BUFFER_LENGTH; i++) { 00093 int channel = (adcInputBuffer[i] >> 24) & 0x7; 00094 int iVal = (adcInputBuffer[i] >> 4) & 0xFFF; 00095 double fVal = 3.3 * (double)((double)iVal) / ((double)0x1000); // scale to 0v to 3.3v 00096 pc.printf("Array index %02d : ADC input channel %d = 0x%03x %01.3f volts\n", i, channel, iVal, fVal); 00097 } 00098 } 00099 00100 // Just flash LED1 for something to do. 00101 led1 = !led1; 00102 wait(0.25); 00103 } 00104 } 00105 00106 // Configuration callback on TC 00107 void TC0_callback(void) { 00108 00109 MODDMA_Config *config = dma.getConfig(); 00110 00111 // Disbale burst mode and switch off the IRQ flag. 00112 LPC_ADC->ADCR &= ~(1UL << 16); 00113 LPC_ADC->ADINTEN = 0; 00114 00115 // Finish the DMA cycle by shutting down the channel. 00116 dma.haltAndWaitChannelComplete( (MODDMA::CHANNELS)config->channelNum()); 00117 dma.Disable( (MODDMA::CHANNELS)config->channelNum() ); 00118 00119 // Tell main() while(1) loop to print the results. 00120 dmaTransferComplete = true; 00121 00122 // Switch on LED2 to show transfer complete. 00123 led2 = 1; 00124 00125 // Clear DMA IRQ flags. 00126 if (dma.irqType() == MODDMA::TcIrq) dma.clearTcIrq(); 00127 if (dma.irqType() == MODDMA::ErrIrq) dma.clearErrIrq(); 00128 } 00129 00130 // Configuration callback on Error 00131 void ERR0_callback(void) { 00132 // Switch off burst conversions. 00133 LPC_ADC->ADCR |= ~(1UL << 16); 00134 LPC_ADC->ADINTEN = 0; 00135 error("Oh no! My Mbed EXPLODED! :( Only kidding, go find the problem"); 00136 } 00137
Generated on Tue Jul 12 2022 12:57:52 by 1.7.2