AnsweredAssumed Answered

LPC82x ADC+DMA

Question asked by Tiago Fernandes on Jul 6, 2016
Latest reply on Jul 27, 2016 by Tiago Fernandes

Hello,

 

I'm trying to use the ADC+DMA to read 8 adc channels (not sequential (channel 2,3,4,5,6,7,8 and 9)) and save your values to the DMA to reduce the number of interruptions. For this I search in NXP community and on the internet and I found some people that uses this approach. I tried to testing this approachs, for be capable of read one adc and write in the dma (this is the first test that I'm trying to implement the ADC+DMA) but I have a problem, when I read the value saved in the DMA the value is always 0, even with different voltagens in the channel input. Then let my code, does anyone know tell me what am I doing wrong?

 

Best Regards,

Tiago

 

void DMA_IRQHandler(void)

{

  // Clear DMA interrupt for the channel

  Chip_DMA_ClearActiveIntAChannel(LPC_DMA, DMA_CH0);

}

 

init_adc+dma()

{

 

//disable pull up and pull down

Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_IOCON);

Chip_IOCON_PinSetMode(LPC_IOCON, IOCON_PIO6, PIN_MODE_INACTIVE);

Chip_IOCON_PinSetMode(LPC_IOCON, IOCON_PIO14, PIN_MODE_INACTIVE);

Chip_Clock_DisablePeriphClock(SYSCTL_CLOCK_IOCON);

 

  //init adc

  Chip_ADC_Init(LPC_ADC, 0);

  Chip_ADC_StartCalibration(LPC_ADC);

  while (!(Chip_ADC_IsCalibrationDone(LPC_ADC))) {

  }

  Chip_ADC_SetClockRate(LPC_ADC, ADC_MAX_SAMPLE_RATE);

  Chip_ADC_SetDivider(LPC_ADC,0);

 

  Chip_ADC_SetupSequencer(LPC_ADC, ADC_SEQA_IDX,

  (ADC_SEQ_CTRL_CHANSEL(1) //| ADC_SEQ_CTRL_CHANSEL(2)

  //| ADC_SEQ_CTRL_CHANSEL(3) | ADC_SEQ_CTRL_CHANSEL(4)

  |ADC_SEQ_CTRL_BURST

  | ADC_SEQ_CTRL_MODE_EOS));

 

  Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_SWM);

  Chip_SWM_DisableFixedPin(SWM_FIXED_VDDCMP);

  Chip_SWM_DisableFixedPin(SWM_FIXED_ACMP_I3);

  Chip_SWM_DisableFixedPin(SWM_FIXED_ACMP_I4);

  /* Configure the SWM for P0-6 as the input for the ADC1 */

  Chip_SWM_EnableFixedPin(SWM_FIXED_ADC1);

  //Chip_SWM_EnableFixedPin(SWM_FIXED_ADC2);

  /* Disable the clock to the Switch Matrix to save power */

  Chip_Clock_DisablePeriphClock(SYSCTL_CLOCK_SWM);

 

  /* Clear all pending interrupts */

  Chip_ADC_ClearFlags(LPC_ADC, Chip_ADC_GetFlags(LPC_ADC));

 

  Chip_ADC_EnableInt(LPC_ADC, (ADC_INTEN_SEQA_ENABLE

  //| ADC_INTEN_OVRRUN_ENABLE

  ));

 

  //NVIC_EnableIRQ(ADC_SEQA_IRQn);

  /* Enable sequencer */

  Chip_ADC_EnableSequencer(LPC_ADC, ADC_SEQA_IDX);

 

  // Setup DMA for ADC

  /* DMA initialization - enable DMA clocking and reset DMA if needed */

  Chip_DMA_Init(LPC_DMA);

  /* Enable DMA controller and use driver provided DMA table for current descriptors */

  Chip_DMA_Enable(LPC_DMA);

  Chip_DMA_SetSRAMBase(LPC_DMA, DMA_ADDR(Chip_DMA_Table));

 

  Chip_DMA_EnableChannel(LPC_DMA, DMA_CH0);

  Chip_DMA_EnableIntChannel(LPC_DMA, DMA_CH0);

 

  Chip_DMA_SetupChannelConfig(LPC_DMA, DMA_CH0,

  (DMA_CFG_HWTRIGEN

  | DMA_CFG_TRIGTYPE_EDGE | DMA_CFG_TRIGPOL_HIGH

  | DMA_CFG_TRIGBURST_BURST | DMA_CFG_BURSTPOWER_1

  //| SRCBURSTWRAP

  | DMA_CFG_CHPRIORITY(0)));

 

  // Attempt to use ADC SEQA to trigger DMA xfer

  Chip_DMATRIGMUX_SetInputTrig(LPC_DMATRIGMUX, DMA_CH0, DMATRIG_ADC_SEQA_IRQ);

 

  /* DMA descriptor for peripheral to memory operation - note that addresses must

  be the END address for src and destination, not the starting address.

  DMA operations moves from end to start. */

  dmaDescA.source = DMA_ADDR(&(LPC_ADC->DR[adc_channel])); //adc_channel=1

  dmaDescA.dest = DMA_ADDR(&adc_buffer[SIZE_BUFFER_1 - 1]);     //SIZE_BUFFER_1=1;  uint16_t adc_buffer//

  dmaDescA.next = DMA_ADDR(0);

 

  // Enable DMA interrupt. Will be invoked at end of DMA transfer.

  NVIC_EnableIRQ(DMA_IRQn);

 

  /* Setup transfer descriptor and validate it */

  Chip_DMA_SetupTranChannel(LPC_DMA, DMA_CH0, &dmaDescA);

  Chip_DMA_SetValidChannel(LPC_DMA, DMA_CH0);

 

  // Setup data transfer and hardware trigger

  Chip_DMA_SetupChannelTransfer(LPC_DMA, DMA_CH0, (

  DMA_XFERCFG_CFGVALID

  | DMA_XFERCFG_RELOAD

  | DMA_XFERCFG_SETINTA

  //| DMA_XFERCFG_SWTRIG

  | DMA_XFERCFG_WIDTH_16

  | DMA_XFERCFG_SRCINC_0 // do not increment source - I want read from the adc and save always in the same memory position

  | DMA_XFERCFG_DSTINC_0 // do not increment dst

  | DMA_XFERCFG_XFERCOUNT(SIZE_BUFFER_1)));

 

  Chip_ADC_ClearFlags(LPC_ADC, Chip_ADC_GetFlags(LPC_ADC));

}

 

main()

{

 

     //print the data from the DMA

     //put only the 12bits of the adc

     for (i = 0; i < SIZE_BUFFER_1; i++) {    

            adc_buffer[i] >>= 4;

       }

     //send data

       for (i = 0; i < SIZE_BUFFER_1; i++) {

          print_data(adc_buffer[i] );  //send to UART the data from the DMA  

       }

 

}

Outcomes