Initial commit: CCU621_M firmware project with BLE debug link support.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,387 @@
|
||||
#include "card_ctrl/card_ctrl.h"
|
||||
#include "usart.h"
|
||||
#include "publicdata/publicdata.h"
|
||||
#include "app_init/app_init.h"
|
||||
#include "mylog/mylog.h"
|
||||
|
||||
#define STX 0x02 //开始符
|
||||
#define ETX 0x03 //结束符
|
||||
|
||||
#define CARD_RET_Y 0x59 //操作成功
|
||||
#define CARD_RET_N 0x4E //操作失败
|
||||
|
||||
#if SYSTEM_TYPE == SYSTEM_TYPE_CCU601E_D
|
||||
#define CARD_COM_ID E_USART_1
|
||||
#elif SYSTEM_TYPE == SYSTEM_TYPE_CCU621_M
|
||||
#define CARD_COM_ID E_USART_0
|
||||
#else
|
||||
#define CARD_COM_ID E_USART_0
|
||||
#endif
|
||||
|
||||
#define D_Print_flag (0) //测试打印
|
||||
|
||||
#define CARD_BUF_LENGTH 50
|
||||
#define CARD_RECV_WAIT_TICK 100 //每次等待5个TICK,也就是50ms
|
||||
#define CARD_RECV_TIMEOUT_CNT 5 //超时计数最大值为10,超时值为500ms
|
||||
|
||||
typedef struct
|
||||
{
|
||||
U16_T u16_len; //数据域长度
|
||||
U8_T u8_cmd; //命令字
|
||||
U8_T u8_para; //命令字参数
|
||||
U8_T u8_state; //状态字
|
||||
U8_T u8_data[32]; //数据域
|
||||
}CARD_CMD_T;
|
||||
|
||||
#if 1 //收发接口
|
||||
/**
|
||||
* ************************************************************************
|
||||
* @brief - 数据发送接口函数 发送
|
||||
*
|
||||
* @param[in] u8_sendBuf - 发送数据地址
|
||||
* @param[in] u16_len - 发送数据长度
|
||||
*
|
||||
*
|
||||
* @author jiankalka
|
||||
* @date 2025-08-07
|
||||
* ************************************************************************
|
||||
*/
|
||||
void v_card_send_data(U8_T *u8_sendBuf , U16_T u16_len)
|
||||
{
|
||||
u16_usart_send(CARD_COM_ID,u8_sendBuf, u16_len);
|
||||
|
||||
#if D_Print_flag //调试打印
|
||||
printf("card send,len is [%d]\r\n", u16_len);
|
||||
printf_hex("--",u8_sendBuf,u16_len);
|
||||
#endif
|
||||
}
|
||||
/**
|
||||
* ************************************************************************
|
||||
* @brief - 数据接收接口函数 接收
|
||||
*
|
||||
* @param[in] u8_recvBuf - 接收数据地址
|
||||
* @param[in] u16_len - 预期接收数据长度
|
||||
*
|
||||
* @return U16_T - 已接收数据长度
|
||||
*
|
||||
* @author jiankalka
|
||||
* @date 2025-08-07
|
||||
* ************************************************************************
|
||||
*/
|
||||
U16_T u16_card_recv_data(U8_T *u8_recvBuf ,U16_T u16_len)
|
||||
{
|
||||
U16_T recv_len;
|
||||
|
||||
memset(u8_recvBuf , 0 , u16_len);
|
||||
|
||||
recv_len = u16_usart_recv(CARD_COM_ID,u8_recvBuf,u16_len);
|
||||
|
||||
#if D_Print_flag //调试打印
|
||||
if(recv_len == 0) return 0;
|
||||
printf("card recv,len is [%d]\r\n", recv_len);
|
||||
printf_hex("--",u8_recvBuf,recv_len);
|
||||
#endif
|
||||
|
||||
return recv_len;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 1 //内部控制
|
||||
/**
|
||||
* ************************************************************************
|
||||
* @brief - 组发送帧函数
|
||||
*
|
||||
* @param[in] pt_cmd - 发送内容 结构体
|
||||
*
|
||||
*
|
||||
* @author jiankalka
|
||||
* @date 2025-11-28
|
||||
* ************************************************************************
|
||||
*/
|
||||
static void v_card_send_cmd(CARD_CMD_T *pt_cmd) //发送
|
||||
{
|
||||
U32_T i;
|
||||
U8_T u8_card_tx_buf[CARD_BUF_LENGTH] = {0};
|
||||
|
||||
u8_card_tx_buf[0] = STX;
|
||||
u8_card_tx_buf[1] = (U8_T)(pt_cmd->u16_len>>8);
|
||||
u8_card_tx_buf[2] = (U8_T)(pt_cmd->u16_len);
|
||||
u8_card_tx_buf[3] = pt_cmd->u8_cmd;
|
||||
u8_card_tx_buf[4] = pt_cmd->u8_para;
|
||||
|
||||
for (i=0; i<pt_cmd->u16_len-2; i++)
|
||||
u8_card_tx_buf[5+i] = pt_cmd->u8_data[i];
|
||||
|
||||
u8_card_tx_buf[pt_cmd->u16_len+3] = ETX;
|
||||
u8_card_tx_buf[pt_cmd->u16_len+4] = u8_calculate_bcc(u8_card_tx_buf, pt_cmd->u16_len+4);
|
||||
|
||||
v_card_send_data(u8_card_tx_buf , pt_cmd->u16_len+5);
|
||||
}
|
||||
/**
|
||||
* ************************************************************************
|
||||
* @brief - 接收数据解帧操作
|
||||
*
|
||||
* @param[in] u16_byte_len - 数据长度
|
||||
* @param[in] u8_card_rx_buf - 数据内容
|
||||
* @param[in] pt_rx_cmd - 解析存储位置
|
||||
*
|
||||
* @return U8_T - 0 解析失败 1解析成功
|
||||
*
|
||||
* @author jiankalka
|
||||
* @date 2025-11-28
|
||||
* ************************************************************************
|
||||
*/
|
||||
static U8_T u8_card_recv_unpack(U16_T u16_byte_len,U8_T *u8_card_rx_buf ,CARD_CMD_T *pt_rx_cmd)
|
||||
{
|
||||
U8_T j;
|
||||
pt_rx_cmd->u16_len = u16_byte_len;
|
||||
pt_rx_cmd->u8_cmd = u8_card_rx_buf[3]; //命令字
|
||||
pt_rx_cmd->u8_para = u8_card_rx_buf[4]; //命令参数
|
||||
//pt_cmd->u8_state = u8_card_rx_buf[i+5]; //状态字
|
||||
|
||||
if(pt_rx_cmd->u8_cmd == 0x34)
|
||||
{
|
||||
if(pt_rx_cmd->u8_para == 0x30) //寻卡
|
||||
{
|
||||
pt_rx_cmd->u8_state = u8_card_rx_buf[5];
|
||||
return 1;
|
||||
}
|
||||
else if(pt_rx_cmd->u8_para == 0x32) //验证密码
|
||||
{
|
||||
pt_rx_cmd->u8_state = u8_card_rx_buf[6];
|
||||
return 1;
|
||||
}
|
||||
else if(pt_rx_cmd->u8_para == 0x33) //读卡号
|
||||
{
|
||||
if(u16_byte_len == 0x15) //判长度或判返回状态字是否为0x59
|
||||
{
|
||||
pt_rx_cmd->u8_state = u8_card_rx_buf[7];
|
||||
|
||||
for(j=0; j<u16_byte_len-5; j++)
|
||||
{
|
||||
pt_rx_cmd->u8_data[j] = u8_card_rx_buf[8+j];
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
/**
|
||||
* ************************************************************************
|
||||
* @brief - 读卡器收发控制
|
||||
*
|
||||
* @param[in] pt_tx_cmd - 发送数据内容
|
||||
* @param[in] pt_rx_cmd - 对应接收数据内容
|
||||
*
|
||||
* @return U32_T -
|
||||
*
|
||||
* @author jiankalka
|
||||
* @date 2025-11-28
|
||||
* ************************************************************************
|
||||
*/
|
||||
static U32_T u32_card_unpacket(CARD_CMD_T *pt_tx_cmd, CARD_CMD_T *pt_rx_cmd) //解帧
|
||||
{
|
||||
U16_T u16_byte_len, u16_rx_len, u16_timeout = 0;
|
||||
U32_T i, j;
|
||||
U8_T u8_card_rx_buf[CARD_BUF_LENGTH];
|
||||
|
||||
while (u16_timeout++ < CARD_RECV_TIMEOUT_CNT) //是否超时 10
|
||||
{
|
||||
v_card_send_cmd(pt_tx_cmd);
|
||||
|
||||
mSleep(CARD_RECV_WAIT_TICK); //等待接收
|
||||
|
||||
u16_rx_len = u16_card_recv_data(u8_card_rx_buf, CARD_BUF_LENGTH);
|
||||
|
||||
if (u16_rx_len <= 5)
|
||||
continue;
|
||||
|
||||
for (i=0; i<u16_rx_len-5; i++)
|
||||
{
|
||||
if ((u8_card_rx_buf[i] == STX) //STX
|
||||
&& (u8_card_rx_buf[i+3] == pt_tx_cmd->u8_cmd) //命令字
|
||||
&& (u8_card_rx_buf[i+4] == pt_tx_cmd->u8_para)) //命令参数
|
||||
{
|
||||
u16_byte_len = ((u8_card_rx_buf[i+1]<<8) | u8_card_rx_buf[i+2]);
|
||||
|
||||
if ((u16_rx_len - i) < (u16_byte_len + 5))
|
||||
{
|
||||
//logMsg("接收到的为非完整报文\n");
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((u8_card_rx_buf[i+u16_byte_len+3] == ETX) &&
|
||||
(u8_card_rx_buf[i+u16_byte_len+4] == u8_calculate_bcc(&u8_card_rx_buf[i], u16_byte_len+4)))
|
||||
{
|
||||
//logMsg("card 解帧 校验成功\n");
|
||||
return u8_card_recv_unpack(u16_byte_len , &u8_card_rx_buf[i] , pt_rx_cmd);
|
||||
}
|
||||
}
|
||||
}
|
||||
//logMsg("STX校验未通过\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* ************************************************************************
|
||||
* @brief - 寻卡操作
|
||||
*
|
||||
*
|
||||
* @return U8_T - 0失败 1成功
|
||||
*
|
||||
* @author jiankalka
|
||||
* @date 2025-11-28
|
||||
* ************************************************************************
|
||||
*/
|
||||
static U8_T u8_card_seek_card() //寻卡
|
||||
{
|
||||
CARD_CMD_T t_card_tx_cmd; //命令
|
||||
CARD_CMD_T t_card_rx_cmd; //命令
|
||||
|
||||
//发送寻卡命令
|
||||
memset(&t_card_tx_cmd, 0, sizeof(t_card_tx_cmd));
|
||||
t_card_tx_cmd.u16_len = 2;
|
||||
t_card_tx_cmd.u8_cmd = 0x34;
|
||||
t_card_tx_cmd.u8_para = 0x30;
|
||||
|
||||
//解包
|
||||
memset(&t_card_rx_cmd, 0, sizeof(t_card_rx_cmd));
|
||||
if (u32_card_unpacket(&t_card_tx_cmd, &t_card_rx_cmd) == 1)
|
||||
{
|
||||
if (t_card_rx_cmd.u8_state == CARD_RET_Y)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/**
|
||||
* ************************************************************************
|
||||
* @brief - 验证密码
|
||||
*
|
||||
* @param[in] u8_sectorNo - 扇区号
|
||||
* @param[in] u8_key - 验证密码
|
||||
* @param[in] u8_keyLen - 密码长度
|
||||
*
|
||||
* @return U8_T - 0失败 1成功
|
||||
*
|
||||
* @author jiankalka
|
||||
* @date 2025-11-28
|
||||
* ************************************************************************
|
||||
*/
|
||||
static U8_T u8_check_keys(U8_T u8_sectorNo ,const U8_T *u8_key ,U8_T u8_keyLen) //验证密码
|
||||
{
|
||||
CARD_CMD_T t_card_tx_cmd; //命令
|
||||
CARD_CMD_T t_card_rx_cmd; //命令
|
||||
|
||||
if(u8_key == NULL || u8_keyLen > 30) return 0;
|
||||
|
||||
//发送验证密码命令
|
||||
memset(&t_card_tx_cmd, 0, sizeof(t_card_tx_cmd));
|
||||
t_card_tx_cmd.u16_len = 3+u8_keyLen;
|
||||
t_card_tx_cmd.u8_cmd = 0x34;
|
||||
t_card_tx_cmd.u8_para = 0x32;
|
||||
t_card_tx_cmd.u8_data[0] = u8_sectorNo; //扇区号
|
||||
memcpy(&t_card_tx_cmd.u8_data[1] ,u8_key , u8_keyLen); //扇区密码
|
||||
|
||||
//解包
|
||||
memset(&t_card_rx_cmd, 0, sizeof(t_card_rx_cmd));
|
||||
if (u32_card_unpacket(&t_card_tx_cmd, &t_card_rx_cmd) == 1)
|
||||
{
|
||||
if (t_card_rx_cmd.u8_state == CARD_RET_Y)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/**
|
||||
* ************************************************************************
|
||||
* @brief - d读取卡号
|
||||
*
|
||||
* @param[in] u8_sectorNo - 扇区号
|
||||
* @param[in] u8_blockNo -
|
||||
* @param[in] u8_cardId - 卡号缓存
|
||||
* @param[in] u8_cardLen - 卡号缓存长度
|
||||
*
|
||||
* @return U8_T -
|
||||
*
|
||||
* @author jiankalka
|
||||
* @date 2025-12-04
|
||||
* ************************************************************************
|
||||
*/
|
||||
static U8_T u8_read_card(U8_T u8_sectorNo ,U8_T u8_blockNo ,U8_T *u8_cardId , U8_T u8_cardLen) //读卡号
|
||||
{
|
||||
char i,index=0;
|
||||
unsigned char cardNo_hex[16] = {0};
|
||||
unsigned char cardNo_ascii[16] = {0};
|
||||
unsigned char cardNum[18] = {0};
|
||||
|
||||
CARD_CMD_T t_card_tx_cmd; //命令
|
||||
CARD_CMD_T t_card_rx_cmd; //命令
|
||||
|
||||
memset(&t_card_tx_cmd, 0, sizeof(t_card_tx_cmd));
|
||||
t_card_tx_cmd.u16_len = 4;
|
||||
t_card_tx_cmd.u8_cmd = 0x34;
|
||||
t_card_tx_cmd.u8_para = 0x33;
|
||||
t_card_tx_cmd.u8_data[0] = u8_sectorNo;//扇区号
|
||||
t_card_tx_cmd.u8_data[1] = u8_blockNo;//块号
|
||||
|
||||
//解包
|
||||
memset(&t_card_rx_cmd, 0, sizeof(t_card_rx_cmd));
|
||||
if(u32_card_unpacket(&t_card_tx_cmd, &t_card_rx_cmd) == 1)
|
||||
{
|
||||
if(u8_cardId == NULL) return 1;
|
||||
|
||||
memset(u8_cardId, 0, u8_cardLen);
|
||||
if(t_card_rx_cmd.u16_len-5 > u8_cardLen)
|
||||
return 0;
|
||||
memcpy(&u8_cardId[0], &t_card_rx_cmd.u8_data[0], t_card_rx_cmd.u16_len-5);
|
||||
return t_card_rx_cmd.u16_len-5;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
/**
|
||||
* ************************************************************************
|
||||
* @brief - 读卡号
|
||||
*
|
||||
* @param[in] u8_data - 卡号接收数据 不接收只读卡时填NULL
|
||||
* @param[in] u8_len - 读取缓存长度 长度要预留'/0'的位置
|
||||
*
|
||||
* @return U8_T - 0 未读取到 非0 已读取到 且为卡号长度
|
||||
*
|
||||
* @author jiankalka
|
||||
* @date 2025-11-28
|
||||
* ************************************************************************
|
||||
*/
|
||||
U8_T u8_read_card_id(U8_T *u8_data , U8_T u8_len)
|
||||
{
|
||||
U8_T u8_sectorNo = 0; //扇区
|
||||
U8_T u8_blockNo = 1; //块
|
||||
U8_T u8_recvlen;
|
||||
const U8_T u8_key[6] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}; //卡密钥
|
||||
U8_T u8_card[20];
|
||||
|
||||
if(u8_card_seek_card() &&
|
||||
u8_check_keys(u8_sectorNo,u8_key,sizeof(u8_key)))
|
||||
{
|
||||
u8_recvlen = u8_read_card(u8_sectorNo,u8_blockNo,u8_card,20);
|
||||
|
||||
//printf_hex("card",u8_card,u8_recvlen);
|
||||
bcd_to_ascii((const U8_T *)u8_card, 8, (char *)u8_data, u8_len); //模块读取卡号最大16位
|
||||
printf("读取卡号成功 %s\r\n",u8_data);
|
||||
return u8_recvlen;
|
||||
}
|
||||
//printf("读取卡号失败\r\n");
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
|
||||
#ifndef CARD_CTRL_H
|
||||
#define CARD_CTRL_H
|
||||
|
||||
#ifdef __cplusplus /*C++编译环境下兼容C语言*/
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*------ Exported includes(头文件) ----------------------*/
|
||||
#include "main.h"
|
||||
/*------ Exported macro(宏定义) -------------------------*/
|
||||
|
||||
/*------ Exported struct(结构体定义) --------------------*/
|
||||
|
||||
/*------ Exported variables(变量定义) -------------------*/
|
||||
|
||||
/*------ Exported function prototypes (函数声明) -------*/
|
||||
U8_T u8_read_card_id(U8_T *u8_data , U8_T u8_len);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* CARD_CTRL_H */
|
||||
Reference in New Issue
Block a user