Commit b63fe1c3 authored by Dinesh Kumar K's avatar Dinesh Kumar K Committed by Anas Nashif
Browse files

drivers: sensor: grow_r502a: modified Tx and Rx data handling

improvised uart tx and rx handler functions to handle
large chunk of fingerprint data from/to the sensor.

Signed-off-by: default avatarDinesh Kumar K <dinesh@linumiz.com>
parent 3c8bd0bc
Loading
Loading
Loading
Loading
+105 −36
Changes for drivers/sensor/grow_r502a/grow_r502a.c: 105 added lines, 36 removed lines.
Original line number Diff line number Diff line
@@ -18,19 +18,22 @@
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(GROW_R502A, CONFIG_SENSOR_LOG_LEVEL);

static void transceive_packet(const struct device *dev, union r502a_packet *tx_packet,
static int transceive_packet(const struct device *dev, union r502a_packet *tx_packet,
				union r502a_packet *rx_packet, char const data_len)
{
	const struct grow_r502a_config *cfg = dev->config;
	struct grow_r502a_data *drv_data = dev->data;

	if (tx_packet) {
		uint16_t check_sum, pkg_len;

		pkg_len = data_len + R502A_CHECKSUM_LEN;
		check_sum = (pkg_len >> 8) + (pkg_len & 0xFF) + tx_packet->pid;

	sys_put_be16(R502A_STARTCODE, tx_packet->start);
	sys_put_be32(cfg->comm_addr, tx_packet->addr);
	sys_put_be16(pkg_len, tx_packet->len);
		tx_packet->start = sys_cpu_to_be16(R502A_STARTCODE);
		tx_packet->addr = sys_cpu_to_be32(cfg->comm_addr);
		tx_packet->len = sys_cpu_to_be16(pkg_len);

		for (int i = 0; i < data_len; i++) {
			check_sum += tx_packet->data[i];
		}
@@ -39,14 +42,28 @@ static void transceive_packet(const struct device *dev, union r502a_packet *tx_p
		drv_data->tx_buf.len = pkg_len + R502A_HEADER_LEN;
		drv_data->tx_buf.data = tx_packet->buf;

	drv_data->rx_buf.data = rx_packet->buf;

		LOG_HEXDUMP_DBG(drv_data->tx_buf.data, drv_data->tx_buf.len, "TX");

	uart_irq_rx_disable(cfg->dev);
		uart_irq_tx_enable(cfg->dev);

	k_sem_take(&drv_data->uart_rx_sem, K_FOREVER);
		if (k_sem_take(&drv_data->uart_tx_sem, K_MSEC(1500)) != 0) {
			LOG_ERR("Tx data timeout");
			return -ETIMEDOUT;
		}
	}

	if (rx_packet) {
		drv_data->rx_buf.data = rx_packet->buf;
		drv_data->rx_buf.len = 0;
		drv_data->pkt_len = R502A_HEADER_LEN;
		uart_irq_rx_enable(cfg->dev);
		if (k_sem_take(&drv_data->uart_rx_sem, K_MSEC(1500)) != 0) {
			LOG_ERR("Rx data timeout");
			return -ETIMEDOUT;
		}
	}

	return 0;
}

static void uart_cb_tx_handler(const struct device *dev)
@@ -54,21 +71,18 @@ static void uart_cb_tx_handler(const struct device *dev)
	const struct grow_r502a_config *config = dev->config;
	struct grow_r502a_data *drv_data = dev->data;
	int sent = 0;
	uint8_t retries = 3;

	while (drv_data->tx_buf.len) {
		sent = uart_fifo_fill(config->dev, &drv_data->tx_buf.data[sent],
	if (drv_data->tx_buf.len > 0) {
		sent = uart_fifo_fill(config->dev, drv_data->tx_buf.data,
							drv_data->tx_buf.len);
		drv_data->tx_buf.data += sent;
		drv_data->tx_buf.len -= sent;
	}

	while (retries--) {
		if (uart_irq_tx_complete(config->dev)) {
	if (!drv_data->tx_buf.len && uart_irq_tx_complete(config->dev) > 0) {
		uart_irq_tx_disable(config->dev);
			drv_data->rx_buf.len = 0;
			uart_irq_rx_enable(config->dev);
			break;
		}
		k_sem_give(&drv_data->uart_tx_sem);
		return;
	}
}

@@ -76,7 +90,7 @@ static void uart_cb_handler(const struct device *dev, void *user_data)
{
	const struct device *uart_dev = user_data;
	struct grow_r502a_data *drv_data = uart_dev->data;
	int len, pkt_sz = 0;
	int len = 0;
	int offset = drv_data->rx_buf.len;

	if ((uart_irq_update(dev) > 0) && (uart_irq_is_pending(dev) > 0)) {
@@ -86,18 +100,24 @@ static void uart_cb_handler(const struct device *dev, void *user_data)

		while (uart_irq_rx_ready(dev)) {
			len = uart_fifo_read(dev, &drv_data->rx_buf.data[offset],
						R502A_BUF_SIZE - offset);
								drv_data->pkt_len);
			offset += len;
			drv_data->rx_buf.len = offset;

			if (offset >= R502A_HEADER_LEN) {
				pkt_sz = R502A_HEADER_LEN +
						drv_data->rx_buf.data[R502A_HEADER_LEN-1];
			if (drv_data->pkt_len != len) {
				drv_data->pkt_len -= len;
				continue;
			}
			if (offset < pkt_sz) {

			if (offset == R502A_HEADER_LEN) {
				drv_data->pkt_len = sys_get_be16(
							&drv_data->rx_buf.data[R502A_PKG_LEN_IDX]
							);
				continue;
			}

			LOG_HEXDUMP_DBG(drv_data->rx_buf.data, offset, "RX");
			uart_irq_rx_disable(dev);
			k_sem_give(&drv_data->uart_rx_sem);
			break;
		}
@@ -108,6 +128,7 @@ static int fps_led_control(const struct device *dev, struct r502a_led_params *le
{
	union r502a_packet rx_packet = {0};
	char const led_ctrl_len = 5;
	int ret = 0;

	union r502a_packet tx_packet = {
		.pid = R502A_COMMAND_PACKET,
@@ -115,7 +136,10 @@ static int fps_led_control(const struct device *dev, struct r502a_led_params *le
				led_control->speed, led_control->color_idx, led_control->cycle}
	};

	transceive_packet(dev, &tx_packet, &rx_packet, led_ctrl_len);
	ret = transceive_packet(dev, &tx_packet, &rx_packet, led_ctrl_len);
	if (ret != 0) {
		return ret;
	}

	if (rx_packet.pid != R502A_ACK_PACKET) {
		LOG_ERR("Error receiving ack packet 0x%X", rx_packet.pid);
@@ -137,6 +161,7 @@ static int fps_verify_password(const struct device *dev)
{
	union r502a_packet rx_packet = {0};
	char const verify_pwd_len = 5;
	int ret = 0;

	union r502a_packet tx_packet = {
		.pid = R502A_COMMAND_PACKET,
@@ -145,7 +170,10 @@ static int fps_verify_password(const struct device *dev)

	sys_put_be32(R502A_DEFAULT_PASSWORD, &tx_packet.data[1]);

	transceive_packet(dev, &tx_packet, &rx_packet, verify_pwd_len);
	ret = transceive_packet(dev, &tx_packet, &rx_packet, verify_pwd_len);
	if (ret != 0) {
		return ret;
	}

	if (rx_packet.pid != R502A_ACK_PACKET) {
		LOG_ERR("Error receiving ack packet 0x%X", rx_packet.pid);
@@ -167,13 +195,17 @@ static int fps_get_template_count(const struct device *dev)
	struct grow_r502a_data *drv_data = dev->data;
	union r502a_packet rx_packet = {0};
	char const get_temp_cnt_len = 1;
	int ret = 0;

	union r502a_packet tx_packet = {
		.pid = R502A_COMMAND_PACKET,
		.data = {R502A_TEMPLATECOUNT},
	};

	transceive_packet(dev, &tx_packet, &rx_packet, get_temp_cnt_len);
	ret = transceive_packet(dev, &tx_packet, &rx_packet, get_temp_cnt_len);
	if (ret != 0) {
		return ret;
	}

	if (rx_packet.pid != R502A_ACK_PACKET) {
		LOG_ERR("Error receiving ack packet 0x%X", rx_packet.pid);
@@ -206,7 +238,10 @@ static int fps_read_template_table(const struct device *dev, uint32_t *free_idx)

	k_mutex_lock(&drv_data->lock, K_FOREVER);

	transceive_packet(dev, &tx_packet, &rx_packet, temp_table_len);
	ret = transceive_packet(dev, &tx_packet, &rx_packet, temp_table_len);
	if (ret != 0) {
		goto unlock;
	}

	if (rx_packet.pid != R502A_ACK_PACKET) {
		LOG_ERR("Error receiving ack packet 0x%X", rx_packet.pid);
@@ -244,6 +279,7 @@ static int fps_get_image(const struct device *dev)
{
	union r502a_packet rx_packet = {0};
	char const get_img_len = 1;
	int ret = 0;

	struct r502a_led_params led_ctrl = {
		.ctrl_code = R502A_LED_CTRL_BREATHING,
@@ -257,7 +293,10 @@ static int fps_get_image(const struct device *dev)
		.data = {R502A_GENIMAGE},
	};

	transceive_packet(dev, &tx_packet, &rx_packet, get_img_len);
	ret = transceive_packet(dev, &tx_packet, &rx_packet, get_img_len);
	if (ret != 0) {
		return ret;
	}

	if (rx_packet.pid != R502A_ACK_PACKET) {
		LOG_ERR("Error receiving ack packet 0x%X", rx_packet.pid);
@@ -282,13 +321,17 @@ static int fps_image_to_char(const struct device *dev, uint8_t char_buf_idx)
{
	union r502a_packet rx_packet = {0};
	char const img_to_char_len = 2;
	int ret = 0;

	union r502a_packet tx_packet = {
		.pid = R502A_COMMAND_PACKET,
		.data = {R502A_IMAGE2TZ, char_buf_idx}
	};

	transceive_packet(dev, &tx_packet, &rx_packet, img_to_char_len);
	ret = transceive_packet(dev, &tx_packet, &rx_packet, img_to_char_len);
	if (ret != 0) {
		return ret;
	}

	if (rx_packet.pid != R502A_ACK_PACKET) {
		LOG_ERR("Error receiving ack packet 0x%X", rx_packet.pid);
@@ -309,13 +352,17 @@ static int fps_create_model(const struct device *dev)
{
	union r502a_packet rx_packet = {0};
	char const create_model_len = 1;
	int ret = 0;

	union r502a_packet tx_packet = {
		.pid = R502A_COMMAND_PACKET,
		.data = {R502A_REGMODEL}
	};

	transceive_packet(dev, &tx_packet, &rx_packet, create_model_len);
	ret = transceive_packet(dev, &tx_packet, &rx_packet, create_model_len);
	if (ret != 0) {
		return ret;
	}

	if (rx_packet.pid != R502A_ACK_PACKET) {
		LOG_ERR("Error receiving ack packet 0x%X", rx_packet.pid);
@@ -354,7 +401,10 @@ static int fps_store_model(const struct device *dev, uint16_t id)

	k_mutex_lock(&drv_data->lock, K_FOREVER);

	transceive_packet(dev, &tx_packet, &rx_packet, store_model_len);
	ret = transceive_packet(dev, &tx_packet, &rx_packet, store_model_len);
	if (ret != 0) {
		goto unlock;
	}

	if (rx_packet.pid != R502A_ACK_PACKET) {
		LOG_ERR("Error receiving ack packet 0x%X", rx_packet.pid);
@@ -393,7 +443,10 @@ static int fps_delete_model(const struct device *dev, uint16_t id, uint16_t coun

	k_mutex_lock(&drv_data->lock, K_FOREVER);

	transceive_packet(dev, &tx_packet, &rx_packet, delete_model_len);
	ret = transceive_packet(dev, &tx_packet, &rx_packet, delete_model_len);
	if (ret != 0) {
		goto unlock;
	}

	if (rx_packet.pid != R502A_ACK_PACKET) {
		LOG_ERR("Error receiving ack packet 0x%X", rx_packet.pid);
@@ -426,7 +479,10 @@ static int fps_empty_db(const struct device *dev)

	k_mutex_lock(&drv_data->lock, K_FOREVER);

	transceive_packet(dev, &tx_packet, &rx_packet, empty_db_len);
	ret = transceive_packet(dev, &tx_packet, &rx_packet, empty_db_len);
	if (ret != 0) {
		goto unlock;
	}

	if (rx_packet.pid != R502A_ACK_PACKET) {
		LOG_ERR("Error receiving ack packet 0x%X", rx_packet.pid);
@@ -470,7 +526,10 @@ static int fps_search(const struct device *dev, struct sensor_value *val)

	k_mutex_lock(&drv_data->lock, K_FOREVER);

	transceive_packet(dev, &tx_packet, &rx_packet, search_len);
	ret = transceive_packet(dev, &tx_packet, &rx_packet, search_len);
	if (ret != 0) {
		goto unlock;
	}

	if (rx_packet.pid != R502A_ACK_PACKET) {
		LOG_ERR("Error receiving ack packet 0x%X", rx_packet.pid);
@@ -520,7 +579,10 @@ static int fps_load_template(const struct device *dev, uint16_t id)

	k_mutex_lock(&drv_data->lock, K_FOREVER);

	transceive_packet(dev, &tx_packet, &rx_packet, load_tmp_len);
	ret = transceive_packet(dev, &tx_packet, &rx_packet, load_tmp_len);
	if (ret != 0) {
		goto unlock;
	}

	if (rx_packet.pid != R502A_ACK_PACKET) {
		LOG_ERR("Error receiving ack packet 0x%X", rx_packet.pid);
@@ -562,7 +624,10 @@ static int fps_match_templates(const struct device *dev, struct sensor_value *va

	k_mutex_lock(&drv_data->lock, K_FOREVER);

	transceive_packet(dev, &tx_packet, &rx_packet, match_templates_len);
	ret = transceive_packet(dev, &tx_packet, &rx_packet, match_templates_len);
	if (ret != 0) {
		goto unlock;
	}

	if (rx_packet.pid != R502A_ACK_PACKET) {
		LOG_ERR("Error receiving ack packet 0x%X", rx_packet.pid);
@@ -784,9 +849,13 @@ static int grow_r502a_init(const struct device *dev)

	k_mutex_init(&drv_data->lock);
	k_sem_init(&drv_data->uart_rx_sem, 0, 1);
	k_sem_init(&drv_data->uart_tx_sem, 0, 1);

	uart_irq_callback_user_data_set(cfg->dev, uart_cb_handler, (void *)dev);

	uart_irq_rx_disable(cfg->dev);
	uart_irq_tx_disable(cfg->dev);

#ifdef CONFIG_GROW_R502A_TRIGGER
	ret = grow_r502a_init_interrupt(dev);

+14 −6
Changes for drivers/sensor/grow_r502a/grow_r502a.h: 14 added lines, 6 removed lines.
Original line number Diff line number Diff line
@@ -112,6 +112,8 @@
#define R502A_PKG_LEN_IDX 7
#define R502A_CC_IDX 9 /* Confirmation code index*/

#define R502A_COMMON_ACK_LEN 12

#define R502A_STARTCODE_LEN 2
#define R502A_ADDRESS_LEN 4
#define R502A_PKG_LEN	2
@@ -120,10 +122,14 @@

#define R502A_CHAR_BUF_1 1
#define R502A_CHAR_BUF_2 2
#define R502A_CHAR_BUF_TOTAL 2

#define R502A_CHAR_BUF_SIZE 384 /* Maximum size of characteristic value buffer*/
#define R502A_TEMPLATE_SIZE 768 /* Maximum size of template, twice of CHAR_BUF*/
#define R502A_MAX_BUF_SIZE 779 /*sum of checksum, header and template sizes*/
#define R502A_BUF_SIZE 64

#define R502A_MAX_BUF_SIZE  R502A_BUF_SIZE + R502A_COMMON_ACK_LEN

#define R502A_TEMPLATES_PER_PAGE 256
#define R502A_TEMP_TABLE_BUF_SIZE 32
#define R502A_DELETE_COUNT_OFFSET 1
@@ -173,14 +179,14 @@ struct r502a_led_params {

union r502a_packet {
	struct {
		uint8_t	start[R502A_STARTCODE_LEN];
		uint8_t	addr[R502A_ADDRESS_LEN];
		uint16_t start;
		uint32_t addr;
		uint8_t	pid;
		uint8_t	len[R502A_PKG_LEN];
		uint16_t len;
		uint8_t data[R502A_BUF_SIZE];
	};
	} __packed;

	uint8_t buf[R502A_BUF_SIZE];
	uint8_t buf[R502A_MAX_BUF_SIZE];
};

struct r502a_buf {
@@ -206,8 +212,10 @@ struct grow_r502a_data {

	struct r502a_buf tx_buf;
	struct r502a_buf rx_buf;
	uint16_t pkt_len;

	struct k_mutex lock;
	struct k_sem uart_tx_sem;
	struct k_sem uart_rx_sem;

	uint16_t template_count;