mfrc500.c
来自「mifarea卡程序mifarea卡程序mifarea卡程序」· C语言 代码 · 共 2,163 行 · 第 1/5 页
C
2,163 行
}
/*
uchar M500GetHareVerNO(uchar* info)
{
uchar status = MI_OK;
FlushFIFO();
ResetInfo(&MInfo);
SndBuffer[0] = 0x00;
SndBuffer[1] = 0x00;
SndBuffer[2] = 16;
MInfo.nBytesToSend = 3;
status = M500PcdCmd(PCD_READE2, SndBuffer, RcvBuffer, &MInfo);
if (status == MI_OK)
{
memcpy(info,&RcvBuffer[8],4);
}
return status ;
}
*/
///////////////////////////////////////////////////////////////////////
// C O N F I G M F O U T S E L E C T
///////////////////////////////////////////////////////////////////////
void M500PcdMfOutSelect(unsigned char type)
{
WriteIO(RegMfOutSelect,type&0x7);
}
#if 0
uchar M500SendRead(char *tosend, uchar sendlen, char *read, uchar readlen)
{
uchar idata status = MI_OK;
uchar idata tmp = 0;
FlushFIFO();
M500PcdSetTmo(255);
WriteIO(RegChannelRedundancy,0x0F);
ResetInfo(&MInfo);
/*
SndBuffer[0] = PICC_READ;
SndBuffer[1] = Address;
*/
memcpy(SndBuffer, tosend, sendlen);
MInfo.nBytesToSend = sendlen;
status = M500PcdCmd(PCD_TRANSCEIVE, SndBuffer, RcvBuffer, &MInfo);
if (status != MI_OK)
{
if (status != MI_NOTAGERR )
{
if (MInfo.nBitsReceived == 4)
{
RcvBuffer[0] &= 0x0f;
if ((RcvBuffer[0] & 0x0a) == 0)
{
status = MI_NOTAUTHERR;
}
else
{
status = MI_CODEERR;
}
}
}
}
else
{
/*
if (MInfo.nBytesReceived != 16)
{
status = MI_BYTECOUNTERR;
}
else
*/
{
read[0] = MInfo.nBytesReceived;
memcpy(read+1, RcvBuffer, MInfo.nBytesReceived);
}
}
return status;
}
#endif
///////////////////////////////////////////////////////////////////////////////
// Interrupt Handler RC500
///////////////////////////////////////////////////////////////////////////////
void RC500ISR (void) interrupt 0 using 1 //Ext0 interrupt
{
#if 0
static unsigned char idata irqBits;
static unsigned char idata irqMask;
static unsigned char idata nbytes;
static unsigned char idata cnt;
IE0 = 0; // Clear interrupt request flag
if (MpIsrInfo && MpIsrOut && MpIsrIn) // transfer pointers have to be set
// correctly
{
while( ReadIO(RegPrimaryStatus) & 0x08) // loop while IRQ pending
// Attention: IRQ bit is
// inverted when used with
// low activ IRQ
{
irqMask = ReadIO(RegInterruptEn); // read enabled interrupts
// read pending interrupts
irqBits = ReadIO(RegInterruptRq) & irqMask;
MpIsrInfo->irqSource |= irqBits; // save pending interrupts
//************ LoAlertIRQ ******************
if (irqBits & 0x01) // LoAlert
{
nbytes = MFIFOLength - ReadIO(RegFIFOLength);
// less bytes to send, than space in FIFO
if ((MpIsrInfo->nBytesToSend - MpIsrInfo->nBytesSent) <= nbytes)
{
nbytes = MpIsrInfo->nBytesToSend - MpIsrInfo->nBytesSent;
WriteIO(RegInterruptEn,0x01); // disable LoAlert IRQ
}
// write remaining data to the FIFO
for ( cnt = 0;cnt < nbytes;cnt++)
{
WriteIO(RegFIFOData,MpIsrOut[MpIsrInfo->nBytesSent]);
MpIsrInfo->nBytesSent++;
}
WriteIO(RegInterruptRq,0x01); // reset IRQ bit
}
//************* TxIRQ Handling **************
if (irqBits & 0x10) // TxIRQ
{
WriteIO(RegInterruptRq,0x10); // reset IRQ bit
WriteIO(RegInterruptEn,0x82); // enable HiAlert Irq for
// response
if (MpIsrInfo->cmd == PICC_ANTICOLL1) // if cmd is anticollision
{ // switch off parity generation
WriteIO(RegChannelRedundancy,0x02); // RXCRC and TXCRC disable, parity disable
}
}
//************* HiAlertIRQ or RxIRQ Handling ******************
if (irqBits & 0x0E) // HiAlert, Idle or RxIRQ
{
// read some bytes ( length of FIFO queue)
// into the receive buffer
nbytes = ReadIO(RegFIFOLength);
// read date from the FIFO and store them in the receive buffer
for ( cnt = 0; cnt < nbytes; cnt++)
{
MpIsrIn[MpIsrInfo->nBytesReceived] = ReadIO(RegFIFOData);
MpIsrInfo->nBytesReceived++;
}
WriteIO(RegInterruptRq,0x0A & irqBits);
// reset IRQ bit - idle irq will
// be deleted in a seperate section
}
//************** IdleIRQ Handling ***********
if (irqBits & 0x04) // Idle IRQ
{
WriteIO(RegInterruptEn,0x20); // disable Timer IRQ
WriteIO(RegInterruptRq,0x20); // disable Timer IRQ request
irqBits &= ~0x20; // clear Timer IRQ in local var
MpIsrInfo->irqSource &= ~0x20; // clear Timer IRQ in info var
// when idle received, then cancel
// timeout
WriteIO(RegInterruptRq,0x04); // reset IRQ bit
// status should still be MI_OK
// no error - only used for wake up
}
//************* TimerIRQ Handling ***********
if (irqBits & 0x20) // timer IRQ
{
WriteIO(RegInterruptRq,0x20); // reset IRQ bit
MpIsrInfo->status = MI_NOTAGERR; // timeout error
// otherwise ignore the interrupt
}
}
}
#else
static unsigned char idata irqBits;
static unsigned char idata irqMask;
static unsigned char idata oldPageSelect;
static unsigned char idata nbytes;
static unsigned char idata cnt;
if (MpIsrInfo && MpIsrOut && MpIsrIn) // transfer pointers have to be set
// correctly
{
oldPageSelect = ReadRawIO(RegPage); // save old page select
// Attention: ReadIO cannnot be
// used because of the internal
// write sequence to the page
// reg
WriteRawIO(RegPage,0x80); // select page 0 for ISR
while( (ReadRawIO(RegPrimaryStatus) & 0x08)) // loop while IRQ pending
{
irqMask = ReadRawIO(RegInterruptEn); // read enabled interrupts
// read pending interrupts
irqBits = ReadRawIO(RegInterruptRq) & irqMask;
MpIsrInfo->irqSource |= irqBits; // save pending interrupts
//************ LoAlertIRQ ******************
if (irqBits & 0x01) // LoAlert
{
nbytes = MFIFOLength - ReadRawIO(RegFIFOLength);
// less bytes to send, than space in FIFO
if ((MpIsrInfo->nBytesToSend - MpIsrInfo->nBytesSent) <= nbytes)
{
nbytes = MpIsrInfo->nBytesToSend - MpIsrInfo->nBytesSent;
WriteRawIO(RegInterruptEn,0x01); // disable LoAlert IRQ
}
// write remaining data to the FIFO
for ( cnt = 0;cnt < nbytes;cnt++)
{
WriteRawIO(RegFIFOData,MpIsrOut[MpIsrInfo->nBytesSent]);
MpIsrInfo->nBytesSent++;
}
WriteRawIO(RegInterruptRq,0x01); // reset IRQ bit
}
//************* TxIRQ Handling **************
if (irqBits & 0x10) // TxIRQ
{
WriteRawIO(RegInterruptRq,0x10); // reset IRQ bit
WriteRawIO(RegInterruptEn,0x82); // enable HiAlert Irq for
// response
if (MpIsrInfo->cmd == PICC_ANTICOLL1) // if cmd is anticollision
{ // switch off parity generation
WriteIO(RegChannelRedundancy,0x02); // RxCRC and TxCRC disable, parity disable
WriteRawIO(RegPage,0x00); // reset page address
}
}
//************* HiAlertIRQ or RxIRQ Handling ******************
if (irqBits & 0x0E) // HiAlert, Idle or RxIRQ
{
// read some bytes ( length of FIFO queue)
// into the receive buffer
nbytes = ReadRawIO(RegFIFOLength);
// read date from the FIFO and store them in the receive buffer
for ( cnt = 0; cnt < nbytes; cnt++)
{
MpIsrIn[MpIsrInfo->nBytesReceived] = ReadRawIO(RegFIFOData);
MpIsrInfo->nBytesReceived++;
}
WriteRawIO(RegInterruptRq,0x0A & irqBits);
// reset IRQ bit - idle irq will
// be deleted in a seperate section
}
//************** IdleIRQ Handling ***********
if (irqBits & 0x04) // Idle IRQ
{
WriteRawIO(RegInterruptEn,0x20); // disable Timer IRQ
WriteRawIO(RegInterruptRq,0x20); // disable Timer IRQ request
irqBits &= ~0x20; // clear Timer IRQ in local var
MpIsrInfo->irqSource &= ~0x20; // clear Timer IRQ in info var
// when idle received, then cancel
// timeout
WriteRawIO(RegInterruptRq,0x04); // reset IRQ bit
// status should still be MI_OK
// no error - only used for wake up
}
//************* TimerIRQ Handling ***********
if (irqBits & 0x20) // timer IRQ the timeout !!Hack
{
WriteRawIO(RegInterruptRq,0x20); // reset IRQ bit
MpIsrInfo->status = MI_NOTAGERR; // timeout error what the timeout ,how long the time setting for IRQ?
// otherwise ignore the interrupt
}
}
WriteRawIO(RegPage,oldPageSelect | 0x80);
}
#endif
}
/***************************************************************************************
****************************************************************************************
*
代码段说明: 以下代码专用于Mifare Pro卡片的操作函数. * *
*
代码核心函数: M500PiccExchangeBlock. *
*
功能说明: 数据块交换数据. *
*
*
****************************************************************************************
****************************************************************************************/
char M500PiccCascSelect(unsigned char select_code,
unsigned char *snr,
unsigned char *sak)
{
char status = MI_OK;
char grid = 0x0D;
if ((status = M500PcdSetDefaultAttrib()) == MI_OK)
{
M500PcdSetTmo(2);
WriteIO(RegChannelRedundancy,0x0F); // RxCRC,TxCRC, Parity enable
ClearBitMask(RegControl,0x08); // disable crypto 1 unit
//************* Cmd Sequence **********************************
ResetInfo(&MInfo);
SndBuffer[0] = select_code;
SndBuffer[1] = 0x70; // number of bytes send
memcpy(SndBuffer + 2,snr,4);
SndBuffer[6] = SndBuffer[2]
^ SndBuffer[3]
^ SndBuffer[4]
^ SndBuffer[5];
MInfo.nBytesToSend = 7;
// MInfo.DisableDF = 1;
status = M500PcdCmd(PCD_TRANSCEIVE,
SndBuffer,
RcvBuffer,
&MInfo);
ComWrite(&status,1);
ComWrite(&grid,1);
*sak = 0;
if (status == MI_OK) // no timeout occured
{
if (MInfo.nBitsReceived != 8) // last byte is not complete
{
status = MI_BITCOUNTERR;
}
else
{
memcpy(MLastSelectedSnr,snr,4);
}
}
// copy received data in any case - for debugging reasons
*sak = RcvBuffer[0];
}
return status;
}
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
char grid = 0x0E;
//************* Initialisation ******************************
//M500PcdSetTmo(2);
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;
}
SndBuffer[0] = select_code;
SndBuffer[1] = 0x20 + ((bcnt/8) << 4) + nbits; //number of bytes send
for (i = 0; i < nbytes; i++) // Sende Buffer beschreiben
{
SndBuffer[i + 2] = snr_in[i];
}
MInfo.nBytesToSend = 2 + nbytes;
M500PcdSetTmo(2);
status = M500PcdCmd(PCD_TRANSCEIVE,
SndBuffer,
RcvBuffer,
&MInfo);
ComWrite(&status,1);
ComWrite(&grid,1);
// in order to solve an inconsistancy in the anticollision sequence
// (will
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?