algo_port.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378
  1. /*******************************************************************************
  2. * @file algo_port.c
  3. * @author MEMS Application Team
  4. * @version V1.0
  5. * @date 2020-08-12
  6. * @brief sensor testing
  7. *******************************************************************************/
  8. /******************************************************************************/
  9. // includes
  10. /******************************************************************************/
  11. #include <stdio.h>
  12. #include <string.h>
  13. #include <zephyr.h>
  14. #include <soc.h>
  15. #include <sys_manager.h>
  16. #include <sensor_hal.h>
  17. #include <sensor_algo.h>
  18. #include <hr_algo.h>
  19. #include <os_common_api.h>
  20. #include <linker/linker-defs.h>
  21. #ifdef CONFIG_SYS_WAKELOCK
  22. #include <sys_wakelock.h>
  23. #endif
  24. #include "sensor_algo.h"
  25. #include "sensor_port.h"
  26. #include "sensor_sleep.h"
  27. #include "algo_port.h"
  28. #include "gps_manager.h"
  29. #if CONFIG_AEM_WATCH_SUPPORT
  30. #include "aem_adapter_sensor.h"
  31. #endif
  32. /******************************************************************************/
  33. // declarations
  34. /******************************************************************************/
  35. extern int sensor_service_callback(int evt_id, sensor_res_t *res);
  36. static void usr_evt_handler(sensor_evt_t *evt);
  37. static void hr_wear_handler(uint8_t wearing_state, bool check);
  38. static void hr_hb_handler(uint8_t hb_val, uint8_t hb_lvl_val, uint16_t rr_val);
  39. static void hr_spo2_handler(uint8_t spo2_val, uint8_t spo2_lvl_val, uint8_t hb_val,
  40. uint8_t hb_lvl_val, uint16_t rr_val[4], uint8_t rr_lvl_val, uint8_t rr_cnt, uint16_t spo2_r_val);
  41. static void hr_hrv_handler(uint16_t *rr_val_arr, uint8_t rr_val_cnt, uint8_t rr_lvl);
  42. /******************************************************************************/
  43. // variables
  44. /******************************************************************************/
  45. const static sensor_os_api_t os_api =
  46. {
  47. .user_handler = usr_evt_handler,
  48. };
  49. const static hr_os_api_t hr_os_api =
  50. {
  51. .wear_handler = hr_wear_handler,
  52. .hb_handler = hr_hb_handler,
  53. .spo2_handler = hr_spo2_handler,
  54. .hrv_handler = hr_hrv_handler,
  55. };
  56. #ifdef CONFIG_GPS_MANAGER
  57. static int _gps_res_callback(int evt_id, gps_res_t *res)
  58. {
  59. SYS_LOG_INF("_gps_res_callback %d:%d:%d,fix_quality:%d,tracked:%d\n", res->gga_data.time.hours,
  60. res->gga_data.time.minutes, res->gga_data.time.seconds, res->gga_data.fix_quality, res->gga_data.satellites_tracked);
  61. sensor_raw_t sdata;
  62. memset(&sdata, 0, sizeof(sdata));
  63. sdata.id = IN_GNSS;
  64. if (res)
  65. {
  66. /*
  67. "double[0] = latitude (degrees)
  68. double[1] = longitude (degrees)
  69. double[2] = altitude (meters)
  70. double[3] = bearing (heading in degrees)
  71. double[4] = speed (m/s)
  72. double[5] = Horizontal_Accuracy (meters)
  73. double[6] = Vertical_Accuracy (meters)
  74. double[7] = HDOP
  75. double[8] = VDOP"
  76. */
  77. sdata.dData[0] = minmea_tofloat(&res->gga_data.latitude);
  78. sdata.dData[1] = minmea_tofloat(&res->gga_data.longitude);
  79. sdata.dData[2] = minmea_tofloat(&res->gga_data.altitude);
  80. #ifdef CONFIG_GPS_PARSE_RMC_ENABLE
  81. sdata.dData[3] = minmea_tofloat(&res->rmc_data.course);
  82. sdata.dData[4] = minmea_tofloat(&res->rmc_data.speed);
  83. #endif
  84. sdata.dData[7] = minmea_tofloat(&res->gga_data.hdop);
  85. }
  86. printk("IN_GNSS:%0.4f,%0.4f,%0.4f\n", sdata.dData[0], sdata.dData[1], sdata.dData[2]);
  87. sensor_algo_input(&sdata);
  88. // call algo
  89. sensor_algo_process(IN_GNSS);
  90. return 0;
  91. }
  92. #endif
  93. /******************************************************************************/
  94. // functions
  95. /******************************************************************************/
  96. __sleepfunc static void usr_evt_handler(sensor_evt_t *evt)
  97. {
  98. sensor_res_t *res = sensor_algo_get_result();
  99. // dump event
  100. // sensor_algo_dump_event(evt);
  101. // process in sleep mode
  102. if (soc_in_sleep_mode())
  103. {
  104. switch (evt->id)
  105. {
  106. case ALGO_HANDUP:
  107. printk("handup=%d\r\n", res->handup);
  108. if (res->handup == 1)
  109. {
  110. sensor_sleep_wakeup(1);
  111. }
  112. break;
  113. case RAW_HEARTRATE:
  114. printk("hr=%d\r\n", (int)res->heart_rate);
  115. if (res->heart_rate > 0)
  116. {
  117. sensor_sleep_wakeup(0);
  118. }
  119. break;
  120. }
  121. }
  122. else
  123. {
  124. // process in system mode
  125. switch (evt->id)
  126. {
  127. case REQ_SENSOR:
  128. SYS_LOG_INF("REQ_SENSOR, id:%d,on:%d\n", (int)evt->fData[1], (int)evt->fData[2]);
  129. if ((int)evt->fData[2])
  130. {
  131. sensor_hal_enable((int)evt->fData[1]);
  132. if ((int)evt->fData[1] == IN_HEARTRATE)
  133. {
  134. extern int sensor_get_hr_mode(void);
  135. int mode = sensor_get_hr_mode();
  136. sensor_res_t *res = sensor_algo_get_result();
  137. if (res)
  138. {
  139. res->onbody = 0xff;
  140. }
  141. hr_algo_start(mode);
  142. }
  143. if ((int)evt->fData[1] == IN_GNSS)
  144. {
  145. #ifdef CONFIG_GPS_MANAGER
  146. gps_manager_enable(0, 0);
  147. gps_manager_add_callback(_gps_res_callback);
  148. #endif
  149. }
  150. }
  151. else
  152. {
  153. sensor_hal_disable((int)evt->fData[1]);
  154. if ((int)evt->fData[1] == IN_HEARTRATE)
  155. {
  156. hr_algo_stop();
  157. }
  158. if ((int)evt->fData[1] == IN_GNSS)
  159. {
  160. #ifdef CONFIG_GPS_MANAGER
  161. gps_manager_disable(0, 0);
  162. #endif
  163. }
  164. }
  165. break;
  166. case ALGO_ACTIVITY_OUTPUT:
  167. sensor_algo_dump_result(res);
  168. break;
  169. case RAW_HEARTRATE:
  170. SYS_LOG_INF("usr_evt_handler, hr=%d\n", (int)res->heart_rate);
  171. break;
  172. case ALGO_HANDUP:
  173. SYS_LOG_INF("handup=%d", res->handup);
  174. #ifdef CONFIG_SYS_WAKELOCK
  175. #if CONFIG_AEM_WATCH_SUPPORT
  176. adapter_sen_update_gesture_state(res->handup);
  177. #else
  178. if (res->handup == 1)
  179. {
  180. sys_wake_lock(FULL_WAKE_LOCK);
  181. sys_wake_unlock(FULL_WAKE_LOCK);
  182. }
  183. else if (res->handup == 2)
  184. {
  185. system_request_fast_standby();
  186. }
  187. #endif
  188. #endif
  189. break;
  190. }
  191. // callback
  192. sensor_service_callback(evt->id, res);
  193. }
  194. }
  195. static void hr_wear_handler(uint8_t wearing_state, bool check)
  196. {
  197. sensor_raw_t sdata;
  198. sensor_res_t *res = sensor_algo_get_result();
  199. SYS_LOG_INF("hr_wear_handler,wear:%d,pre:%d\n", wearing_state, res->onbody);
  200. if (res && check ? res->onbody != wearing_state : true)
  201. {
  202. // input wear data
  203. memset(&sdata, 0, sizeof(sdata));
  204. sdata.id = IN_OFFBODY;
  205. sdata.fData[0] = wearing_state;
  206. sensor_algo_input(&sdata);
  207. // call algo
  208. sensor_algo_process(sdata.id);
  209. }
  210. }
  211. static void hr_hb_handler(uint8_t hb_val, uint8_t hb_lvl_val, uint16_t rr_val)
  212. {
  213. sensor_raw_t sdata;
  214. // input wear data
  215. memset(&sdata, 0, sizeof(sdata));
  216. sdata.id = IN_HEARTRATE;
  217. sdata.fData[0] = hb_val;
  218. sdata.fData[1] = (hb_lvl_val == 0) ? 3 : 0;
  219. sdata.fData[2] = 200;
  220. sdata.fData[3] = 40;
  221. sensor_algo_input(&sdata);
  222. // call algo
  223. sensor_algo_process(sdata.id);
  224. }
  225. static void hr_spo2_handler(uint8_t spo2_val, uint8_t spo2_lvl_val, uint8_t hb_val,
  226. uint8_t hb_lvl_val, uint16_t rr_val[4], uint8_t rr_lvl_val, uint8_t rr_cnt, uint16_t spo2_r_val)
  227. {
  228. SYS_LOG_INF("hr_spo2_handler,spo2:%d\n", spo2_val);
  229. #if CONFIG_AEM_WATCH_SUPPORT
  230. adapter_sen_set_spo2(spo2_val);
  231. #endif
  232. }
  233. static void hr_hrv_handler(uint16_t *rr_val_arr, uint8_t rr_val_cnt, uint8_t rr_lvl)
  234. {
  235. SYS_LOG_INF("hr_hrv_handler,hrv:%d\n", rr_lvl);
  236. #if CONFIG_AEM_WATCH_SUPPORT
  237. adapter_sen_set_hrv(rr_lvl);
  238. #endif
  239. }
  240. void algo_init(void)
  241. {
  242. SYS_LOG_INF("algo_init\n");
  243. // init algo
  244. sensor_algo_init(&os_api);
  245. // init fifo
  246. sensor_algo_input_fifo_init(20);
  247. // init heart-rate algo
  248. hr_algo_init(&hr_os_api);
  249. }
  250. __sleepfunc void algo_handler(int id, sensor_dat_t *dat)
  251. {
  252. int idx;
  253. uint64_t ts, delta;
  254. float val[3];
  255. sensor_raw_t sdata;
  256. int ret;
  257. #ifdef CONFIG_SENSOR_ALGO_MOTION_CYWEE_DML
  258. sensor_cvt_ag_t ag_cov = {0};
  259. #endif
  260. // printk("sensor algo_handler id=%d, evt=%d\n", id, dat->evt);
  261. // input data
  262. switch (id)
  263. {
  264. case ID_ACC:
  265. case ID_MAG:
  266. if (dat)
  267. {
  268. // start fifo
  269. if (dat->cnt > 1)
  270. {
  271. ts = dat->ts * 1000000ull;
  272. #ifdef CONFIG_SENSOR_ALGO_MOTION_CYWEE_DML
  273. delta = sensor_algo_get_data_period(id) * 1000000ull;
  274. #else
  275. delta = dat->pd * 1000000ull;
  276. #endif
  277. sensor_algo_input_fifo_start(id, ts, delta);
  278. }
  279. // input data
  280. for (idx = 0; idx < dat->cnt; idx++)
  281. {
  282. // get value
  283. #ifdef CONFIG_SENSOR_ALGO_MOTION_CYWEE_DML
  284. sensor_hal_cvt_data(id, dat->buf + dat->sz * idx, dat->sz, NULL, ag_cov.acc_raw);
  285. sensor_algo_convert_data(&ag_cov);
  286. memcpy(val, ag_cov.acc_data, sizeof(float) * 3);
  287. #else
  288. sensor_hal_get_value(id, dat, idx, val);
  289. #endif
  290. // printk("%s %.2f %.2f %.2f\n", sensor_hal_get_name(id), val[0], val[1], val[2]);
  291. // input acc data
  292. memset(&sdata, 0, sizeof(sensor_raw_t));
  293. sdata.id = id;
  294. memcpy(sdata.fData, val, sizeof(float) * 3);
  295. sensor_algo_input(&sdata);
  296. }
  297. // end fifo
  298. if (dat->cnt > 1)
  299. {
  300. sensor_algo_input_fifo_end(id);
  301. }
  302. }
  303. // call algo
  304. sensor_algo_process(id);
  305. break;
  306. case ID_BARO:
  307. if (dat)
  308. {
  309. if (dat->cnt == 0)
  310. {
  311. ret = sensor_hal_poll_data(id, dat, NULL);
  312. if (ret)
  313. {
  314. printk("sensor %d poll failed!\n", id);
  315. break;
  316. }
  317. }
  318. // get value
  319. sensor_hal_get_value(id, dat, 0, val);
  320. // printk("%s %0.2f %0.2f\n", sensor_hal_get_name(id), val[0], val[1]);
  321. // input baro data
  322. memset(&sdata, 0, sizeof(sdata));
  323. sdata.id = IN_BARO;
  324. sdata.fData[0] = val[0];
  325. sdata.fData[1] = 1.0f;
  326. sdata.fData[2] = val[1];
  327. sensor_algo_input(&sdata);
  328. }
  329. // call algo
  330. sensor_algo_process(id);
  331. break;
  332. case ID_HR:
  333. // call algo
  334. hr_algo_process();
  335. break;
  336. }
  337. }