26
26
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
27
*/
28
28
#include <stddef.h>
29
+ #include <stdbool.h>
29
30
#include "us_ticker_api.h"
30
31
#include "PeripheralNames.h"
31
32
34
35
35
36
static TIM_HandleTypeDef TimMasterHandle ;
36
37
static int us_ticker_inited = 0 ;
38
+ static bool us_ticker_stabilized = false;
37
39
38
- volatile uint32_t SlaveCounter = 0 ;
40
+ volatile uint16_t SlaveCounter = 0 ;
39
41
volatile uint32_t oc_int_part = 0 ;
40
42
volatile uint16_t oc_rem_part = 0 ;
41
43
@@ -58,24 +60,39 @@ void us_ticker_init(void)
58
60
59
61
uint32_t us_ticker_read ()
60
62
{
61
- uint32_t counter , counter2 ;
63
+ volatile uint16_t cntH_old , cntH , cntL ;
64
+
62
65
if (!us_ticker_inited ) us_ticker_init ();
63
- // A situation might appear when Master overflows right after Slave is read and before the
64
- // new (overflowed) value of Master is read. Which would make the code below consider the
65
- // previous (incorrect) value of Slave and the new value of Master, which would return a
66
- // value in the past. Avoid this by computing consecutive values of the timer until they
67
- // are properly ordered.
68
- counter = (uint32_t )(SlaveCounter << 16 );
69
- counter += TIM_MST -> CNT ;
70
- while (1 ) {
71
- counter2 = (uint32_t )(SlaveCounter << 16 );
72
- counter2 += TIM_MST -> CNT ;
73
- if (counter2 > counter ) {
74
- break ;
75
- }
76
- counter = counter2 ;
77
- }
78
- return counter2 ;
66
+
67
+ // There's a situation where the first tick still may overflow and to avoid
68
+ // it we need to check if our ticker has stabilized and due to that we need
69
+ // to return only the lower part of your 32 bit software timer.
70
+ if (us_ticker_stabilized ) {
71
+ do {
72
+ // For some reason on L0xx series we need to read and clear the
73
+ // overflow flag which give extra time to propelry handle possible
74
+ // hiccup after ~60s
75
+ if (__HAL_TIM_GET_FLAG (& TimMasterHandle , TIM_FLAG_CC1OF ) == SET ) {
76
+ __HAL_TIM_CLEAR_FLAG (& TimMasterHandle , TIM_FLAG_CC1OF );
77
+ }
78
+ cntH_old = SlaveCounter ;
79
+ if (__HAL_TIM_GET_FLAG (& TimMasterHandle , TIM_FLAG_UPDATE ) == SET ) {
80
+ cntH_old += 1 ;
81
+ }
82
+ cntL = TIM_MST -> CNT ;
83
+
84
+ cntH = SlaveCounter ;
85
+ if (__HAL_TIM_GET_FLAG (& TimMasterHandle , TIM_FLAG_UPDATE ) == SET ) {
86
+ cntH += 1 ;
87
+ }
88
+ } while (cntH_old != cntH );
89
+ } else {
90
+ us_ticker_stabilized = true;
91
+ return (uint32_t ) TIM_MST -> CNT ;
92
+ }
93
+
94
+ // Glue the upper and lower part together to get a 32 bit timer
95
+ return (uint32_t )(cntH << 16 | cntL );
79
96
}
80
97
81
98
void us_ticker_set_interrupt (timestamp_t timestamp )
0 commit comments