标题:
rc522 rc523 pn512的底层代码和14443A 和14443B
[打印本页]
作者:
sukoo
时间:
2018-11-12 17:17
标题:
rc522 rc523 pn512的底层代码和14443A 和14443B
关于rc522 rc523 pn512的底层代码和14443A 和14443B 只要掌握了这些代码就可以开发对应的M1卡和CPU卡读写程序
0.png
(37.7 KB, 下载次数: 53)
下载附件
2018-11-12 21:19 上传
单片机源程序如下:
// 文 件 名: PN512.c
// 文件描述: PN512底层函数
// 版 本: V1.00
// 创 建 人: 曾本森
// 创建日期: 2010.01.26
// 说 明: 注意超时变量g_ucPCDTimeOutCnt定义和有关源代码。
//=================================================================================================
//-----------------修改记录------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
#define PN512_GLOBALS
#include <string.h>
#include "PcdInclude.h"
//============= 常量定义 ==========================================================================
#define PCD_FIFO_MAX_SIZE 64 // PCD FIFO的最大为64 - 2字节
#define PCD_FIFO_WATER_LEVEL 16 // PCD FIFO警戒线
//============= 全局变量定义 ======================================================================
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 函数原型: void ResetInfo(void)
// 函数功能: 复位命令信息
// 入口参数: -
// 出口参数: -
// 返 回 值: -
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
void ResetInfo(void)
{
INT8U i;
INT8U *BfrPtr = (INT8U *)(&MInfo);
for(i=0 ; i<sizeof(MfCmdInfo); i++)
BfrPtr[i] = 0;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 函数原型: void WriteReg(INT8U ucReg,INT8U ucValue)
// 函数功能: 写寄存器
// 入口参数: INT8U Reg // 寄存器地址
// INT8U Value // 写入的数据
// 出口参数: -
// 返 回 值: -
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
#if PCD_WRITE_REG_EN
void WriteReg(INT8U ucReg,INT8U ucValue)
{
if(ucReg == JREG_TXCONTROL)
{
g_ucTxConMask = ucValue & 0x03;
}
RcSetReg(ucReg, ucValue);
}
#endif // PCD_WRITE_REG_EN
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 函数原型: INT8U ReadReg(INT8U ucReg)
// 函数功能: 写寄存器
// 入口参数: INT8U ucReg // 寄存器地址
// 出口参数: -
// 返 回 值: 读出的数据
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
#if PCD_READ_REG_EN
INT8U ReadReg(INT8U ucReg)
{
return RcGetReg(ucReg);
}
#endif // PCD_READ_REG_EN
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 函数原型: void PcdHardRst(void)
// 函数功能: PCD硬件复位
// 入口参数: -
// 出口参数: -
// 返 回 值: -
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
void PcdHardRst(void)
{
INTU i;
PcdClrTPD();
for(i = 0; i < 75; i++); // 低电平脉冲宽度大于100ns即可
PcdSetTPD();
for(i = 0;i < 2500; i++); // 等待晶振稳定,根据晶振起振情况调整此延时时间
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 函数原型: void PcdClose(void)
// 函数功能: 关闭PCD
// 入口参数: -
// 出口参数: -
// 返 回 值: -
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
#if PCD_CLOSE_EN
void PcdClose()
{
#if HARDWARE_MODE
PcdClrTPD();
#else
RcSetReg(JREG_COMMAND, JCMD_SOFTRESET); // 软件复位
#endif // HARDWARE_MODE
}
#endif // PCD_CLOSE_EN
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 函数原型: void SetTimeOut(INT32U _302us)
// 函数功能: 设置定时器超时。
// 入口参数: INT32U _302us ; 超时时间 = (_302us) * 302 (us)
// 出口参数: -
// 返 回 值: -
// 说 明: 在PcdConfig()中已将预分频器设置为每302us输出一计数脉冲。
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
void SetTimeOut(INT32U _302us)
{
RcSetReg(JREG_TRELOADLO, ((INT8U)(_302us & 0xff)));
RcSetReg(JREG_TRELOADHI, ((INT8U)((_302us >> 8) & 0xff)));
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 函数原型: void PcdISOType(INT8U ucType)
// 函数功能: 修改PCD的模式
// 入口参数: INT8U ucType // ISO14443_TYPEA,
// // ISO14443_TYPEB
// // ISO18092_NFCIP
// 出口参数: -
// 返 回 值: -
// 说 明: 默认模式为TYPEA
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
void PcdISOType(INT8U ucType)
{
#if PCD_MODE == PN512
// 使用PN512
if(ucType == ISO18092_NFCIP)
{
RcSetReg(JREG_CONTROL, 0x10);
RcSetReg(JREG_TXMODE, 0x92);
RcSetReg(JREG_RXMODE, 0x96);
//RcSetReg(JREG_TXCONTROL, 0x80);
RcSetReg(JREG_TXASK, 0x37);
RcSetReg(JREG_RXTHRESHOLD, 0x55);
RcSetReg(JREG_DEMOD, 0x41);
// RcSetReg(JREG_MIFNFC, 0x62);
// RcSetReg(JREG_TXBITPHASE, (RcGetReg(JREG_TXASK) & 0x80) | 0x0f);
RcSetReg(JREG_RFCFG, 0x59);
RcSetReg(JREG_GSN, 0xFF);
RcSetReg(JREG_CWGSP, 0x3F);
RcSetReg(JREG_MODGSP, 0x0F);
}
else if (ucType == ISO14443_TYPEB)
{
RcSetReg(JREG_TXASK, 0x00);
RcSetReg(JREG_CONTROL, 0x10);
RcSetReg(JREG_TXMODE, 0x03);
RcSetReg(JREG_RXMODE, 0x0B);
RcSetReg(JREG_TYPEB, 0x03);
RcSetReg(JREG_DEMOD, 0x4D);
RcSetReg(JREG_GSN, 0xFF);
RcSetReg(JREG_CWGSP, 0x3F);
// RcSetReg(JREG_MODGSP, 0x1b);
RcSetReg(JREG_MODGSP, 0x18);
RcSetReg(JREG_RXTHRESHOLD, 0x55);
RcSetReg(JREG_RFCFG, 0x68);
}
else
{
RcSetReg(JREG_TXASK, 0x40);
RcSetReg(JREG_CONTROL, 0x10);
RcSetReg(JREG_TXMODE, 0x00);
RcSetReg(JREG_RXMODE, 0x08);
RcSetReg(JREG_DEMOD, 0x4D);
RcSetReg(JREG_CWGSP, 0x3F);
RcSetReg(JREG_RXTHRESHOLD, 0x84);
RcSetReg(JREG_RFCFG, 0x48);
}
#elif PCD_MODE == RC523
// 使用RC523
if(ucType == ISO14443_TYPEB)
{
RcSetReg(JREG_TXASK, 0x00);
RcSetReg(JREG_CONTROL, 0x10);
RcSetReg(JREG_TXMODE, 0x03);
RcSetReg(JREG_RXMODE, 0x0B);
RcSetReg(JREG_TYPEB, 0x03);
RcSetReg(JREG_DEMOD, 0x4d);
RcSetReg(JREG_GSN, 0xff);
RcSetReg(JREG_CWGSP, 0x3f);
// RcSetReg(JREG_MODGSP, 0x1b);
RcSetReg(JREG_MODGSP, 0x18);
RcSetReg(JREG_RXTHRESHOLD, 0x55);
RcSetReg(JREG_RFCFG, 0x68);
}
else
{
RcSetReg(JREG_TXASK, 0x40);
RcSetReg(JREG_CONTROL, 0x10);
RcSetReg(JREG_TXMODE, 0x00);
RcSetReg(JREG_RXMODE, 0x08);
RcSetReg(JREG_DEMOD, 0x4D);
RcSetReg(JREG_CWGSP, 0x3F);
RcSetReg(JREG_RXTHRESHOLD, 0x84);
RcSetReg(JREG_RFCFG, 0x48);
}
#else
// 使用RC522
ucType = ucType;
RcSetReg(JREG_TXASK, 0x40);
RcSetReg(JREG_CONTROL, 0x10);
RcSetReg(JREG_TXMODE, 0x00);
RcSetReg(JREG_RXMODE, 0x08);
RcSetReg(JREG_DEMOD, 0x4D);
RcSetReg(JREG_CWGSP, 0x3F);
RcSetReg(JREG_RXTHRESHOLD, 0x84);
RcSetReg(JREG_RFCFG, 0x48);
#endif
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 函数原型: INT8U PcdConfig(INT8U ucType)
// 函数功能: 配置芯片
// 入口参数: INT8U ucType // TYPEA -- ISO14443A,TYPEB -- ISO14443B
// 出口参数: -
// 返 回 值: STATUS_SUCCESS -- 操作成功,其他值 -- 操作失败
// 说 明: -
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
INT8U PcdConfig(INT8U ucType)
{
INT8U ucRegVal;
#if HARDWARE_MODE
PcdHardRst(); // 硬件复位
#else
RcSetReg(JREG_COMMAND, JCMD_SOFTRESET); // 复位芯片
#endif // HARDWARE_MODE
PcdISOType(ucType);
RcSetReg(JREG_GSN, 0xF0 | 0x04);
ucRegVal = RcGetReg(JREG_GSN);
if(ucRegVal != 0xF4)
return STATUS_INIT_ERROR;
RcSetReg(JREG_TPRESCALER, FREQ_SPLI_302us & 0xff);
RcSetReg(JREG_TMODE, JBIT_TAUTO | ((FREQ_SPLI_302us >> 8) & JMASK_TPRESCALER_HI));
SetTimeOut(RIC_DELAY5MS);
RcModifyReg(JREG_TXCONTROL, 1, JBIT_TX2RFEN | JBIT_TX1RFEN);
RcModifyReg(JREG_CONTROL, 1, JBIT_TSTARTNOW);
do {
ucRegVal = RcGetReg(JREG_COMMIRQ);
}while(!(ucRegVal & JBIT_TIMERI));
RcSetReg(JREG_COMMIRQ, JBIT_TIMERI);
RcSetReg(JREG_COMMAND, JCMD_IDLE);
RcSetReg(JREG_ANALOGTEST, 0xCD);
RcSetReg(JREG_TXSEL, 0x17);
#if PCD_IRQ_EN
RcSetReg(JREG_WATERLEVEL, PCD_FIFO_WATER_LEVEL);
#endif // INIT_MODE_EN
g_ucTxConMask = 0x03;
return STATUS_SUCCESS;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 函数原型: void PCDISR (void)
// 函数功能: Pcd中断服务程序
// 入口参数: -
// 出口参数: -
// 返 回 值: -
// 说 明: -
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
#if PCD_IRQ_EN
#ifdef __C51__
void PCDISR (void) interrupt 0 using 1
{
IE0 = 0;
#else
void PCDISR (void)
{
#endif // __C51__
MInfo.Irq = (INT8U)(RcGetReg(JREG_COMMIRQ) & MInfo.CommIrqEn);
// MInfo.Irq = RcGetReg(JREG_COMMIRQ);
// MInfo.Irq &= MInfo.CommIrqEn;
if (MInfo.Irq & JBIT_LOALERTI)
{// FIFO空中断
MInfo.nBytes = MInfo.nBytesToSend - MInfo.nBytesSent;
if (MInfo.nBytes < PCD_FIFO_MAX_SIZE - 2 * PCD_FIFO_WATER_LEVEL)
{
if(MInfo.nBytes)
{
WriteFIFO(MInfo.pExBuf + MInfo.nBytesSent, MInfo.nBytes);
MInfo.nBytesSent += MInfo.nBytes;
}
if (MInfo.DoRcv)
MInfo.CommIrqEn |= JBIT_RXI | JBIT_HIALERTI;
MInfo.CommIrqEn &= ~JBIT_LOALERTI;
RcSetReg(JREG_COMMIEN, (INT8U)(JBIT_IRQINV | MInfo.CommIrqEn));
RcSetReg(JREG_COMMIRQ, JBIT_LOALERTI);
}
else
{
WriteFIFO(MInfo.pExBuf + MInfo.nBytesSent, PCD_FIFO_MAX_SIZE - 2 * PCD_FIFO_WATER_LEVEL);
RcSetReg(JREG_COMMIRQ, JBIT_LOALERTI);
MInfo.nBytesSent += PCD_FIFO_MAX_SIZE - 2 * PCD_FIFO_WATER_LEVEL;
}
}
if (MInfo.Irq & JBIT_TXI)
{
MInfo.CommIrqEn &= ~(JBIT_TXI | JBIT_LOALERTI);
if (MInfo.DoRcv)
MInfo.CommIrqEn |= JBIT_RXI | JBIT_HIALERTI;
RcSetReg(JREG_COMMIEN, (INT8U)(JBIT_IRQINV | MInfo.CommIrqEn));
RcSetReg(JREG_COMMIRQ, JBIT_TXI | JBIT_LOALERTI);
}
if (MInfo.Irq & (JBIT_HIALERTI | JBIT_IDLEI |JBIT_RXI))
{
if(MInfo.DoRcv)
{
MInfo.nBitsReceived = RcGetReg(JREG_FIFOLEVEL);
ReadFIFO(MInfo.pExBuf + MInfo.nBytesReceived, MInfo.nBitsReceived);
MInfo.nBytesReceived += MInfo.nBitsReceived;
MInfo.nBitsReceived = (INT8U)(RcGetReg(JREG_CONTROL) & 0x07);
if(MInfo.nBitsReceived && MInfo.nBytesReceived)
MInfo.nBytesReceived --;
RcSetReg(JREG_COMMIRQ, JBIT_HIALERTI | JBIT_RXI | JBIT_IDLEI);
}
}
if (MInfo.Irq & JBIT_IDLEI)
{
RcModifyReg(JREG_COMMIEN, 0, JBIT_TIMERI| JBIT_IDLEI);
RcSetReg(JREG_COMMIRQ, JBIT_TIMERI | JBIT_IDLEI);
}
if (MInfo.Irq & JBIT_TIMERI)
{
RcModifyReg(JREG_COMMIEN, 0, JBIT_TIMERI);
RcSetReg(JREG_COMMIRQ, JBIT_TIMERI);
MInfo.Status = STATUS_IO_TIMEOUT;
}
if (MInfo.Irq & JBIT_ERRI)
{
MInfo.nBytes = RcGetReg(JREG_ERROR);
if(MInfo.nBytes)
{
if(MInfo.nBytes & JBIT_COLLERR)
MInfo.Status = STATUS_COLLISION_ERROR;
else if(MInfo.nBytes & JBIT_PARITYERR)
MInfo.Status = STATUS_PARITY_ERROR;
if(MInfo.nBytes & JBIT_PROTERR)
MInfo.Status = STATUS_PROTOCOL_ERROR;
else if(MInfo.nBytes & JBIT_BUFFEROVFL)
MInfo.Status = STATUS_BUFFER_OVERFLOW;
else if(MInfo.nBytes & JBIT_CRCERR)
{
if(MInfo.nBytesReceived == 0x01 &&
(MInfo.nBitsReceived == 0x04 ||
MInfo.nBitsReceived == 0x00))
{
MInfo.pExBuf[0] = RcGetReg(JREG_FIFODATA);
MInfo.nBytesReceived = 1;
MInfo.Status = STATUS_ACK_SUPPOSED;
}
else
MInfo.Status = STATUS_CRC_ERROR;
}
else if(MInfo.nBytes & JBIT_TEMPERR)
MInfo.Status = STATUS_TEMP_ERROR;
if(MInfo.nBytes & JBIT_WRERR)
MInfo.Status = STATUS_FIFO_WRITE_ERROR;
if(MInfo.Status == STATUS_SUCCESS)
MInfo.Status = STATUS_ERROR_NY_IMPLEMENTED;
}
RcSetReg(JREG_ERROR, 0);
RcSetReg(JREG_COMMIRQ, JBIT_ERRI);
}
MInfo.AllCommIrq |= MInfo.Irq;
MInfo.Irq = (INT8U)(RcGetReg(JREG_DIVIRQ) & MInfo.DivIrqEn);
if (MInfo.Irq)
{
if (MInfo.Irq & JBIT_SIGINACTI)
{
RcSetReg(JREG_DIVIRQ, JBIT_SIGINACTI);
}
if (MInfo.Irq & JBIT_MODE)
{
RcSetReg(JREG_DIVIRQ, JBIT_MODE);
}
if (MInfo.Irq & JBIT_CRCI)
{
RcSetReg(JREG_DIVIRQ, JBIT_CRCI);
}
if (MInfo.Irq & JBIT_RFON)
{
RcSetReg(JREG_DIVIRQ, JBIT_RFON);
}
if (MInfo.Irq & JBIT_RFOFF)
{
RcSetReg(JREG_DIVIRQ, JBIT_RFOFF);
}
MInfo.AllDivIrq |= MInfo.Irq;
}
}
#endif // PCD_IRQ_EN
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 函数原型: INT8U PcdCmd(INT8U ucCmd,INT16U nCmdLen,INT8U *pExchangeBuf)
// 函数功能: Pcd将数据发送到卡,然后等待接收从卡返回的数据。
// 入口参数: INT8U ucCmd // 命令
// INT16U nCmdLen // 命令长度
// INT8U *pExchangeBuf // 发送数据缓冲区首址。
// 出口参数: INT8U *pExchangeBuf // 接收数据缓冲区首址。
// 返 回 值: STATUS_SUCCESS -- 操作成功,其他值 -- 操作失败
// 说 明: -
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
#if PCD_IRQ_EN
// 使用中断模式
INT8U PcdCmd(INT8U ucCmd,INT16U nCmdLen,INT8U *pExchangeBuf)
{
INT8U ucRegVal;
MInfo.Status = STATUS_SUCCESS;
MInfo.Cmd = ucCmd;
MInfo.pExBuf = pExchangeBuf;
MInfo.nBytesToSend = nCmdLen;
// MInfo.nBytesSent = 0;
// RcSetReg(JREG_COMMIEN, 0x00);
// RcSetReg(JREG_DIVIEN, 0x00);
RcSetReg(JREG_COMMIRQ, 0x7F);
RcSetReg(JREG_DIVIRQ, 0x7F);
RcSetReg(JREG_FIFOLEVEL, JBIT_FLUSHBUFFER);
ucRegVal = RcGetReg(JREG_COMMAND);
if(MInfo.Cmd == JCMD_TRANSCEIVE)
{
RcSetReg(JREG_COMMAND, (INT8U)((ucRegVal & ~JMASK_COMMAND) | JCMD_TRANSCEIVE));
}
else
{
RcSetReg(JREG_COMMAND, (INT8U)(ucRegVal & ~JMASK_COMMAND));
}
switch(MInfo.Cmd)
{
case JCMD_IDLE:
MInfo.WaitForComm = 0;
MInfo.WaitForDiv = 0;
break;
#ifndef RC522
case JCMD_MEM:
MInfo.CommIrqEn = JBIT_IDLEI;
MInfo.WaitForComm = JBIT_IDLEI;
break;
#endif
case JCMD_CALCCRC:
MInfo.WaitForComm = 0;
MInfo.WaitForDiv = 0;
break;
case JCMD_TRANSMIT:
MInfo.CommIrqEn = JBIT_TXI | JBIT_TIMERI| JBIT_LOALERTI | JBIT_ERRI;
MInfo.WaitForComm = JBIT_TXI | JBIT_ERRI;
break;
case JCMD_RECEIVE:
MInfo.CommIrqEn = JBIT_RXI | JBIT_TIMERI | JBIT_HIALERTI |JBIT_ERRI;
MInfo.WaitForComm = JBIT_RXI | JBIT_TIMERI | JBIT_ERRI;
MInfo.DoRcv = 1;
break;
case JCMD_TRANSCEIVE:
MInfo.CommIrqEn = JBIT_RXI | JBIT_TIMERI | JBIT_LOALERTI | JBIT_ERRI;
MInfo.WaitForComm = JBIT_RXI | JBIT_TIMERI | JBIT_ERRI;
MInfo.DoRcv = 1;
break;
case JCMD_AUTHENT:
MInfo.CommIrqEn = JBIT_IDLEI | JBIT_TIMERI | JBIT_ERRI;
MInfo.WaitForComm = JBIT_IDLEI | JBIT_TIMERI | JBIT_ERRI;
break;
case JCMD_SOFTRESET:
MInfo.WaitForComm = 0;
MInfo.WaitForDiv = 0;
break;
default:
MInfo.Status = STATUS_UNSUPPORTED_COMMAND;
}
if(MInfo.Status == STATUS_SUCCESS)
{
OS_ENTER_CRITICAL();
RcSetReg(JREG_COMMIEN, JBIT_IRQINV | MInfo.CommIrqEn);
// RcSetReg(JREG_DIVIEN, MInfo.DivIrqEn);
RcSetReg(JREG_DIVIEN, JBIT_IRQPUSHPULL | MInfo.DivIrqEn);
OS_EXIT_CRITICAL();
if(MInfo.Cmd == JCMD_TRANSCEIVE)
{
RcModifyReg(JREG_BITFRAMING, 1, JBIT_STARTSEND);
}
else
RcSetReg(JREG_COMMAND, (INT8U)((RcGetReg(JREG_COMMAND) & ~JMASK_COMMAND) | MInfo.Cmd));
while(!(MInfo.WaitForComm ? (MInfo.WaitForComm & MInfo.AllCommIrq) : 1) ||
!(MInfo.WaitForDiv ? (MInfo.WaitForDiv & MInfo.AllDivIrq ) : 1))
{
OSSemPend(PcdIntSem,100,&ucRegVal);
if(ucRegVal != OS_NO_ERR)
{
MInfo.Status = STATUS_ACCESS_TIMEOUT;
break;
}
}
}
// RcModifyReg(JREG_COMMIEN, 0, MInfo.CommIrqEn);
// RcModifyReg(JREG_DIVIEN, 0, MInfo.DivIrqEn);
RcSetReg(JREG_COMMIEN, 0x80);
RcSetReg(JREG_DIVIEN, 0x00);
RcSetReg(JREG_COMMIRQ, 0x7F);
RcSetReg(JREG_DIVIRQ, 0X7F);
RcSetReg(JREG_FIFOLEVEL, JBIT_FLUSHBUFFER);
RcSetReg(JREG_BITFRAMING, 0);
return MInfo.Status;
}
#else
// 使用查询模式
INT8U PcdCmd(INT8U ucCmd,INT16U ucCmdLen,INT8U *pExchangeBuf)
{
INT8U ucStatus = STATUS_SUCCESS;
INT8U CommIrqEn = 0;
INT8U divIrqEn = 0;
INT8U WaitForComm = JBIT_ERRI | JBIT_TXI;
INT8U WaitForDiv = 0;
INT8U doReceive = 0;
INT8U getRegVal,setRegVal;
INT8U nbytes;
INT16U nbits;
MInfo.Cmd = ucCmd;
MInfo.nBytesToSend = (INT8U)(ucCmdLen & 0xFF);
RcSetReg(JREG_COMMIRQ, 0x7F);
RcSetReg(JREG_DIVIRQ, 0x7F);
RcSetReg(JREG_FIFOLEVEL, JBIT_FLUSHBUFFER);
getRegVal = RcGetReg(JREG_COMMAND);
if(MInfo.Cmd == JCMD_TRANSCEIVE)
{
setRegVal = (getRegVal & ~JMASK_COMMAND) | JCMD_TRANSCEIVE;
RcSetReg(JREG_COMMAND, setRegVal);
}
else
{
setRegVal = (getRegVal & ~JMASK_COMMAND);
RcSetReg(JREG_COMMAND, setRegVal);
}
switch(MInfo.Cmd)
{
case JCMD_IDLE:
WaitForComm = 0;
WaitForDiv = 0;
break;
#ifndef RC522
case JCMD_MEM:
CommIrqEn = JBIT_IDLEI;
WaitForComm = JBIT_IDLEI;
break;
#endif
case JCMD_CALCCRC:
WaitForComm = 0;
WaitForDiv = 0;
break;
case JCMD_TRANSMIT:
CommIrqEn = JBIT_TXI | JBIT_TIMERI;
WaitForComm = JBIT_TXI;
break;
case JCMD_RECEIVE:
CommIrqEn = JBIT_RXI | JBIT_TIMERI; //| JBIT_ERRI;
WaitForComm = JBIT_RXI | JBIT_TIMERI; //| JBIT_ERRI;
doReceive = 1;
break;
case JCMD_TRANSCEIVE:
CommIrqEn = JBIT_RXI | JBIT_TIMERI; //| JBIT_ERRI;
WaitForComm = JBIT_RXI | JBIT_TIMERI; //| JBIT_ERRI;
doReceive = 1;
break;
case JCMD_AUTHENT:
CommIrqEn = JBIT_IDLEI | JBIT_TIMERI; //| JBIT_ERRI;
WaitForComm = JBIT_IDLEI | JBIT_TIMERI; //| JBIT_ERRI;
break;
case JCMD_SOFTRESET:
WaitForComm = 0;
WaitForDiv = 0;
break;
default:
ucStatus = STATUS_UNSUPPORTED_COMMAND;
}
if(ucStatus == STATUS_SUCCESS)
{
getRegVal = RcGetReg(JREG_COMMIEN);
RcSetReg(JREG_COMMIEN, (INT8U)(getRegVal | CommIrqEn));
getRegVal = RcGetReg(JREG_DIVIEN);
RcSetReg(JREG_DIVIEN, (INT8U)(getRegVal | divIrqEn));
WriteFIFO(pExchangeBuf,MInfo.nBytesToSend);
if(MInfo.Cmd == JCMD_TRANSCEIVE)
{
RcModifyReg(JREG_BITFRAMING, 1, JBIT_STARTSEND);
}
else
{
getRegVal = RcGetReg(JREG_COMMAND);
RcSetReg(JREG_COMMAND, (INT8U)((getRegVal & ~JMASK_COMMAND) | MInfo.Cmd));
}
getRegVal = 0;
setRegVal = 0;
g_ucPCDTmOut = PCD_DELAY555MS;
while(!(WaitForComm ? (WaitForComm & setRegVal) : 1) ||
!(WaitForDiv ? (WaitForDiv & getRegVal) :1))
{
setRegVal = RcGetReg(JREG_COMMIRQ);
getRegVal = RcGetReg(JREG_DIVIRQ);
if(g_ucPCDTmOut == 0)
break;
}
if(g_ucPCDTmOut == 0)
{
ucStatus = STATUS_ACCESS_TIMEOUT;
}
else
{
WaitForComm = (INT8U)(WaitForComm & setRegVal);
WaitForDiv = (INT8U)(WaitForDiv & getRegVal);
if (setRegVal & JBIT_TIMERI)
{
ucStatus = STATUS_IO_TIMEOUT;
}
}
}
RcModifyReg(JREG_COMMIEN, 0, CommIrqEn);
RcModifyReg(JREG_DIVIEN, 0, divIrqEn);
if(doReceive && (ucStatus == STATUS_SUCCESS))
{
MInfo.nBytesReceived = RcGetReg(JREG_FIFOLEVEL);
nbytes = MInfo.nBytesReceived;
getRegVal = RcGetReg(JREG_CONTROL);
MInfo.nBitsReceived = (INT8U)(getRegVal & 0x07);
nbits = MInfo.nBitsReceived;
getRegVal = RcGetReg(JREG_ERROR);
if(getRegVal)
{
if(getRegVal & JBIT_COLLERR)
ucStatus = STATUS_COLLISION_ERROR;
else if(getRegVal & JBIT_PARITYERR)
ucStatus = STATUS_PARITY_ERROR;
if(getRegVal & JBIT_PROTERR)
ucStatus = STATUS_PROTOCOL_ERROR;
else if(getRegVal & JBIT_BUFFEROVFL)
ucStatus = STATUS_BUFFER_OVERFLOW;
else if(getRegVal & JBIT_CRCERR)
{
if(MInfo.nBytesReceived == 0x01 &&
(MInfo.nBitsReceived == 0x04 ||
MInfo.nBitsReceived == 0x00))
{
pExchangeBuf[0] = RcGetReg(JREG_FIFODATA);
MInfo.nBytesReceived = 1;
ucStatus = STATUS_ACK_SUPPOSED;
}
else
ucStatus = STATUS_CRC_ERROR;
}
else if(getRegVal & JBIT_TEMPERR)
ucStatus = STATUS_TEMP_ERROR;
if(getRegVal & JBIT_WRERR)
ucStatus = STATUS_FIFO_WRITE_ERROR;
if(ucStatus == STATUS_SUCCESS)
ucStatus = STATUS_ERROR_NY_IMPLEMENTED;
RcSetReg(JREG_ERROR, 0);
}
if(ucStatus != STATUS_ACK_SUPPOSED)
{
ReadFIFO(pExchangeBuf,MInfo.nBytesReceived);
if(MInfo.nBitsReceived && MInfo.nBytesReceived)
MInfo.nBytesReceived --;
}
}
RcSetReg(JREG_COMMIRQ, WaitForComm);
RcSetReg(JREG_DIVIRQ, WaitForDiv);
RcSetReg(JREG_FIFOLEVEL, JBIT_FLUSHBUFFER);
RcSetReg(JREG_COMMIRQ, JBIT_TIMERI);
RcSetReg(JREG_BITFRAMING, 0);
return ucStatus;
}
#endif // PCD_IRQ_EN
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 函数原型: void CardReset(INT8U ucPause_1ms,INT8U ucWait_1ms)
// 函数功能: 使RF场产生1个暂停,让卡复位
// 入口参数: INT8U ucPause_1ms ; 暂停时间,关闭RF场该时间后重新打开,
// ; 若为0则不重新打开
// INT8U ucWait_1ms ; RF场重新打开后持续等待该时间,若为0则不等待
// 出口参数: -
// 返 回 值: -
// 说 明: 等待时间可根据卡的功耗而定,如Mifare1卡的功耗较小,等待数毫秒即可,
// 而CPU卡功耗较大,需要等待80毫秒左右。
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
#if PCD_CARD_REST_EN
void CardReset(INT8U ucPause_1ms,INT8U ucWait_1ms)
{
INT8U RegVal;
// 关闭RF场
……………………
…………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei提供下载:
Driver.zip
(33.43 KB, 下载次数: 137)
2018-11-12 17:17 上传
点击文件名下载附件
下载积分: 黑币 -5
作者:
peterhzm
时间:
2019-8-23 09:07
有使用示例吗??
作者:
fl15614
时间:
2020-6-22 13:08
谢谢分享
作者:
dotnfc
时间:
2024-12-20 10:06
整合需要,下载试试。
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1