2019-10-11 02:55 AM
Hello,
I need to count the number of (positive and negative) edges in a signal within certain time period. For that I use a timer on STM32L452. The AN4776 says that External Clock Mode 1 is able to update the counter on both edges (for the price of not being able to trigger). I tried this (see the code below) and figured out that with a 50% duty cycle square test signal of 100mHz the CNT register is incremented every 10 seconds by 2. I would expect the CNT to increment by 1 every 5 seconds.
What am I doing wrong?
Thanks
Petr
Below is my code using TIM2 CH1 for clock and CH3 for capture (without clock, DMA and interrupt initialization):
// ---------- initialize GPIO ------------
GPIO_InitTypeDef GpioInitStruct;
// initialize the bitstream pin
GpioInitStruct.Pin = GPIO_PIN_5;
GpioInitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GpioInitStruct.Mode = GPIO_MODE_AF_PP;
GpioInitStruct.Pull = GPIO_NOPULL;
GpioInitStruct.Alternate = GPIO_AF1_TIM2;
HAL_GPIO_Init(GPIOA, &GpioInitStruct);
// initialize the sync pin
GpioInitStruct.Pin = GPIO_PIN_2;
GpioInitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GpioInitStruct.Mode = GPIO_MODE_AF_PP;
GpioInitStruct.Pull = GPIO_NOPULL;
GpioInitStruct.Alternate = GPIO_AF1_TIM2;
HAL_GPIO_Init(GPIOA, &GpioInitStruct);
// ------------ initialize timer -------------
// basic initialization of the structure
TIM_HandleTypeDef *pTmrHandle;
pTmrHandle->Instance = TIM2;
pTmrHandle->Init.Prescaler = 0;
pTmrHandle->Init.CounterMode = TIM_COUNTERMODE_UP;
pTmrHandle->Init.Period = 0xffff;
pTmrHandle->Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
pTmrHandle->Init.RepetitionCounter = 0;
pTmrHandle->Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
// configure the clock source
TIM_ClockConfigTypeDef ClockSourceConfig;
ClockSourceConfig.ClockFilter = 0; // no filter
ClockSourceConfig.ClockPrescaler = TIM_CLOCKPRESCALER_DIV1; // no prescaler
ClockSourceConfig.ClockPolarity = TIM_CLOCKPOLARITY_BOTHEDGE; // trigger on both edges
ClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_TI1ED; // both edges
// select the clock using the above clock configuration
if (HAL_TIM_ConfigClockSource(pTmrHandle, &ClockSourceConfig) != HAL_OK) {
return false;
}
// initialize input capture time base
if (HAL_TIM_IC_Init(pTmrHandle) != HAL_OK) {
return false;
}
// configure the input-capture channel (triggered by the sync signal) to trigger on both edges
TIM_IC_InitTypeDef InputCaptureConfig = {
.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING, // trigger on the rising edge
.ICSelection = TIM_ICSELECTION_DIRECTTI, // direct mapping of timer inputs
.ICPrescaler = TIM_ICPSC_DIV1, // no divider - we want to count all edges
.ICFilter = 0, // no filter
};
// trigger on the rising edge of CH3 (sync)
if (HAL_TIM_IC_ConfigChannel(pTmrHandle, &InputCaptureConfig, TIM_CHANNEL_3) != HAL_OK) {
return false;
}
// configure both edges on CH1 (clock)
InputCaptureConfig.ICPolarity = TIM_INPUTCHANNELPOLARITY_BOTHEDGE;
if (HAL_TIM_IC_ConfigChannel(pTmrHandle, &InputCaptureConfig, TIM_CHANNEL_1) != HAL_OK) {
return false;
}
// to start reception:
if (HAL_TIM_IC_Start_DMA(pTmrHandle, TIM_CHANNEL_3, (uint32_t*)dmaBuffer_, 2 * dmaBlockSize_) != HAL_OK) {
return false;
}
2019-10-11 07:41 AM
At this moment, I am inclined to believe you've hit a genuine silicon bug.
You may want to contact ST directly, perhaps through the web support form. If I guess your nationality correctly based on your name, you can also try to describe the problem on hw-list at list.hw.cz .
You may want to try other pins, and/or other TIM, meantime.
JW