3. Initial Project
This tutorial will use a modified version of one of the sample projects contained within the SDK, \projects\target_apps\template\empty_peripheral_template, as the starting point for each individual section. To create this modified project you’ll need to make the following changes to the empty_peripheral_template project.
3.1. Application Callbacks
There are a number of system callbacks that we need to re-route to user space, to do this modify
the user_app_main_loop_callbacks
structure in user_callback_config.h as follows:
static const struct arch_main_loop_callbacks user_app_main_loop_callbacks = {
.app_on_init = user_on_init,
// By default the watchdog timer is reloaded and resumed when the system wakes up.
// The user has to take into account the watchdog timer handling (keep it running,
// freeze it, reload it, resume it, etc), when the app_on_ble_powered() is being
// called and may potentially affect the main loop.
.app_on_ble_powered = NULL,
// By default the watchdog timer is reloaded and resumed when the system wakes up.
// The user has to take into account the watchdog timer handling (keep it running,
// freeze it, reload it, resume it, etc), when the app_on_system_powered() is being
// called and may potentially affect the main loop.
.app_on_system_powered = NULL,
.app_before_sleep = NULL,
.app_validate_sleep = NULL,
.app_going_to_sleep = NULL,
.app_resume_from_sleep = NULL,
};
We also need to add some Bluetooth stack callbacks, to do this modify the user_app_callbacks
structure in user_callback_config.h as follows:
static const struct app_callbacks user_app_callbacks = {
.app_on_connection = user_on_connection,
.app_on_disconnect = user_on_disconnect,
.app_on_update_params_rejected = NULL,
.app_on_update_params_complete = NULL,
.app_on_set_dev_config_complete = user_on_set_dev_config_complete,
.app_on_adv_nonconn_complete = NULL,
.app_on_adv_undirect_complete = NULL,
.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 = default_app_on_pairing_request,
.app_on_tk_exch = default_app_on_tk_exch,
.app_on_irk_exch = NULL,
.app_on_csrk_exch = NULL,
.app_on_ltk_exch = default_app_on_ltk_exch,
.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,
.app_on_ral_cmp_evt = NULL,
.app_on_ral_size_ind = NULL,
.app_on_ral_addr_ind = NULL,
#endif // (BLE_APP_SEC)
};
We then need to add function prototypes for the new callback functions to user_empty_peripheral_template.h as follows:
void user_on_init(void);
void user_on_set_dev_config_complete(void);
Finally we need to add the actual user space callback functions to user_empty_peripheral_template.c as follows:
void user_on_init(void)
{
arch_printf("\n\r%s", __FUNCTION__);
default_app_on_init();
}
void user_on_set_dev_config_complete(void)
{
arch_printf("\n\r%s", __FUNCTION__);
default_app_on_set_dev_config_complete();
}
3.2. Sleep Mode
By default the project does not use sleep mode and so we need to perform the following modification to ensure the device enters sleep mode whenever possible. We can do this by modifying app_default_sleep_mode
in user_config.h as follows:
static const sleep_state_t app_default_sleep_mode = ARCH_EXT_SLEEP_ON;
3.3. SPI Flash
A number of the following chapters use the SPI interface to access the flash memory found on the development kits. On both the PRO and USB kits the flash memory is connected to the following DA14531 pins:
SPI Flash MISO: P0_3
SPI Flash MOSI: P0_0
SPI Flash CLK: P0_4
SPI Flash CS: P0_1
First add definitions for these pin mappings to the file user_periph_setup.h as follows:
/****************************************************************************************/
/* SPI configuration */
/****************************************************************************************/
#define SPI_EN_PORT GPIO_PORT_0
#define SPI_EN_PIN GPIO_PIN_1
#define SPI_CLK_PORT GPIO_PORT_0
#define SPI_CLK_PIN GPIO_PIN_4
#define SPI_DO_PORT GPIO_PORT_0
#define SPI_DO_PIN GPIO_PIN_0
#define SPI_DI_PORT GPIO_PORT_0
#define SPI_DI_PIN GPIO_PIN_3
Next we need to reserve these pins so that the SDK can check for duplicate assignments. To do this add the following code to the GPIO_reservations
function that can be found in the user_periph_setup.c file:
RESERVE_GPIO(SPI_FLASH_CS, SPI_EN_PORT, SPI_EN_PIN, PID_SPI_EN);
RESERVE_GPIO(SPI_FLASH_CLK, SPI_CLK_PORT, SPI_CLK_PIN, PID_SPI_CLK);
RESERVE_GPIO(SPI_FLASH_DO, SPI_DO_PORT, SPI_DO_PIN, PID_SPI_DO);
RESERVE_GPIO(SPI_FLASH_DI, SPI_DI_PORT, SPI_DI_PIN, PID_SPI_DI);
Now configure the pins to have the relevant SPI function by adidng the following to the set_pad_functions
function:
GPIO_ConfigurePin(SPI_EN_PORT, SPI_EN_PIN, OUTPUT, PID_SPI_EN, true);
GPIO_ConfigurePin(SPI_CLK_PORT, SPI_CLK_PIN, OUTPUT, PID_SPI_CLK, false);
GPIO_ConfigurePin(SPI_DO_PORT, SPI_DO_PIN, OUTPUT, PID_SPI_DO, false);
GPIO_ConfigurePin(SPI_DI_PORT, SPI_DI_PIN, INPUT, PID_SPI_DI, false);
3.4. Serial Debug
We will now enable serial debug capability so that a terminal emulator (such as Tera Term etc.) can be used to view debug information output by the application running on the DA14531.
3.4.1. Enabling the Serial Port
We can enable the UART with a simple modification to the configuration file: da1458x_config_basic.h. Scroll down and find the #undef CFG_PRINTF
statement and change it to:
#define CFG_PRINTF
Note
There are two #undef CFG_PRINTF
statements in the file, one for the DA14585/6 and one for the DA14531, make sure to change one related to the device you are working on!
In user_periph_setup.h change the GPIO used as the UART transmit output by the DA14531 devkit PRO and USB to P0_5 as follows:
#define UART2_TX_PIN GPIO_PIN_5
This will automatically select and configure the proper GPIO for the UART TX. In order to give ourselves access to a more user friendly API, we will add the following include statement to user_empty_peripheral_template.c:
#include "arch_console.h"
We can now use the following functions:
arch_puts()
, to transmit a simple string via the UARTarch_printf()
, to format and transmit a string via the UART
3.4.2. Testing the Serial Port
Configure your Terminal Emulator as follows:
Baud Rate: 115200
Data: 8 bits
Parity: None
Stop Bits: 1
Flow Control: None
Build the project and load it onto target.
When you run the application using the debugger you should see the following be transmitted via the UART: