cancel
Showing results for 
Search instead for 
Did you mean: 

Input capture interrupts not fired on STM32F401

marcosartore
Associate II

Hello,

I have configured a CUBE IDE project to match a Nucleo-F401RE board to measure the system clock pulses (at 84MHz) between to consecutive rising edges of an external signal applied to pin PA3 (which is Timer2 Channel4 input).

The Input Capture interrupt gets never fired.

I have done a similar test on a custom made board with a different STM32 chip (namely STM32L431RCT6) and the interrupts are fired. For this reason I suspect that the auto generated code by the IDE contains some error preventing the system to work properly, but I'm not able to identify what I am missing here.

Attached the whole CUBE IDE project.

Thanks in advance for your hints,

Marco

1 ACCEPTED SOLUTION

Accepted Solutions

Don't use (s)printf() and blocking calls (UART Tx) in the ISR.

JW

View solution in original post

5 REPLIES 5

Read out and check/post content of TIM and relevant GPIO registers.

If that's all OK, here are generic hints to debug "interrupt does not fire" problem.

JW

marcosartore
Associate II

Many thanks for your answer.

I will go through the indicated hints, but in the meantime I post the relevant main and tim code.

This is the main.c:

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
uint32_t IC1 = 0u;
uint32_t IC2 = 0u;
uint8_t flag =0u;
char str[50];
/* USER CODE END PM */
 
/* Private variables ---------------------------------------------------------*/
 
/* USER CODE BEGIN PV */
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef* htim)
{
	uint32_t d;
 
	sprintf(str, "In the ISR callback\n");
	HAL_UART_Transmit(&huart1, (uint8_t *) str, strlen(str), HAL_MAX_DELAY);
 
	if ( htim->Instance == TIM2)
	{
 
		if(!flag)
		{
			IC1 = HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_4);
			flag = 1;
		}
		else
		{
			IC2 = HAL_TIM_ReadCapturedValue(&htim2,TIM_CHANNEL_4);
			if (IC1 != 0u && IC2 != 0u)
			{
				flag = 0u;
				d = (IC2-IC1);
				sprintf(str, "IC1 = %ld, IC2 = %ld  --> delta = %ld\n", IC1, IC2, d);
				HAL_UART_Transmit(&huart1, (uint8_t *) str, strlen(str), HAL_MAX_DELAY);
			}
			IC1 = 0u;
			IC2 = 0u;
		}
	}
}
/* USER CODE END PV */
 
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */
 
/* USER CODE END PFP */
 
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
 
/* USER CODE END 0 */
 
/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */
 
  /* USER CODE END 1 */
 
  /* MCU Configuration--------------------------------------------------------*/
 
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();
 
  /* USER CODE BEGIN Init */
 
  /* USER CODE END Init */
 
  /* Configure the system clock */
  SystemClock_Config();
 
  /* USER CODE BEGIN SysInit */
 
  /* USER CODE END SysInit */
 
  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_TIM2_Init();
  MX_USART1_UART_Init();
  /* USER CODE BEGIN 2 */
  HAL_TIM_IC_Start_IT(&htim2,TIM_CHANNEL_4);
  /* USER CODE END 2 */
 
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */
 
    /* USER CODE BEGIN 3 */
    sprintf(str, "In the loop\n");
	HAL_UART_Transmit(&huart1, (uint8_t *) str, strlen(str), HAL_MAX_DELAY);
 
	HAL_GPIO_WritePin(LED_green_GPIO_Port, LED_green_Pin, GPIO_PIN_RESET);
	HAL_Delay(100);
	HAL_GPIO_WritePin(LED_green_GPIO_Port, LED_green_Pin, GPIO_PIN_SET);
	HAL_Delay(100);
  }
  /* USER CODE END 3 */
}

This is tim.c:

TIM_HandleTypeDef htim2;
 
/* TIM2 init function */
void MX_TIM2_Init(void)
{
 
  /* USER CODE BEGIN TIM2_Init 0 */
 
  /* USER CODE END TIM2_Init 0 */
 
  TIM_ClockConfigTypeDef sClockSourceConfig = {0};
  TIM_MasterConfigTypeDef sMasterConfig = {0};
  TIM_IC_InitTypeDef sConfigIC = {0};
 
  /* USER CODE BEGIN TIM2_Init 1 */
 
  /* USER CODE END TIM2_Init 1 */
  htim2.Instance = TIM2;
  htim2.Init.Prescaler = 1;
  htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
  htim2.Init.Period = 4294967295;
  htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;
  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_IC_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();
  }
  sConfigIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING;
  sConfigIC.ICSelection = TIM_ICSELECTION_DIRECTTI;
  sConfigIC.ICPrescaler = TIM_ICPSC_DIV1;
  sConfigIC.ICFilter = 0;
  if (HAL_TIM_IC_ConfigChannel(&htim2, &sConfigIC, TIM_CHANNEL_4) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN TIM2_Init 2 */
 
  /* USER CODE END TIM2_Init 2 */
 
}

Thanks again,

Marco

marcosartore
Associate II

I have checked the register and compared with those of the STM32L431, as far as I can argue, they are just OK. Then in the IDE I moved the input capture function from channel4 to channel1 and the interrupt started firing.

Since I need two channels, then I programmed also TIM5 (channel1) for input capture together with TIM2 (channel2: unfortunately channel1 is no longer possible because the input pin PA0 is shared with TIM5). Now the program gets stuck and even the main endless loop is not running, until I comment out the line

HAL_TIM_IC_Start_IT(&htim2,TIM_CHANNEL_2);

Then if commenting out this line the program runs normally and even the TIM5 interrupt is fired.

Since I am utilizing the bare Nucleo-F401RE, can anybody try and load the code of my original post and check if the same behavior is detected ? It is needed just a 30Hz square wave to apply at the timer(s) inputs.

Many thanks,

Marco

Don't use (s)printf() and blocking calls (UART Tx) in the ISR.

JW

marcosartore
Associate II

Thanks waclawek.jan, that was the issue (since the beginning), i.e. using blocking calls inside the ISR. After removing them, the original code as well as the latter work as expected.

Thanks for your support,

Marco