Raspberry Pi Weighting Control System
This project serves as a simple weighting control system, that was realized as a Bachelor Thesis
Functions | Variables
rc522.cpp File Reference
#include <memory>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <spdlog/spdlog.h>
#include "rc522.h"

Go to the source code of this file.

Functions

void InitRc522 (SPI *p_spi)
 
char PcdRequest (uint8_t req_code, uint8_t *pTagType)
 
char PcdAnticoll (uint8_t cascade, uint8_t *pSnr)
 
char PcdSelect (uint8_t cascade, uint8_t *pSnr, uint8_t *SAK)
 
char PcdAuthState (uint8_t auth_mode, uint8_t addr, uint8_t *pKey, uint8_t *pSnr)
 
char PcdRead (uint8_t addr, uint8_t *p)
 
char PcdWrite (uint8_t addr, uint8_t *p)
 
char PcdHalt (void)
 
char PcdValue (uint8_t act, uint8_t addr, double value)
 
void Pcd_stopcrypto1 ()
 
int PcdCheckAuth ()
 
void CalulateCRC (uint8_t *pIn, uint8_t len, uint8_t *pOut)
 
char PcdReset (void)
 
uint8_t ReadRawRC (uint8_t Address)
 
uint8_t WriteRawRC (uint8_t Address, uint8_t value)
 
void SetBitMask (uint8_t reg, uint8_t mask)
 
void ClearBitMask (uint8_t reg, uint8_t mask)
 
char PcdComMF522 (uint8_t Command, uint8_t *pIn, uint8_t InLenByte, uint8_t *pOut, uint8_t *pOutLenBit, int CheckTimeout)
 
void PcdAntennaOn (void)
 
void PcdAntennaOff (void)
 

Variables

ewf int extra_delay =0
 
SPI * spi
 

Function Documentation

◆ CalulateCRC()

void CalulateCRC ( uint8_t *  pIn,
uint8_t  len,
uint8_t *  pOut 
)

Definition at line 461 of file rc522.cpp.

462 {
463  uint8_t i,n;
464 
465  // clear the calcCRC is active and all data is processed bit
466  ClearBitMask(DivIrqReg,0x04);
467 
468  // cancel any other command that might be pending/executed
470 
471  // flush read/write pointers and ERRORreg BufferOvfl bit
472  SetBitMask(FIFOLevelReg,0x80);
473 
474  // fill the FIFO with the data
475  for (i=0; i<len; i++) WriteRawRC(FIFODataReg, *(pIn +i));
476 
477  // start calculation of the CRC
479 
480  // set a time out
481  i = 0xFF;
482 
483  // loop until time out of CRC has been calculated bit has been set
484  do
485  {
486  n = ReadRawRC(DivIrqReg);
487  i--;
488  }
489  while ((i!=0) && !(n&0x04));
490 
491  // read the calucated CRC value (no check on timeout, CRC is wrong anyway)
492  pOut [0] = ReadRawRC(CRCResultRegL);
493  pOut [1] = ReadRawRC(CRCResultRegM);
494 }
void ClearBitMask(uint8_t reg, uint8_t mask)
Definition: rc522.cpp:618
uint8_t WriteRawRC(uint8_t Address, uint8_t value)
Definition: rc522.cpp:593
void SetBitMask(uint8_t reg, uint8_t mask)
Definition: rc522.cpp:609
uint8_t ReadRawRC(uint8_t Address)
Definition: rc522.cpp:573
#define FIFOLevelReg
Definition: rc522.h:77
#define FIFODataReg
Definition: rc522.h:76
#define CommandReg
Definition: rc522.h:68
#define PCD_CALCCRC
Definition: rc522.h:44
#define DivIrqReg
Definition: rc522.h:72
#define PCD_IDLE
Definition: rc522.h:38
#define CRCResultRegM
Definition: rc522.h:96
#define CRCResultRegL
Definition: rc522.h:97

◆ ClearBitMask()

void ClearBitMask ( uint8_t  reg,
uint8_t  mask 
)

Definition at line 618 of file rc522.cpp.

619 {
620  char tmp = 0x0;
621  tmp = ReadRawRC(reg);
622  WriteRawRC(reg, tmp & ~mask); // clear bit mask
623 }

◆ InitRc522()

void InitRc522 ( SPI *  p_spi)

Definition at line 39 of file rc522.cpp.

40 {
41  if (p_spi) spi = p_spi;
42  else spdlog::critical("rc522.cpp - RC522 didn't recieve SPI");
43  PcdReset();
44 }
char PcdReset(void)
Definition: rc522.cpp:498
SPI * spi
Definition: rc522.cpp:36

◆ Pcd_stopcrypto1()

void Pcd_stopcrypto1 ( )

Definition at line 433 of file rc522.cpp.

434 {
435 
436  /* clear MIFARE Crypto-1
437  * needed after authorisation otherwise no further card can be read*/
438  ClearBitMask(Status2Reg,0x08);
439 }
#define Status2Reg
Definition: rc522.h:75

◆ PcdAntennaOff()

void PcdAntennaOff ( void  )

Definition at line 798 of file rc522.cpp.

799 {
800  ClearBitMask(TxControlReg, 0x03);
801 }
#define TxControlReg
Definition: rc522.h:86

◆ PcdAntennaOn()

void PcdAntennaOn ( void  )

Definition at line 790 of file rc522.cpp.

791 {
792  // check if not on already
793  if (!(ReadRawRC(TxControlReg) & 0x03))
794  SetBitMask(TxControlReg, 0x03);
795 }

◆ PcdAnticoll()

char PcdAnticoll ( uint8_t  cascade,
uint8_t *  pSnr 
)

Definition at line 89 of file rc522.cpp.

90 {
91  char status;
92  uint8_t i,snr_check=0;
93  uint8_t unLen;
94  uint8_t ucComMF522Buf[MAXRLEN];
95  uint8_t pass=32; // max 32 bits (ISo standard)
96  uint8_t collbits=0;
97 
98  i=0;
99 
100  /*
101  * LSB of the received bit is stored at bit position 0, the second on stored on ps 1
102  * all bits of the last byte will be transferred */
104 
105  // bits received after collision are cleared
106  WriteRawRC(CollReg,0x80);
107 
108  do {
109  /* anti collision commands 0x93, 0x95 or 0x97 */
110  ucComMF522Buf[0] = cascade;
111 
112  /* NVB = number of valid bits/bytes
113  *
114  * NVB : 0x20 = no part of UID is sent = anticollision command
115  *
116  * 0x20 => top 4 bits is byte count = 2 valid bytes to transmit: cascade (or SEL or CL) + NVB
117  * byte count 2 = minimum, 7 max
118  *
119  * 0x20 => bottom 4 bits is bit count = 0 : number of valid data bits (include SEL+NVB) modulo 8
120  *
121  * normal way to connect at first, second the UID will be asked
122  * with collbits set to the correct number of UID bits
123  */
124  ucComMF522Buf[1] = 0x20+collbits;
125 
126  // WriteRawRC(0x0e,0);
127 
128  /* write Transceive command to card*/
129  status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,2+i,ucComMF522Buf,&unLen,1);
130 
131  if (status == TAG_COLLISION) {
132 
133  collbits=ReadRawRC(CollReg)&0x1f;
134 
135  /* 00 = bit collision of 32nd bit
136  * that sets the length of the UID */
137  if (collbits==0) collbits=32;
138 
139  i=(collbits-1)/8 +1;
140 // printf ("--- %02x %02x %02x %02x %d\n",ucComMF522Buf[0],ucComMF522Buf[1],ucComMF522Buf[2],ucComMF522Buf[3],unLen);
141 
142  ucComMF522Buf[i-1]|=(1<<((collbits-1)%8)); // move collbit to right place
143  ucComMF522Buf[5]=ucComMF522Buf[3];
144  ucComMF522Buf[4]=ucComMF522Buf[2];
145  ucComMF522Buf[3]=ucComMF522Buf[1];
146  ucComMF522Buf[2]=ucComMF522Buf[0];
147 
148  WriteRawRC(BitFramingReg,(collbits % 8));
149 // printf (" %d %d %02x %d\n",collbits,i,ucComMF522Buf[i+1],collbits % 8);
150  }
151  } while ( --pass > 0 && status == TAG_COLLISION);
152 // printf ("na %02x %02x %02x %02x %d\n",ucComMF522Buf[0],ucComMF522Buf[1],ucComMF522Buf[2],ucComMF522Buf[3],unLen);
153 
154  if (status == TAG_OK) // 4 bytes as defined by ISO
155  {
156  for (i=0; i < 4; i++)
157  {
158  *(pSnr+i) = ucComMF522Buf[i];
159  snr_check ^= ucComMF522Buf[i];
160  }
161  // check BCC = block check characters match
162  if (snr_check != ucComMF522Buf[i]) status = TAG_ERR;
163  }
164 
165  return status;
166 }
char PcdComMF522(uint8_t Command, uint8_t *pIn, uint8_t InLenByte, uint8_t *pOut, uint8_t *pOutLenBit, int CheckTimeout)
Definition: rc522.cpp:626
#define TAG_ERR
Definition: rc522.h:127
#define TAG_OK
Definition: rc522.h:125
#define PCD_TRANSCEIVE
Definition: rc522.h:42
#define MAXRLEN
Definition: rc522.h:64
#define TAG_COLLISION
Definition: rc522.h:129
#define CollReg
Definition: rc522.h:81
#define BitFramingReg
Definition: rc522.h:80

◆ PcdAuthState()

char PcdAuthState ( uint8_t  auth_mode,
uint8_t  addr,
uint8_t *  pKey,
uint8_t *  pSnr 
)

Definition at line 259 of file rc522.cpp.

260 {
261  char status;
262  uint8_t unLen;
263  uint8_t ucComMF522Buf[MAXRLEN];
264 
265  memset(ucComMF522Buf,0,sizeof(ucComMF522Buf)); // clear buffer
266 
267  ucComMF522Buf[0] = auth_mode;
268  ucComMF522Buf[1] = addr;
269 
270  memcpy(&ucComMF522Buf[2], pKey, 6); // included Key A or KeyB
271  memcpy(&ucComMF522Buf[8], pSnr, 4); // include only first 4 bytes of UID
272 
273  status = PcdComMF522(PCD_AUTHENT,ucComMF522Buf,12,ucComMF522Buf,&unLen,1);
274 
275  // check that Crypt0-1 bit is set to indicate succesfull authorization
276  if ((status != TAG_OK) || (!(ReadRawRC(Status2Reg) & 0x08)))
277  status = TAG_ERR;
278 
279  return(status);
280 }
#define PCD_AUTHENT
Definition: rc522.h:39

◆ PcdCheckAuth()

int PcdCheckAuth ( )

Definition at line 445 of file rc522.cpp.

446 {
447  if (ReadRawRC(Status2Reg) & 0x08) return(0);
448 
449  return(1);
450 }

◆ PcdComMF522()

char PcdComMF522 ( uint8_t  Command,
uint8_t *  pIn,
uint8_t  InLenByte,
uint8_t *  pOut,
uint8_t *  pOutLenBit,
int  CheckTimeout 
)

Definition at line 626 of file rc522.cpp.

632 {
633 
634  char status = TAG_ERR; // return code
635  uint8_t irqEn = 0x00; // IRQ register content
636  uint8_t waitFor = 0x00;
637  uint8_t lastBits;
638  uint8_t n;
639  uint32_t i;
640  uint8_t PcdErr;
641 
642  switch (Command)
643  {
644  case PCD_AUTHENT:
645  irqEn = 0x12; // enable Idle and low alert interrupts
646  waitFor = 0x10; // expect interrupt to continue (idle interrupt)
647  break;
648  case PCD_TRANSCEIVE:
649  irqEn = 0x77; // enable all alert except high alert interrupt
650  waitFor = 0x30; // expect interrupt to continue (Idle and received end of valid data stream)
651  break;
652  default:
653  printf("FATAL - RC522 unrecognized command in PcdComMF522(...)");
654  exit(1); // TODO alternative instead exit
655  }
656  /*
657  * B7 1 IRQ inverted with respect to Status1reg IRq bit
658  * B6 1 allows transmitter interrupt request
659  * B5 1 Allow receiver interrupt request
660  * B4 1 allow idle interrupt request
661  * B3 1 allow high alert interrupt request
662  * B2 1 allows low alert interrupt request
663  * B1 1 allow error interrupt request
664  * B0 1 allows time interrupt request
665  */
666  WriteRawRC(ComIEnReg,irqEn|0x80);
667 
668  /* clear IRQ inverted respect to status1reg
669  * indicates that the marked bits in the ComIrqReg register are set */
670  ClearBitMask(ComIrqReg,0x80);
671 
672  /* Flushbuffer / clear FIFO*/
673  SetBitMask(FIFOLevelReg,0x80);
674 
675  /* sent command to set RC522 to Idle & cancel any pending execution */
677 
678  /* write data in FIFO data for the length of buffer*/
679  for (i=0; i<InLenByte; i++) WriteRawRC(FIFODataReg, pIn [i]);
680 
681  /* sent the command */
682  WriteRawRC(CommandReg, Command);
683 
684  /* start the transmission of data in Transceive mode*/
685  if (Command == PCD_TRANSCEIVE) SetBitMask(BitFramingReg,0x80);
686 
687  i = 150;
688 
689  /* as long as not count down
690  * Time out has not happened
691  * and other possible wait for interrupts
692  * n&01 = time out has happened (timeout was set in PcdReset as 24ms)
693  * n&waitfor = good interrupts to happen
694  */
695 
696  do
697  {
698  usleep(200);
699 
700  /* read interrupt register */
701  n = ReadRawRC(ComIrqReg);
702  i--;
703  }
704  while (i!=0 && (! (n&0x01)) && (!(n&waitFor)));
705 
706  /* removing start data transmission in transceive */
707  if (Command == PCD_TRANSCEIVE) ClearBitMask(BitFramingReg,0x80);
708 
709  /* maybe something received as no count-down */
710  if (i != 0)
711  {
712  PcdErr=ReadRawRC(ErrorReg);
713 
714  /* check for parity or buffer overflow/protocol err */
715  if (!(PcdErr & 0x11))
716  {
717  status = TAG_OK;
718 
719  /* time out had triggered (~24 ms) */
720  if (n & irqEn & 0x01)
721  {
722  /* necessary to discard during data transmission with increment, decrement,
723  * transfer these commands time out as there is NAK responds
724  * to be expected. */
725  if (CheckTimeout) status = TAG_NOTAG;
726  }
727  else if (Command == PCD_TRANSCEIVE)
728  {
729  /* get # of bytes received in FIFO */
730  n = ReadRawRC(FIFOLevelReg);
731 
732  /* get # valid bits in the last byte 00 = all*/
733  lastBits = ReadRawRC(ControlReg) & 0x07;
734 
735  /* determine the correct amount of bits */
736  if (lastBits) *pOutLenBit = (n-1)*8 + lastBits;
737  else *pOutLenBit = n*8;
738 
739  /* set counter start and maximum good */
740  if (n == 0) n = 1;
741  if (n > MAXRLEN) n = MAXRLEN;
742 
743  /* read the receive information */
744  for (i=0; i < n; i++) {
745  pOut [i] = ReadRawRC(FIFODataReg);
746 
747  /* Based on field testing, usleep seems to be needed from some cards / systems
748  * The usleep code itself takes 70us and as such this takes 80us
749  * that is about the same as the printf underneath and seemed to be necessary
750  * during a field test.
751  *
752  * don't ask me why.... */
753 
754  //usleep(10);
755 
756  //printf ("%s :%d .%02X\n",__func__,i, pOut[i]);
757  }
758 
759  /* Given the comment above, an extra delay can now be requested on the command
760  * line with -E. The 80us mentioned above was resulting in 400us or 500us depending
761  * on the number of databytes that were received.
762  *
763  * allow for 500us extra delay for slow card to recover */
764  if (extra_delay) usleep(500);
765  }
766  }
767  else {
768  printf("Parity or buffer overflow\n");
769  status = TAG_ERR;
770  }
771 
772  /* collision error detected ?*/
773  if (PcdErr & 0x08)
774  {
775  printf("ERROR - RC522 PcdComRF522 Collision!"); // debug print
776  status = TAG_COLLISION;
777  }
778  }
779 
780  SetBitMask(ControlReg,0x80); // stop timer now
781 // printf("%s : status %02x, length of message %d, PCD err %02x\n"
782 // ,__func__, status,*pOutLenBit, PcdErr);
783 
784  return status;
785 }
ewf int extra_delay
Definition: rc522.cpp:35
#define ComIEnReg
Definition: rc522.h:69
#define ControlReg
Definition: rc522.h:79
#define ComIrqReg
Definition: rc522.h:71
#define TAG_NOTAG
Definition: rc522.h:126
#define ErrorReg
Definition: rc522.h:73

◆ PcdHalt()

char PcdHalt ( void  )

Definition at line 363 of file rc522.cpp.

364 {
365  uint8_t status;
366  uint8_t unLen;
367  uint8_t ucComMF522Buf[MAXRLEN];
368 
369  ucComMF522Buf[0] = PICC_HALT; //0x50
370  ucComMF522Buf[1] = 0; //add CRC-A
371  CalulateCRC(ucComMF522Buf,2,&ucComMF522Buf[2]);
372  // sent to card
373  status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,4,ucComMF522Buf,&unLen,1);
374 
375  Pcd_stopcrypto1();
376 
377  return(status);
378 }
void Pcd_stopcrypto1()
Definition: rc522.cpp:433
void CalulateCRC(uint8_t *pIn, uint8_t len, uint8_t *pOut)
Definition: rc522.cpp:461
#define PICC_HALT
Definition: rc522.h:60

◆ PcdRead()

char PcdRead ( uint8_t  addr,
uint8_t *  p 
)

Definition at line 286 of file rc522.cpp.

287 {
288  char status;
289  uint8_t unLen;
290  uint8_t i,ucComMF522Buf[MAXRLEN];
291  uint8_t CRC_buff[2];
292 
293  memset(ucComMF522Buf,0,sizeof(ucComMF522Buf)); // clear buffer
294 
295  ucComMF522Buf[0] = PICC_READ; // 0x30 = read
296  ucComMF522Buf[1] = addr; // add address to read
297  CalulateCRC(ucComMF522Buf,2,&ucComMF522Buf[2]); // add crc
298 
299  // perform read operation from card
300  status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,4,ucComMF522Buf,&unLen,1);
301 
302  // check status and received bits / bytes 0x90 => 144 / 8 => 18 bytes => 16 data bytes + 2 CRC
303  if ((status == TAG_OK) && (unLen == 0x90))
304  {
305  // calculate CRC
306  CalulateCRC(ucComMF522Buf,16,CRC_buff); // 16 bytes should used for CRC check
307 
308 // printf("debug %02x%02x %02x%02x ",ucComMF522Buf[16],ucComMF522Buf[17],CRC_buff[0],CRC_buff[1]);
309 
310  // check CRC is correct
311  if ((CRC_buff[0]!=ucComMF522Buf[16])||(CRC_buff[1]!=ucComMF522Buf[17]))
312  status = TAG_ERRCRC;
313 
314  else
315  {
316  // copy 16 data bytes received
317  for (i=0; i<16; i++) *(p+i) = ucComMF522Buf[i];
318  }
319  }
320  else
321  status = TAG_ERR;
322 
323  return(status);
324 }
#define PICC_READ
Definition: rc522.h:54
#define TAG_ERRCRC
Definition: rc522.h:128

◆ PcdRequest()

char PcdRequest ( uint8_t  req_code,
uint8_t *  pTagType 
)

Definition at line 47 of file rc522.cpp.

48 {
49  char status;
50  uint8_t unLen;
51  uint8_t ucComMF522Buf[MAXRLEN];
52 
53  /*
54  * B7 1 = start transmission of data (with transceive command)
55  * B6 - B4 0 = LSB stored in position 0
56  * B3 not used
57  * B2 - B0 number of bits of last byte that will be transmitted
58  */
59 
61 
62  ucComMF522Buf[0] = req_code;
63 
64  /* write request with length 1, receive in buf and unlen = #bits received*/
65  status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,1,ucComMF522Buf,&unLen,1);
66 
67  /* expect 2 bytes or 16 bits with card type*/
68  if ((status == TAG_OK) && (unLen == 0x10))
69  {
70  *pTagType = ucComMF522Buf[0];
71  *(pTagType+1) = ucComMF522Buf[1];
72  }
73  else if (status == TAG_COLLISION) {
74 // printf("ATQA %02x%02x\n",ucComMF522Buf[0],ucComMF522Buf[1]);
75  }
76  else if (status != TAG_NOTAG) status = TAG_ERR;
77 
78  return status;
79 }

◆ PcdReset()

char PcdReset ( void  )

Definition at line 498 of file rc522.cpp.

499 {
500  // perform a softreset
502 
503  // give it time to settle
504  usleep(10000);
505 
506  // wait for Soft power-down to finish
507  // this ins't in the python version, but since it works
508  while (ReadRawRC(CommandReg) & 0x10);
509 
510  // Turn antenna off
511  // not in python, but ok i guess
512  PcdAntennaOff();
513 
514  // give it time to settle
515  usleep(10000);
516 
517  /* setup internal timer (used in PcdComMF522 for timeout)
518  *
519  * This TPrescaler is set to 0xa9 => 169 => 40 khz => 25us
520  * The reload value is 0x3e8 = 1000, as such : 25 ms
521  */
522 
523  /* timer mode
524  * B7 = 1 Timer start automatically at end of transmission
525  * B6/B5 = 00 Non-gated mode (no dependency on MFIN or AUX1 pin)
526  * B4 = 0 No automatic restart (comIRQReg TimeIRQ bit is set at 0)
527  * B3-B0 = 0x0 Higher 4 bits of Tprescaler divider
528  */
529  //WriteRawRC(TModeReg,0x80); // changed value to 0x8D from 0x80
530  WriteRawRC(TModeReg,0x8D); // changed value to 0x8D from 0x80
531 
532  /* B7 -B0 = Tprescaler LSB 7 bits of divider */
533  // changed value from 0xA9 to 0x3E
534  //WriteRawRC(TPrescalerReg,0xA9); // + TmodeReg[3...0]
535  WriteRawRC(TPrescalerReg,0x3E); // + TmodeReg[3...0]
536 
537  /* time reload value, lower 8 bits */
538  //WriteRawRC(TReloadRegL, 0xE8); //changed value from 0xE8 to 30 (dec)
539  WriteRawRC(TReloadRegL, 30); //changed value from 0xE8 to 30 (dec)
540 
541  /* timer reload value, higher 8 bits */
542  //WriteRawRC(TReloadRegH, 0x03); //changed value from 0x03 to 0 (dec)
543  WriteRawRC(TReloadRegH, 0); //changed value from 0x03 to 0 (dec)
544 
545  /* forces a 100% ASK modulation independent of modGsPReg (Type-A)
546  * ASK = Amplitude Shift Keying */
547  // same value, in python called TxAutoReg
548  WriteRawRC(TxASKReg,0x40);
549 
550  /* Preset value
551  * B7 0 CRC does not start with MSB first
552  * B6 0 Not used
553  * B5 1 transmitter can only be started if RF field is generated
554  * B4 0 not used
555  * B3 1 Polarity on MFIN is active high
556  * B2 1 not used
557  * B1 B0 01 CRC preset value 6363 (TYPE-A)*/
558  //changed value from 0x2D to 0x3D
559  //WriteRawRC(ModeReg,0x2D); //CRC initialize value
560  WriteRawRC(ModeReg,0x3D); //CRC initialize value
561 
562  // Turn antenna on
563  PcdAntennaOn();
564 
565  return(TAG_OK);
566 }
void PcdAntennaOn(void)
Definition: rc522.cpp:790
void PcdAntennaOff(void)
Definition: rc522.cpp:798
#define TxASKReg
Definition: rc522.h:87
#define ModeReg
Definition: rc522.h:83
#define TPrescalerReg
Definition: rc522.h:104
#define TReloadRegH
Definition: rc522.h:105
#define TReloadRegL
Definition: rc522.h:106
#define PCD_RESETPHASE
Definition: rc522.h:43
#define TModeReg
Definition: rc522.h:103

◆ PcdSelect()

char PcdSelect ( uint8_t  cascade,
uint8_t *  pSnr,
uint8_t *  SAK 
)

Definition at line 187 of file rc522.cpp.

188 {
189  char status;
190  uint8_t i;
191  uint8_t unLen;
192  uint8_t ucComMF522Buf[MAXRLEN];
193  uint8_t CRC_buff[2];
194 
195  ucComMF522Buf[0] = cascade; // 0x93, 0x95 or 0x97
196  ucComMF522Buf[1] = 0x70; // 0x70 : SELECT command
197  ucComMF522Buf[6] = 0; // BCC
198 
199  for (i=0; i<4; i++) // add UID & calc BCC
200  {
201  ucComMF522Buf[i+2] = *(pSnr+i);
202  ucComMF522Buf[6] ^= *(pSnr+i);
203  }
204  // add 2 CRC-A bytes
205  CalulateCRC(ucComMF522Buf,7,&ucComMF522Buf[7]);
206 
207  /* clear MIFARE Crypto-1 (just in case)*/
208  ClearBitMask(Status2Reg,0x08);
209 
210  /* sent select command */
211  status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,9,ucComMF522Buf,&unLen,1);
212 
213  // expects 24 bytes response (as for ISO)
214  if ((status == TAG_OK) && (unLen == 0x18))
215  {
216  // calculate CRC
217  CalulateCRC(ucComMF522Buf,1,CRC_buff); // 1 byte used for CRC check
218 
219 // printf("debug %02x%02x %02x%02x ",ucComMF522Buf[1],ucComMF522Buf[2],CRC_buff[0],CRC_buff[1]);
220 
221  // check CRC is correct
222  if ((CRC_buff[0]!=ucComMF522Buf[1])||(CRC_buff[1]!=ucComMF522Buf[2]))
223  status = TAG_ERRCRC;
224 
225  else
226  {
227  *SAK = ucComMF522Buf[0]; // copy SAK
228  status = TAG_OK;
229  }
230  }
231  else
232  status = TAG_ERR;
233 
234  return status;
235 }

◆ PcdValue()

char PcdValue ( uint8_t  act,
uint8_t  addr,
double  value 
)

Definition at line 385 of file rc522.cpp.

386 {
387  uint8_t status;
388  uint8_t unLen;
389  uint8_t ucComMF522Buf[MAXRLEN];
390 
391  // sent command and block address
392  ucComMF522Buf[0] = act;
393  ucComMF522Buf[1] = addr;
394 
395  //add CRC-A
396  CalulateCRC(ucComMF522Buf,2,&ucComMF522Buf[2]);
397 
398  // sent to card
399  status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,4,ucComMF522Buf,&unLen,1);
400 
401  if (status != TAG_OK)
402  {
403  printf("ERROR - PcdValue(...) cannot send command!!!");
404  return(status);
405  }
406 
407  // sent the amount
408  ucComMF522Buf[0] = ((long long) value & (long long) 0xff);
409  ucComMF522Buf[1] = ((long long) value & (long long) 0xff00) >> 8;
410  ucComMF522Buf[2] = ((long long) value & (long long) 0xff0000) >> 16;
411  ucComMF522Buf[3] = ((long long) value & (long long) 0xff000000) >> 24;
412 
413  //add CRC-A
414  CalulateCRC(ucComMF522Buf,4,&ucComMF522Buf[4]);
415 
416  /* sent to card
417  *
418  * !!! NO check on time out !!!
419  *
420  * This necessary during data transmission with increment, decrement,
421  * transfer these commands time out as there is NAK responds
422  * to be expected from the PICC.
423  */
424 
425  status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,6,ucComMF522Buf,&unLen,0);
426 
427  if (status != TAG_OK) printf("ERROR - PcdValue(...) cannot send value!!!");
428 
429  return(status);
430 }

◆ PcdWrite()

char PcdWrite ( uint8_t  addr,
uint8_t *  p 
)

Definition at line 326 of file rc522.cpp.

327 {
328  char status;
329  uint8_t unLen;
330  uint8_t i,ucComMF522Buf[MAXRLEN];
331 
332  ucComMF522Buf[0] = PICC_WRITE; // a0
333  ucComMF522Buf[1] = addr; // add addr + CRC
334  CalulateCRC(ucComMF522Buf,2,&ucComMF522Buf[2]);
335 
336  status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,4,ucComMF522Buf,&unLen,1);
337 
338  // check for ACK
339  if ((status != TAG_OK) || (unLen != 4) || ((ucComMF522Buf[0] & 0x0F) != 0x0A))
340  { status = TAG_ERR; }
341 
342  if (status == TAG_OK)
343  {
344  for (i=0; i<16; i++) ucComMF522Buf[i] = *(p+i);
345 
346  CalulateCRC(ucComMF522Buf,16,&ucComMF522Buf[16]);
347 
348  status = PcdComMF522(PCD_TRANSCEIVE,ucComMF522Buf,18,ucComMF522Buf,&unLen,1);
349 
350  // 0xA is ACK, any other value is NAK
351  // must have received 4 bytes ??
352  if ((status != TAG_OK) || (unLen != 4) || ((ucComMF522Buf[0] & 0x0F) != 0x0A))
353  status = TAG_ERR;
354  }
355 
356  return(status);
357 }
#define PICC_WRITE
Definition: rc522.h:55

◆ ReadRawRC()

uint8_t ReadRawRC ( uint8_t  Address)

Definition at line 573 of file rc522.cpp.

574 {
575  uint8_t in_buff[2] = {0};
576  uint8_t out_buff[2] = {0};
577 
578  in_buff[0] = ((Address<<1)&0x7E)|0x80;
579  //printf("addr: %d, translated to: %d\n", Address, buff[0]);
580  spi->xfer(in_buff, 2, out_buff, 2);
581  //spi->read(buff, 2);
582  //printf("val: %d %d\n", buff[0], buff[1]);
583  //printf("out buff: %.2x %.2x\n", out_buff[0], out_buff[1]);
584  return (uint8_t) out_buff[1];
585  //return (uint8_t)buff[0];
586 }

◆ SetBitMask()

void SetBitMask ( uint8_t  reg,
uint8_t  mask 
)

Definition at line 609 of file rc522.cpp.

610 {
611  char tmp = 0x0;
612  tmp = ReadRawRC(reg);
613  WriteRawRC(reg,tmp | mask); // set bit mask
614 
615 }

◆ WriteRawRC()

uint8_t WriteRawRC ( uint8_t  Address,
uint8_t  value 
)

Definition at line 593 of file rc522.cpp.

594 {
595  uint8_t buff[2];
596 
597  buff[0] = ((Address<<1)&0x7E);
598  buff[1] = value;
599 
600  // using only write, because it doesn't read anyting
601  spi->write(buff, 2);
602 
603  // return error register
604  return(ReadRawRC(ErrorReg));
605 
606 }

Variable Documentation

◆ extra_delay

int extra_delay =0

Definition at line 35 of file rc522.cpp.

◆ spi

SPI* spi

Definition at line 36 of file rc522.cpp.