cancel
Showing results for 
Search instead for 
Did you mean: 

CubeF1 ADC with DMA, DMA1_Channel1_IRQHandler interrupt is blocked by while() loop?

calltherain
Associate II
Posted on January 30, 2015 at 05:05

Attached is the project files, CubeMX file is also in the package.

I just added some simple code in these 2 places. everything else is generated by CubeMX. main.c, int main(void)

/* USER CODE BEGIN 3 */
/* Infinite loop */
while (1) {
DMATC = 0;
HAL_ADC_Start_DMA(&hadc1, (uint32_t *) adcValues, 5);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_14, GPIO_PIN_SET); //for debug
while(DMATC == 0)
{
;
}
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_14, GPIO_PIN_RESET); //for debug
}
/* USER CODE END 3 */

stm32f1xx_it.c

void DMA1_Channel1_IRQHandler(void)
{
/* USER CODE BEGIN DMA1_Channel1_IRQn 0 */
/* USER CODE END DMA1_Channel1_IRQn 0 */
HAL_DMA_IRQHandler(&hdma_adc1);
/* USER CODE BEGIN DMA1_Channel1_IRQn 1 */
if ( HAL_DMA_GetState( &hdma_adc1 ) == HAL_DMA_STATE_READY )
DMATC = 1;
/* USER CODE END DMA1_Channel1_IRQn 1 */
}

With the above

while(DMATC == 0)

loop in main.c the interrupt handler is never invoked, if I remove the while() loop in main.c then the interrupt is invoked. What am I doing wrong? Maybe I missed some configuration ? Thanks
3 REPLIES 3
calltherain
Associate II
Posted on February 01, 2015 at 11:32

I tried not using while(1) to wait the ADC DMA completes, instead, I used a 1Kh timer to start the ADC:

/**
* @brief This function handles TIM1 update interrupt.
*/
void TIM1_UP_IRQHandler(void)
{
/* USER CODE BEGIN TIM1_UP_IRQn 0 */
/* USER CODE END TIM1_UP_IRQn 0 */
HAL_TIM_IRQHandler(&htim1);
/* USER CODE BEGIN TIM1_UP_IRQn 1 */
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_15, GPIO_PIN_SET); //for debug

HAL_ADC_Start_DMA( &hadc1, (uint32_t *)adcValues, 2);

HAL_GPIO_WritePin(GPIOB, GPIO_PIN_15, GPIO_PIN_RESET); //for debug
/* USER CODE END TIM1_UP_IRQn 1 */
}

And I added my own implementation for void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)

void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{

HAL_GPIO_WritePin(GPIOB, GPIO_PIN_14, GPIO_PIN_SET); //for debug

HAL_GPIO_WritePin(GPIOB, GPIO_PIN_14, GPIO_PIN_RESET); //for debug

}

by using a scope I can see that sometimes there is no pulse for PB14, so it seems that the DMA sometimes failed for some reason?
childresss
Associate II
Posted on February 02, 2015 at 04:50

is DMATC a constant? Being upper case, by convention, it's a #defined constant or an unchanging const I/O register or some such.

If DMATC is declared as global variable, is it declared as volatile since the ISR alters it?

calltherain
Associate II
Posted on February 02, 2015 at 16:34

DMATC is a global var declared in main.c,

/* USER CODE BEGIN PV */
__IO uint8_t DMATC;

in stm32f1xx_it.c, it is referenced :

extern __IO uint8_t DMATC;

now I'm using HAL_ADC_PollForConversion to wait the conversion completes because I can specify a timeout value:

HAL_StatusTypeDef HAL_ADC_PollForConversion ( ADC_HandleTypeDef * hadc, uint32_t Timeout )

and seems that it works okay. But I can't figure out why while(1) doesn't work as expected.