In the case where ICU overflow is used to accumulate timer wrap around (count periods in excess of the timer using the callbacks) then the change of state by the overflow handler prevents the period callback from ever being executed as follows...
The timer CC interrupt is handled but as the state is ICU_WAITING the ICU is still in synchronisation mode and simply changes state to ICU_ACTIVE.
The next overflow (since we are measuring a period beyond the timer capacity) will again set the state to ICU_WAITING.
Thus the ICU never reports anything other than OVERFLOW.
The ICU overflow handler should leave it to the user callback to determine what to do on overflow.
BTW in the case where ICU does not use callbacks then ICU state is not changed by the driver when an overflow occurs.
FYI the use case in the above is a GPS disciplined oscillator where the APB frequency (48MHz in this case) is counted using a 16 bit TIM ICU triggered by GPS TIMEPULSE all wrapped in a state machine.
The state machine manages start of accumulation (after one ICU period has been seen) and then accumulates each ICU overflow into a total count of clocking frequency + final amount taken at closing ICU period callback.
Code: Select all
Index: hal_icu.h
===================================================================
--- hal_icu.h (revision 12389)
+++ hal_icu.h (working copy)
@@ -200,8 +200,8 @@
/**
* @brief Common ISR code, ICU timer overflow event.
- * @note An overflow always brings the driver back to the @p ICU_WAITING
- * state.
+ * @note An overflow leaves the state unchanged so that the callback can
+ * determine what action to take.
*
* @param[in] icup pointer to the @p ICUDriver object
*
@@ -209,7 +209,6 @@
*/
#define _icu_isr_invoke_overflow_cb(icup) do { \
(icup)->config->overflow_cb(icup); \
- (icup)->state = ICU_WAITING; \
} while (0)
/** @} */