CH582-BLE-Peripheral-Control LED switch

1. Controlling the LED light on and off is a BLE service, and the switch control is realized by modifying the characteristic value of the service.

        To realize the reading and writing of characteristic values, there must be services, characteristic declarations, and characteristic value declarations. First, create an attribute table in the gattprofile.c file, which contains services, feature declarations, feature value declarations, and feature user descriptions (not required); services, feature declarations, feature value declarations, and feature user descriptions all belong to each attribute Each has its corresponding UUID; UUID contains UUID values ​​of different attribute types.

》Property table definition

//定义一个服务
static const gattAttrType_t ledProfileService = {ATT_BT_UUID_SIZE, ledProfileServUUID};

//特征值初始化
// 特征值属性,读或者写
static uint8_t ledProfileCharProps = GATT_PROP_READ | GATT_PROP_WRITE;
// 值,可以向其写入数据,也可以读出数据。这里是一个字符数组
static uint8_t ledProfileChar[LEDPROFILE_CHAR_LEN] = {0};
// 用户描述,展现给用户的名字
static uint8_t ledProfileCharUserDesp[] = "Led_Contral\0";
//属性表
static gattAttribute_t ledProfileAttrTb[]=
{
        //led priofile service
        {
            {ATT_BT_UUID_SIZE,primaryServiceUUID}, //type(属性类型)   属性类型:主服务primaryServiceUUIDd为0x2800即主服务类型。 
            GATT_PERMIT_READ,                      //permissions(GATT客户端对于该属性的权限)    即客户端对于该服务的权限,GATT_PERMIT_READ客户端可以发现这个服务。
            0,                                     //handle(表中属性的索引)    即在这个属性表中的位置指明这是在这个数组中的第几个数组元素,因为这个句柄是协议栈自动分配的,因此默认初始化为0
            (uint8 *)&ledProfileService            //pValue(指向属性值的指针)    用自己定义的UUID值0xFFF0来指向这个服务
        },
        //characteristic Declaration
        {
            {ATT_BT_UUID_SIZE,characterUUID},    //属性类型:特征值  characterUUID为0x2803即特征值类型
            GATT_PERMIT_READ,                    //数组这个元素权限为可读
            0,
            &ledProfileCharProps                 //ledProfileCharProps描述的是特征值具有的属性(指读写属性),一个是权限一个是属性。
        },
        //characteristic Value
        {
            {ATT_BT_UUID_SIZE,ledProfilecharUUID},    //特征值的自定义UUID
            GATT_PERMIT_READ | GATT_PERMIT_WRITE,     //权限为可读可写,要与特征值类型描述里的ledProfileCharProps特征值属性一致。
            0,
            ledProfileChar                            //特征值存放地方,就是修改里面的内容实现特征值的读写
        },
        //charateristic User Description
        {
            {ATT_BT_UUID_SIZE,charUserDescUUID},     //特征描述的UUID
            GATT_PERMIT_READ,
            0,
            ledProfileCharUserDesp                   //描述的内容       
        },

};

》Registration Service 

Mainly through the BLE library function GATTServApp_RegisterService(), register the GATT table in the BLE STACK, and set the read and write callback functions.

//读写回调设置
gattServiceCBs_t ledProfileCBs = {
    ledProfile_ReadAttrCB,  // Read callback function pointer
    ledProfile_WriteAttrCB, // Write callback function pointer

    NULL                       // Authorization callback function pointer
};
//注册服务函数
bStatus_t LedProfile_Addservice(uint32 services)
{
    uint8 status = SUCCESS;

    if(services & LEDPROFILE_SERVICE)
    {
        status = GATTServApp_RegisterService(ledProfileAttrTb,             //属性表   
                                        GATT_NUM_ATTRS(ledProfileAttrTb),
                                        GATT_MAX_ENCRYPT_KEY_SIZE,
                                        &ledProfileCBs);                    //读写回调函数有数据读写时调到读写函数中
    }
    return (status);

}

"Property read callback 

//读写回调
static bStatus_t ledProfile_ReadAttrCB(uint16_t connHandle, gattAttribute_t *pAttr,
                                          uint8_t *pValue, uint16_t *pLen, uint16_t offset, uint16_t maxLen, uint8_t method)
{
    bStatus_t status =SUCCESS;

    if(gattPermitAuthenRead(pAttr->permissions))
    {
        return(ATT_ERR_INSUFFICIENT_AUTHOR);
    }
    if( offset > 0)
    {
        return(ATT_ERR_ATTR_NOT_LONG);
    }
    if(pAttr->type.len == ATT_BT_UUID_SIZE)
    {
        uint16 uuid = BUILD_UINT16(pAttr->type.uuid[0],pAttr->type.uuid[1]);
        switch(uuid)
        {
        case LEDPROFILE_CHAR_UUID:
             *pLen = LEDPROFILE_CHAR_LEN;
             tmos_memcpy(pValue, pAttr->pValue, LEDPROFILE_CHAR_LEN);
             printf("Led_read\r\n");
        break;
        default:
            *pLen = 0;
            status = ATT_ERR_ATTR_NOT_FOUND;
        break;
        }
    }
    else {
        *pLen = 0;
        status = ATT_ERR_INVALID_HANDLE;
    }
    return(status);
}

static bStatus_t ledProfile_WriteAttrCB(uint16_t connHandle, gattAttribute_t *pAttr,
                                           uint8_t *pValue, uint16_t len, uint16_t offset, uint8_t method)
{
    bStatus_t status =SUCCESS;
    uint8 notifyApp = 0xFF;

    if(gattPermitAuthenWrite(pAttr->permissions))
    {
        return(ATT_ERR_INSUFFICIENT_AUTHOR);
    }

    if(pAttr->type.len == ATT_BT_UUID_SIZE)
    {
        uint16 uuid = BUILD_UINT16(pAttr->type.uuid[0],pAttr->type.uuid[1]);
        switch(uuid)
        {
        case LEDPROFILE_CHAR_UUID:
            if(offset == 0)
            {
                if(len > LEDPROFILE_CHAR_LEN)
                {
                    status = ATT_ERR_INVALID_VALUE_SIZE;
                }
            }
            else {
                status = ATT_ERR_ATTR_NOT_LONG;
            }

            if(status == SUCCESS)
            {
                tmos_memcpy(pAttr->pValue, pValue, LEDPROFILE_CHAR_LEN);
                notifyApp = LEDPROFILE_CHAR;
            }
            printf("LED_write\r\n");
        break;
        default:

            status = ATT_ERR_ATTR_NOT_FOUND;
            break;
        }
    }
    else {
        status = ATT_ERR_INVALID_HANDLE;
    }
    // If a charactersitic value changed then callback function to notify application of change
    if ( (notifyApp != 0xFF ) && ledProfile_AppCBs && ledProfile_AppCBs->pfnledProfileChange )
      {
        ledProfile_AppCBs->pfnledProfileChange( notifyApp, pValue, len );
      }
      return ( status );
}

Reference articles for the above content:

[BLE 5.3 wireless MCU CH582] 11. The mobile app controls the LED to turn on and off- Domestic Chip Exchange- Electronic Engineering World-Forum

 2. Learning and understanding of writing callback functions

//在peripheral.c 中调用注册服务函数
  LedProfile_Addservice(GATT_ALL_SERVICES);
    将ledProfileAttrTb,和回调函数ledProfileCBs注册GATT服务中。

/*****************************************************************/

//在peripheral.c 注册回调函数
 LedProfile_RegisterAppCBs(&Peripheral_ledProfileCBs);

bStatus_t LedProfile_RegisterAppCBs(ledProfileCBs_t *appCallbacks)
{
    if(appCallbacks)
    {
        ledProfile_AppCBs = appCallbacks;

        return (SUCCESS);
    }
    else
    {
        return (bleAlreadyInRequestedMode);
    }
}


执行完这个函数 相当于ledProfile_AppCBs这个函数指针指向接收数据的函数
ledProfileChangeCB(uint8 paramID,uint8 *pValue,uint16 len)

/*****************************************************************/
//对应写回调函数中的这一段
If a charactersitic value changed then callback function to notify application of change
    if ( (notifyApp != 0xFF ) && ledProfile_AppCBs && ledProfile_AppCBs->pfnledProfileChange )
      {
        ledProfile_AppCBs->pfnledProfileChange( notifyApp, pValue, len );
      }

//即在写回调函数最后跳转到 ledProfile_AppCBs指向的 ledProfileChangeCB
中对APP写入到BLE的数据进行处理
//接收主机数据进行处理
static void ledProfileChangeCB(uint8 paramID,uint8 *pValue,uint16 len)
{
    switch(paramID)
    {
    case LEDPROFILE_CHAR:
        {
            uint8 newValue[LEDPROFILE_CHAR_LEN];
            tmos_memcpy(newValue, pValue, len);
            if(newValue[0])
            {
                printf("led_on\r\n");
                GPIOB_SetBits(GPIO_Pin_6);
            }
            else {
                printf("led_off\r\n");
                GPIOB_ResetBits(GPIO_Pin_6);
            }
            break;
                }
    default:
        break;
    }

 

Guess you like

Origin blog.csdn.net/qq_45803449/article/details/127004832