📄 rc500.c
字号:
/****************************************************************************
* 名 称:ClearBitMask()
* 功 能:清一个bit
* 入口参数:reg 内存
mask俺码
* 出口参数:无
****************************************************************************/
char ClearBitMask(unsigned char reg,unsigned char mask)
{
char tmp = 0x00;
tmp = ReadIO(reg);
WriteIO(reg,tmp & ~mask); // clear bit mask
return 0x00;
}
/****************************************************************************
* 名 称:FlushFIFO()
* 功 能:清除内部FIFO
* 入口参数:无
* 出口参数:无
****************************************************************************/
void FlushFIFO(void)
{
SetBitMask(RegControl,0x01);
}
/****************************************************************************
* 名 称:M500PcdCmd()
* 功 能:清一个bit
* 入口参数:unsigned char cmd,
unsigned char *rcv,
MfCmdInfo idata *info
* 出口参数:0正常,其它错误码
****************************************************************************/
char M500PcdCmd(unsigned char cmd,
unsigned char *rcv,
MfCmdInfo *info)
{
char status = MI_OK;
unsigned char irqEn = 0x00;
unsigned char waitFor = 0x00;
unsigned int timecnt = 0;
char tmpStatus ;
unsigned char lastBits;
WriteIO(RegInterruptEn,0x7F); //开中断
WriteIO(RegInterruptRq,0x7F); //清中断
WriteIO(RegCommand,PCD_IDLE); //清除指令
FlushFIFO();
MpIsrInfo = info;
MpIsrOut = rcv;
info->irqSource = 0x00;
switch(cmd)
{
case PCD_IDLE: //0x00 无指令,清指令
irqEn = 0x00;
waitFor = 0x00;
break;
case PCD_WRITEE2: //0x01 写FIFO,并定入EEPROM
irqEn = 0x11;
waitFor = 0x10;
break;
case PCD_READE2: //0x03 从EEPROM取数据并写入FIFO
irqEn = 0x07;
waitFor = 0x04;
break;
case PCD_LOADCONFIG: //0x07 从EEPROM读数据并用于初始化
case PCD_LOADKEYE2: //0x0b 将密钥从EEPROM复制到KEY缓存
case PCD_AUTHENT1: //0x0c 执行Cryptol算法的认证过程
irqEn = 0x05;
waitFor = 0x04;
break;
case PCD_CALCCRC: //0x12 激活CRC
irqEn = 0x11;
waitFor = 0x10;
break;
case PCD_AUTHENT2: //0x14 执行Cryptol算法的认证过程二
irqEn = 0x04;
waitFor = 0x04;
break;
case PCD_RECEIVE: //0x16 接收
info->nBitsReceived = -(ReadIO(RegBitFraming) >> 4);
irqEn = 0x06;
waitFor = 0x04;
break;
case PCD_LOADKEY: //0x19 将密钥从FIFO复制到KEY缓存
irqEn = 0x05;
waitFor = 0x04;
break;
case PCD_TRANSMIT: //0x1a 发送FIFO缓存数据
irqEn = 0x05;
waitFor = 0x04;
break;
case PCD_TRANSCEIVE: //1e 发送接收
info->nBitsReceived = -(ReadIO(RegBitFraming) >> 4);
irqEn = 0x3D;
waitFor = 0x04;
break;
default:
status = MI_UNKNOWN_COMMAND; //23
}
if (status == MI_OK)
{
irqEn |= 0x20; //发送中断
waitFor |= 0x20; //发送中断
timecnt=200000;
WriteIO(RegInterruptEn,irqEn | 0x80);
WriteIO(RegCommand,cmd);
while ((!(MpIsrInfo->irqSource & waitFor))&&(--timecnt));
WriteIO(RegInterruptEn,0x7F); //开中断
WriteIO(RegInterruptRq,0x7F); //清中断
SetBitMask(RegControl,0x04); //内部电流消耗模块包括晶振在内关闭
WriteIO(RegCommand,PCD_IDLE); //清指令
if (!(MpIsrInfo->irqSource & waitFor))
{
status = MI_ACCESSTIMEOUT; //
}
else
{
status = MpIsrInfo->status; // 超时
}
if (status == MI_OK)
{
//有错
tmpStatus = (ReadIO(RegErrorFlag) & 0x17);
if (tmpStatus)//Error 标志指示上一个执行命令的错误状态
{
if (tmpStatus & 0x01) //如果检测到一个位冲突该位置位
{
info->collPos = ReadIO(RegCollPos); //取位碰撞的位置
status = MI_COLLERR;
}
else
{
info->collPos = 0; //没有位冲突
if (tmpStatus & 0x02)
{
status = MI_PARITYERR; //如果奇偶校验失
}
}
if (tmpStatus & 0x04) //如果SOF 不正确该位置 起始桢头不正确
{
status = MI_FRAMINGERR;
}
if (tmpStatus & 0x10) //FIFO 缓冲区而FIFO 缓冲区已满时
{
FlushFIFO();
status = MI_OVFLERR;
}
if (tmpStatus & 0x08) //如果RxCRCEn 置位且CRC 失败
{
status = MI_CRCERR;
}
if (status == MI_OK) //
status = MI_NY_IMPLEMENTED; //100
}
if (cmd == PCD_TRANSCEIVE)
{
lastBits = ReadIO(RegSecondaryStatus) & 0x07;//显示最后接收字节的有效位个数
if (lastBits)
info->nBitsReceived += (info->nBytesReceived-1) * 8 + lastBits;
else
info->nBitsReceived += info->nBytesReceived * 8;
}
}
else
{
info->collPos = 0x00;
}
}
MpIsrInfo = 0;
MpIsrOut = 0;
return status;
}
/****************************************************************************
* 名 称:M500PcdConfig
* 功 能:复位rc500
* 入口参数:无
* 出口参数:0正常,其它错误码
****************************************************************************/
char M500PcdReset()
{
char status = MI_OK;
unsigned int timecnt=0;
RC531RST_CLR();
delay_1ms(25);
RC531RST_SET();
delay_50us(200);
RC531RST_CLR();
delay_50us(50);
timecnt = 5000;
// a = (ReadIO(RegCommand) & 0x3F);
while ( (ReadIO(RegCommand) & 0x3F) && timecnt)
{
timecnt--;
}
if(!timecnt)
{
status = MI_RESETERR;
}
else
{
if (ReadIO(RegCommand) != 0x00)
{
status = MI_INTERFACEERR;
}
}
return status;
}
/****************************************************************************
* 名 称:M500PcdRfReset
* 功 能:复位RF卡
* 入口参数:MS 时间 毫秒
* 出口参数:0正常,其它错误码
****************************************************************************/
char M500PcdRfReset(unsigned char ms)
{
char status = MI_OK;
if(ms)
{
ClearBitMask(RegTxControl,0x03); //0x11
delay_1ms(2);
SetBitMask(RegTxControl,0x03); //输出信号将传递由发送数据调制的13.56MHz 能量载波
}
else
{
ClearBitMask(RegTxControl,0x03);
}
WriteIO(RegCwConductance, 0x3f); //0x3f, 设置输出驱动的电导系数
return status;
}
/****************************************************************************
* 名 称:M500PcdConfig
* 功 能:配置RC500内部寄存器函数
* 入口参数:无
* 出口参数:0正常,其它错误码
****************************************************************************/
unsigned char M500PcdConfig(void)
{
char status;
if ((status = M500PcdReset()) == MI_OK)
{
WriteIO(RegClockQControl,0x00); //0x1f 控制时钟产生用于90o相移的Q 信道时钟
WriteIO(RegClockQControl,0x40);
delay_50us(2);
ClearBitMask(RegClockQControl,0x40); //如果该位为0 Q-时钟在复位后和从卡接收数据后自动校准
WriteIO(RegBitPhase,0xAD); //0x1b 选择发送器和接收器时钟之间的位相位
WriteIO(RegRxThreshold,0xFF); //0x1c 选择位解码器的阀值
WriteIO(RegRxControl2,0x01); //0x1e 控制解码器的状态并定义接收器的输入源
WriteIO(RegFIFOLevel,0x1A); //0x29 定义FIFO 上溢和下溢警告界限
WriteIO(RegTimerControl,0x02); //0x2b 选择定时器的起始和停止条件
WriteIO(RegIRqPinConfig,0x03); //0x2d 配置管脚IRQ 的输出状态
M500PcdRfReset(1);
}
return status;
}
/****************************************************************************
* 名 称:M500PcdMfOutSelect
* 功 能:Select Command defined in ISO14443(MIFARE)
* 入口参数:无
* 出口参数:0正常,其它错误码
****************************************************************************/
char M500PcdMfOutSelect(unsigned char type)
{
WriteIO(RegMfOutSelect,type&0x7); //0x26 选择输出到管脚MFOUT 的内部信号
//来自内部编码器的调制信号包络Miller 编码
return MI_OK;
}
/****************************************************************************
* 名 称:MfConfig
* 功 能:芯片初始化
* 入口参数:无
* 出口参数:0正常,其它错误码
****************************************************************************/
unsigned char MfConfig(void)
{
char status=MI_OK;
char bak;
bak=M500PcdConfig();
if(bak!=MI_OK)status=bak;
bak=M500PcdMfOutSelect(2);
if(bak!=MI_OK)status=bak;
return status;
}
/****************************************************************************
* 名 称:M500PcdSetTmo
* 功 能:设置定时时间
* 入口参数:tmoLength 时间
* 出口参数:无
****************************************************************************/
void M500PcdSetTmo(unsigned char tmoLength)
{
switch(tmoLength)
{
case 1:
WriteIO(RegTimerClock,0x07);
WriteIO(RegTimerReload,0x6a);
break;
case 2:
WriteIO(RegTimerClock,0x07);
WriteIO(RegTimerReload,0xa0);
break;
case 3:
WriteIO(RegTimerClock,0x09);
WriteIO(RegTimerReload,0xa0);
break;
case 4:
WriteIO(RegTimerClock,0x09);
WriteIO(RegTimerReload,0xff);
break;
case 5:
WriteIO(RegTimerClock,0x0b);
WriteIO(RegTimerReload,0xff);
break;
case 6:
WriteIO(RegTimerClock,0x0d);
WriteIO(RegTimerReload,0xff);
break;
case 7:
WriteIO(RegTimerClock,0x0f);
WriteIO(RegTimerReload,0xff);
break;
default:
WriteIO(RegTimerClock,0x15);
WriteIO(RegTimerReload,tmoLength);
break;
}
}
/****************************************************************************
* 名 称:M500PiccCommonRequest
* 功 能:寻卡,防冲突,选择卡 返回卡类型(2 bytes)+ 卡系列号(4 bytes)
* 入口参数:req_code 寻卡指令 request code ALL = 0x52 or IDLE = 0x26
agq 返回卡类型
* 出口参数:0正常,其它错误码
****************************************************************************/
char M500PiccCommonRequest(unsigned char req_code,unsigned char *atq)
{
char status = MI_OK;
M500PcdSetTmo(3);
WriteIO(RegChannelRedundancy,0x03); //奇校验
ClearBitMask(RegControl,0x08); //选择定时器的起始和停止条件-当数据接收结束时定时器自动停
WriteIO(RegBitFraming,0x07); //定义要发送的最后一个字节的位数
SetBitMask(RegTxControl,0x03); //管脚TX2 ,TX1上的输出信号将传递由发送数据调制的13.56MHz 能量载波
ResetInfo(MInfo); //清0
SerBuffer[0] = req_code;
MInfo.nBytesToSend = 1;
// 0x1e
status = M500PcdCmd((unsigned char)PCD_TRANSCEIVE,(unsigned char *)SerBuffer,(MfCmdInfo *)&MInfo);
if (status)
{
*atq = 0;
}
else
{
if (MInfo.nBitsReceived != 16)
{
*atq = 0;
status = MI_BITCOUNTERR;
}
else
{
status = MI_OK;
memcpy((void *)atq,(void *)SerBuffer,2);
}
}
return status;
}
/****************************************************************************
* 名 称:M500PiccCommonRequest
* 功 能:防冲突 读卡的系列号 MLastSelectedSnr
* 入口参数:bcnt 0
snr 卡序列号
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -