cancel
Showing results for 
Search instead for 
Did you mean: 

Timer2 channel 3+ADC+DMA

Posted on October 20, 2017 at 22:51

Hi

    I am using STM32L431xx Timer3 and CC3 (compare mode ) on channel 3 and i want to trigger (ADC1  channel 1) and (DMA 1 and channel 1 ) to do collection of samples triggered on the timer edge. The timer works perfectly fine for the period I have set it work on. But I am not able to get the ADC->DMA chain working with the timer. Below are the ADC settings :

LL_ADC_SetCommonPathInternalCh(ADC1_COMMON,LL_ADC_PATH_INTERNAL_VREFINT);

LL_ADC_SetCommonClock(ADC1_COMMON,LL_ADC_CLOCK_SYNC_PCLK_DIV4);

LL_ADC_SetResolution(ADC1, LL_ADC_RESOLUTION_12B);

LL_ADC_SetOffset(ADC1, LL_ADC_OFFSET_1, LL_ADC_CHANNEL_1, 0x000);

LL_ADC_SetOffsetState(ADC1, LL_ADC_OFFSET_1,LL_ADC_OFFSET_DISABLE);

LL_ADC_SetChannelSamplingTime(ADC1,LL_ADC_CHANNEL_1, LL_ADC_SAMPLINGTIME_12CYCLES_5);

LL_ADC_REG_SetDMATransfer(ADC1,LL_ADC_REG_DMA_TRANSFER_UNLIMITED);

LL_ADC_REG_SetContinuousMode(ADC1, LL_ADC_REG_CONV_CONTINUOUS);

LL_ADC_REG_SetTriggerSource(ADC1,LL_ADC_REG_TRIG_EXT_TIM2_TRGO);

LL_ADC_Enable(ADC1);

DMA settings

LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_DMA1);

DMA_cfg.CPAR = (uint32_t)&ADC1->DR;

DMA_cfg.CMAR = (uint32_t)destAddress;//destinatoin address

DMA_cfg.CNDTR = numData;//number of bytes to be trasnferred

DMA1_Channel1->CCR = ( DMA_CCR_TCIE | DMA_CCR_TEIE | DMA_CCR_CIRC | DMA_CCR_HTIE| DMA_CCR_MINC | DMA_CCR_PSIZE_32BIT | DMA_CCR_MSIZE_32BIT | DMA_CCR_PL_VERY_HIGH ) 

DMA1_CSELR->CSELR = DMA1_CFG_CSELR; \\this value is '0'

NVIC_SetPriority(DMA1_Channel1_IRQn, 0);

NVIC_EnableIRQ(DMA1_Channel1_IRQn);

LL_DMA_EnableChannel(DMA1,LL_DMA_CHANNEL_1);

I dont see that I am able to get the ADC to trigger so that transfer happens!!!

Please help!

Regards

Bala

2 REPLIES 2
Posted on October 20, 2017 at 23:38

>>Please help!

Look at how I post working examples, and ask yourself how to format/present code to be worked on.

The count length for DMA is units, not bytes. The ADC->DR is 16-bit wide. I'd tinker, but see point #1

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on October 23, 2017 at 21:46

Hi Clive

   Thanks for the suggestion:

This is what I did in the sequence below to get the TIM2 (CC on Channel 3) and that will trigger an event to start ADC1 channel 1 and I am hooking up the DMA1 channel 1 to the ADC channel

/*This function is called from main() after setting the Timer2 channel 3 to generate TRG event */

void Init_ADCwDMA( uint16_t *destAddress, uint16_t numData ){

DMA_Channel_TypeDef DMA_cfg;

DMA_cfg.CPAR = (uint32_t)&ADC1->DR;

DMA_cfg.CMAR = (uint32_t)destAddress;

DMA_cfg.CNDTR = numData;

Init_ADC();

Init_DMA();

setDMAChannel(DMA1_Channel1, &DMA_cfg);

}

void Init_DMA()

{

/* (1) Enable the clock of DMA1 and DMA1 */

LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_DMA1);

DMA_Channel_TypeDef DMA1_CH1_cfg = DMA1_CH1_CFG;

DMA1_Channel1->CCR = 0x3aae;//( DMA_CCR_TCIE | DMA_CCR_TEIE | DMA_CCR_CIRC | DMA_CCR_HTIE|                                                                 //DMA_CCR_MINC | DMA_CCR_PSIZE_32BIT | DMA_CCR_MSIZE_32BIT |                                                                      //DMA_CCR_PL_VERY_HIGH )

DMA1_CSELR->CSELR = 0x0;

NVIC_SetPriority(DMA1_Channel1_IRQn, 0);

NVIC_EnableIRQ(DMA1_Channel1_IRQn);

LL_DMA_EnableChannel(DMA1,LL_DMA_CHANNEL_1);

}

/* setting DMA1 channel 1 with a config of DMA1*/

void setDMAChannel(DMA_Channel_TypeDef* channel, DMA_Channel_TypeDef *DMA_CONFIG){

channel->CCR &= ~DMA_CCR_EN;

channel->CNDTR = DMA_CONFIG->CNDTR;

channel->CPAR = DMA_CONFIG->CPAR;

channel->CMAR = DMA_CONFIG->CMAR;

channel->CCR |= DMA_CCR_EN;

}

void Init_ADC( void )

{

uint8_t timeout;

LL_ADC_SetCommonPathInternalCh(ADC1_COMMON,LL_ADC_PATH_INTERNAL_VREFINT);//Set an internal reference voltage for ADC

LL_ADC_SetCommonClock(ADC1_COMMON,LL_ADC_CLOCK_SYNC_PCLK_DIV4);//Set ADC clock to SYSCLK/.4

LL_ADC_SetResolution(ADC1, LL_ADC_RESOLUTION_12B);//12 Bit resolution

LL_ADC_SetOffset(ADC1, LL_ADC_OFFSET_1, LL_ADC_CHANNEL_1, 0x000);//ADC1 channel 1 

LL_ADC_SetOffsetState(ADC1, LL_ADC_OFFSET_1,LL_ADC_OFFSET_DISABLE);//Disable ADC offset 

LL_ADC_SetChannelSamplingTime(ADC1,LL_ADC_CHANNEL_1, LL_ADC_SAMPLINGTIME_12CYCLES_5);//set conversion time

LL_ADC_REG_SetDMATransfer(ADC1,LL_ADC_REG_DMA_TRANSFER_UNLIMITED); unlimited DMA transfer

LL_ADC_REG_SetContinuousMode(ADC1, LL_ADC_REG_CONV_CONTINUOUS);//continous conversion

LL_ADC_REG_SetTriggerSource(ADC1,LL_ADC_REG_TRIG_EXT_TIM2_TRGO);//Generate Timer2 trigger

LL_ADC_Enable(ADC1);//Enable ADC1

}

void main()

{

     Init_ADCwDMA( &aRcvBuf[0],160);

/ * below was  timer code and the timer does work as expected as a PWM*/

/*The timer2 channel 3 is set in CC mode and it works good and it is tested*/

/*The code was not put out to avoid cluttering*/

/* Force update generation */

LL_TIM_GenerateEvent_UPDATE(TIM2);

/* Enable output channel 3 */

LL_TIM_CC_EnableChannel(TIM2, LL_TIM_CHANNEL_CH3);

LL_ADC_REG_StartConversion(ADC1);

}