cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F411 Tim2 Input Capture via DMA

mh.ferris9
Associate II
Posted on August 18, 2015 at 11:56

I'm trying to get 2 channels (rising edge and falling edge) of Tim2 input capture via DMA working, using the HAL drivers. I had got it working without using the HAL drivers but decided I should probably use the HAL drivers instead because of the other peripherals I'm using would be a bit easier.

I can get one channel working at a time, but as soon as I combine them it fails on the second because its the same instance of Tim2 used for both DMA's, and its configured into a BUSY state by the first configuration. I could be wrong here, but thats what it looks like. I set up the instance of Tim2, set the IC config channel1 and then Ch2, then start the DMA. It fails at the second DMA start because its returningHAL_BUSY. Any ideas as to what to do?

void
HAL_TIM_IC_MspInit(TIM_HandleTypeDef *htim)
{
GPIO_InitTypeDef GPIO_InitStruct;
static
DMA_HandleTypeDef hdma_tim2;
/* TIM2 Peripheral clock enable */
__HAL_RCC_TIM2_CLK_ENABLE(); 
__HAL_RCC_DMA1_CLK_ENABLE();
/* Enable GPIO channels Clock */
__HAL_RCC_GPIOA_CLK_ENABLE();
/* Configure (TIM2_Channel) in Alternate function */
GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF1_TIM2;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* Configure the DMA streams */
/* Set the parameters to be configured */
hdma_tim2.Instance = DMA1_Stream6;
hdma_tim2.Init.Channel = DMA_CHANNEL_3;
hdma_tim2.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_tim2.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_tim2.Init.MemInc = DMA_MINC_ENABLE;
hdma_tim2.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
hdma_tim2.Init.MemDataAlignment = DMA_PDATAALIGN_WORD;
hdma_tim2.Init.Mode = DMA_CIRCULAR;
hdma_tim2.Init.Priority = DMA_PRIORITY_HIGH;
hdma_tim2.Init.FIFOMode = DMA_FIFOMODE_DISABLE; 
hdma_tim2.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_HALFFULL;
hdma_tim2.Init.MemBurst = DMA_MBURST_SINGLE;
hdma_tim2.Init.PeriphBurst = DMA_PBURST_SINGLE; 
HAL_DMA_Init(&hdma_tim2);
/* Associate the initialized DMA handle to the the ADC handle */
__HAL_LINKDMA(htim, hdma[TIM_DMA_ID_CC2], hdma_tim2);
#ifdef FALLING_EDGE_CAPTURE
hdma_tim2.Instance = DMA1_Stream5;
hdma_tim2.Init.Channel = DMA_CHANNEL_3;
hdma_tim2.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_tim2.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_tim2.Init.MemInc = DMA_MINC_ENABLE;
hdma_tim2.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
hdma_tim2.Init.MemDataAlignment = DMA_PDATAALIGN_WORD;
hdma_tim2.Init.Mode = DMA_CIRCULAR;
hdma_tim2.Init.Priority = DMA_PRIORITY_HIGH;
hdma_tim2.Init.FIFOMode = DMA_FIFOMODE_DISABLE; 
hdma_tim2.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_HALFFULL;
hdma_tim2.Init.MemBurst = DMA_MBURST_SINGLE;
hdma_tim2.Init.PeriphBurst = DMA_PBURST_SINGLE; 
HAL_DMA_Init(&hdma_tim2);
/* Associate the initialized DMA handle to the the ADC handle */
__HAL_LINKDMA(htim, hdma[TIM_DMA_ID_CC1], hdma_tim2);
#endif 
}
/* ==================== BELOW IN MAIN() ==================== */
/* Set TIM2 instance */
TimHandle2.Instance = TIM2;
/* Initialize TIMx peripheral */
TimHandle2.Init.Period = 0xFFFFFFFF;
TimHandle2.Init.Prescaler = 400;
TimHandle2.Init.ClockDivision = 0;
TimHandle2.Init.CounterMode = TIM_COUNTERMODE_UP;
TimHandle2.Init.RepetitionCounter = 0;
if
(HAL_TIM_IC_Init(&TimHandle2) != HAL_OK)
{
/* Initialization Error */
Error_Handler();
}
/* Configure the Input Capture of channel 2 */
sICConfig.ICPolarity = TIM_ICPOLARITY_RISING;
sICConfig.ICSelection = TIM_ICSELECTION_DIRECTTI;
sICConfig.ICPrescaler = TIM_ICPSC_DIV1;
sICConfig.ICFilter = 0; 
if
(HAL_TIM_IC_ConfigChannel(&TimHandle2, &sICConfig, TIM_CHANNEL_2) != HAL_OK)
{
/* Configuration Error */
Error_Handler();
}
#ifdef FALLING_EDGE_CAPTURE 
sICConfig.ICPolarity = TIM_ICPOLARITY_FALLING;
sICConfig.ICSelection = TIM_ICSELECTION_DIRECTTI;
sICConfig.ICPrescaler = TIM_ICPSC_DIV1;
sICConfig.ICFilter = 0; 
if
(HAL_TIM_IC_ConfigChannel(&TimHandle2, &sICConfig, TIM_CHANNEL_1) != HAL_OK)
{
/* Configuration Error */
Error_Handler();
}
#endif
if
(HAL_TIM_IC_Start_DMA(&TimHandle2, TIM_CHANNEL_2, DeltaBufferRising, DELTA_SAMPLES) != HAL_OK)
{
/* Initialization Error */
Error_Handler();
}
#ifdef FALLING_EDGE_CAPTURE 
if
(HAL_TIM_IC_Start_DMA(&TimHandle2, TIM_CHANNEL_1, DeltaBufferFalling, DELTA_SAMPLES) != HAL_OK)
{
// Initialization Error - FAILS HERE DUE TO TIM2 HANDLE BEING BUSY
Error_Handler();
}
#endif

#timer #stm32 #dma
0 REPLIES 0