ADC TIMER triggered DMA doesn't starts, STM32F401
Hi everyone!
I am trying to write a simple code that starts an ADC DMA based on timer temporization.
In order to do this on a Nucleo-STM32F401RE board I use:
TIM2, channel 1, output compare no output, mode frozen;
ADC1, channel 0, timer 2 trigger out event, rising edge;
DMA2 Stream0, mode circular.
Looking at the debug the code works fine, timer2 starts and fire interrupts if they are enable, ADC conversion enable bit change its value in the register after the start instruction, but the DMA callback and ADC conversions never happen so the conversion buffer still empty.
There is someone who could take a look into the code and help me?
Below the code:
TIMER 2 INIT:
void MX_TIM2_Init(void)
{
TIM_ClockConfigTypeDef sClockSourceConfig = {0};
TIM_MasterConfigTypeDef sMasterConfig = {0};
TIM_OC_InitTypeDef sConfigOC = {0};
htim2.Instance = TIM2;
htim2.Init.Prescaler = 100;
htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
htim2.Init.Period = 100;
htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
if (HAL_TIM_Base_Init(&htim2) != HAL_OK)
{
Error_Handler();
}
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK)
{
Error_Handler();
}
if (HAL_TIM_OC_Init(&htim2) != HAL_OK)
{
Error_Handler();
}
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
{
Error_Handler();
}
sConfigOC.OCMode = TIM_OCMODE_TIMING;
sConfigOC.Pulse = 0;
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
if (HAL_TIM_OC_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
{
Error_Handler();
}
}ADC 1 INIT:
void MX_ADC1_Init(void)
{
ADC_ChannelConfTypeDef sConfig = {0};
/** Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)
*/
hadc1.Instance = ADC1;
hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2;
hadc1.Init.Resolution = ADC_RESOLUTION_8B;
hadc1.Init.ScanConvMode = DISABLE;
hadc1.Init.ContinuousConvMode = DISABLE;
hadc1.Init.DiscontinuousConvMode = DISABLE;
hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISING;
hadc1.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T2_TRGO;
hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc1.Init.NbrOfConversion = 1;
hadc1.Init.DMAContinuousRequests = DISABLE;
hadc1.Init.EOCSelection = ADC_EOC_SEQ_CONV;
if (HAL_ADC_Init(&hadc1) != HAL_OK)
{
Error_Handler();
}
/** Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
*/
sConfig.Channel = ADC_CHANNEL_0;
sConfig.Rank = 1;
sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES;
if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
{
Error_Handler();
}
}DMA INIT:
void MX_DMA_Init(void)
{
/* DMA controller clock enable */
__HAL_RCC_DMA2_CLK_ENABLE();
/* DMA interrupt init */
/* DMA2_Stream0_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn);
}MAIN AND CALLBACK:
#define DEBUG 1
#define UART_RX_BUF_SIZE 1
#define UART_TIMEOUT 0X00000FFF
#define ADC_BUF_SIZE 5
volatile uint8_t UART_rx_buf[UART_RX_BUF_SIZE] = {0};
volatile uint8_t UART_rx_pending = 0;
const volatile char UART_tx_start[1] = "U";
volatile uint8_t UART_timeout = 0;
volatile uint16_t ADC_buf[ADC_BUF_SIZE] = {0};
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_DMA_Init();
MX_USART2_UART_Init();
MX_ADC1_Init();
MX_TIM2_Init();
#ifdef DEBUG
DBGMCU->APB1FZ |= DBGMCU_APB1_FZ_DBG_TIM2_STOP;
#endif
/*INITIALIZATION: SEND A CHARACTER AND WAIT FOR A RESPONSE*/
HAL_Delay(10);
UART_timeout = HAL_UART_Transmit(&huart2, (uint8_t*)UART_tx_start, (uint16_t)1, (uint32_t)UART_TIMEOUT);
UART_timeout = HAL_UART_Receive(&huart2, (uint8_t*)UART_rx_buf, (uint16_t)UART_RX_BUF_SIZE, (uint32_t)UART_TIMEOUT);
if(UART_timeout == HAL_TIMEOUT) UART_config_timeout();
/*DSO START CONFIGURATION*/
TIMER_CONFIG(UART_rx_buf[0]); //SET TIMER PRSC AND ARR
HAL_UART_Receive_IT(&huart2, (uint8_t*)UART_rx_buf, (uint16_t)UART_RX_BUF_SIZE); //UART RX INTERUPT ENABLE
HAL_ADC_Start_DMA(&hadc1, (uint32_t*) ADC_buf, ADC_BUF_SIZE); //START ADC-DMA REQUEAST
HAL_TIM_Base_Start(&htim2); //START TIMER
while (1)
{
if(UART_rx_pending == 1) {
UART_rx_pending = 0;
/*MANAGE RX DATA*/
HAL_UART_Receive_IT(&huart2, (uint8_t*)UART_rx_buf, (uint16_t)UART_RX_BUF_SIZE);
}
}
}
============================================================================
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc) {
int i=0;
i++;
};
============================================================================The USART communication is just to set the ARR and PSC of the timer, but for debug, they are set at 0x63 (100)
Thanks to all!
