AnsweredAssumed Answered

KINETIS MK12DN512VMC5 - ADC WITH DMA

Question asked by Aviv Agam on Jan 27, 2016
Latest reply on Jan 27, 2016 by jeremyzhou

Hi all,

My project based on MK12DN512VMC5 MCU and I want to change the ADC method from interrupt (via internal timer) to DMA due to

the need to increase the sampling rate to 10 KHz to 7 ADC channels serially (it’s mean 70KHz sampling rate…).

I am trying to implement sampling with DMA that will bring me interrupt after the sampling buffer is full ( 7 channels, 4 samples each)

 

I am trying to use software trigger for ADC, following my ADC code:

 

  Master_Adc_Config.CONFIG1  = ADLPC_NORMAL | ADC_CFG1_ADIV(ADIV_1) | /* ADLSMP_SHORT*/ ADLSMP_LONG| ADC_CFG1_MODE(MODE_16) | ADC_CFG1_ADICLK(ADICLK_BUS);

  Master_Adc_Config.CONFIG2  = MUXSEL_ADCA | ADACKEN_DISABLED | ADHSC_HISPEED | ADC_CFG2_ADLSTS(ADLSTS_2) ;

  Master_Adc_Config.COMPARE1 = 0x1234u ;

  Master_Adc_Config.COMPARE2 = 0x5678u ;

 

 

  Master_Adc_Config.STATUS2  = ADTRG_SW | ACFE_DISABLED | ACFGT_GREATER | ACREN_DISABLED | DMAEN_ENABLED | ADC_SC2_REFSEL(REFSEL_EXT);

  Master_Adc_Config.STATUS3  = CAL_OFF | ADCO_SINGLE | /*AVGE_ENABLED*/AVGE_DISABLED | ADC_SC3_AVGS(AVGS_4);

  Master_Adc_Config.STATUS1A = AIEN_ON | DIFF_SINGLE | ADC_SC1_ADCH(SNSR_1);

  Master_Adc_Config.STATUS1B = AIEN_ON | DIFF_SINGLE | ADC_SC1_ADCH(SNSR_1);

 

In addition i am trying to use 2 DMA channels in order to get continuous scan mode, following my DMA initialization code:

(void DMACH0_CH1_Init(void
}
  //****************************************************************************
  //**** DMA channel 0, use for Write ADC mux channel, form SRAM to ADC ********
  //****************************************************************************
  DMAMUX_CHCFG0           = DMAMUX_CHCFG_ENBL_MASK|DMAMUX_CHCFG_SOURCE(0x36);   //DMA source DMA Mux
  DMA_TCD0_SADDR          = (uint32) &uc_adc_mux[0];                            //New mux setiing
  DMA_TCD0_SOFF           = 0x01;                                               //Source address increment, adding "1"
  DMA_TCD0_SLAST          = (uint32) -7;                                        //Source address decrement after major loop complete
  DMA_TCD0_DADDR          = (uint32) &ADC0_SC1A;                                //Destination address ADC0 mux selector
  DMA_TCD0_DOFF           = 0x00;                                               //Destination address increment, adding "0"
  DMA_TCD0_DLASTSGA       = 0x00;                                               //Destination address shift, go to back to [0]
  DMA_TCD0_NBYTES_MLNO    = 0x02;                                               //No of bytes minor loop
  DMA_TCD0_BITER_ELINKNO  = 0x07;                                               //Major loop step, 7 ADC channel are scaning
  DMA_TCD0_CITER_ELINKNO  = 0x07;                                               //Major loop step, 7 ADC channel are scaning
  DMA_TCD0_ATTR           = DMA_ATTR_SSIZE(1)|DMA_ATTR_DSIZE(1);                //Source a destination size, 16bit
  DMA_TCD0_CSR            = 0x0000;                                             //
 
  //****************************************************************************
  //**** DMA channel 1, use for Read ADC result data, form ADC to SRAM *********
  //****************************************************************************
  NVIC_SetIsr(INT_DMA1,2);                                                      //17


  DMAMUX_CHCFG1           = DMAMUX_CHCFG_ENBL_MASK|DMAMUX_CHCFG_SOURCE(0x28);   //DMA source ADC0
  DMA_TCD1_SADDR          = (uint32) &ADC0_RA;                                  //Source address ADC0 result register
  DMA_TCD1_SOFF           = 0x00;                                               //Source address increment, adding "0"
  DMA_TCD1_SLAST          = 0x00;                                               //Source address decrement after major loop complete
  DMA_TCD1_DADDR          = (uint32) &ui_adc_result[0];                         //Destination address, ADC0 result buffer
  DMA_TCD1_DOFF           = 0x02;                                               //Destination address increment, adding "+2"
  DMA_TCD1_DLASTSGA       = (uint32) -24;                                       //Destination address decrement after major loop complete
  DMA_TCD1_NBYTES_MLNO    = 0x02;                                               //No of bytes minor loop, 16bit ADC result
  DMA_TCD1_BITER_ELINKNO  = (DMA_BITER_ELINKNO_ELINK_MASK|0x0000|0x1C);         //Channel 0 Link, Channel 0, Major loop step 7 x 4 = 28
  DMA_TCD1_CITER_ELINKNO  = (DMA_CITER_ELINKNO_ELINK_MASK|0x1C);                //Channel 0 Link, Major loop step 7 x 4 = 28
  DMA_TCD1_ATTR           = DMA_ATTR_SSIZE(1)|DMA_ATTR_DSIZE(1);                //Source a destination size, 16bit
  DMA_TCD1_CSR            = (DMA_CSR_MAJORLINKCH(0)|DMA_CSR_MAJORELINK_MASK)|   //Major loop finished start request for Channel 0
                            DMA_CSR_INTMAJOR_MASK; //|DMA_CSR_INTHALF_MASK;     //Irq. enable, full transfer, half complet transfer
  DMA_ERQ                |= DMA_ERQ_ERQ1_MASK;                                  //HW request enable
{

for some reason I am not getting interrupt via the DMA isr:

 

(void dma_ch1_isr(void

}

  DMA_CINT = DMA_CINT_CINT(1);                                                  //Clear the interrupt flag for channel 0  

{

 

...What is not Ok with my initialization code? I tried to refer AN4590

Outcomes