/* File: Mfrc522.cpp Mfrc522 - Library for communicating with MFRC522 based NFC Reader/Writers Created by Eelco Rouw - Mainly based on code from Grant Gibson (www.grantgibson.co.uk) and Dr.Leong ( WWW.B2CQSHOP.COM ) Lightly modified by Frank Milburn Lightly modified by Roy Bakker C++ --> C Released into the public domain Lightly modified by Mats van Reenen: use other SPI interface */ #include #include #include //#include void RC522_init(int chipSelectPin, int NRSTPD) { _chipSelectPin = chipSelectPin; P1DIR |= _chipSelectPin; P1OUT |= _chipSelectPin; _NRSTPD = NRSTPD; P1DIR |= _NRSTPD; P1OUT |= _NRSTPD; RC522_reset(); //Timer: TPrescaler*TreloadVal/6.78MHz = 24ms RC522_writeReg(TModeReg, 0x8D); //Tauto=1; f(Timer) = 6.78MHz/TPreScaler RC522_writeReg(TPrescalerReg, 0x3E); //TModeReg[3..0] + TPrescalerReg RC522_writeReg(TReloadRegL, 30); RC522_writeReg(TReloadRegH, 0); RC522_writeReg(TxAutoReg, 0x40); //100%ASK RC522_writeReg(ModeReg, 0x3D); //RC522_clearBitMask(Status2Reg, 0x08); //MFCrypto1On=0 //RC522_writeReg(RxSelReg, 0x86); //RxWait = RxSelReg[5..0] //RC522_writeReg(RFCfgReg, 0x7F); //RxGain = 48dB RC522_antennaOn(); } /* * Function: WriteReg * Description: write a byte data into one register of MR RC522 * Input parameter: addr--register address;val--the value that need to write in * Return: Null */ void RC522_writeReg(unsigned char addr, unsigned char val) { SPIInitSend(_chipSelectPin, SPI_Mode0, SPI_Clock_4MHz); SPI_packet[3] = (addr<<1)&0x7E; SPI_packet[4] = val; SPI_packetC = 3; SPISend(); // P1OUT &= ~(_chipSelectPin); // SPI_transfer((addr<<1)&0x7E); // SPI_transfer(val); // P1OUT |= _chipSelectPin; } /* * Function: ReadReg * Description: read a byte data into one register of MR RC522 * Input parameter: addr--register address * Return: return the read value */ unsigned char RC522_readReg(unsigned char addr) { SPIInitSend(_chipSelectPin, SPI_Mode0, SPI_Clock_4MHz); SPI_packet[3] = ((addr<<1)&0x7E) | 0x80; SPI_packet[4] = 0; SPI_packetC = 3; SPISend(); return SPI_packet[4]; // unsigned char val; // P1OUT &= ~(_chipSelectPin); // SPI_transfer(((addr<<1)&0x7E) | 0x80); // val = SPI_transfer(0x00); // P1OUT |= _chipSelectPin; // return val; } /* * Function: SetBitMask * Description: set RC522 register bit * Input parameter: reg--register address;mask--value * Return: null */ void RC522_setBitMask(unsigned char reg, unsigned char mask) { unsigned char tmp; tmp = RC522_readReg(reg); RC522_writeReg(reg, tmp | mask); // set bit mask } /* * Function: ClearBitMask * Description: clear RC522 register bit * Input parameter: reg--register address;mask--value * Return: null */ void RC522_clearBitMask(unsigned char reg, unsigned char mask) { unsigned char tmp; tmp = RC522_readReg(reg); RC522_writeReg(reg, tmp & (~mask)); // clear bit mask } /* * Function: AntennaOn * Description: Turn on antenna, every time turn on or shut down antenna need at least 1ms delay * Input parameter: null * Return: null */ void RC522_antennaOn(void) { unsigned char temp; temp = RC522_readReg(TxControlReg); if (!(temp & 0x03)) { RC522_setBitMask(TxControlReg, 0x03); } } /* * Function: AntennaOff * Description: Turn off antenna, every time turn on or shut down antenna need at least 1ms delay * Input parameter: null * Return: null */ void RC522_antennaOff(void) { RC522_clearBitMask(TxControlReg, 0x03); } /** * Set the MFRC522 Receiver Gain (RxGain) to value specified by given mask. * See 9.3.3.6 / table 98 in http://www.nxp.com/documents/data_sheet/MFRC522.pdf * NOTE: Given mask is scrubbed with (0x07<<4)=01110000b as RCFfgReg may use reserved bits. */ void RC522_setAntennaGain(unsigned char mask) { RC522_clearBitMask(RFCfgReg, (0x07<<4)); // clear needed to allow 000 pattern RC522_setBitMask(RFCfgReg, (mask & 0x07)<<4); // only set RxGain[2:0] bits } /* * Function: Reset * Description: reset RC522 * Input parameter: null * Return: null */ void RC522_reset(void) { RC522_writeReg(CommandReg, PCD_RESETPHASE); } /* * Function: Request * Description: Searching card, read card type * Input parameter: reqMode--search methods, * TagType--return card types * 0x4400 = Mifare_UltraLight * 0x0400 = Mifare_One(S50) * 0x0200 = Mifare_One(S70) * 0x0800 = Mifare_Pro(X) * 0x4403 = Mifare_DESFire * Return: return MI_OK if successed */ unsigned char RC522_request(unsigned char reqMode, unsigned char *TagType) { unsigned char status; unsigned int backBits; RC522_writeReg(BitFramingReg, 0x07); //TxLastBists = BitFramingReg[2..0] ??? TagType[0] = reqMode; status = RC522_toCard(PCD_TRANSCEIVE, TagType, 1, TagType, &backBits); if ((status != MI_OK) || (backBits != 0x10)) { status = MI_ERR; } return status; } /* * Function: ToCard * Description: communicate between RC522 and ISO14443 * Input parameter: command--MF522 command bits * sendData--send data to card via rc522 * sendLen--send data length * backData--the return data from card * backLen--the length of return data * Return: return MI_OK if successed */ unsigned char RC522_toCard(unsigned char command, unsigned char *sendData, unsigned char sendLen, unsigned char *backData, unsigned int *backLen) { unsigned char status = MI_ERR; unsigned char irqEn = 0x00; unsigned char waitIRq = 0x00; unsigned char lastBits; unsigned char n; unsigned int i; switch (command) { case PCD_AUTHENT: { irqEn = 0x12; waitIRq = 0x10; break; } case PCD_TRANSCEIVE: { irqEn = 0x77; waitIRq = 0x30; break; } default: break; } RC522_writeReg(CommIEnReg, irqEn|0x80); RC522_clearBitMask(CommIrqReg, 0x80); RC522_setBitMask(FIFOLevelReg, 0x80); RC522_writeReg(CommandReg, PCD_IDLE); for (i=0; i MAX_LEN) { n = MAX_LEN; } for (i=0; i