CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug Reports on this forum. Send them to support@ccsinfo.com

Using MFRC522 RFID Reader with PIC16F877

 
Post new topic   Reply to topic    CCS Forum Index -> Code Library
View previous topic :: View next topic  
Author Message
Mario_KA



Joined: 16 Nov 2017
Posts: 22

View user's profile Send private message

Using MFRC522 RFID Reader with PIC16F877
PostPosted: Thu Nov 30, 2017 6:51 am     Reply with quote

I managed to implement the MFRC522. The headerfile is based on https://github.com/ljos/MFRC522

main.c
Code:
#include <main.h>
#include <lcd16216.c>
#define CS PIN_A5
#use rs232( baud=9600, parity=N, xmit=PIN_C6, rcv=PIN_C7, bits=8, ERRORS)

//spi modes
#define SPI_MODE_0  (SPI_L_TO_H | SPI_XMIT_L_TO_H)
#define SPI_MODE_1  (SPI_L_TO_H)
#define SPI_MODE_2  (SPI_H_TO_L)
#define SPI_MODE_3  (SPI_H_TO_L | SPI_XMIT_L_TO_H)

byte FoundTag; // Variable used to check if Tag was found
byte ReadTag; // Variable used to store anti-collision value to read Tag information
byte TagData[16]; // Variable used to store Full Tag Data
byte GoodTagSerialNumber[4] = {0x9E, 0x80, 0xB1, 0x59}; // The Tag Serial number we are looking for
int i=0;
char buffer[20],buffer2[20],text[20];
byte version;
int GoodTag=0; // Variable used to confirm good Tag Detected

#include <mario_rfid.h>

void checktag()
{
   if (GoodTag == 1)
   {
      printf("Access granted\r\n");   
      GoodTag=0;
      delay_ms(500);
   }
   else
   {
      printf("Access Denied\r\n");   
      GoodTag=0;
      delay_ms(500);
   }
}
void readRFID()
{
    // Get anti-collision value to properly read information from the Tag
    ReadTag = antiCollision(TagData);
 
    printf("Tag detected.\r\n");
    printf("Serial Number: \r\n");
    text = "Tag Serial";
   
   for(i=0;i<=2;i++)
   {
    sprintf(buffer2,"%2X",(TagData[i])); //display version in hexadecimal
    delay_ms(20);
    printf(buffer2);
    printf(", ");
   }
    sprintf(buffer2,"%2X",(TagData[i])); //display version in hexadecimal
    delay_ms(20);
    printf(buffer2);
    printf("\r\nCheck Validity \r\n");
   
   for(int i=0; i <= 3; i++)
   {
    if (GoodTagSerialNumber[i] != TagData[i])
   {
    GoodTag=0;
    break; // if not equal, then break out of the "for" loop
   }
   }
   
   if (TagData[3]==GoodTagSerialNumber[3])
   {
   // if we made it to 4 loops then the Tag Serial numbers are matching
   GoodTag=1;
   }
}


void print(){
version = readFromRegister(VersionReg);

if(!version)
{
 
  text = "NO DEVICE";
  lcd_gotoxy(1, 1);//go to position 1,1 on lcd
   lcd_print(text);
 
}
if(version)
{
 
  text = "DEVICE found";
  lcd_gotoxy(1, 1);//go to position 1,1 on lcd
  lcd_print(text);//print on lcd
  sprintf(buffer,"%2X",(version)); //display version in hexadecimal
  lcd_gotoxy(1, 2); //go to second line of lcd
  lcd_print(buffer);
}
}

void main()
{
   setup_oscillator(OSC_8MHZ, 3);  //Adjust Oscillator for proper Serial Communication
   setup_spi(SPI_MASTER|SPI_MODE_0|SPI_CLK_DIV_16);
   lcd_init();
   lcd_clear();
   delay_ms(50);
   begin(); //initialize MFRC522
   print(); //print Firmwareverion on LCD
   
   while(TRUE)
   {
     //  Check to see if a Tag was detected
     // If yes, then the variable FoundTag will contain "MI_OK"
    FoundTag = requestTag(MF1_REQIDL, TagData);
    printf("Checking for Tag \r\n");
    delay_ms(2000);
   
   
     if (FoundTag == MI_OK)
     {
        readRFID();
        checktag();
        delay_ms(500);
     }
       
     else printf("No Tag found");
     
   }
}
         


RFID.h
Code:
#define     MAX_LEN               16        // Maximum length of an array. CHECK IF IT IS MAXIMUM LENGTH/SIZE OF FIFO!!!!!!!!!!!

//MF522 MFRC522 error codes.
#define     MI_OK                 0         // Everything A-OK.
#define     MI_NOTAGERR           1         // No tag error
#define     MI_ERR                2         // General error

//MF522 Command word
#define     MFRC522_IDLE          0x00      // NO action; Cancel the current command
#define     MFRC522_MEM           0x01      // Store 25 byte into the internal buffer.
#define     MFRC522_GENID         0x02      // Generates a 10 byte random ID number.
#define     MFRC522_CALCCRC       0x03      // CRC Calculate or selftest.
#define     MFRC522_TRANSMIT      0x04      // Transmit data
#define     MFRC522_NOCMDCH       0x07      // No command change.
#define     MFRC522_RECEIVE       0x08      // Receive Data
#define     MFRC522_TRANSCEIVE    0x0C      // Transmit and receive data,
#define     MFRC522_AUTHENT       0x0E      // Authentication Key
#define     MFRC522_SOFTRESET     0x0F      // Reset

//Mifare_One tag command word
#define     MF1_REQIDL            0x26      // find the antenna area does not enter hibernation
#define     MF1_REQALL            0x52      // find all the tags antenna area
#define     MF1_ANTICOLL          0x93      // anti-collision
#define     MF1_SELECTTAG         0x93      // election tag
#define     MF1_AUTHENT1A         0x60      // authentication key A
#define     MF1_AUTHENT1B         0x61      // authentication key B
#define     MF1_READ              0x30      // Read Block
#define     MF1_WRITE             0xA0      // write block
#define     MF1_DECREMENT         0xC0      // debit
#define     MF1_INCREMENT         0xC1      // recharge
#define     MF1_RESTORE           0xC2      // transfer block data to the buffer
#define     MF1_TRANSFER          0xB0      // save the data in the buffer
#define     MF1_HALT              0x50      // Sleep


//------------------ MFRC522 registers---------------
//Page 0:Command and Status
#define     Reserved00            0x00
#define     CommandReg            0x01
#define     CommIEnReg            0x02
#define     DivIEnReg             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
//-----------------------------------------------


//Reads the value at a register.
byte readFromRegister(byte addr) {
  byte val;
  output_low(CS);
  spi_write(((addr<<1)&0x7E) | 0x80);
  val =spi_read(0x00);
  output_high(CS);
  return val;
}

//writes Values to specified registers.
void writeToRegister(byte addr, byte val) {
  output_low(CS);

  //Address format: 0XXXXXX0
  spi_write((addr<<1)&0x7E);
  spi_write(val);

  output_high(CS);
}

//Mask to update registers
void setBitMask(byte addr, byte mask) {
  byte current;
  current = readFromRegister(addr);
  writeToRegister(addr, current | mask);
}

//remove bitmask  maybe not necessary
void clearBitMask(byte addr, byte mask) {
  byte current;
  current = readFromRegister(addr);
  writeToRegister(addr, current & (~mask));
}

//Initialize RFID Reader
//Does the setup for the MFRC522.
void reset() {
  writeToRegister(CommandReg, MFRC522_SOFTRESET);
}



void begin() {
  output_high(CS);

  reset();

  //Timer: TPrescaler*TreloadVal/6.78MHz = 24ms
 writeToRegister(TModeReg, 0x8D);   
  delay_ms(20);// Tauto=1; f(Timer) = 6.78MHz/TPreScaler
  writeToRegister(TPrescalerReg, 0x3E);  // TModeReg[3..0] + TPrescalerReg
  delay_ms(20);
  writeToRegister(TReloadRegL, 30);
  delay_ms(20);
  writeToRegister(TReloadRegH, 0);
  delay_ms(20);
  writeToRegister(TxAutoReg, 0x40);      // 100%ASK
  delay_ms(20);
  writeToRegister(ModeReg, 0x3D);        // CRC initial value 0x6363
  delay_ms(20);
 //writeToRegister(TxControlReg, 0x82);     
  delay_ms(20);
 setBitMask(TxControlReg, 0x03);        // Turn antenna on.
}

//Checking MFRC522 Firmwareversion
byte getFirmwareVersion() {
  byte response;
  response = readFromRegister(VersionReg);
  return response;
}


/**************************************************************************/
/*!

  @brief   Sends a command to a tag.

  @param   cmd     The command to the MFRC522 to send a command to the tag.
  @param   data    The data that is needed to complete the command.
  @param   dlen    The length of the data.
  @param   result  The result returned by the tag.
  @param   rlen    The number of valid bits in the resulting value.

  @returns Returns the status of the calculation.
           MI_ERR        if something went wrong,
           MI_NOTAGERR   if there was no tag to send the command to.
           MI_OK         if everything went OK.

 */
/**************************************************************************/

int commandTag(byte cmd, byte *data, int dlen, byte *result, int *rlen) {
  int status = MI_ERR;
  byte irqEn = 0x00;
  byte waitIRq = 0x00;
  byte lastBits, n;
  int i;

  switch (cmd) {
  case MFRC522_AUTHENT:
    irqEn = 0x12;
    waitIRq = 0x10;
    break;
  case MFRC522_TRANSCEIVE:
    irqEn = 0x77;
    waitIRq = 0x30;
    break;
  default:
    break;
  }

  writeToRegister(CommIEnReg, irqEn|0x80);    // interrupt request
  clearBitMask(CommIrqReg, 0x80);             // Clear all interrupt requests bits.
  setBitMask(FIFOLevelReg, 0x80);             // FlushBuffer=1, FIFO initialization.

  writeToRegister(CommandReg, MFRC522_IDLE);  // No action, cancel the current command.

  // Write to FIFO
  for (i=0; i < dlen; i++) {
    writeToRegister(FIFODataReg, data[i]);
  }

  // Execute the command.
  writeToRegister(CommandReg, cmd);
  if (cmd == MFRC522_TRANSCEIVE) {
    setBitMask(BitFramingReg, 0x80);  // StartSend=1, transmission of data starts
  }

  // Waiting for the command to complete so we can receive data.
  i = 25; // Max wait time is 25ms.
  do {
    delay_ms(1);
    // CommIRqReg[7..0]
    // Set1 TxIRq RxIRq IdleIRq HiAlerIRq LoAlertIRq ErrIRq TimerIRq
    n = readFromRegister(CommIrqReg);
    i--;
  } while ((i!=0) && !(n&0x01) && !(n&waitIRq));

  clearBitMask(BitFramingReg, 0x80);  // StartSend=0

  if (i != 0) { // Request did not time out.
    if(!(readFromRegister(ErrorReg) & 0x1D)) {  // BufferOvfl Collerr CRCErr ProtocolErr
      status = MI_OK;
      if (n & irqEn & 0x01) {
        status = MI_NOTAGERR;
      }

      if (cmd == MFRC522_TRANSCEIVE) {
        n = readFromRegister(FIFOLevelReg);
        lastBits = readFromRegister(ControlReg) & 0x07;
        if (lastBits) {
          *rlen = (n-1)*8 + lastBits;
        } else {
          *rlen = n*8;
        }

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

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

        // Reading the recieved data from FIFO.
        for (i=0; i<n; i++) {
          result[i] = readFromRegister(FIFODataReg);
        }
      }
    } else {
      status = MI_ERR;
    }
  }
  return status;
}


/**************************************************************************/
/*

  @brief   Checks to see if there is a tag in the vicinity.

  @param   mode  The mode we are requsting in.
  @param   type  If we find a tag, this will be the type of that tag.
                 0x4400 = Mifare_UltraLight
                 0x0400 = Mifare_One(S50)
                 0x0200 = Mifare_One(S70)
                 0x0800 = Mifare_Pro(X)
                 0x4403 = Mifare_DESFire

  @returns Returns the status of the request.
           MI_ERR        if something went wrong,
           MI_NOTAGERR   if there was no tag to send the command to.
           MI_OK         if everything went OK.

 */
/**************************************************************************/
int requestTag(byte mode, byte *data) {
  int status, len;
  writeToRegister(BitFramingReg, 0x07);  // TxLastBists = BitFramingReg[2..0]

  data[0] = mode;
  status = commandTag(MFRC522_TRANSCEIVE, data, 1, data, &len);

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

  return status;
}

/**************************************************************************/
/*!

  @brief   Handles collisions that might occur if there are multiple
           tags available.

  @param   serial  The serial nb of the tag.

  @returns Returns the status of the collision detection.
           MI_ERR        if something went wrong,
           MI_NOTAGERR   if there was no tag to send the command to.
           MI_OK         if everything went OK.

 */
/**************************************************************************/
int antiCollision(byte *serial) {
  int status, i, len;
  byte check = 0x00;

  writeToRegister(BitFramingReg, 0x00);  // TxLastBits = BitFramingReg[2..0]

  serial[0] = MF1_ANTICOLL;
  serial[1] = 0x20;
  status = commandTag(MFRC522_TRANSCEIVE, serial, 2, serial, &len);
  len = len / 8; // len is in bits, and we want each byte.
  if (status == MI_OK) {
    // The checksum of the tag is the ^ of all the values.
    for (i = 0; i < len-1; i++) {
      check ^= serial[i];
    }
    // The checksum should be the same as the one provided from the
    // tag (serial[4]).
    if (check != serial[i]) {
      status = MI_ERR;
    }
  }

  return status;
}

/**************************************************************************/
/*!

  @brief   Calculates the CRC value for some data that should be sent to
           a tag.

  @param   data    The data to calculate the value for.
  @param   len     The length of the data.
  @param   result  The result of the CRC calculation.

 */
/**************************************************************************/
void calculateCRC(byte *data, int len, byte *result) {
  int i;
  byte n;

  clearBitMask(DivIrqReg, 0x04);   // CRCIrq = 0
  setBitMask(FIFOLevelReg, 0x80);  // Clear the FIFO pointer

  //Writing data to the FIFO.
  for (i = 0; i < len; i++) {
    writeToRegister(FIFODataReg, data[i]);
  }
  writeToRegister(CommandReg, MFRC522_CALCCRC);

  // Wait for the CRC calculation to complete.
  i = 0xFF;
  do {
    n = readFromRegister(DivIrqReg);
    i--;
  } while ((i != 0) && !(n & 0x04));  //CRCIrq = 1

  // Read the result from the CRC calculation.
  result[0] = readFromRegister(CRCResultRegL);
  result[1] = readFromRegister(CRCResultRegM);
}


The Code is ready to use. You can just read RFID Tags/Serialnumbers.
To write Tags you have to edit/add some more functions from LJOS Library.
merhuman



Joined: 10 Dec 2017
Posts: 2

View user's profile Send private message

PostPosted: Thu Dec 21, 2017 1:18 pm     Reply with quote

Hi Mario_KA, Im currently doing a project similar to yours. However, i use pic16f877a and feed it with 5v power source and crystal is 8Mhz. Yes, i also use lm1117 3.3v to down the voltage from 5v to 3.3v for supplying the mfrc522. I connect my pic and mfrc522 like this:

PIN_C5 (pin 24) -- MOSI
PIN_C4 (pin 25) -- MISO
PIN_C3 (pin 18) -- SCK
PIN_E2 (pin 10) -- SS
PIN_E0 (pin 8) -- RST

I tried to port the arduino code to c file too, but i didnt work. I also tried your code but the result still the same. The SPI communication between pic and mfrc522 is fine, but when it comes to transfer data to PICC tag the result is not so good.
Also im using ccs c 5.015. Really need some help about this. Thanks
PCM programmer



Joined: 06 Sep 2003
Posts: 20137

View user's profile Send private message

PostPosted: Thu Dec 21, 2017 7:14 pm     Reply with quote

Are you using the PDIP-40 package for the 16F877A ? Probably.

You have MISO connected to the wrong pin on the PIC. MISO should
connect to pin RC4/SDI/SDA, which is on pin 23 of the PDIP-40 package
as shown below:
merhuman wrote:

I connect my pic and mfrc522 like this:

PIN_C5 (pin 24) -- MOSI
PIN_C4 (pin 25) -- MISO <-- Should be pin 23 on the PIC
PIN_C3 (pin 18) -- SCK
PIN_E2 (pin 10) -- SS
PIN_E0 (pin 8) -- RST

merhuman



Joined: 10 Dec 2017
Posts: 2

View user's profile Send private message

PostPosted: Fri Dec 22, 2017 1:20 am     Reply with quote

Hi PCM programmer. Yes, you are right. I mistyped the number 25. It's pin 23 on my hardware tho Smile . Sorry, i was exhausted.

But as i mentioned before, the write and read work fine. Here is the code i use

main.h
Code:

#include <16F877A.h>
#device ADC=16

#include <stdlib.h>

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES NOBROWNOUT         //No brownout reset
#FUSES NOLVP                     //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O

#use delay(crystal = 8000000)
#use spi(MASTER, SPI1, BAUD = 9600, MODE=0, BITS=8, STREAM=XFER)


#use standard_io(B)
#use standard_io(C)
#use standard_io(D)
#use standard_io(E)

//*******************header of RFID********************

#define SSLOW (output_low(PIN_E2))
#define SSHIGH (output_high(PIN_E2))
#define RSTLOW (output_low(PIN_E0))
#define RSTHIGH (output_high(PIN_E0))

//PCD_Register
//Page 0: Command and status
#define CommandReg         0x01  // starts and stops command execution
#define ComIEnReg          0x02  // enable and disable interrupt request control bits
#define DivIEnReg          0x03  // enable and disable interrupt request control bits
#define ComIrqReg          0x04  // interrupt request bits
#define DivIrqReg          0x05  // interrupt request bits
#define ErrorReg           0x06  // error bits showing the error status of the last command executed
#define Status1Reg         0x07  // communication status bits 
#define Status2Reg         0x08  // receiver and transmitter status bits
#define FIFODataReg        0x09  // input and output of 64 byte FIFO buffer
#define FIFOLevelReg       0x0a  // number of bytes stored in the FIFO buffer
#define WaterLevelReg      0x0b  // level for FIFO underflow and overflow warning
#define ControlReg         0x0c  // miscellaneous control registers
#define BitFramingReg      0x0d  // adjustments for bit-oriented frames
#define CollReg            0x0e  // bit position of the first bit-collision detected on the RF interface

//Page 1: Command
#define ModeReg            0x11  // defines general modes for transmitting and receiving
#define TxModeReg          0x12  // defines transmission data rate and framing
#define RxModeReg          0x13  // defines reception data rate and framing
#define TxControlReg       0x14  // controls the logical behavior of the antenna driver pins TX1 and TX2
#define TxASKReg           0x15  // controls the setting of the transmission modulation
#define TxSelReg           0x16  // selects the internal sources for the antenna driver
#define RxSelReg           0x17  // selects internal receiver settings
#define RxThresholdReg     0x18  // selects thresholds for the bit decoder
#define DemodReg           0x19  // defines demodulator settings
#define MfTxReg            0x1c  // controls some MIFARE communication transmit parameters
#define MfRxReg            0x1d  // controls some MIFARE communication receive parameters
#define SerialSpeedReg     0x1f  // selects the speed of the serial UART interface

//Page 2: Configuration
#define CRCResultRegH      0x21  // shows the MSB and LSB values of the CRC calculation 
#define CRCResultRegL      0x22 
#define ModWidthReg        0x24  // controls the ModWidth setting?
#define RFCfgReg           0x26  // configures the receiver gain
#define GsNReg             0x27  // selects the conductance of the antenna driver pins TX1 and TX2 for modulation
#define CWGsPReg           0x28  // defines the conductance of the p-driver output during periods of no modulation
#define ModeGsPReg         0x29  // defines the conductance of the p-driver output during periods of modulation
#define TModeReg           0x2a  // defines settings for the internal timer 
#define TPrescalerReg      0x2b  // the lower 8 bits of the TPrescaler value. The 4 high bits are in TModeReg.
#define TReloadRegH        0x2c  // defines the 16-bit timer reload value
#define TReloadRegL        0x2d
#define TCounterValueRegH  0x2e  // shows the 16-bit timer value
#define TCounterValueRegL  0x2f

//Commands
#define PCD_Idle              0x00  // no action, cancels current command execution
#define PCD_Mem               0x01  // stores 25 bytes into the internal buffer
#define PCD_GenerateRandomID  0x02  // generates a 10-byte random ID number
#define PCD_CalcCRC           0x03  // activates the CRC coprocessor or performs a self-test
#define PCD_Transmit          0x04  // transmits data from the FIFO buffer
#define PCD_NoCmdChange       0x07  // no command change, can be used to modify the CommandReg register bits without affecting the command, for example, the PowerDown bit
#define PCD_Receive           0x08  // activates the receiver circuits
#define PCD_Transceive        0x0c  // transmits data from FIFO buffer to antenna and automatically activates the receiver after transmission
#define PCD_MFAuthent         0x0e  // performs the MIFARE standard authentication as a reader
#define PCD_SoftReset         0x0f  // resets the MFRC522

///Mifare_One tag command word
#define     MF1_REQIDL            0x26      // find the antenna area does not enter hibernation
#define     MF1_REQALL            0x52      // find all the tags antenna area
#define     MF1_ANTICOLL          0x93      // anti-collision
#define     MF1_SELECTTAG         0x93      // election tag
#define     MF1_AUTHENT1A         0x60      // authentication key A
#define     MF1_AUTHENT1B         0x61      // authentication key B
#define     MF1_READ              0x30      // Read Block
#define     MF1_WRITE             0xA0      // write block
#define     MF1_DECREMENT         0xC0      // debit
#define     MF1_INCREMENT         0xC1      // recharge
#define     MF1_RESTORE           0xC2      // transfer block data to the buffer
#define     MF1_TRANSFER          0xB0      // save the data in the buffer
#define     MF1_HALT              0x50      // Sleep

//Status code

#define MI_OK                    0
#define MI_NOTAGERR              1
#define MI_ERR                   2

#define MAX_LEN                  16



and here is the main.c
Code:

void main()
{
   
   spi_init(XFER, TRUE);
   delay_ms(100);
   LCD_Init();
   LCD_PutCmd(0x01);
   LCD_PutCmd(0x80);
   RSTHIGH;                   // set rst pin of mfrc522 high
   PCD_Init();
   infoVersion();
   
   while(TRUE)
   {
      //TODO: User Code
      FoundTag = requestTag(MF1_REQIDL, TagData);
      LCD_PutCmd(0x01);
      LCD_PutCmd(0x80);
      delay_ms(2000);
      if(FoundTag == MI_OK)
      {
         LCD_PutChar("tag found");
      }
      else
      {
         LCD_PutChar("no tag found");
      }
   }

}


//******** RFID function ***********
//Read from register
unsigned int8 PCD_RdReg(unsigned int8 reg)
{
   unsigned int8 address;
   unsigned int8 value = 0;
   SSLOW;
   delay_us(20);
   address = ((reg << 1) & 0x7e) | 0x80;
   spi_xfer(XFER, address);
   value = spi_xfer(XFER, 0x00);
   delay_us(20);
   SSHIGH;
   return value;
}


//Write to register
void PCD_WrReg(unsigned int8 reg, unsigned int8 value)
{
   unsigned int8 address;
   SSLOW;
   delay_us(20);
   address = ((reg << 1) & 0x7e);
   spi_xfer(XFER, address);
   spi_xfer(XFER, value);
   delay_us(20);
   SSHIGH;
}

//Initialize the mfrc522 chip
void PCD_Init(void)
{
   PCD_HReset();
   delay_ms(50);
   PCD_Reset();
   //PCD_WrReg(TxModeReg, 0x00);
   //PCD_WrReg(RxModeReg, 0x00);
   //PCD_WrReg(ModWidthReg, 0x26);
   PCD_WrReg(TModeReg, 0x8D);
   PCD_WrReg(TPrescalerReg, 0x3e);
   PCD_WrReg(TReloadRegH, 0x00);
   PCD_WrReg(TReloadRegL, 0x30);
   PCD_WrReg(TxASKReg, 0x40);
   PCD_WrReg(ModeReg, 0x3d);
   PCD_AntennaOn();
}

unsigned int8 getFirmwareVersion(void)
{
   unsigned int8 response = PCD_RdReg(VersionReg);
   return response;
}

int commandTag(byte cmd, byte *data, int dlen, byte *result, int *rlen)
{
   int status = MI_ERR;
   byte irqEn = 0x00;
   byte waitIRq = 0x00;
   byte lastBits, n;
   int j;
   
   switch (cmd)
   {
      case PCD_MFAuthent:
         irqEn = 0x12;
         waitIRq = 0x10;
         break;
         
      case PCD_Transceive:
         irqEn = 0x77;
         waitIRq = 0x30;
         break;
         
      default:
         break;
   }
   PCD_WrReg(ComIEnReg, irqEn|0x80);    // interrupt request
   PCD_ClrBitMsk(ComIrqReg, 0x80);             // Clear all interrupt requests bits.
   PCD_SetBitMsk(FIFOLevelReg, 0x80);             // FlushBuffer=1, FIFO initialization.

   PCD_WrReg(CommandReg, PCD_Idle);  // No action, cancel the current command.

   // Write to FIFO
   for (j=0; j < dlen; j++)
   {
      PCD_WrReg(FIFODataReg, data[j]);
   }

   // Execute the command.
   PCD_WrReg(CommandReg, cmd);
   if (cmd == PCD_Transceive)
   {
      PCD_SetBitMsk(BitFramingReg, 0x80);  // StartSend=1, transmission of data starts
   }

   // Waiting for the command to complete so we can receive data.
   j = 25; // Max wait time is 25ms.
   do {
      delay_ms(1);
      // CommIRqReg[7..0]
      // Set1 TxIRq RxIRq IdleIRq HiAlerIRq LoAlertIRq ErrIRq TimerIRq
      n = PCD_RdReg(ComIrqReg);
      j--;
   } while ((j!=0) && !(n&0x01) && !(n&waitIRq));

   PCD_ClrBitMsk(BitFramingReg, 0x80);  // StartSend=0

   if (j != 0)
   { // Request did not time out.
      if(!(PCD_RdReg(ErrorReg) & 0x1D))
      {  // BufferOvfl Collerr CRCErr ProtocolErr
         status = MI_OK;
         if (n & irqEn & 0x01)
         {
            status = MI_NOTAGERR;
         }

         if (cmd == PCD_Transceive)
         {
            n = PCD_RdReg(FIFOLevelReg);
            lastBits = PCD_RdReg(ControlReg) & 0x07;
            if (lastBits)
            {
               *rlen = (n-1)*8 + lastBits;
            }
            else
            {
               *rlen = n*8;
            }

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

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

            // Reading the recieved data from FIFO.
            for (j=0; j<n; j++)
            {
               result[j] = PCD_RdReg(FIFODataReg);
            }
         }
      }
      else
      {
         status = MI_ERR;
      }
  }
  return status;
}

int requestTag(byte mode, byte *data)
{
   int status, len;
   PCD_WrReg(BitFramingReg, 0x07);
   data[0] = mode;
   status = commandTag(PCD_Transceive, data, 1, data, &len);
   if((status != MI_OK) || (len != 0x10))
   {
      status = MI_ERR;
   }
   return status;
}

int antiCollision(byte *serial)
{
   int status, i, len;
   byte check = 0x00;
   PCD_WrReg(BitFramingReg, 0x00);
   serial[0] = MF1_ANTICOLL;
   serial[1] = 0x20;
   status = commandTag(PCD_Transceive, serial, 2, serial, &len);
   len = len / 8;
   if (status == MI_OK)
   {
      for(i = 0; i < len-1; i++)
      {
         check ^= serial[i];
      }
      if(check != serial[i])
      {
         status = MI_ERR;
      }
   }
   return status;
}

void calculateCRC(byte *data, int len, byte *result)
{
   int i;
   byte n;
   PCD_ClrBitMsk(DivIrqReg, 0x04);
   PCD_SetBitMsk(FIFOLevelReg, 0x80);
   
   for(i = 0; i < len; i++)
   {
      PCD_WrReg(FIFODataReg, data[i]);
   }
   PCD_WrReg(CommandReg, PCD_CalcCRC);
   
   i = 0xff;
   do{
      n = PCD_RdReg(DivIrqReg);
      i--;
   }while((i != 0) && !(n & 0x04));
   result[0] = PCD_RdReg(CRCResultRegL);
   result[1] = PCD_RdReg(CRCResultRegH);
}

////////////////////////////////////
void PCD_ClrBitMsk(char reg, char mask)
{
   unsigned int8 tmp = 0x00;
   tmp = PCD_RdReg(reg);
   PCD_WrReg(reg, tmp&(~mask));
}

///////////////////////////////////
void PCD_SetBitMsk(char reg, char mask)
{
   unsigned int8 tmp = 0x00;
   PCD_WrReg(reg, tmp|mask);
}

//Soft Reset
void PCD_Reset(void)
{
   PCD_WrReg(CommandReg,PCD_SoftReset);
   delay_ms(50);
   while(PCD_RdReg(CommandReg) & (1<<4));
}

//Hard Reset
void PCD_HReset(void)
{
   RSTHIGH;
   delay_us(1);
   RSTLOW;
   delay_us(1);
   RSTHIGH;
   delay_us(1);
}

//Turn the antenna on
void PCD_AntennaOn(void)
{
   unsigned int8 value = PCD_RdReg(TxControlReg);
   if((value & 0x03) != 0x03)
   {
      PCD_WrReg(TxControlReg, value | 0x03);
   }
}

//Turn the antenna off
void PCD_AntennaOff(void)
{
   PCD_ClrBitMsk(TxControlReg, 0x03);
}

void infoVersion(void)
{
   version = PCD_RdReg(VersionReg);
   if(!version)
   {
      LCD_PutChar("no device");
   }
   else
   {
      LCD_PutChar("device found");
      LCD_PutCmd(0xc0);
      LCD_Check(version);
   }
}


Most of the code is similar to Mario_KA's code. Just the name of the registers and commands are a little bit different because of the ported code from arduino i have made from last month.

I stuck at requestTag(), it just return MI_ERR all the time. Is it because of the transmission time? I'm trying to figure it out by reading the references:

an10833 https://www.nxp.com/docs/en/application-note/AN10833.pdf

an10834https://www.nxp.com/docs/en/application-note/AN10834.pdf

an10927https://www.nxp.com/docs/en/application-note/AN10927.pdf

But still haven't figure it out.
PCM programmer



Joined: 06 Sep 2003
Posts: 20137

View user's profile Send private message

PostPosted: Fri Dec 22, 2017 2:36 am     Reply with quote

I suggest that you post your problem in the main forum so everyone can
look at it. Most things don't get solved in the Code Library. They may
get solved in the main forum:
http://www.ccsinfo.com/forum/viewforum.php?f=1

Also, I suggest that you read this 4-page thread. Mario_KA's questions
start on page 2.
http://www.ccsinfo.com/forum/viewtopic.php?t=51393


merhuman wrote:

I use pic16f877a and feed it with 5v power source and crystal is
8Mhz. Yes, i also use lm1117 3.3v to down the voltage from 5v to 3.3v
for supplying the mfrc522
.

They are not going to like it when they find out you are running the
MFRC522 at 3.3v and the PIC at 5v. Read the thread in the link above,
starting at page 1. They discuss this issue.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> Code Library All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group