From 00bb0d53d0f13960d82bae27a79f30213da3b0d9 Mon Sep 17 00:00:00 2001 From: Andrey Perminov Date: Tue, 5 May 2020 13:10:01 -0700 Subject: [PATCH] Moved all BM-Lite commands to bmlite_if Updated all BM-Lite commands for hcp_tyny.c compatibility Added callbacks for compatibility with embedded systems Change-Id: I473e3566576da4c6991bffa438fc0dae5a381b4a --- BMLite_example/Makefile | 3 + BMLite_example/inc/bep_host_if.h | 178 ---------- BMLite_example/inc/bmlite_if.h | 347 ++++++++++++++++++++ BMLite_example/inc/bmlite_if_callbacks.h | 92 ++++++ BMLite_example/inc/hcp_tiny.h | 40 +-- BMLite_example/inc/platform.h | 10 + BMLite_example/src/bep_host_if.c | 400 ----------------------- BMLite_example/src/bmlite_if.c | 307 +++++++++++++++++ BMLite_example/src/hcp_tiny.c | 242 +++++++------- BMLite_example/src/main.c | 152 +++++++-- BMLite_example/src/platform_linux.c | 6 + 11 files changed, 1033 insertions(+), 744 deletions(-) delete mode 100644 BMLite_example/inc/bep_host_if.h create mode 100644 BMLite_example/inc/bmlite_if.h create mode 100644 BMLite_example/inc/bmlite_if_callbacks.h delete mode 100644 BMLite_example/src/bep_host_if.c create mode 100644 BMLite_example/src/bmlite_if.c diff --git a/BMLite_example/Makefile b/BMLite_example/Makefile index 9e5b93e..0771bf3 100644 --- a/BMLite_example/Makefile +++ b/BMLite_example/Makefile @@ -45,6 +45,9 @@ CFLAGS +=\ -MP\ -Wno-unused-result +CFLAGS +=\ + -DBMLITE_USE_CALLBACK + # C source files C_SRCS = $(wildcard src/*.c) diff --git a/BMLite_example/inc/bep_host_if.h b/BMLite_example/inc/bep_host_if.h deleted file mode 100644 index c71c4d5..0000000 --- a/BMLite_example/inc/bep_host_if.h +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Copyright (c) 2020 Fingerprint Cards AB - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef BEP_HOST_IF_H -#define BEP_HOST_IF_H - -/** - * @file bep_host_if.h - * @brief BEP Host Interface API - */ - -#include -#include -#include "fpc_bep_types.h" -// #include "fpc_com_chain.h" - -#include "hcp_tiny.h" - -#define REMOVE_ID_ALL_TEMPLATES 0U - -/** - * @brief Sends HCP commands for capturing an image in Bio MCU - * - * @param[in] chain HCP com chain - * @param[in] timeout Timeout in ms - * @return ::fpc_bep_result_t - */ -fpc_bep_result_t bep_capture(HCP_comm_t *chain, uint16_t timeout); - -/** - * @brief Sends HCP commands for enrolling a finger in Bio MCU - * - * @param[in] chain HCP com chain - * @return ::fpc_bep_result_t - */ -fpc_bep_result_t bep_enroll_finger(HCP_comm_t *chain); - -/** - * @brief Sends HCP commands for identifying a finger in Bio MCU - * - * @param[in] chain HCP com chain - * @param[out] template_id Template id that was identified (only valid if match is true) - * @param[out] match True if match - * @return ::fpc_bep_result_t - */ -fpc_bep_result_t bep_identify_finger(HCP_comm_t *chain, uint32_t timeout, uint16_t *template_id, bool *match); - - -/** - * @brief Sends HCP commands for saving template of an enrolled finger in Bio MCU - * - * @param[in] chain HCP com chain - * @param[in] template_id Template id to save - * @return ::fpc_bep_result_t - */ -fpc_bep_result_t bep_save_template(HCP_comm_t *chain, uint16_t template_id); - -/** - * @brief Remove template(s) stored - * - * @param[in] chain HCP com chain - * @param[in] template_id template id to remove, if =REMOVE_ID_ALL_TEMPLATES removes all templates - * @return ::fpc_bep_result_t - */ -fpc_bep_result_t bep_delete_template(HCP_comm_t *chain, uint16_t template_id); - -/** - * @brief Gets all template ids from Bio MCU - * - * @param[in] chain HCP com chain - * @param[out] template_ids Should be allocated by the caller for storing template ids and should - * have capacity to hold bio_get_template_count - * @param[in] nof_templates This should be acquired using bio_get_template_count - * @return ::fpc_bep_result_t - */ -fpc_bep_result_t bep_get_template_ids(HCP_comm_t *chain, uint16_t *template_ids, - uint32_t nof_templates); - -/** - * @brief Get the number of templates in Bio MCU - * - * @param[in] chain HCP com chain - * @param[out] template_count - * @return ::fpc_bep_result_t - */ -fpc_bep_result_t bep_get_template_count(HCP_comm_t *chain, uint32_t *template_count); - - -/** - * @brief Sends HCP commands for extracting a template from a previously capture image in Bio MCU - * - * @param[in] chain HCP com chain - * @return ::fpc_bep_result_t - */ -fpc_bep_result_t bep_image_extract(HCP_comm_t *chain); - -/** - * @brief Sends HCP commands for getting the image size of a previously capture image in Bio MCU - * - * @param[in] chain HCP com chain - * @return ::fpc_bep_result_t - */ -fpc_bep_result_t bep_image_get_size(HCP_comm_t *chain, uint32_t *size); - -/** - * @brief Sends HCP commands for getting the image data of a previously capture image in Bio MCU - * - * @param[in] chain HCP com chain - * @return ::fpc_bep_result_t - */ -fpc_bep_result_t bep_image_get(HCP_comm_t *chain, uint8_t *data, uint32_t size); - -/** - * @brief Sends HCP commands for fetching the version of the Bio MCU FW - * - * @param[in] chain HCP com chain - * @param[out] version Version string buffer - * @param[out] len Length of version string buffer - * @return ::fpc_bep_result_t - */ -fpc_bep_result_t bep_version(HCP_comm_t *chain, char *version, int len); - -/** - * @brief Sends HCP commands for resetting the Bio MCU - * - * @param[in] chain HCP com chain - * @return ::fpc_bep_result_t - */ -fpc_bep_result_t bep_reset(HCP_comm_t *chain); - -/** - * @brief Sends HCP commands for calibrating the sensor in the Bio MCU - * - * @param[in] chain HCP com chain - * @return ::fpc_bep_result_t - */ -fpc_bep_result_t bep_sensor_calibrate(HCP_comm_t *chain); - -/** - * @brief Sends HCP commands for removing the sensor calibration in the Bio MCU - * - * @param[in] chain HCP com chain - * @return ::fpc_bep_result_t - */ -fpc_bep_result_t bep_sensor_calibrate_remove(HCP_comm_t *chain); - -/** - * @brief Sends HCP commands for setting the sensor in sleep and waiting for finger in the Bio MCU - * - * @param[in] chain HCP com chain - * @param[in] timeout Timeout in ms - * @return ::fpc_bep_result_t - */ -fpc_bep_result_t bep_sensor_wait_for_finger(HCP_comm_t *chain, uint16_t timeout); - -/** - * @brief Sends HCP commands that returns when finger is not on the sensor in the Bio MCU - * - * @param[in] chain HCP com chain - * @param[in] timeout Timeout in ms - * @return ::fpc_bep_result_t - */ -fpc_bep_result_t bep_sensor_wait_finger_not_present(HCP_comm_t *chain, uint16_t timeout); - -#endif /* BEP_HOST_IF_H */ diff --git a/BMLite_example/inc/bmlite_if.h b/BMLite_example/inc/bmlite_if.h new file mode 100644 index 0000000..d5ebef3 --- /dev/null +++ b/BMLite_example/inc/bmlite_if.h @@ -0,0 +1,347 @@ +#ifndef BMLITE_IF_H +#define BMLITE_IF_H + +#include "hcp_tiny.h" +#include "bmlite_if_callbacks.h" + +/** + * @brief Build and send command to FPC BM-Lite and receive answer + * + * @param[in] chain - HCP com chain + * @param[in] cmd - BM-Lite command + * @param[in] arg_type - Argument without parameters + * set to ARG_NONE if the command has no argument + * + * @return ::fpc_bep_result_t + */ +fpc_bep_result_t bmlite_send_cmd(HCP_comm_t *chain, uint16_t cmd, uint16_t arg_type); + +/** + * @brief Build and send command with additiona argument with parameters + * + * @param[in] chain - HCP com chain + * @param[in] cmd - BM-Lite command + * @param[in] arg1_type - argument 1 without parameters + * set to ARG_NONE if the command has no argument without paramener + * @param[in] arg2_type - argument 2 + * @param[in] arg2_data - data pointer for argument 2 + * set to 0 if argument 2 has no parameter + * @param[in] arg2_length - length of data for argument 2 + * set to 0 if argument 2 has no parameter + * + * @return ::fpc_bep_result_t + */ +fpc_bep_result_t bmlite_send_cmd_arg(HCP_comm_t *chain, uint16_t cmd, uint16_t arg1_type, uint16_t arg2_type, void *arg2_data, uint16_t arg2_length); + +/** + * @brief Wait for finger present on sensor" + * + * @param[in] chain - HCP com chain + * @param[in] timeout - timeout (msec). Maximum timeout 65535 msec + * set to 0 for waiting indefinitely + * + * @return ::fpc_bep_result_t + */ +fpc_bep_result_t sensor_wait_finger_present(HCP_comm_t *chain, uint16_t timeout); + +/** + * @brief Wait for finger not present on sensor" + * + * @param[in] chain - HCP com chain + * @param[in] timeout - timeout (msec). Maximum timeout 65535 msec + * set to 0 for waiting indefinitely + * + * @return ::fpc_bep_result_t + */ +fpc_bep_result_t sensor_wait_finger_not_present(HCP_comm_t *chain, uint16_t timeout); + +/** + * @brief Wait for finger present on sensor and capture image" + * + * @param[in] chain - HCP com chain + * @param[in] timeout - timeout (msec). Maximum timeout 65535 msec + * set to 0 for waiting indefinitely + * + * @return ::fpc_bep_result_t + */ +fpc_bep_result_t bep_capture(HCP_comm_t *chain, uint16_t timeout); + +/** + * @brief Get size of captured image + * + * @param[in] chain - HCP com chain + * + * @param[out] size + * + * @return ::fpc_bep_result_t + */ +fpc_bep_result_t bep_image_get_size(HCP_comm_t *chain, uint32_t *size); + +/** + * @brief Allocates image buffer on FPC BM-LIte + * + * @param[in] chain - HCP com chain + * + * @return ::fpc_bep_result_t + */ +fpc_bep_result_t image_create(HCP_comm_t *chain); + +/** + * @brief Deletes image buffer on FPC BM-LIte + * + * @param[in] chain - HCP com chain + * + * @return ::fpc_bep_result_t + */ +fpc_bep_result_t image_delete(HCP_comm_t *chain); + +/** + * @brief Pull captured image from FPC BM-Lite + * + * @param[in] chain - HCP com chain + * + * @param[in] data - pointer to image buffer + * @param[in] size - size of the image buffer + * if buffer size is not enough the image + * will be truncated + * chain->arg.size will contain real size of the image + * + * @return ::fpc_bep_result_t + */ +fpc_bep_result_t bep_image_get(HCP_comm_t *chain, uint8_t *data, uint32_t size); + +/** + * @brief Push image to FPC BM-Lite + * + * @param[in] chain - HCP com chain + * + * @param[in] data - pointer to image buffer + * @param[in] size - size of the image buffer + * + * @return ::fpc_bep_result_t + */ +fpc_bep_result_t bep_image_put(HCP_comm_t *chain, uint8_t *data, uint32_t size); + +/** + * @brief Extract image features to prepare image for enrolling or matching + * + * @param[in] chain - HCP com chain + * + * @return ::fpc_bep_result_t + */ +fpc_bep_result_t bep_image_extract(HCP_comm_t *chain); + +/** + * @brief Identify prepared image against existing templates in Flash storage + * + * @param[in] chain - HCP com chain + * + * @return ::fpc_bep_result_t + */ +fpc_bep_result_t bep_identify(HCP_comm_t *chain); + +/** + * @brief Enroll finger. Created template must be saved to FLASH storage + * + * @param[in] chain - HCP com chain + * + * @return ::fpc_bep_result_t + */ +fpc_bep_result_t bep_enroll_finger(HCP_comm_t *chain); + +/** + * @brief Capture and identify finger against existing templates in Flash storage + * + * @param[in] chain - HCP com chain + * @param[in] timeout - timeout (msec). Maximum timeout 65535 msec + * set to 0 for waiting indefinitely + * + * @param[out] template_id - pointer for matched template ID + * @param[out] match - pointer to match result + * + * @return ::fpc_bep_result_t + */ +fpc_bep_result_t bep_identify_finger(HCP_comm_t *chain, uint32_t timeout, + uint16_t *template_id, bool *match); + +/** + * @brief Save template after enroll is finished to FLASH storage + * + * @param[in] chain - HCP com chain + * @param[out] template_id - template ID + * + * @return ::fpc_bep_result_t + */ +fpc_bep_result_t bep_template_save(HCP_comm_t *chain, uint16_t template_id); + +/** + * @brief Remove template from RAM + * + * @param[in] chain - HCP com chain + * @param[in] template_id - template ID + * + * @return ::fpc_bep_result_t + */ +fpc_bep_result_t bep_template_remove_ram(HCP_comm_t *chain); + +/** + * @brief Pull template stored in RAM from FPC BM-Lite + * + * @param[in] chain - HCP com chain + * + * @param[in] data - pointer to template buffer + * @param[in] size - size of the template buffer + * if buffer size is not enough the template + * will be truncated + * chain->arg.size will contain real size of the template + * + * @return ::fpc_bep_result_t + */ +fpc_bep_result_t bep_template_get(HCP_comm_t *chain, uint8_t *data, uint32_t size); + +/** + * @brief Push template to FPC BM-Lite and stored it to RAM + * + * @param[in] chain - HCP com chain + * + * @param[in] data - pointer to template buffer + * @param[in] size - size of the template buffer + * + * @return ::fpc_bep_result_t + */ +fpc_bep_result_t bep_template_put(HCP_comm_t *chain, uint8_t *data, uint16_t length); + +/** + * @brief Remove template from FLASH storage + * + * @param[in] chain - HCP com chain + * @param[in] template_id - template ID + * + * @return ::fpc_bep_result_t + */ +fpc_bep_result_t bep_template_remove(HCP_comm_t *chain, uint16_t template_id); + +/** + * @brief Remove all templates from FLASH storage + * + * @param[in] chain - HCP com chain + * + * @return ::fpc_bep_result_t + */ +fpc_bep_result_t bep_template_remove_all(HCP_comm_t *chain); + +/** + * @brief Copy template from FLASH storage to RAM + * + * @param[in] chain - HCP com chain + * @param[in] template_id - template ID + * + * @return ::fpc_bep_result_t + */ +fpc_bep_result_t bep_template_load_storage(HCP_comm_t *chain, uint16_t template_id); + +/** + * @brief Remove template from FLASH storage + * + * @param[in] chain - HCP com chain + * @param[out] template_id - template ID + * + * @return ::fpc_bep_result_t + */ +fpc_bep_result_t bep_template_get_count(HCP_comm_t *chain, uint16_t *count); + +/** + * @brief Get array of template ID stored on FPC BM-LIte + * + * @param[in] chain - HCP com chain + * @return ::fpc_bep_result_t + * chain->arg.data - pointer to array of uint16_t of IDs + * chain->arg.size - length of the array (in bytes). For calculating + * number of templates divide the arg.size by 2 + */ +fpc_bep_result_t bep_template_get_ids(HCP_comm_t *chain); + +/** + * @brief Software reset of FCP BM-Lite + * + * @return ::fpc_bep_result_t + */ +fpc_bep_result_t bep_sw_reset(HCP_comm_t *chain); + +/** + * @brief Calibrate FPC BM-LIte sensor and store calibration data to FLASH storage + * + * @param[in] chain - HCP com chain + * + * @return ::fpc_bep_result_t + * + * FPC BM-Lite must be restarted to activate new calibration data + */ +fpc_bep_result_t bep_sensor_calibrate(HCP_comm_t *chain); + +/** + * @brief Remove FPC BM-LIte sensor calibration data from FLASH storage + * + * @param[in] chain - HCP com chain + * + * @return ::fpc_bep_result_t + * + * FPC BM-Lite must be restarted to activate + */ +fpc_bep_result_t bep_sensor_calibrate_remove(HCP_comm_t *chain); + +/** + * @brief Get version of FPC BM-LIte firmware + * + * @param[in] chain - HCP com chain + * @param[in] version - pointer to data buffer + * @param[in] size - size of the data buffer + * if buffer size is not enough the data + * will be truncated + * chain->arg.size will contain real size of the data + * + * @return ::fpc_bep_result_t + */ +fpc_bep_result_t bep_version(HCP_comm_t *chain, char *version, int len); + +/** + * @brief Get version of FPC BM-LIte firmware + * + * @param[in] chain - HCP com chain + * @param[in] unique_id - pointer to data buffer + * chain->arg.size will contain real size of the data + * + * @return ::fpc_bep_result_t + */ +fpc_bep_result_t bep_unique_id_get(HCP_comm_t *chain, uint8_t *unique_id); + +/** + * @brief Set requested UART communication speed + * + * @param[in] chain - HCP com chain + * @param[in] speed - UART speed + * + * @return ::fpc_bep_result_t + */ +fpc_bep_result_t bep_uart_speed_set(HCP_comm_t *chain, uint32_t speed); + +/** + * @brief Get current UART communication speed + * + * @param[in] chain - HCP com chain + * @param[out] speed - UART speed + * + * @return ::fpc_bep_result_t + */ +fpc_bep_result_t bep_uart_speed_get(HCP_comm_t *chain, uint32_t *speed); + +/** + * @brief Reset FPC BM-Lite fingerprint sensor + * + * @param[in] chain - HCP com chain + * + * @return ::fpc_bep_result_t + */ +fpc_bep_result_t bep_sensor_reset(HCP_comm_t *chain); + +#endif \ No newline at end of file diff --git a/BMLite_example/inc/bmlite_if_callbacks.h b/BMLite_example/inc/bmlite_if_callbacks.h new file mode 100644 index 0000000..de22022 --- /dev/null +++ b/BMLite_example/inc/bmlite_if_callbacks.h @@ -0,0 +1,92 @@ +#ifndef BMLITE_IF_CALLBACKS_H +#define BMLITE_IF_CALLBACKS_H +#include + +#ifndef BMLITE_USE_CALLBACK + #define bmlite_on_error(error, value) + #define bmlite_on_start_capture() + #define bmlite_on_finish_capture() + #define bmlite_on_finish_enroll() + #define bmlite_on_start_enroll() + #define bmlite_on_start_enrollcapture() + #define bmlite_on_finish_enrollcapture() + #define bmlite_on_identify_start() + #define bmlite_on_identify_finish() + +#else + +typedef enum { + BMLITE_ERROR_OK = 0, + BMLITE_ERROR_CAPTURE, + BMLITE_ERROR_CAPTURE_START, + BMLITE_ERROR_ENROLL_START, + BMLITE_ERROR_ENROLL_ADD, + BMLITE_ERROR_ENROLL_FINISH, + BMLITE_ERROR_WRONG_ANSWER, + BMLITE_ERROR_FINGER_WAIT, + BMLITE_ERROR_IDENTYFY, + BMLITE_ERROR_TEMPLATE_SAVE, + BMLITE_ERROR_TEMPLATE_DELETE, + BMLITE_ERROR_TEMPLATE_COUNT, + BMLITE_ERROR_TEMPLATE_GETIDS, + BMLITE_ERROR_IMAGE_EXTRACT, + BMLITE_ERROR_IMAGE_GETSIZE, + BMLITE_ERROR_IMAGE_GET, + BMLITE_ERROR_GETVERSION, + BMLITE_ERROR_SW_RESET, + BMLITE_ERROR_CALIBRATE, + BMLITE_ERROR_CALIBRATE_DELETE, + BMLITE_ERROR_SEND_CMD, + BMLITE_ERROR_GET_ARG, +} bmlite_error_t; + +/** + * @brief Error Callback function + * + * @param[in] Callback Error Code + * @param[in] BEP result code + */ +void bmlite_on_error(bmlite_error_t error, int32_t value); + +/** + * @brief Starting Capture Callback function + */ +void bmlite_on_start_capture(); + +/** + * @brief Finishing Capture Callback function + */ +void bmlite_on_finish_capture(); + +/** + * @brief Starting Enroll Callback function + */ +void bmlite_on_start_enroll(); + +/** + * @brief Finishing Enroll Callback function + */ +void bmlite_on_finish_enroll(); + +/** + * @brief Starting Capture for Enroll Callback function + */ +void bmlite_on_start_enrollcapture(); + +/** + * @brief Finishing Capture for Enroll Callback function + */ +void bmlite_on_finish_enrollcapture(); + +/** + * @brief Starting Identify Callback function + */ +void bmlite_on_identify_start(); + +/** + * @brief Finishing Identify Callback function + */ +void bmlite_on_identify_finish(); +#endif // BMLITE_USE_CALLBACK + +#endif \ No newline at end of file diff --git a/BMLite_example/inc/hcp_tiny.h b/BMLite_example/inc/hcp_tiny.h index 4977f39..e19c673 100644 --- a/BMLite_example/inc/hcp_tiny.h +++ b/BMLite_example/inc/hcp_tiny.h @@ -10,6 +10,11 @@ /** Communication acknowledge definition */ #define FPC_BEP_ACK 0x7f01ff7f +typedef struct { + uint32_t size; + uint8_t *data; +} HCP_arg_t; + typedef struct { /** Send data to BM-Lite */ fpc_bep_result_t (*write) (uint16_t, const uint8_t *, uint32_t, void *); @@ -25,25 +30,13 @@ typedef struct { uint32_t pkt_size; /** Buffer of MTU size for transport layer */ uint8_t *txrx_buffer; + /** Values of last argument pulled by bmlite_get_arg + Values are valid only right after bmlite_get_arg() call */ + HCP_arg_t arg; + /** Result of execution command on BM-Lite */ + fpc_bep_result_t bep_result; } HCP_comm_t; -/** - * @brief Helper function for sending HCP commands - * - * @param chain HCP communication chain - * @param command_id command to send - * @param arg_key1 first key to add to the command - * @param arg_data1 first argument data to add - * @param arg_data1_length first data length of argument data - * @param arg_key2 second key to add to the command - * @param arg_data2 second argument data to add - * @param arg_data2_length second data length of argument data - * @return ::fpc_bep_result_t - */ -fpc_bep_result_t send_command_args2(HCP_comm_t *chain, fpc_hcp_cmd_t command_id, - fpc_hcp_arg_t arg_key1, void *arg_data1, uint16_t arg_data1_length, - fpc_hcp_arg_t arg_key2, void *arg_data2, uint16_t arg_data2_length); - /** * @brief Helper function for receiving HCP commands @@ -56,8 +49,15 @@ fpc_bep_result_t send_command_args2(HCP_comm_t *chain, fpc_hcp_cmd_t command_id, * @param arg_data2_length second argument * @return ::fpc_bep_result_t */ -fpc_bep_result_t receive_result_args2(HCP_comm_t *chain, - fpc_hcp_arg_t arg_key1, void *arg_data1, uint16_t arg_data1_length, - fpc_hcp_arg_t arg_key2, void *arg_data2, uint16_t arg_data2_length); +fpc_bep_result_t bmlite_receive(HCP_comm_t *hcp_comm); +fpc_bep_result_t bmlite_send(HCP_comm_t *hcp_comm); +fpc_bep_result_t bmlite_tranceive(HCP_comm_t *hcp_comm); + +fpc_bep_result_t bmlite_init_cmd(HCP_comm_t *hcp_comm, uint16_t cmd, uint16_t arg); +fpc_bep_result_t bmlite_add_arg(HCP_comm_t *hcp_comm, uint16_t arg, void *data, uint16_t size); +fpc_bep_result_t bmlite_get_arg(HCP_comm_t *hcp_comm, uint16_t arg_type); +fpc_bep_result_t bmlite_copy_arg(HCP_comm_t *hcp_comm, uint16_t arg_key, void *arg_data, uint16_t arg_data_length); + + #endif \ No newline at end of file diff --git a/BMLite_example/inc/platform.h b/BMLite_example/inc/platform.h index ff38a56..29a32ef 100644 --- a/BMLite_example/inc/platform.h +++ b/BMLite_example/inc/platform.h @@ -109,4 +109,14 @@ uint64_t platform_get_time(void); */ void platform_clear_screen(void); +/** + * @brief Busy wait. + * + * @param[in] ms Time to wait [ms]. + * 0 => return immediately + * 1 => wait at least 1ms etc. + */ +void hal_timebase_busy_wait(uint32_t ms); + + #endif /* PLATFORM_H */ diff --git a/BMLite_example/src/bep_host_if.c b/BMLite_example/src/bep_host_if.c deleted file mode 100644 index cccb324..0000000 --- a/BMLite_example/src/bep_host_if.c +++ /dev/null @@ -1,400 +0,0 @@ -/* - * Copyright (c) 2020 Fingerprint Cards AB - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @file bep_host_if.c - * @brief BEP Host Interface implementation. - */ - -#include -#include -#include - -#include "platform.h" -#include "fpc_hcp_common.h" -#include "bep_host_if.h" -#include "hcp_tiny.h" - -/** Returns the number of elements in an array. */ -#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) - -#define RECEIVE_TIMEOUT 10 - -#ifdef DEBUG -#define log_debug(format, ...) printf(format, ##__VA_ARGS__) -#else -#define log_debug(format, ...) -#endif -#define log_info(format, ...) printf(format, ##__VA_ARGS__) -#define log_error(format, ...) printf(format, ##__VA_ARGS__) - -/** Maximum attempts for capture image */ -static const uint8_t MAX_CAPTURE_ATTEMPTS = 15U; -static const uint16_t CAPTURE_TIMEOUT = 3000; - -static fpc_bep_result_t send_command_no_args(HCP_comm_t *chain, fpc_hcp_cmd_t command_id) -{ - return send_command_args2(chain, command_id, ARG_NONE, NULL, 0, ARG_NONE, NULL, 0); -} - -static fpc_bep_result_t send_command(HCP_comm_t *chain, fpc_hcp_cmd_t command_id, - fpc_hcp_arg_t arg_key, void *arg_data, uint16_t arg_data_length) -{ - return send_command_args2(chain, command_id, arg_key, arg_data, arg_data_length, - ARG_NONE, NULL, 0); -} - -static fpc_bep_result_t receive_result_no_args(HCP_comm_t *chain) -{ - return receive_result_args2(chain, ARG_NONE, NULL, 0, ARG_NONE, NULL, 0); -} - -static fpc_bep_result_t receive_result_args1(HCP_comm_t *chain, - fpc_hcp_arg_t arg_key, void *arg_data, uint16_t arg_data_length) -{ - return receive_result_args2(chain, arg_key, arg_data, arg_data_length, ARG_NONE, NULL, 0); -} - - -fpc_bep_result_t bep_capture(HCP_comm_t *chain, uint16_t timeout) -{ - fpc_bep_result_t bep_result; - - log_info("Put finger on sensor\n"); - - /* Capture finger down */ - bep_result = send_command(chain, CMD_CAPTURE, ARG_TIMEOUT, &timeout, sizeof(timeout)); - if (bep_result != FPC_BEP_RESULT_OK) { - log_error("%s:%u Error transmitting CMD_CAPTURE\n", __func__, __LINE__); - return bep_result; - } - - return receive_result_no_args(chain); -} - -fpc_bep_result_t bep_enroll_finger(HCP_comm_t *chain) -{ - uint32_t samples_remaining = 0; - fpc_bep_result_t bep_result = FPC_BEP_RESULT_OK; - bool enroll_done = false; - - /* Enroll start */ - bep_result = send_command(chain, CMD_ENROLL, ARG_START, NULL, 0); - if (bep_result != FPC_BEP_RESULT_OK) { - log_error("%s, ERROR line:%u\n", __func__, __LINE__); - goto exit; - } - - bep_result = receive_result_no_args(chain); - if (bep_result != FPC_BEP_RESULT_OK) { - log_error("%s:%u, ERROR receiving status=%d\n", __func__, __LINE__, bep_result); - goto exit; - } - - for (uint8_t i = 0; i < MAX_CAPTURE_ATTEMPTS; ++i) { - - bep_result = bep_capture(chain, CAPTURE_TIMEOUT); - if (bep_result != FPC_BEP_RESULT_OK) { - log_error("Capture failed\n"); - break; - } - - log_info("Capture done. Remove finger from sensor\n"); - - if (bep_result != FPC_BEP_RESULT_OK) { - log_error("%s:%u, ERROR receiving, result=%d\n", __func__, __LINE__, bep_result); - continue; - } - - /* Enroll add */ - bep_result = send_command(chain, CMD_ENROLL, ARG_ADD, NULL, 0); - if (bep_result != FPC_BEP_RESULT_OK) { - log_error("%s:%u, ERROR\n", __func__, __LINE__); - continue; - } - - bep_result = receive_result_args1(chain, ARG_COUNT, &samples_remaining, - sizeof(samples_remaining)); - if (bep_result != FPC_BEP_RESULT_OK) { - log_error("%s:%u, ERROR receiving status=%d\n", __func__, __LINE__, bep_result); - continue; - } - - log_info("Enroll samples remaining: %d\n", samples_remaining); - - if (samples_remaining == 0U) { - enroll_done = true; - break; - } - - bep_result = send_command(chain, CMD_WAIT, ARG_FINGER_UP, NULL, 0); - if (bep_result != FPC_BEP_RESULT_OK) { - log_error("%s:%u, ERROR\n", __func__, __LINE__); - continue; - } - - /* Wait for finger to be lifted from sensor */ - bep_result = receive_result_no_args(chain); - if (bep_result != FPC_BEP_RESULT_OK) { - log_error("%s:%u, ERROR receiving status=%d\n", __func__, __LINE__, bep_result); - continue; - } - } - - bep_result = send_command(chain, CMD_ENROLL, ARG_FINISH, NULL, 0); - if (bep_result == FPC_BEP_RESULT_OK) { - bep_result = receive_result_no_args(chain); - if (bep_result != FPC_BEP_RESULT_OK) { - log_error("%s:%u, ERROR receiving status=%d\n", __func__, __LINE__, bep_result); - } - } - -exit: - return (!enroll_done) ? FPC_BEP_RESULT_GENERAL_ERROR : bep_result; -} - -fpc_bep_result_t bep_identify_finger(HCP_comm_t *chain, uint32_t timeout, uint16_t *template_id, bool *match) -{ - fpc_bep_result_t bep_result = FPC_BEP_RESULT_OK; - - *match = false; - - uint32_t prev_timeout = chain->phy_rx_timeout; - chain->phy_rx_timeout = timeout; - bep_result = bep_capture(chain, timeout); - chain->phy_rx_timeout = prev_timeout; - if (bep_result != FPC_BEP_RESULT_OK) { - log_error("Capture failed result=%d\n", bep_result); - return bep_result; - } - - log_info("Capture done. Remove finger from sensor\n"); - - bep_result = bep_image_extract(chain); - if (bep_result != FPC_BEP_RESULT_OK) { - log_error("Extract failed\n"); - return bep_result; - } - - bep_result = send_command(chain, CMD_IDENTIFY, ARG_NONE, NULL, 0); - if (bep_result != FPC_BEP_RESULT_OK) { - log_error("Identify failed\n"); - return bep_result; - } - - bep_result = receive_result_args2(chain, ARG_MATCH, match, sizeof(bool), - ARG_ID, template_id, sizeof(uint16_t)); - if (bep_result != FPC_BEP_RESULT_OK) { - log_error("Identify failed\n"); - return bep_result; - } - - return bep_result; -} - -fpc_bep_result_t bep_save_template(HCP_comm_t *chain, uint16_t template_id) -{ - fpc_bep_result_t bep_result = FPC_BEP_RESULT_OK; - - bep_result = send_command_args2(chain, CMD_TEMPLATE, ARG_SAVE, NULL, 0, ARG_ID, &template_id, - sizeof(template_id)); - if (bep_result != FPC_BEP_RESULT_OK) { - log_error("%s:%u, ERROR\n", __func__, __LINE__); - return bep_result; - } - - return receive_result_no_args(chain); -} - -fpc_bep_result_t bep_delete_template(HCP_comm_t *chain, uint16_t template_id) -{ - fpc_bep_result_t bep_result = FPC_BEP_RESULT_OK; - - if (template_id == REMOVE_ID_ALL_TEMPLATES) { - bep_result = send_command_args2(chain, CMD_STORAGE_TEMPLATE, ARG_DELETE, NULL, 0, - ARG_ALL, NULL, 0); - } else { - bep_result = send_command_args2(chain, CMD_STORAGE_TEMPLATE, ARG_DELETE, NULL, 0, - ARG_ID, &template_id, sizeof(template_id)); - } - if (bep_result != FPC_BEP_RESULT_OK) { - log_error("%s:%u, ERROR\n", __func__, __LINE__); - return bep_result; - } - - return receive_result_no_args(chain); -} - -fpc_bep_result_t bep_get_template_count(HCP_comm_t *chain, uint32_t *template_count) -{ - fpc_bep_result_t bep_result = FPC_BEP_RESULT_OK; - - bep_result = send_command(chain, CMD_STORAGE_TEMPLATE, ARG_COUNT, NULL, 0); - if (bep_result != FPC_BEP_RESULT_OK) { - log_error("%s:%u ERROR sending CMD_STORAGE_TEMPLATE\n", __func__, __LINE__); - return bep_result; - } - - bep_result = receive_result_args1(chain, ARG_COUNT, template_count, sizeof(template_count[0])); - if (bep_result != FPC_BEP_RESULT_OK) { - log_error("%s:%u, ERROR receiving status=%d\n", __func__, __LINE__, bep_result); - return bep_result; - } - - return bep_result; -} - -fpc_bep_result_t bep_get_template_ids(HCP_comm_t *chain, uint16_t *template_ids, - uint32_t nof_templates) -{ - fpc_bep_result_t bep_result = FPC_BEP_RESULT_OK; - - bep_result = send_command(chain, CMD_STORAGE_TEMPLATE, ARG_ID, NULL, 0); - if (bep_result != FPC_BEP_RESULT_OK) { - log_error("%s:%u ERROR sending CMD_STORAGE_TEMPLATE\n", __func__, __LINE__); - return bep_result; - } - - bep_result = receive_result_args1(chain, ARG_DATA, template_ids, nof_templates * - sizeof(template_ids[0])); - if (bep_result != FPC_BEP_RESULT_OK) { - log_error("%s:%u, ERROR receiving status=%d\n", __func__, __LINE__, bep_result); - return bep_result; - } - - return bep_result; -} - -fpc_bep_result_t bep_image_extract(HCP_comm_t *chain) -{ - fpc_bep_result_t bep_result; - - bep_result = send_command(chain, CMD_IMAGE, ARG_EXTRACT, NULL, 0); - if (bep_result != FPC_BEP_RESULT_OK) { - log_error("Extract failed\n"); - return bep_result; - } - - return receive_result_no_args(chain); -} - -fpc_bep_result_t bep_image_get_size(HCP_comm_t *chain, uint32_t *size) -{ - fpc_bep_result_t bep_result; - - bep_result = send_command(chain, CMD_IMAGE, ARG_SIZE, NULL, 0); - if (bep_result != FPC_BEP_RESULT_OK) { - log_error("Extract failed\n"); - return bep_result; - } - - log_info("Downloading image data...\n"); - - return receive_result_args1(chain, ARG_SIZE, size, sizeof(size)); -} - -fpc_bep_result_t bep_image_get(HCP_comm_t *chain, uint8_t *data, uint32_t size) -{ - fpc_bep_result_t bep_result; - - bep_result = send_command(chain, CMD_IMAGE, ARG_UPLOAD, NULL, 0); - if (bep_result != FPC_BEP_RESULT_OK) { - log_error("Extract failed\n"); - return bep_result; - } - - return receive_result_args1(chain, ARG_DATA, data, size); -} - -fpc_bep_result_t bep_version(HCP_comm_t *chain, char *version, int len) -{ - fpc_bep_result_t bep_result; - - bep_result = send_command_args2(chain, CMD_INFO, ARG_GET, NULL, 0, ARG_VERSION, NULL, 0); - if (bep_result != FPC_BEP_RESULT_OK) { - log_error("%s, ERROR line:%u\n", __func__, __LINE__); - return bep_result; - } - - return receive_result_args1(chain, ARG_VERSION, version, len); -} - -fpc_bep_result_t bep_reset(HCP_comm_t *chain) -{ - fpc_bep_result_t bep_result; - - bep_result = send_command_no_args(chain, CMD_RESET); - if (bep_result != FPC_BEP_RESULT_OK) { - log_error("%s:%u, ERROR\n", __func__, __LINE__); - return bep_result; - } - - return receive_result_no_args(chain); -} - -fpc_bep_result_t bep_sensor_calibrate(HCP_comm_t *chain) -{ - fpc_bep_result_t bep_result; - - bep_result = send_command_no_args(chain, CMD_STORAGE_CALIBRATION); - if (bep_result != FPC_BEP_RESULT_OK) { - log_error("%s:%u, ERROR\n", __func__, __LINE__); - return bep_result; - } - - return receive_result_no_args(chain); -} - -fpc_bep_result_t bep_sensor_calibrate_remove(HCP_comm_t *chain) -{ - fpc_bep_result_t bep_result; - - bep_result = send_command(chain, CMD_STORAGE_CALIBRATION, ARG_DELETE, NULL, 0); - if (bep_result != FPC_BEP_RESULT_OK) { - log_error("%s:%u, ERROR\n", __func__, __LINE__); - return bep_result; - } - - return receive_result_no_args(chain); -} - -fpc_bep_result_t bep_sensor_wait_for_finger(HCP_comm_t *chain, uint16_t timeout) -{ - fpc_bep_result_t bep_result; - - bep_result = send_command(chain, CMD_WAIT, ARG_FINGER_DOWN, NULL, 0); - if (bep_result != FPC_BEP_RESULT_OK) { - log_error("%s:%u, ERROR\n", __func__, __LINE__); - return bep_result; - } - - /* Wait for finger on sensor */ - return receive_result_no_args(chain); -} - -fpc_bep_result_t bep_sensor_wait_finger_not_present(HCP_comm_t *chain, uint16_t timeout) -{ - fpc_bep_result_t bep_result; - - bep_result = send_command(chain, CMD_WAIT, ARG_FINGER_UP, NULL, 0); - if (bep_result != FPC_BEP_RESULT_OK) { - log_error("%s:%u, ERROR\n", __func__, __LINE__); - return bep_result; - } - - /* Wait for finger to be lifted from sensor */ - return receive_result_no_args(chain); -} diff --git a/BMLite_example/src/bmlite_if.c b/BMLite_example/src/bmlite_if.c new file mode 100644 index 0000000..9e8560f --- /dev/null +++ b/BMLite_example/src/bmlite_if.c @@ -0,0 +1,307 @@ +#include "hcp_tiny.h" +#include "bmlite_if.h" +#include "platform.h" +#include + +#include "bmlite_if_callbacks.h" + +#define MAX_CAPTURE_ATTEMPTS 15 +#define CAPTURE_TIMEOUT 3000 + +#define exit_if_err(c) { bep_result = c; if(bep_result) goto exit; } + +#define assert(c) { fpc_bep_result_t res = c; if(res) return res; } + +#ifdef BMLITE_USE_CALLBACK +/** + * @brief Mock callback functions + */ +__attribute__((weak)) void bmlite_on_error(bmlite_error_t error, int32_t value) { (void)error; (void)value; } + +__attribute__((weak)) void bmlite_on_start_capture() {} +__attribute__((weak)) void bmlite_on_finish_capture() {} + +__attribute__((weak)) void bmlite_on_start_enroll() {} +__attribute__((weak)) void bmlite_on_finish_enroll() {} + +__attribute__((weak)) void bmlite_on_start_enrollcapture() {} +__attribute__((weak)) void bmlite_on_finish_enrollcapture() {} + +__attribute__((weak)) void bmlite_on_identify_start() {} +__attribute__((weak)) void bmlite_on_identify_finish() {} +#endif + +fpc_bep_result_t bmlite_send_cmd(HCP_comm_t *chain, uint16_t cmd, uint16_t arg_type) +{ + assert(bmlite_init_cmd(chain, cmd, arg_type)); + return bmlite_tranceive(chain); +} + +fpc_bep_result_t bmlite_send_cmd_arg(HCP_comm_t *chain, uint16_t cmd, uint16_t arg1_type, uint16_t arg2_type, void *arg2_data, uint16_t arg2_length) +{ + assert(bmlite_init_cmd(chain, cmd, arg1_type)); + assert(bmlite_add_arg(chain, arg2_type, arg2_data, arg2_length)); + + return bmlite_tranceive(chain); +} + +fpc_bep_result_t sensor_wait_finger_present(HCP_comm_t *chain, uint16_t timeout) +{ + fpc_bep_result_t bep_result; + uint32_t prev_timeout = chain->phy_rx_timeout; + + bmlite_on_start_capture(); + chain->phy_rx_timeout = timeout; + bep_result = bmlite_send_cmd_arg(chain, CMD_WAIT, ARG_FINGER_DOWN, ARG_TIMEOUT, &timeout, sizeof(timeout)); + chain->phy_rx_timeout = prev_timeout; + bmlite_on_finish_capture(); + + return bep_result; +} + +fpc_bep_result_t sensor_wait_finger_not_present(HCP_comm_t *chain, uint16_t timeout) +{ + fpc_bep_result_t bep_result; + uint32_t prev_timeout = chain->phy_rx_timeout; + + chain->phy_rx_timeout = timeout; + bep_result = bmlite_send_cmd_arg(chain, CMD_WAIT, ARG_FINGER_UP, ARG_TIMEOUT, &timeout, sizeof(timeout)); + chain->phy_rx_timeout = prev_timeout; + + return bep_result; +} + +fpc_bep_result_t bep_capture(HCP_comm_t *chain, uint16_t timeout) +{ + fpc_bep_result_t bep_result; + uint32_t prev_timeout = chain->phy_rx_timeout; + + bmlite_on_start_capture(); + chain->phy_rx_timeout = timeout; + bep_result = bmlite_send_cmd_arg(chain, CMD_CAPTURE, ARG_NONE, ARG_TIMEOUT, &timeout, sizeof(timeout)); + chain->phy_rx_timeout = prev_timeout; + bmlite_on_finish_capture(); + + return bep_result; +} + +fpc_bep_result_t bep_image_get_size(HCP_comm_t *chain, uint32_t *size) +{ + assert(bmlite_send_cmd(chain, CMD_IMAGE, ARG_SIZE)); + assert(bmlite_get_arg(chain, ARG_SIZE)); + + *size = *(uint32_t*)chain->arg.data; + + return FPC_BEP_RESULT_OK; +} + +fpc_bep_result_t image_create(HCP_comm_t *chain) +{ + return bmlite_send_cmd(chain, CMD_IMAGE, ARG_CREATE); +} + +fpc_bep_result_t image_delete(HCP_comm_t *chain) +{ + return bmlite_send_cmd(chain, CMD_IMAGE, ARG_DELETE); +} + +fpc_bep_result_t bep_image_get(HCP_comm_t *chain, uint8_t *data, uint32_t size) +{ + assert(bmlite_send_cmd(chain, CMD_IMAGE, ARG_UPLOAD)); + return bmlite_copy_arg(chain, ARG_DATA, data, size); +} + +fpc_bep_result_t bep_image_put(HCP_comm_t *chain, uint8_t *data, uint32_t size) +{ + return bmlite_send_cmd_arg(chain, CMD_IMAGE, ARG_DOWNLOAD, ARG_DATA, data, size); +} + +fpc_bep_result_t bep_image_extract(HCP_comm_t *chain) +{ + return bmlite_send_cmd(chain, CMD_IMAGE, ARG_EXTRACT); +} + +fpc_bep_result_t bep_identify(HCP_comm_t *chain) +{ + return bmlite_send_cmd(chain, CMD_IDENTIFY, ARG_NONE); +} + +fpc_bep_result_t bep_enroll_finger(HCP_comm_t *chain) +{ + uint32_t samples_remaining = 0; + fpc_bep_result_t bep_result = FPC_BEP_RESULT_OK; + bool enroll_done = false; + + bmlite_on_start_enroll(); + /* Enroll start */ + exit_if_err(bmlite_send_cmd(chain, CMD_ENROLL, ARG_START)); + + for (uint8_t i = 0; i < MAX_CAPTURE_ATTEMPTS; ++i) { + + bmlite_on_start_enrollcapture(); + bep_result = bep_capture(chain, CAPTURE_TIMEOUT); + bmlite_on_finish_enrollcapture(); + + if (bep_result != FPC_BEP_RESULT_OK) { + continue; + } + + /* Enroll add */ + bep_result = bmlite_send_cmd(chain, CMD_ENROLL, ARG_ADD); + if (bep_result != FPC_BEP_RESULT_OK) { + continue; + } + + bmlite_get_arg(chain, ARG_COUNT); + samples_remaining = *(uint32_t *)chain->arg.data; + +// log_info("Enroll samples remaining: %d\n", samples_remaining); + + /* Break enrolling if we can't collect enough correct images for enroll*/ + if (samples_remaining == 0U) { + enroll_done = true; + break; + } + + sensor_wait_finger_not_present(chain, 0); + } + + bep_result = bmlite_send_cmd(chain, CMD_ENROLL, ARG_FINISH); + +exit: + bmlite_on_finish_enroll(); + return (!enroll_done) ? FPC_BEP_RESULT_GENERAL_ERROR : bep_result; +} + +fpc_bep_result_t bep_identify_finger(HCP_comm_t *chain, uint32_t timeout, uint16_t *template_id, bool *match) +{ + fpc_bep_result_t bep_result; + *match = false; + + bmlite_on_identify_start(); + + exit_if_err(bep_capture(chain, timeout)); + exit_if_err(bep_image_extract(chain)); + exit_if_err(bep_identify(chain)); + exit_if_err(bmlite_get_arg(chain, ARG_MATCH)); + *match = *(bool *)chain->arg.data; + if(*match) { + bmlite_get_arg(chain, ARG_ID); + *template_id = *(uint16_t *)chain->arg.data; + // Delay for possible updating template on BM-Lite + hal_timebase_busy_wait(50); + } + + bep_result = sensor_wait_finger_not_present(chain, 0); + +exit: + bmlite_on_identify_finish(); + return bep_result; +} + +fpc_bep_result_t bep_template_save(HCP_comm_t *chain, uint16_t template_id) +{ + return bmlite_send_cmd_arg(chain, CMD_TEMPLATE, ARG_SAVE, ARG_ID, &template_id, sizeof(template_id)); +} + +fpc_bep_result_t bep_template_remove_ram(HCP_comm_t *chain) +{ + return bmlite_send_cmd(chain, CMD_TEMPLATE, ARG_DELETE); +} + +fpc_bep_result_t bep_template_get(HCP_comm_t *chain, uint8_t *data, uint32_t size) +{ + assert(bmlite_send_cmd(chain, CMD_TEMPLATE, ARG_UPLOAD)); + return bmlite_copy_arg(chain, ARG_DATA, data, size); +} + +fpc_bep_result_t bep_template_put(HCP_comm_t *chain, uint8_t *data, uint16_t length) +{ + return bmlite_send_cmd_arg(chain, CMD_TEMPLATE, ARG_DOWNLOAD, + ARG_DATA, data, length); +} + +fpc_bep_result_t bep_template_remove(HCP_comm_t *chain, uint16_t template_id) +{ + return bmlite_send_cmd_arg(chain, CMD_STORAGE_TEMPLATE, ARG_DELETE, + ARG_ID, &template_id, sizeof(template_id)); +} + +fpc_bep_result_t bep_template_remove_all(HCP_comm_t *chain) +{ + return bmlite_send_cmd_arg(chain, CMD_STORAGE_TEMPLATE, ARG_DELETE, + ARG_ALL, 0, 0); +} + +fpc_bep_result_t bep_template_load_storage(HCP_comm_t *chain, uint16_t template_id) +{ + return bmlite_send_cmd_arg(chain, CMD_STORAGE_TEMPLATE, ARG_UPLOAD, + ARG_ID, &template_id, sizeof(template_id)); +} + +fpc_bep_result_t bep_template_get_count(HCP_comm_t *chain, uint16_t *count) +{ + assert(bmlite_send_cmd(chain, CMD_STORAGE_TEMPLATE, ARG_COUNT)); + assert(bmlite_get_arg(chain, ARG_COUNT)); + *count = *(uint16_t*)chain->arg.data; + return FPC_BEP_RESULT_OK; +} + +fpc_bep_result_t bep_template_get_ids(HCP_comm_t *chain) +{ + assert(bmlite_send_cmd(chain, CMD_STORAGE_TEMPLATE, ARG_ID)); + return bmlite_get_arg(chain, ARG_DATA); +} + +fpc_bep_result_t bep_sw_reset(HCP_comm_t *chain) +{ + return bmlite_send_cmd(chain, CMD_RESET, ARG_NONE); +} + +fpc_bep_result_t bep_sensor_calibrate(HCP_comm_t *chain) +{ + return bmlite_send_cmd(chain, CMD_STORAGE_CALIBRATION, ARG_NONE); +} + +fpc_bep_result_t bep_sensor_calibrate_remove(HCP_comm_t *chain) +{ + return bmlite_send_cmd(chain, CMD_STORAGE_CALIBRATION, ARG_DELETE); +} + +fpc_bep_result_t bep_version(HCP_comm_t *chain, char *version, int len) +{ + assert(bmlite_send_cmd_arg(chain, CMD_INFO, ARG_GET, ARG_VERSION, 0, 0)); + return bmlite_copy_arg(chain, ARG_VERSION, version, len); +} + +fpc_bep_result_t bep_unique_id_get(HCP_comm_t *chain, uint8_t *unique_id) +{ + assert(bmlite_send_cmd_arg(chain, CMD_INFO, ARG_GET, ARG_UNIQUE_ID, 0, 0)); + return bmlite_copy_arg(chain, ARG_UNIQUE_ID, unique_id, 12); +} + +fpc_bep_result_t bep_uart_speed_set(HCP_comm_t *chain, uint32_t speed) +{ + assert(bmlite_init_cmd(chain, CMD_COMMUNICATION, ARG_SPEED)); + assert(bmlite_add_arg(chain, ARG_SET, 0, 0)); + assert(bmlite_add_arg(chain, ARG_DATA, (uint8_t*)&speed, sizeof(speed))); + return bmlite_tranceive(chain); + +} + +fpc_bep_result_t bep_uart_speed_get(HCP_comm_t *chain, uint32_t *speed) +{ + assert(bmlite_init_cmd(chain, CMD_COMMUNICATION, ARG_SPEED)); + assert(bmlite_add_arg(chain, ARG_GET, 0, 0)); + assert(bmlite_tranceive(chain)); + return bmlite_copy_arg(chain, ARG_DATA, speed, sizeof(speed)); + +} + +fpc_bep_result_t bep_sensor_reset(HCP_comm_t *chain) +{ + // Delay for possible updating template on BM-Lite + hal_timebase_busy_wait(50); + + return bmlite_send_cmd(chain, CMD_SENSOR, ARG_RESET); +} diff --git a/BMLite_example/src/hcp_tiny.c b/BMLite_example/src/hcp_tiny.c index 99a4b4d..4dfcff0 100644 --- a/BMLite_example/src/hcp_tiny.c +++ b/BMLite_example/src/hcp_tiny.c @@ -1,26 +1,27 @@ -#include -#include #include -#include "bep_host_if.h" #include "platform.h" #include "fpc_crc.h" #include "fpc_hcp_common.h" #include "hcp_tiny.h" -#define DEBUG(...) printf(__VA_ARGS__) +#include "bmlite_if_callbacks.h" + +#define DEBUG + +#ifdef DEBUG +#include +#include +#define LOG_DEBUG(...) printf(__VA_ARGS__) +#else +#define LOG_DEBUG(...) +#endif static uint32_t fpc_com_ack = FPC_BEP_ACK; -static fpc_bep_result_t _rx_application(HCP_comm_t *hcp_comm); static fpc_bep_result_t _rx_link(HCP_comm_t *hcp_comm); -static fpc_bep_result_t _tx_application(HCP_comm_t *hcp_comm); static fpc_bep_result_t _tx_link(HCP_comm_t *hcp_comm); -static fpc_bep_result_t hcp_init_cmd(HCP_comm_t *hcp_comm, uint16_t cmd); -static fpc_bep_result_t hcp_add_arg(HCP_comm_t *hcp_comm, uint16_t arg, uint8_t *data, uint16_t size); -static fpc_bep_result_t hcp_get_arg(HCP_comm_t *hcp_comm, uint16_t arg_type, uint16_t *size, uint8_t **payload); - typedef struct { uint16_t cmd; uint16_t args_nr; @@ -42,18 +43,30 @@ typedef struct { _HCP_cmd_t t_pld; } _HPC_pkt_t; -fpc_bep_result_t hcp_init_cmd(HCP_comm_t *hcp_comm, uint16_t cmd) +fpc_bep_result_t bmlite_init_cmd(HCP_comm_t *hcp_comm, uint16_t cmd, uint16_t arg_key) { + fpc_bep_result_t bep_result; + _HCP_cmd_t *out = (_HCP_cmd_t *)hcp_comm->pkt_buffer; out->cmd = cmd; out->args_nr = 0; hcp_comm->pkt_size = 4; + + if(arg_key != ARG_NONE) { + bep_result = bmlite_add_arg(hcp_comm, arg_key, NULL, 0); + if(bep_result) { + bmlite_on_error(BMLITE_ERROR_SEND_CMD, bep_result); + return bep_result; + } + } + return FPC_BEP_RESULT_OK; } -fpc_bep_result_t hcp_add_arg(HCP_comm_t *hcp_comm, uint16_t arg, uint8_t *data, uint16_t size) +fpc_bep_result_t bmlite_add_arg(HCP_comm_t *hcp_comm, uint16_t arg, void *data, uint16_t size) { if(hcp_comm->pkt_size + 4 + size > hcp_comm->pkt_size_max) { + bmlite_on_error(BMLITE_ERROR_SEND_CMD, FPC_BEP_RESULT_NO_MEMORY); return FPC_BEP_RESULT_NO_MEMORY; } @@ -68,7 +81,7 @@ fpc_bep_result_t hcp_add_arg(HCP_comm_t *hcp_comm, uint16_t arg, uint8_t *data, return FPC_BEP_RESULT_OK; } -fpc_bep_result_t hcp_get_arg(HCP_comm_t *hcp_comm, uint16_t arg_type, uint16_t *size, uint8_t **payload) +fpc_bep_result_t bmlite_get_arg(HCP_comm_t *hcp_comm, uint16_t arg_type) { uint16_t i = 0; uint8_t *buffer = hcp_comm->pkt_buffer; @@ -77,51 +90,99 @@ fpc_bep_result_t hcp_get_arg(HCP_comm_t *hcp_comm, uint16_t arg_type, uint16_t * while (i < args_nr && (pdata - buffer) <= hcp_comm->pkt_size) { _CMD_arg_t *parg = (_CMD_arg_t *)pdata; if(parg->arg == arg_type) { - *size = parg->size; - *payload = parg->pld; + hcp_comm->arg.size = parg->size; + hcp_comm->arg.data = parg->pld; return FPC_BEP_RESULT_OK; } else { i++; pdata += 4 + parg->size; } } + + // Ignore missing ARG_RESULT because some command return result other way + // if (arg_type != ARG_RESULT) { + bmlite_on_error(BMLITE_ERROR_GET_ARG, FPC_BEP_RESULT_INVALID_ARGUMENT); + // } return FPC_BEP_RESULT_INVALID_ARGUMENT; } -static fpc_bep_result_t _rx_application(HCP_comm_t *hcp_comm) +fpc_bep_result_t bmlite_copy_arg(HCP_comm_t *hcp_comm, uint16_t arg_key, void *arg_data, uint16_t arg_data_length) { - fpc_bep_result_t status = FPC_BEP_RESULT_OK; + fpc_bep_result_t bep_result; + bep_result = bmlite_get_arg(hcp_comm, arg_key); + if(bep_result == FPC_BEP_RESULT_OK) { + if(arg_data == NULL) { + bmlite_on_error(BMLITE_ERROR_GET_ARG, FPC_BEP_RESULT_NO_MEMORY); + return FPC_BEP_RESULT_NO_MEMORY; + } + memcpy(arg_data, hcp_comm->arg.data, HCP_MIN(arg_data_length, hcp_comm->arg.size)); + } else { + bmlite_on_error(BMLITE_ERROR_GET_ARG, FPC_BEP_RESULT_INVALID_ARGUMENT); + return FPC_BEP_RESULT_INVALID_ARGUMENT; + } + + return bep_result; +} + +fpc_bep_result_t bmlite_tranceive(HCP_comm_t *hcp_comm) +{ + fpc_bep_result_t bep_result; + + bep_result = bmlite_send(hcp_comm); + if (bep_result == FPC_BEP_RESULT_OK) { + bep_result = bmlite_receive(hcp_comm); + + if (bmlite_get_arg(hcp_comm, ARG_RESULT) == FPC_BEP_RESULT_OK) { + hcp_comm->bep_result = *(int8_t*)hcp_comm->arg.data; + } else { + hcp_comm->bep_result = FPC_BEP_RESULT_OK; + } + } + + return bep_result; +} + +fpc_bep_result_t bmlite_receive(HCP_comm_t *hcp_comm) +{ + fpc_bep_result_t bep_result = FPC_BEP_RESULT_OK; fpc_bep_result_t com_result = FPC_BEP_RESULT_OK; uint16_t seq_nr = 0; uint16_t seq_len = 1; - uint16_t len; uint8_t *p = hcp_comm->pkt_buffer; _HPC_pkt_t *pkt = (_HPC_pkt_t *)hcp_comm->txrx_buffer; uint16_t buf_len = 0; while(seq_nr < seq_len) { - status = _rx_link(hcp_comm); + bep_result = _rx_link(hcp_comm); - if (!status) { - len = pkt->lnk_size - 4; + if (!bep_result) { seq_nr = pkt->t_seq_nr; seq_len = pkt->t_seq_len; - if(buf_len + len < hcp_comm->pkt_size_max) { - memcpy(p, &pkt->t_pld, len); - p += len; - buf_len += len; + if(pkt->t_size != pkt->lnk_size - 6) { + com_result = FPC_BEP_RESULT_IO_ERROR; + continue; + } + if(buf_len + pkt->t_size < hcp_comm->pkt_size_max) { + memcpy(p, &pkt->t_pld, pkt->t_size); + p += pkt->t_size; + buf_len += pkt->t_size; } else { com_result = FPC_BEP_RESULT_NO_MEMORY; } +#ifdef DEBUG if (seq_len > 1) - DEBUG("S: Seqence %d of %d\n", seq_nr, seq_len); + LOG_DEBUG("Received data chunk %d of %d\n", seq_nr, seq_len); +#endif } else { - DEBUG("S: Receiving chunk error %d\n", status); - return status; + bmlite_on_error(BMLITE_ERROR_SEND_CMD, bep_result); + return bep_result; } } hcp_comm->pkt_size = buf_len; + if(com_result != FPC_BEP_RESULT_OK) { + bmlite_on_error(BMLITE_ERROR_SEND_CMD, com_result); + } return com_result; } @@ -133,7 +194,7 @@ static fpc_bep_result_t _rx_link(HCP_comm_t *hcp_comm) uint16_t size; if (result) { - //DEBUG("Timed out waiting for response.\n"); + LOG_DEBUG("Timed out waiting for response.\n"); return result; } @@ -141,7 +202,8 @@ static fpc_bep_result_t _rx_link(HCP_comm_t *hcp_comm) // Check if size plus header and crc is larger than max package size. if (MTU < size + 8) { - DEBUG("S: Invalid size %d, larger than MTU %d.\n", size, MTU); + // LOG_DEBUG("S: Invalid size %d, larger than MTU %d.\n", size, MTU); + bmlite_on_error(BMLITE_ERROR_SEND_CMD, FPC_BEP_RESULT_IO_ERROR); return FPC_BEP_RESULT_IO_ERROR; } @@ -151,20 +213,21 @@ static fpc_bep_result_t _rx_link(HCP_comm_t *hcp_comm) uint32_t crc_calc = fpc_crc(0, hcp_comm->txrx_buffer+4, size); if (crc_calc != crc) { - DEBUG("S: CRC mismatch. Calculated %08X, received %08X\n", crc_calc, crc); + LOG_DEBUG("CRC mismatch. Calculated %08X, received %08X\n", crc_calc, crc); + bmlite_on_error(BMLITE_ERROR_SEND_CMD, FPC_BEP_RESULT_IO_ERROR); return FPC_BEP_RESULT_IO_ERROR; } // Send Ack hcp_comm->write(4, (uint8_t *)&fpc_com_ack, 0, NULL); - return 0; + return FPC_BEP_RESULT_OK; } -static fpc_bep_result_t _tx_application(HCP_comm_t *hcp_comm) +fpc_bep_result_t bmlite_send(HCP_comm_t *hcp_comm) { uint16_t seq_nr = 1; - fpc_bep_result_t status = FPC_BEP_RESULT_OK; + fpc_bep_result_t bep_result = FPC_BEP_RESULT_OK; uint16_t data_left = hcp_comm->pkt_size; uint8_t *p = hcp_comm->pkt_buffer; @@ -179,48 +242,46 @@ static fpc_bep_result_t _tx_application(HCP_comm_t *hcp_comm) phy_frm->lnk_chn = 0; phy_frm->t_seq_len = seq_len; - for (seq_nr = 1; seq_nr <= seq_len && !status; seq_nr++) { + for (seq_nr = 1; seq_nr <= seq_len && !bep_result; seq_nr++) { phy_frm->t_seq_nr = seq_nr; if (data_left < app_mtu) { phy_frm->t_size = data_left; - memcpy(hcp_comm->txrx_buffer + 10, p, data_left); - phy_frm->lnk_size = data_left + 6; } else { phy_frm->t_size = app_mtu; - memcpy(hcp_comm->txrx_buffer + 10, p, app_mtu); - phy_frm->lnk_size = app_mtu + 6; - p += app_mtu; - data_left -= app_mtu; } + memcpy(&phy_frm->t_pld, p, phy_frm->t_size); + phy_frm->lnk_size = phy_frm->t_size + 6; + p += phy_frm->t_size; + data_left -= phy_frm->t_size; - status = _tx_link(hcp_comm); + bep_result = _tx_link(hcp_comm); } - return status; + if(bep_result) { + bmlite_on_error(BMLITE_ERROR_SEND_CMD, bep_result); + } + return bep_result; } fpc_bep_result_t _tx_link(HCP_comm_t *hcp_comm) { - fpc_bep_result_t result; + fpc_bep_result_t bep_result; _HPC_pkt_t *pkt = (_HPC_pkt_t *)hcp_comm->txrx_buffer; uint32_t crc_calc = fpc_crc(0, &pkt->t_size, pkt->lnk_size); - *(uint32_t *)(hcp_comm->txrx_buffer + 4 + pkt->lnk_size) = crc_calc; + *(uint32_t *)(hcp_comm->txrx_buffer + pkt->lnk_size + 4) = crc_calc; uint16_t size = pkt->lnk_size + 8; - result = hcp_comm->write(size, hcp_comm->txrx_buffer, 0, NULL); - if(result) { - DEBUG("S: Sending error\n"); - return result; - } + bep_result = hcp_comm->write(size, hcp_comm->txrx_buffer, 0, NULL); // Wait for ACK uint32_t ack; - result = hcp_comm->read(4, (uint8_t *)&ack, 100, NULL); - if (result == FPC_BEP_RESULT_TIMEOUT) { - DEBUG("S: ASK timeout\n"); - return FPC_BEP_RESULT_OK; + bep_result = hcp_comm->read(4, (uint8_t *)&ack, 500, NULL); + if (bep_result == FPC_BEP_RESULT_TIMEOUT) { + LOG_DEBUG("ASK read timeout\n"); + bmlite_on_error(BMLITE_ERROR_SEND_CMD, FPC_BEP_RESULT_TIMEOUT); + return FPC_BEP_RESULT_IO_ERROR; } if(ack != fpc_com_ack) { @@ -230,76 +291,3 @@ fpc_bep_result_t _tx_link(HCP_comm_t *hcp_comm) return FPC_BEP_RESULT_OK; } -fpc_bep_result_t send_command_args2(HCP_comm_t *chain, fpc_hcp_cmd_t command_id, - fpc_hcp_arg_t arg_key1, void *arg_data1, uint16_t arg_data1_length, - fpc_hcp_arg_t arg_key2, void *arg_data2, uint16_t arg_data2_length) -{ - fpc_bep_result_t bep_result; - hcp_init_cmd(chain, command_id); - - if(arg_key1 != ARG_NONE) { - bep_result = hcp_add_arg(chain, arg_key1, arg_data1, arg_data1_length); - if(bep_result) { - return bep_result; - } - } - - if(arg_key2 != ARG_NONE) { - bep_result = hcp_add_arg(chain, arg_key2, arg_data2, arg_data2_length); - if(bep_result) { - return bep_result; - } - } - - bep_result = _tx_application(chain); - - if (bep_result != FPC_BEP_RESULT_OK) { - DEBUG("%s:%u ERROR %d\n", __func__, __LINE__, bep_result); - } - - return bep_result; -} - -fpc_bep_result_t receive_result_args2(HCP_comm_t *chain, - fpc_hcp_arg_t arg_key1, void *arg_data1, uint16_t arg_data1_length, - fpc_hcp_arg_t arg_key2, void *arg_data2, uint16_t arg_data2_length) -{ - fpc_bep_result_t bep_result; - uint16_t size; - uint8_t *pld; - - - bep_result = _rx_application(chain); - if(bep_result) { - DEBUG("S: Receive err: %d\n", bep_result); - return bep_result; - } - - if (arg_key1 != ARG_NONE) { - bep_result = hcp_get_arg(chain, arg_key1, &size, &pld); - if(bep_result == FPC_BEP_RESULT_OK) { - if(arg_data1 == NULL) { - return FPC_BEP_RESULT_NO_MEMORY; - } - memcpy(arg_data1, pld, arg_data1_length); - } else { - DEBUG("Arg1 0x%04X not found\n", arg_key1); - return FPC_BEP_RESULT_INVALID_ARGUMENT; - } - } - - if (arg_key2 != ARG_NONE) { - bep_result = hcp_get_arg(chain, arg_key2, &size, &pld); - if(bep_result == FPC_BEP_RESULT_OK) { - if(arg_data2 == NULL) { - return FPC_BEP_RESULT_NO_MEMORY; - } - memcpy(arg_data2, pld, arg_data2_length); - } else { - DEBUG("Arg2 0x%04X not found\n", arg_key2); - //return FPC_BEP_RESULT_INVALID_ARGUMENT; - } - } - - return FPC_BEP_RESULT_OK; -} diff --git a/BMLite_example/src/main.c b/BMLite_example/src/main.c index a01c6ee..c2164ad 100644 --- a/BMLite_example/src/main.c +++ b/BMLite_example/src/main.c @@ -31,7 +31,7 @@ #include #include -#include "bep_host_if.h" +#include "bmlite_if.h" #include "platform.h" #define DATA_BUFFER_SIZE 102400 @@ -48,13 +48,62 @@ static HCP_comm_t hcp_chain = { .phy_rx_timeout = 2000, }; - static void help(void) { fprintf(stderr, "BEP Host Communication Application\n"); fprintf(stderr, "Syntax: bep_host_com [-s] [-p port] [-b baudrate] [-t timeout]\n"); } +void bmlite_on_error(bmlite_error_t error, int32_t value) +{ + printf("Error: %d, return code %d\n", error, (int16_t)value); +} + +void bmlite_on_start_capture() +{ + printf("Put finger on the sensor\n"); +} +void bmlite_on_finish_capture() +{ + printf("Remove finger from the sensor\n"); +} + +void bmlite_on_start_enroll() +{ + printf("Start enrolling\n"); +} + +void bmlite_on_finish_enroll() +{ + printf("Finish enrolling\n"); +} + +void bmlite_on_start_enrollcapture() {} +void bmlite_on_finish_enrollcapture() {} + +void bmlite_on_identify_start() +{ + printf("Start Identifying\n"); +} +void bmlite_on_identify_finish() +{ + printf("Finish Identifying\n"); +} + +void save_to_pgm(FILE *f, uint8_t *image, int res_x, int res_y) +{ + /* Print 8-bpp PGM ASCII header */ + fprintf(f, "P2\n%d %d\n255\n", res_x, res_y); + for (int y = 0; y < res_y; y++) { + for (int x = 0; x < res_x; x++, image++) + fprintf(f,"%d ", *image); + fprintf(f,"\n"); + } + + fprintf(f,"\x04"); /* End Of Transmission */ +} + + int main (int argc, char **argv) { char *port = NULL; @@ -62,9 +111,6 @@ int main (int argc, char **argv) int timeout = 5; int index; int c; - // uint8_t buffer[512]; - // uint16_t size[2] = { 256, 256 }; - //fpc_com_chain_t hcp_chain; interface_t iface = COM_INTERFACE; opterr = 0; @@ -130,8 +176,6 @@ int main (int argc, char **argv) exit(1); } - // init_com_chain(&hcp_chain, buffer, size, NULL, iface); - // hcp_chain.channel = 1; if (iface == COM_INTERFACE) { hcp_chain.read = platform_com_receive; hcp_chain.write = platform_com_send; @@ -146,7 +190,7 @@ int main (int argc, char **argv) uint16_t template_id; bool match; - platform_clear_screen(); + // platform_clear_screen(); printf("BM-Lite Interface\n"); if (iface == SPI_INTERFACE) printf("SPI port: speed %d Hz\n", baudrate); @@ -160,9 +204,11 @@ int main (int argc, char **argv) printf("c: Remove all templates\n"); printf("d: Save template\n"); printf("e: Remove template\n"); + printf("l: List of templates\n"); printf("f: Capture image\n"); - printf("g: Image upload\n"); + printf("g: Pull captured image\n"); printf("h: Get version\n"); + printf("r: SW Reset\n"); printf("q: Exit program\n"); printf("\nOption>> "); fgets(cmd, sizeof(cmd), stdin); @@ -181,19 +227,30 @@ int main (int argc, char **argv) } break; case 'c': - res = bep_delete_template(&hcp_chain, REMOVE_ID_ALL_TEMPLATES); + res = bep_template_remove_all(&hcp_chain); break; case 'd': printf("Template id: "); fgets(cmd, sizeof(cmd), stdin); template_id = atoi(cmd); - res = bep_save_template(&hcp_chain, template_id); + res = bep_template_save(&hcp_chain, template_id); + // res = bep_template_remove_ram(&hcp_chain); break; case 'e': printf("Template id: "); fgets(cmd, sizeof(cmd), stdin); template_id = atoi(cmd); - res = bep_delete_template(&hcp_chain, template_id); + res = bep_template_remove(&hcp_chain, template_id); + break; + case 'l': + res = bep_template_get_ids(&hcp_chain); + if (hcp_chain.bep_result == FPC_BEP_RESULT_OK) { + printf("Template list\n"); + for(int i=0; i < hcp_chain.arg.size/2; i++) { + printf("%d ", *(uint16_t *)(hcp_chain.arg.data+i*2)); + } + printf("\n"); + } break; case 'f': { printf("Timeout (ms): "); @@ -212,16 +269,63 @@ int main (int argc, char **argv) if (buf) { res = bep_image_get(&hcp_chain, buf, size); if (res == FPC_BEP_RESULT_OK) { - FILE *f = fopen("image.raw", "wb"); + // if(size != hcp_chain.arg.size) { + printf("Image size: %d. Received %d bytes\n", size, hcp_chain.arg.size); + // } + FILE *f = fopen("image.raw", "wb"); + if (f) { + fwrite(buf, 1, size, f); + fclose(f); + printf("Image saved as image.raw\n"); + } + f = fopen("image.pgm", "wb"); + if(f) { + save_to_pgm(f, buf, 160, 160); + fclose(f); + printf("Image saved as image.pgm\n"); + } + free(buf); + } + } + } + break; + } + case 'T': { + uint32_t size; + uint8_t *buf = malloc(102400); + FILE *f = fopen("stemplate.raw", "rb"); + if (f) { + size = fread(buf, 1, 102400, f); + fclose(f); + if(size > 0) { + printf("Pushing template size %d\n", size); + res = bep_template_put(&hcp_chain, buf, size); + if (res != FPC_BEP_RESULT_OK) { + printf("Pushing template error: %d\n", res); + } + } + } + free(buf); + + break; + } + case 't': { + uint8_t *buf = malloc(102400); + if (buf) { + res = bep_template_get(&hcp_chain, buf, 102400); + if (res == FPC_BEP_RESULT_OK) { + // if(size != hcp_chain.arg.size) { + printf("Template size received %d bytes\n", hcp_chain.arg.size); + // } + FILE *f = fopen("template.raw", "wb"); if (f) { - fwrite(buf, 1, size, f); + fwrite(buf, 1, hcp_chain.arg.size, f); fclose(f); printf("Image saved as image.raw\n"); } - } + } } - - } + free(buf); break; } case 'h': { @@ -234,16 +338,26 @@ int main (int argc, char **argv) } break; } + case 'r': + bep_sw_reset(&hcp_chain); + break; case 'q': return 0; default: printf("\nUnknown command\n"); } - if (res == FPC_BEP_RESULT_OK) { + if (hcp_chain.bep_result == FPC_BEP_RESULT_OK) { printf("\nCommand succeded\n"); } else { - printf("\nCommand failed with error code %d\n", res); + printf("\nCommand failed with error code %d\n", hcp_chain.bep_result); } + + if (res == FPC_BEP_RESULT_OK) { + printf("Transfer succeded\n"); + } else { + printf("Transfer failed with error code %d\n", res); + } + printf("Press any key to continue..."); fgets(cmd, sizeof(cmd), stdin); } diff --git a/BMLite_example/src/platform_linux.c b/BMLite_example/src/platform_linux.c index 085bf2d..6227ced 100644 --- a/BMLite_example/src/platform_linux.c +++ b/BMLite_example/src/platform_linux.c @@ -28,6 +28,7 @@ #include #include #include +#include #include "platform.h" @@ -46,4 +47,9 @@ uint64_t platform_get_time(void) void platform_clear_screen(void) { system("clear"); +} + +void hal_timebase_busy_wait(uint32_t ms) +{ + usleep(ms * 1000); } \ No newline at end of file