📄 m500auc.c
字号:
{
char idata status = MI_OK;
FlushFIFO(); // empty FIFO
ResetInfo(MInfo);
MSndBuffer[0] = 0x10; // addr low byte
MSndBuffer[1] = 0x00; // addr high byte
MSndBuffer[2] = 0x00; // Page
MSndBuffer[3] = 0x7B; // RegTxControl modsource 11,InvTx2,Tx2RFEn,TX1RFEn
MSndBuffer[4] = 0x3F; // RegCwConductance
MSndBuffer[5] = 0x3F; // RFU13
MSndBuffer[6] = 0x19; // RFU14
MSndBuffer[7] = 0x13; // RegModWidth
MSndBuffer[8] = 0x00; // RFU16
MSndBuffer[9] = 0x00; // RFU17
MSndBuffer[10] = 0x00; // Page
MSndBuffer[11] = 0x73; // RegRxControl1
MSndBuffer[12] = 0x08; // RegDecoderControl
MSndBuffer[13] = 0x6c; // RegBitPhase
MSndBuffer[14] = 0xFF; // RegRxThreshold
MSndBuffer[15] = 0x00; // RFU1D
MSndBuffer[16] = 0x00; // RegRxControl2
MSndBuffer[17] = 0x00; // RegClockQControl
MSndBuffer[18] = 0x00; // Page
MSndBuffer[19] = 0x06; // RegRxWait
MSndBuffer[20] = 0x03; // RegChannelRedundancy
MSndBuffer[21] = 0x63; // RegCRCPresetLSB
MSndBuffer[22] = 0x63; // RegCRCPresetMSB
MSndBuffer[23] = 0x0; // RFU25
MSndBuffer[24] = 0x04; // RegMfOutSelect enable mfout = manchester HT
MSndBuffer[25] = 0x00; // RFU27
// PAGE 5 FIFO, Timer and IRQ-Pin Configuration
MSndBuffer[26] = 0x00; // Page
MSndBuffer[27] = 0x08; // RegFIFOLevel
MSndBuffer[28] = 0x07; // RegTimerClock
MSndBuffer[29] = 0x06; // RegTimerControl
MSndBuffer[30] = 0x0A; // RegTimerReload
MSndBuffer[31] = 0x02; // RegIRqPinConfig
MSndBuffer[32] = 0x00; // RFU
MSndBuffer[33] = 0x00; // RFU
MInfo.nBytesToSend = 34;
status = M500PcdCmd(PCD_WRITEE2,
MSndBuffer,
MRcvBuffer,
&MInfo); // write e2
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
///////////////////////////////////////////////////////////////////////
char M500PcdMfInOutMasterConfig(void)
{
WriteIO(RegRxControl2,0x42);
WriteIO(RegTxControl,0x10);
WriteIO(RegBitPhase,0x11);
return MI_OK;
}
///////////////////////////////////////////////////////////////////////
// M A S T E R K E Y L O A D
///////////////////////////////////////////////////////////////////////
char M500PcdLoadMk(unsigned char auth_mode, // KEYA or KEYB
unsigned char key_addr, // 0 <= key_addr <= 15
unsigned char *mk) // 6 bytes uncoded master key
{
unsigned char idata offset = (auth_mode == PICC_AUTHENT1A) ? 0 : 6;
memcpy(MKeys[key_addr] + offset,mk,6);
return MI_OK;
}
///////////////////////////////////////////////////////////////////////
// E E P R O M M A S T E R K E Y L O A D
///////////////////////////////////////////////////////////////////////
char M500PcdLoadKeyE2(unsigned char key_type,
unsigned char sector,
unsigned char *uncoded_keys)
{
char idata status = MI_OK;
// eeprom address calculation
// 0x80 ... offset
// key_sector ... sector
// 0x18 ... 2 * 12 = 24 = 0x18
unsigned short idata e2addr = 0x80 + sector * 0x18;
unsigned char idata *e2addrbuf = (unsigned char*)&e2addr;
unsigned char idata keycoded[12];
if (key_type == PICC_AUTHENT1B)
e2addr += 12; // key B offset
FlushFIFO(); // empty FIFO
ResetInfo(MInfo);
M500HostCodeKey(uncoded_keys,keycoded);
memcpy(MSndBuffer,e2addrbuf,2); // write low and high byte of address
MSndBuffer[2] = MSndBuffer[0]; // Move the LSB of the 2-bytes
MSndBuffer[0] = MSndBuffer[1]; // address to the first byte
MSndBuffer[1] = MSndBuffer[2];
memcpy(&MSndBuffer[2],keycoded,12); // write 12 bytes of coded keys
MInfo.nBytesToSend = 14;
// write load command
status = M500PcdCmd(PCD_WRITEE2,
MSndBuffer,
MRcvBuffer,
&MInfo);
return status;
}
///////////////////////////////////////////////////////////////////////
// E E P R O M R E A D
///////////////////////////////////////////////////////////////////////
char PcdReadE2(unsigned short startaddr,
unsigned char length,
unsigned char* _data)
{
char status = MI_OK;
// ************* Cmd Sequence **********************************
ResetInfo(MInfo);
MSndBuffer[0] = startaddr & 0xFF;
MSndBuffer[1] = (startaddr >> 8) & 0xFF;
MSndBuffer[2] = length;
MInfo.nBytesToSend = 3;
status = M500PcdCmd(PCD_READE2,
MSndBuffer,
MRcvBuffer,
&MInfo);
if (status == MI_OK)
{
memcpy(_data,MRcvBuffer,length);
}
else // Response Processing
{
_data[0] = 0;
}
return status ;
}
///////////////////////////////////////////////////////////////////////
// E E P R O M W R I T E
///////////////////////////////////////////////////////////////////////
char PcdWriteE2(unsigned short startaddr,
unsigned char length,
unsigned char* _data)
{
char status = MI_OK;
// ************* Cmd Sequence **********************************
ResetInfo(MInfo);
MSndBuffer[0] = startaddr & 0xFF;
MSndBuffer[1] = (startaddr >> 8) & 0xFF;
memcpy(MSndBuffer + 2,_data,length);
MInfo.nBytesToSend = length + 2;
status = M500PcdCmd(PCD_WRITEE2,
MSndBuffer,
MRcvBuffer,
&MInfo); // write e2
return status;
}
///////////////////////////////////////////////////////////////////////
// C O N F I G M F O U T S E L E C T
///////////////////////////////////////////////////////////////////////
char M500PcdMfOutSelect(unsigned char type)
{
WriteIO(RegMfOutSelect,type&0x7);
return MI_OK;
}
///////////////////////////////////////////////////////////////////////
// W R I T E R E G I S T E R
///////////////////////////////////////////////////////////////////////
char M500PcdWriteRegister(unsigned char Reg, unsigned char value)
{
WriteIO(Reg,value);
return MI_OK;
}
///////////////////////////////////////////////////////////////////////
// R E A D R E G I S T E R
///////////////////////////////////////////////////////////////////////
char M500PcdReadRegister(unsigned char Reg)
{
char value;
value = ReadIO(Reg);
return (value);
}
///////////////////////////////////////////////////////////////////////
// M I F A R E R E Q U E S T
///////////////////////////////////////////////////////////////////////
char M500PiccRequest(unsigned char req_code, // request code ALL = 0x52
// or IDLE = 0x26
unsigned char *atq) // answer to request
{
return M500PiccCommonRequest(req_code,atq);
}
///////////////////////////////////////////////////////////////////////
// M I F A R E C O M M O N R E Q U E S T
///////////////////////////////////////////////////////////////////////
char M500PiccCommonRequest(unsigned char req_code,
unsigned char *atq)
{
char idata status = MI_OK;
//************* initialize ******************************
WriteIO(RegChannelRedundancy,0x03); // RxCRC and TxCRC disable, parity enable
ClearBitMask(RegControl,0x08); // disable crypto 1 unit
WriteIO(RegBitFraming,0x07); // set TxLastBits to 7
SetBitMask(RegTxControl,0x03); // Tx2RF-En, Tx1RF-En enable
ResetInfo(MInfo);
MSndBuffer[0] = req_code;
MInfo.nBytesToSend = 1;
status = M500PcdCmd(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;
memcpy(atq,MRcvBuffer,2);
}
}
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;
// bcnt = 0; // no part of the snr is known
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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -