ISO/IEC 14443 PCD Abstract Class¶
Abstract ISO14443 Proximity Coupling Device (card reader) driver interface.
This header defines an abstract interface useful to access generic ISO14443-compliant PCDs (contactless card readers) in a standardized way.
Design
This header provides communication interface with the PCD (Proximity Coupling Device) as described in ISO/IEC 14443-3. This standard defines communication with 2 different card types: A and B. The naming convention is ‘A’-related functions end with A, B-related functions end with B, common functions end with AB.
Currently, API for part A is fully designed, API for part B will be added later.
Communication between the PCD and the PICC consists of sending and receiving frames. The frames are transmitted in pairs, PCD to PICC followed by PICC to PCD.
Part A of the standard defines transmission of 3 different types of frames:
- Short frame: transmits 7 bits.
- Standard frame: Used for data exchange and can transmit several bytes with parity.
- Bit oriented anticollision frame: 7 byte long frame spit anywhere into two parts. First part is transmitted by the PCD, second part is added by the PICC. It is used during bit-oriented anticollision loop.
ISO/IEC 14443-3 specifies different communication methods (different modulation type / index, different encoding) for part A and B. This driver should support setting these modes, various other communication parameters within these modes as defined by the standard, and should also be able to advertise its capabilities. Communication speeds can’t be arbitrary and are defined by ISO/IEC 14443-4 as $ 1 etu = 128 / (D x fc) $, where etu is the elementary time unit (duration of one bit), fc is the carrier frequency (defined in ISO/IEC 14443-2 to be $ 13.56MHz \pm 7kHz $) and D is an integer divisor, which may be 1, 2, 4 or 8. This paradoxically means that increasing the divisor also increases the communication speed.
The readers also usually support a number of extended features, not covered by the ISO/IEC 14443 standard. For example, the MFRC522 is able to perform a Mifare authentication using its crypto unit, or a self-test. Upper layers which know how to use these extended features should have access to them, but they should not clutter the main API. That is why each extended feature will have a globally assigned number (in the global abstract header). Then other layers could use these numbers to invoke the extended feature, passing in a “parameter structure”. These structures are also defined globally in the abstract header (although in a different file) to allow their re-use.
Often PCDs have a maximum data size they can handle at once. ISO/IEC 14443 standard takes this into account and defines “protocol chaining”, a method to send large data units in multiple smaller frames. The upper library handles this, but for it to know whether to use chaining the PCD must be able to report maximum frame size it can handle.
Driver state diagram
This abstract class presumes a driver with state. The following diagram illustrates available states (see pcdstate_t) and transitions between them.
Some functions may be called only in specific states, this is indicated in documentation of each function. Calling a function in an invalid state will be caught by assertion (if assertions are enabled).
Thread safety
Implementation of this API does not have to guarantee that it is thread-safe. If you need API access from multiple threads use pcdAcquireBus and pcdReleaseBus APIs in order to get exclusive access.
Macro functions (Pcd)
Convenience macros for easy calling of ‘member functions’
-
pcdGetStateAB(ip)¶
-
pcdActivateRFAB(ip)¶
-
pcdDeactivateRFAB(ip)¶
-
pcdGetSupportedParamsAB(ip)¶
-
pcdSetParamsAB(ip, rx_spd, tx_spd, mode, txcrc, rxcrc)¶
-
pcdTransceiveShortFrameA(ip, data, resp_len_p, timeout_us)¶
-
pcdTransceiveStandardFrameA(ip, data, size, resp_len_p, timeout_us)¶
-
pcdTransceiveAnticollFrameA(ip, data, size, n_last_bits, align_rx, resp_len_p, timeout_us)¶
-
pcdGetRespLengthA(ip)¶
-
pcdGetRespAB(ip, buf_size, buffer, size_copied, n_last_bits_p)¶
-
pcdAcquireBus(ip)¶
-
pcdReleaseBus(ip)¶
-
pcdSupportsExtFeature(ip, feature)¶
-
pcdCallExtFeature(ip, feature, params, result)¶
Enums
-
enum
pcdstate_t¶ States of the driver state machine.
Values:
-
PCD_UNINT¶ Not initialized
-
PCD_STOP¶ Initialized, not active.
-
PCD_RF_OFF¶ RF Field is off
-
PCD_READY¶ Ready to transmit
-
PCD_ACTIVE¶ Transceiving
-
-
enum
pcdresult_t¶ Operation result codes.
Values:
-
PCD_OK¶ Command completed successfully
-
PCD_BAD_STATE¶ Command not possible in this state
-
PCD_UNSUPPORTED¶ This PCD does not support this command
-
PCD_OK_COLLISION¶ Command OK, but received collision
-
PCD_OK_TIMEOUT¶ Command OK, but card did not respond
-
PCD_ERROR¶ An unspecified error has occured
-
PCD_TX_ERROR¶ Transmission error
-
PCD_RX_ERROR¶ Receiver error (such as bad parity)
-
PCD_RX_OVERFLOW¶ A receive buffer has overflown
-
PCD_TX_OVERFLOW¶ This message won’t fit to tx buffer
-
-
enum
pcdspeed_rx_t¶ Receive speed keys for speed bitmask.
Values:
-
PCD_RX_SPEED_106= 1¶
-
PCD_RX_SPEED_212= 2¶
-
PCD_RX_SPEED_424= 4¶
-
PCD_RX_SPEED_848= 8¶
-
-
enum
pcdspeed_tx_t¶ Transmit speed keys for speed bitmask.
Values:
-
PCD_TX_SPEED_106= 16¶
-
PCD_TX_SPEED_212= 32¶
-
PCD_TX_SPEED_424= 64¶
-
PCD_TX_SPEED_848= 128¶
-
-
enum
pcdfeature_t¶ List of possible extended features.
For each extended feature 2 structures are defined in file hal_abstract_iso14443_pcd_ext.h. The first is a param strucure, the second is a response structure.
Values:
-
PCD_EXT_SELFTEST¶ Perform a self-test
-
PCD_EXT_CALCULATE_CRC_A¶ Calculate type-A CRC
-
PCD_EXT_CALCULATE_CRC_B¶ Calculate type-B CRC
-
PCD_EXT_MIFARE_AUTH¶ Perform a Mifare auth and turn on crypto
-
-
struct
PcdSParams¶ - #include <hal_abstract_iso14443_pcd.h>
Structure of communuication parameters supported by the PCD.
Public Members
-
uint8_t
supported_speedsA¶ Bit mask of supported tx/rx speeds
-
uint8_t
supported_speedsB¶ Bit mask of supported tx/rx speeds
-
bool
supported_asym_speeds¶ Support of asymetric speed setting
-
uint8_t
supported_modes¶ Bit mask of supported modes (A or B)
-
uint8_t
supported_crc_on¶ Support for automatic CRC generation
-
uint8_t
supported_crc_off¶ Whether CRC gen can be off at the given speed
-
uint16_t
max_tx_size¶ Maximum Transmit buffer size
-
uint16_t
max_rx_size¶ Maximum Receive buffer size
-
uint8_t
-
struct
BasePcdVMT¶ - #include <hal_abstract_iso14443_pcd.h>
Abstract ISO14443 PCD Virtual Method Table.
- Note
- use macros defined in this file to call these functions for convenience. Name of the macro is the same as a name of this function with
pcdprefix.
Public Members
-
pcdstate_t (*
getStateAB)(void *inst)¶ Returns the device state.
- Note
- This function can be called in all states.
- Return
- State of the device
- Parameters
inst: Pointer to a Pcd structure
-
pcdresult_t (*
activateRFAB)(void *inst)¶ Activates RF Field of the PCD.
- Note
- This function can be called in the following states:
- Parameters
inst: Pointer to a Pcd structure
- Return Value
-
pcdresult_t (*
deactivateRFAB)(void *inst)¶ Deactivates the RF Field of the PCD.
- Note
- This function can be called in the following states:
- Parameters
inst: Pointer to a Pcd structure
- Return Value
PCD_OK: Field successfully deactivated. Pcd transitions to PCD_RF_OFF state.PCD_BAD_STATE: RF Field cannot be deactivated now or is already inactive. State won’t change.PCD_ERROR: An error has occured. State won’t change.
-
const PcdSParams *(*
getSupportedParamsAB)(void *inst)¶ Returns structure with supported features of this PCD.
- Note
- This function can be called in all states
- Return
- Pointer to a PcdSParams structure. Content of this structure should not be modified.
- Parameters
inst: Pointer to a Pcd structure
-
pcdresult_t (*
setParamsAB)(void *inst, pcdspeed_rx_t rx_spd, pcdspeed_tx_t tx_spd, pcdmode_t mode, bool generate_CRC, bool verify_CRC)¶ Sets communication parameters.
If the parameter combination is unsupported PCD_UNSUPPORTED will be returned. It is advised to first check the value returned by getSupportedParamsAB.
- Note
- This function can be called in the following states:
- Parameters
inst: pointer to a Pcd strucutrerx_spd: desired reception speedtx_spd: desired transmission speedmode: desired communication modegenerate_CRC: Whether the CRC should be generated and transmitted automatically during transmissionverify_CRC: Whether the CRC should be verified automatically during reception
- Return Value
PCD_OK: Parameters applied successfully. State won’t change.PCD_BAD_STATE: Parameters can’t be changed now. State won’t change.PCD_UNSUPPORTED: Some requested parameters are not supported byt this PCD. State won’t change.PCD_ERROR: An error has occured. State won’t change.
-
pcdresult_t (*
transceiveShortFrameA)(void *inst, uint8_t data, uint16_t *resp_length, uint32_t timeout_us)¶ Transmits a ‘Short Frame’ and blocks until the response is received or a timeout occurs.
Short frame transmits 7 data bits without parity. Therefore only 7 Least Significant Bits of parameter
dataare sent. This function discards remaining data in the response buffer, if any.- Note
- This function can be called in the following states:
- Note
- This function call either returns immediatelly with error or will change the state PCD_ACTIVE when the operation is in progress. Unless noted otherwise, the state returns to PCD_READY after this function returns.
- Parameters
inst: pointer to a Pcd structuredata: 7 bits of data to be sent (MSB is ignored)resp_len_p: Length of the received response (see transceiveStandardFrameA).timeout_us: Max number of microseconds to wait for a response.
- Return Value
PCD_OK: Transmission successful and response received.PCD_OK_COLLISION: Transmission successful and multiple responses received.PCD_OK_TIMEOUT: Transmission successful but no response was received.PCD_BAD_STATE: Can’t transmit right now. The state won’t change.PCD_ERROR: A driver od hardware error has occured.PCD_TX_ERROR: A transmission error has occured.PCD_RX_ERROR: A reception error has occured.PCD_RX_OVERFLOW: Too much data received.
-
pcdresult_t (*
transceiveStandardFrameA)(void *inst, uint8_t *buffer, uint16_t length, uint16_t *resp_length, uint32_t timeout_us)¶ Transmits a ‘Standard Frame’ and blocks until the response is ready.
Standard frame transmits
n(wheren >= 1) bytes. Thelenparameter cannot be greater than maximum buffer size supported by the reader. After the response is receivedresp_len_pwill be set to the received response length. You can then use this parameter to allocate a new buffer and obtain the response using the getResponseAB function. This function discards remaining data in the response buffer, if any.- Note
- This function can be called in the following states:
- Note
- This function call either returns immediatelly with error or will change the state PCD_ACTIVE when the operation is in progress. Unless noted otherwise, the state returns to PCD_READY after this function returns.
- Parameters
inst: pointer to a Pcd structurebuffer: Bytes to send in a standard framelen: Size of thebufferresp_len_p: Size of received responsetimeout_us: Max number of microseconds to wait for a response.
- Return Value
PCD_OK: Transmission successful and response received.PCD_OK_COLLISION: Transmission successful and multiple responses received.PCD_OK_TIMEOUT: Transmission successful but no response was received.PCD_BAD_STATE: Can’t transmit right now. The state won’t change.PCD_ERROR: A driver od hardware error has occured.PCD_TX_ERROR: A transmission error has occured.PCD_RX_ERROR: A reception error has occured.PCD_RX_OVERFLOW: Too much data received.PCD_TX_OVERFLOW: Can’t transmit this much data. The state won’t change.
-
pcdresult_t (*
transceiveAnticollFrameA)(void *inst, uint8_t *buffer, uint16_t length, uint8_t n_last_bits, uint8_t align_rx, uint16_t *resp_length, uint32_t timeout_us)¶ Transmits the first part of an ‘Anticollision Frame’ and blocks until the response is ready.
Anticollision frame is a standard 7-byte frame split anywhere after 16th bit and before 55th bit. First part is transmitted by the PCD and the second part is transmitted by the PICC as a part of an anticollision sequence. For
resp_len_pmeaning see pcdTransceiveStdFrameA. This function discards remaining data in the response buffer, if any.- Note
- This function can be called in the following states:
- Note
- This function call either returns immediatelly with error or will change the state PCD_ACTIVE when the operation is in progress. Unless noted otherwise, the state returns to PCD_READY after this function returns.
- Parameters
inst: pointer to a Pcd structurebuffer: Bytes to send in an anticoll framelen: Size of the buffern_last_bits: Number of valid bits in the last byte to be transmitted. 0 means the whole byte is valid.align_rx: Desired position of the first received bit in the first byte of the response.resp_len_p: Size of the received responsetimeout_us: Max number of microseconds to wait for a response.
- Return Value
PCD_OK: Transmission successful and response received.PCD_OK_COLLISION: Transmission successful and multiple responses received.PCD_OK_TIMEOUT: Transmission successful but no response was received.PCD_BAD_STATE: Can’t transmit right now. The state won’t change.PCD_ERROR: A driver od hardware error has occured.PCD_TX_ERROR: A transmission error has occured.PCD_RX_ERROR: A reception error has occured.PCD_RX_OVERFLOW: Too much data received.PCD_TX_OVERFLOW: Can’t transmit this much data. The state won’t change.
-
uint16_t (*
getResponseLengthA)(void *inst)¶ Gets (remaining) size of response stored in the buffer, if any.
- Note
- This function can be called in the following states:
- Return
- Number of bytes in the response buffer.
0if the response buffer is empty. - Parameters
inst: pointer to a Pcd structure
-
pcdresult_t (*
getResponseAB)(void *inst, uint16_t buffer_size, uint8_t *buffer, uint16_t *size_copied, uint8_t *n_last_bits)¶ Read response from the internal response buffer.
Read response from the internal buffer. If size of the buffer passed to this function is smaller than the response size only part of the response will be copied and this function must be called several times. Bytes received first are copied first.
n_last_bits_pis valid only when copying last part of the response.- Note
- This function can be called in the following states:
- Parameters
inst: pointer to a Pcd structurebuf_size: Max size to readbuffer: The buffersize_copied: Number of bytes written to the buffern_last_bits_p: Number of valid bits in last byte copied to the buffer.
- Return Value
PCD_OK: Bytes were copiedPCD_ERROR: No more bytes to copyPCD_BAD_STATE: This function can’t be called in this state.
-
void (*
acquireBus)(void *inst)¶ Acquires exclusive access to the PCD.
- Parameters
inst: pointer to a Pcd structure
-
void (*
releaseBus)(void *inst)¶ Acquires exclusive access to the PCD.
- Parameters
inst: pointer to a Pcd structure
-
bool (*
supportsExtFeature)(void *inst, pcdfeature_t feature)¶ Checks whether this PCD supports the given extended feature.
- Parameters
inst: pointer to a Pcd structure
-
pcdresult_t (*
callExtFeature)(void *inst, pcdfeature_t feature, void *params, void *result)¶ Invokes an extended feature.
- Parameters
inst: pointer to a Pcd structurefeature: identifier of the featureparams: parameters passed to the feature function. Can be NULL if function doesn’t expect any.result: result of the feature function.
- Return Value
PCD_OK: Feature function executed successfullyPCD_BAD_STATE: Feature function can’t be executed nowPCD_UNSUPPORTED: This feature is not supported
-
struct
Pcd¶ - #include <hal_abstract_iso14443_pcd.h>
Base ISO/IEC 14443 PCD.
This class represents a generic ISO/IEC 14443 Proximity Coupling device.
Public Members
-
const struct BasePcdVMT *
vmt¶ Virtual Methods Table
-
void *
data¶ Private data of a driver
-
const struct BasePcdVMT *
ISO/IEC 14443 PCD Structures for Extended Features¶
Structures for extended / optional features of an abstract ISO/IEC 14443 PCD.
Real-world ISO/IEC 14443 PCDs (card readers) support a number of extended features which are not covered by the abstract PCD driver. These features can be still used using the pcdCallExtraFeatures API. Structures used as parameters and results of various commands are defined here.
-
struct
PcdExtSelftest_params¶ - #include <hal_abstract_iso14443_pcd_ext.h>
Parameters for PCD_EXT_SELFTEST command.
PCD_EXT_SELFTEST takes no parameters, this structure is empty and
paramsargument can beNULL.
-
struct
PcdExtSelftest_result¶ - #include <hal_abstract_iso14443_pcd_ext.h>
Result of the PCD_EXT_SELFTEST command.
Public Members
-
bool
passed¶ Did the self-test passed?
-
bool
-
struct
PcdExtCalcCRC_params¶ - #include <hal_abstract_iso14443_pcd_ext.h>
Parameters for PCD_EXT_CALCULATE_CRC_A and PCD_EXT_CALCULATE_CRC_B commands.
-
struct
PcdExtCalcCRC_result¶ - #include <hal_abstract_iso14443_pcd_ext.h>
Result of PCD_EXT_CALCULATE_CRC_A and PCD_EXT_CALCULATE_CRC_B commands.
Public Members
-
uint16_t
crc¶ Resulting CRC
-
uint16_t
-
struct
PcdExtMifareAuth_params¶ - #include <hal_abstract_iso14443_pcd_ext.h>
Parameters for the PCD_EXT_MIFARE_AUTH command.
-
struct
PcdExtMifareAuth_result¶ - #include <hal_abstract_iso14443_pcd_ext.h>
Result of the PCD_EXT_MIFARE_AUTH command.
Public Members
-
bool
authSuccess¶
-
bool