【NUCLEO-WB09KE】BLE application architecture and analysis
[Copy link]
1. Test introduction
(1) Pre-test instructions
In order to understand the programming architecture of ST BLE devices, we started to test the applications provided by ST. At first, we used the "BLE_Peripheral_Lite" application for research, but the application failed to pair, so we gave up the application and used the BLE_p2pServer application for testing. So the following test is the analysis and test of this application.
(2) Hardware required for testing
PC host: System is Windows 10 version
USB Bluetooth adapter: The version is 5.4. It is recommended to use products that require a driver. Products that require a driver may have compatibility issues.
NUCLEO-WB09KE development board: The main chip is the STM32WB09KE chip, which is a low-power product ARM m0+ core
(3) Software required for testing
Bluetooth LE Eplorer: This software is a test product provided by Microsoft. Although its functions are general, it is quite practical. It can be obtained for free from the Microsoft App Store.
BLE_p2pServer: Demo program for STM32WB0. Use STM32CubeMX to copy
ComAssistant: can be downloaded from EE, the software is written by me
2. Testing process
(1) Download and install the Bluetooth LE Eplorer software
The software is relatively simple and can be used as soon as it is started.
(2) Burn BLE_p2pServer to the development board
Note: You need to set the jumper of the development board to the Boot Loader state.
Open the Keil software to compile the program, and if the development board can be connected, burn it.
After burning to the development board, power it on again.
Open the serial port connection to test the serial port baud rate: 115200, N, 8, 1
Press B3 to stop the system indicator from flashing, and press B1 to start the system connection state
(3) Connection pairing
Set the jumper of the development board to USER FLASH state
After pairing, you can find that the PIN codes of the devices are the same. If: multiple pairings are performed, you need to delete the device in Windows Device Management.
After pairing successfully
To operate, write 0101 to the device to turn on LED1, and write 0100 to turn off LED1
Write command
3. Program structure analysis
Device function parameters, the device contains three groups of "Service"
Service ID: UUID
SERVICE1
UUID:00001801-0000-1000-8000-00805f9b34fb
SERVICE2
UUID:00001800-0000-1000-8000-00805f9b34fb
SERVICE3
UUID:0000fe40-cc7a-482a-984a-7f2ed5b3e58f
#define P2P_SERVER_UUID 0x8f,0xe5,0xb3,0xd5,0x2e,0x7f,0x4a,0x98,0x2a,0x48,0x7a,0xcc,0x40,0xfe,0x00,0x00
#define LED_C_UUID 0x19,0xed,0x82,0xae,0xed,0x21,0x4c,0x9d,0x41,0x45,0x22,0x8e,0x41,0xfe,0x00,0x00
#define SWITCH_C_UUID 0x19,0xed,0x82,0xae,0xed,0x21,0x4c,0x9d,0x41,0x45,0x22,0x8e,0x42,0xfe,0x00,0x00
This is consistent with the program definition.
/* USER CODE BEGIN Header */
/**
******************************************************************************
* [url=home.php?mod=space&uid=1307177]@File[/url] p2p_server_app.c
* [url=home.php?mod=space&uid=1315547]@author[/url] MCD Application Team
* [url=home.php?mod=space&uid=159083]@brief[/url] p2p_server_app application definition.
******************************************************************************
* [url=home.php?mod=space&uid=1020061]@attention[/url] *
* Copyright (c) 2024 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "app_common.h"
#include "app_ble.h"
#include "ble.h"
#include "p2p_server_app.h"
#include "p2p_server.h"
#include "stm32_seq.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
typedef struct{
uint8_t Device_Led_Selection;
uint8_t Led1;
}P2P_LedCharValue_t;
typedef struct{
uint8_t Device_Button_Selection;
uint8_t ButtonStatus;
}P2P_ButtonCharValue_t;
/* USER CODE END PTD */
typedef enum
{
Switch_c_NOTIFICATION_OFF,
Switch_c_NOTIFICATION_ON,
/* USER CODE BEGIN Service1_APP_SendInformation_t */
/* USER CODE END Service1_APP_SendInformation_t */
P2P_SERVER_APP_SENDINFORMATION_LAST
} P2P_SERVER_APP_SendInformation_t;
typedef struct
{
P2P_SERVER_APP_SendInformation_t Switch_c_Notification_Status;
/* USER CODE BEGIN Service1_APP_Context_t */
P2P_LedCharValue_t LedControl;
P2P_ButtonCharValue_t ButtonControl;
/* USER CODE END Service1_APP_Context_t */
uint16_t ConnectionHandle;
} P2P_SERVER_APP_Context_t;
/* Private defines -----------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
/* External variables --------------------------------------------------------*/
/* USER CODE BEGIN EV */
/* USER CODE END EV */
/* Private macros ------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
static P2P_SERVER_APP_Context_t P2P_SERVER_APP_Context;
uint8_t a_P2P_SERVER_UpdateCharData[247];
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
static void P2P_SERVER_Switch_c_SendNotification(void);
/* USER CODE BEGIN PFP */
static void P2P_SERVER_APP_LED_BUTTON_context_Init(void);
/* USER CODE END PFP */
/* Functions Definition ------------------------------------------------------*/
void P2P_SERVER_Notification(P2P_SERVER_NotificationEvt_t *p_Notification)
{
/* USER CODE BEGIN Service1_Notification_1 */
/* USER CODE END Service1_Notification_1 */
switch(p_Notification->EvtOpcode)
{
/* USER CODE BEGIN Service1_Notification_Service1_EvtOpcode */
/* USER CODE END Service1_Notification_Service1_EvtOpcode */
case P2P_SERVER_LED_C_READ_EVT:
/* USER CODE BEGIN Service1Char1_READ_EVT */
/* USER CODE END Service1Char1_READ_EVT */
break;
case P2P_SERVER_LED_C_WRITE_NO_RESP_EVT:
/* USER CODE BEGIN Service1Char1_WRITE_NO_RESP_EVT */
if(p_Notification->DataTransfered.p_Payload[1] == 0x01)
{
BSP_LED_On(LED_BLUE);
APP_DBG_MSG("-- P2P APPLICATION SERVER : LED1 ON\n");
P2P_SERVER_APP_Context.LedControl.Led1 = 0x01; /* LED1 ON */
}
if(p_Notification->DataTransfered.p_Payload[1] == 0x00)
{
BSP_LED_Off(LED_BLUE);
APP_DBG_MSG("-- P2P APPLICATION SERVER : LED1 OFF\n");
P2P_SERVER_APP_Context.LedControl.Led1 = 0x00; /* LED1 OFF */
}
/* USER CODE END Service1Char1_WRITE_NO_RESP_EVT */
break;
case P2P_SERVER_SWITCH_C_NOTIFY_ENABLED_EVT:
/* USER CODE BEGIN Service1Char2_NOTIFY_ENABLED_EVT */
P2P_SERVER_APP_Context.Switch_c_Notification_Status = Switch_c_NOTIFICATION_ON;
APP_DBG_MSG("-- P2P APPLICATION SERVER : NOTIFICATION ENABLED\n");
APP_DBG_MSG(" \n\r");
/* USER CODE END Service1Char2_NOTIFY_ENABLED_EVT */
break;
case P2P_SERVER_SWITCH_C_NOTIFY_DISABLED_EVT:
/* USER CODE BEGIN Service1Char2_NOTIFY_DISABLED_EVT */
P2P_SERVER_APP_Context.Switch_c_Notification_Status = Switch_c_NOTIFICATION_OFF;
APP_DBG_MSG("-- P2P APPLICATION SERVER : NOTIFICATION DISABLED\n");
APP_DBG_MSG(" \n\r");
/* USER CODE END Service1Char2_NOTIFY_DISABLED_EVT */
break;
default:
/* USER CODE BEGIN Service1_Notification_default */
/* USER CODE END Service1_Notification_default */
break;
}
/* USER CODE BEGIN Service1_Notification_2 */
/* USER CODE END Service1_Notification_2 */
return;
}
void P2P_SERVER_APP_EvtRx(P2P_SERVER_APP_ConnHandleNotEvt_t *p_Notification)
{
/* USER CODE BEGIN Service1_APP_EvtRx_1 */
/* USER CODE END Service1_APP_EvtRx_1 */
switch(p_Notification->EvtOpcode)
{
/* USER CODE BEGIN Service1_APP_EvtRx_Service1_EvtOpcode */
/* USER CODE END Service1_APP_EvtRx_Service1_EvtOpcode */
case P2P_SERVER_CONN_HANDLE_EVT :
P2P_SERVER_APP_Context.ConnectionHandle = p_Notification->ConnectionHandle;
/* USER CODE BEGIN Service1_APP_CENTR_CONN_HANDLE_EVT */
/* USER CODE END Service1_APP_CENTR_CONN_HANDLE_EVT */
break;
case P2P_SERVER_DISCON_HANDLE_EVT :
P2P_SERVER_APP_Context.ConnectionHandle = 0xFFFF;
/* USER CODE BEGIN Service1_APP_DISCON_HANDLE_EVT */
P2P_SERVER_APP_LED_BUTTON_context_Init();
/* USER CODE END Service1_APP_DISCON_HANDLE_EVT */
break;
default:
/* USER CODE BEGIN Service1_APP_EvtRx_default */
/* USER CODE END Service1_APP_EvtRx_default */
break;
}
/* USER CODE BEGIN Service1_APP_EvtRx_2 */
/* USER CODE END Service1_APP_EvtRx_2 */
return;
}
void P2P_SERVER_APP_Init(void)
{
P2P_SERVER_APP_Context.ConnectionHandle = 0xFFFF;
P2P_SERVER_Init();
/* USER CODE BEGIN Service1_APP_Init */
UTIL_SEQ_RegTask( 1U << CFG_TASK_SEND_NOTIF_ID, UTIL_SEQ_RFU, P2P_SERVER_Switch_c_SendNotification);
/**
* Initialize LedButton Service
*/
P2P_SERVER_APP_Context.Switch_c_Notification_Status= Switch_c_NOTIFICATION_OFF;
P2P_SERVER_APP_LED_BUTTON_context_Init();
/* USER CODE END Service1_APP_Init */
return;
}
/* USER CODE BEGIN FD */
void P2P_SERVER_APP_LED_BUTTON_context_Init(void)
{
BSP_LED_Off(LED_BLUE);
P2P_SERVER_APP_Context.LedControl.Device_Led_Selection=0x01; /* Device1 */
P2P_SERVER_APP_Context.LedControl.Led1=0x00; /* led OFF */
P2P_SERVER_APP_Context.ButtonControl.Device_Button_Selection=0x01;/* Device1 */
P2P_SERVER_APP_Context.ButtonControl.ButtonStatus=0x00;
return;
}
/* USER CODE END FD */
/*************************************************************
*
* LOCAL FUNCTIONS
*
*************************************************************/
__USED void P2P_SERVER_Switch_c_SendNotification(void) /* Property Notification */
{
P2P_SERVER_APP_SendInformation_t notification_on_off = Switch_c_NOTIFICATION_OFF;
P2P_SERVER_Data_t p2p_server_notification_data;
p2p_server_notification_data.p_Payload = (uint8_t*)a_P2P_SERVER_UpdateCharData;
p2p_server_notification_data.Length = 0;
/* USER CODE BEGIN Service1Char2_NS_1*/
if(P2P_SERVER_APP_Context.ButtonControl.ButtonStatus == 0x00)
{
P2P_SERVER_APP_Context.ButtonControl.ButtonStatus = 0x01;
}
else
{
P2P_SERVER_APP_Context.ButtonControl.ButtonStatus = 0x00;
}
a_P2P_SERVER_UpdateCharData[0] = 0x01; /* Device Led selection */
a_P2P_SERVER_UpdateCharData[1] = P2P_SERVER_APP_Context.ButtonControl.ButtonStatus;
/* Update notification data length */
p2p_server_notification_data.Length = (p2p_server_notification_data.Length) + 2;
if(P2P_SERVER_APP_Context.Switch_c_Notification_Status == Switch_c_NOTIFICATION_ON)
{
APP_DBG_MSG("-- P2P APPLICATION SERVER : INFORM CLIENT BUTTON 1 PUSHED\n");
notification_on_off = Switch_c_NOTIFICATION_ON;
}
else
{
APP_DBG_MSG("-- P2P APPLICATION SERVER : CAN'T INFORM CLIENT - NOTIFICATION DISABLED\n");
}
/* USER CODE END Service1Char2_NS_1*/
if (notification_on_off != Switch_c_NOTIFICATION_OFF && P2P_SERVER_APP_Context.ConnectionHandle != 0xFFFF)
{
P2P_SERVER_NotifyValue(P2P_SERVER_SWITCH_C, &p2p_server_notification_data, P2P_SERVER_APP_Context.ConnectionHandle);
}
/* USER CODE BEGIN Service1Char2_NS_Last*/
/* USER CODE END Service1Char2_NS_Last*/
return;
}
/* USER CODE BEGIN FD_LOCAL_FUNCTIONS*/
/* USER CODE END FD_LOCAL_FUNCTIONS*/
Program excerpt and p2p_serverApp.c file.
/* Private function prototypes -----------------------------------------------*/
static void P2P_SERVER_Switch_c_SendNotification(void);
/* USER CODE BEGIN PFP */
static void P2P_SERVER_APP_LED_BUTTON_context_Init(void);
There is a key callback function in the program: P2P_SERVER_Switch_c_SendNotification, which is called after receiving a message.
The event is executed as follows:
case P2P_SERVER_LED_C_WRITE_NO_RESP_EVT:
/* USER CODE BEGIN Service1Char1_WRITE_NO_RESP_EVT */
if(p_Notification->DataTransfered.p_Payload[1] == 0x01)
{
BSP_LED_On(LED_BLUE);
APP_DBG_MSG("-- P2P APPLICATION SERVER : LED1 ON\n");
P2P_SERVER_APP_Context.LedControl.Led1 = 0x01; /* LED1 ON */
}
if(p_Notification->DataTransfered.p_Payload[1] == 0x00)
{
BSP_LED_Off(LED_BLUE);
APP_DBG_MSG("-- P2P APPLICATION SERVER : LED1 OFF\n");
P2P_SERVER_APP_Context.LedControl.Led1 = 0x00; /* LED1 OFF */
}
/* USER CODE END Service1Char1_WRITE_NO_RESP_EVT */
break;
There is a switch control here: P2P_SERVER_SWITCH_C_NOTIFY_ENABLED_EVT can extend this function.
|