The EZRadioPro Si4x6x family consists of high-performance transceivers covering the sub-GHz frequency bands, while the EFR32 product family provides high-performance SOCs that combine an energy-friendly MCU with a highly integrated radio transceiver that covers sub-GHz frequency bands and the 2.4GHz frequency band.
This document provides some assistance for migrating from the EZRadioPro family to the EFR32 chip family. The main differences in firmware development (such as initialization, transmit, rx start and packet downloading) between the two chip families are described here. It is highly recommended that the customer read the corresponding data sheets, reference manual, and application notes when converting a design from the EZRadioPro family to the EFR32 family.
2. General Differences between EZRadioPro and EFR32
Radio usage and control differs between EZRadioPro and EFR32 due to their different chip architectures.
The EZRadioPro is a transceiver. It provides a SPI interface for the host MCU to control the operations of the chip by sending commands to (or getting responses from) the radio chip. The commands and properties that control the chip are defined in API documents, and the application FW (firmware) runs on the host MCU.
The EFR32 family uses RAIL (Radio Abstraction Interface Layer). As a SOC device, the integrated radio component can be treated as a peripheral of the chip. In order to simplify access to the radio hardware, Silabs provides an interface layer (RAIL) for developers. The developer can simply treat RAIL as a library which provides the APIs to access the radio hardware of the chip.
The table below shows the main differences between EZRadioPro and EFR32 usage.
EZRadioPro
EFR32
Example Chip
Si446x
EFR32FG
Chip Architecture
Transceiver
SOC
Frequency Bands
Sub-G
Sub-G, 2.4G, or Sub-G plus 2.4G bands
Development Tool
WDS
Simplicity Studio
Radio Configuration Generation
radio_config.h (from WDS)
rail_config.h/c (from the radio configurator in Simplicity Studio)
Radio Operation Interface
Command/property via SPI with Host
RAIL
Application
Host MCU application
Application on top of RAIL inside SOC
Event Handling
Interrupt plus pending bit
Callbacks plus events
FIFO
TX FIFO (64 Bytes)
RX FIFO (64 Bytes)
Shared FIFO (129 Bytes)
TX FIFO (defined by application)
RX FIFO (512 Bytes by default)
Payload field
Maximum 5 payload fields
One payload field
Downloading Rx data
Read data via SPI command by Host
Read Rx data from RX FIFO
In Sections 3~6, the differences in initialization, transmission and reception are described.
3. Difference in Initialization
For chip initialization, both EZRadioPro and EFR32 need register/API values. They use different radio configurator tools to generate register settings based on the radio/modem /packet information input by the developer. EZRadioPro uses the WDS radio configurator, while EFR32 uses the radio configurator within Simplicity Studio (presented as a component within AppBuilder, the tool that configures a project’s .isc file). For further information on radio configurator usage, please refer to AN692 (for EZRadioPro) or AN971 (for EFR32).
If the developer wants the packet to be correctly received, configurations in both the transmitter and receiver sides should match, including: RF parameters (frequency, data rate, channel, etc.), structure of the packet (preamble, sync words, header, crc, etc.), symbol coding, etc. Regarding the structure of the packet, there is an obvious difference in that one EZRadioPro packet can contain a maximum of 5 packet fields (and every field can be configured individually), but for EFR32 one packet always contains just one payload field.
Here we describe the differences of initialization between EZRadioPro and EFR32 using the example projects “Bidirectional Packet” and “Simple_rail_with_hal”, which can be separately generated from WDS and Simplicity Studio (respectively).
EZRadioPro:
In the EZRadioPro chip, commands should be sent to the chip via SPI. The developer can refer to the sample projects provided in WDS, like Bidirectional Packet project. This example will be used in this section to show the differences between EZRadioPro family and EFR32 family.
The following is the pseudo code snippet to show the initialization steps. The developer invokes these functions in the host MCU project to send commands to or get responses from the radio chip via SPI.
Step 2: Send the chip register/API setting values to the chip in si446x_configuration_init() function via SPI. The radio/modem/packet/PA setting is generated by WDS and stored in radio_config.h header file.
Step 3: Invoke the function si446x_get_int_status(0u, 0u, 0u) at the end of the initialization function to clear pending interrupts with GET_INT_STATUS command. Please note that this function should be called to clear the pending interrupt after interrupt happens or before entering sleep mode.
Chapter 8 of AN633 describes more details about the initialization for EZRadioPro.
EFR32:
he developer can directly invoke APIs to implement the initialization for EFR32. The following is the pseudo code snippet to show the initialization steps for EFR32:
Step 1: Invoke halInit() to initialize system clock and the peripherals that the project uses.
Step 2: Invoke RAIL_Init() to initialize the RAIL. The parameter railCfg of this function includes a callback, where the events of RAIL should be handled in the application layer of the project, such as RAIL_EVENT_TX_PACKET_SENT, RAIL_EVENT_RX_PACKET_RECEIVED, etc. This function will return a handle which will be used when invoking other RAIL APIs.
Step3: The developer should also initialize RAIL calibration with RAIL_ConfigCal(). Calibration initialization provides the calibration settings that correspond to the current radio configuration.
Step 4: Before performing any radio operations, invoke RAIL_ConfigChannels() to set a valid channel for radio. It will also configure the relevant radio registers with the input parameters. The parameters related to the channels come from rail_config.h, which is generated by the radio configurator in Simplicity Studio. Simplicity Studio provides an easy way (GUI) for developers to configure the parameters and generate the PHY setting of the channel.
Step 5: The developer should invoke the RAIL_ConfigTxPower() and RAIL_SetTxPower() to set the PA mode and Tx power. Note that the second parameter of the RAIL_SetTxPower() is PA power level. The actual Tx power corresponding to the power level can be found with the method described in AN1127. Also refer to the PA conversions plugin in radio configurator (or PA of the hardware configurator defined in .hwconf) of Simplicity Studio.
Here we describe the differences of transmit between EZRadioPro and EFR32, using the example projects “Bidirectional Packet” and “Simple_trx_with_fifo”.
EZRadioPro:
The chip contains one Tx FIFO (64 Bytes) and one Rx FIFO (64 Bytes). This size cannot be changed (note that for EFR32, the application defines Tx FIFO size), but the chip can be instead configured to have a unified 129 Bytes FIFO shared by both Tx and Rx operation (Refer to API document about property GLOBAL_CONFIG :
FIFO_MODE).
The following pseudo code snippet shows how to start transmitting and how to handle the tx events. The developer invokes these functions in the host MCU project to send commands to or get responses from the radio chip via SPI.
//write fifo and start tx
si446x_change_state (SI446X_CMD_CHANGE_STATE_ARG_NEXT_STATE1_NEW_STATE_ENUM_READY);
si446x_get_int_status (0u, 0u, 0u);
si446x_fifo_info (SI446X_CMD_FIFO_INFO_ARG_FIFO_TX_BIT);
si446x_write_tx_fifo (length, pioRadioPacket);
si446x_start_tx (channel, 0x80, length);
//check and handle tx events
si446x_get_int_status (0u, 0u, 0u);
if (Si446xCmd.GET_INT_STATUS.PH_PEND & SI446X_CMD_GET_INT_STATUS_REP_PH_PEND_PACKET_SENT_PEND_BIT){…}
if (Si446xCmd.GET_INT_STATUS.PH_PEND & SI446X_CMD_GET_INT_STATUS_REP_PH_PEND_TX_FIFO_ALMOST_EMPTY_PEND_BIT){…}
Step 1: Send data to Tx FIFO. Before starting transmitting, the developer should send the packet payload to the Tx FIFO of the radio chip via SPI. If the payload length is greater than the size of the Tx FIFO, the developer can use the TX_FIFO_ALMOST_EMPTY interrupt to send the payload to the Tx FIFO in several segments. As with the EFR32, the developer should set a threshold value for the Tx FIFO threshold property PKT_TX_THRESHOLD. An interrupt is generated when the amount of empty space in the Tx FIFO is equal to or greater than this threshold. When event TX_FIFO_ALMOST_EMPTY_PEND (Refer to API document about command GET_INT_STATUS: PH_PEND: TX_FIFO_ALMOST_EMPTY_PEND) happens, the application should send more payload bytes to Tx FIFO.
It is suggested that before transmitting starts, the application should reset the chip FIFO with si446x_fifo_info() and clear the previous pending interrupt with si446x_get_int_status (0u, 0u, 0u).
Step 2: Use si446x_start_tx() to startup transmitting. Note that if the parameter TX_LEN of this command is non-zero, the packet will be transmitted with TX_LEN number of data bytes with the definition in the packet field 1 (PKT_FIELD_1_X) configuration options (e.g., CRC, data whitening, Manchester coding, etc.). If TX_LEN is zero, the chip will transmit the data according to the configuration of the packet fields properties PKT_FIELD_X_X (Refer to API document about command START_TX).
Step 3: Check and handle the events. The host MCU application should check the status if an event happens.
The interrupt event (TX_FIFO_ALMOST_EMPTY or PACKET_SENT) is defined in the radio_config.h and enabled in WDS based on the customer selection.
If the relevant interrupts are enabled and one or more enabled interrupts happen, nIRQ pin will be put low. The host MCU application should use si446x_get_int_status() to get status of the chip (Refer to API document about command GET_INT_STATUS) and check which interrupt happened and handle it accordingly.
Settings about state transition. The radio chip can automatically change state after completion of a packet transmission. To achieve this purpose, a desired state defined in TXCOMPLETE_STATE should be passed with the command START_TX (Refer to API document about command START_TX).
EFR32:
The following pseudo code snippet shows the transmit steps for EFR32 (config the events, set/write Tx FIFO, start tx, and events handling):
Step 1: To transmit a packet, application FW should first set a buffer as the RAIL Tx FIFO. Note that it can only handle Tx buffer sizes of a power of 2 between 64 and 4096. The pointer of the buffer is passed to RAIL as a parameter of RAIL_SetTxFifo() . Before calling this function, initialize the buffer with the transmitted payload data so that the transmitted payload data can be passed to Tx FIFO with this function. Another method to pass the transmitted payload data to Tx FIFO is to invoke RAIL_WriteTxFifo() after setting the Tx FIFO (with RAIL_SetTxFifo()).
Step 2: RAIL_StartTx() should be invoked to send out the packet data in Tx FIFO. When invoking this function, the developer should specify the channel on which the radio will transmit the packet. Some options can be set for the transmission of the packet, such as waiting for ACK, needing CCA etc.
Step 3: Upon finishing transmitting a packet, event RAIL_EVENT_TX_PACKET_SENT will happen. If the length of the packet is greater than the size of Tx FIFO, another event RAIL_EVENT_TX_FIFO_ALMOST_EMPTY is useful (see the description of the event in RAIL API document). While handling this event, we can write more packet data to Tx FIFO – even though the transmit process is still on going. The developer should set a threshold value for the event RAIL_EVENT_TX_FIFO_ALMOST_EMPTY using RAIL_SetTxFifoThreshold().
The developer should configure these events during initialization with RAIL_ConfigEvents(). Note that the process of event handling is in interrupt context, so they should be handled as fast as possible.
Setting up state transitions after transmitting. After transmitting (either successfully or not), what is the next state of the radio? RAIL provides a way to configure automatic state transitions. To use this function, the developer should use RAIL_SetTxTransitions() to set the automatic states (RX or IDLE) before transmitting (see the RAIL API document). Of course, the developer can also manually change the radio states using RAIL_Idle() and RAIL_StartRx().
Here we describe the differences of rx start between EZRadioPro and EFR32 using the example projects “Bidirectional Packet” and “Simple_trx_with_fifo”.
EZRadioPro:
The following pseudo code snippet shows how to start Rx and how to handle the Rx events. The developer invokes these functions in the host MCU project to send commands to or get responses from the radio chip via SPI.
As mentioned in the previous chapter, the chip has two FIFOs: Tx FIFO (64 Bytes) and Rx FIFO (64 Bytes). They can be combined into one FIFO (129 Bytes) as a shared FIFO for both Tx and Rx (Refer to API document about property GLOBAL_CONFIG:FIFO_MODE ). Note that developers should make sure that the data in the shared FIFO will not be lost when the state changes between Tx and Rx.
Step 1: Use si446x_start_rx() to start Rx. Three next states may be passed with this command to make the radio chip automatically enter to a desired state upon timeout of preamble detection, reception of a valid packet or reception of an invalid packet.
The packet can include maximum of 5 fields. Note that if the parameter length argument of this command is non-zero, the radio chip will receive and decode the packet based on the definition in the packet field 1 (PKT_FIELD_1_X) configuration options (e.g., CRC, data whitening, Manchester coding, etc.). If length is zero, the chip will receive the packet according to the configuration of the packet fields properties PKT_FIELD_X_X (Refer to API document about command START_RX).
Step 2: Handle the Rx events. During reception, the host MCU should check the status of the radio chip by si446x_get_int_status (0u, 0u, 0u). If the relevant interrupts are previously enabled and the interrupt happens, the nIRQ pin will put low to inform the host MCU that events have happened. If a whole packet is received, interrupt PACKET_RX_PEND (Refer to API document about command GET_INT_STATUS : PH_PEND: PACKET_RX_PEND ) will happen. The host MCU can use command READ_RX_FIFO to read the received data from Rx FIFO. If the size of the whole packet is greater than that of Rx FIFO, the event RX_FIFO_ALMOST_FULL_PEND is useful. When this event happens, the host MCU should immediately read the received data bytes from the Rx FIFO to avoid overflow. The threshold should be set in property PKT_RX_THRESHLOD .
It is suggested that before Rx start, the developer should reset the chip FIFO with si446x_fifo_info() and clear the previous pending interrupt with si446x_get_int_status (0u, 0u, 0u).
EFR32:
The following pseudo code snippet shows the starting Rx steps for EFR32 (config the events, start rx and events handling):
RAIL_ConfigEvents (railHandle,
RAIL_EVENTS_ALL,
(RAIL_EVENT_RX_PACKET_RECEIVED
| RAIL_EVENT_RX_FIFO_OVERFLOW
| RAIL_EVENT_RX_FIFO_ALMOST_FULL
| RAIL_EVENT_RX_SYNC1_DETECT));
RAIL_SetRxFifoThreshold (railHandle, RX_FIFO_THRESHOLD);
RAIL_StartRx (railHandle, channel, NULL);
if (events & RAIL_EVENT_RX_SYNC1_DETECT) {…}
if (events & RAIL_EVENT_RX_PACKET_RECEIVED) {…}
if (events & RAIL_EVENT_RX_FIFO_ALMOST_FULL) {…}
if (events & RAIL_EVENT_RX_FIFO_OVERFLOW) {…}
Step 1: The developer invokes RAIL_StartRx() to start Rx. The channel number should be passed with this function, so the radio component is able to correctly receive and decode the packet.
Step 2: Handle events. If an event happens, the event can be handled in the callback. Of course, the developer needs to have previously configured the Rx events.
By default, the size of the Rx FIFO is 512 bytes (max value), so if the size of a packet is greater than that, developer should handle the event RAIL_EVENT_RX_FIFO_ALMOST_FULL and read the received data bytes from Rx FIFO to avoid overflow. The developer should set a threshold value using RAIL_SetRxFifoThreshold().
When the chip receives a whole packet, event RAIL_EVENT_RX_PACKET_RECEIVED will be generated. The developer should handle these events as soon as possible. For more on this topic, see the article: RAIL Tutorial 3: Event Handling
Setting up the state transitions. Similar to Tx, after receiving (either successfully or not), the radio can transition to a predefined state (RX/IDLE) automatically. The next state can be set using function RAIL_SetRxTransitions(). Of course, the developer can also manually change the radio state using RAIL_Idle() and RAIL_StartRx().
6. Downloading the Packet
Here we describe the differences about downloading the packet between EZRadioPro and EFR32 using the example projects “Bidirectional Packet” and “Simple_trx_with_fifo”.
EZRadioPro:
The following pseudo code snippet shows how to download the packet from the Rx FIFO. The developer invokes these functions in the host MCU project to send commands to or get responses from radio chip via SPI.
When RX_FIFO_ALMOST_FULL_PEND or PACKET_RX_PEND event happened, the application can use command si446x_read_rx_fifo() to get the received data from radio chip. Before that, use si446x_fifo_info() to get the length of the received packet in Rx FIFO.
For event RX_FIFO_ALMOST_FULL_PEND. the developer should set threshold in property PKT_RX_THRESHOLD.
EFR32:
The following pseudo code snippet shows how to download the packet from the Rx FIFO.
When the amount of the received data bytes in Rx FIFO is equal to or greater than the threshold, event RAIL_EVENT_RX_FIFO_ALMOST_FULL will happen. At this moment, the application can use RAIL_ReadRxFifo() to read the received data. Before reading, the application should get the packet length of the received packet in Rx FIFO with RAIL_GetRxFifoBytesAvailable().
When a whole packet is received, event RAIL_EVENT_RX_PACKET_RECEIVED will happen, the application can read out the data from RX FIFO by RAIL_ReadRxFifo(). The application can also obtain more detailed information about the packet with RAIL_GetRxPacketDetails().
Proprietary Knowledge Base
Si4x55 EZRadio API guide
Question
Where can I find the AN691: EZRadio API Guide application note?
Answer
AN691 is obsolete for a long time and not available on silabs.com.
API documentation is provided in html format and can be found at
EZRadio API Rev B1A
or at
EZRadio API REVC2A
Pick the one that matches your chip revision.
Differences between the usage of EZRadioPro Si4x6x and EFR32 for proprietary protocols
1. Introduction
The EZRadioPro Si4x6x family consists of high-performance transceivers covering the sub-GHz frequency bands, while the EFR32 product family provides high-performance SOCs that combine an energy-friendly MCU with a highly integrated radio transceiver that covers sub-GHz frequency bands and the 2.4GHz frequency band.
This document provides some assistance for migrating from the EZRadioPro family to the EFR32 chip family. The main differences in firmware development (such as initialization, transmit, rx start and packet downloading) between the two chip families are described here. It is highly recommended that the customer read the corresponding data sheets, reference manual, and application notes when converting a design from the EZRadioPro family to the EFR32 family.
2. General Differences between EZRadioPro and EFR32
Radio usage and control differs between EZRadioPro and EFR32 due to their different chip architectures.
The EZRadioPro is a transceiver. It provides a SPI interface for the host MCU to control the operations of the chip by sending commands to (or getting responses from) the radio chip. The commands and properties that control the chip are defined in API documents, and the application FW (firmware) runs on the host MCU.
The EFR32 family uses RAIL (Radio Abstraction Interface Layer). As a SOC device, the integrated radio component can be treated as a peripheral of the chip. In order to simplify access to the radio hardware, Silabs provides an interface layer (RAIL) for developers. The developer can simply treat RAIL as a library which provides the APIs to access the radio hardware of the chip.
The table below shows the main differences between EZRadioPro and EFR32 usage.
EZRadioPro
EFR32
Example Chip
Si446x
EFR32FG
Chip Architecture
Transceiver
SOC
Frequency Bands
Sub-G
Sub-G, 2.4G, or Sub-G plus 2.4G bands
Development Tool
WDS
Simplicity Studio
Radio Configuration Generation
radio_config.h (from WDS)
rail_config.h/c (from the radio configurator in Simplicity Studio)
Radio Operation Interface
Command/property via SPI with Host
RAIL
Application
Host MCU application
Application on top of RAIL inside SOC
Event Handling
Interrupt plus pending bit
Callbacks plus events
FIFO
TX FIFO (64 Bytes)
RX FIFO (64 Bytes)
Shared FIFO (129 Bytes)
TX FIFO (defined by application)
RX FIFO (512 Bytes by default)
Payload field
Maximum 5 payload fields
One payload field
Downloading Rx data
Read data via SPI command by Host
Read Rx data from RX FIFO
In Sections 3~6, the differences in initialization, transmission and reception are described.
3. Difference in Initialization
For chip initialization, both EZRadioPro and EFR32 need register/API values. They use different radio configurator tools to generate register settings based on the radio/modem /packet information input by the developer. EZRadioPro uses the WDS radio configurator, while EFR32 uses the radio configurator within Simplicity Studio (presented as a component within AppBuilder, the tool that configures a project’s .isc file). For further information on radio configurator usage, please refer to AN692 (for EZRadioPro) or AN971 (for EFR32).
If the developer wants the packet to be correctly received, configurations in both the transmitter and receiver sides should match, including: RF parameters (frequency, data rate, channel, etc.), structure of the packet (preamble, sync words, header, crc, etc.), symbol coding, etc. Regarding the structure of the packet, there is an obvious difference in that one EZRadioPro packet can contain a maximum of 5 packet fields (and every field can be configured individually), but for EFR32 one packet always contains just one payload field.
Here we describe the differences of initialization between EZRadioPro and EFR32 using the example projects “Bidirectional Packet” and “Simple_rail_with_hal”, which can be separately generated from WDS and Simplicity Studio (respectively).
EZRadioPro:
In the EZRadioPro chip, commands should be sent to the chip via SPI. The developer can refer to the sample projects provided in WDS, like Bidirectional Packet project. This example will be used in this section to show the differences between EZRadioPro family and EFR32 family.
The following is the pseudo code snippet to show the initialization steps. The developer invokes these functions in the host MCU project to send commands to or get responses from the radio chip via SPI.
Step 1: Invoke vRadio_Init() to reset the chip by toggling SDN from high to low. Refer to the following article: Si4x6x-C2A, Si4x55-C2A startup sequence
Step 2: Send the chip register/API setting values to the chip in si446x_configuration_init() function via SPI. The radio/modem/packet/PA setting is generated by WDS and stored in radio_config.h header file.
Step 3: Invoke the function si446x_get_int_status(0u, 0u, 0u) at the end of the initialization function to clear pending interrupts with GET_INT_STATUS command. Please note that this function should be called to clear the pending interrupt after interrupt happens or before entering sleep mode.
Chapter 8 of AN633 describes more details about the initialization for EZRadioPro.
EFR32:
he developer can directly invoke APIs to implement the initialization for EFR32. The following is the pseudo code snippet to show the initialization steps for EFR32:
Step 1: Invoke halInit() to initialize system clock and the peripherals that the project uses.
Step 2: Invoke RAIL_Init() to initialize the RAIL. The parameter railCfg of this function includes a callback, where the events of RAIL should be handled in the application layer of the project, such as RAIL_EVENT_TX_PACKET_SENT, RAIL_EVENT_RX_PACKET_RECEIVED, etc. This function will return a handle which will be used when invoking other RAIL APIs.
Step3: The developer should also initialize RAIL calibration with RAIL_ConfigCal(). Calibration initialization provides the calibration settings that correspond to the current radio configuration.
Step 4: Before performing any radio operations, invoke RAIL_ConfigChannels() to set a valid channel for radio. It will also configure the relevant radio registers with the input parameters. The parameters related to the channels come from rail_config.h, which is generated by the radio configurator in Simplicity Studio. Simplicity Studio provides an easy way (GUI) for developers to configure the parameters and generate the PHY setting of the channel.
Step 5: The developer should invoke the RAIL_ConfigTxPower() and RAIL_SetTxPower() to set the PA mode and Tx power. Note that the second parameter of the RAIL_SetTxPower() is PA power level. The actual Tx power corresponding to the power level can be found with the method described in AN1127. Also refer to the PA conversions plugin in radio configurator (or PA of the hardware configurator defined in .hwconf) of Simplicity Studio.
The following article provides more details about initialization: RAIL Tutorial 1: Introduction and Initialization
4. Difference in Transmit
Here we describe the differences of transmit between EZRadioPro and EFR32, using the example projects “Bidirectional Packet” and “Simple_trx_with_fifo”.
EZRadioPro:
The chip contains one Tx FIFO (64 Bytes) and one Rx FIFO (64 Bytes). This size cannot be changed (note that for EFR32, the application defines Tx FIFO size), but the chip can be instead configured to have a unified 129 Bytes FIFO shared by both Tx and Rx operation (Refer to API document about property GLOBAL_CONFIG :
FIFO_MODE).
The following pseudo code snippet shows how to start transmitting and how to handle the tx events. The developer invokes these functions in the host MCU project to send commands to or get responses from the radio chip via SPI.
Step 1: Send data to Tx FIFO. Before starting transmitting, the developer should send the packet payload to the Tx FIFO of the radio chip via SPI. If the payload length is greater than the size of the Tx FIFO, the developer can use the TX_FIFO_ALMOST_EMPTY interrupt to send the payload to the Tx FIFO in several segments. As with the EFR32, the developer should set a threshold value for the Tx FIFO threshold property PKT_TX_THRESHOLD. An interrupt is generated when the amount of empty space in the Tx FIFO is equal to or greater than this threshold. When event TX_FIFO_ALMOST_EMPTY_PEND (Refer to API document about command GET_INT_STATUS: PH_PEND: TX_FIFO_ALMOST_EMPTY_PEND) happens, the application should send more payload bytes to Tx FIFO.
It is suggested that before transmitting starts, the application should reset the chip FIFO with si446x_fifo_info() and clear the previous pending interrupt with si446x_get_int_status (0u, 0u, 0u).
Step 2: Use si446x_start_tx() to startup transmitting. Note that if the parameter TX_LEN of this command is non-zero, the packet will be transmitted with TX_LEN number of data bytes with the definition in the packet field 1 (PKT_FIELD_1_X) configuration options (e.g., CRC, data whitening, Manchester coding, etc.). If TX_LEN is zero, the chip will transmit the data according to the configuration of the packet fields properties PKT_FIELD_X_X (Refer to API document about command START_TX).
Step 3: Check and handle the events. The host MCU application should check the status if an event happens.
The interrupt event (TX_FIFO_ALMOST_EMPTY or PACKET_SENT) is defined in the radio_config.h and enabled in WDS based on the customer selection.
If the relevant interrupts are enabled and one or more enabled interrupts happen, nIRQ pin will be put low. The host MCU application should use si446x_get_int_status() to get status of the chip (Refer to API document about command GET_INT_STATUS) and check which interrupt happened and handle it accordingly.
Settings about state transition. The radio chip can automatically change state after completion of a packet transmission. To achieve this purpose, a desired state defined in TXCOMPLETE_STATE should be passed with the command START_TX (Refer to API document about command START_TX).
EFR32:
The following pseudo code snippet shows the transmit steps for EFR32 (config the events, set/write Tx FIFO, start tx, and events handling):
Step 1: To transmit a packet, application FW should first set a buffer as the RAIL Tx FIFO. Note that it can only handle Tx buffer sizes of a power of 2 between 64 and 4096. The pointer of the buffer is passed to RAIL as a parameter of RAIL_SetTxFifo() . Before calling this function, initialize the buffer with the transmitted payload data so that the transmitted payload data can be passed to Tx FIFO with this function. Another method to pass the transmitted payload data to Tx FIFO is to invoke RAIL_WriteTxFifo() after setting the Tx FIFO (with RAIL_SetTxFifo()).
Step 2: RAIL_StartTx() should be invoked to send out the packet data in Tx FIFO. When invoking this function, the developer should specify the channel on which the radio will transmit the packet. Some options can be set for the transmission of the packet, such as waiting for ACK, needing CCA etc.
Step 3: Upon finishing transmitting a packet, event RAIL_EVENT_TX_PACKET_SENT will happen. If the length of the packet is greater than the size of Tx FIFO, another event RAIL_EVENT_TX_FIFO_ALMOST_EMPTY is useful (see the description of the event in RAIL API document). While handling this event, we can write more packet data to Tx FIFO – even though the transmit process is still on going. The developer should set a threshold value for the event RAIL_EVENT_TX_FIFO_ALMOST_EMPTY using RAIL_SetTxFifoThreshold().
The developer should configure these events during initialization with RAIL_ConfigEvents(). Note that the process of event handling is in interrupt context, so they should be handled as fast as possible.
For more details see article: RAIL Tutorial 3: Event Handling
Setting up state transitions after transmitting. After transmitting (either successfully or not), what is the next state of the radio? RAIL provides a way to configure automatic state transitions. To use this function, the developer should use RAIL_SetTxTransitions() to set the automatic states (RX or IDLE) before transmitting (see the RAIL API document). Of course, the developer can also manually change the radio states using RAIL_Idle() and RAIL_StartRx().
The following article tells more about transmit on EFR32: RAIL Tutorial 2: Transmitting a Packet
5. Difference in Rx Start
Here we describe the differences of rx start between EZRadioPro and EFR32 using the example projects “Bidirectional Packet” and “Simple_trx_with_fifo”.
EZRadioPro:
The following pseudo code snippet shows how to start Rx and how to handle the Rx events. The developer invokes these functions in the host MCU project to send commands to or get responses from the radio chip via SPI.
As mentioned in the previous chapter, the chip has two FIFOs: Tx FIFO (64 Bytes) and Rx FIFO (64 Bytes). They can be combined into one FIFO (129 Bytes) as a shared FIFO for both Tx and Rx (Refer to API document about property GLOBAL_CONFIG:FIFO_MODE ). Note that developers should make sure that the data in the shared FIFO will not be lost when the state changes between Tx and Rx.
Step 1: Use si446x_start_rx() to start Rx. Three next states may be passed with this command to make the radio chip automatically enter to a desired state upon timeout of preamble detection, reception of a valid packet or reception of an invalid packet.
The packet can include maximum of 5 fields. Note that if the parameter length argument of this command is non-zero, the radio chip will receive and decode the packet based on the definition in the packet field 1 (PKT_FIELD_1_X) configuration options (e.g., CRC, data whitening, Manchester coding, etc.). If length is zero, the chip will receive the packet according to the configuration of the packet fields properties PKT_FIELD_X_X (Refer to API document about command START_RX).
Step 2: Handle the Rx events. During reception, the host MCU should check the status of the radio chip by si446x_get_int_status (0u, 0u, 0u). If the relevant interrupts are previously enabled and the interrupt happens, the nIRQ pin will put low to inform the host MCU that events have happened. If a whole packet is received, interrupt PACKET_RX_PEND (Refer to API document about command GET_INT_STATUS : PH_PEND: PACKET_RX_PEND ) will happen. The host MCU can use command READ_RX_FIFO to read the received data from Rx FIFO. If the size of the whole packet is greater than that of Rx FIFO, the event RX_FIFO_ALMOST_FULL_PEND is useful. When this event happens, the host MCU should immediately read the received data bytes from the Rx FIFO to avoid overflow. The threshold should be set in property PKT_RX_THRESHLOD .
It is suggested that before Rx start, the developer should reset the chip FIFO with si446x_fifo_info() and clear the previous pending interrupt with si446x_get_int_status (0u, 0u, 0u).
EFR32:
The following pseudo code snippet shows the starting Rx steps for EFR32 (config the events, start rx and events handling):
Step 1: The developer invokes RAIL_StartRx() to start Rx. The channel number should be passed with this function, so the radio component is able to correctly receive and decode the packet.
Step 2: Handle events. If an event happens, the event can be handled in the callback. Of course, the developer needs to have previously configured the Rx events.
By default, the size of the Rx FIFO is 512 bytes (max value), so if the size of a packet is greater than that, developer should handle the event RAIL_EVENT_RX_FIFO_ALMOST_FULL and read the received data bytes from Rx FIFO to avoid overflow. The developer should set a threshold value using RAIL_SetRxFifoThreshold().
When the chip receives a whole packet, event RAIL_EVENT_RX_PACKET_RECEIVED will be generated. The developer should handle these events as soon as possible. For more on this topic, see the article: RAIL Tutorial 3: Event Handling
Setting up the state transitions. Similar to Tx, after receiving (either successfully or not), the radio can transition to a predefined state (RX/IDLE) automatically. The next state can be set using function RAIL_SetRxTransitions(). Of course, the developer can also manually change the radio state using RAIL_Idle() and RAIL_StartRx().
6. Downloading the Packet
Here we describe the differences about downloading the packet between EZRadioPro and EFR32 using the example projects “Bidirectional Packet” and “Simple_trx_with_fifo”.
EZRadioPro:
The following pseudo code snippet shows how to download the packet from the Rx FIFO. The developer invokes these functions in the host MCU project to send commands to or get responses from radio chip via SPI.
When RX_FIFO_ALMOST_FULL_PEND or PACKET_RX_PEND event happened, the application can use command si446x_read_rx_fifo() to get the received data from radio chip. Before that, use si446x_fifo_info() to get the length of the received packet in Rx FIFO.
For event RX_FIFO_ALMOST_FULL_PEND. the developer should set threshold in property PKT_RX_THRESHOLD.
EFR32:
The following pseudo code snippet shows how to download the packet from the Rx FIFO.
When the amount of the received data bytes in Rx FIFO is equal to or greater than the threshold, event RAIL_EVENT_RX_FIFO_ALMOST_FULL will happen. At this moment, the application can use RAIL_ReadRxFifo() to read the received data. Before reading, the application should get the packet length of the received packet in Rx FIFO with RAIL_GetRxFifoBytesAvailable().
When a whole packet is received, event RAIL_EVENT_RX_PACKET_RECEIVED will happen, the application can read out the data from RX FIFO by RAIL_ReadRxFifo(). The application can also obtain more detailed information about the packet with RAIL_GetRxPacketDetails().
The following article gives more details about downloading the packet: RAIL Tutorial 4: Combining Transmit and Receive.