NAV Navbar

CYW20819 Low-Power Modes – CE225540

This example demonstrates low-power modes on CYW20819 using ModusToolboxTM IDE.

Requirements

Tool: ModusToolbox IDE 1.1 or later version

Programming Language: C

Associated Parts: CYW20819

Related Hardware: CYW920819EVB-02 Evaluation Kit

Overview

This example demonstrates the use of low-power mode APIs for CYW20819 and shows how to measure the current on the CYW20819EVB-02 Evaluation Kit. This example uses switch SW3 on the evaluation kit to switch between different states such as starting BLE advertisement, disconnecting from BLE connection, and so on. On startup, the device initializes the stack and immediately enters enhanced Power Down Sleep (ePDS) mode. Pressing switch SW3 will start advertisement while in ePDS mode. An external GAP Central can be used to connect to this device and enable notifications. The device will maintain the connection while in ePDS mode. Upon disconnection, the device will enter HID-Off mode for 10 seconds and then start executing from the beginning.

Hardware Setup

Remove jumpers J14 and J18 to disable unused peripherals on the evaluation kit. For the rest of the jumpers, use the kit’s default configuration. Refer to the kit guide to ensure the kit is configured correctly. The default settings will power the board at 3.3 V. If you want to power the kit using a different voltage like 1.8 V or a coin cell, change jumpers J7 and J8 to the appropriate position for VDDIO and VBAT domain.

An iOS/Android mobile device or a PC with CY5677 CySmart BLE 4.2 USB Dongle can act as the BLE Central which can connect to the Peripheral device CYW20819 on the CYW20819EVB-02 Evaluation Kit.

Software Setup

This code example consists of two parts: the GAP Central and the GAP Peripheral. For the GAP Central, download and install the CySmart app for iOS or Android.

You can also use the CySmart Host Emulation Tool Windows PC application if you have access to the CY5677 CySmart BLE 4.2 USB Dongle.

Scan the following QR codes from your mobile phone to download the CySmart app.

iOS Android

Instructions in this example use Tera Term as the terminal emulator, but you can use any that you prefer.

Operation

Figure 1. CYW920819EVB-02 Jumpers to Measure Current

Figure 2. Programming the CYW20819 Device from ModusToolbox

Figure 3. Bootup Log

Figure 4. Start Advertisement Log

Figure 5. Evaluating with the CySmart App on Android

Figure 6. Connection, Pairing, and Connection Parameters Update Messages

Figure 7. Disconnection, HID-Off, and Restart Trace Messages

  1. Connect the kit to your PC using the provided USB cable.
  2. If you want to measure power consumption, connect an ammeter across J15.1 and J15.2, and a second ammeter across J8.2 and J8.4 to measure the current in VDDIO and VBAT domains respectively as shown in Figure 1. If you don’t have two ammeters, measure the current on one domain at a time. Note that the VPA_BT power domain is not used on this kit; therefore, there is no need to measure the current on this domain.
  3. Remove jumpers J14 and J18 to disable unused peripherals on the evaluation kit.
  4. The USB Serial interface on the kit provides access to the two UART interfaces of the CYW20819 device – WICED HCI UART and WICED Peripheral UART (PUART). The HCI UART is used only for downloading the application code in this code example; PUART is used for printing the Bluetooth stack and application trace messages. Open your terminal software and select the PUART COM port, with a baud rate setting of 115200 bps. If you want to disable trace messages, comment out the following line in the file low_power_20819.c:
  5. wiced_set_debug_uart( WICED_ROUTE_DEBUG_TO_PUART );
  6. Import the code example into a new or existing workspace. See KBA225201.
  7. Build and program the application: In the project explorer, select the [App Name]_mainapp project. In the Quick Panel, scroll to the Launches section, and click the [App Name] Build + Program configuration as shown in Figure 2.
  8. After the programming is complete, the device will boot up and enter ePDS mode. The continuous '.' prints means that the PMU is asking for permission from the application to enter ePDS mode. The '.' stops when the device enters ePDS mode. Note the current readings from the ammeters. These are the current consumed in ePDS mode with no Bluetooth activity.
  9. Press switch SW3 on the evaluation kit. The application will get a button callback and it will start advertising. Note the current readings on the ammeters. This is the average current in ePDS mode with advertisement. The ‘.’ character is printed every time the application gets a sleep permission callback from the PMU and the boxes are printed every time the wakes up from ePDS. These prints will not occur if you comment them out in the low_power_sleep_handler function.
  10. To test a connection using the CySmart mobile app, follow the steps below (see equivalent CySmart app screenshots in Figure 5):
    1. Turn ON Bluetooth on your Android or iOS device.
    2. Launch the CySmart app.
    3. Swipe down on the CySmart app home screen to start scanning for BLE Peripherals; your device appears in the CySmart app home screen. Select your device to establish a BLE connection. Once the device is connected, you can read the current numbers from the ammeters. These are the current in ePDS mode with a connection at a connection interval of 100 ms.
    4. Select the GATT DB from the carousel view.
    5. Select Battery Service and then select Characteristics.
    6. Select Notify. CYW920819EVB-02 will start sending GATT notifications to the mobile device. Note the current readings on the ammeters. These are the current in ePDS mode with a connection at a connection interval of 100 ms and notifications being sent every 5 seconds.
    7. Disconnect the Bluetooth connection by pressing SW3 on the kit or by backing out from the mobile app. The device will enter HID-Off mode for 10 seconds. Note the current numbers. These are the current numbers in HID-Off mode.
  11. To test using the CySmart desktop application on a PC:
    1. Open the CySmart desktop application and connect to the CySmart CY5677 dongle (Central device). Refer to the CySmart User Guide on how to use this application.
    2. Scan and connect to 'low_power_20819' device. When asked for a connection parameter update, accept it. After the connection is established, you can measure the current values. These are the current numbers in ePDS mode with connection at 100 ms interval.
    3. Go to the device tab and click Discover all attributes.
    4. Click Enable all Notifications. The device will start sending notifications every 5 seconds. Note the current readings on the ammeters. These are the current in ePDS mode with a connection at a connection interval of 100 ms and notifications being sent every 5 seconds.
    5. Click Disconnect to disconnect from the Central. The device will enter HID-Off mode for 10 seconds. Note the current numbers. These are the current numbers in HID-Off mode.

Design and Implementation

This code example implements a GATT Server and GAP Peripheral role on CYW920819EVB-02. Once the device is powered on, it boots up, configures sleep, initializes the Bluetooth stack, registers a button interrupt and GATT database, and then enters ePDS mode. You need to press switch SW3 on the kit to start low-duty-cycle advertisement. The device is still in ePDS mode. You can now connect to the device using a GAP Central. Upon connection, the device will request connection parameters to be updated (specifically the connection interval to 100 ms). If the request is accepted, the connection interval changes to 100 ms. The device remains in ePDS mode and maintains the connection by sending empty packets. The GAP Central can now discover all attributes and enable GATT notifications. The GAP Peripheral will start sending a dummy battery level value every 5 seconds.

The GATT Server implements a Battery Service with a Battery Level characteristic. This characteristic is readable and notifiable.

The application code and Bluetooth stack runs on the Arm® Cortex®-M4 core of the CYW20819 SoC. The application-level source files for this code example are listed in Table 1.

Table 1. Code Example File Structure

File Name Comments
low_power_20819.c This file contains the application_start() function, which is the entry point for execution of the user application code after device startup. It also has the sleep callback function used by the PMU. The function to enter HID-Off is also included in this file. The contents in this file can be referenced to implement low-power modes in other applications.
wiced_bt_cfg.c This file contains the runtime Bluetooth stack configuration parameters such as device name and advertisement/connection settings.
cycfg_bt.h, cycfg_gatt_db.c, cycfg_gatt_db.h These files reside in the GeneratedSource folder under the application folder. They contain the GATT database information generated using the Bluetooth Configurator tool.
low_power_20819_ble.c This file contains the Bluetooth events callback function along with other functions to service Bluetooth events. It also contains the button callback function.

Application Flow

Figure 8. Application Flow after Bootup

Figure 9. Button Callback Flow

Figure 10. BT Stack Management Callback Flow

Figure 11. GATT Event Callback Flow

Figure 12. BT Management and GATT Events Function Call Tree

The following diagrams show the flow of the application code. Figure 8 shows the flow of the application when it boots up. Figure 9 shows the flow of the button callback, Figure 10 shows the flow of BT stack management event callbacks, Figure 11 shows the flow of GATT event callbacks and Figure 12 shows the tree of functions that are called on BT and GATT event callbacks from the stack.

Current Measurements

The instantaneous current consumed by the device is not a steady state value but varies depending on the state of the device that dynamically changes with the power mode transitions, making the measurement of each individual instantaneous current with a handheld multimeter practically impossible because the duration of these current bursts is very small. Therefore, you should use a multimeter that provides the option to set the ”aperture” of the measurement. The aperture is the period ”T” during which the multimeter measures the instantaneous currents, integrates them, and then displays the average current for the period ”T”. For accurate measurements, the aperture of the multimeter should be set to be the same as the advertising or the connection interval. The following tables gives the current values for VBAT and VDDIO in various scenarios. Note that the current is averaged over 10-second intervals.

Table 2. CYW20819 Current in Different Modes

State ePDS Enabled ePDS Enabled ePDS Disabled ePDS Disabled
VDDIO VBAT VDDIO VBAT
No Bluetooth activity 2.1 uA 7.7 uA 47.9 uA 0.97 mA
ADV (2.56 s interval) 2.3 uA 26.1 uA 47.9 uA 0.98 mA
Connection (100 ms connection interval) 3.2 uA 147.2 uA 47.9 uA 1.02 mA
Notifications (5 s interval) 3.3 uA 148.3 uA 47.9 uA 1.02 mA

Table 3. Current in HID-Off Mode

State VDDIO VBAT
HID-Off 2.2 uA 0.7 uA
Connection Interval ePDS Enabled ePDS Enabled ePDS Disabled ePDS Disabled
VDDIO VBAT VDDIO VBAT
7.5 ms 14.5 uA 1.49 mA 47.9 uA 1.58 mA
10 ms 11.3 uA 1.16 mA 47.9 uA 1.43 mA
11.25 ms 10.2 uA 1.03 mA 47.9 uA 1.38 mA
12.5 ms 9.4 uA 0.92 mA 47.9 uA 1.34 mA
13.75 ms 9.9 uA 0.96 mA 47.9 uA 1.31 mA
15 ms 9.4 uA 0.89 mA 47.9 uA 1.28 mA
25 ms 6.6 uA 0.54 mA 47.9 uA 1.17 mA
50 ms 4.4 uA 0.27 mA 47.9 uA 1.08 mA
100 ms 3.2 uA 0.14 mA 47.9 uA 1.03 mA
500 ms 2.31 uA 0.04 Ma 47.9 uA 0.98 mA
1000 ms 2.2 uA 0.02 mA 47.9 uA 0.98 mA
2000 ms 2.2 uA 0.02 mA 47.9 uA 0.98 mA
4000 ms 2.1 uA 0.02 mA 47.9 uA 0.97 mA

Note that these current values also include the leakage current on the board because some GPIOs connected to the on-board components draw current. For accurate current numbers, see the device datasheet.

Resources and Settings

This example uses the default device configurator settings i.e., when this example is imported to ModusToolbox, the IDE creates the design.modus file (used for design configuration with default settings for the kit). Note that in the design.modus file, the SPI and I2C modules are enabled, but because these are not used in the application, they will not cause any current leakage. It also provides the GATT database files so that you don't have to generate the files.

Reusing This Example

This example is designed in a way so that you can use the low-power functions from this example in your own example with minimal changes.

Code Example

The low-power demo application demonstrates the low-power modes PDS and HID-OFF in CYW20819 on the CYW920819EVB-02 board. The application enters PDS mode immediately after boot. It advertises itself when the SW3 switch is pressed, and establishes a connection. After disconnection, the device enters HID-OFF mode for 10 seconds and then starts executing from the beginning.

BLE Initialization

BLE Initialization (low_power_20819.c)

/* Initialize Bluetooth Controller and Host Stack */
if(WICED_BT_SUCCESS != wiced_bt_stack_init(low_power_20819_management_callback, &wiced_bt_cfg_settings, wiced_bt_cfg_buf_pools))
{
       WICED_BT_TRACE("Stack initialization failed\r\n");
}

The wiced_bt_stack_init() function initializes the Bluetooth controller and stack, along with registering a callback for Bluetooth event notifications.

The function return value is wiced_result_t, which will return WICED_BT_SUCCESS on successful initialization of the BT stack and WICED_BT_FAILED if an error occurs.

The callback low_power_20819_management_callback is called to handle BLE stack events and processes.

Main Loop

Main Loop (low_power_20819_ble.c)


wiced_bt_dev_status_t low_power_20819_management_callback( wiced_bt_management_evt_t event, wiced_bt_management_evt_data_t *p_event_data )
{
switch (event)
    {
    case BTM_ENABLED_EVT:
        /* Bluetooth Controller and Host Stack Enabled */
        if (WICED_BT_SUCCESS == p_event_data->enabled.status)
        {
            /* Bluetooth is enabled */
            wiced_bt_dev_read_local_addr(bda);

            /* Perform application-specific initialization */
            low_power_20819_app_init();
        }
        break;
    case BTM_DISABLED_EVT:
        /* Bluetooth Controller and Host Stack Disabled */
        break;
    case BTM_SECURITY_REQUEST_EVT:
        /* Security Request */
        wiced_bt_ble_security_grant(p_event_data->security_request.bd_addr, WICED_BT_SUCCESS);
        break;
    case BTM_PAIRING_IO_CAPABILITIES_BLE_REQUEST_EVT:
        /* Request for Pairing IO Capabilities (BLE) */
        p_event_data->pairing_io_capabilities_ble_request.local_io_cap = BTM_IO_CAPABILITIES_NONE;
        p_event_data->pairing_io_capabilities_ble_request.oob_data = BTM_OOB_NONE;
        p_event_data->pairing_io_capabilities_ble_request.auth_req = BTM_LE_AUTH_REQ_SC_ONLY;
        p_event_data->pairing_io_capabilities_ble_request.max_key_size = 0x10;
        p_event_data->pairing_io_capabilities_ble_request.init_keys = 0;
        p_event_data->pairing_io_capabilities_ble_request.resp_keys = BTM_LE_KEY_PENC|BTM_LE_KEY_PID;
        break;
    case BTM_PAIRING_COMPLETE_EVT:
        /* Pairing is Complete */
        p_ble_info = &p_event_data->pairing_complete.pairing_complete_info.ble;
        break;
    case BTM_ENCRYPTION_STATUS_EVT:
        /* Encryption Status Change */
        WICED_BT_TRACE("Encryption Status event: bd ( %B ) res %d\r\n", p_event_data->encryption_status.bd_addr, p_event_data->encryption_status.result);
        break;
    case BTM_PAIRED_DEVICE_LINK_KEYS_REQUEST_EVT:
        /* Paired Device Link Keys Request */
        WICED_BT_TRACE("Paired Device Link Request Keys Event\r\n");
        status = WICED_BT_ERROR;
        break;
    case BTM_LOCAL_IDENTITY_KEYS_UPDATE_EVT:
        /* Local identity Keys Update */
        WICED_BT_TRACE("Local Identity Update Keys Event\r\n");
        status = WICED_BT_ERROR;
        break;
    case BTM_LOCAL_IDENTITY_KEYS_REQUEST_EVT:
        /* Local identity Keys Request */
        WICED_BT_TRACE("Local Identity Request Keys Event\r\n");
        status = WICED_BT_ERROR;
        break;
    case BTM_BLE_ADVERT_STATE_CHANGED_EVT:
        /* Advertisement State Changed */
        p_adv_mode = &p_event_data->ble_advert_state_changed;
        break;
    case BTM_BLE_CONNECTION_PARAM_UPDATE:
        /* Connection parameters updated */
        if(WICED_SUCCESS == p_event_data->ble_connection_param_update.status)
        {
            WICED_BT_TRACE("New connection parameters:\n\rConnection interval = %d\n\rConnection latency = %d\n\rSupervision timeout = %d",
                    ((p_event_data->ble_connection_param_update.conn_interval)),
                    p_event_data->ble_connection_param_update.conn_latency,
                    ((p_event_data->ble_connection_param_update.supervision_timeout)));
        }
        break;
    default:
        WICED_BT_TRACE("Unhandled Bluetooth Management Event: 0x%x (%d)\r\n", event, event);
        break;
    }
}

The BTM_ENABLED_EVT event is triggered once BLE stack initialization is complete. When this event occurs, the Bluetooth address of the device will be read using wiced_bt_dev_read_local_addr(bda); the main application will start executing by calling the low_power_20819_app_init() function. In low_power_20819_app_init(), a button callback button_cb () will be registered. The current time will be received and a timer will be initialized. wiced_bt_gatt_register() function is also called for registering GATT events.

The BTM_DISABLED_EVT event occurs when the Bluetooth controller and host stack is disabled.

The BTM_SECURITY_REQUEST_EVT event occurs when the client requests a secure connection. When this event occurs, wiced_bt_ble_security_grant() is called to establish a secure connection.

The BTM_PAIRING_IO_CAPABILITIES_BLE_REQUEST_EVT event occurs when the client queries for the type of capability that the device has that will allow validation of the connection.

The BTM_PAIRING_COMPLETE_EVT event indicates that pairing has been completed successfully. Information about the paired device such as its BD_ADDR should be saved in NVRAM at this point.

The BTM_ENCRYPTION_STATUS_EVT occurs when the secure link is established. Previously saved information such as paired device BD_ADDR and notify settings are read. If no device has been previously bonded, this will return all 0s.

The BTM_PAIRED_DEVICE_LINK_KEYS_REQUEST_EVT event is called by the stack so that the firmware can load the paired device's keys from NVRAM. If keys are not available, this state must return WICED_BT_ERROR. That return value causes the stack to generate keys and then it will call the corresponding update event so that the new keys can be saved in NVRAM.

The BTM_LOCAL_IDENTITY_KEYS_UPDATE_EVT event is called if reading of the privacy keys from NVRAM failed (i.e., the return value from BTM_LOCAL_IDENTITY_KEYS_REQUEST_EVT was not 0). During this event, the privacy keys must be saved to NVRAM.

When the BTM_LOCAL_IDENTITY_KEYS_REQUEST_EVT event occurs, the firmware must load the privacy keys from NVRAM.

The BTM_BLE_ADVERT_STATE_CHANGED_EVT event is called when the advertisement state switching happens. For fast advertisement, you will see return value 3 indicating BTM_BLE_ADVERT_UNDIRECTED_HIGH advertisement mode. Similarly, when advertisement stops, BTM_BLE_ADVERT_OFF mode will be called with return value 0.

The BTM_BLE_CONNECTION_PARAM_UPDATE function is called after the connection is established and connection parameters like BD address, connection interval, etc. are updated.

GATT Event Handler

GATT Event Handler (low_power_20819_ble.c)


wiced_bt_gatt_status_t low_power_20819_event_handler( wiced_bt_gatt_evt_t event, wiced_bt_gatt_event_data_t *p_event_data )
{
switch ( event )
{
    case GATT_CONNECTION_STATUS_EVT:
        status = low_power_20819_connect_callback( &p_event_data->connection_status);
        break;
    case GATT_ATTRIBUTE_REQUEST_EVT:
        p_attr_req = &p_event_data->attribute_request;
  status = low_power_20819_server_callback( p_attr_req->conn_id,   p_attr_req>request_type, &p_attr_req->data );
        break;
    default:
        WICED_BT_TRACE("Unhandled GATT Event: 0x%x (%d)\r\n", event, event);
        status = WICED_BT_GATT_SUCCESS;
        break;
}
}

The low_power_20819_event_handler() is called after BT stack initialization to handle GATT events from the BT stack. The function returns the GATT status wiced_bt_gatt_status_t with different GATT codes. For example, WICED_BT_GATT_INVALID_HANDLE is returned with value '1', indicating an invalid handle. For a complete list of codes, see wiced_bt_gatt.h.

The GATT_CONNECTION_STATUS_EVT event is triggered when the GATT connection status is changed. The function low_power_20819_connect_callback() will be called to check the connection status with a particular connection ID. If the device is in the connected state, the connection parameters will be updated. If a disconnection occurs, the device will enter HID-OFF mode by calling the function low_power_20819_enter_hid_off().

The GATT_ATTRIBUTE_REQUEST_EVT event is called when a GATT read event GATTS_REQ_TYPE_READ or a GATT write event GATTS_REQ_TYPE_WRITE occurs. Thelow_power_20819_read_handler() function will be called after a read request, which will call the function low_power_20819_get_value(). This function searches the GATT DB for the specified handle passes on the value. When a write request occurs, low_power_20819_write_handler() will be called; depending on the battery level configuration, timer functioning will occur.

Button Callback

Button Callback (low_power_20819_ble.c):

void button_cb (void* user_data, uint8_t value )
{
switch(low_power_20819_current_state)
{
    case SLEEP_WITHOUT_BLE:
        /* If the device is sleeping without any activity, start ADV */
        /* Set Advertisement Data */
        low_power_20819_set_advertisement_data();

        wiced_bt_start_advertisements(BTM_BLE_ADVERT_UNDIRECTED_LOW, 0, NULL);

        low_power_20819_current_state = SLEEP_WITH_ADV;
        break;

    case SLEEP_WITH_CONNECTION:

        /* If the device is in connection, disconnect and got to HID-Off */
        disconnect_status = wiced_bt_gatt_disconnect(low_power_20819_conn_id);
        break;
    default:
        break;
}
}

The button_cb() function will be called after SW3 is pressed. Depending on the current status of the device, the following functionality will take place: