Skip to content

Commit

Permalink
* implemented reset timeout in mfrc522
Browse files Browse the repository at this point in the history
  • Loading branch information
matej committed Nov 6, 2014
1 parent 1e70c1e commit 56e3c7a
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 54 deletions.
39 changes: 24 additions & 15 deletions mfrc522.c
Expand Up @@ -26,9 +26,9 @@ void MFRC522_init() {
}


/////////////////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------------
// Basic interface functions for communicating with the MFRC522
/////////////////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------------

/**
* Writes a byte to the specified register in the MFRC522 chip.
Expand Down Expand Up @@ -170,21 +170,23 @@ byte PCD_CalculateCRC( byte *data, ///< In: Pointer to the data to transfer to
}


/////////////////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------------
// Functions for manipulating the MFRC522
/////////////////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------------

/**
* Initializes the MFRC522 chip.
*/
void PCD_Init() {
byte PCD_Init() {
if ( 0 == (MFRC522_RST_PORT & _BV(MFRC522_RST_BIT)) ) { //The MFRC522 chip is in power down mode.
MFRC522_RST_PORT |= _BV(MFRC522_RST_BIT); // 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.
_delay_ms(50);
}
else { // Perform a soft reset
PCD_Reset();
if( STATUS_OK != PCD_Reset() ) {
return STATUS_TIMEOUT;
}
}
// When communicating with a PICC we need a timeout if something goes wrong.
// f_timer = 13.56 MHz / (2*TPreScaler+1) where TPreScaler = [TPrescaler_Hi:TPrescaler_Lo].
Expand All @@ -197,21 +199,28 @@ void PCD_Init() {
PCD_WriteRegister(TxASKReg, 0x40); // Default 0x00. Force a 100 % ASK modulation independent of the ModGsPReg register setting
PCD_WriteRegister(ModeReg, 0x3D); // Default 0x3F. Set the preset value for the CRC coprocessor for the CalcCRC command to 0x6363 (ISO 14443-3 part 6.2.4)
PCD_AntennaOn(); // Enable the antenna driver pins TX1 and TX2 (they were disabled by the reset)

return STATUS_OK;
}

/**
* Performs a soft reset on the MFRC522 chip and waits for it to be ready again.
*/
void PCD_Reset() {
byte PCD_Reset() {
PCD_WriteRegister(CommandReg, PCD_SoftReset); // Issue the SoftReset command.
// The datasheet does not mention how long the SoftRest command takes to complete.
// But the MFRC522 might have been in soft power-down mode (triggered by bit 4 of CommandReg)
// 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.
_delay_ms(50);
// Wait for the PowerDown bit in CommandReg to be cleared
word i = 5000;
while (PCD_ReadRegister(CommandReg) & (1<<4)) {
// PCD still restarting - unlikely after waiting 50ms, but better safe than sorry.
if( --i == 0 ) {
return STATUS_TIMEOUT;
}
}
return STATUS_OK;
}

/**
Expand All @@ -225,9 +234,9 @@ void PCD_AntennaOn() {
}
}

/////////////////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------------
// Functions for communicating with PICCs
/////////////////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------------

/**
* Executes the Transceive command.
Expand Down Expand Up @@ -659,9 +668,9 @@ byte PICC_HaltA() {
}


/////////////////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------------
// Functions for communicating with MIFARE PICCs
/////////////////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------------

/**
* Executes the MFRC522 MFAuthent command.
Expand Down Expand Up @@ -921,9 +930,9 @@ byte MIFARE_Transfer( byte blockAddr ///< The block (0-0xff) number.
}
*/

/////////////////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------------
// Support functions
/////////////////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------------

/**
* Wrapper for MIFARE protocol communication.
Expand Down Expand Up @@ -1342,9 +1351,9 @@ void MIFARE_SetAccessBits( byte *accessBitBuffer, ///< Pointer to byte 6, 7 and
}
*/

/////////////////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------------
// Convenience functions - does not add extra functionality
/////////////////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------------

/**
* Returns true if a PICC responds to PICC_CMD_REQA.
Expand Down
78 changes: 39 additions & 39 deletions mfrc522.h
Expand Up @@ -17,7 +17,7 @@
DivIEnReg = 0x03 << 1, // enable and disable interrupt request control bits
ComIrqReg = 0x04 << 1, // interrupt request bits
DivIrqReg = 0x05 << 1, // interrupt request bits
ErrorReg = 0x06 << 1, // error bits showing the error status of the last command executed
ErrorReg = 0x06 << 1, // error bits showing the error status of the last command executed
Status1Reg = 0x07 << 1, // communication status bits
Status2Reg = 0x08 << 1, // receiver and transmitter status bits
FIFODataReg = 0x09 << 1, // input and output of 64 byte FIFO buffer
Expand All @@ -27,10 +27,10 @@
BitFramingReg = 0x0D << 1, // adjustments for bit-oriented frames
CollReg = 0x0E << 1, // bit position of the first bit-collision detected on the RF interface
// 0x0F // reserved for future use

// Page 1:Command
// 0x10 // reserved for future use
ModeReg = 0x11 << 1, // defines general modes for transmitting and receiving
ModeReg = 0x11 << 1, // defines general modes for transmitting and receiving
TxModeReg = 0x12 << 1, // defines transmission data rate and framing
RxModeReg = 0x13 << 1, // defines reception data rate and framing
TxControlReg = 0x14 << 1, // controls the logical behavior of the antenna driver pins TX1 and TX2
Expand All @@ -45,7 +45,7 @@
MfRxReg = 0x1D << 1, // controls some MIFARE communication receive parameters
// 0x1E // reserved for future use
SerialSpeedReg = 0x1F << 1, // selects the speed of the serial UART interface

// Page 2: Configuration
// 0x20 // reserved for future use
CRCResultRegH = 0x21 << 1, // shows the MSB and LSB values of the CRC calculation
Expand All @@ -54,7 +54,7 @@
ModWidthReg = 0x24 << 1, // controls the ModWidth setting?
// 0x25 // reserved for future use
RFCfgReg = 0x26 << 1, // configures the receiver gain
GsNReg = 0x27 << 1, // selects the conductance of the antenna driver pins TX1 and TX2 for modulation
GsNReg = 0x27 << 1, // selects the conductance of the antenna driver pins TX1 and TX2 for modulation
CWGsPReg = 0x28 << 1, // defines the conductance of the p-driver output during periods of no modulation
ModGsPReg = 0x29 << 1, // defines the conductance of the p-driver output during periods of modulation
TModeReg = 0x2A << 1, // defines settings for the internal timer
Expand All @@ -63,7 +63,7 @@
TReloadRegL = 0x2D << 1,
TCounterValueRegH = 0x2E << 1, // shows the 16-bit timer value
TCounterValueRegL = 0x2F << 1,

// Page 3:Test Registers
// 0x30 // reserved for future use
TestSel1Reg = 0x31 << 1, // general test signal configuration
Expand All @@ -82,7 +82,7 @@
// 0x3E // reserved for production tests
// 0x3F // reserved for production tests
};

// MFRC522 comands. Described in chapter 10 of the datasheet.
enum PCD_Command {
PCD_Idle = 0x00, // no action, cancels current command execution
Expand All @@ -96,7 +96,7 @@
PCD_MFAuthent = 0x0E, // performs the MIFARE standard authentication as a reader
PCD_SoftReset = 0x0F // resets the MFRC522
};

// Commands sent to the PICC.
enum PICC_Command {
// The commands used by the PCD to manage communication with several PICCs (ISO 14443-3, Type A, section 6.4)
Expand All @@ -122,7 +122,7 @@
// The PICC_CMD_MF_READ and PICC_CMD_MF_WRITE can also be used for MIFARE Ultralight.
PICC_CMD_UL_WRITE = 0xA2 // Writes one 4 byte page to the PICC.
};

// MIFARE constants that does not fit anywhere else
enum MIFARE_Misc {
MF_ACK = 0xA, // The MIFARE Classic uses a 4 bit ACK/NAK. Any other value than 0xA is NAK.
Expand All @@ -132,7 +132,7 @@
// PICC types we can detect. Remember to update PICC_GetTypeName() if you add more.
enum PICC_Type {
PICC_TYPE_UNKNOWN = 0,
PICC_TYPE_ISO_14443_4 = 1, // PICC compliant with ISO/IEC 14443-4
PICC_TYPE_ISO_14443_4 = 1, // PICC compliant with ISO/IEC 14443-4
PICC_TYPE_ISO_18092 = 2, // PICC compliant with ISO/IEC 18092 (NFC)
PICC_TYPE_MIFARE_MINI = 3, // MIFARE Classic protocol, 320 bytes
PICC_TYPE_MIFARE_1K = 4, // MIFARE Classic protocol, 1KB
Expand All @@ -142,7 +142,7 @@
PICC_TYPE_TNP3XXX = 8, // Only mentioned in NXP AN 10833 MIFARE Type Identification Procedure
PICC_TYPE_NOT_COMPLETE = 255 // SAK indicates UID is not complete.
};

// Return codes from the functions in this class. Remember to update GetStatusCodeName() if you add more.
enum StatusCode {
STATUS_OK = 1, // Success
Expand All @@ -155,34 +155,34 @@
STATUS_CRC_WRONG = 8, // The CRC_A does not match
STATUS_MIFARE_NACK = 9 // A MIFARE PICC responded with NAK.
};

// A struct used for passing the UID of a PICC.
typedef struct {
byte size; // Number of bytes in the UID. 4, 7 or 10.
byte uidByte[10];
byte sak; // The SAK (Select acknowledge) byte returned from the PICC after successful selection.
} Uid;

// A struct used for passing a MIFARE Crypto1 key
typedef struct {
byte keyByte[MF_KEY_SIZE];
} MIFARE_Key;

// Member variables
//Uid uid; // Used by PICC_ReadCardSerial().

// Size of the MFRC522 FIFO
//static const byte FIFO_SIZE = 64; // The FIFO is 64 bytes.
/////////////////////////////////////////////////////////////////////////////////////

//-----------------------------------------------------------------------------------
// Functions for setting up the Arduino
/////////////////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------------
void MFRC522_init(void);
void setSPIConfig(void);
/////////////////////////////////////////////////////////////////////////////////////

//-----------------------------------------------------------------------------------
// Basic interface functions for communicating with the MFRC522
/////////////////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------------
void PCD_WriteRegister(byte reg, byte value);
void PCD_WriteRegister2(byte reg, byte count, byte *values);
byte PCD_ReadRegister(byte reg);
Expand All @@ -192,28 +192,28 @@
void PCD_ClearRegisterBitMask(byte reg, byte mask);
byte PCD_CalculateCRC(byte *data, byte length, byte *result);

/////////////////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------------
// Functions for manipulating the MFRC522
/////////////////////////////////////////////////////////////////////////////////////
void PCD_Init(void);
void PCD_Reset(void);
//-----------------------------------------------------------------------------------
byte PCD_Init(void);
byte PCD_Reset(void);
void PCD_AntennaOn(void);
/////////////////////////////////////////////////////////////////////////////////////

//-----------------------------------------------------------------------------------
// Functions for communicating with PICCs
/////////////////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------------
byte PCD_TransceiveData(byte *sendData, byte sendLen, byte *backData, byte *backLen, byte *validBits, byte rxAlign, bool checkCRC);
byte PCD_CommunicateWithPICC(byte command, byte waitIRq, byte *sendData, byte sendLen, byte *backData, byte *backLen, byte *validBits, byte rxAlign, bool checkCRC);

byte PICC_RequestA(byte *bufferATQA, byte *bufferSize);
byte PICC_WakeupA(byte *bufferATQA, byte *bufferSize);
byte PICC_REQA_or_WUPA( byte command, byte *bufferATQA, byte *bufferSize);
byte PICC_REQA_or_WUPA( byte command, byte *bufferATQA, byte *bufferSize);
byte PICC_Select(Uid *uid, byte validBits);
byte PICC_HaltA(void);
/////////////////////////////////////////////////////////////////////////////////////

//-----------------------------------------------------------------------------------
// Functions for communicating with MIFARE PICCs
/////////////////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------------
byte PCD_Authenticate(byte command, byte blockAddr, MIFARE_Key *key, Uid *uid);
void PCD_StopCrypto1(void);
byte MIFARE_Read(byte blockAddr, byte *buffer, byte *bufferSize);
Expand All @@ -223,10 +223,10 @@
byte MIFARE_Restore(byte blockAddr);
byte MIFARE_Transfer(byte blockAddr);
byte MIFARE_Ultralight_Write(byte page, byte *buffer, byte bufferSize);
/////////////////////////////////////////////////////////////////////////////////////

//-----------------------------------------------------------------------------------
// Support functions
/////////////////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------------
byte PCD_MIFARE_Transceive( byte *sendData, byte sendLen, bool acceptTimeout);
const char *GetStatusCodeName(byte code);
byte PICC_GetType(byte sak);
Expand All @@ -236,12 +236,12 @@
void PICC_DumpMifareClassicSectorToSerial(Uid *uid, MIFARE_Key *key, byte sector);
void PICC_DumpMifareUltralightToSerial(void);
void MIFARE_SetAccessBits(byte *accessBitBuffer, byte g0, byte g1, byte g2, byte g3);
/////////////////////////////////////////////////////////////////////////////////////

//-----------------------------------------------------------------------------------
// Convenience functions - does not add extra functionality
/////////////////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------------
bool PICC_IsNewCardPresent(void);
bool PICC_ReadCardSerial(Uid* uid);
bool PICC_ReadCardSerial(Uid* uid);

/*
private:
Expand Down

0 comments on commit 56e3c7a

Please sign in to comment.