📄 armspi.c
字号:
}
//////////////////////////////////////////////////////////////////////
// W R I T E A P C D C O M M A N D
///////////////////////////////////////////////////////////////////////
int8 FM1702PcdCmd(uint8 cmd,volatile uint8* send, volatile uint8* rcv, volatile MfCmdInfo *info)
{
int8 status = MI_OK;
int8 tmpStatus ;
uint8 lastBits;
uint8 irqEn = 0x00;
uint8 waitFor = 0x00;
WriteIO(RegInterruptEn,0x7F);
WriteIO(RegInterruptRq,0x7F);
WriteIO(RegCommand,PCD_IDLE);
FlushFIFO(); // 清空FIFO
// save info structures to module pointers
MpIsrInfo = info;
MpIsrOut = send;
MpIsrIn = rcv;
info->irqSource = 0x0; // reset interrupt flags
switch(cmd)
{
case PCD_IDLE: // 空闲命令不用打开任何中断
irqEn = 0x00;
waitFor = 0x00;
break;
case PCD_WRITEE2: // 写E2PROM命令
irqEn = 0x11;
waitFor = 0x10;
break;
case PCD_READE2: // 读E2PROM
irqEn = 0x07;
waitFor = 0x04;
break;
case PCD_LOADCONFIG: // 配置命令
case PCD_LOADKEYE2: // 装载密钥须打开
case PCD_AUTHENT1: // 验证1须打开
irqEn = 0x05;
waitFor = 0x04;
break;
case PCD_CALCCRC: // LoAlert and TxIRq
irqEn = 0x11;
waitFor = 0x10;
break;
case PCD_AUTHENT2: // IdleIRq
irqEn = 0x04;
waitFor = 0x04;
break;
case PCD_RECEIVE: // HiAlert and IdleIRq
info->nBitsReceived = -(ReadIO(RegBitFraming) >> 4);
irqEn = 0x06;
waitFor = 0x04;
break;
case PCD_LOADKEY: // IdleIRq
irqEn = 0x05;
waitFor = 0x04;
break;
case PCD_TRANSMIT: // LoAlert and IdleIRq
irqEn = 0x05;
waitFor = 0x04;
break;
case PCD_TRANSCEIVE: // TxIrq, RxIrq, IdleIRq and LoAlert
info->nBitsReceived = -(ReadIO(RegBitFraming) >> 4);
irqEn = 0x3D;
waitFor = 0x04;
break;
default:
status = MI_UNKNOWN_COMMAND;
}
if (status == MI_OK)
{
// Initialize uC Timer for global Timeout management
irqEn |= 0xA0;
waitFor |= 0x20; // always wait for timeout
start_timeout(8000); // initialise and start guard timer for reader
// 50us resolution, 200ms
VICIntEnClr=(1<<14);
WriteIO(RegInterruptEn,irqEn);
VICIntEnable=(1<<14);
WriteIO(RegCommand,cmd); //写命令,
// wait for commmand completion
// a command is completed, if the corresponding interrupt occurs
// or a timeout is signaled
while (!((MpIsrInfo->irqSource & waitFor)|| Timer1out_flag));
// wait for cmd completion or timeou
WriteIO(RegInterruptEn,0x7F);
WriteIO(RegInterruptRq,0x7F);
SetBitMask(RegControl,0x04);
stop_timeout(); // stop timeout for reader
WriteIO(RegCommand,PCD_IDLE);
if (!(MpIsrInfo->irqSource & waitFor)) // reader has not terminated
{ // timer 2 expired
status = MI_ACCESSTIMEOUT;
}
else
status = MpIsrInfo->status; // set status
if (status == MI_OK) //no timeout error occured
{ tmpStatus = (ReadIO(RegErrorFlag) & 0x17);
if (tmpStatus) // error occured
{
if (tmpStatus & 0x01) // collision detected
{
info->collPos = ReadIO(RegCollpos); // read collision position
status = MI_COLLERR;
}
else
{
info->collPos = 0;
if (tmpStatus & 0x02) // parity error
{
status = MI_PARITYERR;
}
}
if (tmpStatus & 0x04) // framing error
{
status = MI_FRAMINGERR;
}
if (tmpStatus & 0x10) // FIFO overflow
{
FlushFIFO(); //清空 FIFO缓冲区
status = MI_OVFLERR;
}
if (tmpStatus & 0x08) //CRC error
{
status = MI_CRCERR;
}
if (status == MI_OK)
status = MI_NY_IMPLEMENTED;
// key error occures always, because of
// missing crypto 1 keys loaded
}
if (cmd == PCD_TRANSCEIVE)
{
// number of bits in the last byte
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; // reset interface variables for ISR
MpIsrOut = 0;
MpIsrIn = 0;
return status;
}
//////////////////////////////////////////////////////////////////////
// S E T A B I T M A S K
///////////////////////////////////////////////////////////////////////
int8 SetBitMask(uint8 reg,uint8 mask) //
{
int8 tmp = 0x0;
tmp = ReadIO(reg);
WriteIO(reg,tmp | mask); // set bit mask
return 0x0;
}
//////////////////////////////////////////////////////////////////////
// C L E A R A B I T M A S K
///////////////////////////////////////////////////////////////////////
int8 ClearBitMask(uint8 reg,uint8 mask) //
{
int8 tmp = 0x0;
tmp = ReadIO(reg);
WriteIO(reg,tmp & ~mask); // clear bit mask
return 0x0;
}
///////////////////////////////////////////////////////////////////////
// F L U S H F I F O
///////////////////////////////////////////////////////////////////////
void FlushFIFO(void)
{
SetBitMask(RegControl,0x01);//将Control寄存器中的FIFOFlush位置1
}
/*---------------------------------------------------------------------
// M I F A R E M O D U L E R E S E T
---------------------------------------------------------------------*/
int8 FM1702PcdReset(void)
{
uint8 a;
int8 status = MI_OK;
IO0CLR=FM1702_RESET; // clear reset pin--P0.11
//delay_50us(500); // wait for 25ms
OSTimeDly(OS_TICKS_PER_SEC/40);
IO0SET = FM1702_RESET; // reset RC500
//delay_50us(50); // wait for 2.5ms
OSTimeDly(OS_TICKS_PER_SEC/400);
IO0CLR=FM1702_RESET; // clear reset pin
start_timeout(42000); // count down with a period of 50 us
// 42000 * 50 us = 2.1 s
// wait until reset command recognized
a=(ReadIO(RegCommand) & 0x3F);
while ((a != 0x3F) && !Timer1out_flag) a=(ReadIO(RegCommand) & 0x3F);//退出---Timer1out_flag=1或Cmd=3F
// while reset sequence in progress
a=(ReadIO(RegCommand) & 0x3F);
while (a && !Timer1out_flag) a=(ReadIO(RegCommand) & 0x3F);
stop_timeout(); // stop timeout counter
if (Timer1out_flag)
{
status = MI_RESETERR;
Timer1out_flag = 0;
}
else
{
WriteIO(RegPage,0x80);
if (ReadIO(RegCommand)!= 0x00)
{
status = MI_INTERFACEERR;
}
else
status=MI_OK;
WriteIO(RegPage,0x00);
}
return status;
}
///////////////////////////////////////////////////////////////////////
// M I F A R E M O D U L E C O N F I G U R A T I O N
///////////////////////////////////////////////////////////////////////
int8 FM1702PcdConfig(void)
{
int8 status;
if ((status = FM1702PcdReset()) == MI_OK)
{
// test clock Q calibration - value in the range of 0x46 expected
WriteIO(RegClockQControl,0x0);
WriteIO(RegClockQControl,0x40);
delay_50us(2); // wait approximately 100 us - calibration in progress等待约100us
//OSTimeDly(1);
ClearBitMask(RegClockQControl,0x40); // clear bit ClkQCalib for further calibration
WriteIO(RegBitPhase,0xAD);
// initialize minlevel
WriteIO(RegRxThreshold,0xFF);
// disable auto power down
WriteIO(RegRxControl2,0x01);
WriteIO(RegFIFOLevel,0x04);
//Timer configuration
WriteIO(RegTimerControl,0x02); // TStopRxEnd=0,TStopRxBeg=0,TStartTxEnd=1,TStartTxBeg=0
// timer must be stopped manually
FM1702PcdSetTmo(1); // short timeout
WriteIO(RegIRqPinConfig,0x03);
FM1702PcdRfReset(1); // Rf - reset and enable output driverRF复位50us
}
return status;
}
///////////////////////////////////////////////////////////////////////
// M I F A R E R E M O T E A N T E N N A
// Configuration of master module
///////////////////////////////////////////////////////////////////////
int8 FM1702PcdMfInOutMasterConfig(void)
{
WriteIO(RegRxControl2,0x42);
WriteIO(RegTxControl,0x10);
WriteIO(RegBitPhase,0x11);
return MI_OK;
}
///////////////////////////////////////////////////////////////////////
// M I F A R E R E Q U E S T
///////////////////////////////////////////////////////////////////////
int8 FM1702PiccRequest(uint8 req_code, uint8 *atq)
// req_code ALL = 0x52 or IDLE = 0x26;atq:answer to request
{
int8 status = MI_OK;
//************* initialize ******************************
WriteIO(RegChannelRedundancy,0x03);
ClearBitMask(RegControl,0x08);
WriteIO(RegBitFraming,0x07);
SetBitMask(RegTxControl,0x03);
ResetInfo(MInfo);
MSndBuffer[0] = req_code;
MInfo.nBytesToSend = 1;
status = FM1702PcdCmd(PCD_TRANSCEIVE,MSndBuffer,MRcvBuffer, &MInfo);
if (status) // error occured
{
*atq = 0;
}
else
{
if (MInfo.nBitsReceived != 16) // 2 bytes expected
{
*atq = 0;
status = MI_BITCOUNTERR;
}
else
{
status = MI_OK;
memcpy1(atq,(uint8*)MRcvBuffer,2);
}
}
return status;
}
///////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////
int8 FM1702PiccAnticoll (uint8 bcnt, uint8 *snr)
{
int8 status = MI_OK;
uint8 snr_in[4]; // copy of the input parameter snr
uint8 _0000[5]="0000";
int8 nbytes = 0;
int8 nbits = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -