Um2890 RFNFC Abstraction Layer Rfal Stmicroelectronics
Um2890 RFNFC Abstraction Layer Rfal Stmicroelectronics
User manual
Introduction
The RF abstraction layer is a library that provides several functionalities required to perform RF/NFC communications and other
common related operations. It integrates different RF ICs (existing and future ST25R devices) into an easy-to-use common
interface.
This common interface makes the upper software layers independent from the underlying device. The RFAL with the same APIs
is available for all ST25R devices, thus reducing software effort when prototyping and migrating from one device to another.
ST25R3911B
ST25R3912
ST25R3911
ST25R3914
ST25R3915
ST25R3916
ST25R3916B
ST25R3917
ST25R3916 ST25R3917B
ST25R3918
ST25R3920
ST25R3920B
ST25R95 ST25R95
ST25R100
ST25R200
ST25R200
1 Acronyms
Table 2. Acronyms
Acronym Description
AC Analog configuration
ACM Active communication mode
AFE Analog front end
AP2P Active P2P
APDU Application protocol data unit
API Application programming interface
CE Card emulation
CPU Central processing unit
DEP Data exchange protocol
DPO Dynamic power output
FAQ Frequently asked question
FDT Frame delay time
FWT Frame wait time
FW Firmware
FIFO First in first out
GPIO General purpose input/output
GT Guard time
HAL Hardware abstraction layer
HW Hardware
IC Integrated circuit
MCU Microcontroller unit
MPU Microprocessor unit
NFC Near field communication
NFCID NFC identifier
P2P Peer-to-Peer
PCD Proximity coupling device
PCM Passive communication mode
PICC Proximity inductive coupling card
UID Unique identifier
WTX Waiting time extensions
RAM Random access memory
RFAL RF abstraction layer
RF HAL RFAL hardware abstraction layer
RF HL RFAL higher layer
RW Reader/writer
SW Software
TC Test case
TS Test suite
2 RFAL library
NFC-A x x x x
NFC-B x x x x
RW
NFC-F x x x -
NFC-V x x x x
NFC-A - x - -
CE
NFC-F - x - -
P2P x x - -
Initiator x x - -
AP2P
Target x x - -
2.2 Description
The RFAL provides some functionalities required to perform RF/NFC communications, as well as other common
tasks conducted by an NFC device. The different RF ICs (existing and future ST25R devices) are encapsulated
into a common interface that provides support for:
• NFC modes:
– Reader/Writer (Poller)
– P2P initiator (PCM and ACM)
– P2P target (PCM and ACM)
– Card emulation (Listener)
• Technologies:
– NFC-A (ISO14443-A)
– NFC-B (ISO14443-B)
– NFC-F (FeliCa™)
– NFC-V (ISO15693)
– P2P (ISO18092)
– Proprietary technologies (for example, ST25TB, CTS, Kovio™, B’, iClass®, Calypso®)
• Protocols:
– ISO-DEP (ISO data exchange protocol - ISO14443-4)
– NFC-DEP (NFC data exchange protocol - ISO18092)
• Operating modes:
– NFC device mode
– Low power mode
– Wake-up mode
MISRA C is a set of guidelines for programming in the C language, developed and published by the motor
industry software reliability association (MISRA). These guidelines aim to improve code safety, security, portability
and reliability by identifying aspects of the C language that must be avoided due to their ambiguity and
susceptibility to common programming mistakes. The MISRA standard is widely used by the automotive industry
for embedded software.
For further details refer to the compliance report provided on RFAL’s documentation folder enclosed within each
release package.
2.4 Hardware
2.4.1 Requirements
Depending on the used device, the hardware requirements in top level to enable RFAL are:
• Serial interface bus (SPI, I²C or UART) capable to drive the ST25R NFC reader (refer to the datasheet)
• GPIOs for the serial bus and other control lines, such as IRQ, bus selection, and reset pins
• External interrupt trigger source (preferred approach, not mandatory)
• An MCU/MPU/system with sufficient RAM and flash memory to accommodate the RFAL library
• Ability to measure time intervals in a simple millisecond tick counter
2.5 Software
2.5.1 Dependencies
The RFAL library is based on some common SW abstractions typically available with the C compiler toolchains
and the device drivers that are frequently provided by the host device’s HAL.
• C toolchain
– stdint.h, stdbool.h for type definitions (user defined types are also possible)
– limits.h for parameter checking
– math.h for mathematical operations
• rfal_utils
– Provides a list of predefined errors and macros used by the RFAL to handle and report specific
errors/events.
– A glue layer that provides some convenience macros and makes possible to redirect some typical
utilities, such as Min, Max, memcpy.
• HAL
– Serial interface (SPI, I²C, UART), to transmit and receive data
– GPIO, to control specific features (such as IRQ, chip select or reset pins)
– Timer, to control internal mechanisms that must comply with given time requirements
All the dependencies listed above must be provided in a central location/file named rfal_platform. Every
RFAL modules relies on this configuration file, which allows the user to define/remap all platform specifics in the
form of includes, feature switches and macro definitions. More info is available in Section 4.1.
2.6 Architecture
The RFAL library is a multilayer stack with different modules and abstractions for different application needs.
RFAL NFC
RF RF RF RF RF
Note: ST25Rx represents future devices that may be added to the ST25R family.
Internally the RFAL is divided into three sub layers:
• RF HL
• RF AL
• RF HAL
2.6.1 RF HAL
In this layer are provided the low level drivers for each NFC IC.
All modules encapsulated on this layer are chip specific/dependent and are provided for each ST25R device. The
modules are:
ST25R
This module contains the low level support of the NFC IC with direct control of the HW by means of registers
access and the execution of commands (for futher details refer to the datasheet). These provide an interface to
the execution of some HW activities.
Note: Direct access to the APIs is not recommended as these bypass the normal driver flow making the application not
portable as the APIs are chip specific. Typical applications use of the RF module as the lowest interface.
RF configurations
This module, also called analog configurations, contains table/list of analog settings that are applied by the RFAL
at specific moments of the execution.
The table contains a set of RMVs (register, mask, value) that allow for certain configuration (bits) to be loaded at
different moments of the driver execution. This allows for the IC settings to be changed if needed depending on
the mode the device is currently operating.
Individual sets of RMVs are loaded (if defined) at specific times of the RFAL driver run. These are internally
encoded by a 16-bit identifier. Furthermore, specific events are also encoded by this identifier, such as:
• Chip Init: loaded upon IC start up / reset / initialization
• Chip Deinit: loaded upon deinitialization of the IC
• Field On: loaded before transition to Field On
• Field Off: loaded after transition to Field Off
• Wake-up On: loaded before entering wake-up mode
• Wake-up Off: loaded after exiting wake-up mode
• Listen On: loaded before entering Listen mode
• Listen Off: loaded after exiting Listen mode
• Low power mode On: loaded before entering Low Power mode
• Low power mode Off: loaded after exiting low power mode
• Poll Common: if in Poll mode, loaded before bitrate specific configurations
• Listen Common: if in Listen mode, loaded before bitrate specific configurations
• Power Level n: loaded if a specific power level is entered (may be used in conjunction with DPO).
Note: Settings/register bits here concern only analog aspects of the device. The other bits required for the proper
operation of the device are not manipulated and are handled by the normal driver execution. Great care and a
considerable experience level is required when computing/manipulating such analog configuration table.
Figure 2 shows these analog configuration sequence.
POLL_tech_BITRATE_COMMON_TX /
rfalSetMode(tech;bitrate) rfalSetAnalogConfig() LISTEN_tech_BITRATE_COMMON_TX
POLL_tech_BITRATE_COMMON_RX /
LISTEN_tech_BITRATE_COMMON_RX
CHIP_POLL_COMMON /
rfalSetBitRate(bitrate) rfalSetAnalogConfig() CHIP_LISTEN_COMMON
POLL_tech_bitrate_TX /
LISTEN_tech_bitrate_TX
POLL_tech_bitrate_RX /
LISTEN_tech_bitrate_RX
POLL_tech_bitrate_TX
POLL_tech_bitrate_RX
Note: In case of need there is the possibility to instruct the RFAL to use the user defined table, hereafter referred as
custom analog configuration.
The RFAL library provides a default analog configuration table, used during testing to verify the release.
The loading of ACs is performed hierarchically. If the same setting/configuration/bit is addressed in multiple AC
entries, the last one prevails regardless of the previous.
Note: A common misconception is that the AC entry POLL_COMMON or LISTEN_COMMON is loaded before all the other
mode and bitrate specific entries. To ensure that the POLL/LISTEN_COMMON entry is always loaded, this AC is
loaded by the rfalSetBitrate(), which is executed by the rfalSetMode() after loading mode specific the
AC entries.
The rfalSetMode() usage is particularly complex as it sets both the mode and a bitrate dependent setting. By
this, it internally includes the execution of rfalSetBitrate().
1. POLL_NFCA_COMMON_TX
2. POLL_NFCA_COMMON_RX
3. POLL_ COMMON
4. POLL_NFCA_106_TX
5. POLL_NFCA_106_RX
If the rfalSetMode() API is executed for NFC-A Poller at 106 kbps it is necessary to load the following
sequence:
Detailed explanation on the more complex usage (setting a new mode and bitrate)
On the DISCO GUI, a tab dedicated to AC is available (even with no demonstration HW/FW). Within it, users load
AC tables, visualize them, modify settings, and generate the custom AC file to include in the projects.
RF
The RF module holds a pivotal part of the whole RFAL library, where all necessary handlings are provided
granting support for each individual NFC IC.
This module provides the APIs to initialize the NFC drivers, to set them into the right modes, and to perform the
required operations. It is also in charge of several critical activities and the processes, referred as workers, which
require the NFC task to be serviced periodically - rfalWorker(). Those activities/processes are:
• Transceive
Transceive operations are the most common procedure of the whole library. They are the simplest way to
transmit and receive arbitrary data, regardless of protocol selected. During a transceive operation the
process/worker controls and monitors the AFE to complete the data exchange as requested. This requires
that the process/worker (rfalWorker()) is serviced frequently enough to meet some strict time critical
operations (reloading of the HW FIFO, EMD handling, among others).
• Listen mode
The Listen mode is used to establish NFC communication in Listen mode, PICC or CE mode. As the
Listener is activated in multiple protocols and bitrates, this process enables to configure the supported/
allowed modes/protocols, and then it monitors and handles that whole card activation automatically. This
mode ends when the first data packet is received from the Poller after the low level activation is completed.
In the RF layer the card activation is completed before the protocol activation, as detailed below:
– NFC-A: first packet received after the UID/NFC ID selection (RATS command in case of a T4T
emulation, or an ATR_REQ in case of P2P)
– NFC-F: first packet received after the SENSF_REQ (check/update command in case of a T3T
emulation, or an ATR_REQ in case of P2P)
– AP2P: first data received ATR_REQ
Once the activation is done, and after a data packet the upper/protocol layers check the correct protocol
activation, set the correct mode and make use of transceive operations to exchange data (same as in
Poller mode).
• Wake-up mode
In this mode the AFE is put in wake-up mode where the device remains in a low power state and
periodically performs specific measurements to assess whether there is some change on its surroundings.
The worker needs to run to update.
An additional option for certain ST25R devices is also available, where the RFAL performs SW Tag
detection. In this mode most of the activities are triggered by the host directly (not by the AFE itself) and
therefore the process/worker needs to be frequently executed.
Apart from the common interface provided by this layer in rfal_rf.h, access to more chip specific
operations can also be achieved via a chip independent interface available via rfal_chip.h. This permits
for a generic interface to perform certain actions such as read register or execute commands while keeping
the SW layers agnostic to the actual AFE itself.
2.6.2 RF AL
The NFC protocol stack, placed on top of the low-level drivers of the RFAL HAL, is provided in this layer. All
modules described here are device independent, and their focus is to provide support for individual features,
technologies, and protocols.
Individual modules can be disabled/excluded, when not needed, to better fit into a multitude of application needs.
Note: To enable/disable individual features/modules of the RFAL refer to Section 4.2.
Technologies
These modules provide support and convenience methods for several NFC technologies. For each supported
technology there are interfaces for common tasks, depending on each technology specific needs (most of them
detailed in [1]). Examples of those activities are:
• Initialization
• Technology detection
• Collision resolution
• Activation
• Sleep/Deactivation
• Computing/parsing commands and responses
• Technology/card specific operations
NFC-A
This module provides the functionality required to support NFC-A (ISO14443A) compliant devices. It enables to
configure the AFE for this mode covering analog, digital and protocol aspects of this technology. It provides a
Poller (ISO14443A PCD) interface as well as some NFC-A Listener (ISO14443A PICC) helpers. Support for
performing technology detection, anticollision/collision resolution, card selection/activation and sleep/deactivation
are available.
The detection and selection of all NFC-A tag types (T1T, T2T, T4T) is handled by this module, which provides
definitions and helper methods up to ISO14443-3 layer. Operations specific to a certain tag type are then provided
in a dedicated module.
NFC-B
This module provides the functionality to support NFC-B (ISO14443B) compliant devices. It permits to configure
the AFE for this mode covering analog, digital and protocol aspects of this technology as a Poller device
(ISO14443B PCD). Support for performing technology detection, anticollision/collision resolution, card activation
and sleep/deactivation are available.
The definitions and helper methods provided by this module cover up to ISO14443-three layer (excluding ATTRIB
command which is used to enter ISO-DEP / ISO14443-4).
NFC-F
This module provides the interfaces to support NFC-F (FeliCa - JIS X6319-4) compliant devices. It permits to
configure the AFE for this mode covering analog, digital and protocol aspects of this technology as a Poller device
(FeliCa PCD). Support for performing technology detection, anticollision/collision resolution, card activation are
available.
Support for T3T commands to read and write memory blocks is provided (CHECK/UPDATE).
NFC-V
This module provides the functionality to support NFC-V (ISO15693) compliant devices. It permits to configure the
AFE for this mode covering analog, digital and protocol aspects of this technology as a Poller device (ISO15693
VCD). Support for performing technology detection, anticollision/collision resolution, card selection/activation and
sleep/deactivation are available.
Support for typical T5T commands is provided.
Note: The APIs within this module enable accessing the tags in the three different modes as foreseen in ISO15693:
• Addressed mode: after inventory no individual card is selected and each command contains the
NFCID/UID of the tag addressed
• Non addressed mode: no individual card is selected and the commands exchanged do not contain a
specific NFCID/UID. This causes all tags in the vicinity to react to the command (broadcast)
• Select mode: after inventory one individual card is selected using its NFCID/UID and each command
thereafter does not contain an NFCID/UID
These modes are controlled via the flags, and uid parameters on the API, and the usage of
rfalNfcvPollerSelect()
T1T
This module provides the functionality to support T1T compliant devices. It permits to configure the AFE for this
mode covering and exchange tag specific commands. Support for T1T commands to read and write memory
blocks are here provided (RID, RALL and WRITE_E).
T2T
This module provides the functionality to support T2T compliant devices and their commands needed to read and
write memory blocks (READ, WRITE and SECTOR SELECT).
T4T
This module provides convenience methods and definitions for T4T (ISO7816-4) with an interface to compute and
parse T4T APDUs according to NFC Forum and ISO7816-4.
This does not perform any actual data exchange, it simply computes and parses APDUs which shall be then
conveyed via the protocol layer ISO-DEP (ISO144443-4).
ST25TB
This module provides the functionality to support ST25TB devices (SRTx, SRIx). It permits to configure the AFE
covering analog, digital and protocol aspects of this technology as a Poller device (ISO14443B PCD). Support for
performing technology detection, anticollision/collision resolution, card selection/activation and sleep/deactivation
are available as well as card specific operations such as memory access.
Protocols
After successful card activation, typically data exchange is performed between the Poller and the Listener (PCD
and PICC). This data exchange is sometimes achieved by simple pair of command, response sequence or in the
form of more advanced protocols.
These protocols provide a more robust mechanisms to ensure reliable data exchange, allowing data chaining
mechanisms to split long frames into several chinks, and define specific handlings in case an error occurs
allowing for recovery without breaking the on going communication link. These modules enable the usage of such
protocols handling all protocol specifics (framing, timings, error handling, etc).
ISO-DEP
This module provides support for establishing an ISO-DEP (ISO14443-4) protocol link and to perform data
exchange. It handles the protocol activation and deactivation in both Poller and Listener mode. Once the protocol
is activated, data (typically APDUs) are exchanged by the means of transceive operations.
The transceive interfaces provided are non blocking and can be used in two different manners:
• Block: handles the exchange of a single data block (I-Block) which contains a complete or partial APDU.
Upon transmission the caller must indicate whether the block is complete or partial (chained) chunk of data
(see input isTxChaining parameter). Similarly, during reception if a chained packet is received the output
parameter isRxChaining it set, and a special return code (ERR_AGAIN) is sent. This interface handles all
protocol specifics such as control packets, error handling, repetitions, and returns either successful or not
in case an irrecoverable error has occurred.
• APDU: handles the exchange of a complete APDU. In case the data length is bigger than the one
supported and announced by one of the devices, it automatically splits the APDU into smaller chunks/
chained packets and handles the chaining, both for transmission and reception, automatically. This
interface (which makes use of the block interface internally) requires an additional temporary buffer (of the
maximum frame size supported) to cope with protocol specifics.
NFC-DEP
This module provides support for establishing an NFC-DEP (ISO18092, NFCIP1, P2P) protocol link and to
perform data exchange. It handles the protocol activation and deactivation in both Poller and Listener mode
(Initiator and Target).
This protocol layer are used for passive P2P and active P2P. For the passive P2P is performed a normal device
anticollision and selection, for the AP2P an ATR_REQ is sent right after initial RF collision avoidance.
Once the protocol is activated, data (typically LLCP packets) can be exchanged by the means of transceive
operations.
The transceive interfaces provided are non blocking and are used in two different manners:
• Block: it handles the exchange of a single data block (I-PDU) that contains a complete or partial PDU.
Upon transmission the caller must indicate whether the block is complete or partial (chained) chunk of data
– see input isTxChaining parameter. Similarly, during reception if a chained packet is received the
output parameter isRxChaining is set, and a special return code (ERR_AGAIN) is sent. This interface
handles all protocol specifics such as control packets, error handling, repetitions, and returns either
successful or not in case an irrecoverable error has occurred.
• PDU: it handles the exchange of a complete PDU. In case the data length is bigger than the one supported
and announced by one of the devices, it automatically splits the PDU into smaller chunks/chained packets
and handle the chaining, both for transmission and reception, automatically. This interface (which makes
use of the Block interface internally) requires an additional temporary buffer (of the maximum frame size
supported) to cope with protocol specifics.
Note: In both protocols (ISO-DEP and NFC-DEP), once a chained block/DEP is received, the error ERR_AGAIN is
sent. At this point the caller must handle/store the received data immediately. When ERR_AGAIN is returned an
ACK has already been sent to the other device and the next block might be incoming. If rfalWorker() is
called frequently it places the next block on the same buffer provided in the transceive parameters.
Note: In both protocols (ISO-DEP and NFC-DEP) a Listener device is only considered active after the first data packet
or a protocol parameter selection (PPS or PSL) is received. Therefore, the interface that handles activation in
Listen mode holds the first data packet in its buffer passed on activation parameters. Once the Listener
activation has completed (rfalIsoDepListenGetActivationStatus() /
rfalNfcDepListenGetActivationStatus() returns ERR_NONE) the method
rfalIsoDepGetTransceiveStatus() / rfalNfcDepGetTransceiveStatus() must be called.
Note: If activation has completed due to reception of a data block (not PPS/PSL) the buffer owned by the caller and
passed on the listen activation parameters must still contain this data. The first data are processed by
rfalIsoDepGetTransceiveStatus(), inform the caller and then the next transaction can flow normally
starting with rfalIsoDepStartTransceive() / rfalNfcDepStartTransceive()
2.6.3 RF HL
This layer sits on the top of the device specific drivers (RF HAL) and the necessary NFC technology and protocol
stack (RF AL). It is the application/higher layer that makes use of the RFAL functionalities, such as NFC Forum
Activities (NFCC), EMVCo, DISCO/NUCLEO demonstration.
This layer provides convenient abstractions for common NFC related tasks, such as NFC Forum compliant Poller
and Listener device.
Modules contained in this layer are:
NFC
This module provides a simple interface to easily implement an NFC Forum compliant Poller and Listener device.
It combines conveniently all NFC technologies and enables the functionality required to perform the multiple NFC
activities [1]: technology detection, collision resolution, activation, data exchange, and deactivation.
The NFC module is influenced by (but not fully aligned with) the NFC Forum specifications, in particular Activity
[1] and NCI [3].
The aim of this module is to provide support for common NFC implementations, while keeping its usage
straightforward. Not all RFAL available parameters and configurations available are exported on this module
interface.
Its inner state machine, which mimics NFC Forum NCI recommendation, is shown below. The arrows represent
the available APIs where the caller can control this module, and the circles the states.
De
ac
te SELECT
a
tiv
t iv
at
ac
De
e
Se
lec
ies
t
over
Deactivate
e
Disc
at
iv t
Discover
ac
Initialize
Dat
De
aEx
Activated
cha
nge
DATA
NOT_INIT IDLE DISCOVERY
EXCHANGE
Deactivate
Deactivate
DT54836
Deactivate
2.6.4 Overview
As shown in Figure 5, the RFAL is composed by several stacked layers and modules, organized according to the
functionality they provide and their dependencies.
Application
RFAL
ST25R
RF HAL Control
RF AL
IRQ
IRQ
Serial
Interface
RF HL Worker
2.6.5 Concurrency
When integrating the library concurrency aspects need to be considered and an orderly access to the HW
resources must be ensured. Different complexities are tackled depending on the nature of the systems itself, if
bare metal or a multi-thread environment such as an RTOS or embedded Linux.
Serial interface atomicity
The NFC AFE is controlled via the serial interface which is addressed on different contexts or threads. It is
important to ensure that each operation is atomic and that an ongoing operation, for example main/user context,
is not interrupted by another one (e.g from an interrupt/ISR context).
Such scenario is depicted in Figure 6 where a ST25R controlled via the SPI with two interrupts. The driver running
on the main/user context then triggers a FIFO read operation to retrieve the received data and another interrupt is
flagged by the ST25R which abruptly interrupts a ongoing SPI operation/traffic, resulting in an invalid SPI
sequence.
To avoid the scenario above each operation on the serial interface must be protected, blocking/claiming the
shared resource preventing concurrent access from multiple contexts.
In Figure 7 if an interrupt occurs (IRQ signal high) during an ongoing operation the handling of this event is
deferred to when the serial interface is free again.
The RFAL provides the means of protecting the serial interface by the means of the following APIs:
platformProtectST25RComm(), platformUnprotectST25RComm(),
platformProtectST25RIrqStatus() and platformUnprotectST25RIrqStatus() detailed in
Section 4.1. The actual protection implementation takes many forms depending on each platform and the system
architecture. Recommendation is to make use of the interrupt enable mechanism if running on an embedded
system in bare metal or the use of mutex in a multi-thread environment. Examples on this protection mechanism
are available on multiple demonstrations available at st.com, namely X-CUBE-NFC3, X-CUBE-NFC5, X-CUBE-
NFC5, STSW-ST25R-LIB as well as in Section Appendix A.
Multi-thread environment
When running in a multi-thread environment such as an RTOS or embedded Linux other constrains need to be
considered. Implementations on these environments commonly make use of a thread to take care of the interrupt
status and other(s) for user/main context.
In the same manner parallel access from multiple contexts needs to be protected and RFAL allows to deploy
further protection mechanisms (commonly by the use of mutexes) by the following APIs:
platformProtectST25RComm(), platformUnprotectST25RComm(),
platformProtectST25RIrqStatus(), platformUnprotectST25RIrqStatus(),
platformProtectWorker() and platformUnprotectWorker() detailed in Section 4.1.
Examples of such protection mechanism are available on several demonstrations at www.st.com. Such as:
• STSW-ST25R009
• STSW-ST25R013 packages for Linux
• STSW-ST25R-LIB for FreeRTOS.
3 Releases
• doc/: contains RFAL documentation which include release notes, detailed API documentation (Doxygen
format), compliance reports, such as MISRA, for applicable devices
• include/: contains exported.h (header) files for the common RFAL AL and RFAL HL layers. Projects
using the RFAL shall add this location to its include paths
• source/: contains .c (source) and some internal.h (header) files for the common RFAL AL and RFAL HL
layers. Projects using the RFAL shall also add this location to its include paths
• source/st25r…/: contains.c (source) and internal .h (header) files for the common RFAL HAL. Projects
using the RFAL must add this location to its include paths.
To set up and configure the RFAL a few settings must be defined by the user. These settings must be provided on
a file named rfal_platform, to whom every RFAL modules relies on. Examples are found at: X-CUBE-NFC3,
X-CUBE-NFC5, STSW-ST25R-LIB, as well as in Section Appendix A.
Pin definitions
• ST25R_SS_PIN / ST25R_SS_PORT: Pin and port definitions used for SPI chip select (CS) / slave select
(SS) (mandatory). The SPI CS must be controlled by SW, not automatically handled by the SPI peripheral.
If HAL driver uses single definition to address GPIOs PORT and PIN only one definition must be defined,
and then used on GPIO macros
• ST25R_INT_PIN / ST25R_INT_PORT: Pin and port definitions used for ST25R IRQ line (mandatory).
The state of this GPIO is checked on the ISR. If HAL driver uses single definition to address GPIOs PORT
and PIN only one definition must be defined, and then used on GPIO macros
• PLATFORM_LED_RX_PIN / PLATFORM_LED_RX_PORT: Pin and port definitions used for reception LED
(optional). If defined LED drives this GPIO high during a reception. If optional LED feature is not be used
remove these definitions. If HAL driver uses single definition to address GPIOs PORT and PIN only one
definition must be defined, and then used on LED macros
• PLATFORM_LED_FIELD_PIN / PLATFORM_LED_FIELD_PORT: Pin and Port definitions used for Field
LED (optional). If defined RFAL drives this LED high when the field is turned on. This optional feature is
disabled by removing this definitions. If HAL driver uses single definition to address GPIOs PORT and PIN
only one definition must be defined, and then used on LED macros.
• platformUnprotectST25RIrqStatus()
Unprotects the IRQ status var. IRQ enable on a single thread environment (MCU) ; Mutex unlock on a multi
thread environment (optional).
• platformProtectWorker()
Protects \ locks the single execution of the RFAL worker (optional). If not required, this macro must be left
empty.
• platformUnprotectWorker()
Unprotects \ unlocks the unique execution of the RFAL worker (optional). If not required, this macro must
be left empty.
• platformIrqST25RPinInitialize()
Initializes the ST25R IRQ pin as input / external interrupt (optional). Upon initializing, RFAL calls this macro
to configure the IRQ pin. If GPIO already configured by the user, this macro mustbe left empty.
• platformIrqST25RSetCallback( cb )
Sets the ST25R ISR (optional). Upon initializing, RFAL calls this macro to set the callback (cb) of the IRQ
pin. If the interrupt is already configured by the user and st25r391xIsr() being called upon an IRQ, this
macro must be left empty.
• platformLedsInitialize()
Configures LEDs as outputs. (optional). Upon initializing, RFAL calls this macro to initialize the required
pins as outputs. If the LEDs not used or already configured by the user, this macro must be left empty.
• platformLedOff( port, pin )
Turns LED Off (optional). If the LEDs are not used, this macro must be left empty.
• platformLedOn( port, pin )
Turns LED On (optional). If the LEDs are not used, this macro must be left empty.
• platformGpioSet( port, pin )
Sets GPIO to logical high state (mandatory).
• platformGpioClear( port, pin )
Sets GPIO to logical low state (mandatory).
• platformGpioToogle( port, pin )
Toogles GPIO logical state (mandatory).
• platformGpioIsHigh( port, pin )
Checks if the state of a GPIO is in logical high state (mandatory).
• platformGpioIsLow( port, pin )
Checks if the state of a GPIO is in logical low state (mandatory).
• platformTimerCreate( t )
Creates a timer that must expire in the given time (t) expressed in milliseconds (mandatory). This
calculates a timer/tick/reference to a timeout that must be expired after the time defined. It returns this
timer/tick/reference expressed as an unsigned 32 bit variable.
• platformTimerIsExpired( timer )
Checks if the timer previously created is expired (mandatory). This receives the timer/tick/reference
returned by platformTimerCreate() and return true if expired.
• platformTimerDestroy( timer )
Stops and releases the given timer if previously created (optional). If not required, this macro must be left
empty.
• platformDelay( t )
Delays/Blocks the MCU for the given time (t) in milliseconds (mandatory).
• platformGetSysTick()
Returns the current tick counter in millisecods (optional). If not required, this macro must be left empty.
• platformAssert()
Asserts whether the given expression is true. Logging, error handle or trap otherwise. (optional). If not
required, this macro must be left empty.
• platformErrorHandle()
Global error handler or trap (optional). If not required, this macro must be left empty.
• platformSpiSelect()
SPI SS \ CS: Chip|Slave Select (mandatory).
• platformSpiDeselect()
SPI SS \ CS: Chip|Slave Deselect (mandatory).
• platformSpiTxRx( txBuf, rxBuf, len )
SPI Transceive (mandatory).This transmits/receives from/to the given buffers for the given amount of bytes
(len). The SPI Bus must be clocked for the given number of bytes (len). If transmission buffer (txBuff)
equals NULL, only reception must be done, leading to zeros on the MOSI line, and the MISO bytes into
rxBuff.If reception buffer (rxBuff) equals NULL, only transmission smust be done, leading to transmission
on the MOSI line, and data from MISO being ignored / not placed into the rxBuff.
• platformLog( ... )
Logs the given message (optional).
Certain definitions and interfaces listed above are mandatory and some are optional. Specific features/extensions
are not required, e.g IRQ/GPIO initialization called from RFAL itself, ST25R LED handling, global error handler/
trap, etc.
5 FAQs
ST25R3911B
ST25R3916
ST25R95
The numbers provided are based on a compilation for STM32L4 with optimizations set at -O3.
Each module is compiled with all functionalities included and further reductions are observed by disabling specific
features of an individual module (detailed in Section 5.1: Detailed information of each RFAL API). For example if
Listen mode is not needed, disabling RFAL_FEATURE_ISO_DEP_LISTEN and RFAL_FEATURE_LISTEN_MODE
show smaller footprint of the ISO-DEP and RF modules.
With this table and knowing that is the targeted application and the modes, one calculates a rough estimation.
Here a few examples for ST25R3916 based on RFAL v2.2.0.
AC Table 764 8
ISO-DEP 5908 188
NFC-A 1774 56
NFC-B 986 2
9816 1028
1648 4
RFAL HAL
1140 515
634 16
22670 1817
Total
22.14 K 1.77 K
AC Table 764 8
CRC 54 0
ISO15693-2 1004 12
NFC-V 2098 0
9816 1028
1648 4
RFAL HAL
1140 515
634 16
17158 1583
Total
16.76 K 1.55 K
AC Table 764 8
CRC 54 0
ISO15693-2 1004 12
ISO-DEP 5908 188
NFC-A 1774 56
NFC-B 986 2
NFC-DEP 4884 176
NFC-F 1150 322
NFC-V 2098 0
T1T 302 0
T2T 298 0
T4T 672 0
9816 1028
1648 4
RFAL HAL
1140 515
634 16
33132 2327
Total
32.36 K 2.27 K
AC Table 764 8
ISO-DEP 5908 188
NFC 4150 2181
NFC-A 1774 56
NFC-B 986 2
9816 1028
1648 4
RFAL HAL
1140 515
634 16
26820 3998
Total
26.19 K 3.90 K
AC Table 764 8
ISO-DEP 5908 188
NFC-A 1774 56
9816 1028
1648 4
RFAL HAL
1140 515
634 16
21684 1815
Total
21.18 K 1.77 K
AC Table 764 8
NFC-F 1150 322
9816 1028
1648 4
RFAL HAL
1140 515
634 16
15152 1893
Total
14.80 K 1.85 K
AC Table 764 8
ISO-DEP 5908 188
NFC 4150 2181
NFC-A 1774 56
NFC-F 1150 322
9816 1028
1648 4
RFAL HAL
1140 515
634 16
26984 4318
Total
26.35 K 4.22 K
AC Table 764 8
CD 818 11
CRC 54 0
DPO 26 0
ISO15693-2 1004 12
ISO-DEP 5908 188
NFC 4150 2181
NFC-A 1774 56
NFC-B 986 2
NFC-DEP 4884 176
NFC-F 1150 322
NFC-V 2098 0
ST25TB 892 0
ST25xV 1346 0
T1T 302 0
T2T 298 0
T4T 672 0
9816 1028
1648 4
RFAL HAL 748 0
1140 515
634 16
41112 4519
Total
40.15 K 4.41 K
Application RF ST25R
rfalDoOperation( )
AccessRegisters
AccessRegisters
ExecuteCommand
IRQ
AccessRegisters
AccessRegisters
DONE
When using the non blocking APIs the flow is quite different. The call that triggers an operation promptly returns
control to the caller, and from this point he can poll for when the operation has concluded. The rfalWorker()
needs to run autonomously performing the requested task.
Application RF ST25R
rfalStartOperation( )
DONE
rfalGetOperationStatus( )
BUSY
AccessRegisters
AccessRegisters
ExecuteCommand
RFALWorker()
IRQ
rfalGetOperationStatus( )
BUSY
AccessRegisters
AccessRegisters
rfalGetOperationStatus( )
DONE
In a single thread environment these are actually executed sequentially as the application alternates from
executing the rfalWorker() and returns to the context that waits the operation completion and polls it. The
below a representation shows how activity is actually only executed when the rfalWorker() is run (and of
course by the ISR)
Application RF ST25R
rfalStartOperation( )
DONE
rfalGetOperationStatus( )
BUSY
AccessRegisters
RFALWorker()
AccessRegisters
rfalGetOperationStatus( )
BUSY
RFALWorker()
ExecuteCommand
IRQ
RFALWorker()
AccessRegisters
AccessRegisters
rfalGetOperationStatus( )
DONE
Note: It is recommended to make use of the non blocking APIs as much as possible while integrating the RFAL into a
final project/product. Due to simplicity, code readability, prototyping purposes, and single task application (no
parallel/concurrent peripherals) some of the demonstration projects provided at st.com use blocking APIs. Each
SW developer must assess if such usage does not pose a thread and is acceptable for the targeted product and
system architecture.
In Figure 13 an edge-triggered IRQ is capable of handling multiple interrupts if these occur sufficiently apart so
that the ISR has already concluded.
Such are not ensured and therefore there is the possibility for an IRQ event to occur while the ISR is still running
and retrieving the information from IRQ status registers. When such occurs the IRQ goes back to high and
remains as the ISR is never triggered again due to the fact that an edge/transition is not observed again. This
causes the driver to stall because the new event has not been processed and upcoming ones is also not
detected.
To avoid that the IRQ pin is checked at the end of the ISR procedure verifying if a pending event has occurred. If
so, runs again the procedure retrieving the latest information.
Such check/loop is not required if the IRQ is configured as level-triggered and can be removed. As such handling
causes no harm and for the sake of interoperability the RFAL provides it by default.
6 Additional references
ID Reference
#ifdef LED_FIELD_Pin
#define PLATFORM_LED_FIELD_PIN LED_FIELD_Pin /*!< GPIO pin used as field LE
D */
#endif
#ifdef LED_FIELD_GPIO_Port
#define PLATFORM_LED_FIELD_PORT LED_FIELD_GPIO_Port /*!< GPIO port used as field L
ED */
#endif
#ifdef LED_RX_Pin
#define PLATFORM_LED_RX_PIN LED_RX_Pin /*!< GPIO pin used as field LE
D */
#endif
#ifdef LED_RX_GPIO_Port
#define PLATFORM_LED_RX_PORT LED_RX_GPIO_Port /*!< GPIO port used as field L
ED */
#endif
/*
******************************************************************************
* GLOBAL MACROS
******************************************************************************
*/
#define platformProtectST25RComm() do{ globalCommProtectCnt++; __DSB();NVI
C_DisableIRQ(EXTI0_IRQn);__DSB();__ISB();}while(0) /*!< Protect unique access to ST25R commun
ication channel - IRQ disable on single thread environment (MCU) ; Mutex lock on a multi thre
ad environment */
#define platformUnprotectST25RComm() do{ if (--globalCommProtectCnt==0) {NVI
C_EnableIRQ(EXTI0_IRQn);} }while(0) /*!< Unprotect unique access to ST25R comm
unication channel - IRQ enable on a single thread environment (MCU) ; Mutex unlock on a multi
thread environment */
#define platformLog(...)
/*!< Log method */
/*
******************************************************************************
* GLOBAL VARIABLES
******************************************************************************
*/
extern uint8_t globalCommProtectCnt; /* Global Protection Counter provid
ed per platform - instantiated in main.c */
/*
******************************************************************************
* RFAL FEATURES CONFIGURATION
******************************************************************************
*/
/*
******************************************************************************
* RFAL OPTIONAL MACROS (Do not change)
******************************************************************************
*/
#ifndef platformProtectST25RIrqStatus
#define platformProtectST25RIrqStatus() /*!< Protect unique access to IRQ status v
ar - IRQ disable on single thread environment (MCU) ; Mutex lock on a multi thread environmen
t */
#endif /* platformProtectST25RIrqStatus */
#ifndef platformUnprotectST25RIrqStatus
#define platformUnprotectST25RIrqStatus() /*!< Unprotect the IRQ status var - IRQ en
able on a single thread environment (MCU) ; Mutex unlock on a multi thread environment
*/
#endif /* platformUnprotectST25RIrqStatus */
#ifndef platformProtectWorker
#define platformProtectWorker() /* Protect RFAL Worker/Task/Process from c
oncurrent execution on multi thread platforms */
#endif /* platformProtectWorker */
#ifndef platformUnprotectWorker
#define platformUnprotectWorker() /* Unprotect RFAL Worker/Task/Process from
concurrent execution on multi thread platforms */
#endif /* platformUnprotectWorker */
#ifndef platformIrqST25RPinInitialize
#define platformIrqST25RPinInitialize() /*!< Initializes ST25R IRQ pin
*/
#endif /* platformIrqST25RPinInitialize */
#ifndef platformIrqST25RSetCallback
#define platformIrqST25RSetCallback( cb ) /*!< Sets ST25R ISR callback
*/
#endif /* platformIrqST25RSetCallback */
#ifndef platformLedsInitialize
#define platformLedsInitialize() /*!< Initializes the pins used as LEDs to
outputs */
#endif /* platformLedsInitialize */
#ifndef platformLedOff
#define platformLedOff( port, pin ) /*!< Turns the given LED Off
*/
#endif /* platformLedOff */
#ifndef platformLedOn
#ifndef platformLedToogle
#ifndef platformGetSysTick
#ifndef platformTimerDestroy
#define platformTimerDestroy( timer ) /*!< Stops and released the given timer
*/
#endif /* platformTimerDestroy */
#ifndef platformAssert
#ifndef platformErrorHandle
#endif /* RFAL_PLATFORM */
Application RF ST25R
rfalInitialize() Initialize()
SetConfigs()
DONE
rfalFieldOnAndStartGT() FieldOn()
DONE
In this simple example, often used for checking the basic functionality of a new HW setup, the application layer
initializes the RFAL which in turn initializes the NFC AFE by performing a reset sequence, loading initial
configurations and setting it into a defined state. Then field RF carrier is turned on by calling the
rfalFieldOnAndStartGT().
rfalNfcaPollerCheckPresence() ͙ TransceiveShortFrame()
Tech Detection
GT timer
Blocking Loop
TxRx()
IRQs
DONE DONE
͙ TransceiveAnticollisionFrame () TxRx()
NfcaPollerFullCollisionResolution()
IRQs
DONE
Blocking Loop
()
Col Resolution
͙ TransceiveAnticollisionFrame
TxRx()
IRQs
DONE
DONE
͙ PollAHandleActivation()
rfalTransceiveBlockingTxRx()
RFALWorker()
TxRx()
Activation
IRQs
DONE DONE
rfalIsoDepStartTransceive() rfalStartTransceive()
DONE DONE
Tx()
͙ GetTransceiveStatus() rfalGetTransceiveStatus()
BUSY BUSY
RFALWorker()
Data Echange
«IsoDepGetTransceiveStatus() rfalGetTransceiveStatus()
BUSY BUSY
IRQs
...IsoDepGetTransceiveStatus() rfalGetTransceiveStatus()
DONE DONE
Here the application activates an NFC-A T4T device and exchanges some data. In this example the application
makes direct use of the APIs available on NFC-A and ISO-DEP modules, and uses the blocking APIs for the
whole card activation process. It starts by initializing for NFC-A communication and enabling the field (RF carrier),
which starts the configured GT timer. Once the presence check/technology detection is executed, it waits until the
GT requirement is fulfilled (if not yet expired) and then transmit the polling command (SENS_REQ/REQA). As a
card(s) have been detected, the application goes into collision resolution calling
rfalNfcaPollerFullCollisionResolution(), a blocking API where some anticollision commands are
exchanged (actual number depends on several factors, such as the number of cards present and their NFCID).
When all Listeners/cards have been identified, the application can activate the one it wants to select (in case of
multiple, not shown here), and must activate one of the supported protocols (in this example ISO-DEP). To
activate the card in ISO14443-4, the API rfalIsoDepPollAHandleActivation() is used, it handles the
whole layer four activation procedures. This method exchanges one or more commands with the Listener device.
It must be highlighted that during this process longer timeouts/FWT are applied (~5 ms), the whole activation may
amount to several milliseconds. After activation, data exchange can flow naturally on top of the ISO-DEP protocol.
To achieve this the application performs ISO-DEP transceive operations (block or APDU), which internally handle
the protocol and trigger the lower level RF transceive process for the actual transmission and reception.
During protocol data exchange (ISO-DEP and NFC-DEP) the FWT can be quite long (up to 5 seconds), and when
combined with waiting time extensions and repetitions one single protocol transceive operation can take several
seconds. Due to this reason, RFAL does not provide (nor it is recommended) to perform blocking protocol
operations unless such long execution does not pose a difficulty to a particular application flow. On the sequence
above, after an initial rfalIsoDepStartTransceive() the method rfalIsoDepGetTransceiveStatus()
must be polled until the transceive operation is completed (not ERR_BUSY). The actual transmission and reception
is handled by the RF module in parallel via the rfalWorker(), and, once completed, the outcome is stored until
the rfalIsoDepGetTransceiveStatus() is called again.
Important: • The rfalGetOperationStatus() must be called/polled until the operation is completed, which means
that its returned value is different from ERR_BUSY. Once the operation is concluded and its outcome
returned, the caller must handle its result immediately. Calling the rfalGetOperationStatus()
thereafter does not ensure that the previous outcome and context remain valid (apart from specific
exceptions)
• Non-blocking APIs execute a certain procedure and have a defined start and end event. It is not allowed
to start another RFAL operation while a previous is ongoing. Doing so may lead to unexpected behaviour
and inconsistent state.
rfalNfcaPollerTechnologyDetection () ͙ TransceiveShortFrame()
Tech Detection
GT timer
Blocking Loop
TxRx()
IRQs
DONE DONE
..StartFullCollisionResolution()
DONE
͙ TransceiveAnticollisionFrame () TxRx()
..GetFullCollisionResolutionStatus()
IRQs
BUSY
DONE
Col Resolution
͙ TransceiveAnticollisionFrame ()
..GetFullCollisionResolutionStatus() TxRx()
BUSY IRQs
DONE
..GetFullCollisionResolutionStatus()
DONE
͙ PollAStartActivation()
DONE rfalStartTransceive()
Tx()
DONE
͙ PollAGetActivationStatus() IRQs
rfalGetTransceiveStatus()
DONE
BUSY
RFALWorker()
͙ PollAGetActivationStatus()
Activation
rfalStartTransceive()
Tx()
DONE
BUSY
͙ PollAGetActivationStatus()
rfalGetTransceiveStatus()
rfalIsoDepStartTransceive() rfalStartTransceive()
DONE DONE
Tx()
͙ GetTransceiveStatus() rfalGetTransceiveStatus()
BUSY BUSY
Data Echange
RFALWorker()
«IsoDepGetTransceiveStatus() rfalGetTransceiveStatus()
BUSY BUSY
IRQs
...IsoDepGetTransceiveStatus() rfalGetTransceiveStatus()
DONE DONE
Here the same card activation and data exchange shown in the previous section are achieved. The main
difference is that non-blocking APIs are used instead of the blocking ones during activation process. As usual the
non-blocking APIs initiate a procedure that must be polled until it has been completed, which now are also used
collision resolution and protocol activation. Another minor difference from the previous example is that during
protocol activation two frames are exchanged (for example RATS and PPS), showing that the protocol activation
may trigger one or more RF transceive operations within a single protocol activation operation.
Figure 18. NFC-A / ISO14443A activation and data exchange using RFAL HL
DONE SetConfigs()
DONE
rfalNfcDiscover()
DONE
rfalNfcaPollerTechnologyDetection () ͙ TransceiveShortFrame()
GT timer
Blocking Loop
rfalNfcGetState() TxRx()
POLL_TECHDETECT IRQs
DONE DONE
..StartFullCollisionResolution()
rfalNfcGetState()
rfalGetState()
DONE
POLL_COLAVOIDANCE ͙ TransceiveAnticollisionFrame () TxRx()
..GetFullCollisionResolutionStatus()
IRQs
BUSY
DONE
rfalNfcGetState()
POLL_COLAVOIDANCE
͙ TransceiveAnticollisionFrame ()
..GetFullCollisionResolutionStatus() TxRx()
BUSY IRQs
Discovery
DONE
..GetFullCollisionResolutionStatus()
DONE
͙ PollAStartActivation()
DONE rfalStartTransceive()
Tx()
rfalNfcWorker()
DONE
͙ PollAGetActivationStatus() IRQs
rfalGetTransceiveStatus()
DONE
BUSY
rfalNfcGetState()
POLL_ACTIVATION
RFALWorker()
͙ PollAGetActivationStatus()
rfalStartTransceive()
Tx()
DONE
BUSY
͙ PollAGetActivationStatus()
rfalGetTransceiveStatus()
DataExchangeStart()
DONE
StartAPDUTransceive() rfalStartTransceive()
DONE DONE
Tx()
͙ Get APDU TransceiveStatus()
rfalGetTransceiveStatus()
BUSY BUSY
Data Echange
DataExchangeGetStatus()
BUSY
RFALWorker()
BUSY BUSY
DataExchangeGetStatus() IRQs
BUSY
͙ Get APDU TransceiveStatus() rfalGetTransceiveStatus()
DONE
The same card activation and data exchange shown before are achieved. The main difference is that the NFC
module on RFAL HL is used. This module conveniently handles all different activities/procedures with minimal
user/application interaction. User simply needs to initialize the RFAL, start the discovery process, and exchange
the desired data when a device is activated. The whole Listener/card discovery process (technology detection,
collision resolution and activation) is handled internally and the application monitors the present state by polling
the current state via rfalNfcGetState() or by registering with the optional notification callback (notifyCb). The
NFC module notifies noteworthy events/states as it evolves. Similarly to the previous examples, once Listener has
been activated, data exchange is performed via tranceive operations. In this case using the RFAL HL - NFC
module can be achieved by the API pair rfalNfcDataExchangeStart() and GetDataExchangeStatus().
DONE SetConfigs()
DONE
rfalNfcDiscover()
DONE
rfalNfcGetState() rfalNfcfPollerStartCheckPresence ()
GT timer
rfalStartFeliCaPoll()
POLL_TECHDETECT
DONE DONE
..GetCheckPresenceStatus () ...GetFeliCaPollStatus()
Tx()
BUSY BUSY
ISRs
..GetCheckPresenceStatus () ...GetFeliCaPollStatus()
DONE DONE
Discove
ry
..StartCollisionResolution()
rfalNfcGetState()
rfalGetState()
DONE
POLL_COLAVOIDANCE rfalStartFeliCaPoll()
..GetCollisionResolutionStatus()
DONE
BUSY
rfalNfcGetState()
..GetCollisionResolutionStatus()
POLL_COLAVOIDANCE
ralGetFeliCaPollStatus () TxRx()
BUSY BUSY
ISRs
rfalNfcWorker()
..GetCollisionResolutionStatus() ralGetFeliCaPollStatus ()
DONE DONE
notifyCb()
DataExchangeStart()
rfalStartTransceive()
DONE DONE
DataExchangeGetStatus() rfalGetTransceiveStatus()
BUSY BUSY
Tx()
DataExchangeGetStatus() rfalGetTransceiveStatus()
Data Echange
BUSY BUSY
RFALWorker()
DataExchangeGetStatus() rfalGetTransceiveStatus()
BUSY BUSY
ISRs
DataExchangeGetStatus() rfalGetTransceiveStatus()
DONE DONE
In this example a sequence where activation and data exchange is shown again. The main difference in this
example is that the Listener is an NFC-F T3T that does not use a data exchange protocol. Therefore no protocol
activation is performed, and the RF interface is used for data exchange. An analogous flow takes place when
dealing with an NFC-V T5T.
Figure 20. AP2P initiator activation and data exchange using RFAL HL
rfalNfcDiscover()
DONE
rfalSetMode() SetConfigs()
rfalFieldOnStartGT()
NfcDepInitiatorHandleActivation
() rfalStartTransceive( ) Tx()
rfalGetTransceiveStatus()
RFALWorker()
Blocking Loop
BUSY
Discovery
IRQs
rfalGetTransceiveStatus()
DONE
notifyCb() DONE
DataExchangeStart()
NfcNfcDepActivate
DONE
NfcDepStartTransceive() rfalStartTransceive()
DONE DONE Tx()
IRQs
DataExchangeGetStatus() NfcDepGetTransceiveStatus() rfalGetTransceiveStatus()
DataExchangeStart()
DONE
DataExchangeGetStatus() NfcDepStartTransceive() rfalStartTransceive()
BUSY DONE DONE Tx()
As in AP2P, there is no collision resolution phase (apart from RF collision avoidance procedure), the Initiator
transmits the protocol activation command (ATR_REQ). Once activation is completed, it goes into data exchange
and performs a series transceive operations.
Figure 21. AP2P target activation and data exchange using RFAL HL
rfalNfcDiscover()
DONE
rfalListenStart() SetConfigs()
rfalListenGetState()
POWER_OFF
Field ISR
EnableListen()
RFListenGetState()
RFALWorker()
IDLE
rfalNfcGetState()
LISTEN_TECHDETECT IRQs
RFListenGetState()
IDLE (*DATA)
EOF
isATRCheck()
Discovery
TRUE
ListenSetState(TARGET_A) SetActive A
NfcDepListenStartActivation() rfalStartTransceive( )
Tx()
NfcDepListenGetActivationStatus
() rfalGetTransceiveStatus()
BUSY BUSY
rfalNfcWorker()
rfalNfcGetState()
rfalGetState()
IRQs
LISTEN_COLAVOIDANCE NfcDepListenGetActivationStatus
() rfalGetTransceiveStatus()
DONE DONE
notifyCb()
DataExchangeStart()
DONE
DataExchangeGetStatus()
DONE
Data Echange
DataExchangeStart()
NfcDepStartTransceive() rfalStartTransceive()
Tx()
BUSY
IRQs
DataExchangeGetStatus() NfcDepGetTransceiveStatus() rfalGetTransceiveStatus()
Here we can observe an activation and following data exchange when in listen mode. As before in AP2P there is
no collision resolution phase (apart from RF collision avoidance procedure) and the Initiator goes straight to
transmitting the protocol activation command (ATR_REQ). As a Listener this frame is received while the generic
listen mode handler in RF layer which output the payload received. This payload is then verified by the protocol
layer (NFC-DEP in this case), and if as expected the protocol activation handler is executed which provides an
answer to the ATR_REQ received. In case the frame received is already a data packet (no parameter change
PSL_REQ) the activation is terminated and data exchange is entered.
Important to highlight that in lsten mode if a data packet is received during activation, it is then retrieved by the
first time the data exchange / transceive methods are called. In the sequence above one can observe that the first
time rfalNfcDataExchangeStart() / rfalNfcDataExchangeGetStatus() are called no actual
exchange takes place. Instead the data received from the Poller/Initiator is immediately handed over to the caller
for processing.
AP2P target activation (including PSL_REQ) and data exchange using RFAL HL
rfalNfcDiscover()
DONE
rfalListenStart() SetConfigs()
rfalListenGetState()
POWER_OFF
Field ISR
EnableListen()
RFListenGetState()
RFALWorker()
IDLE
rfalNfcGetState()
LISTEN_TECHDETECT IRQs
RFListenGetState()
IDLE (*DATA)
EOF
isATRCheck()
Discovery TRUE
ListenSetState(TARGET_A) SetActive A
NfcDepListenStartActivation() rfalStartTransceive( )
Tx()
NfcDepListenGetActivationStatus
() rfalGetTransceiveStatus()
BUSY BUSY
rfalNfcGetState()
rfalGetState()
IRQs
rfalNfcWorker()
LISTEN_COLAVOIDANCE
Tx()
NfcDepListenGetActivationStatus
() rfalGetTransceiveStatus()
DONE DONE
notifyCb()
DataExchangeStart()
DONE
DataExchangeGetStatus()
rfalNfcDepGetTransceiveStatus() rfalGetTransceiveStatus()
IRQs
DataExchangeGetStatus()
NfcDepGetTransceiveStatus() rfalGetTransceiveStatus()
DataExchangeStart()
NfcDepStartTransceive() rfalStartTransceive()
Tx()
BUSY
IRQs
DataExchangeGetStatus() NfcDepGetTransceiveStatus() rfalGetTransceiveStatus()
This example is the same as the previous with one additional frame (PSL_REQ) during activation. The PSL
allows to modify some parameters of the upcoming communication, and once acknowledged the activation
procedure is completed moving into data exchange. This therefore results in a different flow as the data is not
readily available on the first time rfalNfcDataExchangeStart() / rfalNfcDataExchangeGetStatus()
are called.
Figure 23. NFC-A / ISO14443 Listener activation and data exchange using RFAL HL
rfalNfcDiscover()
DONE
rfalListenStart() SetConfigs()
rfalListenGetState()
POWER_OFF
Field ISR
EnableListen()
RFListenGetState()
IDLE
rfalNfcGetState()
LISTEN_TECHDETECT IRQs
RFListenGetState()
READY_A
IRQs
IRQs
RFListenGetState()
READY_A IRQs
rfalNfcGetState()
rfalGetState()
LISTEN_COLAVOIDANCE IRQs
Discovery
IRQs
RFListenGetState()
ACTIVE_A(*DATA)
isRATS()
TRUE
rfalNfcWorker()
ListenSetState(CARDEMU_4A)
RFALWorker()
...ListenStartActivation() rfalStartTransceive( )
DONE DONE
Tx()
...ListenGetActivationStatus() rfalGetTransceiveStatus()
BUSY BUSY
rfalNfcGetState()
rfalGetState()
LISTEN_ACTIVATION
IRQs
͙ ListenGetActivationStatus() rfalGetTransceiveStatus()
DONE DONE
notifyCb()
DataExchangeStart()
DONE
DataExchangeGetStatus()
...GetTransceiveStatus()
DONE DONE
DataExchangeStart()
Data Echange
...StartTransceive() rfalStartTransceive()
DONE
Tx()
DataExchangeGetStatus() ...GetTransceiveStatus() rfalGetTransceiveStatus()
IRQs
DataExchangeGetStatus() ...GetTransceiveStatus() rfalGetTransceiveStatus()
In this example the ST25R is activated as a Listener device in T4T CE mode. Once the listen mode is started, the
anticollision sequence is handled, and the device is selected, the ACTIVE_A state is reached. Once the following
command is received (RATS), the payload is handed over so that the protocol layer (ISO-DEP) checks its validity.
The protocol activation is started responding to the RATS. Afterwards, a data packets is received, which
concludes the protocol activation (no PPS). As before, received data are passed on the first call of the data
exchange to be handled by the application. Then other data exchanges can take place normally.
Figure 24. NFC-F / FeliCa Listener activation and data exchange using RFAL HL
rfalNfcDiscover()
DONE
rfalListenStart() SetConfigs()
rfalListenGetState()
POWER_OFF
Field ISR
EnableListen()
RFListenGetState()
IDLE
rfalNfcGetState()
LISTEN_TECHDETECT IRQs
RFListenGetState()
READY_F
IRQs
Discovery
RFListenGetState()
READY_F
rfalNfcGetState()
rfalGetState()
LISTEN_COLAVOIDANCE
IRQs
rfalNfcWorker()
RFListenGetState()
ACTIVE_F(*DATA)
ListenSetState(CARDEMU_3) RFALWorker()
notifyCb()
DataExchangeStart()
DONE
DataExchangeGetStatus()
DONE
DataExchangeStart()
Data Echange
rfalStartTransceive()
DONE
Tx()
DataExchangeGetStatus() rfalGetTransceiveStatus()
BUSY BUSY
IRQs
DataExchangeGetStatus() rfalGetTransceiveStatus()
DONE DONE
In this example the ST25R is activated as a Listener device in T3T CE mode. It is the same as the previous flow
T4T flow, without the protocol activation, as T3T does not require a particular data exchange protocol.
rfalNfcInitialize()
rfalInitialize() Initialize()
SetConfigs()
DONE DONE
rfalNfcDiscover()
DONE
rfalNfcaPollerInitialize() rfalSetMode() SetConfigs()
rfalFieldOnStartGT()
rfalNfcaPollerTechnologyDetection () ͙ TransceiveShortFrame()
GT timer
TxRx()
IRQs
DONE DONE
rfalNfcbPollerInitialize()
rfalFieldOnStartGT()
rfalNfcbPollerTechnologyDetection () ͙ TransceiveBlockingTxRx()
GT timer
TxRx()
IRQs
DONE DONE
Discovery
rfalNfcWorker()
RFALWorker()
rfalNfcfPollerInitialize()
rfalFieldOnStartGT()
rfalNfcfPollerStartCheckPresence () rfalStartFeliCaPoll()
GT timer
DONE DONE
rfalNfcGetState()
POLL_TECHDETECT
TxRx()
IRQs
rfalNfcfPollerGetCheckPresenceStatus () rfalGetFeliCaPollStatus()
DONE DONE
rfalNfcvPollerInitialize()
rfalFieldOnStartGT()
...PollerCheckPresence() rfalNfcvPollerInventory()
GT timer
TxRx()
IRQs
DONE DONE
Here the NFC module is configured to poll for NFC-A, NFC-B, NFC-F, and NFC-V. In this case no card is
presented and the different technologies are polled with timeout error. Once all technologies have been executed,
the module waits to complete the request total duration (if not expired) and poll again in the same manner.
Revision history
Table 12. Document revision history
Contents
1 Acronyms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2
2 RFAL library . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3
2.1 Features overview. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
2.2 Description . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
2.3 Coding rules and conventions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
2.3.1 Coding conventions. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
2.3.2 Run time checking . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
2.3.3 MISRA-C 2012 compliance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
2.3.4 NFC nomenclature . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.4 Hardware . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.4.1 Requirements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.4.2 Supported host devices. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.5 Software . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.5.1 Dependencies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.5.2 Supported development tools . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.6 Architecture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2.6.1 RF HAL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2.6.2 RF AL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
2.6.3 RF HL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
2.6.4 Overview. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
2.6.5 Concurrency . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
3 Releases . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .19
3.1 Package description . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
3.2 Quality criteria . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
4 How to use the RFAL library . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .20
4.1 Peripherals initialization and configuration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
4.2 Library configurations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
4.3 How to run the first example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
5 FAQs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .25
5.1 Detailed information of each RFAL API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
5.2 Calculating RFAL library footprint . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
5.3 Using a custom analog configuration table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
5.4 Changing AM modulation index. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
5.5 Changing AM/OOK modulation type. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
5.6 Usage of user defined data types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
List of tables
Table 1. Applicable products . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
Table 2. Acronyms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
Table 3. Supported modes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
Table 4. NFC-A/NFC-B Poller (ISO144443A/B reader) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
Table 5. NFC-V Poller (ISO15693 reader) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
Table 6. NFC forum universal device . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
Table 7. NFC-A/NFC-B Poller (ISO144443A/B Reader) with RFAL HL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
Table 8. NFC-A passive Listener (CE). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
Table 9. NFC-F passive Listener (CE). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
Table 10. NFC-A/NFC-B Listener (ISO144443A/B CE) with RFAL HL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
Table 11. Full featured RFAL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
Table 12. Document revision history . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
List of figures
Figure 1. RFAL stack architecture. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
Figure 2. Analog configuration sequence . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
Figure 3. Analog configuration tab . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
Figure 4. NFC module state diagram. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
Figure 5. System overview. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
Figure 6. Concurrency without protection. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
Figure 7. Concurrency with protection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
Figure 8. RFAL package structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
Figure 9. Blocking API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
Figure 10. Non blocking API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
Figure 11. Non-blocking API: rfalWorker() detailed . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
Figure 12. Edge-triggered ISR: OK . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
Figure 13. Edge-triggered ISR: fail . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
Figure 14. Edge-triggered ISR: loop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
Figure 15. RFAL initialization and RF carrier on . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
Figure 16. NFC-A / ISO14443A blocking activation and data exchange . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
Figure 17. NFC-A / ISO14443A activation and data exchange . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
Figure 18. NFC-A / ISO14443A activation and data exchange using RFAL HL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
Figure 19. NFC-V/FeliCa activation and data exchange using RFAL HL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
Figure 20. AP2P initiator activation and data exchange using RFAL HL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
Figure 21. AP2P target activation and data exchange using RFAL HL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
Figure 22. Additional frame (PSL_REQ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
Figure 23. NFC-A / ISO14443 Listener activation and data exchange using RFAL HL . . . . . . . . . . . . . . . . . . . . . . . . . . 48
Figure 24. NFC-F / FeliCa Listener activation and data exchange using RFAL HL. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
Figure 25. Polling cycle using RFAL HL. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50