1 /**
2  * @file lv_tick.c
3  * Provide access to the system tick with 1 millisecond resolution
4  */
5 
6 /*********************
7  *      INCLUDES
8  *********************/
9 #include "lv_tick_private.h"
10 #include "../misc/lv_types.h"
11 #include "../core/lv_global.h"
12 
13 /*********************
14  *      DEFINES
15  *********************/
16 #define state LV_GLOBAL_DEFAULT()->tick_state
17 
18 /**********************
19  *      TYPEDEFS
20  **********************/
21 
22 /**********************
23  *  STATIC PROTOTYPES
24  **********************/
25 
26 /**********************
27  *  STATIC VARIABLES
28  **********************/
29 
30 /**********************
31  *      MACROS
32  **********************/
33 
34 /**********************
35  *   GLOBAL FUNCTIONS
36  **********************/
37 
lv_tick_inc(uint32_t tick_period)38 LV_ATTRIBUTE_TICK_INC void lv_tick_inc(uint32_t tick_period)
39 {
40     lv_tick_state_t * state_p = &state;
41 
42     state_p->sys_irq_flag = 0;
43     state_p->sys_time += tick_period;
44 }
45 
lv_tick_get(void)46 uint32_t lv_tick_get(void)
47 {
48     lv_tick_state_t * state_p = &state;
49 
50     if(state_p->tick_get_cb)
51         return state_p->tick_get_cb();
52 
53     /*If `lv_tick_inc` is called from an interrupt while `sys_time` is read
54      *the result might be corrupted.
55      *This loop detects if `lv_tick_inc` was called while reading `sys_time`.
56      *If `tick_irq_flag` was cleared in `lv_tick_inc` try to read again
57      *until `tick_irq_flag` remains `1`.*/
58     uint32_t result;
59     do {
60         state_p->sys_irq_flag = 1;
61         result        = state_p->sys_time;
62     } while(!state_p->sys_irq_flag); /*Continue until see a non interrupted cycle*/
63 
64     return result;
65 }
66 
lv_tick_elaps(uint32_t prev_tick)67 uint32_t lv_tick_elaps(uint32_t prev_tick)
68 {
69     uint32_t act_time = lv_tick_get();
70 
71     /*If there is no overflow in sys_time simple subtract*/
72     if(act_time >= prev_tick) {
73         prev_tick = act_time - prev_tick;
74     }
75     else {
76         prev_tick = UINT32_MAX - prev_tick + 1;
77         prev_tick += act_time;
78     }
79 
80     return prev_tick;
81 }
82 
lv_delay_ms(uint32_t ms)83 void lv_delay_ms(uint32_t ms)
84 {
85     if(state.delay_cb) {
86         state.delay_cb(ms);
87     }
88     else {
89         uint32_t t = lv_tick_get();
90         while(lv_tick_elaps(t) < ms) {
91             /*Do something to no call `lv_tick_elaps` too often as it might interfere with interrupts*/
92             volatile uint32_t i;
93             volatile uint32_t x = ms;
94             for(i = 0; i < 100; i++) {
95                 x = x * 3;
96             }
97         }
98     }
99 }
100 
lv_tick_set_cb(lv_tick_get_cb_t cb)101 void lv_tick_set_cb(lv_tick_get_cb_t cb)
102 {
103     state.tick_get_cb = cb;
104 }
105 
lv_delay_set_cb(lv_delay_cb_t cb)106 void lv_delay_set_cb(lv_delay_cb_t cb)
107 {
108     state.delay_cb = cb;
109 }
110 
111 /**********************
112  *   STATIC FUNCTIONS
113  **********************/
114