MFRC522 Driver¶
Driver for the MFRC522 module.
This is a driver for the MFRC522 Mifare and NTAG frontend. It supports the MFRC522 chip connected over various interfaces. It exports an Pcd object for use by other layers.
Note: This driver requires the EXT driver to be enabled and configured with non-const EXTConfig strcture (as opposed to one documented by function extStart)!
This driver invokes the extSetChannelMode function, see its docs for explanation.
Defines
-
MFRC522_USE_SPI¶ Enables SPI support.
- Note
- Disabling this option saves both code and data space.
-
MFRC522_USE_I2C¶ Enables I2C support.
- Note
- Disabling this option saves both code and data space.
-
MFRC522_USE_UART¶ Enables UART support.
- Note
- Disabling this option saves both code and data space.
-
MFRC522_MAX_DEVICES¶ Maximum number of simultaneously active devices this driver should handle.
- Note
- Lowering this value saves data space and increases driver performance.
Functions
-
void
mfrc522Init(void)¶ Initializes the MFRC522 driver.
- Note
- This function is called implicitly by halCustomInit, no need to call it explicitly.
-
void
mfrc522ObjectInitSPI(Mfrc522Driver *mdp, SPIDriver *spip)¶ Initializes the driver object for a MFRC522 module connected over the SPI.
- Parameters
mdp: Uninitialized driver object.spip: Initialized and started SPI driver object.
-
void
mfrc522ObjectInitI2C(Mfrc522Driver *mdp, I2CDriver *i2cp)¶ Initializes the driver object for a MFRC522 module connected over the I2C.
- Note
- Not yet implemented!
- Parameters
mdp: Uninitialized driver object.i2cp: Initialized and started I2C driver object
-
void
mfrc522ObjectInitSerial(Mfrc522Driver *mdp, SerialDriver *sdp)¶ Initializes the driver object for a MFRC522 module connected over the Serial.
- Note
- Not yet implemented!
- Parameters
mdp: Uninitialized driver object.sdp: Initialized and started Serial driver object
-
void
mfrc522Start(Mfrc522Driver *mdp, const Mfrc522Config *config)¶ Starts the MFRC522 module.
This function powers up, soft-resets the MFRC522 module, initializes, configures it and register is for use with this driver. It also reconfigures the provided Ext driver and register its own interrupt handler to handle interrupts on channel config->interrupt_channel.
- Parameters
mdp: Initialized driver objectconfig: Configuration to apply
-
void
mfrc522Reconfig(Mfrc522Driver *mdp, const Mfrc522Config *config)¶ Reconfigures the MFRC522 module without resetting it.
This function reprograms control registers of the MFRC522 module without resetting it, which is useful for hot-swapping MFRC522-specific config options during the module run-time.
This function won’t reconfig the following options:
EXTDriver *extpexpchannel_t interrupt_channelvoid *reset_line
The only way to change these is to stop and restart the module.
- Parameters
mdp: Started driver objectconfig: Configuration to apply
-
void
mfrc522Stop(Mfrc522Driver *mdp)¶ Stops the MFRC522 module.
Unregisters this module from this driver and powers it down.
- Parameters
mdp: Started driver object
-
struct
Mfrc522Config¶ - #include <hal_mfrc522.h>
Config options for the MFRC522 module.
In order for the driver to function properly you have to specify:
EXTDriver *extpexpchannel_t interrupt_channelvoid *reset_line
Rest of these options are intended for advanced configuration of the module if you have special needs, otherwise default values are just fine.
If you need to modify something consult the MFRC522 Datasheet.
Public Types
-
enum
driver_input_select_t¶ Selects the input of drivers TX1 and TX2.
Default: MFRC522_DRSEL_MPE
MFRC522 Datasheet page 51
Values:
-
MFRC522_DRSEL_3STATE= 0b00¶ 3-state mode during soft powerdown
-
MFRC522_DRSEL_MPE= 0b01¶ modulation signal (envelope) from the internal encoder, Miller pulse encoded
-
MFRC522_DRSEL_MFIN= 0b10¶ modulation signal (envelope) from pin MFIN
-
MFRC522_DRSEL_HIGH= 0b11¶ HIGH; the HIGH level depends on the setting of bits InvTx1RFOn/InvTx1RFOff and InvTx2RFOn/InvTx2RFOff
-
-
enum
mfout_select_t¶ Selects the input for pin MFOUT.
Default: MFRC522_MFSEL_3STATE
MFRC522 Datasheet page 52
Values:
-
MFRC522_MFSEL_3STATE= 0b0000¶ 3-state
-
MFRC522_MFSEL_LOW= 0b0001¶ LOW.
-
MFRC522_MFSEL_HIGH= 0b0010¶ HIGH.
-
MFRC522_MFSEL_TBUS= 0b0011¶ test bus signal as defined by the test_bus_bit_sel
-
MFRC522_MFSEL_MPE= 0b0100¶ modulation signal (envelope) from the internal encoder, Miller pulse encoded
-
MFRC522_MFSEL_SSTRT= 0b0101¶ serial data stream to be transmitted, data stream before Miller encoder
-
MFRC522_MFSEL_SSTRR= 0b0111¶ serial data stream received, data stream after Manchester decoder
-
-
enum
cl_uart_in_sel_t¶ Selects the input of the contactless UART.
Default: MFRC522_UINSEL_ANALOG
MFRC522 Datasheet page 52
Values:
-
MFRC522_UINSEL_LOW= 0b00¶ constant LOW
-
MFRC522_UINSEL_MAN_MFIN= 0b01¶ Manchester with subcarrier from pin MFIN
-
MFRC522_UINSEL_ANALOG= 0b10¶ modulated signal from the internal analog module, default
-
MFRC522_UINSEL_NRZ_MFIN= 0b11¶ NRZ coding without subcarrier from pin MFIN which is only valid for transfer speeds above 106 kBd
-
Public Members
-
EXTDriver *
extp¶ EXT driver to use for handling MFRC522-issued interrupts
-
expchannel_t
interrupt_channel¶ EXT channel to which the IRQ pin (and only the IRQ pin) of the MFRC522 is connected.
-
void *
reset_line¶ PAL line, which when set low resets the connected MFRC522
-
bool
MFIN_polarity¶ Defines polarity of pin MFIN.
true: MFIN is active HIGH false: MFIN is active LOW
Default: true
MFRC522 Datasheet page 48
-
bool
inverse_modulation¶ Modulation of transmitted data should be inverted.
Default: false
MFRC522 Datasheet page 49
-
uint8_t
tx_control_reg¶ Value of the transmission control register.
Default: 0x80
MFRC522 Datasheet page 50
-
Mfrc522Config::driver_input_select_t
driver_input_select¶
-
Mfrc522Config::mfout_select_t
mfout_select¶
-
Mfrc522Config::cl_uart_in_sel_t
cl_uart_in_sel¶
-
uint8_t
min_rx_signal_strength¶ Minimum signal strength which will be accepted by the decoder.
Only 4 lowest bits are taken into account.
Default: 8
MFRC522 Datasheet page 53
-
uint8_t
min_rx_collision_level¶ Minimum collision signal strength.
Minimum signal strength at the decoder input that must be reached by the weaker half-bit of the Manchester encoded signal to generate a bit-collision relative to the amplitude of the stronger half-bit.
Only 3 lowest bits are taken into account.
Default: 4
MFRC522 Datasheet page 53
-
uint8_t
demod_reg¶ Demodulator settings.
Default: 0x4D
MFRC522 Datasheet page 53
-
Mfrc522Config::receiver_gain_t
receiver_gain¶
-
uint8_t
transmit_power_n¶ Conductance of the output n-driver (CWGsN) which can be used to regulate the output power.
Default: 8
MFRC522 Datasheet page 59
-
uint8_t
modulation_index_n¶ Conductance of the output n-driver (ModGsN) which can be used to regulate the modulation index.
Default: 8
MFRC522 Datasheet page 59
-
uint8_t
transmit_power_p¶ Conductance of the output p-driver (CWGsP) which can be used to regulate the output power.
Default: 32
MFRC522 Datasheet page 60
-
uint8_t
modulation_index_p¶ Conductance of the output n-driver (ModGsP) which can be used to regulate the modulation index.
Default: 32
MFRC522 Datasheet page 60
-
struct
Mfrc522Driver¶ - #include <hal_mfrc522.h>
Structure representing a MFRC522 driver.
For functions expecting a Pcd object use the
pcdmemeber of this structure. Otherwise don’t modify any of these values.Public Types
Public Members
-
pcdstate_t
state¶ Driver state
-
Mfrc522Driver::mfrc522_conntype_t
connection_type¶
-
union Mfrc522Driver::iface_u
iface¶
-
EXTDriver *
extp¶ EXT driver to use for handling MFRC522-issued interrupts
-
expchannel_t
interrupt_channel¶ EXT channel to which the IRQ pin is connected
-
void *
reset_line¶ PAL line, which when set low resets the connected MFRC522
-
const Mfrc522Config *
current_config¶ Lastly applied config
-
volatile bool
interrupt_pending¶ Interrupt is pending for this reader
-
thread_reference_t
tr¶ Thread reference the reader will sleep on
-
uint8_t
response[64]¶ Response buffer
-
uint8_t
resp_last_valid_bits¶ Number of last valid bits in the response
-
uint8_t
resp_length¶ Response length
-
uint8_t
resp_read_bytes¶ Number of already retreived response bytes
-
mutex_t
mutex¶ Mutex for mutual access
-
union
iface_u¶ - #include <hal_mfrc522.h>
Pointer to a given interface driver.
-
pcdstate_t
Internal functioning of the driver¶
Although most of the drivers in the HAL are contained in one file, the MFRC522 driver was becoming unreadable, so I’ve split it between several files.
src/hal_mfrc522/hal_mfrc522_internal.hheader contains internal constants and internal documentation. It is not supposed to be used by application using this driver.src/hal_mfrc522/hal_mfrc522.cis the main driver file. It contains MFRC522-specific initialization and configuration functions. It also contains the interrupt handler only purpose of which is to wake up a sleeping thread.src/hal_mfrc522/hal_mfrc522_ext_api.ccontains implementation of extended features. See hal_abstract_iso14443_pcd_ext.h.src/hal_mfrc522/hal_mfrc522_llcom.ccontains low-level communication routines for reading and writing registers of the MFRC522 over various connection interfaces.src/hal_mfrc552/hal_mfrc522_pcd_api.ccontains implementation of Pcd API functions for MFRC522.
Primary goals
This driver should provide easy-to-use synchronous API to drivers of higher protocol layers while being efficient and friendly to other threads (it suspends the calling thread while it’s waiting for data).
Initialization and configuration functions handling global objects of this driver must be thread-safe.
This driver does not guarantee thread safety if single Mfrc522Driver file is used simultaneously by multiple threads. Those threads should call pcdAcquireBus and pcdReleaseBus to achiveve mutual exclusion. However, it is safe to use different Mfrc522Driver objects from different threads simultaneously.
This driver should be as universal as possible. This is the reason for (over?)complicated configuration structure. It allows you to, when you know what are you doing, configure the MFRC522 modulee for your specific use-case (like using an external modulator with the chip). It is also easy to use, since default values work out-of-the box with the typical use-case (like the RFID-RC522 chinese module).
Thread suspend and interrupt handling
Each time this driver waits for the action of the reader it suspends the calling thread, to allow other threads to run.
MFRC522 has a mechanism of waking up the host using its IRQ pin. Host can conigure which interrupts propagate to the interrupt pin, and later figure out which interrupt occured by reading a specific register.
This driver uses the Ext driver provided by ChibiOS to handle these interrupts. It registers its own interrupt handler, the same for each interrupt channel. However, in the current version the Ext driver doesn’t allow passing custom parameters to the handler function, therefore when an interrupt occurs we only know which channel it came from. Then we may wake up all sleeping driver threads and let every thread check whether the interrupt is intended for it. This is problemating due to race conditions, necessity of events buffering, etc. Instead, we have imposed limitation that each interrupt channel can have only one reader (and nothing else than the reader) attached to it. Therefore when an interrupt occures by knowing the interrupt channel we can wake up the proper thread.
In addition this wake-up is buffered if the thread couldn’t be suspended in time.
Anticollision detection
TODO