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

Committer:
AjK
Date:
Sat Mar 02 19:27:12 2013 +0000
Revision:
17:97a16bf2ff43
Parent:
12:1dfee7208043
1.13 See ChangeLog.c

Who changed what in which revision?

UserRevisionLine numberNew contents of line
AjK 12:1dfee7208043 1 /*
AjK 12:1dfee7208043 2 * This example was provided to support Mbed forum thread:-
AjK 12:1dfee7208043 3 * http://mbed.org/forum/mbed/topic/1798
AjK 12:1dfee7208043 4 */
AjK 12:1dfee7208043 5
AjK 12:1dfee7208043 6 #include "mbed.h"
AjK 12:1dfee7208043 7 #include "MODDMA.h"
AjK 12:1dfee7208043 8
AjK 12:1dfee7208043 9 #define SAMPLE_BUFFER_LENGTH 32
AjK 12:1dfee7208043 10
AjK 12:1dfee7208043 11 DigitalOut led1(LED1);
AjK 12:1dfee7208043 12 DigitalOut led2(LED2);
AjK 12:1dfee7208043 13
AjK 12:1dfee7208043 14 MODDMA dma;
AjK 12:1dfee7208043 15 Serial pc(USBTX, USBRX);
AjK 12:1dfee7208043 16
AjK 12:1dfee7208043 17 // ISR set's this when transfer complete.
AjK 12:1dfee7208043 18 bool dmaTransferComplete = false;
AjK 12:1dfee7208043 19
AjK 12:1dfee7208043 20 // Function prototypes for IRQ callbacks.
AjK 12:1dfee7208043 21 // See definitions following main() below.
AjK 12:1dfee7208043 22 void TC0_callback(void);
AjK 12:1dfee7208043 23 void ERR0_callback(void);
AjK 12:1dfee7208043 24
AjK 12:1dfee7208043 25 int main() {
AjK 12:1dfee7208043 26
AjK 12:1dfee7208043 27 // Create a buffer to hold the ADC samples and clear it.
AjK 12:1dfee7208043 28 // Note, we are going to sample two ADC inputs so they
AjK 12:1dfee7208043 29 // end up in this buffer "interleaved". So you will want
AjK 12:1dfee7208043 30 // a buffer twice this size to a real life given sample
AjK 12:1dfee7208043 31 // frequency. See the printf() output for details.
AjK 12:1dfee7208043 32 uint32_t adcInputBuffer[SAMPLE_BUFFER_LENGTH];
AjK 12:1dfee7208043 33 memset(adcInputBuffer, 0, sizeof(adcInputBuffer));
AjK 12:1dfee7208043 34
AjK 12:1dfee7208043 35 // We use the ADC irq to trigger DMA and the manual says
AjK 12:1dfee7208043 36 // that in this case the NVIC for ADC must be disabled.
AjK 12:1dfee7208043 37 NVIC_DisableIRQ(ADC_IRQn);
AjK 12:1dfee7208043 38
AjK 12:1dfee7208043 39 // Power up the ADC and set PCLK
AjK 12:1dfee7208043 40 LPC_SC->PCONP |= (1UL << 12);
AjK 12:1dfee7208043 41 LPC_SC->PCLKSEL0 &= ~(3UL << 24); // PCLK = CCLK/4 96M/4 = 24MHz
AjK 12:1dfee7208043 42
AjK 12:1dfee7208043 43 // Enable the ADC, 12MHz, ADC0.0 & .1
AjK 12:1dfee7208043 44 LPC_ADC->ADCR = (1UL << 21) | (1UL << 8) | (3UL << 0);
AjK 12:1dfee7208043 45
AjK 12:1dfee7208043 46 // Set the pin functions to ADC
AjK 12:1dfee7208043 47 LPC_PINCON->PINSEL1 &= ~(3UL << 14); /* P0.23, Mbed p15. */
AjK 12:1dfee7208043 48 LPC_PINCON->PINSEL1 |= (1UL << 14);
AjK 12:1dfee7208043 49 LPC_PINCON->PINSEL1 &= ~(3UL << 16); /* P0.24, Mbed p16. */
AjK 12:1dfee7208043 50 LPC_PINCON->PINSEL1 |= (1UL << 16);
AjK 12:1dfee7208043 51
AjK 12:1dfee7208043 52 // Setup the serial port to print out results.
AjK 12:1dfee7208043 53 pc.baud(115200);
AjK 12:1dfee7208043 54 pc.printf("ADC with DMA example\n");
AjK 12:1dfee7208043 55 pc.printf("====================\n");
AjK 12:1dfee7208043 56
AjK 12:1dfee7208043 57 // Prepare an ADC configuration.
AjK 12:1dfee7208043 58 MODDMA_Config *conf = new MODDMA_Config;
AjK 12:1dfee7208043 59 conf
AjK 12:1dfee7208043 60 ->channelNum ( MODDMA::Channel_0 )
AjK 12:1dfee7208043 61 ->srcMemAddr ( 0 )
AjK 12:1dfee7208043 62 ->dstMemAddr ( (uint32_t)adcInputBuffer )
AjK 12:1dfee7208043 63 ->transferSize ( SAMPLE_BUFFER_LENGTH )
AjK 12:1dfee7208043 64 ->transferType ( MODDMA::p2m )
AjK 12:1dfee7208043 65 ->transferWidth ( MODDMA::word )
AjK 12:1dfee7208043 66 ->srcConn ( MODDMA::ADC )
AjK 12:1dfee7208043 67 ->dstConn ( 0 )
AjK 12:1dfee7208043 68 ->dmaLLI ( 0 )
AjK 12:1dfee7208043 69 ->attach_tc ( &TC0_callback )
AjK 12:1dfee7208043 70 ->attach_err ( &ERR0_callback )
AjK 12:1dfee7208043 71 ; // end conf.
AjK 12:1dfee7208043 72
AjK 12:1dfee7208043 73 // Prepare configuration.
AjK 12:1dfee7208043 74 dma.Setup( conf );
AjK 12:1dfee7208043 75
AjK 12:1dfee7208043 76 // Enable configuration.
AjK 12:1dfee7208043 77 dma.Enable( conf );
AjK 12:1dfee7208043 78
AjK 12:1dfee7208043 79 // Enable ADC irq flag (to DMA).
AjK 12:1dfee7208043 80 // Note, don't set the individual flags,
AjK 12:1dfee7208043 81 // just set the global flag.
AjK 12:1dfee7208043 82 LPC_ADC->ADINTEN = 0x100;
AjK 12:1dfee7208043 83
AjK 12:1dfee7208043 84 // Enable burst mode on inputs 0 and 1.
AjK 12:1dfee7208043 85 LPC_ADC->ADCR |= (1UL << 16);
AjK 12:1dfee7208043 86
AjK 12:1dfee7208043 87 while (1) {
AjK 12:1dfee7208043 88 // When transfer complete do this block.
AjK 12:1dfee7208043 89 if (dmaTransferComplete) {
AjK 12:1dfee7208043 90 delete conf; // No memory leaks, delete the configuration.
AjK 12:1dfee7208043 91 dmaTransferComplete = false;
AjK 12:1dfee7208043 92 for (int i = 0; i < SAMPLE_BUFFER_LENGTH; i++) {
AjK 12:1dfee7208043 93 int channel = (adcInputBuffer[i] >> 24) & 0x7;
AjK 12:1dfee7208043 94 int iVal = (adcInputBuffer[i] >> 4) & 0xFFF;
AjK 12:1dfee7208043 95 double fVal = 3.3 * (double)((double)iVal) / ((double)0x1000); // scale to 0v to 3.3v
AjK 12:1dfee7208043 96 pc.printf("Array index %02d : ADC input channel %d = 0x%03x %01.3f volts\n", i, channel, iVal, fVal);
AjK 12:1dfee7208043 97 }
AjK 12:1dfee7208043 98 }
AjK 12:1dfee7208043 99
AjK 12:1dfee7208043 100 // Just flash LED1 for something to do.
AjK 12:1dfee7208043 101 led1 = !led1;
AjK 12:1dfee7208043 102 wait(0.25);
AjK 12:1dfee7208043 103 }
AjK 12:1dfee7208043 104 }
AjK 12:1dfee7208043 105
AjK 12:1dfee7208043 106 // Configuration callback on TC
AjK 12:1dfee7208043 107 void TC0_callback(void) {
AjK 12:1dfee7208043 108
AjK 12:1dfee7208043 109 MODDMA_Config *config = dma.getConfig();
AjK 12:1dfee7208043 110
AjK 12:1dfee7208043 111 // Disbale burst mode and switch off the IRQ flag.
AjK 12:1dfee7208043 112 LPC_ADC->ADCR &= ~(1UL << 16);
AjK 12:1dfee7208043 113 LPC_ADC->ADINTEN = 0;
AjK 12:1dfee7208043 114
AjK 12:1dfee7208043 115 // Finish the DMA cycle by shutting down the channel.
AjK 12:1dfee7208043 116 dma.haltAndWaitChannelComplete( (MODDMA::CHANNELS)config->channelNum());
AjK 12:1dfee7208043 117 dma.Disable( (MODDMA::CHANNELS)config->channelNum() );
AjK 12:1dfee7208043 118
AjK 12:1dfee7208043 119 // Tell main() while(1) loop to print the results.
AjK 12:1dfee7208043 120 dmaTransferComplete = true;
AjK 12:1dfee7208043 121
AjK 12:1dfee7208043 122 // Switch on LED2 to show transfer complete.
AjK 12:1dfee7208043 123 led2 = 1;
AjK 12:1dfee7208043 124
AjK 12:1dfee7208043 125 // Clear DMA IRQ flags.
AjK 12:1dfee7208043 126 if (dma.irqType() == MODDMA::TcIrq) dma.clearTcIrq();
AjK 12:1dfee7208043 127 if (dma.irqType() == MODDMA::ErrIrq) dma.clearErrIrq();
AjK 12:1dfee7208043 128 }
AjK 12:1dfee7208043 129
AjK 12:1dfee7208043 130 // Configuration callback on Error
AjK 12:1dfee7208043 131 void ERR0_callback(void) {
AjK 12:1dfee7208043 132 // Switch off burst conversions.
AjK 12:1dfee7208043 133 LPC_ADC->ADCR |= ~(1UL << 16);
AjK 12:1dfee7208043 134 LPC_ADC->ADINTEN = 0;
AjK 12:1dfee7208043 135 error("Oh no! My Mbed EXPLODED! :( Only kidding, go find the problem");
AjK 12:1dfee7208043 136 }
AjK 12:1dfee7208043 137