From f30ff7054c503b853a17bc9a88f8d5216d5539c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Szyma=C5=84ski?= Date: Thu, 10 Aug 2023 22:26:22 +0200 Subject: [PATCH 01/16] Add animation modes support --- .gitignore | 4 +- firmware/application/Makefile | 1 + firmware/application/src/app_cmd.c | 24 +++++++ firmware/application/src/app_main.c | 56 +++++++++++------ firmware/application/src/data_cmd.h | 3 + .../src/rfid/nfctag/tag_emulation.c | 1 + .../src/rfid/nfctag/tag_persistence.c | 2 +- .../src/rfid/nfctag/tag_persistence.h | 21 ------- firmware/application/src/settings.c | 63 +++++++++++++++++++ firmware/application/src/settings.h | 21 +++++++ firmware/application/src/utils/fds_ids.h | 30 +++++++++ software/script/chameleon_cli_main.py | 9 +++ software/script/chameleon_cli_unit.py | 38 +++++++++++ software/script/chameleon_cmd.py | 22 +++++++ software/script/chameleon_status.py | 4 ++ 15 files changed, 257 insertions(+), 42 deletions(-) create mode 100644 firmware/application/src/settings.c create mode 100644 firmware/application/src/settings.h create mode 100644 firmware/application/src/utils/fds_ids.h diff --git a/.gitignore b/.gitignore index 79e7608..9b759bb 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ .idea/ .vscode/ -.vs/ \ No newline at end of file +.vs/ + +.DS_Store \ No newline at end of file diff --git a/firmware/application/Makefile b/firmware/application/Makefile index f248a1a..c0e0122 100644 --- a/firmware/application/Makefile +++ b/firmware/application/Makefile @@ -11,6 +11,7 @@ SRC_FILES += \ $(PROJ_DIR)/app_cmd.c \ $(PROJ_DIR)/ble_main.c \ $(PROJ_DIR)/rfid_main.c \ + $(PROJ_DIR)/settings.c \ $(PROJ_DIR)/usb_main.c \ $(PROJ_DIR)/rgb_marquee.c \ $(PROJ_DIR)/bsp/bsp_delay.c \ diff --git a/firmware/application/src/app_cmd.c b/firmware/application/src/app_cmd.c index 2eb7559..27e2e52 100644 --- a/firmware/application/src/app_cmd.c +++ b/firmware/application/src/app_cmd.c @@ -12,6 +12,7 @@ #include "app_status.h" #include "tag_persistence.h" #include "nrf_pwr_mgmt.h" +#include "settings.h" #define NRF_LOG_MODULE_NAME app_cmd @@ -80,6 +81,26 @@ data_frame_tx_t* cmd_processor_get_device_address(uint16_t cmd, uint16_t status, return data_frame_make(cmd, STATUS_DEVICE_SUCCESS, 6, (uint8_t*)(&device_address[0])); } +data_frame_tx_t* cmd_processor_save_settings(uint16_t cmd, uint16_t status, uint16_t length, uint8_t *data) { + status = settings_save_config(); + return data_frame_make(cmd, status, 0, NULL); +} + +data_frame_tx_t* cmd_processor_set_animation_mode(uint16_t cmd, uint16_t status, uint16_t length, uint8_t *data) { + if (length == 1) { + settings_set_animation_config(data[0]); + } + else { + status = STATUS_PAR_ERR; + } + return data_frame_make(cmd, status, 0, NULL); +} + +data_frame_tx_t* cmd_processor_get_animation_mode(uint16_t cmd, uint16_t status, uint16_t length, uint8_t *data) { + uint8_t animation_mode = settings_get_animation_config(); + return data_frame_make(cmd, STATUS_DEVICE_SUCCESS, 1, (uint8_t *)(&animation_mode)); +} + #if defined(PROJECT_CHAMELEON_ULTRA) data_frame_tx_t* cmd_processor_14a_scan(uint16_t cmd, uint16_t status, uint16_t length, uint8_t *data) { @@ -524,6 +545,9 @@ static cmd_data_map_t m_data_cmd_map[] = { { DATA_CMD_ENTER_BOOTLOADER, NULL, cmd_processor_enter_bootloader, NULL }, { DATA_CMD_GET_DEVICE_CHIP_ID, NULL, cmd_processor_get_device_chip_id, NULL }, { DATA_CMD_GET_DEVICE_ADDRESS, NULL, cmd_processor_get_device_address, NULL }, + { DATA_CMD_SAVE_SETTINGS, NULL, cmd_processor_save_settings, NULL }, + { DATA_CMD_SET_ANIMATION_MODE, NULL, cmd_processor_set_animation_mode, NULL }, + { DATA_CMD_GET_ANIMATION_MODE, NULL, cmd_processor_get_animation_mode, NULL }, #if defined(PROJECT_CHAMELEON_ULTRA) diff --git a/firmware/application/src/app_main.c b/firmware/application/src/app_main.c index 2c4a529..387bd5e 100644 --- a/firmware/application/src/app_main.c +++ b/firmware/application/src/app_main.c @@ -36,6 +36,8 @@ NRF_LOG_MODULE_REGISTER(); #include "usb_main.h" #include "rgb_marquee.h" +#include "settings.h" + // Defining soft timers APP_TIMER_DEF(m_button_check_timer); // Timer for button debounce @@ -219,22 +221,25 @@ static void system_off_enter(void) { for (uint8_t i = 0; i < RGB_LIST_NUM; i++) { nrf_gpio_pin_clear(p_led_array[i]); } - uint8_t slot = tag_emulation_get_slot(); - // Power off animation - uint8_t dir = slot > 3 ? 1 : 0; - uint8_t color = get_color_by_slot(slot); - if (m_reset_source & (NRF_POWER_RESETREAS_NFC_MASK | NRF_POWER_RESETREAS_LPCOMP_MASK)) { - if (m_reset_source & NRF_POWER_RESETREAS_NFC_MASK) { - color = 1; - } else { - color = 2; + uint8_t animation_config = settings_get_animation_config(); + if (animation_config == SETTINGS_ANIMATION_FULL) { + uint8_t slot = tag_emulation_get_slot(); + // Power off animation + uint8_t dir = slot > 3 ? 1 : 0; + uint8_t color = get_color_by_slot(slot); + if (m_reset_source & (NRF_POWER_RESETREAS_NFC_MASK | NRF_POWER_RESETREAS_LPCOMP_MASK)) { + if (m_reset_source & NRF_POWER_RESETREAS_NFC_MASK) { + color = 1; + } else { + color = 2; + } } + ledblink5(color, slot, dir ? 7 : 0); + ledblink4(color, dir, 7, 99, 75); + ledblink4(color, !dir, 7, 75, 50); + ledblink4(color, dir, 7, 50, 25); + ledblink4(color, !dir, 7, 25, 0); } - ledblink5(color, slot, dir ? 7 : 0); - ledblink4(color, dir, 7, 99, 75); - ledblink4(color, !dir, 7, 75, 50); - ledblink4(color, dir, 7, 50, 25); - ledblink4(color, !dir, 7, 25, 0); rgb_marquee_stop(); } @@ -346,9 +351,17 @@ static void check_wakeup_src(void) { advertising_start(); // Turn on Bluetooth radio // Button wake-up boot animation - ledblink2(color, !dir, 11); - ledblink2(color, dir, 11); - ledblink2(color, !dir, dir ? slot : 7 - slot); + uint8_t animation_config = settings_get_animation_config(); + if (animation_config == SETTINGS_ANIMATION_FULL) + { + ledblink2(color, !dir, 11); + ledblink2(color, dir, 11); + ledblink2(color, !dir, dir ? slot : 7 - slot); + } + else if (animation_config == SETTINGS_ANIMATION_MINIMAL) { + ledblink2(color, !dir, dir ? slot : 7 - slot); + } + // The indicator of the current card slot lights up at the end of the animation light_up_by_slot(); @@ -374,8 +387,11 @@ static void check_wakeup_src(void) { // 当前是模拟卡事件唤醒系统,我们可以让场强灯先亮起来 TAG_FIELD_LED_ON(); - // In the case of field wake-up, only one round of RGB is swept as the power-on animation - ledblink2(color, !dir, dir ? slot : 7 - slot); + uint8_t animation_config = settings_get_animation_config(); + if (animation_config == SETTINGS_ANIMATION_FULL) { + // In the case of field wake-up, only one round of RGB is swept as the power-on animation + ledblink2(color, !dir, dir ? slot : 7 - slot); + } set_slot_light_color(color); light_up_by_slot(); @@ -517,6 +533,8 @@ int main(void) { tag_emulation_init(); // Analog card initialization rgb_marquee_init(); // Light effect initialization + settings_load_config(); // Load settings from flash + // cmd callback register on_data_frame_complete(on_data_frame_received); diff --git a/firmware/application/src/data_cmd.h b/firmware/application/src/data_cmd.h index e5437ae..89284f2 100644 --- a/firmware/application/src/data_cmd.h +++ b/firmware/application/src/data_cmd.h @@ -20,6 +20,9 @@ #define DATA_CMD_ENTER_BOOTLOADER (1010) #define DATA_CMD_GET_DEVICE_CHIP_ID (1011) #define DATA_CMD_GET_DEVICE_ADDRESS (1012) +#define DATA_CMD_SAVE_SETTINGS (1013) +#define DATA_CMD_SET_ANIMATION_MODE (1014) +#define DATA_CMD_GET_ANIMATION_MODE (1015) // // ****************************************************************** diff --git a/firmware/application/src/rfid/nfctag/tag_emulation.c b/firmware/application/src/rfid/nfctag/tag_emulation.c index dfa1ff1..849cd03 100644 --- a/firmware/application/src/rfid/nfctag/tag_emulation.c +++ b/firmware/application/src/rfid/nfctag/tag_emulation.c @@ -3,6 +3,7 @@ #include "lf_tag_em.h" #include "nfc_mf1.h" #include "nfc_ntag.h" +#include "fds_ids.h" #include "fds_util.h" #include "tag_emulation.h" #include "tag_persistence.h" diff --git a/firmware/application/src/rfid/nfctag/tag_persistence.c b/firmware/application/src/rfid/nfctag/tag_persistence.c index 2bf7a38..4997be2 100644 --- a/firmware/application/src/rfid/nfctag/tag_persistence.c +++ b/firmware/application/src/rfid/nfctag/tag_persistence.c @@ -1,5 +1,5 @@ #include "tag_persistence.h" - +#include "fds_ids.h" #define NRF_LOG_MODULE_NAME tag_persistence #include "nrf_log.h" diff --git a/firmware/application/src/rfid/nfctag/tag_persistence.h b/firmware/application/src/rfid/nfctag/tag_persistence.h index d25982e..21b51d0 100644 --- a/firmware/application/src/rfid/nfctag/tag_persistence.h +++ b/firmware/application/src/rfid/nfctag/tag_persistence.h @@ -5,27 +5,6 @@ #include "tag_base_type.h" -/* - * 卡槽配置,只有一份,一致即可 - */ -#define FDS_CONFIG_RECORD_FILE_KEY 0x1066 -#define FDS_CONFIG_RECORD_FILE_ID 0x1066 - -/* - * 每个卡槽有高低频两种数据,其中key是跟卡槽走的,而id+n就等于数据索引,固定某个索引为指定类型即可 - * 每个slot的file_key都不一样 - * 每个slot有两种类型的卡片,因此有两个数据ID(当前) - */ -#define FDS_SLOT_TAG_DUMP_FILE_KEY 0x1067 -#define FDS_SLOT_TAG_DUMP_FILE_ID 0x1067 - -/* - * 每个卡槽有高低频两种数据,因此卡槽的昵称也要有两种,其中key是跟卡槽走的,而id+n就等于数据索引,固定某个索引为指定类型即可 - */ -#define FDS_SLOT_TAG_NICK_NAME_KEY 0x1068 -#define FDS_SLOT_TAG_NICK_NAME_ID 0x1068 - - typedef struct { uint16_t key; uint16_t id; diff --git a/firmware/application/src/settings.c b/firmware/application/src/settings.c new file mode 100644 index 0000000..1dc03f5 --- /dev/null +++ b/firmware/application/src/settings.c @@ -0,0 +1,63 @@ +#include +#include "crc_utils.h" +#include "app_status.h" +#include "settings.h" +#include "fds_ids.h" +#include "fds_util.h" + +#define NRF_LOG_MODULE_NAME settings +#include "nrf_log.h" +#include "nrf_log_ctrl.h" +#include "nrf_log_default_backends.h" +NRF_LOG_MODULE_REGISTER(); + +static settings_data_t config; + +static uint16_t m_config_crc; + +void settings_load_config(void) +{ + bool ret = fds_read_sync(FDS_SETTINGS_ID, FDS_SETTINGS_KEY, sizeof(config), (uint8_t *)&config); + if (ret) { + // After the reading is complete, we first save a copy of the current CRC, which can be used as a reference for comparison of changes when saving later + calc_14a_crc_lut((uint8_t *)&config, sizeof(config), (uint8_t *)&m_config_crc); + NRF_LOG_INFO("Load config done."); + } else { + NRF_LOG_INFO("config no exists."); + } +} + +uint8_t settings_save_config(void) +{ + // We are saving the configuration, we need to calculate the crc code of the current configuration to judge whether the following data is updated + uint16_t new_calc_crc; + calc_14a_crc_lut((uint8_t *)&config, sizeof(config), (uint8_t *)&new_calc_crc); + if (new_calc_crc != m_config_crc) { // Before saving, make sure that the configuration has changed + NRF_LOG_INFO("Save tag slot config start."); + bool ret = fds_write_sync(FDS_CONFIG_RECORD_FILE_ID, FDS_CONFIG_RECORD_FILE_KEY, sizeof(config) / 4, (uint8_t *)&config); + if (ret) { + NRF_LOG_INFO("Save tag slot config success."); + m_config_crc = new_calc_crc; // store new CRC so we know that we've updated the configuration + } + else + { + NRF_LOG_ERROR("Save tag slot config error."); + return STATUS_FLASH_WRITE_FAIL; + } + } else { + NRF_LOG_INFO("Tag slot config no change."); + } + + return STATUS_DEVICE_SUCCESS; +} + +uint8_t settings_get_animation_config() +{ + return config & 0x3; +} + +void settings_set_animation_config(uint8_t value) +{ + config &= ~(0x3); + config |= value; +} diff --git a/firmware/application/src/settings.h b/firmware/application/src/settings.h new file mode 100644 index 0000000..a42baa3 --- /dev/null +++ b/firmware/application/src/settings.h @@ -0,0 +1,21 @@ +#ifndef SETTINGS_H +#define SETTINGS_H + +#include + +#define SETTINGS_ANIMATION_FULL 0 +#define SETTINGS_ANIMATION_MINIMAL 1 +#define SETTINGS_ANIMATION_NONE 2 + +/* + * bits [0-1]: animation config + * bits [2-31]: reserved + */ +typedef uint32_t settings_data_t; + +void settings_load_config(void); +uint8_t settings_save_config(void); +uint8_t settings_get_animation_config(); +void settings_set_animation_config(uint8_t value); + +#endif \ No newline at end of file diff --git a/firmware/application/src/utils/fds_ids.h b/firmware/application/src/utils/fds_ids.h new file mode 100644 index 0000000..ca11e2e --- /dev/null +++ b/firmware/application/src/utils/fds_ids.h @@ -0,0 +1,30 @@ +#ifndef FDS_IDS_H +#define FDS_IDS_H + +/* + * 卡槽配置,只有一份,一致即可 + */ +#define FDS_CONFIG_RECORD_FILE_KEY 0x1066 +#define FDS_CONFIG_RECORD_FILE_ID 0x1066 + +/* + * 每个卡槽有高低频两种数据,其中key是跟卡槽走的,而id+n就等于数据索引,固定某个索引为指定类型即可 + * 每个slot的file_key都不一样 + * 每个slot有两种类型的卡片,因此有两个数据ID(当前) + */ +#define FDS_SLOT_TAG_DUMP_FILE_KEY 0x1067 +#define FDS_SLOT_TAG_DUMP_FILE_ID 0x1067 + +/* + * 每个卡槽有高低频两种数据,因此卡槽的昵称也要有两种,其中key是跟卡槽走的,而id+n就等于数据索引,固定某个索引为指定类型即可 + */ +#define FDS_SLOT_TAG_NICK_NAME_KEY 0x1068 +#define FDS_SLOT_TAG_NICK_NAME_ID 0x1068 + +/* + * Slot for settings like LED animation mode and future options + */ +#define FDS_SETTINGS_KEY 0x1069 +#define FDS_SETTINGS_ID 0x1069 + +#endif \ No newline at end of file diff --git a/software/script/chameleon_cli_main.py b/software/script/chameleon_cli_main.py index 83fba87..fe23a4e 100755 --- a/software/script/chameleon_cli_main.py +++ b/software/script/chameleon_cli_main.py @@ -87,6 +87,15 @@ class ChameleonCLI: 'help': "Emulation tag slot.", }, 'dfu': new_uint(chameleon_cli_unit.HWDFU, "Restart application to bootloader mode(Not yet implement dfu)."), + 'settings': { + 'animation': { + 'get': new_uint(chameleon_cli_unit.HWSettingsAnimationGet, "Get current animation mode value"), + 'set': new_uint(chameleon_cli_unit.HWSettingsAnimationSet, "Change chameleon animation mode"), + 'help': 'Manage wake-up and sleep animation mode' + }, + 'store': new_uint(chameleon_cli_unit.HWSettingsStore, "Store current settings to flash"), + 'help': "Chameleon settings management" + }, 'help': "hardware controller", }, 'hf': { diff --git a/software/script/chameleon_cli_unit.py b/software/script/chameleon_cli_unit.py index 4cb0ded..0654743 100644 --- a/software/script/chameleon_cli_unit.py +++ b/software/script/chameleon_cli_unit.py @@ -994,3 +994,41 @@ class HWDFU(DeviceRequiredUnit): print(" - Enter success @.@~") # let time for comm thread to send dfu cmd and close port time.sleep(0.1) + +class HWSettingsAnimationGet(DeviceRequiredUnit): + def args_parser(self) -> ArgumentParserNoExit or None: + return None + def on_exec(self, args: argparse.Namespace): + resp: chameleon_com.Response = self.cmd_standard.get_settings_animation() + if resp.data[0] == 0: + print("Full animation") + elif resp.data[0] == 1: + print("Minimal animation") + elif resp.data[0] == 2: + print("No animation") + else: + print("Unknown setting value, something failed.") + +class HWSettingsAnimationSet(DeviceRequiredUnit): + def args_parser(self) -> ArgumentParserNoExit or None: + parser = ArgumentParserNoExit() + parser.add_argument('-m', '--mode', type=int, required=True, help="0 is full (default), 1 is minimal (only single pass on button wakeup), 2 is none", choices=[0, 1, 2]) + return None + + def on_exec(self, args: argparse.Namespace): + mode = args.mode + self.cmd_standard.set_settings_animation(mode) + print("Animation mode change success. Do not forget to store your settings in flash!") + + +class HWSettingsStore(DeviceRequiredUnit): + def args_parser(self) -> ArgumentParserNoExit or None: + return None + + def on_exec(self, args: argparse.Namespace): + print("Storing settings...") + resp: chameleon_com.Response = self.cmd_standard.store_settings() + if resp.status == chameleon_status.Device.STATUS_DEVICE_SUCCESS: + print(" - Store success @.@~") + else: + print(" - Store failed") diff --git a/software/script/chameleon_cmd.py b/software/script/chameleon_cmd.py index 0f793d5..924ff33 100644 --- a/software/script/chameleon_cmd.py +++ b/software/script/chameleon_cmd.py @@ -20,6 +20,10 @@ DATA_CMD_ENTER_BOOTLOADER = 1010 DATA_CMD_GET_DEVICE_CHIP_ID = 1011 DATA_CMD_GET_DEVICE_ADDRESS = 1012 +DATA_CMD_SAVE_SETTINGS = 1013 +DATA_CMD_SET_ANIMATION_MODE = 1014 +DATA_CMD_GET_ANIMATION_MODE = 1015 + DATA_CMD_SCAN_14A_TAG = 2000 DATA_CMD_MF1_SUPPORT_DETECT = 2001 DATA_CMD_MF1_NT_LEVEL_DETECT = 2002 @@ -424,6 +428,24 @@ class BaseChameleonCMD: :return: """ return self.device.send_cmd_auto(DATA_CMD_ENTER_BOOTLOADER, 0x00, close=True) + + def get_settings_animation(self): + """ + Get animation mode value + """ + return self.device.send_cmd_sync(DATA_CMD_GET_ANIMATION_MODE, 0x00, None) + + def set_settings_animation(self, value: int): + """ + Set animation mode value + """ + return self.device.send_cmd_sync(DATA_CMD_SET_ANIMATION_MODE, 0x00, bytearray([value])) + + def store_settings(self): + """ + Store settings to flash memory + """ + return self.device.send_cmd_sync(DATA_CMD_SAVE_SETTINGS, 0x00) class NegativeResponseError(Exception): diff --git a/software/script/chameleon_status.py b/software/script/chameleon_status.py index bab7cde..675aaea 100644 --- a/software/script/chameleon_status.py +++ b/software/script/chameleon_status.py @@ -41,6 +41,8 @@ class Device(metaclass=MetaDevice): STATUS_INVALID_CMD = 0x67 # 无效的指令 STATUS_DEVICE_SUCCESS = 0x68 # 设备相关操作成功执行 STATUS_NOT_IMPLEMENTED = 0x69 # 调用了某些未实现的操作,属于开发者遗漏的错误 + STATUS_FLASH_WRITE_FAIL = 0x70 # flash写入失败 + STATUS_FLASH_READ_FAIL = 0x71 # flash读取失败 message = { @@ -68,4 +70,6 @@ message = { Device.STATUS_INVALID_CMD : "API request fail, cmd invalid", Device.STATUS_DEVICE_SUCCESS : "Device operation succeeded", Device.STATUS_NOT_IMPLEMENTED : "Some api not implemented", + Device.STATUS_FLASH_WRITE_FAIL : "Flash write failed", + Device.STATUS_FLASH_READ_FAIL : "Flash read failed" } From 85b2fb3d8ace6f828548693de304e39de07157b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Szyma=C5=84ski?= Date: Thu, 10 Aug 2023 22:59:00 +0200 Subject: [PATCH 02/16] Upgrade command parser --- software/script/chameleon_cli_main.py | 5 +++-- software/script/chameleon_cli_unit.py | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/software/script/chameleon_cli_main.py b/software/script/chameleon_cli_main.py index fe23a4e..212fa34 100755 --- a/software/script/chameleon_cli_main.py +++ b/software/script/chameleon_cli_main.py @@ -152,14 +152,15 @@ class ChameleonCLI: cmds = cmd_str.split(" ") cmd_maps: dict or types.FunctionType = self.cmd_maps cmd_end = "" + cmd_end_position = 0 for cmd in cmds: if cmd in cmd_maps: # CMD found in map, we can continue find next cmd_maps = cmd_maps[cmd] cmd_end = cmd + cmd_end_position += len(cmd) + 1 else: # CMD not found break - cmd_end_position = cmd_str.index(cmd_end) + len(cmd_end) + 1 - return cmd_maps, (cmd_str[:cmd_end_position], cmd_str[cmd_end_position:]) + return cmd_maps, (cmd_str[:cmd_end_position - 1], cmd_str[cmd_end_position:]) def startCLI(self): """ diff --git a/software/script/chameleon_cli_unit.py b/software/script/chameleon_cli_unit.py index 0654743..aec53f8 100644 --- a/software/script/chameleon_cli_unit.py +++ b/software/script/chameleon_cli_unit.py @@ -1013,7 +1013,7 @@ class HWSettingsAnimationSet(DeviceRequiredUnit): def args_parser(self) -> ArgumentParserNoExit or None: parser = ArgumentParserNoExit() parser.add_argument('-m', '--mode', type=int, required=True, help="0 is full (default), 1 is minimal (only single pass on button wakeup), 2 is none", choices=[0, 1, 2]) - return None + return parser def on_exec(self, args: argparse.Namespace): mode = args.mode From 166faaeee7cf574596b44f259fe351e69b73d2d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Szyma=C5=84ski?= Date: Thu, 10 Aug 2023 23:04:39 +0200 Subject: [PATCH 03/16] Fix wrong storage space --- firmware/application/src/settings.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firmware/application/src/settings.c b/firmware/application/src/settings.c index 1dc03f5..52db9bf 100644 --- a/firmware/application/src/settings.c +++ b/firmware/application/src/settings.c @@ -34,7 +34,7 @@ uint8_t settings_save_config(void) calc_14a_crc_lut((uint8_t *)&config, sizeof(config), (uint8_t *)&new_calc_crc); if (new_calc_crc != m_config_crc) { // Before saving, make sure that the configuration has changed NRF_LOG_INFO("Save tag slot config start."); - bool ret = fds_write_sync(FDS_CONFIG_RECORD_FILE_ID, FDS_CONFIG_RECORD_FILE_KEY, sizeof(config) / 4, (uint8_t *)&config); + bool ret = fds_write_sync(FDS_SETTINGS_ID, FDS_SETTINGS_KEY, sizeof(config) / 4, (uint8_t *)&config); if (ret) { NRF_LOG_INFO("Save tag slot config success."); m_config_crc = new_calc_crc; // store new CRC so we know that we've updated the configuration From e916e10c66286f2a65e42c3e6006e919f5bae70a Mon Sep 17 00:00:00 2001 From: DXL <64101226@qq.com> Date: Fri, 11 Aug 2023 22:24:57 +0800 Subject: [PATCH 04/16] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 124db27..d46f334 100644 --- a/README.md +++ b/README.md @@ -39,6 +39,7 @@ Downloading a GUI https://www.youtube.com/watch?v=rHH7iqbX3nY Link to the GUI + https://github.com/GameTec-live/ChameleonUltraGUI # Hardware Pictures From 83811861cc160561ec011643257a0fcc8e63f20c Mon Sep 17 00:00:00 2001 From: Nemanja Nedeljkovic Date: Fri, 11 Aug 2023 18:01:02 +0200 Subject: [PATCH 05/16] Add git version command --- firmware/Makefile.defs | 4 ++++ firmware/application/Makefile | 3 +++ firmware/application/src/app_cmd.c | 8 ++++++++ firmware/application/src/data_cmd.h | 1 + 4 files changed, 16 insertions(+) diff --git a/firmware/Makefile.defs b/firmware/Makefile.defs index 89fec0a..7023b1d 100644 --- a/firmware/Makefile.defs +++ b/firmware/Makefile.defs @@ -22,4 +22,8 @@ LD_DIR := $(SRC_COMMON) CHAMELEON_ULTRA := ultra CHAMELEON_LITE := lite # What device is it? + CURRENT_DEVICE_TYPE ?= ${CHAMELEON_ULTRA} + +# Versioning information +GIT_VERSION := "$(shell git describe --abbrev=7 --dirty --always --tags)" diff --git a/firmware/application/Makefile b/firmware/application/Makefile index f248a1a..9ca868a 100644 --- a/firmware/application/Makefile +++ b/firmware/application/Makefile @@ -311,6 +311,9 @@ CFLAGS += -mfloat-abi=hard -mfpu=fpv4-sp-d16 CFLAGS += -ffunction-sections -fdata-sections -fno-strict-aliasing CFLAGS += -fno-builtin -fshort-enums +# Versioning flags +CFLAGS += -DGIT_VERSION=\"$(GIT_VERSION)\" + # C++ flags common to all targets CXXFLAGS += $(OPT) # Assembler flags common to all targets diff --git a/firmware/application/src/app_cmd.c b/firmware/application/src/app_cmd.c index 2eb7559..c33f50d 100644 --- a/firmware/application/src/app_cmd.c +++ b/firmware/application/src/app_cmd.c @@ -27,6 +27,13 @@ data_frame_tx_t* cmd_processor_get_version(uint16_t cmd, uint16_t status, uint16 return data_frame_make(cmd, status, 2, (uint8_t*)&version); } + +data_frame_tx_t* cmd_processor_get_git_version(uint16_t cmd, uint16_t status, uint16_t length, uint8_t *data) { + uint32_t* version = (uint32_t*)GIT_VERSION; + return data_frame_make(cmd, status, 7, (uint8_t*)version); +} + + data_frame_tx_t* cmd_processor_change_device_mode(uint16_t cmd, uint16_t status, uint16_t length, uint8_t *data) { #if defined(PROJECT_CHAMELEON_ULTRA) if (length == 1) { @@ -524,6 +531,7 @@ static cmd_data_map_t m_data_cmd_map[] = { { DATA_CMD_ENTER_BOOTLOADER, NULL, cmd_processor_enter_bootloader, NULL }, { DATA_CMD_GET_DEVICE_CHIP_ID, NULL, cmd_processor_get_device_chip_id, NULL }, { DATA_CMD_GET_DEVICE_ADDRESS, NULL, cmd_processor_get_device_address, NULL }, + { DATA_CMD_GET_GIT_VERSION, NULL, cmd_processor_get_git_version, NULL }, #if defined(PROJECT_CHAMELEON_ULTRA) diff --git a/firmware/application/src/data_cmd.h b/firmware/application/src/data_cmd.h index e5437ae..9a5e8c8 100644 --- a/firmware/application/src/data_cmd.h +++ b/firmware/application/src/data_cmd.h @@ -20,6 +20,7 @@ #define DATA_CMD_ENTER_BOOTLOADER (1010) #define DATA_CMD_GET_DEVICE_CHIP_ID (1011) #define DATA_CMD_GET_DEVICE_ADDRESS (1012) +#define DATA_CMD_GET_GIT_VERSION (1013) // // ****************************************************************** From ee8990aacd75849b64c1551b8344a4b6f835ab16 Mon Sep 17 00:00:00 2001 From: Augusto Zanellato Date: Fri, 11 Aug 2023 18:55:29 +0200 Subject: [PATCH 06/16] fw git version fixes, client support Fix git version string length handling Add git to docker fw-builder image Add git version command to client Add client support --- firmware/Dockerfile | 3 ++- firmware/application/src/app_cmd.c | 3 +-- software/script/chameleon_cli_main.py | 1 + software/script/chameleon_cli_unit.py | 10 ++++++++++ software/script/chameleon_cmd.py | 6 +++++- 5 files changed, 19 insertions(+), 4 deletions(-) diff --git a/firmware/Dockerfile b/firmware/Dockerfile index bc38922..1646b91 100644 --- a/firmware/Dockerfile +++ b/firmware/Dockerfile @@ -6,7 +6,8 @@ ARG NRF_CLT_URL=https://nsscprodmedia.blob.core.windows.net/prod/software-and-ot RUN set -xe; \ DEBIAN_FRONTEND=noninteractive; \ apt update -q; \ - apt install -qy --no-install-recommends ca-certificates curl xz-utils make; \ + apt install -qy --no-install-recommends ca-certificates curl xz-utils make git; \ + git config --global --add safe.directory /workdir; \ curl -sLo /usr/bin/nrfutil https://developer.nordicsemi.com/.pc-tools/nrfutil/x64-linux/nrfutil; \ curl -sLo /tmp/nrf-clt.deb $NRF_CLT_URL; \ apt install -qfy /tmp/nrf-clt.deb; \ diff --git a/firmware/application/src/app_cmd.c b/firmware/application/src/app_cmd.c index c33f50d..ef48978 100644 --- a/firmware/application/src/app_cmd.c +++ b/firmware/application/src/app_cmd.c @@ -29,8 +29,7 @@ data_frame_tx_t* cmd_processor_get_version(uint16_t cmd, uint16_t status, uint16 data_frame_tx_t* cmd_processor_get_git_version(uint16_t cmd, uint16_t status, uint16_t length, uint8_t *data) { - uint32_t* version = (uint32_t*)GIT_VERSION; - return data_frame_make(cmd, status, 7, (uint8_t*)version); + return data_frame_make(cmd, status, strlen(GIT_VERSION), (uint8_t*)GIT_VERSION); } diff --git a/software/script/chameleon_cli_main.py b/software/script/chameleon_cli_main.py index 83fba87..53289bf 100755 --- a/software/script/chameleon_cli_main.py +++ b/software/script/chameleon_cli_main.py @@ -86,6 +86,7 @@ class ChameleonCLI: 'openall': new_uint(chameleon_cli_unit.HWSlotOpenAll, "Open all slot and set to default data"), 'help': "Emulation tag slot.", }, + 'version': new_uint(chameleon_cli_unit.HWVersion, "Get current device firmware version"), 'dfu': new_uint(chameleon_cli_unit.HWDFU, "Restart application to bootloader mode(Not yet implement dfu)."), 'help': "hardware controller", }, diff --git a/software/script/chameleon_cli_unit.py b/software/script/chameleon_cli_unit.py index 4cb0ded..0a8aabe 100644 --- a/software/script/chameleon_cli_unit.py +++ b/software/script/chameleon_cli_unit.py @@ -253,6 +253,16 @@ class HWAddressGet(DeviceRequiredUnit): def on_exec(self, args: argparse.Namespace): print(f' - Device address: ' + self.cmd_positive.get_device_address()) +class HWVersion(DeviceRequiredUnit): + + def args_parser(self) -> ArgumentParserNoExit or None: + return None + + def on_exec(self, args: argparse.Namespace): + fw_version_int = self.cmd_positive.get_firmware_version() + fw_version = f'v{fw_version_int // 256}.{fw_version_int % 256}' + git_version = self.cmd_positive.get_git_version() + print(f' - Version: {fw_version} ({git_version})') class HF14AScan(ReaderRequiredUint): def args_parser(self) -> ArgumentParserNoExit or None: diff --git a/software/script/chameleon_cmd.py b/software/script/chameleon_cmd.py index 0f793d5..cb32228 100644 --- a/software/script/chameleon_cmd.py +++ b/software/script/chameleon_cmd.py @@ -19,6 +19,7 @@ DATA_CMD_SLOT_DATA_CONFIG_SAVE = 1009 DATA_CMD_ENTER_BOOTLOADER = 1010 DATA_CMD_GET_DEVICE_CHIP_ID = 1011 DATA_CMD_GET_DEVICE_ADDRESS = 1012 +DATA_CMD_GET_GIT_VERSION = 1013 DATA_CMD_SCAN_14A_TAG = 2000 DATA_CMD_MF1_SUPPORT_DETECT = 2001 @@ -108,7 +109,10 @@ class BaseChameleonCMD: """ resp = self.device.send_cmd_sync(DATA_CMD_GET_DEVICE_ADDRESS, 0x00, None) return resp.data[::-1].hex() - + + def get_git_version(self) -> str: + resp = self.device.send_cmd_sync(DATA_CMD_GET_GIT_VERSION, 0x00, None) + return resp.data.decode('utf-8') def is_reader_device_mode(self) -> bool: """ From 6e81b5917e58f9bfe8ecb99989421671e1433eca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Szyma=C5=84ski?= Date: Tue, 15 Aug 2023 22:56:53 +0200 Subject: [PATCH 07/16] Add version field, make it bitfield struct --- firmware/application/src/rfid/nfctag/tag_emulation.h | 3 +-- firmware/application/src/settings.c | 5 ++--- firmware/application/src/settings.h | 12 +++++++----- firmware/common/utils.h | 7 +++++++ 4 files changed, 17 insertions(+), 10 deletions(-) create mode 100644 firmware/common/utils.h diff --git a/firmware/application/src/rfid/nfctag/tag_emulation.h b/firmware/application/src/rfid/nfctag/tag_emulation.h index 1be4573..789424f 100644 --- a/firmware/application/src/rfid/nfctag/tag_emulation.h +++ b/firmware/application/src/rfid/nfctag/tag_emulation.h @@ -5,12 +5,11 @@ #include #include +#include "utils.h" #include "tag_base_type.h" // 最多八张卡槽 #define TAG_MAX_SLOT_NUM 8 -// u32 size align. -#define ALIGN_U32 __attribute__((aligned(4))) extern bool g_is_tag_emulating; diff --git a/firmware/application/src/settings.c b/firmware/application/src/settings.c index 52db9bf..73cd281 100644 --- a/firmware/application/src/settings.c +++ b/firmware/application/src/settings.c @@ -53,11 +53,10 @@ uint8_t settings_save_config(void) uint8_t settings_get_animation_config() { - return config & 0x3; + return config.animation_config; } void settings_set_animation_config(uint8_t value) { - config &= ~(0x3); - config |= value; + config.animation_config = value; } diff --git a/firmware/application/src/settings.h b/firmware/application/src/settings.h index a42baa3..b0dcadd 100644 --- a/firmware/application/src/settings.h +++ b/firmware/application/src/settings.h @@ -3,15 +3,17 @@ #include +#include "utils.h" + #define SETTINGS_ANIMATION_FULL 0 #define SETTINGS_ANIMATION_MINIMAL 1 #define SETTINGS_ANIMATION_NONE 2 -/* - * bits [0-1]: animation config - * bits [2-31]: reserved - */ -typedef uint32_t settings_data_t; + +typedef struct ALIGN_U32 { + uint16_t version; + uint16_t animation_config : 2; +} settings_data_t; void settings_load_config(void); uint8_t settings_save_config(void); diff --git a/firmware/common/utils.h b/firmware/common/utils.h new file mode 100644 index 0000000..00ecf46 --- /dev/null +++ b/firmware/common/utils.h @@ -0,0 +1,7 @@ +#ifndef UTILS_H_ +#define UTILS_H_ + +// u32 size align. +#define ALIGN_U32 __attribute__((aligned(4))) + +#endif \ No newline at end of file From 2ed37d9c2a709b69d62dda6a0d86c50b0604308f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Szyma=C5=84ski?= Date: Wed, 16 Aug 2023 01:17:45 +0200 Subject: [PATCH 08/16] Fix log messages --- firmware/application/src/settings.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/firmware/application/src/settings.c b/firmware/application/src/settings.c index 73cd281..eba29b5 100644 --- a/firmware/application/src/settings.c +++ b/firmware/application/src/settings.c @@ -33,19 +33,19 @@ uint8_t settings_save_config(void) uint16_t new_calc_crc; calc_14a_crc_lut((uint8_t *)&config, sizeof(config), (uint8_t *)&new_calc_crc); if (new_calc_crc != m_config_crc) { // Before saving, make sure that the configuration has changed - NRF_LOG_INFO("Save tag slot config start."); + NRF_LOG_INFO("Save config start."); bool ret = fds_write_sync(FDS_SETTINGS_ID, FDS_SETTINGS_KEY, sizeof(config) / 4, (uint8_t *)&config); if (ret) { - NRF_LOG_INFO("Save tag slot config success."); + NRF_LOG_INFO("Save config success."); m_config_crc = new_calc_crc; // store new CRC so we know that we've updated the configuration } else { - NRF_LOG_ERROR("Save tag slot config error."); + NRF_LOG_ERROR("Save config error."); return STATUS_FLASH_WRITE_FAIL; } } else { - NRF_LOG_INFO("Tag slot config no change."); + NRF_LOG_INFO("Config no change."); } return STATUS_DEVICE_SUCCESS; From 707136a241868def2b264e07546aa0045155128f Mon Sep 17 00:00:00 2001 From: Augusto Zanellato Date: Wed, 16 Aug 2023 18:04:06 +0200 Subject: [PATCH 09/16] Add settings init, reset and migration logic Align settings size to uint32_t Add 78 reserved bits to settings Use an enum for animation mode --- firmware/application/src/app_cmd.c | 7 +++ firmware/application/src/app_main.c | 9 ++-- firmware/application/src/data_cmd.h | 5 +- firmware/application/src/settings.c | 71 ++++++++++++++++++++++++--- firmware/application/src/settings.h | 20 +++++--- software/script/chameleon_cli_main.py | 1 + software/script/chameleon_cli_unit.py | 12 +++++ software/script/chameleon_cmd.py | 11 ++++- 8 files changed, 113 insertions(+), 23 deletions(-) diff --git a/firmware/application/src/app_cmd.c b/firmware/application/src/app_cmd.c index 27e2e52..4ea39a0 100644 --- a/firmware/application/src/app_cmd.c +++ b/firmware/application/src/app_cmd.c @@ -86,6 +86,12 @@ data_frame_tx_t* cmd_processor_save_settings(uint16_t cmd, uint16_t status, uint return data_frame_make(cmd, status, 0, NULL); } +data_frame_tx_t* cmd_processor_reset_settings(uint16_t cmd, uint16_t status, uint16_t length, uint8_t *data) { + settings_init_config(); + status = settings_save_config(); + return data_frame_make(cmd, status, 0, NULL); +} + data_frame_tx_t* cmd_processor_set_animation_mode(uint16_t cmd, uint16_t status, uint16_t length, uint8_t *data) { if (length == 1) { settings_set_animation_config(data[0]); @@ -546,6 +552,7 @@ static cmd_data_map_t m_data_cmd_map[] = { { DATA_CMD_GET_DEVICE_CHIP_ID, NULL, cmd_processor_get_device_chip_id, NULL }, { DATA_CMD_GET_DEVICE_ADDRESS, NULL, cmd_processor_get_device_address, NULL }, { DATA_CMD_SAVE_SETTINGS, NULL, cmd_processor_save_settings, NULL }, + { DATA_CMD_RESET_SETTINGS, NULL, cmd_processor_reset_settings, NULL }, { DATA_CMD_SET_ANIMATION_MODE, NULL, cmd_processor_set_animation_mode, NULL }, { DATA_CMD_GET_ANIMATION_MODE, NULL, cmd_processor_get_animation_mode, NULL }, diff --git a/firmware/application/src/app_main.c b/firmware/application/src/app_main.c index 387bd5e..99a016b 100644 --- a/firmware/application/src/app_main.c +++ b/firmware/application/src/app_main.c @@ -222,7 +222,7 @@ static void system_off_enter(void) { nrf_gpio_pin_clear(p_led_array[i]); } uint8_t animation_config = settings_get_animation_config(); - if (animation_config == SETTINGS_ANIMATION_FULL) { + if (animation_config == SettingsAnimationModeFull) { uint8_t slot = tag_emulation_get_slot(); // Power off animation uint8_t dir = slot > 3 ? 1 : 0; @@ -352,13 +352,12 @@ static void check_wakeup_src(void) { // Button wake-up boot animation uint8_t animation_config = settings_get_animation_config(); - if (animation_config == SETTINGS_ANIMATION_FULL) + if (animation_config == SettingsAnimationModeFull) { ledblink2(color, !dir, 11); ledblink2(color, dir, 11); ledblink2(color, !dir, dir ? slot : 7 - slot); - } - else if (animation_config == SETTINGS_ANIMATION_MINIMAL) { + } else if (animation_config == SettingsAnimationModeMinimal) { ledblink2(color, !dir, dir ? slot : 7 - slot); } @@ -388,7 +387,7 @@ static void check_wakeup_src(void) { TAG_FIELD_LED_ON(); uint8_t animation_config = settings_get_animation_config(); - if (animation_config == SETTINGS_ANIMATION_FULL) { + if (animation_config == SettingsAnimationModeFull) { // In the case of field wake-up, only one round of RGB is swept as the power-on animation ledblink2(color, !dir, dir ? slot : 7 - slot); } diff --git a/firmware/application/src/data_cmd.h b/firmware/application/src/data_cmd.h index 89284f2..a653574 100644 --- a/firmware/application/src/data_cmd.h +++ b/firmware/application/src/data_cmd.h @@ -21,8 +21,9 @@ #define DATA_CMD_GET_DEVICE_CHIP_ID (1011) #define DATA_CMD_GET_DEVICE_ADDRESS (1012) #define DATA_CMD_SAVE_SETTINGS (1013) -#define DATA_CMD_SET_ANIMATION_MODE (1014) -#define DATA_CMD_GET_ANIMATION_MODE (1015) +#define DATA_CMD_RESET_SETTINGS (1014) +#define DATA_CMD_SET_ANIMATION_MODE (1015) +#define DATA_CMD_GET_ANIMATION_MODE (1016) // // ****************************************************************** diff --git a/firmware/application/src/settings.c b/firmware/application/src/settings.c index eba29b5..944060c 100644 --- a/firmware/application/src/settings.c +++ b/firmware/application/src/settings.c @@ -15,29 +15,84 @@ static settings_data_t config; static uint16_t m_config_crc; +static void update_config_crc(void) +{ + calc_14a_crc_lut((uint8_t *)&config, sizeof(config), (uint8_t *)&m_config_crc); +} + +static bool config_did_change(void) +{ + uint16_t new_calc_crc; + calc_14a_crc_lut((uint8_t *)&config, sizeof(config), (uint8_t *)&new_calc_crc); + return new_calc_crc != m_config_crc; +} + +void settings_init_config(void) +{ + config.version = SETTINGS_CURRENT_VERSION; + config.animation_config = SettingsAnimationModeFull; +} + +void settings_migrate(void) +{ + switch (config.version) { + case 0: + NRF_LOG_ERROR("Unexpected configuration version detected!"); + settings_init_config(); + break; + /* + * When needed migrations can be implemented like this: + * + * case 1: + * config->new_field = some_default_value; + * case 2: + * config->another_new_field = some_default_value; + * case 3: + * config->another_new_field = some_default_value; + * break; + * + * Note that the `break` statement should only be used on the last migration step, all the previous steps must fall + * through to the next case. + */ + default: + NRF_LOG_ERROR("Unsupported configuration migration attempted! (%d -> %d)", config.version, SETTINGS_CURRENT_VERSION); + break; + } +} + void settings_load_config(void) { bool ret = fds_read_sync(FDS_SETTINGS_ID, FDS_SETTINGS_KEY, sizeof(config), (uint8_t *)&config); if (ret) { - // After the reading is complete, we first save a copy of the current CRC, which can be used as a reference for comparison of changes when saving later - calc_14a_crc_lut((uint8_t *)&config, sizeof(config), (uint8_t *)&m_config_crc); NRF_LOG_INFO("Load config done."); + // After the reading is complete, we first save a copy of the current CRC, which can be used as a reference for comparison of changes when saving later + update_config_crc(); } else { - NRF_LOG_INFO("config no exists."); + NRF_LOG_WARNING("Config does not exist, loading default values..."); + settings_init_config(); + } + if (config.version > SETTINGS_CURRENT_VERSION) { + NRF_LOG_WARNING("Config version %d is greater than current firmware supports (%d). Default config will be loaded.", config.version, SETTINGS_CURRENT_VERSION); + settings_init_config(); + } + if (config.version < SETTINGS_CURRENT_VERSION) { + NRF_LOG_INFO("Config version (%d) is not latest, performing migration to %d", config.version, SETTINGS_CURRENT_VERSION); + settings_migrate(); + } + if (config_did_change()) { + settings_save_config(); } } uint8_t settings_save_config(void) { // We are saving the configuration, we need to calculate the crc code of the current configuration to judge whether the following data is updated - uint16_t new_calc_crc; - calc_14a_crc_lut((uint8_t *)&config, sizeof(config), (uint8_t *)&new_calc_crc); - if (new_calc_crc != m_config_crc) { // Before saving, make sure that the configuration has changed + if (config_did_change()) { // Before saving, make sure that the configuration has changed NRF_LOG_INFO("Save config start."); bool ret = fds_write_sync(FDS_SETTINGS_ID, FDS_SETTINGS_KEY, sizeof(config) / 4, (uint8_t *)&config); if (ret) { NRF_LOG_INFO("Save config success."); - m_config_crc = new_calc_crc; // store new CRC so we know that we've updated the configuration + update_config_crc(); } else { @@ -45,7 +100,7 @@ uint8_t settings_save_config(void) return STATUS_FLASH_WRITE_FAIL; } } else { - NRF_LOG_INFO("Config no change."); + NRF_LOG_INFO("Config did not change."); } return STATUS_DEVICE_SUCCESS; diff --git a/firmware/application/src/settings.h b/firmware/application/src/settings.h index b0dcadd..d8cf545 100644 --- a/firmware/application/src/settings.h +++ b/firmware/application/src/settings.h @@ -5,19 +5,27 @@ #include "utils.h" -#define SETTINGS_ANIMATION_FULL 0 -#define SETTINGS_ANIMATION_MINIMAL 1 -#define SETTINGS_ANIMATION_NONE 2 +#define SETTINGS_CURRENT_VERSION 1 +typedef enum { + SettingsAnimationModeFull = 0, + SettingsAnimationModeMinimal = 1, + SettingsAnimationModeNone = 2, +} settings_animation_mode_t; typedef struct ALIGN_U32 { uint16_t version; - uint16_t animation_config : 2; + uint8_t animation_config : 2; + uint16_t reserved0 : 14; + uint32_t reserved1; + uint32_t reserved2; } settings_data_t; +void settings_init_config(void); +void settings_migrate(void); void settings_load_config(void); uint8_t settings_save_config(void); -uint8_t settings_get_animation_config(); +uint8_t settings_get_animation_config(void); void settings_set_animation_config(uint8_t value); -#endif \ No newline at end of file +#endif diff --git a/software/script/chameleon_cli_main.py b/software/script/chameleon_cli_main.py index 212fa34..c3bc0aa 100755 --- a/software/script/chameleon_cli_main.py +++ b/software/script/chameleon_cli_main.py @@ -94,6 +94,7 @@ class ChameleonCLI: 'help': 'Manage wake-up and sleep animation mode' }, 'store': new_uint(chameleon_cli_unit.HWSettingsStore, "Store current settings to flash"), + 'reset': new_uint(chameleon_cli_unit.HWSettingsReset, "Reset settings to default values"), 'help': "Chameleon settings management" }, 'help': "hardware controller", diff --git a/software/script/chameleon_cli_unit.py b/software/script/chameleon_cli_unit.py index aec53f8..378c922 100644 --- a/software/script/chameleon_cli_unit.py +++ b/software/script/chameleon_cli_unit.py @@ -1032,3 +1032,15 @@ class HWSettingsStore(DeviceRequiredUnit): print(" - Store success @.@~") else: print(" - Store failed") + +class HWSettingsReset(DeviceRequiredUnit): + def args_parser(self) -> ArgumentParserNoExit or None: + return None + + def on_exec(self, args: argparse.Namespace): + print("Initializing settings...") + resp: chameleon_com.Response = self.cmd_standard.reset_settings() + if resp.status == chameleon_status.Device.STATUS_DEVICE_SUCCESS: + print(" - Reset success @.@~") + else: + print(" - Reset failed") diff --git a/software/script/chameleon_cmd.py b/software/script/chameleon_cmd.py index 924ff33..ab9e94a 100644 --- a/software/script/chameleon_cmd.py +++ b/software/script/chameleon_cmd.py @@ -21,8 +21,9 @@ DATA_CMD_GET_DEVICE_CHIP_ID = 1011 DATA_CMD_GET_DEVICE_ADDRESS = 1012 DATA_CMD_SAVE_SETTINGS = 1013 -DATA_CMD_SET_ANIMATION_MODE = 1014 -DATA_CMD_GET_ANIMATION_MODE = 1015 +DATA_CMD_RESET_SETTINGS = 1014 +DATA_CMD_SET_ANIMATION_MODE = 1015 +DATA_CMD_GET_ANIMATION_MODE = 1016 DATA_CMD_SCAN_14A_TAG = 2000 DATA_CMD_MF1_SUPPORT_DETECT = 2001 @@ -441,6 +442,12 @@ class BaseChameleonCMD: """ return self.device.send_cmd_sync(DATA_CMD_SET_ANIMATION_MODE, 0x00, bytearray([value])) + def reset_settings(self): + """ + Reset settings stored in flash memory + """ + return self.device.send_cmd_sync(DATA_CMD_RESET_SETTINGS, 0x00) + def store_settings(self): """ Store settings to flash memory From b0233538b0c59d989306bc38a8567e69b46947c1 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 16 Aug 2023 20:14:57 +0200 Subject: [PATCH 10/16] little fix for mode 2 to light up the slot LED on button press --- firmware/application/src/app_main.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/firmware/application/src/app_main.c b/firmware/application/src/app_main.c index 99a016b..1e92c1b 100644 --- a/firmware/application/src/app_main.c +++ b/firmware/application/src/app_main.c @@ -359,6 +359,8 @@ static void check_wakeup_src(void) { ledblink2(color, !dir, dir ? slot : 7 - slot); } else if (animation_config == SettingsAnimationModeMinimal) { ledblink2(color, !dir, dir ? slot : 7 - slot); + } else { + set_slot_light_color(color); } // The indicator of the current card slot lights up at the end of the animation From e3e6b63117af1586fb1b5a2389e3adb1fbd6d52b Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 16 Aug 2023 19:07:00 +0200 Subject: [PATCH 11/16] Force tag_specific_type_t enum to be 32b and allocate banks so size and mapping won't change when we add new types --- firmware/application/src/rfid/nfctag/tag_base_type.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/firmware/application/src/rfid/nfctag/tag_base_type.h b/firmware/application/src/rfid/nfctag/tag_base_type.h index 224b1e2..0f28bd7 100644 --- a/firmware/application/src/rfid/nfctag/tag_base_type.h +++ b/firmware/application/src/rfid/nfctag/tag_base_type.h @@ -22,14 +22,14 @@ typedef enum { // 特定的且必须存在的标志不存在的类型 TAG_TYPE_UNKNOWN, // 125khz(ID卡)系列 - TAG_TYPE_EM410X, + TAG_TYPE_EM410X = 0x10000, // Mifare系列 - TAG_TYPE_MIFARE_Mini, + TAG_TYPE_MIFARE_Mini = 0x20000, TAG_TYPE_MIFARE_1024, TAG_TYPE_MIFARE_2048, TAG_TYPE_MIFARE_4096, // NTAG系列 - TAG_TYPE_NTAG_213, + TAG_TYPE_NTAG_213 = 0x20100, TAG_TYPE_NTAG_215, TAG_TYPE_NTAG_216, } tag_specific_type_t; From 5afd3332bdf314901b22c604a336120c47d49a0e Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 16 Aug 2023 23:20:42 +0200 Subject: [PATCH 12/16] Suppress GCC 12 linker warnings about missing stubs --- firmware/application/Makefile | 1 + firmware/bootloader/Makefile | 1 + firmware/common/libc_nano_stubs.c | 51 +++++++++++++++++++++++++++++++ 3 files changed, 53 insertions(+) create mode 100644 firmware/common/libc_nano_stubs.c diff --git a/firmware/application/Makefile b/firmware/application/Makefile index f248a1a..6027cd6 100644 --- a/firmware/application/Makefile +++ b/firmware/application/Makefile @@ -7,6 +7,7 @@ $(OUTPUT_DIRECTORY)/application.out: \ # Source files common to all targets SRC_FILES += \ $(SRC_COMMON)/hw_connect.c \ + $(SRC_COMMON)/libc_nano_stubs.c \ $(PROJ_DIR)/app_main.c \ $(PROJ_DIR)/app_cmd.c \ $(PROJ_DIR)/ble_main.c \ diff --git a/firmware/bootloader/Makefile b/firmware/bootloader/Makefile index 8086414..d2cdba7 100644 --- a/firmware/bootloader/Makefile +++ b/firmware/bootloader/Makefile @@ -10,6 +10,7 @@ SRC_FILES += \ $(PROJ_DIR)/main.c \ $(PROJ_DIR)/dfu_public_key.c \ $(SRC_COMMON)/hw_connect.c \ + $(SRC_COMMON)/libc_nano_stubs.c \ $(SDK_ROOT)/modules/nrfx/drivers/src/nrfx_clock.c \ $(SDK_ROOT)/modules/nrfx/drivers/src/nrfx_power.c \ $(SDK_ROOT)/modules/nrfx/drivers/src/nrfx_systick.c \ diff --git a/firmware/common/libc_nano_stubs.c b/firmware/common/libc_nano_stubs.c new file mode 100644 index 0000000..0558de5 --- /dev/null +++ b/firmware/common/libc_nano_stubs.c @@ -0,0 +1,51 @@ +/* +Flag --specs=nano.specs forces linking against libc_nano which contains .gnu.warnings since GCC 11.3 like: + arm-gnu-toolchain-12.2.rel1-x86_64-arm-none-eabi/arm-none-eabi/lib/thumb/v7e-m+fp/hard/libc_nano.a(libc_a-closer.o): in function `_close_r': + closer.c:(.text._close_r+0xc): warning: _close is not implemented and will always fail +So we are providing stubs to suppress these warnings +See also https://stackoverflow.com/questions/73742774/gcc-arm-none-eabi-11-3-is-not-implemented-and-will-always-fail +*/ + +#include +#include +#undef errno +extern int errno; + +int _close(int file) { + errno = EINVAL; + return -1; +} + +int _fstat(int file, struct stat *st) { + errno = EINVAL; + return -1; +} + +int _getpid(void) { + return 1; +} + +int _isatty(int file) { + errno = EINVAL; + return 0; +} + +int _kill(int pid, int sig) { + errno = EINVAL; + return -1; +} + +int _lseek(int file, int ptr, int dir) { + errno = EINVAL; + return -1; +} + +int _read(int file, char *ptr, int len) { + errno = EINVAL; + return -1; +} + +int _write(int file, char *ptr, int len) { + errno = EINVAL; + return -1; +} From 92a3f0966f1b12972479661524873d651d1baa9b Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Wed, 16 Aug 2023 23:21:13 +0200 Subject: [PATCH 13/16] suppress GCC warnings in nRF SDK and restore -Warray-bounds and -Wsizeof-array-div --- firmware/application/Makefile | 9 ++++----- firmware/bootloader/Makefile | 11 +++++++++-- .../libraries/experimental_section_vars/nrf_section.h | 2 ++ firmware/nrf52_sdk/modules/nrfx/hal/nrf_pwm.h | 4 ++++ 4 files changed, 19 insertions(+), 7 deletions(-) diff --git a/firmware/application/Makefile b/firmware/application/Makefile index 6027cd6..1cb7d19 100644 --- a/firmware/application/Makefile +++ b/firmware/application/Makefile @@ -367,14 +367,13 @@ TEMPLATE_PATH := $(SDK_ROOT)/components/toolchain/gcc include ../Makefile.defs include $(TEMPLATE_PATH)/Makefile.common -# tolerate warnings in newer gcc versions # need to be called after $(TEMPLATE_PATH)/Makefile.common CC_VERSION = $(shell $(CC) -dumpversion 2>/dev/null|sed 's/\..*//') CC_VERSION := $(or $(strip $(CC_VERSION)),0) -CFLAGS += -Wno-error=array-bounds -ifeq ($(shell expr $(CC_VERSION) \>= 12), 1) - CFLAGS += -Wno-error=sizeof-array-div -endif +# usage example: +#ifeq ($(shell expr $(CC_VERSION) \>= 12), 1) +# CFLAGS += -Wno-error=sizeof-array-div +#endif $(foreach target, $(TARGETS), $(call define_target, $(target))) diff --git a/firmware/bootloader/Makefile b/firmware/bootloader/Makefile index d2cdba7..e88f044 100644 --- a/firmware/bootloader/Makefile +++ b/firmware/bootloader/Makefile @@ -198,8 +198,6 @@ CFLAGS += -mfloat-abi=hard -mfpu=fpv4-sp-d16 # keep every function in a separate section, this allows linker to discard unused ones CFLAGS += -ffunction-sections -fdata-sections -fno-strict-aliasing CFLAGS += -fno-builtin -fshort-enums -# fix newer compilator versions -CFLAGS += -Wno-error=array-bounds # C++ flags common to all targets CXXFLAGS += $(OPT) @@ -254,6 +252,15 @@ TEMPLATE_PATH := $(SDK_ROOT)/components/toolchain/gcc include $(TEMPLATE_PATH)/Makefile.common +# tolerate warnings in newer gcc versions +# need to be called after $(TEMPLATE_PATH)/Makefile.common +CC_VERSION = $(shell $(CC) -dumpversion 2>/dev/null|sed 's/\..*//') +CC_VERSION := $(or $(strip $(CC_VERSION)),0) +ifeq ($(shell expr $(CC_VERSION) \>= 12), 1) + # avoid a couple of false warnings in nRF SDK + CFLAGS += --param=min-pagesize=0 +endif + $(foreach target, $(TARGETS), $(call define_target, $(target))) .PHONY: flash flash_softdevice erase diff --git a/firmware/nrf52_sdk/components/libraries/experimental_section_vars/nrf_section.h b/firmware/nrf52_sdk/components/libraries/experimental_section_vars/nrf_section.h index 1549930..fb0f15d 100644 --- a/firmware/nrf52_sdk/components/libraries/experimental_section_vars/nrf_section.h +++ b/firmware/nrf52_sdk/components/libraries/experimental_section_vars/nrf_section.h @@ -41,6 +41,8 @@ #define NRF_SECTION_H__ #include "nordic_common.h" +// ChameleonUltra: nRF SDK produces a number of GCC warnings due to its NRF_SECTION macros and we want to ignore them +#pragma GCC diagnostic ignored "-Warray-bounds" #ifdef __cplusplus extern "C" { diff --git a/firmware/nrf52_sdk/modules/nrfx/hal/nrf_pwm.h b/firmware/nrf52_sdk/modules/nrfx/hal/nrf_pwm.h index 35567b6..87b5cf9 100644 --- a/firmware/nrf52_sdk/modules/nrfx/hal/nrf_pwm.h +++ b/firmware/nrf52_sdk/modules/nrfx/hal/nrf_pwm.h @@ -64,6 +64,10 @@ extern "C" { /** @brief Number of channels in each PWM instance. */ #define NRF_PWM_CHANNEL_COUNT 4 +// ChameleonUltra: nRF SDK produces a wrong GCC warning as the following macro is not meant to give an array size +#if __GNUC__ >= 12 +#pragma GCC diagnostic ignored "-Wsizeof-array-div" +#endif /** * @brief Helper macro for calculating the number of 16-bit values in the specified * array of duty cycle values. From c6d95f34f7d5bedab6157417ccf96cc72d255264 Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Thu, 17 Aug 2023 00:14:11 +0200 Subject: [PATCH 14/16] Revert "Force tag_specific_type_t enum to be 32b and allocate banks so size and mapping won't change when we add new types" This reverts commit e3e6b63117af1586fb1b5a2389e3adb1fbd6d52b. --- firmware/application/src/rfid/nfctag/tag_base_type.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/firmware/application/src/rfid/nfctag/tag_base_type.h b/firmware/application/src/rfid/nfctag/tag_base_type.h index 0f28bd7..224b1e2 100644 --- a/firmware/application/src/rfid/nfctag/tag_base_type.h +++ b/firmware/application/src/rfid/nfctag/tag_base_type.h @@ -22,14 +22,14 @@ typedef enum { // 特定的且必须存在的标志不存在的类型 TAG_TYPE_UNKNOWN, // 125khz(ID卡)系列 - TAG_TYPE_EM410X = 0x10000, + TAG_TYPE_EM410X, // Mifare系列 - TAG_TYPE_MIFARE_Mini = 0x20000, + TAG_TYPE_MIFARE_Mini, TAG_TYPE_MIFARE_1024, TAG_TYPE_MIFARE_2048, TAG_TYPE_MIFARE_4096, // NTAG系列 - TAG_TYPE_NTAG_213 = 0x20100, + TAG_TYPE_NTAG_213, TAG_TYPE_NTAG_215, TAG_TYPE_NTAG_216, } tag_specific_type_t; From 997f58d0d0a6d12861eeae0150a3f7f03ba8eddb Mon Sep 17 00:00:00 2001 From: Philippe Teuwen Date: Thu, 17 Aug 2023 04:00:47 +0200 Subject: [PATCH 15/16] Fix FDS records conflicts (dumps/nicks/settings overwriting each other) --- .../src/rfid/nfctag/tag_emulation.c | 4 +- .../src/rfid/nfctag/tag_persistence.c | 29 ++++------- firmware/application/src/settings.c | 4 +- firmware/application/src/utils/fds_ids.h | 48 +++++++++++-------- 4 files changed, 41 insertions(+), 44 deletions(-) diff --git a/firmware/application/src/rfid/nfctag/tag_emulation.c b/firmware/application/src/rfid/nfctag/tag_emulation.c index 849cd03..b65da99 100644 --- a/firmware/application/src/rfid/nfctag/tag_emulation.c +++ b/firmware/application/src/rfid/nfctag/tag_emulation.c @@ -384,7 +384,7 @@ void tag_emulation_sense_switch(tag_sense_type_t type, bool enable) { */ void tag_emulation_load_config(void) { // 读取卡槽配置数据 - bool ret = fds_read_sync(FDS_CONFIG_RECORD_FILE_ID, FDS_CONFIG_RECORD_FILE_KEY, sizeof(slotConfig), (uint8_t *)&slotConfig); + bool ret = fds_read_sync(FDS_EMULATION_CONFIG_FILE_ID, FDS_EMULATION_CONFIG_RECORD_KEY, sizeof(slotConfig), (uint8_t *)&slotConfig); if (ret) { // 读取完成后,我们先保存一份当前配置的BCC,后面保存的时候可以作为变动对比的参考 calc_14a_crc_lut((uint8_t *)&slotConfig, sizeof(slotConfig), (uint8_t *)&m_slot_config_crc); @@ -403,7 +403,7 @@ void tag_emulation_save_config(void) { calc_14a_crc_lut((uint8_t *)&slotConfig, sizeof(slotConfig), (uint8_t *)&new_calc_crc); if (new_calc_crc != m_slot_config_crc) { // 在保存之前,先确保卡槽配置有变动了 NRF_LOG_INFO("Save tag slot config start."); - bool ret = fds_write_sync(FDS_CONFIG_RECORD_FILE_ID, FDS_CONFIG_RECORD_FILE_KEY, sizeof(slotConfig) / 4, (uint8_t *)&slotConfig); + bool ret = fds_write_sync(FDS_EMULATION_CONFIG_FILE_ID, FDS_EMULATION_CONFIG_RECORD_KEY, sizeof(slotConfig) / 4, (uint8_t *)&slotConfig); if (ret) { NRF_LOG_INFO("Save tag slot config success."); } else { diff --git a/firmware/application/src/rfid/nfctag/tag_persistence.c b/firmware/application/src/rfid/nfctag/tag_persistence.c index 4997be2..dbfa15e 100644 --- a/firmware/application/src/rfid/nfctag/tag_persistence.c +++ b/firmware/application/src/rfid/nfctag/tag_persistence.c @@ -9,35 +9,24 @@ NRF_LOG_MODULE_REGISTER(); -void get_fds_map_by_slot_auto_inc_id(uint16_t key, uint16_t id, uint8_t slot, tag_sense_type_t sense_type, fds_slot_record_map_t* map) { - map->key = key + slot; - uint8_t base_id = 0; - switch(sense_type) { - case TAG_SENSE_HF: - base_id = 0; - break; - case TAG_SENSE_LF: - base_id = 1; - break; - case TAG_SENSE_NO: - // never to here...(if dev wrong, must fix) - APP_ERROR_CHECK(NRF_ERROR_INVALID_PARAM); +static void get_fds_map_by_slot_auto_inc_id(uint16_t id, uint8_t slot, tag_sense_type_t sense_type, fds_slot_record_map_t* map) { + if ((sense_type == TAG_SENSE_NO) || (slot > 7)) { + APP_ERROR_CHECK(NRF_ERROR_INVALID_PARAM); } - map->id = id + base_id; + map->id = id + slot; + map->key = sense_type; } - /** - * 根据卡槽和卡槽中指定的场类型获得其在FDS中对应的数据的KEY和ID + * Obtain the KEY and ID of the corresponding data in FDS according to the card slot and the field type specified in the card slot */ void get_fds_map_by_slot_sense_type_for_dump(uint8_t slot, tag_sense_type_t sense_type, fds_slot_record_map_t* map) { - // 根据 @see FDS_SLOT_TAG_DUMP_FILE_KEY 的约定,每个slot以其为起点,每个slot都有其单独的key的record,并且每个slot中独特的场类型也有一个数据的id - get_fds_map_by_slot_auto_inc_id(FDS_SLOT_TAG_DUMP_FILE_KEY, FDS_SLOT_TAG_DUMP_FILE_ID, slot, sense_type, map); + get_fds_map_by_slot_auto_inc_id(FDS_SLOT_TAG_DUMP_FILE_ID_BASE, slot, sense_type, map); } /** - * 根据卡槽和卡槽中指定的场类型获得其在FDS中对应的数据的KEY和ID + * Obtain the KEY and ID of the corresponding data in FDS according to the card slot and the field type specified in the card slot */ void get_fds_map_by_slot_sense_type_for_nick(uint8_t slot, tag_sense_type_t sense_type, fds_slot_record_map_t* map) { - get_fds_map_by_slot_auto_inc_id(FDS_SLOT_TAG_NICK_NAME_KEY, FDS_SLOT_TAG_NICK_NAME_ID, slot, sense_type, map); + get_fds_map_by_slot_auto_inc_id(FDS_SLOT_TAG_NICK_NAME_FILE_ID_BASE, slot, sense_type, map); } diff --git a/firmware/application/src/settings.c b/firmware/application/src/settings.c index 944060c..aa76743 100644 --- a/firmware/application/src/settings.c +++ b/firmware/application/src/settings.c @@ -62,7 +62,7 @@ void settings_migrate(void) void settings_load_config(void) { - bool ret = fds_read_sync(FDS_SETTINGS_ID, FDS_SETTINGS_KEY, sizeof(config), (uint8_t *)&config); + bool ret = fds_read_sync(FDS_SETTINGS_FILE_ID, FDS_SETTINGS_RECORD_KEY, sizeof(config), (uint8_t *)&config); if (ret) { NRF_LOG_INFO("Load config done."); // After the reading is complete, we first save a copy of the current CRC, which can be used as a reference for comparison of changes when saving later @@ -89,7 +89,7 @@ uint8_t settings_save_config(void) // We are saving the configuration, we need to calculate the crc code of the current configuration to judge whether the following data is updated if (config_did_change()) { // Before saving, make sure that the configuration has changed NRF_LOG_INFO("Save config start."); - bool ret = fds_write_sync(FDS_SETTINGS_ID, FDS_SETTINGS_KEY, sizeof(config) / 4, (uint8_t *)&config); + bool ret = fds_write_sync(FDS_SETTINGS_FILE_ID, FDS_SETTINGS_RECORD_KEY, sizeof(config) / 4, (uint8_t *)&config); if (ret) { NRF_LOG_INFO("Save config success."); update_config_crc(); diff --git a/firmware/application/src/utils/fds_ids.h b/firmware/application/src/utils/fds_ids.h index ca11e2e..eb8e86b 100644 --- a/firmware/application/src/utils/fds_ids.h +++ b/firmware/application/src/utils/fds_ids.h @@ -2,29 +2,37 @@ #define FDS_IDS_H /* - * 卡槽配置,只有一份,一致即可 + * Card slot configuration, only one, consistent */ -#define FDS_CONFIG_RECORD_FILE_KEY 0x1066 -#define FDS_CONFIG_RECORD_FILE_ID 0x1066 - -/* - * 每个卡槽有高低频两种数据,其中key是跟卡槽走的,而id+n就等于数据索引,固定某个索引为指定类型即可 - * 每个slot的file_key都不一样 - * 每个slot有两种类型的卡片,因此有两个数据ID(当前) - */ -#define FDS_SLOT_TAG_DUMP_FILE_KEY 0x1067 -#define FDS_SLOT_TAG_DUMP_FILE_ID 0x1067 - -/* - * 每个卡槽有高低频两种数据,因此卡槽的昵称也要有两种,其中key是跟卡槽走的,而id+n就等于数据索引,固定某个索引为指定类型即可 - */ -#define FDS_SLOT_TAG_NICK_NAME_KEY 0x1068 -#define FDS_SLOT_TAG_NICK_NAME_ID 0x1068 +#define FDS_EMULATION_CONFIG_FILE_ID 0x1000 +#define FDS_EMULATION_CONFIG_RECORD_KEY 0x1 /* * Slot for settings like LED animation mode and future options */ -#define FDS_SETTINGS_KEY 0x1069 -#define FDS_SETTINGS_ID 0x1069 +#define FDS_SETTINGS_FILE_ID 0x1001 +#define FDS_SETTINGS_RECORD_KEY 0x1 -#endif \ No newline at end of file +/* + * Each card slot has two types of data, high and low frequency + * FDS file ID follows the card slot, starting from 0x1100 to 0x1107 + * FDS record key mirrors TAG_SENSE_LF/HF so is 1 for LF, 2 for HF (currently) + */ +#define FDS_SLOT_TAG_DUMP_FILE_ID_BASE 0x1100 + +/* + * Each card slot has two types of data, high and low frequency, so it can get two names + * FDS file ID follows the card slot, starting from 0x1200 to 0x1207 + * FDS record key mirrors TAG_SENSE_LF/HF so is 1 for LF, 2 for HF (currently) + */ +#define FDS_SLOT_TAG_NICK_NAME_FILE_ID_BASE 0x1200 + +// Note that previously assigned records may need to be cleaned from Flash. +// Taking into account the possible overlaps, it boils down to +// ID 0x1066 Keys 0x1066 +// ID 0x1067 Keys 0x1067-0x106e +// ID 0x1068 Keys 0x1067-0x106f +// ID 0x1069 Keys 0x1068-0x1070 + + +#endif From 7e7abc50eae61caa4a432f16cabc2ce34710cec6 Mon Sep 17 00:00:00 2001 From: Sgnusov Date: Thu, 17 Aug 2023 11:13:28 +0000 Subject: [PATCH 16/16] Fix data sanity check --- firmware/application/src/app_cmd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/firmware/application/src/app_cmd.c b/firmware/application/src/app_cmd.c index 4ea39a0..f143de5 100644 --- a/firmware/application/src/app_cmd.c +++ b/firmware/application/src/app_cmd.c @@ -407,13 +407,13 @@ data_frame_tx_t* cmd_processor_get_mf1_detection_log(uint16_t cmd, uint16_t stat data_frame_tx_t* cmd_processor_set_mf1_emulator_block(uint16_t cmd, uint16_t status, uint16_t length, uint8_t *data) { if (length > 0 && (((length - 1) % NFC_TAG_MF1_DATA_SIZE) == 0)) { uint8_t block_index = data[0]; - uint8_t block_count = (length - 1) % NFC_TAG_MF1_DATA_SIZE; + uint8_t block_count = (length - 1) / NFC_TAG_MF1_DATA_SIZE; if (block_index + block_count > NFC_TAG_MF1_BLOCK_MAX) { status = STATUS_PAR_ERR; } else { tag_data_buffer_t* buffer = get_buffer_by_tag_type(TAG_TYPE_MIFARE_4096); nfc_tag_mf1_information_t *info = (nfc_tag_mf1_information_t *)buffer->buffer; - for (int i = 1, j = block_index; i < length - 1; i += NFC_TAG_MF1_DATA_SIZE, j++) { + for (int i = 1, j = block_index; i < length; i += NFC_TAG_MF1_DATA_SIZE, j++) { uint8_t *p_block = &data[i]; memcpy(info->memory[j], p_block, NFC_TAG_MF1_DATA_SIZE); }