1 /**
2  * @file lv_hal_tick.c
3  * Provide access to the system tick with 1 millisecond resolution
4  */
5 
6 /*********************
7  *      INCLUDES
8  *********************/
9 #include "lv_hal_tick.h"
10 #include <stddef.h>
11 
12 #if LV_TICK_CUSTOM == 1
13     #include LV_TICK_CUSTOM_INCLUDE
14 #endif
15 
16 /*********************
17  *      DEFINES
18  *********************/
19 
20 /**********************
21  *      TYPEDEFS
22  **********************/
23 
24 /**********************
25  *  STATIC PROTOTYPES
26  **********************/
27 
28 /**********************
29  *  STATIC VARIABLES
30  **********************/
31 #if !LV_TICK_CUSTOM
32     static uint32_t sys_time = 0;
33     static volatile uint8_t tick_irq_flag;
34 #endif
35 
36 /**********************
37  *      MACROS
38  **********************/
39 
40 /**********************
41  *   GLOBAL FUNCTIONS
42  **********************/
43 
44 #if !LV_TICK_CUSTOM
45 /**
46  * You have to call this function periodically
47  * @param tick_period the call period of this function in milliseconds
48  */
lv_tick_inc(uint32_t tick_period)49 LV_ATTRIBUTE_TICK_INC void lv_tick_inc(uint32_t tick_period)
50 {
51     tick_irq_flag = 0;
52     sys_time += tick_period;
53 }
54 #endif
55 
56 /**
57  * Get the elapsed milliseconds since start up
58  * @return the elapsed milliseconds
59  */
lv_tick_get(void)60 uint32_t lv_tick_get(void)
61 {
62 #if LV_TICK_CUSTOM == 0
63 
64     /*If `lv_tick_inc` is called from an interrupt while `sys_time` is read
65      *the result might be corrupted.
66      *This loop detects if `lv_tick_inc` was called while reading `sys_time`.
67      *If `tick_irq_flag` was cleared in `lv_tick_inc` try to read again
68      *until `tick_irq_flag` remains `1`.*/
69     uint32_t result;
70     do {
71         tick_irq_flag = 1;
72         result        = sys_time;
73     } while(!tick_irq_flag); /*Continue until see a non interrupted cycle*/
74 
75     return result;
76 #else
77     return LV_TICK_CUSTOM_SYS_TIME_EXPR;
78 #endif
79 }
80 
81 /**
82  * Get the elapsed milliseconds since a previous time stamp
83  * @param prev_tick a previous time stamp (return value of lv_tick_get() )
84  * @return the elapsed milliseconds since 'prev_tick'
85  */
lv_tick_elaps(uint32_t prev_tick)86 uint32_t lv_tick_elaps(uint32_t prev_tick)
87 {
88     uint32_t act_time = lv_tick_get();
89 
90     /*If there is no overflow in sys_time simple subtract*/
91     if(act_time >= prev_tick) {
92         prev_tick = act_time - prev_tick;
93     }
94     else {
95         prev_tick = UINT32_MAX - prev_tick + 1;
96         prev_tick += act_time;
97     }
98 
99     return prev_tick;
100 }
101 
102 /**********************
103  *   STATIC FUNCTIONS
104  **********************/
105