Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added esp8266 support #235

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
171 changes: 156 additions & 15 deletions MFRC522.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@
#include <Arduino.h>
#include <MFRC522.h>

#if defined (SPI_HAS_TRANSACTION)
static SPISettings mySPISettings;
#elif defined (__AVR__)
static uint8_t SPCRbackup;
static uint8_t mySPCR;
#endif

/////////////////////////////////////////////////////////////////////////////////////
// Functions for setting up the Arduino
/////////////////////////////////////////////////////////////////////////////////////
Expand All @@ -27,6 +34,10 @@ MFRC522::MFRC522( byte chipSelectPin, ///< Arduino pin connected to MFRC522's S
_resetPowerDownPin = resetPowerDownPin;
} // End constructor

#if defined(CORE_TEENSY) && !defined(__AVR__)
#define __AVR__
#endif

/////////////////////////////////////////////////////////////////////////////////////
// Basic interface functions for communicating with the MFRC522
/////////////////////////////////////////////////////////////////////////////////////
Expand All @@ -38,12 +49,31 @@ MFRC522::MFRC522( byte chipSelectPin, ///< Arduino pin connected to MFRC522's S
void MFRC522::PCD_WriteRegister( byte reg, ///< The register to write to. One of the PCD_Register enums.
byte value ///< The value to write.
) {
SPI.beginTransaction(SPISettings(SPI_CLOCK_DIV4, MSBFIRST, SPI_MODE0)); // Set the settings to work with SPI bus
#if defined (SPI_HAS_TRANSACTION)
SPI.beginTransaction(mySPISettings);
digitalWrite(_chipSelectPin, LOW); // Select slave
SPI.transfer(reg & 0x7E); // MSB == 0 is for writing. LSB is not used in address. Datasheet section 8.1.2.3.
SPI.transfer(value);
#elif defined (__AVR__)
SPCRbackup = SPCR;
SPCR = mySPCR;
digitalWrite(_chipSelectPin, LOW); // Select slave
SPI.transfer(reg & 0x7E); // MSB == 0 is for writing. LSB is not used in address. Datasheet section 8.1.2.3.
SPI.transfer(value);
SPCR = SPCRbackup;
// SPDR = c;
// while(!(SPSR & _BV(SPIF)));
#elif defined (__arm__)
SPI.setClockDivider(21); //4MHz
SPI.setDataMode(SPI_MODE0);
digitalWrite(_chipSelectPin, LOW); // Select slave
SPI.transfer(reg & 0x7E); // MSB == 0 is for writing. LSB is not used in address. Datasheet section 8.1.2.3.
SPI.transfer(value);
#endif
#if defined (SPI_HAS_TRANSACTION)
SPI.endTransaction();
#endif
digitalWrite(_chipSelectPin, HIGH); // Release slave again
SPI.endTransaction(); // Stop using the SPI bus
} // End PCD_WriteRegister()

/**
Expand All @@ -54,14 +84,37 @@ void MFRC522::PCD_WriteRegister( byte reg, ///< The register to write to. One o
byte count, ///< The number of bytes to write to the register
byte *values ///< The values to write. Byte array.
) {
SPI.beginTransaction(SPISettings(SPI_CLOCK_DIV4, MSBFIRST, SPI_MODE0)); // Set the settings to work with SPI bus
#if defined (SPI_HAS_TRANSACTION)
SPI.beginTransaction(mySPISettings);
digitalWrite(_chipSelectPin, LOW); // Select slave
SPI.transfer(reg & 0x7E); // MSB == 0 is for writing. LSB is not used in address. Datasheet section 8.1.2.3.
for (byte index = 0; index < count; index++) {
SPI.transfer(values[index]);
}
#elif defined (__AVR__)
SPCRbackup = SPCR;
SPCR = mySPCR;
digitalWrite(_chipSelectPin, LOW); // Select slave
SPI.transfer(reg & 0x7E); // MSB == 0 is for writing. LSB is not used in address. Datasheet section 8.1.2.3.
for (byte index = 0; index < count; index++) {
SPI.transfer(values[index]);
}
SPCR = SPCRbackup;
// SPDR = c;
// while(!(SPSR & _BV(SPIF)));
#elif defined (__arm__)
SPI.setClockDivider(21); //4MHz
SPI.setDataMode(SPI_MODE0);
digitalWrite(_chipSelectPin, LOW); // Select slave
SPI.transfer(reg & 0x7E); // MSB == 0 is for writing. LSB is not used in address. Datasheet section 8.1.2.3.
for (byte index = 0; index < count; index++) {
SPI.transfer(values[index]);
}
#endif
#if defined (SPI_HAS_TRANSACTION)
SPI.endTransaction();
#endif
digitalWrite(_chipSelectPin, HIGH); // Release slave again
SPI.endTransaction(); // Stop using the SPI bus
} // End PCD_WriteRegister()

/**
Expand All @@ -70,13 +123,31 @@ void MFRC522::PCD_WriteRegister( byte reg, ///< The register to write to. One o
*/
byte MFRC522::PCD_ReadRegister( byte reg ///< The register to read from. One of the PCD_Register enums.
) {
byte value;
SPI.beginTransaction(SPISettings(SPI_CLOCK_DIV4, MSBFIRST, SPI_MODE0)); // Set the settings to work with SPI bus
digitalWrite(_chipSelectPin, LOW); // Select slave
#if defined (SPI_HAS_TRANSACTION)
SPI.beginTransaction(mySPISettings);
digitalWrite(_chipSelectPin, LOW); // Select slave
SPI.transfer(0x80 | (reg & 0x7E)); // MSB == 1 is for reading. LSB is not used in address. Datasheet section 8.1.2.3.
byte value = SPI.transfer(0); // Read the value back. Send 0 to stop reading.
#elif defined (__AVR__)
SPCRbackup = SPCR;
SPCR = mySPCR;
digitalWrite(_chipSelectPin, LOW); // Select slave
SPI.transfer(0x80 | (reg & 0x7E)); // MSB == 1 is for reading. LSB is not used in address. Datasheet section 8.1.2.3.
value = SPI.transfer(0); // Read the value back. Send 0 to stop reading.
digitalWrite(_chipSelectPin, HIGH); // Release slave again
SPI.endTransaction(); // Stop using the SPI bus
byte value = SPI.transfer(0); // Read the value back. Send 0 to stop reading.
SPCR = SPCRbackup;
// SPDR = c;
// while(!(SPSR & _BV(SPIF)));
#elif defined (__arm__)
SPI.setClockDivider(21); //4MHz
SPI.setDataMode(SPI_MODE0);
digitalWrite(_chipSelectPin, LOW); // Select slave
SPI.transfer(0x80 | (reg & 0x7E)); // MSB == 1 is for reading. LSB is not used in address. Datasheet section 8.1.2.3.
byte value = SPI.transfer(0); // Read the value back. Send 0 to stop reading.
#endif
#if defined (SPI_HAS_TRANSACTION)
SPI.endTransaction();
#endif
digitalWrite(_chipSelectPin, HIGH); // Release slave again
return value;
} // End PCD_ReadRegister()

Expand All @@ -92,12 +163,13 @@ void MFRC522::PCD_ReadRegister( byte reg, ///< The register to read from. One o
if (count == 0) {
return;
}
//Serial.print(F("Reading ")); Serial.print(count); Serial.println(F(" bytes from register."));
byte address = 0x80 | (reg & 0x7E); // MSB == 1 is for reading. LSB is not used in address. Datasheet section 8.1.2.3.
byte index = 0; // Index in values array.
SPI.beginTransaction(SPISettings(SPI_CLOCK_DIV4, MSBFIRST, SPI_MODE0)); // Set the settings to work with SPI bus
count--;
// One read is performed outside of the loop
#if defined (SPI_HAS_TRANSACTION)
SPI.beginTransaction(mySPISettings);
digitalWrite(_chipSelectPin, LOW); // Select slave
count--; // One read is performed outside of the loop
SPI.transfer(address); // Tell MFRC522 which address we want to read
while (index < count) {
if (index == 0 && rxAlign) { // Only update bit positions rxAlign..7 in values[0]
Expand All @@ -117,8 +189,60 @@ void MFRC522::PCD_ReadRegister( byte reg, ///< The register to read from. One o
index++;
}
values[index] = SPI.transfer(0); // Read the final byte. Send 0 to stop reading.
digitalWrite(_chipSelectPin, HIGH); // Release slave again
SPI.endTransaction(); // Stop using the SPI bus
#elif defined (__AVR__)
SPCRbackup = SPCR;
SPCR = mySPCR;
digitalWrite(_chipSelectPin, LOW); // Select slave
SPI.transfer(address); // Tell MFRC522 which address we want to read
while (index < count) {
if (index == 0 && rxAlign) { // Only update bit positions rxAlign..7 in values[0]
// Create bit mask for bit positions rxAlign..7
byte mask = 0;
for (byte i = rxAlign; i <= 7; i++) {
mask |= (1 << i);
}
// Read value and tell that we want to read the same address again.
byte value = SPI.transfer(address);
// Apply mask to both current value of values[0] and the new data in value.
values[0] = (values[index] & ~mask) | (value & mask);
}
else { // Normal case
values[index] = SPI.transfer(address); // Read value and tell that we want to read the same address again.
}
index++;
}
values[index] = SPI.transfer(0); // Read the final byte. Send 0 to stop reading.
SPCR = SPCRbackup;
// SPDR = c;
// while(!(SPSR & _BV(SPIF)));
#elif defined (__arm__)
SPI.setClockDivider(21); //4MHz
SPI.setDataMode(SPI_MODE0);
digitalWrite(_chipSelectPin, LOW); // Select slave
SPI.transfer(address); // Tell MFRC522 which address we want to read
while (index < count) {
if (index == 0 && rxAlign) { // Only update bit positions rxAlign..7 in values[0]
// Create bit mask for bit positions rxAlign..7
byte mask = 0;
for (byte i = rxAlign; i <= 7; i++) {
mask |= (1 << i);
}
// Read value and tell that we want to read the same address again.
byte value = SPI.transfer(address);
// Apply mask to both current value of values[0] and the new data in value.
values[0] = (values[index] & ~mask) | (value & mask);
}
else { // Normal case
values[index] = SPI.transfer(address); // Read value and tell that we want to read the same address again.
}
index++;
}
values[index] = SPI.transfer(0); // Read the final byte. Send 0 to stop reading.
#endif
#if defined (SPI_HAS_TRANSACTION)
SPI.endTransaction();
#endif
digitalWrite(_chipSelectPin, HIGH); // Release slave again
} // End PCD_ReadRegister()

/**
Expand Down Expand Up @@ -195,6 +319,23 @@ void MFRC522::PCD_Init() {
// Set the resetPowerDownPin as digital output, do not reset or power down.
pinMode(_resetPowerDownPin, OUTPUT);

#if defined (SPI_HAS_TRANSACTION)
SPI.begin();
mySPISettings = SPISettings(10000000, MSBFIRST, SPI_MODE0);
#elif defined (__AVR__)
SPCRbackup = SPCR;
SPI.begin();
SPI.setClockDivider(SPI_CLOCK_DIV4);
SPI.setDataMode(SPI_MODE0);
mySPCR = SPCR; // save our preferred state
//Serial.print("mySPCR = 0x"); Serial.println(SPCR, HEX);
SPCR = SPCRbackup; // then restore
#elif defined (__SAM3X8E__)
SPI.begin();
SPI.setClockDivider(21); //4MHz
SPI.setDataMode(SPI_MODE0);
#endif

if (digitalRead(_resetPowerDownPin) == LOW) { //The MFRC522 chip is in power down mode.
digitalWrite(_resetPowerDownPin, HIGH); // Exit power down mode. This triggers a hard reset.
// Section 8.8.2 in the datasheet says the oscillator start-up time is the start up time of the crystal + 37,74�s. Let us be generous: 50ms.
Expand Down
27 changes: 24 additions & 3 deletions MFRC522.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,18 @@
#include <Arduino.h>
#include <SPI.h>

#if defined(__SAM3X8E__)
#include <include/pio.h>
#define PROGMEM
#define pgm_read_byte(addr) (*(const unsigned char *)(addr))
#define pgm_read_word(addr) (*(const unsigned short *)(addr))
typedef unsigned char prog_uchar;
#elif defined(__AVR__)
#include <avr/pgmspace.h>
#elif defined(ESP8266)
#include <pgmspace.h>
#endif

// Firmware data for self-test
// Reference values based on firmware version
// Hint: if needed, you can remove unused self-test data to save flash memory
Expand Down Expand Up @@ -322,7 +334,7 @@ class MFRC522 {
// Functions for setting up the Arduino
/////////////////////////////////////////////////////////////////////////////////////
MFRC522();
MFRC522(byte chipSelectPin, byte resetPowerDownPin);
MFRC522(byte chipSelectPin, byte resetPowerDownPin=-1);

/////////////////////////////////////////////////////////////////////////////////////
// Basic interface functions for communicating with the MFRC522
Expand Down Expand Up @@ -408,9 +420,18 @@ class MFRC522 {
bool PICC_ReadCardSerial();

private:
byte _chipSelectPin; // Arduino pin connected to MFRC522's SPI slave select input (Pin 24, NSS, active low)
byte _resetPowerDownPin; // Arduino pin connected to MFRC522's reset and power down input (Pin 6, NRSTPD, active low)
//byte _chipSelectPin; // Arduino pin connected to MFRC522's SPI slave select input (Pin 24, NSS, active low)
//byte _resetPowerDownPin; // Arduino pin connected to MFRC522's reset and power down input (Pin 6, NRSTPD, active low)
StatusCode MIFARE_TwoStepHelper(byte command, byte blockAddr, long data);

#if defined(__AVR__) || defined(CORE_TEENSY)
uint8_t _chipSelectPin,_resetPowerDownPin;
#elif defined(__arm__)
uint32_t _chipSelectPin,_resetPowerDownPin;
#elif defined(ESP8266)
uint32_t _chipSelectPin,_resetPowerDownPin;
#endif

};

#endif