This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CCS/EK-TM4C123GXL: MFRC552 library from C++ to C

Part Number: EK-TM4C123GXL

Tool/software: Code Composer Studio

Hello again, guys. Digging the web I found a library to allow easy use of MFRC552, but it was written in C++, but I use C, so I tried to port to C, but there is an issue: I can't authenticate my cards/tags. The code below is able to retrieve card/tag ID, but every time I try to authenticate to read or write a block, it fails and I guess it is some problem with porting code from C++ to C. I tried several changes in MFRC552_Auth function but nothing worked.

main.c

#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "driverlib/gpio.h"
#include "driverlib/pin_map.h"
#include "driverlib/sysctl.h"
#include "driverlib/uart.h"
#include "driverlib/ssi.h"
#include "driverlib/timer.h"
#include "driverlib/rom_map.h"
#include "driverlib/interrupt.h"
#include "utils/uartstdio.h"
#include "MFRC522.h"


/*PIN Connections:
 * Used SSI2 (Module 2)
 *
 * To use another Module or Reset Pin, the variables...
 * ...NRSTPD and chipSelectPin should be changed to the Pin Mask.
 *
 * Also, in MFRC552_cpp, the definitions of CHIPSELECT_BASE,...
 * ...NRSTPD_BASE and SSI_BASE must be changed to the respective...
 * ...Port Base used.
 *
 * Finally, the respective chipSelectPin and NRSTPD...
 * ... GPIO Base and Pin should be enabled in InitSSI function.
 *
 *
 * Further versions should auto-change this values.
 *
 *
 * SDA / CS / FSS ------------ PB5
 * SCK  / CLK     ------------ PB4
 * MOSI / TX      ------------ PB7
 * MISO /  RX     ------------ PB6
 *
 * RST            ------------ PF0 *
 *
 */

#define redLED   0x00000002
#define blueLED  0x00000004
#define greenLED 0x00000008

void initLeds();
void dumpHex(unsigned char* buffer, int len);

uint8_t Version;
uint8_t AntennaGain;
uint8_t status;
uint32_t readTeste;
unsigned char str[MAX_LEN];
unsigned char cardID[CARD_LENGTH];
unsigned char RxData[MAX_LEN];
unsigned char TxData[MAX_LEN];


void InitConsole(void)
{
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);

    GPIOPinConfigure(GPIO_PA0_U0RX);
    GPIOPinConfigure(GPIO_PA1_U0TX);

    SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);

    UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC);

    GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);

    UARTStdioConfig(0, 115200, 16000000);
}


void InitSSI(){
    uint32_t junkAuxVar;

    SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI2);

    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB); //SDA
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF); //reset

    GPIOPinConfigure(GPIO_PB4_SSI2CLK);
    //GPIOPinConfigure(GPIO_PB5_SSI2FSS);
    GPIOPinConfigure(GPIO_PB6_SSI2RX);
    GPIOPinConfigure(GPIO_PB7_SSI2TX);

    GPIOPinTypeSSI(GPIO_PORTB_BASE, GPIO_PIN_4 | GPIO_PIN_6 | GPIO_PIN_7);

    GPIOPinTypeGPIOOutput(CHIP_SELECT_BASE, CHIP_SELECT_PIN); //chipSelectPin
    GPIOPinTypeGPIOOutput(NRSTPD_BASE, NRSTPD_PIN); //NRSTPD

    SSIConfigSetExpClk(SSI2_BASE, SysCtlClockGet(), SSI_FRF_MOTO_MODE_0, SSI_MODE_MASTER, 4000000, 8);

    SSIEnable(SSI2_BASE);

    while(SSIDataGetNonBlocking(SSI2_BASE, &junkAuxVar));

    UARTprintf("SSI Enabled! SPI Mode!  \nData: 8bits.\n\n");

}


int main(void)
{
    SysCtlClockSet(SYSCTL_SYSDIV_2_5 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ); //80MHz

    InitConsole();
    initLeds();

    InitSSI();

    unsigned char key[6], i;
    for (i = 0; i < 6; i++)
        key[i] = 0xFF;

    GPIOPinWrite(CHIP_SELECT_BASE, CHIP_SELECT_PIN, 0);
    GPIOPinWrite(NRSTPD_BASE, NRSTPD_PIN, NRSTPD_PIN);

    MFRC552_Init();

    Version = MFRC552_ReadReg(VersionReg);
    AntennaGain = MFRC552_ReadReg(PICC_REQIDL) & (0x70);

    UARTprintf("Version: 0x%x \n", Version);
    UARTprintf("Antenna Gain: 0x%x \n\n", AntennaGain);

    while(1)
    {
        status = MFRC552_Request(PICC_REQIDL, str);
        if(status == MI_OK)
        {
            UARTprintf("Cartao 0x%0X Detectado! \n", (str[0] << 8) + str[1]); //Card Detected
            status = MFRC552_Anticoll(str);
            if(status == MI_OK)
            {
                memcpy(cardID, str, CARD_LENGTH);
                UARTprintf("ID: ");
                dumpHex((unsigned char*)cardID, CARD_LENGTH);
                if(cardID[0] == 0x36 || cardID[1] == 0xE2 || cardID[2] == 0x45 ||
                        cardID[3] == 0x43 || cardID[0] == 0xD2)
                    GPIOPinWrite(GPIO_PORTF_BASE, greenLED, greenLED);
                else
                    GPIOPinWrite(GPIO_PORTF_BASE, blueLED, blueLED);

                strcpy(TxData, "1234567890");

                status = MFRC552_Auth(0x60, 1, key, cardID);
                if(status == MI_ERR)
                {
                    UARTprintf("FALHA NA AUTENTICACAO: 0x%X\n", MFRC552_ReadReg(ErrorReg));
                    GPIOPinWrite(GPIO_PORTF_BASE, redLED, redLED);
                }
                status = MFRC552_WriteBlock(1, TxData);
                if(status == MI_ERR)
                {
                    UARTprintf("FALHA NA ESCRITA: 0x%X\n", MFRC552_ReadReg(ErrorReg));
                    GPIOPinWrite(GPIO_PORTF_BASE, redLED, redLED);
                }

                SysCtlDelay(SysCtlClockGet()/6); //Delay

                status = MFRC552_Auth(0x60, 1, key, cardID);
                if(status == MI_ERR)
                {
                    UARTprintf("FALHA NA AUTENTICACAO: 0x%X\n", MFRC552_ReadReg(ErrorReg));
                    GPIOPinWrite(GPIO_PORTF_BASE, redLED, redLED);
                }
                status = MFRC552_ReadBlock(1, RxData);
                if(status == MI_ERR)
                {
                    UARTprintf("FALHA NA LEITURA: 0x%X\n", MFRC552_ReadReg(ErrorReg));
                    GPIOPinWrite(GPIO_PORTF_BASE, redLED, redLED);
                }
                else if(status == MI_OK)
                    dumpHex((unsigned char*)RxData, 10);
            }

            else if(status == MI_ERR)
            {
                UARTprintf("Colisao detectada!!!\n", MFRC552_ReadReg(ErrorReg));
                GPIOPinWrite(GPIO_PORTF_BASE, redLED, redLED);
            }

            SysCtlDelay(SysCtlClockGet()/3); //Delay
            GPIOPinWrite(GPIO_PORTF_BASE, 0x0E, 0);
            UARTprintf("\n\nAproxime o cartao/tag\n");
        }
    }
}

void initLeds(){
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
    GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3);
}

void dumpHex(unsigned char* buffer, int len){
    int i;

    for(i=0; i < len; i++)
        UARTprintf("0x%X ", buffer[i]);
    UARTprintf("\n\n");
}

MFRC552.h

/*
	File: MFRC522.h
	MFRC522 - Library for communicating with cheap MFRC522 based NFC Reader/Writers
	Created by Eelco Rouw - Mainly based on code from Grant Gibson (www.grantgibson.co.uk) and Dr.Leong ( WWW.B2CQSHOP.COM )
	Ported to C by Stephen S. M.
	Released into the public domain
*/

/*
	MFRC522 and Card specific defines. For the role of each define, please consult the datasheet.
*/

#define MAX_LEN	16

#define CARD_LENGTH 5

#define CHIP_SELECT_BASE  GPIO_PORTB_BASE
#define CHIP_SELECT_PIN  GPIO_PIN_5
#define NRSTPD_BASE    GPIO_PORTF_BASE
#define NRSTPD_PIN    GPIO_PIN_0
#define SSI_BASE       SSI2_BASE

//MF522 - Commands
#define PCD_IDLE              0x00               
#define PCD_AUTHENT           0x0E               
#define PCD_RECEIVE           0x08               
#define PCD_TRANSMIT          0x04               
#define PCD_TRANSCEIVE        0x0C               
#define PCD_RESETPHASE        0x0F               
#define PCD_CALCCRC           0x03               

//Mifare_One - Commands
#define PICC_REQIDL           0x26
#define PICC_REQALL           0x52
#define PICC_ANTICOLL         0x93
#define PICC_SElECTTAG        0x93
#define PICC_AUTHENT1A        0x60
#define PICC_AUTHENT1B        0x61
#define PICC_READ             0x30
#define PICC_WRITE            0xA0
#define PICC_DECREMENT        0xC0
#define PICC_INCREMENT        0xC1
#define PICC_RESTORE          0xC2
#define PICC_TRANSFER         0xB0
#define PICC_HALT             0x50

//MF522 - Status
#define MI_OK                 0
#define MI_NOTAGERR           1
#define MI_ERR                2

//MF522 - Registers
//Page 0:Command and Status
#define     Reserved00            0x00    
#define     CommandReg            0x01    
#define     CommIEnReg            0x02    
#define     DivlEnReg             0x03    
#define     CommIrqReg            0x04    
#define     DivIrqReg             0x05
#define     ErrorReg              0x06    
#define     Status1Reg            0x07    
#define     Status2Reg            0x08    
#define     FIFODataReg           0x09
#define     FIFOLevelReg          0x0A
#define     WaterLevelReg         0x0B
#define     ControlReg            0x0C
#define     BitFramingReg         0x0D
#define     CollReg               0x0E
#define     Reserved01            0x0F

//Page 1:Command     
#define     Reserved10            0x10
#define     ModeReg               0x11
#define     TxModeReg             0x12
#define     RxModeReg             0x13
#define     TxControlReg          0x14
#define     TxAutoReg             0x15
#define     TxSelReg              0x16
#define     RxSelReg              0x17
#define     RxThresholdReg        0x18
#define     DemodReg              0x19
#define     Reserved11            0x1A
#define     Reserved12            0x1B
#define     MifareReg             0x1C
#define     Reserved13            0x1D
#define     Reserved14            0x1E
#define     SerialSpeedReg        0x1F

//Page 2:CFG    
#define     Reserved20            0x20  
#define     CRCResultRegM         0x21
#define     CRCResultRegL         0x22
#define     Reserved21            0x23
#define     ModWidthReg           0x24
#define     Reserved22            0x25
#define     RFCfgReg              0x26
#define     GsNReg                0x27
#define     CWGsPReg	          0x28
#define     ModGsPReg             0x29
#define     TModeReg              0x2A
#define     TPrescalerReg         0x2B
#define     TReloadRegH           0x2C
#define     TReloadRegL           0x2D
#define     TCounterValueRegH     0x2E
#define     TCounterValueRegL     0x2F

//Page 3:TestRegister     
#define     Reserved30            0x30
#define     TestSel1Reg           0x31
#define     TestSel2Reg           0x32
#define     TestPinEnReg          0x33
#define     TestPinValueReg       0x34
#define     TestBusReg            0x35
#define     AutoTestReg           0x36
#define     VersionReg            0x37
#define     AnalogTestReg         0x38
#define     TestDAC1Reg           0x39  
#define     TestDAC2Reg           0x3A   
#define     TestADCReg            0x3B   
#define     Reserved31            0x3C   
#define     Reserved32            0x3D   
#define     Reserved33            0x3E   
#define     Reserved34			  0x3F


void MFRC552_WriteReg(unsigned char addr, unsigned char val);
unsigned char MFRC552_ReadReg(unsigned char addr);
void MFRC552_SetBitMask(unsigned char reg, unsigned char mask);
void MFRC552_ClearBitMask(unsigned char reg, unsigned char mask);
void MFRC552_AntennaOn(void);
void MFRC552_AntennaOff(void);
void MFRC552_Reset(void);
void MFRC552_Init(void);
unsigned char MFRC552_Request(unsigned char reqMode, unsigned char *TagType);
unsigned char MFRC552_ToCard(unsigned char command, unsigned char *sendData, unsigned char sendLen, unsigned char *backData, unsigned int *backLen);
unsigned char MFRC552_Anticoll(unsigned char *serNum);
void MFRC552_CalulateCRC(unsigned char *pIndata, unsigned char len, unsigned char *pOutData);
unsigned char MFRC552_SelectTag(unsigned char *serNum);
unsigned char MFRC552_Auth(unsigned char authMode, unsigned char BlockAddr, unsigned char *Sectorkey, unsigned char *serNum);
unsigned char MFRC552_ReadBlock(unsigned char blockAddr, unsigned char *recvData);
unsigned char MFRC552_WriteBlock(unsigned char blockAddr, unsigned char *writeData);
void MFRC552_Halt(void);

MFRC552.c

#include <stdbool.h>
#include <stdint.h>

/*
    File: MFRC522.h
    MFRC522 - Library for communicating with cheap MFRC522 based NFC Reader/Writers
    Created by Eelco Rouw - Mainly based on code from Grant Gibson (www.grantgibson.co.uk) and Dr.Leong ( WWW.B2CQSHOP.COM )
    Ported to C by Stephen S. M.
    Released into the public domain
*/


#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "driverlib/gpio.h"
#include "driverlib/pin_map.h"
#include "driverlib/sysctl.h"
#include "driverlib/ssi.h"
#include "MFRC522.h"


/*
 * Function: WriteReg
 * Description: write a byte data into one register of MR RC522
 * Input parameter: addr--register addressï¼›val--the value that need to write in
 * Return: Null
 */
uint8_t SPI_transfer(uint8_t data)
{
    uint32_t rxtxData;

    rxtxData = data;

    SSIDataPut(SSI_BASE, (uint8_t) rxtxData);

    while(SSIBusy(SSI_BASE));

    SSIDataGet(SSI_BASE, &rxtxData);

    return (uint8_t) rxtxData;
}


void MFRC552_WriteReg(unsigned char addr, unsigned char val)
{
    GPIOPinWrite(CHIP_SELECT_BASE, CHIP_SELECT_PIN, 0);

    SPI_transfer((addr<<1)&0x7E);
    SPI_transfer(val);
    
    GPIOPinWrite(CHIP_SELECT_BASE, CHIP_SELECT_PIN, CHIP_SELECT_PIN);
}

/*
 * Function: ReadReg
 * Description: read a byte data into one register of MR RC522
 * Input parameter: addr--register address
 * Return: return the read value
 */
unsigned char MFRC552_ReadReg(unsigned char addr)
{
    unsigned char val;
    GPIOPinWrite(CHIP_SELECT_BASE, CHIP_SELECT_PIN, 0);

    SPI_transfer(((addr<<1)&0x7E) | 0x80);
    val = SPI_transfer(0x00);
    
    GPIOPinWrite(CHIP_SELECT_BASE, CHIP_SELECT_PIN, CHIP_SELECT_PIN);
    
    return val;    
}


/*
 * Function: SetBitMask
 * Description: set RC522 register bit
 * Input parameter: reg--register address;mask--value
 * Return: null
 */
void MFRC552_SetBitMask(unsigned char reg, unsigned char mask)
{
    unsigned char tmp;
    tmp = MFRC552_ReadReg(reg);
    MFRC552_WriteReg(reg, tmp | mask);  // set bit mask
}


/*
 * Function: ClearBitMask
 * Description: clear RC522 register bit
 * Input parameter: reg--register address;mask--value
 * Return: null
 */
void MFRC552_ClearBitMask(unsigned char reg, unsigned char mask)
{
    unsigned char tmp;
    tmp = MFRC552_ReadReg(reg);
    MFRC552_WriteReg(reg, tmp & (~mask));  // clear bit mask
}


/*
 * Function: AntennaOn
 * Description: Turn on antenna, every time turn on or shut down antenna need at least 1ms delay
 * Input parameter: null
 * Return: null
 */
void MFRC552_AntennaOn(void)
{
    unsigned char temp;

    temp = MFRC552_ReadReg(TxControlReg);
    if (!(temp & 0x03))
    {
        MFRC552_SetBitMask(TxControlReg, 0x03);
    }
}


/*
 * Function: AntennaOff
 * Description: Turn off antenna, every time turn on or shut down antenna need at least 1ms delay
 * Input parameter: null
 * Return: null
 */
void MFRC552_AntennaOff(void)
{
    MFRC552_ClearBitMask(TxControlReg, 0x03);
}


/*
 * Function: Reset
 * Description:  reset RC522
 * Input parameter: null
 * Return: null
 */
void MFRC552_Reset(void)
{
    MFRC552_WriteReg(CommandReg, PCD_RESETPHASE);
}


/*
 * Function: Init
 * Description: initilize RC522
 * Input parameter: null
 * Return: null
 */
void MFRC552_Init(void)
{
    GPIOPinWrite(NRSTPD_BASE, NRSTPD_PIN, NRSTPD_PIN);

    MFRC552_Reset();
         
    //Timer: TPrescaler*TreloadVal/6.78MHz = 24ms
    MFRC552_WriteReg(TModeReg, 0x8D);        //Tauto=1; f(Timer) = 6.78MHz/TPreScaler
    MFRC552_WriteReg(TPrescalerReg, 0x3E);    //TModeReg[3..0] + TPrescalerReg
    MFRC552_WriteReg(TReloadRegL, 30);
    MFRC552_WriteReg(TReloadRegH, 0);
    
    MFRC552_WriteReg(TxAutoReg, 0x40);        //100%ASK
    MFRC552_WriteReg(ModeReg, 0x3D);

    //ClearBitMask(Status2Reg, 0x08);        //MFCrypto1On=0
    //WriteReg(RxSelReg, 0x86);        //RxWait = RxSelReg[5..0]
    //WriteReg(RFCfgReg, 0x7F);           //RxGain = 48dB

    MFRC552_AntennaOn();
}


/*
 * Function: Request
 * Description: Searching card, read card type
 * Input parameter: reqMode--search methods:
 *             TagType--return card types
 *                 0x4400 = Mifare_UltraLight
 *                0x0400 = Mifare_One(S50)
 *                0x0200 = Mifare_One(S70)
 *                0x0800 = Mifare_Pro(X)
 *                0x4403 = Mifare_DESFire
 * return: return MI_OK if successed
 */
unsigned char MFRC552_Request(unsigned char reqMode, unsigned char *TagType)
{
    unsigned char status;  
    unsigned int backBits;

    MFRC552_WriteReg(BitFramingReg, 0x07);        //TxLastBists = BitFramingReg[2..0]    ???
    
    TagType[0] = reqMode;
    status = MFRC552_ToCard(PCD_TRANSCEIVE, TagType, 1, TagType, &backBits);

    if ((status != MI_OK) || (backBits != 0x10))
    {    
        status = MI_ERR;
    }
   
    return status;
}


/*
 * Function: ToCard
 * Description: communicate between RC522 and ISO14443
 * Input parameter: command--MF522 command bits
 *             sendData--send data to card via rc522
 *             sendLen--send data length        
 *             backData--the return data from card
 *             backLen--the length of return data
 * return: return MI_OK if successed
 */
unsigned char MFRC552_ToCard(unsigned char command, unsigned char *sendData, unsigned char sendLen, unsigned char *backData, unsigned int *backLen)
{
    unsigned char status = MI_ERR;
    unsigned char irqEn = 0x00;
    unsigned char waitIRq = 0x00;
    unsigned char lastBits;
    unsigned char n;
    unsigned int i;

    switch (command)
    {
        case PCD_AUTHENT:
        {
            irqEn = 0x12;
            waitIRq = 0x10;
            break;
        }
        case PCD_TRANSCEIVE:
        {
            irqEn = 0x77;
            waitIRq = 0x30;
            break;
        }
        default:
            break;
    }
   
    MFRC552_WriteReg(CommIEnReg, irqEn|0x80);
    MFRC552_ClearBitMask(CommIrqReg, 0x80);
    MFRC552_SetBitMask(FIFOLevelReg, 0x80);
    
    MFRC552_WriteReg(CommandReg, PCD_IDLE);

    for (i=0; i < sendLen; i++)
    {   
        MFRC552_WriteReg(FIFODataReg, sendData[i]);
    }

    MFRC552_WriteReg(CommandReg, command);
    if (command == PCD_TRANSCEIVE)
    {    
        MFRC552_SetBitMask(BitFramingReg, 0x80);        //StartSend=1,transmission of data starts
    }   

    i = 10000;
    do
    {
        n = MFRC552_ReadReg(CommIrqReg);
        i--;
    }
    while ((i!=0) && !(n&0x01) && !(n&waitIRq));

    MFRC552_ClearBitMask(BitFramingReg, 0x80);            //StartSend=0
    
    if (i != 0)
    {    
        if(!(MFRC552_ReadReg(ErrorReg) & 0x1B))    //BufferOvfl Collerr CRCErr ProtecolErr
        {
            status = MI_OK;
            if (n & irqEn & 0x01)
            {   
                status = MI_NOTAGERR;            //??   
            }

            if (command == PCD_TRANSCEIVE)
            {
                n = MFRC552_ReadReg(FIFOLevelReg);
                lastBits = MFRC552_ReadReg(ControlReg) & 0x07;
                if (lastBits)
                {   
                    *backLen = (n-1)*8 + lastBits;   
                }
                else
                {   
                    *backLen = n*8;   
                }
                if (n == 0)
                {   
                    n = 1;    
                }
                if (n > MAX_LEN)
                {   
                    n = MAX_LEN;   
                }
                
                for (i=0; i<n; i++)
                {   
                    backData[i] = MFRC552_ReadReg(FIFODataReg);
                }
            }
        }
        else
        {   
            status = MI_ERR;  
        }
    }
    
//SetBitMask(ControlReg,0x80);           //timer stops
//WriteReg(CommandReg, PCD_IDLE);

    return status;
}


/*
 * Function: MFRC522_Anticoll
 * Description: Prevent conflict, read the card serial number
 * Input parameter: serNum--return the 4 bytes card serial number, the 5th byte is recheck byte
 * return: return MI_OK if successed
 */
unsigned char MFRC552_Anticoll(unsigned char *serNum)
{
    unsigned char status;
    unsigned char i;
    unsigned char serNumCheck=0;
    unsigned int unLen;


//ClearBitMask(Status2Reg, 0x08);        //TempSensclear
//ClearBitMask(CollReg,0x80);            //ValuesAfterColl
    MFRC552_WriteReg(BitFramingReg, 0x00);        //TxLastBists = BitFramingReg[2..0]
    serNum[0] = PICC_ANTICOLL;
    serNum[1] = 0x20;
    status = MFRC552_ToCard(PCD_TRANSCEIVE, serNum, 2, serNum, &unLen);

    if (status == MI_OK)
    {
        for (i=0; i<4; i++)
        {   
            serNumCheck ^= serNum[i];
        }
        if (serNumCheck != serNum[i])
        {   
            status = MI_ERR;    
        }
    }

    //SetBitMask(CollReg, 0x80);        //ValuesAfterColl=1

    return status;
}


/*
 * Function: CalulateCRC
 * Description: Use MF522 to calculate CRC
 * Input parameter: pIndata--the CRC data need to be read,len--data length,pOutData-- the caculated result of CRC
 * return: Null
 */
void MFRC552_CalulateCRC(unsigned char *pIndata, unsigned char len, unsigned char *pOutData)
{
    unsigned char i, n;

    MFRC552_ClearBitMask(DivIrqReg, 0x04);            //CRCIrq = 0
    MFRC552_SetBitMask(FIFOLevelReg, 0x80);
    //WriteReg(CommandReg, PCD_IDLE);

    for (i=0; i<len; i++)
    {   
        MFRC552_WriteReg(FIFODataReg, *(pIndata+i));
    }
    MFRC552_WriteReg(CommandReg, PCD_CALCCRC);

    i = 0xFF;
    do
    {
        n = MFRC552_ReadReg(DivIrqReg);
        i--;
    }
    while ((i!=0) && !(n&0x04));            //CRCIrq = 1

    pOutData[0] = MFRC552_ReadReg(CRCResultRegL);
    pOutData[1] = MFRC552_ReadReg(CRCResultRegM);
}


/*
 * Function: SelectTag
 * Description: Select card, read card storage volume
 * Input parameter: serNum--Send card serial number
 * return: return the card storage volume
 */
unsigned char MFRC552_SelectTag(unsigned char *serNum)
{
    unsigned char i;
    unsigned char status;
    unsigned char size;
    unsigned int recvBits;
    unsigned char buffer[9];

    //ClearBitMask(Status2Reg, 0x08);            //MFCrypto1On=0

    buffer[0] = PICC_SElECTTAG;
    buffer[1] = 0x70;
    for (i=0; i<5; i++)
    {
        buffer[i+2] = *(serNum+i);
    }
    MFRC552_CalulateCRC(buffer, 7, &buffer[7]);        //??
    status = MFRC552_ToCard(PCD_TRANSCEIVE, buffer, 9, buffer, &recvBits);
    
    if ((status == MI_OK) && (recvBits == 0x18))
    {   
        size = buffer[0];
    }
    else
    {   
        size = 0;    
    }

    return size;
}


/*
 * Function: Auth
 * Description: verify card password
 * Input parameters: authMode--password verify mode
                 0x60 = verify A password key
                 0x61 = verify B password key
             BlockAddr--Block address
             Sectorkey--Block password
             serNum--Card serial number ,4 bytes
 * return: return MI_OK if successed
 */
unsigned char MFRC552_Auth(unsigned char authMode, unsigned char BlockAddr, unsigned char *Sectorkey, unsigned char *serNum)
{
    unsigned char status;
    unsigned int recvBits;
    unsigned char i;
    unsigned char buff[12];

    buff[0] = authMode;
    buff[1] = BlockAddr;
    for (i=0; i<6; i++)
    {
        buff[i+2] = *(Sectorkey+i);
    }
    for (i=0; i<4; i++)
    {
        buff[i+8] = *(serNum+i);
    }
    status = MFRC552_ToCard(PCD_AUTHENT, buff, 12, buff, &recvBits);

    if ((status != MI_OK) || (!(MFRC552_ReadReg(Status2Reg) & 0x08)))
    {
        status = MI_ERR;
    }
    
    return status;
}


/*
 * Function: ReadBlock
 * Description: Read data
 * Input parameters: blockAddr--block address;recvData--the block data which are read
 * return: return MI_OK if successed
 */
unsigned char MFRC552_ReadBlock(unsigned char blockAddr, unsigned char *recvData)
{
    unsigned char status;
    unsigned int unLen;

    recvData[0] = PICC_READ;
    recvData[1] = blockAddr;
    MFRC552_CalulateCRC(recvData,2, &recvData[2]);
    status = MFRC552_ToCard(PCD_TRANSCEIVE, recvData, 4, recvData, &unLen);

    if ((status != MI_OK) || (unLen != 0x90))
    {
        status = MI_ERR;
    }
    
    return status;
}


/*
 * Function: WriteBlock
 * Description: write block data
 * Input parameters: blockAddr--block address;writeData--Write 16 bytes data into block
 * return: return MI_OK if successed
 */
unsigned char MFRC552_WriteBlock(unsigned char blockAddr, unsigned char *writeData)
{
    unsigned char status;
    unsigned int recvBits;
    unsigned char i;
    unsigned char buff[18];
    
    buff[0] = PICC_WRITE;
    buff[1] = blockAddr;
    MFRC552_CalulateCRC(buff, 2, &buff[2]);
    status = MFRC552_ToCard(PCD_TRANSCEIVE, buff, 4, buff, &recvBits);

    if ((status != MI_OK) || (recvBits != 4) || ((buff[0] & 0x0F) != 0x0A))
    {   
        status = MI_ERR;   
    }

    if (status == MI_OK)
    {
        for (i=0; i<16; i++)
        {    
            buff[i] = *(writeData+i);   
        }
        MFRC552_CalulateCRC(buff, 16, &buff[16]);
        status = MFRC552_ToCard(PCD_TRANSCEIVE, buff, 18, buff, &recvBits);

        if ((status != MI_OK) || (recvBits != 4) || ((buff[0] & 0x0F) != 0x0A))
        {   
            status = MI_ERR;   
        }
    }
    
    return status;
}


/*
 * Function: Halt
 * Description: Command the cards into sleep mode
 * Input parameters: null
 * return: null
 */
void MFRC552_Halt(void)
{
    unsigned char status;
    unsigned int unLen;
    unsigned char buff[4];

    buff[0] = PICC_HALT;
    buff[1] = 0;
    MFRC552_CalulateCRC(buff, 2, &buff[2]);
 
    status = MFRC552_ToCard(PCD_TRANSCEIVE, buff, 4, buff, &unLen);
}

  • Hello Stephen,

    TI has our own NFC/RFID reader/writer devices, as such as we will not offer support for an NXP solution.

    If you want to read NFC/RFID tags, look into our TI design: www.ti.com/.../TIDM-TM4C129XNFC
  • Hello Stephen,

    Though you indicated my prior response did not resolve your issue, you offered no feedback regarding why, please clarify this or allow us to close this thread. Thank you.
  • You suggested me looking for TI products, but:
    1) I already have a RFID module. Why buying another instead using the one I have that is very popular?
    2) TI products (except the TM4C123GXL I have) are out of my budget (I live in Brazil. Taxes here for importing are not friendly), so buying is not a option for now.
    And I strongly believe my issue is with coding (moving the code from C++ to C), not exactly with the product itself.

    But I really thank you for your suggestion.

  • Hello Stephen,

    I am not saying the issue is with the product itself.

    However, please keep in mind that it also does not benefit us to help solve an issue that is centered on a competitors product that is in direct competition of our own devices.

    If the issue was related to TivaWare or the SPI functionality of the TM4C, we absolutely would offer support for that as those issues are specific to our device which is the TM4C MCU.

    However, what you are asking for is debugging the C library ported that handles communication for a competitors device and that query is no longer an issue specific to a TI device. That is the core of the issue here.
  • Well, I totally agree with this argument, and I guess there is nothing left to do. Thanks for your suport anyway, sir.