Data streaming between two BLE devices: PSoc6 and nRF52832
Published at September 10, 2022 · Last Modified at September 13, 2022 · 3 min read · Tags: ble iot zephyr
Data streaming between two BLE devices: PSoc6 and nRF52832
Published at September 10, 2022 · Last Modified at September 13, 2022 · 3 min read · Tags: ble iot zephyr
I had a project where I had to stream data between two BLE devices. The data source was connected to PSoc6 and sent using its BLE transceiver to the destination device, nRF52832. Usually but not must, the peripheral devices are used as a GATT client, and the central machines are used as a GATT server. Therefore, I set the PSoc6 (The data source) as the central device (client) and the nRF52832 as the peripheral device (server). This setup is convenient for timing a new data packet and sending it whenever possible.
In this section, I present the BLE settings on PSoc6 as a central device/ For doing it, I had to follow the teachings on this video, and I summarized them in this section.
To parse the advertising stream, I have used the same function from the function from here.
void find_adv_info(uint8_t *adv, uint8_t len) {
memset ((void*)&adv_info, 0, sizeof(struct adv_info));
for (uint8_t i=0;i < len;){
switch (adv[i+1]) {
case 0x07:// servce uuid
adv_info.serviceUUID = &adv[i+2];
adv_info.servUUID_len = adv[i] - 1;
break;
case 0x09: // name
adv_info.name = (char*)&adv[i+2];
adv_info.name_len = adv[i] - 1;
break;
}
i = i + adv[i] + 1;
}
}
The main BLE task, the one that runs that BLE stack, looks like that:
struct adv_info {
char *name;
int name_len;
uint8_t *serviceUUID;
uint8_t servUUID_len;
} adv_info;
void ble_task(void *arg)
{
(void)arg;
Cy_BLE_Start(customEventHandler);
while (Cy_BLE_GetState() != CY_BLE_STATE_ON)
{
Cy_BLE_ProcessEvents();
}
Cy_BLE_RegisterAppHostCallback(ble_irq);
// Cy_BLE_RegisterAttCallback(ias_event);
for(;;)
{
uint32_t ulNotifiedValue = ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
Cy_BLE_ProcessEvents();
}
}
Where ble_irq looks like this:
static __inline void ble_irq(void)
{
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
if (xBLETaskHandle != 0) {
vTaskNotifyGiveFromISR( xBLETaskHandle, &xHigherPriorityTaskWoken );
portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
}
}
And the custom event handle looks like a witch case function that responds to GATT client events. Here are some useful events:
void customEventHandler(uint32_t event, void *eventParameter)
{
cy_stc_ble_gatts_write_cmd_req_param_t *writeReqParameter;
switch (event)
{
.....
}
}
case CY_BLE_EVT_STACK_ON:
case CY_BLE_EVT_GAP_DEVICE_DISCONNECTED:
{
Cy_BLE_GAPC_StartScan(CY_BLE_SCANNING_FAST, 0);
break;
}
In this sample, I detected the device by its name “Nordic.” The better way to do it is by the UUID.
case CY_BLE_EVT_GAPC_SCAN_PROGRESS_RESULT:
{
cy_stc_ble_gapc_adv_report_param_t *scan_progress_param = (cy_stc_ble_gapc_adv_report_param_t*)eventParameter;
if (memcmp(adv_info.name,"Nordic",5) ==0) {
cy_stc_ble_gap_bd_addr_t connected_addr;
memcpy(&connected_addr.bdAddr[0], &scan_progress_param->peerBdAddr[0], CY_BLE_GAP_BD_ADDR_SIZE);
connected_addr.type = scan_progress_param->peerAddrType;
Cy_BLE_GAPC_ConnectDevice(&connected_addr, 0);
Cy_BLE_GAPC_StopScan();
}
break;
}
case CY_BLE_EVT_GATT_CONNECT_IND:
{
cy_en_ble_api_result_t res;
cy_stc_ble_gatt_xchg_mtu_param_t p;
p.connHandle = (cy_ble_connHandle[0]);
p.mtu = 400;
res = Cy_BLE_GATTC_ExchangeMtuReq(&p);
break;
}
void customEventHandler(uint32_t event, void *eventParameter)
{
cy_stc_ble_gatts_write_cmd_req_param_t *writeReqParameter;
switch (event)
{
case CY_BLE_EVT_GATTC_DISCOVERY_COMPLETE:
{
break;
}
case CY_BLE_EVT_GATTC_ERROR_RSP:
{
break;
}
case CY_BLE_EVT_GATTC_WRITE_RSP:
break;
case CY_BLE_EVT_GATTC_XCHNG_MTU_RSP :
break;
}
The device is set up to be a central device. So I change the parameters of MTU (maximum transfer unit) to be at maximum. So the MTU parameter has a direct influent on the data rate.
The clock setting was defined as presented in the following figure. Refer here for more details.
I have used the same work details I allready did in this.
[1] zephyr Bluetooth APIs
[2] https://infineon.github.io/bless/ble_api_reference_manual/html/
[3] A Practical Guide to BLE Throughput