**Describe the bug** The function `HardwareTimer::setOverflow()` allow to set the overflow value as a `uint32_t` an then set the value of the STM32 ARR Register to: $overflow - 1$ since the function is meant to recieve as argument the overflow value and not the **terminal count**. has shown in the function implementation below. https://github.com/stm32duino/Arduino_Core_STM32/blob/8ff274affbbce42f1d452e74365b66ba03e66c6c/libraries/SrcWrapper/src/HardwareTimer.cpp#L521-L557 this works fine with 16 bit counters and 32 bit counters when not used in the full range. but to set the max value of a 32 bit counter the **ARR** register value should be set to `0xFFFFFFFF` to do so the function argument should be set to `0x100000000` but since the argument is defined as `uint32_t` the value will not fit and overflow as `0` I want to point out that setting the value to the maximum is an important thing, since not only will increase marginally the maximum counter value but more importantly allows to calculate values of thresholds and time elapsed between input capture event easly because `elapsedTicks = capture - oldCapture` if all variables are defined as `uint32_t` and the elapsedTicks guaranteed to be under `0x100000000` will work even if an overflow occurs. and in the same way when generating a square wave updating the **ARR** value with the next event value can be done as `nextVal = lastVal + delta` under the same conditions. this methods are common practice on timer usage on any $\mu Controller$ **workaround** In the actual state the problem can be solved by either - compensating for the missing value in the period computation ```C++ if(capture < captureOld) elapsedTicks = capture - oldCapture - 1; else elapsedTicks = capture - oldCapture; ``` - initializing the timer overflow by accessing directly to the STM32 HAL ```C++ timerObj_t _timerObj; _timerObj.handle.Instance = TIM2; __HAL_TIM_SET_AUTORELOAD(&_timerObj.handle, 0xFFFFFFFF); ``` neither of these solution are efficient nor elegant. **Suggested Fixes** to me the easiest way to fix this issue is changing the function definition from ```C++ void HardwareTimer::setOverflow(uint32_t overflow, TimerFormat_t format) ``` to ```C++ void HardwareTimer::setOverflow(uint64_t overflow, TimerFormat_t format) ``` by using this approach the fix should not cause any compatibility issues with existing code **Constatation** here you can see the serial output of the STM32 when measuring a 1hz pulse over an 80Mhz timebase both generated by the same oscilltor so they are perfectly coherent. all the readings are perfect except for when the overflow occurs in that case you sistematically get one count more that is due to the missing code. ``` captureOld capture difference 4059789198 4139789198 80000000 4139789198 4219789198 80000000 4219789198 4821903 80000001 4821903 84821903 80000000 84821903 164821903 80000000 164821903 244821903 80000000 ``` after applying one of the above workaround the error **never** appears again ``` captureOld capture difference 4106049847 4186049847 80000000 4186049847 4266049847 80000000 4266049847 51082551 80000000 51082551 131082551 80000000 131082551 211082551 80000000 211082551 291082551 80000000 ``` here there is a the code on witch i've found the bug: ```C++ #include <Arduino.h> HardwareTimer *FCT; //FCT Frequency Counter Timer volatile uint32_t captureOld = 0, capture; volatile uint32_t period; volatile bool newMeas = false; void IC_Callback(){ capture = FCT->getCaptureCompare(LL_TIM_CHANNEL_CH1); Serial.print(captureOld); //print inside an interrupt, bad practice but accettable for debugging Serial.print(" "); Serial.print(capture); Serial.print(" "); period = capture - captureOld; Serial.println(period); captureOld = capture; newMeas = true; } void setup() { Serial.begin(115200); FCT = new HardwareTimer(TIM2); FCT->setMode(LL_TIM_CHANNEL_CH1,TIMER_INPUT_CAPTURE_RISING,PA_0); FCT->setPrescaleFactor(1); FCT->setOverflow(0xFFFFFFFF);//max value on 32 bit // invert the comment on these line to passs //timerObj_t _timerObj; //from the bug to the workaround //_timerObj.handle.Instance = TIM2; // //__HAL_TIM_SET_AUTORELOAD(&_timerObj.handle, 0xFFFFFFFF); // FCT->updateRegistersIfNotRunning(_timerObj.handle.Instance); FCT->attachInterrupt(LL_TIM_CHANNEL_CH1,IC_Callback); FCT->resume(); } void loop() { if (newMeas){ //Serial.println(period); newMeas = false; } } // unrelated to the issue // this was the clock configuration to use a 10Mhz extenal oscillator // that was important to have the 1pps signal exactly coherent to the clock // otherwise the problem can be hard to spot // this may be replicable using a wave generated by another timer extern "C" void SystemClock_Config(void){...} ``` **Desktop :** - OS: Windows 10 - Platformio version: core 6.1.7 on clion - STM32 core version: 2.6.0 - Upload method: Default **Board:** - Name: Nucleo L476RG - Extra hardware used if any: squarewave generator