lørdag den 3. august 2019

BLE from scratch part 2: Integrating the softdevice

Continued from part 1

The SoftDevice

A SoftDevice in Nordic lingo is a binary that is installed in the lower parts of flash and RAM in the SoC. The SoftDevice contains the bluetooth stack and hooks for building your application on top. There are several flavors, but the one we will be using here is the S112 which is the simplest of them, and which is meant to build peripherals - the kind of BLE application we try to build here.

The various SoftDevices can be found in the SDK in components/softdevice. To ease the setup in the project, we define a Project Macro called SoftDevice:

Open the project options, make sure to choose the common configuration. Then choose 
build->project macros and set up a macro like this:


The SoftDeviceDir should point to the location of where you installed the SDK of course, but this gives an easy way of retargeting when new SDKs come out.

We then need to set up the include path to include the headers from the softdevice. This is done in Preprocessor->User Include Directories. Here we use the macro we just defined:



In order for the SoftDevice to work correctly, we need to allow it to configure the interrupt vectors. This is done by setting the NO_VTOR_CONFIG macro in Preprocessor->Preprocessor Definitions:

Then we need to configure the debugger to download the softdevice. This is done by adding an additional load file in the project options under Debug->Loader:



Last we need to tell the debugger not to start at the entry point for our application. This is done to allow the softdevice to be configured prior to starting the application. To do this choose 
Debug->Debugger and then set "Start from entry point symbol" to no:


Error handling

Interacting with the softdevice can generate errors, and in order to get insight to how the system is running, it is nice to have printed debug output when any error occurs. Hence I have implemented a generic framework for error handling that can be seen here:

There are three important elements:

A hardfault handler void fault_handler(uint32_t id, uint32_t pc, uint32_t info); that is used by the softdevice to handle hardfaults. This is always enabled in any configuration

An error checking macro CHK_ERR(x) that will check if x is NRF_SUCCESS. If it is not, a relevant error message will be printed in the debug terminal in SES during debug, whereafter the device will reset. If the project is built in release mode the device will just reset.

Lastly an information macro INFO(x) will print the string x to the debug terminal during debug, or just no-op during release. 

The full implementation can be seen here:


Starting the softdevice

The code for starting the softdevice is surprisingly simple. The management functions for the softdevice is declared in nrf_sdm.h and the code looks like this:

These lines: actually starts the softdevice. If the hardware has a 32.768kHz crystal, the softdevice should use this for timing as it provides more precise timing and therefore allows for less "slack" in the radio and thereby lower power consumption. If such a crystal is not available, these lines should be commented in instead of These lines enables the less precise internal RC and sets up the internal calibration procedure for that in the SoftDevice.

The loop in the end is an event loop that will keep the processor in sleep unless events happen in the BLE stack. We will populate the functions around this in a future post.

The next part can be found here

Ingen kommentarer:

Send en kommentar