BLE_DCF_TYQ_CH592F/APP/peripheral.c

1010 lines
34 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
2025-05-28 19:29:52 +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"
2025-06-04 12:54:03 +08:00
// #include "bsp_i2c.h"
#include "bsp_gxhtc3c.h"
2024-12-14 18:40:24 +08:00
#include "bsp_adc.h"
2024-12-17 14:51:12 +08:00
#include "bsp_beep_led_emv.h"
#include "SLEEP.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-16 21:26:43 +08:00
volatile uint8_t mtu_flag = 0;
2024-12-16 15:36:45 +08:00
2024-12-16 21:26:43 +08:00
static volatile bool periodic_upload_block_flag = false;
2024-12-02 16:26:55 +08:00
2024-12-16 21:26:43 +08:00
void BSP_NeeedReplyCMdFirst(void)
{
periodic_upload_block_flag = true;
}
void BSP_NoNeeedReplyCMd(void)
{
periodic_upload_block_flag = false;
}
2024-12-02 16:26:55 +08:00
// How often to perform periodic event
// TODO:这里长点功耗低
2025-06-03 15:05:04 +08:00
#define SBP_PERIODIC_EVT_PERIOD (1600 * 60 * 3) // (160 = 100ms)
2024-12-02 16:26:55 +08:00
// How often to perform read rssi event
2024-12-15 19:04:05 +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-16 10:04:41 +08:00
#define SBP_PARAM_UPDATE_DELAY (1600 * 1)
2024-12-02 16:26:55 +08:00
// PHY update delay
2024-12-16 15:36:45 +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-16 21:26:43 +08:00
#define DEFAULT_ADVERTISING_INTERVAL (160 * 8)
2024-12-02 16:26:55 +08:00
// Limited discoverable mode advertises for 30.72s, and then stops
// General discoverable mode advertises indefinitely
2024-12-15 19:04:05 +08:00
#define DEFAULT_DISCOVERABLE_MODE GAP_ADTYPE_FLAGS_GENERAL
2024-12-02 16:26:55 +08:00
// Minimum connection interval (units of 1.25ms, 6=7.5ms)
2024-12-16 21:26:43 +08:00
#define DEFAULT_DESIRED_MIN_CONN_INTERVAL (80 * 4) // (80 = 100ms)
2024-12-02 16:26:55 +08:00
// Maximum connection interval (units of 1.25ms, 100=125ms)
#define DEFAULT_DESIRED_MAX_CONN_INTERVAL (80 * 6)
2024-12-02 16:26:55 +08:00
// Slave latency to use parameter update
2024-12-16 21:26:43 +08:00
#define DEFAULT_DESIRED_SLAVE_LATENCY 0
2024-12-02 16:26:55 +08:00
// Supervision timeout value (units of 10ms, 100=1s)
#define DEFAULT_DESIRED_CONN_TIMEOUT (100 * 3)
2024-12-02 16:26:55 +08:00
// Company Identifier: WCH
2024-12-15 19:04:05 +08:00
#define WCH_COMPANY_ID 0x07D7
2024-12-02 16:26:55 +08:00
2024-12-15 19:04:05 +08:00
#define MAC_NAME "TYQ-93:B4:8F:10:53:5C"
// TYQ-93:B4:8F:10:53:5C
#define MAC_NAME_LEN 22
2024-12-02 16:26:55 +08:00
2024-12-16 21:26:43 +08:00
uint8_t Peripheral_TaskID = INVALID_TASK_ID; // Task ID for internal task/event processing
2024-12-02 16:26:55 +08:00
2025-05-28 19:29:52 +08:00
// 蓝牙广播包的最大长度是37个字节其中设备地址占用了6个字节只有31个字节是可用的。
// TODO:响应体名称加上MAC地址
2024-12-02 16:26:55 +08:00
// 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-08 11:29:48 +08:00
'B',
'L',
'E',
'T',
'Y',
'Q',
' ',
'P',
'e',
'r',
'i',
'p',
'h',
'e',
'r',
'a',
'l',
2024-12-08 11:29:48 +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),
2024-12-15 19:04:05 +08:00
HI_UINT16(SIMPLEPROFILE_SERV_UUID)};
2024-12-08 11:29:48 +08:00
2024-12-02 16:26:55 +08:00
// GAP GATT Attributes
static uint8_t attDeviceName[GAP_DEVICE_NAME_LEN] = "BLE_TYQ";
2024-12-02 16:26:55 +08:00
// 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);
static void performPeriodicTask(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)
2024-12-15 19:04:05 +08:00
peripheralParamUpdateCB};
2024-12-02 16:26:55 +08:00
// 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)
2024-12-15 19:04:05 +08:00
NULL, // Pairing / Bonding state Callback (not used by application)
2024-12-02 16:26:55 +08:00
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
{
2025-05-28 19:29:52 +08:00
// 开启广播使能
2024-12-15 19:04:05 +08:00
uint8_t initial_advertising_enable = TRUE;
2025-05-28 19:29:52 +08:00
// 最小连接间隔
2024-12-02 16:26:55 +08:00
uint16_t desired_min_interval = DEFAULT_DESIRED_MIN_CONN_INTERVAL;
2025-05-28 19:29:52 +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
2025-05-28 19:29:52 +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"
2024-12-15 19:04:05 +08:00
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;
2024-12-02 16:26:55 +08:00
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] = {0};
uint8_t charValue2[SIMPLEPROFILE_CHAR2_LEN] = {0};
uint8_t charValue3[SIMPLEPROFILE_CHAR3_LEN] = {0};
uint8_t charValue4[SIMPLEPROFILE_CHAR4_LEN] = {0};
uint8_t charValue5[SIMPLEPROFILE_CHAR5_LEN] = {0, 0, 0, 0, 0};
2024-12-02 16:26:55 +08:00
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);
2024-12-16 15:36:45 +08:00
// https://www.cnblogs.com/ZYL-FS/p/18061479
GATT_InitClient();
2024-12-02 16:26:55 +08:00
}
/*********************************************************************
* @fn peripheralInitConnItem
*
* @brief Init Connection Item
*
* @param peripheralConnList -
*
* @return NULL
*/
static void peripheralInitConnItem(peripheralConnItem_t *peripheralConnList)
{
2024-12-15 19:04:05 +08:00
peripheralConnList->connHandle = GAP_CONNHANDLE_INIT;
peripheralConnList->connInterval = 0;
2024-12-02 16:26:55 +08:00
peripheralConnList->connSlaveLatency = 0;
2024-12-15 19:04:05 +08:00
peripheralConnList->connTimeout = 0;
2024-12-02 16:26:55 +08:00
}
/*********************************************************************
* @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
2024-12-15 19:04:05 +08:00
if (events & SYS_EVENT_MSG)
2024-12-02 16:26:55 +08:00
{
uint8_t *pMsg;
2024-12-15 19:04:05 +08:00
if ((pMsg = tmos_msg_receive(Peripheral_TaskID)) != NULL)
2024-12-02 16:26:55 +08:00
{
Peripheral_ProcessTMOSMsg((tmos_event_hdr_t *)pMsg);
// Release the TMOS message
tmos_msg_deallocate(pMsg);
}
// return unprocessed events
return (events ^ SYS_EVENT_MSG);
}
2024-12-15 19:04:05 +08:00
if (events & SBP_START_DEVICE_EVT)
2024-12-02 16:26:55 +08:00
{
// Start the Device
GAPRole_PeripheralStartDevice(Peripheral_TaskID, &Peripheral_BondMgrCBs, &Peripheral_PeripheralCBs);
2024-12-15 19:04:05 +08:00
2024-12-02 16:26:55 +08:00
return (events ^ SBP_START_DEVICE_EVT);
}
2024-12-16 21:26:43 +08:00
if (events & SBP_REPLY_CMD_EVT)
{
logDebug("SBP_REPLY_CMD_EVT");
2024-12-02 16:26:55 +08:00
2024-12-16 21:26:43 +08:00
peripheralChar4Notify((uint8_t *)&RelyData.buf[0], RelyData.len);
BSP_NoNeeedReplyCMd();
2025-06-04 12:54:03 +08:00
tmos_set_event(led_task_id, LED_SHOW_START_EVT);
2024-12-16 21:26:43 +08:00
return (events ^ SBP_REPLY_CMD_EVT);
}
2024-12-15 19:04:05 +08:00
if (events & SBP_PERIODIC_EVT)
2024-12-02 16:26:55 +08:00
{
2025-05-28 19:29:52 +08:00
// 防止主机下发指令,从机回复响应的时候,先传的是状态数据
2024-12-16 21:26:43 +08:00
if (periodic_upload_block_flag == false && mtu_flag == 1)
2024-12-02 16:26:55 +08:00
{
2024-12-16 21:26:43 +08:00
// Perform periodic application task
performPeriodicTask();
// Restart timer
2024-12-02 16:26:55 +08:00
tmos_start_task(Peripheral_TaskID, SBP_PERIODIC_EVT, SBP_PERIODIC_EVT_PERIOD);
}
2024-12-16 21:26:43 +08:00
else
{
2025-05-28 19:29:52 +08:00
// 需要等先回复了下发的指令1s 之后再尝试回复状态数据
2025-04-24 13:36:09 +08:00
tmos_start_task(Peripheral_TaskID, SBP_PERIODIC_EVT, MS1_TO_SYSTEM_TIME(1000));
2024-12-16 21:26:43 +08:00
}
2024-12-02 16:26:55 +08:00
return (events ^ SBP_PERIODIC_EVT);
}
2024-12-15 19:04:05 +08:00
if (events & SBP_PARAM_UPDATE_EVT)
2024-12-02 16:26:55 +08:00
{
// 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);
}
2024-12-15 19:04:05 +08:00
if (events & SBP_PHY_UPDATE_EVT)
2024-12-02 16:26:55 +08:00
{
// start phy update
2024-12-13 13:22:31 +08:00
logDebug("PHY Update %x...", GAPRole_UpdatePHY(peripheralConnList.connHandle, 0,
2024-12-15 19:04:05 +08:00
GAP_PHY_BIT_LE_2M, GAP_PHY_BIT_LE_2M, 0));
2024-12-02 16:26:55 +08:00
return (events ^ SBP_PHY_UPDATE_EVT);
}
2024-12-15 19:04:05 +08:00
if (events & SBP_READ_RSSI_EVT)
2024-12-02 16:26:55 +08:00
{
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)
{
2024-12-15 19:04:05 +08:00
switch (pEvent->gap.opcode)
2024-12-02 16:26:55 +08:00
{
case GAP_SCAN_REQUEST_EVENT:
{
logDebug("Receive scan req from %x %x %x %x %x %x ..", pEvent->scanReqEvt.scannerAddr[0],
2024-12-15 19:04:05 +08:00
pEvent->scanReqEvt.scannerAddr[1], pEvent->scanReqEvt.scannerAddr[2], pEvent->scanReqEvt.scannerAddr[3],
pEvent->scanReqEvt.scannerAddr[4], pEvent->scanReqEvt.scannerAddr[5]);
2024-12-02 16:26:55 +08:00
break;
}
case GAP_PHY_UPDATE_EVENT:
{
logDebug("Phy update Rx:%x Tx:%x ..", 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)
{
2024-12-15 19:04:05 +08:00
switch (pMsg->event)
2024-12-02 16:26:55 +08:00
{
case GAP_MSG_EVENT:
{
Peripheral_ProcessGAPMsg((gapRoleEvent_t *)pMsg);
break;
}
case GATT_MSG_EVENT:
{
gattMsgEvent_t *pMsgEvent;
pMsgEvent = (gattMsgEvent_t *)pMsg;
2024-12-15 19:04:05 +08:00
if (pMsgEvent->method == ATT_MTU_UPDATED_EVENT)
2024-12-02 16:26:55 +08:00
{
peripheralMTU = pMsgEvent->msg.exchangeMTUReq.clientRxMTU;
2024-12-16 21:26:43 +08:00
mtu_flag = 1;
2024-12-15 19:04:05 +08:00
logDebug("****mtu exchange: %d****", pMsgEvent->msg.exchangeMTUReq.clientRxMTU);
2025-05-28 19:29:52 +08:00
// TODO连上之后先给个状态回应
2025-04-24 13:36:09 +08:00
// tmos_set_event(vavle_task_id, VAVLE_UPDATE_EVT);
performPeriodicTask();
2025-05-28 19:29:52 +08:00
// gValveData.bat = BSP_ReadVbat();
tmos_start_task(Peripheral_TaskID, SBP_PERIODIC_EVT, MS1_TO_SYSTEM_TIME(5000));
2025-05-28 19:29:52 +08:00
2025-04-24 13:36:09 +08:00
tmos_set_event(led_task_id, CONNECT_BEEP_START_EVT);
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
2024-12-15 19:04:05 +08:00
if (peripheralConnList.connHandle != GAP_CONNHANDLE_INIT)
2024-12-02 16:26:55 +08:00
{
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
{
2024-12-15 19:04:05 +08:00
peripheralConnList.connHandle = event->connectionHandle;
peripheralConnList.connInterval = event->connInterval;
2024-12-02 16:26:55 +08:00
peripheralConnList.connSlaveLatency = event->connLatency;
2024-12-15 19:04:05 +08:00
peripheralConnList.connTimeout = event->connTimeout;
2024-12-16 15:36:45 +08:00
peripheralMTU = ATT_MTU_SIZE;
// peripheralMTU = BLE_BUFF_MAX_LEN - 4;
2024-12-02 16:26:55 +08:00
// 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-16 15:36:45 +08:00
// https://www.cnblogs.com/ZYL-FS/p/17759138.html
2025-05-28 19:29:52 +08:00
// 使能通知
2024-12-16 15:36:45 +08:00
enable_notify(peripheralConnList.connHandle, ENABLE);
2024-12-15 19:04:05 +08:00
logDebug("Conn %x - Int %x= %.1fms", event->connectionHandle, event->connInterval, event->connInterval * 1.25);
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;
2024-12-15 19:04:05 +08:00
if (event->connectionHandle == peripheralConnList.connHandle)
2024-12-02 16:26:55 +08:00
{
2024-12-15 19:04:05 +08:00
peripheralConnList.connHandle = GAP_CONNHANDLE_INIT;
peripheralConnList.connInterval = 0;
2024-12-02 16:26:55 +08:00
peripheralConnList.connSlaveLatency = 0;
2024-12-15 19:04:05 +08:00
peripheralConnList.connTimeout = 0;
2024-12-02 16:26:55 +08:00
tmos_stop_task(Peripheral_TaskID, SBP_PERIODIC_EVT);
tmos_stop_task(Peripheral_TaskID, SBP_READ_RSSI_EVT);
// Restart advertising
{
2025-05-28 19:29:52 +08:00
// 三个广播通道全部打开
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-16 15:36:45 +08:00
mtu_flag = 0;
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-16 21:26:43 +08:00
gValveData.rssi = rssi;
logDebug("RSSI %d dB Conn %x ", gValveData.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)
{
2024-12-15 19:04:05 +08:00
if (connHandle == peripheralConnList.connHandle)
2024-12-02 16:26:55 +08:00
{
2024-12-15 19:04:05 +08:00
peripheralConnList.connInterval = connInterval;
2024-12-02 16:26:55 +08:00
peripheralConnList.connSlaveLatency = connSlaveLatency;
2024-12-15 19:04:05 +08:00
peripheralConnList.connTimeout = connTimeout;
2024-12-02 16:26:55 +08:00
2024-12-16 21:26:43 +08:00
logDebug("ParamUpdateCB (Handle)%x - (connInt 0x%x=%.1fms) - (connSlaveLatency) %x - (connTimeout 0x%x=%dms) ", connHandle, connInterval, connInterval * 1.25, connSlaveLatency, connTimeout * 10, connTimeout * 10);
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)
{
2024-12-15 19:04:05 +08:00
switch (newState & GAPROLE_STATE_ADV_MASK)
2024-12-02 16:26:55 +08:00
{
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:
2024-12-15 19:04:05 +08:00
if (pEvent->gap.opcode == GAP_LINK_TERMINATED_EVENT)
2024-12-02 16:26:55 +08:00
{
Peripheral_LinkTerminated(pEvent);
logDebug("Disconnected.. Reason:%x", pEvent->linkTerminate.reason);
2024-12-15 14:30:06 +08:00
logDebug("Advertising..");
2024-12-02 16:26:55 +08:00
}
2024-12-15 19:04:05 +08:00
else if (pEvent->gap.opcode == GAP_MAKE_DISCOVERABLE_DONE_EVENT)
2024-12-02 16:26:55 +08:00
{
2024-12-15 14:30:06 +08:00
logDebug("Advertising..");
2024-12-02 16:26:55 +08:00
}
break;
case GAPROLE_CONNECTED:
2024-12-15 19:04:05 +08:00
if (pEvent->gap.opcode == GAP_LINK_ESTABLISHED_EVENT)
2024-12-02 16:26:55 +08:00
{
Peripheral_LinkEstablished(pEvent);
2024-12-15 14:30:06 +08:00
logDebug("Connected..");
2024-12-16 15:36:45 +08:00
2025-05-28 19:29:52 +08:00
// 在蓝牙建立连接之后,调用 GATT ExchangeMTU 来修改 MTU 的值
2024-12-16 15:36:45 +08:00
// Update MTU
2024-12-16 21:26:43 +08:00
attExchangeMTUReq_t req = {
.clientRxMTU = BLE_BUFF_MAX_LEN - 4,
};
2024-12-16 15:36:45 +08:00
GATT_ExchangeMTU(peripheralConnList.connHandle, &req, Peripheral_TaskID);
// Peripheral_SetMacName();
2024-12-02 16:26:55 +08:00
}
break;
case GAPROLE_CONNECTED_ADV:
2024-12-15 19:04:05 +08:00
if (pEvent->gap.opcode == GAP_MAKE_DISCOVERABLE_DONE_EVENT)
2024-12-02 16:26:55 +08:00
{
2024-12-15 14:30:06 +08:00
logDebug("Connected Advertising..");
2024-12-02 16:26:55 +08:00
}
break;
case GAPROLE_WAITING:
2024-12-15 19:04:05 +08:00
if (pEvent->gap.opcode == GAP_END_DISCOVERABLE_DONE_EVENT)
2024-12-02 16:26:55 +08:00
{
2024-12-15 14:30:06 +08:00
logDebug("Waiting for advertising..");
2024-12-02 16:26:55 +08:00
}
2024-12-15 19:04:05 +08:00
else if (pEvent->gap.opcode == GAP_LINK_TERMINATED_EVENT)
2024-12-02 16:26:55 +08:00
{
Peripheral_LinkTerminated(pEvent);
logDebug("Disconnected.. Reason:%x", pEvent->linkTerminate.reason);
2024-12-02 16:26:55 +08:00
}
2024-12-15 19:04:05 +08:00
else if (pEvent->gap.opcode == GAP_LINK_ESTABLISHED_EVENT)
2024-12-02 16:26:55 +08:00
{
2024-12-15 19:04:05 +08:00
if (pEvent->gap.hdr.status != SUCCESS)
2024-12-02 16:26:55 +08:00
{
2024-12-15 14:30:06 +08:00
logDebug("Waiting for advertising..");
2024-12-02 16:26:55 +08:00
}
else
{
logError("Err..");
2024-12-02 16:26:55 +08:00
}
}
else
{
logError("Err..%x", pEvent->gap.opcode);
2024-12-02 16:26:55 +08:00
}
break;
case GAPROLE_ERROR:
logError("Err..");
2024-12-02 16:26:55 +08:00
break;
default:
break;
}
}
/*********************************************************************
* @fn performPeriodicTask
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
*/
static void performPeriodicTask(void)
2024-12-02 16:26:55 +08:00
{
2025-06-03 08:45:46 +08:00
// if (boost_en_flag == 0 && GPIOA_ReadITFlagBit(BOOST_APIN) == 0)
if (boost_en_flag == 0)
2024-12-16 21:26:43 +08:00
{
gValveData.bat = BSP_ReadVbat();
// TODO温湿度传感器读错的话就不发了
float _humi, _temp;
if (BSP_ReadTempHumi(&_humi, &_temp) == 0)
2025-05-28 19:29:52 +08:00
{
gValveData.temp = (int8_t)_temp;
gValveData.humi = (uint8_t)_humi;
if (gValveData.temp >= HIGN_TEMP_CLOSE_C)
{
logDebug("高温关阀");
tmos_set_event(vavle_task_id, VAVLE_CLOSE_START_EVT);
2025-06-04 12:54:03 +08:00
// 给个回应
tmos_start_task(Peripheral_TaskID, SBP_PERIODIC_EVT, MS1_TO_SYSTEM_TIME(6000));
}
2025-05-28 19:29:52 +08:00
}
else
{
2025-06-04 12:54:03 +08:00
gValveData.temp = -100;
gValveData.humi = 100;
logError("Read TempHumi Err");
// return;
}
#if 1
logDebug("switch_status:%d Temp:%d Bat:%d Humi:%d%% RSSI: %d"
, gValveData.switch_status, gValveData.temp, gValveData.bat, gValveData.humi, gValveData.rssi);
2024-12-14 18:40:24 +08:00
#endif
TsRawFrameData RawData;
2024-12-14 18:40:24 +08:00
BSP_VALVE_Generate_UploadData(&RawData);
2024-12-14 18:40:24 +08:00
peripheralChar4Notify(&RawData.buf[0], RawData.len);
tmos_set_event(led_task_id, LED_SHOW_START_EVT);
}
2025-06-03 08:45:46 +08:00
// else if(GPIOA_ReadITFlagBit(BOOST_APIN) == 1)
else
{
tmos_start_task(Peripheral_TaskID, SBP_PERIODIC_EVT, MS1_TO_SYSTEM_TIME(1000));
}
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)
{
2025-02-22 17:22:49 +08:00
#if 1
2024-12-02 16:26:55 +08:00
attHandleValueNoti_t noti;
2024-12-15 19:04:05 +08:00
if (len > (peripheralMTU - 3))
2024-12-02 16:26:55 +08:00
{
2024-12-13 13:22:31 +08:00
logDebug("Too large noti");
2024-12-02 16:26:55 +08:00
return;
}
2024-12-15 19:04:05 +08:00
noti.len = len;
2024-12-02 16:26:55 +08:00
noti.pValue = GATT_bm_alloc(peripheralConnList.connHandle, ATT_HANDLE_VALUE_NOTI, noti.len, NULL, 0);
2024-12-15 19:04:05 +08:00
if (noti.pValue)
2024-12-02 16:26:55 +08:00
{
tmos_memcpy(noti.pValue, pValue, noti.len);
2024-12-15 19:04:05 +08:00
if (simpleProfile_Notify(peripheralConnList.connHandle, &noti) != SUCCESS)
2024-12-02 16:26:55 +08:00
{
2024-12-16 10:04:41 +08:00
logError("Noti Err");
2024-12-02 16:26:55 +08:00
GATT_bm_free((gattMsg_t *)&noti, ATT_HANDLE_VALUE_NOTI);
}
2024-12-16 15:36:45 +08:00
else
{
logDebug("Noti Success");
}
2024-12-02 16:26:55 +08:00
}
2025-02-22 17:22:49 +08:00
#endif
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-16 21:26:43 +08:00
// TsRawFrameData RawData;
BSP_NeeedReplyCMdFirst();
2024-12-15 19:04:05 +08:00
switch (paramID)
2024-12-02 16:26:55 +08:00
{
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-16 21:26:43 +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-16 21:26:43 +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-16 21:26:43 +08:00
// uint8_t newValue[SIMPLEPROFILE_CHAR3_LEN];
// tmos_memset(newValue, 0, sizeof(newValue));
// tmos_memcpy(newValue, pValue, len);
2024-12-13 13:22:31 +08:00
logDebug("CHAR3 Start");
2024-12-16 21:26:43 +08:00
// logHexDumpAll(newValue, len);
2025-05-28 19:29:52 +08:00
// TODO:发送rev数据
2024-12-16 21:26:43 +08:00
uint8_t *p_rev_msg;
// TsValveMsg *ValveMsg;
// ValveMsg = tmos_msg_allocate(len);
// ValveMsg.data = tmos_msg_allocate(len);
p_rev_msg = tmos_msg_allocate(len + 1);
if ( p_rev_msg )
{
p_rev_msg[0] = len;
tmos_memcpy(&p_rev_msg[1], pValue, len);
int ret = tmos_msg_send(vavle_task_id, p_rev_msg);
if (ret == SUCCESS)
{
logDebug("p_rev_msg send ret = %d", ret);
}
else
{
logError("p_rev_msg send ret = %d", ret);
}
}
else
{
2025-05-28 19:29:52 +08:00
logError("内存不足");
2024-12-16 21:26:43 +08:00
}
#if 0
2024-12-12 19:38:57 +08:00
TsFrameData *HostFrameData = BSP_VAVLE_GetFrameData(newValue, len);
if (HostFrameData != NULL)
{
2025-05-28 19:29:52 +08:00
// logHexDumpAll(&HostFrameData->data[0], HostFrameData->len); // 数据段
2024-12-13 13:22:31 +08:00
// BSP_UART1_TxLoop();
2024-12-12 19:38:57 +08:00
// HR_ProcessData(HostFrameData);
switch (HostFrameData->cmd)
{
2024-12-15 19:04:05 +08:00
case kCmdCfg:
// uint8_t data_buf[64] = {0};
// tmos_memset(data_buf, 0, sizeof(data_buf));
2025-05-28 19:29:52 +08:00
// 处理数据帧
2024-12-15 19:04:05 +08:00
logDebug("kCmdCfg");
break;
case kCmdCloseVavle:
logDebug("kCmdCloseVavle");
2024-12-16 21:26:43 +08:00
2025-05-28 19:29:52 +08:00
// TODO:注意这里
2024-12-16 21:26:43 +08:00
BSP_NeeedReplyCMdFirst();
// EMV_CHARGE
EMV_CHARGE_EN;
logDebug("EMV_CHARGE_EN");
2025-05-28 19:29:52 +08:00
// 开始一个定时event,1s后产生,当前语句只会产生一次event
// 可以在event产生后去开启event,可以是别的task的,也可以是当前task的event
2024-12-16 21:26:43 +08:00
tmos_start_task(vavle_task_id, VAVLE_CLOSE_ACTION_EVT, MS1_TO_SYSTEM_TIME(CHARGE_TIME_MS));
// BSP_VALVE_Generate_ValveResponse(&RawData, kCmdCloseVavle, 1);
2025-05-28 19:29:52 +08:00
// // TODO: 关阀动作
2024-12-16 21:26:43 +08:00
// peripheralChar4Notify((uint8_t *)&RawData.buf[0], RawData.len);
2024-12-15 19:04:05 +08:00
break;
2024-12-16 21:26:43 +08:00
2024-12-15 19:04:05 +08:00
case kCmdOpenVavle:
logDebug("kCmdOpenVavle");
BSP_VALVE_Generate_ValveResponse(&RawData, kCmdOpenVavle, 1);
peripheralChar4Notify((uint8_t *)&RawData.buf[0], RawData.len);
2024-12-16 21:26:43 +08:00
// BSP_UART1_TxLoop();
2024-12-15 19:04:05 +08:00
break;
default:
2025-05-28 19:29:52 +08:00
logError("无效的命令");
2024-12-15 19:04:05 +08:00
// logHexDumpAll(data, len);
break;
2024-12-12 19:38:57 +08:00
}
}
2024-12-13 13:22:31 +08:00
else
{
2025-05-28 19:29:52 +08:00
logError("数据帧解析失败");
2024-12-13 13:22:31 +08:00
}
2024-12-15 19:04:05 +08:00
tmos_msg_deallocate((uint8_t *)HostFrameData);
2024-12-12 19:38:57 +08:00
HostFrameData = NULL;
2024-12-15 19:04:05 +08:00
#endif
2024-12-12 19:38:57 +08:00
logDebug("profile ChangeCB CHAR3.. End");
2024-12-02 16:26:55 +08:00
break;
}
default:
// should not reach here!
break;
}
}
2024-12-16 10:04:41 +08:00
#if 0
2025-05-28 19:29:52 +08:00
// TODO:应用加入广播数据更新部分状态数据
// 动态更新广播数据
// taskID 请求更改广播任务的 ID
// adTypeTRUE 更改广播数据FALSE 更改扫描回复数据
// datalen数据长度
// *pAdvertData数据指针
2024-12-15 14:30:06 +08:00
void Peripheral_UpdateAdvertData(uint8_t adType, uint8_t dataLen, uint8_t *pAdvertData)
{
GAP_UpdateAdvertisingData(Peripheral_TaskID, adType, dataLen, pAdvertData);
}
2024-12-15 19:04:05 +08:00
#include "stdio.h"
#include "stdarg.h"
2025-05-28 19:29:52 +08:00
// TODO:先不弄,后面改广播名,应用加入广播数据更新部分状态数据
2024-12-15 17:34:07 +08:00
void Peripheral_SetMacName(void)
{
2024-12-15 19:04:05 +08:00
uint8_t mac_addr[6];
GetMACAddress(mac_addr);
2025-05-28 19:29:52 +08:00
// 手机APP显示是倒序的[5-0],不是[0-5]
2024-12-15 19:04:05 +08:00
logDebug("MacAddr: %02X:%02X:%02X:%02X:%02X:%02X", mac_addr[0], mac_addr[1]
, mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
2024-12-15 17:34:07 +08:00
// GAPRole_SetParameter(GAPROLE_ADVERT_DATA, sizeof(advertData), advertData);
2024-12-15 19:04:05 +08:00
uint8_t scan_rsp_data[128];
uint8_t len = 0;
uint8_t name_len;
// complete name
scan_rsp_data[1] = GAP_ADTYPE_LOCAL_NAME_COMPLETE;
name_len = sprintf(&scan_rsp_data[2], "TYQ-%02X:%02X:%02X:%02X:%02X:%02X", mac_addr[0], mac_addr[1]
, mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
len = name_len + 1;
scan_rsp_data[0] = len;
logDebug("len:%d", len);
// connection interval range
scan_rsp_data[len++] = 0x05;
scan_rsp_data[len++] = LO_UINT16(DEFAULT_DESIRED_MIN_CONN_INTERVAL);
scan_rsp_data[len++] = HI_UINT16(DEFAULT_DESIRED_MIN_CONN_INTERVAL);
scan_rsp_data[len++] = LO_UINT16(DEFAULT_DESIRED_MAX_CONN_INTERVAL);
scan_rsp_data[len++] = HI_UINT16(DEFAULT_DESIRED_MAX_CONN_INTERVAL);
// Tx power level
scan_rsp_data[len++] = 0x02;
scan_rsp_data[len++] = GAP_ADTYPE_POWER_LEVEL;
scan_rsp_data[len] = 0;
logDebug("len:%d", len);
// logDebug("scan_rsp_data:");
logHexDumpAll(scan_rsp_data, len);
2025-05-28 19:29:52 +08:00
// // 更新扫描响应体
2024-12-15 19:04:05 +08:00
GAP_UpdateAdvertisingData(Peripheral_TaskID, FALSE, scan_rsp_data, len);
2024-12-15 17:34:07 +08:00
}
2024-12-16 10:04:41 +08:00
#endif