1 /*!
2 * @file tsc_time.c
3 *
4 * @brief This file contains all functions to manage the timings in general.
5 *
6 * @version V1.0.0
7 *
8 * @date 2022-02-21
9 *
10 * @attention
11 *
12 * Copyright (C) 2020-2022 Geehy Semiconductor
13 *
14 * You may not use this file except in compliance with the
15 * GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
16 *
17 * The program is only for reference, which is distributed in the hope
18 * that it will be useful and instructional for customers to develop
19 * their software. Unless required by applicable law or agreed to in
20 * writing, the program is distributed on an "AS IS" BASIS, WITHOUT
21 * ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
22 * See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
23 * and limitations under the License.
24 */
25
26 #include "tsc.h"
27 #include "tsc_time.h"
28
29 /** @addtogroup TSC_Driver_Library TSC Driver Library
30 @{
31 */
32
33 /** @addtogroup TSC_Time_Driver TSC Time Driver
34 @{
35 */
36
37 /** @defgroup TSC_Time_Macros Macros
38 @{
39 */
40
41 /**@} end of group TSC_Time_Macros */
42
43 /** @defgroup TSC_Time_Enumerations Enumerations
44 @{
45 */
46
47 /**@} end of group TSC_Time_Enumerations */
48
49 /** @defgroup TSC_Time_Structures Structures
50 @{
51 */
52
53 /**@} end of group TSC_Time_Structures */
54
55 /** @defgroup TSC_Time_Variables Variables
56 @{
57 */
58
59 /**@} end of group TSC_Time_Variables */
60
61 /** @defgroup TSC_Time_Functions Functions
62 @{
63 */
64
65 /*!
66 * @brief Configurate of the timing module
67 *
68 * @param None
69 *
70 * @retval pointer to a TSC_STATUS_T structure
71 */
TSC_Time_Config(void)72 TSC_STATUS_T TSC_Time_Config(void)
73 {
74 /* Program one systick interrupt every (1 / TOUCH_TICK_FREQ) ms */
75 if (SysTick_Config(SystemCoreClock / TOUCH_TICK_FREQ))
76 {
77 return TSC_STATUS_ERROR;
78 }
79 else
80 {
81 return TSC_STATUS_OK;
82 }
83 }
84
85 /*!
86 * @brief Management of the timing module interrupt service routine.
87 *
88 * @param None
89 *
90 * @retval None
91 */
TSC_Time_ProcessInterrupt(void)92 void TSC_Time_ProcessInterrupt(void)
93 {
94 static TSC_tTick_ms_T val_1s = 0;
95
96 /* Count 1 global tick every xxx ms (defined by TOUCH_TICK_FREQ parameter) */
97 TSC_Globals.Tick_ms++;
98
99 /* Check if 1 second has elapsed */
100 val_1s++;
101 if (val_1s > (TOUCH_TICK_FREQ - 1))
102 {
103 TSC_Globals.Tick_sec++;
104 if (TSC_Globals.Tick_sec > 63)
105 {
106 TSC_Globals.Tick_sec = 0;
107 }
108 val_1s = 0;
109 }
110
111 /* Callback function */
112 #if TOUCH_USE_TIMER_CALLBACK > 0
113 TSC_CallBack_TimerTick();
114 #endif
115 }
116
117 /*!
118 * @brief Check if a delay (in ms) has elapsed
119 * This function must be called regularly due to counter Roll-over only managed one time
120 *
121 * @param delay_ms: Delay in ms
122 *
123 * @param last_tick: Variable holding the last tick value
124 *
125 * @retval Status
126 */
TSC_Time_Delay_ms(TSC_tTick_ms_T delay_ms,__IO TSC_tTick_ms_T * last_tick)127 TSC_STATUS_T TSC_Time_Delay_ms(TSC_tTick_ms_T delay_ms, __IO TSC_tTick_ms_T* last_tick)
128 {
129 TSC_tTick_ms_T count1, count2;
130
131 disableInterrupts();
132
133 count1 = TSC_Globals.Tick_ms;
134
135 if (delay_ms == 0)
136 {
137 enableInterrupts();
138 return TSC_STATUS_ERROR;
139 }
140
141 /* Counter Roll-over management */
142 if (count1 < *last_tick)
143 {
144 count2 = (0xFFFF - *last_tick) + count1 + 1;
145
146 }
147 else
148 {
149 count2 = count1 - *last_tick;
150 }
151
152 #if (TOUCH_TICK_FREQ == 125)
153 if (count2 >= (TSC_tTick_ms_T)(delay_ms >> 3)) //!< Divide by 8 for 8ms tick
154 #endif
155 #if (TOUCH_TICK_FREQ == 250)
156 if (count2 >= (TSC_tTick_ms_T)(delay_ms >> 2)) //!< Divide by 4 for 4ms tick
157 #endif
158 #if (TOUCH_TICK_FREQ == 500)
159 if (count2 >= (TSC_tTick_ms_T)(delay_ms >> 1)) //!< Divide by 2 for 2ms tick
160 #endif
161 #if (TOUCH_TICK_FREQ == 1000)
162 if (count2 >= (TSC_tTick_ms_T)delay_ms) //!< Direct value for 1ms tick
163 #endif
164 #if (TOUCH_TICK_FREQ == 2000)
165 if (count2 >= (TSC_tTick_ms_T)(delay_ms << 1)) //!< Multiply by 2 for 0.5ms tick
166 #endif
167 {
168 /* Save current time */
169 *last_tick = count1;
170 enableInterrupts();
171 return TSC_STATUS_OK;
172 }
173 enableInterrupts();
174 return TSC_STATUS_BUSY;
175 }
176
177 /*!
178 * @brief Check if a delay has elapsed.
179 *
180 * @param delay_sec: Delay in seconds
181 *
182 * @param last_tick: Variable holding the last tick value
183 *
184 * @retval Status
185 */
TSC_Time_Delay_sec(TSC_tTick_sec_T delay_sec,__IO TSC_tTick_sec_T * last_tick)186 TSC_STATUS_T TSC_Time_Delay_sec(TSC_tTick_sec_T delay_sec, __IO TSC_tTick_sec_T* last_tick)
187 {
188 TSC_tTick_sec_T count1, count2;
189
190 disableInterrupts();
191
192 count1 = TSC_Globals.Tick_sec;
193
194 if (delay_sec == 0)
195 {
196 enableInterrupts();
197 return TSC_STATUS_ERROR;
198 }
199
200 /* Counter Roll-over management */
201 if (count1 < *last_tick)
202 {
203 count2 = (TSC_tTick_sec_T)((63 - *last_tick) + count1 + 1);
204
205 }
206 else
207 {
208 count2 = (TSC_tTick_sec_T)(count1 - *last_tick);
209 }
210
211 if (count2 >= delay_sec)
212 {
213 /* Save current time */
214 *last_tick = count1;
215 enableInterrupts();
216 return TSC_STATUS_OK;
217 }
218 enableInterrupts();
219 return TSC_STATUS_BUSY;
220 }
221
222 /**@} end of group TSC_Time_Functions */
223 /**@} end of group TSC_Time_Driver */
224 /**@} end of group TSC_Driver_Library */
225