1 /*
2  * Copyright (c) 2016-2020, 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 /*!
71  *  @brief  Prototype for a ClockP function.
72  */
73 typedef void (*ClockP_Fxn)(uintptr_t arg);
74 
75 /*!
76  *  @brief    Number of bytes greater than or equal to the size of any RTOS
77  *            ClockP object.
78  *
79  *  nortos:   32 (biggest of the HW-specific ClockP instance structs)
80  *  SysBIOS:  36
81  *  Zephyr:   Modified to match size of ClockP_Obj
82  */
83 #define ClockP_STRUCT_SIZE   (sizeof(struct k_timer) + \
84 	sizeof(ClockP_Fxn) + sizeof(uintptr_t) + \
85 	sizeof(uint32_t) * 2) + sizeof(bool)
86 
87 /*!
88  *  @brief    ClockP structure.
89  *
90  *  Opaque structure that should be large enough to hold any of the
91  *  RTOS specific ClockP objects.
92  */
93 typedef union ClockP_Struct {
94     uint32_t dummy;  /*!< Align object */
95     char     data[ClockP_STRUCT_SIZE];
96 } ClockP_Struct;
97 
98 /*!
99  *  @brief  Frequency-in-hertz struct
100  */
101 typedef struct {
102     uint32_t hi;      /*!< most significant 32-bits of frequency */
103     uint32_t lo;      /*!< least significant 32-bits of frequency */
104 } ClockP_FreqHz;
105 
106 /*!
107  *  @brief    Status codes for ClockP APIs
108  */
109 typedef enum {
110     ClockP_OK = 0,
111     ClockP_FAILURE = -1
112 } ClockP_Status;
113 
114 /*!
115  *  @brief    Opaque client reference to an instance of a ClockP
116  *
117  *  A ClockP_Handle returned from the ::ClockP_create represents that instance.
118  *  and then is used in the other instance based functions (e.g. ::ClockP_start,
119  *  ::ClockP_stop, etc.).
120  */
121 typedef  void *ClockP_Handle;
122 
123 #define ClockP_handle(x) ((ClockP_Handle)(x))
124 
125 extern uint32_t ClockP_tickPeriod;
126 
127 /*!
128  *  @brief    Basic ClockP Parameters
129  *
130  *  Structure that contains the parameters passed into ::ClockP_create
131  *  when creating a ClockP instance. The ::ClockP_Params_init function should
132  *  be used to initialize the fields to default values before the application
133  *  sets the fields manually. The ClockP default parameters are noted in
134  *  ClockP_Params_init.
135  *  The default startFlag is false, meaning the user will have to call
136  *  ClockP_start().  If startFlag is true, the clock instance will be
137  *  started automatically when it is created.
138  *
139  *  The default value of period is 0, indicating a one-shot clock object.
140  *  A non-zero period indicates the clock function will be called
141  *  periodically at the period rate (in system clock ticks), after the
142  *  clock is initially started and set to expire with the 'timeout'
143  *  argument.
144  */
145 typedef struct {
146     bool      startFlag; /*!< Start immediately after instance is created. */
147     uint32_t  period;    /*!< Period of clock object. */
148     uintptr_t arg;       /*!< Argument passed into the clock function. */
149 } ClockP_Params;
150 
151 
152 /*!
153  *  @brief  Function to construct a clock object.
154  *
155  *  @param  clockP    Pointer to ClockP_Struct object.
156  *  @param  timeout   The startup timeout, if supported by the RTOS.
157  *  @param  clockFxn  Function called when timeout or period expires.
158  *
159  *  @param  params    Pointer to the instance configuration parameters. NULL
160  *                    denotes to use the default parameters. The ClockP default
161  *                    parameters are noted in ::SwiP_Params_init.
162  *
163  *  @return A ClockP_Handle on success or a NULL on an error
164  */
165 extern ClockP_Handle ClockP_construct(ClockP_Struct *clockP,
166                                       ClockP_Fxn clockFxn,
167                                       uint32_t timeout,
168                                       ClockP_Params *params);
169 
170 /*!
171  *  @brief  Function to destruct a clock object
172  *
173  *  @param  clockP  Pointer to a ClockP_Struct object that was passed to
174  *                  ClockP_construct().
175  *
176  *  @return
177  */
178 extern void ClockP_destruct(ClockP_Struct *clockP);
179 
180 /*!
181  *  @brief  Function to create a clock object.
182  *
183  *  @param  clockFxn  Function called when timeout or period expires.
184  *  @param  timeout   The startup timeout, if supported by the RTOS.
185  *  @param  params    Pointer to the instance configuration parameters. NULL
186  *                    denotes to use the default parameters. The ClockP default
187  *                    parameters are noted in ::ClockP_Params_init.
188  *
189  *  @return A ClockP_Handle on success or a NULL on an error.  This handle can
190  *          be passed to ClockP_start()
191  */
192 extern ClockP_Handle ClockP_create(ClockP_Fxn clockFxn,
193                                    uint32_t timeout,
194                                    ClockP_Params *params);
195 
196 /*!
197  *  @brief  Function to delete a clock.
198  *
199  *  @param  handle  A ClockP_Handle returned from ::ClockP_create
200  */
201 extern void ClockP_delete(ClockP_Handle handle);
202 
203 /*!
204  *  @brief  Get CPU frequency in Hz
205  *
206  *  @param  freq  Pointer to the FreqHz structure
207  */
208 extern void ClockP_getCpuFreq(ClockP_FreqHz *freq);
209 
210 /*!
211  *  @brief  Get the system tick period in microseconds.
212  *
213  *  @return The kernel's system tick period in microseconds.
214  */
215 extern uint32_t ClockP_getSystemTickPeriod();
216 
217 /*!
218  *  @brief  Get the current tick value
219  *
220  *  The value returned will wrap back to zero after it reaches the max
221  *  value that can be stored in 32 bits.
222  *
223  *  @return Time in system clock ticks
224  */
225 extern uint32_t ClockP_getSystemTicks();
226 
227 /*!
228  *  @brief  Get number of ClockP tick periods expected to expire between
229  *          now and the next interrupt from the timer peripheral
230  *
231  *  Returns the number of ClockP tick periods that are expected to expore
232  *  between now and the next interrupt from the timer peripheral.
233  *
234  *  Used internally by PowerCC26XX module
235  *
236  *  @return count in ticks
237  */
238 extern uint32_t ClockP_getTicksUntilInterrupt();
239 
240 /*!
241  *  @brief  Get timeout of clock instance.
242  *
243  *  Returns the remaining time in clock ticks if the instance has
244  *  been started.  If the clock is not active, the initial timeout value
245  *  is returned.
246  *
247  *  @return  remaining timeout in clock ticks.
248  *
249  *  Cannot change the initial timeout if the clock has been started.
250  */
251 extern uint32_t ClockP_getTimeout(ClockP_Handle handle);
252 
253 /*!
254  *  @brief  Determine if a clock object is currently active (i.e., running)
255  *
256  *  Returns true if the clock object is currently active, otherwise
257  *  returns false.
258  *
259  *  @return  active state
260  */
261 extern bool ClockP_isActive(ClockP_Handle handle);
262 
263 /*!
264  *  @brief  Initialize params structure to default values.
265  *
266  *  The default parameters are:
267  *   - name: NULL
268  *   - arg: 0
269  *
270  *  @param params  Pointer to the instance configuration parameters.
271  */
272 extern void ClockP_Params_init(ClockP_Params *params);
273 
274 /*!
275  *  @brief  Set the initial timeout
276  *
277  *  @param timeout    Initial timeout in ClockP ticks
278  *
279  *  Cannot change the initial timeout if the clock has been started.
280  */
281 extern void ClockP_setTimeout(ClockP_Handle handle, uint32_t timeout);
282 
283 /*!
284  *  @brief  Function to start a clock.
285  *
286  *  @param  handle  A ClockP_Handle returned from ::ClockP_create
287  */
288 extern void ClockP_start(ClockP_Handle handle);
289 
290 /*!
291  *  @brief  Function to stop a clock.
292  *
293  *  @param  handle  A ClockP_Handle returned from ::ClockP_create
294  *
295  *  It is ok to call ClockP_stop() for a clock that has not been started.
296  *
297  *  @return Status of the functions
298  *    - ClockP_OK: Stopped the clock function successfully
299  *    - ClockP_FAILURE: The API failed.
300  */
301 extern void ClockP_stop(ClockP_Handle handle);
302 
303 extern void ClockP_timestamp(ClockP_Handle handle);
304 
305 /*!
306  *  @brief  Set delay in microseconds
307  *
308  *  @param  usec  A duration in micro seconds
309  *
310  *  @return ClockP_OK
311  */
312 extern void ClockP_usleep(uint32_t usec);
313 
314 /*!
315  *  @brief  Set delay in seconds
316  *
317  *  @param  sec  A duration in seconds
318  *
319  *  @return ClockP_OK
320  */
321 extern void ClockP_sleep(uint32_t sec);
322 
323 
324 #ifdef __cplusplus
325 }
326 #endif
327 
328 #endif /* ti_dpl_ClockP__include */
329