6. Preparing the Central

This chapter is dedicated to explaining the modifications that need to be performed on project ble_central that comes along with the SDK. The goal is for the reader to understand how to configure a DA1469x device so the measurements discussed in Chapter 2.2 can be properly performed.

The reader may opt to use their cellphone instead in order to connect and test the peripheral, however cellphone applications do not provide much control. Furthermore, unless the reader is the developer of the mobile phone application it is likely that they cannot control the event generation. The code for the central device can be found DA1469x Power Consumption Central as well, should the reader decide to use it.

6.1. Program Flow

The modified program, defines four operation modes, read, write, write no response, and notifications .

For READ and WRITE modes, initially one ATT operation is issued and after its completion, at the reception of read_completed or write_completed event the same operation is requested again.

In a similar way, during automatic write no response, the central will issue an ATT write no response request and another one every two seconds as dictated by write_no_response_trigger.

Notifications mode creates an instance of the ccc descriptor of each characteristic that has notifications or indications in its properties, as discovered during service_browse. This mode needs to be set if the scenario involves notifications/indications.

When measuring the power consumption of DA1469x devices, it is advised to wait at least 30 seconds before commencing the measurement procedure in order for the power saving mechanism of CMAC (M0+) processor to be fully activated. For the tester’s convenience, this implementation waits 60 seconds and then starts performing the operations to be measured.

6.2. Code Modifications

6.2.1. Definitions

In this implementation, four different operation modes are defined, that can even be used in conjunction to one another. In file ble_central_task.c add the following part of the code right after the #include directives.

/*
 * Read Mode   : Disabled (0), Enabled(1)
 */
#define USER_READ_BLE_OP_EN                     (1)

/*
 * Write Mode   : Disabled (0), Enabled(1)
 */
#define USER_WRITE_BLE_OP_EN                    (0)

/*
 * Write No Response Mode   : Disabled (0), Enabled(1)
 */
#define USER_WRITE_NO_RESPONSE_BLE_OP_EN        (0)

/*
 * Notifications/Indications Request : Disabled (0), Enabled(1)
 */
#define USER_BLE_NOTIFICATIONS_EN               (1)

/*
 * Suppress Messages Mode : Disabled (0), Enabled(1)
 */
#define USER_SUPPRESS_LOGS_EN                   (1)

In the task notification definitions section, add the highlighted lines:

/*
 * Notification bits reservation
 * bit #0 is always assigned to BLE event queue notification
 */
#define DISCOVER_NOTIF                          (1 << 1)
#define RECONNECT_NOTIF                         (1 << 2)
#define WRITE_NO_RESPONSE_T_NOTIF               (1 << 3)
#define START_MEASURE_T_NOTIF                   (1 << 4)

In order to connect to a device, a connection interval should be set as well as the address of the peer to connect to.

/*
 * Desired connection interval after service browse action (in milliseconds)
 */
#define USER_CONNECTION_INTERVAL_MS             (500)

/*
 * BDAddress to automatically connect to
 */
#define customBLE_STATIC_ADDRESS                {0x01, 0x01, 0x01, 0x06, 0x06, 0x06}

Define the handle of the characteristic to be accessed by read or write or write no response operations as well as the value to be written when issuing write requests.

#if( USER_READ_BLE_OP_EN || USER_WRITE_NO_RESPONSE_BLE_OP_EN || USER_WRITE_BLE_OP_EN )
__RETAINED_RW static uint16_t first_char_value_handle = 0x0b;
#endif

#if(USER_WRITE_NO_RESPONSE_BLE_OP_EN || USER_WRITE_BLE_OP_EN )
        /*
         * The value to be written to the characteristic.
         */
      uint8_t written_value[] = { 'A', ' ', 's' ,'t', 'r', 'i', 'n', 'g', ' ', 'o', 'f', ' ', '2', '0', ' ', 'c', 'h', 'a', 'r', 's'} ;
#endif

6.2.2. Timers

6.2.2.1. Declarations

Depending on the ATT Operation a write timer might need to be created as well as a callback function for it. Add the following snippet after written_value[] definition.

#if(USER_WRITE_NO_RESPONSE_BLE_OP_EN == 1)
        __RETAINED OS_TIMER write_no_response_timer_h;
#endif

Optionally define another timer in order to prevent the testing scenario from starting before a predetermined point in time(e.g. 30 seconds after ble_central_task() starts executing in order for DA1469x CMAC to utilize its power saving mode to its fullest.) , and then declare a flag variable to ensure that ATT write operations which will happen during browse service will not trigger new writes since service_browse should occur before the expiration of this timer.

__RETAINED OS_TIMER start_measurement_timer_h;

/* Flag byte to ble operations */
__RETAINED static uint8_t start_ble_operations_flag;

6.2.2.2. Creation

In ble_central_task() function create the timers, if they need to be created, right before the for(;;) section. Additionally start “start_measurement” timer.

#if (USER_WRITE_NO_RESPONSE_BLE_OP_EN == 1)
        /*Create the timer for writing to the characteristic*/
        write_no_response_timer_h=OS_TIMER_CREATE("write_no_response_trigger", OS_MS_2_TICKS(USER_CONNECTION_INTERVAL_MS),
                OS_TIMER_SUCCESS, (void *)OS_GET_CURRENT_TASK(),
                write_no_response_timer_cb);
#endif

        start_measurement_timer_h=OS_TIMER_CREATE("start_measurement", OS_MS_2_TICKS(30000),
                OS_TIMER_SUCCESS, (void *)OS_GET_CURRENT_TASK(),
                start_measurement_timer_cb);

        OS_TIMER_START(start_measurement_timer_h, OS_TIMER_FOREVER);

6.2.2.3. Callback Functions

Create the timer callback functions for the timers that will be used. All these callback functions notify ble_central_task() setting the corresponding bit. Additionally in start_measurement_timer_cb function the start_ble_operations_flag is set in order for ATT read and write operations to now trigger subsequent reads/writes to generate the scenario for measurements.

#if(USER_WRITE_NO_RESPONSE_BLE_OP_EN == 1)
static void write_no_response_timer_cb(OS_TIMER xTimer)
{

        OS_TASK_NOTIFY(ble_central_task_handle, WRITE_NO_RESPONSE_T_NOTIF, eSetBits);

}
#endif


static void start_measurement_timer_cb(OS_TIMER xTimer)
{
        start_ble_operations_flag = 1;
        OS_TASK_NOTIFY(ble_central_task_handle, START_MEASURE_T_NOTIF, eSetBits);
}

6.2.3. MTU change

To set up the maximum MTU that this central could be locked at, add the following line in ble_central_task right after the ble_register_app() call.

ble_gap_mtu_size_set(512);

Value 512 could be replaced by any value between 65 and 512 bytes as the reader sees fit. If the MTU value provided is less than 65 the SDK will automatically set it to the minimum which is 65.