Introduction, RAIL components, and the Empty Example#

What is RAIL?#

RAIL is short for Radio Abstraction Interface Layer, and is the most direct interface available for EFR32 radios. You can think of it as a radio driver. While this sounds like a restriction, this actually makes software development for proprietary wireless much simpler:

  • EFR32 has a very flexible radio, which also makes it quite complex. RAIL (and the radio configurator) provides an easy-to-use interface of EFR32's features.

  • The various generations of EFR32s are slightly different, but the RAIL API is the same (except maybe the chip specific updates), which makes hardware updates almost seamless.

  • We plan to add RAIL support to all of our future wireless MCUs.

RAIL application development is currently possible in the SiSDK in Simplicity Studio. To progress further with this tutorial, please remember to open the RAIL API documentation.

When to Use RAIL?#

If you have an existing protocol, and you must be compatible with it, you'd probably have to use RAIL (as all of our stacks use a standardized frame format).

If you want to use sub-GHz communication, you have a few options, including RAIL. For simple point to point communication, RAIL might be the simplest solution. However, as soon as you need security or addressing, it might be better choose a protocol stack, such as Connect.

RAIL also has the benefit that it adds the least amount of delays to all radio events. In fact, some event notification will happen in interrupt context.

What is Covered by RAIL?#

RAIL only supports what the radio hardware supports. For example, auto ACK and address filter is available, as the hardware provides support for it. On the other hand, while security is important for wireless communication, it's not really a radio task, hence RAIL does not support it. The crypto engine is an independent peripheral that can be used to encrypt payloads before giving them to RAIL and the radio hardware.

Supported Energy Modes#

EM1p or higher is required for the radio to be operational (i.e., Transmitting, receiving, or waiting for packets, RAIL timer running from HF clock). On devices without EM1p support, EM1 is required for the radio. See AN1244: EFR32 Migration Guide for Proprietary Applications for more details on EM1p.

EM2 or higher is required for RAIL scheduling or timers. In this mode, timers are running from LF clock, which needs configuration. This is configured by default in our examples, and will be discussed in a later article in detail.

EM3 or higher is required for RAIL to work without re-initialization.

Writing Code from Scratch#

We do not recommend writing code from scratch because it is much simpler to have something existing that sets up the include paths and linker settings correctly. The best way to start is the example RAIL - SoC Empty.

RAIL Components#

The empty application includes the following RAIL related components (under 'Platform/Radio'):

  • RAIL Library, Single Protocol, which is the library itself

  • RAIL Utility, PA, which configures and initializes the power amplifier

  • RAIL Utility, Initialization, which initializes RAIL and loads an initial configuration

  • RAIL Utility, Callbacks, which currently only implements the assertion callback

  • RAIL Utility, PTI, which enables Packet Trace Interface, the hardware that feeds data to the Network Analyzer

  • RAIL Utility, RSSI, which compensates the RSSI offset error (and can be fine tuned)

And a few other RAIL components, that are useful if you plan to use a RAIL-supported protocol, like IEEE 802.15.4.

There are a few components that you might want to install:

  • RAIL Utility, DMA, which allocates a DMA channel to speed up RAIL initalization

  • Radio Utility, Front End Module, which can be used to drive a FEM (or external PA/LNA), if your HW uses one

  • RAIL Utility, RF Path, which can be used to select the antenna path on the parts that have multiple (like EFR32xG23)

If you work on a starter kit, you don't need to change the configuration of most of these components, except the Initialization component. However, the initialization component also includes a good starting point, that we don't need to modify for simple applications.

The Radio Configurator#

The Radio Configurator is accessible by configuring the component Advanced Configurators/Radio Configurator. The usage of the radio configurator is out of scope for this tutorial series. For more details, see AN1253: EFR32 Radio Configurator Guide.

The Project Structure#

Projects always include the following parts:

  • autogen folder: Only the autogen folder includes generated code. It includes the PHY configuration (rail_config.c), init code, the linker script, and other generated code used by components, like the command descriptors for the CLI interface

  • config folder: Component configuration headers are placed into this folder. These can be edited with the Component Editor that can be opened on the Project Configurator via the Configure button, but directly editing the header file is also possible. The input of the radio configuration is also here, in rail/radio_settings.radioconf

  • simplicity_sdk folder (with version number): Source and binary files added by components

  • files in the root folder: Only the application specific files should be in the root folder, including source files, the project configurator (.slcp file) the Pin tool (.pintool file) and a readme file.

Project StructureProject Structure

Note that all files related to the project should be visible in the project explorer, including header and library files.

Where to Add User Code#

All projects include main.c, which is not recommended to modify. Instead, add the initialization code to app_init.c, and implement the main loop in app_process.c. This way, the System components can initialize components, and call the "process" function of the components that requires this. Additionally, enabling an RTOS will convert app_process's main loop into an RTOS task.

Conclusion#

This project is ready to send out frames. We're going to do that in the next part.