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

drivers: sensor: grow_r502a: move enroll, search, delete to application

Removed fps_enroll, fps_search and fps_delete from
driver code, since they did application usage inside
driver. add the following attributes to achieve the
above functionality from application.
1. SENSOR_ATTR_R502A_CAPTURE
2. SENSOR_ATTR_R502A_TEMPLATE_CREATE
3. SENSOR_ATTR_R502A_RECORD_ADD
4. SENSOR_ATTR_R502A_RECORD_LOAD
5. SENSOR_ATTR_R502A_COMPARE

Signed-off-by: default avatarDinesh Kumar K <dinesh@linumiz.com>
parent 378034c6
Loading
Loading
Loading
Loading
+112 −63
Changes for drivers/sensor/grow_r502a/grow_r502a.c: 112 added lines, 63 removed lines.
Original line number Diff line number Diff line
@@ -335,8 +335,10 @@ static int fps_create_model(const struct device *dev)

static int fps_store_model(const struct device *dev, uint16_t id)
{
	struct grow_r502a_data *drv_data = dev->data;
	union r502a_packet rx_packet = {0};
	char const store_model_len = 4;
	int ret = 0;

	struct led_params led_ctrl = {
		.ctrl_code = LED_CTRL_BREATHING,
@@ -351,11 +353,14 @@ static int fps_store_model(const struct device *dev, uint16_t id)
	};
	sys_put_be16(id, &tx_packet.data[2]);

	k_mutex_lock(&drv_data->lock, K_FOREVER);

	transceive_packet(dev, &tx_packet, &rx_packet, store_model_len);

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

	if (rx_packet.buf[R502A_CC_IDX] == R502A_OK) {
@@ -366,16 +371,19 @@ static int fps_store_model(const struct device *dev, uint16_t id)
		LOG_INF("Fingerprint stored! at ID #%d", id);
	} else {
		LOG_ERR("Error storing model 0x%X", rx_packet.buf[R502A_CC_IDX]);
		return -EIO;
		ret = -EIO;
	}

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

static int fps_delete_model(const struct device *dev, uint16_t id, uint16_t count)
{
	struct grow_r502a_data *drv_data = dev->data;
	union r502a_packet rx_packet = {0};
	char const delete_model_len = 5;
	int ret = 0;

	union r502a_packet tx_packet = {
		.pid = R502A_COMMAND_PACKET,
@@ -384,21 +392,25 @@ static int fps_delete_model(const struct device *dev, uint16_t id, uint16_t coun
	sys_put_be16(id, &tx_packet.data[1]);
	sys_put_be16(count + R502A_DELETE_COUNT_OFFSET, &tx_packet.data[3]);

	k_mutex_lock(&drv_data->lock, K_FOREVER);

	transceive_packet(dev, &tx_packet, &rx_packet, delete_model_len);

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

	if (rx_packet.buf[R502A_CC_IDX] == R502A_OK) {
		LOG_INF("Fingerprint Deleted from ID #%d to #%d", id, (id + count));
	} else {
		LOG_ERR("Error deleting image 0x%X", rx_packet.buf[R502A_CC_IDX]);
		return -EIO;
		ret = -EIO;
	}

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

static int fps_empty_db(const struct device *dev)
@@ -429,7 +441,6 @@ static int fps_empty_db(const struct device *dev)
		LOG_ERR("Error emptying fingerprint library 0x%X",
					rx_packet.buf[R502A_CC_IDX]);
		ret = -EIO;
		goto unlock;
	}

unlock:
@@ -437,11 +448,12 @@ unlock:
	return ret;
}

static int fps_search(const struct device *dev, uint8_t char_buf_idx)
static int fps_search(const struct device *dev, struct sensor_value *val)
{
	struct grow_r502a_data *drv_data = dev->data;
	union r502a_packet rx_packet = {0};
	char const search_len = 6;
	int ret = 0;

	struct led_params led_ctrl = {
		.ctrl_code = LED_CTRL_BREATHING,
@@ -452,16 +464,19 @@ static int fps_search(const struct device *dev, uint8_t char_buf_idx)

	union r502a_packet tx_packet = {
		.pid = R502A_COMMAND_PACKET,
		.data = {R502A_SEARCH, char_buf_idx}
		.data = {R502A_SEARCH, R502A_CHAR_BUF_1}
	};
	sys_put_be16(R02A_LIBRARY_START_IDX, &tx_packet.data[2]);
	sys_put_be16(R502A_DEFAULT_CAPACITY, &tx_packet.data[4]);

	k_mutex_lock(&drv_data->lock, K_FOREVER);

	transceive_packet(dev, &tx_packet, &rx_packet, search_len);

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

	if (rx_packet.buf[R502A_CC_IDX] == R502A_OK) {
@@ -469,94 +484,119 @@ static int fps_search(const struct device *dev, uint8_t char_buf_idx)
		led_ctrl.color_idx = LED_COLOR_PURPLE;
		led_ctrl.cycle = 0x01;
		fps_led_control(dev, &led_ctrl);
		drv_data->finger_id = sys_get_be16(&rx_packet.data[1]);
		drv_data->matching_score = sys_get_be16(&rx_packet.data[3]);
		LOG_INF("Found a matching print! at ID #%d", drv_data->finger_id);
	} else if (rx_packet.buf[R502A_CC_IDX] == R502A_NOT_FOUND) {
		val->val1 = sys_get_be16(&rx_packet.data[1]);
		val->val2 = sys_get_be16(&rx_packet.data[3]);
		LOG_INF("Found a matching print! at ID #%d", val->val1);
	} else if (rx_packet.buf[R502A_CC_IDX] == R502A_NOT_FOUND_CC) {
		led_ctrl.ctrl_code = LED_CTRL_BREATHING;
		led_ctrl.color_idx = LED_COLOR_RED;
		led_ctrl.cycle = 0x02;
		fps_led_control(dev, &led_ctrl);
		LOG_ERR("Did not find a match");
		return -ENOENT;
		ret = -ENOENT;
	} else {
		led_ctrl.ctrl_code = LED_CTRL_ON_ALWAYS;
		led_ctrl.color_idx = LED_COLOR_RED;
		fps_led_control(dev, &led_ctrl);
		LOG_ERR("Error searching for image 0x%X", rx_packet.buf[R502A_CC_IDX]);
		return -EIO;
		ret = -EIO;
	}

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

static int fps_enroll(const struct device *dev, const struct sensor_value *val)
static int fps_load_template(const struct device *dev, uint16_t id)
{
	struct grow_r502a_data *drv_data = dev->data;
	int ret = -1;
	union r502a_packet rx_packet = {0};
	char const load_tmp_len = 4;
	int ret = 0;

	if (val->val1 < 0 || val->val1 > R502A_DEFAULT_CAPACITY) {
		LOG_ERR("Invalid ID number");
		return -EINVAL;
	}
	union r502a_packet tx_packet = {
		.pid = R502A_COMMAND_PACKET,
		.data = {R502A_LOAD, R502A_CHAR_BUF_1}
	};
	sys_put_be16(id, &tx_packet.data[2]);

	k_mutex_lock(&drv_data->lock, K_FOREVER);

	ret = fps_get_image(dev);
	if (ret != 0) {
		goto unlock;
	}

	ret = fps_image_to_char(dev, R502A_CHAR_BUF_1);
	if (ret != 0) {
		goto unlock;
	}

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

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

	ret = fps_create_model(dev);
	if (ret != 0) {
		goto unlock;
	if (rx_packet.buf[R502A_CC_IDX] == R502A_OK) {
		LOG_DBG("Load template data from id #%d to Char_buffer2", id);
	} else {
		LOG_ERR("Error Loading template 0x%X",
					rx_packet.buf[R502A_CC_IDX]);
		ret = -EIO;
	}

	ret = fps_store_model(dev, val->val1);

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

static int fps_delete(const struct device *dev, const struct sensor_value *val)
static int fps_match_templates(const struct device *dev, struct sensor_value *val)
{
	struct grow_r502a_data *drv_data = dev->data;
	int ret = -1;
	union r502a_packet rx_packet = {0};
	char const match_templates_len = 1;
	int ret = 0;

	struct led_params led_ctrl = {
		.ctrl_code = LED_CTRL_BREATHING,
		.color_idx = LED_COLOR_BLUE,
		.speed = LED_SPEED_HALF,
		.cycle = 0x01,
	};

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

	k_mutex_lock(&drv_data->lock, K_FOREVER);

	ret = fps_delete_model(dev, val->val1, val->val2);
	if (ret != 0) {
	transceive_packet(dev, &tx_packet, &rx_packet, match_templates_len);

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

	ret = fps_get_template_count(dev);

	if (rx_packet.buf[R502A_CC_IDX] == R502A_OK) {
		fps_led_control(dev, &led_ctrl);
		val->val1 = R502A_FINGER_MATCH_FOUND;
		val->val2 = sys_get_be16(&rx_packet.data[1]);
		LOG_INF("Fingerprint matched with a score %d", val->val2);
	} else if (rx_packet.buf[R502A_CC_IDX] == R502A_NOT_MATCH_CC) {
		val->val1 = R502A_FINGER_MATCH_NOT_FOUND;
		LOG_ERR("Fingerprint not matched");
		ret = -ENOENT;
	} else {
		led_ctrl.ctrl_code = LED_CTRL_ON_ALWAYS;
		led_ctrl.color_idx = LED_COLOR_RED;
		fps_led_control(dev, &led_ctrl);
		LOG_ERR("Error Matching templates 0x%X",
					rx_packet.buf[R502A_CC_IDX]);
		ret = -EIO;
	}
unlock:
	k_mutex_unlock(&drv_data->lock);
	return ret;
}

static int fps_match(const struct device *dev, struct sensor_value *val)
static int fps_capture(const struct device *dev)
{
	struct grow_r502a_data *drv_data = dev->data;
	int ret = -1;
	int ret;

	k_mutex_lock(&drv_data->lock, K_FOREVER);

@@ -570,12 +610,13 @@ static int fps_match(const struct device *dev, struct sensor_value *val)
		goto unlock;
	}

	ret = fps_search(dev, R502A_CHAR_BUF_1);
	if (ret == 0) {
		val->val1 = drv_data->finger_id;
		val->val2 = drv_data->matching_score;
	ret = fps_get_image(dev);
	if (ret != 0) {
		goto unlock;
	}

	ret = fps_image_to_char(dev, R502A_CHAR_BUF_2);

unlock:
	k_mutex_unlock(&drv_data->lock);
	return ret;
@@ -643,12 +684,18 @@ static int grow_r502a_attr_set(const struct device *dev, enum sensor_channel cha
	}

	switch ((enum sensor_attribute_grow_r502a)attr) {
	case SENSOR_ATTR_R502A_CAPTURE:
		return fps_capture(dev);
	case SENSOR_ATTR_R502A_TEMPLATE_CREATE:
		return fps_create_model(dev);
	case SENSOR_ATTR_R502A_RECORD_ADD:
		return fps_enroll(dev, val);
		return fps_store_model(dev, val->val1);
	case SENSOR_ATTR_R502A_RECORD_DEL:
		return fps_delete(dev, val);
		return fps_delete_model(dev, val->val1, val->val2);
	case SENSOR_ATTR_R502A_RECORD_EMPTY:
		return fps_empty_db(dev);
	case SENSOR_ATTR_R502A_RECORD_LOAD:
		return fps_load_template(dev, val->val1);
	default:
		LOG_ERR("Sensor attribute not supported");
		return -ENOTSUP;
@@ -660,7 +707,6 @@ static int grow_r502a_attr_get(const struct device *dev, enum sensor_channel cha
			       enum sensor_attribute attr, struct sensor_value *val)
{
	int ret;
	struct grow_r502a_data *drv_data = dev->data;

	if ((enum sensor_channel_grow_r502a)chan != SENSOR_CHAN_FINGERPRINT) {
		LOG_ERR("Channel not supported");
@@ -669,11 +715,14 @@ static int grow_r502a_attr_get(const struct device *dev, enum sensor_channel cha

	switch ((enum sensor_attribute_grow_r502a)attr) {
	case SENSOR_ATTR_R502A_RECORD_FIND:
		ret = fps_match(dev, val);
		ret = fps_search(dev, val);
		break;
	case SENSOR_ATTR_R502A_RECORD_FREE_IDX:
		ret = fps_read_template_table(dev, &val->val1);
		break;
	case SENSOR_ATTR_R502A_COMPARE:
		ret = fps_match_templates(dev, val);
		break;
	default:
		LOG_ERR("Sensor attribute not supported");
		ret = -ENOTSUP;
+5 −3
Changes for drivers/sensor/grow_r502a/grow_r502a.h: 5 added lines, 3 removed lines.
Original line number Diff line number Diff line
@@ -61,7 +61,6 @@
 */

#define R502A_OK 0x00 /*commad execution complete*/
#define R502A_NOT_FOUND 0x09 /*fail to find the matching finger*/

/*Package Identifier's definition*/
#define R502A_COMMAND_PACKET 0x1 /*Command packet*/
@@ -95,6 +94,11 @@
#define R502A_HANDSHAKE 0x40 /*Handshake*/
#define R502A_BADPACKET 0xFE /* Bad packet was sent*/

#define R502A_NOT_MATCH_CC 0x08 /* templates of two buffers not matching*/
#define R502A_NOT_FOUND_CC 0x09 /*fail to find the matching finger*/
#define R502A_FINGER_MATCH_NOT_FOUND 0
#define R502A_FINGER_MATCH_FOUND 1

#define R502A_STARTCODE 0xEF01 /*Fixed value, High byte transferred first*/
#define R502A_DEFAULT_PASSWORD 0x00000000
#define R502A_DEFAULT_ADDRESS 0xFFFFFFFF
@@ -187,8 +191,6 @@ struct grow_r502a_data {
	struct k_mutex lock;
	struct k_sem uart_rx_sem;

	uint16_t finger_id;
	uint16_t matching_score;
	uint16_t template_count;
};

+39 −2
Changes for include/zephyr/drivers/sensor/grow_r502a.h: 39 added lines, 2 removed lines.
Original line number Diff line number Diff line
@@ -24,16 +24,53 @@ enum sensor_trigger_type_grow_r502a {
};

enum sensor_attribute_grow_r502a {
	/** Add values to the sensor which are having record storage facility */
	SENSOR_ATTR_R502A_RECORD_ADD = SENSOR_ATTR_PRIV_START,
	/** To capture finger and store as feature file in
	 * RAM buffers char_buf_1 and char_buf_2.
	 */
	SENSOR_ATTR_R502A_CAPTURE = SENSOR_ATTR_PRIV_START,
	/** create template from feature files at RAM buffers
	 * char_buf_1 & char_buf_2 and store a template data
	 * back in both RAM buffers char_buf_1 and char_buf_2.
	 */
	SENSOR_ATTR_R502A_TEMPLATE_CREATE,
	/** Add template to the sensor record storage */
	/**
	 * @param val->val1	record index for template to be
	 *			stored in the sensor device's flash
	 *			library.
	 */
	SENSOR_ATTR_R502A_RECORD_ADD,
	/** To find requested data in record storage */
	/**
	 * @result val->val1	matched record index.
	 *	   val->val2	matching score.
	 */
	SENSOR_ATTR_R502A_RECORD_FIND,
	/** To delete mentioned data from record storage */
	/**
	 * @param val->val1	record start index to be deleted.
	 * @param val->val2	number of records to be deleted.
	 */
	SENSOR_ATTR_R502A_RECORD_DEL,
	/** To get available position to store data on record storage */
	SENSOR_ATTR_R502A_RECORD_FREE_IDX,
	/** To empty the storage record*/
	SENSOR_ATTR_R502A_RECORD_EMPTY,
	/** To load template from storage to RAM buffer of sensor*/
	/**
	 * @param val->val1	record start index to be loaded in
	 *			device internal RAM buffer.
	 */
	SENSOR_ATTR_R502A_RECORD_LOAD,
	/** To template data stored in sensor's RAM buffer*/
	/**
	 * @result
	 *	val->val1	match result.
	 *			[R502A_FINGER_MATCH_FOUND or
	 *			R502A_FINGER_MATCH_NOT_FOUND]
	 *	val->val2	matching score.
	 */
	SENSOR_ATTR_R502A_COMPARE,
};

#ifdef __cplusplus
+36 −16
Changes for samples/sensor/grow_r502a/src/main.c: 36 added lines, 16 removed lines.
Original line number Diff line number Diff line
@@ -11,32 +11,54 @@
#include <zephyr/drivers/sensor/grow_r502a.h>

static bool enroll;
static struct sensor_value fid, val;
static struct sensor_value fid_get, count, find, del;

static void finger_match(const struct device *dev)
static void finger_find(const struct device *dev)
{
	struct sensor_value input;
	int ret;

	ret = sensor_attr_set(dev, SENSOR_CHAN_FINGERPRINT,
			SENSOR_ATTR_R502A_CAPTURE, NULL);
	if (ret != 0) {
		printk("Capture fingerprint failed %d\n", ret);
		return;
	}

	ret = sensor_attr_get(dev, SENSOR_CHAN_FINGERPRINT,
		SENSOR_ATTR_R502A_RECORD_FIND, &input);
		SENSOR_ATTR_R502A_RECORD_FIND, &find);
	if (ret != 0) {
		printk("Sensor attr get failed %d\n", ret);
		printk("Find fingerprint failed %d\n", ret);
		return;
	}
	printk("Matched ID : %d\n", input.val1);
	printk("confidence : %d\n", input.val2);
	printk("Matched ID : %d\n", find.val1);
	printk("confidence : %d\n", find.val2);
}

static void finger_enroll(const struct device *dev)
{
	int ret;

	ret = sensor_attr_set(dev, SENSOR_CHAN_FINGERPRINT, SENSOR_ATTR_R502A_RECORD_ADD, &fid);
	ret = sensor_attr_set(dev, SENSOR_CHAN_FINGERPRINT,
			SENSOR_ATTR_R502A_CAPTURE, NULL);
	if (ret != 0) {
		printk("Capture fingerprint failed %d\n", ret);
		return;
	}

	ret = sensor_attr_set(dev, SENSOR_CHAN_FINGERPRINT,
			SENSOR_ATTR_R502A_TEMPLATE_CREATE, NULL);
	if (ret != 0) {
		printk("Create template failed %d\n", ret);
		return;
	}

	if (ret == 0) {
		printk("Fingerprint successfully stored at #%d\n", fid.val1);
	ret = sensor_attr_set(dev, SENSOR_CHAN_FINGERPRINT,
			SENSOR_ATTR_R502A_RECORD_ADD, &fid_get);
	if (!ret) {
		printk("Fingerprint successfully stored at #%d\n", fid_get.val1);
		enroll = false;
	} else {
		printk("Fingerprint store failed %d\n", ret);
	}
}

@@ -49,12 +71,12 @@ static void template_count_get(const struct device *dev)
		printk("Sample Fetch Error %d\n", ret);
		return;
	}
	ret = sensor_channel_get(dev, SENSOR_CHAN_FINGERPRINT, &val);
	ret = sensor_channel_get(dev, SENSOR_CHAN_FINGERPRINT, &count);
	if (ret < 0) {
		printk("Channel Get Error %d\n", ret);
		return;
	}
	printk("template count : %d\n", val.val1);
	printk("template count : %d\n", count.val1);
}

static void trigger_handler(const struct device *dev,
@@ -64,13 +86,12 @@ static void trigger_handler(const struct device *dev,
		finger_enroll(dev);
	} else {
		template_count_get(dev);
		finger_match(dev);
		finger_find(dev);
	}
}

int main(void)
{
	static struct sensor_value del, fid_get;
	int ret;

	const struct device *dev =  DEVICE_DT_GET_ONE(hzgrow_r502a);
@@ -103,9 +124,8 @@ int main(void)
	}
	printk("Fingerprint template free idx at ID #%d\n", fid_get.val1);

	fid.val1 = fid_get.val1;
	printk("Waiting for valid finger to enroll as ID #%d\n"
		"Place your finger\n", fid.val1);
		"Place your finger\n", fid_get.val1);
	enroll = true;

	if (IS_ENABLED(CONFIG_GROW_R502A_TRIGGER)) {