ruuvi.drivers.c ${PROJECT_VERSION}
Drivers for external sensors and peripherals on embedded systems.
Loading...
Searching...
No Matches
ruuvi_nrf5_sdk15_timer.c
Go to the documentation of this file.
3#if RUUVI_NRF5_SDK15_TIMER_ENABLED
7
8#include "nrf_error.h"
9#include "nrf_drv_clock.h"
10#include "sdk_errors.h"
11#include "app_timer.h"
12
13#include <stdbool.h>
14
15#if RI_TIMER_MAX_INSTANCES > 10
16#error "Allocating over 10 timers is not supported"
17#endif
18#if RI_TIMER_MAX_INSTANCES > 9
19APP_TIMER_DEF (timer_9);
20#endif
21#if RI_TIMER_MAX_INSTANCES > 8
22APP_TIMER_DEF (timer_8);
23#endif
24#if RI_TIMER_MAX_INSTANCES > 7
25APP_TIMER_DEF (timer_7);
26#endif
27#if RI_TIMER_MAX_INSTANCES > 6
28APP_TIMER_DEF (timer_6);
29#endif
30#if RI_TIMER_MAX_INSTANCES > 5
31APP_TIMER_DEF (timer_5);
32#endif
33#if RI_TIMER_MAX_INSTANCES > 4
34APP_TIMER_DEF (timer_4);
35#endif
36#if RI_TIMER_MAX_INSTANCES > 3
37APP_TIMER_DEF (timer_3);
38#endif
39#if RI_TIMER_MAX_INSTANCES > 2
40APP_TIMER_DEF (timer_2);
41#endif
42#if RI_TIMER_MAX_INSTANCES > 1
43APP_TIMER_DEF (timer_1);
44#endif
45#if RI_TIMER_MAX_INSTANCES > 0
46APP_TIMER_DEF (timer_0);
47#endif
48#if 0 >= RI_TIMER_MAX_INSTANCES
49#error "No instances enabled for application timer"
50#endif
51
52static uint8_t timer_idx = 0;
53static bool m_is_init = false;
54
58static app_timer_id_t get_timer_id (void)
59{
60 switch (timer_idx++)
61 {
62#if RI_TIMER_MAX_INSTANCES > 0
63
64 case 0:
65 return timer_0;
66#endif
67#if RI_TIMER_MAX_INSTANCES > 1
68
69 case 1:
70 return timer_1;
71#endif
72#if RI_TIMER_MAX_INSTANCES > 2
73
74 case 2:
75 return timer_2;
76#endif
77#if RI_TIMER_MAX_INSTANCES > 3
78
79 case 3:
80 return timer_3;
81#endif
82#if RI_TIMER_MAX_INSTANCES > 4
83
84 case 4:
85 return timer_4;
86#endif
87#if RI_TIMER_MAX_INSTANCES > 5
88
89 case 5:
90 return timer_5;
91#endif
92#if RI_TIMER_MAX_INSTANCES > 6
93
94 case 6:
95 return timer_6;
96#endif
97#if RI_TIMER_MAX_INSTANCES > 7
98
99 case 7:
100 return timer_7;
101#endif
102#if RI_TIMER_MAX_INSTANCES > 8
103
104 case 8:
105 return timer_8;
106#endif
107#if RI_TIMER_MAX_INSTANCES > 9
108
109 case 9:
110 return timer_9;
111#endif
112
113 default:
114 return NULL;
115 }
116}
117
119{
120 rd_status_t err_code = RD_SUCCESS;
121 ret_code_t nrf_code = NRF_SUCCESS;
122
123 if (m_is_init)
124 {
125 err_code |= RD_ERROR_INVALID_STATE;
126 }
127 // Initialize clock if not already initialized
128 else if (false == nrf_drv_clock_init_check())
129 {
130 nrf_code |= nrf_drv_clock_init();
131 err_code |= ruuvi_nrf5_sdk15_to_ruuvi_error (nrf_code);
132 }
133
134 if (RD_SUCCESS == err_code)
135 {
136 nrf_drv_clock_lfclk_request (NULL);
137 nrf_code |= app_timer_init();
138 }
139
140 if (NRF_SUCCESS == nrf_code)
141 {
142 m_is_init = true;
143 }
144
145 return ruuvi_nrf5_sdk15_to_ruuvi_error (nrf_code) | err_code;
146}
147
148//return true if timers have been successfully initialized.
149bool ri_timer_is_init (void)
150{
151 return m_is_init;
152}
153
155 p_timer_id, const ri_timer_mode_t mode,
156 const ruuvi_timer_timeout_handler_t timeout_handler)
157{
158 rd_status_t err_code = RD_SUCCESS;
159 app_timer_mode_t nrf_mode = APP_TIMER_MODE_SINGLE_SHOT;
160
161 if (m_is_init)
162 {
163 if (RI_TIMER_MODE_REPEATED == mode)
164 {
165 nrf_mode = APP_TIMER_MODE_REPEATED;
166 }
167
168 app_timer_id_t tid = get_timer_id();
169
170 if (NULL != tid)
171 {
172 ret_code_t nrf_code = app_timer_create (&tid,
173 nrf_mode,
174 (app_timer_timeout_handler_t) timeout_handler);
175
176 if (NRF_SUCCESS == nrf_code)
177 {
178 *p_timer_id = (void *) tid;
179 }
180
181 err_code |= ruuvi_nrf5_sdk15_to_ruuvi_error (err_code);
182 }
183 else
184 {
185 err_code |= RD_ERROR_RESOURCES;
186 }
187 }
188 else
189 {
190 err_code |= RD_ERROR_INVALID_STATE;
191 }
192
193 return err_code;
194}
195
197 timer_id, const uint32_t ms,
198 void * const context)
199{
200 // Counters are 24 bits
201 // nrf5 sdk_config.h has prescaler setting for timer, resolution can be traded for run time
202 if (APP_TIMER_TICKS (ms) >= (1 << 24))
203 {
204 ri_log (RI_LOG_LEVEL_ERROR, "Timer overflow, timer not started\r\n");
206 }
207
208 ret_code_t err_code = app_timer_start ( (app_timer_id_t) timer_id, APP_TIMER_TICKS (ms),
209 context);
210 return ruuvi_nrf5_sdk15_to_ruuvi_error (err_code);
211}
212
214{
215 ret_code_t err_code = app_timer_stop ( (app_timer_id_t) timer_id);
216 return ruuvi_nrf5_sdk15_to_ruuvi_error (err_code);
217}
218
220{
221 app_timer_stop_all();
222 nrf_drv_clock_lfclk_release();
223 timer_idx = 0;
224 m_is_init = false;
225 return RD_SUCCESS;
226}
227
228#endif
#define RD_ERROR_INVALID_PARAM
Invalid Parameter.
uint32_t rd_status_t
bitfield for representing errors
rd_status_t ruuvi_nrf5_sdk15_to_ruuvi_error(const ret_code_t error)
convert nrf5 sdk15 error code into Ruuvi error code.
#define RD_ERROR_RESOURCES
Not enough resources for operation.
#define RD_SUCCESS
Internal Error.
#define RD_ERROR_INVALID_STATE
Invalid state, operation disallowed in this state.
void ri_log(const ri_log_severity_t severity, const char *const message)
Queues messages into log.
@ RI_LOG_LEVEL_ERROR
bool ri_timer_is_init(void)
Check if timer is initialized.
rd_status_t ri_timer_uninit(void)
rd_status_t ri_timer_start(ri_timer_id_t timer_id, uint32_t ms, void *const context)
Start given timer at a mode defined in ri_timer_create.
rd_status_t ri_timer_create(ri_timer_id_t *p_timer_id, ri_timer_mode_t mode, ruuvi_timer_timeout_handler_t timeout_handler)
void(* ruuvi_timer_timeout_handler_t)(void *const p_context)
Function to be called when timer times out.
rd_status_t ri_timer_init(void)
ri_timer_mode_t
Enable implementation selected by application.
rd_status_t ri_timer_stop(ri_timer_id_t timer_id)
void * ri_timer_id_t
Pointer to timer data.
@ RI_TIMER_MODE_REPEATED
Header to enable and disable module compilation.
Ruuvi error codes and error check function.
Interface functions to timer.