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 | }
|