EmbDev.net

Forum: µC & Digital Electronics RFID MFRC522 with PIC18


von Leonardo A. (oleoarruda)


Rate this post
0 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

Entering an e-mail address is optional. If you want to receive reply notifications by e-mail, please log in.

Rules — please read before posting

  • Post long source code as attachment, not in the text
  • Posting advertisements is forbidden.

Formatting options

  • [c]C code[/c]
  • [avrasm]AVR assembler code[/avrasm]
  • [code]code in other languages, ASCII drawings[/code]
  • [math]formula (LaTeX syntax)[/math]




Bild automatisch verkleinern, falls nötig