1 /*
2 * Copyright (c) 2018 Intel Corporation
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/kernel.h>
8 #include <cmsis_os.h>
9 #include <string.h>
10
11 #define ACTIVE 1
12 #define NOT_ACTIVE 0
13
14 static void zephyr_timer_wrapper(struct k_timer *timer);
15
16 struct timer_obj {
17 struct k_timer ztimer;
18 os_timer_type type;
19 uint32_t status;
20 void (*callback_function)(void const *argument);
21 void *arg;
22 };
23
24 K_MEM_SLAB_DEFINE(cmsis_timer_slab, sizeof(struct timer_obj),
25 CONFIG_CMSIS_TIMER_MAX_COUNT, __alignof__(struct timer_obj));
26
zephyr_timer_wrapper(struct k_timer * timer)27 static void zephyr_timer_wrapper(struct k_timer *timer)
28 {
29 struct timer_obj *cm_timer;
30
31 cm_timer = CONTAINER_OF(timer, struct timer_obj, ztimer);
32 (cm_timer->callback_function)(cm_timer->arg);
33 }
34
35 /**
36 * @brief Create a Timer
37 */
osTimerCreate(const osTimerDef_t * timer_def,os_timer_type type,void * argument)38 osTimerId osTimerCreate(const osTimerDef_t *timer_def, os_timer_type type,
39 void *argument)
40 {
41 struct timer_obj *timer;
42
43 if (timer_def == NULL) {
44 return NULL;
45 }
46
47 if (type != osTimerOnce && type != osTimerPeriodic) {
48 return NULL;
49 }
50
51 if (k_mem_slab_alloc(&cmsis_timer_slab, (void **)&timer, K_MSEC(100)) == 0) {
52 (void)memset(timer, 0, sizeof(struct timer_obj));
53 } else {
54 return NULL;
55 }
56
57 timer->callback_function = timer_def->ptimer;
58 timer->arg = argument;
59 timer->type = type;
60 timer->status = NOT_ACTIVE;
61
62 k_timer_init(&timer->ztimer, zephyr_timer_wrapper, NULL);
63
64 return (osTimerId)timer;
65 }
66
67 /**
68 * @brief Start or restart a Timer
69 */
osTimerStart(osTimerId timer_id,uint32_t millisec)70 osStatus osTimerStart(osTimerId timer_id, uint32_t millisec)
71 {
72 struct timer_obj *timer = (struct timer_obj *) timer_id;
73
74 if (timer == NULL) {
75 return osErrorParameter;
76 }
77
78 if (k_is_in_isr()) {
79 return osErrorISR;
80 }
81
82 if (timer->type == osTimerOnce) {
83 k_timer_start(&timer->ztimer, K_MSEC(millisec), K_NO_WAIT);
84 } else if (timer->type == osTimerPeriodic) {
85 k_timer_start(&timer->ztimer, K_MSEC(millisec),
86 K_MSEC(millisec));
87 }
88
89 timer->status = ACTIVE;
90 return osOK;
91 }
92
93 /**
94 * @brief Stop the Timer
95 */
osTimerStop(osTimerId timer_id)96 osStatus osTimerStop(osTimerId timer_id)
97 {
98 struct timer_obj *timer = (struct timer_obj *) timer_id;
99
100 if (timer == NULL) {
101 return osErrorParameter;
102 }
103
104 if (k_is_in_isr()) {
105 return osErrorISR;
106 }
107
108 if (timer->status == NOT_ACTIVE) {
109 return osErrorResource;
110 }
111
112 k_timer_stop(&timer->ztimer);
113 timer->status = NOT_ACTIVE;
114 return osOK;
115 }
116
117 /**
118 * @brief Delete the timer that was created by osTimerCreate
119 */
osTimerDelete(osTimerId timer_id)120 osStatus osTimerDelete(osTimerId timer_id)
121 {
122 struct timer_obj *timer = (struct timer_obj *) timer_id;
123
124 if (timer == NULL) {
125 return osErrorParameter;
126 }
127
128 if (k_is_in_isr()) {
129 return osErrorISR;
130 }
131
132 if (timer->status == ACTIVE) {
133 k_timer_stop(&timer->ztimer);
134 timer->status = NOT_ACTIVE;
135 }
136
137 k_mem_slab_free(&cmsis_timer_slab, (void *)timer);
138 return osOK;
139 }
140