Chapter 6 Platform API Reference
This chapter describes the platform API.
6.1 Configuration & Information
6.1.1 platform_config
Configure some platform functionalities.
6.1.1.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
: Print host controller interface messages. Default: Disabled.Only available on ING918. HCI logging is only intended for a quick check on BLE behavior. Please consider using tracing (see Debugging & Tracing).
PLATFORM_CFG_POWER_SAVING
: Power saving. Default: Disabled.PLATFORM_CFG_TRACE_MASK
: Bit map of selected trace items. Default:0
.typedef enum { = 0, PLATFORM_TRACE_ID_EVENT = 1, PLATFORM_TRACE_ID_HCI_CMD = 2, PLATFORM_TRACE_ID_HCI_EVENT = 3, PLATFORM_TRACE_ID_HCI_ACL = 4, PLATFORM_TRACE_ID_LLCP //.. } platform_trace_item_t;
PLATFORM_CFG_RT_RC_EN
: Enable/Disable real-time RC clock. Default: Enabled.PLATFORM_CFG_RT_OSC_EN
: Enable/Disable real-time crystal oscillator. Default: Enabled.PLATFORM_CFG_RT_CLK
: Real-time clock selection. Flag isplatform_rt_clk_src_t
. Default:PLATFORM_RT_RC
typedef enum { , // External real-time crystal oscillator PLATFORM_RT_OSC// Internal real-time RC clock PLATFORM_RT_RC } platform_rt_clk_src_t;
For ING918, When modifying this configuration, both RT_RC and RT_OSC should be enabled and run:
* For RT_OSC, wait until status of RT_OSC is OK; * For RT_RC, wait 100μs after enabled.
And wait another 100μs before disabling the unused clock.
PLATFORM_CFG_RT_CLK_ACC
: Configure real-time clock accuracy in ppm.PLATFORM_CFG_RT_CALI_PERIOD
: Real-time clock auto-calibration period in seconds. Default: 3600 * 2 (2 hours).PLATFORM_CFG_DEEP_SLEEP_TIME_REDUCTION
: Sleep time reduction (deep sleep mode) in micro seconds. ING918 Default: ~550μs.PLATFORM_CFG_SLEEP_TIME_REDUCTION
: Sleep time reduction (other sleep mode) in micro seconds. ING918 Default: ~450μs.PLATFORM_CFG_LL_DBG_FLAGS
: Link layer flags. Combination of bits inll_cfg_flag_t
.typedef enum { = 1, // disable CTE processing LL_FLAG_DISABLE_CTE_PREPROCESSING = 4, // initiating only using legacy ADV LL_FLAG_LEGACY_ONLY_INITIATING = 8, // scanning only using legacy ADV LL_FLAG_LEGACY_ONLY_SCANNING } 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.PLATFORM_CFG_RTOS_ENH_TICK
: Enable enhanced ticks for RTOS. Default: Disabled. When enabled, ticks becomes more accurate when peripherals are generating interrupt requests frequently.PLATFORM_CFG_LL_DELAY_COMPENSATION
: Delay compensation for Link Layer.When system runs at a lower frequency, more time (in μs) is needed by Link Layer to schedule RF tasks. For example, if ING916 runs at 24MHz, a compensation of ~2500 μs is needed.
PLATFORM_CFG_24M_OSC_TUNE
: 24M OSC tunning. Not available for ING918.For ING916, tunning value may vary in 0x16~0x2d.
PLATFORM_CFG_ALWAYS_CALL_WAKEUP
: Always triggerPLATFORM_CB_EVT_ON_DEEP_SLEEP_WAKEUP
event no matter if deep sleep procedure is completed or aborted (failed). Default for ING918: Disabled for backward compatibility. Default for ING916: Enabled.PLATFORM_CFG_FAST_DEEP_SLEEP_TIME_REDUCTION
: Sleep time reduction for fast deep sleep mode in micro seconds. Not available for ING918.This configuration must be less or equal to
PLATFORM_CFG_DEEP_SLEEP_TIME_REDUCTION
. When equal toPLATFORM_CFG_DEEP_SLEEP_TIME_REDUCTION
, fast deep sleep mode is not used.Default for ING916: ~2000μs.
PLATFORM_CFG_AUTO_REDUCE_CLOCK_FREQ
: Automatically reduce CPU clock frequency in these circumstances:- The default IDLE procedure,
- When entering sleep modes.
Not available for ING918. Default for ING916: Enabled.
const uint32_t flag
To disable or enable an item. It can be one of following values:
PLATFORM_CFG_ENABLE
PLATFORM_CFG_DISABLE
6.1.2 platform_get_version
Get version number of platform.
6.1.3 platform_read_info
Read platform information.
6.1.3.2 Parameters
const platform_info_item_t item
Information item.
PLATFORM_INFO_RT_OSC_STATUS
: Read status of real-time crystal oscillator. Value 0: not OK; Non-0: OK.
For ING916: this clock become running after selected as real time clock source.
PLATFORM_INFO_RT_CLK_CALI_VALUE
: Read current real time clock calibration result.PLATFOFM_INFO_IRQ_NUMBER
: Get the underline IRQ number of a platform IRQ.For example, get the underline IRQ number of UART0:
( platform_read_info+ PLATFORM_CB_IRQ_UART0) PLATFOFM_INFO_IRQ_NUMBER
6.2 Events & Interrupts
6.2.1 platform_set_evt_callback_table
Register a callback function table for all platform events.
6.2.1.4 Remarks
This function shall only be called in app_main
. If platform_set_evt_callback
is used,
this function shall not be used.
Comparing to platform_set_evt_callback
, use this function can save a block of RAM
of sizeof(platform_evt_cb_table_t)
bytes.
6.2.1.5 Example
static const platform_evt_cb_table_t evt_cb_table =
{
.callbacks = {
[PLATFORM_CB_EVT_HARD_FAULT] = {
.f = (f_platform_evt_cb)cb_hard_fault,
},
[PLATFORM_CB_EVT_PROFILE_INIT] = {
.f = setup_profile,
},
// ...
}
};
int app_main()
{
// ...
(&evt_cb_table);
platform_set_evt_callback_table// ...
}
6.2.2 platform_set_irq_callback_table
Register a callback function table for all platform interrupt requests.
6.2.3 platform_set_evt_callback
Registers callback functions to platform events.
6.2.3.1 Prototype
void platform_set_evt_callback(platform_evt_callback_type_t type,
,
f_platform_evt_cb fvoid *user_data);
6.2.3.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 eventWhen platform want to output ASCII characters for logging, this event is fired. Parameter
void *data
passed into the callback function is casted fromchar *
.Wizard
can automatically generate code that redirects platform log to UART ifPrint to UART
is checked onCommon Function
when creating a new project.PLATFORM_CB_EVT_PROFILE_INIT
: Profile initialization eventWhen host initializes, this event is fired to request app to initialize GATT profile.
Wizard
can automatically generate code for this event when creating a new project.PLATFORM_CB_EVT_ON_DEEP_SLEEP_WAKEUP
: Wakeup from deep sleep eventWhen 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.
Wizard
can automatically generate code for event ifDeep Sleep
is checked onCommon Function
when creating a new project.Parameter
void *data
passed into the callback function is casted fromplatform_wakeup_call_info_t *
.RTOS is not resumed yet, some ROTS APIs are not usable; Some platform APIs (such as
platform_get_us_time
) might be unusable either.PLATFORM_CB_EVT_ON_IDLE_TASK_RESUMED
: OS is fully resumed from power saving modes.The callback is invoked after
PLATFORM_CB_EVT_ON_DEEP_SLEEP_WAKEUP
if its reason isPLATFORM_WAKEUP_REASON_NORMAL
. For NoOS variants, the callback is invoked byplatform_os_idle_resumed_hook()
. This event is different withPLATFORM_CB_EVT_ON_DEEP_SLEEP_WAKEUP
:- all OS functionalities are resumed (For NoOS variants, this depends on the
proper use of
platform_os_idle_resumed_hook()
) - all platform APIs are functional
- callback is invoked in the idle task.
Parameter
void *data
is alwaysNULL
.- all OS functionalities are resumed (For NoOS variants, this depends on the
proper use of
PLATFORM_CB_EVT_QUERY_DEEP_SLEEP_ALLOWED
: Query if deep sleep is allowed eventWhen 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.Wizard
can automatically generate code for event ifDeep Sleep
is checked onCommon Function
when creating a new project.PLATFORM_CB_EVT_HARD_FAULT
: Hard fault occursWhen hard fault occurs, this event is fired. Parameter
void *data
passed into the callback function is casted fromhard_fault_info_t *
. If this callback is not defined, CPU enters a dead loop when hard fault occurs.PLATFORM_CB_EVT_ASSERTION
: Software assertion failsWhen software assertion fails, this event is fired. Parameter
void *data
passed into the callback function is casted fromassertion_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 fromplatform_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
anddata2
. Note:len1
orlen2
might be 0, but not both;If callback function finds that it can’t output data of size
len1
+len2
, then, bothdata1
&data2
should be discarded to avoid trace item corruption.
PLATFORM_CB_EVT_EXCEPTION
: Hardware exceptions.Parameter
void *data
is casted fromplatform_exception_id_t *
.PLATFORM_CB_EVT_IDLE_PROC
: Customized IDLE procedure.See “Programmer’s Guide - Power Saving”23.
PLATFORM_CB_EVT_HCI_RECV
: Take over HCI and isolate the built-in Host completely.When defined:
- HCI events and ACL data are passed to this callback;
PLATFORM_CB_EVT_PROFILE_INIT
is ignored.
Parameter
void *data
is casted fromconst platform_hci_recv_t *
. See alsoplatform_get_link_layer_interf
.
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.2.3.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
including platform_printf
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.2.4 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.
6.2.4.1 Prototype
void platform_set_irq_callback(platform_irq_callback_type_t type,
,
f_platform_irq_cb fvoid *user_data);
6.2.4.2 Parameters
platform_irq_callback_type_t type
Specify the IRQ type to which the callback function is registered. Values vary for different chip families. Take ING918 as an example:
, 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.2.4.4 Remarks
When a callback function is registered to an IRQ, the IRQ is enabled automatically.
See also platform_enable_irq
.
6.2.5 platform_enable_irq
Enable or disable a specified IRQ.
6.2.5.2 Parameters
platform_irq_callback_type_t type
:The IRQ to be configured.
uint8_t flag
:Enable (1) or disable (0).
6.3 Clocks
See also “The Real-time Clock”24 in “Programmer’s Guide - Power Saving”25.
6.3.2 platform_rt_rc_auto_tune
Automatically tune the internal real-time RC clock, and get the tuning value.
For ING918, this function tunes the internal real-time RC clock to 50kHz26. For others, it tunes the internal real-time RC clock to 32768Hz.
6.3.3 platform_rt_rc_auto_tune2
Automatically tune the internal real-time RC clock to a specific frequency, and get the tuning value.
6.3.4 platform_rt_rc_tune
Tune internal the real-time RC clock with the tune value.
6.3.4.2 Parameters
uint16_t value
Value used to tune the clock (returned by
platform_rt_rc_auto_tune
, orplatform_rt_rc_auto_tune2
)
6.4 RF
6.4.2 platform_set_rf_init_data
Customize RF initialization data. This function is for internal use.
6.4.3 platform_set_rf_power_mapping
Power level is represented by an index internally. There is a power mapping table which lists the actual Tx power level of an index. Take ING918 as an example, power index is in a range of [0..63], and power mapping table is an array of 64 entries, each entry giving the Tx power level in 0.01 dBm.
For applications that need better power level control, actual power level can be measured for each index. Update the mapping with this function, then the stack can determine the proper index for a request power level.
6.5 Memory & RTOS
6.5.1 platform_call_on_stack
Call a function on a separate dedicated stack. This is useful when a function that uses a lot of stack needs to be called, occasionally.
6.5.1.1 Prototype
void platform_call_on_stack(
,
f_platform_function fvoid *user_data,
void *stack_start,
uint32_t stack_size);
6.5.2 platform_get_current_task
Get the current task from which this API is called.
6.5.3 platform_get_gen_os_driver
Get the generic OS driver. For “NoOS” variants, driver provided by app is returned; for bundles with built-in RTOS, an emulated driver is returned.
6.5.4 platform_get_heap_status
Get current heap status, such as available size, etc.
6.5.6 platform_install_task_stack
Install a new RTOS stack for a specific platform task.
Use this to enlarge stack when the default stack size is not enough for internal tasks. For example, user developed RTOS timer callbacks might require a larger stack space.
Developers can check RTOS documentation for how to check stack usages. For example,
uxTaskGetStackHighWaterMark
in FreeRTOS is used to query how close a task has
come to overflowing the stack space allocated to it.
6.5.6.1 Prototype
void platform_install_task_stack(
,
platform_task_id_t idvoid *start,
uint32_t size);
6.5.7 platform_install_isr_stack
Install a new stack for ISR.
6.5.7.2 Parameters
void *top
Top of the new stack, which must be properly aligned for the underlying CPU.
6.6 Time & Timers
API for reading current time (timer counter):
platform_get_timer_counter
platform_get_us_time
API for using timers with 625μs resolution:
platform_set_abs_timer
platform_set_timer
platform_delete_timer
API for using timer with 1μs resolution:
platform_create_us_timer
platform_cancel_us_timer
Both types of timers can be used with power saving, i.e. it just works as expected when power saving is enabled. A comparison of of these two types of timers is shown in Table 6.1.
Type | 625μs resolution | 1μs resolution |
---|---|---|
Callback | Invoked from a task-like context | Invoked from an ISR |
Identifier | Callback function pointer | Timer handle |
6.6.1 platform_cancel_us_timer
Cancel a platform timer previously created by platform_create_us_timer
.
6.6.2 platform_create_us_timer
Setup a single-shot platform timer with 1 microsecond (μs) resolution.
6.6.2.1 Prototype
(
platform_us_timer_handle_t platform_create_us_timeruint64_t abs_time,
,
f_platform_us_timer_callback callbackvoid *param);
6.6.2.2 Parameters
uint64_t abs_time
When
platform_get_us_timer() == abs_time
, the callback is invoked.f_platform_us_timer_callback callback
The callback function. The signature is:
typedef void * (* f_platform_us_timer_callback)( , platform_us_timer_handle_t timer_handleuint64_t time_us, void *param);
Where,
timer_handle
is the returned value ofplatform_create_us_timer
, i.e. ,time_us
is current value ofplatform_get_us_timer
when invoking the callback, andparam
is the user parameter when creating this timer.void *param
User parameter.
6.6.2.3 Return Value
This function returns a handle of the created timer. A non-NULL value is returned when the timer is successfully created. Otherwise, NULL is returned.
6.6.2.4 Remarks
Although abs_time
is in microsecond (μs), callback is not guaranteed to be
invoked with such resolution.
This type of timers are much like platform_set_timer
, except that:
- resolution is higher;
- callback is invoked in the context of an ISR.
DO NOT call platform_create_us_timer
again in callback
.
6.6.3 platform_delete_timer
Delete a previously platform timer created by platform_set_timer
or platform_set_abs_timer
.
6.6.5 platform_get_us_time
Read the internal time counting from BLE initialization.
6.6.6 platform_set_abs_timer
Setup a single-shot platform timer triggered at an absolute time with 625μs resolution.
6.6.6.1 Prototype
void platform_set_abs_timer(
,
f_platform_timer_callback callbackuint32_t abs_time);
6.6.6.2 Parameters
f_platform_timer_callback callback
The callback function when the timer expired, and is called in a RTOS task-like27 context, but not an ISR.
uint32_t abs_time
when
platform_get_timer_counter() == abs_time
,callback
is invoked. Ifabs_time
just passesplatform_get_timer_counter()
,callback
is invoked immediately, for example,abs_time
isplatform_get_timer_counter() - 1
.
6.6.6.5 Example
Use this function to emulate a periodic timer.
#define PERIOD 100
static uint32_t last_timer = 0;
void platform_timer_callback(void)
{
+= PERIOD;
last_timer (platform_timer_callback, last_timer);
platform_set_abs_timer
// do periodic job
// ...
}
= platform_get_timer_counter() + PERIOD;
last_timer (platform_timer_callback, last_timer); platform_set_abs_timer
6.6.7 platform_set_timer
Setup a single-shot platform timer after a delay from “now” with 625μs resolution.
6.6.7.2 Parameters
f_platform_timer_callback callback
The callback function when the timer expired, and is called in a RTOS task-like context, but not an ISR.
uint32_t delay
Time delay before the timer expires (unit: 625μs).
Valid Range: 0~0x7fffffff. When
delay
is 0, the timer is cleared.
6.6.7.4 Remarks
This function always succeeds, except when running out of memory.
platform_set_timer(f, 100)
is equivalent to:
(f,
platform_set_abs_timer() + 100); platform_get_timer_counter
platform_set_timer(f, 0)
is equivalent to:
(f); platform_delete_timer
but not
(f,
platform_set_abs_timer() + 0); platform_get_timer_counter
Since callback
is also the identifier of the timer, below two lines defines only
a timer expiring after 200 units but not two separate timers:
(f, 100);
platform_set_timer(f, 200); // update the timer, but not creating a new one platform_set_timer
If f
is used once again in platform_set_abs_timer
, then the timer is updated
again:
(f, ...); platform_set_abs_timer
6.7 Utilities
6.7.1 platform_hrng
Generate random bytes by using hardware random-number generator.
6.7.2 platform_rand
Generate a pseudo random integer by internal PRNG.
6.7.3 platform_read_persistent_reg
Read value from the persistent register. See also
platform_write_persistent_reg
.
6.7.3.3 Return Value
The value written by
platform_write_persistent_reg
.
6.7.5 platform_shutdown
Bring the whole system into shutdown state, and reboot after a specified duration. Optionally, a portion of memory can be retained 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:
- External wake-up signal is issued;
- Input parameters are not proper;
- Internal components are busy.
6.7.5.1 Prototype
void platform_shutdown(const uint32_t duration_cycles,
const void *p_retention_data,
const uint32_t data_size);
6.7.5.2 Parameters
const uint32_t duration_cycles
Duration (measured in cycles of real-time 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 retained. Only data within SYSTEM memory can be retained. This parameter can be set to
NULL
whendata_size
is0
.data_size
Size of the data to be retained. Set to
0
when memory retention is not needed.
6.7.6 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.
Only a few bits are saved as shown in Table 6.2.
Chip Family | Register Size (bit) |
---|---|
ING918 | 4 |
ING916 | 5 |
6.8 Debugging & Tracing
6.8.1 platform_printf
The printf
function stored in platform binary.
6.9 Others
6.9.2 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 standard28.
https://ingchips.github.io/application-notes/pg_power_saving_en/↩︎
https://ingchips.github.io/application-notes/pg_power_saving_en/ch-api.html#the-real-time-clock↩︎
https://ingchips.github.io/application-notes/pg_power_saving_en/↩︎
Starting from v8.4.6. For elder version, 32768Hz is used.↩︎
It’s called from the Controller task if existing.↩︎