http://http://diytec.web.fc2.com/mark2r2/
Dependencies: EthernetNetIf NTPClient_NetServices mbed ConfigFile
Diff: adcdma.c
- Revision:
- 0:08a4d61cd84c
diff -r 000000000000 -r 08a4d61cd84c adcdma.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/adcdma.c Tue Sep 20 12:46:26 2011 +0000 @@ -0,0 +1,152 @@ +/************************************************************* + + History + 2011/07/26 - Add "shape_mode" option. + + +*************************************************************/ +#include "MODDMA.h" + +#define SAMPLE_BUFFER_LENGTH 256 + +extern int shape_mode; + +// for ADC DMA read +static MODDMA dma; +static MODDMA_Config *conf = new MODDMA_Config; +static uint32_t adcInputBuffer[SAMPLE_BUFFER_LENGTH]; + +/****************** +To read ADC DMA +*******************/ +// Configuration callback on TC +void TC0_callback(void) { + + MODDMA_Config *config = dma.getConfig(); + + // Disbale burst mode and switch off the IRQ flag. + LPC_ADC->ADCR &= ~(1UL << 16); + LPC_ADC->ADINTEN = 0; + + // Finish the DMA cycle by shutting down the channel. + dma.haltAndWaitChannelComplete( (MODDMA::CHANNELS)config->channelNum()); + dma.Disable( (MODDMA::CHANNELS)config->channelNum() ); + + // Clear DMA IRQ flags. + if (dma.irqType() == MODDMA::TcIrq) dma.clearTcIrq(); + if (dma.irqType() == MODDMA::ErrIrq) dma.clearErrIrq(); + + int m=0,max=0,n=0; + int downtrend=0; + int errata=0; + + for (int i = 0; i < SAMPLE_BUFFER_LENGTH; i++) { + int channel = (adcInputBuffer[i] >> 24) & 0x7; + int iVal = (adcInputBuffer[i] >> 4) & 0xFFF; +// double fVal = 3.3 * (double)((double)iVal) / ((double)0x1000); // scale to 0v to 3.3v +// pc.printf("Array index %02d : ADC input channel %d = 0x%03x %01.3f volts\n", i, channel, iVal, fVal); + + if( channel == 0 ){ + + n = iVal; + +//PEAKMAX + if(!downtrend){ + max= n>max ? n:max; + if(n<max){ + downtrend=1; + } + }else{ + if (n>max+100) + errata=1; + } + +//Accumulation + m+=n; + + if (shape_mode) { // 2011/07/26 + double fVal = 3.3 * (double)((double)n) / ((double)0x1000); + printf("%01.3f\n",fVal); + } + } + + if(n==0 && max !=0) break; + } + + if(!errata){ + if (shape_mode) { // 2011/07/26 + double fm = 3.3 * (double)((double)m) / ((double)0x1000); + double fmax = 3.3 * (double)((double)max) / ((double)0x1000); + printf("%01.3f,%01.3f\n",fm,fmax); + } + printf("%d,%d\n",m,max); + + if (shape_mode) { // 2011/07/26 + printf("-----\n"); + } + } +} + +// Configuration callback on Error +void ERR0_callback(void) { + // Switch off burst conversions. + LPC_ADC->ADCR |= ~(1UL << 16); + LPC_ADC->ADINTEN = 0; + error("Oh no! My Mbed EXPLODED! :( Only kidding, go find the problem"); +} + +void read_dma_data() +{ + memset(adcInputBuffer, 0, sizeof(adcInputBuffer)); + + // Prepare configuration. + dma.Setup( conf ); + + // Enable configuration. + dma.Enable( conf ); + + // Enable ADC irq flag (to DMA). + // Note, don't set the individual flags, + // just set the global flag. + LPC_ADC->ADINTEN = 0x100; + + // Enable burst mode on inputs 0 and 1. + LPC_ADC->ADCR |= (1UL << 16); + return; +} + +void setup_adcdma() +{ + // We use the ADC irq to trigger DMA and the manual says + // that in this case the NVIC for ADC must be disabled. + NVIC_DisableIRQ(ADC_IRQn); + + // Power up the ADC and set PCLK + LPC_SC->PCONP |= (1UL << 12); + LPC_SC->PCLKSEL0 &= ~(3UL << 24); // PCLK = CCLK/4 96M/4 = 24MHz + + // Enable the ADC, 12MHz + LPC_ADC->ADCR = (1UL << 21) | (1UL << 8) | (1UL << 0); + + // Set the pin functions to ADC + LPC_PINCON->PINSEL1 &= ~(3UL << 14); /* P0.23, Mbed p15. */ + LPC_PINCON->PINSEL1 |= (1UL << 14); + +// Prepare an ADC configuration. +// MODDMA_Config *conf = new MODDMA_Config; + + conf + ->channelNum ( MODDMA::Channel_0 ) + ->srcMemAddr ( 0 ) + ->dstMemAddr ( (uint32_t)adcInputBuffer ) + ->transferSize ( SAMPLE_BUFFER_LENGTH ) + ->transferType ( MODDMA::p2m ) + ->transferWidth ( MODDMA::word ) + ->srcConn ( MODDMA::ADC ) + ->dstConn ( 0 ) + ->dmaLLI ( 0 ) + ->attach_tc ( &TC0_callback ) + ->attach_err ( &ERR0_callback ) + ; // end conf. +} +