📄 mifare.c
字号:
for(i=0; i<MpIsrInfo->nBytesToSend; i++)
{
RcSetReg(JREG_FIFODATA, ExchangeBuf[i]);
}
/*do seperate action if command to be executed is transceive*/
if(cmd == JCMD_TRANSCEIVE)
{
/*TRx is always an endless loop, Initiator and Target must set STARTSEND.*/
RcModifyReg(JREG_BITFRAMING, 1, JBIT_STARTSEND);
}
else
{
getRegVal = RcGetReg(JREG_COMMAND);
RcSetReg(JREG_COMMAND, (getRegVal & ~JMASK_COMMAND) | cmd);
}
/*polling mode*/
getRegVal = 0;
setRegVal = 0;
counter = 0; /*Just for debug*/
while(!(waitForComm ? (waitForComm & setRegVal) : 1) ||
!(waitForDiv ? (waitForDiv & getRegVal) :1))
{
setRegVal = RcGetReg(JREG_COMMIRQ);
getRegVal = RcGetReg(JREG_DIVIRQ);
counter ++;
if(counter > 0x0100)
break;
}
/*store IRQ bits for clearance afterwards*/
waitForComm = (unsigned char)(waitForComm & setRegVal);
waitForDiv = (unsigned char)(waitForDiv & getRegVal);
/*set status to Timer Interrupt occurence*/
if (setRegVal & JBIT_TIMERI)
{
istatus = STATUS_IO_TIMEOUT;
}
}
/*disable all interrupt sources*/
RcModifyReg(JREG_COMMIEN, 0, commIrqEn);
RcModifyReg(JREG_DIVIEN, 0, divIrqEn);
if(doReceive && (istatus == STATUS_SUCCESS))
{
/*read number of bytes received (used for error check and correct transaction*/
MpIsrInfo->nBytesReceived = RcGetReg(JREG_FIFOLEVEL);
nbytes = MpIsrInfo->nBytesReceived;
getRegVal = RcGetReg(JREG_CONTROL);
MpIsrInfo->nBitsReceived = (unsigned char)(getRegVal & 0x07);
nbits = MpIsrInfo->nBitsReceived;
getRegVal = RcGetReg(JREG_ERROR);
/*set status information if error occured*/
if(getRegVal)
{
if(getRegVal & JBIT_COLLERR)
istatus = STATUS_COLLISION_ERROR; /* Collision Error */
else if(getRegVal & JBIT_PARITYERR)
istatus = STATUS_PARITY_ERROR; /* Parity Error */
if(getRegVal & JBIT_PROTERR)
istatus = STATUS_PROTOCOL_ERROR; /* Protocoll Error */
else if(getRegVal & JBIT_BUFFEROVFL)
istatus = STATUS_BUFFER_OVERFLOW; /* BufferOverflow Error */
else if(getRegVal & JBIT_CRCERR)
{ /* CRC Error */
if(MpIsrInfo->nBytesReceived == 0x01 &&
(MpIsrInfo->nBitsReceived == 0x04 ||
MpIsrInfo->nBitsReceived == 0x00))
{ /* CRC Error and only one byte received might be a Mifare (N)ACK */
ExchangeBuf[0] = RcGetReg(JREG_FIFODATA);
MpIsrInfo->nBytesReceived = 1;
istatus = STATUS_ACK_SUPPOSED; /* (N)ACK supposed */
}
else
istatus = STATUS_CRC_ERROR; /* CRC Error */
}
else if(getRegVal & JBIT_TEMPERR)
istatus = STATUS_JOINER_TEMP_ERROR; /* Temperature Error */
if(getRegVal & JBIT_WRERR)
istatus = STATUS_FIFO_WRITE_ERROR; /* Error Writing to FIFO */
if(istatus == STATUS_SUCCESS)
istatus = STATUS_ERROR_NY_IMPLEMENTED; /* Error not yet implemented, shall never occur! */
/* if an error occured, clear error register before IRQ register */
RcSetReg(JREG_ERROR, 0);
}
/*read data from FIFO and set response parameter*/
if(istatus != STATUS_ACK_SUPPOSED)
{
for(i=0; i<MpIsrInfo->nBytesReceived; i++)
{
ExchangeBuf[i] = RcGetReg(JREG_FIFODATA);
}
/*in case of incomplete last byte reduce number of complete bytes by 1*/
if(MpIsrInfo->nBitsReceived && MpIsrInfo->nBytesReceived)
MpIsrInfo->nBytesReceived --;
}
}
RcSetReg(JREG_COMMIRQ, waitForComm);
RcSetReg(JREG_DIVIRQ, waitForDiv);
RcSetReg(JREG_FIFOLEVEL, JBIT_FLUSHBUFFER);
RcSetReg(JREG_COMMIRQ, JBIT_TIMERI);
RcSetReg(JREG_BITFRAMING, 0);
return istatus;
}
/*************************************************
Function: Request
Description:
REQA, request to see if have a ISO14443A card in the field
Parameter:
req_code command code(ISO14443_3_REQALL or ISO14443_3_REQIDL)
atq the buffer to save the answer to request from the card
Return:
short status of implement
**************************************************/
short Request(unsigned char req_code, unsigned char *atq)
{
char status = STATUS_SUCCESS;
/************* initialize *****************/
RcModifyReg(JREG_STATUS2, 0, JBIT_CRYPTO1ON); /* disable Crypto if activated before */
RcSetReg(JREG_COLL, JBIT_VALUESAFTERCOLL); //active values after coll
RcModifyReg(JREG_TXMODE, 0, JBIT_CRCEN); //disable TxCRC and RxCRC
RcModifyReg(JREG_RXMODE, 0, JBIT_CRCEN);
RcSetReg(JREG_BITFRAMING, REQUEST_BITS);
/* set necessary parameters for transmission */
ResetInfo(MInfo);
SerBuffer[0] = req_code;
MInfo.nBytesToSend = 1;
/* Set timeout for REQA, ANTICOLL, SELECT*/
SetTimeOut(300);
status = M522PcdCmd(JCMD_TRANSCEIVE,
SerBuffer,
&MInfo);
if (status) // error occured
{
*atq = 0;
}
else
{
if (MInfo.nBytesReceived != 2) // 2 bytes expected
{
*atq = 0;
status = STATUS_BITCOUNT_ERROR;
}
else
{
status = STATUS_SUCCESS;
memcpy(atq,SerBuffer,2);
}
}
return status;
}
/*************************************************
Function: CascAnticoll
Description:
Functions to split anticollission and select internally.
NOTE: this founction is used internal only, and cannot call by application program
Parameter:
sel_code command code
bitcount the bit counter of known UID
snr the UID have known
Return:
short status of implement
**************************************************/
short CascAnticoll(unsigned char sel_code,
unsigned char bitcount,
unsigned char *snr)
{
short status = STATUS_SUCCESS;
short istatus = STATUS_SUCCESS;
unsigned char idata i;
unsigned char idata complete = 0; /* signs end of anticollission loop */
unsigned char idata rbits = 0; /* number of total received bits */
unsigned char idata nbits = 0; /* */
unsigned char idata nbytes = 0; /* */
unsigned char idata byteOffset; /* stores offset for ID copy if uncomplete last byte was sent */
/* initialise relvant bytes in internal buffer */
for(i=2;i<7;i++)
SerBuffer[i] = 0x00;
/* disable TxCRC and RxCRC */
RcModifyReg(JREG_TXMODE, 0, JBIT_CRCEN);
RcModifyReg(JREG_RXMODE, 0, JBIT_CRCEN);
/* activate deletion of bits after coll */
RcSetReg(JREG_COLL, 0);
/* init parameters for anticollision */
while(!complete && (istatus == STATUS_SUCCESS))
{
/* if there is a communication problem on the RF interface, bcnt
could be larger than 32 - folowing loops will be defective. */
if(bitcount > SINGLE_UID_LENGTH)
{
istatus = STATUS_INVALID_PARAMETER;
continue;
}
/* prepare data length */
nbits = (unsigned char)(bitcount % BITS_PER_BYTE);
nbytes = (unsigned char)(bitcount / BITS_PER_BYTE);
if(nbits)
nbytes++;
/* prepare data buffer */
SerBuffer[0] = sel_code;
SerBuffer[1] = (unsigned char)(NVB_MIN_PARAMETER + ((bitcount / BITS_PER_BYTE) << UPPER_NIBBLE_SHIFT) + nbits);
for(i=0;i<nbytes;i++)
SerBuffer[2+i] = snr[i]; /* copy serial number to tranmit buffer */
/* set TxLastBits and RxAlign to number of bits sent */
RcSetReg(JREG_BITFRAMING, (unsigned char)((nbits << UPPER_NIBBLE_SHIFT) | nbits));
/* prepare data for common transceive */
ResetInfo(MInfo);
MInfo.nBytesToSend = (unsigned char)(nbytes + 2);
SetTimeOut(300);
status = M522PcdCmd(JCMD_TRANSCEIVE, SerBuffer, &MInfo);
if(istatus == STATUS_COLLISION_ERROR || istatus == STATUS_SUCCESS)
{
/* store number of received data bits and bytes internaly */
rbits = (unsigned char)(MInfo.nBitsReceived + (MInfo.nBytesReceived << 3) - nbits);
if((rbits + bitcount) > COMPLETE_UID_BITS)
{
istatus = STATUS_BITCOUNT_ERROR;
continue;
}
/* increment number of bytes received if also some bits received */
if(MInfo.nBitsReceived)
MInfo.nBytesReceived++;
/* reset offset for data copying */
byteOffset = 0;
/* if number of bits sent are not 0, write first received byte in last of sent */
if(nbits)
{ /* last byte transmitted and first byte received are the same */
snr[nbytes - 1] |= SerBuffer[0];
byteOffset++;
}
for(i=0;i<(4-nbytes);i++)
snr[nbytes + i] = SerBuffer[i + byteOffset];
if(istatus == STATUS_COLLISION_ERROR)
{
/* calculate new bitcount value */
bitcount = (unsigned char)(bitcount + rbits);
istatus = STATUS_SUCCESS;
} else
{
if((snr[0] ^ snr[1] ^ snr[2] ^ snr[3]) != SerBuffer[i + byteOffset])
{
istatus = STATUS_WRONG_UID_CHECKBYTE;
continue;
}
complete=1;
}
}
}
/* clear RxAlign and TxLastbits */
RcSetReg(JREG_BITFRAMING, 0);
/* activate values after coll */
RcSetReg(JREG_COLL, JBIT_VALUESAFTERCOLL);
return istatus;
}
/*************************************************
Function: AnticollSelect
Description:
selecte a card to response the following command
NOTE: this founction is used internal only, and cannot call by application program
Parameter:
sel_code command code
snr buffer to store the card UID
sak the byte to save the ACK from card
Return:
short status of implement
**************************************************/
short Select(unsigned char sel_code, unsigned char *snr, unsigned char *sak)
{
short status = STATUS_SUCCESS;
/* define local variables */
unsigned char i;
/* activate CRC */
RcModifyReg(JREG_TXMODE, 1, JBIT_CRCEN);
RcModifyReg(JREG_RXMODE, 1, JBIT_CRCEN);
/* prepare data stream */
SerBuffer[0] = sel_code; /* command code */
SerBuffer[1] = NVB_MAX_PARAMETER; /* parameter */
for(i=0;i<4;i++)
SerBuffer[2+i] = snr[i]; /* serial numbner bytes 1 to 4 */
SerBuffer[6] = (unsigned char)(snr[0] ^ snr[1] ^ snr[2] ^ snr[3]); /* serial number check byte */
/* prepare data for common transceive */
ResetInfo(MInfo);
MInfo.nBytesToSend = 0x07;
SetTimeOut(300);
status = M522PcdCmd(JCMD_TRANSCEIVE, SerBuffer, &MInfo);
if(status == STATUS_SUCCESS)
{
if(MInfo.nBytesReceived == SAK_LENGTH && MInfo.nBitsReceived == 0)
*sak = SerBuffer[0];
else
status = STATUS_BITCOUNT_ERROR;
}
return status;
}
/*************************************************
Function: AnticollSelect
Description:
Anticollision loop and selecte a card to operate
Parameter:
bcnt bit counter of known UID
snr buffer to store the card UID
Return:
short status of implement
**************************************************/
short AnticollSelect(unsigned char bcnt, unsigned char *snr)
{
unsigned char i;
short status=STATUS_SUCCESS;
unsigned char length, casc_code, length_in,sak,tmpSnr[12];
length_in = bcnt;
/* do loop for max. cascade level */
for(i=0;i<MAX_CASCADE_LEVELS;i++)
{
if(length_in)
{
if(length_in > SINGLE_UID_LENGTH)
{
length = SINGLE_UID_LENGTH;
length_in -= SINGLE_UID_LENGTH;
}
else
{
length = length_in;
length_in = 0;
}
}
else
{
length = 0;
}
switch(i)
{
case 1: casc_code = SELECT_CASCADE_LEVEL_2;
memcpy(snr, tmpSnr+1,3);
break;
case 2: casc_code = SELECT_CASCADE_LEVEL_3;
break;
default: casc_code = SELECT_CASCADE_LEVEL_1;
break;
}
if(length != SINGLE_UID_LENGTH && status == STATUS_SUCCESS)
/* do anticollission with selected level */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -