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 Feb 05 08:53:26 2011 +0000
Revision:
8:cb4d323ce6fd
Child:
9:e7ecf909e834
1.5 See ChangeLog.c

Who changed what in which revision?

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