BLE_DCF_TYQ_CH592F/APP/peripheral.c

952 lines
31 KiB
C
Raw Normal View History

2024-12-02 16:26:55 +08:00
/********************************** (C) COPYRIGHT *******************************
* File Name : peripheral.C
* Author : WCH
* Version : V1.0
* Date : 2018/12/10
2024-12-13 13:22:31 +08:00
* Description : 广广
*
2024-12-02 16:26:55 +08:00
*********************************************************************************
* Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
2024-12-02 17:03:41 +08:00
* Attention: This software (modified or not) and binary are used for
2024-12-02 16:26:55 +08:00
* microcontroller manufactured by Nanjing Qinheng Microelectronics.
*******************************************************************************/
/*********************************************************************
* INCLUDES
*/
#include "CONFIG.h"
#include "devinfoservice.h"
#include "gattprofile.h"
#include "peripheral.h"
2024-12-12 19:38:57 +08:00
#include "bsp_valve.h"
2024-12-13 13:22:31 +08:00
#include "bsp_uart.h"
2024-12-12 19:38:57 +08:00
#include "log.h"
2024-12-14 18:40:24 +08:00
#include "bsp_i2c.h"
#include "bsp_adc.h"
2024-12-12 19:38:57 +08:00
#undef LOG_ENABLE
2024-12-14 18:40:24 +08:00
#define LOG_ENABLE 1
2024-12-12 19:38:57 +08:00
#undef LOG_TAG
2024-12-13 13:22:31 +08:00
#define LOG_TAG "peripheral"
2024-12-12 19:38:57 +08:00
2024-12-02 16:26:55 +08:00
/*********************************************************************
* MACROS
*/
/*********************************************************************
* CONSTANTS
*/
// How often to perform periodic event
2024-12-15 14:30:06 +08:00
#define SBP_PERIODIC_EVT_PERIOD (160 * 10) // (160 = 100ms)
2024-12-02 16:26:55 +08:00
// How often to perform read rssi event
2024-12-15 14:30:06 +08:00
#define SBP_READ_RSSI_EVT_PERIOD (1600 * 3) // (160 = 100ms)
2024-12-02 16:26:55 +08:00
// Parameter update delay
2024-12-15 14:30:06 +08:00
#define SBP_PARAM_UPDATE_DELAY (1600 * 4)
2024-12-02 16:26:55 +08:00
// PHY update delay
2024-12-15 14:30:06 +08:00
#define SBP_PHY_UPDATE_DELAY (1600 * 2)
2024-12-02 16:26:55 +08:00
// What is the advertising interval when device is discoverable (units of 625us, 80=50ms)
2024-12-14 18:40:24 +08:00
#define DEFAULT_ADVERTISING_INTERVAL (160 * 1)
2024-12-02 16:26:55 +08:00
// Limited discoverable mode advertises for 30.72s, and then stops
// General discoverable mode advertises indefinitely
#define DEFAULT_DISCOVERABLE_MODE GAP_ADTYPE_FLAGS_GENERAL
// Minimum connection interval (units of 1.25ms, 6=7.5ms)
2024-12-15 14:30:06 +08:00
#define DEFAULT_DESIRED_MIN_CONN_INTERVAL (80 * 5) // (80 = 100ms)
2024-12-02 16:26:55 +08:00
// Maximum connection interval (units of 1.25ms, 100=125ms)
2024-12-09 16:13:41 +08:00
#define DEFAULT_DESIRED_MAX_CONN_INTERVAL (80 * 10)
2024-12-02 16:26:55 +08:00
// Slave latency to use parameter update
2024-12-09 16:13:41 +08:00
#define DEFAULT_DESIRED_SLAVE_LATENCY 3
2024-12-02 16:26:55 +08:00
// Supervision timeout value (units of 10ms, 100=1s)
2024-12-09 16:13:41 +08:00
#define DEFAULT_DESIRED_CONN_TIMEOUT (100 * 5)
2024-12-02 16:26:55 +08:00
// Company Identifier: WCH
#define WCH_COMPANY_ID 0x07D7
/*********************************************************************
* TYPEDEFS
*/
/*********************************************************************
* GLOBAL VARIABLES
*/
/*********************************************************************
* EXTERNAL VARIABLES
*/
/*********************************************************************
* EXTERNAL FUNCTIONS
*/
/*********************************************************************
* LOCAL VARIABLES
*/
static uint8_t Peripheral_TaskID = INVALID_TASK_ID; // Task ID for internal task/event processing
// GAP - SCAN RSP data (max size = 31 bytes)
static uint8_t scanRspData[] = {
// complete name
0x12, // length of this data
GAP_ADTYPE_LOCAL_NAME_COMPLETE,
2024-12-15 14:30:06 +08:00
's', 'i', 'm', 'p', 'l', 'e', ' ', 'P', 'e', 'r', 'i', 'p', 'h', 'e', 'r', 'a', 'l',
2024-12-02 16:26:55 +08:00
// connection interval range
0x05, // length of this data
GAP_ADTYPE_SLAVE_CONN_INTERVAL_RANGE,
LO_UINT16(DEFAULT_DESIRED_MIN_CONN_INTERVAL), // 100ms
HI_UINT16(DEFAULT_DESIRED_MIN_CONN_INTERVAL),
LO_UINT16(DEFAULT_DESIRED_MAX_CONN_INTERVAL), // 1s
HI_UINT16(DEFAULT_DESIRED_MAX_CONN_INTERVAL),
// Tx power level
0x02, // length of this data
GAP_ADTYPE_POWER_LEVEL,
0 // 0dBm
};
// GAP - Advertisement data (max size = 31 bytes, though this is
// best kept short to conserve power while advertising)
static uint8_t advertData[] = {
// Flags; this sets the device to use limited discoverable
// mode (advertises for 30 seconds at a time) instead of general
// discoverable mode (advertises indefinitely)
0x02, // length of this data
GAP_ADTYPE_FLAGS,
DEFAULT_DISCOVERABLE_MODE | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED,
// service UUID, to notify central devices what services are included
// in this peripheral
0x03, // length of this data
GAP_ADTYPE_16BIT_MORE, // some of the UUID's, but not all
LO_UINT16(SIMPLEPROFILE_SERV_UUID),
HI_UINT16(SIMPLEPROFILE_SERV_UUID)
};
2024-12-08 11:29:48 +08:00
#if 0
2024-12-13 13:22:31 +08:00
// 蓝牙广播包的最大长度是37个字节其中设备地址占用了6个字节只有31个字节是可用的。
2024-12-08 11:29:48 +08:00
// GAP - SCAN RSP data (max size = 31 bytes)
static uint8_t scanRspData[] = {
// complete name
0x08, // length of this data
GAP_ADTYPE_LOCAL_NAME_COMPLETE,
'B',
'L',
'E',
'-',
'T',
'Y',
'Q',
// connection interval range
0x05, // length of this data
GAP_ADTYPE_SLAVE_CONN_INTERVAL_RANGE,
LO_UINT16(DEFAULT_DESIRED_MIN_CONN_INTERVAL), // 100ms
HI_UINT16(DEFAULT_DESIRED_MIN_CONN_INTERVAL),
LO_UINT16(DEFAULT_DESIRED_MAX_CONN_INTERVAL), // 1s
HI_UINT16(DEFAULT_DESIRED_MAX_CONN_INTERVAL),
// Tx power level
0x02, // length of this data
GAP_ADTYPE_POWER_LEVEL,
0 // 0dBm
0x03, // length of this data
GAP_ADTYPE_MANUFACTURER_SPECIFIC,
2024-12-13 13:22:31 +08:00
// 前两个字节表示厂商 ID
2024-12-08 11:29:48 +08:00
0,
0,
2024-12-13 13:22:31 +08:00
0x10, // 1B 电池电压 30=3V,18=1.8V
0x01, // 1B 阀门类型
0x00, // 1B 阀门工作状态 超欠压、过流
0x00, // 1B 阀门连接状态 电磁阀BLE控制盒 0=未连接 1=已连接
0x01, // 1B 阀门开关状态 0=未知 1=关闭 2=关闭过,未按按键恢复 3=关闭过,按下了恢复键 4=打开
0x03, // 1B 阀门温度 有符号整数 25 C
0x04, // 1B 阀门进口压力 0~156 (0)kPa
0x05, // 1B 阀门出口压力 0~100 hPa 0.1kpa
0x06, // 1B 阀门大气压力 80~110 kPa
2024-12-08 11:29:48 +08:00
};
2024-12-10 15:39:32 +08:00
2024-12-08 11:29:48 +08:00
// GAP - Advertisement data (max size = 31 bytes, though this is
// best kept short to conserve power while advertising)
static uint8_t advertData[] = {
// Flags; this sets the device to use limited discoverable
// mode (advertises for 30 seconds at a time) instead of general
// discoverable mode (advertises indefinitely)
0x02, // length of this data
GAP_ADTYPE_FLAGS,
DEFAULT_DISCOVERABLE_MODE | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED,
// service UUID, to notify central devices what services are included
// in this peripheral
0x03, // length of this data
GAP_ADTYPE_16BIT_MORE, // some of the UUID's, but not all
LO_UINT16(SIMPLEPROFILE_SERV_UUID),
HI_UINT16(SIMPLEPROFILE_SERV_UUID)
};
#endif
2024-12-02 16:26:55 +08:00
// GAP GATT Attributes
static uint8_t attDeviceName[GAP_DEVICE_NAME_LEN] = "Simple Peripheral";
// Connection item list
static peripheralConnItem_t peripheralConnList;
static uint16_t peripheralMTU = ATT_MTU_SIZE;
/*********************************************************************
* LOCAL FUNCTIONS
*/
static void Peripheral_ProcessTMOSMsg(tmos_event_hdr_t *pMsg);
static void peripheralStateNotificationCB(gapRole_States_t newState, gapRoleEvent_t *pEvent);
2024-12-13 18:14:02 +08:00
static void UploadPeriodicTask(void);
2024-12-02 16:26:55 +08:00
static void simpleProfileChangeCB(uint8_t paramID, uint8_t *pValue, uint16_t len);
static void peripheralParamUpdateCB(uint16_t connHandle, uint16_t connInterval,
uint16_t connSlaveLatency, uint16_t connTimeout);
static void peripheralInitConnItem(peripheralConnItem_t *peripheralConnList);
static void peripheralRssiCB(uint16_t connHandle, int8_t rssi);
static void peripheralChar4Notify(uint8_t *pValue, uint16_t len);
/*********************************************************************
* PROFILE CALLBACKS
*/
// GAP Role Callbacks
static gapRolesCBs_t Peripheral_PeripheralCBs = {
peripheralStateNotificationCB, // Profile State Change Callbacks
peripheralRssiCB, // When a valid RSSI is read from controller (not used by application)
peripheralParamUpdateCB
};
// Broadcast Callbacks
static gapRolesBroadcasterCBs_t Broadcaster_BroadcasterCBs = {
NULL, // Not used in peripheral role
NULL // Receive scan request callback
};
// GAP Bond Manager Callbacks
static gapBondCBs_t Peripheral_BondMgrCBs = {
NULL, // Passcode callback (not used by application)
NULL, // Pairing / Bonding state Callback (not used by application)
NULL // oob callback
};
// Simple GATT Profile Callbacks
static simpleProfileCBs_t Peripheral_SimpleProfileCBs = {
simpleProfileChangeCB // Characteristic value change callback
};
/*********************************************************************
* PUBLIC FUNCTIONS
*/
/*********************************************************************
* @fn Peripheral_Init
*
* @brief Initialization function for the Peripheral App Task.
* This is called during initialization and should contain
* any application specific initialization (ie. hardware
* initialization/setup, table initialization, power up
* notificaiton ... ).
*
* @param task_id - the ID assigned by TMOS. This ID should be
* used to send messages and set timers.
*
* @return none
*/
void Peripheral_Init()
{
Peripheral_TaskID = TMOS_ProcessEventRegister(Peripheral_ProcessEvent);
// Setup the GAP Peripheral Role Profile
{
2024-12-13 13:22:31 +08:00
//开启广播使能
2024-12-02 16:26:55 +08:00
uint8_t initial_advertising_enable = TRUE;
2024-12-13 13:22:31 +08:00
//最小连接间隔
2024-12-02 16:26:55 +08:00
uint16_t desired_min_interval = DEFAULT_DESIRED_MIN_CONN_INTERVAL;
2024-12-13 13:22:31 +08:00
//最大连接间隔
2024-12-02 16:26:55 +08:00
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);
2024-12-15 14:30:06 +08:00
2024-12-02 16:26:55 +08:00
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);
2024-12-08 11:29:48 +08:00
// https://www.cnblogs.com/debugdabiaoge/p/17871551.html
2024-12-13 13:22:31 +08:00
// 默认从机在回复扫描请求后,会结束广播事件(默认广播应该是 37 38 39 在 3 个信道轮发)
// 如下使能后,可以保证广播包不受扫描请求的影响
2024-12-08 11:29:48 +08:00
// uint16_t adv_event_contnue=1<<1;
// GAP_SetParamValue(TGAP_ADV_SCAN_REQ_NOTIFY, adv_event_contnue);
2024-12-02 16:26:55 +08:00
// Enable scan req notify
GAP_SetParamValue(TGAP_ADV_SCAN_REQ_NOTIFY, ENABLE);
}
// Setup the GAP Bond Manager
{
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, GAP_DEVICE_NAME_LEN, 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);
}
/*********************************************************************
* @fn peripheralInitConnItem
*
* @brief Init Connection Item
*
* @param peripheralConnList -
*
* @return NULL
*/
static void peripheralInitConnItem(peripheralConnItem_t *peripheralConnList)
{
peripheralConnList->connHandle = GAP_CONNHANDLE_INIT;
peripheralConnList->connInterval = 0;
peripheralConnList->connSlaveLatency = 0;
peripheralConnList->connTimeout = 0;
}
/*********************************************************************
* @fn Peripheral_ProcessEvent
*
* @brief Peripheral Application Task event processor. This function
* is called to process all events for the task. Events
* include timers, messages and any other user defined events.
*
* @param task_id - The TMOS assigned task ID.
* @param events - events to process. This is a bit map and can
* contain more than one event.
*
* @return events not processed
*/
uint16_t Peripheral_ProcessEvent(uint8_t task_id, uint16_t events)
{
// VOID task_id; // TMOS required parameter that isn't used in this function
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)
{
// Start the Device
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
2024-12-13 18:14:02 +08:00
UploadPeriodicTask();
2024-12-02 16:26:55 +08:00
return (events ^ SBP_PERIODIC_EVT);
}
if(events & SBP_PARAM_UPDATE_EVT)
{
// Send connect param update request
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
2024-12-13 13:22:31 +08:00
logDebug("PHY Update %x...", GAPRole_UpdatePHY(peripheralConnList.connHandle, 0,
2024-12-02 16:26:55 +08:00
GAP_PHY_BIT_LE_2M, GAP_PHY_BIT_LE_2M, 0));
return (events ^ SBP_PHY_UPDATE_EVT);
}
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;
}
/*********************************************************************
* @fn Peripheral_ProcessGAPMsg
*
* @brief Process an incoming task message.
*
* @param pMsg - message to process
*
* @return none
*/
static void Peripheral_ProcessGAPMsg(gapRoleEvent_t *pEvent)
{
switch(pEvent->gap.opcode)
{
case GAP_SCAN_REQUEST_EVENT:
{
2024-12-12 19:38:57 +08:00
logDebug("Receive scan req from %x %x %x %x %x %x ..\n", pEvent->scanReqEvt.scannerAddr[0],
2024-12-02 16:26:55 +08:00
pEvent->scanReqEvt.scannerAddr[1], pEvent->scanReqEvt.scannerAddr[2], pEvent->scanReqEvt.scannerAddr[3],
pEvent->scanReqEvt.scannerAddr[4], pEvent->scanReqEvt.scannerAddr[5]);
break;
}
case GAP_PHY_UPDATE_EVENT:
{
2024-12-12 19:38:57 +08:00
logDebug("Phy update Rx:%x Tx:%x ..\n", pEvent->linkPhyUpdate.connRxPHYS, pEvent->linkPhyUpdate.connTxPHYS);
2024-12-02 16:26:55 +08:00
break;
}
default:
break;
}
}
/*********************************************************************
* @fn Peripheral_ProcessTMOSMsg
*
* @brief Process an incoming task message.
*
* @param pMsg - message to process
*
* @return none
*/
static void Peripheral_ProcessTMOSMsg(tmos_event_hdr_t *pMsg)
{
switch(pMsg->event)
{
case GAP_MSG_EVENT:
{
Peripheral_ProcessGAPMsg((gapRoleEvent_t *)pMsg);
break;
}
case GATT_MSG_EVENT:
{
gattMsgEvent_t *pMsgEvent;
pMsgEvent = (gattMsgEvent_t *)pMsg;
if(pMsgEvent->method == ATT_MTU_UPDATED_EVENT)
{
peripheralMTU = pMsgEvent->msg.exchangeMTUReq.clientRxMTU;
2024-12-12 19:38:57 +08:00
logDebug("mtu exchange: %d\n", pMsgEvent->msg.exchangeMTUReq.clientRxMTU);
2024-12-02 16:26:55 +08:00
}
break;
}
default:
break;
}
}
/*********************************************************************
* @fn Peripheral_LinkEstablished
*
* @brief Process link established.
*
* @param pEvent - event to process
*
* @return none
*/
static void Peripheral_LinkEstablished(gapRoleEvent_t *pEvent)
{
gapEstLinkReqEvent_t *event = (gapEstLinkReqEvent_t *)pEvent;
// See if already connected
if(peripheralConnList.connHandle != GAP_CONNHANDLE_INIT)
{
GAPRole_TerminateLink(pEvent->linkCmpl.connectionHandle);
2024-12-15 14:30:06 +08:00
logDebug("Connection max...");
2024-12-02 16:26:55 +08:00
}
else
{
peripheralConnList.connHandle = event->connectionHandle;
peripheralConnList.connInterval = event->connInterval;
peripheralConnList.connSlaveLatency = event->connLatency;
peripheralConnList.connTimeout = event->connTimeout;
peripheralMTU = ATT_MTU_SIZE;
// Set timer for periodic event
tmos_start_task(Peripheral_TaskID, SBP_PERIODIC_EVT, SBP_PERIODIC_EVT_PERIOD);
// Set timer for param update event
tmos_start_task(Peripheral_TaskID, SBP_PARAM_UPDATE_EVT, SBP_PARAM_UPDATE_DELAY);
// Start read rssi
tmos_start_task(Peripheral_TaskID, SBP_READ_RSSI_EVT, SBP_READ_RSSI_EVT_PERIOD);
2024-12-12 19:38:57 +08:00
logDebug("Conn %x - Int %x \n", event->connectionHandle, event->connInterval);
2024-12-02 16:26:55 +08:00
}
}
/*********************************************************************
* @fn Peripheral_LinkTerminated
*
* @brief Process link terminated.
*
* @param pEvent - event to process
*
* @return none
*/
static void Peripheral_LinkTerminated(gapRoleEvent_t *pEvent)
{
gapTerminateLinkEvent_t *event = (gapTerminateLinkEvent_t *)pEvent;
if(event->connectionHandle == peripheralConnList.connHandle)
{
peripheralConnList.connHandle = GAP_CONNHANDLE_INIT;
peripheralConnList.connInterval = 0;
peripheralConnList.connSlaveLatency = 0;
peripheralConnList.connTimeout = 0;
tmos_stop_task(Peripheral_TaskID, SBP_PERIODIC_EVT);
tmos_stop_task(Peripheral_TaskID, SBP_READ_RSSI_EVT);
// Restart advertising
{
2024-12-15 14:30:06 +08:00
// 三个广播通道全部打开
// uint8_t init_adv_channel_map = GAP_ADVCHAN_ALL ;
// GAPRole_SetParameter( GAPROLE_ADV_CHANNEL_MAP, sizeof( uint8_t ), &init_adv_channel_map);
// 开启广播
2024-12-02 16:26:55 +08:00
uint8_t advertising_enable = TRUE;
GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t), &advertising_enable);
}
}
else
{
2024-12-15 14:30:06 +08:00
logError("ERR..");
2024-12-02 16:26:55 +08:00
}
}
/*********************************************************************
* @fn peripheralRssiCB
*
* @brief RSSI callback.
*
* @param connHandle - connection handle
* @param rssi - RSSI
*
* @return none
*/
static void peripheralRssiCB(uint16_t connHandle, int8_t rssi)
{
2024-12-12 19:38:57 +08:00
logDebug("RSSI -%d dB Conn %x \n", -rssi, connHandle);
2024-12-02 16:26:55 +08:00
}
/*********************************************************************
* @fn peripheralParamUpdateCB
*
* @brief Parameter update complete callback
*
* @param connHandle - connect handle
* connInterval - connect interval
* connSlaveLatency - connect slave latency
* connTimeout - connect timeout
*
* @return none
*/
static void peripheralParamUpdateCB(uint16_t connHandle, uint16_t connInterval,
uint16_t connSlaveLatency, uint16_t connTimeout)
{
if(connHandle == peripheralConnList.connHandle)
{
peripheralConnList.connInterval = connInterval;
peripheralConnList.connSlaveLatency = connSlaveLatency;
peripheralConnList.connTimeout = connTimeout;
2024-12-12 19:38:57 +08:00
logDebug("peripheralParamUpdateCB (connHandle)%x - (connInterval) %x- (connSlaveLatency) %x - (connTimeout) %x\n"
, connHandle, connInterval, connSlaveLatency, connTimeout);
2024-12-02 16:26:55 +08:00
}
else
{
2024-12-15 14:30:06 +08:00
logError("ERR..");
2024-12-02 16:26:55 +08:00
}
}
/*********************************************************************
* @fn peripheralStateNotificationCB
*
* @brief Notification from the profile of a state change.
*
* @param newState - new state
*
* @return none
*/
static void peripheralStateNotificationCB(gapRole_States_t newState, gapRoleEvent_t *pEvent)
{
switch(newState & GAPROLE_STATE_ADV_MASK)
{
case GAPROLE_STARTED:
2024-12-15 14:30:06 +08:00
logDebug("Initialized..");
2024-12-02 16:26:55 +08:00
break;
case GAPROLE_ADVERTISING:
if(pEvent->gap.opcode == GAP_LINK_TERMINATED_EVENT)
{
Peripheral_LinkTerminated(pEvent);
2024-12-12 19:38:57 +08:00
logDebug("Disconnected.. Reason:%x\n", pEvent->linkTerminate.reason);
2024-12-15 14:30:06 +08:00
logDebug("Advertising..");
2024-12-02 16:26:55 +08:00
}
else if(pEvent->gap.opcode == GAP_MAKE_DISCOVERABLE_DONE_EVENT)
{
2024-12-15 14:30:06 +08:00
logDebug("Advertising..");
2024-12-02 16:26:55 +08:00
}
break;
case GAPROLE_CONNECTED:
if(pEvent->gap.opcode == GAP_LINK_ESTABLISHED_EVENT)
{
Peripheral_LinkEstablished(pEvent);
2024-12-15 14:30:06 +08:00
logDebug("Connected..");
2024-12-02 16:26:55 +08:00
}
break;
case GAPROLE_CONNECTED_ADV:
if(pEvent->gap.opcode == GAP_MAKE_DISCOVERABLE_DONE_EVENT)
{
2024-12-15 14:30:06 +08:00
logDebug("Connected Advertising..");
2024-12-02 16:26:55 +08:00
}
break;
case GAPROLE_WAITING:
if(pEvent->gap.opcode == GAP_END_DISCOVERABLE_DONE_EVENT)
{
2024-12-15 14:30:06 +08:00
logDebug("Waiting for advertising..");
2024-12-02 16:26:55 +08:00
}
else if(pEvent->gap.opcode == GAP_LINK_TERMINATED_EVENT)
{
Peripheral_LinkTerminated(pEvent);
2024-12-12 19:38:57 +08:00
logDebug("Disconnected.. Reason:%x\n", pEvent->linkTerminate.reason);
2024-12-02 16:26:55 +08:00
}
else if(pEvent->gap.opcode == GAP_LINK_ESTABLISHED_EVENT)
{
if(pEvent->gap.hdr.status != SUCCESS)
{
2024-12-15 14:30:06 +08:00
logDebug("Waiting for advertising..");
2024-12-02 16:26:55 +08:00
}
else
{
2024-12-15 14:30:06 +08:00
logDebug("Error..");
2024-12-02 16:26:55 +08:00
}
}
else
{
2024-12-12 19:38:57 +08:00
logDebug("Error..%x\n", pEvent->gap.opcode);
2024-12-02 16:26:55 +08:00
}
break;
case GAPROLE_ERROR:
2024-12-15 14:30:06 +08:00
logDebug("Error..");
2024-12-02 16:26:55 +08:00
break;
default:
break;
}
}
/*********************************************************************
2024-12-13 18:14:02 +08:00
* @fn UploadPeriodicTask
2024-12-02 16:26:55 +08:00
*
* @brief Perform a periodic application task. This function gets
* called every five seconds as a result of the SBP_PERIODIC_EVT
* TMOS event. In this example, the value of the third
* characteristic in the SimpleGATTProfile service is retrieved
* from the profile, and then copied into the value of the
* the fourth characteristic.
*
* @param none
*
* @return none
*/
2024-12-13 18:14:02 +08:00
static void UploadPeriodicTask(void)
2024-12-02 16:26:55 +08:00
{
2024-12-12 19:38:57 +08:00
// static uint8_t counter = 0;
// uint8_t notiData[SIMPLEPROFILE_CHAR4_LEN] = {0x11, 0x22, 0x33, 0x44, 0};
// notiData[4] = counter;
// // peripheralChar4Notify(notiData, SIMPLEPROFILE_CHAR4_LEN);
// peripheralChar4Notify(notiData, 5);
// counter++;
2024-12-14 18:40:24 +08:00
#if 1
// VBAT
uint32_t CountBat = 0;
uint16_t adcBuff[40];
uint8_t i = 0;
// uint32_t countadc = 0;
uint16_t min_number = 0;
uint16_t max_number = 0;
ADC_InterBATSampInit();
for (i = 0; i < 20; i++)
{
adcBuff[i] = ADC_ExcutSingleConver(); // 连续采样20次
}
for (i = 0; i < 20; i++)
{
CountBat += adcBuff[i];
if (i == 0)
{
min_number = adcBuff[i];
max_number = adcBuff[i];
}
min_number = ((min_number > adcBuff[i]) ? adcBuff[i] : min_number); // 软件滤波
max_number = ((max_number < adcBuff[i]) ? adcBuff[i] : max_number);
}
logDebug("min_number = %d, max_number = %d", min_number, max_number);
CountBat = (CountBat - min_number - max_number) / 18; // 删除最小与最大值
logDebug("AverageCountBat = %d", CountBat);
#endif
int ret;
GXHTC3C_Wakeup();
DelayMs(20);
GXHTC3C_GetStart();
DelayMs(20);
float humi, temp;
ret = GXHTC3C_GetTempHumi(&humi, &temp);
if (ret == 0)
2024-12-12 19:38:57 +08:00
{
2024-12-14 18:40:24 +08:00
logDebug("humi %.2f %, temp %.2f C", humi, temp);
2024-12-12 19:38:57 +08:00
}
2024-12-14 18:40:24 +08:00
GXHTC3C_Sleep();
TsRawFrameData RawData;
// static uint8_t humi;
// humi++;
BSP_VALVE_Generate_Data(&RawData, 0, CountBat/100, temp, humi);
// if (humi > 99)
// {
// humi = 0;
// }
2024-12-12 19:38:57 +08:00
peripheralChar4Notify(&RawData.buf[0], RawData.len);
2024-12-02 16:26:55 +08:00
}
/*********************************************************************
* @fn peripheralChar4Notify
*
* @brief Prepare and send simpleProfileChar4 notification
*
* @param pValue - data to notify
* len - length of data
*
* @return none
*/
static void peripheralChar4Notify(uint8_t *pValue, uint16_t len)
{
attHandleValueNoti_t noti;
if(len > (peripheralMTU - 3))
{
2024-12-13 13:22:31 +08:00
logDebug("Too large noti");
2024-12-02 16:26:55 +08:00
return;
}
noti.len = len;
noti.pValue = GATT_bm_alloc(peripheralConnList.connHandle, ATT_HANDLE_VALUE_NOTI, noti.len, NULL, 0);
if(noti.pValue)
{
tmos_memcpy(noti.pValue, pValue, noti.len);
if(simpleProfile_Notify(peripheralConnList.connHandle, &noti) != SUCCESS)
{
GATT_bm_free((gattMsg_t *)&noti, ATT_HANDLE_VALUE_NOTI);
}
}
}
2024-12-12 19:38:57 +08:00
2024-12-02 16:26:55 +08:00
/*********************************************************************
* @fn simpleProfileChangeCB
*
* @brief Callback from SimpleBLEProfile indicating a value change
*
* @param paramID - parameter ID of the value that was changed.
* pValue - pointer to data that was changed
* len - length of data
*
* @return none
*/
static void simpleProfileChangeCB(uint8_t paramID, uint8_t *pValue, uint16_t len)
{
2024-12-15 14:30:06 +08:00
// tmos_event_hdr_t *test_message;
2024-12-12 19:38:57 +08:00
TsRawFrameData RawData;
2024-12-02 16:26:55 +08:00
switch(paramID)
{
case SIMPLEPROFILE_CHAR1:
{
uint8_t newValue[SIMPLEPROFILE_CHAR1_LEN];
tmos_memcpy(newValue, pValue, len);
2024-12-15 14:30:06 +08:00
logDebug("profile ChangeCB CHAR1.. Start");
for (uint8_t i = 0; i < len; i++)
{
2024-12-12 19:38:57 +08:00
logDebug("%02x ", newValue[i]);
2024-12-13 13:22:31 +08:00
BSP_UART1_TxLoop();
}
2024-12-15 14:30:06 +08:00
logDebug("\n profile ChangeCB CHAR1.. End");
// test_message =(tmos_event_hdr_t*) tmos_msg_allocate(sizeof(tmos_event_hdr_t));
2024-12-13 13:22:31 +08:00
BSP_UART1_TxLoop();
2024-12-15 14:30:06 +08:00
2024-12-02 16:26:55 +08:00
break;
}
case SIMPLEPROFILE_CHAR3:
{
2024-12-13 18:14:02 +08:00
uint8_t newValue[SIMPLEPROFILE_CHAR3_LEN];
2024-12-12 19:38:57 +08:00
tmos_memset(newValue, 0, sizeof(newValue));
2024-12-02 16:26:55 +08:00
tmos_memcpy(newValue, pValue, len);
2024-12-13 13:22:31 +08:00
logDebug("CHAR3 Start");
logHexDumpAll(newValue, len);
// for (uint8_t i = 0; i < len; i++)
// {
// logDebug("%02x ", newValue[i]);
// }
2024-12-12 19:38:57 +08:00
#if 1
TsFrameData *HostFrameData = BSP_VAVLE_GetFrameData(newValue, len);
if (HostFrameData != NULL)
{
2024-12-13 13:22:31 +08:00
// logHexDumpAll(&HostFrameData->data[0], HostFrameData->len); // 数据段
// BSP_UART1_TxLoop();
2024-12-12 19:38:57 +08:00
// HR_ProcessData(HostFrameData);
switch (HostFrameData->cmd)
{
case kCmdCfg:
// uint8_t data_buf[64] = {0};
// tmos_memset(data_buf, 0, sizeof(data_buf));
2024-12-13 13:22:31 +08:00
// 处理数据帧
2024-12-12 19:38:57 +08:00
logDebug("kCmdCfg");
break;
case kCmdCloseVavle:
logDebug("kCmdCloseVavle");
BSP_VALVE_Generate_ValveResponse(&RawData, kCmdCloseVavle, 1);
peripheralChar4Notify((uint8_t*)&RawData.buf[0], RawData.len);
2024-12-13 13:22:31 +08:00
BSP_UART1_TxLoop();
2024-12-12 19:38:57 +08:00
break;
case kCmdOpenVavle:
logDebug("kCmdOpenVavle");
BSP_VALVE_Generate_ValveResponse(&RawData, kCmdOpenVavle, 1);
peripheralChar4Notify((uint8_t*)&RawData.buf[0], RawData.len);
2024-12-13 13:22:31 +08:00
BSP_UART1_TxLoop();
2024-12-12 19:38:57 +08:00
break;
default:
2024-12-13 13:22:31 +08:00
logError("无效的命令");
2024-12-12 19:38:57 +08:00
// logHexDumpAll(data, len);
break;
}
}
2024-12-13 13:22:31 +08:00
else
{
logError("数据帧解析失败");
}
2024-12-12 19:38:57 +08:00
tmos_msg_deallocate((uint8_t*)HostFrameData);
HostFrameData = NULL;
#endif
logDebug("profile ChangeCB CHAR3.. End");
2024-12-02 16:26:55 +08:00
break;
}
default:
// should not reach here!
break;
}
}
2024-12-15 14:30:06 +08:00
// TODO:应用加入广播数据更新部分状态数据
// 动态更新广播数据
// taskID 请求更改广播任务的 ID
// adTypeTRUE 更改广播数据FALSE 更改扫描回复数据
// datalen数据长度
// *pAdvertData数据指针
void Peripheral_UpdateAdvertData(uint8_t adType, uint8_t dataLen, uint8_t *pAdvertData)
{
GAP_UpdateAdvertisingData(Peripheral_TaskID, adType, dataLen, pAdvertData);
}