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

drivers: sensor: grow_r502a: add set/read system parameter

Add functionality for read and set system
parameter of sensor device.

Signed-off-by: default avatarDinesh Kumar K <dinesh@linumiz.com>
parent b63fe1c3
Loading
Loading
Loading
Loading
+9 −0
Changes for drivers/sensor/grow_r502a/Kconfig: 9 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -13,6 +13,15 @@ menuconfig GROW_R502A

if GROW_R502A

config R502A_DATA_PKT_SIZE
	int "Template data packet size"
	default 128
	help
	  Template data packet size for upload and download
	  to the sensor device.
	  valid values are:
	  32, 64, 128, 256.

choice
	prompt "Trigger mode"
	default GROW_R502A_TRIGGER_NONE
+122 −0
Changes for drivers/sensor/grow_r502a/grow_r502a.c: 122 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -11,6 +11,7 @@
#include <zephyr/drivers/uart.h>
#include <zephyr/sys/byteorder.h>
#include <zephyr/drivers/led.h>
#include <zephyr/sys/util.h>

#include <zephyr/drivers/sensor/grow_r502a.h>
#include "grow_r502a.h"
@@ -124,6 +125,103 @@ static void uart_cb_handler(const struct device *dev, void *user_data)
	}
}

/**
 * @brief	Set sensor device's basic parameters like baud rate, security level
 *		and data package length.
 */
static int fps_set_sys_param(const struct device *dev, const struct sensor_value *val)
{
	union r502a_packet rx_packet = {0};
	int ret = 0;
	char const set_sys_param_len = 3;

	union r502a_packet tx_packet = {
		.pid = R502A_COMMAND_PACKET,
		.data = { R502A_SETSYSPARAM, val->val1, val->val2}
	};

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

	if (rx_packet.pid != R502A_ACK_PACKET) {
		LOG_ERR("Error receiving ack packet 0x%X", rx_packet.pid);
		return -EIO;
	}

	if (rx_packet.buf[R502A_CC_IDX] == R502A_OK) {
		LOG_DBG("R502A set system parameter success");
	} else {
		LOG_ERR("R502A set system parameter error %d", rx_packet.buf[R502A_CC_IDX]);
		return -EIO;
	}

	return 0;
}

int r502a_read_sys_param(const struct device *dev, struct r502a_sys_param *val)
{
	struct grow_r502a_data *drv_data = dev->data;

	union r502a_packet rx_packet = {0};
	int offset = 0, ret = 0;
	char const read_sys_param_len = 1;

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

	k_mutex_lock(&drv_data->lock, K_FOREVER);

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

	if (rx_packet.pid != R502A_ACK_PACKET) {
		LOG_ERR("Error receiving ack packet 0x%X", rx_packet.pid);
		ret = -EIO;
		goto unlock;
	}

	if (rx_packet.buf[R502A_CC_IDX] == R502A_OK) {
		LOG_DBG("R502A read system parameter success");
	} else {
		LOG_ERR("R502A read system parameter error %d", rx_packet.buf[R502A_CC_IDX]);
		ret = -EIO;
		goto unlock;
	}

	val->status_reg = sys_get_be16(
				&rx_packet.data[offsetof(struct r502a_sys_param, status_reg) + 1]
				);
	val->system_id = sys_get_be16(
				&rx_packet.data[offsetof(struct r502a_sys_param, system_id) + 1]
				);
	val->lib_size = sys_get_be16(
				&rx_packet.data[offsetof(struct r502a_sys_param, lib_size) + 1]
				);
	val->sec_level = sys_get_be16(
				&rx_packet.data[offsetof(struct r502a_sys_param, sec_level) + 1]
				);
	val->addr = sys_get_be32(
			&rx_packet.data[offsetof(struct r502a_sys_param, addr) + 1]
			);
	offset = sys_get_be16(
			&rx_packet.data[offsetof(struct r502a_sys_param, data_pkt_size) + 1]
			);
	val->data_pkt_size = 32 * (1 << offset);
	val->baud = sys_get_be16(
			&rx_packet.data[offsetof(struct r502a_sys_param, baud) + 1]
			) * 9600;

unlock:
	k_mutex_unlock(&drv_data->lock);
	return ret;
}

static int fps_led_control(const struct device *dev, struct r502a_led_params *led_control)
{
	union r502a_packet rx_packet = {0};
@@ -689,6 +787,7 @@ unlock:
static int fps_init(const struct device *dev)
{
	struct grow_r502a_data *drv_data = dev->data;
	struct sensor_value val;
	int ret;

	struct r502a_led_params led_ctrl = {
@@ -705,6 +804,13 @@ static int fps_init(const struct device *dev)
		goto unlock;
	}

	val.val1 = R502A_DATA_PKG_LEN;
	val.val2 = LOG2(CONFIG_R502A_DATA_PKT_SIZE >> 5);
	ret = fps_set_sys_param(dev, &val);
	if (ret != 0) {
		goto unlock;
	}

	ret = fps_led_control(dev, &led_ctrl);

unlock:
@@ -762,6 +868,22 @@ static int grow_r502a_attr_set(const struct device *dev, enum sensor_channel cha
		return fps_empty_db(dev);
	case SENSOR_ATTR_R502A_RECORD_LOAD:
		return fps_load_template(dev, val->val1);
	case SENSOR_ATTR_R502A_SYS_PARAM: {
		int ret = 0;

		if (val->val1 == R502A_DATA_PKG_LEN) {
			LOG_ERR("Data package length should not be runtime configurable");
			return -EINVAL;
		};
		k_mutex_lock(&drv_data->lock, K_FOREVER);
		ret = fps_set_sys_param(dev, val);
		if (ret != 0) {
			k_mutex_unlock(&drv_data->lock);
			return ret;
		}
		k_mutex_unlock(&drv_data->lock);
		return 0;
	}
	default:
		LOG_ERR("Sensor attribute not supported");
		return -ENOTSUP;
+2 −3
Changes for drivers/sensor/grow_r502a/grow_r502a.h: 2 added lines, 3 removed lines.
Original line number Diff line number Diff line
@@ -126,9 +126,8 @@

#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_BUF_SIZE 64

#define R502A_MAX_BUF_SIZE  R502A_BUF_SIZE + R502A_COMMON_ACK_LEN
#define R502A_MAX_BUF_SIZE  (CONFIG_R502A_DATA_PKT_SIZE + R502A_COMMON_ACK_LEN)

#define R502A_TEMPLATES_PER_PAGE 256
#define R502A_TEMP_TABLE_BUF_SIZE 32
@@ -183,7 +182,7 @@ union r502a_packet {
		uint32_t addr;
		uint8_t	pid;
		uint16_t len;
		uint8_t data[R502A_BUF_SIZE];
		uint8_t data[CONFIG_R502A_DATA_PKT_SIZE];
	} __packed;

	uint8_t buf[R502A_MAX_BUF_SIZE];
+48 −0
Changes for include/zephyr/drivers/sensor/grow_r502a.h: 48 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -20,6 +20,43 @@ enum r502a_led_color_idx {
	R502A_LED_COLOR_PURPLE,
};

#define R502A_BAUD_9600 1
#define R502A_BAUD_19200 2
#define R502A_BAUD_38400 4
#define R502A_BAUD_57600 6
#define R502A_BAUD_115200 12

enum r502a_sec_level {
	R502A_SEC_LEVEL_1 = 1,
	R502A_SEC_LEVEL_2,
	R502A_SEC_LEVEL_3,
	R502A_SEC_LEVEL_4,
	R502A_SEC_LEVEL_5
};

enum r502a_data_len {
	R502A_PKG_LEN_32,
	R502A_PKG_LEN_64,
	R502A_PKG_LEN_128,
	R502A_PKG_LEN_256
};

enum r502a_sys_param_set {
	R502A_BAUD_RATE = 4,
	R502A_SECURITY_LEVEL,
	R502A_DATA_PKG_LEN
};

struct r502a_sys_param {
	uint16_t status_reg;
	uint16_t system_id;
	uint16_t lib_size;
	uint16_t sec_level;
	uint32_t addr;
	uint16_t data_pkt_size;
	uint32_t baud;
} __packed;

enum sensor_channel_grow_r502a {
	/** Fingerprint template count, ID number for enrolling and searching*/
	SENSOR_CHAN_FINGERPRINT = SENSOR_CHAN_PRIV_START,
@@ -78,8 +115,19 @@ enum sensor_attribute_grow_r502a {
	 *	val->val2	matching score.
	 */
	SENSOR_ATTR_R502A_COMPARE,
	/** To read and write device's system parameters */
	/** sensor_attr_set
	 * @param val->val1 parameter number from enum r502a_sys_param_set.
	 * @param val->val2 content to be written for the respective parameter.
	 */
	/** sensor_attr_get
	 * @result val->ex.data buffer holds the system parameter values.
	 */
	SENSOR_ATTR_R502A_SYS_PARAM,
};

int r502a_read_sys_param(const struct device *dev, struct r502a_sys_param *val);

#ifdef __cplusplus
}
#endif
+3 −0
Changes for samples/sensor/grow_r502a/prj.conf: 3 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -4,3 +4,6 @@ CONFIG_UART_INTERRUPT_DRIVEN=y
CONFIG_SENSOR=y
CONFIG_LED=y
CONFIG_GROW_R502A_TRIGGER_OWN_THREAD=y

# Minimum stack size needed
CONFIG_GROW_R502A_THREAD_STACK_SIZE=1536
Loading