BLE 5.3无线MCU CH582实现外围设备(Peripheral)
准备材料
自制CH582 Demo板
MounRiver Studio
WCHISPStudio
nRF Connector & nRF52840-MDK USB Dongle
工程预览
1. APP – 有关应用的源文件和头文件均可放置于此,例程的 main 函数也在这里。
2. HAL – 此文件夹中为 HAL 层的源代码与头文件,HAL 层即蓝牙协议栈与芯片硬件驱动交互层。
3. LIB – 低功耗蓝牙的协议栈库文件。
4. LD – 链接脚本。
5. Profile – 该文件从包含 GAP 角色配置文件,GAP 安全配置文件和 GATT 配置文件的源代码与头文件,同时也包含 GATT 服务所需的头文件。
6. RVMSIS – RISC-V 内核访问的源代码与头文件。
7. Startup – 启动文件。沁恒低功耗蓝牙软件开发参考手册
8. StdPeriphDriver – 包括芯片外设的底层驱动文件。
main()
/*********************************************************************
* @fn Main_Circulation
*
* @brief 主循环
*
* @return none
*/
__HIGH_CODE
__attribute__((noinline))
void Main_Circulation()
{
while(1)
{
TMOS_SystemProcess();
}
}
/*********************************************************************
* @fn main
*
* @brief 主函数
*
* @return none
*/
int main(void)
{
#if(defined(DCDC_ENABLE)) && (DCDC_ENABLE == TRUE)
//开启片上DC/DC
PWR_DCDCCfg(ENABLE);
#endif
//初始化系统时钟
SetSysClock(CLK_SOURCE_PLL_60MHz);
#ifdef DEBUG
GPIOA_SetBits(bTXD1);
GPIOA_ModeCfg(bTXD1, GPIO_ModeOut_PP_5mA);
UART1_DefInit();
#endif
PRINT("%s\n", VER_LIB);
//初始化蓝牙库
CH58X_BLEInit();
//初始化HAL层
HAL_Init();
//GAP 外围设备初始化
GAPRole_PeripheralInit();
// 外围设备应用程序任务的初始化
Peripheral_Init();
//主循环
Main_Circulation();
}
蓝牙库初始化函数 CH58X_BLEInit(),通过配置参数 bleConfig_t 配置库的内存,时钟,发射功率等参数,然后通过 BLE_LibInit()函数将配置参数传进库中。
注册 HAL 层任务,对硬件参数进行初始化,如 RTC 时钟,睡眠唤醒,RF 校准等
/*******************************************************************************
* @fn HAL_Init
*
* @brief 硬件初始化
*
* @param None.
*
* @return None.
*/
void HAL_Init()
{
halTaskID = TMOS_ProcessEventRegister(HAL_ProcessEvent);
HAL_TimeInit();
#if(defined HAL_SLEEP) && (HAL_SLEEP == TRUE)
HAL_SleepInit();
#endif
#if(defined HAL_LED) && (HAL_LED == TRUE)
HAL_LedInit();
#endif
#if(defined HAL_KEY) && (HAL_KEY == TRUE)
HAL_KeyInit();
#endif
#if(defined BLE_CALIBRATION_ENABLE) && (BLE_CALIBRATION_ENABLE == TRUE)
tmos_start_task(halTaskID, HAL_REG_INIT_EVENT, MS1_TO_SYSTEM_TIME(BLE_CALIBRATION_PERIOD));
// 添加校准任务,单次校准耗时小于10ms
#endif
// tmos_start_task( halTaskID, HAL_TEST_EVENT, 1600 ); // 测试任务
}
蓝牙外围设备初始化,此过程包括两个部分:
GAP 角色的初始化,此过程由低功耗蓝牙库完成;
低功耗蓝牙从机应用初始化,包括从机任务的注册,参数配置(如广播参数,连接参数,绑定参数等),GATT 层服务的注册,以及回调函数的注册。
外围设备应用程序任务的初始化
void Peripheral_Init()
{
Peripheral_TaskID = TMOS_ProcessEventRegister(Peripheral_ProcessEvent);
// 设置GAP外围角色配置文件
{
uint8_t initial_advertising_enable = TRUE;
uint16_t desired_min_interval = DEFAULT_DESIRED_MIN_CONN_INTERVAL;
uint16_t desired_max_interval = DEFAULT_DESIRED_MAX_CONN_INTERVAL;
// Set the GAP Role Parameters
// 开启广播
GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t), &initial_advertising_enable);
// 设置扫描回复数据
GAPRole_SetParameter(GAPROLE_SCAN_RSP_DATA, sizeof(scanRspData), scanRspData);
// 设置广播数据
GAPRole_SetParameter(GAPROLE_ADVERT_DATA, sizeof(advertData), advertData);
// 设置最短连接间隔
GAPRole_SetParameter(GAPROLE_MIN_CONN_INTERVAL, sizeof(uint16_t), &desired_min_interval);
// 设置最长连接间隔
GAPRole_SetParameter(GAPROLE_MAX_CONN_INTERVAL, sizeof(uint16_t), &desired_max_interval);
}
{
uint16_t advInt = DEFAULT_ADVERTISING_INTERVAL;
// Set advertising interval
// 设置广播间隔
GAP_SetParamValue(TGAP_DISC_ADV_INT_MIN, advInt);
GAP_SetParamValue(TGAP_DISC_ADV_INT_MAX, advInt);
// 开启扫描请求通知
GAP_SetParamValue(TGAP_ADV_SCAN_REQ_NOTIFY, ENABLE);
}
// Setup the GAP Bond Manager 设置GAP绑定管理
{
uint32_t passkey = 0; // passkey "000000"
uint8_t pairMode = GAPBOND_PAIRING_MODE_WAIT_FOR_REQ;
uint8_t mitm = TRUE;
uint8_t bonding = TRUE;
uint8_t ioCap = GAPBOND_IO_CAP_DISPLAY_ONLY;
GAPBondMgr_SetParameter(GAPBOND_PERI_DEFAULT_PASSCODE, sizeof(uint32_t), &passkey);
GAPBondMgr_SetParameter(GAPBOND_PERI_PAIRING_MODE, sizeof(uint8_t), &pairMode);
GAPBondMgr_SetParameter(GAPBOND_PERI_MITM_PROTECTION, sizeof(uint8_t), &mitm);
GAPBondMgr_SetParameter(GAPBOND_PERI_IO_CAPABILITIES, sizeof(uint8_t), &ioCap);
GAPBondMgr_SetParameter(GAPBOND_PERI_BONDING_ENABLED, sizeof(uint8_t), &bonding);
}
// Initialize GATT attributes
GGS_AddService(GATT_ALL_SERVICES); // GAP
GATTServApp_AddService(GATT_ALL_SERVICES); // GATT attributes
DevInfo_AddService(); // Device Information Service
SimpleProfile_AddService(GATT_ALL_SERVICES); // Simple GATT Profile
// Set the GAP Characteristics
GGS_SetParameter(GGS_DEVICE_NAME_ATT, sizeof(attDeviceName), attDeviceName);
// Setup the SimpleProfile Characteristic Values
{
uint8_t charValue1[SIMPLEPROFILE_CHAR1_LEN] = {1};
uint8_t charValue2[SIMPLEPROFILE_CHAR2_LEN] = {2};
uint8_t charValue3[SIMPLEPROFILE_CHAR3_LEN] = {3};
uint8_t charValue4[SIMPLEPROFILE_CHAR4_LEN] = {4};
uint8_t charValue5[SIMPLEPROFILE_CHAR5_LEN] = {1, 2, 3, 4, 5};
SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR1, SIMPLEPROFILE_CHAR1_LEN, charValue1);
SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR2, SIMPLEPROFILE_CHAR2_LEN, charValue2);
SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR3, SIMPLEPROFILE_CHAR3_LEN, charValue3);
SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR4, SIMPLEPROFILE_CHAR4_LEN, charValue4);
SimpleProfile_SetParameter(SIMPLEPROFILE_CHAR5, SIMPLEPROFILE_CHAR5_LEN, charValue5);
}
// Init Connection Item
peripheralInitConnItem(&peripheralConnList);
// Register callback with SimpleGATTprofile
SimpleProfile_RegisterAppCBs(&Peripheral_SimpleProfileCBs);
// Register receive scan request callback
GAPRole_BroadcasterSetCB(&Broadcaster_BroadcasterCBs);
// Setup a delayed profile startup
tmos_set_event(Peripheral_TaskID, SBP_START_DEVICE_EVT);
}
DevInfo_AddService
// GATT属性列表
static gattAttribute_t devInfoAttrTbl[] = {
//设备信息服务
{
{ATT_BT_UUID_SIZE, primaryServiceUUID}, /* type */
GATT_PERMIT_READ, /* permissions */
0, /* handle */
(uint8_t *)&devInfoService /* pValue */
},
// ID
{
{ATT_BT_UUID_SIZE, characterUUID},
GATT_PERMIT_READ,
0,
&devInfoSystemIdProps},
// ID值
{
{ATT_BT_UUID_SIZE, devInfoSystemIdUUID},
GATT_PERMIT_READ,
0,
(uint8_t *)devInfoSystemId},
// 型号
{
{ATT_BT_UUID_SIZE, characterUUID},
GATT_PERMIT_READ,
0,
&devInfoModelNumberProps},
// 型号值
{
{ATT_BT_UUID_SIZE, devInfoModelNumberUUID},
GATT_PERMIT_READ,
0,
(uint8_t *)devInfoModelNumber},
// 序列号
{
{ATT_BT_UUID_SIZE, characterUUID},
GATT_PERMIT_READ,
0,
&devInfoSerialNumberProps},
// 序列号值
{
{ATT_BT_UUID_SIZE, devInfoSerialNumberUUID},
GATT_PERMIT_READ,
0,
(uint8_t *)devInfoSerialNumber},
// 固件固件版本
{
{ATT_BT_UUID_SIZE, characterUUID},
GATT_PERMIT_READ,
0,
&devInfoFirmwareRevProps},
// 固件版本值
{
{ATT_BT_UUID_SIZE, devInfoFirmwareRevUUID},
GATT_PERMIT_READ,
0,
(uint8_t *)devInfoFirmwareRev},
// 硬件版本
{
{ATT_BT_UUID_SIZE, characterUUID},
GATT_PERMIT_READ,
0,
&devInfoHardwareRevProps},
// 硬件版本值
{
{ATT_BT_UUID_SIZE, devInfoHardwareRevUUID},
GATT_PERMIT_READ,
0,
(uint8_t *)devInfoHardwareRev},
// Software Revision String Declaration
{
{ATT_BT_UUID_SIZE, characterUUID},
GATT_PERMIT_READ,
0,
&devInfoSoftwareRevProps},
// Software Revision Value
{
{ATT_BT_UUID_SIZE, devInfoSoftwareRevUUID},
GATT_PERMIT_READ,
0,
(uint8_t *)devInfoSoftwareRev},
// Manufacturer Name String Declaration
{
{ATT_BT_UUID_SIZE, characterUUID},
GATT_PERMIT_READ,
0,
&devInfoMfrNameProps},
// Manufacturer Name Value
{
{ATT_BT_UUID_SIZE, devInfoMfrNameUUID},
GATT_PERMIT_READ,
0,
(uint8_t *)devInfoMfrName},
// IEEE 11073-20601 Regulatory Certification Data List Declaration
{
{ATT_BT_UUID_SIZE, characterUUID},
GATT_PERMIT_READ,
0,
&devInfo11073CertProps},
// IEEE 11073-20601 Regulatory Certification Data List Value
{
{ATT_BT_UUID_SIZE, devInfo11073CertUUID},
GATT_PERMIT_READ,
0,
(uint8_t *)devInfo11073Cert},
// PnP ID Declaration
{
{ATT_BT_UUID_SIZE, characterUUID},
GATT_PERMIT_READ,
0,
&devInfoPnpIdProps},
// PnP ID Value
{
{ATT_BT_UUID_SIZE, devInfoPnpIdUUID},
GATT_PERMIT_READ,
0,
(uint8_t *)devInfoPnpId}
};
bStatus_t DevInfo_AddService(void)
{
// 使用GATT服务器应用程序注册GATT属性列表和回调函数
return GATTServApp_RegisterService(devInfoAttrTbl,
GATT_NUM_ATTRS(devInfoAttrTbl),
GATT_MAX_ENCRYPT_KEY_SIZE,
&devInfoCBs);
}
//Peripheral_ProcessEvent 事件处理
uint16_t Peripheral_ProcessEvent(uint8_t task_id, uint16_t events)
{
//系统消息事件
if(events & SYS_EVENT_MSG)
{
uint8_t *pMsg;
if((pMsg = tmos_msg_receive(Peripheral_TaskID)) != NULL)
{
Peripheral_ProcessTMOSMsg((tmos_event_hdr_t *)pMsg);
// Release the TMOS message
tmos_msg_deallocate(pMsg);
}
// return unprocessed events
return (events ^ SYS_EVENT_MSG);
}
// 启动设备事件
if(events & SBP_START_DEVICE_EVT)
{
// 启动设备 GAP绑定回调,GAP Role任务回调
// Peripheral_PeripheralCBs包括配置文件状态更改回调,控制器读取到有效的RSSI回调,外围参数更新回调
GAPRole_PeripheralStartDevice(Peripheral_TaskID, &Peripheral_BondMgrCBs, &Peripheral_PeripheralCBs);
return (events ^ SBP_START_DEVICE_EVT);
}
if(events & SBP_PERIODIC_EVT)
{
// Restart timer
if(SBP_PERIODIC_EVT_PERIOD)
{
tmos_start_task(Peripheral_TaskID, SBP_PERIODIC_EVT, SBP_PERIODIC_EVT_PERIOD);
}
// Perform periodic application task
performPeriodicTask();
return (events ^ SBP_PERIODIC_EVT);
}
// 连接参数更新事件
if(events & SBP_PARAM_UPDATE_EVT)
{
// 发送连接参数更新请求
GAPRole_PeripheralConnParamUpdateReq(peripheralConnList.connHandle,
DEFAULT_DESIRED_MIN_CONN_INTERVAL,
DEFAULT_DESIRED_MAX_CONN_INTERVAL,
DEFAULT_DESIRED_SLAVE_LATENCY,
DEFAULT_DESIRED_CONN_TIMEOUT,
Peripheral_TaskID);
return (events ^ SBP_PARAM_UPDATE_EVT);
}
if(events & SBP_PHY_UPDATE_EVT)
{
// start phy update
PRINT("PHY Update %x...\n", GAPRole_UpdatePHY(peripheralConnList.connHandle, 0,
GAP_PHY_BIT_LE_2M, GAP_PHY_BIT_LE_2M, GAP_PHY_OPTIONS_NOPRE));
return (events ^ SBP_PHY_UPDATE_EVT);
}
// 读取RSSI事件
if(events & SBP_READ_RSSI_EVT)
{
GAPRole_ReadRssiCmd(peripheralConnList.connHandle);
tmos_start_task(Peripheral_TaskID, SBP_READ_RSSI_EVT, SBP_READ_RSSI_EVT_PERIOD);
return (events ^ SBP_READ_RSSI_EVT);
}
// Discard unknown events
return 0;
}
评论区