📄 armspi.c
字号:
int8 complete= 0;
int8 i = 0;
int8 byteOffset= 0;
uint8 snr_crc;
uint8 snr_check;
uint8 dummyShift1; // dummy byte for snr shift
uint8 dummyShift2; // dummy byte for snr shift
//************* Initialisation ******************************
FM1702PcdSetTmo(106);
memcpy1(snr_in,snr,4);
WriteIO(RegDecoderControl,0x28);
ClearBitMask(RegControl,0x08);
//************** Anticollision Loop ***************************
complete = 0;
// bcnt = 0;
while (!complete && (status == MI_OK) )
{
ResetInfo(MInfo);
WriteIO(RegChannelRedundancy,0x03);
nbits = bcnt % 8; // remaining number of bits
if (nbits)
{
WriteIO(RegBitFraming,nbits << 4 | nbits); // TxLastBits/RxAlign auf nb_bi
nbytes = bcnt / 8 + 1;
// number of bytes known
// in order to solve an inconsistency(矛盾) in the anticollision sequence
// (will be solved soon), the case of 7 bits has to be treated in a
// separate way - please note the err data sheet
if (nbits == 7)
{
MInfo.cmd = PICC_ANTICOLL1; // pass command flag to ISR
WriteIO(RegBitFraming,nbits); // reset RxAlign to zero
}
}
else
{
nbytes = bcnt / 8;
}
MSndBuffer[0] = PICC_ANTICOLL1;
MSndBuffer[1] = 0x20 + ((bcnt/8) << 4) + nbits; //number of bytes send
for (i = 0; i < nbytes; i++) // Sende Buffer beschreiben
{
MSndBuffer[i + 2] = snr_in[i];
}
MInfo.nBytesToSend = 2 + nbytes;
status = FM1702PcdCmd(PCD_TRANSCEIVE,MSndBuffer, MRcvBuffer, &MInfo);
if (nbits == 7)
{
// reorder received bits
dummyShift1 = 0x00;
for (i = 0; i < MInfo.nBytesReceived; i++)
{
dummyShift2 = MRcvBuffer[i];
MRcvBuffer[i] = (dummyShift1 >> (i+1)) | (MRcvBuffer[i] << (7-i));
dummyShift1 = dummyShift2;
}
MInfo.nBitsReceived -= MInfo.nBytesReceived; // subtract received parity bits
// recalculation of collision position
if ( MInfo.collPos ) MInfo.collPos += 7 - (MInfo.collPos + 6) / 9;
}
if ( status == MI_OK || status == MI_COLLERR) // no other occured
{
// R e s p o n s e P r o c e s s i n g
if ( MInfo.nBitsReceived != (40 - bcnt) )
{ // not 5 bytes answered
status = MI_BITCOUNTERR; // Exit with error
}
else
{
byteOffset = 0;
if( nbits != 0 ) // last byte was not complete
{
snr_in[nbytes - 1] = snr_in[nbytes - 1] | MRcvBuffer[0];
byteOffset = 1;
}
for ( i =0; i < (4 - nbytes); i++)
{
snr_in[nbytes + i] = MRcvBuffer[i + byteOffset];
}
if (status != MI_COLLERR )
{
// SerCh check
snr_crc = snr_in[0] ^ snr_in[1] ^ snr_in[2] ^ snr_in[3];
snr_check = MRcvBuffer[MInfo.nBytesReceived - 1];
if (snr_crc != snr_check)
{
status = MI_SERNRERR;
}
else
{
complete = 1;
}
}
else // collision occured
{
bcnt = bcnt + MInfo.collPos - nbits;
status = MI_OK;
}
}
}
}
if (status == MI_OK)
{
// transfer snr_in to snr
memcpy1(snr,snr_in,4);
}
else
{
memcpy1(snr,_0000,4);
}
//----------------------Einstellungen aus Initialisierung ruecksetzen
ClearBitMask(RegDecoderControl,0x20); // ZeroAfterColl disable
return status;
}
///////////////////////////////////////////////////////////////////////
// M I F A R E S E L E C T
// for std. select
///////////////////////////////////////////////////////////////////////
int8 FM1702PiccSelect(uint8 *snr, uint8 *sak)
{
int8 status = MI_OK;
FM1702PcdSetTmo(106);
WriteIO(RegChannelRedundancy,0x0F);
ClearBitMask(RegControl,0x08); // disable crypto 1 unit
//************* Cmd Sequence **********************************
ResetInfo(MInfo);
MSndBuffer[0] = PICC_SELECT1;
MSndBuffer[1] = 0x70; // number of bytes send
memcpy1((uint8*)(MSndBuffer + 2),snr,4);
MSndBuffer[6] = MSndBuffer[2] ^ MSndBuffer[3]^ MSndBuffer[4]^ MSndBuffer[5];
MInfo.nBytesToSend = 7;
status = FM1702PcdCmd(PCD_TRANSCEIVE, MSndBuffer, MRcvBuffer,&MInfo);
*sak = 0;
if (status == MI_OK) // no timeout occured
{
if (MInfo.nBitsReceived != 8) // last byte is not complete
{
status = MI_BITCOUNTERR;
}
else
{
*sak = MRcvBuffer[0];
memcpy1(MLastSelectedSnr,snr,4);
}
}
return status;
}
///////////////////////////////////////////////////////////////////////
// C O D E K E Y S
///////////////////////////////////////////////////////////////////////
int8 FM1702HostCodeKey( uint8 *uncoded, uint8 *coded)
{
uint8 cnt = 0;
uint8 ln = 0; // low nibble
uint8 hn = 0; // high nibble
for (cnt = 0; cnt < 6; cnt++)
{
ln = uncoded[cnt] & 0x0F;
hn = uncoded[cnt] >> 4;
coded[cnt * 2 + 1] = (~ln << 4) | ln;
coded[cnt * 2 ] = (~hn << 4) | hn;
}
return MI_OK;
}
/*---------------------------------------------------------------------
// E E P R O M M A S T E R K E Y L O A D
---------------------------------------------------------------------*/
int8 FM1702PcdLoadKeyE2(uint8 key_type, uint8 sector,uint8 *uncoded_keys)
{
int8 status = MI_OK;
uint16 e2addr = 0x80 + sector * 0x18;
uint8 keycoded[12];
if (key_type == PICC_AUTHENT1B)
e2addr += 12;
FlushFIFO(); // empty FIFO
ResetInfo(MInfo);
FM1702HostCodeKey(uncoded_keys,keycoded);
MSndBuffer[0]=e2addr&0xff;
MSndBuffer[1]=(e2addr&0xff00)>>8;
memcpy1((uint8*)&MSndBuffer[2],keycoded,12); // write 12 bytes of coded keys
MInfo.nBytesToSend = 14;
// write load command
status = FM1702PcdCmd(PCD_WRITEE2,MSndBuffer,MRcvBuffer,&MInfo);
return status;
}
///////////////////////////////////////////////////////////////////////
// A U T H E N T I C A T I O N
// W I T H K E Y S F R O M E 2 P R O M
///////////////////////////////////////////////////////////////////////
int8 FM1702PiccAuthE2( uint8 auth_mode, uint8 *snr, uint8 key_sector, uint8 block)
{
int8 status = MI_OK;
uint16 e2addr;
uint8 *e2addrbuf = (uint8*)&e2addr;
e2addr = 0x80 + key_sector * 0x18;
if (auth_mode == PICC_AUTHENT1B)
e2addr += 12;
e2addrbuf = (uint8*)&e2addr;
FlushFIFO(); // empty FIFO
ResetInfo(MInfo);
memcpy1((uint8*)MSndBuffer,e2addrbuf,2);
MSndBuffer[2] = MSndBuffer[0];
MSndBuffer[0] = MSndBuffer[1];
MSndBuffer[1] = MSndBuffer[2];
MInfo.nBytesToSend = 2;
if ((status=FM1702PcdCmd(PCD_LOADKEYE2,MSndBuffer,MRcvBuffer,&MInfo)) == MI_OK)
{
status = FM1702PiccAuthState(auth_mode,snr,block);
}
return status;
}
///////////////////////////////////////////////////////////////////////
// M I F A R E A U T H E N T I C A T I O N
// 直接密钥验证
///////////////////////////////////////////////////////////////////////
int8 FM1702PiccAuthKey(uint8 auth_mode, uint8 *snr, uint8 *key_addr,uint8 block)
{
int8 status = MI_OK;
uint8 keycoded[12];
FM1702HostCodeKey(key_addr,keycoded);
FlushFIFO(); // empty FIFO
ResetInfo(MInfo);
memcpy1((uint8*)MSndBuffer,keycoded,12); // write 12 bytes of the key
MInfo.nBytesToSend = 12;
if ((status=FM1702PcdCmd(PCD_LOADKEY,MSndBuffer,MRcvBuffer,&MInfo)) == MI_OK)
{
status = FM1702PiccAuthState(auth_mode,snr,block);
}
return status;
}
///////////////////////////////////////////////////////////////////////
// A U T H E N T I C A T I O N S T A T E S
///////////////////////////////////////////////////////////////////////
int8 FM1702PiccAuthState( uint8 auth_mode, uint8 *snr, uint8 block)
{
int8 status = MI_OK;
status = ReadIO(RegErrorFlag);
if (status != MI_OK)
{
if (status & 0x40) // key error flag set
status = MI_KEYERR;
else
status = MI_AUTHERR;
}
else
{
MSndBuffer[0] = auth_mode;
MSndBuffer[1] = block;
memcpy1((uint8*)(MSndBuffer + 2),snr,4);
ResetInfo(MInfo);
MInfo.nBytesToSend = 6;
if ((status = FM1702PcdCmd(PCD_AUTHENT1,MSndBuffer, MRcvBuffer, &MInfo)) == MI_OK)
{
if (ReadIO(RegSecondaryStatus) & 0x07)
{
status = MI_BITCOUNTERR;
}
else
{
ResetInfo(MInfo);
MInfo.nBytesToSend = 0;
if ((status = FM1702PcdCmd(PCD_AUTHENT2,MSndBuffer,MRcvBuffer,&MInfo)) == MI_OK)
{
if ( ReadIO(RegControl) & 0x08 )
{
status = MI_OK;
}
else
{
status = MI_AUTHERR;
}
}
}
}
}
return status;
}
///////////////////////////////////////////////////////////////////////
// M I F A R E R E A D
///////////////////////////////////////////////////////////////////////
int8 FM1702PiccRead( uint8 block,
uint8 *_data)
{
int8 status = MI_OK;
uint8 _16ge0[17]="0000000000000000";
FlushFIFO(); // empty FIFO
FM1702PcdSetTmo(3); // long timeout
WriteIO(RegChannelRedundancy,0x0F);
// ************* Cmd Sequence **********************************
ResetInfo(MInfo);
MSndBuffer[0] = PICC_READ;
MSndBuffer[1] = block;
MInfo.nBytesToSend = 2;
status = FM1702PcdCmd(PCD_TRANSCEIVE,MSndBuffer, MRcvBuffer, &MInfo);
if (status != MI_OK)
{
if (status != MI_NOTAGERR ) // no timeout occured
{
if (MInfo.nBitsReceived == 4) // NACK
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -