5
5
*/
6
6
7
7
#include <zephyr/drivers/led.h>
8
+ #include <zephyr/kernel.h>
8
9
9
- int z_impl_led_on (const struct device * dev , uint32_t led )
10
+ #include "led_blink.h"
11
+
12
+ static int led_core_on (const struct device * dev , uint32_t led )
10
13
{
11
14
const struct led_driver_api * api = (const struct led_driver_api * )dev -> api ;
12
15
@@ -21,7 +24,7 @@ int z_impl_led_on(const struct device *dev, uint32_t led)
21
24
return api -> on (dev , led );
22
25
}
23
26
24
- int z_impl_led_off (const struct device * dev , uint32_t led )
27
+ static int led_core_off (const struct device * dev , uint32_t led )
25
28
{
26
29
const struct led_driver_api * api = (const struct led_driver_api * )dev -> api ;
27
30
@@ -36,10 +39,110 @@ int z_impl_led_off(const struct device *dev, uint32_t led)
36
39
return api -> off (dev , led );
37
40
}
38
41
42
+ #ifdef CONFIG_LED_BLINK_SOFTWARE
43
+ static void led_blink_software_off (struct k_work * work );
44
+ static struct led_blink_software_data * led_blink_software_get_data (const struct device * dev ,
45
+ uint32_t led )
46
+ {
47
+ const struct led_driver_api * api = (const struct led_driver_api * )dev -> api ;
48
+
49
+ if (!api -> get_blink_data ) {
50
+ return NULL ;
51
+ }
52
+
53
+ return api -> get_blink_data (dev , led );
54
+ }
55
+
56
+ static void led_blink_software_on (struct k_work * work )
57
+ {
58
+ struct k_work_delayable * dwork = k_work_delayable_from_work (work );
59
+ struct led_blink_software_data * data =
60
+ CONTAINER_OF (dwork , struct led_blink_software_data , work );
61
+
62
+ led_core_on (data -> dev , data -> led );
63
+ k_work_init_delayable (& data -> work , led_blink_software_off );
64
+ k_work_schedule (& data -> work , K_MSEC (data -> delay_on ));
65
+ }
66
+
67
+ static void led_blink_software_off (struct k_work * work )
68
+ {
69
+ struct k_work_delayable * dwork = k_work_delayable_from_work (work );
70
+ struct led_blink_software_data * data =
71
+ CONTAINER_OF (dwork , struct led_blink_software_data , work );
72
+
73
+ led_core_off (data -> dev , data -> led );
74
+ k_work_init_delayable (& data -> work , led_blink_software_on );
75
+ k_work_schedule (& data -> work , K_MSEC (data -> delay_off ));
76
+ }
77
+
78
+ int led_blink_software_start (const struct device * dev , uint32_t led , uint32_t delay_on ,
79
+ uint32_t delay_off )
80
+ {
81
+ struct led_blink_software_data * data ;
82
+
83
+ data = led_blink_software_get_data (dev , led );
84
+ if (!data ) {
85
+ return - EINVAL ;
86
+ }
87
+
88
+ if (!delay_on && !delay_off ) {
89
+ /* Default 1Hz blinking when delay_on and delay_off are 0 */
90
+ delay_on = 500 ;
91
+ delay_off = 500 ;
92
+ } else if (!delay_on ) {
93
+ /* Always off */
94
+ led_core_off (dev , led );
95
+ } else if (!delay_off ) {
96
+ /* Always on */
97
+ led_core_on (dev , led );
98
+ }
99
+
100
+ data -> dev = dev ;
101
+ data -> led = led ;
102
+ data -> delay_on = delay_on ;
103
+ data -> delay_off = delay_off ;
104
+
105
+ k_work_init_delayable (& data -> work , led_blink_software_on );
106
+ return k_work_schedule (& data -> work , K_NO_WAIT );
107
+ }
108
+
109
+ static void led_blink_software_stop (const struct device * dev , uint32_t led )
110
+ {
111
+ struct led_blink_software_data * data ;
112
+
113
+ data = led_blink_software_get_data (dev , led );
114
+ if (data ) {
115
+ struct k_work_sync sync ;
116
+
117
+ k_work_cancel_delayable_sync (& data -> work , & sync );
118
+ }
119
+ }
120
+ #else
121
+ static inline void led_blink_software_stop (const struct device * dev , uint32_t led )
122
+ {
123
+ }
124
+ #endif /* CONFIG_LED_BLINK_SOFTWARE */
125
+
126
+ int z_impl_led_on (const struct device * dev , uint32_t led )
127
+ {
128
+ led_blink_software_stop (dev , led );
129
+ return led_core_on (dev , led );
130
+ }
131
+
132
+ int z_impl_led_off (const struct device * dev , uint32_t led )
133
+ {
134
+ led_blink_software_stop (dev , led );
135
+ return led_core_off (dev , led );
136
+ }
137
+
39
138
int z_impl_led_set_brightness (const struct device * dev , uint32_t led , uint8_t value )
40
139
{
41
140
const struct led_driver_api * api = (const struct led_driver_api * )dev -> api ;
42
141
142
+ if (!value ) {
143
+ led_blink_software_stop (dev , led );
144
+ }
145
+
43
146
if (api -> set_brightness == NULL ) {
44
147
if (api -> on == NULL || api -> off == NULL ) {
45
148
return - ENOSYS ;
@@ -66,7 +169,7 @@ int z_impl_led_blink(const struct device *dev, uint32_t led, uint32_t delay_on,
66
169
const struct led_driver_api * api = (const struct led_driver_api * )dev -> api ;
67
170
68
171
if (api -> blink == NULL ) {
69
- return - ENOSYS ;
172
+ return led_blink_software_start ( dev , led , delay_on , delay_off ) ;
70
173
}
71
174
return api -> blink (dev , led , delay_on , delay_off );
72
175
}
0 commit comments