Introduction

In this module we will learn about Bluetooth® low energy (LE) connections. How is a Blutooth LE connection formed? What information needs to be shared by two devices in order for them to stay connected? How can BLE connections be updated? This tutorial will give you an overview of how to set up Bluetooth LE connections suited to your needs.

In this lab we will be working with Project Zero and BTool in order to form a Bluetooth LE connection. In the first two tasks, two devices will be programmed, one as a Bluetooth LE peripheral and one with the Host Test project which can be used together with the program BTool. In the third and fourth task, BTool will be used to initiate a connection in legacy and long range mode. In the fourth and fifth tasks, the connection parameters will be updated, from the Central and Peripheral side, respectively. In the last task, the connection will be terminated.

This tutorial will take about two hours to complete and requires basic embedded programming skills (see the Prerequisites section for details).

Attention

This lab cannot be run from CCS Cloud. In order to do this lab, you need to have Code Composer Studio (CCS) installed locally. You also need to install the SimpleLink™ Bluetooth® low energy software development kit (SDK).

Prerequisites

Hardware

For this lab, you need two Bluetooth-enabled development boards. Supported devices are:

Software

About BLE Connections

What is a Bluetooth LE connection? A connection implies a link between devices over time. Bluetooth LE is a synchronous radio frequency (RF) protocol, meaning that any transmission between devices must be scheduled. A Bluetooth LE connection can thus be perceived as a series of meetings where two devices transmit and receive information at the same time, on the same radio frequency. In order for this to work, the devices must agree on where (that is, on what frequency) and when next to meet. The BLE5-Stack handles connection timing and frequency hopping. The latter will not be further explained in the following text.

The timing, however, we will dive deeper into, in the Connection Parameters section.

Organizing a radio meeting.

A Bluetooth LE connection always consists of two devices. The device that initiates the connection is called the Central. This device also has the final word on timing and frequency hopping. The device that responds to a connection initiation is called the Peripheral.

The Link Layer is a part of a Bluetooth low energy application that keeps track of whether the device is in a connected state (link) or not. As described in BLE Scanning and Advertising, in order for Bluetooth LE devices to find each other, they must either scan or advertise. A scanning device that has found a connectable advertiser can initiate a connection. The Link Layer states are summed up in the following figure.

As explained in BLE Scanning and Advertising, a Bluetooth low energy device has a defined GAP role, which can be one or more of the following: Broadcaster, Observer, Peripheral or Central. As only peripherals and centrals can enter connections, these two will be the focus of this lab. A peripheral is a device with the ability to advertise and to enter a connection allowing to be controlled. A Central is a device that can scan for Bluetooth LE devices and initiate connections. The Central is always the controller of the connection.

Bluetooth LE Connection Life Cycle

As mentioned, the connection must be initiated by the Central and then accepted by the peripheral device. The connection can be terminated from either the Central or the Peripheral.

The two Bluetooth LE devices are connected as long as they periodically exchange data. The exchange is called a connection event and consists of both devices transmitting and receiving information consecutively. Each connection event starts with the Central transmitting and the Peripheral receiving. Then the Peripheral transmits and the Central receives.

Quiz

Which statement is true?

Which of the following is not a GAPRole?

Can the Central and the Peripheral communicate outside of the connection events?

Bluetooth LE Connection Limitations

Before Bluetooth Core Specification v4.1, a Bluetooth LE peripheral device could connect to only one Central device at a time. Over time, Bluetooth LE has evolved to support more complex topologies, e.g. a star network configuration where one Central device connects to multiple peripheral devices. Or a network where peripheral devices can connect to multiple Central devices, and a device can operate both as a Peripheral and Central role (in different connections) simultaneously without needing to swap roles. Still, Peripherals cannot connect to each other, but instead are limited to connect with Central devices.

The specification does not limit the number of connections. The available memory resources of the device and the time domain determines the maximum number of connections supported. The user can profile the heap used in the project to determine the maximum amount of connections that can be supported.

  • For more information, see the Debugging Common Heap Issues Chapter of the TI BLE5-Stack User's Guide.

  • See the multi_role project for an example of a multi role (simultaneous Central/peripheral GAPRole) example project: <SDK_INSTALL_DIR>\examples\rtos\<BOARD_NAME>\ble5stack\multi_role\README.html

  • See the Topology section ([Vol 1], Part A, Section 3.3.2.1.3) of the Bluetooth Core Specification Version 5.2 for reference.

Task 1 – Set Up a Peripheral Device

For our Central device to have something to connect to, we need to set up a Bluetooth LE peripheral device. We will use Project Zero for this purpose. You can find Project Zero in the SDK alongside other BLE5-Stack example projects.

Flash one of your LaunchPads with Project Zero. If you need help, follow the instructions in the Bluetooth low energy Fundamentals SimpleLink Academy module. If you want to check that your peripheral device (Project Zero) is advertising, you can use your phone, using the SimpleLink Starter app or another Bluetooth LE Client app.

Great!

Now we have a peripheral that our Central device can connect to. Let's proceed!

Task 2 – Use Host Test with BTool

BTool is a tool bundled with the SimpleLink SDK, found under <SDK_INSTALL_DIR>\tools\ble5stack\btool. In order to use it, your computer must be connected to a LaunchPad running the Host Test example project. In this module we will use BTool to control a Bluetooth LE Central, but it can be used for other situations as well. This means that not all commands found in BTool are suitable or permitted.

Program a LaunchPad with Host Test

Attention

To make sure the correct device is flashed with the Host Test project (i.e. that the peripheral device is not overwritten), you should assign a specific LaunchPad to each CCS project. Instructions for this is found here.

Import the Host Test app and stack project to CCS by selecting Project → Import CCS Projects... The project is located under <SDK_INSTALL_DIR>\examples\rtos\CC26X2R1_LAUNCHXL\ble5stack\host_test (or corresponding folder).

  1. Build the Stack_Wrapper project by right-clicking on it and selecting Build.
  2. Build and load the program by right-clicking on ble5_host_test_cc26x2r1lp_app and selecting Debug As → Code Composer Debug Session.
  3. Terminate the Debug session by pressing the red square.

Open BTool

Open Run_BTool.bat in <SDK_INSTALL_DIR>\tools\ble5stack\btool.

You will be prompted for the COM port of the device. You can find this by opening the Windows Device Manager. (Right click on This PC → More → Properties. Device Manager is found on the menu to the left.) Look for the port called XDS110 Class Application/User UART.

If everything went well, BTool will start printing green and blue events. (If you're seeing yellow or red events, please make sure you found the correct COM port and that the device is not paused by a debug session in CCS. You may also need to hit the LaunchPad reset button before connecting to BTool.)

If you scroll all the way to the top of the BTool log, you can see that the device has been initialized as a Central by GAP.

To the left BTool displays information about the host device. This is also where information about any active connections will be displayed. In the center BTool prints out a log of all commands and events. To the right, some actions are displayed.

When the user sends a command, this is printed in green. These command log entries start with <Tx> as they are transmitted from BTool to the device running Host Test. Events received from the LaunchPad running Host Test are printed in blue and start with <Rx>. For each command sent, BTool will receive one GAP_HCI_ExtentionCommandStatus event to indicate that the command was received.

Task 3 – Initiate a Connection

Scan for Nearby Devices

Press the Scan button. BTool will start printing out GAP_AdvertiserScannerEvent events. When the scan is finished, a GAP_EVT_SCAN_DISABLED event will give a summary of the discovered devices. If the scanner found multiple Blutooth LE devices, look through the log for the Project Zero advertiser scanner event in order to find your peripheral device's address.

Or find the ProjectZero device address in the serial output. An example serial output is shown below with the unique device address.

Connect to Project Zero

Choose the correct Peripheral BDA (Bluetooth Device Address) and press Establish to connect to the peripheral device.

BTool will send a GAP_EstablishLinkRequest command which will prompt the device to send a connection request through the BLE5-Stack to Project Zero. If the connection is successful, a GAP_EstablishLink event will be posted with information with information about the connection including type and address of peer device. Connection info will also appear in the far left column of BTool.

By using a Bluetooth LE packet sniffer, we can see what is transmitted over the air. Here is a printout of the connection request packet and the following connection event packets.

The connection request packet is the Bluetooth LE packet sent from the Central to initiate a connection with a Peripheral. It contains the addresses of both the Central and the Peripheral in the requested connection (under InitA and AdvA). It also contains information about the packet itself; e.g the packet type and how to calculate the CRC (cyclic redundancy check). If you're curious, you can read about some of the fields in the connection request packet, below:

  • P.nbr. (226) - Packet sniffer's packet number.
  • Time (us) (+414) - Time since the last packet was received.
  • Channel (0x25) - Bluetooth LE channel this packet was sent on (0x25 = channel 37). As explained in BLE Scanning and Advertising, channels 37, 38 and 39 are advertising channels while channels 0 through 36 are data channels.
  • Adv PDU Type (ADV_CONNECT_REQ) - Connection request packet. (PDU = Packet Data Unit.)
  • PDU-Length (34) -Length of the packet.
  • InitA (0x98072DAA67E) - Bluetooth device address (BDA) of the initiator (Central).
  • AdvA (0xB0B448D07AB4) - BDA of the intended Peripheral device.
  • Interval, Latency and Timeout (0x0050, 0x0000 and 0x07D0) - Connection parameters (see the next section). Here the connection interval is 0x0050 which equals 80 (100 ms), the Peripheral latency is zero and the connection timeout is 0x07D0 = 2000 ms.
  • ChM (1F FF FF FF FF) - Channel map. Here the channel map is 1F FF FF FF FF = 0001 1111 1111 1111 1111 1111 1111 1111 1111 1111 in binary, meaning that all data channels (0-37) will be used in this connection. Channel 37-39 will not be used, which is indicated by the zeros in the first three positions.
  • Hop (0x08) - Channel hop increment. You can see that the first data packet is sent on channel 0x08, and the next on channel 0x10 (=16).
  • SCA (0x05) - Sleep clock accuracy.
  • CRC (0xC375A0) - Cyclic redundancy check. CRC is used to check that the full packet has been received.
  • RSSI (-32) - Received signal strength indication.

After having sent the connection request, the Central starts sending connection event packets (yellow). The bottom yellow packet is the Peripheral responding. In addition to the fields common with the connection request packet, the connection event packets contain:

  • Time (us) - By looking at the timestamps of the connection event data packets, the connection interval can be determined. (The connection interval will be further discussed in a following section.)
  • Access Address (0xE4CEB330) - The packet sniffer's ID for this connection.
  • Direction (C→P) - Central to Peripheral or Peripheral to Central.
  • NESN (1) - Next expected sequence number.
  • SN (0) - Sequence number. By comparing the NESN to the SN of the next packet, the BLE stack determines whether a packet has been missed. This is also how the packet sniffer sets the ACK Status.

What Happens on the Peripheral Side?

By default, Project Zero advertises with connectable undirected advertisements. This is defined through SysConfig in BLEBroadcaster ConfigurationAdvertisement Set XAdvertisement Parameters X (field Legacy Event Properties Options). You can read more about advertising properties in BLE Scanning and Advertising. When using connectable undirected advertisements, the peripheral device accepts connection requests from any initiator. The peripheral does not send a packet to notify the Central that the connection has been accepted. Instead it waits for the first connection event.

Connection Parameters

When forming a connection, four parameters must be determined. They all have to do with the connection timing:

Connection Parameter Description Range
Min Connection Interval Minimum connection interval 7.5 ms to 4 s
Max Connection Interval Maximum connection interval 7.5 ms to 4 s
Peripheral Latency Number of skipped connection events 0 - 499
Supervision Timeout Connection supervision timeout 100 ms to 32 s

The connection parameters are set in the Central before initiating the connection. GAP handles these parameters. In BTool, you can find the connection settings to the right, under Discover Connect. Please note that in BTool, these connection settings cannot be used to update the connection parameters during an active connection.

Here we'll focus on the connection interval. If you want to know more about Peripheral latency or supervision time-out, you can read about them in the TI BLE5-Stack User's Guide in the Developing a Bluetooth Low Energy Application section.

Connection Interval

The connection interval is the time between each connection event. The connection interval must be agreed upon by the two devices in the connection in order for them to be transmitting and receiving at the same time. The connection interval has to be between 7.5 ms and 4 s to comply with the Bluetooth Core Specification Version 5.2. Each connection event consumes power, therefore we generally want a large connection interval. On the other hand, the connection interval represents latency. This means that in a connection with 1 s connection interval, a button press on the Peripheral device might not be registered on the Central device before 1 s has passed.

The connection interval is defined in terms of a minimum and a maximum value. If you want your application to have a fixed connection interval, you can give both variables the same value. Sometimes we want to give the Central device the freedom to change the connection interval without any further input from the user. In that case, give the minimum and maximum variables different values. The Central device will then be free to change its connection interval, as long as it stays within the defined limits. Per default, the device will start with as large connection interval as possible (i.e. the max value will be chosen by the BLE stack as the connection interval) in order to minimize power consumption. Your peer device may have specific connection interval requirements so make sure the connection interval you choose is supported by the peer you wish to connect to.

Quiz

For an application that needs low latency between an event happening and a message being transmitted, which connection interval would you choose?

Consider the following connection settings and decide what the initial connection interval will be:

Which statement(s) are true?

Task 4 – Changing the Connection Interval from BTool

In order to change the connection interval, BTool must first give the new parameters to the Central device. Then the Central must send a connection parameter update request to the Peripheral.

Under Adv.Commands, find GAP_UpdateLinkParamReq. Choose new values for intervalMin and intervalMax, e.g. 160 and 320. (Remember that these values are given in 1.25 ms, which means that intervalMax = 320 will give a connection interval of 400 ms.) Don't forget to press Send Command.

A short while after the GAP_UpdateLinkParamReq command is sent, a GAP_LinkParamUpdate event is received. This event contains information about the connection. The chosen connection interval is returned in (ConnInterval), a value that is between intervalMin and intervalMax. It is critical that you use the correct connection handle (connHandle) especially in case of multiple connections. This is found to the left in BTool, under Connection Info.

Task 5 – Connection Parameter Update from the Peripheral

It seems unfair that only the Central device has something to say when it comes to the connection parameters. The Peripheral device can send a connection parameter update request, which will be processed by the Central device. Let's configure Project Zero to send connection parameter update requests by pressing a button!

The technicalities of this operation will be taken care of by the GAP API. As Project Zero is a peripheral device, the GAP APIs can be called within the main application file project_zero.c, which is found in the Application folder of the app project.

As used in the project_zero.c, the connection parameters are updated with a call to the GAP_UpdateLinkParamReq API with the desired connection parameter values after connection has been established. If you're not sure what to put, sneak a peek at the solution below.

If you want to know more about Connection Parameter Requests, you can read more about this in the ([Vol 3], Part C, Section 9.3.9.2) of the Bluetooth Core Specification Version 5.2

The default project calls the following function after a connection is established which also starts a timer to send a parameter update request. After delay of SEND_PARAM_UPDATE_DELAY, the GAP_UpdateLinkParamReq API will be called to start the parameter update request. We set the startFlag parameter Util_constructClock() to false to disable automatic parameter update request:

// Construct the clock. This is only used once and will be deconstructed
// once the update is sent
Util_constructClock(connList[i].pUpdateClock,
                    ProjectZero_paramUpdClockHandler,
                    SEND_PARAM_UPDATE_DELAY, 0, false,
                    (uintptr_t)connHandle);

project_zero.c :: ProjectZero_addConn() – Enable clock for connection parameter update request.

If we want the Connection Parameter Update Request to happen with a button press, we must find the function in project_zero.c where button presses are processed. This function is called ProjectZero_handleButtonPress().

Then we can call the GAP_UpdateLinkParamReq API on a button press after setting the DEFAULT_DESIRED_x parameters. For this solution we will choose CONFIG_PIN_BTN1 (BTN-1 or left button on LaunchPad - sometimes named BUTTON0) to send our request to all active connections.

case CONFIG_PIN_BTN1:
{
    ButtonService_SetParameter(BS_BUTTON0_ID,
                               sizeof(pState->state),
                               &pState->state);

    uint8_t i;
    gapUpdateLinkParamReq_t req;
    req.connLatency = DEFAULT_DESIRED_SLAVE_LATENCY;
    req.connTimeout = DEFAULT_DESIRED_CONN_TIMEOUT;
    req.intervalMin = DEFAULT_DESIRED_MIN_CONN_INTERVAL;
    req.intervalMax = DEFAULT_DESIRED_MAX_CONN_INTERVAL;

    for(i = 0; i < MAX_NUM_BLE_CONNS; i++)
    {
        // For all existing connections, send a parameter update request.
        if (connList[i].connHandle != 0xFFFF)
        {
            // Send parameter update
            req.connectionHandle = connList[i].connHandle;
            bStatus_t status = GAP_UpdateLinkParamReq(&req);

            Log_info0("Sending Conn Param Update");
        }
    }
}
break;

project_zero.c :: ProjectZero_handleButtonPress() – Enable connection parameter update request.

If you want you can use values other than those defined.

Again, be careful that you're programming the correct device. The parameter update request will be sent automatically after BTN-1 is pressed (CONFIG_PIN_BTN1 refers to BTN-1 on the board). The GAP_LinkParamUpdate event should thus show up in BTool not long after the connection has been formed.

When the request is received, the Central will receive HCI_LE_RemoteConnectionParameterRequestReply followed by GAP_LinkParamUpdate with the new connection parameters.

Task 6 – Terminate the Connection

At some point, the connection has done its job and it's time to break the connection. In BTool, this is simply done by pressing Terminate under Discover Connect. Again, please make sure that you have the correct connection handle entered. This should trigger a GAP_TerminateLink event with the reason 0x16 (which is 22 in decimal), Host requested.

Terminate the Connection from the Peripheral

Let's program the Peripheral to disconnect when a button is pressed. We will use GAP_TerminateLinkReq(). This function, defined in GAP, tells GAP to terminate the connection. This gets broadcasted to the Central, along with a reason why the connection was terminated. Simultaneously, a GAP_LINK_TERMINATED_EVENT gets posted in the GAP message event queue. (This event gets posted whether the termination was intentional or not.)

Since we are using CONFIG_PIN_BTN1 as our Connection Parameter Update button, we will use CONFIG_PIN_BTN2 (BTN-2 or right button on LaunchPad - sometimes called BUTTON1) to call the function GAP_TerminateLinkReq().

case CONFIG_PIN_BTN2:
    ButtonService_SetParameter(BS_BUTTON1_ID,
                               sizeof(pState->state),
                               &pState->state);

    uint8_t i;
    for(i = 0; i < MAX_NUM_BLE_CONNS; i++)
    {
        //For all existing connections, terminate the link.
        if (connList[i].connHandle != 0xFFFF)
        {
            GAP_TerminateLinkReq(connList[i].connHandle, HCI_DISCONNECT_REMOTE_USER_TERM);
            Log_info0("Terminating connection(s).");
        }
    }
break;

project_zero.c :: ProjectZero_handleButtonPress() – Terminating the connection.

Rebuild and debug Project Zero. In BTool, form the connection. Pressing the right button (BTN-2) on the peripheral device will cause the connection to terminate with the reason 0x13, Peer requested.

Further Reading

In this SimpleLink Academy lab, we have talked a lot about what a Bluetooth LE connection is, but very little about its purpose. Usually, we want to exchange specific information between the two devices. This can be accomplished with Bluetooth Services and Characteristics. If you want to learn about this, you should move on to the SimpleLink Academy module Bluetooth low energy Custom Profile.

References

TI BLE5-Stack User's Guide

Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License.