侧边栏壁纸
博主头像
李振洋的博客博主等级

歌颂动荡的青春

  • 累计撰写 38 篇文章
  • 累计创建 6 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录

BLE 5.3无线MCU CH582实现外围设备(Peripheral)

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;
}

code.png

测试结果

information.png

0

评论区