1 /*
2 * Copyright (c) 2017, Texas Instruments Incorporated
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/kernel.h>
8 #include <ti/drivers/dpl/ClockP.h>
9
10 #define CLOCKP_TICK_PERIOD (US_PER_S / CONFIG_SYS_CLOCK_TICKS_PER_SEC);
11
12 /*
13 * ClockP_STRUCT_SIZE in ClockP.h must be updated to match the size of this
14 * struct
15 */
16 typedef struct _ClockP_Obj {
17 struct k_timer timer;
18 ClockP_Fxn clock_fxn;
19 uintptr_t arg;
20 uint32_t timeout; /* in sys clock uptime ticks */
21 uint32_t period; /* in sys clock uptime ticks */
22 bool active;
23 } ClockP_Obj;
24
25 static ClockP_Params ClockP_defaultParams = {
26 .startFlag = false,
27 .period = 0,
28 .arg = 0,
29 };
30
expiry_fxn(struct k_timer * timer_id)31 static void expiry_fxn(struct k_timer *timer_id)
32 {
33 ClockP_Obj *obj = (ClockP_Obj *)k_timer_user_data_get(timer_id);
34
35 obj->clock_fxn(obj->arg);
36 }
37
38 /*
39 * ======== ClockP_construct ========
40 * @param timeout in sys clock uptime ticks
41 */
ClockP_construct(ClockP_Struct * handle,ClockP_Fxn clockFxn,uint32_t timeout,ClockP_Params * params)42 ClockP_Handle ClockP_construct(ClockP_Struct *handle, ClockP_Fxn clockFxn,
43 uint32_t timeout, ClockP_Params *params)
44 {
45 ClockP_Obj *obj = (ClockP_Obj *)handle;
46
47 if (handle == NULL) {
48 return NULL;
49 }
50
51 if (params == NULL) {
52 params = &ClockP_defaultParams;
53 }
54
55 obj->clock_fxn = clockFxn;
56 obj->arg = params->arg;
57 obj->period = params->period;
58 obj->timeout = timeout;
59 obj->active = false;
60
61 k_timer_init(&obj->timer, expiry_fxn, NULL);
62 k_timer_user_data_set(&obj->timer, obj);
63
64 if (params->startFlag) {
65 ClockP_start(obj);
66 }
67
68 return ((ClockP_Handle)handle);
69 }
70
71 /*
72 * ======== ClockP_getSystemTickFreq ========
73 */
ClockP_getSystemTickFreq()74 inline uint32_t ClockP_getSystemTickFreq()
75 {
76 return CONFIG_SYS_CLOCK_TICKS_PER_SEC;
77 }
78
79 /*
80 * ======== ClockP_getSystemTickPeriod ========
81 *
82 * This implementation rounds the system tick period down by ~17250ppm
83 * which makes it useless for any precision timing. Use
84 * (timeUs * ClockP_getSystemTickFreq() for these purposes instead.
85 */
ClockP_getSystemTickPeriod()86 inline uint32_t ClockP_getSystemTickPeriod()
87 {
88 return CLOCKP_TICK_PERIOD;
89 }
90
ClockP_getSystemTicks()91 uint32_t ClockP_getSystemTicks()
92 {
93 /* may wrap */
94 return k_uptime_ticks();
95 }
96
97 /*
98 * ======== ClockP_Params_init ========
99 */
ClockP_Params_init(ClockP_Params * params)100 void ClockP_Params_init(ClockP_Params *params)
101 {
102 params->arg = 0;
103 params->startFlag = false;
104 params->period = 0;
105 }
106
107 /*
108 * ======== ClockP_setTimeout ========
109 * @param timeout in sys clock uptime ticks
110 */
ClockP_setTimeout(ClockP_Handle handle,uint32_t timeout)111 void ClockP_setTimeout(ClockP_Handle handle, uint32_t timeout)
112 {
113 ClockP_Obj *obj = (ClockP_Obj *)handle;
114
115 obj->timeout = timeout;
116 }
117
118 /*
119 * ======== ClockP_start ========
120 */
ClockP_start(ClockP_Handle handle)121 void ClockP_start(ClockP_Handle handle)
122 {
123 ClockP_Obj *obj = (ClockP_Obj *)handle;
124
125 k_timer_start(&obj->timer, K_TICKS(obj->timeout), K_TICKS(obj->period));
126 obj->active = true;
127 }
128
129 /*
130 * ======== ClockP_stop ========
131 */
ClockP_stop(ClockP_Handle handle)132 void ClockP_stop(ClockP_Handle handle)
133 {
134 ClockP_Obj *obj = (ClockP_Obj *)handle;
135
136 k_timer_stop(&obj->timer);
137 obj->active = false;
138 }
139
140 /*
141 * ======== ClockP_usleep ========
142 */
ClockP_usleep(uint32_t usec)143 void ClockP_usleep(uint32_t usec)
144 {
145 k_sleep(K_USEC(usec));
146 }
147
148 /*
149 * ======== ClockP_getTimeout ========
150 */
ClockP_getTimeout(ClockP_Handle handle)151 uint32_t ClockP_getTimeout(ClockP_Handle handle) {
152 ClockP_Obj *obj = (ClockP_Obj *)handle;
153 return obj->active ? k_timer_remaining_ticks(&obj->timer) : obj->timeout;
154 }
155
156 /*
157 * ======== ClockP_isActive ========
158 */
ClockP_isActive(ClockP_Handle handle)159 bool ClockP_isActive(ClockP_Handle handle) {
160 ClockP_Obj *obj = (ClockP_Obj *)handle;
161 return obj->active;
162 }
163
ClockP_destruct(ClockP_Struct * clockP)164 void ClockP_destruct(ClockP_Struct *clockP)
165 {
166 ClockP_Obj *obj = (ClockP_Obj *)clockP->data;
167
168 obj->clock_fxn = NULL;
169 obj->arg = 0;
170 obj->period = 0;
171 obj->timeout = 0;
172 obj->active = false;
173
174 k_timer_stop(&obj->timer);
175 }
176