📄 m500auc.c
字号:
unsigned char cmdASEL;
*uid_len = 0;
if ((status=M500PiccCommonRequest(PICC_REQSTD,atq))==MI_OK)
{
if((atq[0] & 0x1F) == 0x00) // check lower 5 bits, for tag-type
// all tags within this 5 bits have to
// provide a bitwise anticollision
{
status = MI_NOBITWISEANTICOLL;
}
}
if (status == MI_OK)
{
//Get UID in 1 - 3 levels (standard, [double], [triple] )
//-------
switch(br)
{
case 0: cmdASEL = PICC_ANTICOLL1; break;
default:
status = MI_BAUDRATE_NOT_SUPPORTED; break;
}
}
if (status == MI_OK)
{
cascade_level = 0;
uid_index = 0;
do
{
//Select code depends on cascade level
sel_code = cmdASEL + (2 * cascade_level);
cmdASEL = PICC_ANTICOLL1; // reset anticollistion level for calculation
//ANTICOLLISION
status = M500PiccCascAnticoll(sel_code, 0, &uid[uid_index]);
//SELECT
if (status == MI_OK)
{
status = M500PiccCascSelect(sel_code, &uid[uid_index], sak);
if (status == MI_OK)
{
cascade_level++;
//we differ cascaded and uncascaded UIDs
if (*sak & 0x04) // if cascaded, bit 2 is set in answer to select
{
//this UID is cascaded, remove the cascaded tag that is
//0x88 as first of the 4 byte received
memmove(&uid[uid_index], &uid[uid_index + 1], 3);
uid_index += 3;
*uid_len += 3;
}
else
{
//this UID is not cascaded -> the length is 4 bytes
uid_index += 4;
*uid_len += 4;
}
}
}
}
while((status == MI_OK) // error status
&& (*sak & 0x04) // no further cascade level
&& (cascade_level < 3)); // highest cascade level is reached
}
if (status == MI_OK)
{
//Exit function, if cascade level is triple and sak indicates another
//cascase level.
if ((cascade_level == 3) && (*sak & 0x04))
{
*uid_len = 0;
status = MI_SERNRERR;
}
}
return (status);
}
char M500PiccActivateAll(unsigned char br,
unsigned char *atq,
unsigned char *sak,
unsigned char *uid,
unsigned char *uid_len)
{
unsigned char cascade_level;
unsigned char sel_code;
unsigned char uid_index;
signed char status;
unsigned char cmdASEL;
*uid_len = 0;
if ((status=M500PiccCommonRequest(PICC_REQALL,atq))==MI_OK)
{
if((atq[0] & 0x1F) == 0x00) // check lower 5 bits, for tag-type
// all tags within this 5 bits have to
// provide a bitwise anticollision
{
status = MI_NOBITWISEANTICOLL;
}
}
if (status == MI_OK)
{
//Get UID in 1 - 3 levels (standard, [double], [triple] )
//-------
switch(br)
{
case 0: cmdASEL = PICC_ANTICOLL1; break;
default:
status = MI_BAUDRATE_NOT_SUPPORTED; break;
}
}
if (status == MI_OK)
{
cascade_level = 0;
uid_index = 0;
do
{
//Select code depends on cascade level
sel_code = cmdASEL + (2 * cascade_level);
cmdASEL = PICC_ANTICOLL1; // reset anticollistion level for calculation
//ANTICOLLISION
status = M500PiccCascAnticoll(sel_code, 0, &uid[uid_index]);
//SELECT
if (status == MI_OK)
{
status = M500PiccCascSelect(sel_code, &uid[uid_index], sak);
if (status == MI_OK)
{
cascade_level++;
//we differ cascaded and uncascaded UIDs
if (*sak & 0x04) // if cascaded, bit 2 is set in answer to select
{
//this UID is cascaded, remove the cascaded tag that is
//0x88 as first of the 4 byte received
memmove(&uid[uid_index], &uid[uid_index + 1], 3);
uid_index += 3;
*uid_len += 3;
}
else
{
//this UID is not cascaded -> the length is 4 bytes
uid_index += 4;
*uid_len += 4;
}
}
}
}
while((status == MI_OK) // error status
&& (*sak & 0x04) // no further cascade level
&& (cascade_level < 3)); // highest cascade level is reached
}
if (status == MI_OK)
{
//Exit function, if cascade level is triple and sak indicates another
//cascase level.
if ((cascade_level == 3) && (*sak & 0x04))
{
*uid_len = 0;
status = MI_SERNRERR;
}
}
return (status);
}
///////////////////////////////////////////////////////////////////////
// M I F A R E A N T I C O L L I S I O N
// for standard select
///////////////////////////////////////////////////////////////////////
char M500PiccAnticoll (unsigned char bcnt,
unsigned char *snr)
{
return M500PiccCascAnticoll(0x93,bcnt,snr); // first cascade level
}
///////////////////////////////////////////////////////////////////////
// M I F A R E A N T I C O L L I S I O N
// for extended serial numbers
///////////////////////////////////////////////////////////////////////
char M500PiccCascAnticoll (unsigned char select_code,
unsigned char bcnt,
unsigned char *snr)
{
char idata status = MI_OK;
char idata snr_in[4]; // copy of the input parameter snr
char idata nbytes = 0;
char idata nbits = 0;
char idata complete = 0;
char idata i = 0;
char idata byteOffset = 0;
unsigned char idata snr_crc;
unsigned char idata snr_check;
unsigned char dummyShift1; // dummy byte for snr shift
unsigned char dummyShift2; // dummy byte for snr shift
//************* Initialisation ******************************
M500PcdSetTmo(106);
memcpy(snr_in,snr,4);
WriteIO(RegDecoderControl,0x28); // ZeroAfterColl aktivieren
ClearBitMask(RegControl,0x08); // disable crypto 1 unit
//************** Anticollision Loop ***************************
complete = 0;
while (!complete && (status == MI_OK) )
{
ResetInfo(MInfo);
WriteIO(RegChannelRedundancy,0x03); // RxCRC and TxCRC disable, parity enable
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 inconsistancy in the anticollision sequence
// (will be solved soon), the case of 7 bits has to be treated in a
// separate way - please note the errata 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] = select_code;
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 = M500PcdCmd(PCD_TRANSCEIVE,
MSndBuffer,
MRcvBuffer,
&MInfo);
// in order to solve an inconsistancy in the anticollision sequence
// (will be solved soon), the case of 7 bits has to be treated in a
// separate way
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 ) // no error and no collision
{
// 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
memcpy(snr,snr_in,4);
}
else
{
memcpy(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
///////////////////////////////////////////////////////////////////////
char M500PiccSelect(unsigned char *snr,
unsigned char *sak)
{
return M500PiccCascSelect(0x93,snr,sak); // first cascade level
}
///////////////////////////////////////////////////////////////////////
// M I F A R E C A S C A D E D S E L E C T
// for extended serial number
///////////////////////////////////////////////////////////////////////
char M500PiccCascSelect(unsigned char select_code,
unsigned char *snr,
unsigned char *sak)
{
char idata status = MI_OK;
M500PcdSetTmo(106);
WriteIO(RegChannelRedundancy,0x0F); // RxCRC,TxCRC, Parity enable
ClearBitMask(RegControl,0x08); // disable crypto 1 unit
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -