Skip to content

Commit 3c8bd0b

Browse files
DineshDK03nashif
authored andcommitted
drivers: sensor: grow_r502a: add built-in LED control
Add LED control attribute for sensor device's built-in LED using zephyr's led driver APIs. Signed-off-by: Dinesh Kumar K <[email protected]>
1 parent e57c6f9 commit 3c8bd0b

File tree

6 files changed

+182
-49
lines changed

6 files changed

+182
-49
lines changed

drivers/sensor/grow_r502a/grow_r502a.c

Lines changed: 98 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,13 @@
44
* SPDX-License-Identifier: Apache-2.0
55
*/
66

7-
#define DT_DRV_COMPAT hzgrow_r502a
8-
97
#include <zephyr/init.h>
108
#include <zephyr/kernel.h>
119
#include <zephyr/drivers/gpio.h>
1210
#include <zephyr/drivers/sensor.h>
1311
#include <zephyr/drivers/uart.h>
1412
#include <zephyr/sys/byteorder.h>
13+
#include <zephyr/drivers/led.h>
1514

1615
#include <zephyr/drivers/sensor/grow_r502a.h>
1716
#include "grow_r502a.h"
@@ -105,7 +104,7 @@ static void uart_cb_handler(const struct device *dev, void *user_data)
105104
}
106105
}
107106

108-
static int fps_led_control(const struct device *dev, struct led_params *led_control)
107+
static int fps_led_control(const struct device *dev, struct r502a_led_params *led_control)
109108
{
110109
union r502a_packet rx_packet = {0};
111110
char const led_ctrl_len = 5;
@@ -246,10 +245,10 @@ static int fps_get_image(const struct device *dev)
246245
union r502a_packet rx_packet = {0};
247246
char const get_img_len = 1;
248247

249-
struct led_params led_ctrl = {
250-
.ctrl_code = LED_CTRL_BREATHING,
251-
.color_idx = LED_COLOR_BLUE,
252-
.speed = LED_SPEED_HALF,
248+
struct r502a_led_params led_ctrl = {
249+
.ctrl_code = R502A_LED_CTRL_BREATHING,
250+
.color_idx = R502A_LED_COLOR_BLUE,
251+
.speed = R502A_LED_SPEED_HALF,
253252
.cycle = 0x01,
254253
};
255254

@@ -269,8 +268,8 @@ static int fps_get_image(const struct device *dev)
269268
fps_led_control(dev, &led_ctrl);
270269
LOG_DBG("Image taken");
271270
} else {
272-
led_ctrl.ctrl_code = LED_CTRL_ON_ALWAYS;
273-
led_ctrl.color_idx = LED_COLOR_RED;
271+
led_ctrl.ctrl_code = R502A_LED_CTRL_ON_ALWAYS;
272+
led_ctrl.color_idx = R502A_LED_COLOR_RED;
274273
fps_led_control(dev, &led_ctrl);
275274
LOG_ERR("Error getting image 0x%X", rx_packet.buf[R502A_CC_IDX]);
276275
return -EIO;
@@ -340,10 +339,10 @@ static int fps_store_model(const struct device *dev, uint16_t id)
340339
char const store_model_len = 4;
341340
int ret = 0;
342341

343-
struct led_params led_ctrl = {
344-
.ctrl_code = LED_CTRL_BREATHING,
345-
.color_idx = LED_COLOR_BLUE,
346-
.speed = LED_SPEED_HALF,
342+
struct r502a_led_params led_ctrl = {
343+
.ctrl_code = R502A_LED_CTRL_BREATHING,
344+
.color_idx = R502A_LED_COLOR_BLUE,
345+
.speed = R502A_LED_SPEED_HALF,
347346
.cycle = 0x01,
348347
};
349348

@@ -364,8 +363,8 @@ static int fps_store_model(const struct device *dev, uint16_t id)
364363
}
365364

366365
if (rx_packet.buf[R502A_CC_IDX] == R502A_OK) {
367-
led_ctrl.color_idx = LED_COLOR_BLUE;
368-
led_ctrl.ctrl_code = LED_CTRL_FLASHING;
366+
led_ctrl.color_idx = R502A_LED_COLOR_BLUE;
367+
led_ctrl.ctrl_code = R502A_LED_CTRL_FLASHING;
369368
led_ctrl.cycle = 0x03;
370369
fps_led_control(dev, &led_ctrl);
371370
LOG_INF("Fingerprint stored! at ID #%d", id);
@@ -455,10 +454,10 @@ static int fps_search(const struct device *dev, struct sensor_value *val)
455454
char const search_len = 6;
456455
int ret = 0;
457456

458-
struct led_params led_ctrl = {
459-
.ctrl_code = LED_CTRL_BREATHING,
460-
.color_idx = LED_COLOR_BLUE,
461-
.speed = LED_SPEED_HALF,
457+
struct r502a_led_params led_ctrl = {
458+
.ctrl_code = R502A_LED_CTRL_BREATHING,
459+
.color_idx = R502A_LED_COLOR_BLUE,
460+
.speed = R502A_LED_SPEED_HALF,
462461
.cycle = 0x01,
463462
};
464463

@@ -480,23 +479,23 @@ static int fps_search(const struct device *dev, struct sensor_value *val)
480479
}
481480

482481
if (rx_packet.buf[R502A_CC_IDX] == R502A_OK) {
483-
led_ctrl.ctrl_code = LED_CTRL_FLASHING;
484-
led_ctrl.color_idx = LED_COLOR_PURPLE;
482+
led_ctrl.ctrl_code = R502A_LED_CTRL_FLASHING;
483+
led_ctrl.color_idx = R502A_LED_COLOR_PURPLE;
485484
led_ctrl.cycle = 0x01;
486485
fps_led_control(dev, &led_ctrl);
487486
val->val1 = sys_get_be16(&rx_packet.data[1]);
488487
val->val2 = sys_get_be16(&rx_packet.data[3]);
489488
LOG_INF("Found a matching print! at ID #%d", val->val1);
490489
} else if (rx_packet.buf[R502A_CC_IDX] == R502A_NOT_FOUND_CC) {
491-
led_ctrl.ctrl_code = LED_CTRL_BREATHING;
492-
led_ctrl.color_idx = LED_COLOR_RED;
490+
led_ctrl.ctrl_code = R502A_LED_CTRL_BREATHING;
491+
led_ctrl.color_idx = R502A_LED_COLOR_RED;
493492
led_ctrl.cycle = 0x02;
494493
fps_led_control(dev, &led_ctrl);
495494
LOG_ERR("Did not find a match");
496495
ret = -ENOENT;
497496
} else {
498-
led_ctrl.ctrl_code = LED_CTRL_ON_ALWAYS;
499-
led_ctrl.color_idx = LED_COLOR_RED;
497+
led_ctrl.ctrl_code = R502A_LED_CTRL_ON_ALWAYS;
498+
led_ctrl.color_idx = R502A_LED_COLOR_RED;
500499
fps_led_control(dev, &led_ctrl);
501500
LOG_ERR("Error searching for image 0x%X", rx_packet.buf[R502A_CC_IDX]);
502501
ret = -EIO;
@@ -549,10 +548,10 @@ static int fps_match_templates(const struct device *dev, struct sensor_value *va
549548
char const match_templates_len = 1;
550549
int ret = 0;
551550

552-
struct led_params led_ctrl = {
553-
.ctrl_code = LED_CTRL_BREATHING,
554-
.color_idx = LED_COLOR_BLUE,
555-
.speed = LED_SPEED_HALF,
551+
struct r502a_led_params led_ctrl = {
552+
.ctrl_code = R502A_LED_CTRL_BREATHING,
553+
.color_idx = R502A_LED_COLOR_BLUE,
554+
.speed = R502A_LED_SPEED_HALF,
556555
.cycle = 0x01,
557556
};
558557

@@ -581,8 +580,8 @@ static int fps_match_templates(const struct device *dev, struct sensor_value *va
581580
LOG_ERR("Fingerprint not matched");
582581
ret = -ENOENT;
583582
} else {
584-
led_ctrl.ctrl_code = LED_CTRL_ON_ALWAYS;
585-
led_ctrl.color_idx = LED_COLOR_RED;
583+
led_ctrl.ctrl_code = R502A_LED_CTRL_ON_ALWAYS;
584+
led_ctrl.color_idx = R502A_LED_COLOR_RED;
586585
fps_led_control(dev, &led_ctrl);
587586
LOG_ERR("Error Matching templates 0x%X",
588587
rx_packet.buf[R502A_CC_IDX]);
@@ -627,10 +626,10 @@ static int fps_init(const struct device *dev)
627626
struct grow_r502a_data *drv_data = dev->data;
628627
int ret;
629628

630-
struct led_params led_ctrl = {
631-
.ctrl_code = LED_CTRL_FLASHING,
632-
.color_idx = LED_COLOR_PURPLE,
633-
.speed = LED_SPEED_HALF,
629+
struct r502a_led_params led_ctrl = {
630+
.ctrl_code = R502A_LED_CTRL_FLASHING,
631+
.color_idx = R502A_LED_COLOR_PURPLE,
632+
.speed = R502A_LED_SPEED_HALF,
634633
.cycle = 0x02,
635634
};
636635

@@ -678,6 +677,8 @@ static int grow_r502a_channel_get(const struct device *dev, enum sensor_channel
678677
static int grow_r502a_attr_set(const struct device *dev, enum sensor_channel chan,
679678
enum sensor_attribute attr, const struct sensor_value *val)
680679
{
680+
struct grow_r502a_data *drv_data = dev->data;
681+
681682
if ((enum sensor_channel_grow_r502a)chan != SENSOR_CHAN_FINGERPRINT) {
682683
LOG_ERR("Channel not supported");
683684
return -ENOTSUP;
@@ -808,6 +809,53 @@ static const struct sensor_driver_api grow_r502a_api = {
808809
#endif
809810
};
810811

812+
#ifdef CONFIG_LED
813+
static int grow_r502a_led_set_color(const struct device *dev, uint32_t led,
814+
uint8_t num_colors, const uint8_t *color)
815+
{
816+
struct grow_r502a_data *drv_data = dev->data;
817+
818+
if (!(*color)) {
819+
LOG_ERR("invalid color code value");
820+
return -ENOTSUP;
821+
}
822+
drv_data->led_color = *color;
823+
824+
return 0;
825+
}
826+
827+
static int grow_r502a_led_on(const struct device *dev, uint32_t led)
828+
{
829+
struct grow_r502a_data *drv_data = dev->data;
830+
831+
if (!drv_data->led_color) {
832+
drv_data->led_color = R502A_LED_COLOR_BLUE;
833+
}
834+
835+
struct r502a_led_params led_ctrl = {
836+
.ctrl_code = R502A_LED_CTRL_ON_ALWAYS,
837+
.color_idx = drv_data->led_color,
838+
};
839+
840+
return fps_led_control(dev, &led_ctrl);
841+
}
842+
843+
static int grow_r502a_led_off(const struct device *dev, uint32_t led)
844+
{
845+
struct r502a_led_params led_ctrl = {
846+
.ctrl_code = R502A_LED_CTRL_OFF_ALWAYS,
847+
};
848+
849+
return fps_led_control(dev, &led_ctrl);
850+
}
851+
852+
static const struct led_driver_api grow_r502a_leds_api = {
853+
.set_color = grow_r502a_led_set_color,
854+
.on = grow_r502a_led_on,
855+
.off = grow_r502a_led_off,
856+
};
857+
#endif
858+
811859
#define GROW_R502A_INIT(index) \
812860
static struct grow_r502a_data grow_r502a_data_##index; \
813861
\
@@ -822,7 +870,20 @@ static const struct sensor_driver_api grow_r502a_api = {
822870
}; \
823871
\
824872
DEVICE_DT_INST_DEFINE(index, &grow_r502a_init, NULL, &grow_r502a_data_##index, \
825-
&grow_r502a_config_##index, POST_KERNEL, \
826-
CONFIG_SENSOR_INIT_PRIORITY, &grow_r502a_api);
873+
&grow_r502a_config_##index, POST_KERNEL, \
874+
CONFIG_SENSOR_INIT_PRIORITY, &grow_r502a_api); \
827875

876+
#define GROW_R502A_LED_INIT(index) \
877+
DEVICE_DT_INST_DEFINE(index, NULL, NULL, &grow_r502a_data_##index, \
878+
&grow_r502a_config_##index, POST_KERNEL, \
879+
CONFIG_LED_INIT_PRIORITY, &grow_r502a_leds_api); \
880+
881+
#define DT_DRV_COMPAT hzgrow_r502a
828882
DT_INST_FOREACH_STATUS_OKAY(GROW_R502A_INIT)
883+
#undef DT_DRV_COMPAT
884+
885+
#ifdef CONFIG_LED
886+
#define DT_DRV_COMPAT hzgrow_r502a_led
887+
DT_INST_FOREACH_STATUS_OKAY(GROW_R502A_LED_INIT)
888+
#undef DT_DRV_COMPAT
889+
#endif

drivers/sensor/grow_r502a/grow_r502a.h

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -131,21 +131,40 @@
131131
#define R502A_DELAY 200
132132
#define R502A_RETRY_DELAY 5
133133

134-
#define LED_CTRL_BREATHING 0x01
135-
#define LED_CTRL_FLASHING 0x02
136-
#define LED_CTRL_ON_ALWAYS 0x03
137-
#define LED_CTRL_OFF_ALWAYS 0x04
138-
#define LED_CTRL_ON_GRADUALLY 0x05
139-
#define LED_CTRL_OFF_GRADUALLY 0x06
134+
/*LED glow control code*/
135+
enum r502a_led_ctrl_code {
136+
R502A_LED_CTRL_BREATHING = 0x01,
137+
R502A_LED_CTRL_FLASHING,
138+
R502A_LED_CTRL_ON_ALWAYS,
139+
R502A_LED_CTRL_OFF_ALWAYS,
140+
R502A_LED_CTRL_ON_GRADUALLY,
141+
R502A_LED_CTRL_OFF_GRADUALLY,
142+
};
143+
144+
/* LED glow speed code
145+
* if needed, use desired speed between 0-255
146+
*/
147+
enum r502a_led_speed {
148+
R502A_LED_SPEED_MAX = 0x00,
149+
R502A_LED_SPEED_HALF = 0x50,
150+
R502A_LED_SPEED_MIN = 0xFF,
151+
};
140152

141-
#define LED_SPEED_HALF 0x50
142-
#define LED_SPEED_FULL 0xFF
153+
/* LED glowing cycle
154+
* if needed, use desired cycle count between 1-255
155+
*/
156+
enum r502a_led_cycle {
157+
R502A_LED_CYCLE_INFINITE = 0x00,
158+
R502A_LED_CYCLE_1,
159+
R502A_LED_CYCLE_2,
160+
R502A_LED_CYCLE_3,
161+
R502A_LED_CYCLE_4,
162+
R502A_LED_CYCLE_5,
163+
R502A_LED_CYCLE_255 = 0xFF,
164+
};
143165

144-
#define LED_COLOR_RED 0x01
145-
#define LED_COLOR_BLUE 0x02
146-
#define LED_COLOR_PURPLE 0x03
147166

148-
struct led_params {
167+
struct r502a_led_params {
149168
uint8_t ctrl_code;
150169
uint8_t color_idx;
151170
uint8_t speed; /* Speed 0x00-0xff */
@@ -192,6 +211,7 @@ struct grow_r502a_data {
192211
struct k_sem uart_rx_sem;
193212

194213
uint16_t template_count;
214+
uint8_t led_color;
195215
};
196216

197217
struct grow_r502a_config {

include/zephyr/drivers/sensor/grow_r502a.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,13 @@ extern "C" {
1313

1414
#include <zephyr/drivers/sensor.h>
1515

16+
/*LED color code*/
17+
enum r502a_led_color_idx {
18+
R502A_LED_COLOR_RED = 0x01,
19+
R502A_LED_COLOR_BLUE,
20+
R502A_LED_COLOR_PURPLE,
21+
};
22+
1623
enum sensor_channel_grow_r502a {
1724
/** Fingerprint template count, ID number for enrolling and searching*/
1825
SENSOR_CHAN_FINGERPRINT = SENSOR_CHAN_PRIV_START,

samples/sensor/grow_r502a/boards/esp32_devkitc_wroom_procpu.overlay

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,9 @@
2525
int-gpios = <&gpio1 3 GPIO_ACTIVE_LOW>;
2626
};
2727
};
28+
29+
led {
30+
compatible = "hzgrow,r502a-led";
31+
status = "okay";
32+
};
2833
};

samples/sensor/grow_r502a/prj.conf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@ CONFIG_SERIAL=y
22
CONFIG_UART_INTERRUPT_DRIVEN=y
33

44
CONFIG_SENSOR=y
5+
CONFIG_LED=y
56
CONFIG_GROW_R502A_TRIGGER_OWN_THREAD=y

samples/sensor/grow_r502a/src/main.c

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <zephyr/drivers/uart.h>
1010
#include <zephyr/drivers/gpio.h>
1111
#include <zephyr/drivers/sensor/grow_r502a.h>
12+
#include <zephyr/drivers/led.h>
1213

1314
static bool enroll;
1415
static struct sensor_value fid_get, count, find, del;
@@ -79,6 +80,38 @@ static void template_count_get(const struct device *dev)
7980
printk("template count : %d\n", count.val1);
8081
}
8182

83+
static int r502a_led(void)
84+
{
85+
int ret;
86+
const int led_num = 0;
87+
const int led_color_a_inst = 1;
88+
uint8_t led_color = R502A_LED_COLOR_PURPLE;
89+
const struct device *led_dev = DEVICE_DT_GET_ONE(hzgrow_r502a_led);
90+
91+
if (led_dev == NULL) {
92+
printk("Error: no device found\n");
93+
return -ENODEV;
94+
}
95+
96+
if (!device_is_ready(led_dev)) {
97+
printk("Error: Device %s is not ready\n", led_dev->name);
98+
return -EAGAIN;
99+
}
100+
101+
ret = led_set_color(led_dev, led_num, led_color_a_inst, &led_color);
102+
if (ret != 0) {
103+
printk("led set color failed %d\n", ret);
104+
return -1;
105+
}
106+
107+
ret = led_on(led_dev, led_num);
108+
if (ret != 0) {
109+
printk("led on failed %d\n", ret);
110+
return -1;
111+
}
112+
return 0;
113+
}
114+
82115
static void trigger_handler(const struct device *dev,
83116
const struct sensor_trigger *trigger)
84117
{
@@ -106,6 +139,12 @@ int main(void)
106139
return 0;
107140
}
108141

142+
ret = r502a_led();
143+
if (ret != 0) {
144+
printk("Error: device led failed to set %d", ret);
145+
return 0;
146+
}
147+
109148
template_count_get(dev);
110149

111150
del.val1 = 3;

0 commit comments

Comments
 (0)