Controlling the firmware boot up process

The Thingsquare firmware SDK allows developing custom user applications running directly on the hardware and communicating both with the REST API and the hardware itself.

Custom firmware applications often run on custom hardware. To control the custom hardware, the firmware SDK provides a set of features to configure and control how the hardware is set up.

Custom flash

To provide over-the-air firmware updates, the Thingsquare firmware needs to be able to store downloaded firmware images in an dedicated storage. The CC13x0/CC26x0/CC13x2 platforms require an external flash chip.

On platforms that require an external flash chip, the configuration for the connection between the microcontroller and the flash chip must be specified by the user application.

Changing the flash configuration (CC13x0/CC26x0/CC13x2)

To change the SPI pins used to connect the flash chip on the CC13x0/CC26x0/CC13x2, a call to BOOTLOADERPARAMS_OVERRIDE_XMEM_CONF(); must be added to the application code. The function takes four parameters: the MISO, MOSI, CLK, and CS pins. It can be used like this:

#include "thsq.h"
#include "ti-lib.h" // CC13x0/CC26x0
#include "ioc.h"    // CC13x2
/*---------------------------------------------------------------------------*/
#define XMEM_MISO IOID_8
#define XMEM_MOSI IOID_9
#define XMEM_CLK  IOID_10
#define XMEM_CS   IOID_20

BOOTLOADERPARAMS_OVERRIDE_XMEM_CONF(XMEM_MISO, XMEM_MOSI, XMEM_CLK, XMEM_CS);
/*---------------------------------------------------------------------------*/
void
app(void)
{
}
/*---------------------------------------------------------------------------*/

This will cause the system to connect to the flash chip with MISO pin at 1, MOSI pin 2, CLK pin 3, and CS pin 4.

Custom LEDs

The Thingsquare system uses two LEDs to indicate the progress of the system, one red and one green. The system may in the future potentially use a blue LED, but not in the current version. The pin configuration of the LEDs can be specified by the application code. This is done differently on different platforms.

The LED configuration is done in a separate function called init_leds(). If this function is implemented in the application code, the system will itself not attempt to initialize the LED configuration. Instead, the application code is expected to initialize the LEDs.

LED initialization (CC13x0/CC26x0/CC13x2)

On the CC13x0/CC26x0/CC13x2, the LEDs are configured with leds_arch_set_pins(), where the arguments are the pin numbers of the red, green, and blue LEDs respectively. Like this:

#include "thsq.h"
#include "ti-lib.h" // CC13x0/CC26x0
#include "ioc.h"    // CC13x2
/*---------------------------------------------------------------------------*/
void
init_leds(void)
{
  /* Specify red LED on pin 6, green on pin 7, and no blue LED available on hw */
  leds_arch_set_pins(IOID_6, IOID_7, IOID_UNUSED);
}
/*---------------------------------------------------------------------------*/
void
app(void)
{
}
/*---------------------------------------------------------------------------*/

Custom UART settings

The UART settings are configured at boot up by the system, but can be overridden by the application code through a callback function called init_uart(). This function is called to set up the UART. If the application code does not set up any UART, the code will run without a UART.

This code will cause the system to run without a UART:

#include "thsq.h"
/*---------------------------------------------------------------------------*/
void
init_uart(void)
{
   /* Do nothing */
}
/*---------------------------------------------------------------------------*/
void
app(void)
{
}
/*---------------------------------------------------------------------------*/

Custom UART settings (CC13x0/CC26x0)

To specify custom UART settings on the CC1310/CC1350/CC2650, we use the cc26xx_uart_init() function with the TX and RX pins. Like this:

#include "thsq.h"
#include "ti-lib.h"
/*---------------------------------------------------------------------------*/
void
init_uart(void)
{
  /* Set up TX pin 6, RX pin 7 */
  cc26xx_uart_init(IOID_6, IOID_7, IOID_UNUSED, IOID_UNUSED);
}
/*---------------------------------------------------------------------------*/
void
app(void)
{
}
/*---------------------------------------------------------------------------*/

Custom UART settings (CC13x2)

To specify custom UART settings on the CC13x2, we use the uart0_init() function with the TX and RX pins. Like this:

#include "thsq.h"
#include "ioc.h"
#include "uart0-arch.h"
/*---------------------------------------------------------------------------*/
void
init_uart(void)
{
  /* Set up TX pin 6, RX pin 7 */
  uart0_init(IOID_6, IOID_7, IOID_UNUSED, IOID_UNUSED);
}
/*---------------------------------------------------------------------------*/
void
app(void)
{
}
/*---------------------------------------------------------------------------*/

Radio configuration

The wireless SOCs are generally very flexible and can accomodate a wide range of radio hardware setups. The software needs to be configured to take this into account. You do this by overriding the init_radio() function. You can for example configure use of LNA/PA, frontend mode, and limit the transmission power. The latter may be important for regulatory reasons, for example if a high-gain antenna is used.

If you consider departing from the Launchpad reference designs, talk to us at design-time and we can help you find the right setup for you.

Radio configuration (CC13x0/CC26x0/CC13x2)

To configure the radio on the CC13x0/CC26x0/CC13x2 chips, we can for example,

#include "thsq.h"
#include "ti-lib.h" // CC13x0/CC26x0
#include "ioc.h"    // CC13x2
/*---------------------------------------------------------------------------*/
void
init_radio(void)
{
  void thsq_rf_set_frontend_mode(int interface, int mode);
  thsq_rf_set_frontend_mode(THSQ_RF_INTERFACE_PRIMARY, THSQ_RF_FEM_SINGLE_RFP);
  thsq_rf_set_frontend_mode(THSQ_RF_INTERFACE_BLE, THSQ_RF_FEM_SINGLE_RFN);

  /* by not initializing the rf switch, we disable use of it */
  // void thsq_rf_set_rf_switch(int power, int select);
}
/*---------------------------------------------------------------------------*/
void
app(void)
{
}
/*---------------------------------------------------------------------------*/

Customizing oscillator settings

In the rare case of required changes to the oscillator settings, the function init_oscillator() can be overriden.

Custom oscillator settings (CC13x0/CC26x0)

This set of chips default to the Launchpad configuration with an external 32.768 oscillator connected to the two LF_XOSC pins. They can also run on a single-pin external clock. To accomplish this, we must override the init_oscillator() function so not the default is initialized.

#include "thsq.h"
/*---------------------------------------------------------------------------*/
void
init_oscillator(void)
{
  /* nothing to do */
}
/*---------------------------------------------------------------------------*/
void
app(void)
{
}
/*---------------------------------------------------------------------------*/

Ethernet configuration

Ethernet-based access points that do not follow the default pinout for the SPI connection can change the pinout this. There is no dedicated callback for this but should be done in init_leds().

Ethernet configuration (CC13x0/CC26x0/CC13x2)

To configure the ethernet SPI on the CC13x0/CC26x0/CC13x2,

#include "thsq.h"
#include "ti-lib.h" // CC13x0/CC26x0
#include "ioc.h"    // CC13x2
/*---------------------------------------------------------------------------*/
void
init_leds(void)
{
#define ENC_SPI_MISO IOID_12
#define ENC_SPI_MOSI IOID_15
#define ENC_SPI_CLK  IOID_21
#define ENC_SPI_CS   IOID_1
  void enc28j60_arch_set_pins(int cs, int miso, int mosi, int clk);
  enc28j60_arch_set_pins(ENC_SPI_CS, ENC_SPI_MISO, ENC_SPI_MOSI, ENC_SPI_CLK);
}
/*---------------------------------------------------------------------------*/
void
app(void)
{
}
/*---------------------------------------------------------------------------*/