Chapter 6 Platform API Reference

6.1 platform_32k_rc_auto_tune

Automatically tune the internal 32k RC clock, and get the tuning value.

6.1.1 Prototype

uint16_t platform_32k_rc_auto_tune(void);

6.1.2 Parameters

Void.

6.1.3 Return Value

The 16-bits tuning value.

6.1.4 Remarks

This operation costs ~250ms. It is recommended to call this once and store the returned value for later usage.

6.1.5 Example

uint16_t value = platform_32k_rc_auto_tune();

6.2 platform_32k_rc_tune

Tune internal the 32k RC clock with the tune value.

6.2.1 Prototype

void platform_32k_rc_tune(uint16_t value);

6.2.2 Parameters

6.2.3 Return Value

Void.

6.2.4 Remarks

void.

6.2.5 Example

platform_32k_rc_tune(value);

6.3 platform_config

Configure some platform functionalities.

6.3.1 Prototype

void platform_config(const platform_cfg_item_t item,
                     const uint32_t flag);

6.3.2 Parameters

  • const platform_cfg_item_t item

    Specify the item to be configured. It can be one of following values:

    • PLATFORM_CFG_LOG_HCI: Host controller interface messages. Default: Disabled.

    • PLATFORM_CFG_POWER_SAVING: Power saving. Default: Disabled.

    • PLATFORM_CFG_TRACE_MASK: Bit map of selected trace items. Default: 0.

      typedef enum
      {
          PLATFORM_TRACE_ID_EVENT                 = 0,
          PLATFORM_TRACE_ID_HCI_CMD               = 1,
          PLATFORM_TRACE_ID_HCI_EVENT             = 2,
          PLATFORM_TRACE_ID_HCI_ACL               = 3,
          PLATFORM_TRACE_ID_LLCP                  = 4
      } platform_trace_item_t;
    • PLATFORM_CFG_RC32K_EN: Enable/Disable RC 32k clock. Default: Enabled.

    • PLATFORM_CFG_OSC32K_EN: Enable/Disable 32k crystal oscillator. Default: Enabled.

    • PLATFORM_CFG_32K_CLK: 32k clock selection. Flag is platform_32k_clk_src_t. Default: PLATFORM_32K_RC

      typedef enum
      {    
          PLATFORM_32K_OSC,           // External 32k crystal oscillator
          PLATFORM_32K_RC             // Internal RC 32k clock
      } platform_32k_clk_src_t;

      When modifying this configuration, both RC32K and OSC32K should be enabled and run:

        * For OSC32K, wait until status of OSC32K is OK;
        * For RC32K, wait 100us after enabled.

      Note: Wait another 100us before disabling the unused clock.

    • PLATFORM_CFG_32K_CLK_ACC: Configure 32k clock accurary in ppm.

    • PLATFORM_CFG_32K_CALI_PERIOD: 32K clock auto-calibartion period in seconds. Default: 3600 * 2 (2 hours).

    • PLATFORM_CFG_DEEP_SLEEP_TIME_REDUCTION: Sleep time reduction (deep sleep mode) in micro seconds. Default: ~550us.

    • PLATFORM_CFG_SLEEP_TIME_REDUCTION: Sleep time reduction (other sleep mode) in micro seconds. Default: ~450us.

    • PLATFORM_CFG_LL_DBG_FLAGS: Link layer flags. Combination of bits in ll_cfg_flag_t.

      typedef enum
      {
          LL_FLAG_DISABLE_CTE_PREPROCESSING = 1,  // disable CTE processing
          LL_FLAG_LEGACY_ONLY_INITIATING = 4,     // initiating only using legacy ADV
          LL_FLAG_LEGACY_ONLY_SCANNING = 8,       // scanning only using legacy ADV
      } ll_cfg_flag_t;
    • PLATFORM_CFG_LL_LEGACY_ADV_INTERVAL: Link layer legacy advertising intervals for high duty cycle (higher 16bits) and normal duty cycle (lower 16bits) in micro seconds. Default for high duty cycle: 1250; default for normal duty cycle: 1500.

  • const uint32_t flag

    To disable or enable an item. It can be one of following values:

    • PLATFORM_CFG_ENABLE
    • PLATFORM_CFG_DISABLE

6.3.3 Return Value

Void.

6.3.4 Remarks

Void.

6.3.5 Example

// Enable HCI logging
platform_config(PLATFORM_CFG_LOG_HCI, PLATFORM_CFG_ENABLE);

6.4 platform_get_heap_status

Get current heap status, such as available size, etc.

6.4.1 Prototype

void platform_get_heap_status(platform_heap_status_t *status);

6.4.2 Parameters

  • platform_heap_status_t *status

    Heap status.

6.4.3 Return Value

Void.

6.4.4 Remarks

Heap status is defined as:

typedef struct
{
    uint32_t bytes_free;                // total free bytes
    uint32_t bytes_minimum_ever_free;   // mininum of bytes_free from startup
} platform_heap_status_t;

6.4.5 Example

platform_heap_status_t status;
platform_get_heap_status(&status);

6.5 platform_get_us_time

Read the internal timer counting from BLE initialization.

6.5.1 Prototype

int64_t platform_get_us_time(void);

6.5.2 Parameters

Void.

6.5.3 Return Value

Value of the internal timer counting at 1us.

6.5.4 Remarks

This timer restarts after shutdown, while RTC timer does not.

6.5.5 Example

platform_get_us_time();

6.6 platform_get_version

Get version number of platform.

6.6.1 Prototype

const platform_ver_t *platform_get_version(void);

6.6.2 Parameters

Void.

6.6.3 Return Value

Pointer to platform_ver_t.

6.6.4 Remarks

Platform version number has three parts, major, minor and patch:

typedef struct platform_ver
{
    unsigned short major;
    char  minor;
    char  patch;
} platform_ver_t;

6.6.5 Example

const platform_ver_t *ver = platform_get_version();
printf("Platform version: %d.%d.%d\n", ver->major, ver->minor, ver->patch);

6.7 platform_hrng

Generate random bytes by using hardware random-number generator.

6.7.1 Prototype

void  platform_hrng(uint8_t *bytes, const uint32_t len);

6.7.2 Parameters

  • uint8_t *bytes

    Random data output.

  • const uint32_t len

    Number of random bytes to be generated.

6.7.3 Return Value

Void.

6.7.4 Remarks

Time consumption to generate a fix length of data is undetermined.

6.7.5 Example

uint32_t strong_random;
platform_hrng(&strong_random, sizeof(strong_random));

6.8 platform_install_isr_stack

Install a new stack for ISR.

6.8.1 Prototype

void platform_install_isr_stack(void *top);

6.8.2 Parameters

  • void *top

    Top of the new stack, which must be 4-bytes aligned.

6.8.3 Return Value

Void.

6.8.4 Remarks

In case apps need a much larger stack than the default one in ISR, a new stack can be installed to replace the default one.

This function is only allowed to be called in app_main. The new stack is put into use after app_main returns.

6.8.5 Example

uint32_t new_stack[2048];
...
platform_install_isr_stack(new_stack + sizeof(new_stack) / sizeof(new_stack[0]));

6.9 platform_printf

The printf function stored in platform binary.

6.9.1 Prototype

 void  platform_printf(const char *format, ...);

6.9.2 Parameters

  • const char *format

    Format string.

  • ...

    Variable arguments for format string.

6.9.3 Return Value

Void.

6.9.4 Remarks

There are pros & cons to use this function.

Pros:

  • This function is located in platform binary, app binary size can be saved.

Cons:

  • Output is directed PLATFORM_CB_EVT_PUTC event, so its callback function must be defined.

6.9.5 Example

platform_printf("Hello world");

6.10 platform_raise_assertion

Raise a software assertion.

6.10.1 Prototype

void  platform_raise_assertion(const char *file_name, int line_no);

6.10.2 Parameters

  • const char *file_name

    File name where the assertion occurred.

  • int line_no

    Line number where the assertion occurred.

6.10.3 Return Value

Void.

6.10.4 Remarks

Void.

6.10.5 Example

  if (NULL == ptr)
    platform_raise_assertion(__FILE__, __LINE__);

6.11 platform_rand

Generate a pseudo random integer by internal PRNG.

6.11.1 Prototype

int platform_rand(void);

6.11.2 Parameters

Void.

6.11.3 Return Value

A pseudo random integer in range of 0 to RAND_MAX.

6.11.4 Remarks

Seed of the internal PRNG is initialized by HRNG at startup.

6.11.5 Example

printf("rand: %d\n", platform_rand());

6.12 platform_read_info

Read platform information

6.12.1 Prototype

uint32_t platform_read_info(const platform_info_item_t item);

6.12.2 Parameters

  • const platform_info_item_t item

    Information item.

    typedef enum
    {
        PLATFORM_INFO_OSC32K_STATUS,     // Read status of 32k crystal oscillator.
                                         // Value 0: not OK; Non-0: OK
    } platform_info_item_t;

6.12.3 Return Value

Value of the information item.

6.12.4 Remarks

Void.

6.12.5 Example

platform_read_info(PLATFORM_INFO_OSC32K_STATUS);

6.13 platform_read_persistent_reg

Read value from the persistent register. See also platform_write_persistent_reg.

6.13.1 Prototype

uint32_t platform_read_persistent_reg(void);

6.13.2 Parameters

Void.

6.13.3 Return Value

The **four* bits value writen by platform_write_persistent_reg.

6.13.4 Remarks

Void.

6.13.5 Example

platform_read_persistent_reg();

6.14 platform_reset

Reset platform (SoC).

6.14.1 Prototype

void platform_reset(void);

6.14.2 Parameters

Void.

6.14.3 Return Value

Void.

6.14.4 Remarks

When calling this function, the code after it will not be executed.

6.14.5 Example

  if (out-of-memory)
    platform_reset();

6.15 platform_set_evt_callback

Registers callback functions to platform events.

6.15.1 Prototype

void platform_set_evt_callback(platform_evt_callback_type_t type, 
                               f_platform_evt_cb f, 
                               void *user_data);

6.15.2 Parameters

  • platform_evt_callback_type_t type

    Specify the event type to which the callback function is registered. It can be one of following values:

    • PLATFORM_CB_EVT_PUTC: Ouput ASCII character event

      When platform want to output ASCII characters for logging, this event is fired. Parameter void *data passed into the callback function is casted from char *.

      ingWizard can automatically generate code that redirects platform log to UART if Print to UART is checked on Common Function when creating a new project.

    • PLATFORM_CB_EVT_PROFILE_INIT: Profile initialization event

      When host initializes, this event is fired to request app to initialize GATT profile.

      ingWizard can automatically generate code for this event when creating a new project.

    • PLATFORM_CB_EVT_ON_DEEP_SLEEP_WAKEUP: Wakeup from deep sleep event

      When waking up from deep sleep, this event is fired. During deep sleep, peripheral interfaces (such as UART, I2C, etc) are all powered off. So, when waking up, these interfaces might need to be re-initialized.

      ingWizard can automatically generate code for event if Deep Sleep is checked on Common Function when creating a new project.

    • PLATFORM_CB_EVT_QUERY_DEEP_SLEEP_ALLOWED: Query if deep sleep is allowed event

      When platform prepares to enter deep sleep mode, this event is fired to query app if deep sleep is allow at this moment. Callback function can reject deep sleep by returning 0, and allow it by returning a non-0 value.

      ingWizard can automatically generate code for event if Deep Sleep is checked on Common Function when creating a new project.

    • PLATFORM_CB_EVT_HARD_FAULT: Hard fault occurs

      When hard fault occurs, this event is fired. Parameter void *data passed into the callback function is casted from hard_fault_info_t *. If this callback is not defined, CPU enters a dead loop when hard fault occurs.

    • PLATFORM_CB_EVT_ASSERTION: Software assertion fails

      When software assertion fails, this event is fired. Parameter void *data passed into the callback function is casted from assertion_info_t *. If this callback is not defined, CPU enters a dead loop when assertion occurs.

    • PLATFORM_CB_EVT_LLE_INIT: Link layer engine initialized.

      When link layer engine initialized, this event is fired.

    • PLATFORM_CB_EVT_HEAP_OOM: Out of memory.

      When allocation on heap fails (heap out of memory), this event is fired. If this event is fired and no callback is defined, CPU enters a dead loop.

    • PLATFORM_CB_EVT_TRACE: Trace output.

      When a trace item is emitted, this event is fired. Apps can define a callback function for this event to save or log trace output. param to the callback is casted from platform_trace_evt_t * (See Debugging & Tracing).

      typedef struct
      {
          const void *data1;
          const void *data2;
          uint16_t len1;
          uint16_t len2;
      } platform_evt_trace_t;

      A trace item is a combination of data1 and data2. Note:

      1. len1 or len2 might be 0, but not both;

      2. If callback function finds that it can’t output data of size len1 + len2, then, both data1 & data2 should be discarded to avoid trace item corruption.

  • f_platform_evt_cb f

    The callback function registered to event type. f_platform_evt_cb is:

    typedef uint32_t (*f_platform_evt_cb)(void *data, void *user_data);
  • void *user_data

    This is passed to callback function’s user_data unchanged.

6.15.3 Return Value

Void.

6.15.4 Remarks

It is not required to register callback functions to each event.

If no callback function is registered to PLATFORM_CB_EVT_PUTC event, all platform log is discarded.

If no callback function is registered to PLATFORM_CB_EVT_PROFILE_INIT event, BLE device’s profile is empty.

If no callback function is registered to PLATFORM_CB_EVT_ON_DEEP_SLEEP_WAKEUP event, app will not be notified when waking up from deep sleep.

If no callback function is registered to PLATFORM_CB_EVT_QUERY_DEEP_SLEEP_ALLOWED event, deep sleep is disabled.

6.15.5 Example

uint32_t cb_putc(char *c, void *dummy)
{
    // TODO: output char c to UART
    return 0;
}

......

platform_set_evt_callback(PLATFORM_CB_EVT_PUTC, (f_platform_evt_cb)cb_putc, 
                          NULL);

6.16 platform_set_irq_callback

Registers callback functions to interrupt requests.

Developers do not need to define IRQ handlers in apps, but use callback functions instead. There are 11 such IRQs, summarized in Table 6.1.

Table 6.1: IRQ Summary
Peripheral Type Number Notes
RTC 1 Real Time Clock
TIMER 3 Timer
GPIO 1 General Purpose Input/Output
SPI 2 Serial Peripheral Interface
UART 2 Universal Asynchronous Receiver-Transmitter
I2C 2 Inter-Integrated Circuit

6.16.1 Prototype

void platform_set_irq_callback(platform_irq_callback_type_t type,
                               f_platform_irq_cb f, 
                               void *user_data);

6.16.2 Parameters

  • platform_irq_callback_type_t type

    Specify the IRQ type to which the callback function is registered. It can be one of following values:

    PLATFORM_CB_IRQ_RTC,
    PLATFORM_CB_IRQ_TIMER0,
    PLATFORM_CB_IRQ_TIMER1,
    PLATFORM_CB_IRQ_TIMER2,
    PLATFORM_CB_IRQ_GPIO,
    PLATFORM_CB_IRQ_SPI0,
    PLATFORM_CB_IRQ_SPI1,
    PLATFORM_CB_IRQ_UART0,
    PLATFORM_CB_IRQ_UART1,
    PLATFORM_CB_IRQ_I2C0,
    PLATFORM_CB_IRQ_I2C1
  • f_platform_irq_cb f

    The callback function registered to IRQ type. f_platform_irq_cb is:

    typedef uint32_t (*f_platform_irq_cb)(void *user_data);
  • void *user_data

    This is passed to callback function’s user_data unchanged.

6.16.3 Return Value

Void.

6.16.4 Remarks

When a callback function is registered to an IRQ, the IRQ is enabled automatically.

6.16.5 Example

uint32_t cb_irq_uart0(void *dummy)
{
    // TODO: add UART0 IRQ handling code
    return 0;
}

......

platform_set_irq_callback(PLATFORM_CB_IRQ_UART0, cb_irq_uart0, 
                          NULL);

6.17 platform_shutdown

Bring the whole system into shutdown state, and reboot after a specified duration. Optionally, a portion of memory can be retentioned during shutdown, and apps can continue to use it after reboot.

Note that this function will NOT return except that shutdown procedure fails to initiate. Possible causes for failures include:

  1. External wake-up signal is issued;
  2. Input parameters are not proper;
  3. Internal components are busy.

6.17.1 Prototype

void platform_shutdown(const uint32_t duration_cycles, 
                       const void *p_retention_data,
                       const uint32_t data_size);

6.17.2 Parameters

  • const uint32_t duration_cycles

    Duration (measured in cycles of 32k clock) before power on again (reboot). The minimum duration is 825 cycles (about 25.18ms). If 0 is used, the system will stay in shutdown state until external wake-up signal is issued.

  • const void *p_retention_data

    Pointer to the start of data to be retentioned. Only data within SYSTEM memory can be retentioned. This parameter can be set to NULL when data_size is 0.

  • data_size

    Size of the data to be retentioned. Set to 0 when memory retention is not needed.

6.17.3 Return Value

Void.

6.17.4 Remarks

Void.

6.17.5 Example

// Shutdown the system and reboot after 1s.
platform_shutdown(32768, NULL, 0);

6.18 platform_switch_app

Switch to a secondary app.

6.18.1 Prototype

void platform_switch_app(const uint32_t app_addr);

6.18.2 Parameters

  • const uint32_t app_addr

    Entry address of the secondary app.

6.18.3 Return Value

Void.

6.18.4 Remarks

When calling this function, the code after it will not be executed.

6.18.5 Example

platform_switch_app(0x80000);

6.19 platform_write_persistent_reg

Write a value to the persistent register. This value is kept even in power saving, shutdown mode, or when switching to another app.

6.19.1 Prototype

void platform_write_persistent_reg(const uint8_t value);

6.19.2 Parameters

  • const uint8_t value

    The value.

6.19.3 Return Value

Void.

6.19.4 Remarks

Only four bits are saved.

6.19.5 Example

platform_write_persistent_reg(1);

6.20 sysSetPublicDeviceAddr

Set the public address of device.

The public address of a BLE device is a 48-bit extended unique identifier (EUI-48) created in accordance with the IEEE 802-2014 standard18.

INGCHIPS 918xx DO NOT have public addresses. This function should ONLY be used for debugging or testing, and NEVER be used in final products.

6.20.1 Prototype

void sysSetPublicDeviceAddr(const unsigned char *addr);

6.20.2 Parameters

  • const unsigned char *addr

    New public address.

6.20.3 Return Value

Void.

6.20.4 Remarks

In order to avoid potential issues, this function should be called before calling any GAP functions. It is recommended to call this function in app_main or PLATFORM_CB_EVT_PROFILE_INIT event callback function.

6.20.5 Example

const unsigned char pub_addr[] = {1,2,3,4,5,6};
sysSetPublicDeviceAddr(pub_addr);