1 /*
2 * Copyright (c) 2021 Linumiz
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/init.h>
8 #include <zephyr/kernel.h>
9 #include <zephyr/drivers/gpio.h>
10 #include <zephyr/drivers/sensor.h>
11 #include <zephyr/drivers/uart.h>
12 #include <zephyr/sys/byteorder.h>
13 #include <zephyr/drivers/led.h>
14 #include <zephyr/sys/util.h>
15
16 #include <zephyr/drivers/sensor/grow_r502a.h>
17 #include "grow_r502a.h"
18
19 #include <zephyr/logging/log.h>
20 LOG_MODULE_REGISTER(GROW_R502A, CONFIG_SENSOR_LOG_LEVEL);
21
transceive_packet(const struct device * dev,union r502a_packet * tx_packet,union r502a_packet * rx_packet,uint16_t data_len)22 static int transceive_packet(const struct device *dev, union r502a_packet *tx_packet,
23 union r502a_packet *rx_packet, uint16_t data_len)
24 {
25 const struct grow_r502a_config *cfg = dev->config;
26 struct grow_r502a_data *drv_data = dev->data;
27
28 if (tx_packet) {
29 uint16_t check_sum, pkg_len;
30
31 pkg_len = data_len + R502A_CHECKSUM_LEN;
32 check_sum = (pkg_len >> 8) + (pkg_len & 0xFF) + tx_packet->pid;
33
34 tx_packet->start = sys_cpu_to_be16(R502A_STARTCODE);
35 tx_packet->addr = sys_cpu_to_be32(cfg->comm_addr);
36 tx_packet->len = sys_cpu_to_be16(pkg_len);
37
38 for (int i = 0; i < data_len; i++) {
39 check_sum += tx_packet->data[i];
40 }
41 sys_put_be16(check_sum, &tx_packet->buf[data_len + R502A_HEADER_LEN]);
42
43 drv_data->tx_buf.len = pkg_len + R502A_HEADER_LEN;
44 drv_data->tx_buf.data = tx_packet->buf;
45
46 LOG_HEXDUMP_DBG(drv_data->tx_buf.data, drv_data->tx_buf.len, "TX");
47
48 uart_irq_tx_enable(cfg->dev);
49
50 if (k_sem_take(&drv_data->uart_tx_sem, K_MSEC(1500)) != 0) {
51 LOG_ERR("Tx data timeout");
52 return -ETIMEDOUT;
53 }
54 }
55
56 if (rx_packet) {
57 drv_data->rx_buf.data = rx_packet->buf;
58 drv_data->rx_buf.len = 0;
59 drv_data->pkt_len = R502A_HEADER_LEN;
60 uart_irq_rx_enable(cfg->dev);
61 if (k_sem_take(&drv_data->uart_rx_sem, K_MSEC(1500)) != 0) {
62 LOG_ERR("Rx data timeout");
63 return -ETIMEDOUT;
64 }
65 }
66
67 return 0;
68 }
69
r502a_validate_rx_packet(union r502a_packet * rx_packet)70 static int r502a_validate_rx_packet(union r502a_packet *rx_packet)
71 {
72 uint16_t recv_cks = 0, calc_cks = 0;
73 uint8_t cks_start_idx;
74
75 if (sys_be16_to_cpu(rx_packet->start) == R502A_STARTCODE) {
76 LOG_DBG("startcode matched 0x%X", sys_be16_to_cpu(rx_packet->start));
77 } else {
78 LOG_ERR("startcode didn't match 0x%X", sys_be16_to_cpu(rx_packet->start));
79 return -EINVAL;
80 }
81
82 if (sys_be32_to_cpu(rx_packet->addr) == R502A_DEFAULT_ADDRESS) {
83 LOG_DBG("Address matched 0x%X", sys_be32_to_cpu(rx_packet->addr));
84 } else {
85 LOG_ERR("Address didn't match 0x%X", sys_be32_to_cpu(rx_packet->addr));
86 return -EINVAL;
87 }
88
89 switch (rx_packet->pid) {
90 case R502A_DATA_PACKET:
91 LOG_DBG("Data Packet Received 0x%X", rx_packet->pid);
92 break;
93 case R502A_END_DATA_PACKET:
94 LOG_DBG("End of Data Packet Received 0x%X", rx_packet->pid);
95 break;
96 case R502A_ACK_PACKET:
97 LOG_DBG("Acknowledgment Packet Received 0x%X", rx_packet->pid);
98 break;
99 default:
100 LOG_ERR("Error Package ID 0x%X", rx_packet->pid);
101 return -EINVAL;
102 }
103
104 const uint16_t packet_len = sys_be16_to_cpu(rx_packet->len);
105
106 if (packet_len < R502A_CHECKSUM_LEN || packet_len > CONFIG_R502A_DATA_PKT_SIZE) {
107 LOG_ERR("Invalid packet length %d", packet_len);
108 return -EINVAL;
109 }
110
111 cks_start_idx = packet_len - R502A_CHECKSUM_LEN;
112
113 recv_cks = sys_get_be16(&rx_packet->data[cks_start_idx]);
114
115 calc_cks += rx_packet->pid + (sys_be16_to_cpu(rx_packet->len) >> 8) +
116 (sys_be16_to_cpu(rx_packet->len) & 0xFF);
117
118 for (int i = 0; i < cks_start_idx; i++) {
119 calc_cks += rx_packet->data[i];
120 }
121
122 if (recv_cks == calc_cks) {
123 LOG_DBG("Checksum matched calculated 0x%x received 0x%x", calc_cks, recv_cks);
124 } else {
125 LOG_ERR("Checksum mismatch calculated 0x%x received 0x%x", calc_cks, recv_cks);
126 return -EINVAL;
127 }
128
129 return 0;
130 }
131
uart_cb_tx_handler(const struct device * dev)132 static void uart_cb_tx_handler(const struct device *dev)
133 {
134 const struct grow_r502a_config *config = dev->config;
135 struct grow_r502a_data *drv_data = dev->data;
136 int sent = 0;
137
138 if (drv_data->tx_buf.len > 0) {
139 sent = uart_fifo_fill(config->dev, drv_data->tx_buf.data,
140 drv_data->tx_buf.len);
141 drv_data->tx_buf.data += sent;
142 drv_data->tx_buf.len -= sent;
143 }
144
145 if (!drv_data->tx_buf.len && uart_irq_tx_complete(config->dev) > 0) {
146 uart_irq_tx_disable(config->dev);
147 k_sem_give(&drv_data->uart_tx_sem);
148 return;
149 }
150 }
151
uart_cb_handler(const struct device * dev,void * user_data)152 static void uart_cb_handler(const struct device *dev, void *user_data)
153 {
154 const struct device *uart_dev = user_data;
155 struct grow_r502a_data *drv_data = uart_dev->data;
156 int len = 0;
157 int offset = drv_data->rx_buf.len;
158
159 if ((uart_irq_update(dev) > 0) && (uart_irq_is_pending(dev) > 0)) {
160 if (uart_irq_tx_ready(dev)) {
161 uart_cb_tx_handler(uart_dev);
162 }
163
164 while (uart_irq_rx_ready(dev)) {
165 len = uart_fifo_read(dev, &drv_data->rx_buf.data[offset],
166 drv_data->pkt_len);
167 offset += len;
168 drv_data->rx_buf.len = offset;
169
170 if (drv_data->pkt_len != len) {
171 drv_data->pkt_len -= len;
172 continue;
173 }
174
175 if (offset == R502A_HEADER_LEN) {
176 drv_data->pkt_len = sys_get_be16(
177 &drv_data->rx_buf.data[R502A_PKG_LEN_IDX]
178 );
179 continue;
180 }
181
182 LOG_HEXDUMP_DBG(drv_data->rx_buf.data, offset, "RX");
183 uart_irq_rx_disable(dev);
184 k_sem_give(&drv_data->uart_rx_sem);
185 break;
186 }
187 }
188 }
189
190 /**
191 * @brief Set sensor device's basic parameters like baud rate, security level
192 * and data package length.
193 */
fps_set_sys_param(const struct device * dev,const struct sensor_value * val)194 static int fps_set_sys_param(const struct device *dev, const struct sensor_value *val)
195 {
196 union r502a_packet rx_packet = {0};
197 int ret = 0;
198 char const set_sys_param_len = 3;
199
200 union r502a_packet tx_packet = {
201 .pid = R502A_COMMAND_PACKET,
202 .data = { R502A_SETSYSPARAM, val->val1, val->val2}
203 };
204
205 ret = transceive_packet(dev, &tx_packet, &rx_packet, set_sys_param_len);
206 if (ret != 0) {
207 return ret;
208 }
209
210 ret = r502a_validate_rx_packet(&rx_packet);
211 if (ret != 0) {
212 return ret;
213 }
214
215 if (rx_packet.buf[R502A_CC_IDX] == R502A_OK) {
216 LOG_DBG("R502A set system parameter success");
217 } else {
218 LOG_ERR("R502A set system parameter error %d", rx_packet.buf[R502A_CC_IDX]);
219 return -EIO;
220 }
221
222 return 0;
223 }
224
r502a_read_sys_param(const struct device * dev,struct r502a_sys_param * val)225 int r502a_read_sys_param(const struct device *dev, struct r502a_sys_param *val)
226 {
227 struct grow_r502a_data *drv_data = dev->data;
228
229 union r502a_packet rx_packet = {0};
230 int offset = 0, ret = 0;
231 char const read_sys_param_len = 1;
232
233 union r502a_packet tx_packet = {
234 .pid = R502A_COMMAND_PACKET,
235 .data = {R502A_READSYSPARAM}
236 };
237
238 k_mutex_lock(&drv_data->lock, K_FOREVER);
239
240 ret = transceive_packet(dev, &tx_packet, &rx_packet, read_sys_param_len);
241 if (ret != 0) {
242 goto unlock;
243 }
244
245 ret = r502a_validate_rx_packet(&rx_packet);
246 if (ret != 0) {
247 goto unlock;
248 }
249
250 if (rx_packet.buf[R502A_CC_IDX] == R502A_OK) {
251 LOG_DBG("R502A read system parameter success");
252 } else {
253 LOG_ERR("R502A read system parameter error %d", rx_packet.buf[R502A_CC_IDX]);
254 ret = -EIO;
255 goto unlock;
256 }
257
258 val->status_reg = sys_get_be16(
259 &rx_packet.data[offsetof(struct r502a_sys_param, status_reg) + 1]
260 );
261 val->system_id = sys_get_be16(
262 &rx_packet.data[offsetof(struct r502a_sys_param, system_id) + 1]
263 );
264 val->lib_size = sys_get_be16(
265 &rx_packet.data[offsetof(struct r502a_sys_param, lib_size) + 1]
266 );
267 val->sec_level = sys_get_be16(
268 &rx_packet.data[offsetof(struct r502a_sys_param, sec_level) + 1]
269 );
270 val->addr = sys_get_be32(
271 &rx_packet.data[offsetof(struct r502a_sys_param, addr) + 1]
272 );
273 offset = sys_get_be16(
274 &rx_packet.data[offsetof(struct r502a_sys_param, data_pkt_size) + 1]
275 );
276 val->data_pkt_size = 32 * (1 << offset);
277 val->baud = sys_get_be16(
278 &rx_packet.data[offsetof(struct r502a_sys_param, baud) + 1]
279 ) * 9600;
280
281 unlock:
282 k_mutex_unlock(&drv_data->lock);
283 return ret;
284 }
285
fps_led_control(const struct device * dev,struct r502a_led_params * led_control)286 static int fps_led_control(const struct device *dev, struct r502a_led_params *led_control)
287 {
288 union r502a_packet rx_packet = {0};
289 char const led_ctrl_len = 5;
290 int ret = 0;
291
292 union r502a_packet tx_packet = {
293 .pid = R502A_COMMAND_PACKET,
294 .data = { R502A_LED_CONFIG, led_control->ctrl_code,
295 led_control->speed, led_control->color_idx, led_control->cycle}
296 };
297
298 ret = transceive_packet(dev, &tx_packet, &rx_packet, led_ctrl_len);
299 if (ret != 0) {
300 return ret;
301 }
302
303 ret = r502a_validate_rx_packet(&rx_packet);
304 if (ret != 0) {
305 return ret;
306 }
307
308 if (rx_packet.buf[R502A_CC_IDX] == R502A_OK) {
309 LOG_DBG("R502A LED ON");
310 k_sleep(K_MSEC(R502A_DELAY));
311 } else {
312 LOG_ERR("R502A LED control error %d", rx_packet.buf[R502A_CC_IDX]);
313 return -EIO;
314 }
315
316 return 0;
317 }
318
fps_verify_password(const struct device * dev)319 static int fps_verify_password(const struct device *dev)
320 {
321 union r502a_packet rx_packet = {0};
322 char const verify_pwd_len = 5;
323 int ret = 0;
324
325 union r502a_packet tx_packet = {
326 .pid = R502A_COMMAND_PACKET,
327 .data[0] = R502A_VERIFYPASSWORD,
328 };
329
330 sys_put_be32(R502A_DEFAULT_PASSWORD, &tx_packet.data[1]);
331
332 ret = transceive_packet(dev, &tx_packet, &rx_packet, verify_pwd_len);
333 if (ret != 0) {
334 return ret;
335 }
336
337 ret = r502a_validate_rx_packet(&rx_packet);
338 if (ret != 0) {
339 return ret;
340 }
341
342 if (rx_packet.buf[R502A_CC_IDX] == R502A_OK) {
343 LOG_DBG("Correct password, R502A verified");
344 } else {
345 LOG_ERR("Password verification error 0x%X", rx_packet.buf[R502A_CC_IDX]);
346 return -EIO;
347 }
348
349 return 0;
350 }
351
fps_get_template_count(const struct device * dev)352 static int fps_get_template_count(const struct device *dev)
353 {
354 struct grow_r502a_data *drv_data = dev->data;
355 union r502a_packet rx_packet = {0};
356 char const get_temp_cnt_len = 1;
357 int ret = 0;
358
359 union r502a_packet tx_packet = {
360 .pid = R502A_COMMAND_PACKET,
361 .data = {R502A_TEMPLATECOUNT},
362 };
363
364 ret = transceive_packet(dev, &tx_packet, &rx_packet, get_temp_cnt_len);
365 if (ret != 0) {
366 return ret;
367 }
368
369 ret = r502a_validate_rx_packet(&rx_packet);
370 if (ret != 0) {
371 return ret;
372 }
373
374 if (rx_packet.buf[R502A_CC_IDX] == R502A_OK) {
375 LOG_DBG("Read success");
376 drv_data->template_count = sys_get_be16(&rx_packet.data[1]);
377 LOG_INF("Remaining templates count : %d", drv_data->template_count);
378 } else {
379 LOG_ERR("R502A template count get error");
380 return -EIO;
381 }
382
383 return 0;
384 }
385
fps_read_template_table(const struct device * dev,uint32_t * free_idx)386 static int fps_read_template_table(const struct device *dev, uint32_t *free_idx)
387 {
388 struct grow_r502a_data *drv_data = dev->data;
389 union r502a_packet rx_packet = {0};
390 char const temp_table_len = 2;
391 int ret = 0;
392
393 union r502a_packet tx_packet = {
394 .pid = R502A_COMMAND_PACKET,
395 .data = {R502A_READTEMPLATEINDEX, 0x00}
396 };
397
398 k_mutex_lock(&drv_data->lock, K_FOREVER);
399
400 ret = transceive_packet(dev, &tx_packet, &rx_packet, temp_table_len);
401 if (ret != 0) {
402 goto unlock;
403 }
404
405 ret = r502a_validate_rx_packet(&rx_packet);
406 if (ret != 0) {
407 goto unlock;
408 }
409
410 if (rx_packet.buf[R502A_CC_IDX] == R502A_OK) {
411 LOG_DBG("Read success");
412 } else {
413 LOG_ERR("R502A template table get error");
414 ret = -EIO;
415 goto unlock;
416 }
417
418 for (int group_idx = 0; group_idx < R502A_TEMP_TABLE_BUF_SIZE; group_idx++) {
419 uint8_t group = rx_packet.data[group_idx + 1];
420
421 /* if group is all occupied */
422 if (group == 0xff) {
423 continue;
424 }
425
426 *free_idx = (group_idx * 8) + find_lsb_set(~group) - 1;
427 goto unlock;
428 }
429
430 unlock:
431 k_mutex_unlock(&drv_data->lock);
432 return ret;
433 }
434
fps_get_image(const struct device * dev)435 static int fps_get_image(const struct device *dev)
436 {
437 union r502a_packet rx_packet = {0};
438 char const get_img_len = 1;
439 int ret = 0;
440
441 struct r502a_led_params led_ctrl = {
442 .ctrl_code = R502A_LED_CTRL_BREATHING,
443 .color_idx = R502A_LED_COLOR_BLUE,
444 .speed = R502A_LED_SPEED_HALF,
445 .cycle = 0x01,
446 };
447
448 union r502a_packet tx_packet = {
449 .pid = R502A_COMMAND_PACKET,
450 .data = {R502A_GENIMAGE},
451 };
452
453 ret = transceive_packet(dev, &tx_packet, &rx_packet, get_img_len);
454 if (ret != 0) {
455 return ret;
456 }
457
458 ret = r502a_validate_rx_packet(&rx_packet);
459 if (ret != 0) {
460 return ret;
461 }
462
463 if (rx_packet.buf[R502A_CC_IDX] == R502A_OK) {
464 fps_led_control(dev, &led_ctrl);
465 LOG_DBG("Image taken");
466 } else {
467 led_ctrl.ctrl_code = R502A_LED_CTRL_ON_ALWAYS;
468 led_ctrl.color_idx = R502A_LED_COLOR_RED;
469 fps_led_control(dev, &led_ctrl);
470 LOG_ERR("Error getting image 0x%X", rx_packet.buf[R502A_CC_IDX]);
471 return -EIO;
472 }
473
474 return 0;
475 }
476
fps_image_to_char(const struct device * dev,uint8_t char_buf_idx)477 static int fps_image_to_char(const struct device *dev, uint8_t char_buf_idx)
478 {
479 union r502a_packet rx_packet = {0};
480 char const img_to_char_len = 2;
481 int ret = 0;
482
483 union r502a_packet tx_packet = {
484 .pid = R502A_COMMAND_PACKET,
485 .data = {R502A_IMAGE2TZ, char_buf_idx}
486 };
487
488 ret = transceive_packet(dev, &tx_packet, &rx_packet, img_to_char_len);
489 if (ret != 0) {
490 return ret;
491 }
492
493 ret = r502a_validate_rx_packet(&rx_packet);
494 if (ret != 0) {
495 return ret;
496 }
497
498 if (rx_packet.buf[R502A_CC_IDX] == R502A_OK) {
499 LOG_DBG("Image converted");
500 } else {
501 LOG_ERR("Error converting image 0x%X", rx_packet.buf[R502A_CC_IDX]);
502 return -EIO;
503 }
504
505 return 0;
506 }
507
fps_create_model(const struct device * dev)508 static int fps_create_model(const struct device *dev)
509 {
510 union r502a_packet rx_packet = {0};
511 char const create_model_len = 1;
512 int ret = 0;
513
514 union r502a_packet tx_packet = {
515 .pid = R502A_COMMAND_PACKET,
516 .data = {R502A_REGMODEL}
517 };
518
519 ret = transceive_packet(dev, &tx_packet, &rx_packet, create_model_len);
520 if (ret != 0) {
521 return ret;
522 }
523
524 ret = r502a_validate_rx_packet(&rx_packet);
525 if (ret != 0) {
526 return ret;
527 }
528
529 if (rx_packet.buf[R502A_CC_IDX] == R502A_OK) {
530 LOG_DBG("Model Created");
531 } else {
532 LOG_ERR("Error creating model 0x%X", rx_packet.buf[R502A_CC_IDX]);
533 return -EIO;
534 }
535
536 return 0;
537 }
538
fps_store_model(const struct device * dev,uint16_t id)539 static int fps_store_model(const struct device *dev, uint16_t id)
540 {
541 struct grow_r502a_data *drv_data = dev->data;
542 union r502a_packet rx_packet = {0};
543 char const store_model_len = 4;
544 int ret = 0;
545
546 struct r502a_led_params led_ctrl = {
547 .ctrl_code = R502A_LED_CTRL_BREATHING,
548 .color_idx = R502A_LED_COLOR_BLUE,
549 .speed = R502A_LED_SPEED_HALF,
550 .cycle = 0x01,
551 };
552
553 union r502a_packet tx_packet = {
554 .pid = R502A_COMMAND_PACKET,
555 .data = {R502A_STORE, R502A_CHAR_BUF_1}
556 };
557 sys_put_be16(id, &tx_packet.data[2]);
558
559 k_mutex_lock(&drv_data->lock, K_FOREVER);
560
561 ret = transceive_packet(dev, &tx_packet, &rx_packet, store_model_len);
562 if (ret != 0) {
563 goto unlock;
564 }
565
566 ret = r502a_validate_rx_packet(&rx_packet);
567 if (ret != 0) {
568 goto unlock;
569 }
570
571 if (rx_packet.buf[R502A_CC_IDX] == R502A_OK) {
572 led_ctrl.color_idx = R502A_LED_COLOR_BLUE;
573 led_ctrl.ctrl_code = R502A_LED_CTRL_FLASHING;
574 led_ctrl.cycle = 0x03;
575 fps_led_control(dev, &led_ctrl);
576 LOG_INF("Fingerprint stored! at ID #%d", id);
577 } else {
578 LOG_ERR("Error storing model 0x%X", rx_packet.buf[R502A_CC_IDX]);
579 ret = -EIO;
580 }
581 unlock:
582 k_mutex_unlock(&drv_data->lock);
583 return ret;
584 }
585
fps_delete_model(const struct device * dev,uint16_t id,uint16_t count)586 static int fps_delete_model(const struct device *dev, uint16_t id, uint16_t count)
587 {
588 struct grow_r502a_data *drv_data = dev->data;
589 union r502a_packet rx_packet = {0};
590 char const delete_model_len = 5;
591 int ret = 0;
592
593 union r502a_packet tx_packet = {
594 .pid = R502A_COMMAND_PACKET,
595 .data = {R502A_DELETE}
596 };
597 sys_put_be16(id, &tx_packet.data[1]);
598 sys_put_be16(count + R502A_DELETE_COUNT_OFFSET, &tx_packet.data[3]);
599
600 k_mutex_lock(&drv_data->lock, K_FOREVER);
601
602 ret = transceive_packet(dev, &tx_packet, &rx_packet, delete_model_len);
603 if (ret != 0) {
604 goto unlock;
605 }
606
607 ret = r502a_validate_rx_packet(&rx_packet);
608 if (ret != 0) {
609 goto unlock;
610 }
611
612 if (rx_packet.buf[R502A_CC_IDX] == R502A_OK) {
613 LOG_INF("Fingerprint Deleted from ID #%d to #%d", id, (id + count));
614 } else {
615 LOG_ERR("Error deleting image 0x%X", rx_packet.buf[R502A_CC_IDX]);
616 ret = -EIO;
617 }
618 unlock:
619 k_mutex_unlock(&drv_data->lock);
620 return ret;
621 }
622
fps_empty_db(const struct device * dev)623 static int fps_empty_db(const struct device *dev)
624 {
625 struct grow_r502a_data *drv_data = dev->data;
626 union r502a_packet rx_packet = {0};
627 char const empty_db_len = 1;
628 int ret = 0;
629
630 union r502a_packet tx_packet = {
631 .pid = R502A_COMMAND_PACKET,
632 .data = {R502A_EMPTYLIBRARY}
633 };
634
635 k_mutex_lock(&drv_data->lock, K_FOREVER);
636
637 ret = transceive_packet(dev, &tx_packet, &rx_packet, empty_db_len);
638 if (ret != 0) {
639 goto unlock;
640 }
641
642 ret = r502a_validate_rx_packet(&rx_packet);
643 if (ret != 0) {
644 goto unlock;
645 }
646
647 if (rx_packet.buf[R502A_CC_IDX] == R502A_OK) {
648 LOG_INF("Emptied Fingerprint Library");
649 } else {
650 LOG_ERR("Error emptying fingerprint library 0x%X",
651 rx_packet.buf[R502A_CC_IDX]);
652 ret = -EIO;
653 }
654
655 unlock:
656 k_mutex_unlock(&drv_data->lock);
657 return ret;
658 }
659
fps_search(const struct device * dev,struct sensor_value * val)660 static int fps_search(const struct device *dev, struct sensor_value *val)
661 {
662 struct grow_r502a_data *drv_data = dev->data;
663 union r502a_packet rx_packet = {0};
664 char const search_len = 6;
665 int ret = 0;
666
667 struct r502a_led_params led_ctrl = {
668 .ctrl_code = R502A_LED_CTRL_BREATHING,
669 .color_idx = R502A_LED_COLOR_BLUE,
670 .speed = R502A_LED_SPEED_HALF,
671 .cycle = 0x01,
672 };
673
674 union r502a_packet tx_packet = {
675 .pid = R502A_COMMAND_PACKET,
676 .data = {R502A_SEARCH, R502A_CHAR_BUF_1}
677 };
678 sys_put_be16(R02A_LIBRARY_START_IDX, &tx_packet.data[2]);
679 sys_put_be16(R502A_DEFAULT_CAPACITY, &tx_packet.data[4]);
680
681 k_mutex_lock(&drv_data->lock, K_FOREVER);
682
683 ret = transceive_packet(dev, &tx_packet, &rx_packet, search_len);
684 if (ret != 0) {
685 goto unlock;
686 }
687
688 ret = r502a_validate_rx_packet(&rx_packet);
689 if (ret != 0) {
690 goto unlock;
691 }
692
693 if (rx_packet.buf[R502A_CC_IDX] == R502A_OK) {
694 led_ctrl.ctrl_code = R502A_LED_CTRL_FLASHING;
695 led_ctrl.color_idx = R502A_LED_COLOR_PURPLE;
696 led_ctrl.cycle = 0x01;
697 fps_led_control(dev, &led_ctrl);
698 val->val1 = sys_get_be16(&rx_packet.data[1]);
699 val->val2 = sys_get_be16(&rx_packet.data[3]);
700 LOG_INF("Found a matching print! at ID #%d", val->val1);
701 } else if (rx_packet.buf[R502A_CC_IDX] == R502A_NOT_FOUND_CC) {
702 led_ctrl.ctrl_code = R502A_LED_CTRL_BREATHING;
703 led_ctrl.color_idx = R502A_LED_COLOR_RED;
704 led_ctrl.cycle = 0x02;
705 fps_led_control(dev, &led_ctrl);
706 LOG_ERR("Did not find a match");
707 ret = -ENOENT;
708 } else {
709 led_ctrl.ctrl_code = R502A_LED_CTRL_ON_ALWAYS;
710 led_ctrl.color_idx = R502A_LED_COLOR_RED;
711 fps_led_control(dev, &led_ctrl);
712 LOG_ERR("Error searching for image 0x%X", rx_packet.buf[R502A_CC_IDX]);
713 ret = -EIO;
714 }
715 unlock:
716 k_mutex_unlock(&drv_data->lock);
717 return ret;
718 }
719
fps_load_template(const struct device * dev,uint16_t id)720 static int fps_load_template(const struct device *dev, uint16_t id)
721 {
722 struct grow_r502a_data *drv_data = dev->data;
723 union r502a_packet rx_packet = {0};
724 char const load_tmp_len = 4;
725 int ret = 0;
726
727 union r502a_packet tx_packet = {
728 .pid = R502A_COMMAND_PACKET,
729 .data = {R502A_LOAD, R502A_CHAR_BUF_1}
730 };
731 sys_put_be16(id, &tx_packet.data[2]);
732
733 k_mutex_lock(&drv_data->lock, K_FOREVER);
734
735 ret = transceive_packet(dev, &tx_packet, &rx_packet, load_tmp_len);
736 if (ret != 0) {
737 goto unlock;
738 }
739
740 ret = r502a_validate_rx_packet(&rx_packet);
741 if (ret != 0) {
742 goto unlock;
743 }
744
745 if (rx_packet.buf[R502A_CC_IDX] == R502A_OK) {
746 LOG_DBG("Load template data from id #%d to Char_buffer2", id);
747 } else {
748 LOG_ERR("Error Loading template 0x%X",
749 rx_packet.buf[R502A_CC_IDX]);
750 ret = -EIO;
751 }
752
753 unlock:
754 k_mutex_unlock(&drv_data->lock);
755 return ret;
756 }
757
fps_match_templates(const struct device * dev,struct sensor_value * val)758 static int fps_match_templates(const struct device *dev, struct sensor_value *val)
759 {
760 struct grow_r502a_data *drv_data = dev->data;
761 union r502a_packet rx_packet = {0};
762 char const match_templates_len = 1;
763 int ret = 0;
764
765 struct r502a_led_params led_ctrl = {
766 .ctrl_code = R502A_LED_CTRL_BREATHING,
767 .color_idx = R502A_LED_COLOR_BLUE,
768 .speed = R502A_LED_SPEED_HALF,
769 .cycle = 0x01,
770 };
771
772 union r502a_packet tx_packet = {
773 .pid = R502A_COMMAND_PACKET,
774 .data = {R502A_MATCH}
775 };
776
777 k_mutex_lock(&drv_data->lock, K_FOREVER);
778
779 ret = transceive_packet(dev, &tx_packet, &rx_packet, match_templates_len);
780 if (ret != 0) {
781 goto unlock;
782 }
783
784 ret = r502a_validate_rx_packet(&rx_packet);
785 if (ret != 0) {
786 goto unlock;
787 }
788
789 if (rx_packet.buf[R502A_CC_IDX] == R502A_OK) {
790 fps_led_control(dev, &led_ctrl);
791 val->val1 = R502A_FINGER_MATCH_FOUND;
792 val->val2 = sys_get_be16(&rx_packet.data[1]);
793 LOG_INF("Fingerprint matched with a score %d", val->val2);
794 } else if (rx_packet.buf[R502A_CC_IDX] == R502A_NOT_MATCH_CC) {
795 val->val1 = R502A_FINGER_MATCH_NOT_FOUND;
796 LOG_ERR("Fingerprint not matched");
797 ret = -ENOENT;
798 } else {
799 led_ctrl.ctrl_code = R502A_LED_CTRL_ON_ALWAYS;
800 led_ctrl.color_idx = R502A_LED_COLOR_RED;
801 fps_led_control(dev, &led_ctrl);
802 LOG_ERR("Error Matching templates 0x%X",
803 rx_packet.buf[R502A_CC_IDX]);
804 ret = -EIO;
805 }
806 unlock:
807 k_mutex_unlock(&drv_data->lock);
808 return ret;
809 }
810
fps_capture(const struct device * dev)811 static int fps_capture(const struct device *dev)
812 {
813 struct grow_r502a_data *drv_data = dev->data;
814 int ret;
815
816 k_mutex_lock(&drv_data->lock, K_FOREVER);
817
818 ret = fps_get_image(dev);
819 if (ret != 0) {
820 goto unlock;
821 }
822
823 ret = fps_image_to_char(dev, R502A_CHAR_BUF_1);
824 if (ret != 0) {
825 goto unlock;
826 }
827
828 ret = fps_get_image(dev);
829 if (ret != 0) {
830 goto unlock;
831 }
832
833 ret = fps_image_to_char(dev, R502A_CHAR_BUF_2);
834
835 unlock:
836 k_mutex_unlock(&drv_data->lock);
837 return ret;
838 }
839
840 /**
841 * @brief upload template from sensor device's RAM buffer 1 to controller.
842 *
843 * @result temp->data holds the template to be uploaded to controller.
844 * temp->len holds the length of the template.
845 */
fps_upload_char_buf(const struct device * dev,struct r502a_template * temp)846 int fps_upload_char_buf(const struct device *dev, struct r502a_template *temp)
847 {
848 struct grow_r502a_data *drv_data = dev->data;
849 union r502a_packet rx_packet = {0};
850 char const upload_temp_len = 2;
851 int ret = 0, idx = 0;
852
853 if (!temp->data || (temp->len < R502A_TEMPLATE_MAX_SIZE)) {
854 LOG_ERR("Invalid temp data");
855 return -EINVAL;
856 }
857
858 union r502a_packet tx_packet = {
859 .pid = R502A_COMMAND_PACKET,
860 .data = {R502A_UPCHAR, R502A_CHAR_BUF_1}
861 };
862
863 k_mutex_lock(&drv_data->lock, K_FOREVER);
864
865 ret = transceive_packet(dev, &tx_packet, &rx_packet, upload_temp_len);
866 if (ret != 0) {
867 goto unlock;
868 }
869
870 ret = r502a_validate_rx_packet(&rx_packet);
871 if (ret != 0) {
872 goto unlock;
873 }
874
875 if (rx_packet.buf[R502A_CC_IDX] == R502A_OK) {
876 LOG_DBG("Upload to host controller");
877 } else {
878 LOG_ERR("Error uploading template 0x%X",
879 rx_packet.buf[R502A_CC_IDX]);
880 ret = -EIO;
881 goto unlock;
882 }
883
884 do {
885 ret = transceive_packet(dev, NULL, &rx_packet, 0);
886 if (ret != 0) {
887 goto unlock;
888 }
889
890 ret = r502a_validate_rx_packet(&rx_packet);
891 if (ret != 0) {
892 goto unlock;
893 }
894
895 memcpy(&temp->data[idx], &rx_packet.data,
896 sys_be16_to_cpu(rx_packet.len) - R502A_CHECKSUM_LEN);
897 idx += sys_be16_to_cpu(rx_packet.len) - R502A_CHECKSUM_LEN;
898 } while (rx_packet.pid != R502A_END_DATA_PACKET);
899
900 temp->len = idx;
901
902 unlock:
903 k_mutex_unlock(&drv_data->lock);
904 return ret;
905 }
906
907 /**
908 * @brief download template from controller to sensor device's RAM buffer.
909 * @Notes char_buf_id - other than value 1 will be considered as value 2
910 * by R502A sensor.
911 */
fps_download_char_buf(const struct device * dev,uint8_t char_buf_id,const struct r502a_template * temp)912 int fps_download_char_buf(const struct device *dev, uint8_t char_buf_id,
913 const struct r502a_template *temp)
914 {
915 struct grow_r502a_data *drv_data = dev->data;
916 union r502a_packet rx_packet = {0};
917 char const down_temp_len = 2;
918 int ret = 0, i = 0;
919
920 if (!temp->data || (temp->len < R502A_TEMPLATE_MAX_SIZE)) {
921 LOG_ERR("Invalid temp data");
922 return -EINVAL;
923 }
924
925 union r502a_packet tx_packet = {
926 .pid = R502A_COMMAND_PACKET,
927 .data = {R502A_DOWNCHAR, char_buf_id}
928 };
929
930 k_mutex_lock(&drv_data->lock, K_FOREVER);
931
932 ret = transceive_packet(dev, &tx_packet, &rx_packet, down_temp_len);
933 if (ret != 0) {
934 goto unlock;
935 }
936
937 ret = r502a_validate_rx_packet(&rx_packet);
938 if (ret != 0) {
939 goto unlock;
940 }
941
942 if (rx_packet.buf[R502A_CC_IDX] == R502A_OK) {
943 LOG_DBG("Download to R502A sensor");
944 } else {
945 LOG_ERR("Error downloading template 0x%X",
946 rx_packet.buf[R502A_CC_IDX]);
947 ret = -EIO;
948 goto unlock;
949 }
950
951 while (i < (R502A_TEMPLATE_MAX_SIZE - CONFIG_R502A_DATA_PKT_SIZE)) {
952 tx_packet.pid = R502A_DATA_PACKET;
953 memcpy(tx_packet.data, &temp->data[i], CONFIG_R502A_DATA_PKT_SIZE);
954
955 ret = transceive_packet(dev, &tx_packet, NULL, CONFIG_R502A_DATA_PKT_SIZE);
956 if (ret != 0) {
957 goto unlock;
958 }
959
960 i += CONFIG_R502A_DATA_PKT_SIZE;
961 }
962
963 memcpy(tx_packet.data, &temp->data[i], (R502A_TEMPLATE_MAX_SIZE - i));
964 tx_packet.pid = R502A_END_DATA_PACKET;
965 ret = transceive_packet(dev, &tx_packet, NULL, (R502A_TEMPLATE_MAX_SIZE - i));
966
967 unlock:
968 k_mutex_unlock(&drv_data->lock);
969 return ret;
970 }
971
fps_init(const struct device * dev)972 static int fps_init(const struct device *dev)
973 {
974 struct grow_r502a_data *drv_data = dev->data;
975 struct sensor_value val;
976 int ret;
977
978 struct r502a_led_params led_ctrl = {
979 .ctrl_code = R502A_LED_CTRL_FLASHING,
980 .color_idx = R502A_LED_COLOR_PURPLE,
981 .speed = R502A_LED_SPEED_HALF,
982 .cycle = 0x02,
983 };
984
985 k_mutex_lock(&drv_data->lock, K_FOREVER);
986
987 ret = fps_verify_password(dev);
988 if (ret != 0) {
989 goto unlock;
990 }
991
992 val.val1 = R502A_DATA_PKG_LEN;
993 val.val2 = LOG2(CONFIG_R502A_DATA_PKT_SIZE >> 5);
994 ret = fps_set_sys_param(dev, &val);
995 if (ret != 0) {
996 goto unlock;
997 }
998
999 ret = fps_led_control(dev, &led_ctrl);
1000
1001 unlock:
1002 k_mutex_unlock(&drv_data->lock);
1003 return ret;
1004 }
1005
grow_r502a_sample_fetch(const struct device * dev,enum sensor_channel chan)1006 static int grow_r502a_sample_fetch(const struct device *dev, enum sensor_channel chan)
1007 {
1008 struct grow_r502a_data *drv_data = dev->data;
1009 int ret;
1010
1011 k_mutex_lock(&drv_data->lock, K_FOREVER);
1012 ret = fps_get_template_count(dev);
1013 k_mutex_unlock(&drv_data->lock);
1014
1015 return ret;
1016 }
1017
grow_r502a_channel_get(const struct device * dev,enum sensor_channel chan,struct sensor_value * val)1018 static int grow_r502a_channel_get(const struct device *dev, enum sensor_channel chan,
1019 struct sensor_value *val)
1020 {
1021 struct grow_r502a_data *drv_data = dev->data;
1022
1023 if ((enum sensor_channel_grow_r502a)chan == SENSOR_CHAN_FINGERPRINT) {
1024 val->val1 = drv_data->template_count;
1025 } else {
1026 LOG_ERR("Invalid channel");
1027 return -ENOTSUP;
1028 }
1029
1030 return 0;
1031 }
1032
grow_r502a_attr_set(const struct device * dev,enum sensor_channel chan,enum sensor_attribute attr,const struct sensor_value * val)1033 static int grow_r502a_attr_set(const struct device *dev, enum sensor_channel chan,
1034 enum sensor_attribute attr, const struct sensor_value *val)
1035 {
1036 struct grow_r502a_data *drv_data = dev->data;
1037
1038 if ((enum sensor_channel_grow_r502a)chan != SENSOR_CHAN_FINGERPRINT) {
1039 LOG_ERR("Channel not supported");
1040 return -ENOTSUP;
1041 }
1042
1043 switch ((enum sensor_attribute_grow_r502a)attr) {
1044 case SENSOR_ATTR_R502A_CAPTURE:
1045 return fps_capture(dev);
1046 case SENSOR_ATTR_R502A_TEMPLATE_CREATE:
1047 return fps_create_model(dev);
1048 case SENSOR_ATTR_R502A_RECORD_ADD:
1049 return fps_store_model(dev, val->val1);
1050 case SENSOR_ATTR_R502A_RECORD_DEL:
1051 return fps_delete_model(dev, val->val1, val->val2);
1052 case SENSOR_ATTR_R502A_RECORD_EMPTY:
1053 return fps_empty_db(dev);
1054 case SENSOR_ATTR_R502A_RECORD_LOAD:
1055 return fps_load_template(dev, val->val1);
1056 case SENSOR_ATTR_R502A_SYS_PARAM: {
1057 int ret = 0;
1058
1059 if (val->val1 == R502A_DATA_PKG_LEN) {
1060 LOG_ERR("Data package length should not be runtime configurable");
1061 return -EINVAL;
1062 };
1063 k_mutex_lock(&drv_data->lock, K_FOREVER);
1064 ret = fps_set_sys_param(dev, val);
1065 if (ret != 0) {
1066 k_mutex_unlock(&drv_data->lock);
1067 return ret;
1068 }
1069 k_mutex_unlock(&drv_data->lock);
1070 return 0;
1071 }
1072 default:
1073 LOG_ERR("Sensor attribute not supported");
1074 return -ENOTSUP;
1075 }
1076
1077 }
1078
grow_r502a_attr_get(const struct device * dev,enum sensor_channel chan,enum sensor_attribute attr,struct sensor_value * val)1079 static int grow_r502a_attr_get(const struct device *dev, enum sensor_channel chan,
1080 enum sensor_attribute attr, struct sensor_value *val)
1081 {
1082 int ret;
1083
1084 if ((enum sensor_channel_grow_r502a)chan != SENSOR_CHAN_FINGERPRINT) {
1085 LOG_ERR("Channel not supported");
1086 return -ENOTSUP;
1087 }
1088
1089 switch ((enum sensor_attribute_grow_r502a)attr) {
1090 case SENSOR_ATTR_R502A_RECORD_FIND:
1091 ret = fps_search(dev, val);
1092 break;
1093 case SENSOR_ATTR_R502A_RECORD_FREE_IDX:
1094 ret = fps_read_template_table(dev, &val->val1);
1095 break;
1096 case SENSOR_ATTR_R502A_COMPARE:
1097 ret = fps_match_templates(dev, val);
1098 break;
1099 default:
1100 LOG_ERR("Sensor attribute not supported");
1101 ret = -ENOTSUP;
1102 break;
1103 }
1104
1105 return ret;
1106 }
1107
grow_r502a_uart_flush(const struct device * dev)1108 static void grow_r502a_uart_flush(const struct device *dev)
1109 {
1110 uint8_t c;
1111
1112 while (uart_fifo_read(dev, &c, 1) > 0) {
1113 continue;
1114 }
1115 }
1116
grow_r502a_init(const struct device * dev)1117 static int grow_r502a_init(const struct device *dev)
1118 {
1119 const struct grow_r502a_config *cfg = dev->config;
1120 struct grow_r502a_data *drv_data = dev->data;
1121 int ret;
1122
1123 if (!device_is_ready(cfg->dev)) {
1124 LOG_ERR("%s: grow_r502a device not ready", dev->name);
1125 return -ENODEV;
1126 }
1127
1128 if (IS_ENABLED(CONFIG_GROW_R502A_GPIO_POWER)) {
1129 if (!gpio_is_ready_dt(&cfg->vin_gpios)) {
1130 LOG_ERR("GPIO port %s not ready", cfg->vin_gpios.port->name);
1131 return -ENODEV;
1132 }
1133
1134 ret = gpio_pin_configure_dt(&cfg->vin_gpios, GPIO_OUTPUT_ACTIVE);
1135
1136 if (ret < 0) {
1137 return ret;
1138 }
1139
1140 k_sleep(K_MSEC(R502A_DELAY));
1141
1142 if (!gpio_is_ready_dt(&cfg->act_gpios)) {
1143 LOG_ERR("GPIO port %s not ready", cfg->act_gpios.port->name);
1144 return -ENODEV;
1145 }
1146
1147 ret = gpio_pin_configure_dt(&cfg->act_gpios, GPIO_OUTPUT_ACTIVE);
1148 if (ret < 0) {
1149 return ret;
1150 }
1151
1152 k_sleep(K_MSEC(R502A_DELAY));
1153 }
1154
1155 grow_r502a_uart_flush(cfg->dev);
1156
1157 k_mutex_init(&drv_data->lock);
1158 k_sem_init(&drv_data->uart_rx_sem, 0, 1);
1159 k_sem_init(&drv_data->uart_tx_sem, 0, 1);
1160
1161 uart_irq_callback_user_data_set(cfg->dev, uart_cb_handler, (void *)dev);
1162
1163 uart_irq_rx_disable(cfg->dev);
1164 uart_irq_tx_disable(cfg->dev);
1165
1166 #ifdef CONFIG_GROW_R502A_TRIGGER
1167 ret = grow_r502a_init_interrupt(dev);
1168
1169 if (ret < 0) {
1170 LOG_ERR("Failed to initialize interrupt!");
1171 return ret;
1172 }
1173 #endif
1174
1175 return fps_init(dev);
1176 }
1177
1178 static DEVICE_API(sensor, grow_r502a_api) = {
1179 .sample_fetch = grow_r502a_sample_fetch,
1180 .channel_get = grow_r502a_channel_get,
1181 .attr_set = grow_r502a_attr_set,
1182 .attr_get = grow_r502a_attr_get,
1183 #ifdef CONFIG_GROW_R502A_TRIGGER
1184 .trigger_set = grow_r502a_trigger_set,
1185 #endif
1186 };
1187
1188 #ifdef CONFIG_LED
grow_r502a_led_set_color(const struct device * dev,uint32_t led,uint8_t num_colors,const uint8_t * color)1189 static int grow_r502a_led_set_color(const struct device *dev, uint32_t led,
1190 uint8_t num_colors, const uint8_t *color)
1191 {
1192 struct grow_r502a_data *drv_data = dev->data;
1193
1194 if (!(*color)) {
1195 LOG_ERR("invalid color code value");
1196 return -ENOTSUP;
1197 }
1198 drv_data->led_color = *color;
1199
1200 return 0;
1201 }
1202
grow_r502a_led_on(const struct device * dev,uint32_t led)1203 static int grow_r502a_led_on(const struct device *dev, uint32_t led)
1204 {
1205 struct grow_r502a_data *drv_data = dev->data;
1206
1207 if (!drv_data->led_color) {
1208 drv_data->led_color = R502A_LED_COLOR_BLUE;
1209 }
1210
1211 struct r502a_led_params led_ctrl = {
1212 .ctrl_code = R502A_LED_CTRL_ON_ALWAYS,
1213 .color_idx = drv_data->led_color,
1214 };
1215
1216 return fps_led_control(dev, &led_ctrl);
1217 }
1218
grow_r502a_led_off(const struct device * dev,uint32_t led)1219 static int grow_r502a_led_off(const struct device *dev, uint32_t led)
1220 {
1221 struct r502a_led_params led_ctrl = {
1222 .ctrl_code = R502A_LED_CTRL_OFF_ALWAYS,
1223 };
1224
1225 return fps_led_control(dev, &led_ctrl);
1226 }
1227
1228 static DEVICE_API(led, grow_r502a_leds_api) = {
1229 .set_color = grow_r502a_led_set_color,
1230 .on = grow_r502a_led_on,
1231 .off = grow_r502a_led_off,
1232 };
1233 #endif
1234
1235 #define GROW_R502A_INIT(index) \
1236 static struct grow_r502a_data grow_r502a_data_##index; \
1237 \
1238 static struct grow_r502a_config grow_r502a_config_##index = { \
1239 .dev = DEVICE_DT_GET(DT_INST_BUS(index)), \
1240 .comm_addr = DT_INST_REG_ADDR(index), \
1241 IF_ENABLED(CONFIG_GROW_R502A_GPIO_POWER, \
1242 (.vin_gpios = GPIO_DT_SPEC_INST_GET_OR(index, vin_gpios, {}), \
1243 .act_gpios = GPIO_DT_SPEC_INST_GET_OR(index, act_gpios, {}),)) \
1244 IF_ENABLED(CONFIG_GROW_R502A_TRIGGER, \
1245 (.int_gpios = GPIO_DT_SPEC_INST_GET_OR(index, int_gpios, {}),)) \
1246 }; \
1247 \
1248 DEVICE_DT_INST_DEFINE(index, &grow_r502a_init, NULL, &grow_r502a_data_##index, \
1249 &grow_r502a_config_##index, POST_KERNEL, \
1250 CONFIG_SENSOR_INIT_PRIORITY, &grow_r502a_api); \
1251
1252 #define GROW_R502A_LED_INIT(index) \
1253 DEVICE_DT_INST_DEFINE(index, NULL, NULL, &grow_r502a_data_##index, \
1254 &grow_r502a_config_##index, POST_KERNEL, \
1255 CONFIG_LED_INIT_PRIORITY, &grow_r502a_leds_api); \
1256
1257 #define DT_DRV_COMPAT hzgrow_r502a
1258 DT_INST_FOREACH_STATUS_OKAY(GROW_R502A_INIT)
1259 #undef DT_DRV_COMPAT
1260
1261 #ifdef CONFIG_LED
1262 #define DT_DRV_COMPAT hzgrow_r502a_led
1263 DT_INST_FOREACH_STATUS_OKAY(GROW_R502A_LED_INIT)
1264 #undef DT_DRV_COMPAT
1265 #endif
1266