Why am i not able to switch on and off DMA randomly in STM32F051R6T6TR?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2018-12-14 3:08 AM
i'm trying to sample 40 adc values by using dma which means i have configure adc with dma(interrupt).Time period is also a constrain which means that a value is read after every 500us.After obtaining 40 readings
,i disabled both timer and dma then send the adc values via uart.I repeated this procedure several times and happen to notice that the program doesnt enter DMA ISR after random number of cycles therefater unable to read ADC values.
I have atatched my DMA code configurations below:
void DMA_config()
{
RCC->AHBENR |= RCC_AHBENR_DMA1EN;
ADC1->CFGR1 |= ADC_CFGR1_DMAEN | ADC_CFGR1_DMACFG;
DMA1_Channel1->CPAR = (uint32_t) (&(ADC1->DR));
DMA1_Channel1->CMAR = (uint32_t)(ADC_array);
DMA1_Channel1->CNDTR = 1 ;
DMA1_Channel1->CCR |= DMA_CCR_MINC | DMA_CCR_MSIZE_0 | DMA_CCR_PSIZE_0 | DMA_CCR_CIRC | DMA_CCR_PL_0;
DMA1_Channel1->CCR |= DMA_CCR_EN|DMA_CCR_TCIE;
NVIC_EnableIRQ(DMA1_Ch1_IRQn);
}
void timer_DMA_off()
{
TIM3->DIER &= ~TIM_DIER_UIE;
DMA1_Channel1->CCR &= ~(DMA_CCR_EN|DMA_CCR_TCIE);
}
void timer_DMA_on()
{
//TIMER
RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;
TIM3->DIER = TIM_DIER_UIE;
TIM3->CR1 |= TIM_CR1_CEN;
NVIC_EnableIRQ(TIM3_IRQn);
//ADC
ADC1->CR |= ADC_CR_ADEN;
while(!(ADC1->ISR & ADC_ISR_ADRDY));
ADC1->CR |= ADC_CR_ADSTART;
//DMA
ADC1->CFGR1 |= ADC_CFGR1_DMAEN | ADC_CFGR1_DMACFG;
DMA1_Channel1->CCR |= DMA_CCR_EN|DMA_CCR_TCIE;
}
void adc_configuration()
{
PORTA_CLK_EN ;
GPIOA->MODER |= BIT(11) | BIT(10);
RCC->APB2ENR |= RCC_APB2ENR_ADCEN;
RCC->CR2 |= RCC_CR2_HSI14ON;
while(!(RCC->CR2 & RCC_CR2_HSI14RDY));
ADC1->CFGR2 &=~ ADC_CFGR2_CKMODE; // Asynchronous clock mode
ADC1->CFGR1 |= ADC_CFGR1_CONT | ADC_CFGR1_DMACFG | ADC_CFGR1_DMAEN | ADC_CFGR1_RES_0;
//ADC1->CFGR1 |= ADC_CFGR1_RES_0; // 10 bit resolution
ADC1->CFGR1 &=~ ADC_CFGR1_ALIGN | ADC_CFGR1_SCANDIR; // Right alignment, Upward scan
ADC1->SMPR &=~ ADC_SMPR_SMP;
ADC1->CHSELR |= ADC_CHSELR_CHSEL5 ;
ADC1->CR |= 0;
ADC1->CR |= ADC_CR_ADEN;
while(!(ADC1->ISR & ADC_ISR_ADRDY));
ADC1->CR |= ADC_CR_ADSTART;
}
void timer_config()
{
RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;
TIM3->ARR = 23400;
TIM3->CR1 |= TIM_CR1_ARPE | TIM_CR1_CKD_0 | TIM_CR1_CEN;
TIM3->DIER &= ~TIM_DIER_UIE;
TIM3->EGR |= TIM_EGR_UG;
NVIC_EnableIRQ(TIM3_IRQn);
}
- Labels:
-
ADC
-
DMA
-
STM32F0 Series
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2018-12-14 3:40 AM
There may be several reasons why DMA stops working, but one of them is ADC overrun, see ADC chapter in RM.
JW
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2018-12-19 12:36 AM
Hai,
Actually please note that we are just turning the DMA and the timer on and off but the ADC isn't turned off at any instant.When i checked the code i found that, the error which you specified could be due to overrun is not happening if i continuously read adc.It happens only when turning on and off DMA.
