Minimal RAIL application

by <a href="http://community.silabs.com/t5/Welcome-and-Announcements/Community-Ranking-System-and-Recognition-Program/m-p/140490#U140490"><font color="#000000"><font size="2">Hero Employee</font></font> </a> andrasbiro on ‎08-24-2016 07:04 AM

Most of our demos use a lot of peripherals, and in a lot of projects, you barely need any peripherals. So the question arises: How an absolute minimum RAIL application would look like?

Let's say, just initialize the radio, send a really small message, than do nothing.

 

Generating the project

 

Use the empty_rail example, since it's basically just the configurator, nothing else. We will use our own c code. Set up the RadioConfig to whatever you want, and only enable the RAIL Library plugin:

2016-08-24_14h00_40.png

We will use the RAILCb_RfReady callback, so enable that, but only that:

2016-08-24_13h15_52.png

On the other tab, add some include paths (directories) needed to use the kit. The last directory should represent the board you use.

2016-08-24_13h17_17.png

(The first one is in there by default, but it's not shown until you manually add some more)

 

Adding drivers

 

RAIL (or the peripherals needed by RAIL) needs a few emlib c files to work. Namely: em_cmu.c, em_emu.c em_int.c and em_system.c.

So let's add them to the project. The simplest way to do it is to create a new folder in the project, than drag end drop the c files there from <RAILFolder>\submodules\emlib\src\. Studio will pop up a window there, it's a good idea to create a link, relative to STUDIO_SDK_LOC: since that points to the RAIL folder, the project should work, even if you move it to an other computer.

 2016-08-24_10h59_18.png

In the end, the project should look something like this:

 

 2016-08-24_13h26_31.png

 

Creating the main.c file

 

Add a main.c file to the project, and for now, just create the simplest file that should compile:

 

int main(void){
while(1)
; return 0; } void RAILCb_RfReady(void) { }

 

Initializing RAIL

 

In our examples, RAIL initialization starts with halInit(). We won't use that call, since it starts up PTI, some timers, etc - a lot of things we want to avoid.

Note: Most WirelessGecko boards have an onboard serial flash chip, which, at power on reset consumes quite a lot of power. We won't start that, so be aware that the current consumption will be significantly higher. See the boardDisableSpiFlash() function in hal_efr.c to see how to turn it off.

 

RAIL actually only needs the following:

  • DCDC
  • HFXO
  • PA

Note: Unless you want to use RFSense in EM2. That would need some LF oscillator

So let's modify our very simple main.c which will start up those, than starts and configures RAIL:

 

#include "rail.h"
#include "rail_types.h"
#include "rail_config.h"

#include "em_chip.h"
#include "em_emu.h"
#include "em_cmu.h"
#include "bsp.h"
#include "pa.h"

#define MAX_PACKET_SIZE  1

RAIL_Init_t railInitParams = {
		MAX_PACKET_SIZE,
		RADIO_CONFIG_XTAL_FREQUENCY,
		RAIL_CAL_ALL,
};

volatile bool initialized = false;

int main(void){
	CHIP_Init();
	EMU_DCDCInit_TypeDef dcdcInit = EMU_DCDCINIT_WSTK_DEFAULT;
	CMU_HFXOInit_TypeDef hfxoInit = CMU_HFXOINIT_WSTK_DEFAULT;
	RADIO_PAInit_t paInit;

	EMU_DCDCInit(&dcdcInit);
	CMU_HFXOInit(&hfxoInit);

	/* Switch HFCLK to HFXO and disable HFRCO */
	CMU_ClockSelectSet(cmuClock_HF, cmuSelect_HFXO);
	CMU_OscillatorEnable(cmuOsc_HFRCO, false, false);

	// Initialize the PA now that the HFXO is up and the timing is correct
	#if (RADIO_CONFIG_BASE_FREQUENCY < 1000000000UL)
	paInit = (RADIO_PAInit_t) RADIO_PA_SUBGIG_INIT;
	#else
	paInit = (RADIO_PAInit_t) RADIO_PA_2P4_INIT;
	#endif

	RADIO_PA_Init(&paInit);
	RAIL_RfInit(&railInitParams);
	RAIL_RfIdle();

	RAIL_PacketLengthConfigFrameType(frameTypeConfigList[0]);
	if (RAIL_RadioConfig((void*)configList[0])) { while(1); }

	RAIL_ChannelConfig(channelConfigs[0]);

	while( !initialized )
		;

while(1)
; return 0; } void RAILCb_RfReady(void) { initialized = true; }

 

Sending a packet

 

To send a packet, we need to define its payload

 

uint8_t txData[1];

RAIL_TxData_t transmitPayload = {
		(uint8_t*)(&txData),
		sizeof(txData),
};

Then, after initialization, we set up the payload, load it to RAIL, then send it:

 

 

txData[0] = 0x12;
RAIL_RfIdle();
RAIL_TxDataLoad(&transmitPayload);
RAIL_TxStart(0, NULL, NULL);

And that's it. You should have something similar to the attached code. This is a very minimal RAIL example which work.

 

 

Reducing code size (GCC only)

 

 By defualt, GCC compiles in float support for printf, which uses a lot of code space.  You can turn that off in the project properties:

2016-08-24_13h57_07.png

Comments
by <a href="http://community.silabs.com/t5/Welcome-and-Announcements/Community-Ranking-System-and-Recognition-Program/m-p/140490#U140490"><font color="#000000"><font size="2">Hero Employee</font></font> </a> andrasbiro
on ‎02-23-2017 07:22 AM

Just a few notes with the release of Flex SDK:

  • Unfortunately, the MCU system/startup and  header files were moved into the HAL plugin. With this change, it's much more complicated to create a project without HAL, I recommend to use the hal plugin, and remove the unwanted c files.
  • With the new Gecko SDK 5, em_int.c was depricated in RAIL with em_core.c, which enables much more control over the interrupts.