MFRC 522与ATmega8。 Mifare Classic 1K不会进行身份验证

时间:2015-01-24 16:36:02

标签: nfc rfid mifare atmega atmel

基于ATmega8和Mifare RC-522的NFC / RFID控制器存在问题。

我使用this library并且我设法读取了卡片的UID。

但是,我还要读取和写入卡的其他部分,但每当我尝试使用MFRC522_Auth功能时,我都不会得到我应该的空闲中断,而是我LoAlertIrqFIFObuffer几乎是空的。

以下是readercard的文档,以下是我的代码的相关部分。

main.c:

byte = mfrc522_request(PICC_REQALL,str);
if(byte == CARD_FOUND)
{
    byte = mfrc522_get_card_serial(str);
    if(byte == CARD_FOUND)
    {
        byte = mfrc522_auth(PICC_AUTHENT1A, 7, sectorKeyA, str);
        if( (byte == CARD_FOUND) )
        {
            byte = MFRC522_Read1(4, str);
            if(byte == CARD_FOUND)
            {
                //write content of that block
            }
    }
}

图书馆的相关功能:

void mfrc522_write(uint8_t reg, uint8_t data)
{
    ENABLE_CHIP();
    spi_transmit((reg<<1)&0x7E);
    spi_transmit(data);
    DISABLE_CHIP();
}

uint8_t mfrc522_read(uint8_t reg)
{
    uint8_t data;
    ENABLE_CHIP();
    spi_transmit(((reg<<1)&0x7E)|0x80);
    data = spi_transmit(0x00);
    DISABLE_CHIP();
    return data;
}

uint8_t mfrc522_to_card(uint8_t cmd, uint8_t *send_data, uint8_t send_data_len, uint8_t *back_data, uint32_t *back_data_len)
{
    uint8_t status = 0;
    uint8_t irqEn = 0x00;
    uint8_t waitIRq = 0x00;
    uint8_t lastBits;
    uint8_t n;
    uint8_t tmp;
    uint32_t i;

    switch (cmd)
    {
        case MFAuthent_CMD:     //Certification cards close
        {
            irqEn = 0x12;
            waitIRq = 0x10;
            break;
        }
        case Transceive_CMD:    //Transmit FIFO data
        {
            irqEn = 0x77;
            waitIRq = 0x30;
            break;
        }
        default:
            break;
    }

    mfrc522_write(ComIEnReg, irqEn|0x80);   //Interrupt request
    n=mfrc522_read(ComIrqReg);
    mfrc522_write(ComIrqReg,n&(~0x80));//clear all interrupt bits
    n=mfrc522_read(FIFOLevelReg);
    mfrc522_write(FIFOLevelReg,n|0x80);//flush FIFO data
   // mfrc522_write(CommandReg, Idle_CMD);  //NO action; Cancel the current cmd???

    n=mfrc522_read(CommandReg);
    mfrc522_write(CommandReg,n|0x00);

    //Writing data to the FIFO
    for (i=0; i<send_data_len; i++)
    {
        mfrc522_write(FIFODataReg, send_data[i]);
    }


    //Execute the cmd
    mfrc522_write(CommandReg, cmd);
    if (cmd == Transceive_CMD)
    {
        n=mfrc522_read(BitFramingReg);
        mfrc522_write(BitFramingReg,n|0x80);
    }


    //Waiting to receive data to complete
    i = 2000;   //i according to the clock frequency adjustment, the operator M1 card maximum waiting time 25ms???
    while (1) {
        n = mfrc522_read(ComIrqReg);    // ComIrqReg[7..0] bits are: Set1 TxIRq RxIRq IdleIRq   HiAlertIRq LoAlertIRq ErrIRq TimerIRq

        if (n & waitIRq) {                  // One of the interrupts that signal success has been set.
            break;
        }
        if (n & 0x01) {                     // Timer interrupt - nothing received in 25ms
//          return 6; //debug purpose
            if (cmd == MFAuthent_CMD) {
                        LCD_Clear();
                        LCD_WriteTextXY(1, 3, LCD_itoa( mfrc522_read(ComIrqReg) ) );
                        _delay_ms(2500);
                    }
            break;
        }
        if (--i == 0) {                     // The emergency break. If all other condions fail we will eventually terminate on this one after 35.7ms. Communication with the MFRC522 might be down.
            if (cmd == MFAuthent_CMD) {
                LCD_Clear();
                LCD_WriteTextXY(1, 3, LCD_itoa( mfrc522_read(ComIrqReg) ) );
                _delay_ms(2500);
            }
            break;
        }
    }


    tmp=mfrc522_read(BitFramingReg);
    mfrc522_write(BitFramingReg,tmp&(~0x80));

    if (i != 0)
    {
        if(!(mfrc522_read(ErrorReg) & 0x1B))    //BufferOvfl Collerr CRCErr ProtecolErr
        {
            status = CARD_FOUND;
            if (n & irqEn & 0x01)
            {
                status = CARD_NOT_FOUND;            //??
            }

            if (cmd == Transceive_CMD)
            {
                n = mfrc522_read(FIFOLevelReg);
                lastBits = mfrc522_read(ControlReg) & 0x07;
                if (lastBits)
                {
                    *back_data_len = (n-1)*8 + lastBits;
                }
                else
                {
                    *back_data_len = n*8;
                }

                if (n == 0)
                {
                    n = 1;
                }
                if (n > MAX_LEN)
                {
                    n = MAX_LEN;
                }

                //Reading the received data in FIFO
                for (i=0; i<n; i++)
                {
                    back_data[i] = mfrc522_read(FIFODataReg);
                }
            }
        }

        if (cmd == MFAuthent_CMD) {
            LCD_WriteTextXY(1, 10, LCD_itoa16( mfrc522_read(Status2Reg) ) );
            _delay_ms(2500);
        }
    } else status = 9;


    return status;
}


uint8_t mfrc522_get_card_serial(uint8_t * serial_out)
{
    uint8_t status;
    uint8_t i;
    uint8_t serNumCheck=0;
    uint32_t unLen;

    mfrc522_write(BitFramingReg, 0x00);     //TxLastBists = BitFramingReg[2..0]

    serial_out[0] = PICC_ANTICOLL;
    serial_out[1] = 0x20;
    status = mfrc522_to_card(Transceive_CMD, serial_out, 2, serial_out, &unLen);

    if (status == CARD_FOUND)
    {
        //Check card serial number
        for (i=0; i<4; i++)
        {
            serNumCheck ^= serial_out[i];
        }
        if (serNumCheck != serial_out[i])
        {
            status = ERROR;
        }
    }
    return status;
}

uint8_t mfrc522_auth(uint8_t authMode, uint8_t BlockAddr, uint8_t *Sectorkey, uint8_t *serNum)
{
    uint8_t status;
    uint32_t recvBits;
    uint8_t i;
    uint8_t buff[12];

 // Validate instruction block address + sector + password + card serial number
    buff[0] = authMode;
    buff[1] = BlockAddr;
    for (i=0; i<6; i++)
    {
        buff[i+2] = 0xFF /**(Sectorkey+i)*/;
    }
    for (i=0; i<4; i++)
    {
        buff[i+8] = *(serNum+i);
    }

    status = mfrc522_to_card(MFAuthent_CMD, buff, 12, buff, &recvBits);

    return status;
}

uint8_t MFRC522_Read1(uint8_t blockAddr, uint8_t *recvData)
{
    uint8_t status = 0;
    uint8_t unLen, efa;

    recvData[0] = PICC_READ;
    recvData[1] = blockAddr;
    CalculateCRC(recvData, 2, &recvData);
    status = mfrc522_to_card(Transceive_CMD, recvData, 4, recvData, &unLen);

    if ((status != CARD_FOUND)|| (unLen != 0x90))
    {
        status = ERROR;
    }

    return status;
}

uint8_t CalculateCRC(uint8_t *pIndata, uint8_t len, uint8_t *pOutData)
{
    uint8_t i, n;
    uint8_t status = 0;

    n = mfrc522_read(DivIrqReg);
    mfrc522_write(DivIrqReg,n&(~0x04));         //CRCIrq = 0
    n = mfrc522_read(FIFOLevelReg);         //FIFO
    mfrc522_write(FIFOLevelReg, n|0x80);
    //Write_MFRC522(CommandReg, PCD_IDLE);

    // Write data to the FIFO
    for (i=0; i<len; i++)
    {
        mfrc522_write(FIFODataReg, *(pIndata+i));
    }
    mfrc522_write(CommandReg, CalcCRC_CMD);

    // Read the CRC calculation result
    i = 0xFF;

    while(1){
        n = mfrc522_read(DivIrqReg);

        if (n & 0x04) {
            break;
        }

        if (--i != 0) {
            return 7;
        }
    }

    // Read the CRC calculation result
    pOutData[3] = mfrc522_read(CRCResultReg_2);
    pOutData[4] = mfrc522_read(CRCResultReg_1);

    return status = 0;
}

0 个答案:

没有答案