/*************************************************************************************************
**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);
  }
}

/*---------------------------------------------------------------*/
