Merge pull request #299 from xianglin1998/main

Fix some bugs & Performance improvement
This commit is contained in:
DXL
2026-01-24 19:44:04 +08:00
committed by GitHub
11 changed files with 154 additions and 51 deletions
+3
View File
@@ -5,6 +5,9 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac
## [unreleased][unreleased]
- Fix for static nested key recovery (@jekkos)
- Fix LEDs being stuck on after battery check (@suut)
- Fix the issue where some reader cause CU to enter a strange state (@xianglin1998)
- The transmission performance of USB has been improved (@xianglin1998)
- Added cmd for set mf1 config 'field_off_do_reset' (@xianglin1998)
## [v2.1.0][2025-09-02]
- Added UV, formatter and linter. Contribution guidelines. (@GameTec-live)
+16 -1
View File
@@ -996,7 +996,7 @@ static data_frame_tx_t *cmd_processor_mf1_write_emu_block_data(uint16_t cmd, uin
uint8_t block_index = data[0];
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;
return data_frame_make(cmd, STATUS_PAR_ERR, 0, NULL);
}
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;
@@ -1374,6 +1374,19 @@ static data_frame_tx_t *cmd_processor_mf1_set_write_mode(uint16_t cmd, uint16_t
return data_frame_make(cmd, STATUS_SUCCESS, 0, NULL);
}
static data_frame_tx_t *cmd_processor_mf1_get_field_off_do_reset(uint16_t cmd, uint16_t status, uint16_t length, uint8_t *data) {
uint8_t enable = nfc_tag_mf1_is_field_off_do_reset();
return data_frame_make(cmd, STATUS_SUCCESS, 1, &enable);
}
static data_frame_tx_t *cmd_processor_mf1_set_field_off_do_reset(uint16_t cmd, uint16_t status, uint16_t length, uint8_t *data) {
if (length != 1 || data[0] >= 2) {
return data_frame_make(cmd, STATUS_PAR_ERR, 0, NULL);
}
nfc_tag_mf1_set_field_off_do_reset(data[0]);
return data_frame_make(cmd, STATUS_SUCCESS, 0, NULL);
}
static data_frame_tx_t *cmd_processor_get_enabled_slots(uint16_t cmd, uint16_t status, uint16_t length, uint8_t *data) {
struct {
uint8_t enabled_hf;
@@ -1630,6 +1643,8 @@ static cmd_data_map_t m_data_cmd_map[] = {
{ DATA_CMD_MF1_SET_BLOCK_ANTI_COLL_MODE, NULL, cmd_processor_mf1_set_block_anti_coll_mode, NULL },
{ DATA_CMD_MF1_GET_WRITE_MODE, NULL, cmd_processor_mf1_get_write_mode, NULL },
{ DATA_CMD_MF1_SET_WRITE_MODE, NULL, cmd_processor_mf1_set_write_mode, NULL },
{ DATA_CMD_MF1_GET_FIELD_OFF_DO_RESET, NULL, cmd_processor_mf1_get_field_off_do_reset, NULL },
{ DATA_CMD_MF1_SET_FIELD_OFF_DO_RESET, NULL, cmd_processor_mf1_set_field_off_do_reset, NULL },
{ DATA_CMD_MF0_NTAG_GET_UID_MAGIC_MODE, NULL, cmd_processor_mf0_ntag_get_uid_mode, NULL },
{ DATA_CMD_MF0_NTAG_SET_UID_MAGIC_MODE, NULL, cmd_processor_mf0_ntag_set_uid_mode, NULL },
+2
View File
@@ -139,6 +139,8 @@
#define DATA_CMD_MF0_NTAG_GET_DETECTION_LOG (4035)
#define DATA_CMD_MF0_NTAG_GET_DETECTION_ENABLE (4036)
#define DATA_CMD_MF0_NTAG_GET_EMULATOR_CONFIG (4037)
#define DATA_CMD_MF1_SET_FIELD_OFF_DO_RESET (4038)
#define DATA_CMD_MF1_GET_FIELD_OFF_DO_RESET (4039)
//
// ******************************************************************
@@ -61,7 +61,10 @@ static volatile bool m_is_responded = false;
static uint8_t m_nfc_rx_buffer[MAX_NFC_RX_BUFFER_SIZE] = { 0x00 };
static uint8_t m_nfc_tx_buffer[MAX_NFC_TX_BUFFER_SIZE] = { 0x00 };
// The N -secondary connection needs to use SAK, when the "third 'bit' in SAK is 1 is 1, the logo UID is incomplete
static uint8_t m_uid_incomplete_sak[] = { 0x04, 0xda, 0x17 };
static uint8_t m_uid_incomplete_sak[] = { 0x04, 0xda, 0x17 };
// Reset nfc peripheral after field lost?
static bool reset_if_field_lost = false; // default is 'false', Unless there is a genuine need for a reset.
/**
* @brief Calculate BCC
@@ -349,7 +352,7 @@ void nfc_tag_14a_data_process(uint8_t *p_data) {
m_tag_state_14a = NFC_TAG_STATE_14A_READY;
// After receiving the WUPA or REQA instruction, we need to reply to ATQA
nfc_tag_14a_tx_bytes(auto_coll_res->atqa, 2, false);
// NRF_LOG_INFO("ATQA reply.");
// NRF_LOG_INFO("ATQA reply: %02x%02x", auto_coll_res->atqa[0], auto_coll_res->atqa[1]);
} else {
m_tag_state_14a = NFC_TAG_STATE_14A_IDLE;
NRF_LOG_INFO("Auto anti-collision resource no exists.");
@@ -523,6 +526,43 @@ void nfc_tag_14a_data_process(uint8_t *p_data) {
}
}
// Copy from nrf_nfct.c and modified for nrf52840 adapted(no verify on nrf52832)
static inline void nrf_nfct_reset(void) {
uint32_t fdm;
uint32_t int_enabled;
// Save parameter settings before the reset of the NFCT peripheral.
fdm = nrf_nfct_frame_delay_max_get();
int_enabled = nrf_nfct_int_enable_get();
// Reset the NFCT peripheral.
*(volatile uint32_t *)0x40005FFC = 0;
*(volatile uint32_t *)0x40005FFC;
*(volatile uint32_t *)0x40005FFC = 1;
// Restore parameter settings after the reset of the NFCT peripheral.
nrf_nfct_frame_delay_max_set(fdm);
// Use Window Grid frame delay mode.
nrf_nfct_frame_delay_mode_set(NRF_NFCT_FRAME_DELAY_MODE_WINDOWGRID);
/* Begin: Workaround for anomaly 25 */
/* Workaround for wrong SENSRES values require using SDD00001, but here SDD00100 is used
because it is required to operate with Windows Phone */
nrf_nfct_sensres_bit_frame_sdd_set(NRF_NFCT_SENSRES_BIT_FRAME_SDD_00100);
/* End: Workaround for anomaly 25 */
// Restore interrupts.
nrf_nfct_int_enable(int_enabled);
// Disable interrupts associated with data exchange.
nrf_nfct_int_disable(NRF_NFCT_INT_RXFRAMESTART_MASK |
NRF_NFCT_INT_RXFRAMEEND_MASK |
NRF_NFCT_INT_RXERROR_MASK |
NRF_NFCT_INT_TXFRAMESTART_MASK |
NRF_NFCT_INT_TXFRAMEEND_MASK);
}
static inline void nfc_fdt_reset(void) {
// STOP TX
*(volatile uint32_t *)0x40005010 = 0x01;
@@ -571,6 +611,13 @@ void nfc_tag_14a_event_callback(nrfx_nfct_evt_t const *p_event) {
TAG_FIELD_LED_OFF()
m_tag_state_14a = NFC_TAG_STATE_14A_IDLE;
if (reset_if_field_lost) {
// Fix a bug where certain special conditions prevent triggering TX start events and actually transmit incorrect data to the card reader.
// After more more more testing, I found that simply going into sleep mode and restarting can restore work.
// Therefore, I suspect that there may be some issues with the NFC peripheral that require a reset to resolve.
nrf_nfct_reset();
}
NRF_LOG_INFO("HF FIELD LOST");
break;
}
@@ -688,3 +735,11 @@ bool is_valid_uid_size(uint8_t uid_length) {
uid_length == NFC_TAG_14A_UID_DOUBLE_SIZE ||
uid_length == NFC_TAG_14A_UID_TRIPLE_SIZE;
}
void nfc_tag_14a_set_reset_enable(bool enable) {
reset_if_field_lost = enable;
}
bool nfc_tag_14a_is_reset_enable() {
return reset_if_field_lost;
}
@@ -115,4 +115,8 @@ void nfc_tag_14a_tx_nbit(uint8_t data, uint32_t bits);
// Determine whether it is an effective UID length
bool is_valid_uid_size(uint8_t uid_length);
// Reset nfc peripheral after field lost
void nfc_tag_14a_set_reset_enable(bool enable);
bool nfc_tag_14a_is_reset_enable();
#endif
@@ -1111,6 +1111,8 @@ int nfc_tag_mf1_data_loadcb(tag_specific_type_t type, tag_data_buffer_t *buffer)
.cb_reset = nfc_tag_mf1_reset_handler,
};
nfc_tag_14a_set_handler(&handler_for_14a);
NRF_LOG_INFO("HF mf1 config 'field_off_do_reset' = %d", m_tag_information->config.field_off_do_reset);
nfc_tag_14a_set_reset_enable(m_tag_information->config.field_off_do_reset);
NRF_LOG_INFO("HF mf1 data load finish.");
} else {
NRF_LOG_ERROR("nfc_tag_mf1_information_t too big.");
@@ -1157,6 +1159,12 @@ bool nfc_tag_mf1_data_factory(uint8_t slot, tag_specific_type_t tag_type) {
p_mf1_information->config.use_mf1_coll_res = false;
p_mf1_information->config.mode_block_write = NFC_TAG_MF1_WRITE_NORMAL;
p_mf1_information->config.detection_enable = false;
p_mf1_information->config.field_off_do_reset = false;
// zero for reserved byte
p_mf1_information->config.reserved1 = 0x00;
p_mf1_information->config.reserved2 = 0x00;
p_mf1_information->config.reserved3 = 0x00;
// save data to flash
tag_sense_type_t sense_type = get_sense_type_from_tag_type(tag_type);
@@ -1236,3 +1244,10 @@ nfc_tag_mf1_write_mode_t nfc_tag_mf1_get_write_mode(void) {
return m_tag_information->config.mode_block_write;
}
void nfc_tag_mf1_set_field_off_do_reset(bool enable) {
m_tag_information->config.field_off_do_reset = enable;
}
bool nfc_tag_mf1_is_field_off_do_reset(void) {
return m_tag_information->config.field_off_do_reset;
}
@@ -71,8 +71,15 @@ typedef struct {
uint8_t detection_enable: 1;
// Allow to write block 0 (CUID/gen2 mode)
uint8_t mode_gen2_magic: 1;
// reserve
uint8_t reserved1: 4;
/**
* Should the NFC peripheral be reset after losing the RF field?
* This configuration can fix the issue where some card readers cause the CU to enter a strange state of no response/incorrect response.
* Once in this state, the device must be restarted to resolve the issue.
* Alternatively, enabling this configuration for resetting the NFC after leaving the rf field can also solve the aforementioned problem.
*/
uint8_t field_off_do_reset: 1;
// reserved
uint8_t reserved1: 3;
uint8_t reserved2;
uint8_t reserved3;
} nfc_tag_mf1_configure_t;
@@ -157,6 +164,7 @@ void nfc_tag_mf1_set_use_mf1_coll_res(bool enable);
bool nfc_tag_mf1_is_use_mf1_coll_res(void);
void nfc_tag_mf1_set_write_mode(nfc_tag_mf1_write_mode_t write_mode);
nfc_tag_mf1_write_mode_t nfc_tag_mf1_get_write_mode(void);
void nfc_tag_mf1_set_field_off_do_reset(bool enable);
bool nfc_tag_mf1_is_field_off_do_reset(void);
#endif
+12 -15
View File
@@ -40,19 +40,19 @@ APP_USBD_CDC_ACM_GLOBAL_DEF(m_app_cdc_acm,
volatile bool g_usb_connected = false;
volatile bool g_usb_port_opened = false;
volatile bool g_usb_led_marquee_enable = true;
static uint8_t cdc_data_buffer[NRF_DRV_USBD_EPSIZE];
/** @brief User event handler @ref app_usbd_cdc_acm_user_ev_handler_t */
static void cdc_acm_user_ev_handler(app_usbd_class_inst_t const *p_inst, app_usbd_cdc_acm_user_event_t event) {
static uint8_t cdc_data_buffer[1];
// app_usbd_cdc_acm_t const *p_cdc_acm = app_usbd_cdc_acm_class_get(p_inst);
switch (event) {
case APP_USBD_CDC_ACM_USER_EVT_PORT_OPEN: {
/*
*theProbabilityOfTheEntireUsbReceivingDataIsTheAppUsbdCdcAcmRead *AppUsbdCdcAcmReadFunctionIsNotASeriousReception,ItIsGivenAPointer,AndThenWaitForTheUsbBuffer *SoYouNeedToInitializeTheHeadPointerFirstWhenTheAppUsbdCdcAcmUserEvtPortOpenIsInitialized *IfTheAppUsbdCdcAcmUserEvtRxDoneUsesASubscribed0ToAccessTheBuffer,ItWillCauseTheFirstByteToLoseTheFirstSendEssence
*/
ret_code_t ret = app_usbd_cdc_acm_read(&m_app_cdc_acm, cdc_data_buffer, 1);
// Setup first transfer
ret_code_t ret = app_usbd_cdc_acm_read_any(&m_app_cdc_acm, cdc_data_buffer, sizeof(cdc_data_buffer));
UNUSED_VARIABLE(ret);
NRF_LOG_INFO("CDC ACM port opened");
g_usb_port_opened = true;
break;
@@ -68,16 +68,13 @@ static void cdc_acm_user_ev_handler(app_usbd_class_inst_t const *p_inst, app_usb
break;
case APP_USBD_CDC_ACM_USER_EVT_RX_DONE: {
ret_code_t ret;
//Take out the first byte first
data_frame_receive(cdc_data_buffer, 1);
do {
ret = app_usbd_cdc_acm_read(&m_app_cdc_acm, cdc_data_buffer, 1);
if (ret == NRF_SUCCESS) {
// The byte after success
data_frame_receive(cdc_data_buffer, 1);
}
} while (ret == NRF_SUCCESS);
// Get amount of data transfered to process data
size_t size = app_usbd_cdc_acm_rx_size(&m_app_cdc_acm);
data_frame_receive(cdc_data_buffer, size);
// Setup next transfer
ret_code_t ret = app_usbd_cdc_acm_read_any(&m_app_cdc_acm, cdc_data_buffer, sizeof(cdc_data_buffer));
UNUSED_VARIABLE(ret);
break;
}
default:
+15 -9
View File
@@ -28,6 +28,11 @@ static uint8_t compute_lrc(uint8_t *buf, uint16_t bufsize) {
return 0x100 - lrc;
}
//
// !!!!!!!!!!!!!!!!! NRF_LOG_HEXDUMP_INFO() printing long data can cause freezing and needs to be fixed. !!!!!!!!!!!!!!!!!
// FIXME.
//
/**
* @brief: create a packet, put the created data packet into the buffer, and wait for the post to set up a non busy state
* @param cmd: instructionResponse
@@ -44,10 +49,11 @@ data_frame_tx_t *data_frame_make(uint16_t cmd, uint16_t status, uint16_t data_le
NRF_LOG_ERROR("data_frame_make error, too much data.");
return NULL;
}
NRF_LOG_INFO("TX Data frame: cmd = 0x%04x (%i), status = 0x%04x, length = %d%s", cmd, cmd, status, data_length, data_length > 0 ? ", data =" : "");
if (data_length > 0) {
NRF_LOG_HEXDUMP_INFO(data, data_length);
}
// NRF_LOG_INFO("TX Data frame: cmd = 0x%04x (%i), status = 0x%04x, length = %d%s", cmd, cmd, status, data_length, data_length > 0 ? ", data =" : "");
// if (data_length > 0) {
// NRF_LOG_HEXDUMP_INFO(data, data_length);
// }
netdata_frame_postamble_t *tx_post = (netdata_frame_postamble_t *)((uint8_t *)&m_netdata_frame_tx_buf + sizeof(netdata_frame_preamble_t) + data_length);
// sof
@@ -92,7 +98,7 @@ void data_frame_receive(uint8_t *data, uint16_t length) {
return;
}
// buffer overflow
if (m_data_rx_position + length >= sizeof(m_netdata_frame_rx_buf)) {
if (m_data_rx_position + length > sizeof(m_netdata_frame_rx_buf)) {
NRF_LOG_ERROR("Data frame wait overflow.");
data_frame_reset();
return;
@@ -142,10 +148,10 @@ void data_frame_receive(uint8_t *data, uint16_t length) {
// and we are receive completed
m_data_buffer = m_data_len > 0 ? (uint8_t *)&m_netdata_frame_rx_buf.data : NULL;
m_data_completed = true;
NRF_LOG_INFO("RX Data frame: cmd = 0x%04x (%i), status = 0x%04x, length = %d%s", m_data_cmd, m_data_cmd, m_data_status, m_data_len, m_data_len > 0 ? ", data =" : "");
if (m_data_len > 0) {
NRF_LOG_HEXDUMP_INFO(m_data_buffer, m_data_len);
}
// NRF_LOG_INFO("RX Data frame: cmd = 0x%04x (%i), status = 0x%04x, length = %d%s", m_data_cmd, m_data_cmd, m_data_status, m_data_len, m_data_len > 0 ? ", data =" : "");
// if (m_data_len > 0) {
// NRF_LOG_HEXDUMP_INFO(m_data_buffer, m_data_len);
// }
} else {
// data frame lrc error
NRF_LOG_ERROR("Data frame finally lrc error.");
+2 -1
View File
@@ -259,7 +259,8 @@ 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/\..*//')
# The return value of the Windows+msys2 build platform has carriage returns and line breaks, which need to be removed.
CC_VERSION = $(shell $(CC) -dumpversion 2>/dev/null | tr -d '\r' | cut -d. -f1)
CC_VERSION := $(or $(strip $(CC_VERSION)),0)
ifeq ($(shell expr $(CC_VERSION) \>= 12), 1)
# avoid a couple of false warnings in nRF SDK
@@ -818,29 +818,9 @@ void nrfx_nfct_irq_handler(void)
NRFX_NFCT_CB_HANDLE(m_nfct_cb.config.cb, nfct_evt);
/* Clear TXFRAMESTART EVENT so it can be checked in hal_nfc_send */
nrf_nfct_event_clear(NRF_NFCT_EVENT_TXFRAMESTART);
NRFX_LOG_DEBUG("Rx fend");
}
if (NRFX_NFCT_EVT_ACTIVE(TXFRAMEEND))
{
nrf_nfct_event_clear(NRF_NFCT_EVENT_TXFRAMEEND);
nrfx_nfct_evt_t nfct_evt =
{
.evt_id = NRFX_NFCT_EVT_TX_FRAMEEND
};
/* Disable TX END event to ignore frame transmission other than READ response */
nrf_nfct_int_disable(NRFX_NFCT_TX_INT_MASK);
NRFX_NFCT_CB_HANDLE(m_nfct_cb.config.cb, nfct_evt);
NRFX_LOG_DEBUG("Tx fend");
}
if (NRFX_NFCT_EVT_ACTIVE(SELECTED))
{
nrf_nfct_event_clear(NRF_NFCT_EVENT_SELECTED);
@@ -913,6 +893,23 @@ void nrfx_nfct_irq_handler(void)
m_nfct_cb.config.cb(&nfct_evt);
}
}
if (NRFX_NFCT_EVT_ACTIVE(TXFRAMEEND))
{
nrf_nfct_event_clear(NRF_NFCT_EVENT_TXFRAMEEND);
nrfx_nfct_evt_t nfct_evt =
{
.evt_id = NRFX_NFCT_EVT_TX_FRAMEEND
};
/* Disable TX END event to ignore frame transmission other than READ response */
nrf_nfct_int_disable(NRFX_NFCT_TX_INT_MASK);
NRFX_NFCT_CB_HANDLE(m_nfct_cb.config.cb, nfct_evt);
NRFX_LOG_DEBUG("Tx fend");
}
}
#endif // NRFX_CHECK(NRFX_NFCT_ENABLED)