1 /*
2 * Copyright (c) 2018 Intel Corporation
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/kernel.h>
8 #include <string.h>
9 #include "wrapper.h"
10
11 #define ACTIVE 1
12 #define NOT_ACTIVE 0
13
14 static void zephyr_timer_wrapper(struct k_timer *timer);
15
16 K_MEM_SLAB_DEFINE(cv2_timer_slab, sizeof(struct cv2_timer),
17 CONFIG_CMSIS_V2_TIMER_MAX_COUNT, 4);
18
19 static const osTimerAttr_t init_timer_attrs = {
20 .name = "ZephyrTimer",
21 .attr_bits = 0,
22 .cb_mem = NULL,
23 .cb_size = 0,
24 };
25
zephyr_timer_wrapper(struct k_timer * timer)26 static void zephyr_timer_wrapper(struct k_timer *timer)
27 {
28 struct cv2_timer *cm_timer;
29
30 cm_timer = CONTAINER_OF(timer, struct cv2_timer, z_timer);
31 (cm_timer->callback_function)(cm_timer->arg);
32 }
33
34 /**
35 * @brief Create a Timer
36 */
osTimerNew(osTimerFunc_t func,osTimerType_t type,void * argument,const osTimerAttr_t * attr)37 osTimerId_t osTimerNew(osTimerFunc_t func, osTimerType_t type,
38 void *argument, const osTimerAttr_t *attr)
39 {
40 struct cv2_timer *timer;
41
42 if (type != osTimerOnce && type != osTimerPeriodic) {
43 return NULL;
44 }
45
46 if (k_is_in_isr()) {
47 return NULL;
48 }
49
50 if (attr == NULL) {
51 attr = &init_timer_attrs;
52 }
53
54 if (k_mem_slab_alloc(&cv2_timer_slab, (void **)&timer, K_MSEC(100)) == 0) {
55 (void)memset(timer, 0, sizeof(struct cv2_timer));
56 } else {
57 return NULL;
58 }
59
60 timer->callback_function = func;
61 timer->arg = argument;
62 timer->type = type;
63 timer->status = NOT_ACTIVE;
64
65 k_timer_init(&timer->z_timer, zephyr_timer_wrapper, NULL);
66
67 if (attr->name == NULL) {
68 strncpy(timer->name, init_timer_attrs.name,
69 sizeof(timer->name) - 1);
70 } else {
71 strncpy(timer->name, attr->name, sizeof(timer->name) - 1);
72 }
73
74 return (osTimerId_t)timer;
75 }
76
77 /**
78 * @brief Start or restart a Timer
79 */
osTimerStart(osTimerId_t timer_id,uint32_t ticks)80 osStatus_t osTimerStart(osTimerId_t timer_id, uint32_t ticks)
81 {
82 struct cv2_timer *timer = (struct cv2_timer *)timer_id;
83
84 if (timer == NULL) {
85 return osErrorParameter;
86 }
87
88 if (k_is_in_isr()) {
89 return osErrorISR;
90 }
91
92 if (timer->type == osTimerOnce) {
93 k_timer_start(&timer->z_timer, K_TICKS(ticks), K_NO_WAIT);
94 } else if (timer->type == osTimerPeriodic) {
95 k_timer_start(&timer->z_timer,
96 K_TICKS(ticks), K_TICKS(ticks));
97 }
98
99 timer->status = ACTIVE;
100 return osOK;
101 }
102
103 /**
104 * @brief Stop the Timer
105 */
osTimerStop(osTimerId_t timer_id)106 osStatus_t osTimerStop(osTimerId_t timer_id)
107 {
108 struct cv2_timer *timer = (struct cv2_timer *)timer_id;
109
110 if (timer == NULL) {
111 return osErrorParameter;
112 }
113
114 if (k_is_in_isr()) {
115 return osErrorISR;
116 }
117
118 if (timer->status == NOT_ACTIVE) {
119 return osErrorResource;
120 }
121
122 k_timer_stop(&timer->z_timer);
123 timer->status = NOT_ACTIVE;
124 return osOK;
125 }
126
127 /**
128 * @brief Delete the timer that was created by osTimerCreate
129 */
osTimerDelete(osTimerId_t timer_id)130 osStatus_t osTimerDelete(osTimerId_t timer_id)
131 {
132 struct cv2_timer *timer = (struct cv2_timer *) timer_id;
133
134 if (timer == NULL) {
135 return osErrorParameter;
136 }
137
138 if (k_is_in_isr()) {
139 return osErrorISR;
140 }
141
142 if (timer->status == ACTIVE) {
143 k_timer_stop(&timer->z_timer);
144 timer->status = NOT_ACTIVE;
145 }
146
147 k_mem_slab_free(&cv2_timer_slab, (void *)timer);
148 return osOK;
149 }
150
151 /**
152 * @brief Get name of a timer.
153 */
osTimerGetName(osTimerId_t timer_id)154 const char *osTimerGetName(osTimerId_t timer_id)
155 {
156 struct cv2_timer *timer = (struct cv2_timer *)timer_id;
157
158 if (k_is_in_isr() || (timer == NULL)) {
159 return NULL;
160 }
161
162 return timer->name;
163 }
164
165 /**
166 * @brief Check if a timer is running.
167 */
osTimerIsRunning(osTimerId_t timer_id)168 uint32_t osTimerIsRunning(osTimerId_t timer_id)
169 {
170 struct cv2_timer *timer = (struct cv2_timer *)timer_id;
171
172 if (k_is_in_isr() || (timer == NULL)) {
173 return 0;
174 }
175
176 return !(!(k_timer_remaining_get(&timer->z_timer)));
177 }
178