⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 zlg500.c

📁 smart2300平台全部驱动例程 LPC2378所有中间件
💻 C
字号:
#include <string.h>
#include "Zlg500.h"
#include "zlg500Commu.h"

// 命令类型
enum CommandType
{
	CT_CTRL_DEV		= 1,	// 设备控制类
	CT_CTRL_14443A	= 2		// ISO14443A类
};

// 设备控制类命令(对读卡设备)
enum ControlDeviceCommand
{
	CDC_GET_DEV_INFO	= 'A',		// 获取设备信息
	CDC_CONFIG_CHIP		= 'B',		// 配置读卡芯片
	CDC_CLOSE_CHIP		= 'C',		// 关闭读卡芯片
	CDC_LOAD_KEY		= 'E',		// 装载密钥
	CDC_WRITE_REG		= 'F',		// 写读卡芯片寄存器
	CDC_READ_REG		= 'G'		// 读读卡芯片寄存器
};

// ISO14443A类命令(对卡)
enum ISO14443ACommand
{
	ISOAC_REQUEST			= 'A',	// 请求
	ISOAC_ANTICOLL			= 'B',	// 防碰撞
	ISOAC_SELECT			= 'C',	// 选择
	ISOAC_HALT				= 'D',	// 挂失
	ISOAC_AUTH_KEY_E2PROM	= 'E',	// 用E2PROM的密钥来验证实
	ISOAC_AUTH_KEY			= 'F',	// 直接密钥验证
	ISOAC_READ_BLOCK		= 'G',	// 读数据块
	ISOAC_WRITE_BLOCK		= 'H',	// 写数据块
	ISOAC_UL_WRITE_BLOCK	= 'I',	// 写UltraLight卡的数据块
	ISOAC_OP_VALUE			= 'J',	// 值操作
	ISOAC_CLOSE_ANT			= 'L',	// 关闭天线
	ISOAC_ACTIVE_TYPE_A		= 'M',	// 激活A型卡
	ISOAC_AUTO_DETECT		= 'N',	// 设置自动检测卡
	ISOAC_READ_DETECT_DATA	= 'O'	// 读自动检测数据
};

///////////////////////////////////////////////////////////////////////////////
// 读卡模块控制函数
//

// 初始化与读卡模块的通信
uint8 PCD_Init(void)
{
	return ZLG500_COM_Init();
}

//	获取读卡模块的描述信息
#if PCD_GET_DEV_INFO_EN
uint8 PCD_GetDevInfo(char *pDevInfo, uint8 nInfoSize)
{
	return ZLG500_COM_SendReceive(CT_CTRL_DEV, CDC_GET_DEV_INFO, NULL, 0, pDevInfo, nInfoSize);
}
#endif	// PCD_GET_DEV_INFO_EN

//	配置读卡模块,配置后默认为ISO14443A方式。
#if PCD_CONFIG_EN
uint8 PCD_Config(void)
{
	return ZLG500_COM_SendReceive(CT_CTRL_DEV, CDC_CONFIG_CHIP, NULL, 0, NULL, 0);
}
#endif	// PCD_CONFIG_EN

//	关闭读卡芯片。
#if PCD_CLOSE_EN
uint8 PCD_Close(void)
{
	return ZLG500_COM_SendReceive(CT_CTRL_DEV, CDC_CLOSE_CHIP, NULL, 0, NULL, 0);
}
#endif	// PCD_CLOSE_EN

//	装载密钥到读卡模块
#if PCD_LOAD_KEY_EN
uint8 PCD_LoadKey(uint8 nSectorNumber, uint8 nKeyType, const uint8 *pKey)
{
	uint8 buf[8];
	buf[0]	= nKeyType;
	buf[1]	= nSectorNumber;
	memcpy(&buf[2], pKey, 6);
	
	return ZLG500_COM_SendReceive(CT_CTRL_DEV, CDC_LOAD_KEY, buf, 8, NULL, 0);
}
#endif	// PCD_LOAD_KEY_EN

// 写读卡芯片的寄存器
uint8 PCD_WriteReg(uint8 nRegAddr, uint8 nRegValue)
{
	uint8 buf[2];
	buf[0]	= nRegAddr;
	buf[1]	= nRegValue;
	
	return ZLG500_COM_SendReceive(CT_CTRL_DEV, CDC_WRITE_REG, buf, 2, NULL, 0);
}

// 读读卡芯片的寄存器
#if 0	// 一般不需使用此函数
uint8 PCD_ReadReg(uint8 nRegAddr, uint8 *pRegValue)
{
	return ZLG500_COM_SendReceive(CT_CTRL_DEV, CDC_READ_REG, 
								  &nRegAddr, sizeof(nRegAddr), 
								  pRegValue, sizeof(*pRegValue));
}
#endif	// 0

//	选择天线的输出方式,可同时选择两个天线输出。
#if PCD_SEL_ANT_EN
uint8 PCD_SelectAntennaTx(uint8 bEnableTx1, uint8 bEnableTx2)
{
	// 地址为0x11的寄存器的0 bit和1 bit分别控制天线1和天线2的开关
	uint8 nValue = 0x58;
	if (bEnableTx1)
	{
		nValue |= 1 << 0;
	}
	
	if (bEnableTx2)
	{
		nValue |= 1 << 1;
	}
	
	return PCD_WriteReg(0x11, nValue);
}
#endif	// PCD_SEL_ANT_EN

//	关闭天线。
#if PCD_CLOSE_ANT_EN
uint8 PCD_CloseAntennaTx(uint8 nCloseTime)
{
	return ZLG500_COM_SendReceive(CT_CTRL_14443A, ISOAC_CLOSE_ANT, &nCloseTime, 1, NULL, 0);
}
#endif	// PCD_CLOSE_ANT_EN



///////////////////////////////////////////////////////////////////////////////
// ISO14443A命令函数
//

//	请求卡片
#if PICC_REQUEST_EN
uint8 PICC_Request(uint8 nRequestMode, uint16 *pCardType)
{
	return ZLG500_COM_SendReceive(CT_CTRL_14443A, ISOAC_REQUEST, 
								  &nRequestMode, sizeof(nRequestMode), 
								  pCardType, sizeof(*pCardType));
}
#endif	// PICC_REQUEST_EN

//	防碰撞。
#if PICC_ANTICOLL_EN
uint8 PICC_Anticoll(uint8 nSelectCode, uint32 *pCardSN)
{
	uint8 nBitCount = 0;
	
	uint8 buf[2];
	buf[0] = nSelectCode;
	buf[1] = nBitCount;
	return ZLG500_COM_SendReceive(CT_CTRL_14443A, ISOAC_ANTICOLL, 
								  buf, sizeof(buf), 
								  pCardSN, sizeof(*pCardSN));
}
#endif	// PICC_ANTICOLL_EN

//	选择卡片。
#if PICC_SELECT_EN
uint8 PICC_Select(uint8 nSelectCode, uint32 nCardSN, uint8 *pSAK)
{
	uint8 buf[5];
	buf[0] = nSelectCode;
	memcpy(&buf[1], &nCardSN, sizeof(nCardSN));
	
	return ZLG500_COM_SendReceive(CT_CTRL_14443A, ISOAC_SELECT, 
								  buf, sizeof(buf), 
								  pSAK, sizeof(*pSAK));
}
#endif	// PICC_SELECT_EN

//	激活A型卡,此操作是卡片请求、防碰撞和选择三个步骤的综合。
#if PICC_ACTIVE_TYPEA_EN
uint8 PICC_ActiveTypeA(uint8 nRequestCode, uint16 *pCardType, uint32 *pCardSN)
{
	uint8 nBaudrate = 0; 
	uint8 nStatus;
	uint8 sendBuf[2];
	uint8 receiveBuf[12];	
	
	sendBuf[0] = nBaudrate;
	sendBuf[1] = nRequestCode;
	nStatus = ZLG500_COM_SendReceive(CT_CTRL_14443A, ISOAC_ACTIVE_TYPE_A, sendBuf, 2, receiveBuf, sizeof(receiveBuf));
	if (nStatus == OK)
	{
		memcpy(pCardType, &receiveBuf[0], sizeof(*pCardType));
//		*pATS = receiveBuf[2];
//		*pCardSNLen = receiveBuf[3];
		memcpy(pCardSN, &receiveBuf[4], 4);
	}

	return nStatus;
}
#endif	// PICC_ACTIVE_TYPEA_EN

//	将之前选择的卡片挂起。
#if PICC_HALT_EN
uint8 PICC_Halt()
{
	return ZLG500_COM_SendReceive(CT_CTRL_14443A, ISOAC_HALT, NULL, 0, NULL, 0);
}
#endif	// PICC_HALT_EN

//	通过保存在读卡模块E2PEOM的密钥来验证相应的卡块。
#if PICC_AUTH_KEY_E2PROM_EN
uint8 PICC_AuthKeyE2PROM(uint8 nSectorNumber, uint8 nKeyType, uint32 nCardSN, uint8 nBlockNumber)
{
	uint8 buf[7];
	buf[0] = nKeyType;
	memcpy(&buf[1], &nCardSN, sizeof(nCardSN));
	buf[5] = nSectorNumber;
	buf[6] = nBlockNumber;
	
	return ZLG500_COM_SendReceive(CT_CTRL_14443A, ISOAC_AUTH_KEY_E2PROM, buf, 7, NULL, 0);
}
#endif	// PICC_AUTH_KEY_E2PROM_EN


//	使用直接密钥来验证相应的卡块。
#if PICC_AUTH_KEY_EN
uint8 PICC_AuthKeyDirect(const uint8 *pKey, uint8 nKeyType, uint32 nCardSN,uint8 nBlockNumber)
{
	uint8 buf[12];
	buf[0] = nKeyType;
	memcpy(&buf[1], &nCardSN, sizeof(nCardSN));
	memcpy(&buf[5], pKey, 6);
	buf[11] = nBlockNumber;
	
	return ZLG500_COM_SendReceive(CT_CTRL_14443A, ISOAC_AUTH_KEY, buf, 12, NULL, 0);
}
#endif	// PICC_AUTH_KEY_EN

//	读卡片数据块,一块数据的大小为16字节。
#if PICC_READ_BLOCK_EN
uint8 PICC_ReadBlock(uint8 nBlockNumber, uint8 *pBlockData)
{
	return ZLG500_COM_SendReceive(CT_CTRL_14443A, ISOAC_READ_BLOCK, 
								  &nBlockNumber, sizeof(nBlockNumber), 
								  pBlockData, 16);
}
#endif	// PICC_AUTH_KEY_EN

//	写数据到卡片指定的块,一块数据的大小为16字节。
#if PICC_WRITE_BLOCK_EN
uint8 PICC_WriteBlock(uint8 nBlockNumber, const uint8 *pBlockData)
{
	uint8 buf[17];
	buf[0] = nBlockNumber;
	memcpy(&buf[1], pBlockData, 16);
	
	return ZLG500_COM_SendReceive(CT_CTRL_14443A, ISOAC_WRITE_BLOCK, buf, 17, NULL, 0);
}
#endif	// PICC_WRITE_BLOCK_EN

//	读Ultralight卡片数据块,一块数据的大小为4字节。
#if PICC_UL_READ_BLOCK_EN
uint8 PICC_ULReadBlock(uint8 nBlockNumber, uint8 *pBlockData)
{
	uint8 buf[16];
	uint8 nStatus = PICC_ReadBlock(nBlockNumber, buf);
	if (nStatus == OK)
	{
		memcpy(pBlockData, buf, 4);
	}
	
	return nStatus;
}
#endif	// PICC_UL_READ_BLOCK_EN

//	写数据到Ultralight卡片指定的块,一块数据的大小为4字节。
#if PICC_UL_WRITE_BLOCK_EN
uint8 PICC_ULWriteBlock(uint8 nBlockNumber, const uint8 *pBlockData)
{
	uint8 buf[5];
	buf[0] = nBlockNumber;
	memcpy(&buf[1], pBlockData, 4);
	
	return ZLG500_COM_SendReceive(CT_CTRL_14443A, ISOAC_UL_WRITE_BLOCK, buf, 5, NULL, 0);
}
#endif	// PICC_UL_WRITE_BLOCK_EN

//	读取卡片内指定的块的数值,数值为32位有符号数,一块只能存放
//	一个数值,有固定的存放格式,具体请参考Mifare 1的数据手册。
#if PICC_READ_VALUE_EN
uint8 PICC_ReadValue(int32 *pValue, uint8 nBlockNumber)
{
	uint8 buf[16];
	int32 nValue1, nValue2, nValue3;
	
	uint8 nStatus = PICC_ReadBlock(nBlockNumber, buf);
	if (nStatus == OK)
	{
		memcpy(&nValue1, &buf[0], 4);
		memcpy(&nValue2, &buf[4], 4);
		memcpy(&nValue3, &buf[8], 4);
		
		if (nValue1 != ~nValue2 || nValue1 != nValue3)
		{
			return (uint8) -1;
		}
		*pValue = nValue1;
		
		if (buf[12] != (uint8) ~buf[13] || buf[12] != buf[14] || buf[12] != (uint8) ~buf[15])
		{
			return (uint8) -1;
		}
	}
		
	return nStatus;
}
#endif	// PICC_READ_VALUE_EN

//	写数值到卡片,一块只能存放一个数值。
#if PICC_WRITE_VALUE_EN
uint8 PICC_WriteValue(int32 nValue, uint8 nBlockNumber)
{
	uint8 buf[16];
	
	// 数值:原值--取反--原值
	int32 nInvertValue = ~nValue;
	memcpy(&buf[0], &nValue, 4);
	memcpy(&buf[4], &nInvertValue, 4);
	memcpy(&buf[8], &nValue, 4);
	
	// 地址:原值--取反--原值--取反
	buf[12] = nBlockNumber;
	buf[13] = ~nBlockNumber;
	buf[14] = nBlockNumber;
	buf[15] = ~nBlockNumber;
	
	return PICC_WriteBlock(nBlockNumber, buf);
}
#endif	// PICC_WRITE_VALUE_EN

//	操作数值。
#if PICC_OPERATE_VALUE_EN
uint8 PICC_OperateValue(uint8 nOperationMode, int32 nValue, uint8 nSourceBlockNumber, uint8 nDestBlockNumber)
{
	uint8 buf[7];
	buf[0] = nOperationMode;
	buf[1] = nSourceBlockNumber;
	memcpy(&buf[2], &nValue, 4);
	buf[6] = nDestBlockNumber;
	
	return ZLG500_COM_SendReceive(CT_CTRL_14443A, ISOAC_OP_VALUE, buf, 7, NULL, 0);
}
#endif	// PICC_OPERATE_VALUE_EN


//	设置自动检测卡片的参数。
#if PICC_AUTO_DETECT_EN
uint8 PICC_AutoDetect(uint8 nOutMode, uint8 nTxMode, uint8 nRequestMode, uint8 nAuthMode, 
					  uint8 nKeyType, const uint8 *pKey, uint8 nSectorNumber, uint8 nBlockNumber)
{
	uint8 buf[12];
	uint8 nInfoLen = 0;
	
	buf[0] = nOutMode;
	buf[1] = nTxMode;
	buf[2] = nRequestMode;
	buf[3] = nAuthMode;
	
	switch (nAuthMode)
	{
		case 0:
			nInfoLen = 4;
			break;
			
		case 'E':
			nInfoLen = 7;
			buf[4] = nKeyType;
			buf[5] = nSectorNumber;
			buf[6] = nBlockNumber;
			break;
			
		case 'F':
			nInfoLen = 12;
			buf[4] = nKeyType;
			memcpy(&buf[5], pKey, 6);
			buf[11]  = nBlockNumber;
			break;
			
		default:
			return COMM_ERR;
	}
	
	return ZLG500_COM_SendReceive(CT_CTRL_14443A, ISOAC_AUTO_DETECT, buf, nInfoLen, NULL, 0);	
}
#endif	// PICC_AUTO_DETECT_EN

//	接收模块自动检测到卡片主动发送上来的数据。
#if PICC_RECV_DETECT_DATA_EN
uint8 PICC_ReceiveDetectData(uint8 *pTxNumber, uint16 *pCardType, uint32 *pCardSN, uint8 *pBlockData)
{
	uint8 bResult;
	uint8 nCommType;
	uint8 nStatus;
	uint8 nRecvLen;
	uint8 buf[30];
	
	bResult = ZLG500_COM_Receive(&nCommType, &nStatus, buf, sizeof(buf), &nRecvLen);
	if (!bResult)
	{
		return COMM_ERR;
	}

	*pTxNumber = buf[0];
	memcpy(pCardType, &buf[1], 2);
//	*pSAK = buf[3];
	memcpy(pCardSN, &buf[5], 4);
	
	if (pBlockData != NULL)
	{
		memcpy(pBlockData, &buf[5 + buf[4]], 16);
	}
	
	return nStatus;
}
#endif	// PICC_RECV_DETECT_DATA_EN

//	读取模块自动检测到卡片的数据。
#if PICC_READ_DETECT_DATA_EN
uint8 PICC_ReadDetectData(uint8 nDetectMode, uint8 *pTxNumber, uint16 *pCardType, uint32 *pCardSN, uint8 *pBlockData)
{
	uint8 nStatus;
	uint8 buf[30];
	
	nStatus = ZLG500_COM_SendReceive(CT_CTRL_DEV, ISOAC_READ_DETECT_DATA, &nDetectMode, 1, buf, sizeof(buf));
	if (nStatus == OK)
	{
		*pTxNumber = buf[0];
		memcpy(pCardType, &buf[1], 2);
	//	*pSAK = buf[3];
		memcpy(pCardSN, &buf[5], 4);
		
		if (pBlockData != NULL)
		{
			memcpy(pBlockData, &buf[5 + buf[4]], 16);
		}
	}
	
	return nStatus;
}
#endif	// PICC_READ_DETECT_DATA_EN


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -