Issues initializing SPI connection between MFRC522 reader and nRF52840 dongle

Hey im new to the nordics family. Recently bought nRF52840dongle to work with a project im developing. So im using RFID-RC522 reader connected to the nRF52840 dongle via SPI. Problem is that i cant get anything out of the reader. Found some topics here all ready and tried https://github.com/mervedamar/MFRC522-NRF52 this. Changed pin configurations regarding my own physical wiring connected between nRF52840dongle and RC522 reader. From oscilloscope i could see that clock and MOSI was giving some signals. is there any samples or could you provide me some help to proceed with my project. Thanks!

Parents
  • Hi,

    I do not have any experience with RC522 and we do not have explicit support for it, but you should be able to communicate with it over SPI and use it as I see is done in the Github repository you linked to.

    The next thing should be to debug to understand what is going on. Do you have a debugger you can hook up to the dongle? If not, an alternative is an nRF52840 DK, which has an onboard debugger (that is a better development platform in itself, and can also be used to debug the dongle).

    As you see data on MOSI the nRF is clearly attempting to communicate with the slave (RC522). Is there any data being read back? Have you analyzed the data sent from the nRF to see if it is valid for the RC522? This will be easier to check if you have a logic analyzer that can analyze SPI and show you the data. Also, have you checked basic connections?

  • Hey Einar,

    Unfortunately i dont have debugger that i could hook into the dongle. The application is running till this point i can see from terminal: 

    Could the problem be how the RST or CS is handled? Cant figure out how to configure them...

  • here you can see the files and configures im using atm:

    #include <zephyr/drivers/gpio.h>
    
    #include <zephyr/drivers/SPi.h>
    #include "MFRC522.h"
    
    
    
    /* The devicetree node identifier for the "led0" alias. */
    #define LED0_NODE DT_ALIAS(led0)
    uint8_t ID[5];
    /*
     * A build error on this line means your board is unsupported.
     * See the sample documentation for information on how to fix this.
     */
    static const struct gpio_dt_spec led = GPIO_DT_SPEC_GET(LED0_NODE, gpios);
    
    int main(void)
    {
    	int ret;
    SPI_Init();
    TM_MFRC522_Init();
    	if (!gpio_is_ready_dt(&led)) {
    		return 0;
    	}
    
    	ret = gpio_pin_configure_dt(&led, GPIO_OUTPUT_ACTIVE);
    	if (ret < 0) {
    		return 0;
    	}
    
    	while (1) {
    
        if ((TM_MFRC522_Check(ID) == MI_OK))
    	{
    		gpio_pin_toggle_dt(&led);
    printk(" [%02x%02x%02x%02x%02x]\n\r\n", ID[0], ID[1], ID[2], ID[3], ID[4]);
    	}
    
    	
    	
    	}
    	return 0;
    }
    #include <stdio.h>
    #include "MFRC522.h"
    
    #include <zephyr/drivers/gpio.h>
    #include <zephyr/drivers/spi.h>
    
    
    
    #define PICC_TIMEOUT_5MS    0x09
    #define PICC_TIMEOUT_10MS   0x13
    #define PICC_TIMEOUT_15MS   0x1E
    
    
    const struct device *gpio1_dev = DEVICE_DT_GET(DT_NODELABEL(gpio1));
    const struct device *spi_dev;
    
    struct spi_config spi_cfg;
    struct spi_cs_control chip;
    
    struct spi_buf tx_buf;
    struct spi_buf rx_buf;
    
    void SPI_Init(void)
    {
     spi_dev = DEVICE_DT_GET(DT_NODELABEL(spi1));
        if (!spi_dev) {
            printk("Failed to get SPI device\n");
            return;
        }
    
        gpio0_dev = DEVICE_DT_GET(DT_NODELABEL(gpio0)); // GPIO cihazını tanımla
    
        if (!gpio0_dev) {
            printk("Failed to get GPIO device\n");
            return;
        }
    
        // SPI yapılandırması
        spi_cfg.frequency = 4000000;
        spi_cfg.operation = SPI_WORD_SET(8) | SPI_TRANSFER_MSB |
                            SPI_MODE_CPOL | SPI_MODE_CPHA;
        spi_cfg.slave = 0;
    
        // CS pini için yapılandırma
        chip.gpio.port = gpio1_dev;
        chip.gpio.pin = 13;
        chip.gpio.dt_flags = GPIO_ACTIVE_LOW;
        chip.delay = 2;
    
        // SPI yapılandırmasına CS pinini ekle
        spi_cfg.cs = &chip;
    
        printk("\r\nSPI device is initialized and ready.\n");
    }
    
    uint8_t TM_MFRC522_RdReg(uint8_t ucAddress)
    {
        uint8_t command = ucAddress | 0x80; // MFRC522 adresi ile okuma komutunu oluştur
        uint8_t tx_data[2] = {command, 0x00};  // Okunan veriyi alacak buffer
        uint8_t rx_data[2] = {0};  // Okunan veriyi alacak buffer
    
        tx_buf.buf = tx_data;
        tx_buf.len = 2;
    
        rx_buf.buf = rx_data;
        rx_buf.len = 2;
    
        struct spi_buf_set tx = {
            .buffers = &tx_buf,
            .count = 1
        };
    
        struct spi_buf_set rx = {
            .buffers = &rx_buf,
            .count = 1
        };
    
        if (spi_transceive(spi_dev, &spi_cfg, &tx, &rx) != 0) {
            printk("\r\nError reading MFRC522 register\r\n");
            return 0;  // Hata durumunda 0 dön
        }
    
        return rx_data[1];  // Okunan veriyi dön
    }
    
    
    void TM_MFRC522_WrReg(uint8_t ucAddress, uint8_t ucValue)
    {
        uint8_t command = (ucAddress << 1) & 0x7E;  // MFRC522 adresi ile yazma komutunu oluştur
    
        struct spi_buf_set tx_bufs;
        struct spi_buf txb[2];
    
        txb[0].buf = &command;
        txb[0].len = 1;
        txb[1].buf = &ucValue;
        txb[1].len = 1;
    
        tx_bufs.buffers = txb;
        tx_bufs.count = 2;
    
        int ret = spi_write(spi_dev, &spi_cfg, &tx_bufs);
        if (ret != 0) {
            printk("\r\nSPI transfer failed with error: %d\r\n", ret);
            // Hata durumunda gerekli işlemler yapılabilir
        } else {
            // SPI iletişimi başarıyla gerçekleştirildi
        }
    }
    
    
    
    
    
     
    
    
    
    void TM_MFRC522_Init(void)
        {
    
        TM_MFRC522_Reset();
    
        TM_MFRC522_WrReg(MFRC522_REG_T_MODE, 0x8D);
        TM_MFRC522_WrReg(MFRC522_REG_T_PRESCALER, 0x3E);
    
        TM_MFRC522_WrReg(MFRC522_REG_T_RELOAD_L, 0x09);
        TM_MFRC522_WrReg(MFRC522_REG_T_RELOAD_H, 0);
    
        TM_MFRC522_WrReg(MFRC522_REG_TX_AUTO, 0x40);
        TM_MFRC522_WrReg(MFRC522_REG_MODE, 0x3D);
    
        TM_MFRC522_WrReg(MFRC522_REG_RF_CFG, 0x70);
    
        TM_MFRC522_SetBitMask(MFRC522_REG_DIV1_EN, 0x80);
    
        TM_MFRC522_AntennaOn();
    
    
        }
    
    
    /* A function to initialize SPI Instance */
    
    
    
    void TM_MFRC522_SetBitMask(uint8_t reg, uint8_t mask)
        {
        TM_MFRC522_WrReg(reg, TM_MFRC522_RdReg(reg) | mask);
        }
    
    void TM_MFRC522_ClearBitMask(uint8_t reg, uint8_t mask)
        {
        TM_MFRC522_WrReg(reg, TM_MFRC522_RdReg(reg) & (~mask));
        }
    
    void TM_MFRC522_AntennaOn(void)
        {
        uint8_t temp;
    
        temp = TM_MFRC522_RdReg(MFRC522_REG_TX_CONTROL);
        if (!(temp & 0x03))
    	TM_MFRC522_SetBitMask(MFRC522_REG_TX_CONTROL, 0x03);
        }
    
    void TM_MFRC522_AntennaOff(void)
        {
        TM_MFRC522_ClearBitMask(MFRC522_REG_TX_CONTROL, 0x03);
        }
    
    void TM_MFRC522_Reset(void)
        {
        uint8_t temp;
    
        TM_MFRC522_WrReg(MFRC522_REG_COMMAND, PCD_RESETPHASE);
    
        do
    	{
    	temp = TM_MFRC522_RdReg(MFRC522_REG_COMMAND);
    	temp &= 0x10;
    	}
        while (temp);
        }
    
    uint8_t MFRC522_ToCard(uint8_t command, uint8_t *sendData, uint8_t sendLen, uint8_t *backData,unsigned *backLen)
        {
        uint8_t _status = MI_ERR;
        uint8_t irqEn = 0x00;
        uint8_t waitIRq = 0x00;
        uint8_t lastBits;
        uint8_t n;
        unsigned i;
    
        switch (command)
    	{
        case PCD_AUTHENT:
    	{
    	irqEn = 0x12;
    	waitIRq = 0x10;
    	break;
    	}
        case PCD_TRANSCEIVE:
    	{
    	irqEn = 0x77;
    	waitIRq = 0x30;
    	break;
    	}
        default:
    	break;
    	}
    
        TM_MFRC522_WrReg(MFRC522_REG_COMM_IE_N, irqEn | 0x80);
        TM_MFRC522_ClearBitMask(MFRC522_REG_COMM_IRQ, 0x80);
        TM_MFRC522_SetBitMask(MFRC522_REG_FIFO_LEVEL, 0x80);
        TM_MFRC522_WrReg(MFRC522_REG_COMMAND, PCD_IDLE);
    
        for (i = 0; i < sendLen; i++)
    	{
    	TM_MFRC522_WrReg(MFRC522_REG_FIFO_DATA, sendData[i]);
    	}
    
        TM_MFRC522_WrReg(MFRC522_REG_COMMAND, command);
    
        if (command == PCD_TRANSCEIVE)
    	{
    	TM_MFRC522_SetBitMask(MFRC522_REG_BIT_FRAMING, 0x80);
    	}
    
        i = 0xFFFF;
        do
    	{
    
    	n = TM_MFRC522_RdReg(MFRC522_REG_COMM_IRQ);
    	i--;
    	}
        while (i && !(n & 0x01) && !(n & waitIRq));
    
        TM_MFRC522_ClearBitMask(MFRC522_REG_BIT_FRAMING, 0x80);
    
        if (i != 0)
    	{
    	if (!(TM_MFRC522_RdReg(MFRC522_REG_ERROR) & 0x1B))
    	    {
    	    _status = MI_OK;
    	    if (n & irqEn & 0x01)
    		{
    		_status = MI_NOTAGERR;
    		}
    
    	    if (command == PCD_TRANSCEIVE)
    		{
    		n = TM_MFRC522_RdReg(MFRC522_REG_FIFO_LEVEL);
    		lastBits = TM_MFRC522_RdReg(MFRC522_REG_CONTROL) & 0x07;
    		if (lastBits)
    		    {
    		    *backLen = (n - 1) * 8 + lastBits;
    		    }
    		else
    		    {
    		    *backLen = n * 8;
    		    }
    
    		if (n == 0)
    		    {
    		    n = 1;
    		    }
    
    		if (n > 16)
    		    {
    		    n = 16;
    		    }
    
    		for (i = 0; i < n; i++)
    		    {
    		    backData[i] = TM_MFRC522_RdReg(MFRC522_REG_FIFO_DATA);
    		    }
    
    		backData[i] = 0;
    		}
    	    }
    	else
    	    {
    	    _status = MI_ERR;
    	    }
    
    	}
    
        return _status;
        }
    
    uint8_t MFRC522_Request(uint8_t reqMode, uint8_t *TagType)
        {
        uint8_t _status;
        unsigned backBits;
    
        TM_MFRC522_WrReg(MFRC522_REG_BIT_FRAMING, 0x07);
    
        TagType[0] = reqMode;
        _status = MFRC522_ToCard(PCD_TRANSCEIVE, TagType, 1, TagType, &backBits);
    
        if ((_status != MI_OK) || (backBits != 0x10))
    	{
    	_status = MI_ERR;
    	}
    
        return _status;
        }
    
    uint8_t MFRC522_isCard(uint8_t *TagType)
        {
        if (MFRC522_Request(PICC_REQA, TagType) == MI_OK)
    
    	return 1;
        else
    	return 0;
        }
    		
    TM_MFRC522_STS_T TM_MFRC522_Anticoll(uint8_t* serNum)
    {
        TM_MFRC522_STS_T status;
        uint8_t i;
        uint8_t serNumCheck = 0;
        uint16_t unLen;
    	
    		TM_MFRC522_ClearBitMask(MFRC522_REG_STATUS2,0x08);
        TM_MFRC522_WrReg(MFRC522_REG_BIT_FRAMING, 0x00);		//TxLastBists = BitFramingReg[2..0]
    		TM_MFRC522_SetBitMask(MFRC522_REG_COLL,0x80);
    	
        /* ANTICOLLISION command with NVB does not specify 40 valid bits (NVB not to 0x70) */
        /* Note: "NVB=0x20" defines that the PCD will transmit no part of UID CLn, and it forces all
                 PICCs in the field to respond with their complete UID CLn. */
        serNum[0] = PICC_ANTICOLL;
        serNum[1] = 0x20;   // NVB
        status = TM_MFRC522_ToCard(PCD_TRANSCEIVE, serNum, 2, serNum, &unLen);
    
        if (status == MI_OK) {
            /* Check card serial number */
            for (i = 0; i < 4; i++) { 
    					serNumCheck ^= serNum[i];					
            }
            
            /* BCC: UID CLn checkbyte and is calculated
               as exclusive-or over the 4 previous bytes */
            if (serNumCheck != serNum[i] ) {
                status = MI_ERR;    
            }
        }
    		TM_MFRC522_SetBitMask(MFRC522_REG_COLL,0x80);
    		
        return status;
    } 
    
    TM_MFRC522_STS_T TM_MFRC522_ToCard(uint8_t command, uint8_t* sendData, uint8_t sendLen, uint8_t* backData, uint16_t* backLen)
    {
        TM_MFRC522_STS_T status = MI_ERR;
        uint8_t irqEn = 0x00;
    		uint8_t waitFor = 0x00;
        uint8_t lastBits;
        uint8_t regValue;
        uint16_t i;
        
        switch (command)
        {
            case PCD_AUTHENT:
                irqEn = 0x13;
    						waitFor = 0x10;
            //    irqEn = 0x12; (original setting)
                break;
            case PCD_TRANSCEIVE:
                /* TxIRq(b6), RxIRq(b5), IdleIRq(b4),
                   HiAlerIRq(b3), LoAlertIRq(b2), ErrIRq(b1), TimerIRq(b0) */
                /* wait response from PICC or 5 ms timeout */
                irqEn = 0x21;
    						waitFor = 0x30;
                break;
            default:
                break;
        }
        /* IRQ pin is inverted with respect to the Status1Reg register’s IRq bit */
        TM_MFRC522_WrReg(MFRC522_REG_COMM_IE_N, irqEn | 0x80);
    
        /* Clear marked bits in ComIrqReg register */
        TM_MFRC522_ClearBitMask(MFRC522_REG_COMM_IRQ, 0x80);
    		
    		TM_MFRC522_WrReg(MFRC522_REG_COMMAND,PCD_IDLE);
    
        /* Flush FIFO contents */
        TM_MFRC522_SetBitMask(MFRC522_REG_FIFO_LEVEL, 0x80);
    
        /* Cancel current comand execution */
        TM_MFRC522_WrReg(MFRC522_REG_COMMAND, PCD_IDLE);
    
        /* Write data to FIFO */
        for (i = 0; i < sendLen; i++) {   
            TM_MFRC522_WrReg(MFRC522_REG_FIFO_DATA, sendData[i]);    
        }
    
        /* Execute PCD_TRANSCEIVE command */
        TM_MFRC522_WrReg(MFRC522_REG_COMMAND, command);
        
        if (command == PCD_TRANSCEIVE) {    
            /* Start frame transmission */
            TM_MFRC522_SetBitMask(MFRC522_REG_BIT_FRAMING, 0x80);
        }   
    			
    		i = 1000;
        /* Wait response from PICC or internal timer 5 ms timeout happened */
        do
    		{
    			
        regValue = TM_MFRC522_RdReg(MFRC522_REG_COMM_IRQ);
    		i--;
    		}while ((i!=0) && !(regValue&0x01) && !(regValue&waitFor));
    		
    		
        /* Set StartSend=0 */
        TM_MFRC522_ClearBitMask(MFRC522_REG_BIT_FRAMING, 0x80);
    
        /* Check if internal timer timeout */
        if (!(regValue &0x01))
        {
            if(i!=0)
    				{
            if (!(TM_MFRC522_RdReg(MFRC522_REG_ERROR) & 0x1B))
            {
                status = MI_OK;
                
                if (command == PCD_TRANSCEIVE)
                {
                    /* Check the number of bytes stored in FIFO */
                    regValue = TM_MFRC522_RdReg(MFRC522_REG_FIFO_LEVEL);
                    
                    /* Check valid bit number of last byte */
                    lastBits = TM_MFRC522_RdReg(MFRC522_REG_CONTROL) & 0x07;
                    if (lastBits)
                        *backLen = (regValue - 1) * 8 + lastBits;   
                    else
                        *backLen = regValue * 8;
    
                    if (regValue == 0)
                        regValue = 1;    
                    if (regValue > MFRC522_MAX_LEN)
                        regValue = MFRC522_MAX_LEN;   
    
                    /* Read received data in FIFO */
                    for (i = 0; i < regValue; i++)
                        backData[i] = TM_MFRC522_RdReg(MFRC522_REG_FIFO_DATA);    
                }
            }
            else
    				{status = MI_ERR;}
        }
    
    }
    		TM_MFRC522_SetBitMask(MFRC522_REG_CONTROL,0x80);
    		TM_MFRC522_WrReg(MFRC522_REG_COMMAND,PCD_IDLE);
        return status;
    		}
    
    
    		
    		
    		
    		
    
    void TM_MFRC522_CalculateCRC(uint8_t *pIndata, uint8_t len, uint8_t *pOutData)
        {
        uint8_t i, n;
    
        TM_MFRC522_ClearBitMask(MFRC522_REG_DIV_IRQ, 0x04);
    
        TM_MFRC522_SetBitMask(MFRC522_REG_FIFO_LEVEL, 0x80);
    
        for (i = 0; i < len; i++)
    	{
    	TM_MFRC522_WrReg(MFRC522_REG_FIFO_DATA, *(pIndata + i));
    	}
        TM_MFRC522_WrReg(MFRC522_REG_COMMAND, PCD_CALCCRC);
    
        i = 0xFF;
        do
    	{
    	n = TM_MFRC522_RdReg(MFRC522_REG_DIV_IRQ);
    	i--;
    	}
        while ((i != 0) && !(n & 0x04));
    
        pOutData[0] = TM_MFRC522_RdReg(MFRC522_REG_CRC_RESULT_L);
        pOutData[1] = TM_MFRC522_RdReg(MFRC522_REG_CRC_RESULT_M);
        }
    
    
    void TM_MFRC522_Halt(void)
        {
    
        unsigned unLen;
        uint8_t buff[4];
    
        buff[0] = PICC_HALT;
        buff[1] = 0;
        TM_MFRC522_CalculateCRC(buff, 2, &buff[2]);
    
        if (MFRC522_ToCard(PCD_TRANSCEIVE, buff, 4, buff, &unLen) != MI_NOTAGERR)
    	{
    	printf("Halt command error. \n");
    	}
    
        }
    
    		
    		uint8_t TM_MFRC522_Check(uint8_t *id)
        {
        uint8_t status;
        uint8_t cardtype[3];
    
        status = MFRC522_Request(PICC_REQA, cardtype);
        if (status == MI_OK)
    	status = TM_MFRC522_Anticoll(id);
        else
    	status = MI_ERR;
    		
        return status;
    		
        }
    		
    		
    		
    
    5078.MFRC522.h

Reply
  • here you can see the files and configures im using atm:

    #include <zephyr/drivers/gpio.h>
    
    #include <zephyr/drivers/SPi.h>
    #include "MFRC522.h"
    
    
    
    /* The devicetree node identifier for the "led0" alias. */
    #define LED0_NODE DT_ALIAS(led0)
    uint8_t ID[5];
    /*
     * A build error on this line means your board is unsupported.
     * See the sample documentation for information on how to fix this.
     */
    static const struct gpio_dt_spec led = GPIO_DT_SPEC_GET(LED0_NODE, gpios);
    
    int main(void)
    {
    	int ret;
    SPI_Init();
    TM_MFRC522_Init();
    	if (!gpio_is_ready_dt(&led)) {
    		return 0;
    	}
    
    	ret = gpio_pin_configure_dt(&led, GPIO_OUTPUT_ACTIVE);
    	if (ret < 0) {
    		return 0;
    	}
    
    	while (1) {
    
        if ((TM_MFRC522_Check(ID) == MI_OK))
    	{
    		gpio_pin_toggle_dt(&led);
    printk(" [%02x%02x%02x%02x%02x]\n\r\n", ID[0], ID[1], ID[2], ID[3], ID[4]);
    	}
    
    	
    	
    	}
    	return 0;
    }
    #include <stdio.h>
    #include "MFRC522.h"
    
    #include <zephyr/drivers/gpio.h>
    #include <zephyr/drivers/spi.h>
    
    
    
    #define PICC_TIMEOUT_5MS    0x09
    #define PICC_TIMEOUT_10MS   0x13
    #define PICC_TIMEOUT_15MS   0x1E
    
    
    const struct device *gpio1_dev = DEVICE_DT_GET(DT_NODELABEL(gpio1));
    const struct device *spi_dev;
    
    struct spi_config spi_cfg;
    struct spi_cs_control chip;
    
    struct spi_buf tx_buf;
    struct spi_buf rx_buf;
    
    void SPI_Init(void)
    {
     spi_dev = DEVICE_DT_GET(DT_NODELABEL(spi1));
        if (!spi_dev) {
            printk("Failed to get SPI device\n");
            return;
        }
    
        gpio0_dev = DEVICE_DT_GET(DT_NODELABEL(gpio0)); // GPIO cihazını tanımla
    
        if (!gpio0_dev) {
            printk("Failed to get GPIO device\n");
            return;
        }
    
        // SPI yapılandırması
        spi_cfg.frequency = 4000000;
        spi_cfg.operation = SPI_WORD_SET(8) | SPI_TRANSFER_MSB |
                            SPI_MODE_CPOL | SPI_MODE_CPHA;
        spi_cfg.slave = 0;
    
        // CS pini için yapılandırma
        chip.gpio.port = gpio1_dev;
        chip.gpio.pin = 13;
        chip.gpio.dt_flags = GPIO_ACTIVE_LOW;
        chip.delay = 2;
    
        // SPI yapılandırmasına CS pinini ekle
        spi_cfg.cs = &chip;
    
        printk("\r\nSPI device is initialized and ready.\n");
    }
    
    uint8_t TM_MFRC522_RdReg(uint8_t ucAddress)
    {
        uint8_t command = ucAddress | 0x80; // MFRC522 adresi ile okuma komutunu oluştur
        uint8_t tx_data[2] = {command, 0x00};  // Okunan veriyi alacak buffer
        uint8_t rx_data[2] = {0};  // Okunan veriyi alacak buffer
    
        tx_buf.buf = tx_data;
        tx_buf.len = 2;
    
        rx_buf.buf = rx_data;
        rx_buf.len = 2;
    
        struct spi_buf_set tx = {
            .buffers = &tx_buf,
            .count = 1
        };
    
        struct spi_buf_set rx = {
            .buffers = &rx_buf,
            .count = 1
        };
    
        if (spi_transceive(spi_dev, &spi_cfg, &tx, &rx) != 0) {
            printk("\r\nError reading MFRC522 register\r\n");
            return 0;  // Hata durumunda 0 dön
        }
    
        return rx_data[1];  // Okunan veriyi dön
    }
    
    
    void TM_MFRC522_WrReg(uint8_t ucAddress, uint8_t ucValue)
    {
        uint8_t command = (ucAddress << 1) & 0x7E;  // MFRC522 adresi ile yazma komutunu oluştur
    
        struct spi_buf_set tx_bufs;
        struct spi_buf txb[2];
    
        txb[0].buf = &command;
        txb[0].len = 1;
        txb[1].buf = &ucValue;
        txb[1].len = 1;
    
        tx_bufs.buffers = txb;
        tx_bufs.count = 2;
    
        int ret = spi_write(spi_dev, &spi_cfg, &tx_bufs);
        if (ret != 0) {
            printk("\r\nSPI transfer failed with error: %d\r\n", ret);
            // Hata durumunda gerekli işlemler yapılabilir
        } else {
            // SPI iletişimi başarıyla gerçekleştirildi
        }
    }
    
    
    
    
    
     
    
    
    
    void TM_MFRC522_Init(void)
        {
    
        TM_MFRC522_Reset();
    
        TM_MFRC522_WrReg(MFRC522_REG_T_MODE, 0x8D);
        TM_MFRC522_WrReg(MFRC522_REG_T_PRESCALER, 0x3E);
    
        TM_MFRC522_WrReg(MFRC522_REG_T_RELOAD_L, 0x09);
        TM_MFRC522_WrReg(MFRC522_REG_T_RELOAD_H, 0);
    
        TM_MFRC522_WrReg(MFRC522_REG_TX_AUTO, 0x40);
        TM_MFRC522_WrReg(MFRC522_REG_MODE, 0x3D);
    
        TM_MFRC522_WrReg(MFRC522_REG_RF_CFG, 0x70);
    
        TM_MFRC522_SetBitMask(MFRC522_REG_DIV1_EN, 0x80);
    
        TM_MFRC522_AntennaOn();
    
    
        }
    
    
    /* A function to initialize SPI Instance */
    
    
    
    void TM_MFRC522_SetBitMask(uint8_t reg, uint8_t mask)
        {
        TM_MFRC522_WrReg(reg, TM_MFRC522_RdReg(reg) | mask);
        }
    
    void TM_MFRC522_ClearBitMask(uint8_t reg, uint8_t mask)
        {
        TM_MFRC522_WrReg(reg, TM_MFRC522_RdReg(reg) & (~mask));
        }
    
    void TM_MFRC522_AntennaOn(void)
        {
        uint8_t temp;
    
        temp = TM_MFRC522_RdReg(MFRC522_REG_TX_CONTROL);
        if (!(temp & 0x03))
    	TM_MFRC522_SetBitMask(MFRC522_REG_TX_CONTROL, 0x03);
        }
    
    void TM_MFRC522_AntennaOff(void)
        {
        TM_MFRC522_ClearBitMask(MFRC522_REG_TX_CONTROL, 0x03);
        }
    
    void TM_MFRC522_Reset(void)
        {
        uint8_t temp;
    
        TM_MFRC522_WrReg(MFRC522_REG_COMMAND, PCD_RESETPHASE);
    
        do
    	{
    	temp = TM_MFRC522_RdReg(MFRC522_REG_COMMAND);
    	temp &= 0x10;
    	}
        while (temp);
        }
    
    uint8_t MFRC522_ToCard(uint8_t command, uint8_t *sendData, uint8_t sendLen, uint8_t *backData,unsigned *backLen)
        {
        uint8_t _status = MI_ERR;
        uint8_t irqEn = 0x00;
        uint8_t waitIRq = 0x00;
        uint8_t lastBits;
        uint8_t n;
        unsigned i;
    
        switch (command)
    	{
        case PCD_AUTHENT:
    	{
    	irqEn = 0x12;
    	waitIRq = 0x10;
    	break;
    	}
        case PCD_TRANSCEIVE:
    	{
    	irqEn = 0x77;
    	waitIRq = 0x30;
    	break;
    	}
        default:
    	break;
    	}
    
        TM_MFRC522_WrReg(MFRC522_REG_COMM_IE_N, irqEn | 0x80);
        TM_MFRC522_ClearBitMask(MFRC522_REG_COMM_IRQ, 0x80);
        TM_MFRC522_SetBitMask(MFRC522_REG_FIFO_LEVEL, 0x80);
        TM_MFRC522_WrReg(MFRC522_REG_COMMAND, PCD_IDLE);
    
        for (i = 0; i < sendLen; i++)
    	{
    	TM_MFRC522_WrReg(MFRC522_REG_FIFO_DATA, sendData[i]);
    	}
    
        TM_MFRC522_WrReg(MFRC522_REG_COMMAND, command);
    
        if (command == PCD_TRANSCEIVE)
    	{
    	TM_MFRC522_SetBitMask(MFRC522_REG_BIT_FRAMING, 0x80);
    	}
    
        i = 0xFFFF;
        do
    	{
    
    	n = TM_MFRC522_RdReg(MFRC522_REG_COMM_IRQ);
    	i--;
    	}
        while (i && !(n & 0x01) && !(n & waitIRq));
    
        TM_MFRC522_ClearBitMask(MFRC522_REG_BIT_FRAMING, 0x80);
    
        if (i != 0)
    	{
    	if (!(TM_MFRC522_RdReg(MFRC522_REG_ERROR) & 0x1B))
    	    {
    	    _status = MI_OK;
    	    if (n & irqEn & 0x01)
    		{
    		_status = MI_NOTAGERR;
    		}
    
    	    if (command == PCD_TRANSCEIVE)
    		{
    		n = TM_MFRC522_RdReg(MFRC522_REG_FIFO_LEVEL);
    		lastBits = TM_MFRC522_RdReg(MFRC522_REG_CONTROL) & 0x07;
    		if (lastBits)
    		    {
    		    *backLen = (n - 1) * 8 + lastBits;
    		    }
    		else
    		    {
    		    *backLen = n * 8;
    		    }
    
    		if (n == 0)
    		    {
    		    n = 1;
    		    }
    
    		if (n > 16)
    		    {
    		    n = 16;
    		    }
    
    		for (i = 0; i < n; i++)
    		    {
    		    backData[i] = TM_MFRC522_RdReg(MFRC522_REG_FIFO_DATA);
    		    }
    
    		backData[i] = 0;
    		}
    	    }
    	else
    	    {
    	    _status = MI_ERR;
    	    }
    
    	}
    
        return _status;
        }
    
    uint8_t MFRC522_Request(uint8_t reqMode, uint8_t *TagType)
        {
        uint8_t _status;
        unsigned backBits;
    
        TM_MFRC522_WrReg(MFRC522_REG_BIT_FRAMING, 0x07);
    
        TagType[0] = reqMode;
        _status = MFRC522_ToCard(PCD_TRANSCEIVE, TagType, 1, TagType, &backBits);
    
        if ((_status != MI_OK) || (backBits != 0x10))
    	{
    	_status = MI_ERR;
    	}
    
        return _status;
        }
    
    uint8_t MFRC522_isCard(uint8_t *TagType)
        {
        if (MFRC522_Request(PICC_REQA, TagType) == MI_OK)
    
    	return 1;
        else
    	return 0;
        }
    		
    TM_MFRC522_STS_T TM_MFRC522_Anticoll(uint8_t* serNum)
    {
        TM_MFRC522_STS_T status;
        uint8_t i;
        uint8_t serNumCheck = 0;
        uint16_t unLen;
    	
    		TM_MFRC522_ClearBitMask(MFRC522_REG_STATUS2,0x08);
        TM_MFRC522_WrReg(MFRC522_REG_BIT_FRAMING, 0x00);		//TxLastBists = BitFramingReg[2..0]
    		TM_MFRC522_SetBitMask(MFRC522_REG_COLL,0x80);
    	
        /* ANTICOLLISION command with NVB does not specify 40 valid bits (NVB not to 0x70) */
        /* Note: "NVB=0x20" defines that the PCD will transmit no part of UID CLn, and it forces all
                 PICCs in the field to respond with their complete UID CLn. */
        serNum[0] = PICC_ANTICOLL;
        serNum[1] = 0x20;   // NVB
        status = TM_MFRC522_ToCard(PCD_TRANSCEIVE, serNum, 2, serNum, &unLen);
    
        if (status == MI_OK) {
            /* Check card serial number */
            for (i = 0; i < 4; i++) { 
    					serNumCheck ^= serNum[i];					
            }
            
            /* BCC: UID CLn checkbyte and is calculated
               as exclusive-or over the 4 previous bytes */
            if (serNumCheck != serNum[i] ) {
                status = MI_ERR;    
            }
        }
    		TM_MFRC522_SetBitMask(MFRC522_REG_COLL,0x80);
    		
        return status;
    } 
    
    TM_MFRC522_STS_T TM_MFRC522_ToCard(uint8_t command, uint8_t* sendData, uint8_t sendLen, uint8_t* backData, uint16_t* backLen)
    {
        TM_MFRC522_STS_T status = MI_ERR;
        uint8_t irqEn = 0x00;
    		uint8_t waitFor = 0x00;
        uint8_t lastBits;
        uint8_t regValue;
        uint16_t i;
        
        switch (command)
        {
            case PCD_AUTHENT:
                irqEn = 0x13;
    						waitFor = 0x10;
            //    irqEn = 0x12; (original setting)
                break;
            case PCD_TRANSCEIVE:
                /* TxIRq(b6), RxIRq(b5), IdleIRq(b4),
                   HiAlerIRq(b3), LoAlertIRq(b2), ErrIRq(b1), TimerIRq(b0) */
                /* wait response from PICC or 5 ms timeout */
                irqEn = 0x21;
    						waitFor = 0x30;
                break;
            default:
                break;
        }
        /* IRQ pin is inverted with respect to the Status1Reg register’s IRq bit */
        TM_MFRC522_WrReg(MFRC522_REG_COMM_IE_N, irqEn | 0x80);
    
        /* Clear marked bits in ComIrqReg register */
        TM_MFRC522_ClearBitMask(MFRC522_REG_COMM_IRQ, 0x80);
    		
    		TM_MFRC522_WrReg(MFRC522_REG_COMMAND,PCD_IDLE);
    
        /* Flush FIFO contents */
        TM_MFRC522_SetBitMask(MFRC522_REG_FIFO_LEVEL, 0x80);
    
        /* Cancel current comand execution */
        TM_MFRC522_WrReg(MFRC522_REG_COMMAND, PCD_IDLE);
    
        /* Write data to FIFO */
        for (i = 0; i < sendLen; i++) {   
            TM_MFRC522_WrReg(MFRC522_REG_FIFO_DATA, sendData[i]);    
        }
    
        /* Execute PCD_TRANSCEIVE command */
        TM_MFRC522_WrReg(MFRC522_REG_COMMAND, command);
        
        if (command == PCD_TRANSCEIVE) {    
            /* Start frame transmission */
            TM_MFRC522_SetBitMask(MFRC522_REG_BIT_FRAMING, 0x80);
        }   
    			
    		i = 1000;
        /* Wait response from PICC or internal timer 5 ms timeout happened */
        do
    		{
    			
        regValue = TM_MFRC522_RdReg(MFRC522_REG_COMM_IRQ);
    		i--;
    		}while ((i!=0) && !(regValue&0x01) && !(regValue&waitFor));
    		
    		
        /* Set StartSend=0 */
        TM_MFRC522_ClearBitMask(MFRC522_REG_BIT_FRAMING, 0x80);
    
        /* Check if internal timer timeout */
        if (!(regValue &0x01))
        {
            if(i!=0)
    				{
            if (!(TM_MFRC522_RdReg(MFRC522_REG_ERROR) & 0x1B))
            {
                status = MI_OK;
                
                if (command == PCD_TRANSCEIVE)
                {
                    /* Check the number of bytes stored in FIFO */
                    regValue = TM_MFRC522_RdReg(MFRC522_REG_FIFO_LEVEL);
                    
                    /* Check valid bit number of last byte */
                    lastBits = TM_MFRC522_RdReg(MFRC522_REG_CONTROL) & 0x07;
                    if (lastBits)
                        *backLen = (regValue - 1) * 8 + lastBits;   
                    else
                        *backLen = regValue * 8;
    
                    if (regValue == 0)
                        regValue = 1;    
                    if (regValue > MFRC522_MAX_LEN)
                        regValue = MFRC522_MAX_LEN;   
    
                    /* Read received data in FIFO */
                    for (i = 0; i < regValue; i++)
                        backData[i] = TM_MFRC522_RdReg(MFRC522_REG_FIFO_DATA);    
                }
            }
            else
    				{status = MI_ERR;}
        }
    
    }
    		TM_MFRC522_SetBitMask(MFRC522_REG_CONTROL,0x80);
    		TM_MFRC522_WrReg(MFRC522_REG_COMMAND,PCD_IDLE);
        return status;
    		}
    
    
    		
    		
    		
    		
    
    void TM_MFRC522_CalculateCRC(uint8_t *pIndata, uint8_t len, uint8_t *pOutData)
        {
        uint8_t i, n;
    
        TM_MFRC522_ClearBitMask(MFRC522_REG_DIV_IRQ, 0x04);
    
        TM_MFRC522_SetBitMask(MFRC522_REG_FIFO_LEVEL, 0x80);
    
        for (i = 0; i < len; i++)
    	{
    	TM_MFRC522_WrReg(MFRC522_REG_FIFO_DATA, *(pIndata + i));
    	}
        TM_MFRC522_WrReg(MFRC522_REG_COMMAND, PCD_CALCCRC);
    
        i = 0xFF;
        do
    	{
    	n = TM_MFRC522_RdReg(MFRC522_REG_DIV_IRQ);
    	i--;
    	}
        while ((i != 0) && !(n & 0x04));
    
        pOutData[0] = TM_MFRC522_RdReg(MFRC522_REG_CRC_RESULT_L);
        pOutData[1] = TM_MFRC522_RdReg(MFRC522_REG_CRC_RESULT_M);
        }
    
    
    void TM_MFRC522_Halt(void)
        {
    
        unsigned unLen;
        uint8_t buff[4];
    
        buff[0] = PICC_HALT;
        buff[1] = 0;
        TM_MFRC522_CalculateCRC(buff, 2, &buff[2]);
    
        if (MFRC522_ToCard(PCD_TRANSCEIVE, buff, 4, buff, &unLen) != MI_NOTAGERR)
    	{
    	printf("Halt command error. \n");
    	}
    
        }
    
    		
    		uint8_t TM_MFRC522_Check(uint8_t *id)
        {
        uint8_t status;
        uint8_t cardtype[3];
    
        status = MFRC522_Request(PICC_REQA, cardtype);
        if (status == MI_OK)
    	status = TM_MFRC522_Anticoll(id);
        else
    	status = MI_ERR;
    		
        return status;
    		
        }
    		
    		
    		
    
    5078.MFRC522.h

Children
Related