|
20 | 20 | LOG_MODULE_REGISTER(GROW_R502A, CONFIG_SENSOR_LOG_LEVEL);
|
21 | 21 |
|
22 | 22 | static int transceive_packet(const struct device *dev, union r502a_packet *tx_packet,
|
23 |
| - union r502a_packet *rx_packet, char const data_len) |
| 23 | + union r502a_packet *rx_packet, uint16_t data_len) |
24 | 24 | {
|
25 | 25 | const struct grow_r502a_config *cfg = dev->config;
|
26 | 26 | struct grow_r502a_data *drv_data = dev->data;
|
@@ -784,6 +784,135 @@ static int fps_capture(const struct device *dev)
|
784 | 784 | return ret;
|
785 | 785 | }
|
786 | 786 |
|
| 787 | +/** |
| 788 | + * @brief upload template from sensor device's RAM buffer 1 to controller. |
| 789 | + * |
| 790 | + * @result temp->data holds the template to be uploaded to controller. |
| 791 | + * temp->len holds the length of the template. |
| 792 | + */ |
| 793 | +int fps_upload_char_buf(const struct device *dev, struct r502a_template *temp) |
| 794 | +{ |
| 795 | + struct grow_r502a_data *drv_data = dev->data; |
| 796 | + union r502a_packet rx_packet = {0}; |
| 797 | + char const upload_temp_len = 2; |
| 798 | + int ret = 0, idx = 0; |
| 799 | + |
| 800 | + if (!temp->data || (temp->len < R502A_TEMPLATE_MAX_SIZE)) { |
| 801 | + LOG_ERR("Invalid temp data"); |
| 802 | + return -EINVAL; |
| 803 | + } |
| 804 | + |
| 805 | + union r502a_packet tx_packet = { |
| 806 | + .pid = R502A_COMMAND_PACKET, |
| 807 | + .data = {R502A_UPCHAR, R502A_CHAR_BUF_1} |
| 808 | + }; |
| 809 | + |
| 810 | + k_mutex_lock(&drv_data->lock, K_FOREVER); |
| 811 | + |
| 812 | + ret = transceive_packet(dev, &tx_packet, &rx_packet, upload_temp_len); |
| 813 | + if (ret != 0) { |
| 814 | + goto unlock; |
| 815 | + } |
| 816 | + |
| 817 | + if (rx_packet.pid != R502A_ACK_PACKET) { |
| 818 | + LOG_ERR("Error receiving ack packet 0x%X", rx_packet.pid); |
| 819 | + ret = -EIO; |
| 820 | + goto unlock; |
| 821 | + } |
| 822 | + |
| 823 | + if (rx_packet.buf[R502A_CC_IDX] == R502A_OK) { |
| 824 | + LOG_DBG("Upload to host controller"); |
| 825 | + } else { |
| 826 | + LOG_ERR("Error uploading template 0x%X", |
| 827 | + rx_packet.buf[R502A_CC_IDX]); |
| 828 | + ret = -EIO; |
| 829 | + goto unlock; |
| 830 | + } |
| 831 | + |
| 832 | + do { |
| 833 | + ret = transceive_packet(dev, NULL, &rx_packet, 0); |
| 834 | + if (ret != 0) { |
| 835 | + goto unlock; |
| 836 | + } |
| 837 | + |
| 838 | + memcpy(&temp->data[idx], &rx_packet.data, |
| 839 | + sys_be16_to_cpu(rx_packet.len) - R502A_CHECKSUM_LEN); |
| 840 | + idx += sys_be16_to_cpu(rx_packet.len) - R502A_CHECKSUM_LEN; |
| 841 | + } while (rx_packet.pid != R502A_END_DATA_PACKET); |
| 842 | + |
| 843 | + temp->len = idx; |
| 844 | + |
| 845 | +unlock: |
| 846 | + k_mutex_unlock(&drv_data->lock); |
| 847 | + return ret; |
| 848 | +} |
| 849 | + |
| 850 | +/** |
| 851 | + * @brief download template from controller to sensor device's RAM buffer. |
| 852 | + * @Notes char_buf_id - other than value 1 will be considered as value 2 |
| 853 | + * by R502A sensor. |
| 854 | + */ |
| 855 | +int fps_download_char_buf(const struct device *dev, uint8_t char_buf_id, |
| 856 | + const struct r502a_template *temp) |
| 857 | +{ |
| 858 | + struct grow_r502a_data *drv_data = dev->data; |
| 859 | + union r502a_packet rx_packet = {0}; |
| 860 | + char const down_temp_len = 2; |
| 861 | + int ret = 0, i = 0; |
| 862 | + |
| 863 | + if (!temp->data || (temp->len < R502A_TEMPLATE_MAX_SIZE)) { |
| 864 | + LOG_ERR("Invalid temp data"); |
| 865 | + return -EINVAL; |
| 866 | + } |
| 867 | + |
| 868 | + union r502a_packet tx_packet = { |
| 869 | + .pid = R502A_COMMAND_PACKET, |
| 870 | + .data = {R502A_DOWNCHAR, char_buf_id} |
| 871 | + }; |
| 872 | + |
| 873 | + k_mutex_lock(&drv_data->lock, K_FOREVER); |
| 874 | + |
| 875 | + ret = transceive_packet(dev, &tx_packet, &rx_packet, down_temp_len); |
| 876 | + if (ret != 0) { |
| 877 | + goto unlock; |
| 878 | + } |
| 879 | + |
| 880 | + if (rx_packet.pid != R502A_ACK_PACKET) { |
| 881 | + LOG_ERR("Error receiving ack packet 0x%X", rx_packet.pid); |
| 882 | + ret = -EIO; |
| 883 | + goto unlock; |
| 884 | + } |
| 885 | + |
| 886 | + if (rx_packet.buf[R502A_CC_IDX] == R502A_OK) { |
| 887 | + LOG_DBG("Download to R502A sensor"); |
| 888 | + } else { |
| 889 | + LOG_ERR("Error downloading template 0x%X", |
| 890 | + rx_packet.buf[R502A_CC_IDX]); |
| 891 | + ret = -EIO; |
| 892 | + goto unlock; |
| 893 | + } |
| 894 | + |
| 895 | + while (i < (R502A_TEMPLATE_MAX_SIZE - CONFIG_R502A_DATA_PKT_SIZE)) { |
| 896 | + tx_packet.pid = R502A_DATA_PACKET; |
| 897 | + memcpy(tx_packet.data, &temp->data[i], CONFIG_R502A_DATA_PKT_SIZE); |
| 898 | + |
| 899 | + ret = transceive_packet(dev, &tx_packet, NULL, CONFIG_R502A_DATA_PKT_SIZE); |
| 900 | + if (ret != 0) { |
| 901 | + goto unlock; |
| 902 | + } |
| 903 | + |
| 904 | + i += CONFIG_R502A_DATA_PKT_SIZE; |
| 905 | + } |
| 906 | + |
| 907 | + memcpy(tx_packet.data, &temp->data[i], (R502A_TEMPLATE_MAX_SIZE - i)); |
| 908 | + tx_packet.pid = R502A_END_DATA_PACKET; |
| 909 | + ret = transceive_packet(dev, &tx_packet, NULL, (R502A_TEMPLATE_MAX_SIZE - i)); |
| 910 | + |
| 911 | +unlock: |
| 912 | + k_mutex_unlock(&drv_data->lock); |
| 913 | + return ret; |
| 914 | +} |
| 915 | + |
787 | 916 | static int fps_init(const struct device *dev)
|
788 | 917 | {
|
789 | 918 | struct grow_r502a_data *drv_data = dev->data;
|
|
0 commit comments