http://http://diytec.web.fc2.com/mark2r2/

Dependencies:   EthernetNetIf NTPClient_NetServices mbed ConfigFile

adcdma.c

Committer:
mark2r2
Date:
2011-09-20
Revision:
0:08a4d61cd84c

File content as of revision 0:08a4d61cd84c:

/*************************************************************

 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.
}