translate fw app comments

This commit is contained in:
Philippe Teuwen
2023-08-23 03:56:42 +02:00
parent dbda8b92fb
commit e7e4be04d0
41 changed files with 1824 additions and 1831 deletions
+8 -8
View File
@@ -295,24 +295,24 @@ static void system_off_enter(void) {
// Turn off all soft timers
app_timer_stop_all();
// 检查是否存在低频场,解决休眠时有非常强的场信号一直使比较器处于高电平输入状态从而无法产生上升沿而无法唤醒系统的问题。
// Check whether there are low -frequency fields, solving very strong field signals during dormancy have always caused the comparator to be at a high level input state, so that the problem of uprising the rising edge cannot be awakened.
if (lf_is_field_exists()) {
// 关闭比较器
// Close the comparator
nrf_drv_lpcomp_disable();
// 设置reset原因,重启后需要拿到此原因,避免误判唤醒源
// Set the reason for Reset. After restarting, you need to get this reason to avoid misjudgment from the source of wake up.
sd_power_gpregret_clr(1, GPREGRET_CLEAR_VALUE_DEFAULT);
sd_power_gpregret_set(1, RESET_ON_LF_FIELD_EXISTS_Msk);
// 触发reset唤醒系统,重新启动模拟过程
// Trigger the RESET awakening system, restart the simulation process
nrf_pwr_mgmt_shutdown(NRF_PWR_MGMT_SHUTDOWN_RESET);
return;
};
// Go to system-off mode (this function will not return; wakeup will cause a reset).
// 注意,如果插着jlink或者开着debug,进入低功耗的函数可能会报错,
// 开启调试时我们应当禁用低功耗状态值检测,或者干脆不进入低功耗
// Note that if you insert jlink or drive a Debug, you may report an error when entering the low power consumption.
// When starting debugging, we should disable low power consumption state values, or simply not enter low power consumption
ret = sd_power_system_off();
// OK,此处非常重要,如果开启了日志输出并且使能了RTT,则不去检查低功耗模式的错误
// OK, here is very important. If you open the log output and enable RTT, you will not check the error of the low power mode
#if !(NRF_LOG_ENABLED && NRF_LOG_BACKEND_RTT_ENABLED)
APP_ERROR_CHECK(ret);
#else
@@ -389,7 +389,7 @@ static void check_wakeup_src(void) {
}
}
// 当前是模拟卡事件唤醒系统,我们可以让场强灯先亮起来
// It is currently the wake -up system of the simulation card event, we can make the strong lights on the field first
TAG_FIELD_LED_ON();
uint8_t animation_config = settings_get_animation_config();
+23 -23
View File
@@ -5,42 +5,42 @@
/////////////////////////////////////////////////////////////////////
// 14a status
/////////////////////////////////////////////////////////////////////
#define HF_TAG_OK (0x00) // IC卡操作成功
#define HF_TAG_NO (0x01) // 没有发现IC卡
#define HF_ERRSTAT (0x02) // IC卡通信异常
#define HF_ERRCRC (0x03) // IC卡通信校验异常
#define HF_COLLISION (0x04) // IC卡冲突
#define HF_ERRBCC (0x05) // IC卡BCC错误
#define MF_ERRAUTH (0x06) // MF卡验证失败
#define HF_ERRPARITY (0x07) // IC卡奇偶校验错误
#define HF_TAG_OK (0x00) // IC card operation successfully
#define HF_TAG_NO (0x01) // No IC card found
#define HF_ERRSTAT (0x02) // IC cartoon letter abnormal
#define HF_ERRCRC (0x03) // IC Card communication verification abnormality
#define HF_COLLISION (0x04) // IC card conflict
#define HF_ERRBCC (0x05) // IC card BCC error
#define MF_ERRAUTH (0x06) // MF card verification failed
#define HF_ERRPARITY (0x07) // ica Kazi even verification error
/////////////////////////////////////////////////////////////////////
// MIFARE status
/////////////////////////////////////////////////////////////////////
#define DARKSIDE_CANT_FIXED_NT (0x20) // Darkside,无法固定随机数,这个情况可能出现在UID卡上
#define DARKSIDE_LUCK_AUTH_OK (0x21) // Darkside,直接验证成功了,可能刚好密钥是空的
#define DARKSIDE_NACK_NO_SEND (0x22) // Darkside,卡片不响应nack,可能是一张修复了nack逻辑漏洞的卡片
#define DARKSIDE_TAG_CHANGED (0x23) // Darkside,在运行darkside的过程中出现了卡片切换,可能信号问题,或者真的是两张卡迅速切换了
#define NESTED_TAG_IS_STATIC (0x24) // Nested,检测到卡片应答的随机数是固定的
#define NESTED_TAG_IS_HARD (0x25) // Nested,检测到卡片应答的随机数是不可预测的
#define DARKSIDE_CANT_FIXED_NT (0x20) // Darkside, the random number cannot be fixed, this situation may appear on the UID card
#define DARKSIDE_LUCK_AUTH_OK (0x21) // Darkside, the direct verification is successful, maybe the key is just empty
#define DARKSIDE_NACK_NO_SEND (0x22) // Darkside, the card does not respond to NACK, it may be a card that fixes Nack logic vulnerabilities
#define DARKSIDE_TAG_CHANGED (0x23) // Darkside, card switching in the process of running DARKSIDE, May is the two cards quickly switched
#define NESTED_TAG_IS_STATIC (0x24) // Nested, the random number of the card response is fixed
#define NESTED_TAG_IS_HARD (0x25) // Nested, the random number of the card response is unpredictable
/////////////////////////////////////////////////////////////////////
// lf status
/////////////////////////////////////////////////////////////////////
#define LF_TAG_OK (0x40) // 低频卡的一些操作成功!
#define EM410X_TAG_NO_FOUND (0x41) // 无法搜索到有效的EM410X标签
#define LF_TAG_OK (0x40) // Some of the low -frequency cards are successful!
#define EM410X_TAG_NO_FOUND (0x41) // Can't search for valid EM410X tags
/////////////////////////////////////////////////////////////////////
// other status
/////////////////////////////////////////////////////////////////////
#define STATUS_PAR_ERR (0x60) // BLE指令传递的参数错误,或者是调用某些函数传递的参数错误
#define STATUS_DEVIEC_MODE_ERROR (0x66) // 当前设备所处的模式错误,无法调用对应的API
#define STATUS_INVALID_CMD (0x67) // 无效的指令
#define STATUS_DEVICE_SUCCESS (0x68) // 设备相关操作成功执行
#define STATUS_NOT_IMPLEMENTED (0x69) // 调用了某些未实现的操作,属于开发者遗漏的错误
#define STATUS_FLASH_WRITE_FAIL (0x70) // flash写入失败
#define STATUS_FLASH_READ_FAIL (0x71) // flash读取失败
#define STATUS_PAR_ERR (0x60) // The parameter errors transferred by the BLE instruction, or call the parameter error transmitted by certain functions
#define STATUS_DEVIEC_MODE_ERROR (0x66) // The mode of the current device is wrong, and the corresponding API cannot be called
#define STATUS_INVALID_CMD (0x67) // Invalid instruction
#define STATUS_DEVICE_SUCCESS (0x68) // Device -related operations successfully executed
#define STATUS_NOT_IMPLEMENTED (0x69) // Calling some unrealized operations, which belongs to the missed error of the developer
#define STATUS_FLASH_WRITE_FAIL (0x70) // Flash writing failed
#define STATUS_FLASH_READ_FAIL (0x71) // Flash read failed
#endif
+21 -21
View File
@@ -189,19 +189,19 @@ __INLINE uint32_t map(uint32_t x, uint32_t in_min, uint32_t in_max, uint32_t out
return (uint32_t)((x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min);
}
//电池电压到百分比计算
//Battery voltage to percentage calculation
uint32_t BATVOL2PERCENT(uint16_t VOL) {
//100% 4.20V 1
//90 % 4.06V 80%-100%
//90 % 4.06V 80%-100% white
//80 % 3.98V 1
//70 % 3.92V 60%-80%
//70 % 3.92V 60%-80% white
//60 % 3.87V 1
//50 % 3.82V 40%-60%
//50 % 3.82V 40%-60% white
//40 % 3.79V 1
//30 % 3.77V 20%-40%
//30 % 3.77V 20%-40% white
//20 % 3.74V 1
//10 % 3.68V 5%-20%
//5 % 3.45V 1 关机
//10 % 3.68V 5%-20% red
//5 % 3.45V 1 Turn off
//0 % 3.00V
//#define P100VOL 4200
//#define P80VOL 3980
@@ -211,16 +211,16 @@ uint32_t BATVOL2PERCENT(uint16_t VOL) {
//#define P5VOL 3450
//100% 4.20V 1
//90 % 4.00V 80%-100%
//90 % 4.00V 80%-100% white
//80 % 3.89V 1
//70 % 3.79V 60%-80%
//70 % 3.79V 60%-80% white
//60 % 3.70V 1
//50 % 3.62V 40%-60%
//50 % 3.62V 40%-60% white
//40 % 3.57V 1
//30 % 3.53V 20%-40%
//30 % 3.53V 20%-40% white
//20 % 3.51V 1
//10 % 3.46V 5%-20%
//5 % 3.43V 1 关机
//10 % 3.46V 5%-20% red
//5 % 3.43V 1 Turn off
//0 % 3.00V
#define P100VOL 4200
#define P80VOL 3890
@@ -610,12 +610,12 @@ void create_battery_timer(void) {
* @brief Function for init ble slave.
*/
void ble_slave_init(void) {
adc_configure(); // ADC初始化
create_battery_timer(); // 创建电池电量更新定时器
ble_stack_init(); // BLE协议栈初始化
gap_params_init(); // GAP参数初始化
gatt_init(); // GATT协议初始化
services_init(); // 服务特征初始化
advertising_init(); // 广播参数初始化
conn_params_init(); // 连接参数初始化
adc_configure(); // ADC initialization
create_battery_timer(); // Create a battery power update timer
ble_stack_init(); // BLE protocol stack initialization
gap_params_init(); // GAP parameter initialization
gatt_init(); // Gatt protocol initialization
services_init(); // Initialization of service characteristics
advertising_init(); // Broadcast parameter initialization
conn_params_init(); // Connection parameter initialization
}
+5 -5
View File
@@ -3,18 +3,18 @@
#include "nrf_delay.h"
//初始化延迟函数
//Initialized delay function
void bsp_delay_init(void) {
}
//延时nms
//注意nms的范围
//Delay NMS
//Pay attention to the range of NMS
void bsp_delay_ms(uint16_t nms) {
nrf_delay_us(nms * 1000);
}
//延时nus
//nus为要延时的us数.
//Delay NUS
//NUS is the number of US numbers to be delayed.
void bsp_delay_us(uint32_t nus) {
nrf_delay_us(nus);
}
+22 -22
View File
@@ -2,16 +2,16 @@
#include "app_timer.h"
#define TICK_PERIOD APP_TIMER_TICKS(10) // 定时时间
#define TICK_PERIOD APP_TIMER_TICKS(10) // Timing
// 定义一个软定时器
// Define a soft timer
APP_TIMER_DEF(m_app_timer);
// 定时器池
// Timer pool
autotimer bsptimers[TIMER_BSP_COUNT] = { 0 };
// 定时器迭代位置
// Timer iteration position
static uint8_t g_timer_fori;
// 当前定时器运行状态
// The current timer is running status
static volatile enum {
UNINIT,
INIT,
@@ -21,9 +21,9 @@ static volatile enum {
/*
* 获取一个空闲的定时器,这个定时器
* 1、会自动跑滴答
* 2、是空闲的
* Get a free timer, this timer
* 1. Will run automatically
* 2. It's free
*/
autotimer *bsp_obtain_timer(uint32_t start_value) {
uint8_t i;
@@ -38,7 +38,7 @@ autotimer *bsp_obtain_timer(uint32_t start_value) {
}
/*
* 设置定时器,该操作会操作目标定时器,修改当前值
* Set the timer, the operation will operate the target timer and modify the current value
*/
inline uint8_t bsp_set_timer(autotimer *timer, uint32_t start_value) {
if (timer->busy == 0) return 0;
@@ -47,17 +47,17 @@ inline uint8_t bsp_set_timer(autotimer *timer, uint32_t start_value) {
}
/*
* 归还定时器,该操作会自动释放定时器
* 并且对定时器归零
* Return the timer, the operation will automatically release the timer
* And zero to the timer
*/
inline void bsp_return_timer(autotimer *timer) {
timer->busy = 0;
timer->time = 0;
}
/** @brief 测试定时器的回调函数
* @param arg 回调参数
* @return
/** @brief Test timer callback function
* @param arg Callback parameter
* @return none
*/
void timer_app_callback(void *arg) {
UNUSED_PARAMETER(arg);
@@ -68,26 +68,26 @@ void timer_app_callback(void *arg) {
}
}
// 初始化定时器
// Initialized timer
void bsp_timer_init(void) {
if (bsp_timer_state == UNINIT) {
bsp_timer_state = INIT;
// 创建定时器
// Create a timer
ret_code_t err_code = app_timer_create(&m_app_timer, APP_TIMER_MODE_REPEATED, timer_app_callback);
APP_ERROR_CHECK(err_code);
}
}
// 反初始化定时器
// Counter -initialization timer
void bsp_timer_uninit(void) {
// 暂时无法反初始化软定时器,只能关闭
// Can't reverse the initialized soft timer for the time being, it can only be closed
bsp_timer_stop();
}
// 启动定时器
// Start the timer
void bsp_timer_start(void) {
if (bsp_timer_state != UNINIT) {
// 确保定时器没有被启动过
// Make sure the timer is not started
if (bsp_timer_state != START) {
app_timer_start(m_app_timer, TICK_PERIOD, NULL);
bsp_timer_state = START;
@@ -96,11 +96,11 @@ void bsp_timer_start(void) {
}
// 停止定时器
// Stop timer
void bsp_timer_stop(void) {
if (bsp_timer_state != UNINIT) {
if (bsp_timer_state == START) {
// 停止定时器
// Stop timer
app_timer_stop(m_app_timer);
bsp_timer_state = STOP;
}
+6 -6
View File
@@ -6,20 +6,20 @@
#ifndef NULL
#define NULL ((void *)0)
#endif
//定义可以同时使用的计时器的最多数量
//Define the maximum number of timer that can be used at the same time
#define TIMER_BSP_COUNT 10
// 定义一个结构体
// 这个结构体存放了基本的时钟信息
// Define a structure
// This structure stores basic clock information
typedef struct {
// 当前定时器的滴答数
// The number of ticks of the current timer
volatile uint32_t time;
// 是否繁忙
// Whether it is busy
uint8_t busy;
} autotimer;
// 实现一个判断超时的宏定义
// Realize a grand definition of judgment timeout
#define NO_TIMEOUT_1MS(timer, count) ((((autotimer*)timer)->time <= (count))? 1: 0)
void bsp_timer_init(void);
+8 -8
View File
@@ -1,6 +1,6 @@
#include "crc_utils.h"
// CRC查表
//CRC check table
static uint16_t crc_table[256] = {
0x0000, 0x1189, 0x2312, 0x329B, 0x4624, 0x57AD, 0x6536, 0x74BF,
0x8C48, 0x9DC1, 0xAF5A, 0xBED3, 0xCA6C, 0xDBE5, 0xE97E, 0xF8F7,
@@ -38,17 +38,17 @@ static uint16_t crc_table[256] = {
/**
* @brief 在MCU上使用查表法计算14443a协议专用的CRCcrc16
* @param data 将被计算的CRC的原始数据
* @param length 数据的长度,不包括CRC
* @param output 输出缓冲区,长度必须是大于等于两个字节
* @brief Use the table check method on the MCU to calculate the CRC (CRC16) dedicated to the 144443A protocol.
* @param data The original data of the calculated CRC
* @param length The length of the data does not include CRC
* @param output The output buffer must be greater than or equal to two bytes
*
*/
void calc_14a_crc_lut(uint8_t *data, int length, uint8_t *output) {
// 取巧,强制指针类型转换
//Take the clever, compulsory pointer type conversion
uint16_t *crc = (uint16_t *)output;
// 赋予多项式初始值
//Give the initial value of polynomial
*crc = 0x6363;
// 然后开始对每个字节进行查表
//Then start checking the table of each byte
while (length--) *crc = (*crc >> 8) ^ crc_table[(*crc & 0xFF) ^ *data++];
}
+9 -9
View File
@@ -2,11 +2,11 @@
/**
* @brief : 将大数字转换为HEX字节数组
* @param :n : 将被转换的值
* @param :len : 存放转换后的数值的字节长度
* @param :dest : 存放转换结果的缓冲区
* @retval :
* @brief : Convert the large number to the hex byte array
* @param :n : The value of the conversion
* @param :len : The byte length of the value after the conversion is stored
* @param :dest : Caps that store conversion results
* @retval : none
*
*/
void num_to_bytes(uint64_t n, uint8_t len, uint8_t *dest) {
@@ -17,10 +17,10 @@ void num_to_bytes(uint64_t n, uint8_t len, uint8_t *dest) {
}
/**
* @brief : 将字节数组转换为大数字
* @param :len : 存放数值的缓冲区的字节长度
* @param :src : 存放数值的字节缓冲区
* @retval : 转换结果
* @brief : Convert byte array to large number
* @param :len : The byte length of the buffer of the value of the value
* @param :src : Byte buffer stored in the numerical
* @retval : Converting result
*
*/
uint64_t bytes_to_num(uint8_t *src, uint8_t len) {
@@ -24,9 +24,9 @@ void mf_crypto1_encryptEx(struct Crypto1State *pcs, uint8_t *data_in, uint8_t *k
int i;
for (i = 0; i < len; i++) {
uint8_t bt = data_in[i];
// 加密字节流
// Encrypted bytes
data_out[i] = crypto1_byte(pcs, keystream ? keystream[i] : 0x00, 0) ^ data_in[i];
// 生成奇偶校验位
// Generate strange school inspection
par[i] = filter(pcs->odd) ^ oddparity8(bt);
}
}
File diff suppressed because it is too large Load Diff
@@ -8,7 +8,7 @@
#define NFC_TAG_14A_CRC_LENGTH 2
// 是否使能自动移除奇偶校验位(硬件移除)
// Whether to automatically remove the coupling school test (hardware removed)
#define NFC_TAG_14A_RX_PARITY_AUTO_DEL_ENABLE 0
#define NFC_TAG_14A_CASCADE_CT 0x88
@@ -27,51 +27,51 @@
// TBIV = Transfer Buffer Invalid
#define ACK_NAK_FRAME_SIZE 4 /* Bits */
#define ACK_VALUE 0x0A
#define NAK_INVALID_OPERATION_TBV 0x00 // 这个不常用
#define NAK_CRC_PARITY_ERROR_TBV 0x01 // 这个不常用
#define NAK_INVALID_OPERATION_TBV 0x00 //This is not commonly used
#define NAK_CRC_PARITY_ERROR_TBV 0x01 //This is not commonly used
#define NAK_INVALID_OPERATION_TBIV 0x04
#define NAK_CRC_PARITY_ERROR_TBIV 0x05
#define NAK_OTHER_ERROR 0x06 // 这个不在手册中定义,属于变色龙特有(可能需要扇区)
#define NAK_OTHER_ERROR 0x06 // This is not defined in the manual, it belongs to the color -changing dragon special (may need the sector)
// ISO14443-A 通用状态机
// ISO14443-A Universal state machine
typedef enum {
NFC_TAG_STATE_14A_IDLE, // 空闲状态,可等待任何指令
NFC_TAG_STATE_14A_READY, // 选卡状态,当前在进行标准的14A防冲撞
NFC_TAG_STATE_14A_ACTIVE, // 选卡或者其他指令使其进入工作状态,可接收处理所有的数据
NFC_TAG_STATE_14A_HALTED, // 标签中止工作状态,只能由halt或者其他特殊指令(非标)唤醒
NFC_TAG_STATE_14A_IDLE, // Leisure, you can wait for any instructions
NFC_TAG_STATE_14A_READY, // Select card status, currently the standard 14A anti -rushing collision
NFC_TAG_STATE_14A_ACTIVE, // Select cards or other instructions to enter the working status, which can receive all data
NFC_TAG_STATE_14A_HALTED, // The label stops working status and can only be awakened by Halt or other special instructions (non -labels)
} nfc_tag_14a_state_t;
// 枚举规范内的长度的UID
//UID of the length in the enumeration specification
typedef enum {
NFC_TAG_14A_UID_SINGLE_SIZE = 4u, ///< Length of single-size NFCID1.
NFC_TAG_14A_UID_DOUBLE_SIZE = 7u, ///< Length of double-size NFCID1.
NFC_TAG_14A_UID_TRIPLE_SIZE = 10u, ///< Length of triple-size NFCID1.
} nfc_tag_14a_uid_size;
// 枚举规范内的级联等级
// Extraordinarian level level level level level
typedef enum {
NFC_TAG_14A_CASCADE_LEVEL_1,
NFC_TAG_14A_CASCADE_LEVEL_2,
NFC_TAG_14A_CASCADE_LEVEL_3,
} nfc_tag_14a_cascade_level_t;
// ats封装结构体
// ATS packaging structure
typedef struct {
uint8_t data[0xFF];
uint8_t length;
} nfc_14a_ats_t;
// 基于bit的防冲撞需要用上的资源实体,占用空间大
// Bit -based anti -bumps need to use the resource entity that needs to be used, occupying a large space
typedef struct {
nfc_tag_14a_uid_size size; // uid的长度
nfc_tag_14a_uid_size size; // UID length
uint8_t atqa[2]; // atqa
uint8_t sak[1]; // sak
uint8_t uid[10]; // uid,最大十个字节
uint8_t uid[10]; // uid,The largest ten bytes
nfc_14a_ats_t ats;
} nfc_tag_14a_coll_res_entity_t;
// 防冲突资源的封装引用,纯引用空间占用比较小
// Calculation of anti -conflict resources, pure quoting space occupation is relatively small
typedef struct {
nfc_tag_14a_uid_size *size;
uint8_t *atqa;
@@ -80,31 +80,31 @@ typedef struct {
nfc_14a_ats_t *ats;
} nfc_tag_14a_coll_res_referen_t;
// 通信接管需要实现的回调函数
// Communication reception function that needs to be implemented
typedef void (*nfc_tag_14a_reset_handler_t)(void);
typedef void (*nfc_tag_14a_state_handler_t)(uint8_t *data, uint16_t szBits);
typedef nfc_tag_14a_coll_res_referen_t *(*nfc_tag_14a_coll_handler_t)(void);
// 14a通信接管者需要实现的接口
// The interface that 14A communication receiver needs to be implemented
typedef struct {
nfc_tag_14a_reset_handler_t cb_reset;
nfc_tag_14a_state_handler_t cb_state;
nfc_tag_14a_coll_handler_t get_coll_res;
} nfc_tag_14a_handler_t;
// 异或校验码
// Different or verification code
void nfc_tag_14a_create_bcc(uint8_t *pbtData, size_t szLen, uint8_t *pbtBcc);
void nfc_tag_14a_append_bcc(uint8_t *pbtData, size_t szLen);
// 14a循环冗余校验码
// 14A cycle redundant school code
void nfc_tag_14a_append_crc(uint8_t *pbtData, size_t szLen);
bool nfc_tag_14a_checks_crc(uint8_t *pbtData, size_t szLen);
// 14a帧组解
// 14A frame combination
uint8_t nfc_tag_14a_wrap_frame(const uint8_t *pbtTx, const size_t szTxBits, const uint8_t *pbtTxPar, uint8_t *pbtFrame);
uint8_t nfc_tag_14a_unwrap_frame(const uint8_t *pbtFrame, const size_t szFrameBits, uint8_t *pbtRx, uint8_t *pbtRxPar);
// 14a通信控制
// 14A communication control
void nfc_tag_14a_sense_switch(bool enable);
void nfc_tag_14a_set_handler(nfc_tag_14a_handler_t *handler);
void nfc_tag_14a_set_state(nfc_tag_14a_state_t state);
@@ -114,7 +114,7 @@ void nfc_tag_14a_tx_bits(uint8_t *data, uint32_t bits);
void nfc_tag_14a_tx_nbit_delay_window(uint8_t data, uint32_t bits);
void nfc_tag_14a_tx_nbit(uint8_t data, uint32_t bits);
// 判断是否是有效的uid长度
// Determine whether it is an effective UID length
bool is_valid_uid_size(uint8_t uid_length);
#endif
File diff suppressed because it is too large Load Diff
@@ -12,7 +12,7 @@
#define NFC_TAG_MF1_BLOCK_MAX 256
// mf1标签写入模式
//MF1 label writing mode
typedef enum {
NFC_TAG_MF1_WRITE_NORMAL = 0u,
NFC_TAG_MF1_WRITE_DENIED = 1u,
@@ -20,7 +20,7 @@ typedef enum {
NFC_TAG_MF1_WRITE_SHADOW = 3u,
} nfc_tag_mf1_write_mode_t;
// mf1标签gen1a模式状态机
// MF1 tag Gen1a mode state machine
typedef enum {
GEN1A_STATE_DISABLE,
GEN1A_STATE_UNLOCKING,
@@ -28,21 +28,21 @@ typedef enum {
GEN1A_STATE_WRITING,
} nfc_tag_mf1_gen1a_state_machine_t;
// mf1标签标准模式状态机
// MF1 label standard mode state machine
typedef enum {
// 验证状态机
// Verification state machine
MF1_STATE_UNAUTH,
MF1_STATE_AUTHING,
MF1_STATE_AUTHED,
// 操作状态机
// Operating state machine
MF1_STATE_WRITE,
MF1_STATE_INCREMENT,
MF1_STATE_DECREMENT,
MF1_STATE_RESTORE
} nfc_tag_mf1_std_state_machine_t;
// mf1配置
// MF1 configuration
typedef struct {
/**
* Normal write mode (write normally according to the current state, affected by the control bit and the back door card)
@@ -53,31 +53,31 @@ typedef struct {
*/
nfc_tag_mf1_write_mode_t mode_block_write;
/**
* 使m1扇区数据中的部分信息
* 使4 NFC_TAG_14A_UID_SINGLE_SIZE
* 7100SAK的规范说明
* In communication mode, if the interoperability mode is enabled, some information in the M1 sector data will be used
* Otherwise, the information defined by the anti -collision phase will be used alone. This setting is limited to 4 bytes NFC_TAG_14A_UID_SINGLE_SIZE.
* Unless there are any documents that indicate 0 blocks of 7 -bytes and 10 -byte cards with relevant SAK specifications
*/
uint8_t use_mf1_coll_res: 1;
/**
* Chinese Gen1A
* mode_block_write
* Chinese Gen1A back door card mode, the highest permissions of this mode
* After turning on, the response of the back door card operation instruction, and all operations are released directly, not affected by the Mode_block_write and control bit
*/
uint8_t mode_gen1a_magic: 1;
/**
* 使mf1的验证日志
* Make detection, it will automatically record the verification log of MF1
*/
uint8_t detection_enable: 1;
// Allow to write block 0 (CUID/gen2 mode)
uint8_t mode_gen2_magic: 1;
// 保留
// reserve
uint8_t reserved1: 4;
uint8_t reserved2;
uint8_t reserved3;
} nfc_tag_mf1_configure_t;
/*
* mf1标签信息结构4
* flash时将发生访问越界的异常
* MF1 label information structure, keep in mind the 4 -byte alignment
* If the byte alignment is not performed, the abnormalities of visiting the cross -border will occur when the structure is directly stated and saved directly to the Flash
*/
typedef struct __attribute__((aligned(4))) {
nfc_tag_14a_coll_res_entity_t res_coll;
@@ -86,9 +86,9 @@ typedef struct __attribute__((aligned(4))) {
}
nfc_tag_mf1_information_t;
// 4Byte卡片的出厂固化的0块结构
// 4 -earte card's 0 block structure of factory solidification
typedef struct {
// 例如:
// For example:
// 30928E04 28 08 0400 0177A2CC35AFA51D
uint8_t uid[4];
uint8_t bcc[1];
@@ -97,38 +97,38 @@ typedef struct {
uint8_t manufacturer[8];
} nfc_tag_mf1_factory_info_t;
// 通用的mf1扇区尾部块数据结构
// General MF1 sector rear block data structure
typedef struct {
uint8_t keya[6]; // 秘钥A
uint8_t acs[4]; // 控制位
uint8_t keyb[6]; // 秘钥B
uint8_t keya[6]; // Secret A
uint8_t acs[4]; // Control position
uint8_t keyb[6]; // Secret B
} nfc_tag_mf1_trailer_info_t;
// 专用于mifare通信的发送缓冲区
// Send buffer dedicated to miFare communication
typedef struct {
// 原始buffer,用于承载任何未经加密的指令
// Primitive buffer, used to carry any unblocked instructions
uint8_t tx_raw_buffer[NFC_TAG_MF1_FRAME_SIZE];
// 经过crypto1加密后,每个字节的奇偶校验位
// After Crypto1 encrypted, each byte of the puppet test is
uint8_t tx_bit_parity[NFC_TAG_MF1_FRAME_SIZE];
// 用于承载crypto1加密后的数据与parity合并之后的数据
// The maximum frame length is 163 bits (16 data bytes + 2 CRC bytes = 16 × 9 + 2 × 9 + 1 start bit).
// Used to carry data after Crypto1 encrypted data and Parity merged data
// The maximum frame length is 163 bits (16 data bytes + 2 CRC bytes = 16 * 9 + 2 * 9 + 1 start bit).
uint8_t tx_warp_frame[21];
// 打包之后的数据的长度,根据上面的消息可知,mf1通信的最大bit数量不超过163个,
// 因此一个字节足够存放长度值
// The length of the data after packing, according to the above news, it can be seen that the maximum number of BITs of MF1 communication does
// Therefore, a byte is sufficient to store the length value
uint8_t tx_frame_bit_size;
} nfc_tag_mf1_tx_buffer_t;
// mf1标签验证历史记录
// MF1 label verification history
typedef struct {
// 验证的基础信息
// Basic information of verification
struct {
uint8_t block;
uint8_t is_keyb: 1;
uint8_t is_nested: 1;
// 空域,占位置用的
// Airspace, occupying positions
uint8_t : 6;
} cmd;
// mfkey32必要参数
// MFKEY32 necessary parametersessary parameters
uint8_t uid[4];
uint8_t nt[4];
uint8_t nr[4];
@@ -69,13 +69,13 @@ const uint8_t ntagVersion[8] = {0x00, 0x04, 0x04, 0x02, 0x01, 0x00, 0x11, 0x03};
/* pwd auth for amiibo */
uint8_t ntagPwdOK[2] = {0x80, 0x80};
// 指向标签信息的数据结构指针
// Data structure pointer to the label information
static nfc_tag_ntag_information_t *m_tag_information = NULL;
// 定义并且使用影子防冲撞资源
// Define and use shadow anti -collision resources
static nfc_tag_14a_coll_res_referen_t m_shadow_coll_res;
// 定义并且使用ntag专用通信缓冲区
//Define and use NTAG special communication buffer
static nfc_tag_ntag_tx_buffer_t m_tag_tx_buffer;
// 保存当前正在模拟的NTAG的具体类型
// Save the specific type of NTAG currently being simulated
static tag_specific_type_t m_tag_type;
static int get_block_max_by_tag_type(tag_specific_type_t tag_type) {
@@ -190,13 +190,13 @@ void nfc_tag_ntag_state_handler(uint8_t *p_data, uint16_t szDataBits) {
}
nfc_tag_14a_coll_res_referen_t *get_ntag_coll_res() {
// 使用单独的防冲突信息,而不是使用扇区中的信息
// Use a separate anti -conflict information instead of using the information in the sector
m_shadow_coll_res.sak = m_tag_information->res_coll.sak;
m_shadow_coll_res.atqa = m_tag_information->res_coll.atqa;
m_shadow_coll_res.uid = m_tag_information->res_coll.uid;
m_shadow_coll_res.size = &(m_tag_information->res_coll.size);
m_shadow_coll_res.ats = &(m_tag_information->res_coll.ats);
// 最终返回一个只带引用,不带实体的影子数据结构指针
// Finally, a shadow data structure pointer with only reference, no physical shadow,
return &m_shadow_coll_res;
}
@@ -208,14 +208,14 @@ static int get_information_size_by_tag_type(tag_specific_type_t type) {
return sizeof(nfc_tag_14a_coll_res_entity_t) + sizeof(nfc_tag_ntag_configure_t) + (get_block_max_by_tag_type(type) * NFC_TAG_NTAG_DATA_SIZE);
}
/** @brief ntag保存数据之前的回调
* @param type
* @param buffer
* @return 0
/** @brief ntag's callback before saving data
* @param type detailed label type
* @param buffer data buffer
* @return to be saved, the length of the data that needs to be saved, it means not saved when 0
*/
int nfc_tag_ntag_data_savecb(tag_specific_type_t type, tag_data_buffer_t *buffer) {
if (m_tag_type != TAG_TYPE_UNKNOWN) {
// 根据当前标签类型保存对应大小的数据
// Save the corresponding size data according to the current label type
return get_information_size_by_tag_type(type);
} else {
return 0;
@@ -225,11 +225,11 @@ int nfc_tag_ntag_data_savecb(tag_specific_type_t type, tag_data_buffer_t *buffer
int nfc_tag_ntag_data_loadcb(tag_specific_type_t type, tag_data_buffer_t *buffer) {
int info_size = get_information_size_by_tag_type(type);
if (buffer->length >= info_size) {
// 将数据缓冲区强转为ntag结构类型
// Convert the data buffer to NTAG structure type
m_tag_information = (nfc_tag_ntag_information_t *)buffer->buffer;
// 缓存正在模拟的Ntag的具体类型
// The specific type of NTAG that is simulated by the cache
m_tag_type = type;
// 注册14a通信管理接口
// Register 14A communication management interface
nfc_tag_14a_handler_t handler_for_14a = {
.get_coll_res = get_ntag_coll_res,
.cb_state = nfc_tag_ntag_state_handler,
@@ -243,7 +243,7 @@ int nfc_tag_ntag_data_loadcb(tag_specific_type_t type, tag_data_buffer_t *buffer
return info_size;
}
// 初始化ntag的工厂数据
// Initialized NTAG factory data
bool nfc_tag_ntag_data_factory(uint8_t slot, tag_specific_type_t tag_type) {
// default ntag data
uint8_t default_p0[] = { 0x04, 0x68, 0x95, 0x71 };
@@ -15,7 +15,7 @@
typedef struct {
uint8_t mode_uid_magic: 1;
uint8_t detection_enable: 1;
// 保留
// reserve
uint8_t reserved1: 5;
uint8_t reserved2;
uint8_t reserved3;
@@ -18,37 +18,37 @@
NRF_LOG_MODULE_REGISTER();
// 获取指定的位置的bit
// Get the specified position bit
#define GETBIT(v, bit) ((v >> bit) & 0x01)
// 天线控制
// Antenna control
#define ANT_TO_MOD() nrf_gpio_pin_set(LF_MOD)
#define ANT_NO_MOD() nrf_gpio_pin_clear(LF_MOD)
// usb灯效是否允许使能
// Whether the USB light effect is allowed to enable
extern bool g_usb_led_marquee_enable;
// 承载64位ID号的比特数据
// Bit data carrying 64 -bit ID number
static uint64_t m_id_bit_data = 0;
// 当前发送的卡片ID的bit位置
// The bit position of the card ID currently sent
static uint8_t m_bit_send_position;
// 当前是否在发送第一个沿
// Whether to send the first edge
static bool m_is_send_first_edge;
// 当前广播ID号总计几次 33ms 一次,一秒钟大概能广播30次
// The current broadcast ID number is 33ms every few times, and can be broadcast about 30 times a second
static uint8_t m_send_id_count;
// 当前是否正在广播低频卡号中
// Whether it is currently in the low -frequency card number of broadcasting
static volatile bool m_is_lf_emulating = false;
// 发送卡号的定时器,我们使用定时器 3
// The timer of the delivery card number, we use the timer 3
const nrfx_timer_t m_timer_send_id = NRFX_TIMER_INSTANCE(3);
// 缓存标签类型
// Cache label type
static tag_specific_type_t m_tag_type = TAG_TYPE_UNKNOWN;
/**
* @brief EM410X的卡号转为U64的内存布局
* EM4100 使U64足以容纳
* @brief Convert the card number of EM410X to the memory layout of U64 and calculate the puppet school inspection
* According to the instructions of the manual, EM4100 is sufficient to accommodate U64
*/
uint64_t em410x_id_to_memory64(uint8_t id[5]) {
// 联合体,所见即所得
//Union, what you see is obtained
union {
uint64_t u64;
struct {
@@ -123,12 +123,12 @@ uint64_t em410x_id_to_memory64(uint8_t id[5]) {
} bit;
} memory;
// 好了,到了目前最关键的时候了,现在需要赋值和计算奇偶校验位了
// 1、先把前导码给赋值了
// Okay, it's the most critical time at present, and now you need to assign and calculate the Qiqi school inspection
// 1. First assign the front guide code
memory.bit.h00 = memory.bit.h01 = memory.bit.h02 =
memory.bit.h03 = memory.bit.h04 = memory.bit.h05 =
memory.bit.h06 = memory.bit.h07 = memory.bit.h08 = 1;
// 2、把8bit的版本或者自定义ID给赋值了
//2. Assign the 8bit version or custom ID
memory.bit.d00 = GETBIT(id[0], 7);
memory.bit.d01 = GETBIT(id[0], 6);
memory.bit.d02 = GETBIT(id[0], 5);
@@ -139,8 +139,8 @@ uint64_t em410x_id_to_memory64(uint8_t id[5]) {
memory.bit.d12 = GETBIT(id[0], 1);
memory.bit.d13 = GETBIT(id[0], 0);
memory.bit.p1 = memory.bit.d10 ^ memory.bit.d11 ^ memory.bit.d12 ^ memory.bit.d13;
// 3、把32bit的数据给赋值了
// - byte1
// 3. Assign the data of 32Bit
// -byte1
memory.bit.d20 = GETBIT(id[1], 7);
memory.bit.d21 = GETBIT(id[1], 6);
memory.bit.d22 = GETBIT(id[1], 5);
@@ -184,85 +184,85 @@ uint64_t em410x_id_to_memory64(uint8_t id[5]) {
memory.bit.d92 = GETBIT(id[4], 1);
memory.bit.d93 = GETBIT(id[4], 0);
memory.bit.p9 = memory.bit.d90 ^ memory.bit.d91 ^ memory.bit.d92 ^ memory.bit.d93;
// 4、计算纵向的偶校验
// 4. Calculate the vertical puppet verification
memory.bit.pc0 = memory.bit.d00 ^ memory.bit.d10 ^ memory.bit.d20 ^ memory.bit.d30 ^ memory.bit.d40 ^ memory.bit.d50 ^ memory.bit.d60 ^ memory.bit.d70 ^ memory.bit.d80 ^ memory.bit.d90;
memory.bit.pc1 = memory.bit.d01 ^ memory.bit.d11 ^ memory.bit.d21 ^ memory.bit.d31 ^ memory.bit.d41 ^ memory.bit.d51 ^ memory.bit.d61 ^ memory.bit.d71 ^ memory.bit.d81 ^ memory.bit.d91;
memory.bit.pc2 = memory.bit.d02 ^ memory.bit.d12 ^ memory.bit.d22 ^ memory.bit.d32 ^ memory.bit.d42 ^ memory.bit.d52 ^ memory.bit.d62 ^ memory.bit.d72 ^ memory.bit.d82 ^ memory.bit.d92;
memory.bit.pc3 = memory.bit.d03 ^ memory.bit.d13 ^ memory.bit.d23 ^ memory.bit.d33 ^ memory.bit.d43 ^ memory.bit.d53 ^ memory.bit.d63 ^ memory.bit.d73 ^ memory.bit.d83 ^ memory.bit.d93;
// 5、设置最后一个EOF的位,这波转换就算是结束了
//5. Set the position of the last EOF, this wave of conversion is over
memory.bit.s0 = 0;
// 返回联合体中的u64数据,这才是我们最终需要的数据,
// 后期模拟卡只需要拿出每个bit去发送就行了
//Return to the U64 data in the combination, this is the data we finally need,
// In the later stage analog card, just take out each bit to send it
return memory.u64;
}
/**
* @brief
* @brief Judgment field status
*/
bool lf_is_field_exists(void) {
nrf_drv_lpcomp_enable();
bsp_delay_us(20); // 延迟一段时间再采样,避免误判
nrf_lpcomp_task_trigger(NRF_LPCOMP_TASK_SAMPLE); // 触发一次采样
return nrf_lpcomp_result_get() == 1; // 判断LF场状态的采样结果
bsp_delay_us(20); // Display for a period of time and sampling to avoid misjudgment
nrf_lpcomp_task_trigger(NRF_LPCOMP_TASK_SAMPLE); //Trigger a sampling
return nrf_lpcomp_result_get() == 1; //Determine the sampling results of the LF field status
}
void timer_ce_handler(nrf_timer_event_t event_type, void *p_context) {
bool mod;
switch (event_type) {
// 因为我们配置的是使用CC通道2,所以事件回调
// 函数中判断NRF_TIMER_EVENT_COMPARE0事件
// Because we are configured using the CC channel 2, the event recovers
// Detect nrf_timer_event_compare0 event in the function
case NRF_TIMER_EVENT_COMPARE2: {
if (m_is_send_first_edge) {
if (GETBIT(m_id_bit_data, m_bit_send_position)) {
// 发送 1 的第一个沿
// The first edge of the send 1
ANT_TO_MOD();
mod = true;
} else {
// 发送 0 的第一个沿
// The first edge of the send 0
ANT_NO_MOD();
mod = false;
}
m_is_send_first_edge = false; // 下次发送第二个沿
m_is_send_first_edge = false; //The second edge is sent next time
} else {
if (GETBIT(m_id_bit_data, m_bit_send_position)) {
// 发送 1 的第二个沿
// Send the second edge of 1
ANT_NO_MOD();
mod = false;
} else {
// 发送 0 的第二个沿
//The second edge of the send 0
ANT_TO_MOD();
mod = true;
}
m_is_send_first_edge = true; // 下次发送第一个沿
m_is_send_first_edge = true; //The first edge of the next sends next time
}
// measure field only during no-mod half of last bit of last broadcast
if ((! mod) &&
(m_bit_send_position + 1 >= LF_125KHZ_EM410X_BIT_SIZE) &&
(m_send_id_count + 1 >= LF_125KHZ_BORADCAST_MAX)) {
nrfx_timer_disable(&m_timer_send_id); // 关闭广播场的定时器
// 我们不需要任何的事件,仅仅需要检测一下场的状态
nrfx_timer_disable(&m_timer_send_id); // Close the timer of the broadcast venue
// We don't need any events, but only need to detect the state of the field
NRF_LPCOMP->INTENCLR = LPCOMP_INTENCLR_CROSS_Msk | LPCOMP_INTENCLR_UP_Msk | LPCOMP_INTENCLR_DOWN_Msk | LPCOMP_INTENCLR_READY_Msk;
if (lf_is_field_exists()) {
nrf_drv_lpcomp_disable();
nrfx_timer_enable(&m_timer_send_id); // 打开广播场的定时器,继续模拟
nrfx_timer_enable(&m_timer_send_id); // Open the timer of the broadcaster and continue to simulate
} else {
// 开启事件中断,让下次场事件可以正常出入
g_is_tag_emulating = false; // 重设模拟中的标志位
// Open the incident interruption, so that the next event can be in and out normally
g_is_tag_emulating = false; // Reset the flag in the simulation
m_is_lf_emulating = false;
TAG_FIELD_LED_OFF() // 确保关闭LF的场状态的指示灯
TAG_FIELD_LED_OFF() // Make sure the indicator light of the LF field status
NRF_LPCOMP->INTENSET = LPCOMP_INTENCLR_CROSS_Msk | LPCOMP_INTENCLR_UP_Msk | LPCOMP_INTENCLR_DOWN_Msk | LPCOMP_INTENCLR_READY_Msk;
// call sleep_timer_start *after* unsetting g_is_tag_emulating
sleep_timer_start(SLEEP_DELAY_MS_FIELD_125KHZ_LOST); // 启动进入休眠的定时器
sleep_timer_start(SLEEP_DELAY_MS_FIELD_125KHZ_LOST); // Start the timer to enter the sleep
NRF_LOG_INFO("LF FIELD LOST");
}
}
if (m_is_send_first_edge == true) { // 下次发送第一个沿
if (m_is_send_first_edge == true) { // The first edge of the next sends next time
if (++m_bit_send_position >= LF_125KHZ_EM410X_BIT_SIZE) {
m_bit_send_position = 0; // 广播一次成功,bit位置归零
m_bit_send_position = 0; // The broadcast is successful once, and the BIT position is zero
if (++m_send_id_count >= LF_125KHZ_BORADCAST_MAX) {
m_send_id_count = 0; // 广播次数达到上限,重新识别场状态并且重新统计广播次数
m_send_id_count = 0; //The number of broadcasts reaches the upper limit, re -identifies the status of the field and re -statistically count the number of broadcast times
}
}
}
@@ -284,30 +284,30 @@ void timer_ce_handler(nrf_timer_event_t event_type, void *p_context) {
* priority is set to APP_IRQ_PRIORITY_HIGH).
*/
static void lpcomp_event_handler(nrf_lpcomp_event_t event) {
// 仅限于未启动低频模拟时,并且是上升沿事件才去启动模拟卡
// Only when the low -frequency simulation is not launched, and the analog card is started
if (!m_is_lf_emulating && event == NRF_LPCOMP_EVENT_UP) {
// 关闭休眠延时
// Turn off dormant delay
sleep_timer_stop();
// 关闭比较器
// Close the comparator
nrf_drv_lpcomp_disable();
// 设置模拟状态标志位
// Set the simulation status logo bit
m_is_lf_emulating = true;
g_is_tag_emulating = true;
// 模拟卡状态应当关闭USB灯效
// Simulation card status should be turned off the USB light effect
g_usb_led_marquee_enable = false;
// LED状态更新
// LED status update
set_slot_light_color(2);
TAG_FIELD_LED_ON()
// 无论如何,每次场状态发现变化都需要重置发送的bit位置
//In any case, every time the state finds changes, you need to reset the BIT location of the sending
m_send_id_count = 0;
m_bit_send_position = 0;
m_is_send_first_edge = true;
// 开启精准的硬件定时器去广播卡号
// openThePreciseHardwareTimerToTheBroadcastCardNumber
nrfx_timer_enable(&m_timer_send_id);
NRF_LOG_INFO("LF FIELD DETECTED");
@@ -338,9 +338,9 @@ static void lf_sense_enable(void) {
}
static void lf_sense_disable(void) {
nrfx_timer_uninit(&m_timer_send_id); // 反初始化定时器
nrfx_lpcomp_uninit(); // 反初始化比较器
m_is_lf_emulating = false; // 设置为非模拟中状态
nrfx_timer_uninit(&m_timer_send_id); //counterInitializationTimer
nrfx_lpcomp_uninit(); //antiInitializationComparator
m_is_lf_emulating = false; //setAsNonSimulatedState
}
static enum {
@@ -350,21 +350,21 @@ static enum {
} m_lf_sense_state = LF_SENSE_STATE_NONE;
/**
* @brief LF场感应使能状态
* @brief switchLfFieldInductionToEnableTheState
*/
void lf_tag_125khz_sense_switch(bool enable) {
// 初始化调制脚为输出
// initializationModulationFootIsOutput
nrf_gpio_cfg_output(LF_MOD);
// 默认不短路天线(短路会导致RSSI无法判断)
//theDefaultIsNotShortCircuitAntenna (shortCircuitWillCauseRssiToBeUnableToJudge)
ANT_NO_MOD();
// 首次执行或者是禁用状态,只允许初始化
//forTheFirstTimeOrDisabled,OnlyInitializationIsAllowed
if (m_lf_sense_state == LF_SENSE_STATE_NONE || m_lf_sense_state == LF_SENSE_STATE_DISABLE) {
if (enable) {
m_lf_sense_state = LF_SENSE_STATE_ENABLE;
lf_sense_enable();
}
} else { // 其他情况只允许反初始化
} else { // inOtherCases,OnlyAntiInitializationIsAllowed
if (!enable) {
m_lf_sense_state = LF_SENSE_STATE_DISABLE;
lf_sense_disable();
@@ -372,14 +372,14 @@ void lf_tag_125khz_sense_switch(bool enable) {
}
}
/** @brief em410x加载数据
* @param type
* @param buffer
/** @brief EM410X load data
* @param type Refined label type
* @param buffer Data buffer
*/
int lf_tag_em410x_data_loadcb(tag_specific_type_t type, tag_data_buffer_t *buffer) {
// 确保外部容量足够转换为信息结构体
//Make sure that external capacity is enough to convert to an information structure
if (buffer->length >= LF_EM410X_TAG_ID_SIZE) {
// 此处直接转换ID卡号为对应的bit数据流
// The ID card number is directly converted here as the corresponding BIT data stream
m_tag_type = type;
m_id_bit_data = em410x_id_to_memory64(buffer->buffer);
NRF_LOG_INFO("LF Em410x data load finish.");
@@ -389,34 +389,34 @@ int lf_tag_em410x_data_loadcb(tag_specific_type_t type, tag_data_buffer_t *buffe
return LF_EM410X_TAG_ID_SIZE;
}
/** @brief ID卡保存卡号之前的回调
* @param type
* @param buffer
* @return 0
/** @brief Id card deposit card number before callback
* @param type Refined label type
* @param buffer Data buffer
* @return The length of the data that needs to be saved is that it does not save when 0
*/
int lf_tag_em410x_data_savecb(tag_specific_type_t type, tag_data_buffer_t *buffer) {
// 确保加载了此标签才允许保存
// Make sure to load this label before allowing saving
if (m_tag_type != TAG_TYPE_UNKNOWN) {
// 直接保存原本的卡包即可
// Just save the original card package directly
return LF_EM410X_TAG_ID_SIZE;
} else {
return 0;
}
}
/** @brief ID卡保存卡号之前的回调
* @param slot
* @param tag_type
* @return truefalse
/** @brief Id card deposit card number before callback
* @param slot Card slot number
* @param tag_type Refined label type
* @return Whether the format is successful, if the formatting is successful, it will return to True, otherwise False will be returned
*/
bool lf_tag_em410x_data_factory(uint8_t slot, tag_specific_type_t tag_type) {
// default id, must to align(4), more word...
uint8_t tag_id[8] = { 0xDE, 0xAD, 0xBE, 0xEF, 0x88 };
// 将数据写进去flash
// Write the data in Flash
tag_sense_type_t sense_type = get_sense_type_from_tag_type(tag_type);
fds_slot_record_map_t map_info; // 获取专用卡槽FDS记录信息
fds_slot_record_map_t map_info; // Get the special card slot FDS record information
get_fds_map_by_slot_sense_type_for_dump(slot, sense_type, &map_info);
// 调用堵塞式的fds写入函数,将卡槽指定场类型的数据写入到flash
//Call the blocked FDS to write the function, and write the data of the specified field type of the card slot into the Flash
bool ret = fds_write_sync(map_info.id, map_info.key, sizeof(tag_id) / 4, (uint8_t *)tag_id);
if (ret) {
NRF_LOG_INFO("Factory slot data success.");
@@ -7,11 +7,11 @@
/**
*
* 01
* Low -frequency analog card adjustment Manchester signal
* The definition of the packaging tool macro only needs to be modulated 0 and 1
*/
#define LF_125KHZ_EM410X_BIT_SIZE 64
#define LF_125KHZ_BORADCAST_MAX 3 // 32.768ms一次,一秒大概能广播31次
#define LF_125KHZ_BORADCAST_MAX 3 // 32.768ms once, about 31 times in one second
#define LF_125KHZ_EM410X_BIT_CLOCK 256
#define LF_EM410X_TAG_ID_SIZE 5
@@ -2,33 +2,33 @@
#define TAG_BASE_TYPE_H
// 场的感应类型
// Field sensor type
typedef enum {
// 无场感应
//No sense of induction
TAG_SENSE_NO,
// 低频125khz场感应
// Low -frequency 125kHz field induction
TAG_SENSE_LF,
// 高频13.56mhz场感应
// High -frequency 13.56MHz field induction
TAG_SENSE_HF,
} tag_sense_type_t;
/**
*
*
*
*
*The definition of all types of labels that support analog
* Note that all the defined label type below is the specific type statistics of the application layer refine
* No longer distinguish between high and low frequencies
*/
typedef enum {
// 特定的且必须存在的标志不存在的类型
//Specific and necessary signs do not exist
TAG_TYPE_UNKNOWN,
// 125khzID卡)系列
//125kHz (ID card) series
TAG_TYPE_EM410X,
// Mifare系列
// MiFare series
TAG_TYPE_MIFARE_Mini,
TAG_TYPE_MIFARE_1024,
TAG_TYPE_MIFARE_2048,
TAG_TYPE_MIFARE_4096,
// NTAG系列
// NTAG series
TAG_TYPE_NTAG_213,
TAG_TYPE_NTAG_215,
TAG_TYPE_NTAG_216,
File diff suppressed because it is too large Load Diff
@@ -8,28 +8,28 @@
#include "utils.h"
#include "tag_base_type.h"
// 最多八张卡槽
//Up to eight card slots
#define TAG_MAX_SLOT_NUM 8
extern bool g_is_tag_emulating;
// 标签的数据缓冲区
// Label data buffer
typedef struct {
uint16_t length;
uint8_t *buffer;
uint16_t *crc;
} tag_data_buffer_t;
// 场感应使能与闭能切换函数
//Farming impact enable and closed energy switching function
typedef void (*tag_sense_switch_t)(bool enable);
// flash数据加载到RAM后通知给注册者
// Flash data is notified to the registrar after loading to RAM
typedef int (*tag_datas_loadcb_t)(tag_specific_type_t type, tag_data_buffer_t *buffer);
// 数据要保存到flash之前通知给注册者
// The data should be saved to the registered person before Flash
typedef int (*tag_datas_savecb_t)(tag_specific_type_t type, tag_data_buffer_t *buffer);
// 数据的工厂初始化函数
// Data factory initialization function
typedef bool (*tag_datas_factory_t)(uint8_t slot, tag_specific_type_t type);
// 标签的数据加载与保存事件的回调函数映射表
// The data of the label data loading and the recovery function of the preservation event mapping table
typedef struct {
tag_sense_type_t sense_type;
tag_specific_type_t tag_type;
@@ -40,70 +40,70 @@ typedef struct {
} tag_base_handler_map_t;
/**
*
* Flash
* 4Word
* The storage configuration of parameters such as the type of card simulated in the card slot
* This configuration can be preserved by persistently to Flash
* 4 bytes a word, keep in mind the entire word alignment
*/
typedef struct ALIGN_U32 {
// 基础配置
//Basic configuration
struct {
uint8_t activated; // 当前激活了哪个卡槽(哪个卡槽被使用了)
uint8_t reserved1; // 保留
uint8_t reserved2; // 保留
uint8_t reserved3; // 保留
uint8_t activated; //Which card slot is currently activated (which card slot is used)
uint8_t reserved1; // reserve
uint8_t reserved2; //reserve
uint8_t reserved3; // reserve
} config;
// 每个卡槽自身的配置
// The configuration of each card slot itself
struct {
// 基础配置,占用两个字节
uint8_t enable: 1; // 是否使能该卡槽
uint8_t reserved1: 7; // 保留
uint8_t reserved2; // 保留
// 具体的正在模拟卡的类型
//Basic configuration, occupying two bytes
uint8_t enable: 1; // Whether to enable the card
uint8_t reserved1: 7; // reserve
uint8_t reserved2; //reserve
// Specific type of simulation card
tag_specific_type_t tag_hf;
tag_specific_type_t tag_lf;
} group[TAG_MAX_SLOT_NUM];
} tag_slot_config_t;
// 最基本的模拟卡初始化程序
// The most basic simulation card initialization program
void tag_emulation_init(void);
// 标签的一些存放在RAM中的数据可以通过此接口持久化保存到flash
//Some of the data stored in RAM can be saved to Flash through this interface
void tag_emulation_save(void);
// 模拟卡的启动与结束
// Starting and ending of the simulation card
void tag_emulation_sense_run(void);
void tag_emulation_sense_end(void);
// 场感应使能状态切换封装函数
// Farming response enable state switching package function
void tag_emulation_sense_switch(tag_sense_type_t type, bool enable);
// 删除卡槽中指定的场类型的卡片
// Delete the type of card specified in the card slot
void tag_emulation_delete_data(uint8_t slot, tag_sense_type_t sense_type);
// 将指定卡槽初始化为指定类型的卡片的出厂数据
// Initial data of the factory data of the specified card slot into the factory of the specified type of card
bool tag_emulation_factory_data(uint8_t slot, tag_specific_type_t tag_type);
// 更改正在模拟的卡片的类型
// Change the type of the card that is being simulated
void tag_emulation_change_type(uint8_t slot, tag_specific_type_t tag_type);
// 从内存中加载数据到模拟卡缓冲区
//Load the data from the memory to the simulation card buffer
bool tag_emulation_load_by_buffer(tag_specific_type_t tag_type, bool update_crc);
tag_sense_type_t get_sense_type_from_tag_type(tag_specific_type_t type);
tag_data_buffer_t *get_buffer_by_tag_type(tag_specific_type_t type);
// 设置当前使用的卡槽
// Set the card slot currently used
void tag_emulation_set_slot(uint8_t index);
// 获取当前使用的卡槽
// Get the card slot currently used
uint8_t tag_emulation_get_slot(void);
// 切换卡槽,根据传入参数控制是否在切换期间关闭场监听
// Switch the card slot to control whether the passing parameter control is closed during the switching period to listen to
void tag_emulation_change_slot(uint8_t index, bool sense_disable);
// 获取卡槽使能状态
// Get the card slot to enable the state
bool tag_emulation_slot_is_enable(uint8_t slot);
// 设置卡槽使能
// Set the card slot to enable
void tag_emulation_slot_set_enable(uint8_t slot, bool enable);
// 获取对应卡槽的模拟卡类型
// Get the simulation card type of the corresponding card slot
void tag_emulation_get_specific_type_by_slot(uint8_t slot, tag_specific_type_t tag_type[2]);
// 初始化某些出厂数据
// Initialize some factory data
void tag_emulation_factory_init(void);
// 在某个方向上查询任何一个使能的卡槽
//In the direction, query any card slot that enable
uint8_t tag_emulation_slot_find_next(uint8_t slot_now);
uint8_t tag_emulation_slot_find_prev(uint8_t slot_now);

Some files were not shown because too many files have changed in this diff Show More