mirror of
https://github.com/RfidResearchGroup/ChameleonUltra.git
synced 2026-05-12 11:22:59 -07:00
Merge branch 'main' into bugfix/cli-offset
This commit is contained in:
@@ -309,3 +309,14 @@ in a second terminal:
|
||||
```
|
||||
JLinkRTTClient
|
||||
```
|
||||
|
||||
## Using SWO pin as UART to monitor NRF_LOG
|
||||
|
||||
One can set `NRF_LOG_UART_ON_SWO_ENABLED := 1` in `Makefile.defs` to activate this functionality.
|
||||
When activated, NRF_LOG will be available if one connects a UART bridge to the SWO pin which will work as a UART TX pin.
|
||||
UART works at 115200 bauds. E.g. one can use a FTDI dongle and `screen /dev/ttyUSB0 115200`.
|
||||
Contrary to RTT that needs to be activated by a JTAG probe, UART logs are immediately available.
|
||||
|
||||
Limitations:
|
||||
* SWO pin is shared with... SWO so when e.g. reflashing the device, garbage may appear on the monitoring terminal.
|
||||
* SWO pin is also shared with the blue channel of the RGB slot LEDs, so faint blue may appear briefly when logs are sent and LED might not work properly when supposed to be blue.
|
||||
|
||||
@@ -27,3 +27,6 @@ CURRENT_DEVICE_TYPE ?= ${CHAMELEON_ULTRA}
|
||||
|
||||
# Versioning information
|
||||
GIT_VERSION := "$(shell git describe --abbrev=7 --dirty --always --tags)"
|
||||
|
||||
# Enable NRF_LOG on SWO pin as UART TX
|
||||
NRF_LOG_UART_ON_SWO_ENABLED := 0
|
||||
|
||||
@@ -17,6 +17,7 @@ SRC_FILES += \
|
||||
$(PROJ_DIR)/rgb_marquee.c \
|
||||
$(PROJ_DIR)/bsp/bsp_delay.c \
|
||||
$(PROJ_DIR)/bsp/bsp_time.c \
|
||||
$(PROJ_DIR)/bsp/bsp_wdt.c \
|
||||
$(PROJ_DIR)/rfid/crc_utils.c \
|
||||
$(PROJ_DIR)/rfid/hex_utils.c \
|
||||
$(PROJ_DIR)/rfid/mf1_crapto1.c \
|
||||
@@ -30,6 +31,7 @@ SRC_FILES += \
|
||||
$(PROJ_DIR)/rfid/nfctag/hf/nfc_ntag.c \
|
||||
$(PROJ_DIR)/rfid/nfctag/lf/lf_tag_em.c \
|
||||
$(PROJ_DIR)/utils/dataframe.c \
|
||||
$(PROJ_DIR)/utils/delayed_reset.c \
|
||||
$(PROJ_DIR)/utils/fds_util.c \
|
||||
$(PROJ_DIR)/utils/syssleep.c \
|
||||
$(PROJ_DIR)/utils/timeslot.c \
|
||||
@@ -93,6 +95,7 @@ SRC_FILES += \
|
||||
$(SDK_ROOT)/modules/nrfx/drivers/src/nrfx_spi.c \
|
||||
$(SDK_ROOT)/modules/nrfx/drivers/src/nrfx_rng.c \
|
||||
$(SDK_ROOT)/modules/nrfx/drivers/src/nrfx_ppi.c \
|
||||
$(SDK_ROOT)/modules/nrfx/drivers/src/nrfx_wdt.c \
|
||||
$(SDK_ROOT)/external/segger_rtt/SEGGER_RTT.c \
|
||||
$(SDK_ROOT)/external/segger_rtt/SEGGER_RTT_Syscalls_GCC.c \
|
||||
$(SDK_ROOT)/external/segger_rtt/SEGGER_RTT_printf.c \
|
||||
@@ -288,6 +291,23 @@ else
|
||||
$(error Chameleon <Application>: No device type define.)
|
||||
endif
|
||||
|
||||
ifeq (${NRF_LOG_UART_ON_SWO_ENABLED}, 1)
|
||||
SRC_FILES += \
|
||||
$(SDK_ROOT)/components/libraries/log/src/nrf_log_backend_uart.c \
|
||||
$(SDK_ROOT)/integration/nrfx/legacy/nrf_drv_uart.c \
|
||||
$(SDK_ROOT)/modules/nrfx/drivers/src/nrfx_uarte.c
|
||||
|
||||
CFLAGS += -DNRFX_UARTE_ENABLED=1 -DNRFX_UARTE0_ENABLED=1
|
||||
CFLAGS += -DNRF_LOG_BACKEND_UART_ENABLED=1
|
||||
#define NRF_GPIO_PIN_MAP(port, pin) (((port) << 5) | ((pin) & 0x1F))
|
||||
#define NRF_LOG_BACKEND_UART_TX_PIN NRF_GPIO_PIN_MAP(1, 0)
|
||||
CFLAGS += -DNRF_LOG_BACKEND_UART_TX_PIN=32
|
||||
# 30801920 = 115200 baud
|
||||
CFLAGS += -DNRF_LOG_BACKEND_UART_BAUDRATE=30801920
|
||||
CFLAGS += -DNRF_LOG_BACKEND_UART_TEMP_BUFFER_SIZE=64
|
||||
|
||||
$(info Chameleon <Application>: enable NRF_LOG on UART via SWO pin.)
|
||||
endif
|
||||
|
||||
# Optimization flags
|
||||
OPT = -O3 -g3
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "tag_persistence.h"
|
||||
#include "nrf_pwr_mgmt.h"
|
||||
#include "settings.h"
|
||||
#include "delayed_reset.h"
|
||||
|
||||
|
||||
#define NRF_LOG_MODULE_NAME app_cmd
|
||||
@@ -357,6 +358,13 @@ data_frame_tx_t* cmd_processor_get_slot_info(uint16_t cmd, uint16_t status, uint
|
||||
return data_frame_make(cmd, STATUS_DEVICE_SUCCESS, 16, slot_info);
|
||||
}
|
||||
|
||||
data_frame_tx_t* cmd_processor_wipe_fds(uint16_t cmd, uint16_t status, uint16_t length, uint8_t *data) {
|
||||
bool success = fds_wipe();
|
||||
status = success ? STATUS_DEVICE_SUCCESS : STATUS_FLASH_WRITE_FAIL;
|
||||
delayed_reset(50);
|
||||
return data_frame_make(cmd, status, 0, NULL);
|
||||
}
|
||||
|
||||
data_frame_tx_t* cmd_processor_set_em410x_emu_id(uint16_t cmd, uint16_t status, uint16_t length, uint8_t *data) {
|
||||
if (length == LF_EM410X_TAG_ID_SIZE) {
|
||||
tag_data_buffer_t* buffer = get_buffer_by_tag_type(TAG_TYPE_EM410X);
|
||||
@@ -473,7 +481,6 @@ data_frame_tx_t* cmd_processor_set_mf1_anti_collision_res(uint16_t cmd, uint16_t
|
||||
}
|
||||
|
||||
data_frame_tx_t* cmd_processor_set_slot_tag_nick_name(uint16_t cmd, uint16_t status, uint16_t length, uint8_t *data) {
|
||||
// one chinese have 2byte(gbk).
|
||||
if (length > 34 || length < 3) {
|
||||
status = STATUS_PAR_ERR;
|
||||
} else {
|
||||
@@ -498,7 +505,6 @@ data_frame_tx_t* cmd_processor_set_slot_tag_nick_name(uint16_t cmd, uint16_t sta
|
||||
}
|
||||
|
||||
data_frame_tx_t* cmd_processor_get_slot_tag_nick_name(uint16_t cmd, uint16_t status, uint16_t length, uint8_t *data) {
|
||||
// one chinese have 2byte(gbk).
|
||||
if (length != 2) {
|
||||
status = STATUS_PAR_ERR;
|
||||
} else {
|
||||
@@ -607,6 +613,7 @@ static cmd_data_map_t m_data_cmd_map[] = {
|
||||
{ DATA_CMD_SLOT_DATA_CONFIG_SAVE, NULL, cmd_processor_slot_data_config_save, NULL },
|
||||
{ DATA_CMD_GET_ACTIVE_SLOT, NULL, cmd_processor_get_activated_slot, NULL },
|
||||
{ DATA_CMD_GET_SLOT_INFO, NULL, cmd_processor_get_slot_info, NULL },
|
||||
{ DATA_CMD_WIPE_FDS, NULL, cmd_processor_wipe_fds, NULL },
|
||||
|
||||
|
||||
{ DATA_CMD_SET_EM410X_EMU_ID, NULL, cmd_processor_set_em410x_emu_id, NULL },
|
||||
|
||||
@@ -27,6 +27,7 @@ NRF_LOG_MODULE_REGISTER();
|
||||
#include "ble_main.h"
|
||||
#include "bsp_delay.h"
|
||||
#include "bsp_time.h"
|
||||
#include "bsp_wdt.h"
|
||||
#include "dataframe.h"
|
||||
#include "fds_util.h"
|
||||
#include "hex_utils.h"
|
||||
@@ -38,7 +39,6 @@ NRF_LOG_MODULE_REGISTER();
|
||||
|
||||
#include "settings.h"
|
||||
|
||||
|
||||
// Defining soft timers
|
||||
APP_TIMER_DEF(m_button_check_timer); // Timer for button debounce
|
||||
static bool m_is_read_btn_press = false;
|
||||
@@ -545,6 +545,7 @@ int main(void) {
|
||||
// usbd event listener
|
||||
APP_ERROR_CHECK(app_usbd_power_events_enable());
|
||||
|
||||
bsp_wdt_init();
|
||||
// Enter main loop.
|
||||
NRF_LOG_INFO("Chameleon working");
|
||||
while (1) {
|
||||
@@ -558,6 +559,8 @@ int main(void) {
|
||||
while (NRF_LOG_PROCESS());
|
||||
// USB event process
|
||||
while (app_usbd_event_queue_process());
|
||||
// WDT refresh
|
||||
bsp_wdt_feed();
|
||||
// No task to process, system sleep enter.
|
||||
// If system idle sometime, we can enter deep sleep state.
|
||||
// Some task process done, we can enter cpu sleep state.
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
#include "nrf_drv_wdt.h"
|
||||
#include "hw_connect.h"
|
||||
#include "nrf_gpio.h"
|
||||
|
||||
static nrf_drv_wdt_channel_id m_channel_id;
|
||||
|
||||
static void wdt_event_handler(void)
|
||||
{
|
||||
//NOTE: The max amount of time we can spend in WDT interrupt is two cycles of 32768[Hz] clock - after that, reset occurs
|
||||
uint32_t* p_led_array = hw_get_led_array();
|
||||
for (uint8_t i = 0; i < RGB_LIST_NUM; i++) {
|
||||
nrf_gpio_pin_clear(p_led_array[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void bsp_wdt_init(void) {
|
||||
ret_code_t err_code;
|
||||
// err_code = nrf_drv_clock_init(); // already done by usb_cdc_init() -> app_usbd_init()
|
||||
// APP_ERROR_CHECK(err_code);
|
||||
nrf_drv_wdt_config_t config = NRF_DRV_WDT_DEAFULT_CONFIG; // typo is in the SDK...
|
||||
err_code = nrf_drv_wdt_init(&config, wdt_event_handler);
|
||||
APP_ERROR_CHECK(err_code);
|
||||
err_code = nrf_drv_wdt_channel_alloc(&m_channel_id);
|
||||
APP_ERROR_CHECK(err_code);
|
||||
nrf_drv_wdt_enable();
|
||||
}
|
||||
|
||||
void bsp_wdt_feed(void) {
|
||||
nrf_drv_wdt_channel_feed(m_channel_id);
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
#ifndef __BSP_WDT_H__
|
||||
#define __BSP_WDT_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void bsp_wdt_init(void);
|
||||
void bsp_wdt_feed(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // __BSP_WDT_H__
|
||||
@@ -27,6 +27,7 @@
|
||||
#define DATA_CMD_GET_GIT_VERSION (1017)
|
||||
#define DATA_CMD_GET_ACTIVE_SLOT (1018)
|
||||
#define DATA_CMD_GET_SLOT_INFO (1019)
|
||||
#define DATA_CMD_WIPE_FDS (1020)
|
||||
//
|
||||
// ******************************************************************
|
||||
|
||||
|
||||
@@ -4630,7 +4630,7 @@
|
||||
// <e> NRFX_WDT_ENABLED - nrfx_wdt - WDT peripheral driver
|
||||
//==========================================================
|
||||
#ifndef NRFX_WDT_ENABLED
|
||||
#define NRFX_WDT_ENABLED 0
|
||||
#define NRFX_WDT_ENABLED 1
|
||||
#endif
|
||||
// <o> NRFX_WDT_CONFIG_BEHAVIOUR - WDT behavior in CPU SLEEP or HALT mode
|
||||
|
||||
@@ -4647,7 +4647,7 @@
|
||||
|
||||
|
||||
#ifndef NRFX_WDT_CONFIG_RELOAD_VALUE
|
||||
#define NRFX_WDT_CONFIG_RELOAD_VALUE 2000
|
||||
#define NRFX_WDT_CONFIG_RELOAD_VALUE 5000
|
||||
#endif
|
||||
|
||||
// <o> NRFX_WDT_CONFIG_NO_IRQ - Remove WDT IRQ handling from WDT driver
|
||||
@@ -4677,7 +4677,7 @@
|
||||
// <e> NRFX_WDT_CONFIG_LOG_ENABLED - Enables logging in the module.
|
||||
//==========================================================
|
||||
#ifndef NRFX_WDT_CONFIG_LOG_ENABLED
|
||||
#define NRFX_WDT_CONFIG_LOG_ENABLED 0
|
||||
#define NRFX_WDT_CONFIG_LOG_ENABLED 1
|
||||
#endif
|
||||
// <o> NRFX_WDT_CONFIG_LOG_LEVEL - Default Severity level
|
||||
|
||||
@@ -5868,9 +5868,10 @@
|
||||
|
||||
// <e> UART_ENABLED - nrf_drv_uart - UART/UARTE peripheral driver - legacy layer
|
||||
//==========================================================
|
||||
#ifndef UART_ENABLED
|
||||
#define UART_ENABLED 0
|
||||
#endif
|
||||
//Don't define it at all else it conflicts with NRFX
|
||||
//#ifndef UART_ENABLED
|
||||
//#define UART_ENABLED 0
|
||||
//#endif
|
||||
// <o> UART_DEFAULT_CONFIG_HWFC - Hardware Flow Control
|
||||
|
||||
// <0=> Disabled
|
||||
@@ -6018,9 +6019,10 @@
|
||||
|
||||
// <e> WDT_ENABLED - nrf_drv_wdt - WDT peripheral driver - legacy layer
|
||||
//==========================================================
|
||||
#ifndef WDT_ENABLED
|
||||
#define WDT_ENABLED 0
|
||||
#endif
|
||||
//Don't define it at all else it conflicts with NRFX
|
||||
//#ifndef WDT_ENABLED
|
||||
//#define WDT_ENABLED 0
|
||||
//#endif
|
||||
// <o> WDT_CONFIG_BEHAVIOUR - WDT behavior in CPU SLEEP or HALT mode
|
||||
|
||||
// <1=> Run in SLEEP, Pause in HALT
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
#include "app_timer.h"
|
||||
#include "delayed_reset.h"
|
||||
|
||||
#include "nrf_log.h"
|
||||
#include "nrf_log_ctrl.h"
|
||||
#include "nrf_log_default_backends.h"
|
||||
|
||||
APP_TIMER_DEF(m_reset_timer);
|
||||
|
||||
static void delayed_reset_event_handler(void* ctx) {
|
||||
while (NRF_LOG_PROCESS());
|
||||
ret_code_t ret = sd_nvic_SystemReset();
|
||||
APP_ERROR_CHECK(ret);
|
||||
while (1) {
|
||||
__NOP();
|
||||
}
|
||||
}
|
||||
|
||||
void delayed_reset(uint32_t delay) {
|
||||
NRF_LOG_INFO("Resetting in %d ms...", delay);
|
||||
ret_code_t ret;
|
||||
ret = app_timer_create(&m_reset_timer, APP_TIMER_MODE_SINGLE_SHOT, delayed_reset_event_handler);
|
||||
APP_ERROR_CHECK(ret);
|
||||
ret = app_timer_start(m_reset_timer, APP_TIMER_TICKS(delay), NULL);
|
||||
APP_ERROR_CHECK(ret);
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
void delayed_reset(uint32_t delay);
|
||||
@@ -10,10 +10,11 @@ NRF_LOG_MODULE_REGISTER();
|
||||
|
||||
// current write record info
|
||||
static struct {
|
||||
uint16_t id; // file id
|
||||
uint16_t key; // file key
|
||||
bool success; // task is success
|
||||
bool waiting; // task waiting done.
|
||||
uint32_t record_id; // record id, used for sync delete
|
||||
uint16_t id; // file id
|
||||
uint16_t key; // file key
|
||||
bool success; // task is success
|
||||
bool waiting; // task waiting done.
|
||||
} fds_operation_info;
|
||||
|
||||
|
||||
@@ -120,12 +121,7 @@ bool fds_write_sync(uint16_t id, uint16_t key, uint16_t data_length_words, void*
|
||||
} else if (err_code == FDS_ERR_NO_SPACE_IN_FLASH) { // 确保还有空间可以操作,否则需要GC
|
||||
// 当前报错是属于空间不足的报错,可能我们需要进行GC
|
||||
NRF_LOG_INFO("FDS no space, gc auto start.");
|
||||
err_code = fds_gc(); // 发起GC操作
|
||||
APP_ERROR_CHECK(err_code); // 检查GC是否正常执行
|
||||
// 等待GC完成
|
||||
while(!fds_operation_info.success) {
|
||||
__NOP();
|
||||
};
|
||||
fds_gc_sync();
|
||||
|
||||
// gc完成后,可以重新进行相应的操作了
|
||||
NRF_LOG_INFO("FDS auto gc success, write record continue.");
|
||||
@@ -162,6 +158,7 @@ int fds_delete_sync(uint16_t id, uint16_t key) {
|
||||
ret_code_t err_code;
|
||||
while(fds_find_record(id, key, &record_desc)) {
|
||||
fds_operation_info.success = false;
|
||||
fds_record_id_from_desc(&record_desc, &fds_operation_info.record_id);
|
||||
err_code = fds_record_delete(&record_desc);
|
||||
APP_ERROR_CHECK(err_code);
|
||||
delete_count++;
|
||||
@@ -199,9 +196,13 @@ static void fds_evt_handler(fds_evt_t const * p_evt) {
|
||||
} break;
|
||||
case FDS_EVT_DEL_RECORD: {
|
||||
if (p_evt->result == NRF_SUCCESS) {
|
||||
NRF_LOG_INFO("Record remove: FileID: 0x%04x, RecordKey: 0x%04x", p_evt->del.file_id, p_evt->del.record_key);
|
||||
if (p_evt->write.file_id == fds_operation_info.id && p_evt->write.record_key == fds_operation_info.key) {
|
||||
// 上面的逻辑已经确保是我们当前删除记录的任务完成了!
|
||||
NRF_LOG_INFO(
|
||||
"Record remove: FileID: 0x%04x, RecordKey: 0x%04x, RecordID: %08x",
|
||||
p_evt->del.file_id, p_evt->del.record_key, p_evt->del.record_id
|
||||
);
|
||||
if (p_evt->del.record_id == fds_operation_info.record_id) {
|
||||
// Only check record id because fileID and recordKey aren't available
|
||||
// if deleting via fds_record_iterate. record id is guaranteed to be unique.
|
||||
fds_operation_info.success = true;
|
||||
}
|
||||
} else {
|
||||
@@ -234,3 +235,45 @@ void fds_util_init() {
|
||||
err_code = fds_init();
|
||||
APP_ERROR_CHECK(err_code);
|
||||
}
|
||||
|
||||
void fds_gc_sync(void) {
|
||||
fds_operation_info.success = false;
|
||||
ret_code_t err_code = fds_gc();
|
||||
APP_ERROR_CHECK(err_code);
|
||||
while(!fds_operation_info.success) {
|
||||
__NOP();
|
||||
};
|
||||
}
|
||||
|
||||
static bool fds_next_record_delete_sync() {
|
||||
fds_find_token_t tok = {0};
|
||||
fds_record_desc_t desc = {0};
|
||||
if (fds_record_iterate(&desc, &tok) != NRF_SUCCESS) {
|
||||
NRF_LOG_INFO("No more records to delete");
|
||||
return false;
|
||||
}
|
||||
|
||||
fds_record_id_from_desc(&desc, &fds_operation_info.record_id);
|
||||
NRF_LOG_INFO("Deleting record with id=%08x", fds_operation_info.record_id);
|
||||
|
||||
fds_operation_info.success = false;
|
||||
ret_code_t rc = fds_record_delete(&desc);
|
||||
if (rc != NRF_SUCCESS) {
|
||||
NRF_LOG_WARNING("Record id=%08x deletion failed with rc=%d!", fds_operation_info.record_id, rc);
|
||||
return false;
|
||||
}
|
||||
|
||||
while(!fds_operation_info.success) {
|
||||
__NOP();
|
||||
}
|
||||
|
||||
NRF_LOG_INFO("Record id=%08x deleted successfully", fds_operation_info.record_id);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool fds_wipe(void) {
|
||||
NRF_LOG_INFO("Full fds wipe requested");
|
||||
while (fds_next_record_delete_sync()) {}
|
||||
fds_gc_sync();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -9,5 +9,7 @@ bool fds_write_sync(uint16_t id, uint16_t key, uint16_t data_length_words, void*
|
||||
int fds_delete_sync(uint16_t id, uint16_t key);
|
||||
bool fds_is_exists(uint16_t id, uint16_t key);
|
||||
void fds_util_init(void);
|
||||
void fds_gc_sync(void);
|
||||
bool fds_wipe(void);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -27,13 +27,12 @@ LITE = r"""
|
||||
|
||||
# create by http://patorjk.com/software/taag/#p=display&f=ANSI%20Shadow&t=Chameleon%20Ultra
|
||||
BANNER = f"""
|
||||
██████╗██╗ ██╗ █████╗ ███╗ ███╗███████╗██╗ ███████╗ ██████╗ ███╗ ██╗
|
||||
██╔════╝██║ ██║██╔══██╗████╗ ████║██╔════╝██║ ██╔════╝██╔═══██╗████╗ ██║
|
||||
██║ ███████║███████║██╔████╔██║█████╗ ██║ █████╗ ██║ ██║██╔██╗ ██║
|
||||
██║ ██╔══██║██╔══██║██║╚██╔╝██║██╔══╝ ██║ ██╔══╝ ██║ ██║██║╚██╗██║
|
||||
╚██████╗██║ ██║██║ ██║██║ ╚═╝ ██║███████╗███████╗███████╗╚██████╔╝██║ ╚████║
|
||||
╚═════╝╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝╚══════╝╚══════╝ ╚═════╝ ╚═╝ ╚═══╝
|
||||
|
||||
██████╗██╗ ██╗ █████╗ ██╗ ██╗███████╗██╗ ███████╗ █████╗ ██╗ ██╗
|
||||
██╔════╝██║ ██║██╔══██╗███╗ ███║██╔════╝██║ ██╔════╝██╔══██╗███╗ ██║
|
||||
██║ ███████║███████║████████║█████╗ ██║ █████╗ ██║ ██║████╗██║
|
||||
██║ ██╔══██║██╔══██║██╔██╔██║██╔══╝ ██║ ██╔══╝ ██║ ██║██╔████║
|
||||
╚██████╗██║ ██║██║ ██║██║╚═╝██║███████╗███████╗███████╗╚█████╔╝██║╚███║
|
||||
╚═════╝╚═╝ ╚═╝╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝╚══════╝╚══════╝ ╚════╝ ╚═╝ ╚══╝
|
||||
"""
|
||||
|
||||
|
||||
@@ -99,6 +98,7 @@ class ChameleonCLI:
|
||||
'reset': new_uint(chameleon_cli_unit.HWSettingsReset, "Reset settings to default values"),
|
||||
'help': "Chameleon settings management"
|
||||
},
|
||||
'factory_reset': new_uint(chameleon_cli_unit.HWFactoryReset, "Wipe all data and return to factory settings"),
|
||||
'help': "hardware controller",
|
||||
},
|
||||
'hf': {
|
||||
|
||||
@@ -950,10 +950,10 @@ class HWSlotNickSet(SlotIndexRequireUint, SenseTypeRequireUint):
|
||||
slot_num = args.slot
|
||||
sense_type = args.sense_type
|
||||
name: str = args.name
|
||||
if len(name.encode(encoding="gbk")) > 32:
|
||||
uname = name.encode(encoding="utf8")
|
||||
if len(uname) > 32:
|
||||
raise ValueError("Your tag nick name too long.")
|
||||
self.cmd_positive.set_slot_tag_nick_name(slot_num, sense_type, name)
|
||||
#print(f'{slot_num} selected for nickname {name}.')
|
||||
self.cmd_positive.set_slot_tag_nick_name(slot_num, sense_type, uname)
|
||||
print(f' - Set tag nick name for slot {slot_num} success.')
|
||||
|
||||
|
||||
@@ -969,7 +969,7 @@ class HWSlotNickGet(SlotIndexRequireUint, SenseTypeRequireUint):
|
||||
slot_num = args.slot
|
||||
sense_type = args.sense_type
|
||||
res = self.cmd_positive.get_slot_tag_nick_name(slot_num, sense_type)
|
||||
print(f' - Get tag nick name for slot {slot_num}: {res.data.decode(encoding="gbk")}')
|
||||
print(f' - Get tag nick name for slot {slot_num}: {res.data.decode(encoding="utf8")}')
|
||||
|
||||
|
||||
class HWSlotUpdate(DeviceRequiredUnit):
|
||||
@@ -1077,3 +1077,27 @@ class HWSettingsReset(DeviceRequiredUnit):
|
||||
print(" - Reset success @.@~")
|
||||
else:
|
||||
print(" - Reset failed")
|
||||
|
||||
class HWFactoryReset(DeviceRequiredUnit):
|
||||
def args_parser(self) -> ArgumentParserNoExit:
|
||||
parser = ArgumentParserNoExit()
|
||||
parser.description = "Permanently wipes Chameleon to factory settings. " \
|
||||
"This will delete all your slot data and custom settings. " \
|
||||
"There's no going back."
|
||||
parser.add_argument(
|
||||
"--i-know-what-im-doing",
|
||||
default=False,
|
||||
action="store_true",
|
||||
help="Just to be sure :)"
|
||||
)
|
||||
return parser
|
||||
def on_exec(self, args: argparse.Namespace):
|
||||
if not args.i_know_what_im_doing:
|
||||
print("This time your data's safe. Read the command documentation next time.")
|
||||
return
|
||||
resp = self.cmd_positive.factory_reset()
|
||||
if resp.status == chameleon_status.Device.STATUS_DEVICE_SUCCESS:
|
||||
print(" - Reset successful! Please reconnect.")
|
||||
print(" - A Serial Error below is normal, please ignore it")
|
||||
else:
|
||||
print(" - Reset failed!")
|
||||
|
||||
@@ -30,6 +30,8 @@ DATA_CMD_GET_GIT_VERSION = 1017
|
||||
DATA_CMD_GET_ACTIVE_SLOT = 1018
|
||||
DATA_CMD_GET_SLOT_INFO = 1019
|
||||
|
||||
DATA_CMD_WIPE_FDS = 1020
|
||||
|
||||
DATA_CMD_SCAN_14A_TAG = 2000
|
||||
DATA_CMD_MF1_SUPPORT_DETECT = 2001
|
||||
DATA_CMD_MF1_NT_LEVEL_DETECT = 2002
|
||||
@@ -464,7 +466,7 @@ class BaseChameleonCMD:
|
||||
data.extend(uid)
|
||||
return self.device.send_cmd_sync(DATA_CMD_SET_MF1_ANTI_COLLISION_RES, 0X00, data)
|
||||
|
||||
def set_slot_tag_nick_name(self, slot: SlotNumber, sense_type: TagSenseType, name: str):
|
||||
def set_slot_tag_nick_name(self, slot: SlotNumber, sense_type: TagSenseType, name: bytes):
|
||||
"""
|
||||
设置MF1的模拟卡的防冲撞资源信息
|
||||
:param slot: 卡槽号码
|
||||
@@ -475,7 +477,7 @@ class BaseChameleonCMD:
|
||||
# SlotNumber() will raise error for us if slot not in slot range
|
||||
data = bytearray()
|
||||
data.extend([SlotNumber.to_fw(slot), sense_type])
|
||||
data.extend(name.encode(encoding="gbk"))
|
||||
data.extend(name)
|
||||
return self.device.send_cmd_sync(DATA_CMD_SET_SLOT_TAG_NICK, 0x00, data)
|
||||
|
||||
def get_slot_tag_nick_name(self, slot: SlotNumber, sense_type: TagSenseType):
|
||||
@@ -528,6 +530,12 @@ class BaseChameleonCMD:
|
||||
Store settings to flash memory
|
||||
"""
|
||||
return self.device.send_cmd_sync(DATA_CMD_SAVE_SETTINGS, 0x00)
|
||||
|
||||
def factory_reset(self):
|
||||
"""
|
||||
Reset to factory settings
|
||||
"""
|
||||
return self.device.send_cmd_sync(DATA_CMD_WIPE_FDS, 0x00)
|
||||
|
||||
|
||||
class NegativeResponseError(Exception):
|
||||
@@ -653,7 +661,7 @@ class PositiveChameleonCMD(BaseChameleonCMD):
|
||||
self.check_status(ret.status, chameleon_status.Device.STATUS_DEVICE_SUCCESS)
|
||||
return ret
|
||||
|
||||
def set_slot_tag_nick_name(self, slot: int, sense_type: int, name: str):
|
||||
def set_slot_tag_nick_name(self, slot: int, sense_type: int, name: bytes):
|
||||
ret = super(PositiveChameleonCMD, self).set_slot_tag_nick_name(slot, sense_type, name)
|
||||
self.check_status(ret.status, chameleon_status.Device.STATUS_DEVICE_SUCCESS)
|
||||
return ret
|
||||
|
||||
Reference in New Issue
Block a user