1 /*
2 * Copyright (c) 2021 Linumiz
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6 #include <zephyr/kernel.h>
7 #include <zephyr/device.h>
8 #include <zephyr/drivers/sensor.h>
9 #include <zephyr/drivers/uart.h>
10 #include <zephyr/drivers/sensor/grow_r502a.h>
11 #include <zephyr/drivers/led.h>
12
13 static bool enroll;
14 static struct sensor_value fid_get, count, find, del, param;
15
finger_find(const struct device * dev)16 static void finger_find(const struct device *dev)
17 {
18 int ret;
19
20 ret = sensor_attr_set(dev, SENSOR_CHAN_FINGERPRINT,
21 SENSOR_ATTR_R502A_CAPTURE, NULL);
22 if (ret != 0) {
23 printk("Capture fingerprint failed %d\n", ret);
24 return;
25 }
26
27 ret = sensor_attr_get(dev, SENSOR_CHAN_FINGERPRINT,
28 SENSOR_ATTR_R502A_RECORD_FIND, &find);
29 if (ret != 0) {
30 printk("Find fingerprint failed %d\n", ret);
31 return;
32 }
33 printk("Matched ID : %d\n", find.val1);
34 printk("confidence : %d\n", find.val2);
35 }
36
finger_enroll(const struct device * dev)37 static void finger_enroll(const struct device *dev)
38 {
39 int ret;
40
41 ret = sensor_attr_set(dev, SENSOR_CHAN_FINGERPRINT,
42 SENSOR_ATTR_R502A_CAPTURE, NULL);
43 if (ret != 0) {
44 printk("Capture fingerprint failed %d\n", ret);
45 return;
46 }
47
48 ret = sensor_attr_set(dev, SENSOR_CHAN_FINGERPRINT,
49 SENSOR_ATTR_R502A_TEMPLATE_CREATE, NULL);
50 if (ret != 0) {
51 printk("Create template failed %d\n", ret);
52 return;
53 }
54
55 ret = sensor_attr_set(dev, SENSOR_CHAN_FINGERPRINT,
56 SENSOR_ATTR_R502A_RECORD_ADD, &fid_get);
57 if (!ret) {
58 printk("Fingerprint successfully stored at #%d\n", fid_get.val1);
59 enroll = false;
60 } else {
61 printk("Fingerprint store failed %d\n", ret);
62 }
63 }
64
template_count_get(const struct device * dev)65 static void template_count_get(const struct device *dev)
66 {
67 int ret;
68
69 ret = sensor_sample_fetch(dev);
70 if (ret < 0) {
71 printk("Sample Fetch Error %d\n", ret);
72 return;
73 }
74 ret = sensor_channel_get(dev, SENSOR_CHAN_FINGERPRINT, &count);
75 if (ret < 0) {
76 printk("Channel Get Error %d\n", ret);
77 return;
78 }
79 printk("template count : %d\n", count.val1);
80 }
81
r502a_led(void)82 static int r502a_led(void)
83 {
84 int ret;
85 const int led_num = 0;
86 const int led_color_a_inst = 1;
87 uint8_t led_color = R502A_LED_COLOR_PURPLE;
88 const struct device *led_dev = DEVICE_DT_GET_ONE(hzgrow_r502a_led);
89
90 if (led_dev == NULL) {
91 printk("Error: no device found\n");
92 return -ENODEV;
93 }
94
95 if (!device_is_ready(led_dev)) {
96 printk("Error: Device %s is not ready\n", led_dev->name);
97 return -EAGAIN;
98 }
99
100 ret = led_set_color(led_dev, led_num, led_color_a_inst, &led_color);
101 if (ret != 0) {
102 printk("led set color failed %d\n", ret);
103 return -1;
104 }
105
106 ret = led_on(led_dev, led_num);
107 if (ret != 0) {
108 printk("led on failed %d\n", ret);
109 return -1;
110 }
111 return 0;
112 }
113
trigger_handler(const struct device * dev,const struct sensor_trigger * trigger)114 static void trigger_handler(const struct device *dev,
115 const struct sensor_trigger *trigger)
116 {
117 if (enroll) {
118 finger_enroll(dev);
119 } else {
120 template_count_get(dev);
121 finger_find(dev);
122 }
123 }
124
read_fps_param(const struct device * dev)125 static void read_fps_param(const struct device *dev)
126 {
127 int ret = 0;
128 struct r502a_sys_param res;
129
130 ret = r502a_read_sys_param(dev, &res);
131 if (ret != 0) {
132 printk("r502a read system parameter failed %d\n", ret);
133 return;
134 }
135
136 printk("baud %d\n", res.baud);
137 printk("addr 0x%x\n", res.addr);
138 printk("lib_size %d\n", res.lib_size);
139 printk("data_pkt_size %d\n", res.data_pkt_size);
140 }
141
main(void)142 int main(void)
143 {
144 int ret;
145
146 const struct device *dev = DEVICE_DT_GET_ONE(hzgrow_r502a);
147
148 if (dev == NULL) {
149 printk("Error: no device found\n");
150 return 0;
151 }
152
153 if (!device_is_ready(dev)) {
154 printk("Error: Device %s is not ready\n", dev->name);
155 return 0;
156 }
157
158 ret = r502a_led();
159 if (ret != 0) {
160 printk("Error: device led failed to set %d", ret);
161 return 0;
162 }
163
164 template_count_get(dev);
165
166 read_fps_param(dev);
167
168 del.val1 = 3;
169 ret = sensor_attr_set(dev, SENSOR_CHAN_FINGERPRINT, SENSOR_ATTR_R502A_RECORD_DEL, &del);
170 if (ret != 0) {
171 printk("Sensor attr set failed %d\n", ret);
172 return 0;
173 }
174 printk("Fingerprint Deleted at ID #%d\n", del.val1);
175
176 ret = sensor_attr_get(dev, SENSOR_CHAN_FINGERPRINT,
177 SENSOR_ATTR_R502A_RECORD_FREE_IDX, &fid_get);
178 if (ret != 0) {
179 printk("Sensor attr get failed %d\n", ret);
180 return 0;
181 }
182 printk("Fingerprint template free idx at ID #%d\n", fid_get.val1);
183
184 printk("Waiting for valid finger to enroll as ID #%d\n"
185 "Place your finger\n", fid_get.val1);
186 enroll = true;
187
188 if (IS_ENABLED(CONFIG_GROW_R502A_TRIGGER)) {
189 struct sensor_trigger trig = {
190 .type = SENSOR_TRIG_TOUCH,
191 .chan = SENSOR_CHAN_FINGERPRINT,
192 };
193 ret = sensor_trigger_set(dev, &trig, trigger_handler);
194 if (ret != 0) {
195 printk("Could not set trigger\n");
196 return 0;
197 }
198 }
199
200 return 0;
201 }
202