⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mifare.c

📁 RC522完整源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
        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 + -