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