1 /*
2  * Copyright (c) 2016-2024, Texas Instruments Incorporated
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * *  Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  *
12  * *  Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * *  Neither the name of Texas Instruments Incorporated nor the names of
17  *    its contributors may be used to endorse or promote products derived
18  *    from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 /** ============================================================================
33  *  @file       ClockP.h
34  *
35  *  @brief      Clock interface for the RTOS Porting Interface
36  *
37  *  The ClockP module can be used to schedule functions that run at intervals
38  *  specified in the underlying kernel's system ticks.  ClockP instances are
39  *  one-shot.  The one-shot function will be run once
40  *  after the specified period has elapsed since calling ClockP_start().
41  *
42  *  The ClockP module can also be used to obtain the period of the kernel's
43  *  system tick in microseconds.  This is useful for determining the number of
44  *  ticks needed for setting a Clock object's period.
45  *
46  *  When using the TI-RTOS kernel, ClockP functions are run at software
47  *  interrupt level. With FreeRTOS, the ClockP functions are run by a timer
48  *  service task with priority configured by the application.
49  *
50  *  A common use case is to post a semaphore in the clock function. There is a
51  *  specific API for this: Semaphore_postFromClock(). This must be used in a
52  *  clock function (instead of Semaphore_post).
53  *
54  *  ============================================================================
55  */
56 
57 #ifndef ti_dpl_ClockP__include
58 #define ti_dpl_ClockP__include
59 
60 #include <stdint.h>
61 #include <stdbool.h>
62 #include <stddef.h>
63 
64 #include <zephyr/kernel.h>
65 
66 #ifdef __cplusplus
67 extern "C" {
68 #endif
69 
70 #define ClockP_TICK_PERIOD (USEC_PER_SEC / CONFIG_SYS_CLOCK_TICKS_PER_SEC)
71 
72 /*!
73  *  @brief  Prototype for a ClockP function.
74  */
75 typedef void (*ClockP_Fxn)(uintptr_t arg);
76 
77 /*!
78  *  @brief    Number of bytes greater than or equal to the size of any RTOS
79  *            ClockP object.
80  *
81  *  nortos:   32 (biggest of the HW-specific ClockP instance structs)
82  *  SysBIOS:  36
83  *  Zephyr:   Modified to match size of ClockP_Obj
84  */
85 #define ClockP_STRUCT_SIZE   (sizeof(struct k_timer) + \
86 	sizeof(ClockP_Fxn) + sizeof(uintptr_t) + \
87 	sizeof(uint32_t) * 2) + sizeof(bool)
88 
89 /*!
90  *  @brief    ClockP structure.
91  *
92  *  Opaque structure that should be large enough to hold any of the
93  *  RTOS specific ClockP objects.
94  */
95 typedef union ClockP_Struct {
96     uint32_t dummy;  /*!< Align object */
97     char     data[ClockP_STRUCT_SIZE];
98 } ClockP_Struct;
99 
100 /*!
101  *  @brief  Frequency-in-hertz struct
102  */
103 typedef struct {
104     uint32_t hi;      /*!< most significant 32-bits of frequency */
105     uint32_t lo;      /*!< least significant 32-bits of frequency */
106 } ClockP_FreqHz;
107 
108 /*!
109  *  @brief    Status codes for ClockP APIs
110  */
111 typedef enum {
112     ClockP_OK = 0,
113     ClockP_FAILURE = -1
114 } ClockP_Status;
115 
116 /*!
117  *  @brief    Opaque client reference to an instance of a ClockP
118  *
119  *  A ClockP_Handle returned from the ::ClockP_create represents that instance.
120  *  and then is used in the other instance based functions (e.g. ::ClockP_start,
121  *  ::ClockP_stop, etc.).
122  */
123 typedef  void *ClockP_Handle;
124 
125 #define ClockP_handle(x) ((ClockP_Handle)(x))
126 
127 extern uint32_t ClockP_tickPeriod;
128 
129 /*!
130  *  @brief    Basic ClockP Parameters
131  *
132  *  Structure that contains the parameters passed into ::ClockP_create
133  *  when creating a ClockP instance. The ::ClockP_Params_init function should
134  *  be used to initialize the fields to default values before the application
135  *  sets the fields manually. The ClockP default parameters are noted in
136  *  ClockP_Params_init.
137  *  The default startFlag is false, meaning the user will have to call
138  *  ClockP_start().  If startFlag is true, the clock instance will be
139  *  started automatically when it is created.
140  *
141  *  The default value of period is 0, indicating a one-shot clock object.
142  *  A non-zero period indicates the clock function will be called
143  *  periodically at the period rate (in system clock ticks), after the
144  *  clock is initially started and set to expire with the 'timeout'
145  *  argument.
146  */
147 typedef struct {
148     bool      startFlag; /*!< Start immediately after instance is created. */
149     uint32_t  period;    /*!< Period of clock object. */
150     uintptr_t arg;       /*!< Argument passed into the clock function. */
151 } ClockP_Params;
152 
153 
154 /*!
155  *  @brief  Function to construct a clock object.
156  *
157  *  @param  clockP    Pointer to ClockP_Struct object.
158  *  @param  timeout   The startup timeout, if supported by the RTOS.
159  *  @param  clockFxn  Function called when timeout or period expires.
160  *
161  *  @param  params    Pointer to the instance configuration parameters. NULL
162  *                    denotes to use the default parameters. The ClockP default
163  *                    parameters are noted in ::SwiP_Params_init.
164  *
165  *  @return A ClockP_Handle on success or a NULL on an error
166  */
167 extern ClockP_Handle ClockP_construct(ClockP_Struct *clockP,
168                                       ClockP_Fxn clockFxn,
169                                       uint32_t timeout,
170                                       ClockP_Params *params);
171 
172 /*!
173  *  @brief  Function to destruct a clock object
174  *
175  *  @param  clockP  Pointer to a ClockP_Struct object that was passed to
176  *                  ClockP_construct().
177  *
178  *  @return
179  */
180 extern void ClockP_destruct(ClockP_Struct *clockP);
181 
182 /*!
183  *  @brief  Function to create a clock object.
184  *
185  *  @param  clockFxn  Function called when timeout or period expires.
186  *  @param  timeout   The startup timeout, if supported by the RTOS.
187  *  @param  params    Pointer to the instance configuration parameters. NULL
188  *                    denotes to use the default parameters. The ClockP default
189  *                    parameters are noted in ::ClockP_Params_init.
190  *
191  *  @return A ClockP_Handle on success or a NULL on an error.  This handle can
192  *          be passed to ClockP_start()
193  */
194 extern ClockP_Handle ClockP_create(ClockP_Fxn clockFxn,
195                                    uint32_t timeout,
196                                    ClockP_Params *params);
197 
198 /*!
199  *  @brief  Function to delete a clock.
200  *
201  *  @param  handle  A ClockP_Handle returned from ::ClockP_create
202  */
203 extern void ClockP_delete(ClockP_Handle handle);
204 
205 /*!
206  *  @brief  Get CPU frequency in Hz
207  *
208  *  @param  freq  Pointer to the FreqHz structure
209  */
210 extern void ClockP_getCpuFreq(ClockP_FreqHz *freq);
211 
212 /*!
213  *  @brief  Get the system tick period in microseconds.
214  *
215  *  @return The kernel's system tick period in microseconds.
216  */
217 extern uint32_t ClockP_getSystemTickPeriod();
218 
219 /*!
220  *  @brief  Get the current tick value
221  *
222  *  The value returned will wrap back to zero after it reaches the max
223  *  value that can be stored in 32 bits.
224  *
225  *  @return Time in system clock ticks
226  */
227 extern uint32_t ClockP_getSystemTicks();
228 
229 /*!
230  *  @brief  Get number of ClockP tick periods expected to expire between
231  *          now and the next interrupt from the timer peripheral
232  *
233  *  Returns the number of ClockP tick periods that are expected to expire
234  *  between now and the next interrupt from the timer peripheral.
235  *
236  *  Used internally by PowerCC26XX module
237  *
238  *  @return count in ticks
239  */
240 extern uint32_t ClockP_getTicksUntilInterrupt();
241 
242 /*!
243  *  @brief  Get timeout of clock instance.
244  *
245  *  Returns the remaining time in clock ticks if the instance has
246  *  been started.  If the clock is not active, the initial timeout value
247  *  is returned.
248  *
249  *  @return  remaining timeout in clock ticks.
250  *
251  *  Cannot change the initial timeout if the clock has been started.
252  */
253 extern uint32_t ClockP_getTimeout(ClockP_Handle handle);
254 
255 /*!
256  *  @brief  Determine if a clock object is currently active (i.e., running)
257  *
258  *  Returns true if the clock object is currently active, otherwise
259  *  returns false.
260  *
261  *  @return  active state
262  */
263 extern bool ClockP_isActive(ClockP_Handle handle);
264 
265 /*!
266  *  @brief  Initialize params structure to default values.
267  *
268  *  The default parameters are:
269  *   - name: NULL
270  *   - arg: 0
271  *
272  *  @param params  Pointer to the instance configuration parameters.
273  */
274 extern void ClockP_Params_init(ClockP_Params *params);
275 
276 /*!
277  *  @brief  Function to overwrite ClockP callback function and arg
278  *
279  *  @param  handle    A #ClockP_Handle returned from #ClockP_create() or
280  *                    #ClockP_construct()
281  *  @param  clockFxn  Function called when timeout or period expires.
282  *  @param  arg       Argument passed to \c clockFxn
283  */
284 extern void ClockP_setFunc(ClockP_Handle handle, ClockP_Fxn clockFxn, uintptr_t arg);
285 
286 /*!
287  *  @brief  Set the initial timeout
288  *
289  *  @param timeout    Initial timeout in ClockP ticks
290  *
291  *  Cannot change the initial timeout if the clock has been started.
292  */
293 extern void ClockP_setTimeout(ClockP_Handle handle, uint32_t timeout);
294 
295 /*!
296  *  @brief  Function to start a clock.
297  *
298  *  @param  handle  A ClockP_Handle returned from ::ClockP_create
299  */
300 extern void ClockP_start(ClockP_Handle handle);
301 
302 /*!
303  *  @brief  Function to stop a clock.
304  *
305  *  @param  handle  A ClockP_Handle returned from ::ClockP_create
306  *
307  *  It is ok to call ClockP_stop() for a clock that has not been started.
308  *
309  *  @return Status of the functions
310  *    - ClockP_OK: Stopped the clock function successfully
311  *    - ClockP_FAILURE: The API failed.
312  */
313 extern void ClockP_stop(ClockP_Handle handle);
314 
315 extern void ClockP_timestamp(ClockP_Handle handle);
316 
317 /*!
318  *  @brief  Set delay in microseconds
319  *
320  *  @param  usec  A duration in micro seconds
321  *
322  *  @return ClockP_OK
323  */
324 extern void ClockP_usleep(uint32_t usec);
325 
326 /*!
327  *  @brief  Set delay in seconds
328  *
329  *  @param  sec  A duration in seconds
330  *
331  *  @return ClockP_OK
332  */
333 extern void ClockP_sleep(uint32_t sec);
334 
335 
336 #ifdef __cplusplus
337 }
338 #endif
339 
340 #endif /* ti_dpl_ClockP__include */
341