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