diff --git a/Mfrc522.c b/Mfrc522.c new file mode 100644 index 0000000..fafda50 --- /dev/null +++ b/Mfrc522.c @@ -0,0 +1,540 @@ +/* + 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 +*/ + +#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) +{ + 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) +{ + 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 C + Released into the public domain +*/ +#ifndef Mfrc522_h +#define Mfrc522_h + +/* + MFRC522 and Card specific defines. For the role of each define, please consult the datasheet. +*/ + +#define MAX_LEN 16 + +//MF522 - Commands +#define PCD_IDLE 0x00 +#define PCD_AUTHENT 0x0E +#define PCD_RECEIVE 0x08 +#define PCD_TRANSMIT 0x04 +#define PCD_TRANSCEIVE 0x0C +#define PCD_RESETPHASE 0x0F +#define PCD_CALCCRC 0x03 + +//Mifare_One - Commands +#define PICC_REQIDL 0x26 +#define PICC_REQALL 0x52 +#define PICC_ANTICOLL 0x93 +#define PICC_SElECTTAG 0x93 +#define PICC_AUTHENT1A 0x60 +#define PICC_AUTHENT1B 0x61 +#define PICC_READ 0x30 +#define PICC_WRITE 0xA0 +#define PICC_DECREMENT 0xC0 +#define PICC_INCREMENT 0xC1 +#define PICC_RESTORE 0xC2 +#define PICC_TRANSFER 0xB0 +#define PICC_HALT 0x50 + +//MF522 - Status +#define MI_OK 0 +#define MI_NOTAGERR 1 +#define MI_ERR 2 + +//MF522 - Registers +//Page 0:Command and Status +#define Reserved00 0x00 +#define CommandReg 0x01 +#define CommIEnReg 0x02 +#define DivlEnReg 0x03 +#define CommIrqReg 0x04 +#define DivIrqReg 0x05 +#define ErrorReg 0x06 +#define Status1Reg 0x07 +#define Status2Reg 0x08 +#define FIFODataReg 0x09 +#define FIFOLevelReg 0x0A +#define WaterLevelReg 0x0B +#define ControlReg 0x0C +#define BitFramingReg 0x0D +#define CollReg 0x0E +#define Reserved01 0x0F + +//Page 1:Command +#define Reserved10 0x10 +#define ModeReg 0x11 +#define TxModeReg 0x12 +#define RxModeReg 0x13 +#define TxControlReg 0x14 +#define TxAutoReg 0x15 +#define TxSelReg 0x16 +#define RxSelReg 0x17 +#define RxThresholdReg 0x18 +#define DemodReg 0x19 +#define Reserved11 0x1A +#define Reserved12 0x1B +#define MifareReg 0x1C +#define Reserved13 0x1D +#define Reserved14 0x1E +#define SerialSpeedReg 0x1F + +//Page 2:CFG +#define Reserved20 0x20 +#define CRCResultRegM 0x21 +#define CRCResultRegL 0x22 +#define Reserved21 0x23 +#define ModWidthReg 0x24 +#define Reserved22 0x25 +#define RFCfgReg 0x26 +#define GsNReg 0x27 +#define CWGsPReg 0x28 +#define ModGsPReg 0x29 +#define TModeReg 0x2A +#define TPrescalerReg 0x2B +#define TReloadRegH 0x2C +#define TReloadRegL 0x2D +#define TCounterValueRegH 0x2E +#define TCounterValueRegL 0x2F + +//Page 3:TestRegister +#define Reserved30 0x30 +#define TestSel1Reg 0x31 +#define TestSel2Reg 0x32 +#define TestPinEnReg 0x33 +#define TestPinValueReg 0x34 +#define TestBusReg 0x35 +#define AutoTestReg 0x36 +#define VersionReg 0x37 +#define AnalogTestReg 0x38 +#define TestDAC1Reg 0x39 +#define TestDAC2Reg 0x3A +#define TestADCReg 0x3B +#define Reserved31 0x3C +#define Reserved32 0x3D +#define Reserved33 0x3E +#define Reserved34 0x3F + +void RC522_init(int chipSelectPin, int NRSTPD); +void RC522_writeReg(unsigned char addr, unsigned char val); +unsigned char RC522_readReg(unsigned char addr); +void RC522_setBitMask(unsigned char reg, unsigned char mask); +void RC522_clearBitMask(unsigned char reg, unsigned char mask); +void RC522_antennaOn(void); +void RC522_antennaOff(void); +void RC522_setAntennaGain(unsigned char mask); +void RC522_reset(void); + +unsigned char RC522_request(unsigned char reqMode, unsigned char *TagType); +unsigned char RC522_toCard(unsigned char command, unsigned char *sendData, unsigned char sendLen, unsigned char *backData, unsigned int *backLen); +unsigned char RC522_anticoll(unsigned char *serNum); +void RC522_calculateCRC(unsigned char *pIndata, unsigned char len, unsigned char *pOutData); +unsigned char RC522_selectTag(unsigned char *serNum); +unsigned char RC522_auth(unsigned char authMode, unsigned char BlockAddr, unsigned char *Sectorkey, unsigned char *serNum); +void RC522_stopCrypto(); +unsigned char RC522_readBlock(unsigned char blockAddr, unsigned char *recvData); +unsigned char RC522_writeBlock(unsigned char blockAddr, unsigned char *writeData); +unsigned char RC522_halt(void); + +int _chipSelectPin; +int _NRSTPD; + + +#endif diff --git a/NFC.c b/NFC.c new file mode 100644 index 0000000..f5483e0 --- /dev/null +++ b/NFC.c @@ -0,0 +1,5 @@ +#include +#include "NFC.h" +#include "SPI2.h" +#include "Mfrc522.h" + diff --git a/NFC.h b/NFC.h new file mode 100644 index 0000000..b997490 --- /dev/null +++ b/NFC.h @@ -0,0 +1,7 @@ +/* + * NFC.c + * + * Created on: 22 mei 2020 + * Author: Yeti + */ + diff --git a/SPI2.h b/SPI2.h new file mode 100644 index 0000000..c888638 --- /dev/null +++ b/SPI2.h @@ -0,0 +1,38 @@ +#ifndef _SPI_H_INCLUDED +#define _SPI_H_INCLUDED + +#include +#include + +inline static void SPI_begin(); +inline static uint8_t SPI_transfer(uint8_t data); +inline static void SPI_end(); + +void SPI_begin(void) { + /* Configure P1.5, 1.6, 1.7 for SPI. */ + P1SEL |= (BIT5 | BIT6 | BIT7); + P1SEL2 |= (BIT5 | BIT6 | BIT7); + + /* Setup SPI on USCI B */ + UCB0CTL1 = (UCSSEL_2 | UCSWRST); // SMCLK + Reset + UCB0CTL0 = (UCCKPL | UCMSB | UCMST | UCSYNC); // 3-pin, 8-bit SPI master + UCB0BR0 = 8; // /8 + UCB0BR1 = 0; // + + UCB0CTL1 &= ~UCSWRST; // release USCI for operation +} + +uint8_t SPI_transfer(uint8_t data) { + UCB0TXBUF = data; // Setting TXBUF clears the TXIFG + + while(UCB0STAT & UCBUSY); // wait for SPI TX/RX to finish + + return UCB0RXBUF; // Reading clears RXIFG +} + +void SPI_end() +{ + UCB0CTL1 |= UCSWRST; // Put USCI in reset mode +} + +#endif