RFID MFRC522 with PIC18

OP #6541239
Rate this post
• ▲ useful
▼ not useful
Hello everyone.

I'm having trouble reading MIFARE cards using the MFRC522 module.
I know where the problem is, but I don't know how to fix it.
I am able to communicate with the module via SPI. When I call the 
function to identify if there is a card, it transmits the 0x26 byte to 
the antenna and waits to receive a byte from the card. However, she is 
not receiving anything, even with the card next to the antenna.

attached is the code for a part of the main. I didn't put the 
configuration pins, because I think everything is ok

Code:
1
 MFRC522_Init();
2

3

4
    /*--------------- Loop embarcado ---------------*/
5
    while (1)
6
    {
7

8

9
        UART_Write(0x11);
10
        {
11
        if( MFRC522_isCard( TagType ) )
12
            UART_Write(0xCC);
13
           
14
            if( MFRC522_ReadCardSerial( &UID ) )
15
            { 
16
               
17
                //sprintf(texto,"%lu",codigo_rfid);// lo pasa a unsigned long
18
                           
19
                //LongIntToHex(codigo_rfid,texto);
20
                   
21
               
22
                UART_Write(0xAA);
23
               
24
            }
25
        }



attached is the library code:
(the problem is in the MFRC522_ToCard function. After executing the 
command, it loops, counting 25 ms, waiting for a bit from the COMMIRQREG 
register to be set, indicating that a data has been received.
But even with the card, it receives nothing (the loop ends without 
setting the bit in the register))


Code:
1
//conecci�n de modulo RFID   usando SPI pot software
2

3
#include "SPI-Flash.h"
4

5
//MF522 Command word
6
#define PCD_IDLE              0x00               //NO action; Cancel the current command
7
#define PCD_AUTHENT           0x0E               //Authentication Key
8
#define PCD_RECEIVE           0x08               //Receive Data
9
#define PCD_TRANSMIT          0x04               //Transmit data
10
#define PCD_TRANSCEIVE        0x0C               //Transmit and receive data,
11
#define PCD_RESETPHASE        0x0F               //Reset
12
#define PCD_CALCCRC           0x03               //CRC Calculate
13

14
// Mifare_One card command word
15
#define PICC_REQIDL          0x26               // find the antenna area does not enter hibernation
16
#define PICC_REQALL          0x52               // find all the cards antenna area
17
#define PICC_ANTICOLL        0x93               // anti-collision
18
#define PICC_SElECTTAG       0x93               // election card
19
#define PICC_AUTHENT1A       0x60               // authentication key A
20
#define PICC_AUTHENT1B       0x61               // authentication key B
21
#define PICC_READ            0x30               // Read Block
22
#define PICC_WRITE           0xA0               // write block
23
#define PICC_DECREMENT       0xC0               // debit
24
#define PICC_INCREMENT       0xC1               // recharge
25
#define PICC_RESTORE         0xC2               // transfer block data to the buffer
26
#define PICC_TRANSFER        0xB0               // save the data in the buffer
27
#define PICC_HALT            0x50               // Sleep
28
//And MF522 The error code is returned when communication
29
#define MI_OK                 0
30
#define MI_NOTAGERR           1
31
#define MI_ERR                2
32
//------------------MFRC522 Register---------------
33
//Page 0:Command and Status
34
#define     RESERVED00            0x00
35
#define     COMMANDREG            0x01
36
#define     COMMIENREG            0x02
37
#define     DIVLENREG             0x03
38
#define     COMMIRQREG            0x04
39
#define     DIVIRQREG             0x05
40
#define     ERRORREG              0x06
41
#define     STATUS1REG            0x07
42
#define     STATUS2REG            0x08
43
#define     FIFODATAREG           0x09
44
#define     FIFOLEVELREG          0x0A
45
#define     WATERLEVELREG         0x0B
46
#define     CONTROLREG            0x0C
47
#define     BITFRAMINGREG         0x0D
48
#define     COLLREG               0x0E
49
#define     RESERVED01            0x0F
50
//PAGE 1:Command
51
#define     RESERVED10            0x10
52
#define     MODEREG               0x11
53
#define     TXMODEREG             0x12
54
#define     RXMODEREG             0x13
55
#define     TXCONTROLREG          0x14
56
#define     TXAUTOREG             0x15
57
#define     TXSELREG              0x16
58
#define     RXSELREG              0x17
59
#define     RXTHRESHOLDREG        0x18
60
#define     DEMODREG              0x19
61
#define     RESERVED11            0x1A
62
#define     RESERVED12            0x1B
63
#define     MIFAREREG             0x1C
64
#define     RESERVED13            0x1D
65
#define     RESERVED14            0x1E
66
#define     SERIALSPEEDREG        0x1F
67
//PAGE 2:CFG
68
#define     RESERVED20            0x20
69
#define     CRCRESULTREGM         0x21
70
#define     CRCRESULTREGL         0x22
71
#define     RESERVED21            0x23
72
#define     MODWIDTHREG           0x24
73
#define     RESERVED22            0x25
74
#define     RFCFGREG              0x26
75
#define     GSNREG                0x27
76
#define     CWGSPREG              0x28
77
#define     MODGSPREG             0x29
78
#define     TMODEREG              0x2A
79
#define     TPRESCALERREG         0x2B
80
#define     TRELOADREGH           0x2C
81
#define     TRELOADREGL           0x2D
82
#define     TCOUNTERVALUEREGH     0x2E
83
#define     TCOUNTERVALUEREGL     0x2F
84
//PAGE 3:TEST REGISTER
85
#define     RESERVED30            0x30
86
#define     TESTSEL1REG           0x31
87
#define     TESTSEL2REG           0x32
88
#define     TESTPINENREG          0x33
89
#define     TESTPINVALUEREG       0x34
90
#define     TESTBUSREG            0x35
91
#define     AUTOTESTREG           0x36
92
#define     VERSIONREG            0x37
93
#define     ANALOGTESTREG         0x38
94
#define     TESTDAC1REG           0x39
95
#define     TESTDAC2REG           0x3A
96
#define     TESTADCREG            0x3B
97
#define     RESERVED31            0x3C
98
#define     RESERVED32            0x3D
99
#define     RESERVED33            0x3E
100
#define     RESERVED34            0x3F
101
static void MFRC522_Wr( char addr, char value )
102
{
103
        MFRC522_CS = 0;
104
        SPI_Write( ( addr << 1 ) & 0x7E );
105
        SPI_Write( value );
106
        MFRC522_CS = 1;
107
}
108
static uint8_t MFRC522_Rd( char addr )
109
{
110
        uint8_t value;
111
        MFRC522_CS = 0;
112
        SPI_Write( (( addr << 1 ) & 0x7E) | 0x80 );
113
        value = SPI_Read();
114
        MFRC522_CS = 1;
115
        return value;
116
}
117
static void MFRC522_Clear_Bit( char addr, char mask )
118
{
119
     MFRC522_Wr( addr, MFRC522_Rd( addr ) & (~mask) );
120
}
121
static void MFRC522_Set_Bit( char addr, char mask )
122
{
123
     MFRC522_Wr( addr, MFRC522_Rd( addr ) | mask );
124
}
125
void MFRC522_Reset()
126
{
127
        MFRC522_Wr( COMMANDREG, PCD_RESETPHASE );
128
}
129
void MFRC522_AntennaOn()
130
{
131
 MFRC522_Set_Bit( TXCONTROLREG, 0x03 );
132
}
133
void MFRC522_AntennaOff()
134
{
135
 MFRC522_Clear_Bit( TXCONTROLREG, 0x03 );
136
}
137
void MFRC522_Init()
138
{
139
     MFRC522_CS_Direction = 0;
140
     MFRC522_Rst_Direction = 0;
141
     MFRC522_CS = 1;
142
     MFRC522_Rst = 1;
143

144
     MFRC522_Reset();
145

146
     MFRC522_Wr( TMODEREG, 0x8D );      //Tauto=1; f(Timer) = 6.78MHz/TPreScaler
147
     MFRC522_Wr( TPRESCALERREG, 0x3E ); //TModeReg[3..0] + TPrescalerReg
148
     MFRC522_Wr( TRELOADREGL, 30 );
149
     MFRC522_Wr( TRELOADREGH, 0 );
150
     MFRC522_Wr( TXAUTOREG, 0x40 );
151
     MFRC522_Wr( MODEREG, 0x3D );
152

153
    //  MFRC522_Wr( TMODEREG, 0x8D );      //Tauto=1; f(Timer) = 6.78MHz/TPreScaler
154
    //  MFRC522_Wr( TPRESCALERREG, 0x3E ); //TModeReg[3..0] + TPrescalerReg
155
    //  MFRC522_Wr( TRELOADREGL, 30 );
156
    //  MFRC522_Wr( TRELOADREGH, 0 );
157

158
     
159

160
    //  MFRC522_Wr( TXAUTOREG, 0x40 );    //100%ASK
161
    //  MFRC522_Wr( MODEREG, 0x3D );      // CRC valor inicial de 0x6363
162

163
     //MFRC522_Clear_Bit( STATUS2REG, 0x08 );//MFCrypto1On=0
164
     //MFRC522_Wr( RXSELREG, 0x86 );      //RxWait = RxSelReg[5..0]
165
     //MFRC522_Wr( RFCFGREG, 0x7F );     //RxGain = 48dB
166
    UART_Write(0x99);
167
     MFRC522_AntennaOn();
168
    MFRC522_Wr( RFCFGREG, 0x50 );
169

170
}
171
char MFRC522_ToCard( char command, char *sendData, char sendLen, char *backData, unsigned *backLen )
172
{
173
  char _status = MI_ERR;
174
  char irqEn = 0x00;
175
  char waitIRq = 0x00;
176
  char lastBits;
177
  char n;
178
  unsigned i;
179

180
  switch (command)
181
  {
182
    case PCD_AUTHENT:       //Certification cards close
183
    {
184
      irqEn = 0x12;
185
      waitIRq = 0x10;
186
      break;
187
    }
188
    case PCD_TRANSCEIVE:    //Transmit FIFO data
189
    {
190
      irqEn = 0x77;
191
      waitIRq = 0x30;
192
      break;
193
    }
194
    default:
195
      break;
196
  }
197
  MFRC522_Wr( COMMIENREG, irqEn | 0x80 );
198
  MFRC522_Clear_Bit( COMMIRQREG, 0x80 );
199
  MFRC522_Set_Bit( FIFOLEVELREG, 0x80 );
200
  MFRC522_Wr( COMMANDREG, PCD_IDLE );
201

202

203
  //Writing data to the FIFO
204
  for ( i=0; i < sendLen; i++ )
205
  {
206
    MFRC522_Wr( FIFODATAREG, sendData[i] );
207
  }
208
 
209

210
  //Execute the command
211
  MFRC522_Wr( COMMANDREG, command );
212
  if (command == PCD_TRANSCEIVE )
213
  {
214
    MFRC522_Set_Bit( BITFRAMINGREG, 0x80 ); //StartSend=1,transmission of data starts
215
  }
216
    //UART_Write(MFRC522_Rd(FIFODATAREG));
217

218
  //Waiting to receive data to complete
219
  //i according to the clock frequency adjustment, the operator M1 card maximum waiting time 25ms???
220
 
221
  i = 25;
222

223
  do
224
  {
225
    __delay_ms(1);
226
    //CommIrqReg[7..0]
227
    //Set1 TxIRq RxIRq IdleIRq HiAlerIRq LoAlertIRq ErrIRq TimerIRq
228
   
229
    n = MFRC522_Rd( COMMIRQREG );
230
    i--;
231
         
232

233
  }
234
  while ( i && !(n & 0x01) && !( n & waitIRq ) );
235
  MFRC522_Clear_Bit( BITFRAMINGREG, 0x80 );    //StartSend=0
236
   
237

238

239
  UART_Write(MFRC522_Rd(RFCFGREG));
240
 UART_Write(0x78);
241
  UART_Write(MFRC522_Rd(STATUS2REG));
242
  UART_Write(0x22);
243
  UART_Write(i);
244
  UART_Write(0x33);
245
  UART_Write(n);
246
  if (i != 0)
247
  {
248
    if (!(MFRC522_Rd(ERRORREG) & 0x1B)) //BufferOvfl Collerr CRCErr ProtecolErr
249
    {
250
      _status = MI_OK;
251
      if (n & irqEn & 0x01)
252
      {
253
        _status = MI_NOTAGERR; //??
254
      }
255
      if (command == PCD_TRANSCEIVE)
256
      {
257

258
        n = MFRC522_Rd(FIFOLEVELREG);
259

260
        lastBits = MFRC522_Rd(CONTROLREG) & 0x07;
261
        if (lastBits)
262
        {
263
          *backLen = (n - 1) * 8 + lastBits;
264
        }
265
        else
266
        {
267
          *backLen = n * 8;
268
        }
269
        if (n == 0)
270
        {
271
          n = 1;
272
        }
273
        if (n > 16)
274
        {
275
          n = 16;
276
        }
277
        //Reading the received data in FIFO
278
        for (i = 0; i < n; i++)
279
        {
280
          backData[i] = MFRC522_Rd(FIFODATAREG);
281
        }
282

283
        backData[i] = 0;
284
      }
285
    }
286
    else
287
    {
288
      _status = MI_ERR;
289
    }
290
  }
291
  //MFRC522_Set_Bit( CONTROLREG, 0x80 );
292
  //MFRC522_Wr( COMMANDREG, PCD_IDLE );
293
  return _status;
294
}
295
char MFRC522_Request(char reqMode, char *TagType)
296
{
297

298
  char _status;
299
  unsigned backBits; //The received data bits
300

301
  MFRC522_Wr(BITFRAMINGREG, 0x07); //TxLastBists = BitFramingReg[2..0]   ???
302

303
  TagType[0] = reqMode;
304
  _status = MFRC522_ToCard(PCD_TRANSCEIVE, TagType, 1, TagType, &backBits);
305
  if ((_status != MI_OK) || (backBits != 0x10))
306
  {
307
    _status = MI_ERR;
308
  }
309
  return _status;
310
}
311
void MFRC522_CRC(char *dataIn, char length, char *dataOut)
312
{
313
  char i, n;
314
  MFRC522_Clear_Bit(DIVIRQREG, 0x04);
315
  MFRC522_Set_Bit(FIFOLEVELREG, 0x80);
316

317
  //Escreve dados no FIFO
318
  for (i = 0; i < length; i++)
319
  {
320
    MFRC522_Wr(FIFODATAREG, *dataIn++);
321
  }
322

323
  MFRC522_Wr(COMMANDREG, PCD_CALCCRC);
324

325
  i = 0xFF;
326
  //Espera a finaliza��o do Calculo do CRC
327
  do
328
  {
329
    n = MFRC522_Rd(DIVIRQREG);
330
    i--;
331
  } while (i && !(n & 0x04)); //CRCIrq = 1
332

333
  dataOut[0] = MFRC522_Rd(CRCRESULTREGL);
334
  dataOut[1] = MFRC522_Rd(CRCRESULTREGM);
335
}
336
char MFRC522_SelectTag(char *serNum)
337
{
338
  char i;
339
  char _status;
340
  char size;
341
  unsigned recvBits;
342
  char buffer[9];
343

344
  //MFRC522_Clear_Bit( STATUS2REG, 0x08 );   //MFCrypto1On=0
345

346
  buffer[0] = PICC_SElECTTAG;
347
  buffer[1] = 0x70;
348

349
  for (i = 2; i < 7; i++)
350
  {
351
    buffer[i] = *serNum++;
352
  }
353

354
  MFRC522_CRC(buffer, 7, &buffer[7]);
355

356
  _status = MFRC522_ToCard(PCD_TRANSCEIVE, buffer, 9, buffer, &recvBits);
357
  if ((_status == MI_OK) && (recvBits == 0x18))
358
  {
359
    size = buffer[0];
360
  }
361
  else
362
  {
363
    size = 0;
364
  }
365
  return size;
366
}
367
//hibernation
368
void MFRC522_Halt()
369
{
370
  unsigned unLen;
371
  char buff[4];
372

373
  buff[0] = PICC_HALT;
374
  buff[1] = 0;
375
  MFRC522_CRC( buff, 2, &buff[2] );
376
  MFRC522_Clear_Bit( STATUS2REG, 0x80 );
377
  MFRC522_ToCard( PCD_TRANSCEIVE, buff, 4, buff, &unLen );
378
  MFRC522_Clear_Bit( STATUS2REG, 0x08 );
379
}
380
char MFRC522_Auth( char authMode, char BlockAddr, char *Sectorkey, char *serNum )
381
{
382
  char _status;
383
  unsigned recvBits;
384
  char i;
385
  char buff[12];
386

387
  //Verify the command block address + sector + password + card serial number
388
  buff[0] = authMode;
389
  buff[1] = BlockAddr;
390

391
  for ( i = 2; i < 8; i++ )
392
  {
393
    buff[i] = Sectorkey[i-2];
394
  }
395

396
  for ( i = 8; i < 12; i++ )
397
  {
398
    buff[i] = serNum[i-8];
399
  }
400

401
  _status = MFRC522_ToCard( PCD_AUTHENT, buff, 12, buff, &recvBits );
402

403
  if ( ( _status != MI_OK ) || !( MFRC522_Rd( STATUS2REG ) & 0x08 ) )
404
  {
405
    _status = MI_ERR;
406
  }
407

408
  return _status;
409
}
410
char MFRC522_Write( char blockAddr, char *writeData )
411
{
412
  char _status;
413
  unsigned recvBits;
414
  char i;
415
  char buff[18];
416
  buff[0] = PICC_WRITE;
417
  buff[1] = blockAddr;
418

419
  MFRC522_CRC( buff, 2, &buff[2] );
420
  _status = MFRC522_ToCard( PCD_TRANSCEIVE, buff, 4, buff, &recvBits );
421
  if ( (_status != MI_OK) || (recvBits != 4) || ( (buff[0] & 0x0F) != 0x0A) )
422
  {
423
    _status = MI_ERR;
424
  }
425
  if (_status == MI_OK)
426
  {
427
    for ( i = 0; i < 16; i++ )                //Data to the FIFO write 16Byte
428
    {
429
      buff[i] = writeData[i];
430
    }
431

432
    MFRC522_CRC( buff, 16, &buff[16] );
433
    _status = MFRC522_ToCard( PCD_TRANSCEIVE, buff, 18, buff, &recvBits );
434
    if ( (_status != MI_OK) || (recvBits != 4) || ( (buff[0] & 0x0F) != 0x0A ) )
435
    {
436
      _status = MI_ERR;
437
    }
438
  }
439
  return _status;
440
}
441
char MFRC522_Read( char blockAddr, char *recvData )
442
{
443
  char _status;
444
  unsigned unLen;
445
  recvData[0] = PICC_READ;
446
  recvData[1] = blockAddr;
447

448
  MFRC522_CRC( recvData, 2, &recvData[2] );
449

450
  _status = MFRC522_ToCard( PCD_TRANSCEIVE, recvData, 4, recvData, &unLen );
451
  if ( (_status != MI_OK) || (unLen != 0x90) )
452
  {
453
    _status = MI_ERR;
454
  }
455
  return _status;
456
}
457
char MFRC522_AntiColl( char *serNum )
458
{
459
  char _status;
460
  char i;
461
  char serNumCheck = 0;
462
  unsigned unLen;
463
  MFRC522_Wr( BITFRAMINGREG, 0x00 );                //TxLastBists = BitFramingReg[2..0]
464
  serNum[0] = PICC_ANTICOLL;
465
  serNum[1] = 0x20;
466
  MFRC522_Clear_Bit( STATUS2REG, 0x08 );
467
  _status = MFRC522_ToCard( PCD_TRANSCEIVE, serNum, 2, serNum, &unLen );
468
  if (_status == MI_OK)
469
  {
470
    for ( i=0; i < 4; i++ )
471
    {
472
      serNumCheck ^= serNum[i];
473
    }
474

475
    if ( serNumCheck != serNum[4] )
476
    {
477
      _status = MI_ERR;
478
    }
479
  }
480
  return _status;
481
}
482
//0x0044 = Mifare_UltraLight
483
//0x0004 = Mifare_One (S50)
484
//0x0002 = Mifare_One (S70)
485
//0x0008 = Mifare_Pro (X)
486
//0x0344 = Mifare_DESFire
487
char MFRC522_isCard( char *TagType )
488
{
489
   
490
    if (MFRC522_Request( PICC_REQALL, TagType ) == MI_OK)
491
        return 1;
492
    else
493
        return 0;
494
}
495
char MFRC522_ReadCardSerial( char *str )
496
{
497
char _status;
498
 _status = MFRC522_AntiColl( str );
499
 str[5] = 0;
500
 if (_status == MI_OK)
501
  return 1;
502
 else
503
  return 0;
504
}

Reply

Note: the original post is older than 6 months. Please don't ask any new questions in this thread, but start a new one.

Formatting
  • [c]C-Code[/c]
  • [code]code in other languages, ASCII drawings[/code]
  • [math]formula (LaTeX syntax)[/math]
  • [[Title]] – link to an article
  • Link to another post: right-click its post ID (#8078628), copy the address, paste it into the text

More about formatting

Post long source code as an attachment, not in the text.

Already registered? Log in

Not shown to anyone. We send you a link; your post appears once you confirm it there.

By submitting you create a free account and accept the terms of use.