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 external storage. Some platforms, like the CC2538, have enough internal on-chip flash memory to hold an entire firmware update, whereas smaller platforms like the CC1310/CC1350/CC2650 require an external flash chip.

The Thingsquare firmware SDK for the CC1310/CC1350/CC2650 supports a set of WinBond and Macronix flash chips, connected via an SPI connection to the microcontroller. See hardware documentation for details.

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.

This is done via two special lines of code: one for disabling the flash chip and one for setting the flash chip pins.

Disabling the flash chip (CC1310/CC1350/CC2650)

Disabling the flash completely is typically done during development, as a first step to getting something running on a new custom hardware platform. By disabling the flash, over-the-air updates are effectively disabled too, so it is never to be used in a production environment.

Disabling the flash chip is done by adding the code BOOTLOADERPARAMS_OVERRIDE_XMEM_DISABLE(); to the application code. Like this:

#include "thsq.h"
/*---------------------------------------------------------------------------*/
BOOTLOADERPARAMS_OVERRIDE_XMEM_DISABLE();
/*---------------------------------------------------------------------------*/
void
app(void)
{
}
/*---------------------------------------------------------------------------*/

Changing the flash configuration (CC1310/CC1350/CC2650)

To change the SPI pins used to connect the flash chip on the CC1310/CC1350/CC2650, 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"
/*---------------------------------------------------------------------------*/
#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 (CC1310/CC1350/CC2650)

On the CC1310/CC1350/CC2650, 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"
/*---------------------------------------------------------------------------*/
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)
{
}
/*---------------------------------------------------------------------------*/

LED initialization (CC2538)

The pin configuration on the CC2538 is slightly different because pins on the CC2538 must be configured with two arguments, one pin and one port. Like this:

#include "thsq.h"
#include "ti-lib.h"
/*---------------------------------------------------------------------------*/
void
init_leds(void)
{
  /* Specify red LED on pin D5, green on D4, the rest on D3 */
  leds_arch_set_pins(GPIO_D_BASE, (1 << 5),
                     GPIO_D_BASE, (1 << 4),
                     GPIO_D_BASE, (1 << 3),
                     GPIO_D_BASE, (1 << 3));
}
/*---------------------------------------------------------------------------*/
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 (CC1310/CC1350/CC2650)

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 (CC2538)

The UART configuration on the CC2538 require a bit more than on the CC1310/CC1350/CC2650 because pins are specified with both a port and a pin number.

#include "thsq.h"
/*---------------------------------------------------------------------------*/
void
init_uart(void)
{
  /* Set up TX on PA0, RX on PA1 */
#define UART_RX_BASE                GPIO_A_NUM
#define UART_RX_PIN                 GPIO_PIN_0
#define UART_TX_BASE                GPIO_A_NUM
#define UART_TX_PIN                 GPIO_PIN_1
#define UART_INSTANCE               0

  uart_set_pins(UART_INSTANCE, UART_RX_BASE, UART_RX_PIN, UART_TX_BASE, UART_TX_PIN);
  uart_init(UART_INSTANCE);
}
/*---------------------------------------------------------------------------*/
void
app(void)
{
}
/*---------------------------------------------------------------------------*/

Radio configuration

In some cases, a customer may need to configure or limit the radio for a specific hardware. This is done in the init_radio() call. For example, one may need to enable an external PA/LNA or change pins used for the RF switch (CC1350).

Radio configuration (CC1310/CC1350/CC2650)

To configure the radio on the CC1310/CC1350/CC2650, we can for example,

#include "thsq.h"
#include "ti-lib.h"
/*---------------------------------------------------------------------------*/
void
init_radio(void)
{
  /* prototypes */
  void rf_switch_set_pins(unsigned int power, unsigned int select);
  void rf_switch_init(void);

  /* set pins and init */
  rf_switch_set_pins(IOID_30, IOID_1);
  rf_switch_init();
}
/*---------------------------------------------------------------------------*/
void
app(void)
{
}
/*---------------------------------------------------------------------------*/

Radio configuration (CC2538)

Radio configuration is not yet available on the cc2538. Contact us for details.

Ethernet configuration

Ethernet-based gateways 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 (CC1310/CC1350/CC2650)

To configure the ethernet SPI on the CC1310/CC1350/CC2650,

#include "thsq.h"
#include "ti-lib.h"
/*---------------------------------------------------------------------------*/
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)
{
}
/*---------------------------------------------------------------------------*/

Ethernet configuration (CC2538)

To configure the ethernet SPI on the CC2538,

#include "thsq.h"

/*---------------------------------------------------------------------------*/
void
init_leds(void)
{
#define UNUSED                      0
#define ENC28J60_SPI_MISO_BASE      GPIO_A_BASE
#define ENC28J60_SPI_MISO_BIT       GPIO_PIN_0
#define ENC28J60_SPI_MOSI_BASE      GPIO_A_BASE
#define ENC28J60_SPI_MOSI_BIT       GPIO_PIN_1
#define ENC28J60_SPI_CLK_BASE       GPIO_D_BASE
#define ENC28J60_SPI_CLK_BIT        GPIO_PIN_5
#define ENC28J60_SPI_CS_BASE        GPIO_D_BASE
#define ENC28J60_SPI_CS_BIT         GPIO_PIN_0
#define ENC28J60_RESET_BASE         UNUSED /* optional */
#define ENC28J60_RESET_BIT          UNUSED /* optional */

  enc28j60_arch_set_pins(ENC28J60_SPI_CS_BASE, ENC28J60_SPI_CS_BIT,
                         ENC28J60_SPI_MISO_BASE, ENC28J60_SPI_MISO_BIT,
                         ENC28J60_SPI_MOSI_BASE, ENC28J60_SPI_MOSI_BIT,
                         ENC28J60_SPI_CLK_BASE, ENC28J60_SPI_CLK_BIT,
                         ENC28J60_RESET_BASE, ENC28J60_RESET_BIT);
}
/*---------------------------------------------------------------------------*/
void
app(void)
{
}
/*---------------------------------------------------------------------------*/