AnsweredAssumed Answered

STM32F411 Tim2 Input Capture via DMA

Question asked by cicerom on Aug 18, 2015
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 returning HAL_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

Outcomes