1517 lines
43 KiB
C
1517 lines
43 KiB
C
/*************************************************************************************************
|
||
**Filename:
|
||
**Version :
|
||
**Author :
|
||
**Date :
|
||
**Description:
|
||
**
|
||
*************************************************************************************************/
|
||
#include "mcu_bsp.h"
|
||
#include "lsm6d.h"
|
||
#include "lis2dh.h"
|
||
#include "ota.h"
|
||
#include "gpadc.h"
|
||
#include "delay.h"
|
||
#include "cjson.h"
|
||
#include <stdarg.h>
|
||
#include <stdlib.h>
|
||
#include <string.h>
|
||
#include "crc16.h"
|
||
#include "common.h"
|
||
#include "wdt.h"
|
||
#include "DebugLog.h"
|
||
#include "softtimer.h"
|
||
#include "app_timer.h"
|
||
#include "SYD_ble_service_service.h"
|
||
|
||
/*---------------------------------------------------------------*/
|
||
//变量定义
|
||
Tx_Buffer_t dtts_tx_buffer; // 存放发送给主机的数据
|
||
static struct gap_ble_addr dev_addr;
|
||
uint8_t work_led_count = 6;
|
||
/* 设置配置数组 */
|
||
static uint8_t Device_Name_Array[Device_Name_Len]= {Device_Name};
|
||
/* this is for change the byte to char*/
|
||
static char hex[] = "0123456789ABCDEF";
|
||
/**< GATT属性列表头,传入到协议栈中进行初始化*/
|
||
static struct gap_att_report_handle *g_report;
|
||
/* connection*/
|
||
uint8_t connect_flag=0;
|
||
uint8_t Adv_State = 0;
|
||
/* 延迟状态 */
|
||
static uint8_t latency_state = 0;
|
||
/* SPP延时计数*/
|
||
static uint16_t spp_delay_cnt=0;
|
||
uint8_t update_latency_mode=0;
|
||
/* 设置启动发送功能,允许将数据notify到服务*/
|
||
uint8_t start_tx = 0;
|
||
uint8_t syd_nosleep_control=0;
|
||
int batteryPercentage =0; /**< 剩余电量百分比*/
|
||
/* adv data array*/
|
||
uint8_t ADV_DATA[] = {
|
||
0x02, /**< length*/
|
||
0x01, /**< AD Type: Flags*/
|
||
0x05, /**< LE Limited Discoverable Mode & BR/EDR Not Supported*/
|
||
0X0B, /**< length*/
|
||
0XFF, /**< AD Type: MANUFACTURER SPECIFIC DATA*/
|
||
0X4C, /**< Company Identifier (0x00)*/
|
||
0X76, /**< Company Identifier (0x00)*/
|
||
0X42, /**< Company Identifier (0x00)*/
|
||
0X75, /**< Company Identifier (0x42)*/
|
||
0X00, /**< for mac*/
|
||
0X00, /**< for mac*/
|
||
0X00, /**< for mac*/
|
||
0X00, /**< for mac*/
|
||
0X00, /**< for mac*/
|
||
0X00, /**< for mac*/
|
||
Device_Name_Len+1, /**< length*/
|
||
0x09, /**< AD Type: Complete local name*/
|
||
Device_Name /**< Device name*/
|
||
};
|
||
/* scan data array*/
|
||
uint8_t SCAN_DATA[]= {
|
||
0X05, /**< length*/
|
||
0X03, /**< AD Type: MANUFACTURER SPECIFIC DATA*/
|
||
0X16, /**< Company Identifier (0x00)*/
|
||
0X18, /**< Company Identifier (0x00)*/
|
||
0XE0,
|
||
0XFF,
|
||
0X04,
|
||
0X16,
|
||
0X04,
|
||
0X2A,
|
||
0X01, /**< 0X01 踏频,0x02 码表,0x03 灯,04电池,05电显*/
|
||
};
|
||
/*---------------------------------------------------------------*/
|
||
//外部变量调用声明
|
||
extern PAS_SENSOR_t PAS;
|
||
|
||
static void ble_init();
|
||
void ble_evt_callback(struct gap_ble_evt *p_evt);
|
||
static void ble_gatt_write(struct gap_att_write_evt evt);
|
||
static void ble_gatt_read(struct gap_att_read_evt evt);
|
||
static void setup_adv_data();
|
||
uint8_t str_cmp(uint8_t *p1,uint8_t *p2,uint8_t len);
|
||
void nvic_priority(void);
|
||
void rtc_event_handler(void);
|
||
void ota_manage(void);
|
||
void BLSetConnectionUpdate(uint8_t target);
|
||
static void timer_event_handler();
|
||
static void timer_1_callback(void);
|
||
uint8_t BLE_SendRPPData(uint8_t *buf, uint8_t len);
|
||
void pack_timer_event();
|
||
static void send_to_master(void);
|
||
void Connection_latency(void);
|
||
void cal_battery_value(uint16_t adc);
|
||
uint8_t BLE_NotifyBatteryLevel();
|
||
uint8_t get_battery_value();
|
||
static void rf_stop(void);
|
||
static void PowerDown(void);
|
||
void gpio_init(void);
|
||
void Charge_State_Judge(void);
|
||
void LED_State_Indicator(void);
|
||
void syd_nosleep(bool en,SYD_NOSLEEP_CONTROL condit);
|
||
void JsProtocol_Report(int16_t MasterValue,int16_t SlaveValue,int16_t FunCodeValue,
|
||
char* Key1,int16_t Value1,char* Key2,int16_t Value2);
|
||
|
||
/*---------------------------------------------------------------*/
|
||
//主函数
|
||
int main()
|
||
{
|
||
__disable_irq();
|
||
|
||
delay_ms(10);
|
||
|
||
/* 蓝牙初始化,系统主时钟初始化64M,32K时钟初始化为LPO */
|
||
ble_init();
|
||
|
||
/*把串口优先级设置到最高*/
|
||
nvic_priority();
|
||
|
||
/* 根据需要重新设置系统主时钟为64M并校准*/
|
||
MCUClockSwitch(SYSTEM_CLOCK_64M_RCOSC);
|
||
RCOSCCalibration();
|
||
|
||
#ifdef USER_32K_CLOCK_RCOSC
|
||
ClockSwitch(SYSTEM_32K_CLOCK_RCOSC);
|
||
GAPBBDelayMS(500); //内部晶振首次校准的时候必须使用等待硬件复位完成
|
||
LPOCalibration(); //这是内部RC32k晶振的校准函数,经过该函数后定时器能够得到一个比较准确的值
|
||
#else
|
||
ClockSwitch(SYSTEM_32K_CLOCK_XOSC);
|
||
#endif
|
||
|
||
#ifdef _SYD_RTT_DEBUG_
|
||
DebugLogInit(); /**< 调试日志*/
|
||
#endif
|
||
|
||
UartEn(false);
|
||
#if ((1) && (defined(_DEBUG_) || defined(_SYD_RTT_DEBUG_)))
|
||
dbg_printf("SYD8811 GPIO test demo %s:%s\r\n", __DATE__ , __TIME__);
|
||
#endif
|
||
|
||
gpio_init();
|
||
|
||
/* software:timr0 blelib:timer3 */
|
||
SYD_Timer_Init(EVT_NUM, syd_sysTimer);
|
||
Timer_Evt_List();
|
||
Timer_Evt_Start(EVT_1S_WORK);
|
||
Timer_Evt_Start(EVT_1S_OTA);
|
||
Timer_Evt_Start(EVT_300MS_PACK);
|
||
Timer_Evt_Start(EVT_20S_BATTERY);
|
||
|
||
/*5 seconds wdt*/
|
||
#ifdef _WDT_
|
||
wdt_enable(128*5);
|
||
#endif
|
||
|
||
BSP_MCU_Config();
|
||
Lsm6dso_Init();
|
||
Timer2_Enable();
|
||
Lis2dh_Init();
|
||
|
||
StartAdv(); //开始广播
|
||
Adv_State = 1;
|
||
|
||
ReadFlashData(FLASH_INTERNAL_DATA_ADDR, sizeof(PAS.transpModes), (unsigned char*)&PAS.transpModes);
|
||
|
||
dbg_printf("transpModes = %d\r\n",PAS.transpModes);
|
||
|
||
__enable_irq();
|
||
|
||
get_battery_value(); //上电或者POWNDOWN唤醒时,计算一次电量
|
||
|
||
while(1)
|
||
{
|
||
ble_sched_execute(); /*协议栈任务轮训*/
|
||
timer_event_handler();
|
||
|
||
Charge_State_Judge();
|
||
|
||
if(start_tx & 0x01)
|
||
{
|
||
send_to_master();
|
||
}
|
||
|
||
if(!(syd_nosleep_control & SYD_NOSLEEP_SW))
|
||
{
|
||
SystemSleep(); //浅度休眠,定时器中断唤醒
|
||
}
|
||
|
||
if(PAS.sleepState == 1)
|
||
{
|
||
PowerDown();
|
||
}
|
||
}
|
||
}
|
||
|
||
/*---------------------------------------------------------------*/
|
||
//充电状态检测
|
||
//高电平:非充电状态/充满
|
||
//低电平:正在充电
|
||
//注意: IO口输入反向
|
||
void Charge_State_Judge(void)
|
||
{
|
||
if((GPIO_Pin_Read(U32BIT(CHARGE_STATE_PIN)) & U32BIT(CHARGE_STATE_PIN))!= 0)
|
||
{
|
||
PAS.chargeState = 1;
|
||
|
||
if(PAS.transpModes == 1)
|
||
{
|
||
PAS.transpModes = 0;
|
||
PAS.exitTransmode = 1;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
PAS.chargeState = 0;
|
||
}
|
||
}
|
||
/*********************************************************************
|
||
* Function : gpio_init
|
||
* Param in : none
|
||
* Param out: none
|
||
* Return : none
|
||
* Describe : 初始化IO参数
|
||
*/
|
||
void gpio_init(void)
|
||
{
|
||
uint8_t i;
|
||
uint32_t io_input=0,io_pull=0,io_output=0,io_outlow=0,io_invert=0;
|
||
|
||
#ifdef USER_32K_CLOCK_RCOSC
|
||
/* 如果使用内部时钟,时钟引脚上拉*/
|
||
PIN_CONFIG->PAD_INPUT_PULL_UP[0] = 0xff; //pull up
|
||
#else
|
||
/* 如果使用外部时钟,时钟引脚下拉*/
|
||
PIN_CONFIG->PAD_INPUT_PULL_UP[0] = 0xfc; //pull up gpio 0 1 32K xosc
|
||
#endif
|
||
/* 配置其他GPIO的引脚,这里需要注意IO和PAD的关系*/
|
||
PIN_CONFIG->PAD_INPUT_PULL_UP[1] = 0xff; //pull up
|
||
PIN_CONFIG->PAD_INPUT_PULL_UP[2] = 0xff; //pull up
|
||
PIN_CONFIG->PAD_INPUT_PULL_UP[3] = 0xc7; //pull up pin29/pin28 SWD pen21/reset
|
||
PIN_CONFIG->PAD_INPUT_PULL_UP[4] = 0xff; //pull up
|
||
|
||
for(i=0;i<32;i++)
|
||
{
|
||
switch(i)
|
||
{
|
||
/* 外部时钟I0配置*/
|
||
#ifndef USER_32K_CLOCK_RCOSC
|
||
case GPIO_0:
|
||
case GPIO_1:
|
||
break;
|
||
#endif
|
||
|
||
case PEN_PIN:
|
||
io_output |=U32BIT(i);
|
||
io_outlow &=~U32BIT(i); //输出高
|
||
break;
|
||
|
||
case LIS2D_INT2:
|
||
io_input |=U32BIT(i);
|
||
io_pull |=U32BIT(i);
|
||
io_invert |=U32BIT(i);
|
||
break;
|
||
|
||
/**< RESET IO*/
|
||
case GPIO_21:
|
||
io_input |=U32BIT(i);
|
||
io_pull |=U32BIT(i);
|
||
break;
|
||
|
||
/**< 默认上拉输入*/
|
||
default:
|
||
io_input |=U32BIT(i);
|
||
io_pull |=U32BIT(i);
|
||
break;
|
||
}
|
||
}
|
||
|
||
/* 设置GPIO21为IO口模式,而不是复位管脚*/
|
||
BBRFWrite(0x7f, 0x00);
|
||
BBRFWrite(0x1a, 0x40);
|
||
|
||
/* 默认输出IO配置*/
|
||
GPIO_Set_Output(io_output);
|
||
PIN_Pullup_Disable(T_QFN_48, io_output);
|
||
/* 默认输出高电平IO配置*/
|
||
GPIO_Pin_Set(io_output & (~io_outlow));
|
||
/* 默认输出低电平IO配置*/
|
||
GPIO_Pin_Clear(io_outlow);
|
||
/* 默认IO设置是上拉输入*/
|
||
GPIO_Set_Input(io_input,io_invert);
|
||
PIN_Pullup_Enable(T_QFN_48,io_pull);
|
||
}
|
||
/*********************************************************************
|
||
* Function : PowerDown
|
||
* Param in : none
|
||
* Param out: none
|
||
* Return : none
|
||
* Describe : PowerDown
|
||
*/
|
||
static void PowerDown(void)
|
||
{
|
||
struct gap_wakeup_config pw_cfg;
|
||
|
||
__disable_irq();
|
||
|
||
#ifdef _WDT_
|
||
wdt_disable();
|
||
#endif
|
||
|
||
LED_ON();
|
||
delay_ms(300);
|
||
LED_OFF();
|
||
|
||
Lsm6dso_Disable();
|
||
|
||
PEN_DISABLE();
|
||
CEN_DISABLE(); // 母线电压采样MOS关闭
|
||
|
||
pw_cfg.wakeup_type = POWERDOWN_WAKEUP;
|
||
pw_cfg.wdt_wakeup_en = (bool)false;
|
||
pw_cfg.rtc_wakeup_en = (bool)false;
|
||
pw_cfg.timer_wakeup_en = (bool)false;
|
||
pw_cfg.gpi_wakeup_en = (bool)true;
|
||
|
||
if(PAS.transpModes == 1)
|
||
{
|
||
pw_cfg.gpi_wakeup_cfg = U32BIT(CHARGE_STATE_PIN); //中断唤醒pin
|
||
|
||
EraseFlashData(FLASH_INTERNAL_DATA_ADDR,1);
|
||
WriteFlashData(FLASH_INTERNAL_DATA_ADDR,sizeof(PAS.transpModes), (unsigned char*)&PAS.transpModes);
|
||
}
|
||
else
|
||
{
|
||
pw_cfg.gpi_wakeup_cfg = U32BIT(LIS2D_INT2); //中断唤醒pin
|
||
|
||
if(PAS.exitTransmode)
|
||
{
|
||
PAS.exitTransmode = 0;
|
||
|
||
EraseFlashData(FLASH_INTERNAL_DATA_ADDR,1);
|
||
WriteFlashData(FLASH_INTERNAL_DATA_ADDR,sizeof(PAS.transpModes), (unsigned char*)&PAS.transpModes);
|
||
}
|
||
}
|
||
WakeupConfig(&pw_cfg);
|
||
|
||
SystemPowerDown();
|
||
|
||
delay_ms(5);
|
||
|
||
__enable_irq();
|
||
}
|
||
/*********************************************************************
|
||
* Function : work_timer_event
|
||
* Param in : none
|
||
* Param out: none
|
||
* Return : none
|
||
* Describe : work_timer_event
|
||
*/
|
||
static void work_timer_event(void)
|
||
{
|
||
/*****************判断是否进入POWERDOWN状态***********************/
|
||
if(connect_flag == 1)
|
||
{
|
||
if(PAS.RPM == 0)
|
||
{
|
||
PAS.sleepCnt++;
|
||
if((PAS.sleepCnt >= WORK_SLEEP_TIME)&&(PAS.sleepFlag==0)&&(ota_state == 0))
|
||
{
|
||
PAS.sleepCnt = 0;
|
||
PAS.sleepFlag = 1;
|
||
DisConnect(); //不要重复断开连接,否则软件定时器会死机
|
||
}
|
||
}
|
||
else
|
||
{
|
||
PAS.sleepCnt=0;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
Timer2_Disable();
|
||
|
||
dtts_tx_buffer.header = dtts_tx_buffer.tail;
|
||
|
||
if((GPIO_Pin_Read(U32BIT(LIS2D_INT2)) & U32BIT(LIS2D_INT2))!= 0)
|
||
{
|
||
PAS.sleepCnt = 0;
|
||
}
|
||
else
|
||
{
|
||
PAS.sleepCnt++;
|
||
}
|
||
|
||
if((PAS.sleepCnt >= WORK_SLEEP_TIME)&&(ota_state == 0))
|
||
{
|
||
PAS.sleepFlag = 1; //准备休眠 关广播
|
||
}
|
||
|
||
if((PAS.sleepFlag == 1)&&(Adv_State==0))
|
||
{
|
||
PAS.sleepState = 1;
|
||
}
|
||
}
|
||
}
|
||
/*********************************************************************
|
||
* Function : battery_timer_event
|
||
* Param in : none
|
||
* Param out: none
|
||
* Return : none
|
||
* Describe : get battery event, it be called every 20s
|
||
*/
|
||
static void battery_timer_event(void)
|
||
{
|
||
static uint8_t count = 0;
|
||
|
||
count++;
|
||
if(count>=3)
|
||
{
|
||
count=0;
|
||
if((PAS.sleepCnt < (WORK_SLEEP_TIME - 10))&&(PAS.sleepFlag != 1)&&(PAS.sleepState != 1))
|
||
{
|
||
get_battery_value();
|
||
}
|
||
}
|
||
}
|
||
/*********************************************************************
|
||
* Function : LED_State_Indicator
|
||
* Param in : none
|
||
* Param out: none
|
||
* Return : none
|
||
* Describe : get LED_State_Indicator value
|
||
*/
|
||
void LED_State_Indicator(void)
|
||
{
|
||
/*****************工作状态指示灯***********************/
|
||
|
||
if(PAS.chargeState == 1)
|
||
{
|
||
LED_ON();
|
||
work_led_count = 0;
|
||
}
|
||
else
|
||
{
|
||
if(work_led_count > 0)
|
||
{
|
||
work_led_count--;
|
||
LED_TURN();
|
||
|
||
if(work_led_count==0)
|
||
{
|
||
LED_OFF();
|
||
}
|
||
}
|
||
else
|
||
{
|
||
LED_OFF();
|
||
}
|
||
}
|
||
}
|
||
|
||
/*********************************************************************
|
||
* Function : get_battery_value
|
||
* Param in : none
|
||
* Param out: none
|
||
* Return : none
|
||
* Describe : get battery value
|
||
*/
|
||
uint8_t get_battery_value()
|
||
{
|
||
GPADC_channel_sel(ADCGP_CH);
|
||
|
||
syd_nosleep((bool)true,SYD_NOSLEEP_ADC);
|
||
|
||
GPADC_start(cal_battery_value);
|
||
|
||
if(connect_flag)
|
||
{
|
||
BLE_NotifyBatteryLevel();
|
||
}
|
||
return 1;
|
||
}
|
||
/*********************************************************************
|
||
* Function : 计算电池的值
|
||
* Param in : none
|
||
* Param out: none
|
||
* Return : none
|
||
* Describe : calculate the battery value
|
||
*/
|
||
void cal_battery_value(uint16_t adc)
|
||
{
|
||
static uint8_t count,batteryPercenttemp[2];
|
||
|
||
#if ((1) && (defined(_DEBUG_) || defined(_SYD_RTT_DEBUG_)))
|
||
dbg_printf("battery adc:%04x ",adc);
|
||
#endif
|
||
if(0xffff != adc)
|
||
{
|
||
float batteryVoltage=0.0;
|
||
batteryVoltage=(float)adc*3.6/1024;
|
||
|
||
// PAS.batt_vol = batteryVoltage*100;
|
||
|
||
#if ((1) && (defined(_DEBUG_) || defined(_SYD_RTT_DEBUG_)))
|
||
dbg_printf("pin_vol:%4.3f ",batteryVoltage);
|
||
#endif
|
||
|
||
/* 转换为电池电压*/
|
||
batteryVoltage = batteryVoltage*4/3+0.04;
|
||
|
||
batteryPercentage = (batteryVoltage*1000-3000)/11.5+0.5;
|
||
if(batteryPercentage < 0)batteryPercentage=0;
|
||
if(batteryPercentage > 100)batteryPercentage=100;
|
||
count++;
|
||
if(count>=2)count=0;
|
||
batteryPercenttemp[count]=batteryPercentage;
|
||
if((batteryPercenttemp[0] == batteryPercenttemp[1])||(PAS.batt_level == 0))
|
||
{
|
||
PAS.batt_level = batteryPercentage;
|
||
}
|
||
#ifdef BATTERY_low_PROTECT
|
||
if(batteryVoltage<3.0)Battery_low=1;
|
||
else Battery_low=0;
|
||
#endif
|
||
|
||
#if ((1) && (defined(_DEBUG_) || defined(_SYD_RTT_DEBUG_)))
|
||
dbg_printf("bat_vol:%4.3f level:%d\r\n",batteryVoltage,batteryPercentage);
|
||
#endif
|
||
}
|
||
else
|
||
{
|
||
#if ((1) && (defined(_DEBUG_) || defined(_SYD_RTT_DEBUG_)))
|
||
dbg_printf("battery adc Err \r\n");
|
||
#endif
|
||
}
|
||
|
||
syd_nosleep((bool)false,SYD_NOSLEEP_ADC);
|
||
}
|
||
/*********************************************************************
|
||
* Function : syd_nosleep
|
||
* Param in : none
|
||
* Param out: none
|
||
* Return : none
|
||
* Describe : don't into sleep when read adc
|
||
*/
|
||
void syd_nosleep(bool en,SYD_NOSLEEP_CONTROL condit)
|
||
{
|
||
if(en)
|
||
{
|
||
syd_nosleep_control |=SYD_NOSLEEP_SW | condit;
|
||
}
|
||
else
|
||
{
|
||
syd_nosleep_control &=~condit;
|
||
if(!(syd_nosleep_control & 0xFFFE)) syd_nosleep_control &=~SYD_NOSLEEP_SW;
|
||
}
|
||
}
|
||
/*********************************************************************
|
||
* Function : BLE_NotifyBatteryLevel
|
||
* Param in : none
|
||
* Param out: none
|
||
* Return : none
|
||
* Describe : notify the battery level
|
||
*/
|
||
uint8_t BLE_NotifyBatteryLevel()
|
||
{
|
||
struct gap_att_report report;
|
||
report.primary =BLE_DTTS;
|
||
report.uuid = BLE_BATTERY_LEVEL_UUID;
|
||
report.hdl = BLE_BATTERY_LEVEL_VALUE_HANDLE;
|
||
report.value = BLE_GATT_NOTIFICATION;
|
||
|
||
return GATTDataSend(BLE_GATT_NOTIFICATION, &report, 1, &PAS.batt_level);
|
||
}
|
||
/*********************************************************************
|
||
* Function : ble_init
|
||
* Param in : none
|
||
* Param out: none
|
||
* Return : none
|
||
* Describe : BLE初始化
|
||
*/
|
||
static void ble_init()
|
||
{
|
||
struct gap_evt_callback evt;
|
||
struct smp_pairing_req sec_params;
|
||
struct gap_wakeup_config pw_cfg;
|
||
|
||
BleInit();
|
||
|
||
SetWinWideMinusCnt(1);
|
||
|
||
GetGATTReportHandle(&g_report);
|
||
|
||
/* security parameters */
|
||
sec_params.io = IO_NO_INPUT_OUTPUT;
|
||
sec_params.oob = OOB_AUTH_NOT_PRESENT;
|
||
sec_params.flags = AUTHREQ_BONDING;
|
||
sec_params.mitm = 0;
|
||
sec_params.max_enc_sz = 16;
|
||
sec_params.init_key = 0;
|
||
sec_params.rsp_key = (SMP_KEY_MASTER_IDEN |SMP_KEY_ADDR_INFO);
|
||
SetSecParams(&sec_params);
|
||
|
||
evt.evt_mask=(GAP_EVT_CONNECTION_SLEEP|GAP_EVT_CONNECTION_INTERVAL);
|
||
evt.p_callback=&ble_evt_callback;
|
||
SetEvtCallback(&evt);
|
||
|
||
/* Bond Manager (MAX:10) */
|
||
SetBondManagerIndex(0x00);
|
||
|
||
setup_adv_data();
|
||
/*
|
||
当POWERDOWN_WAKEUP时,
|
||
PW_CTRL->DSLP_LPO_EN = true,这些中断源才能唤醒并复位运行,
|
||
如果是false就只有pin能唤醒并复位运行
|
||
*/
|
||
pw_cfg.wakeup_type = SLEEP_WAKEUP;
|
||
pw_cfg.wdt_wakeup_en = (bool)false;
|
||
pw_cfg.rtc_wakeup_en = (bool)false;
|
||
pw_cfg.timer_wakeup_en = (bool)true;
|
||
pw_cfg.gpi_wakeup_en = (bool)false;
|
||
pw_cfg.gpi_wakeup_cfg = U32BIT(LIS2D_INT2); //中断唤醒pin
|
||
WakeupConfig(&pw_cfg);
|
||
}
|
||
|
||
/*********************************************************************
|
||
* Function : ble_evt_callback
|
||
* Param in : none
|
||
* Param out: none
|
||
* Return : none
|
||
* Describe : handle the ble event
|
||
*/
|
||
void ble_evt_callback(struct gap_ble_evt *p_evt)
|
||
{
|
||
if(p_evt->evt_code == GAP_EVT_ATT_WRITE)
|
||
{
|
||
ble_gatt_write(p_evt->evt.att_write_evt);
|
||
}
|
||
else if(p_evt->evt_code == GAP_EVT_ATT_READ)
|
||
{
|
||
ble_gatt_read(p_evt->evt.att_read_evt);
|
||
}
|
||
else if(p_evt->evt_code == GAP_EVT_CONNECTED)
|
||
{
|
||
connect_flag = 1;
|
||
PAS.sleepCnt = 0;
|
||
PAS.sleepFlag = 0;
|
||
update_latency_mode = 0;
|
||
Timer_Evt_Start(EVT_2S); //修改连接参数
|
||
Timer2_Enable();
|
||
|
||
#if defined(_DEBUG_) || defined(_SYD_RTT_DEBUG_)
|
||
DBGHEXDUMP("Connected addr:",p_evt->evt.bond_dev_evt.addr,sizeof(p_evt->evt.bond_dev_evt.addr));
|
||
#endif
|
||
|
||
#ifdef _OTA_
|
||
ota_variable_clear(true);
|
||
#endif
|
||
|
||
}
|
||
else if(p_evt->evt_code == GAP_EVT_DISCONNECTED)
|
||
{
|
||
#if defined(_DEBUG_) || defined(_SYD_RTT_DEBUG_)
|
||
DBGPRINTF("Disconnected,reson:0x%02x\r\n", p_evt->evt.disconn_evt.reason);
|
||
#endif
|
||
|
||
start_tx &= ~0x01; //清零
|
||
connect_flag = 0;
|
||
PAS.sleepCnt = 0;
|
||
|
||
#ifdef _OTA_
|
||
if(Timer_Get_State(EVT_1S_OTA) && (ota_state!=3))
|
||
{
|
||
Timer_Evt_Stop(EVT_1S_OTA);
|
||
}
|
||
#endif
|
||
|
||
/* 成功断开连接之后功耗会加大10ua,
|
||
同时启动广播*/
|
||
if((PAS.sleepFlag == 0)||(PAS.chargeState == 1))
|
||
{
|
||
setup_adv_data();
|
||
StartAdv();
|
||
Adv_State = 1;
|
||
#if defined(_DEBUG_) || defined(_SYD_RTT_DEBUG_)
|
||
DBGPRINTF(("restart adv @ disc!\r\n"));
|
||
#endif
|
||
}
|
||
else
|
||
{
|
||
rf_stop();
|
||
Adv_State = 0;
|
||
#if defined(_DEBUG_) || defined(_SYD_RTT_DEBUG_)
|
||
DBGPRINTF(("stop adv @ disc!\r\n"));
|
||
#endif
|
||
}
|
||
|
||
|
||
|
||
}
|
||
else if(p_evt->evt_code == GAP_EVT_ATT_HANDLE_CONFIGURE)
|
||
{
|
||
#if defined(_DEBUG_) || defined(_SYD_RTT_DEBUG_)
|
||
DBGPRINTF(("GAP_EVT_ATT_HANDLE_CONFIGURE= %2x,%2x,%2x\r\n"),
|
||
p_evt->evt.att_handle_config_evt.uuid,
|
||
p_evt->evt.att_handle_config_evt.hdl,
|
||
p_evt->evt.att_handle_config_evt.value);
|
||
#endif
|
||
if(p_evt->evt.att_handle_config_evt.uuid == BLE_DTTS)
|
||
{
|
||
if(p_evt->evt.att_handle_config_evt.value == BLE_GATT_NOTIFICATION)
|
||
{
|
||
switch (p_evt->evt.att_handle_config_evt.hdl)
|
||
{
|
||
case (BLE_RPP_VALUE_HANDLE+1):
|
||
{
|
||
start_tx |= 0x01;
|
||
dtts_tx_buffer.header = dtts_tx_buffer.tail;
|
||
|
||
#if defined(_DEBUG_) || defined(_SYD_RTT_DEBUG_)
|
||
DBGPRINTF(("RPP notify Enabled!\r\n"));
|
||
#endif
|
||
}
|
||
break;
|
||
case (BLE_CTL_VALUE_HANDLE+1):
|
||
{
|
||
start_tx |= 0x02;
|
||
dtts_tx_buffer.header = dtts_tx_buffer.tail;
|
||
|
||
#if defined(_DEBUG_) || defined(_SYD_RTT_DEBUG_)
|
||
DBGPRINTF(("CTL notify Enabled!\r\n"));
|
||
#endif
|
||
}
|
||
break;
|
||
case (BLE_BATTERY_LEVEL_VALUE_HANDLE+1):
|
||
{
|
||
start_tx |= 0x03;
|
||
dtts_tx_buffer.header = dtts_tx_buffer.tail;
|
||
|
||
#if defined(_DEBUG_) || defined(_SYD_RTT_DEBUG_)
|
||
DBGPRINTF(("BAT notify Enabled!\r\n"));
|
||
#endif
|
||
}
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
switch (p_evt->evt.att_handle_config_evt.hdl)
|
||
{
|
||
case (BLE_RPP_VALUE_HANDLE+1):
|
||
{
|
||
start_tx &= ~0x01;
|
||
/* 允许硬件自由控制32Mhz晶振,休眠的时候功耗很低*/
|
||
UartEn(false);
|
||
#if defined(_DEBUG_) || defined(_SYD_RTT_DEBUG_)
|
||
DBGPRINTF(("RPP notify Disabled!\r\n"));
|
||
#endif
|
||
}
|
||
break;
|
||
case (BLE_CTL_VALUE_HANDLE+1):
|
||
{
|
||
start_tx &= ~0x02;
|
||
#if defined(_DEBUG_) || defined(_SYD_RTT_DEBUG_)
|
||
DBGPRINTF(("CTL notify Disabled!\r\n"));
|
||
#endif
|
||
}
|
||
break;
|
||
case (BLE_BATTERY_LEVEL_VALUE_HANDLE+1):
|
||
{
|
||
start_tx &= ~0x03;
|
||
#if defined(_DEBUG_) || defined(_SYD_RTT_DEBUG_)
|
||
DBGPRINTF(("BAT notify Disabled!\r\n"));
|
||
#endif
|
||
}
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
else if(p_evt->evt_code == GAP_EVT_L2CAP_UPDATE_RSP)
|
||
{
|
||
switch(p_evt->evt.l2cap_update_rsp_evt.result)
|
||
{
|
||
case CONN_PARAMS_ACCEPTED:
|
||
#if defined(_DEBUG_) || defined(_SYD_RTT_DEBUG_)
|
||
DBGPRINTF(("update rsp ACCEPTED\r\n"));
|
||
{
|
||
struct gap_link_params link_app;
|
||
GetLinkParameters(&link_app);
|
||
#if defined(_DEBUG_) || defined(_SYD_RTT_DEBUG_)
|
||
dbg_printf("interval:%x latency:%x\r\n",link_app.interval,link_app.latency);
|
||
#endif
|
||
}
|
||
#endif
|
||
break;
|
||
case CONN_PARAMS_REJECTED:
|
||
#if defined(_DEBUG_) || defined(_SYD_RTT_DEBUG_)
|
||
//DBGPRINTF(("update rsp REJECTED\r\n"));
|
||
#endif
|
||
break;
|
||
case CONN_PARAM_SMART_TIMEROUT:
|
||
#if defined(_DEBUG_) || defined(_SYD_RTT_DEBUG_)
|
||
//DBGPRINTF(("update rsp TIMEROUT\r\n"));
|
||
#endif
|
||
break;
|
||
case CONN_PARAM_SMART_SUCCEED:
|
||
#if defined(_DEBUG_) || defined(_SYD_RTT_DEBUG_)
|
||
//DBGPRINTF(("update rsp SUCCEED\r\n"));
|
||
#endif
|
||
break;
|
||
case CONN_PARAM_LATENCY_ENABLE:
|
||
#if defined(_DEBUG_) || defined(_SYD_RTT_DEBUG_)
|
||
// DBGPRINTF(("Enable latency\r\n"));
|
||
#endif
|
||
break;
|
||
case CONN_PARAM_LATENCY_DISABLE:
|
||
#if defined(_DEBUG_) || defined(_SYD_RTT_DEBUG_)
|
||
// DBGPRINTF(("Disable latency\r\n"));
|
||
#endif
|
||
break;
|
||
}
|
||
}
|
||
else if(p_evt->evt_code == GAP_EVT_CONN_UPDATE_COMP)
|
||
{
|
||
struct gap_link_params link;
|
||
GetLinkParameters(&link);
|
||
#if defined(_DEBUG_) || defined(_SYD_RTT_DEBUG_)
|
||
DBGPRINTF("CONN_UPDATE_COMP: %d, %d, %d\r\n", link.interval, link.latency, link.svto);
|
||
#endif
|
||
}
|
||
else if(p_evt->evt_code == GAP_EVT_ADV_END)
|
||
{
|
||
#if defined(_DEBUG_) || defined(_SYD_RTT_DEBUG_)
|
||
DBGPRINTF(("GAP_EVT_ADV_END\r\n"));
|
||
#endif
|
||
|
||
if((PAS.sleepFlag == 0)||(PAS.chargeState == 1))
|
||
{
|
||
StartAdv();
|
||
Adv_State = 1;
|
||
}
|
||
else
|
||
{
|
||
rf_stop();
|
||
Adv_State = 0;
|
||
}
|
||
|
||
#if defined(_DEBUG_) || defined(_SYD_RTT_DEBUG_)
|
||
DBGPRINTF(("restart adv\r\n"));
|
||
#endif
|
||
}
|
||
}
|
||
/*********************************************************************
|
||
* Function :
|
||
* Param in : none
|
||
* Param out: none
|
||
* Return : none
|
||
* Describe :
|
||
*/
|
||
static void rf_stop(void)
|
||
{
|
||
RFSleep();
|
||
}
|
||
/*********************************************************************
|
||
* Function : 发送指令
|
||
* Param in : none
|
||
* Param out: none
|
||
* Return : none
|
||
* Describe :
|
||
*/
|
||
uint8_t BLE_SendCMDData(uint8_t *buf, uint8_t len)
|
||
{
|
||
struct gap_att_report report;
|
||
|
||
report.primary = BLE_DTTS;
|
||
report.uuid = BLE_CTL_UUID;
|
||
report.hdl = BLE_CTL_VALUE_HANDLE;
|
||
report.value = BLE_GATT_NOTIFICATION;
|
||
|
||
return GATTDataSend(BLE_GATT_NOTIFICATION, &report, len, buf);
|
||
}
|
||
/*********************************************************************
|
||
* Function : ble_gatt_write
|
||
* Param in : none
|
||
* Param out: none
|
||
* Return : none
|
||
* Describe : GATT属性写入处理
|
||
*/
|
||
static void ble_gatt_write(struct gap_att_write_evt evt)
|
||
{
|
||
if(evt.uuid == BLE_SPP_UUID)
|
||
{
|
||
}
|
||
else if(evt.uuid ==BLE_CTL_UUID)
|
||
{
|
||
#if defined(_DEBUG_) || defined(_SYD_RTT_DEBUG_)
|
||
DBGHEXDUMP("BLE_CTL_UUID:",evt.data, evt.sz);
|
||
#endif
|
||
if(evt.sz >= 2&& evt.data[0] == '@' && evt.data[evt.sz-1] == '#')
|
||
{
|
||
/* 测试指令 */
|
||
if((evt.sz == 6) && str_cmp(evt.data,
|
||
(uint8_t *)"@TEST#", 6))
|
||
{
|
||
#if defined(_DEBUG_) || defined(_SYD_RTT_DEBUG_)
|
||
dbg_printf("@OK#\r\n");
|
||
#endif
|
||
}
|
||
else if((evt.sz == 5) && str_cmp(evt.data,
|
||
(uint8_t *)"@OFF#", 5))
|
||
{
|
||
uint8_t data[6]="@OK#\r\n";
|
||
BLE_SendCMDData(data,6);
|
||
PAS.transpModes = 1; //运输模式
|
||
PAS.sleepCnt = WORK_SLEEP_TIME; //运输模式,加快进入深度休眠模式
|
||
|
||
}
|
||
else if((evt.sz == 5) && str_cmp(evt.data,
|
||
(uint8_t *)"@CAL#", 5))
|
||
{
|
||
PAS.adjustFlag = 1;
|
||
#if defined(_DEBUG_) || defined(_SYD_RTT_DEBUG_)
|
||
DBGPRINTF("PAS.adjustFlag = %d\r\n",PAS.adjustFlag);
|
||
#endif
|
||
}
|
||
}
|
||
else
|
||
{
|
||
#if defined(_DEBUG_) || defined(_SYD_RTT_DEBUG_)
|
||
dbg_printf("@ERROR cmd#\r\n");
|
||
#endif
|
||
}
|
||
|
||
}
|
||
else if(evt.uuid== BLE_OTA_Read_Write_UUID)
|
||
{
|
||
#ifdef _OTA_
|
||
ota_cmd(evt.data, evt.sz);
|
||
#endif
|
||
}
|
||
}
|
||
/*********************************************************************
|
||
* Function : ble_gatt_read
|
||
* Param in : none
|
||
* Param out: none
|
||
* Return : none
|
||
* Describe : GATT属性读取处理
|
||
*/
|
||
static void ble_gatt_read(struct gap_att_read_evt evt)
|
||
{
|
||
/* 设备名称*/
|
||
if(evt.uuid == BLE_DEVICE_NAME_UUID)
|
||
{
|
||
uint8_t gatt_buf_sz = sizeof(Device_Name_Array);
|
||
|
||
SetGATTReadRsp(gatt_buf_sz, Device_Name_Array);
|
||
}
|
||
/* 制造商名称*/
|
||
else if(evt.uuid == BLE_MANUFACTURER_NAME_STRING_UUID)
|
||
{
|
||
SetGATTReadRsp(Manufacturer_Size, (uint8_t *)Manufacturer_Name);
|
||
}
|
||
/* 产品型号*/
|
||
else if(evt.uuid == BLE_MODEL_NUMBER_STRING_UUID)
|
||
{
|
||
SetGATTReadRsp(Model_Size, (uint8_t *)Model_Number);
|
||
}
|
||
/* 产品串号*/
|
||
else if(evt.uuid == BLE_SERIAL_NUMBER_STRING_UUID)
|
||
{
|
||
SetGATTReadRsp(Serial_Size, (uint8_t *)Serial_Number);
|
||
}
|
||
/* 硬件版本号*/
|
||
else if(evt.uuid == BLE_HARDWARE_REVISION_STRING_UUID)
|
||
{
|
||
SetGATTReadRsp(Hardware_Size, (uint8_t *)Hardware_Vesion);
|
||
}
|
||
/* 软件版本号*/
|
||
else if(evt.uuid == BLE_SOFTWARE_REVISION_STRING_UUID)
|
||
{
|
||
SetGATTReadRsp(Software_Size, (uint8_t *)Software_Vesion);
|
||
}
|
||
/* 电池电量*/
|
||
else if(evt.uuid == BLE_BATTERY_LEVEL_UUID)
|
||
{
|
||
// SetGATTReadRsp(1, (uint8_t *) &AD_Value.PowerScale);
|
||
}
|
||
/* OTA*/
|
||
else if(evt.uuid == BLE_OTA_Read_Write_UUID)
|
||
{
|
||
#ifdef _OTA_
|
||
uint8_t sz=0;
|
||
uint8_t rsp[sizeof(struct hci_evt)]= {0};
|
||
ota_rsp(rsp, &sz);
|
||
SetGATTReadRsp(sz, rsp);
|
||
#endif
|
||
}
|
||
}
|
||
/*********************************************************************
|
||
* Function : setup_adv_data
|
||
* Param in : none
|
||
* Param out: none
|
||
* Return : none
|
||
* Describe : 设置广播数据
|
||
*/
|
||
static void setup_adv_data()
|
||
{
|
||
struct gap_adv_params adv_params;
|
||
|
||
adv_params.type = ADV_IND;
|
||
/**< advertising channel : 37 & 38 & 39*/
|
||
adv_params.channel = 0x07;
|
||
/**< advertising interval : 1000ms (1600 * 0.625ms),这里需要注意的问题
|
||
就是设置的interval要是100的整数倍数,这样时间才会比较准确,默认1600*/
|
||
adv_params.interval = 80;
|
||
adv_params.timeout = ADV_TIMEOUT; /**< timeout : 30s*/
|
||
|
||
/* 设置广播的参数*/
|
||
SetAdvParams(&adv_params);
|
||
|
||
/* 获取蓝牙的地址 */
|
||
GetDevAddr(&dev_addr);
|
||
ADV_DATA[9] = dev_addr.addr[5];
|
||
ADV_DATA[10] = dev_addr.addr[4];
|
||
ADV_DATA[11] = dev_addr.addr[3];
|
||
ADV_DATA[12] = dev_addr.addr[2];
|
||
ADV_DATA[13] = dev_addr.addr[1];
|
||
ADV_DATA[14] = dev_addr.addr[0];
|
||
|
||
/*the mac last 4 char to the adv name*/
|
||
ADV_DATA[25] = hex[(dev_addr.addr[1]>>4)&0X0F];
|
||
ADV_DATA[26] = hex[dev_addr.addr[1]&0X0F];
|
||
ADV_DATA[27] = hex[(dev_addr.addr[0]>>4)&0X0F];
|
||
ADV_DATA[28] = hex[dev_addr.addr[0]&0X0F];
|
||
|
||
Device_Name_Array[8] = ADV_DATA[25];
|
||
Device_Name_Array[9] = ADV_DATA[26];
|
||
Device_Name_Array[10]= ADV_DATA[27];
|
||
Device_Name_Array[11]= ADV_DATA[28];
|
||
|
||
/* set the adv data and scan data*/
|
||
SetAdvData(ADV_DATA, sizeof(ADV_DATA), SCAN_DATA, sizeof(SCAN_DATA));
|
||
|
||
*(uint8_t *)0x40020014 = 0x01; /*< 设置ADV_PITV为1,降低功耗*/
|
||
}
|
||
/*********************************************************************
|
||
* Function : nvic_priority
|
||
* Param in : none
|
||
* Param out: none
|
||
* Return : none
|
||
* Describe : config teh nvic priority
|
||
*/
|
||
void nvic_priority(void)
|
||
{
|
||
NVIC_SetPriority(LLC_IRQn, 2);
|
||
NVIC_SetPriority(RTC_IRQn, 2);
|
||
NVIC_SetPriority(SW_IRQn, 2);
|
||
NVIC_SetPriority(I2C0_IRQn, 2);
|
||
NVIC_SetPriority(I2C1_IRQn, 2);
|
||
NVIC_SetPriority(UART0_IRQn, 2);
|
||
NVIC_SetPriority(UART1_IRQn, 2);
|
||
NVIC_SetPriority(TIMER0_IRQn, 3);
|
||
NVIC_SetPriority(TIMER1_IRQn, 2);
|
||
NVIC_SetPriority(TIMER2_IRQn, 2);
|
||
NVIC_SetPriority(TIMER3_IRQn, 2);
|
||
NVIC_SetPriority(GPIO_IRQn, 2);
|
||
NVIC_SetPriority(HID_IRQn, 2);
|
||
NVIC_SetPriority(SPIM_IRQn, 2);
|
||
NVIC_SetPriority(CAP_IRQn, 0);
|
||
NVIC_SetPriority(GPADC_IRQn, 2);
|
||
NVIC_SetPriority(LLC2_IRQn, 2);
|
||
NVIC_SetPriority(ISO7816_IRQn, 2);
|
||
NVIC_SetPriority(IR_Tx_IRQn, 2);
|
||
NVIC_SetPriority(TOUCH_IRQn, 2);
|
||
NVIC_SetPriority(HPWM_IRQn, 2);
|
||
NVIC_SetPriority(HTIMER_IRQn, 2);
|
||
NVIC_SetPriority(IR_Rx_IRQn, 2);
|
||
}
|
||
/*********************************************************************
|
||
* Function : RTC事件处理
|
||
* Param in : none
|
||
* Param out: none
|
||
* Return : none
|
||
* Describe : rtc时钟定时事件处理
|
||
*/
|
||
void rtc_event_handler(void)
|
||
{
|
||
/* 实时时钟处理*/
|
||
if(RTC_EVT)
|
||
{
|
||
#ifdef RTCEVT_185S
|
||
if(RTC_EVT & RTCEVT_185S)
|
||
{
|
||
#ifdef USER_32K_CLOCK_RCOSC
|
||
LPOCalibration();
|
||
#endif
|
||
|
||
#if defined(_DEBUG_) || defined(_SYD_RTT_DEBUG_)
|
||
DBGPRINTF(("RTCEVT_185S\r\n"));
|
||
#endif
|
||
|
||
RTC_EVT_Clr(RTCEVT_185S);
|
||
}
|
||
#endif
|
||
}
|
||
}
|
||
|
||
/*************************************************************************************************
|
||
* Function Name:
|
||
* Description : 设置连接延迟
|
||
* Arguments :
|
||
* Return Value :
|
||
*************************************************************************************************/
|
||
void Connection_latency(void)
|
||
{
|
||
update_latency_mode++;
|
||
|
||
if(update_latency_mode>=3)
|
||
{
|
||
latency_state=0;
|
||
/* low energy connect setting*/
|
||
BLSetConnectionUpdate(1);
|
||
Timer_Evt_Stop(EVT_2S);
|
||
}
|
||
}
|
||
/*********************************************************************
|
||
* Function : timer_event_handler
|
||
* Param in : none
|
||
* Param out: none
|
||
* Return : none
|
||
* Describe : 定时器事件处理
|
||
*/
|
||
static void timer_event_handler()
|
||
{
|
||
/* 定时器事件处理*/
|
||
if(TIMER_EVT)
|
||
{
|
||
#ifdef EVT_1S_OTA
|
||
if(TIMER_EVT&EVT_1S_OTA)
|
||
{
|
||
ota_manage(); /**< ota 过程管理 操作屏幕等*/
|
||
Timer_Evt_Clr(EVT_1S_OTA);
|
||
}
|
||
#endif
|
||
|
||
#ifdef EVT_2S
|
||
if(TIMER_EVT&EVT_2S)
|
||
{
|
||
Connection_latency(); /**< 连接参数相关设置*/
|
||
Timer_Evt_Clr(EVT_2S);
|
||
}
|
||
#endif
|
||
|
||
#ifdef EVT_1S_WORK
|
||
if(TIMER_EVT&EVT_1S_WORK)
|
||
{
|
||
work_timer_event();
|
||
|
||
Timer_Evt_Clr(EVT_1S_WORK);
|
||
}
|
||
#endif
|
||
|
||
#ifdef EVT_300MS_PACK
|
||
if(TIMER_EVT&EVT_300MS_PACK)
|
||
{
|
||
LED_State_Indicator();
|
||
|
||
#ifdef _WDT_
|
||
wdt_clear();
|
||
#endif
|
||
|
||
Timer_Evt_Clr(EVT_300MS_PACK);
|
||
}
|
||
#endif
|
||
|
||
#ifdef EVT_20S_BATTERY
|
||
if(TIMER_EVT&EVT_20S_BATTERY)
|
||
{
|
||
//计算电池电量
|
||
battery_timer_event();
|
||
Timer_Evt_Clr(EVT_20S_BATTERY);
|
||
}
|
||
#endif
|
||
}
|
||
}
|
||
/*********************************************************************
|
||
* Function : BLSetConnectionUpdate
|
||
* Param in : uint8_t target
|
||
* 0:ota
|
||
* 1:low energy
|
||
* Param out: none
|
||
* Return : none
|
||
* Describe : 更新连接参数
|
||
*/
|
||
void BLSetConnectionUpdate(uint8_t target)
|
||
{
|
||
struct gap_smart_update_params smart_params;
|
||
|
||
switch(target) {
|
||
/* 0:ota */
|
||
case 0:
|
||
/* connection parameters */
|
||
smart_params.updateitv_target=0x0010; /**< target connection interval (value * 1.25ms = 75 ms)*/
|
||
smart_params.updatesvto=0x00c8; /**< supervisory timeout (400 * 10 ms = 4s)*/
|
||
smart_params.updatelatency=0x0000;
|
||
break;
|
||
/* 1:low energy */
|
||
case 1:
|
||
/* connection parameters */
|
||
smart_params.updateitv_target=16; /**< target connection interval (value * 1.25ms = 75 ms)*/
|
||
smart_params.updatesvto=400; /**< supervisory timeout (value * 10 ms = 4s)*/
|
||
smart_params.updatelatency=1;
|
||
break;
|
||
}
|
||
smart_params.updatectrl=SMART_CONTROL_LATENCY | SMART_CONTROL_UPDATE;
|
||
smart_params.updateadj_num=MAX_UPDATE_ADJ_NUM;
|
||
gap_s_smart_update_latency(&smart_params);
|
||
|
||
#if defined(_DEBUG_) || defined(_SYD_RTT_DEBUG_)
|
||
dbg_printf("smart_params interval:%x latency:%x svto:%x\r\n",smart_params.updateitv_target,
|
||
smart_params.updatelatency,smart_params.updatesvto);
|
||
#endif
|
||
}
|
||
/*********************************************************************
|
||
* Function : ota_manage
|
||
* Param in : none
|
||
* Param out: none
|
||
* Return : none
|
||
* Describe : manage the ota operation
|
||
*/
|
||
void ota_manage(void)
|
||
{
|
||
#ifdef _OTA_
|
||
if(ota_state) {
|
||
switch(ota_state) {
|
||
case 1 :
|
||
#if defined(_DEBUG_) || defined(_SYD_RTT_DEBUG_)
|
||
dbg_printf("start FwErase\r\n");
|
||
#endif
|
||
CmdFwErase();
|
||
#if defined(_DEBUG_) || defined(_SYD_RTT_DEBUG_)
|
||
dbg_printf("OTA start\r\n");
|
||
#endif
|
||
ota_state =2;
|
||
ota_writecnt=0;
|
||
break;
|
||
case 2 :
|
||
ota_writecnt++;
|
||
if(ota_writecnt>0x20)
|
||
{
|
||
#if defined(_DEBUG_) || defined(_SYD_RTT_DEBUG_)
|
||
dbg_printf("OTA faile\r\n");
|
||
#endif
|
||
Timer_Evt_Stop(EVT_1S_OTA);
|
||
}
|
||
break;
|
||
case 3 :
|
||
ota_state=0;
|
||
Timer_Evt_Stop(EVT_1S_OTA);
|
||
#if defined(_DEBUG_) || defined(_SYD_RTT_DEBUG_)
|
||
dbg_printf("OTA finish\r\n");
|
||
#endif
|
||
delay_ms(1000);
|
||
#if defined(_DEBUG_) || defined(_SYD_RTT_DEBUG_)
|
||
dbg_printf("Start Reset 1000s\r\n");
|
||
#endif
|
||
SystemReset();
|
||
break;
|
||
default :
|
||
break;
|
||
}
|
||
}
|
||
#endif
|
||
}
|
||
/*************************************************************************************************
|
||
* Function Name:
|
||
* Description :
|
||
* Arguments : 将缓冲区数据发送到主机
|
||
* Return Value :
|
||
*************************************************************************************************/
|
||
static void send_to_master(void)
|
||
{
|
||
uint32_t len, header, tail;
|
||
|
||
header = dtts_tx_buffer.header;
|
||
tail = dtts_tx_buffer.tail;
|
||
|
||
/*有数据,处理数据*/
|
||
if(header != tail)
|
||
{
|
||
if(latency_state==0)
|
||
{
|
||
latency_state = 1;
|
||
spp_delay_cnt = 0;
|
||
timer_1_enable(32768/200, timer_1_callback); //5MS定时中断
|
||
}
|
||
}
|
||
else
|
||
{
|
||
return;
|
||
}
|
||
//caculate len
|
||
if(header >= tail)
|
||
{
|
||
len = header - tail;
|
||
}
|
||
else
|
||
{
|
||
len = header + MAX_RX_LENGTH - tail;
|
||
}
|
||
/* len bigger then 20, send data immediately*/
|
||
if(len>=PDULENTH)
|
||
{
|
||
for(; len>=PDULENTH; len-=PDULENTH)
|
||
{
|
||
uint8_t send_data[PDULENTH], i;
|
||
spp_delay_cnt = 0;
|
||
|
||
//memcpy PDULENTH byte
|
||
for(i=0; i<PDULENTH; i++)
|
||
{
|
||
send_data[i] = dtts_tx_buffer.data[tail++];
|
||
|
||
if(tail >= MAX_RX_LENGTH)
|
||
{
|
||
tail = 0;
|
||
}
|
||
}
|
||
//send
|
||
if(BLE_SendRPPData(send_data, PDULENTH))
|
||
{
|
||
dtts_tx_buffer.tail = tail;
|
||
}
|
||
else
|
||
{
|
||
break;
|
||
}
|
||
}
|
||
|
||
// if(len >= 1)
|
||
// {
|
||
// uint8_t send_data[PDULENTH], i;
|
||
//
|
||
// for(i=0; i< len; i++)
|
||
// {
|
||
// send_data[i] = dtts_tx_buffer.data[tail++];
|
||
|
||
// if(tail >= MAX_RX_LENGTH)
|
||
// {
|
||
// tail = 0;
|
||
// }
|
||
// }
|
||
// //send
|
||
// if(BLE_SendRPPData(send_data, len))
|
||
// {
|
||
// dtts_tx_buffer.tail = tail;
|
||
// }
|
||
// }
|
||
}
|
||
else if(len >= 1)
|
||
{
|
||
if(spp_delay_cnt >= 3)
|
||
{
|
||
uint8_t send_data[PDULENTH],i;
|
||
//memcpy len byte
|
||
for(i=0; i<len; i++)
|
||
{
|
||
send_data[i] = dtts_tx_buffer.data[tail++];
|
||
|
||
if(tail >= MAX_RX_LENGTH)
|
||
{
|
||
tail = 0;
|
||
}
|
||
}
|
||
//send
|
||
if(BLE_SendRPPData(send_data, len))
|
||
{
|
||
dtts_tx_buffer.tail = tail;
|
||
}
|
||
|
||
spp_delay_cnt = 0;
|
||
}
|
||
}
|
||
}
|
||
/*************************************************************************************************
|
||
* Function Name:
|
||
* Description :
|
||
* Arguments : 将串口数据发送到BLE服务
|
||
* Return Value :
|
||
*************************************************************************************************/
|
||
uint8_t BLE_SendRPPData(uint8_t *buf, uint8_t len)
|
||
{
|
||
if(start_tx & 0x01)
|
||
{
|
||
struct gap_att_report report;
|
||
|
||
report.primary = BLE_DTTS;
|
||
report.uuid = BLE_RPP_UUID;
|
||
report.hdl = BLE_RPP_VALUE_HANDLE;
|
||
report.value = BLE_GATT_NOTIFICATION;
|
||
|
||
return GATTDataSend(BLE_GATT_NOTIFICATION, &report, len, buf);
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
/*************************************************************************************************
|
||
* Function Name:
|
||
* Description :
|
||
* Arguments : 定时器1的回调处理
|
||
* Return Value :
|
||
*************************************************************************************************/
|
||
static void timer_1_callback(void)
|
||
{
|
||
spp_delay_cnt++;
|
||
|
||
/* 经过三次回调,spp缓冲区无数据后停止定时器*/
|
||
if((dtts_tx_buffer.header == dtts_tx_buffer.tail) && (spp_delay_cnt > 3))
|
||
{
|
||
latency_state = 0;
|
||
timer_1_disable();
|
||
}
|
||
}
|
||
/*************************************************************************************************
|
||
* Function Name:
|
||
* Description : json 数据上报
|
||
* Arguments :
|
||
* Return Value :
|
||
*************************************************************************************************/
|
||
void JsProtocol_Report(int16_t MasterValue,int16_t SlaveValue,int16_t FunCodeValue,
|
||
char* Key1,int16_t Value1,char* Key2,int16_t Value2)
|
||
{
|
||
int i=0;
|
||
cJSON* JsFrameTx_Report=NULL; //new一个响应的的json主体
|
||
cJSON* JsTx_Data=NULL; //new一个响应的的json主体
|
||
int16_t TxJs_Len; //保存json包长度
|
||
char* Tx_Pack;
|
||
char* pReport_Dfu;
|
||
int16_t pStr_Response_Index=0;
|
||
int16_t CRC16_Data;
|
||
|
||
/* 响应json包*/
|
||
JsFrameTx_Report=cJSON_CreateObject(); //!!!申请内存,创建帧json
|
||
cJSON_AddNumberToObject(JsFrameTx_Report,"M",MasterValue); //pack:主机
|
||
cJSON_AddNumberToObject(JsFrameTx_Report,"S",SlaveValue); //pack:从机
|
||
cJSON_AddNumberToObject(JsFrameTx_Report,"F",FunCodeValue); //pack:功能码
|
||
JsTx_Data=cJSON_CreateObject(); //!!!申请内存,创建数据json
|
||
cJSON_AddItemToObject(JsFrameTx_Report, "D",JsTx_Data); //pack:数据数组
|
||
|
||
cJSON_AddNumberToObject(JsTx_Data,Key1,Value1); //pack:数据
|
||
cJSON_AddNumberToObject(JsTx_Data,Key2,Value2); //pack:数据
|
||
|
||
/* change json to char */
|
||
Tx_Pack=cJSON_Print(JsFrameTx_Report); //!!!申请内存(json转char)
|
||
cJSON_Minify(Tx_Pack); //瘦身
|
||
TxJs_Len=stringLength(Tx_Pack); //计算json长度
|
||
|
||
/* DFU pack */
|
||
pReport_Dfu=(char*)malloc(TxJs_Len*sizeof(char)+5); //!!!申请内存pStr1
|
||
|
||
pReport_Dfu[pStr_Response_Index++]=0x7f;
|
||
pReport_Dfu[pStr_Response_Index++]=LSB_16(TxJs_Len); //pack:json长度低
|
||
pReport_Dfu[pStr_Response_Index++]=MSB_16(TxJs_Len); //pack:json长度高
|
||
memcpy(&pReport_Dfu[pStr_Response_Index],Tx_Pack,TxJs_Len);
|
||
pStr_Response_Index+=TxJs_Len;
|
||
CRC16_Data = crc16_ccitt( (uint8_t*)pReport_Dfu, pStr_Response_Index );
|
||
pReport_Dfu[pStr_Response_Index++] = LSB_16(CRC16_Data);
|
||
pReport_Dfu[pStr_Response_Index++] = MSB_16(CRC16_Data);
|
||
|
||
for(i=0; i<pStr_Response_Index; i++)
|
||
{
|
||
dtts_tx_buffer.data[dtts_tx_buffer.header]=pReport_Dfu[i];
|
||
dtts_tx_buffer.header++;
|
||
if(dtts_tx_buffer.header >= MAX_RX_LENGTH)
|
||
{
|
||
dtts_tx_buffer.header = 0;
|
||
}
|
||
}
|
||
|
||
free(pReport_Dfu); //销毁内存!!!
|
||
cJSON_free(Tx_Pack); //销毁链表!!!
|
||
cJSON_Delete(JsFrameTx_Report); //销毁内存!!!
|
||
}
|
||
|
||
/*************************************************************************************************
|
||
* Function Name:
|
||
* Description :
|
||
* Arguments : 打包数据并发送事件
|
||
* Return Value :
|
||
*************************************************************************************************/
|
||
void pack_timer_event()
|
||
{
|
||
if(start_tx & 0x01)
|
||
{
|
||
/* 打包数据到缓冲区 */
|
||
JsProtocol_Report(3,0,4,"41",PAS.RPM,"50",PAS.batt_level);
|
||
}
|
||
}
|
||
|
||
/*---------------------------------------------------------------*/
|