ruuvi.drivers.c ${PROJECT_VERSION}
Drivers for external sensors and peripherals on embedded systems.
Loading...
Searching...
No Matches
ruuvi_task_led.c
Go to the documentation of this file.
1
12#if RT_LED_ENABLED
13#include "ruuvi_task_led.h"
14#include "ruuvi_driver_error.h"
17#include <stddef.h>
18
19static uint16_t m_activity_led;
20static uint16_t m_blink_led;
21static bool m_initialized;
22static ri_gpio_id_t m_led_list[RT_MAX_LED_CFG];
23static ri_gpio_state_t m_led_active_state[RT_MAX_LED_CFG];
24//Store user configured led number in case there's extra space in array.
25static size_t m_num_leds;
26// Timer instance for LED timer
27#ifndef CEEDLING
28static
29#endif
30ri_timer_id_t m_timer;
31
32#ifndef CEEDLING
33static
34#endif
35int8_t is_led (const ri_gpio_id_t led)
36{
37 int8_t led_valid = -1;
38
39 for (size_t ii = 0U;
40 (ii < m_num_leds) && (0 > led_valid);
41 ii++)
42 {
43 if (led == m_led_list[ii])
44 {
45 led_valid = ii;
46 }
47 }
48
49 return led_valid;
50}
51
52static inline ri_gpio_state_t led_to_pin_state (ri_gpio_id_t led, bool active)
53{
55 int8_t index = is_led (led);
56
57 if (index > -1)
58 {
59 if (RI_GPIO_HIGH == m_led_active_state[index])
60 {
61 state = active ? RI_GPIO_HIGH : RI_GPIO_LOW;
62 }
63 else
64 {
65 state = active ? RI_GPIO_LOW : RI_GPIO_HIGH;
66 }
67 }
68
69 return state;
70}
71
72rd_status_t rt_led_init (const ri_gpio_id_t * const leds,
73 const ri_gpio_state_t * const active_states,
74 const size_t num_leds)
75{
76 rd_status_t err_code = RD_SUCCESS;
77
78 if (m_initialized)
79 {
80 err_code |= RD_ERROR_INVALID_STATE;
81 }
82 else
83 {
84 if (!ri_gpio_is_init())
85 {
86 err_code |= ri_gpio_init();
87 }
88 }
89
90 if (RD_SUCCESS == err_code)
91 {
92 for (size_t ii = 0u; ii < num_leds; ii++)
93 {
94 m_led_list[ii] = leds[ii];
95 m_led_active_state[ii] = active_states[ii];
96 err_code |= ri_gpio_configure (m_led_list[ii],
98 err_code |= ri_gpio_write (m_led_list[ii], !m_led_active_state[ii]);
99 }
100
101 m_activity_led = RI_GPIO_ID_UNUSED;
102 m_blink_led = RI_GPIO_ID_UNUSED;
103 m_num_leds = num_leds;
104 m_initialized = true;
105 }
106
107 return err_code;
108}
109
111{
112 rd_status_t err_code = RD_SUCCESS;
113
114 for (size_t ii = 0U; ii < m_num_leds; ii++)
115 {
116 err_code |= ri_gpio_configure (m_led_list[ii], RI_GPIO_MODE_HIGH_Z);
117 }
118
119 m_activity_led = RI_GPIO_ID_UNUSED;
120 m_blink_led = RI_GPIO_ID_UNUSED;
121 m_initialized = false;
122 m_num_leds = 0;
123 return err_code;
124}
125
126rd_status_t rt_led_write (const ri_gpio_id_t led, const bool active)
127{
128 rd_status_t err_code = RD_SUCCESS;
129
130 if (!m_initialized)
131 {
132 err_code |= RD_ERROR_INVALID_STATE;
133 }
134 else if (0 > is_led (led))
135 {
136 err_code |= RD_ERROR_INVALID_PARAM;
137 }
138 else
139 {
140 const ri_gpio_state_t state = led_to_pin_state (led, active);
141 err_code |= ri_gpio_write (led, state);
142 }
143
144 return err_code;
145}
146
147void rt_led_activity_indicate (const bool active)
148{
149 // Error code cannot be returned, ignore
150 (void) rt_led_write (m_activity_led, active);
151}
152
154{
155 rd_status_t err_code = RD_SUCCESS;
156
157 if (RI_GPIO_ID_UNUSED == led)
158 {
159 m_activity_led = RI_GPIO_ID_UNUSED;
160 }
161 else if (0 > is_led (led))
162 {
163 err_code |= RD_ERROR_INVALID_PARAM;
164 }
165 else
166 {
167 m_activity_led = led;
168 }
169
170 return err_code;
171}
172
173uint16_t rt_led_activity_led_get (void)
174{
175 return m_activity_led;
176}
177
178#ifndef CEEDLING
179static
180#endif
181void rt_led_blink_isr (void * const p_context)
182{
183 static bool active = true;
184 rt_led_write (m_blink_led, active);
185 active = !active;
186}
187
188#ifndef CEEDLING
189static
190#endif
191void rt_led_blink_once_isr (void * const p_context)
192{
193 rt_led_blink_stop (m_blink_led);
194}
195
196rd_status_t rt_led_blink_start (const ri_gpio_id_t led, const uint16_t interval_ms)
197{
198 rd_status_t err_code = RD_SUCCESS;
199
200 if (!ri_timer_is_init())
201 {
202 err_code |= ri_timer_init();
203 }
204
205 if (!m_timer)
206 {
207 err_code |= ri_timer_create (&m_timer, RI_TIMER_MODE_REPEATED, &rt_led_blink_isr);
208 }
209
210 if (RI_GPIO_ID_UNUSED != m_blink_led)
211 {
212 err_code |= RD_ERROR_INVALID_STATE;
213 }
214
215 if (0 > is_led (led))
216 {
217 err_code |= RD_ERROR_INVALID_PARAM;
218 }
219
220 if (RD_SUCCESS == err_code)
221 {
222 err_code |= ri_timer_start (m_timer, interval_ms, NULL);
223 }
224
225 if (RD_SUCCESS == err_code)
226 {
227 m_blink_led = led;
228 }
229
230 return err_code;
231}
232
233rd_status_t rt_led_blink_once (const ri_gpio_id_t led, const uint16_t interval_ms)
234{
235 rd_status_t err_code = RD_SUCCESS;
236
237 if (!ri_timer_is_init())
238 {
239 err_code |= ri_timer_init();
240 }
241
242 if (!m_timer)
243 {
244 err_code |= ri_timer_create (&m_timer, RI_TIMER_MODE_SINGLE_SHOT, &rt_led_blink_once_isr);
245 }
246
247 if (RI_GPIO_ID_UNUSED != m_blink_led)
248 {
249 err_code |= RD_ERROR_INVALID_STATE;
250 }
251
252 if (0 > is_led (led))
253 {
254 err_code |= RD_ERROR_INVALID_PARAM;
255 }
256
257 if (RD_SUCCESS == err_code)
258 {
259 err_code |= ri_timer_start (m_timer, interval_ms, NULL);
260 }
261
262 if (RD_SUCCESS == err_code)
263 {
264 m_blink_led = led;
265 err_code |= rt_led_write (m_blink_led, true);
266 }
267
268 return err_code;
269}
270
272{
273 rd_status_t err_code = RD_SUCCESS;
274
275 if (led != m_blink_led)
276 {
277 err_code |= RD_ERROR_INVALID_STATE;
278 }
279 else
280 {
281 ri_timer_stop (m_timer);
282 m_blink_led = RI_GPIO_ID_UNUSED;
283 rt_led_write (led, false);
284 }
285
286 return err_code;
287}
288
289bool rt_led_is_init (void)
290{
291 return m_initialized;
292}
293
294#endif
#define RD_ERROR_INVALID_PARAM
Invalid Parameter.
uint32_t rd_status_t
bitfield for representing errors
#define RD_SUCCESS
Internal Error.
#define RD_ERROR_INVALID_STATE
Invalid state, operation disallowed in this state.
bool ri_gpio_is_init(void)
return true if GPIO is init, false otherwise.
rd_status_t ri_gpio_configure(const ri_gpio_id_t pin, const ri_gpio_mode_t mode)
Configure a pin of a port into a mode. If there are several ports the platform driver must implement ...
rd_status_t ri_gpio_init(void)
Initializes GPIO module. Call this before other GPIO functions. After initialization all GPIO pins sh...
rd_status_t ri_gpio_write(const ri_gpio_id_t pin, const ri_gpio_state_t state)
Write a pin of a port into given state If there are several ports the platform driver must implement ...
bool ri_timer_is_init(void)
Check if timer is initialized.
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)
rd_status_t ri_timer_init(void)
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
@ RI_TIMER_MODE_SINGLE_SHOT
Header to enable and disable module compilation.
Ruuvi error codes and error check function.
uint16_t ri_gpio_id_t
port<<8 + pin
#define RI_GPIO_ID_UNUSED
Enable implementation selected by application.
@ RI_GPIO_MODE_OUTPUT_HIGHDRIVE
Push-pull output, can be written. Higher current drive than standard.
@ RI_GPIO_MODE_HIGH_Z
High-impedance mode, electrically disconnected.
ri_gpio_state_t
States of GPIO pins.
@ RI_GPIO_LOW
GPIO electrically low.
@ RI_GPIO_HIGH
GPIO electrically high.
Interface functions to timer.
rd_status_t rt_led_init(const ri_gpio_id_t *const leds, const ri_gpio_state_t *const active_states, const size_t num_leds)
LED initialization function.
rd_status_t rt_led_blink_once(const ri_gpio_id_t led, const uint16_t interval_ms)
Function to blink led once.
rd_status_t rt_led_activity_led_set(const ri_gpio_id_t led)
Set LED which is used to indicate activity.
uint16_t rt_led_activity_led_get(void)
Get LED which is used to indicate activity.
bool rt_led_is_init(void)
Check if LED task has been initialized.
rd_status_t rt_led_blink_start(const ri_gpio_id_t led, const uint16_t interval_ms)
Start blinking led at 50 % duty cycle at given interval.
rd_status_t rt_led_blink_stop(const ri_gpio_id_t led)
Stop blinking led and leave the pin as high-drive output in inactive state.
rd_status_t rt_led_write(const ri_gpio_id_t led, const bool state)
LED write function. Set given LED ON or OFF.
void rt_led_activity_indicate(const bool state)
Function to indicate activity in program. Led is turned on while program is active and off while in s...
rd_status_t rt_led_uninit(void)
LED uninitialization function.