请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
器件型号:CC2650EM-7ID-RD /*********
文件名: simpleBLEPeripheral.c
已修订: $Date:2016-01-07 16:59:59-0800 (Thu、2016年1月7日)$
修订版: $Revision:44594 $
说明:此文件包含简单的 BLE 外设示例
与 CC2650低功耗蓝牙配合使用的应用
协议栈。
版权所有2013 - 2015 Texas Instruments Incorporated。 保留所有权利。
重要说明:您对本软件的使用仅限于
下载软件的用户、其雇主(必须是您的雇主)
和德州仪器(TI)公司("许可")之间根据软件许可协议条款授予的特定权利。
除非您同意遵守许可条款、否则不得使用本软件。 许可证
限制您的使用、并且您承认、除非
将本软件嵌入到德州仪器微控制器
上、或者仅与
集成到您产品中的德州仪器射频收发器一起使用、否则不得对其进行修改、复制或分发。 除
上述目的
外、您不得出于任何目的使用、复制、复制、复制、准备本软件和/或其文档的衍生作品、修改、分发、执行、展示或销售本软件和/或其文档。
您进一步确认并同意软件和文档
按“原样”提供,不提供任何明示或暗示的担保,
包括但不限于对适销性、所有权、
非侵权性和特定用途适用性的任何担保。
在任何情况下、德州仪器或其许可人都不应根据合同、
疏忽、严格责任、贡献、违反保修、 或其他
法律公平理论任何直接或间接损害或费用、
包括但不限于任何偶然、特殊、间接、惩罚
性或后果性损害、利润损失或数据丢失、
采购替代产品、技术、服务的费用、 或第三方的任何索赔
(包括但不限于其任何抗辩)或其他类似费用。
如果您对使用本软件的权利有任何疑问、
请通过 www.ti.com 联系德州仪器公司。
秘书长的报告 /
/*********
*包括
*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
include "hci_tl.h"
#include "gatt.h"
#include "gapgattserver.h"
#include "gattoad servapp.h"
#include "devinfoservice.h"
#include "simpleGATTprofile.h"
#if defined (SENSORTAG_HW)
include "bond_spi.h"
#endifer包括"#include "#include "#include "#nature_board.h"#include "#include "#nature.h"#include "#nature.h"#include "#nature.nature.h"#include "#nature.h #include "#include "#nature.h #include "#nature.nature.h #include #include "#gap_board.nature.h #include #include "#include "#include "#gap_mgr.h #include #include "#include "#include "#include "#.nature.nature.nature.nature.nature.h #include "#include #.
"simpleBLEPeripheral.h"
/*********
*常量
*/
//可发现器件时的广播间隔(单位625us、160=100ms)
#define DEFAULT_advertising_interval 160
//受限可发现模式广播30.72,然后停止
//一般可发现模式广播无限
#define DEFAULT_DISCOVERADE_MODE GAP_ADTYPE_FLAGS_General
#ifndef FITY_OAD
//最小连接间隔(单位为1.25ms、80=100ms)(如果
启用了自动//参数更新请求
)#define DEFAULT_MILLED_CONN_INTERVAL 80
//如果
启用了自动//参数更新请求
,则最大连接间隔(单位为1.25ms,800=1000ms)#define DEFAULT_REGIND_MAX_CONN_INTERVAL 800
#else
//如果
启用了自动//参数更新请求
,则最小连接间隔(1.25ms、8=10ms 的单位)#define DEFAULT_MILLED_CONN_INTERVAL 8
//如果启用了自动
//参数更新请求
#define DEFAULT_RETOVE_MAX_CONN_INTERVAL,则最大连接间隔(单位为1.25ms,8=10ms) 8
#endif // feature_OAD
//启用自动参数更新请求时使用的从器件延迟
#define default_desired slave_latency 0
//如果启用了自动参数
//更新请求
#define DEFAULT_MILLED_CONN_TIMEOUT,则监控超时值(10ms、1000=10s 的单位) 1000
//连接时是否启用自动参数更新请求
//形成
#define DEFAULT_ENABLE_UPDATE_REQUEST True
//连接暂停外设时间值(以秒为单位)
#define DEFAULT_CONN_PAUSE_PERIFT 6
//执行周期性事件的频率(以 msec 为单位)
#define SBP_PERIOD_EVT_PERIOD 5000
#ifdef FITY_OAD
// OAD 数据包的大小。
#define OAD_PACKET_SIZE (((OAD_BLOCK_SIZE)+ 2)
#endif // Feature_OAD
//任务配置
#define SBP_TASK_PRIORITY 1
#ifndef SBP_task_stack_size
#define SBP_task_stack_size 644
#endif
// RTOS 应用
程序的内部事件#define SBP_State_change_EVT 0x0001
#define SBP_CHAR_CHANGE_EVT 0x0002
#define SBP_Period_EVT 0x0004
#define SBP_CONN_EVT_END_EVT 0x0008
uint8_t *分辨率;
/*********
* typedef
*/
//从配置文件传递的应用程序事件。
typedef 结构
{
appEvtHdr_t HDR;//事件头。
} sbpEvt_t;
/*********
*局部变量
*/
//全局实体 ID 用于检查消息的源和/或目标
静态 iCall_EntityID selfEntity;
//全局信号量用于将事件发布到应用程序线程
静态 iCall_Semaphore SEM;
//内部周期性事件的时钟实例。
静态时钟结构周期时钟;
//用于应用消息的队列对象
static Queue_StructapMsg;
static Queue_handle appMsgQueue;
#if defined (feature_OAD)
//来自 OAD 配置文件的事件数据。
静态 Queue_StructoadQ;
静态 Queue_handle hOadQ;
内部
应用事件的#endif //feature_OAD //事件标志。
静态 uint16_t 事件;
//任务配置
Task_StructsbpTask;
Char sbpTaskStack[SBP_task_stack_size];
//////////////////////////
/*static PIN_Config SPIPinTable[]={
BOARD_ACC_PWR | PIN_GPIO_OUTP_EN | PIN_GPIO_HIGH | PIN_PushPull、//启用加速计。 需要高电平才能使 ACC 工作。
BOARD_SPI0_MOSI | PIN_PUL拉、
BOARD_SPI0_MISO | PIN_PUL拉、
Board_SPI0_CLK | PIN_PUL拉、
PIN_TERMINATE
//Board_SPI0_CSn | PIN_GPIO_OUTP_EN | PIN_GPIO_HIGH | PIN_PushPull、
//Board_3V3_EN | PIN_GPIO_OUTP_DIS | PIN_GPIO_HIGH | PIN_PushPull、
// PIN_Terminate //终止列表
};*/
*静态 PIN_Config BoardSpiInitTable[]={
BOARD_SPI0_MOSI | PIN_PUL拉、
BOARD_SPI0_MISO | PIN_PUL拉、
Board_SPI0_CLK | PIN_PUL拉、
PIN_TERMINATE
};*/
////////////////////////////////////////////
//系统配置状态和参数
//静态 gaprole_states_t gapProfileState = GAPROLE_init;
// GAP -扫描 RSP 数据(最大大小= 31字节)
静态 uint8_t scanRspData[]=
{
//完整名称
0x14、//此数据的长度
GAP_ADTYPE_LOCAL_NAME_COMPLETE、
0x53/'S
、0x67/'S /'S
//'p'
0x6c、//'l'
0x65、//'e'
0x42、//'B'
0x4c、//'L'
0x45、 //'E'
0x50、//'P'
0x65、//'e'
0x72、//'r'
0x69、//'I'
0x70、 //'p'
0x68、//'h'
0x65、//'e'
0x72、//'r'
0x61、//'a'
0x6c、 //'l'
//连接间隔范围
0x05,//此数据
的长度 GAP_ADTYPE_SLAVE_CONN_INTERVAL 范围,
LO_UINT16 (DEFAULT_REWITY_MIN_CONN_INTERVAL),// 100ms
HI_UINT16 (DEFAULT_MIN_CONN_INTERVAL),
LO_UINT16 (DEFAULT_MAX_ON_MIN_INTERVAL),
期望值
// Tx 功率级别
0x02、//此数据
的长度 GAP_ADTYPE_POWER_LEVEL、
0 // 0dBm
};
// GAP -广播数据(最大大小= 31字节、尽管这是
//在进行广播时最好保持较短的时间以节省功耗)
静态 uint8_t advertData[]=
{
// Flags;这会将器件设置为使用有限
的//模式(一次可发现30秒) 不是通用
//可发现模式(无限期广播)
0x02、//此数据
GAP_ADTYPE_FLAGS 的长度、
DEFAULT_DISCOVE_MODE | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED、
//服务 UUID、以通知中央设备包含哪些服务
//在此外设
0x03中、//此数据
GAP_ADTYPE_16BIT_MORE 的长度 //一些 UUID,但并非所有
#ifdef Feature_OAD
LO_UINT16 (OAD_SERVICE_UUUID)、
HI_UINT16 (OAD_SERVICE_UUUUUUUUUID)
#else
LO_UINT16 (SIMPLEPROFILE_SERV_GATT)、
HI_UINT16 (SIMPLE_PROFILE_SERVICE_UUID)#elt LO_UINT16 (SIMPLE_RESET_UNT_STATUSTRY
= 0)*静态响应* 0、LSINT_INT_INTOOT_INT_UNT_UNT_ENTRY_STATUSTRY = 0;*静态响应* 0 = 0 *静态空* 0 =静态空*静态空* 0和静态空*静态空* 0 =静态空*空*空*空* 0;静态空
*本地函数
*/
static void SimpleBLEPeripheral_init (void);
static void SimpleBLEPeripheral_taskFxn (UArg a0、UArg A1);
static uint8_t SimpleBLEPeripheral_processStackMsg (iCall_HDR *pChangeMsg);
static uint8_t SimpleBLEPeripheral_processMsgt (
static SimpleMsstep_processMsg);static SimpleEvt_processBLEPeripheral_processBLEPeripheral_processMsg (static SimpleMsstepsstepsstackg
void prole_states_t newState);static void SimpleBLEPeripheral_processCharValueChangeEvt (uint8_t paramID);static void SimpleBLEPeripheral_performPeriodicTask (void);static void SimpleBLEPeripheral_sendAttRsp (void);static void SimpleBLEPeripheral_Attrobt 8 (static) void SimpleBLEPeripheral_t_enut (void 8);static void SimpleState_eneoutral_t_eneoutrent (void 8)
uint8_t *pData);
#endif //feature_OAD
静态空 SimpleBLEPeripheral_clockHandler (UARg arg);
extern void Board_openEEP (void);
/*********
*配置文件回调
*/
// GAP 角色回调
静态 gapRolesCBs_t SimpleBLEPeripheral_gapRoleCBs =
{
SimpleBLEPeripheral_stateChangeCB //配置文件状态更改回调
};
// GAP 绑定管理器回调
静态 gapBondCBs_t simpleBLEPeripheral_BondMgrCBs =
{
NULL,//密码回调(不被应用程序使用)
NULL //配对/绑定状态回调(不被应用程序使用)
};
//简单 GATT 配置文件回调
#ifndef Feature_OAD
静态 simpleProfileCBs_t SimpleBLEPeripheral_simpleProfileCBs =
{
SimpleBLEPeripheral_charValueChangeCB //特征值更改
};
#endif //!Feature_OAD
#ifdef Feature_OAD
静态 oadWritePeripheral_WriteCBs =
{SimplePeripheral_WriteBSimplePeripheral_WriteBAD_WriteBQBAD_Peripheral =}
。
};
#endif //feature_OAD/
*********
*公共职能
*/
*@fn SimpleBLEPeripheral_createTask
*
*@简单 BLE 外设的简短任务创建函数。
*
*@param 无。
*
*@返回无。
//
void SimpleBLEPeripheral_createTask (void)
{
Task_Params taskParams;
//配置任务
Task_Params_init (&taskParams);
taskParams.stack = sbpSTACKStack;taskParams.TaskCKSIZE
= SBP_TASK_STACK_SIZE;
taskParams.priority = SBP_TASK_TASK_PRIZE = SBP_TASK_TASK_TASK_TASK_BACK_PRIVE_TASK;
task_TASK_TASK ( SimpleBLEPeripheral_taskFxn、&taskParams、NULL);
}
/*********
*@fn SimpleBLEPeripheral_init
*
*@初始化期间调用的简短说明、其中包含应用
* 特定初始化(即硬件初始化/设置、
* 表初始化、加电通知等)和
* 配置文件初始化/设置。
*
*@param 无。
*
*@返回无。
*/
static void SimpleBLEPeripheral_init (void)
{
//******
//在调用 iCall_registerApp 之前可能会发生 N0栈 API 调用
//
//将当前线程注册为 ICall 调度程序//
以便应用程序可以发送和接收消息。
iCall_registerApp (&selfEntity、&sem);
//对 BD 地址进行硬编码、直至 CC2650板获取其自己的 IEEE 地址
//uint8 bdAddress[B_ADDR_LEN]={0xAD、0xD0、0x0A、0xAD、0xD0、 0x0A};
//HCI_EXT_SetBDADDRCmd (bdAddress);
//设置器件的睡眠时钟精度
//HCI_EXT_SetSCACmd (500);
//为要发送到应用程序的配置文件中的消息创建 RTOS 队列。
appMsgQueue = Util_constructQueue (&appMsg);
//为内部周期事件创建单次时钟。
Util_constructClock (周期时钟、SimpleBLEPeripheral_clockHandler、
SBP_PERIOD_EVT_PERIOD、0、false、SBP_PERIOD_EVT);
// Board_openEEP ();
/* Board_openACC ();*/
#ifndef SENSORTAG_HW
// while (1)
{
uint16_t *a=Board_intacc ();//Board_intacc
// Board_closeacc ();
Board_openlcd ();
LCD_write_string ("自由落体"、LCD_Page3);
LCD_write_string_value ("角度:"、 (uint16_t)*A、10、LCD_Page3);
Task_sleep (1000*1000/Clock_tickPeriod);
Board_closeLCD();
////////////////////////////////////////////////////////////////////////////////////////
/*SPICC26XX_HWAttrs const *hwAttrs;
SPI_Handle 套件;
PIN_Config spiPinTable[5];
hSPIPins = PIN_OPEN (&SPIPinState、SPIPinTable);
if (hSPIPins=NULL)
{
返回;
}
uint8_t txbuy[3]、rxbuy[5];*/
// uint8_t *分辨率;
// res=rxbuff;
//spi_handle rndle =(spi_handle)和(spi_config);
// SPI_Params SPI_parms;
// SPI_Transaction 事务;
// parms.bitrate = 1000000;
// spi_params_init (&spi_parms);//spi_params * params
// lcdhwAttrs = ndell->hwAttrs;
// spi_parms.frameFormat = SPI_POL0_PHA0;
// SPI_parms.mode = SPI_MASTER;
/* txbuff [0]= 0x80;
txbuff[1]=0xFF;
txbuff[2]= 0xFF;
transaction.count = 3;
transaction.txBuf = txbuff;
transaction.rxBuf = rxbuff;
hndel=SPI_open (CC2650_SPI0、&SPI_parms);
if (!ndle)
{
返回;
}
hwAttrs=hndel->hwAttrs;
spipinTable[0]=hwAttrs->mosiPin | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PushPull | PIN_INPUT_DIS | PIN_DRVSTR_MED;
spiPinTable[1]=hwAttrs->MISO 引脚| PIN_INPUT_EN | PIN_PULLUDOWN;
spiPinTable[2]=hwAttrs->clkPin | PIN_GPIO_OUTP_EN | PIN_GPIO_HIGH | PIN_PushPull;
spiPinTable[3]=hwAttrs->csnPin | PIN_GPIO_OUTP_EN | PIN_GPIO_HIGH | PIN_PushPull;
spiPinTable[4]=PIN_TERMINATE;
hndle =(SPI_Handle)&(SPI_CONFIG);*/
/* while (SSIBusy ((((SPICC26XX_HWAttrs*) object->spiHandle->hwAttrs)->baseAddr))
{};*/
/* hSPIPin=PIN_OPEN (&SPI、spipinTable);
pin_setOutputValue (hSPIPins、hwAttrs->csnPin、0);
if (!hSPIPin)
{*/
/*引脚分配失败,引脚可能已被分配*/
/*返回;
}
if (PIN_setOutputValue (hSPIPins、hwAttrs->csnPin、0)=PIN_SUCCESS)
{
bool re=SPI_transfer (hndle、&transaction);//SSIBusy
if (re == false)
{
返回;
}
}
pin_setOutputValue (hSPIPins、hwAttrs->csnPin、1);*/
// Res=rxbuff;
//////////////////////////////////////////////////////////////////////////////////////////
Board_openLCD ();
#endif //SENSORTAG_HW
#if SENSORTAG_HW
//为串行闪存和 Devpack 接口设置 SPI 总线
bspSpiOpen ();
#endif //SENSORTAG_HW
//设置 GAP
GAP_SetParamValue (TGAP_CONN_PAUSE_PERUSTRUST、DEFAULT_CONN_PAUSE_PERUSTRUST);
//设置 GAP 外设角色配置文件
{
//对于所有硬件平台,设备在初始化时开始广播
uint8_t 初始化地址使能= true;
//通过将此值设置为零,器件将在之后进入等待状态
//可发现30.72秒,并且不会再次进行广播
//直到启用程序设置回 true
uint16_t advertOffTime = 0;
uint8_t enableUpdateRequest = default_enable_update_request;
uint16_t desedMinInterval = default_desed_min_CONN_interval;
uint16_t desedMaxInterval = default_desed_MAX_CONN_INTERVAL;
uint16_t desedSlaveLatency = default_desed_slave_latency;
uint16_t desedConnTimeout = default_desed_CONN_TIMEOUT;
//设置 GAP 角色参数
GAPRole_SetParameter (GAPROLE_Adverte_enabled、sizeof (uint8_t)、
初始化启用(&A);
GAPRole_SetParameter (GAPROLE_GOOD_OFF_TIME、sizeof (uint16_t)、
advertOffTime (advertOffTime)(&D);
GAPRole_SetParameter (GAPROLE_SCAN_RSP_DATA、sizeof (scanRspData)、
scanRspData);
GAPRole_SetParameter (GAPROLE_adverted_data、sizeof (advertData)、advertData);
GAPRole_SetParameter (GAPROLE_PARAM_UPDATE_ENABLE、sizeof (uint8_t)、
enableUpdateRequest (enableUpdateRequest)(enableUpdateRequest));
GAPRole_SetParameter (GAPROLE_MIN_CONN_INTERVAL、sizeof (uint16_t)、
需要最小间隔(&D);
GAPRole_SetParameter (GAPROLE_MAX_CONN_INTERVAL、sizeof (uint16_t)、
指定最大间隔(&D);
GAPRole_SetParameter (GAPROLE_SLAVE_DELUMMER、sizeof (uint16_t)、
希望从属延迟(&D);
GAPRole_SetParameter (GAPROLE_TIMEOUT_MULTIER、sizeof (uint16_t)、
需要连接超时);
}
//设置 GGS_SetParameter (
GGS_DEVICE_NAME_ATT、GAP_DEVICE_NAME_LEN、attDeviceName) GAP 特性;
//设置广播间隔
{
uint16_t advInt = default_advertising_interval;
GAP_SetParamValue (TGAP_LIM_DISC_ADV_INT_MIN、advInt);
GAP_SetParamValue (TGAP_LIM_DISC_ADV_INT_MAX、advInt);
GAP_SetParamValue (TGAP_GEN_DISC_ADV_INT_MIN、advInt);
GAP_SetParamValue (TGAP_GEN_DISC_ADV_INT_MAX、advInt);
}
//设置 GAP 绑定管理
器{
uint32_t 密钥= 0;//密钥"000000"
uint8_t pairMode = GAPBOND_Pairing_mode_wait_for_Req;
uint8_t MIPTM = true;
uint8_t ioCap = GAPBOND_IO_CAP_DISPLAY_ONLY;
uint8_t 绑定= true;
GAPBondMgr_SetParameter (GAPBOND_DEFAULT_Passcode、sizeof (uint32_t)、
密钥);
GAPBondMgr_SetParameter (GAPBOND_Pairing_mode、sizeof (uint8_t)、&pairMode);
GAPBondMgr_SetParameter (GAPBOND_MITM_protection、sizeof (uint8_t)、&MIPTM);
GAPBondMgr_SetParameter (GAPBOND_IO_Capabilities、sizeof (uint8_t)、&ioCap);
GAPBondMgr_SetParameter (GAPBOND_BUSIONIND_ENABLED、sizeof (uint8_t)、&bonding);
}
//初始化 GATT 属性
GGS_AddService (GATT_ALL_SERVICES); // GAP
GATTServApp_AddService (GATT_All_services);// GATT 属性
DevInfo_AddService (); //设备信息服务
#ifndef Feature_OAD
SimpleProfile_AddService (GATT_All_services);//简单 GATT 配置文件
#endif //!Feature_OAD
#ifdef Feature_OAD
void OAD_addService (); // OAD 配置文件
OAD_register ((oadTargetCBs_t *)&simpleBLEPeripheral_oadCBs);
hOadQ = Util_constructQueue (&oadQ);
#endif
#ifdef image_invalidate
Reset_addService ();
#endif //image_invalidate
#ifndef Feature_OAD
//设置 SimpleProfile 特征值
{
uint8_t charValue1 = 1;
uint8_t charValue2 = 2;
uint8_t charValue3 = 3;
uint8_t charValue4 = 4;
uint8_t charValue5[SIMPLEPROFILE_CHAR5_LEN]={1、2、3、4、5};
SimpleProfile_SetParameter (SIMPLEPROFILE_CHAR1、sizeof (uint8_t)、
charValue1);
SimpleProfile_SetParameter (SIMPLEPROFILE_CHAR2、sizeof (uint8_t)、
charValue2);
SimpleProfile_SetParameter (SIMPLEPROFILE_CHAR3、sizeof (uint8_t)、
charValue3);
SimpleProfile_SetParameter (SIMPLEPROFILE_CHAR4、sizeof (uint8_t)、
charValue4);
SimpleProfile_SetParameter (SIMPLEPROFILE_CHAR5、SIMPLEPROFILE_CHAR5_LEN、
charValue5);
}
//使用 SimpleGATTprofile
SimpleProfile_RegisterAppCBs (&SimpleBLEPeripheral_simpleProfileCBs)注册回调;
#endif //!Feature_OAD
//启动设备
void GAPRole_StartDevice (&SimpleBLEPeripheral_gapRoleCBs);
//启动绑定管理
器 void GAPBondMgr_Register (&simpleBLEPeripheral_BondMgrCBs);
//使用 GAP 注册 HCI/主机消息
GAP_RegisterForMsgs (self 实体);
//注册 GATT 本地事件和待发送的 ATT 响应
GATT_RegisterForMsgs (self 实体);
#if defined Feature_OAD
#if defined (HAL_image_A)
LCD_WRITE_string ("BLE Peripheral A"、LCD_PAGE0);
#else
LCD_write_string ("BLE Peripheral B"、LCD_PAGE0);#lCD_enf
和#lcd/#t&tendif/#lcd/#lcd/#f/#feature/#lcd/#feature/#f/#lcd/#feature/f/
#feature #lcd/#lcd/#br/
/*********
*@fn SimpleBLEPeripheral_taskFxn
*
*@简单 BLE 外设的简要应用任务入口点。
*
*@param a0、A1 -未使用。
*
*@返回无。
//
静态空 SimpleBLEPeripheral_taskFxn (UARg a0、UARg A1)
{
//初始化应用
SimpleBLEPeripheral_init ();
//
应用程序主循环(;)
{
//等待与调用线程关联的信号量。
//请注意、当发出信号时、与线程关联的信号量会发出信号
//消息在线程的消息接收队列中排队,或在何时排队
// iCall_signal ()函数被调用到信号量上。
iCall_errno errno = iCall_Wait (ICALL_TIMEOUT_FOREVAL);
if (errno =ICALL_errno_Success)
{
iCall_EntityID dest;
iCall_ServiceEnum src;
iCall_HciExtEvt *pMsg =空;
if (iCall_fetchServiceMsg (&src、&dest、
(void **)&pMsg)=ICALL_errno_Success)
{
uint8 safeToDealloc = true;
IF (((src =ICALL_SERVICE_CLASS_BLE)&&(dest =self Entity))
{
iCall_Event *pEvt =(iCall_Event *) pMsg;
//首先检查 BLE 堆栈事件
if (pEvt->signature == 0xFFFF)
{
if (pEvt->EVENT_FLAG & SBP_CONN_EVT_END_EVT)
{
//尝试重新发送待处理的 ATT 响应(如果有)
SimpleBLEPeripheral_sendAttRsp();
}
}
其他
{
//处理任务间消息
SAFeToDealloc = SimpleBLEPeripheral_processStackMsg (
(iCall_HDR *) pMsg);
}
}
if (pMsg && safeToDealloc)
{
iCall_freeMsg (pMsg);
}
}
//如果 RTOS 队列不为空,则处理应用程序消息。
while (!Queue_empty (appMsgQueue))
{
sbpEvt_t *pMsg =(sbpEvt_t *) Util_dequeueMsg (appMsgQueue);
if (pMsg)
{
//处理消息。
SimpleBLEPeripheral_processAppMsg (pMsg);
//从消息中释放空间。
iCall_free (pMsg);
}
}
IF (事件和 SBP_Periode_EVT)
{
事件&=~SBP_Periode_EVT;
Util_startClock (周期时钟);
//执行周期性应用任务
SimpleBLEPeripheral_performPeriodicTask();
}
#ifdef Feature_OAD
while (!Queue_empty (hOadQ))
{
oadTargetWrite_t * oadWriteEvt = Queue_dequeue (hOadQ);
//识别新图像。
if (oadWriteEvt->event == OAD_WRITE_Identify_Req)
{
OAD_imgIdentifyWrite (oadWriteEvt->connHandle、oadWriteEvt->pData);
}
//写下一个块请求。
否则(oadWriteEvt->event =OAD_WRITE_BLOCK_REQ)
{
OAD_imgBlockWrite (oadWriteEvt->connHandle、oadWriteEvt->pData);
}
//自由缓冲区。
iCall_free (oadWriteEvt);
}
#endif //feature_OAD
}
}
/*********
*@fn SimpleBLEPeripheral_processStackMsg
*
*@简短地处理传入的堆栈消息。
*
*@param pMsg -要处理的消息
*
*@如果可以安全地取消分配传入消息、则返回 true、否则返回 false。
//
静态 uint8_t SimpleBLEPeripheral_processStackMsg (iCall_HDR *pMsg)
{
uint8_t safeToDealloc = true;
switch (pMsg->EVENT)
{
案例 GATT_MSG_EVENT:
//处理 GATT 消息
safeToDealloc = SimpleBLEPeripheral_processGATTMsg (
(gattMsgEvent_t *) pMsg);
中断;
案例 HCI_GAP_EVENT_EVENT:
{
//处理 HCI 消息
switch (pMsg->status)
{
案例 HCI_COMMAND_COMPLET_EVENT_CODE:
//处理 HCI 命令完成事件
中断;
默认值:
中断;
}
}
中断;
默认值:
//不执行任何操作
中断;
}
返回(safeToDealloc);
}
/*********
*@fn SimpleBLEPeripheral_processGATTMsg
*
@简短处理 GATT 消息和事件。
*
*@如果可以安全地取消分配传入消息、则返回 true、否则返回 false。
//
静态 uint8_t SimpleBLEPeripheral_processGATTMsg (gattMsgEvent_t *pMsg)
{
//查看 GATT 服务器是否无法发送 ATT 响应
(如果(pMsg->HDR.status == blePending)
{
//没有 HCI 缓冲器可用。 让我们尝试重新传输响应
//发生下一个连接事件。
if (HCI_EXT_ConnEventNoticeCmd (pMsg->connHandle、self 实体、
SBP_CONN_EVT_END_EVT)=成功)
{
//首先释放任何待处理的响应
SimpleBLEPeripheral_freeAttsp (故障);
//保持响应消息以重新传输
pAttRsp = pMsg;
//尚未释放响应消息
返回(false);
}
}
否则、如果(pMsg->method =ATT_flow_CTRL_쟖 랸_event)
{
// ATT 请求-响应或指示-确认流量控制为
//违反。 所有后续 ATT 请求或指示将被丢弃。
//如果应用程序想要断开连接,将通知该应用程序。
//显示导致违规的消息的操作码。
lcd_write_string_value ("FC inceeded:"、pMsg->msg.flowCtrlEvt.opcode、
10、LCD_page5);
}
否则、如果(pMsg->method =ATT_MTU_updated_event)
{
// MTU 大小已更新
lcd_write_string_value ("MTU 大小:"、pMsg->msg.mtuEvt.MTU、10、lcd_page5);
}
//自由消息有效载荷。 仅用于 ATT 协议消息
GATT_BM_FREE (&pMsg->msg、pMsg->method);
//释放传入的消息
返回是安全的(TRUE);
}
/*********
*@fn SimpleBLEPeripheral_sendAttRsp
*
*@简短发送待处理的 ATT 响应消息。
*
*@param none
*
*@return none
*/
static void SimpleBLEPeripheral_sendAttRsp (void)
{
//如果
(pAttRsp!= NULL)
、请查看是否有待处理的 ATT 响应要传输{
uint8_t status;
//递增重发计数
rspTxRetry++;
//尝试重新发送 ATT 响应,直到我们成功或
// ATT 客户端超时(30秒后)并断开连接。
status = GATT_SendRsp (pAttRsp->connHandle、pAttRsp->method、
&(pAttRs->msg));
if ((status!= blePending)&&(status!= MSG_buffer_no_avail))
{
//禁用连接事件结束通知
HCI_EXT_ConnEventNoticeCmd (pAttRsp->connHandle、self 实体、0);
//我们已完成响应消息
SimpleBLEPeripheral_freeAttsp (status);
}
其他
{
//继续重试
LCD_WRITE_STRING_VALUE ("RSP SEND RETRY:"、rspTxRetry、10、LCD_PAGE5);
}
}
/*********
*@fn SimpleBLEPeripheral_freeAttsp
*
*@简短的 Free ATT Response 消息。
*
**@param status - Response transmit status
*
*@return none
*/
static void SimpleBLEPeripheral_freeAttRsp (uint8_t status)
{
//如果
(pAttRsp!= NULL)、请查看是否存在待处理的 ATT 响应消息
{
//查看响应是否已成功发送
if (status == Success)(如果(状态==成功))
{
lcd_write_string_value ("rsp sent、retry:"、rspTxRetry、10、lcd_page5);
}
其他
{
//自由响应有效载荷
GATT_BM_FREE (&pAttRsp->msg、pAttRsp->method);
LCD_write_string_value ("RSP retry failed:"、rspTxRetry、10、LCD_page5);
}
//自由响应消息
iCall_freeMsg (pAttRsp);
//重置我们的全局变量
pAttRsp =空;
rspTxRetry = 0;
}
/*********
*@fn SimpleBLEPeripheral_processAppMsg
*
*@简要处理来自配置文件的传入回调。
*
*@param pMsg -要处理的消息
*
@返回无。
//
静态空 SimpleBLEPeripheral_processAppMsg (sbpEvt_t *pMsg)
{
switch (pMsg->HDR.event)
{
案例 SBP_State_change_EVT:
SimpleBLEPeripheral_processStateChangeEvt ((gaprole_states_t) pMsg->
HDR.state);
中断;
案例 SBP_CHAR_CHANGE_EVT:
SimpleBLEPeripheral_processCharValueChangeEvt (pMsg->HDR.state);
中断;
默认值:
//不执行任何操作。
中断;
}
/*********
*@fn SimpleBLEPeripheral_stateChangeCB
*
*@GAP 角色的简短回调、指示角色状态更改。
*
*@param newState - new state
*
*@return None。
*/
static void SimpleBLEPeripheral_stateChangeCB (gaprole_states_t newState)
{
SimpleBLEPeripheral_enqueueMsg (SBP_State_Change_EVT、newState);
}
/*********
*@fn SimpleBLEPeripheral_processStateChangeEvt
*
*@简要处理待处理的 GAP 角色状态更改事件。
*
*@param newState - new state
*
*@return None。
*/
static void SimpleBLEPeripheral_processStateChangeEvt (gaprole_states_t newState)
{
#ifdef plus_broadcaster
static bool ConnfirstFlag = false;
#endif // plus_broadcaster
switch (newState)
{
案例 GAPROLE_Started:
{
uint8_t ownAddress[B_ADDR_LEN];
uint8_t systemId[DevInfo_system_ID_LEN];
GAPRole_GetParameter (GAPROLE_BD_ADDR、ownAddress);
//将6个字节的设备地址用于8个字节的系统 ID 值
SystemID[0]= ownAddress[0];
SystemID[1]= ownAddress[1];
SystemID[2]= ownAddress[2];
//将中间字节设置为零
SystemID[4]= 0x00;
SystemID[3]= 0x00;
//向上移动三个字节
SystemID[7]= ownAddress[5];
SystemID[6]= ownAddress[4];
SystemID[5]= ownAddress[3];
DevInfo_SetParameter (DevInfo_system_ID、DevInfo_system_ID_LEN、
系统 ID);
//显示设备地址
LCD_WRITE_string (Util_convertBdAddr2Str (ownAddress)、LCD_Page1);
lcd_write_string ("已初始化"、lcd_Page2);
}
中断;
案例 GAPROLE_advertising:
LCD_write_string ("广播"、LCD_Page2);
break;
#ifdef plus_broadcaster
/*在断开连接后,PLUS_Broadcaster 中的设备将继续
*发送不可连接的广播并应发送此更改
向应用程序发送*状态。 然后在这里禁用这些功能、以便发送
*可以恢复可连接的广播。
*
案例 GAPROLE_advertising_NONCONN:
{
uint8_t advertEnabled = false;
//禁用非连接的广播。
GAPRole_SetParameter (GAPROLE_ADV_NONCONN_ENABLED、sizeof (uint8_t)、
advertEnabled (advertEnabled)(&D);
advertEnabled = true;
//启用可连接广播。
GAPRole_SetParameter (GAPROLE_Adverte_enabled、sizeof (uint8_t)、
advertEnabled (advertEnabled)(&D);
//重置下一个连接的标志。
firstConnFlag = false;
SimpleBLEPeripheral_freeAttsp (bleNotConnected);
}
break;
#endif //plus_broadcaster
案例 GAPROLE_Connected:
{
uint8_t peerAddress[B_ADDR_LEN];
GAPRole_GetParameter (GAPROLE_CONN_BD_ADDR、peerAddress);
Util_startClock (周期时钟);
lcd_write_string ("已连接"、lcd_Page2);
LCD_WRITE_string (Util_convertBdAddr2Str (peerAddress)、LCD_Page3);
#ifdef PLUS_Broadcaster
//仅在我们首次连接时打开此状态的广播
//否则、当我们从 connected 广播返回到该状态时
//我们将重新打开广播。
if (ConnfirstFlag = false)
{
uint8_t advertEnabled = false;//打开广播
//禁用可连接的广播。
GAPRole_SetParameter (GAPROLE_Adverte_enabled、sizeof (uint8_t)、
advertEnabled (advertEnabled)(&D);
//对于非连接的广播,设置为 true。
advertEnabled = true;
//启用非连接的广播。
GAPRole_SetParameter (GAPROLE_ADV_NONCONN_ENABLED、sizeof (uint8_t)、
advertEnabled (advertEnabled)(&D);
firstConnFlag = true;
}
#endif // plus_broadcaster
}
中断;
案例 GAPROLE_Connected ADV:
LCD_write_string ("连接广播"、LCD_Page2);
中断;
案例 GAPROLE_等待:
Util_stopClock (周期时钟);
SimpleBLEPeripheral_freeAttsp (bleNotConnected);
LCD_write_string ("断开连接"、LCD_Page2);
//清除剩余行
lcd_write_string (""、lcd_Page3);
lcd_write_string (""、lcd_page4);
lcd_write_string (""、lcd_page5);
中断;
案例 GAPROLE_WAITING_FACT_TIMEOUT:
SimpleBLEPeripheral_freeAttsp (bleNotConnected);
LCD_WRITE_STRING ("超时"、LCD_Page2);
//清除剩余行
lcd_write_string (""、lcd_Page3);
lcd_write_string (""、lcd_page4);
lcd_write_string (""、lcd_page5);
#ifdef PLUS_Broadcaster
//重置下一个连接的标志。
firstConnFlag = false;
#endif //#ifdef (PLUS_Broadcaster)
中断;
案例 GAPROLE_ERROR:
LCD_WRITE_STRING ("错误"、LCD_Page2);
中断;
默认值:
lcd_write_string (""、lcd_Page2);
break;
}
//更新状态
//gapProfileState = newState;
}
#ifndef Feature_OAD
/*********
*@fn SimpleBLEPeripheral_charValueChangeCB
*
*@简单配置文件中指示特征的简短回调
* 值变化。
*
*@param paramID -已更改值的参数 ID。
*
*@返回无。
*/
static void SimpleBLEPeripheral_charValueChangeCB (uint8_t paramID)
{
SimpleBLEPeripheral_enqueueMsg (SBP_char_change_evt、paramID);
}
#endif //!feature_OAD
/*********
*@fn SimpleBLEPeripheral_processCharValueChangeEvt
*
*@简要处理暂挂的简单配置文件特征值更改
* 事件。
*
*@param paramID -已更改值的参数 ID。
*
*@返回无。
*/
static void SimpleBLEPeripheral_processCharValueChangeEvt (uint8_t paramID)
{
#ifndef feature_OAD
uint8_t newValue;
switch (paramID)
{
SIMPLEPROFILE_CHAR1案例:
SimpleProfile_GetParameter (SIMPLEPROFILE_CHAR1、newValue);
lcd_write_string_value ("字符1:"、(uint16_t) newValue、10、lcd_page4);
中断;
SIMPLEPROFILE_CHAR3案例:
SimpleProfile_GetParameter (SIMPLEPROFILE_CHAR3、newValue);
lcd_write_string_value ("字符3:"、(uint16_t) newValue、10、lcd_page4);
中断;
默认值:
//不应该到达这里!
break;
}
#endif //!feature_OAD
}
/*********
*@fn SimpleBLEPeripheral_performPeriodicTask
*
*@brief 会执行周期性应用任务。 此函数被调用
* 每5秒(SBP_PERIOD_EVT_PERIOD)。 在此示例中、
* SimpleGATTProfile
*中第三个特征的值 服务从配置文件中检索、然后复制到
*中 第四个特征的值。
*
*@param 无。
*
*@返回无。
//
static void SimpleBLEPeripheral_performPeriodicTask (void)
{
#ifndef Feature_OAD
uint8_t valueToCopy;
//如果
(SimpleProfile_GetParameter (SIMPLEPROFILE_CHAR3、&valueToCopy)== Success)、则调用以检索配置文件中第三个特征的值
{
//调用以设置配置文件中第四个特征的值。
//请注意,如果已收到第四个特征的通知
// GATT 客户端设备启用,然后将发送通知
//每次调用此函数。
SimpleProfile_SetParameter (SIMPLEPROFILE_CHAR4、sizeof (uint8_t)、
ValueToCopy);
}
#endif //!Feature_OAD
}
#if defined (Feature_OAD)
/*********
*@fn SimpleBLEPeripheral_processOadWriteCB
*
*@简要处理一个到 OAD 配置文件的写入请求。
*
*@param 事件 -事件类型:
* OAD_WRITE_Identify_Req
* OAD_WRITE_BLOCK_REQ
*@param connHandle -此请求的连接句柄来自。
*@param pData -指向数据的指针,用于处理和/或存储。
*
*@返回无。
//
void SimpleBLEPeripheral_processOadWriteCB (uint8_t 事件、uint16_t connHandle、
uint8_t *pData)
{
oadTargetWrite_t * oadWriteEvt = iCall_malloc (sizeof (oadTargetWrite_t)+\
sizeof (uint8_t)* OAD_packet_size);
if (oadWriteEvt!= NULL)
{
oadWriteEvt->event = event;
oadWriteEvt->connHandle = connHandle;
oadWriteEvt->pData =(uint8_t *)(oadWriteEvt->pData + 1);
memcpy (oadWriteEvt->pData、pData、OAD_packet_size);
Queue_enqueue (hOadQ、(Queue_Elem *) oadWriteEvt);
//发布应用程序的信标。
Semaphore_post (sem);
}
否则
{
//无提示失败
。}
}
#endif //feature_OAD/
*********
*@fn SimpleBLEPeripheral_clockHandler
*
*@用于时钟超时的简短处理函数。
*
*@param arg -事件类型
*
@返回无。
*/
static void SimpleBLEPeripheral_clockHandler (UARg arg)
{
//存储事件。
Events |= arg;
//唤醒应用程序。
Semaphore_post (SEM);
}
/*********
*@fn SimpleBLEPeripheral_enqueueMsg
*
*@brief 会创建一条消息并将该消息放入 RTOS 队列中。
*
*@param 事件-消息事件。
*@参数状态-消息状态。
*
*@返回无。
//
静态空 SimpleBLEPeripheral_enqueueMsg (uint8_t 事件、uint8_t 状态)
{
sbpEvt_t *pMsg;
//创建消息的动态指针。
if (((pMsg = iCall_malloc (sizeof (sbpEvt_t))))
){
pMsg->HDR.EVENT =事件;
pMsg->HDR.state = state;
//将消息排队。
Util_enqueueMsg (appMsgQueue、SEM、(uint8*) pMsg);
}
/*********
(三 /
大家好!
我正在使用 Smart RF06开发板对简单的 BLE 外设项目进行编程。当我运行它时 、LCD 上会显示"广播"、但当我在智能手机中启用蓝牙时 、智能手机中不会显示名称、这可能是有原因的。任何帮助都值得赞赏。
下面随附的是 simpleblepherhipal.c 文件