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