Zoltan Hudak / MODDMA
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers example2.h Source File

example2.h

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