浏览代码

shoe_mcu2.2.1_new_v2

lwy 2 年之前
父节点
当前提交
22f73c22dc
共有 100 个文件被更改,包括 16844 次插入0 次删除
  1. 二进制
      shoe_mcu2.2.1_new_v2/Picture/Down.png
  2. 二进制
      shoe_mcu2.2.1_new_v2/Picture/Hotkey.png
  3. 二进制
      shoe_mcu2.2.1_new_v2/Picture/config.png
  4. 26 0
      shoe_mcu2.2.1_new_v2/README.md
  5. 137 0
      shoe_mcu2.2.1_new_v2/app/app_Calibration.c
  6. 19 0
      shoe_mcu2.2.1_new_v2/app/app_Calibration.h
  7. 488 0
      shoe_mcu2.2.1_new_v2/app/app_ImuCalibration.c
  8. 13 0
      shoe_mcu2.2.1_new_v2/app/app_ImuCalibration.h
  9. 171 0
      shoe_mcu2.2.1_new_v2/app/app_baseinfo.c
  10. 15 0
      shoe_mcu2.2.1_new_v2/app/app_baseinfo.h
  11. 232 0
      shoe_mcu2.2.1_new_v2/app/app_charge/app_charge - 副本 (2).c
  12. 207 0
      shoe_mcu2.2.1_new_v2/app/app_charge/app_charge - 副本.c
  13. 205 0
      shoe_mcu2.2.1_new_v2/app/app_charge/app_charge.c
  14. 15 0
      shoe_mcu2.2.1_new_v2/app/app_charge/app_charge.h
  15. 215 0
      shoe_mcu2.2.1_new_v2/app/app_client.c
  16. 17 0
      shoe_mcu2.2.1_new_v2/app/app_client.h
  17. 171 0
      shoe_mcu2.2.1_new_v2/app/app_client_step.c
  18. 20 0
      shoe_mcu2.2.1_new_v2/app/app_client_step.h
  19. 208 0
      shoe_mcu2.2.1_new_v2/app/app_config.c
  20. 12 0
      shoe_mcu2.2.1_new_v2/app/app_config.h
  21. 236 0
      shoe_mcu2.2.1_new_v2/app/app_connect_manage.c
  22. 12 0
      shoe_mcu2.2.1_new_v2/app/app_connect_manage.h
  23. 83 0
      shoe_mcu2.2.1_new_v2/app/app_data_transfer.c
  24. 55 0
      shoe_mcu2.2.1_new_v2/app/app_data_transfer.h
  25. 228 0
      shoe_mcu2.2.1_new_v2/app/app_detectIsHost.c
  26. 27 0
      shoe_mcu2.2.1_new_v2/app/app_detectIsHost.h
  27. 412 0
      shoe_mcu2.2.1_new_v2/app/app_flash - 副本.c
  28. 365 0
      shoe_mcu2.2.1_new_v2/app/app_flash.c
  29. 120 0
      shoe_mcu2.2.1_new_v2/app/app_flash.h
  30. 299 0
      shoe_mcu2.2.1_new_v2/app/app_game.c
  31. 14 0
      shoe_mcu2.2.1_new_v2/app/app_game.h
  32. 94 0
      shoe_mcu2.2.1_new_v2/app/app_host.c
  33. 27 0
      shoe_mcu2.2.1_new_v2/app/app_host.h
  34. 41 0
      shoe_mcu2.2.1_new_v2/app/app_losspack.c
  35. 17 0
      shoe_mcu2.2.1_new_v2/app/app_losspack.h
  36. 207 0
      shoe_mcu2.2.1_new_v2/app/app_math.c
  37. 16 0
      shoe_mcu2.2.1_new_v2/app/app_math.h
  38. 55 0
      shoe_mcu2.2.1_new_v2/app/app_organ.c
  39. 12 0
      shoe_mcu2.2.1_new_v2/app/app_organ.h
  40. 224 0
      shoe_mcu2.2.1_new_v2/app/app_ota.c
  41. 13 0
      shoe_mcu2.2.1_new_v2/app/app_ota.h
  42. 299 0
      shoe_mcu2.2.1_new_v2/app/app_overturn - 副本 (2).c
  43. 385 0
      shoe_mcu2.2.1_new_v2/app/app_overturn - 副本 (3).c
  44. 256 0
      shoe_mcu2.2.1_new_v2/app/app_overturn - 副本.c
  45. 285 0
      shoe_mcu2.2.1_new_v2/app/app_overturn.c
  46. 14 0
      shoe_mcu2.2.1_new_v2/app/app_overturn.h
  47. 258 0
      shoe_mcu2.2.1_new_v2/app/app_overturn_备份.c
  48. 760 0
      shoe_mcu2.2.1_new_v2/app/app_pair_chargerpin.c
  49. 27 0
      shoe_mcu2.2.1_new_v2/app/app_pair_chargerpin.h
  50. 71 0
      shoe_mcu2.2.1_new_v2/app/app_power/app_power.c
  51. 13 0
      shoe_mcu2.2.1_new_v2/app/app_power/app_power.h
  52. 35 0
      shoe_mcu2.2.1_new_v2/app/app_safe.c
  53. 15 0
      shoe_mcu2.2.1_new_v2/app/app_safe.h
  54. 383 0
      shoe_mcu2.2.1_new_v2/app/app_self_checking.c
  55. 39 0
      shoe_mcu2.2.1_new_v2/app/app_self_checking.h
  56. 485 0
      shoe_mcu2.2.1_new_v2/app/app_single_line_pair.c
  57. 57 0
      shoe_mcu2.2.1_new_v2/app/app_single_line_pair.h
  58. 289 0
      shoe_mcu2.2.1_new_v2/app/app_step.c
  59. 15 0
      shoe_mcu2.2.1_new_v2/app/app_step.h
  60. 39 0
      shoe_mcu2.2.1_new_v2/app/app_switchimu.c
  61. 19 0
      shoe_mcu2.2.1_new_v2/app/app_switchimu.h
  62. 464 0
      shoe_mcu2.2.1_new_v2/ble_cfg/ble_comm.h
  63. 699 0
      shoe_mcu2.2.1_new_v2/ble_cfg/cli.c
  64. 100 0
      shoe_mcu2.2.1_new_v2/ble_cfg/cli.h
  65. 593 0
      shoe_mcu2.2.1_new_v2/ble_cfg/cli_vt100.h
  66. 289 0
      shoe_mcu2.2.1_new_v2/ble_cfg/dtalige.c
  67. 676 0
      shoe_mcu2.2.1_new_v2/ble_cfg/host.c
  68. 46 0
      shoe_mcu2.2.1_new_v2/ble_cfg/queue.c
  69. 76 0
      shoe_mcu2.2.1_new_v2/ble_cfg/queue.h
  70. 82 0
      shoe_mcu2.2.1_new_v2/ble_cfg/ringframe.c
  71. 62 0
      shoe_mcu2.2.1_new_v2/ble_cfg/ringframe.h
  72. 1634 0
      shoe_mcu2.2.1_new_v2/ble_cfg/slave.c
  73. 177 0
      shoe_mcu2.2.1_new_v2/ble_cfg/timeslot.c
  74. 325 0
      shoe_mcu2.2.1_new_v2/ble_dfu/ble_dfu.c
  75. 249 0
      shoe_mcu2.2.1_new_v2/ble_dfu/ble_dfu.h
  76. 367 0
      shoe_mcu2.2.1_new_v2/ble_dfu/ble_dfu_bonded.c
  77. 299 0
      shoe_mcu2.2.1_new_v2/ble_dfu/ble_dfu_unbonded.c
  78. 271 0
      shoe_mcu2.2.1_new_v2/bsp/bsp_adc.c
  79. 60 0
      shoe_mcu2.2.1_new_v2/bsp/bsp_adc.h
  80. 190 0
      shoe_mcu2.2.1_new_v2/bsp/bsp_esb.c
  81. 20 0
      shoe_mcu2.2.1_new_v2/bsp/bsp_esb.h
  82. 106 0
      shoe_mcu2.2.1_new_v2/bsp/bsp_flash.c
  83. 39 0
      shoe_mcu2.2.1_new_v2/bsp/bsp_flash.h
  84. 16 0
      shoe_mcu2.2.1_new_v2/bsp/bsp_gpio.c
  85. 12 0
      shoe_mcu2.2.1_new_v2/bsp/bsp_gpio.h
  86. 230 0
      shoe_mcu2.2.1_new_v2/bsp/bsp_interface.c
  87. 10 0
      shoe_mcu2.2.1_new_v2/bsp/bsp_interface.h
  88. 84 0
      shoe_mcu2.2.1_new_v2/bsp/bsp_mpu9250.c
  89. 143 0
      shoe_mcu2.2.1_new_v2/bsp/bsp_mpu9250.h
  90. 91 0
      shoe_mcu2.2.1_new_v2/bsp/bsp_ms5611.c
  91. 10 0
      shoe_mcu2.2.1_new_v2/bsp/bsp_ms5611.h
  92. 32 0
      shoe_mcu2.2.1_new_v2/bsp/bsp_protocol.c
  93. 32 0
      shoe_mcu2.2.1_new_v2/bsp/bsp_protocol.h
  94. 467 0
      shoe_mcu2.2.1_new_v2/bsp/bsp_pwm.c
  95. 88 0
      shoe_mcu2.2.1_new_v2/bsp/bsp_pwm.h
  96. 13 0
      shoe_mcu2.2.1_new_v2/bsp/bsp_pwm/bsp_pwm.h
  97. 92 0
      shoe_mcu2.2.1_new_v2/bsp/bsp_pwm/bsp_pwm_led_gpio.c
  98. 65 0
      shoe_mcu2.2.1_new_v2/bsp/bsp_pwm/bsp_pwm_led_ws2812.c
  99. 144 0
      shoe_mcu2.2.1_new_v2/bsp/bsp_rtc.c
  100. 19 0
      shoe_mcu2.2.1_new_v2/bsp/bsp_rtc.h

二进制
shoe_mcu2.2.1_new_v2/Picture/Down.png


二进制
shoe_mcu2.2.1_new_v2/Picture/Hotkey.png


二进制
shoe_mcu2.2.1_new_v2/Picture/config.png


+ 26 - 0
shoe_mcu2.2.1_new_v2/README.md

@@ -0,0 +1,26 @@
+
+### 编译环境
+keil 5.3
+### 
+
+#### 准备
+1. 下载nordic SDK ,nRF5_SDK_17.0.0_9d13099 [链接](http://git.ouj.com/ouj/shoes/src/master/smart_shoes/nRF5_SDK_17.0.0_9d13099)   
+2. 下载并安装nrfjprom工具 [链接](https://www.nordicsemi.com/-/media/Software-and-other-downloads/Desktop-software/nRF-command-line-tools/sw/Versions-10-x-x/10-15-2/nRF-Command-Line-Tools-10.15.2-x86.exe)
+
+### 编译和烧录
+在keil 中打开工程,根据实际需要选择PCB板和鞋子的功能,打开Application目录下的usr_config.h
+#### 选择使用的板子
+     选择PCB板>>>> PCB_VERSION - PCB板选择  >>>> PCB2.1
+#### 烧录快捷键
+##### 1. 添加OTA down
+   Tools >>>> Customize Tools Menu  添加OTA down
+![image] (http://git.ouj.com/ouj/shoe_mcu/src/master/Picture/Down.png)
+
+##### 2. 设置快捷键
+   Edit >>> Configuration >>>>> Shortcut Keys
+![image] (http://git.ouj.com/ouj/shoe_mcu/src/master/Picture/Hotkey.png)
+#### 设置DFU功能
+   勾选 BleNameHoldOn_ENANBLE  
+   公共 >>> 系统设置  >>>> BleNameHoldOn_ENANBLE
+![image] (http://git.ouj.com/ouj/shoe_mcu/src/master/Picture/config.png)
+

+ 137 - 0
shoe_mcu2.2.1_new_v2/app/app_Calibration.c

@@ -0,0 +1,137 @@
+#include "app_Calibration.h"
+#include "bsp_time.h"
+#include "system.h"
+#include "hal_imu.h"
+#include "hal_flash.h"
+#include "hal_ble_client.h"
+#include "arm_math.h"
+#include "drv_calibration.h"
+#include "nrf_gpio.h"
+#include "app_charge.h"
+
+static int16_t Acc[3]={0};
+static int16_t Gry[3]={0};
+static int16_t FrontMag[3]={0};
+
+/***********************************
+ *未校准:灭灯
+ *校准中:指示灯常亮
+ *校准完成:指示灯慢闪,亮10ms,灭灯2S
+ *校准错误:指示灯快闪,亮10ms,灭灯100ms
+************************************/
+static void app_calibration_CalLed_Process(void){
+	
+		static uint32_t tim =0;
+	
+		if(tim == 0){
+			tim = TIME_GetTicks();
+		}else if(TIME_GetTicks()-tim >= 60000){								//亮1分钟
+			tim = 0;
+			Process_Stop(app_calibration_CalLed_Process);				//停止该任务	
+		}
+		
+		
+		
+		nrf_gpio_pin_write(PIN_LED_RUN,0); 
+		nrf_delay_ms(10);
+		nrf_gpio_pin_write(PIN_LED_RUN,1);
+	  
+	  char printdata[200]={0};
+	  sprintf(printdata,"caldata:%f,%f,%f,%f,%f,%f",mBackup.cal[0],mBackup.cal[1],mBackup.cal[2],mBackup.cal[3],mBackup.cal[4],mBackup.cal[5]);
+	  DEBUG_LOG("%s\n",printdata);
+		Mahony_PRINT("caldata:%f,%f,%f,%f,%f,%f",mBackup.cal[0],mBackup.cal[1],mBackup.cal[2],mBackup.cal[3],mBackup.cal[4],mBackup.cal[5]);
+		
+		
+
+}
+
+#define USED_MAG_CHECK_BAREBOARD_VALUE_START		0
+#define USED_MAG_CHECK_BAREBOARD_VALUE_END			300
+void app_calibration_is_BareBoard_Process(void)
+{
+	if(IMU_GetCurrentMode() == STATE_IDLE_MODE)
+	{
+		IMU_GetMagFront(FrontMag);
+		if(USED_MAG_CHECK_BAREBOARD_VALUE_START < FrontMag[0] &&  FrontMag[0] < USED_MAG_CHECK_BAREBOARD_VALUE_END){
+			IMU_SetBareBoardMode(1);		//进入板子模式
+		}else{
+			IMU_SetBareBoardMode(0);		//不进入板子模式
+		}
+	}
+}
+
+void app_calibration_is_Calibration_Process(void)
+{
+	if(IMU_GetCurrentMode() == STATE_BAREBOARD_MODE)
+	{
+		
+		if(IMU_GetBareBoardMode() == 1)IMU_SetBareBoardMode(0);		//进入板子模式后,将进入板子模式的标志位清零。
+		
+		IMU_GetAcc(Acc);
+		IMU_GetGry(Gry);
+		IMU_GetMagFront(FrontMag);
+		
+		ImuCalibration_pcs(Acc, Gry, FrontMag);
+		if(ImuCalibration_GetState() == ImuCal_GetData){
+				nrf_gpio_pin_write(PIN_LED_RUN,0);
+				IMU_SetCalibrationMode(1);														//进入校准模式
+		}else{
+			if(FrontMag[0] >= USED_MAG_CHECK_BAREBOARD_VALUE_END || USED_MAG_CHECK_BAREBOARD_VALUE_START >= FrontMag[0]){
+				IMU_SetLowPowerMode(1);																//进入低功耗模式。
+			}
+		}
+	}
+}
+
+void app_calibration_Calibration_in_Process(void)
+{
+	if(IMU_GetCurrentMode() == STATE_CALIBRATION_MODE)
+	{
+		
+		if(IMU_GetCalibrationMode() == 1)IMU_SetCalibrationMode(0);		//进入板子校准模式后,将进入板子校准模式的标志位清零。
+		
+		IMU_GetAcc(Acc);
+		IMU_GetGry(Gry);
+		IMU_GetMagFront(FrontMag);
+		
+		ImuCalibration_pcs(Acc, Gry, FrontMag);
+		if(ImuCalibration_GetState() == ImuCal_finish){
+			Flash_SaveBackup();
+			Mahony_PRINT("ImuCal_state ImuCal_finish");
+			Process_Start(2000,"app_calibration_CalLed_Process",app_calibration_CalLed_Process);
+			Process_UpdatePeroid(app_calibration_CalLed_Process,2000);
+			IMU_SetLowPowerMode(1);																																														//进入低功耗模式。
+		}else if(ImuCalibration_GetState() == ImuCal_error || ImuCalibration_GetState() == ImuCal_quiet){
+			Mahony_PRINT("ImuCal_state ImuCal_error");
+			if(app_charge_Getstate() == BLE_Client_T_CHARGE_INSERT ||	app_charge_Getstate() == BLE_Client_T_CHARGE_DONE){			//若是充电,重新校准
+				ImuCalibration_SetState(ImuCal_init);
+				IMU_SetBareBoardMode(1);																																												//进入板子模式
+			}else{
+				Process_Start(100,"app_calibration_CalLed_Process",app_calibration_CalLed_Process);
+				Process_UpdatePeroid(app_calibration_CalLed_Process,100);
+				IMU_SetLowPowerMode(1);																																													//进入低功耗模式。
+			}
+		}
+	}
+	
+}
+
+void app_calibration_Init(void)
+{
+	Process_Start(1000,"app_calibration_is_BareBoard_Process",app_calibration_is_BareBoard_Process);				//是否进入板子模式
+	Process_Start(200,"app_calibration_is_Calibration_Process",app_calibration_is_Calibration_Process);			//是否进入板子校准模式
+	Process_Start(10,"app_calibration_Calibration_in_Process",app_calibration_Calibration_in_Process);			//校准处理中
+}
+
+
+
+
+
+
+
+
+
+
+
+
+

+ 19 - 0
shoe_mcu2.2.1_new_v2/app/app_Calibration.h

@@ -0,0 +1,19 @@
+#ifndef __APP_CALIBRATION_H__
+#define __APP_CALIBRATION_H__
+#include <stdbool.h>
+#include <stdint.h>
+#include <string.h>
+#include "sdk_common.h"
+#include "SEGGER_RTT.h"
+#include "usr_config.h"
+
+
+void app_calibration_Init(void);
+
+
+#endif
+
+
+
+
+

+ 488 - 0
shoe_mcu2.2.1_new_v2/app/app_ImuCalibration.c

@@ -0,0 +1,488 @@
+#include <math.h>
+#include "stdio.h"
+#include "ble_comm.h"
+#include "hal_flash.h"
+#include "hal_imu.h"
+#include "system.h"
+#include "bsp_time.h"
+#include "app_ImuCalibration.h"
+#include "app_charge.h"
+#include "hal_ble_client.h"
+
+
+#if CALIBRATION_ENANBLE
+
+enum{
+	ImuCal_init,
+	ImuCal_GetData,
+	ImuCal_Analyze,
+	ImuCal_finish,
+	ImuCal_error,
+  ImuCal_quiet,
+};
+
+char printfbuf[256];
+void send_ANO(unsigned char fun, unsigned char* p, int len);
+#define Mahony_PRINT(...) send_ANO(0,(unsigned char*)printfbuf,sprintf(printfbuf,__VA_ARGS__))
+#define ERROR_PIN_ON nrf_gpio_pin_write(PIN_LED_RUN,0);
+#define ERROR_PIN_OFF nrf_gpio_pin_write(PIN_LED_RUN,1);
+
+static float invSampleFreq = 0.010f;                                     //采样率(Hz)
+
+//匿名四轴上位机api
+void send_ANO(unsigned char fun, unsigned char* p, int len){
+    unsigned char buf[256];
+    int L = 0;
+    unsigned char ver = 0;
+    buf[L] = 0xAA;
+    ver += buf[L++];
+    buf[L] = 0x05;
+    ver += buf[L++];
+    buf[L] = 0xAF;
+    ver += buf[L++];
+    buf[L] = fun;
+    ver += buf[L++];
+    buf[L] = len;
+    ver += buf[L++];
+    for (int i = 0; i < len; i++)
+    {
+        buf[L] = p[i];
+        ver += buf[L++];
+    }
+    buf[L++] = ver;
+    //    extern void send_bytes_client(unsigned char* bytes, int len);
+    send_bytes_client(buf, L);
+//          SEGGER_RTT_Write(0,buf, L);
+    //  ESB_SendBuff(buf,L);
+}
+
+void send_ANO_Quaternion(float* Q){
+    unsigned char buf[256];
+    unsigned char L = 0;
+    int quat[4];
+    quat[0] = Q[0] * 10000;
+    quat[1] = Q[1] * 10000;
+    quat[2] = Q[2] * 10000;
+    quat[3] = Q[3] * 10000;
+    buf[L++] = (unsigned char)(quat[0] >> 24);
+    buf[L++] = (unsigned char)(quat[0] >> 16);
+    buf[L++] = (unsigned char)(quat[0] >> 8);
+    buf[L++] = (unsigned char)(quat[0] >> 0);
+    buf[L++] = (unsigned char)(quat[1] >> 24);
+    buf[L++] = (unsigned char)(quat[1] >> 16);
+    buf[L++] = (unsigned char)(quat[1] >> 8);
+    buf[L++] = (unsigned char)(quat[1] >> 0);
+    buf[L++] = (unsigned char)(quat[2] >> 24);
+    buf[L++] = (unsigned char)(quat[2] >> 16);
+    buf[L++] = (unsigned char)(quat[2] >> 8);
+    buf[L++] = (unsigned char)(quat[2] >> 0);
+    buf[L++] = (unsigned char)(quat[3] >> 24);
+    buf[L++] = (unsigned char)(quat[3] >> 16);
+    buf[L++] = (unsigned char)(quat[3] >> 8);
+    buf[L++] = (unsigned char)(quat[3] >> 0);
+    buf[L++] = 0;
+    send_ANO(0x03, buf, L);
+}
+
+void send_ANO_STATUS(float _roll, float _pitch, float _yaw, float _posx, float _posy, float _posz){
+    unsigned char buf[256];
+    unsigned char L = 0;
+    short roll = _roll * 100;
+    short pitch = _pitch * 100;
+    short yaw = _yaw * 100;
+    short posx = _posx * 100;
+    short posy = _posy * 100;
+    short posz = _posz * 100;
+    buf[L++] = (unsigned char)(roll >> 8);
+    buf[L++] = (unsigned char)(roll >> 0);
+    buf[L++] = (unsigned char)(pitch >> 8);
+    buf[L++] = (unsigned char)(pitch >> 0);
+    buf[L++] = (unsigned char)(yaw >> 8);
+    buf[L++] = (unsigned char)(yaw >> 0);
+    buf[L++] = (unsigned char)(posx >> 8);
+    buf[L++] = (unsigned char)(posx >> 0);
+    buf[L++] = (unsigned char)(posy >> 8);
+    buf[L++] = (unsigned char)(posy >> 0);
+    buf[L++] = (unsigned char)(posz >> 8);
+    buf[L++] = (unsigned char)(posz >> 0);
+    buf[L++] = 0;
+    send_ANO(0x01, buf, L);
+}
+
+void send_ANO_SENSER(short gx, short gy, short gz, short ax, short ay, short az, short mx, short my, short mz){
+    unsigned char buf[256];
+    unsigned char L = 0;
+    buf[L++] = (unsigned char)(ax >> 8);
+    buf[L++] = (unsigned char)(ax >> 0);
+    buf[L++] = (unsigned char)(ay >> 8);
+    buf[L++] = (unsigned char)(ay >> 0);
+    buf[L++] = (unsigned char)(az >> 8);
+    buf[L++] = (unsigned char)(az >> 0);
+    buf[L++] = (unsigned char)(gx >> 8);
+    buf[L++] = (unsigned char)(gx >> 0);
+    buf[L++] = (unsigned char)(gy >> 8);
+    buf[L++] = (unsigned char)(gy >> 0);
+    buf[L++] = (unsigned char)(gz >> 8);
+    buf[L++] = (unsigned char)(gz >> 0);
+    buf[L++] = (unsigned char)(mx >> 8);
+    buf[L++] = (unsigned char)(mx >> 0);
+    buf[L++] = (unsigned char)(my >> 8);
+    buf[L++] = (unsigned char)(my >> 0);
+    buf[L++] = (unsigned char)(mz >> 8);
+    buf[L++] = (unsigned char)(mz >> 0);
+    send_ANO(0x02, buf, L);
+}
+
+//LDLT分解法解线性方程组,和LDLTBKSB_6一起用
+char LDLTDCMP_6(int n, float (*a)[6]){
+    int k;
+    int m;
+    int i;
+    for (k = 0; k < n; k++){
+        for (m = 0; m < k; m++){
+            a[k][k] = a[k][k] - a[m][k] * a[k][m];
+        }
+        if (a[k][k] == 0){
+            return 1;//error
+        }
+        for(i = k + 1; i < n; i++){
+            for (m = 0; m < k; m++){
+                a[k][i] = a[k][i] - a[m][i] * a[k][m];
+            }
+            a[i][k] = a[k][i] / a[k][k];
+        }
+    }
+    return 0;
+}
+
+//LDLT分解法解线性方程组,和LDLTDCMP_6一起用
+void LDLTBKSB_6(int n, float (*a)[6], float* b)
+{
+    int k;
+    int i;
+    for (i = 0; i < n; i++){
+        for (k = 0; k < i; k++){
+            b[i] = b[i] - a[i][k] * b[k];
+        }
+    }
+    for (i = n - 1; i >= 0; i--){
+        b[i] = b[i] / a[i][i];
+        for (k = i + 1; k < n; k++){
+            b[i] = b[i] - a[k][i] * b[k];
+        }
+    }
+}
+
+float Acc_static_calibration_b[6] = {0.0f};
+float Acc_static_calibration_D[6][6] = {0.0f};
+float Acc_static_calibration_out[6] = {1.000718f, 1.001100f, 0.988632f, 0.012943f, 0.006423f, 0.0034f}; //V1.3板
+
+void Ellipsoidfit_six_pram_update(float X, float Y, float Z, float* b, float (*D)[6]){
+    float coft[6] = {0.0f};
+    int  r, j;
+    coft[0] = X * X;
+    coft[3] = 2.0f * X;
+    coft[1] = Y * Y;
+    coft[4] = 2.0f * Y;
+    coft[2] = Z * Z;
+    coft[5] = 2.0f * Z;
+    for (j = 0; j < 6; j++){
+        b[j] += coft[j];
+    }
+    for (r = 0; r < 6; r++){
+        for (j = 0; j <= r; j++){
+            D[r][j] += coft[r] * coft[j];
+        }
+    }
+    for (r = 0; r < 6; r++){
+        for (j = 5; j > r; j--){
+            D[r][j] = D[j][r];
+        }
+    }
+}
+
+void Ellipsoidfit_six_pram_Solution(float* b, float (*D)[6], float* out)
+{
+    float temp = 0;
+    //解线性方程组,求解超定方程最小二乘解
+    LDLTDCMP_6(6, D);
+    LDLTBKSB_6(6, D, b);
+    temp = b[1] * b[2] * b[3] * b[3] + b[0] * b[2] * b[4] * b[4] + b[0] * b[1] * b[5] * b[5];
+    temp = 1.0f - (temp / (temp + (b[0] * b[1] * b[2])));
+    out[0] = sqrtf(temp * b[0]);
+    out[1] = sqrtf(temp * b[1]);
+    out[2] = sqrtf(temp * b[2]);
+    out[3] = b[3] * temp / out[0];
+    out[4] = b[4] * temp / out[1];
+    out[5] = b[5] * temp / out[2];
+}
+
+
+	static float Acc_before[3];
+	static float accmod=0,accmodbef=0;
+	static char cun=0;
+static unsigned int  timer_cli=0;
+//需要200ms执行一次,开始信号检测,检测到返回1,否则返回0
+char begin_REC(float *acccli)
+{
+
+	float gyrmod = 0;
+	gyrmod = (acccli[0]*Acc_before[0]) + (acccli[1]*Acc_before[1]) + (acccli[2]*Acc_before[2]);
+	accmod = sqrtf(acccli[0] * acccli[0] + acccli[1] * acccli[1] + acccli[2] * acccli[2]);
+	gyrmod = gyrmod/(accmod * accmodbef);
+	gyrmod = acosf(gyrmod)*3.14f;
+	Acc_before[0]=acccli[0];Acc_before[1]=acccli[1];Acc_before[2]=acccli[2];
+	accmodbef=accmod;
+	Mahony_PRINT("gyrmod:%f,timer:%d cun:%d  %f\n",gyrmod,TIME_GetTicks()-timer_cli,cun,accmodbef);
+	timer_cli=TIME_GetTicks();
+
+	if((gyrmod > 0.25f)&&(gyrmod < 0.75f))
+	{
+		cun++;
+	}else 
+	{
+//		if(cun>=3)cun--;else 
+		cun=0;		
+	}
+	if(cun>=10){
+		cun=0;
+		return 1;
+	}
+	else return 0;
+}
+
+static uint8_t ImuCal_state = ImuCal_init;
+char Acc_static_calibration(float* Acc_in, float* Acc_out, const float* gyr)
+{
+    static int temp = 0;
+    static int overtime = 0;
+    static int caiyingcun = 0;
+    switch (ImuCal_state){
+        case ImuCal_init:{//未校准状态
+					if(begin_REC(Acc_in)){
+							ImuCal_state = ImuCal_GetData;
+							caiyingcun = 0;
+							overtime = 0;
+							for (int i = 0; i < 6; i++){
+									Acc_static_calibration_b[i] = 0.0f;
+									Acc_static_calibration_D[i][0] = 0.0f;
+									Acc_static_calibration_D[i][1] = 0.0f;
+									Acc_static_calibration_D[i][2] = 0.0f;
+									Acc_static_calibration_D[i][3] = 0.0f;
+									Acc_static_calibration_D[i][4] = 0.0f;
+									Acc_static_calibration_D[i][5] = 0.0f;
+							}
+							ERROR_PIN_ON
+							Mahony_PRINT("Acc_static_calibration -> start \r\n");
+							temp = 0;
+					}
+        }
+        break;
+        case ImuCal_GetData:{//采集校准数据状态
+        
+								float gyrmod = sqrtf(gyr[0] * gyr[0] + gyr[1] * gyr[1] + gyr[2] * gyr[2]);
+								if (gyrmod < 18.27f){ //静止检测
+										//采样数据
+										if(((Acc_in[0]<2.0f)||(Acc_in[0]>-2.0f))&&((Acc_in[1]<2.0f)||(Acc_in[1]>-2.0f))&&((Acc_in[2]<2.0f)||(Acc_in[2]>-2.0f))){
+											Ellipsoidfit_six_pram_update(Acc_in[0], Acc_in[1], Acc_in[2], Acc_static_calibration_b, Acc_static_calibration_D);
+											caiyingcun++;
+											send_ANO_SENSER(gyr[0] * 100, gyr[1] * 100, gyr[2] * 100, Acc_in[0] * 100, Acc_in[1] * 100, Acc_in[2] * 100, 0, 0, 0);	
+										}
+								}
+								
+								//检测结束条件
+								if ((gyrmod > 25.0f) && (gyrmod < 60.0f) && (caiyingcun > 20)){
+										temp = temp + 1;
+								}
+								else{
+									if(temp>50)temp--;else temp = 0;									
+								}								
+								
+								if (temp * invSampleFreq > 2.0f){
+										Ellipsoidfit_six_pram_Solution(Acc_static_calibration_b, Acc_static_calibration_D, Acc_static_calibration_out);
+										ImuCal_state = ImuCal_Analyze;
+									  Mahony_PRINT("ImuCal_GetData");
+								}
+								else
+								{
+//									Mahony_PRINT("ImuCal_GetData temp %d",temp);
+								}
+								overtime++;
+								
+								if (overtime * invSampleFreq > 300.0f){
+										ImuCal_state = ImuCal_error;
+									  Mahony_PRINT("ImuCal overtime ImuCal_error");
+								}
+						}
+        break;
+        case ImuCal_Analyze:{//校准数据处理状态
+								float gyrmod = sqrtf(gyr[0] * gyr[0] + gyr[1] * gyr[1] + gyr[2] * gyr[2]);
+								if (gyrmod < 18.27f){ //静止检测
+										if (((Acc_static_calibration_out[0] > 0.85f) && (Acc_static_calibration_out[0] < 1.15f)) &&
+												((Acc_static_calibration_out[1] > 0.85f) && (Acc_static_calibration_out[1] < 1.15f)) &&
+												((Acc_static_calibration_out[2] > 0.85f) && (Acc_static_calibration_out[2] < 1.15f))){
+//													Mahony_PRINT("out[%f,%f,%f,%f,%f,%f] \r\n", Acc_static_calibration_out[0], Acc_static_calibration_out[1], Acc_static_calibration_out[2], Acc_static_calibration_out[3], Acc_static_calibration_out[4], Acc_static_calibration_out[5]);
+													Mahony_PRINT("ImuCal_state ImuCal_finish");
+													temp = 0;
+													ImuCal_state = ImuCal_finish;
+													for(int a = 0; a < 6; a++){
+									            mBackup.cal[a] = Acc_static_calibration_out[a];
+								          } 
+										}
+										else{
+												ImuCal_state = ImuCal_quiet;
+										}
+										overtime = 0;
+								}
+             }
+        break;
+//        case ImuCal_finish:{//已经校准完状态
+//					    Mahony_PRINT("ImuCal_state ImuCal_init");
+//							ImuCal_state = 0;
+//            }
+//        break;
+//        case ImuCal_error:{//校准过程中断退出状态
+//					    Mahony_PRINT("ImuCal_state ImuCal_init");
+//							ImuCal_state = 0;
+//					    Mahony_PRINT("ImuCal_state ImuCal_init");
+//            }
+//        break;
+//        case ImuCal_quiet:{//校准过程中断退出状态
+//							ImuCal_state = 0;
+//					  }
+//        break;
+    }
+    return ImuCal_state;
+}
+
+void Mahony_imu_lbs(short* Acc_in, short* Gyr_in, short* Mag_in, float* Acc, float* Gyr, float* Mag)
+{
+    float ACC_LBS = 32768.0f / 16.0f;
+    float GYR_LBS = 32768.0f / 2000.0f;
+    Acc[0] = Acc_in[0] / ACC_LBS;
+    Acc[1] = Acc_in[1] / ACC_LBS;
+    Acc[2] = Acc_in[2] / ACC_LBS;
+    Gyr[0] = Gyr_in[0] / GYR_LBS;
+    Gyr[1] = Gyr_in[1] / GYR_LBS;
+    Gyr[2] = Gyr_in[2] / GYR_LBS;
+    Mag[0] = Mag_in[0] / 1.0f;
+    Mag[1] = Mag_in[1] / 1.0f;
+    Mag[2] = Mag_in[2] / 1.0f;
+}
+
+static float acc[3], gyr[3], mag[3];
+static void ImuCalibration_pcs(short* Acc, short* Gyr, short* Mag)
+{
+    Mahony_imu_lbs(Acc, Gyr, Mag, acc, gyr, mag); //转换IMU数据量程,加速度单位转换为G,陀螺仪单位转换为度每秒,磁力计不需要转换单位,后面会做归一化处理
+    Acc_static_calibration(acc, NULL, gyr);
+}
+
+/***********************************
+ *未校准:灭灯
+ *校准中:指示灯常亮
+ *校准完成:指示灯慢闪,亮10ms,灭灯2S
+ *校准错误:指示灯快闪,亮10ms,灭灯100ms
+************************************/
+static void app_ImuCalLed_process(void){
+		nrf_gpio_pin_write(PIN_LED_RUN,0); 
+		nrf_delay_ms(10);
+		nrf_gpio_pin_write(PIN_LED_RUN,1);
+	  
+	  char printdata[200]={0};
+	  sprintf(printdata,"caldata:%f,%f,%f,%f,%f,%f",mBackup.cal[0],mBackup.cal[1],mBackup.cal[2],mBackup.cal[3],mBackup.cal[4],mBackup.cal[5]);
+	  DEBUG_LOG("%s\n",printdata);
+		Mahony_PRINT("caldata:%f,%f,%f,%f,%f,%f",mBackup.cal[0],mBackup.cal[1],mBackup.cal[2],mBackup.cal[3],mBackup.cal[4],mBackup.cal[5]);
+
+}
+
+uint8_t app_imucal_getstate(void){
+	 if(ImuCal_GetData == ImuCal_state || ImuCal_Analyze == ImuCal_state)return 1;
+	 else return 0;
+}
+
+static void app_cal_process(void){
+	 static uint8_t state =0;
+   static uint8_t temp =0;
+	 int16_t Acc[3]={0};
+	 int16_t Gry[3]={0};
+	 int16_t Mag[3]={0};
+	 uint8_t isGameMode =0;
+	 switch(state){
+		 case 0: 
+			    IMU_GetFrontMagAndLowPowerAcc();
+			    IMU_GetAcc(Acc);
+          IMU_GetGry(Gry);
+		      
+					 ImuCalibration_pcs((short *)Acc,(short *)Gry,(short *)Mag);
+					 if(ImuCal_state == ImuCal_GetData){
+							Process_UpdatePeroid(app_cal_process,10);
+//							Process_SetHoldOn(app_cal_process,1);
+						  nrf_gpio_pin_write(PIN_LED_RUN,0);
+							state =1;
+						  isGameMode = 1;
+	            IMU_SetGameMode(isGameMode);
+						  temp=0;
+					 } 
+					 break;
+		 case 1:
+			     if(IMU_GetGameMode()){
+						  state =2;
+					 }else{
+						  temp++;
+						  if(temp >=20)state =0;
+					 }
+			     break;
+		 case 2:
+			    IMU_GetAcc(Acc);
+          IMU_GetGry(Gry);
+				  ImuCalibration_pcs((short *)Acc,(short *)Gry,(short *)Mag);
+//		      DEBUG_LOG(">>>>>>>22222\n");
+				  if(ImuCal_state == ImuCal_finish){
+						Flash_SaveBackup();
+						Mahony_PRINT("ImuCal_state ImuCal_finish");
+						Process_Start(2000,"app_cal_process",app_ImuCalLed_process);
+						Process_UpdatePeroid(app_ImuCalLed_process,2000);
+						
+						Process_UpdatePeroid(app_cal_process,200);
+//						Process_SetHoldOn(app_cal_process,0);
+						state =3;
+				  }
+				  else if(ImuCal_state == ImuCal_error || ImuCal_state == ImuCal_quiet){
+						Mahony_PRINT("ImuCal_state ImuCal_error");
+						Process_Start(100,"app_cal_process",app_ImuCalLed_process);
+						Process_UpdatePeroid(app_ImuCalLed_process,100);
+						
+						Process_UpdatePeroid(app_cal_process,200);
+//						Process_SetHoldOn(app_cal_process,0);
+						isGameMode = 0;
+	          IMU_SetGameMode(isGameMode);
+						state =3;
+				  }
+					break;
+		 case 3:
+			    if(!IMU_GetGameMode()){
+					    state = 4;
+				  }
+				  else if(++temp>20){ temp = 0;
+					    state = 4;
+				  }
+			    break;
+		 case 4:
+			    if(app_charge_Getstate() == BLE_Client_T_CHARGE_INSERT ||	app_charge_Getstate() == BLE_Client_T_CHARGE_DONE){
+						  state =0;
+						  ImuCal_state = ImuCal_init;
+						  Process_Stop(app_ImuCalLed_process);
+					}
+
+			    break;
+	 }
+}
+
+void app_ImuCalibration_init(void){
+	 Process_Start(200,"app_cal_process",app_cal_process);
+	 Process_SetHoldOn(app_cal_process,1);
+}
+
+#endif
+
+

+ 13 - 0
shoe_mcu2.2.1_new_v2/app/app_ImuCalibration.h

@@ -0,0 +1,13 @@
+#ifndef __app_ImuCalibration_h__
+#define __app_ImuCalibration_h__
+#include <stdbool.h>
+#include <stdint.h>
+#include <string.h>
+#include "sdk_common.h"
+#include "SEGGER_RTT.h"
+#include "usr_config.h"
+
+void app_ImuCalibration_init(void);
+uint8_t app_imucal_getstate(void);
+
+#endif

+ 171 - 0
shoe_mcu2.2.1_new_v2/app/app_baseinfo.c

@@ -0,0 +1,171 @@
+#include "usr.h"
+#include "app_baseinfo.h"
+#include "hal_ble_client.h"
+#include "hal_ble_host.h"
+#include "bsp_time.h"
+#include "hal_led.h"
+#include "ble_gap.h"
+#include "bsp_battery.h"
+#include "drv_ms5611.h"
+
+/*************************************************/
+#define SHOES_NAME "SMART SHOE"
+#define SHOES_NAME_LEN  64
+#define HARDWARE_VERSION	0x0100
+#define SOFTWARE_VERSION	0x0100
+#define BASEINFOBUFF_LEN  80
+static uint8_t baseinfoBuff[128];
+static uint8_t basedata[16];
+
+static uint8_t isGetClientInfo = 0;
+void Host_GetClientInfo(void)
+{
+	static uint8_t buf[16];
+	buf[0] = BLE_Host_T_UPDATE_BASEINFO;
+	BLE_Host_Tx_Send(BLE_Host_T_UPDATE,buf,9,1,0,0,0);
+}
+
+void BASEINFO_HostGetClientData(void)
+{
+	static uint32_t tim=0;
+	if(TIME_GetTicks()-tim>=10000){ tim = TIME_GetTicks();
+		if(isGetClientInfo==0) Host_GetClientInfo();
+	}
+}
+
+ //>> 0xA1: 查询
+void cb_BLE_Host_R_UPDATE(void* handle)
+{
+	BLE_Host_Rx_t *target = handle;
+	uint8_t _cmd = target->pDat[0];
+	switch(_cmd){
+		case BLE_Client_R_UPDATE_BASEINFO:{
+			//>> 0(设备基本信息): 开始时间ms(8)
+			//<< 0(子命令): 设备型号(64)+左鞋蓝牙地址(6)+硬件版本(2)+软件版本(2)+左鞋蓝牙地址(6)+硬件版本(6)+软件版本(2)
+			//>> AA 06 F9 A1 00 4A
+			//<< AA 55 AA A1 00 53 4D 41 52 54 20 53 48 4F 45 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 C1 EB D0 E3 87 47 01 00 01 00 00 00 00 00 00 4F
+			BLE_Client_Tx_Send(BLE_Client_T_UPDATE,baseinfoBuff,BASEINFOBUFF_LEN,1,0,0,0);
+			break;}
+		case BLE_Client_R_UPDATE_DATA:{
+			//>> 1(设备数据)
+			//<< 1(子命令): 左鞋电量(1)+左鞋温度(1)+左鞋压力(4)+右鞋电量(1)+右鞋温度(1)+右鞋压力(4)
+			//>> AA 06 F9 A1 01 4B
+			//<< AA 12 ED A1 01 00 90 12 34 56 78 00 90 12 34 56 78 93
+
+			break;}
+		case BLE_Client_R_UPDATE_STEPNUM:{//>> 2: 查询步数 + 0 + byte[8]: 更新时间ms + byte[1]:距离上一个整点的分钟数 
+								//	<< 2 + 0: 开始 + byte[8]: 开始时间ms + byte[1]: 包的数量
+								//		<< 2 + byte[1]: 包序号 + byte[4]: 每小时步数(前面两个byte为步数,后面两个byte为距离) + byte[4]: 每小时步数(前面两个byte为步数,后面两个byte为距离) + byte[4]: 每小时步数(前面两个byte为步数,后面两个byte为距离) ..
+								//			>> 2 + byte[1]: 包序号(表示收到反馈)
+								//  	<< 2 + 2: byte[4]: 每小时步数 + byte[4]: 每小时步数 + byte[4]: 每小时步数 ..
+								//			>> 2 + byte[1]: 包序号(表示收到反馈).. 包的数量 == 序号 结束流程
+			
+			break;}
+		default:break;
+	}
+}
+
+void BASEINFO_SendUpdateData(void)
+{
+	//>> 1(设备数据)
+	//<< 1(子命令): 左鞋电量(1)+左鞋温度(1)+左鞋压力(4)+右鞋电量(1)+右鞋温度(1)+右鞋压力(4)
+	//>> AA 06 F9 A1 01 4B
+	//<< AA 12 ED A1 01 00 90 12 34 56 78 00 90 12 34 56 78 93
+	uint8_t L=0;
+	int32_t temperature;
+	uint32_t press;
+	sd_temp_get(&temperature);
+	temperature = temperature>>2; 
+	press = MS5611_ReadPressure();
+	DEBUG_LOG("temperature=%d\n",temperature);
+	DEBUG_LOG("press=%d\n",press);
+	temperature = 0x90;
+	press = 0x12345678;
+	
+	//子命令
+	basedata[L++] = BLE_Client_T_UPDATE_DATA;
+	//左鞋
+	basedata[L++] = ADC_GetBatteryPersent();
+	basedata[L++] = (uint8_t)temperature;
+	basedata[L++] = (uint8_t)(press>>24);
+	basedata[L++] = (uint8_t)(press>>16);
+	basedata[L++] = (uint8_t)(press>>8);
+	basedata[L++] = (uint8_t)(press>>0);
+	//右鞋
+	basedata[L++] = ADC_GetBatteryPersent();
+	basedata[L++] = (uint8_t)temperature;
+	basedata[L++] = (uint8_t)(press>>24);
+	basedata[L++] = (uint8_t)(press>>16);
+	basedata[L++] = (uint8_t)(press>>8);
+	basedata[L++] = (uint8_t)(press>>0);
+	BLE_Client_Tx_Send(BLE_Client_T_UPDATE,basedata,L,1,0,0,0);
+}
+
+ //>> 0xA1: 查询
+void cb_BLE_Client_R_UPDATE(void* handle)
+{
+	BLE_Client_Rx_t *target = handle;
+	uint8_t _cmd = target->pDat[0];
+	switch(_cmd){
+		case BLE_Client_R_UPDATE_BASEINFO:{
+			//>> 0(设备基本信息): 开始时间ms(8)
+			//<< 0(子命令): 设备型号(64)+左鞋蓝牙地址(6)+硬件版本(2)+软件版本(2)+左鞋蓝牙地址(6)+硬件版本(6)+软件版本(2)
+			//>> AA 06 F9 A1 00 4A
+			//<< AA 55 AA A1 00 53 4D 41 52 54 20 53 48 4F 45 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 C1 EB D0 E3 87 47 01 00 01 00 00 00 00 00 00 4F
+			BLE_Client_Tx_Send(BLE_Client_T_UPDATE,baseinfoBuff,BASEINFOBUFF_LEN,1,0,0,0);
+			break;}
+		case BLE_Client_R_UPDATE_DATA:{
+			//>> 1(设备数据)
+			//<< 1(子命令): 左鞋电量(1)+左鞋温度(1)+左鞋压力(4)+右鞋电量(1)+右鞋温度(1)+右鞋压力(4)
+			//>> AA 06 F9 A1 01 4B
+			//<< AA 12 ED A1 01 00 90 12 34 56 78 00 90 12 34 56 78 93
+			BASEINFO_SendUpdateData();
+			break;}
+		case BLE_Client_R_UPDATE_STEPNUM:{//>> 2: 查询步数 + 0 + byte[8]: 更新时间ms + byte[1]:距离上一个整点的分钟数 
+								//	<< 2 + 0: 开始 + byte[8]: 开始时间ms + byte[1]: 包的数量
+								//		<< 2 + byte[1]: 包序号 + byte[4]: 每小时步数(前面两个byte为步数,后面两个byte为距离) + byte[4]: 每小时步数(前面两个byte为步数,后面两个byte为距离) + byte[4]: 每小时步数(前面两个byte为步数,后面两个byte为距离) ..
+								//			>> 2 + byte[1]: 包序号(表示收到反馈)
+								//  	<< 2 + 2: byte[4]: 每小时步数 + byte[4]: 每小时步数 + byte[4]: 每小时步数 ..
+								//			>> 2 + byte[1]: 包序号(表示收到反馈).. 包的数量 == 序号 结束流程
+			
+			break;}
+		default:break;
+	}
+}
+
+void BASEINFO_Set(void)
+{ //<< 0(设备基本信息): 设备型号(64)+左鞋蓝牙地址(6)+硬件版本(2)+软件版本(2)+左鞋蓝牙地址(6)+硬件版本(6)+软件版本(2)
+	ble_gap_addr_t mAddr;
+	uint32_t err_code;
+	uint8_t L = SHOES_NAME_LEN+1;
+	memset(baseinfoBuff,0,sizeof(baseinfoBuff));
+	//子命令
+	baseinfoBuff[0] = BLE_Client_T_UPDATE_BASEINFO;
+	//设备名称
+	for(int i=0;i<sizeof(SHOES_NAME);i++){
+		baseinfoBuff[i+1] = SHOES_NAME[i];
+	}
+	//MAC 地址
+	err_code = sd_ble_gap_addr_get(&mAddr); APP_ERROR_CHECK(err_code);
+	DEBUG_LOG("mac addr:");for(int i=0;i<6;i++){DEBUG_LOG("%02X ",mAddr.addr[i]);}DEBUG_LOG("\n");
+	for(int i=0;i<6;i++){
+		baseinfoBuff[L++] = mAddr.addr[5-i];
+	}
+	//硬件版本
+	baseinfoBuff[L++] = (uint8_t)((uint16_t)HARDWARE_VERSION>>8);
+	baseinfoBuff[L++] = (uint8_t)((uint16_t)HARDWARE_VERSION>>0);
+	//软件版本
+	baseinfoBuff[L++] = (uint8_t)((uint16_t)SOFTWARE_VERSION>>8);
+	baseinfoBuff[L++] = (uint8_t)((uint16_t)SOFTWARE_VERSION>>0);
+}
+
+void BASEINFO_Initialize(void)
+{
+	BASEINFO_Set();
+	BLE_Client_Rx_Regist(BLE_Client_R_UPDATE,cb_BLE_Client_R_UPDATE);
+	BLE_Host_Rx_Regist(BLE_Host_R_UPDATE,cb_BLE_Host_R_UPDATE);
+	Process_Regist(BASEINFO_HostGetClientData);
+	
+}
+
+

+ 15 - 0
shoe_mcu2.2.1_new_v2/app/app_baseinfo.h

@@ -0,0 +1,15 @@
+#ifndef __app_baseinfo_h__
+#define __app_baseinfo_h__
+#include <stdbool.h>
+#include <stdint.h>
+#include <string.h>
+#include "sdk_common.h"
+#include "SEGGER_RTT.h"
+#include "usr_config.h"
+
+void BASEINFO_Initialize(void);
+
+#endif
+
+
+

+ 232 - 0
shoe_mcu2.2.1_new_v2/app/app_charge/app_charge - 副本 (2).c

@@ -0,0 +1,232 @@
+#include "usr_config.h"
+#include "bsp_time.h"
+#include "system.h"
+#include "hal_led.h"
+#include "nrf_gpio.h"
+#include "hal_ble_client.h"
+#include "hal_ble_host.h"
+#include "app_charge.h"
+#include "app_flash.h"
+#include "hal_battery.h"
+#include "ble_comm.h"
+#include "hal_ble_uart0.h"
+
+/************************ 函数声明 ***********************************/
+
+/************************ 变量 ***********************************/
+static uint8_t app_charge_state = BLE_CHARGE_PULLOUT;
+
+/********************************************************/
+uint8_t app_charge_Getstate(void)
+{
+	return app_charge_state;
+}
+
+static void app_send_charge(void)
+{
+	uint8_t sbuf[2]={0};
+	uint8_t L = 0;
+	if(mFlash.isHost) sbuf[L++] = 0;
+	else sbuf[L++] = 1;
+	sbuf[L++] = app_charge_state;
+	BLE_Client_Tx_Send(0,BLE_CHARGE,sbuf,L);
+}
+
+void cb_BLE_Client_R_CHARGE(void* handle)
+{
+	BLE_Client_Rx_t* target = handle;
+	DEBUG_LOG("!!!!!!!!cb_BLE_Client_R_CHARGE\n");
+	app_send_charge();
+	BLE_Host_Tx_Send(0,BLE_CHARGE,target->pDat,target->datLen);
+}
+
+void cb_BLE_Host_R_CHARGE(void* handle)
+{
+	BLE_Host_Rx_t* target = handle;
+	BLE_Client_Tx_Send(0,BLE_CHARGE,target->pDat,target->datLen);
+	DEBUG_LOG("cb_BLE_Host_R_CHARGE:%d,%d,%d\n",target->pDat[0],target->pDat[1],target->datLen);
+}
+
+static BLE_Host_Tx_t mBLE_Host_BLE_CHAR_VOL_R = {
+	.n = 15,
+	.t = 200,
+	.cb = 0,
+};
+
+static BLE_Client_Tx_t mBLE_Client_BLE_CHAR_VOL_R = {
+	.n = 15,
+	.t = 200,
+	.cb = 0,
+};
+
+static void app_charge_Vol_Charge_Send(void)
+{
+	uint8_t buf[10];
+	uint8_t L = 0;
+	buf[L++] = GetBatteryPersent();
+	buf[L++] = app_charge_state;
+  if(mFlash.isHost)BLE_Host_Tx_Send(0,BLE_CHAR_VOL,buf,L);
+	else BLE_Client_Tx_Send(0,BLE_CHAR_VOL,buf,L);
+}
+
+static uint8_t OtherShoesVol = 0;
+static uint8_t otherShoes_charge = BLE_CHARGE_PULLOUT;
+static void cb_BLE_R_CHAR_VOL(void* handle)
+{	
+	UART0_Rx_t* target = handle;
+	OtherShoesVol = target->pDat[0];
+	otherShoes_charge = target->pDat[1];
+	if(!mFlash.isHost)app_charge_Vol_Charge_Send();
+//	DEBUG_LOG("OtherShoesVol=%d\n",OtherShoesVol);
+}
+
+static void cb_BLE_Host_R_CHAR_VOL(void* handle)
+{	
+	UART0_Rx_t* target = handle;
+	OtherShoesVol = target->pDat[0];
+	otherShoes_charge = target->pDat[1];
+//	DEBUG_LOG("OtherShoesVol=%d\n",OtherShoesVol);
+}
+
+static void app_charge_Process(void)
+{
+	static uint8_t client_connect =0;
+	static uint8_t blink_state =0;
+	
+	if(slave_isconnect() && !client_connect){
+		app_send_charge();
+		uint8_t data =0;
+		BLE_Host_Tx_Send(0,BLE_CHARGE,&data,1);
+	}
+	else if(!slave_isconnect() && client_connect && (!mFlash.isHost)){
+		OtherShoesVol = 0;
+    otherShoes_charge =0;
+	}
+	
+	if(client_connect != slave_isconnect())client_connect = slave_isconnect();
+	
+	uint32_t ch = nrf_gpio_pin_read(PIN_CHARGING);//		DEBUG_LOG("charge state:%d\n",ch);
+	if(mFlash.isHost)app_charge_Vol_Charge_Send(); //共享充电电量和充电状态
+	
+	if(!ch){	//没充电
+		if(app_charge_state!=BLE_CHARGE_PULLOUT){ DEBUG_LOG("charge out...\n");
+			app_charge_state = BLE_CHARGE_PULLOUT;
+			Process_SetHoldOn(app_charge_Process,0);
+			LED_Stop(LED_CHARGE);
+			app_send_charge();
+			OtherShoesVol = 0;
+      otherShoes_charge =0;
+			blink_state =0;
+		}
+		return;
+	}
+	
+	if(GetBatteryPersent() >=100 ){	//左右鞋都充满电的情况下
+		if(app_charge_state!=BLE_CHARGE_DONE){ DEBUG_LOG("charge done:%d...\n",OtherShoesVol);
+			 app_charge_state = BLE_CHARGE_DONE;
+				app_send_charge();
+				Process_SetHoldOn(app_charge_Process,1);
+		}
+	}else{	//正在充电
+		if(app_charge_state!=BLE_CHARGE_INSERT){ DEBUG_LOG("charge in...\n");
+			app_charge_state = BLE_CHARGE_INSERT;
+			app_send_charge();
+			Process_SetHoldOn(app_charge_Process,1);
+		}
+	}
+	
+	if((otherShoes_charge == BLE_CHARGE_INSERT || otherShoes_charge == BLE_CHARGE_DONE)){
+		if(OtherShoesVol >=100 ){
+			if(1 != blink_state){blink_state = 1;
+				LED_Start(LED_CHARGE,COLOR_GREEN);
+			}
+		}
+		else {
+			if(2 != blink_state){blink_state = 2;
+				LED_Start(LED_CHARGE,COLOR_ORANGE);
+			}
+		}
+	}
+	else{
+		 if(0 != blink_state){blink_state = 0;
+				LED_Stop(LED_CHARGE);
+		 }
+	}
+}
+
+static void app_charge_monitor_battery_charge_data_process(void)
+{
+	#define BATTERY_VOL_THRESHOLD_MIN											2500		//2.5V
+	#define BATTERY_VOL_THRESHOLD_MAX											4000		//4V
+	#define CHARGE_VOL_THRESHOLD													80			//充电前和充电期间的充电电压变化值,单位mv
+	
+	//监测电池和充电数据
+	int16_t						bat_vol = 0;
+	int16_t						charge_vol = 0;
+	int16_t						charge_threshold = 0;
+	uint32_t 					ch = nrf_gpio_pin_read(PIN_CHARGING);
+	static uint32_t 	charge_cycle = 50;
+	static int16_t		before_charge_vol = 0;		//充电前的电压值
+	static int16_t		charge_vol_max = 0;				//充电期间最大的电压值
+	
+	if(!ch)//没充电
+	{		
+		charge_vol = ADC_RESULT_IN_MILLI_VOLTS(ADC_GetValue(PIN_ADC_CHARGMEASURE_CHANNEL));
+		before_charge_vol = before_charge_vol > charge_vol ? charge_vol : before_charge_vol;
+		charge_vol_max = 0;
+		charge_cycle = 50;
+	}else	//充电
+	{			
+		/* 过筛50轮 */
+		if(charge_cycle != 0){
+			charge_vol = ADC_RESULT_IN_MILLI_VOLTS(ADC_GetValue(PIN_ADC_CHARGMEASURE_CHANNEL));
+			charge_vol_max = charge_vol_max < charge_vol ? charge_vol : charge_vol_max;
+			charge_cycle--;
+			return;
+		}
+		charge_vol = ADC_RESULT_IN_MILLI_VOLTS(ADC_GetValue(PIN_ADC_CHARGMEASURE_CHANNEL));
+		charge_vol_max = charge_vol_max < charge_vol ? charge_vol : charge_vol_max;		
+		bat_vol    = ADC_RESULT_IN_MILLI_VOLTS(ADC_GetValue(PIN_ADC_BAT_CHANNEL))*5/3;
+		
+		//当电池电量没满,充电(经测试,电量没满的充电电压跟电池电压有关,最小充电电压100+mv)
+		charge_threshold = 	charge_vol_max - before_charge_vol;	//充电前和充电期间的充电电压变化值
+//		DEBUG_LOG("charge_threshold:%d,%d,%d,%d\n",charge_vol_max,before_charge_vol,charge_threshold,CHARGE_VOL_THRESHOLD);
+//		if(charge_threshold < CHARGE_VOL_THRESHOLD && bat_vol < BATTERY_VOL_THRESHOLD_MAX)
+//		{		
+//			Except_SetExceptype(EXCEPT_DATA_CHARGE);
+//			Except_TxError(EXCEPT_DATA_CHARGE,"except_charging_chip");
+//		}
+//		else
+//		{
+//			Except_ClearExceptype(EXCEPT_DATA_CHARGE);
+//		}
+		
+//		//电池小于2.5V或充电电压变化小于阈值且电池电压大于4V
+//		if(bat_vol <= BATTERY_VOL_THRESHOLD_MIN || (charge_threshold < CHARGE_VOL_THRESHOLD && bat_vol > BATTERY_VOL_THRESHOLD_MAX))
+//		{
+//			Except_SetExceptype(EXCEPT_DATA_BATTERY);
+//			Except_TxError(EXCEPT_DATA_BATTERY,"except_battery");
+//		}
+//		else
+//		{
+//			Except_ClearExceptype(EXCEPT_DATA_BATTERY);
+//		}
+	}
+}
+
+void app_charge_Init(void)
+{
+	nrf_gpio_cfg_input(PIN_CHARGING,NRF_GPIO_PIN_NOPULL); 
+	
+	BLE_Client_Rx_Regist(BLE_CHAR_VOL,cb_BLE_R_CHAR_VOL);
+	BLE_Host_Rx_Regist(BLE_CHAR_VOL,cb_BLE_Host_R_CHAR_VOL);
+	
+	BLE_Client_Rx_Regist(BLE_CHARGE,cb_BLE_Client_R_CHARGE);
+	BLE_Host_Rx_Regist(BLE_CHARGE,cb_BLE_Host_R_CHARGE);
+	Process_Start(500,"app_charge",app_charge_Process);
+	app_charge_Process();
+	
+	Process_Start(10,"app_charge_monitor_battery_charge_data_process",app_charge_monitor_battery_charge_data_process);
+}
+
+

+ 207 - 0
shoe_mcu2.2.1_new_v2/app/app_charge/app_charge - 副本.c

@@ -0,0 +1,207 @@
+#include "usr_config.h"
+#include "bsp_time.h"
+#include "system.h"
+#include "hal_led.h"
+#include "nrf_gpio.h"
+#include "hal_ble_client.h"
+#include "hal_ble_host.h"
+#include "app_charge.h"
+#include "app_flash.h"
+#include "hal_battery.h"
+#include "hal_ble_uart0.h"
+#include "ble_comm.h"
+#include "hal_ble_uart0.h"
+
+/************************ 函数声明 ***********************************/
+void app_charge_Process(void);
+
+/************************ 变量 ***********************************/
+static uint8_t app_charge_state = BLE_CHARGE_PULLOUT;
+
+/********************************************************/
+uint8_t app_charge_Getstate(void)
+{
+	return app_charge_state;
+}
+
+void send_charge(void)
+{
+	static uint8_t sbuf[2];
+	uint8_t L = 0;
+	if(mFlash.isHost) sbuf[L++] = 0;
+	else sbuf[L++] = 1;
+	sbuf[L++] = app_charge_state;
+	BLE_Client_Tx_Send(0,BLE_CHARGE,sbuf,L);
+}
+
+void cb_BLE_Client_R_CHARGE(void* handle)
+{
+	BLE_Client_Rx_t* target = handle;
+	send_charge();
+	BLE_Host_Tx_Send(0,BLE_CHARGE,target->pDat,target->datLen);
+}
+
+void cb_BLE_Host_R_CHARGE(void* handle)
+{
+	BLE_Host_Rx_t* target = handle;
+	BLE_Client_Tx_Send(0,BLE_CHARGE,target->pDat,target->datLen);
+//	DEBUG_LOG("cb_BLE_Host_R_CHARGE:%d,%d,%d\n",target->pDat[0],target->pDat[1],target->datLen);
+}
+
+void cb_BLE_Client_T_CHARGE(void* handle) 
+{
+	DEBUG_LOG("cb_BLE_Client_T_CHARGE\n");
+}
+
+static void app_charge_Vol_Charge_Send(BLE_CMD_n cmd)
+{
+	uint8_t buf[32];
+	uint8_t L = 0;
+	
+	buf[L++] = GetBatteryPersent();
+	buf[L++] = app_charge_state;
+	if(mFlash.isHost)BLE_Host_Tx_Send(0,cmd,buf,L);
+	else BLE_Client_Tx_Send(0,cmd,buf,L);
+}
+
+static uint8_t OtherShoesVol = 0;
+static uint8_t otherShoes_charge =0;
+static void cb_BLE_R_CHAR_VOL_CHARGE(void* handle)
+{	
+	UART0_Rx_t* target = handle;
+	OtherShoesVol = target->pDat[0];
+	otherShoes_charge = target->pDat[1];
+//	DEBUG_LOG("OtherShoesVol=%d\n",OtherShoesVol);
+}
+
+static void app_charge_Process(void)
+{
+	uint8_t client_connect =0;
+	static uint8_t ResponseFlag =0;
+	
+	app_charge_Vol_Charge_Send(BLE_CHAR_VOL); //共享充电电量和充电状态
+	
+	uint32_t ch = nrf_gpio_pin_read(PIN_CHARGING);
+
+	client_connect = slave_isconnect();
+//		DEBUG_LOG("charge state:%d\n",ch);
+	if(!ch){	//没充电
+		if(app_charge_state!=BLE_CHARGE_PULLOUT){ DEBUG_LOG("charge out...\n");
+			app_charge_state = BLE_CHARGE_PULLOUT;
+			Process_SetHoldOn(app_charge_Process,0);
+			LED_Stop(LED_CHARGE);
+			if(client_connect){
+				ResponseFlag = 0;
+				send_charge();
+			}
+			else ResponseFlag =1;
+		}
+		
+		return;
+	}
+	
+	if((otherShoes_charge == BLE_CHARGE_INSERT || otherShoes_charge == BLE_CHARGE_DONE) && 
+		GetBatteryPersent() >=100 && 
+	  OtherShoesVol >=100 ){	//左右鞋都充满电的情况下
+			if(app_charge_state!=BLE_CHARGE_DONE){ DEBUG_LOG("charge done:%d...\n",OtherShoesVol);
+				app_charge_state = BLE_CHARGE_DONE;
+				Process_SetHoldOn(app_charge_Process,1);
+				LED_Start(LED_CHARGE,COLOR_GREEN);
+				send_charge();
+		}
+	}else{	//正在充电
+		if(app_charge_state!=BLE_CHARGE_INSERT){ DEBUG_LOG("charge in...\n");
+			app_charge_state = BLE_CHARGE_INSERT;
+			Process_SetHoldOn(app_charge_Process,1);
+			LED_Start(LED_CHARGE,COLOR_ORANGE);
+			if(client_connect){
+				send_charge();
+				ResponseFlag = 0;
+			}
+			else ResponseFlag =1;
+		}
+	}
+	if(client_connect && ResponseFlag){
+		ResponseFlag =0;
+		send_charge();
+	}
+}
+
+static void app_charge_monitor_battery_charge_data_process(void)
+{
+	#define BATTERY_VOL_THRESHOLD_MIN											2500		//2.5V
+	#define BATTERY_VOL_THRESHOLD_MAX											4000		//4V
+	#define CHARGE_VOL_THRESHOLD													80			//充电前和充电期间的充电电压变化值,单位mv
+	
+	//监测电池和充电数据
+	int16_t						bat_vol;
+	int16_t						charge_vol;
+	int16_t						charge_threshold;
+	uint32_t 					ch = nrf_gpio_pin_read(PIN_CHARGING);
+	static uint32_t 	charge_cycle = 50;
+	static int16_t		before_charge_vol;		//充电前的电压值
+	static int16_t		charge_vol_max;				//充电期间最大的电压值
+	
+	if(!ch)//没充电
+	{		
+		charge_vol = ADC_RESULT_IN_MILLI_VOLTS(ADC_GetValue(PIN_ADC_CHARGMEASURE_CHANNEL));
+		before_charge_vol = before_charge_vol > charge_vol ? charge_vol : before_charge_vol;
+		charge_vol_max = 0;
+		charge_cycle = 50;
+	}else	//充电
+	{			
+		/* 过筛50轮 */
+		if(charge_cycle != 0){
+			charge_vol = ADC_RESULT_IN_MILLI_VOLTS(ADC_GetValue(PIN_ADC_CHARGMEASURE_CHANNEL));
+			charge_vol_max = charge_vol_max < charge_vol ? charge_vol : charge_vol_max;
+			charge_cycle--;
+			return;
+		}
+		charge_vol = ADC_RESULT_IN_MILLI_VOLTS(ADC_GetValue(PIN_ADC_CHARGMEASURE_CHANNEL));
+		charge_vol_max = charge_vol_max < charge_vol ? charge_vol : charge_vol_max;		
+		bat_vol    = ADC_RESULT_IN_MILLI_VOLTS(ADC_GetValue(PIN_ADC_BAT_CHANNEL))*5/3;
+		
+		//当电池电量没满,充电(经测试,电量没满的充电电压跟电池电压有关,最小充电电压100+mv)
+		charge_threshold = 	charge_vol_max - before_charge_vol;	//充电前和充电期间的充电电压变化值
+//		DEBUG_LOG("charge_threshold:%d,%d,%d,bat:%d\n",charge_threshold,ob_monitor.charge_vol_max,ob_monitor.before_charge_vol,bat_vol);
+		if(charge_threshold < CHARGE_VOL_THRESHOLD)
+		{		
+			Except_SetExceptype(EXCEPT_DATA_CHARGE);
+			Except_TxError(EXCEPT_DATA_CHARGE,"except_charging_chip");
+		}
+		else
+		{
+			Except_ClearExceptype(EXCEPT_DATA_CHARGE);
+		}
+		
+		//电池小于2.5V或充电电压变化小于阈值且电池电压大于4V
+		if(bat_vol <= BATTERY_VOL_THRESHOLD_MIN || (charge_threshold < CHARGE_VOL_THRESHOLD && bat_vol > BATTERY_VOL_THRESHOLD_MAX))
+		{
+			Except_SetExceptype(EXCEPT_DATA_BATTERY);
+			Except_TxError(EXCEPT_DATA_BATTERY,"except_battery");
+		}
+		else
+		{
+			Except_ClearExceptype(EXCEPT_DATA_BATTERY);
+		}
+	}
+}
+
+void app_charge_Init(void)
+{
+	nrf_gpio_cfg_input(PIN_CHARGING,NRF_GPIO_PIN_NOPULL); 
+
+	if(mFlash.isHost) 
+		BLE_Host_Rx_Regist(BLE_CHAR_VOL,cb_BLE_R_CHAR_VOL_CHARGE);
+	else 
+		BLE_Client_Rx_Regist(BLE_CHAR_VOL,cb_BLE_R_CHAR_VOL_CHARGE);
+	
+	BLE_Client_Rx_Regist(BLE_CHARGE,cb_BLE_Client_R_CHARGE);
+	BLE_Host_Rx_Regist(BLE_CHARGE,cb_BLE_Host_R_CHARGE);
+	Process_Start(1000,"app_charge",app_charge_Process);
+	app_charge_Process();
+	
+	Process_Start(10,"app_charge_monitor_battery_charge_data_process",app_charge_monitor_battery_charge_data_process);
+}
+
+

+ 205 - 0
shoe_mcu2.2.1_new_v2/app/app_charge/app_charge.c

@@ -0,0 +1,205 @@
+#include "usr_config.h"
+#include "bsp_time.h"
+#include "system.h"
+#include "hal_led.h"
+#include "nrf_gpio.h"
+#include "hal_ble_client.h"
+#include "hal_ble_host.h"
+#include "app_charge.h"
+#include "app_flash.h"
+#include "hal_battery.h"
+#include "ble_comm.h"
+#include "hal_ble_uart0.h"
+
+/************************ 函数声明 ***********************************/
+
+/************************ 变量 ***********************************/
+static uint8_t app_charge_state = BLE_CHARGE_PULLOUT;
+
+/********************************************************/
+uint8_t app_charge_Getstate(void)
+{
+	return app_charge_state;
+}
+
+static void app_send_charge(void)
+{
+	uint8_t sbuf[2]={0};
+	uint8_t L = 0;
+	if(mFlash.isHost) sbuf[L++] = 0;
+	else sbuf[L++] = 1;
+	sbuf[L++] = app_charge_state;
+	BLE_Client_Tx_Send(0,BLE_CHARGE,sbuf,L);
+}
+
+void cb_BLE_Client_R_CHARGE(void* handle)
+{
+	BLE_Client_Rx_t* target = handle;
+	DEBUG_LOG("!!!!!!!!cb_BLE_Client_R_CHARGE\n");
+	app_send_charge();
+	BLE_Host_Tx_Send(0,BLE_CHARGE,target->pDat,target->datLen);
+}
+
+void cb_BLE_Host_R_CHARGE(void* handle)
+{
+	BLE_Host_Rx_t* target = handle;
+	BLE_Client_Tx_Send(0,BLE_CHARGE,target->pDat,target->datLen);
+//	DEBUG_LOG("cb_BLE_Host_R_CHARGE:%d,%d,%d\n",target->pDat[0],target->pDat[1],target->datLen);
+}
+
+static void app_charge_Vol_Charge_Send(void)
+{
+	uint8_t buf[10]={0};
+	uint8_t L = 0;
+	buf[L++] = GetBatteryPersent();
+	buf[L++] = app_charge_state;
+  if(mFlash.isHost)BLE_Host_Tx_Send(0,BLE_CHAR_VOL,buf,L);
+	else BLE_Client_Tx_Send(0,BLE_CHAR_VOL,buf,L);
+}
+
+static uint8_t OtherShoesVol = 0;
+static uint8_t otherShoes_charge = BLE_CHARGE_PULLOUT;
+static void cb_BLE_R_CHAR_VOL(void* handle)
+{	
+	UART0_Rx_t* target = handle;
+	OtherShoesVol = target->pDat[0];
+	otherShoes_charge = target->pDat[1];
+	if(!mFlash.isHost)app_charge_Vol_Charge_Send();
+//	DEBUG_LOG("OtherShoesVol=%d\n",OtherShoesVol);
+}
+
+static void cb_BLE_Host_R_CHAR_VOL(void* handle)
+{	
+	UART0_Rx_t* target = handle;
+	OtherShoesVol = target->pDat[0];
+	otherShoes_charge = target->pDat[1];
+//	DEBUG_LOG("OtherShoesVol=%d\n",OtherShoesVol);
+}
+
+static void app_charge_Process(void)
+{
+	static uint8_t client_connect =0;
+	
+	if(slave_isconnect() && !client_connect){
+		app_send_charge();
+		uint8_t data =0;
+		BLE_Host_Tx_Send(0,BLE_CHARGE,&data,1);
+	}
+	else if(!slave_isconnect() && client_connect && (!mFlash.isHost)){
+		OtherShoesVol = 0;
+    otherShoes_charge =0;
+	}
+	
+	if(client_connect != slave_isconnect())client_connect = slave_isconnect();
+	
+	uint32_t ch = nrf_gpio_pin_read(PIN_CHARGING);//		DEBUG_LOG("charge state:%d\n",ch);
+	
+	if(!ch){	//没充电
+		if(app_charge_state!=BLE_CHARGE_PULLOUT){ DEBUG_LOG("charge out...\n");
+			app_charge_state = BLE_CHARGE_PULLOUT;
+			Process_SetHoldOn(app_charge_Process,0);
+			LED_Stop(LED_CHARGE);
+			app_send_charge();
+			OtherShoesVol = 0;
+      otherShoes_charge =0;
+		}
+		return;
+	}
+	
+	if(mFlash.isHost)app_charge_Vol_Charge_Send(); //共享充电电量和充电状态
+	if((otherShoes_charge == BLE_CHARGE_INSERT || otherShoes_charge == BLE_CHARGE_DONE) && 
+		GetBatteryPersent() >=100 && 
+	  OtherShoesVol >=100 ){	//左右鞋都充满电的情况下
+			if(app_charge_state!=BLE_CHARGE_DONE){ DEBUG_LOG("charge done:%d...\n",OtherShoesVol);
+				app_charge_state = BLE_CHARGE_DONE;
+				Process_SetHoldOn(app_charge_Process,1);
+				LED_Start(LED_CHARGE,COLOR_GREEN);
+				app_send_charge();
+		}
+	}else{	//正在充电
+		if(app_charge_state!=BLE_CHARGE_INSERT){ DEBUG_LOG("charge in...\n");
+			app_charge_state = BLE_CHARGE_INSERT;
+			Process_SetHoldOn(app_charge_Process,1);
+			LED_Start(LED_CHARGE,COLOR_ORANGE);
+			app_send_charge();
+		}
+	}
+
+}
+
+static void app_charge_monitor_battery_charge_data_process(void)
+{
+	#define BATTERY_VOL_THRESHOLD_MIN											2500		//2.5V
+	#define BATTERY_VOL_THRESHOLD_MAX											4000		//4V
+	#define CHARGE_VOL_THRESHOLD													80			//充电前和充电期间的充电电压变化值,单位mv
+	
+	//监测电池和充电数据
+	int16_t						bat_vol = 0;
+	int16_t						charge_vol = 0;
+	int16_t						charge_threshold = 0;
+	uint32_t 					ch = nrf_gpio_pin_read(PIN_CHARGING);
+	static uint32_t 	charge_cycle = 50;
+	static int16_t		before_charge_vol = 0;		//充电前的电压值
+	static int16_t		charge_vol_max = 0;				//充电期间最大的电压值
+	
+	if(!ch)//没充电
+	{		
+		charge_vol = ADC_RESULT_IN_MILLI_VOLTS(ADC_GetValue(PIN_ADC_CHARGMEASURE_CHANNEL));
+		before_charge_vol = before_charge_vol > charge_vol ? charge_vol : before_charge_vol;
+		charge_vol_max = 0;
+		charge_cycle = 50;
+	}else	//充电
+	{			
+		/* 过筛50轮 */
+		if(charge_cycle != 0){
+			charge_vol = ADC_RESULT_IN_MILLI_VOLTS(ADC_GetValue(PIN_ADC_CHARGMEASURE_CHANNEL));
+			charge_vol_max = charge_vol_max < charge_vol ? charge_vol : charge_vol_max;
+			charge_cycle--;
+			return;
+		}
+		charge_vol = ADC_RESULT_IN_MILLI_VOLTS(ADC_GetValue(PIN_ADC_CHARGMEASURE_CHANNEL));
+		charge_vol_max = charge_vol_max < charge_vol ? charge_vol : charge_vol_max;		
+		bat_vol    = ADC_RESULT_IN_MILLI_VOLTS(ADC_GetValue(PIN_ADC_BAT_CHANNEL))*5/3;
+		
+		//当电池电量没满,充电(经测试,电量没满的充电电压跟电池电压有关,最小充电电压100+mv)
+		charge_threshold = 	charge_vol_max - before_charge_vol;	//充电前和充电期间的充电电压变化值
+//		DEBUG_LOG("charge_threshold:%d,%d,%d,%d\n",charge_vol_max,before_charge_vol,charge_threshold,CHARGE_VOL_THRESHOLD);
+//		if(charge_threshold < CHARGE_VOL_THRESHOLD && bat_vol < BATTERY_VOL_THRESHOLD_MAX)
+//		{		
+//			Except_SetExceptype(EXCEPT_DATA_CHARGE);
+//			Except_TxError(EXCEPT_DATA_CHARGE,"except_charging_chip");
+//		}
+//		else
+//		{
+//			Except_ClearExceptype(EXCEPT_DATA_CHARGE);
+//		}
+		
+//		//电池小于2.5V或充电电压变化小于阈值且电池电压大于4V
+//		if(bat_vol <= BATTERY_VOL_THRESHOLD_MIN || (charge_threshold < CHARGE_VOL_THRESHOLD && bat_vol > BATTERY_VOL_THRESHOLD_MAX))
+//		{
+//			Except_SetExceptype(EXCEPT_DATA_BATTERY);
+//			Except_TxError(EXCEPT_DATA_BATTERY,"except_battery");
+//		}
+//		else
+//		{
+//			Except_ClearExceptype(EXCEPT_DATA_BATTERY);
+//		}
+	}
+}
+
+void app_charge_Init(void)
+{
+	nrf_gpio_cfg_input(PIN_CHARGING,NRF_GPIO_PIN_NOPULL); 
+	
+	BLE_Client_Rx_Regist(BLE_CHAR_VOL,cb_BLE_R_CHAR_VOL);
+	BLE_Host_Rx_Regist(BLE_CHAR_VOL,cb_BLE_Host_R_CHAR_VOL);
+	
+	BLE_Client_Rx_Regist(BLE_CHARGE,cb_BLE_Client_R_CHARGE);
+	BLE_Host_Rx_Regist(BLE_CHARGE,cb_BLE_Host_R_CHARGE);
+	Process_Start(1000,"app_charge",app_charge_Process);
+	app_charge_Process();
+	
+	Process_Start(10,"app_charge_monitor_battery_charge_data_process",app_charge_monitor_battery_charge_data_process);
+}
+
+

+ 15 - 0
shoe_mcu2.2.1_new_v2/app/app_charge/app_charge.h

@@ -0,0 +1,15 @@
+#ifndef __app_charge_h__
+#define __app_charge_h__
+#include <stdbool.h>
+#include <stdint.h>
+#include <string.h>
+#include "sdk_common.h"
+#include "SEGGER_RTT.h"
+#include "usr_config.h"
+
+void app_charge_Init(void);
+uint8_t app_charge_Getstate(void);
+
+#endif
+
+

+ 215 - 0
shoe_mcu2.2.1_new_v2/app/app_client.c

@@ -0,0 +1,215 @@
+#include "system.h"
+#include "app_client.h"
+#include "hal_ble_client.h"
+#include "hal_ble_host.h"
+#include "bsp_time.h"
+#include "hal_led.h"
+#include "ble_gap.h"
+#include "app_host.h"
+#include "app_flash.h"
+#include "app_client_step.h"
+#include "hal_battery.h"
+#include "ble_comm.h"
+#include "app_game.h"
+#include "app_step.h"
+
+void app_client_DataUpdate_Send(void)
+{
+	//>> 1(设备数据)
+	//<< 1(子命令): 左鞋电量(1)+左鞋温度(1)+左鞋压力(4)+左鞋步数(4)+右鞋电量(1)+右鞋温度(1)+右鞋压力(4)+右鞋步数(4)
+	uint8_t buf[32];
+	uint8_t L=0;
+	int32_t temperature;
+ 
+	sd_temp_get(&temperature);
+	temperature = temperature>>2; 
+
+	//子命令
+	buf[L++] = BLE_UPDATE_DATA;
+	//左鞋
+	buf[L++] = GetBatteryPersent();
+	buf[L++] = (uint8_t)temperature;
+  //压力数据
+  buf[L++] = 0;
+	buf[L++] = 0;
+	buf[L++] = 0;
+	buf[L++] = 0;
+	
+	buf[L++] = (uint8_t)(mFlash.mStep.stepCur[0]>>24);
+	buf[L++] = (uint8_t)(mFlash.mStep.stepCur[0]>>16);
+	buf[L++] = (uint8_t)(mFlash.mStep.stepCur[0]>>8);
+	buf[L++] = (uint8_t)(mFlash.mStep.stepCur[0]>>0);
+	//右鞋
+	buf[L++] = app_host_GetVol_R();
+	buf[L++] = app_host_GetTemp_R();
+	buf[L++] = (uint8_t)(app_host_GetPress_R()>>24);
+	buf[L++] = (uint8_t)(app_host_GetPress_R()>>16);
+	buf[L++] = (uint8_t)(app_host_GetPress_R()>>8);
+	buf[L++] = (uint8_t)(app_host_GetPress_R()>>0);
+	buf[L++] = (uint8_t)(mFlash.mStep.stepCur[1]>>24);
+	buf[L++] = (uint8_t)(mFlash.mStep.stepCur[1]>>16);
+	buf[L++] = (uint8_t)(mFlash.mStep.stepCur[1]>>8);
+	buf[L++] = (uint8_t)(mFlash.mStep.stepCur[1]>>0);
+	
+	int16_t left_adc = hal_GetBatttery_Adc();
+	buf[L++] = (uint8_t)(left_adc>>8);
+	buf[L++] = (uint8_t)(left_adc);
+	
+	buf[L++] = (uint8_t)(app_host_GetVolAdc_R()>>8);
+	buf[L++] = (uint8_t)(app_host_GetVolAdc_R());
+	
+	BLE_Client_Tx_Send(0,BLE_UPDATE,buf,L);
+}
+
+void app_client_infomation_Send_defineName(uint8_t name[],uint8_t lenth)
+{
+	//<< 0(设备基本信息): 设备型号(64)+左鞋蓝牙地址(6)+硬件版本(2)+软件版本(2)+左鞋蓝牙地址(6)+硬件版本(6)+软件版本(2)
+	ble_gap_addr_t mAddr;
+	uint32_t err_code;
+	uint8_t buf[128];
+	uint8_t L = SHOES_NAME_LEN+1;
+	
+	memset(buf,0,sizeof(buf));
+	//子命令
+	buf[0] = BLE_UPDATE_BASEINFO;
+	//设备名称
+	for(int i=0;i<lenth;i++){
+		buf[i+1] = name[i];
+	}
+	//MAC 地址
+	err_code = sd_ble_gap_addr_get(&mAddr); APP_ERROR_CHECK(err_code);
+	//DEBUG_LOG("mac addr:");for(int i=0;i<6;i++){DEBUG_LOG("%02X ",mAddr.addr[i]);}DEBUG_LOG("\n");
+	for(int i=0;i<6;i++){
+		buf[L++] = mAddr.addr[5-i];
+	} 
+	//硬件版本
+	buf[L++] = (uint8_t)((uint32_t)HARDWARE_VERSION>>24);
+	buf[L++] = (uint8_t)((uint32_t)HARDWARE_VERSION>>16);
+	buf[L++] = (uint8_t)((uint32_t)HARDWARE_VERSION>>8);
+	buf[L++] = (uint8_t)((uint32_t)HARDWARE_VERSION>>0);
+	//软件版本
+	buf[L++] = (uint8_t)(SOFTWARE_VERSION>>8);
+	buf[L++] = (uint8_t)(SOFTWARE_VERSION>>0);
+	
+	//右鞋mac地址
+	for(int i=0;i<6;i++) buf[L++] = mFlash.mClient.macAddr[i];
+	
+	//右鞋硬件版本
+	buf[L++] = (uint8_t)((uint32_t)mFlash.mClient.hardVersion>>24);
+	buf[L++] = (uint8_t)((uint32_t)mFlash.mClient.hardVersion>>16);
+	buf[L++] = (uint8_t)((uint32_t)mFlash.mClient.hardVersion>>8);
+	buf[L++] = (uint8_t)((uint32_t)mFlash.mClient.hardVersion>>0);
+	//右鞋软件版本
+	buf[L++] = (uint8_t)(mFlash.mClient.sotfVersion>>8);
+	buf[L++] = (uint8_t)(mFlash.mClient.sotfVersion>>0);
+	
+	BLE_Client_Tx_Send(0,BLE_UPDATE,buf,L);
+}
+
+void app_client_infomation_Send(void)
+{
+	//<< 0(设备基本信息): 设备型号(64)+左鞋蓝牙地址(6)+硬件版本(2)+软件版本(2)+左鞋蓝牙地址(6)+硬件版本(6)+软件版本(2)
+	ble_gap_addr_t mAddr;
+	uint32_t err_code;
+	uint8_t buf[128];
+	uint8_t L = SHOES_NAME_LEN+1;
+	
+	memset(buf,0,sizeof(buf));
+	//子命令
+	buf[0] = BLE_UPDATE_BASEINFO;
+	//设备名称
+	for(int i=0;i<sizeof(SHOES_NAME);i++){
+		buf[i+1] = SHOES_NAME[i];
+	}
+	//MAC 地址
+	err_code = sd_ble_gap_addr_get(&mAddr); APP_ERROR_CHECK(err_code);
+//	DEBUG_LOG("mac addr:");for(int i=0;i<6;i++){DEBUG_LOG("%02X ",mAddr.addr[i]);}DEBUG_LOG("\n");
+	for(int i=0;i<6;i++){
+		buf[L++] = mAddr.addr[5-i];
+	}
+	//硬件版本
+	buf[L++] = (uint8_t)((uint32_t)HARDWARE_VERSION>>24);
+	buf[L++] = (uint8_t)((uint32_t)HARDWARE_VERSION>>16);
+	buf[L++] = (uint8_t)((uint32_t)HARDWARE_VERSION>>8);
+	buf[L++] = (uint8_t)((uint32_t)HARDWARE_VERSION>>0);
+	//软件版本
+	buf[L++] = (uint8_t)(SOFTWARE_VERSION>>8);
+	buf[L++] = (uint8_t)(SOFTWARE_VERSION>>0);
+	
+	//右鞋mac地址
+	for(int i=0;i<6;i++) buf[L++] = mFlash.mClient.macAddr[i];
+//	DEBUG_LOG("mac addr:");for(int i=0;i<6;i++){DEBUG_LOG("%02X ",mFlash.mClient.macAddr[i]);}DEBUG_LOG("\n");
+	//右鞋硬件版本
+	buf[L++] = (uint8_t)((uint32_t)mFlash.mClient.hardVersion>>24);
+	buf[L++] = (uint8_t)((uint32_t)mFlash.mClient.hardVersion>>16);
+	buf[L++] = (uint8_t)((uint32_t)mFlash.mClient.hardVersion>>8);
+	buf[L++] = (uint8_t)((uint32_t)mFlash.mClient.hardVersion>>0);
+	//右鞋软件版本
+	//右鞋软件版本
+	buf[L++] = (uint8_t)(mFlash.mClient.sotfVersion>>8);
+	buf[L++] = (uint8_t)(mFlash.mClient.sotfVersion>>0);
+	
+	BLE_Client_Tx_Send(0,BLE_UPDATE,buf,L);
+}
+
+//>> 0xA1: 查询
+void cb_BLE_Client_R_UPDATE(void* handle)
+{
+	BLE_Client_Rx_t *target = handle;
+	uint8_t _cmd = target->pDat[0];
+	switch(_cmd){
+		case BLE_UPDATE_BASEINFO:{
+			//>> 0(设备基本信息): 开始时间ms(8)
+			//<< 0(子命令): 设备型号(64)+左鞋蓝牙地址(6)+硬件版本(2)+软件版本(2)+右鞋蓝牙地址(6)+硬件版本(6)+软件版本(2)
+			//>> AA 06 F9 A1 00 4A
+			//<< AA 55 AA A1 00 53 4D 41 52 54 20 53 48 4F 45 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 C1 EB D0 E3 87 47 01 00 01 00 00 00 00 00 00 4F
+			if(1 == mFlash.isHost){
+				 app_host_GetClientInfo();
+			}
+      else app_client_infomation_Send();
+//			DEBUG_LOG("!!!!!!!!!!!!!!!=======>app_client_infomation_Send\n");
+			break;}
+		case BLE_UPDATE_DATA:{
+			//>> 1(设备数据)
+			//<< 1(子命令): 左鞋电量(1)+左鞋温度(1)+左鞋压力(4)+左鞋步数(4)+右鞋电量(1)+右鞋温度(1)+右鞋压力(4)+右鞋步数(4)
+			
+			if(1 == mFlash.isHost){
+				 app_host_GetClientData(20);
+			}
+      else app_client_DataUpdate_Send();
+			break;}
+		case BLE_UPDATE_STEPNUM:{
+			//>> 2(查询步数): 包序号[0全部](2)
+			//<< 2(查询步数): +开始时间ms(8)+包的数量(2)+包序号(2)+每小时步数(4)+...
+			if(!app_step_Real_Get())app_client_SendStep(target);
+			break;}
+		case BLE_UPDATE_STEPNUM_CLERA:{
+			//>> 3(删除步数): 开始时间ms(8)+距离上一个整点的分钟数(1)
+			//<< 3(删除步数): 开始时间ms(8)+距离上一个整点的分钟数(1)
+			BLE_Client_Tx_Send(0,BLE_UPDATE,target->pDat,target->datLen);
+			app_client_DeleteStep(target);
+			break;}
+		default:break;
+	}
+}
+
+static void app_client_Process(void)
+{
+	static uint8_t cnt =0;
+	if(mFlash.isHost)return;
+	if(slave_isconnect()){//右鞋连接上左鞋
+		if(app_game_GetGameMode()){
+			 if(cnt++ >= 4){cnt =0;
+				  app_client_DataUpdate_Send();
+			 }
+		}
+		else app_client_DataUpdate_Send();
+	}
+}
+
+void app_client_Initialize(void)
+{
+	BLE_Client_Rx_Regist(BLE_UPDATE,cb_BLE_Client_R_UPDATE);
+	app_client_step_Initialize();
+	Process_Start(2000,"app_client",app_client_Process);
+}

+ 17 - 0
shoe_mcu2.2.1_new_v2/app/app_client.h

@@ -0,0 +1,17 @@
+#ifndef __app_client_h__
+#define __app_client_h__
+#include <stdbool.h>
+#include <stdint.h>
+#include <string.h>
+#include "sdk_common.h"
+#include "SEGGER_RTT.h"
+#include "usr_config.h"
+
+void app_client_Initialize(void);
+void app_client_DataUpdate_Send(void);
+void app_client_infomation_Send(void);
+
+#endif
+
+
+

+ 171 - 0
shoe_mcu2.2.1_new_v2/app/app_client_step.c

@@ -0,0 +1,171 @@
+#include "system.h"
+#include "app_client_step.h"
+#include "app_flash.h"
+#include "bsp_time.h"
+#include "system.h"
+#include "app_host.h"
+#include "app_step.h"
+#include "ble_comm.h"
+#include "app_math.h"
+#include "app_flash.h"
+
+/************************ 函数定义 ***************************/
+void cb_BLE_Client_T_UPDATE_STEPNUM(void* handle);
+
+/************************ 获取步数 ***************************/
+
+static uint8_t isScan = 0;
+
+uint8_t app_client_step_GetIsScan(void)
+{
+	return isScan;
+}
+
+void app_client_step_SetIsScan(void)
+{
+	isScan =1;
+}
+
+//一小时保存一次步数
+static void app_client_step_Process(void)
+{
+  static uint8_t state =0;
+	static uint32_t tim =0;
+	switch(state){
+		case 0:
+			    if(1 == isScan){
+						state =1;
+						tim = TIME_GetTicks();
+					}
+			    break;
+	  case 1:
+			    if(TIME_GetTicks() - tim >= 10000)state =2;
+				  else app_host_GetClientData(1);
+					break;
+		case 2:
+		      if(Flash_SaveStep() != ZONE_OP_SUCCESS)Except_TxError(EXCEPT_DATEStep,"save step fail");
+		      isScan = 0;
+		      state =0;
+		      DEBUG_LOG("Flash_SaveInfomation:%d,mFlash.mStep.stepCur[1]:%d\r\n",TIME_GetTicks(),mFlash.mStep.stepCur[1]);
+			    break;
+		default:state =0;isScan = 0;break; 
+	}
+}
+
+/************************ 删除步数 ***************************/
+void app_client_DeleteStep(BLE_Client_Rx_t* target)
+{
+	uint8_t i =0;
+	for(i=0;i<8;i++) mFlash.mStep.startTime[i] = target->pDat[i+1];
+	app_math_calit_time(target->pDat[9]);
+	if(0 != mFlash.mStep.step_num){mFlash.mStep.step_num = 0;
+		 flash_SetClearStepFlag();
+	}
+}
+
+/************************ 发送步数 ***************************/
+#define PACK_STEP_LEN 40		//发送 PACK_STEP_LEN*4 个字节
+
+static uint8_t isSendAll = 0;
+static uint16_t packDex = 0;
+static uint16_t packNum = 0;
+static uint16_t lastNum = 0;
+
+BLE_Client_Tx_t mSendStep = {
+	.n = 1,
+	.t = 1,
+	.cb = cb_BLE_Client_T_UPDATE_STEPNUM,
+};
+
+void app_client_SendStepAll(uint16_t n)
+{
+	static uint8_t buf[250];
+	uint8_t L=0;
+	
+	uint32_t addr = (flash_GetStep_StartAddress()+PACK_STEP_LEN*4*(n-1));
+	buf[L++] = BLE_UPDATE_STEPNUM;
+	for(int i=0;i<8;i++){buf[L++] = mFlash.mStep.startTime[i];}
+	buf[L++] = (uint8_t)(packNum>>8);
+	buf[L++] = (uint8_t)(packNum>>0);
+	buf[L++] = (uint8_t)(n>>8);
+	buf[L++] = (uint8_t)(n>>0);
+	if(n==0){
+		uint32_t step = app_step_GetStep_L() + app_step_GetStep_R();
+//		DEBUG_LOG("====>step=%d,app_step_GetStep_L()=%d,app_step_GetStep_R()=%d\n",step,app_step_GetStep_L(),app_step_GetStep_R());
+		buf[L++] = (uint8_t)(step>>24);
+		buf[L++] = (uint8_t)(step>>16);
+		buf[L++] = (uint8_t)(step>>8);
+		buf[L++] = (uint8_t)(step>>0);
+	}else if(n==packNum){
+		flash_Data_Read(addr,(uint32_t*)&buf[L],lastNum*4); L+=lastNum*4;
+	}else{
+		flash_Data_Read(addr,(uint32_t*)&buf[L],PACK_STEP_LEN*4); L+=PACK_STEP_LEN*4;
+	}
+//	DEBUG_LOG("====>lastNum=%d,PACK_STEP_LEN=%d\n",lastNum,PACK_STEP_LEN);
+//	DEBUG_LOG("app_client_SendStepAll:"); for(int i=0;i<L;i++){DEBUG_LOG("%02X ",buf[i]);} DEBUG_LOG("\r\n");
+	BLE_Client_Tx_Send(&mSendStep,BLE_UPDATE,buf,L);
+}
+
+void app_client_SendStepN(uint16_t n)
+{
+	uint8_t buf[250];
+	uint8_t L=0;
+	
+	uint32_t addr = (flash_GetStep_StartAddress()+PACK_STEP_LEN*4*(n-1));
+	buf[L++] = BLE_UPDATE_STEPNUM;
+	for(int i=0;i<8;i++){buf[L++] = mFlash.mStep.startTime[i];}
+	
+	buf[L++] = (uint8_t)(packNum>>8);
+	buf[L++] = (uint8_t)(packNum>>0);
+	buf[L++] = (uint8_t)(n>>8);
+	buf[L++] = (uint8_t)(n>>0);
+	if(n == packNum){
+		flash_Data_Read(addr,(uint32_t*)&buf[L],lastNum*4); L+=lastNum*4;
+	}else{
+		flash_Data_Read(addr,(uint32_t*)&buf[L],PACK_STEP_LEN*4); L+=PACK_STEP_LEN*4;
+	}
+//	DEBUG_LOG("app_client_SendStepN:"); for(int i=0;i<L;i++){DEBUG_LOG("%02X ",buf[i]);} DEBUG_LOG("\r\n");
+	BLE_Client_Tx_Send(0,BLE_UPDATE,buf,L);
+}
+
+void app_client_SendStep(BLE_Client_Rx_t* target)
+{
+	uint16_t n = ((uint16_t)target->pDat[1]<<8)|((uint16_t)target->pDat[2]<<0);
+	
+	if(mFlash.mStep.step_num > 0){
+		packNum = ((mFlash.mStep.step_num-1)/PACK_STEP_LEN)+1;
+		lastNum = ((mFlash.mStep.step_num-1)%PACK_STEP_LEN)+1;
+	}else{
+		packNum = 0;
+		lastNum = 0;
+	}
+	
+//	DEBUG_LOG("====>mFlash.mStep.step_num=%d,packNum=%d,lastNum=%d,nnnn=%d\n",mFlash.mStep.step_num,packNum,lastNum,n);
+	
+	if(n==0){
+		isSendAll = 1;
+		packDex = 0;
+		app_client_SendStepAll(packDex);
+	}else{
+		app_client_SendStepN(n);
+	}
+}
+
+static void cb_BLE_Client_T_UPDATE_STEPNUM(void* handle)
+{
+	if(isSendAll==0) return;
+	if(packDex<packNum){
+		if(++packDex>=packNum) isSendAll = 0;
+		app_client_SendStepAll(packDex);
+	}
+}
+
+/************************ 初始化 ***************************/
+void app_client_step_Initialize(void)
+{
+	Process_Start(1000,"app_client_step",app_client_step_Process);
+	if(mFlash.mStep.stepCur[0]<mFlash.mStep.step[0])
+	mFlash.mStep.step[0] = mFlash.mStep.stepCur[0];
+	DEBUG_LOG("mFlash.mStep.step_num=%d\n",mFlash.mStep.step_num);
+	DEBUG_LOG("mFlash.mStep.stepCur[0]=%d,mFlash.mStep.stepCur[1]=%d\n",mFlash.mStep.stepCur[0],mFlash.mStep.stepCur[1]);
+}

+ 20 - 0
shoe_mcu2.2.1_new_v2/app/app_client_step.h

@@ -0,0 +1,20 @@
+#ifndef __app_client_step_h__
+#define __app_client_step_h__
+#include <stdbool.h>
+#include <stdint.h>
+#include <string.h>
+#include "sdk_common.h"
+#include "SEGGER_RTT.h"
+#include "usr_config.h"
+#include "hal_ble_client.h"
+
+void app_client_step_Initialize(void);
+void app_client_SendStep(BLE_Client_Rx_t* target);
+void app_client_DeleteStep(BLE_Client_Rx_t* target);
+uint8_t app_client_step_GetIsScan(void);
+void app_client_step_SetIsScan(void);
+
+#endif
+
+
+

+ 208 - 0
shoe_mcu2.2.1_new_v2/app/app_config.c

@@ -0,0 +1,208 @@
+#include "app_config.h"
+#include "nrf_gpio.h"
+#include "usr_config.h"
+#include "bsp_time.h"
+#include "system.h"
+#include "hal_mt.h"
+#include "hal_battery.h"
+#include "app_charge.h"
+#include "hal_ble_client.h"
+#include "hal_led.h"
+#include "hal_flash.h"
+#include "ble_gap.h"
+#include "hal_ble_uart0.h"
+#include "ble_comm.h"
+
+static ble_gap_addr_t mAddr;
+static uint8_t isConfig = 0;
+
+void UART0_Config_Send(uint8_t cmd)
+{
+	uint8_t buf[32];
+	uint8_t L = 0;
+	//MAC 地址
+	for(int i=0;i<6;i++){
+		buf[L++] = mAddr.addr[5-i];
+	}
+	//硬件版本
+	buf[L++] = (uint8_t)((uint16_t)HARDWARE_VERSION>>8);
+	buf[L++] = (uint8_t)((uint16_t)HARDWARE_VERSION>>0);
+	//软件版本
+	buf[L++] = (uint8_t)((uint16_t)SOFTWARE_VERSION>>8);
+	buf[L++] = (uint8_t)((uint16_t)SOFTWARE_VERSION>>0);
+	UART0_Tx_Send(0,cmd,buf,L);
+}
+
+void app_config_Process(void)
+{
+	static uint8_t flag = 0;
+	if(app_charge_Getstate()!=BLE_Client_T_CHARGE_PULLOUT){
+		if(flag != 1)
+		{
+//			UART0_Initialize();
+			flag = 1;
+		}
+		else if(isConfig<50){ isConfig++;
+			if(mFlash.isHost){ //充电模式下主机主机申请配对
+//				UART0_Config_Send(UART0_T_CONFIG_ASK);
+			}
+		}
+	}else{
+		if(flag != 2)
+		{
+//			UART0_unInit();
+			flag = 2;
+		}
+		else if(isConfig>0) isConfig = 0;
+	}
+}
+
+void app_config_LED(void)
+{
+	static uint8_t state = 0;
+	switch(state){
+		case 0:
+			Process_SetHoldOn(app_config_LED,1);
+			LED_SetColor(LED_CONFIG,COLOR_BLUE);
+			LED_Start(LED_CONFIG);
+			state = 1;
+			Process_UpdatePeroid(app_config_LED,2000);
+			break;
+		case 1:
+			Process_UpdatePeroid(app_config_LED,0);
+			LED_Stop(LED_CONFIG);
+			state = 0;
+			Process_SetHoldOn(app_config_LED,0);
+			Process_Stop(app_config_LED);
+			break;
+		default:state=0;Process_UpdatePeroid(app_config_LED,0);break;
+	}
+	
+}
+
+void cb_UART0_R_CONFIG_ASK(void* handle)
+{	//从机接收到配对申请
+	UART0_Rx_t* target = handle;
+	uint8_t mac[6];
+	char buf[16];
+	uint8_t ret = 0;
+	
+	if(app_charge_Getstate()==BLE_Client_T_CHARGE_PULLOUT) return; //非充电模式不匹配
+	if(mFlash.isHost) return; //主机自发自收
+	
+	for(int i=0;i<6;i++) mac[i] = target->pDat[i];
+	uint16_t hv = ((uint16_t)target->pDat[6]<<8)| ((uint16_t)target->pDat[7]<<0);
+	uint16_t sv = ((uint16_t)target->pDat[8]<<8)| ((uint16_t)target->pDat[9]<<0);
+
+	if(slave_isconnect()) slave_disconnect();
+	else advertising_stop();
+	
+	UART0_Config_Send(UART0_T_CONFIG_ACK);//应答主机申请
+	
+	mFlash.mClient.isConfig = 'C';
+	if(mBackup.isConfig != mFlash.mClient.isConfig)ret = 1;
+	for(int i=0;i<6;i++){
+		mFlash.mClient.macAddr[i] = mAddr.addr[5-i];	//从机自身mac地址
+		mFlash.macHost[i] = mac[i];						//主机发过来的mac地址
+		if(mBackup.macAddr_L[i]!=mFlash.macHost[i]) ret = 1;
+		if(mBackup.macAddr_R[i]!=mFlash.mClient.macAddr[i]) ret = 1;
+	}
+	mFlash.mClient.hardVersion = hv;
+	mFlash.mClient.sotfVersion = sv;
+	if(	mBackup.hardVersion != mFlash.mClient.hardVersion) ret = 1;
+	if( mBackup.sotfVersion != mFlash.mClient.sotfVersion) ret = 1;
+	DEBUG_LOG("mFlash.mClient.hardVersion:%X\n",mFlash.mClient.hardVersion);
+	DEBUG_LOG("mFlash.mClient.sotfVersion:%X\n",mFlash.mClient.sotfVersion);
+	DEBUG_LOG("mFlash.mClient.macAddr:%02X %02X %02X %02X %02X %02X\n",mFlash.mClient.macAddr[0],mFlash.mClient.macAddr[1],mFlash.mClient.macAddr[2],mFlash.mClient.macAddr[3],mFlash.mClient.macAddr[4],mFlash.mClient.macAddr[5]);
+	DEBUG_LOG("mFlash.macHost:%02X %02X %02X %02X %02X %02X\n",mFlash.macHost[0],mFlash.macHost[1],mFlash.macHost[2],mFlash.macHost[3],mFlash.macHost[4],mFlash.macHost[5]);
+	Process_Start(0,"config_LED",app_config_LED);
+	
+	memset(buf,0,16);
+	sprintf(buf,"%02X%02X%02X%02X%02X%02X",mFlash.macHost[0],mFlash.macHost[1],mFlash.macHost[2],mFlash.mClient.macAddr[3],mFlash.mClient.macAddr[4],mFlash.mClient.macAddr[5]);
+	DEBUG_LOG("advName(%d):%s\n",strlen(buf),buf);
+	slave_set_adv_name(buf,strlen(buf));
+	slave_adv_init();
+	if(ret >=1){
+		
+		for(int i=0;i<6;i++){
+				mBackup.macAddr_L[i] = mFlash.macHost[i];		     //主机地址
+				mBackup.macAddr_R[i] = mFlash.mClient.macAddr[i];//从机地址	
+		}
+		mBackup.hardVersion = mFlash.mClient.hardVersion;
+		mBackup.sotfVersion = mFlash.mClient.sotfVersion;
+		mBackup.isConfig = mFlash.mClient.isConfig;
+		//DEBUG_LOG("AAAAAbackup config:%d,hardVersion:%d,sotfVersion:%d\n",mBackup.isConfig,mBackup.hardVersion,mBackup.sotfVersion);
+		Flash_SaveInfomation();
+		Flash_SaveBackup();
+	}
+	
+	while(slave_isconnect());
+	advertising_start();
+//	nrf_gpio_cfg_output(PIN_LED_RUN); 	
+//	nrf_gpio_pin_write(PIN_LED_RUN,0);
+	
+}
+
+void cb_UART0_R_CONFIG_ACK(void* handle)
+{	//主机接收到配对应答
+	UART0_Rx_t* target = handle;
+	uint8_t mac[6];
+	char buf[16];
+	uint8_t ret = 0;
+	
+	if(app_charge_Getstate()==BLE_Client_T_CHARGE_PULLOUT) return; //非充电模式不匹配
+	if(!mFlash.isHost) return; //从机自发自收
+	
+	for(int i=0;i<6;i++) mac[i] = target->pDat[i];
+	uint16_t hv = ((uint16_t)target->pDat[6]<<8)| ((uint16_t)target->pDat[7]<<0);
+	uint16_t sv = ((uint16_t)target->pDat[8]<<8)| ((uint16_t)target->pDat[9]<<0);
+	
+	isConfig = 100;	//已配对,停止配对发送
+	
+	mFlash.mClient.isConfig = 'C';
+	if(mBackup.isConfig != mFlash.mClient.isConfig)ret = 1;
+	for(int i=0;i<6;i++){
+		mFlash.mClient.macAddr[i] = mac[i]; 	//收到的从机mac地址
+		mFlash.macHost[i] = mAddr.addr[5-i];	//主机本身mac地址
+		if(mBackup.macAddr_L[i]!=mFlash.macHost[i]) ret = 1;
+		if(mBackup.macAddr_R[i]!=mFlash.mClient.macAddr[i]) ret = 1;
+	}
+	mFlash.mClient.hardVersion = hv;
+	mFlash.mClient.sotfVersion = sv;
+	if(	mBackup.hardVersion != mFlash.mClient.hardVersion) ret = 1;
+	if( mBackup.sotfVersion != mFlash.mClient.sotfVersion) ret = 1;
+	DEBUG_LOG("mFlash.mClient.hardVersion:%X\n",mFlash.mClient.hardVersion);
+	DEBUG_LOG("mFlash.mClient.sotfVersion:%X\n",mFlash.mClient.sotfVersion);
+	DEBUG_LOG("mFlash.mClient.macAddr:%02X %02X %02X %02X %02X %02X\n",mFlash.mClient.macAddr[0],mFlash.mClient.macAddr[1],mFlash.mClient.macAddr[2],mFlash.mClient.macAddr[3],mFlash.mClient.macAddr[4],mFlash.mClient.macAddr[5]);
+	DEBUG_LOG("mFlash.macHost:%02X %02X %02X %02X %02X %02X\n",mFlash.macHost[0],mFlash.macHost[1],mFlash.macHost[2],mFlash.macHost[3],mFlash.macHost[4],mFlash.macHost[5]);
+	Process_Start(0,"config_LED",app_config_LED);
+	
+	memset(buf,0,16);
+	sprintf(buf,"%02X%02X%02X%02X%02X%02X",mFlash.macHost[0],mFlash.macHost[1],mFlash.macHost[2],mFlash.mClient.macAddr[3],mFlash.mClient.macAddr[4],mFlash.mClient.macAddr[5]);
+	DEBUG_LOG("scanName(%d):%s\n",strlen(buf),buf);
+	host_set_scan_name(buf,strlen(buf));
+	
+	if(ret >=1){
+		for(int i=0;i<6;i++){
+			mBackup.macAddr_L[i] = mFlash.macHost[i];		//主机地址
+			mBackup.macAddr_R[i] = mFlash.mClient.macAddr[i];//从机地址
+		}
+		mBackup.hardVersion = mFlash.mClient.hardVersion;
+		mBackup.sotfVersion = mFlash.mClient.sotfVersion;
+		mBackup.isConfig = mFlash.mClient.isConfig;
+		//DEBUG_LOG("AAAAAbackup config:%d,hardVersion:%d,sotfVersion:%d\n",mBackup.isConfig,mBackup.hardVersion,mBackup.sotfVersion);
+		Flash_SaveInfomation();
+		Flash_SaveBackup();
+	}
+	//nrf_gpio_cfg_output(PIN_LED_RUN); 	nrf_gpio_pin_write(PIN_LED_RUN,0);
+}
+
+void app_config_Init(void)
+{
+	uint32_t err_code = sd_ble_gap_addr_get(&mAddr); APP_ERROR_CHECK(err_code);
+	Process_Start(100,"app_config",app_config_Process);
+	UART0_Rx_Regist(UART0_R_CONFIG_ASK,cb_UART0_R_CONFIG_ASK);
+	UART0_Rx_Regist(UART0_R_CONFIG_ACK,cb_UART0_R_CONFIG_ACK);
+}
+
+

+ 12 - 0
shoe_mcu2.2.1_new_v2/app/app_config.h

@@ -0,0 +1,12 @@
+#ifndef __app_config_h__
+#define __app_config_h__
+#include <stdbool.h>
+#include <stdint.h>
+#include <string.h>
+#include "sdk_common.h"
+#include "SEGGER_RTT.h"
+#include "usr_config.h"
+
+void app_config_Init(void);
+
+#endif

+ 236 - 0
shoe_mcu2.2.1_new_v2/app/app_connect_manage.c

@@ -0,0 +1,236 @@
+#include "app_connect_manage.h"
+#include "bsp_time.h"
+#include "system.h"
+#include "ble_comm.h"
+#include "app_flash.h"
+#include "app_charge.h"
+#include "app_ota.h"
+#include "app_game.h"
+#include "exception.h"
+#include "hal_ble_client.h"
+#include "hal_ble_host.h"
+#include "hal_led.h"
+#include "app_self_checking.h"
+#include "exception.h"
+#include "hal_mt.h"
+#include "hal_battery.h"
+
+/********************** 变量区 *************************/
+#define Ble_update_connted_Error 60//一次最多更新蓝牙连接间隔 次数
+
+/********************** 函数声明区 *************************/
+extern uint8_t app_client_step_GetIsScan(void);
+
+BLE_Client_Tx_t mBLE_Client_T_CONNET_R = {
+	.n = 10,
+	.t = 500,
+	.cb = 0,
+};
+
+static uint16_t LedPlaytime =0;
+static uint32_t LedBlinktim =0;
+
+static uint8_t app_conneted_getRight(void){
+	uint8_t state =BLE_RIGHT_DISCONNTED;
+	
+	if('C' != mFlash.mClient.isConfig)
+		 state =BLE_RIGHT_NOCONFIG;
+	else if(host_isconnect())
+		 state =BLE_RIGHT_CONNTED;
+	
+	#if BleNameHoldOn_ENANBLE 
+	   if(host_isconnect())
+		 state =BLE_RIGHT_CONNTED;
+	#endif
+	
+	return state;
+}
+
+void app_connect_LED_Process(void)
+{
+	static uint8_t ResportCs_Flag = 0;
+	static uint8_t state =0;
+	static uint8_t host_state=0;
+	switch(state){
+		case 0:
+			    if(slave_isconnect()){
+						state =1;
+						ResportCs_Flag = 0;
+					}
+			    break;
+		case 1:
+			    if(host_isconnect()){ 
+							if(0 == ResportCs_Flag){ResportCs_Flag = 1;		
+								host_state = app_conneted_getRight();
+								BLE_Client_Tx_Send(&mBLE_Client_T_CONNET_R,BLE_CONNET_R,&host_state,1);
+								DEBUG_LOG("====================>BLE_Host_T_CONNET_LED:%d\n",TIME_GetTicks());
+							}
+					}
+					else if(ResportCs_Flag > 0)	{ResportCs_Flag = 0;
+						  BLE_Client_Tx_Clear(&mBLE_Client_T_CONNET_R);
+					}
+					
+					if(0 != LedPlaytime){
+						 if(TIME_GetTicks() - LedBlinktim >=LedPlaytime){LedPlaytime =0;
+							 LED_Stop(LED_OVERTURN);
+							 Process_SetHoldOn(app_connect_LED_Process,0);
+						 }
+					}
+					if(!slave_isconnect()){
+						state =0;
+						LedPlaytime =0;
+						Process_SetHoldOn(app_connect_LED_Process,0);
+						LED_Stop(LED_OVERTURN);
+						BLE_Client_Tx_Clear(&mBLE_Client_T_CONNET_R);
+					}
+			    break;
+		default:state =0;LedPlaytime =0;LED_Stop(LED_OVERTURN);break;
+			    
+	}
+}
+
+static void cb_BLE_BLINK_LED(void* handle)
+{	
+	BLE_Client_Rx_t* target = handle;
+	uint8_t buf[2]={0};
+
+	buf[0] = target->pDat[0];
+	buf[1] = target->pDat[1];
+	
+  LedPlaytime = ((target->pDat[0]<<8) + target->pDat[1]);
+	DEBUG_LOG("=======>cb_BLE_BLINK_LED,displaytime:%d\n",LedPlaytime);
+	BLE_Host_Tx_Send(0,BLE_BLINK_LED,buf,2); 
+	Process_SetHoldOn(app_connect_LED_Process,1);
+	LedBlinktim = TIME_GetTicks();
+	if(GetBatteryPersent()>20){
+			LED_Start(LED_OVERTURN,COLOR_GREEN);
+	}else{
+			LED_Start(LED_OVERTURN,COLOR_ORANGE);
+	}
+}
+
+void cb_Slave_Connect(void)
+{
+	DEBUG_LOG("=======>cb_Slave_Connect\n");
+	if(mFlash.isHost) slave_update_conn_interval_request(30,30);
+}
+
+void cb_Host_Connect(void)
+{
+	DEBUG_LOG("=======>cb_Host_Connect\n");
+}
+
+void app_connect_Process(void)
+{
+	static uint8_t state = 0;
+	static uint32_t cnt = 0;
+	static uint16_t  update_temp = 0;
+	static uint8_t ble_con_int = 0;//左右鞋蓝牙之间的连接间隔
+	static uint8_t hostclientswitch =0;
+	if(!mFlash.isHost){
+		if(1 == hostclientswitch){hostclientswitch =0;
+			 state = 0;
+			 cnt = 0;
+			 update_temp = 0;
+			 ble_con_int = 0;
+			 Process_SetHoldOn(app_connect_Process,0);
+		}
+		return;
+	}
+	
+	if( 1 != hostclientswitch)hostclientswitch =1;
+		
+		
+	switch(state){
+			case 0:{
+				if((app_client_step_GetIsScan()||slave_isconnect()||(app_charge_Getstate()!=BLE_CHARGE_PULLOUT)) && 0 == app_ota_host_state()){
+					DEBUG_LOG("=======>scan_start:%d,%d\n",app_client_step_GetIsScan(),slave_isconnect());
+					Process_SetHoldOn(app_connect_Process,1);
+					scan_start();
+					cnt = 0;
+					state = 1;
+				}
+				if(mFlash.isHost && 0 == slave_isconnect()){
+					if(host_isconnect())host_disconnect();
+				} 
+				break;}
+			case 1:{
+				if(app_client_step_GetIsScan()==0&&slave_isconnect()==0&&(app_charge_Getstate()==BLE_CHARGE_PULLOUT)){
+					Except_TxError(EXCEPT_DFU,"adv disconnted over time");
+					DEBUG_LOG("=======>nrf_ble_scan_stop\n");
+					nrf_ble_scan_stop();
+					Process_SetHoldOn(app_connect_Process,0);
+					state = 0;
+				}else if(host_isconnect()){
+					DEBUG_LOG("=======>host_isconnect\n");
+					Process_SetHoldOn(app_connect_Process,0);
+					if(mFlash.isHost){
+						update_temp =0;
+						ble_con_int = 0;
+					}
+					state =2;
+				}
+				if(++cnt>=100){ if(0 == app_client_step_GetIsScan() && 'C' == mFlash.mClient.isConfig)Except_TxError(EXCEPT_CONNET,"scan right shoes over time");
+					DEBUG_LOG("=======>app_err_Set nrf_ble_scan_stop\n");
+					nrf_ble_scan_stop();
+					Process_SetHoldOn(app_connect_Process,0);
+					state = 0;
+				}
+				break;}
+			case 2:{
+				if(app_game_GetGameMode()){//游戏模式下更新连接间隔
+						if(ble_con_int !=2 && update_temp <= Ble_update_connted_Error){
+							if(APP_SUCCESS ==  Ble_update_conn_interval(7.5,7.5)){
+								ble_con_int =2;
+								update_temp  =0;
+							}
+							else {
+							  if(Ble_update_connted_Error == update_temp)Except_TxError(EXCEPT_CONNET,"update Ble conn interval 7.5ms fail");
+								++update_temp;
+							}
+						}
+				}else{
+						if(ble_con_int !=1 && update_temp <= Ble_update_connted_Error){
+							if(APP_SUCCESS ==  Ble_update_conn_interval(100,100)){
+								ble_con_int =1;
+								update_temp =0;
+							}
+							else {
+							  if(Ble_update_connted_Error == update_temp)Except_TxError(EXCEPT_CONNET,"update Ble conn interval 100ms fail");
+								update_temp++;
+							}
+						}
+				}
+				if(app_client_step_GetIsScan()==0 && slave_isconnect()==0 && (app_charge_Getstate()==BLE_CHARGE_PULLOUT)){
+					if(host_isconnect())host_disconnect();
+				}
+				if(!host_isconnect()){
+					DEBUG_LOG("=======>host_disconnect\n");
+					Process_SetHoldOn(app_connect_Process,0);
+					state = 0;
+				}
+				
+				break;}
+			default:state=0;break;
+		}
+}
+
+static void cb_BLE_BLE_CONNET_R(void* handle)
+{	
+	uint8_t host_state=BLE_RIGHT_DISCONNTED;
+	host_state =app_conneted_getRight();
+//	DEBUG_LOG("!!!!app_conneted_getRight:%d\n",host_state);
+	BLE_Client_Tx_Send(0,BLE_CONNET_R,&host_state,1);
+}
+
+void app_connect_manage_Init(void)
+{
+	Process_Start(100,"app_connect",app_connect_Process);
+	Ble_Slave_Connectd_Evt_Regist(cb_Slave_Connect);
+	Ble_Host_Connectd_Evt_Regist(cb_Host_Connect);
+	Process_Start(100,"app_connect_led",app_connect_LED_Process);
+	BLE_Client_Rx_Regist(BLE_CONNET_R,cb_BLE_BLE_CONNET_R);
+	BLE_Client_Rx_Regist(BLE_BLINK_LED,cb_BLE_BLINK_LED);
+}
+
+

+ 12 - 0
shoe_mcu2.2.1_new_v2/app/app_connect_manage.h

@@ -0,0 +1,12 @@
+#ifndef __app_connect_manage_h__
+#define __app_connect_manage_h__
+#include <stdbool.h>
+#include <stdint.h>
+#include <string.h>
+#include "sdk_common.h"
+#include "SEGGER_RTT.h"
+#include "usr_config.h"
+
+void app_connect_manage_Init(void);
+
+#endif

+ 83 - 0
shoe_mcu2.2.1_new_v2/app/app_data_transfer.c

@@ -0,0 +1,83 @@
+/*Includes ----------------------------------------------*/
+#include "system.h"
+#include "ble_comm.h"
+#include "bsp_time.h"
+#include "hal_ble_host.h"
+#include "hal_ble_client.h"
+#include "hal_ble_common.h"
+#include "app_flash.h"
+#include "app_game.h"
+#include "app_data_transfer.h"
+#include "app_step.h"
+
+/*Local Functions ------------------------------------------------------------------------------------------------------------------------------------*/
+static void app_data_transfer_Process(void)
+{
+	static uint32_t tim 	= 0;
+	static uint32_t	tim2 	= 0;
+	static uint8_t	flag 	= 0;
+	//全功率模式
+	if(app_game_GetGameMode() || app_step_Real_Get())
+	{
+		if(!flag){flag =1;
+			Process_SetHoldOn(app_data_transfer_Process,1);
+		}
+		if(TIME_GetTicks()-tim>=500){tim = TIME_GetTicks();
+			if( 0 == slave_isconnect()){
+//				DEBUG_LOG("app_data_transfer_Process advertising_start\r\n");
+				advertising_stop();
+				advertising_start();
+			}
+			if(mFlash.isHost && 0 == host_isconnect())scan_start();
+		}
+
+		if(TIME_GetTicks()-tim2>=3){tim2 = TIME_GetTicks();	
+			IMU_Dtalige();
+		}			
+	}
+	else{
+		if(flag){flag =0;
+			Process_SetHoldOn(app_data_transfer_Process,0);
+		}
+	}
+}
+
+
+/*API -------------------------------------------------------*/
+/**
+	@brief 		将旧版本的IMU_SetSlaveData(uint8_t* pdat,uint8_t len)写在这里
+	@param 		pdat	略
+	@param 		len		略
+	@return 	无
+*/
+void app_data_transfer_set_SlaveData(uint8_t* pdat,uint8_t len)
+{
+	if(pdat[3]==BLE_TRACK){
+		IMU_Rec_data(pdat,len);
+	}
+	app_game_SetClientGameMode();
+}
+/**
+	@brief 		初始化数据传输应用
+	@param 		无
+	@return 	错误代码					- [out]	-1失败,0成功
+*/
+int	app_data_transfer_Init(void)
+{
+	//设置数据传输线程
+	Process_Start(0,"app_data_transfer_Process",app_data_transfer_Process);
+	
+	BLE_Host_Rx_Regist_Game(app_data_transfer_set_SlaveData);
+	
+	return 0;
+}
+
+void send_protocol(uint8_t index,uint8_t cmd,uint8_t* p,uint8_t datLen)
+{
+	BLE_Client_Tx_Send(0,(BLE_CMD_n)cmd,p,datLen);
+}	
+
+
+
+
+

+ 55 - 0
shoe_mcu2.2.1_new_v2/app/app_data_transfer.h

@@ -0,0 +1,55 @@
+#ifndef __APP_DATA_TRANSFER_H__
+#define __APP_DATA_TRANSFER_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*Includes ------------------------------------------------------*/
+#include <stdbool.h>
+#include <stdint.h>
+#include <string.h>
+#include "sdk_common.h"
+#include "SEGGER_RTT.h"
+#include "usr_config.h"
+
+/*STRUCTION ----------------------------------------------------*/	
+	
+	
+	
+/*API -------------------------------------------------------*/
+/**
+	@brief 		初始化数据传输应用
+	@param 		无
+	@return 	错误代码					- [out]	-1失败,0成功
+*/
+int		app_data_transfer_Init(void);
+/**
+	@brief 		将旧版本的IMU_SetSlaveData(uint8_t* pdat,uint8_t len)写在这里
+	@param 		pdat	略
+	@param 		len		略
+	@return 	无
+*/
+void	app_data_transfer_set_SlaveData(uint8_t* pdat,uint8_t len);
+	
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+ 228 - 0
shoe_mcu2.2.1_new_v2/app/app_detectIsHost.c

@@ -0,0 +1,228 @@
+/*********************************************************************
+ * INCLUDES
+ */
+#include "ble_comm.h"
+#include "app_detectIsHost.h"
+#include "hal_ble_client.h"
+#include "app_flash.h"
+#include "hal_qma.h"
+#include "hal_mt.h"
+#include "tool.h"
+#include "bll_imu.h"
+
+#define DETECT_LR_TIMEOUT							10		
+
+static DETECT_LR_e ob_detect_LR = DETECT_LR_INIT;
+
+static uint8_t SetDeviceNameFlag = 0;
+
+static void app_SetDeviceName_Porcess(void){
+	 static uint8_t state =0;
+	 char buf[16];
+	 memset(buf,0,16);
+	 switch(state){
+		 case 0:
+			     if(1 == SetDeviceNameFlag){
+						  state =1; 
+					 }
+			     break;
+		 case 1:
+			     if(host_isconnect()){
+						  host_disconnect();
+					 }
+					 else{
+						 if(slave_isconnect()) 
+							   slave_disconnect();
+						 else{
+							   advertising_stop();
+							   ST_scan_stop();
+							   state =2;
+						 }
+					 }
+			     break;
+		 case 2:
+					if(app_Get_isHost()){	//
+						#if BleNameHoldOn_ENANBLE
+							slave_set_adv_name((char *) LEFT_NAME,sizeof(LEFT_NAME));
+							DEBUG_LOG("AdvName(%d):%s\n",sizeof(LEFT_NAME),LEFT_NAME);
+							host_set_scan_name((char *)RIGHT_NAME,sizeof(RIGHT_NAME));
+							DEBUG_LOG("scanName(%d):%s\n",sizeof(RIGHT_NAME),RIGHT_NAME);
+					  #else
+							if(mFlash.mClient.isConfig == 'C'){ 
+						    sprintf(buf,"%02X%02X%02X%02X%02X%02X",mFlash.macHost[0],mFlash.macHost[1],mFlash.macHost[2],mFlash.mClient.macAddr[3],mFlash.mClient.macAddr[4],mFlash.mClient.macAddr[5]);
+			          DEBUG_LOG("scanName(%d):%s\n",strlen(buf),buf);
+			          host_set_scan_name(buf,strlen(buf));
+							}
+					  #endif
+					}else{ //
+						#if BleNameHoldOn_ENANBLE 
+							slave_set_adv_name((char *)RIGHT_NAME,sizeof(RIGHT_NAME));
+							DEBUG_LOG("AdvName(%d):%s\n",sizeof(RIGHT_NAME),RIGHT_NAME);
+						#else
+							if(mFlash.mClient.isConfig=='C'){ //
+								sprintf(buf,"%02X%02X%02X%02X%02X%02X",mFlash.macHost[0],mFlash.macHost[1],mFlash.macHost[2],mFlash.mClient.macAddr[3],mFlash.mClient.macAddr[4],mFlash.mClient.macAddr[5]);
+								DEBUG_LOG("advName(%d):%s\n",strlen(buf),buf);
+								slave_set_adv_name(buf,strlen(buf));
+						  }
+						  host_set_scan_name((char *)"12321321312",sizeof("12321321312"));
+						#endif
+					 } 
+					 
+					 slave_adv_init();
+	         advertising_start();
+					 state =0;
+					 SetDeviceNameFlag = 0;
+			     break;
+		 default:state =0;SetDeviceNameFlag = 0;break;
+	 }
+}
+
+static void app_detect_LR_Porcess(void)
+{
+
+//	int consZ=0;
+	int ret =-1;
+	static uint8_t counter = 0;
+	bll_imu_data_t f_data = {0};
+	qma_data_t 	qma_data={0};
+	
+  static DETECT_LR_e direct_detect_LR = DETECT_LR_INIT;
+	uint8_t direct_detect_host = 0;
+	
+	#define Bufflength 6
+  static int32_t buff[Bufflength]={0};
+	int32_t LvBobuff[Bufflength]={0};
+	uint8_t i=0;
+	int32_t acc_norm  =0;
+	int32_t temp =0;
+	static uint8_t firtRunflag =0; 
+	
+	//获取中间加速度值
+	ret = drv_qma_get_acc_data(&qma_data);
+	if(-1 == ret || (0 == qma_data.acc[0] && 0 == qma_data.acc[1] && 0== qma_data.acc[2]))return;
+	
+//  DEBUG_LOG("qma_data.acc:%d,%d,%d\r\n",qma_data.acc[0],qma_data.acc[1],qma_data.acc[2]);
+	acc_norm = sqrt(qma_data.acc[0] * qma_data.acc[0] +qma_data.acc[1] * qma_data.acc[1] + qma_data.acc[2] * qma_data.acc[2]);
+	
+	//获取前脚IMU的值
+	if(bll_imu_get_data_num(BLL_IMU_DIR_FRONT) >= 0){
+		if(-1 == bll_imu_get_data(BLL_IMU_DIR_FRONT, 0, &f_data))
+			return;
+	}
+	//第一次启动给所有的BUFF赋值
+  if( 0 == firtRunflag)	{firtRunflag =1;
+		for(i=0;i< Bufflength;i++){
+		    buff[i]=acc_norm;
+	  }	
+	}
+	
+	for(i=0;i<(Bufflength-1);i++){
+		  buff[i]=buff[i+1];
+	}
+	buff[Bufflength-1] = acc_norm;
+	
+	//数据排序
+	memcpy(LvBobuff,buff,sizeof(buff));
+	for(uint8_t d=0;d<(Bufflength-1);d++){
+		 for(uint8_t b=0;b<(Bufflength-1-d);b++){
+				if(LvBobuff[b]>LvBobuff[b+1]){
+					temp=LvBobuff[b+1];
+					LvBobuff[b+1]=LvBobuff[b];
+					LvBobuff[b]=temp;
+				}
+		 }
+	}
+	
+	char printfbuff[100]={0};
+	memset(printfbuff,0,sizeof(printfbuff));
+	int consZ=(int)sqrt((float)(qma_data.acc[0]*qma_data.acc[0]+qma_data.acc[1]*qma_data.acc[1]+qma_data.acc[2]*qma_data.acc[2]));
+  DEBUG_LOG("f acc:%6d,%6d,%6d,qma acc:%6d,%6d,%6d  %d\r\n",f_data.acc[0],f_data.acc[1],f_data.acc[2],qma_data.acc[0],qma_data.acc[1],qma_data.acc[2],consZ);
+//	Except_TxError(EXCEPT_Power,(const char*)printfbuff);
+//	
+//	DEBUG_LOG("LvBobuff:%d,%d\r\n",LvBobuff[Bufflength-1],LvBobuff[0]);
+	if((LvBobuff[Bufflength-1] - LvBobuff[0]) < 500){
+//		 DEBUG_LOG("f_data.acc[0]:%6d,qma_data.acc[0]:%6d\r\n",f_data.acc[0],qma_data.acc[0]);
+//		 DEBUG_LOG("f_data.acc[1]:%6d,qma_data.acc[1]:%6d\r\n",f_data.acc[1],qma_data.acc[1]);
+//		 DEBUG_LOG("f_data.acc[2]:%6d,qma_data.acc[2]:%6d\r\n",f_data.acc[2],qma_data.acc[2]);
+		
+//		consZ=f_data.acc[2]*qma_data.acc[2];
+		
+//		DEBUG_LOG("f_data.acc[2]:%6d\r\n",f_data.acc[2]);
+		
+		  if(f_data.acc[2] < -1850  && f_data.acc[2] > -2050 ){//平放的时候才判断左右鞋 
+				 if(qma_data.acc[2] > 500){//同向 		
+					  #if _SAME_DIRECTION
+								if(DETECT_LR_IS_LEFT == direct_detect_LR)counter++;
+								else counter =0;
+								direct_detect_LR = DETECT_LR_IS_LEFT;    
+						#else
+								if(DETECT_LR_IS_RIGHT == direct_detect_LR)counter++;
+								else counter =0;
+								direct_detect_LR = DETECT_LR_IS_RIGHT;
+						#endif
+				 }
+				 else {//反向 		
+						#if _SAME_DIRECTION
+								if(DETECT_LR_IS_RIGHT == direct_detect_LR)counter++;
+								else counter =0;
+								direct_detect_LR = DETECT_LR_IS_RIGHT;	
+						#else
+								if(DETECT_LR_IS_LEFT == direct_detect_LR)counter++;
+								else counter =0;
+								direct_detect_LR = DETECT_LR_IS_LEFT;
+						#endif 
+				 }
+		 }
+	}
+	else counter =0;
+
+	
+	if(counter >= DETECT_LR_TIMEOUT){counter = 0;
+
+				if(direct_detect_LR != ob_detect_LR){ob_detect_LR = direct_detect_LR;
+					  if(ob_detect_LR == DETECT_LR_IS_LEFT)
+							direct_detect_host = 1;
+						else 
+							direct_detect_host = 0;
+					  if(direct_detect_host != mFlash.isHost){
+							mFlash.isHost = direct_detect_host;
+							Flash_SaveInfomation();
+							SetDeviceNameFlag =1;
+							MT_Run(500);
+						}
+						direct_detect_LR = DETECT_LR_INIT;
+				}
+
+		}
+
+}
+
+/**
+ @brief 返回主机标志位
+ @param 无
+ @return 主机标志位
+*/
+uint8_t app_Get_isHost(void)
+{
+	return mFlash.isHost;
+}
+
+void app_detect_Init(void)
+{
+	SetDeviceNameFlag =1;
+  
+	Process_Start(100,"app_SetDeviceName_Porcess",app_SetDeviceName_Porcess);
+	Process_Start(1000,"app_detect_LR_Init_Porcess",app_detect_LR_Porcess);
+	if(mFlash.isHost){
+		DEBUG_LOG("======= Left  shooe ======= \n");
+	}else{
+		DEBUG_LOG("======= Right shooe ======= \n");
+	}
+}
+
+ 
+
+
+
+
+

+ 27 - 0
shoe_mcu2.2.1_new_v2/app/app_detectIsHost.h

@@ -0,0 +1,27 @@
+#ifndef __APP_DETECT_ISHOST_H__
+#define __APP_DETECT_ISHOST_H__
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <string.h>
+#include "sdk_common.h"
+#include "SEGGER_RTT.h"
+#include "system.h"
+#include "usr_config.h"
+
+typedef enum
+{
+	DETECT_LR_INIT     = 0, 
+	
+	DETECT_LR_IS_RIGHT = 1,
+	
+	DETECT_LR_IS_LEFT  = 2,
+	
+} DETECT_LR_e;
+
+void app_detect_Init(void);
+uint8_t app_Get_isHost(void);
+
+#endif
+
+

+ 412 - 0
shoe_mcu2.2.1_new_v2/app/app_flash - 副本.c

@@ -0,0 +1,412 @@
+#include "app_flash.h"
+#include "bsp_wdt.h"
+#include "exception.h"
+#include "system.h"
+#include "hal_minifds.h"
+#include "nrf_sdh_soc.h"
+#include "app_step.h"
+#include "nrf_pwr_mgmt.h"
+#include "bsp_flash.h"
+
+/*************************************
+ *DEFINITION
+ */
+#define FLASH_HEAD									        0xAA5555AA
+
+
+
+#define FLASH_START_ADDR_INFOR 0x00074000UL
+#define FLASH_END_ADDR_INFOR   0x00076000UL
+
+#define FLASH_START_ADDR_STEP  0x00076000UL
+#define FLASH_END_ADDR_STEP    0x00077FFFUL
+#define FLASH_ADDR_STEP_PAGENUM 		2
+
+#define MaxLength(a,b) 							a>b?a:b
+
+
+
+typedef struct t_mflash_param_type{
+  const char    *name;	   //参数名字
+	void    *value;          //数据指针
+	const uint8_t length;    //数据长度
+//	const myvalue_type mtype;//数据类型
+}mflash_param_type;
+
+#define MAX_mflash_param_LENGTH 27
+
+const mflash_param_type All_Falsh_value[MAX_mflash_param_LENGTH]={
+{"inforhead",&mFlash.head,4},
+{"macHost",mFlash.macHost,6},
+{"IsHost",&mFlash.isHost,1},
+
+{"startTime",mFlash.mStep.startTime,8},
+{"stepCur",mFlash.mStep.stepCur,8},
+
+{"step",mFlash.mStep.step,8},
+{"step_num",&mFlash.mStep.step_num,4},
+{"C_isConfig",&mFlash.mClient.isConfig,1},
+{"C_hard",&mFlash.mClient.hardVersion,4},
+{"C_sotf",&mFlash.mClient.sotfVersion,2},
+{"C_macAddr",&mFlash.mClient.macAddr,6},
+{"Errorflag",&mFlash.mFlashLog.Errorflag,1},
+{"logData",mFlash.mFlashLog.logData,50},
+{"PB_BR_V2E",&mFlash.mbattercb_t.preBestResult_Voltage2power,4},
+{"PB_BR_C2P",&mFlash.mbattercb_t.preBestResult_chargeV2P_f,4},
+{"PB_P_MAH",&mFlash.mbattercb_t.P_mAh,4},
+{"PB_KG",   &mFlash.mbattercb_t.kg,4},
+{"PP2",   &mFlash.mbattercb_t.P2,4},
+{"PP1",   &mFlash.mbattercb_t.P1,4},
+{"PCAP_MAH",&mFlash.mbattercb_t.Battery_capacity_mAh,4},
+{"PTP4056",&mFlash.mbattercb_t.adc_tp4056_power,4},
+{"PINIT", &mFlash.mbattercb_t.init,1},
+{"PSTA",  &mFlash.mbattercb_t.sta,1},
+{"PCV2P_INIT",&mFlash.mbattercb_t.chargeV2P_f_init,1},
+{"PV2P_INIT",&mFlash.mbattercb_t.Voltage2power_init},
+
+{"Safe_cnt",&mFlash.Safe_cnt,1},
+{"RestartCnt",&mFlash.RestartCnt,1},
+};
+
+/*
+typedef enum myvalue_type{
+  Value_CHAR =0,
+	Value_UINT8_T,
+	Value_UINT16_T,
+	Value_UINT32_T,
+	Value_FLOAT,
+	Value_BUFF
+}myvalue_type;
+const mflash_param_type All_Falsh_value[MAX_mflash_param_LENGTH]={
+{"inforhead",&mFlash.head,4,Value_UINT32_T},
+{"macHost",mFlash.macHost,6,Value_BUFF},
+{"IsHost",&mFlash.isHost,1,Value_UINT8_T},
+
+{"startTime",mFlash.mStep.startTime,8,Value_BUFF},
+{"stepCur",mFlash.mStep.stepCur,8,Value_BUFF},
+
+{"step",mFlash.mStep.step,8,Value_BUFF},
+{"step_num",&mFlash.mStep.step_num,4,Value_UINT32_T},
+{"C_isConfig",&mFlash.mClient.isConfig,1,Value_UINT8_T},
+{"C_hard",&mFlash.mClient.hardVersion,4,Value_UINT32_T},
+{"C_sotf",&mFlash.mClient.sotfVersion,2,Value_UINT16_T},
+{"C_macAddr",&mFlash.mClient.macAddr,6,Value_BUFF},
+{"Errorflag",&mFlash.mFlashLog.Errorflag,1,Value_UINT8_T},
+{"logData",mFlash.mFlashLog.logData,50,Value_UINT8_T},
+{"PB_BR_V2E",&mFlash.mbattercb_t.preBestResult_Voltage2power,4,Value_FLOAT},
+{"PB_BR_C2P",&mFlash.mbattercb_t.preBestResult_chargeV2P_f,4,Value_FLOAT},
+{"PB_P_MAH",&mFlash.mbattercb_t.P_mAh,4,Value_FLOAT},
+{"PB_KG",   &mFlash.mbattercb_t.kg,4,Value_FLOAT},
+{"PP2",   &mFlash.mbattercb_t.P2,4,Value_FLOAT},
+{"PP1",   &mFlash.mbattercb_t.P1,4,Value_FLOAT},
+{"PCAP_MAH",&mFlash.mbattercb_t.Battery_capacity_mAh,4,Value_FLOAT},
+{"PTP4056",&mFlash.mbattercb_t.adc_tp4056_power,4,Value_FLOAT},
+{"PINIT", &mFlash.mbattercb_t.init,1,Value_CHAR},
+{"PSTA",  &mFlash.mbattercb_t.sta,1,Value_CHAR},
+{"PCV2P_INIT",&mFlash.mbattercb_t.chargeV2P_f_init,1,Value_CHAR},
+{"PV2P_INIT",&mFlash.mbattercb_t.Voltage2power_init,1,Value_CHAR},
+
+{"Safe_cnt",&mFlash.Safe_cnt,1,Value_UINT8_T},
+{"RestartCnt",&mFlash.RestartCnt,1,Value_UINT8_T},
+};*/
+
+DEFINE_MINIINF(information, FLASH_START_ADDR_INFOR, FLASH_END_ADDR_INFOR, sdflash_write, sdflash_page_erase);
+
+Flash_t 				mFlash={0};
+
+/****************************************************接口****************************************************/
+void Flash_Initialize(void)
+{
+	uint8_t i = 0;
+	uint8_t length =0;
+	minfds_init(&information);
+  for(i =0;i<MAX_mflash_param_LENGTH;i++){
+		 if(MINIFDS_SUCCESS == pm_get_length(&information,All_Falsh_value[i].name,strlen(All_Falsh_value[i].name),&length)){
+				if(length == All_Falsh_value[i].length){
+					 pm_find(&information,All_Falsh_value[i].name,strlen(All_Falsh_value[i].name),(uint8_t *)All_Falsh_value[i].value,&length);
+				}
+				else{
+					 pm_delete(&information,All_Falsh_value[i].name,strlen(All_Falsh_value[i].name));
+					 pm_add(&information,All_Falsh_value[i].name,strlen(All_Falsh_value[i].name),(uint8_t *)All_Falsh_value[i].value,All_Falsh_value[i].length);
+				}
+		 }
+  }
+	
+
+	DEBUG_LOG(">>>>>>>>1111111 mFlash.mStep.stepCur[0]:%d, %d\n",mFlash.mStep.stepCur[0],mFlash.mStep.step_num);
+	
+	DEBUG_LOG("Flash head read(%04X).\n",mFlash.head);
+	if(mFlash.head !=FLASH_HEAD){  DEBUG_LOG("Flash first init(%04X),write infomation to flash.\n",mFlash.head);
+		memset((uint8_t*)(&mFlash),0,sizeof(Flash_t));
+		mFlash.head = FLASH_HEAD;
+		
+		for(i =0;i<MAX_mflash_param_LENGTH;i++){
+		   pm_add(&information,All_Falsh_value[i].name,strlen(All_Falsh_value[i].name),(uint8_t *)All_Falsh_value[i].value,All_Falsh_value[i].length);
+    }
+		
+		if(MINIFDS_SUCCESS == pm_get_length(&information,All_Falsh_value[0].name,strlen(All_Falsh_value[0].name),&length)){
+			if(length == All_Falsh_value[0].length)
+			{
+				pm_find(&information,All_Falsh_value[0].name,strlen(All_Falsh_value[0].name),(uint8_t *)All_Falsh_value[0].value,&length);
+			}
+		 }
+//		
+		DEBUG_LOG("Flash head second read(%04X).\n",mFlash.head);
+		if(mFlash.head != FLASH_HEAD){ 
+			DEBUG_LOG("Flash write head fail.\n");
+			Except_TxError(EXCEPT_FLASH,"Flash write head fail");
+			return;
+		}
+		DEBUG_LOG("System reset...\n",mFlash.head);
+		for(uint8_t i =0;i<6;i++){
+			nrf_delay_ms(500);
+			feed_watchdog();
+		}
+		NVIC_SystemReset();
+	}
+
+	DEBUG_LOG("err code :%s\n",mFlash.mFlashLog.logData);
+	DEBUG_LOG("Flash init ok.\n");
+	
+	mFlash.isHost = _IS_HOST;
+	
+	#ifdef PIN_SEL
+	nrf_gpio_cfg_input(PIN_SEL,NRF_GPIO_PIN_PULLUP);
+	nrf_delay_ms(100);
+	mFlash.isHost = (uint8_t)nrf_gpio_pin_read(PIN_SEL);
+	if(1 == mFlash.isHost)nrf_gpio_cfg_input(PIN_SEL,NRF_GPIO_PIN_PULLDOWN);
+	else nrf_gpio_cfg_input(PIN_SEL,NRF_GPIO_PIN_NOPULL);
+	#endif
+	if(mFlash.isHost){
+		DEBUG_LOG("======= Left  shooe ======= \n");
+	}else{
+		DEBUG_LOG("======= Right shooe ======= \n");
+	}
+	
+	
+	//TestHalFlashInterface();
+}
+
+
+/**
+ @brief 设置清空flash的标志
+ @param 无
+ @return 无
+*/
+static uint8_t FlashStep_ClearFlag =0;
+void flash_SetClearStepFlag(void){
+	FlashStep_ClearFlag =1;
+}
+
+uint32_t flash_GetStep_StartAddress(void){
+	return FLASH_START_ADDR_STEP;
+}
+
+/**
+ @brief 存储步数
+ @param 无
+ @return 错误代码
+*/
+uint32_t Flash_SaveStep(void)
+{
+	flash_OPER_Result err_code;
+	uint32_t 				flash_data;
+	
+	#define Max_Hour PAGE_INT_SIZE * FLASH_ADDR_STEP_PAGENUM
+	DEBUG_LOG("==============\n");
+	if(mFlash.mStep.step_num < Max_Hour)
+	{
+//		mFlash.mStep.stepCur[0] +=1 ;
+		uint32_t step = app_step_GetStep_L() + app_step_GetStep_R(); //获取左右鞋步数
+		
+		flash_data =  ((step<<24 & 0xff000000) | (step<<8 & 0x00ff0000) | (step>>8 & 0x0000ff00) | (step>>24 & 0x000000ff));
+		
+	  //清空步数的flash step内容
+	  if(1 == FlashStep_ClearFlag){
+			if(Flash_DeleteAllStep() != ZONE_OP_SUCCESS){
+				Except_TxError(EXCEPT_DATEStep,"clear step fail");
+				return ZONE_ERROR_WRITE_FAIL;
+			}
+			mFlash.mStep.step_num  = 0;
+			FlashStep_ClearFlag = 0;
+	  }
+		
+		DEBUG_LOG("step %d,flash_data:%d,step_num:%d\n",step, flash_data,mFlash.mStep.step_num);
+		err_code = sdflash_write((uint32_t*)(FLASH_START_ADDR_STEP + (mFlash.mStep.step_num * 4)), &flash_data, 1);
+		if(err_code != FLASH_OP_SUCCESS)return ZONE_ERROR_WRITE_FAIL;
+		
+		mFlash.mStep.step_num++;
+		mFlash.mStep.step[0] = mFlash.mStep.stepCur[0];
+		mFlash.mStep.step[1] = mFlash.mStep.stepCur[1];	
+
+		if(Flash_SaveInfomation() != ZONE_OP_SUCCESS){
+			Except_TxError(EXCEPT_FLASH,"save information fail");
+		}
+
+		uint8_t i=4;
+		uint8_t length =0;
+		for(;i<5;i++){
+		 if(MINIFDS_SUCCESS == pm_get_length(&information,All_Falsh_value[i].name,strlen(All_Falsh_value[i].name),&length)){
+				if(length == All_Falsh_value[i].length){
+					 if(MINIFDS_SUCCESS == pm_find(&information,All_Falsh_value[i].name,strlen(All_Falsh_value[i].name),(uint8_t *)All_Falsh_value[i].value,&length))
+					 {
+						 DEBUG_LOG(">>>>>>>>%s value:%d\n",All_Falsh_value[i].name,mFlash.mStep.stepCur[0]);
+					 }
+				}
+		 }
+  }
+		
+		
+	}
+	else return ZONE_ERROR_WRITE_FAIL;
+	return ZONE_OP_SUCCESS;
+}
+
+/**
+ @brief 删除所有步数
+ @param 无
+ @return 错误代码
+*/
+uint32_t Flash_DeleteAllStep(void)
+{
+	uint32_t errcode = ZONE_OP_SUCCESS;
+	uint32_t pag_addr = 0;
+	
+	for(uint8_t i=0;i<FLASH_ADDR_STEP_PAGENUM;i++){
+		pag_addr = (FLASH_START_ADDR_STEP +i*FLASH_PAGE_SIZE);
+		errcode = sdflash_page_erase(pag_addr);
+		if(errcode != NRF_SUCCESS)
+		   return ZONE_ERROR_ERASE_FAIL;
+	}
+	return ZONE_OP_SUCCESS;
+}
+
+/**
+ @brief 读取一个区域中指定位置的数据
+ @param destination_addr[in] - 读取区域的地址
+ @param pData[in] - 指向存储的buff
+ @param dataLen[in] - 读取的长度,单位字节
+ @return 错误代码
+*/ 
+uint32_t flash_Data_Read(uint32_t addr, uint32_t *pData, uint32_t dataLen){
+	 if(pData != NULL && dataLen != 0){
+		  if(addr < START_FSTORAGE_ADDR || addr >= END_FSTORAGE_ADDR){
+				 return  ZONE_ERROR_ADDRESS_FAIL;
+			}
+			else 
+				 memcpy(pData, (uint32_t*)addr, dataLen);
+	 }
+	 return ZONE_OP_SUCCESS;
+}
+
+/**
+ @brief 存储基本信息
+ @param 无
+ @return 错误代码
+*/
+uint32_t Flash_SaveInfomation(void)
+{
+	char result =0;
+	for(uint8_t i =0;i<MAX_mflash_param_LENGTH;i++){
+		 result = pm_update(&information,All_Falsh_value[i].name,strlen(All_Falsh_value[i].name),(uint8_t *)All_Falsh_value[i].value,All_Falsh_value[i].length);
+		 if(result != MINIFDS_SUCCESS){
+			 return ZONE_ERROR_WRITE_FAIL;
+		 }
+	}
+	return ZONE_OP_SUCCESS;
+}
+
+/**
+ @brief 保存日志信息
+ @param[in] id    Fault identifier. See @ref NRF_FAULT_IDS.
+ @param[in] pc    The program counter of the instruction that triggered the fault, or 0 if
+                  unavailable.
+ @param[in] info  Optional additional information regarding the fault. The value of the @p id
+                  parameter dictates how to interpret this parameter. Refer to the documentation
+                  for each fault identifier (@ref NRF_FAULT_IDS and @ref APP_ERROR_FAULT_IDS) for
+                  details about interpreting @p info.
+ @return 错误代码
+*/
+uint32_t Flash_SaveLog(uint32_t id, uint32_t pc, uint32_t info)
+{
+	memset((uint8_t*)(&mFlash.mFlashLog),0,sizeof(FlashLog));
+	mFlash.mFlashLog.Errorflag =1;
+	switch (id)
+ {
+	#if defined(SOFTDEVICE_PRESENT) && SOFTDEVICE_PRESENT
+					case NRF_FAULT_ID_SD_ASSERT:
+							memcpy(mFlash.mFlashLog.logData,"SD: ASSERTION FAILED\r\n",MaxLength(sizeof("SD: ASSERTION FAILED\r\n"),sizeof(mFlash.mFlashLog.logData)));
+							break;
+					case NRF_FAULT_ID_APP_MEMACC:
+							memcpy(mFlash.mFlashLog.logData,"SD: INVALID MEMORY ACCESS\r\n",MaxLength(sizeof("SD: INVALID MEMORY ACCESS\r\n"),sizeof(mFlash.mFlashLog.logData)));
+							break;
+	#endif
+					case NRF_FAULT_ID_SDK_ASSERT:
+					{
+							assert_info_t * p_info = (assert_info_t *)info;
+							sprintf((char *)mFlash.mFlashLog.logData,"ASSERTION FAILED %s:%u\r\n",
+														p_info->p_file_name,
+														p_info->line_num);
+							break;
+					}
+					case NRF_FAULT_ID_SDK_ERROR:
+					{
+							error_info_t * p_info = (error_info_t *)info;
+						  
+						  sprintf((char *)mFlash.mFlashLog.logData,"error:%u,%s:%u\r\n",
+														p_info->err_code,
+														p_info->p_file_name,
+														p_info->line_num);
+							DEBUG_LOG(">>>>>err code :%d,%s",p_info->err_code,mFlash.mFlashLog.logData);
+
+							break;
+					}
+					default:
+							sprintf((char *)mFlash.mFlashLog.logData,"UNKNOWN FAULT 0x%08X\n", pc);
+							break;
+	}
+ 
+	return Flash_SaveInfomation();
+}
+
+/**
+ @brief 返回主机标志位
+ @param 无
+ @return 主机标志位
+*/
+uint8_t Get_isHost(void)
+{
+	return mFlash.isHost;
+}
+
+
+/**
+ @brief 测试halflash接口
+ @param 无
+ @return 无
+*/
+void TestHalFlashInterface(void)
+{
+
+//	uint2_t i; 
+//	Flash_t m_testflash;
+//	FlashBackup_t m_testbackup;
+	
+//	//测试基本信息和备份信息的写入和读取
+//	for(i=0;i<10000;i++)
+//	{
+//		mFlash.mStep.step_num = i;
+//		DEBUG_LOG("Flash_SaveInfomation[%d]:%d \n",i,Flash_SaveInfomation());
+//		
+//		DEBUG_LOG("Flash_SaveBackup[%d]:%d \n",i,Flash_SaveBackup());
+//	}
+//	
+//	DEBUG_LOG("Flash_GetInfomation[%d]:%d \n",i,Flash_GetInfomation(&m_testflash));
+//	DEBUG_LOG("m_testflash:%d \n",m_testflash.mStep.num);
+//	
+//	DEBUG_LOG("Flash_GetBackup[%d]:%d \n",i,Flash_GetBackup(&m_testbackup));
+//	DEBUG_LOG("m_testbackup:%d \n",m_testbackup.hardVersion);
+	
+}
+
+

+ 365 - 0
shoe_mcu2.2.1_new_v2/app/app_flash.c

@@ -0,0 +1,365 @@
+#include "app_flash.h"
+#include "bsp_wdt.h"
+#include "exception.h"
+#include "system.h"
+#include "hal_minifds.h"
+#include "nrf_sdh_soc.h"
+#include "app_step.h"
+#include "nrf_pwr_mgmt.h"
+#include "bsp_flash.h"
+
+/*************************************
+ *DEFINITION
+ */
+#define FLASH_HEAD									        0xAA5555AA
+
+#define FLASH_START_ADDR_INFOR 0x00074000UL
+#define FLASH_END_ADDR_INFOR   0x00076000UL
+#define FLASH_ADDR_INFOR_PAGENUM 		2
+
+#define FLASH_START_ADDR_STEP  0x00076000UL
+#define FLASH_END_ADDR_STEP    0x00077FFFUL
+#define FLASH_ADDR_STEP_PAGENUM 		2
+
+#define MaxLength(a,b) 							a>b?a:b
+
+typedef struct t_mflash_param_type{
+  const char    *name;	   //参数名字
+	void    *value;          //数据指针
+	const uint8_t length;    //数据长度
+}mflash_param_type;
+
+#define MAX_mflash_param_LENGTH 27
+
+const mflash_param_type All_Falsh_value[MAX_mflash_param_LENGTH]={
+{"inforhead",&mFlash.head,4},
+{"macHost",mFlash.macHost,6},
+{"IsHost",&mFlash.isHost,1},
+
+{"startTime",mFlash.mStep.startTime,8},
+{"stepCur",mFlash.mStep.stepCur,8},
+
+{"step",mFlash.mStep.step,8},
+{"step_num",&mFlash.mStep.step_num,4},
+{"C_isConfig",&mFlash.mClient.isConfig,1},
+{"C_hard",&mFlash.mClient.hardVersion,4},
+{"C_sotf",&mFlash.mClient.sotfVersion,2},
+{"C_macAddr",&mFlash.mClient.macAddr,6},
+{"Errorflag",&mFlash.mFlashLog.Errorflag,1},
+{"logData",mFlash.mFlashLog.logData,50},
+{"PB_BR_V2E",&mFlash.mbattercb_t.preBestResult_Voltage2power,4},
+{"PB_BR_C2P",&mFlash.mbattercb_t.preBestResult_chargeV2P_f,4},
+{"PB_P_MAH",&mFlash.mbattercb_t.P_mAh,4},
+{"PB_KG",   &mFlash.mbattercb_t.kg,4},
+{"PP2",   &mFlash.mbattercb_t.P2,4},
+{"PP1",   &mFlash.mbattercb_t.P1,4},
+{"PCAP_MAH",&mFlash.mbattercb_t.Battery_capacity_mAh,4},
+{"PTP4056",&mFlash.mbattercb_t.adc_tp4056_power,4},
+{"PINIT", &mFlash.mbattercb_t.init,1},
+{"PSTA",  &mFlash.mbattercb_t.sta,1},
+{"PCV2P_INIT",&mFlash.mbattercb_t.chargeV2P_f_init,1},
+{"PV2P_INIT",&mFlash.mbattercb_t.Voltage2power_init,1},
+
+{"Safe_cnt",&mFlash.Safe_cnt,1},
+{"RestartCnt",&mFlash.RestartCnt,1},
+};
+
+DEFINE_MINIINF(information, FLASH_START_ADDR_INFOR, FLASH_END_ADDR_INFOR, sdflash_write, sdflash_page_erase);
+
+Flash_t 				mFlash={0};
+
+/****************************************************接口****************************************************/
+void Flash_Initialize(void)
+{
+	uint8_t i = 0;
+	uint8_t length =0;
+	minfds_init(&information);
+  for(i =0;i<MAX_mflash_param_LENGTH;i++){
+		 if(MINIFDS_SUCCESS == pm_get_length(&information,All_Falsh_value[i].name,strlen(All_Falsh_value[i].name),&length)){
+				if(length == All_Falsh_value[i].length){
+					 pm_find(&information,All_Falsh_value[i].name,strlen(All_Falsh_value[i].name),(uint8_t *)All_Falsh_value[i].value,&length);
+				}
+				else{
+					 pm_delete(&information,All_Falsh_value[i].name,strlen(All_Falsh_value[i].name));
+					 pm_add(&information,All_Falsh_value[i].name,strlen(All_Falsh_value[i].name),(uint8_t *)All_Falsh_value[i].value,All_Falsh_value[i].length);
+				}
+		 }
+  }
+	
+	DEBUG_LOG("Flash head read(%04X).\n",mFlash.head);
+	if(mFlash.head !=FLASH_HEAD){  DEBUG_LOG("Flash first init(%04X),write infomation to flash.\n",mFlash.head);
+		
+		Flash_DeleteAllInfor();
+		Flash_DeleteAllStep();
+		
+		memset((uint8_t*)(&mFlash),0,sizeof(Flash_t));
+		mFlash.head = FLASH_HEAD;
+		mFlash.isHost = _IS_HOST;
+		
+		for(i =0;i<MAX_mflash_param_LENGTH;i++){
+		   pm_add(&information,All_Falsh_value[i].name,strlen(All_Falsh_value[i].name),(uint8_t *)All_Falsh_value[i].value,All_Falsh_value[i].length);
+    }
+		
+		mFlash.head =0;
+		for(i =0;i<MAX_mflash_param_LENGTH;i++){
+			if(MINIFDS_SUCCESS == pm_get_length(&information,All_Falsh_value[i].name,strlen(All_Falsh_value[i].name),&length)){
+				if(length == All_Falsh_value[i].length)
+				{
+					pm_find(&information,All_Falsh_value[i].name,strlen(All_Falsh_value[i].name),(uint8_t *)All_Falsh_value[i].value,&length);
+				}
+			 }
+		 }
+//		
+		DEBUG_LOG("Flash head second read(%04X).\n",mFlash.head);
+		if(mFlash.head != FLASH_HEAD){ 
+			DEBUG_LOG("Flash write head fail.\n");
+			Except_TxError(EXCEPT_FLASH,"Flash write head fail");
+			return;
+		}
+		DEBUG_LOG("System reset...\n",mFlash.head);
+		for(uint8_t i =0;i<6;i++){
+			nrf_delay_ms(500);
+			feed_watchdog();
+		}
+		NVIC_SystemReset();
+	}
+
+	DEBUG_LOG("err code :%s\n",mFlash.mFlashLog.logData);
+	DEBUG_LOG("Flash init ok.\n");
+	
+	//TestHalFlashInterface();
+}
+
+
+/**
+ @brief 设置清空flash的标志
+ @param 无
+ @return 无
+*/
+static uint8_t FlashStep_ClearFlag =0;
+void flash_SetClearStepFlag(void){
+	FlashStep_ClearFlag =1;
+}
+
+uint32_t flash_GetStep_StartAddress(void){
+	return FLASH_START_ADDR_STEP;
+}
+
+/**
+ @brief 存储步数
+ @param 无
+ @return 错误代码
+*/
+uint32_t Flash_SaveStep(void)
+{
+	flash_OPER_Result err_code;
+	uint32_t 				flash_data;
+	
+	#define Max_Hour PAGE_INT_SIZE * FLASH_ADDR_STEP_PAGENUM
+
+	if(mFlash.mStep.step_num < Max_Hour)
+	{
+//		mFlash.mStep.stepCur[0] +=1 ;
+		uint32_t step = app_step_GetStep_L() + app_step_GetStep_R(); //获取左右鞋步数
+		
+		flash_data =  ((step<<24 & 0xff000000) | (step<<8 & 0x00ff0000) | (step>>8 & 0x0000ff00) | (step>>24 & 0x000000ff));
+		
+	  //清空步数的flash step内容
+	  if(1 == FlashStep_ClearFlag){
+			if(Flash_DeleteAllStep() != ZONE_OP_SUCCESS){
+				Except_TxError(EXCEPT_DATEStep,"clear step fail");
+				return ZONE_ERROR_WRITE_FAIL;
+			}
+			mFlash.mStep.step_num  = 0;
+			FlashStep_ClearFlag = 0;
+	  }
+		
+		DEBUG_LOG("step %d,flash_data:%d,step_num:%d\n",step, flash_data,mFlash.mStep.step_num);
+		err_code = sdflash_write((uint32_t*)(FLASH_START_ADDR_STEP + (mFlash.mStep.step_num * 4)), &flash_data, 1);
+		if(err_code != FLASH_OP_SUCCESS)return ZONE_ERROR_WRITE_FAIL;
+		
+		mFlash.mStep.step_num++;
+		mFlash.mStep.step[0] = mFlash.mStep.stepCur[0];
+		mFlash.mStep.step[1] = mFlash.mStep.stepCur[1];	
+
+		if(Flash_SaveInfomation() != ZONE_OP_SUCCESS){
+			Except_TxError(EXCEPT_FLASH,"save information fail");
+		}
+
+		uint8_t i=4;
+		uint8_t length =0;
+		for(;i<5;i++){
+		 if(MINIFDS_SUCCESS == pm_get_length(&information,All_Falsh_value[i].name,strlen(All_Falsh_value[i].name),&length)){
+				if(length == All_Falsh_value[i].length){
+					 if(MINIFDS_SUCCESS == pm_find(&information,All_Falsh_value[i].name,strlen(All_Falsh_value[i].name),(uint8_t *)All_Falsh_value[i].value,&length))
+					 {
+						 DEBUG_LOG(">>>>>>>>%s value:%d\n",All_Falsh_value[i].name,mFlash.mStep.stepCur[0]);
+					 }
+				}
+		 }
+  }
+		
+		
+	}
+	else return ZONE_ERROR_WRITE_FAIL;
+	return ZONE_OP_SUCCESS;
+}
+
+/**
+ @brief 删除所有步数
+ @param 无
+ @return 错误代码
+*/
+uint32_t Flash_DeleteAllStep(void)
+{
+	uint32_t errcode = ZONE_OP_SUCCESS;
+	uint32_t pag_addr = 0;
+	
+	for(uint8_t i=0;i<FLASH_ADDR_STEP_PAGENUM;i++){
+		pag_addr = (FLASH_START_ADDR_STEP +i*FLASH_PAGE_SIZE);
+		errcode = sdflash_page_erase(pag_addr);
+		if(errcode != NRF_SUCCESS)
+		   return ZONE_ERROR_ERASE_FAIL;
+	}
+	return ZONE_OP_SUCCESS;
+}
+
+/**
+ @brief 删除infromation的数据
+ @param 无
+ @return 错误代码
+*/
+uint32_t Flash_DeleteAllInfor(void)
+{
+	uint32_t errcode = ZONE_OP_SUCCESS;
+	uint32_t pag_addr = 0;
+	
+	for(uint8_t i=0;i<FLASH_ADDR_INFOR_PAGENUM;i++){
+		pag_addr = (FLASH_START_ADDR_INFOR +i*FLASH_PAGE_SIZE);
+		errcode = sdflash_page_erase(pag_addr);
+		if(errcode != NRF_SUCCESS)
+		   return ZONE_ERROR_ERASE_FAIL;
+	}
+	return ZONE_OP_SUCCESS;
+}
+
+
+/**
+ @brief 读取一个区域中指定位置的数据
+ @param destination_addr[in] - 读取区域的地址
+ @param pData[in] - 指向存储的buff
+ @param dataLen[in] - 读取的长度,单位字节
+ @return 错误代码
+*/ 
+uint32_t flash_Data_Read(uint32_t addr, uint32_t *pData, uint32_t dataLen){
+	 if(pData != NULL && dataLen != 0){
+		  if(addr < START_FSTORAGE_ADDR || addr >= END_FSTORAGE_ADDR){
+				 return  ZONE_ERROR_ADDRESS_FAIL;
+			}
+			else 
+				 memcpy(pData, (uint32_t*)addr, dataLen);
+	 }
+	 return ZONE_OP_SUCCESS;
+}
+
+/**
+ @brief 存储基本信息
+ @param 无
+ @return 错误代码
+*/
+uint32_t Flash_SaveInfomation(void)
+{
+	char result =0;
+	for(uint8_t i =0;i<MAX_mflash_param_LENGTH;i++){
+		 result = pm_update(&information,All_Falsh_value[i].name,strlen(All_Falsh_value[i].name),(uint8_t *)All_Falsh_value[i].value,All_Falsh_value[i].length);
+		 if(result != MINIFDS_SUCCESS){
+			 DEBUG_LOG("Flash_SaveInfomation fail name %s,result %d\r\n",All_Falsh_value[i].name,result);
+			 return ZONE_ERROR_WRITE_FAIL;
+		 }
+	}
+	return ZONE_OP_SUCCESS;
+}
+
+/**
+ @brief 保存日志信息
+ @param[in] id    Fault identifier. See @ref NRF_FAULT_IDS.
+ @param[in] pc    The program counter of the instruction that triggered the fault, or 0 if
+                  unavailable.
+ @param[in] info  Optional additional information regarding the fault. The value of the @p id
+                  parameter dictates how to interpret this parameter. Refer to the documentation
+                  for each fault identifier (@ref NRF_FAULT_IDS and @ref APP_ERROR_FAULT_IDS) for
+                  details about interpreting @p info.
+ @return 错误代码
+*/
+uint32_t Flash_SaveLog(uint32_t id, uint32_t pc, uint32_t info)
+{
+	memset((uint8_t*)(&mFlash.mFlashLog),0,sizeof(FlashLog));
+	mFlash.mFlashLog.Errorflag =1;
+	switch (id)
+ {
+	#if defined(SOFTDEVICE_PRESENT) && SOFTDEVICE_PRESENT
+					case NRF_FAULT_ID_SD_ASSERT:
+							memcpy(mFlash.mFlashLog.logData,"SD: ASSERTION FAILED\r\n",MaxLength(sizeof("SD: ASSERTION FAILED\r\n"),sizeof(mFlash.mFlashLog.logData)));
+							break;
+					case NRF_FAULT_ID_APP_MEMACC:
+							memcpy(mFlash.mFlashLog.logData,"SD: INVALID MEMORY ACCESS\r\n",MaxLength(sizeof("SD: INVALID MEMORY ACCESS\r\n"),sizeof(mFlash.mFlashLog.logData)));
+							break;
+	#endif
+					case NRF_FAULT_ID_SDK_ASSERT:
+					{
+							assert_info_t * p_info = (assert_info_t *)info;
+							sprintf((char *)mFlash.mFlashLog.logData,"ASSERTION FAILED %s:%u\r\n",
+														p_info->p_file_name,
+														p_info->line_num);
+							break;
+					}
+					case NRF_FAULT_ID_SDK_ERROR:
+					{
+							error_info_t * p_info = (error_info_t *)info;
+						  
+						  sprintf((char *)mFlash.mFlashLog.logData,"error:%u,%s:%u\r\n",
+														p_info->err_code,
+														p_info->p_file_name,
+														p_info->line_num);
+							DEBUG_LOG(">>>>>err code :%d,%s",p_info->err_code,mFlash.mFlashLog.logData);
+
+							break;
+					}
+					default:
+							sprintf((char *)mFlash.mFlashLog.logData,"UNKNOWN FAULT 0x%08X\n", pc);
+							break;
+	}
+ 
+	return Flash_SaveInfomation();
+}
+
+/**
+ @brief 测试halflash接口
+ @param 无
+ @return 无
+*/
+void TestHalFlashInterface(void)
+{
+
+//	uint2_t i; 
+//	Flash_t m_testflash;
+//	FlashBackup_t m_testbackup;
+	
+//	//测试基本信息和备份信息的写入和读取
+//	for(i=0;i<10000;i++)
+//	{
+//		mFlash.mStep.step_num = i;
+//		DEBUG_LOG("Flash_SaveInfomation[%d]:%d \n",i,Flash_SaveInfomation());
+//		
+//		DEBUG_LOG("Flash_SaveBackup[%d]:%d \n",i,Flash_SaveBackup());
+//	}
+//	
+//	DEBUG_LOG("Flash_GetInfomation[%d]:%d \n",i,Flash_GetInfomation(&m_testflash));
+//	DEBUG_LOG("m_testflash:%d \n",m_testflash.mStep.num);
+//	
+//	DEBUG_LOG("Flash_GetBackup[%d]:%d \n",i,Flash_GetBackup(&m_testbackup));
+//	DEBUG_LOG("m_testbackup:%d \n",m_testbackup.hardVersion);
+	
+}
+
+

+ 120 - 0
shoe_mcu2.2.1_new_v2/app/app_flash.h

@@ -0,0 +1,120 @@
+#ifndef __APP_FLASH_H__
+#define __APP_FLASH_H__
+/*************************************
+ *INCLUDES
+ */
+#include "exception.h"
+#include "app_power.h"
+#include "nrf_gpio.h"
+#include "nrf_delay.h"
+#include "nrf_sdm.h"
+
+//ERROR CODE
+#define ZONE_OP_SUCCESS										0x00																//ZONE操作成功
+#define ZONE_ERROR_READ_FAIL							(ZONE_OP_SUCCESS+0x01)							//读取该区域失败
+#define ZONE_ERROR_WRITE_FAIL							(ZONE_OP_SUCCESS+0x02)							//写入该区域失败
+#define ZONE_ERROR_ERASE_FAIL							(ZONE_OP_SUCCESS+0x03)							//擦除该区域失败
+#define ZONE_ERROR_ADDRESS_FAIL						(ZONE_OP_SUCCESS+0x04)							//输入地址越界
+
+/********************************************
+*API FUCTIONS
+*/
+
+//size:36
+typedef struct _FlashStep{
+	uint8_t 	startTime[8];		   //当前时间
+	uint32_t 	stepCur[2];				 //当前永久步数
+	uint32_t 	step[2];					 //每小时记录的左右鞋永久步数0左1右
+	uint32_t 	step_num;					 //已经记录的每小时步数数量
+}FlashStep_t;
+//size:12
+typedef struct _FlashClient{
+	uint8_t 	isConfig;
+	uint32_t 	hardVersion;
+	uint16_t 	sotfVersion;
+	uint8_t	 	macAddr[6];
+}FlashClient_t;
+//size:
+typedef struct _FlashLog{
+	uint8_t Errorflag;
+	uint8_t logData[50];
+}FlashLog;
+//size:64
+typedef struct _Flash_Param{
+  uint32_t       head;	
+	uint8_t  			isHost;
+	uint8_t 			macHost[6];
+	FlashStep_t 	mStep;
+	FlashClient_t mClient;
+	FlashLog 			mFlashLog;
+	uint8_t       Safe_cnt;
+	battercb_t 		mbattercb_t;
+	uint8_t       RestartCnt;
+}Flash_t;
+
+
+extern Flash_t mFlash;
+
+
+/*1.当新API读到旧的数据的时候,新API多的参数用默认值填充,写回的时候按照新API的格式写回。(向后兼容)
+  2.当旧API读到新数据,自己不认识的那段buff,要保存起来,写回的时候,将这段buff原样memcpy。(向前兼容,没实现)
+*/
+ 
+/********************************************
+ *API FUCTIONS
+ */
+void Flash_Initialize(void);
+//存储步数
+uint32_t Flash_SaveStep(void);
+//获取步数区域首地址
+uint32_t Flash_GetStepZoneStartAddr(void);
+
+//删除所有步数
+uint32_t Flash_DeleteAllStep(void);
+//删除information的数据
+uint32_t Flash_DeleteAllInfor(void);
+	
+//存储基本信息
+uint32_t Flash_SaveInfomation(void);
+//获取脚步的起始地址
+uint32_t flash_GetStep_StartAddress(void);
+//读取指定flash的内容
+uint32_t flash_Data_Read(uint32_t addr, uint32_t *pData, uint32_t dataLen);
+//保存日志信息
+uint32_t Flash_SaveLog(uint32_t id, uint32_t pc, uint32_t info);
+
+//测试接口
+void TestHalFlashInterface(void);
+
+void flash_SetClearStepFlag(void);
+
+#endif
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+ 299 - 0
shoe_mcu2.2.1_new_v2/app/app_game.c

@@ -0,0 +1,299 @@
+#include "app_game.h"
+#include "usr_config.h"
+#include "bsp_time.h"
+#include "system.h"
+#include "hal_mt.h"
+#include "hal_battery.h"
+#include "app_charge.h"
+#include "hal_ble_client.h"
+#include "hal_ble_host.h"
+#include "nrf_delay.h"
+#include "app_flash.h"
+#include "ble_comm.h"
+#include "exception.h"
+#include "bll_imu.h"
+#include "hal_led.h"
+#include "pdrStatus.h"
+
+/********************** 函数声明区 *************************/
+
+//游戏模式
+static const bll_imu_one_way_param_t game_front_param={
+	.acc_power_mode 						= FML_IMU_ACC_POWER_MODE_NORMAL,						//前脚 - 加速度正常模式
+	.gry_power_mode 						= FML_IMU_GRY_POWER_MODE_NORMAL,						//前脚 - 陀螺仪正常模式
+	.timestamp_resolution 			= FML_IMU_TIMESTAMP_25US,										//前脚 - 时间戳25US精度
+	.timestamp_switch 					= FML_IMU_TIMESTAMP_ON,											//前脚 - 时间戳开启
+	.acc_fs 										= FML_IMU_ACC_FS_16G,												//前脚 - 加速度量程 - 16G
+	.gry_fs 										= FML_IMU_GRY_FS_2000DPS,										//前脚 - 陀螺仪量程 - 2000DPS
+	.mag_fs 										= FML_IMU_MAG_FS_30GS,											//前脚 - 地磁计量程 - 30GS
+	.acc_odr 									  = FML_IMU_ACC_ODR_104HZ,										//前脚 - 加速度采样频率 - 104HZ
+	.gry_odr 									  = FML_IMU_GRY_ODR_104HZ,										//前脚 - 陀螺仪采样频率 - 104HZ
+	.mag_odr 									  = FML_IMU_MAG_ODR_200HZ,										//前脚 - 地磁计采样频率 - 200HZ
+	.fifo_odr 									= FML_IMU_FIFO_ODR_104HZ,	
+};
+
+static const bll_imu_one_way_param_t game_back_param={
+	.acc_power_mode 						= FML_IMU_ACC_POWER_MODE_NORMAL,						//后脚 - 加速度正常模式
+	.gry_power_mode 						= FML_IMU_GRY_POWER_MODE_NORMAL,						//后脚 - 陀螺仪正常模式
+	.timestamp_resolution 			= FML_IMU_TIMESTAMP_25US,										//后脚 - 时间戳25US精度
+	.timestamp_switch 					= FML_IMU_TIMESTAMP_OFF,										//后脚 - 时间戳关闭
+	.acc_fs 										= FML_IMU_ACC_FS_16G,											  //后脚 - 加速度量程 - 16G
+	.gry_fs 										= FML_IMU_GRY_FS_2000DPS,										//后脚 - 陀螺仪量程 - 2000DPS
+	.mag_fs 										= FML_IMU_MAG_FS_30GS,											//后脚 - 地磁计量程 - 30GS
+	.acc_odr 										= FML_IMU_ACC_ODR_OFF,											//后脚 - 加速度采样频率 - 关闭
+	.gry_odr 										= FML_IMU_GRY_ODR_OFF,											//后脚 - 陀螺仪采样频率 - 关闭
+	.mag_odr 										= FML_IMU_MAG_ODR_200HZ,										//后脚 - 地磁计采样频率 - 200HZ
+	.fifo_odr 									= FML_IMU_FIFO_ODR_OFF,	
+};
+
+static const bll_imu_param_t game_bll_imu_param_t={
+	.config_param[FML_IMU_DIR_FRONT] = &game_front_param,
+	.config_param[FML_IMU_DIR_BACK] =  &game_back_param,
+};
+
+typedef struct game_manager{
+ uint8_t clientCnt;       //右鞋游戏模式的标志位
+ uint8_t right_discnt;    //右鞋断开连接计数器
+ uint8_t client_discnt;   //主机连接断开计数器
+ uint8_t Signal;          //收到主机的游戏指令
+ uint8_t HeartCnt;        //游戏模式心跳维护,左鞋
+ uint8_t GameMode;        //是否在游戏
+}game_manager_t;
+
+static game_manager_t game_manager ={0};
+
+#define IMU_MAX_GROUP_NUM 10
+
+static int16_t 	acc_front[IMU_MAX_GROUP_NUM][3];
+static int16_t  gry_front[IMU_MAX_GROUP_NUM][3];
+static int16_t	mag6310_front[IMU_MAX_GROUP_NUM][3];
+
+static int16_t	mag6310_back[3];
+static int32_t	timestamp_front[IMU_MAX_GROUP_NUM];
+static uint8_t  rssi;
+
+static uint8_t  IMU_STATUS; //记录状态用来重新记录时间戳
+
+static int32_t  timestamp;
+
+static int32_t  last_timestamp;
+
+static void process_imu_data_front(int front_index)
+{
+	if(IMU_STATUS != 1){
+		IMU_STATUS = 1;
+		last_timestamp = timestamp_front[0];
+		timestamp = 0;
+	}
+	
+	if(front_index >IMU_MAX_GROUP_NUM)return;
+	for(int i = 0; i < front_index; i++)
+	{
+		int32_t dt = timestamp_front[i] - last_timestamp;
+		
+		if(dt > 20000 || dt < 0)
+		{
+			dt = 10000;
+		}
+		
+		timestamp += dt;
+		
+//		DEBUG_LOG("timestamp_front[i] - last_timestamp : %d;  i = %d NRF_RTC0->COUNTER:%d\r\n", timestamp_front[i] - last_timestamp, i,NRF_RTC0->COUNTER);
+		
+		last_timestamp = timestamp_front[i];
+		
+//		DEBUG_LOG("timestamp_front[i] : %d;  i = %d\r\n", timestamp_front[i], i);
+		
+		IMU_Process_motion_queue(mFlash.isHost, timestamp, acc_front[i],
+		gry_front[i],mag6310_front[i], mag6310_back, rssi);
+	}
+}
+
+void app_game_SetClientGameMode(void)
+{
+	if(game_manager.clientCnt != 3) game_manager.clientCnt = 3;
+}
+
+uint8_t app_game_GetGameMode(void)
+{
+	return game_manager.GameMode;
+}
+
+static void cb_BLE_Client_R_GAMEMODE(void* handle)
+{
+	BLE_Client_Rx_t* target = handle;
+	game_manager.Signal = target->pDat[0];
+	if(game_manager.Signal){
+		game_manager.HeartCnt =0;
+		bll_imu_Resume_config_param(&game_bll_imu_param_t);
+		//是否上传原始数据
+		if(1 == game_manager.Signal)IMU_Dtalige_Rowdata_OFF();
+		else if(2 == game_manager.Signal)IMU_Dtalige_Rowdata_ON();
+	}else{
+		bll_imu_Resume_unregister_config_param(&game_bll_imu_param_t);
+	}
+	
+	BLE_Host_Tx_Send(0,BLE_GAMEMODE,&game_manager.Signal,1);
+	DEBUG_LOG(">>>>>>>>>>cb_BLE_Client_R_GAMEMODE:%d\r\n",game_manager.Signal);
+}
+
+//通知右鞋进入或者退出游戏模式
+static void app_game_notify_host(uint8_t mode){
+	uint8_t clientMode = mode;
+	BLE_Host_Tx_Send(0,BLE_GAMEMODE,&clientMode,1);
+}
+
+//测试使用,游戏模式下 1S亮绿灯20ms.
+static void app_game_led(uint8_t gamemode){
+	static uint8_t led_state =0;
+	static uint8_t temp =0;
+	if(gamemode){
+		 temp++;
+		 if(temp == 100){
+			  if(led_state){led_state =0;
+					LED_Start(LED_RUN,COLOR_GREEN);
+			  }
+			  else {led_state =1;
+					LED_Start(LED_RUN,COLOR_BLACK);
+			  }
+	   }
+		 if(temp > 102){temp =0;
+			 LED_Stop(LED_RUN);
+		 }
+	}else{
+		 if(2 == led_state){
+		    LED_Stop(LED_RUN);
+		 }
+	}
+}
+
+//IMU数据回调
+static void gamemode_data_notify_cb(uint32_t dir_bit)
+{
+	int16_t 				group_num = 0;
+	bll_imu_data_t data={0};
+	
+	if(0 == app_game_GetGameMode())return;
+	
+	if((dir_bit >> BLL_IMU_DIR_FRONT) & 0x01){
+		rssi = 0-host_get_rssi();
+		group_num = bll_imu_get_data_num(BLL_IMU_DIR_FRONT);
+		if(group_num >IMU_MAX_GROUP_NUM)return;
+		for(int i=0;i<group_num;i++){
+			bll_imu_get_data(BLL_IMU_DIR_FRONT, i, &data);
+			gry_front[i][0] = data.gry[0];gry_front[i][1] = data.gry[1];gry_front[i][2] = data.gry[2];
+			acc_front[i][0] = data.acc[0];acc_front[i][1] = data.acc[1];acc_front[i][2] = data.acc[2];
+			mag6310_front[i][0] = data.mag[0];mag6310_front[i][1] = data.mag[1];mag6310_front[i][2] = data.mag[2];
+			timestamp_front[i] = data.fifo_timestamp;
+		}
+		
+		if(bll_imu_get_data_num(BLL_IMU_DIR_BACK) >= 1){
+			bll_imu_get_data(BLL_IMU_DIR_BACK, 0, &data);
+			mag6310_back[0] = data.mag[0];mag6310_back[1] = data.mag[1];mag6310_back[2] = data.mag[2];
+		}
+		
+		if(mFlash.isHost){
+				process_imu_data_front(group_num);
+			}else if(Slave_Get7_5ms_interval()){
+				process_imu_data_front(group_num);
+			}
+			app_game_led(1);
+	}
+	
+}
+
+static void app_game_Process(void)
+{
+	static uint8_t configcnt = 0;
+  static uint8_t state = 0;
+	uint8_t front_CS =0,back_CS =0;
+	if(game_manager.clientCnt>0) game_manager.clientCnt--;
+	switch(state){
+		case 0:{
+						if(game_manager.Signal){
+								front_CS = bll_imu_query_config_param_is_ready(BLL_IMU_DIR_FRONT,&game_bll_imu_param_t);
+								back_CS  = bll_imu_query_config_param_is_ready(BLL_IMU_DIR_BACK,&game_bll_imu_param_t);
+								DEBUG_LOG("front_CS:%d back_CS:%d\r\n",front_CS,back_CS);
+								if(BLL_IMU_CONFIG_FINISH == front_CS && BLL_IMU_CONFIG_FINISH == back_CS){
+									state =1;
+									game_manager.GameMode =1;
+								}
+								else  if(BLL_IMU_CONFIG_DOING != front_CS || BLL_IMU_CONFIG_DOING != back_CS){
+									 bll_imu_Resume_config_param(&game_bll_imu_param_t);
+									 if(++configcnt >= 20){configcnt =0;
+											game_manager.Signal =0;
+											bll_imu_Resume_unregister_config_param(&game_bll_imu_param_t);
+											Except_TxError(EXCEPT_GAME,"shoes into game mode fail");
+									 }
+								}
+								if(0 != game_manager.HeartCnt)game_manager.HeartCnt =0;
+					  }
+						if(game_manager.clientCnt >0 && mFlash.isHost) app_game_notify_host(0);
+						break;
+					}
+		case 1:{
+					 if(mFlash.isHost){//管理右鞋状态
+							 if(host_isconnect()){
+								 if(0 == game_manager.clientCnt){
+										app_game_notify_host(1);
+										if(++configcnt >= 10){configcnt =0;
+											DEBUG_LOG("ERR_NUM_GAME app_game_Process\r\n");
+											Except_TxError(EXCEPT_GAME,"no get right shoes data");
+										}
+								 }
+								 else if(configcnt>0) configcnt = 0;
+								 if(0 != game_manager.right_discnt)game_manager.right_discnt =0;
+							 }
+							 else game_manager.right_discnt++;
+						}
+						
+						if(0 == slave_isconnect())game_manager.client_discnt++;
+						else if(0 != game_manager.client_discnt)game_manager.client_discnt =0;
+							
+						if(0 == game_manager.Signal  ||      //收到退出游戏的指令
+							game_manager.client_discnt > 5 ||  //与主机断开5秒后,退出游戏模式
+							game_manager.right_discnt  > 10    //与右鞋断开10秒后,退出游戏模式
+						){
+								if(game_manager.right_discnt > 10)Except_TxError(EXCEPT_GAME,"In game mode,right shoes disconnted long time");
+								if(game_manager.client_discnt > 5)Except_TxError(EXCEPT_GAME,"In game mode,client disconnted long time");
+								configcnt =0;
+								state =0;
+								game_manager.Signal = 0;
+								game_manager.client_discnt =0;
+								game_manager.right_discnt =0;
+								game_manager.GameMode =0;
+								bll_imu_Resume_unregister_config_param(&game_bll_imu_param_t);
+								if(mFlash.isHost)app_game_notify_host(0);
+
+								IMU_STATUS = 0;
+								set_pdr_status();
+								app_game_led(0);
+							
+						}
+						break;
+					}
+		default: state =0;game_manager.Signal = 0;game_manager.client_discnt =0;break;
+	  }
+}
+
+static void app_AutoOutgame_Process(void){
+	uint8_t front_CS = bll_imu_query_config_param_is_ready(BLL_IMU_DIR_FRONT,&game_bll_imu_param_t);
+	uint8_t back_CS  = bll_imu_query_config_param_is_ready(BLL_IMU_DIR_BACK,&game_bll_imu_param_t);
+	
+	if(mFlash.isHost && app_game_GetGameMode()){
+		DEBUG_LOG("game_manager.GameModeHeartCnt:%d\r\n",game_manager.HeartCnt);
+		if(game_manager.HeartCnt++ >= 5){
+			 game_manager.Signal = 0;
+			 bll_imu_Resume_unregister_config_param(&game_bll_imu_param_t);
+			 BLE_Host_Tx_Send(0,BLE_GAMEMODE,&game_manager.Signal,1); 
+		}
+	}
+}
+
+void app_game_Init(void)
+{
+	Process_Start(1000,"app_game",app_game_Process);
+	BLE_Client_Rx_Regist(BLE_GAMEMODE,cb_BLE_Client_R_GAMEMODE);
+	Process_Start(60000,"app_AutoOutgame",app_AutoOutgame_Process);
+	bll_imu_register_data_notify_callback(BLL_IMU_DATA_NOTIFY_CB_PRIORITY_1, gamemode_data_notify_cb);
+}

+ 14 - 0
shoe_mcu2.2.1_new_v2/app/app_game.h

@@ -0,0 +1,14 @@
+#ifndef __app_game_h__
+#define __app_game_h__
+#include <stdbool.h>
+#include <stdint.h>
+#include <string.h>
+#include "sdk_common.h"
+#include "SEGGER_RTT.h"
+#include "usr_config.h"
+
+void app_game_Init(void);
+void app_game_SetClientGameMode(void);
+uint8_t app_game_GetGameMode(void);
+
+#endif

+ 94 - 0
shoe_mcu2.2.1_new_v2/app/app_host.c

@@ -0,0 +1,94 @@
+#include "system.h"
+#include "app_host.h"
+#include "hal_ble_client.h"
+#include "hal_ble_host.h"
+#include "bsp_time.h"
+#include "hal_led.h"
+#include "ble_gap.h"
+#include "hal_battery.h"
+#include "app_flash.h"
+#include "ble_comm.h"
+#include "app_client.h"
+
+/************************ 定义 ***************************/
+static uint8_t  vol_R    = 0;	//右鞋电量
+static uint8_t  temp_R   = 0;	//右鞋温度
+static uint32_t press_R  = 0;	//右鞋压力
+static int16_t  volADC_R = 0;	//右鞋电池ADC
+
+uint8_t app_host_GetVol_R(void){ return vol_R; }
+int16_t app_host_GetVolAdc_R(void){ return volADC_R; }
+uint8_t app_host_GetTemp_R(void){ return temp_R; }
+uint32_t app_host_GetPress_R(void){ return press_R; }
+
+/***************************** 主动获取从机信息 ******************************/
+static BLE_Host_Tx_t mBLE_Host_T_UPDATE_INFO_R = {
+	.n = 10,
+	.t = 1000,
+	.cb = 0,
+};
+
+void app_host_GetClientInfo(void)
+{//AA 06 F9 A1 00 4A
+	static uint8_t buf=BLE_UPDATE_BASEINFO;
+	BLE_Host_Tx_Send(&mBLE_Host_T_UPDATE_INFO_R,BLE_UPDATE,&buf,1);
+}
+
+static BLE_Host_Tx_t mBLE_Host_T_UPDATE_DATA_R = {
+	.n = 0,
+	.t = 500,
+	.cb = 0,
+};
+
+void app_host_GetClientData(uint8_t temp)
+{//AA 06 F9 A1 01 4B
+	static uint8_t buf=BLE_UPDATE_DATA;
+	BLE_Host_Tx_Send(0,BLE_UPDATE,&buf,1);
+	if(0 == mBLE_Host_T_UPDATE_DATA_R.n && temp >=2){
+		mBLE_Host_T_UPDATE_DATA_R.n = temp;
+		BLE_Host_Tx_Send(&mBLE_Host_T_UPDATE_DATA_R,BLE_UPDATE,&buf,1);
+	}
+}
+
+ //>> 0xA1: 查询
+void cb_BLE_Host_R_UPDATE(void* handle)
+{
+	if(!mFlash.isHost)return;
+	
+	BLE_Host_Rx_t *target = handle;
+	uint8_t _cmd = target->pDat[0];
+	switch(_cmd){
+		case BLE_UPDATE_BASEINFO:{
+			//<< 0(子命令): 设备型号(64)+左鞋蓝牙地址(6)+硬件版本(2)+软件版本(2)+右鞋蓝牙地址(6)+硬件版本(6)+软件版本(2)
+			for(int i=0;i<6;i++) mFlash.mClient.macAddr[i] = target->pDat[i+1+SHOES_NAME_LEN];
+//			DEBUG_LOG("mFlash.mClient.macAddr:%02X %02X %02X %02X %02X %02X\n",mFlash.mClient.macAddr[0],mFlash.mClient.macAddr[1],mFlash.mClient.macAddr[2],mFlash.mClient.macAddr[3],mFlash.mClient.macAddr[4],mFlash.mClient.macAddr[5]);
+			uint8_t L = SHOES_NAME_LEN+7;
+			mFlash.mClient.hardVersion = ((uint32_t)target->pDat[L]<<24)  |((uint32_t)target->pDat[L+1]<<16) |((uint32_t)target->pDat[L+2]<<8) |((uint32_t)target->pDat[L+3]);
+			mFlash.mClient.sotfVersion = ((uint16_t)target->pDat[L+4]<<8 | (uint16_t)target->pDat[L+5]);
+//			DEBUG_LOG("BLE_Host_R_UPDATE_BASEINFO:"); for(int i=64;i<(28+64);i++){DEBUG_LOG("%02X ",target->pDat[i]);} DEBUG_LOG("\r\n");
+//			DEBUG_LOG("sotfVersion,hardVersion:%x,%x\n",mFlash.mClient.sotfVersion,mFlash.mClient.hardVersion);
+			app_client_infomation_Send();
+			break;}
+		case BLE_UPDATE_DATA:{
+			//<< 1(子命令): 左鞋电量(1)+左鞋温度(1)+左鞋压力(4)+左鞋步数(4)+右鞋电量(1)+右鞋温度(1)+右鞋压力(4)+右鞋步数(4)
+			vol_R = target->pDat[1];
+			temp_R = target->pDat[2];
+			press_R = ((uint32_t)target->pDat[3]<<24)|((uint32_t)target->pDat[4]<<16)|((uint32_t)target->pDat[5]<<8)|((uint32_t)target->pDat[6]<<0);
+			mFlash.mStep.stepCur[1]  = ((uint32_t)target->pDat[7]<<24)|((uint32_t)target->pDat[8]<<16)|((uint32_t)target->pDat[9]<<8)|((uint32_t)target->pDat[10]<<0);
+			
+			if(target->datLen >= 25)volADC_R = ((target->pDat[21]<<8)+target->pDat[22]);
+			
+			mBLE_Host_T_UPDATE_DATA_R.n = 0;
+			app_client_DataUpdate_Send();
+//			DEBUG_LOG("right step:%d\n",mFlash.mStep.stepCur[1]);
+			break;}
+	default:break;
+	}
+}
+
+
+void app_host_Initialize(void)
+{
+		BLE_Host_Rx_Regist(BLE_UPDATE,cb_BLE_Host_R_UPDATE);
+}
+

+ 27 - 0
shoe_mcu2.2.1_new_v2/app/app_host.h

@@ -0,0 +1,27 @@
+#ifndef __app_host_h__
+#define __app_host_h__
+#include <stdbool.h>
+#include <stdint.h>
+#include <string.h>
+#include "sdk_common.h"
+#include "SEGGER_RTT.h"
+#include "usr_config.h"
+
+void app_host_Initialize(void);
+
+//void app_host_GetMac_R(uint8_t* p);
+//uint16_t app_host_HardVer_R(void);
+//uint16_t app_host_SoftVer_R(void);
+
+uint8_t app_host_GetVol_R(void);
+int16_t app_host_GetVolAdc_R(void);
+uint8_t app_host_GetTemp_R(void);
+uint32_t app_host_GetPress_R(void);
+void app_host_GetClientInfo(void);
+void app_host_GetClientData(uint8_t temp);
+
+
+#endif
+
+
+

+ 41 - 0
shoe_mcu2.2.1_new_v2/app/app_losspack.c

@@ -0,0 +1,41 @@
+#include "app_losspack.h"
+#include "bsp_time.h"
+#include "app_flash.h"
+#include "system.h"
+#include "hal_ble_client.h"
+#include "ble_comm.h"
+#include "app_game.h"
+
+#if LOSSPACK_ENANBLE 
+uint16_t lose_pack_all =0;
+
+void LossPack_process(void){
+	if(!mFlash.isHost)return;
+	if(app_game_GetGameMode()){
+		uint16_t pack_l =0;
+		uint8_t rssi = 0-host_get_rssi();
+		
+		pack_l = lose_pack_all;
+		uint8_t buf[8];
+		uint8_t L = 0;
+		buf[L++] = (uint8_t)(pack_l>>8);
+		buf[L++] = (uint8_t)(pack_l);
+		buf[L++] = (uint8_t)(rssi);
+		BLE_Client_Tx_Send(0,(BLE_CMD_n)0x03,buf,L);
+	//	DEBUG_LOG("lose_pack_all:%d, h_rssi=%d\r\n",lose_pack_all,rssi);
+		
+		lose_pack_all = 0;
+	}
+}
+
+
+void app_losspack_Init(void)
+{
+	Process_Start(1000,"LossPack_process",LossPack_process);
+}
+#endif
+
+
+
+
+

+ 17 - 0
shoe_mcu2.2.1_new_v2/app/app_losspack.h

@@ -0,0 +1,17 @@
+#ifndef __APP_LOSSPACK_H__
+#define __APP_LOSSPACK_H__
+#include <stdbool.h>
+#include <stdint.h>
+#include <string.h>
+#include "sdk_common.h"
+#include "SEGGER_RTT.h"
+#include "usr_config.h"
+
+
+
+void app_losspack_Init(void);
+
+#endif
+
+
+

+ 207 - 0
shoe_mcu2.2.1_new_v2/app/app_math.c

@@ -0,0 +1,207 @@
+#include "app_math.h"
+#include "bsp_time.h"
+#include "system.h"
+#include "math.h"
+#include "ble_comm.h"
+#include "app_flash.h"
+#include "detect_zero_vel.h"
+#include "tool.h"
+#include "app_switchimu.h"
+#include "detect_step_by_mag.h"
+#include "pdrStatus.h"
+#include "detect_step_by_mag.h"
+#include "app_client_step.h"
+#include "hal_mt.h"
+#include "hal_led.h"
+#include "bll_imu.h"
+#include "app_game.h"
+
+static uint32_t timeCNT = 0;
+static uint8_t  FlagFix_process = 0;
+static int16_t  offset_milisecond =0;
+static uint64_t last_newtime_ms =0;
+static uint8_t  RealMinute =0;
+
+//叫硫珂쇌
+void app_math_calit_time(uint8_t appminute){
+	
+	static uint32_t last_device_time_ms = 0;
+	uint64_t newtime_ms =0;
+	uint32_t device_time_ms = 0;
+
+	newtime_ms = (
+	((uint64_t) mFlash.mStep.startTime[0]  << 56) | ((uint64_t)mFlash.mStep.startTime[1] << 48 )
+	|((uint64_t)mFlash.mStep.startTime[2] << 40) | ((uint64_t)mFlash.mStep.startTime[3] << 32)
+	|((uint64_t)mFlash.mStep.startTime[4] << 24) | ((uint64_t)mFlash.mStep.startTime[5] << 16)
+	|((uint64_t)mFlash.mStep.startTime[6] << 8)  | (uint64_t)mFlash.mStep.startTime[7]);
+	
+	device_time_ms = timeCNT;
+	DEBUG_LOG("app_math_calit_time:realminute:%d,%lu,%lu\n",appminute,(uint32_t)(newtime_ms-last_newtime_ms),(uint32_t)((device_time_ms-last_device_time_ms)/32.768));
+//	if(0 != last_newtime_ms){
+//		 if( newtime_ms > last_newtime_ms
+//			   && (newtime_ms - last_newtime_ms >= 30000)
+//		     &&  device_time_ms > last_device_time_ms){
+//				 uint32_t time_interval =0,devicetime_interval =0;
+//				 time_interval = (newtime_ms - last_newtime_ms);
+//				 devicetime_interval = (device_time_ms - last_device_time_ms)/32.768;
+//				 DEBUG_LOG("app_math_calit_time:%u,%u\n",time_interval,devicetime_interval);
+//		 }
+//	}
+	uint8_t mymintu =0;
+	mymintu = (uint8_t)(newtime_ms%(60000));
+	DEBUG_LOG("apptime : %u:%u,shoes time:  %u:%u\n",appminute,mymintu,(uint32_t)((timeCNT)/32768/60),(uint8_t)((timeCNT)/32768%60));
+	
+	timeCNT = (appminute)*60*32768;
+	last_newtime_ms = newtime_ms;
+	last_device_time_ms = device_time_ms;
+//	
+}
+
+//寧鬼珂셕珂
+static void app_math_Hour_process(void){
+	static uint8_t Halfhour_cnt =0;
+	uint32_t sec = 0;
+	static uint32_t cnt_b=0;
+	uint32_t cnt = NRF_RTC0->COUNTER;
+	if(cnt<cnt_b) cnt += 16777216;
+	timeCNT += cnt - cnt_b;
+	sec = (timeCNT+offset_milisecond)/32768;
+  
+	if(cnt >16777216)cnt_b = cnt - 16777216;
+	else cnt_b = cnt;
+	
+	if(sec >=1800){//곕鬼珂
+		if(1 != Halfhour_cnt){
+			Halfhour_cnt =1;
+			FlagFix_process =1;
+		}
+	}
+	
+	if(sec >= 3600){//寧鬼珂
+		timeCNT =0;
+		app_client_step_SetIsScan();
+		FlagFix_process =1;
+		Halfhour_cnt =0;
+		DEBUG_LOG("timeCNT(%d)(%d)\n",timeCNT,sec);
+	}
+
+}
+
+//炬랬叫硫친駕
+static const bll_imu_one_way_param_t calibration_front_param={
+	.acc_power_mode 						= FML_IMU_ACC_POWER_MODE_NORMAL,						//품신 - 속醵똑攣끽친駕
+	.gry_power_mode 						= FML_IMU_GRY_POWER_MODE_NORMAL,						//품신 - 顧쭁老攣끽친駕
+	.timestamp_resolution 			= FML_IMU_TIMESTAMP_25US,										//품신 - 珂쇌늑25US쑹똑
+	.timestamp_switch 					= FML_IMU_TIMESTAMP_ON,											//품신 - 珂쇌늑역폘
+	.acc_fs 										= FML_IMU_ACC_FS_16G,												//품신 - 속醵똑좆넋 - 16G
+	.gry_fs 										= FML_IMU_GRY_FS_2000DPS,										//품신 - 顧쭁老좆넋 - 2000DPS
+	.mag_fs 										= FML_IMU_MAG_FS_30GS,											//품신 - 뒈늚셕좆넋 - 30GS
+	.acc_odr 									  = FML_IMU_ACC_ODR_104HZ,										//품신 - 속醵똑꽃湳틉쪽 - 104HZ
+	.gry_odr 									  = FML_IMU_GRY_ODR_104HZ,										//품신 - 顧쭁老꽃湳틉쪽 - 104HZ
+	.mag_odr 									  = FML_IMU_MAG_ODR_200HZ,										//품신 - 뒈늚셕꽃湳틉쪽 - 200HZ
+	.fifo_odr 									= FML_IMU_FIFO_ODR_104HZ,	
+};
+
+static const bll_imu_one_way_param_t calibration_back_param={
+	.acc_power_mode 						= FML_IMU_ACC_POWER_MODE_NORMAL,						//빈신 - 속醵똑攣끽친駕
+	.gry_power_mode 						= FML_IMU_GRY_POWER_MODE_NORMAL,						//빈신 - 顧쭁老攣끽친駕
+	.timestamp_resolution 			= FML_IMU_TIMESTAMP_25US,										//빈신 - 珂쇌늑25US쑹똑
+	.timestamp_switch 					= FML_IMU_TIMESTAMP_OFF,										//빈신 - 珂쇌늑밑균
+	.acc_fs 										= FML_IMU_ACC_FS_16G,											  //빈신 - 속醵똑좆넋 - 16G
+	.gry_fs 										= FML_IMU_GRY_FS_2000DPS,										//빈신 - 顧쭁老좆넋 - 2000DPS
+	.mag_fs 										= FML_IMU_MAG_FS_30GS,											//빈신 - 뒈늚셕좆넋 - 30GS
+	.acc_odr 										= FML_IMU_ACC_ODR_OFF,											//빈신 - 속醵똑꽃湳틉쪽 - 밑균
+	.gry_odr 										= FML_IMU_GRY_ODR_OFF,											//빈신 - 顧쭁老꽃湳틉쪽 - 밑균
+	.mag_odr 										= FML_IMU_MAG_ODR_200HZ,										//빈신 - 뒈늚셕꽃湳틉쪽 - 200HZ
+	.fifo_odr 									= FML_IMU_FIFO_ODR_OFF,	
+};
+
+static const bll_imu_param_t calibration_bll_imu_param_t={
+	.config_param[BLL_IMU_DIR_FRONT] = &calibration_front_param,
+	.config_param[BLL_IMU_DIR_BACK] =  &calibration_back_param,
+};
+
+
+static void app_gyro_Fix_process(void){//顧쭁老쥐튤시攣
+	static uint8_t state =0;
+	static int16_t sample_count =0;
+	static uint32_t tim =0;
+	static uint8_t Setimu_config =0;
+	bll_imu_data_t data= {0};
+	uint8_t front_CS =0,back_CS =0;
+	
+	
+	switch(state){
+		case 0:
+			    if(!app_game_GetGameMode() && 1 == FlagFix_process){
+							Process_SetHoldOn(app_gyro_Fix_process,1);
+							bll_imu_Resume_config_param(&calibration_bll_imu_param_t);
+							state =1;
+						  FlagFix_process =0;
+						  tim = TIME_GetTicks();
+						  Setimu_config =0;
+						  DEBUG_LOG("====>>>>HAL_SER_IMU_MODE_MANAGE_CALIBRATION,tim:%d s\r\n",TIME_GetTicks()/1000);
+					}
+			    break;
+		case 1: 
+			    front_CS = bll_imu_query_config_param_is_ready(BLL_IMU_DIR_FRONT,&calibration_bll_imu_param_t);
+	        back_CS  = bll_imu_query_config_param_is_ready(BLL_IMU_DIR_BACK,&calibration_bll_imu_param_t);
+			    if(BLL_IMU_CONFIG_FINISH == front_CS && BLL_IMU_CONFIG_FINISH == back_CS){
+						 state =2;
+						 Process_UpdatePeroid(app_gyro_Fix_process,10);
+						 sample_count =0;
+						 tim = TIME_GetTicks();
+//						 MT_Run(500);
+//						 DEBUG_LOG("====INTO HAL_SER_IMU_MODE_MANAGE_CALIBRATION\r\n");
+					}
+					else  if(BLL_IMU_CONFIG_DOING != front_CS || BLL_IMU_CONFIG_DOING != back_CS){
+								 bll_imu_Resume_config_param(&calibration_bll_imu_param_t);
+								 if(++Setimu_config >= 20){Setimu_config =0;
+										bll_imu_Resume_unregister_config_param(&calibration_bll_imu_param_t);
+									  state =3;
+										Except_TxError(EXCEPT_GAME,"shoes into CALIBRATION mode fail");
+								 }
+					}
+					if(app_game_GetGameMode())state =3;//踏狗친駕苟藁놔
+			    break;
+		case 2:
+					//뗍혤ACC令6
+					if(bll_imu_get_data_num(BLL_IMU_DIR_FRONT) >= 1){
+						bll_imu_get_data(BLL_IMU_DIR_FRONT, 0, &data);
+						estimate_gyr_bias_interface(data.gry,sample_count);
+//						DEBUG_LOG("====>>>>gry:%d,%d,%d,tim:%d\r\n",data.gry[0],data.gry[1],data.gry[2],sample_count);
+						sample_count++;
+					}
+					if(TIME_GetTicks()-tim>=10000){ //텝供10취藁놔
+						 state =3;
+//						 DEBUG_LOG("====>>>>HAL_SER_IMU_MODE_MANAGE_CALIBRATION\r\n");
+					}
+					if(app_game_GetGameMode())state =3;//踏狗친駕苟藁놔
+			    break;
+		case 3:
+			    Process_UpdatePeroid(app_gyro_Fix_process,1000);
+		      bll_imu_Resume_unregister_config_param(&calibration_bll_imu_param_t);
+		      Process_SetHoldOn(app_gyro_Fix_process,0);
+				  state =0;
+		      Setimu_config =0;
+//		      DEBUG_LOG("====OUT app_gyro_Fix_process\r\n");
+			    break;
+		default:state =0;Setimu_config =0;break;
+	}
+	
+}
+
+void app_math_Init(void)
+{
+	Process_Start(500,"app_gyro_Fix_process",app_gyro_Fix_process);
+	Process_Start(1000,"app_math_Hour",app_math_Hour_process);
+}
+
+
+
+
+
+
+
+
+

+ 16 - 0
shoe_mcu2.2.1_new_v2/app/app_math.h

@@ -0,0 +1,16 @@
+#ifndef __APP_MATH_H__
+#define __APP_MATH_H__
+#include <stdbool.h>
+#include <stdint.h>
+#include <string.h>
+#include "sdk_common.h"
+#include "SEGGER_RTT.h"
+#include "usr_config.h"
+
+void app_math_Init(void);
+void app_math_calit_time(uint8_t realminute);
+
+#endif
+
+
+

+ 55 - 0
shoe_mcu2.2.1_new_v2/app/app_organ.c

@@ -0,0 +1,55 @@
+
+#include "app_organ.h"
+#include "nrf_gpio.h"
+#include "usr_config.h"
+#include "bsp_time.h"
+#include "system.h"
+#include "hal_mt.h"
+#include "app_host.h"
+#include "app_charge.h"
+#include "hal_ble_client.h"
+#include "hal_ble_host.h"
+#include "nrf_delay.h"
+#include "hal_flash.h"
+#include "ble_comm.h"
+#include "hal_imu.h"
+
+#if LASER_ENABLE
+static uint8_t OrganIs_open = 0;
+
+void cb_BLE_CLient_R_SET_ORGAN(void* handle)
+{
+	BLE_Client_Rx_t* target = handle;
+	OrganIs_open = target->pDat[0];
+	DEBUG_LOG("cb_BLE_CLient_R_SET_ORGAN...%d\n",OrganIs_open);
+	IMU_SwitchOrgan(OrganIs_open);
+	BLE_Host_Tx_Send(0,BLE_Host_T_SET_ORGAN,&OrganIs_open,1);
+}
+
+//void app_oragan_Process(void)
+//{
+//	static uint32_t tim=0;
+//	if(TIME_GetTicks()-tim>=1000){ tim = TIME_GetTicks();
+//	  
+// }   
+//}
+
+/*********************** ½ÓÊÕ´Ó»úÃüÁî ************************/
+void cb_Host_R_SET_ORGAN(void* handle)
+{
+	uint8_t data =0;
+	BLE_Host_Rx_t* target = handle;
+	data = (*target->pDat+IMU_GetOrgan());
+	DEBUG_LOG("Host_R_SET_ORGA...%d\n",data);
+	BLE_Client_Tx_Send(0,BLE_CLient_T_SET_ORGAN,&data,1);	//´Ó»úÓ¦´ð
+}
+
+void app_organ_Init(void)
+{
+//AA 06 F9 A9 01 53
+		BLE_Client_Rx_Regist(BLE_CLient_R_SET_ORGAN,cb_BLE_CLient_R_SET_ORGAN);
+//	  Process_Start(" ",app_oragan_Process);
+	  BLE_Host_Rx_Regist(BLE_Host_R_SET_ORGAN,cb_Host_R_SET_ORGAN);
+}
+#endif
+

+ 12 - 0
shoe_mcu2.2.1_new_v2/app/app_organ.h

@@ -0,0 +1,12 @@
+#ifndef __app_organ_h__
+#define __app_organ_h__
+#include <stdbool.h>
+#include <stdint.h>
+#include <string.h>
+#include "sdk_common.h"
+#include "SEGGER_RTT.h"
+#include "usr_config.h"
+
+void app_organ_Init(void);
+
+#endif

+ 224 - 0
shoe_mcu2.2.1_new_v2/app/app_ota.c

@@ -0,0 +1,224 @@
+#include "app_ota.h"
+#include "nrf_gpio.h"
+#include "usr_config.h"
+#include "bsp_time.h"
+#include "system.h"
+#include "hal_mt.h"
+#include "app_host.h"
+#include "app_charge.h"
+#include "hal_ble_client.h"
+#include "hal_ble_host.h"
+#include "nrf_delay.h"
+#include "app_flash.h"
+#include "ble_comm.h"
+#include "exception.h"
+#include "hal_led.h"
+
+static ble_gap_addr_t mAddr;
+static uint32_t isOTA=0;
+static uint8_t  isHostOTA=0;
+static volatile uint8_t m_ready_for_reset = 0;
+static uint8_t ResRightFlag = 0; 
+
+static bool app_shutdown_handler(nrf_pwr_mgmt_evt_t event)
+{
+    switch (event){
+        case NRF_PWR_MGMT_EVT_PREPARE_DFU:
+					   switch(m_ready_for_reset){
+							  case 0:m_ready_for_reset =1;return false;
+							  case 1:return false;
+							  default: break;
+			       }
+            break;
+        default:return true;
+    }
+    DEBUG_LOG("Into bootloader\n");
+    return true;
+}
+
+static void app_ota_clear_flash(void)
+{
+	if(1 == m_ready_for_reset){
+		LED_Close_Enforce();
+		if(Flash_SaveStep() != ZONE_OP_SUCCESS)Except_TxError(EXCEPT_DFU,"save step fail");
+			
+		extern battercb_t battery_record;
+		extern void printbatter_cb(battercb_t *c,battercb_t *C_flash);
+		
+		memcpy(&mFlash.mbattercb_t,&battery_record,sizeof(battercb_t));
+		printbatter_cb(&battery_record,&mFlash.mbattercb_t);
+		mFlash.RestartCnt =0;	
+		if(Flash_SaveInfomation() != ZONE_OP_SUCCESS)Except_TxError(EXCEPT_DFU,"save information fail");
+		DEBUG_LOG("------>save flash\n");
+		m_ready_for_reset =2;
+	}
+	else if(2 == m_ready_for_reset){
+		nrf_pwr_mgmt_shutdown(NRF_PWR_MGMT_SHUTDOWN_CONTINUE);
+	} 
+}
+
+NRF_PWR_MGMT_HANDLER_REGISTER(app_shutdown_handler, 0);
+
+static void app_ota_Process(void)
+{
+	static uint8_t state = 0;
+	char buf[16];
+
+	uint8_t responhost =0;
+	switch(state){
+		case 0:{
+			if(mFlash.isHost > 0){//左鞋
+				 if(1 == isHostOTA){
+					 DEBUG_LOG("------>isHostOTA\n");
+					 state = 1;
+					 host_disconnect();
+					 nrf_ble_scan_stop();
+					 Process_UpdatePeroid(app_ota_Process,10000);
+					 BLE_Client_Tx_Send(0,BLE_DFU,&responhost,1);
+				 }
+			}
+			else{
+					if(1== isOTA && 1 == ResRightFlag){ isOTA = 0;ResRightFlag =0;
+						if(slave_isconnect()) slave_disconnect();
+						else advertising_stop();
+						memset(buf,0,16);
+						sprintf(buf,"SH_%02X%02X%02X%02X%02X%02X",mAddr.addr[5],mAddr.addr[4],mAddr.addr[3],mAddr.addr[2],mAddr.addr[1],mAddr.addr[0]);
+						DEBUG_LOG("OTA name(%d):%s\n",strlen(buf),buf);
+						slave_set_adv_name(buf,strlen(buf));
+						slave_adv_init();
+						state = 1;
+						Process_UpdatePeroid(app_ota_Process,2000);
+					}
+			}
+			break;}
+		case 1:{
+			if(mFlash.isHost > 0){//左鞋
+				isHostOTA =0;
+				state =0;
+				DEBUG_LOG("------>left out to dfu\n");
+			}
+			else{
+				if(slave_isconnect()==0){
+					DEBUG_LOG("app_ota_Process advertising_start\r\n");
+					advertising_start();
+					Process_UpdatePeroid(app_ota_Process,10000);
+					state = 2;
+				}
+				else slave_disconnect();
+			}
+			break;}
+		case 2:{
+			if(slave_isconnect()) state = 0;
+			Process_UpdatePeroid(app_ota_Process,0);
+			advertising_stop();
+			memset(buf,0,16);
+			
+			#if BleNameHoldOn_ENANBLE 
+			slave_set_adv_name((char *)RIGHT_NAME,sizeof(RIGHT_NAME));
+			DEBUG_LOG("AdvName(%d):%s\n",sizeof(RIGHT_NAME),RIGHT_NAME);
+		  #else
+			sprintf(buf,"%02X%02X%02X%02X%02X%02X",mFlash.macHost[0],mFlash.macHost[1],mFlash.macHost[2],mFlash.mClient.macAddr[3],mFlash.mClient.macAddr[4],mFlash.mClient.macAddr[5]);
+			DEBUG_LOG("ADV name(%d):%s\n",strlen(buf),buf);
+			slave_set_adv_name(buf,strlen(buf));
+			#endif
+			
+			Except_TxError(EXCEPT_DFU,"adv disconnted over time");
+			slave_adv_init();
+			advertising_start();
+			state = 0;
+			break;}
+		 default:state = 0;Process_UpdatePeroid(app_ota_Process,0);break;
+	}
+	
+	
+}
+
+/*********************** 接收从机命令 ************************/
+void cb_BLE_Host_R_DFU(void* handle)
+{
+  uint8_t left_dfu_state =0;
+	BLE_Host_Rx_t* target = handle;
+	left_dfu_state = target->pDat[0];
+	
+	BLE_Client_Tx_Send(0,BLE_DFU,&left_dfu_state,1);
+}
+
+static void cb_Client_BLE_DFU(void* handle)
+{
+   Process_SetHoldOn(app_ota_Process,0);
+	 ResRightFlag =1;
+}
+
+static BLE_Client_Tx_t m_Client_BLE_DFU = {
+	.n = 15,
+	.t = 200,
+	.cb = cb_Client_BLE_DFU,
+};
+
+/*********************** 接收手机命令 ************************/
+void cb_BLE_Client_R_DFU(void* handle)
+{
+	  DEBUG_LOG(">>>>>>>>>>BLE_Client_R_DFU\n");
+		BLE_Client_Rx_t* target = handle;
+		if(mFlash.isHost>0){
+			 if(target->pDat[0] == 0){isHostOTA = 1;
+				  return; //左鞋不需要理会
+			 }
+			 else if(target->pDat[0] == 1){
+				  BLE_Host_Tx_Send(0,BLE_DFU,target->pDat,1);	//发给从机
+			 }
+		}
+		else {
+			static uint8_t responhost =1;
+			BLE_Client_Tx_Send(&m_Client_BLE_DFU,BLE_DFU,&responhost,1);
+			isOTA = 1;
+			Process_SetHoldOn(app_ota_Process,1);
+		  DEBUG_LOG(">>>>>>>>>>DFU start....\n");
+		}
+}
+
+uint8_t app_ota_host_state(void)
+{
+	  return isHostOTA;
+}
+
+#if BleNameHoldOn_ENANBLE
+extern uint8_t SaveFlashFlag_holdOn;
+static void app_ota_SaveFlash(void){
+	if(1 ==SaveFlashFlag_holdOn ){
+		 SaveFlashFlag_holdOn =0;
+		 if(Flash_SaveInfomation() != ZONE_OP_SUCCESS)Except_TxError(EXCEPT_DFU,"save information fail");
+		 uint8_t i =0;
+		 DEBUG_LOG("mac host addr:");for(i=0;i<6;i++){DEBUG_LOG("%02X ",mFlash.macHost[i]);}DEBUG_LOG("\n");
+		 DEBUG_LOG("mClient addr:");for(i=0;i<6;i++){DEBUG_LOG("%02X ",mFlash.mClient.macAddr[i]);}DEBUG_LOG("\n");
+	}
+}
+#endif
+
+
+void app_ota_Init(void)
+{
+	uint32_t err_code = sd_ble_gap_addr_get(&mAddr); APP_ERROR_CHECK(err_code); 
+	Process_Start(0,"app_ota_Process",app_ota_Process);
+	BLE_Client_Rx_Regist(BLE_DFU,cb_BLE_Client_R_DFU);
+  BLE_Host_Rx_Regist(BLE_DFU,cb_BLE_Host_R_DFU);
+	Process_Start(500,"app_ota_clear_flash",app_ota_clear_flash);
+	
+	#if BleNameHoldOn_ENANBLE
+	DEBUG_LOG("mac addr:");for(int i=0;i<6;i++){DEBUG_LOG("%02X ",mAddr.addr[i]);}DEBUG_LOG("\n");
+	uint8_t i=0;
+	for(i=0;i<6;i++)if(mFlash.macHost[i] !=0xff)break;
+	if(6 ==i){
+		 for(uint8_t a=0;a<6;a++){
+			   mFlash.macHost[a] = mAddr.addr[5-a];
+		 }
+		 SaveFlashFlag_holdOn =1;
+	}
+	
+	Process_Start(1000,"app_ota_SaveFlash",app_ota_SaveFlash);
+	#endif
+	
+	
+}
+
+

+ 13 - 0
shoe_mcu2.2.1_new_v2/app/app_ota.h

@@ -0,0 +1,13 @@
+#ifndef __app_ota_h__
+#define __app_ota_h__
+#include <stdbool.h>
+#include <stdint.h>
+#include <string.h>
+#include "sdk_common.h"
+#include "SEGGER_RTT.h"
+#include "usr_config.h"
+
+void app_ota_Init(void);
+uint8_t app_ota_host_state(void);
+
+#endif

+ 299 - 0
shoe_mcu2.2.1_new_v2/app/app_overturn - 副本 (2).c

@@ -0,0 +1,299 @@
+#include "usr_config.h"
+#include "hal_battery.h"
+#include "nrf_drv_saadc.h"
+#include "bsp_time.h"
+#include "system.h"
+#include "hal_led.h"
+#include "hal_ser_imu_mode_manage.h"
+#include "app_overturn.h"
+#include "hal_wearshoes.h"
+
+
+#include "ble_comm.h"
+
+#define SLIDE_WINDOW_LEN 5
+				
+
+typedef struct
+{
+	int16_t max_temp;
+	uint16_t time_count;
+}ACC_TIME_TYPE;
+
+typedef struct
+{
+	ACC_TIME_TYPE slide_window[SLIDE_WINDOW_LEN];
+	
+	int window_length;
+	
+}SLIDE_WINDOW;
+
+static uint8_t flag_move =0;
+
+void sort_silde_window(SLIDE_WINDOW *max_slide_window, SLIDE_WINDOW *min_slide_window, int16_t acc_val, uint16_t	time_count)
+{
+		ACC_TIME_TYPE acc_time_type_temp = {acc_val, time_count};
+//	  DEBUG_LOG("max_slide_window->slide_window[0]:0%2x,0%2x\n",max_slide_window->slide_window[0],&max_slide_window->slide_window[0]);
+		
+	//检测当前的值是是否是最大值
+	if(max_slide_window->window_length == 0)
+	{
+		max_slide_window->slide_window[0] = acc_time_type_temp;
+		
+		max_slide_window->window_length = 1;
+	}
+	else
+	{
+		//先判断长度是否溢出来了
+		DEBUG_LOG("sort_silde_window>>>>>>>>:%d,%d\n",time_count,max_slide_window->slide_window[0].time_count);
+		while(time_count - max_slide_window->slide_window[0].time_count >= SLIDE_WINDOW_LEN)
+		{
+			memcpy(max_slide_window->slide_window, max_slide_window->slide_window + 1, (SLIDE_WINDOW_LEN - 1) *sizeof(ACC_TIME_TYPE));
+			max_slide_window->window_length --;
+			DEBUG_LOG("111111 window_length:%d\n",max_slide_window->window_length);
+		}
+		
+		DEBUG_LOG("22222 window_length:%d,time_count:%d\n",max_slide_window->window_length,time_count);
+//		//再检测新的元素需要前面的元素小
+//		while(max_slide_window->window_length > 0)
+//		{
+//			DEBUG_LOG("33333 window_length:%d\n",max_slide_window->window_length);
+//			if(max_slide_window->slide_window[max_slide_window->window_length - 1].max_temp < acc_val)
+//			{
+//				DEBUG_LOG("44444 window_length:%d\n",max_slide_window->window_length);
+//				max_slide_window->window_length --;
+//			}
+//			else
+//			{
+//				break;
+//			}
+//		}
+		DEBUG_LOG("5555 window_length:%d\n",max_slide_window->window_length);
+		max_slide_window->slide_window[max_slide_window->window_length] = acc_time_type_temp;
+		
+		max_slide_window->window_length ++;
+		
+		DEBUG_LOG("<<<<<<<<<<<sort_silde_window end :%d\n",max_slide_window->window_length);
+	}
+	
+	//检测当前的值是是否是最小值
+	if(min_slide_window->window_length == 0)
+	{
+		min_slide_window->slide_window[0] = acc_time_type_temp;
+		min_slide_window->window_length = 1;
+	}
+	else
+	{
+		//先判断长度是否溢出来了
+		while(time_count - min_slide_window->slide_window[0].time_count >= SLIDE_WINDOW_LEN)
+		{
+			memcpy(min_slide_window->slide_window, min_slide_window->slide_window + 1, (SLIDE_WINDOW_LEN - 1) *sizeof(ACC_TIME_TYPE));
+			min_slide_window->window_length --;
+		}
+		
+		//再检测新的元素需要前面的元素小
+		while(min_slide_window->window_length > 0)
+		{
+			if(min_slide_window->slide_window[min_slide_window->window_length - 1].max_temp > acc_val)
+			{
+				min_slide_window->window_length --;
+			}
+			else
+			{
+				break;
+			}
+		}
+		
+		min_slide_window->slide_window[min_slide_window->window_length] = acc_time_type_temp;
+		
+		min_slide_window->window_length ++;
+	}
+}
+
+/************************ 踮脚显示电量 ***********************************/
+
+//没穿鞋的情况下
+
+void app_BatDispaly_Process_N(void)        
+{
+		ser_imu_data_t data= {0};
+	  static uint8_t lED_LIFE_SIGNAL = 0;
+    static uint8_t lED_LIFE_TIME = 0;
+		
+//	DEBUG_LOG("app_BatDispaly_Process_N;\n");
+		
+		if(-1 == hal_ser_imu_mode_manage_get_ready(HAL_SER_IMU_MODE_MANAGE_STANDBY))
+		{
+			return;//停止状态
+		}
+
+		//获取最新一组前脚加速度
+		int16_t data_size = 0;
+		
+		data_size = hal_ser_imu_mode_manage_get_data_num(SER_IMU_DIR_FRONT);
+		
+	  if(data_size > 0){
+			
+				hal_ser_imu_mode_manage_get_data(SER_IMU_DIR_FRONT, data_size -1 , &data);
+				
+				int32_t acc_norm = (data.acc[0] * data.acc[0] +data.acc[1] * data.acc[1] + data.acc[2] * data.acc[2]);
+				
+				if(abs(acc_norm - 4194304) < 362144 && data.acc[2] > 1536)
+				{
+					lED_LIFE_SIGNAL = 3;
+				}
+				else if(lED_LIFE_SIGNAL > 0)lED_LIFE_SIGNAL --;
+				
+				if(abs(acc_norm - 4194304) < 362144 && data.acc[2] < -1024)
+				{ 
+					lED_LIFE_SIGNAL = 0;
+				}
+				
+				DEBUG_LOG("000000 data.acc[2]:%d\n",data.acc[2]);
+				
+//				DEBUG_LOG("acc_norm:%d,lED_LIFE_SIGNAL:%d,data.acc2:%d,lED_LIFE_TIME:%d\n",abs(acc_norm - 4194304),lED_LIFE_SIGNAL,data.acc[2],lED_LIFE_TIME);
+				if(lED_LIFE_SIGNAL > 0)
+				{
+//					DEBUG_LOG("unwearshoes LED_Start(LED_OVERTURN,COLOR_GREEN);;\n");
+					  if(lED_LIFE_TIME == 0){
+								lED_LIFE_TIME = (10000/StandByPower_Interval);
+								if(GetBatteryPersent()>20){
+									LED_Start(LED_OVERTURN,COLOR_GREEN);
+								}else{
+									LED_Start(LED_OVERTURN,COLOR_ORANGE);
+								}
+								Process_SetHoldOn(app_BatDispaly_Process_N,1);
+						 }
+						 else if (2 == lED_LIFE_TIME){
+							  LED_Stop(LED_OVERTURN);
+						    Process_SetHoldOn(app_BatDispaly_Process_N,0);
+						 }
+						 if (lED_LIFE_TIME > 1)lED_LIFE_TIME--;
+				}
+				else
+				{
+//					DEBUG_LOG("unwearshoes LED_Stop(LED_OVERTURN);\n");
+					if(0 != lED_LIFE_TIME ){lED_LIFE_TIME =0;
+					   LED_Stop(LED_OVERTURN);
+					   Process_SetHoldOn(app_BatDispaly_Process_N,0);
+					}
+					if(1 == flag_move){flag_move =0;
+					 LED_Stop(LED_OVERTURN);
+					 Process_SetHoldOn(app_BatDispaly_Process_N,0);
+				  }
+				}
+	 }
+}
+
+//穿鞋的情况下
+void app_BatDispaly_Process(void)
+{
+	  ser_imu_data_t data={0};
+		
+		static uint8_t	time_count = 0;
+		
+		static uint16_t station_count =0;
+		static uint16_t overturn_180_count = 0;
+		static uint8_t lED_LIFE_SIGNAL = 0;
+    static uint8_t lED_LIFE_TIME = 0;
+		
+		static SLIDE_WINDOW max_slide_window = { {-3096,0},0 };
+		static SLIDE_WINDOW min_slide_window = { {3096,0},0 };
+		
+	
+		if(-1 == hal_ser_imu_mode_manage_get_ready(HAL_SER_IMU_MODE_MANAGE_NORMAL))
+		{
+			return;//走路状态
+		}			
+//		DEBUG_LOG("app_BatDispaly_Process;\n");
+		//获取最新一组前脚加速度, 有fifo
+		int16_t data_size = 0;
+		
+		data_size = hal_ser_imu_mode_manage_get_data_num(SER_IMU_DIR_FRONT);
+		
+	  if(data_size > 0){
+			
+//					DEBUG_LOG("data_size : %d,  hal_wearshoes_is_wearshoes: %d\n", data_size,hal_wearshoes_is_wearshoes());
+		     
+					hal_ser_imu_mode_manage_get_data(SER_IMU_DIR_FRONT, data_size-1 , &data);
+				  
+					//耗时较少的计算滑动窗口的最大值、最小值
+					sort_silde_window(&max_slide_window, &min_slide_window,  data.acc[0], time_count);
+					
+					if(time_count > SLIDE_WINDOW_LEN)
+					{
+						if(data.acc[0] - min_slide_window.slide_window[0].max_temp < 256 &&  max_slide_window.slide_window[0].max_temp -  data.acc[0] < 256
+							&& max_slide_window.slide_window[0].max_temp  - min_slide_window.slide_window[0].max_temp < 256 &&  data.acc[0] < -1500)
+						{
+							
+							station_count++;
+						}
+						else station_count =0;
+					}
+					
+					time_count++;
+
+//					DEBUG_LOG("111111 %d:%d:%d:%d\n",(data.acc[0] - min_slide_window.slide_window[0].max_temp),
+//							                                 (max_slide_window.slide_window[0].max_temp -  data.acc[0]),
+//							                                 (max_slide_window.slide_window[0].max_temp  - min_slide_window.slide_window[0].max_temp),data.acc[0]);
+					//在穿鞋状态下,被翻转了
+//					DEBUG_LOG("111111 data.acc[2]:%d\n",data.acc[2]);
+					int32_t acc_norm = (data.acc[0] * data.acc[0] +data.acc[1] * data.acc[1] + data.acc[2] * data.acc[2]);
+					if(abs(acc_norm - 4194304) < 362144 && data.acc[2] > 1536)
+					{
+						//DEBUG_LOG(" wear shoes if(abs(acc_norm - 4194304) < 262144 && data.acc[2] > 1536);\n");
+						overturn_180_count ++;
+					}
+					else
+					{
+						overturn_180_count = 0;
+					}
+					
+					if(overturn_180_count >= 5 || station_count > 4)
+					{
+//						 DEBUG_LOG(" overturn_180_count > 5;\n");
+						lED_LIFE_SIGNAL = 6;
+					}
+					
+					if(lED_LIFE_SIGNAL > 0)lED_LIFE_SIGNAL --;
+					
+					if(lED_LIFE_SIGNAL > 0)
+					{
+//						DEBUG_LOG("wearshoes LED_Start(LED_OVERTURN,COLOR_GREEN);;\n");
+						 if(lED_LIFE_TIME == 0){
+								lED_LIFE_TIME = (10000/LowPower_Interval);
+								if(GetBatteryPersent()>20){
+									LED_Start(LED_OVERTURN,COLOR_GREEN);
+								}else{
+									LED_Start(LED_OVERTURN,COLOR_ORANGE);
+								}
+								Process_SetHoldOn(app_BatDispaly_Process,1);
+						 }
+						 else if (2 == lED_LIFE_TIME){
+							  LED_Stop(LED_OVERTURN);
+						    Process_SetHoldOn(app_BatDispaly_Process,0);
+						 }
+						 if (lED_LIFE_TIME > 1)lED_LIFE_TIME--;
+					}
+					else
+					{
+//						DEBUG_LOG("wearshoes LED_Stop(LED_OVERTURN);\n");
+						if(0 != lED_LIFE_TIME ){lED_LIFE_TIME =0;
+					    LED_Stop(LED_OVERTURN);
+					    Process_SetHoldOn(app_BatDispaly_Process,0);
+					  }
+						if(0 == flag_move){flag_move =1;
+							 LED_Stop(LED_OVERTURN);
+							 Process_SetHoldOn(app_BatDispaly_Process_N,0);
+				    }
+					}
+		}
+		
+}
+
+
+void app_overturn_Init(void)
+{
+	Process_Start(LowPower_Interval,"BatDispaly",app_BatDispaly_Process);
+	Process_Start(StandByPower_Interval,"BatDispaly_N",app_BatDispaly_Process_N);
+}

+ 385 - 0
shoe_mcu2.2.1_new_v2/app/app_overturn - 副本 (3).c

@@ -0,0 +1,385 @@
+#include "usr_config.h"
+#include "hal_battery.h"
+#include "nrf_drv_saadc.h"
+#include "bsp_time.h"
+#include "system.h"
+#include "hal_led.h"
+#include "app_overturn.h"
+#include "hal_wearshoes.h"
+#include "bll_imu.h"
+
+#include "ble_comm.h"
+
+#define SLIDE_WINDOW_LEN 5
+
+//全功率
+static const fml_imu_param_t game_front_param={
+	.acc_power_mode 						= FML_IMU_ACC_POWER_MODE_NORMAL,						//前脚 - 加速度正常模式
+	.gry_power_mode 						= FML_IMU_GRY_POWER_MODE_NORMAL,						//前脚 - 陀螺仪正常模式
+	.timestamp_resolution 			= FML_IMU_TIMESTAMP_25US,										//前脚 - 时间戳25US精度
+	.timestamp_switch 					= FML_IMU_TIMESTAMP_ON,											//前脚 - 时间戳开启
+	.acc_fs 										= FML_IMU_ACC_FS_16G,												//前脚 - 加速度量程 - 16G
+	.gry_fs 										= FML_IMU_GRY_FS_2000DPS,										//前脚 - 陀螺仪量程 - 2000DPS
+	.mag_fs 										= FML_IMU_MAG_FS_30GS,											//前脚 - 地磁计量程 - 30GS
+	.acc_odr 									  = FML_IMU_ACC_ODR_104HZ,										//前脚 - 加速度采样频率 - 104HZ
+	.gry_odr 									  = FML_IMU_GRY_ODR_104HZ,										//前脚 - 陀螺仪采样频率 - 104HZ
+	.mag_odr 									  = FML_IMU_MAG_ODR_200HZ,										//前脚 - 地磁计采样频率 - 200HZ
+	.fifo_odr 									= FML_IMU_FIFO_ODR_104HZ,	
+};
+
+static const fml_imu_param_t game_back_param={
+	.acc_power_mode 						= FML_IMU_ACC_POWER_MODE_NORMAL,						//后脚 - 加速度正常模式
+	.gry_power_mode 						= FML_IMU_GRY_POWER_MODE_NORMAL,						//后脚 - 陀螺仪正常模式
+	.timestamp_resolution 			= FML_IMU_TIMESTAMP_25US,										//后脚 - 时间戳25US精度
+	.timestamp_switch 					= FML_IMU_TIMESTAMP_OFF,										//后脚 - 时间戳关闭
+	.acc_fs 										= FML_IMU_ACC_FS_16G,											  //后脚 - 加速度量程 - 16G
+	.gry_fs 										= FML_IMU_GRY_FS_2000DPS,										//后脚 - 陀螺仪量程 - 2000DPS
+	.mag_fs 										= FML_IMU_MAG_FS_30GS,											//后脚 - 地磁计量程 - 30GS
+	.acc_odr 										= FML_IMU_ACC_ODR_OFF,											//后脚 - 加速度采样频率 - 关闭
+	.gry_odr 										= FML_IMU_GRY_ODR_OFF,											//后脚 - 陀螺仪采样频率 - 关闭
+	.mag_odr 										= FML_IMU_MAG_ODR_200HZ,										//后脚 - 地磁计采样频率 - 200HZ
+	.fifo_odr 									= FML_IMU_FIFO_ODR_OFF,	
+};
+
+//低功耗
+static const fml_imu_param_t shoes_front_param={
+	.acc_power_mode 						= FML_IMU_ACC_POWER_MODE_NORMAL,						//前脚 - 加速度正常模式
+	.gry_power_mode 						= FML_IMU_GRY_POWER_MODE_NORMAL,						//前脚 - 陀螺仪正常模式
+	.timestamp_resolution 			= FML_IMU_TIMESTAMP_25US,										//前脚 - 时间戳25US精度
+	.timestamp_switch 					= FML_IMU_TIMESTAMP_OFF,										//前脚 - 时间戳关闭
+	.acc_fs 										= FML_IMU_ACC_FS_16G,												//前脚 - 加速度量程 - 16G
+	.gry_fs 										= FML_IMU_GRY_FS_2000DPS,										//前脚 - 陀螺仪量程 - 2000DPS
+	.mag_fs 										= FML_IMU_MAG_FS_30GS,											//前脚 - 地磁计量程 - 30GS
+	.acc_odr 									  = FML_IMU_ACC_ODR_104HZ,										//前脚 - 加速度采样频率 - 104HZ
+	.gry_odr 									  = FML_IMU_GRY_ODR_OFF,										  //前脚 - 陀螺仪采样频率 关闭
+	.mag_odr 									  = FML_IMU_MAG_ODR_100HZ,										//前脚 - 地磁计采样频率 - 100HZ
+	.fifo_odr 									= FML_IMU_FIFO_ODR_104HZ,
+};
+
+static const fml_imu_param_t shoes_back_param={
+	.acc_power_mode 						= FML_IMU_ACC_POWER_MODE_NORMAL,						//后脚 - 加速度正常模式
+	.gry_power_mode 						= FML_IMU_GRY_POWER_MODE_NORMAL,						//后脚 - 陀螺仪正常模式
+	.timestamp_resolution 			= FML_IMU_TIMESTAMP_25US,										//后脚 - 时间戳25US精度
+	.timestamp_switch 					= FML_IMU_TIMESTAMP_OFF,										//后脚 - 时间戳关闭
+	.acc_fs 										= FML_IMU_ACC_FS_16G,												//后脚 - 加速度量程 - 16G
+	.gry_fs 										= FML_IMU_GRY_FS_2000DPS,										//后脚 - 陀螺仪量程 - 2000DPS
+	.mag_fs 										= FML_IMU_MAG_FS_30GS,											//后脚 - 地磁计量程 - 30GS
+	.acc_odr 										= FML_IMU_ACC_ODR_OFF,											//后脚 - 加速度采样频率 - 关闭
+	.gry_odr 										= FML_IMU_GRY_ODR_OFF,											//后脚 - 陀螺仪采样频率 - 关闭
+	.mag_odr 										= FML_IMU_MAG_ODR_OFF,										  //后脚 - 地磁计采样频率 - 200HZ
+	.fifo_odr 									= FML_IMU_FIFO_ODR_OFF,				
+};
+
+//待机模式
+static const fml_imu_param_t standby_front_param={
+	.acc_power_mode 						= FML_IMU_ACC_POWER_MODE_NORMAL,						//前脚 - 加速度正常模式
+	.gry_power_mode 						= FML_IMU_GRY_POWER_MODE_NORMAL,						//前脚 - 陀螺仪正常模式
+	.timestamp_resolution 			= FML_IMU_TIMESTAMP_25US,										//前脚 - 时间戳25US精度
+	.timestamp_switch 					= FML_IMU_TIMESTAMP_OFF,										//前脚 - 时间戳关闭
+	.acc_fs 										= FML_IMU_ACC_FS_16G,												//前脚 - 加速度量程 - 16G
+	.gry_fs 										= FML_IMU_GRY_FS_2000DPS,										//前脚 - 陀螺仪量程 - 2000DPS
+	.mag_fs 										= FML_IMU_MAG_FS_30GS,											//前脚 - 地磁计量程 - 30GS
+	.acc_odr 									  = FML_IMU_ACC_ODR_12HZ5,										//前脚 - 加速度采样频率 - 12.5HZ
+	.gry_odr 									  = FML_IMU_GRY_ODR_OFF,										  //前脚 - 陀螺仪采样频率 - 关闭
+	.mag_odr 									  = FML_IMU_MAG_ODR_OFF,										  //前脚 - 地磁计采样频率 - 关闭
+	.fifo_odr 									= FML_IMU_FIFO_ODR_OFF,										  //前脚 - FIFO采样频率 - 104HZ
+};
+
+static const fml_imu_param_t standby_param={
+	.acc_power_mode 						= FML_IMU_ACC_POWER_MODE_NORMAL,						//后脚 - 加速度正常模式
+	.gry_power_mode 						= FML_IMU_GRY_POWER_MODE_NORMAL,						//后脚 - 陀螺仪正常模式
+	.timestamp_resolution 			= FML_IMU_TIMESTAMP_25US,										//后脚 - 时间戳25US精度
+	.timestamp_switch 					= FML_IMU_TIMESTAMP_OFF,										//后脚 - 时间戳关闭
+	.acc_fs 										= FML_IMU_ACC_FS_16G,												//后脚 - 加速度量程 - 16G
+	.gry_fs 										= FML_IMU_GRY_FS_2000DPS,										//后脚 - 陀螺仪量程 - 2000DPS
+	.mag_fs 										= FML_IMU_MAG_FS_30GS,											//后脚 - 地磁计量程 - 30GS
+	.acc_odr 										= FML_IMU_ACC_ODR_OFF,											//后脚 - 加速度采样频率 - 关闭
+	.gry_odr 										= FML_IMU_GRY_ODR_OFF,											//后脚 - 陀螺仪采样频率 - 关闭
+	.mag_odr 										= FML_IMU_MAG_ODR_10HZ,										  //后脚 - 地磁计采样频率 - 10HZ
+	.fifo_odr 									= FML_IMU_FIFO_ODR_OFF,											//后脚 - FIFO采样频率 - 关闭			
+};
+
+
+typedef struct
+{
+	int16_t max_temp;
+	uint16_t time_count;
+}ACC_TIME_TYPE;
+
+typedef struct
+{
+	ACC_TIME_TYPE slide_window[SLIDE_WINDOW_LEN];
+	
+	int window_length;
+	
+}SLIDE_WINDOW;
+
+int cal_unsigned_D_value(uint16_t left_value, uint16_t right_value)
+{
+	if(left_value <= right_value)
+	{
+		return right_value - left_value;
+	}
+	else
+	{
+		return 65535-left_value + 1 + right_value;
+	}
+}
+
+static uint8_t flag_move =0;
+
+void sort_silde_window(SLIDE_WINDOW *max_slide_window, SLIDE_WINDOW *min_slide_window, int16_t acc_val, uint16_t	time_count)
+{
+	ACC_TIME_TYPE acc_time_type_temp = {acc_val, time_count};
+	
+	//检测当前的值是是否是最大值
+	if(max_slide_window->window_length == 0)
+	{
+		max_slide_window->slide_window[0] = acc_time_type_temp;
+		
+		max_slide_window->window_length = 1;
+	}
+	else
+	{
+		//先判断长度是否溢出来了
+		while(cal_unsigned_D_value(max_slide_window->slide_window[0].time_count, time_count)>= SLIDE_WINDOW_LEN)
+		{
+			memcpy(max_slide_window->slide_window, max_slide_window->slide_window + 1, (SLIDE_WINDOW_LEN - 1) *sizeof(ACC_TIME_TYPE));
+			max_slide_window->window_length --;
+		}
+		
+		//再检测新的元素需要前面的元素小
+		while(max_slide_window->window_length > 0)
+		{
+			if(max_slide_window->slide_window[max_slide_window->window_length - 1].max_temp < acc_val)
+			{
+				max_slide_window->window_length --;
+			}
+			else
+			{
+				break;
+			}
+		}
+		
+		max_slide_window->slide_window[max_slide_window->window_length] = acc_time_type_temp;
+		
+		max_slide_window->window_length ++;
+	}
+	
+	//检测当前的值是是否是最大值
+	if(min_slide_window->window_length == 0)
+	{
+		min_slide_window->slide_window[0] = acc_time_type_temp;
+		min_slide_window->window_length = 1;
+	}
+	else
+	{
+		//先判断长度是否溢出来了
+		while(cal_unsigned_D_value(min_slide_window->slide_window[0].time_count, time_count)>= SLIDE_WINDOW_LEN)
+		{
+			memcpy(min_slide_window->slide_window, min_slide_window->slide_window + 1, (SLIDE_WINDOW_LEN - 1) *sizeof(ACC_TIME_TYPE));
+			min_slide_window->window_length --;
+		}
+		
+		//再检测新的元素需要前面的元素小
+		while(min_slide_window->window_length > 0)
+		{
+			if(min_slide_window->slide_window[min_slide_window->window_length - 1].max_temp > acc_val)
+			{
+				min_slide_window->window_length --;
+			}
+			else
+			{
+				break;
+			}
+		}
+		
+		min_slide_window->slide_window[min_slide_window->window_length] = acc_time_type_temp;
+		
+		min_slide_window->window_length ++;
+	}
+}
+
+/************************ 踮脚显示电量 ***********************************/
+
+//没穿鞋的情况下
+
+void app_BatDispaly_Process_N(void)        
+{
+		ser_imu_data_t data= {0};
+	  static uint8_t lED_LIFE_SIGNAL = 0;
+    static uint8_t lED_LIFE_TIME = 0;
+		
+//	DEBUG_LOG("app_BatDispaly_Process_N;\n");
+		
+		if(-1 == hal_ser_imu_mode_manage_get_ready(HAL_SER_IMU_MODE_MANAGE_STANDBY))
+		{
+			return;//停止状态
+		}
+
+		//获取最新一组前脚加速度
+		int16_t data_size = 0;
+		
+		data_size = hal_ser_imu_mode_manage_get_data_num(SER_IMU_DIR_FRONT);
+		
+	  if(data_size > 0){
+			
+				hal_ser_imu_mode_manage_get_data(SER_IMU_DIR_FRONT, data_size -1 , &data);
+				
+				int32_t acc_norm = (data.acc[0] * data.acc[0] +data.acc[1] * data.acc[1] + data.acc[2] * data.acc[2]);
+				
+				if(abs(acc_norm - 4194304) < 362144 && data.acc[2] > 1536)
+				{
+					lED_LIFE_SIGNAL = 3;
+				}
+				else if(lED_LIFE_SIGNAL > 0)lED_LIFE_SIGNAL --;
+				
+				if(abs(acc_norm - 4194304) < 362144 && data.acc[2] < -1024)
+				{ 
+					lED_LIFE_SIGNAL = 0;
+				}
+				
+//				DEBUG_LOG("acc_norm:%d,lED_LIFE_SIGNAL:%d,data.acc2:%d,lED_LIFE_TIME:%d\n",abs(acc_norm - 4194304),lED_LIFE_SIGNAL,data.acc[2],lED_LIFE_TIME);
+				if(lED_LIFE_SIGNAL > 0)
+				{
+//					DEBUG_LOG("unwearshoes LED_Start(LED_OVERTURN,COLOR_GREEN);;\n");
+					 if(lED_LIFE_TIME == 0){
+								lED_LIFE_TIME = (10000/StandByPower_Interval);
+								if(GetBatteryPersent()>20){
+									LED_Start(LED_OVERTURN,COLOR_GREEN);
+								}else{
+									LED_Start(LED_OVERTURN,COLOR_ORANGE);
+								}
+								Process_SetHoldOn(app_BatDispaly_Process_N,1);
+						 }
+						 else if (2 == lED_LIFE_TIME){
+							  LED_Stop(LED_OVERTURN);
+						    Process_SetHoldOn(app_BatDispaly_Process_N,0);
+						 }
+						 if (lED_LIFE_TIME > 1)lED_LIFE_TIME--;
+				}
+				else
+				{
+//					DEBUG_LOG("unwearshoes LED_Stop(LED_OVERTURN);\n");
+					if(0 != lED_LIFE_TIME ){lED_LIFE_TIME =0;
+					   LED_Stop(LED_OVERTURN);
+					   Process_SetHoldOn(app_BatDispaly_Process_N,0);
+					}
+					if(1 == flag_move){flag_move =0;
+					 LED_Stop(LED_OVERTURN);
+					 Process_SetHoldOn(app_BatDispaly_Process_N,0);
+				  }
+				}
+	 }
+}
+
+//穿鞋的情况下
+void app_BatDispaly_Process(void)
+{
+	  ser_imu_data_t data={0};
+		
+		static uint16_t	time_count = 0;
+		
+		static uint16_t station_count =0;
+		static uint16_t overturn_180_count = 0;
+		static uint8_t lED_LIFE_SIGNAL = 0;
+    static uint8_t lED_LIFE_TIME = 0;
+		
+		static SLIDE_WINDOW max_slide_window = { {-3096,0},0 };
+		static SLIDE_WINDOW min_slide_window = { {3096,0},0 };
+		
+		
+		
+		if(-1 == hal_ser_imu_mode_manage_get_ready(HAL_SER_IMU_MODE_MANAGE_NORMAL))
+		{
+			return;//走路状态
+		}			
+//		DEBUG_LOG("app_BatDispaly_Process;\n");
+		//获取最新一组前脚加速度, 有fifo
+		int16_t data_size = 0;
+		
+		data_size = hal_ser_imu_mode_manage_get_data_num(SER_IMU_DIR_FRONT);
+		
+	  if(data_size > 0){
+			
+//					DEBUG_LOG("data_size : %d,  hal_wearshoes_is_wearshoes: %d\n", data_size,hal_wearshoes_is_wearshoes());
+		
+					hal_ser_imu_mode_manage_get_data(SER_IMU_DIR_FRONT, data_size-1 , &data);
+				
+					//耗时较少的计算滑动窗口的最大值、最小值
+					sort_silde_window(&max_slide_window, &min_slide_window,  data.acc[0], time_count);
+					
+					if(time_count > SLIDE_WINDOW_LEN)
+					{
+						if(data.acc[0] - min_slide_window.slide_window[0].max_temp < 256 &&  max_slide_window.slide_window[0].max_temp -  data.acc[0] < 256
+							&& max_slide_window.slide_window[0].max_temp  - min_slide_window.slide_window[0].max_temp < 256 &&  data.acc[0] < -1400)
+						{
+							station_count++;
+						}
+						else station_count =0;
+					}
+					
+					time_count++;
+					
+					//在穿鞋状态下,被翻转了
+					int32_t acc_norm = (data.acc[0] * data.acc[0] +data.acc[1] * data.acc[1] + data.acc[2] * data.acc[2]);
+					if(abs(acc_norm - 4194304) < 362144 && data.acc[2] > 1536)
+					{
+						//DEBUG_LOG(" wear shoes if(abs(acc_norm - 4194304) < 262144 && data.acc[2] > 1536);\n");
+						overturn_180_count ++;
+					}
+					else
+					{
+						overturn_180_count = 0;
+					}
+					
+					if(overturn_180_count >= 5 || station_count > 4)
+					{
+//						 DEBUG_LOG(" overturn_180_count > 5;\n");
+						lED_LIFE_SIGNAL = 6;
+					}
+					
+					if(lED_LIFE_SIGNAL > 0)lED_LIFE_SIGNAL --;
+					
+					if(lED_LIFE_SIGNAL > 0)
+					{
+//						DEBUG_LOG("wearshoes LED_Start(LED_OVERTURN,COLOR_GREEN);;\n");
+						 if(lED_LIFE_TIME == 0){
+								lED_LIFE_TIME = (10000/LowPower_Interval);
+								if(GetBatteryPersent()>20){
+									LED_Start(LED_OVERTURN,COLOR_GREEN);
+								}else{
+									LED_Start(LED_OVERTURN,COLOR_ORANGE);
+								}
+								Process_SetHoldOn(app_BatDispaly_Process,1);
+						 }
+						 else if (2 == lED_LIFE_TIME){
+							  LED_Stop(LED_OVERTURN);
+						    Process_SetHoldOn(app_BatDispaly_Process,0);
+						 }
+						 if (lED_LIFE_TIME > 1)lED_LIFE_TIME--;
+					}
+					else
+					{
+//						DEBUG_LOG("wearshoes LED_Stop(LED_OVERTURN);\n");
+						if(0 != lED_LIFE_TIME ){lED_LIFE_TIME =0;
+					    LED_Stop(LED_OVERTURN);
+					    Process_SetHoldOn(app_BatDispaly_Process,0);
+					  }
+						if(0 == flag_move){flag_move =1;
+							 LED_Stop(LED_OVERTURN);
+							 Process_SetHoldOn(app_BatDispaly_Process_N,0);
+				    }
+					}
+		}
+		
+}
+
+
+void app_overturn_Init(void)
+{
+	Process_Start(LowPower_Interval,"BatDispaly",app_BatDispaly_Process);
+	Process_Start(StandByPower_Interval,"BatDispaly_N",app_BatDispaly_Process_N);
+	fml_imu_mode_manage_imu_full_power_init(&app1_config_param.config_param[BLL_IMU_DIR_FRONT], &app1_config_param.config_param[BLL_IMU_DIR_BACK]);
+	
+}

+ 256 - 0
shoe_mcu2.2.1_new_v2/app/app_overturn - 副本.c

@@ -0,0 +1,256 @@
+#include "usr_config.h"
+#include "hal_battery.h"
+#include "nrf_drv_saadc.h"
+#include "bsp_time.h"
+#include "system.h"
+#include "hal_led.h"
+#include "hal_ser_imu_mode_manage.h"
+#include "app_overturn.h"
+#include "hal_wearshoes.h"
+
+
+#include "ble_comm.h"
+
+#define SLIDE_WINDOW_LEN 5
+				
+
+typedef struct
+{
+	int16_t max_temp;
+	uint16_t time_count;
+}ACC_TIME_TYPE;
+
+typedef struct
+{
+	ACC_TIME_TYPE slide_window[SLIDE_WINDOW_LEN];
+	
+	int window_length;
+	
+}SLIDE_WINDOW;
+
+void sort_silde_window(SLIDE_WINDOW *max_slide_window, SLIDE_WINDOW *min_slide_window, int16_t acc_val, uint16_t	time_count)
+{
+		ACC_TIME_TYPE acc_time_type_temp = {acc_val, time_count};
+	
+	//检测当前的值是是否是最大值
+	if(max_slide_window->window_length == 0)
+	{
+		max_slide_window->slide_window[0] = acc_time_type_temp;
+		
+		max_slide_window->window_length = 1;
+	}
+	else
+	{
+		//先判断长度是否溢出来了
+		while(time_count - max_slide_window->slide_window[0].time_count >= SLIDE_WINDOW_LEN)
+		{
+			memcpy(max_slide_window->slide_window, max_slide_window->slide_window + 1, (SLIDE_WINDOW_LEN - 1) *sizeof(ACC_TIME_TYPE));
+			max_slide_window->window_length --;
+		}
+		
+		//再检测新的元素需要前面的元素小
+		while(max_slide_window->window_length > 0)
+		{
+			if(max_slide_window->slide_window[max_slide_window->window_length - 1].max_temp < acc_val)
+			{
+				max_slide_window->window_length --;
+			}
+			else
+			{
+				break;
+			}
+		}
+		
+		max_slide_window->slide_window[max_slide_window->window_length] = acc_time_type_temp;
+		
+		max_slide_window->window_length ++;
+	}
+	
+	//检测当前的值是是否是最大值
+	if(min_slide_window->window_length == 0)
+	{
+		min_slide_window->slide_window[0] = acc_time_type_temp;
+		min_slide_window->window_length = 1;
+	}
+	else
+	{
+		//先判断长度是否溢出来了
+		while(time_count - min_slide_window->slide_window[0].time_count >= SLIDE_WINDOW_LEN)
+		{
+			memcpy(min_slide_window->slide_window, min_slide_window->slide_window + 1, (SLIDE_WINDOW_LEN - 1) *sizeof(ACC_TIME_TYPE));
+			min_slide_window->window_length --;
+		}
+		
+		//再检测新的元素需要前面的元素小
+		while(min_slide_window->window_length > 0)
+		{
+			if(min_slide_window->slide_window[min_slide_window->window_length - 1].max_temp > acc_val)
+			{
+				min_slide_window->window_length --;
+			}
+			else
+			{
+				break;
+			}
+		}
+		
+		min_slide_window->slide_window[min_slide_window->window_length] = acc_time_type_temp;
+		
+		min_slide_window->window_length ++;
+	}
+}
+
+/************************ 踮脚显示电量 ***********************************/
+
+//没穿鞋的情况下
+
+void app_BatDispaly_Process_N(void)        
+{
+		ser_imu_data_t data;
+	
+		static uint8_t	led_light_count  = -1;
+		
+		static uint8_t station_count =0;
+	
+		static int LED_LIVE_TIME = 0;
+
+//		DEBUG_LOG("app_BatDispaly_Process_N;\n");
+		
+					
+		if(-1 == hal_ser_imu_mode_manage_get_ready(HAL_SER_IMU_MODE_MANAGE_STANDBY))
+		{
+			return;//停止状态
+		}
+
+		//获取最新一组前脚加速度
+		int16_t data_size = 0;
+		
+		data_size = hal_ser_imu_mode_manage_get_data_num(SER_IMU_DIR_FRONT);
+		
+		
+	  if(data_size > 0){
+			 
+				hal_ser_imu_mode_manage_get_data(SER_IMU_DIR_FRONT, data_size -1 , &data);
+				
+				int32_t acc_norm = (data.acc[0] * data.acc[0] +data.acc[1] * data.acc[1] + data.acc[2] * data.acc[2]);
+				
+//				if(abs(acc_norm - 4194304) < 262144  && data.acc[2] > 1536)
+//					station_count =1;
+//				else 
+//					station_count =0;
+//				
+//				if(abs(acc_norm - 4194304) < 262144 && data.acc[2] < -1024)
+//					station_count =0;
+			
+			  if(data.acc[2] > 1200)
+					station_count =1;
+				else 
+					station_count =0;
+				
+          
+				DEBUG_LOG("acc_norm:%d,station_count:%d,data.acc2:%d\n",abs(acc_norm - 4194304),station_count,data.acc[2]);
+				if(station_count > 0){
+						if(0 == LED_LIVE_TIME){
+							LED_LIVE_TIME = (10000/StandByPower_Interval);
+							if(GetBatteryPersent()>20){
+								LED_Start(LED_OVERTURN,COLOR_GREEN);
+							}else{
+								LED_Start(LED_OVERTURN,COLOR_ORANGE);
+							}
+							Process_SetHoldOn(app_BatDispaly_Process_N,1);
+						}
+						else if (2 == LED_LIVE_TIME){
+							LED_Stop(LED_OVERTURN);
+						  Process_SetHoldOn(app_BatDispaly_Process_N,0);
+						}
+						if (LED_LIVE_TIME > 1)LED_LIVE_TIME--;
+				}
+				else if (LED_LIVE_TIME > 0 && 0 == station_count){LED_LIVE_TIME=0;
+						LED_Stop(LED_OVERTURN);
+						Process_SetHoldOn(app_BatDispaly_Process_N,0);
+				}
+	 }
+}
+
+//穿鞋的情况下
+void app_BatDispaly_Process(void)
+{
+	  ser_imu_data_t data={0};
+		
+		static uint16_t	time_count = 0;
+		
+		static uint16_t station_count= 0;
+		
+		static SLIDE_WINDOW max_slide_window = { {-3096,0},0 };
+		static SLIDE_WINDOW min_slide_window = { {3096,0},0 };
+		
+		static uint16_t overturn_180_count = 0;
+		
+		static uint8_t lED_LIFE_TIME = 0;
+
+		if(-1 == hal_ser_imu_mode_manage_get_ready(HAL_SER_IMU_MODE_MANAGE_NORMAL))
+		{
+			return;//走路状态
+		}			
+//		DEBUG_LOG("app_BatDispaly_Process;\n");
+		//获取最新一组前脚加速度, 有fifo
+		int16_t data_size = 0;
+		
+		data_size = hal_ser_imu_mode_manage_get_data_num(SER_IMU_DIR_FRONT);
+		
+	  if(data_size > 0){
+			
+//					DEBUG_LOG("data_size : %d,  hal_wearshoes_is_wearshoes: %d\n", data_size,hal_wearshoes_is_wearshoes());
+		
+					hal_ser_imu_mode_manage_get_data(SER_IMU_DIR_FRONT, data_size-1 , &data);
+				
+					//耗时较少的计算滑动窗口的最大值、最小值
+					sort_silde_window(&max_slide_window, &min_slide_window,  data.acc[0], time_count);
+					
+					if(time_count > SLIDE_WINDOW_LEN){
+						if(data.acc[0] - min_slide_window.slide_window[0].max_temp < 256 &&  max_slide_window.slide_window[0].max_temp -  data.acc[0] < 256
+							&& max_slide_window.slide_window[0].max_temp  - min_slide_window.slide_window[0].max_temp < 256 &&  data.acc[0] < -308){
+							station_count =6;
+						}
+						else if(station_count > 0)station_count--;
+					}
+					time_count++;
+					
+					//在穿鞋状态下,被翻转了
+				  int32_t acc_norm = (data.acc[0] * data.acc[0] +data.acc[1] * data.acc[1] + data.acc[2] * data.acc[2]);
+					if(abs(acc_norm - 4194304) < 362144 && data.acc[2] > 1536)
+						overturn_180_count ++;
+					else 
+						overturn_180_count = 0;
+		
+					DEBUG_LOG("acc_norm:%d,station_count:%d,overturn_180_count:%d\n",abs(acc_norm - 4194304),station_count,overturn_180_count);
+          if(station_count > 0 || overturn_180_count >= 5){
+						if(0 == lED_LIFE_TIME){
+							lED_LIFE_TIME = (10000/LowPower_Interval);
+							if(GetBatteryPersent()>20){
+								LED_Start(LED_OVERTURN,COLOR_GREEN);
+							}else{
+								LED_Start(LED_OVERTURN,COLOR_ORANGE);
+							}
+							Process_SetHoldOn(app_BatDispaly_Process,1);
+						}
+						else if (2 == lED_LIFE_TIME){
+							LED_Stop(LED_OVERTURN);
+						  Process_SetHoldOn(app_BatDispaly_Process,0);
+						}
+						if (lED_LIFE_TIME > 1)lED_LIFE_TIME--;
+					}
+					else if (lED_LIFE_TIME > 0 && (0 == station_count && 0 == overturn_180_count)){lED_LIFE_TIME=0;
+						LED_Stop(LED_OVERTURN);
+						Process_SetHoldOn(app_BatDispaly_Process,0);
+					}
+		}
+		
+}
+
+
+void app_overturn_Init(void)
+{
+	Process_Start(LowPower_Interval,"BatDispaly",app_BatDispaly_Process);
+	Process_Start(StandByPower_Interval,"BatDispaly_N",app_BatDispaly_Process_N);
+}

+ 285 - 0
shoe_mcu2.2.1_new_v2/app/app_overturn.c

@@ -0,0 +1,285 @@
+#include "usr_config.h"
+#include "hal_battery.h"
+#include "nrf_drv_saadc.h"
+#include "bsp_time.h"
+#include "system.h"
+#include "hal_led.h"
+#include "app_overturn.h"
+#include "hal_wearshoes.h"
+#include "bll_imu.h"
+
+#include "ble_comm.h"
+
+#define SLIDE_WINDOW_LEN 5
+
+typedef struct
+{
+	int16_t max_temp;
+	uint16_t time_count;
+}ACC_TIME_TYPE;
+
+typedef struct
+{
+	ACC_TIME_TYPE slide_window[SLIDE_WINDOW_LEN];
+	
+	int window_length;
+	
+}SLIDE_WINDOW;
+
+int cal_unsigned_D_value(uint16_t left_value, uint16_t right_value)
+{
+	if(left_value <= right_value)
+	{
+		return right_value - left_value;
+	}
+	else
+	{
+		return 65535-left_value + 1 + right_value;
+	}
+}
+
+static uint8_t flag_move =0;
+
+void sort_silde_window(SLIDE_WINDOW *max_slide_window, SLIDE_WINDOW *min_slide_window, int16_t acc_val, uint16_t	time_count)
+{
+	ACC_TIME_TYPE acc_time_type_temp = {acc_val, time_count};
+	
+	//检测当前的值是是否是最大值
+	if(max_slide_window->window_length == 0)
+	{
+		max_slide_window->slide_window[0] = acc_time_type_temp;
+		
+		max_slide_window->window_length = 1;
+	}
+	else
+	{
+		//先判断长度是否溢出来了
+		while(cal_unsigned_D_value(max_slide_window->slide_window[0].time_count, time_count)>= SLIDE_WINDOW_LEN)
+		{
+			memcpy(max_slide_window->slide_window, max_slide_window->slide_window + 1, (SLIDE_WINDOW_LEN - 1) *sizeof(ACC_TIME_TYPE));
+			max_slide_window->window_length --;
+		}
+		
+		//再检测新的元素需要前面的元素小
+		while(max_slide_window->window_length > 0)
+		{
+			if(max_slide_window->slide_window[max_slide_window->window_length - 1].max_temp < acc_val)
+			{
+				max_slide_window->window_length --;
+			}
+			else
+			{
+				break;
+			}
+		}
+		
+		max_slide_window->slide_window[max_slide_window->window_length] = acc_time_type_temp;
+		
+		max_slide_window->window_length ++;
+	}
+	
+	//检测当前的值是是否是最大值
+	if(min_slide_window->window_length == 0)
+	{
+		min_slide_window->slide_window[0] = acc_time_type_temp;
+		min_slide_window->window_length = 1;
+	}
+	else
+	{
+		//先判断长度是否溢出来了
+		while(cal_unsigned_D_value(min_slide_window->slide_window[0].time_count, time_count)>= SLIDE_WINDOW_LEN)
+		{
+			memcpy(min_slide_window->slide_window, min_slide_window->slide_window + 1, (SLIDE_WINDOW_LEN - 1) *sizeof(ACC_TIME_TYPE));
+			min_slide_window->window_length --;
+		}
+		
+		//再检测新的元素需要前面的元素小
+		while(min_slide_window->window_length > 0)
+		{
+			if(min_slide_window->slide_window[min_slide_window->window_length - 1].max_temp > acc_val)
+			{
+				min_slide_window->window_length --;
+			}
+			else
+			{
+				break;
+			}
+		}
+		
+		min_slide_window->slide_window[min_slide_window->window_length] = acc_time_type_temp;
+		
+		min_slide_window->window_length ++;
+	}
+}
+
+/************************ 踮脚显示电量 ***********************************/
+
+//没穿鞋的情况下
+void app_BatDispaly_Process_N(void)        
+{
+		bll_imu_data_t data= {0};
+	  static uint8_t lED_LIFE_SIGNAL = 0;
+    static uint8_t lED_LIFE_TIME = 0;
+		
+//	DEBUG_LOG("app_BatDispaly_Process_N;\n");
+		if(hal_wearshoes_is_wearshoes())return;
+			
+		//获取最新一组前脚加速度
+		int16_t data_size = 0;
+		
+		data_size = bll_imu_get_data_num(BLL_IMU_DIR_FRONT);
+		
+		if(data_size > 0){
+			
+				bll_imu_get_data(BLL_IMU_DIR_FRONT, data_size -1 , &data);
+				
+				int32_t acc_norm = (data.acc[0] * data.acc[0] +data.acc[1] * data.acc[1] + data.acc[2] * data.acc[2]);
+				
+				if(abs(acc_norm - 4194304) < 362144 && data.acc[2] > 1536)
+				{
+					lED_LIFE_SIGNAL = 3;
+				}
+				else if(lED_LIFE_SIGNAL > 0)lED_LIFE_SIGNAL --;
+				
+				if(abs(acc_norm - 4194304) < 362144 && data.acc[2] < -1024)
+				{ 
+					lED_LIFE_SIGNAL = 0;
+				}
+				
+//				DEBUG_LOG("acc_norm:%d,lED_LIFE_SIGNAL:%d,data.acc2:%d,lED_LIFE_TIME:%d\n",abs(acc_norm - 4194304),lED_LIFE_SIGNAL,data.acc[2],lED_LIFE_TIME);
+				if(lED_LIFE_SIGNAL > 0)
+				{
+//					DEBUG_LOG("unwearshoes LED_Start(LED_OVERTURN,COLOR_GREEN);;\n");
+					 if(lED_LIFE_TIME == 0){
+								lED_LIFE_TIME = (10000/StandByPower_Interval);
+								if(GetBatteryPersent()>20){
+									LED_Start(LED_OVERTURN,COLOR_GREEN);
+								}else{
+									LED_Start(LED_OVERTURN,COLOR_ORANGE);
+								}
+								Process_SetHoldOn(app_BatDispaly_Process_N,1);
+						 }
+						 else if (2 == lED_LIFE_TIME){
+								LED_Stop(LED_OVERTURN);
+								Process_SetHoldOn(app_BatDispaly_Process_N,0);
+						 }
+						 if (lED_LIFE_TIME > 1)lED_LIFE_TIME--;
+				}
+				else
+				{
+//					DEBUG_LOG("unwearshoes LED_Stop(LED_OVERTURN);\n");
+						if(0 != lED_LIFE_TIME ){lED_LIFE_TIME =0;
+							 LED_Stop(LED_OVERTURN);
+							 Process_SetHoldOn(app_BatDispaly_Process_N,0);
+						}
+						if(1 == flag_move){flag_move =0;
+						 LED_Stop(LED_OVERTURN);
+						 Process_SetHoldOn(app_BatDispaly_Process_N,0);
+						}
+				}
+			}
+}
+
+//穿鞋的情况下
+void app_BatDispaly_Process(void)
+{
+	  bll_imu_data_t data={0};
+		
+		static uint16_t	time_count = 0;
+		
+		static uint16_t station_count =0;
+		static uint16_t overturn_180_count = 0;
+		static uint8_t lED_LIFE_SIGNAL = 0;
+    static uint8_t lED_LIFE_TIME = 0;
+		
+		static SLIDE_WINDOW max_slide_window = { {-3096,0},0 };
+		static SLIDE_WINDOW min_slide_window = { {3096,0},0 };
+		
+    if(!hal_wearshoes_is_wearshoes())return;
+		
+//		DEBUG_LOG("app_BatDispaly_Process;\n");
+		//获取最新一组前脚加速度, 有fifo
+		int16_t data_size = 0;
+		
+		data_size = bll_imu_get_data_num(BLL_IMU_DIR_FRONT);
+		
+		if(data_size > 0){
+			
+//					DEBUG_LOG("data_size : %d,  hal_wearshoes_is_wearshoes: %d\n", data_size,hal_wearshoes_is_wearshoes());
+		
+					bll_imu_get_data(BLL_IMU_DIR_FRONT, data_size-1 , &data);
+				
+					//耗时较少的计算滑动窗口的最大值、最小值
+					sort_silde_window(&max_slide_window, &min_slide_window,  data.acc[0], time_count);
+					
+					if(time_count > SLIDE_WINDOW_LEN)
+					{
+						if(data.acc[0] - min_slide_window.slide_window[0].max_temp < 256 &&  max_slide_window.slide_window[0].max_temp -  data.acc[0] < 256
+							&& max_slide_window.slide_window[0].max_temp  - min_slide_window.slide_window[0].max_temp < 256 &&  data.acc[0] < -1400)
+						{
+							station_count++;
+						}
+						else station_count =0;
+					}
+					
+					time_count++;
+					
+					//在穿鞋状态下,被翻转了
+					int32_t acc_norm = (data.acc[0] * data.acc[0] +data.acc[1] * data.acc[1] + data.acc[2] * data.acc[2]);
+					if(abs(acc_norm - 4194304) < 362144 && data.acc[2] > 1536)
+					{
+						//DEBUG_LOG(" wear shoes if(abs(acc_norm - 4194304) < 262144 && data.acc[2] > 1536);\n");
+						overturn_180_count ++;
+					}
+					else
+					{
+						overturn_180_count = 0;
+					}
+					
+					if(overturn_180_count >= 5 || station_count > 4)
+					{
+//						 DEBUG_LOG(" overturn_180_count > 5;\n");
+						lED_LIFE_SIGNAL = 6;
+					}
+					
+					if(lED_LIFE_SIGNAL > 0)lED_LIFE_SIGNAL --;
+					
+					if(lED_LIFE_SIGNAL > 0)
+					{
+//						DEBUG_LOG("wearshoes LED_Start(LED_OVERTURN,COLOR_GREEN);;\n");
+						 if(lED_LIFE_TIME == 0){
+								lED_LIFE_TIME = (10000/LowPower_Interval);
+								if(GetBatteryPersent()>20){
+									LED_Start(LED_OVERTURN,COLOR_GREEN);
+								}else{
+									LED_Start(LED_OVERTURN,COLOR_ORANGE);
+								}
+								Process_SetHoldOn(app_BatDispaly_Process,1);
+						 }
+						 else if (2 == lED_LIFE_TIME){
+								LED_Stop(LED_OVERTURN);
+								Process_SetHoldOn(app_BatDispaly_Process,0);
+						 }
+						 if (lED_LIFE_TIME > 1)lED_LIFE_TIME--;
+					}
+					else
+					{
+//						DEBUG_LOG("wearshoes LED_Stop(LED_OVERTURN);\n");
+						if(0 != lED_LIFE_TIME ){lED_LIFE_TIME =0;
+							LED_Stop(LED_OVERTURN);
+							Process_SetHoldOn(app_BatDispaly_Process,0);
+						}
+						if(0 == flag_move){flag_move =1;
+							 LED_Stop(LED_OVERTURN);
+							 Process_SetHoldOn(app_BatDispaly_Process_N,0);
+						}
+					}
+		}
+}
+
+
+void app_overturn_Init(void)
+{
+	Process_Start(LowPower_Interval,"BatDispaly",app_BatDispaly_Process);
+	Process_Start(StandByPower_Interval,"BatDispaly_N",app_BatDispaly_Process_N);
+}

+ 14 - 0
shoe_mcu2.2.1_new_v2/app/app_overturn.h

@@ -0,0 +1,14 @@
+#ifndef __app_overturn_h__
+#define __app_overturn_h__
+#include <stdbool.h>
+#include <stdint.h>
+#include <string.h>
+#include "sdk_common.h"
+#include "SEGGER_RTT.h"
+#include "usr_config.h"
+
+void app_overturn_Init(void);
+
+#endif
+
+

+ 258 - 0
shoe_mcu2.2.1_new_v2/app/app_overturn_备份.c

@@ -0,0 +1,258 @@
+#include "usr_config.h"
+#include "hal_battery.h"
+#include "nrf_drv_saadc.h"
+#include "bsp_time.h"
+#include "system.h"
+#include "hal_led.h"
+#include "hal_ser_imu_mode_manage.h"
+#include "app_overturn.h"
+#include "hal_wearshoes.h"
+
+
+#include "ble_comm.h"
+
+#define SLIDE_WINDOW_LEN 5
+				
+
+typedef struct
+{
+	int16_t max_temp;
+	uint16_t time_count;
+}ACC_TIME_TYPE;
+
+typedef struct
+{
+	ACC_TIME_TYPE slide_window[SLIDE_WINDOW_LEN];
+	
+	int window_length;
+	
+}SLIDE_WINDOW;
+
+void sort_silde_window(SLIDE_WINDOW *max_slide_window, SLIDE_WINDOW *min_slide_window, int16_t acc_val, uint16_t	time_count)
+{
+		ACC_TIME_TYPE acc_time_type_temp = {acc_val, time_count};
+	
+	//检测当前的值是是否是最大值
+	if(max_slide_window->window_length == 0)
+	{
+		max_slide_window->slide_window[0] = acc_time_type_temp;
+		
+		max_slide_window->window_length = 1;
+	}
+	else
+	{
+		//先判断长度是否溢出来了
+		while(time_count - max_slide_window->slide_window[0].time_count >= SLIDE_WINDOW_LEN)
+		{
+			memcpy(max_slide_window->slide_window, max_slide_window->slide_window + 1, (SLIDE_WINDOW_LEN - 1) *sizeof(ACC_TIME_TYPE));
+			max_slide_window->window_length --;
+		}
+		
+		//再检测新的元素需要前面的元素小
+		while(max_slide_window->window_length > 0)
+		{
+			if(max_slide_window->slide_window[max_slide_window->window_length - 1].max_temp < acc_val)
+			{
+				max_slide_window->window_length --;
+			}
+			else
+			{
+				break;
+			}
+		}
+		
+		max_slide_window->slide_window[max_slide_window->window_length] = acc_time_type_temp;
+		
+		max_slide_window->window_length ++;
+	}
+	
+	//检测当前的值是是否是最大值
+	if(min_slide_window->window_length == 0)
+	{
+		min_slide_window->slide_window[0] = acc_time_type_temp;
+		min_slide_window->window_length = 1;
+	}
+	else
+	{
+		//先判断长度是否溢出来了
+		while(time_count - min_slide_window->slide_window[0].time_count >= SLIDE_WINDOW_LEN)
+		{
+			memcpy(min_slide_window->slide_window, min_slide_window->slide_window + 1, (SLIDE_WINDOW_LEN - 1) *sizeof(ACC_TIME_TYPE));
+			min_slide_window->window_length --;
+		}
+		
+		//再检测新的元素需要前面的元素小
+		while(min_slide_window->window_length > 0)
+		{
+			if(min_slide_window->slide_window[min_slide_window->window_length - 1].max_temp > acc_val)
+			{
+				min_slide_window->window_length --;
+			}
+			else
+			{
+				break;
+			}
+		}
+		
+		min_slide_window->slide_window[min_slide_window->window_length] = acc_time_type_temp;
+		
+		min_slide_window->window_length ++;
+	}
+}
+
+/************************ 踮脚显示电量 ***********************************/
+
+//没穿鞋的情况下
+
+void app_BatDispaly_Process_N(void)        
+{
+		ser_imu_data_t data;
+	
+		static uint16_t	led_light_count  = -1;
+		
+		static uint16_t station_count;
+	
+		static int LED_LIVE_TIME = 0;
+
+//		DEBUG_LOG("app_BatDispaly_Process_N;\n");
+		
+					
+		if(-1 == hal_ser_imu_mode_manage_get_ready(HAL_SER_IMU_MODE_MANAGE_STANDBY))
+		{
+			return;//停止状态
+		}
+
+		//获取最新一组前脚加速度
+		int16_t data_size = 0;
+		
+		data_size = hal_ser_imu_mode_manage_get_data_num(SER_IMU_DIR_FRONT);
+		
+		
+	  if(data_size > 0){
+			
+
+				hal_ser_imu_mode_manage_get_data(SER_IMU_DIR_FRONT, data_size -1 , &data);
+				
+				int32_t acc_norm = (data.acc[0] * data.acc[0] +data.acc[1] * data.acc[1] + data.acc[2] * data.acc[2]);
+				
+				if(abs(acc_norm - 4194304) < 262144 && data.acc[2] > 1536)
+				{
+					LED_LIVE_TIME = 3;
+				}
+				else
+				{
+				  LED_LIVE_TIME --;
+				}
+				
+				if(LED_LIVE_TIME > 0)
+				{
+//					DEBUG_LOG("unwearshoes LED_Start(LED_OVERTURN,COLOR_GREEN);;\n");
+					
+					if(GetBatteryPersent()>20){
+							LED_Start(LED_OVERTURN,COLOR_GREEN);
+					}
+					else{
+							LED_Start(LED_OVERTURN,COLOR_ORANGE);
+					}
+						
+					Process_SetHoldOn(app_BatDispaly_Process_N,1);
+				}
+				else
+				{
+//					DEBUG_LOG("unwearshoes LED_Stop(LED_OVERTURN);\n");
+					LED_Stop(LED_OVERTURN);
+					Process_SetHoldOn(app_BatDispaly_Process_N,0);
+				}
+				
+				if(abs(acc_norm - 4194304) < 262144 && data.acc[2] < -1024)
+				{ 
+					LED_LIVE_TIME = 0;
+					LED_Stop(LED_OVERTURN);
+					Process_SetHoldOn(app_BatDispaly_Process_N,0);
+				}
+
+	 }
+}
+
+//穿鞋的情况下
+void app_BatDispaly_Process(void)
+{
+	  ser_imu_data_t data={0};
+		
+		static uint16_t	time_count = 0;
+		
+		static uint16_t station_count= 0;
+		
+		static SLIDE_WINDOW max_slide_window = { {-3096,0},0 };
+		static SLIDE_WINDOW min_slide_window = { {3096,0},0 };
+		
+		static uint16_t overturn_180_count = 0;
+		
+		static uint8_t lED_LIFE_TIME = 0;
+
+		if(-1 == hal_ser_imu_mode_manage_get_ready(HAL_SER_IMU_MODE_MANAGE_NORMAL))
+		{
+			return;//走路状态
+		}			
+//		DEBUG_LOG("app_BatDispaly_Process;\n");
+		//获取最新一组前脚加速度, 有fifo
+		int16_t data_size = 0;
+		
+		data_size = hal_ser_imu_mode_manage_get_data_num(SER_IMU_DIR_FRONT);
+		
+	  if(data_size > 0){
+			
+//					DEBUG_LOG("data_size : %d,  hal_wearshoes_is_wearshoes: %d\n", data_size,hal_wearshoes_is_wearshoes());
+		
+					hal_ser_imu_mode_manage_get_data(SER_IMU_DIR_FRONT, data_size-1 , &data);
+				
+					//耗时较少的计算滑动窗口的最大值、最小值
+					sort_silde_window(&max_slide_window, &min_slide_window,  data.acc[0], time_count);
+					
+					if(time_count > SLIDE_WINDOW_LEN){
+						if(data.acc[0] - min_slide_window.slide_window[0].max_temp < 256 &&  max_slide_window.slide_window[0].max_temp -  data.acc[0] < 256
+							&& max_slide_window.slide_window[0].max_temp  - min_slide_window.slide_window[0].max_temp < 256 &&  data.acc[0] < -308){
+							station_count ++;
+						}
+						else station_count = 0;
+					}
+					time_count++;
+					
+					//在穿鞋状态下,被翻转了
+					int32_t acc_norm = (data.acc[0] * data.acc[0] +data.acc[1] * data.acc[1] + data.acc[2] * data.acc[2]);
+					if(abs(acc_norm - 4194304) < 262144 && data.acc[2] > 1536)
+						overturn_180_count ++;
+					else 
+						overturn_180_count = 0;
+		
+					
+          if(station_count > 0 || overturn_180_count >= 5){
+						if(0 == lED_LIFE_TIME){
+							lED_LIFE_TIME = (10000/LowPower_Interval);
+							if(GetBatteryPersent()>20){
+								LED_Start(LED_OVERTURN,COLOR_GREEN);
+							}else{
+								LED_Start(LED_OVERTURN,COLOR_ORANGE);
+							}
+							Process_SetHoldOn(app_BatDispaly_Process,1);
+						}
+						else if (2 == lED_LIFE_TIME){
+							LED_Stop(LED_OVERTURN);
+						  Process_SetHoldOn(app_BatDispaly_Process,0);
+						}
+						if (lED_LIFE_TIME > 1)lED_LIFE_TIME--;
+					}
+					else if (lED_LIFE_TIME > 0){lED_LIFE_TIME=0;
+						LED_Stop(LED_OVERTURN);
+						Process_SetHoldOn(app_BatDispaly_Process,0);
+					}
+		}
+		
+}
+
+
+void app_overturn_Init(void)
+{
+	Process_Start(100,"BatDispaly",app_BatDispaly_Process);
+	Process_Start(StandByPower_Interval,"BatDispaly_N",app_BatDispaly_Process_N);
+}

+ 760 - 0
shoe_mcu2.2.1_new_v2/app/app_pair_chargerpin.c

@@ -0,0 +1,760 @@
+#include "usr_config.h"
+#include "bsp_time.h"
+#include "system.h"
+#include "nrf_gpio.h"
+#include "app_charge.h"
+#include "app_flash.h"
+#include "ble_comm.h"
+#include "bsp_adc.h"
+#include "app_pair_chargerpin.h"
+
+#define PIN_LED_RUN 2
+
+#define NO_BUTTON 0
+#define DATA_LENGTH 4
+#define BITWIDTH 40
+#define LOW_BIT_DELAY 20
+#define DELAY_SEND 100
+#define DELAY_REPLY 100
+#define DELAY_CHECK 100
+#define DELAY_LEDON (BITWIDTH*(8*DATA_LENGTH+3)*2+DELAY_SEND+DELAY_REPLY+DELAY_CHECK+5*BITWIDTH)
+#define LEDON_KEEP 100
+unsigned static char rxbuf[DATA_LENGTH];
+unsigned static char txbuf[DATA_LENGTH];
+__IO static char writefig=0;
+unsigned static char savebuf[DATA_LENGTH];
+
+static char one_ms_status = 0;
+static void chargerpin_one_ms_pcs(void* t)
+{
+    unsigned int ms = *(unsigned int*)t;
+    static unsigned int bit_width = 0;
+    static unsigned int now_bit = 0;
+    static unsigned int delay_send_count = 0;
+    static unsigned int delay_reply_count = 0;
+    static unsigned int delay_check_count = 0;
+    static unsigned int delay_ledon_count = 0;
+    static int bitindex = 0;
+    static int bytesindes = 0;
+    static int value = 0;
+    static int txrxcount = 0;
+
+		static char lowbitdelay=0;
+    switch (one_ms_status)
+    {
+        case 0://init				
+						bit_width = 0;
+						now_bit = 0;
+						delay_send_count = 0;
+						delay_reply_count = 0;
+						delay_check_count = 0;
+						delay_ledon_count = 0;
+						bitindex = 0;
+						bytesindes = 0;
+						value = 0;
+						txrxcount = 0;
+						one_ms_status = 0;
+						lowbitdelay=0;
+            nrf_gpio_cfg(
+                PIN_CHARGING,
+                NRF_GPIO_PIN_DIR_OUTPUT,
+                NRF_GPIO_PIN_INPUT_CONNECT,
+                NRF_GPIO_PIN_NOPULL,
+                NRF_GPIO_PIN_D0H1,
+                NRF_GPIO_PIN_NOSENSE);
+            nrf_gpio_cfg_watcher(PIN_CHARGING);
+            one_ms_status = 1;
+            nrf_gpio_pin_clear(PIN_CHARGING);
+            PAIR_CHARGERPIN_PRINT("nrf_gpio_cfg_watcher(PIN_CHARGING); clear.%d\r\n", ms);
+            break;
+        case 1:
+            if (now_bit == nrf_gpio_pin_read(PIN_CHARGING))
+            {
+              bit_width++;
+							//左鞋自动触发配对
+							#if NO_BUTTON							
+							if(mFlash.isHost)
+							{
+								if((bit_width>2000)&&(now_bit==0))
+								{
+									nrf_gpio_pin_toggle(PIN_CHARGING);
+								}
+								if((bit_width>BITWIDTH*3)&&(now_bit==1))
+								{
+									nrf_gpio_pin_toggle(PIN_CHARGING);
+								}
+							}
+							#endif
+            }
+            else
+            {
+                //由高电平切换到低电平,下降信号
+                if (now_bit == 1)
+                {
+                    now_bit = 0;
+                    if ((bit_width > 1.5 * BITWIDTH - BITWIDTH/10) && (bit_width < 1.5 * BITWIDTH + BITWIDTH/10))
+                    {
+                        one_ms_status = 3;
+                        txrxcount = 1.5 * BITWIDTH;
+                        value = 30;
+                        if (mFlash.isHost == 0)
+                        {
+                            delay_ledon_count = 1.5 * BITWIDTH + DELAY_SEND;
+                            PAIR_CHARGERPIN_PRINT("delay_ledon_count = 1.5 * BITWIDTH + DELAY_SEND.%d\r\n", txrxcount);
+                        }
+                        else
+                        {
+                            delay_ledon_count = 2.5 * BITWIDTH + DELAY_SEND + BITWIDTH * 8 * DATA_LENGTH + 1.5 * BITWIDTH + DELAY_REPLY;
+                            PAIR_CHARGERPIN_PRINT("delay_ledon_count = 2.5 * BITWIDTH + DELAY_SEND + BITWIDTH*8*DATA_LENGTH + 1.5 * BITWIDTH + DELAY_REPLY .%d\r\n", txrxcount);
+                        }
+                        PAIR_CHARGERPIN_PRINT("-----------------------RX MODE start .%d\r\n", bit_width);
+                        break;
+                    }
+                    else
+                    {
+                        if (mFlash.isHost)
+                        {
+                            delay_send_count = 1; //左边鞋发送数据
+                        }
+                        PAIR_CHARGERPIN_INFO("EXTI CHARGEING MOID.%d bit_width %d \r\n", ms,bit_width);
+                    }
+                }
+                else
+                {
+                    now_bit = 1;
+                    delay_send_count = 0;
+                    delay_reply_count = 0;
+                    delay_check_count = 0;
+                    nrf_gpio_pin_write(PIN_LED_RUN, 0);
+                    delay_ledon_count = 0;
+                    PAIR_CHARGERPIN_PRINT("delay_ledon_count = 0 .%d\r\n", txrxcount);
+                    PAIR_CHARGERPIN_INFO("INTO CHARGEING MOID.%d\r\n", ms);
+                }
+                bit_width = 0;
+            }
+						
+            if (delay_send_count != 0)
+            {
+                delay_send_count++;
+            }
+            if (delay_send_count > DELAY_SEND)
+            {
+                unsigned char macbuff[32];
+                delay_send_count = 0;
+                PAIR_CHARGERPIN_PRINT("BEGIN send MAC.%d\r\n", ms);
+                Get_MACaddr(macbuff);
+                macbuff[DATA_LENGTH - 1] = 0;
+                for (int i = 0; i < DATA_LENGTH - 1; i++)
+                {
+                    macbuff[DATA_LENGTH - 1] += macbuff[i];
+                }
+                memcpy(txbuf, macbuff, DATA_LENGTH);
+                PAIR_CHARGERPIN_PRINT("host_mac send.%d\r\n", ms);
+                one_ms_status = 2;
+								
+                txrxcount = 0;
+                for (int i = 0; i < DATA_LENGTH; i++)
+                {
+                    PAIR_CHARGERPIN_PRINT("txbuf.%x\r\n", txbuf[i]);
+                }
+                break;
+            }
+            if (delay_reply_count != 0)
+            {
+                delay_reply_count++;
+            }
+            if (delay_reply_count > DELAY_REPLY)
+            {
+                unsigned char macbuff[16];
+                delay_reply_count = 0;
+                PAIR_CHARGERPIN_PRINT("BEGIN send MAC.%d\r\n", ms);
+                Get_MACaddr(macbuff);
+                memcpy(txbuf, &macbuff[3], DATA_LENGTH);
+                txbuf[DATA_LENGTH - 1] = 0;
+                for (int i = 0; i < DATA_LENGTH - 1; i++)
+                {
+                    txbuf[DATA_LENGTH - 1] += txbuf[i];
+                }
+                PAIR_CHARGERPIN_PRINT("host_mac send.%d\r\n", ms);
+                one_ms_status = 2;
+                txrxcount = 0;
+                for (int i = 0; i < DATA_LENGTH; i++)
+                {
+                    PAIR_CHARGERPIN_PRINT("txbuf.%x\r\n", txbuf[i]);
+                }
+                break;
+            }
+            if (delay_check_count != 0)
+            {
+                delay_check_count++;
+            }
+            if (delay_check_count > DELAY_CHECK)
+            {
+                delay_check_count = 0;
+                one_ms_status = 4;
+                txrxcount = 0;
+                PAIR_CHARGERPIN_PRINT("CHECK start.%d\r\n", ms);
+                break;
+            }
+            else if (delay_check_count > 0)
+            {
+                if (now_bit > 0)
+                {
+                    delay_check_count = 0;
+                    PAIR_CHARGERPIN_PRINT("CANCEL CHECK.%d\r\n", ms);
+                }
+            }
+            break;
+        case 2://tx
+        {
+						lowbitdelay++;
+            static char send_interrupt = 0;
+            if ((now_bit == 0) && (nrf_gpio_pin_read(PIN_CHARGING)) && (lowbitdelay>LOW_BIT_DELAY))
+            {
+                if (mFlash.isHost)
+                {
+                    one_ms_status = 1;
+                    nrf_gpio_pin_clear(PIN_CHARGING);
+                    PAIR_CHARGERPIN_PRINT("clear.%d\r\n", ms);
+                    delay_ledon_count = 0;
+                    PAIR_CHARGERPIN_PRINT("delay_ledon_count1 = 0;\r\n", txrxcount);
+                    PAIR_CHARGERPIN_PRINT("EXTI SEND MODE.CAN NOT SET LOW  %d\r\n", txrxcount);
+                    send_interrupt = 0;
+                    break;
+                }
+                else
+                {
+                    nrf_gpio_pin_clear(PIN_CHARGING);
+                    PAIR_CHARGERPIN_PRINT("clear.%d\r\n", ms);
+                    send_interrupt = 1;
+                }
+            }
+            if ((txrxcount == 0) && (send_interrupt == 0))
+            {
+                nrf_gpio_pin_set(PIN_CHARGING);
+                PAIR_CHARGERPIN_PRINT("set.%d\r\n", ms);
+                now_bit = 1;
+            }
+            if ((txrxcount == 1.5 * BITWIDTH) && (send_interrupt == 0))
+            {
+                nrf_gpio_pin_clear(PIN_CHARGING);
+                PAIR_CHARGERPIN_PRINT("clear.%d\r\n", ms);
+                now_bit = 0;
+								lowbitdelay=0;
+            }
+            if ((txrxcount >= (int)(2.5 * BITWIDTH) && (txrxcount - (int)(2.5 * BITWIDTH)) % BITWIDTH == 0) && (send_interrupt == 0))
+            {
+                bytesindes = ((txrxcount - (int)(2.5 * BITWIDTH)) / BITWIDTH) / 8;
+                bitindex = 7 - ((txrxcount - (int)(2.5 * BITWIDTH)) / BITWIDTH) % 8;
+                nrf_gpio_pin_write(PIN_CHARGING, (txbuf[bytesindes] >> bitindex) & 0x01);
+								lowbitdelay=0;
+                PAIR_CHARGERPIN_PRINT("write.%d %d\r\n", ((txbuf[bytesindes] >> bitindex) & 0x01), ms);
+                now_bit = (txbuf[bytesindes] >> bitindex) & 0x01;
+                PAIR_CHARGERPIN_PRINT("%d %d %d %d %x\r\n", (txrxcount - (int)(2.5 * BITWIDTH)) / BITWIDTH
+                    , bytesindes
+                    , bitindex
+                    , (txbuf[bytesindes] >> bitindex) & 0x01
+                    , txbuf[bytesindes]
+                );
+            }
+            if (send_interrupt)
+            {
+                if (nrf_gpio_pin_read(PIN_CHARGING) == 0)
+                {
+                    send_interrupt = 0;
+                    delay_ledon_count = DELAY_SEND;
+                    PAIR_CHARGERPIN_PRINT("delay_ledon_count = DELAY_SEND;.%d\r\n", txrxcount);
+                    PAIR_CHARGERPIN_PRINT("RX SEND MODE MAC START.%d\r\n", txrxcount);
+                    txrxcount = 0;
+                    break;
+                }
+            }
+						
+						if (txrxcount == BITWIDTH * (8 * DATA_LENGTH + 2.5) - 1)
+						{
+						    nrf_gpio_pin_clear(PIN_CHARGING);
+                PAIR_CHARGERPIN_PRINT("clear.%d\r\n", ms);
+								if (mFlash.isHost == 0)
+                {
+                    delay_check_count = 1;
+                }
+						}
+						if(delay_check_count!=0)delay_check_count++;
+            if (txrxcount >= BITWIDTH * (8 * DATA_LENGTH + 2.5) - 1 + LOW_BIT_DELAY)
+            {
+                one_ms_status = 1;
+                send_interrupt = 0;
+                now_bit = 0;
+                bit_width = 0;
+                PAIR_CHARGERPIN_PRINT("SEDN DONE .%d pin one_ms_status  %d\r\n", ms,nrf_gpio_pin_read(PIN_CHARGING));
+                break;
+            }
+            txrxcount++;
+        }
+        break;
+        case 3://rx
+            if (now_bit == nrf_gpio_pin_read(PIN_CHARGING))
+            {
+                bit_width++;
+            }
+            else
+            {
+                if (now_bit == 1)
+                {
+                    now_bit = 0;
+                    if ((bit_width > 1.5 * BITWIDTH - 3) && (bit_width < 1.8 * BITWIDTH + 3))
+                    {
+                        txrxcount = 1.5 * BITWIDTH;
+                        value = 30;
+                        delay_ledon_count = DELAY_SEND + 1.5 * BITWIDTH;
+                        PAIR_CHARGERPIN_PRINT("DELAY_SEND + 1.5 * BITWIDTHt .%d\r\n", txrxcount);
+                        PAIR_CHARGERPIN_PRINT("RX MODE restart .%d\r\n", ms);
+                    }
+                }
+                else
+                {
+                    now_bit = 1;
+                }
+                bit_width = 0;
+            }
+            if (txrxcount >= (int)(3.5 * BITWIDTH) && (txrxcount - (int)(3.5 * BITWIDTH)) % BITWIDTH == 0)
+            {
+                bytesindes = ((txrxcount - (int)(3.5 * BITWIDTH)) / BITWIDTH) / 8;
+                bitindex = 7 - ((txrxcount - (int)(3.5 * BITWIDTH)) / BITWIDTH) % 8;
+                if (value > 0)
+                {
+                    rxbuf[bytesindes] |= 0x01 << bitindex;
+                }
+                else
+                {
+                    rxbuf[bytesindes] &= ~(0x01 << bitindex);
+                }
+                PAIR_CHARGERPIN_PRINT("%d %d %d %d %x\r\n", txrxcount
+                    , bytesindes
+                    , bitindex
+                    , value
+                    , rxbuf[bytesindes]
+                );
+                value = 0;
+                nrf_gpio_pin_toggle(PIN_LED_RUN);
+            }
+            else
+            {
+                if (now_bit)
+                {
+                    value++;
+                }
+                else
+                {
+                    value--;
+                }
+            }
+            if (txrxcount >= BITWIDTH * (8 * DATA_LENGTH + 2.5))
+            {
+                unsigned char dataerrcheck = 0;
+                unsigned char crc = 0;
+                one_ms_status = 1;
+                PAIR_CHARGERPIN_PRINT("RECEVIC DONE .%d\r\n", txrxcount);
+                nrf_gpio_pin_clear(PIN_LED_RUN);
+                PAIR_CHARGERPIN_PRINT("clear.%d\r\n", ms);
+                for (int i = 0; i < DATA_LENGTH - 1; i++)
+                {
+                    crc += rxbuf[i];
+                }
+                for (int i = 0; i < DATA_LENGTH - 1; i++)
+                {
+                    if (rxbuf[i] == 0)
+                    {
+                        dataerrcheck++;
+                    }
+                }
+                if (dataerrcheck == DATA_LENGTH - 1)
+                {
+                    PAIR_CHARGERPIN_PRINT("CRC ERROR ALL 0x00.%x\r\n", crc);
+                    delay_ledon_count = 0;
+                    PAIR_CHARGERPIN_PRINT("delay_ledon_count 2= 0;\r\n", txrxcount);
+                    break;
+                }
+                dataerrcheck = 0;
+                for (int i = 0; i < DATA_LENGTH - 1; i++)
+                {
+                    if (rxbuf[i] == 0xff)
+                    {
+                        dataerrcheck++;
+                    }
+                }
+                if (dataerrcheck == DATA_LENGTH - 1)
+                {
+                    PAIR_CHARGERPIN_PRINT("CRC ERROR ALL 0xFF.%x\r\n", crc);
+                    delay_ledon_count = 0;
+                    PAIR_CHARGERPIN_PRINT("delay_ledon_count 3= 0;\r\n", txrxcount);
+                    break;
+                }
+                if (crc == rxbuf[DATA_LENGTH - 1])
+                {
+                    if (mFlash.isHost)
+                    {
+                        delay_check_count = 1; //延时校验计数器
+                    }
+                    else
+                    {
+                        delay_reply_count = 1; //延时回复计数器
+                    }
+										PAIR_CHARGERPIN_PRINT("---------------CRC SUCCESS .%x----------------\r\n", crc);
+                }
+                else
+                {
+                    PAIR_CHARGERPIN_PRINT("CRC ERROR .%x\r\n", crc);
+                    delay_ledon_count = 0;
+                    PAIR_CHARGERPIN_PRINT("delay_ledon_count 4= 0;\r\n", txrxcount);
+                }
+                for (int i = 0; i < DATA_LENGTH; i++)
+                {
+                    PAIR_CHARGERPIN_PRINT("rxbuf[%d].%x\r\n",i, rxbuf[i]);
+                }
+            }
+            txrxcount++;
+            break;
+        case 4:
+            if (nrf_gpio_pin_read(PIN_CHARGING))
+            {
+                value++;
+            }
+            else
+            {
+                value--;
+            }
+            if (mFlash.isHost)
+            {
+                if (txrxcount == 0)
+                {
+                    value = 0;
+                    nrf_gpio_pin_set(PIN_CHARGING);
+                    PAIR_CHARGERPIN_PRINT("set.%d\r\n", ms);
+                }
+                if (txrxcount == 3 * BITWIDTH)
+                {
+                    nrf_gpio_pin_clear(PIN_CHARGING);
+                    PAIR_CHARGERPIN_PRINT("clear.%d\r\n", delay_ledon_count);
+                }
+								if (txrxcount >= 3 * BITWIDTH + LOW_BIT_DELAY)
+                {
+                    value = 0;
+                    one_ms_status = 1;
+                    now_bit = 0;
+                    bit_width = 0;
+                }
+            }
+            else
+            {
+                if (txrxcount == 0)
+                {
+                    value = 0;
+                }
+                if (txrxcount > 3 * BITWIDTH)
+                {
+                    if (value < 2 * BITWIDTH)
+                    {
+                        PAIR_CHARGERPIN_PRINT("CHECK ERROR .%d\r\n", txrxcount);
+                        delay_ledon_count = 0;
+                        PAIR_CHARGERPIN_PRINT("delay_ledon_count 5= 0;\r\n", txrxcount);
+                    }
+                    else
+                    {
+                        PAIR_CHARGERPIN_PRINT("CHECK DONE .%d\r\n", txrxcount);
+                    }
+                    value = 0;
+                    one_ms_status = 1;
+                    nrf_gpio_pin_clear(PIN_CHARGING);
+                    PAIR_CHARGERPIN_PRINT("clear.%d\r\n", ms);
+                    now_bit = 1;
+                    bit_width = 0;
+                }
+            }
+            txrxcount++;
+            break;
+    }
+    if (delay_ledon_count != 0)
+    {
+        delay_ledon_count++;
+    }
+    if (delay_ledon_count == DELAY_LEDON)
+    {
+        nrf_gpio_pin_write(PIN_LED_RUN, 1);
+				PAIR_CHARGERPIN_PRINT("LEDCOPEN.%d\r\n", ms);
+				memcpy(savebuf,rxbuf,DATA_LENGTH-1);
+    }
+
+    if ((delay_ledon_count > DELAY_LEDON )
+			&& (delay_ledon_count - DELAY_LEDON == LEDON_KEEP))
+    {
+        delay_ledon_count = 0;
+        PAIR_CHARGERPIN_PRINT("delay_ledon_count 6= 0;\r\n", txrxcount);
+        nrf_gpio_pin_write(PIN_LED_RUN, 0);
+        PAIR_CHARGERPIN_PRINT("LEDCLOSE.%d\r\n", ms);
+				writefig=1;
+    }
+}
+//写配对相关的flish
+static int pair_writeflish(unsigned char* macAddr_L, unsigned char* macAddr_R)
+{
+    if (memcmp(macAddr_L, mFlash.macHost, 6) != 0)
+    {
+        goto writein;
+    }
+    if (memcmp(macAddr_R, mFlash.mClient.macAddr, 6) != 0)
+    {
+        goto writein;
+    }
+    if (mFlash.mClient.isConfig != 'C')
+    {
+        goto writein;
+    }
+    PAIR_CHARGERPIN_PRINT("mFlash.mClient.isConfig:%X\n", mFlash.mClient.isConfig);
+    PAIR_CHARGERPIN_PRINT("mFlash.mClient.macAddr:%02X %02X %02X %02X %02X %02X\n", mFlash.mClient.macAddr[0], mFlash.mClient.macAddr[1], mFlash.mClient.macAddr[2], mFlash.mClient.macAddr[3], mFlash.mClient.macAddr[4], mFlash.mClient.macAddr[5]);
+    PAIR_CHARGERPIN_PRINT("mFlash.macHost:%02X %02X %02X %02X %02X %02X\n", mFlash.macHost[0], mFlash.macHost[1], mFlash.macHost[2], mFlash.macHost[3], mFlash.macHost[4], mFlash.macHost[5]);
+    return 0;
+writein:
+    mFlash.mClient.isConfig = 'C';
+    for (int i = 0; i < 6; i++)
+    {
+        mFlash.mClient.macAddr[i] = macAddr_R[i];       //从机自身mac地址
+        mFlash.macHost[i] = macAddr_L[i];                       //主机发过来的mac地址
+    }
+
+    PAIR_CHARGERPIN_PRINT("mFlash.mClient.isConfig:%X\n", mFlash.mClient.isConfig);
+    PAIR_CHARGERPIN_PRINT("mFlash.mClient.macAddr:%02X %02X %02X %02X %02X %02X\n", mFlash.mClient.macAddr[0], mFlash.mClient.macAddr[1], mFlash.mClient.macAddr[2], mFlash.mClient.macAddr[3], mFlash.mClient.macAddr[4], mFlash.mClient.macAddr[5]);
+    PAIR_CHARGERPIN_PRINT("mFlash.macHost:%02X %02X %02X %02X %02X %02X\n", mFlash.macHost[0], mFlash.macHost[1], mFlash.macHost[2], mFlash.macHost[3], mFlash.macHost[4], mFlash.macHost[5]);
+    Flash_SaveInfomation();
+    return 1;
+}
+
+static void load_adv_name_from_flish(void)
+{
+    char buf[16];
+    memset(buf, 0, 16);
+    advertising_stop();
+    sprintf(buf, "%02X%02X%02X%02X%02X%02X", mFlash.macHost[0], mFlash.macHost[1], mFlash.macHost[2], mFlash.mClient.macAddr[3], mFlash.mClient.macAddr[4], mFlash.mClient.macAddr[5]);
+    SEGGER_RTT_printf(0, "advName(%d):%s\n", strlen(buf), buf);
+    slave_set_adv_name(buf, strlen(buf));
+    slave_adv_init();
+		advertising_start();
+}
+
+static void load_scan_name_from_flish(void)
+{
+    char buf[16];
+    memset(buf, 0, 16);
+    sprintf(buf, "%02X%02X%02X%02X%02X%02X", mFlash.macHost[0], mFlash.macHost[1], mFlash.macHost[2], mFlash.mClient.macAddr[3], mFlash.mClient.macAddr[4], mFlash.mClient.macAddr[5]);
+    SEGGER_RTT_printf(0, "scanName1(%d):%s\n", strlen(buf), buf);
+    host_set_scan_name(buf, strlen(buf));
+}
+
+static void load_scan_name_dafual(void)
+{
+    char buf[] = "SCANBUFF";
+    SEGGER_RTT_printf(0, "scanName1(%d):%s\n", strlen(buf), buf);
+    host_set_scan_name(buf, strlen(buf));
+}
+
+static void app_pair_chargerpin_pcs(void)
+{
+	int rev=0;
+	if(writefig==1)
+	{
+		unsigned char Lbuff[6];
+		unsigned char Rbuff[6];
+		if(mFlash.isHost)
+		{
+			Get_MACaddr(Lbuff);
+			Rbuff[0]=0xFF;Rbuff[1]=0xFF;Rbuff[2]=0xFF;
+			Rbuff[3]=savebuf[0];Rbuff[4]=savebuf[1];Rbuff[5]=savebuf[2];
+		}
+		else
+		{
+			Get_MACaddr(Rbuff);
+			Lbuff[0]=savebuf[0];Lbuff[1]=savebuf[1];Lbuff[2]=savebuf[2];
+			Lbuff[3]=0xFF;Lbuff[4]=0xFF;Lbuff[5]=0xFF;
+		}
+		rev=pair_writeflish(Lbuff,Rbuff);
+		if(rev)
+		{
+			if(mFlash.isHost)
+			{
+				load_scan_name_from_flish();
+			}
+			else
+			{
+				load_adv_name_from_flish();
+			}
+		}
+			
+		writefig=0;
+	}
+}
+
+static void chargerpin_one_ms_pcs_test(void* t)
+{
+	static unsigned int count=0;
+	count++;
+	if(count%20==0)
+	{
+		nrf_gpio_pin_toggle(PIN_LED_RUN);
+	SEGGER_RTT_printf(0, "count (  %d  ):\n", count);
+	}
+}
+
+#define CHARGE_ADC 1800
+#define DISCON_L_MAX_ADC 1450
+#define DISCON_L_MIN_ADC 1300
+#define CONN_MAX_ADC 1000
+#define CONN_MIN_ADC 500
+#define DISCON_R_MAX_ADC 100
+
+typedef enum
+{
+	CHARGE=0,
+	CONNECT_NO_CHARGE,
+	DISCONNECT_CHARGE,
+}pair_line_t;
+
+#define ADC_CHECKMS 1000
+#define DELAY_PAIR_COUNT 100
+
+void adc_check(void)
+{
+	static unsigned char status=0;
+	short ADC_value=0;
+	static pair_line_t pair_line;
+	static unsigned int delay_pair_count=0;
+	static unsigned int overtime=0;
+	static unsigned char ishost;
+	switch(status)
+	{
+		case 0:
+			ishost=mFlash.isHost;
+			if (mFlash.isHost == 1)
+			{
+				
+				ADC_Disable();
+        ADC_SetPinChannel(PIN_CHARGING,PIN_CHARGING_CHANNEL,NRF_GPIO_PIN_PULLUP);
+        ADC_Initialize();
+			}
+			else 
+			{
+				ADC_Disable();
+        ADC_SetPinChannel(PIN_CHARGING,PIN_CHARGING_CHANNEL,NRF_GPIO_PIN_NOPULL);		
+        ADC_Initialize();				
+			}
+			status=1;
+			break;
+		case 1:
+		if(ishost!=mFlash.isHost)
+		{
+			status=0;
+			PAIR_CHARGERPIN_PRINT("mFlash.isHost change %d\n",mFlash.isHost);
+		}
+		ADC_Read(PIN_CHARGING_CHANNEL,&ADC_value);
+		PAIR_CHARGERPIN_PRINT( "ADC (  %d  ):%d\n", ADC_value,mFlash.isHost);	
+		if(ADC_value>=CHARGE_ADC)
+		{
+			PAIR_CHARGERPIN_PRINT(" CHARGE_ADC \n");
+			pair_line=CHARGE;
+		}
+		if(mFlash.isHost)
+		{
+			if((ADC_value<=DISCON_L_MAX_ADC)&&(ADC_value>=DISCON_L_MIN_ADC))
+			{
+				PAIR_CHARGERPIN_PRINT("L DISCON_L_ADC \n");
+				pair_line=DISCONNECT_CHARGE;
+			}
+		}
+		else
+		{
+			if(ADC_value<=DISCON_R_MAX_ADC)
+			{
+				PAIR_CHARGERPIN_PRINT("R DISCON_R_MAX_ADC \n");
+				pair_line=DISCONNECT_CHARGE;
+			}		
+		}
+		if((ADC_value>=CONN_MIN_ADC)&&(ADC_value<=CONN_MAX_ADC))
+		{
+			PAIR_CHARGERPIN_PRINT("  CONN_ADC  %d \n",pair_line);
+			if(pair_line!=CONNECT_NO_CHARGE)
+			{
+				PAIR_CHARGERPIN_PRINT("  Process_SetHoldOn(adc_check,1);  \n");
+				overtime=TIME_GetTicks();			
+				Process_UpdatePeroid(adc_check,10);
+				Process_SetHoldOn(adc_check,1);
+				if(mFlash.isHost)	
+				{
+					status=2;
+					delay_pair_count=TIME_GetTicks();
+				}
+				else 
+				{
+					status=5;
+					TIME_Regist(chargerpin_one_ms_pcs);			
+					one_ms_status = 0;
+				}
+			}
+			pair_line=CONNECT_NO_CHARGE;
+		}
+		break;
+		case 2://
+			if(TIME_GetTicks()- delay_pair_count > ADC_CHECKMS+100)
+			{
+					TIME_Regist(chargerpin_one_ms_pcs);			
+					one_ms_status = 0;
+					status=3;
+				PAIR_CHARGERPIN_PRINT("  TIME_Regist(chargerpin_one_ms_pcs); %d \n",TIME_GetTicks());
+			}
+			break;
+		case 3:
+			if(TIME_GetTicks()- delay_pair_count > DELAY_PAIR_COUNT)
+			{
+				nrf_gpio_pin_set(PIN_CHARGING);
+				PAIR_CHARGERPIN_PRINT("  SEND PAIR TAG HIG; %d \n",TIME_GetTicks());
+				status=4;
+			}
+			break;
+		case 4:
+			if(TIME_GetTicks()- delay_pair_count>(DELAY_PAIR_COUNT+100))
+			{
+				nrf_gpio_pin_clear(PIN_CHARGING);
+				PAIR_CHARGERPIN_PRINT("  SEND PAIR TAG LOW; %d \n",TIME_GetTicks());
+				status=5;
+			}
+			break;
+		case 5:
+			if(writefig==1)
+			{
+				app_pair_chargerpin_pcs();
+				TIME_UnRegist(chargerpin_one_ms_pcs);
+				Process_UpdatePeroid(adc_check,ADC_CHECKMS);
+				Process_SetHoldOn(adc_check,0);
+				status=0;
+				PAIR_CHARGERPIN_PRINT("  ---------------------------PAIR SUCESS------------- \n");
+			}
+			if(TIME_GetTicks()-overtime > DELAY_LEDON+DELAY_PAIR_COUNT+2000)
+			{
+				TIME_UnRegist(chargerpin_one_ms_pcs);
+				Process_UpdatePeroid(adc_check,ADC_CHECKMS);
+				Process_SetHoldOn(adc_check,0);
+				status=0;
+				PAIR_CHARGERPIN_PRINT("  ---------------------------PAIR OVER TIME %d------------- \n",TIME_GetTicks());
+			}
+			break;
+	}
+}
+
+void app_pair_chargerpin_Init(void)
+{		
+	Process_Start(ADC_CHECKMS,"adc_check",adc_check);
+}
+
+
+
+
+
+

+ 27 - 0
shoe_mcu2.2.1_new_v2/app/app_pair_chargerpin.h

@@ -0,0 +1,27 @@
+#ifndef APP_PAIR_CHARGERPIN__
+#define APP_PAIR_CHARGERPIN__
+
+
+// <q> BLE_PRINTF  - µ÷ÊÔÐÅÏ¢
+#ifndef PAIR_CHARGERPIN_PRINTF
+#define PAIR_CHARGERPIN_PRINTF 0
+#endif
+#if PAIR_CHARGERPIN_PRINTF
+#define PAIR_CHARGERPIN_PRINT(...) SEGGER_RTT_printf(0, __VA_ARGS__)
+#else
+#define PAIR_CHARGERPIN_PRINT(...) ;
+#endif
+
+// <q> PAIR_INFO_EN  - µ÷ÊÔÐÅÏ¢
+#ifndef PAIR_CHARGERPIN_INFO_EN
+#define PAIR_CHARGERPIN_INFO_EN 1
+#endif
+#if PAIR_CHARGERPIN_INFO_EN
+#define PAIR_CHARGERPIN_INFO(...) SEGGER_RTT_printf(0, __VA_ARGS__)
+#else
+#define PAIR_CHARGERPIN_INFO(...) ;
+#endif
+
+void app_pair_chargerpin_Init(void);
+
+#endif

+ 71 - 0
shoe_mcu2.2.1_new_v2/app/app_power/app_power.c

@@ -0,0 +1,71 @@
+#include "app_power.h"
+#include "nrf_gpio.h"
+#include "usr_config.h"
+#include "bsp_time.h"
+#include "system.h"
+#include "hal_mt.h"
+#include "hal_battery.h"
+#include "app_charge.h"
+#include "hal_ble_client.h"
+#include "nrf_delay.h"
+#include "app_flash.h"
+#include "bsp_wdt.h"
+#include "app_timer.h"
+#include "system.h"
+#include "bsp_pwm.h"
+#include "app_client.h"
+#include "hal_ble_uart0.h"
+#include "hal_led.h"
+#include "lsm6ds3tr_c.h"
+#include "app_math.h"
+#include "bll_imu.h"
+#include "drv_qma7981.h"
+
+/********************** 变量区 *************************/
+
+/********************** 函数声明区 *************************/
+void PWR_Off(void)
+{
+//		UART0_unInit(PIN_TXD_BLE,PIN_RXD_BLE);
+	  LED_Close_Enforce();
+	
+		bll_imu_close();
+    drv_qma_power_off();
+		nrf_gpio_pin_write(PIN_MT_EN,0);
+		nrf_delay_ms(200);
+		nrf_gpio_cfg_sense_input(PIN_CHARGING, NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_SENSE_HIGH);//IO 
+		uint32_t err_code = sd_power_system_off();
+	  DEBUG_LOG("power off...BAT:%d,ERR:%d\n",GetBatteryPersent(),err_code);
+    //APP_ERROR_CHECK(err_code);
+}
+
+static void PWR_Process(void)
+{
+	if((0 == GetBatteryPersent() && app_charge_Getstate()==BLE_CHARGE_PULLOUT)){
+		DEBUG_LOG("BatteryPersent:%d\n",GetBatteryPersent());
+		DEBUG_LOG("power off...\n");
+		//保存数据到flash
+		if(Flash_SaveStep() != ZONE_OP_SUCCESS)Except_TxError(EXCEPT_Power,"save step fail");
+		
+		extern battercb_t battery_record;
+		extern void printbatter_cb(battercb_t *c,unsigned char *buff);
+		memcpy(&mFlash.mbattercb_t,&battery_record,sizeof(battercb_t));
+		
+		mFlash.RestartCnt =0;
+		if(Flash_SaveInfomation() != ZONE_OP_SUCCESS)Except_TxError(EXCEPT_Power,"save information fail");
+		MT_Run(1000);
+		feed_watchdog();
+		for(uint8_t temp = 0;temp < 10; temp++){
+				app_client_DataUpdate_Send();
+				nrf_delay_ms(100);
+		}
+		PWR_Off();
+	}
+}
+
+void PWR_Init(void)
+{
+	Process_Start(10000,"PWR_Process",PWR_Process);
+}
+
+

+ 13 - 0
shoe_mcu2.2.1_new_v2/app/app_power/app_power.h

@@ -0,0 +1,13 @@
+#ifndef __app_power_h__
+#define __app_power_h__
+#include <stdbool.h>
+#include <stdint.h>
+#include <string.h>
+#include "sdk_common.h"
+#include "SEGGER_RTT.h"
+#include "usr_config.h"
+
+void PWR_Init(void);
+void PWR_Off(void);
+
+#endif

+ 35 - 0
shoe_mcu2.2.1_new_v2/app/app_safe.c

@@ -0,0 +1,35 @@
+/*********************************************************************
+ * INCLUDES
+ */
+#include "ble_comm.h"
+#include "app_flash.h"
+#include "hal_ble_client.h"
+#include "app_safe.h"
+#include "app_flash.h"
+
+static void app_safe_Process(void)
+{
+	if(mFlash.RestartCnt > 1){
+		 char buff[40]={0};
+		 memset(buff,0,sizeof(buff));
+		 if(mFlash.isHost){
+		    sprintf(buff,"left shoes restart:%d",mFlash.RestartCnt);
+		 }else{
+    		sprintf(buff,"right shoes restart:%d",mFlash.RestartCnt);	 
+		 }
+		 Except_TxError(EXCEPT_Power,(const char*)buff);
+	}
+}
+
+void app_safe_Init(void)
+{
+	mFlash.RestartCnt++;
+	Process_Start(10000,"app_safe_Process",app_safe_Process);
+}
+
+ 
+
+
+
+
+

+ 15 - 0
shoe_mcu2.2.1_new_v2/app/app_safe.h

@@ -0,0 +1,15 @@
+#ifndef __APP_SAFE_H__
+#define __APP_SAFE_H__
+#include <stdbool.h>
+#include <stdint.h>
+#include <string.h>
+#include "sdk_common.h"
+#include "SEGGER_RTT.h"
+#include "system.h"
+#include "usr_config.h"
+
+void app_safe_Init(void);
+
+#endif
+
+

+ 383 - 0
shoe_mcu2.2.1_new_v2/app/app_self_checking.c

@@ -0,0 +1,383 @@
+/*Includes ----------------------------------------------*/
+#include "system.h"
+#include "exception.h"
+#include "app_charge.h"
+#include "app_flash.h"
+#include "app_self_checking.h"
+#include "hal_led.h"
+#include "hal_mt.h"
+#include "hal_ble_uart0.h"
+#include "hal_ble_client.h"
+#include "app_flash.h"
+#include "app_pair_chargerpin.h"
+#include "bsp_time.h"
+#include "hal_scan_manage.h"
+#include "ble_comm.h"
+#include "bll_imu.h"
+
+/*Private macro ------------------------------------------------*/
+#define	SELF_CHECK_WHEEL_EMPTY_TIMES_MAX		MONITOR_SUSPEND_MODE_OVERFLOW_ERR_SUM_MAX			//允许最大轮空次数
+
+#define SELF_CHECK_ITEM_SUCCESS							0																							//自检项目成功
+#define SELF_CHECK_ITEM_FAIL								1	
+
+//自检项目失败
+enum{
+	SELF_CHECK_ITEM_FRONT_SENSOR=0,																	//自检项目 - 前脚传感器
+	SELF_CHECK_ITEM_BACK_SENSOR,																		//自检项目 - 后脚传感器
+	SELF_CHECK_ITEM_BATTERY,																				//自检项目 - 电量
+	SELF_CHECK_ITEM_CHARGE,																					//自检项目 - 充电电压
+	SELF_CHECK_ITEM_ANT,																						//自检项目 - 天线
+	SELF_CHECK_ITEM_SUSPEND_MODE,																		//自检项目 - 异常挂起		
+	SELF_CHECK_ITEMS																					      //自检项数	
+};
+
+#define SELF_CHECK_LED_DISPLAY_TIME					3000					  //自检灯显示时长 - ms为单位
+
+#define SELF_CHECK_LED_TOGGLE_TIME					200						  //自检灯翻转时长 - ms为单位
+
+#define SELF_CHECK_SCAN_TRIGGER_TIMEOUT			10000						//扫描触发自检超时时间 - ms为单位
+
+#define SELF_CHECK_SET_IMU_TIMEOUT			    20000						//等待IMU初始化成功的时间
+
+#define SELF_CHECK_SCAN_TARGET_ADV_NAME			"SH_SELF_CHECK"																//扫描触发的目标广播名字
+
+/*STRUCTION --------------------------------------------------
+--*/
+typedef enum {
+	SELF_CHECK_STAGE_READY,																																	//准备阶段
+	SELF_CHECK_STAGE_CHECK,																																	//自检阶段
+	
+} SELF_CHECK_STAGE_e;
+typedef enum{
+	SELF_CHECK_LED_ON,																																			//自检灯 - 开
+	SELF_CHECK_LED_OFF,																																			//自检灯 - 关
+} SELF_CHECK_LED_SWITCH_e;
+typedef struct self_check
+{
+	/*private member*/
+	SELF_CHECK_STAGE_e				stage;																												//阶段字段
+	
+	uint8_t										result[SELF_CHECK_ITEMS];																			//自检结果
+	
+	uint8_t										item_fail_num;																								//自检项目失败数量
+	
+	SELF_CHECK_LED_SWITCH_e		led_switch;																										//自检灯开关
+
+	uint32_t									led_display_time;																							//自检灯显示时长
+	
+	uint32_t									led_toggle_time;																							//自检灯翻转时长
+	
+	uint32_t									scan_trigger_timeout;																					//扫描触发自检超时时间
+	
+	bool											is_scan_success;																							//是否找到广播名字
+
+} Self_Check_t;
+
+/*Local Variable -----------------------------------------------*/
+static Self_Check_t ob_self_check;
+
+/*Local Functions ----------------------------------------------*/
+static void clear_all_except(void)
+{
+	Except_ClearExceptype(EXCEPT_DATA_BACK_MAG);
+	Except_ClearExceptype(EXCEPT_DATA_FRONT_ACC);
+	Except_ClearExceptype(EXCEPT_DATA_FRONT_GRY);
+	Except_ClearExceptype(EXCEPT_DATA_FRONT_MAG);
+	Except_ClearExceptype(EXCEPT_DATA_CHARGE);
+	Except_ClearExceptype(EXCEPT_DATA_BATTERY);
+	Except_ClearExceptype(EXCEPT_IMU_SUSPEND_OVERFLOW);
+	Except_ClearExceptype(EXCEPT_ANT_DAMAGE);
+}
+
+static void selft_scan_cb(void)
+{
+	ob_self_check.is_scan_success = true;
+}
+
+static scan_reslt_t scan_reslt_handle ={
+	.handle = selft_scan_cb,
+	.scanname =SELF_CHECK_SCAN_TARGET_ADV_NAME,
+};
+
+//static pair_reslt_t UartPair_result ={
+//	.flag = 0,
+//};
+
+static void app_self_check_getreslut(){
+	  uint8_t i=0;
+		/*获取自检结果前---------------------------------------------------------------------*/
+	  for(i=0;i<SELF_CHECK_ITEMS;i++)ob_self_check.result[i] = SELF_CHECK_ITEM_SUCCESS;
+		ob_self_check.item_fail_num = 0;
+
+		/*获取自检结果中---------------------------------------------------------------------*/
+		
+		//自检结果 - 异常挂起
+		if(Except_IsError(EXCEPT_IMU_SUSPEND_OVERFLOW)){ob_self_check.result[SELF_CHECK_ITEM_SUSPEND_MODE] = SELF_CHECK_ITEM_FAIL;ob_self_check.item_fail_num = SELF_CHECK_ITEM_SUSPEND_MODE + 1;}	
+		//自检结果 - 前脚传感器
+		if(Except_IsError(EXCEPT_DATA_FRONT_ACC)){ob_self_check.result[SELF_CHECK_ITEM_FRONT_SENSOR] = SELF_CHECK_ITEM_FAIL;}
+		if(Except_IsError(EXCEPT_DATA_FRONT_GRY)){ob_self_check.result[SELF_CHECK_ITEM_FRONT_SENSOR] = SELF_CHECK_ITEM_FAIL;}
+		if(Except_IsError(EXCEPT_DATA_FRONT_MAG)){ob_self_check.result[SELF_CHECK_ITEM_FRONT_SENSOR] = SELF_CHECK_ITEM_FAIL;}
+		if(Except_IsError(EXCEPT_DATA_FRONT_ACC) || Except_IsError(EXCEPT_DATA_FRONT_GRY) || Except_IsError(EXCEPT_DATA_FRONT_MAG)){ob_self_check.item_fail_num = SELF_CHECK_ITEM_FRONT_SENSOR + 1;}
+		//自检结果 - 后脚传感器
+		if(Except_IsError(EXCEPT_DATA_BACK_MAG)){ob_self_check.result[SELF_CHECK_ITEM_BACK_SENSOR] = SELF_CHECK_ITEM_FAIL;ob_self_check.item_fail_num = SELF_CHECK_ITEM_BACK_SENSOR + 1;}
+		//自检结果 - 电量
+		if(Except_IsError(EXCEPT_DATA_BATTERY)){ob_self_check.result[SELF_CHECK_ITEM_BATTERY] = SELF_CHECK_ITEM_FAIL;ob_self_check.item_fail_num = SELF_CHECK_ITEM_BATTERY + 1;}
+		//自检结果 - 充电电压
+		if(Except_IsError(EXCEPT_DATA_CHARGE)){ob_self_check.result[SELF_CHECK_ITEM_CHARGE] = SELF_CHECK_ITEM_FAIL;ob_self_check.item_fail_num = SELF_CHECK_ITEM_CHARGE+ 1;}
+		//自检结果 - 天线
+		if(Except_IsError(EXCEPT_ANT_DAMAGE)){ob_self_check.result[SELF_CHECK_ITEM_ANT] = SELF_CHECK_ITEM_FAIL;ob_self_check.item_fail_num = SELF_CHECK_ITEM_ANT + 1;}					
+		
+		//设置自检灯显示时长和翻转时长
+		if(ob_self_check.item_fail_num != 0){
+			ob_self_check.led_switch = SELF_CHECK_LED_ON;
+			ob_self_check.led_display_time = TIME_GetTicks();
+			ob_self_check.led_toggle_time = TIME_GetTicks();
+		}else{
+			ob_self_check.led_switch = SELF_CHECK_LED_ON;
+//			if(UartPair_result.flag){
+//				LED_Start(LED_SELF_CHECK,COLOR_BLUE);
+//			}
+//			else{
+//				LED_Start(LED_SELF_CHECK,COLOR_CYAN);
+//			}
+		}
+}
+
+//自检模式
+static const bll_imu_one_way_param_t selfcheck_front_param={
+	.acc_power_mode 						= FML_IMU_ACC_POWER_MODE_NORMAL,						//前脚 - 加速度正常模式
+	.gry_power_mode 						= FML_IMU_GRY_POWER_MODE_NORMAL,						//前脚 - 陀螺仪正常模式
+	.timestamp_resolution 			= FML_IMU_TIMESTAMP_25US,										//前脚 - 时间戳25US精度
+	.timestamp_switch 					= FML_IMU_TIMESTAMP_ON,											//前脚 - 时间戳开启
+	.acc_fs 										= FML_IMU_ACC_FS_16G,												//前脚 - 加速度量程 - 16G
+	.gry_fs 										= FML_IMU_GRY_FS_2000DPS,										//前脚 - 陀螺仪量程 - 2000DPS
+	.mag_fs 										= FML_IMU_MAG_FS_30GS,											//前脚 - 地磁计量程 - 30GS
+	.acc_odr 									  = FML_IMU_ACC_ODR_104HZ,										//前脚 - 加速度采样频率 - 104HZ
+	.gry_odr 									  = FML_IMU_GRY_ODR_104HZ,										//前脚 - 陀螺仪采样频率 - 104HZ
+	.mag_odr 									  = FML_IMU_MAG_ODR_200HZ,										//前脚 - 地磁计采样频率 - 200HZ
+	.fifo_odr 									= FML_IMU_FIFO_ODR_104HZ,	
+};
+
+static const bll_imu_one_way_param_t selfcheck_back_param={
+	.acc_power_mode 						= FML_IMU_ACC_POWER_MODE_NORMAL,						//后脚 - 加速度正常模式
+	.gry_power_mode 						= FML_IMU_GRY_POWER_MODE_NORMAL,						//后脚 - 陀螺仪正常模式
+	.timestamp_resolution 			= FML_IMU_TIMESTAMP_25US,										//后脚 - 时间戳25US精度
+	.timestamp_switch 					= FML_IMU_TIMESTAMP_OFF,										//后脚 - 时间戳关闭
+	.acc_fs 										= FML_IMU_ACC_FS_16G,											  //后脚 - 加速度量程 - 16G
+	.gry_fs 										= FML_IMU_GRY_FS_2000DPS,										//后脚 - 陀螺仪量程 - 2000DPS
+	.mag_fs 										= FML_IMU_MAG_FS_30GS,											//后脚 - 地磁计量程 - 30GS
+	.acc_odr 										= FML_IMU_ACC_ODR_OFF,											//后脚 - 加速度采样频率 - 关闭
+	.gry_odr 										= FML_IMU_GRY_ODR_OFF,											//后脚 - 陀螺仪采样频率 - 关闭
+	.mag_odr 										= FML_IMU_MAG_ODR_200HZ,										//后脚 - 地磁计采样频率 - 200HZ
+	.fifo_odr 									= FML_IMU_FIFO_ODR_OFF,	
+};
+
+static const bll_imu_param_t selfcheck_bll_imu_param_t={
+	.config_param[FML_IMU_DIR_FRONT] = &selfcheck_front_param,
+	.config_param[FML_IMU_DIR_BACK] =  &selfcheck_back_param,
+};
+
+static void ReadyIntoSelfMode(void){
+		//设置为自检模式,且跳转到下一个流程
+		hal_ble_scan_result_Regist(&scan_reslt_handle);
+		ob_self_check.is_scan_success 			= false;
+		ob_self_check.scan_trigger_timeout 	= TIME_GetTicks();
+	  ob_self_check.stage = SELF_CHECK_STAGE_READY;
+		clear_all_except();	//清除所有异常
+		LED_Start(LED_SELF_CHECK,COLOR_BLACK); 
+		LED_Stop(LED_SELF_CHECK);
+		bll_imu_Resume_config_param(&selfcheck_bll_imu_param_t);
+		
+		memset(ob_self_check.result, SELF_CHECK_ITEM_SUCCESS, SELF_CHECK_ITEMS);	
+//	  UartPair_result.flag =0;
+//	  app_UartPair_Regist(&UartPair_result);
+		DEBUG_LOG("app_self_checking_Process clear_all_except\r\n");
+}
+
+
+static void app_self_checking_Process(void)
+{
+	static uint8_t state =0;
+	static uint8_t state_selft =0;
+	static uint8_t displaycnt =0;
+  uint8_t front_CS =0,back_CS =0;
+	uint8_t imu_configcnt =0;
+	
+	switch(state){
+		case 0:
+			    if(BLE_CHARGE_DONE == app_charge_Getstate() || \
+						 BLE_CHARGE_INSERT == app_charge_Getstate()
+						){
+							if(Except_IsErrorExist())																																														//如果存在错误
+							{
+								front_CS = bll_imu_query_config_param_is_ready(BLL_IMU_DIR_FRONT,&selfcheck_bll_imu_param_t);
+							  back_CS  = bll_imu_query_config_param_is_ready(BLL_IMU_DIR_BACK,&selfcheck_bll_imu_param_t);
+								if(BLL_IMU_CONFIG_FINISH == front_CS && BLL_IMU_CONFIG_FINISH == back_CS){																		//如果当前是自检配置
+									bll_imu_Resume_unregister_config_param(&selfcheck_bll_imu_param_t);//关掉自检配置
+								}
+								else{																																																							//如果当前不是自检配置{
+									ST_scan_start();
+									ReadyIntoSelfMode();
+									state =1;
+									state_selft =0;
+								}
+							}
+							else{
+								ST_scan_start();//设置为自检模式,且跳转到下一个流程
+								ReadyIntoSelfMode();
+								state =1;
+								state_selft =0;
+							}
+					}
+			    break;
+    case 1:
+					if(ob_self_check.is_scan_success == true)
+					{
+						ob_self_check.stage = SELF_CHECK_STAGE_CHECK;																				//进入自检阶段
+						state =2;
+						Process_SetHoldOn(app_self_checking_Process,1);
+						DEBUG_LOG("ob_self_check.is_scan_success\r\n");
+					}else{
+             if((TIME_GetTicks() - ob_self_check.scan_trigger_timeout) > SELF_CHECK_SCAN_TRIGGER_TIMEOUT)		//超时且没扫描到广播名
+						 {
+							  state = 2;
+							  ob_self_check.is_scan_success 			= false;																					//重置扫描成功标志位
+							  state_selft =3;
+							  hal_ble_scan_result_Clear(&scan_reslt_handle);																				//禁止扫描触发
+						    ST_scan_stop();
+							  DEBUG_LOG("ob_self_check.scan_trigger_timeout\r\n");
+						 }
+					}
+			    break;
+		case 2:
+			    if(BLE_CHARGE_PULLOUT == app_charge_Getstate()){
+						 state = 0;
+//						 app_UartPair_Clear(&UartPair_result);
+						 DEBUG_LOG("ob_self_check.scan BLE_Client_T_CHARGE_PULLOUT\r\n");
+					}
+			    break;
+		default:
+			    break;
+	}
+	
+	switch(state_selft)
+	{
+		case 0:																															   
+			  if(SELF_CHECK_STAGE_CHECK == ob_self_check.stage){//扫描成功
+					  MT_Run(500);
+						bll_imu_Resume_config_param(&selfcheck_bll_imu_param_t);//开启自检模式
+				    state_selft = 1;
+					  imu_configcnt =0;
+				}
+				break;
+		case 1:
+			  if(BLE_CHARGE_PULLOUT == app_charge_Getstate()){
+					 state_selft = 3;
+				}
+			  else {
+					  front_CS = bll_imu_query_config_param_is_ready(BLL_IMU_DIR_FRONT,&selfcheck_bll_imu_param_t);
+						back_CS  = bll_imu_query_config_param_is_ready(BLL_IMU_DIR_BACK,&selfcheck_bll_imu_param_t);
+						if(BLL_IMU_CONFIG_FINISH == front_CS && BLL_IMU_CONFIG_FINISH == back_CS){
+							state_selft = 2;
+							displaycnt =0;
+							app_self_check_getreslut();
+						}
+						else if(BLL_IMU_CONFIG_DOING != front_CS || BLL_IMU_CONFIG_DOING != back_CS){
+							bll_imu_Resume_config_param(&selfcheck_bll_imu_param_t);
+							imu_configcnt++;
+							DEBUG_LOG(">>>>>>222 out sleep mode,%d  %d\n",front_CS,back_CS);
+							if(imu_configcnt > 20){imu_configcnt =0;
+								 Except_SetExceptype(EXCEPT_DATA_FRONT_ACC);
+								 Except_SetExceptype(EXCEPT_DATA_FRONT_GRY);
+								 Except_SetExceptype(EXCEPT_DATA_FRONT_MAG);
+								 Except_SetExceptype(EXCEPT_IMU_SUSPEND_OVERFLOW); 
+								 state_selft = 2;
+								 displaycnt =0;
+							} 
+						}
+			  }
+			  break;
+	  case 2:
+			   if(displaycnt < ob_self_check.item_fail_num){
+						if(TIME_GetTicks() - ob_self_check.led_toggle_time >= SELF_CHECK_LED_TOGGLE_TIME){ob_self_check.led_toggle_time = TIME_GetTicks();
+							if(ob_self_check.led_switch == SELF_CHECK_LED_ON){
+								LED_Start(LED_SELF_CHECK,COLOR_LIGHRED);
+								ob_self_check.led_switch = SELF_CHECK_LED_OFF;
+							}
+							else{
+								LED_Start(LED_SELF_CHECK,COLOR_BLACK);
+								ob_self_check.led_switch = SELF_CHECK_LED_ON;
+								displaycnt++;
+							}
+						}
+					}
+				  else if(TIME_GetTicks() - ob_self_check.led_display_time >= SELF_CHECK_LED_DISPLAY_TIME){//显示时间到了,重现读取自检结果,并显示
+						ob_self_check.led_display_time = TIME_GetTicks();
+						displaycnt =0;
+						app_self_check_getreslut();
+					}
+			    break;
+		 case 3:
+				 state_selft = 0;
+		     ob_self_check.stage = SELF_CHECK_STAGE_READY;
+         LED_Start(LED_SELF_CHECK,COLOR_BLACK); 
+				 LED_Stop(LED_SELF_CHECK);
+				 ob_self_check.led_switch = SELF_CHECK_LED_OFF;																					//设置自检灯为关
+				 bll_imu_Resume_unregister_config_param(&selfcheck_bll_imu_param_t);//关掉自检配置				
+				 break;
+		 default:
+			   break;
+	}	
+}
+//static void app_self_checking_printf_process(void)
+//{
+//	DEBUG_LOG("self_check: FRONT_SENSOR:%d BACK_SENSOR:%d BATTERY:%d CHARGE:%d ANT:%d suspend_mode:%d scan_trigger_timeout:%d\n", \
+//	Except_IsError(EXCEPT_DATA_FRONT_ACC) || Except_IsError(EXCEPT_DATA_FRONT_GRY) || Except_IsError(EXCEPT_DATA_FRONT_MAG), \
+//	Except_IsError(EXCEPT_DATA_BACK_MAG), \
+//	Except_IsError(EXCEPT_DATA_BATTERY), \
+//	Except_IsError(EXCEPT_DATA_CHARGE), \
+//	Except_IsError(EXCEPT_ANT_DAMAGE), \
+//	Except_IsError(EXCEPT_IMU_SUSPEND_OVERFLOW),ob_self_check.scan_trigger_timeout);
+//}
+
+/*API ----------------------------------------------------------*/
+void app_self_checking_Init(void)
+{
+	ob_self_check.stage = SELF_CHECK_STAGE_READY;
+	ob_self_check.item_fail_num = 0;
+	ob_self_check.led_switch = SELF_CHECK_LED_OFF;
+	ob_self_check.led_display_time = 0;
+	ob_self_check.led_toggle_time = 0;
+	ob_self_check.is_scan_success = false;																		
+	ob_self_check.scan_trigger_timeout = SELF_CHECK_SCAN_TRIGGER_TIMEOUT;								
+
+	Process_Start(10,"app_self_checking_Process",app_self_checking_Process);
+  
+//	Process_Start(1000,"app_self_checking_printf_process",app_self_checking_printf_process);
+}
+
+uint32_t app_self_checking_get_scan_trigger_timeout(void)
+{
+	return ob_self_check.scan_trigger_timeout;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+ 39 - 0
shoe_mcu2.2.1_new_v2/app/app_self_checking.h

@@ -0,0 +1,39 @@
+#ifndef __APP_SELF_CHECKING_H__
+#define __APP_SELF_CHECKING_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*Includes ------------------------------------------------------*/
+#include <stdbool.h>
+#include <stdint.h>
+#include <string.h>
+#include "sdk_common.h"
+#include "SEGGER_RTT.h"
+#include "usr_config.h"
+
+/*API -------------------------------------------------------*/
+void app_self_checking_Init(void);
+
+uint32_t app_self_checking_get_scan_trigger_timeout(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+ 485 - 0
shoe_mcu2.2.1_new_v2/app/app_single_line_pair.c

@@ -0,0 +1,485 @@
+/*Includes ----------------------------------------------*/
+#include "ble_gap.h"
+#include "ble_comm.h"
+#include "bsp_time.h"
+#include "system.h"
+#include "hal_mt.h"
+#include "hal_led.h"
+#include "app_flash.h"
+#include "app_single_line_pair.h"
+
+
+/*Private macro ------------------------------------------------*/
+#define						APP_SINGLE_LINE_PAIR_TRIGGER_TIMES																		1																				//触发次数
+
+#define						APP_SINGLE_LINE_PAIR_CMD																							0x00																		//配对指令
+
+#define						APP_SINGLE_LINE_PAIR_LR_CMD																						0x01																		//获取左右指令
+
+#define						APP_SINGLE_LINE_PAIR_TIMEOUT																					6000																		//配对超时时间		单位:ms
+
+/*STRUCTION -----------------------------------------------------*/
+typedef enum
+{
+	APP_SINGLE_LINE_PAIR_STATE_PAIR_DONE = 0,																																											//配对状态 —— 配对完成
+	
+	APP_SINGLE_LINE_PAIR_STATE_PAIR_ING,																																													//配对状态 —— 配对中
+	
+	APP_SINGLE_LINE_PAIR_STATE_PAIR_FAIL,																																													//配对状态 —— 配对失败
+	
+} APP_SINGLE_LINE_PAIR_STATE_e;																																																	//配对状态
+
+typedef struct _app_single_line_pair
+{
+	APP_SINGLE_LINE_PAIR_ROLE_e								role;																																								//角色
+	
+	APP_SINGLE_LINE_PAIR_STATE_e							state;																																							//配对状态
+	
+	uint8_t																		mac[6];																																							//物理地址
+	
+	int																				trigger_times;																																			//触发次数
+	
+	uint32_t																	pair_timeout_ms;																																		//配对超时
+	
+	int																				pair_flow;																																					//配对流程
+	
+	int																				save_adv_scan_flow;																																	//保存、广播、扫描流程
+	
+} App_Single_Line_Pair_t;
+
+/*Local Variable ----------------------------------------------*/
+static App_Single_Line_Pair_t ob_app_single_line_pair;
+
+/*Local Functions ----------------------------------------------*/
+static void app_single_line_pair_Process(void);
+
+static void app_single_line_pair_save_adv_or_scan_Process(void)
+{
+	static uint32_t tim =0;
+	char 						buf[16];
+	
+	switch(ob_app_single_line_pair.save_adv_scan_flow)
+	{
+		case 0:
+			 MT_Run(500);
+			 //配对时候清空所有的步数
+			 if(Flash_DeleteAllStep() != ZONE_OP_SUCCESS){Except_TxError(EXCEPT_DATEStep,"clear step fail");break;}
+			 
+			 memset(&mFlash.mStep,0,sizeof(FlashStep_t));
+			 mFlash.mClient.isConfig = 'C';
+			 if(Flash_SaveStep() != ZONE_OP_SUCCESS)Except_TxError(EXCEPT_DATEStep,"save step fail");
+			 
+			 //右鞋地址
+			 mFlash.mClient.macAddr[0] = 0;
+			 mFlash.mClient.macAddr[1] = 0;
+			 mFlash.mClient.macAddr[2] = 0;
+			 mFlash.mClient.macAddr[3] = ob_app_single_line_pair.mac[3];
+			 mFlash.mClient.macAddr[4] = ob_app_single_line_pair.mac[4];
+			 mFlash.mClient.macAddr[5] = ob_app_single_line_pair.mac[5];
+			 
+			 //左鞋地址
+			 mFlash.macHost[0] = ob_app_single_line_pair.mac[0];
+			 mFlash.macHost[1] = ob_app_single_line_pair.mac[1];
+			 mFlash.macHost[2] = ob_app_single_line_pair.mac[2];
+			 mFlash.macHost[3] = 0;
+			 mFlash.macHost[4] = 0;
+			 mFlash.macHost[5] = 0;
+			 
+			 ob_app_single_line_pair.save_adv_scan_flow =1;
+			 tim = TIME_GetTicks();
+			break;
+		
+		case 1:
+	    if(TIME_GetTicks()-tim>=10000)
+			{
+				tim = TIME_GetTicks();//10秒超时退出
+				//只有配对成功时,才运行。
+				Process_Stop(app_single_line_pair_save_adv_or_scan_Process);	
+				//关灯
+				LED_Stop(LED_PAIR);
+				//取消全功率配对
+				Process_SetHoldOn(app_single_line_pair_Process,0);	
+				//更新状态
+				ob_app_single_line_pair.state = APP_SINGLE_LINE_PAIR_STATE_PAIR_FAIL;
+			}
+			
+			if(ob_app_single_line_pair.role == APP_SINGLE_LINE_PAIR_ROLE_HOST)	//主机处理
+			{
+				if(host_isconnect())
+				{
+					host_disconnect();
+				}
+				else
+				{
+					DEBUG_LOG(">>>>>ST_scan_start =0 \r\n");
+					memset(buf,0,sizeof(buf));
+					sprintf(buf,"%02X%02X%02X%02X%02X%02X",mFlash.macHost[0],mFlash.macHost[1],mFlash.macHost[2],mFlash.mClient.macAddr[3],mFlash.mClient.macAddr[4],mFlash.mClient.macAddr[5]);
+					DEBUG_LOG("scanName(%d):%s\n",strlen(buf),buf);
+					host_set_scan_name(buf,strlen(buf));
+					ST_scan_stop();
+					ST_scan_start();
+					//只有配对成功时,才运行。
+					Process_Stop(app_single_line_pair_save_adv_or_scan_Process);	
+					//关灯
+					LED_Stop(LED_PAIR);					
+					//取消全功率配对
+					Process_SetHoldOn(app_single_line_pair_Process,0);	
+					//更新状态
+					ob_app_single_line_pair.state = APP_SINGLE_LINE_PAIR_STATE_PAIR_DONE;
+				}
+			}
+			else	//从机处理
+			{
+				if(slave_isconnect())
+				{
+					slave_disconnect();
+				}
+				else 
+				{
+					memset(buf,0,sizeof(buf));
+					sprintf(buf,"%02X%02X%02X%02X%02X%02X",mFlash.macHost[0],mFlash.macHost[1],mFlash.macHost[2],mFlash.mClient.macAddr[3],mFlash.mClient.macAddr[4],mFlash.mClient.macAddr[5]);
+					DEBUG_LOG("advName(%d):%s\n",strlen(buf),buf);
+					slave_set_adv_name(buf,strlen(buf));
+					advertising_stop();
+					slave_adv_init();
+					DEBUG_LOG(">>>>>>>>advertising_start =0 \r\n");
+					advertising_start();
+					//只有配对成功时,才运行。
+					Process_Stop(app_single_line_pair_save_adv_or_scan_Process);	
+					//关灯
+					LED_Stop(LED_PAIR);
+					//取消全功率配对
+					Process_SetHoldOn(app_single_line_pair_Process,0);	
+					//更新状态
+					ob_app_single_line_pair.state = APP_SINGLE_LINE_PAIR_STATE_PAIR_DONE;
+				}
+			}
+			break;
+	}
+}
+
+static void app_single_line_pair_host_process(uint8_t byte)
+{
+	static int index = 0;
+	
+	DEBUG_LOG("host_process:%d\r\n",byte);
+	
+	switch(ob_app_single_line_pair.pair_flow)
+	{
+		case 0:						//接收指令阶段
+			if(byte == APP_SINGLE_LINE_PAIR_CMD)
+			{
+				if(bll_single_line_half_duplex_is_ready_to_transfer() == 0)
+				{
+					if(bll_single_line_half_duplex_transfer_onebyte(ob_app_single_line_pair.mac[0]) == 0)
+					{
+						index = 0;
+						ob_app_single_line_pair.pair_flow = 1;
+					}
+					else
+					{
+						ob_app_single_line_pair.state 						= APP_SINGLE_LINE_PAIR_STATE_PAIR_FAIL;//配对失败
+					}
+				}
+				else
+				{
+					ob_app_single_line_pair.state 							= APP_SINGLE_LINE_PAIR_STATE_PAIR_FAIL;//配对失败
+				}
+			}
+			//获取左右指令
+			if(byte == APP_SINGLE_LINE_PAIR_LR_CMD)
+			{
+				if(bll_single_line_half_duplex_is_ready_to_transfer() == 0)
+				{
+					if(mFlash.isHost == 1)
+						bll_single_line_half_duplex_transfer_onebyte(0x55);
+					else
+						bll_single_line_half_duplex_transfer_onebyte(0x56);
+				}
+			}
+			break;
+			
+		case 1:						//发送数据阶段
+			ob_app_single_line_pair.mac[3 + index] = byte;
+		
+			if(bll_single_line_half_duplex_is_ready_to_transfer() == 0 && index != 2)
+			{
+				if(bll_single_line_half_duplex_transfer_onebyte(ob_app_single_line_pair.mac[index + 1]) == 0)
+				{
+					index++;
+				}
+				else
+				{
+					ob_app_single_line_pair.state 							= APP_SINGLE_LINE_PAIR_STATE_PAIR_FAIL;//配对失败
+				}
+			}
+			else
+			{
+				if(index == 2)
+				{
+					ob_app_single_line_pair.pair_flow 					= 0;
+					ob_app_single_line_pair.state 							= APP_SINGLE_LINE_PAIR_STATE_PAIR_DONE;
+					ob_app_single_line_pair.save_adv_scan_flow  = 0;
+					//注册线程任务,用于处理保存、广播、扫描
+					Process_Start(0,"app_single_line_pair_save_adv_or_scan_Process",app_single_line_pair_save_adv_or_scan_Process);					
+				}
+				else
+				{
+					ob_app_single_line_pair.state 							= APP_SINGLE_LINE_PAIR_STATE_PAIR_FAIL;//配对失败
+				}
+			}
+			break;
+	}
+}
+
+static void app_single_line_pair_slave_process(uint8_t byte)
+{
+	static int index = 0;
+	
+	DEBUG_LOG("--->s index:%d flow:%d byte:%d\r\n",index,ob_app_single_line_pair.pair_flow,byte);
+	
+	switch(ob_app_single_line_pair.pair_flow)
+	{
+		case 0:						//接收指令阶段
+			if(byte == APP_SINGLE_LINE_PAIR_CMD)
+			{
+				//更改状态
+				ob_app_single_line_pair.state 							= APP_SINGLE_LINE_PAIR_STATE_PAIR_ING;
+				//记录配对开始时间
+				ob_app_single_line_pair.pair_timeout_ms	 		= TIME_GetTicks();
+				
+				DEBUG_LOG("cmd TIME_GetTicks():%d,ob_app_single_line_pair.pair_timeout_ms:%d,counter:%d\r\n",TIME_GetTicks(),ob_app_single_line_pair.pair_timeout_ms,NRF_RTC0->COUNTER);
+				//全功率配对
+				Process_SetHoldOn(app_single_line_pair_Process,1);				
+				//亮灯
+				LED_Start(LED_PAIR,COLOR_BLUE);
+				
+				if(bll_single_line_half_duplex_is_ready_to_transfer() == 0)
+				{
+					if(bll_single_line_half_duplex_transfer_onebyte(APP_SINGLE_LINE_PAIR_CMD) == 0)//回馈指令
+					{
+						index 																	= 0;
+						ob_app_single_line_pair.pair_flow 			= 1;
+					}
+					else
+					{
+						ob_app_single_line_pair.state 					= APP_SINGLE_LINE_PAIR_STATE_PAIR_FAIL;//配对失败
+						DEBUG_LOG("============>err 1\r\n");
+					}
+				}
+				else
+				{
+					ob_app_single_line_pair.state 						= APP_SINGLE_LINE_PAIR_STATE_PAIR_FAIL;//配对失败
+					DEBUG_LOG("============>err 2\r\n");
+				}
+			}
+			//获取左右指令
+			if(byte == APP_SINGLE_LINE_PAIR_LR_CMD)
+			{
+				if(bll_single_line_half_duplex_is_ready_to_transfer() == 0)
+				{
+					if(mFlash.isHost == 1)
+						bll_single_line_half_duplex_transfer_onebyte(0x55);
+					else
+						bll_single_line_half_duplex_transfer_onebyte(0x56);
+				}
+			}
+			break;
+			
+		case 1:						//发送数据阶段
+			ob_app_single_line_pair.mac[index] = byte;
+		
+			if(bll_single_line_half_duplex_is_ready_to_transfer() == 0 && index != 3)
+			{
+				if(bll_single_line_half_duplex_transfer_onebyte(ob_app_single_line_pair.mac[3 + index]) == 0)
+				{
+					index++;
+					
+					if(index == 3)
+					{
+						ob_app_single_line_pair.pair_flow 					= 0;
+						ob_app_single_line_pair.state 							= APP_SINGLE_LINE_PAIR_STATE_PAIR_DONE;
+						ob_app_single_line_pair.save_adv_scan_flow  = 0;
+						//注册线程任务,用于处理保存、广播、扫描
+						Process_Start(0,"app_single_line_pair_save_adv_or_scan_Process",app_single_line_pair_save_adv_or_scan_Process);					
+					}
+				}
+				else
+				{
+					ob_app_single_line_pair.state 								= APP_SINGLE_LINE_PAIR_STATE_PAIR_FAIL;//配对失败
+					DEBUG_LOG("============>err 3\r\n");
+				}
+			}
+			else
+			{
+				ob_app_single_line_pair.state 									= APP_SINGLE_LINE_PAIR_STATE_PAIR_FAIL;//配对失败
+				DEBUG_LOG("============>err 4\r\n");
+			}
+			break;
+	}
+	
+}
+
+
+static void app_single_line_pair_Process(void)
+{
+	//角色切换
+	if(mFlash.isHost == 1 && ob_app_single_line_pair.role != APP_SINGLE_LINE_PAIR_ROLE_HOST)
+	{
+		app_single_line_pair_Init(APP_SINGLE_LINE_PAIR_ROLE_HOST);
+	}
+	else if(mFlash.isHost == 0 && ob_app_single_line_pair.role != APP_SINGLE_LINE_PAIR_ROLE_SLAVE)
+	{
+		app_single_line_pair_Init(APP_SINGLE_LINE_PAIR_ROLE_SLAVE);
+	}
+	
+	
+	switch(ob_app_single_line_pair.role)
+	{
+		case APP_SINGLE_LINE_PAIR_ROLE_HOST:							//主机行为
+			//配对完成或配对失败
+			if(ob_app_single_line_pair.state == APP_SINGLE_LINE_PAIR_STATE_PAIR_DONE || ob_app_single_line_pair.state == APP_SINGLE_LINE_PAIR_STATE_PAIR_FAIL)
+			{
+				//配对操作失败,必须得超时才能尝试下一轮。
+				if(ob_app_single_line_pair.state == APP_SINGLE_LINE_PAIR_STATE_PAIR_FAIL && TIME_GetTicks() - ob_app_single_line_pair.pair_timeout_ms < APP_SINGLE_LINE_PAIR_TIMEOUT)
+				{
+					ob_app_single_line_pair.pair_flow = 0;
+					//更新触发次数
+					ob_app_single_line_pair.trigger_times = APP_SINGLE_LINE_PAIR_TRIGGER_TIMES;
+					//灭灯
+					LED_Stop(LED_PAIR);
+					//取消全功率配对
+					Process_SetHoldOn(app_single_line_pair_Process,0);	
+					
+					DEBUG_LOG("o fail TIME_GetTicks():%d,ob_app_single_line_pair.pair_timeout_ms:%d,counter:%d\r\n",TIME_GetTicks(),ob_app_single_line_pair.pair_timeout_ms,NRF_RTC0->COUNTER);
+					return;
+				}
+				
+				//允许发送
+				if(bll_single_line_half_duplex_is_ready_to_transfer() == 0)
+				{
+					//触发次数不为0
+					if(ob_app_single_line_pair.trigger_times != 0)
+					{
+						//发送配对指令
+						bll_single_line_half_duplex_transfer_onebyte(APP_SINGLE_LINE_PAIR_CMD);
+						//更改状态
+						ob_app_single_line_pair.state 		= APP_SINGLE_LINE_PAIR_STATE_PAIR_ING;
+						DEBUG_LOG("cmd TIME_GetTicks():%d,ob_app_single_line_pair.pair_timeout_ms:%d,counter:%d\r\n",TIME_GetTicks(),ob_app_single_line_pair.pair_timeout_ms,NRF_RTC0->COUNTER);
+						LED_Start(LED_PAIR,COLOR_BLUE);
+						ob_app_single_line_pair.pair_flow = 0;
+						//记录配对开始时间
+						ob_app_single_line_pair.pair_timeout_ms = TIME_GetTicks();
+						//减少触发次数
+						ob_app_single_line_pair.trigger_times--;
+						//全功率配对
+						Process_SetHoldOn(app_single_line_pair_Process,1);
+					}
+				}
+				else
+				{
+					//更新触发次数
+					ob_app_single_line_pair.trigger_times = APP_SINGLE_LINE_PAIR_TRIGGER_TIMES;
+				}
+			}				
+			else
+			{
+				//监控是否超时,主机要比从机多一个字节的传输时间来确保从机已经超时。
+				if(TIME_GetTicks() - ob_app_single_line_pair.pair_timeout_ms >= (APP_SINGLE_LINE_PAIR_TIMEOUT + (FML_SINGLE_LINE_SIMPLEX_PWM_SEQ_VALUES_LEN * FML_SINGLE_LINE_SIMPLEX_SEND_ONE_BIT_TIEMS / 1000)) && \
+					ob_app_single_line_pair.state == APP_SINGLE_LINE_PAIR_STATE_PAIR_ING)
+				{
+					//配对超时失败
+					ob_app_single_line_pair.state 		= APP_SINGLE_LINE_PAIR_STATE_PAIR_FAIL;
+					ob_app_single_line_pair.pair_flow = 0;
+					//更新触发次数
+					ob_app_single_line_pair.trigger_times = APP_SINGLE_LINE_PAIR_TRIGGER_TIMES;
+					DEBUG_LOG("t fail TIME_GetTicks():%d,ob_app_single_line_pair.pair_timeout_ms:%d,counter:%d\r\n",TIME_GetTicks(),ob_app_single_line_pair.pair_timeout_ms,NRF_RTC0->COUNTER);
+					//灭灯
+					LED_Stop(LED_PAIR);
+					//取消全功率配对
+					Process_SetHoldOn(app_single_line_pair_Process,0);				
+				}
+			}
+			break;
+		
+		case APP_SINGLE_LINE_PAIR_ROLE_SLAVE:							//从机行为
+				//监控是否超时。
+				if(TIME_GetTicks() - ob_app_single_line_pair.pair_timeout_ms >= (APP_SINGLE_LINE_PAIR_TIMEOUT - (FML_SINGLE_LINE_SIMPLEX_PWM_SEQ_VALUES_LEN * FML_SINGLE_LINE_SIMPLEX_SEND_ONE_BIT_TIEMS / 1000)) && \
+					ob_app_single_line_pair.state == APP_SINGLE_LINE_PAIR_STATE_PAIR_ING)
+				{
+					//配对超时失败
+					ob_app_single_line_pair.state 		= APP_SINGLE_LINE_PAIR_STATE_PAIR_FAIL;	
+					DEBUG_LOG("t fail TIME_GetTicks():%d,ob_app_single_line_pair.pair_timeout_ms:%d,counter:%d\r\n",TIME_GetTicks(),ob_app_single_line_pair.pair_timeout_ms,NRF_RTC0->COUNTER);
+				}
+				
+				if(ob_app_single_line_pair.state == APP_SINGLE_LINE_PAIR_STATE_PAIR_FAIL)
+				{
+					ob_app_single_line_pair.pair_flow = 0;
+					DEBUG_LOG("o fail TIME_GetTicks():%d,ob_app_single_line_pair.pair_timeout_ms:%d,counter:%d\r\n",TIME_GetTicks(),ob_app_single_line_pair.pair_timeout_ms,NRF_RTC0->COUNTER);
+					//灭灯
+					LED_Stop(LED_PAIR);
+					//取消全功率配对
+					Process_SetHoldOn(app_single_line_pair_Process,0);							
+				}
+			break;
+	}
+}
+
+/*API ----------------------------------------------*/
+/**
+	@brief 		初始化单线配对应用
+	@param 		role									- [in]	角色
+	@return 	错误代码							- [out]	-1失败,0成功
+*/
+int app_single_line_pair_Init(APP_SINGLE_LINE_PAIR_ROLE_e role)
+{
+	int 						ret;
+	ble_gap_addr_t 	mAddr;
+	
+	//初始化单线半双工业务
+	ret = bll_single_line_half_duplex_Init((BLL_SINGLE_LINE_HALF_DUPLEX_ROLE_e)role);
+	
+	//重置
+	memset(&ob_app_single_line_pair, 0, sizeof(ob_app_single_line_pair));
+	
+	//初始化结构体
+	uint32_t err_code = sd_ble_gap_addr_get(&mAddr);
+	if(err_code != NRF_SUCCESS)return -1;
+	
+	if(role == APP_SINGLE_LINE_PAIR_ROLE_HOST)
+	{
+		ob_app_single_line_pair.mac[0] = mAddr.addr[0];
+		ob_app_single_line_pair.mac[1] = mAddr.addr[1];
+		ob_app_single_line_pair.mac[2] = mAddr.addr[2];
+		
+		bll_single_line_half_duplex_receive_register(app_single_line_pair_host_process);
+	}
+	else
+	{
+		ob_app_single_line_pair.mac[3] = mAddr.addr[0];
+		ob_app_single_line_pair.mac[4] = mAddr.addr[1];
+		ob_app_single_line_pair.mac[5] = mAddr.addr[2];
+		
+		bll_single_line_half_duplex_receive_register(app_single_line_pair_slave_process);
+	}
+	
+	ob_app_single_line_pair.trigger_times = APP_SINGLE_LINE_PAIR_TRIGGER_TIMES;
+	
+	ob_app_single_line_pair.state					=	APP_SINGLE_LINE_PAIR_STATE_PAIR_DONE;
+	
+	ob_app_single_line_pair.role					=	role;
+		
+	//初始化配对线程
+	Process_Start(1000,"app_single_line_pair_Process",app_single_line_pair_Process);
+	
+	return (ret == 0)?0:-1;
+}
+
+
+
+
+
+
+
+
+

+ 57 - 0
shoe_mcu2.2.1_new_v2/app/app_single_line_pair.h

@@ -0,0 +1,57 @@
+#ifndef __APP_SINGLE_LINE_PAIR_H__
+#define __APP_SINGLE_LINE_PAIR_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+	
+
+/*Includes ------------------------------------------------------*/
+#include "bll_single_line_half_duplex.h"
+/*Private macro ------------------------------------------------*/
+
+
+/*STRUCTION -----------------------------------------------------*/
+typedef enum
+{
+	APP_SINGLE_LINE_PAIR_ROLE_HOST 		= BLL_SINGLE_LINE_HALF_DUPLEX_ROLE_HOST,																//角色 —— 主机
+	
+	APP_SINGLE_LINE_PAIR_ROLE_SLAVE 	= BLL_SINGLE_LINE_HALF_DUPLEX_ROLE_SLAVE																//角色 —— 从机
+	
+} APP_SINGLE_LINE_PAIR_ROLE_e;
+
+
+/*API -------------------------------------------------------*/
+/**
+	@brief 		初始化单线配对应用
+	@param 		role									- [in]	角色
+	@return 	错误代码							- [out]	-1失败,0成功
+*/
+int app_single_line_pair_Init(APP_SINGLE_LINE_PAIR_ROLE_e role);
+
+	
+#ifdef __cplusplus
+}
+#endif
+
+#endif	
+	
+	
+	
+	
+	
+	
+	
+	
+	
+	
+	
+	
+	
+	
+	
+	
+	
+	
+	
+

+ 289 - 0
shoe_mcu2.2.1_new_v2/app/app_step.c

@@ -0,0 +1,289 @@
+#include "app_step.h"
+#include "nrf_gpio.h"
+#include "usr_config.h"
+#include "bsp_time.h"
+#include "system.h"
+#include "hal_mt.h"
+#include "app_host.h"
+#include "app_charge.h"
+#include "hal_ble_client.h"
+#include "hal_ble_host.h"
+#include "nrf_delay.h"
+#include "app_flash.h"
+#include "ble_comm.h"
+#include "exception.h"
+#include "bll_imu.h"
+#include "detect_zero_vel.h"
+#include "detect_step_by_mag.h"
+#include "pdrStatus.h"
+#include "hal_wearshoes.h"
+
+//实时计步模式
+static const bll_imu_one_way_param_t realstep_front_param={
+	.acc_power_mode 						= FML_IMU_ACC_POWER_MODE_NORMAL,						//前脚 - 加速度正常模式
+	.gry_power_mode 						= FML_IMU_GRY_POWER_MODE_NORMAL,						//前脚 - 陀螺仪正常模式
+	.fifo_odr 									= FML_IMU_FIFO_ODR_104HZ,	                  //前脚 --FIFO采集频率
+	.timestamp_resolution 			= FML_IMU_TIMESTAMP_25US,										//前脚 - 时间戳25US精度
+	.timestamp_switch 					= FML_IMU_TIMESTAMP_ON,											//前脚 - 时间戳开启
+	.acc_odr 									  = FML_IMU_ACC_ODR_104HZ,										//前脚 - 加速度采样频率 - 104HZ
+	.gry_odr 									  = FML_IMU_GRY_ODR_104HZ,										//前脚 - 陀螺仪采样频率 - 104HZ
+	.mag_odr 									  = FML_IMU_MAG_ODR_200HZ,										//前脚 - 地磁计采样频率 - 200HZ
+	.acc_fs 										= FML_IMU_ACC_FS_16G,												//前脚 - 加速度量程 - 16G
+	.gry_fs 										= FML_IMU_GRY_FS_2000DPS,										//前脚 - 陀螺仪量程 - 2000DPS
+	.mag_fs 										= FML_IMU_MAG_FS_30GS,											//前脚 - 地磁计量程 - 30GS
+};
+
+static const bll_imu_one_way_param_t realstep_back_param={
+	.acc_power_mode 						= FML_IMU_ACC_POWER_MODE_NORMAL,						//后脚 - 加速度正常模式
+	.gry_power_mode 						= FML_IMU_GRY_POWER_MODE_NORMAL,						//后脚 - 陀螺仪正常模式
+	.fifo_odr 									= FML_IMU_FIFO_ODR_OFF,	                    //后脚 -- FIFO采集频率
+	.timestamp_resolution 			= FML_IMU_TIMESTAMP_25US,										//后脚 - 时间戳25US精度
+	.timestamp_switch 					= FML_IMU_TIMESTAMP_OFF,										//后脚 - 时间戳关闭
+	.acc_odr 										= FML_IMU_ACC_ODR_OFF,											//后脚 - 加速度采样频率 - 关闭
+	.gry_odr 										= FML_IMU_GRY_ODR_OFF,											//后脚 - 陀螺仪采样频率 - 关闭
+	.mag_odr 										= FML_IMU_MAG_ODR_200HZ,										//后脚 - 地磁计采样频率 - 200HZ
+	.acc_fs 										= FML_IMU_ACC_FS_16G,											  //后脚 - 加速度量程 - 16G
+	.gry_fs 										= FML_IMU_GRY_FS_2000DPS,										//后脚 - 陀螺仪量程 - 2000DPS
+	.mag_fs 										= FML_IMU_MAG_FS_30GS,											//后脚 - 地磁计量程 - 30GS
+	
+	
+};
+
+
+static const bll_imu_param_t realstep_bll_imu_param_t={
+	.config_param[FML_IMU_DIR_FRONT] = &realstep_front_param,
+	.config_param[FML_IMU_DIR_BACK] =  &realstep_back_param,
+};
+
+static uint8_t  realStepMode = BLE_REALTIMESTEP_EXIT;       //是否为实时计步模式
+static uint32_t realStepCur_L = 0;      //左鞋步数记录点
+static uint32_t realStepAdd_R = 0;      //右鞋步数
+static uint8_t  realStepTimCnt = 0;     //右鞋实时计步的心跳
+static uint16_t  realStepHeartCnt = 0;   //实时计步模式心跳计时
+static uint8_t  RealStepFlag =BLE_REALTIMESTEP_EXIT;        //实时计步的信号。
+
+#define IMU_MAX_GROUP_NUM 5
+
+static int16_t 	acc_front[IMU_MAX_GROUP_NUM][3];
+static int16_t	mag6310_front[IMU_MAX_GROUP_NUM][3];
+
+static int16_t	mag6310_back[3];
+
+/********************** 函数声明区 *************************/
+uint32_t app_step_GetStep_L(void)
+{
+	return mFlash.mStep.stepCur[0];
+}
+
+uint32_t app_step_GetStep_R(void)
+{ 
+	return mFlash.mStep.stepCur[1];
+}
+
+//发送实时左右鞋步数到CLIENT端
+static void app_step_RealSendClient()
+{
+	if(realStepMode == BLE_REALTIMESTEP_ENTER){
+		uint8_t buf[8]={0};
+		uint8_t L = 0;
+		buf[L++] = BLE_REALTIMESTEP_ENTER;
+		buf[L++] = (uint8_t)((mFlash.mStep.stepCur[0]-realStepCur_L)>>24);
+		buf[L++] = (uint8_t)((mFlash.mStep.stepCur[0]-realStepCur_L)>>16);
+		buf[L++] = (uint8_t)((mFlash.mStep.stepCur[0]-realStepCur_L)>>8);
+		buf[L++] = (uint8_t)((mFlash.mStep.stepCur[0]-realStepCur_L)>>0);
+		buf[L++] = (uint8_t)(realStepAdd_R>>24);
+		buf[L++] = (uint8_t)(realStepAdd_R>>16);
+		buf[L++] = (uint8_t)(realStepAdd_R>>8);
+		buf[L++] = (uint8_t)(realStepAdd_R>>0);
+		DEBUG_LOG("mFlash.mStep.stepCur[0]:%d,realStepCur_L:%d,realStepAdd_R:%d\n",mFlash.mStep.stepCur[0],realStepCur_L,realStepAdd_R);
+		BLE_Client_Tx_Send(0,BLE_REALTIMESTEP,buf,L);
+	}
+}
+
+//右鞋实时计步发送
+static void app_step_RealSendProcess()
+{
+	if(mFlash.isHost)return;
+	app_step_RealSendClient();
+}
+
+//IMU数据回调
+static void real_data_notify_cb(uint32_t dir_bit)
+{
+	int16_t 				group_num = 0;
+	bll_imu_data_t data={0};
+	
+	if(BLE_REALTIMESTEP_ENTER != realStepMode)return;
+	
+	if((dir_bit >> BLL_IMU_DIR_FRONT) & 0x01)
+	{
+		group_num = bll_imu_get_data_num(BLL_IMU_DIR_FRONT);
+		if(group_num >IMU_MAX_GROUP_NUM)return;
+		for(int i=0;i<group_num;i++){
+			bll_imu_get_data(BLL_IMU_DIR_FRONT, i, &data);
+			acc_front[i][0] = data.acc[0];acc_front[i][1] = data.acc[1];acc_front[i][2] = data.acc[2];
+			mag6310_front[i][0] = data.mag[0];mag6310_front[i][1] = data.mag[1];mag6310_front[i][2] = data.mag[2];
+		}
+		if(bll_imu_get_data_num(BLL_IMU_DIR_BACK) >= 1){
+			bll_imu_get_data(BLL_IMU_DIR_BACK, 0, &data);
+			mag6310_back[0] = data.mag[0];mag6310_back[1] = data.mag[1];mag6310_back[2] = data.mag[2];
+		}
+		
+//		DEBUG_LOG("======RealTimeStep=====%d\r\n",TIME_GetTicks());
+		if(RealTimeStep((int16_t*)mag6310_front, (int16_t*)mag6310_back, (int16_t*)acc_front)){
+			 mFlash.mStep.stepCur[0]++;
+			 DEBUG_LOG("======RealTimeStep=====step %d\r\n",mFlash.mStep.stepCur[0]);
+		}	
+	}
+	
+}
+
+uint8_t app_step_Real_Get(void){
+	 if(realStepMode == BLE_REALTIMESTEP_ENTER)return 1;
+	 else return 0;
+}
+
+//右鞋实时计步连接管理
+void app_step_RealConnectProcess(void)
+{
+	 static uint8_t state =0;
+	 static uint8_t imu_configcnt =0;
+	 uint8_t mod =0;
+	 uint8_t front_CS =0,back_CS =0;
+	 
+	 switch(state){
+		 case 0:{//空闲
+						 if(RealStepFlag == BLE_REALTIMESTEP_ENTER){
+							 state =1;
+							 imu_configcnt =0;
+							 bll_imu_Resume_config_param(&realstep_bll_imu_param_t);
+						 }else{
+							 if(realStepTimCnt>0){ realStepTimCnt = 0;
+									BLE_Host_Tx_Send(0,BLE_REALTIMESTEP,&RealStepFlag,1);
+							 }
+						 }
+						 break;
+				   }
+		 case 1:{//配置IMU
+						 front_CS = bll_imu_query_config_param_is_ready(BLL_IMU_DIR_FRONT,&realstep_bll_imu_param_t);
+						 back_CS  = bll_imu_query_config_param_is_ready(BLL_IMU_DIR_BACK, &realstep_bll_imu_param_t);
+						 if(BLL_IMU_CONFIG_FINISH == front_CS && BLL_IMU_CONFIG_FINISH == back_CS){
+							 DEBUG_LOG(">>>>>>into real step mode\n");
+							 state =2;
+							 realStepCur_L = mFlash.mStep.stepCur[0]; //重新计数
+							 realStepAdd_R = 0;
+							 realStepHeartCnt = 0;
+							 realStepMode = BLE_REALTIMESTEP_ENTER;
+						 }
+						 else if(BLL_IMU_CONFIG_DOING != front_CS || BLL_IMU_CONFIG_DOING != back_CS){
+									bll_imu_Resume_config_param(&realstep_bll_imu_param_t);
+									imu_configcnt++;
+							    
+							    if(imu_configcnt >=20){
+										bll_imu_Resume_unregister_config_param(&realstep_bll_imu_param_t);
+									  state =0;
+									  RealStepFlag = BLE_REALTIMESTEP_EXIT;
+									  realStepMode = BLE_REALTIMESTEP_EXIT;
+								 } 
+						 }
+						 
+			     break;
+					 }
+		 case 2://进入实时计步
+			     realStepHeartCnt++;
+					 if(realStepHeartCnt >= 600){realStepHeartCnt=0;
+							mod = BLE_REALTIMESTEP_EXIT;
+							BLE_Host_Tx_Send(0,BLE_REALTIMESTEP,&mod,1); //退出从机实时步数
+						  bll_imu_Resume_unregister_config_param(&realstep_bll_imu_param_t);
+						  realStepMode = BLE_REALTIMESTEP_EXIT;
+						  state =0;
+					 }else{
+							if(realStepTimCnt > 0) realStepTimCnt--;
+							if(realStepTimCnt==0) {
+								mod = BLE_REALTIMESTEP_ENTER;
+								BLE_Host_Tx_Send(0,BLE_REALTIMESTEP,&mod,1);
+							}
+					 }
+					 if(RealStepFlag == BLE_REALTIMESTEP_EXIT){
+							 realStepMode = BLE_REALTIMESTEP_EXIT;
+							 bll_imu_Resume_unregister_config_param(&realstep_bll_imu_param_t);
+							 state =0;
+					 }
+			     break;
+		 default:RealStepFlag = BLE_REALTIMESTEP_EXIT;realStepMode = BLE_REALTIMESTEP_EXIT;state =0;break;
+	 }
+}
+
+
+
+//接收右鞋实时步数并发送到手机
+void cb_BLE_Host_R_REALTIMESTEP(void* handle)
+{
+	BLE_Client_Rx_t* target = handle;
+	if(target->pDat[0]==BLE_REALTIMESTEP_ENTER){
+		  if(realStepMode == BLE_REALTIMESTEP_ENTER){
+				realStepAdd_R = ((uint32_t)target->pDat[1]<<24) | (uint32_t)(target->pDat[2]<<16) | (uint32_t)(target->pDat[3]<<8) | ((uint32_t)target->pDat[4]<<0);
+				app_step_RealSendClient();
+		    DEBUG_LOG(">>>>>>realStepCur_L:%ld,realStepAdd_R:%ld,\n",realStepCur_L,realStepAdd_R);
+			}
+			realStepTimCnt = 3;
+	}
+}
+
+//接收手机命令
+void cb_BLE_Client_R_REALTIMESTEP(void* handle)
+{
+	BLE_Client_Rx_t* target = handle;
+	RealStepFlag = target->pDat[0];
+
+	if(RealStepFlag == BLE_REALTIMESTEP_ENTER){
+		realStepHeartCnt = 0;
+		bll_imu_Resume_config_param(&realstep_bll_imu_param_t);
+	}
+	else{
+		bll_imu_Resume_unregister_config_param(&realstep_bll_imu_param_t);
+	}
+	
+	BLE_Host_Tx_Send(0,BLE_REALTIMESTEP,&RealStepFlag,1);
+}
+
+//日常计步
+static void app_math_DailyStep_Process(void)
+{
+	int16_t 	acc[3];
+	int16_t		mag6310[3];
+	int16_t 	group_num = 0;
+	bll_imu_data_t data= {0};
+	
+	if(hal_wearshoes_is_wearshoes() && realStepMode != BLE_REALTIMESTEP_ENTER){
+		group_num = bll_imu_get_data_num(BLL_IMU_DIR_FRONT);
+		for(int i=0; i < group_num; i++){
+			bll_imu_get_data(BLL_IMU_DIR_FRONT, i, &data);
+			mag6310[0] = data.mag[0];mag6310[1] = data.mag[1];mag6310[2] = data.mag[2];
+			acc[0] = data.acc[0];acc[1] = data.acc[1];acc[2] = data.acc[2];
+			
+//			DEBUG_LOG("f_mx=%d\r,f_my=%d\r,f_mz=%d\r\n",mag6310[0],mag6310[1],mag6310[2]);
+			if(1 == detect_step_by_mag(mag6310,acc[2])){
+					mFlash.mStep.stepCur[0]++;
+				  DEBUG_LOG("DailyStep current step:%d\r\n",mFlash.mStep.stepCur[0]);
+				  break;
+			}
+		}
+	}
+}
+
+
+void app_step_Init(void)
+{
+	
+  Process_Start(100,"step_RealSend",app_step_RealSendProcess);
+	BLE_Client_Rx_Regist(BLE_REALTIMESTEP,cb_BLE_Client_R_REALTIMESTEP);
+	Process_Start(100,"step_RealConnect",app_step_RealConnectProcess);
+	
+  BLE_Host_Rx_Regist(BLE_REALTIMESTEP,cb_BLE_Host_R_REALTIMESTEP);
+	bll_imu_register_data_notify_callback(BLL_IMU_DATA_NOTIFY_CB_PRIORITY_1, real_data_notify_cb);
+	Process_Start(0,"app_math_DailyStep_Process",app_math_DailyStep_Process);
+	
+}
+
+

+ 15 - 0
shoe_mcu2.2.1_new_v2/app/app_step.h

@@ -0,0 +1,15 @@
+#ifndef __app_step_h__
+#define __app_step_h__
+#include <stdbool.h>
+#include <stdint.h>
+#include <string.h>
+#include "sdk_common.h"
+#include "SEGGER_RTT.h"
+#include "usr_config.h"
+
+void app_step_Init(void);
+uint32_t app_step_GetStep_L(void);
+uint32_t app_step_GetStep_R(void);
+uint8_t app_step_Real_Get(void);
+
+#endif

+ 39 - 0
shoe_mcu2.2.1_new_v2/app/app_switchimu.c

@@ -0,0 +1,39 @@
+#include "app_switchimu.h"
+#include "usr_config.h"
+#include "bsp_time.h"
+#include "system.h"
+#include "hal_ble_client.h"
+#include "hal_ble_host.h"
+#include "hal_mt.h"
+#include "nrf_delay.h"
+
+static uint8_t switch_front_or_center_lsm = USED_FRONT_LSM;
+
+uint8_t app_switchimu_GetGameModeLsm(void)
+{
+	return switch_front_or_center_lsm;
+}
+
+//½ÓÊÕÊÖ»úÃüÁî
+void cb_BLE_Client_R_SWITCH_IMU(void* handle)
+{
+	BLE_Client_Rx_t* target = handle;
+	uint8_t cmd = target->pDat[0];
+	
+	BLE_Host_Tx_Send(0,BLE_SWITCH_IMU,&cmd,1);
+	
+	nrf_delay_ms(500);
+	
+	NVIC_SystemReset();				//¸´Î»ÖØÆô		
+	
+}
+
+void app_switchimu_Init(void)
+{
+	BLE_Client_Rx_Regist(BLE_SWITCH_IMU,cb_BLE_Client_R_SWITCH_IMU);
+}
+
+
+
+
+

+ 19 - 0
shoe_mcu2.2.1_new_v2/app/app_switchimu.h

@@ -0,0 +1,19 @@
+#ifndef __app_switchimu_h__
+#define __app_switchimu_h__
+#include <stdbool.h>
+#include <stdint.h>
+#include <string.h>
+#include "sdk_common.h"
+#include "SEGGER_RTT.h"
+#include "usr_config.h"
+
+#define USED_FRONT_LSM					0
+#define USED_CENTER_LSM					1
+
+void app_switchimu_Init(void);
+uint8_t app_switchimu_GetGameModeLsm(void);
+
+#endif
+
+
+

+ 464 - 0
shoe_mcu2.2.1_new_v2/ble_cfg/ble_comm.h

@@ -0,0 +1,464 @@
+/** @file
+ *
+ * @API 文档
+ *
+ */
+
+#ifndef __BLE_COMM__
+#define __BLE_COMM__
+
+#include "sdk_common.h"
+#include "ble_db_discovery.h"
+#include "sdk_errors.h"
+#include "app_error.h"
+#include "app_util.h"
+#include "bsp_btn_ble.h"
+#include "ble.h"
+#include "ble_gap.h"
+#include "ble_hci.h"
+#include "nrf_sdh.h"
+#include "nrf_sdh_ble.h"
+#include "nrf_sdh_soc.h"
+#include "ble_nus_c.h"
+#include "nrf_ble_gatt.h"
+#include "nrf_pwr_mgmt.h"
+#include "nrf_ble_scan.h"
+#include "app_timer.h"
+#include "ble_conn_state.h"
+
+#include "SEGGER_RTT.h"
+#include "nrf_delay.h"
+#include "main.h"
+#include "queue.h"
+#include "ringframe.h"
+#include "ble_advdata.h"
+
+// <<< Use Configuration Wizard in Context Menu >>>\r\n
+#define APP_BLE_CONN_CFG_TAG 1
+
+// <q> USE_LADDR  - 广播名称是否添加地址后缀
+#ifndef USE_LADDR
+#define USE_LADDR 1
+#endif
+// <q> USENAMEFR  - 扫描是否采用名字匹配
+#ifndef USENAMEFR
+#define USENAMEFR 1
+#endif
+// <q> USEMACNAME  - 采用mac地址作为蓝牙名称
+#ifndef USEMACNAME
+#define USEMACNAME 0
+#endif
+
+// <q> USEFIFO  - 采用FIFO方式发送
+#ifndef USEFIFO
+#define USEFIFO 1
+#endif
+
+#define TARFET_LEN_MAX NRF_BLE_SCAN_NAME_MAX_LEN
+
+// <q> BLE_PRINTF  - 调试信息
+#ifndef BLE_PRINTF
+#define BLE_PRINTF 0
+#endif
+#if BLE_PRINTF
+#define BLE_PRINT(...) DEBUG_LOG( __VA_ARGS__)
+#else
+#define BLE_PRINT(...) ;
+#endif
+#define APP_ERR_BASE 0
+
+/**@brief 各种错误数据类型. */
+enum
+{
+	APP_SUCCESS = APP_ERR_BASE,
+	APP_ERR_DISCONN,
+	APP_ERR_CONNECTED,
+	APP_ERR_PARAMERR,
+	APP_ERR_OVERLENGTH,
+	APP_ERR_BUSY,
+	APP_ERROR_RESOURCES,
+};
+
+/**@brief 报错函数.
+ *
+ * @param[in]      err_num       	 错误代码
+ *
+ * @warning 
+ */
+void err(int err_num);
+
+/**@brief 扫描到的广播数据包回调事件类型
+ *
+ * @param[in]      unsigned short   广播数据包的长度
+ * @param[out]     unsigned char *  接收到的完整广播数据包的指针
+ * @param[in]      signed char      RSSI
+ *
+ * @warning 
+ */
+typedef void (*advdata_rep_handler_t)(unsigned char *, unsigned short ,signed char);
+
+/**@brief 数据接收类型
+ *
+ * @warning 
+ */
+typedef void (*Ble_receive_handler_t)(unsigned char *, int);
+
+/**@brief 蓝牙时间回调类型
+ *
+ * @warning 
+ */
+typedef void (*Ble_evt_cb)(void);
+
+/**@brief 发送数据到从机
+ *
+ * @param[in]      bytes       要发送的数据的指针.
+ * @param[in]      len  			 要发送的数据的长度
+ *
+ * @retval 0  			操作成功
+ * @retval 1 				发送失败
+ *
+ * @warning 
+ */
+unsigned int send_bytes_server(uint8_t *bytes, uint16_t len);
+
+/**@brief 发送数据到主机
+ *
+ * @param[in]      bytes       要发送的数据的指针.
+ * @param[in]      len  			 要发送的数据的长度
+ *
+ * @retval 0  			操作成功
+ * @retval 1 				发送失败
+ *
+ * @warning 
+ */
+unsigned int send_bytes_client(unsigned char *bytes, uint16_t len);
+
+/**@brief 主机初始化
+ *
+ * @warning 
+ */
+void host_init(Ble_receive_handler_t receive_handler);
+
+/**@brief 从机初始化
+ *
+ * @warning 
+ */
+void slave_init(Ble_receive_handler_t receive_handler);
+
+/**@brief 从机角色获取链接是否建立
+ *
+ * @retval 1   链接已经建立
+ * @retval 0   链接未建立
+ *
+ * @warning 
+ */
+unsigned char slave_isconnect(void);
+
+/**@brief 主机角色获取链接是否建立
+ *
+ * @retval 1   链接已经建立
+ * @retval 0   链接未建立
+ *
+ * @warning 
+ */
+unsigned char host_isconnect(void);
+
+/**@brief 设置扫描名称
+ *
+ * @param[in]      name      要设置的名称
+ * @param[in]      len       要设置的名称的长度
+ *
+ * @retval APP_SUCCESS            操作成功
+ * @retval APP_ERR_CONNECTED      链接已经建立
+ * @retval APP_ERR_OVERLENGTH     长度太长
+ *
+ * @warning 
+ */
+unsigned int host_set_scan_name(char *name, int len);
+
+/**@brief 设置广播名称
+ *
+ * @param[in]      name      要设置的广播名称
+ * @param[in]      len       要设置的广播名称的长度
+ *
+ * @retval APP_SUCCESS            操作成功 
+ *
+ * @warning 
+ */
+unsigned int slave_set_adv_name(char *name, int len);
+
+/**@brief 获取当前正在广播的名称长度
+ *
+ * @param[out]     len  					 广播的名称长度
+ *
+ * @warning 
+ */
+void slave_get_advname_len(int *len);
+
+/**@brief 获取当前正在广播的名称,要和void slave_get_advname_len(int *len);合用
+ *
+ * @param[in]      len    广播名称的长度
+ * @param[out]     name   广播名称
+ *
+ * @warning 
+ */
+void slave_get_advname(char *name, int len);
+
+/**@brief 注册一个在连接建立的时候的通知
+ *
+ * @param[in]      cb       要注册的回调函数指针
+ *
+ * @retval -1     要注册的回调已经存在
+ * @retval 0 			注册成功
+ * @retval -2     注册的队列已经满了
+ *
+ * @warning 
+ */
+int Ble_Host_Connectd_Evt_Regist(Ble_evt_cb cb);
+
+/**@brief 注册一个在连接断开的时候的通知
+ *
+ * @param[in]      cb       要注册的回调函数指针
+ *
+ * @retval -1     要注册的回调已经存在
+ * @retval 0 			注册成功
+ * @retval -2     注册的队列已经满了
+ *
+ * @warning 
+ */
+int Ble_Host_Disconn_Evt_Regist(Ble_evt_cb cb);
+
+/**@brief 注册一个在连接建立的时候的通知
+ *
+ * @param[in]      cb       要注册的回调函数指针
+ *
+ * @retval -1     要注册的回调已经存在
+ * @retval 0 			注册成功
+ * @retval -2     注册的队列已经满了
+ *
+ * @warning 
+ */
+int Ble_Slave_Connectd_Evt_Regist(Ble_evt_cb cb);
+
+/**@brief 注册一个在连接断开的时候的通知
+ *
+ * @param[in]      cb       要注册的回调函数指针
+ *
+ * @retval -1     要注册的回调已经存在
+ * @retval 0 			注册成功
+ * @retval -2     注册的队列已经满了
+ *
+ * @warning 
+ */
+int Ble_Slave_Disconn_Evt_Regist(Ble_evt_cb cb);
+
+/**@brief 作为主机时申请更新链接间隔
+ *
+ * @param[in]      min_conn_interval   最小链接间隔
+ * @param[in]      max_conn_interval   最大链接间隔
+ *  
+ * @retval APP_ERR_PARAMERR   输如的参数错误
+ * @retval APP_ERR_DISCONN    链接已经断开
+ *
+ * @warning 
+ */
+unsigned int Ble_update_conn_interval(float min_conn_interval, float max_conn_interval);
+
+/**@brief 作为从机时申请更新链接间隔
+ *
+ * @param[in]      min_conn_interval   最小链接间隔
+ * @param[in]      max_conn_interval   最大链接间隔
+ *
+ * @retval APP_ERR_BUSY       正处在一个申请流程中,此时不接受新的申请     
+ * @retval APP_ERR_PARAMERR   输如的参数错误
+ * @retval APP_ERR_DISCONN    链接已经断开
+ *
+ * @warning 
+ */
+unsigned int slave_update_conn_interval_request(float min_conn_interval, float max_conn_interval);
+
+/**@brief 关闭广播
+ *
+ * @warning 
+ */
+void advertising_stop(void);
+
+/**@brief 开启广播
+ *
+ * @warning 
+ */
+void advertising_start(void);
+
+/**@brief 开启扫描
+ *
+ * @warning 
+ */
+void scan_start(void);
+
+//关掉扫描直接调用  void nrf_ble_scan_stop(void);
+
+/**@brief 略
+ *
+ * @warning 
+ */
+uint8_t Slave_Get7_5ms_interval(void);
+
+/**@brief 作为从机角色的时候主动断开蓝牙链接
+ *
+ * @warning 
+ */
+void slave_disconnect(void);
+
+/**@brief 作为主机角色的时候主动断开蓝牙链接
+ *
+ * @warning 
+ */
+void host_disconnect(void);
+
+/**@brief 作为从机角色的时候获取连接参数
+ *
+ * @param[out]     p  获取到的链接参数的存放指针
+ *
+ * @warning 
+ */
+void slave_get_conn_params(ble_gap_conn_params_t *p);
+
+/**@brief 作为主机角色的时候获取连接参数
+ *
+ * @param[out]     p  获取到的链接参数的存放指针
+ *
+ * @warning 
+ */
+void host_get_conn_params(ble_gap_conn_params_t *p);
+
+/**@brief 从机广播初始化
+ * @warning 
+ */
+void slave_adv_init(void);
+
+/**@brief 作为从机角色的时候获取RSSI
+ *
+ * @retval 获取到的RSSI  
+ *
+ * @warning 
+ */
+signed char slave_get_rssi(void);
+
+/**@brief 作为主机角色的时候获取RSSI
+ *
+ * @retval 获取到的RSSI  
+ *
+ * @warning 
+ */
+signed char host_get_rssi(void);
+
+/**@brief 运动算法处理
+ *
+ * @param[in]      IS_HOST     是否是左鞋.
+ * @param[in]      time_stamp  时间戳.
+ * @param[in]      _acc        加速度.
+ * @param[in]      _gry        陀螺仪.
+ * @param[in]      front_mag   前磁力计.
+ * @param[in]      back_mag    后磁力计.
+ * @param[in]      _rssi       信号强度.
+ *
+ * @warning 
+ */
+void IMU_Process_motion_queue(uint8_t IS_HOST, int32_t time_stamp, int16_t* _acc,int16_t* _gry, int16_t* front_mag, int16_t* back_mag, uint8_t _rssi);
+
+/**@brief 对齐功能驱动
+ *
+ * @details 
+ * @warning 
+ */
+void IMU_Rec_data(uint8_t* pdat,uint8_t len);
+
+/**@brief IMU_Dtalige 对齐函数
+ * @warning 
+ */
+void IMU_Dtalige(void);
+
+/**@brief 打开原始数据上传模式
+ * @warning 
+ */
+void IMU_Dtalige_Rowdata_ON(void);
+
+/**@brief 关闭原始数据上传模式
+ * @warning 
+ */
+void IMU_Dtalige_Rowdata_OFF(void);
+
+/**@brief 这个函数是在系统大循环中调的
+ *
+ * @warning 
+ */
+void send_bytes_client_pcs(void);
+
+/**@brief Function for searching through encoded Advertising data for a complete local name.
+ *
+ * @param[in]    p_encoded_data Data buffer containing the encoded Advertising data.
+ * @param[in]    data_len       Length of the data buffer \p p_encoded_data.
+ * @param[in]    p_target_name  Name to search for.
+ *
+ * @retval true   If \p p_target_name was found among \p p_encoded_data, as a complete local name.
+ * @retval false  If \p p_target_name was not found among \p p_encoded_data, or if \p p_encoded_data
+ *                or \p p_target_name was NULL.
+ */
+bool advdata_name_find(uint8_t const * p_encoded_data,
+                           uint16_t        data_len,
+                           char    const * p_target_name);
+
+/**@brief Function for searching through encoded Advertising data for a device shortened name.
+ *
+ * @param[in]    p_encoded_data     Data buffer containing the encoded Advertising data.
+ * @param[in]    data_len           Length of the data buffer \p p_encoded_data.
+ * @param[in]    p_target_name      Name to search for.
+ * @param[in]    short_name_min_len Minimum length of the shortened name.
+ *               For example, if the advertising data has a shortened name 'No' and this parameter is
+ *               set to 4 with a target_name set to Nordic_XXX it will return false, but if
+ *               the shortened name in the advertising data is 'Nord', it will return true.
+ * @note: If the shortened name in the Advertising data has the same length as the target name,
+ *        this function will return false, since this means that the complete name is actually
+ *        longer, thus different than the target name.
+ *
+ * @retval true   If \p p_target_name was found among \p p_encoded_data, as short local name.
+ * @retval false  If \p p_target_name was not found among \p p_encoded_data, or if \p p_encoded_data
+ *                or \p p_target_name was NULL.
+ */
+bool advdata_short_name_find(uint8_t const * p_encoded_data,
+                                 uint16_t        data_len,
+                                 char    const * p_target_name,
+                                 uint8_t const   short_name_min_len);
+																 
+/**@brief 这个函数用来注册收到广播数据包时候的事件.
+ *
+ * @param[in]   handler     需要注册的回调函数的函数指针
+ *
+ * @note: 			此函数每次调用都会覆盖上一次的注册的handler,建议只调用一次,注册成功后会在每次收到广播数据包以后产生事件回调。
+ *
+ */
+void advdata_report_Evt_Regist(advdata_rep_handler_t handler);
+																 
+/**@brief 关闭扫描
+ * @warning 
+ */																 
+void ST_scan_stop(void);
+
+/**@brief 无条件打开扫描
+ * @warning 
+ *
+ * @retval APP_ERROR_RESOURCES   radio占用过多,先关闭一个或多个链路后再打开就好了   
+ * @retval APP_SUCCESS           操作成功
+ *  			
+ * @note:
+ */
+unsigned int ST_scan_start(void);																 
+
+/**@brief 获取本机mac地址,*mac提供的内存长度必须大于6个字节否则内存溢出
+ * @warning 
+ *  			
+ * @note:
+ */
+void Get_MACaddr(unsigned char *mac);	
+
+#endif

+ 699 - 0
shoe_mcu2.2.1_new_v2/ble_cfg/cli.c

@@ -0,0 +1,699 @@
+#include "cli.h"
+
+extern void *cli_cmd$$Base;
+extern void *cli_cmd$$Limit;
+
+void cli_write(cli_t *p_cli)
+{
+	for (int i = 0; i < p_cli->chartemplen; i++)
+		p_cli->char_put(p_cli->tempbuf[i]);
+}
+
+int ringbufcmp(unsigned char *ringbuf, unsigned char ringbufis, const char *cr, int len)
+{
+	unsigned char i = ringbufis;
+	for (int j = 0; j < len; j++)
+	{
+		if (ringbuf[i] != cr[j])
+			return 1;
+		i++;
+	}
+	return 0;
+}
+
+/**
+ * @brief CLI colors for @ref nrf_cli_fprintf function.
+ */
+#define NRF_CLI_DEFAULT NRF_CLI_VT100_COLOR_DEFAULT /**< Turn off character attributes. */
+#define NRF_CLI_NORMAL NRF_CLI_VT100_COLOR_WHITE	/**< Normal color printf.           */
+#define NRF_CLI_INFO NRF_CLI_VT100_COLOR_GREEN		/**< Info color printf.             */
+#define NRF_CLI_OPTION NRF_CLI_VT100_COLOR_CYAN		/**< Option color printf.           */
+#define NRF_CLI_WARNING NRF_CLI_VT100_COLOR_YELLOW	/**< Warning color printf.          */
+#define NRF_CLI_ERROR NRF_CLI_VT100_COLOR_RED		/**< Error color printf.            */
+static void vt100_color_set(cli_t *p_cli, nrf_cli_vt100_color_t color)
+{
+	if (p_cli->col.col == color)
+	{
+		return;
+	}
+	p_cli->col.col = color;
+	cli_printf(p_cli, "\033[3%dm", color); //设置颜色
+}
+
+static void vt100_bgcolor_set(cli_t *p_cli, nrf_cli_vt100_color_t bgcolor)
+{
+	if (p_cli->col.bgcol == bgcolor)
+	{
+		return;
+	}
+	p_cli->col.bgcol = bgcolor;
+	cli_printf(p_cli, "\033[4%dm", bgcolor); //设置颜色
+}
+
+static inline void vt100_colors_store(cli_t *p_cli,
+									  nrf_cli_vt100_colors_t *p_color)
+{
+	memcpy(p_color, &p_cli->col, sizeof(nrf_cli_vt100_colors_t));
+}
+
+static void vt100_colors_restore(cli_t *p_cli,
+								 nrf_cli_vt100_colors_t const *p_color)
+{
+	vt100_color_set(p_cli, p_color->col);
+	vt100_bgcolor_set(p_cli, p_color->bgcol);
+}
+
+#define print_name cli_fprintf(p_cli, NRF_CLI_VT100_COLOR_GREEN, "\033[1m \r%s", p_cli->p_name)
+
+void Tab_pcs(cli_t *p_cli)
+{
+	int temp = 0;
+	cli_section_cmd_t *stmy;
+	if (p_cli->cmdwp == p_cli->cmdrp)
+	{
+		cli_printf(p_cli, "\n\r\t");
+		for (int p = (unsigned int)&cli_cmd$$Base; p < (unsigned int)&cli_cmd$$Limit; p += sizeof(cli_section_cmd_t))
+		{
+			stmy = ((cli_section_cmd_t *)p);
+			cli_fprintf(p_cli, NRF_CLI_VT100_COLOR_CYAN, "%s\t", stmy->_p_cmd_str);
+			temp++;
+			if (temp % 5 == 0)
+				cli_printf(p_cli, "\n\r\t");
+		}
+		cli_printf(p_cli, "\n");
+		print_name;
+	}
+	else
+	{
+		for (int p = (unsigned int)&cli_cmd$$Base; p < (unsigned int)&cli_cmd$$Limit; p += sizeof(cli_section_cmd_t))
+		{
+			stmy = ((cli_section_cmd_t *)p);
+			if (ringbufcmp(p_cli->cmdbuf, p_cli->cmdrp, stmy->_p_cmd_str, p_cli->cmdwp - p_cli->cmdrp) == 0)
+			{
+				for (int i = p_cli->cmdwp - p_cli->cmdrp; i < strlen(stmy->_p_cmd_str); i++)
+					p_cli->cmdbuf[p_cli->cmdwp++] = stmy->_p_cmd_str[i];
+				cli_printf(p_cli, "\n\r");
+				print_name;
+				cli_printf(p_cli, "%s", stmy->_p_cmd_str);
+				break;
+			}
+		}
+	}
+}
+void Backspace_pcs(cli_t *p_cli)
+{
+	if (p_cli->cmdwp != p_cli->cmdrp)
+	{
+		NRF_CLI_VT100_CMD(p_cli, NRF_CLI_VT100_CLEAREOL); //清除光标后面的内容
+		p_cli->cmdwp--;
+	}
+	else
+	{
+		cli_printf(p_cli, "\033[1C"); //光标右移动
+	}
+}
+void Delete_pcs(cli_t *p_cli)
+{
+	
+}
+
+#define Historyshowlen 50
+void Up_pcs(cli_t *p_cli)
+{
+	unsigned char showH_p = 0;
+	unsigned char fir = 1;
+	nrf_cli_vt100_colors_t col;
+	if (p_cli->cmdbuf[(unsigned char)(p_cli->historyrp - 1)] != '*')
+		return;
+	if (p_cli->historyrp != p_cli->cmdwp)
+	{
+		p_cli->cmdwp = p_cli->cmdrp;
+		cli_printf(p_cli, "\r");
+		print_name;
+		cli_printf(p_cli, "\033[K");
+	}
+	for (unsigned char i = (unsigned char)p_cli->historyrp - 2; i != (unsigned char)(p_cli->historyrp - Historyshowlen); i--)
+	{
+		if (p_cli->cmdbuf[i] == '*')
+		{
+			if (fir)
+			{
+				for (int j = 0; j < showH_p; j++)
+				{
+					p_cli->char_put(p_cli->cmdbuf[(unsigned char)(i + j + 1)]);
+					p_cli->cmdbuf[p_cli->cmdwp++] = p_cli->cmdbuf[(unsigned char)(i + j + 1)];
+				}
+				cli_printf(p_cli, "\033[s");
+				p_cli->char_put(' ');
+				p_cli->historyrp = i + 1;
+				fir = 0;
+				vt100_colors_store(p_cli, &col);
+				vt100_color_set(p_cli, NRF_CLI_VT100_COLOR_CYAN);
+				p_cli->char_put('[');
+			}
+			else
+			{
+				for (int j = 0; j < showH_p; j++)
+					p_cli->char_put(p_cli->cmdbuf[(unsigned char)(i + j + 1)]);
+				p_cli->char_put(' ');
+			}
+
+			showH_p = 0;
+		}
+		else
+			showH_p++;
+		if ((p_cli->cmdbuf[i] == 0) || (i == p_cli->cmdwp))
+			break;
+	}
+	if (fir == 0)
+	{
+		p_cli->char_put(']');
+		vt100_colors_restore(p_cli, &col);
+		cli_printf(p_cli, "\033[u");
+	}
+}
+
+void Down_pcs(cli_t *p_cli)
+{
+	for (unsigned char j = 0; j < p_cli->cmdwp; j++)
+		p_cli->char_put(p_cli->cmdbuf[j]);
+}
+
+void Left_pcs(cli_t *p_cli)
+{
+	cli_printf(p_cli, "\033[1D"); 
+}
+
+void Right_pcs(cli_t *p_cli)
+{
+	cli_printf(p_cli, "\033[1C");
+}
+#define ARGVCUNMAX 25
+char *cmd_argv[ARGVCUNMAX]; //最多存放25个参数的指针
+
+void cmd_pcs(cli_t *p_cli)
+{
+	cli_section_cmd_t *stmy;
+	int stmy_len = 0;
+	char sgv_tag = 0;
+	unsigned short agvc = 0;
+	char argvtrg = 0;
+	for (int p = (unsigned int)&cli_cmd$$Base; p < (unsigned int)&cli_cmd$$Limit; p += sizeof(cli_section_cmd_t))
+	{
+		stmy = ((cli_section_cmd_t *)p);
+		stmy_len = strlen(stmy->_p_cmd_str);
+		if (
+				((unsigned char)stmy_len == (unsigned char)(p_cli->cmdwp - p_cli->cmdrp))||
+				(((unsigned char)stmy_len < (unsigned char)(p_cli->cmdwp - p_cli->cmdrp))&&(p_cli->cmdbuf[(unsigned char)(p_cli->cmdrp + stmy_len)] == ' '))
+			 )
+		{
+			if (ringbufcmp(p_cli->cmdbuf, p_cli->cmdrp, stmy->_p_cmd_str, stmy_len) == 0)
+			{
+				cli_printf(p_cli, "\r\n");
+				if ((unsigned char)stmy_len == (unsigned char)(p_cli->cmdwp - p_cli->cmdrp))
+				{
+					(*(cli_cmd_t *)(&(stmy->_p_cmd_hander)))(p_cli, 0, NULL); //调用没参数的命令
+				}
+				else 
+				{
+					agvc = 0;
+					p_cli->cmdbuf[p_cli->cmdwp++] = ' ';
+					//找出所有参数的指针
+					for (unsigned char i = (unsigned char)(p_cli->cmdrp + stmy_len); (unsigned char)i != p_cli->cmdwp; i++)
+					{
+						switch (sgv_tag)
+						{
+						case 0:
+							if (p_cli->cmdbuf[i] != ' ')
+							{
+								cmd_argv[agvc++] = (char *)(&(p_cli->cmdbuf[i]));
+								sgv_tag++;
+							}
+							break;
+						default:
+							if (p_cli->cmdbuf[i] == ' ')
+							{
+								p_cli->cmdbuf[i] = 0;
+								sgv_tag = 0;
+							}
+							else if ((i == 255) && (p_cli->cmdbuf[0] != ' ')) //参数不连续
+							{
+								argvtrg = 1;
+							}
+							break;
+						}
+					}
+
+					if (argvtrg == 0) //没有出现参数不连续的情况
+					{
+						//调用命令,带参数					
+						(*(cli_cmd_t *)(&(stmy->_p_cmd_hander)))(p_cli, agvc, cmd_argv);
+					}
+					else
+					{
+						cli_fprintf(p_cli, NRF_CLI_ERROR, "\tPlase try once again! ");
+					}
+					if(agvc>0)p_cli->cmdwp = (unsigned char)((unsigned int)(&cmd_argv[agvc - 1][strlen(cmd_argv[agvc - 1])]) - (unsigned int)&p_cli->cmdbuf[0]);
+					for (int i = 0; i < agvc; i++)
+					{
+						cmd_argv[i][strlen(cmd_argv[i])] = ' ';
+					}
+				}
+				cli_printf(p_cli, "\n");
+				print_name;		
+				p_cli->cmdbuf[p_cli->cmdwp++] = '*';	
+				for(unsigned char i=p_cli->cmdwp-1;i>p_cli->cmdrp-1;i--)
+				{
+					if(p_cli->cmdbuf[i]!= p_cli->cmdbuf[(unsigned char)(i-(p_cli->cmdwp-p_cli->cmdrp))])
+					{	
+						//添加到运行历史
+						p_cli->cmdrp = p_cli->cmdwp;						
+						return ;
+					}
+				}
+				p_cli->cmdwp = p_cli->cmdrp;
+				return;
+			}
+		}
+	}
+	p_cli->cmdbuf[p_cli->cmdwp] = 0;
+	cli_fprintf(p_cli, NRF_CLI_ERROR, "\tCan not find cmd [");
+	for (unsigned char i = p_cli->cmdrp; i != p_cli->cmdwp; i++)
+		p_cli->char_put(p_cli->cmdbuf[i]);
+	cli_fprintf(p_cli, NRF_CLI_ERROR, "]\n");
+	print_name;
+	p_cli->cmdwp = p_cli->cmdrp;
+}
+
+void Enter_pcs(cli_t *p_cli)
+{
+	if (p_cli->cmdwp == p_cli->cmdrp)
+	{
+		print_name;
+	}
+	else
+	{
+		cmd_pcs(p_cli);
+	}
+	p_cli->historyrp = p_cli->cmdwp;
+}
+
+void F4_pcs(cli_t *p_cli)
+{
+	NRF_CLI_VT100_CMD(p_cli, NRF_CLI_VT100_CURSORHOME);
+	NRF_CLI_VT100_CMD(p_cli, NRF_CLI_VT100_CLEARSCREEN);
+	print_name;
+}
+void F5_pcs(cli_t *p_cli)
+{
+	Up_pcs(p_cli);
+	cli_printf(p_cli, "\r\n");
+	Enter_pcs(p_cli);
+}
+
+void cli_process(cli_t *p_cli)
+{
+	static unsigned char FN = 0;
+	unsigned char key = 0;
+	if (p_cli->char_ok())
+	{
+		key = p_cli->char_get();
+		switch (key)
+		{
+#if 1
+		case 0x08: //Backspace
+			Backspace_pcs(p_cli);
+			break;
+		case 0x09: //Tab
+			Tab_pcs(p_cli);
+			break;
+
+		case 0x0d:
+			FN = 20;
+			break;
+		case 0x0a: //Enter
+			if (FN == 20)
+			{
+				Enter_pcs(p_cli);
+				FN = 0;
+			}
+
+			break;
+
+		case 0x1B: //Esc
+			FN = 1;
+			break;
+
+		case 'A':
+			if (FN == 1)
+			{
+				Up_pcs(p_cli);
+				FN = 0;
+			}
+			else
+				p_cli->cmdbuf[p_cli->cmdwp++] = key;
+			break;
+		case 'B':
+			if (FN == 1)
+			{
+				Down_pcs(p_cli);
+				FN = 0;
+			}
+			else
+				p_cli->cmdbuf[p_cli->cmdwp++] = key;
+			break;
+		case 'C':
+			if (FN == 1)
+			{
+				Right_pcs(p_cli);
+				FN = 0;
+			}
+			else
+				p_cli->cmdbuf[p_cli->cmdwp++] = key;
+			break;
+		case 'D':
+			if (FN == 1)
+			{
+				Left_pcs(p_cli);
+				FN = 0;
+			}
+			else
+				p_cli->cmdbuf[p_cli->cmdwp++] = key;
+			break;
+		case 'O': //
+			if (FN == 1)
+				FN = 2;
+			else
+				p_cli->cmdbuf[p_cli->cmdwp++] = key;
+			break;
+
+		case 'P':
+			if (FN == 2)
+			{
+				FN = 0;
+				p_cli->char_put('F');
+				p_cli->char_put('1');
+			}
+			else
+				p_cli->cmdbuf[p_cli->cmdwp++] = key;
+			break;
+
+		case 'Q':
+			if (FN == 2)
+			{
+				FN = 0;
+				p_cli->char_put('F');
+				p_cli->char_put('2');
+			}
+			else
+				p_cli->cmdbuf[p_cli->cmdwp++] = key;
+			break;
+
+		case 'R':
+			if (FN == 2)
+			{
+				FN = 0;
+				p_cli->char_put('F');
+				p_cli->char_put('3');
+			}
+			else
+				p_cli->cmdbuf[p_cli->cmdwp++] = key;
+			break;
+
+		case 'S':
+			if (FN == 2)
+			{
+				FN = 0;
+				F4_pcs(p_cli); //F4按钮
+			}
+			else
+				p_cli->cmdbuf[p_cli->cmdwp++] = key;
+			break;
+
+		case '[':
+			FN = 1;
+			break;
+		case '0':
+			if (FN == 2)
+				FN = 9;
+			else
+				p_cli->cmdbuf[p_cli->cmdwp++] = key;
+			break;
+		case '1':
+			if (FN == 2)
+				FN = 10;
+			else if (FN == 1)
+				FN = 2;
+			else
+				p_cli->cmdbuf[p_cli->cmdwp++] = key;
+			break;
+		case '2':
+			if (FN == 1)
+				FN = 2;
+			else
+				p_cli->cmdbuf[p_cli->cmdwp++] = key;
+			break;
+		case '3':
+			if (FN == 2)
+				FN = 11;
+			else
+				p_cli->cmdbuf[p_cli->cmdwp++] = key;
+			break;
+		case '4':
+			if (FN == 2)
+				FN = 12;
+			else
+				p_cli->cmdbuf[p_cli->cmdwp++] = key;
+			break;
+		case '5':
+			if (FN == 2)
+			{
+				FN = 5;
+			}
+			else
+				p_cli->cmdbuf[p_cli->cmdwp++] = key;
+			break;
+
+		case '7':
+			if (FN == 2)
+			{
+				FN = 6;
+			}
+			else
+				p_cli->cmdbuf[p_cli->cmdwp++] = key;
+			break;
+
+		case '8':
+			if (FN == 2)
+			{
+				FN = 7;
+			}
+			else
+				p_cli->cmdbuf[p_cli->cmdwp++] = key;
+			break;
+
+		case '9':
+			if (FN == 2)
+			{
+				FN = 8;
+			}
+			else
+				p_cli->cmdbuf[p_cli->cmdwp++] = key;
+			break;
+
+		case '~':
+			switch (FN)
+			{
+			case 5:
+				F5_pcs(p_cli);
+				break;
+			case 6:
+				p_cli->char_put('F');
+				p_cli->char_put('6');
+				FN = 0;
+				break;
+			case 7:
+				p_cli->char_put('F');
+				p_cli->char_put('7');
+				FN = 0;
+				break;
+			case 8:
+				p_cli->char_put('F');
+				p_cli->char_put('8');
+				FN = 0;
+				break;
+			case 9:
+				p_cli->char_put('F');
+				p_cli->char_put('9');
+				FN = 0;
+				break;
+			case 10:
+				p_cli->char_put('F');
+				p_cli->char_put('1');
+				p_cli->char_put('0');
+				FN = 0;
+				break;
+			case 11:
+				p_cli->char_put('F');
+				p_cli->char_put('1');
+				p_cli->char_put('1');
+				FN = 0;
+				break;
+			case 12:
+				p_cli->char_put('F');
+				p_cli->char_put('1');
+				p_cli->char_put('2');
+				FN = 0;
+				break;
+			default:
+				SEGGER_RTT_Write(0, &key, 1);
+				break;
+			}
+			break;
+
+		case 0x7f: //Delete
+			Delete_pcs(p_cli);
+			break;
+#endif
+		default:
+			p_cli->cmdbuf[p_cli->cmdwp++] = key;
+			break;
+		}
+	}
+extern 	void recall_cmd_pcs(cli_t *p_cli);
+	recall_cmd_pcs(p_cli);
+}
+
+void cli_exe_cmd(cli_t *p_cli,char *cmd)
+{
+	int len =strlen(cmd);
+	if(len>128)return;
+	for(unsigned char i= 0;i<len;i++)
+	{
+		p_cli->cmdbuf[p_cli->cmdwp++]=cmd[i];
+	}
+	Enter_pcs(p_cli);
+}
+
+void clc_pcs(cli_t *p_cli, unsigned short argc, char **argv)
+{
+	NRF_CLI_VT100_CMD(p_cli, NRF_CLI_VT100_CURSORHOME);
+	NRF_CLI_VT100_CMD(p_cli, NRF_CLI_VT100_CLEARSCREEN);
+}
+
+CLI_CMD_REGISTER(clc, "clear sereen", clc_pcs);
+CLI_CMD_REGISTER(clear, "clear sereen", clc_pcs);
+
+void History_pcs(cli_t *p_cli, unsigned short argc, char **argv)
+{
+	cli_fprintf(p_cli, NRF_CLI_VT100_COLOR_CYAN, "[1]History");
+}
+CLI_CMD_REGISTER(history, "Cli cmd history", History_pcs);
+void print_param_pcs(cli_t *p_cli, unsigned short argc, char **argv)
+{
+	for (int i = 0; i < argc; i++)
+	{
+		cli_fprintf(p_cli, NRF_CLI_VT100_COLOR_CYAN, "%s\r\n", argv[i]);
+	}
+}
+CLI_CMD_REGISTER(print_param, "Cli cmd history", print_param_pcs);
+
+#define RECALL_CMD_LEN_MAX 30
+unsigned char recall_cmd_buff[RECALL_CMD_LEN_MAX];
+static int recall_cmd_buff_len=0;
+static unsigned int recall_cmd_pcs_interval = 0;
+static int recall_cmd_times = 0;
+static char allcall=0;
+void recall_cmd_pcs(cli_t *p_cli)
+{
+	static unsigned int cun = 0;
+	if ((recall_cmd_times > 0)||(allcall))
+	{
+		if (cun >= recall_cmd_pcs_interval)
+		{
+			cun = 0;			
+			for(int i=0;i<recall_cmd_buff_len;i++)
+			{
+				p_cli->cmdbuf[p_cli->cmdwp++]=recall_cmd_buff[i];
+			}
+			cli_fprintf(p_cli, NRF_CLI_VT100_COLOR_CYAN, "recall times %d ...\r\n",recall_cmd_times);
+			Enter_pcs(p_cli);
+			if(!allcall)recall_cmd_times--;
+		}
+		cun++;
+	}
+}
+void recall_pcs(cli_t *p_cli, unsigned short argc, char **argv)
+{
+	if (argc == 0)
+	{
+		recall_cmd_times = 0;
+		allcall=0;
+		cli_fprintf(p_cli, NRF_CLI_VT100_COLOR_CYAN, "help: recall interval times cmd ...");
+	}
+	else if (argc >= 3)
+	{
+		recall_cmd_pcs_interval = atoi(argv[0]);
+		recall_cmd_times = atoi(argv[1]);
+		if((recall_cmd_times==0)||(recall_cmd_pcs_interval==0))
+		{
+			if((recall_cmd_times==0)&&(recall_cmd_pcs_interval!=0)&&(argv[1][0]=='*'))
+			{
+				allcall=1;				
+			}
+			else
+			{
+				cli_fprintf(p_cli, NRF_CLI_VT100_COLOR_CYAN, "help: recall interval times cmd ...\r\n");
+				cli_fprintf(p_cli, NRF_CLI_VT100_COLOR_CYAN, "interval and times is a number\r\n");
+				return ;
+			}
+		}
+		recall_cmd_buff_len=0;
+		for (int i = 2; i < argc; i++)
+		{
+			memcpy(&recall_cmd_buff[recall_cmd_buff_len],argv[i],strlen(argv[i]));
+			recall_cmd_buff_len+=strlen(argv[i]);
+			recall_cmd_buff[recall_cmd_buff_len++]=' ';
+		}
+		cli_printf(p_cli, "recall [ ");			
+		for(int i=0;i<recall_cmd_buff_len;i++)
+		{
+			p_cli->char_put(recall_cmd_buff[i]);
+		}
+		if(allcall){cli_printf(p_cli, " ] interval =%d times= **** success\r\n",recall_cmd_pcs_interval);	
+		}else {cli_printf(p_cli, " ] interval =%d times= %d success\r\n",recall_cmd_pcs_interval,recall_cmd_times);	
+		}SEGGER_RTT_Write(0,recall_cmd_buff,recall_cmd_buff_len);
+	}
+	else
+	{
+		cli_printf(p_cli, "recall_pcs -> param err");
+	}
+}
+CLI_CMD_REGISTER(recall, "Cli cmd history", recall_pcs);
+
+char rttok(void)
+{
+	if (SEGGER_RTT_HasKey())
+		return 1;
+	return 0;
+}
+unsigned char rttget(void)
+{
+	unsigned char buf[60];
+	SEGGER_RTT_Read(0, buf, 60);
+	return buf[0];
+}
+void rttput(unsigned char p)
+{
+	unsigned char buf[60];
+	buf[0] = p;
+	SEGGER_RTT_Write(0, buf, 1);
+}
+
+CLI_DEFINE(clirtt, "CLI^$:", rttok, rttget, rttput);
+
+int mai5n(void)
+{
+	while (1)
+		cli_process(&clirtt);
+}

+ 100 - 0
shoe_mcu2.2.1_new_v2/ble_cfg/cli.h

@@ -0,0 +1,100 @@
+#ifndef _CLI_H__
+#define _CLI_H__
+#include "SEGGER_RTT.h"
+#include "string.h"
+#include "stdlib.h"
+#include "cli_vt100.h" //¿ÉÖ±½Ó¸´ÖÆÎļþ
+
+typedef enum
+{
+	NRF_CLI_VT100_COLOR_BLACK = 0,
+	NRF_CLI_VT100_COLOR_RED,
+	NRF_CLI_VT100_COLOR_GREEN,
+	NRF_CLI_VT100_COLOR_YELLOW,
+	NRF_CLI_VT100_COLOR_BLUE,
+	NRF_CLI_VT100_COLOR_MAGENTA,
+	NRF_CLI_VT100_COLOR_CYAN,
+	NRF_CLI_VT100_COLOR_WHITE,
+} nrf_cli_vt100_color_t;
+
+typedef struct
+{
+	nrf_cli_vt100_color_t col;	 // text color
+	nrf_cli_vt100_color_t bgcol; // background color
+} nrf_cli_vt100_colors_t;
+
+typedef void (*cli_char_put_t)(unsigned char);
+typedef unsigned char (*cli_char_get_t)(void);
+typedef char (*cli_char_ok_t)(void);
+
+typedef struct
+{
+	const char *_p_cmd_str;
+	const char *_p_cmd_help_str;
+	const void *_p_cmd_hander;
+} cli_section_cmd_t;
+
+typedef struct
+{
+	char const *const p_name;
+	cli_char_put_t char_put;
+	cli_char_get_t char_get;
+	cli_char_ok_t char_ok;
+	unsigned char cmdbuf[256];
+	unsigned char cmdwp;
+	unsigned char cmdrp;
+	unsigned char historyrp;
+	char tempbuf[256];
+	unsigned chartemplen;
+	unsigned char tab_sta;
+	nrf_cli_vt100_colors_t col;
+} cli_t;
+
+/**
+ * @brief CLI command handler prototype.
+ */
+typedef void (*cli_cmd_t)(cli_t const *p_cli, unsigned short argc, char **argv);
+
+#define CLI_CMD_REGISTER(_p_cmd, _p_help, _p_handler)                                    \
+	__attribute__((section("cli_cmd"))) cli_section_cmd_t const cli_cmd_##_p_cmd##_row = \
+		{                                                                                \
+			._p_cmd_str = (const char *)STRINGIFY(_p_cmd),                               \
+			._p_cmd_help_str = (const char *)_p_help,                                    \
+			._p_cmd_hander = (const void *)_p_handler}
+
+#define cli_fprintf(p_cli, color, ...)     \
+	{                                      \
+		nrf_cli_vt100_colors_t col;        \
+		vt100_colors_store(p_cli, &col);   \
+		vt100_color_set(p_cli, color);     \
+		cli_printf(p_cli, __VA_ARGS__);    \
+		vt100_colors_restore(p_cli, &col); \
+	}
+
+#define cli_printf(p_cli, ...)                                     \
+	{                                                              \
+		p_cli->chartemplen = sprintf(p_cli->tempbuf, __VA_ARGS__); \
+		for (int i = 0; i < p_cli->chartemplen; i++)               \
+			p_cli->char_put(p_cli->tempbuf[i]);                    \
+	}
+
+#define NRF_CLI_VT100_CMD(_p_cli_, _cmd_) \
+	{                                     \
+		static char const cmd[] = _cmd_;  \
+		cli_printf(_p_cli_, "%s", cmd);   \
+	}
+
+#define CLI_DEFINE(name, cli_prefix, p_char_ok, p_char_get, p_char_put) \
+	cli_t name = {                                                      \
+		.p_name = cli_prefix,                                           \
+		.char_ok = p_char_ok,                                           \
+		.char_get = p_char_get,                                         \
+		.char_put = p_char_put,                                         \
+		.cmdbuf[255] = '*',                                             \
+		.col.col = NRF_CLI_VT100_COLOR_WHITE}
+
+void cli_process(cli_t *p_cli);
+void cli_exe_cmd(cli_t *p_cli,char *cmd);
+		
+extern cli_t clirtt;
+#endif

+ 593 - 0
shoe_mcu2.2.1_new_v2/ble_cfg/cli_vt100.h

@@ -0,0 +1,593 @@
+#ifndef NRF_CLI_VT100_H__
+#define NRF_CLI_VT100_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define NRF_CLI_VT100_ASCII_ESC     (0x1b)
+#define NRF_CLI_VT100_ASCII_DEL     (0x7F)
+#define NRF_CLI_VT100_ASCII_BSPACE  (0x08)
+#define NRF_CLI_VT100_ASCII_CTRL_A  (0x1)
+#define NRF_CLI_VT100_ASCII_CTRL_C  (0x03)
+#define NRF_CLI_VT100_ASCII_CTRL_E  (0x5)
+#define NRF_CLI_VT100_ASCII_CTRL_L  (0x0C)
+#define NRF_CLI_VT100_ASCII_CTRL_U  (0x15)
+#define NRF_CLI_VT100_ASCII_CTRL_W  (0x17)
+
+
+#define NRF_CLI_VT100_SETNL                                             \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, '[', '2', '0', 'h', '\0'               \
+    } /* Set new line mode */
+#define NRF_CLI_VT100_SETAPPL                                           \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, '[', '?', '1', 'h', '\0'               \
+    } /* Set cursor key to application */
+#define NRF_CLI_VT100_SETCOL_132                                        \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, '[', '?', '3', 'h', '\0'               \
+    } /* Set number of columns to 132 */
+#define NRF_CLI_VT100_SETSMOOTH                                         \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, '[', '?', '4', 'h', '\0'               \
+    } /* Set smooth scrolling */
+#define NRF_CLI_VT100_SETREVSCRN                                        \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, '[', '?', '5', 'h', '\0'               \
+    } /* Set reverse video on screen */
+#define NRF_CLI_VT100_SETORGREL                                         \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, '[', '?', '6', 'h', '\0'               \
+    } /* Set origin to relative */
+#define NRF_CLI_VT100_SETWRAP_ON                                        \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, '[', '?', '7', 'h', '\0'               \
+    } /* Set auto-wrap mode */
+#define NRF_CLI_VT100_SETWRAP_OFF                                       \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, '[', '?', '7', 'l', '\0'               \
+    } /* Set auto-wrap mode */
+
+#define NRF_CLI_VT100_SETREP                                            \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, '[', '?', '8', 'h', '\0'               \
+    } /* Set auto-repeat mode */
+#define NRF_CLI_VT100_SETINTER                                          \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, '[', '?', '9', 'h', '\0'               \
+    } /* Set interlacing mode */
+
+#define NRF_CLI_VT100_SETLF                                             \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, '[', '2', '0', 'l', '\0'               \
+    } /* Set line feed mode */
+#define NRF_CLI_VT100_SETCURSOR                                         \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, '[', '?', '1', 'l', '\0'               \
+    } /* Set cursor key to cursor */
+#define NRF_CLI_VT100_SETVT52                                           \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, '[', '?', '2', 'l', '\0'               \
+    } /* Set VT52 (versus ANSI) */
+#define NRF_CLI_VT100_SETCOL_80                                         \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, '[', '?', '3', 'l', '\0'               \
+    } /* Set number of columns to 80 */
+#define NRF_CLI_VT100_SETJUMP                                           \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, '[', '?', '4', 'l', '\0'               \
+    } /* Set jump scrolling */
+#define NRF_CLI_VT100_SETNORMSCRN                                       \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, '[', '?', '5', 'l', '\0'               \
+    } /* Set normal video on screen */
+#define NRF_CLI_VT100_SETORGABS                                         \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, '[', '?', '6', 'l', '\0'               \
+    } /* Set origin to absolute */
+#define NRF_CLI_VT100_RESETWRAP                                         \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, '[', '?', '7', 'l', '\0'               \
+    } /* Reset auto-wrap mode */
+#define NRF_CLI_VT100_RESETREP                                          \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, '[', '?', '8', 'l', '\0'               \
+    } /* Reset auto-repeat mode */
+#define NRF_CLI_VT100_RESETINTER                                        \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, '[', '?', '9', 'l', '\0'               \
+    } /* Reset interlacing mode */
+
+#define NRF_CLI_VT100_ALTKEYPAD                                         \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, '=', '\0'                              \
+    } /* Set alternate keypad mode */
+#define NRF_CLI_VT100_NUMKEYPAD                                         \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, '>', '\0'                              \
+    } /* Set numeric keypad mode */
+
+#define NRF_CLI_VT100_SETUKG0                                           \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, '(', 'A', '\0'                         \
+    } /* Set United Kingdom G0 character set */
+#define NRF_CLI_VT100_SETUKG1                                           \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, ')', 'A', '\0'                         \
+    } /* Set United Kingdom G1 character set */
+#define NRF_CLI_VT100_SETUSG0                                           \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, '(', 'B', '\0'                         \
+    } /* Set United States G0 character set */
+#define NRF_CLI_VT100_SETUSG1                                           \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, ')', 'B', '\0'                         \
+    } /* Set United States G1 character set */
+#define NRF_CLI_VT100_SETSPECG0                                         \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, '(', '0', '\0'                         \
+    } /* Set G0 special chars. & line set */
+#define NRF_CLI_VT100_SETSPECG1                                         \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, ')', '0', '\0'                         \
+    } /* Set G1 special chars. & line set */
+#define NRF_CLI_VT100_SETALTG0                                          \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, '(', '1', '\0'                         \
+    } /* Set G0 alternate character ROM */
+#define NRF_CLI_VT100_SETALTG1                                          \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, ')', '1', '\0'                         \
+    } /* Set G1 alternate character ROM */
+#define NRF_CLI_VT100_SETALTSPECG0                                      \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, '(', '2', '\0'                         \
+    } /* Set G0 alt char ROM and spec. graphics */
+#define NRF_CLI_VT100_SETALTSPECG1                                      \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, ')', '2', '\0'                         \
+    } /* Set G1 alt char ROM and spec. graphics */
+
+#define NRF_CLI_VT100_SETSS2                                            \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, 'N', '\0'                              \
+    } /* Set single shift 2 */
+#define NRF_CLI_VT100_SETSS3                                            \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, 'O', '\0'                              \
+    } /* Set single shift 3 */
+
+#define NRF_CLI_VT100_MODESOFF                                          \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, '[', 'm', '\0'                         \
+    } /* Turn off character attributes */
+#define NRF_CLI_VT100_MODESOFF_                                         \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, '[', '0', 'm', '\0'                    \
+    } /* Turn off character attributes */
+#define NRF_CLI_VT100_BOLD                                              \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, '[', '1', 'm', '\0'                    \
+    } /* Turn bold mode on */
+#define NRF_CLI_VT100_LOWINT                                            \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, '[', '2', 'm', '\0'                    \
+    } /* Turn low intensity mode on */
+#define NRF_CLI_VT100_UNDERLINE                                         \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, '[', '4', 'm', '\0'                    \
+    } /* Turn underline mode on */
+#define NRF_CLI_VT100_BLINK                                             \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, '[', '5', 'm', '\0'                    \
+    } /* Turn blinking mode on */
+#define NRF_CLI_VT100_REVERSE                                           \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, '[', '7', 'm', '\0'                    \
+    } /* Turn reverse video on */
+#define NRF_CLI_VT100_INVISIBLE                                         \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, '[', '8', 'm', '\0'                    \
+    } /* Turn invisible text mode on */
+
+#define NRF_CLI_VT100_SETWIN(t, b)                                      \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, '[', (t), ';', (b), 'r', '\0'          \
+    } /* Set top and bottom line#s of a window */
+
+#define NRF_CLI_VT100_CURSORUP(n)                                       \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, '[', (n), 'A', '\0'                    \
+    } /* Move cursor up n lines */
+#define NRF_CLI_VT100_CURSORDN(n)                                       \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, '[', (n), 'B', '\0'                    \
+    } /* Move cursor down n lines */
+#define NRF_CLI_VT100_CURSORRT(n)                                       \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, '[', (n), 'C', '\0'                    \
+    } /* Move cursor right n lines */
+#define NRF_CLI_VT100_CURSORLF(n)                                       \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, '[', (n), 'D', '\0'                    \
+    } /* Move cursor left n lines */
+#define NRF_CLI_VT100_CURSORHOME                                        \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, '[', 'H', '\0'                         \
+    } /* Move cursor to upper left corner */
+#define NRF_CLI_VT100_CURSORHOME_                                       \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, '[', ';', 'H', '\0'                    \
+    } /* Move cursor to upper left corner */
+#define NRF_CLI_VT100_CURSORPOS(v, h)                                   \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, '[', (v), ';', (h), 'H', '\0'          \
+    } /* Move cursor to screen location v,h */
+
+#define NRF_CLI_VT100_HVHOME                                            \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, '[', 'f', '\0'                         \
+    } /* Move cursor to upper left corner */
+#define NRF_CLI_VT100_HVHOME_                                           \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, '[', ';', 'f', '\0'                    \
+    } /* Move cursor to upper left corner */
+#define NRF_CLI_VT100_HVPOS(v, h)                                       \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, '[', (v), ';', (h), 'f', '\0'          \
+    } /* Move cursor to screen location v,h */
+#define NRF_CLI_VT100_INDEX                                             \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, 'D', '\0'                              \
+    } /* Move/scroll window up one line */
+#define NRF_CLI_VT100_REVINDEX                                          \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, 'M', '\0'                              \
+    } /* Move/scroll window down one line */
+#define NRF_CLI_VT100_NEXTLINE                                          \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, 'E', '\0'                              \
+    } /* Move to next line */
+#define NRF_CLI_VT100_SAVECURSOR                                        \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, '7', '\0'                              \
+    } /* Save cursor position and attributes */
+#define NRF_CLI_VT100_RESTORECURSOR                                     \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, '8', '\0'                              \
+    } /* Restore cursor position and attribute */
+
+#define NRF_CLI_VT100_TABSET                                            \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, 'H', '\0'                              \
+    } /* Set a tab at the current column */
+#define NRF_CLI_VT100_TABCLR                                            \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, '[', 'g', '\0'                         \
+    } /* Clear a tab at the current column */
+#define NRF_CLI_VT100_TABCLR_                                           \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, '[', '0', 'g', '\0'                    \
+    } /* Clear a tab at the current column */
+#define NRF_CLI_VT100_TABCLRALL                                         \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, '[', '3', 'g', '\0'                    \
+    } /* Clear all tabs */
+
+#define NRF_CLI_VT100_DHTOP                                             \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, '#', '3', '\0'                         \
+    } /* Double-height letters, top half */
+#define NRF_CLI_VT100_DHBOT                                             \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, '#', '4', '\0'                         \
+    } /* Double-height letters, bottom hal */
+#define NRF_CLI_VT100_SWSH                                              \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, '#', '5', '\0'                         \
+    } /* Single width, single height letters */
+#define NRF_CLI_VT100_DWSH                                              \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, '#', '6', '\0'                         \
+    } /* Double width, single height letters */
+
+#define NRF_CLI_VT100_CLEAREOL                                          \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, '[', 'K', '\0'                         \
+    } /* Clear line from cursor right */
+#define NRF_CLI_VT100_CLEAREOL_                                         \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, '[', '0', 'K', '\0'                    \
+    } /* Clear line from cursor right */
+#define NRF_CLI_VT100_CLEARBOL                                          \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, '[', '1', 'K', '\0'                    \
+    } /* Clear line from cursor left */
+#define NRF_CLI_VT100_CLEARLINE                                         \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, '[', '2', 'K', '\0'                    \
+    } /* Clear entire line */
+
+#define NRF_CLI_VT100_CLEAREOS                                          \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, '[', 'J', '\0'                         \
+    } /* Clear screen from cursor down */
+#define NRF_CLI_VT100_CLEAREOS_                                         \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, '[', '0', 'J', '\0'                    \
+    } /* Clear screen from cursor down */
+#define NRF_CLI_VT100_CLEARBOS                                          \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, '[', '1', 'J', '\0'                    \
+    } /* Clear screen from cursor up */
+#define NRF_CLI_VT100_CLEARSCREEN                                       \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, '[', '2', 'J', '\0'                    \
+    } /* Clear entire screen */
+
+#define NRF_CLI_VT100_DEVSTAT                                           \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, '5', 'n', '\0'                         \
+    } /* Device status report */
+#define NRF_CLI_VT100_TERMOK                                            \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, '0', 'n', '\0'                         \
+    } /* Response: terminal is OK */
+#define NRF_CLI_VT100_TERMNOK                                           \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, '3', 'n', '\0'                         \
+    } /* Response: terminal is not OK */
+
+#define NRF_CLI_VT100_GETCURSOR                                         \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, '[', '6', 'n', '\0'                    \
+    } /* Get cursor position */
+#define NRF_CLI_VT100_CURSORPOSAT                                       \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, (v), ';', (h), 'R', '\0'               \
+    } /* Response: cursor is at v,h */
+
+#define NRF_CLI_VT100_IDENT                                             \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, '[', 'c', '\0'                         \
+    } /* Identify what terminal type */
+#define NRF_CLI_VT100_IDENT_                                            \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, '[', '0', 'c', '\0'                    \
+    } /* Identify what terminal type */
+#define NRF_CLI_VT100_GETTYPE                                           \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, '[', '?', '1', ';', (n), '0', 'c', '\0'\
+    } /* Response: terminal type code n */
+
+#define NRF_CLI_VT100_RESET                                             \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, 'c', '\0'                              \
+    } /*  Reset terminal to initial state */
+
+#define NRF_CLI_VT100_ALIGN                                             \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, '#', '8', '\0'                         \
+    } /* Screen alignment display */
+#define NRF_CLI_VT100_TESTPU                                            \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, '[', '2', ';', '1', 'y', '\0'          \
+    } /* Confidence power up test */
+#define NRF_CLI_VT100_TESTLB                                            \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, '[', '2', ';', '2', 'y', '\0'          \
+    } /* Confidence loopback test */
+#define NRF_CLI_VT100_TESTPUREP                                         \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, '[', '2', ';', '9', 'y', '\0'          \
+    } /* Repeat power up test */
+#define NRF_CLI_VT100_TESTLBREP                                         \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, '[', '2', ';', '1', '0', 'y', '\0'     \
+    } /* Repeat loopback test */
+
+#define NRF_CLI_VT100_LEDSOFF                                           \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, '[', '0', 'q', '\0'                    \
+    } /* Turn off all four leds */
+#define NRF_CLI_VT100_LED1                                              \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, '[', '1', 'q', '\0'                    \
+    } /* Turn on LED #1 */
+#define NRF_CLI_VT100_LED2                                              \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, '[', '2', 'q', '\0'                    \
+    } /* Turn on LED #2 */
+#define NRF_CLI_VT100_LED3                                              \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, '[', '3', 'q', '\0'                    \
+    } /* Turn on LED #3 */
+#define NRF_CLI_VT100_LED4                                              \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, '[', '4', 'q', '\0'                    \
+    } /* Turn on LED #4 */
+
+/* Function Keys */
+
+#define NRF_CLI_VT100_PF1                                               \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, 'O', 'P', '\0'                         \
+    }
+#define NRF_CLI_VT100_PF2                                               \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, 'O', 'Q', '\0'                         \
+    }
+#define NRF_CLI_VT100_PF3                                               \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, 'O', 'R', '\0'                         \
+    }
+#define NRF_CLI_VT100_PF4                                               \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, 'O', 'S', '\0'                         \
+    }
+
+/* Arrow keys */
+
+#define NRF_CLI_VT100_UP_RESET                                          \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, 'A', '\0'                              \
+    }
+#define NRF_CLI_VT100_UP_SET                                            \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, 'O', 'A', '\0'                         \
+    }
+#define NRF_CLI_VT100_DOWN_RESET                                        \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, 'B', '\0'                              \
+    }
+#define NRF_CLI_VT100_DOWN_SET                                          \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, 'O', 'B', '\0'                         \
+    }
+#define NRF_CLI_VT100_RIGHT_RESET                                       \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, 'C', '\0'                              \
+    }
+#define NRF_CLI_VT100_RIGHT_SET                                         \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, 'O', 'C', '\0'                         \
+    }
+#define NRF_CLI_VT100_LEFT_RESET                                        \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, 'D', '\0'                              \
+    }
+#define NRF_CLI_VT100_LEFT_SET                                          \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, 'O', 'D', '\0'                         \
+    }
+
+/* Numeric Keypad Keys */
+
+#define NRF_CLI_VT100_NUMERIC_0                                         \
+    {                                                                   \
+        '0', '\0'                                                       \
+    }
+#define NRF_CLI_VT100_ALT_0                                             \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, 'O', 'p', '\0'                         \
+    }
+#define NRF_CLI_VT100_NUMERIC_1                                         \
+    {                                                                   \
+        '1', '\0'                                                       \
+    }
+#define NRF_CLI_VT100_ALT_1                                             \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, 'O', 'q', '\0'                         \
+    }
+#define NRF_CLI_VT100_NUMERIC_2                                         \
+    {                                                                   \
+        '2', '\0'                                                       \
+    }
+#define NRF_CLI_VT100_ALT_2                                             \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, 'O', 'r', '\0'                         \
+    }
+#define NRF_CLI_VT100_NUMERIC_3                                         \
+    {                                                                   \
+        '3', '\0'                                                       \
+    }
+#define NRF_CLI_VT100_ALT_3                                             \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, 'O', 's', '\0'                         \
+    }
+#define NRF_CLI_VT100_NUMERIC_4                                         \
+    {                                                                   \
+        '4', '\0'                                                       \
+    }
+#define NRF_CLI_VT100_ALT_4                                             \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, 'O', 't', '\0'                         \
+    }
+#define NRF_CLI_VT100_NUMERIC_5                                         \
+    {                                                                   \
+        '5', '\0'                                                       \
+    }
+#define NRF_CLI_VT100_ALT_5                                             \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, 'O', 'u', '\0'                         \
+    }
+#define NRF_CLI_VT100_NUMERIC_6                                         \
+    {                                                                   \
+        '6', '\0'                                                       \
+    }
+#define NRF_CLI_VT100_ALT_6                                             \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, 'O', 'v', '\0'                         \
+    }
+#define NRF_CLI_VT100_NUMERIC_7                                         \
+    {                                                                   \
+        '7', '\0'                                                       \
+    }
+#define NRF_CLI_VT100_ALT_7                                             \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, 'O', 'w', '\0'                         \
+    }
+#define NRF_CLI_VT100_NUMERIC_8                                         \
+    {                                                                   \
+        '8', '\0'                                                       \
+    }
+#define NRF_CLI_VT100_ALT_8                                             \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, 'O', 'x', '\0'                         \
+    }
+#define NRF_CLI_VT100_NUMERIC_9                                         \
+    {                                                                   \
+        '9', '\0'
+#define NRF_CLI_VT100_ALT_9                                             \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, 'O', 'y'                               \
+    }
+#define NRF_CLI_VT100_NUMERIC_MINUS                                     \
+    {                                                                   \
+        '-', '\0'                                                       \
+    }
+#define NRF_CLI_VT100_ALT_MINUS                                         \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, 'O', 'm', '\0'                         \
+    }
+#define NRF_CLI_VT100_NUMERIC_COMMA                                     \
+    {                                                                   \
+        ',', '\0'                                                       \
+    }
+#define NRF_CLI_VT100_ALT_COMMA                                         \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, 'O', 'l', '\0'                         \
+    }
+#define NRF_CLI_VT100_NUMERIC_PERIOD                                    \
+    {                                                                   \
+        '.', '\0'                                                       \
+    }
+#define NRF_CLI_VT100_ALT_PERIOD                                        \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, 'O', 'n', '\0'                         \
+    }
+#define NRF_CLI_VT100_NUMERIC_ENTER                                     \
+    {                                                                   \
+        ASCII_CR                                                        \
+    }
+#define NRF_CLI_VT100_ALT_ENTER                                         \
+    {                                                                   \
+        NRF_CLI_VT100_ASCII_ESC, 'O', 'M', '\0'                         \
+    }
+
+#define NRF_CLI_VT100_COLOR(__col)                                            \
+    {                                                                         \
+        NRF_CLI_VT100_ASCII_ESC, '[', '1', ';', '3', '0' + (__col), 'm', '\0' \
+    }
+#define NRF_CLI_VT100_BGCOLOR(__col)                                          \
+    {                                                                         \
+        NRF_CLI_VT100_ASCII_ESC, '[', '4', '0' + (__col), 'm', '\0'           \
+    }
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* NRF_CLI_VT100_H__ */
+

+ 289 - 0
shoe_mcu2.2.1_new_v2/ble_cfg/dtalige.c

@@ -0,0 +1,289 @@
+#include "ble_comm.h"
+#include "vl53l1.h"
+#include "tool.h"
+
+
+#define GAMEUSEDTALIGE 1
+
+static unsigned char USEdtalige = 1;
+
+void IMU_Dtalige_Rowdata_ON(void)
+{
+	USEdtalige = 0;
+}
+
+void IMU_Dtalige_Rowdata_OFF(void)
+{
+	USEdtalige = 1;
+}
+
+//.....................重写运动库接口.............................
+unsigned char left_right_buff[60];
+unsigned char left_right_data_len;
+
+static void d_integrate_left_right(uint8_t* left_buff, uint8_t left_len, uint8_t* right_buff, uint8_t right_len)
+{
+	unsigned char L=0;
+	for(int i=0;i<left_len;i++)
+	{
+		left_right_buff[L++]=left_buff[i];
+	}
+	for(int i=0;i<right_len;i++)
+	{
+		left_right_buff[L++]=right_buff[i];
+	}
+	left_right_data_len=L;
+}
+
+static void d_get_game_package(uint8_t* buff_address, uint8_t * buff_len)
+{
+	for(int i=0;i<left_right_data_len;i++)
+	{
+		buff_address[i]=left_right_buff[i];
+	}
+	*buff_len=left_right_data_len;
+}
+
+unsigned char mofoot_buff[30];
+unsigned char mofoot_data_len;
+
+static void d_process_motion(int32_t time_stamp, int16_t _acc[3], int16_t _gry[3],  int16_t front_mag[3], int16_t back_mag[3], uint8_t _rssi)
+{
+	int L=0;
+	
+	mofoot_buff[L++]=_acc[0]>>8;
+	mofoot_buff[L++]=_acc[0];
+	mofoot_buff[L++]=_acc[1]>>8;
+	mofoot_buff[L++]=_acc[1];
+	mofoot_buff[L++]=_acc[2]>>8;
+	mofoot_buff[L++]=_acc[2];
+	
+	mofoot_buff[L++]=_gry[0]>>8;
+	mofoot_buff[L++]=_gry[0];
+	mofoot_buff[L++]=_gry[1]>>8;
+	mofoot_buff[L++]=_gry[1];
+	mofoot_buff[L++]=_gry[2]>>8;
+	mofoot_buff[L++]=_gry[2];
+	
+	mofoot_buff[L++]=front_mag[0]>>8;
+	mofoot_buff[L++]=front_mag[0];
+	mofoot_buff[L++]=front_mag[1]>>8;
+	mofoot_buff[L++]=front_mag[1];
+	mofoot_buff[L++]=front_mag[2]>>8;
+	mofoot_buff[L++]=front_mag[2];
+	
+	mofoot_buff[L++]=back_mag[0]>>8;
+	mofoot_buff[L++]=back_mag[0];
+	mofoot_buff[L++]=back_mag[1]>>8;
+	mofoot_buff[L++]=back_mag[1];
+	mofoot_buff[L++]=back_mag[2]>>8;
+	mofoot_buff[L++]=back_mag[2];
+	
+//	mofoot_buff[L++]=_rssi;
+//	
+//	mofoot_buff[L++]=time_stamp>>24;
+//	mofoot_buff[L++]=time_stamp>>16;
+//	mofoot_buff[L++]=time_stamp>>8;
+//	mofoot_buff[L++]=time_stamp;
+	
+	mofoot_data_len=L;
+}
+
+static void d_get_foot_data(uint8_t *buf, uint8_t *buff_len)
+{
+	for(int i=0;i<mofoot_data_len;i++)
+	{
+		buf[i]=mofoot_buff[i];
+	}
+	*buff_len=mofoot_data_len;
+}
+//.....................重写运动库接口.............................end
+
+typedef struct {
+	unsigned char imubuff[80];
+	unsigned char imubuff_len;
+	uint16_t        ts;
+}IMU_Hal_t;
+
+typedef struct {
+        IMU_Hal_t         h;
+        IMU_Hal_t         s;
+}IMU_Hal_RL_t;
+
+typedef void (*process_motion_t)(uint8_t* left_buff,uint8_t left_len, uint8_t* right_buff, uint8_t right_len);
+
+extern void get_game_package(uint8_t* buff_address, uint8_t * buff_len);
+extern void integrate_left_right(uint8_t* left_buff,uint8_t left_len, uint8_t* right_buff, uint8_t right_len);
+extern void get_foot_data(uint8_t *buf, uint8_t *buff_len);
+
+IMU_Hal_t rev_s={.ts=0};
+IMU_Hal_t rev={.ts=0};
+IMU_Hal_t rev_io;
+IMU_Hal_RL_t temp_IMU_DAT;
+QUEUE_DEF(IMU_Hal_t, IMU_DAT_H_queue, size_4, QUEUE_MODE_OVERFLOW);
+QUEUE_DEF(IMU_Hal_t, IMU_DAT_S_queue, size_4, QUEUE_MODE_OVERFLOW);
+
+extern uint16_t lose_pack_all;
+void IMU_dtalige(IMU_Hal_RL_t *outp, queue_t *ph, queue_t *ps, process_motion_t process_p)
+{
+    static char sta = 0;
+    static unsigned short R_timestamp_re = 0;
+    switch (sta)
+    {
+    case 0:
+        if (ps->element_count > 0)
+        {
+            BLE_PRINT( "IMU_dtalige init.\r\n");
+            sta = 1;
+            queue_reset(ps);
+            queue_reset(ph);
+        }
+        break;
+    case 1:  
+				while (ps->element_count > ph->element_count)
+				{
+						queue_out(ps, &outp->s);
+						R_timestamp_re = outp->s.ts;
+				}
+				if (ps->element_count > 0)
+				{
+						queue_out(ps, &outp->s);
+						R_timestamp_re++;
+						if (R_timestamp_re != outp->s.ts)
+						{
+								do
+								{
+										BLE_PRINT( "lose packet %d\r\n", R_timestamp_re);
+										#if LOSSPACK_ENANBLE
+									
+										extern uint16_t lose_pack_all;
+										lose_pack_all++;
+										#endif
+									
+										R_timestamp_re++;
+										queue_out(ph, &outp->h);
+										if (R_timestamp_re == outp->h.ts)
+										{
+												queue_out(ph, &outp->h);
+												process_p(outp->h.imubuff, outp->h.imubuff_len, outp->s.imubuff, outp->s.imubuff_len);
+												get_game_package(rev_io.imubuff, &rev_io.imubuff_len); 
+											
+												rev_io.ts++;
+												rev_io.imubuff[rev_io.imubuff_len + 1] = rev_io.ts;
+												rev_io.imubuff[rev_io.imubuff_len] = rev_io.ts >> 8;
+												if(rev_io.ts%2==0)
+												send_protocol(0, 4, rev_io.imubuff, rev_io.imubuff_len);
+												break;
+										}
+										if (ph->element_count <= 0)
+										{
+												sta = 0;
+												break;
+										}
+								} while (1);
+						}
+						else
+						{
+								queue_out(ph, &outp->h);
+							
+								process_p(outp->h.imubuff, outp->h.imubuff_len, outp->s.imubuff, outp->s.imubuff_len);
+								get_game_package(rev_io.imubuff, &rev_io.imubuff_len);
+							
+								rev_io.ts++;
+								rev_io.imubuff[rev_io.imubuff_len + 1] = rev_io.ts;
+								rev_io.imubuff[rev_io.imubuff_len] = rev_io.ts >> 8;
+								if(rev_io.ts%2==0)
+								send_protocol(0, 4, rev_io.imubuff, rev_io.imubuff_len);
+						}
+				}       
+        break;
+    }
+//		DEBUG_LOG( "%d,%d\r\n",ph->element_count,ps->element_count);
+}
+
+void IMU_Dtalige(void)
+{
+	if( USEdtalige )
+	{
+		#if GAMEUSEDTALIGE
+		IMU_dtalige(&temp_IMU_DAT, &IMU_DAT_H_queue, &IMU_DAT_S_queue, integrate_left_right);
+		#endif
+	}
+}
+
+void IMU_Rec_data(uint8_t* pdat,uint8_t len)
+{
+	if(pdat[3]==4)
+	{		
+		memcpy(rev_s.imubuff,&pdat[4],pdat[1]);
+		rev_s.imubuff_len=pdat[1]-7;
+		rev_s.ts=((uint16_t)pdat[pdat[1]-3]<<8) |((uint16_t)pdat[pdat[1]-2]<<0);
+		if( USEdtalige )
+		{
+			#if GAMEUSEDTALIGE
+			queue_in(&IMU_DAT_S_queue,&rev_s);	
+			#endif
+		}
+	}
+}
+
+void IMU_Process_motion_queue(uint8_t IS_HOST, int32_t time_stamp, int16_t* _acc,int16_t* _gry, int16_t* front_mag, int16_t* back_mag, uint8_t _rssi)
+{
+	if( USEdtalige )
+	{		
+		process_motion(time_stamp, _acc, _gry, front_mag, back_mag, _rssi);
+
+		get_foot_data(rev.imubuff,&rev.imubuff_len);
+	}
+	else
+	{
+		d_process_motion(time_stamp, _acc, _gry, front_mag, back_mag, _rssi);
+
+		d_get_foot_data(rev.imubuff,&rev.imubuff_len);
+	}
+	rev.ts++;		
+		
+	if(IS_HOST)
+	{
+		if( USEdtalige )
+		{
+			#if GAMEUSEDTALIGE
+			queue_in(&IMU_DAT_H_queue,&rev);
+			#else
+			integrate_left_right(rev.imubuff, rev.imubuff_len, rev_s.imubuff, rev_s.imubuff_len);
+			get_game_package(rev_io.imubuff, &rev_io.imubuff_len);
+			rev_io.ts++;
+			rev_io.imubuff[rev_io.imubuff_len + 1] = rev_io.ts;
+			rev_io.imubuff[rev_io.imubuff_len] = rev_io.ts >> 8;
+			if(rev_io.ts%2==0)
+			send_protocol(0, 4, rev_io.imubuff, rev_io.imubuff_len);
+			#endif
+		}
+		else
+		{
+			d_integrate_left_right(rev.imubuff, rev.imubuff_len, rev_s.imubuff, rev_s.imubuff_len);
+			d_get_game_package(rev_io.imubuff, &rev_io.imubuff_len);
+			rev_io.ts++;
+			rev_io.imubuff[rev_io.imubuff_len + 1] = rev_io.ts;
+			rev_io.imubuff[rev_io.imubuff_len] = rev_io.ts >> 8;
+			if(rev_io.ts%2==0)
+			send_protocol(0, 4, rev_io.imubuff, rev_io.imubuff_len);
+		}
+	}
+	else
+	{
+		rev.imubuff[rev.imubuff_len+1]=rev.ts;
+		rev.imubuff[rev.imubuff_len]=rev.ts>>8;
+		send_protocol(0,4,rev.imubuff,rev.imubuff_len+2);
+	}
+}
+
+
+
+
+
+
+
+
+
+

+ 676 - 0
shoe_mcu2.2.1_new_v2/ble_cfg/host.c

@@ -0,0 +1,676 @@
+#include "ble_comm.h"
+#include "app_flash.h"
+#include "system.h"
+
+#if USENAMEFR
+char Target_scan[TARFET_LEN_MAX] = "SH_E9F4";
+#else
+char Target_scan[TARFET_LEN_MAX] = {0x01, 0xf9, 0x84, 0x6a, 0x83, 0xeb};
+#endif
+
+static Ble_receive_handler_t Rec_h = NULL;
+
+#define APP_BLE_OBSERVER_PRIO 3                          /**< BLE observer priority of the application. There is no need to modify this value. */
+#define NUS_SERVICE_UUID_TYPE BLE_UUID_TYPE_VENDOR_BEGIN /**< UUID type for the Nordic UART Service (vendor specific). */
+#define ECHOBACK_BLE_UART_DATA 1                         /**< Echo the UART data that is received over the Nordic UART Service (NUS) back to the sender. */
+BLE_NUS_C_DEF(m_ble_nus_c);                              /**< BLE Nordic UART Service (NUS) client instance. */
+NRF_BLE_GATT_DEF(m_gatt);                                /**< GATT module instance. */
+BLE_DB_DISCOVERY_DEF(m_db_disc);                         /**< Database discovery module instance. */
+NRF_BLE_SCAN_DEF(m_scan);                                /**< Scanning Module instance. */
+NRF_BLE_GQ_DEF(m_ble_gatt_queue,                         /**< BLE GATT Queue instance. */
+               NRF_SDH_BLE_CENTRAL_LINK_COUNT,
+               NRF_BLE_GQ_QUEUE_SIZE);
+static uint16_t m_ble_nus_max_data_len = BLE_GATT_ATT_MTU_DEFAULT - OPCODE_LENGTH - HANDLE_LENGTH; /**< Maximum length of data (in bytes) that can be transmitted to the peer by the Nordic UART service module. */
+unsigned char connect_to_server = 0;
+ble_gap_conn_params_t host_conn_params = {0};
+static void db_disc_handler(ble_db_discovery_evt_t *p_evt)
+{
+    ble_nus_c_on_db_disc_evt(&m_ble_nus_c, p_evt);
+}
+void timer_init(void)
+{
+    ret_code_t err_code = app_timer_init();
+    APP_ERROR_CHECK(err_code);
+}
+static void db_discovery_init(void)
+{
+    ble_db_discovery_init_t db_init;
+
+    memset(&db_init, 0, sizeof(ble_db_discovery_init_t));
+
+    db_init.evt_handler = db_disc_handler;
+    db_init.p_gatt_queue = &m_ble_gatt_queue;
+
+    ret_code_t err_code = ble_db_discovery_init(&db_init);
+    APP_ERROR_CHECK(err_code);
+}
+void power_management_init(void)
+{
+    ret_code_t err_code;
+    err_code = nrf_pwr_mgmt_init();
+    APP_ERROR_CHECK(err_code);
+}
+static void gatt_evt_handler(nrf_ble_gatt_t *p_gatt, nrf_ble_gatt_evt_t const *p_evt)
+{
+    if (p_evt->evt_id == NRF_BLE_GATT_EVT_ATT_MTU_UPDATED)
+    {
+        BLE_PRINT("GATT MTU exchange completed.\r\r\n");
+
+        m_ble_nus_max_data_len = p_evt->params.att_mtu_effective - OPCODE_LENGTH - HANDLE_LENGTH;
+        BLE_PRINT("Ble NUS max data length set to 0x%X(%d)\r\r\n", m_ble_nus_max_data_len, m_ble_nus_max_data_len);
+    }
+}
+void gatt_init(void)
+{
+    ret_code_t err_code;
+
+    err_code = nrf_ble_gatt_init(&m_gatt, gatt_evt_handler);
+    APP_ERROR_CHECK(err_code);
+
+    err_code = nrf_ble_gatt_att_mtu_central_set(&m_gatt, NRF_SDH_BLE_GATT_MAX_MTU_SIZE);
+    APP_ERROR_CHECK(err_code);
+	
+	  err_code = nrf_ble_gatt_att_mtu_periph_set(&m_gatt, NRF_SDH_BLE_GATT_MAX_MTU_SIZE);
+    APP_ERROR_CHECK(err_code);
+}
+
+void scan_start(void)
+{
+  ret_code_t ret;
+
+	if(connect_to_server)return;
+  ret = nrf_ble_scan_start(&m_scan);
+  APP_ERROR_CHECK(ret);
+	BLE_PRINT("scan_start -> scan_name  <%s> \r\n", Target_scan);
+}
+
+
+void ST_scan_stop(void)
+{
+  nrf_ble_scan_stop();
+	BLE_PRINT("ST_scan_stop \r\n");
+}
+
+unsigned int ST_scan_start(void)
+{
+  ret_code_t ret;
+  ret = nrf_ble_scan_start(&m_scan);
+  APP_ERROR_CHECK(ret);
+	BLE_PRINT("ST_scan_start -> scan_name  <%s> \r\n", Target_scan);
+	if(ret != APP_SUCCESS)
+	{
+		return APP_ERROR_RESOURCES;
+	}
+	return APP_SUCCESS;
+}
+
+
+static void ble_nus_c_evt_handler(ble_nus_c_t *p_ble_nus_c, ble_nus_c_evt_t const *p_ble_nus_evt)
+{
+    ret_code_t err_code;
+
+    switch (p_ble_nus_evt->evt_type)
+    {
+    case BLE_NUS_C_EVT_DISCOVERY_COMPLETE:
+        BLE_PRINT("Discovery complete.\r\n");
+        err_code = ble_nus_c_handles_assign(p_ble_nus_c, p_ble_nus_evt->conn_handle, &p_ble_nus_evt->handles);
+        APP_ERROR_CHECK(err_code);
+
+        err_code = ble_nus_c_tx_notif_enable(p_ble_nus_c);
+        APP_ERROR_CHECK(err_code);
+        BLE_PRINT("Connected to device with Nordic UART Service.\r\n");
+        break;
+
+    case BLE_NUS_C_EVT_NUS_TX_EVT: //作为主机接收从机的数据
+        Rec_h(p_ble_nus_evt->p_data, p_ble_nus_evt->data_len);
+        break;
+
+    case BLE_NUS_C_EVT_DISCONNECTED:
+        BLE_PRINT("Disconnected.\r\n");
+#if		DEBUGBLE
+        scan_start();
+#endif
+        break;
+    }
+}
+static void nus_error_handler(uint32_t nrf_error)
+{
+    if (nrf_error == NRF_ERROR_RESOURCES)
+        return;
+		if (nrf_error == NRF_ERROR_INVALID_STATE)
+        return;
+    APP_ERROR_HANDLER(nrf_error);
+}
+static void nus_c_init(void)
+{
+    ret_code_t err_code;
+    ble_nus_c_init_t init;
+
+    init.evt_handler = ble_nus_c_evt_handler;
+    init.error_handler = nus_error_handler;
+    init.p_gatt_queue = &m_ble_gatt_queue;
+
+    err_code = ble_nus_c_init(&m_ble_nus_c, &init);
+    APP_ERROR_CHECK(err_code);
+}
+
+#define host_connected_evt_num_max 3
+static uint8_t host_connected_evt_num = 0;
+static Ble_evt_cb ble_host_connected_evt_cb[host_connected_evt_num_max] = {0};
+int Ble_Host_Connectd_Evt_Regist(Ble_evt_cb cb)
+{
+    for (int i = 0; i < host_connected_evt_num_max; i++)
+    {
+        if (ble_host_connected_evt_cb[i] == cb)
+            return -1;
+        if (ble_host_connected_evt_cb[i] == 0)
+        {
+            host_connected_evt_num++;
+            ble_host_connected_evt_cb[i] = cb; //回调函数
+            return 0;
+        }
+    }
+    DEBUG_LOG( "ble_evt_Regist -> too many!\n");
+    return -2;
+}
+
+void ble_host_connected_evt_pcs(void)
+{
+    for (int i = 0; i < host_connected_evt_num; i++)
+    { //DEBUG_LOG("time_cb[%d]=%d\n",i,time_cb[i]);
+        if (ble_host_connected_evt_cb[i])
+        {
+            ble_host_connected_evt_cb[i](); //回调函数
+        }
+    }
+}
+
+#define host_disconn_evt_num_max 16
+static uint8_t host_disconn_evt_num = 0;
+static Ble_evt_cb ble_Host_disconn_evt_cb[host_disconn_evt_num_max] = {0};
+int Ble_Host_Disconn_Evt_Regist(Ble_evt_cb cb)
+{
+    for (int i = 0; i < host_disconn_evt_num_max; i++)
+    {
+        if (ble_Host_disconn_evt_cb[i] == cb)
+            return -1;
+        if (ble_Host_disconn_evt_cb[i] == 0)
+        {
+            host_disconn_evt_num++;
+            ble_Host_disconn_evt_cb[i] = cb; //回调函数
+            return 0;
+        }
+    }
+    DEBUG_LOG( "Ble_Slave_Disconn_Evt_Regist -> too many!\r\n");
+    return -2;
+}
+
+void ble_host_dicconn_evt_pcs(void)
+{
+    for (int i = 0; i < host_disconn_evt_num; i++)
+    { //DEBUG_LOG("time_cb[%d]=%d\n",i,time_cb[i]);
+        if (ble_Host_disconn_evt_cb[i])
+        {
+            ble_Host_disconn_evt_cb[i](); //回调函数
+        }
+    }
+}
+
+bool advdata_name_find(uint8_t const * p_encoded_data,
+                           uint16_t        data_len,
+                           char    const * p_target_name)
+{
+	return ble_advdata_name_find(p_encoded_data,data_len,p_target_name);
+}
+
+bool advdata_short_name_find(uint8_t const * p_encoded_data,
+                                 uint16_t        data_len,
+                                 char    const * p_target_name,
+                                 uint8_t const   short_name_min_len)
+{
+	return ble_advdata_short_name_find(p_encoded_data,data_len,p_target_name,short_name_min_len);
+}
+
+#if BleNameHoldOn_ENANBLE
+uint8_t SaveFlashFlag_holdOn =0;
+#endif
+
+advdata_rep_handler_t _advdata_rep_callback = NULL;
+void advdata_report_Evt_Regist(advdata_rep_handler_t handler)
+{
+	if(handler==NULL)
+	{
+		BLE_PRINT("advdata_report_Evt_Regist ERROR\r\n"); 
+	}
+	else
+	{
+		BLE_PRINT("advdata_report_Evt_Regist SUCCESS\r\n"); 
+		_advdata_rep_callback=handler;
+	}
+}
+
+static void on_ble_central_evt(ble_evt_t const *p_ble_evt, void *p_context) //作为主设备时的处理
+{
+    ret_code_t err_code;
+    ble_gap_evt_t const *p_gap_evt = &p_ble_evt->evt.gap_evt;
+
+    switch (p_ble_evt->header.evt_id)
+    {
+    case BLE_GAP_EVT_CONNECTED:
+        err_code = ble_nus_c_handles_assign(&m_ble_nus_c, p_ble_evt->evt.gap_evt.conn_handle, NULL);
+        APP_ERROR_CHECK(err_code);
+
+        BLE_PRINT("start discovery services\r\n"); //添加开始发现服务提示
+        connect_to_server = 1;
+        // start discovery of services. The NUS Client waits for a discovery result
+        err_code = ble_db_discovery_start(&m_db_disc, p_ble_evt->evt.gap_evt.conn_handle);
+        APP_ERROR_CHECK(err_code);
+        ble_host_connected_evt_pcs();
+		
+        #if BleNameHoldOn_ENANBLE
+		    if(mFlash.isHost >0){
+						uint8_t i =0;
+						for(i=0;i<6;i++){
+							 if(mFlash.mClient.macAddr[i] != 0xff)break;
+						}
+						if(6 == i){
+							for(i=0;i<6;i++){
+									mFlash.mClient.macAddr[i] = p_ble_evt->evt.gap_evt.params.connected.peer_addr.addr[5-i];
+							}
+							SaveFlashFlag_holdOn = 1;
+						}
+				}
+		    #endif
+				
+        sd_ble_gap_rssi_start(m_ble_nus_c.conn_handle, BLE_GAP_RSSI_THRESHOLD_INVALID, 0);
+        break;
+
+    case BLE_GAP_EVT_DISCONNECTED:
+        connect_to_server = 0;
+        BLE_PRINT("Disconnected. conn_handle: 0x%x, reason: 0x%x",
+                  p_gap_evt->conn_handle,
+                  p_gap_evt->params.disconnected.reason);
+        BLE_PRINT("Disconnected to Server.\r\n");
+        ble_host_dicconn_evt_pcs();
+
+        sd_ble_gap_rssi_stop(m_ble_nus_c.conn_handle);
+        break;
+
+    case BLE_GAP_EVT_TIMEOUT:
+        if (p_gap_evt->params.timeout.src == BLE_GAP_TIMEOUT_SRC_CONN)
+        {
+            BLE_PRINT("Connection Request timed out.\r\n");
+        }
+        break;
+
+    case BLE_GAP_EVT_SEC_PARAMS_REQUEST:
+        // Pairing not supported.
+        err_code = sd_ble_gap_sec_params_reply(p_ble_evt->evt.gap_evt.conn_handle, BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP, NULL, NULL);
+        APP_ERROR_CHECK(err_code);
+        BLE_PRINT("on_ble_central_evt -> BLE_GAP_EVT_SEC_PARAMS_REQUEST\r\n");
+        break;
+
+    case BLE_GAP_EVT_PHY_UPDATE_REQUEST:
+    {
+        BLE_PRINT("Connection 0x%x PHY update request.", p_ble_evt->evt.gap_evt.conn_handle);
+        ble_gap_phys_t const phys =
+            {
+                .rx_phys = BLE_GAP_PHY_AUTO,
+                .tx_phys = BLE_GAP_PHY_AUTO,
+            };
+        err_code = sd_ble_gap_phy_update(p_ble_evt->evt.gap_evt.conn_handle, &phys);
+        APP_ERROR_CHECK(err_code);
+    }
+    break;
+
+    case BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST:
+        // Accepting parameters requested by peer.
+        err_code = sd_ble_gap_conn_param_update(p_gap_evt->conn_handle,
+                                                &p_gap_evt->params.conn_param_update_request.conn_params); //主机接受从机连接参数更新连接参数
+        APP_ERROR_CHECK(err_code);
+        BLE_PRINT("on_ble_central_evt -> BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST\r\n");
+        break;
+
+    case BLE_GAP_EVT_CONN_PARAM_UPDATE:
+			
+        BLE_PRINT("on_ble_central_evt -> BLE_GAP_EVT_CONN_PARAM_UPDATE\r\n");
+        memcpy(&host_conn_params, &p_gap_evt->params.conn_param_update_request.conn_params, sizeof(ble_gap_conn_params_t));
+        BLE_PRINT("min_conn_interval : %d * 1.25 ms\r\n", p_gap_evt->params.conn_param_update_request.conn_params.min_conn_interval);
+        BLE_PRINT("max_conn_interval : %d * 1.25 ms\r\n", p_gap_evt->params.conn_param_update_request.conn_params.max_conn_interval);
+        BLE_PRINT("slave_latency     : %d\r\n", p_gap_evt->params.conn_param_update_request.conn_params.slave_latency);
+        BLE_PRINT("conn_sup_timeout  : %d * 10   ms\r\n", p_gap_evt->params.conn_param_update_request.conn_params.conn_sup_timeout);
+        break;
+
+    case BLE_GATTC_EVT_TIMEOUT:
+        // Disconnect on GATT Client timeout event.
+        BLE_PRINT("GATT Client Timeout.\r\n");
+        err_code = sd_ble_gap_disconnect(p_ble_evt->evt.gattc_evt.conn_handle,
+                                         BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
+        APP_ERROR_CHECK(err_code);
+        break;
+
+    case BLE_GATTS_EVT_TIMEOUT:
+        // Disconnect on GATT Server timeout event.
+        BLE_PRINT("GATT Server Timeout.\r\n");
+        err_code = sd_ble_gap_disconnect(p_ble_evt->evt.gatts_evt.conn_handle,
+                                         BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
+        APP_ERROR_CHECK(err_code);
+        break;
+		
+		case BLE_GAP_EVT_ADV_REPORT:
+				{					
+					if(p_gap_evt->params.adv_report.type.scan_response == 0)
+					{
+						if(_advdata_rep_callback != NULL)
+						{
+							_advdata_rep_callback(p_gap_evt->params.adv_report.data.p_data , p_gap_evt->params.adv_report.data.len ,p_gap_evt->params.adv_report.rssi);
+						}
+//						unsigned short parsed_name_len;
+//						uint16_t offset = 0;
+//						parsed_name_len = ble_advdata_search(p_gap_evt->params.adv_report.data.p_data,p_gap_evt->params.adv_report.data.len,&offset,BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME);
+//						if(parsed_name_len>0)
+//						{
+//							printf( " RSSI:%d \tNAME :",p_gap_evt->params.adv_report.rssi);
+//							for(int k=0;k<parsed_name_len;k++)
+//							{
+//								printf( "%c" ,p_gap_evt->params.adv_report.data.p_data[k+offset] );
+//							}
+//							printf( "\r\n");
+//						}		
+							
+					}
+				}
+			break;
+
+    default:
+        break;
+    }
+}
+extern bool ble_evt_is_advertising_timeout(ble_evt_t const *p_ble_evt);
+extern void on_ble_peripheral_evt(ble_evt_t const *p_ble_evt); //作为从设备的处理
+static void ble_evt_handler(ble_evt_t const *p_ble_evt, void *p_context)
+{
+    uint16_t conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
+    uint16_t role = ble_conn_state_role(conn_handle);
+
+    // Based on the role this device plays in the connection, dispatch to the right handler.不同角色下所做的处理
+    if (role == BLE_GAP_ROLE_PERIPH || ble_evt_is_advertising_timeout(p_ble_evt))
+    {
+        //			  ble_nus_on_ble_evt(p_ble_evt, &m_nus);
+        on_ble_peripheral_evt(p_ble_evt);
+    }
+    else if ((role == BLE_GAP_ROLE_CENTRAL) || (p_ble_evt->header.evt_id == BLE_GAP_EVT_ADV_REPORT))
+    {
+        //        ble_nus_c_on_ble_evt(p_ble_evt, &m_ble_nus_c);
+        on_ble_central_evt(p_ble_evt, NULL);
+    }
+    else
+    {
+        BLE_PRINT("ble_evt_handler -> other\r\n");
+    }
+}
+void ble_stack_init(void)
+{
+    ret_code_t err_code;
+
+    err_code = nrf_sdh_enable_request();
+    APP_ERROR_CHECK(err_code);
+
+    // Configure the BLE stack using the default settings.
+    // Fetch the start address of the application RAM.
+    uint32_t ram_start = 0;
+    err_code = nrf_sdh_ble_default_cfg_set(APP_BLE_CONN_CFG_TAG, &ram_start);
+    APP_ERROR_CHECK(err_code);
+
+    // Enable BLE stack.
+    err_code = nrf_sdh_ble_enable(&ram_start);
+    APP_ERROR_CHECK(err_code);
+
+    // Register a handler for BLE events.
+    NRF_SDH_BLE_OBSERVER(m_ble_observer, APP_BLE_OBSERVER_PRIO, ble_evt_handler, NULL);
+}
+#define PRINT_MAC 0
+/**@brief Function for handling Scanning Module events.
+ */
+static void scan_evt_handler(scan_evt_t const *p_scan_evt)
+{
+    ret_code_t err_code;
+
+    switch (p_scan_evt->scan_evt_id)
+    {
+    case NRF_BLE_SCAN_EVT_CONNECTING_ERROR:
+    {
+        err_code = p_scan_evt->params.connecting_err.err_code;
+//        APP_ERROR_CHECK(err_code);
+        BLE_PRINT("scan_evt_handler -> NRF_BLE_SCAN_EVT_CONNECTING_ERROR \r\n");
+    }
+    break;
+
+    case NRF_BLE_SCAN_EVT_CONNECTED:
+    {
+        BLE_PRINT("scan_evt_handler -> NRF_BLE_SCAN_EVT_CONNECTED\r\n");
+#if PRINT_MAC
+        ble_gap_evt_connected_t const *p_connected =
+            p_scan_evt->params.connected.p_connected;
+        // Scan is automatically stopped by the connection.
+        BLE_PRINT("Connecting to Host %02x%02x %02x%02x %02x%02x\r\r\n",
+                  p_connected->peer_addr.addr[0],
+                  p_connected->peer_addr.addr[1],
+                  p_connected->peer_addr.addr[2],
+                  p_connected->peer_addr.addr[3],
+                  p_connected->peer_addr.addr[4],
+                  p_connected->peer_addr.addr[5]);
+#endif
+    }
+    break;
+
+    case NRF_BLE_SCAN_EVT_SCAN_TIMEOUT:
+    {
+        BLE_PRINT("scan_evt_handler -> NRF_BLE_SCAN_EVT_SCAN_TIMEOUT -> Scan timed out.\r\n");
+        scan_start();
+    }
+    break;
+
+    case NRF_BLE_SCAN_EVT_FILTER_MATCH:
+    {
+        BLE_PRINT("scan_evt_handler -> NRF_BLE_SCAN_EVT_FILTER_MATCH\r\n");
+    }
+    break;
+
+    case NRF_BLE_SCAN_EVT_WHITELIST_REQUEST:
+    {
+        BLE_PRINT("scan_evt_handler -> NRF_BLE_SCAN_EVT_WHITELIST_REQUEST\r\n");
+    }
+    break;
+
+    case NRF_BLE_SCAN_EVT_WHITELIST_ADV_REPORT:
+    {
+        BLE_PRINT("scan_evt_handler -> NRF_BLE_SCAN_EVT_WHITELIST_ADV_REPORT\r\n");
+    }
+    break;
+
+    case NRF_BLE_SCAN_EVT_NOT_FOUND:
+    {
+        //						 BLE_PRINT("scan_evt_handler -> NRF_BLE_SCAN_EVT_NOT_FOUND");
+    }
+    break;
+
+    default:
+        BLE_PRINT("scan_evt_handler -> default:%d \r\n", p_scan_evt->scan_evt_id);
+        break;
+    }
+}
+
+unsigned int send_bytes_server(uint8_t *bytes, uint16_t len)
+{
+    if (connect_to_server == 0)
+    {
+        BLE_PRINT("send_bytes_server -> APP_ERR_DISCONN\r\n");
+        return APP_ERR_DISCONN;
+    }
+    if (len > m_ble_nus_max_data_len)
+    {
+        BLE_PRINT("send_bytes_server -> fail ->overlength\r\n");
+        return APP_ERR_OVERLENGTH;
+    }
+    if (NRF_SUCCESS != ble_nus_c_string_send(&m_ble_nus_c, bytes, len))
+    {
+        BLE_PRINT("send_bytes_server -> fail\r\n");
+    }
+    return APP_SUCCESS;
+}
+
+static void scan_init(void)
+{
+    ret_code_t err_code;
+    nrf_ble_scan_init_t init_scan;
+
+    memset(&init_scan, 0, sizeof(init_scan));
+
+    init_scan.connect_if_match = true;
+    init_scan.conn_cfg_tag = APP_BLE_CONN_CFG_TAG;
+
+    err_code = nrf_ble_scan_init(&m_scan, &init_scan, scan_evt_handler);
+    APP_ERROR_CHECK(err_code);
+
+#if USENAMEFR
+    err_code = nrf_ble_scan_filter_set(&m_scan, SCAN_NAME_FILTER, &Target_scan);
+    APP_ERROR_CHECK(err_code);
+
+    err_code = nrf_ble_scan_filters_enable(&m_scan, NRF_BLE_SCAN_NAME_FILTER, false);
+    APP_ERROR_CHECK(err_code);
+    BLE_PRINT("scan_init -> scan_name  <%s> \r\n", Target_scan);
+#else
+    err_code = nrf_ble_scan_filter_set(&m_scan, SCAN_ADDR_FILTER, &Target_scan);
+    APP_ERROR_CHECK(err_code);
+
+    err_code = nrf_ble_scan_filters_enable(&m_scan, NRF_BLE_SCAN_ADDR_FILTER, false);
+    APP_ERROR_CHECK(err_code);
+
+    BLE_PRINT("scan_start -> scan_MAC [ %02X %02X %02X %02X %02X %02X ]\r\n", Target_scan[0], Target_scan[1], Target_scan[2], Target_scan[3], Target_scan[4], Target_scan[5]);
+
+#endif
+}
+
+unsigned char host_isconnect(void)
+{
+    return connect_to_server;
+}
+char ble_stack_init_sta = 1;
+char host_init_sta = 0;
+void host_init(Ble_receive_handler_t receive_handler)
+{
+    if (receive_handler == NULL)
+    {
+        BLE_PRINT("host_init -> param err \r\n");
+        return;
+    }
+    Rec_h = receive_handler;
+    if (ble_stack_init_sta)
+    {
+        timer_init();            //
+        power_management_init(); //
+        ble_stack_init();        //
+        gatt_init();             //
+        ble_stack_init_sta = 0;
+    }
+
+    db_discovery_init();
+    nus_c_init();
+
+    scan_init();
+		host_init_sta=1;
+}
+
+void err(int err_num)
+{
+    BLE_PRINT("APP ERROR -> %d \r\n", err_num);
+}
+
+unsigned int host_set_scan_name(char *name, int len)
+{
+	unsigned int err_code;
+    if (len > TARFET_LEN_MAX)
+        return APP_ERR_OVERLENGTH;
+		if(connect_to_server)
+				return APP_ERR_CONNECTED;
+		memset(Target_scan, 0, TARFET_LEN_MAX);
+		if(host_init_sta)
+		{
+			memcpy(Target_scan, name, len);
+					err_code =nrf_ble_scan_all_filter_remove(&m_scan);
+					APP_ERROR_CHECK(err_code);
+			#if USENAMEFR
+					err_code = nrf_ble_scan_filter_set(&m_scan, SCAN_NAME_FILTER, &Target_scan);
+					APP_ERROR_CHECK(err_code);
+
+					err_code = nrf_ble_scan_filters_enable(&m_scan, NRF_BLE_SCAN_NAME_FILTER, false);
+					APP_ERROR_CHECK(err_code);
+					BLE_PRINT("host_set_scan_name -> scan_name  <%s> \r\n", Target_scan);
+			#else
+					err_code = nrf_ble_scan_filter_set(&m_scan, SCAN_ADDR_FILTER, &Target_scan);
+					APP_ERROR_CHECK(err_code);
+
+					err_code = nrf_ble_scan_filters_enable(&m_scan, NRF_BLE_SCAN_ADDR_FILTER, false);
+					APP_ERROR_CHECK(err_code);
+
+					BLE_PRINT("host_set_scan_name -> scan_MAC [ %02X %02X %02X %02X %02X %02X ]\r\n", Target_scan[0], Target_scan[1], Target_scan[2], Target_scan[3], Target_scan[4], Target_scan[5]);
+
+			#endif
+		}
+		else
+		{
+			memcpy(Target_scan, name, len);
+		}
+    return APP_SUCCESS;
+}
+
+unsigned int Ble_update_conn_interval(float min_conn_interval, float max_conn_interval)
+{
+    ret_code_t err_code;
+    ble_gap_conn_params_t bgcp;
+    //主机接受从机连接参数更新连接参数
+	
+    if (connect_to_server)
+    {	
+				if ((max_conn_interval > 1.25 * 1599) || (max_conn_interval < min_conn_interval))
+						return APP_ERR_PARAMERR;
+				if (min_conn_interval < 7.5f)
+						return APP_ERR_PARAMERR;
+				bgcp.max_conn_interval = MSEC_TO_UNITS(max_conn_interval, UNIT_1_25_MS);
+				bgcp.min_conn_interval = MSEC_TO_UNITS(min_conn_interval, UNIT_1_25_MS);
+				bgcp.conn_sup_timeout = MSEC_TO_UNITS(4000, UNIT_10_MS);
+				bgcp.slave_latency = 0;
+				
+        err_code = sd_ble_gap_conn_param_update(m_ble_nus_c.conn_handle, &bgcp);
+				if(err_code != NRF_ERROR_INVALID_STATE && err_code != NRF_ERROR_BUSY && err_code != NRF_SUCCESS){
+					APP_ERROR_CHECK(err_code);
+				}
+        return err_code;
+    }
+    else
+    {
+        return APP_ERR_DISCONN;
+    }
+}
+
+void host_disconnect(void)
+{
+    if (connect_to_server)
+        sd_ble_gap_disconnect(m_ble_nus_c.conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
+}
+void host_get_conn_params(ble_gap_conn_params_t *p)
+{
+    memcpy(p, &host_conn_params, sizeof(ble_gap_conn_params_t));
+}
+static signed char rssi = 0;
+signed char host_get_rssi(void)
+{
+    unsigned char channel;
+    if (connect_to_server == 0)
+        return 1;
+    sd_ble_gap_rssi_get(m_ble_nus_c.conn_handle, &rssi, &channel);
+    ///BLE_PRINT("rssi= %d  channel=%d\r\n", rssi, channel);
+    return rssi;
+}
+

+ 46 - 0
shoe_mcu2.2.1_new_v2/ble_cfg/queue.c

@@ -0,0 +1,46 @@
+#include "queue.h"
+
+
+unsigned short queue_in(queue_t * p_queue, void const * p_element)
+{
+	unsigned char * p = (unsigned char*)p_queue->p_buffer + ((p_queue->front & (p_queue->size-1))*(p_queue->element_size));
+	if(p_queue->element_count>=p_queue->size)return 0;
+	for(int i=0;i<p_queue->element_size;i++)
+	{
+		p[i]=((unsigned char*)(void*)p_element)[i];
+	}
+	p_queue->front++;
+	p_queue->element_count++;
+	return 1;
+}
+
+unsigned short queue_out(queue_t * p_queue, void * p_element)
+{
+	unsigned char * p = (unsigned char*)p_queue->p_buffer + ((p_queue->back & (p_queue->size-1))*(p_queue->element_size));
+	if(p_queue->element_count<1)return 0;
+	for(int i=0;i<p_queue->element_size;i++)
+	{
+		((unsigned char*)(void*)p_element)[i]=p[i];
+	}
+	p_queue->back++;
+	p_queue->element_count--;
+	return 1;
+}
+
+unsigned short queue_peek(queue_t * p_queue, void * p_element)
+{
+	unsigned char * p = (unsigned char*)p_queue->p_buffer + ((p_queue->back & (p_queue->size-1))*(p_queue->element_size));
+	if(p_queue->element_count<1)return 0;
+	for(int i=0;i<p_queue->element_size;i++)
+	{
+		((unsigned char*)(void*)p_element)[i]=p[i];
+	}
+	return 1;
+}
+
+void queue_reset(queue_t * p_queue)
+{
+	p_queue->back=0;
+	p_queue->front=0;              
+	p_queue->element_count=0;																		
+}

+ 76 - 0
shoe_mcu2.2.1_new_v2/ble_cfg/queue.h

@@ -0,0 +1,76 @@
+#ifndef __QUEUE_H
+#define __QUEUE_H
+
+/**@brief   队列模式类型
+ * @details 
+ *          Also, it keeps the information about which memory is allocated for the buffer
+ *          and its size. This structure must be initialized by app_fifo_init() before use.
+ */
+typedef enum
+{
+    QUEUE_MODE_OVERFLOW,        //!< If the queue is full, new element will overwrite the oldest.
+    QUEUE_MODE_NO_OVERFLOW,     //!< If the queue is full, new element will not be accepted.
+} queue_mode_t;
+/**@brief   A FIFO instance structure.
+ * @details Keeps track of which bytes to read and write next.
+ *          Also, it keeps the information about which memory is allocated for the buffer
+ *          and its size. This structure must be initialized by app_fifo_init() before use.
+ */
+typedef enum
+{
+	size_4 		  = 0x0004U,
+	size_8 		  = 0x0008U,
+	size_16 		= 0x0010U,								 	                            
+	size_32 		= 0x0020U,
+	size_64 		= 0x0040U,
+	size_128 		= 0x0080U,
+  size_256 		= 0x0100U,         
+	size_512 		= 0x0200U,
+	size_1024 	= 0x0400U,
+	size_2048 	= 0x0800U,
+	size_4096 	= 0x1000U,
+	size_8192 	= 0x2000U,
+	size_16384	= 0x4000U,
+	size_32768	= 0x8000U,
+} queue_size_t;
+
+typedef struct
+{
+  volatile unsigned short front;          //!< Queue front index.
+  volatile unsigned short back;           //!< Queue back index.
+	void           		* p_buffer;          //!< Pointer to the memory that is used as storage.
+	queue_size_t  		size;              //!< Size of the queue.
+	unsigned short    element_count;
+	unsigned short  	element_size;      //!< Size of one element.
+	queue_mode_t      mode;
+} queue_t;
+
+/******************************API 接口*************************************/
+#define QUEUE_DEF(element_type, _name, _size, _mode)        \
+				element_type   _name##_queue_buffer[(_size)];      	\
+				queue_t _name=                             					\
+								{                             							\
+									.front 					= 0,              				\
+									.back 					= 0,                    	\
+									.p_buffer 			= _name##_queue_buffer,   \
+									.size  					= (_size),          			\
+									.element_count	= 0,											\
+									.element_size   = sizeof(element_type),   \
+									.mode           = _mode,       						\
+								}    
+
+//元素进队列
+unsigned short queue_in(queue_t * p_queue, void const * p_element);
+//元素出队列
+unsigned short queue_out(queue_t * p_queue, void * p_element);
+//查看队列中最后一个元素,队列中元素并没有减少
+unsigned short queue_peek(queue_t * p_queue, void * p_element);
+//清空队列
+void queue_reset(queue_t * p_queue);	
+//获取队列中元素个数
+unsigned short queue_element_count(queue_t * p_queue);	
+//查看队列中指定数组下标的元素的从最早进入队列的元素下标index==0开始算								
+unsigned short queue_read(queue_t * p_queue, void * p_element ,int index);		
+//扔掉掉列最后一个元素								
+unsigned short queue_throw_element(queue_t * p_queue);
+#endif 

+ 82 - 0
shoe_mcu2.2.1_new_v2/ble_cfg/ringframe.c

@@ -0,0 +1,82 @@
+#include "ringframe.h"
+
+unsigned short ringframe_in(ringframe_t * p_ringframe, void * p_data,unsigned char data_size)
+{
+		unsigned char * p;
+		if(p_ringframe->freespace < ( data_size + 1 ))return 1;
+		p = (unsigned char*)p_ringframe->p_buffer + p_ringframe->front ;        
+		* p=data_size;
+		p_ringframe->front++;
+		p_ringframe->front &= p_ringframe->size-1;
+		for(int i=0;i<data_size;i++)
+		{
+						p = (unsigned char*)p_ringframe->p_buffer + p_ringframe->front ;
+						* p=((unsigned char*)p_data)[i];
+						p_ringframe->front++;
+						p_ringframe->front &= p_ringframe->size-1;
+		}
+		p_ringframe->freespace -= (data_size+1);
+		p_ringframe->element_count++;
+		return 0;
+}
+
+unsigned short ringframe_out(ringframe_t * p_ringframe, void * p_data,unsigned char * data_size)
+{
+	unsigned char * p;
+	if(p_ringframe->element_count < 1)return 1;
+	p = (unsigned char*)p_ringframe->p_buffer + p_ringframe->back ;	
+	* data_size = * p;
+	p_ringframe->back++;
+	p_ringframe->back &= p_ringframe->size-1;
+	for(int i=0;i < *data_size;i++)
+	{
+		p = (unsigned char*)p_ringframe->p_buffer + p_ringframe->back ;
+		((unsigned char*)p_data)[i]= * p;
+		p_ringframe->back++;
+		p_ringframe->back &= p_ringframe->size-1;
+	}
+	p_ringframe->freespace += (* data_size+1);
+	p_ringframe->element_count--;
+	return 0;
+}
+
+unsigned short ringframe_peek(ringframe_t * p_ringframe, void * p_data,unsigned char * data_size)
+{
+	unsigned char * p;
+	unsigned short temp = p_ringframe->back;
+	if(p_ringframe->element_count < 1)return 1;
+	p = (unsigned char*)p_ringframe->p_buffer + temp ;	
+	* data_size = * p;
+	temp++;
+	temp &= p_ringframe->size-1;
+	for(int i=0;i < *data_size;i++)
+	{
+		p = (unsigned char*)p_ringframe->p_buffer + temp ;
+		((unsigned char*)p_data)[i]= * p;
+		temp++;
+		temp &= p_ringframe->size-1;
+	}
+	return 0;
+}
+
+unsigned short ringframe_throw(ringframe_t * p_ringframe)
+{
+	unsigned char * p;
+	if(p_ringframe->element_count < 1)return 1;
+	p = (unsigned char*)p_ringframe->p_buffer + p_ringframe->back ;	
+	p_ringframe->back = p_ringframe->back + * p + 1;
+	p_ringframe->back &= p_ringframe->size-1;
+	p_ringframe->freespace += (* p +1);
+	p_ringframe->element_count--;
+	return 0;
+}
+
+void ringframe_reset(ringframe_t * p_ringframe)
+{
+	p_ringframe->back=0;
+	p_ringframe->front=0;              
+	p_ringframe->element_count=0;	
+	p_ringframe->freespace =	p_ringframe->size -1;
+}
+
+

+ 62 - 0
shoe_mcu2.2.1_new_v2/ble_cfg/ringframe.h

@@ -0,0 +1,62 @@
+#ifndef __RINGFRAME_H
+#define __RINGFRAME_H
+
+/**@brief   A FIFO instance structure.
+ * @details Keeps track of which bytes to read and write next.
+ *          Also, it keeps the information about which memory is allocated for the buffer
+ *          and its size. This structure must be initialized by app_fifo_init() before use.
+ */
+typedef enum
+{
+	ringframe_size_4 		  = 0x0004U,
+	ringframe_size_8 		  = 0x0008U,
+	ringframe_size_16 		= 0x0010U,								 	                            
+	ringframe_size_32 		= 0x0020U,
+	ringframe_size_64 		= 0x0040U,
+	ringframe_size_128 		= 0x0080U,
+  ringframe_size_256 		= 0x0100U,         
+	ringframe_size_512 		= 0x0200U,
+	ringframe_size_1024 	= 0x0400U,
+	ringframe_size_2048 	= 0x0800U,
+	ringframe_size_4096 	= 0x1000U,
+	ringframe_size_8192 	= 0x2000U,
+	ringframe_size_16384	= 0x4000U,
+	ringframe_size_32768	= 0x8000U,
+}ringframe_size_t;
+
+typedef struct
+{
+  volatile unsigned short front;          //!< ringframe front index.
+  volatile unsigned short back;           //!< ringframe back index.
+	void           		* p_buffer;          //!< Pointer to the memory that is used as storage.
+	ringframe_size_t  size;									//单位为字节
+	unsigned short    element_count;
+	unsigned short 		freespace;
+} ringframe_t;
+
+/******************************API 接口*************************************/
+#define RINGFRAME_DEF( _name, _size)        								  \
+				unsigned char   _name##_ringframe_buffer[(_size)];    \
+				ringframe_t _name=                             			  \
+								{                             							  \
+									.front 					= 0,              				  \
+									.back 					= 0,                    	  \
+									.p_buffer 			= _name##_ringframe_buffer, \
+									.size  					= (_size),          			  \
+									.element_count	= 0,											  \
+									.freespace      = (_size)-1,       				  \
+								}    
+
+//返回0表示操作成功,否则失败
+unsigned short ringframe_in(ringframe_t * p_ringframe, void * p_data,unsigned char data_size);
+//返回0表示操作成功,否则失败								
+unsigned short ringframe_out(ringframe_t * p_ringframe, void * p_data,unsigned char * data_size);
+								
+void ringframe_reset(ringframe_t * p_ringframe);
+//返回0表示操作成功,否则失败																	
+unsigned short ringframe_peek(ringframe_t * p_ringframe, void * p_data,unsigned char * data_size);
+//返回0表示操作成功,否则失败									
+unsigned short ringframe_throw(ringframe_t * p_ringframe);
+								
+								
+#endif 

+ 1634 - 0
shoe_mcu2.2.1_new_v2/ble_cfg/slave.c

@@ -0,0 +1,1634 @@
+#include "ble_comm.h"
+
+#include "ble_advertising.h"
+#include "ble_conn_params.h"
+#include "nrf_ble_qwr.h"
+
+#include "nrf_fstorage.h"
+#include "nrf_soc.h"
+#include "ble_nus.h"
+
+#include "bsp_time.h"
+#include "system.h"
+#include "app_flash.h"
+
+// <<< Use Configuration Wizard in Context Menu >>>\r\n
+
+#define APP_ADV_INTERVAL 320                                 /**< The advertising interval (in units of 0.625 ms). This value corresponds to 187.5 ms. */
+#define APP_ADV_DURATION 18000                               /**< The advertising duration (180 seconds) in units of 10 milliseconds. */
+#define FIRST_CONN_PARAMS_UPDATE_DELAY APP_TIMER_TICKS(1000) /**< Time from initiating event (connect or start of notification) to first time sd_ble_gap_conn_param_update is called (5 seconds). */
+#define NEXT_CONN_PARAMS_UPDATE_DELAY APP_TIMER_TICKS(5000)  /**< Time between each call to sd_ble_gap_conn_param_update after the first call (30 seconds). */
+#define MAX_CONN_PARAMS_UPDATE_COUNT 1
+static char DEVICE_NAME[TARFET_LEN_MAX] = "SH";
+#if USE_LADDR == 1
+char BleReallyName[TARFET_LEN_MAX] = {0};
+#endif
+#define MIN_CONN_INTERVAL MSEC_TO_UNITS(7.5, UNIT_1_25_MS)         /**< Minimum acceptable connection interval (20 ms), Connection interval uses 1.25 ms units. */
+#define MAX_CONN_INTERVAL MSEC_TO_UNITS(1.25 * 1599, UNIT_1_25_MS) /**< Maximum acceptable connection interval (75 ms), Connection interval uses 1.25 ms units. */
+#define SLAVE_LATENCY 0                                            /**< Slave latency. */
+#define CONN_SUP_TIMEOUT MSEC_TO_UNITS(4000, UNIT_10_MS)
+#define NUS_SERVICE_UUID_TYPE BLE_UUID_TYPE_VENDOR_BEGIN
+static ble_uuid_t m_adv_uuids[] =
+    {
+        {BLE_UUID_NUS_SERVICE, NUS_SERVICE_UUID_TYPE}};
+static unsigned char connect_to_client = 0;
+static Ble_receive_handler_t Rec_h = NULL;
+BLE_NUS_DEF(m_nus, NRF_SDH_BLE_TOTAL_LINK_COUNT);
+BLE_ADVERTISING_DEF(m_advertising);
+NRF_BLE_QWRS_DEF(m_qwr, NRF_SDH_BLE_TOTAL_LINK_COUNT);
+uint16_t m_conn_handle = BLE_CONN_HANDLE_INVALID;
+
+ble_gap_conn_params_t slave_conn_params = {0};
+
+static void nrf_qwr_error_handler(uint32_t nrf_error) //?óáDD′′í?ó2ù×÷
+{
+    APP_ERROR_HANDLER(nrf_error);
+}
+//′ó BLE ?óêüêy?Y
+static void nus_data_handler(ble_nus_evt_t *p_evt)
+{
+    if (p_evt->type == BLE_NUS_EVT_RX_DATA)
+    {
+        Rec_h((unsigned char *)(p_evt->params.rx_data.p_data), p_evt->params.rx_data.length);
+    }
+}
+static void services_init(void) //·t??3?ê??ˉ
+{
+    uint32_t err_code;
+    ble_nus_init_t nus_init;
+    nrf_ble_qwr_init_t qwr_init = {0};
+
+    // Initialize Queued Write Module.
+    qwr_init.error_handler = nrf_qwr_error_handler;
+
+    for (uint32_t i = 0; i < NRF_SDH_BLE_TOTAL_LINK_COUNT; i++)
+    {
+        err_code = nrf_ble_qwr_init(&m_qwr[i], &qwr_init);
+        APP_ERROR_CHECK(err_code);
+    }
+
+    // Initialize NUS.
+    memset(&nus_init, 0, sizeof(nus_init));
+
+    nus_init.data_handler = nus_data_handler;
+
+    err_code = ble_nus_init(&m_nus, &nus_init);
+    APP_ERROR_CHECK(err_code);
+}
+static void on_adv_evt(ble_adv_evt_t ble_adv_evt) //1?2¥ê??t
+{
+    switch (ble_adv_evt)
+    {
+    case BLE_ADV_EVT_FAST:
+    {
+        BLE_PRINT("Fast advertising.\r\n");
+    }
+    break;
+
+    case BLE_ADV_EVT_IDLE:
+    {
+        BLE_PRINT("on_adv_evt->BLE_ADV_EVT_IDLE\r\n");
+        ret_code_t err_code = ble_advertising_start(&m_advertising, BLE_ADV_MODE_FAST); //?aê?1?2¥
+        APP_ERROR_CHECK(err_code);
+    }
+    break;
+
+    default:
+        // No implementation needed.
+        break;
+    }
+}
+static void advertising_init(void)
+{
+    uint32_t err_code;
+    ble_advertising_init_t init;
+    int8_t txpower = 4;
+
+    memset(&init, 0, sizeof(init));
+
+    init.advdata.name_type = BLE_ADVDATA_FULL_NAME;
+    init.advdata.include_appearance = false;
+    init.advdata.flags = BLE_GAP_ADV_FLAGS_LE_ONLY_LIMITED_DISC_MODE;
+    init.advdata.p_tx_power_level = &txpower;
+
+    init.srdata.uuids_complete.uuid_cnt = sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]);
+    init.srdata.uuids_complete.p_uuids = m_adv_uuids;
+
+    init.config.ble_adv_fast_enabled = true;
+    init.config.ble_adv_fast_interval = APP_ADV_INTERVAL;
+    init.config.ble_adv_fast_timeout = APP_ADV_DURATION;
+    init.evt_handler = on_adv_evt;
+
+    err_code = ble_advertising_init(&m_advertising, &init);
+    APP_ERROR_CHECK(err_code);
+
+    ble_advertising_conn_cfg_tag_set(&m_advertising, APP_BLE_CONN_CFG_TAG);
+}
+static void conn_params_error_handler(uint32_t nrf_error)
+{
+    APP_ERROR_HANDLER(nrf_error);
+}
+static void conn_params_init(void)
+{
+    ret_code_t err_code;
+    ble_conn_params_init_t cp_init;
+
+    memset(&cp_init, 0, sizeof(cp_init));
+
+    cp_init.p_conn_params = NULL;
+    cp_init.first_conn_params_update_delay = FIRST_CONN_PARAMS_UPDATE_DELAY;
+    cp_init.next_conn_params_update_delay = NEXT_CONN_PARAMS_UPDATE_DELAY;
+    cp_init.max_conn_params_update_count = MAX_CONN_PARAMS_UPDATE_COUNT;
+    cp_init.start_on_notify_cccd_handle = BLE_CONN_HANDLE_INVALID; // Start upon connection.
+    cp_init.disconnect_on_fail = true;
+    cp_init.evt_handler = NULL; // Ignore events.
+    cp_init.error_handler = conn_params_error_handler;
+
+    err_code = ble_conn_params_init(&cp_init);
+    APP_ERROR_CHECK(err_code);
+}
+void advertising_start(void)
+{
+    ret_code_t err_code;
+    err_code = ble_advertising_start(&m_advertising, BLE_ADV_MODE_FAST); //同时开始广播
+	  DEBUG_LOG("advertising_start !\r\n");
+    if(NRF_ERROR_INVALID_STATE != err_code){
+			APP_ERROR_CHECK(err_code);
+		}
+}
+void advertising_stop(void)
+{
+    ret_code_t err_code;
+    err_code = sd_ble_gap_adv_stop(m_advertising.adv_handle); //停止广播
+	  DEBUG_LOG("advertising_stop !\r\n");
+    if(NRF_ERROR_INVALID_STATE != err_code){
+			APP_ERROR_CHECK(err_code);
+		}
+}
+bool ble_evt_is_advertising_timeout(ble_evt_t const *p_ble_evt)
+{
+    return (p_ble_evt->header.evt_id == BLE_GAP_EVT_ADV_SET_TERMINATED);
+}
+static void multi_qwr_conn_handle_assign(uint16_t conn_handle)
+{
+    for (uint32_t i = 0; i < NRF_SDH_BLE_TOTAL_LINK_COUNT; i++)
+    {
+        if (m_qwr[i].conn_handle == BLE_CONN_HANDLE_INVALID)
+        {
+            ret_code_t err_code = nrf_ble_qwr_conn_handle_assign(&m_qwr[i], conn_handle);
+            APP_ERROR_CHECK(err_code);
+            break;
+        }
+    }
+}
+
+#define slave_connected_evt_num_max 16
+static uint8_t slave_connected_evt_num = 0;
+static Ble_evt_cb ble_Slave_evt_cb[slave_connected_evt_num_max] = {0};
+int Ble_Slave_Connectd_Evt_Regist(Ble_evt_cb cb)
+{
+    for (int i = 0; i < slave_connected_evt_num_max; i++)
+    {
+        if (ble_Slave_evt_cb[i] == cb)
+            return -1;
+        if (ble_Slave_evt_cb[i] == 0)
+        {
+            slave_connected_evt_num++;
+            ble_Slave_evt_cb[i] = cb; //??μ÷oˉêy
+            return 0;
+        }
+    }
+    DEBUG_LOG( "ble_evt_Regist -> too many!\n");
+    return -2;
+}
+
+void ble_slave_connected_evt_pcs(void)
+{
+    for (int i = 0; i < slave_connected_evt_num; i++)
+    { //DEBUG_LOG("time_cb[%d]=%d\n",i,time_cb[i]);
+        if (ble_Slave_evt_cb[i])
+        {
+            ble_Slave_evt_cb[i](); //??μ÷oˉêy
+        }
+    }
+}
+
+#define slave_disconn_evt_num_max 16
+static uint8_t slave_disconn_evt_num = 0;
+static Ble_evt_cb ble_Slave_disconn_evt_cb[slave_disconn_evt_num_max] = {0};
+int Ble_Slave_Disconn_Evt_Regist(Ble_evt_cb cb)
+{
+    for (int i = 0; i < slave_disconn_evt_num_max; i++)
+    {
+        if (ble_Slave_disconn_evt_cb[i] == cb)
+            return -1;
+        if (ble_Slave_disconn_evt_cb[i] == 0)
+        {
+            slave_disconn_evt_num++;
+            ble_Slave_disconn_evt_cb[i] = cb; //??μ÷oˉêy
+            return 0;
+        }
+    }
+    DEBUG_LOG( "Ble_Slave_Disconn_Evt_Regist -> too many!\r\n");
+    return -2;
+}
+
+void ble_slave_dicconn_evt_pcs(void)
+{
+    for (int i = 0; i < slave_disconn_evt_num; i++)
+    { //DEBUG_LOG("time_cb[%d]=%d\n",i,time_cb[i]);
+        if (ble_Slave_disconn_evt_cb[i])
+        {
+            ble_Slave_disconn_evt_cb[i](); //??μ÷oˉêy
+        }
+    }
+}
+unsigned char slave_update_conn_interval_request_sta = 0;
+static ble_gap_phys_t const phys =
+{
+		.rx_phys = BLE_GAP_PHY_1MBPS,
+		.tx_phys = BLE_GAP_PHY_1MBPS,
+};
+
+static uint8_t _7_5ms_intervalFlag =0;
+uint8_t Slave_Get7_5ms_interval(void){
+	return _7_5ms_intervalFlag;
+}
+
+void on_ble_peripheral_evt(ble_evt_t const *p_ble_evt) //×÷?a′óéè±?μ?′|àí
+{
+    ret_code_t err_code;
+    ble_gap_evt_t const *p_gap_evt = &p_ble_evt->evt.gap_evt;
+    
+    switch (p_ble_evt->header.evt_id)
+    {
+    case BLE_GAP_EVT_CONNECTED:{
+        BLE_PRINT("on_ble_peripheral_evt -> BLE_GAP_EVT_CONNECTED\r\n");
+        m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
+        multi_qwr_conn_handle_assign(p_ble_evt->evt.gap_evt.conn_handle); //QWR句柄分配
+			
+				err_code = sd_ble_gap_tx_power_set(BLE_GAP_TX_POWER_ROLE_CONN,m_conn_handle,4);
+				APP_ERROR_CHECK(err_code);
+
+        connect_to_client = 1;
+        ble_slave_connected_evt_pcs();
+#if 1		
+				BLE_PRINT("PHY update request.");
+				err_code = sd_ble_gap_phy_update(p_gap_evt->conn_handle, &phys);
+				APP_ERROR_CHECK(err_code);
+#endif
+		   
+        BLE_PRINT("Connection 0x%x Received ble gap evt data length update request.", p_ble_evt->evt.gap_evt.conn_handle);
+        ble_gap_data_length_params_t dlp =
+				{
+						.max_rx_time_us= BLE_GAP_DATA_LENGTH_AUTO,
+						.max_tx_time_us= BLE_GAP_DATA_LENGTH_AUTO,
+						.max_rx_octets = BLE_GAP_DATA_LENGTH_AUTO,
+						.max_tx_octets = BLE_GAP_DATA_LENGTH_AUTO,
+				};
+        err_code = sd_ble_gap_data_length_update(p_ble_evt->evt.gap_evt.conn_handle, &dlp, NULL);
+        APP_ERROR_CHECK(err_code);
+				
+				
+        sd_ble_gap_rssi_start(m_conn_handle, BLE_GAP_RSSI_THRESHOLD_INVALID, 0);
+			  }
+        break;
+    case BLE_GAP_EVT_DISCONNECTED:
+        connect_to_client = 0;
+        ble_slave_dicconn_evt_pcs();
+
+        sd_ble_gap_rssi_stop(m_conn_handle);
+		    _7_5ms_intervalFlag =0;
+		    BLE_PRINT("on_ble_peripheral_evt -> BLE_GAP_EVT_DISCONNECTED,reason:%d\r\n",p_gap_evt->params.disconnected.reason);
+        break;
+
+    case BLE_GAP_EVT_PHY_UPDATE_REQUEST:
+    {
+        BLE_PRINT("on_ble_peripheral_evt -> BLE_GAP_EVT_PHY_UPDATE_REQUEST\r\n");
+        err_code = sd_ble_gap_phy_update(p_ble_evt->evt.gap_evt.conn_handle, &phys);
+        APP_ERROR_CHECK(err_code);
+    }
+    break;
+
+    case BLE_GATTC_EVT_TIMEOUT:
+        // Disconnect on GATT Client timeout event.
+        BLE_PRINT("on_ble_peripheral_evt -> BLE_GATTC_EVT_TIMEOUT\r\n");
+        err_code = sd_ble_gap_disconnect(p_ble_evt->evt.gattc_evt.conn_handle,
+                                         BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
+        APP_ERROR_CHECK(err_code);
+        break;
+
+    case BLE_GATTS_EVT_TIMEOUT:
+        // Disconnect on GATT Server timeout event.
+        BLE_PRINT("on_ble_peripheral_evt -> BLE_GATTS_EVT_TIMEOUT\r\n");
+        err_code = sd_ble_gap_disconnect(p_ble_evt->evt.gatts_evt.conn_handle,
+                                         BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
+        APP_ERROR_CHECK(err_code);
+        break;
+
+    case BLE_GAP_EVT_CONN_PARAM_UPDATE:
+		{
+        BLE_PRINT("on_ble_peripheral_evt -> BLE_GAP_EVT_CONN_PARAM_UPDATE\r\n");
+        slave_update_conn_interval_request_sta = 0;
+        memcpy(&slave_conn_params, &p_gap_evt->params.conn_param_update_request.conn_params, sizeof(ble_gap_conn_params_t));
+        BLE_PRINT("min_conn_interval : %d * 1.25 ms\r\n", p_gap_evt->params.conn_param_update_request.conn_params.min_conn_interval);
+        BLE_PRINT("max_conn_interval : %d * 1.25 ms\r\n", p_gap_evt->params.conn_param_update_request.conn_params.max_conn_interval);
+        BLE_PRINT("slave_latency     : %d\r\n", p_gap_evt->params.conn_param_update_request.conn_params.slave_latency);
+        BLE_PRINT("conn_sup_timeout  : %d * 10   ms\r\n", p_gap_evt->params.conn_param_update_request.conn_params.conn_sup_timeout);
+			  
+			  if(6 == p_gap_evt->params.conn_param_update_request.conn_params.min_conn_interval && 6 == p_gap_evt->params.conn_param_update_request.conn_params.max_conn_interval)
+						    _7_5ms_intervalFlag =1;
+					else 	_7_5ms_intervalFlag =0;
+        }BLE_PRINT("_7_5ms_intervalFlag  : %d\r\n", _7_5ms_intervalFlag);
+		break;
+				
+	case BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST:
+        {
+					BLE_PRINT("on_ble_peripheral_evt -> BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST\r\n");
+					ble_gap_conn_params_t params;
+					params = p_gap_evt->params.conn_param_update_request.conn_params;
+					err_code = sd_ble_gap_conn_param_update(p_gap_evt->conn_handle, &params);
+					BLE_PRINT("=====>BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST error:%d\r\n",err_code);
+					APP_ERROR_CHECK(err_code);
+
+					
+					memcpy(&slave_conn_params, &p_gap_evt->params.conn_param_update_request.conn_params, sizeof(ble_gap_conn_params_t));
+					BLE_PRINT("min_conn_interval : %d * 1.25 ms\r\n", p_gap_evt->params.conn_param_update_request.conn_params.min_conn_interval);
+					BLE_PRINT("max_conn_interval : %d * 1.25 ms\r\n", p_gap_evt->params.conn_param_update_request.conn_params.max_conn_interval);
+					BLE_PRINT("slave_latency     : %d\r\n", p_gap_evt->params.conn_param_update_request.conn_params.slave_latency);
+					BLE_PRINT("conn_sup_timeout  : %d * 10   ms\r\n", p_gap_evt->params.conn_param_update_request.conn_params.conn_sup_timeout);
+          
+        } break;
+
+    case BLE_GAP_EVT_RSSI_CHANGED:
+        BLE_PRINT("on_ble_peripheral_evt -> BLE_GAP_EVT_RSSI_CHANGED\r\n");
+        break;
+				
+    case BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST:
+    {
+				BLE_PRINT("on_ble_peripheral_evt -> BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST\r\n");
+        ble_gap_data_length_params_t const dlp =
+				{
+						.max_rx_octets = BLE_GAP_DATA_LENGTH_AUTO,
+						.max_tx_octets = BLE_GAP_DATA_LENGTH_AUTO,
+				};
+        err_code = sd_ble_gap_data_length_update(p_ble_evt->evt.gap_evt.conn_handle, &dlp, NULL);
+        APP_ERROR_CHECK(err_code);
+    }
+    break;
+
+    case BLE_GAP_EVT_DATA_LENGTH_UPDATE:
+    {
+			  BLE_PRINT("on_ble_peripheral_evt -> BLE_GAP_EVT_DATA_LENGTH_UPDATE\r\n");
+        BLE_PRINT("max_rx_octets   : %d \r\n", p_gap_evt->params.data_length_update.effective_params.max_rx_octets);
+        BLE_PRINT("max_rx_time_us  : %d \r\n", p_gap_evt->params.data_length_update.effective_params.max_rx_time_us);
+        BLE_PRINT("max_tx_octets   : %d \r\n", p_gap_evt->params.data_length_update.effective_params.max_tx_octets);
+        BLE_PRINT("max_tx_time_us  : %d \r\n", p_gap_evt->params.data_length_update.effective_params.max_tx_time_us);
+    }
+    break;		
+		
+    case BLE_GAP_EVT_ADV_SET_TERMINATED:
+        BLE_PRINT("on_ble_peripheral_evt -> BLE_GAP_EVT_ADV_SET_TERMINATED\r\n");
+        break;
+    case BLE_GATTS_EVT_HVN_TX_COMPLETE:
+        //        BLE_PRINT("on_ble_peripheral_evt -> BLE_GATTS_EVT_HVN_TX_COMPLETE\r\n");
+        break;
+    case BLE_GATTS_EVT_WRITE: //D′è?2ù×÷ò??-íê3é
+        break;
+		
+    case BLE_GATTC_EVT_EXCHANGE_MTU_RSP:				
+//				err_code = sd_ble_gattc_exchange_mtu_request(p_ble_evt->evt.gattc_evt.conn_handle,247);		
+//				APP_ERROR_CHECK(err_code);		
+        BLE_PRINT("on_ble_peripheral_evt -> BLE_GATTC_EVT_EXCHANGE_MTU_RSP  -> server_rx_mtu = %d\r\n",p_ble_evt->evt.gattc_evt.params.exchange_mtu_rsp.server_rx_mtu);
+        break;
+		case BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST://?÷?ú?ò′ó?úéê??mtuê±μ?ê??t
+	  {
+	    sd_ble_gatts_exchange_mtu_reply(m_conn_handle, NRF_SDH_BLE_GATT_MAX_MTU_SIZE);
+	    BLE_PRINT("on_ble_peripheral_evt -> BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST -> client_rx_mtu=%d\r\n",p_ble_evt->evt.gatts_evt.params.exchange_mtu_request.client_rx_mtu);
+	  }break;
+		
+    default:
+        BLE_PRINT("on_ble_peripheral_evt -> default : 0x%2x\r\n", p_ble_evt->header.evt_id);
+        // No implementation needed.
+        break;
+    }
+}
+
+static ble_gap_addr_t m_my_addr;
+void Get_MACaddr(unsigned char *mac)
+{
+	mac[0]=m_my_addr.addr[0];
+	mac[1]=m_my_addr.addr[1];
+	mac[2]=m_my_addr.addr[2];
+	mac[3]=m_my_addr.addr[3];
+	mac[4]=m_my_addr.addr[4];
+	mac[5]=m_my_addr.addr[5];
+}
+
+#if USE_LADDR == 1
+char set_adv_name = 0;
+#endif
+static void gap_params_init(void) //GAP3?ê??ˉ
+{
+    uint32_t err_code;
+    ble_gap_conn_params_t gap_conn_params;
+    ble_gap_conn_sec_mode_t sec_mode;
+
+    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode);
+#if USE_LADDR == 1
+    err_code = sd_ble_gap_addr_get(&m_my_addr);
+    APP_ERROR_CHECK(err_code);
+    if (set_adv_name == 0)
+    {
+        BLE_PRINT("MAC [ %02X %02X %02X %02X %02X %02X ]\r\n", m_my_addr.addr[0], m_my_addr.addr[1], m_my_addr.addr[2], m_my_addr.addr[3], m_my_addr.addr[4], m_my_addr.addr[5]);
+
+        sprintf(BleReallyName, "%s_%02X%02X", DEVICE_NAME, m_my_addr.addr[4], m_my_addr.addr[5]);
+                err_code = sd_ble_gap_device_name_set(&sec_mode,
+                                          (const uint8_t *)BleReallyName,
+                                          strlen(DEVICE_NAME) + 5);         
+		}
+		else
+		{
+						err_code = sd_ble_gap_device_name_set(&sec_mode,
+																			(const uint8_t *)BleReallyName,
+																			strlen(BleReallyName));
+		}
+		BLE_PRINT(">>>>>>>name:%d,%s",set_adv_name,BleReallyName);	
+#else
+
+    err_code = sd_ble_gap_device_name_set(&sec_mode,
+                                          (const uint8_t *)DEVICE_NAME,
+                                          strlen(DEVICE_NAME));
+#endif
+    APP_ERROR_CHECK(err_code);
+
+    memset(&gap_conn_params, 0, sizeof(gap_conn_params));
+
+    gap_conn_params.min_conn_interval = MIN_CONN_INTERVAL;
+    gap_conn_params.max_conn_interval = MAX_CONN_INTERVAL;
+    gap_conn_params.slave_latency = SLAVE_LATENCY;
+    gap_conn_params.conn_sup_timeout = CONN_SUP_TIMEOUT;
+
+    err_code = sd_ble_gap_ppcp_set(&gap_conn_params);
+    APP_ERROR_CHECK(err_code);
+    //		err_code = sd_ble_gap_tx_power_set(BLE_GAP_TX_POWER_ROLE_CONN,m_conn_handle,0);
+    //		APP_ERROR_CHECK(err_code);
+}
+
+#if USEFIFO 
+RINGFRAME_DEF(sbc,ringframe_size_1024);
+static unsigned int TIME_GetTicks_ms;
+unsigned int send_bytes_client(unsigned char *bytes, uint16_t len)
+{
+    unsigned short length = len;
+    if (connect_to_client)
+    {
+			do
+			{
+				if(ringframe_in(&sbc,bytes,length)==0)return 0;
+			}while(ringframe_throw(&sbc)==0);		
+			Process_SetHoldOn(send_bytes_client_pcs,1);
+			TIME_GetTicks_ms=TIME_GetTicks();
+			return 0;
+		}
+		else
+    {
+        BLE_PRINT("send_bytes_client error. connect_to_client=0\r\n");
+        return 1;
+    }
+} //作为从机时发送数据给主机
+
+void send_bytes_client_pcs(void)
+{
+	unsigned char sbuff[256];
+	unsigned char len=0;
+	while(ringframe_peek(&sbc,sbuff,&len)==0)
+	{
+			unsigned short length = len;
+			uint32_t flag = 0;
+			flag = ble_nus_data_send(&m_nus, sbuff, &length, m_conn_handle);
+			if(flag==0)ringframe_throw(&sbc);
+			else 
+			{
+				if((TIME_GetTicks()-TIME_GetTicks_ms>100)||(TIME_GetTicks_ms>TIME_GetTicks()))
+				{
+					Process_SetHoldOn(send_bytes_client_pcs,0);
+				}
+				return;
+			}
+	}
+	Process_SetHoldOn(send_bytes_client_pcs,0);
+}
+
+#else
+unsigned int send_bytes_client(unsigned char *bytes, uint16_t len)
+{
+	unsigned int rev=0;
+    unsigned short length = len;
+    if (connect_to_client){
+		   rev=ble_nus_data_send(&m_nus, bytes, &length, m_conn_handle);
+			 return rev;
+	  }
+	  else{
+       BLE_PRINT("send_bytes_client error. connect_to_client=0\r\n");
+       return 1;
+    }
+} //作为从机时发送数据给主机
+
+void send_bytes_client_pcs(void)
+{
+	
+}
+
+#endif
+
+extern void timer_init(void);
+extern void power_management_init(void);
+extern void ble_stack_init(void);
+extern void gatt_init(void);
+extern char ble_stack_init_sta;
+extern uint8_t app_Get_isHost(void);
+#if USEMACNAME && USE_LADDR != 1
+ble_gap_addr_t mAddr;
+#endif
+void slave_init(Ble_receive_handler_t receive_handler)
+{
+    static unsigned char init = 1;
+    if (init)
+    {
+        if (receive_handler == NULL)
+        {
+            BLE_PRINT("slave_init -> param err \r\n");
+            return;
+        }
+        Rec_h = receive_handler;
+        if (ble_stack_init_sta)
+        {
+            timer_init();            //
+            power_management_init(); //
+            ble_stack_init();        //
+            gatt_init();             //
+            ble_stack_init_sta = 0;
+        }
+#if USEMACNAME && USE_LADDR != 1
+        if (!app_Get_isHost())
+        {
+            sd_ble_gap_addr_get(&mAddr);
+            memset(DEVICE_NAME, 0, TARFET_LEN_MAX);
+            sprintf(DEVICE_NAME, "%02X%02X%02X%02X%02X%02X", mAddr.addr[5], mAddr.addr[4], mAddr.addr[3], mAddr.addr[2], mAddr.addr[1], mAddr.addr[0]);
+        }
+#endif
+		
+        gap_params_init();
+
+        services_init();
+        advertising_init();
+        conn_params_init();
+        advertising_start();
+        init = 0;
+#if USE_LADDR
+        BLE_PRINT("slave_init -> name [ %s ] \r\n", BleReallyName);
+#else
+        BLE_PRINT("slave_init -> name [ %s ] \r\n", DEVICE_NAME);
+#endif
+    }
+    else
+    {
+        BLE_PRINT("slave_init -> err slave has init done \r\n");
+    }
+}
+unsigned char slave_isconnect(void)
+{
+    return connect_to_client;
+}
+
+unsigned int slave_set_adv_name(char *name, int len)
+{
+#if USE_LADDR == 1
+    if (len > TARFET_LEN_MAX)
+        return APP_ERR_OVERLENGTH;
+    set_adv_name = 1;
+    memset(BleReallyName, 0, TARFET_LEN_MAX);
+    memcpy(BleReallyName, name, len);
+#else
+    if (len > TARFET_LEN_MAX)
+        return APP_ERR_OVERLENGTH;
+    memset(DEVICE_NAME, 0, TARFET_LEN_MAX);
+    memcpy(DEVICE_NAME, name, len);
+#endif
+    return APP_SUCCESS;
+}
+
+void slave_get_advname_len(int *len)
+{
+	*len = strlen(BleReallyName);
+}
+
+void slave_get_advname(char *name, int len)
+{
+	memcpy(name,BleReallyName,len);
+}
+
+void slave_disconnect(void)
+{
+    if (connect_to_client)
+        sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
+}
+
+unsigned int slave_update_conn_interval_request(float min_conn_interval, float max_conn_interval)
+{
+    ret_code_t err_code;
+    ble_gap_conn_params_t bgcp;
+    if (slave_update_conn_interval_request_sta)
+        return APP_ERR_BUSY;
+    if (connect_to_client)
+    {
+        slave_update_conn_interval_request_sta = 1;
+        if ((max_conn_interval > 1.25 * 1599) || (max_conn_interval < min_conn_interval))
+            return APP_ERR_PARAMERR;
+        if (min_conn_interval < 7.5f)
+            return APP_ERR_PARAMERR;
+        bgcp.max_conn_interval = MSEC_TO_UNITS(max_conn_interval, UNIT_1_25_MS);
+        bgcp.min_conn_interval = MSEC_TO_UNITS(min_conn_interval, UNIT_1_25_MS);
+        bgcp.conn_sup_timeout = MSEC_TO_UNITS(4000, UNIT_10_MS);
+        bgcp.slave_latency = 0;
+        BLE_PRINT("slave_update_conn_interval_request -> %d  \r\n", bgcp.max_conn_interval);
+        err_code = sd_ble_gap_conn_param_update(m_conn_handle, &bgcp);
+        APP_ERROR_CHECK(err_code);
+        return err_code;
+    }
+    else
+    {
+        return APP_ERR_DISCONN;
+    }
+}
+void slave_get_conn_params(ble_gap_conn_params_t *p)
+{
+    p->conn_sup_timeout = slave_conn_params.conn_sup_timeout;
+    p->max_conn_interval = slave_conn_params.max_conn_interval;
+    p->min_conn_interval = slave_conn_params.min_conn_interval;
+    p->slave_latency = slave_conn_params.slave_latency;
+}
+
+void slave_adv_init(void)
+{
+    gap_params_init();  //ìí?óμ?GAP3?ê??ˉ
+    conn_params_init(); //ìí?óμ?á??ó2?êy3?ê??ˉ
+    advertising_init(); //ìí?ó1?2¥3?ê??ˉ
+}
+
+static signed char rssi = 0;
+signed char slave_get_rssi(void)
+{
+    unsigned char channel;
+    if (connect_to_client == 0)
+        return 1;
+    sd_ble_gap_rssi_get(m_conn_handle, &rssi, &channel);
+    //    BLE_PRINT("rssi= %d  channel=%d\r\n", rssi, channel);
+    return rssi;
+}
+
+#if DEBUGBLE
+#define led 13
+#define tx 11 //1.1
+#define rx 12
+//#define LS -1611916254 //?a·¢°?
+//#define RS -889050188
+//#define LS 97376119  //31
+//#define RS 627878688  //32
+#define LS -1087551583 //1.1
+#define RS -957332282  //1.1
+#define PS -1372482754 //usb
+unsigned char buff[255];
+char start = 0;
+void host_r(unsigned char *p, int len)
+{
+    BLE_PRINT("hr : %d,0x%x\r\n", len, p[0]);
+    if (p[0] == 0xbb)
+    {
+        BLE_PRINT("hr -------------: 0xbb\r\n");
+        SEGGER_RTT_Write(0, &p[1], len);
+    }
+    if (p[0] == 0xcc)
+    {
+        BLE_PRINT("hr -------------: 0xcc\r\n");
+    }
+}
+#define TIMER_TICK 25
+#define TCUN 1000
+unsigned short cun = 0;
+unsigned short ts = 0;
+unsigned short rec[5] = {0};
+unsigned short recrtc[5] = {0};
+unsigned int rtc_cun = 0;
+void slave_r(unsigned char *p, int len)
+{
+    if (p[0] == 0xaa)
+    {
+        cun++;
+        ts = p[1];
+        ts = ts << 8;
+        ts += p[2];
+        if (ts >= 1)
+        {
+            start = 1;
+            rtc_cun = NRF_RTC2->COUNTER;
+        }
+        if (ts == TCUN)
+            start = 0;
+
+        if (start)
+        {
+            if (NRF_RTC2->COUNTER - rtc_cun < 1 * TIMER_TICK)
+                recrtc[0]++;
+            if ((NRF_RTC2->COUNTER - rtc_cun >= 1 * TIMER_TICK) && (NRF_RTC2->COUNTER - rtc_cun < 2 * TIMER_TICK))
+                recrtc[1]++;
+            if ((NRF_RTC2->COUNTER - rtc_cun >= 2 * TIMER_TICK) && (NRF_RTC2->COUNTER - rtc_cun < 3 * TIMER_TICK))
+                recrtc[2]++;
+            if ((NRF_RTC2->COUNTER - rtc_cun >= 3 * TIMER_TICK) && (NRF_RTC2->COUNTER - rtc_cun < 4 * TIMER_TICK))
+                recrtc[3]++;
+            if (NRF_RTC2->COUNTER - rtc_cun > 4 * TIMER_TICK)
+                recrtc[4]++;
+            rtc_cun = NRF_RTC2->COUNTER;
+        }
+
+        BLE_PRINT("sr : %d\r\n", ts);
+    }
+    if (p[0] == 0xbb)
+    {
+        buff[0] = 0xbb;
+        int leng = sprintf(((char *)&buff[1]), "0 :%d,%d\r\n1 :%d,%d\r\n2 :%d,%d\r\n3 :%d,%d\r\n4 :%d,%d\r\n", rec[0], recrtc[0], rec[1], recrtc[1], rec[2], recrtc[2], rec[3], recrtc[3], rec[4], recrtc[4]);
+        send_bytes_server(buff, leng);
+    }
+
+    if (p[0] == 0xcc)
+    {
+        BLE_PRINT("sr -------------: 0xcc\r\n");
+        memset(rec, 0, 10);
+        memset(recrtc, 0, 10);
+        send_bytes_server(p, 3);
+    }
+}
+
+#include "cli.h"
+nrf_radio_request_t radio_request_p;
+APP_TIMER_DEF(s_Timer);
+#define TEST_PERIOD APP_TIMER_TICKS(TIMER_TICK)
+unsigned short tims = 0;
+unsigned short stp = 0;
+void s_TimerCallback(void *arg)
+{
+    if ((tims > 0) && (tims <= TCUN))
+    {
+        buff[0] = 0xaa;
+        buff[1] = tims >> 8;
+        buff[2] = tims;
+        send_bytes_client(buff, 100);
+        BLE_PRINT("send : %d\r\n", tims);
+        tims++;
+    }
+    if (start)
+    {
+        if (cun > 4)
+            cun = 4;
+        rec[cun]++;
+        cun = 0;
+    }
+    //·¢êy?Y??ê??ú
+    if (*NRF_FICR->DEVICEID == LS) //×ó±?D?
+    {
+        if (start)
+        {
+            buff[0] = 0xaa;
+            buff[1] = stp >> 8;
+            buff[2] = stp;
+            send_bytes_client(buff, 100);
+        }
+        stp++;
+    }
+    //		nrf_gpio_pin_toggle(rx);
+    //nrf_gpio_pin_write(rx, 0);
+    //		 BLE_PRINT("error= %d\r\n", sd_radio_request(&radio_request_p));
+}
+void Radio_State(void)
+{
+    switch (NRF_RADIO->STATE)
+    {
+    case RADIO_STATE_STATE_Disabled:
+        BLE_PRINT("RADIO_STATE_STATE_Disabled\r\n");
+        break;
+    case RADIO_STATE_STATE_RxRu:
+        BLE_PRINT("RADIO_STATE_STATE_RxRu\r\n");
+        break;
+    case RADIO_STATE_STATE_RxIdle:
+        BLE_PRINT("RADIO_STATE_STATE_RxIdle\r\n");
+        break;
+    case RADIO_STATE_STATE_Rx:
+        BLE_PRINT("RADIO_STATE_STATE_Rx\r\n");
+        break;
+    case RADIO_STATE_STATE_RxDisable:
+        BLE_PRINT("RADIO_STATE_STATE_RxDisable\r\n");
+        break;
+    case RADIO_STATE_STATE_TxRu:
+        BLE_PRINT("RADIO_STATE_STATE_TxRu\r\n");
+        break;
+    case RADIO_STATE_STATE_TxIdle:
+        BLE_PRINT("RADIO_STATE_STATE_TxIdle\r\n");
+        break;
+    case RADIO_STATE_STATE_Tx:
+        BLE_PRINT("RADIO_STATE_STATE_Tx\r\n");
+        break;
+    case RADIO_STATE_STATE_TxDisable:
+        BLE_PRINT("RADIO_STATE_STATE_TxDisable\r\n");
+        break;
+    }
+}
+void unoioo(void)
+{
+    Ble_update_conn_interval(7.5,7.5);
+	
+}
+
+void unoioo_s(void)
+{
+    slave_update_conn_interval_request(30, 30);
+	scan_start();
+}
+
+void unoioo_s_d(void)
+{
+host_disconnect();
+	scan_start();
+}
+
+void rtc_config(void)
+{
+    NRF_RTC2->PRESCALER = 0; //??ò?oá????êy?÷?ó1,1024us
+    NRF_RTC2->TASKS_START = 1;
+}
+#include "nrf_drv_timer.h"
+void radio_evt_conf(void);
+const nrf_drv_timer_t TIMER_RADIO = NRF_DRV_TIMER_INSTANCE(2);
+void timer_led_event_handler(nrf_timer_event_t event_type, void *p_context)
+{
+    if (*NRF_FICR->DEVICEID == LS) //×ó±?D?
+    {
+        switch (event_type)
+        {
+        case NRF_TIMER_EVENT_COMPARE0: //320
+            sd_radio_request(&radio_request_p);
+            NRF_PPI->CHEN &= (~(PPI_CHENCLR_CH0_Enabled << PPI_CHEN_CH0_Pos) | (PPI_CHENCLR_CH1_Enabled << PPI_CHEN_CH1_Pos));
+            break;
+        case NRF_TIMER_EVENT_COMPARE1: //324
+            sd_radio_request(&radio_request_p);
+            break;
+        case NRF_TIMER_EVENT_COMPARE2: //328
+            sd_radio_request(&radio_request_p);
+            break;
+        case NRF_TIMER_EVENT_COMPARE3: //332
+            NRF_PPI->CHEN |= (PPI_CHENCLR_CH0_Enabled << PPI_CHEN_CH0_Pos) | (PPI_CHENCLR_CH1_Enabled << PPI_CHEN_CH1_Pos);
+            break;
+
+        default:
+            //Do nothing.
+            break;
+        }
+    }
+    if (*NRF_FICR->DEVICEID == RS) //óò±?D?
+    {
+        switch (event_type)
+        {
+        case NRF_TIMER_EVENT_COMPARE0: //320
+            nrf_gpio_pin_write(tx, 1);
+            break;
+        case NRF_TIMER_EVENT_COMPARE1: //324
+            nrf_gpio_pin_write(tx, 0);
+            break;
+        case NRF_TIMER_EVENT_COMPARE2: //328
+            break;
+        case NRF_TIMER_EVENT_COMPARE3: //332
+            break;
+
+        default:
+            //Do nothing.
+            break;
+        }
+    }
+}
+void timer_config(void)
+{
+    uint32_t time_us = 5000; //Time(in miliseconds) between consecutive compare events.
+    uint32_t time_ticks;
+    uint32_t err_code = NRF_SUCCESS;
+    nrf_drv_timer_config_t timer_cfg = NRF_DRV_TIMER_DEFAULT_CONFIG;
+    err_code = nrf_drv_timer_init(&TIMER_RADIO, &timer_cfg, timer_led_event_handler);
+    APP_ERROR_CHECK(err_code);
+    if (*NRF_FICR->DEVICEID == LS) //×ó±?D?
+    {
+        time_ticks = nrf_drv_timer_us_to_ticks(&TIMER_RADIO, time_us);
+        nrf_drv_timer_extended_compare(&TIMER_RADIO, NRF_TIMER_CC_CHANNEL0, time_ticks, 0, true);
+
+        time_ticks = nrf_drv_timer_us_to_ticks(&TIMER_RADIO, time_us + 10000);
+        nrf_drv_timer_extended_compare(&TIMER_RADIO, NRF_TIMER_CC_CHANNEL1, time_ticks, 0, true);
+
+        time_ticks = nrf_drv_timer_us_to_ticks(&TIMER_RADIO, time_us + 20000);
+        nrf_drv_timer_extended_compare(&TIMER_RADIO, NRF_TIMER_CC_CHANNEL2, time_ticks, 0, true);
+
+        time_ticks = nrf_drv_timer_us_to_ticks(&TIMER_RADIO, 29000);
+        nrf_drv_timer_extended_compare(&TIMER_RADIO, NRF_TIMER_CC_CHANNEL3, time_ticks, NRF_TIMER_SHORT_COMPARE3_CLEAR_MASK, true);
+    }
+    if (*NRF_FICR->DEVICEID == RS) //óò±?D?
+    {
+        time_us = 1000;
+        time_ticks = nrf_drv_timer_us_to_ticks(&TIMER_RADIO, time_us);
+        nrf_drv_timer_extended_compare(&TIMER_RADIO, NRF_TIMER_CC_CHANNEL0, time_ticks, 0, true);
+
+        time_ticks = nrf_drv_timer_us_to_ticks(&TIMER_RADIO, time_us + 9000 + 1);
+        nrf_drv_timer_extended_compare(&TIMER_RADIO, NRF_TIMER_CC_CHANNEL1, time_ticks, NRF_TIMER_SHORT_COMPARE1_CLEAR_MASK, true);
+
+        nrf_drv_timer_enable(&TIMER_RADIO);
+    }
+    //	nrf_drv_timer_enable(&TIMER_RADIO);
+}
+
+void ppi_set(void)
+{
+    NRF_PPI->CH[0].EEP = (unsigned int)(&NRF_TIMER0->EVENTS_COMPARE[0]);
+    NRF_PPI->CH[0].TEP = (unsigned int)(&NRF_TIMER2->TASKS_START);
+
+    NRF_PPI->CH[1].EEP = (unsigned int)(&NRF_TIMER2->EVENTS_COMPARE[3]);
+    NRF_PPI->CH[1].TEP = (unsigned int)(&NRF_TIMER2->TASKS_SHUTDOWN);
+
+    NRF_PPI->CHEN |= (PPI_CHENCLR_CH0_Enabled << PPI_CHEN_CH0_Pos) |
+                     (PPI_CHENCLR_CH1_Enabled << PPI_CHEN_CH1_Pos);
+}
+
+extern void USR_Init(void);
+extern void USR_Process(void);
+extern void TIME_Init(void);
+extern char Target_scan[];
+
+unsigned char txbuff[300] = {0x0a, 0x03, 0, 0, 2, 3, 4, 5, 6, 0, 8, 9};
+unsigned char rxbuff[300] = {0};
+void radio_init_R(void)
+{
+    NRF_RADIO->POWER = (RADIO_POWER_POWER_Enabled << RADIO_POWER_POWER_Pos);
+    /* Start 16 MHz crystal oscillator */
+    NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;
+    NRF_CLOCK->TASKS_HFCLKSTART = 1;
+
+    /* Wait for the external oscillator to start up */
+    while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0)
+    {
+        // Do nothing.
+    }
+
+    // Radio config
+    NRF_RADIO->TXPOWER = (RADIO_TXPOWER_TXPOWER_0dBm << RADIO_TXPOWER_TXPOWER_Pos);
+    NRF_RADIO->FREQUENCY = 7UL; // Frequency bin 7, 2407MHz
+    NRF_RADIO->MODE = (RADIO_MODE_MODE_Nrf_1Mbit << RADIO_MODE_MODE_Pos);
+
+    NRF_RADIO->PREFIX0 = 0xC3438303;
+    NRF_RADIO->PREFIX1 = 0xE3630023;
+    NRF_RADIO->BASE0 = 0x80C4A2E6;
+    NRF_RADIO->BASE1 = 0x91D5B3F7;
+
+    NRF_RADIO->TXADDRESS = 0x00UL;   // Set device address 0 to use when transmitting
+    NRF_RADIO->RXADDRESSES = 0x01UL; // Enable device address 0 to use to select which addresses to receive
+
+    NRF_RADIO->PCNF0 = 0X00030006;
+    NRF_RADIO->PCNF1 = 0X01040020;
+
+    NRF_RADIO->CRCCNF = (RADIO_CRCCNF_LEN_Two << RADIO_CRCCNF_LEN_Pos); // Number of checksum bits
+
+    NRF_RADIO->CRCINIT = 0xFFFFUL;  // Initial value
+    NRF_RADIO->CRCPOLY = 0x11021UL; // CRC poly: x^16 + x^12^x^5 + 1
+
+    NRF_RADIO->PACKETPTR = (uint32_t)&txbuff[0];
+}
+#include "nrf_drv_rtc.h"
+const nrf_drv_rtc_t rtc = NRF_DRV_RTC_INSTANCE(0); /**< Declaring an instance of nrf_drv_rtc for RTC2. */
+unsigned int countevt = 0;
+void radio_connect(void)
+{
+    NRF_RTC0->CC[2] = NRF_RTC0->COUNTER;
+    countevt = 1;
+    nrf_drv_rtc_cc_set(&rtc, 0, NRF_RTC0->CC[2] + countevt * 0.009 * 32768, true);
+    countevt++;
+}
+void RADIO_IRQHandler(void)
+{
+    if (NRF_RADIO->EVENTS_READY && (NRF_RADIO->INTENSET & RADIO_INTENSET_READY_Msk))
+    {
+        NRF_RADIO->EVENTS_READY = 0U;
+        BLE_PRINT("a");
+    }
+    if (NRF_RADIO->EVENTS_ADDRESS && (NRF_RADIO->INTENSET & RADIO_INTENSET_ADDRESS_Msk))
+    {
+        NRF_RADIO->EVENTS_ADDRESS = 0U;
+        BLE_PRINT("b");
+    }
+    if (NRF_RADIO->EVENTS_PAYLOAD && (NRF_RADIO->INTENSET & RADIO_INTENSET_PAYLOAD_Msk))
+    {
+        NRF_RADIO->EVENTS_PAYLOAD = 0U;
+        BLE_PRINT("c");
+    }
+    if (NRF_RADIO->EVENTS_END && (NRF_RADIO->INTENSET & RADIO_INTENSET_END_Msk))
+    {
+        NRF_RADIO->EVENTS_END = 0U;
+        //		NRF_LOG_INFO("d");
+        if (NRF_RADIO->STATE >= 5UL)
+        {
+            NRF_RADIO->EVENTS_DISABLED = 0U;
+            NRF_RADIO->TASKS_DISABLE = 1U;
+            nrf_gpio_pin_write(tx, 0);
+            //			BLE_PRINT("Tx  end\r\n");
+        }
+        else
+        {
+            //ê?μ?êy?Yoó?è?D???a·¢?í?£ê?
+            NRF_RTC0->CC[2] = NRF_RTC0->COUNTER;
+
+            NRF_RADIO->PACKETPTR = (unsigned int)txbuff;
+            NRF_RADIO->SHORTS = RADIO_SHORTS_READY_START_Msk;
+
+            nrf_gpio_pin_write(tx, 0);
+
+            NRF_RADIO->EVENTS_DISABLED = 0U;
+            NRF_RADIO->TASKS_DISABLE = 1U;
+            while (NRF_RADIO->EVENTS_DISABLED == 0)
+                ;
+
+            NRF_RADIO->TASKS_TXEN = 1;
+
+            nrf_gpio_pin_write(tx, 1);
+
+            nrf_drv_rtc_cc_set(&rtc, 0, NRF_RTC0->CC[2] + 0.010 * 32768, true);
+            nrf_drv_rtc_cc_set(&rtc, 1, NRF_RTC0->CC[2] + 0.018 * 32768, true);
+
+            for (int i = 0; i < 50; i++)
+            {
+                BLE_PRINT("%x", rxbuff[i]);
+            }
+            BLE_PRINT("Rx\r\n", rxbuff[1]);
+        }
+    }
+    if (NRF_RADIO->EVENTS_DISABLED && (NRF_RADIO->INTENSET & RADIO_INTENSET_DISABLED_Msk))
+    {
+        NRF_RADIO->EVENTS_DISABLED = 0U;
+        BLE_PRINT("e");
+    }
+    if (NRF_RADIO->EVENTS_DEVMATCH && (NRF_RADIO->INTENSET & RADIO_INTENSET_DEVMATCH_Msk))
+    {
+        NRF_RADIO->EVENTS_DEVMATCH = 0U;
+        BLE_PRINT("f");
+    }
+    if (NRF_RADIO->EVENTS_DEVMISS && (NRF_RADIO->INTENSET & RADIO_INTENSET_DEVMISS_Msk))
+    {
+        NRF_RADIO->EVENTS_DEVMISS = 0U;
+        BLE_PRINT("g");
+    }
+    if (NRF_RADIO->EVENTS_RSSIEND && (NRF_RADIO->INTENSET & RADIO_INTENSET_RSSIEND_Msk))
+    {
+        NRF_RADIO->EVENTS_RSSIEND = 0U;
+        BLE_PRINT("h");
+    }
+    if (NRF_RADIO->EVENTS_BCMATCH && (NRF_RADIO->INTENSET & RADIO_INTENSET_BCMATCH_Msk))
+    {
+        NRF_RADIO->EVENTS_BCMATCH = 0U;
+        BLE_PRINT("i");
+    }
+    if (NRF_RADIO->EVENTS_CRCOK && (NRF_RADIO->INTENSET & RADIO_INTENSET_CRCOK_Msk))
+    {
+        NRF_RADIO->EVENTS_CRCOK = 0U;
+        BLE_PRINT("k");
+    }
+    if (NRF_RADIO->EVENTS_CRCERROR && (NRF_RADIO->INTENSET & RADIO_INTENSET_CRCERROR_Msk))
+    {
+        NRF_RADIO->EVENTS_CRCERROR = 0U;
+        BLE_PRINT("l");
+    }
+    NVIC_ClearPendingIRQ(RADIO_IRQn);
+}
+
+void radio_scan_start(void)
+{
+    NRF_RADIO->SHORTS = 0;
+    NRF_RADIO->SHORTS |= RADIO_SHORTS_DISABLED_RXEN_Msk;
+    NRF_RADIO->SHORTS |= RADIO_SHORTS_READY_START_Msk;
+    NRF_RADIO->SHORTS |= RADIO_SHORTS_END_START_Msk;
+
+    NRF_RADIO->INTENSET |= RADIO_INTENSET_END_Msk;
+
+    NRF_RADIO->TASKS_RXEN = 1;
+    NRF_RADIO->EVENTS_READY = 0;
+    while (NRF_RADIO->EVENTS_READY == 0)
+    {
+    }
+
+    NRF_RADIO->TASKS_START = 1;
+    NVIC_EnableIRQ(RADIO_IRQn);
+    Radio_State();
+}
+
+static void rtc_handler(nrf_drv_rtc_int_type_t int_type)
+{
+    switch (int_type)
+    {
+    case NRFX_RTC_INT_COMPARE0:
+        nrf_gpio_pin_write(tx, 1);
+        NRF_RADIO->SHORTS = RADIO_SHORTS_READY_START_Msk;
+        NRF_RADIO->PACKETPTR = (unsigned int)rxbuff;
+        NRF_RADIO->TASKS_RXEN = 1U;
+        break;
+    case NRFX_RTC_INT_COMPARE1:
+        Radio_State();
+        BLE_PRINT("NRFX_RTC_INT_COMPARE1\r\n");
+        break;
+    case NRFX_RTC_INT_COMPARE2:
+        break;
+    case NRFX_RTC_INT_COMPARE3:
+        break;
+    case NRFX_RTC_INT_TICK:
+        break;
+    case NRFX_RTC_INT_OVERFLOW:
+        nrf_drv_rtc_counter_clear(&rtc);
+        break;
+    }
+}
+
+/**********************************************************
+ * oˉêy??×?£ortc_config
+ * oˉêy×÷ó?£ortc?y?ˉ3?ê??ˉoíéè??
+ * oˉêy2?êy£o?T
+ * oˉêy·μ???μ£o?T
+ ***********************************************************/
+
+void radio_rtc_config(void)
+{
+    uint32_t err_code;
+
+    NRF_CLOCK->LFCLKSRC = (CLOCK_LFCLKSRC_SRC_RC << CLOCK_LFCLKSRC_SRC_Pos);
+    NRF_CLOCK->EVENTS_LFCLKSTARTED = 0;
+    NRF_CLOCK->TASKS_LFCLKSTART = 1;
+
+    while (NRF_CLOCK->EVENTS_LFCLKSTARTED == 0)
+    {
+        // Do nothing.
+    }
+
+    //Initialize RTC instance
+    nrf_drv_rtc_config_t config = NRF_DRV_RTC_DEFAULT_CONFIG;
+    config.prescaler = 0; //4095;????????=32768/(config.prescaler+1)Hz;
+    err_code = nrf_drv_rtc_init(&rtc, &config, rtc_handler);
+    APP_ERROR_CHECK(err_code);
+
+    //Enable tick event & interrupt
+    //    nrf_drv_rtc_tick_enable(&rtc, true);
+
+    //Set compare channel to trigger interrupt after COMPARE_COUNTERTIME seconds
+    //    err_code = nrf_drv_rtc_cc_set(&rtc, 0, 8, true);
+    //    APP_ERROR_CHECK(err_code);
+
+    //Power on RTC instance
+    nrf_drv_rtc_enable(&rtc);
+}
+
+int main(void)
+{
+    unsigned int error = 0;
+    unsigned int rtctemp = 0;
+    unsigned int start = 0;
+    unsigned int radio_dis_cun = 0;
+    unsigned int radio_dis_cun_rtc = 0;
+
+    nrf_gpio_cfg_output(led);
+    nrf_gpio_pin_write(led, 1);
+
+    nrf_gpio_cfg_output(tx);
+    nrf_gpio_pin_write(tx, 0);
+
+    nrf_gpio_cfg_output(8);
+    nrf_gpio_pin_write(8, 0);
+
+    nrf_gpio_cfg_output(rx);
+    nrf_gpio_pin_write(rx, 0);
+
+    BLE_PRINT("NRF_FICR->DEVICEID : %d\r\n", *NRF_FICR->DEVICEID);
+
+    if (*NRF_FICR->DEVICEID == RS) //óò±?D?
+    {
+#if 1
+        slave_init(host_r);
+#else
+        radio_init_R();
+        radio_rtc_config();
+        radio_scan_start();
+#endif
+        BLE_PRINT("you \r\n");
+    }
+
+    if (*NRF_FICR->DEVICEID == LS) //×ó±?D?
+    {
+#if 0			
+			Target_scan[0]=0xe3;  //3132
+			Target_scan[1]=0x3f;
+			Target_scan[2]=0xd9;
+			Target_scan[3]=0x0d;
+			Target_scan[4]=0x0e;
+			Target_scan[5]=0xc6;
+			
+			sscanf("A1 A3 9D 04 E9 F4","%hhx %hhx %hhx %hhx %hhx %hhx",&Target_scan[0],&Target_scan[1],&Target_scan[2],&Target_scan[3],&Target_scan[4],&Target_scan[5]);
+			
+//			Target_scan[0]=0x3C;  //?a·¢°?
+//			Target_scan[1]=0x83;
+//			Target_scan[2]=0xCF;
+//			Target_scan[3]=0x49;
+//			Target_scan[4]=0x50;
+//			Target_scan[5]=0xE1;
+//
+#endif
+        Ble_Host_Connectd_Evt_Regist(unoioo);
+        Ble_Slave_Connectd_Evt_Regist(unoioo_s);
+			Ble_Slave_Disconn_Evt_Regist(unoioo_s_d);
+        //			extern void radio_request_earliest(void);
+        //			Ble_Slave_Connectd_Evt_Regist(radio_request_earliest);
+        slave_init(host_r);
+        host_init(slave_r);
+        
+
+        //				timer_config();
+        BLE_PRINT("zuo \r\n");
+    }
+
+    if (*NRF_FICR->DEVICEID == PS) //ê??ú
+    {
+#if 0	
+        Target_scan[0] = 0x21;
+        Target_scan[1] = 0x8a;
+        Target_scan[2] = 0x4f;
+        Target_scan[3] = 0x61;
+        Target_scan[4] = 0xcb;
+        Target_scan[5] = 0xe8;
+#endif
+        host_set_scan_name("SH_13EC", 7);
+        BLE_PRINT("shou \r\n");
+        host_init(slave_r);
+        scan_start();
+    }
+    rtc_config();
+    for (int i = 1; i < 200; i++)
+    {
+        buff[i] = i + 0x30;
+        //			txbuff[i]=i;
+    }
+    app_timer_create(&s_Timer, APP_TIMER_MODE_REPEATED, s_TimerCallback);
+    app_timer_start(s_Timer, TEST_PERIOD, NULL);
+    //		ppi_set();
+
+    while (1)
+    {
+        cli_process(&clirtt);
+        if (NRF_SUCCESS == sd_evt_get(&error))
+        {
+            BLE_PRINT("shou \r\n");
+        }
+        //				if (*NRF_FICR->DEVICEID == LS) //×ó±?D?
+        {
+            if (NRF_RADIO->STATE == RADIO_STATE_STATE_Disabled)
+            {
+                nrf_gpio_pin_write(tx, 0);
+            }
+            else
+            {
+                nrf_gpio_pin_write(tx, 1);
+            }
+        }
+    }
+}
+void host_init_pcs(cli_t *p_cli, unsigned short argc, char **argv)
+{
+    host_init(slave_r);
+}
+CLI_CMD_REGISTER(host_init, "clear sereen", host_init_pcs);
+
+void hsb_pcs(cli_t *p_cli, unsigned short argc, char **argv)
+{
+    send_bytes_server(buff, 200);
+}
+CLI_CMD_REGISTER(hsb, "clear sereen", hsb_pcs);
+
+void send_pcs(cli_t *p_cli, unsigned short argc, char **argv)
+{
+    tims = 1;
+}
+CLI_CMD_REGISTER(send, "clear sereen", send_pcs);
+
+void scc_pcs(cli_t *p_cli, unsigned short argc, char **argv)
+{
+    buff[0] = 0xcc;
+    send_bytes_client(buff, 6);
+}
+CLI_CMD_REGISTER(scc, "clear sereen", scc_pcs);
+
+void sbb_pcs(cli_t *p_cli, unsigned short argc, char **argv)
+{
+    buff[0] = 0xbb;
+    send_bytes_client(buff, 6);
+}
+CLI_CMD_REGISTER(sbb, "clear sereen", sbb_pcs);
+
+void hcb_pcs(cli_t *p_cli, unsigned short argc, char **argv)
+{
+    send_bytes_client(buff, 200);
+}
+CLI_CMD_REGISTER(hcb, "clear sereen", hcb_pcs);
+
+void slave_init_pcs(cli_t *p_cli, unsigned short argc, char **argv)
+{
+    slave_init(host_r);
+}
+CLI_CMD_REGISTER(slave_init, "clear sereen", slave_init_pcs);
+
+void bleupdata_pcs(cli_t *p_cli, unsigned short argc, char **argv)
+{
+    unsigned int error = 0;
+    error = Ble_update_conn_interval(10, 10);
+    cli_printf(p_cli, "err %d", error);
+}
+CLI_CMD_REGISTER(bleupdata10, "clear sereen", bleupdata_pcs);
+
+void bleupdata_1000pcs(cli_t *p_cli, unsigned short argc, char **argv)
+{
+    unsigned int error = 0;
+    error = Ble_update_conn_interval(1000, 1000);
+    cli_printf(p_cli, "err %d", error);
+}
+CLI_CMD_REGISTER(bleupdata1000, "clear sereen", bleupdata_1000pcs);
+
+void slaveupdata_pcs(cli_t *p_cli, unsigned short argc, char **argv)
+{
+    unsigned int error =
+        slave_update_conn_interval_request(40, 40);
+    cli_printf(p_cli, "err %d", error);
+}
+CLI_CMD_REGISTER(slaveupdata, "clear sereen", slaveupdata_pcs);
+
+void conn_pcs(cli_t *p_cli, unsigned short argc, char **argv)
+{
+    if (argc == 1)
+    {
+        host_set_scan_name(argv[0], strlen(argv[0]));
+        host_init(slave_r);
+    }
+    else
+        cli_printf(p_cli, "err ");
+}
+CLI_CMD_REGISTER(conn, "clear sereen", conn_pcs);
+
+void scan_name_set_pcs(cli_t *p_cli, unsigned short argc, char **argv)
+{
+    if (argc == 1)
+    {
+        host_set_scan_name(argv[0], strlen(argv[0]));
+    }
+    else
+        cli_printf(p_cli, "err ");
+}
+CLI_CMD_REGISTER(scan_name_set, "clear sereen", scan_name_set_pcs);
+
+void systemreset_pcs(cli_t *p_cli, unsigned short argc, char **argv)
+{
+    NVIC_SystemReset();
+}
+CLI_CMD_REGISTER(systemreset, "clear sereen", systemreset_pcs);
+
+void scanstart_pcs(cli_t *p_cli, unsigned short argc, char **argv)
+{
+    scan_start();
+}
+CLI_CMD_REGISTER(scanstart, "clear sereen", scanstart_pcs);
+
+void slave_dec_pcs(cli_t *p_cli, unsigned short argc, char **argv)
+{
+    slave_disconnect();
+}
+CLI_CMD_REGISTER(slave_dec, "clear sereen", slave_dec_pcs);
+
+void host_dec_pcs(cli_t *p_cli, unsigned short argc, char **argv)
+{
+    host_disconnect();
+}
+CLI_CMD_REGISTER(host_dec, "clear sereen", host_dec_pcs);
+
+void getconn_pcs(cli_t *p_cli, unsigned short argc, char **argv)
+{
+    BLE_PRINT("min_conn_interval : %d * 1.25 ms\r\n", slave_conn_params.min_conn_interval);
+    BLE_PRINT("max_conn_interval : %d * 1.25 ms\r\n", slave_conn_params.max_conn_interval);
+    BLE_PRINT("slave_latency     : %d\r\n", slave_conn_params.slave_latency);
+    BLE_PRINT("conn_sup_timeout  : %d * 10   ms\r\n", slave_conn_params.conn_sup_timeout);
+    extern ble_gap_conn_params_t host_conn_params;
+    BLE_PRINT("min_conn_interval : %d * 1.25 ms\r\n", host_conn_params.min_conn_interval);
+    BLE_PRINT("max_conn_interval : %d * 1.25 ms\r\n", host_conn_params.max_conn_interval);
+    BLE_PRINT("slave_latency     : %d\r\n", host_conn_params.slave_latency);
+    BLE_PRINT("conn_sup_timeout  : %d * 10   ms\r\n", host_conn_params.conn_sup_timeout);
+
+    slave_set_adv_name("123456", 6);
+    gap_params_init();
+    while (slave_isconnect() == 1)
+    {
+    }
+    BLE_PRINT("123456555");
+    advertising_start();
+    BLE_PRINT("4554564");
+}
+CLI_CMD_REGISTER(getconn, "clear sereen", getconn_pcs);
+
+void slave_get_rssi_pcs(cli_t *p_cli, unsigned short argc, char **argv)
+{
+    slave_get_rssi();
+}
+CLI_CMD_REGISTER(slave_get_rssi, "clear sereen", slave_get_rssi_pcs);
+void host_get_rssi_pcs(cli_t *p_cli, unsigned short argc, char **argv)
+{
+    host_get_rssi();
+}
+CLI_CMD_REGISTER(host_get_rssi, "clear sereen", host_get_rssi_pcs);
+
+int teg = 0;
+unsigned int rtccc = 0;
+void radio_evt_conf(void)
+{
+    NRF_RADIO->POWER = (RADIO_POWER_POWER_Enabled << RADIO_POWER_POWER_Pos);
+    /* Start 16 MHz crystal oscillator */
+    NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;
+    NRF_CLOCK->TASKS_HFCLKSTART = 1;
+    txbuff[1] = NRF_RTC0->COUNTER;
+    txbuff[2] = teg;
+    /* Wait for the external oscillator to start up */
+    while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0)
+    {
+        // Do nothing.
+    }
+
+    // Radio config
+    NRF_RADIO->TXPOWER = (RADIO_TXPOWER_TXPOWER_0dBm << RADIO_TXPOWER_TXPOWER_Pos);
+    NRF_RADIO->FREQUENCY = 7UL; // Frequency bin 7, 2407MHz
+    NRF_RADIO->MODE = (RADIO_MODE_MODE_Nrf_1Mbit << RADIO_MODE_MODE_Pos);
+
+    NRF_RADIO->PREFIX0 = 0xC3438303;
+    NRF_RADIO->PREFIX1 = 0xE3630023;
+    NRF_RADIO->BASE0 = 0x80C4A2E6;
+    NRF_RADIO->BASE1 = 0x91D5B3F7;
+
+    NRF_RADIO->TXADDRESS = 0x00UL;   // Set device address 0 to use when transmitting
+    NRF_RADIO->RXADDRESSES = 0x01UL; // Enable device address 0 to use to select which addresses to receive
+
+    NRF_RADIO->PCNF0 = 0X00030006;
+    NRF_RADIO->PCNF1 = 0X01040020;
+
+    NRF_RADIO->CRCCNF = (RADIO_CRCCNF_LEN_Two << RADIO_CRCCNF_LEN_Pos); // Number of checksum bits
+
+    NRF_RADIO->CRCINIT = 0xFFFFUL;  // Initial value
+    NRF_RADIO->CRCPOLY = 0x11021UL; // CRC poly: x^16 + x^12^x^5 + 1
+
+    NRF_RADIO->SHORTS = RADIO_SHORTS_READY_START_Enabled << RADIO_SHORTS_READY_START_Pos //READYoó×??ˉ?aê??′DDSTART
+                        | RADIO_SHORTS_END_DISABLE_Enabled << RADIO_SHORTS_END_DISABLE_Pos;
+
+    // Set payload pointer
+    NRF_RADIO->PACKETPTR = (uint32_t)&txbuff[0];
+
+    NRF_RADIO->EVENTS_DISABLED = 0; //??3y±ê????
+    NRF_RADIO->TASKS_TXEN = 1;      //?aê?oó?á?ú2?×??o2ù×÷
+    while (NRF_RADIO->EVENTS_END == 0)
+    {
+        //μè′y·¢?ííê3é
+    }
+    nrf_gpio_pin_write(rx, 0);
+    NRF_RADIO->SHORTS = 0;
+    NRF_RADIO->EVENTS_DISABLED = 0U;
+    NRF_RADIO->TASKS_DISABLE = 1U;
+    while (NRF_RADIO->EVENTS_DISABLED == 0)
+    {
+        //μè′y1?μ?radio
+    }
+
+    NRF_RADIO->EVENTS_READY = 0U;
+    // Enable radio and wait for ready
+    NRF_RADIO->TASKS_RXEN = 1U;
+
+    NRF_RADIO->PACKETPTR = (uint32_t)&rxbuff[0];
+
+    while (NRF_RADIO->EVENTS_READY == 0U)
+    {
+        // wait
+    }
+    nrf_gpio_pin_write(rx, 1);
+    NRF_RADIO->EVENTS_END = 0U;
+    // Start listening and wait for address received event
+    NRF_RADIO->TASKS_START = 1U;
+
+    // Wait for end of packet or buttons state changed
+
+    for (int j = 0; j < 5000; j++)
+    {
+        if (NRF_RADIO->EVENTS_END == 1)
+            break;
+    }
+
+    if (NRF_RADIO->CRCSTATUS == 1U)
+    {
+        for (int i = 0; i < 50; i++)
+        {
+            BLE_PRINT("%x", rxbuff[i]);
+        }
+        BLE_PRINT("\r\n ");
+        memset(rxbuff, 0, 60);
+    }
+    else
+    {
+        BLE_PRINT("E\r\n ");
+    }
+}
+
+nrf_radio_signal_callback_return_param_t call_radio_return_val;
+nrf_radio_signal_callback_return_param_t *call_radio(unsigned char sig)
+{
+    nrf_gpio_pin_write(rx, 1);
+
+    radio_evt_conf();
+
+    nrf_gpio_pin_write(rx, 0);
+    call_radio_return_val.callback_action = NRF_RADIO_SIGNAL_CALLBACK_ACTION_REQUEST_AND_END;
+    return &call_radio_return_val;
+}
+
+void radio_session_open(void)
+{
+    BLE_PRINT("error= %d\r\n", sd_radio_session_open(call_radio));
+}
+
+void radio_session_open_pcs(cli_t *p_cli, unsigned short argc, char **argv)
+{
+    BLE_PRINT("error= %d\r\n", sd_radio_session_open(call_radio));
+}
+CLI_CMD_REGISTER(radio_s_open, "clear sereen", radio_session_open_pcs);
+
+void radio_session_close_pcs(cli_t *p_cli, unsigned short argc, char **argv)
+{
+    BLE_PRINT("error= %d\r\n", sd_radio_session_close());
+}
+CLI_CMD_REGISTER(radio_s_close, "clear sereen", radio_session_close_pcs);
+
+void radio_request_earliest(void)
+{
+    radio_session_open();
+
+    radio_request_p.request_type = NRF_RADIO_REQ_TYPE_EARLIEST;
+    radio_request_p.params.earliest.hfclk = NRF_RADIO_HFCLK_CFG_NO_GUARANTEE;
+    radio_request_p.params.earliest.length_us = 4000;
+    radio_request_p.params.earliest.priority = NRF_RADIO_PRIORITY_NORMAL;
+    radio_request_p.params.earliest.timeout_us = 2000;
+    BLE_PRINT("radio_request_earliest= %d\r\n", sd_radio_request(&radio_request_p));
+    //
+    //	radio_request_p.request_type=NRF_RADIO_REQ_TYPE_NORMAL;
+    //	radio_request_p.params.normal.hfclk=NRF_RADIO_HFCLK_CFG_XTAL_GUARANTEED;
+    //	radio_request_p.params.normal.distance_us=10000;
+    //	radio_request_p.params.normal.length_us=5000;
+    //	radio_request_p.params.normal.priority=NRF_RADIO_PRIORITY_NORMAL;
+}
+
+void radio_request_e_pcs(cli_t *p_cli, unsigned short argc, char **argv)
+{
+    radio_request_p.request_type = NRF_RADIO_REQ_TYPE_EARLIEST;
+    radio_request_p.params.earliest.hfclk = NRF_RADIO_HFCLK_CFG_XTAL_GUARANTEED;
+    radio_request_p.params.earliest.length_us = 5000;
+    radio_request_p.params.earliest.priority = NRF_RADIO_PRIORITY_NORMAL;
+    radio_request_p.params.earliest.timeout_us = 2000;
+    BLE_PRINT("error= %d", sd_radio_request(&radio_request_p));
+}
+CLI_CMD_REGISTER(radio_r_e, "clear sereen", radio_request_e_pcs);
+
+void radio_request_n_pcs(cli_t *p_cli, unsigned short argc, char **argv)
+{
+    radio_request_p.request_type = NRF_RADIO_REQ_TYPE_NORMAL;
+    BLE_PRINT("error= %d", sd_radio_request(&radio_request_p));
+}
+
+CLI_CMD_REGISTER(radio_r_n, "clear sereen", radio_request_n_pcs);
+
+void Radio_State_pcs(cli_t *p_cli, unsigned short argc, char **argv)
+{
+    Radio_State();
+}
+
+CLI_CMD_REGISTER(Radio_State, "clear sereen", Radio_State_pcs);
+
+void s100_pcs(cli_t *p_cli, unsigned short argc, char **argv)
+{
+    send_bytes_client(buff, 150);
+}
+
+CLI_CMD_REGISTER(s100, "clear sereen", s100_pcs);
+
+#endif

+ 177 - 0
shoe_mcu2.2.1_new_v2/ble_cfg/timeslot.c

@@ -0,0 +1,177 @@
+//需要使用的头文件
+#include <stdint.h>
+#include <stdbool.h>
+#include "nrf.h"
+#include "app_error.h"
+#include "nrf_gpio.h"
+#include "boards.h"
+#include "nrf_nvic.h"
+#include "ble_comm.h"
+
+// 定义一个timeSlot的变量,该变量用来设置 请求的timeSlot的特性。
+static nrf_radio_request_t m_timeslot_request;
+// 请求的timeSlot的时间间隙长度
+static uint32_t m_slot_length;
+// 信号处理函数的返回值。
+static nrf_radio_signal_callback_return_param_t signal_callback_return_param;
+
+
+//请求一个earliest possible 类型的timeSlot,第一次请求timeSLot的时候总是以该类型发起
+// timeSlot时间长度为  5000 us
+// timeSlot的请求优先级为正常优先级
+// 这里设置了在timeSlot运行过程中会打开外部高频晶振时钟源,不过其实不是必须的。
+// timeout_us表示请求timeSlot发出后,系统接收这个请求的最大延迟。
+// timeSLot的时间长度为5000us
+uint32_t request_next_event_earliest(void)
+{
+    m_slot_length = 5000;
+    m_timeslot_request.request_type = NRF_RADIO_REQ_TYPE_EARLIEST;
+    m_timeslot_request.params.earliest.hfclk = NRF_RADIO_HFCLK_CFG_XTAL_GUARANTEED;
+    m_timeslot_request.params.earliest.priority = NRF_RADIO_PRIORITY_NORMAL;
+    m_timeslot_request.params.earliest.length_us = m_slot_length;
+    m_timeslot_request.params.earliest.timeout_us = 1000000;
+    return sd_radio_request(&m_timeslot_request);
+}
+
+// 配置 earliest possible的类型的 timeSlot
+void configure_next_event_earliest(void)
+{
+    m_slot_length = 5000;
+    m_timeslot_request.request_type = NRF_RADIO_REQ_TYPE_EARLIEST;
+    m_timeslot_request.params.earliest.hfclk = NRF_RADIO_HFCLK_CFG_XTAL_GUARANTEED;
+    m_timeslot_request.params.earliest.priority = NRF_RADIO_PRIORITY_NORMAL;
+    m_timeslot_request.params.earliest.length_us = m_slot_length;
+    m_timeslot_request.params.earliest.timeout_us = 1000000;
+}
+
+// 配置normal类型的timeSlot
+void configure_next_event_normal(void)
+{
+    m_slot_length = 5000;
+    m_timeslot_request.request_type = NRF_RADIO_REQ_TYPE_NORMAL;
+    m_timeslot_request.params.normal.hfclk = NRF_RADIO_HFCLK_CFG_XTAL_GUARANTEED;
+		m_timeslot_request.params.normal.priority = NRF_RADIO_PRIORITY_HIGH;
+// norma类型的timeSlot 的开始时间为距离上一个 timeSlot的开始时间 distance_us后
+    m_timeslot_request.params.normal.distance_us = 100000;
+    m_timeslot_request.params.normal.length_us = m_slot_length;
+}
+
+
+// timeSlot 会话相关的 一些事件的处理
+// 这里的主要处理是,在收到 IDLE事件,即申请的这段会话中没有 timeSlot需要处理后会
+// 产生这个事件,那么就可以 通过sd_radio_session_close 函数关闭这个 会话了
+// 另外请求的timeSlot可能因为和协议栈运行产生冲突,那么就可以被阻塞或去掉,所以
+// NRF_EVT_RADIO_BLOCKED 和 NRF_EVT_RADIO_CANCELED 事件的处理都是重新发起请求
+void nrf_evt_signal_handler(uint32_t evt_id)
+{
+    uint32_t err_code;
+    switch (evt_id)
+    {
+        case NRF_EVT_RADIO_SIGNAL_CALLBACK_INVALID_RETURN:
+            BLE_PRINT("NRF_EVT_RADIO_SIGNAL_CALLBACK_INVALID_RETURN\r\n");
+            break;
+        case NRF_EVT_RADIO_SESSION_IDLE:
+            BLE_PRINT("NRF_EVT_RADIO_SESSION_IDLE\r\n");
+            sd_radio_session_close();
+            break;
+        case NRF_EVT_RADIO_SESSION_CLOSED:
+            BLE_PRINT("NRF_EVT_RADIO_SESSION_CLOSED\r\n");
+            break;
+        case NRF_EVT_RADIO_BLOCKED:
+            BLE_PRINT("NRF_EVT_RADIO_BLOCKED\r\n");
+            //注意这里没有break,所以 这两个事件的处理都是重新发起请求
+        case NRF_EVT_RADIO_CANCELED:
+            BLE_PRINT("NRF_EVT_RADIO_CANCELED\r\n");
+            err_code = request_next_event_earliest();
+            APP_ERROR_CHECK(err_code);
+            break;
+        default:
+            break;
+    }
+}
+
+
+// timeSlot相关的信号处理函数。
+// 当请求的timeSlot 被安排开始后,就会收到 START信号,在这个信号处理里面实现
+// 实现翻转 LED灯同时设置 Timer0的超时时间,time0在timeSLot开始后会被自动重置为
+// 1MH运行从0 计数,所以这里设置time0的超时时间比 timeSlot的时间长度短1000us,//这样在timeSLot
+// 结束之前就可以收到 NRF_RADIO_CALLBACK_SIGNAL_TYPE_TIMER0信号,然后在这信号处
+// 理里做一些收尾工作,在这里我们实现的是请求下一个timeSlot
+
+// NRF_RADIO_CALLBACK_SIGNAL_TYPE_RADIO信号不需要处理,因为我们没有在timeSLot
+// 中使用Radio,所以不会有这个信号。
+
+nrf_radio_signal_callback_return_param_t * radio_callback(uint8_t signal_type)
+{
+    static uint8_t start_count = 0;
+    static uint8_t timer0_count = 0;
+
+    switch(signal_type)
+    {
+        case NRF_RADIO_CALLBACK_SIGNAL_TYPE_START:
+            signal_callback_return_param.params.request.p_next = NULL;
+						signal_callback_return_param.callback_action    = NRF_RADIO_SIGNAL_CALLBACK_ACTION_NONE;
+
+            NRF_TIMER0->INTENSET = TIMER_INTENSET_COMPARE0_Msk;
+            NRF_TIMER0->CC[0] = m_slot_length - 1000;
+            NVIC_EnableIRQ(TIMER0_IRQn);
+
+            nrf_gpio_pin_toggle(16);
+            //避免打印太快
+            if(start_count++ >10 ){            
+                BLE_PRINT("NRF_RADIO_CALLBACK_SIGNAL_TYPE_START\r\n");
+                start_count = 0;
+            }
+            break;
+
+        case NRF_RADIO_CALLBACK_SIGNAL_TYPE_RADIO:
+            signal_callback_return_param.params.request.p_next = NULL;
+            signal_callback_return_param.callback_action = NRF_RADIO_SIGNAL_CALLBACK_ACTION_NONE;
+            break;
+
+        case NRF_RADIO_CALLBACK_SIGNAL_TYPE_TIMER0:
+            configure_next_event_normal();
+            signal_callback_return_param.params.request.p_next = &m_timeslot_request;
+            signal_callback_return_param.callback_action    = NRF_RADIO_SIGNAL_CALLBACK_ACTION_REQUEST_AND_END;
+            if(timer0_count++ >10 ){            
+                BLE_PRINT("NRF_RADIO_CALLBACK_SIGNAL_TYPE_TIMER0\r\n");
+                timer0_count = 0;
+            }
+            break;
+        case NRF_RADIO_CALLBACK_SIGNAL_TYPE_EXTEND_SUCCEEDED:
+            BLE_PRINT("NRF_RADIO_CALLBACK_SIGNAL_TYPE_EXTEND_SUCCEEDED\r\n");
+            break;
+        case NRF_RADIO_CALLBACK_SIGNAL_TYPE_EXTEND_FAILED:
+            BLE_PRINT("NRF_RADIO_CALLBACK_SIGNAL_TYPE_EXTEND_FAILED\r\n");
+            configure_next_event_earliest();
+            signal_callback_return_param.params.request.p_next = &m_timeslot_request;
+						signal_callback_return_param.callback_action    = NRF_RADIO_SIGNAL_CALLBACK_ACTION_REQUEST_AND_END;
+            break;
+        default:
+            //No implementation needed
+            break;
+    }
+    return (&signal_callback_return_param);
+}
+
+// timeSlot初始化函数。
+uint32_t timeslot_sd_init(void)
+{
+    uint32_t err_code;
+
+    err_code = sd_radio_session_open(radio_callback);
+    if (err_code != NRF_SUCCESS)
+    {
+        return err_code;
+    }
+
+    err_code = request_next_event_earliest();
+    if (err_code != NRF_SUCCESS)
+    {
+        (void)sd_radio_session_close();
+        return err_code;
+    }
+    nrf_gpio_cfg_output(16);
+    return NRF_SUCCESS;
+}
+

+ 325 - 0
shoe_mcu2.2.1_new_v2/ble_dfu/ble_dfu.c

@@ -0,0 +1,325 @@
+/**
+ * Copyright (c) 2017 - 2020, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ *    list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ *    Semiconductor ASA integrated circuit in a product or a software update for
+ *    such product, must reproduce the above copyright notice, this list of
+ *    conditions and the following disclaimer in the documentation and/or other
+ *    materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ *    contributors may be used to endorse or promote products derived from this
+ *    software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ *    Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ *    engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/* Attention!
+ *  To maintain compliance with Nordic Semiconductor ASA's Bluetooth profile
+ *  qualification listings, this section of source code must not be modified.
+ */
+
+#include "ble_dfu.h"
+#include <string.h>
+#include "ble_hci.h"
+#include "sdk_macros.h"
+#include "ble_srv_common.h"
+#include "nrf_nvic.h"
+#include "nrf_soc.h"
+#include "nrf_log.h"
+#include "nrf_dfu_ble_svci_bond_sharing.h"
+#include "nrf_bootloader_info.h"
+#include "nrf_svci_async_function.h"
+#include "nrf_pwr_mgmt.h"
+#include "peer_manager.h"
+#include "gatts_cache_manager.h"
+#include "peer_id.h"
+
+#define MAX_CTRL_POINT_RESP_PARAM_LEN   3                           /**< Max length of the responses. */
+
+#define BLE_DFU_SERVICE_UUID            0xFE59                      /**< The 16-bit UUID of the Secure DFU Service. */
+
+static ble_dfu_buttonless_t             m_dfu;                      /**< Structure holding information about the Buttonless Secure DFU Service. */
+
+NRF_SDH_BLE_OBSERVER(m_dfus_obs, BLE_DFU_BLE_OBSERVER_PRIO, ble_dfu_buttonless_on_ble_evt, &m_dfu);
+
+
+/**@brief Function that is called if no event handler is provided.
+ */
+static void dummy_evt_handler(ble_dfu_buttonless_evt_type_t evt)
+{
+    NRF_LOG_DEBUG("Dummy event handler received event 0x%x", evt);
+}
+
+
+/**@brief Function for handling write events to the Buttonless Secure DFU Service Service Control Point characteristic.
+ *
+ * @param[in]   p_evt_write   Write event received from the BLE stack.
+ */
+static void on_ctrlpt_write(ble_gatts_evt_write_t const * p_evt_write)
+{
+    uint32_t      err_code;
+
+    ble_gatts_rw_authorize_reply_params_t write_authorize_reply;
+    memset(&write_authorize_reply, 0, sizeof(write_authorize_reply));
+
+    write_authorize_reply.type   = BLE_GATTS_AUTHORIZE_TYPE_WRITE;
+
+    uint8_t cccd_val[2];
+    ble_gatts_value_t value = {.p_value = cccd_val, .len = 2, .offset = 0};
+    err_code = sd_ble_gatts_value_get(m_dfu.conn_handle, m_dfu.control_point_char.cccd_handle, &value);
+    if (err_code == NRF_SUCCESS && ble_srv_is_indication_enabled(cccd_val))
+    {
+        write_authorize_reply.params.write.update      = 1;
+        write_authorize_reply.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS;
+    }
+    else
+    {
+        write_authorize_reply.params.write.gatt_status = BLE_GATT_STATUS_ATTERR_CPS_CCCD_CONFIG_ERROR;
+    }
+
+    // Authorize the write request
+    do {
+        err_code = sd_ble_gatts_rw_authorize_reply(m_dfu.conn_handle, &write_authorize_reply);
+    } while (err_code == NRF_ERROR_BUSY);
+
+
+    if (write_authorize_reply.params.write.gatt_status != BLE_GATT_STATUS_SUCCESS)
+    {
+        return;
+    }
+
+    // Forward the write event to the Buttonless DFU module.
+    ble_dfu_buttonless_on_ctrl_pt_write(p_evt_write);
+}
+
+
+/**@brief Write authorization request event handler.
+ *
+ * @details The write authorization request event handler is called when writing to the control point.
+ *
+ * @param[in]   p_ble_evt Event received from the BLE stack.
+ */
+static void on_rw_authorize_req(ble_evt_t const * p_ble_evt)
+{
+    if (p_ble_evt->evt.gatts_evt.conn_handle != m_dfu.conn_handle)
+    {
+        return;
+    }
+
+    const ble_gatts_evt_rw_authorize_request_t * p_auth_req =
+        &p_ble_evt->evt.gatts_evt.params.authorize_request;
+
+    if (
+        (p_auth_req->type == BLE_GATTS_AUTHORIZE_TYPE_WRITE)                            &&
+        (p_auth_req->request.write.handle == m_dfu.control_point_char.value_handle)     &&
+        (p_auth_req->request.write.op != BLE_GATTS_OP_PREP_WRITE_REQ)                   &&
+        (p_auth_req->request.write.op != BLE_GATTS_OP_EXEC_WRITE_REQ_NOW)               &&
+        (p_auth_req->request.write.op != BLE_GATTS_OP_EXEC_WRITE_REQ_CANCEL)
+       )
+    {
+        on_ctrlpt_write(&p_auth_req->request.write);
+    }
+}
+
+
+/**@brief Connect event handler.
+ *
+ * @param[in]   p_ble_evt   Event received from the BLE stack.
+ */
+static void on_connect(ble_evt_t const * p_ble_evt)
+{
+    if (p_ble_evt->evt.gap_evt.params.connected.role == BLE_GAP_ROLE_PERIPH)
+    {
+        m_dfu.conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
+    }
+}
+
+
+/**@brief Disconnect event handler.
+ *
+ * @param[in]   p_ble_evt   Event received from the BLE stack.
+ */
+static void on_disconnect(ble_evt_t const * p_ble_evt)
+{
+    if (m_dfu.conn_handle != p_ble_evt->evt.gap_evt.conn_handle)
+    {
+        return;
+    }
+
+    m_dfu.conn_handle = BLE_CONN_HANDLE_INVALID;
+}
+
+
+/**@brief Function for handling the HVC events.
+ *
+ * @details Handles HVC events from the BLE stack.
+ *
+ * @param[in] p_ble_evt  Event received from the BLE stack.
+ */
+static void on_hvc(ble_evt_t const * p_ble_evt)
+{
+    uint32_t err_code;
+    ble_gatts_evt_hvc_t const * p_hvc = &p_ble_evt->evt.gatts_evt.params.hvc;
+
+    if (p_hvc->handle == m_dfu.control_point_char.value_handle)
+    {
+        // Enter bootloader if we were waiting for reset after hvc indication confimation.
+        if (m_dfu.is_waiting_for_reset)
+        {
+            err_code = ble_dfu_buttonless_bootloader_start_prepare();
+            if (err_code != NRF_SUCCESS)
+            {
+                m_dfu.evt_handler(BLE_DFU_EVT_BOOTLOADER_ENTER_FAILED);
+            }
+        }
+    }
+}
+
+
+void ble_dfu_buttonless_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context)
+{
+    VERIFY_PARAM_NOT_NULL_VOID(p_ble_evt);
+
+    switch (p_ble_evt->header.evt_id)
+    {
+        case BLE_GAP_EVT_CONNECTED:
+            on_connect(p_ble_evt);
+            break;
+
+        case BLE_GAP_EVT_DISCONNECTED:
+            on_disconnect(p_ble_evt);
+            break;
+
+        case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST:
+            on_rw_authorize_req(p_ble_evt);
+            break;
+
+        case BLE_GATTS_EVT_HVC:
+            on_hvc(p_ble_evt);
+            break;
+
+        default:
+            // no implementation
+            break;
+    }
+}
+
+
+uint32_t ble_dfu_buttonless_resp_send(ble_dfu_buttonless_op_code_t op_code, ble_dfu_buttonless_rsp_code_t rsp_code)
+{
+    // Send indication
+    uint32_t                err_code;
+    const uint16_t          len = MAX_CTRL_POINT_RESP_PARAM_LEN;
+    uint16_t                hvx_len;
+    uint8_t                 hvx_data[MAX_CTRL_POINT_RESP_PARAM_LEN];
+    ble_gatts_hvx_params_t  hvx_params;
+
+    memset(&hvx_params, 0, sizeof(hvx_params));
+
+    hvx_len     = len;
+    hvx_data[0] = DFU_OP_RESPONSE_CODE;
+    hvx_data[1] = (uint8_t)op_code;
+    hvx_data[2] = (uint8_t)rsp_code;
+
+    hvx_params.handle = m_dfu.control_point_char.value_handle;
+    hvx_params.type   = BLE_GATT_HVX_INDICATION;
+    hvx_params.offset = 0;
+    hvx_params.p_len  = &hvx_len;
+    hvx_params.p_data = hvx_data;
+
+    err_code = sd_ble_gatts_hvx(m_dfu.conn_handle, &hvx_params);
+    if ((err_code == NRF_SUCCESS) && (hvx_len != len))
+    {
+        err_code = NRF_ERROR_DATA_SIZE;
+    }
+
+    return err_code;
+}
+
+
+uint32_t ble_dfu_buttonless_bootloader_start_finalize(void)
+{
+    uint32_t err_code;
+
+    NRF_LOG_DEBUG("In ble_dfu_buttonless_bootloader_start_finalize\r\n");
+
+    err_code = sd_power_gpregret_clr(0, 0xffffffff);
+    VERIFY_SUCCESS(err_code);
+
+    err_code = sd_power_gpregret_set(0, BOOTLOADER_DFU_START);
+    VERIFY_SUCCESS(err_code);
+
+    // Indicate that the Secure DFU bootloader will be entered
+    m_dfu.evt_handler(BLE_DFU_EVT_BOOTLOADER_ENTER);
+
+    // Signal that DFU mode is to be enter to the power management module
+    nrf_pwr_mgmt_shutdown(NRF_PWR_MGMT_SHUTDOWN_GOTO_DFU);
+
+    return NRF_SUCCESS;
+}
+
+
+uint32_t ble_dfu_buttonless_init(const ble_dfu_buttonless_init_t * p_dfu_init)
+{
+    uint32_t        err_code;
+    ble_uuid_t      service_uuid;
+    ble_uuid128_t   nordic_base_uuid = BLE_NORDIC_VENDOR_BASE_UUID;
+
+    VERIFY_PARAM_NOT_NULL(p_dfu_init);
+
+    // Initialize the service structure.
+    m_dfu.conn_handle                  = BLE_CONN_HANDLE_INVALID;
+    m_dfu.evt_handler                  = p_dfu_init->evt_handler;
+    m_dfu.is_waiting_for_reset         = false;
+
+    if (m_dfu.evt_handler == NULL)
+    {
+        m_dfu.evt_handler = dummy_evt_handler;
+    }
+
+    err_code = ble_dfu_buttonless_backend_init(&m_dfu);
+    VERIFY_SUCCESS(err_code);
+
+    BLE_UUID_BLE_ASSIGN(service_uuid, BLE_DFU_SERVICE_UUID);
+
+    // Add the DFU service declaration.
+    err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY,
+                                        &service_uuid,
+                                        &(m_dfu.service_handle));
+
+    VERIFY_SUCCESS(err_code);
+
+    // Add vendor specific base UUID to use with the Buttonless DFU characteristic.
+    err_code = sd_ble_uuid_vs_add(&nordic_base_uuid, &m_dfu.uuid_type);
+    VERIFY_SUCCESS(err_code);
+
+    // Add the Buttonless DFU Characteristic (with bonds/without bonds).
+    err_code = ble_dfu_buttonless_char_add(&m_dfu);
+    VERIFY_SUCCESS(err_code);
+
+    return NRF_SUCCESS;
+}

+ 249 - 0
shoe_mcu2.2.1_new_v2/ble_dfu/ble_dfu.h

@@ -0,0 +1,249 @@
+/**
+ * Copyright (c) 2012 - 2020, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ *    list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ *    Semiconductor ASA integrated circuit in a product or a software update for
+ *    such product, must reproduce the above copyright notice, this list of
+ *    conditions and the following disclaimer in the documentation and/or other
+ *    materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ *    contributors may be used to endorse or promote products derived from this
+ *    software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ *    Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ *    engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/** @file
+ *
+ * @defgroup ble_dfu Buttonless DFU Service
+ * @{
+ * @ingroup ble_sdk_srv
+ * @brief Buttonless DFU Service module.
+ *
+ * @details This module implements a proprietary Buttonless Secure DFU Service. The service can
+ *          be configured to support bonds or not. The bond support configuration must correspond to the
+ *          requirement of Secure DFU bootloader.
+ *
+ * @note Attention!
+ *  To maintain compliance with Nordic Semiconductor ASA Bluetooth profile
+ *  qualification listings, this section of source code must not be modified.
+ */
+
+#ifndef BLE_DFU_H__
+#define BLE_DFU_H__
+
+#include <stdint.h>
+#include "ble_srv_common.h"
+#include "nrf_sdh_ble.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**@brief   SoC observer priority.
+ * @details Priority of this module's SoC event handler.
+ */
+#define BLE_DFU_SOC_OBSERVER_PRIO   1
+
+#define BLE_DFU_BUTTONLESS_CHAR_UUID        (0x0003)    /**< Value combined with vendor-specific base to create Unbonded Buttonless characteristic UUID. */
+#define BLE_DFU_BUTTONLESS_BONDED_CHAR_UUID (0x0004)    /**< Value combined with vendor-specific base to create Bonded Buttonless characteristic UUID. */
+
+
+/**@brief Nordic vendor-specific base UUID.
+ */
+#define BLE_NORDIC_VENDOR_BASE_UUID                 \
+{{                                                  \
+    0x50, 0xEA, 0xDA, 0x30, 0x88, 0x83, 0xB8, 0x9F, \
+    0x60, 0x4F, 0x15, 0xF3, 0x00, 0x00, 0xC9, 0x8E  \
+}}
+
+
+/**@brief Nordic Buttonless DFU Service event type .
+ */
+typedef enum
+{
+    BLE_DFU_EVT_BOOTLOADER_ENTER_PREPARE,   /**< Event indicating that the device is preparing to enter bootloader.*/
+    BLE_DFU_EVT_BOOTLOADER_ENTER,           /**< Event indicating that the bootloader will be entered after return of this event.*/
+    BLE_DFU_EVT_BOOTLOADER_ENTER_FAILED,    /**< Failure to enter bootloader mode.*/
+    BLE_DFU_EVT_RESPONSE_SEND_ERROR,        /**< Failure to send response.*/
+} ble_dfu_buttonless_evt_type_t;
+
+
+/**@brief Nordic Buttonless DFU Service event handler type.
+ */
+typedef void (*ble_dfu_buttonless_evt_handler_t) (ble_dfu_buttonless_evt_type_t p_evt);
+/**@brief Enumeration of Bootloader DFU response codes.
+ */
+typedef enum
+{
+    DFU_RSP_INVALID               = 0x00,                                           /**< Invalid op code. */
+    DFU_RSP_SUCCESS               = 0x01,                                           /**< Success. */
+    DFU_RSP_OP_CODE_NOT_SUPPORTED = 0x02,                                           /**< Op code not supported. */
+    DFU_RSP_OPERATION_FAILED      = 0x04,                                           /**< Operation failed. */
+    DFU_RSP_ADV_NAME_INVALID      = 0x05,                                           /**< Requested advertisement name is too short or too long. */
+    DFU_RSP_BUSY                  = 0x06,                                           /**< Ongoing async operation. */
+    DFU_RSP_NOT_BONDED            = 0x07,                                           /**< Buttonless unavailable due to device not bonded. */
+} ble_dfu_buttonless_rsp_code_t;
+
+
+/**@brief Enumeration of Bootloader DFU Operation codes.
+ */
+typedef enum
+{
+    DFU_OP_RESERVED         = 0x00, /**< Reserved for future use. */
+    DFU_OP_ENTER_BOOTLOADER = 0x01, /**< Enter bootloader. */
+    DFU_OP_SET_ADV_NAME     = 0x02, /**< Set advertisement name to use in DFU mode. */
+    DFU_OP_RESPONSE_CODE    = 0x20  /**< Response code. */
+} ble_dfu_buttonless_op_code_t;
+
+
+/**@brief Type holding memory used by Secure DFU Buttonless Service.
+  */
+typedef struct
+{
+    uint8_t                             uuid_type;                      /**< UUID type for DFU UUID. */
+    uint16_t                            service_handle;                 /**< Service Handle of DFU (as provided by the SoftDevice). */
+    uint16_t                            conn_handle;                    /**< Connection handle for the current peer. */
+    ble_gatts_char_handles_t            control_point_char;             /**< Handles related to the DFU Control Point characteristic. */
+    uint32_t                            peers_count;                    /**< Counter to see how many persistently stored peers must be updated for Service Changed indication. This value will be counted down when comparing write requests. */
+    ble_dfu_buttonless_evt_handler_t    evt_handler;                    /**< Event handler that is called upon Buttonless DFU events. See @ref ble_dfu_buttonless_evt_type_t. */
+    bool                                is_waiting_for_reset;           /**< Flag indicating that the device will enter bootloader. */
+    bool                                is_waiting_for_svci;            /**< Flag indicating that the device is waiting for async SVCI operation */
+} ble_dfu_buttonless_t;
+
+
+/**@brief Type used to initialize the Secure DFU Buttonless Service.
+ */
+typedef struct
+{
+    ble_dfu_buttonless_evt_handler_t   evt_handler;                       /**< Bootloader event handler. */
+} ble_dfu_buttonless_init_t;
+
+
+/**@brief Function for initializing the Device Firmware Update module.
+ *
+ * @param[in]   p_dfu_init   Structure containing the values of characteristics needed by the
+ *                           service.
+ * @retval      NRF_SUCCESS on successful initialization of the service.
+ */
+uint32_t ble_dfu_buttonless_init(const ble_dfu_buttonless_init_t * p_dfu_init);
+
+
+/**@brief Function for initializing the async SVCI interface.
+ *
+ * @warning Ensure that no interrupts are triggered when calling this functions as
+ *          interrupts and exceptions are forwarded to the bootloader for the period
+ *          of the call and may be lost.
+ *
+ * @details This configures the async interface for calling to the
+ *          bootloader through SVCI interface.
+ *
+ * @retval NRF_SUCCESS on success, otherwise an error code.
+ */
+uint32_t ble_dfu_buttonless_async_svci_init(void);
+
+
+/**@brief Function to initialize the backend Secure DFU Buttonless service which is either
+ *        supports bonds or not.
+ *
+ * @note    Do not call this function directly. It is called internally by @ref ble_dfu_buttonless_init.
+ *
+ * @param[in] p_dfu     Nordic DFU Service structure.
+ *
+ * @return NRF_SUCCESS  On sucessfully initializing, otherwise an error code.
+ */
+uint32_t ble_dfu_buttonless_backend_init(ble_dfu_buttonless_t * p_dfu);
+
+
+
+/**@brief Function for adding the buttonless characteristic.
+ *
+ * @note This will be implemented differently on bonded/unbonded Buttonless DFU service.
+ *
+ * @param[in] p_dfu       Nordic DFU Service structure.
+ *
+ * @return NRF_SUCCESS on success, otherwise an error code.
+ */
+uint32_t ble_dfu_buttonless_char_add(ble_dfu_buttonless_t * p_dfu);
+
+
+/**@brief Function for sending a response back to the client.
+ *
+ * @param[in]   op_code     Operation code to send the response for.
+ * @param[in]   rsp_code    Response code for the operation.
+ *
+ * @retval NRF_SUCCESS on success, otherwise an error code.
+ */
+uint32_t ble_dfu_buttonless_resp_send(ble_dfu_buttonless_op_code_t op_code, ble_dfu_buttonless_rsp_code_t rsp_code);
+
+
+/**@brief Function for handling the application's BLE stack events.
+ *
+ * @details Handles all events from the BLE stack of interest to the DFU buttonless service.
+ *
+ * @param[in]   p_ble_evt   Event received from the BLE stack.
+ * @param[in]   p_context   BLE context structure.
+ */
+void ble_dfu_buttonless_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context);
+
+
+/**@brief Function for handling control point write requests.
+ *
+ * @details Handles write requests to the control point in
+ *          DFU with bonds or without bonds.
+ *
+ * @param[in]   p_evt_write     GATTS write event.
+ */
+void ble_dfu_buttonless_on_ctrl_pt_write(ble_gatts_evt_write_t const * p_evt_write);
+
+
+/**@brief Function for preparing to enter the bootloader.
+ *
+ * @warning This function is called directly. (It is called internally).
+ *
+ * @retval Any error code from calling @ref sd_ble_gap_disconnect.
+ */
+uint32_t ble_dfu_buttonless_bootloader_start_prepare(void);
+
+
+/**@brief Function for finalizing entering the bootloader.
+ *
+ * @warning This function is not to be called. (It is called internally).
+ *
+ * @retval NRF_SUCCESS Finalize was started correctly.
+ */
+uint32_t ble_dfu_buttonless_bootloader_start_finalize(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // BLE_DIS_H__
+
+/** @} */

+ 367 - 0
shoe_mcu2.2.1_new_v2/ble_dfu/ble_dfu_bonded.c

@@ -0,0 +1,367 @@
+/**
+ * Copyright (c) 2017 - 2020, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ *    list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ *    Semiconductor ASA integrated circuit in a product or a software update for
+ *    such product, must reproduce the above copyright notice, this list of
+ *    conditions and the following disclaimer in the documentation and/or other
+ *    materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ *    contributors may be used to endorse or promote products derived from this
+ *    software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ *    Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ *    engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include "nrf_dfu_ble_svci_bond_sharing.h"
+#include "nordic_common.h"
+#include "nrf_error.h"
+#include "ble_dfu.h"
+#include "nrf_log.h"
+#include "peer_manager.h"
+#include "gatts_cache_manager.h"
+#include "peer_id.h"
+#include "nrf_sdh_soc.h"
+#include "nrf_strerror.h"
+
+#if (NRF_DFU_BLE_BUTTONLESS_SUPPORTS_BONDS)
+
+
+void ble_dfu_buttonless_on_sys_evt(uint32_t, void * );
+uint32_t nrf_dfu_svci_vector_table_set(void);
+uint32_t nrf_dfu_svci_vector_table_unset(void);
+
+/**@brief Define function for async interface to set peer data. */
+NRF_SVCI_ASYNC_FUNC_DEFINE(NRF_DFU_SVCI_SET_PEER_DATA, nrf_dfu_set_peer_data, nrf_dfu_peer_data_t);
+
+// Register SoC observer for the Buttonless Secure DFU service
+NRF_SDH_SOC_OBSERVER(m_dfu_buttonless_soc_obs, BLE_DFU_SOC_OBSERVER_PRIO, ble_dfu_buttonless_on_sys_evt, NULL);
+
+ble_dfu_buttonless_t       * mp_dfu;
+static nrf_dfu_peer_data_t   m_peer_data;
+
+
+/**@brief Function for handling Peer Manager events.
+ *
+ * @param[in] p_evt  Peer Manager event.
+ */
+static void pm_evt_handler(pm_evt_t const * p_evt)
+{
+    uint32_t ret;
+
+    if (mp_dfu == NULL)
+    {
+        return;
+    }
+
+    // Only handle this when we are waiting to reset into DFU mode
+    if (!mp_dfu->is_waiting_for_reset)
+    {
+        return;
+    }
+
+    switch(p_evt->evt_id)
+    {
+        case PM_EVT_PEER_DATA_UPDATE_SUCCEEDED:
+            if (p_evt->params.peer_data_update_succeeded.data_id == PM_PEER_DATA_ID_SERVICE_CHANGED_PENDING)
+            {
+                mp_dfu->peers_count--;
+                NRF_LOG_DEBUG("Updating Service Changed indication for peers, %d left", mp_dfu->peers_count);
+                if (mp_dfu->peers_count == 0)
+                {
+                    NRF_LOG_DEBUG("Finished updating Service Changed indication for peers");
+                    // We have updated Service Changed Indication for all devices.
+                    ret = ble_dfu_buttonless_bootloader_start_finalize();
+                    if (ret != NRF_SUCCESS)
+                    {
+                        mp_dfu->evt_handler(BLE_DFU_EVT_BOOTLOADER_ENTER_FAILED);
+                    }
+                }
+            }
+            break;
+
+        case PM_EVT_PEER_DATA_UPDATE_FAILED:
+            // Failure to update data. Service Changed cannot be sent but DFU mode is still possible
+            ret = ble_dfu_buttonless_bootloader_start_finalize();
+            if (ret != NRF_SUCCESS)
+            {
+                mp_dfu->evt_handler(BLE_DFU_EVT_BOOTLOADER_ENTER_FAILED);
+            }
+            break;
+
+        default:
+            break;
+    }
+}
+
+
+static uint32_t retrieve_peer_data(void)
+{
+    ret_code_t              ret;
+    pm_peer_data_bonding_t  bonding_data = {0};
+    pm_peer_id_t            peer_id;
+
+    ret = pm_peer_id_get(mp_dfu->conn_handle, &peer_id);
+    VERIFY_SUCCESS(ret);
+
+    if (peer_id == PM_PEER_ID_INVALID)
+    {
+        return NRF_ERROR_FORBIDDEN;
+    }
+
+    ret = pm_peer_data_bonding_load(peer_id, &bonding_data);
+    VERIFY_SUCCESS(ret);
+
+    memcpy(&m_peer_data.ble_id,  &bonding_data.peer_ble_id, sizeof(ble_gap_id_key_t));
+    memcpy(&m_peer_data.enc_key, &bonding_data.own_ltk,     sizeof(ble_gap_enc_key_t));
+
+    uint16_t len = SYSTEM_SERVICE_ATT_SIZE;
+    ret = sd_ble_gatts_sys_attr_get(mp_dfu->conn_handle,
+                                    m_peer_data.sys_serv_attr,
+                                    &len,
+                                    BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS);
+
+    NRF_LOG_DEBUG("system attribute table len: %d", len);
+
+    return ret;
+}
+
+
+/**@brief Function for entering the bootloader.
+ *
+ * @details This starts forwarding peer data to the Secure DFU bootloader.
+ */
+static uint32_t enter_bootloader(void)
+{
+    uint32_t ret;
+
+    NRF_LOG_INFO("Writing peer data to the bootloader...");
+
+    if (mp_dfu->is_waiting_for_svci)
+    {
+        return ble_dfu_buttonless_resp_send(DFU_OP_ENTER_BOOTLOADER, DFU_RSP_BUSY);
+    }
+
+    // If retrieve_peer_data returns NRF_ERROR_FORBIDDEN, then the device was not bonded.
+    ret = retrieve_peer_data();
+    VERIFY_SUCCESS(ret);
+
+    ret = nrf_dfu_set_peer_data(&m_peer_data);
+    if (ret == NRF_SUCCESS)
+    {
+        // The request was accepted. Waiting for sys events to progress.
+        mp_dfu->is_waiting_for_svci = true;
+    }
+    else if (ret == NRF_ERROR_FORBIDDEN)
+    {
+        NRF_LOG_ERROR("The bootloader has write protected its settings page. This prohibits setting the peer data. "\
+                      "The bootloader must be compiled with NRF_BL_SETTINGS_PAGE_PROTECT=0 to allow setting the peer data.");
+    }
+
+    return ret;
+}
+
+
+uint32_t ble_dfu_buttonless_backend_init(ble_dfu_buttonless_t * p_dfu)
+{
+    VERIFY_PARAM_NOT_NULL(p_dfu);
+
+    // Set the memory used by the backend.
+    mp_dfu = p_dfu;
+
+    // Initialize the Peer manager handler.
+    return pm_register(pm_evt_handler);
+}
+
+
+uint32_t ble_dfu_buttonless_async_svci_init(void)
+{
+    uint32_t ret;
+
+    // Set the vector table base address to the bootloader.
+    ret = nrf_dfu_svci_vector_table_set();
+    NRF_LOG_DEBUG("nrf_dfu_svci_vector_table_set() -> %s",
+                  (ret == NRF_SUCCESS) ? "success" : nrf_strerror_get(ret));
+    VERIFY_SUCCESS(ret);
+
+    // Initialize the asynchronous SuperVisor interface to set peer data in Secure DFU bootloader.
+    ret = nrf_dfu_set_peer_data_init();
+    NRF_LOG_DEBUG("nrf_dfu_set_peer_data_init() -> %s",
+                  (ret == NRF_SUCCESS) ? "success" : nrf_strerror_get(ret));
+    VERIFY_SUCCESS(ret);
+
+    // Set the vector table base address back to main application.
+    ret = nrf_dfu_svci_vector_table_unset();
+    NRF_LOG_DEBUG("nrf_dfu_svci_vector_table_unset() -> %s",
+                  (ret == NRF_SUCCESS) ? "success" : nrf_strerror_get(ret));
+
+    return ret;
+}
+
+
+void ble_dfu_buttonless_on_sys_evt(uint32_t sys_evt, void * p_context)
+{
+    uint32_t ret;
+
+    if (!nrf_dfu_set_peer_data_is_initialized())
+    {
+        return;
+    }
+
+    ret = nrf_dfu_set_peer_data_on_sys_evt(sys_evt);
+    if (ret == NRF_ERROR_INVALID_STATE)
+    {
+        // The system event is not from an operation started by buttonless DFU.
+        // No action is taken, and nothing is reported.
+    }
+    else if (ret == NRF_SUCCESS)
+    {
+        // Peer data was successfully forwarded to the Secure DFU bootloader.
+        // Set the flag indicating that we are waiting for indication response
+        // to activate the reset.
+        mp_dfu->is_waiting_for_reset = true;
+        mp_dfu->is_waiting_for_svci  = false;
+
+        // Report back the positive response
+        ret = ble_dfu_buttonless_resp_send(DFU_OP_ENTER_BOOTLOADER, DFU_RSP_SUCCESS);
+        if (ret != NRF_SUCCESS)
+        {
+            mp_dfu->evt_handler(BLE_DFU_EVT_RESPONSE_SEND_ERROR);
+            mp_dfu->is_waiting_for_reset = false;
+        }
+    }
+    else
+    {
+        // Failed to set peer data. Report this.
+        mp_dfu->is_waiting_for_reset = false;
+        mp_dfu->is_waiting_for_svci  = false;
+        ret = ble_dfu_buttonless_resp_send(DFU_OP_ENTER_BOOTLOADER, DFU_RSP_BUSY);
+
+        // Report the failure to send the response to the client
+        if (ret != NRF_SUCCESS)
+        {
+            mp_dfu->evt_handler(BLE_DFU_EVT_RESPONSE_SEND_ERROR);
+        }
+
+        // Report the failure to enter DFU mode
+        mp_dfu->evt_handler(BLE_DFU_EVT_BOOTLOADER_ENTER_FAILED);
+    }
+}
+
+
+uint32_t ble_dfu_buttonless_char_add(ble_dfu_buttonless_t * p_dfu)
+{
+    ble_add_char_params_t add_char_params;
+
+    memset(&add_char_params, 0, sizeof(add_char_params));
+    add_char_params.uuid                = BLE_DFU_BUTTONLESS_BONDED_CHAR_UUID;
+    add_char_params.uuid_type           = p_dfu->uuid_type;
+    add_char_params.char_props.indicate = 1;
+    add_char_params.char_props.write    = 1;
+    add_char_params.is_defered_write    = true;
+    add_char_params.is_var_len          = true;
+    add_char_params.max_len             = BLE_GATT_ATT_MTU_DEFAULT;
+
+    add_char_params.cccd_write_access = SEC_JUST_WORKS;
+    add_char_params.write_access      = SEC_JUST_WORKS;
+    add_char_params.read_access       = SEC_OPEN;
+
+    return characteristic_add(p_dfu->service_handle, &add_char_params, &p_dfu->control_point_char);
+}
+
+
+void ble_dfu_buttonless_on_ctrl_pt_write(ble_gatts_evt_write_t const * p_evt_write)
+{
+    uint32_t ret;
+    ble_dfu_buttonless_rsp_code_t rsp_code = DFU_RSP_OPERATION_FAILED;
+
+    // Start executing the control point write action
+    switch (p_evt_write->data[0])
+    {
+        case DFU_OP_ENTER_BOOTLOADER:
+            ret = enter_bootloader();
+            if (ret == NRF_SUCCESS)
+            {
+                rsp_code = DFU_RSP_SUCCESS;
+            }
+            else if (ret == NRF_ERROR_BUSY)
+            {
+                rsp_code = DFU_RSP_BUSY;
+            }
+            else if (ret == NRF_ERROR_FORBIDDEN)
+            {
+                rsp_code = DFU_RSP_NOT_BONDED;
+            }
+            break;
+
+        default:
+            rsp_code = DFU_RSP_OP_CODE_NOT_SUPPORTED;
+            break;
+    }
+
+    // Report back in case of error
+    if (rsp_code != DFU_RSP_SUCCESS)
+    {
+        ret = ble_dfu_buttonless_resp_send((ble_dfu_buttonless_op_code_t)p_evt_write->data[0],
+                                            rsp_code);
+
+        if (ret != NRF_SUCCESS)
+        {
+            mp_dfu->evt_handler(BLE_DFU_EVT_RESPONSE_SEND_ERROR);
+        }
+
+        // Report the error to the main application
+        mp_dfu->evt_handler(BLE_DFU_EVT_BOOTLOADER_ENTER_FAILED);
+    }
+}
+
+
+uint32_t ble_dfu_buttonless_bootloader_start_prepare(void)
+{
+    NRF_LOG_DEBUG("In ble_dfu_buttonless_bootloader_start_prepare");
+
+    // Indicate to main app that DFU mode is starting.
+    // This event can be used to let the device take down any connection to
+    // bonded devices.
+    mp_dfu->evt_handler(BLE_DFU_EVT_BOOTLOADER_ENTER_PREPARE);
+
+    // Store the number of peers for which Peer Manager is expected to successfully write events.
+    mp_dfu->peers_count = peer_id_n_ids();
+
+    // Set local database changed to get Service Changed indication for all bonded peers
+    // on next bootup (either because of a successful or aborted DFU).
+    gscm_local_database_has_changed();
+
+    return NRF_SUCCESS;
+}
+
+#endif // NRF_DFU_BLE_BUTTONLESS_SUPPORTS_BONDS
+

+ 299 - 0
shoe_mcu2.2.1_new_v2/ble_dfu/ble_dfu_unbonded.c

@@ -0,0 +1,299 @@
+/**
+ * Copyright (c) 2017 - 2020, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ *    list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ *    Semiconductor ASA integrated circuit in a product or a software update for
+ *    such product, must reproduce the above copyright notice, this list of
+ *    conditions and the following disclaimer in the documentation and/or other
+ *    materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ *    contributors may be used to endorse or promote products derived from this
+ *    software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ *    Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ *    engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include "nrf_dfu_ble_svci_bond_sharing.h"
+#include "nordic_common.h"
+#include "nrf_error.h"
+#include "ble_dfu.h"
+#include "nrf_log.h"
+#include "nrf_sdh_soc.h"
+
+#if (!NRF_DFU_BLE_BUTTONLESS_SUPPORTS_BONDS)
+
+#define NRF_DFU_ADV_NAME_MAX_LENGTH     (20)
+
+
+void ble_dfu_buttonless_on_sys_evt(uint32_t, void * );
+uint32_t nrf_dfu_svci_vector_table_set(void);
+uint32_t nrf_dfu_svci_vector_table_unset(void);
+
+/**@brief Define functions for async interface to set new advertisement name for DFU mode.  */
+NRF_SVCI_ASYNC_FUNC_DEFINE(NRF_DFU_SVCI_SET_ADV_NAME, nrf_dfu_set_adv_name, nrf_dfu_adv_name_t);
+
+// Register SoC observer for the Buttonless Secure DFU service
+NRF_SDH_SOC_OBSERVER(m_dfu_buttonless_soc_obs, BLE_DFU_SOC_OBSERVER_PRIO, ble_dfu_buttonless_on_sys_evt, NULL);
+
+ble_dfu_buttonless_t      * mp_dfu = NULL;
+static nrf_dfu_adv_name_t   m_adv_name;
+
+
+/**@brief Function for setting an advertisement name.
+ *
+ * @param[in]   adv_name    The new advertisement name.
+ *
+ * @retval NRF_SUCCESS      Advertisement name was successfully set.
+ * @retval DFU_RSP_BUSY     Advertisement name was not set because of an ongoing operation.
+ * @retval Any other errors from the SVCI interface call.
+ */
+static uint32_t set_adv_name(nrf_dfu_adv_name_t * p_adv_name)
+{
+    uint32_t err_code;
+
+    if (mp_dfu->is_waiting_for_svci)
+    {
+        return DFU_RSP_BUSY;
+    }
+
+    err_code = nrf_dfu_set_adv_name(p_adv_name);
+    if (err_code == NRF_SUCCESS)
+    {
+        // The request was accepted.
+        mp_dfu->is_waiting_for_svci = true;
+    }
+    else if (err_code == NRF_ERROR_FORBIDDEN)
+    {
+        NRF_LOG_ERROR("The bootloader has write protected its settings page. This prohibits setting the advertising name. "\
+                      "The bootloader must be compiled with NRF_BL_SETTINGS_PAGE_PROTECT=0 to allow setting the advertising name.");
+    }
+
+    return err_code;
+}
+
+
+/**@brief Function for entering the bootloader.
+ */
+static uint32_t enter_bootloader()
+{
+    uint32_t err_code;
+
+    if (mp_dfu->is_waiting_for_svci)
+    {
+        // We have an ongoing async operation. Entering bootloader mode is not possible at this time.
+        err_code = ble_dfu_buttonless_resp_send(DFU_OP_ENTER_BOOTLOADER, DFU_RSP_BUSY);
+        if (err_code != NRF_SUCCESS)
+        {
+            mp_dfu->evt_handler(BLE_DFU_EVT_RESPONSE_SEND_ERROR);
+        }
+        return NRF_SUCCESS;
+    }
+
+    // Set the flag indicating that we expect DFU mode.
+    // This will be handled on acknowledgement of the characteristic indication.
+    mp_dfu->is_waiting_for_reset = true;
+
+    err_code = ble_dfu_buttonless_resp_send(DFU_OP_ENTER_BOOTLOADER, DFU_RSP_SUCCESS);
+    if (err_code != NRF_SUCCESS)
+    {
+        mp_dfu->is_waiting_for_reset = false;
+    }
+
+    return err_code;
+}
+
+
+uint32_t ble_dfu_buttonless_backend_init(ble_dfu_buttonless_t * p_dfu)
+{
+    VERIFY_PARAM_NOT_NULL(p_dfu);
+
+    mp_dfu = p_dfu;
+
+    return NRF_SUCCESS;
+}
+
+
+uint32_t ble_dfu_buttonless_async_svci_init(void)
+{
+    uint32_t ret_val;
+
+    ret_val = nrf_dfu_svci_vector_table_set();
+    VERIFY_SUCCESS(ret_val);
+
+    ret_val = nrf_dfu_set_adv_name_init();
+    VERIFY_SUCCESS(ret_val);
+
+    ret_val = nrf_dfu_svci_vector_table_unset();
+
+    return ret_val;
+}
+
+
+void ble_dfu_buttonless_on_sys_evt(uint32_t sys_evt, void * p_context)
+{
+    uint32_t err_code;
+
+    if (!nrf_dfu_set_adv_name_is_initialized())
+    {
+        return;
+    }
+
+    err_code = nrf_dfu_set_adv_name_on_sys_evt(sys_evt);
+    if (err_code == NRF_ERROR_INVALID_STATE)
+    {
+        // The system event is not from an operation started by buttonless DFU.
+        // No action is taken, and nothing is reported.
+    }
+    else if (err_code == NRF_SUCCESS)
+    {
+        // The async operation is finished.
+        // Set the flag indicating that we are waiting for indication response
+        // to activate the reset.
+        mp_dfu->is_waiting_for_svci = false;
+
+        // Report back the positive response
+        err_code = ble_dfu_buttonless_resp_send(DFU_OP_SET_ADV_NAME, DFU_RSP_SUCCESS);
+        if (err_code != NRF_SUCCESS)
+        {
+            mp_dfu->evt_handler(BLE_DFU_EVT_RESPONSE_SEND_ERROR);
+        }
+    }
+    else
+    {
+        // Invalid error code reported back.
+        mp_dfu->is_waiting_for_svci = false;
+
+        err_code = ble_dfu_buttonless_resp_send(DFU_OP_SET_ADV_NAME, DFU_RSP_BUSY);
+        if (err_code != NRF_SUCCESS)
+        {
+            mp_dfu->evt_handler(BLE_DFU_EVT_RESPONSE_SEND_ERROR);
+        }
+
+        // Report the failure to enter DFU mode
+        mp_dfu->evt_handler(BLE_DFU_EVT_BOOTLOADER_ENTER_FAILED);
+    }
+}
+
+
+uint32_t ble_dfu_buttonless_char_add(ble_dfu_buttonless_t * p_dfu)
+{
+    ble_add_char_params_t add_char_params;
+
+    memset(&add_char_params, 0, sizeof(add_char_params));
+    add_char_params.uuid                = BLE_DFU_BUTTONLESS_CHAR_UUID;
+    add_char_params.uuid_type           = p_dfu->uuid_type;
+    add_char_params.char_props.indicate = 1;
+    add_char_params.char_props.write    = 1;
+    add_char_params.is_defered_write    = true;
+    add_char_params.is_var_len          = true;
+    add_char_params.max_len             = BLE_GATT_ATT_MTU_DEFAULT;
+
+    add_char_params.cccd_write_access = SEC_OPEN;
+    add_char_params.write_access      = SEC_OPEN;
+    add_char_params.read_access       = SEC_OPEN;
+
+    return characteristic_add(p_dfu->service_handle, &add_char_params, &p_dfu->control_point_char);
+}
+
+
+void ble_dfu_buttonless_on_ctrl_pt_write(ble_gatts_evt_write_t const * p_evt_write)
+{
+    uint32_t err_code;
+    ble_dfu_buttonless_rsp_code_t rsp_code = DFU_RSP_OPERATION_FAILED;
+
+    // Start executing the control point write operation
+    /*lint -e415 -e416 -save "Out of bounds access"*/
+    switch (p_evt_write->data[0])
+    {
+        case DFU_OP_ENTER_BOOTLOADER:
+            err_code = enter_bootloader();
+            if (err_code == NRF_SUCCESS)
+            {
+                rsp_code = DFU_RSP_SUCCESS;
+            }
+            else if (err_code == NRF_ERROR_BUSY)
+            {
+                rsp_code = DFU_RSP_BUSY;
+            }
+            break;
+
+        case DFU_OP_SET_ADV_NAME:
+            if(    (p_evt_write->data[1] > NRF_DFU_ADV_NAME_MAX_LENGTH)
+                || (p_evt_write->data[1] == 0))
+            {
+                // New advertisement name too short or too long.
+                rsp_code = DFU_RSP_ADV_NAME_INVALID;
+            }
+            else
+            {
+                memcpy(m_adv_name.name, &p_evt_write->data[2], p_evt_write->data[1]);
+                m_adv_name.len = p_evt_write->data[1];
+                err_code = set_adv_name(&m_adv_name);
+                if (err_code == NRF_SUCCESS)
+                {
+                    rsp_code = DFU_RSP_SUCCESS;
+                }
+            }
+            break;
+
+        default:
+            rsp_code = DFU_RSP_OP_CODE_NOT_SUPPORTED;
+            break;
+    }
+    /*lint -restore*/
+
+
+    // Report back in case of error
+    if (rsp_code != DFU_RSP_SUCCESS)
+    {
+        err_code = ble_dfu_buttonless_resp_send((ble_dfu_buttonless_op_code_t)p_evt_write->data[0], rsp_code);
+        if (err_code != NRF_SUCCESS)
+        {
+            mp_dfu->evt_handler(BLE_DFU_EVT_RESPONSE_SEND_ERROR);
+
+        }
+        // Report the error to the main application
+        mp_dfu->evt_handler(BLE_DFU_EVT_BOOTLOADER_ENTER_FAILED);
+    }
+}
+
+uint32_t ble_dfu_buttonless_bootloader_start_prepare(void)
+{
+    uint32_t err_code;
+
+    // Indicate to main app that DFU mode is starting.
+    mp_dfu->evt_handler(BLE_DFU_EVT_BOOTLOADER_ENTER_PREPARE);
+
+    err_code = ble_dfu_buttonless_bootloader_start_finalize();
+    return err_code;
+}
+
+#endif // NRF_DFU_BOTTONLESS_SUPPORT_BOND

+ 271 - 0
shoe_mcu2.2.1_new_v2/bsp/bsp_adc.c

@@ -0,0 +1,271 @@
+/*********************************************************************
+ * INCLUDES
+ */
+#include "bsp_adc.h"
+#include "system.h"
+#include "exception.h"
+/*********************************************************************
+ * DEFINITIONS
+ */
+ #define CHANNEL_MAX							8
+ #define PIN_NOT_USED							0xFF
+ #define CHANNEL_NOT_USED					0xFF
+ #define WAIT_TIME_VALUE					10000								// 等待超时最大值
+/*********************************************************************
+ * STRUCTION
+ */
+typedef struct {
+	uint32_t pin;
+	uint32_t channel;
+}adc_config_t;
+/*********************************************************************
+ * LOCAL VARIABLES
+ */
+static adc_config_t									m_adc_config[CHANNEL_MAX] 	= {{PIN_NOT_USED,CHANNEL_NOT_USED},{PIN_NOT_USED,CHANNEL_NOT_USED},{PIN_NOT_USED,CHANNEL_NOT_USED},{PIN_NOT_USED,CHANNEL_NOT_USED},{PIN_NOT_USED,CHANNEL_NOT_USED},{PIN_NOT_USED,CHANNEL_NOT_USED},{PIN_NOT_USED,CHANNEL_NOT_USED},{PIN_NOT_USED,CHANNEL_NOT_USED}};
+static nrf_saadc_channel_config_t 	channelConfig[CHANNEL_MAX];
+static nrf_saadc_value_t 						s_bufferPool[CHANNEL_MAX] 	= {0};
+static volatile bool 								adc_SampleOk 								= true;		// adc采集完成标志
+//定义SAADC采样数据缓存
+//定义SAADC采样缓存数组大小
+//只有采样结果存满该缓存之后,才会产生SAADC采样完成事件
+static uint32_t 										sample_in_buffer 						= 0;
+/*********************************************************************
+ * LOCAL FUNCTIONS
+ */
+/**
+ @brief ADC中断处理回调函数
+ @param 无
+ @return 无
+*/
+static void adcCallbackFunc(nrf_drv_saadc_evt_t const *pEvent)
+{
+	ret_code_t err_code;
+	if(pEvent->type == NRF_DRV_SAADC_EVT_DONE)	// 采样完成,采集时填充顺序为,通道编号小的先填充。
+	{
+		//设置好缓存,为下一次采样做准备
+		err_code=nrf_drv_saadc_buffer_convert(pEvent->data.done.p_buffer,sample_in_buffer);
+		if(err_code == NRF_SUCCESS)
+		{
+			adc_SampleOk = true;
+		}
+	}
+}
+
+static void bsp_adc_init_process(void)
+{
+	if(Except_TxError(EXCEPT_ADC_INIT,"bsp_adc_init_error\r\n") == 0)
+	{
+		Process_Stop(bsp_adc_init_process);
+	}
+}
+
+/**
+	@brief	初始化ADC
+	@param	无
+	@return 无
+*/
+static void ADC_Init(void)
+{
+	int 				ret = 0;
+	ret_code_t 	errCode;
+	
+	nrf_drv_saadc_config_t p_config = NRFX_SAADC_DEFAULT_CONFIG;
+	p_config.interrupt_priority = ADC_IRQ_PRIORITY;
+	
+	
+	// ADC初始化
+	errCode = nrf_drv_saadc_init(&p_config, adcCallbackFunc);//优先级设置为3,比定时器中断要高,不然回调会在定时器中断结束后触发。
+	if(errCode != NRF_SUCCESS)ret = -1;
+	
+	// ADC通道配置
+	for(int i=0;i<CHANNEL_MAX;i++)
+	{
+		if(m_adc_config[i].pin != PIN_NOT_USED && m_adc_config[i].channel != CHANNEL_NOT_USED)
+		{
+			// ADC通道初始化
+			errCode = nrf_drv_saadc_channel_init(m_adc_config[i].channel, &channelConfig[m_adc_config[i].channel]);
+			if(errCode != NRF_SUCCESS)ret = -1;
+		}
+	}
+	
+	if(sample_in_buffer > 0)
+	{
+		// 缓冲配置
+		errCode = nrf_drv_saadc_buffer_convert(s_bufferPool, sample_in_buffer);
+		if(errCode != NRF_SUCCESS)ret = -1;
+	}
+	
+	
+	if(ret == -1)
+	{
+		Process_Start(0,"bsp_adc_init_process",bsp_adc_init_process);
+	}
+}
+static void cb_adcWakeup(uint32_t t)
+{
+	ADC_Enable(); 
+}
+
+static void cb_adcSleep(uint32_t t)
+{
+	ADC_Disable();
+}
+
+/*********************************************************************
+ * PUBLIC FUNCTIONS
+ */
+/**
+	@brief	初始化ADC引脚和通道
+	@param	pin -[in]	需要初始化的adc引脚
+	@param	channel -[in]	需要初始化的adc通道
+	@return 错误代码
+*/
+uint32_t ADC_SetPinChannel(uint32_t pin, uint32_t channel,nrf_gpio_pin_pull_t pin_pull)
+{
+	ret_code_t 	errCode;
+	
+	//清除已存在的引脚和通道
+	ADC_RemovePinChannel(pin, channel);
+	
+	for(int i=0;i<CHANNEL_MAX;i++)
+	{
+		if(m_adc_config[i].pin == PIN_NOT_USED && m_adc_config[i].channel == CHANNEL_NOT_USED && PIN_NOT_USED != pin)	
+		{
+			m_adc_config[i].pin = pin;
+			m_adc_config[i].channel = channel;
+			
+			//设置ADC引脚为浮空
+			nrf_gpio_cfg_input(m_adc_config[i].pin,pin_pull);
+			// 单端输入
+			channelConfig[m_adc_config[i].channel].resistor_p = NRF_SAADC_RESISTOR_DISABLED;
+			channelConfig[m_adc_config[i].channel].resistor_n = NRF_SAADC_RESISTOR_DISABLED;
+			channelConfig[m_adc_config[i].channel].gain       = NRF_SAADC_GAIN1_6;
+			channelConfig[m_adc_config[i].channel].reference  = NRF_SAADC_REFERENCE_INTERNAL;
+			channelConfig[m_adc_config[i].channel].acq_time   = NRF_SAADC_ACQTIME_10US;
+			channelConfig[m_adc_config[i].channel].mode       = NRF_SAADC_MODE_SINGLE_ENDED;
+			channelConfig[m_adc_config[i].channel].burst      = NRF_SAADC_BURST_DISABLED;
+			channelConfig[m_adc_config[i].channel].pin_p      = (nrf_saadc_input_t)(m_adc_config[i].channel + 1);
+			channelConfig[m_adc_config[i].channel].pin_n      = NRF_SAADC_INPUT_DISABLED;
+			// ADC通道初始化
+			errCode = nrf_drv_saadc_channel_init(m_adc_config[i].channel, &channelConfig[m_adc_config[i].channel]);
+			if(errCode != NRF_SUCCESS)return ADC_ERR_INIT_CONGESTION;
+			
+			sample_in_buffer++;
+			
+//			SEGGER_RTT_printf(0, "add channel (  %d  ):\n", channel);
+
+			return ADC_OP_SUCCESS;
+		}
+	}
+	return ADC_ERR_INIT_CONGESTION;
+}
+/**
+	@brief	移除已初始化ADC引脚和通道
+	@param	pin -[in]	需要移除的adc引脚
+	@param	channel -[in]	需要移除的adc通道
+	@return 错误代码
+*/
+uint32_t ADC_RemovePinChannel(uint32_t pin, uint32_t channel)
+{
+	for(int i=0;i<CHANNEL_MAX;i++)
+	{
+		if(m_adc_config[i].pin == pin && m_adc_config[i].channel == channel)
+		{
+			nrf_drv_saadc_channel_uninit(m_adc_config[i].channel);
+			m_adc_config[i].pin = PIN_NOT_USED;
+			m_adc_config[i].channel = CHANNEL_NOT_USED;
+			if(sample_in_buffer != 0)sample_in_buffer--;
+			
+//			SEGGER_RTT_printf(0, "del channel (  %d  ):\n", channel);
+			return ADC_OP_SUCCESS;
+		}
+	}
+	return ADC_ERR_REMOVE_PIN_CHANNEL;
+}
+/**
+	@brief ADC初始化
+	@param 无
+	@return 无
+*/
+void ADC_Initialize(void)
+{
+	ADC_SetPinChannel(PIN_ADC_BAT_IN, PIN_ADC_BAT_CHANNEL,NRF_GPIO_PIN_NOPULL);
+	ADC_SetPinChannel(PIN_ADC_CHARGMEASURE, PIN_ADC_CHARGMEASURE_CHANNEL,NRF_GPIO_PIN_NOPULL);
+	ADC_Init();
+	Wakeup_Regist(cb_adcWakeup);
+	Sleep_Regist(cb_adcSleep);
+}
+/**
+	@brief ADC读取
+	@param channel -[in] 需要读取的通道
+	@param p_adc_value -[out] 返回读取的通道值
+	@return 错误代码
+*/
+uint32_t ADC_Read(uint32_t channel, int16_t *p_adc_value)
+{
+	uint32_t errCode;
+	uint32_t wait_time_out = WAIT_TIME_VALUE;
+	uint8_t  adc_sort[CHANNEL_MAX] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF};
+	uint8_t  sort_index = 0;
+	int  		 i;
+	adc_SampleOk = false;
+	
+	//没有配置通道返回失败
+	if(sample_in_buffer == 0)return ADC_ERR_READ_NO_CHANNEL;
+	
+	errCode = nrf_drv_saadc_sample();
+	if(errCode != NRF_SUCCESS)return ADC_ERR_READ_FAIL;
+	
+	//等待采集
+	while(!adc_SampleOk)
+	{
+		if(wait_time_out--){
+//			nrf_pwr_mgmt_run();
+		}
+		else{
+			return ADC_ERR_READ_TIMEOUT;
+		}
+	}
+	//预先排序,采集时填充顺序为,通道编号小的先填充。
+	for(i=0;i<CHANNEL_MAX;i++)
+	{
+		if(channelConfig[i].pin_p != NRF_SAADC_INPUT_DISABLED){
+			adc_sort[sort_index] = i;
+			sort_index++;
+		}
+	}
+	//获取数据
+	for(i=0;i<sample_in_buffer;i++)
+	{
+		if(adc_sort[i] == channel)
+		{
+			*p_adc_value = s_bufferPool[i];
+		}
+	}
+
+	return ADC_OP_SUCCESS;
+}
+/**
+ @brief 开启ADC,与初始化没有区别,为了与Disable成对出现
+ @param 无
+ @return 无
+*/
+void ADC_Enable(void)
+{
+	ADC_Init();
+}
+/**
+ @brief 禁用ADC
+ @param 无
+ @return 无
+*/
+void ADC_Disable(void)
+{
+	nrf_drv_saadc_uninit();
+}
+
+
+
+
+
+

+ 60 - 0
shoe_mcu2.2.1_new_v2/bsp/bsp_adc.h

@@ -0,0 +1,60 @@
+#ifndef	__BSP_ADC_H__
+#define __BSP_ADC_H__
+/*********************************************************************
+ * INCLUDES
+ */
+#include <stdbool.h>
+#include <stdint.h>
+#include <string.h>
+#include "sdk_common.h"
+#include "SEGGER_RTT.h"
+#include "usr_config.h"
+#include "nrf_gpio.h"
+#include "nrf_pwr_mgmt.h"
+#include "nrf_drv_saadc.h"
+/*********************************************************************
+ * DEFINITIONS
+ */
+//ERROR CODE
+#define ADC_OP_SUCCESS										0x00													//adc操作成功
+#define ADC_ERR_INIT_PIN									0x01													//该引脚已初始化
+#define ADC_ERR_INIT_CHANNEL							0x02													//该通道已初始化
+#define ADC_ERR_INIT_CONGESTION						0x03													//有效通道已全部初始化
+#define ADC_ERR_REMOVE_PIN_CHANNEL				0x04													//移除通道和引脚失败
+#define ADC_ERR_READ_NO_CHANNEL						0x05													//无配置通道,读取失败
+#define ADC_ERR_READ_TIMEOUT							0x06													//读取adc超时
+#define ADC_ERR_READ_FAIL									0x07													//读取adc失败
+/*********************************************************************
+ * API
+ */
+ 
+//初始化ADC引脚和通道
+uint32_t ADC_SetPinChannel(uint32_t pin, uint32_t channel,nrf_gpio_pin_pull_t pin_pull);
+//移除已初始化ADC引脚和通道
+uint32_t ADC_RemovePinChannel(uint32_t pin, uint32_t channel);
+//ADC初始化
+void ADC_Initialize(void);
+//ADC读取
+uint32_t ADC_Read(uint32_t channel, int16_t *p_adc_value);
+//开启ADC,与初始化没有区别,为了与Disable成对出现
+void ADC_Enable(void);
+//禁用ADC
+void ADC_Disable(void);
+
+#endif
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

+ 190 - 0
shoe_mcu2.2.1_new_v2/bsp/bsp_esb.c

@@ -0,0 +1,190 @@
+/********************** 头文件 *************************/
+#include "bsp_esb.h"
+#include "nrf_esb.h"
+#include "nrf_error.h"
+#include "nrf_esb_error_codes.h"
+#include "hal_imu.h"
+
+/********************** 变量区 *************************/
+static nrf_esb_payload_t        tx_payload = NRF_ESB_CREATE_PAYLOAD(0, 0x01, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00);
+static nrf_esb_payload_t        rx_payload;
+
+/********************** 环形缓存区 *************************/
+static const int  RxLen = 1024;
+static volatile unsigned char RxBuf[RxLen];
+static volatile unsigned char* RxW=RxBuf;
+static volatile unsigned char* RxR=RxBuf;
+
+void ESB_Push(unsigned char* p,int len)
+{
+	volatile unsigned char *W=RxW; //这里要与上面指针相同
+	if(len<=0) return;
+	for(int i=0;i<len;i++){
+		W=RxW+1; if(W>=RxBuf+RxLen) W=RxBuf;        //取下一位置(到顶转到底)
+		if(W!=RxR){*RxW=*(p+i); RxW=W;}
+		else break;
+	}
+}
+
+unsigned int ESB_CheckLen(void) //检查RX接收了多少数据
+{   
+	unsigned int Len; //short 
+	volatile unsigned char *W=RxW; volatile unsigned char *R=RxR; 
+	if(W>=R)Len=W-R;else Len=(W+RxLen)-R;         //这样正确(中途中断改变也变不了结果)
+    return Len; 
+}
+
+unsigned char ESB_ReadByte(void)   //读RX中数锯,地指加一,和丢弃
+{	
+	unsigned char R=*RxR;       //读数
+	if(RxR!=RxW){	if(RxR+1>=(RxBuf+RxLen))RxR =RxBuf; else RxR++;}//下标
+	return R; 
+}
+
+unsigned char ESB_CheckByte(unsigned short n) //看RX中数锯,地指不变, 
+{  	
+	volatile unsigned char *R=RxR+n; 
+	if(R>=(RxBuf+RxLen))R-=RxLen; 
+	return *R; 
+}	
+
+void ESB_Discard(unsigned short n) //丢弃RX数据几位  
+{	
+	while(n){ n--;  
+		if(RxR==RxW) return; 
+		if(RxR+1>=RxBuf+RxLen){RxR=RxBuf;} else RxR++; //下标 
+	}	
+}
+//static void Radio_State(void)
+//{
+//        switch(NRF_RADIO->STATE)
+//        {
+//                case RADIO_STATE_STATE_Disabled:
+//                        DEBUG_LOG("RADIO_STATE_STATE_Disabled\n");
+//                        break;
+//                case RADIO_STATE_STATE_RxRu:
+//                        DEBUG_LOG("RADIO_STATE_STATE_RxRu\n");
+//                        break;
+//                case RADIO_STATE_STATE_RxIdle:
+//                        DEBUG_LOG("RADIO_STATE_STATE_RxIdle\n");
+//                        break;
+//                case RADIO_STATE_STATE_Rx:
+//                        DEBUG_LOG("RADIO_STATE_STATE_Rx\n");
+//                        break;
+//                case RADIO_STATE_STATE_RxDisable:
+//                        DEBUG_LOG("RADIO_STATE_STATE_RxDisable\n");
+//                        break;
+//                case RADIO_STATE_STATE_TxRu:
+//                        DEBUG_LOG("RADIO_STATE_STATE_TxRu\n");
+//                        break;
+//                case RADIO_STATE_STATE_TxIdle:
+//                        DEBUG_LOG("RADIO_STATE_STATE_TxIdle\n");
+//                        break;
+//                case RADIO_STATE_STATE_Tx:
+//                        DEBUG_LOG("RADIO_STATE_STATE_Tx\n");
+//                        break;
+//                case RADIO_STATE_STATE_TxDisable:
+//                        DEBUG_LOG("RADIO_STATE_STATE_TxDisable\n");
+//                        break;
+//        }
+//}
+
+#define ESB_COMMAND_LENGTH_MAX  200
+void ESB_SendBuff(unsigned char *p,int L)//发送缓存
+{
+	uint8_t i;
+	if(L>ESB_COMMAND_LENGTH_MAX) return;
+	
+	
+//	
+	(void) nrf_esb_stop_rx();
+	
+//	Radio_State();
+	
+	for(i=0;i<L;i++){
+		tx_payload.data[i] = p[i];
+	}
+	tx_payload.noack = false;
+	tx_payload.length = L;
+	nrf_esb_write_payload(&tx_payload);
+}
+
+//*****************************************************************//
+
+/********************** 函数声明区 *************************/
+void nrf_esb_event_handler(nrf_esb_evt_t const * p_event)
+{
+    switch (p_event->evt_id)
+    {
+        case NRF_ESB_EVENT_TX_SUCCESS:
+//			DEBUG_LOG("NRF_ESB_EVENT_TX_SUCCESS\n");
+			(void) nrf_esb_flush_tx();
+            (void) nrf_esb_start_rx();
+            break;
+        case NRF_ESB_EVENT_TX_FAILED:
+//			DEBUG_LOG("NRF_ESB_EVENT_TX_FAILED\n");
+            (void) nrf_esb_flush_tx();
+            (void) nrf_esb_start_rx();
+            break;
+        case NRF_ESB_EVENT_RX_RECEIVED:
+//			DEBUG_LOG("NRF_ESB_EVENT_RX_RECEIVED\n");
+            while (nrf_esb_read_rx_payload(&rx_payload) == NRF_SUCCESS){
+                if(rx_payload.length > 0){
+					#if DEBUG_ESB_INT
+					DEBUG_LOG("INT_ESB:"); for(int i=0;i<rx_payload.length;i++){DEBUG_LOG("%02X ",rx_payload.data[i]);} DEBUG_LOG("\r\n");
+					#endif
+					
+					IMU_SetRssi(rx_payload.rssi);
+					if(rx_payload.data[0]==0xAA && rx_payload.data[1]==(uint8_t)(~rx_payload.data[2])){
+						if(rx_payload.data[3]==0){ //IMU data		
+							IMU_SetSlaveData(rx_payload.data,rx_payload.length);
+						}else
+						ESB_Push(rx_payload.data,rx_payload.length);
+					}
+                }
+            }
+            break;
+    }
+}
+
+#define  ADDR ESB_ADDR
+
+uint32_t ESB_Init(void)
+{
+    uint32_t err_code;
+    uint8_t base_addr_0[4] = {0x01, 0x01, ADDR, ADDR};
+    uint8_t base_addr_1[4] = {0x01, 0x01, ADDR, ADDR};
+    uint8_t addr_prefix[8] = {0x01, 0x01, 0x01, 0x01, ADDR, ADDR, ADDR, ADDR };
+
+    nrf_esb_config_t nrf_esb_config         = NRF_ESB_DEFAULT_CONFIG;
+//    nrf_esb_config.protocol                 = NRF_ESB_PROTOCOL_ESB_DPL;
+	nrf_esb_config.payload_length           = 250;
+//    nrf_esb_config.retransmit_delay         = 600;
+//	nrf_esb_config.payload_length           = ESB_COMMAND_LENGTH_MAX;
+    nrf_esb_config.bitrate                  = NRF_ESB_BITRATE_2MBPS;
+    nrf_esb_config.event_handler            = nrf_esb_event_handler;
+    nrf_esb_config.mode                     = NRF_ESB_MODE_PTX;
+    nrf_esb_config.selective_auto_ack       = false;
+
+    err_code = nrf_esb_init(&nrf_esb_config);
+
+    VERIFY_SUCCESS(err_code);
+
+    err_code = nrf_esb_set_base_address_0(base_addr_0);
+    VERIFY_SUCCESS(err_code);
+
+    err_code = nrf_esb_set_base_address_1(base_addr_1);
+    VERIFY_SUCCESS(err_code);
+
+    err_code = nrf_esb_set_prefixes(addr_prefix, NRF_ESB_PIPE_COUNT);
+    VERIFY_SUCCESS(err_code);
+	
+	(void) nrf_esb_flush_tx();
+	(void) nrf_esb_start_rx();
+//	uint8_t temp = 0;
+//	ESB_SendBuff(&temp,1);
+	
+    return err_code;
+}
+
+

+ 20 - 0
shoe_mcu2.2.1_new_v2/bsp/bsp_esb.h

@@ -0,0 +1,20 @@
+#ifndef __bsp_esb_h__
+#define __bsp_esb_h__
+#include <stdbool.h>
+#include <stdint.h>
+#include <string.h>
+#include "sdk_common.h"
+#include "SEGGER_RTT.h"
+#include "usr_config.h"
+
+uint32_t ESB_Init(void);
+//void ESB_SendStr(char *p);//发送字符串
+void ESB_SendBuff(unsigned char *p,int L);//发送缓存
+//void ESB_SendChar(unsigned char ch);//发送一位数锯
+void ESB_Discard(unsigned short n); //丢弃RX数据几位  
+unsigned char ESB_CheckByte(unsigned short n); //看RX中数锯,地指不变, 
+unsigned char ESB_ReadByte(void);   //读RX中数锯,地指加一,和丢弃
+unsigned int ESB_CheckLen(void); //检查RX接收了多少数据
+void ESB_Test(void);
+
+#endif

+ 106 - 0
shoe_mcu2.2.1_new_v2/bsp/bsp_flash.c

@@ -0,0 +1,106 @@
+
+//flash 1.0V
+
+/*********************************************************************
+ * INCLUDES
+ */
+#include "bsp_flash.h"
+#include "exception.h"
+#include "system.h"
+#include "nrf_sdh_soc.h"
+#include "nrf_pwr_mgmt.h"
+#include "nrf_sdm.h"
+
+typedef enum
+{
+    NRF_STATE_IDLE,    //FALSH空闲
+    NRF_STATE_BUSY,    //FLASH忙
+} falsh_busy_state;
+
+typedef enum
+{
+    NRF_FLASH_OPERATION_IDLE,            //!< No operations requested to the SoftDevice.
+	  NRF_FLASH_OPERATION_FINISH
+} nrf_flash_sd_state_t;
+
+static volatile falsh_busy_state BUSY_FLAG =NRF_STATE_IDLE;
+static volatile nrf_flash_sd_state_t FLASH_OP_state =NRF_FLASH_OPERATION_IDLE;
+
+//等待flash操作完成
+static void waitForFlashReady(void)
+{
+	  uint8_t flag =0;
+	
+	  //没有打开协议栈直接退出
+	  sd_softdevice_is_enabled(&flag);
+	  if(0 == flag){
+			 BUSY_FLAG = NRF_STATE_IDLE;
+			 FLASH_OP_state =NRF_FLASH_OPERATION_FINISH;
+			 return;
+		}
+		
+    while(BUSY_FLAG != NRF_STATE_IDLE)										// While fstorage is busy, sleep and wait for an event.
+    {
+       nrf_pwr_mgmt_run();
+    }
+}
+
+void flash_evt_handler(uint32_t sys_evt, void *p_context)
+{
+    //UNUSED_PARAMETER(p_context);
+//    DEBUG_LOG(" NRF_EVT_FLASH_OPERATION_SUCCESS\r\n");
+	  
+    if ((sys_evt != NRF_EVT_FLASH_OPERATION_SUCCESS) && (sys_evt != NRF_EVT_FLASH_OPERATION_ERROR))
+    {
+        return;
+    }
+    switch (sys_evt)
+    {
+			case NRF_EVT_FLASH_OPERATION_SUCCESS:
+				   BUSY_FLAG =NRF_STATE_IDLE;
+					 FLASH_OP_state =NRF_FLASH_OPERATION_FINISH;
+					 break;
+			case NRF_EVT_FLASH_OPERATION_ERROR:
+				   BUSY_FLAG =NRF_STATE_IDLE;
+					 break;
+    }
+}
+
+NRF_SDH_SOC_OBSERVER(m_sys_obs, 0, flash_evt_handler, NULL);
+
+
+flash_OPER_Result sdflash_write(uint32_t *p_dst, uint32_t const *p_src, uint32_t sizewords)
+{
+	  if ((unsigned int)p_dst + (sizewords * 4) > END_FSTORAGE_ADDR || (unsigned int)p_dst < START_FSTORAGE_ADDR)
+    {
+        DEBUG_LOG(" ----------------------------sd_flash_write,0x%x 0x%x %d\r\n",  (unsigned int)p_dst, (unsigned int)p_src, sizewords);
+        return FLASH_ERROR_ADDRESS_FAIL;
+    }
+		
+		BUSY_FLAG =NRF_STATE_BUSY;
+		FLASH_OP_state =NRF_FLASH_OPERATION_IDLE;
+    sd_flash_write(p_dst, p_src, sizewords);
+	  waitForFlashReady();
+	
+    if(NRF_FLASH_OPERATION_FINISH != FLASH_OP_state)return FLASH_ERROR_WRITE_FAIL;
+    return FLASH_OP_SUCCESS;
+}
+
+flash_OPER_Result sdflash_page_erase(uint32_t page_addr)
+{  
+	  if(page_addr % 4 != 0 || page_addr == 0)return FLASH_ERROR_ADDRESS_FAIL;
+	
+    uint32_t page_number = page_addr / FLASH_PAGE_SIZE;
+	  BUSY_FLAG =NRF_STATE_BUSY;
+		FLASH_OP_state =NRF_FLASH_OPERATION_IDLE;
+    sd_flash_page_erase(page_number);
+	  waitForFlashReady();
+	
+	  if(NRF_FLASH_OPERATION_FINISH != FLASH_OP_state)return FLASH_ERROR_ERASE_FAIL;
+//	  DEBUG_LOG(">>>>>>>>>>sdflash_page_erase FLASH_OP_SUCCESS,%02x\r\n",page_addr);
+    return FLASH_OP_SUCCESS;
+}
+
+
+
+/****************************************************END OF FILE****************************************************/

+ 39 - 0
shoe_mcu2.2.1_new_v2/bsp/bsp_flash.h

@@ -0,0 +1,39 @@
+#ifndef __BSP_FLASH_H__
+#define __BSP_FLASH_H__
+
+//flash 1.0V
+
+/*********************************************************************
+ * INCLUDES
+ */
+ 
+#include "nrf_fstorage.h"
+#include "nrf_fstorage_sd.h"
+#include "nrf_pwr_mgmt.h"
+#include "nrf_soc.h"
+#include "nrf_log.h"
+#include "app_error.h"
+#include "SEGGER_RTT.h"
+
+#define FLASH_PAGE_SIZE											4096	
+#define PAGE_INT_SIZE												(FLASH_PAGE_SIZE/4)		//一页所包含的4字节个数
+#define START_FSTORAGE_ADDR									0x00074000UL		//FLASH起始地址
+#define END_FSTORAGE_ADDR										0x00078000UL		//FLASH结束地址
+
+//ERROR CODE
+		
+typedef enum{
+	FLASH_OP_SUCCESS =0,      //ZONE操作成功
+	FLASH_ERROR_READ_FAIL,    //读取该区域失败
+	FLASH_ERROR_WRITE_FAIL,   //写入该区域失败
+	FLASH_ERROR_ERASE_FAIL,   //擦除该区域失败
+	FLASH_ERROR_ADDRESS_FAIL, //输入地址越界
+}flash_OPER_Result;
+
+
+flash_OPER_Result sdflash_write(uint32_t *p_dst, uint32_t const *p_src, uint32_t sizewords);
+flash_OPER_Result sdflash_page_erase(uint32_t page_addr);
+
+#endif
+
+

+ 16 - 0
shoe_mcu2.2.1_new_v2/bsp/bsp_gpio.c

@@ -0,0 +1,16 @@
+#include "bsp_gpio.h"
+#include "nrf_gpio.h"
+#include "usr_config.h"
+#include "bsp_time.h"
+#include "usr.h"
+/********************** ±äÁ¿Çø *************************/
+
+
+/********************** º¯ÊýÉùÃ÷Çø *************************/
+
+void GPIO_Init(void)
+{
+
+}
+
+

+ 12 - 0
shoe_mcu2.2.1_new_v2/bsp/bsp_gpio.h

@@ -0,0 +1,12 @@
+#ifndef __bsp_gpio_h__
+#define __bsp_gpio_h__
+#include <stdbool.h>
+#include <stdint.h>
+#include <string.h>
+#include "sdk_common.h"
+#include "SEGGER_RTT.h"
+#include "usr_config.h"
+
+void GPIO_Init(void);
+
+#endif

+ 230 - 0
shoe_mcu2.2.1_new_v2/bsp/bsp_interface.c

@@ -0,0 +1,230 @@
+///********************** 头文件 *************************/
+#include "bsp_interface.h"
+
+///********************** 变量区 *************************/
+////extern int16_t gyro[3];
+////extern int16_t accel[3];
+//extern uint16_t press;
+
+
+
+/********************** 函数声明区 *************************/
+
+////发给匿名飞控
+//void sen_ANO_data_to_host(void)
+//{
+//	uint8_t buf[256];
+//	uint8_t L=0;
+//	
+//	
+//	int16_t roll  = (int16_t)(getRoll()*100);
+//	int16_t pitch = (int16_t)(getPitch()*100);
+//	int16_t yaw   = (int16_t)(getYaw()*100);
+//	
+//	buf[L++] = 0xAA; //帧头
+//	buf[L++] = 0x05; //发送设备
+//	buf[L++] = 0xAF; //目标设备
+//	buf[L++] = 0x01; //功能字
+//	buf[L++] = 0x01; //LEN
+//	
+//	buf[L++] = (uint8_t)(roll>>0);
+//	buf[L++] = (uint8_t)(roll>>8);
+
+//	buf[L++] = (uint8_t)(pitch>>0);
+//	buf[L++] = (uint8_t)(pitch>>8);
+
+//	buf[L++] = (uint8_t)(yaw>>0);
+//	buf[L++] = (uint8_t)(yaw>>8);
+//	
+//	buf[L++] = 0;
+//	buf[L++] = 0;
+//	buf[L++] = 0;
+//	buf[L++] = 0;
+//	
+//	buf[L++] = 0;
+//	
+//	buf[L++] = 0;
+//	
+//	buf[L++] = 0;
+//	
+//	
+//	
+////	buf[L++] = (uint8_t)(mMPU9250.acc_x>>0);
+////	buf[L++] = (uint8_t)(mMPU9250.acc_x>>8);
+////	
+////	buf[L++] = (uint8_t)(mMPU9250.acc_y>>0);
+////	buf[L++] = (uint8_t)(mMPU9250.acc_y>>8);
+////	
+////	buf[L++] = (uint8_t)(mMPU9250.acc_z>>0);
+////	buf[L++] = (uint8_t)(mMPU9250.acc_z>>8);
+//	
+//	buf[L++] = (uint8_t)(mMPU9250.mag_x>>0);
+//	buf[L++] = (uint8_t)(mMPU9250.mag_x>>8);
+//	
+//	buf[L++] = (uint8_t)(mMPU9250.mag_y>>0);
+//	buf[L++] = (uint8_t)(mMPU9250.mag_y>>8);
+//	
+//	buf[L++] = (uint8_t)(mMPU9250.mag_z>>0);
+//	buf[L++] = (uint8_t)(mMPU9250.mag_z>>8);
+//	
+//	buf[L++] = (uint8_t)(mMPU9250.gyro_x>>0);
+//	buf[L++] = (uint8_t)(mMPU9250.gyro_x>>8);
+//	
+//	buf[L++] = (uint8_t)(mMPU9250.gyro_y>>0);
+//	buf[L++] = (uint8_t)(mMPU9250.gyro_y>>8);
+//	
+//	buf[L++] = (uint8_t)(mMPU9250.gyro_z>>0);
+//	buf[L++] = (uint8_t)(mMPU9250.gyro_z>>8);
+
+//	buf[L++] = (uint8_t)(roll>>0);
+//	buf[L++] = (uint8_t)(roll>>8);
+
+//	buf[L++] = (uint8_t)(pitch>>0);
+//	buf[L++] = (uint8_t)(pitch>>8);
+
+//	buf[L++] = (uint8_t)(yaw>>0);
+//	buf[L++] = (uint8_t)(yaw>>8);
+//	
+//	bsp_esb_send(buf,L); //发送出去
+//}
+
+//void sen_data_to_host(void)
+//{
+//	uint8_t buf[256];
+//	uint8_t L=0;
+//	
+//	int32_t roll, pitch, yaw;
+//	
+//	buf[L++] = (uint8_t)(press>>8);
+//	buf[L++] = (uint8_t)(press>>0);
+//	
+//	roll = (int32_t)(getRoll()*100);
+//	pitch = (int32_t)(getPitch()*100);
+//	yaw = (int32_t)(getYaw()*100);
+//	
+//	buf[L++] = (uint8_t)(roll>>24);
+//	buf[L++] = (uint8_t)(roll>>16);
+//	buf[L++] = (uint8_t)(roll>>8);
+//	buf[L++] = (uint8_t)(roll>>0);
+//	
+//	buf[L++] = (uint8_t)(pitch>>24);
+//	buf[L++] = (uint8_t)(pitch>>16);
+//	buf[L++] = (uint8_t)(pitch>>8);
+//	buf[L++] = (uint8_t)(pitch>>0);
+//	
+//	buf[L++] = (uint8_t)(yaw>>24);
+//	buf[L++] = (uint8_t)(yaw>>16);
+//	buf[L++] = (uint8_t)(yaw>>8);
+//	buf[L++] = (uint8_t)(yaw>>0);
+////	
+////	buf[L++] = (uint8_t)(accel[0]>>8);
+////	buf[L++] = (uint8_t)(accel[0]>>0);
+////	
+////	buf[L++] = (uint8_t)(accel[1]>>8);
+////	buf[L++] = (uint8_t)(accel[1]>>0);
+////	
+////	buf[L++] = (uint8_t)(accel[2]>>8);
+////	buf[L++] = (uint8_t)(accel[2]>>0);
+////	
+////	buf[L++] = (uint8_t)(gyro[0]>>8);
+////	buf[L++] = (uint8_t)(gyro[0]>>0);
+////	
+////	buf[L++] = (uint8_t)(gyro[1]>>8);
+////	buf[L++] = (uint8_t)(gyro[1]>>0);
+////	
+////	buf[L++] = (uint8_t)(gyro[2]>>8);
+////	buf[L++] = (uint8_t)(gyro[2]>>0);
+//	
+//	send_protocol(DEX_NUM,CMD_HEART,buf,L);
+//}
+
+
+////发给维特智能上位机显示
+//void sen_wit_motion_data_to_host(void)
+//{
+//	uint8_t buf[256];
+//	uint8_t L=0;
+//	
+//	
+//	int16_t roll  = (int16_t)(getRoll()/180.0f*32768.0f);
+//	int16_t pitch = (int16_t)(getPitch()/180.0f*32768.0f);
+//	int16_t yaw   = (int16_t)(getYaw()/180.0f*32768.0f);
+//	
+//	buf[L++] = 0x55;
+//	buf[L++] = 0x61;
+//	
+////	buf[L++] = (uint8_t)(mMPU9250.acc_x>>0);
+////	buf[L++] = (uint8_t)(mMPU9250.acc_x>>8);
+////	
+////	buf[L++] = (uint8_t)(mMPU9250.acc_y>>0);
+////	buf[L++] = (uint8_t)(mMPU9250.acc_y>>8);
+////	
+////	buf[L++] = (uint8_t)(mMPU9250.acc_z>>0);
+////	buf[L++] = (uint8_t)(mMPU9250.acc_z>>8);
+//	
+//	buf[L++] = (uint8_t)(mMPU9250.mag_x>>0);
+//	buf[L++] = (uint8_t)(mMPU9250.mag_x>>8);
+//	
+//	buf[L++] = (uint8_t)(mMPU9250.mag_y>>0);
+//	buf[L++] = (uint8_t)(mMPU9250.mag_y>>8);
+//	
+//	buf[L++] = (uint8_t)(mMPU9250.mag_z>>0);
+//	buf[L++] = (uint8_t)(mMPU9250.mag_z>>8);
+//	
+//	buf[L++] = (uint8_t)(mMPU9250.gyro_x>>0);
+//	buf[L++] = (uint8_t)(mMPU9250.gyro_x>>8);
+//	
+//	buf[L++] = (uint8_t)(mMPU9250.gyro_y>>0);
+//	buf[L++] = (uint8_t)(mMPU9250.gyro_y>>8);
+//	
+//	buf[L++] = (uint8_t)(mMPU9250.gyro_z>>0);
+//	buf[L++] = (uint8_t)(mMPU9250.gyro_z>>8);
+
+//	buf[L++] = (uint8_t)(roll>>0);
+//	buf[L++] = (uint8_t)(roll>>8);
+
+//	buf[L++] = (uint8_t)(pitch>>0);
+//	buf[L++] = (uint8_t)(pitch>>8);
+
+//	buf[L++] = (uint8_t)(yaw>>0);
+//	buf[L++] = (uint8_t)(yaw>>8);
+//	
+////	bsp_esb_send(buf,L); //发送出去
+//	for(int i=0;i<L;i++) app_uart_put(buf[i]);
+//}
+
+//static uint8_t send_motion = 0;
+//static uint8_t send_ts = 0;
+//static uint8_t send_times = 0;
+//void send_motion_to_phone(uint8_t motion,uint16_t ts)
+//{
+//	send_motion = motion;
+//	send_ts = ts;
+//	send_times = 10;
+////	uint8_t buf[16];
+////	uint8_t L=0;
+
+////	buf[L++] = motion;
+////	
+////	buf[L++] = (uint8_t)(ts>>8);
+////	buf[L++] = (uint8_t)(ts>>0);
+////	
+////	for(int i = 0; i <5; i++)
+////		send_protocol(DEX_NUM,CMD_MOTION,buf,L);
+//}
+
+//void send_to_phone_process(void)
+//{
+//	uint8_t buf[16];
+//	uint8_t L=0;
+
+//	if(send_times>0){
+//		send_times--;
+//		buf[L++] = send_motion;
+//		buf[L++] = (uint8_t)(send_ts>>8);
+//		buf[L++] = (uint8_t)(send_ts>>0);
+//		send_protocol(DEX_NUM,CMD_MOTION,buf,L);
+//	}
+//}
+
+

+ 10 - 0
shoe_mcu2.2.1_new_v2/bsp/bsp_interface.h

@@ -0,0 +1,10 @@
+#ifndef __bsp_interface_h__
+#define __bsp_interface_h__
+#include "main.h"
+
+void sen_data_to_host(void);
+void send_to_phone_process(void);
+void send_motion_to_phone(uint8_t motion,uint16_t ts);
+void sen_wit_motion_data_to_host(void);
+	
+#endif

+ 84 - 0
shoe_mcu2.2.1_new_v2/bsp/bsp_mpu9250.c

@@ -0,0 +1,84 @@
+#include "main.h"
+
+
+//**************************************
+//写入一个字节数据
+//**************************************
+bool MPU9250_Write_Byte(uint8_t Device_Address,uint8_t REG_Address,uint8_t REG_data)
+{
+	uint8_t buf[2];
+//	DEBUG_LOG("MPU9250_Write_Byte\n");
+    buf[0] = REG_Address;
+    buf[1] = REG_data;
+    return twi_master_transfer(Device_Address, buf, 2, TWI_ISSUE_STOP);
+}
+//**************************************
+//读取N个字节数据
+//**************************************
+bool MPU9250_Read_nBytes(uint8_t Device_Address,uint8_t REG_Address,uint8_t *readDataBuf,uint8_t readDataLen)
+{
+	bool ret;
+    ret  = twi_master_transfer(Device_Address, &REG_Address, 1, TWI_DONT_ISSUE_STOP);
+    ret &= twi_master_transfer(Device_Address|TWI_READ_BIT, readDataBuf, readDataLen, TWI_ISSUE_STOP);
+    return ret;
+}
+
+bool MPU9250_register_write_len(uint8_t Device_Address,uint8_t register_address, uint8_t len,uint8_t *buf)
+{
+    uint8_t w2_data[50],i;
+
+    w2_data[0] = register_address;
+	  for(i=0;i<len;i++)w2_data[i+1] = *(buf+i);
+
+	  
+	  if(twi_master_transfer(Device_Address, w2_data, len+1, TWI_ISSUE_STOP) == true)return 0;
+	  else return true;
+}
+
+bool MPU9250_register_read_len(uint8_t Device_Address,uint8_t register_address, uint8_t number_of_bytes,uint8_t * destination )
+{
+    bool transfer_succeeded;
+    transfer_succeeded  = twi_master_transfer(Device_Address, &register_address, 1, TWI_DONT_ISSUE_STOP);
+    transfer_succeeded &= twi_master_transfer(Device_Address|TWI_READ_BIT, destination, number_of_bytes, TWI_ISSUE_STOP);
+    
+	  if(transfer_succeeded == true)return 0;
+	  else return true;
+}
+
+int MPU9250_init(void)
+{
+	if(!MPU9250_Write_Byte(MPU9250_I2C_ADDR,MPU9250_PWR_MGMT_1,0x80)) return 1;                //复位所有寄存器,复位完后自动进入睡眠模式,所以要sleep位要清0
+	nrf_delay_ms(5);
+	if(!MPU9250_Write_Byte(MPU9250_I2C_ADDR,MPU9250_PWR_MGMT_1,0x00)) return 1;			//唤醒mpu9250
+	if(!MPU9250_Write_Byte(MPU9250_I2C_ADDR,MPU9250_SMPLRT_DIV,0x07)) return 2;    		
+	if(!MPU9250_Write_Byte(MPU9250_I2C_ADDR,MPU9250_CONFIG,0x00)) return 3;    			//低通滤波5hz
+	if(!MPU9250_Write_Byte(MPU9250_I2C_ADDR,MPU9250_GYRO_CONFIG,0x18)) return 4;			//不自检,2000deg/s
+	if(!MPU9250_Write_Byte(MPU9250_I2C_ADDR,MPU9250_ACCEL_CONFIG,0x18)) return 5;			//(0x00 +-2g;)  ( 0x08 +-4g;)  (0x10 +-8g;)  (0x18 +-16g)
+	if(!MPU9250_Write_Byte(MPU9250_I2C_ADDR,MPU9250_ACCEL_CONFIG_2,0x04)) return 6;			//
+	if(!MPU9250_Write_Byte(MPU9250_I2C_ADDR,MPU9250_INT_PIN_CFG,0x02)) return 7;
+	if(!MPU9250_Write_Byte(MPU9250_I2C_ADDR,MPU9250_USER_CTRL,0x00)) return 8;				//使能I2C
+	if(!MPU9250_Write_Byte(AK8963_I2C_ADDR,AK8963_CNTL1,0x0f)) return 9;
+	return 0;
+}
+
+int MPU9250_Read(int16_t* acc,int16_t* gyr,int16_t* mag,int16_t* temperature)
+{
+	uint8_t buf[14],bufM[6];    			
+	if(!MPU9250_Read_nBytes(MPU9250_I2C_ADDR,MPU9250_ACCEL_XOUT_H,  buf, 14)) 	return -1;//读取加速度,温度,陀螺仪传感器
+	if(!MPU9250_Read_nBytes(AK8963_I2C_ADDR,AK8963_HXL,  bufM, 6)) 				return -2;//读取地磁传感器
+	if(!MPU9250_Write_Byte(AK8963_I2C_ADDR,AK8963_CNTL1,0x11)) 					return -3;//每读一次数据,ak8963会自动进入powerdown模式,这里需要重新设定为单测量模式
+	acc[0]  = ((int16_t)buf[0]<<8)|((int16_t)buf[1]);
+	acc[1]  = ((int16_t)buf[2]<<8)|((int16_t)buf[3]);
+	acc[2]  = ((int16_t)buf[4]<<8)|((int16_t)buf[5]);
+	temperature[0]   = ((int16_t)buf[6]<<8)|((int16_t)buf[7]);
+	gyr[0] = ((int16_t)buf[8]<<8)|((int16_t)buf[9]);
+	gyr[1] = ((int16_t)buf[10]<<8)|((int16_t)buf[11]);
+	gyr[2] = ((int16_t)buf[12]<<8)|((int16_t)buf[13]);
+	mag[0]  = ((int16_t)bufM[1]<<8)|((int16_t)bufM[0]);
+	mag[1]  = ((int16_t)bufM[3]<<8)|((int16_t)bufM[2]);
+	mag[2]  = ((int16_t)bufM[5]<<8)|((int16_t)bufM[4]);
+	return 0;
+}
+
+
+

+ 143 - 0
shoe_mcu2.2.1_new_v2/bsp/bsp_mpu9250.h

@@ -0,0 +1,143 @@
+#ifndef __bsp_mpu9250_H
+#define __bsp_mpu9250_H
+#include "main.h"
+
+/* ---- MPU9250 Reg In MPU9250 ---------------------------------------------- */
+
+#define MPU9250_I2C_ADDR            ((uint8_t)0xD0)
+#define MPU9250_Device_ID           ((uint8_t)0x71)  // In MPU9250
+
+#define MPU9250_SELF_TEST_XG        ((uint8_t)0x00)
+#define MPU9250_SELF_TEST_YG        ((uint8_t)0x01)
+#define MPU9250_SELF_TEST_ZG        ((uint8_t)0x02)
+#define MPU9250_SELF_TEST_XA        ((uint8_t)0x0D)
+#define MPU9250_SELF_TEST_YA        ((uint8_t)0x0E)
+#define MPU9250_SELF_TEST_ZA        ((uint8_t)0x0F)
+#define MPU9250_XG_OFFSET_H         ((uint8_t)0x13)
+#define MPU9250_XG_OFFSET_L         ((uint8_t)0x14)
+#define MPU9250_YG_OFFSET_H         ((uint8_t)0x15)
+#define MPU9250_YG_OFFSET_L         ((uint8_t)0x16)
+#define MPU9250_ZG_OFFSET_H         ((uint8_t)0x17)
+#define MPU9250_ZG_OFFSET_L         ((uint8_t)0x18)
+#define MPU9250_SMPLRT_DIV          ((uint8_t)0x19)
+#define MPU9250_CONFIG              ((uint8_t)0x1A)
+#define MPU9250_GYRO_CONFIG         ((uint8_t)0x1B)
+#define MPU9250_ACCEL_CONFIG        ((uint8_t)0x1C)
+#define MPU9250_ACCEL_CONFIG_2      ((uint8_t)0x1D)
+#define MPU9250_LP_ACCEL_ODR        ((uint8_t)0x1E)
+#define MPU9250_MOT_THR             ((uint8_t)0x1F)
+#define MPU9250_FIFO_EN             ((uint8_t)0x23)
+#define MPU9250_I2C_MST_CTRL        ((uint8_t)0x24)
+#define MPU9250_I2C_SLV0_ADDR       ((uint8_t)0x25)
+#define MPU9250_I2C_SLV0_REG        ((uint8_t)0x26)
+#define MPU9250_I2C_SLV0_CTRL       ((uint8_t)0x27)
+#define MPU9250_I2C_SLV1_ADDR       ((uint8_t)0x28)
+#define MPU9250_I2C_SLV1_REG        ((uint8_t)0x29)
+#define MPU9250_I2C_SLV1_CTRL       ((uint8_t)0x2A)
+#define MPU9250_I2C_SLV2_ADDR       ((uint8_t)0x2B)
+#define MPU9250_I2C_SLV2_REG        ((uint8_t)0x2C)
+#define MPU9250_I2C_SLV2_CTRL       ((uint8_t)0x2D)
+#define MPU9250_I2C_SLV3_ADDR       ((uint8_t)0x2E)
+#define MPU9250_I2C_SLV3_REG        ((uint8_t)0x2F)
+#define MPU9250_I2C_SLV3_CTRL       ((uint8_t)0x30)
+#define MPU9250_I2C_SLV4_ADDR       ((uint8_t)0x31)
+#define MPU9250_I2C_SLV4_REG        ((uint8_t)0x32)
+#define MPU9250_I2C_SLV4_DO         ((uint8_t)0x33)
+#define MPU9250_I2C_SLV4_CTRL       ((uint8_t)0x34)
+#define MPU9250_I2C_SLV4_DI         ((uint8_t)0x35)
+#define MPU9250_I2C_MST_STATUS      ((uint8_t)0x36)
+#define MPU9250_INT_PIN_CFG         ((uint8_t)0x37)
+#define MPU9250_INT_ENABLE          ((uint8_t)0x38)
+#define MPU9250_INT_STATUS          ((uint8_t)0x3A)
+#define MPU9250_ACCEL_XOUT_H        ((uint8_t)0x3B)
+#define MPU9250_ACCEL_XOUT_L        ((uint8_t)0x3C)
+#define MPU9250_ACCEL_YOUT_H        ((uint8_t)0x3D)
+#define MPU9250_ACCEL_YOUT_L        ((uint8_t)0x3E)
+#define MPU9250_ACCEL_ZOUT_H        ((uint8_t)0x3F)
+#define MPU9250_ACCEL_ZOUT_L        ((uint8_t)0x40)
+#define MPU9250_TEMP_OUT_H          ((uint8_t)0x41)
+#define MPU9250_TEMP_OUT_L          ((uint8_t)0x42)
+#define MPU9250_GYRO_XOUT_H         ((uint8_t)0x43)
+#define MPU9250_GYRO_XOUT_L         ((uint8_t)0x44)
+#define MPU9250_GYRO_YOUT_H         ((uint8_t)0x45)
+#define MPU9250_GYRO_YOUT_L         ((uint8_t)0x46)
+#define MPU9250_GYRO_ZOUT_H         ((uint8_t)0x47)
+#define MPU9250_GYRO_ZOUT_L         ((uint8_t)0x48)
+#define MPU9250_EXT_SENS_DATA_00    ((uint8_t)0x49)
+#define MPU9250_EXT_SENS_DATA_01    ((uint8_t)0x4A)
+#define MPU9250_EXT_SENS_DATA_02    ((uint8_t)0x4B)
+#define MPU9250_EXT_SENS_DATA_03    ((uint8_t)0x4C)
+#define MPU9250_EXT_SENS_DATA_04    ((uint8_t)0x4D)
+#define MPU9250_EXT_SENS_DATA_05    ((uint8_t)0x4E)
+#define MPU9250_EXT_SENS_DATA_06    ((uint8_t)0x4F)
+#define MPU9250_EXT_SENS_DATA_07    ((uint8_t)0x50)
+#define MPU9250_EXT_SENS_DATA_08    ((uint8_t)0x51)
+#define MPU9250_EXT_SENS_DATA_09    ((uint8_t)0x52)
+#define MPU9250_EXT_SENS_DATA_10    ((uint8_t)0x53)
+#define MPU9250_EXT_SENS_DATA_11    ((uint8_t)0x54)
+#define MPU9250_EXT_SENS_DATA_12    ((uint8_t)0x55)
+#define MPU9250_EXT_SENS_DATA_13    ((uint8_t)0x56)
+#define MPU9250_EXT_SENS_DATA_14    ((uint8_t)0x57)
+#define MPU9250_EXT_SENS_DATA_15    ((uint8_t)0x58)
+#define MPU9250_EXT_SENS_DATA_16    ((uint8_t)0x59)
+#define MPU9250_EXT_SENS_DATA_17    ((uint8_t)0x5A)
+#define MPU9250_EXT_SENS_DATA_18    ((uint8_t)0x5B)
+#define MPU9250_EXT_SENS_DATA_19    ((uint8_t)0x5C)
+#define MPU9250_EXT_SENS_DATA_20    ((uint8_t)0x5D)
+#define MPU9250_EXT_SENS_DATA_21    ((uint8_t)0x5E)
+#define MPU9250_EXT_SENS_DATA_22    ((uint8_t)0x5F)
+#define MPU9250_EXT_SENS_DATA_23    ((uint8_t)0x60)
+#define MPU9250_I2C_SLV0_DO         ((uint8_t)0x63)
+#define MPU9250_I2C_SLV1_DO         ((uint8_t)0x64)
+#define MPU9250_I2C_SLV2_DO         ((uint8_t)0x65)
+#define MPU9250_I2C_SLV3_DO         ((uint8_t)0x66)
+#define MPU9250_I2C_MST_DELAY_CTRL  ((uint8_t)0x67)
+#define MPU9250_SIGNAL_PATH_RESET   ((uint8_t)0x68)
+#define MPU9250_MOT_DETECT_CTRL     ((uint8_t)0x69)
+#define MPU9250_USER_CTRL           ((uint8_t)0x6A)
+#define MPU9250_PWR_MGMT_1          ((uint8_t)0x6B)
+#define MPU9250_PWR_MGMT_2          ((uint8_t)0x6C)
+#define MPU9250_FIFO_COUNTH         ((uint8_t)0x72)
+#define MPU9250_FIFO_COUNTL         ((uint8_t)0x73)
+#define MPU9250_FIFO_R_W            ((uint8_t)0x74)
+#define MPU9250_WHO_AM_I            ((uint8_t)0x75)	// ID = 0x71 In MPU9250
+#define MPU9250_XA_OFFSET_H         ((uint8_t)0x77)
+#define MPU9250_XA_OFFSET_L         ((uint8_t)0x78)
+#define MPU9250_YA_OFFSET_H         ((uint8_t)0x7A)
+#define MPU9250_YA_OFFSET_L         ((uint8_t)0x7B)
+#define MPU9250_ZA_OFFSET_H         ((uint8_t)0x7D)
+#define MPU9250_ZA_OFFSET_L         ((uint8_t)0x7E)
+
+/* ---- AK8963 Reg In MPU9250 ----------------------------------------------- */
+
+#define AK8963_I2C_ADDR             ((uint8_t)0x18)
+#define AK8963_Device_ID            ((uint8_t)0x48)
+
+// Read-only Reg
+#define AK8963_WIA                  ((uint8_t)0x00)
+#define AK8963_INFO                 ((uint8_t)0x01)
+#define AK8963_ST1                  ((uint8_t)0x02)
+#define AK8963_HXL                  ((uint8_t)0x03)
+#define AK8963_HXH                  ((uint8_t)0x04)
+#define AK8963_HYL                  ((uint8_t)0x05)
+#define AK8963_HYH                  ((uint8_t)0x06)
+#define AK8963_HZL                  ((uint8_t)0x07)
+#define AK8963_HZH                  ((uint8_t)0x08)
+#define AK8963_ST2                  ((uint8_t)0x09)
+// Write/Read Reg
+#define AK8963_CNTL1                ((uint8_t)0x0A)
+#define AK8963_CNTL2                ((uint8_t)0x0B)
+#define AK8963_ASTC                 ((uint8_t)0x0C)
+#define AK8963_TS1                  ((uint8_t)0x0D)
+#define AK8963_TS2                  ((uint8_t)0x0E)
+#define AK8963_I2CDIS               ((uint8_t)0x0F)
+// Read-only Reg ( ROM )
+#define AK8963_ASAX                 ((uint8_t)0x10)
+#define AK8963_ASAY                 ((uint8_t)0x11)
+#define AK8963_ASAZ                 ((uint8_t)0x12)
+
+
+int MPU9250_init(void);
+int MPU9250_Read(int16_t* acc,int16_t* gyr,int16_t* mag,int16_t* temperature);
+#endif
+

+ 91 - 0
shoe_mcu2.2.1_new_v2/bsp/bsp_ms5611.c

@@ -0,0 +1,91 @@
+#include "main.h"
+
+//#define MSE5611_Slave 0xEC   	//½Ó¸ß
+//#define MSE5611_Slave 0xEE	//½ÓµÍ
+
+#define MSE5611_Reset 0x1E
+#define Convert_D1_256 0x40
+#define Convert_D1_512 0x42
+#define Convert_D1_1024 0x44
+#define Convert_D1_2048 0x46
+#define Convert_D1_4096 0x48
+#define Convert_D2_256 0x50
+#define Convert_D2_512 0x52
+#define Convert_D2_1024 0x54
+#define Convert_D2_2048 0x56
+#define Convert_D2_4096 0x58
+#define ADC_Read 0x00
+
+#define PROM_Read_0 0xA0
+#define PROM_Read_1 0xA2
+#define PROM_Read_2 0xA4
+#define PROM_Read_3 0xA6
+#define PROM_Read_4 0xA8
+#define PROM_Read_5 0xAA
+#define PROM_Read_6 0xAC
+#define PROM_Read_7 0xAE
+
+#define Sea_Level_Pressure 101325.0
+uint16_t Reserve = 0;
+uint16_t CFG[6] = {0};
+uint16_t MSE5611_CRC = 0;
+uint32_t D[2] = {0};
+
+//int32_t Temp = 0;
+//int32_t Press = 0;
+//float Height = 0;
+
+int MSE5611_register_write_len(uint8_t addr,uint8_t register_address, uint8_t len,uint8_t *buf)
+{
+	uint8_t w2_data[50],i;
+	w2_data[0] = register_address;
+	for(i=0;i<len;i++){
+		w2_data[i+1] = *(buf+i);
+	}
+	if(twi_master_transfer(addr, w2_data, len+1, TWI_ISSUE_STOP) == true) return 0;
+	else return -1;
+}
+
+int MSE5611_register_read_len(uint8_t addr,uint8_t register_address, uint8_t number_of_bytes,uint8_t * destination )
+{
+    bool transfer_succeeded;
+    transfer_succeeded  = twi_master_transfer(addr, &register_address, 1, TWI_DONT_ISSUE_STOP);
+    transfer_succeeded &= twi_master_transfer(addr|TWI_READ_BIT, destination, number_of_bytes, TWI_ISSUE_STOP);
+    
+	  if(transfer_succeeded == true)return 0;
+	  else return -1;
+}
+
+void ReadPressure_Pre(void)
+{
+	uint8_t dat = 0;
+	//I2C_WriteByte(I2C1,MSE5611_Slave,Convert_D1_4096);
+	MSE5611_register_write_len(MSE5611_Slave, Convert_D1_256, 0, &dat);
+}
+uint32_t ReadPressure(void)
+{
+	uint8_t dd[3] = {0,0,0};
+	uint8_t R = 0;
+	
+	MSE5611_register_read_len(MSE5611_Slave,R,3,dd);
+	D[0] = ((uint32_t)(dd[0]<<16)|(dd[1]<<8)|(dd[2]<<0));
+	return D[0];
+}
+
+int MS5611_Init(void)
+{
+	uint8_t i;
+	uint8_t dd[2];
+	MSE5611_register_read_len(MSE5611_Slave,PROM_Read_0,2,dd);
+	Reserve = ((uint16_t)dd[0]<<8|dd[1]);
+	DEBUG_LOG("MSE5611_Config:");
+	for(i=0;i<6;i++){
+		MSE5611_register_read_len(MSE5611_Slave,PROM_Read_1+i*2,2,dd);
+		CFG[i] = ((uint16_t)dd[0]<<8 | dd[1]);
+		DEBUG_LOG("%02X ",CFG[i]);
+	}
+	DEBUG_LOG("\n");
+	MSE5611_register_read_len(MSE5611_Slave,PROM_Read_7,2,dd);
+	MSE5611_CRC = ((uint16_t)dd[0]<<8|dd[1]);
+}
+

+ 10 - 0
shoe_mcu2.2.1_new_v2/bsp/bsp_ms5611.h

@@ -0,0 +1,10 @@
+#ifndef __bsp_ms5611_h_
+#define __bsp_ms5611_h_
+
+#include "main.h"
+
+int MS5611_Init(void);
+int MS5611_Read_RawData_Pre(void);
+int MS5611_Read_RawData(uint32_t* p);
+
+#endif

+ 32 - 0
shoe_mcu2.2.1_new_v2/bsp/bsp_protocol.c

@@ -0,0 +1,32 @@
+/********************** 头文件 *************************/
+#include "bsp_protocol.h"
+
+/********************** 变量区 *************************/
+
+
+/********************** 函数声明区 *************************/
+void send_protocol(uint8_t index,uint8_t cmd,uint8_t* dat,uint8_t datLen)
+{
+	uint8_t buf[128];
+	uint16_t Len = datLen+5;
+	uint16_t L=0;
+	uint8_t i;
+	uint8_t ver = 0;
+	
+	if(Len>128) return;
+	
+	buf[L++] = 0xAA;  ver += 0xAA;	//帧头
+//	buf[L++] = 0xBB;  ver += 0xBB; 	//帧头
+//	buf[L++] = 0xCC;  ver += 0xCC; 	//帧头
+	buf[L++] = Len;   ver += Len;	//长度
+	buf[L++] = ~Len;  ver += (~Len);//长度反码
+//	buf[L++] = index; ver += index;	//设备号
+	buf[L++] = cmd;   ver += cmd;	//命令
+	for(i=0;i<datLen;i++){ buf[L++] = dat[i]; ver += dat[i];} //数据
+	buf[L++] = ver;   				//校验
+	
+	ESB_SendBuff(buf,L); //发送出去
+}
+
+
+

+ 32 - 0
shoe_mcu2.2.1_new_v2/bsp/bsp_protocol.h

@@ -0,0 +1,32 @@
+#ifndef __bsp_protocol_h__
+#define __bsp_protocol_h__
+#include "main.h"
+
+#define DEX_NUM 0
+
+enum _cmd{
+		CMD_HEART = 0,
+		CMD_MOTION,
+	};
+enum _CMD_MOTION{
+		MOTION_STOP = 0,
+		MOTION_RUN,
+		MOTION_JUMP,
+		MOTION_DOWN,
+		MOTION_LEFT,
+		MOTION_RIGHT,
+		MOTION_FRONT,
+		MOTION_BACK,
+		MOTION_LEFT_UP,
+		MOTION_LEFT_DOWN,
+		MOTION_RIGHT_UP,
+		MOTION_RIGHT_DOWN,
+		MOTION_STEP,
+	
+		NUMBERS_OF_MOTION,
+	};
+
+void send_protocol(uint8_t index,uint8_t cmd,uint8_t* dat,uint8_t datLen);
+
+
+#endif

+ 467 - 0
shoe_mcu2.2.1_new_v2/bsp/bsp_pwm.c

@@ -0,0 +1,467 @@
+/*********************************************************************
+ * INCLUDES
+ */
+#include "sdk_common.h"
+#include "SEGGER_RTT.h"
+#include "usr_config.h"
+#include "exception.h"
+#include "system.h"
+#include "nrf_gpio.h"
+#include "bsp_pwm.h"
+
+/*********************************************************************
+ * DEFINITIONS
+ */
+#define PWM_INSTANCE						0
+
+#define PWM1_INSTANCE						1
+
+/*********************************************************************
+ * LOCAL VARIABLES
+ */
+static nrf_drv_pwm_t m_pwm = NRF_DRV_PWM_INSTANCE(PWM_INSTANCE);
+
+static nrf_drv_pwm_t m1_pwm = NRF_DRV_PWM_INSTANCE(PWM1_INSTANCE);
+
+static nrf_drv_pwm_config_t m_config =
+{
+		.output_pins =
+		{
+				NRF_DRV_PWM_PIN_NOT_USED, // channel 0
+				NRF_DRV_PWM_PIN_NOT_USED, // channel 1
+				NRF_DRV_PWM_PIN_NOT_USED, // channel 2
+				NRF_DRV_PWM_PIN_NOT_USED	 // channel 3
+		},
+		.irq_priority = PWM0_IRQ_PRIORITY,
+		.base_clock   = NRF_PWM_CLK_125kHz,
+		.count_mode   = NRF_PWM_MODE_UP,
+		.top_value    = 15612,
+		.load_mode    = NRF_PWM_LOAD_INDIVIDUAL,
+		.step_mode    = NRF_PWM_STEP_AUTO
+};
+
+static nrf_drv_pwm_config_t m1_config =
+{
+		.output_pins =
+		{
+				NRF_DRV_PWM_PIN_NOT_USED, // channel 0
+				NRF_DRV_PWM_PIN_NOT_USED, // channel 1
+				NRF_DRV_PWM_PIN_NOT_USED, // channel 2
+				NRF_DRV_PWM_PIN_NOT_USED	 // channel 3
+		},
+		.irq_priority = PWM0_IRQ_PRIORITY,
+		.base_clock   = NRF_PWM_CLK_125kHz,
+		.count_mode   = NRF_PWM_MODE_UP,
+		.top_value    = 15612,
+		.load_mode    = NRF_PWM_LOAD_INDIVIDUAL,
+		.step_mode    = NRF_PWM_STEP_AUTO
+};
+
+static nrfx_pwm_handler_t m_pwm_callback = NULL;
+
+static nrfx_pwm_handler_t m1_pwm_callback = NULL;
+
+static void bsp_pwm_init_process(void)
+{
+	if(Except_TxError(EXCEPT_PWM_INIT,"bsp_pwm_init_error\r\n") == 0)
+	{
+		Process_Stop(bsp_pwm_init_process);
+	}
+}
+
+static void bsp_pwm1_init_process(void)
+{
+	if(Except_TxError(EXCEPT_PWM_INIT,"bsp_pwm1_init_error\r\n") == 0)
+	{
+		Process_Stop(bsp_pwm1_init_process);
+	}
+}
+
+/*********************************************************************
+ * LOCAL FUNCTIONS
+ */
+/**
+	@brief PWM 初始化
+	@prama 无
+	@return 无
+*/
+static void Pwm_init(void)
+{
+	int 				ret = 0;
+	ret_code_t 	errCode;
+	
+	errCode = nrf_drv_pwm_init(&m_pwm, &m_config, m_pwm_callback);
+	if(errCode != NRF_SUCCESS)ret = -1;
+	
+	if(ret == -1)
+	{
+		Process_Start(0,"bsp_pwm_init_process",bsp_pwm_init_process);
+	}
+}
+/**
+	@brief PWM 初始化
+	@prama 无
+	@return 无
+*/
+static void Pwm1_init(void)
+{
+	int 				ret = 0;
+	ret_code_t 	errCode;
+	
+	errCode = nrf_drv_pwm_init(&m1_pwm, &m1_config, m1_pwm_callback);
+	if(errCode != NRF_SUCCESS)ret = -1;
+	
+	if(ret == -1)
+	{
+		Process_Start(0,"bsp_pwm1_init_process",bsp_pwm1_init_process);
+	}
+}
+///**
+//	@brief PWM 唤醒操作
+//	@prama t - [in] 唤醒时间
+//	@return 无
+//*/
+//static void cb_pwmWakeup(uint32_t t)
+//{
+//	Pwm_init();
+//}
+///**
+//	@brief PWM 睡眠操作
+//	@prama t - [in] 睡眠时间
+//	@return 无
+//*/
+//static void cb_pwmSleep(uint32_t t)
+//{
+//	nrfx_pwm_uninit(&m_pwm);
+//}
+/**
+ @brief 设置PWM的通道的加载模式
+ @param load_mode -[in] 加载模式
+ @return 无
+*/
+static void SetPwm_ChannelsLoadMode(nrf_pwm_dec_load_t load_mode)
+{
+	m_config.load_mode = load_mode;
+}
+
+/**
+ @brief 设置PWM1的通道的加载模式
+ @param load_mode -[in] 加载模式
+ @return 无
+*/
+static void SetPwm1_ChannelsLoadMode(nrf_pwm_dec_load_t load_mode)
+{
+	m1_config.load_mode = load_mode;
+}
+/*********************************************************************
+ * PUBLIC FUNCTIONS
+ */
+/**
+ @brief 设置PWM的引脚通道
+ @param p_pins -[in] 输入的引脚通道
+ @return 无
+*/
+void SetPwm_Channels(uint32_t channel_1, uint32_t channel_2, uint32_t channel_3, uint32_t channel_4)
+{
+	m_config.output_pins[0] = channel_1;
+	m_config.output_pins[1] = channel_2;
+	m_config.output_pins[2] = channel_3;
+	m_config.output_pins[3] = channel_4;
+}
+/**
+ @brief 设置PWM的中断回调函数
+ @param pwm_callback -[in] 中断函数的地址
+ @param irq_priority -[in] 中断函数的优先级
+ @return 无
+*/
+void SetPwm_IRQ(nrfx_pwm_handler_t pwm_callback, uint8_t irq_priority)
+{
+	m_pwm_callback = pwm_callback;
+	m_config.irq_priority = irq_priority;
+}
+/**
+ @brief 设置PWM的基础时钟
+ @param clock -[in] 时钟频率
+ @return 无
+*/
+void SetPwm_BaseClock(nrf_pwm_clk_t clock)
+{
+	m_config.base_clock = clock;
+}
+/**
+ @brief 设置PWM的计数模式
+ @param count_mode -[in] 计数模式
+ @return 无
+*/
+void SetPwm_CountMode(nrf_pwm_mode_t count_mode)
+{
+	m_config.count_mode = count_mode;
+}
+/**
+ @brief 设置PWM的最大的占空比阈值
+ @param Max_duty_cycle_value -[in] 最大的占空比阈值,根据频率决定。
+ @return 无
+*/
+void SetPwm_DutyCycleThreshold(uint16_t Max_duty_cycle_value)
+{
+	m_config.top_value = Max_duty_cycle_value;
+}
+/**
+ @brief 设置PWM的序列的推进模式,定义下一个cycle的进行方式。
+ @param step_mode -[in] 推进模式
+ @return 无
+*/
+void SetPwm_SequenceStepMode(nrf_pwm_dec_step_t step_mode)
+{
+	m_config.step_mode = step_mode;
+}
+/**
+ @brief PWM 的初始化
+ @param 无
+ @return 无
+*/
+void Pwm_Initialize(void){
+	Pwm_init();
+}
+/**
+ @brief PWM 的未初始化
+ @param 无
+ @return 无
+*/
+void Pwm_UnInitialize(void)
+{
+	nrfx_pwm_uninit(&m_pwm);
+}
+
+
+
+/**
+ @brief 设置一个独立通道序列
+ @param p_seqValues -[in]	指向一个独立通道序列
+ @param	seqValues_length - [in]	序列的大小
+ @param seqValues_repeats -[in] 序列的每个占空比重复的次数
+ @param	seqValues_end_delay - [in]  每个序列中,最后一个占空比重复的次数
+ @return 无
+*/
+nrf_pwm_sequence_t* Pwm_SetIndSequence(pwm_values_individual_t *p_seqValues, uint16_t seqValues_length,  uint32_t seqValues_repeats, uint32_t seqValues_end_delay)
+{
+	static nrf_pwm_sequence_t m_sequence;
+	
+	if(m_config.load_mode != NRF_PWM_LOAD_INDIVIDUAL)
+	{
+		SetPwm_ChannelsLoadMode(NRF_PWM_LOAD_INDIVIDUAL);
+		Pwm_UnInitialize();
+		Pwm_Initialize();
+	}
+	m_sequence.values.p_individual = (nrf_pwm_values_individual_t*)p_seqValues;
+	m_sequence.length = seqValues_length;
+	m_sequence.repeats = seqValues_repeats;
+	m_sequence.end_delay = seqValues_end_delay;
+	
+	return &m_sequence;
+}
+/**
+ @brief 设置一个共用通道序列
+ @param p_seqValues -[in]	指向一个共用通道序列
+ @param	seqValues_length - [in]	序列的大小
+ @param seqValues_repeats -[in] 序列的每个占空比重复的次数
+ @param	seqValues_end_delay - [in]  每个序列中,最后一个占空比重复的次数
+ @return 无
+*/
+nrf_pwm_sequence_t* Pwm_SetComSequence(pwm_values_common_t *p_seqValues, uint16_t seqValues_length,  uint32_t seqValues_repeats, uint32_t seqValues_end_delay)
+{
+	static nrf_pwm_sequence_t m_sequence;
+	
+	if(m_config.load_mode != NRF_PWM_LOAD_COMMON)
+	{
+		SetPwm_ChannelsLoadMode(NRF_PWM_LOAD_COMMON);
+		Pwm_UnInitialize();
+		Pwm_Initialize();
+	}
+	m_sequence.values.p_common = (nrf_pwm_values_common_t*)p_seqValues;
+	m_sequence.length = seqValues_length;
+	m_sequence.repeats = seqValues_repeats;
+	m_sequence.end_delay = seqValues_end_delay;
+	
+	return &m_sequence;
+}
+/**
+ @brief 设置PWM的指定单个序列的播放
+ @param pwm_sequence -[in] 输入序列的值
+ @param	playback_count -[in] 播放次数
+ @param	flags - [in]	播放模式
+ @return 错误代码
+*/
+uint32_t SetSimplePwmPlayBack(nrf_pwm_sequence_t *pwm_sequence, uint16_t playback_count, uint32_t flags)
+{
+	return nrf_drv_pwm_simple_playback(&m_pwm, pwm_sequence, playback_count, flags);
+}
+/**
+ @brief 设置PWM的指定多个序列的播放
+ @param pwm_sequence0 -[in] 输入序列的值
+ @param pwm_sequence1 -[in] 输入序列的值
+ @param	playback_count -[in] 播放次数
+ @param	flags - [in]	播放模式
+ @return 错误代码
+*/
+uint32_t SetComplexPwmPlayBack(nrf_pwm_sequence_t *pwm_sequence0, nrf_pwm_sequence_t *pwm_sequence1, uint16_t playback_count, uint32_t flags)
+{
+	return nrf_drv_pwm_complex_playback(&m_pwm, pwm_sequence0, pwm_sequence1, playback_count, flags);
+}
+
+/****************************************************************************************************************************************************************************/
+
+
+/**
+ @brief 设置PWM1的引脚通道
+ @param p_pins -[in] 输入的引脚通道
+ @return 无
+*/
+void SetPwm1_Channels(uint32_t channel_1, uint32_t channel_2, uint32_t channel_3, uint32_t channel_4)
+{
+	m1_config.output_pins[0] = channel_1;
+	m1_config.output_pins[1] = channel_2;
+	m1_config.output_pins[2] = channel_3;
+	m1_config.output_pins[3] = channel_4;
+}
+/**
+ @brief 设置PWM1的中断回调函数
+ @param pwm_callback -[in] 中断函数的地址
+ @param irq_priority -[in] 中断函数的优先级
+ @return 无
+*/
+void SetPwm1_IRQ(nrfx_pwm_handler_t pwm_callback, uint8_t irq_priority)
+{
+	m1_pwm_callback = pwm_callback;
+	m1_config.irq_priority = irq_priority;
+}
+/**
+ @brief 设置PWM1的基础时钟
+ @param clock -[in] 时钟频率
+ @return 无
+*/
+void SetPwm1_BaseClock(nrf_pwm_clk_t clock)
+{
+	m1_config.base_clock = clock;
+}
+/**
+ @brief 设置PWM1的计数模式
+ @param count_mode -[in] 计数模式
+ @return 无
+*/
+void SetPwm1_CountMode(nrf_pwm_mode_t count_mode)
+{
+	m1_config.count_mode = count_mode;
+}
+/**
+ @brief 设置PWM1的最大的占空比阈值
+ @param Max_duty_cycle_value -[in] 最大的占空比阈值,根据频率决定。
+ @return 无
+*/
+void SetPwm1_DutyCycleThreshold(uint16_t Max_duty_cycle_value)
+{
+	m1_config.top_value = Max_duty_cycle_value;
+}
+/**
+ @brief 设置PWM1的序列的推进模式,定义下一个cycle的进行方式。
+ @param step_mode -[in] 推进模式
+ @return 无
+*/
+void SetPwm1_SequenceStepMode(nrf_pwm_dec_step_t step_mode)
+{
+	m1_config.step_mode = step_mode;
+}
+/**
+ @brief PWM1 的初始化
+ @param 无
+ @return 无
+*/
+void Pwm1_Initialize(void){
+	Pwm1_init();
+}
+/**
+ @brief PWM 的未初始化
+ @param 无
+ @return 无
+*/
+void Pwm1_UnInitialize(void)
+{
+	nrfx_pwm_uninit(&m1_pwm);
+}
+
+
+
+/**
+ @brief 设置一个独立通道序列
+ @param p_seqValues -[in]	指向一个独立通道序列
+ @param	seqValues_length - [in]	序列的大小
+ @param seqValues_repeats -[in] 序列的每个占空比重复的次数
+ @param	seqValues_end_delay - [in]  每个序列中,最后一个占空比重复的次数
+ @return 无
+*/
+nrf_pwm_sequence_t* Pwm1_SetIndSequence(pwm_values_individual_t *p_seqValues, uint16_t seqValues_length,  uint32_t seqValues_repeats, uint32_t seqValues_end_delay)
+{
+	static nrf_pwm_sequence_t m1_sequence;
+	
+	if(m1_config.load_mode != NRF_PWM_LOAD_INDIVIDUAL)
+	{
+		SetPwm1_ChannelsLoadMode(NRF_PWM_LOAD_INDIVIDUAL);
+		Pwm1_UnInitialize();
+		Pwm1_Initialize();
+	}
+	m1_sequence.values.p_individual = (nrf_pwm_values_individual_t*)p_seqValues;
+	m1_sequence.length = seqValues_length;
+	m1_sequence.repeats = seqValues_repeats;
+	m1_sequence.end_delay = seqValues_end_delay;
+	
+	return &m1_sequence;
+}
+/**
+ @brief 设置一个共用通道序列
+ @param p_seqValues -[in]	指向一个共用通道序列
+ @param	seqValues_length - [in]	序列的大小
+ @param seqValues_repeats -[in] 序列的每个占空比重复的次数
+ @param	seqValues_end_delay - [in]  每个序列中,最后一个占空比重复的次数
+ @return 无
+*/
+nrf_pwm_sequence_t* Pwm1_SetComSequence(pwm_values_common_t *p_seqValues, uint16_t seqValues_length,  uint32_t seqValues_repeats, uint32_t seqValues_end_delay)
+{
+	static nrf_pwm_sequence_t m1_sequence;
+	
+	if(m1_config.load_mode != NRF_PWM_LOAD_COMMON)
+	{
+		SetPwm1_ChannelsLoadMode(NRF_PWM_LOAD_COMMON);
+		Pwm1_UnInitialize();
+		Pwm1_Initialize();
+	}
+	m1_sequence.values.p_common = (nrf_pwm_values_common_t*)p_seqValues;
+	m1_sequence.length = seqValues_length;
+	m1_sequence.repeats = seqValues_repeats;
+	m1_sequence.end_delay = seqValues_end_delay;
+	
+	return &m1_sequence;
+}
+/**
+ @brief 设置PWM的指定单个序列的播放
+ @param pwm_sequence -[in] 输入序列的值
+ @param	playback_count -[in] 播放次数
+ @param	flags - [in]	播放模式
+ @return 错误代码
+*/
+uint32_t SetSimplePwm1PlayBack(nrf_pwm_sequence_t *pwm_sequence, uint16_t playback_count, uint32_t flags)
+{
+	return nrf_drv_pwm_simple_playback(&m1_pwm, pwm_sequence, playback_count, flags);
+}
+/**
+ @brief 设置PWM的指定多个序列的播放
+ @param pwm_sequence0 -[in] 输入序列的值
+ @param pwm_sequence1 -[in] 输入序列的值
+ @param	playback_count -[in] 播放次数
+ @param	flags - [in]	播放模式
+ @return 错误代码
+*/
+uint32_t SetComplexPwm1PlayBack(nrf_pwm_sequence_t *pwm_sequence0, nrf_pwm_sequence_t *pwm_sequence1, uint16_t playback_count, uint32_t flags)
+{
+	return nrf_drv_pwm_complex_playback(&m1_pwm, pwm_sequence0, pwm_sequence1, playback_count, flags);
+}
+

+ 88 - 0
shoe_mcu2.2.1_new_v2/bsp/bsp_pwm.h

@@ -0,0 +1,88 @@
+#ifndef __bsp_pwm_h__
+#define __bsp_pwm_h__
+#include <stdbool.h>
+#include <stdint.h>
+#include <string.h>
+#include "sdk_common.h"
+#include "SEGGER_RTT.h"
+#include "usr_config.h"
+#include "nrf_drv_pwm.h"
+
+
+/**************************************
+DEFINECTION
+*/
+
+
+#define PWM_SEQUENCE_VALUES_LEN(seq_values)			NRF_PWM_VALUES_LENGTH(seq_values)						//SEQUENCE_VALUES_LEN
+
+#define PWM_FLAG_STOP														NRF_DRV_PWM_FLAG_STOP												//PLAYBACK_MODE
+#define PWM_FLAG_LOOP														NRF_DRV_PWM_FLAG_LOOP												//PLAYBACK_MODE
+#define PWM_FLAG_SIGNAL_END_SEQ0								NRF_DRV_PWM_FLAG_SIGNAL_END_SEQ0   					//PLAYBACK_MODE     
+#define PWM_FLAG_SIGNAL_END_SEQ1								NRF_DRV_PWM_FLAG_SIGNAL_END_SEQ1     				//PLAYBACK_MODE   
+#define PWM_FLAG_NO_EVT_FINISHED								NRF_DRV_PWM_FLAG_NO_EVT_FINISHED      			//PLAYBACK_MODE  
+#define PWM_FLAG_START_VIA_TASK									NRF_DRV_PWM_FLAG_START_VIA_TASK         		//PLAYBACK_MODE
+/**************************************
+STRUCTION
+*/
+typedef struct
+{
+    uint16_t channel_0; ///< Duty cycle value for channel 0.
+    uint16_t channel_1; ///< Duty cycle value for channel 1.
+    uint16_t channel_2; ///< Duty cycle value for channel 2.
+    uint16_t channel_3; ///< Duty cycle value for channel 3.
+} pwm_values_individual_t;
+
+typedef uint16_t pwm_values_common_t;
+/**************************************
+API
+*/
+//设置PWM的引脚通道
+void SetPwm_Channels(uint32_t channel_1, uint32_t channel_2, uint32_t channel_3, uint32_t channel_4);
+//设置PWM的中断回调函数
+void SetPwm_IRQ(nrfx_pwm_handler_t pwm_callback, uint8_t irq_priority);
+//设置PWM的基础时钟
+void SetPwm_BaseClock(nrf_pwm_clk_t clock);
+//设置PWM的计数模式
+void SetPwm_CountMode(nrf_pwm_mode_t count_mode);
+//设置PWM的最大的占空比阈值
+void SetPwm_DutyCycleThreshold(uint16_t Max_duty_cycle_value);
+//设置PWM的序列的推进模式,定义下一个cycle的进行方式。
+void SetPwm_SequenceStepMode(nrf_pwm_dec_step_t step_mode);
+//PWM 的初始化
+void Pwm_Initialize(void);
+//PWM 的未初始化
+void Pwm_UnInitialize(void);
+//设置一个独立通道序列
+nrf_pwm_sequence_t* Pwm_SetIndSequence(pwm_values_individual_t *p_seqValues, uint16_t seqValues_length,  uint32_t seqValues_repeats, uint32_t seqValues_end_delay);
+//设置一个共用通道序列
+nrf_pwm_sequence_t* Pwm_SetComSequence(pwm_values_common_t *p_seqValues, uint16_t seqValues_length,  uint32_t seqValues_repeats, uint32_t seqValues_end_delay);
+//设置PWM的指定单个序列的播放
+uint32_t SetSimplePwmPlayBack(nrf_pwm_sequence_t *pwm_sequence, uint16_t playback_count, uint32_t flags);
+
+/****************************************************************************************************************************************************************************/
+
+//设置PWM1的引脚通道
+void SetPwm1_Channels(uint32_t channel_1, uint32_t channel_2, uint32_t channel_3, uint32_t channel_4);
+//设置PWM1的中断回调函数
+void SetPwm1_IRQ(nrfx_pwm_handler_t pwm_callback, uint8_t irq_priority);
+//设置PWM1的基础时钟
+void SetPwm1_BaseClock(nrf_pwm_clk_t clock);
+//设置PWM1的计数模式
+void SetPwm1_CountMode(nrf_pwm_mode_t count_mode);
+//设置PWM1的最大的占空比阈值
+void SetPwm1_DutyCycleThreshold(uint16_t Max_duty_cycle_value);
+//设置PWM1的序列的推进模式,定义下一个cycle的进行方式。
+void SetPwm1_SequenceStepMode(nrf_pwm_dec_step_t step_mode);
+//PWM1 的初始化
+void Pwm1_Initialize(void);
+//PWM1 的未初始化
+void Pwm1_UnInitialize(void);
+//设置一个独立通道序列
+nrf_pwm_sequence_t* Pwm1_SetIndSequence(pwm_values_individual_t *p_seqValues, uint16_t seqValues_length,  uint32_t seqValues_repeats, uint32_t seqValues_end_delay);
+//设置一个共用通道序列
+nrf_pwm_sequence_t* Pwm1_SetComSequence(pwm_values_common_t *p_seqValues, uint16_t seqValues_length,  uint32_t seqValues_repeats, uint32_t seqValues_end_delay);
+//设置PWM1的指定单个序列的播放
+uint32_t SetSimplePwm1PlayBack(nrf_pwm_sequence_t *pwm_sequence, uint16_t playback_count, uint32_t flags);
+
+#endif

+ 13 - 0
shoe_mcu2.2.1_new_v2/bsp/bsp_pwm/bsp_pwm.h

@@ -0,0 +1,13 @@
+#ifndef __bsp_pwm_h__
+#define __bsp_pwm_h__
+#include <stdbool.h>
+#include <stdint.h>
+#include <string.h>
+#include "sdk_common.h"
+#include "SEGGER_RTT.h"
+#include "usr_config.h"
+
+void Pwm_Initialize(void);
+void Pwm_update_duty(uint8_t duty_1,uint8_t duty_2,uint8_t duty_3);
+
+#endif

+ 92 - 0
shoe_mcu2.2.1_new_v2/bsp/bsp_pwm/bsp_pwm_led_gpio.c

@@ -0,0 +1,92 @@
+#include "sdk_common.h"
+#include "SEGGER_RTT.h"
+#include "nrf_drv_pwm.h"
+#include "usr_config.h"
+#include "system.h"
+#include "nrf_gpio.h"
+#include "bsp_pwm.h"
+
+/********************** ±äÁ¿Çø *************************/
+
+static nrf_drv_pwm_t m_pwm0 = NRF_DRV_PWM_INSTANCE(0);
+
+static const uint16_t pwm_const = 1250;
+
+static nrf_pwm_values_individual_t m_demo1_seq_values={0,0,0};
+
+static nrf_pwm_sequence_t const    m_demo1_seq =
+{
+    .values.p_individual = &m_demo1_seq_values,
+    .length              = NRF_PWM_VALUES_LENGTH(m_demo1_seq_values),
+    .repeats             = 0,
+    .end_delay           = 0
+};
+
+void Pwm_update_duty(uint8_t duty_1,uint8_t duty_2,uint8_t duty_3)
+{
+	   if(duty_1 >  100)duty_1 =100;
+	   if(duty_2 >  100)duty_2 =100;
+	   if(duty_3 >  100)duty_3 =100;
+	  
+	   if(PCB_VERSION == 1 || PCB_VERSION == 3){
+			   duty_1 = 100-duty_1;
+			   duty_2 = 100-duty_2;
+			   duty_3 = 100-duty_3;
+		 }
+		 uint16_t duty1_t = (uint16_t)(duty_1*pwm_const/100);
+		 uint16_t duty2_t = (uint16_t)(duty_2*pwm_const/100);
+		 uint16_t duty3_t = (uint16_t)(duty_3*pwm_const/100);
+     m_demo1_seq_values.channel_0 = duty1_t;
+	   m_demo1_seq_values.channel_1 = duty2_t;
+	   m_demo1_seq_values.channel_2 = duty3_t;
+		 
+		 //DEBUG_LOG("led debug %d,%d,%d\n",m_demo1_seq_values.channel_0,m_demo1_seq_values.channel_1,m_demo1_seq_values.channel_2);
+}
+
+static void Pwm_init(void)
+{
+    nrf_drv_pwm_config_t const config0 =
+    {
+        .output_pins =
+        {
+            PIN_LED_R, // channel 0
+            PIN_LED_G, // channel 1
+            PIN_LED_B, // channel 2
+            NRF_DRV_PWM_PIN_NOT_USED
+        },
+        .irq_priority = APP_IRQ_PRIORITY_LOWEST,
+        .base_clock   = NRF_PWM_CLK_125kHz,
+        .count_mode   = NRF_PWM_MODE_UP,
+        .top_value    = pwm_const,
+        .load_mode    = NRF_PWM_LOAD_INDIVIDUAL,
+        .step_mode    = NRF_PWM_STEP_AUTO
+    };
+    APP_ERROR_CHECK(nrf_drv_pwm_init(&m_pwm0, &config0, NULL));
+		
+    m_demo1_seq_values.channel_0 = pwm_const;
+    m_demo1_seq_values.channel_1 = pwm_const;
+    m_demo1_seq_values.channel_2 = pwm_const;
+
+    (void)nrf_drv_pwm_simple_playback(&m_pwm0, &m_demo1_seq, 1,
+                                      NRF_DRV_PWM_FLAG_LOOP);
+		
+}
+
+static void cb_pwmWakeup(uint32_t t)
+{
+	  Pwm_init();
+}
+
+static void cb_pwmSleep(uint32_t t)
+{
+	  nrfx_pwm_uninit(&m_pwm0);
+	  nrf_gpio_cfg_input(PIN_LED_R, NRF_GPIO_PIN_NOPULL);//IO 
+	  nrf_gpio_cfg_input(PIN_LED_G, NRF_GPIO_PIN_NOPULL);
+	  nrf_gpio_cfg_input(PIN_LED_B, NRF_GPIO_PIN_NOPULL);
+}
+
+void Pwm_Initialize(void){
+	Pwm_init();
+	Wakeup_Regist(cb_pwmWakeup);
+  Sleep_Regist(cb_pwmSleep);
+}

+ 65 - 0
shoe_mcu2.2.1_new_v2/bsp/bsp_pwm/bsp_pwm_led_ws2812.c

@@ -0,0 +1,65 @@
+#include "sdk_common.h"
+#include "SEGGER_RTT.h"
+#include "nrf_drv_pwm.h"
+#include "usr_config.h"
+#include "system.h"
+#include "nrf_gpio.h"
+#include "bsp_pwm.h"
+
+/********************** ±äÁ¿Çø *************************/
+
+static nrf_drv_pwm_t m_pwm0 = NRF_DRV_PWM_INSTANCE(0);
+
+static nrf_pwm_values_individual_t m_demo1_seq_values[]={
+{0},{0},{0},{0},{0},{0}
+};
+
+static nrf_pwm_sequence_t const    m_demo1_seq =
+{
+    .values.p_individual = m_demo1_seq_values,
+    .length              = NRF_PWM_VALUES_LENGTH(m_demo1_seq_values),
+    .repeats             = 0,
+    .end_delay           = 0
+};
+
+static void Pwm_init(void)
+{
+    nrf_drv_pwm_config_t const config0 =
+    {
+        .output_pins =
+        {
+            PIN_LED_CONTROL, // channel 0
+            NRF_DRV_PWM_PIN_NOT_USED, 
+            NRF_DRV_PWM_PIN_NOT_USED,
+            NRF_DRV_PWM_PIN_NOT_USED
+        },
+        .irq_priority = APP_IRQ_PRIORITY_LOWEST,
+        .base_clock   = NRF_PWM_CLK_125kHz,
+        .count_mode   = NRF_PWM_MODE_UP,
+        .top_value    = 1,
+        .load_mode    = NRF_PWM_LOAD_INDIVIDUAL,
+        .step_mode    = NRF_PWM_STEP_AUTO
+    };
+    APP_ERROR_CHECK(nrf_drv_pwm_init(&m_pwm0, &config0, NULL));
+		
+    (void)nrf_drv_pwm_simple_playback(&m_pwm0, &m_demo1_seq, 1,
+                                      NRF_DRV_PWM_FLAG_LOOP);
+		
+}
+
+static void cb_pwmWakeup(uint32_t t)
+{
+	  Pwm_init();
+}
+
+static void cb_pwmSleep(uint32_t t)
+{
+	  nrfx_pwm_uninit(&m_pwm0);
+	  nrf_gpio_cfg_input(PIN_LED_CONTROL, NRF_GPIO_PIN_NOPULL);//IO 
+}
+
+void Pwm_Initialize(void){
+	Pwm_init();
+	Wakeup_Regist(cb_pwmWakeup);
+  Sleep_Regist(cb_pwmSleep);
+}

+ 144 - 0
shoe_mcu2.2.1_new_v2/bsp/bsp_rtc.c

@@ -0,0 +1,144 @@
+#include "bsp_rtc.h"
+#include "ble_conn_state.h"
+#include "nrf_ble_scan.h"
+#include "app_timer.h"
+#include "bsp_battery.h"
+#include "drv_mpu9250.h"
+#include "nrf_delay.h"
+
+#define COMPARE_COUNTERTIME  (1UL)                                        /**< Get Compare event COMPARE_TIME seconds after the counter starts from 0. */
+
+static const nrf_drv_rtc_t rtc = NRF_DRV_RTC_INSTANCE(2); /**< Declaring an instance of nrf_drv_rtc for RTC2. */
+
+static uint16_t	m_sleeptimes_S = 0;
+
+/** @brief: Function for handling the RTC0 interrupts.
+ * Triggered on TICK and COMPARE0 match.
+ */
+static void rtc_handler(nrf_drv_rtc_int_type_t int_type)
+{
+	uint32_t err_code;
+    if (int_type == NRF_DRV_RTC_INT_COMPARE0)
+    {
+		nrf_drv_rtc_counter_clear(&rtc);
+		err_code = nrf_drv_rtc_cc_set(&rtc,0,m_sleeptimes_S,true);
+		APP_ERROR_CHECK(err_code);
+        DEBUG_LOG("NRF_DRV_RTC_INT_COMPARE0(0x%X)\n",NRF_RTC0->COUNTER);
+    }
+    else if (int_type == NRF_DRV_RTC_INT_TICK)
+    {
+//        DEBUG_LOG("NRF_DRV_RTC_INT_TICK(0x%X)\n",NRF_RTC0->COUNTER);
+    }
+}
+
+/** @brief Function initialization and configuration of RTC driver instance.
+ */
+void RTC_init(void)
+{
+	uint32_t err_code;
+
+	//Initialize RTC instance
+	nrf_drv_rtc_config_t config = NRF_DRV_RTC_DEFAULT_CONFIG;
+	config.prescaler = 0;// f(RTC) = 32.768kHZ/(prescaler+1) = 8HZ = 125ms
+	err_code = nrf_drv_rtc_init(&rtc, &config, rtc_handler);
+	APP_ERROR_CHECK(err_code);
+	
+	err_code = nrf_drv_rtc_cc_set(&rtc,0,300,true);
+	APP_ERROR_CHECK(err_code);
+	
+	nrf_drv_rtc_counter_clear(&rtc);
+
+//	//Enable tick event & interrupt
+//	nrf_drv_rtc_tick_enable(&rtc,true);
+
+//	//Set compare channel to trigger interrupt after COMPARE_COUNTERTIME seconds
+//	err_code = nrf_drv_rtc_cc_set(&rtc,0,COMPARE_COUNTERTIME * 8,true);
+//	APP_ERROR_CHECK(err_code);
+
+//	//Power on RTC instance
+	nrf_drv_rtc_enable(&rtc);
+
+}
+
+void rtc_start(uint16_t sleep_S)
+{
+	uint32_t err_code;
+	
+	m_sleeptimes_S = sleep_S;
+		//Set compare channel to trigger interrupt after sleep_S seconds
+	err_code = nrf_drv_rtc_cc_set(&rtc,0,m_sleeptimes_S,true);
+	APP_ERROR_CHECK(err_code);
+	
+	nrf_drv_rtc_counter_clear(&rtc);
+	
+	nrf_drv_rtc_enable(&rtc);
+//	DEBUG_LOG("nrf_drv_rtc_enable(0x%X)\n",NRF_RTC0->COUNTER);
+}
+
+void rtc_stop(void)
+{
+	nrf_drv_rtc_disable(&rtc);
+//	DEBUG_LOG("nrf_drv_rtc_disable(0x%X)\n",NRF_RTC0->COUNTER);
+}
+
+/*
+@brief			睡眠函数
+@param			sleep_ms	:睡眠时间,units of 125 ms
+@return			实际睡眠时间
+*/
+uint32_t rtc_sleep(uint32_t sleep_125ms)
+{
+	uint32_t sleep_times,wakeup_times,actual_sleeptimes;
+	//关闭蓝牙扫描
+//	if(!ble_conn_state_central_conn_count())//作为主机没有连接情况下才停止扫描
+//	{
+//		nrf_ble_scan_stop();
+////		DEBUG_LOG("scan off...\n");
+//	}
+	
+	//暂停软件定时器
+	
+//	app_timer_pause();
+//	nrf_delay_ms(100);
+	DEBUG_LOG("timer off...\n");
+	
+	//关闭ADC
+//	ADC_Enable(false);
+//	DEBUG_LOG("adc off...\n");
+	
+	//设定rtc唤醒时间且开启rtc
+	rtc_start(sleep_125ms);
+//	DEBUG_LOG("rtc start(%d)ms\n",sleep_125ms * 125);
+	
+	sleep_times = NRF_RTC0->COUNTER;
+	
+	//进入睡眠
+	CRITICAL_REGION_ENTER();
+	__SEV();
+	__WFE();
+	CRITICAL_REGION_EXIT();
+	(void)sd_app_evt_wait();
+	wakeup_times = NRF_RTC0->COUNTER;
+//	DEBUG_LOG("===============>rtc sleep_times(%d)\n",sleep_times);
+//	DEBUG_LOG("===============>rtc wakeup_times(%d)\n",wakeup_times);
+	//停止rtc
+	rtc_stop();
+//	DEBUG_LOG("rtc end...\n");
+	
+	//开启ADC
+//	ADC_Enable(true);
+//	DEBUG_LOG("adc on...\n");
+	
+	//恢复软件定时器
+//	app_timer_resume();
+	DEBUG_LOG("timer on...\n");
+	nrf_delay_ms(100);
+	actual_sleeptimes = (wakeup_times - sleep_times)/32.768*1000;
+	
+	return  actual_sleeptimes/1000;
+}
+
+
+
+
+

+ 19 - 0
shoe_mcu2.2.1_new_v2/bsp/bsp_rtc.h

@@ -0,0 +1,19 @@
+#ifndef __BSP_RTC_H__
+#define __BSP_RTC_H__
+#include <stdbool.h>
+#include <stdint.h>
+#include <string.h>
+#include "nrf.h"
+#include "app_error.h"
+#include "nrf_drv_rtc.h"
+#include "sdk_common.h"
+#include "SEGGER_RTT.h"
+#include "usr_config.h"
+#include "nrf_assert.h"
+
+void RTC_init(void);
+uint32_t rtc_sleep(uint32_t sleep_125ms);
+
+
+#endif
+

部分文件因为文件数量过多而无法显示