app_game.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307
  1. #include "app_game.h"
  2. #include "usr_config.h"
  3. #include "bsp_time.h"
  4. #include "system.h"
  5. #include "hal_mt.h"
  6. #include "hal_battery.h"
  7. #include "app_charge.h"
  8. #include "hal_ble_client.h"
  9. #include "hal_ble_host.h"
  10. #include "nrf_delay.h"
  11. #include "app_flash.h"
  12. #include "ble_comm.h"
  13. #include "exception.h"
  14. #include "bll_imu.h"
  15. #include "hal_led.h"
  16. #include "pdrStatus.h"
  17. /********************** 函数声明区 *************************/
  18. //游戏模式
  19. static const bll_imu_one_way_param_t game_front_param={
  20. .acc_power_mode = FML_IMU_ACC_POWER_MODE_NORMAL, //前脚 - 加速度正常模式
  21. .gry_power_mode = FML_IMU_GRY_POWER_MODE_NORMAL, //前脚 - 陀螺仪正常模式
  22. .timestamp_resolution = FML_IMU_TIMESTAMP_25US, //前脚 - 时间戳25US精度
  23. .timestamp_switch = FML_IMU_TIMESTAMP_ON, //前脚 - 时间戳开启
  24. .acc_fs = FML_IMU_ACC_FS_16G, //前脚 - 加速度量程 - 16G
  25. .gry_fs = FML_IMU_GRY_FS_2000DPS, //前脚 - 陀螺仪量程 - 2000DPS
  26. .mag_fs = FML_IMU_MAG_FS_30GS, //前脚 - 地磁计量程 - 30GS
  27. .acc_odr = FML_IMU_ACC_ODR_416HZ, //前脚 - 加速度采样频率 - 104HZ
  28. .gry_odr = FML_IMU_GRY_ODR_416HZ, //前脚 - 陀螺仪采样频率 - 104HZ
  29. .mag_odr = FML_IMU_MAG_ODR_200HZ, //前脚 - 地磁计采样频率 - 200HZ
  30. .fifo_odr = FML_IMU_FIFO_ODR_416HZ,
  31. };
  32. static const bll_imu_one_way_param_t game_back_param={
  33. .acc_power_mode = FML_IMU_ACC_POWER_MODE_NORMAL, //后脚 - 加速度正常模式
  34. .gry_power_mode = FML_IMU_GRY_POWER_MODE_NORMAL, //后脚 - 陀螺仪正常模式
  35. .timestamp_resolution = FML_IMU_TIMESTAMP_25US, //后脚 - 时间戳25US精度
  36. .timestamp_switch = FML_IMU_TIMESTAMP_OFF, //后脚 - 时间戳关闭
  37. .acc_fs = FML_IMU_ACC_FS_16G, //后脚 - 加速度量程 - 16G
  38. .gry_fs = FML_IMU_GRY_FS_2000DPS, //后脚 - 陀螺仪量程 - 2000DPS
  39. .mag_fs = FML_IMU_MAG_FS_30GS, //后脚 - 地磁计量程 - 30GS
  40. .acc_odr = FML_IMU_ACC_ODR_OFF, //后脚 - 加速度采样频率 - 关闭
  41. .gry_odr = FML_IMU_GRY_ODR_OFF, //后脚 - 陀螺仪采样频率 - 关闭
  42. .mag_odr = FML_IMU_MAG_ODR_200HZ, //后脚 - 地磁计采样频率 - 200HZ
  43. .fifo_odr = FML_IMU_FIFO_ODR_OFF,
  44. };
  45. static const bll_imu_param_t game_bll_imu_param_t={
  46. .config_param[FML_IMU_DIR_FRONT] = &game_front_param,
  47. .config_param[FML_IMU_DIR_BACK] = &game_back_param,
  48. };
  49. typedef struct game_manager{
  50. uint8_t clientCnt; //右鞋游戏模式的标志位
  51. uint8_t right_discnt; //右鞋断开连接计数器
  52. uint8_t client_discnt; //主机连接断开计数器
  53. uint8_t Signal; //收到主机的游戏指令
  54. uint8_t HeartCnt; //游戏模式心跳维护,左鞋
  55. uint8_t GameMode; //是否在游戏
  56. }game_manager_t;
  57. static game_manager_t game_manager ={0};
  58. #define IMU_MAX_GROUP_NUM 10
  59. static int16_t acc_front[IMU_MAX_GROUP_NUM][3];
  60. static int16_t gry_front[IMU_MAX_GROUP_NUM][3];
  61. static int16_t mag6310_front[IMU_MAX_GROUP_NUM][3];
  62. static int16_t mag6310_back[3];
  63. static int32_t timestamp_front[IMU_MAX_GROUP_NUM];
  64. static uint8_t rssi;
  65. static uint8_t IMU_STATUS; //记录状态用来重新记录时间戳
  66. static uint32_t timestamp;
  67. static int32_t last_timestamp;
  68. static void process_imu_data_front(int front_index)
  69. {
  70. if(IMU_STATUS != 1){
  71. IMU_STATUS = 1;
  72. last_timestamp = timestamp_front[0];
  73. timestamp = 0;
  74. }
  75. if(front_index >IMU_MAX_GROUP_NUM)return;
  76. for(int i = 0; i < front_index; i++)
  77. {
  78. int32_t dt = timestamp_front[i] - last_timestamp;
  79. last_timestamp = timestamp_front[i];
  80. DEBUG_LOG("dt : %d\n", dt);
  81. if(dt == 0)
  82. {
  83. DEBUG_LOG("as dt == 0, return\n", dt);
  84. continue;
  85. }
  86. if(dt < 0)
  87. {
  88. dt = 2425;
  89. }
  90. timestamp += dt;
  91. DEBUG_LOG("timestamp : %ud\n", timestamp);
  92. DEBUG_LOG("timestamp_front[i] : %d\n", timestamp_front[i]);
  93. IMU_Process_motion_queue(mFlash.isHost, timestamp, acc_front[i],
  94. gry_front[i],mag6310_front[i], mag6310_back, rssi);
  95. }
  96. }
  97. void app_game_SetClientGameMode(void)
  98. {
  99. if(game_manager.clientCnt != 3) game_manager.clientCnt = 3;
  100. }
  101. uint8_t app_game_GetGameMode(void)
  102. {
  103. return game_manager.GameMode;
  104. }
  105. static void cb_BLE_Client_R_GAMEMODE(void* handle)
  106. {
  107. BLE_Client_Rx_t* target = handle;
  108. game_manager.Signal = target->pDat[0];
  109. if(game_manager.Signal){
  110. game_manager.HeartCnt =0;
  111. bll_imu_Resume_config_param(&game_bll_imu_param_t);
  112. //是否上传原始数据
  113. if(1 == game_manager.Signal)IMU_Dtalige_Rowdata_OFF();
  114. else if(2 == game_manager.Signal)IMU_Dtalige_Rowdata_ON();
  115. }else{
  116. bll_imu_Resume_unregister_config_param(&game_bll_imu_param_t);
  117. }
  118. BLE_Host_Tx_Send(0,BLE_GAMEMODE,&game_manager.Signal,1);
  119. DEBUG_LOG(">>>>>>>>>>cb_BLE_Client_R_GAMEMODE:%d\r\n",game_manager.Signal);
  120. }
  121. //通知右鞋进入或者退出游戏模式
  122. static void app_game_notify_host(uint8_t mode){
  123. uint8_t clientMode = mode;
  124. BLE_Host_Tx_Send(0,BLE_GAMEMODE,&clientMode,1);
  125. }
  126. //测试使用,游戏模式下 1S亮绿灯20ms.
  127. static void app_game_led(uint8_t gamemode){
  128. static uint8_t led_state =0;
  129. static uint8_t temp =0;
  130. if(gamemode){
  131. temp++;
  132. if(temp == 100){
  133. if(led_state){led_state =0;
  134. LED_Start(LED_RUN,COLOR_GREEN);
  135. }
  136. else {led_state =1;
  137. LED_Start(LED_RUN,COLOR_BLACK);
  138. }
  139. }
  140. if(temp > 102){temp =0;
  141. LED_Stop(LED_RUN);
  142. }
  143. }else{
  144. if(2 == led_state){
  145. LED_Stop(LED_RUN);
  146. }
  147. }
  148. }
  149. //IMU数据回调
  150. static void gamemode_data_notify_cb(uint32_t dir_bit)
  151. {
  152. int16_t group_num = 0;
  153. bll_imu_data_t data={0};
  154. if(0 == app_game_GetGameMode())return;
  155. if((dir_bit >> BLL_IMU_DIR_FRONT) & 0x01){
  156. rssi = 0-host_get_rssi();
  157. group_num = bll_imu_get_data_num(BLL_IMU_DIR_FRONT);
  158. if(group_num >IMU_MAX_GROUP_NUM)return;
  159. for(int i=0;i<group_num;i++){
  160. bll_imu_get_data(BLL_IMU_DIR_FRONT, i, &data);
  161. gry_front[i][0] = data.gry[0];gry_front[i][1] = data.gry[1];gry_front[i][2] = data.gry[2];
  162. acc_front[i][0] = data.acc[0];acc_front[i][1] = data.acc[1];acc_front[i][2] = data.acc[2];
  163. mag6310_front[i][0] = data.mag[0];mag6310_front[i][1] = data.mag[1];mag6310_front[i][2] = data.mag[2];
  164. timestamp_front[i] = data.fifo_timestamp;
  165. }
  166. if(bll_imu_get_data_num(BLL_IMU_DIR_BACK) >= 1){
  167. bll_imu_get_data(BLL_IMU_DIR_BACK, 0, &data);
  168. mag6310_back[0] = data.mag[0];mag6310_back[1] = data.mag[1];mag6310_back[2] = data.mag[2];
  169. }
  170. if(mFlash.isHost){
  171. process_imu_data_front(group_num);
  172. }else if(Slave_Get7_5ms_interval()){
  173. process_imu_data_front(group_num);
  174. }
  175. app_game_led(1);
  176. }
  177. }
  178. static void app_game_Process(void)
  179. {
  180. static uint8_t configcnt = 0;
  181. static uint8_t state = 0;
  182. uint8_t front_CS =0,back_CS =0;
  183. if(game_manager.clientCnt>0) game_manager.clientCnt--;
  184. switch(state){
  185. case 0:{
  186. if(game_manager.Signal){
  187. front_CS = bll_imu_query_config_param_is_ready(BLL_IMU_DIR_FRONT,&game_bll_imu_param_t);
  188. back_CS = bll_imu_query_config_param_is_ready(BLL_IMU_DIR_BACK,&game_bll_imu_param_t);
  189. DEBUG_LOG("front_CS:%d back_CS:%d\r\n",front_CS,back_CS);
  190. if(BLL_IMU_CONFIG_FINISH == front_CS && BLL_IMU_CONFIG_FINISH == back_CS){
  191. state =1;
  192. game_manager.GameMode =1;
  193. }
  194. else if(BLL_IMU_CONFIG_DOING != front_CS || BLL_IMU_CONFIG_DOING != back_CS){
  195. bll_imu_Resume_config_param(&game_bll_imu_param_t);
  196. if(++configcnt >= 20){configcnt =0;
  197. game_manager.Signal =0;
  198. bll_imu_Resume_unregister_config_param(&game_bll_imu_param_t);
  199. Except_TxError(EXCEPT_GAME,"shoes into game mode fail");
  200. }
  201. }
  202. if(0 != game_manager.HeartCnt)game_manager.HeartCnt =0;
  203. }
  204. if(game_manager.clientCnt >0 && mFlash.isHost) app_game_notify_host(0);
  205. break;
  206. }
  207. case 1:{
  208. if(mFlash.isHost){//管理右鞋状态
  209. if(host_isconnect()){
  210. if(0 == game_manager.clientCnt){
  211. app_game_notify_host(1);
  212. if(++configcnt >= 10){configcnt =0;
  213. DEBUG_LOG("ERR_NUM_GAME app_game_Process\r\n");
  214. Except_TxError(EXCEPT_GAME,"no get right shoes data");
  215. }
  216. }
  217. else if(configcnt>0) configcnt = 0;
  218. if(0 != game_manager.right_discnt)game_manager.right_discnt =0;
  219. }
  220. else game_manager.right_discnt++;
  221. }
  222. if(0 == slave_isconnect())game_manager.client_discnt++;
  223. else if(0 != game_manager.client_discnt)game_manager.client_discnt =0;
  224. if(0 == game_manager.Signal || //收到退出游戏的指令
  225. game_manager.client_discnt > 5 || //与主机断开5秒后,退出游戏模式
  226. game_manager.right_discnt > 10 //与右鞋断开10秒后,退出游戏模式
  227. ){
  228. if(game_manager.right_discnt > 10)Except_TxError(EXCEPT_GAME,"In game mode,right shoes disconnted long time");
  229. if(game_manager.client_discnt > 5)Except_TxError(EXCEPT_GAME,"In game mode,client disconnted long time");
  230. configcnt =0;
  231. state =0;
  232. game_manager.Signal = 0;
  233. game_manager.client_discnt =0;
  234. game_manager.right_discnt =0;
  235. game_manager.GameMode =0;
  236. bll_imu_Resume_unregister_config_param(&game_bll_imu_param_t);
  237. if(mFlash.isHost)app_game_notify_host(0);
  238. IMU_STATUS = 0;
  239. set_pdr_status();
  240. app_game_led(0);
  241. }
  242. break;
  243. }
  244. default: state =0;game_manager.Signal = 0;game_manager.client_discnt =0;break;
  245. }
  246. }
  247. static void app_AutoOutgame_Process(void){
  248. uint8_t front_CS = bll_imu_query_config_param_is_ready(BLL_IMU_DIR_FRONT,&game_bll_imu_param_t);
  249. uint8_t back_CS = bll_imu_query_config_param_is_ready(BLL_IMU_DIR_BACK,&game_bll_imu_param_t);
  250. if(mFlash.isHost && app_game_GetGameMode()){
  251. DEBUG_LOG("game_manager.GameModeHeartCnt:%d\r\n",game_manager.HeartCnt);
  252. if(game_manager.HeartCnt++ >= 5){
  253. game_manager.Signal = 0;
  254. bll_imu_Resume_unregister_config_param(&game_bll_imu_param_t);
  255. BLE_Host_Tx_Send(0,BLE_GAMEMODE,&game_manager.Signal,1);
  256. }
  257. }
  258. }
  259. void app_game_Init(void)
  260. {
  261. Process_Start(1000,"app_game",app_game_Process);
  262. BLE_Client_Rx_Regist(BLE_GAMEMODE,cb_BLE_Client_R_GAMEMODE);
  263. Process_Start(60000,"app_AutoOutgame",app_AutoOutgame_Process);
  264. bll_imu_register_data_notify_callback(BLL_IMU_DATA_NOTIFY_CB_PRIORITY_1, gamemode_data_notify_cb);
  265. }