Timer in slave reset mode is not resetting counter?
I've spent literally dozens of hours just trying to understand and get a timer to work. This is not due to a lack of effort.
I'm creating a setup to use TIM1 in input capture mode to capture the rising and falling edges of a pin coming from an IR receiver, using the same strategy STM shows in AN4834. Full code is below. I understand everything about the basic timer setup, and setting up the two input channels to capture both edges. All good.
I thought I fully understood the point of the slave mode configuration: The slave aspect is used so that on the specified edge (the falling edge) of the specified timer input (TI2FP2), the clock is reset. So on the falling edge of IC2, the count is captured (in CC2), and then the clock resets to 0. However...
However, what I'm seeing is that even though the falling edge and capture occurs, the clock is NOT being reset to 0. It keeps counting up until the period elapses and an update event is generated. Why?
GPIO_InitTypeDef gpio_init_struct = {0};
TIM_IC_InitTypeDef tim_ic_init = {0};
TIM_SlaveConfigTypeDef tim_slave_conf = {0};
TIM_MasterConfigTypeDef tim_master_conf = {0};
gpio_init_struct.Pin = irPin;
gpio_init_struct.Mode = GPIO_MODE_AF_OD;
gpio_init_struct.Pull = GPIO_NOPULL;
gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;
gpio_init_struct.Alternate = GPIO_AF2_TIM1;
HAL_GPIO_Init(irPort, &gpio_init_struct);
timer->Instance = TIM1;
timer->Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
timer->Init.CounterMode = TIM_COUNTERMODE_UP;
timer->Init.Period = clockHz / 1000 * BEACON_TIMEOUT_MS - 1;
timer->Init.Prescaler = TIMER_PRESCALER - 1;
timer->Init.RepetitionCounter = 0;
timer->Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
HAL_TIM_IC_Init(timer);
tim_ic_init.ICPolarity = TIM_ICPOLARITY_RISING;
tim_ic_init.ICSelection = TIM_ICSELECTION_DIRECTTI;
tim_ic_init.ICPrescaler = TIM_ICPSC_DIV1;
tim_ic_init.ICFilter = 0x0;
HAL_TIM_IC_ConfigChannel(timer, &tim_ic_init, TIM_CHANNEL_1);
tim_ic_init.ICPolarity = TIM_ICPOLARITY_FALLING;
tim_ic_init.ICSelection = TIM_ICSELECTION_INDIRECTTI; // same pin as Channel 1
tim_ic_init.ICPrescaler = TIM_ICPSC_DIV1;
tim_ic_init.ICFilter = 0x0;
HAL_TIM_IC_ConfigChannel(timer, &tim_ic_init, TIM_CHANNEL_2);
tim_slave_conf.SlaveMode = TIM_SLAVEMODE_RESET;
tim_slave_conf.InputTrigger = TIM_TS_TI2FP2;
tim_slave_conf.TriggerPolarity = TIM_TRIGGERPOLARITY_FALLING;
tim_slave_conf.TriggerFilter = 0;
HAL_TIM_SlaveConfigSynchro(timer, &tim_slave_conf);
tim_master_conf.MasterSlaveMode = TIM_MASTERSLAVEMODE_ENABLE;
tim_master_conf.MasterOutputTrigger = TIM_TRGO_RESET;
HAL_TIMEx_MasterConfigSynchronization(timer, &tim_master_conf);
__HAL_RCC_TIM1_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
HAL_NVIC_SetPriority(TIM1_CC_IRQn, 0, 1);
HAL_NVIC_EnableIRQ(TIM1_CC_IRQn);
__HAL_TIM_URS_ENABLE(timer);
__HAL_TIM_CLEAR_FLAG(timer, TIM_FLAG_UPDATE | TIM_FLAG_CC1 | TIM_FLAG_CC2);
__HAL_TIM_ENABLE_IT(timer, TIM_FLAG_UPDATE | TIM_IT_CC1 | TIM_IT_CC2);
__HAL_TIM_ENABLE(timer);
if (HAL_TIM_IC_Start_IT(timer, TIM_CHANNEL_1) != HAL_OK) {
while (1)
{}
}
if (HAL_TIM_IC_Start_IT(timer, TIM_CHANNEL_2) != HAL_OK) {
while (1)
{}
}Bonus questions:
1) What purpose is the "master" side of this doing? Why does the TRGO of the master matter at all? As I understand it, the only thing the master's configuration as shown above means is that if an update event is generated, then TRGO goes high also. But what *uses* that TRGO in this arrangement?
2) Since both input channels are connected to the same pin due to the use of indirect mode on channel 2, doesn't that mean that for the slave configuration the input trigger could be either TIM_TS_TI1FP1 *or* TIM_TS_TI2FP2? Aren't they doing the same exact thing?
