Designing low-power, cloud-connected IoT devices with PSoC® 6 MCU’s and WICED® Wi-Fi/Bluetooth

Summary

Although I a like the video game, it is for sure missing something.  That something is IoT.  The first IoT thing that we will do to the game is to add a BLE remote control.  I wanted a pre-done remote control that could be downloaded from the App store.  After looking around a little bit I found GoBle.  I published a detailed article about GoBle here, but I’ll explain enough to make it work with the game.

Here is a screen shot of what the remote control looks like.  You can see that on the left there is a joystick, and on the right there are some buttons.  My son tells me that this is a classic layout for a remote control.

This remote control works as a “Central” meaning it knows how to connect to Peripherals.  For this lesson we will turn on the CYW4343W and make it be a Bluetooth Peripheral.

To implement this lesson I will follow these steps:

  1. Create a folder called “L5GoBle”
  2. Create a makefile called L5GoBle.mk
  3. Setup a GATT database by creating GoBle_db.h and GoBle_db.c
  4. Setup wiced_bt_cfg.c
  5. Create GoBleThread.c
  6. Create GoBle.c to startup the GoBleThread
  7. Build, Program and Test

Create a directory called “L5GoBle”

Create a makefile called L5GoBle.mk

NAME := App_WStudio_L5GoBle

$(NAME)_SOURCES    := GoBle.c \
			          GoBleThread.c \
                      GoBle_db.c \
                      wiced_bt_cfg.c

$(NAME)_INCLUDES   := .

$(NAME)_COMPONENTS += libraries/drivers/bluetooth/low_energy 

Setup a GATT database by creating GoBle_db.h and GoBle_db.c

Create a file called “GoBle_db.h”

// GoBle_db.h

#ifndef __GATT_DATABASE_H__
#define __GATT_DATABASE_H__

#include "wiced.h"

#define __UUID_GOBLE                                 0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0xb0, 0xdf, 0x00, 0x00
#define __UUID_GOBLE_SERIALPORTID                    0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80, 0x00, 0x10, 0x00, 0x00, 0xb1, 0xdf, 0x00, 0x00

// ***** Primary Service 'Generic Attribute'
#define HDLS_GENERIC_ATTRIBUTE                       0x0001

// ***** Primary Service 'Generic Access'
#define HDLS_GENERIC_ACCESS                          0x0014
// ----- Characteristic 'Device Name'
#define HDLC_GENERIC_ACCESS_DEVICE_NAME              0x0015
#define HDLC_GENERIC_ACCESS_DEVICE_NAME_VALUE        0x0016
// ----- Characteristic 'Appearance'
#define HDLC_GENERIC_ACCESS_APPEARANCE               0x0017
#define HDLC_GENERIC_ACCESS_APPEARANCE_VALUE         0x0018

// ***** Primary Service 'GoBle'
#define HDLS_GOBLE                                   0x0028
// ----- Characteristic 'SerialPortId'
#define HDLC_GOBLE_SERIALPORTID                      0x0029
#define HDLC_GOBLE_SERIALPORTID_VALUE                0x002A
// ===== Descriptor 'Client Configuration'
#define HDLD_GOBLE_SERIALPORTID_CLIENT_CONFIGURATION 0x002B


// External definitions
extern const uint8_t  gatt_database[];
extern const uint16_t gatt_database_len;
extern uint8_t BT_LOCAL_NAME[];
extern const uint16_t BT_LOCAL_NAME_CAPACITY;

#endif /* __GATT_DATABASE_H__ */

Create a file called “GoBle.c”

/*
 * This file has been automatically generated by the WICED 20719-B1 Designer.
 * BLE device's GATT database and device configuration.
 *
 */

// GoBle_db.c

#include "GoBle_db.h"

#include "wiced.h"
#include "wiced_bt_uuid.h"
#include "wiced_bt_gatt.h"

/*************************************************************************************
** GATT server definitions
*************************************************************************************/

const uint8_t gatt_database[] = // Define GATT database
{
    /* Primary Service 'Generic Attribute' */
    PRIMARY_SERVICE_UUID16 (HDLS_GENERIC_ATTRIBUTE, UUID_SERVICE_GATT),

    /* Primary Service 'Generic Access' */
    PRIMARY_SERVICE_UUID16 (HDLS_GENERIC_ACCESS, UUID_SERVICE_GAP),

    /* Primary Service 'GoBle' */
    PRIMARY_SERVICE_UUID128 (HDLS_GOBLE, __UUID_GOBLE),

        /* Characteristic 'SerialPortId' */
        CHARACTERISTIC_UUID128_WRITABLE (HDLC_GOBLE_SERIALPORTID, HDLC_GOBLE_SERIALPORTID_VALUE,
            __UUID_GOBLE_SERIALPORTID, LEGATTDB_CHAR_PROP_READ | LEGATTDB_CHAR_PROP_WRITE_NO_RESPONSE | LEGATTDB_CHAR_PROP_WRITE | LEGATTDB_CHAR_PROP_NOTIFY,
            LEGATTDB_PERM_READABLE | LEGATTDB_PERM_WRITE_CMD | LEGATTDB_PERM_WRITE_REQ),

            /* Descriptor 'Client Characteristic Configuration' */
            CHAR_DESCRIPTOR_UUID16_WRITABLE (HDLD_GOBLE_SERIALPORTID_CLIENT_CONFIGURATION,
                UUID_DESCRIPTOR_CLIENT_CHARACTERISTIC_CONFIGURATION, LEGATTDB_PERM_READABLE | LEGATTDB_PERM_WRITE_REQ | LEGATTDB_PERM_AUTH_WRITABLE),

};

// Length of the GATT database
const uint16_t gatt_database_len = sizeof(gatt_database);

Setup wiced_bt_cfg.c

The WICED Bluetooth Configuration file is called “wiced_bt_config.c”.  The only change I made from the default is the timeout value of the advertising.  You can copy this directly into your file.

/*
 * This file has been automatically generated by the WICED 20719-B1 Designer.
 * Device Configuration.
 *
 */

/** wiced_bt_cfg.c
 *
 * Runtime Bluetooth stack configuration parameters
 *
 */

#include "wiced_bt_dev.h"
#include "wiced_bt_ble.h"
#include "wiced_bt_uuid.h"
#include "wiced_bt_gatt.h"
#include "wiced_bt_avrc.h"
#include "wiced_bt_cfg.h"

/* Null-Terminated Local Device Name */
uint8_t BT_LOCAL_NAME[] = { 'G','o','B','l','e','T','e','s','t','\0' };
const uint16_t BT_LOCAL_NAME_CAPACITY = sizeof(BT_LOCAL_NAME);


/*******************************************************************
 * wiced_bt core stack configuration
 ******************************************************************/
const wiced_bt_cfg_settings_t wiced_bt_cfg_settings =
{
    .device_name =                          (uint8_t*)BT_LOCAL_NAME,                                    /**< Local device name (NULL terminated) */
    .device_class =                         {0x00, 0x00, 0x00},                                         /**< Local device class */
    .security_requirement_mask =            BTM_SEC_NONE,                                               /**< Security requirements mask (BTM_SEC_NONE, or combination of BTM_SEC_IN_AUTHENTICATE, BTM_SEC_OUT_AUTHENTICATE, BTM_SEC_ENCRYPT */
    .max_simultaneous_links =               1,                                                          /**< Maximum number of simultaneous links to different devices */

    /* BR/EDR Scan Configuration */
    .br_edr_scan_cfg = {
        .inquiry_scan_type =                BTM_SCAN_TYPE_STANDARD,                                     /**< Inquiry Scan Type (BTM_SCAN_TYPE_STANDARD or BTM_SCAN_TYPE_INTERLACED) */
        .inquiry_scan_interval =            0x0000,                                                     /**< Inquiry Scan Interval (0 to use default) */
        .inquiry_scan_window =              0x0000,                                                     /**< Inquiry Scan Window (0 to use default) */

        .page_scan_type =                   BTM_SCAN_TYPE_STANDARD,                                     /**< Page Scan Type (BTM_SCAN_TYPE_STANDARD or BTM_SCAN_TYPE_INTERLACED) */
        .page_scan_interval =               0x0000,                                                     /**< Page Scan Interval (0 to use default) */
        .page_scan_window =                 0x0000,                                                     /**< Page Scan Window (0 to use default) */
    },

    /* BLE Scan Settings */
    .ble_scan_cfg = {
        .scan_mode =                        BTM_BLE_SCAN_MODE_PASSIVE,                                  /**< BLE Scan Mode (BTM_BLE_SCAN_MODE_PASSIVE or BTM_BLE_SCAN_MODE_ACTIVE) */

        /* Advertisement Scan Configuration */
        .high_duty_scan_interval =          WICED_BT_CFG_DEFAULT_HIGH_DUTY_SCAN_INTERVAL,               /**< High Duty Scan Interval */
        .high_duty_scan_window =            WICED_BT_CFG_DEFAULT_HIGH_DUTY_SCAN_WINDOW,                 /**< High Duty Scan Window */
        .high_duty_scan_duration =          5,                                                          /**< High Duty Scan Duration in seconds (0 for infinite) */

        .low_duty_scan_interval =           WICED_BT_CFG_DEFAULT_LOW_DUTY_SCAN_INTERVAL,                /**< Low Duty Scan Interval */
        .low_duty_scan_window =             WICED_BT_CFG_DEFAULT_LOW_DUTY_SCAN_WINDOW,                  /**< Low Duty Scan Window */
        .low_duty_scan_duration =           5,                                                          /**< Low Duty Scan Duration in seconds (0 for infinite) */

        /* Connection Scan Configuration */
        .high_duty_conn_scan_interval =     WICED_BT_CFG_DEFAULT_HIGH_DUTY_CONN_SCAN_INTERVAL,          /**< High Duty Connection Cycle Connection Scan Interval */
        .high_duty_conn_scan_window =       WICED_BT_CFG_DEFAULT_HIGH_DUTY_CONN_SCAN_WINDOW,            /**< High Duty Connection Cycle Connection Scan Window */
        .high_duty_conn_duration =          30,                                                         /**< High Duty Connection Cycle Connection Duration in seconds (0 for infinite) */

        .low_duty_conn_scan_interval =      WICED_BT_CFG_DEFAULT_LOW_DUTY_CONN_SCAN_INTERVAL,           /**< Low Duty Connection Cycle Connection Scan Interval */
        .low_duty_conn_scan_window =        WICED_BT_CFG_DEFAULT_LOW_DUTY_CONN_SCAN_WINDOW,             /**< Low Duty Connection Cycle Connection Scan Window */
        .low_duty_conn_duration =           30,                                                         /**< Low Duty Connection Cycle Connection Duration in seconds (0 for infinite) */

        /* Connection Configuration */
        .conn_min_interval =                WICED_BT_CFG_DEFAULT_CONN_MIN_INTERVAL,                     /**< Minimum Connection Interval */
        .conn_max_interval =                WICED_BT_CFG_DEFAULT_CONN_MAX_INTERVAL,                     /**< Maximum Connection Interval */
        .conn_latency =                     WICED_BT_CFG_DEFAULT_CONN_LATENCY,                          /**< Connection Latency */
        .conn_supervision_timeout =         WICED_BT_CFG_DEFAULT_CONN_SUPERVISION_TIMEOUT,              /**< Connection Link Supervision Timeout */
    },

    /* BLE Advertisement Settings */
    .ble_advert_cfg = {
        .channel_map =                      BTM_BLE_ADVERT_CHNL_37 |                                    /**< Advertising Channel Map (mask of BTM_BLE_ADVERT_CHNL_37, BTM_BLE_ADVERT_CHNL_38, BTM_BLE_ADVERT_CHNL_39) */
                                            BTM_BLE_ADVERT_CHNL_38 |
                                            BTM_BLE_ADVERT_CHNL_39,

        .high_duty_min_interval =           WICED_BT_CFG_DEFAULT_HIGH_DUTY_ADV_MIN_INTERVAL,            /**< High Duty Undirected Connectable Minimum Advertising Interval */
        .high_duty_max_interval =           WICED_BT_CFG_DEFAULT_HIGH_DUTY_ADV_MAX_INTERVAL,            /**< High Duty Undirected Connectable Maximum Advertising Interval */
        .high_duty_duration =               0,                                                         /**< High Duty Undirected Connectable Advertising Duration in seconds (0 for infinite) */

        .low_duty_min_interval =            WICED_BT_CFG_DEFAULT_LOW_DUTY_ADV_MIN_INTERVAL,             /**< Low Duty Undirected Connectable Minimum Advertising Interval */
        .low_duty_max_interval =            WICED_BT_CFG_DEFAULT_LOW_DUTY_ADV_MAX_INTERVAL,             /**< Low Duty Undirected Connectable Maximum Advertising Interval */
        .low_duty_duration =                60,                                                         /**< Low Duty Undirected Connectable Advertising Duration in seconds (0 for infinite) */

        .high_duty_directed_min_interval =  WICED_BT_CFG_DEFAULT_HIGH_DUTY_DIRECTED_ADV_MIN_INTERVAL,   /**< High Duty Directed Minimum Advertising Interval */
        .high_duty_directed_max_interval =  WICED_BT_CFG_DEFAULT_HIGH_DUTY_DIRECTED_ADV_MAX_INTERVAL,   /**< High Duty Directed Maximum Advertising Interval */

        .low_duty_directed_min_interval =   WICED_BT_CFG_DEFAULT_LOW_DUTY_DIRECTED_ADV_MIN_INTERVAL,    /**< Low Duty Directed Minimum Advertising Interval */
        .low_duty_directed_max_interval =   WICED_BT_CFG_DEFAULT_LOW_DUTY_DIRECTED_ADV_MAX_INTERVAL,    /**< Low Duty Directed Maximum Advertising Interval */
        .low_duty_directed_duration =       30,                                                         /**< Low Duty Directed Advertising Duration in seconds (0 for infinite) */

        .high_duty_nonconn_min_interval =   WICED_BT_CFG_DEFAULT_HIGH_DUTY_NONCONN_ADV_MIN_INTERVAL,    /**< High Duty Non-Connectable Minimum Advertising Interval */
        .high_duty_nonconn_max_interval =   WICED_BT_CFG_DEFAULT_HIGH_DUTY_NONCONN_ADV_MAX_INTERVAL,    /**< High Duty Non-Connectable Maximum Advertising Interval */
        .high_duty_nonconn_duration =       30,                                                         /**< High Duty Non-Connectable Advertising Duration in seconds (0 for infinite) */

        .low_duty_nonconn_min_interval =    WICED_BT_CFG_DEFAULT_LOW_DUTY_NONCONN_ADV_MIN_INTERVAL,     /**< Low Duty Non-Connectable Minimum Advertising Interval */
        .low_duty_nonconn_max_interval =    WICED_BT_CFG_DEFAULT_LOW_DUTY_NONCONN_ADV_MAX_INTERVAL,     /**< Low Duty Non-Connectable Maximum Advertising Interval */
        .low_duty_nonconn_duration =        0,                                                          /**< Low Duty Non-Connectable Advertising Duration in seconds (0 for infinite) */
    },

    /* GATT Configuration */
    .gatt_cfg = {
        .appearance =                       0x0000,                                                     /**< GATT Appearance */
        .client_max_links =                 1,                                                          /**< Client Config: Maximum number of servers that local client can connect to */
        .server_max_links =                 1,                                                          /**< Server Config: Maximum number of remote client connections allowed by local server */
        .max_attr_len =                     512,                                                        /**< Maximum attribute length; wiced_bt_cfg must have a corresponding buffer pool that can hold this length */
        .max_mtu_size =                     515,                                                        /**< Maximum MTU size for GATT connections, should be between 23 and (max_attr_len + 5) */
    },

    /* RFCOMM Configuration */
    .rfcomm_cfg = {
        .max_links =                        0,                                                          /**< Maximum number of simultaneous connected remote devices */
        .max_ports =                        0,                                                          /**< Maximum Number of simultaneous RFCOMM ports */
    },

    /* Application-Managed L2CAP Protocol Configuration */
    .l2cap_application = {
        .max_links =                        0,                                                          /**< Maximum Number of Application-Managed L2CAP Links (BR/EDR and BLE) */
        .max_psm =                          0,                                                          /**< Maximum Number of Application-Managed BR/EDR PSMs */
        .max_channels =                     0,                                                          /**< Maximum Number of Application-Managed BR/EDR Channels */
        .max_le_psm =                       0,                                                          /**< Maximum Number of Application-Managed LE PSMs */
        .max_le_channels =                  0,                                                          /**< Maximum Number of Application-Managed LE Channels */
        .max_le_l2cap_fixed_channels =      0,                                                          /**< Maximum Number of Application-Managed LE L2CAP Fixed Channnels supported (in addition to mandatory channels 4, 5, and 6 */
    },

    /* Audio/Video Distribution Configuration */
    .avdt_cfg = {
        .max_links =                        0,                                                          /**< Maximum Number of simultaneous Audio/Video links */
        .max_seps =                         0,                                                          /**< Maximum Number of stream end points */
    },

    /* AVRC Configuration */
    .avrc_cfg = {
        .roles =                            0,                                                          /**< Local Roles supported (AVRC_CONN_INITIATOR or AVRC_CONN_ACCEPTOR) */
        .max_links =                        0,                                                          /**< Maximum simultaneous Remote Control links */
    },

    /* LE Address Resolution Database Settings */
    .addr_resolution_db_size =              10,                                                         /**< LE Address Resolution Database Size - Effective only for pre-4.2 controller */
    .max_number_of_buffer_pools =           4,                                                          /**< Maximum number of buffer pools in p_btm_cfg_buf_pools and by wiced_create_pool */
    .rpa_refresh_timeout =                  0,         /**< Interval of random address refreshing - secs */
};

/*******************************************************************
 * wiced_bt_stack buffer pool configuration
 *
 * Configure buffer pools used by the stack
 *
 * Pools must be ordered in increasing buf_size.
 * If a pools runs out of buffers, the next pool will be used.
 ******************************************************************/
const wiced_bt_cfg_buf_pool_t wiced_bt_cfg_buf_pools[WICED_BT_CFG_NUM_BUF_POOLS] =
{
/*  { buf_size, buf_count, }, */
    { 64,       12,        }, /* Small Buffer Pool */
    { 360,      4,         }, /* Medium Buffer Pool (used for HCI & RFCOMM control messages, min recommended size is 360) */
    { 512,      4,         }, /* Large Buffer Pool  (used for HCI ACL messages) */
    { 1024,     2,         }, /* Extra Large Buffer Pool (used for AVDT media packets and miscellaneous; if not needed, set buf_count to 0) */
};

Create GoBleThread.c

In  order for the GoBleThread to work you need:

  1. The includes for the GATT Database and the WICED bluetooth stack.
  2. External References to the GATT Database.
  3. A few function prototypes.
  4. A function called “GoBleThread_start” to startup the Bluetooth stack and get things going. This includes providing Bluetooth management and GATT event handler functions.
#include "GoBle_db.h"
#include "wiced.h"
#include "wiced_bt_ble.h"
#include "wiced_bt_gatt.h"
#include "wiced_bt_stack.h"

/*******************************************************************
 * Variable Definitions
 ******************************************************************/
extern const wiced_bt_cfg_settings_t wiced_bt_cfg_settings;
extern const wiced_bt_cfg_buf_pool_t wiced_bt_cfg_buf_pools[WICED_BT_CFG_NUM_BUF_POOLS];

/*******************************************************************
 * Function Prototypes
 ******************************************************************/
static wiced_bt_dev_status_t  goble_management_callback    ( wiced_bt_management_evt_t event, wiced_bt_management_evt_data_t *p_event_data );
static void                   goble_set_advertisement_data ( void );
static wiced_bt_gatt_status_t goble_event_handler          ( wiced_bt_gatt_evt_t  event, wiced_bt_gatt_event_data_t *p_event_data );

/*******************************************************************
 * Function Definitions
 ******************************************************************/
void GoBleThread_start(void)
{
    wiced_bt_stack_init(goble_management_callback, &wiced_bt_cfg_settings, wiced_bt_cfg_buf_pools);
}

Create a function to setup the advertising data.  The GoBle iOS App looks for Peripherals that are advertising the UUID of the GoBLE Service.

/* Set Advertisement Data */
void goble_set_advertisement_data( void )
{
    wiced_bt_ble_advert_elem_t adv_elem[3] = { 0 };
    uint8_t adv_flag = BTM_BLE_GENERAL_DISCOVERABLE_FLAG | BTM_BLE_BREDR_NOT_SUPPORTED;
    uint8_t num_elem = 0; 

    /* Advertisement Element for Flags */
    adv_elem[num_elem].advert_type = BTM_BLE_ADVERT_TYPE_FLAG;
    adv_elem[num_elem].len = sizeof(uint8_t);
    adv_elem[num_elem].p_data = &adv_flag;
    num_elem++;

    uint8_t gobleuuid[] = {__UUID_GOBLE};

    /* Advertisement Element for Name */
    adv_elem[num_elem].advert_type = BTM_BLE_ADVERT_TYPE_128SRV_COMPLETE;
    adv_elem[num_elem].len = 16;
    adv_elem[num_elem].p_data = gobleuuid;
    num_elem++;

    /* Set Raw Advertisement Data */
    wiced_bt_ble_set_raw_advertisement_data(num_elem, adv_elem);
}

The Bluetooth Management Event Handler needs to take actions when the stack turns on, or one of the pairing events occur.

/* Bluetooth Management Event Handler */
wiced_bt_dev_status_t goble_management_callback( wiced_bt_management_evt_t event, wiced_bt_management_evt_data_t *p_event_data )
{
    wiced_bt_dev_status_t status = WICED_BT_SUCCESS;

    switch (event)
    {
    case BTM_ENABLED_EVT:
        goble_set_advertisement_data();
        wiced_bt_gatt_register( goble_event_handler );
        wiced_bt_gatt_db_init( gatt_database, gatt_database_len );
        wiced_bt_start_advertisements(BTM_BLE_ADVERT_UNDIRECTED_HIGH, 0, NULL);
        break;

    case BTM_SECURITY_REQUEST_EVT:
        wiced_bt_ble_security_grant(p_event_data->security_request.bd_addr, WICED_BT_SUCCESS);
        break;

    case BTM_PAIRING_IO_CAPABILITIES_BLE_REQUEST_EVT:
        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_NO_BOND;
        break;


    case BTM_USER_CONFIRMATION_REQUEST_EVT: // Just confirm
        wiced_bt_dev_confirm_req_reply( WICED_BT_SUCCESS , p_event_data->user_confirmation_request.bd_addr);
        break;

    case BTM_PAIRED_DEVICE_LINK_KEYS_REQUEST_EVT:
        WPRINT_APP_INFO(("Paired linke keys\n"));
        status = WICED_BT_ERROR;
        break;

    case BTM_LOCAL_IDENTITY_KEYS_REQUEST_EVT:
    case BTM_PAIRING_COMPLETE_EVT:
    case BTM_ENCRYPTION_STATUS_EVT:
    case BTM_BLE_ADVERT_STATE_CHANGED_EVT:
    case BTM_LPM_STATE_LOW_POWER:
        break;

    default:
        WPRINT_APP_INFO(("Unhandled Bluetooth Management Event: 0x%x (%d)\n", event, event));
        break;
    }

    return status;
}

The GATT Event Handler is called

  1. When a connection is made or terminated
  2. When the GoBle app writes to your GATT database.  When that happens we will just printout the value that was written
/* GATT Event Handler */
wiced_bt_gatt_status_t goble_event_handler( wiced_bt_gatt_evt_t event, wiced_bt_gatt_event_data_t *p_event_data )
{
    wiced_bt_gatt_status_t status = WICED_BT_GATT_ERROR;
    wiced_bt_gatt_attribute_request_t *p_attr_req = NULL;

    switch ( event )
    {
    case GATT_CONNECTION_STATUS_EVT:
        if(!p_event_data->connection_status.connected)
        {
            WPRINT_APP_INFO(("Disconnected\n"));
            wiced_bt_start_advertisements(BTM_BLE_ADVERT_UNDIRECTED_HIGH, 0, NULL);
        }
        else
            WPRINT_APP_INFO(("Connected\n"));
        break;
    case GATT_ATTRIBUTE_REQUEST_EVT:

        p_attr_req = &p_event_data->attribute_request;
        if( p_attr_req->request_type == GATTS_REQ_TYPE_WRITE  && p_attr_req->data.handle == HDLC_GOBLE_SERIALPORTID_VALUE)
        {
            uint32_t numButtons = p_attr_req->data.write_req.p_val[3];
            uint32_t sliderY = p_attr_req->data.write_req.p_val[5+numButtons];
            uint32_t sliderX = p_attr_req->data.write_req.p_val[6+numButtons];
            uint32_t buttonMask = 0x00;
            for(int i=0;i<numButtons;i++)
            {
                buttonMask |= (1<<p_attr_req->data.write_req.p_val[5+i]);
            }

            WPRINT_APP_INFO(("# Buttons = %d ButtonMask=%02X Slider x=%02X Slider Y=%02X Raw=",(int)numButtons,(unsigned int)buttonMask,(unsigned int)sliderX,(unsigned int)sliderY));

            for(int i=0;i<p_attr_req->data.write_req.val_len;i++)
            {
                WPRINT_APP_INFO(("%02X ",p_attr_req->data.write_req.p_val[i]));
            }
            WPRINT_APP_INFO(("\n"));
            status = WICED_BT_GATT_SUCCESS;
        }
        break;
    default:
        status = WICED_BT_GATT_SUCCESS;
        break;
    }

    return status;
}

Create GoBleThread.h

#pragma once

extern void GoBleThread_start(void);

Create GoBle.c to startup the GoBleThread

#include "GoBleThread.h"
#include "wiced.h"


/*******************************************************************
 * Function Definitions
 ******************************************************************/
void application_start(void)
{
    wiced_init();
    GoBleThread_start();

}

Build, Program and Test

Recommended Posts

2 Comments

  1. Hello,
    I’ve made simmilar project on PSOC 4 BLE based on your settings.
    I can connect to the PSoC 4 device and send data from CySmart:
    https://imgur.com/z0Hz9g0
    Infromation from CySmart :
    https://imgur.com/a/P8JotMi

    On iPhone I can see my device via CySmart but GoBle doesn’t see it.

    P.S. It would be nice to have possibility for attaching pictures to this form.

    • That should work…though I am not exactly sure to how to have a GATT only (no gattdb) on P4


Leave a Reply to Vasyl Yosypenko Cancel reply

Your email address will not be published. Required fields are marked *