4. User Guides

4.1. BLE Features

4.1.1. Device Configuration

Device configuration is provided at user level and subsequently applied in the application layer of the SDK. In the context of our BLE example applications, such a configuration is defined in the form of a structure, namely user_gapm_conf, in the respective user_config.h file. It is possible to modify the members of the structure as needed. For instance, GAP role and Bluetooth device address are two of the configuration items that may be provided at user level.

The following code snippet from user_config.h shows the GAPM configuration struct of ble_app_barebone example application:

static const struct gapm_configuration user_gapm_conf = {
    /// Device Role: Central, Peripheral, Observer, Broadcaster or All roles. (@see enum gap_role)
    .role = GAP_ROLE_PERIPHERAL,

    /// Maximal MTU. Shall be set to 23 if Legacy Pairing is used, 65 if Secure Connection is used,
    /// more if required by the application
    .max_mtu = 23,

    /// Device Address Type
    .addr_type = APP_CFG_ADDR_TYPE(USER_CFG_ADDRESS_MODE),
    /// Duration before regenerating the Random Private Address when privacy is enabled
    .renew_dur = 15000,    // 15000 * 10ms = 150s is the minimum value

    /***********************
     * Privacy configuration
     ***********************
     */

    /// Random Static address
    // NOTE: The address shall comply with the following requirements:
    // - the two most significant bits of the address shall be equal to 1,
    // - all the remaining bits of the address shall NOT be equal to 1,
    // - all the remaining bits of the address shall NOT be equal to 0.
    // In case the {0x00, 0x00, 0x00, 0x00, 0x00, 0x00} null address is used, a
    // random static address will be automatically generated.
    .addr = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00},

    /// Device IRK used for Resolvable Private Address generation (LSB first)
    .irk = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f},

    /****************************
     * ATT database configuration
     ****************************
     */

    /// Attribute database configuration (@see enum gapm_att_cfg_flag)
    ///    7     6    5     4     3    2    1    0
    /// +-----+-----+----+-----+-----+----+----+----+
    /// | DBG | RFU | SC | PCP | APP_PERM |NAME_PERM|
    /// +-----+-----+----+-----+-----+----+----+----+
    /// - Bit [0-1]: Device Name write permission requirements for peer device (@see device_name_write_perm)
    /// - Bit [2-3]: Device Appearance write permission requirements for peer device (@see device_appearance_write_perm)
    /// - Bit [4]  : Slave Preferred Connection Parameters present
    /// - Bit [5]  : Service change feature present in GATT attribute database.
    /// - Bit [6]  : Reserved
    /// - Bit [7]  : Enable Debug Mode
    .att_cfg = GAPM_MASK_ATT_SVC_CHG_EN,

    /// GAP service start handle
    .gap_start_hdl = 0,

    /// GATT service start handle
    .gatt_start_hdl = 0,

    /**************************************************
     * Data packet length extension configuration (4.2)
     **************************************************
     */

    /// Maximal MPS
    .max_mps = 0,

    /// Maximal Tx octets (connInitialMaxTxOctets value, as defined in 4.2 Specification)
    .max_txoctets = 251,

    /// Maximal Tx time (connInitialMaxTxTime value, as defined in 4.2 Specification)
    .max_txtime = 2120,
};

4.1.1.1. Bluetooth Device Address Types

All Bluetooth devices shall have a Bluetooth Device Address that uniquely identifies the device to another Bluetooth device.

Bluetooth device address may be configured at user level if USER_CFG_ADDRESS_MODE is modified according to the user’s needs (see user_config.h in ble_app_barebone, as an example).

There are two types of Bluetooth device address:

  • Public (APP_CFG_ADDR_PUB)

  • Random

The random device address may be of either of the following two sub-types:

  • Static (APP_CFG_ADDR_STATIC)

  • Private

In turn, the private device address may be of one of the following sub-types:

  • APP_CFG_HOST_PRIV_RPA: The device operates with a resolvable private address that is generated in the BLE Host

  • APP_CFG_HOST_PRIV_NRPA: The device operates with a non-resolvable private address that is generated in the BLE Host (non-connectable device)

  • APP_CFG_CNTL_PRIV_RPA_PUB: The device operates with a resolvable private address that is generated in the BLE Controller. If the resolving list of the device is empty, i.e. there are no bonded peers on the list, the device will operate with a public address

  • APP_CFG_CNTL_PRIV_RPA_RAND: The device operates with a resolvable private address that is generated in the BLE Controller (independent of the existence of bonded peers on the resolving list)

Note

The public address type of the device for the ble_app_barebone example application is set with the USER_CFG_ADDRESS_MODE flag in user_config.h.

#define USER_CFG_ADDRESS_MODE       APP_CFG_ADDR_PUB

Note

The public address of the device for the ble_app_barebone example application is set with the CFG_NVDS_TAG_BD_ADDRESS flag in da14531_config_advanced.h as an example.

#define CFG_NVDS_TAG_BD_ADDRESS             {0x09, 0x00, 0xF4, 0x35, 0x23, 0x48}

4.1.2. Advertising Configuration

One may configure advertising through the advertise_configuration structure (see user_config.h in ble_app_barebone, as an example):

  • Advertising mode in the cases of non-connectable undirected (GAPM_ADV_NON_CONN) and connectable undirected (GAPM_ADV_UNDIRECT) advertising:

    • GAP_NON_DISCOVERABLE – Non-discoverable

    • GAP_GEN_DISCOVERABLE – General discoverable

    • GAP_LIM_DISCOVERABLE – Limited discoverable

    • GAP_BROADCASTER_MODE – Broadcaster

  • Advertising filter policy in the cases of non-connectable undirected (GAPM_ADV_NON_CONN) and connectable undirected (GAPM_ADV_UNDIRECT) advertising:

    • ADV_ALLOW_SCAN_ANY_CON_ANY – Allow both scan and connection requests from any device

    • ADV_ALLOW_SCAN_ANY_CON_WLST – Allow scan requests from any device and connection requests from whitelist devices only

  • Peer device address in the case of connectable directed advertising (GAPM_ADV_DIRECT or GAPM_ADV_DIRECT_LDC)

  • Peer device address type in the case of connectable directed advertising (GAPM_ADV_DIRECT or GAPM_ADV_DIRECT_LDC):

    • 0 – Public

    • 1 – Random

4.1.3. Advertising Types

The following 4 advertising types are supported:

ADV_IND

Connectable undirected advertising: Starts by calling the app_easy_gap_undirected_advertise_start() API function.

ADV_DIRECT_IND

Connectable directed advertising: Starts by calling the app_easy_gap_directed_advertise_start() API function, optionally enabling the low duty cycle mode.

ADV_NONCONN_IND

Non-connectable undirected advertising: Starts by calling the app_easy_gap_non_connectable_advertise_start() API function, without any scan response data.

The following code snippet from user_config.h implies that ADV_NONCONN_IND type will be used:

/// Advertising data
#define USER_ADVERTISE_DATA         "\x03"\
                                    ADV_TYPE_COMPLETE_LIST_16BIT_SERVICE_IDS\
                                    ADV_UUID_DEVICE_INFORMATION_SERVICE

/// Scan response data
#define USER_ADVERTISE_SCAN_RESPONSE_DATA ""
ADV_SCAN_IND

Scannable undirected advertising: Starts by calling the app_easy_gap_non_connectable_advertise_start() API function, additionally providing scan response data.

The following code snippet from user_config.h implies that ADV_SCAN_IND type will be used:

/// Advertising data
#define USER_ADVERTISE_DATA         ("\x09"\
                                    ADV_TYPE_COMPLETE_LIST_16BIT_SERVICE_IDS\
                                    ADV_UUID_LINK_LOSS_SERVICE\
                                    ADV_UUID_IMMEDIATE_ALERT_SERVICE\
                                    ADV_UUID_TX_POWER_SERVICE\
                                    ADV_UUID_SUOTAR_SERVICE\
                                    "\x10"\
                                    ADV_TYPE_URI\
                                    "\x16\x2F\x2F\x77\x77\x77\x2E\x69\x61\x6E\x61\x2E\x6F\x72\x67")

/// Scan response data
#define USER_ADVERTISE_SCAN_RESPONSE_DATA     "\x0a"\
                                              ADV_TYPE_MANUFACTURER_SPECIFIC_DATA\
                                              ADV_DIALOG_MANUFACTURER_CODE\
                                              "DLG-BLE"

The SDK BLE example applications use by default the ADV_IND type (with the exception of ble_app_non_con demonstrating both ADV_NONCONN_IND and ADV_SCAN_IND).

As an example, ble_app_barebone may be modified (see user_app_adv_start() function in aforementioned BLE example) to demonstrate any of the rest advertising types.

4.1.4. Advertising Data Update

The app_easy_gap_update_adv_data() API function may be called in order for the advertising data to be updated during the application runtime. The aforementioned function may be called in order for the scan response data to be updated as well.

As an example, see the adv_data_update_timer_cb() callback function in the ble_app_barebone example application.

4.1.5. Application Timer

In order to add a one-shot timer in the application context, the app_easy_timer() API function may be called. In order to restart an already added timer, the above-mentioned function shall be called again. Other related API functions are:

  • app_easy_timer_cancel() to cancel a programmed application timer

  • app_easy_timer_modify() to modify a programmed application timer

  • app_easy_timer_cancel_all() to cancel all programmed application timers

As an example, in the ble_app_barebone example application, a timer has been added to the user_app_adv_start() function. Once the timer expires, i.e. in 30 seconds, the adv_data_update_timer_cb() callback function will be called. In the context of the latter, the timer is restarted in order for the advertising data to get updated every 30 seconds.

4.1.6. BLE Stack Message Handling at Application Level

BLE stack messages that are destined to the application layer are normally handled in the application layer of the SDK, either by app_task.c or by the respective app_<module>_task.c module task.

The following code snippet shows an example of the messages that are handled in the application layer by the app_task.c module. These messages are destined from the BLE stack to the application layer.

static const struct ke_msg_handler app_gap_process_handlers[]=
{
{GAPM_DEVICE_READY_IND,                 (ke_msg_func_t)gapm_device_ready_ind_handler},
{GAPM_CMP_EVT,                          (ke_msg_func_t)gapm_cmp_evt_handler},
{GAPC_CMP_EVT,                          (ke_msg_func_t)gapc_cmp_evt_handler},
{GAPC_CONNECTION_REQ_IND,               (ke_msg_func_t)gapc_connection_req_ind_handler},
{GAPC_DISCONNECT_IND,                   (ke_msg_func_t)gapc_disconnect_ind_handler},
{GAPC_GET_DEV_INFO_REQ_IND,             (ke_msg_func_t)gapc_get_dev_info_req_ind_handler},
{GAPC_SET_DEV_INFO_REQ_IND,             (ke_msg_func_t)gapc_set_dev_info_req_ind_handler},
{GAPM_PROFILE_ADDED_IND,                (ke_msg_func_t)gapm_profile_added_ind_handler},
{GAPM_ADV_REPORT_IND,                   (ke_msg_func_t)gapm_adv_report_ind_handler},
{GAPC_PARAM_UPDATE_REQ_IND,             (ke_msg_func_t)gapc_param_update_req_ind_handler},
{GAPC_LE_PKT_SIZE_IND,                  (ke_msg_func_t)gapc_le_pkt_size_ind_handler},
{GATTC_SVC_CHANGED_CFG_IND,             (ke_msg_func_t)gattc_svc_changed_cfg_ind_handler},
{GAPC_PEER_FEATURES_IND,                (ke_msg_func_t)gapc_peer_features_ind_handler},

#if (BLE_APP_SEC)
{GAPC_SECURITY_IND,                     (ke_msg_func_t)gapc_security_ind_handler},
#endif
};

The following code snippet shows the messages that are destined to the application layer of the BASS profile. These messages are handled in the app_bass_task.c file.

static const struct ke_msg_handler app_bass_process_handlers[] =
{
{BASS_ENABLE_RSP,                       (ke_msg_func_t)bass_enable_rsp_handler},
{BASS_BATT_LEVEL_UPD_RSP,               (ke_msg_func_t)bass_batt_level_upd_rsp_handler},
{BASS_BATT_LEVEL_NTF_CFG_IND,           (ke_msg_func_t)bass_batt_level_ntf_cfg_ind_handler},
{APP_BASS_TIMER,                        (ke_msg_func_t)app_bass_timer_handler},
{APP_BASS_ALERT_TIMER,                  (ke_msg_func_t)app_bass_alert_timer_handler},
};

If a BLE stack message is not handled in the application layer of the SDK (app_task.c or app_<module>_task.c), it may be handled at user level instead. This is possible via a message-forwarding mechanism called in the SDK as catch rest handling.

With reference to ble_app_peripheral as an example, we will proceed to outline how to enable and use this mechanism:

  • A handler function shall be added at user level. This function may process any messages forwarded by the application layer (it is up to the user to determine which of the forwarded messages will be processed at user level. For details, see the user_catch_rest_hndl() function implementation in user_peripheral.c).

  • In order to facilitate the message-forwarding mechanism, app_process_catch_rest_cb shall be defined in user_callback_config.h (see #define app_process_catch_rest_cb       user_catch_rest_hndl in BLE example ble_app_peripheral).

4.1.7. BLE Event Callbacks

BLE events may be handled at user level through callback functions. For instance, user_app_connection() is the callback function that will be conditionally called upon receiving the GAPC_CONNECTION_REQ_IND event from the BLE stack (see app_task.c for details).

The ble_app_barebone example registers the following callback functions:

static const struct app_callbacks user_app_callbacks = {
    .app_on_connection                  = user_app_connection,
    .app_on_disconnect                  = user_app_disconnect,
    .app_on_update_params_rejected      = NULL,
    .app_on_update_params_complete      = NULL,
    .app_on_set_dev_config_complete     = default_app_on_set_dev_config_complete,
    .app_on_adv_nonconn_complete        = NULL,
    .app_on_adv_undirect_complete       = user_app_adv_undirect_complete,
    .app_on_adv_direct_complete         = NULL,
    .app_on_db_init_complete            = default_app_on_db_init_complete,
    .app_on_scanning_completed          = NULL,
    .app_on_adv_report_ind              = NULL,
    .app_on_get_dev_name                = default_app_on_get_dev_name,
    .app_on_get_dev_appearance          = default_app_on_get_dev_appearance,
    .app_on_get_dev_slv_pref_params     = default_app_on_get_dev_slv_pref_params,
    .app_on_set_dev_info                = default_app_on_set_dev_info,
    .app_on_data_length_change          = NULL,
    .app_on_update_params_request       = default_app_update_params_request,
    .app_on_generate_static_random_addr = default_app_generate_static_random_addr,
    .app_on_svc_changed_cfg_ind         = NULL,
    .app_on_get_peer_features           = NULL,
#if (BLE_APP_SEC)
    .app_on_pairing_request             = NULL,
    .app_on_tk_exch                     = NULL,
    .app_on_irk_exch                    = NULL,
    .app_on_csrk_exch                   = NULL,
    .app_on_ltk_exch                    = NULL,
    .app_on_pairing_succeeded           = NULL,
    .app_on_encrypt_ind                 = NULL,
    .app_on_encrypt_req_ind             = NULL,
    .app_on_security_req_ind            = NULL,
    .app_on_addr_solved_ind             = NULL,
    .app_on_addr_resolve_failed         = NULL,
#if !defined (__DA14531_01__) && !defined (__DA14535__)
    .app_on_ral_cmp_evt                 = NULL,
    .app_on_ral_size_ind                = NULL,
    .app_on_ral_addr_ind                = NULL,
#endif // not for DA14531-01, DA14535
#endif // (BLE_APP_SEC)
};

The above structure defines that a certain event will be processed:

  • by a default handler or

  • by a user-defined handler or

  • it will not be processed at all (NULL entries)

The user-defined handlers of the ble_app_barebone example (for example user_app_connection(), user_app_disconnect(), user_app_adv_undirect_complete(), etc.) are defined in C source file user_barebone.c.

As an example, the user_app_adv_undirect_complete() callback will be called when the undirect connectable advertising is completed.

The following code snippet from app_task.c shows how the user_app_adv_undirect_complete() callback will be called:

// Undirected connectable advertising finished
case GAPM_ADV_UNDIRECT:
{
    CALLBACK_ARGS_1(user_app_callbacks.app_on_adv_undirect_complete, param->status)
}
break;

4.1.8. Connection/Disconnection to/from Peer Device

Connection to a peer device is essentially a BLE event. The same goes for disconnection from a peer device. Our BLE example applications demonstrate connection/disconnection handling at user level.

As an example, see the user_app_connection() callback function in ble_app_barebone. When a connection to a peer device is made, the aforementioned function will be called through the corresponding entry of the user_app_callbacks callback structure (defined in file user_callback_config.h).

Similarly, the user_app_disconnect() callback function will be called when disconnected from a peer device.

The user application code flow in ble_app_barebone is shown in the following figure:

../_images/barebone_user_app_code_flow.png

Figure 36 User Application Code Flow in ble_app_barebone

4.1.9. Connection Parameter Update via L2CAP

When a connection is made to a peer device, connection parameters may be updated as needed. To this end, the app_easy_gap_param_update_start() API function is called.

Our BLE example applications show how a connection parameter update may be initiated at user level. As an example, in ble_app_barebone, upon connecting to a peer device, an application timer is conditionally added (if the parameters of the established connection are not the preferred ones; see for details the user_app_connection() function). If the timer is added, a connection parameter update will start through the param_update_request_timer_cb() callback function (as soon as the timer expires, i.e. in 10 seconds).

The following code snippet from user_config.h shows the parameter update configuration for a BLE connection of the ble_app_barebone example application:

static const struct connection_param_configuration user_connection_param_conf = {
    /// Connection interval minimum measured in ble double slots (1.25ms)
    /// use the macro MS_TO_DOUBLESLOTS to convert from milliseconds (ms) to double slots
    .intv_min = MS_TO_DOUBLESLOTS(10),

    /// Connection interval maximum measured in ble double slots (1.25ms)
    /// use the macro MS_TO_DOUBLESLOTS to convert from milliseconds (ms) to double slots
    .intv_max = MS_TO_DOUBLESLOTS(20),

    /// Latency measured in connection events
    .latency = 0,

    /// Supervision timeout measured in timer units (10 ms)
    /// use the macro MS_TO_TIMERUNITS to convert from milliseconds (ms) to timer units
    .time_out = MS_TO_TIMERUNITS(1250),

    /// Minimum Connection Event Duration measured in ble double slots (1.25ms)
    /// use the macro MS_TO_DOUBLESLOTS to convert from milliseconds (ms) to double slots
    .ce_len_min = MS_TO_DOUBLESLOTS(0),

    /// Maximum Connection Event Duration measured in ble double slots (1.25ms)
    /// use the macro MS_TO_DOUBLESLOTS to convert from milliseconds (ms) to double slots
    .ce_len_max = MS_TO_DOUBLESLOTS(0),
};

4.1.10. LE Data Packet Length Extension

The app_easy_gap_set_data_packet_length() API function may be called to set the maximum data packet length. The maximum length that is supported is 251 octets. See also CFG_MAX_TX_PACKET_LENGTH in the da14531x_config_advanced.h file as an example of any of our BLE example applications.

It should be highlighted that the app_easy_gap_get_peer_features() API function is called before app_easy_gap_set_data_packet_length() is called, in order to determine whether a peer device supports LE Data Packet Length Extension as well.

Note

For the production test firmware, the maximum length being supported – for the test TX/RX data packets, i.e. when CFG_PRODUCTION_TEST is defined in the prod_test example (see the MAX_PAYLOAD_LENGTH_BY_SPEC and MIN_PAYLOAD_LENGTH_BY_SPEC definitions – when CFG_PRODUCTION_TEST is defined – in da1458x_scatter_config.h) – is 255 octets. In the prod_test example, CFG_PRODUCTION_TEST is defined by default.

4.1.11. Bluetooth Profiles

4.1.11.1. Bluetooth SIG Profiles

The BLE example applications show how to enable Bluetooth SIG GATT-based profiles at user level, through appropriate definitions in user_modules_config.h and user_profiles_config.h, and to add the respective source files to the project.

As an example, we will proceed to outline how PROXR is enabled in the prox_reporter example:

  • In user_modules_config.h, #define EXCLUDE_DLG_PROXR(0) has been defined

  • In user_profiles_config.h, #define CFG_PRF_PXPR has been defined

  • The following source files have been added to the project:

    • proxr.c and proxr_task.c comprise the PROXR profile implementation and are available in <sdk_root_directory>\sdk\ble_stack\profiles\prox\proxr\src,

    • app_proxr.c and app_proxr_task.c are the implementation of the SDK application layer of PROXR and are available in <sdk_root_directory>\sdk\app_modules\src\app_proxr. Essentially, the app_proxr.c holds the API functions, which the user can call in his application and app_proxr_task.c holds the function handlers of the messages which are destined to PROXR task.

The SDK supports the following Bluetooth SIG profiles/services (see Table 4 for details):

  • Proximity Profile (Monitor role)

  • Proximity Profile (Reporter role)

  • Find Me Profile (Locator role)

  • Find Me Profile (Target role)

  • Health Thermometer Profile (Collector role)

  • Health Thermometer Profile (Thermometer role)

  • Device Information Service (Client role)

  • Device Information Service (Server role)

  • Blood Pressure Profile (Collector role)

  • Blood Pressure Profile (Sensor role)

  • Time Profile (Client role)

  • Time Profile (Server role)

  • Heart Rate Profile (Collector role)

  • Heart Rate Profile (Sensor role)

  • Scan Parameter Profile (Client role)

  • Scan Parameter Profile (Server role)

  • Battery Service (Client role)

  • Battery Service (Server role)

  • HID (Device role)

  • HID Boot (Host role)

  • HID Report (Host role)

  • Glucose Profile (Collector role)

  • Glucose Profile (Sensor role)

  • Running Speed and Cadence Profile (Collector role)

  • Running Speed and Cadence Profile (Server role)

  • Cycling Speed and Cadence Profile (Collector role)

  • Cycling Speed and Cadence Profile (Server role)

  • Cycling Power Profile (Collector role)

  • Cycling Power Profile (Server role)

  • Location and Navigation Profile (Collector role)

  • Location and Navigation Profile (Server role)

  • Alert Notification Profile (Client role)

  • Alert Notification Profile (Server role)

  • Phone Alert Status Profile (Client role)

  • Phone Alert Status Profile (Server role)

  • Bond Management Service (Client role)

  • Bond Management Service (Server role)

  • Apple Notification Center Service (Client role)

  • Body Composition Service (Client role)

  • Body Composition Service (Server role)

  • Weight Scale Service (Client role)

  • Weight Scale Service (Server role)

  • User Data Service (Client role)

  • User Data Service (Server role)

  • Generic Attribute Profile Service (Client role)

4.1.11.2. Custom Profile – GATT Server Role

The SDK provides two custom profiles (Server role) identical to each other, namely CUSTS1 and CUSTS2. CUSTS1 and CUSTS2 APIs and corresponding implementations are in directory <sdk_root_directory>\sdk\ble_stack\profiles\custom. CUSTS1- and CUSTS2-related APIs and implementations in the application layer of the SDK are respectively in directory <sdk_root_directory>\sdk\app_modules\api (app_customs.h and app_customs_task.h files) and <sdk_root_directory>\sdk\app_modules\src\app_custs.

Two of our BLE example applications, namely ble_app_profile and ble_app_peripheral, show how you can add, enable and deal with a custom profile at user level that consists of three services. ble_app_profile demonstrates how to add a custom profile (user-defined 128-bit UUIDs for its services and their characteristics) as well as how to create its database. ble_app_peripheral builds upon ble_app_profile and demonstrates how to add some basic functionality at user level with respect to the custom profile. In the remainder of this section, we will focus on the ble_app_peripheral example application.

user_custs_config.c, user_custs1_def.c, user_custs1_impl.c and user_peripheral.c make up the custom-profile-related logic at user level:

  • user_custs_config.c: defines the custom profile callback function table (cust_prf_funcs[] array) that consists of the database creation function, i.e. app_custs1_create_db(), which is called at the application layer of the SDK

  • user_custs1_def.c: contains the custom profile database description, essentially the attributes of the three services

  • user_custs1_impl.c: defines user-logic handlers that will be called accordingly upon attribute access

  • user_peripheral.c: contains the user_catch_rest_hndl() handler function that calls any of the handlers defined in user_custs1_impl.c, depending on the case (see Section 4.1.6 for more information on user_catch_rest_hndl())

4.1.11.3. SUOTA Receiver Profile

A SUOTAR profile allows for Software Updates Over The Air that is initiated by a peer device. It consists of the SUOTAR service whose UUID has been assigned by the Bluetooth SIG (0xFEF5).

ble_app_ota is one of our BLE example applications that show how to add, enable and use the SUOTAR profile. SUOTAR is enabled similar to DISS (see Section 4.1.11.1). The following source files are added to the project:

  • suotar.c and suotar_task.c are the SUOTAR profile implementation and are available in directory <sdk_root_directory>\sdk\ble_stack\profiles\suota\suotar\src

  • app_suotar.c and app_suotar_task.c are the implementation of the SDK application layer of SUOTAR and available in directory <sdk_root_directory>\sdk\app_modules\src\app_suotar

4.1.11.4. GATT-Client-Role Profile – ANCS Client

ANCS Client is a BLE example application that demonstrates how to add, enable and use a GATT-Client-role profile. The application is available in directory <sdk_root_directory>\projects\target_apps\misc\ancs_client.

  • In user_profiles_config.h:
    • GATT and ANCS Clients are enabled if CFG_PRF_GATTC and CFG_PRF_ANCC are defined respectively,

    • ANCS-related configuration has been added:
      • ANC_CFG_DROP_PREEXISTING_NTF is enabled by default

      • CFG_VERBOSE_LOG is disabled by default

  • The following source files are added to the project:
    • ancc.c and ancc_task.c are in <sdk_root_directory>\sdk\ble_stack\profiles\anc\ancc\src

    • gatt_client.c and gatt_client_task.c are in <sdk_root_directory>\sdk\ble_stack\profiles\gatt\gatt_client\src

    • app_ancc.c and app_ancc_task.c are in <sdk_root_directory>\sdk\app_modules\src\app_ancc

    • app_gattc.c and app_gattc_task.c are in <sdk_root_directory>\sdk\app_modules\src\app_gattc

Note

ANCS stands for Apple Notification Center Service. ANCS is meant for Apple devices only.

4.1.12. Security

To add security functionality to a BLE application, define CFG_APP_SECURITY. Several security schemes are supported, including LE Legacy Pairing, LE Secure Connections and Link Layer Privacy.

ble_app_security is one of our BLE example applications that demonstrate security capabilities:

  • CFG_APP_SECURITY is defined in da1458x_config_basic.h

  • The following security-related source files are added to the project: app_security.c and app_security_task.c, both are in <sdk_root_directory>\sdk\app_modules\src\app_sec

  • Security functionality may be configured at user level according to the user’s needs (see for details the user_config.h file as well as Section 4.1.12.1 and Section 4.1.12.2 below)

4.1.12.1. Security Configuration at User Level

BLE security may be configured at user level through the available options in the respective user_config.h file:

  • I/O capabilities of the device

  • Out-of-Band (OOB) data support

  • Authentication requirements

  • Encryption key size

  • Minimum allowed security level (security requirements)

  • Key distribution capabilities

  • Depending on the user security configuration and the security capabilities of the peer device, one of the following pairing methods may occur:

    • Legacy Pairing – OOB

    • Legacy Pairing – Just Works

    • Legacy Pairing – Passkey Entry

    • Secure Connection – Just Works

    • Secure Connection – Passkey Entry

    • Secure Connection – Numeric Comparison

  • If none of the above-mentioned methods is used, security features will be set to the minimum security capabilities.

  • Bond data related to the peer device may be stored to an external SPI Flash or I2C EEPROM memory:

    • #define USER_CFG_APP_BOND_DB_USE_SPI_FLASH for SPI Flash (default)

    • #define USER_CFG_APP_BOND_DB_USE_I2C_EEPROM for I2C EEPROM

    • If neither of the above flags is defined the bond data will be only cached in the application RAM.

    • #define USER_CFG_BOND_DB_MAX_BONDED_PEERS defines the number of maximum bond data slots in database

user_config.h allows also to select the addressing mode and privacy capabilities of the peripheral device if USER_CFG_ADDRESS_MODE is defined with one of the following options:

  • APP_CFG_ADDR_PUB:

    • The peripheral device is non-private and operates with Public Address. Although it does not claim privacy support, it can resolve the Random Resolvable Private Address (RPA) of a bonded peer in its BLE host layer.

    • The Public Address of the device shall be set with the CFG_NVDS_TAG_BD_ADDRESS flag in the respective da1458x_config_advanced.h file. This address does not change upon power-cycle.

  • APP_CFG_ADDR_STATIC:

    • The peripheral device is non-private and operates with a Random Static Address (RSA). Although it does not claim privacy support, it can resolve the RPA of a bonded peer in its BLE host layer.

    • There are three options to configure the RSA:

      • If user_gapm_conf.addr_type is set to a valid RSA, then this RSA will be used. This address does not change upon power-cycle.

      • If user_gapm_conf.addr_type is not valid and default_app_generate_static_random_addr is connected to app_on_generate_static_random_addr in the respective user_callback_config.h file, then a new RSA will be generated at each power-cycle.

      • If user_gapm_conf.addr_type is not valid and default_app_generate_unique_static_random_addr is connected to app_on_generate_static_random_addr in the respective user_callback_config.h file, then a unique device RSA will be generated based on information stored in the OTP header. This address does not change upon power-cycle.

  • APP_CFG_HOST_PRIV_RPA:

    • The peripheral device is a private one and operates with an RPA generated in its BLE host layer. The RPA of a bonded peer can also be resolved in its BLE host layer.

    • Identity information: The device shall exchange its identity information during the pairing procedure.

      • A valid IRK shall be set in user_gapm_conf.irk and GAP_KDIST_IDKEY shall be enabled in USER_CFG_FEAT_RESP_KDIST.

      • The device will always send its Public Address defined in CFG_NVDS_TAG_BD_ADDRESS as identity address.

      • Renew duration: The interval of generating a new RPA shall be set in user_gapm_conf.renew_dur. This field controls the duration of the RPA before it gets regenerated and is counted in units of 10 ms. The minimum valid value for renew_dur is 15000 (150 s). If the value of renew_dur is set to less than 15000, then the BLE stack will automatically set the value to 15000.

  • APP_CFG_HOST_PRIV_NRPA:

    • The device is a private one and operates with a non-RPA generated in its BLE host layer. This configuration can only be used in non-connectable modes/procedures (e.g. broadcaster role, non-connectable advertising).

  • APP_CFG_CNTL_PRIV_RPA_PUB:

    • The peripheral device is a private one and operates with an RPA generated in its BLE controller layer. When the device is bonded with a peer, then the device information of the peer will be stored in the resolving list located in the BLE controller layer. Upon re-connection, the RPA of the bonded peer will be automatically resolved in the BLE controller layer and its identity will be directly used in the application layer of the peripheral device. If the resolving list of the peripheral is empty (no bonded devices), then it will operate with a Public Address.

    • Identity information: The device shall exchange its identity information during pairing procedure.

      • A valid IRK shall be set in user_gapm_conf.irk and GAP_KDIST_IDKEY shall be enabled in USER_CFG_FEAT_RESP_KDIST.

      • The device will always send its Public Address defined in CFG_NVDS_TAG_BD_ADDRESS as identity address.

      • Renew duration: The interval of generating a new RPA shall be set in user_gapm_conf.renew_dur. This field controls the duration of RPA before it gets regenerated and is counted in units of 10 ms. The minimum valid value for renew_dur is 15000 (150 s). If the value of renew_dur is set to less than 15000, then BLE stack will automatically set the value to 15000.

  • APP_CFG_CNTL_PRIV_RPA_RAND:

    • The peripheral device is a private one and operates with an RPA generated in its BLE controller layer. When the device is bonded with a peer, then the device information of the peer will be stored in the resolving list located in the BLE controller layer. Upon re-connection, the RPA of the bonded peer will be automatically resolved in the BLE controller layer and its identity will be directly used in the application layer of the peripheral device. The peripheral will operate with RPA independently to the existence of bonded peers.

    • Identity information: The device shall exchange its identity information during pairing procedure.

      • A valid IRK shall be set in user_gapm_conf.irk and GAP_KDIST_IDKEY shall be enabled in USER_CFG_FEAT_RESP_KDIST.

      • The device will always send its Public Address defined in CFG_NVDS_TAG_BD_ADDRESS as identity address.

      • Renew duration: The interval of generating a new RPA shall be set in user_gapm_conf.renew_dur. This field controls the duration of RPA before it gets regenerated and is counted in units of 10 ms. The minimum valid value for renew_dur is 15000 (150 s). If the value of renew_dur is set to less than 15000 then BLE stack will automatically set the value to 15000.

  • Controller privacy mode is set with USER_CFG_CNTL_PRIV_MODE and can have one of the following values:

  • APP_CFG_CNTL_PRIV_MODE_NETWORK: Peripheral device will only accept advertising packets from bonded peer devices that operate with RPA.

  • APP_CFG_CNTL_PRIV_MODE_DEVICE: Peripheral device will accept advertising packets from bonded peer devices that operate with both RPA and non-private addresses (Public, Random Static).

Besides the aforementioned configuration, callback functions may be provided at user level, through user_callback_config.h, in order to handle certain security-related events or operations, as discussed in the section below.

4.1.12.2. Security Event Handling

Several events can occur during the lifetime of the Bluetooth low energy application and these events need to be handled in a specific manner. The application is responsible to select which events and operations it should handle and which it should just leave to be handled with the default SDK behavior.

The SDK uses a mechanism that registers callbacks for every event or operation that defines the system behavior. The C header file user_callback_config.h, which is part of the user application contains the registration of callback functions.

In ble_app_security, the following security-related callback functions are present (derived from the respective user_callback_config.h file):

#if (BLE_APP_SEC)

.app_on_pairing_request = default_app_on_pairing_request,

.app_on_tk_exch = user_app_on_tk_exch,

.app_on_irk_exch = NULL,

.app_on_csrk_exch = default_app_on_csrk_exch,

.app_on_ltk_exch = default_app_on_ltk_exch,

.app_on_pairing_succeeded = default_app_on_pairing_succeeded,

.app_on_encrypt_ind = NULL,

.app_on_encrypt_req_ind = default_app_on_encrypt_req_ind,

.app_on_security_req_ind = NULL,

.app_on_addr_solved_ind = default_app_on_addr_solved_ind,

.app_on_addr_resolve_failed = default_app_on_addr_resolve_failed,

#if !defined (__DA14531_01__) && !defined (__DA14535__)

.app_on_ral_cmp_evt = default_app_on_ral_cmp_evt,

.app_on_ral_size_ind = NULL,

.app_on_ral_addr_ind = NULL,

#endif // not for DA14531-01, DA14535

#endif // (BLE_APP_SEC)

Note

The above-mentioned callback functions will be conditionally called, for instance when BLE_APP_SEC is set to 1 (which is automatically done when CFG_APP_SECURITY is defined in da1458x_config_basic.h).

Note

The default configuration of the project uses UART to display the Temporary Keys in case of Passkey Entry and Numeric Comparison pairing methods:

  • However, if CFG_PRINTF is undefined or default_app_on_tk_exch is used, then the Passkey will have a default value of “123456”.

  • In each case of Numeric Comparison, the confirmation value will be automatically accepted, since a keyboard or Yes/No buttons are not implemented in the specific example.

  • In case of Secure Connections, the LTK will also be printed in UART, so that it can be used with debugging/sniffing tools.

When a peer device uses a resolvable private address that needs to be resolved by the peripheral, then app_easy_security_resolve_bdaddr() can be called. app_easy_security_resolve_bdaddr() sends the stored IRKs in the BLE stack, which tries to find the IRK that resolves the BD address of the peer. If address resolution is successful, then the host application will receive an .app_on_addr_solved_ind event. If the operation fails, an .app_on_addr_resolve_failed event will be received.

Specific events for the bond database are handled through the callback functions below:

static const struct app_bond_db_callbacks user_app_bond_db_callbacks = {

.app_bdb_init = default_app_bdb_init,

.app_bdb_get_size = default_app_bdb_get_size,

.app_bdb_add_entry = default_app_bdb_add_entry,

.app_bdb_remove_entry = NULL,

.app_bdb_search_entry = default_app_bdb_search_entry,

.app_bdb_get_stored_irks = default_app_bdb_get_stored_irks,

};

The above-mentioned structure defines that a certain event will be processed by a default handler or by a user-defined handler or it will not be processed at all (NULL entries). By default a bond database is implemented in app_bond_db.c. However, a user implementation of the bond database can be hooked to the callback table above. The default implementation of the bond database:

  • Has a default number of five bond data slots.

  • In each valid slot, depending on the bonding procedure, the bond database stores the keys (LTKs – including EDIV and RandNB, remote IRK – including peer’s identity, CSRKs), the peer’s BD address and a set of flags.

  • When bond data is added for a peer device the algorithm that stores the bond data checks if an older entry exists for that peer in the bond DB. If yes, the old entry is updated, otherwise an empty slot is used. If there is no empty slot in the database, then the oldest added slot is replaced.

  • Bond data of known peer devices can be searched and/or removed using different types (by slot, by EDIV, by BD address, by IRK, etc.)

  • app_bdb_get_stored_irks can be used to get all the stored IRKs in the database. This is useful when the peer has a random private resolvable address, which needs to be resolved.

The code flow in ble_app_security for the user application is shown in Figure 37 and Figure 38:

../_images/security_user_app_code_flow_pairing.png

Figure 37 User Application Code Flow in ble_app_security – Pairing Procedure

../_images/security_user_app_code_flow_encryption.png

Figure 38 User Application Code Flow in ble_app_security – Encryption

4.1.13. Whitelist support for Peripheral mode

This feature provides limited functionality on Link Layer privacy by enabling the application to add devices to Whitelist while operating in Peripheral role. It facilitates the device to allow connection only from the peer (remote) device that is listed in the Whitelist. The feature works when the peer (remote) device uses Public address, Static Random and Resolvable Private device address. The SDK provides API for the Whitelist managment:

  • app_easy_whitelist.c, holds the API function which can be called by the

    user in his application in order to manage Whitelist.

The following code snippet from app_easy_whitelist.h shows the supported operations for White List feature:

/// Whitelist operation type
typedef enum
{
    /// Get White List Size.
    APP_WLIST_OP_GET_SIZE           = GAPM_GET_WLIST_SIZE,

    /// Add devices in white list.
    APP_WLIST_OP_ADD_DEV            = GAPM_ADD_DEV_IN_WLIST,

    /// Remove devices form white list.
    APP_WLIST_OP_RMV_DEV            = GAPM_RMV_DEV_FRM_WLIST,

    /// Clear all devices from white list.
    APP_WLIST_OP_CLEAR              = GAPM_CLEAR_WLIST,
} app_wlist_op_t;

Note

Detailed information about Whitelist API can be found in API documentation.

4.1.13.1. How to use Whitelist as a Peripheral

The ADV_ALLOW_SCAN_ANY_CON_WLST advertising policy must be selected when the Peripheral device requires the use of the Whiltelist. Using the selected policy, the Peripheral device will allow connection requests ONLY from the whitelisted peer devices.

/// Advertising filter policy:
/// - ADV_ALLOW_SCAN_ANY_CON_ANY: Allow both scan and connection requests from anyone
/// - ADV_ALLOW_SCAN_ANY_CON_WLST: Allow both scan req from anyone and connection req from
///                                White List devices only
.adv_filt_policy = ADV_ALLOW_SCAN_ANY_CON_WLST,

The following Whitelist Management operations are supported by the API:

Add a peer device address to Whitelist
app_easy_manage_wlist(APP_WLIST_OP_ADD_DEV, struct bd_addr addr, app_wlist_addr_t type)
Remove a peer device address from Whitelist
app_easy_manage_wlist(APP_WLIST_OP_RMV_DEV, struct bd_addr addr, app_wlist_addr_t type)
Clear all peer device addresses from Whitelist
app_easy_manage_wlist(APP_WLIST_OP_CLEAR, struct bd_addr addr, app_wlist_addr_t type)
Get the Whitelist size
app_easy_manage_wlist(APP_WLIST_OP_GET_SIZE, struct bd_addr addr, app_wlist_addr_t type)

Note

The type of the peer address must be either public or random.

/// Whitelist address type
typedef enum
{
   /// Public address
   APP_WLIST_ADDR_PUBLIC            = ADDR_PUBLIC,

   /// Random address
   APP_WLIST_ADDR_RANDOM            = ADDR_RAND,

} app_wlist_addr_t;

Note

The GAPM Command Complete events messages of the aforementioned Whitelist Management operations are not handled in the application layer of the SDK. They can be handled in the user application level using the catch rest mechanism (see Section 4.1.6 for further information on user_catch_rest_hndl()).

4.2. System Features

4.2.1. Bluetooth Hardware Configurations

The basic layers of the Bluetooth protocol stack are:

Application

The user application that interfaces with the Bluetooth protocol stack.

Host

The upper layers of the Bluetooth protocol stack.

Controller

The lower layers of the Bluetooth protocol stack, including the radio.

The above layers are implemented by the SDK in hardware in 3 different setups:

  • integrated processor

  • external processor

  • hci

The 3 different hardware configurations are depicted in Figure 39.

../_images/ble-hw-conf.png

Figure 39 BLE Hardware Configurations

Note

The GTL is a proprietary interface for Application-Host communication over a serial interface (like UART, SPI, I2C).

The SDK6.0.22 incorporates essential files facilitating booting of the DA1453x from an external Renesas microcontroller via UART interface. The required files, namely fsp_ext_task.c/.h and fsp_ext_sdk_version.h, are located within the directory: sdk\platform\utilities\fsp. The following APIs have been implemented:

  • APP_GET_FW_VERSION

This is an API message to request the firmware version and subversion as well as custom firmware-related data from DA14585/531.

../_images/APP_GET_FW_VERSION.jpg

Figure 40 APP_GET_FW_VERSION Symbolic Message Structure

../_images/APP_GET_FW_VERSION_EXPLE.jpg

Figure 41 APP_GET_FW_VERSION Example

  • APP_FW_VERSION_IND

This is the response to APP_GET_FW_VERSION that includes the DA14585/531 firmware version. The response is relative to the information stored at sdk/platform/utilities/fsp/fsp_ext_sdk_version.h file.

../_images/FW_VERSION_IND_responce.jpg

Figure 42 APP_FW_VERSION_IND Symbolic Message Structure

The fsp_ext_sdk_version.h file has following definitions as default:

#define SDK_MAJOR_VERSION    6
#define SDK_MINOR_VERSION    0
#define SDK_PATCH_VERSION    22
#define SDK_BUILD_NUMBER     1401
#define SDK_BUILD_EXTENSION  0
  • SET_TX_PWR_CMD

This is an API message to set the Tx power level of the DA14585/531.

../_images/set_tx_pwr.jpg

Figure 43 SET_TX_PWR_CMD Symbolic Message Structure

../_images/set_tx_pwr_cmd.jpg

Figure 44 SET_TX_PWR_CMD Example

  • SET_TX_PWR_CMP_EVT

Following the completion of the Tx power level procedure, DA14531 sends a completion event message (SET_TX_PWR_CMP_EVT) of SET_TX_PWR_CMD.

../_images/set_tx_pwr_cmp_evt.jpg

Figure 45 SET_TX_PWR_CMP_EVT Example

  • GET_TX_PWR_CMD

This is an API message to get the Tx power level of the DA14585/531.

../_images/GET_TX_PWR_CMD.jpg

Figure 46 GET_TX_PWR_CMD Symbolic Message Structure

../_images/get_tx_pwr.jpg

Figure 47 GET_TX_PWR_CMD Example

  • GET_TX_PWR_RSP

Following the completion of GET_TX_PWR_CMD, DA14531 sends a response to this message carrying the value saved in retained memory block. The return value is an enumerator that defines the transmit output power level from -19.5 dBm up to +2.5 dBm according to rf_tx_pwr_lvl_t.

../_images/GET_TX_PWR_RSP.jpg

Figure 48 GET_TX_PWR_RSP Symbolic Message Structure

../_images/GET_TX_PWR_RSP_EXP.jpg

Figure 49 GET_TX_PWR_RSP Example

Important

The GTL binary image, transferred from the Renesas MCU to the DA1453x, is generated from the FSP Attach Target Firmware projects found on the SDK6 GitHub repository.

When compiling with the FSP to enable DA1453x devices to boot from a host Renesas microcontroller, the GTL binary is situated at the following location: ra/renesas/wireless/da14xxx/r_ble_gtl/r_ble_gtl_image.c.

For detailed instructions, please refer to the Getting started with DA1453x and FSP BLE Framework on Renesas Microcontrollers. For details about the the middleware for the Bluetooth peripheral on RA MCUs you can refer to the FSP documentation.

The following SDK BLE examples run on the integrated processor hardware configuration:

  • ble_app_barebone

  • ble_app_profile

  • ble_app_peripheral

  • ble_app_security

  • ble_app_sleepmode

  • ble_app_ota

  • ble_app_all_in_one

  • prox_reporter

  • ble_app_noncon

  • aes

  • ancs_client

  • ble_app_lecb

  • empty_peripheral_template

The following SDK BLE examples run on the external processor hardware configuration:

  • prox_monitor_ext

  • prox_reporter_ext

  • empty_template_ext

The following SDK BLE examples run on the hci hardware configuration:

  • hci

  • prod_test

4.2.2. Sleep Modes

4.2.2.1. DA1458x

The following sleep modes are supported:

  • Extended sleep without OTP copy on wake-up: Application code and data are stored in RAM. After wake up there is no OTP mirroring and no boot from SPI / I2C / UART.

    • RAM blocks which include code will be retained.

    • RAM blocks which include retention data will be retained.

    • RAM block 4 is always retained (it holds various ROM data variables).

  • Extended sleep with OTP copy on wake-up: Application code is stored in OTP. After waking up, OTP mirroring will take place.

    • RAM blocks which include code will NOT be retained.

    • RAM blocks which include retention data will be retained.

    • RAM block 4 is always retained (it holds various ROM data variables).

Note

The SDK makes the assumption that the code is comprised of the RO code and data, plus the RW data which are non-zero initialized. Take for example the following excerpt from a Keil project map file:

.......

0x07fc4230   0x07fc4230   0x00000008   Data   RO         2778    .constdata          app_diss_task.o
0x07fc4238   0x07fc4238   0x00000110   Data   RO         2869    .constdata          da14585_586.lib(patch.o)
0x07fc4348   0x07fc4348   0x00000016   Data   RO         2893    .constdata          da14585_586.lib(pll_vcocal_lut.o)
0x07fc435e   0x07fc435e   0x00000002   PAD
0x07fc4360   0x07fc4360   0x00000030   Data   RO         2930    Region$$Table       anon$$obj.o
0x07fc4390   0x07fc4390   0x00000004   Data   RW          650    .data               arch_system.o


Execution Region ER_PRODTEST (Exec base: 0x07fc4398, Load base: 0x07fc4394, Size: 0x00000000, Max: 0xffffffff, ABSOLUTE, UNINIT)

**** No section assigned to this execution region ****


Execution Region ER_ZI (Exec base: 0x07fc4398, Load base: 0x07fc4394, Size: 0x00000648, Max: 0xffffffff, ABSOLUTE)

Exec Addr    Load Addr    Size         Type   Attr      Idx    E Section Name        Object

0x07fc4398        -       0x00000030   Zero   RW         1510    .bss                i2c.o

......

The 0x07fc4390 address, which holds 32-bit RW non-zero initialized data, is considered to be part of the calculated code size, as calculated by the SDK.

Note

The default sleep mode can be defined. Among others, one of the following options can be set (see app_default_sleep_mode in user_config.h):

  • ARCH_SLEEP_OFF: no sleep

  • ARCH_EXT_SLEEP_ON: extended sleep without OTP copy on wake-up

  • ARCH_EXT_SLEEP_OTP_COPY_ON: extended sleep with OTP copy on wake-up

As an example, in ble_app_sleepmode, the system goes to extended sleep with OTP copy on wake-up when in advertising state. It goes to extended sleep without OTP copy on wake-up, when in connected state.

  • The system wakes up synchronously from the BLE timer when in connected or advertising state.

  • The system may wake up asynchronously from a GPIO, which is configured to use the wake-up timer. The asynchronous wake-up is enabled only when the advertising stops after a predefined time (e.g. 30 sec).

  • Deep sleep: Typically, nothing is retained (all RAM blocks are powered off). The system wakes up from the wake-up timer (GPIO) or a Power-On-Reset source and the boot code is invoked. A BLE connection cannot be maintained.

    With reference to the prox_reporter as an example, the system may go to deep sleep, simply by defining CFG_APP_GOTO_DEEP_SLEEP and wake up asynchronously either from the wake-up timer (GPIO), or from a Power-On-Reset pin (see user_proxr.h for details).

Note

Before going to sleep (any of the above-mentioned modes), the system clock changes to low-power clock whose type is determined at user level through the CFG_LP_CLK definition (external XTAL32K oscillator; internal RCX oscillator).

4.2.2.2. DA1453x

The following sleep modes are supported:

  • Extended sleep without OTP copy on wake-up: Application code and data are stored in RAM. After wake up there is no OTP mirroring and no booting from SPI / I2C / UART.

    • RAM blocks that include code will be retained

    • RAM blocks that include retention data will be retained

    • Last RAM block is always retained (it holds the ROM data variables)

  • Extended sleep with OTP copy on wake-up: Application code is stored in OTP. After wake up, OTP mirroring takes place.

    • RAM blocks that include code will NOT be retained

    • RAM blocks that include retention data will be retained

    • Last RAM block is always retained (it holds the ROM data variables)

Note

The default sleep mode can be defined. Among others, the following options can be set (see app_default_sleep_mode in user_config.h):

  • ARCH_SLEEP_OFF: no sleep

  • ARCH_EXT_SLEEP_ON: extended sleep without OTP copy on wake-up

  • ARCH_EXT_SLEEP_OTP_COPY_ON: extended sleep with OTP copy on wake-up

As an example, in ble_app_sleepmode, the system goes to extended sleep with OTP copy on wake-up when in advertising state. The system goes to extended sleep without OTP copy on wake-up, when in connected state.

  • The system wakes up synchronously from the BLE timer when in connected or advertising state.

  • The system wakes up asynchronously from a GPIO if configured to use the wake-up timer. The asynchronous wake-up is enabled only when the advertising stops after a predefined time (e.g. 30 sec).

  • Deep sleep: Typically, nothing is retained (all RAM blocks are powered off). The system wakes up from the wake-up timer (GPIO) or a Power-On-Reset source, and the boot code is invoked. A BLE connection cannot be maintained.

    With reference to prox_reporter as an example, the system may go to deep sleep, simply by defining CFG_APP_GOTO_DEEP_SLEEP and wake up asynchronously from the wake-up timer (GPIO), or from a Power-On-Reset pin, or from an RTC alarm, or from Timer1 (see user_proxr.h for details).

Note

Before going to sleep (any of the above-mentioned modes), system clock will change to low-power clock whose type is determined at user level through the CFG_LP_CLK definition (external XTAL32K oscillator; internal RCX oscillator).

  • Hibernation: Typically, nothing is retained (all RAM blocks are powered off). It should be noted that there are no available clocks, when in hibernation mode. System may wake up from one of the following GPIO pins:

    • P0_1

    • P0_2

    • P0_3

    • P0_4

    • P0_5

    In the context of prox_reporter, the system may enter hibernation mode, by simply defining CFG_APP_GOTO_HIBERNATION (see user_proxr.h for details) – the system will wake up from P0_3 (configurable at user level – see user_periph_setup.h for details).

Note

If SysRAM1 is chosen to be remapped at address 0 for execution after waking up from hibernation, SysRAM1 shall be retained. Similarly, if SysRAM3 is chosen to be remapped at address 0 for execution after waking up from hibernation, SysRAM3 shall be retained.

  • Stateful hibernation: RAM blocks shall be retained according to application memory layout, e.g., using the default linker script, RAM1 and RAM3 blocks shall be always retained and RAM2 block shall be retained only if holding state code and/or data. Similarly as with the hibernation mode above, the system may wake up from one of the following GPIO pins:

    • P0_1

    • P0_2

    • P0_3

    • P0_4

    • P0_5

    In the context of prox_reporter, the system may go to stateful hibernation (with all three RAM blocks being retained), by defining CFG_APP_GOTO_STATEFUL_HIBERNATION (see user_proxr.h for details) as well as CFG_STATEFUL_HIBERNATION (in the project settings – see Section 3.2.5 for details) – the system will wake up from P0_3 (configurable at user level – see user_periph_setup.h for details).

Note

If SysRAM1 is chosen to be remapped at address 0 for execution after waking up from stateful hibernation, SysRAM1 shall be retained. If SysRAM3 is chosen instead to be remapped at address 0 for execution after waking up from stateful hibernation, SysRAM3 shall be retained.

Note

At present, stateful hibernation can only be used in combination with integrated processor HW configurations. Furthermore, the API function letting the device go to stateful hibernation shall not be called while the device being connected to a peer device (as a BLE connection cannot be maintained) and/or there have been prescheduled BLE or timer events.

4.2.3. System library patch control mechanism

The system library patch control mechanism is used in order to fix problematic ROM functions and data using the following methods:

  • the hardware patching mechanism for ROM functions and ROM data.

  • the jump table patching mechanism for ROM functions in the jump table.

  • the custom message handlers patching mechanism for ROM functions message handlers.

For each target device there is a specific source file Figure 50 which contains definitions, local variables, function declarations and the source code of the patch_func() function.

Moreover this source file may contain the following:

  • The source table (patch_orig_table[]) with the ROM functions to be patched and the destination table (patch_new_table[]) with the patched ROM functions, used by the hardware patching mechanism. The patch_func() function enables the hardware patching mechanism when it is called from periph_init() in the system initialization and when the system resumes from sleep.

  • Functions that patch entries in the ROM jump table.

  • Functions that patch ROM function messages handlers and belong to the my_custom_msg_handlers[] table entries.

../_images/system_library_source_file.png

Figure 50 System library source files in the Keil project tree

In the Keil->Option for target->Linker tab there is a path to the library file (*.lib) which contains the s/w patches and accompany every SDK release Figure 51.

../_images/path_to_the_system_library.png

Figure 51 System library path

From SDK-6.0.22 and forth, the user can control at compile time which patches are going to be built in his/her application. The system_library.h controls which patches will be built. The following code snippet shows a paradigm.

#if defined (__DA14535__)

#undef CFG_SKIP_SLAVE_LATENCY
#undef CFG_USE_HEAP_LOG
#undef CFG_USE_DATA_PATCH_1
#undef CFG_USE_DATA_PATCH_2

#elif defined (__DA14531_01__)

#undef CFG_SKIP_SLAVE_LATENCY
#undef CFG_USE_HEAP_LOG
#undef CFG_USE_DATA_PATCH_1
#undef CFG_USE_DATA_PATCH_2

#elif defined (__DA14531__)

#undef CFG_SKIP_SLAVE_LATENCY
#undef CFG_USE_HEAP_LOG
#define CFG_USE_DATA_PATCH_1
#undef CFG_USE_DATA_PATCH_2

#else

#define CFG_START_SMP_TIMEOUT_TIMER_UPON_TX_SEC_REQ_CMD
#undef CFG_SKIP_SLAVE_LATENCY
#undef CFG_USE_HEAP_LOG
#define CFG_USE_DATA_PATCH_1
#undef CFG_USE_DATA_PATCH_2

#endif

Hint

Unused patches will be opted out at compile time to save more RAM for the application.

4.2.4. Data Logging

Data may be logged through the UART interface for debugging purposes (by calling functions of the arch_console.h API, as needed). In the context of our BLE example applications, data logging may be enabled by defining CFG_PRINTF in the respective da1458x_config_basic.h file. Furthermore, if UART2 is to be used for data logging purposes, CFG_PRINTF_UART2 shall be defined as well.

4.2.5. True Random Number Generation (TRNG)

The random number generation is possible, utilizing either of the following methods:

  • The C standard library random function, stdlib\rand.c module, or

  • The third-party ChaCha20 module

For example, The CFG_USE_CHACHA20_RAND flag is defined by default in the da14531_config_advanced.h file, then the ChaCha20 module will be used. If it is undefined, then any random number will be generated by the C standard library.

In order to improve randomness, TRNG feature may be additionally used – a random seed number will be generated that will be subsequently used in order to initialize whichever of the aforementioned two random number generators is to be used. To this end, CFG_TRNG shall be defined in the respective da14531_config_advanced.h file.

4.2.5.1. TRNG in DA1458x

The random seed number is generated by capturing data from the DA1458x radio module. Every time the system_init() function is being called, a new random number seed is generated. The DA1458x TRNG mechanism allocates at maximum 1024 bytes in RAM. The user may decrease the size of this buffer.

Note

CFG_TRNG enables both the TRNG mechanism and selects the TRNG buffer size. It is important to note that a trade-off exists between TRNG buffer size and system start-up latency. As buffer size increases, code size also increases while system start-up latency decreases. On the other hand, small buffer sizes have a negative impact on system start-up latency, but produce smaller code sizes.

4.2.5.2. TRNG in DA1453x

The random seed number is extracted from entropy which is harvested from the power-up noise of a RAM buffer. Per device power-up, a single full entropy 128-bit seed can be generated from an uninitialized RAM buffer of at least 448 bytes.

The TRNG mechanism is triggered every time the RAM3 block was previously off, due to the fact that the uninitialized RAM buffer resides always in RAM3 block.

A simple 32-bit variable check (trng_state_val) is used to define if the RAM3 block was previously off. The trng_state_val is compared to a magic 32-bit value, 0x12348765. If there is no match, the RAM3 block is considered to contain uninitialized data and the TRNG mechanism can run. Otherwise, it is not triggered. Once the TRNG has successfully run, the seed number is fed to either the C standard library random function or the ChaCha20 respective function. Both states of the aforementioned random generators are kept in retention memory area, hence there is no need to re-trigger the TRNG mechanism every time the system_init() function is being called.

Note

Simply defining CFG_TRNG is sufficient to enable the TRNG mechanism.

Note

  • The trng_state_val variable always resides in RAM3 block. Although its start-up value is considered to be random and not equal to the magic 32-bit value, there is a low possibility that this may happen.

  • The trng_state_val variable has been placed on purpose at a fixed memory address, inside the Free area and before the ROM data starting address, 0x07FCB900.

4.2.6. Data Encryption & Decryption

AES-based data encryption/decryption is possible using the Crypto API residing in <sdk_root_directory>\sdk\platform\core_modules\crypto. The Crypto API makes use of the AES-128 Encryption hardware block to accelerate the calculations needed to perform an AES encryption – for decryption, a SW-based algorithm is applied instead. It should be noted that the Crypto API may be used while a BLE connection is ongoing.

Our AES example application, in <sdk_root_directory>\projects\target_apps\misc\aes, shows how the Crypto API can be used for data encryption/decryption at user level.

Last but not least, know that the following AES variants are implemented in the SDK context:

  • AES-CBC

  • AES-CCM

  • AES-CMAC

4.2.7. User Data Storage

Data at user level may be stored with an external memory device, either SPI Flash or I2C EEPROM. The type of data that is considered to be stored includes, but is not limited to, bond data (in case of a BLE security application) and a software image (in case of a SUOTA appication). We support the former and demonstrate that in the context of the ble_app_security example application, the latter is also supported and shown in the context of ble_app_ota.

At user level it is possible to indicate if SPI Flash or I2C EEPROM is used for data storage purposes. Simply provide the right definition in the respective da1458x_config_basic.h file:

  • #define CFG_SPI_FLASH_ENABLE for SPI Flash

  • #define CFG_I2C_EEPROM_ENABLE for I2C EEPROM

4.2.8. Memory Organization

4.2.8.1. DA1458x

DA1458x features the following memory blocks:

  • ROM: A 128-KB ROM contains the BLE protocol stack as well as the boot code sequence

  • OTP: A 64-KB OTP memory, used to store the application code as well as Bluetooth Low Energy profiles. It also contains the system configuration and calibration data. Upon power-up/reset, the primary boot code (ROM) checks whether OTP is programmed. If this is the case, the OTP content will be mirrored to System RAM

  • System RAM: Four RAM blocks, 32 KB + 16 KB + 16 KB + 32 KB = 96 KB in total, used to mirror the program code from either OTP or external Flash when the system powers up as well as to retain data as needed before the system goes to extended sleep. Data retention ensures a secure and quick configuration of the BLE Core after the system wakes up. Every cell can be powered on/off according to the user’s own application needs in terms of retaining data when extended sleep mode is to be used.

4.2.8.2. DA1453x

DA1453x features the following memory blocks:

  • ROM: A 144-KB ROM (DA14531) contains the BLE protocol stack, the boot code sequence and some common SDK code which has been transferred to ROM space (see Section 4.2.12 for details). The DA14535 has 160-KB ROM.

  • OTP: A 32-KB OTP memory (DA14531), used to store the application code as well as Bluetooth Low Energy profiles. It also contains the system configuration and calibration data. Upon power-up/reset, the primary boot code (ROM) checks whether OTP is programmed. If this is the case, the OTP content will be mirrored to System RAM. The DA14535 has 12-KB OTP.

  • System RAM: Three RAM blocks, 16 KB + 12 KB + 20 KB = 48 KB (DA14531) in total, used for mirroring the program code from either OTP or external Flash when the system powers up as well as to retain data as needed before the system goes to extended sleep. Data retention ensures a secure and quick configuration of the BLE Core after the system wakes up. Every cell can be powered on/off according to the user’s own application needs in terms of data retention when extended sleep mode is to be used.The DA14535 has 64-KB Retainable RAM.

4.2.8.3. Linker File Included in SDK

A script file is needed to instruct the Linker to place code and data as needed. In the ARM Keil toolchain context, such a file is commonly referred to as Scatter file. SDK includes linker files for both DA1458x and DA1453x, residing in <sdk_root_directory>\sdk\common_project_files.

The SDK BLE example applications use the aforementioned default linker files. When using the default linker file, selection of RAM blocks to be retained during extended sleep is done automatically.

Note

DA1458x case: The 4th RAM block (last RAM block) must be always ON during extended sleep. The last RAM block contains the ROM data variables and the part of the memory which is shared with the BLE contoller.

Note

DA1453x case: The 3rd RAM block (last RAM block) must be always ON during extended sleep. The last RAM block contains ROM data variable and the part of the RAM which is shared with the BLE controller.

4.2.9. System Event/State Callbacks

Our BLE example applications expose a number of callback functions in the form of a structure (see the user_app_main_loop_callbacks structure definition in the respective user_callback_config.h file). Such functions may be called in the main loop in order to handle certain events system-wise.

The currently provided callbacks are summarized in the table below:

Table 6 System Callback Functions

#

Function Name

Description

Timing Constraints

1

app_on_init()

Called at system start up. Application tasks related to application initialization can be called here.

None

2

app_on_ble_powered()

Called if BLE core is active. Usually used to send messages to kernel tasks generated from asynchronous events that have been processed in app_on_system_powered().

Note: By default, the watchdog timer is reloaded and resumed when the system wakes up. Take watchdog timer handling into account (keep it running, freeze it, reload it, resume it, etc.).

Medium

3

app_on_system_powered()

Called if system domain is on (processor is active) while BLE core can be in sleep mode. Usually used to process asynchronous events at user level. The corresponding ISRs should be kept as short as possible and any remaining processing shall be done at this point. Note: By default, the watchdog timer is reloaded and resumed when the system wakes up. Take watchdog timer handling into account (keep it running, freeze it, reload it, resume it, etc.).

Medium

4

app_before_sleep()

Used to update the state of the application based on the latest status just before sleep checking starts.

Medium

5

app_validate_sleep()

Used to potentially cancel entry to extended sleep mode (with or without OTP copy) based on current application state. BLE and Radio are still powered off but other parts of the power domains stay active.

Hard

6

app_going_to_sleep()

Used for application-specific tasks just before entering low-power mode.

Hard

7

app_resume_from_sleep()

Used for application-specific tasks immediately after exit from low-power mode.

Hard

4.2.10. Processor Exceptions & Interrupt Requests

4.2.10.1. DA1458x

The following processor exceptions and interrupt requests are supported (for details see da14585_586.h as well as the corresponding datasheet):

  • NonMaskableInt_IRQn

  • HardFault_IRQn

  • SVCall_IRQn

  • PendSV_IRQn

  • SysTick_IRQn

  • BLE_WAKEUP_LP_IRQn

  • BLE_GEN_IRQn

  • UART_IRQn

  • UART2_IRQn

  • I2C_IRQn

  • SPI_IRQn

  • ADC_IRQn

  • KEYBRD_IRQn

  • BLE_RF_DIAG_IRQn

  • RFCAL_IRQn

  • GPIO0_IRQn

  • GPIO1_IRQn

  • GPIO2_IRQn

  • GPIO3_IRQn

  • GPIO4_IRQn

  • SWTIM_IRQn

  • WKUP_QUADEC_IRQn

  • PCM_IRQn

  • SRC_IN_IRQn

  • SRC_OUT_IRQn

  • DMA_IRQn

  • RESERVED21_IRQn

  • RESERVED22_IRQn

  • RESERVED23_IRQn

4.2.10.2. DA1453x

The following processor exceptions and interrupt requests are supported (for details see da14531.h or da14535.h as well as the corresponding datasheet):

  • NonMaskableInt_IRQn

  • HardFault_IRQn

  • SVCall_IRQn

  • PendSV_IRQn

  • SysTick_IRQn

  • BLE_WAKEUP_LP_IRQn

  • BLE_GEN_IRQn

  • UART_IRQn

  • UART2_IRQn

  • I2C_IRQn

  • SPI_IRQn

  • ADC_IRQn

  • KEYBRD_IRQn

  • BLE_RF_DIAG_IRQn

  • RF_CAL_IRQn

  • GPIO0_IRQn

  • GPIO1_IRQn

  • GPIO2_IRQn

  • GPIO3_IRQn

  • GPIO4_IRQn

  • SWTIM_IRQn

  • WKUP_QUADEC_IRQn

  • SWTIM1_IRQn

  • RTC_IRQn

  • DMA_IRQn

  • XTAL32M_RDY_IRQn

  • RESERVED21_IRQn

  • RESERVED22_IRQn

  • RESERVED23_IRQn

4.2.11. NVDS

The Non-Volatile Data Storage (NVDS) is used to keep system configuration settings such as the Bluetooth device address.

struct nvds_data_struct
{
   uint16_t lpclk_drift;         // Low power clock accourancy
   uint8_t bd_address[6];        // Device Bluetooth address
   uint16_t ble_ca_timer_dur;    // Default Channel Assessment Timer duration
   uint8_t ble_cra_timer_dur;    // Default Channel Reassessment Timer duration
   uint8_t ble_ca_min_rssi;      // Default Minimal RSSI Threshold
   uint8_t ble_ca_nb_pkt;        // Default number of packets to receive for statistics
   uint8_t ble_ca_nb_bad_pkt;    // Default number of bad packets needed to remove a channel
};

As an example, the following code snippet from da14531x_config_advanced.h of the ble_app_barebone example application shows the values of NVDS struct:

/****************************************************************************************************************/
/* NVDS configuration                                                                                           */
/* - CFG_NVDS_TAG_BD_ADDRESS            Default bdaddress. If bdaddress is written in the OTP header this       */
/*                                      value is ignored                                                        */
/* - CFG_NVDS_TAG_LPCLK_DRIFT           Low power clock drift. Permitted values in ppm are:                     */
/*      + DRIFT_20PPM                                                                                           */
/*      + DRIFT_30PPM                                                                                           */
/*      + DRIFT_50PPM                                                                                           */
/*      + DRIFT_75PPM                                                                                           */
/*      + DRIFT_100PPM                                                                                          */
/*      + DRIFT_150PPM                                                                                          */
/*      + DRIFT_250PPM                                                                                          */
/*      + DRIFT_500PPM                  Default value (500 ppm)                                                 */
/* - CFG_NVDS_TAG_BLE_CA_TIMER_DUR      Channel Assessment Timer duration (Multiple of 10ms)                    */
/* - CFG_NVDS_TAG_BLE_CRA_TIMER_DUR     Channel Reassessment Timer duration (Multiple of CA timer duration)     */
/* - CFG_NVDS_TAG_BLE_CA_MIN_RSSI       Minimum RSSI Threshold                                                  */
/* - CFG_NVDS_TAG_BLE_CA_NB_PKT         Number of packets to receive for statistics                             */
/* - CFG_NVDS_TAG_BLE_CA_NB_BAD_PKT     Number  of bad packets needed to remove a channel                       */
/****************************************************************************************************************/
#define CFG_NVDS_TAG_BD_ADDRESS             {0x09, 0x00, 0xF4, 0x35, 0x23, 0x48}

#define CFG_NVDS_TAG_LPCLK_DRIFT            DRIFT_500PPM
#define CFG_NVDS_TAG_BLE_CA_TIMER_DUR       2000
#define CFG_NVDS_TAG_BLE_CRA_TIMER_DUR      6
#define CFG_NVDS_TAG_BLE_CA_MIN_RSSI        0x40
#define CFG_NVDS_TAG_BLE_CA_NB_PKT          100
#define CFG_NVDS_TAG_BLE_CA_NB_BAD_PKT      50

4.2.12. SDK modules in ROM space (only for DA14531/535)

Several SDK modules have been transferred from SDK to DA14531 and DA14535 ROM to save RAM space. These modules can be re-defined in the SDK space if the user makes the following modifications:

  • globally define the __EXCLUDE_ROM_*__ flag in order to include the SDK defined module in the project build .

  • comment out the respective ROM symbols.

The following list contains the which are the SDK modules which have been transferred to ROM space:

arch_console.c

The module is by default placed in ROM space. It can be re-transferred to RAM space if the flag __EXCLUDE_ROM_ARCH_CONSOLE__ is defined and the respective da14531_symbols.txt, da14531_01_symbols.txt or da14535_symbols.txt ROM symbols are commented out.

Availability:

  • DA14531-00 : Yes

  • DA14531-01 : Yes

  • DA14535 : Yes

nvds.c

The module is by default placed in ROM space. It can be re-transferred to RAM space if the flag __EXCLUDE_ROM_NVDS__ is defined and the respective da14531_symbols.txt, da14531_01_symbols.txt or da14535_symbols.txt ROM symbols are commented out.

Availability:

  • DA14531-00 : Yes

  • DA14531-01 : Yes

  • DA14535 : Yes

chacha20.c

The module is by default placed in ROM space. It can be re-transferred to RAM space if the flag __EXCLUDE_ROM_CHACHA20__ is defined and the respective da14531_symbols.txt, da14531_01_symbols.txt or da14535_symbols.txt ROM symbols are commented out.

Availability:

  • DA14531-00 : Yes

  • DA14531-01 : Yes

  • DA14535 : Yes

prf.c

This module is by default put in ROM space. It can be re-transferred to RAM space if the flag __EXCLUDE_ROM_PRF__ is defined and the respective da14531_symbols.txt, da14531_01_symbols.txt or da14535_symbols.txt ROM symbols are commented out.

Availability:

  • DA14531-00 : Yes

  • DA14531-01 : Yes

  • DA14535 : Yes

prf_utils.c

This module is by default put in ROM space. It can be re-transferred to RAM space if the flag __EXCLUDE_ROM_PRF_UTILS__ is defined and the respective da14531_symbols.txt, da14531_01_symbols.txt or da14535_symbols.txt ROM symbols are commented out.

Availability:

  • DA14531-00 : Yes

  • DA14531-01 : Yes

  • DA14535 : Yes

diss.c - diss_task.c

These 2 modules are by default put in ROM space. They can be re-transferred to RAM space if the flag __EXCLUDE_ROM_DISS__ is defined and the respective da14531_symbols.txt ROM symbols are commented out.

Availability:

  • DA14531-00 : Yes

  • DA14531-01 : No

  • DA14535 : No

bass.c - bass_task.c

These 2 modules are by default put in ROM space. They can be re-transferred to RAM space if the flag __EXCLUDE_ROM_BASS__ is defined and the respective da14531_symbols.txt ROM symbols are commented out.

Availability:

  • DA14531-00 : Yes

  • DA14531-01 : No

  • DA14535 : No

suotar.c - suotar_task.c

These 2 modules are by default put in ROM space. They can be re-transferred to RAM space if the flag __EXCLUDE_ROM_SUOTAR__ is defined and the respective da14531_symbols.txt, da14531_01_symbols.txt or da14535_symbols.txt ROM symbols are commented out.

Availability:

  • DA14531-00 : Yes

  • DA14531-01 : Yes

  • DA14535 : Yes

custom_common.c

The module is by default placed in ROM space. It can be re-transferred to RAM space if the flag __EXCLUDE_ROM_CUSTOM_COMMON__ is defined and the respective da14531_symbols.txt, da14531_01_symbols.txt or da14535_symbols.txt ROM symbols are commented out.

Availability:

  • DA14531-00 : Yes

  • DA14531-01 : Yes

  • DA14535 : Yes

custs1.c and custs1_task.c

These 2 modules are by default put in ROM space. They can be re-transferred to RAM space if the flag __EXCLUDE_ROM_CUSTS1__ is defined and the respective da14531_symbols.txt, da14531_01_symbols.txt or da14535_symbols.txt ROM symbols are commented out.

Availability:

  • DA14531-00 : Yes

  • DA14531-01 : Yes

  • DA14535 : Yes

attm_db_128.c

The module is by default placed in ROM space. It can be re-transferred to RAM space if the flag __EXCLUDE_ROM_ATTM_DB_128__ is defined and the respective da14531_symbols.txt, da14531_01_symbols.txt or da14535_symbols.txt ROM symbols are commented out.

Availability:

  • DA14531-00 : Yes

  • DA14531-01 : Yes

  • DA14535 : Yes

app.c, app_task.c and app_entry_point.c

These 3 modules are by default put in ROM space. They can be re-transferred to RAM space if the flag __EXCLUDE_ROM_APP_TASK__ is defined and the respective da14531_symbols.txt, da14531_01_symbols.txt or da14535_symbols.txt ROM symbols are commented out.

Availability:

  • DA14531-00 : Yes

  • DA14531-01 : Yes

  • DA14535 : Yes

app_utils.c

This module is by default put in ROM space. It can be re-transferred to RAM space if the flag __EXCLUDE_ROM_APP_UTILS__ is defined and the respective da14531_symbols.txt, da14531_01_symbols.txt or da14535_symbols.txt ROM symbols are commented out.

Availability:

  • DA14531-00 : Yes

  • DA14531-01 : Yes

  • DA14535 : Yes

Note

The following module is available ONLY on the DA14531-01 ROM.

system_DA14531.c

This module is by default put in ROM space. It can be re-transferred to RAM space if the flag __EXCLUDE_ROM_SYSTEM_DA14531__ is defined and the respective da14531_01_symbols.txt ROM symbols are commented out.

Availability:

  • DA14531-00 : No

  • DA14531-01 : Yes

  • DA14535 : No

Note

The following module is available ONLY on the DA14535 ROM.

system_DA14535.c

This module is by default put in ROM space. It can be re-transferred to RAM space if the flag __EXCLUDE_ROM_SYSTEM_DA14535__ is defined and the respective da14535_symbols.txt ROM symbols are commented out.

Availability:

  • DA14531-00 : No

  • DA14531-01 : No

  • DA14535 : Yes

Note

The following modules are available ONLY on the DA14531-01 and DA14535 ROM.

arch_system.c

This module is by default put in ROM space. It can be re-transferred to RAM space if the flag __EXCLUDE_ROM_ARCH_SYSTEM__ is defined and the respective da14531_01_symbols.txt or da14535_symbols.txt ROM symbols are commented out.

Availability:

  • DA14531-00 : No

  • DA14531-01 : Yes

  • DA14535 : Yes

hash.c

This module is by default put in ROM space. It can be re-transferred to RAM space if the flag __EXCLUDE_ROM_HASH__ is defined and the respective da14531_01_symbols.txt or da14535_symbols.txt ROM symbols are commented out.

Availability:

  • DA14531-00 : No

  • DA14531-01 : Yes

  • DA14535 : Yes

otp_cs.c

This module is by default put in ROM space. It can be re-transferred to RAM space if the flag __EXCLUDE_ROM_OTP_CS__ is defined and the respective da14531_01_symbols.txt or da14535_symbols.txt ROM symbols are commented out.

Availability:

  • DA14531-00 : No

  • DA14531-01 : Yes

  • DA14535 : Yes

syscntl.c

This module is by default put in ROM space. It can be re-transferred to RAM space if the flag __EXCLUDE_ROM_SYSCNTL__ is defined and the respective da14531_01_symbols.txt or da14535_symbols.txt ROM symbols are commented out.

Availability:

  • DA14531-00 : No

  • DA14531-01 : Yes

  • DA14535 : Yes

gpio.c

This module is by default put in ROM space. It can be re-transferred to RAM space if the flag __EXCLUDE_ROM_GPIO__ is defined and the respective da14531_01_symbols.txt or da14535_symbols.txt ROM symbols are commented out.

Availability:

  • DA14531-00 : No

  • DA14531-01 : Yes

  • DA14535 : Yes

wkupct_quadec.c

This module is by default put in ROM space. It can be re-transferred to RAM space if the flag __EXCLUDE_ROM_WKUPCT_QUADEC__ is defined and the respective da14531_01_symbols.txt or da14535_symbols.txt ROM symbols are commented out.

Availability:

  • DA14531-00 : No

  • DA14531-01 : Yes

  • DA14535 : Yes

Apart from the aforementioned SDK code/data, which has been transferred to ROM, the following items have been transferred as well:

spi_531.c

This module is by default put in ROM space. It can be re-transferred to RAM space if the flag __EXCLUDE_ROM_SPI_531__ is defined and the respective da14531_01_symbols.txt or da14535_symbols.txt ROM symbols are commented out.

Availability:

  • DA14531-00 : No

  • DA14531-01 : Yes

  • DA14535 : Yes

i2c_eeprom.c

This module is by default put in ROM space. It can be re-transferred to RAM space if the flag __EXCLUDE_ROM_I2C_EEPROM__ is defined and the respective da14531_01_symbols.txt or da14535_symbols.txt ROM symbols are commented out.

Availability:

  • DA14531-00 : No

  • DA14531-01 : Yes

  • DA14535 : Yes

uart.c

This module is by default put in ROM space. It can be re-transferred to RAM space if the flag __EXCLUDE_ROM_UART__ is defined and the respective da14531_01_symbols.txt or da14535_symbols.txt ROM symbols are commented out.

Availability:

  • DA14531-00 : No

  • DA14531-01 : Yes

  • DA14535 : Yes

i2c.c

This module is by default put in ROM space. It can be re-transferred to RAM space if the flag __EXCLUDE_ROM_I2C__ is defined and the respective da14531_01_symbols.txt or da14535_symbols.txt ROM symbols are commented out.

Availability:

  • DA14531-00 : No

  • DA14531-01 : Yes

  • DA14535 : Yes

hw_otpc_531.c

This module is by default put in ROM space. It can be re-transferred to RAM space if the flag __EXCLUDE_ROM_HW_OTPC_531__ is defined and the respective da14531_01_symbols.txt or da14535_symbols.txt ROM symbols are commented out.

Availability:

  • DA14531-00 : No

  • DA14531-01 : Yes

  • DA14535 : Yes

adc_531.c

This module is by default put in ROM space. It can be re-transferred to RAM space if the flag __EXCLUDE_ROM_ADC_531__ is defined and the respective da14531_01_symbols.txt or da14535_symbols.txt ROM symbols are commented out.

Availability:

  • DA14531-00 : No

  • DA14531-01 : Yes

  • DA14535 : Yes

rwble.c

This module is by default put in ROM space. It can be re-transferred to RAM space if the flag __EXCLUDE_ROM_RWBLE__ is defined and the respective da14531_01_symbols.txt or da14535_symbols.txt ROM symbols are commented out.

Availability:

  • DA14531-00 : No

  • DA14531-01 : Yes

  • DA14535 : Yes

rwip.c

This module is by default put in ROM space. It can be re-transferred to RAM space if the flag __EXCLUDE_ROM_RWIP__ is defined and the respective da14531_01_symbols.txt or da14535_symbols.txt ROM symbols are commented out.

Availability:

  • DA14531-00 : No

  • DA14531-01 : Yes

  • DA14535 : Yes

rf_531.c

This module is by default put in ROM space. It can be re-transferred to RAM space if the flag __EXCLUDE_ROM_RF_531__ is defined and the respective da14531_01_symbols.txt or da14535_symbols.txt ROM symbols are commented out.

Availability:

  • DA14531-00 : No

  • DA14531-01 : Yes

  • DA14535 : Yes

ble_arp.c

This module is by default put in ROM space. It can be re-transferred to RAM space if the flag __EXCLUDE_ROM_BLE_ARP__ is defined and the respective da14531_01_symbols.txt or da14535_symbols.txt ROM symbols are commented out.

Availability:

  • DA14531-00 : No

  • DA14531-01 : Yes

  • DA14535 : Yes

Apart from the aforementioned SDK code/data, which has been transferred to ROM, the following items have been transferred as well:

; ARM library stuff
0x07f233f3 T __aeabi_ldivmod
0x07f2343f T __aeabi_llsr
0x07f2343f T _ll_ushift_r
0x07f23461 T __aeabi_uldivmod
; Some SDK data

; (controlled by __EXCLUDE_ROM_GAP_CFG_DATA__)
0x07f23f60 D gap_cfg_user_var_struct

Warning

If prf.c is excluded from ROM space, then diss.c, bass.c and suotar.c must be excluded from ROM as well, if the application uses the respective BLE profiles.

Note

It is recommended to make a project clean after excluding/including any of the above ROM from/in the project build.

4.2.13. Dynamic Radio TX Power Control (only for DA14531, DA14531_01 and DA14535)

As far as DA14531, DA14531_01 or DA14535 is concerned, the radio transmit output power may be adjusted at runtime. For instance, in the context of a BLE application, full power may be needed during advertising, but, once DA14531 gets connected to a peer device, the power can be set to a lower value aiming at reducing the current/power consumption. As soon as DA14531, DA14531_01 or DA14535 gets disconnected from the peer device, the radio transmit output power may be set back to its initial value.

In order to realize the aforementioned use case, CFG_ENHANCED_TX_PWR_CTRL shall be defined in the project (C/C++) settings, as shown in Figure 52.

../_images/CFG_ENHANCED_TX_PWR_CTRL.png

Figure 52 Defining CFG_ENHANCED_TX_PWR_CTRL in the Keil IDE

Then, the rf_pa_pwr_adv_set() and rf_pa_pwr_conn_set() API functions – see for details rf_531.h, residing in <sdk_root_directory>\sdk\platform\core_modules\rf\api – shall be called accordingly.