1 /*
2 * Copyright (C) 2017 XRADIO TECHNOLOGY CO., LTD. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the
12 * distribution.
13 * 3. Neither the name of XRADIO TECHNOLOGY CO., LTD. nor the names of
14 * its contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30 #include "os_timer.h"
31 #include "os_util.h"
32
33
34 /**
35 * @brief Create and initialize a timer object
36 *
37 * @note Creating a timer does not start the timer running. The OS_TimerStart()
38 * and OS_TimerChangePeriod() API functions can all be used to start the
39 * timer running.
40 *
41 * @param[in] timer Pointer to the timer object
42 * @param[in] type Timer type
43 * @param[in] cb Timer expire callback function
44 * @param[in] arg Argument of Timer expire callback function
45 * @param[in] periodMS Timer period in milliseconds
46 * @retval OS_Status, OS_OK on success
47 */
OS_TimerCreate(OS_Timer_t * timer,OS_TimerType type,OS_TimerCallback_t cb,void * arg,OS_Time_t periodMS)48 OS_Status OS_TimerCreate(OS_Timer_t *timer, OS_TimerType type,
49 OS_TimerCallback_t cb, void *arg, OS_Time_t periodMS)
50 {
51 rt_uint8_t flag;
52
53 OS_HANDLE_ASSERT(!OS_TimerIsValid(timer), timer->handle);
54
55 flag = RT_TIMER_FLAG_SOFT_TIMER;
56 if (type == OS_TIMER_PERIODIC) {
57 flag |= RT_TIMER_FLAG_PERIODIC;
58 } else {
59 flag |= RT_TIMER_FLAG_ONE_SHOT;
60 }
61
62 timer->handle = rt_timer_create("os_timer", cb, arg,
63 OS_MSecsToTicks(periodMS), flag);
64 OS_DBG("%s(), handle %p\n", __func__, timer->handle);
65
66 if (timer->handle == NULL) {
67 OS_ERR("err %"OS_HANDLE_F"\n", timer->handle);
68 return OS_FAIL;
69 }
70 return OS_OK;
71 }
72
OS_TimerDelete(OS_Timer_t * timer)73 OS_Status OS_TimerDelete(OS_Timer_t *timer)
74 {
75 rt_err_t ret;
76
77 OS_DBG("%s(), handle %p\n", __func__, timer->handle);
78 OS_HANDLE_ASSERT(OS_TimerIsValid(timer), timer->handle);
79
80 ret = rt_timer_delete(timer->handle);
81 if (ret != RT_EOK) {
82 OS_ERR("err %"OS_BASETYPE_F"\n", ret);
83 return OS_FAIL;
84 }
85
86 OS_TimerSetInvalid(timer);
87 return OS_OK;
88 }
89
90 /**
91 * @brief Start a timer running.
92 * @note If the timer is already running, this function will re-start the timer.
93 * @param[in] timer Pointer to the timer object
94 * @retval OS_Status, OS_OK on success
95 */
OS_TimerStart(OS_Timer_t * timer)96 OS_Status OS_TimerStart(OS_Timer_t *timer)
97 {
98 rt_err_t ret;
99
100 OS_DBG("%s(), handle %p\n", __func__, timer->handle);
101 OS_HANDLE_ASSERT(OS_TimerIsValid(timer), timer->handle);
102
103 ret = rt_timer_start(timer->handle);
104 if (ret != RT_EOK) {
105 OS_ERR("err %"OS_BASETYPE_F"\n", ret);
106 return OS_FAIL;
107 }
108
109 return OS_OK;
110 }
111
112 /**
113 * @brief Change the period of a timer
114 *
115 * If OS_TimerChangePeriod() is used to change the period of a timer that is
116 * already running, then the timer will use the new period value to recalculate
117 * its expiry time. The recalculated expiry time will then be relative to when
118 * OS_TimerChangePeriod() was called, and not relative to when the timer was
119 * originally started.
120
121 * If OS_TimerChangePeriod() is used to change the period of a timer that is
122 * not already running, then the timer will use the new period value to
123 * calculate an expiry time, and the timer will start running.
124 *
125 * @param[in] timer Pointer to the timer object
126 * @retval OS_Status, OS_OK on success
127 */
OS_TimerChangePeriod(OS_Timer_t * timer,OS_Time_t periodMS)128 OS_Status OS_TimerChangePeriod(OS_Timer_t *timer, OS_Time_t periodMS)
129 {
130 rt_err_t ret;
131
132 OS_DBG("%s(), handle %p\n", __func__, timer->handle);
133 OS_HANDLE_ASSERT(OS_TimerIsValid(timer), timer->handle);
134
135 if (OS_TimerIsActive(timer)) {
136 ret = rt_timer_stop(timer->handle);
137 if (ret != RT_EOK) {
138 OS_ERR("err %"OS_BASETYPE_F"\n", ret);
139 return OS_FAIL;
140 }
141 }
142 ret = rt_timer_control(timer->handle, RT_TIMER_CTRL_SET_TIME, &periodMS);
143 if (ret != RT_EOK) {
144 OS_ERR("err %"OS_BASETYPE_F"\n", ret);
145 return OS_FAIL;
146 }
147 ret = rt_timer_start(timer->handle);
148 if (ret != RT_EOK) {
149 OS_ERR("err %"OS_BASETYPE_F"\n", ret);
150 return OS_FAIL;
151 }
152
153 return OS_OK;
154 }
155
156 /**
157 * @brief Stop a timer running.
158 * @param[in] timer Pointer to the timer object
159 * @retval OS_Status, OS_OK on success
160 */
OS_TimerStop(OS_Timer_t * timer)161 OS_Status OS_TimerStop(OS_Timer_t *timer)
162 {
163 rt_err_t ret;
164
165 OS_DBG("%s(), handle %p\n", __func__, timer->handle);
166 OS_HANDLE_ASSERT(OS_TimerIsValid(timer), timer->handle);
167
168 if (!OS_TimerIsActive(timer)) {
169 return OS_OK;
170 }
171
172 ret = rt_timer_stop(timer->handle);
173 if (ret != RT_EOK) {
174 OS_ERR("err %"OS_BASETYPE_F"\n", ret);
175 return OS_FAIL;
176 }
177
178 return OS_OK;
179 }
180