gnss与log动态切换,优化UI产测,蓝牙产测,加入汇顶驱动文件
authorpenglei <1624952103@qq.com>
Mon, 25 Aug 2025 02:58:04 +0000 (10:58 +0800)
committerpenglei <1624952103@qq.com>
Mon, 25 Aug 2025 02:58:04 +0000 (10:58 +0800)
158 files changed:
code/sdk/application/brandy/brandy_standard/thread_pri_init.c
code/sdk/application/wearable/fd230app/nativeui/producttest/src/testLCD.cpp
code/sdk/application/wearable/fd230app/nativeui/producttest/src/testPresenter.cpp
code/sdk/application/wearable/fd230app/nativeui/producttest/src/testSEChipTest.cpp
code/sdk/application/wearable/fd230app/nativeui/producttest/src/testTP.cpp
code/sdk/application/wearable/fd230app/nativeui/producttest/src/testView.cpp
code/sdk/application/wearable/fd230app/nativeui/producttest/src/testbt.cpp
code/sdk/application/wearable/fd230app/nativeui/producttest/src/testbutton.cpp
code/sdk/application/wearable/fd230app/nativeui/producttest/src/testcat1.cpp
code/sdk/application/wearable/fd230app/nativeui/producttest/src/testchanging.cpp
code/sdk/application/wearable/fd230app/nativeui/producttest/src/testgsenson.cpp
code/sdk/application/wearable/fd230app/nativeui/producttest/src/testhrsenson.cpp
code/sdk/application/wearable/fd230app/nativeui/producttest/src/testluminance.cpp
code/sdk/application/wearable/fd230app/nativeui/producttest/src/testmagnetic.cpp
code/sdk/application/wearable/fd230app/nativeui/producttest/src/testmicrophone.cpp
code/sdk/application/wearable/fd230app/nativeui/producttest/src/testmotor.cpp
code/sdk/application/wearable/fd230app/nativeui/producttest/src/testspeak.cpp
code/sdk/application/wearable/service/factorytest_service/factorytest_protocol.c
code/sdk/application/wearable/service/msg_center/src/notify/debug_output_notification/debug_output_notification.cpp
code/sdk/build/config/target_config/brandy/config.py
code/sdk/drivers/boards/brandy_evb/board_config/board_w9.h
code/sdk/drivers/chips/brandy/include/platform_core.h
code/sdk/drivers/drivers/driver/uart/uart.c
code/sdk/drivers/peripheral/cywee/src/main_dml.c
code/sdk/drivers/peripheral/gnss/CMakeLists.txt
code/sdk/drivers/peripheral/gnss/driver/product_porting/porting/tiot_board_uart_port.c
code/sdk/drivers/peripheral/gnss/inc/gnss_http_server.h [new file with mode: 0644]
code/sdk/drivers/peripheral/gnss/sample/gnss_sample/gnss_sample.c
code/sdk/drivers/peripheral/gnss/sample/pgnss_sample/pgnss_sample.c
code/sdk/drivers/peripheral/gnss/src/gnss_http_server.c [new file with mode: 0644]
code/sdk/drivers/peripheral/gnss/src/uart_gnss.c
code/sdk/drivers/peripheral/ppg/gh3x2x/CMakeLists.txt
code/sdk/drivers/peripheral/ppg/gh3x2x/algo_params/HR/04_EXCLUSIVE/HRNet_knBasicWeights.c [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/algo_params/HR/04_EXCLUSIVE/HRNet_knConfNetWeights.c [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/algo_params/HR/04_EXCLUSIVE/HRNet_knMultiWeights.c [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/algo_params/HR/04_EXCLUSIVE/HRNet_knSceneNetWeights.c [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/algo_params/HR/04_EXCLUSIVE/HRNet_knSceneSwitchWeights.c [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/algo_params/HR/04_EXCLUSIVE/HRNet_knSmallWeights.c [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/algo_params/HR/04_EXCLUSIVE/HRNet_knTdfusionWeights.c [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/algo_params/HR/04_EXCLUSIVE/HRNet_knWeights.c [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/algo_params/HR/04_EXCLUSIVE/heart_net_org_dll.c [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/algo_params/HR/04_EXCLUSIVE/heart_net_org_export.h [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/algo_params/SPO2/02_PREMIUM_EXCLUSIVE/pv_v2.1.0.0_spo2wrnet_for_GH3228T_cd023f.c [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/algo_params/goodix_ecg_config.c [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/algo_params/goodix_hba_config.c [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/algo_params/goodix_hrv_config.c [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/algo_params/goodix_nadt_config.c [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/algo_params/goodix_spo2_config.c [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_application/inc/gh3x2x_demo_accppg_sync.h [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_application/inc/gh3x2x_demo_algo_call.h [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_application/inc/gh3x2x_demo_algo_call_version.h [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_application/inc/gh3x2x_demo_algo_config.h [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_application/inc/gh3x2x_demo_algo_hook.h [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_application/inc/gh3x2x_demo_algo_memory.h [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_application/inc/gh3x2x_demo_algorithm_calc.h [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_application/inc/gh3x2x_demo_common.h [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_application/src/gh3x2x_demo_accppg_sync.c [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_application/src/gh3x2x_demo_algo_call.c [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_application/src/gh3x2x_demo_algo_config.c [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_application/src/gh3x2x_demo_algo_frame.c [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_application/src/gh3x2x_demo_algo_hook.c [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_application/src/gh3x2x_demo_algo_memory.c [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_application/src/gh3x2x_demo_algo_reg_array.c [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_application/src/gh3x2x_demo_strategy.c [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_call/inc/goodix_af.h [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_call/inc/goodix_algo.h [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_call/inc/goodix_algo_bt.h [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_call/inc/goodix_ecg.h [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_call/inc/goodix_hba.h [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_call/inc/goodix_hrv.h [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_call/inc/goodix_hsm.h [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_call/inc/goodix_log.h [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_call/inc/goodix_mem.h [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_call/inc/goodix_nadt.h [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_call/inc/goodix_resp.h [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_call/inc/goodix_spo2.h [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_call/inc/goodix_type.h [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_call/inc/iot_sys_def.h [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_call/src/gh3x2x_demo_algo_call_adt.c [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_call/src/gh3x2x_demo_algo_call_af.c [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_call/src/gh3x2x_demo_algo_call_bt.c [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_call/src/gh3x2x_demo_algo_call_ecg.c [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_call/src/gh3x2x_demo_algo_call_hr.c [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_call/src/gh3x2x_demo_algo_call_hrv.c [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_call/src/gh3x2x_demo_algo_call_hsm.c [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_call/src/gh3x2x_demo_algo_call_nadt.c [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_call/src/gh3x2x_demo_algo_call_resp.c [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_call/src/gh3x2x_demo_algo_call_spo2.c [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/driver/inc/gh_drv.h [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/driver/inc/gh_drv_common.h [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/driver/inc/gh_drv_config.h [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/driver/inc/gh_drv_control.h [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/driver/inc/gh_drv_dump.h [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/driver/inc/gh_drv_interface.h [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/driver/inc/gh_drv_registers.h [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/driver/inc/gh_drv_version.h [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/driver/src/gh_drv_config.c [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/driver/src/gh_drv_control.c [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/driver/src/gh_drv_dump.c [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/driver/src/gh_drv_interface.c [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/kernel/gh_demo.c [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/kernel/gh_demo.h [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/kernel/gh_demo_config.h [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/kernel/gh_demo_hook.c [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/kernel/gh_demo_inner.h [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/kernel/gh_demo_protocol.c [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/kernel/gh_demo_reg_array.c [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/kernel/gh_demo_user.c [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/kernel/gh_demo_version.h [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/module/gh_agc/gh_agc.c [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/module/gh_agc/gh_agc.h [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/module/gh_ecg/gh_ecg.c [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/module/gh_ecg/gh_ecg.h [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/module/gh_other/gh_changeinttime.c [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/module/gh_other/gh_movedetect.c [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/module/gh_other/gh_movedetect.h [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/module/gh_protocol/gh_datatrans.c [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/module/gh_protocol/gh_datatrans.h [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/module/gh_protocol/gh_uprotocol.c [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/module/gh_protocol/gh_uprotocol.h [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/module/gh_protocol/gh_zip.c [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/module/gh_protocol/gh_zip.h [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/module/gh_soft_adt/gh_multi_sen_pro.c [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/module/gh_soft_adt/gh_multi_sen_pro.h [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/demo_mp_code/inc/gh3x2x_demo_mp.h [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/demo_mp_code/inc/gh3x2x_demo_mp_process.h [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/demo_mp_code/inc/gh3x2x_mp_algorithm.h [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/demo_mp_code/inc/gh3x2x_mp_common.h [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/demo_mp_code/inc/gh3x2x_mp_config.h [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/demo_mp_code/inc/gh3x2x_mp_define.h [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/demo_mp_code/inc/gh3x2x_mp_param_config.h [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/demo_mp_code/inc/gh3x2x_mp_reg_config.h [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/demo_mp_code/src/gh3x2x_demo_mp.c [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/demo_mp_code/src/gh3x2x_demo_mp_process.c [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/demo_mp_code/src/gh3x2x_demo_mp_user.c [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/demo_mp_code/src/gh3x2x_mp_algorithm.c [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/demo_mp_code/src/gh3x2x_mp_param_config.c [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/demo_mp_code/src/gh3x2x_mp_reg_config.c [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/inc/gh3x2x_afe_drv.h
code/sdk/drivers/peripheral/ppg/gh3x2x/lib/dl.a [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/lib/drv_common.a [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/lib/dsp.a [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/lib/ecg.a [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/lib/hr.a [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/lib/hrv.a [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/lib/nadt.a [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/lib/spo2.a [new file with mode: 0644]
code/sdk/drivers/peripheral/ppg/gh3x2x/src/gh3x2x_afe_drv.c
code/sdk/drivers/peripheral/ppg/gh3x2x/src/gh3x2x_afe_user.c
code/sdk/drivers/peripheral/ppg/hal/ppg_hal.c
code/sdk/drivers/peripheral/ppg/hal/ppg_hal.h
code/sdk/drivers/peripheral/ppg/pah8009/sensor/pah800x_main.c
code/sdk/drivers/peripheral/ppg/pah8009/sensor/pah_800x_config.h
code/sdk/drivers/peripheral/ppg/ppgBleService/ppgBleService.c
code/sdk/drivers/peripheral/ppg/service/ppg_service.cpp
code/sdk/drivers/peripheral/utils/custom_utils.c
code/sdk/drivers/peripheral/vibrator/service/vibrator_service.cpp
code/sdk/middleware/services/media/hal/audio/plugins/brandy/primary/primary_sub_port_in.c

index aad3fdf..7155401 100755 (executable)
@@ -138,6 +138,10 @@ extern int tcp_manager_test_init(void);
 #include "gyro_service.h"
 #endif
 
+#ifdef SUPPORT_GNSS
+#include "gnss_http_server.h"
+#endif
+
 #define EMMC_BASE_ADDR              0x52062000
 #define TASK_PRIORITY_APP           (osPriority_t)(17)
 #define TICK_TEN_MS                 (10U)
@@ -574,8 +578,9 @@ uapi_pm_remove_sleep_veto(PM_ID_DEBUG);
     uapi_pin_set_ie(S_MGPIO34, HAL_PIO_IE_ENBALE);
 #endif
 
-#ifdef SUPPORT_GNSS_SERVER
+#ifdef SUPPORT_GNSS
     gnss_uart_init();
+    // uapi_gnss_http_server_init();
 #endif
 
 #ifdef SUPPORT_AT_OHOSFWK
index c2754d9..12eec1a 100644 (file)
@@ -66,12 +66,12 @@ namespace OHOS
                 delete Title;
                 Title=nullptr;
             }
-             uint8_t cnt = pm_veto_get_id_cnt(PM_ID_P_TEST);
-            if (cnt == 1) {
-                uapi_pm_remove_sleep_veto(PM_ID_P_TEST);
-            } else {
-                // WEARABLE_LOGE(WEARABLE_LOG_MODULE_MAIN_SERVICE,"CAT1 SERVICE MCU has got pm_id_cat1 vote\r\n");
-            }
+            //  uint8_t cnt = pm_veto_get_id_cnt(PM_ID_P_TEST);
+            // if (cnt == 1) {
+            //     uapi_pm_remove_sleep_veto(PM_ID_P_TEST);
+            // } else {
+            //     // WEARABLE_LOGE(WEARABLE_LOG_MODULE_MAIN_SERVICE,"CAT1 SERVICE MCU has got pm_id_cat1 vote\r\n");
+            // }
 
             delete testLCDScrollView;
             testLCDScrollView=nullptr;
index 970d02f..4937657 100644 (file)
     #include "factorytest_protocol.h"\r
 #endif\r
 \r
-\r
-\r
 #include "custom_runtime.h"\r
 \r
 #if defined(SUPPORT_GNSS)\r
 #include "gnss_ctl.h"\r
 #endif\r
 \r
+#ifdef __cplusplus\r
+#if __cplusplus\r
+extern "C"\r
+{\r
+#endif\r
+#endif\r
+#include "pm_definition.h"\r
+#include "pm_veto.h"\r
+#include "pm.h"\r
+#ifdef __cplusplus\r
+#if __cplusplus\r
+}\r
+#endif\r
+#endif\r
 namespace OHOS\r
 {\r
 \r
@@ -202,11 +214,21 @@ namespace OHOS
         if(strcmp(view.GetViewId(),"deepsleep") == 0)\r
         {\r
             //TODO: close bt and cat1 , then deepsleep\r
+\r
             do_cywee_service_check_msg(CYWEE_SERVICE_CMD_STOP_ACC,NULL);\r
             stop_custom_ble_service();\r
             LOS_Msleep(50);\r
             uapi_set4GCapability(false);\r
             LOS_Msleep(50);\r
+\r
+            uint8_t cnt = pm_veto_get_id_cnt(PM_ID_P_TEST);\r
+            if (cnt == 1) {\r
+                uapi_pm_remove_sleep_veto(PM_ID_P_TEST);\r
+            } else {\r
+                // WEARABLE_LOGE(WEARABLE_LOG_MODULE_MAIN_SERVICE,"CAT1 SERVICE MCU has got pm_id_cat1 vote\r\n");\r
+            }\r
+\r
+\r
             mcu_pm_lcd_off(NULL,NULL);\r
             return true;\r
         }\r
@@ -311,12 +333,17 @@ namespace OHOS
         }\r
         if(strcmp(view.GetViewId(),"deep") == 0)\r
         { \r
+\r
             do_cywee_service_check_msg(CYWEE_SERVICE_CMD_STOP_ACC,NULL);\r
             stop_custom_ble_service();\r
             LOS_Msleep(50);\r
             uapi_set4GCapability(false);\r
             LOS_Msleep(50);\r
             mcu_pm_lcd_off(NULL,NULL);\r
+            uint8_t cnt = pm_veto_get_id_cnt(PM_ID_P_TEST);\r
+            if (cnt == 1) {\r
+                uapi_pm_remove_sleep_veto(PM_ID_P_TEST);\r
+            }\r
             return true;\r
         }\r
         #ifdef SUPPORT_A5133_SERVICE\r
index 4d31992..4c9555b 100644 (file)
@@ -78,12 +78,12 @@ namespace OHOS
                 efuse_label=nullptr;
             }
 
-            uint8_t cnt = pm_veto_get_id_cnt(PM_ID_P_TEST);
-            if (cnt == 1) {
-                uapi_pm_remove_sleep_veto(PM_ID_P_TEST);
-            } else {
-                // WEARABLE_LOGE(WEARABLE_LOG_MODULE_MAIN_SERVICE,"CAT1 SERVICE MCU has got pm_id_cat1 vote\r\n");
-            }
+            // uint8_t cnt = pm_veto_get_id_cnt(PM_ID_P_TEST);
+            // if (cnt == 1) {
+            //     uapi_pm_remove_sleep_veto(PM_ID_P_TEST);
+            // } else {
+            //     // WEARABLE_LOGE(WEARABLE_LOG_MODULE_MAIN_SERVICE,"CAT1 SERVICE MCU has got pm_id_cat1 vote\r\n");
+            // }
 
 
             delete testSEChipScrollView;
index 884005e..03f5510 100644 (file)
@@ -64,12 +64,12 @@ namespace OHOS
                 delete Title;
                 Title=nullptr;
             }
-             uint8_t cnt = pm_veto_get_id_cnt(PM_ID_P_TEST);
-            if (cnt == 1) {
-                uapi_pm_remove_sleep_veto(PM_ID_P_TEST);
-            } else {
-                // WEARABLE_LOGE(WEARABLE_LOG_MODULE_MAIN_SERVICE,"CAT1 SERVICE MCU has got pm_id_cat1 vote\r\n");
-            }
+            //  uint8_t cnt = pm_veto_get_id_cnt(PM_ID_P_TEST);
+            // if (cnt == 1) {
+            //     uapi_pm_remove_sleep_veto(PM_ID_P_TEST);
+            // } else {
+            //     // WEARABLE_LOGE(WEARABLE_LOG_MODULE_MAIN_SERVICE,"CAT1 SERVICE MCU has got pm_id_cat1 vote\r\n");
+            // }
             delete testTPScrollView;
             testTPScrollView=nullptr;
 
index e5b8e14..b3c1bd2 100644 (file)
     #include "factorytest_protocol.h"\r
 #endif\r
 \r
+#ifdef __cplusplus\r
+#if __cplusplus\r
+extern "C"\r
+{\r
+#endif\r
+#endif\r
+#include "pm_definition.h"\r
+#include "pm_veto.h"\r
+#include "pm.h"\r
+#ifdef __cplusplus\r
+#if __cplusplus\r
+}\r
+#endif\r
+#endif\r
+\r
 namespace OHOS\r
 {\r
 \r
@@ -916,6 +931,14 @@ namespace OHOS
          }  \r
         display_api->set_auto_timeout_function(false);\r
 \r
+        uint8_t cnt = pm_veto_get_id_cnt(PM_ID_P_TEST);\r
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "cnt : %d\n",cnt);\r
+        if (cnt == 0) \r
+        {\r
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "uapi_pm_add_sleep_veto(PM_ID_P_TEST);");\r
+            uapi_pm_add_sleep_veto(PM_ID_P_TEST);\r
+        }\r
+\r
         uapi_set4GCapability(true);\r
 \r
         start_custom_ble_service();\r
index c4652c8..9246de8 100644 (file)
@@ -97,12 +97,12 @@ namespace OHOS
 
             BluetoothModel::GetInstance()->set_test_bt_falg(false);
 
-            uint8_t cnt = pm_veto_get_id_cnt(PM_ID_P_TEST);
-            if (cnt == 1) {
-                uapi_pm_remove_sleep_veto(PM_ID_P_TEST);
-            } else {
-                // WEARABLE_LOGE(WEARABLE_LOG_MODULE_MAIN_SERVICE,"CAT1 SERVICE MCU has got pm_id_cat1 vote\r\n");
-            }
+            // uint8_t cnt = pm_veto_get_id_cnt(PM_ID_P_TEST);
+            // if (cnt == 1) {
+            //     uapi_pm_remove_sleep_veto(PM_ID_P_TEST);
+            // } else {
+            //     // WEARABLE_LOGE(WEARABLE_LOG_MODULE_MAIN_SERVICE,"CAT1 SERVICE MCU has got pm_id_cat1 vote\r\n");
+            // }
 
 
             delete testBTScrollView;
index f6aae65..3eeded5 100644 (file)
@@ -70,12 +70,12 @@ namespace OHOS
             }
             RootView::GetInstance()->ClearOnKeyActListener();
 
-             uint8_t cnt = pm_veto_get_id_cnt(PM_ID_P_TEST);
-            if (cnt == 1) {
-                uapi_pm_remove_sleep_veto(PM_ID_P_TEST);
-            } else {
-                // WEARABLE_LOGE(WEARABLE_LOG_MODULE_MAIN_SERVICE,"CAT1 SERVICE MCU has got pm_id_cat1 vote\r\n");
-            }
+            //  uint8_t cnt = pm_veto_get_id_cnt(PM_ID_P_TEST);
+            // if (cnt == 1) {
+            //     uapi_pm_remove_sleep_veto(PM_ID_P_TEST);
+            // } else {
+            //     // WEARABLE_LOGE(WEARABLE_LOG_MODULE_MAIN_SERVICE,"CAT1 SERVICE MCU has got pm_id_cat1 vote\r\n");
+            // }
             
             delete testBUTTONScrollView;
             testBUTTONScrollView=nullptr;
index f6d47e6..c9dce85 100644 (file)
@@ -36,6 +36,8 @@ namespace OHOS
     static osTimerId_t  Gsenson_TEST_timer=NULL;
     void testcat1View::ClearAll()
     {
+        uapi_set4GCapability(false);
+        
         if(testcat1ScrollView)
         {
             testcat1ScrollView->RemoveAll();
index 24efbe7..ef38634 100644 (file)
@@ -69,12 +69,12 @@ namespace OHOS
                 charnge_label=nullptr;
             }
             
-             uint8_t cnt = pm_veto_get_id_cnt(PM_ID_P_TEST);
-            if (cnt == 1) {
-                uapi_pm_remove_sleep_veto(PM_ID_P_TEST);
-            } else {
-                // WEARABLE_LOGE(WEARABLE_LOG_MODULE_MAIN_SERVICE,"CAT1 SERVICE MCU has got pm_id_cat1 vote\r\n");
-            }
+            //  uint8_t cnt = pm_veto_get_id_cnt(PM_ID_P_TEST);
+            // if (cnt == 1) {
+            //     uapi_pm_remove_sleep_veto(PM_ID_P_TEST);
+            // } else {
+            //     // WEARABLE_LOGE(WEARABLE_LOG_MODULE_MAIN_SERVICE,"CAT1 SERVICE MCU has got pm_id_cat1 vote\r\n");
+            // }
 
             delete testCHANINGScrollView;
            testCHANINGScrollView=nullptr;
index 42e5ec5..a2acce2 100644 (file)
@@ -92,12 +92,12 @@ namespace OHOS
                 delete labelButton_next;
                 labelButton_next=nullptr;
             }
-             uint8_t cnt = pm_veto_get_id_cnt(PM_ID_P_TEST);
-            if (cnt == 1) {
-                uapi_pm_remove_sleep_veto(PM_ID_P_TEST);
-            } else {
-                // WEARABLE_LOGE(WEARABLE_LOG_MODULE_MAIN_SERVICE,"CAT1 SERVICE MCU has got pm_id_cat1 vote\r\n");
-            }
+            //  uint8_t cnt = pm_veto_get_id_cnt(PM_ID_P_TEST);
+            // if (cnt == 1) {
+            //     uapi_pm_remove_sleep_veto(PM_ID_P_TEST);
+            // } else {
+            //     // WEARABLE_LOGE(WEARABLE_LOG_MODULE_MAIN_SERVICE,"CAT1 SERVICE MCU has got pm_id_cat1 vote\r\n");
+            // }
             delete testGsonsonScrollView;
             testGsonsonScrollView=nullptr;
         }
index bcde2a1..0bbd60b 100644 (file)
@@ -80,12 +80,12 @@ namespace OHOS
                 delete Title;
                 Title=nullptr;
             }
-             uint8_t cnt = pm_veto_get_id_cnt(PM_ID_P_TEST);
-            if (cnt == 1) {
-                uapi_pm_remove_sleep_veto(PM_ID_P_TEST);
-            } else {
-                // WEARABLE_LOGE(WEARABLE_LOG_MODULE_MAIN_SERVICE,"CAT1 SERVICE MCU has got pm_id_cat1 vote\r\n");
-            }
+            //  uint8_t cnt = pm_veto_get_id_cnt(PM_ID_P_TEST);
+            // if (cnt == 1) {
+            //     uapi_pm_remove_sleep_veto(PM_ID_P_TEST);
+            // } else {
+            //     // WEARABLE_LOGE(WEARABLE_LOG_MODULE_MAIN_SERVICE,"CAT1 SERVICE MCU has got pm_id_cat1 vote\r\n");
+            // }
 
             delete testhrsensonScrollView;
             testhrsensonScrollView=nullptr;
@@ -292,10 +292,10 @@ namespace OHOS
 
         testhrsensonScrollView->SetTouchable(true);
         testhrsensonScrollView->SetDraggable(true);
-
+#ifdef SUPPORT_PPG_SERVICE
         int8_t md = PPG_SERVICE_CMD_TYPE_STOP_PPG_TEST;
         send_ppg_cmd_msg(md);
-
+#endif
          uint8_t cnt = pm_veto_get_id_cnt(PM_ID_P_TEST);
         if (cnt == 0) {
             uapi_pm_add_sleep_veto(PM_ID_P_TEST);
index 7b26e3c..4a676ed 100644 (file)
@@ -64,12 +64,12 @@ namespace OHOS
                 delete Title;
                 Title=nullptr;
             }
-             uint8_t cnt = pm_veto_get_id_cnt(PM_ID_P_TEST);
-            if (cnt == 1) {
-                uapi_pm_remove_sleep_veto(PM_ID_P_TEST);
-            } else {
-                // WEARABLE_LOGE(WEARABLE_LOG_MODULE_MAIN_SERVICE,"CAT1 SERVICE MCU has got pm_id_cat1 vote\r\n");
-            }
+            //  uint8_t cnt = pm_veto_get_id_cnt(PM_ID_P_TEST);
+            // if (cnt == 1) {
+            //     uapi_pm_remove_sleep_veto(PM_ID_P_TEST);
+            // } else {
+            //     // WEARABLE_LOGE(WEARABLE_LOG_MODULE_MAIN_SERVICE,"CAT1 SERVICE MCU has got pm_id_cat1 vote\r\n");
+            // }
 
            delete testLUMScrollView;
            testLUMScrollView=nullptr;
index 64bb1ea..7a1f47f 100644 (file)
@@ -78,12 +78,12 @@ namespace OHOS
                 delete labelButton_next;
                 labelButton_next=nullptr;
             }
-             uint8_t cnt = pm_veto_get_id_cnt(PM_ID_P_TEST);
-            if (cnt == 1) {
-                uapi_pm_remove_sleep_veto(PM_ID_P_TEST);
-            } else {
-                // WEARABLE_LOGE(WEARABLE_LOG_MODULE_MAIN_SERVICE,"CAT1 SERVICE MCU has got pm_id_cat1 vote\r\n");
-            }
+            //  uint8_t cnt = pm_veto_get_id_cnt(PM_ID_P_TEST);
+            // if (cnt == 1) {
+            //     uapi_pm_remove_sleep_veto(PM_ID_P_TEST);
+            // } else {
+            //     // WEARABLE_LOGE(WEARABLE_LOG_MODULE_MAIN_SERVICE,"CAT1 SERVICE MCU has got pm_id_cat1 vote\r\n");
+            // }
             delete testmagicScrollView;
             testmagicScrollView=nullptr;
         }
index f084d39..227a9c8 100644 (file)
@@ -83,12 +83,12 @@ namespace OHOS
                 delete Title;
                 Title=nullptr;
             }
-             uint8_t cnt = pm_veto_get_id_cnt(PM_ID_P_TEST);
-            if (cnt == 1) {
-                uapi_pm_remove_sleep_veto(PM_ID_P_TEST);
-            } else {
-                // WEARABLE_LOGE(WEARABLE_LOG_MODULE_MAIN_SERVICE,"CAT1 SERVICE MCU has got pm_id_cat1 vote\r\n");
-            }
+            //  uint8_t cnt = pm_veto_get_id_cnt(PM_ID_P_TEST);
+            // if (cnt == 1) {
+            //     uapi_pm_remove_sleep_veto(PM_ID_P_TEST);
+            // } else {
+            //     // WEARABLE_LOGE(WEARABLE_LOG_MODULE_MAIN_SERVICE,"CAT1 SERVICE MCU has got pm_id_cat1 vote\r\n");
+            // }
             AlarmClockModel::GetInstance()->AlarmPlayerStop();
             delete testmakephoneScrollView;
             testmakephoneScrollView=nullptr;
index 87d21ff..8dfddfd 100644 (file)
@@ -68,12 +68,12 @@ namespace OHOS
                 delete Title;
                 Title=nullptr;
             }
-             uint8_t cnt = pm_veto_get_id_cnt(PM_ID_P_TEST);
-            if (cnt == 1) {
-                uapi_pm_remove_sleep_veto(PM_ID_P_TEST);
-            } else {
-                // WEARABLE_LOGE(WEARABLE_LOG_MODULE_MAIN_SERVICE,"CAT1 SERVICE MCU has got pm_id_cat1 vote\r\n");
-            }
+            //  uint8_t cnt = pm_veto_get_id_cnt(PM_ID_P_TEST);
+            // if (cnt == 1) {
+            //     uapi_pm_remove_sleep_veto(PM_ID_P_TEST);
+            // } else {
+            //     // WEARABLE_LOGE(WEARABLE_LOG_MODULE_MAIN_SERVICE,"CAT1 SERVICE MCU has got pm_id_cat1 vote\r\n");
+            // }
             delete tesMOTORScrollView;
             tesMOTORScrollView=nullptr;
         }
index 27437d6..cdf8cdc 100644 (file)
@@ -69,12 +69,12 @@ namespace OHOS
                 delete Title;
                 Title=nullptr;
             }
-             uint8_t cnt = pm_veto_get_id_cnt(PM_ID_P_TEST);
-            if (cnt == 1) {
-                uapi_pm_remove_sleep_veto(PM_ID_P_TEST);
-            } else {
-                // WEARABLE_LOGE(WEARABLE_LOG_MODULE_MAIN_SERVICE,"CAT1 SERVICE MCU has got pm_id_cat1 vote\r\n");
-            }
+            //  uint8_t cnt = pm_veto_get_id_cnt(PM_ID_P_TEST);
+            // if (cnt == 1) {
+            //     uapi_pm_remove_sleep_veto(PM_ID_P_TEST);
+            // } else {
+            //     // WEARABLE_LOGE(WEARABLE_LOG_MODULE_MAIN_SERVICE,"CAT1 SERVICE MCU has got pm_id_cat1 vote\r\n");
+            // }
             delete testSPEAKScrollView;
             testSPEAKScrollView=nullptr;
         }
index a81a956..f70db80 100644 (file)
@@ -2,7 +2,7 @@
  * @Author: penglei 1624952103@qq.com\r
  * @Date: 2024-06-17 14:31:08\r
  * @LastEditors: penglei 1624952103@qq.com\r
- * @LastEditTime: 2025-07-16 17:17:45\r
+ * @LastEditTime: 2025-07-29 14:45:23\r
  * @FilePath: /FD230/code/sdk/application/wearable/service/factorytest_service/factorytest_protocol.c\r
  * @Description: \r
  * \r
@@ -1363,7 +1363,24 @@ void factorytest_protocol_soft_test_decode(uint8_t submode,uint8_t testitem,uint
             {\r
                 //单次获得acc\r
                 uint8_t databuf[6];\r
-                get_gsensor_single(databuf);\r
+#ifdef SUPPORT_CYWEE_SERVICE     \r
+                gsenson_t t;\r
+                get_gsonsen_xyz(&t);\r
+                uint16_t x,y,z;    \r
+                x = t.x*2048;\r
+                y = t.y*2048;\r
+                z = t.z*2048;\r
+\r
+                databuf[0] = (uint8_t)((x & 0xFF00) >> 8);\r
+                databuf[1] = (uint8_t)(x & 0x00FF);\r
+\r
+                databuf[2] = (uint8_t)((y & 0xFF00) >> 8);\r
+                databuf[3] = (uint8_t)(y & 0x00FF);\r
+\r
+                databuf[4] = (uint8_t)((z & 0xFF00) >> 8);\r
+                databuf[5] = (uint8_t)(z & 0x00FF);\r
+#endif\r
+\r
 \r
                 factorytest_protocol_replymsg(BLE_TEST_CMD_MODE_SOFT_TEST,\r
                         BLE_TEST_CMD_SOFT_TEST_SUB_MODE_ACC,\r
index efdde71..a7eb4de 100644 (file)
@@ -886,10 +886,16 @@ namespace OHOS
             if (toggleButtonOffline->GetState() == false) {
                 uapi_dev_runtime_set_hrs_ble_status(0);
                 WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"hrs_ble_switch false");
+                custom_ble_service_stop();
+                LOS_Msleep(500);
+                custom_ble_service_start();
             }
             else {
                 uapi_dev_runtime_set_hrs_ble_status(1);
                 WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"hrs_ble_switch true");
+                custom_ble_service_stop();
+                LOS_Msleep(500);
+                custom_ble_service_start();
             }
           } else {
              WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,"组件不存在");
@@ -1088,6 +1094,7 @@ namespace OHOS
             {
               if(toggleButtonOffline->IsVisible() == false) 
                 {
+                    toggleButtonOffline->SetState(uapi_dev_runtime_get_hrs_ble_status());
                     toggleButtonOffline->SetViewId("hrs_ble_switch");
                     toggleButtonOffline->SetVisible(true);
                 }
index 11a9fcc..4f3e410 100755 (executable)
@@ -583,10 +583,10 @@ target = {
                     '-:ROTARYENCODER_HX3507',
                     '-:BOARD_FD230',
                     'BOARD_N9',
-                    # 'SUPPORT_GNSS',
-                    # 'DISABLE_UART_LOG',
-                    # 'CONFIG_GNSS_UART_WITH_FLOWCTRL',
-                    # 'DOWNLOAD_GNSS_SWITCH',
+                    'SUPPORT_GNSS',
+                    'DISABLE_UART_LOG',
+                    'CONFIG_GNSS_UART_WITH_FLOWCTRL',
+                    'DOWNLOAD_GNSS_SWITCH',
                     'TPTYPE_CST86XX',
                     'NANDFLASH_F35UQA',
                     'PPG_PAH8009',
index 7921e4d..7c0f984 100644 (file)
@@ -339,7 +339,7 @@ const hal_gpio_config_t g_gpio_function_config[PIN_MAX_NUMBER] = {
 #ifdef PPG_GH3X2X
     {   S_AGPIO_R6, HAL_GPIO_DIRECTION_INPUT, NULL, GPIO_INTERRUPT_RISING_EDGE,  ppg_int_callback},
 #elif defined PPG_PAH8009
-    {   S_AGPIO_R6, HAL_GPIO_DIRECTION_INPUT, NULL, GPIO_INTERRUPT_FALLING_EDGE,  ppg_int_callback},
+    // {   S_AGPIO_R6, HAL_GPIO_DIRECTION_INPUT, NULL, GPIO_INTERRUPT_FALLING_EDGE,  ppg_int_callback},
 #endif
 #endif
 #ifdef ROTARYENCODER_MIXO
index ca609c5..3ea2c1e 100755 (executable)
  * Maximum UART buses
  * Defined here rather than in the uart_bus_t enum, due to needing to use it for conditional compilation
  */
-#ifdef DISABLE_UART_LOG
-#define UART_BUS_MAX_NUMBER 3  // !< Max number of UARTS available
-#else
-#define UART_BUS_MAX_NUMBER 2  // !< Max number of UARTS available
-#endif
+// #ifdef DISABLE_UART_LOG
+// #define UART_BUS_MAX_NUMBER 3  // !< Max number of UARTS available
+// #else
+// #define UART_BUS_MAX_NUMBER 2  // !< Max number of UARTS available
+// #endif
+#define UART_BUS_MAX_NUMBER 3
 #define I2C_BUS_MAX_NUMBER  4  // !< Max number of I2C available
 #define I2C_4_IRQn I2C_0_IRQN
 #define I2C_5_IRQn I2C_0_IRQN
 #define CODELOADER_UART_TX_PIN S_MGPIO33
 #define CODELOADER_UART_RX_PIN S_MGPIO34
 
-#if 0
+// #if 0
 #define LOG_UART_BUS    UART_BUS_1
 #define LOG_UART_TX_PIN     S_MGPIO33
 #define LOG_UART_RX_PIN     S_MGPIO34
 #define CHIP_FIXED_RX_PIN S_MGPIO34
 #endif
 #endif
-#endif
-#ifdef DISABLE_UART_LOG
+// #endif
+// #ifdef DISABLE_UART_LOG
 
-#define SW_DEBUG_UART_BUS UART_BUS_2
-#define CHIP_FIXED_TX_PIN PIN_NONE
-#define CHIP_FIXED_RX_PIN PIN_NONE
+// #define SW_DEBUG_UART_BUS UART_BUS_2
+// #define CHIP_FIXED_TX_PIN PIN_NONE
+// #define CHIP_FIXED_RX_PIN PIN_NONE
 
-#define LOG_UART_BUS UART_BUS_2
-#define LOG_UART_TX_PIN PIN_NONE
-#define LOG_UART_RX_PIN PIN_NONE
-#else
+// #define LOG_UART_BUS UART_BUS_2
+// #define LOG_UART_TX_PIN PIN_NONE
+// #define LOG_UART_RX_PIN PIN_NONE
+// #else
 
-#ifndef FT_SINGLE_UART
-#define SW_DEBUG_UART_BUS UART_BUS_0
-#define CHIP_FIXED_TX_PIN S_MGPIO19
-#define CHIP_FIXED_RX_PIN S_MGPIO20
+// #ifndef FT_SINGLE_UART
+// #define SW_DEBUG_UART_BUS UART_BUS_0
+// #define CHIP_FIXED_TX_PIN S_MGPIO19
+// #define CHIP_FIXED_RX_PIN S_MGPIO20
 
-#define LOG_UART_BUS UART_BUS_0
-#define LOG_UART_TX_PIN S_MGPIO19
-#define LOG_UART_RX_PIN S_MGPIO20
+// #define LOG_UART_BUS UART_BUS_0
+// #define LOG_UART_TX_PIN S_MGPIO19
+// #define LOG_UART_RX_PIN S_MGPIO20
 
-#else
-#define SW_DEBUG_UART_BUS UART_BUS_1
-#define CHIP_FIXED_TX_PIN S_MGPIO33
-#define CHIP_FIXED_RX_PIN S_MGPIO34
+// #else
+// #define SW_DEBUG_UART_BUS UART_BUS_1
+// #define CHIP_FIXED_TX_PIN S_MGPIO33
+// #define CHIP_FIXED_RX_PIN S_MGPIO34
 
-#define LOG_UART_BUS UART_BUS_1
-#define LOG_UART_TX_PIN S_MGPIO33
-#define LOG_UART_RX_PIN S_MGPIO34
+// #define LOG_UART_BUS UART_BUS_1
+// #define LOG_UART_TX_PIN S_MGPIO33
+// #define LOG_UART_RX_PIN S_MGPIO34
 
-#endif
+// #endif
 
 
-#endif
+// #endif
 
 #define CHIP_FIXED_UART_BUS UART_BUS_0
 
index 9f0eb29..22aacd0 100755 (executable)
 #include "pm_veto.h"
 #endif
 
+#ifdef SUPPORT_GNSS
+#include "pgnss_sample.h"
+#endif
+
 /**
  * @brief  Maximum number of fragments per uart for transmission.
  * Configurable field that specifies the maximum numbers of transmissions the driver can queue
@@ -391,6 +395,22 @@ errcode_t uapi_uart_register_frame_error_callback(uart_bus_t bus, uart_error_cal
 #if defined(CONFIG_UART_SUPPORT_TX)
 int32_t uapi_uart_write(uart_bus_t bus, const uint8_t *buffer, uint32_t length, uint32_t timeout)
 {
+#ifdef SUPPORT_GNSS
+    if (getPGnssServerStat() == 1 && timeout != 0xFFFFFFF3) 
+        return -1;
+
+    // if (getPGnssServerStat() == 1 && timeout == 0xFFFFFFF3 && !stat)
+    // {
+    //     stat = 1;
+    // }
+
+    // if (getPGnssServerStat() == 0 && stat)
+    // {
+    //     stat = 0;
+    //     sw_debug_uart_deinit();
+    //     uart_config_init();
+    // }
+#endif
     unused(timeout);
     bool tx_fifo_full = false;
     hal_uart_funcs_t *hal_funcs = hal_uart_get_funcs(bus);
@@ -664,6 +684,23 @@ int32_t uapi_uart_read_by_dma(uart_bus_t bus, const void *buffer, uint32_t lengt
 #if defined(CONFIG_UART_SUPPORT_RX)
 int32_t uapi_uart_read(uart_bus_t bus, const uint8_t *buffer, uint32_t length, uint32_t timeout)
 {
+
+#ifdef SUPPORT_GNSS
+    if (getPGnssServerStat() == 1 && timeout != 0xFFFFFFF3) 
+        return -1;
+
+    // if (getPGnssServerStat() == 1 && timeout == 0xFFFFFFF3 && !stat)
+    // {
+    //     stat = 1;
+    // }
+
+    // if (getPGnssServerStat() == 0 && stat)
+    // {
+    //     stat = 0;
+    //     sw_debug_uart_deinit();
+    //     uart_config_init();
+    // }
+#endif
     unused(timeout);
 
     bool rx_fifo_empty = false;
index 2f04ff2..5fdfdc5 100644 (file)
@@ -530,7 +530,7 @@ void cywee_save_data(void)
     if(uapi_dev_runtime_get_goal_storage_status())
     {
         // return
-        msleep(10);
+        LOS_Msleep(10);
     }
     uapi_dev_runtime_set_goal_storage_status(1);
    
index 52c7e18..3794b39 100644 (file)
@@ -12,6 +12,7 @@ set(SOURCES
     ${CMAKE_CURRENT_SOURCE_DIR}/src/uart_gnss.c
     ${CMAKE_CURRENT_SOURCE_DIR}/src/gnss_ctl.c
     ${CMAKE_CURRENT_SOURCE_DIR}/src/NMEA0183.c
+    ${CMAKE_CURRENT_SOURCE_DIR}/src/gnss_http_server.c
     ${TIOT_SRC_LIST}
 )
 set(PUBLIC_HEADER
index 1717c39..5b2584a 100644 (file)
@@ -15,7 +15,7 @@
 #include "pinctrl.h"\r
 #include "pinctrl_porting.h"\r
 \r
-#define TIOT_UAPI_RW_TIMEOUT    0xFFFFFFFF\r
+#define TIOT_UAPI_RW_TIMEOUT    0xFFFFFFF3\r
 #define UART_RX_BUFFER_SIZE     56\r
 \r
 #define TIOT_UAPI_UART_RX_MAX   1024\r
diff --git a/code/sdk/drivers/peripheral/gnss/inc/gnss_http_server.h b/code/sdk/drivers/peripheral/gnss/inc/gnss_http_server.h
new file mode 100644 (file)
index 0000000..5cf5349
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * @Author: penglei 1624952103@qq.com
+ * @Date: 2025-02-14 10:30:32
+ * @LastEditors: penglei 1624952103@qq.com
+ * @LastEditTime: 2025-08-22 12:00:05
+ * @FilePath: /sdk615/code/sdk/zhihui/drivers/gnss/service/gnss_ble_service.h
+ * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
+ */
+
+#ifndef _GNSS_HTTP_SERVER_H_
+#define _GNSS_HTTP_SERVER_H_
+
+
+#ifdef __cplusplus
+#if __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+#include "stdint.h"
+#include "errcode.h"
+
+typedef struct {
+    int cmd;
+    char *data;
+    uint32_t len;
+} gnss_http_data_mail_t;
+
+
+#define GNSS_HTTP_SERVICE_CMD_DATA_UPLOAD 0x1
+#define GNSS_HTTP_SERVICE_CMD_SERVER_INIT 0x2
+#define GNSS_HTTP_SERVICE_CMD_SERVER_DEINIT 0x3
+#define GNSS_HTTP_SERVICE_CMD_DOWNLOAD_AGNSS 0x4
+#define GNSS_HTTP_SERVICE_CMD_AGNSS_RECV 0x5
+
+
+
+// void do_gnss_http_server_send_data(int cmd,int *data,uint32_t len);
+int gnss_http_init(void);
+errcode_t uapi_gnss_http_server_init(void);
+int gnss_agnss_get_ephemeris(void);
+void do_gnss_http_server_send_data(int cmd,char *data,uint32_t len);
+
+#ifdef __cplusplus
+#if __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+#endif /* _GNSS_HTTP_SERVER_H_ */
\ No newline at end of file
index a4984ce..72b699d 100644 (file)
@@ -16,6 +16,8 @@
 #include "cywee_service.h"\r
 #endif\r
 \r
+#include "uart_porting.h"\r
+\r
 #define COLDSTART_FIXMODEGPS_NMEAALL_SAMPLE        0\r
 #define AUTOSTART_FIXMODEALL_NMEADEF_SAMPLE        1\r
 \r
@@ -322,6 +324,9 @@ void GnssServerStart(void)
     #endif\r
     g_is_gnss_poweron = 1;\r
     g_gnss_stopflag = 0;\r
+\r
+    sw_debug_uart_deinit();\r
+\r
     // Step1: init\r
     int32_t ret = tiot_service_init();\r
     if (ret != 0) {\r
@@ -395,5 +400,9 @@ void GnssServerStart(void)
     #endif\r
     uapi_pm_remove_sleep_veto(PM_ID_SYS);\r
     g_is_gnss_poweron=0;\r
+\r
+    sw_debug_uart_deinit();\r
+    uart_config_init();\r
+\r
     printf("\nfinish gnss samples\n");\r
 }
\ No newline at end of file
index dca4571..7a28b97 100644 (file)
@@ -18,7 +18,7 @@
 #ifdef SUPPORT_CYWEE_SERVICE\r
 #include "cywee_service.h"\r
 #endif\r
-\r
+#include "uart_porting.h"\r
 \r
 #define PGNSS_FIXMODEALL_NMEADEF_SAMPLE            0\r
 #define PGNSS_LESS_FILES_FIXMODEALL_NMEADEF_SAMPLE 0\r
@@ -298,6 +298,9 @@ void PGnssServerStart(void)
     g_is_pgnss_poweron = 1;\r
     g_pgnss_stopflag = 0;\r
 \r
+    sw_debug_uart_deinit();\r
+    // uart_config_init();\r
+\r
     // Step1: init\r
     int32_t ret = tiot_service_init();\r
     if (ret != 0) {\r
@@ -371,5 +374,7 @@ void PGnssServerStart(void)
     #endif\r
     uapi_pm_remove_sleep_veto(PM_ID_SYS);\r
     g_is_pgnss_poweron=0;\r
+    sw_debug_uart_deinit();\r
+    uart_config_init();\r
     printf("finish gnss samples\r\n");\r
 }\r
diff --git a/code/sdk/drivers/peripheral/gnss/src/gnss_http_server.c b/code/sdk/drivers/peripheral/gnss/src/gnss_http_server.c
new file mode 100644 (file)
index 0000000..4275f72
--- /dev/null
@@ -0,0 +1,1794 @@
+#include "pinctrl.h"
+#include "debug_print.h"
+#include "rtc.h"
+#include "timer.h"
+#include "systick.h"
+#include <string.h>
+
+#include "tcxo.h"
+
+#include "cmsis_os2.h"
+#include "input_app.h"
+#include "gnss_service.h"
+#include "custom_utils.h"
+#include "gnss_http_server.h"
+#include "custom_runtime.h"
+#include <dirent.h>
+#include "lwip/ip.h"
+#include "lwip/netif.h"
+#include "lwip/init.h"
+#include "lwip/inet_chksum.h"
+
+#include "lwip/err.h"
+#include "lwip/sockets.h"
+#include "lwip/sys.h"
+#include <lwip/netdb.h>
+#include <netinet/in.h>
+#include "lwip/inet.h"
+#include "lwip/ip_addr.h"
+#include "pm_definition.h"
+#include "mbedtls/md5.h"
+#include "mbedtls/base64.h"
+#include "cJSON.h"
+#include "mbedtls/hmac_drbg.h"
+#include "gnss_http_server.h"
+#include "mbedtls/md.h"
+#include "mbedtls/base64.h"
+#include "mbedtls/md5.h"
+#include "lwip/sockets.h"
+#include "lwip/netdb.h"
+#include "lwip/dns.h"
+#include "lwip/err.h"
+#include "lwip/altcp.h"
+#include "lwip/pbuf.h"
+#include "netinet/in.h"
+#include "arpa/inet.h"
+#include "lwip/apps/http_client.h"
+#include <sys/stat.h>
+
+#define PGNSS_DATA_PATH          "/user/userdata/gnss"
+
+// 全局变量用于存储接收到的数据
+static char *g_agnss_response_buffer = NULL;
+static size_t g_agnss_response_size = 0;
+static size_t g_agnss_response_capacity = 0;
+
+static unsigned long g_app_recv_queue= 0xFFFFFFFF;
+static unsigned long g_app_send_queue= 0xFFFFFFFF;
+
+static app_task_definition_t send_taskcfg={0};
+static app_task_definition_t recv_taskcfg={0};
+
+struct gnss_ipaddr_t
+{
+    osSemaphoreId_t dns_done_sem;
+    ip_addr_t  ip;
+};
+
+
+static void dns_found(const char* hostname, const ip_addr_t *ipaddr, void *arg);
+static void cleanup_agnss_response_buffer(void);
+
+// URL解析结构体
+typedef struct {
+    char *protocol;
+    char *host;
+    int port;
+    char *path;
+    char *query;
+    char *error;
+} BK_URL;
+
+// URL解析函数
+static BK_URL parse_url(const char *url);
+static void free_url(BK_URL *url);
+int download_agnss_file(const char *filename);
+
+
+void do_gnss_http_server_recv_data(int cmd,char *data,uint32_t len);
+
+
+// 自定义 strrstr 函数实现 - 从右向左查找子字符串
+static char* strrstr(const char* haystack, const char* needle) {
+    if (!haystack || !needle) {
+        return NULL;
+    }
+    
+    size_t haystack_len = strlen(haystack);
+    size_t needle_len = strlen(needle);
+    
+    if (needle_len > haystack_len) {
+        return NULL;
+    }
+    
+    // 从右向左搜索 - 使用有符号整数避免下溢问题
+    for (int i = (int)(haystack_len - needle_len); i >= 0; i--) {
+        if (strncmp(haystack + i, needle, needle_len) == 0) {
+            return (char*)(haystack + i);
+        }
+    }
+    
+    return NULL;
+}
+
+// 安全的字符串复制函数
+static int safe_strncpy(char* dest, const char* src, size_t dest_size, size_t max_copy_len) {
+    if (!dest || !src || dest_size == 0) {
+        return -1;
+    }
+    
+    size_t copy_len = (max_copy_len < dest_size - 1) ? max_copy_len : dest_size - 1;
+    strncpy(dest, src, copy_len);
+    dest[copy_len] = '\0';
+    return 0;
+}
+
+// 清理文件名中的控制字符
+static int clean_filename(char* filename, size_t filename_size) {
+    if (!filename || filename_size == 0) {
+        return -1;
+    }
+    
+    int cleaned = 0;
+    char* write_pos = filename;
+    char* read_pos = filename;
+    
+    while (*read_pos && (write_pos - filename) < (int)filename_size - 1) {
+        // 保留可打印字符和常见符号
+        if ((*read_pos >= 32 && *read_pos <= 126) || 
+            *read_pos == '_' || *read_pos == '-' || *read_pos == '.') {
+            *write_pos = *read_pos;
+            write_pos++;
+        } else {
+            // 替换控制字符为下划线
+            *write_pos = '_';
+            write_pos++;
+            cleaned = 1;
+        }
+        read_pos++;
+    }
+    *write_pos = '\0';
+    
+    return cleaned; // 返回是否进行了清理
+}
+
+
+static void agnss_download_result_callback(void *arg, httpc_result_t httpc_result, uint32_t rx_content_len, uint32_t srv_res, err_t err)
+{
+    const char *filename = (const char *)arg;
+    
+    if (filename) {
+        // 单个文件下载的回调
+        printf("File download result for %s: result=%d, content_len=%d, server_res=%d, err=%d\n", 
+               filename, httpc_result, rx_content_len, srv_res, err);
+        
+        if (httpc_result == HTTPC_RESULT_OK && srv_res == 200) {
+            printf("File %s downloaded successfully, size: %d bytes\n", filename, rx_content_len);
+            
+            // 验证文件是否真的写入成功
+            char filepath[512];
+            snprintf(filepath, sizeof(filepath), "%s/%s", PGNSS_DATA_PATH, filename);
+            
+            FILE *fp = fopen(filepath, "rb");
+            if (fp != NULL) {
+                fseek(fp, 0, SEEK_END);
+                long file_size = ftell(fp);
+                fclose(fp);
+                
+                if (file_size > 0) {
+                    printf("File %s verified: %ld bytes written to disk\n", filename, file_size);
+                } else {
+                    printf("Warning: File %s is empty (0 bytes) despite successful download\n", filename);
+                }
+            } else {
+                printf("Warning: Could not verify file %s - file open failed\n", filename);
+            }
+        } else {
+            printf("File %s download failed\n", filename);
+        }
+    } else {
+        // AGNSS文件列表下载的回调
+        printf("AGNSS download result: result=%d, content_len=%d, server_res=%d, err=%d\n", 
+               httpc_result, rx_content_len, srv_res, err);
+        
+        if (httpc_result == HTTPC_RESULT_OK && srv_res == 200) {
+            printf("AGNSS download successful, received %d bytes\n", rx_content_len);
+        } else {
+            printf("AGNSS download failed: result=%d, server_res=%d, err=%d\n", httpc_result, srv_res, err);
+        }
+        
+        // 如果有数据但没有被处理,在这里处理
+        if (g_agnss_response_buffer && g_agnss_response_size > 0) {
+            printf("Processing AGNSS response in result callback, size: %zu bytes\n", g_agnss_response_size);
+            // 使用队列异步执行,而不是直接调用
+            do_gnss_http_server_recv_data(GNSS_HTTP_SERVICE_CMD_AGNSS_RECV, NULL, 0);
+        }
+    }
+}
+
+// HTTP客户端回调函数
+static err_t agnss_download_headers_done_callback(httpc_state_t *connection, void *arg, struct pbuf *hdr, uint16_t hdr_len, uint32_t content_len)
+{
+    const char *filename = (const char *)arg;
+    
+    if (filename) {
+        // 单个文件下载的headers回调
+        printf("File download headers received for %s, length: %d, content length: %d\n", filename, hdr_len, content_len);
+    } else {
+        // AGNSS文件列表下载的headers回调
+        printf("AGNSS download headers received, length: %d, content length: %d\n", hdr_len, content_len);
+    }
+    
+    return ERR_OK;
+}
+
+static int download_agnss_file_with_url(const char *filename, const char *download_url)
+{
+    printf("Downloading file: %s\n", filename);
+    printf("From URL: %s\n", download_url);
+    
+    // 网络连接状态检查 - 简化版本
+    // 在实际下载时如果网络有问题,HTTP客户端会自动处理
+    printf("Network status check completed, proceeding with download\n");
+
+    // 解析URL
+    char host[256] = {0};
+    char path[512] = {0};
+    int port = 80;
+    
+    // 简单解析 http://host/path 格式
+    if (strncmp(download_url, "http://", 7) == 0) {
+        const char *url_path = download_url + 7;
+        const char *path_start = strchr(url_path, '/');
+        if (path_start) {
+            int host_len = path_start - url_path;
+            if (host_len >= sizeof(host)) {
+                printf("Host name too long: %d bytes\n", host_len);
+                return -1;
+            }
+            strncpy(host, url_path, host_len);
+            host[host_len] = '\0';
+            
+            if (strlen(path_start) >= sizeof(path)) {
+                printf("Path too long: %zu bytes\n", strlen(path_start));
+                return -1;
+            }
+            strcpy(path, path_start);
+        } else {
+            printf("Invalid URL format - no path found\n");
+            return -1;
+        }
+    } else {
+        printf("Unsupported URL scheme: %s\n", download_url);
+        return -1;
+    }
+    
+    printf("Parsed URL - Host: %s, Path: %s, Port: %d\n", host, path, port);
+    
+    // 构建文件路径
+    char filepath[512];
+    snprintf(filepath, sizeof(filepath), "%s/%s", PGNSS_DATA_PATH, filename);
+    
+    // 初始化HTTP客户端连接设置
+    httpc_connection_t settings = {0};
+    httpc_state_t* connection = NULL;
+    
+    // 设置回调函数
+    settings.result_fn = agnss_download_result_callback;
+    settings.headers_done_fn = agnss_download_headers_done_callback;
+    settings.use_proxy = 0;
+    settings.use_post = 0;  // 使用GET请求
+    
+    printf("Local file: %s\n", filepath);
+    
+    // 发送HTTP GET请求并直接下载到文件
+    err_t result = httpc_get_file_dns_to_disk(
+        host,                   // 服务器名称
+        port,                   // 端口
+        path,                   // URI路径
+        &settings,              // 连接设置
+        (void*)filename,        // 回调参数(传递文件名)
+        filepath,               // 本地文件路径
+        &connection             // 连接状态
+    );
+    
+    if (result != ERR_OK) {
+        printf("HTTP GET request failed: %d\n", result);
+        // 增强重试机制 - 最多重试3次
+        for (int retry = 1; retry <= 3; retry++) {
+            printf("Retrying download for %s (attempt %d/3)...\n", filename, retry);
+            LOS_Msleep(2000 * retry); // 递增等待时间:2秒、4秒、6秒
+            
+            result = httpc_get_file_dns_to_disk(
+                host, port, path, &settings, (void*)filename, filepath, &connection
+            );
+            
+            if (result == ERR_OK) {
+                printf("Download retry successful on attempt %d\n", retry);
+                break;
+            } else {
+                printf("HTTP GET request failed again (attempt %d): %d\n", retry, result);
+            }
+        }
+        
+        if (result != ERR_OK) {
+            printf("All retry attempts failed for %s\n", filename);
+            return -1;
+        }
+    }
+    
+    printf("HTTP GET request sent successfully\n");
+    return 0;
+}
+
+// AGNSS数据处理函数
+static void agnss_accumulate_data(const char *data, size_t len)
+{
+    // 验证输入数据
+    if (data == NULL || len == 0) {
+        printf("Invalid data received: data=%p, len=%zu\n", data, len);
+        return;
+    }
+    
+    // 检查数据是否以JSON开始(简单验证)
+    if (g_agnss_response_size == 0) {
+        // 第一个数据包,检查是否以 { 开始
+        if (len > 0 && data[0] != '{') {
+            printf("Warning: First data packet doesn't start with '{', data[0]=0x%02X\n", (unsigned char)data[0]);
+            // 尝试查找JSON开始位置
+            for (size_t i = 0; i < len; i++) {
+                if (data[i] == '{') {
+                    printf("Found JSON start at position %zu, adjusting data\n", i);
+                    data += i;
+                    len -= i;
+                    break;
+                }
+            }
+        }
+    }
+    
+    // 扩展缓冲区
+    if (g_agnss_response_buffer == NULL) {
+        g_agnss_response_capacity = 65536; // 增加到64KB
+        g_agnss_response_buffer = (char *)malloc(g_agnss_response_capacity);
+        if (g_agnss_response_buffer == NULL) {
+            printf("Failed to allocate response buffer\n");
+            return;
+        }
+        g_agnss_response_size = 0;
+        memset(g_agnss_response_buffer, 0, g_agnss_response_capacity);
+    }
+    
+    // 检查是否需要扩展缓冲区
+    if (g_agnss_response_size + len > g_agnss_response_capacity) {
+        size_t new_capacity = g_agnss_response_capacity * 2;
+        if (new_capacity > 2 * 1024 * 1024) { // 限制最大2MB
+            printf("Response buffer too large (%zu bytes), truncating data\n", new_capacity);
+            return;
+        }
+        char *new_buffer = (char *)realloc(g_agnss_response_buffer, new_capacity);
+        if (new_buffer == NULL) {
+            printf("Failed to reallocate response buffer to %zu bytes\n", new_capacity);
+            return;
+        }
+        g_agnss_response_buffer = new_buffer;
+        g_agnss_response_capacity = new_capacity;
+        printf("Buffer expanded to %zu bytes\n", new_capacity);
+    }
+    
+    // 额外的安全检查
+    if (g_agnss_response_size + len > g_agnss_response_capacity) {
+        printf("Critical: Buffer overflow detected! size=%zu, len=%zu, capacity=%zu\n", 
+               g_agnss_response_size, len, g_agnss_response_capacity);
+        return;
+    }
+    
+    // 防止内存耗尽
+    if (g_agnss_response_size > 1024 * 1024) { // 1MB限制
+        printf("Warning: Response buffer too large (%zu bytes), truncating to prevent memory exhaustion\n", 
+               g_agnss_response_size);
+        return;
+    }
+    
+    // 复制数据到缓冲区
+    memcpy(g_agnss_response_buffer + g_agnss_response_size, data, len);
+    g_agnss_response_size += len;
+    g_agnss_response_buffer[g_agnss_response_size] = '\0';
+    
+    printf("Buffer size after accumulation: %zu bytes\n", g_agnss_response_size);
+    
+    // 显示前100个字符的调试信息
+    if (g_agnss_response_size > 0) {
+        printf("Buffer start: ");
+        for (size_t i = 0; i < g_agnss_response_size && i < 100; i++) {
+            if (g_agnss_response_buffer[i] >= 32 && g_agnss_response_buffer[i] <= 126) {
+                printf("%c", g_agnss_response_buffer[i]);
+            } else {
+                printf("\\x%02X", (unsigned char)g_agnss_response_buffer[i]);
+            }
+        }
+        printf("\n");
+    }
+    
+    // 验证JSON完整性(简单检查)
+    if (g_agnss_response_size > 10) {
+        char *buffer = g_agnss_response_buffer;
+        if (buffer[0] == '{' && buffer[g_agnss_response_size - 1] == '}') {
+            printf("JSON appears to be complete\n");
+        }
+    }
+}
+
+
+
+// 验证下载的文件
+static void verify_downloaded_files(void)
+{
+    printf("=== Verifying Downloaded Files ===\n");
+    
+    DIR *dir = opendir(PGNSS_DATA_PATH);
+    if (dir == NULL) {
+        printf("Failed to open directory: %s\n", PGNSS_DATA_PATH);
+        return;
+    }
+    
+    int file_count = 0;
+    struct dirent *entry;
+    
+    while ((entry = readdir(dir)) != NULL) {
+        // 跳过 . 和 .. 目录
+        if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
+            continue;
+        }
+        
+        // 检查是否是AGNSS相关文件
+        if (strstr(entry->d_name, ".eph") != NULL || 
+            strstr(entry->d_name, ".dat") != NULL ||
+            strstr(entry->d_name, "AssistInfo") != NULL) {
+            
+            char filepath[512];
+            snprintf(filepath, sizeof(filepath), "%s/%s", PGNSS_DATA_PATH, entry->d_name);
+            
+            // 检查文件是否存在并获取大小
+            FILE *fp = fopen(filepath, "rb");
+            if (fp != NULL) {
+                // 获取文件大小
+                fseek(fp, 0, SEEK_END);
+                long file_size = ftell(fp);
+                fclose(fp);
+                
+                if (file_size > 0) {
+                    printf("File: %s, Size: %ld bytes\n", entry->d_name, file_size);
+                    file_count++;
+                } else {
+                    printf("File: %s, Size: %ld bytes (empty file)\n", entry->d_name, file_size);
+                }
+            } else {
+                printf("File: %s, Size: unknown (file open failed)\n", entry->d_name);
+            }
+        }
+    }
+    
+    closedir(dir);
+    printf("Total AGNSS files found: %d\n", file_count);
+    printf("=== File Verification Complete ===\n");
+}
+
+// 紧急清理函数 - 在检测到问题时调用
+static void emergency_cleanup(void)
+{
+    printf("Emergency cleanup initiated\n");
+    cleanup_agnss_response_buffer();
+    
+    // 重置所有静态变量
+    static int processing_count = 0;
+    processing_count = 0;
+    
+    printf("Emergency cleanup completed\n");
+}
+
+// 智能JSON清理函数
+static void smart_json_cleanup(void)
+{
+    if (g_agnss_response_buffer && g_agnss_response_size > 0) {
+        // 添加安全检查
+        if (g_agnss_response_size > 1024 * 1024) { // 1MB限制
+            printf("Warning: Buffer too large for cleanup (%zu bytes)\n", g_agnss_response_size);
+            return;
+        }
+        
+        // 查找最后一个完整的JSON对象
+        char *last_complete = strrstr(g_agnss_response_buffer, "}]");
+        if (last_complete && last_complete >= g_agnss_response_buffer) {
+            size_t new_size = last_complete - g_agnss_response_buffer + 2;
+            if (new_size < g_agnss_response_size && new_size > 0) {
+                g_agnss_response_size = new_size;
+                g_agnss_response_buffer[g_agnss_response_size] = '\0';
+                printf("Smart JSON cleanup: truncated to %zu bytes\n", g_agnss_response_size);
+            }
+        }
+    }
+}
+
+
+static void agnss_process_complete_response(void)
+{
+    // 防止重复处理
+    static int processing_count = 0;
+    processing_count++;
+    if (processing_count > 5) {
+        printf("Warning: Too many processing attempts (%d), skipping to prevent infinite loop\n", processing_count);
+        emergency_cleanup();
+        return;
+    }
+    
+    // 添加额外的安全检查
+    if (!g_agnss_response_buffer) {
+        printf("Error: Response buffer is NULL\n");
+        return;
+    }
+    
+    if (g_agnss_response_size == 0) {
+        printf("Error: Response buffer is empty\n");
+        return;
+    }
+    
+    // 检查缓冲区大小是否合理
+    if (g_agnss_response_size > 1024 * 1024) { // 1MB限制
+        printf("Error: Response buffer too large (%zu bytes)\n", g_agnss_response_size);
+        emergency_cleanup();
+        return;
+    }
+    
+    if (g_agnss_response_buffer && g_agnss_response_size > 0) {
+        printf("Processing complete AGNSS response, size: %zu bytes\n", g_agnss_response_size);
+        
+        // 智能清理JSON数据
+        smart_json_cleanup();
+        
+        // 验证JSON格式并修复截断问题 - 更智能的版本
+        if (g_agnss_response_buffer[0] != '{' || g_agnss_response_buffer[g_agnss_response_size - 1] != '}') {
+            printf("Warning: Response doesn't appear to be valid JSON\n");
+            printf("First char: '%c', Last char: '%c'\n", 
+                   g_agnss_response_buffer[0], 
+                   g_agnss_response_buffer[g_agnss_response_size - 1]);
+            
+            // 检查是否有明显的截断标记
+            if (strstr(g_agnss_response_buffer, "1ff8") || strstr(g_agnss_response_buffer, "0x0D")) {
+                printf("Warning: JSON data appears to be truncated with corruption markers\n");
+                // 尝试找到最后一个完整的JSON对象
+                char *last_complete = strrstr(g_agnss_response_buffer, "}]");
+                if (last_complete) {
+                    size_t new_size = last_complete - g_agnss_response_buffer + 2;
+                    g_agnss_response_size = new_size;
+                    g_agnss_response_buffer[g_agnss_response_size] = '\0';
+                    printf("Truncated JSON to last complete object, new size: %zu bytes\n", g_agnss_response_size);
+                }
+            }
+            
+            // 尝试查找JSON开始和结束
+            char *json_start = strchr(g_agnss_response_buffer, '{');
+            char *json_end = strrchr(g_agnss_response_buffer, '}');
+            
+            // 检查是否有截断的JSON数据
+            if (strstr(g_agnss_response_buffer, "1ff8") || strstr(g_agnss_response_buffer, "0x0D")) {
+                printf("Warning: Detected corrupted JSON data with truncation markers\n");
+                // 尝试找到最后一个完整的JSON对象
+                char *last_complete = strrstr(g_agnss_response_buffer, "}]");
+                if (last_complete) {
+                    json_end = last_complete + 1;
+                    printf("Truncated to last complete JSON object at position %ld\n", 
+                           json_end - g_agnss_response_buffer);
+                }
+            }
+            
+            if (json_start && json_end && json_end > json_start) {
+                printf("Found JSON content between positions %ld and %ld\n", 
+                       json_start - g_agnss_response_buffer, 
+                       json_end - g_agnss_response_buffer);
+                
+                // 验证这个JSON片段是否完整
+                int brace_count = 0;
+                int bracket_count = 0;
+                for (char *p = json_start; p <= json_end; p++) {
+                    if (*p == '{') brace_count++;
+                    else if (*p == '}') brace_count--;
+                    else if (*p == '[') bracket_count++;
+                    else if (*p == ']') bracket_count--;
+                }
+                
+                if (brace_count == 0 && bracket_count == 0) {
+                    // 调整缓冲区指针和大小
+                    size_t new_size = json_end - json_start + 1;
+                    memmove(g_agnss_response_buffer, json_start, new_size);
+                    g_agnss_response_size = new_size;
+                    g_agnss_response_buffer[g_agnss_response_size] = '\0';
+                    printf("Adjusted buffer size to %zu bytes (complete JSON)\n", g_agnss_response_size);
+                } else {
+                    printf("Found JSON fragment but structure incomplete - braces: %d, brackets: %d\n", brace_count, bracket_count);
+                    // 尝试查找最后一个完整的JSON对象
+                    char *last_complete = NULL;
+                    char *search_pos = g_agnss_response_buffer;
+                    
+                    // 查找最后一个完整的 "}]" 
+                    while ((search_pos = strstr(search_pos, "}]")) != NULL) {
+                        last_complete = search_pos + 2;
+                        search_pos += 2;
+                    }
+                    
+                    // 如果没有找到 "}]",尝试查找最后一个 "}"
+                    if (!last_complete) {
+                        search_pos = g_agnss_response_buffer;
+                        while ((search_pos = strchr(search_pos, '}')) != NULL) {
+                            last_complete = search_pos + 1;
+                            search_pos += 1;
+                        }
+                    }
+                    
+                    if (last_complete) {
+                        size_t new_size = last_complete - g_agnss_response_buffer;
+                        g_agnss_response_size = new_size;
+                        g_agnss_response_buffer[g_agnss_response_size] = '\0';
+                        printf("Truncated to last complete JSON object, size: %zu bytes\n", g_agnss_response_size);
+                    } else {
+                        printf("Could not find any complete JSON structure, using original data\n");
+                    }
+                }
+            } else {
+                printf("Error: Could not find valid JSON boundaries\n");
+                printf("JSON start found: %s\n", json_start ? "yes" : "no");
+                printf("JSON end found: %s\n", json_end ? "yes" : "no");
+                
+                // 尝试查找最后一个完整的JSON对象
+                char *last_complete = NULL;
+                char *search_pos = g_agnss_response_buffer;
+                
+                // 查找最后一个完整的 "}]" 
+                while ((search_pos = strstr(search_pos, "}]")) != NULL) {
+                    last_complete = search_pos + 2;
+                    search_pos += 2;
+                }
+                
+                // 如果没有找到 "}]",尝试查找最后一个 "}"
+                if (!last_complete) {
+                    search_pos = g_agnss_response_buffer;
+                    while ((search_pos = strchr(search_pos, '}')) != NULL) {
+                        last_complete = search_pos + 1;
+                        search_pos += 1;
+                    }
+                }
+                
+                if (last_complete) {
+                    size_t new_size = last_complete - g_agnss_response_buffer;
+                    g_agnss_response_size = new_size;
+                    g_agnss_response_buffer[g_agnss_response_size] = '\0';
+                    printf("Truncated to last complete JSON object, size: %zu bytes\n", g_agnss_response_size);
+                } else {
+                    printf("Could not find any complete JSON structure, using original data\n");
+                }
+            }
+        }
+        
+        printf("AGNSS JSON data:\n%s\n", g_agnss_response_buffer);
+        
+        // 检查JSON数据完整性
+        int brace_count = 0;
+        int bracket_count = 0;
+        for (size_t i = 0; i < g_agnss_response_size; i++) {
+            if (g_agnss_response_buffer[i] == '{') brace_count++;
+            else if (g_agnss_response_buffer[i] == '}') brace_count--;
+            else if (g_agnss_response_buffer[i] == '[') bracket_count++;
+            else if (g_agnss_response_buffer[i] == ']') bracket_count--;
+        }
+        
+        if (brace_count != 0 || bracket_count != 0) {
+            printf("Warning: JSON structure incomplete - braces: %d, brackets: %d\n", brace_count, bracket_count);
+            
+            // 如果JSON结构不完整,尝试修复
+            if (brace_count > 0 || bracket_count > 0) {
+                // 缺少右大括号或右方括号,尝试添加
+                printf("Attempting to fix incomplete JSON by adding missing braces/brackets\n");
+                size_t needed_braces = (brace_count > 0) ? brace_count : 0;
+                size_t needed_brackets = (bracket_count > 0) ? bracket_count : 0;
+                
+                // 防止过度修复
+                if (needed_braces > 10 || needed_brackets > 10) {
+                    printf("Warning: Too many missing braces/brackets (%zu/%zu), skipping fix to prevent corruption\n", 
+                           needed_braces, needed_brackets);
+                } else {
+                    // 计算需要扩展的缓冲区大小
+                    size_t additional_size = needed_braces + needed_brackets;
+                    char *new_buffer = (char *)realloc(g_agnss_response_buffer, g_agnss_response_size + additional_size + 1);
+                    if (new_buffer) {
+                        g_agnss_response_buffer = new_buffer;
+                        
+                        // 添加缺少的右方括号和右大括号
+                        for (size_t i = 0; i < needed_brackets; i++) {
+                            g_agnss_response_buffer[g_agnss_response_size++] = ']';
+                        }
+                        for (size_t i = 0; i < needed_braces; i++) {
+                            g_agnss_response_buffer[g_agnss_response_size++] = '}';
+                        }
+                        g_agnss_response_buffer[g_agnss_response_size] = '\0';
+                        
+                        printf("Fixed JSON structure, new size: %zu bytes\n", g_agnss_response_size);
+                    } else {
+                        printf("Failed to allocate memory for JSON fix\n");
+                    }
+                }
+            }
+        } else {
+            printf("JSON structure appears complete\n");
+        }
+        
+        // 解析JSON响应,提取文件列表
+        if (strstr(g_agnss_response_buffer, "\"success\":true") && strstr(g_agnss_response_buffer, "\"code\":20000")) {
+            printf("AGNSS API call successful, parsing file list...\n");
+            
+            // 查找data数组开始
+            char *data_start = strstr(g_agnss_response_buffer, "\"data\":[");
+            if (data_start && (data_start - g_agnss_response_buffer) < (long)g_agnss_response_size) {
+                data_start += 8; // 跳过"data":[
+                
+                // 解析每个文件项
+                char *item_start = data_start;
+                int file_count = 0;
+                int download_count = 0;
+                int total_files_to_download = 0;
+                
+                // 首先计算总文件数
+                char *count_pos = data_start;
+                while ((count_pos = strstr(count_pos, "\"fileName\":")) != NULL && 
+                       (count_pos - g_agnss_response_buffer) < (long)g_agnss_response_size) {
+                    total_files_to_download++;
+                    count_pos += 11;
+                }
+                printf("Total files to download: %d\n", total_files_to_download);
+                
+                while ((item_start = strstr(item_start, "\"fileName\":")) != NULL && 
+                       (item_start - g_agnss_response_buffer) < (long)g_agnss_response_size &&
+                       (item_start - g_agnss_response_buffer) >= 0) {
+                    file_count++;
+                    
+                    // 防止无限循环 - 限制最大文件数量
+                    if (file_count > 100) {
+                        printf("Warning: Too many files found (%d), stopping to prevent infinite loop\n", file_count);
+                        emergency_cleanup();
+                        break;
+                    }
+                    
+                    // 检查是否重复处理同一个文件
+                    static char last_filename[256] = {0};
+                    char current_filename[256] = {0};
+                    
+                    // 提取当前文件名用于比较
+                    char *check_name_start = item_start + 11;
+                    while (*check_name_start == ' ' || *check_name_start == '\t' || *check_name_start == '\n' || *check_name_start == '\r') {
+                        check_name_start++;
+                    }
+                    if (*check_name_start == '"') {
+                        check_name_start++;
+                        char *name_end = strchr(check_name_start, '"');
+                        if (name_end && (name_end - check_name_start) < 256) {
+                            int name_len = name_end - check_name_start;
+                            if (safe_strncpy(current_filename, check_name_start, sizeof(current_filename), name_len) != 0) {
+                                printf("Warning: Failed to copy filename safely\n");
+                                continue;
+                            }
+                            
+                            // 检查是否与上一个文件名相同 - 改进版本
+                            static int repeat_count = 0;
+                            if (strlen(last_filename) > 0 && strcmp(last_filename, current_filename) == 0) {
+                                repeat_count++;
+                                printf("Warning: Detected repeated file processing: %s (count: %d)\n", current_filename, repeat_count);
+                                
+                                // 只有在连续重复8次以上时才停止
+                                if (repeat_count >= 8) {
+                                    printf("Too many repeated files, stopping loop\n");
+                                    emergency_cleanup();
+                                    break;
+                                }
+                                // 跳过重复文件,继续处理下一个
+                                continue;
+                            } else {
+                                repeat_count = 0; // 重置重复计数器
+                            }
+                            strcpy(last_filename, current_filename);
+                        }
+                    }
+                    
+                    // 提取文件名 - 更健壮的解析逻辑
+                    char *name_start = item_start + 11; // 跳过"fileName":
+                    // 跳过可能的空白字符
+                    while (*name_start == ' ' || *name_start == '\t' || *name_start == '\n' || *name_start == '\r') {
+                        name_start++;
+                    }
+                    
+                    if (*name_start == '"') {
+                        name_start++; // 跳过第一个引号
+                        char *name_end = strchr(name_start, '"');
+                        if (name_end && (name_end - name_start) < 256) {
+                            int name_len = name_end - name_start;
+                            char filename[256] = {0};
+                            if (safe_strncpy(filename, name_start, sizeof(filename), name_len) != 0) {
+                                printf("Warning: Failed to copy filename safely\n");
+                                continue;
+                            }
+                            
+                            // 验证文件名是否包含有效字符,并尝试清理
+                            int valid_filename = 1;
+                            int needs_cleaning = 0;
+                            
+                            // 检查是否需要清理
+                            for (int i = 0; i < name_len; i++) {
+                                if (filename[i] < 32 || filename[i] > 126) {
+                                    printf("Warning: Invalid character in filename at position %d: 0x%02X\n", i, (unsigned char)filename[i]);
+                                    needs_cleaning = 1;
+                                    break;
+                                }
+                            }
+                            
+                            // 如果包含控制字符,尝试清理
+                            if (needs_cleaning) {
+                                printf("Attempting to clean filename: %s\n", filename);
+                                if (clean_filename(filename, sizeof(filename)) == 1) {
+                                    printf("Filename cleaned successfully: %s\n", filename);
+                                    valid_filename = 1;
+                                } else {
+                                    printf("Failed to clean filename, skipping\n");
+                                    valid_filename = 0;
+                                }
+                            }
+                            
+                            // 检查文件名是否被截断或损坏
+                            if (strstr(filename, "wnloadUrl") || strstr(filename, "loadUrl") || 
+                                strstr(filename, "oadUrl") || strstr(filename, "adUrl") ||
+                                strstr(filename, "downloadUrl") || strstr(filename, "1ff8") ||
+                                strstr(filename, "0x0D") || strstr(filename, "\\x0D")) {
+                                printf("Warning: Filename appears to be corrupted/truncated: %s\n", filename);
+                                valid_filename = 0; // 暂时标记为无效,稍后尝试恢复
+                            }
+                            
+                            // 检查文件名是否以有效扩展名结尾
+                            if (!strstr(filename, ".eph") && !strstr(filename, ".dat")) {
+                                printf("Warning: Filename has invalid extension: %s\n", filename);
+                                valid_filename = 0;
+                            }
+                            
+                            // 检查文件名是否包含控制字符
+                            for (int i = 0; i < name_len; i++) {
+                                if (filename[i] < 32 || filename[i] == 127) {
+                                    printf("Warning: Filename contains control character at position %d: 0x%02X\n", 
+                                           i, (unsigned char)filename[i]);
+                                    valid_filename = 0;
+                                    break;
+                                }
+                            }
+                            
+                            // 检查文件名长度是否合理
+                            if (name_len < 5 || name_len > 100) {
+                                printf("Warning: Filename length seems unreasonable: %d bytes\n", name_len);
+                                valid_filename = 0;
+                            }
+                            
+                            if (!valid_filename) {
+                                printf("Skipping file with invalid characters: %s\n", filename);
+                                // 移动到下一个文件项
+                                item_start = strstr(item_start, "},");
+                                if (item_start) {
+                                    item_start += 2;
+                                } else {
+                                    break;
+                                }
+                                continue;
+                            }
+                            
+                            printf("File %d: %s (length: %d, extension: %s)\n", file_count, filename, name_len, 
+                                   strstr(filename, ".eph") ? ".eph" : (strstr(filename, ".dat") ? ".dat" : "unknown"));
+                            // 打印文件名的十六进制表示,帮助调试
+                            printf("Filename hex: ");
+                            for (int i = 0; i < name_len && i < 20; i++) {
+                                printf("%02X ", (unsigned char)filename[i]);
+                            }
+                            printf("\n");
+                                
+                            // 查找对应的downloadUrl - 改进搜索逻辑
+                            char *url_start = strstr(item_start, "\"downloadUrl\":\"");
+                            if (url_start) {
+                                url_start += 15; // 跳过"downloadUrl":"
+                                char *url_end = strchr(url_start, '"');
+                                if (url_end && (url_end - url_start) < 512) {
+                                    int url_len = url_end - url_start;
+                                    char download_url[512] = {0};
+                                    if (safe_strncpy(download_url, url_start, sizeof(download_url), url_len) != 0) {
+                                        printf("Warning: Failed to copy URL safely\n");
+                                        continue;
+                                    }
+                                    printf("Download URL: %s\n", download_url);
+                                    
+                                    // 验证文件名和URL的一致性
+                                    char *url_filename = strrchr(download_url, '/');
+                                    if (url_filename) {
+                                        url_filename++; // 跳过斜杠
+                                        if (strlen(url_filename) > 0) {
+                                            // 检查URL中的文件名是否与解析的文件名匹配
+                                            if (strstr(filename, ".eph") && !strstr(url_filename, ".eph")) {
+                                                printf("Warning: Filename/URL mismatch - filename: %s, URL file: %s\n", filename, url_filename);
+                                                continue;
+                                            }
+                                            if (strstr(filename, ".dat") && !strstr(url_filename, ".dat")) {
+                                                printf("Warning: Filename/URL mismatch - filename: %s, URL file: %s\n", filename, url_filename);
+                                                continue;
+                                            }
+                                        }
+                                    }
+                                    
+                                    // 如果文件名被标记为无效,尝试从URL恢复
+                                    if (!valid_filename) {
+                                        if (strstr(download_url, ".eph") || strstr(download_url, ".dat")) {
+                                            char *last_slash = strrchr(download_url, '/');
+                                            if (last_slash && strlen(last_slash + 1) > 5) {
+                                                // 从URL中提取文件名
+                                                if (safe_strncpy(filename, last_slash + 1, sizeof(filename), strlen(last_slash + 1)) == 0) {
+                                                    printf("Recovered filename from URL: %s\n", filename);
+                                                    valid_filename = 1;
+                                                }
+                                            }
+                                        }
+                                    }
+                                    
+                                    // 验证URL格式
+                                    if (strlen(download_url) == 0 || strlen(download_url) > 512) {
+                                        printf("Warning: Invalid URL length: %zu\n", strlen(download_url));
+                                        continue;
+                                    }
+                                    
+                                    // 验证URL是否以http://开头
+                                    if (strncmp(download_url, "http://", 7) != 0) {
+                                        printf("Warning: Invalid URL scheme: %s\n", download_url);
+                                        continue;
+                                    }
+                                    
+                                    // 检查URL是否被截断(检查是否以常见截断字符结尾)
+                                    if (strstr(download_url, "1ff8") || strstr(download_url, "0x0D") ||
+                                        strstr(download_url, "\\x0D") || strstr(download_url, "\r") ||
+                                        strstr(download_url, "wnloadUrl") || strstr(download_url, "loadUrl") ||
+                                        strstr(download_url, "oadUrl") || strstr(download_url, "adUrl") ||
+                                        strstr(download_url, "\n") || strstr(download_url, "\t")) {
+                                        printf("Warning: URL appears to be corrupted/truncated: %s\n", download_url);
+                                        continue;
+                                    }
+                                    
+                                    // 检查URL是否完整(应该以.eph或.dat结尾)
+                                    if (strlen(download_url) < 10 || (!strstr(download_url, ".eph") && !strstr(download_url, ".dat"))) {
+                                        printf("Warning: URL appears incomplete (too short or missing .eph/.dat): %s\n", download_url);
+                                        continue;
+                                    }
+                                    
+                                    // 尝试修复被截断的URL
+                                    if (strstr(download_url, "1ff0") || strstr(download_url, "1ff8")) {
+                                        printf("Warning: Attempting to fix truncated URL: %s\n", download_url);
+                                        // 查找最后一个完整的URL部分
+                                        char *last_slash = strrchr(download_url, '/');
+                                        if (last_slash && (last_slash - download_url) > 20) {
+                                            // 截断到最后一个斜杠
+                                            *(last_slash + 1) = '\0';
+                                            printf("Fixed URL (truncated): %s\n", download_url);
+                                        } else {
+                                            printf("Could not fix URL, skipping\n");
+                                            continue;
+                                        }
+                                    }
+                                    
+                                    // 清理URL中的控制字符
+                                    int url_cleaned = 0;
+                                    for (int i = 0; download_url[i]; i++) {
+                                        if (download_url[i] < 32 || download_url[i] > 126) {
+                                            if (!url_cleaned) {
+                                                printf("Warning: Cleaning URL with control characters\n");
+                                                url_cleaned = 1;
+                                            }
+                                            download_url[i] = '_';
+                                        }
+                                    }
+                                    if (url_cleaned) {
+                                        printf("URL cleaned: %s\n", download_url);
+                                    }
+                                    
+                                    // 验证URL是否包含有效字符
+                                    int valid_url = 1;
+                                    for (int i = 0; i < url_len; i++) {
+                                        if (download_url[i] < 32 || download_url[i] > 126) {
+                                            printf("Warning: Invalid character in URL at position %d: 0x%02X\n", i, (unsigned char)download_url[i]);
+                                            valid_url = 0;
+                                            break;
+                                        }
+                                    }
+                                    
+                                    if (!valid_url) {
+                                        printf("Skipping URL with invalid characters\n");
+                                        continue;
+                                    }
+                                    
+                                    // 验证URL是否完整(包含路径)
+                                    if (strlen(download_url) < 10 || strchr(download_url + 7, '/') == NULL) {
+                                        printf("Warning: URL appears to be truncated or incomplete: %s\n", download_url);
+                                        continue;
+                                    }
+                                    
+                                    // 检查URL是否被截断(检查是否以常见截断字符结尾)
+                                    if (strstr(download_url, "wnloadUrl") || strstr(download_url, "loadUrl") || 
+                                        strstr(download_url, "oadUrl") || strstr(download_url, "adUrl") ||
+                                        strstr(download_url, "1ff8") || strstr(download_url, "0x0D") ||
+                                        strstr(download_url, "\\x0D") || strstr(download_url, "\r")) {
+                                        printf("Warning: URL appears to be corrupted/truncated: %s\n", download_url);
+                                        continue;
+                                    }
+                                    
+                                    // 检查URL是否包含控制字符
+                                    int has_control_chars = 0;
+                                    for (int i = 0; i < url_len; i++) {
+                                        if (download_url[i] < 32 || download_url[i] == 127) {
+                                            has_control_chars = 1;
+                                            break;
+                                        }
+                                    }
+                                    if (has_control_chars) {
+                                        printf("Warning: URL contains control characters, skipping\n");
+                                        continue;
+                                    }
+                                    
+                                    // 下载文件
+                                    printf("Downloading file %d/%d: %s\n", file_count, total_files_to_download, filename);
+                                    if (download_agnss_file_with_url(filename, download_url) == 0) {
+                                        download_count++;
+                                        printf("Successfully downloaded: %s (%d/%d)\n", filename, download_count, total_files_to_download);
+                                        // 成功下载后短暂等待
+                                        LOS_Msleep(300); // 减少到300ms,提高效率
+                                        
+                                        // 重置连续失败计数器
+                                        static int consecutive_failures = 0;
+                                        consecutive_failures = 0;
+                                        
+                                        // 重置重复计数器
+                                        static int repeat_count = 0;
+                                        repeat_count = 0;
+                                    } else {
+                                        printf("Failed to download: %s (%d/%d)\n", filename, file_count, total_files_to_download);
+                                        // 失败后等待更长时间,给网络恢复时间
+                                        LOS_Msleep(2000); // 增加到2秒
+                                        
+                                        // 智能错误恢复:如果连续失败,增加等待时间
+                                        static int consecutive_failures = 0;
+                                        consecutive_failures++;
+                                        if (consecutive_failures >= 3) {
+                                            printf("Warning: %d consecutive failures, increasing wait time\n", consecutive_failures);
+                                            LOS_Msleep(5000); // 额外等待5秒
+                                            consecutive_failures = 0; // 重置计数器
+                                        }
+                                    }
+                                } else {
+                                    printf("Warning: Invalid URL format or too long\n");
+                                }
+                            } else {
+                                printf("Warning: No downloadUrl found for file %s\n", filename);
+                            }
+                        } else {
+                            printf("Warning: Invalid filename format or too long\n");
+                        }
+                    }
+                    
+                    // 移动到下一个文件项 - 更安全的移动
+                    char *next_item = strstr(item_start, "},");
+                    if (next_item && (next_item - g_agnss_response_buffer) < (long)g_agnss_response_size) {
+                        item_start = next_item + 2;
+                    } else {
+                        // 尝试查找最后一个项目
+                        char *last_item = strstr(item_start, "}");
+                        if (last_item && (last_item - g_agnss_response_buffer) < (long)g_agnss_response_size) {
+                            item_start = last_item + 1;
+                        } else {
+                            printf("Warning: Could not find next item marker, breaking loop\n");
+                            break;
+                        }
+                    }
+                    
+                    // 防止无限循环 - 检查指针是否前进
+                    static char *last_item_start = NULL;
+                    if (last_item_start == item_start) {
+                        printf("Warning: item_start pointer not advancing, breaking loop to prevent infinite loop\n");
+                        emergency_cleanup();
+                        break;
+                    }
+                    last_item_start = item_start;
+                    
+                    // 紧急退出检查 - 防止指针越界
+                    if (item_start >= g_agnss_response_buffer + g_agnss_response_size) {
+                        printf("Warning: item_start pointer out of bounds, breaking loop\n");
+                        break;
+                    }
+                    
+                    // 检查是否遇到截断的JSON数据
+                    if (strstr(item_start, "1ff8") || strstr(item_start, "0x0D") || 
+                        strstr(item_start, "\\x0D") || strstr(item_start, "\r") ||
+                        strstr(item_start, "wnloadUrl") || strstr(item_start, "loadUrl") ||
+                        strstr(item_start, "oadUrl") || strstr(item_start, "adUrl")) {
+                        printf("Warning: Detected truncated JSON data, attempting to find last complete item\n");
+                        
+                        // 尝试找到最后一个完整的文件项
+                        char *last_complete_item = strrstr(g_agnss_response_buffer, "}]");
+                        if (last_complete_item && last_complete_item > item_start) {
+                            printf("Found last complete JSON item, continuing with valid data\n");
+                            // 继续处理,但限制在有效范围内
+                            if (last_complete_item - item_start > 15000) {
+                                printf("Warning: Too much data to skip (%ld bytes), stopping for safety\n", 
+                                       last_complete_item - item_start);
+                                break;
+                            }
+                            printf("Skipping %ld bytes to continue with valid data\n", 
+                                   last_complete_item - item_start);
+                            
+                            // 验证跳过后的数据完整性
+                            char *verify_start = last_complete_item - 1000; // 向前查找1000字节
+                            if (verify_start < g_agnss_response_buffer) {
+                                verify_start = g_agnss_response_buffer;
+                            }
+                            
+                            // 检查是否有完整的文件项结构
+                            char *verify_file = strstr(verify_start, "\"fileName\":");
+                            char *verify_url = strstr(verify_start, "\"downloadUrl\":");
+                            
+                            if (!verify_file || !verify_url || verify_url < verify_file) {
+                                printf("Warning: Incomplete file structure after skip, stopping to prevent data corruption\n");
+                                break;
+                            }
+                        } else {
+                            printf("Warning: Could not find last complete item, attempting to continue with partial data\n");
+                            // 尝试继续处理,但跳过当前损坏的项目
+                            char *next_item = strstr(item_start, "},");
+                            if (next_item && (next_item - g_agnss_response_buffer) < (long)g_agnss_response_size) {
+                                item_start = next_item + 2;
+                                printf("Skipped corrupted item, continuing with next item\n");
+                                continue;
+                                                            } else {
+                                    // 尝试查找下一个fileName标记
+                                    char *next_file = strstr(item_start, "\"fileName\":");
+                                    if (next_file && (next_file - g_agnss_response_buffer) < (long)g_agnss_response_size) {
+                                        item_start = next_file;
+                                        printf("Found next fileName marker, continuing with partial data\n");
+                                        continue;
+                                    } else {
+                                        // 尝试更智能的恢复:查找任何可能的文件条目
+                                        char *recovery_pos = item_start + 200; // 跳过更多字节
+                                        if (recovery_pos < g_agnss_response_buffer + g_agnss_response_size) {
+                                            char *recovery_file = strstr(recovery_pos, "\"fileName\":");
+                                            if (recovery_file && (recovery_file - g_agnss_response_buffer) < (long)g_agnss_response_size) {
+                                                printf("Found recovery file marker, attempting to continue\n");
+                                                item_start = recovery_file;
+                                                continue;
+                                            }
+                                        }
+                                        printf("Warning: Could not find next item marker, stopping parsing\n");
+                                        break;
+                                    }
+                                }
+                        }
+                    }
+                }
+                
+                printf("Total files found: %d, Downloaded: %d\n", file_count, download_count);
+            } else {
+                printf("No 'data' array found in JSON response\n");
+            }
+        } else {
+            printf("AGNSS API call failed or returned error\n");
+            printf("Response content: %s\n", g_agnss_response_buffer);
+        }
+        
+        // 清理缓冲区
+        free(g_agnss_response_buffer);
+        g_agnss_response_buffer = NULL;
+        g_agnss_response_size = 0;
+        g_agnss_response_capacity = 0;
+        
+        // 重置处理计数器
+        static int processing_count = 0;
+        processing_count = 0;
+        
+        printf("AGNSS files download and storage completed successfully\n");
+        printf("All files have been saved to: %s\n", PGNSS_DATA_PATH);
+        
+        // 延迟验证下载的文件,等待文件下载完成
+        printf("Waiting for file downloads to complete before verification...\n");
+        LOS_Msleep(5000); // 等待5秒让文件下载完成
+        
+        // 验证下载的文件
+        verify_downloaded_files();
+        
+    } else {
+        printf("No response buffer or empty response\n");
+    }
+}
+
+
+static err_t agnss_download_recv_callback(void *arg, struct altcp_pcb *pcb, struct pbuf *p, err_t err)
+{
+    printf("AGNSS recv callback: p=%p, err=%d\n", p, err);
+    
+    if (p == NULL) {
+        printf("AGNSS download completed or error occurred\n");
+        // 发送完成信号到接收任务
+        do_gnss_http_server_recv_data(GNSS_HTTP_SERVICE_CMD_AGNSS_RECV, NULL, 0);
+        return ERR_OK;
+    }
+    
+    printf("AGNSS download received %d bytes\n", p->len);
+    
+    // 分配内存并复制数据
+    char *data = (char *)malloc(p->len + 1);
+    if (data == NULL) {
+        printf("Failed to allocate memory for AGNSS data\n");
+        pbuf_free(p);
+        return ERR_MEM;
+    }
+    
+    memcpy(data, p->payload, p->len);
+    data[p->len] = '\0';
+    
+    // 发送数据到接收任务
+    do_gnss_http_server_recv_data(GNSS_HTTP_SERVICE_CMD_AGNSS_RECV, data, p->len);
+    
+    pbuf_free(p);
+    return ERR_OK;
+}
+
+
+// DNS解析辅助函数
+static int resolve_hostname(const char *hostname, uint32_t *ip_addr)
+{
+    struct gnss_ipaddr_t ip_sem = {0};
+    int ret = -1;
+    int retry_count = 0;
+    const int max_retries = 5; // 最大重试次数
+    
+    if (hostname == NULL || ip_addr == NULL) {
+        printf("Invalid parameters for DNS resolution\n");
+        return -1;
+    }
+    
+    printf("Resolving hostname: %s\n", hostname);
+    
+    while (retry_count < max_retries) {
+        printf("DNS resolution attempt %d/%d for %s\n", retry_count + 1, max_retries, hostname);
+        
+        // 创建信号量
+        ip_sem.dns_done_sem = osSemaphoreNew(1, 0, NULL);
+        if (ip_sem.dns_done_sem == NULL) {
+            printf("Failed to create semaphore for DNS resolution\n");
+            return -1;
+        }
+        
+        // 初始化IP地址为0
+        memset(&ip_sem.ip, 0, sizeof(ip_addr_t));
+        
+        // 解析域名
+        dns_gethostbyname(hostname, &(ip_sem.ip), dns_found, &ip_sem);
+        
+        // 等待DNS解析完成
+        if (osSemaphoreAcquire(ip_sem.dns_done_sem, 30000) == osOK) {
+            if (ip_sem.ip.u_addr.ip4.addr != 0) {
+                *ip_addr = ip_sem.ip.u_addr.ip4.addr;
+                printf("DNS resolution successful for %s: 0x%08X (attempt %d)\n", hostname, *ip_addr, retry_count + 1);
+                ret = 0;
+                break; // 成功,跳出循环
+            } else {
+                printf("DNS resolution failed for %s: IP address is 0 (attempt %d)\n", hostname, retry_count + 1);
+            }
+        } else {
+            printf("DNS resolution timeout for %s (attempt %d)\n", hostname, retry_count + 1);
+        }
+        
+        // 释放信号量
+        osSemaphoreDelete(ip_sem.dns_done_sem);
+        
+        // 如果不是最后一次尝试,等待1秒后重试
+        if (retry_count < max_retries - 1) {
+            printf("Waiting 1 second before retry...\n");
+            LOS_Msleep(1000);
+        }
+        
+        retry_count++;
+    }
+    
+    if (ret != 0) {
+        printf("DNS resolution failed after %d attempts for %s\n", max_retries, hostname);
+    }
+    
+    return ret;
+}
+
+// URL解析函数
+static BK_URL parse_url(const char *url) {
+    BK_URL result = {NULL, NULL, 0, NULL, NULL, NULL};
+    
+    if (!url) {
+        result.error = "URL is NULL";
+        return result;
+    }
+    
+    char *temp_url = strdup(url);
+    if (!temp_url) {
+        result.error = "Failed to allocate memory";
+        return result;
+    }
+    
+    char *temp_ptr = temp_url;
+    
+    // 解析协议
+    char *colon = strchr(temp_ptr, ':');
+    if (!colon) {
+        result.error = "Invalid URL: No protocol specified";
+        free(temp_url);
+        return result;
+    }
+    *colon = '\0';
+    result.protocol = strdup(temp_ptr);
+    temp_ptr = colon + 3;  // 跳过 "://"
+    
+    // 解析主机和端口
+    char *slash = strchr(temp_ptr, '/');
+    if (!slash) {
+        result.error = "Invalid URL: No path specified";
+        free(temp_url);
+        return result;
+    }
+    *slash = '\0';
+    
+    char *colon_port = strchr(temp_ptr, ':');
+    if (colon_port) {
+        *colon_port = '\0';
+        result.host = strdup(temp_ptr);
+        result.port = atoi(colon_port + 1);
+        if (!result.port) {
+            result.error = "Invalid port number";
+            free(temp_url);
+            return result;
+        }
+    } else {
+        result.host = strdup(temp_ptr);
+        if (!strcmp(result.protocol, "http")) {
+            result.port = 80;
+        } else if (!strcmp(result.protocol, "https")) {
+            result.port = 443;
+        }
+    }
+    
+    temp_ptr = slash + 1;
+    
+    // 解析路径和查询字符串
+    char *question = strchr(temp_ptr, '?');
+    if (question) {
+        *question = '\0';
+        result.path = strdup(temp_ptr);
+        result.query = strdup(question + 1);
+    } else {
+        result.path = strdup(temp_ptr);
+        result.query = NULL;
+    }
+    
+    free(temp_url);
+    return result;
+}
+
+// 释放URL结构体
+static void free_url(BK_URL *url) {
+    if (url) {
+        free(url->protocol);
+        free(url->host);
+        free(url->path);
+        free(url->query);
+        free(url->error);
+        memset(url, 0, sizeof(BK_URL));
+    }
+}
+
+
+static void dns_found(const char* hostname, const ip_addr_t *ipaddr, void *arg) 
+{
+    struct gnss_ipaddr_t *ip_sem = (struct gnss_ipaddr_t *)arg;
+    char ip_str[20] = {0};
+    
+    printf("hostname: %s, ", hostname);
+    
+    // 详细检查IP地址
+    if (ipaddr == NULL) {
+        printf("DNS解析失败,IP地址为NULL\n");
+        memset(&(ip_sem->ip), 0, sizeof(ip_addr_t));
+        (void)osSemaphoreRelease(ip_sem->dns_done_sem);
+        return;
+    }
+    
+    // 检查IP地址类型
+    if (ipaddr->type != IPADDR_TYPE_V4) {
+        printf("DNS解析失败,不是IPv4地址,类型: %d\n", ipaddr->type);
+        memset(&(ip_sem->ip), 0, sizeof(ip_addr_t));
+        (void)osSemaphoreRelease(ip_sem->dns_done_sem);
+        return;
+    }
+    
+    uint32_t ip_num = ipaddr->u_addr.ip4.addr;
+    printf("Raw IP address: 0x%08X\n", ip_num);
+    
+    if (ip_num == 0) {
+        printf("DNS解析失败,IP地址为0\n");
+        memset(&(ip_sem->ip), 0, sizeof(ip_addr_t));
+        (void)osSemaphoreRelease(ip_sem->dns_done_sem);
+        return;
+    }
+    
+    // 处理IPv4地址
+    // 分解为4字节打印
+    u8_t byte0 = (ip_num >> 24) & 0xFF;
+    u8_t byte1 = (ip_num >> 16) & 0xFF;
+    u8_t byte2 = (ip_num >> 8) & 0xFF;
+    u8_t byte3 = ip_num & 0xFF;
+    printf("IPv4: %d.%d.%d.%d\n", byte0, byte1, byte2, byte3);
+    
+    // 转换为struct in_addr(已为网络字节序)
+    struct in_addr ipv4_addr;
+    ipv4_addr.s_addr = ip_num;
+    inet_ntop(AF_INET, &ipv4_addr, ip_str, sizeof(ip_str));
+    printf("ip: %s\n", ip_str);
+
+    // 复制IP地址到上下文
+    memcpy(&(ip_sem->ip), ipaddr, sizeof(ip_addr_t));
+    printf("DNS解析成功,IP地址已保存\n");
+    (void)osSemaphoreRelease(ip_sem->dns_done_sem);
+}
+
+// 下载AGNSS星历文件
+int download_agnss_file(const char *filename)
+{
+    printf("Downloading file: %s\n", filename);
+    
+    // 获取当前时间戳
+    uint32_t timestamp = 0;
+    uapi_get_timestampe_ss(&timestamp);
+    
+    // 构建文件路径
+    char filepath[512];
+    snprintf(filepath, sizeof(filepath), "%s/%s", PGNSS_DATA_PATH, filename);
+    
+    // 初始化HTTP客户端连接设置
+    httpc_connection_t settings = {0};
+    httpc_state_t* connection = NULL;
+    
+    // 设置回调函数
+    settings.result_fn = agnss_download_result_callback;
+    settings.headers_done_fn = agnss_download_headers_done_callback;
+    settings.use_proxy = 0;
+    settings.use_post = 0;  // 使用GET请求
+    
+    // 构建URI
+    char uri[512];
+    snprintf(uri, sizeof(uri), "/dev/AGNSS/geteph?deviceId=121314243&timestamp=%u", timestamp);
+    
+    printf("Download URI: %s\n", uri);
+    printf("Local file: %s\n", filepath);
+    
+    // 发送HTTP GET请求并直接下载到文件
+    err_t result = httpc_get_file_dns_to_disk(
+        "iot-pub.tos-cn-guangzhou.volces.com",  // 服务器名称(使用正确的文件下载服务器)
+        80,                     // 端口
+        uri,                    // URI
+        &settings,              // 连接设置
+        (void*)filename,        // 回调参数(传递文件名)
+        filepath,               // 本地文件路径
+        &connection             // 连接状态
+    );
+    
+    if (result != ERR_OK) {
+        printf("HTTP GET request failed: %d\n", result);
+        return -1;
+    }
+    
+    printf("HTTP GET request sent successfully\n");
+    return 0;
+}
+
+int download_agnss_files(void)
+{
+    printf("=== Starting AGNSS Files Download ===\n");
+
+    
+    // 获取当前时间戳
+    uint32_t timestamp = 0;
+    uapi_get_timestampe_ss(&timestamp);
+    
+    // 构建完整URL
+    char full_url[512];
+    snprintf(full_url, sizeof(full_url), 
+        "http://app.api.thisiot.com/dev/AGNSS/geteph?deviceId=121314243&timestamp=%u", 
+        timestamp);
+    
+    printf("AGNSS URL: %s\n", full_url);
+    
+    // 初始化HTTP客户端连接设置
+    httpc_connection_t settings = {0};
+    httpc_state_t* connection = NULL;
+    
+    // 设置回调函数
+    settings.result_fn = agnss_download_result_callback;
+    settings.headers_done_fn = agnss_download_headers_done_callback;
+    settings.use_proxy = 0;
+    settings.use_post = 0;  // 使用GET请求
+    
+    printf("HTTP client settings configured:\n");
+    printf("  result_fn: %p\n", settings.result_fn);
+    printf("  headers_done_fn: %p\n", settings.headers_done_fn);
+    printf("  use_proxy: %d\n", settings.use_proxy);
+    printf("  use_post: %d\n", settings.use_post);
+    
+    // 构建URI
+    char uri[512];
+    snprintf(uri, sizeof(uri), "/dev/AGNSS/geteph?deviceId=121314243&timestamp=%u", timestamp);
+    
+    printf("AGNSS URI: %s\n", uri);
+    printf("Server: app.api.thisiot.com, Port: 80\n");
+    
+    // 清理之前的缓冲区
+    cleanup_agnss_response_buffer();
+    
+    // 重置时间戳(用于调试)
+    printf("=== Starting new AGNSS download session ===\n");
+    printf("Download request sent at: %u ms\n", LOS_TickCountGet() * 10);
+    
+    // 发送HTTP GET请求
+    err_t result = httpc_get_file_dns(
+        "app.api.thisiot.com",  // 服务器名称(API服务器,用于获取文件列表)
+        80,                     // 端口
+        uri,                    // URI
+        &settings,              // 连接设置
+        agnss_download_recv_callback,  // 接收回调
+        NULL,                   // 回调参数
+        &connection             // 连接状态
+    );
+    
+    printf("httpc_get_file_dns result: %d (0=OK, other=error)\n", result);
+    
+    if (result != ERR_OK) {
+        printf("HTTP GET request failed: %d\n", result);
+        printf("Error codes: ERR_OK=0, ERR_MEM=-1, ERR_TIMEOUT=-2, ERR_RTE=-3\n");
+        return -1;
+    }
+    
+    printf("HTTP GET request sent successfully\n");
+    printf("Connection pointer: %p\n", connection);
+    
+    printf("=== AGNSS Files Download Request Complete ===\n");
+    printf("Data will be processed asynchronously by gnss_http_server_recv_task\n");
+    printf("No blocking wait - download will start immediately\n");
+    return 0;
+}
+
+
+void do_gnss_http_server_send_data(int cmd,char *data,uint32_t len)
+{
+    errcode_t ret;
+    gnss_http_data_mail_t send_data = {0};
+    send_data.cmd = cmd;
+    if(len && data)
+    {
+        send_data.len = len;
+        send_data.data = (char *)malloc(len);
+        if(send_data.data == NULL)
+        {
+            PRINT("malloc failed\n");
+            return;
+        }
+        memcpy_s(send_data.data,len,data,len);
+    }
+
+    uint32_t send_len = sizeof(send_data);
+
+    ret = osal_msg_queue_write_copy(g_app_send_queue, (void *)&send_data,
+                                    send_len, 0);
+    if (ret != OSAL_SUCCESS) {
+        PRINT("Error gnss Check MSG 0x send failed! err=0x%x! \r\n", ret);
+    }
+}
+
+void do_gnss_http_server_recv_data(int cmd,char *data,uint32_t len)
+{
+    errcode_t ret;
+    gnss_http_data_mail_t send_data = {0};
+    send_data.cmd = cmd;
+    if(len && data)
+    {
+        send_data.len = len;
+        send_data.data = (char *)malloc(len);
+        if(send_data.data == NULL)
+        {
+            PRINT("malloc failed\n");
+            return;
+        }
+        memcpy_s(send_data.data,len,data,len);
+    }
+
+    uint32_t send_len = sizeof(send_data);
+
+    ret = osal_msg_queue_write_copy(g_app_recv_queue, (void *)&send_data,
+                                    send_len, 0);
+    if (ret != OSAL_SUCCESS) {
+        PRINT("Error gnss Check MSG 0x send failed! err=0x%x! \r\n", ret);
+    }
+}
+
+// 清理AGNSS响应缓冲区
+static void cleanup_agnss_response_buffer(void)
+{
+    if (g_agnss_response_buffer) {
+        free(g_agnss_response_buffer);
+        g_agnss_response_buffer = NULL;
+        g_agnss_response_size = 0;
+        g_agnss_response_capacity = 0;
+    }
+}
+
+static void gnss_http_server_send_task(void const *arg)
+{
+    unused(arg);
+    errcode_t ret;
+
+    gnss_http_data_mail_t mail = {0};
+    uint32_t msgsize = sizeof(gnss_http_data_mail_t);
+
+    while (1) {
+        ret = osal_msg_queue_read_copy(g_app_send_queue, (void *)&mail, &msgsize,
+                                       OSAL_MSGQ_WAIT_FOREVER);
+        if (ret != OSAL_SUCCESS) {
+            continue;
+        }
+
+        if(mail.cmd == GNSS_HTTP_SERVICE_CMD_DATA_UPLOAD)
+        {
+            // http_data_handler((int *)mail.data,mail.len);
+            // http_recv_data_handler(mail.data,mail.len);
+            if(mail.data != NULL)
+            {
+                printf("free(mail.data)\n");
+                free(mail.data);
+            }
+        }
+        else if(mail.cmd == GNSS_HTTP_SERVICE_CMD_SERVER_INIT)
+        {
+            // gnss_http_init();
+            uapi_delete_files(PGNSS_DATA_PATH);
+            uapi_create_folder(PGNSS_DATA_PATH);
+    
+            // gnss_http_sign_up();
+            // if(LK_STATUS == 1)
+            // {
+            //     gnss_agnss_get_ephemeris();
+            // }
+            // else
+            // {
+            //     printf("NOT LK\n");
+            // }
+
+        }
+        else if(mail.cmd == GNSS_HTTP_SERVICE_CMD_SERVER_DEINIT)
+        {
+            // gnss_http_deinit();
+        }
+        else if(mail.cmd == GNSS_HTTP_SERVICE_CMD_DOWNLOAD_AGNSS)
+        {
+            uapi_delete_files(PGNSS_DATA_PATH);
+            uapi_create_folder(PGNSS_DATA_PATH);
+
+            printf("Starting AGNSS files download via queue...\n");
+            download_agnss_files();
+            printf("AGNSS files download completed via queue.\n");
+        }
+    }
+}
+
+
+static void gnss_http_server_recv_task(void const *arg)
+{
+    unused(arg);
+    errcode_t ret;
+
+    gnss_http_data_mail_t mail = {0};
+    uint32_t msgsize = sizeof(gnss_http_data_mail_t);
+    
+    // 添加任务保护计数器
+    int task_loop_count = 0;
+    const int max_loop_count = 10000; // 防止无限循环
+
+    while (1) {
+        task_loop_count++;
+        if (task_loop_count > max_loop_count) {
+            printf("Warning: Task loop count exceeded %d, resetting counter\n", max_loop_count);
+            task_loop_count = 0;
+            // 清理可能的内存泄漏
+            cleanup_agnss_response_buffer();
+        }
+        
+        ret = osal_msg_queue_read_copy(g_app_recv_queue, (void *)&mail, &msgsize,
+                                       OSAL_MSGQ_WAIT_FOREVER);
+        if (ret != OSAL_SUCCESS) {
+            continue;
+        }
+        
+        if(mail.cmd == GNSS_HTTP_SERVICE_CMD_AGNSS_RECV)
+        {
+            if (mail.data == NULL) {
+                // 数据接收完成,处理完整的响应
+                printf("AGNSS data reception completed, processing response...\n");
+                agnss_process_complete_response();
+                task_loop_count = 0; // 重置计数器
+            } else {
+                // 接收数据片段
+                printf("AGNSS data received via queue: %d bytes\n", mail.len);
+                agnss_accumulate_data(mail.data, mail.len);
+                free(mail.data); // 释放数据内存
+            }
+        }
+    }
+}
+
+static void create_gnss_http_send_queue(void)
+{
+
+    if (osal_msg_queue_create("gnss_http_service_send_queue", 24, &g_app_send_queue,
+                              0, sizeof(gnss_http_data_mail_t)) != ERRCODE_SUCC) {
+        PRINT("[gnss][service] app create mail fail\n");
+    }
+}
+
+static void create_gnss_http_recv_queue(void)
+{
+
+    if (osal_msg_queue_create("gnss_http_service_recv_queue", 24, &g_app_recv_queue,
+                              0, sizeof(gnss_http_data_mail_t)) != ERRCODE_SUCC) {
+        PRINT("[gnss][service] app create mail fail\n");
+    }
+}
+
+#define GNSS_HTTP_BOARD_TASK_SIZE   0x2000
+errcode_t uapi_gnss_http_server_init(void)
+{
+    PRINT("uapi_gnss_http_server_init !\r\n");
+
+    send_taskcfg.create_queue_handle = create_gnss_http_send_queue;
+    send_taskcfg.attr.name="gnss_http_server_send_task";
+    send_taskcfg.attr.priority = osPriorityNormal;
+    send_taskcfg.attr.stack_size = GNSS_HTTP_BOARD_TASK_SIZE;
+    send_taskcfg.func = gnss_http_server_send_task;
+    send_taskcfg.use_mem = USE_EXTEND_MEM;
+    
+    errcode_t ret=uapi_create_osThread_custom(&send_taskcfg);
+    if(ret != ERRCODE_SUCC)
+    {
+        PRINT("create gnss_send_service failed %d!\r\n",ret);
+        return ERRCODE_FAIL;
+    }
+
+    recv_taskcfg.create_queue_handle = create_gnss_http_recv_queue;
+    recv_taskcfg.attr.name="gnss_http_server_recv_task";
+    recv_taskcfg.attr.priority = osPriorityNormal1;
+    recv_taskcfg.attr.stack_size = GNSS_HTTP_BOARD_TASK_SIZE;
+    recv_taskcfg.func = gnss_http_server_recv_task;
+    recv_taskcfg.use_mem = USE_EXTEND_MEM;
+    
+    ret=uapi_create_osThread_custom(&recv_taskcfg);
+    if(ret != ERRCODE_SUCC)
+    {
+        PRINT("create gnss_recv_service failed %d!\r\n",ret);
+        return ERRCODE_FAIL;
+    }
+
+    return ERRCODE_SUCC;
+}
+
index 506b3b2..2dd7383 100644 (file)
@@ -30,6 +30,7 @@
 #include "uart_gnss.h"
 #include "gnss_ctl.h"
 #include "tiot_board_pin_port.h"
+// #include "pgnss_sample.h"
 #include "pgnss_sample.h"
 // errcode_t gnss_get_next_cmd(uint8_t cmd_index,uint8_t** cmdbuf,int *cmdlen);
 // errcode_t gnss_get_current_cmd(uint8_t cmd_index,uint8_t** cmdbuf,int *cmdlen);
@@ -112,11 +113,11 @@ void do_gnss_cmd(int cmd,uint8_t *buffer,uint32_t size)
 
 uint32_t gnss_write_cmd(uint8_t * cmdbuf,uint16_t cmdlen)
 {
-    return uapi_uart_write(TIOT_UART_PORT, cmdbuf, cmdlen,0);
+    return uapi_uart_write(TIOT_UART_PORT, cmdbuf, cmdlen,0xFFFFFFF3);
 }
 uint32_t gnss_data_read(uint8_t * cmdbuf,uint16_t cmdlen)
 {
-    return uapi_uart_read(TIOT_UART_PORT, cmdbuf, cmdlen,0);
+    return uapi_uart_read(TIOT_UART_PORT, cmdbuf, cmdlen,0xFFFFFFF3);
 }
 static void uart_event_task(void const *arg)
 {
index 1cea5b7..5846c7f 100644 (file)
@@ -8,9 +8,76 @@ if("PPG_GH3X2X" IN_LIST DEFINES)
 
 set(PUBLIC_HEADER
     ${CMAKE_CURRENT_SOURCE_DIR}/inc
+    # ${CMAKE_CURRENT_SOURCE_DIR}/demo_algo_code/goodix_algo_application/inc
+    # ${CMAKE_CURRENT_SOURCE_DIR}/demo_algo_code/goodix_algo_call/inc
+    # ${CMAKE_CURRENT_SOURCE_DIR}/demo_kernel_code/driver/inc
+    # ${CMAKE_CURRENT_SOURCE_DIR}/demo_kernel_code/kernel
+    # ${CMAKE_CURRENT_SOURCE_DIR}/demo_kernel_code/module/gh_agc
+    # ${CMAKE_CURRENT_SOURCE_DIR}/demo_kernel_code/module/gh_ecg
+    # ${CMAKE_CURRENT_SOURCE_DIR}/demo_kernel_code/module/gh_other
+    # ${CMAKE_CURRENT_SOURCE_DIR}/demo_kernel_code/module/gh_protocol
+    # ${CMAKE_CURRENT_SOURCE_DIR}/demo_kernel_code/module/gh_soft_adt
+    # ${CMAKE_CURRENT_SOURCE_DIR}/demo_mp_code/inc
+    # ${CMAKE_CURRENT_SOURCE_DIR}/algo_params/HR/04_EXCLUSIVE/
+    
 )
 
 set(SOURCES ${SOURCES}
+    # ${CMAKE_CURRENT_SOURCE_DIR}/demo_algo_code/goodix_algo_application/src/gh3x2x_demo_accppg_sync.c
+    # ${CMAKE_CURRENT_SOURCE_DIR}/demo_algo_code/goodix_algo_application/src/gh3x2x_demo_algo_call.c
+    # ${CMAKE_CURRENT_SOURCE_DIR}/demo_algo_code/goodix_algo_application/src/gh3x2x_demo_algo_config.c
+    # ${CMAKE_CURRENT_SOURCE_DIR}/demo_algo_code/goodix_algo_application/src/gh3x2x_demo_algo_frame.c
+    # ${CMAKE_CURRENT_SOURCE_DIR}/demo_algo_code/goodix_algo_application/src/gh3x2x_demo_algo_hook.c
+    # ${CMAKE_CURRENT_SOURCE_DIR}/demo_algo_code/goodix_algo_application/src/gh3x2x_demo_algo_memory.c
+    # ${CMAKE_CURRENT_SOURCE_DIR}/demo_algo_code/goodix_algo_application/src/gh3x2x_demo_algo_reg_array.c
+    # ${CMAKE_CURRENT_SOURCE_DIR}/demo_algo_code/goodix_algo_application/src/gh3x2x_demo_strategy.c
+    # ${CMAKE_CURRENT_SOURCE_DIR}/demo_algo_code/goodix_algo_call/src/gh3x2x_demo_algo_call_adt.c
+    # ${CMAKE_CURRENT_SOURCE_DIR}/demo_algo_code/goodix_algo_call/src/gh3x2x_demo_algo_call_af.c
+    # ${CMAKE_CURRENT_SOURCE_DIR}/demo_algo_code/goodix_algo_call/src/gh3x2x_demo_algo_call_bt.c
+    # ${CMAKE_CURRENT_SOURCE_DIR}/demo_algo_code/goodix_algo_call/src/gh3x2x_demo_algo_call_ecg.c
+    # ${CMAKE_CURRENT_SOURCE_DIR}/demo_algo_code/goodix_algo_call/src/gh3x2x_demo_algo_call_hr.c
+    # ${CMAKE_CURRENT_SOURCE_DIR}/demo_algo_code/goodix_algo_call/src/gh3x2x_demo_algo_call_hrv.c
+    # ${CMAKE_CURRENT_SOURCE_DIR}/demo_algo_code/goodix_algo_call/src/gh3x2x_demo_algo_call_hsm.c
+    # ${CMAKE_CURRENT_SOURCE_DIR}/demo_algo_code/goodix_algo_call/src/gh3x2x_demo_algo_call_nadt.c
+    # ${CMAKE_CURRENT_SOURCE_DIR}/demo_algo_code/goodix_algo_call/src/gh3x2x_demo_algo_call_resp.c
+    # ${CMAKE_CURRENT_SOURCE_DIR}/demo_algo_code/goodix_algo_call/src/gh3x2x_demo_algo_call_spo2.c
+    # ${CMAKE_CURRENT_SOURCE_DIR}/demo_kernel_code/driver/src/gh_drv_config.c
+    # ${CMAKE_CURRENT_SOURCE_DIR}/demo_kernel_code/driver/src/gh_drv_control.c
+    # ${CMAKE_CURRENT_SOURCE_DIR}/demo_kernel_code/driver/src/gh_drv_dump.c
+    # ${CMAKE_CURRENT_SOURCE_DIR}/demo_kernel_code/driver/src/gh_drv_interface.c
+    # ${CMAKE_CURRENT_SOURCE_DIR}/demo_kernel_code/kernel/gh_demo_hook.c
+    # ${CMAKE_CURRENT_SOURCE_DIR}/demo_kernel_code/kernel/gh_demo_protocol.c
+    # ${CMAKE_CURRENT_SOURCE_DIR}/demo_kernel_code/kernel/gh_demo_user.c
+    # ${CMAKE_CURRENT_SOURCE_DIR}/demo_kernel_code/kernel/gh_demo.c
+    # ${CMAKE_CURRENT_SOURCE_DIR}/demo_kernel_code/kernel/gh_demo_reg_array.c
+    # ${CMAKE_CURRENT_SOURCE_DIR}/demo_kernel_code/module/gh_agc/gh_agc.c
+    # ${CMAKE_CURRENT_SOURCE_DIR}/demo_kernel_code/module/gh_ecg/gh_ecg.c
+    # ${CMAKE_CURRENT_SOURCE_DIR}/demo_kernel_code/module/gh_other/gh_changeinttime.c
+    # ${CMAKE_CURRENT_SOURCE_DIR}/demo_kernel_code/module/gh_other/gh_movedetect.c
+    # ${CMAKE_CURRENT_SOURCE_DIR}/demo_kernel_code/module/gh_protocol/gh_datatrans.c
+    # ${CMAKE_CURRENT_SOURCE_DIR}/demo_kernel_code/module/gh_protocol/gh_uprotocol.c
+    # ${CMAKE_CURRENT_SOURCE_DIR}/demo_kernel_code/module/gh_protocol/gh_zip.c
+    # ${CMAKE_CURRENT_SOURCE_DIR}/demo_kernel_code/module/gh_soft_adt/gh_multi_sen_pro.c
+    # ${CMAKE_CURRENT_SOURCE_DIR}/demo_mp_code/src/gh3x2x_demo_mp_process.c
+    # ${CMAKE_CURRENT_SOURCE_DIR}/demo_mp_code/src/gh3x2x_demo_mp.c
+    # ${CMAKE_CURRENT_SOURCE_DIR}/demo_mp_code/src/gh3x2x_mp_algorithm.c
+    # ${CMAKE_CURRENT_SOURCE_DIR}/demo_mp_code/src/gh3x2x_mp_param_config.c
+    # ${CMAKE_CURRENT_SOURCE_DIR}/demo_mp_code/src/gh3x2x_mp_reg_config.c
+    # ${CMAKE_CURRENT_SOURCE_DIR}/algo_params/goodix_ecg_config.c
+    # ${CMAKE_CURRENT_SOURCE_DIR}/algo_params/goodix_hba_config.c
+    # ${CMAKE_CURRENT_SOURCE_DIR}/algo_params/goodix_hrv_config.c
+    # ${CMAKE_CURRENT_SOURCE_DIR}/algo_params/goodix_nadt_config.c
+    # ${CMAKE_CURRENT_SOURCE_DIR}/algo_params/goodix_spo2_config.c
+    # ${CMAKE_CURRENT_SOURCE_DIR}/algo_params/HR/04_EXCLUSIVE/heart_net_org_dll.c
+    # ${CMAKE_CURRENT_SOURCE_DIR}/algo_params/HR/04_EXCLUSIVE/HRNet_knBasicWeights.c
+    # ${CMAKE_CURRENT_SOURCE_DIR}/algo_params/HR/04_EXCLUSIVE/HRNet_knConfNetWeights.c
+    # ${CMAKE_CURRENT_SOURCE_DIR}/algo_params/HR/04_EXCLUSIVE/HRNet_knMultiWeights.c
+    # ${CMAKE_CURRENT_SOURCE_DIR}/algo_params/HR/04_EXCLUSIVE/HRNet_knSceneNetWeights.c
+    # ${CMAKE_CURRENT_SOURCE_DIR}/algo_params/HR/04_EXCLUSIVE/HRNet_knSmallWeights.c
+    # ${CMAKE_CURRENT_SOURCE_DIR}/algo_params/HR/04_EXCLUSIVE/HRNet_knTdfusionWeights.c
+    # ${CMAKE_CURRENT_SOURCE_DIR}/algo_params/HR/04_EXCLUSIVE/HRNet_knWeights.c
+    # ${CMAKE_CURRENT_SOURCE_DIR}/algo_params/SPO2/02_PREMIUM_EXCLUSIVE/pv_v2.1.0.0_spo2wrnet_for_GH3228T_cd023f.c
+
     ${CMAKE_CURRENT_SOURCE_DIR}/src/gh3x2x_afe_adt.c
     ${CMAKE_CURRENT_SOURCE_DIR}/src/gh3x2x_afe_agc.c
     ${CMAKE_CURRENT_SOURCE_DIR}/src/gh3x2x_afe_demo.c
@@ -43,6 +110,7 @@ set(COMPONENT_PUBLIC_CCFLAGS
 )
 
 set(COMPONENT_CCFLAGS
+    -mabi=ilp32f
 )
 
 set(WHOLE_LINK
@@ -53,5 +121,30 @@ set(MAIN_COMPONENT
     false
 )
 
+if("PPG_GH3X2X" IN_LIST DEFINES)
+
+find_library(LIB_PATH_DRV_COMMON lib/drv_common.a ${CMAKE_CURRENT_SOURCE_DIR})
+find_library(LIB_PATH_HR lib/hr.a ${CMAKE_CURRENT_SOURCE_DIR})
+find_library(LIB_PATH_SPO2 lib/spo2.a ${CMAKE_CURRENT_SOURCE_DIR})
+find_library(LIB_PATH_ECG lib/ecg.a ${CMAKE_CURRENT_SOURCE_DIR})
+find_library(LIB_PATH_DL lib/dl.a ${CMAKE_CURRENT_SOURCE_DIR})
+find_library(LIB_PATH_DSP lib/dsp.a ${CMAKE_CURRENT_SOURCE_DIR})
+find_library(LIB_PATH_NDAT lib/nadt.a ${CMAKE_CURRENT_SOURCE_DIR})
+find_library(LIB_PATH_HRV lib/hrv.a ${CMAKE_CURRENT_SOURCE_DIR})
+
+
+target_link_libraries(${TARGET_NAME} PRIVATE -Wl,--whole-archive 
+${LIB_PATH_DRV_COMMON} 
+${LIB_PATH_HR} 
+${LIB_PATH_SPO2} 
+${LIB_PATH_ECG}
+${LIB_PATH_DL} 
+${LIB_PATH_DSP} 
+${LIB_PATH_NDAT}
+${LIB_PATH_HRV}
+PRIVATE -Wl,--whole-archive)
+
+endif()
+
 build_component()
 
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/algo_params/HR/04_EXCLUSIVE/HRNet_knBasicWeights.c b/code/sdk/drivers/peripheral/ppg/gh3x2x/algo_params/HR/04_EXCLUSIVE/HRNet_knBasicWeights.c
new file mode 100644 (file)
index 0000000..e2e12eb
--- /dev/null
@@ -0,0 +1,150 @@
+#ifndef Goodix_DSP_EXPORTS\r
+#include "goodix_type.h"\r
+#define NET_VERSION " "\r
+#define NET_SIZE 1033\r
+const uint32_t knBasicWeightsArr[] = {\r
+       0, 1065353216, 724074269, 3885820506, 116917501, 8325352, 4009493501, 3926125851,\r
+       2161842448, 3296732125, 499697052, 3523277298, 461327217, 3960081188, 505348323, 2149717546,\r
+       2845024915, 3171188527, 151061238, 2134244610, 4074417519, 437450231, 267058303, 50458103,\r
+       2813066753, 3038114581, 4112774272, 2137178607, 3643742947, 4011595198, 2154615556, 953478318,\r
+       604049279, 3925351442, 295229678, 1118162559, 1057853400, 718931178, 3792759679, 3789759757,\r
+       650761956, 436161663, 3210615378, 1063018013, 1056639630, 1065353216, 1058578260, 1055904030,\r
+       1059577124, 1063070521, 1063921745, 1053253201, 1062869368, 1063270524, 1056107973, 1054486009,\r
+       1056482121, 1051663868, 1057700387, 1064292754, 4267020469, 30800337, 4243356951, 255311887,\r
+       4148940150, 268435456, 15797825, 4196239507, 10382080, 4206944257, 33168317, 4267549491,\r
+       4194558368, 4251032117, 4136333637, 63549088, 3218110748, 1070627100, 3224244733, 1070740148,\r
+       45552144, 821823230, 4147767820, 3774578669, 3212990201, 1065439819, 1065353216, 268435456,\r
+       3198541715, 1051058067, 0, 1066136862, 2155904896, 2155839615, 2155839359, 2155904896,\r
+       3215048011, 1067481552, 1021622277, 1032504991, 1065353216, 1038368988, 1043184335, 1009913960,\r
+       1057625652, 1015169454, 1028722280, 1045823207, 1062057380, 1041544221, 1042872117, 1026739558,\r
+       1030026884, 1032034585, 4252355240, 31073929, 4189056835, 268435456, 4144192690, 267535180,\r
+       28518707, 4052206990, 12099610, 64170252, 26676094, 4270547324, 4204280637, 4243282847,\r
+       4100214973, 57002036, 3216988996, 1069505348, 3213732839, 1062662953, 0, 1072416415,\r
+       433563725, 3239773163, 2131181908, 4265723304, 488029220, 1057086517, 1376813294, 37438783,\r
+       3212920416, 1065370579, 1061247935, 1065353216, 76575876, 268435456, 3213940763, 1066457115,\r
+       0, 1067168424, 3749740696, 2155083391, 3900669712, 2144960543, 2149833599, 2146271239,\r
+       2157365888, 2146116736, 3216828142, 1069247776, 1061268306, 1054805463, 1062362518, 1048504269,\r
+       1057162170, 1035314156, 1051676869, 1045976474, 1063211847, 1051508606, 1054179445, 1032881169,\r
+       1062210613, 1065353216, 1057175496, 1034667418, 146732556, 20972983, 4255953782, 89001604,\r
+       4287636647, 102922619, 4292032938, 4271503333, 53667483, 181214832, 4294190206, 228610537,\r
+       96137260, 4026531840, 43658581, 4250910859, 3231392109, 1083908461, 3223891720, 1061594917,\r
+       0, 1075135832, 1087603170, 3740693035, 1116173620, 3702372224, 3209232996, 1061646431,\r
+       1065353216, 268435456, 3228063537, 1080579889, 0, 1075011896, 2139062400, 2139127936,\r
+       3225871845, 1078286361, 1065353216, 1028055723, 1043693058, 1040568123, 1035765628, 999522116,\r
+       1031180663, 1040038796, 90966773, 4203970396, 174305310, 268435456, 109511612, 4278446045,\r
+       75256247, 4179291306, 3221254755, 1073771107, 3234841126, 1067097188, 521500212, 923125524,\r
+       136041989, 511646500, 450574421, 3477102367, 24829152, 2811694719, 131393537, 418256385,\r
+       98701815, 2163996400, 248887220, 3632326391, 931798525, 140300498, 343926214, 38207450,\r
+       4233817947, 98817506, 198458898, 2132213620, 351985133, 4148616698, 319362349, 4160554234,\r
+       4162653429, 32247679, 827630504, 19724546, 4042982463, 32116608, 3223693199, 1076124736,\r
+       1053783709, 1047579787, 1062425973, 1050458755, 1059246939, 1048828207, 1065353216, 1055145552,\r
+       87463259, 4203942127, 174412105, 268435456, 109311232, 4280280516, 75283057, 4179587927,\r
+       3221254755, 1073771107, 3228787584, 1083001352, 0, 1082681049, 4289636220, 3089,\r
+       3494182951, 4294297594, 72988, 4286829702, 218107406, 1594677, 3975474687, 3087016388,\r
+       829399039, 4059889639, 3086996961, 4294306798, 4293915577, 4293061563, 4280787864, 10259297,\r
+       11446705, 7839654, 4283199390, 7707534, 3346427648, 4278733445, 3453542400, 3553046190,\r
+       227213452, 151280085, 2412862464, 1298876092, 2525785856, 1484549267, 3026502655, 3284253470,\r
+       5247860, 353346197, 42926223, 81104, 3194144767, 3401890583, 4105499136, 3958468924,\r
+       2274265723, 4287600331, 2173795144, 2019897344, 1932359884, 2171993969, 1904240253, 1701887231,\r
+       3939888944, 4109269760, 1577085385, 1834691385, 1157648608, 1481408275, 1459642582, 1680375616,\r
+       2254608029, 4285168532, 2763194267, 3839463513, 2691677031, 2695142144, 2779232900, 3249315584,\r
+       2204142079, 2526145584, 2959205372, 3416503040, 3573585812, 1582731987, 1050713158, 3226087645,\r
+       1073870099, 3212787730, 3195926809, 3216082652, 3226633333, 3215137574, 1079490460, 1065237717,\r
+       1033423704, 1051672171, 1006691043, 1077082412, 1051372746, 1052938626, 1039207426, 1058496494,\r
+       3203069010, 1052852587, 3199260745, 1041804355, 1051620981, 1060416570, 1039210092, 1061110839,\r
+       3203843233, 1053051779, 3197568205, 1041798471, 1051801222, 1060814499, 3222278102, 1074720694,\r
+       3222375327, 1074817160, 3243751324, 1096267676, 1019754651, 1063519344, 1046064357, 1012698070,\r
+       1045097311, 1019483124, 1065353216, 1058122366, 1061821161, 1021844088, 1018390782, 1048811270,\r
+       1038636641, 1062319611, 1052125277, 1049839807, 1009351890, 1021679867, 1006539629, 1025445043,\r
+       1009359331, 1019697659, 1029568837, 1014340242, 1048884352, 1047653154, 1065353216, 1058945453,\r
+       1054241782, 1054749875, 1051419295, 1060930322, 1059598055, 1052855882, 1057036698, 1050017803,\r
+       1050794751, 1058969392, 1044175313, 1047798903, 1051308378, 1052338510, 1053477983, 1052619626,\r
+       1052905720, 1051702097, 1048767499, 1044379887, 2302371407, 2240179846, 4283848803, 2074846882,\r
+       3635844206, 1888790317, 1955628158, 2529152860, 1302768511, 1232755581, 1734857817, 1968929648,\r
+       2189853336, 1600094103, 2357753474, 2002880677, 2642976623, 1247105878, 2260754278, 1684502892,\r
+       2054652244, 2391367022, 2256377222, 1785020301, 2734708570, 1802335860, 2359125029, 1684676986,\r
+       1360026111, 2563201343, 3531631554, 2325119653, 1111722667, 1048009824, 797014918, 2345028191,\r
+       3362481287, 574717070, 2556936219, 1432371054, 2156353169, 1403614615, 2339402847, 1970825621,\r
+       2678493621, 2727641126, 859936415, 1851017861, 2154730376, 2527034509, 2828375950, 1953644412,\r
+       2975624566, 2206429262, 2073470076, 2226202112, 1064256376, 2425511503, 3920646911, 2465244324,\r
+       916228198, 814777452, 341476752, 2516047224, 3264382863, 305667958, 1467070811, 1565869926,\r
+       2024172456, 1583378038, 1327850659, 2357220007, 4049163220, 2413788064, 2868867364, 2341498016,\r
+       1952158335, 2176677504, 2695596408, 2406964113, 2154855232, 2189385607, 697920411, 1462584454,\r
+       1412538294, 1249202049, 3308727691, 1605420119, 2044826256, 2255774140, 1634614927, 2362949804,\r
+       2492244139, 1728070013, 3784018621, 2674737283, 1016427958, 1081362290, 2203613808, 2693173058,\r
+       4283482003, 3450252167, 1601468566, 1248892532, 1868138890, 3033440088, 3649804436, 1330141300,\r
+       2239477833, 1767209349, 2021943434, 1716483188, 1673572944, 1822994112, 379530495, 3366801818,\r
+       1282774892, 2808668526, 158440073, 2406643963, 3129816764, 1222019195, 2375166632, 3134632250,\r
+       2474793844, 2305981090, 2326502500, 3862859740, 1720206189, 2269347245, 929535087, 2445707719,\r
+       2792467400, 2940971353, 1483629676, 2979170910, 1325374623, 2423878274, 2072279939, 2757334402,\r
+       3112937426, 1885633176, 815705720, 1669499780, 2428538311, 2960163509, 2761390480, 2074156510,\r
+       2476386184, 4002650262, 2626258014, 1660903575, 2188679554, 2155906155, 4291324759, 1398248667,\r
+       3400180140, 2152448895, 2021496435, 2070317915, 2092590739, 2472002224, 1772790682, 1890088344,\r
+       2326437305, 2423428254, 1633125495, 2761711469, 2658242481, 1519817899, 2639642922, 2507045240,\r
+       1333300323, 2676449257, 3361899395, 2173874829, 2304934253, 3072895126, 1938909647, 3059902719,\r
+       2391113856, 2156230785, 2694942289, 2458354355, 3337261939, 1781724068, 3949039009, 2624568447,\r
+       2277853353, 1909167255, 1940895390, 1282526555, 10714289, 2774637045, 2374333294, 2891670442,\r
+       1373538994, 3883109548, 947460457, 3202512048, 2175763296, 2710861501, 3993034136, 2743147982,\r
+       3500746138, 3119084445, 2308868669, 1506639364, 2040954502, 2557769087, 2053009280, 1972140258,\r
+       853694544, 2765512075, 1921744163, 2524614038, 4285042834, 1938137658, 981299846, 947094177,\r
+       2088324335, 2953158528, 2509335680, 2039251336, 2977064568, 1855892376, 1649125311, 1472021649,\r
+       1063813221, 1904369543, 1685217668, 1515678636, 2470744190, 4177548908, 2993367706, 2075725978,\r
+       2392419201, 1800963479, 2189851773, 2122484607, 1702458997, 2120776402, 2231338113, 2324599180,\r
+       2458420078, 2323090298, 2224192910, 2189984905, 2560721549, 2089388167, 1919644800, 1884513478,\r
+       1534550111, 1734584146, 2720108135, 2322961289, 3417010844, 3268969115, 2108072847, 2795686766,\r
+       2164240502, 2342891661, 1904536465, 2474189141, 2070059145, 2577040478, 2089991610, 2292278411,\r
+       3683563399, 2679688357, 3647837311, 2796198320, 2007518831, 2009378000, 2528231051, 2443706220,\r
+       1583191447, 2611517164, 2825025578, 2158077341, 2423949415, 2994247322, 1840149350, 1890218125,\r
+       1970702196, 1987789468, 4281954433, 1970681441, 2926872708, 2391369856, 2272470904, 1987696477,\r
+       2022666361, 2071168396, 1837661275, 2273509193, 118064457, 2285347203, 158559379, 2492631720,\r
+       1783598186, 2840227549, 1799914909, 2493755747, 781274806, 1131314614, 1514308437, 2187958131,\r
+       3113775237, 1719220404, 3332606354, 1759940039, 4035082879, 1839908096, 2411875227, 2206900814,\r
+       1339302786, 2245544064, 3159737404, 1821083239, 2158517870, 1802009772, 1937946555, 1753899628,\r
+       3268095136, 2859440965, 2172484504, 2322572398, 9149555, 1904971239, 1620272011, 1000703876,\r
+       1619437257, 1903658635, 2089454216, 2040232051, 2885517823, 3448233875, 2192464188, 4093657160,\r
+       4290955144, 3703496396, 2877263726, 4281955444, 2426308501, 4294617302, 2460196997, 4198760314,\r
+       2960156521, 4290093758, 2728555105, 4287595116, 2227407998, 4286088069, 1355450493, 1269825437,\r
+       2485208362, 6907223, 1082217584, 2432665229, 2426767359, 3425855426, 2425651849, 1979680417,\r
+       1867601230, 2071094015, 2346882043, 3372246659, 2188413439, 2962261935, 2660564869, 2356995456,\r
+       1218457344, 303519752, 3548905342, 1576130695, 2388561089, 1775147007, 2659568540, 2109144983,\r
+       2289470867, 2030018212, 2157676709, 4285499507, 1045027225, 3195156399, 1037718901, 3160320931,\r
+       1017530882, 1044653376, 1049853487, 1039348670, 1027003274, 1015463069, 1050058673, 1030878119,\r
+       1042229973, 1041485290, 1041891780, 1036171360, 3181755189, 1024276694, 1045172998, 1038873963,\r
+       3175783599, 1012182795, 993447707, 1023382925, 3177036773, 1030424204, 1015367376, 1003961708,\r
+       1017669843, 1034244175, 3171267020, 1015856047, 3214638470, 1067075211, 3215801189, 1068228846,\r
+       3217822470, 1070338822, 1056776477, 1060485056, 1054651097, 1065353216, 1052470295, 1058186576,\r
+       1054163221, 1057801571, 1054622292, 1059229927, 1057568093, 1059816688, 1058757508, 1057082891,\r
+       1057017220, 1057693575, 1046038220, 1058440860, 1041658374, 1050623982, 1045999469, 1041564100,\r
+       1042166701, 1043372405, 1050693278, 1057282511, 1057714692, 1058392653, 1058292420, 1058371987,\r
+       1055819276, 1054472559, 1059487364, 1052380544, 1058333379, 1061166387, 1052129059, 1059485737,\r
+       1051626949, 1053523575, 1062524611, 1061837256, 1051141380, 1058308016, 1060606548, 1061606283,\r
+       1063173819, 1065353216, 1050814981, 1053662896, 1057971445, 1059644381, 1058171151, 1053894099,\r
+       1047368800, 1051703920, 1050999862, 1053630173, 1057851348, 1059678044, 1058248640, 1054333290,\r
+       1048663672, 1050673849, 1050808511, 1053667596, 1057988210, 1059650101, 1058169584, 1053884486,\r
+       1047314016, 1051732412, 1061274806, 1053420314, 1052957645, 1056965528, 1065430091, 1055066668,\r
+       1061157785, 1053396084, 1054162419, 1056244695, 1057685728, 1058014138, 1059934895, 1054778511,\r
+       1051102724, 1054568131, 1061262442, 1054602947, 1052917804, 1056846561, 1065403501, 1052605457,\r
+       1061381802, 1053341833, 1057036907, 1057000930, 1055775738, 1056977090, 1061117621, 1056900118,\r
+       1052932409, 1052905471, 1050927578, 1053569203, 1058382631, 1059597529, 1058116451, 1053698020,\r
+       1047876750, 1051715234, 1050902883, 1053554957, 1058400474, 1059600478, 1058102734, 1053675458,\r
+       1047823251, 1051741527, 1058355593, 1057075606, 1055480181, 1057125400, 1061329790, 1053604470,\r
+       1054332702, 1052876418, 1050775002, 1054451887, 1058090276, 1059593699, 1058105889, 1054179078,\r
+       1048684516, 1050329889, 1060299262, 1060922685, 1060301902, 1058004604, 1060146378, 1057043951,\r
+       1059285650, 1060397044, 1060423376, 1059248241, 1060620034, 1062245968, 1063034750, 1062241084,\r
+       1065406211, 1064111170, 1065408700, 1064448288, 1062284230, 1062284100, 1064973952, 1063096283,\r
+       1059800242,\r
+};\r
+\r
+uint32_t* get_knBasicWeightsArr_addr(void)\r
+{\r
+       return (uint32_t *)(knBasicWeightsArr);\r
+}\r
+uint32_t get_knBasicWeightsArr_size(void)\r
+{\r
+       return sizeof(knBasicWeightsArr) / sizeof(knBasicWeightsArr[0]);\r
+}\r
+void get_knBasicWeightsArr_version(char* ver, uint8_t len)\r
+{\r
+       memcpy(ver, NET_VERSION, len);\r
+}\r
+#endif //#ifndef Goodix_DSP_EXPORTS\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/algo_params/HR/04_EXCLUSIVE/HRNet_knConfNetWeights.c b/code/sdk/drivers/peripheral/ppg/gh3x2x/algo_params/HR/04_EXCLUSIVE/HRNet_knConfNetWeights.c
new file mode 100644 (file)
index 0000000..d604ec4
--- /dev/null
@@ -0,0 +1,393 @@
+#ifndef Goodix_DSP_EXPORTS\r
+#include "goodix_type.h"\r
+#define NET_VERSION "9b33ee"\r
+#define NET_SIZE 2979\r
+const uint32_t knConfNetWeightsArr[] = {\r
+0, 1065349120, 3900738106, 3318004714, 4274026504, 3140808700, 1174986441, 4010724484, \r
+502521472, 4008254750, 3994027268, 319424226, 4046213494, 3924411520, 3840422937, 4012248550, \r
+538570994, 1464026239, 3973627709, 788279823, 643124552, 2120569400, 2160462847, 3994697897, \r
+204536298, 4277653988, 3539339785, 35996543, 3722692310, 3570934288, 3591768022, 437445332, \r
+976701240, 4141645848, 3399531754, 3199010288, 3940279047, 1007597532, 243761231, 2795516186, \r
+3376950555, 487196884, 1784102425, 3470770559, 31710928, 118690058, 4075350260, 3128986812, \r
+1347692540, 1145648951, 1124146224, 674843984, 1949105577, 3611500671, 672572836, 347391710, \r
+2444810259, 1988053540, 4276479770, 84350726, 4075159303, 4159035869, 1448629337, 4111083328, \r
+4196631001, 4102079465, 3219646691, 3640583296, 3991997317, 118423527, 335935236, 318900744, \r
+4180225044, 4162403585, 810716889, 545310721, 3303077132, 1663826153, 3708879231, 353019315, \r
+416341741, 3689084683, 1242545373, 498710896, 2157720101, 3025939201, 520618437, 2138595629, \r
+256859, 183564286, 3908961797, 4227530764, 2138321086, 68941217, 234035703, 2920420368, \r
+4143057719, 759052590, 353176060, 3487352859, 310428621, 3239055373, 2138073688, 3048662602, \r
+3638350515, 47961806, 4243255029, 4130561407, 118231937, 152825601, 451739139, 3876323077, \r
+1483763327, 3855483107, 3388158720, 3271806908, 96710604, 838516864, 4211475313, 4278778370, \r
+4260824056, 4228186623, 3522834303, 4142983091, 3890156554, 3743158521, 302841059, 1095056983, \r
+1598357789, 3552608099, 782559, 607333911, 669560192, 134936926, 72203, 3927248125, \r
+201590783, 3522881422, 219090048, 50459904, 151784459, 4244440582, 725499007, 3974610592, \r
+3470603775, 3893687258, 1041231096, 855370717, 4229304703, 118139100, 734124276, 3403938835, \r
+1460589696, 238621302, 472104692, 450820338, 3454140179, 3791186048, 4261280944, 185276172, \r
+33881337, 521866753, 3208263691, 1060684699, 1050757938, 1057907911, 1054210471, 1045953334, \r
+1051660865, 1057385148, 1050433382, 1058009944, 1056998176, 1049564054, 1044556698, 1053216301, \r
+1056809115, 1058112067, 1054260430, 1051506851, 1050931343, 1055287118, 1043109379, 1057611734, \r
+1050020701, 1052932758, 1049998918, 1059456311, 1061132870, 1050714636, 1057438882, 1065353216, \r
+1050987234, 1056784568, 1049685503, 1064457174, 70498212, 58503888, 4267390377, 13612176, \r
+16693140, 4258212014, 4894117, 4284895581, 4130888878, 268435456, 4279142416, 142222043, \r
+4247864594, 68454020, 4254374046, 4273104253, 4293922130, 4287878881, 4212544288, 4183117306, \r
+4275815948, 66762, 4248662688, 10710117, 24992789, 79629768, 153056835, 40745785, \r
+4221338845, 40145577, 4270845373, 169307526, 3219817242, 1072333594, 3218232944, 1068837551, \r
+776139372, 688609805, 729810152, 2882730173, 3995277301, 3175947791, 3973653076, 4222401619, \r
+3205851242, 1058291097, 1065353216, 268435456, 3212551351, 1065067703, 0, 1078656145, \r
+2290816, 3204397754, 1056783429, 1065353216, 268435456, 3221243295, 1073759647, 0, \r
+1058194463, 2155839359, 2155839359, 2139062400, 2139062144, 2155839360, 2139062143, 2139062400, \r
+2139062399, 3204465839, 1056868427, 1055297541, 1056217720, 1051973082, 1060480751, 1049988760, \r
+1049018483, 1058854830, 1038297867, 1058295548, 1052791255, 1052952300, 1060591501, 1059870573, \r
+1058628283, 1039600008, 1056844973, 1057314991, 1036674212, 1063918753, 1065353216, 1042606230, \r
+1041567050, 1061044338, 1028048714, 1058188544, 1062291287, 1041147230, 1056774660, 1056811537, \r
+1048645073, 1056986276, 1055028972, 6475933, 47458995, 25612877, 481668, 15182755, \r
+9410212, 4294341666, 4267057721, 4168218233, 268435456, 4294270908, 226767434, 26495062, \r
+56878938, 2894489, 4273697869, 2180093, 49504589, 4267074380, 4277158842, 33954514, \r
+20235973, 4286412716, 15617654, 33726759, 129151171, 210469455, 28073590, 11379805, \r
+58591362, 4267492099, 143900420, 3220042848, 1072559200, 3193888458, 1051887117, 0, \r
+1071052189, 4061388249, 3883863765, 88870609, 600893151, 3324055522, 438375177, 3407869982, \r
+101773319, 4165840326, 3363791290, 124591294, 1674560992, 3040613567, 1431046174, 2837116768, \r
+3965196867, 3213786666, 1066230062, 1063313374, 1065353216, 136828864, 268435456, 3212980070, \r
+1065496422, 0, 1082475162, 3426189117, 32520, 3212928231, 1065378333, 1065353216, \r
+1062353328, 82625669, 268435456, 3213967502, 1066483854, 0, 1080013532, 343929983, \r
+2142852479, 2134212673, 2151167615, 2164162624, 394231865, 2145419071, 2134251648, 2143649833, \r
+746590335, 2151251764, 1518305117, 2143899776, 2021621551, 2132429951, 2140279679, 3213379879, \r
+1065826453, 1054429555, 989003575, 1059394170, 1057576237, 1062163485, 1063091647, 1057329293, \r
+1029617484, 1040476443, 1027706019, 1063376311, 1058661573, 1056004798, 1059118203, 1032739992, \r
+1064241988, 1039372092, 1051867859, 1056077566, 1044810446, 1061837093, 1065353216, 1054679368, \r
+1057072084, 1040830584, 1050546967, 1056970891, 1047609756, 1053731225, 1061627951, 1057781979, \r
+1043503381, 4231942549, 4293907570, 4177478783, 4079376787, 16788883, 85436745, 4205351918, \r
+4270089594, 1357106, 65824647, 67706497, 32373565, 148978953, 4107162503, 4204538840, \r
+38994357, 4227335330, 4215831368, 4196895578, 4165061633, 4282293500, 4281651673, 176547827, \r
+4144067114, 4270397415, 5006273, 4026531840, 4176161096, 4159892313, 4220900491, 4186976394, \r
+4280041714, 3224318065, 1076834417, 3223312940, 1081860972, 0, 1081614911, 1049401682, \r
+3180767598, 1046347740, 1046449901, 1050056884, 1044369992, 1031494127, 1050547688, 1059256432, \r
+1056173111, 1053328729, 1047801170, 1043167884, 1033085153, 3188066852, 1009165057, 3182311443, \r
+3195456552, 3194270196, 3199674790, 3165620441, 1051896713, 1040104955, 998882878, 1022079844, \r
+1036282194, 1048805498, 1048274341, 1032000323, 1039526883, 1053243796, 1057439029, 1047028827, \r
+1017109842, 3170947845, 3180766531, 1044486661, 1044608931, 1048531421, 1043978524, 3180151818, \r
+1038328082, 1054010239, 1052319736, 3180300294, 3175342309, 1022587478, 1030045461, 1041004419, \r
+1047347048, 1046961818, 1043697022, 1027773408, 1051087531, 1051423737, 3194480004, 3190975831, \r
+1036191969, 1041339721, 1043400279, 1038341866, 3154212849, 3183407527, 3168968670, 1051360794, \r
+1040265342, 3194672033, 3197446344, 3187709201, 3170475443, 1040317661, 1048069415, 1036996501, \r
+1022109061, 3176721201, 3172395616, 3194629242, 1029933063, 1049948421, 1054704390, 1030591362, \r
+3136228660, 3166744484, 3172851087, 1041059993, 1032665219, 3189852658, 1034733260, 1049343835, \r
+3180606574, 3191059537, 3195932152, 3191221908, 1047355766, 1046762964, 1046897462, 1042012181, \r
+1040291671, 3187416116, 3188913525, 1024784971, 1052923084, 1048576281, 3190668746, 3190843570, \r
+3182610100, 3156300320, 1042877049, 3155605734, 1046072140, 1052263972, 1035820222, 3197905352, \r
+3191632543, 3179536899, 966426146, 1025186865, 3187202288, 3192504083, 3186887235, 1042729491, \r
+1037188863, 3193356313, 3188827595, 1044518490, 1048612835, 1005848295, 3194233338, 3189538000, \r
+3177162437, 1025726785, 1046275579, 1040563572, 1026609160, 3176105971, 3177927080, 3191914067, \r
+1019390086, 1049810974, 1056220769, 998578562, 3173328684, 3172957751, 1029979366, 1044282431, \r
+1041654506, 1038608452, 1045212285, 1031973674, 1036764443, 1041803925, 1030675695, 1040759950, \r
+1028540507, 1042494474, 1042444922, 1056930890, 1033638351, 1053647033, 1054314368, 1056873462, \r
+1054744020, 1048583053, 1053511215, 1056485075, 3198154679, 1051397335, 1051541343, 1020882410, \r
+1046024035, 1040270407, 1044325163, 1037976853, 1035606604, 1036865586, 1051668944, 1021627787, \r
+1052204643, 1033631805, 1043433945, 3190670714, 1051502283, 1029651226, 1038925823, 1027641704, \r
+3166666858, 3195647945, 3171352906, 3189630682, 1065280588, 3190557085, 3193143545, 1057019815, \r
+1051454618, 1052297075, 1057008036, 1056999392, 1057745822, 1040362028, 1055583305, 1052939944, \r
+1055163838, 1049972978, 1049774229, 1031915837, 1056741191, 1035447102, 1044095241, 1045359002, \r
+1056941700, 1039824150, 1057762506, 1057154814, 3204522674, 1058953916, 1041971097, 1024305323, \r
+3173244433, 1023493727, 1040771461, 1018559378, 1042977279, 1052146179, 3191456539, 1053672060, \r
+1008402816, 1051466887, 1052089558, 1033639186, 1027269209, 1047184743, 1050702059, 1048160766, \r
+3200506821, 1059589977, 3197490630, 1041649061, 1053144441, 3188626221, 1056528646, 1048574449, \r
+3181253007, 1053456411, 1050502460, 1033247130, 3181793892, 1054507256, 1049677943, 3195014825, \r
+1053698341, 3197658954, 1056773176, 1031106663, 1036524434, 3160123140, 3191273728, 3204111160, \r
+3193992411, 1049045108, 3198991355, 3202926857, 1043847804, 3195683222, 1042856392, 1049357658, \r
+1064616453, 3189394993, 3191494130, 1033157658, 1053706814, 3203278730, 1058545547, 3166677983, \r
+3180861828, 1045663915, 3200942715, 3189315642, 1059080300, 3192171551, 1021838990, 1038433779, \r
+1047212980, 3176776980, 1057394215, 1050861964, 3196368465, 1056193588, 1036898471, 1054693191, \r
+3209351126, 1055267186, 1052998478, 1052738023, 1042122762, 1038805363, 3199774059, 1044807449, \r
+1021698461, 1028315966, 1044544232, 1049161456, 1032880064, 1042587614, 1056447965, 1049695948, \r
+1043933578, 1035582311, 1038026805, 1034141672, 1040727542, 1039242245, 1034598809, 3138183509, \r
+3178815446, 1059467306, 1040327290, 1062535717, 1065220618, 1059567394, 3191670262, 3161523287, \r
+1045999302, 1062101848, 1050077077, 1058211096, 1069489543, 3200332003, 1065559196, 3188956891, \r
+3188507415, 1054095368, 3209612490, 1061557483, 1065725771, 1060530636, 1059687447, 3199141678, \r
+1018147738, 1060119772, 1053620811, 1053101290, 1064531244, 1057573395, 1056433377, 1031667296, \r
+3180781211, 3180308707, 1053099539, 1031942824, 3136097152, 3201339698, 3201850186, 1045334003, \r
+1018408187, 3176648920, 1031898339, 1041204198, 1022332406, 1048519306, 1007523056, 1031384182, \r
+1046013050, 3170973036, 1015104674, 1051693669, 1047021818, 3170409343, 1041483556, 3183564528, \r
+3187147654, 1031731691, 3159602667, 3160115246, 1046111841, 1030615450, 1022674510, 1059629844, \r
+3138936300, 3196149264, 3184087254, 1023867829, 1034985409, 3161660794, 1004990474, 1015148115, \r
+1032074637, 1017244654, 1033132638, 3147721891, 1051216436, 1037508159, 1045130932, 1026404496, \r
+1062726990, 1026496116, 1048592883, 3191755361, 3190095131, 1034405989, 1063518105, 1040141586, \r
+3185043635, 1055231333, 1045649000, 1024106775, 1041943509, 1016717896, 1049558476, 1055350232, \r
+1021921403, 1059196322, 1028044330, 1040191314, 3203434155, 1024279889, 977116640, 1037040959, \r
+1048614240, 3160696543, 1047481796, 1053255589, 1038738140, 1049118871, 1023891817, 3191118665, \r
+1048643786, 3178358593, 1043905081, 1041415135, 1033119409, 1041090560, 1052555495, 1022909505, \r
+3192091480, 3187733995, 1058958805, 3166300494, 1057529808, 3179704722, 1040872020, 1050127812, \r
+3171614228, 1045710068, 3171436346, 1023394809, 3202321235, 3192340593, 3180920324, 1013996814, \r
+1035697955, 3179240701, 1034438925, 1050641862, 3170296627, 1052408824, 3180797885, 3169179021, \r
+3188992767, 3183956978, 3189487531, 1047587461, 3207708496, 1035521549, 3199450019, 3162613365, \r
+3181715702, 3199544968, 1035532574, 3187295385, 1050433272, 1015616257, 3190253440, 1052246510, \r
+3183228580, 3186419690, 3184727447, 3188126614, 3190298205, 1043017323, 3165083099, 3195408632, \r
+3196746936, 3181266304, 3191025997, 1024052234, 1018408453, 3176648900, 1031898340, 1041204198, \r
+2583660216, 1903260672, 1836020224, 4140874751, 2172682496, 4004446225, 1686962101, 2071756032, \r
+2223211519, 2240120063, 2407697151, 2779227903, 2240120063, 3166155519, 2205127423, 2811592704, \r
+2088532992, 1026949222, 2474872832, 2121692928, 2189523968, 1627419188, 4287930395, 2306770688, \r
+2039021724, 2386067746, 3320997067, 4286721088, 2438070208, 3657204112, 3904858623, 3196025925, \r
+2248112529, 4204608133, 744246038, 1689255859, 3620639487, 3976251812, 2778851839, 2273664961, \r
+738912784, 8825563, 168485898, 10081243, 3232432312, 2758955311, 1716154806, 1063284480, \r
+252299030, 11325379, 3047096499, 2551345986, 3653501134, 3351137837, 3839688909, 3065869125, \r
+3807518445, 4285085999, 2390556559, 1973326527, 2842662038, 2751490940, 3922420217, 4060100420, \r
+1681588319, 915917976, 2657026187, 1456639880, 2102526060, 1345893555, 4087611382, 2541983701, \r
+3211369850, 3172006389, 3196952434, 3204731778, 3168795509, 3198594548, 1041097533, 3166504887, \r
+958997221, 1025208006, 3198934274, 1024833684, 1027543364, 1034736932, 3197653830, 3187495703, \r
+3156576820, 1056995902, 3186797335, 3179861711, 1057953589, 1056667917, 1046431997, 3189768243, \r
+3148384662, 1056996131, 3187036496, 3179170712, 1057953564, 1055676040, 1046422776, 3190029742, \r
+3204540540, 1056990635, 3212950702, 1065400629, 3230603061, 1083119413, 1043351929, 1063400444, \r
+1061107123, 1040476210, 1061558887, 1040381021, 1037583314, 1061144857, 1000170595, 1065353216, \r
+1043304393, 1045015988, 1065352562, 1062316773, 1049978767, 1037102984, 1057673820, 1040288003, \r
+1036052237, 1057227623, 1031431317, 1020212491, 1035405413, 1047421560, 1060612456, 1014825652, \r
+1026199134, 1052038407, 1016057796, 1056420246, 1048356999, 966187847, 950492984, 1015621848, \r
+1061489916, 1024072861, 1018805552, 1052879371, 1049182710, 1040687777, 1000795402, 1065353216, \r
+1055789166, 1035033607, 1058521835, 1055982936, 1055331900, 1039110827, 1954623901, 3008454520, \r
+1115584661, 3198581643, 2894642787, 2788187304, 4199556645, 1833978182, 2197828042, 2136182664, \r
+810897024, 1266980716, 2860739766, 2307495526, 1550148260, 1648072572, 2053004908, 1534756741, \r
+2092075344, 1869304688, 3900056, 1905417505, 1885946252, 2205899661, 1884717960, 2373942902, \r
+2089709707, 2410378610, 2206568591, 2375459218, 2157153915, 2405920348, 1886217073, 2340719214, \r
+1950285936, 1751930992, 1921278073, 1485273461, 1903394931, 2071620227, 2021759350, 2206499229, \r
+2208010421, 2961278855, 1553700268, 1882296990, 2826857601, 2489947589, 1148244, 1348301637, \r
+2100464246, 1452813898, 1582920019, 2175438710, 2071170930, 1823843240, 2727903057, 3293404030, \r
+1750446314, 2054387843, 1228369574, 2273590346, 1095334039, 691955026, 2152278272, 2206495099, \r
+1817525370, 1600281481, 2056999029, 2272859210, 1416326032, 1386580067, 2138973017, 2660469388, \r
+2289659526, 1952933976, 2332067158, 2506841237, 2051434159, 1922253686, 2744297586, 2746724770, \r
+1937592441, 1887650115, 3531492467, 2071670938, 1315423743, 2594997661, 2727640209, 2760152441, \r
+1466197804, 1534926687, 2503547026, 1968969816, 978997369, 1684569730, 1100836922, 2495961305, \r
+1382967687, 2072007278, 1668962142, 1651078278, 1971749740, 2035832403, 7166834, 1618108963, \r
+1917731154, 1835675746, 1768379001, 2088006006, 1971157365, 2205780388, 1283161994, 2409398631, \r
+2288997959, 2808633433, 1986553994, 2139121511, 1899692177, 1716675720, 1785353089, 1267433859, \r
+1735550290, 1785619832, 1854509165, 2374658736, 1920038805, 2191093896, 1534301571, 2088860830, \r
+2020174686, 3028123982, 1601598052, 1482031180, 2200640554, 1364999488, 189289064, 272907130, \r
+2240316298, 2172081520, 1567849580, 1821406058, 1585339233, 862029949, 1313761122, 1584479283, \r
+772563776, 1617965568, 1718900827, 1984836172, 1364818027, 1835232621, 2072639858, 2371653513, \r
+4287976618, 2207926900, 2040050074, 1616412021, 2443351154, 2168216447, 507390291, 428239252, \r
+1696765551, 1598843971, 1349869089, 2660204100, 2289732223, 2357293035, 2844358759, 2473371019, \r
+2490665395, 2292090013, 1953467004, 1736802443, 2368632169, 1434032925, 2123850378, 2572419184, \r
+254164311, 1263619675, 1754560612, 2712161401, 2676984733, 2056293255, 2527107180, 1649639302, \r
+2173599616, 2104658539, 5404044, 2340973714, 1921421417, 1752850531, 2274329461, 2407694717, \r
+1920630384, 2138873276, 1632795220, 1667726473, 1738568023, 2073594508, 2406637940, 2405136013, \r
+1335983203, 2034171905, 2185266308, 1482770785, 1163427690, 1332307298, 2844626350, 2257023361, \r
+1704431510, 2190696052, 1314810958, 2188672389, 2036757617, 2525709141, 1364811083, 1666064731, \r
+2000358786, 1349727344, 3219790, 1383024220, 1838646889, 2439339644, 3367206199, 3462826328, \r
+2140654788, 2556003691, 2275300207, 2074214349, 2105302336, 2138717090, 2209014443, 1568775326, \r
+2089849680, 1837259653, 2474799781, 2089184085, 4271782503, 2949906528, 2212812480, 2463339729, \r
+3483020239, 3187315571, 1061377297, 1904776869, 3043576143, 2293075111, 2678298234, 2797129149, \r
+643580433, 1282559334, 2846009475, 2123596176, 1719445391, 2654772922, 895776356, 2524626242, \r
+1750973012, 372453490, 1801160448, 1870307165, 2706006131, 2058191988, 1853913190, 2105631102, \r
+2509672061, 2845483909, 1937353919, 1715900052, 2324269695, 2307886461, 520140932, 1920102494, \r
+2189849437, 2022078316, 2138927209, 1869769853, 2122022023, 1969709920, 1300672684, 1405002375, \r
+2306359647, 2382342531, 2020132991, 2555986500, 3953828472, 1656081227, 1862749045, 2138076335, \r
+2290636192, 2424932743, 1786090592, 2141158534, 1430462854, 1459620384, 537497727, 1883400519, \r
+2507502692, 1985123728, 1026300709, 1966422070, 2869703992, 1682778514, 1788304189, 1366395768, \r
+1935748223, 1721657925, 1638058434, 3014392201, 1938000034, 2300348301, 1686140068, 2058789201, \r
+67150468, 2015983941, 2292026116, 1704368277, 3009776255, 2913505402, 1598447468, 1653381486, \r
+2408230569, 2193011861, 2339543191, 2730792073, 2137956732, 2269992778, 2893771105, 1668001620, \r
+2449484581, 1952683672, 2188863620, 2510132610, 2004383594, 2089256064, 3720251263, 3665904779, \r
+2510795519, 2437245577, 2292414322, 1601078370, 791830672, 2223732132, 1552578902, 2084595536, \r
+2303956144, 2291174499, 2088647814, 2089257542, 2173863810, 1181655420, 2488176016, 1432189819, \r
+2308018309, 1939819066, 1272697, 2877663854, 2307992938, 2672978821, 1835701637, 2339668883, \r
+2457106091, 2089715037, 2592710300, 2543235495, 2410196374, 1802410629, 2409200244, 1817269354, \r
+6718526, 2946973503, 2082355825, 2457564554, 2306181260, 3146749316, 2054779785, 2038986120, \r
+2641901657, 3007207484, 864858725, 2739047297, 2726771321, 2157300896, 2775009337, 2102263875, \r
+1580703135, 1334342030, 1584908578, 2053912932, 2358473364, 2206283623, 1248909981, 1958804636, \r
+2574331267, 1666027147, 2238146707, 2210357117, 7313025, 1854643624, 1993829740, 1302357106, \r
+2173274232, 2809629841, 1970438770, 2038472321, 2575711629, 2584498842, 1605880380, 1035972251, \r
+1342934475, 3900743600, 2751435880, 1057691758, 2440332648, 3081949100, 2208385548, 1331648120, \r
+2358539168, 2286310765, 3032646039, 2908842345, 2162157567, 1705288065, 2680329827, 2034729576, \r
+732986657, 2780518465, 2250854290, 2236900197, 1902867646, 2074252941, 1921221748, 2273004655, \r
+1602177679, 1536514102, 2305770609, 3496901763, 2814071432, 1953108278, 3479402870, 2647070670, \r
+1864106088, 814306388, 1502133383, 2424273276, 1954576495, 2058201466, 3099813750, 2200462377, \r
+816235493, 1889241956, 2730789958, 2841959619, 1542902654, 2144435712, 2719241636, 2172104810, \r
+1569682117, 1303665038, 1870437250, 2170803120, 4036298099, 3449954128, 3467964159, 1819636878, \r
+2039386480, 1855356742, 1129555013, 2930078048, 1182169418, 2205768761, 3078333261, 2695135371, \r
+2443408771, 2623417681, 2760486533, 2576337081, 2726996407, 1721735567, 2410060182, 2170827139, \r
+1893512854, 3103772303, 2120763606, 2794354832, 1687787668, 1432519818, 2340390792, 2172222057, \r
+3570975339, 3535328662, 2693981659, 2258200958, 2290585203, 1822140348, 4292381308, 2511065246, \r
+1907213556, 2390470287, 2073139849, 2089522304, 2373747080, 2239270262, 711759474, 1200655718, \r
+2255625577, 1768062081, 1720293251, 2374521414, 977375141, 1402516866, 1751523328, 2121615984, \r
+2356109975, 2104522870, 2022073983, 2239138164, 3956861823, 3048341456, 3050360772, 2142017701, \r
+2206697608, 2207945136, 3032266639, 2210046888, 2042739153, 2509081184, 2172093596, 2290124164, \r
+1938461813, 2357294975, 589037714, 810156119, 1430986549, 2086830956, 2187947389, 2590797667, \r
+1215261862, 1747792185, 2504732951, 1855150721, 1566342007, 1265004176, 2022214256, 2088661903, \r
+2778378879, 2360655258, 2726605241, 1870759810, 1936237690, 2052282461, 1281718632, 1837807168, \r
+2080382794, 2572578935, 1988125314, 2122943869, 2257221247, 2307288432, 3634998677, 3502096581, \r
+2392255420, 1955499666, 2660794488, 1582589352, 2263259232, 3184686177, 1938203903, 2241441411, \r
+1754901406, 2139064195, 2004789347, 2256376212, 1789939032, 1870875954, 1469008845, 2024050525, \r
+2630776153, 1564692554, 172979317, 2512724480, 2115765366, 1816477602, 1297654443, 1869834624, \r
+2021030794, 2055767678, 2355723161, 1836483213, 2410782573, 1718323071, 2020367486, 1784696911, \r
+3559478, 2571769142, 2082743388, 1969908085, 1853062246, 2726595190, 2256696208, 2190309532, \r
+2506967947, 2486855495, 1335140442, 3282866814, 2458790507, 1619836590, 4159010380, 2606170181, \r
+2037228202, 1182629529, 1753601387, 2357223291, 2206305921, 2122285979, 2705852014, 1732116577, \r
+1167962930, 2228067212, 2053020283, 2136847025, 2341564273, 2388020528, 2303702501, 1953927818, \r
+1936941122, 1652451951, 1854443115, 2088200842, 2276706920, 2379003036, 2591190731, 1649574530, \r
+2294003822, 1935832686, 2918528, 2278216024, 2170919799, 2339859829, 2171633317, 2106363778, \r
+2105045879, 2021753443, 2522117522, 1653892000, 2285992836, 2404014204, 1872011683, 2260360348, \r
+4119632346, 2042560255, 1977654948, 2543484272, 2508819372, 2122159503, 2441511041, 2120786315, \r
+1031880036, 1165900345, 2072262014, 2203417204, 2693956447, 1881890174, 1048161978, 1656966215, \r
+2181053242, 1569148014, 1569625247, 1904765558, 2274262916, 2307555686, 2923731422, 3680945808, \r
+3475730688, 2906537837, 811686265, 1803265330, 3204420689, 1343250804, 1068983190, 1275046221, \r
+2253550284, 1365200061, 2327838861, 751668054, 1748818127, 1921285324, 2472447671, 3881939864, \r
+2488110592, 2170648230, 1670898603, 3643380445, 3849740333, 3006665728, 2205058018, 1617605923, \r
+3793778749, 589631487, 2100963751, 7741242, 3028578657, 979837320, 15293572, 1408209513, \r
+2441106115, 676677811, 2675218111, 1733681552, 2818594048, 1503141807, 1320447116, 1560259635, \r
+2218485218, 1550009572, 1232426407, 766719026, 3263729006, 893727487, 1962891364, 2172694202, \r
+741840605, 2446260541, 7157140, 226233448, 2443353420, 324216192, 2136583441, 1037172761, \r
+1751736994, 2127975339, 2894956756, 2894910526, 3157131102, 3711247531, 4282803651, 2506745457, \r
+3278410086, 3260959772, 2893326079, 3292060796, 3529314853, 1193891218, 2466283394, 2155122591, \r
+1990076217, 1383093387, 2139663000, 1955200958, 2538165403, 2594408381, 2330739875, 4286081186, \r
+253811316, 760712285, 4282870631, 1613407412, 2255073636, 1957456489, 2449498770, 1397462973, \r
+2713537300, 1332775183, 1331446960, 3663482827, 2504965632, 2820765016, 2063756394, 1983807469, \r
+2791535616, 2155895668, 4290473642, 2019998648, 2028771964, 2105452611, 2897364160, 2624114841, \r
+3187653778, 3161489197, 2106565802, 1401269815, 4284585322, 1633697666, 177160868, 1775743382, \r
+2415880331, 1902600765, 1874094211, 2274139495, 2174621710, 576061528, 3875504355, 1901905787, \r
+2807819214, 2802492608, 2143761771, 1049646035, 2701193148, 3989409408, 3499852287, 2891169623, \r
+3189682537, 2690025874, 2188574617, 2441108100, 2559076963, 2709019782, 889157462, 2631364932, \r
+1029410265, 1958851729, 4284805509, 4032464061, 2157751368, 4067462204, 2224005264, 2590870527, \r
+2255506252, 2658831402, 3160982437, 3928482792, 2580268383, 3910855424, 1502639214, 1910542141, \r
+2035305196, 2395238655, 2458683556, 4284719568, 2472380715, 2789438298, 3714770040, 3060106944, \r
+1940631798, 4294758179, 2794144985, 7898922, 3091393917, 1952353161, 1788309890, 1986099071, \r
+3657380671, 1330925901, 2715000053, 2522407056, 4284639557, 1816622902, 2659876950, 1687521054, \r
+1064927176, 2445703935, 1013208644, 1854349459, 730243217, 1939472252, 2271730002, 3148305841, \r
+1268028616, 3674190750, 3868065733, 2974524051, 3140512631, 4117068704, 1045028196, 3188147096, \r
+3187091715, 1048722458, 1044438150, 1054176875, 3165809453, 3201099181, 3204448470, 1029245143, \r
+3198830178, 3196461227, 3199413977, 3186671000, 3196405201, 3195989811, 1032168884, 1059437825, \r
+1032064060, 1050543985, 1033045084, 1056701195, 1057021569, 1049023561, 1036199045, 1038379015, \r
+1050094320, 1026327563, 1036063437, 3163113125, 1023780035, 1033511828, 3175687190, 3173854553, \r
+3155533713, 3186623314, 1026763278, 3185053318, 1016586273, 3156598046, 3186716290, 1015071120, \r
+1032117674, 1010632425, 995393526, 1032727400, 3171784975, 3175161886, 3176936336, 3162690747, \r
+3175884424, 3186668612, 3166612526, 3188911713, 3166352688, 1022843414, 3190716421, 1020060631, \r
+1043397138, 1043277032, 3169150825, 3184199534, 3188658047, 3161732892, 3224820465, 1077243195, \r
+3212841926, 1065232188, 3223698690, 1076215042, 1050053902, 1056150035, 1065353216, 1053982924, \r
+1053893536, 1052571715, 1050996111, 1064827658, 1059327947, 1057437093, 1058087927, 1051309448, \r
+1054016810, 1060982480, 1060336120, 1056412753, 1049942441, 1045522621, 1051729123, 1060893841, \r
+1052106948, 1052374095, 1051699368, 1057145108, 1052824750, 1054738880, 1057208621, 1046937874, \r
+1052166813, 1042975492, 1052038751, 1049580325, 1043272423, 1042386458, 1054021399, 1057488666, \r
+1053645904, 1057966114, 1054508149, 1054269945, 1052664979, 1048829650, 1054180111, 1048936391, \r
+1050118801, 1050361429, 1048982779, 1050736591, 1055970571, 1055366492, 1065353216, 1062200251, \r
+1061996119, 1054153913, 1059679626, 1064120332, 1060719999, 1059607066, 1063592999, 1062352716, \r
+1060229252, 1062884975, 1060888553, 1061430249, 1056226279, 1052193613, 1058046252, 1058997499, \r
+1050249023, 1060413674, 1058204673, 1051033301, 1057141104, 1054293788, 1057284288, 1055062704, \r
+1048709326, 1056291349, 1054148009, 1052797499, 1056215580, 1059007561, 1052396216, 1057944879, \r
+1060178220, 1055240391, 1057003677, 1058050289, 1057005833, 1056070374, 1057090670, 1056737892, \r
+1056259717, 1055930067, 1057841029, 1055901363, 2185139389, 3931556245, 3355410511, 2869792548, \r
+1564195760, 4285773757, 2447024974, 3023127345, 2013303415, 3358560980, 2644250383, 1668710961, \r
+896173772, 4084989871, 3504910709, 1865105519, 2153289902, 3646003631, 3439311194, 2284411716, \r
+2836280564, 2992439183, 3200088697, 2100251292, 714702959, 2578931290, 2044198811, 2472110732, \r
+1984813224, 4281380794, 2899002672, 1750364186, 2359784843, 4286103972, 2865141599, 2689033051, \r
+1985576085, 4031366510, 3702348128, 2436256512, 2961099936, 4068008300, 3019869822, 4166012850, \r
+2590475162, 2586283965, 2892786271, 1833335040, 1902883035, 3373778101, 4292812886, 1228430381, \r
+1261673399, 3971462343, 2293497713, 3662825581, 858511272, 3312679753, 3640602412, 2420934451, \r
+2905701519, 3011641279, 2371575363, 2558001290, 1899731813, 462057527, 2961842261, 1618149550, \r
+583073937, 3231149831, 228672604, 2082615018, 1889473691, 2475456795, 2190984704, 1245388684, \r
+1932812430, 428375164, 3432767345, 1786804480, 1342142112, 2999311834, 1901268670, 2125181728, \r
+2423128256, 1133102433, 1772593535, 1281175386, 1820091587, 4105174974, 1059937114, 1130271674, \r
+1694471595, 2962080427, 2976283247, 2543434258, 1400864611, 2223154429, 1317880681, 2214574369, \r
+2316016512, 3209647576, 1364656384, 530145714, 1798147947, 457400160, 3650158439, 2376894780, \r
+2988809393, 2205336423, 2587838880, 2926598655, 1189496797, 3136211592, 1362221747, 3379429252, \r
+979187881, 1031981217, 2967606107, 915880192, 3147984513, 9670237, 3363075240, 1650856354, \r
+2680198012, 2641136385, 2389480811, 3478666751, 553695817, 2404854403, 1993840526, 1143277550, \r
+6392898, 2909554616, 1030167335, 2999496060, 1646558371, 2675086847, 1766722081, 1668985458, \r
+1971875951, 2022342299, 2776975740, 8087074, 1398827161, 2816696035, 1336475488, 3175713402, \r
+1905302940, 1642435144, 3032521921, 2392916198, 2140587881, 2594396292, 3044715676, 4284314988, \r
+2345291384, 1636788048, 1939434751, 1704426400, 4278354843, 341733143, 4117994916, 1182534537, \r
+9141384, 1805805211, 2729398289, 1203913841, 2758438535, 2473555130, 1821045676, 4287739308, \r
+1698581618, 8062299, 3162030181, 2463055210, 2434174635, 1853976969, 2674851714, 2203343008, \r
+1704237926, 2595291248, 1350395995, 2447146028, 2883552860, 3899544244, 1753848959, 2963789056, \r
+1358932359, 2809773765, 2267852537, 3984846989, 2514849113, 420915774, 8665813, 3791924984, \r
+2665977649, 1514622296, 1383596203, 2216920232, 4291417744, 844586345, 2218227288, 1483263653, \r
+1101823378, 2954778668, 7362693, 2939231394, 4055135301, 608588363, 1834628095, 3358374101, \r
+3505817066, 520129117, 225192598, 2622366699, 3290116210, 2040180148, 2856910626, 1001149330, \r
+3350415187, 2886060599, 10312655, 2504870358, 2364722370, 1931124627, 363802829, 4280374907, \r
+3367935650, 7249042, 1817063834, 3641742781, 2526640741, 1231166791, 7811729, 3994691279, \r
+3953997703, 1183143495, 3295805659, 1670817719, 3320932462, 2550238726, 531256054, 3489675772, \r
+1903837545, 2792004983, 12723560, 2607489394, 3593801879, 1417204862, 2350138273, 520116945, \r
+2781051177, 1345619240, 591855791, 1549751954, 2944158021, 968012442, 2291161457, 2197857135, \r
+2629337433, 1534787723, 3398010975, 2609616984, 2028352512, 2505596535, 2559341157, 2241818987, \r
+1433684480, 2063341972, 2576448415, 2222369369, 1668072111, 2939944813, 1163653962, 1675180903, \r
+1919845201, 3204678710, 326248191, 1906397482, 2240045664, 2281744461, 278466443, 2238054589, \r
+2106169691, 1822469241, 2119547847, 2835316617, 1081653697, 2082938721, 1652982458, 2342387560, \r
+2961419174, 1560505460, 2054963915, 1526767278, 1316108861, 1489202075, 2835321685, 2757053324, \r
+1551571022, 4285575982, 1467978895, 1582980953, 1689262398, 1252186490, 1000660746, 2058158258, \r
+2543255385, 2287769958, 646558594, 2708769327, 1654996515, 2456027017, 1853325368, 1809455002, \r
+1155946191, 2391268470, 1874263861, 2689676141, 466072046, 3698284927, 1727045974, 4287452734, \r
+1488635516, 2035817563, 2343455701, 4287390306, 2499785119, 1329558901, 1938318728, 2777910399, \r
+4283795033, 1570739861, 3208539292, 1049476240, 3162457972, 1216769466, 4284051599, 1514832615, \r
+2037735607, 2155085714, 1755171888, 1738766189, 2237958021, 2479514540, 4284670596, 916449903, \r
+6913887, 3650587250, 1975681935, 3050009913, 1907031903, 2189716856, 2021872054, 3164461380, \r
+5449085, 2710797184, 2630479680, 2697406846, 263553412, 3360386909, 1275030166, 3885188420, \r
+2978522020, 1973436819, 4284129175, 2444096129, 3685383888, 1180264057, 2757635482, 2116199167, \r
+2506277196, 1723400323, 3646247393, 2408167026, 1090525272, 2883097482, 2188285058, 1187792487, \r
+2900545681, 1550136196, 3093590922, 4286493302, 1056153604, 1001549168, 1062694850, 1057516040, \r
+1041245166, 1063371019, 3211055233, 1055962907, 1037251973, 1058933293, 1017202755, 1056835427, \r
+1059807094, 3205382205, 1045599349, 1046408632, 3174869463, 1048653317, 1037535864, 3164243130, \r
+1050675063, 3197932750, 1040403025, 1040955800, 3181355567, 3183361016, 1046113547, 1047307519, \r
+1040009125, 3184983209, 3193502493, 3174935277, 1041709350, 1036380543, 1038281528, 3178777731, \r
+1032180496, 3185234195, 1034383527, 3186841277, 3189985497, 1045659305, 1035779285, 1040336220, \r
+1039922244, 1029709734, 3189561821, 1039303907, 1024061996, 1037737431, 1038674268, 3175945227, \r
+3179969795, 1026686725, 3158328760, 3155054061, 3185486350, 1043259074, 1025912135, 1038520838, \r
+1023397394, 1031830153, 3180720639, 1026383194, 3215045462, 1067479023, 3209036884, 1061451851, \r
+3227832454, 1080348806, 1060194778, 1060556088, 1059718412, 1057400320, 1065353216, 1058908440, \r
+1064123975, 1061332058, 1059719049, 1057735981, 1058713545, 1058725348, 1054062390, 1058805631, \r
+1051838666, 1056109030, 1056923585, 1045663284, 1051564655, 1056369011, 1052860126, 1055489157, \r
+1049678517, 1055885276, 1057976642, 1053688137, 1055094211, 1054341324, 1051045757, 1052175184, \r
+1053054114, 1053476472, 1046330183, 1049231544, 1052630998, 1047275203, 1049643636, 1047733937, \r
+1051006946, 1052891045, 1046290601, 1046999367, 1051817100, 1045203222, 1052581312, 1044836693, \r
+1051690645, 1049185897, 1056235337, 1062687999, 1065283443, 1059412476, 1064137619, 1062714064, \r
+1064443242, 1059757281, 1060380638, 1058137226, 1060633733, 1059591653, 1060360800, 1060844858, \r
+1064839510, 1059067842, 1052953330, 1055694299, 1061367597, 1057689846, 1057610776, 1056935455, \r
+1059449932, 1057096842, 1058734287, 1057919403, 1058566930, 1056895411, 1054031025, 1055635203, \r
+1059498416, 1055120428, 1058125863, 1058415083, 1065353216, 1058958671, 1060599312, 1059567352, \r
+1060109813, 1059674485, 1064268196, 1057902728, 1060117769, 1059548721, 1063637984, 1056179587, \r
+1063982756, 1062527920, 3182442602, 3188783726, 1015758495, 3190092607, 3187471573, 1030337675, \r
+1037744727, 1035000633, 1047231595, 3201066392, 1017605744, 3187895739, 1020857818, 3197313594, \r
+1006812928, 3157641267, 1036383416, 3148236092, 1023535633, 3195985295, 3183623009, 1030641371, \r
+1034082176, 1048277884, 1044235691, 3196071439, 1033674115, 3182874057, 3178962317, 3196287554, \r
+1039388469, 1031549056, 1039353324, 1043510178, 3169516321, 1049316448, 3189745512, 1027724561, \r
+3194869089, 3146862128, 1041875993, 3188346560, 3191400072, 3196364207, 3150698505, 1034500746, \r
+3164782734, 3178537940, 3208553208, 3184783143, 3180749697, 1037341235, 3198596188, 3195072986, \r
+3197034124, 1028223053, 1049402816, 3201309091, 3200706769, 3198333769, 3189405219, 1040941292, \r
+1043035012, 3188968956, 3183456579, 3201105443, 3178867821, 3159786005, 3193105287, 1039092813, \r
+999969797, 1034627963, 1050340450, 3202272580, 3178361657, 3194381017, 1023004467, 3196857070, \r
+3172066299, 3182772425, 1043909883, 1031371008, 3180088832, 1052223731, 3192133000, 1038612653, \r
+3189019415, 3171557162, 1030087726, 3181895261, 3200770313, 3200032133, 3173051037, 1002037207, \r
+3181656336, 3181374962, 1040710749, 3200674136, 3180968132, 1042597898, 3190194882, 1054120192, \r
+3189831654, 3164759293, 1046631971, 3204620009, 3180860760, 3196129037, 1022019704, 3194365798, \r
+3186657763, 3179465161, 3209682447, 1053443529, 1018091088, 3182846249, 3186277312, 3197705892, \r
+3185991381, 982627531, 1049066620, 3188984639, 3182351727, 3187612721, 3180936076, 1058225152, \r
+1048703438, 1025888536, 1053403047, 1051802598, 3192493801, 1049401700, 3187411851, 1034902514, \r
+3189017154, 3175176071, 1020734439, 1024098904, 3174190304, 3197447640, 3122300643, 1030129987, \r
+1005190391, 3156533679, 3208187636, 3137583766, 3158750930, 3177913017, 3189201020, 3198962021, \r
+1035949322, 1029340399, 1048483900, 3196232128, 3171597973, 3194519393, 3188778030, 1033268335, \r
+1049411613, 1034211732, 3182230353, 3199142305, 3167686807, 3190776493, 3190846108, 1032994716, \r
+1019539884, 1028661121, 1045842692, 3205574650, 3174890315, 3191820215, 3172464520, 3195546236, \r
+1023377709, 3164168209, 1041683328, 3200173606, 3160030277, 1019559630, 3189933411, 1054454429, \r
+3172085723, 1007804112, 1048658525, 3202761363, 991967532, 3188557786, 1033369092, 3195730122, \r
+3185215278, 3168142617, 3198196297, 3181061401, 1036955297, 3169617267, 1040124345, 1045710131, \r
+3193603027, 3192547111, 3186423407, 1039345342, 1040104799, 1035137377, 1044567373, 3172533279, \r
+1043339847, 1033360829, 1053681261, 1051692527, 3192189008, 1049419989, 3187710377, 1035980352, \r
+3188824607, 3175780427, 1018031387, 1025594459, 3177543926, 3197528254, 3148324375, 1030035630, \r
+973531326, 3160105858, 1031936280, 3186712394, 3174293999, 1055228840, 3193659330, 1039887091, \r
+3192757808, 1018349796, 1044522081, 3193885710, 3202133269, 3199541501, 1007411853, 3183413482, \r
+3183209630, 3182242207, 3190629909, 3156766241, 3171087970, 1051396405, 3197442636, 3179009517, \r
+3198779541, 1024609819, 1041671955, 3191846133, 3204476606, 3198788192, 3162582389, 1030916450, \r
+3174491420, 3189356868, 3160138254, 1001264504, 3182630391, 3189285192, 1015495762, 3175718786, \r
+3159127783, 3187305330, 3159803824, 3179601732, 3166411854, 1015250056, 1040338121, 3152543508, \r
+3184214365, 3180519801, 1057038887, 1057448382, 1057074805, 1065932723, 1061535600, 1058982608, \r
+1064637364, 1062871033, 1057069318, 1063966360, 1063053448, 1058452086, 3202895764, 1057068248, \r
+1063761610, 1060457440, 3199239041, \r
+};\r
+\r
+uint32_t* get_knConfNetWeightsArr_addr(void)\r
+{\r
+    return (uint32_t *)(knConfNetWeightsArr);\r
+}\r
+uint32_t get_knConfNetWeightsArr_size(void)\r
+{\r
+    return sizeof(knConfNetWeightsArr) / sizeof(knConfNetWeightsArr[0]);\r
+}\r
+void get_knConfNetWeightsArr_version(char* ver, uint8_t len)\r
+{\r
+    memcpy(ver, NET_VERSION, len);\r
+}\r
+#endif //#ifndef Goodix_DSP_EXPORTS\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/algo_params/HR/04_EXCLUSIVE/HRNet_knMultiWeights.c b/code/sdk/drivers/peripheral/ppg/gh3x2x/algo_params/HR/04_EXCLUSIVE/HRNet_knMultiWeights.c
new file mode 100644 (file)
index 0000000..32cbdfb
--- /dev/null
@@ -0,0 +1,179 @@
+#ifndef Goodix_DSP_EXPORTS\r
+#include "goodix_type.h"\r
+#define NET_VERSION " "  //ep3_1p960957_sha587415\r
+#define NET_SIZE 1269\r
+const uint32_t knMultiWeightsArr[] = {\r
+       1043000169, 1003489461, 3203556548, 1037978647, 3202562628, 3184211800, 1027257975, 1033941631,\r
+       1041876231, 1033497998, 1055704244, 1051900041, 1062166726, 1039604749, 1003602602, 3197306771,\r
+       1050140138, 1031857020, 1057003161, 1057647298, 1059958344, 3204737100, 1051983089, 3201898501,\r
+       1030777414, 3186487550, 3207680481, 1027271899, 3207158883, 1054395695, 1043777335, 1049560253,\r
+       3170463760, 3192379678, 3154618630, 3193969733, 3188197269, 1051341308, 1004068613, 1009718307,\r
+       3177920954, 1020952064, 1055575439, 1048754649, 1053952655, 3203348445, 1046499775, 3198919192,\r
+       1045447337, 1043387650, 3180024562, 3181236357, 1032224772, 3199639544, 3197052369, 3191056953,\r
+       3189990449, 1005405015, 3198433215, 3208204681, 3191164218, 1058954724, 3171072317, 1051756737,\r
+       3190186591, 3181186408, 1015238568, 3197448399, 3197587375, 1057997814, 1042611521, 1055366218,\r
+       1014318639, 1032466341, 1042159326, 1047187093, 1040039301, 3183994137, 1042691451, 3184893581,\r
+       3164788197, 3192789828, 1027358272, 3146807498, 3195845868, 1045112706, 1041816464, 1044159315,\r
+       1017234693, 3196739915, 1055584887, 1012800790, 1058332983, 3189992158, 3192325821, 3179399141,\r
+       1032018321, 1049328871, 1055415586, 1058995111, 1058544142, 3197516881, 1050147019, 1018115355,\r
+       3189097162, 1023171823, 3212746243, 1015977571, 3206425516, 3172660193, 3196458454, 3167788939,\r
+       3188920359, 988068955, 3204138813, 1041183371, 3205198266, 1052188562, 3194924174, 1050324545,\r
+       1050816311, 1060429474, 1065231479, 1066151798, 1067777081, 3207982575, 1061442265, 3204900754,\r
+       1005445651, 1040796112, 3183624010, 3196116845, 3196189984, 1057454199, 1045040363, 1052556588,\r
+       1034886154, 1045306583, 1027667792, 1029645803, 1043237759, 1034278297, 1032760934, 3172126394,\r
+       1049382532, 1049616205, 1042608720, 3164450833, 1051523331, 3198433495, 3193087437, 1015233075,\r
+       1036838536, 1049831594, 3205361544, 1040776858, 3207855834, 1048974733, 1048616042, 1048870711,\r
+       1041765309, 1040322406, 3174433308, 3166421229, 1043310863, 3198266620, 3196019258, 3189281923,\r
+       3164963137, 1054487990, 1038764499, 1051014610, 3163151651, 3167816145, 1048600613, 1028210053,\r
+       1041445398, 1014090059, 1041334344, 1041552907, 1046512422, 3196176836, 1005808251, 3188665101,\r
+       3181108938, 3177707246, 3192140567, 3202945276, 3186217800, 1055109391, 3187918892, 1016674590,\r
+       1035399062, 1052714694, 1053698430, 1047866052, 1054224108, 3197655324, 1051822727, 3196569366,\r
+       1047469631, 1034537912, 1037487120, 1037003306, 1028755771, 3196588466, 1046883441, 3181275112,\r
+       1041427825, 1040531447, 1049487164, 1050907532, 1048395756, 3198576122, 1040974613, 3174735553,\r
+       1043359284, 3174859086, 3194889675, 3189589663, 3206989776, 3177281110, 1049239364, 1054063128,\r
+       1034396553, 1048443495, 1045094033, 1050672781, 1042826858, 3198493844, 1053586833, 3177869211,\r
+       3180613476, 1051909013, 1026350511, 3180832839, 1043166615, 3189795108, 3188156215, 3189005527,\r
+       3154328051, 1047462455, 3202010097, 1029166271, 3207221209, 1042537081, 1044966843, 1048502221,\r
+       3171969303, 1054673228, 1054770692, 1058597149, 1056800603, 3192864870, 1047430741, 3188512005,\r
+       1051087931, 1031063153, 1059554378, 1052857686, 1063816204, 3158589650, 1040342134, 3199572746,\r
+       1045020362, 3178121012, 3205104686, 1049234268, 3208107475, 3203468422, 1031988940, 3171220295,\r
+       1045690063, 1037984854, 1055560868, 1052481609, 1059637251, 3165825504, 1044130818, 3193436513,\r
+       3183215095, 1037690836, 3208438900, 1040312660, 3206264833, 3196265205, 3177317356, 3187915983,\r
+       1029158840, 3173532583, 3198316342, 3182373162, 3200688723, 1041111850, 3169476603, 1019543571,\r
+       1052196691, 1041567592, 1060118185, 1051277733, 1060638818, 3210145033, 1057186995, 3201355357,\r
+       1046179511, 1033049438, 1055643288, 1043829028, 1060956479, 1044155430, 3189899956, 3196833012,\r
+       1040291355, 1040947095, 3198736715, 1053418120, 3205297834, 3199421736, 1044032738, 3192869857,\r
+       1041202379, 1040720767, 3192590122, 3192558750, 1034887895, 3198596937, 3196394775, 3186442772,\r
+       3182151975, 1051892263, 1034947800, 1034041870, 1030627346, 1046068508, 1034417485, 1039990265,\r
+       3181168091, 1045186008, 1044001243, 1048950481, 1049472357, 3191644337, 1048205939, 3192925817,\r
+       1036549381, 1024828122, 1027152967, 1029933203, 1026742536, 3188433806, 1041190904, 3197237341,\r
+       1059816238, 1052170631, 1061303133, 1061767325, 1063931317, 3208086798, 1060645600, 3203123868,\r
+       1042408793, 3164391589, 1041957257, 1054690289, 3151127067, 1052622317, 1045640577, 1046565224,\r
+       1039262784, 1047815138, 1025967974, 3149547249, 1051358043, 1037239506, 3176418852, 1020928587,\r
+       1030790770, 1030787009, 3178911892, 3195943913, 3187777009, 1054712721, 3162957539, 1045337987,\r
+       3143527200, 1036512036, 1048344074, 1044054745, 1046311903, 3204491799, 1046124692, 1023165706,\r
+       1039941713, 3192862799, 1034385289, 1028646294, 1031513321, 3196825451, 1032562118, 3184286301,\r
+       3191052433, 1040010419, 3164004522, 3190984881, 3197770141, 1066543719, 1023638000, 1060829570,\r
+       3147165373, 1048276338, 1049594679, 1042234322, 1040317401, 1024948457, 1048668365, 3178005648,\r
+       1032284096, 3176627329, 3207892681, 3163537769, 3208263027, 3193641508, 3164762844, 1012594079,\r
+       1013310818, 1032347081, 1057259770, 1057773931, 1062351683, 1049655892, 1040731028, 3197632880,\r
+       3173653019, 1052945840, 3186699048, 1016997370, 3196184440, 3202714168, 1042321251, 3193300598,\r
+       3175023464, 1056134339, 1054712529, 1036321310, 1055302741, 3186341880, 3173900933, 3184305214,\r
+       3172269813, 1034455713, 1048835342, 1033431303, 1059236189, 3186369436, 3192258800, 3195495951,\r
+       1038440163, 3176772252, 3201325407, 1041727399, 3201560244, 3174976055, 1009573844, 1026788809,\r
+       1000339335, 1042284962, 3197622804, 3181180761, 3206544438, 1045480200, 1044808812, 1041230273,\r
+       3185989945, 1050582949, 1049783601, 1052685741, 1056424986, 3187353939, 1029194551, 3188686500,\r
+       1035720595, 1049603588, 1053161518, 1052698308, 1059621964, 1033167184, 3168998543, 3164824396,\r
+       3174394752, 1044417334, 3208572758, 1049230686, 3206824051, 1025488192, 3172110667, 3185187924,\r
+       1029403020, 1023439896, 1025154828, 3143621215, 3189118290, 1057109037, 1052953268, 1052672020,\r
+       1047634431, 1028724697, 1041560269, 1036887887, 1041909077, 3188315588, 1042614157, 1016498550,\r
+       3191968066, 1040650947, 979550852, 1047626407, 1030433898, 1032194269, 1047195979, 1049514323,\r
+       1033333292, 1051205027, 1040786610, 1036392030, 1038167175, 1043855391, 1045109358, 1056178311,\r
+       3179782268, 1043328556, 1053670006, 3168206323, 1044451678, 1052274851, 1055104908, 1033422650,\r
+       1048691788, 1034720844, 3190082611, 1052352734, 1042029766, 1035934677, 1044794001, 1043494777,\r
+       1063921913, 1061804433, 1066274629, 1056849883, 1043549742, 3210715942, 3190071953, 3192665740,\r
+       1050954128, 1062288667, 1062815960, 1062357171, 1054180237, 1056329654, 1046951294, 3194010305,\r
+       3188081603, 1045760270, 3199608680, 3197065716, 1057609980, 1058749179, 3162866282, 3212931176,\r
+       1055249297, 1054086214, 1052080438, 3184236709, 1035389871, 1055400134, 1027661996, 1051913301,\r
+       1057848244, 3199349898, 3201160317, 3192344669, 1037220211, 1049492804, 1055699177, 1060921591,\r
+       1059438088, 1044051573, 3189023794, 3181620780, 1025253951, 1017045446, 1049477942, 1044216484,\r
+       3206705265, 1061107003, 1058512852, 3207606680, 1052685089, 1055410073, 3196521888, 3173231615,\r
+       1052213889, 3207067397, 1059398640, 1061212879, 1031908764, 1049368976, 1051842120, 3186205965,\r
+       3183016387, 1053160680, 1053279560, 3162736841, 3211478477, 3187261981, 3201068883, 3192696730,\r
+       1026938053, 1040172730, 1055652853, 3197995727, 1043092976, 1055215738, 1065670847, 1063523461,\r
+       1068169841, 3192683353, 1042193743, 3181565518, 3198112483, 1041365713, 1056242646, 1038210736,\r
+       1060047542, 1060811195, 3204616334, 3154627334, 1058496519, 1050951945, 1052677289, 1057580840,\r
+       3172486658, 1039765541, 1040342149, 3166530791, 3189899264, 1032983727, 1038002307, 1042957241,\r
+       3188656418, 3152624417, 3185376351, 1049902551, 3168453919, 3182179918, 1044125305, 3187814455,\r
+       3172768768, 1042772205, 1032762274, 1036746205, 3172265914, 1008476918, 3131375236, 1050915659,\r
+       1008744620, 1040691653, 1039475782, 1024280570, 1041781963, 3177509311, 1043739362, 3164352644,\r
+       1035955312, 3195943294, 3187016771, 1023005647, 3199769627, 1059549294, 1051599026, 1018405874,\r
+       3202274094, 1060262724, 1057829418, 1064664868, 3191270880, 3193127272, 3210182220, 1064467828,\r
+       3163170493, 1051039213, 3191015834, 1045087475, 1053088610, 3186824807, 3202164641, 1062879562,\r
+       3196875834, 1015991607, 1046865312, 1057228489, 1033147807, 1060942193, 1051578163, 3201923372,\r
+       3186184552, 1041143147, 1058737169, 1021900912, 1051882602, 1066890529, 3212077045, 3206196521,\r
+       1047545249, 3196949426, 3201952902, 1021913396, 3188256574, 1024687711, 1048748530, 3205771691,\r
+       3201325739, 3208159330, 1059476349, 3200714551, 3192545668, 1059040946, 1053308134, 3194773088,\r
+       1058126660, 1051449829, 3165353478, 1041539043, 3169588800, 3174728122, 3208788784, 1054309789,\r
+       3205429377, 3203427841, 3218101242, 3199825718, 3196091550, 3200738230, 1062735250, 3172390380,\r
+       3184759116, 1047432026, 1052885883, 1054433379, 1054330907, 3208645468, 3179399153, 1041965309,\r
+       1062132667, 1058935946, 3213753681, 1062723597, 1047506784, 1049365607, 3191005844, 1044686486,\r
+       1053300025, 3208986473, 3198345736, 1045767690, 1053621898, 1020900202, 1062349365, 3184886093,\r
+       1067074266, 3193967941, 1048236976, 1055902258, 3184999853, 1055140586, 3206752425, 1066531912,\r
+       1031578827, 1039403997, 1033591111, 3199668440, 1049585291, 1010087030, 3196387535, 3172569169,\r
+       3207749968, 3202123202, 1055742619, 3206421510, 1043395818, 1045560765, 3204813586, 3174599588,\r
+       3191648088, 3196889873, 1065124996, 1051185645, 3182148773, 1043689821, 3201783983, 3169317391,\r
+       3204793090, 1055533037, 1040704967, 1059595338, 3209061042, 1057857174, 1063516477, 1045874422,\r
+       3199763463, 1058351603, 1052174940, 3201671775, 3160799321, 1053854368, 3194252243, 3199435615,\r
+       1053596156, 1058534374, 3185848025, 1057755884, 1054812578, 1026463577, 1062193386, 3190231070,\r
+       3192464786, 1058207510, 3206762427, 3180558782, 1044327879, 3210666358, 1062212308, 3190414647,\r
+       1061638167, 3198996165, 1045756437, 1060542141, 3187457494, 1056005769, 3204183946, 1068868877,\r
+       3182236342, 1057642759, 1028701599, 3198597677, 3189822298, 1041378314, 3186630506, 3184211749,\r
+       3205934286, 3199340575, 1055091459, 3199478221, 1043589282, 1050020043, 3208720944, 3198347557,\r
+       1040475638, 3180193761, 1056392185, 1047556728, 1040464187, 3178708530, 3194416098, 3186167573,\r
+       3199764429, 1061767525, 1049508819, 3199822345, 1050761978, 3202380967, 1048423013, 3203941417,\r
+       1042890663, 3173075190, 3188549307, 1051543014, 1031232875, 1059550131, 3198399640, 1057842086,\r
+       3189047594, 3161018718, 1041578123, 3191529680, 3199434469, 3204706102, 1067000068, 1046105874,\r
+       3199603324, 1058714795, 3179725955, 1049641286, 3204458804, 1056526646, 3159943836, 1035903365,\r
+       1057902938, 1052501816, 1040821733, 1051947087, 3198050548, 1033812931, 3193353864, 1046162761,\r
+       3208815609, 3201424865, 3195275136, 3189567844, 1025694885, 1062352193, 3183877297, 1050521438,\r
+       1039709845, 1012653270, 3173156688, 3180418977, 3200018144, 3197622468, 1050722700, 1053512945,\r
+       1019288341, 3171266719, 1042513731, 3207605472, 3197440210, 3147667973, 3189200021, 3198635798,\r
+       1036964000, 3190204742, 1037307295, 1033190336, 1036332676, 1025084036, 1021192765, 1030915842,\r
+       1040194619, 3188248351, 3198154744, 3180180114, 3199704554, 3162140458, 1029651309, 1038925927,\r
+       3181787557, 1049063296, 1050192612, 1052879146, 1048153695, 3166952815, 1043792133, 3192848723,\r
+       1044759122, 1028066456, 1042867655, 3187494595, 1047047120, 1049880747, 3181231227, 1050781803,\r
+       1051119827, 1043822831, 1049046018, 1047111309, 1044681983, 1042226334, 1050648239, 1045598685,\r
+       3177851508, 1027204284, 1043297513, 3172106822, 1055301043, 1051393775, 1008159369, 3164521917,\r
+       1039824911, 1047187923, 1047285473, 1052458449, 1049605211, 3192944925, 1051553815, 3196313141,\r
+       3185042726, 1055534164, 3190484912, 1018484877, 3189841920, 3205075232, 1044709206, 3197845920,\r
+       3198204828, 1038037860, 1050748558, 3190191330, 1057381164, 1049822637, 3190173520, 1031031277,\r
+       1022327203, 1043245708, 1045784048, 1043516145, 1052960952, 3176110738, 3181019431, 3194657965,\r
+       1022008404, 1057661246, 3160805713, 1041777195, 3201571475, 1009068927, 1051207682, 3180063245,\r
+       1048073740, 3175078927, 3189935005, 3169210088, 3192719808, 3197890838, 983412725, 1033985109,\r
+       1011120663, 3198775001, 1048586022, 3193846351, 1058438582, 1061218164, 3188421488, 1045721939,\r
+       3190920874, 1037853488, 3163692257, 3176477397, 3204524270, 1052659206, 1041875374, 1043781255,\r
+       1040187743, 1051605692, 1045139088, 1052177642, 1036382346, 3197434262, 1047539199, 3196427176,\r
+       1052455780, 1016487266, 1051917548, 1050109253, 1050201797, 3198165553, 1041928484, 3190196540,\r
+       1056754196, 3197708447, 3181071723, 3189636751, 3197566516, 3191067508, 1035575869, 1055814464,\r
+       1036972368, 3190204000, 1037326716, 1033252529, 1036374695, 1024999163, 1021272292, 1030876104,\r
+       1036314791, 999930268, 3182807746, 1060737588, 1062596335, 1024377559, 3203258146, 3197988963,\r
+       1044227665, 1049767227, 1039572699, 3163365650, 1045375536, 3205326313, 3208138950, 3171055664,\r
+       1066850400, 1053959903, 3204564750, 3195028173, 3190676857, 1058285565, 1060132231, 3170014952,\r
+       1004862446, 1028730575, 3193500325, 3210901694, 1058008593, 1058441232, 1048520187, 1043517108,\r
+       1040337965, 1024949567, 1022740739, 3175408167, 1055466935, 1016021467, 1038627060, 3180607939,\r
+       3179250214, 3190563515, 3197024697, 3192776382, 3194783404, 3198085010, 3204534883, 3198768625,\r
+       3188312402, 1049441242, 1056971877, 1059402906, 1050810636, 1049399428, 1049931095, 1042746845,\r
+       3172509246, 3193925466, 3190729536, 3194263598, 1055386762, 3190222888, 3195107825, 3200289569,\r
+       3199503347, 3193460214, 3201420184, 3202089320, 3195106943, 3196183300, 3197621843, 1029629695,\r
+       3197770611, 3204510032, 1024051482, 1047359908, 1053819451, 3203707054, 3187419183, 1060965472,\r
+       1054174153, 1056886411, 1056998775, 3196762875, 3189076532, 1043171195, 1049917658, 1043711750,\r
+       3210007438, 3205286690, 1050880739, 1048662011, 1043697771, 1048443709, 1040987604, 1040251225,\r
+       3140494461, 3204557446, 3202155174, 1059280506, 1060019825, 3213525597, 3212692650, 3189998064,\r
+       1041444780, 1049373737, 1046614074, 3197826359, 1043452217, 3163555261, 3198892228, 3206222678,\r
+       1065951269, 1062862038, 3180266539, 3196274777, 3195101172, 1045464922, 1055631865, 3192853179,\r
+       3184610605, 3187516929, 1036469911, 1044244315, 1059123690, 3176065736, 3207367110, 1042906451,\r
+       1049358560, 1057113659, 1060214134, 1060350818, 1041548061, 3168687050, 3148449862, 3189704501,\r
+       3199779983, 3165097079, 3161941291, 3173485904, 1035348862, 1031343646, 3195929988, 1032321254,\r
+       3180927275, 1045211130, 1050206878, 1053890535, 1059784215, 1049735381, 3193400199, 3213193357,\r
+       3205997281, 3198154434, 1049929240, 1052953089, 1057249481, 1023410883, 1035540007, 3177987979,\r
+       3188780147, 3196492340, 3191981236, 3188041167, 1034329805, 3164710949, 3192768836, 1049300799,\r
+       3192710118, 3201340727, 3210457565, 3196116140, 1058634862, 1027192091, 1040920900, 1048504782,\r
+       3188203310, 1039961360, 1061216712, 1018174442, 3180304105, 3187722327, 1051539668, 1051348072,\r
+       3188573692, 3203419861, 3197116783, 3201766333, 3195447989, 3177900690, 3200206214, 3202728528,\r
+       1040462502, 1057243216, 1061968861, 1060250938, 3222740859,\r
+};\r
+\r
+uint32_t* get_knMultiWeightsArr_addr(void)\r
+{\r
+       return (uint32_t *)(knMultiWeightsArr);\r
+}\r
+uint32_t get_knMultiWeightsArr_size(void)\r
+{\r
+       return sizeof(knMultiWeightsArr) / sizeof(knMultiWeightsArr[0]);\r
+}\r
+void get_knMultiWeightsArr_version(char* ver, uint8_t len)\r
+{\r
+       memcpy(ver, NET_VERSION, len);\r
+}\r
+#endif //#ifndef Goodix_DSP_EXPORTS\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/algo_params/HR/04_EXCLUSIVE/HRNet_knSceneNetWeights.c b/code/sdk/drivers/peripheral/ppg/gh3x2x/algo_params/HR/04_EXCLUSIVE/HRNet_knSceneNetWeights.c
new file mode 100644 (file)
index 0000000..6e97d61
--- /dev/null
@@ -0,0 +1,346 @@
+#ifndef Goodix_DSP_EXPORTS\r
+#include "goodix_type.h"\r
+#define NET_VERSION "9b33ee"\r
+#define NET_SIZE 2599\r
+const uint32_t knSceneNetWeightsArr[] = {\r
+0, 1065349120, 3926200329, 271596243, 893109729, 1959652631, 2162769258, 3822046397, \r
+236325760, 217054214, 285871367, 535286017, 2363630463, 4260621249, 4042855962, 3590266376, \r
+4196007928, 3821726131, 4244310912, 3909485045, 4010540281, 34939405, 303701794, 556874507, \r
+1686105086, 703733573, 118495524, 4211871509, 150967560, 25206003, 4170775579, 3438870013, \r
+981428020, 3520003022, 3723368670, 4177326813, 351660759, 36755961, 2141561859, 2566803518, \r
+3641374538, 4244655746, 4025156116, 3695148820, 290513053, 652654782, 4041270024, 4157409827, \r
+3775474437, 371454453, 2162424298, 1984423127, 4176935415, 3943111412, 166324709, 3508797426, \r
+2136947756, 347407092, 2967856968, 3925473270, 305463468, 2133369086, 640089819, 1497450496, \r
+2848279633, 93357440, 170411041, 4109503233, 3857115900, 3824311334, 795815389, 2160206660, \r
+885894575, 3994828159, 776864476, 1343942655, 652671791, 254281978, 3987047931, 1264681183, \r
+286006582, 252709117, 80542740, 3164897335, 3554928075, 3122727358, 637708473, 4227395582, \r
+1494532330, 503807869, 374232129, 522130958, 1920957544, 1399873898, 114354990, 967766277, \r
+38561894, 368770782, 3842040095, 4237766674, 2149256419, 453369849, 235925226, 49808890, \r
+3875066854, 905112291, 1551794002, 4149763681, 15186560, 3820884224, 3103262971, 3941332201, \r
+3993896193, 3350495233, 3856568017, 436662512, 234683166, 757088384, 4283412057, 1857699600, \r
+2370968599, 1228484192, 3742971980, 4262733440, 135649261, 601421817, 4177661214, 4278387449, \r
+3825090068, 552803051, 377452376, 873464577, 690678210, 3740861218, 2759856384, 784979596, \r
+688120594, 1313492, 34335485, 99149302, 2161570064, 2515271384, 1853845874, 4277998642, \r
+4246011642, 370080517, 586943755, 4127064830, 1466990338, 119418947, 4161338108, 4277005550, \r
+3806724121, 524123949, 3944625687, 1848171477, 502466356, 3757239739, 3992191360, 775038468, \r
+451737362, 436600590, 3208968272, 1061383775, 1060350458, 1060899932, 1050734041, 1063381109, \r
+1065353216, 1058850046, 1051238313, 1055825603, 1055593230, 1056564540, 1052908325, 1052508809, \r
+1049578968, 1054728404, 1057456913, 1052613031, 1056251806, 1056584816, 1050558972, 1062042073, \r
+1051740326, 1052512807, 1058344650, 1052135343, 1055555467, 1059985087, 1057169430, 1052523481, \r
+1052639302, 1061233682, 1047055879, 1059213027, 4139482269, 104289657, 72634680, 122609534, \r
+4206395649, 159323114, 43699355, 24615339, 2790, 19423441, 4868590, 39329177, \r
+4289108070, 4266086130, 4213908736, 6373274, 112796662, 4136860831, 4026531840, 48698899, \r
+12122929, 55535503, 145643881, 4282652922, 4165090304, 4185185171, 72738430, 142774152, \r
+54879746, 40858001, 4209613012, 54406490, 3220132772, 1072649124, 3219638433, 1081092436, \r
+3900696058, 4113894660, 4142336218, 4073847258, 3978690565, 3523503089, 3807181928, 3775530804, \r
+3212436647, 1064825054, 1065353216, 268435456, 3220856720, 1073373072, 0, 1075623127, \r
+11536767, 3201189669, 1053600407, 1065353216, 4026531840, 3133131475, 985647827, 0, \r
+1064654253, 2155839616, 2139127679, 2139062400, 2155839615, 2155905151, 2155839360, 2139062144, \r
+2155839615, 3205851304, 1058291159, 1044407605, 1062255870, 1062390296, 1065353216, 1046238359, \r
+1034465492, 1058215057, 997977198, 1039131768, 1050105844, 1029513093, 1013773906, 1044441203, \r
+1007908270, 1061061812, 1043175514, 1017547956, 1044356153, 1046475461, 1055269563, 1019129815, \r
+1056292717, 1033124668, 1062798997, 1051378258, 1032073208, 1039482053, 1007979873, 1062074609, \r
+1034695600, 1015646444, 1058979685, 4130629254, 121916297, 4186073219, 149289773, 4201430000, \r
+159531206, 14521749, 26595246, 29803902, 18839528, 24003349, 57898698, 3499341, \r
+4269420547, 4268244981, 14924042, 100286511, 4122359242, 4026531840, 65624229, 21062071, \r
+25067040, 150081220, 1088546, 4155818987, 4186160077, 68368648, 162216574, 4288546393, \r
+40641207, 4208220973, 89665237, 3219435697, 1071952049, 3197698072, 1043705884, 0, \r
+1080937165, 3640125752, 82041384, 472472959, 3894550827, 254093037, 283439151, 3418956856, \r
+842351122, 2290062592, 3630131705, 587265500, 4166508304, 2616985685, 234450682, 50857254, \r
+3223257677, 3216141893, 1068566888, 1065353216, 1059163084, 4122183622, 268435456, 3221868582, \r
+1074384934, 0, 1090308138, 1823917183, 33009, 3201873293, 1054278690, 1058215454, \r
+1065353216, 4086410951, 268435456, 3186394059, 1038910411, 0, 1069994553, 2163925631, \r
+2407497659, 260079851, 1887403783, 2137081215, 2290057096, 2146337019, 327188375, 1216392320, \r
+4152328222, 2133813376, 2143761536, 4068442109, 343899905, 3816783769, 2136367232, 3210594173, \r
+1062996974, 1053298608, 1058156659, 1062985811, 1054604773, 1042726467, 1057376177, 1064693973, \r
+1035562494, 1055107918, 1050023954, 1051486657, 1045036181, 1041503635, 1042741420, 1057864321, \r
+1035953806, 1064115284, 1056309336, 1057588575, 1059381049, 1024013916, 1059866324, 1057230434, \r
+1056093160, 1065353216, 1065217528, 1063056335, 1053646672, 1060855847, 1056557995, 1057174874, \r
+1054640335, 4201650179, 4208218040, 4234717013, 4172660312, 4211220051, 4291327785, 4240571766, \r
+4281550379, 4271273264, 4174951056, 4234839065, 4167081178, 4240296353, 4240329657, 66247014, \r
+4270293694, 185240523, 4026531840, 167683661, 52278866, 4235629254, 4222033675, 4275099245, \r
+4273205509, 528351, 4081088051, 9055641, 4138375245, 4216661442, 49460817, 3835709, \r
+4129544859, 3213891771, 1066408123, 3206456441, 1057673193, 0, 1080477911, 3193762056, \r
+1052035240, 1057038960, 3206883980, 3200718388, 1049260074, 1049472475, 1050915039, 1041474103, \r
+3186637535, 3177184080, 1035231329, 1060320190, 1055541229, 3190520360, 3193230284, 3180087899, \r
+1033293642, 3189003489, 3182305270, 3201325312, 3197611744, 1043351497, 1049522104, 3204078670, \r
+1051853017, 1060596204, 1049446884, 3162007935, 3169657008, 1055445747, 1059265380, 1048910301, \r
+3188666770, 3196921482, 3185251399, 1058547271, 1059907763, 3199410239, 1042115279, 1036645656, \r
+3196646407, 3192873401, 3182641446, 3186024769, 1051165744, 1041562457, 3206606506, 3185661845, \r
+3196116679, 1058380672, 3196021721, 3182151695, 1057750281, 1052117802, 1036154103, 3198629990, \r
+3204392118, 3196887638, 1053919456, 1047833505, 1057854055, 3177282041, 3161141927, 1034908367, \r
+1027755325, 3191696276, 1042398012, 1035754394, 3190897109, 3194966138, 3208023821, 3184053726, \r
+3203824414, 1032187977, 1022617214, 3196251889, 3188569111, 1045931849, 1039659808, 1053350030, \r
+1057071821, 1051203557, 1057183207, 978348088, 3151324892, 3138814303, 986760012, 1003679182, \r
+1003397563, 3147464069, 1003348039, 3146117646, 3154135754, 3147856013, 3147295877, 986788802, \r
+3151610900, 1004868226, 1003765711, 3151217048, 3143126611, 3147069815, 981136455, 997407590, \r
+3151823870, 3151198848, 3147830093, 1046730773, 3209499113, 3181439701, 1047018404, 3183461506, \r
+3184891897, 1026317389, 3187601080, 1038785957, 1048297315, 1051820382, 1058875924, 3191900030, \r
+1038669750, 1051278810, 1042650709, 3185016587, 3190599635, 1019633566, 1051896632, 1054087596, \r
+1042920951, 3203888311, 3206465936, 1048825564, 3188655612, 1048719438, 1065496435, 1058598489, \r
+1048603888, 1057861852, 1055163878, 1058200437, 1063480031, 1064657573, 1067571282, 1040612424, \r
+1040725612, 1044714952, 3172720018, 1055480253, 1029499101, 1018005318, 3151707530, 3153936805, \r
+1034304917, 1001777315, 1057130111, 1059737890, 3186285890, 1055588217, 3203612261, 1063387888, \r
+3124541447, 1055611647, 980392344, 3123646101, 1056318322, 1063258343, 1050287396, 1057104523, \r
+1064348045, 1015855877, 1065380435, 1048909409, 1061839389, 3208167594, 990586583, 986349303, \r
+3212876072, 3206244558, 3173365992, 1065437624, 3201079404, 1049835726, 3210027118, 1054392542, \r
+3183157964, 1049561696, 3117656923, 1005747000, 3204822910, 1061974952, 3187451682, 3192959614, \r
+3208055046, 3151897313, 3174657038, 1040711573, 3181039234, 1047307291, 3114027453, 1003533418, \r
+1048808393, 1067255342, 3172044511, 3196403559, 1048100328, 1047051296, 1064612443, 3199449796, \r
+1064952264, 3208940569, 990991235, 998653716, 3218107707, 1004847290, 3171054413, 1058458727, \r
+1049473782, 3160558069, 1022400592, 1050450981, 1057957819, 3204083191, 1006818287, 3134197492, \r
+3213972702, 1048270098, 3196271230, 3171982955, 1052179212, 3191018603, 1052055348, 1055988046, \r
+1036621335, 3189778935, 3149006121, 3138937285, 1061555974, 3191505101, 3185637949, 1034976472, \r
+3153017793, 1039708570, 1058696508, 1030726472, 1063525715, 3192095385, 3134879948, 986998539, \r
+3196066979, 1065730722, 3195341975, 1055832128, 3183093224, 984634970, 1054709800, 1005016066, \r
+1061864950, 3148050344, 3123498296, 3100640208, 3177925053, 1061672343, 3190228401, 3201078116, \r
+1044350414, 3194574339, 1064802265, 3209634962, 1043290102, 1047474642, 3105515494, 1003485247, \r
+1050427236, 1059084900, 1021202062, 1040861888, 1065370943, 3182776250, 1053077736, 1057107345, \r
+1049459178, 1045847723, 3147083069, 999608428, 1061414610, 3180956450, 1046150032, 1065345593, \r
+3206440522, 1063213502, 3201922934, 1034878552, 1038774341, 1041471781, 3147869726, 3118500098, \r
+3204139110, 1072545296, 1048384262, 1055909558, 1045350499, 1018927576, 3168184396, 1042841437, \r
+1040024651, 1044008357, 1027050936, 1025884195, 1014048514, 1049628585, 1044361590, 1056543557, \r
+1027097340, 3165134239, 1055818175, 1057414891, 3185561769, 3177220180, 3166707486, 1060501832, \r
+1059838769, 1041345096, 1013306091, 1058466425, 1067473452, 1060226715, 1059087715, 1044545711, \r
+1059365239, 1030973306, 1041409242, 1048802221, 3188220262, 1034477636, 3186218960, 3158631413, \r
+1058632326, 3201114249, 1059571001, 3189336476, 1058793270, 1051772803, 1059069198, 1036683285, \r
+3193666043, 1043493895, 3146758934, 1032342850, 3197578869, 1049112010, 1058315808, 3199909370, \r
+1038593924, 3204423883, 3178497059, 1036007367, 3186575426, 3174781718, 3182677299, 1036419675, \r
+1020975393, 1041969806, 1032173348, 3171598733, 3176200028, 1058336747, 1034667566, 1053095756, \r
+1034914079, 3205510705, 3187957850, 1050590055, 3186313081, 1018965418, 1038720930, 3200433739, \r
+1036570165, 1038324677, 1031984839, 1003309628, 1049605530, 3150675880, 3180119548, 3193773744, \r
+1025934407, 3192023144, 3202511043, 1044672851, 3201727092, 1042443648, 3198589850, 3203958364, \r
+3173546221, 1045071294, 1034138694, 1049399475, 1026221554, 1052735232, 974507978, 1042525457, \r
+3181598342, 1042692065, 3188890100, 3166659978, 1038568888, 1034578246, 1027827153, 1042991838, \r
+1060715052, 1051456168, 3182356625, 1062882072, 3165597115, 3167212718, 3171212126, 994603850, \r
+1041902573, 3170180980, 1053666778, 3178180942, 1027727794, 3183422734, 1038511911, 3180331248, \r
+3167338893, 994524845, 1019271555, 3165981015, 3182389366, 3162106233, 1040015834, 3160383592, \r
+3149965619, 1040579986, 1040654761, 1040090413, 3185293357, 1034789368, 1035295009, 3171833175, \r
+1050929290, 1053266663, 1029843648, 1050210969, 1052053661, 1019128387, 3183578218, 3162737603, \r
+1034403399, 1022701910, 1034989209, 3125223823, 3194467852, 1035899609, 3197615660, 1043223576, \r
+1007230301, 1023834645, 3184633633, 3129617837, 1039606952, 1040596021, 1044921563, 1010972243, \r
+3162653046, 3189304774, 1001054397, 3195119334, 3193846610, 1053937561, 1052564034, 1045536226, \r
+1039277866, 1044891805, 1047965117, 1043767260, 3182514829, 3156152014, 3177664571, 3202090290, \r
+1052031488, 3184915907, 1044644936, 1034778168, 1036062644, 1034563129, 3188321762, 3208177852, \r
+1042297524, 3190783218, 1046354119, 1043273085, 3187329171, 3195601569, 1051703003, 3179132866, \r
+3181445452, 1057137525, 1056645143, 1013291686, 1011731936, 1037758547, 1016724466, 3192636262, \r
+3195874100, 3177281845, 1034856059, 3180974890, 3183733431, 1033630592, 3189354179, 3181172977, \r
+3179865943, 1050677521, 1051324660, 3166019095, 1055271988, 3182832564, 1058015607, 1032456792, \r
+1044494917, 3163359702, 1041189582, 1039811555, 3183384852, 1052164962, 3189552146, 1029922792, \r
+1032954175, 1055314221, 3180189196, 3204995072, 3199395158, 3201231907, 3187326619, 3174313492, \r
+1040092643, 3201892099, 1004056674, 1032396073, 1045438954, 1037693584, 1044776916, 3200489807, \r
+3182742698, 3176918997, 1053839756, 3194990196, 3186577895, 3185175476, 1035516946, 1034020067, \r
+3179245388, 3190729401, 1053372041, 3166248413, 3184873399, 3205161583, 1030604806, 3203257962, \r
+1026119186, 3199801716, 1043223402, 1049939807, 1034352061, 3189822000, 3191709483, 3205951953, \r
+1040695586, 3182850156, 1034548642, 1033720417, 3198055775, 3179320658, 1017002352, 3183252454, \r
+3197157083, 3167397193, 3199464593, 1045248948, 3180011980, 3175485260, 3173693450, 3179988708, \r
+1038587741, 1040520420, 1038837424, 3190930868, 1024360956, 3183511551, 3168865732, 1043018234, \r
+3173564042, 1043516326, 1030297533, 3180659699, 1043845534, 1036827377, 3183116521, 1041026377, \r
+3184915700, 3191278167, 1027293993, 1038737296, 1010442326, 3181948046, 1026413375, 1046045055, \r
+1023884880, 1021834302, 3137564944, 3181058973, 992465940, 1027206753, 991827883, 1048410195, \r
+3153705760, 1028892591, 3154895283, 1040219451, 3186337177, 3173992333, 3182050071, 1035994916, \r
+1023484325, 1041586627, 1032539964, 3167968927, 2507162112, 1987414015, 68390, 327968, \r
+3093511936, 4287260543, 1606588159, 1968321536, 2248135895, 4289041248, 4293649093, 4293778116, \r
+14854840, 3976160650, 4292657314, 2608880895, 4287074683, 7828669, 4286543980, 2842781695, \r
+15496561, 2489646977, 4291277963, 4286135603, 706347052, 3924563424, 1868128853, 2795765929, \r
+2110908666, 2788161, 3152471546, 2057009, 947214198, 2410741856, 2113935515, 2816856693, \r
+2204723811, 2576679079, 1643045, 3706270676, 2659677863, 1937309559, 828575579, 2617210230, \r
+573050408, 3640605633, 438632473, 3858311126, 3602706342, 1426072145, 827843187, 2952795560, \r
+490406958, 3422506927, 3802065043, 2785040480, 371267, 2722784946, 3329739892, 2348829871, \r
+2170608895, 733497466, 2092089814, 1382940771, 1695106611, 3603487232, 3854126761, 1566768998, \r
+559488855, 2801757065, 3447814144, 1603387035, 1052012994, 3171604797, 3220480289, 3221354371, \r
+1062159638, 1047420760, 3187858153, 3180397868, 3181901424, 1056454364, 1071772170, 1073161560, \r
+3198677542, 1046099020, 1066342673, 1040573042, 3212391292, 3189425433, 3196845566, 3189338090, \r
+1051815170, 3162090187, 1057842004, 1061633777, 3212186278, 3190163969, 3197321229, 3188741726, \r
+1054439788, 3189361685, 1058207340, 1065147656, 3219381270, 1071780958, 3215585547, 1068014889, \r
+3238140499, 1090656851, 1049730333, 1048840762, 1062510304, 1065353216, 1049380099, 1028785876, \r
+1049221814, 1050574477, 1042784940, 1053938700, 1063563698, 1065261090, 1042197651, 1044053214, \r
+1060438640, 1047050098, 1015430629, 1049667200, 1027318338, 1025981113, 1024993142, 1031444394, \r
+1058051469, 1019843295, 1058245642, 1062266110, 1047513794, 1058729185, 1062136232, 1055689820, \r
+1065353216, 1057098510, 1054323491, 1054233139, 1060149357, 1061852431, 1053570167, 1050017474, \r
+1055899039, 1055984305, 1059208998, 1052637098, 1050160720, 1052837715, 1053836826, 1055816301, \r
+1058545772, 1056278486, 2458822350, 3350903936, 1838198228, 4025063291, 1687708266, 1231056248, \r
+1874028432, 3618417271, 1149808567, 2544084326, 2291249569, 2090239901, 943817342, 725713284, \r
+2744084541, 1938398611, 2188282248, 2947258524, 2290319048, 1836748683, 2139191164, 1428881453, \r
+2694402851, 1365563272, 2662045826, 795116880, 2139260819, 1906095028, 2053924435, 1600812434, \r
+2726476940, 2223340674, 1096115335, 1233808266, 1618436655, 2258671969, 2542636178, 1971355009, \r
+2392946014, 1597192026, 1701533767, 2120570725, 1597984861, 2073135737, 1938258838, 2221823854, \r
+1718184298, 1297035633, 1886815532, 1649082476, 1887469656, 2608945536, 2257946760, 2223470717, \r
+2359003775, 1534750839, 2173921391, 1955561336, 1029395842, 1098986028, 2291823199, 2290512761, \r
+2089452681, 2173731702, 1627416172, 1451394941, 1717918541, 1936350793, 1987871617, 1465677685, \r
+1902674828, 2088665975, 2541712505, 2219730533, 1684152915, 2305190002, 1465879721, 1734441073, \r
+1652727489, 1620608404, 2509662542, 1131125377, 2745605550, 2561906841, 1581879476, 6063771, \r
+2290435858, 2206375326, 2088272004, 2391375470, 2572446300, 2054395310, 2189783932, 2977170011, \r
+2979100547, 2308878258, 2357363609, 1887013790, 2710207084, 1938476436, 1367378840, 1950420540, \r
+1834586947, 3464325513, 2727584410, 2226172340, 2140047754, 3063576725, 1836999074, 2625533777, \r
+2359396503, 2158607540, 2104719508, 2894042768, 2005502366, 2424280200, 2844240809, 2173076668, \r
+3318462854, 2090250683, 2491979669, 3401363866, 2509083527, 2844955555, 1754702742, 2813853660, \r
+3739538091, 2814037417, 1599947389, 2226022552, 1988849036, 2508809041, 2476121481, 2221964677, \r
+2072798564, 2273809013, 2405309313, 1165256283, 2307627620, 2189132693, 2392163714, 2778044303, \r
+1342214263, 1400660066, 2289329239, 2141425499, 2492237691, 2054126219, 1834643098, 1953860228, \r
+2104654710, 1479685705, 1064591451, 1904959851, 2356652370, 2421125535, 356005185, 2845992489, \r
+1621068134, 3885524088, 2306091837, 1936759213, 2171666513, 2998177911, 3133001133, 2119980674, \r
+2139386760, 2442898556, 2208345001, 1734435944, 2627965561, 3419855038, 2322432935, 2041358468, \r
+1836016506, 2155310966, 3013178991, 1680427624, 2677446211, 2324208606, 2288628333, 1498711974, \r
+2641915256, 1701940377, 1665670987, 24869290, 2273739633, 1785290338, 576153737, 1919844255, \r
+1835011072, 1734907314, 1246842198, 1716347215, 1601862000, 2052268622, 1602123092, 2235836234, \r
+2069382474, 2071760780, 1633246047, 2004647799, 1599754574, 1065443688, 2056033867, 1969095014, \r
+2661861051, 538997395, 2053476925, 625840021, 1197623879, 926101089, 2322696304, 3534534307, \r
+2525809585, 639375469, 1847141001, 2274521493, 2273354640, 2861274784, 1647081131, 1905418384, \r
+2090568023, 1315352576, 3114638704, 3619470779, 2877919880, 2443877554, 1280078471, 2643195826, \r
+976697678, 1346991913, 3921181325, 2455951542, 2121689988, 1704627590, 2425723781, 1321517674, \r
+1453310901, 1653641345, 1218745232, 9418404, 1953588295, 2308220297, 1499299984, 2088727658, \r
+1970305932, 2174202236, 2172020843, 2472171386, 2458211965, 1820103836, 2239592079, 2191633817, \r
+2794553210, 1669760613, 1839695737, 1650994705, 1617528694, 2525525880, 1180980338, 1183289721, \r
+1984959770, 930979978, 271474271, 1348078388, 1595892878, 1068947909, 3212388668, 1921869423, \r
+1130721421, 1347305521, 2776336522, 2170707866, 2207158667, 3399109775, 2068007062, 1215797904, \r
+1701807242, 2424736891, 2960622733, 2054652838, 3724083161, 1968128898, 2511109507, 2425654673, \r
+1767810770, 1691348941, 3447730214, 745187466, 676820558, 1986789403, 2301457080, 511431879, \r
+2992971341, 2073793132, 1483839628, 2490917696, 2610261118, 1900828535, 2172018532, 2675477662, \r
+1686796880, 1665359471, 2251722615, 2339348390, 2846132093, 546340499, 2597831034, 2201116748, \r
+2461033633, 1888328321, 2239846516, 1617733760, 2121816396, 2245445492, 1971233594, 1567921029, \r
+4072642931, 2071705791, 3519860617, 2139793805, 2123273590, 2947986324, 1653698962, 3572213882, \r
+1937023174, 1719060839, 3080747389, 1265142167, 2153466467, 2659879573, 2475853453, 3014721630, \r
+2326634118, 2930072983, 1735147870, 2794286714, 1666415188, 1299617665, 1484544319, 2527964518, \r
+3265830728, 2860172234, 4293504845, 2643433160, 2597122987, 1869580168, 2038395994, 2711463291, \r
+1617071794, 2813239174, 2190904467, 1131079061, 2745669502, 1886486658, 2657643412, 2728825994, \r
+2628820626, 3184488521, 2037421185, 2291704992, 2173593481, 2256440745, 1550757556, 1367693390, \r
+1297773910, 2845078360, 4022992853, 2410199245, 2358868062, 1974063235, 1953810043, 2625996383, \r
+2475983262, 3115297690, 2928979074, 1802538902, 2678296948, 4172128978, 2243268044, 2258347688, \r
+1279364781, 961634658, 2222150947, 1588949553, 3266031531, 1449689770, 2592192149, 1786937469, \r
+1887075972, 1584232555, 2106748288, 1298180984, 1229291627, 1820095567, 1379819415, 1836842947, \r
+2155037543, 1919974782, 1970703728, 2020106347, 1495161452, 2139922322, 2070307692, 2137613180, \r
+2220191061, 2408355204, 2356903578, 2494343834, 2574417281, 744983414, 2244994943, 1550492302, \r
+2726788962, 2357160316, 2744289685, 2474674069, 2239529362, 1937790630, 1820942446, 2071354227, \r
+3373198, 1735465793, 1868651919, 2191294580, 2508558486, 1802866828, 2375649404, 1920498810, \r
+2290387582, 2458090632, 2257221004, 2795605637, 2189072766, 2172420753, 1583840135, 557663360, \r
+2169652015, 2676587390, 2088986529, 1721993840, 2056159646, 1854109297, 2894427239, 9660320, \r
+2038861689, 2037667476, 2339007121, 1268080513, 1970685795, 2190046604, 1719441035, 2541783680, \r
+2473886580, 1534620573, 2121224752, 2070881678, 2055570820, 1837005686, 2122158470, 1937019024, \r
+2507764830, 1904629890, 2054981287, 2168986487, 2256505721, 2407300741, 2156506787, 2039641970, \r
+2742380901, 1158767488, 2423216999, 2373805716, 1433639050, 1733654297, 2574994768, 2444465759, \r
+2190186395, 2711132274, 2140177280, 1836026246, 1837533543, 3519856006, 1784841344, 1818194806, \r
+1550822527, 2290839678, 1702654354, 2390792332, 1903034409, 2222076474, 1717264775, 2391381165, \r
+2374203790, 2792583280, 1149082056, 3903025284, 2205965684, 1802028191, 2273987675, 4287406741, \r
+2160126953, 2541908872, 2020765053, 1988194446, 2189526409, 1937407377, 2407633535, 2311298674, \r
+2575402123, 2324472210, 2292343433, 2088527739, 2273869195, 2471455819, 3181752679, 1908663005, \r
+2458681220, 1619621245, 1737504376, 2105193567, 1162692446, 2414569854, 1063287084, 4608330, \r
+1347387761, 1553191308, 2594416286, 2089713532, 1751549050, 2309532282, 2714730610, 2372424375, \r
+2138084495, 2001226258, 2609088692, 1483507345, 1868576866, 2440856712, 2828105872, 439689876, \r
+1926529362, 2460324742, 1431270792, 1818064740, 1197504219, 1953137760, 2675925103, 2577894521, \r
+1922078504, 1582525573, 2323930490, 3314397090, 3537099706, 2123729548, 2475727727, 2812650900, \r
+1738369131, 1802723411, 2039123070, 743210891, 1969907544, 1819239268, 2458349973, 2357956451, \r
+2341577357, 1800929325, 2541780629, 2645939142, 2306242894, 3113585817, 2727309164, 2103013023, \r
+2407102334, 1601079441, 1466302530, 2273141824, 1095068320, 2068197218, 2087466113, 1803061092, \r
+2157224843, 1667462266, 809851536, 2861268839, 2374147491, 241872174, 2203938371, 2222754429, \r
+2223533179, 2374403209, 1584365718, 2237031015, 2221753678, 2744230525, 2493224849, 2572900475, \r
+1619366282, 2156561252, 1989246096, 3953422961, 2272098925, 2173219485, 2728551811, 4289971610, \r
+2427249886, 2356444299, 2139058558, 2357098631, 1548715388, 2122215535, 2155643793, 2461645206, \r
+2171832210, 2206770842, 1954708147, 2173271687, 2425263237, 2541055300, 3048781945, 1622076626, \r
+2138414988, 2036035969, 2382390640, 1435080077, 481603583, 2612121272, 2744343061, 996216831, \r
+8314699, 1448110479, 1450544639, 2149884067, 2181050792, 3352479461, 3785394809, 2693333119, \r
+2496486296, 2516189393, 4252789861, 6706598, 3131702272, 580286851, 1696421120, 2897855870, \r
+682455039, 1111162014, 1672131431, 3011028735, 4283193928, 3312236748, 4123361146, 4280573034, \r
+846365291, 2812774656, 738209275, 4270226251, 2812463871, 3078190743, 4289551092, 2611226781, \r
+2444666914, 2734637445, 3061892095, 3311898357, 1929389520, 3929651292, 2130680345, 800240275, \r
+12878741, 2356844645, 3190366151, 3204174187, 3191011481, 1060928830, 1062032243, 1049047647, \r
+1044322546, 3179781936, 1056550013, 1047798895, 1050718779, 1049051884, 1043992544, 3159620136, \r
+3193945194, 1055487995, 1028097600, 3145675544, 3168356339, 3188391302, 985532152, 991170796, \r
+1036282719, 3187907275, 3195919452, 1030221463, 3183420086, 3173589840, 1036092823, 996181551, \r
+1034616249, 1049149419, 3220830099, 1073218468, 3213150519, 1065598885, 3226332854, 1078849206, \r
+1057733678, 1061102989, 1065003354, 1065353216, 1056193979, 1063442844, 1057487778, 1057393255, \r
+1055505424, 1062808293, 1058960307, 1056210298, 1053757602, 1058003966, 1059051349, 1059218570, \r
+1058833513, 1060324942, 1051878275, 1057043693, 1048375301, 1053298180, 1053861365, 1062008396, \r
+1064745834, 1061646938, 1059689037, 1063926229, 1064638365, 1049503310, 1065038245, 1059666744, \r
+1057827589, 1053475213, 1056505369, 1054303085, 1058973148, 1053483743, 1059696819, 1061595619, \r
+1057826583, 1062365621, 1059217533, 1059527205, 1057114162, 1057069608, 1058617537, 1065353216, \r
+887209215, 3444629369, 9084847, 2589191288, 10913221, 2553269099, 8096928, 2403584369, \r
+912033023, 2171795075, 92369630, 3141118720, 8646638, 2722811481, 11052464, 3609515393, \r
+7375720, 2392758907, 16047498, 3093737075, 1375773577, 2594212147, 4287785609, 2458619056, \r
+2660021328, 4283727937, 9334482, 1486786396, 1992456605, 2541446143, 1621850111, 1798860597, \r
+2469765155, 1862300793, 2220635647, 846023995, 2952848247, 3184154178, 6974632, 776753753, \r
+4287144300, 1621174006, 2676457828, 2342016256, 381499227, 4284250522, 2920440832, 1507774344, \r
+3317279350, 1073724255, 2327297668, 536844153, 3687611792, 1124048486, 1859181421, 570409829, \r
+2633917572, 536840615, 1953934403, 1890164736, 2377611413, 687843958, 3049692265, 1442815324, \r
+3400050297, 3919642810, 2371978880, 268409283, 2751419018, 3129005165, 5479784, 2136832880, \r
+2415885604, 1535939905, 4281575007, 2059775503, 1080244103, 1693026047, 1899691876, 1432672892, \r
+2389671935, 2509335165, 2353659780, 1310365241, 2331990645, 2655415438, 4283095695, 3173625639, \r
+2172292393, 2036677375, 1662802748, 464322385, 2253352827, 2885642402, 2341107331, 4286540634, \r
+1068763616, 1067730203, 1063880779, 1069243601, 1065860993, 1060900256, 1069957279, 1069038927, \r
+3195168814, 1044094210, 3172439723, 3194668214, 1053397182, 3192648212, 3154732296, 1041181218, \r
+3172767696, 3161282903, 1030698840, 3175788050, 1045086942, 3162020767, 3139346954, 1032130943, \r
+3175200976, 3181080400, 1044770518, 3193983710, 1044200105, 3173779270, 3171860950, 3175741806, \r
+3221267438, 1073694028, 3221063149, 1073449697, 3234252641, 1086768993, 1057618170, 1064071000, \r
+1062896705, 1065353216, 1061095083, 1060463329, 1057718463, 1060023667, 1056994293, 1051834080, \r
+1049282472, 1056211677, 1054501069, 1052164575, 1051906779, 1052002716, 1044745490, 1043729691, \r
+1033266056, 1043755183, 1044167931, 1048639168, 1040846581, 1036874921, 1057253687, 1061346117, \r
+1059124227, 1057639245, 1057137350, 1065353216, 1058350448, 1058925239, 1049830378, 1053237344, \r
+1047621264, 1052474039, 1050708596, 1056945912, 1055120302, 1050702037, 1057301740, 1047368166, \r
+1047409228, 1045500642, 1052367381, 1050066520, 1051632232, 1052271691, 1051979388, 1059891473, \r
+3197414305, 3205585635, 3155142669, 1053812688, 1059917835, 3206905995, 1028870766, 1050705079, \r
+3194204358, 3205893456, 3193994920, 3176623806, 1052096052, 1032891260, 3195311586, 1039209713, \r
+1043998357, 3194582756, 1026709822, 3189769637, 1036140544, 1055645189, 1052630179, 3194947048, \r
+3207852902, 1057224393, 1049819140, 1061374605, 1063077435, 1043312415, 3190044736, 3212134193, \r
+3208489681, 1064011670, 3198067153, 1070256219, 1060099430, 1051254333, 3154773168, 3189073103, \r
+1061203409, 1058122407, 1027680248, 3199516337, 3169218626, 3198484466, 1008785198, 1051208731, \r
+3199276615, 3206277265, 3191311361, 3159964284, 1049470075, 1049703679, 1066115900, 1043869792, \r
+1047699558, 1054490916, 3188645546, 1046821902, 1050129027, 3209736510, 3212641801, 1033737270, \r
+1050502833, 1061173445, 1042613255, 3199804038, 1052011337, 1062415236, 3157602435, 3187003461, \r
+3214017963, 3185747618, 3209738839, 3144589141, 1031520449, 3188454975, 3192011861, 3197246046, \r
+3211665492, 3179299129, 3195776846, 3201651526, 3204458594, 3171818070, 1040431032, 1042904625, \r
+1067889708, 1046123540, 1045250562, 3192821524, 1041142678, 3183677522, 1044065472, 1057652801, \r
+996235264, 3198590355, 3174050368, 1038577743, 1044426929, 1045438991, 1050252630, 3205039795, \r
+1058613320, 1053072288, 3190541936, 1017565297, 3201528487, 3207993510, 3208465786, 1047910729, \r
+3209037301, 3212630816, 3157979943, 1044378579, 3177770624, 3198433253, 1033808381, 3207231542, \r
+1042123507, 1062746140, 3201678915, 1049357744, 3191828460, 3188269300, 3198546349, 3199256998, \r
+3214004895, 1032328729, 3195503113, 3206636085, 3209687326, 3184752020, 1061469808, 3206215885, \r
+1039407417, 3198160511, 1032803992, 3188893081, 1057342654, 3189249682, 3202737148, 1038729710, \r
+3156678940, 3203504879, 3202102384, 1068925260, 1038184758, 3209728340, 3183210171, 3198081869, \r
+1060420537, 1057480607, 1042102789, 3202442018, 1051346180, 1035828748, 3201507967, 3200701163, \r
+3198226702, 1034361728, 1025227541, 1061722575, 1040385598, 3207829092, 1049593075, 3185075518, \r
+1016670685, 1030826757, 1038359528, 976357283, 3175577336, 1052998856, 1029327036, 1042402558, \r
+1032145437, 3176677987, 3180829792, 3171742894, 3199538855, 3185150199, 1024821157, 3176920177, \r
+1035752371, 3190405582, 1040880561, 3233930067, 3208469087, 3220267760, 3204571435, 3226789573, \r
+3222731018, 3213491152, 3231418840, 3222754743, 3225352381, 3220322280, 3224985736, 3211484253, \r
+3223008667, 3210256105, 3208076663, 3220989209, 3229621526, 3229632256, 3214073651, 3229782556, \r
+3229011897, 3239213664, 3205948683, 3233715292, 3232827061, 3196750697, 3233999911, 3231125681, \r
+1078060503, 3234545130, 3236409052, 3211777626, 3233292869, 3228805834, 3231731137, 3234284960, \r
+3236889000, 3230058136, 3232053837, 1052777042, 3231033461, 3216748795, 1073983101, 3210966371, \r
+3225711830, 3230932593, 3232484890, 1064952370, 3219164616, 3231724564, 3224618581, 3232465456, \r
+3219386194, 1062253091, 3230856846, 3225765610, 3230300667, 3236015494, 3216012069, 3230294083, \r
+3232288153, 3233338124, 3229419730, 3234156353, 3219608058, 3230018867, 3229647020, 3219888809, \r
+3232479553, 3216571560, 3230416338, 3230398717, 3236168394, 3206954087, 3229377796, 1049320168, \r
+3235385074, 1074103904, 3238057385, 3211356830, 3235678342, 1056922334, 3233246934, 3232249843, \r
+3236584557, 3229623455, 3236153244, 3208871678, 3238039613, 3237488094, 3232439487, 3233017408, \r
+3221249102, 3238970903, 3235243394, 3242633199, 3201823237, 3231874565, 1026706913, 3242476938, \r
+3228977949, 3220282064, 3237881276, 3217499471, 3223686667, 3229618674, 3230288171, 1077033414, \r
+3196479941, 3238016124, 3229649111, 3223418074, 3233010338, 3227545673, 3236524096, 3237138929, \r
+3241935407, 3234768942, 3234102478, 3226101036, 3239362354, 3222399867, 3227125893, 3236008834, \r
+3225288469, 3215745622, 3231617447, 3226724178, 3234014501, 3236149892, 3232519420, 3234127689, \r
+3232150348, 3234024963, 3235540406, 3238151307, 3231553718, 3232181697, 3239911153, 1075698749, \r
+3246429198, 3239633625, 3233558452, 3210283873, 3244095632, 3225096481, 3220536850, 3238657929, \r
+3234566074, 3231313286, 3235055625, 3204462008, 3238079123, 3216272271, 3234927099, 3234556219, \r
+3237876030, 3222100092, 3227347945, 3221381088, 3231218622, 3241977856, 3237819374, 3231575739, \r
+3212559748, 3237514336, 3217903397, 3233862277, 3208478765, 3220258988, 3204572194, 3226792494, \r
+3222726227, 3213511500, 3231406489, 3222696437, 3225341927, 3220246646, 3224984379, 3211495868, \r
+3223003847, 3210255075, 3207747543, 3220944181, 3229615506, 3229633228, 3213950844, 3229782551, \r
+3223819742, 3241562237, 3232246113, 3234566261, 3234226527, 3226790660, 3234661209, 3223108197, \r
+3229708843, 3204147618, 1074209593, 3236753320, 3239035502, 3222488513, 3230073223, 3236264112, \r
+1080534471, 3220298795, 3232196115, 3232582338, 3227596057, 3247302919, 3217359652, 3219392904, \r
+3218730871, 3227798085, 3224638173, 3225094795, 3224694615, 3247310830, 3217471642, \r
+};\r
+\r
+//scene_reg\r
+uint32_t* get_knSceneNetWeightsArr_addr(void)\r
+{\r
+    return (uint32_t *)(knSceneNetWeightsArr);\r
+}\r
+uint32_t get_knSceneNetWeightsArr_size(void)\r
+{\r
+    return sizeof(knSceneNetWeightsArr) / sizeof(knSceneNetWeightsArr[0]);\r
+}\r
+void get_knSceneNetWeightsArr_version(char* ver, uint8_t len)\r
+{\r
+    memcpy(ver, NET_VERSION, len);\r
+}\r
+#endif //#ifndef Goodix_DSP_EXPORTS\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/algo_params/HR/04_EXCLUSIVE/HRNet_knSceneSwitchWeights.c b/code/sdk/drivers/peripheral/ppg/gh3x2x/algo_params/HR/04_EXCLUSIVE/HRNet_knSceneSwitchWeights.c
new file mode 100644 (file)
index 0000000..94247ce
--- /dev/null
@@ -0,0 +1,764 @@
+#ifndef Goodix_DSP_EXPORTS\r
+#include "goodix_type.h"\r
+#define NET_VERSION " "\r
+#define NET_SIZE 5951\r
+const uint32_t knSceneSwitchWeightsArr[] = {\r
+       2, 6, 2929173119, 1838977409, 2206830696, 2103752849, 2457310537, 1515215977,\r
+       2811811196, 2237056382, 1684371076, 2257486694, 1731950425, 2426440230, 1922012297, 2691137378,\r
+       2116849796, 2320317042, 2315299217, 1133804943, 2789563011, 3129909130, 2291646890, 2421136241,\r
+       1917667007, 1787194713, 2473625453, 2759940428, 1168285044, 1135565855, 2491136671, 2677432771,\r
+       1600222125, 2908711109, 1753191550, 2308535659, 2304015303, 1858966595, 2626663869, 2536150678,\r
+       2271393926, 2122270784, 2072672922, 2912643770, 2207750822, 2374206101, 2142413227, 1652777302,\r
+       2403123067, 1750859876, 1250716845, 2389656433, 2956992829, 3451291010, 1227459686, 2846062271,\r
+       1553077107, 1169005976, 1707538100, 1702293897, 2997659751, 2914751191, 3512102510, 3082592332,\r
+       3047579197, 2102614633, 2610775895, 2438480755, 2743660658, 2358274730, 2721143349, 1837780053,\r
+       9696970, 2270656948, 2940303176, 1418694317, 2674614625, 2843697799, 1820619400, 1784382077,\r
+       1839299466, 1819182173, 2039189132, 2005432681, 1534824058, 1886486669, 2105055391, 1258321795,\r
+       2943514991, 1951300720, 2071037531, 2055115645, 2290987398, 2121905297, 1501324447, 2156953237,\r
+       2273996610, 2290653827, 2208609694, 2425532853, 2475719824, 2155894401, 1853373013, 2337497467,\r
+       2272421009, 3359804338, 2624281202, 1817943168, 2974973149, 2528034751, 1467266153, 2457566128,\r
+       2470275222, 2410068627, 1179751543, 1618763660, 1468494694, 2826015860, 2315281967, 3030429797,\r
+       2830015388, 2573825175, 1990102879, 2474352276, 2306631019, 1635954835, 2624104292, 2934578310,\r
+       2006760618, 609127264, 2339743671, 1148280981, 1803122244, 2784999553, 1565943933, 1766824090,\r
+       2843704205, 2339758502, 2748485310, 1888973198, 2120696452, 1162177393, 2842654573, 2761192574,\r
+       2712115357, 3208816482, 1786732764, 1051812727, 3090122108, 3038604643, 1739225717, 3025501260,\r
+       1350456491, 1975614826, 372930669, 2258271481, 1500671608, 2527365243, 2307764816, 2930620603,\r
+       3041802189, 2653853545, 1145020029, 2192272945, 541154990, 2070241896, 1982433684, 3243464851,\r
+       946763520, 2678805562, 3045883789, 1333687096, 2007595915, 2711389598, 1531139496, 2912728459,\r
+       2858667862, 1362828916, 1366854963, 2351409232, 2306179944, 2221586808, 2138858900, 2274721654,\r
+       1266191722, 2141955476, 2170053059, 1788320861, 3163112504, 1245577363, 2288214873, 2004125561,\r
+       2504690786, 2490341304, 278495397, 2489885790, 2844348498, 949059976, 2573567327, 2256042360,\r
+       1335192746, 2423020656, 1936483621, 2361493876, 2475073967, 1942471800, 1586143536, 3142018850,\r
+       3566846553, 1186178449, 2203276997, 2170330988, 1128677187, 2358486098, 1550158207, 1952730980,\r
+       948990804, 2289013878, 1448315960, 1168286320, 2674570667, 2842976768, 1485336194, 2370867344,\r
+       2391677567, 1568901719, 2440349039, 3452645286, 392664472, 2931002931, 1550846128, 661558870,\r
+       1212751201, 3748116891, 2270196051, 2523095651, 1751891228, 1132484235, 2072018310, 2553417158,\r
+       1721520810, 2358999076, 10572182, 3032451990, 3061164215, 2407291224, 965103502, 1735949573,\r
+       2185469818, 1888469842, 2272686183, 2071613829, 1850619750, 2324140449, 3007807610, 1786738284,\r
+       1667332900, 2596436630, 2523034994, 2073476244, 1216455786, 2165847946, 1028895098, 2407167352,\r
+       1314945706, 1955089497, 2304015745, 2356700253, 1560286606, 1720363894, 2158065815, 1890802490,\r
+       1233608539, 2493243073, 2221374897, 2005631101, 2222761339, 2777037470, 2717892476, 2557578149,\r
+       3789783463, 1250520293, 2372555389, 2747370609, 1669221213, 2361956975, 2259897940, 2246042254,\r
+       1804499063, 4047128143, 1199340374, 2358861929, 1900433261, 1786290541, 2458991971, 2440209803,\r
+       2743454576, 1652926826, 2019778713, 3502998667, 1853122957, 2290212728, 1518738738, 2138670777,\r
+       2852158332, 2274075070, 1918847372, 1439535972, 2964363412, 1804636589, 1558744992, 1975608158,\r
+       2669173353, 2222636913, 1427677300, 1987343739, 2676190090, 2574549672, 2653183384, 1536062860,\r
+       2088803748, 1180633396, 2038582891, 2424690604, 2758243275, 2607643482, 2089319556, 1854900359,\r
+       2472701832, 1601081985, 2002235005, 2220721549, 2321789566, 1383829125, 2235341714, 2642715258,\r
+       2345514927, 1654099391, 2962459996, 1687763031, 1901820250, 2020376930, 2346215054, 1187401483,\r
+       1469413988, 2490789692, 2474273173, 2743955335, 2291432448, 1970830139, 1837083484, 2372882803,\r
+       2342563467, 2645995373, 2525518540, 1804584337, 997421926, 2674675300, 1989384618, 2021305734,\r
+       2541523841, 2428283242, 2073142941, 1756309294, 1066951283, 2069520696, 2372115811, 3128897111,\r
+       1433645477, 2039980621, 2256565896, 2071611904, 814651272, 2874976134, 2591902094, 1601868453,\r
+       2490820716, 2172614300, 2339937956, 2608429473, 1738439288, 2136701587, 4068242599, 1619088896,\r
+       2322837587, 2488489099, 2141545309, 2844622770, 1401002098, 1468291130, 1835621482, 1599768193,\r
+       2223218824, 2454801792, 2776984735, 2290651298, 2254331498, 1401002379, 2121304730, 2792449453,\r
+       2122676335, 2206775421, 2779892969, 2826012559, 1696811145, 3835204515, 2071553424, 2540935569,\r
+       3094847855, 2156951981, 1988610638, 2662177612, 1318896276, 2627765125, 1713137972, 1532657264,\r
+       2141936010, 2475786123, 3214126122, 2074443962, 2926531248, 3300821641, 1135427945, 2711911545,\r
+       2305127536, 1721528456, 2758344540, 2477033777, 2611259816, 1765704789, 3048701836, 2725813355,\r
+       2342094500, 1904316055, 1636747653, 1754617463, 2544413612, 3036688223, 1871497903, 2628426880,\r
+       1566207360, 1768463433, 2228366895, 2586124633, 2392405374, 2307408533, 2105376106, 1904566905,\r
+       2201702534, 2306499397, 2844229973, 2356085109, 2188490919, 1755087241, 1956945278, 1049119448,\r
+       2087018108, 2744098921, 2189852829, 2640937853, 1933414995, 1429778806, 1058977452, 1638320038,\r
+       1921610088, 1900834410, 2793513869, 2390922113, 1207984991, 2103195722, 2405398108, 1986167965,\r
+       2053989031, 2354201694, 1517784035, 1954110825, 2105691012, 2373885034, 2256965742, 1836153200,\r
+       2157362798, 1701086829, 1264100444, 2557767776, 2140515438, 2674626707, 2320659075, 654860923,\r
+       2826400633, 1620082281, 1785100169, 1367312264, 2221833324, 2013277063, 814709366, 2137684894,\r
+       1922977352, 1837805161, 2257289870, 2053076920, 2004969090, 2205762685, 3373354636, 2323416255,\r
+       410482607, 2177291424, 271548035, 4053735844, 3182136664, 2006419830, 4233117153, 2763427961,\r
+       3578834903, 2514592341, 2739637036, 2068400012, 788556140, 2843767952, 2037624857, 2392946560,\r
+       3415315388, 3722004362, 1958335131, 2946954675, 2085530001, 1403155834, 3125784902, 1646446159,\r
+       2594022803, 2635162726, 2103619536, 2407932079, 2426200503, 2289273243, 3145026163, 442806623,\r
+       2205395528, 527197888, 2357091153, 830234389, 2485927568, 1163766567, 2271579251, 1996516454,\r
+       2088921749, 2020895615, 2708694597, 2189387403, 2189136512, 2068982190, 2944820626, 2155830912,\r
+       4285626383, 2793108156, 815409957, 1353497483, 1268289936, 3431046443, 1707973281, 2944894780,\r
+       2486200427, 2830395026, 2160628818, 2091354686, 1940565366, 1437296471, 274818939, 2474408510,\r
+       985983158, 2256591226, 2442488785, 1818400633, 2156778201, 2487392105, 1554755226, 3165042038,\r
+       2490749548, 2695976020, 2628229315, 3243543718, 1651289478, 1718702676, 2676672417, 2695798639,\r
+       2695082124, 2530298792, 2177214368, 2019596408, 2979463030, 962546513, 2019325847, 1934453618,\r
+       1917084239, 1529964869, 930901667, 2136571574, 1770671428, 2055175043, 2525011334, 1464556633,\r
+       326396792, 2155924864, 2405586716, 2140115371, 1647297670, 2512911781, 1768377429, 1349225145,\r
+       3348926321, 2055960918, 1586919744, 2609860757, 2302899553, 1837556355, 2183499328, 1733527375,\r
+       1566991762, 2152678528, 4105796210, 1552390077, 2494923950, 2825874309, 714304391, 2290273023,\r
+       1883476859, 3232470128, 2390203250, 2326504309, 2913560964, 3040132976, 2909629323, 1686661763,\r
+       1392538271, 2459083118, 2473103993, 1535148709, 2231268508, 2322224726, 2087285328, 1085707919,\r
+       2123005842, 1568778091, 1889428351, 1864195470, 1753656158, 1888450203, 1999782841, 1535631515,\r
+       2103671193, 2438038873, 2221885765, 2039038855, 2743507293, 2440988557, 2386070620, 1550366848,\r
+       1938586218, 2562302838, 2188612223, 2121311634, 1685230219, 2426887507, 1180914827, 2021035369,\r
+       1000176953, 1971357825, 2357685901, 1409301652, 1650093895, 2290830435, 2155245711, 2118536556,\r
+       1971004513, 2065858453, 2256555065, 2341039474, 2155714176, 4176781174, 2575414432, 2272880553,\r
+       2509347227, 1869177195, 2221046887, 3214576792, 2408541837, 2725412981, 2305724758, 2086634363,\r
+       2055841425, 4290232235, 1416008836, 2289529472, 1938190231, 2440592985, 2441766517, 2475987335,\r
+       2221374849, 2257158273, 2254011813, 2275971681, 2777317236, 2323149942, 1907337936, 2123864688,\r
+       1216778897, 3515395216, 2643307825, 3264070045, 3350355600, 1818733858, 1738256501, 2169739416,\r
+       2877332877, 2088923797, 2857806461, 2450622636, 1902222950, 2238949251, 2638727554, 2962320025,\r
+       2103605605, 2103902074, 1987666788, 2175198606, 1934978213, 2239519634, 2189324926, 270805370,\r
+       2238333977, 2153678184, 3274671464, 2966259609, 1890743949, 1351204661, 1452771695, 2025881188,\r
+       2576446241, 1939964065, 2072348470, 1903890317, 2290252338, 2291302230, 2544993715, 2156505233,\r
+       2324643203, 2232638015, 3382022529, 1871511503, 2340646729, 1949988004, 2139705721, 2373156211,\r
+       2288611221, 1537125730, 2946397285, 2287631726, 62622365, 1953266867, 2881379660, 1415365293,\r
+       3079505314, 2149804512, 2490795153, 2459341442, 2657782605, 1773296300, 2726590567, 2186191028,\r
+       2316730491, 1971024260, 2135061913, 1783266686, 1652915045, 2287574177, 1415372432, 2675535994,\r
+       2256600954, 1868916565, 2678291592, 1371431024, 1399434143, 1303832716, 3211380921, 2407298118,\r
+       1584886347, 2117828476, 1972789649, 2444928949, 1183148650, 3100153705, 2272169607, 1132974690,\r
+       2457169070, 2547108531, 2289090977, 1937069195, 1754573664, 2742712914, 2225570459, 1990955377,\r
+       2760817561, 2122776449, 2476442472, 1939116451, 3113838170, 2160820152, 2624421016, 1853850078,\r
+       2056612435, 2220200629, 2559404210, 2022140546, 2021026170, 3179064526, 2826133099, 1683975602,\r
+       2659287692, 2085183860, 2053795102, 1887730573, 2324786809, 2374661198, 1769884254, 2044651519,\r
+       1687596462, 2139515000, 2156034688, 2039170467, 2204082554, 2993513862, 2473566324, 1903528339,\r
+       1584803137, 2823333886, 2588779699, 1473225124, 2225112217, 2560403788, 1619149648, 1792193899,\r
+       2587784703, 2893972592, 2224396147, 2866377543, 2911260258, 2172428186, 1621791873, 3263733129,\r
+       2146604653, 2339975514, 2491437426, 2189053311, 3264968003, 3284167563, 1720358251, 1668654720,\r
+       1870578566, 1521122694, 1737520270, 1820564713, 3527514761, 2326367124, 1397533812, 2088480908,\r
+       2175778410, 2121497404, 2754982512, 1719810048, 2056027220, 2843697348, 2004365430, 1988928326,\r
+       2188874357, 2209792995, 2675866002, 2995433177, 2071822981, 3283877707, 2510407125, 2137948505,\r
+       2881005374, 2124920218, 3368983219, 2225646503, 2341832517, 2457172586, 2457916064, 1919671980,\r
+       2256328063, 3355415160, 1520653527, 2438178401, 1901940516, 1160752523, 2693838965, 2022851950,\r
+       1954642100, 2524151917, 2084212097, 1751106459, 2189335966, 2105490051, 2405741942, 2478013574,\r
+       2019658120, 2155253880, 2040113261, 2258466816, 2862326259, 2321979988, 1741136190, 2222890922,\r
+       2309535380, 2357299069, 1247575945, 1387692958, 1119054220, 2336912979, 1904388524, 1871090277,\r
+       2370858880, 1634765999, 2358293387, 2217375863, 3028961942, 2877011832, 2255902841, 3434778781,\r
+       3234047152, 2001579927, 2842686101, 2010308076, 2594139980, 1805539897, 2037742772, 1775526285,\r
+       2181035467, 2883713433, 2592090453, 3262658840, 2509529259, 917779526, 1668905595, 1437635450,\r
+       1970385758, 2139725192, 2219798496, 981447079, 1910814093, 2972753272, 2356050752, 2106443906,\r
+       3449516411, 1701931387, 2259386755, 1467187090, 1854169716, 1426088092, 1938390873, 2725937289,\r
+       2259122063, 2406702458, 3483523942, 2240307842, 1652185475, 2089907855, 2244107649, 2056153946,\r
+       2408143209, 2138339233, 2124648328, 2121697147, 1451714952, 2107086279, 1886947939, 2037939321,\r
+       2189482622, 2238876360, 2389601432, 2560661691, 2386199341, 2496691807, 1936691620, 2322828150,\r
+       2022538644, 2141294210, 2197786527, 2429384842, 2357680530, 1903449681, 2424469449, 2428285590,\r
+       2457693300, 3035881595, 2743701870, 2356509327, 1789430639, 2760813701, 2472640634, 2716968572,\r
+       2911866273, 2339480181, 2753904211, 1200573826, 1669466980, 4104816296, 3829450374, 2474567533,\r
+       2310627481, 3929361297, 2643308292, 2374078345, 1092972386, 1333625525, 4287460488, 2453317477,\r
+       1318869148, 1687186352, 2423549504, 2473776287, 1735886968, 1805569422, 2239202409, 2261820538,\r
+       1419104639, 2708629186, 2022022280, 1901775796, 3936464775, 2610082245, 1685165173, 1855671463,\r
+       2363450972, 2292867121, 2793765283, 2221241502, 2074438024, 3017567875, 1938380421, 1302505320,\r
+       2154935178, 2340977545, 2169530747, 2189435824, 1854368887, 2305459633, 1399859099, 1835943228,\r
+       2066236308, 2388797302, 2928318589, 2189426558, 2648079754, 2221257635, 2091233407, 3312616084,\r
+       2190050963, 1070887808, 3402222828, 1668251003, 2555992723, 1968613809, 2475540407, 2036821413,\r
+       3833643332, 2692526956, 2540392858, 1701214051, 2425133954, 2808964472, 1566411846, 894993365,\r
+       2474803019, 2164283465, 3483600234, 2842972037, 1955556493, 1796894343, 1889890635, 2745592477,\r
+       3335611812, 540644488, 2444731289, 2744417334, 1537769809, 2342280333, 2017549672, 1935199436,\r
+       2391115934, 4285823180, 2184922823, 2276820881, 2257166246, 1334345293, 1769847006, 2174136189,\r
+       2492900767, 1903238228, 2050843791, 945793683, 1518430867, 2122237058, 2863636879, 2997731723,\r
+       2710401390, 2474670986, 2122749900, 3992938639, 2369943330, 1983217008, 2874570398, 2256710700,\r
+       1854452362, 2575998104, 1599103593, 1754380443, 2322755708, 1951559047, 1299753551, 1182950994,\r
+       2036236433, 1332047798, 1349215586, 2152226195, 2934272331, 2710281886, 2172675456, 1700220210,\r
+       1470264426, 194800987, 2677457347, 3294732615, 1077874768, 3062012325, 3326583433, 2485426772,\r
+       2206157629, 2782693215, 1502675095, 3638920855, 1557537171, 2856888687, 2239973518, 1768320821,\r
+       3079499620, 2427552344, 2826329195, 2844491408, 2252572940, 3179690850, 2157675171, 2306162807,\r
+       2058983216, 1602406008, 2755877702, 2572064174, 2457299885, 1786673000, 3196285740, 2039396789,\r
+       2002608541, 2310042707, 795224102, 2944959595, 1419311492, 1453696403, 2255328863, 2396149439,\r
+       3679864392, 1586634169, 2154595511, 2309589363, 1115776930, 2372764110, 2020819968, 2660183898,\r
+       2323340918, 2625113404, 2762098802, 513348468, 1636329638, 710208210, 2415853395, 1550674436,\r
+       2771155351, 1363965503, 2576821608, 1332711806, 1519745685, 1307989054, 492222066, 3795219508,\r
+       1834843326, 1940960424, 3212421242, 1784971181, 2306844279, 1399153806, 2356050860, 1489924414,\r
+       1099070630, 2139420545, 3044561826, 2358734252, 1579916352, 2440333444, 680162428, 1687788686,\r
+       2710820685, 1233815665, 1232252415, 2475128954, 1386587750, 1955030392, 2004818052, 1515692948,\r
+       2575146413, 1952090040, 2340922727, 2491906662, 2539413905, 2084587175, 1820760223, 2149281189,\r
+       2226153546, 2023652200, 2339749749, 3129765995, 2055705195, 1100109750, 1617734049, 2879222971,\r
+       4135739728, 2801838633, 2007263669, 3155586924, 2431678327, 2259382107, 2543210092, 1302437761,\r
+       1736219460, 2069658266, 2139526009, 1487251072, 2021826232, 2054063237, 1721598605, 1299541619,\r
+       2189579661, 2223914838, 728847532, 2155429504, 1537107598, 1904252260, 2052886131, 3350619815,\r
+       2924428894, 2358099802, 2638445406, 3228459917, 3911013, 2139321704, 2268104119, 2909759605,\r
+       3313733955, 2040434822, 663907771, 1770155936, 2524036683, 1584938852, 2119329636, 1602266262,\r
+       1754692488, 2126656637, 1383627884, 1686654737, 2172161919, 3616312752, 1703459956, 2571325324,\r
+       3211767232, 1532912326, 1580489324, 4287076230, 2424544333, 381448280, 2476910698, 2627301500,\r
+       1485779492, 1220322946, 1490429392, 816791163, 2624342634, 2674952519, 3550705461, 1948935820,\r
+       2392356953, 1484277402, 2589045986, 1398899784, 3581638508, 2340020597, 1368153288, 2664075896,\r
+       1009983297, 2644342659, 1464985039, 2376269173, 1784444219, 2571225442, 3422586409, 2392817262,\r
+       2155527385, 2995088516, 2289934775, 1838760335, 2705225582, 2542049740, 2216071291, 1654110542,\r
+       2052301438, 2206625092, 644637791, 2138203755, 1403547527, 1956337723, 2256205946, 2645519773,\r
+       3147795548, 2254075785, 984268661, 2422720965, 2449439908, 1535870048, 3343681457, 1675247491,\r
+       2136897885, 1523692905, 2139718284, 1718785884, 2309131920, 2359066221, 2005368974, 2847651686,\r
+       2424535658, 2255590538, 1986689094, 1635669870, 2342087042, 2294066286, 1685298088, 2206050685,\r
+       3311175060, 2307034833, 677625213, 2076808341, 3196086079, 1824959403, 2093537004, 3517291361,\r
+       1344711038, 2521810136, 1516456342, 863544962, 1590987663, 3749859671, 1603654600, 1633122116,\r
+       2151696553, 3364576933, 2474267041, 1215655267, 2844026696, 1869977764, 3047650272, 4288770983,\r
+       2256442491, 412264870, 2271636141, 1939835214, 2960701061, 1350665190, 3419510196, 1144917892,\r
+       2376497226, 2323729355, 2353026417, 1618386079, 1720085356, 2219745865, 1368614593, 2491988879,\r
+       2311696113, 607077284, 2542112879, 2058017961, 2439337840, 2272225154, 1990173092, 730526719,\r
+       2139467663, 2138859905, 2275570575, 2357498728, 1710132586, 679844234, 2460257626, 2871110035,\r
+       3585892628, 2424536176, 3424628820, 1537567311, 2697543795, 2105566640, 1658488437, 2092613963,\r
+       1537909145, 1902545347, 2946655712, 1449424803, 2205255324, 2371049359, 1903255393, 2253147791,\r
+       1835222604, 1385125996, 2072969093, 2256042904, 1938852000, 2408480611, 175203439, 1599577701,\r
+       2024510108, 1499099001, 1803917919, 2054913434, 2003187355, 1900041847, 2791415959, 9271191,\r
+       1367360081, 2593300372, 1802597000, 1552314785, 1080919184, 1672051092, 1972203898, 2288537762,\r
+       1900251806, 1166378388, 2725730636, 1804571029, 2449801373, 1150781321, 3553131637, 2444259721,\r
+       56963042, 3576784537, 845635803, 1318812833, 2239263933, 3160969462, 1516615809, 1603625561,\r
+       2256618061, 371767114, 1166711955, 2254795639, 2884854126, 1955623819, 2172803524, 2645971323,\r
+       1953704848, 1805157761, 3165829788, 1804904576, 2322708342, 1727170995, 1888459875, 2485695140,\r
+       2354635458, 1549486548, 2446966488, 1582995749, 1986960745, 2861465211, 2593217379, 2573308842,\r
+       2172820842, 9796214, 845641398, 3268250554, 2170516112, 2152295043, 2359585126, 2277937542,\r
+       2241960563, 560809801, 1898483639, 3181138819, 1853319779, 2223142780, 2678429011, 1940164265,\r
+       2083538542, 1131131237, 2897859382, 1184610745, 3047130237, 1817737336, 1334468735, 1937334598,\r
+       2728286632, 2458944168, 1437812584, 1518757744, 2123006847, 2087352956, 2374680575, 2021826955,\r
+       2576976275, 1970296923, 3013037673, 2659216511, 2711056772, 2257294230, 2390294385, 3047373682,\r
+       1267760239, 1653249434, 3501064103, 3970318483, 1104311728, 2194834343, 3569177174, 2040088955,\r
+       2412672574, 3452145596, 664830584, 2464898939, 3982114132, 2006269670, 2304551526, 1713664377,\r
+       4186482595, 2623772469, 1298315218, 1086165060, 2581239939, 2906678398, 1347781749, 2557443177,\r
+       2122343060, 2308076659, 1734447748, 2893124744, 2004057930, 2374345341, 2222095231, 2172750983,\r
+       2372702849, 2239791483, 1954452079, 2591524972, 2492229759, 2356965771, 1738569592, 2223340654,\r
+       1855095296, 1921738112, 2156163420, 2188675418, 2340445312, 2157020049, 2172359038, 2391311481,\r
+       2171937407, 2425048762, 2744868968, 1883860338, 2205190487, 2643156796, 2507576213, 2036968585,\r
+       1752070800, 1467510860, 2063567704, 3032374595, 2525580137, 1326929081, 2571601489, 2155884918,\r
+       2442042955, 3047845154, 1751589580, 2270334570, 2273548077, 932465278, 2160752553, 1919036507,\r
+       2307298942, 2206185341, 2136167814, 2124574866, 1817672317, 3097006959, 3208087126, 1474411564,\r
+       2372629145, 2505998971, 1593815124, 2321454668, 1716490880, 2540273062, 2995431278, 2792376481,\r
+       2224655252, 2005627541, 2677583531, 1452050233, 1903591281, 1419482752, 2441123433, 2187496278,\r
+       1702204821, 2122285194, 2089053060, 2942266506, 2324464002, 2578155916, 210534015, 3047250071,\r
+       2324013724, 1634562726, 2343004030, 2457901416, 2459794348, 1752785021, 1854451327, 1371062167,\r
+       2189472897, 3462106507, 2054261855, 1736992167, 2122080129, 2256037003, 2458426465, 2424598676,\r
+       2223872210, 1687570800, 3062863238, 2239823738, 2728486551, 1737659249, 2258473320, 2724677025,\r
+       1146478059, 2257697817, 3364907146, 1451408461, 3515249710, 2021314202, 616093367, 1937998716,\r
+       67153011, 1619562914, 1487235388, 1941864056, 3347386767, 3566976201, 1887546995, 2124312936,\r
+       441413763, 2170922389, 2390525512, 1450207147, 2089394819, 2684268185, 1180945290, 2910206753,\r
+       2815471721, 1463590629, 1632660002, 2475998539, 2424470129, 2370412193, 2620105766, 2991954572,\r
+       1452597878, 2789576100, 410622291, 2739752844, 2008071365, 1582235761, 2827835760, 2374806198,\r
+       3314785728, 2156427185, 2089252470, 1967413871, 2172087337, 2289505657, 2471456388, 2344257893,\r
+       2544238713, 261860960, 2772339609, 2726672435, 2457576820, 3077416074, 3326836585, 1943768456,\r
+       188317592, 1872200290, 734697132, 3759329189, 1725059388, 1886295964, 1859802426, 2844511603,\r
+       2375199341, 2441046388, 1014076293, 2628353650, 1972796781, 2440198605, 2238972283, 1853264784,\r
+       2038533498, 2292023438, 1885967486, 2509597041, 2625997472, 2325247296, 2309454471, 2222945415,\r
+       1856013175, 2172675216, 2290247781, 1566534785, 2291759220, 1770615444, 2288352119, 1919991471,\r
+       1719107469, 2170392194, 1850564474, 2055364478, 2291168379, 1937539995, 2541714789, 2156330880,\r
+       1752127356, 1854698619, 2056877718, 3965542266, 636038329, 3340544404, 3579867245, 1872331141,\r
+       1754288769, 2109431681, 2541923490, 2476506009, 2053141597, 1184137641, 1503056206, 3029113231,\r
+       2322112620, 2861009025, 1835634323, 1905958294, 1415865530, 2258146746, 2325248337, 2340577679,\r
+       2256863098, 3511385434, 2493439416, 3175912551, 2965189218, 2171125985, 4290631911, 4058374418,\r
+       1981779370, 2451067809, 2359934876, 748630103, 2308021568, 2791455928, 1586603736, 1666408558,\r
+       2677371451, 2424648787, 2426226110, 2520804875, 2190376016, 1602056871, 2385940641, 3050145101,\r
+       2710864041, 2439677294, 2126550382, 1583194518, 1771603320, 1564502135, 1239302840, 2267977262,\r
+       2392147306, 2158928272, 2300022618, 2254808689, 3164180368, 1551206238, 4755881, 1927599477,\r
+       1683967070, 2257027700, 1512263512, 3262796695, 1600739972, 2469551480, 2507252657, 1800510289,\r
+       1688016711, 2036645210, 1921518479, 2638371227, 2240853388, 2310756709, 2524683684, 2005641577,\r
+       2775386777, 4292635677, 1550277803, 3494657652, 1991872650, 1755821422, 2678136504, 1621586785,\r
+       3476730279, 2051856160, 1985185717, 3367898144, 2087696270, 2337247622, 2372899175, 1451446167,\r
+       2712953208, 1300204891, 2460117040, 2340068981, 2107282551, 2122809227, 1870362248, 2825878150,\r
+       2223084177, 1718770306, 2559013502, 1954645368, 2022342012, 2257096317, 2106625670, 2156169831,\r
+       2170777735, 2139133829, 2173141114, 2394005381, 2169993623, 2424272257, 2155118966, 2004853137,\r
+       2189851013, 2175110791, 2189591414, 2525002610, 2206596989, 2208909220, 2023585169, 1670540177,\r
+       4293432709, 2105108326, 2023538036, 2459019880, 1836941678, 2559803762, 2272166015, 2556257380,\r
+       1788052348, 3870452824, 1432319389, 1941737847, 2068676473, 2226163761, 2442495331, 2610716013,\r
+       1735630705, 1081435762, 2020640958, 2191898513, 2140040576, 2339750261, 1790019187, 1686474389,\r
+       1946117765, 1971669086, 2187566453, 1534614731, 2408207491, 2138812293, 2791421296, 1868265312,\r
+       2656339625, 2659417202, 2157224805, 1387941607, 2915607217, 2439545189, 2310054557, 1954260916,\r
+       1970965390, 2054656648, 2155033462, 2139122822, 1603569582, 2859885920, 2105853059, 1690728031,\r
+       2225173655, 1905695312, 2411938940, 2745570759, 4287734999, 2742379067, 2125606544, 2507898470,\r
+       2243067506, 1647401858, 2644145263, 3122488456, 3308414416, 2170914215, 1918608508, 2413280890,\r
+       2675671619, 2489286258, 2340378519, 1434867571, 2337954194, 2158201148, 1771991375, 2390075762,\r
+       1030184851, 1819309083, 2857526420, 2343205758, 2741134591, 1739619957, 1349624467, 2827301854,\r
+       1659073148, 2174058346, 3144509822, 1935502989, 1675543635, 746951594, 2212840148, 1992644261,\r
+       3267598451, 1702512982, 1752469421, 2276941941, 1954784954, 1883128458, 1904241477, 2256427074,\r
+       2039010952, 2186905670, 2809041757, 2706932861, 4095317098, 3183110058, 1503712588, 2841022516,\r
+       2105505673, 1756546079, 2260020575, 2046849447, 1687368065, 477666890, 3460574647, 3764303686,\r
+       2743971467, 1394255788, 2777776717, 1685829262, 1381266607, 1415659918, 2253092292, 3142875490,\r
+       2726392190, 2240081276, 2373296267, 2041602472, 206666071, 595965309, 1407353089, 3356745896,\r
+       1267298994, 1904110209, 2348857013, 1872716194, 3778354234, 2121948834, 1419084408, 2594252343,\r
+       2440061006, 2073857391, 1396876160, 2254787029, 2410250640, 2103815087, 3416233361, 2107914669,\r
+       943359136, 2356523662, 2123349633, 1366193063, 2605479274, 2897176767, 4131802226, 3019938480,\r
+       1098574972, 2376250258, 3527699012, 1297256585, 1990819164, 507139428, 2591401071, 3882400101,\r
+       1363652974, 1536731783, 2560212142, 3265429327, 1518554741, 1921028015, 1791727213, 3025502567,\r
+       1953648288, 2845151349, 2309453711, 2022150280, 2344449660, 1786282619, 2132505018, 1636459147,\r
+       2742196560, 1419217274, 2241701815, 1936957025, 1850697849, 2269487445, 1149531563, 1803719013,\r
+       9482324, 1950375029, 1984065384, 1936104316, 2122493589, 2794150476, 2257286006, 2069671535,\r
+       1517644874, 1953254537, 1501063804, 2206616905, 2122668162, 3101995343, 1920099519, 3211284291,\r
+       2458304873, 2003594673, 4293836665, 1970902736, 2928174694, 2812512346, 2370530626, 794129811,\r
+       1738041944, 2242807083, 1617832101, 2106029146, 2190762558, 220558951, 1720846940, 2476641592,\r
+       2507559009, 360394122, 2202887296, 1112967283, 1284408751, 2323055734, 1191203977, 1955240363,\r
+       2389868244, 1262442865, 2105158799, 2030903180, 2810299545, 1946625739, 1061632686, 3127944707,\r
+       3298761609, 3080418767, 1412936960, 2629265800, 2343473730, 1472175701, 1230605056, 2239132784,\r
+       2122401401, 2475648472, 1950912386, 3263212288, 2394263863, 1903217359, 1247303323, 1159363459,\r
+       1699295090, 2435681381, 2667601426, 1088396933, 1161804624, 703674431, 2641635735, 3175040321,\r
+       2742524276, 2526426222, 1431952929, 3764940161, 1496454938, 3731834879, 1870882168, 2934388264,\r
+       2369625471, 1500401663, 3011939715, 3056503623, 2880585603, 1211071532, 1501466040, 3316541026,\r
+       2138581704, 2461468273, 2142877582, 2510487386, 1633844583, 658878294, 1200394299, 1707234339,\r
+       2912209295, 3162707828, 4288497139, 1785109843, 3329587363, 339781753, 2237214699, 3781642057,\r
+       1014592256, 1098680484, 2624106367, 742339976, 2827129911, 1988857438, 2899089794, 2422171849,\r
+       2573891744, 1116169052, 4282832728, 4288506684, 1285838456, 627289458, 3211895840, 3082178692,\r
+       1889108647, 1903532940, 2443222114, 1785799232, 2543189865, 2824695164, 1954174689, 2489937028,\r
+       3193662140, 1811117894, 1100119552, 2003490451, 3211220602, 2223219032, 1417636225, 2624166765,\r
+       2106040742, 2217292962, 1876670975, 2771959511, 3047465151, 3352415964, 813334347, 4018543999,\r
+       1144977837, 1068906639, 2360528851, 1795157602, 1535153533, 964314414, 2051496058, 2035378790,\r
+       2236846221, 2590145074, 1318977603, 1675250046, 2556403790, 1902743090, 2013173345, 939575425,\r
+       2441293386, 1581588171, 1561361029, 3770183846, 3193140353, 2073143174, 2239542085, 2356513259,\r
+       992904321, 2946393976, 771800391, 1987930368, 1558739267, 2136697059, 2672585493, 2839684665,\r
+       558785909, 2401082480, 2917037459, 1775669248, 609856409, 2136759395, 3711732619, 1763207604,\r
+       3749539221, 2182578625, 1563571175, 3257728949, 2235071624, 1870112181, 3143764135, 2556720440,\r
+       2019675821, 1663990892, 2761293583, 2774026109, 2771797725, 2910084661, 2562158198, 1934596448,\r
+       2698755697, 1836890408, 1751348653, 1813721087, 1752393802, 2927108515, 3691395436, 1048613632,\r
+       2766392642, 678978084, 1638801063, 2686868080, 1933134441, 1025872765, 2394203219, 1416600956,\r
+       2035186297, 1476433047, 2656120876, 2136635261, 2425909614, 2105450899, 2231414705, 2404087228,\r
+       2267912855, 1806471060, 2075110195, 3920968535, 233162555, 1839070993, 2077853009, 2410888913,\r
+       1938666341, 1905178446, 1953272743, 1821527398, 2849089956, 2541709176, 2608237210, 2857387888,\r
+       4287920736, 1610630546, 1651347054, 2205463412, 3029037653, 1886412205, 2774898516, 2407892092,\r
+       2352116717, 1627416253, 2626368141, 2649261907, 2110635930, 2175539923, 2541500091, 3069614518,\r
+       2525191331, 900037759, 3783424928, 3450383668, 3149676519, 3070187387, 4279647061, 2225438550,\r
+       2540341178, 2118475852, 3732764725, 1561751984, 1838563102, 2479458885, 2880655147, 2692192191,\r
+       2842441131, 1716885312, 3180240079, 2827995392, 1420019076, 2073580381, 1386938129, 3137825392,\r
+       2909114758, 2572384617, 2474347691, 2521912064, 1541169851, 998547163, 2613622350, 3043373741,\r
+       2788859781, 1755815643, 1635015021, 1955750345, 3918171254, 3816332930, 1383428032, 2575712942,\r
+       2056680703, 3372200759, 612800090, 911595941, 1127652435, 2240170538, 4073760224, 2607564237,\r
+       1701409132, 2348844364, 2841553990, 2753642603, 2929418051, 1233421435, 2760005936, 2453298730,\r
+       2529558406, 589788846, 583550111, 3060303907, 2476447436, 1227143636, 1969062219, 1873293389,\r
+       2394457507, 3452397824, 2994811337, 1798922650, 2576480896, 4291143661, 2863055992, 2241150544,\r
+       3245269275, 2827255060, 1568244655, 2565823067, 1868855401, 2063105399, 1296913027, 2861145384,\r
+       2304869228, 2147524252, 2073664337, 4285038484, 2170184524, 3184343952, 1925420381, 3899823965,\r
+       2171366744, 3114418550, 3142811071, 1917091539, 2293727744, 2676335767, 2794022340, 1368945986,\r
+       2726724476, 2079811974, 2465492603, 1905553594, 3566706494, 3043229842, 1838250702, 2239701396,\r
+       4281773477, 2221277607, 3668622454, 2596505697, 2990777083, 3143914868, 3568404009, 2812180223,\r
+       2014872191, 1451657084, 2356591239, 3465916182, 1456646989, 1973648204, 1015317428, 2039449780,\r
+       4052785765, 2877261398, 1199186291, 2573645567, 2306352769, 2785051806, 2191981735, 1265793066,\r
+       1858588212, 3347196019, 993634108, 1084398283, 1851293823, 2176225908, 2068610161, 2576381255,\r
+       2390847869, 1828748144, 2156097717, 3372900004, 2523104382, 2491843222, 2070241503, 2812790214,\r
+       1733124906, 4287795043, 3359804398, 2323688949, 1538999988, 2818604506, 2658962577, 1030824800,\r
+       2380427905, 1808220844, 1617351625, 1045706020, 2811196928, 795120336, 136136575, 2342675032,\r
+       2865929280, 1941827655, 8564891, 1566095241, 3078784577, 2891393102, 2743436174, 3148313653,\r
+       1571392831, 2214568625, 2762186602, 1956152641, 2573631062, 3348135552, 1302626303, 2621991057,\r
+       2926681402, 2000135116, 2139858825, 1519157089, 1419613486, 1659240306, 2730566219, 1621984609,\r
+       2217949605, 2154603419, 1448964510, 2207932014, 2852095324, 1722779201, 1263440605, 1852873407,\r
+       1737001571, 1538770297, 1786487353, 2001438567, 2039545789, 576422830, 862375056, 2355657800,\r
+       2053993528, 2153937857, 2455151615, 2689957326, 2775670089, 1820573031, 3433743244, 2573698482,\r
+       1052804747, 4020211558, 2006581198, 1146776187, 560967300, 2906935114, 3008329912, 1736689592,\r
+       2154780989, 1995155638, 5996260, 1869767228, 1916622138, 1797553301, 2067241354, 1772520894,\r
+       3830680947, 4286467911, 2304534931, 2171448144, 1990884516, 2525396844, 3015927138, 1984643954,\r
+       2379743425, 2661713478, 2526725752, 1453290219, 2209243753, 1718067840, 2075745363, 3820505696,\r
+       2340618343, 2233888149, 2038653536, 2931047569, 2494005361, 2460768866, 1870490815, 2075438956,\r
+       3063126937, 3331954836, 4288059241, 2490677409, 4052172911, 4290394443, 1971427132, 1214271430,\r
+       2558543481, 3077739165, 1486190959, 2030672525, 2092849502, 1097529356, 2296487216, 2193405012,\r
+       7697236, 4291984815, 2421021300, 1586386542, 2908903042, 4258709045, 1390259128, 1617853832,\r
+       1699896692, 2239409502, 2155068033, 1811960487, 2084117094, 2538055240, 3045568082, 1911066943,\r
+       1354906466, 1957819542, 4285092977, 1852459875, 3416548519, 3535713903, 1736602214, 1451581311,\r
+       1986199446, 2742907022, 1216107227, 2091097470, 2810548041, 3972373648, 2774370190, 1705008521,\r
+       1434058690, 2459211675, 1787532743, 1569483557, 1335925333, 2085772891, 2941235626, 2709356118,\r
+       2969543471, 2254800535, 2477354939, 3125577623, 2054422430, 1666554990, 1099026539, 2207945054,\r
+       1853976161, 1365023683, 2847259986, 3441704080, 2610972821, 1968978340, 2810445671, 2378854130,\r
+       2105783391, 2372107689, 2235792087, 3233904486, 2427226036, 1990757810, 2153513091, 1571441262,\r
+       1758895930, 2240655733, 704649372, 1588488801, 1640678148, 2104157102, 1283451538, 4073406476,\r
+       1417228088, 4067863163, 4176416052, 3822533833, 352301549, 4225008883, 2966856794, 2387956347,\r
+       3288297085, 3196146242, 2240578680, 2846126266, 2560068444, 1577812100, 2121388969, 1248421723,\r
+       933199050, 1617205394, 1787916615, 1855652043, 2863544983, 11309689, 1692072544, 3819010226,\r
+       1206629859, 2373470079, 1528175445, 3128369192, 1217357376, 2346349500, 3884545400, 2509736813,\r
+       2707850581, 4288565558, 1042932473, 1036046868, 1044706087, 3151670974, 1044635600, 1050108320,\r
+       1047335586, 1041338286, 1038329480, 3171199086, 1027458487, 1026846921, 3170955028, 1038272791,\r
+       1042099733, 1023631841, 1045623678, 1036850238, 3169992935, 1024287600, 1049767013, 995219795,\r
+       1040643307, 998947591, 1036960834, 3179608228, 3141474354, 1039120063, 1014755058, 1037214547,\r
+       1026831299, 3161435107, 989095806, 1012618819, 3173055039, 3167954080, 1029698723, 3161365798,\r
+       1020350416, 1035914227, 3175887125, 1016829433, 3183727383, 3158569601, 985916898, 1030089263,\r
+       1036454680, 3156054842, 1034743508, 3150866466, 1001270247, 1034190346, 1026856113, 1023816386,\r
+       1025003399, 3154975140, 3159031758, 3181516378, 1017520469, 1006920169, 1026471603, 1026108426,\r
+       995969210, 1009538160, 3159696075, 1016583445, 3150715858, 1014529258, 1008555538, 981846227,\r
+       1015419886, 1023845324, 3171510193, 1019527226, 1020908842, 1025199819, 3154815959, 1020766835,\r
+       3162250959, 1007879529, 3145757836, 3162556466, 3145088904, 1022244160, 3162319549, 1033161556,\r
+       3170004997, 3179242728, 3171476541, 3168027689, 1010205841, 3174575065, 1025535253, 1034040803,\r
+       3154321149, 3185116122, 1015042743, 3171072761, 1042197925, 1031880174, 1041379394, 3173578024,\r
+       1036593162, 3156042609, 3177068509, 1034306201, 1021755086, 1037171564, 3166520301, 3174861139,\r
+       1042442184, 1039408677, 3211598967, 1063993918, 3214289855, 1066729320, 3215091656, 1067608008,\r
+       1058473425, 1055736216, 1054558327, 1063297440, 1055686113, 1053456059, 1053046526, 1058930617,\r
+       1055175399, 1055547741, 1060943505, 1053020745, 1057992678, 1058329294, 1057580897, 1059872046,\r
+       1053422499, 1058662413, 1057713315, 1063441270, 1051529937, 1057582539, 1055260105, 1058488996,\r
+       1056874455, 1059299483, 1064722701, 1062051663, 1058006609, 1057492867, 1057124224, 1059576570,\r
+       1059172961, 1057011907, 1058954562, 1058304555, 1058634745, 1053874528, 1064950885, 1058061724,\r
+       1055327304, 1057684010, 1057613151, 1057127010, 1057215669, 1054258060, 1058885185, 1054363004,\r
+       1057714069, 1058454715, 1055368282, 1056380665, 1056908842, 1060970973, 1055869444, 1056191281,\r
+       1052282792, 1057108079, 1049390702, 1050919932, 1053250032, 1048624365, 1060940324, 1053426578,\r
+       1054342651, 1057317567, 1050209903, 1049810963, 1050441118, 1058141981, 1053128956, 1048935443,\r
+       1051213622, 1049666355, 1065353216, 1055890495, 1053174472, 1049231492, 1050745898, 1047192366,\r
+       1050786723, 1049574412, 1053562360, 1053072316, 1057507729, 1057367590, 1056079662, 1058463884,\r
+       1052494894, 1052580291, 1055205078, 1060115266, 1058303732, 1057790119, 1057549084, 1055993629,\r
+       1059989068, 1058558954, 1051178684, 1051282195, 1058567206, 1057040208, 1059791824, 1059472539,\r
+       1053583692, 1053931205, 1052483939, 1059790662, 1053767605, 1061726074, 1060099530, 1052563253,\r
+       1058779104, 1060662324, 1052805962, 1052883783, 1054990562, 1055979719, 1056028454, 1051613030,\r
+       1054551384, 1049019091, 1054663780, 1053511956, 1054675325, 1049570100, 1055518538, 1055157628,\r
+       1058903396, 1055315307, 1054629148, 1057311364, 1056336387, 1056296286, 1065353216, 1054265834,\r
+       1049974239, 1047653313, 1057291978, 1054848638, 1060135905, 1057007033, 1056277221, 1058717363,\r
+       1058149170, 1055662652, 1056756865, 1059471026, 1057994776, 1057341594, 1061162024, 1058353051,\r
+       1053481820, 1055676362, 1058285050, 1057169197, 1060750194, 1058895947, 1058298761, 1060738436,\r
+       1055935944, 1058929747, 1055845734, 1051893656, 1058198359, 1058048579, 1054462770, 1056562600,\r
+       7, 2154921508, 1770887538, 1804571171, 1655211415, 2260834924, 1233620849, 2977933677,\r
+       1719370851, 1966699904, 1851498616, 2471624773, 2124326201, 2058003269, 1484223343, 1618630048,\r
+       2540060241, 1482408865, 2828046186, 2774821528, 2340195995, 3515246248, 2522589317, 1752967824,\r
+       2256904302, 2423408752, 2462826355, 1502910374, 999581839, 2341698925, 2558685392, 2906629262,\r
+       1854834319, 2208474045, 4280128122, 2173539967, 2152229394, 2744758398, 1717462646, 1452905860,\r
+       1601664399, 1539743144, 2535755862, 1871590026, 2659737564, 2123405764, 2458221663, 2171823953,\r
+       1803395948, 1870633160, 2306248567, 2610895255, 3164963712, 2033815449, 2911135387, 1370579833,\r
+       2022673047, 1704893083, 2460899476, 2507711131, 2748544220, 247032917, 1937937467, 2744607828,\r
+       2257874561, 2294385269, 1719141738, 2578311758, 2460375673, 2441442209, 2090906229, 1937913994,\r
+       2187869291, 1132366848, 2006871379, 2457064046, 2777546974, 2324276870, 1451790152, 2624298133,\r
+       2088872309, 992761999, 2743576689, 1552185754, 2198630813, 1921418225, 2422624023, 2810410386,\r
+       2035250813, 2338811502, 2422774663, 2036441023, 2128242228, 1485211460, 2257605976, 2643372192,\r
+       2474677117, 2309851065, 1183029565, 1970551655, 2122408834, 1485082263, 2172753038, 2152033083,\r
+       1654829726, 4288965760, 2865163625, 3146361924, 2347001747, 1301052555, 2107875722, 2288537007,\r
+       1737642078, 1183092587, 2173196165, 2274521769, 2356300089, 2372447354, 2879031210, 2775694482,\r
+       1788444768, 1284874646, 2422168912, 2189786489, 2710268793, 2473573741, 2192800790, 1988804739,\r
+       293228591, 2796140543, 1102156389, 1687245194, 2239063437, 2373227152, 1636399502, 2697687020,\r
+       1454804295, 2141090924, 1787006353, 2170778741, 1582460057, 2291359616, 2950115127, 2611061721,\r
+       2562696639, 2307030171, 3163209639, 2406381717, 1383270777, 1990425954, 2540559977, 1617987909,\r
+       1520741015, 1934182148, 1870571438, 2263191878, 572029663, 2741595192, 2392037987, 1866488439,\r
+       2187826822, 772964329, 2560654669, 1317234560, 2525066066, 2151322479, 2546118292, 2961888539,\r
+       2913242276, 3149902509, 2329787746, 3970778155, 2732289398, 1795180381, 1939053954, 2707740767,\r
+       979011488, 2255907109, 1755610219, 1769185461, 1483965842, 2746907525, 1462598810, 1622568591,\r
+       2426826903, 2269073620, 2155452320, 2659935864, 1333218110, 1820167796, 2677121381, 2575608480,\r
+       2286980761, 1955747436, 2324928369, 2105711616, 2927650436, 2290981454, 2290581371, 1770952573,\r
+       2322826614, 2873980190, 2190776189, 1075212380, 264273020, 2440129406, 1482463052, 2845215077,\r
+       2641598565, 1194813072, 2072289781, 1378852159, 1889543242, 1181527352, 1768772473, 2286330723,\r
+       2207619705, 1950315395, 1956164180, 3064690785, 3230703252, 2627272619, 2779029918, 1600945778,\r
+       2493090377, 2573909607, 2878559618, 261198202, 2707396774, 1083603568, 866758773, 2630988166,\r
+       3399518860, 1566874535, 1638037890, 1921688468, 2488615719, 1986362755, 2389484062, 8214936,\r
+       1804435812, 24270281, 1972357758, 1567938942, 2070716812, 2091680912, 2691007906, 2218496814,\r
+       2004405390, 848203120, 1904901263, 1802969929, 391347813, 1831237726, 2574176673, 2609351630,\r
+       3377882274, 2996872203, 1351183803, 2064616288, 2119854450, 1385380125, 1922075485, 1737523799,\r
+       2440315259, 2535951742, 2069326294, 4291274249, 1972695382, 2423222935, 2813313889, 2072599221,\r
+       2419946080, 994535765, 2104396104, 2256195705, 2335928403, 2141815418, 1979490700, 3450666350,\r
+       2707136719, 3513501313, 2875632295, 2424562061, 2694482286, 2711977945, 1535836159, 2862242756,\r
+       2676074839, 1752791408, 2139240570, 2320542803, 1969518683, 1990046305, 2487452980, 2675018597,\r
+       2829216855, 2411886905, 2156376044, 1167166071, 2573974887, 1553299249, 2459211152, 2306963115,\r
+       2306453383, 2323150464, 2741924217, 2979500606, 2609618603, 2063569570, 2108258901, 2553758585,\r
+       2291489676, 1585085052, 1399223141, 2021809279, 2037560194, 2087145370, 1333884116, 2696899250,\r
+       1570539408, 2593879371, 2350285444, 1347281378, 1249599598, 2339880565, 2528212602, 2241235878,\r
+       2049084598, 1971874173, 2676259218, 3079923353, 2290059429, 2373686941, 1687590761, 1998959259,\r
+       308084676, 2829285469, 2391712086, 1987276359, 980772221, 2289225372, 1835522662, 1721005357,\r
+       2725095816, 2003268963, 1770478491, 2371261531, 2171167329, 1131906653, 2389738354, 2103796906,\r
+       1854509716, 1597790395, 2592442029, 2123990438, 2134552005, 2641336430, 2105241241, 1666678874,\r
+       2508303509, 2036119236, 2645454938, 1299082614, 1615561586, 1935047525, 2219152483, 2958063376,\r
+       2056222534, 2657836433, 1634043562, 1654946419, 2678950292, 2121820287, 1518375333, 2557280104,\r
+       2372682871, 2138333520, 1669242482, 2274071426, 2322950513, 2087874944, 2476196096, 1923196798,\r
+       1734973818, 2010349880, 1785230206, 1887275142, 2172280179, 2342351706, 1335009155, 1920299378,\r
+       1902077295, 2139456810, 2425387439, 2308028778, 2055048352, 2223870844, 1295400058, 2274186837,\r
+       2206387068, 2008123203, 1786097004, 1347782048, 1904910775, 1836090801, 2404746422, 2791208323,\r
+       2792852630, 2521653145, 2526399127, 2579138234, 3048437650, 1404142483, 2035573340, 1450930791,\r
+       2187323747, 3326237230, 1737780798, 2694405715, 3127870338, 2694422188, 2505353611, 521221768,\r
+       2089188928, 2590834534, 3550164856, 1216124814, 1533757741, 2510589352, 1282450825, 1263557503,\r
+       2560663113, 2238427801, 1363163282, 2544021418, 779042895, 2343749529, 4056112771, 2288013424,\r
+       2116854109, 2037098389, 3025826385, 2005270378, 2426492817, 2322237881, 2845398833, 2541654334,\r
+       1418765958, 980592442, 2473202797, 1953923482, 2559478143, 1869120855, 1434933929, 2426120079,\r
+       2122171757, 1756004245, 1820028040, 1667660184, 1769307753, 2433310848, 2004121164, 1985770158,\r
+       2305588577, 1516860769, 2055183224, 1754617948, 1668786812, 2200730229, 1972283285, 2374225574,\r
+       2072793234, 2140445602, 2406964331, 2038890631, 1702914459, 3214112360, 3429342342, 2055264393,\r
+       2958852445, 2288682496, 1633399897, 1837025911, 3248630198, 2370604193, 2408545234, 2910092679,\r
+       1083144036, 2337378665, 1782347883, 2186725478, 2959876129, 967664210, 2640746830, 2628601891,\r
+       1150045552, 2155033544, 424175001, 613768992, 2372895603, 3583279464, 2827983503, 1485993883,\r
+       1938140817, 2137019030, 822192309, 3216420526, 2138476936, 1300407645, 2427227782, 1971499941,\r
+       2979953039, 2156956294, 1516193392, 2503503984, 1971674714, 4289765193, 1973262472, 2895089524,\r
+       2005022639, 2208001471, 2741289846, 527267928, 1604290160, 2624057956, 1952542329, 3450451058,\r
+       2689044128, 2993976474, 1768249716, 2182529479, 1518178387, 2103208044, 1347466326, 2206629571,\r
+       1989148830, 2289732987, 2055171682, 2674088330, 2389934964, 1920292210, 3161958251, 981420655,\r
+       2190452616, 2660805738, 2744336750, 1970766425, 1748907886, 1818840461, 2122428290, 4168389400,\r
+       2142414533, 1334602905, 763011745, 1703574044, 3266630285, 2995232165, 1939193210, 1080721499,\r
+       2292040009, 1802805884, 1806854515, 1533379710, 962888276, 2287951708, 1418151942, 2640569875,\r
+       3180714357, 2964443016, 1266848054, 3095178095, 2667550414, 1770083928, 2139920733, 2473759853,\r
+       2288862355, 1972340624, 3494220704, 2424928915, 2340322419, 2186654305, 2978849913, 1890960315,\r
+       2546696843, 2141603175, 730686066, 2828177500, 1449548136, 1450544222, 1840020365, 1752732019,\r
+       2436874551, 963772527, 2157095045, 2523040659, 1551658344, 2310309593, 1109475686, 276443443,\r
+       2139218048, 1766475112, 1972472476, 675057256, 2894167451, 2341436293, 2547554697, 2980354951,\r
+       1735286424, 2638905473, 2773193805, 2470996347, 2727575380, 2219474532, 2086232441, 1462798436,\r
+       2220771665, 2877862766, 1470562349, 2423155080, 2711279230, 2374649965, 2474295943, 1563784342,\r
+       2561318767, 2557133160, 1952599891, 2137624669, 1934281068, 2508301948, 2695984006, 3143600407,\r
+       1385604229, 2610869914, 3548025713, 2559932276, 2139901267, 1451532080, 1953264766, 2358276778,\r
+       1033345674, 1098562523, 2813549214, 8696966, 1767146576, 2258141828, 2088013734, 1820906160,\r
+       2489802899, 759581011, 1922077839, 2426222997, 3080880504, 2302903154, 1602071460, 2190183056,\r
+       1887664970, 2474157949, 2489675133, 1933086559, 2306504562, 862073108, 2440722220, 1030985329,\r
+       2256044398, 2290519135, 1493198208, 2207292272, 1669749602, 2190175857, 2828775312, 1635744405,\r
+       2054850221, 1939634507, 1904302636, 2139058561, 3094284299, 2325980387, 1918543740, 2777636541,\r
+       3313075818, 2896191354, 2221442502, 1854570364, 3967967588, 2556399938, 460876167, 2675932850,\r
+       3855194707, 2069553590, 2378081125, 1942891090, 2397130594, 1720481850, 2325438370, 2490653506,\r
+       2139661490, 2214607796, 2442283853, 2677236830, 2339859829, 2019785348, 2477689448, 2924644935,\r
+       3114222480, 1786314544, 2793840243, 2858969414, 1568130117, 1137797259, 2137694310, 1549835404,\r
+       2776609635, 4001855894, 1434550678, 1317634191, 2396829062, 2590542933, 1083355813, 2262069120,\r
+       2557055108, 2710408584, 2341634184, 1818002269, 2961535356, 2289599864, 933966180, 2425252720,\r
+       2084664443, 2757399667, 2141688730, 1850572914, 2726516374, 1535672987, 2358205851, 2037869175,\r
+       1097103972, 2223863350, 1811974015, 2525386925, 2288803430, 2376172967, 2038135656, 2038502974,\r
+       2284625792, 2658300786, 2442257835, 2426124925, 2074451802, 1769356401, 2239464827, 2187155711,\r
+       2592242517, 2173208443, 2860628608, 1531932081, 880961954, 2242935572, 1805162900, 2508615063,\r
+       2288869086, 1637129856, 1920952944, 3263216475, 2257672619, 4083659658, 2155121841, 1651478388,\r
+       3397309043, 1889772196, 2056101796, 2239711628, 2089053584, 2119206295, 1500871779, 2089203588,\r
+       1937546371, 2558880106, 2457238143, 1870639216, 2258345067, 2389610339, 2743038272, 1738254927,\r
+       1952215422, 2156360023, 2275312321, 2004454799, 2456259677, 1837537665, 1199346295, 2288876671,\r
+       2174124173, 2458149968, 2074700414, 1838320993, 2139127155, 2223803040, 2054316421, 2794362761,\r
+       2172714879, 1699889497, 3967468425, 1863287722, 2397617568, 1721325567, 1840140897, 1936233335,\r
+       2815077810, 1474320297, 2306119295, 1241557617, 2238985828, 2377408310, 2976341191, 2355060837,\r
+       2558403405, 1600041019, 3851571295, 2208125546, 2880218476, 2475326855, 2087230088, 1817090414,\r
+       2861445196, 2256253562, 1331584617, 2642850707, 2690737015, 2204532669, 2154405315, 1951158961,\r
+       1817028271, 2658842232, 1672441537, 2358078534, 1969389983, 1735094137, 1085708672, 2742076600,\r
+       2155186316, 2220907890, 2340946084, 2609064509, 1883059567, 2288018806, 2726533281, 1769895764,\r
+       2022210960, 2356905317, 2022075784, 2672965297, 2642835354, 2612905040, 1686869124, 2306574461,\r
+       1555926192, 1887985209, 1786290588, 3431824798, 2374661273, 2067305340, 3163325044, 2741731994,\r
+       2169863526, 3427650697, 1586474912, 2089453437, 1667375039, 1985526660, 2812581512, 2105391289,\r
+       2121304933, 1194411998, 1417986669, 2072117125, 2946665926, 2085835412, 2524079720, 2054397258,\r
+       2324725144, 3349715362, 2120669951, 1858628200, 2528337552, 2406388729, 2422174823, 3297623432,\r
+       1892188547, 1600818810, 2622845100, 2188153742, 2205055717, 1268030278, 2340717432, 2341322216,\r
+       2911338634, 2291307381, 2139796446, 1434766716, 2306173559, 2140443765, 1536722045, 3296291659,\r
+       3029043840, 2257039454, 2190500926, 3046078378, 2509744459, 1040150360, 1917889152, 1905491587,\r
+       1970902654, 2390002304, 1487174550, 1672434559, 2188547478, 2289539714, 2072633958, 2291101310,\r
+       1515886968, 2558956428, 2172757913, 1987412806, 2859700089, 2155809408, 2561555057, 2897394007,\r
+       1265204662, 1636394631, 1153973124, 3562585995, 2960097174, 1070307220, 1926069101, 2050730334,\r
+       1536684171, 1973455469, 1970263158, 1705864102, 2072927841, 1924575872, 2107043431, 3112762488,\r
+       2345512031, 2087808148, 2508421551, 2293135419, 1885040701, 1465954201, 2222980987, 2726395500,\r
+       1937865323, 1717984363, 1668845694, 2224912037, 1396991120, 2206173612, 2460113030, 1708289659,\r
+       2259578766, 3398857271, 2508099199, 1656982889, 2072339862, 2021153155, 2225560757, 2222504291,\r
+       1333955521, 2055238544, 2090505668, 1870622037, 2156555111, 2101765667, 1283027094, 2122579842,\r
+       2315274734, 2539097709, 972527262, 3780456226, 2304526463, 981898142, 2684076660, 2913363320,\r
+       1902344847, 2226618704, 1552957160, 1367432503, 3167333538, 3294386168, 3213933436, 2386646839,\r
+       1871458717, 3883588910, 1934908778, 1872407505, 2860526696, 2265448547, 2594167219, 2726426765,\r
+       2138972800, 1999078590, 2526510513, 1899576692, 3409402516, 2372459381, 1667084150, 1685540668,\r
+       3614557334, 2522638433, 2258206094, 1748075147, 1787941302, 2905843610, 2788793192, 1968013413,\r
+       2021103033, 2052800057, 2793060510, 1969979843, 3502346592, 2256435299, 1989955001, 4838118,\r
+       1348830747, 2072228997, 2893572863, 4037250455, 2355406772, 1990488189, 2274193505, 1603760257,\r
+       2338684021, 2977330323, 2538574457, 2545188080, 2510654886, 2424189775, 1065254278, 2221062254,\r
+       2794091422, 2059706926, 2042053482, 1838188921, 2223610717, 2086099609, 1199269225, 2241543829,\r
+       1870680953, 3533274457, 2306393719, 3215945564, 1585884312, 1409324174, 2787284100, 3780225349,\r
+       2427626898, 2739315403, 2034222154, 2756541028, 2136240025, 2520667252, 2271761564, 2892465561,\r
+       1503491124, 1651283354, 1470326958, 3347409297, 795961286, 1565276798, 2171846572, 1601460551,\r
+       2190059185, 3160389476, 2003779462, 1888584080, 2137877880, 2021553003, 2610720593, 2289932171,\r
+       2273555853, 3364191305, 2087474533, 2223736433, 2994303855, 2106683279, 2278278822, 2140251609,\r
+       2759150480, 2676909210, 3012718702, 2277030043, 2983768715, 2257190862, 2530262393, 2172825227,\r
+       2575670684, 2223544686, 1836481677, 1870821021, 2306181239, 2762728906, 2625998502, 3009312398,\r
+       2629747520, 2742211719, 4290201284, 2020439859, 2838418820, 3947261887, 2473361637, 1363366523,\r
+       2559120954, 2361940151, 1804321395, 2352712581, 2059505747, 1586007944, 1519615592, 2208866654,\r
+       2138607469, 2642271897, 2262992250, 2875959709, 2023319194, 2339790710, 2108600679, 2106617503,\r
+       2891028901, 2242283186, 3042947701, 1887526047, 2354410435, 2941627473, 2021230690, 2120580984,\r
+       2054225809, 3129123509, 3081231233, 1656118904, 2555041624, 2159637568, 1822019992, 1853727624,\r
+       2192146259, 2222037874, 2525934158, 2093050218, 1195093447, 1367239279, 2155882368, 1871421082,\r
+       1685226608, 2258919516, 2388116372, 2205526128, 1990551906, 3078191992, 2220286356, 2709828730,\r
+       2160029075, 1346722345, 2642908289, 2021710455, 1906475686, 2075890792, 2713289918, 2939639461,\r
+       1535923677, 2341759653, 1954909857, 2978442353, 2390255785, 4002491679, 2207083655, 2323185526,\r
+       2524918865, 2591710359, 1604093803, 2003997577, 1805490347, 1419155813, 1116769098, 1872004502,\r
+       2157418612, 2676839766, 1435075451, 2961601414, 2778687890, 1215272811, 3411702896, 1901100664,\r
+       2426841019, 2038209700, 1873580161, 2056754080, 1887275380, 2109640633, 1802468559, 578515553,\r
+       2156003200, 1066561703, 2172217230, 2992935598, 3315182694, 1554805086, 3115739814, 2190251604,\r
+       396457304, 1609498544, 2154591823, 2188750740, 1920363680, 2587713365, 1965599103, 2075300238,\r
+       2459141997, 2307526059, 2258225079, 2375337363, 2842589730, 2240717743, 2190897407, 2093334393,\r
+       2407355538, 2272923769, 2141038568, 3130628727, 1086094200, 1703515023, 3784060550, 2410721191,\r
+       2372901809, 3114411373, 883659909, 2160753648, 1664668558, 2357560932, 1084776092, 1855885173,\r
+       10777198, 2092330873, 2033807582, 1082100881, 2004171331, 1921343634, 594838929, 2206310820,\r
+       2832171175, 1768841580, 2072082821, 2507315236, 2507978204, 2605564800, 3747456188, 3479725379,\r
+       1849162380, 3198640784, 2801828210, 1936618614, 1756736557, 3057549515, 2793604897, 3798739301,\r
+       915188799, 1589784736, 1647539254, 848335769, 2053843124, 2660186773, 1405127048, 1151062442,\r
+       2391514040, 1923135342, 3061923347, 2289269881, 2527566893, 2192087168, 3070255978, 1782476119,\r
+       1870237526, 1465091997, 2523571079, 2491135851, 601470046, 1755164546, 1550952362, 2205066365,\r
+       898861484, 1559459995, 2443076544, 2074426524, 2525269926, 1853539758, 2188903005, 2003981978,\r
+       2677048169, 2138147396, 2209322065, 1818591170, 2039055495, 1820361875, 2642111296, 1320061065,\r
+       3047195779, 1571212620, 1719130763, 2105960229, 2405339533, 2552547258, 1959488153, 1285915559,\r
+       2340060039, 2708898659, 2107210159, 1674937195, 2419631426, 1497980568, 1500762460, 2188620923,\r
+       2859288894, 2021090195, 1993035963, 1224721795, 3096467260, 2122512002, 2492050092, 3077010785,\r
+       2340977552, 1149995360, 1617870217, 1400273812, 1015054668, 2824055219, 2801745579, 2323474063,\r
+       1904193925, 2407372158, 1819968116, 2643548085, 2915529091, 1637265526, 1857332292, 2625538323,\r
+       2040505205, 3463552385, 2574864037, 1942777947, 2728621489, 912426837, 2055645318, 3211094310,\r
+       1703250075, 666139728, 2290259882, 1185439053, 1266445866, 3435050158, 3034798423, 1778431866,\r
+       2090760771, 1818039886, 1905358735, 3338107997, 2993314909, 1633728680, 2037733459, 2170596478,\r
+       2274762177, 2690217877, 2225038419, 1719440755, 2402587539, 1584161900, 2879221432, 2373311603,\r
+       806944897, 1987205744, 2247143258, 2714739803, 1317051297, 2072536939, 1199594111, 1419353724,\r
+       2022093952, 2391624890, 2180147018, 2206750599, 3010094939, 1903455641, 2694635664, 2389500603,\r
+       1773510078, 2542767239, 2303708522, 3248981060, 2508493984, 2243070073, 2211283856, 1602853042,\r
+       2306167927, 1784448679, 1618110327, 1168537200, 1604753553, 3062597688, 3497373793, 2644413247,\r
+       2608043896, 2491062084, 1906482858, 2794417055, 2274191963, 2612105362, 2158407016, 411992717,\r
+       2069674050, 1750288463, 2222933619, 2489823899, 1922335643, 2071815266, 2260425630, 1836208512,\r
+       1871613585, 2273116025, 2490005188, 1956811373, 3267331686, 11109028, 1615629127, 2877506717,\r
+       1134987809, 1365607016, 3092811140, 2442932415, 2406124687, 2607313301, 10777502, 406487391,\r
+       1770628753, 2084273752, 1720875371, 1316936115, 1820096625, 2291701088, 2339604886, 1934524576,\r
+       2659541960, 3062379904, 2021950088, 2711249154, 1906221964, 2646382688, 2072010880, 75968947,\r
+       2711445351, 1756267957, 1618032808, 2859631773, 2557585727, 2156103066, 2759690618, 1368355967,\r
+       691386680, 2072414615, 1567013749, 2391431818, 2541307296, 1836707969, 1902944896, 1752001187,\r
+       1829866628, 2558472448, 1315868266, 1971981963, 1805092476, 2911802243, 2236330108, 2087619202,\r
+       1567521215, 1757776519, 1533511493, 2005300918, 2231016057, 2374522251, 1394515801, 2474797154,\r
+       1172337523, 812933275, 4290670517, 2608110740, 2408760983, 1470117217, 2361555604, 2659356266,\r
+       1736845453, 2292228252, 1757389993, 1468220250, 2356575092, 2070323168, 2526251371, 1952022186,\r
+       1537051271, 2038799668, 1683261574, 1821014896, 1583988072, 1634896529, 2025689004, 3062001093,\r
+       2005035909, 1737129838, 1819766862, 2223272322, 2290457678, 1666029994, 1903869328, 2475057280,\r
+       1432253083, 2140760667, 2274261130, 2893975489, 3314652063, 2306473847, 2055976371, 2140959606,\r
+       1702395265, 2290402467, 4290930048, 1555729118, 2037023806, 2226409650, 1821139850, 2292146616,\r
+       2644668562, 2141747845, 1438954649, 2758115673, 1584943327, 2642903940, 1619117649, 1367979890,\r
+       2694472080, 1802858329, 2342608495, 2527753409, 2288480374, 1703315333, 2557146472, 2038994564,\r
+       1669039227, 2290254479, 2675801736, 1770096234, 2574164612, 2390918045, 2324988270, 2020382868,\r
+       2106750602, 1803516280, 1819963262, 2508550769, 2356310911, 1385859712, 2238211174, 2562826911,\r
+       2375267936, 2290182546, 2206371441, 2474791553, 2206495134, 2323617645, 2458150250, 2222456956,\r
+       1937409903, 2140376168, 2424992636, 2258935951, 2525659767, 1867415927, 1754475776, 1750561182,\r
+       2522976374, 2191944527, 2274731341, 1719755653, 1867343466, 1517715070, 1988978549, 2257033041,\r
+       2326433294, 2406641841, 2105515907, 2459392281, 1149342847, 2039184514, 1853713242, 2608812664,\r
+       2139266434, 2674883552, 2610725230, 1933206662, 3565768059, 2976284748, 713212208, 1957410478,\r
+       3311568764, 916247095, 2172615028, 2835359305, 2088792154, 2523036296, 2471976360, 1622112934,\r
+       2441558185, 2206441895, 1820349108, 2020510571, 2493213504, 1451048019, 2307091289, 1568399329,\r
+       2910805124, 2155910784, 2555018111, 1587042200, 2415887972, 949779840, 2679595430, 1419211144,\r
+       1335589948, 2510636419, 3023672425, 2377088607, 2675130721, 2123722648, 1168735144, 2960893799,\r
+       3093473172, 2224248174, 2378535775, 1264925048, 2119980703, 1551660172, 2189226099, 2258342291,\r
+       1719118799, 2358301333, 2189545597, 1434608147, 1266839681, 2461760145, 2427870612, 1820975463,\r
+       3816992152, 2204659276, 2102772831, 3902971193, 2125044337, 1390587093, 2157813125, 1249082243,\r
+       1615901632, 2330214758, 2708585611, 2776706866, 2559334755, 2141622890, 2037484902, 1534106494,\r
+       2013226317, 2305122651, 1298112178, 2222898300, 2059451994, 1987552427, 1703381877, 1165403482,\r
+       2625225109, 3110303626, 2000854636, 2270650738, 2886362762, 2037364991, 2292221277, 2357371322,\r
+       1321048712, 1822075947, 1565101210, 1672376516, 2457709976, 1820626562, 2275240623, 2372243606,\r
+       2340000356, 2053160785, 1534467418, 1081171582, 2055566982, 2655877304, 2645127826, 3114880407,\r
+       1182627950, 2154261353, 3458634355, 1249285819, 3213140630, 2364711239, 2269539712, 937341530,\r
+       1987349895, 935162240, 3493180022, 1674604641, 1685032068, 1146854526, 1416467045, 1568782753,\r
+       2507249525, 1063503231, 2003801557, 1738370122, 1986320549, 1838153875, 2251317482, 2675934578,\r
+       1376881844, 2072485279, 2742380347, 2074187683, 2072614712, 2207671420, 1754495611, 2313449101,\r
+       2639558273, 2305834060, 1165002076, 2578402890, 1520469146, 2344854861, 1347708818, 2273342633,\r
+       2006686849, 2056355733, 1400930666, 2221746901, 2067750591, 3650506859, 2172845951, 2089917269,\r
+       2811725174, 1482512228, 3464390535, 1172111520, 2999158160, 2454877826, 1002465691, 868397946,\r
+       2478082435, 1237631336, 1919118172, 2020179286, 1719097502, 1474469218, 2945221520, 1819121006,\r
+       2593161138, 1603172014, 2390788665, 2339792780, 2054171049, 2393336675, 3632817050, 2106089603,\r
+       2425588325, 2138995593, 2309326964, 2224520845, 2390995605, 3819739515, 2006478261, 1905107076,\r
+       2291437681, 2004651198, 2122036635, 2139273666, 2808628134, 2057006455, 4287985768, 2272513133,\r
+       3280887938, 2038211830, 2254671463, 2021750857, 2222489983, 2073276288, 1550742711, 2004976051,\r
+       2122434434, 1171807789, 1551534467, 3301754493, 2356044664, 1201372566, 2826875477, 2541307358,\r
+       1150976652, 1638248548, 1825022583, 2785002676, 2323882903, 2187172227, 1488226968, 2158526842,\r
+       2339148692, 2122619265, 1769500252, 2037676946, 2003458393, 2860361396, 2040641861, 2630240314,\r
+       1180411297, 2022052232, 2201646527, 2526067070, 887058089, 2188807038, 1330148197, 3263972054,\r
+       2641583462, 1949007815, 3289272676, 2477485937, 2271730049, 1954505846, 1639800454, 2906429010,\r
+       1747955485, 2176212605, 1319707781, 2876740250, 1985701276, 2574487426, 1635642458, 2206884296,\r
+       3076510604, 2913231529, 2206203774, 1955112824, 2189786235, 2055040379, 2373092220, 2239988605,\r
+       1618774413, 2559012216, 2021885819, 2105503878, 2108521329, 1717201300, 2273542528, 2071427718,\r
+       2239596933, 2089320573, 2611122847, 2589552786, 2441178518, 2205781384, 2207024006, 2306836103,\r
+       2226221976, 2474871936, 2407757944, 2189557630, 2709012529, 1854633070, 2323225962, 3917642384,\r
+       727801713, 1585422927, 3183182920, 2423870565, 2024703868, 2155701070, 1571202190, 2089592214,\r
+       3470095246, 1817141158, 1657177703, 2032102749, 2631330614, 1905630846, 2491263385, 2441326208,\r
+       2659139949, 2254276233, 1869545366, 1686597745, 2339809397, 3698300255, 2524618087, 2904255053,\r
+       2071683222, 2637085317, 10044178, 1098286929, 2218442887, 648360530, 2107790746, 3344149434,\r
+       1902147967, 2010796174, 938086050, 3181813675, 2275253861, 3110235298, 2339546558, 2024619955,\r
+       2028472993, 2039582343, 1984525176, 3082855873, 3197138307, 2072361349, 2575209727, 2240904582,\r
+       1504675166, 2676989571, 1318995867, 2879880575, 2409261661, 1891124129, 2977724555, 2308531866,\r
+       2315817629, 2408612719, 2271580529, 2656857494, 2371977918, 2124119697, 2628093555, 2525465772,\r
+       2274856322, 2323798918, 1232816756, 2373280145, 1756164272, 1871998824, 2306315383, 2629340024,\r
+       2755753126, 2223202177, 2221897070, 2608019191, 1765508470, 2051511951, 2788398238, 2816180095,\r
+       2323207110, 3078334873, 1466143417, 9079949, 996040402, 2009737411, 2021938053, 2509825414,\r
+       1737077898, 1668574336, 1233688491, 2154119750, 1886544300, 1920364726, 1970970510, 1988867978,\r
+       2791868097, 1518697831, 2689242520, 3780621151, 3668478904, 702454125, 2304159055, 2175428001,\r
+       12171294, 2751352532, 2101569632, 2122025586, 608926822, 3694410692, 3748500790, 2440395124,\r
+       1518198645, 2576592845, 1853640578, 2307750305, 1601858656, 2135237502, 1923932540, 4036444507,\r
+       2289806201, 2288556421, 2372822626, 1184197538, 1149806449, 1962894376, 1331862360, 2256305020,\r
+       2160354406, 2890323564, 1435665763, 3213244727, 2425180039, 1754623612, 2345287555, 2272555571,\r
+       2628293768, 2117639325, 1986841759, 2521334641, 2376755128, 1249793916, 2324792484, 1936742293,\r
+       2995302027, 2172949631, 1433756965, 1636140400, 3148706689, 3412224372, 2841088578, 2052737439,\r
+       2843710586, 3004985402, 2116993182, 2156034628, 2327532699, 1903061914, 2324012170, 1832637833,\r
+       1285602205, 2509471881, 2459369629, 1904704438, 1989314958, 2759172456, 1635015775, 2037074326,\r
+       2543880593, 3062778486, 2105763203, 2573560374, 1771411568, 1195541942, 2305408384, 1065068688,\r
+       1333625260, 3294995835, 2405463903, 1584358795, 2224320849, 6374572, 2308466520, 1047033175,\r
+       2136045392, 2203735903, 1587849063, 2156578868, 2375827593, 2710679669, 2288035717, 1668772229,\r
+       2238464108, 1282157177, 612912978, 2323174006, 2558333835, 979916202, 3350760263, 2842591022,\r
+       1616687762, 1837670013, 2223278718, 1486325383, 2106698605, 2089045695, 1200961299, 2577251801,\r
+       3734346868, 1850323066, 3211688060, 1999726739, 1871034287, 327698785, 2401005621, 3129507896,\r
+       2458363548, 2294913897, 1888791174, 7436930, 2239507835, 3556773989, 1280750197, 2745590423,\r
+       2092136732, 3232268944, 3746449554, 770404223, 1585271939, 1549483657, 2794766702, 3012309430,\r
+       1737008024, 2622926848, 2681036496, 2843119995, 1627346810, 2743114265, 1700676584, 1753789856,\r
+       3955383429, 679011248, 2990952448, 2862923113, 1941548709, 2226029602, 2956800901, 2079338463,\r
+       3293290317, 3103818603, 1923273578, 1384013420, 2153477943, 2024633460, 1032680384, 2572848767,\r
+       2175945318, 1421962613, 1856416151, 2022796439, 2273933734, 2713603438, 3067230976, 2555743988,\r
+       1651876334, 2709947723, 2809818937, 3234636429, 2506734395, 6328955, 2930928769, 1435990356,\r
+       2998733932, 1974322980, 2696179351, 2776491586, 591265879, 1332447808, 1618770243, 4289187933,\r
+       2630642471, 2326073587, 2386853427, 2874310332, 860946201, 2630895537, 3601366349, 1183465093,\r
+       1565707681, 3533391625, 2256475273, 1552521049, 1265861249, 3297507672, 2824041601, 2124107175,\r
+       949779492, 4283015498, 3195810954, 1808102063, 10260578, 2573174385, 3098044526, 2589172165,\r
+       1137659976, 1432525391, 1920607307, 3713908341, 2344325542, 1117350399, 3114285947, 3046466660,\r
+       2697178624, 1469400133, 1018346829, 3364572269, 2722871343, 2203681438, 3192858491, 2860033993,\r
+       1653503127, 2693529439, 1717103959, 2225365204, 1992329380, 1405073044, 3345361276, 1385347656,\r
+       1382711207, 2624298121, 2714598252, 1968927231, 1136148325, 1516188555, 1857148235, 2036465570,\r
+       1940158499, 2312373015, 2797311137, 2575350282, 3362178900, 1793946273, 1956336232, 3232378713,\r
+       4285234829, 1515874396, 2959175365, 2216918394, 1121693891, 1452380502, 3360519858, 2415961817,\r
+       3698093449, 2568575144, 3093522225, 1677699661, 918467746, 3060034130, 2122534493, 2135257691,\r
+       3795297377, 2963508121, 1758461804, 1600486064, 1753528370, 3451336513, 2604685378, 3151733148,\r
+       490446002, 1839163313, 3613383055, 1979745587, 1149519033, 1884776668, 2537928767, 2204202668,\r
+       1443445940, 1796319490, 2736031231, 2008496109, 1664912700, 274426251, 2165220168, 2188694921,\r
+       2241830756, 1801758679, 2539879561, 2571734528, 3345068202, 3610914264, 661651308, 3821455937,\r
+       2760091725, 2145534935, 1982628627, 2819985027, 207857496, 2759608752, 2714995517, 2127796658,\r
+       1611282339, 3292069893, 2521465364, 997564252, 2714004048, 2686954154, 1750620002, 2034597517,\r
+       2003386255, 4285436061, 1950824079, 1270978123, 196472356, 2824288891, 1351696300, 3379000680,\r
+       8283087, 1280626807, 2020952738, 3132857809, 2221558584, 3347994111, 1849845361, 2507653670,\r
+       1140865758, 1797424729, 3290014446, 2404955627, 1282258216, 3699809965, 2395048317, 3070282315,\r
+       2059898905, 2342407719, 2609274981, 1602063781, 1518699149, 3143115775, 3519283083, 2290848904,\r
+       2542358882, 2407498101, 3885203331, 2187696987, 714515832, 4228133751, 2561545728, 2338660537,\r
+       2591261821, 2088782959, 2127861183, 2192776039, 2662572907, 2602016201, 2317514784, 1904309220,\r
+       1566363738, 2640750125, 1744791320, 2073927293, 2410634592, 2539488111, 2113959865, 1718978178,\r
+       1650565981, 2907012201, 1178228430, 8385631, 1682878645, 2853608800, 2089159494, 2042536710,\r
+       2105498812, 1145929081, 1644865535, 1464895263, 1723698756, 2054769565, 2671916662, 1966304186,\r
+       2139002700, 1532849267, 1900001180, 2121230986, 2225107838, 4283738209, 2292084642, 1353020501,\r
+       1804017475, 4288326814, 2421699006, 3096099010, 2829615666, 2917744265, 1972411288, 1778359937,\r
+       2656350603, 1485337203, 2320926088, 1469283965, 2451484359, 2089380790, 1480425056, 1670804375,\r
+       2055956224, 2710536062, 1563980894, 2378269055, 2542555117, 3622879908, 2840052501, 2376884551,\r
+       2207307261, 716012600, 1617741055, 2302443368, 2223160951, 2370002534, 1905289042, 2387502592,\r
+       1579244906, 2771896778, 1686862969, 2208307675, 3604650034, 2577761926, 2709624953, 1782142207,\r
+       1954627394, 2238257019, 2139707275, 1723048704, 2536860283, 1886708924, 358896727, 2591582535,\r
+       816023710, 2488419508, 2508951966, 2707330870, 2238986110, 2288149176, 1768720896, 2405867153,\r
+       2071017852, 4287647363, 2238420369, 2339023522, 1585275966, 3061079918, 3147272046, 2798673664,\r
+       1820318554, 1781381344, 2961811035, 1453965715, 4016731931, 2257808551, 2039647062, 2746695572,\r
+       2309599430, 3111625301, 2355526144, 2610408856, 1229945511, 2216925695, 1519022679, 2632627578,\r
+       3382755695, 1385969740, 2096080592, 2085286875, 2423444735, 2137340290, 2441511082, 3293355161,\r
+       2080868661, 2807014397, 1377670588, 1602067406, 3361185970, 2087681182, 1822699180, 7678039,\r
+       2306563232, 4286883658, 2951644222, 1502283397, 2502917553, 3127086436, 2879752064, 2887672259,\r
+       2424078764, 2564583381, 3145613605, 2321961242, 1934932139, 1041721020, 3980293887, 2778295456,\r
+       1711001676, 427092058, 1703328603, 3364963464, 2892404285, 1442895523, 2978784811, 1775951155,\r
+       1320794686, 2664759127, 2239714694, 1748078745, 3172971224, 2544233727, 2306178759, 3382288242,\r
+       2082704806, 3365632418, 1027445803, 1082838362, 1702866265, 3378142868, 2415155968, 2174696594,\r
+       2625876406, 364850539, 1717793422, 2392337227, 1706252359, 2781923, 2071495041, 1301058896,\r
+       1655543448, 2456972349, 1833978707, 2478293849, 6724236, 2024397704, 2256110157, 2125359268,\r
+       2355065230, 2827412475, 2794417407, 2794268733, 1631230122, 3112473523, 1682851686, 11913348,\r
+       4170298970, 1996482948, 1665296241, 1720029840, 3629408804, 3295192692, 2092617610, 1481543611,\r
+       2095766947, 4632936, 1703721519, 2017297711, 1715890060, 3380377470, 2658956152, 4287721118,\r
+       2995801212, 1955830207, 2153889678, 2492101782, 1802668905, 3858515781, 2158968333, 1221027890,\r
+       1472443665, 2425482102, 1727047117, 2761529344, 1334016350, 2196263712, 3599383671, 2061045569,\r
+       2385018111, 1030828935, 3091822708, 2055376944, 2188266622, 2738721199, 2274719839, 2844358807,\r
+       2392489809, 4288768845, 1987485572, 3476172682, 3388964423, 2474209923, 1953399209, 2924099710,\r
+       2763940199, 1919899306, 2217318337, 2135312962, 1939919912, 2343287610, 1603311991, 13741232,\r
+       4287845516, 3033573206, 1836211584, 2426162088, 3516711062, 1204330067, 1147516826, 1587097172,\r
+       2329713931, 1130273523, 2718970812, 2534241536, 2053600824, 3165431399, 2138290339, 1248354540,\r
+       2162743146, 3829645408, 3181719672, 1430157818, 2577380864, 1016257645, 1597325192, 2912344501,\r
+       2454613621, 326238367, 2341502821, 3514077506, 4292571811, 2844490191, 1818968502, 1616894888,\r
+       3432523854, 2159964359, 96576865, 1452566834, 1751518720, 3599463368, 3684531569, 3455277973,\r
+       1971354493, 1148659286, 2351717321, 2039349174, 1517392953, 1938721892, 1837989481, 1735612292,\r
+       1467250856, 3519318318, 3332457593, 899109258, 2005041567, 2694094965, 2063555837, 1388072462,\r
+       1970099083, 2425063844, 2029227870, 1836150403, 1788191625, 2036465789, 2292611902, 1704884370,\r
+       2179438272, 1478269767, 1404474753, 2291119216, 2956097622, 478538239, 2591293510, 2008895238,\r
+       1872815007, 2994481024, 1671122913, 514348717, 2865722267, 3268064565, 2339982138, 2633979956,\r
+       2742496818, 1514962397, 2709546836, 2827590401, 1262698628, 2224535198, 1831237214, 2072406954,\r
+       1651354209, 1721063261, 1316618464, 2489073573, 595034021, 2046799449, 3528220021, 1826254820,\r
+       3450365833, 1882542135, 2085653129, 1144509186, 3199656829, 2789834314, 2389190804, 2400761658,\r
+       4288219442, 1042603771, 1035037192, 1041392947, 3164289839, 1046133844, 1043842840, 1049253840,\r
+       1038666594, 1045196835, 3188215987, 1031619627, 1043727733, 1036661432, 1041622745, 1048824264,\r
+       1027215517, 1044437848, 1042579783, 3184765682, 1038538413, 1046623258, 3161780724, 1041333690,\r
+       3133471355, 1047941070, 3185256064, 3166288194, 1035189116, 1034632125, 1032433335, 3175298323,\r
+       1016157480, 1028214081, 3183157347, 3176333289, 1036100462, 3140557907, 1026715857, 3169469313,\r
+       3140780796, 3173586778, 1037662361, 3188986036, 1039576831, 1035604195, 3144976527, 1040946940,\r
+       3147460742, 1031203383, 3177400140, 1026939978, 3180900631, 3164026658, 3179952814, 1040399131,\r
+       1038638804, 1024325640, 3171885748, 3174632920, 1029056305, 1030626655, 1037954418, 1023838274,\r
+       3154441571, 975676812, 1008935137, 1016051759, 3165650861, 3180035793, 1006108728, 3161897497,\r
+       3160511518, 3171917153, 1008931655, 1019814600, 1027394841, 3159197524, 1029224297, 3172138065,\r
+       1019901034, 998804741, 3159419213, 1024485164, 1017952167, 1033292974, 1023102610, 1031625448,\r
+       3162349529, 3189807112, 1032258975, 996297794, 3192633393, 3172214307, 1005434591, 3142289465,\r
+       3194658873, 3155884751, 3175317487, 1028443888, 1040680368, 1028102661, 1009508181, 1049361173,\r
+       3165825931, 3182975263, 3184573791, 3178033442, 1023036774, 1033860938, 3182882872, 1051482665,\r
+       3180928322, 3216852834, 1069272275, 3215652575, 1068081393, 3224132137, 1076648489, 1055061328,\r
+       1054288735, 1051767353, 1055610908, 1056235109, 1051364641, 1051988695, 1055917768, 1051640368,\r
+       1052716616, 1053584217, 1050503795, 1053217794, 1055124746, 1055481068, 1057849754, 1050736347,\r
+       1052631439, 1059168410, 1052699872, 1051648261, 1053599727, 1050728257, 1054429730, 1054853351,\r
+       1051224648, 1058913120, 1051715525, 1055926313, 1057521500, 1058137826, 1061106812, 1052258613,\r
+       1056772553, 1056274931, 1054951367, 1058243306, 1054113033, 1058428496, 1050662770, 1052985765,\r
+       1057450288, 1053636028, 1058040582, 1052837560, 1053268369, 1057973469, 1057709983, 1053742492,\r
+       1055400157, 1048639099, 1055581633, 1055583205, 1056668019, 1054602533, 1057288882, 1053916600,\r
+       1053254942, 1051689684, 1052825094, 1057840440, 1053405299, 1060887946, 1057854803, 1051358457,\r
+       1052326119, 1052071987, 1051411977, 1050359446, 1056069785, 1052857365, 1058765902, 1052870840,\r
+       1051167150, 1065353216, 1053149242, 1048327183, 1057028737, 1050414344, 1049655702, 1052345901,\r
+       1051917585, 1050662169, 1052720943, 1053410517, 1060671004, 1052717848, 1058143277, 1055671864,\r
+       1059147617, 1057690383, 1051027184, 1055805121, 1053202246, 1060001178, 1058611761, 1057931336,\r
+       1056542414, 1056528372, 1058820523, 1054097365, 1056104341, 1057812339, 1059682903, 1054673906,\r
+       1057804793, 1052857407, 1057913727, 1053763454, 1053354143, 1061551273, 1056275317, 1056290864,\r
+       1052376167, 1056612059, 1059516478, 1055004151, 1051314504, 1062125645, 1051562457, 1054867885,\r
+       1059712089, 1058499250, 1058644908, 1059517997, 1052621846, 1057995597, 1056730257, 1057096118,\r
+       1058712602, 1061231925, 1055228442, 1058262020, 1057093883, 1056638879, 1056603106, 1053564184,\r
+       1052400578, 1056714055, 1049950300, 1060693726, 1057772180, 1061522783, 1063238506, 1058120451,\r
+       1059110739, 1060393616, 1061234807, 1057869693, 1059789631, 1064658576, 1061967263, 1060844497,\r
+       1061052711, 1058771597, 1055671998, 1059544269, 1057948895, 1058230096, 1065353216, 1058033139,\r
+       1062183242, 1059375690, 1058814743, 1057741551, 1062971927, 1059964249, 1057398139,\r
+};\r
+\r
+uint32_t* get_knSceneSwitchWeightsArr_addr()\r
+{\r
+       return (uint32_t *)(knSceneSwitchWeightsArr);\r
+}\r
+uint32_t get_knSceneSwitchWeightsArr_size()\r
+{\r
+       return sizeof(knSceneSwitchWeightsArr) / sizeof(knSceneSwitchWeightsArr[0]);\r
+}\r
+void get_knSceneSwitchWeightsArr_version(char* ver, uint8_t len)\r
+{\r
+       memcpy(ver, NET_VERSION, len);\r
+}\r
+#endif //#ifndef Goodix_DSP_EXPORTS\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/algo_params/HR/04_EXCLUSIVE/HRNet_knSmallWeights.c b/code/sdk/drivers/peripheral/ppg/gh3x2x/algo_params/HR/04_EXCLUSIVE/HRNet_knSmallWeights.c
new file mode 100644 (file)
index 0000000..f5e1096
--- /dev/null
@@ -0,0 +1,254 @@
+#ifndef Goodix_DSP_EXPORTS\r
+#include "goodix_type.h"\r
+#define NET_VERSION "ef6000"\r
+#define NET_SIZE 1861\r
+const uint32_t knSmallWeightsArr[] = {\r
+    0, 1065353216, 723812122, 3902531414, 83232768, 8326376, 4026205180, 3859079194,\r
+    2162170138, 3514835163, 332712607, 3590125560, 360665456, 3943107855, 671876327, 2149778726,\r
+    3081742756, 3288432445, 100795637, 2047015422, 97822079, 370474486, 368049535, 33745659,\r
+    2561343231, 3088577808, 4230020224, 2138359528, 3593018085, 3994099140, 2154028040, 937290933,\r
+    637540479, 4026538260, 211082477, 916379263, 1057330916, 954468837, 3859935103, 3773244698,\r
+    718658800, 435637887, 3210680274, 1063082402, 1055065490, 1065353216, 1058203764, 1057598177,\r
+    1059599164, 1063897802, 1064184204, 1053699367, 1062333553, 1063954077, 1055498990, 1056671481,\r
+    1056789418, 1051470807, 1056997914, 1064777577, 4272203610, 42802532, 4240738701, 268435456,\r
+    4141263870, 262322266, 21834126, 4204507522, 35497600, 4224179524, 37337168, 4264372026,\r
+    4174983159, 4252052733, 4126997501, 40900363, 3217633372, 1070149724, 3223308094, 1070699598,\r
+    28774162, 972490496, 4080658440, 3773923306, 3212096687, 1064487750, 1065353216, 268435456,\r
+    3198645187, 1051161539, 0, 1065781652, 2155904896, 2155839615, 2155839359, 2155904896,\r
+    3215758969, 1068186956, 1026691050, 1028905985, 1065353216, 1034275852, 1037151867, 1016549678,\r
+    1057361643, 1024639618, 1012170274, 1047150030, 1061770130, 1040998679, 1041135878, 1024938515,\r
+    1028448923, 1033626658, 4254324992, 34766840, 4254684670, 268435456, 4141953961, 252128093,\r
+    34978502, 4053006291, 31771066, 18528551, 23313140, 4264588030, 4184410713, 4275689192,\r
+    4081945602, 29059742, 3217443012, 1069959364, 3214400132, 1062965875, 0, 1072919447,\r
+    499817044, 3122988005, 2131313759, 4283023270, 505398308, 1006951474, 1276018921, 20137532,\r
+    3213356089, 1065802849, 1059157879, 1065353216, 56775295, 268435456, 3214764151, 1067280503,\r
+    0, 1067079640, 3783295134, 2153378175, 3598679841, 2144370765, 2149635199, 2145681413,\r
+    2273365376, 2131829120, 3217173204, 1069590142, 1061047259, 1051953679, 1062346374, 1049271159,\r
+    1058207950, 1035803004, 1047395297, 1045345303, 1062020498, 1051235752, 1054641419, 1031692732,\r
+    1062268339, 1065353216, 1057676811, 1033425538, 152312653, 10016410, 4263687146, 98383498,\r
+    4245241401, 91786093, 4275593632, 4274814651, 50365847, 174753486, 4293760701, 210686097,\r
+    103853442, 4026531840, 50473322, 4250147132, 3231651314, 1084167666, 3225066264, 1063301196,\r
+    0, 1074270171, 1357152492, 3472324914, 1049261616, 3752439171, 3209428875, 1061840780,\r
+    1065353216, 268435456, 3228622752, 1081139104, 0, 1075894956, 2139062400, 2139127936,\r
+    3225800544, 1078215617, 1065353216, 1021161895, 1045887687, 1039906458, 1035341205, 1007998557,\r
+    1033761179, 1042703111, 104109880, 4294445529, 203247162, 268435456, 79485405, 4231144799,\r
+    89729953, 4225729829, 3221980600, 1074496952, 3235255008, 1070651960, 236023587, 923382804,\r
+    185587217, 444538377, 4244451626, 3006875415, 190634489, 3112231465, 232450565, 351081984,\r
+    115807221, 2163865082, 316391348, 4034977764, 1048780547, 73714644, 293594809, 172423646,\r
+    4216582241, 132633031, 199507504, 1763838591, 319152363, 36042239, 353178157, 4076866294,\r
+    4079685364, 32379775, 809279936, 220200200, 4108911926, 15995776, 3223356808, 1075790973,\r
+    1055623472, 1049520819, 1065353216, 1050199833, 1060061665, 1050682249, 1065041686, 1056393390,\r
+    99735180, 4294403312, 203354404, 268435456, 78473522, 4234006502, 89761080, 4226118139,\r
+    3221980567, 1074496919, 3230747276, 1083490337, 0, 1083460804, 4289038981, 33557783,\r
+    3812687894, 4284791479, 534557, 2094202789, 234884622, 2314817, 3975604991, 1985544426,\r
+    4285552370, 4177521372, 2916337407, 4294436586, 4293982133, 4293849026, 6137994, 11373148,\r
+    8827332, 7179152, 4283920807, 4282469491, 3044573184, 4279325574, 3500720924, 3724502698,\r
+    378536324, 218129631, 1589251605, 2923482, 2625732352, 1635483289, 3048193791, 3133064491,\r
+    1246320051, 1224781949, 278726273, 1066203, 3528710143, 3621241133, 4137219072, 4025779224,\r
+    1617714301, 4286028919, 2156495220, 2239124224, 2033745858, 2223112065, 1467107959, 1213130495,\r
+    3703432512, 3907102720, 2046854332, 2323590554, 1761635255, 1852845787, 1277787348, 1426090294,\r
+    2152236916, 4284579136, 2278621100, 3906363465, 2257698414, 3147670784, 3370705094, 4294034965,\r
+    2124843007, 2358634101, 3094013439, 3249976350, 2974182378, 778344447, 1057020077, 3225313997,\r
+    1075066648, 3212592491, 3196260924, 3213500530, 3226084450, 3209171433, 1080351107, 1065222879,\r
+    1043134895, 1056982473, 3164775302, 1074460257, 1058287265, 1059104523, 1040100302, 1058387604,\r
+    3202136656, 1053622439, 3201793808, 1039810203, 1053468556, 1060617708, 1040105390, 1060661813,\r
+    3204229456, 1053647001, 3201309818, 1039794910, 1053479764, 1060697761, 3222289422, 1074731926,\r
+    3222191866, 1074635132, 3244611971, 1097128323, 1018853971, 1063265417, 1046654034, 1025556313,\r
+    1046683849, 1031972879, 1065353216, 1056616716, 1062311675, 1020713127, 1024757561, 1050572446,\r
+    1040142628, 1060709632, 1054499736, 1052383914, 1013835328, 1019510270, 1005909834, 1022630294,\r
+    1009332921, 1026530518, 1032064977, 1014968600, 1050578924, 1043502734, 1065353216, 1059894724,\r
+    1057082294, 1057286913, 1048877721, 1059630074, 1060440311, 1052787528, 1058296333, 1055196263,\r
+    1043473054, 1057604774, 1046319764, 1046308794, 1049321193, 1051051414, 1051019001, 1048246837,\r
+    1044786149, 1051066931, 1049728273, 1042211615, 664568499, 3852517794, 3948485809, 2011329916,\r
+    1603951947, 1898186642, 2940163974, 2159812039, 2489623935, 1482900821, 3851419779, 1450054253,\r
+    651996530, 23039577, 1835991187, 1434474427, 3630708846, 1803393189, 4170162290, 2594152821,\r
+    2173534607, 1586732676, 899245924, 1535594381, 2507847030, 2575342696, 646473653, 1583263394,\r
+    2350873691, 3197913724, 2348860562, 2810625450, 1624651110, 862222182, 3260910712, 3247860741,\r
+    2695669133, 1349478818, 3196568328, 1117362757, 3195670063, 538331562, 8485445, 2458399346,\r
+    4051325155, 3031312798, 1408067497, 1872007537, 2339485820, 2766649681, 1773297779, 197543255,\r
+    1382991473, 1566302564, 2291442259, 257437511, 995576026, 2677378603, 2889454466, 2934084761,\r
+    558139466, 1114964328, 1903852663, 2730835776, 2843299423, 2032568964, 2606352896, 1079658155,\r
+    1837915288, 1636468101, 1048676217, 2273979822, 2510796619, 2680202401, 1895804584, 2020047992,\r
+    2522185340, 2359391361, 1016167519, 2171169398, 2390785934, 2221572728, 1063734661, 1719782540,\r
+    389787107, 1971935586, 3531431372, 3902970488, 9404895, 791951232, 1065582190, 2027594828,\r
+    4018630049, 845371264, 2622132571, 1936954768, 1837854866, 1622297962, 1700104870, 2844233871,\r
+    4289278386, 2576857714, 1673039959, 1078567448, 777945213, 2829760922, 1921950842, 209025142,\r
+    1821100691, 1732342634, 1551928179, 2073329807, 1753434300, 2761574726, 2180620268, 1591646875,\r
+    564886879, 628769689, 1095598213, 2311085185, 3818082476, 991690867, 2188619088, 760814718,\r
+    1657034858, 1081703329, 1293315690, 2658751583, 4281974247, 2746329242, 2209829468, 1655726451,\r
+    2491263872, 2578225203, 3079120523, 1654158998, 2172178694, 1401397891, 1269659506, 1464750987,\r
+    1934578323, 2459100296, 908612988, 665653706, 1943890023, 1836606794, 2471462246, 1435457880,\r
+    2434565970, 1985813370, 2571829322, 1667138182, 1783265306, 1644996032, 1667329412, 2575718766,\r
+    2678289807, 2257686878, 826305665, 1399683227, 1164605326, 2560207218, 2943700883, 1627416441,\r
+    2928183716, 2052610705, 1820810877, 1349672325, 1365150570, 1868969557, 2989066486, 2449435852,\r
+    2212196172, 2208389810, 2170914176, 2644169846, 2780596364, 1721715106, 3429543532, 2944491915,\r
+    497179460, 562327737, 2217231242, 2309395307, 2762708596, 1772191579, 1644197236, 1954382762,\r
+    1482530213, 1707777701, 2658908749, 1529818515, 1364239772, 2171352952, 659717215, 2003070003,\r
+    1715239334, 2291506770, 3313131693, 3331428473, 1107333264, 1096533570, 612338556, 2730997879,\r
+    2407363439, 124672141, 2372714398, 1920248930, 1401643651, 1414621831, 2373940838, 2339537799,\r
+    3266871745, 2527824268, 1871343968, 2391508681, 2136771711, 2425124738, 2794096020, 1817405050,\r
+    2054780544, 2238869640, 460746539, 1700266119, 2659742906, 1199330226, 2623241658, 1686276240,\r
+    2709292421, 2177012308, 2579598220, 1384503592, 884700818, 2913690272, 4285908841, 2541981823,\r
+    1820685938, 1986952098, 2305595020, 2156567218, 2086894763, 2164224693, 1350280573, 2324267913,\r
+    2155318657, 2272626323, 2474866071, 2306577286, 2004642679, 2324595849, 2776792204, 2475066514,\r
+    4086325326, 2223785933, 2639182681, 2611699129, 2120530333, 2296013482, 3128854169, 2191185152,\r
+    2225702278, 2892993146, 1585928067, 3682813809, 2289735785, 3581325088, 4287846519, 947170239,\r
+    1781458331, 1892504795, 3317076548, 2863178363, 1807381630, 1901559925, 2509206150, 2878308994,\r
+    2829282195, 2523818433, 2694275464, 2272155580, 3078646144, 1600689546, 1538615459, 2155831162,\r
+    2494601312, 2670439300, 2762043280, 1704198346, 1857003141, 2811202190, 2239397712, 1335416992,\r
+    2977794702, 2105579904, 2743402320, 3163795415, 1082690499, 3638804439, 2361215327, 2339607934,\r
+    2172355975, 2524541342, 3653001616, 1149878127, 1503035806, 2071246485, 1774287496, 1163150032,\r
+    664194201, 2038928794, 1547778501, 2224574672, 1408735745, 2606401120, 3547033958, 2235001251,\r
+    984437180, 1275035287, 1286308216, 2492658254, 1870821242, 2442229647, 1903537564, 1870754941,\r
+    2825936809, 2876151663, 2009431703, 2140774521, 9019259, 2056046524, 3278931624, 2676982661,\r
+    2156370563, 2327994470, 2022082194, 2139190405, 2423555483, 2005235080, 1381346610, 2475129246,\r
+    1687130482, 2809028294, 4284314487, 2492576915, 2087884879, 1984080014, 1753557415, 3412643272,\r
+    2172747129, 2306115202, 1821354293, 2291891140, 3266467459, 2792524435, 2876151417, 2236915557,\r
+    3331229570, 2326044238, 764235894, 745302645, 1853072552, 2315308408, 2307548540, 2388419465,\r
+    2408759149, 2542893218, 4288132139, 3057311640, 3190452391, 2207750026, 1604737697, 1338212006,\r
+    2305999020, 2626022754, 94617478, 1973979351, 2340975983, 2507302040, 799582679, 2557303225,\r
+    848389477, 2292424003, 2272889466, 2808449457, 3692344471, 1907824639, 3187235997, 1537639022,\r
+    1267282303, 2391846485, 2440409986, 2677303124, 4290868784, 3533345474, 1667266117, 1754699950,\r
+    2846134896, 2893380309, 3275074949, 2895121901, 3248474998, 2693498764, 1840019095, 2041813327,\r
+    1332234854, 2673105794, 2709794231, 1351130748, 1216903922, 2393599384, 1803115654, 2578307137,\r
+    15637389, 2306254244, 2891918589, 2758904729, 2912390046, 2292466036, 2341700214, 1618448029,\r
+    3091800676, 1871217648, 3132195702, 2309579911, 2192078909, 2358675344, 4087836310, 1925160229,\r
+    1702982291, 1935443859, 2389421556, 2147515808, 1887540100, 2406974570, 2509137503, 1832619112,\r
+    2643431322, 1598902911, 2639357627, 2678109317, 2022871910, 2639102574, 2946135203, 2306184411,\r
+    4292839829, 2156685908, 2140111493, 2475851889, 3735453473, 1954715831, 2806226529, 2090248378,\r
+    3480455291, 2441002029, 1845436284, 2391455836, 631152474, 1385927029, 2574659475, 2656407035,\r
+    2156351347, 1918328504, 2825937062, 2459596224, 2335531473, 738155999, 2977601869, 2291899023,\r
+    2372766097, 2103341952, 1852599424, 2994681992, 2189839693, 2256957807, 2427211126, 1277322930,\r
+    1921489544, 2323491912, 2209899672, 2307096428, 2259242838, 2220138113, 2241296757, 1500817473,\r
+    1957078648, 8227951, 1986815475, 2117639831, 2307619732, 1013930451, 1789254803, 1720820107,\r
+    1733022046, 2257684118, 863032980, 2341213886, 3997592466, 1836405101, 1735023472, 4282354544,\r
+    1433101673, 1974504837, 2777867655, 2210243374, 1717270152, 1651997282, 2382411133, 2023322747,\r
+    2406974098, 2714407307, 2291962253, 2207368520, 1672191621, 2105639577, 2140333671, 2373933443,\r
+    2558493575, 2105506942, 3330950281, 1620944748, 1671652018, 2509918329, 1983416169, 2506859617,\r
+    91914886, 1904436479, 1667772046, 1551459964, 2237887616, 1909760116, 2358273642, 2425252731,\r
+    2009841151, 2119724184, 2497432604, 1887937140, 3284238028, 3352400350, 3784806523, 2493891190,\r
+    2057677978, 3212880790, 2760887739, 2375461570, 2087878758, 2357428078, 1855167414, 2457700461,\r
+    2679138438, 3312029554, 2778427808, 1921892463, 2674760070, 2408419203, 2457415360, 568428946,\r
+    2155850840, 2474442604, 2206041469, 2256829052, 2980346183, 3296957558, 1845101207, 2041877138,\r
+    2995553142, 2103545468, 3727524472, 2071330994, 3482086301, 2747944309, 1836126321, 1736956429,\r
+    1788306043, 1851818408, 1448963224, 1905502110, 2258901418, 3127799642, 1010935142, 2553976430,\r
+    2805379, 2286886398, 1754674858, 346979953, 1485202367, 1865913876, 1803596404, 3167405100,\r
+    2423094156, 1216896886, 3620259500, 2023517184, 2486668157, 1968008274, 1837657488, 1303209605,\r
+    1720942461, 1886219400, 2637194363, 2323478119, 2764869281, 2731451953, 2527764272, 3565375071,\r
+    3801765506, 2811454897, 3733613451, 1285406240, 2927389308, 2574161686, 1909065339, 1257138029,\r
+    2003752960, 1333243953, 2206826627, 2492042123, 2254529200, 1232439698, 1538835364, 2086111144,\r
+    2812959366, 1705864482, 2798606238, 2090968681, 837078406, 3889384325, 4285983289, 1723232094,\r
+    1885428632, 2809360227, 1754572122, 1853635679, 3023722913, 1315798156, 2506991773, 1835451711,\r
+    80638087, 2105304194, 11650885, 317419611, 2020185936, 2558893149, 2657266294, 2427094874,\r
+    1687124605, 1871847046, 4289020067, 2137431947, 2561439348, 2321382753, 26897287, 2526913259,\r
+    2558761841, 1169920111, 1651409867, 2509404587, 1920562046, 2153939061, 2206237313, 2055761018,\r
+    2374008953, 2156102543, 2566879361, 2458752394, 2190049123, 2040824450, 2559347083, 2072413838,\r
+    2358805891, 2239923079, 2036040308, 1834441114, 2188640313, 2559985312, 595626069, 2358869599,\r
+    1113059702, 2005775570, 663205003, 1490419842, 1538276337, 2359362249, 144211266, 1476382635,\r
+    4283924304, 1398810467, 1665624433, 3674102865, 2102554327, 1793952374, 1697020347, 3623840399,\r
+    507014290, 4015588002, 4102766485, 2188574614, 4184647093, 12565813, 2589606060, 2880976588,\r
+    3092084854, 1919615043, 2407818401, 2355847818, 1466388374, 2893699445, 4287650192, 2682440947,\r
+    3032968494, 2441580745, 331672135, 2281650802, 946546176, 3333840329, 777297720, 3666491502,\r
+    2067695299, 2290970672, 3143852181, 2967118335, 1734882676, 2710394783, 1351904126, 2533309644,\r
+    1213661310, 3400227014, 2506778203, 2498938518, 3966583463, 3165672265, 2995290506, 2720565503,\r
+    2071985789, 4290723046, 793284424, 2476279467, 1586669921, 898872401, 3097648842, 2924916991,\r
+    2664675715, 1720704502, 1689033544, 1811906626, 3631567484, 1836091391, 2323089544, 2000721252,\r
+    2247229315, 1586407851, 1250466445, 1801462175, 1744992383, 2777372160, 1182739562, 2306646391,\r
+    2090925984, 2105173084, 1701613488, 2139501442, 911638912, 3422566012, 3749539704, 2276829794,\r
+    1939767427, 1620676772, 946902380, 2248121216, 2610194533, 1586134932, 2240052874, 2291597436,\r
+    3187644792, 1686750115, 3985414089, 1817865409, 3752624895, 1972272751, 2438876306, 1305576587,\r
+    2891907168, 2591597368, 2122623655, 2072084307, 2336865123, 2122421882, 1685957525, 2054422674,\r
+    3852140421, 1168156556, 495104830, 2523061444, 1576093616, 3483697064, 1147438184, 2524921231,\r
+    136353382, 1754233523, 2650834853, 2186106696, 2392561663, 1787069550, 2454739352, 2527766450,\r
+    2492661645, 1988661635, 3211819915, 2424985237, 2550100370, 1905570748, 1469178464, 2126873195,\r
+    4287600001, 748859502, 2725612185, 2453880203, 2240263, 3124046773, 869563669, 741078535,\r
+    3049500519, 867303291, 2610680710, 1807182475, 918561342, 4289752498, 3685772069, 1611128164,\r
+    1212954239, 4286011820, 2105638244, 1921498220, 2877280924, 1485674044, 4017190655, 2675587998,\r
+    2714017144, 1570823069, 2056322963, 2124050043, 2207805520, 2289864077, 2030007920, 1568311705,\r
+    2054395541, 2239398260, 4286079392, 2303579316, 3060898463, 1434299205, 3616174523, 2475919871,\r
+    1902734747, 2875484803, 2910291327, 1972633477, 2358931881, 2122089881, 2223284839, 2097123714,\r
+    2188937080, 2105835908, 2086109828, 4285825416, 3192921485, 1050361065, 3149442914, 3173197302,\r
+    1037782725, 3187674054, 3164118800, 3183141576, 3189952724, 1044421715, 3201875109, 3177659050,\r
+    1050895976, 1044914407, 3168333641, 1039378144, 1040605494, 3163432228, 3135079793, 3164590230,\r
+    1043384252, 3178235543, 1032465731, 1044157367, 1036501142, 3188284441, 1044854541, 1034367409,\r
+    1021915983, 1037486838, 1042596344, 1046247190, 1020602714, 3172857184, 3129006688, 1016232172,\r
+    1045239576, 1000549393, 1044332255, 3153009832, 3164132227, 1027230476, 3181471787, 3173886868,\r
+    1034451663, 3179158457, 1027464034, 1035937807, 1035188122, 3159962702, 3171375809, 3170699076,\r
+    1017801649, 3184143065, 3187586170, 1024206755, 1028312176, 1012618346, 3188786352, 3164042932,\r
+    3174102485, 1010228461, 3170123796, 1040484782, 3214324696, 1066763888, 3216805445, 1069225256,\r
+    3218652853, 1071169205, 1049280423, 1057432742, 1052109265, 1051681762, 1054449020, 1058721350,\r
+    1057279938, 1055801093, 1053061115, 1056951644, 1052473492, 1060135014, 1052207066, 1056045540,\r
+    1058690379, 1058826097, 1058774173, 1065353216, 1055732099, 1053593733, 1049633656, 1058880465,\r
+    1050200571, 1058529665, 1057527702, 1055503162, 1058115414, 1056578272, 1053780662, 1054380386,\r
+    1056587649, 1060688885, 1042342730, 1048951067, 1046894810, 1043779977, 1045184334, 1045914358,\r
+    1049030559, 1044217903, 1042643026, 1040873705, 1051469012, 1043758119, 1043096432, 1044338477,\r
+    1046704522, 1057177562, 1059910484, 1052321435, 1049598651, 1051672173, 1052643463, 1057068400,\r
+    1057386300, 1056872040, 1055353794, 1053994202, 1056377358, 1059403121, 1055129778, 1053611548,\r
+    1050304537, 1051391390, 1050729375, 1043419892, 1051683707, 1051346709, 1057231983, 1053953866,\r
+    1057208394, 1057470769, 1057945889, 1049189026, 1056858721, 1054339242, 1056642004, 1047977704,\r
+    1043059641, 1052368054, 1058985543, 1057019953, 1055259290, 1055945398, 1048805676, 1051124621,\r
+    1051592439, 1057863834, 1057116710, 1054444755, 1063910970, 1057094826, 1052418100, 1057937273,\r
+    1059248393, 1065353216, 1048804560, 3185291693, 1025908581, 1033674267, 1051581933, 1023556120,\r
+    1053094595, 3191215129, 1049974622, 1040061732, 3200393118, 3171525095, 1041427861, 3184434773,\r
+    1034245222, 1056311756, 1049421916, 3186716727, 1027578547, 1033514613, 1050904216, 1023433328,\r
+    1053224405, 3190993738, 1049792849, 1040263798, 3200408458, 3174788296, 1040909677, 3184933853,\r
+    1034801299, 1056205315, 1048740389, 3185945367, 1027096001, 1033518483, 1050911102, 1023525341,\r
+    1053166523, 3190866728, 1049843228, 1040262875, 3200418679, 3173290273, 1041179054, 3184843676,\r
+    1034700573, 1056224759, 1052889451, 3176787866, 1033254425, 1028869836, 1048572213, 1029353719,\r
+    1052666657, 3193738664, 1052763995, 1046318562, 3202334486, 1027901893, 1034301420, 3174503463,\r
+    1017900318, 1053767903, 1049600826, 3186785523, 1027690261, 1033511426, 1050939484, 1023463786,\r
+    1053234294, 3190967774, 1049779951, 1040264022, 3200404486, 3174932263, 1040909628, 3184957422,\r
+    1034902337, 1056199452, 1054747671, 1048556656, 1038104318, 1049578907, 1042091268, 1043216411,\r
+    1048962383, 3203133199, 1060771770, 1048595059, 3200929790, 1050798585, 1054344707, 3196602082,\r
+    1040890332, 1053046357, 1055314630, 1037007426, 1044627343, 1037030715, 1044562077, 1023130230,\r
+    1051007002, 3199216663, 1055861620, 1045085893, 3204442143, 1043629937, 1047882651, 3190452213,\r
+    1045815687, 1052791152, 1048788442, 3185844267, 1020147462, 1035591326, 1051759383, 1018915504,\r
+    1053207216, 3191072651, 1050002662, 1037627062, 3200377532, 3172064120, 1043531622, 3185416242,\r
+    1034484760, 1056201486, 1053144311, 1046505694, 1043580973, 1048003100, 1044329971, 1040235301,\r
+    1050105113, 3201697133, 1059079422, 1040566911, 3200435763, 1051398765, 1054941283, 3197659688,\r
+    1044411666, 1052736963, 1052315481, 3177696990, 1030821663, 1024453082, 1048601381, 1029482796,\r
+    1052795162, 3192963814, 1052760199, 1045368875, 3202081594, 1028069864, 1037530343, 3171413960,\r
+    1022205153, 1054253923, 1048740611, 3185946228, 1027103046, 1033519507, 1050909715, 1023526061,\r
+    1053166038, 3190867119, 1049842451, 1040262775, 3200418635, 3173294269, 1041182263, 3184843374,\r
+    1034701044, 1056223654, 1054946951, 1040402333, 1044992385, 1032812002, 1044543342, 1026727805,\r
+    1050973261, 3200131301, 1056597488, 1044450159, 3204433702, 1044198874, 1048575831, 3191577062,\r
+    1046335570, 1052801722, 1054347662, 1016360477, 1002906328, 1042447931, 1046642803, 1020164943,\r
+    1051013950, 3197183318, 1053269336, 1040168883, 3201511433, 1039991075, 1041241310, 3188775012,\r
+    998590031, 1052781052, 1048801965, 3185321191, 1025880319, 1033672879, 1051588219, 1023545455,\r
+    1053096843, 3191188872, 1049970202, 1040042984, 3200388753, 3171548301, 1041474719, 3184522763,\r
+    1034274156, 1056306627, 1048803738, 3185303679, 1025916459, 1033671493, 1051589245, 1023550302,\r
+    1053095205, 3191205518, 1049972744, 1040056530, 3200390051, 3171535558, 1041428489, 3184459050,\r
+    1034253166, 1056309954, 1048741022, 3185945886, 1027095312, 1033521027, 1050907722, 1023542225,\r
+    1053165405, 3190861107, 1049842370, 1040262637, 3200418788, 3173301900, 1041186166, 3184842760,\r
+    1034706339, 1056224067, 1053869342, 3127512505, 1024996818, 1043990911, 1047459464, 3161285106,\r
+    1051222430, 3196783860, 1053042619, 1040807468, 3201820065, 1036247490, 1038177433, 3192238802,\r
+    3173248855, 1052807282, 1048803978, 3185303758, 1025907683, 1033672508, 1051583682, 1023551349,\r
+    1053095313, 3191206554, 1049972348, 1040052672, 3200389924, 3171538479, 1041442877, 3184463777,\r
+    1034257469, 1056310231, 1053099215, 1048580319, 1048546298, 1036050993, 1044195755, 1042029972,\r
+    1050802387, 3200684577, 1056967500, 1032944341, 3200728736, 1048480881, 1053911185, 3199168533,\r
+    1045044239, 1052859716, 1053139253, 3173608426, 1040070117, 1040375963, 1048481674, 1006215897,\r
+    1052039741, 3195487250, 1052937466, 1046147773, 3202436649, 1032550147, 1029804498, 3183157896,\r
+    3155508970, 1053178710, 1048788660, 3185845839, 1020139252, 1035596246, 1051757084, 1018911059,\r
+    1053207294, 3191072447, 1050001824, 1037626526, 3200377901, 3172073827, 1043533047, 3185415945,\r
+    1034488983, 1056200475, 1057050333, 1056977221, 1056977431, 1056958485, 1056977128, 1053883009,\r
+    1054227116, 1056977358, 1053350793, 1056963731, 1056977436, 1054248788, 1054168123, 1057020633,\r
+    1057035059, 1056977444, 1054276350, 1057037694, 1054104363, 1055709861, 1056977364, 1056997344,\r
+    1056999324, 1056995738, 1058913159, 1056999126, 1060093628, 1059669266, 1056969999, 1059844912,\r
+    1058553794, 1056995694, 1059760434, 1057642937, 1056996722, 1056997432, 1056995490, 1058035519,\r
+    1056997489, 1059948186, 1059115777, 1056970003, 1055263074,\r
+};\r
+\r
+uint32_t* get_knSmallWeightsArr_addr(void)\r
+{\r
+    return (uint32_t *)(knSmallWeightsArr);\r
+}\r
+uint32_t get_knSmallWeightsArr_size(void)\r
+{\r
+    return sizeof(knSmallWeightsArr)/sizeof(knSmallWeightsArr[0]);\r
+}\r
+void get_knSmallWeightsArr_version(char* ver, uint8_t len)\r
+{\r
+    memcpy(ver, NET_VERSION, len);\r
+}\r
+#endif //#ifndef Goodix_DSP_EXPORTS\r
+\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/algo_params/HR/04_EXCLUSIVE/HRNet_knTdfusionWeights.c b/code/sdk/drivers/peripheral/ppg/gh3x2x/algo_params/HR/04_EXCLUSIVE/HRNet_knTdfusionWeights.c
new file mode 100644 (file)
index 0000000..3af58bd
--- /dev/null
@@ -0,0 +1,103 @@
+#ifndef Goodix_DSP_EXPORTS\r
+#include "goodix_type.h"\r
+#define NET_VERSION "972f84"\r
+#define NET_SIZE 660\r
+const uint32_t knTdfusionWeightsArr[] = {\r
+       3212611938, 1065258623, 3617523296, 2162511128, 4131723467, 1527300999, 887990279, 3918715738,\r
+       2480362861, 3730469607, 1029234836, 2145880517, 3970754097, 2715757948, 4064179679, 526442413,\r
+       2145558227, 391976699, 1982203525, 436306985, 4069992803, 2536996647, 688713366, 233739891,\r
+       4003299118, 2792368142, 2049378544, 4212064112, 469195904, 3948908051, 1283651068, 2804756219,\r
+       3971016001, 2950776433, 4014961387, 980150967, 2146612193, 2378490593, 3740128150, 3368265385,\r
+       3196879020, 2358032584, 1376779692, 201965695, 4256264260, 3127921936, 1832646897, 738910080,\r
+       149328250, 3699668773, 2926913799, 1780024303, 29815781, 3270699898, 4159469820, 3882810571,\r
+       2147071461, 3535603583, 3422513411, 208933092, 1459739079, 417579508, 1836664083, 1950817094,\r
+       1208695137, 542735743, 1013215306, 4011265337, 756827264, 356291078, 579794208, 2180390667,\r
+       4147116677, 889161640, 4068518653, 2461269549, 2750951680, 1784487883, 1495652694, 566708571,\r
+       3513548648, 1499616800, 3771399551, 3472718809, 4252426725, 1675880140, 3655386865, 657127552,\r
+       990480146, 4068483382, 2434083370, 270870783, 3908377471, 4162091734, 545120498, 1826878974,\r
+       3942449430, 385548722, 4043026548, 4172312072, 3144619256, 2132144119, 3319262829, 3857802634,\r
+       4117666522, 1300285149, 2497506027, 3498104382, 2363970633, 3981463001, 791726732, 1423737806,\r
+       4138070857, 2616152426, 5599732, 962590379, 2146997472, 69802038, 554907288, 473202934,\r
+       613611815, 2365729042, 3202834563, 1055232450, 1053719888, 1059090724, 1057983160, 1057969890,\r
+       1059453812, 1058076083, 1065353216, 1054161397, 1057260716, 1059049657, 1060082832, 1061889815,\r
+       1055607626, 1060608896, 1058153065, 1057984122, 1058853086, 1059251060, 1062777282, 1059241884,\r
+       1060068278, 1059947500, 1060536208, 1058981408, 4218380337, 76645242, 92193286, 4286382364,\r
+       4222173552, 73206578, 61404453, 5087134, 130630953, 34882024, 195397210, 100948017,\r
+       55848049, 4282024932, 4252891870, 15052396, 4110485541, 5833540, 4128022358, 84887271,\r
+       27454738, 19672006, 268435456, 4290268269, 3222835871, 1075352223, 3219083795, 1071948612,\r
+       3847318036, 4149351411, 1042608640, 4241424389, 1169676, 41892885, 754781668, 4077415324,\r
+       1443004665, 64124697, 3424421139, 2033189440, 3625913566, 4279215449, 3157622331, 202604798,\r
+       1624076732, 2366241729, 635677627, 144893213, 2365607717, 271374087, 415334333, 3554714847,\r
+       3613490983, 4251584762, 908457727, 4174838269, 34920466, 4201466639, 2943439845, 220969796,\r
+       3934219339, 4262693618, 2057455500, 2402427857, 3214281534, 1066721064, 1063059484, 1059221280,\r
+       1058618575, 1057029081, 1065353216, 1062902409, 268435456, 100614101, 4119414, 45803078,\r
+       172138338, 139002063, 3232098395, 1084614747, 0, 1093498247, 2139035010, 360754955,\r
+       3892412284, 1786781818, 32792, 3205643615, 1058085092, 1056665721, 1056607902, 1052747214,\r
+       1065353216, 1059130712, 1054818331, 39734082, 4958179, 99819138, 4290807485, 219101839,\r
+       268435456, 3211494812, 1064011164, 0, 1069137558, 1309798250, 892473216, 2160972874,\r
+       3478204976, 612401338, 644545293, 4215293055, 92337285, 527234768, 2149267420, 461360869,\r
+       47911167, 332693540, 1655763692, 2150087757, 1388683645, 3548369792, 312037621, 2148552851,\r
+       3034586709, 2065326208, 192945120, 684379027, 2131759574, 690709404, 1048608638, 643168780,\r
+       3712948484, 3916726482, 3934281964, 2150839532, 4253010515, 61762815, 667332735, 2214195340,\r
+       1896503424, 3209498059, 1061909423, 1059568812, 1059914863, 1060362191, 1059743562, 1049970827,\r
+       1059229476, 1054063820, 1036700918, 1065353216, 1056876281, 1057223109, 1064236493, 1042844160,\r
+       1061310954, 1040019615, 1043433319, 1054712508, 1064020964, 1058532813, 1059921160, 1056477006,\r
+       1058117930, 1055425540, 1062810102, 37046165, 26912831, 38633761, 192615279, 4057022527,\r
+       260426158, 4174981607, 16338171, 172007841, 60254168, 132512852, 159680009, 153958387,\r
+       27668950, 35015901, 10283278, 4026531840, 4276553097, 4150136022, 4277211435, 113051432,\r
+       4277010931, 176798831, 11770706, 3209451696, 1061968048, 3217396375, 1073235696, 0,\r
+       1075216046, 2589542181, 4130832428, 1769483067, 536147731, 1812325179, 4218569462, 3886785318,\r
+       111139857, 2136068932, 4246729745, 1138602473, 4199765479, 66251813, 167772955, 654956026,\r
+       268790271, 554827504, 2130907144, 1409092038, 201424855, 3855612635, 251203096, 3689880391,\r
+       15517027, 3216946354, 1069365065, 1056224245, 1057011242, 1065353216, 1059493660, 66752937,\r
+       43823882, 4286504935, 268435456, 3233157097, 1085673449, 0, 1087817967, 2155869080,\r
+       3865078543, 1863286912, 3199191604, 1051617952, 1064200395, 1064806055, 1065353216, 1061995188,\r
+       202397346, 88436791, 268435456, 4231180105, 3208254580, 1060770932, 0, 1063501116,\r
+       2149656320, 2140860138, 2475332224, 2149451784, 2999943421, 3186348159, 1397718988, 357203980,\r
+       2151392567, 3262021590, 2163153126, 3498095116, 2148458943, 3672342716, 3390996725, 2148861256,\r
+       3210841781, 1063242648, 1057702199, 1056434892, 1060328997, 1058650920, 1064803264, 1058061423,\r
+       1055484575, 1048649563, 1048732415, 1060605520, 1054827205, 1061463810, 1059535748, 1064123227,\r
+       1050558390, 1065353216, 39125836, 8308965, 268435456, 4196329345, 120011066, 178151569,\r
+       4120159351, 30903888, 96699096, 47082552, 128482097, 137204766, 41517027, 209572119,\r
+       100585998, 4218278974, 3208645219, 1061161571, 3212574289, 1057583986, 3101417194, 1910704255,\r
+       671415072, 3781349858, 3809014548, 3489075995, 76872203, 562046730, 3974351119, 2566323404,\r
+       111628873, 3925342231, 25204455, 133891543, 4026718202, 123141, 117113948, 3792179709,\r
+       4009753615, 622197517, 4261474305, 2150043818, 138018824, 267325439, 3891386769, 371328136,\r
+       3876063781, 70178823, 176217477, 3574661077, 3658874068, 3774877275, 316992697, 4091661604,\r
+       3997008078, 3239695623, 3744413510, 209700031, 368514030, 3584890339, 3775735330, 1124872214,\r
+       522855590, 3058694370, 4196544813, 1861159807, 858331476, 154586635, 4227858600, 4127195059,\r
+       4211086363, 336460827, 4155702783, 17554304, 253238836, 4111139577, 301274386, 4175134974,\r
+       3220578817, 2281509384, 2837587698, 2133719409, 4024891079, 3849053191, 2339767003, 3908561175,\r
+       99408813, 4131449622, 2752120850, 793885212, 864068551, 2937064421, 2989834508, 1865153543,\r
+       333765581, 25151516, 3154228756, 3810464800, 3679143141, 41934025, 3860207403, 4022778355,\r
+       3788257284, 3189838290, 636283015, 3644194268, 3875797538, 2015765631, 728899429, 405248445,\r
+       4067389132, 3796898541, 875697669, 4007587113, 206145663, 4180940073, 3206335898, 1058771967,\r
+       1051744912, 1056748872, 1064885359, 1065353216, 1053842087, 1055410824, 1058972379, 1053415483,\r
+       1059904337, 1060228162, 1051466587, 1044711996, 1051976878, 1050109657, 1049776781, 1049085545,\r
+       39125836, 8308965, 268435456, 4196329345, 120011066, 178151569, 4120159351, 30903888,\r
+       96699096, 47082552, 128482097, 137204766, 41517027, 209572119, 100585998, 4218278974,\r
+       3208645219, 1061161571, 3219098210, 1066109165, 0, 1068318313, 41932027, 4059443515,\r
+       1677903092, 335291124, 4108645116, 31489797, 3842633475, 1392184594, 343887112, 48696183,\r
+       537368838, 755713804, 4201609210, 340980351, 1173430071, 873352969, 3209216526, 1061630090,\r
+       1060547205, 1065353216, 1061679052, 1060891602, 161590128, 268435456, 16818885, 4074195822,\r
+       3209148838, 1061665190, 0, 1058811013, 2192736105, 523206570, 1694400383, 3203421606,\r
+       1055814907, 1060445619, 1057678818, 1065353216, 1061395905, 4026531840, 261082239, 4102204708,\r
+       153547185, 3199029727, 1051546079, 0, 1047340345, 3484858496, 3208897370, 1061313427,\r
+       1065353216, 268435456, 3195868160, 1048384512, 3189408565, 1019949519, 1050158899, 3439443480,\r
+       2150045672, 197595717, 3194796882, 1047192027, 1065353216, 268435456, 3195868160, 1048384512,\r
+       3196364223, 1049228302, 3201412083, 1049498757,\r
+};\r
+\r
+uint32_t* get_knTdfusionWeightsArr_addr(void)\r
+{\r
+       return (uint32_t *)(knTdfusionWeightsArr);\r
+}\r
+uint32_t get_knTdfusionWeightsArr_size(void)\r
+{\r
+       return sizeof(knTdfusionWeightsArr) / sizeof(knTdfusionWeightsArr[0]);\r
+}\r
+void get_knTdfusionWeightsArr_version(char* ver, uint8_t len)\r
+{\r
+       memcpy(ver, NET_VERSION, len);\r
+}\r
+#endif //#ifndef Goodix_DSP_EXPORTS\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/algo_params/HR/04_EXCLUSIVE/HRNet_knWeights.c b/code/sdk/drivers/peripheral/ppg/gh3x2x/algo_params/HR/04_EXCLUSIVE/HRNet_knWeights.c
new file mode 100644 (file)
index 0000000..5309088
--- /dev/null
@@ -0,0 +1,494 @@
+#ifndef Goodix_DSP_EXPORTS\r
+#include "goodix_type.h"\r
+#define NET_VERSION "9b33ee"\r
+#define NET_SIZE 3785\r
+const uint32_t knWeightsArr[] = {\r
+       0, 1065353216, 1434415440, 3351367097, 3203343047, 3996637372, 753911254, 2138535512,\r
+       84213308, 16515587, 16711937, 67044610, 1274795660, 4063526733, 89448655, 1604838906,\r
+       3570273057, 3673628519, 4178592570, 4096032991, 748012506, 2630870016, 1532910975, 3671764372,\r
+       3871288544, 3676367322, 251191529, 2071951937, 100925011, 4277928708, 4294836481, 50202112,\r
+       1667971993, 215992283, 3754268656, 3129011197, 2549019357, 1585404863, 4025365306, 3946244060,\r
+       4141211634, 3267549393, 1008870735, 4261205631, 4191102728, 3306487038, 587069927, 689579873,\r
+       1131577175, 593414942, 1906305798, 3307682902, 1753164268, 3084272421, 3460633505, 906604490,\r
+       163888085, 1769308007, 85075763, 219799553, 519377423, 3422422795, 3598761530, 591288368,\r
+       775832607, 1429211402, 1027740691, 2055175477, 134480222, 33358854, 16974852, 50333696,\r
+       470619446, 660370489, 2138884607, 704002654, 3792108561, 33701759, 3822849123, 3927428072,\r
+       281737460, 3992910321, 668725, 960800107, 494948162, 2924229939, 874589993, 1731137718,\r
+       3859627117, 4264919758, 897635300, 2713708809, 3433244799, 3924800895, 3754496213, 3690391271,\r
+       98691565, 1333746616, 4008049886, 3791379452, 3235514612, 3641249263, 2138927963, 151454264,\r
+       67109892, 16974596, 67044866, 605963391, 3993224586, 3921497080, 3376352731, 621993445,\r
+       570493056, 83754595, 4244635909, 16909317, 4261675515, 67249257, 721280, 151062265,\r
+       4261675006, 50396167, 536216704, 50265706, 4244635908, 16909315, 4261675516, 2138928985,\r
+       151520060, 83887364, 17040388, 50267906, 3196109652, 101578890, 182519042, 3959425282,\r
+       4278911494, 519110528, 50199663, 4227858692, 16909315, 4261675771, 673202047, 67895436,\r
+       167576827, 4211276800, 16711431, 472335659, 16810181, 4203354119, 2518352120, 336264693,\r
+       1141882299, 32868991, 228073983, 3273784573, 316932108, 1245525888, 150800247, 50200584,\r
+       4228188682, 4244898298, 3205400190, 1057843569, 1051880702, 1059676744, 1049259402, 1060052437,\r
+       1055020755, 1057827188, 1052907982, 1049730549, 1065353216, 1057459505, 1050478146, 1060210126,\r
+       1052574825, 1057304205, 1059726057, 1063639454, 1056580671, 1055525787, 1060223832, 1051350660,\r
+       1058004196, 1051071279, 1062226207, 1064255926, 1062626364, 1057282324, 1055887615, 1062951340,\r
+       1062360791, 1059729071, 1060067346, 1057731230, 9161327, 10526901, 43422303, 9485563,\r
+       41803343, 4294635580, 4292301081, 4274504488, 4195907515, 4219429007, 4288203897, 4026531840,\r
+       30825373, 4294757832, 4166827529, 46857534, 4198791116, 4262733151, 118893346, 171801131,\r
+       4294564035, 25526358, 4294787832, 8983822, 10268871, 4292587228, 158000286, 13071751,\r
+       5889193, 4242993919, 4887071, 4284791625, 3219083317, 1071599669, 3217134032, 1074269162,\r
+       2339510357, 88873257, 307413200, 2898794811, 4092285364, 1026044696, 1025972272, 595650864,\r
+       3196990560, 1049434103, 1065353216, 268435456, 3182844497, 1035360849, 0, 1054323930,\r
+       8352613, 3210990908, 1063390610, 1065353216, 268435456, 3163181674, 1015698026, 0,\r
+       1049599547, 2155839359, 2139062143, 2155839360, 2155904896, 2139062144, 2139062143, 2139127679,\r
+       2139127679, 3213540494, 1065985813, 1057473554, 1046078985, 1038063497, 1052024304, 1062027445,\r
+       1050042712, 1055203246, 1060185951, 1039872910, 1011210069, 1052894683, 1058990529, 1060836525,\r
+       1049612578, 1019225221, 1052987007, 1018348850, 1049129878, 1058045751, 1065353216, 1049146658,\r
+       1052832425, 1047529212, 1056047898, 1040430600, 1049504790, 1045728632, 1034072413, 1056028951,\r
+       1055569312, 1063279769, 1054760983, 2675335, 4279234232, 159966472, 26495218, 47519821,\r
+       4269580843, 4286472679, 4268959478, 4192771977, 4136174506, 4256190768, 4048039037, 37488583,\r
+       4265867410, 4150755620, 3243417, 4209197714, 4255026235, 167212860, 244707265, 4262454931,\r
+       4231277358, 4263575242, 4210334825, 4271573380, 4261256193, 268435456, 4279326833, 4255241798,\r
+       4275865985, 10400569, 4239275707, 3221055281, 1073571633, 3199607868, 1059150472, 0,\r
+       1073986285, 3523547710, 492769315, 3631283158, 3623489547, 97218291, 488975376, 1023610933,\r
+       293633295, 3372683323, 897519912, 3628005334, 3355316757, 568093940, 605038098, 388109078,\r
+       366497565, 3214867883, 1067302832, 1061394933, 1065353216, 4248330033, 4026531840, 3210004081,\r
+       1062520433, 0, 1081256487, 3373367076, 32726, 3220023190, 1072417863, 1065353216,\r
+       1055355484, 4026531840, 4232649325, 3183036248, 1035552600, 0, 1087045902, 3347037567,\r
+       2138013442, 1182775423, 2135064326, 2136834043, 2131197567, 729776071, 2150072107, 2132705046,\r
+       2135392277, 2137709439, 2152038219, 3984555800, 2131787745, 377454695, 863993471, 3217283376,\r
+       1069699454, 1057712315, 1045552883, 1060285497, 1042191652, 1057697333, 1051273551, 1063050070,\r
+       1060025580, 1058489437, 1040039088, 1058827350, 1045998986, 1054705396, 1053634695, 1039585905,\r
+       1057402790, 1047376809, 1062204734, 1054315075, 1055785080, 1051511512, 1059948804, 1061866074,\r
+       1062200059, 1064458341, 1054806373, 1061681649, 1065353216, 1059313265, 1060591972, 1046683460,\r
+       1064059637, 4266030383, 4209406849, 185817147, 4226083433, 4166288488, 4167548973, 4243454620,\r
+       157855982, 4256885829, 4239438983, 4234790590, 4190665592, 180042663, 4212531041, 4151507061,\r
+       4274908273, 4233993977, 4239727313, 4229694039, 268435456, 4233083733, 4234193284, 4236595608,\r
+       9145795, 4246362324, 4230425104, 231464088, 4251256872, 4267769565, 4263176546, 4187261452,\r
+       4234519177, 3221647262, 1074163614, 3217060075, 1090861692, 0, 1091707269, 1040741947,\r
+       1048808124, 1057711802, 1032713374, 1045761609, 1033968854, 1056653562, 1030238034, 3190596828,\r
+       3175940054, 1045915392, 1049372314, 1042353611, 1024005112, 3172578050, 3166062809, 1009918109,\r
+       3189752244, 3186697718, 3185900458, 3188332162, 3190607857, 3197900674, 3204666439, 1044012262,\r
+       1033742925, 1018605985, 1007559260, 1035801005, 3188154740, 3186467670, 3184812311, 3189707105,\r
+       3191670656, 3197298679, 3203390151, 1026002027, 1052768620, 1054690950, 1047520794, 1053416749,\r
+       1058270736, 1048731709, 1057097861, 1053568205, 1058744234, 1059788196, 1057446300, 3187745983,\r
+       3191669450, 3180525627, 1048516154, 3183704082, 3177312500, 3193711037, 3188848784, 1050480169,\r
+       1034032306, 3153120472, 3181264804, 1037858285, 1050031708, 1050403289, 1049239935, 1051943237,\r
+       1058045308, 1046263180, 1055335407, 1051307245, 1056083494, 1054470285, 1048823404, 1033285919,\r
+       3180971794, 3190722769, 3179771536, 3181543508, 3192951105, 3196517277, 3190928796, 3190311018,\r
+       3194661358, 3192662829, 3198179307, 1041693229, 1050147675, 1052000771, 1048628471, 1045765490,\r
+       1056234451, 1044636996, 1054333560, 1048870424, 1053262673, 1048646443, 1033731710, 1047899334,\r
+       1034083791, 1021983732, 1030501642, 3181614850, 3181058350, 3175965499, 3193443094, 3182900056,\r
+       3184903704, 3196776671, 3204248758, 1031044787, 1032164170, 1033342675, 1046389031, 1036111006,\r
+       1051211915, 1052195343, 1045232482, 1040484036, 1022957741, 999050757, 1032297980, 1035018905,\r
+       1039173093, 1008567407, 1031219471, 1047153565, 1054079503, 1052703577, 1051770945, 1049469277,\r
+       1045379628, 1050180309, 1048072428, 1042869941, 1032280923, 3183770758, 1045196044, 1053938407,\r
+       1037410513, 3171056753, 3169942607, 1047597966, 1048009717, 1018768274, 3170413963, 3195849933,\r
+       1060031352, 1057968159, 3206056283, 1043641844, 3205067950, 1064874907, 3201285836, 1052950732,\r
+       3195851856, 3201177225, 3196024570, 3185962127, 3193669732, 3193630056, 3183205929, 3210556305,\r
+       3183698341, 3196503943, 3186374934, 3193745017, 3166043374, 3155191174, 3168556185, 3196181302,\r
+       3190350652, 3190738510, 3173742834, 3208835764, 3181527136, 3185178547, 3184672776, 3192990837,\r
+       3182316922, 3148877710, 3178591975, 1030589143, 1032638069, 1019960454, 3181643975, 3205500217,\r
+       3184980257, 1048691378, 3182148404, 3154478931, 3185306835, 3188795782, 3204092769, 3191233978,\r
+       1040955888, 1037969419, 3180255434, 1041176333, 3179735109, 1051016867, 3178002427, 1030626596,\r
+       3185747051, 3192677626, 3177896292, 3190197211, 1043168692, 1036803373, 3181368042, 1041076601,\r
+       3182896773, 1055883899, 3184938154, 3173189715, 3181700490, 3180218114, 3179472731, 3193605478,\r
+       1050008406, 1044239490, 3183168768, 1054950031, 3179079157, 1057706757, 3177159222, 1047048191,\r
+       3172427695, 3181378070, 3182211528, 3179308287, 1049247720, 1047003074, 3187948517, 1058058382,\r
+       3184595436, 1053255558, 3183047827, 1047806870, 3163086692, 3183113712, 3172847479, 3188336851,\r
+       1052968218, 1051150232, 3184804919, 3203456545, 3180339830, 1054982198, 3175466481, 1046553641,\r
+       3175040933, 3184722079, 3179450188, 3178610927, 1053873814, 1050698090, 3182624197, 3193831263,\r
+       3181136551, 1054367580, 3179056051, 1043898042, 3183333077, 3182470569, 3177211587, 3187353615,\r
+       1053152539, 1051499990, 3181028841, 3197813164, 3176909008, 1057388017, 3173917452, 1051836299,\r
+       3191507571, 3186073975, 1025832471, 1031965039, 1057274332, 1057347839, 3184023873, 3195393259,\r
+       3183170660, 1060070660, 3182975462, 1050487678, 3188109676, 3185711351, 3161210356, 1034084290,\r
+       1059804817, 1056323207, 3182014578, 1046061682, 3180555569, 1064843759, 3178392758, 1049634804,\r
+       3187719019, 3192537479, 3167469516, 3191320000, 3182980979, 1044964981, 1041456033, 1047374599,\r
+       1041595198, 1037313357, 1033306300, 1024480654, 1032790860, 1048600022, 1045954024, 3200623530,\r
+       1019505875, 1049469523, 3191669879, 3205469337, 3186583315, 3181332934, 1046748065, 1032207285,\r
+       3177452673, 3184320441, 1058176418, 1051417490, 3187638788, 3117734480, 3174910971, 1027421206,\r
+       3190180579, 1056081058, 1057202963, 3177663057, 3160609525, 3183518831, 3174328406, 3185607243,\r
+       3186459790, 1057245952, 3186381233, 3187139368, 3190972046, 1037829684, 3190284786, 1049593941,\r
+       1058530423, 3191403278, 1055592458, 3189714807, 3180893474, 3181102009, 1055449327, 1063258845,\r
+       1056136942, 3167842590, 1054320211, 3182810143, 3166418165, 1030853238, 3204622244, 3199271999,\r
+       3204566016, 1050841306, 3191822570, 1046551196, 3184967600, 1037010493, 3179332797, 3194654507,\r
+       3180103381, 1032481598, 3189538908, 3180491574, 1049969399, 1045657024, 3181186685, 1048356893,\r
+       1042221946, 1032905461, 1050114529, 3186763100, 1054397589, 3188975097, 3204638701, 3184628652,\r
+       1037439625, 3173254814, 1024481162, 1041413325, 1031331296, 1034649889, 3167282767, 1033677963,\r
+       1037553638, 3179092246, 1033697483, 1020911384, 1032249644, 1032276979, 1028762713, 3196597051,\r
+       1027339014, 1024914914, 1051514671, 1034061458, 1031035182, 3211526147, 1038553091, 3205934931,\r
+       3194666783, 1027709828, 3214455329, 3181431692, 3203316242, 1042821936, 1031959939, 1024000316,\r
+       1028534671, 1032107872, 1040044304, 3179803962, 1043675983, 1028744919, 1028234971, 1045830141,\r
+       3163262644, 1035818125, 3166261849, 1036268980, 1035705628, 1034562353, 1053479274, 1037732893,\r
+       1021811742, 1031381198, 1056178246, 1048580571, 1055229068, 1038703670, 1049060098, 1042061137,\r
+       1051211130, 1033684623, 3192957662, 3201836654, 1042427789, 1053926316, 3206135901, 1044916817,\r
+       1034206771, 1046955807, 1049545317, 3165108201, 1053192379, 1034975792, 1052183320, 1053753154,\r
+       1023173243, 1048832455, 3185011995, 1045590114, 1057254845, 3188981901, 1013092519, 1029237541,\r
+       1054086716, 3187771569, 3185217701, 1042750086, 3188804072, 1041604374, 1049927134, 1022942060,\r
+       1024631923, 3179764912, 1040853186, 1019472462, 3158753724, 1034891207, 1048301535, 1044211840,\r
+       3171553013, 1046698905, 3148492335, 1055788739, 3190339295, 1007295209, 3188597863, 3195495376,\r
+       1052712020, 1053797950, 3197442231, 1041743877, 3172704320, 3172195725, 1057556062, 3192993524,\r
+       3186963870, 3177820360, 1061323400, 1051485220, 1051692469, 3195517794, 1048889329, 1026634951,\r
+       1052091060, 3133018459, 3185371852, 3205486773, 3186906325, 1057055416, 3207236897, 1048587704,\r
+       3135030933, 1045620426, 1053645652, 3189216668, 1057779014, 1013727530, 1060631857, 1059140903,\r
+       3184525169, 1045210938, 3198814051, 1046523706, 3188856796, 3197090733, 1044499838, 1043086488,\r
+       3188295559, 3189119231, 3198145723, 1039256957, 3200838861, 1028108109, 3188495096, 3203123193,\r
+       1041457393, 3191989781, 1017873005, 3205396687, 3192883544, 3194094542, 1048585246, 1048818753,\r
+       3195966009, 3189467181, 3196762506, 3204427818, 3200205874, 3194567698, 1039191332, 3202780094,\r
+       3200570260, 3191075343, 1045206000, 3190584517, 1042222616, 1049591274, 3177720568, 1052236942,\r
+       1044239835, 1045064773, 3194622628, 1034487353, 1048553988, 1043225099, 1019134490, 1056819490,\r
+       3199648540, 1042934955, 1038278038, 1059455977, 1006654770, 3181609271, 1035414400, 1041441923,\r
+       1046414435, 3135475201, 3134476485, 1050066449, 3181380383, 1044745566, 3195726152, 3185927293,\r
+       1049502925, 3160803948, 3162418703, 1019170186, 3189069211, 1035592167, 1041406246, 1065223641,\r
+       1008329426, 1028780775, 3200470840, 3185682447, 1047635755, 1051888153, 3193833856, 1054240403,\r
+       1041236217, 3116049680, 1032514401, 1047222784, 1041524188, 3190081343, 1042864920, 1029844161,\r
+       1005680341, 3193761428, 3197040419, 3192512325, 3199600521, 3166633457, 1003977556, 3200726503,\r
+       3184423365, 3194188045, 1050736328, 3193652911, 3166549449, 1031915590, 3204639296, 3200021163,\r
+       3204580045, 1052159413, 3191833208, 1047558751, 4292108962, 134164, 3561029639, 4285107332,\r
+       3555395, 2679392255, 2963776, 4287069510, 2630183679, 3257663506, 971353599, 177114623,\r
+       4293714373, 1515358975, 4284447845, 4293646785, 4285356396, 3449447936, 6402724, 8435670,\r
+       4282741971, 4283540491, 4279130988, 4285103484, 3164057600, 728925800, 3819640244, 4279975668,\r
+       1392550838, 2042922855, 1587444015, 346987776, 4445796, 585683740, 1497859370, 1467875140,\r
+       4904816, 788058128, 4286565807, 2075145135, 2571108138, 1422713187, 3769958308, 2947135630,\r
+       1937958484, 1241507362, 4280600648, 1606071660, 14835700, 2158838620, 4282362151, 2661446837,\r
+       3625631363, 4186162175, 3068009983, 3130557574, 647890884, 3305129653, 1936457567, 1340790075,\r
+       1728019341, 242420761, 3032019535, 1358904117, 4289561938, 1920665404, 2333648785, 3513581506,\r
+       3345313886, 4282409214, 3297747534, 676921451, 1052843462, 3231804875, 1074211104, 1060469483,\r
+       3205819759, 1065035497, 3192095641, 3213994261, 1046405407, 1064990104, 1042954260, 1052670579,\r
+       1068150280, 3199980299, 1030877466, 1060891741, 3184776674, 1042928035, 3197565765, 3193352272,\r
+       3204975227, 1044222597, 1059917904, 3205023500, 3187044244, 1067348447, 3198214890, 3190186520,\r
+       3204988754, 1040062520, 1058909366, 3205174769, 3222203618, 1074646792, 3220510970, 1072901832,\r
+       3248582091, 1101098443, 1018083559, 1065353216, 1046913864, 1024364864, 1059059146, 1028138404,\r
+       1055840032, 1022409683, 1032787837, 1045492236, 1035283175, 1029494570, 1062667412, 1029423895,\r
+       1033025881, 1057649746, 1021767031, 1027952019, 1023742434, 995104170, 999624448, 1024059424,\r
+       1011026537, 1021158261, 1053153765, 1058093881, 1049687563, 1058630097, 1062636004, 1055230273,\r
+       1065353216, 1050104057, 1054471941, 1041521070, 1043220216, 1048964954, 1049682251, 1056292701,\r
+       1056091201, 1040088407, 1048776317, 1049372041, 1050097385, 1050886532, 1050384962, 1048959619,\r
+       1054379051, 1043470301, 2923539859, 1198650008, 1867107277, 629761685, 1650426669, 3249892939,\r
+       1719499939, 1382326660, 1419161170, 1786937488, 1600622231, 1974893679, 914713770, 1314031224,\r
+       1955963185, 2088902417, 1737704704, 1834703969, 2607455908, 1838789298, 1675271295, 1747953777,\r
+       1112581425, 1919726219, 1732278427, 2829084056, 1213843126, 3245642348, 2590358458, 2236101181,\r
+       407462786, 1402311248, 2509689484, 2846371440, 2307943305, 2607185256, 2966643054, 1068455067,\r
+       2843448714, 2829852031, 2238806425, 2592305, 589209279, 2476233487, 2325862555, 2863225691,\r
+       2242864997, 1971621023, 939544538, 2829863967, 2407313079, 1515238054, 2360517260, 2323871104,\r
+       3233917033, 2420784736, 3180946753, 2643027342, 1870365566, 1246254663, 2105038930, 1804435617,\r
+       1752136565, 2239263866, 2221040234, 1732857088, 1903581802, 1800791931, 1986550927, 2390980200,\r
+       1637513628, 1432717714, 1616804676, 1984673181, 2089186218, 2576587380, 2069960679, 2939439558,\r
+       2309444699, 1655123560, 1383625879, 1703388316, 2001709425, 2389528193, 1855945087, 1798064261,\r
+       1817653124, 2004325788, 977115518, 1599360632, 2057004157, 1979723641, 1901671545, 1352440733,\r
+       1832802705, 1648186996, 2290976934, 1901556847, 1701597313, 2928707697, 2291674968, 1765499551,\r
+       2340906126, 2624027800, 2291354784, 114520064, 1734313356, 980329611, 1164811663, 2120753742,\r
+       1991802756, 224360786, 1567717273, 2575605136, 776828786, 1769827993, 1788703870, 643987020,\r
+       1701345958, 1922718566, 3665848477, 1901549190, 2508554908, 257383484, 1601271194, 3248059246,\r
+       1751735363, 1852271948, 2307946367, 2004527251, 2340601319, 2240709260, 2893988022, 1819621944,\r
+       2610989932, 1488753536, 1887277969, 2791472257, 2408064961, 1989516690, 3616446860, 2376563668,\r
+       1987407228, 2758047110, 1922510227, 3182863489, 1330744709, 3195568473, 2777919141, 2492891013,\r
+       2340597450, 2188156927, 1765227888, 3381166727, 630174446, 1196141659, 2623224385, 2335581054,\r
+       9401716, 544504196, 1400148628, 2555855682, 2761388417, 1666999453, 1735545156, 2307295364,\r
+       1115125895, 1570791809, 2676842869, 1499159960, 1466715963, 1485797036, 1835359334, 2169857407,\r
+       2424870539, 1603305869, 1755068543, 1734833543, 2170711906, 2106139492, 1786736461, 2794104998,\r
+       1920317604, 3144461451, 1613925858, 1950247584, 2191688282, 2726262893, 1529579927, 2456062321,\r
+       2472964979, 1902878078, 1839566219, 2791603070, 1562133643, 2169922376, 2439540600, 1181171779,\r
+       1277165641, 2023977823, 1820895649, 2140450178, 2338885822, 2210569904, 1833929871, 1466798487,\r
+       1653107450, 2336328603, 2682023733, 2418234944, 18194551, 879081624, 1822995607, 2963297594,\r
+       1989837168, 1015447406, 1990956390, 2289529467, 935688073, 2327532901, 1937674612, 695700597,\r
+       1536857161, 2722978970, 1500226996, 2002209886, 2862965640, 2259048555, 2141876125, 2456526447,\r
+       2969590374, 1646549610, 2961667232, 2290190746, 1957340265, 935478856, 33974642, 1933081481,\r
+       2826592607, 2105556119, 1904780173, 1445399888, 1698330226, 2174252155, 2435930505, 1231451241,\r
+       1347985527, 1311836235, 1631151469, 772938779, 2263409, 2389002013, 2662836150, 1648629855,\r
+       1585538937, 3162220915, 525550928, 2674547042, 1870356936, 3126292649, 1822842790, 1570673689,\r
+       1532791159, 2152429420, 2270913187, 1954043728, 1923512959, 2269391711, 1736212863, 2071424627,\r
+       2354591866, 2005700730, 1619889795, 2035233113, 1735558552, 1399340369, 1116761213, 1751866717,\r
+       2088331144, 2253542523, 1920297333, 2442415470, 7768634, 1719227210, 1870164903, 2338224006,\r
+       2641254177, 1299452686, 1884607562, 4359330, 1519563371, 3331260723, 2946787189, 1332771950,\r
+       2171315244, 2525134218, 1985902716, 2813228112, 2978370166, 1231060335, 1851884071, 2212593530,\r
+       2055765598, 572591351, 2390789536, 1468169850, 2948500791, 2697501017, 996637018, 945171505,\r
+       1586063693, 2558697374, 1631160243, 1876449647, 3538333301, 1688102037, 2558295390, 2469531001,\r
+       1953004199, 2429270928, 2876465279, 2559339647, 2745868923, 2623051387, 1936091797, 2041032836,\r
+       2858827407, 1152687818, 1263032185, 1919585117, 2794830521, 4073744260, 4286038140, 1052082865,\r
+       1400835180, 2607524702, 1769233272, 2921689046, 1721012604, 2810015611, 2122620021, 2224204159,\r
+       2391124639, 1819170693, 1853663608, 2641065093, 1953986447, 2324270478, 2878373752, 1938390899,\r
+       1921230959, 2625407609, 1652588189, 2976160693, 1870298798, 2491975809, 2174587298, 2171499133,\r
+       2356056663, 2927659162, 2239656861, 2458490760, 2905220673, 2835395803, 2963295961, 4289108562,\r
+       2442888081, 374310224, 2287377218, 3217064869, 1788776594, 2741346178, 2089591733, 1552981323,\r
+       2221977019, 1537658808, 1988792739, 3310788451, 2576661713, 2576918878, 1687710593, 2543358847,\r
+       2140571549, 1816427140, 1318557795, 2877704628, 1919363641, 2843505205, 2825809315, 2341896063,\r
+       3049892983, 3266481559, 2424140437, 2323810435, 1868784776, 1701428591, 2393206416, 2440324200,\r
+       2088074381, 2257872815, 2459071376, 2006150822, 2426232441, 3211878748, 2306117275, 1446072286,\r
+       1518966142, 2037016656, 3033108631, 3098971550, 2712778707, 2460913278, 1988992939, 2442759567,\r
+       829386637, 1577096626, 2490461112, 2205249436, 3554846038, 2766961508, 1940479807, 2387756465,\r
+       2392673712, 2595371116, 4291921057, 4120602254, 3059774279, 2996404915, 2293327262, 2646813086,\r
+       4005146554, 2763352730, 2698166168, 2173206438, 2574476194, 2322830154, 2744417870, 1128964560,\r
+       2681188006, 2259526250, 897809824, 1599708277, 2559800203, 2895553371, 2677578368, 1518576234,\r
+       1198902373, 1648704341, 2189852296, 1186987851, 2472721522, 3198058137, 1526120221, 1952310362,\r
+       2087477632, 998110274, 1464316329, 1212441205, 2253544355, 2644606081, 2763691686, 1539096132,\r
+       2842525497, 2240574613, 2054774942, 2595197291, 2457625238, 2757579732, 2440204188, 2172224656,\r
+       2593221258, 2712887444, 2307556003, 2592770713, 2743364492, 2510060686, 2913236893, 3077670274,\r
+       2491840911, 2625930648, 2778424457, 2492758924, 3030085780, 1660924762, 2089986409, 1955566712,\r
+       2858389667, 2543879835, 2645005226, 2105723792, 2105716629, 1887867529, 2221508491, 2273673603,\r
+       2272832943, 1618049426, 3161179277, 2590143396, 2315209363, 2927587032, 3526597278, 1927880899,\r
+       3575356321, 2909503619, 2289863838, 2891176088, 3423641734, 2061963262, 3525220816, 2504476239,\r
+       2479327275, 2542759536, 2507578020, 3029443729, 2723533962, 1842393748, 3060824679, 3263656822,\r
+       1752064136, 1752270934, 2390857310, 1637054142, 2039980983, 2172689564, 1823516072, 2190244234,\r
+       1769976201, 1053725400, 2192942549, 1469678211, 872390820, 2058121697, 1918548621, 1100517071,\r
+       2023663280, 2762387379, 3228660598, 2237556858, 1570474885, 1706659731, 2040234984, 2794236781,\r
+       2791537282, 2456714115, 2122806688, 2205250197, 2778767722, 3131288951, 1596090774, 3445848989,\r
+       2521979452, 2456923456, 3819017095, 2304494138, 2333719149, 3232265097, 2860175956, 2020266112,\r
+       4004349583, 2405022227, 2315309206, 2676249988, 1957860518, 2948093044, 2341244287, 2072223639,\r
+       2474729265, 2021367937, 1755750551, 2712808017, 2020845187, 1403226449, 1700689259, 1822527884,\r
+       2999243058, 1587456672, 3096869574, 2356765323, 1098210675, 3465831845, 3556747568, 3111880076,\r
+       3030081369, 3535756130, 559763310, 3567740094, 3958735645, 2543815715, 2322562164, 1145872595,\r
+       2407040909, 1905367399, 2664719770, 2136317819, 1685296247, 1281332152, 1836998291, 2272492694,\r
+       1471908239, 2947124130, 2393343078, 1889513628, 2021753014, 2041150575, 1037801103, 2190901198,\r
+       2364829509, 1856736395, 2627247307, 2548050788, 1105374621, 2125569238, 2918087454, 2923717488,\r
+       1668642502, 2171054256, 1401649796, 1869052290, 1434935705, 2472449437, 2069522278, 1799526655,\r
+       1870303878, 1852728198, 1751148675, 2408354986, 2610851713, 3062604430, 2803214995, 1668526218,\r
+       2557504903, 3557077372, 2310785755, 2021817974, 1262967445, 2895485695, 2756342647, 3775188055,\r
+       1838259662, 1873185158, 2491836240, 2002803277, 2157414284, 1316715467, 3501954984, 1955365005,\r
+       2410967693, 2526369614, 1802919306, 2303429282, 2493031324, 2794815379, 2139398273, 2390716535,\r
+       2590953309, 1487895437, 2123736216, 2811208810, 1912178842, 2072940144, 2315205590, 2712832951,\r
+       2695601826, 3060716110, 551002795, 1852863144, 2085932925, 2892590439, 2055380100, 1793737927,\r
+       3245707401, 1922211994, 1937416610, 3563355747, 2054850215, 2020047754, 2575795576, 2052226432,\r
+       796366208, 2323747465, 3277906048, 2963380327, 2878054804, 3674930327, 2440932463, 1855171181,\r
+       2557731773, 2476116645, 3379336348, 4060479407, 2088282220, 2527102828, 2716890485, 2341111422,\r
+       1972414859, 2107342761, 2594804672, 2359274143, 1691833764, 2106558095, 2591585695, 2877912733,\r
+       2020573552, 2624160616, 2408095329, 1637322388, 1121426830, 2779275153, 1569552488, 1622113967,\r
+       3570511222, 1469937289, 4286151562, 3518233378, 1065580130, 701463940, 3167002002, 1736476598,\r
+       2793956225, 1634892013, 1955239046, 4152338326, 2710100318, 1954724496, 2656670302, 1716940170,\r
+       1452696197, 2675015824, 2191295123, 878870399, 2274730930, 1801424281, 3048579190, 2728949318,\r
+       2054331002, 1768005740, 2797223289, 868318864, 2690033581, 2164199315, 2455144815, 2021164381,\r
+       2360626789, 2858330677, 2829225820, 2791787937, 1504281235, 2724044488, 1787833066, 2612561041,\r
+       2709415006, 2975551128, 1836479383, 1941267528, 1738582960, 594123372, 2691736437, 4284183192,\r
+       3969616813, 2074048934, 2945541795, 2173610092, 1562939528, 2776651417, 2276166282, 1822528656,\r
+       3516623774, 2912463755, 1712423575, 2295843753, 2091877762, 2173080939, 2658953880, 1955690371,\r
+       2174398876, 2125979512, 1703314311, 2121886596, 2271465340, 1606444616, 3262466418, 2388286296,\r
+       1495434933, 1338738812, 1642844308, 2757773135, 2291753352, 2197328749, 1947752851, 3211298948,\r
+       2829041212, 1130525050, 1805535872, 1912567726, 2401328528, 2052047777, 2002687136, 2865012107,\r
+       3212668563, 2813574414, 1854121841, 2541780872, 2186504567, 2528891814, 2173339234, 2874772130,\r
+       2171517548, 1752276839, 2122277510, 2658374994, 2442097830, 2594013589, 1967521548, 1954839941,\r
+       2474928503, 1582948260, 2339664071, 2675867543, 2335812105, 2088988263, 2340518799, 1566474842,\r
+       2559540092, 2039583108, 1737271684, 2424604055, 2794289038, 2072863397, 1920640872, 2073923725,\r
+       1534698621, 1553044324, 2595704096, 2089379204, 1586007684, 1013514137, 2458094713, 2122347100,\r
+       1936691819, 2778285928, 2694681005, 1970177671, 2191737970, 2508092793, 2088669302, 2694400619,\r
+       1921874589, 1668517534, 1010265221, 2020503613, 2273142907, 2055956387, 2575599988, 2596365915,\r
+       2275167319, 2241897353, 2274260112, 2844290738, 1888126819, 2140008086, 3233702490, 2529338268,\r
+       1082228135, 1485800653, 1569626472, 1058394548, 2006680491, 745121704, 1748223908, 3297011859,\r
+       979489897, 67290322, 3904726155, 2726123614, 3315400781, 1939120560, 1185316983, 2674444181,\r
+       1482932856, 2408161148, 3282069340, 1720886455, 1620619387, 2040758378, 1853903469, 1938391679,\r
+       3113974655, 2239654786, 2626581646, 2038133910, 2089446486, 2408679304, 2526649237, 2088600437,\r
+       2442687371, 2962723980, 2007260265, 2274525563, 2762046855, 1068498828, 2372382088, 2004131227,\r
+       2879352428, 1906411910, 1585415049, 2640359799, 2390263200, 2055183251, 2740337530, 2556724120,\r
+       2808178325, 2287561307, 2404476084, 1736860567, 1989046396, 2257809533, 3079754125, 2555011715,\r
+       2575852423, 2842860412, 2818615669, 2607699068, 2306955910, 2926730890, 3383249046, 1319206567,\r
+       1789308798, 2340518784, 2793048190, 2486936943, 3261363797, 1721468030, 929343876, 2309985640,\r
+       2507427954, 2070315410, 2857775906, 1796976800, 3180417912, 1184731221, 3026096030, 2224808000,\r
+       1890018704, 2637262162, 2626463357, 2036495495, 870540178, 2258449642, 2207012483, 3707784559,\r
+       1586341005, 1620214655, 2909319818, 2775547648, 2125232535, 498689896, 2643480245, 1722587830,\r
+       2361221728, 1717734055, 2089188228, 2054260366, 2174322030, 1956025258, 2626119253, 628935314,\r
+       3744481946, 2022875019, 2039439498, 2455932243, 1765248394, 2778547867, 2443633920, 1865519993,\r
+       781081230, 2024060820, 2909164881, 1840843296, 1161332441, 1790294364, 3349374884, 1146643535,\r
+       1634188911, 2572974735, 2288994933, 1017629412, 2458095024, 2640991888, 1079273863, 647202162,\r
+       3448927899, 1837729431, 2691725282, 1215267687, 1685356161, 2088937103, 1404776125, 1450605680,\r
+       1567713735, 1837236437, 1431788647, 2274990753, 2108032686, 1857249900, 2389272674, 1434628741,\r
+       2205843573, 1687709073, 2123850422, 1954840215, 2931068046, 1820624004, 2373401976, 2640545669,\r
+       3184823398, 3902561316, 2898360269, 1636412537, 2527703730, 2757988952, 2359336565, 2186706321,\r
+       2088639375, 2520347286, 2776205386, 1650287332, 1941615737, 3430569565, 1566006183, 1261531776,\r
+       1314035455, 2009112184, 2927582558, 1348700446, 2932180621, 2383637911, 607424992, 1807067444,\r
+       1384554635, 935694921, 1450083487, 2089964917, 1768460191, 2474421437, 2037619395, 2174062962,\r
+       2489217409, 999392165, 2023327077, 2841810568, 13141875, 2627307376, 2372239483, 1115204236,\r
+       2996208222, 2121097363, 3165686099, 1785751442, 2305786754, 866940798, 2140432013, 2389405296,\r
+       2741012063, 2223006046, 2105440129, 1953793409, 1633653071, 2200490109, 2709813588, 1785379943,\r
+       2471138488, 1769115992, 1665432428, 3264477235, 2272564908, 2171433359, 2291124510, 1317441922,\r
+       1786262401, 2410998602, 1733386639, 2142334638, 2319122589, 2175509890, 1801621114, 1665588340,\r
+       3301415760, 2827713943, 2594974030, 1872932509, 2291363456, 2255589257, 1734888237, 2720701298,\r
+       2493075267, 2476838245, 1164928161, 2137493380, 1650491275, 2940353116, 3617561752, 2273207935,\r
+       4279267188, 2256966000, 1703182723, 1937512091, 2845549226, 2004248757, 861376111, 1599956839,\r
+       2288549775, 3255670665, 2708307809, 1418624655, 2192673901, 1886154643, 1669494145, 1850898832,\r
+       1787335560, 3711665509, 1566557828, 2236058800, 2443799638, 2288555329, 2008055165, 3863517301,\r
+       2208278067, 1504806283, 4286682244, 2645386023, 1921884002, 3714951851, 1953846294, 1804372895,\r
+       611931499, 1938665675, 2052751707, 2894366845, 1619876434, 1654222407, 2495119520, 2140678270,\r
+       2490599295, 1937472126, 3591460207, 2187230305, 2593418668, 2190514556, 1468969356, 1749649564,\r
+       2406179427, 2510654277, 1871362383, 2288152202, 1162832267, 1406305133, 2977727838, 1480106604,\r
+       293516861, 826452641, 2306642282, 2957657424, 1668257909, 2717859169, 2595958899, 1539668809,\r
+       2206698108, 3301610047, 2055440522, 1987932816, 3353198018, 3587089063, 1870998664, 1401738112,\r
+       1418360166, 3458041681, 2376435152, 2495914121, 3076085716, 1736996245, 1085479278, 1023742816,\r
+       1654108092, 2225776508, 3025949312, 3384517566, 2182888872, 572993457, 1466189238, 1960030384,\r
+       2692394409, 1518114158, 1799829645, 1006656615, 1689700987, 2524791700, 1688439969, 2983289374,\r
+       3046216079, 3392955285, 2103740826, 1667276195, 1889237365, 2185741903, 3229003402, 1332898170,\r
+       2197878329, 3477118857, 1988862077, 2152962436, 4066590327, 2149023151, 727930013, 659966830,\r
+       2126667379, 4103382330, 3219774434, 3014682191, 1968937139, 1014381677, 1282386345, 2026410086,\r
+       2106817906, 1702728843, 2910421904, 2088198499, 2021890206, 2492560255, 2423882906, 2308341360,\r
+       2154132100, 2373428047, 2056222587, 1938198927, 2303900830, 2022154383, 2038265187, 4152259839,\r
+       2809230502, 1853128617, 2156123717, 3012202391, 2643164292, 2153102265, 2240049778, 1937270897,\r
+       2773632359, 849063482, 835222642, 3109892030, 1200380206, 2751478303, 3215031653, 1283417965,\r
+       2152812196, 2466191245, 1972994964, 2847502689, 3027013730, 2001403928, 10652075, 1552602507,\r
+       2057894779, 2504748600, 130172617, 2714751333, 2123757939, 910168320, 2758173818, 2174681195,\r
+       2692765564, 3770053970, 833513460, 3712324596, 771739137, 473189025, 2593883219, 3604345154,\r
+       3158382248, 2481296128, 1065256855, 2307100399, 1407161344, 1465609552, 1504864151, 199163701,\r
+       3345152995, 2848729246, 2308793685, 1353497394, 3003366655, 1202597448, 665090224, 2353171936,\r
+       14198837, 122308985, 2626945144, 3775347847, 1184657841, 1671538794, 2446069298, 1483678039,\r
+       2353955489, 2693988434, 3363832059, 3853714554, 2291744602, 297323267, 2411314059, 295814266,\r
+       2593300896, 2826043511, 3030622610, 1852595102, 1857776449, 2207078911, 1669202029, 3579267955,\r
+       1903466893, 2574621552, 3366294388, 2524220302, 1802999886, 9800364, 2240252486, 2640987351,\r
+       617482796, 748688896, 443201676, 944146049, 5875888, 2537320616, 1535377527, 3865339767,\r
+       2525547887, 2161672509, 2592047548, 1218969488, 3114316672, 3077477249, 1379467132, 2171439990,\r
+       2522963849, 3533208666, 3718240952, 627743109, 1834195402, 2659534591, 427819168, 2859206523,\r
+       2208537978, 2170129661, 4287224624, 2188543227, 1988522046, 2258989480, 1619114941, 1381928448,\r
+       2507642259, 2387701716, 2945408901, 2382376394, 2177721141, 1131186524, 1634839447, 1768539279,\r
+       2173474156, 10008742, 4290142327, 2172489089, 1938591801, 529560047, 1986034836, 4280499086,\r
+       2324189030, 2253817502, 2141219839, 1971100034, 2023002749, 1834908810, 2137259989, 1213784500,\r
+       1202562421, 2938734490, 2415888009, 1888132737, 2105576829, 2158505103, 4286485098, 1568047990,\r
+       2221038229, 2176293074, 2123079806, 2121302015, 1471251778, 2490401669, 2107286694, 1401749378,\r
+       2089068421, 2491514475, 2005298813, 2231343980, 3849553814, 1654281285, 1801152877, 4286534531,\r
+       2105572214, 1753129283, 1820088675, 1838451531, 2667608818, 1856792157, 1889893561, 1787087237,\r
+       1973026684, 3009181821, 1688108964, 2005176214, 2030017097, 2807266163, 1987992191, 2276363334,\r
+       4285236103, 1871603573, 3197407115, 1414038386, 2004384653, 2290647807, 2806609539, 2539944582,\r
+       1803912058, 2205417365, 3313739829, 2507762052, 2286046097, 1090476679, 2088798588, 2222883971,\r
+       2021953146, 4285234825, 1048764852, 3179624586, 1041413909, 3196611729, 3160056282, 1058294519,\r
+       3192266532, 1042417098, 1010761724, 3192650422, 3183927810, 1038091820, 1057326481, 1045830840,\r
+       1055399649, 1043650942, 1030320479, 1023336164, 1047052367, 1049099471, 1001601523, 1042414314,\r
+       1018814770, 3186905562, 1010540119, 1045335974, 1042342790, 1037034855, 1042037839, 1033833564,\r
+       3154204117, 1042570138, 3159773721, 3164058967, 1033340210, 1029621896, 3177027435, 1015663978,\r
+       1029896658, 1029165993, 1023345062, 3169728338, 3176937547, 1034180599, 3178806156, 3168952431,\r
+       988423444, 3155271010, 991552443, 3191956971, 1035504033, 1024597960, 3180953889, 1025580518,\r
+       1037107555, 1007977363, 1035600952, 3177711927, 3170231252, 1037769082, 3176005292, 1002112056,\r
+       1020328972, 972013123, 3216729932, 1069150333, 3215606876, 1068036051, 3222555383, 1075071735,\r
+       1053550493, 1052162780, 1056523950, 1055869258, 1052827203, 1052008149, 1058268933, 1057659708,\r
+       1054250630, 1053248048, 1057206263, 1052317137, 1051770702, 1057372182, 1053192863, 1055285772,\r
+       1053573068, 1052248576, 1065353216, 1054294802, 1057419897, 1054164021, 1053064325, 1056336453,\r
+       1054066871, 1058033413, 1051657251, 1056687169, 1056397637, 1054302107, 1053760798, 1057538370,\r
+       1048343425, 1041001223, 1052696035, 1043649185, 1040037663, 1038680772, 1043445599, 1039703722,\r
+       1043664463, 1041394109, 1041158144, 1040437448, 1038595135, 1040157971, 1041043545, 1041449032,\r
+       1051341238, 1057667776, 1056281881, 1059436675, 1049325642, 1049876854, 1050756783, 1049021950,\r
+       1058842833, 1053474531, 1057516044, 1054748936, 1056340354, 1054836283, 1045521792, 1058759605,\r
+       1049302787, 1056329000, 1056346828, 1048950626, 1050166842, 1050477119, 1054109639, 1049030405,\r
+       1053645959, 1052505012, 1051608013, 1053253032, 1049664412, 1052581436, 1051749823, 1048586855,\r
+       1058958847, 1050862836, 1063364508, 1059108007, 1058595355, 1060008956, 1058385508, 1059916590,\r
+       1054916218, 1059525615, 1059441444, 1060023962, 1060570985, 1062587505, 1054091605, 1065353216,\r
+       3160297758, 1353799776, 2036341961, 4550520, 1211788872, 2711316360, 3096209523, 1534328933,\r
+       2221751929, 4289297992, 3931282906, 855606692, 1912637548, 2959036541, 1955876740, 2038938735,\r
+       2667599195, 2972719249, 983252850, 1505537896, 1533251441, 2667591582, 613836094, 3029165723,\r
+       3042705537, 2373688457, 1838711434, 851621272, 371439193, 4098836602, 1383145029, 2063535741,\r
+       1510670449, 3770851965, 2474867579, 1736547166, 2523751272, 3690995878, 1301633148, 576220329,\r
+       3501392005, 1760712555, 2627941830, 1516744042, 3160267164, 537641931, 651400533, 2945056689,\r
+       155742057, 2859817364, 2140893333, 2355232887, 2320105520, 2409862460, 3038082220, 3617695889,\r
+       1850900806, 4121961371, 2523293695, 3503540558, 3239724106, 4244654550, 2626948439, 2949821495,\r
+       1821616015, 1685628076, 1621360485, 2236983940, 771731087, 2556989080, 2509479027, 2023249066,\r
+       2642469504, 1461941906, 8486798, 2289272536, 2130697114, 2491913839, 2523960991, 3019887996,\r
+       1488508549, 1275108199, 2255652701, 4093737018, 1922814372, 12951164, 2677186450, 2086038408,\r
+       3169955775, 380922478, 1905508291, 2117012735, 3483936121, 6390851, 1969456619, 2723442612,\r
+       2708956559, 2032101772, 1703175272, 2172885503, 2238776433, 4279923615, 1452053834, 2428158930,\r
+       3932582052, 1952436099, 2006087289, 2471690202, 2028704660, 2591972997, 2055371879, 2606039102,\r
+       2396680583, 2069920650, 1719698579, 4286133137, 4285973101, 2082176158, 578117784, 2355665068,\r
+       4285658953, 2287631746, 1970546318, 1721343860, 2306382220, 2388925582, 1788543086, 1378261196,\r
+       8808133, 1537911634, 2726608528, 2034024231, 2298504055, 1518634111, 1854568329, 1617003899,\r
+       2220723592, 3380177368, 12611676, 2056692055, 2516568719, 2309395304, 2841678214, 3049698412,\r
+       2650786675, 1315082048, 3057419111, 4145445933, 3166868921, 306479489, 1906279070, 2089242367,\r
+       3271146180, 230978679, 1905903552, 2116551679, 620800843, 3278264959, 2743032946, 2340729419,\r
+       3262152491, 3439341979, 744752758, 1670680498, 2042018221, 885642882, 2308170883, 2559795456,\r
+       12865518, 2108997590, 1942940742, 2669618224, 2147458453, 2140239458, 2524355715, 3076663888,\r
+       2633399953, 1821017736, 1837011844, 4284954502, 2273220983, 1300467214, 3405807870, 2709491613,\r
+       3914969145, 2842402687, 2315282900, 1656324253, 983778712, 1871422851, 2106720111, 2507637158,\r
+       4164103090, 2041994731, 3657383338, 3634937826, 2792596480, 2476435375, 1633980057, 2138476424,\r
+       1333501440, 1783247949, 1480737150, 1269792853, 3934668006, 2979200999, 4129403812, 2239011824,\r
+       3970385810, 4073175784, 4280465354, 2256519913, 2106550528, 3783996545, 2859815119, 1737134214,\r
+       3984400895, 1453841391, 3660105143, 3011292122, 2019850240, 2575514495, 2476300446, 1887805315,\r
+       2525334817, 3480483984, 2399175831, 1239719269, 1819053385, 2808217713, 2041255322, 1368952179,\r
+       1952679559, 1650676847, 2170814636, 465225071, 2528601754, 1335731605, 2634068641, 2875087513,\r
+       2171347519, 3094314390, 4289235617, 1921884366, 1681959453, 2473025633, 1412902501, 905952358,\r
+       1735629642, 3027894378, 1585926284, 1654296421, 1786492741, 2873884778, 1014781580, 1787790434,\r
+       1827834982, 1837077101, 1786881058, 4279894637, 2291531971, 934241675, 2733667445, 3258727593,\r
+       1620479345, 1885508962, 2147514813, 1955697764, 3191812214, 1455263170, 1891140995, 2507440895,\r
+       2895749631, 3938206119, 1018015092, 2573755826, 1251383951, 1786351435, 1571618601, 3108330060,\r
+       4282255608, 3294675199, 3576313570, 702077402, 1677756029, 1164742502, 1881708068, 2040708456,\r
+       2056292444, 2441367162, 1612185760, 1335133815, 2865455359, 3063172265, 2590598386, 2958441894,\r
+       898812998, 2906277941, 5397310, 1802924085, 2002220544, 2040146308, 1841705600, 1686803046,\r
+       2387447090, 2124645273, 8024214, 2072613556, 2224785552, 2105773958, 2264957917, 1722258057,\r
+       2191230855, 2641524354, 2097184955, 1651927682, 2594664126, 3011471000, 2390175999, 2756139159,\r
+       3051177660, 750964655, 2588794222, 4280290735, 1165557516, 3072099906, 1047890260, 1537450288,\r
+       2365553081, 1688375439, 1855632295, 3574666379, 3578668220, 1759412698, 2710665381, 2256702463,\r
+       3548401151, 2648272850, 2506854310, 2323151061, 2805872865, 148242344, 3160798569, 2173674153,\r
+       4266005747, 3245259775, 3493345252, 902548443, 2039589216, 4285935739, 1940153489, 1904313466,\r
+       3233761195, 1540325569, 2365600235, 2053856190, 1806338202, 1653383534, 1953038190, 3208992365,\r
+       1648988515, 2740543843, 2533320277, 1655879525, 1864068904, 2930049152, 1604520085, 951698532,\r
+       3423950949, 2432659425, 156129749, 1738911734, 2264959347, 2289395848, 2407355493, 654114440,\r
+       2737795970, 2591392162, 2611309151, 603970467, 1690995595, 1737788263, 1818478714, 4279121255,\r
+       3202814259, 3217553773, 3187909186, 3216771390, 3214214851, 3222544924, 3204114129, 3207995268,\r
+       3191842931, 3217590705, 3183208382, 3224619640, 3227803247, 3192180385, 3207564607, 3217119308,\r
+       1032625267, 1037079029, 3192285273, 1059882233, 1056930330, 998777802, 1027990540, 3181607419,\r
+       1020200737, 1046400206, 3200174496, 1042078882, 1048889257, 1028259388, 1035131311, 1046529212,\r
+       1031897577, 3196121859, 3185132891, 1060700195, 1060082626, 3172207284, 3172180308, 3154621227,\r
+       1032524315, 1035998404, 1028799848, 1045135565, 1053452071, 1031839994, 3180527514, 1035362422,\r
+       1053335096, 3202109615, 1038695577, 1061658846, 1061616997, 1065992050, 1062813215, 3193672031,\r
+       1052928755, 3179389457, 3196265165, 1051964256, 1057981639, 1015669427, 1042273954, 3183139869,\r
+       3216875886, 1069295147, 3224460371, 1076885914, 3244580463, 1097096815, 1050335768, 1062858529,\r
+       1053888724, 1062113925, 1058844314, 1063881340, 1055899017, 1049715772, 1060392890, 1062819881,\r
+       1053851066, 1059855149, 1064880424, 1052341447, 1048680177, 1055731202, 1053087137, 1052851623,\r
+       1057311032, 1052648514, 1045574508, 1062211984, 1064737346, 1055290212, 1056894073, 1053993700,\r
+       1054895024, 1051309739, 1053158459, 1053964199, 1058560720, 1059324988, 1040814367, 1052270193,\r
+       1047479988, 1056284703, 1047245081, 1046856163, 1065353216, 1049491203, 1042329667, 1052634570,\r
+       1040468787, 1050012870, 1056295663, 1047559100, 1050647313, 1053266577, 1033795645, 1047087047,\r
+       1050940929, 1046135960, 1043529598, 1048902746, 1042888638, 1050723053, 1041773389, 1053409182,\r
+       1040654049, 1048995215, 1049563980, 1043007228, 1059891087, 1059899496, 1035474987, 1032736758,\r
+       1041276762, 1037061464, 1032305622, 1039942137, 1062917324, 1037938840, 1041417883, 1036713786,\r
+       1039549315, 1037987850, 1045253702, 1044297206, 1048240739, 1040650724, 1037212702, 1038234118,\r
+       1043275966, 1041474399, 1039802370, 1041667507, 1065353216, 1045145369, 1040711463, 1050590272,\r
+       1044001812, 1038780318, 1038173461, 1045178752, 1049165110, 1049023961, 1053493335, 3201465523,\r
+       1052835077, 1055373177, 1055018436, 1053037920, 1055626545, 3196953759, 1057466692, 1050694167,\r
+       3205793201, 1051427566, 1054939007, 3197686071, 3199453250, 1051260799, 1053734435, 3201961078,\r
+       1053611275, 1054244021, 1054102537, 1055075612, 1054462895, 3199966150, 1054977672, 1053527476,\r
+       3204495224, 1051812657, 1055122343, 3200055061, 3202402861, 1053888350, 1053438082, 3201806503,\r
+       1053265627, 1054383845, 1054202424, 1054866842, 1054602440, 3199679782, 1055586771, 1052876215,\r
+       3204764594, 1051584669, 1055266379, 3199664157, 3202207373, 1053855249, 1053735474, 3201961436,\r
+       1053610605, 1054243523, 1054102061, 1055076670, 1054462244, 3199966598, 1054976147, 1053527872,\r
+       3204494573, 1051812618, 1055122592, 3200056415, 3202403582, 1053889169, 1053733785, 3201960749,\r
+       1053610475, 1054243969, 1054102304, 1055076447, 1054462573, 3199966438, 1054976811, 1053527627,\r
+       3204495071, 1051812544, 1055123439, 3200055906, 3202403139, 1053888829, 1054071965, 3202878786,\r
+       1055370502, 1053385673, 1053334661, 1054538438, 1053556169, 3200545253, 1053570621, 1054349170,\r
+       3202204233, 1052859111, 1053362083, 3201935644, 3202947354, 1054728344, 1053757536, 3201969110,\r
+       1053614019, 1054241815, 1054100842, 1055078904, 1054460000, 3199974471, 1054963921, 1053531061,\r
+       3204487462, 1051814489, 1055072379, 3200063468, 3202406512, 1053892446, 1053486758, 3201554443,\r
+       1052852165, 1055356011, 1055005032, 1053196253, 1055604497, 3197149274, 1057462509, 1050742591,\r
+       3205787529, 1051427497, 1055000386, 3197952274, 3199592101, 1051291130, 1054050852, 3202993471,\r
+       1055976039, 1053415847, 1053338190, 1054572201, 1053582652, 3200538642, 1053475498, 1054367740,\r
+       3202068519, 1052803462, 1053338451, 3202015989, 3203044755, 1054751224, 1053735151, 3201960084,\r
+       1053609871, 1054243491, 1054101940, 1055076982, 1054462220, 3199967399, 1054975809, 1053527985,\r
+       3204494281, 1051812598, 1055123570, 3200056815, 3202403773, 1053888942, 1053477748, 3201807305,\r
+       1053255333, 1054388742, 1054207181, 1054869887, 1054607571, 3199683389, 1055650547, 1052931366,\r
+       3204760028, 1051585953, 1055265767, 3199667330, 3202208101, 1053853058, 1054071809, 3202826797,\r
+       1055350059, 1053390796, 1053340016, 1054578202, 1053562806, 3200551727, 1053332658, 1054352304,\r
+       3202008188, 1052880511, 1053667628, 3201708186, 3203013858, 1054732181, 1054072371, 3202825002,\r
+       1055337883, 1053412671, 1053364756, 1054560820, 1053586358, 3200527384, 1053413889, 1054325458,\r
+       3202051019, 1052892217, 1053649960, 3201688453, 3202984343, 1054704508, 1053483693, 3201503260,\r
+       1052841479, 1055367980, 1055014103, 1053105914, 1055619665, 3197034464, 1057465225, 1050712258,\r
+       3205791537, 1051427284, 1054956449, 3197820065, 3199490012, 1051270098, 1053485967, 3201492855,\r
+       1052839319, 1055369415, 1055015689, 1053085614, 1055621812, 3197012624, 1057465509, 1050707056,\r
+       3205791863, 1051427712, 1054950346, 3197782603, 3199476995, 1051267868, 1053293137, 3201760455,\r
+       1053038836, 1054392572, 1054191994, 1054789113, 1054594607, 3199658228, 1056365207, 1052148820,\r
+       3205025203, 1051335467, 1055361655, 3199446279, 3201657055, 1053148302, 1053736370, 3201962909,\r
+       1053611039, 1054243768, 1054102276, 1055075595, 1054462519, 3199965694, 1054976864, 1053527640,\r
+       3204495005, 1051812515, 1055120562, 3200055575, 3202403326, 1053888523, 1053448027, 3201379351,\r
+       1052841731, 1055364193, 1055008305, 1052939117, 1055618246, 3196842915, 1057466890, 1050676397,\r
+       3205794368, 1051425831, 1054892900, 3197671305, 3199443909, 1051255142, 1054060143, 3202816973,\r
+       1055303699, 1053469986, 1053424917, 1054513993, 1053647398, 3200468562, 1053572683, 1054258225,\r
+       3202135644, 1052912954, 1053664251, 3201628985, 3202914944, 1054635099, 1053733371, 3201960042,\r
+       1053611514, 1054243813, 1054102168, 1055076596, 1054462690, 3199966679, 1054975965, 1053527887,\r
+       3204494680, 1051812752, 1055122903, 3200056632, 3202403323, 1053889032, 1053487336, 3201561769,\r
+       1052853922, 1055354712, 1055004489, 1053206555, 1055603044, 3197162486, 1057462348, 1050745091,\r
+       3205786919, 1051427750, 1055005747, 3197961923, 3199606622, 1051293224, 1055333362, 1054214129,\r
+       1054501862, 1054213775, 1054214039, 1053356473, 1054211514, 1055311215, 1053382943, 1054213717,\r
+       1054486255, 1053410054, 1053432238, 1055327097, 1055328600, 1054468586, 1054213985, 1055325195,\r
+       1053491310, 1054214091, 1055309269, 1059999756, 1060083643, 1060079184, 1060083567, 1060083498,\r
+       1060261121, 1060084491, 1060018088, 1060276839, 1060083958, 1060080569, 1060222796, 1060226992,\r
+       1060012857, 1060005864, 1060075233, 1060083872, 1059584441, 1060231862, 1060083662, 1060019057,\r
+       1056956615,\r
+};\r
+\r
+uint32_t* get_knWeightsArr_addr(void)\r
+{\r
+       return (uint32_t *)(knWeightsArr);\r
+}\r
+uint32_t get_knWeightsArr_size(void)\r
+{\r
+       return sizeof(knWeightsArr) / sizeof(knWeightsArr[0]);\r
+}\r
+void get_knWeightsArr_version(char* ver, uint8_t len)\r
+{\r
+       memcpy(ver, NET_VERSION, len);\r
+}\r
+#endif //#ifndef Goodix_DSP_EXPORTS\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/algo_params/HR/04_EXCLUSIVE/heart_net_org_dll.c b/code/sdk/drivers/peripheral/ppg/gh3x2x/algo_params/HR/04_EXCLUSIVE/heart_net_org_dll.c
new file mode 100644 (file)
index 0000000..c195c7a
--- /dev/null
@@ -0,0 +1,41 @@
+#if (_WIN32 || _WIN64) && !defined(Goodix_DSP_EXPORTS)\r
+#include "heart_net_org_export.h"\r
+void heart_net_dll_param_init()\r
+{\r
+       goodix_win_params st_dll_params_in;\r
+\r
+       st_dll_params_in.knBasicWeights.weight_arr = get_knBasicWeightsArr_addr();\r
+       st_dll_params_in.knBasicWeights.para_size = get_knBasicWeightsArr_size();\r
+       get_knBasicWeightsArr_version(st_dll_params_in.knBasicWeights.net_version, VERSION_SIZE_MAX);\r
+\r
+       st_dll_params_in.knWeightsSmall.weight_arr = get_knSmallWeightsArr_addr();\r
+       st_dll_params_in.knWeightsSmall.para_size = get_knSmallWeightsArr_size();\r
+       get_knSmallWeightsArr_version(st_dll_params_in.knWeightsSmall.net_version, VERSION_SIZE_MAX);\r
+\r
+       st_dll_params_in.knWeights.weight_arr = get_knWeightsArr_addr();\r
+       st_dll_params_in.knWeights.para_size = get_knWeightsArr_size();\r
+       get_knWeightsArr_version(st_dll_params_in.knWeights.net_version, VERSION_SIZE_MAX);\r
+\r
+       st_dll_params_in.knConfNetWeights.weight_arr = get_knConfNetWeightsArr_addr();\r
+       st_dll_params_in.knConfNetWeights.para_size = get_knConfNetWeightsArr_size();\r
+       get_knConfNetWeightsArr_version(st_dll_params_in.knConfNetWeights.net_version, VERSION_SIZE_MAX);\r
+\r
+       st_dll_params_in.knSceneNetWeights.weight_arr = get_knSceneNetWeightsArr_addr();\r
+       st_dll_params_in.knSceneNetWeights.para_size = get_knSceneNetWeightsArr_size();\r
+       get_knSceneNetWeightsArr_version(st_dll_params_in.knSceneNetWeights.net_version, VERSION_SIZE_MAX);\r
+\r
+       st_dll_params_in.knSceneSwitchWeights.weight_arr = get_knSceneSwitchWeightsArr_addr();\r
+       st_dll_params_in.knSceneSwitchWeights.para_size = get_knSceneSwitchWeightsArr_size();\r
+       get_knSceneSwitchWeightsArr_version(st_dll_params_in.knSceneSwitchWeights.net_version, VERSION_SIZE_MAX);\r
+\r
+       st_dll_params_in.knMultiWeights.weight_arr = get_knMultiWeightsArr_addr();\r
+       st_dll_params_in.knMultiWeights.para_size = get_knMultiWeightsArr_size();\r
+       get_knMultiWeightsArr_version(st_dll_params_in.knMultiWeights.net_version, VERSION_SIZE_MAX);\r
+\r
+       st_dll_params_in.knTdfusionWeights.weight_arr = get_knTdfusionWeightsArr_addr();\r
+       st_dll_params_in.knTdfusionWeights.para_size = get_knTdfusionWeightsArr_size();\r
+       get_knTdfusionWeightsArr_version(st_dll_params_in.knTdfusionWeights.net_version, VERSION_SIZE_MAX);\r
+\r
+       goodix_heart_net_dll_set_params_inner(&st_dll_params_in);\r
+}\r
+#endif //#if (_WIN32 || _WIN64) \r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/algo_params/HR/04_EXCLUSIVE/heart_net_org_export.h b/code/sdk/drivers/peripheral/ppg/gh3x2x/algo_params/HR/04_EXCLUSIVE/heart_net_org_export.h
new file mode 100644 (file)
index 0000000..ce61125
--- /dev/null
@@ -0,0 +1,72 @@
+#ifndef _HEART_NET_ORG_DLL_H_  \r
+#define _HEART_NET_ORG_DLL_H_\r
+\r
+#include "goodix_type.h"\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+       extern uint32_t *get_knBasicWeightsArr_addr();\r
+       extern uint32_t get_knBasicWeightsArr_size();\r
+       extern void get_knBasicWeightsArr_version(char* ver, uint8_t len);\r
+\r
+       extern uint32_t *get_knSmallWeightsArr_addr();\r
+       extern uint32_t get_knSmallWeightsArr_size();\r
+       extern void get_knSmallWeightsArr_version(char* ver, uint8_t len);\r
+\r
+       extern uint32_t *get_knWeightsArr_addr();\r
+       extern uint32_t get_knWeightsArr_size();\r
+       extern void get_knWeightsArr_version(char* ver, uint8_t len);\r
+\r
+       extern uint32_t *get_knConfNetWeightsArr_addr();\r
+       extern uint32_t get_knConfNetWeightsArr_size();\r
+       extern void get_knConfNetWeightsArr_version(char* ver, uint8_t len);\r
+\r
+       extern uint32_t *get_knSceneNetWeightsArr_addr();\r
+       extern uint32_t get_knSceneNetWeightsArr_size();\r
+       extern void get_knSceneNetWeightsArr_version(char* ver, uint8_t len);\r
+\r
+       extern uint32_t *get_knSceneSwitchWeightsArr_addr();\r
+       extern uint32_t get_knSceneSwitchWeightsArr_size();\r
+       extern void get_knSceneSwitchWeightsArr_version(char* ver, uint8_t len);\r
+\r
+       extern uint32_t *get_knMultiWeightsArr_addr();\r
+       extern uint32_t get_knMultiWeightsArr_size();\r
+       extern void get_knMultiWeightsArr_version(char* ver, uint8_t len);\r
+\r
+       extern uint32_t *get_knTdfusionWeightsArr_addr();\r
+       extern uint32_t get_knTdfusionWeightsArr_size();\r
+       extern void get_knTdfusionWeightsArr_version(char* ver, uint8_t len);\r
+\r
+\r
+#if (_WIN32 || _WIN64)\r
+#define VERSION_SIZE_MAX        10\r
+typedef struct\r
+{\r
+       char net_version[VERSION_SIZE_MAX];\r
+       uint32_t para_size;\r
+       uint32_t *weight_arr;\r
+\r
+}st_hrnet_params_info;\r
+\r
+typedef struct {\r
+       st_hrnet_params_info knWeightsSmall;\r
+       st_hrnet_params_info knWeights;\r
+       st_hrnet_params_info knConfNetWeights;\r
+       st_hrnet_params_info knSceneNetWeights;\r
+       st_hrnet_params_info knSceneSwitchWeights;\r
+       st_hrnet_params_info knMultiWeights;\r
+       st_hrnet_params_info knBasicWeights;\r
+       st_hrnet_params_info knTdfusionWeights;\r
+}goodix_win_params;\r
+\r
+DRVDLL_API void goodix_heart_net_dll_set_params_inner(goodix_win_params * dll_params_in);\r
+void heart_net_dll_param_init();\r
+#endif\r
+\r
+#ifdef __cplusplus\r
+       }\r
+#endif\r
+\r
+#endif\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/algo_params/SPO2/02_PREMIUM_EXCLUSIVE/pv_v2.1.0.0_spo2wrnet_for_GH3228T_cd023f.c b/code/sdk/drivers/peripheral/ppg/gh3x2x/algo_params/SPO2/02_PREMIUM_EXCLUSIVE/pv_v2.1.0.0_spo2wrnet_for_GH3228T_cd023f.c
new file mode 100644 (file)
index 0000000..6cdadc3
--- /dev/null
@@ -0,0 +1,511 @@
+#ifndef Goodix_DSP_EXPORTS\r
+#include "goodix_type.h"\r
+#define NET_VERSION "GH3228T_cd023f"\r
+#define NET_SIZE 3924\r
+const uint32_t Spo2WRWeights[] = {\r
+0, 1073741329, 3999574012, 3471442047, 3780214886, 4000178303, 2929950804, 2495143628, \r
+2970290559, 2156167122, 619404616, 789348584, 3319933902, 2136996736, 3954499501, 2155844344, \r
+4260807495, 1448902467, 3148709986, 3708372977, 3363859666, 1082112248, 3206147517, 1058585058, \r
+1058107101, 1058524726, 1058716434, 1060996767, 1057088519, 1062156363, 1060983320, 1064176116, \r
+1051455998, 1059839158, 1063356877, 1065353216, 1058338418, 1058483133, 1062110265, 1060347853, \r
+4096437775, 4173578114, 96249287, 142302726, 46176432, 4279652685, 4201656531, 120110439, \r
+112533895, 4131872153, 4251881560, 4259020204, 4058346203, 268435456, 4187527169, 4110472463, \r
+3229969796, 1082486148, 3221450872, 1073899927, 888286203, 1051730340, 3366000070, 85295127, \r
+1387195297, 3675960313, 333756164, 333536896, 3441354296, 856907113, 3363813340, 183520783, \r
+601333949, 3803309266, 3584077349, 2157104088, 3210167754, 1062573886, 1063109708, 1065353216, \r
+1064663899, 1063962545, 4056203542, 27958070, 268435456, 240853462, 3222753533, 1075269885, \r
+0, 1080528951, 150957696, 4169099135, 1745584307, 3212691973, 1065078385, 1056383158, \r
+1065353216, 1059458681, 1059967368, 43763034, 36959618, 29778676, 268435456, 3221610982, \r
+1074127334, 0, 1074752954, 1082923648, 52227200, 4221369216, 2135430759, 2159638586, \r
+3531608289, 4135525715, 2715809664, 209761226, 2771812447, 3622469461, 773619865, 2162688333, \r
+2206207203, 1937762878, 2160061178, 3207675224, 1060100829, 1054674996, 1052144291, 1065353216, \r
+1059417531, 1049044443, 1059058566, 1055481670, 1065001480, 1055421370, 1051162596, 1058362508, \r
+1050752920, 1053679741, 1061351470, 1058995308, 1058531701, 4181018345, 4261061511, 4178568690, \r
+147835997, 155989941, 4121771723, 84695956, 4165806231, 4123362933, 4145569003, 217143882, \r
+4292846979, 4156635296, 268435456, 22989955, 4148329231, 3218508640, 1071024992, 3215272250, \r
+1066893384, 0, 1073250996, 2161419784, 232790274, 3435180006, 1200405713, 2278343415, \r
+3087714316, 3456860347, 951516346, 1377696222, 4062543713, 3579915609, 4084432880, 1108686887, \r
+876234790, 2136013639, 820272608, 3209444426, 1061856209, 1065348550, 1061910582, 1063509064, \r
+1065353216, 4281893116, 4026531840, 74441011, 4282719262, 3228146934, 1080663286, 0, \r
+1082660499, 2153771647, 4033469177, 2145588608, 3208234995, 1060656227, 1061204640, 1063926475, \r
+1059131310, 1065353216, 4293907511, 4285572924, 23145812, 4026531840, 3223207109, 1075723461, \r
+0, 1073459757, 2161707529, 562037750, 2161642503, 2148857586, 142607599, 276888280, \r
+2021710558, 2148950699, 2407560104, 176169955, 981508607, 2161648597, 562031577, 612433660, \r
+1573617582, 4109220736, 3208800200, 1061217016, 1060271586, 1052288904, 1062534431, 1065353216, \r
+1052662144, 1043946311, 1043405011, 1049353392, 1041199451, 1049562776, 1046290015, 1051475883, \r
+1044370844, 1050045716, 1050591949, 1049566002, 4026531840, 4091904097, 4112926457, 4256521358, \r
+4274151182, 4129422542, 4107332473, 4137344156, 4163127615, 4050213461, 4283471552, 4288776512, \r
+4148506786, 88599912, 4191362814, 4205773158, 3214316959, 1066833311, 3197379088, 1035358543, \r
+0, 1072226857, 3188088941, 1045560072, 3180863642, 1049821279, 1057142566, 1053751385, \r
+1034609895, 3198056750, 3190147577, 3203025485, 1060921984, 1044424167, 3125393333, 1052072978, \r
+3178442557, 1044065743, 3187014746, 1059069745, 1036939185, 1055180309, 3181306100, 3171395037, \r
+1049596484, 1053454790, 1042198871, 3185582551, 3195715016, 1047497607, 3163126620, 1028103420, \r
+3182220766, 3163506534, 3148835688, 3193581754, 3183899052, 3174627705, 1030714171, 3172964331, \r
+1052302730, 3182509810, 1045909100, 3179631113, 1039075737, 3172805854, 1056014575, 3157871968, \r
+3179349434, 1047930853, 998135196, 3179998868, 1049233863, 1036866499, 3170565541, 1030639566, \r
+1045211681, 993360752, 1024130666, 3185090281, 3188860645, 1037967182, 1014993599, 1035674196, \r
+3188308867, 3192352835, 1043485487, 3199297430, 1040354856, 1033474467, 3199990705, 1045841800, \r
+3175429609, 1044661920, 3199880136, 1029998133, 1021794559, 1021463703, 1033271914, 1034820233, \r
+1029709998, 3181645919, 3147799899, 1049963030, 3199184164, 3199077444, 3155900674, 3203313546, \r
+1037468479, 3192183590, 1044285232, 3198823559, 3205993607, 3197838891, 3205617185, 3172102450, \r
+1053477708, 3195074063, 3191169307, 1043668327, 3183488291, 1052728242, 1034022353, 1046113422, \r
+1044279750, 1041054848, 3191620331, 3187156697, 1041035348, 1034087071, 1032813201, 1023877648, \r
+1042245215, 3188129766, 3167637752, 1043168907, 3203998333, 3191339179, 3162300078, 3202238577, \r
+3163295464, 1032097768, 1052482054, 3179969028, 3203547446, 3132765183, 993714416, 999208604, \r
+1045959648, 3174859416, 3195910896, 1041232965, 3155232172, 1051441667, 3196366384, 3196841661, \r
+1048244070, 3192420112, 1033124028, 1048715737, 1044820215, 1044733986, 3188801261, 3187447003, \r
+3187977533, 1049484017, 1047212308, 3167346802, 1046109428, 1040397796, 3180521555, 3191611651, \r
+1031928783, 1037162464, 3189617626, 3193939535, 1026923543, 3187748320, 1049254874, 1035633574, \r
+3197885329, 3189034114, 3175164678, 1045463575, 3197861566, 3188564876, 1050754530, 3182087459, \r
+1045174693, 3189564905, 3144047360, 3183190091, 3191713387, 3171598323, 1029072817, 3212869761, \r
+1065287423, 1935179521, 1420445853, 880764287, 1469249464, 3231250559, 1149484672, 904494893, \r
+2160514461, 18154881, 3051126562, 2071985661, 388267929, 478137793, 3995744738, 2135774750, \r
+1630175210, 3179323535, 3472780780, 3414159926, 2158349285, 3206592775, 1059026837, 1060511955, \r
+1059792811, 1064969570, 1061210391, 1062931313, 1064696255, 1064581728, 1065353216, 1060282289, \r
+1064066905, 1058351370, 1061899575, 1062189625, 1061840365, 1061057472, 1064851025, 4279120814, \r
+98907296, 4164514887, 31336640, 4137201817, 4255047186, 4141284609, 122038685, 4254578309, \r
+4138156253, 30501590, 4266867559, 4026531840, 57387976, 4221338006, 4223451414, 3226551897, \r
+1079068249, 3220028740, 1071256481, 394255882, 4277088757, 3472631835, 1875497511, 4110793252, \r
+536542958, 3436300312, 2145178391, 2158366636, 3144058459, 537956298, 3794362566, 620970623, \r
+1015229128, 944261495, 3755134293, 3213671024, 1066115323, 1062815108, 1065353216, 1057691518, \r
+1058210830, 4027065002, 171977037, 4198783646, 268435456, 3212988257, 1065504609, 0, \r
+1084488549, 3902088064, 2131984401, 1105101007, 3211491700, 1063887489, 1060175172, 1061331196, \r
+1061379347, 1065353216, 268435456, 159007971, 4235757866, 53669661, 3230840635, 1083356987, \r
+0, 1068453332, 3873210587, 2137524409, 4005986557, 922452116, 260001295, 3239346407, \r
+2135560412, 3502473221, 4118787726, 3656089621, 2159492934, 2134693288, 2154043287, 545238010, \r
+1954486799, 337575808, 3218290695, 1070698903, 1058037646, 1046971298, 1051851149, 1053039682, \r
+1047134333, 1057149333, 1049680280, 1052161499, 1045619643, 1065353216, 1054905987, 1044675046, \r
+1049074662, 1044604299, 1049352733, 1050360702, 44440324, 4058223431, 4077551628, 4172568318, \r
+118086542, 4130925078, 10311762, 4181443929, 1676601, 12985021, 4278335127, 4122072537, \r
+4280091991, 4167096920, 4026531840, 4063318117, 3214821567, 1067337919, 3216110490, 1061298437, \r
+0, 1078092990, 847190350, 487543542, 4044517401, 148893302, 652227143, 53421900, \r
+1110843663, 3078575385, 3673671144, 3565223828, 3352014834, 3852175336, 2138860898, 273174138, \r
+1076509756, 812991063, 3213074511, 1065523470, 1065353216, 1062390299, 1062765183, 1059857864, \r
+4246158256, 4131911022, 4026531840, 4249656307, 3223861647, 1076377999, 0, 1091265068, \r
+2132605823, 2145683408, 2142110530, 3208989910, 1061405244, 1065353216, 1059505525, 1064833704, \r
+1059611897, 4026531840, 230433096, 4294700819, 163168176, 3224217651, 1076734003, 0, \r
+1081132085, 3205163904, 3856695501, 4260593700, 3151986704, 2147692478, 2509275153, 2162720964, \r
+368869587, 2160706589, 3538821504, 2147228912, 752910368, 2901246143, 2934893184, 2549530240, \r
+269254657, 3208962441, 1061377990, 1056990552, 1061548569, 1063123537, 1060051909, 1058543253, \r
+1053995739, 1058039691, 1065353216, 1054629078, 1052946365, 1044676395, 1062117442, 1059064284, \r
+1062187328, 1059471454, 1060631745, 60177608, 4229137977, 4139826956, 4087864650, 4166052301, \r
+4026531840, 4194234425, 4163332493, 4124766682, 4240524033, 4127614679, 4122431874, 4116267497, \r
+4109987968, 4102945804, 4148880372, 3218808151, 1071324503, 3224008600, 1058411404, 0, \r
+1078148423, 1044206622, 1053430767, 1056639557, 1049911082, 1058440975, 1045600926, 1051295666, \r
+1049504051, 1037647009, 3191770066, 3176605117, 1050932703, 3174820307, 1061602744, 1059485086, \r
+1064398268, 3186784299, 1057080053, 3202219812, 1056136033, 1046105521, 1043444907, 3205015334, \r
+3189649948, 3188307446, 3196246667, 3179146919, 3203560180, 3179822049, 3187058748, 3128552276, \r
+1041648308, 3174100737, 1045517449, 1019777518, 1034703778, 1045043416, 1034437962, 3196975499, \r
+3191496178, 3185590886, 1045498901, 3197404380, 1048020441, 1040863381, 3197627345, 1042614714, \r
+1046713908, 3198131318, 3198766142, 996709457, 3181169656, 1045292443, 1044576779, 1050344993, \r
+1056386536, 3184294258, 3197472383, 3175578921, 3199081539, 3144412053, 1043539774, 1044330652, \r
+3202181394, 1041005636, 1045004977, 3205629050, 1049268002, 3182377285, 3190240943, 1037542947, \r
+3197596410, 3195379236, 1052643436, 3199977501, 1047425113, 3197377786, 3181277733, 3182788862, \r
+1042819476, 1026024375, 1052178452, 1062627375, 1048699344, 3190138415, 1046713891, 3186239350, \r
+1045117425, 1034666791, 1053827024, 1033318928, 1046457723, 1046647845, 3185454146, 1045705785, \r
+1051733151, 3200514160, 1057248131, 3182674871, 3200709601, 1037699909, 1031837487, 1006291401, \r
+3197752302, 3199361146, 3168744842, 3166192477, 3202962896, 3195819441, 1045525673, 1051631453, \r
+3193334791, 1046767212, 3206113678, 3200771626, 1043584866, 3202866770, 1050384903, 1033989224, \r
+3190094361, 3198226275, 3179364448, 3194067628, 3193627120, 3179984256, 1026714116, 1046937217, \r
+3191408781, 1048741869, 1039644997, 3175093253, 1006261299, 3201985755, 1050332211, 1046510808, \r
+3180478847, 1032136374, 3147490039, 3156853076, 3202540773, 1034998490, 1041386093, 1042093516, \r
+3194414963, 1048838842, 1047218431, 3203886903, 3173541244, 3199707043, 1044541491, 1032495013, \r
+3195946982, 3204284267, 3192613026, 3202755777, 3206369496, 3206167038, 3182001609, 1044610496, \r
+3206695141, 1025742914, 3207162995, 3190237992, 1033926510, 3204469703, 1016325476, 1033196987, \r
+1040847229, 986556084, 1039213138, 1037606384, 1033852052, 1043964737, 3175299710, 3172095444, \r
+1046889179, 1041888244, 1045016466, 3167606236, 1031985124, 1043137086, 3152091620, 1035225234, \r
+1029004097, 1035840556, 1045419555, 1038176065, 1036759116, 3193383753, 3188076789, 3193863542, \r
+3194250162, 3204539587, 3201202884, 3192855357, 3196890203, 3189559290, 3203621266, 3199361486, \r
+3191882711, 3197672037, 3195932476, 3191936557, 1041818141, 1041447921, 1052296868, 1048900640, \r
+1045096180, 1048559016, 1046109303, 1045536288, 1049935330, 1028920180, 1048808803, 1049970427, \r
+1036946671, 1044396132, 1048702558, 3192069902, 1044104997, 1022692071, 3193325444, 1040833267, \r
+3170947908, 1045648860, 3157772117, 1039307701, 3163570032, 1034065563, 1028958764, 1041991661, \r
+1041505426, 1043325243, 3171254946, 3180657300, 3194866221, 3190525733, 3199294064, 3196193870, \r
+3199463310, 3196699841, 3202505541, 3198385079, 3198841009, 3172321174, 3196908579, 3198066250, \r
+3200562002, 1029039458, 3170488326, 3199063454, 3187399720, 3201782278, 3161592482, 3196159509, \r
+1008079504, 3198130902, 3173718175, 3188626816, 1004013736, 3187779319, 3190829947, 3196738791, \r
+3189437767, 3206028153, 3201468674, 3199812335, 3211043262, 3204331987, 3204601631, 3198182051, \r
+3201707061, 3204439094, 3201442752, 3192164362, 3204467515, 3206090076, 3198740671, 1046161400, \r
+1045564701, 1026276283, 3190402442, 1018197843, 3174632526, 3193869603, 3184000161, 3196683500, \r
+3185404950, 1039001050, 3167076693, 3173466538, 1038680372, 3187921736, 1036676703, 1045938084, \r
+1045468858, 1048130775, 1039122045, 1043784999, 1041528726, 1041340713, 1046668346, 1041075353, \r
+1043825556, 1049114319, 1047971032, 1032753709, 1029313411, 1021024999, 1033845186, 1049189557, \r
+1056089301, 1044848926, 1041702435, 1051597150, 1050162489, 1051415908, 1048625733, 1049561815, \r
+1051443101, 1049143972, 1054139670, 3138858509, 3154556626, 3188469329, 1033956264, 1022012934, \r
+3163202846, 1016265402, 1027188642, 998388144, 3180865784, 3174574579, 1020684772, 3190393756, \r
+3167259554, 3187329222, 3169705938, 1049869081, 1019289287, 1039851497, 1043585296, 1040284624, \r
+3165753304, 3178708555, 1020028387, 1030497791, 3179713020, 3185570936, 3165444715, 3172774915, \r
+3194711444, 3170019297, 3185565280, 1035067722, 1044192046, 1033560582, 1047646454, 1044225917, \r
+1050325943, 1051781471, 1046614709, 1047472258, 1049488996, 1047448175, 1046005850, 1054123539, \r
+1051552878, 3186433140, 1051908342, 1045315252, 1045900478, 1042618624, 1035767247, 1037349445, \r
+1035625772, 1038703266, 3164920472, 1044664539, 1032962103, 1040455550, 1045053896, 1047505183, \r
+1028626938, 1055238670, 1051567784, 1053226593, 1052511397, 1045555688, 1049611594, 1052122819, \r
+1050461323, 1050747069, 1053543742, 1053701710, 1053314115, 1055454149, 1045603921, 3185700550, \r
+1034118762, 1027765029, 1046001850, 1049282518, 1054410027, 1053263099, 1053190200, 1057085518, \r
+1052260264, 1051294782, 1054363497, 1055658395, 1057376650, 1050397602, 1028055967, 3204779168, \r
+1051165283, 3199060034, 1015434586, 3196551670, 3190132881, 3189400146, 3201557818, 1040310059, \r
+3194891954, 3198020784, 1042232259, 3181103636, 3205506871, 3146463807, 3192915333, 3194937428, \r
+3192271919, 3179929049, 3186448911, 3186279824, 3196884664, 1038624074, 3198972795, 3190574441, \r
+3192791220, 1034949164, 3204879704, 1035713159, 3178805024, 3133200509, 1043005022, 1046042573, \r
+3180108603, 1036066567, 1043876296, 1040412273, 992157139, 1044931277, 1033801378, 1001993338, \r
+1051125452, 980588432, 1047165106, 1057725852, 3177620055, 1046745785, 3197840192, 1046115287, \r
+3187051345, 1021989603, 3207838666, 1050298803, 3174591865, 3205121642, 3185729240, 1019092800, \r
+3199477566, 3196132125, 3187210762, 3173990450, 3191146073, 3189666804, 1038903322, 3190308133, \r
+3179104991, 3174745173, 3155812486, 3196784355, 3162974800, 3173762762, 1032730548, 3204351099, \r
+1048602922, 3190191614, 1043808995, 3173691608, 1042183865, 1044401976, 1035975904, 3136504981, \r
+1036386957, 1022102768, 1000442227, 1037334864, 3162021683, 1041669038, 3181804227, 1044662075, \r
+3167439520, 1045482859, 1010268806, 3149675267, 1041230354, 1019399719, 1035211372, 995671644, \r
+1049385789, 3193399728, 1030167322, 3113291125, 1048739671, 3198390191, 1044077803, 3197902777, \r
+3196276819, 3198122390, 3191125423, 3126098112, 1016084564, 3188874343, 1035048294, 3193480122, \r
+3193145197, 3164712549, 3188617304, 3193860309, 3196117929, 1036064769, 1051661908, 1032188600, \r
+1045186531, 1054389045, 3175841084, 1050507500, 1045537066, 1043422537, 1038651935, 1033697223, \r
+1048076991, 1052289794, 1043678328, 1051875333, 1051148103, 3182219426, 3191026425, 1051155526, \r
+1014529312, 3197471896, 1048256321, 3182283607, 3181555839, 3166493318, 3191864542, 3185462581, \r
+3148655300, 3195309716, 1043065123, 3198356886, 1037220351, 1041224640, 1038807009, 1049769968, \r
+1035933299, 1039053252, 1034235137, 1030846339, 1035455333, 1032758431, 3183481625, 1041247586, \r
+1025314249, 1015899369, 1048522195, 1040284473, 1032055917, 1044294601, 1037530753, 1024632712, \r
+1052729858, 3162615869, 1037842888, 1051211259, 1005153287, 1043196842, 1050936932, 1017828821, \r
+1044944134, 1049632166, 3195436656, 3200984197, 3196697582, 3212183823, 3198202226, 3203718804, \r
+3209612534, 3199582069, 3207084980, 3209087248, 3204462988, 3201434064, 3204801848, 3201482707, \r
+3204837220, 3198621381, 3187627553, 3195440504, 3204991436, 3193740726, 3206330529, 3199337545, \r
+3198560827, 3201107288, 3199916300, 3193448608, 3201745551, 3192450750, 3196203269, 3200762595, \r
+3192819433, 3197923589, 1050501025, 3190096331, 3198603341, 1032496965, 3200603316, 3190204723, \r
+3190643421, 3203532039, 1025674547, 3196354077, 3199364556, 1034065596, 3202148342, 3203154387, \r
+3197692596, 3209586531, 3207841881, 3197351592, 3209082851, 3201045638, 3208168413, 3210373688, \r
+3189032283, 3213289782, 3211010264, 3189432870, 3211333506, 3208521700, 1032716729, 1050173237, \r
+1048898507, 1051464987, 1046295172, 1049973526, 1049368198, 1046414740, 1044121406, 1047777361, \r
+1048117580, 1052919503, 1043261441, 1045446692, 1028110394, 1033360188, 1042727732, 1045751540, \r
+1056423025, 1045486825, 1048266443, 1050749906, 1042419437, 1052495743, 1034977604, 1048993759, \r
+1051418716, 1043760254, 1052140847, 1019473235, 1001972890, 3188194230, 1030239043, 3176823834, \r
+3187886460, 3169649097, 3175421077, 1023293770, 3188238475, 3162779693, 3182244277, 3188165602, \r
+3187266789, 3188505129, 3158647493, 1049340214, 1036246129, 1045203528, 1046410823, 1043449254, \r
+1042160287, 3172768984, 1015004516, 1043640645, 1040537647, 3184383089, 1046223398, 1028774538, \r
+998725771, 3164426960, 3171524895, 1035360170, 1042227534, 1033992100, 1050334975, 1043073259, \r
+1042674138, 1048807858, 1049048218, 1042115330, 1047576118, 1046729989, 1052142071, 1050487457, \r
+1051491421, 3175920747, 1047604945, 1046070889, 1040853765, 1044564089, 1037023894, 1032866137, \r
+1033981886, 1036121231, 3180634922, 1041130457, 1043426704, 1039041979, 1031952783, 1044234397, \r
+1033005365, 1052567121, 1051354653, 1052900593, 1050031550, 1043388381, 1049033602, 1048503284, \r
+1051047274, 1045013712, 1049188731, 1052923496, 1046377299, 1051520170, 1045920031, 3147280754, \r
+1040203027, 1040178504, 1049771827, 1049299982, 1053689343, 1054889314, 1057068609, 1059017659, \r
+1052815469, 1054388783, 1057544204, 1056136604, 1056430081, 1056237455, 3169737096, 1049973056, \r
+1050399358, 1046807571, 1043600306, 1043358631, 1044801181, 1047240286, 1037783048, 1046674652, \r
+1049479734, 1048773843, 1035072451, 1043313556, 1033684521, 3163759900, 1040143336, 1038231753, \r
+1053475346, 1040323086, 1041911000, 1047091104, 1040247968, 1048738566, 1037459201, 1034193965, \r
+1050918962, 1040227319, 1042141734, 1033020758, 1029229935, 3193842629, 1019700490, 3176917567, \r
+3179431951, 3179178771, 3188805048, 3188362836, 3192324531, 3185084962, 3189019769, 3189894041, \r
+3180724413, 3192685802, 3188355481, 1036228514, 1028421515, 1032123534, 1046014261, 1043465920, \r
+1037814260, 3183988309, 1012572891, 1034057770, 1032584172, 3162695548, 1034781229, 3180237885, \r
+3185382693, 993286166, 3182310819, 1034701037, 1040931252, 1042254767, 1050674764, 1048527338, \r
+1048990504, 1049819508, 1049256551, 1050310939, 1046969642, 1048953125, 1052289122, 1050843332, \r
+1049720731, 1031846553, 1042483255, 1032854077, 1044231991, 1043771010, 1034718409, 1041841208, \r
+1041580632, 1032484616, 1030497807, 1046210822, 1037999566, 1044006432, 1036088836, 1042863688, \r
+1027521358, 1049729157, 1045082474, 1048962873, 1037731815, 1036796590, 1048696336, 1036981464, \r
+1044510972, 1032952177, 1041377669, 1049456077, 1045246971, 1045600846, 1040251117, 1035551108, \r
+1046507324, 1047398059, 1051543372, 1051166886, 1051833353, 1053820519, 1057139990, 1056990300, \r
+1055558368, 1055450437, 1058293270, 1053459194, 1057871613, 1053449162, 1026138942, 3190167889, \r
+3191423136, 3190683684, 3171113677, 3196446282, 3200834728, 3172858666, 3197980465, 3196183840, \r
+3193316845, 3199425640, 3194175025, 3198595565, 1043299162, 1042129328, 3204851658, 1037737646, \r
+3200834962, 3187284228, 3200002512, 3121932675, 3190675541, 3191803152, 3184063066, 1006676693, \r
+3188883558, 3192587960, 1029740715, 3192605891, 1033842321, 1049496923, 1044862670, 1045882303, \r
+1050980333, 1048183766, 1046802477, 1052195702, 1052357963, 1035010380, 1054084234, 1031839003, \r
+1054722260, 1032548184, 1051087954, 998732181, 3202667250, 3195078426, 3199348838, 3188526538, \r
+3204664114, 3179745501, 1035686162, 3208962187, 3196344259, 3193415550, 3193756453, 3207590110, \r
+1040064693, 3203671919, 1042647661, 3194730913, 1040422604, 3191340680, 3188371633, 3188050244, \r
+1033914753, 3201703704, 1033585034, 3192766723, 3171844171, 3196996847, 3182808383, 3183905805, \r
+3193759903, 1015949976, 1030755443, 1036575166, 1038461322, 3182272123, 1040318116, 1042815152, \r
+3190493698, 1043854485, 1015428818, 1041689573, 3148795534, 1037194163, 1041843435, 3173560096, \r
+1017409889, 3196411331, 1047593033, 1000387082, 3169113002, 3181310469, 1042389779, 3191034007, \r
+1030265944, 1037257198, 1023730041, 3141168233, 1024450665, 1040913847, 3171416337, 1046292303, \r
+1033658642, 1023981880, 3184023859, 3193383397, 3175681605, 3189042250, 3201471034, 3184055630, \r
+3197183239, 3187873815, 3199793398, 3163396373, 3201487995, 3183595323, 3203137822, 3202383670, \r
+1048033567, 3204275934, 3190682401, 3198087147, 3191764083, 3205411923, 3187739479, 3181333612, \r
+3195330661, 3205379335, 1043938329, 3201181611, 3180246764, 3187712199, 1039035122, 3203581012, \r
+1006868833, 3196322688, 3166586407, 3202467903, 3171053354, 3196180438, 3189666994, 3181444776, \r
+3168684324, 3180274502, 3196087082, 3159641575, 3187684872, 1050917058, 1046156752, 1047837667, \r
+1045866057, 1046736654, 1050668130, 1042330045, 1041931608, 1051368716, 1043094894, 1052422369, \r
+1036165861, 1051563601, 3196503342, 3200849562, 1051798261, 3205020948, 3183357029, 3197685524, \r
+1042759053, 3210945082, 3195522268, 1039501385, 3205953021, 3191008998, 3200598810, 3173281656, \r
+3205181114, 3181542370, 1040771994, 1023700762, 3195749284, 1024097870, 3184333535, 3167500355, \r
+3196759833, 1036062220, 3191504221, 3145556754, 3186025936, 1043022611, 3196756625, 3115379818, \r
+3171226787, 1037457982, 1045898466, 3164855577, 1043164619, 1035451364, 1008430291, 1038878743, \r
+1042511315, 3180005580, 1049555390, 1033331682, 1041133336, 1015265610, 1049987107, 3157669850, \r
+1040793024, 1049299024, 3185165484, 1041199497, 978290741, 1041483279, 3187071413, 1045552314, \r
+3175735214, 1034995668, 1041600615, 1048301256, 1016619073, 1032517731, 1040238546, 3189845619, \r
+3189916697, 3196039522, 3189865147, 3192920927, 3191402493, 3175012595, 3181820255, 3198587732, \r
+3180345726, 3197576417, 3188589283, 3200615573, 3179210314, 3197256450, 1042155692, 3189309723, \r
+1032363984, 1018500878, 3193882249, 3194285598, 1052854574, 1049265288, 1051254334, 1045361756, \r
+3204793168, 1050610659, 1049784114, 1049691483, 3210713230, 3207200828, 1037038493, 3205761095, \r
+1037409618, 3201944327, 3201961443, 3204711049, 1049744176, 1046308492, 3204460996, 1042569851, \r
+1052205389, 1016513416, 1040316657, 996501061, 1034323772, 1050639436, 3199320743, 1039531669, \r
+1042829232, 1111117364, 2149990248, 777591337, 3358533396, 3254321102, 2983108973, 3065035952, \r
+1222876594, 2827844265, 2291229330, 1837324924, 3094267265, 2378335676, 1400335952, 1197948730, \r
+2863343299, 1706984858, 1683776622, 2772465771, 2141747833, 2173928653, 1229814389, 2777105781, \r
+2611072195, 1953920086, 2254928516, 2807953247, 2596388233, 1956814937, 2156175248, 1704914551, \r
+1637242449, 1635413117, 2405796988, 2845998491, 2644298163, 3368466879, 3452747959, 2593239250, \r
+2525661577, 2038135166, 2373419162, 3366294705, 3184236681, 3120353203, 2695807939, 2628035258, \r
+2526973079, 2342297744, 1890549905, 2440614010, 3549607601, 2932452563, 2694226108, 3283003903, \r
+3587691493, 3118590155, 2308151726, 2206963355, 2442235522, 2508289405, 1701341915, 2505725806, \r
+2576338523, 2136572829, 3510272401, 1196400051, 3048597937, 3890472158, 2474210205, 1016379025, \r
+1851478891, 3831259980, 2189339040, 2408547247, 3254352722, 1689958305, 3247155865, 2558621669, \r
+2457832845, 1960050541, 2260430478, 2808391346, 2710414272, 3864011039, 2233036145, 2680141954, \r
+2796530302, 2843506307, 1500088452, 1097880914, 2003587659, 1230789455, 2186966618, 2373139350, \r
+1903005561, 3804199065, 3083445445, 4293654218, 2161372917, 2189918605, 2256568700, 1884969835, \r
+2609805423, 3547107743, 2359854972, 2630136968, 2341179604, 2911732629, 2124650634, 2493154701, \r
+1869323172, 3062675574, 2141958543, 1639093670, 2462673249, 2491267744, 2611999187, 2139738040, \r
+2039047534, 1785363298, 1952270685, 2210295398, 1531199818, 2491180142, 1431398471, 2171765334, \r
+2142403448, 1836483208, 1887408777, 2558833307, 2341107604, 2508425872, 2039384451, 2271909750, \r
+2443263102, 2108268918, 1956811398, 2357426045, 2039780731, 2123204233, 2373086867, 1501915481, \r
+2138283921, 2358215340, 2054849178, 2442959465, 2460003221, 2526121119, 2660342165, 1972741495, \r
+2139267980, 2492364146, 1703411550, 2070639970, 2778770052, 1819186264, 1550218879, 2306443389, \r
+2692260787, 2139392879, 1940758429, 811109762, 1836752673, 1079864206, 2828180887, 2593948840, \r
+2991362161, 2492965040, 2526581905, 1900308591, 2358482852, 2661706620, 2275702945, 2357891996, \r
+2661335393, 2156162721, 2862125706, 2289870275, 2322495618, 1649315495, 167788401, 2153997177, \r
+1078091104, 2524599454, 2157689946, 3582033098, 2744295573, 186917543, 3045219351, 1702053480, \r
+456610604, 3234329290, 3900347517, 2748226787, 1622856910, 1249784392, 2358620269, 2105529774, \r
+3819073186, 3249975234, 2393429409, 3619001254, 1919947462, 3461437845, 1275033977, 1167691412, \r
+1400936112, 2631236758, 2412367272, 3047141747, 1402456769, 2091277411, 3365041313, 1400082328, \r
+3502086711, 3703500006, 3236479999, 2531035089, 2271234656, 2442229363, 1752993913, 2757845062, \r
+1194350248, 1479298472, 2912033799, 2070584942, 3107700841, 2862410113, 1542675116, 902407013, \r
+1750415902, 503670358, 1854908756, 2442096695, 3700791416, 2324742052, 1904246955, 3352142714, \r
+2646971575, 1654958800, 2946456716, 2539148441, 759705156, 1956423737, 2042436515, 2422761836, \r
+2021740140, 1686396763, 2472174180, 3265368761, 3333996209, 3286093780, 2022423754, 1971017073, \r
+1417042008, 1685093230, 2291912569, 2894645439, 2360971919, 3215431839, 2319871376, 1670014563, \r
+2173868641, 3095557485, 3030739327, 2444861055, 2543751607, 2793975463, 2949904833, 3903444713, \r
+3940789227, 1703321521, 1198019684, 1549233492, 1632325223, 2927886197, 2508892836, 2624632478, \r
+2458876549, 1346078079, 1868173568, 792088922, 537990706, 1838303526, 1851148686, 2391047054, \r
+2340389258, 1412522829, 2085578849, 2188789642, 1265132169, 1701278596, 2358141547, 2359400074, \r
+1700115360, 1533632860, 1634956650, 1636724550, 1768978530, 2456309041, 1215920216, 1902923086, \r
+1565288244, 1564944669, 1718837317, 1180334695, 1331834412, 1433764687, 1564503915, 2355516547, \r
+2877127762, 2745215412, 3031407008, 2947916194, 1163820900, 1399155555, 2119200132, 3162135398, \r
+2259844457, 1685754493, 2542308525, 2173346178, 1784111940, 2138928259, 1719309403, 1500563332, \r
+2508357027, 2308335240, 2525007773, 3565118831, 2912126604, 2630920594, 2108215220, 1769175172, \r
+1903389298, 1532846687, 4285034327, 1635683442, 2372627610, 3228469174, 2811086481, 2965727397, \r
+3501491319, 4141477046, 2966145504, 2372505452, 2272551059, 1700222336, 2377811112, 3413412755, \r
+1989904779, 2562168722, 2238624430, 2307749759, 1719115883, 2677633629, 2122225337, 2895957630, \r
+2040428942, 2173801892, 1941206176, 2293603442, 3216179111, 1787938189, 2325375371, 1886938210, \r
+2119656039, 2594463613, 2275706022, 2060298141, 2490334888, 630882969, 1311375411, 1232238713, \r
+993998919, 2505132868, 925523786, 1883662651, 1935105142, 678907262, 1331655537, 2220980106, \r
+1634108564, 1919385177, 2422890082, 2845476236, 2208738956, 2255835777, 2475583048, 2407352175, \r
+1837260903, 1717577567, 1870098066, 1601136456, 846012779, 588318279, 1767718457, 1180119623, \r
+1614612821, 2477631107, 1115383905, 759452742, 3416796011, 3504144315, 3083321054, 2209067432, \r
+1751679634, 1719493991, 2105636486, 2793573747, 2927128658, 1583984752, 2356101233, 2457166144, \r
+1786411375, 2037089166, 2173668453, 2454162574, 2288702313, 896160361, 2319018314, 2342742384, \r
+2425864632, 2493481126, 1584680582, 2022732671, 2474743171, 2089911170, 1988727199, 1268753554, \r
+1467264624, 2710288209, 3637497735, 2506132184, 1949973209, 3566796462, 3970942906, 1656789670, \r
+1166126516, 944326451, 3293797983, 901094506, 2862400673, 2229712601, 1844100510, 3218442156, \r
+1451327628, 1635415407, 2109331564, 2496004258, 3671826044, 3654458239, 3210432655, 2354656570, \r
+2176683133, 3250364823, 3612320676, 694325381, 2003591995, 2706264634, 1499211951, 861548880, \r
+1531192931, 1261254685, 3569398709, 3151614091, 3300514766, 3116874699, 3855797174, 3228878027, \r
+2327294314, 1089271502, 3364732262, 2377019827, 2604061524, 2309391019, 2610351581, 2445140088, \r
+3718948818, 2204193740, 2407774876, 2893252220, 3017374804, 4290299352, 3439119571, 3598823641, \r
+3117336275, 3620251838, 2646847915, 2629740961, 2878656717, 1819768949, 2578809745, 1707053952, \r
+664174746, 487325741, 760885315, 1279933007, 2996005182, 2088024438, 3097334965, 3030826897, \r
+1065372625, 1133548844, 1748926079, 2139328417, 2692724361, 2846331527, 3720922328, 2614539224, \r
+3677309339, 2057729641, 2324991852, 2340586654, 2054773605, 2406175870, 2640477832, 2093250207, \r
+2339795349, 2173997925, 2258733225, 2373281383, 1855358086, 1939246202, 2005700718, 1534167410, \r
+1347833425, 1130318949, 1163480924, 2170640224, 2356765295, 2105503599, 2005166985, 2054122607, \r
+1182107228, 1935832191, 2036881027, 2107280240, 2694424987, 2258140294, 1635812493, 2271707741, \r
+2325965969, 2190377345, 458708857, 977351740, 688923175, 792079145, 2105440588, 2072080771, \r
+1752921975, 1601798784, 2206297088, 1938786670, 2507696259, 2022612873, 2006021278, 1734314363, \r
+2643489681, 2040500876, 1651406425, 2188869762, 1919511170, 1618506349, 1296655711, 1986023761, \r
+1934791552, 1751862630, 1431729757, 1952414308, 1937597287, 1514953336, 1683246179, 1854434640, \r
+2019070042, 2407884648, 1484810613, 2138147968, 2287434121, 2104135310, 1871212434, 2273347976, \r
+4285501818, 2324862358, 1990690691, 2290460286, 2358547115, 202664216, 621427538, 890710548, \r
+2281719571, 2141033373, 2863969720, 2897393336, 2861545646, 2428028053, 3483608242, 2999172776, \r
+2595331240, 3199307168, 3015166907, 3116284350, 3166473348, 2695277738, 3182021837, 3100155093, \r
+2690957191, 2693501329, 2796719511, 1654357951, 2021823860, 2627904409, 2509936304, 1305291913, \r
+2930222277, 2491854493, 2625282459, 1923593134, 1077359941, 642992697, 758725936, 184575782, \r
+1547517526, 2253613667, 1264870491, 2339078749, 1954710625, 2542626953, 1837394070, 1319003013, \r
+2339473272, 1701733024, 2491178865, 2508565144, 2258085249, 2710287539, 1112966826, 1512063053, \r
+522074657, 1077033237, 2289966907, 2675669872, 2190965140, 2860810108, 2373475141, 2545983158, \r
+2713241244, 3772356778, 2154607530, 1698393446, 1417034578, 1618826812, 2643500134, 2074984086, \r
+3551505103, 3115427245, 1314416128, 1538732647, 1433974890, 2207425946, 2125174685, 2844292241, \r
+2561316236, 1795204742, 1248355606, 2808894835, 1670874207, 1415137704, 1482439501, 1098604686, \r
+2176429160, 2293269200, 3265176985, 2795475098, 2746991773, 2678107592, 3197154461, 2832311439, \r
+2728899759, 2947782318, 3133059741, 2445387429, 2358618535, 672609337, 1512439889, 207890728, \r
+2369147188, 3213867453, 2728840079, 2879492521, 1095477668, 1246973495, 1681936743, 2169585988, \r
+2107285306, 2611913103, 2609091737, 2679015560, 2676789651, 2056498826, 2323746486, 77496215, \r
+825433623, 1010186796, 909328980, 2809480526, 2795158417, 3100091827, 3516721593, 2945490326, \r
+3602499001, 3521434557, 3751929072, 753121683, 419439893, 775045944, 1531849792, 3079364431, \r
+2496697562, 1973347978, 2642321331, 640560010, 576069938, 1650806093, 1535203697, 1640872121, \r
+2742803123, 2613072042, 2124727423, 2189133933, 4139494075, 2759041935, 1381329031, 541404433, \r
+1362906426, 1429748777, 2084009323, 2373626259, 2593100193, 2358686598, 2091621790, 1465539671, \r
+1583706204, 1886347898, 975208294, 1363632487, 1935823956, 946229594, 2240895555, 2191888225, \r
+2390983306, 1887403645, 2124250210, 1870566243, 1835953539, 1599108460, 1904251790, 2742060194, \r
+2490533256, 811960975, 1363095601, 1280002383, 1145782846, 1736329302, 1734109795, 1668510046, \r
+2103997315, 1517617249, 1600877909, 2003913305, 1516531857, 3452262745, 3050230728, 3687631796, \r
+3485124796, 3247605169, 3198919588, 2965625026, 3553933556, 3488455591, 3298668501, 3386900417, \r
+1121444523, 2053138312, 1718514047, 2156231292, 2156107905, 2576979157, 3451559576, 3197732814, \r
+2574951854, 2712578788, 3469650659, 2175774899, 2662191000, 3233334209, 3569590192, 2932189900, \r
+2343098844, 2174452335, 2474345851, 2541326462, 1986957694, 2071952761, 2087875199, 2239597415, \r
+1279146752, 994597186, 995314506, 1581011300, 2254015349, 2307685542, 1920107661, 1500542585, \r
+1699104851, 1346648656, 1112095576, 2357881129, 2088986228, 2273866093, 2004582007, 1347845258, \r
+1499752782, 1313368927, 1416781386, 2004314753, 1870237053, 2440464782, 2809296265, 3974676367, \r
+3034044631, 3219968496, 3538808828, 1466729846, 2171362715, 1650950509, 1347116883, 1514950752, \r
+2474345068, 2426119528, 2726913926, 1907078051, 3366226121, 2077145027, 1788913854, 2726201197, \r
+2646515330, 2659885501, 3032376487, 2409982665, 3113932444, 2613536936, 3064319093, 3148848293, \r
+3435626432, 1264616120, 1617652041, 2139587416, 1754302577, 1493124980, 3266606493, 2055952974, \r
+942770025, 2654488926, 2429653944, 2727262856, 1718530920, 2521332559, 1869572497, 2982395019, \r
+2359020923, 3831675295, 1388429980, 3853345485, 2057997418, 663837184, 1329178416, 2672133019, \r
+2210686602, 2439425599, 1436110957, 2237248153, 1467562333, 1783271337, 2352829833, 507061085, \r
+1656697378, 2071754653, 3165563541, 3432497078, 3014483563, 3182796473, 2845743270, 2659362218, \r
+1482271664, 1397761126, 976052517, 1614623286, 1954046781, 2341045138, 3043857568, 2528088937, \r
+3164848518, 3230631632, 2511779257, 2311367643, 1192971871, 879320619, 927683133, 2644597295, \r
+2424998574, 2361438377, 2494993306, 2947061721, 2827385508, 2760146854, 2056292473, 1953075585, \r
+1801416554, 2241429610, 1499626084, 2831427327, 2912991444, 2748104621, 3434459344, 3161544120, \r
+1664705917, 2775807885, 2156959882, 1802470534, 1465475970, 1010910569, 3411826774, 2038477945, \r
+2793114267, 2609870749, 2361099882, 1704755056, 2172754054, 1869896306, 2304166993, 1704104343, \r
+3145826197, 2574557301, 3264116098, 2759949672, 2983825051, 2777467548, 2186236261, 1801604946, \r
+1566390840, 4280958268, 1785490758, 1804433024, 2052623457, 2004834940, 2222097040, 2189126280, \r
+2440661612, 1351709822, 1130246730, 1130194513, 1211847250, 739138121, 1345060934, 875769619, \r
+1194143310, 864310579, 1061902375, 943671629, 927675969, 542131476, 538788109, 573515071, \r
+1429625127, 1515676251, 2135580280, 1633899336, 2052940633, 1616800352, 1735155578, 2038328956, \r
+1952077162, 2839269486, 2119645570, 2725013096, 4285231246, 2295176626, 2761989708, 1604161102, \r
+966568612, 3267982262, 2225164192, 1347116168, 3245959801, 2657584094, 3532534226, 1706116206, \r
+2699781753, 1250918771, 1050030948, 2053276023, 918602396, 914198086, 1898361320, 1866741664, \r
+778275680, 1648073342, 2391638842, 2788266378, 2896942728, 2926406523, 2627297685, 2158414518, \r
+2708508564, 2909497989, 2524941698, 2205649541, 2239069841, 2390390668, 2540801420, 1515998570, \r
+1566665821, 1635676260, 1902737760, 1400857176, 2589749109, 1788577386, 1819446894, 876615474, \r
+992625688, 1293895265, 1901145910, 1231390343, 1851948656, 1900967827, 2590921597, 2376958095, \r
+1904918399, 2342233514, 2441053353, 1735165321, 2440784515, 1735491702, 2155964927, 2809035625, \r
+2207021692, 2391313012, 1249743499, 2141939554, 1398433898, 2002222160, 2423817607, 2593560180, \r
+2559676062, 1837791107, 2676520331, 2425207181, 2007142294, 2390396557, 2558495127, 2626919816, \r
+2106040464, 2578083216, 2358220702, 2191168897, 2393341342, 1550940322, 2609680023, 1834781078, \r
+1687181943, 2022471058, 2289994103, 2207745666, 11769496, 2104785526, 2038461581, 2390787979, \r
+2138083961, 2425919856, 2391572612, 2124258192, 1854112381, 1919186302, 2037154420, 2088340613, \r
+1904572291, 2577176979, 2594207860, 2475263097, 1717803133, 2071298422, 2005502830, 2323027084, \r
+2071490969, 2156299407, 2207742336, 2021094813, 1702917467, 2153674376, 2005760908, 2021748099, \r
+2205124980, 2037937263, 2004123778, 1979665789, 1737061246, 1483829864, 2237367414, 2170718853, \r
+1433098856, 1129205354, 1380020832, 2846591605, 2946477235, 3115751121, 2493300110, 1618776233, \r
+2104186204, 1903711346, 1752848788, 2763242619, 2846612917, 3183319212, 2124066722, 1467123354, \r
+2238617961, 2106619292, 2190176922, 1952082786, 1567981668, 2322754423, 2576310150, 2460917402, \r
+2310643867, 2459206795, 2341011636, 2341242488, 2290315126, 1718583914, 1804363632, 2457436529, \r
+1786020992, 1734768745, 2391313524, 2290124416, 2407762799, 1937016713, 2290256022, 2526188679, \r
+2022207338, 2020243055, 2155711111, 1888518269, 2155181436, 2375125370, 2591846588, 1803588502, \r
+2019004298, 2240511109, 2173013875, 1938199673, 2136703357, 2037088638, 2037476992, 2173467254, \r
+2928182152, 1767476480, 2155047513, 1855028091, 1635546487, 1802851469, 1684236373, 1418168434, \r
+1654559071, 880038190, 2976928192, 75192611, 1613852210, 2474148006, 2352785008, 880696421, \r
+1735030632, 1347906854, 926234289, 1580011651, 2072011858, 2342615406, 2106360925, 2424725858, \r
+2456856203, 2057729147, 2425914512, 680491924, 942351872, 272386370, 1075784532, 223417400, \r
+2289732708, 2172745070, 2292015768, 2610265726, 1801557383, 2288616595, 2123206755, 2579280554, \r
+2141693038, 2055368836, 1704106869, 2036489087, 1933993607, 1586067040, 2205979278, 2359462758, \r
+2893644984, 1871816835, 1819967618, 2321196126, 1938321270, 2390337650, 2391567492, 1011969389, \r
+1145269829, 2323997046, 2474934148, 2593821583, 1903919745, 1718452331, 2566869134, 2088336735, \r
+1768584045, 1853705074, 2002814825, 1854174350, 2070637173, 1836217955, 1531271273, 1817731670, \r
+1835885418, 1719427165, 1380998524, 1615548297, 1802988386, 1112762726, 1513177969, 1635863131, \r
+1617198709, 2036233325, 1550869597, 1653106536, 1584953955, 1735017571, 2322237857, 2289654926, \r
+2155444618, 1818526043, 2172937324, 2155645287, 1787329928, 1869348720, 1098010173, 1148665649, \r
+1313635206, 3335604065, 2932261844, 3114845123, 2997408686, 3650455245, 3232730563, 3101084331, \r
+2879444479, 3655836344, 2813510858, 3167485386, 1120457130, 2053340558, 2558880905, 2257675878, \r
+2509735775, 3029969598, 3197283208, 3298792929, 2591989965, 2190385618, 2881268924, 2611122603, \r
+3368475064, 2831270849, 3703754194, 3570382547, 1938086085, 2708768431, 2072483460, 1720615574, \r
+2760598124, 2122485382, 2676594091, 1955110036, 927681913, 1480077163, 1548242512, 2540127291, \r
+1869904749, 2170515820, 2455537023, 1650360439, 71970048, 1260926013, 1648570958, 1884395568, \r
+1972672891, 2069392758, 1987211647, 3031992940, 2308616065, 2426509711, 2691531403, 1550022497, \r
+1481662574, 1669364825, 4134232422, 1920696147, 2339077758, 2123470965, 1888064142, 2272499073, \r
+2141162872, 2273148287, 2592964984, 2006024310, 2122154631, 2289992831, 2692189323, 2188411008, \r
+1803191189, 2424212098, 2325052307, 1786680201, 2424997243, 2340128124, 2022150764, 1801871991, \r
+2222153081, 2039052897, 2474019987, 2642646396, 2357489284, 2290449762, 2240055403, 2340582794, \r
+1903979392, 1929426571, 1904683390, 1314475352, 1044483653, 2991021142, 3436952475, 2896471235, \r
+2846083495, 2897586346, 3467424449, 3537093822, 3819892156, 4285577177, 1891735724, 4058949567, \r
+3051859857, 2140376362, 2287844469, 3046086063, 2479464615, 2794902639, 2340459195, 3396725189, \r
+2526901393, 2592393647, 2979576224, 2440727990, 2376300652, 2896734613, 3015024300, 3148593599, \r
+2161810079, 2207148628, 1820629361, 2808320918, 1853394335, 2051175227, 1870219117, 2274139258, \r
+3016012905, 2410185614, 2258350715, 2828306350, 1532043376, 1835222294, 2334538587, 1867272248, \r
+2758511294, 2088539050, 1869257847, 1383179632, 1363236976, 2370921837, 1265923928, 2592969026, \r
+1821940347, 3013586096, 3686909375, 2795350881, 2040229548, 2205188980, 2641720451, 1886936832, \r
+2039181460, 1902744431, 1987279791, 3092998801, 2036499098, 2375320456, 2425455008, 2356647313, \r
+1569099900, 1954051435, 2490395244, 1584506484, 2239524255, 2842187113, 1470325370, 1719432537, \r
+1970367889, 1834708810, 1835576928, 2108056430, 2088668568, 1684643688, 2523425654, 1920307807, \r
+2377092483, 2576527989, 2574682761, 2323547290, 2003332214, 4283989105, 3245645450, 2577700237, \r
+2709294219, 2879559284, 1499356190, 1417251931, 1415146332, 2540791913, 2997988319, 3028726678, \r
+2914025632, 1016510371, 1900834320, 1953045363, 459109902, 1133927031, 1044604272, 2122724961, \r
+1380737870, 1744834395, 774586206, 2198613563, 2808887637, 2526395809, 2845610679, 2175177603, \r
+2143455165, 2036883313, 1803310215, 1736806497, 2033138769, 1297424747, 2415935416, 1931540780, \r
+1757513703, 2201366702, 3960144790, 7451984, 2398906593, 1584018595, 1308642221, 2487153475, \r
+2373280234, 1330859195, 3003149514, 1849472584, 1906872750, 2132886965, 3423542948, 257147962, \r
+1543480244, 3346745405, 1023423147, 1635630660, 2094875592, 4151293244, 3329097804, 1521713574, \r
+1975071628, 3814904908, 3848274005, 1892310492, 882795605, 2636013235, 3358261394, 794732382, \r
+2012245681, 867059345, 3710660, 4267028797, 3328486025, 2553571745, 2986475666, 1046724188, \r
+1357339829, 1353462935, 2571075042, 2101018428, 746684145, 2774308270, 2050839654, 2608513905, \r
+820248761, 2450813546, 2283360694, 1061349960, 1711240436, 1503020695, 1442866602, 2469389101, \r
+1218267894, 6501194, 1011708036, 2939926537, 3465139899, 1773323985, 4286869911, 1819226277, \r
+3393746494, 2899755879, 4007692349, 46477823, 1214127959, 1389576518, 1736760831, 137411092, \r
+1424663764, 4259163648, 3063949428, 298340022, 2257280323, 4287679930, 4137826648, 381962183, \r
+1554979893, 1167162935, 2074607499, 2256830053, 3309878399, 3124619724, 1624671488, 2007867337, \r
+1086023072, 986556891, 1255764104, 3905581392, 2785046313, 2942366121, 4287853618, 210129331, \r
+2090798413, 3730287724, 2957508689, 72732548, 2143486161, 4150722403, 3196078125, 817854965, \r
+1970947411, 3849551872, 766776677, 2614774200, 2244268868, 3329145982, 3227726106, 963616429, \r
+2008219753, 3617624641, 4286462585, 182998183, 2108975468, 2461093632, 1174236838, 1005588121, \r
+879032648, 2250709088, 3050805628, 2952816472, 1227059541, 2277181184, 3978962151, 1446378264, \r
+23989941, 693851024, 1331647425, 2591576943, 3330867072, 2434662316, 3017015599, 3015839999, \r
+3660537922, 3080935749, 2234515604, 159229807, 1388531909, 3412166836, 3479531887, 1132169352, \r
+1485963396, 2415897180, 2341820502, 4170597793, 1747209811, 1167275888, 1571195834, 2804706048, \r
+2994048137, 4282560159, 796494437, 2744807375, 1102536364, 1266442358, 427520663, 3683148434, \r
+3042049944, 3563430995, 3677103954, 76133281, 1473773731, 1016280682, 110192578, 3551362407, \r
+3209953153, 1434764287, 4106205274, 543906461, 2400339489, 3011815829, 3192863069, 542478470, \r
+2092433573, 362132874, 1504362403, 4284052855, 2416740432, 1519585536, 793081533, 3295196228, \r
+1818725023, 28410624, 1188719201, 3211149326, 1968088164, 1047930258, 1058077054, 3195213762, \r
+3172068641, 1037083392, 3199290160, 3190810010, 3191101268, 3177867394, 3216281462, 1034079538, \r
+1037628998, 3216993604, 1051294694, 1040306213, 1054331623, 3195193217, 3205042508, 1013177149, \r
+3174890906, 3204078746, 1055382020, 1048493948, 3192172859, 3199930841, 1066843317, 1040417215, \r
+3202514636, 1043437172, 3196864225, 3191710319, 3196627622, 1041420978, 1032051425, 1033969306, \r
+1034689191, 1045201520, 1030816114, 3196743503, 1036266732, 3188901321, 1058093398, 3190885268, \r
+3166849516, 1053422227, 3154349190, 1044440478, 3185250501, 3185433520, 3191817392, 3173354491, \r
+3189560285, 1050689749, 1041869260, 3181591239, 1019383768, 3192930724, 1058101848, 3190464064, \r
+1024318092, 1041742650, 3168562461, 1048195374, 3184696862, 3216057297, 1068482953, 3214881081, \r
+1067315927, 3234987196, 1087503548, 1057921567, 1059576087, 1057527962, 1059869773, 1059935257, \r
+1062565932, 1054567980, 1055934164, 1060113955, 1063546876, 1063286439, 1062820932, 1065353216, \r
+1059717957, 1055044951, 1056698388, 1059235467, 1060375340, 1060677206, 1057916914, 1057652166, \r
+1053917533, 1059083774, 1052269900, 1060184169, 1059124754, 1061477498, 1056532185, 1052272069, \r
+1055281643, 1057635352, 1060379793, 1051204302, 1058416541, 1060006691, 1061419975, 1054937523, \r
+1061235429, 1052790966, 1055892888, 1060132037, 1058809836, 1058539090, 1061701273, 1056931618, \r
+1053633995, 1059829230, 1055759650, 1062913075, 1053071356, 1059480047, 1061441591, 1059342007, \r
+1055999485, 1060575684, 1057885457, 1063821826, 1052438328, 1065353216, 1059979609, 1063429017, \r
+1053774029, 1062372751, 1057072245, 1050815640, 1050033265, 1043018837, 1058087866, 1057225763, \r
+1057472273, 1051448397, 1046388967, 1053507959, 1054771718, 1056329752, 1053123053, 1055555522, \r
+1057584925, 1047416510, 1047729929, 1046796289, 1051578329, 1048401007, 1053878631, 1058587683, \r
+1051487216, 1060015917, 1053785070, 1056318049, 1057975118, 1054732544, 1050208612, 1057288790, \r
+1053033657, 1050682586, 1048891004, 1046460132, 3189681285, 1041024799, 3196711699, 1049163915, \r
+1040619896, 1028321096, 1031040341, 3193175832, 3171861617, 3196079026, 1049402785, 1032310106, \r
+1047353772, 3197765313, 3180313333, 1035898995, 1029101441, 1037491068, 1016311807, 1029377976, \r
+3181481127, 1046606139, 1046980825, 3170404254, 3129182093, 1044579493, 3194416252, 1032688604, \r
+1044922561, 988133882, 1047356562, 3190925225, 1043887229, 3174346728, 1051735017, 3192145061, \r
+3172751232, 1017827586, 1028093246, 1038227108, 1001421494, 1054986195, 3192711542, 990419090, \r
+3195085887, 1041128997, 3192068156, 3184379530, 3188617818, 3173074324, 1041456962, 1009650467, \r
+990787154, 1041447534, 3196348620, 3196943026, 3180609328, 3188344222, 1033624404, 3188267753, \r
+3190436579, 1011796963, 3173869973, 1033920345, 3199742386, 3184478387, 3185633928, 3181073513, \r
+3190901377, 1057583437, 3188456474, 3189327578, 3181075734, 3187278857, 1041613697, 3176336589, \r
+3183609472, 1024654348, 3196639283, 3188975902, 1047228155, 1043238559, 1026972482, 1017758561, \r
+1040265668, 1048281270, 1045654027, 3171579020, 3179324414, 3171683725, 1023724961, 1036536208, \r
+1041774111, 3185681164, 3162958865, 1044762653, 3185853448, 1040950808, 3183031591, 1037163404, \r
+3181097716, 3192944701, 3184692725, 3183998343, 1048008498, 3190456268, 1040353281, 1045661915, \r
+1039646220, 3169876660, 3188798258, 1016365490, 1038780111, 3187706760, 1044572204, 1034158982, \r
+3181052333, 1020570210, 3188436346, 3186692277, 3169791380, 1024201487, 1031101508, 3190939499, \r
+1033361538, 3163140062, 1043798465, 3180771913, 1042875665, 1054349203, 3183265110, 3170239690, \r
+1049288213, 1030572887, 3173707204, 1040251286, 1033934290, 1024237712, 1041888006, 3179315546, \r
+1016084168, 3194920421, 1047469739, 1033404872, 1023265531, 1049500085, 3198488456, 1046243196, \r
+3182480057, 1036598369, 1016299742, 3180404920, 3178300419, 3195842785, 1049630190, 1044212751, \r
+1050209738, 3201718112, 1036951145, 3174397558, 1011283832, 1048922550, 3190459611, 1037349260, \r
+1043032796, 3172570506, 3192970395, 1019381837, 3179074634, 3171671988, 1053123825, 3155715284, \r
+3176653376, 3197451892, 1040528991, 1025842119, 3172699243, 3159077121, 3190454845, 1036579691, \r
+1034102014, 3184608221, 3173236380, 3187247908, 1040835651, 3191247130, 1049566217, 1048694648, \r
+1019362177, 3187510235, 1014081150, 1025985867, 3166942466, 1029963407, 1018500061, 3167145142, \r
+1015247949, 1046534753, 3146050964, 1042003374, 1021866089, 3163759270, 1049638554, 1045233032, \r
+1038264781, 1041385495, 3188168587, 3199635024, 1042193764, 1044473208, 3165704205, 1046415037, \r
+1045263052, 1034938499, 1046903359, 1047791629, \r
+};\r
+\r
+uint32_t* get_Spo2WRWeights_addr(void)\r
+{\r
+    return (uint32_t *)(Spo2WRWeights);\r
+}\r
+uint32_t get_Spo2WRWeights_size(void)\r
+{\r
+    return sizeof(Spo2WRWeights) / sizeof(Spo2WRWeights[0]);\r
+}\r
+void get_Spo2WRWeights_version(char* ver, uint8_t len)\r
+{\r
+    memcpy(ver, NET_VERSION, len);\r
+}\r
+#endif //#ifndef Goodix_DSP_EXPORTS\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/algo_params/goodix_ecg_config.c b/code/sdk/drivers/peripheral/ppg/gh3x2x/algo_params/goodix_ecg_config.c
new file mode 100644 (file)
index 0000000..1bcaf91
--- /dev/null
@@ -0,0 +1,31 @@
+#ifndef Goodix_DSP_EXPORTS\r
+#include "goodix_ecg.h"\r
+#include "gh3x2x_demo_algo_call.h"\r
+#if 0\r
+const goodix_ecg_config external_cfg =\r
+{\r
+       .fs = 500,\r
+       .valid_channel_num = 1,\r
+       .qrs_flag = 0,\r
+       .mode_type = 0,\r
+       .ic_type = 0\r
+};\r
+\r
+const void *goodix_ecg_config_get_arr()\r
+{\r
+       return &external_cfg;\r
+}\r
+\r
+int32_t goodix_ecg_config_get_size()\r
+{\r
+       return sizeof(goodix_ecg_config);\r
+}\r
+#endif\r
+\r
+void goodix_ecg_config_get_version(char* ver, uint8_t ver_len)\r
+{\r
+       uint32_t copy_num = ver_len < (strlen(ECG_INTERFACE_VERSION) + 1) ? ver_len : (strlen(ECG_INTERFACE_VERSION) + 1);\r
+       GH3X2X_Memcpy(ver, ECG_INTERFACE_VERSION, copy_num);\r
+       ver[copy_num - 1] = '\0'; //Èç¹ûECG_CONFIG_VERµÄ³¤¶È´óÓÚsize£¬ÐèÒªÌí¼Ó½áÊø·û\r
+}\r
+#endif\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/algo_params/goodix_hba_config.c b/code/sdk/drivers/peripheral/ppg/gh3x2x/algo_params/goodix_hba_config.c
new file mode 100644 (file)
index 0000000..00d3781
--- /dev/null
@@ -0,0 +1,31 @@
+#ifndef Goodix_DSP_EXPORTS\r
+#include "goodix_hba.h"\r
+#include "gh3x2x_demo_algo_call.h"\r
+#if 0\r
+const goodix_hba_config external_hba_cfg =\r
+{\r
+       .mode = HBA_TEST_DYNAMIC,                       // ÓÐЧͨµÀÊý\r
+       .scence = HBA_SCENES_DEFAULT,\r
+       .fs = 25,                           // Ô­Ê¼²ÉÑù\r
+       .valid_channel_num = 4,\r
+};\r
+\r
+const void *goodix_hba_config_get_arr()\r
+{\r
+       return &external_hba_cfg;\r
+}\r
+\r
+int32_t  goodix_hba_config_get_size()\r
+{\r
+       return sizeof(external_hba_cfg);\r
+}\r
+#endif\r
+\r
+void goodix_hba_config_get_version(char* ver, uint8_t ver_len)\r
+{\r
+       uint32_t copy_num = ver_len < (strlen(HBA_INTERFACE_VERSION) + 1) ? ver_len : (strlen(HBA_INTERFACE_VERSION) + 1);\r
+       GH3X2X_Memcpy(ver, HBA_INTERFACE_VERSION, copy_num);\r
+       ver[copy_num - 1] = '\0'; //Èç¹ûNET_VERSIONµÄ³¤¶È´óÓÚsize£¬ÐèÒªÌí¼Ó½áÊø·û\r
+}\r
+\r
+#endif //Goodix_DSP_EXPORTS\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/algo_params/goodix_hrv_config.c b/code/sdk/drivers/peripheral/ppg/gh3x2x/algo_params/goodix_hrv_config.c
new file mode 100644 (file)
index 0000000..7469f61
--- /dev/null
@@ -0,0 +1,34 @@
+#ifndef Goodix_DSP_EXPORTS\r
+#include <string.h>\r
+#include "goodix_hrv.h"\r
+#include "gh3x2x_demo_algo_call.h"\r
+#if 0\r
+const goodix_hrv_config external_hrv_cfg =\r
+{\r
+       .need_ipl = 1,                  // ÊÇ·ñÐèÒª²åÖµµ½1KHz\r
+       .fs = 100,                          // ²ÉÑùÂÊ\r
+       .acc_thr[0] = 200000,   // acc Ïà¹ØãÐÖµ£¬Ä¬ÈÏֵΪ£º20/10/3/3\r
+       .acc_thr[1] = 100000,\r
+       .acc_thr[2] = 30000,\r
+       .acc_thr[3] = 30000,\r
+};\r
+\r
+const void *goodix_hrv_config_get_arr()\r
+{\r
+       return &external_hrv_cfg;\r
+}\r
+\r
+int32_t goodix_hrv_config_get_size()\r
+{\r
+       return sizeof(external_hrv_cfg);\r
+}\r
+#endif\r
+\r
+void goodix_hrv_config_get_version(char* ver, uint8_t ver_len)\r
+{\r
+       uint32_t copy_num = ver_len < (strlen(HRV_INTERFACE_VERSION) + 1) ? ver_len : (strlen(HRV_INTERFACE_VERSION) + 1);\r
+       GH3X2X_Memcpy(ver, HRV_INTERFACE_VERSION, copy_num);\r
+       ver[copy_num - 1] = '\0'; //Èç¹ûNET_VERSIONµÄ³¤¶È´óÓÚsize£¬ÐèÒªÌí¼Ó½áÊø·û\r
+}\r
+\r
+#endif //Goodix_DSP_EXPORTS\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/algo_params/goodix_nadt_config.c b/code/sdk/drivers/peripheral/ppg/gh3x2x/algo_params/goodix_nadt_config.c
new file mode 100644 (file)
index 0000000..2259bd9
--- /dev/null
@@ -0,0 +1,63 @@
+#ifndef Goodix_DSP_EXPORTS\r
+#include "goodix_nadt.h"\r
+#include "gh3x2x_demo_algo_call.h"\r
+#if 0\r
+const goodix_nadt_config external_cfg =\r
+{\r
+       .sampleRateNADT = 25,                           //²ÉÑùÂÊ\r
+       .unwearDetectLevel = 3,                         //Åå´÷µÈ¼¶\r
+       .sleepStatus = 0,                                       //˯Ãß״̬\r
+       //\r
+       .checkTimeoutThr = 1200,                        //»îÌå¼ì²â³¬Ê±Ê±¼ä\r
+       .unwearCheckCntThr = 4,                         //ÍÑÂäÈ·ÈÏʱ¼ä\r
+       .wearCheckCntThr = 2,                           //»îÌåÈ·ÈÏʱ¼ä\r
+       //\r
+       //ADTÅжÏ\r
+       .adtWearOnThr = 8638608,                        //ADT wear onãÐÖµ\r
+       .adtWearOffThr = 8588608,                       //ADT wear offãÐÖµ\r
+       //\r
+       //Ô˶¯ÅжÏ\r
+       .accStdThr = 25,                                        //ACC±ê×¼²î\r
+       //\r
+       //»îÌå¼ì²â\r
+       .liveDetectEnable = 1,                          //»îÌå¼ì²âʹÄÜ\r
+       .rawPVLenThr = 300,                                     //¸ß´Îг²¨ãÐÖµ\r
+       .heartBeatThrLow = 50,                          //ÐÄÂÊÏÂÏÞ\r
+       .heartBeatThrHigh = 140,                        //ÐÄÂÊÉÏÏÞ\r
+       .difRrInterThr = 8,                                     //ÐÄÂʱ仯ãÐÖµ\r
+       .wearAcfScoreThr = 50,                          //×ÔÏà¹Ø·ÖÊýãÐÖµ\r
+       .baseLinePosRatioThr = 30,                      //»ùÏßµ¥µ÷ÂÊãÐÖµ\r
+       .baseLineDiffThr = 15,                      //»ùÏ߯½Ì¹ÐÔãÐÖµ\r
+       .sigScaleThr = 1000,\r
+       //\r
+       //¸ßƵ±³¾°¹â¼ì²â\r
+       .bgJumpDetectEnable = 1,                        //±³¾°¹âÍ»±ä¼ì²âʹÄÜ\r
+       .jumpBgDiffThr = 100,                           //±³¾°¹â±ä»¯Á¿ãÐÖµ\r
+       .bgPeakValleyNumThr = 12,                       //±³¾°¹â·å¹È¸öÊýãÐÖµ\r
+       //\r
+       //±³¾°¹âÖÜÆÚ¼ì²â\r
+       .bgPeriodDetectEnable = 1,                      //±³¾°¹âÖÜÆÚ¼ì²âʹÄÜ\r
+       .periodBgDiffThr = 10,                          //±³¾°¹â±ä»¯Á¿ãÐÖµ\r
+       .bgPeriodThr = 10,                                      //±³¾°¹âÖÜÆÚãÐÖµ\r
+       .bgPeriodDiffThr = 5                            //±³¾°¹âÖÜÆÚ²îÒìãÐÖµ\r
+};\r
+\r
+const void *goodix_nadt_config_get_arr()\r
+{\r
+       return &external_cfg;\r
+}\r
+\r
+GS32 goodix_nadt_config_get_size()\r
+{\r
+       return sizeof(goodix_nadt_config);\r
+}\r
+#endif\r
+\r
+void goodix_nadt_config_get_version(char* ver, GU8 ver_len)\r
+{\r
+       GU32 copy_num = ver_len < (strlen(NADT_INTERFACE_VERSION) + 1) ? ver_len : (strlen(NADT_INTERFACE_VERSION) + 1);\r
+       GH3X2X_Memcpy(ver, NADT_INTERFACE_VERSION, copy_num);\r
+       ver[copy_num - 1] = '\0'; //Èç¹ûNADT_CONFIG_VERµÄ³¤¶È´óÓÚsize£¬ÐèÒªÌí¼Ó½áÊø·û\r
+}\r
+\r
+#endif\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/algo_params/goodix_spo2_config.c b/code/sdk/drivers/peripheral/ppg/gh3x2x/algo_params/goodix_spo2_config.c
new file mode 100644 (file)
index 0000000..edee270
--- /dev/null
@@ -0,0 +1,63 @@
+#ifndef Goodix_DSP_EXPORTS\r
+\r
+#include "goodix_spo2.h"\r
+#include "gh3x2x_demo_algo_call.h"\r
+#if 0\r
+const goodix_spo2_config external_cfg =\r
+{\r
+       //raw 配置信息\r
+       .valid_chl_num = 1,                     // 有效通道数\r
+       .raw_fs = 25,                       // 原始采样率\r
+       //校准参数\r
+       .cali_coef_a4 = 0,                      //校准参数4次项\r
+       .cali_coef_a3 = 0,                      //校准参数3次项\r
+       .cali_coef_a2 = -1,                 //校准参数2次项\r
+       .cali_coef_a1 = -233736,    //校准参数1次项\r
+       .cali_coef_a0 = 1106394,        //校准参数常数项\r
+       //hb使能标志\r
+       .hb_en_flg = 1,                     //hb使能标志\r
+       //佩戴状态\r
+       .wear_mode = 0,                     //佩戴状态 0:手环  1:手指  2:耳机\r
+       // acc move thr\r
+       .acc_thr_max = 50,\r
+       .acc_thr_min = 25,\r
+       .acc_thr_scale = 3,\r
+       .acc_thr_num = 3,\r
+       .acc_thr_angle = 90,\r
+       //CTR设置\r
+       .ctr_en_flg = 1,\r
+       .ctr_red_thr = 65,\r
+       //信号质量评估相关阈值\r
+       .ppg_jitter_thr = 35,\r
+       .ppg_noise_thr = 25,\r
+       .ppg_coeff_thr = 70,\r
+       .quality_module_key = 253,\r
+       //出值策略\r
+       .low_spo2_thr = 95,\r
+       .fast_out_time = 10,\r
+       .slow_out_time = 30,\r
+       .min_stable_time_high = 2,\r
+       .min_stable_time_low = 7,\r
+       .max_spo2_variation_high = 10,\r
+       .max_spo2_variation_low = 5,\r
+       .ouput_module_key = 3\r
+};\r
+\r
+const void *goodix_spo2_config_get_instance()\r
+{\r
+       return &external_cfg;\r
+}\r
+\r
+int32_t  goodix_spo2_config_get_size()\r
+{\r
+       return sizeof(goodix_spo2_config);\r
+}\r
+#endif\r
+\r
+void goodix_spo2_config_get_version(char* ver,uint8_t ver_len)\r
+{\r
+       uint32_t copy_num = ver_len < (strlen(SPO2_INTERFACE_VERSION) + 1) ? ver_len : (strlen(SPO2_INTERFACE_VERSION) + 1);\r
+       GH3X2X_Memcpy(ver, SPO2_INTERFACE_VERSION, copy_num);\r
+       ver[copy_num - 1] = '\0'; //如果NET_VERSION的长度大于size,需要添加结束符\r
+}\r
+#endif\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_application/inc/gh3x2x_demo_accppg_sync.h b/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_application/inc/gh3x2x_demo_accppg_sync.h
new file mode 100644 (file)
index 0000000..9294328
--- /dev/null
@@ -0,0 +1,20 @@
+/**\r
+ * @copyright (c) 2003 - 2022, Goodix Co., Ltd. All rights reserved.\r
+ *\r
+ * @file    gh3x2x_demo_accppg_sync.h\r
+ *\r
+ * @brief   gh3x2x algo call demo code version\r
+ *\r
+ * @version ref gh3x2x_demo_algo_call_version.h\r
+ *\r
+ */\r
+\r
+#ifndef _GH3X2X_DEMO_ACCPPG_SYNC_H_\r
+#define _GH3X2X_DEMO_ACCPPG_SYNC_H_\r
+\r
+#include "gh3x2x_demo_algo_call.h"\r
+#include "gh3x2x_demo_algo_config.h"\r
+\r
+\r
+\r
+#endif\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_application/inc/gh3x2x_demo_algo_call.h b/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_application/inc/gh3x2x_demo_algo_call.h
new file mode 100644 (file)
index 0000000..e38010b
--- /dev/null
@@ -0,0 +1,76 @@
+/**\r
+ * @copyright (c) 2003 - 2022, Goodix Co., Ltd. All rights reserved.\r
+ *\r
+ * @file    gh3x2x_demo_algo_call.h\r
+ *\r
+ * @brief   gh3x2x algo call\r
+ *\r
+ * @version ref gh3x2x_demo_algo_call.h\r
+ *\r
+ */\r
+#ifndef _GH3X2X_DEMO_ALGO_CALL_H_\r
+#define _GH3X2X_DEMO_ALGO_CALL_H_\r
+\r
+#include "gh_drv.h"\r
+\r
+extern GCHAR* GH3X2X_GetAlgoCallDemoVersion(void);\r
+extern void GH3X2X_AlgoVersion(GU8 uchFunctionID, GCHAR version[120]);\r
+extern GS8 GH3X2X_AlgoInit(GU32 unFunctionID);\r
+extern GS8 GH3X2X_AlgoDeinit(GU32 unFunctionID);\r
+extern GS8 GH3X2X_AlgoCalculate(GU32 unFunctionID);\r
+\r
+extern void GH3X2X_AlgoCallConfigInit(const STGh3x2xFrameInfo * const  pstGh3x2xFrameInfo[], GU8 uchAlgoCfgIndex);\r
+extern void GH3X2X_InitAlgoConfigParameters(void);\r
+extern void GH3X2X_AlgoSensorEnable(GU8 uchAlgoGsensorEnable,GU8 uchAlgoCapEnable,GU8 uchAlgoTempEnable);\r
+\r
+extern void GH3X2X_SoftAdtParaInit(void);\r
+extern void GH3X2X_WriteAlgConfigWithVirtualReg(GU16 usVirtualRegAddr, GU16 usVirtualRegValue);\r
+\r
+/**\r
+ * @fn     GS8 GH3X2X_HbAlgorithmOutputTimeConfig(GS32 nOutputTime)\r
+ *\r
+ * @brief  Hb algorithm output time config\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   nOutputTime          valid 7~GS32_MAX\r
+ * @param[out]  None\r
+ *\r
+ * @return  error code\r
+ * @retval  #GH3X2X_RET_OK                      return successfully\r
+ * @retval  #GH3X2X_RET_ALGO_NO_SUPPORTED       return algorithm no supported error\r
+ */\r
+extern GS8 GH3X2X_HbAlgorithmOutputTimeConfig(GS32 nLatestOutputTime, GS32 nEarliestOutputTime);\r
+\r
+/**\r
+ * @fn     GS8 GH3X2X_HbAlgorithmScenarioConfig(GU8 uchScenario)\r
+ *\r
+ * @brief  Hb algorithm scenario config\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]  uchScenario     @ref EMHbaScenesConfigType\r
+ *                             others: fixed 0(default) and return GH3X2X_RET_PARAMETER_ERROR\r
+ * @param[out]  None\r
+ *\r
+ * @return  error code\r
+ * @retval  #GH3X2X_RET_OK                      return successfully\r
+ * @retval  #GH3X2X_RET_PARAMETER_ERROR         return paramters error\r
+ * @retval  #GH3X2X_RET_ALGO_NO_SUPPORTED       return algorithm no supported error\r
+ */\r
+extern GS8 GH3X2X_HbAlgorithmScenarioConfig(GU8 uchScenario);\r
+extern GS8 GH3X2X_BTAlgorithmRTConfig(GU16 *nRTtable);\r
+extern GU8 GH3X2X_TimestampSyncGetFrameDataFlag(void);\r
+extern void GH3X2X_TimestampSyncAccInit(void);\r
+extern void GH3X2X_TimestampSyncPpgInit(GU32 unFunctionID);\r
+extern void GH3X2X_TimestampSyncSetPpgIntFlag(GU8 uchPpgIntFlag);\r
+extern void GH3X2X_TimestampSyncFillAccSyncBuffer(GU32 unTimeStamp,\r
+                                           GS16 usAccX,\r
+                                           GS16 usAccY,\r
+                                           GS16 usAccZ);\r
+extern void GH3X2X_TimestampSyncFillPpgSyncBuffer(GU32 unTimeStamp,\r
+                                           const STGh3x2xFrameInfo * const pstFrameInfo);\r
+\r
+#endif /* _GH3X2X_DEMO_ALGO_CALL_H_ */\r
+\r
+/********END OF FILE********* Copyright (c) 2003 - 2022, Goodix Co., Ltd. ********/\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_application/inc/gh3x2x_demo_algo_call_version.h b/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_application/inc/gh3x2x_demo_algo_call_version.h
new file mode 100644 (file)
index 0000000..bb0b55e
--- /dev/null
@@ -0,0 +1,25 @@
+/**\r
+ * @copyright (c) 2003 - 2022, Goodix Co., Ltd. All rights reserved.\r
+ *\r
+ * @file    gh3x2x_demo_version.h\r
+ *\r
+ * @brief   gh3x2x algo call demo code version\r
+ *\r
+ * @version ref gh3x2x_demo_algo_call_version.h\r
+ *\r
+ */\r
+\r
+#ifndef _GH3X2X_DEMO_ALGO_CALL_VERSION_H_\r
+#define _GH3X2X_DEMO_ALGO_CALL_VERSION_H_\r
+\r
+#define   GOODIX_DEMO_MAJOR_VERSION_NUMBER        0      /**< major version number */\r
+#define   GOODIX_DEMO_MINOR_VERSION_NUMBER        5      /**< minor version number */\r
+\r
+#define   GOODIX_TO_STRING(x)       #x                      /**< number to char */\r
+#define   GOODIX_STR(x)             GOODIX_TO_STRING(x)     /**< number to char */\r
+\r
+/// makeup version string\r
+#define   GOODIX_ALGO_CALL_VERSION_STRING     "Goodix_Algocall_"\\r
+                                              "v"GOODIX_STR(GOODIX_DEMO_MAJOR_VERSION_NUMBER)\\r
+                                              "."GOODIX_STR(GOODIX_DEMO_MINOR_VERSION_NUMBER)\r
+#endif\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_application/inc/gh3x2x_demo_algo_config.h b/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_application/inc/gh3x2x_demo_algo_config.h
new file mode 100644 (file)
index 0000000..251f7d0
--- /dev/null
@@ -0,0 +1,131 @@
+/**\r
+ * @copyright (c) 2003 - 2022, Goodix Co., Ltd. All rights reserved.\r
+ *\r
+ * @file    gh3x2x_demo_algo_config.h\r
+ *\r
+ * @brief   gh3x2x algo config\r
+ *\r
+ * @version ref gh3x2x_demo_algo_config.h\r
+ *\r
+ */\r
+#ifndef _GH3X2X_DEMO_ALGO_CONFIG_H_\r
+#define _GH3X2X_DEMO_ALGO_CONFIG_H_\r
+\r
+#ifdef GOODIX_DEMO_PLATFORM\r
+//#include "Goodix_Platform_config.h"\r
+#endif\r
+\r
+#define GH3X2X_ALGO_FUNCTION_GROUP_0 (GH3X2X_FUNCTION_HR|GH3X2X_FUNCTION_SPO2|GH3X2X_FUNCTION_HRV|GH3X2X_FUNCTION_SOFT_ADT_GREEN)\r
+#define GH3X2X_ALGO_FUNCTION_GROUP_1 (GH3X2X_FUNCTION_SPO2)\r
+#define GH3X2X_ALGO_FUNCTION_GROUP_2 (GH3X2X_FUNCTION_ECG)\r
+#define GH3X2X_ALGO_FUNCTION_GROUP_3 (GH3X2X_FUNCTION_HRV)\r
+#define GH3X2X_ALGO_FUNCTION_GROUP_4 (GH3X2X_NO_FUNCTION)\r
+\r
+#define GOODIX_ALGO_BASIC                      (1)\r
+#define GOODIX_ALGO_MEDIUM                     (2)\r
+#define GOODIX_ALGO_PREMIUM                    (3)\r
+#define GOODIX_ALGO_EXCLUSIVE                  (4)\r
+\r
+#define GOODIX_ECG_ALGO_500FS_QRS_ENABLE       (1)\r
+#define GOODIX_ECG_ALGO_500FS_QRS_DISABLE      (2)\r
+#define GOODIX_ECG_ALGO_250FS_QRS_ENABLE       (3)\r
+#define GOODIX_ECG_ALGO_250FS_QRS_DISABLE      (4)\r
+\r
+#ifndef __GOODIX_HR_ALGO_VERISON__\r
+#define __GOODIX_HR_ALGO_VERISON__             (GOODIX_ALGO_EXCLUSIVE)\r
+#endif \r
+#ifndef __GOODIX_SPO2_ALGO_VERISON__\r
+#define __GOODIX_SPO2_ALGO_VERISON__           (GOODIX_ALGO_EXCLUSIVE)\r
+#endif \r
+#ifndef __GOODIX_ECG_ALGO_CONFIG__\r
+#define __GOODIX_ECG_ALGO_CONFIG__             (GOODIX_ECG_ALGO_250FS_QRS_ENABLE)\r
+#endif \r
+\r
+#if ((__GOODIX_HR_ALGO_VERISON__ == GOODIX_ALGO_BASIC) || (__GOODIX_HR_ALGO_VERISON__ == GOODIX_ALGO_MEDIUM))\r
+#if ((__GOODIX_SPO2_ALGO_VERISON__ == GOODIX_ALGO_PREMIUM) || (__GOODIX_SPO2_ALGO_VERISON__ == GOODIX_ALGO_EXCLUSIVE))\r
+#error "HR algo BASIC\MEDIUM version should adapt to SPO2 BASIC\MEDIUM version"\r
+#endif\r
+#endif\r
+\r
+#if ((__GOODIX_HR_ALGO_VERISON__ == GOODIX_ALGO_PREMIUM) || (__GOODIX_HR_ALGO_VERISON__ == GOODIX_ALGO_EXCLUSIVE))\r
+#if ((__GOODIX_SPO2_ALGO_VERISON__ == GOODIX_ALGO_BASIC) || (__GOODIX_SPO2_ALGO_VERISON__ == GOODIX_ALGO_MEDIUM))\r
+#error "HR algo PREMIUM\EXCLUSIVE version should adapt to SPO2 PREMIUM\EXCLUSIVE version"\r
+#endif\r
+#endif\r
+\r
+/* 0: global buffer for goodix algorithm mem pool\r
+ * 1: user dynamic buffer for goodix algorithm mem pool */\r
+#define __USER_DYNAMIC_ALGO_MEM_EN__           (0)\r
+#if __USER_DYNAMIC_ALGO_MEM_EN__\r
+#define GH3X2X_ALGORITHMS_MEMORY_SIZE_USERSET  (0)\r
+#endif\r
+\r
+/* function algo enable config */\r
+#define __USE_GOODIX_ADT_ALGORITHM__           (0)\r
+#define __USE_GOODIX_HR_ALGORITHM__            (1)\r
+#define __USE_GOODIX_HRV_ALGORITHM__           (1)\r
+#define __USE_GOODIX_HSM_ALGORITHM__           (0)\r
+#define __USE_GOODIX_SPO2_ALGORITHM__          (1)\r
+#define __USE_GOODIX_ECG_ALGORITHM__           (1)\r
+#define __USE_GOODIX_BT_ALGORITHM__            (1)\r
+#define __USE_GOODIX_RESP_ALGORITHM__          (0)\r
+#define __USE_GOODIX_AF_ALGORITHM__            (0)\r
+#define __USE_GOODIX_BP_ALGORITHM__            (0)\r
+#define __USE_GOODIX_SOFT_ADT_ALGORITHM__      (1)\r
+\r
+/* algorithm log */\r
+#define __GH3X2X_ALGO_LOG_LV_0__                (0)    /** no log **/\r
+#define __GH3X2X_ALGO_LOG_LV_1__                (1)    /** include EXAMPLE LOG information **/\r
+#define __GH3X2X_ALGO_LOG_LV_2__                (2)    /** include EXAMPLE LOG debug **/\r
+\r
+#define __ALGO_LOG_CONFIG__                    (__GH3X2X_ALGO_LOG_LV_0__) \r
+\r
+/* BT NTC Drv Convert config*/\r
+#if __USE_GOODIX_BT_ALGORITHM__\r
+#define __USE_GOODIX_DRV_NTC_Convert                       (1)\r
+#endif\r
+\r
+/* algorithm config max number */\r
+#define __GOODIX_ALGO_CFG_LIST_MAX_NUM__       (1)\r
+\r
+/*algorithm output value process strategy config*/\r
+#define __GH3X2X_HR_OUTPUT_VALUE_STRATEGY_EN__ (0)\r
+\r
+/* algoritm channel nunber config*/\r
+#define __HR_ALGORITHM_SUPPORT_CHNL_NUM__      (4)  /* range 1~4 */\r
+#define __SPO2_ALGORITHM_SUPPORT_CHNL_NUM__    (1)  /* range 1-4 */\r
+\r
+/* algo and drv interactivity*/\r
+#define __GH_MSG_WTIH_DRV_LAYER_EN__           (0)\r
+#define __GH_SEPARATE_ALGO_EN__                (0)\r
+\r
+#if (__USE_GOODIX_SOFT_ADT_ALGORITHM__)\r
+#define __SOFT_ADT_IR_DETECT_TIMEOUT__         (30) /** (recomended value = 30 seconds) ir detect timeout **/\r
+#endif\r
+\r
+#define GH_SEND_MSG_WEAR_EVENT(event)   //add your code to send message to drv layer\r
+\r
+\r
+\r
+/***********************************  DO NOT MODIFY FOLLOWING CODE *******************************/\r
+#if (\\r
+    __USE_GOODIX_HR_ALGORITHM__      ||\\r
+    __USE_GOODIX_HRV_ALGORITHM__     ||\\r
+    __USE_GOODIX_HSM_ALGORITHM__     ||\\r
+    __USE_GOODIX_SPO2_ALGORITHM__    ||\\r
+    __USE_GOODIX_ECG_ALGORITHM__     ||\\r
+    __USE_GOODIX_BT_ALGORITHM__      ||\\r
+    __USE_GOODIX_RESP_ALGORITHM__    ||\\r
+    __USE_GOODIX_AF_ALGORITHM__      ||\\r
+    __USE_GOODIX_BP_ALGORITHM__      ||\\r
+    __USE_GOODIX_SOFT_ADT_ALGORITHM__\\r
+    )\r
+#define __GOODIX_ALGO_CALL_MODE__           (1)\r
+#else\r
+#define __GOODIX_ALGO_CALL_MODE__           (0)\r
+#endif\r
+\r
+\r
+#endif /* _GH3X2X_DEMO_ALGO_CALL_H_ */\r
+\r
+/********END OF FILE********* Copyright (c) 2003 - 2022, Goodix Co., Ltd. ********/\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_application/inc/gh3x2x_demo_algo_hook.h b/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_application/inc/gh3x2x_demo_algo_hook.h
new file mode 100644 (file)
index 0000000..aea2e77
--- /dev/null
@@ -0,0 +1,128 @@
+#include <stdio.h>\r
+#include "gh_drv.h"\r
+#include "gh3x2x_demo_algo_config.h"\r
+\r
+#ifdef GOODIX_DEMO_PLATFORM\r
+#include "gh3x2x_demo_goodix_PLATFORM.h"\r
+#else\r
+#define GOODIX_PLATFORM_NADT_RESULT_HANDLE_ENTITY()\r
+#define GOODIX_PLATFORM_LOG_ENTITY()\r
+#endif\r
+\r
+#if (__GOODIX_ALGO_CALL_MODE__)\r
+\r
+/**\r
+ * @fn     void GH3X2X_AdtAlgorithmResultReport(STHbAlgoResult stHbAlgoRes[], GU16 pusAlgoResIndexArr[], usAlgoResCnt)\r
+ *\r
+ * @brief  This function will be called after calculate adt algorithm.\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   stHbAlgoRes             hb algorithm result array\r
+ * @param[in]   pusAlgoResIndexArr      frame index of every algo result\r
+ * @param[in]   usAlgoResCnt            number of algo result\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_AdtAlgorithmResultReport(STGh3x2xAlgoResult * pstAlgoResult, GU32 lubFrameId);\r
+\r
+/**\r
+ * @fn     void GH3X2X_HrAlgorithmResultReport(STHbAlgoResult stHbAlgoRes[], GU16 pusAlgoResIndexArr[], usAlgoResCnt)\r
+ *\r
+ * @brief  This function will be called after calculate hb algorithm.\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   stHbAlgoRes             hb algorithm result array\r
+ * @param[in]   pusAlgoResIndexArr      frame index of every algo result\r
+ * @param[in]   usAlgoResCnt            number of algo result\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_HrAlgorithmResultReport(STGh3x2xAlgoResult * pstAlgoResult, GU32 lubFrameId);\r
+\r
+/**\r
+ * @fn     void GH3X2X_Spo2AlgorithmResultReport(STGh3x2xAlgoResult * pstAlgoResult)\r
+ *\r
+ *\r
+ * @brief  This function will be called after calculate spo2 algorithm.\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   stSpo2AlgoRes           spo2 algorithm result array\r
+ * @param[in]   pusAlgoResIndexArr      frame index of every algo result\r
+ * @param[in]   usAlgoResCnt            number of algo result\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_Spo2AlgorithmResultReport(STGh3x2xAlgoResult * pstAlgoResult, GU32 lubFrameId);\r
+\r
+/**\r
+ * @fn     void GH3X2X_HrvAlgorithmResultReport(STHrvAlgoResult stHrvAlgoRes[], GU16 pusAlgoResIndexArr[], usAlgoResCnt)\r
+ *\r
+ * @brief  This function will be called after calculate hrv algorithm.\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   stHrvAlgoRes            hrv algorithm result array\r
+ * @param[in]   pusAlgoResIndexArr      frame index of every algo result\r
+ * @param[in]   usAlgoResCnt            number of algo result\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_HrvAlgorithmResultReport(STGh3x2xAlgoResult * pstAlgoResult, GU32 lubFrameId);\r
+\r
+/**\r
+ * @fn     void GH3X2X_EcgAlgorithmResultReport(STEcgAlgoResult stEcgAlgoRes[], GU16 pusAlgoResIndexArr[], usAlgoResCnt)\r
+ *\r
+ * @brief  This function will be called after calculate ecg algorithm.\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   stEcgAlgoRes            ecg algorithm result array\r
+ * @param[in]   pusAlgoResIndexArr      frame index of every algo result\r
+ * @param[in]   usAlgoResCnt            number of algo result\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_EcgAlgorithmResultReport(STGh3x2xAlgoResult * pstAlgoResult, GU32 lubFrameId);\r
+\r
+/**\r
+ * @fn     void GH3X2X_SoftAdtGreenAlgorithmResultReport(STGh3x2xAlgoResult * pstAlgoResult, GU32 lubFrameId)\r
+ *\r
+ * @brief  This function will be called after calculate ecg algorithm.\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   stEcgAlgoRes            ecg algorithm result array\r
+ * @param[in]   pusAlgoResIndexArr      frame index of every algo result\r
+ * @param[in]   usAlgoResCnt            number of algo result\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_SoftAdtGreenAlgorithmResultReport(STGh3x2xAlgoResult * pstAlgoResult, GU32 lubFrameId);\r
+\r
+/**\r
+ * @fn     void GH3X2X_SoftAdtIrAlgorithmResultReport(STGh3x2xAlgoResult * pstAlgoResult, GU32 lubFrameId)\r
+ *\r
+ * @brief  This function will be called after calculate ecg algorithm.\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   stEcgAlgoRes            ecg algorithm result array\r
+ * @param[in]   pusAlgoResIndexArr      frame index of every algo result\r
+ * @param[in]   usAlgoResCnt            number of algo result\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_SoftAdtIrAlgorithmResultReport(STGh3x2xAlgoResult * pstAlgoResult, GU32 lubFrameId);\r
+\r
+#endif // end else #if (__DRIVER_LIB_MODE__==__DRV_LIB_WITHOUT_ALGO__)\r
+\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_application/inc/gh3x2x_demo_algo_memory.h b/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_application/inc/gh3x2x_demo_algo_memory.h
new file mode 100644 (file)
index 0000000..a0b999d
--- /dev/null
@@ -0,0 +1,394 @@
+/**\r
+ * @copyright (c) 2003 - 2022, Goodix Co., Ltd. All rights reserved.\r
+ *\r
+ * @file    gh3x2x_demo_algo_memory.h\r
+ *\r
+ * @brief   gh3x2x algo memory set\r
+ *\r
+ * @version ref gh3x2x_demo_algo_memory.h\r
+ *\r
+ */\r
+#ifndef _GH3X2X_DEMO_ALGO_MEMORY_H_\r
+#define _GH3X2X_DEMO_ALGO_MEMORY_H_\r
+\r
+#include "gh3x2x_demo_algo_call.h"\r
+#include "gh3x2x_demo_algo_config.h"\r
+\r
+#if (__GOODIX_ALGO_CALL_MODE__)\r
+\r
+/* algorithm run mode:simultaneously or not */\r
+#define GH3X2X_ALGORITHM_RUN_ALONE                  (0)          /**< only excute one algorithm at the same time */\r
+#define GH3X2X_ALGORITHM_RUN_SIMULTANEOUSLY         (1)          /**< excute more than one algorithm */\r
+\r
+/* algorithm mem size in byte */\r
+#if (__GOODIX_HR_ALGO_VERISON__ == GOODIX_ALGO_BASIC)\r
+\r
+#define GH3X2X_HR_ALGORITHM_MEMORY_PEAK_1CHNL       (2116)       /**< HB 1 chnl algorithm peak memory size in byte */\r
+#define GH3X2X_HR_ALGORITHM_MEMORY_PEAK_2CHNL       (2116)       /**< HB 2 chnl  algorithm peak memory size in byte */\r
+#define GH3X2X_HR_ALGORITHM_MEMORY_PEAK_3CHNL       (2116)       /**< HB 3 chnl  algorithm peak memory size in byte */\r
+#define GH3X2X_HR_ALGORITHM_MEMORY_PEAK_4CHNL       (2116)       /**< HB 4 chnl  algorithm peak memory size in byte */\r
+#define GH3X2X_HR_ALGORITHM_MEMORY_RESIDENT_1CHNL   (1196)       /**< HB 1 chnl  algorithm desident memory size in byte */\r
+#define GH3X2X_HR_ALGORITHM_MEMORY_RESIDENT_2CHNL   (1196)       /**< HB 2 chnl  algorithm desident memory size in byte */\r
+#define GH3X2X_HR_ALGORITHM_MEMORY_RESIDENT_3CHNL   (1196)       /**< HB 3 chnl  algorithm desident memory size in byte */\r
+#define GH3X2X_HR_ALGORITHM_MEMORY_RESIDENT_4CHNL   (1196)       /**< HB 4 chnl  algorithm desident memory size in byte */\r
+#define GH3X2X_HR_ALGORITHM_MEMORY_REDUNDANCY       (100)\r
+#define GH3X2X_HR_ALGORITHM_ROM                     (20212)\r
+#define GH3X2X_HR_ALGORITHM_STACK                   (556)\r
+#define GH3X2X_HR_ALGORITHM_MIPS_MS                 (2.61)\r
+\r
+#elif (__GOODIX_HR_ALGO_VERISON__ == GOODIX_ALGO_MEDIUM)\r
+\r
+#define GH3X2X_HR_ALGORITHM_MEMORY_PEAK_1CHNL       (3248)       /**< HB 1 chnl algorithm peak memory size in byte */\r
+#define GH3X2X_HR_ALGORITHM_MEMORY_PEAK_2CHNL       (3248)       /**< HB 2 chnl  algorithm peak memory size in byte */\r
+#define GH3X2X_HR_ALGORITHM_MEMORY_PEAK_3CHNL       (3248)       /**< HB 3 chnl  algorithm peak memory size in byte */\r
+#define GH3X2X_HR_ALGORITHM_MEMORY_PEAK_4CHNL       (3248)       /**< HB 4 chnl  algorithm peak memory size in byte */\r
+#define GH3X2X_HR_ALGORITHM_MEMORY_RESIDENT_1CHNL   (2060)       /**< HB 1 chnl  algorithm desident memory size in byte */\r
+#define GH3X2X_HR_ALGORITHM_MEMORY_RESIDENT_2CHNL   (2060)       /**< HB 2 chnl  algorithm desident memory size in byte */\r
+#define GH3X2X_HR_ALGORITHM_MEMORY_RESIDENT_3CHNL   (2060)       /**< HB 3 chnl  algorithm desident memory size in byte */\r
+#define GH3X2X_HR_ALGORITHM_MEMORY_RESIDENT_4CHNL   (2060)       /**< HB 4 chnl  algorithm desident memory size in byte */\r
+#define GH3X2X_HR_ALGORITHM_MEMORY_REDUNDANCY       (100)\r
+#define GH3X2X_HR_ALGORITHM_ROM                     (25988)\r
+#define GH3X2X_HR_ALGORITHM_STACK                   (612)\r
+#define GH3X2X_HR_ALGORITHM_MIPS_MS                 (3.25)\r
+\r
+#elif (__GOODIX_HR_ALGO_VERISON__ == GOODIX_ALGO_PREMIUM)\r
+\r
+#define GH3X2X_HR_ALGORITHM_MEMORY_PEAK_1CHNL       (8944)       /**< HB 1 chnl algorithm peak memory size in byte */\r
+#define GH3X2X_HR_ALGORITHM_MEMORY_PEAK_2CHNL       (8944)       /**< HB 2 chnl  algorithm peak memory size in byte */\r
+#define GH3X2X_HR_ALGORITHM_MEMORY_PEAK_3CHNL       (8944)       /**< HB 3 chnl  algorithm peak memory size in byte */\r
+#define GH3X2X_HR_ALGORITHM_MEMORY_PEAK_4CHNL       (8944)       /**< HB 4 chnl  algorithm peak memory size in byte */\r
+#define GH3X2X_HR_ALGORITHM_MEMORY_RESIDENT_1CHNL   (3932)       /**< HB 1 chnl  algorithm desident memory size in byte */\r
+#define GH3X2X_HR_ALGORITHM_MEMORY_RESIDENT_2CHNL   (3932)       /**< HB 2 chnl  algorithm desident memory size in byte */\r
+#define GH3X2X_HR_ALGORITHM_MEMORY_RESIDENT_3CHNL   (3932)       /**< HB 3 chnl  algorithm desident memory size in byte */\r
+#define GH3X2X_HR_ALGORITHM_MEMORY_RESIDENT_4CHNL   (3932)       /**< HB 4 chnl  algorithm desident memory size in byte */\r
+#define GH3X2X_HR_ALGORITHM_MEMORY_REDUNDANCY       (100)\r
+#define GH3X2X_HR_ALGORITHM_ROM                     (76424)\r
+#define GH3X2X_HR_ALGORITHM_STACK                   (676)\r
+#define GH3X2X_HR_ALGORITHM_MIPS_MS                 (21)\r
+\r
+#elif (__GOODIX_HR_ALGO_VERISON__ == GOODIX_ALGO_EXCLUSIVE)\r
+\r
+#define GH3X2X_HR_ALGORITHM_MEMORY_PEAK_1CHNL       (15584)      /**< HB 1 chnl algorithm peak memory size in byte */\r
+#define GH3X2X_HR_ALGORITHM_MEMORY_PEAK_2CHNL       (15584)      /**< HB 2 chnl  algorithm peak memory size in byte */\r
+#define GH3X2X_HR_ALGORITHM_MEMORY_PEAK_3CHNL       (15584)      /**< HB 3 chnl  algorithm peak memory size in byte */\r
+#define GH3X2X_HR_ALGORITHM_MEMORY_PEAK_4CHNL       (15584)      /**< HB 4 chnl  algorithm peak memory size in byte */\r
+#define GH3X2X_HR_ALGORITHM_MEMORY_RESIDENT_1CHNL   (5248)       /**< HB 1 chnl  algorithm desident memory size in byte */\r
+#define GH3X2X_HR_ALGORITHM_MEMORY_RESIDENT_2CHNL   (5248)       /**< HB 2 chnl  algorithm desident memory size in byte */\r
+#define GH3X2X_HR_ALGORITHM_MEMORY_RESIDENT_3CHNL   (5248)       /**< HB 3 chnl  algorithm desident memory size in byte */\r
+#define GH3X2X_HR_ALGORITHM_MEMORY_RESIDENT_4CHNL   (5248)       /**< HB 4 chnl  algorithm desident memory size in byte */\r
+#define GH3X2X_HR_ALGORITHM_MEMORY_REDUNDANCY       (100)\r
+#define GH3X2X_HR_ALGORITHM_ROM                     (57176)\r
+#define GH3X2X_HR_ALGORITHM_STACK                   (552)\r
+#define GH3X2X_HR_ALGORITHM_MIPS_MS                 (38)\r
+\r
+#else\r
+#error "please define __GOODIX_HR_ALGO_VERISON__ in gh3x2x_demo_algo_config.h !"\r
+#endif\r
+\r
+#if (__GOODIX_SPO2_ALGO_VERISON__ == GOODIX_ALGO_BASIC) || (__GOODIX_SPO2_ALGO_VERISON__ == GOODIX_ALGO_MEDIUM)\r
+\r
+#define GH3X2X_SPO2_ALGORITHM_MEMORY_PEAK_1CHNL     (2736)       /**< SPO2 1 chnl  algorithm peak memory size in byte */\r
+#define GH3X2X_SPO2_ALGORITHM_MEMORY_PEAK_2CHNL     (2736)       /**< SPO2 2 chnl  algorithm peak memory size in byte */\r
+#define GH3X2X_SPO2_ALGORITHM_MEMORY_PEAK_3CHNL     (2736)       /**< SPO2 3 chnl  algorithm peak memory size in byte */\r
+#define GH3X2X_SPO2_ALGORITHM_MEMORY_PEAK_4CHNL     (2736)       /**< SPO2 4 chnl  algorithm peak memory size in byte */\r
+#define GH3X2X_SPO2_ALGORITHM_MEMORY_RESIDENT_1CHNL (1956)       /**< SPO2 1 chnl  algorithm memory size in byte */\r
+#define GH3X2X_SPO2_ALGORITHM_MEMORY_RESIDENT_2CHNL (1956)       /**< SPO2 2 chnl  algorithm memory size in byte */\r
+#define GH3X2X_SPO2_ALGORITHM_MEMORY_RESIDENT_3CHNL (1956)       /**< SPO2 3 chnl  algorithm memory size in byte */\r
+#define GH3X2X_SPO2_ALGORITHM_MEMORY_RESIDENT_4CHNL (1956)       /**< SPO2 4 chnl  algorithm memory size in byte */\r
+#define GH3X2X_SPO2_ALGORITHM_MEMORY_REDUNDANCY     (100)\r
+#define GH3X2X_SPO2_ALGORITHM_ROM                   (12596)\r
+#define GH3X2X_SPO2_ALGORITHM_STACK                 (376)\r
+#define GH3X2X_SPO2_ALGORITHM_MIPS_MS               (/)\r
+\r
+#elif (__GOODIX_SPO2_ALGO_VERISON__ == GOODIX_ALGO_PREMIUM) || (__GOODIX_SPO2_ALGO_VERISON__ == GOODIX_ALGO_EXCLUSIVE)\r
+\r
+#define GH3X2X_SPO2_ALGORITHM_MEMORY_PEAK_1CHNL     (7864)       /**< SPO2 1 chnl  algorithm peak memory size in byte */\r
+#define GH3X2X_SPO2_ALGORITHM_MEMORY_PEAK_2CHNL     (7864)       /**< SPO2 2 chnl  algorithm peak memory size in byte */\r
+#define GH3X2X_SPO2_ALGORITHM_MEMORY_PEAK_3CHNL     (7864)       /**< SPO2 3 chnl  algorithm peak memory size in byte */\r
+#define GH3X2X_SPO2_ALGORITHM_MEMORY_PEAK_4CHNL     (7864)       /**< SPO2 4 chnl  algorithm peak memory size in byte */\r
+#define GH3X2X_SPO2_ALGORITHM_MEMORY_RESIDENT_1CHNL (5020)       /**< SPO2 1 chnl  algorithm memory size in byte */\r
+#define GH3X2X_SPO2_ALGORITHM_MEMORY_RESIDENT_2CHNL (5020)       /**< SPO2 2 chnl  algorithm memory size in byte */\r
+#define GH3X2X_SPO2_ALGORITHM_MEMORY_RESIDENT_3CHNL (5020)       /**< SPO2 3 chnl  algorithm memory size in byte */\r
+#define GH3X2X_SPO2_ALGORITHM_MEMORY_RESIDENT_4CHNL (5020)       /**< SPO2 4 chnl  algorithm memory size in byte */\r
+#define GH3X2X_SPO2_ALGORITHM_MEMORY_REDUNDANCY     (100)\r
+#define GH3X2X_SPO2_ALGORITHM_ROM                   (49084)\r
+#define GH3X2X_SPO2_ALGORITHM_STACK                 (492)\r
+#define GH3X2X_SPO2_ALGORITHM_MIPS_MS               (26)\r
+\r
+#else\r
+#error "please define __GOODIX_SPO2_ALGO_VERISON__ in gh3x2x_demo_algo_config.h !"\r
+#endif\r
+\r
+#if (__GOODIX_ECG_ALGO_CONFIG__ == GOODIX_ECG_ALGO_500FS_QRS_ENABLE)\r
+\r
+#define GH3X2X_ECG_ALGORITHM_MEMORY_PEAK            (38360)       /**< ECG algorithm peak memory size in byte */\r
+#define GH3X2X_ECG_ALGORITHM_MEMORY_RESIDENT        (37176)       /**< ECG algorithm resident memory size in byte */\r
+#define GH3X2X_ECG_ALGORITHM_MEMORY_REDUNDANCY      (100)\r
+#define GH3X2X_ECG_ALGORITHM_ROM                    (33784)\r
+#define GH3X2X_ECG_ALGORITHM_STACK                  (5128)\r
+#define GH3X2X_ECG_ALGORITHM_MIPS_MS                (216)\r
+\r
+#elif (__GOODIX_ECG_ALGO_CONFIG__ == GOODIX_ECG_ALGO_500FS_QRS_DISABLE)\r
+\r
+#define GH3X2X_ECG_ALGORITHM_MEMORY_PEAK            (32024)       /**< ECG algorithm peak memory size in byte */\r
+#define GH3X2X_ECG_ALGORITHM_MEMORY_RESIDENT        (30640)       /**< ECG algorithm resident memory size in byte */\r
+#define GH3X2X_ECG_ALGORITHM_MEMORY_REDUNDANCY      (100)\r
+#define GH3X2X_ECG_ALGORITHM_ROM                    (33784)\r
+#define GH3X2X_ECG_ALGORITHM_STACK                  (5128)\r
+#define GH3X2X_ECG_ALGORITHM_MIPS_MS                (161)\r
+\r
+#elif (__GOODIX_ECG_ALGO_CONFIG__ == GOODIX_ECG_ALGO_250FS_QRS_ENABLE)\r
+\r
+#define GH3X2X_ECG_ALGORITHM_MEMORY_PEAK            (23476)       /**< ECG algorithm peak memory size in byte */\r
+#define GH3X2X_ECG_ALGORITHM_MEMORY_RESIDENT        (22132)       /**< ECG algorithm resident memory size in byte */\r
+#define GH3X2X_ECG_ALGORITHM_MEMORY_REDUNDANCY      (100)\r
+#define GH3X2X_ECG_ALGORITHM_ROM                    (33784)\r
+#define GH3X2X_ECG_ALGORITHM_STACK                  (5128)\r
+#define GH3X2X_ECG_ALGORITHM_MIPS_MS                (151)\r
+\r
+#elif (__GOODIX_ECG_ALGO_CONFIG__ == GOODIX_ECG_ALGO_250FS_QRS_DISABLE)\r
+\r
+#define GH3X2X_ECG_ALGORITHM_MEMORY_PEAK            (19464)       /**< ECG algorithm peak memory size in byte */\r
+#define GH3X2X_ECG_ALGORITHM_MEMORY_RESIDENT        (18120)       /**< ECG algorithm resident memory size in byte */\r
+#define GH3X2X_ECG_ALGORITHM_MEMORY_REDUNDANCY      (100)\r
+#define GH3X2X_ECG_ALGORITHM_ROM                    (33784)\r
+#define GH3X2X_ECG_ALGORITHM_STACK                  (5128)\r
+#define GH3X2X_ECG_ALGORITHM_MIPS_MS                (126)\r
+\r
+#else\r
+#error "please define __GOODIX_ECG_ALGO_CONFIG__ in gh3x2x_demo_algo_config.h !"\r
+#endif\r
+\r
+#define GH3X2X_HRV_ALGORITHM_MEMORY_PEAK            (3008)        /**< HRV algorithm peak memory size in byte */\r
+#define GH3X2X_HRV_ALGORITHM_MEMORY_RESIDENT        (2844)        /**< HRV algorithm resident memory size in byte */\r
+#define GH3X2X_HRV_ALGORITHM_MEMORY_REDUNDANCY      (100)\r
+#define GH3X2X_HRV_ALGORITHM_ROM                    (13320)\r
+#define GH3X2X_HRV_ALGORITHM_STACK                  (964)\r
+#define GH3X2X_HRV_ALGORITHM_MIPS_MS                (/)\r
+\r
+\r
+#define GH3X2X_SOFT_ADT_ALGORITHM_MEMORY_PEAK       (1128)        /**< SOFT ADT algorithm peak memory size in byte */\r
+#define GH3X2X_SOFT_ADT_ALGORITHM_MEMORY_RESIDENT   (104)         /**< SOFT ADT algorithm resident memory size in byte */\r
+#define GH3X2X_SOFT_ADT_ALGORITHM_MEMORY_REDUNDANCY (100)         /**< SOFT ADT algorithm redundancy memory size in byte */\r
+#define GH3X2X_SOFT_ADT_ALGORITHM_ROM               (16889)\r
+#define GH3X2X_SOFT_ADT_ALGORITHM_STACK             (4088)\r
+#define GH3X2X_SOFT_ADT_ALGORITHM_MIPS_MS           (/)\r
+\r
+\r
+#define GH3X2X_HSM_ALGORITHM_MEMORY_PEAK            (944)         /**< HSM algorithm memory peak size in byte */\r
+#define GH3X2X_HSM_ALGORITHM_MEMORY_RESIDENT        (944)         /**< HSM algorithm memory resident size in byte */\r
+#define GH3X2X_HSM_ALGORITHM_MEMORY_REDUNDANCY      (100)\r
+\r
+\r
+#define GH3X2X_BT_ALGORITHM_MEMORY_PEAK             (1600)        /**< BT algorithm memory peak size in byte */\r
+#define GH3X2X_BT_ALGORITHM_MEMORY_RESIDENT         (1500)        /**< BT algorithm memory resident size in byte */\r
+#define GH3X2X_BT_ALGORITHM_MEMORY_REDUNDANCY       (200)\r
+\r
+\r
+#define GH3X2X_RESP_ALGORITHM_MEMORY_PEAK           (5435)        /**< RESP algorithm memory peak size in byte */\r
+#define GH3X2X_RESP_ALGORITHM_MEMORY_RESIDENT       (2363)        /**< RESP algorithm memory resident size in byte */\r
+#define GH3X2X_RESP_ALGORITHM_MEMORY_REDUNDANCY     (500)\r
+\r
+\r
+#define GH3X2X_AF_ALGORITHM_MEMORY_PEAK             (3262)        /**< AF algorithm memory peak size in byte */\r
+#define GH3X2X_AF_ALGORITHM_MEMORY_RESIDENT         (1102)        /**< AF algorithm memory resident size in byte */\r
+#define GH3X2X_AF_ALGORITHM_MEMORY_REDUNDANCY       (300)\r
+\r
+\r
+/* algorithm mem config */\r
+#if (__GOODIX_ALGO_CALL_MODE__)\r
+\r
+#if (__USE_GOODIX_HR_ALGORITHM__)\r
+#if __HR_ALGORITHM_SUPPORT_CHNL_NUM__ <= 1\r
+#define   GH3X2X_ALGORITHM_HR_MEMORY_PEAK      GH3X2X_HR_ALGORITHM_MEMORY_PEAK_1CHNL\r
+#define   GH3X2X_ALGORITHM_HR_MEMORY_RESIDENT  GH3X2X_HR_ALGORITHM_MEMORY_RESIDENT_1CHNL \r
+#elif __HR_ALGORITHM_SUPPORT_CHNL_NUM__ == 2\r
+#define   GH3X2X_ALGORITHM_HR_MEMORY_PEAK   GH3X2X_HR_ALGORITHM_MEMORY_PEAK_2CHNL\r
+#define   GH3X2X_ALGORITHM_HR_MEMORY_RESIDENT  GH3X2X_HR_ALGORITHM_MEMORY_RESIDENT_2CHNL \r
+#elif __HR_ALGORITHM_SUPPORT_CHNL_NUM__ == 3\r
+#define   GH3X2X_ALGORITHM_HR_MEMORY_PEAK   GH3X2X_HR_ALGORITHM_MEMORY_PEAK_3CHNL\r
+#define   GH3X2X_ALGORITHM_HR_MEMORY_RESIDENT  GH3X2X_HR_ALGORITHM_MEMORY_RESIDENT_3CHNL \r
+#elif __HR_ALGORITHM_SUPPORT_CHNL_NUM__ >= 4\r
+#define   GH3X2X_ALGORITHM_HR_MEMORY_PEAK   GH3X2X_HR_ALGORITHM_MEMORY_PEAK_4CHNL\r
+#define   GH3X2X_ALGORITHM_HR_MEMORY_RESIDENT  GH3X2X_HR_ALGORITHM_MEMORY_RESIDENT_4CHNL \r
+#endif\r
+#define GH3X2X_ALGORITHM_HR_MEMORY_PEAK_WITHOUT_RESIDENT    (GH3X2X_ALGORITHM_HR_MEMORY_PEAK - GH3X2X_ALGORITHM_HR_MEMORY_RESIDENT)\r
+#define GH3X2X_ALGORITHM_HR_MEMORY_REDUNDANCY                 GH3X2X_HR_ALGORITHM_MEMORY_REDUNDANCY\r
+#else\r
+#define GH3X2X_ALGORITHM_HR_MEMORY_RESIDENT   (0)\r
+#define GH3X2X_ALGORITHM_HR_MEMORY_PEAK_WITHOUT_RESIDENT    (0)\r
+#define GH3X2X_ALGORITHM_HR_MEMORY_REDUNDANCY               (0)\r
+#endif\r
+\r
+#if (__USE_GOODIX_HSM_ALGORITHM__)\r
+#define   GH3X2X_ALGORITHM_HSM_MEMORY_RESIDENT   (GH3X2X_HSM_ALGORITHM_MEMORY_RESIDENT)\r
+#define GH3X2X_ALGORITHM_HSM_MEMORY_PEAK_WITHOUT_RESIDENT    (GH3X2X_HSM_ALGORITHM_MEMORY_PEAK - GH3X2X_HSM_ALGORITHM_MEMORY_RESIDENT)\r
+#define GH3X2X_ALGORITHM_HSM_MEMORY_REDUNDANCY                GH3X2X_HSM_ALGORITHM_MEMORY_REDUNDANCY\r
+#else\r
+#define GH3X2X_ALGORITHM_HSM_MEMORY_RESIDENT   (0)\r
+#define GH3X2X_ALGORITHM_HSM_MEMORY_PEAK_WITHOUT_RESIDENT    (0)\r
+#define GH3X2X_ALGORITHM_HSM_MEMORY_REDUNDANCY               (0)\r
+#endif\r
+\r
+#if (__USE_GOODIX_SPO2_ALGORITHM__)\r
+#if __SPO2_ALGORITHM_SUPPORT_CHNL_NUM__ <= 1\r
+#define   GH3X2X_ALGORITHM_SPO2_MEMORY_PEAK      GH3X2X_SPO2_ALGORITHM_MEMORY_PEAK_1CHNL\r
+#define   GH3X2X_ALGORITHM_SPO2_MEMORY_RESIDENT  GH3X2X_SPO2_ALGORITHM_MEMORY_RESIDENT_1CHNL \r
+#elif __SPO2_ALGORITHM_SUPPORT_CHNL_NUM__ == 2\r
+#define   GH3X2X_ALGORITHM_SPO2_MEMORY_PEAK   GH3X2X_SPO2_ALGORITHM_MEMORY_PEAK_2CHNL\r
+#define   GH3X2X_ALGORITHM_SPO2_MEMORY_RESIDENT  GH3X2X_SPO2_ALGORITHM_MEMORY_RESIDENT_2CHNL \r
+#elif __SPO2_ALGORITHM_SUPPORT_CHNL_NUM__ == 3\r
+#define   GH3X2X_ALGORITHM_SPO2_MEMORY_PEAK   GH3X2X_SPO2_ALGORITHM_MEMORY_PEAK_3CHNL\r
+#define   GH3X2X_ALGORITHM_SPO2_MEMORY_RESIDENT  GH3X2X_SPO2_ALGORITHM_MEMORY_RESIDENT_3CHNL \r
+#elif __SPO2_ALGORITHM_SUPPORT_CHNL_NUM__ >= 4\r
+#define   GH3X2X_ALGORITHM_SPO2_MEMORY_PEAK   GH3X2X_SPO2_ALGORITHM_MEMORY_PEAK_4CHNL\r
+#define   GH3X2X_ALGORITHM_SPO2_MEMORY_RESIDENT  GH3X2X_SPO2_ALGORITHM_MEMORY_RESIDENT_4CHNL \r
+#endif\r
+#define GH3X2X_ALGORITHM_SPO2_MEMORY_PEAK_WITHOUT_RESIDENT    (GH3X2X_ALGORITHM_SPO2_MEMORY_PEAK - GH3X2X_ALGORITHM_SPO2_MEMORY_RESIDENT)\r
+#define GH3X2X_ALGORITHM_SPO2_MEMORY_REDUNDANCY                 GH3X2X_SPO2_ALGORITHM_MEMORY_REDUNDANCY\r
+#else\r
+#define GH3X2X_ALGORITHM_SPO2_MEMORY_RESIDENT   (0)\r
+#define GH3X2X_ALGORITHM_SPO2_MEMORY_PEAK_WITHOUT_RESIDENT    (0)\r
+#define GH3X2X_ALGORITHM_SPO2_MEMORY_REDUNDANCY                (0)\r
+\r
+#endif\r
+\r
+#if (__USE_GOODIX_ECG_ALGORITHM__)\r
+#define   GH3X2X_ALGORITHM_ECG_MEMORY_RESIDENT   (GH3X2X_ECG_ALGORITHM_MEMORY_RESIDENT)\r
+#define GH3X2X_ALGORITHM_ECG_MEMORY_PEAK_WITHOUT_RESIDENT    (GH3X2X_ECG_ALGORITHM_MEMORY_PEAK - GH3X2X_ECG_ALGORITHM_MEMORY_RESIDENT)\r
+#define GH3X2X_ALGORITHM_ECG_MEMORY_REDUNDANCY                GH3X2X_ECG_ALGORITHM_MEMORY_REDUNDANCY\r
+#else\r
+#define GH3X2X_ALGORITHM_ECG_MEMORY_RESIDENT   (0)\r
+#define GH3X2X_ALGORITHM_ECG_MEMORY_PEAK_WITHOUT_RESIDENT    (0)\r
+#define GH3X2X_ALGORITHM_ECG_MEMORY_REDUNDANCY                (0)\r
+#endif\r
+\r
+#if (__USE_GOODIX_HRV_ALGORITHM__)\r
+#define   GH3X2X_ALGORITHM_HRV_MEMORY_RESIDENT   (GH3X2X_HRV_ALGORITHM_MEMORY_RESIDENT)\r
+#define GH3X2X_ALGORITHM_HRV_MEMORY_PEAK_WITHOUT_RESIDENT    (GH3X2X_HRV_ALGORITHM_MEMORY_PEAK - GH3X2X_HRV_ALGORITHM_MEMORY_RESIDENT)\r
+#define GH3X2X_ALGORITHM_HRV_MEMORY_REDUNDANCY                GH3X2X_HRV_ALGORITHM_MEMORY_REDUNDANCY\r
+#else\r
+#define GH3X2X_ALGORITHM_HRV_MEMORY_RESIDENT   (0)\r
+#define GH3X2X_ALGORITHM_HRV_MEMORY_PEAK_WITHOUT_RESIDENT    (0)\r
+#define GH3X2X_ALGORITHM_HRV_MEMORY_REDUNDANCY               (0)\r
+#endif\r
+\r
+#if (__USE_GOODIX_BT_ALGORITHM__)\r
+#define   GH3X2X_ALGORITHM_BT_MEMORY_RESIDENT   (GH3X2X_BT_ALGORITHM_MEMORY_RESIDENT)\r
+#define GH3X2X_ALGORITHM_BT_MEMORY_PEAK_WITHOUT_RESIDENT    (GH3X2X_BT_ALGORITHM_MEMORY_PEAK - GH3X2X_BT_ALGORITHM_MEMORY_RESIDENT)\r
+#define GH3X2X_ALGORITHM_BT_MEMORY_REDUNDANCY                GH3X2X_BT_ALGORITHM_MEMORY_REDUNDANCY\r
+#else\r
+#define GH3X2X_ALGORITHM_BT_MEMORY_RESIDENT   (0)\r
+#define GH3X2X_ALGORITHM_BT_MEMORY_PEAK_WITHOUT_RESIDENT    (0)\r
+#define GH3X2X_ALGORITHM_BT_MEMORY_REDUNDANCY               (0)\r
+#endif\r
+\r
+#if (__USE_GOODIX_RESP_ALGORITHM__)\r
+#define   GH3X2X_ALGORITHM_RESP_MEMORY_RESIDENT   (GH3X2X_RESP_ALGORITHM_MEMORY_RESIDENT)\r
+#define GH3X2X_ALGORITHM_RESP_MEMORY_PEAK_WITHOUT_RESIDENT    (GH3X2X_RESP_ALGORITHM_MEMORY_PEAK - GH3X2X_RESP_ALGORITHM_MEMORY_RESIDENT)\r
+#define GH3X2X_ALGORITHM_RESP_MEMORY_REDUNDANCY                GH3X2X_RESP_ALGORITHM_MEMORY_REDUNDANCY\r
+#else\r
+#define GH3X2X_ALGORITHM_RESP_MEMORY_RESIDENT   (0)\r
+#define GH3X2X_ALGORITHM_RESP_MEMORY_PEAK_WITHOUT_RESIDENT    (0)\r
+#define GH3X2X_ALGORITHM_RESP_MEMORY_REDUNDANCY               (0)\r
+#endif\r
+\r
+#if (__USE_GOODIX_AF_ALGORITHM__)\r
+#define   GH3X2X_ALGORITHM_AF_MEMORY_RESIDENT   (GH3X2X_AF_ALGORITHM_MEMORY_RESIDENT)\r
+#define GH3X2X_ALGORITHM_AF_MEMORY_PEAK_WITHOUT_RESIDENT    (GH3X2X_AF_ALGORITHM_MEMORY_PEAK - GH3X2X_AF_ALGORITHM_MEMORY_RESIDENT)\r
+#define GH3X2X_ALGORITHM_AF_MEMORY_REDUNDANCY                GH3X2X_AF_ALGORITHM_MEMORY_REDUNDANCY\r
+#else\r
+#define GH3X2X_ALGORITHM_AF_MEMORY_RESIDENT   (0)\r
+#define GH3X2X_ALGORITHM_AF_MEMORY_PEAK_WITHOUT_RESIDENT    (0)\r
+#define GH3X2X_ALGORITHM_AF_MEMORY_REDUNDANCY               (0)\r
+#endif\r
+\r
+\r
+#if (__USE_GOODIX_SOFT_ADT_ALGORITHM__)\r
+#define   GH3X2X_ALGORITHM_SOFT_ADT_MEMORY_RESIDENT   (GH3X2X_SOFT_ADT_ALGORITHM_MEMORY_RESIDENT)\r
+#define GH3X2X_ALGORITHM_SOFT_ADT_MEMORY_PEAK_WITHOUT_RESIDENT    (GH3X2X_SOFT_ADT_ALGORITHM_MEMORY_PEAK - GH3X2X_SOFT_ADT_ALGORITHM_MEMORY_RESIDENT)\r
+#define GH3X2X_ALGORITHM_SOFT_ADT_MEMORY_REDUNDANCY                GH3X2X_SOFT_ADT_ALGORITHM_MEMORY_REDUNDANCY\r
+#else\r
+#define GH3X2X_ALGORITHM_SOFT_ADT_MEMORY_RESIDENT   (0)\r
+#define GH3X2X_ALGORITHM_SOFT_ADT_MEMORY_PEAK_WITHOUT_RESIDENT    (0)\r
+#define GH3X2X_ALGORITHM_SOFT_ADT_MEMORY_REDUNDANCY                (0)\r
+#endif\r
+\r
+\r
+\r
+#endif\r
+\r
+#define MAX2(a0, a1)                                   (((a0) > (a1)) ? (a0) : (a1))\r
+#define ADD2(a0, a1)                                   ((a0) + (a1))\r
+#define MAX4(a0,a1,a2,a3)                              (MAX2(MAX2(a0, a1),MAX2(a2, a3)))\r
+#define MAX5(a0,a1,a2,a3,a4)                           (MAX2(MAX4(a0,a1,a2,a3),a4))\r
+#define MAX9(a0, a1, a2, a3, a4, a5 ,a6, a7, a8)   (MAX2(MAX5(a0,a1,a2,a3,a4),MAX4(a5,a6,a7,a8))))\r
+\r
+#define GH3X2X_FUNCTION_SOFT_ADT  (GH3X2X_FUNCTION_SOFT_ADT_GREEN|GH3X2X_FUNCTION_SOFT_ADT_IR)\r
+\r
+#define   GH3X2X_ALGORITHMS_MEMORY_RESIDENT_(x) (\\r
+    ((0 != (x & GH3X2X_FUNCTION_HR)) * __USE_GOODIX_HR_ALGORITHM__ * GH3X2X_ALGORITHM_HR_MEMORY_RESIDENT) + \\r
+    ((0 != (x & GH3X2X_FUNCTION_SPO2)) * __USE_GOODIX_SPO2_ALGORITHM__ * GH3X2X_ALGORITHM_SPO2_MEMORY_RESIDENT) + \\r
+    ((0 != (x & GH3X2X_FUNCTION_ECG)) * __USE_GOODIX_ECG_ALGORITHM__ * GH3X2X_ALGORITHM_ECG_MEMORY_RESIDENT) + \\r
+    ((0 != (x & GH3X2X_FUNCTION_HRV)) * __USE_GOODIX_HRV_ALGORITHM__ * GH3X2X_ALGORITHM_HRV_MEMORY_RESIDENT) + \\r
+    ((0 != (x & GH3X2X_FUNCTION_HSM)) * __USE_GOODIX_HSM_ALGORITHM__ * GH3X2X_ALGORITHM_HSM_MEMORY_RESIDENT) + \\r
+    ((0 != (x & GH3X2X_FUNCTION_BT)) * __USE_GOODIX_BT_ALGORITHM__ * GH3X2X_ALGORITHM_BT_MEMORY_RESIDENT) + \\r
+    ((0 != (x & GH3X2X_FUNCTION_RESP)) * __USE_GOODIX_RESP_ALGORITHM__ * GH3X2X_ALGORITHM_RESP_MEMORY_RESIDENT) + \\r
+    ((0 != (x & GH3X2X_FUNCTION_AF)) * __USE_GOODIX_AF_ALGORITHM__ * GH3X2X_ALGORITHM_AF_MEMORY_RESIDENT) + \\r
+    ((0 != (x & GH3X2X_FUNCTION_SOFT_ADT)) * __USE_GOODIX_SOFT_ADT_ALGORITHM__ * GH3X2X_ALGORITHM_SOFT_ADT_MEMORY_RESIDENT))\r
+\r
+#define   GH3X2X_ALGORITHMS_MEMORY_PEAK_WITHOUT_RESIDENT_(x) (MAX9(\\r
+    ADD2(((0 != (x & GH3X2X_FUNCTION_HR))* __USE_GOODIX_HR_ALGORITHM__ * GH3X2X_ALGORITHM_HR_MEMORY_PEAK_WITHOUT_RESIDENT),\\r
+    ((0 != (x & GH3X2X_FUNCTION_HR))* __USE_GOODIX_HR_ALGORITHM__ * GH3X2X_ALGORITHM_HR_MEMORY_REDUNDANCY)),\\r
+    ADD2(((0 != (x & GH3X2X_FUNCTION_SPO2))* __USE_GOODIX_SPO2_ALGORITHM__* GH3X2X_ALGORITHM_SPO2_MEMORY_PEAK_WITHOUT_RESIDENT),\\r
+    ((0 != (x & GH3X2X_FUNCTION_SPO2))* __USE_GOODIX_SPO2_ALGORITHM__* GH3X2X_ALGORITHM_SPO2_MEMORY_REDUNDANCY)), \\r
+    ADD2(((0 != (x & GH3X2X_FUNCTION_ECG))* __USE_GOODIX_ECG_ALGORITHM__* GH3X2X_ALGORITHM_ECG_MEMORY_PEAK_WITHOUT_RESIDENT),\\r
+    ((0 != (x & GH3X2X_FUNCTION_ECG))* __USE_GOODIX_ECG_ALGORITHM__* GH3X2X_ALGORITHM_ECG_MEMORY_REDUNDANCY)), \\r
+    ADD2(((0 != (x & GH3X2X_FUNCTION_HRV))* __USE_GOODIX_HRV_ALGORITHM__* GH3X2X_ALGORITHM_HRV_MEMORY_PEAK_WITHOUT_RESIDENT),\\r
+    ((0 != (x & GH3X2X_FUNCTION_HRV))* __USE_GOODIX_HRV_ALGORITHM__* GH3X2X_ALGORITHM_HRV_MEMORY_REDUNDANCY)), \\r
+    ADD2(((0 != (x & GH3X2X_FUNCTION_HSM))* __USE_GOODIX_HSM_ALGORITHM__* GH3X2X_ALGORITHM_HSM_MEMORY_PEAK_WITHOUT_RESIDENT),\\r
+    ((0 != (x & GH3X2X_FUNCTION_HSM))* __USE_GOODIX_HSM_ALGORITHM__* GH3X2X_ALGORITHM_HSM_MEMORY_REDUNDANCY)), \\r
+    ADD2(((0 != (x & GH3X2X_FUNCTION_BT))* __USE_GOODIX_BT_ALGORITHM__* GH3X2X_ALGORITHM_BT_MEMORY_PEAK_WITHOUT_RESIDENT),\\r
+    ((0 != (x & GH3X2X_FUNCTION_BT))* __USE_GOODIX_BT_ALGORITHM__* GH3X2X_ALGORITHM_BT_MEMORY_REDUNDANCY)), \\r
+    ADD2(((0 != (x & GH3X2X_FUNCTION_RESP))* __USE_GOODIX_RESP_ALGORITHM__* GH3X2X_ALGORITHM_RESP_MEMORY_PEAK_WITHOUT_RESIDENT),\\r
+    ((0 != (x & GH3X2X_FUNCTION_RESP))* __USE_GOODIX_RESP_ALGORITHM__* GH3X2X_ALGORITHM_RESP_MEMORY_REDUNDANCY)), \\r
+    ADD2(((0 != (x & GH3X2X_FUNCTION_AF))* __USE_GOODIX_AF_ALGORITHM__* GH3X2X_ALGORITHM_AF_MEMORY_PEAK_WITHOUT_RESIDENT),\\r
+    ((0 != (x & GH3X2X_FUNCTION_AF))* __USE_GOODIX_AF_ALGORITHM__* GH3X2X_ALGORITHM_AF_MEMORY_REDUNDANCY)), \\r
+    ADD2(((0 != (x & GH3X2X_FUNCTION_SOFT_ADT))* __USE_GOODIX_SOFT_ADT_ALGORITHM__ * GH3X2X_ALGORITHM_SOFT_ADT_MEMORY_PEAK_WITHOUT_RESIDENT),\\r
+    ((0 != (x & GH3X2X_FUNCTION_SOFT_ADT))* __USE_GOODIX_SOFT_ADT_ALGORITHM__ * GH3X2X_ALGORITHM_SOFT_ADT_MEMORY_REDUNDANCY)))\r
+\r
+#define GH3X2X_ALGORITHMS_MEMORY_(x)  (GH3X2X_ALGORITHMS_MEMORY_RESIDENT_(x) + GH3X2X_ALGORITHMS_MEMORY_PEAK_WITHOUT_RESIDENT_(x))\r
+\r
+#define __GH3X2X_ALGORITHMS_MEMORY  (\\r
+                                    MAX5(\\r
+                                    GH3X2X_ALGORITHMS_MEMORY_(GH3X2X_ALGO_FUNCTION_GROUP_0),\\r
+                                    GH3X2X_ALGORITHMS_MEMORY_(GH3X2X_ALGO_FUNCTION_GROUP_1),\\r
+                                    GH3X2X_ALGORITHMS_MEMORY_(GH3X2X_ALGO_FUNCTION_GROUP_2),\\r
+                                    GH3X2X_ALGORITHMS_MEMORY_(GH3X2X_ALGO_FUNCTION_GROUP_3),\\r
+                                    GH3X2X_ALGORITHMS_MEMORY_(GH3X2X_ALGO_FUNCTION_GROUP_4)\\r
+                                    )\\r
+                                )\r
+//final size\r
+#define GH3X2X_ALGORITHMS_MEMORY_SIZE_FINAL  (((GU32)((__GH3X2X_ALGORITHMS_MEMORY + 3) / 4)) * 4)\r
+\r
+\r
+/**\r
+ * @fn     GS8 GH3X2X_AlgoMemConfig( GU32 unMemSize)\r
+ *\r
+ * @brief  Config algorithm memory.\r
+ *\r
+ * @attention   Mem can only be static,such as global array\r
+ *\r
+ * @param[in]  unMemSize       memory size(unit:byte)\r
+ *\r
+ * @return  error code\r
+ * @retval  #GH3X2X_RET_OK                      return successfully\r
+ * @retval  #GH3X2X_RET_RESOURCE_ERROR          return algorithm mem config error\r
+ */\r
+GS8 GH3X2X_AlgoMemConfig( GU32 unMemSize);\r
+\r
+#endif\r
+\r
+#endif /* _GH3X2X_DEMO_ALGO_CALL_H_ */\r
+\r
+/********END OF FILE********* Copyright (c) 2003 - 2022, Goodix Co., Ltd. ********/\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_application/inc/gh3x2x_demo_algorithm_calc.h b/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_application/inc/gh3x2x_demo_algorithm_calc.h
new file mode 100644 (file)
index 0000000..25c3ca9
--- /dev/null
@@ -0,0 +1,355 @@
+/**\r
+ * @copyright (c) 2003 - 2022, Goodix Co., Ltd. All rights reserved.\r
+ *\r
+ * @file    gh3x2x_demo_algorithm_calc.h\r
+ *\r
+ * @brief   gh3x2x algorithm calc define & declaration\r
+ *\r
+ * @version ref gh3x2x_demo_algorithm_calc.h\r
+ *\r
+ */\r
+\r
+#ifndef _GH3X2X_DEMO_ALGORITHM_CALC_H_\r
+#define _GH3X2X_DEMO_ALGORITHM_CALC_H_\r
+\r
+\r
+#include "gh3x2x_demo_algo_config.h"\r
+#include "gh3x2x_demo_algo_call.h"\r
+#include "gh3x2x_demo_algo_hook.h"\r
+#include "gh3x2x_demo_common.h"\r
+\r
+\r
+/// algorithm calculate hook type\r
+typedef GS8 (*pfnAlgorithmCallFunc)(const STGh3x2xFrameInfo * const pstFrameInfo);\r
+\r
+extern STGh3x2xFrameInfo ** g_pstGh3x2xAlgoFrameInfo;\r
+\r
+#define GOODIX_HR_PARAMS_NUM_MAX           (10)\r
+#define GOODIX_HRV_PARAMS_NUM_MAX          (5)\r
+#define GOODIX_SPO2_PARAMS_NUM_MAX         (26)\r
+#define GOODIX_ECG_PARAMS_NUM_MAX          (5)\r
+#define GOODIX_BT_PARAMS_NUM_MAX           (20)\r
+#define GOODIX_AF_PARAMS_NUM_MAX           (2)\r
+\r
+#define GH3X2X_RAWDATA_BASE_VALUE          (1<<23)\r
+\r
+#define  GH3X2X_GAIN_VALUE_INVALID                      (0xFF)\r
+\r
+/// xor val for xor num in encrypt & decrypt\r
+#define   GH3X2X_CRYP_XOR_XOR_VAL                       (0xFF)\r
+\r
+/// fixed val in encrypt & decrypt\r
+#define   GH3X2X_CRYP_FIXED_VAL                         (0x55)\r
+\r
+/// header len in encrypt & decrypt\r
+#define   GH3X2X_CRYP_HEADER_LEN                        (5u)\r
+\r
+/// cryp rawdata len to index\r
+#define   GH3X2X_ENCRYPT_LEN2INDEX                      (1u)\r
+\r
+/* encrypt & decrypt header index */\r
+#define   GH3X2X_CRYP_HEADER_0                          (0u)     /**< cryp header index 0 */\r
+#define   GH3X2X_CRYP_HEADER_1                          (1u)     /**< cryp header index 1 */\r
+#define   GH3X2X_CRYP_HEADER_2                          (2u)     /**< cryp header index 2 */\r
+#define   GH3X2X_CRYP_HEADER_3                          (3u)     /**< cryp header index 3 */\r
+#define   GH3X2X_CRYP_HEADER_4                          (4u)     /**< cryp header index 4 */\r
+\r
+/// encrypt data min len, min len is 4\r
+#define   GH3X2X_ENCRYPT_CHECK_MIN_LEN(x)               ((x) > 3)\r
+\r
+/// encrypt source add magic bytes, add after source buffer & len must >= 4, magic bytes len align to cryp header len\r
+#define   GH3X2X_ENCRYPT_SRC_ADD_MAGIC(src, len)        do {\\r
+                                                            (src)[(len)] = ((src)[0] ^ (src)[(len) - 1]);\\r
+                                                            (src)[(len) + 1] = ((src)[1] ^ (src)[(len) - 3]);\\r
+                                                            (src)[(len) + 2] = GH3X2X_CRYP_FIXED_VAL;\\r
+                                                            (src)[(len) + 3] = ((src)[2] ^ (src)[(len) - 2]);\\r
+                                                            (src)[(len) + 4] = ((src)[3] ^ (src)[(len) - 4]);\\r
+                                                        } while (0)\r
+\r
+/// encrypt source verify magic bytes, add after source buffer & len must >= 4\r
+#define   GH3X2X_ENCRYPT_VERIFY_SRC_MAGIC(src, len)     (((src)[(len)] == ((src)[0] ^ (src)[(len) - 1])) &&\\r
+                                                         ((src)[(len) + 1] == ((src)[1] ^ (src)[(len) - 3])) &&\\r
+                                                         ((src)[(len) + 2] == GH3X2X_CRYP_FIXED_VAL) &&\\r
+                                                         ((src)[(len) + 3] == ((src)[2] ^ (src)[(len) - 2])) &&\\r
+                                                         ((src)[(len) + 4] == ((src)[3] ^ (src)[(len) - 4])))\r
+\r
+/// hba scenario mcaro max val\r
+#define   GH3X2X_HBA_SCENARIO_CONFIG_MAX_VAL            (HBA_SCENES_SIZE)\r
+\r
+/* rawdata package for algorithm */\r
+#define   GH3X2X_ALGO_RAW_GX_INDEX                      (0u)    /**< rawdata gsensor x-asix index */\r
+#define   GH3X2X_ALGO_RAW_GY_INDEX                      (1u)    /**< rawdata gsensor y-asix index */\r
+#define   GH3X2X_ALGO_RAW_GZ_INDEX                      (2u)    /**< rawdata gsensor z-asix index */\r
+#define   GH3X2X_ALGO_RAW_CH0_INDEX                     (3u)    /**< rawdata ch0 data index */\r
+#define   GH3X2X_ALGO_RAW_CH1_INDEX                     (4u)    /**< rawdata ch1 data index */\r
+#define   GH3X2X_ALGO_RAW_CH2_INDEX                     (5u)    /**< rawdata ch2 data index */\r
+#define   GH3X2X_ALGO_RAW_CH3_INDEX                     (6u)    /**< rawdata ch3 data index */\r
+#define   GH3X2X_ALGO_RAW_CH4_INDEX                     (7u)    /**< rawdata ch4 data index */\r
+#define   GH3X2X_ALGO_RAW_CH5_INDEX                     (8u)    /**< rawdata ch5 data index */\r
+#define   GH3X2X_ALGO_RAW_CH6_INDEX                     (9u)    /**< rawdata ch6 data index */\r
+#define   GH3X2X_ALGO_RAW_CH7_INDEX                     (10u)   /**< rawdata ch7 data index */\r
+#define   GH3X2X_ALGO_RAW_CH8_INDEX                     (11u)   /**< rawdata ch8 data index */\r
+#define   GH3X2X_ALGO_RAW_CH9_INDEX                     (12u)   /**< rawdata ch9 data index */\r
+#define   GH3X2X_ALGO_RAW_CH10_INDEX                    (13u)   /**< rawdata ch10 data index */\r
+#define   GH3X2X_ALGO_RAW_CH11_INDEX                    (14u)   /**< rawdata ch11 data index */\r
+#define   GH3X2X_ALGO_RAWDATA_LEN                       (35u)   /**< rawdata packet len for algorithm */\r
+\r
+/// algorithm channel max cnt support\r
+#define   GH3X2X_CHANNEL_MAP_MAX_CNT                    (32u)\r
+\r
+/// get slot & adc num from rawdata flag byte, equal channel map formats\r
+#define   GH3X2X_CHANNEL_MAP_GET(x)                     ((x) & GH3X2X_SLOT_ADC_NUM_BITS)\r
+\r
+/// channel map invalid val\r
+#define   GH3X2X_CHANNEL_MAP_INVALID_VAL                (0x07)\r
+\r
+/// channel map is ecg channel\r
+#define   GH3X2X_CHANNEL_MAP_ISNOT_ECG_CH(x)            (GH3X2X_CHECK_BIT_NOT_SET((x), GH3X2X_CHANNEL_MAP_ADC3))\r
+\r
+/// algorithm output GF32 to GS32, multiply by (100)\r
+#define   GH3X2X_ALGORITHM_GF32_2_GS32(x)               ((GS32)((x) * 100))\r
+\r
+/// rawdata is new sampling data\r
+#define   GH3X2X_IS_NEW_RAWDATA                         (1)\r
+\r
+/// rawdata is new sampling data\r
+#define   GH3X2X_IS_NOT_NEW_RAWDATA                     (0)\r
+\r
+/// number of ECG algorithm output\r
+#define  GH3X2X_ECG_ALGO_OUTPUT_NUM                 (sizeof(STEcgAlgoResult))\r
+\r
+/// number of spo2 algorithm output\r
+#define  GH3X2X_SPO2_ALGO_OUTPUT_NUM                (sizeof(STSpo2AlgoResult))\r
+\r
+/// number of hb algorithm output\r
+#define  GH3X2X_HB_ALGO_OUTPUT_NUM                  (sizeof(STHbAlgoResult))\r
+\r
+/// number of hrv algorithm output\r
+#define  GH3X2X_HRV_ALGO_OUTPUT_NUM                 (sizeof(STHrvAlgoResult))\r
+\r
+/// memory for algorithm is not inited\r
+#define ALGO_MEM_NO_INIT                            (0) \r
+\r
+/// memory for algorithm is already inited\r
+#define ALGO_MEM_INIT_OK                            (1)\r
+\r
+// algo chnl map num\r
+#define ALGO_CHNL_NUM                               (32)\r
+\r
+// algo green chnl pos\r
+#define ALGO_GREEN_CHNL_POS                         (0)\r
+\r
+// algo ir chnl pos\r
+#define ALGO_IR_CHNL_POS                            (8)\r
+\r
+// algo red chnl pos\r
+#define ALGO_RED_CHNL_POS                           (16)\r
+\r
+/* ecg algorithm */\r
+\r
+// ECG 采样率\r
+#ifndef ECG_FS\r
+#define ECG_FS 500\r
+#endif\r
+\r
+#define ECG_OUT_FACTOR                  (100)\r
+#define ECG_SNR_FACTOR                  (10000000)\r
+\r
+#define ECG_FRAME_UNUSED                (5)\r
+\r
+#define  GH3X2X_REG_IS_VIRTUAL0X3_BIT               (0x3000)\r
+#define GH3X2X_VREG_FUNCTION_OFFSET                 (0X0300)\r
+#define GH3X2X_ADT_DRV_CFG_ADDR                     (0x3000)\r
+#define GH3X2X_ADT_ALG_CFG_ADDR                     (0x30C0)\r
+#define GH3X2X_REG_ADDR_SIZE                        (0x0002)    /**< reg addr size */\r
+#define GH3X2X_VREG_ALGO_CHNL_MAP_OFFSET            (0X0200)\r
+#define GH3X2X_HR_SCENARIO_CFG_L_ADDR               (0x33C0)\r
+#define GH3X2X_HR_ALGO_CHNL_NUM_ADDR                (0x35C0)\r
+#define GH3X2X_SPO2_ALGO_CHNL_NUM_ADDR              (0x44C0)\r
+#define GH3X2X_SPO2_CH3_CORRECTION_FACTOR4_H_ADDR   (0x430E)\r
+#define GH3X2X_SPO2_CH0_CORRECTION_FACTOR0_L_ADDR   (0x42C0)\r
+\r
+#define GH3X2X_HSM_FLAG_BUFF_LEN (120)\r
+\r
+typedef enum\r
+{\r
+    ADT_ALGO_RESULT_DEFULT = 0,\r
+    ADT_ALGO_RESULT_WAER_ON,   /**< detect wear on */\r
+    ADT_ALGO_RESULT_WAER_OFF,\r
+} EMAdtAlgoStatus;\r
+\r
+/**\r
+ * @brief gh3x2x algo function id\r
+ */\r
+typedef enum \r
+{ \r
+    GH3X2X_ALGO_INIT_FUNCTION = 0,\r
+    GH3X2X_ALGO_CALCULATE_FUNCTION,\r
+//    GH3X2X_ALGO_FINAL_CALCULATE_FUNCTION,\r
+    GH3X2X_ALGO_DEINIT_FUNCTION,\r
+    GH3X2X_ALGO_FUNCTION_NUM_MAX,\r
+} EMAlgoFunctionID;\r
+\r
+// algo chnl map struct\r
+typedef struct\r
+{\r
+    GU8 uchFlag;\r
+    GU8 uchNum;\r
+    GU8 uchEcgAlgoChnlMap;\r
+    GU8 uchAlgoChnlMap[ALGO_CHNL_NUM];\r
+} STAlgoChnlMap;\r
+\r
+typedef struct\r
+{\r
+    GS32 nHbaScenario;\r
+    GS32 nHbaCalcOutputTime;\r
+    GS32 nFrequency;\r
+}STAlgoHrParas;\r
+\r
+/* hb algorithm */\r
+#if (__USE_GOODIX_HR_ALGORITHM__)\r
+extern GS32 g_unHrParamsArr[GOODIX_HR_PARAMS_NUM_MAX];\r
+/// hbd rawdata channel map\r
+extern STAlgoChnlMap g_stHbaAlgoChnlMap;\r
+#endif\r
+\r
+/* hrv algorithm */\r
+#if (__USE_GOODIX_HRV_ALGORITHM__)\r
+extern GS32 g_nHrvParamsArr[GOODIX_HRV_PARAMS_NUM_MAX];\r
+#endif\r
+\r
+/* spo2 algorithm */\r
+#if (__USE_GOODIX_SPO2_ALGORITHM__)\r
+extern GS32 g_nSpo2ParamssArr[GOODIX_SPO2_PARAMS_NUM_MAX];\r
+/// spo2 rawdata channel map\r
+extern STAlgoChnlMap g_stSpo2AlgoChnlMap;\r
+#endif\r
+\r
+/* ecg algorithm */\r
+#if (__USE_GOODIX_ECG_ALGORITHM__)\r
+extern GS32 g_nEcgParamsArr[GOODIX_ECG_PARAMS_NUM_MAX];\r
+/// ecg frame data cnt\r
+extern GU32 g_unEcgFrameCnt;\r
+extern GU8 g_uchClassificationFlag;\r
+extern GU8 g_unEcgTimeSeconds;\r
+#endif\r
+\r
+/* bt algorithm */\r
+#if (__USE_GOODIX_BT_ALGORITHM__)\r
+extern GS32 g_nBtParamsArr[GOODIX_BT_PARAMS_NUM_MAX];\r
+#endif\r
+\r
+/* af algorithm */\r
+#if (__USE_GOODIX_AF_ALGORITHM__)\r
+extern GS32 g_nAfParamsArr[GOODIX_AF_PARAMS_NUM_MAX];\r
+#endif\r
+\r
+extern GU8 g_uchAlgoGsensorEnable;\r
+extern GU8 g_uchAlgoCapEnable;\r
+extern GU8 g_uchAlgoTempEnable;\r
+\r
+extern GU8 GH3X2X_GetAlgoMemStatus(void);\r
+\r
+/**\r
+ * @fn     GS8 GH3X2X_AlgoMemInit(void)\r
+ *\r
+ * @brief  algorithm memory init\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  error code\r
+ * @retval  #GH3X2X_RET_OK                      return successfully\r
+ * @retval  #GH3X2X_RET_RESOURCE_ERROR          return algorithm mem init error\r
+ */\r
+GS8 GH3X2X_AlgoMemInit(void);\r
+\r
+/**\r
+ * @fn     void GH3X2X_AlgoMemDeinit(void)\r
+ *\r
+ * @brief  algorithm memory deinit\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_AlgoMemDeinit(void);\r
+\r
+/**\r
+ * @fn     void GH3X2X_SetNewDataFlag(EMChannelMapId emFuncId, GU8 uchFlag)\r
+ *\r
+ * @brief  Set new sampling data flag\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   emFuncId    function id\r
+ * @param[in]   uchFlag      new data or not\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_SetNewDataFlag(GU8 emFuncId, GU8 uchFlag);\r
+extern void Gh3x2xOutputValueStrategyInit(GU32 unFunctionID);\r
+extern void GH3x2xSleepFlagSet(GU8 uchSleepFlag);\r
+extern GU8 GH3x2xSleepFlagGet(void);\r
+extern GS32 GH3x2x_Round(GF32 fValue);\r
+extern GU8 GH3x2x_BitCount(GU32 n);\r
+extern void GH3X2X_LoadGoodixAlgoRegConfigArr(const STGh3x2xInitConfig *pstGoodixAlgoCfgListArr);\r
+\r
+extern GU8* GH3x2xAdtVersion(void);\r
+extern GS8 GH3x2xAdtAlgoInit(const STGh3x2xFrameInfo * const pstFrameInfo);\r
+extern GS8 GH3x2xAdtAlgoDeinit(const STGh3x2xFrameInfo * const pstFrameInfo);\r
+extern GS8 GH3x2xAdtAlgoExe(const STGh3x2xFrameInfo * const pstFrameInfo);\r
+\r
+extern GS8 GH3x2xHrAlgoInit(const STGh3x2xFrameInfo * const pstFrameInfo);\r
+extern GS8 GH3x2xHrAlgoDeinit(const STGh3x2xFrameInfo * const pstFrameInfo);\r
+extern GS8 GH3x2xHrAlgoExe(const STGh3x2xFrameInfo * const pstFrameInfo);\r
+extern void GH3X2X_HbaAlgoChnlMapDefultSet(void);\r
+extern void Gh3x2xHrOutputValueStrategyPro(STGh3x2xAlgoResult * pstAlgoResult, GU32 lubFrameId);\r
+\r
+extern GS8 GH3x2xHrvAlgoInit(const STGh3x2xFrameInfo * const pstFrameInfo);\r
+extern GS8 GH3x2xHrvAlgoDeinit(const STGh3x2xFrameInfo * const pstFrameInfo);\r
+extern GS8 GH3x2xHrvAlgoExe(const STGh3x2xFrameInfo * const pstFrameInfo);\r
+\r
+extern GS8 GH3x2xSpo2AlgoInit(const STGh3x2xFrameInfo * const pstFrameInfo);\r
+extern GS8 GH3x2xSpo2AlgoDeinit(const STGh3x2xFrameInfo * const pstFrameInfo);\r
+extern GS8 GH3x2xSpo2AlgoExe(const STGh3x2xFrameInfo * const pstFrameInfo);\r
+extern void GH3X2X_Spo2AlgoChnlMapDefultSet(void);\r
+\r
+extern GS8 GH3x2xAfAlgoInit(const STGh3x2xFrameInfo * const pstFrameInfo);\r
+extern GS8 GH3x2xAfAlgoDeinit(const STGh3x2xFrameInfo * const pstFrameInfo);\r
+extern GS8 GH3x2xAfAlgoExe(const STGh3x2xFrameInfo * const pstFrameInfo);\r
+\r
+extern GS8 GH3x2xAfAlgoInit(const STGh3x2xFrameInfo * const pstFrameInfo);\r
+extern GS8 GH3x2xAfAlgoDeinit(const STGh3x2xFrameInfo * const pstFrameInfo);\r
+extern GS8 GH3x2xAfAlgoExe(const STGh3x2xFrameInfo * const pstFrameInfo);\r
+\r
+extern GS8 GH3x2xRespAlgoInit(const STGh3x2xFrameInfo * const pstFrameInfo);\r
+extern GS8 GH3x2xRespAlgoDeinit(const STGh3x2xFrameInfo * const pstFrameInfo);\r
+extern GS8 GH3x2xRespAlgoExe(const STGh3x2xFrameInfo * const pstFrameInfo);\r
+\r
+extern GS8 GH3x2xBtAlgoInit(const STGh3x2xFrameInfo * const pstFrameInfo);\r
+extern GS8 GH3x2xBtAlgoDeinit(const STGh3x2xFrameInfo * const pstFrameInfo);\r
+extern GS8 GH3x2xBtAlgoExe(const STGh3x2xFrameInfo * const pstFrameInfo);\r
+\r
+extern GS8 GH3x2xHsmAlgoInit(const STGh3x2xFrameInfo * const pstFrameInfo);\r
+extern GS8 GH3x2xHsmAlgoDeinit(const STGh3x2xFrameInfo * const pstFrameInfo);\r
+extern GS8 GH3x2xHsmAlgoExe(const STGh3x2xFrameInfo * const pstFrameInfo);\r
+\r
+extern GS8 GH3x2xSoftAdtAlgoInit(const STGh3x2xFrameInfo * const pstFrameInfo);\r
+extern GS8 GH3x2xSoftAdtAlgoDeinit(const STGh3x2xFrameInfo * const pstFrameInfo);\r
+extern GS8 GH3x2xSoftAdtAlgoExe(const STGh3x2xFrameInfo * const pstFrameInfo);\r
+\r
+extern GS8 GH3x2xEcgAlgoInit(const STGh3x2xFrameInfo * const pstFrameInfo);\r
+extern GS8 GH3x2xEcgAlgoDeinit(const STGh3x2xFrameInfo * const pstFrameInfo);\r
+extern GS8 GH3x2xEcgAlgoExe(const STGh3x2xFrameInfo * const pstFrameInfo);\r
+extern GU8 GH3x2xEcgAlgoClassification(void);\r
+\r
+#endif /* _GH3X2X_DRV_ALGORITHM_CALC_H_ */\r
+\r
+/********END OF FILE********* Copyright (c) 2003 - 2022, Goodix Co., Ltd. ********/\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_application/inc/gh3x2x_demo_common.h b/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_application/inc/gh3x2x_demo_common.h
new file mode 100644 (file)
index 0000000..49be1b8
--- /dev/null
@@ -0,0 +1,344 @@
+/**\r
+ * @copyright (c) 2003 - 2022, Goodix Co., Ltd. All rights reserved.\r
+ *\r
+ * @file    gh3x2x_demo_common.h\r
+ *\r
+ * @brief   gh3x2x algo common define\r
+ *\r
+ * @version ref gh3x2x_demo_common.h\r
+ *\r
+ */\r
+\r
+#ifndef _GH3X2X_DEMO_COMMON_H_\r
+#define _GH3X2X_DEMO_COMMON_H_\r
+\r
+\r
+#include "gh3x2x_demo_algo_config.h"\r
+#include "goodix_algo.h"\r
+\r
+/* extern log function */\r
+extern void GH3X2X_AlgoLog(GCHAR *chLogString);\r
+/// log support len\r
+#define GH3X2X_LOG_ALGO_SUP_LEN     (128)\r
+\r
+\r
+#if (__ALGO_LOG_CONFIG__ > __GH3X2X_ALGO_LOG_LV_0__)\r
+#if (__ALGO_LOG_CONFIG__ == __GH3X2X_ALGO_LOG_LV_1__)\r
+#define   GH3X2X_INFO_ALGO_LOG(...)         do {\\r
+                                                        GCHAR chDebugStr[GH3X2X_LOG_ALGO_SUP_LEN] = {0};\\r
+                                                        snprintf(chDebugStr, GH3X2X_LOG_ALGO_SUP_LEN, \\r
+                                                                "[LOG_ALGO_I]: "__VA_ARGS__);\\r
+                                                        GH3X2X_AlgoLog(chDebugStr);\\r
+                                                    } while (0)\r
+#else\r
+#define   GH3X2X_INFO_ALGO_LOG(...)\r
+#endif\r
+\r
+#if (__ALGO_LOG_CONFIG__ == __GH3X2X_ALGO_LOG_LV_2__)\r
+#define   GH3X2X_DEBUG_ALGO_LOG(...)        do {\\r
+                                                GCHAR chDebugStr[GH3X2X_LOG_ALGO_SUP_LEN] = {0};\\r
+                                                snprintf(chDebugStr, GH3X2X_LOG_ALGO_SUP_LEN, \\r
+                                                        "[LOG_ALGO_D]: "__VA_ARGS__);\\r
+                                                GH3X2X_AlgoLog(chDebugStr);\\r
+                                            } while (0)\r
+#else\r
+#define   GH3X2X_DEBUG_ALGO_LOG(...)\r
+#endif\r
+\r
+#else\r
+#define   GH3X2X_INFO_ALGO_LOG(...)\r
+#define   GH3X2X_DEBUG_ALGO_LOG(...)\r
+#endif\r
+\r
+/// channel map max channel support to unpack rawdata\r
+#define   GH3X2X_CHANNEL_MAP_MAX_CH                             (32)\r
+\r
+/// fifo rawdata bytes max len\r
+#define   GH3X2X_FIFO_DATA_BYTES_MAX_LEN    (3200)    // GH3X2X_FIFO_CNT_CALC(800)\r
+\r
+/// fifo rawdata size\r
+#define   GH3X2X_FIFO_RAWDATA_SIZE          (4)\r
+\r
+/// fifo rawdataindex size\r
+#define   GH3X2X_FIFO_RAWDATAINDEX_SIZE     (2)\r
+\r
+/// fifo gsensordata size\r
+#define   GH3X2X_FIFO_GSENSORDATA_SIZE      (6)\r
+\r
+/// fifo agcdata size\r
+#define   GH3X2X_FIFO_AGCDATA_SIZE          (4)\r
+\r
+/// fifo cnt calc\r
+#define   GH3X2X_FIFO_CNT_CALC(x)           ((x) * GH3X2X_FIFO_RAWDATA_SIZE)\r
+\r
+/// g sensor data size\r
+#define   GH3X2X_GSENSOR_DATA_SIZE          (6)\r
+\r
+/// agc data size\r
+#define   GH3X2X_AGC_DATA_SIZE              (4)\r
+\r
+/// agc data cnt calc\r
+#define   GH3X2X_AGC_CNT_CALC(x)           ((x) * GH3X2X_AGC_DATA_SIZE)\r
+\r
+/// algorithm result size\r
+#define   GH3X2X_ALGO_RESULT_SIZE           (4)\r
+\r
+/// algorithm result calc\r
+#define   GH3X2X_ALGO_RESULT_CALC(x)           ((x) * GH3X2X_ALGO_RESULT_SIZE)\r
+\r
+/// algorithm result with tag calc.\r
+#define   GH3X2X_ALGO_RESULT_WITH_TAG_CALC(x)           ((x) * (GH3X2X_ALGO_RESULT_SIZE + 1))\r
+\r
+/// g sensor data size\r
+#define   GH3X2X_GSENSOR_DATA_SIZE          (6)\r
+\r
+/// agc data size\r
+#define   GH3X2X_AGC_DATA_SIZE              (4)\r
+\r
+/// agc data cnt calc\r
+#define   GH3X2X_AGC_CNT_CALC(x)           ((x) * GH3X2X_AGC_DATA_SIZE)\r
+\r
+/// algorithm result size\r
+#define   GH3X2X_ALGO_RESULT_SIZE           (4)\r
+\r
+/// algorithm result calc\r
+#define   GH3X2X_ALGO_RESULT_CALC(x)           ((x) * GH3X2X_ALGO_RESULT_SIZE)\r
+\r
+/// algorithm result with tag calc.\r
+#define   GH3X2X_ALGO_RESULT_WITH_TAG_CALC(x)           ((x) * (GH3X2X_ALGO_RESULT_SIZE + 1))\r
+\r
+/* rawdata macro */\r
+\r
+/// rawdata clear slot & adc num\r
+#define   GH3X2X_RAWDATA_CLEAR_SLOT_ADC_NUM(x)          ((x) & 0x07FFFFFF)\r
+\r
+/// rawdata get slot num from dword\r
+#define   GH3X2X_DWORD_RAWDATA_GET_SLOT_NUM(x)          (((x) & 0xE0000000) >> 29)\r
+\r
+/// rawdata get adc num from dword\r
+#define   GH3X2X_DWORD_RAWDATA_GET_ADC_NUM(x)           (((x) & 0x18000000) >> 27)\r
+\r
+/// rawdata get slot&adc num from dword\r
+#define   GH3X2X_DWORD_RAWDATA_GET_SLOT_ADC_NUM(x)      (((x) & 0xF8000000) >> 27)\r
+\r
+/// rawdata get slot num from byte\r
+#define   GH3X2X_BYTE_RAWDATA_GET_SLOT_NUM(x)           (((x) & 0xE0) >> 5)\r
+\r
+/// rawdata get adc num from byte\r
+#define   GH3X2X_BYTE_RAWDATA_GET_ADC_NUM(x)            (((x) & 0x18) >> 3)\r
+\r
+/// slot & adc num bits of rawdata byte\r
+#define   GH3X2X_SLOT_ADC_NUM_BITS                      (0xF8)\r
+\r
+/// rawdata get slot adc num from byte\r
+#define   GH3X2X_BYTE_RAWDATA_GET_SLOT_ADC_NUM(x)       (((x) & GH3X2X_SLOT_ADC_NUM_BITS) >> 3)\r
+\r
+/// get slot index from channel num\r
+#define   GH3X2X_GET_SLOT_FROM_CHANNEL_NUM(x)           (((x) & 0x1F) >> 2)\r
+\r
+/// get adc index from channel num\r
+#define   GH3X2X_GET_ADC_FROM_CHANNEL_NUM(x)            ((x) & 0x3)\r
+\r
+/// rawdata clear all flag\r
+#define   GH3X2X_RAWDATA_CLEAR_ALL_FLAG(x)              ((x) & 0x00FFFFFF)\r
+\r
+/// rawdata clear data\r
+#define   GH3X2X_RAWDATA_CLEAR_DATA(x)                  ((x) & 0xFF000000)\r
+\r
+/// rawdata get adj flag0\r
+#define   GH3X2X_RAWDATA_GET_ADJ_FLAG0(x)               (((x) & 0x4000000) >> 26)\r
+\r
+/// rawdata get adj flag1\r
+#define   GH3X2X_RAWDATA_GET_ADJ_FLAG1(x)               (((x) & 0x2000000) >> 25)\r
+\r
+/// get rawdata for algorithm\r
+#define   GH3X2X_GET_RAWDATA_FOR_ALGO(x)                ((x) >> 7)\r
+\r
+/// rawdata get fast recovery flag\r
+#define   GH3X2X_RAWDATA_GET_FAST_RECOVERY_FLAG(x)      (((x) & 0x4000000) >> 26)\r
+\r
+/// rawdata real offset\r
+#define   GH3X2X_RAWDATA_REAL_OFFSET                    (0x00800000)\r
+\r
+/* utils macro */\r
+\r
+/// byte true flag val\r
+#define   GH3X2X_BYTE_FLAG_TRUE                     (1)\r
+\r
+/// byte false flag val\r
+#define   GH3X2X_BYTE_FLAG_FALSE                    (0)\r
+\r
+/// GF32 0 val\r
+#define   GH3X2X_GF32_0                             (0.0f)\r
+\r
+/// null val\r
+#define   GH3X2X_PTR_NULL                           ((void *) 0)\r
+\r
+/// get high 4bits from byte\r
+#define   GH3X2X_GET_HIGH_4BITS(val)                ((val) & 0xF0)\r
+\r
+/// get low 4bits from byte\r
+#define   GH3X2X_GET_LOW_4BITS(val)                 ((val) & 0x0F)\r
+\r
+/// get first 4bits from byte\r
+#define   GH3X2X_GET_FIRST_4BITS(val)               ((val) & 0x0000000FU)\r
+\r
+/// get high byte from word\r
+#define   GH3X2X_GET_HIGH_BYTE_FROM_WORD(sValue)    ((GU8)(((sValue) >> 8) & 0xFFU))\r
+\r
+/// get low byte from word\r
+#define   GH3X2X_GET_LOW_BYTE_FROM_WORD(sValue)     ((GU8)((sValue) & 0xFFU))\r
+\r
+/// get byte3 from dword\r
+#define   GH3X2X_GET_BYTE3_FROM_DWORD(unValue)      ((GU8)(((unValue) >> 24) & 0x000000FFU))\r
+\r
+/// get byte2 from dword\r
+#define   GH3X2X_GET_BYTE2_FROM_DWORD(unValue)      ((GU8)(((unValue) >> 16) & 0x000000FFU))\r
+\r
+/// get byte1 from dword\r
+#define   GH3X2X_GET_BYTE1_FROM_DWORD(unValue)      ((GU8)(((unValue) >> 8) & 0x000000FFU))\r
+\r
+/// get byte0 from dword\r
+#define   GH3X2X_GET_BYTE0_FROM_DWORD(unValue)      ((GU8)((unValue) & 0x000000FFU))\r
+\r
+/// get high word from dword\r
+#define   GH3X2X_GET_HIGH_WORD_FROM_DWORD(unValue)      ((GU16)(((unValue) >> 16) & 0x0000FFFFU))\r
+\r
+/// get low word from dword\r
+#define   GH3X2X_GET_LOW_WORD_FROM_DWORD(unValue)       ((GU16)((unValue) & 0x0000FFFFU))    \r
+\r
+/// makeup word from bytes\r
+#define   GH3X2X_MAKEUP_WORD(uchHighByte, uchLowByte)              ((GU16)(((((GU16)(uchHighByte)) << 8)& 0xFF00) |\\r
+                                                                            (((GU16)(uchLowByte))& 0x00FF)))\r
+\r
+/// makeup dword from bytes\r
+#define   GH3X2X_MAKEUP_DWORD(uchByte3, uchByte2, uchByte1, uchByte0)     (((((GU32)(uchByte3)) << 24) & 0xFF000000U)|\\r
+                                                                          ((((GU32)(uchByte2)) << 16) & 0x00FF0000U) |\\r
+                                                                          ((((GU32)(uchByte1)) << 8) & 0x0000FF00U) |\\r
+                                                                          (((GU32)(uchByte0)) & 0x000000FFU))\r
+\r
+/// makeup dword from words\r
+#define   GH3X2X_MAKEUP_DWORD2(usHighWord, usLowWord)                  (((((GU32)(usHighWord)) << 16) & 0xFFFF0000U) |\\r
+                                                                            (((GU32)(usLowWord)) & 0x0000FFFFU))\r
+\r
+/// macro of hook function call\r
+/* NOLINTNEXTLINE(501) */\r
+#define   HOOK_FUNC_CALL(func, argv)        do { if ((func) != GH3X2X_PTR_NULL) { func argv; } } while (0)\r
+\r
+/// macro of handle function call\r
+/* NOLINTNEXTLINE(501) */\r
+#define   HANDLE_FUNC_CALL(func, argv)      do { if ((func) != GH3X2X_PTR_NULL) { func argv; } } while (0)\r
+\r
+/// macro of set val via ptr\r
+#define   SET_VAL_VIA_PTR(ptr, val)     do { if ((ptr) != GH3X2X_PTR_NULL) { (*(ptr)) = (val); } } while (0)\r
+\r
+/* bit operation macro */\r
+\r
+/// macro of set bits\r
+#define   GH3X2X_SET_BIT(x, b)              ((x) | (b))\r
+\r
+/// macro of val set bits\r
+#define   GH3X2X_VAL_SET_BIT(x, b)          ((x) |= (b))\r
+\r
+/// macro of clear bits\r
+#define   GH3X2X_CLEAR_BIT(x, b)            ((x) & (~(b)))\r
+\r
+/// macro of val clear bits\r
+#define   GH3X2X_VAL_CLEAR_BIT(x, b)        ((x) &= (~(b)))\r
+\r
+/// macro of val get bits\r
+#define   GH3X2X_VAL_GET_BIT(x, b)          ((x) &= (b))\r
+\r
+/// macro of check bits set\r
+#define   GH3X2X_CHECK_BIT_SET(x, b)        (((x) & (b)) == (b))\r
+\r
+/// macro of check bits not set\r
+#define   GH3X2X_CHECK_BIT_NOT_SET(x, b)    (((x) & (b)) != (b))\r
+\r
+/// macro of check bits is set\r
+#define   GH3X2X_CHECK_BIT_IS_SET(x, b)     (((x) & (b)) == (b))\r
+\r
+/// macro of get bits is set\r
+#define   GH3X2X_GET_BIT_IS_SET(x)          ((x) & 0xf000)\r
+\r
+/// macro of bit number in one byte\r
+#define   GH3X2X_BIT_PER_BYTE    (4)\r
+\r
+/// macro of bit in reg addr for check\r
+#define   GH3X2X_REG_MODE_BIT    (3)\r
+\r
+/// macro of check bits zero\r
+#define   GH3X2X_CHECK_REG_MODE_BIT_ZERO(x)    (((x) >> (GH3X2X_BIT_PER_BYTE * GH3X2X_REG_MODE_BIT)) == (0))\r
+\r
+/// macro of check lsb set\r
+#define   GH3X2X_CHECK_LSB_SET(x)           (GH3X2X_CHECK_BIT_SET((x), 0x01))\r
+\r
+/// macro of check left shift bit set\r
+#define   GH3X2X_CHECK_LEFT_BIT_SET(x, l)           (GH3X2X_CHECK_BIT_SET((x), (1u << (l))))\r
+\r
+/// macro of check left shift bit not set\r
+#define   GH3X2X_CHECK_LEFT_BIT_NOT_SET(x, l)       (GH3X2X_CHECK_BIT_NOT_SET((x), (1u << (l))))\r
+\r
+/// macro of val clear left shift bit\r
+#define   GH3X2X_VAL_CLEAR_LEFT_BIT(x, l)                ((x) &= (~((1u << (l)))))\r
+\r
+/// check ret error\r
+#define   GH3X2X_RET_ERROR_CHECK(x)             do { \\r
+                                                    if ((x) != GH3X2X_RET_OK)\\r
+                                                    {\\r
+                                                        return (x);\\r
+                                                    }\\r
+                                                } while (0)\r
+\r
+/// check ret the error\r
+#define   GH3X2X_RET_ERROR_CHECK_E(x, e)        do { \\r
+                                                    if ((x) == (e))\\r
+                                                    {\\r
+                                                        return (x);\\r
+                                                    }\\r
+                                                } while (0)\r
+\r
+/// check ret the error\r
+#define   GH3X2X_RET_ERROR_CHECK_ER(x, e, r)    do { \\r
+                                                    if ((x) == (e))\\r
+                                                    {\\r
+                                                        return (r);\\r
+                                                    }\\r
+                                                } while (0)\r
+\r
+/// val rigth shfit\r
+#define   GH3X2X_SET_VAL_RIGTH_SHIFT(x, r)      ((x) >>= (r))\r
+\r
+/// val rigth shfit 1bit\r
+#define   GH3X2X_SET_VAL_RIGTH_SHIFT_1BIT(x)    (GH3X2X_SET_VAL_RIGTH_SHIFT((x), 1u))\r
+\r
+/// val left shfit\r
+#define   GH3X2X_SET_VAL_LEFT_SHIFT(x, l)       ((x) <<= (l))\r
+\r
+/// val left shfit 1bit\r
+#define   GH3X2X_SET_VAL_LEFT_SHIFT_1BIT(x)     (GH3X2X_SET_VAL_LEFT_SHIFT((x), 1u))\r
+\r
+/// get left shfit val\r
+#define   GH3X2X_GET_LEFT_SHIFT_VAL(l)          (1u << (l))\r
+\r
+/// val left shfit\r
+#define   GH3X2X_VAL_LEFT_SHIFT(x, l)           ((x) << (l))\r
+\r
+/// val cal diff value\r
+#define   GH3X2X_VAL_DIFF_VALUE(a, b)           ((a) > (b) ? ((a) - (b)) : ((b) - (a)))\r
+\r
+/// val cal diff status\r
+#define   GH3X2X_VAL_DIFF_STA(a, b)             ((a) > (b) ? (0) : (1))\r
+\r
+/// val cal diff ABS\r
+#define   GH3X2X_VAL_ABS(x)                     ((x) >= 0 ? (x) : - (x))\r
+\r
+/// val zip rawdata send cmd EVEN or ODD\r
+#define   GH3X2X_VAL_ZIPSENDCMD(x)              ((x) == 1 ? (GH3X2X_UPROTOCOL_CMD_ZIPEVENRAWDATA) \\r
+                                                 : (GH3X2X_UPROTOCOL_CMD_ZIPODDRAWDATA))\r
+\r
+\r
+\r
+#endif /* _GH3X2X_DRV_COMMON_H_ */\r
+\r
+/********END OF FILE********* Copyright (c) 2003 - 2022, Goodix Co., Ltd. ********/\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_application/src/gh3x2x_demo_accppg_sync.c b/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_application/src/gh3x2x_demo_accppg_sync.c
new file mode 100644 (file)
index 0000000..bd37a8d
--- /dev/null
@@ -0,0 +1,39 @@
+#include <stdio.h>\r
+//#include "gh3x2x_demo_inner.h"\r
+#include "gh3x2x_demo_algo_config.h"\r
+#include "gh3x2x_demo_accppg_sync.h"\r
+#include "gh3x2x_demo_common.h"\r
+\r
+GU8 GH3X2X_TimestampSyncGetFrameDataFlag(void)\r
+{\r
+    return 1;\r
+}\r
+\r
+void GH3X2X_TimestampSyncSetPpgIntFlag(GU8 uchPpgIntFlag)\r
+{\r
+}\r
+\r
+void GH3X2X_TimestampSyncAccInit(void)\r
+{\r
+}\r
+\r
+void GH3X2X_TimestampSyncPpgInit(GU32 unFunctionID)\r
+{\r
+}\r
+\r
+void GH3X2X_TimestampSyncSend2AlgoCall(GU8 uchFuncOffsetID)\r
+{\r
+}\r
+\r
+void GH3X2X_TimestampSyncFillAccSyncBuffer(GU32 unTimeStamp,\r
+                                           GS16 usAccX,\r
+                                           GS16 usAccY,\r
+                                           GS16 usAccZ)\r
+{\r
+}\r
+\r
+void GH3X2X_TimestampSyncFillPpgSyncBuffer(GU32 unTimeStamp,\r
+                                           const STGh3x2xFrameInfo * const pstFrameInfo)\r
+{\r
+}\r
+\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_application/src/gh3x2x_demo_algo_call.c b/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_application/src/gh3x2x_demo_algo_call.c
new file mode 100644 (file)
index 0000000..6c50082
--- /dev/null
@@ -0,0 +1,367 @@
+#include <stdio.h>\r
+#include "gh3x2x_demo_algo_memory.h"\r
+#include "gh3x2x_demo_algo_call.h"\r
+#include "gh3x2x_demo_algo_config.h"\r
+#include "gh3x2x_demo_algorithm_calc.h"\r
+#include "gh3x2x_demo_algo_call_version.h"\r
+#include "goodix_algo.h"\r
+#include "goodix_mem.h"\r
+#include "goodix_type.h"\r
+#include "goodix_hba.h"\r
+#include "goodix_ecg.h"\r
+#include "goodix_af.h"\r
+#include "goodix_hsm.h"\r
+#include "goodix_resp.h"\r
+#include "goodix_hrv.h"\r
+#include "goodix_spo2.h"\r
+#include "goodix_nadt.h"\r
+#include "goodix_algo_bt.h"\r
+\r
+#if (__GOODIX_ALGO_CALL_MODE__)\r
+extern const STGh3x2xInitConfig g_stGoodixAlgoCfgListArr[__GOODIX_ALGO_CFG_LIST_MAX_NUM__];\r
+STGh3x2xFrameInfo ** g_pstGh3x2xAlgoFrameInfo = GH3X2X_PTR_NULL;\r
+static GU32 g_unAlgoFuncStartedBitmap = 0;\r
+static GU8 g_uchAlgInitFlag[GH3X2X_FUNC_OFFSET_MAX] = {0};\r
+static const pfnAlgorithmCallFunc g_pfnAlgorithmCallFunc[GH3X2X_FUNC_OFFSET_MAX][GH3X2X_ALGO_FUNCTION_NUM_MAX] = {\r
+//adt\r
+#if __USE_GOODIX_ADT_ALGORITHM__\r
+    { GH3x2xAdtAlgoInit, GH3x2xAdtAlgoExe, GH3x2xAdtAlgoDeinit },\r
+#else\r
+    { 0, 0, 0 },\r
+#endif\r
+//hr\r
+#if __USE_GOODIX_HR_ALGORITHM__\r
+    { GH3x2xHrAlgoInit, GH3x2xHrAlgoExe, GH3x2xHrAlgoDeinit },\r
+#else\r
+    { 0, 0, 0 },\r
+#endif\r
+//hrv\r
+#if __USE_GOODIX_HRV_ALGORITHM__\r
+    { GH3x2xHrvAlgoInit, GH3x2xHrvAlgoExe, GH3x2xHrvAlgoDeinit },\r
+#else\r
+    { 0, 0, 0 },\r
+#endif\r
+//hsm\r
+#if __USE_GOODIX_HSM_ALGORITHM__\r
+    { GH3x2xHsmAlgoInit, GH3x2xHsmAlgoExe, GH3x2xHsmAlgoDeinit },\r
+#else\r
+    { 0, 0, 0 },\r
+#endif\r
+//fpbp\r
+//pwa\r
+#if __USE_GOODIX_BP_ALGORITHM__\r
+    { GH3x2xBpAlgoInit, GH3x2xBpAlgoExe, GH3x2xBpAlgoDeinit },\r
+    { GH3x2xBpAlgoInit, GH3x2xBpAlgoExe, GH3x2xBpAlgoDeinit },\r
+#else\r
+    { 0, 0, 0 },\r
+    { 0, 0, 0 },\r
+#endif\r
+//spo2\r
+#if __USE_GOODIX_SPO2_ALGORITHM__\r
+    { GH3x2xSpo2AlgoInit, GH3x2xSpo2AlgoExe, GH3x2xSpo2AlgoDeinit },\r
+#else\r
+    { 0, 0, 0 },\r
+#endif\r
+//ecg\r
+#if __USE_GOODIX_ECG_ALGORITHM__\r
+    { GH3x2xEcgAlgoInit, GH3x2xEcgAlgoExe, GH3x2xEcgAlgoDeinit },\r
+#else\r
+    { 0, 0, 0 },\r
+#endif\r
+//pwtt\r
+    { 0, 0, 0 },\r
+//soft adt green\r
+#if __USE_GOODIX_SOFT_ADT_ALGORITHM__\r
+    { GH3x2xSoftAdtAlgoInit, GH3x2xSoftAdtAlgoExe, GH3x2xSoftAdtAlgoDeinit },\r
+#else\r
+    { 0, 0, 0 },\r
+#endif\r
+//bt\r
+#if __USE_GOODIX_BT_ALGORITHM__\r
+    { GH3x2xBtAlgoInit, GH3x2xBtAlgoExe, GH3x2xBtAlgoDeinit },\r
+#else\r
+    { 0, 0, 0 },\r
+#endif\r
+//resp\r
+#if __USE_GOODIX_RESP_ALGORITHM__\r
+    { GH3x2xRespAlgoInit, GH3x2xRespAlgoExe, GH3x2xRespAlgoDeinit },\r
+#else\r
+    { 0, 0, 0 },\r
+#endif\r
+//af\r
+#if __USE_GOODIX_AF_ALGORITHM__ && __USE_GOODIX_HRV_ALGORITHM__\r
+    { GH3x2xAfAlgoInit, GH3x2xAfAlgoExe, GH3x2xAfAlgoDeinit },\r
+#else\r
+    { 0, 0, 0 },\r
+#endif\r
+//test\r
+    { 0, 0, 0 },\r
+    { 0, 0, 0 },\r
+//soft adt ir\r
+#if __USE_GOODIX_SOFT_ADT_ALGORITHM__\r
+    { GH3x2xSoftAdtAlgoInit, GH3x2xSoftAdtAlgoExe, GH3x2xSoftAdtAlgoDeinit },\r
+#else\r
+    { 0, 0, 0 },\r
+#endif\r
+};\r
+\r
+GCHAR* GH3X2X_GetAlgoCallDemoVersion(void)\r
+{\r
+    return GOODIX_ALGO_CALL_VERSION_STRING;\r
+}\r
+\r
+void GH3X2X_RegisterFuncInfoStruct(const STGh3x2xFrameInfo * const  pstGh3x2xFrameInfo[])\r
+{\r
+    g_pstGh3x2xAlgoFrameInfo = (STGh3x2xFrameInfo **)pstGh3x2xFrameInfo;\r
+}\r
+\r
+void GH3X2X_AlgoCallConfigInit(const STGh3x2xFrameInfo * const  pstGh3x2xFrameInfo[], GU8 uchAlgoCfgIndex)\r
+{\r
+    if (pstGh3x2xFrameInfo != GH3X2X_PTR_NULL)\r
+    {\r
+        g_pstGh3x2xAlgoFrameInfo = (STGh3x2xFrameInfo **)pstGh3x2xFrameInfo;\r
+    }\r
+    GH3X2X_AlgoMemConfig(GH3X2X_ALGORITHMS_MEMORY_SIZE_FINAL);\r
+    GH3X2X_DEBUG_ALGO_LOG("Algorithm mem size = %d\r\n",(int)GH3X2X_ALGORITHMS_MEMORY_SIZE_FINAL);\r
+    if(uchAlgoCfgIndex < __GOODIX_ALGO_CFG_LIST_MAX_NUM__)\r
+    {\r
+        GH3X2X_LoadGoodixAlgoRegConfigArr(&g_stGoodixAlgoCfgListArr[uchAlgoCfgIndex]);\r
+    }\r
+\r
+}\r
+\r
+void GH3X2X_AlgoVersion(GU8 uchFunctionID, GCHAR version[120])\r
+{\r
+    if (version == 0)\r
+    {\r
+        GH3X2X_DEBUG_ALGO_LOG("[%s]:version buffer is NULL!!!\r\n", __FUNCTION__);\r
+        return;\r
+    }\r
+    GCHAR chNoVersion[10] = "no_ver";\r
+\r
+    switch (uchFunctionID)\r
+    {\r
+#if __USE_GOODIX_ADT_ALGORITHM__\r
+    case GH3X2X_FUNC_OFFSET_ADT:\r
+        GH3X2X_Memcpy(version, GH3x2xAdtVersion(), strlen((const GCHAR *)GH3x2xAdtVersion()) + 1);\r
+        break;\r
+#endif\r
+#if __USE_GOODIX_HR_ALGORITHM__\r
+    case GH3X2X_FUNC_OFFSET_HR:\r
+        goodix_hba_version((uint8_t*)version);\r
+        break;\r
+#endif\r
+#if __USE_GOODIX_HRV_ALGORITHM__\r
+    case GH3X2X_FUNC_OFFSET_HRV:\r
+        GH3X2X_Memcpy(version, goodix_hrv_version(), strlen((const GCHAR *)goodix_hrv_version()) + 1);\r
+        break;\r
+#endif\r
+#if __USE_GOODIX_SPO2_ALGORITHM__\r
+    case GH3X2X_FUNC_OFFSET_SPO2:\r
+        goodix_spo2_version((uint8_t*)version);\r
+        break;\r
+#endif\r
+#if __USE_GOODIX_ECG_ALGORITHM__\r
+    case GH3X2X_FUNC_OFFSET_ECG:\r
+        goodix_ecg_version((uint8_t*)version);\r
+        break;\r
+#endif\r
+#if __USE_GOODIX_HSM_ALGORITHM__\r
+    case GH3X2X_FUNC_OFFSET_HSM:\r
+        GH3X2X_Memcpy(version, HSMAlgoVersion(), strlen((const GCHAR *)HSMAlgoVersion()) + 1);\r
+        break;\r
+#endif\r
+#if __USE_GOODIX_AF_ALGORITHM__\r
+    case GH3X2X_FUNC_OFFSET_AF:\r
+        GH3X2X_Memcpy(version, AFVersion(), strlen((const GCHAR *)AFVersion()) + 1);\r
+        break;\r
+#endif\r
+#if __USE_GOODIX_RESP_ALGORITHM__\r
+    case GH3X2X_FUNC_OFFSET_RESP:\r
+        GH3X2X_Memcpy(version, RespAlgoVersion(), strlen((const GCHAR *)RespAlgoVersion()) + 1);\r
+        break;\r
+#endif\r
+#if __USE_GOODIX_SOFT_ADT_ALGORITHM__\r
+    case GH3X2X_FUNC_OFFSET_SOFT_ADT_GREEN:\r
+    case GH3X2X_FUNC_OFFSET_SOFT_ADT_IR:\r
+        GetNadtVersion((uint8_t *)version);\r
+        break;\r
+#endif\r
+#if __USE_GOODIX_BP_ALGORITHM__\r
+    case GH3X2X_FUNC_OFFSET_PWA:\r
+    case GH3X2X_FUNC_OFFSET_FPBP:\r
+        //GH3X2X_Memcpy(version, GoodixBpAlgoVersion(), strlen((const GCHAR *)GoodixBpAlgoVersion()) + 1);\r
+        break;\r
+#endif\r
+#if __USE_GOODIX_BT_ALGORITHM__\r
+    case GH3X2X_FUNC_OFFSET_BT:\r
+#if!__USE_GOODIX_DRV_NTC_Convert\r
+        GH3X2X_Memcpy(version, GoodixBtAlgoVersion(), strlen((const GCHAR *)GoodixBtAlgoVersion()) + 1);\r
+#endif\r
+        break;\r
+#endif\r
+    default:\r
+        GH3X2X_Memcpy(version, (GCHAR *)chNoVersion,\\r
+        strlen((const GCHAR *)chNoVersion) + 1);\r
+        break;\r
+    }\r
+    //GH3X2X_INFO_ALGO_LOG("version = %s\n", version);\r
+}\r
+\r
+GS8 GH3X2X_AlgoInit(GU32 unFunctionID)\r
+{\r
+    GU8 chRet = GH3X2X_RET_OK;\r
+\r
+    if(GH3X2X_PTR_NULL == g_pstGh3x2xAlgoFrameInfo)\r
+    {\r
+        GH3X2X_INFO_ALGO_LOG("[%s]: Warning!!! g_pstGh3x2xAlgoFrameInfo is not init!\r\n", __FUNCTION__);\r
+        return GH3X2X_RET_OK;\r
+    }\r
+    \r
+    /* set started bit */\r
+    g_unAlgoFuncStartedBitmap |= unFunctionID;\r
+\r
+    /* init mem pool */\r
+    if (GH3X2X_GetAlgoMemStatus() != ALGO_MEM_INIT_OK)\r
+    {\r
+        return -1;\r
+    }\r
+\r
+    for(GU8 uchFunCnt = 0; uchFunCnt < GH3X2X_FUNC_OFFSET_MAX; uchFunCnt ++)\r
+    {\r
+        if (((1<<uchFunCnt) & unFunctionID) == (1<<uchFunCnt))\r
+        {\r
+            /* int algo */\r
+            const STGh3x2xFrameInfo * const pstFrameInfo = g_pstGh3x2xAlgoFrameInfo[uchFunCnt];\r
+            if (1 == g_uchAlgInitFlag[uchFunCnt])\r
+            {\r
+                GH3X2X_DEBUG_ALGO_LOG("[%s]:Function(function id = %d) already init!\r\n", __FUNCTION__, (int)uchFunCnt);\r
+            }\r
+            else\r
+            {\r
+                if (g_pfnAlgorithmCallFunc[uchFunCnt][GH3X2X_ALGO_INIT_FUNCTION] != GH3X2X_PTR_NULL)\r
+                {\r
+                    chRet = g_pfnAlgorithmCallFunc[uchFunCnt][GH3X2X_ALGO_INIT_FUNCTION](pstFrameInfo);\r
+                    if (chRet != GH3X2X_RET_OK)\r
+                    {\r
+                        GH3X2X_DEBUG_ALGO_LOG("[%s]:Function(function id = %d) init fail! errcode = %d\r\n", __FUNCTION__, (int)uchFunCnt, (int)chRet);\r
+                    }\r
+                    else\r
+                    {\r
+                        GH3X2X_DEBUG_ALGO_LOG("[%s]:Function(function id = %d) init success!\r\n", __FUNCTION__, (int)uchFunCnt);\r
+                        g_uchAlgInitFlag[uchFunCnt] = 1;\r
+                    }\r
+                }\r
+                else\r
+                {\r
+                    GH3X2X_DEBUG_ALGO_LOG("[%s]:Function(function id = %d) init func null!\r\n", __FUNCTION__, (int)uchFunCnt);\r
+                }\r
+                Gh3x2xOutputValueStrategyInit(unFunctionID);\r
+            }\r
+            GH3X2X_RET_ERROR_CHECK(chRet);\r
+        }\r
+    }\r
+    return chRet;\r
+}\r
+\r
+GS8 GH3X2X_AlgoDeinit(GU32 unFunctionID)\r
+{\r
+    GS32 chRet = GH3X2X_RET_OK;\r
+    \r
+    if(GH3X2X_PTR_NULL == g_pstGh3x2xAlgoFrameInfo)\r
+    {\r
+        GH3X2X_INFO_ALGO_LOG("[%s]: Warning!!! g_pstGh3x2xAlgoFrameInfo is not init!\r\n", __FUNCTION__);\r
+        return GH3X2X_RET_OK;\r
+    }\r
+    \r
+    /* clear started bit */\r
+    g_unAlgoFuncStartedBitmap &= (~unFunctionID);\r
+\r
+    /* deint algo */\r
+    for(GU8 uchFunCnt = 0; uchFunCnt < GH3X2X_FUNC_OFFSET_MAX; uchFunCnt ++)\r
+    {\r
+        if (((1<<uchFunCnt) & unFunctionID) == (1<<uchFunCnt))\r
+        {\r
+            /* deint algo */\r
+            const STGh3x2xFrameInfo * const pstFrameInfo = g_pstGh3x2xAlgoFrameInfo[uchFunCnt];\r
+            if (0 == g_uchAlgInitFlag[uchFunCnt])\r
+            {\r
+                GH3X2X_DEBUG_ALGO_LOG("[%s]:Function(function id = %d) didn't init!\r\n", __FUNCTION__, (int)uchFunCnt);\r
+            }\r
+            else\r
+            {\r
+                if (g_pfnAlgorithmCallFunc[uchFunCnt][GH3X2X_ALGO_DEINIT_FUNCTION] != GH3X2X_PTR_NULL)\r
+                {\r
+                    chRet = g_pfnAlgorithmCallFunc[uchFunCnt][GH3X2X_ALGO_DEINIT_FUNCTION](pstFrameInfo);\r
+                    if (chRet != GH3X2X_RET_OK)\r
+                    {\r
+                        GH3X2X_DEBUG_ALGO_LOG("[%s]:Function(function id = %d) deinit fail! errcode = %d\r\n", __FUNCTION__, (int)uchFunCnt, (int)chRet);\r
+                    }\r
+                    else\r
+                    {\r
+                        GH3X2X_DEBUG_ALGO_LOG("[%s]:Function(function id = %d) deinit success!\r\n", __FUNCTION__, (int)uchFunCnt);\r
+                        g_uchAlgInitFlag[uchFunCnt] = 0;\r
+                    }\r
+                }\r
+                else\r
+                {\r
+                    GH3X2X_DEBUG_ALGO_LOG("[%s]:Function(function id = %d) deinit func null!\r\n", __FUNCTION__, (int)uchFunCnt);\r
+                }\r
+            }\r
+            GH3X2X_RET_ERROR_CHECK(chRet);\r
+        }\r
+    }\r
+    return chRet;\r
+}\r
+\r
+GS8 GH3X2X_AlgoCalculate(GU32 unFunctionID)\r
+{\r
+    if (g_unAlgoFuncStartedBitmap == GH3X2X_NO_FUNCTION)\r
+    {\r
+        return GH3X2X_RET_OK;\r
+    }\r
+\r
+    GS32 chRet = GH3X2X_RET_GENERIC_ERROR;\r
+\r
+    for(GU8 uchFunCnt = 0; uchFunCnt < GH3X2X_FUNC_OFFSET_MAX; uchFunCnt ++)\r
+    {\r
+        if (((1<<uchFunCnt) & unFunctionID) == (1<<uchFunCnt))\r
+        {\r
+            /* calc algo */\r
+            if (GH3X2X_CHECK_BIT_SET(g_unAlgoFuncStartedBitmap, unFunctionID))\r
+            {\r
+                const STGh3x2xFrameInfo * const pstFrameInfo = g_pstGh3x2xAlgoFrameInfo[uchFunCnt];\r
+                if(GH3x2xSleepFlagGet())\r
+                {\r
+                    pstFrameInfo->punFrameFlag[2] |= ((GU32)1)<<3;\r
+                }\r
+                if (0 == g_uchAlgInitFlag[uchFunCnt])\r
+                {\r
+                    //GH3X2X_DEBUG_ALGO_LOG("Function(funcition id = %d) didn't init!\r\n",(int)uchFunCnt);\r
+                }\r
+                else\r
+                {\r
+                    if (g_pfnAlgorithmCallFunc[uchFunCnt][GH3X2X_ALGO_CALCULATE_FUNCTION] != GH3X2X_PTR_NULL)\r
+                    {\r
+                        chRet = g_pfnAlgorithmCallFunc[uchFunCnt][GH3X2X_ALGO_CALCULATE_FUNCTION](pstFrameInfo);\r
+                        if( *(pstFrameInfo->punFrameCnt) == 0 && pstFrameInfo->pstAlgoResult->uchUpdateFlag == 0 )\r
+                        {\r
+                            GH3X2X_Memset(pstFrameInfo->pstAlgoResult,0,sizeof(STGh3x2xAlgoResult));\r
+                            pstFrameInfo->pstAlgoResult->uchUpdateFlag = 1;\r
+                            pstFrameInfo->pstAlgoResult->usResultBit = 0xFF;\r
+                            pstFrameInfo->pstAlgoResult->uchResultNum = GH3x2x_BitCount(pstFrameInfo->pstAlgoResult->usResultBit);\r
+                        }\r
+                    }\r
+                }\r
+            }\r
+        }\r
+        else\r
+        {\r
+            chRet = GH3X2X_RET_OK;\r
+        }\r
+    }\r
+    return chRet;\r
+}\r
+\r
+#endif\r
+\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_application/src/gh3x2x_demo_algo_config.c b/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_application/src/gh3x2x_demo_algo_config.c
new file mode 100644 (file)
index 0000000..42ada59
--- /dev/null
@@ -0,0 +1,648 @@
+/**\r
+ * @copyright (c) 2003 - 2022, Goodix Co., Ltd. All rights reserved.\r
+ *\r
+ * @file    gh3x2x_drv_algorithm_calc.c\r
+ *\r
+ * @brief   gh3x2x algorithm calc functions\r
+ *\r
+ * @version ref gh3x2x_drv_version.h\r
+ *\r
+ */\r
+\r
+\r
+#include <stdio.h>\r
+#include "gh3x2x_demo_algorithm_calc.h"\r
+#include "gh3x2x_demo_algo_config.h"\r
+#include "goodix_algo.h"\r
+#include "goodix_mem.h"\r
+#include "goodix_type.h"\r
+#include "goodix_hba.h"\r
+#include "goodix_hrv.h"\r
+#include "goodix_spo2.h"\r
+#include "goodix_nadt.h"\r
+#include "goodix_algo_bt.h"\r
+\r
+#if (__GOODIX_ALGO_CALL_MODE__)\r
+\r
+/* hb algorithm */\r
+#if (__USE_GOODIX_HR_ALGORITHM__)\r
+GS32 g_unHrParamsArr[GOODIX_HR_PARAMS_NUM_MAX] = {\r
+                                                        0,                                  // 测试模式\r
+                                                        0,                                  // 运动场景\r
+                                                        0,                                  // 预留未使用\r
+                                                        20,                                 // 最晚出值时间\r
+                                                        8,                                  // 最早出值时间\r
+                                                        0,                                  // 预留未使用\r
+                                                        0,                                  // 预留未使用\r
+                                                        0,                                  // 预留未使用\r
+                                                        0,                                  // 预留未使用\r
+                                                        0                                   // 预留未使用\r
+                                                 };\r
+/// hbd rawdata channel map\r
+STAlgoChnlMap g_stHbaAlgoChnlMap = {0};\r
+#endif\r
+\r
+/* hrv algorithm */\r
+#if (__USE_GOODIX_HRV_ALGORITHM__)\r
+GS32 g_nHrvParamsArr[GOODIX_HRV_PARAMS_NUM_MAX] = {\r
+                                                        0,                                  // 需要分辨率为1ms的输出\r
+                                                        200000, 100000, 300000, 300000      // ACC相关阈值\r
+                                                  };\r
+#endif\r
+\r
+/* spo2 algorithm */\r
+#if (__USE_GOODIX_SPO2_ALGORITHM__)\r
+#if ((__GOODIX_SPO2_ALGO_VERISON__ == GOODIX_ALGO_BASIC) || (__GOODIX_SPO2_ALGO_VERISON__ == GOODIX_ALGO_MEDIUM))\r
+GS32 g_nSpo2ParamssArr[GOODIX_SPO2_PARAMS_NUM_MAX] = {\r
+                                                          0, 0, -134717, -115284, 1097668,  // 校准参数\r
+                                                          0,                                // 心率使能标志\r
+                                                          0,                                // 佩戴模式\r
+                                                          30, 15, 4, 3, 90,                 // ACC运动判断阈值\r
+                                                          1, 65,                            // 备用\r
+                                                          30, 10, 90,                       // PPG参数\r
+                                                          253,                              // 质量评估模块使能开关\r
+                                                          95,                               // 低氧阈值\r
+                                                          10, 25, 3, 6, 10, 5,              // 出值策略\r
+                                                          3                                 // 出值相关模块使能开关\r
+                                                     };\r
+#elif ((__GOODIX_SPO2_ALGO_VERISON__ == GOODIX_ALGO_PREMIUM) || (__GOODIX_SPO2_ALGO_VERISON__ == GOODIX_ALGO_EXCLUSIVE))\r
+GS32 g_nSpo2ParamssArr[GOODIX_SPO2_PARAMS_NUM_MAX] = {\r
+                                                          0, 0, 0, -239878, 1111827,   // 校准参数\r
+                                                          1,                                // 心率使能标志\r
+                                                          0,                                // 佩戴模式\r
+                                                          50, 25, 3, 3, 90,                 // ACC运动判断阈值\r
+                                                          0, 160,                            // 备用\r
+                                                          35, 25, 85,                       // PPG参数\r
+                                                          0xFD,                             // 质量评估模块使能开关\r
+                                                          95,                               // 低氧阈值\r
+                                                          12, 18, 2, 7, 10, 5,              // 出值策略\r
+                                                          3                                 // 出值相关模块使能开关\r
+                                                     };\r
+#endif\r
+/// spo2 rawdata channel map\r
+STAlgoChnlMap g_stSpo2AlgoChnlMap = {0};\r
+#endif\r
+\r
+/* ecg algorithm */\r
+#if (__USE_GOODIX_ECG_ALGORITHM__)\r
+GS32 g_nEcgParamsArr[GOODIX_ECG_PARAMS_NUM_MAX] = {\r
+                                                         0,                                 // 采样率\r
+                                                         1,                                 // 算法有效通道数\r
+                                                         1,                                 // QRS检测标志\r
+                                                         0,                                 // ECG耦合方式\r
+                                                         0                                  // 芯片类型\r
+                                                   };\r
+/// ecg frame data cnt\r
+GU32 g_unEcgFrameCnt = 0;\r
+GU8 g_uchClassificationFlag;\r
+GU8 g_unEcgTimeSeconds = 0;\r
+#endif\r
+\r
+/* bt algorithm */\r
+#if (__USE_GOODIX_BT_ALGORITHM__)\r
+GS32 g_nBtParamsArr[GOODIX_BT_PARAMS_NUM_MAX] = {0};\r
+#endif\r
+\r
+/* af algorithm */\r
+#if (__USE_GOODIX_AF_ALGORITHM__)\r
+GS32 g_nAfParamsArr[GOODIX_AF_PARAMS_NUM_MAX] = {45, 0};\r
+#endif\r
+\r
+/// new data flag\r
+GU8 g_uchNewDataFlag = 0;\r
+GU8 g_uchGh3x2xSleepFlag = 0;\r
+\r
+//sensor enable\r
+GU8 g_uchAlgoGsensorEnable = 0;\r
+GU8 g_uchAlgoCapEnable = 0;\r
+GU8 g_uchAlgoTempEnable = 0;\r
+\r
+GS32 GH3x2x_Round(GF32 fValue)\r
+{\r
+    GS32 nRet = 0;\r
+    float fEpsinon = 0.00001;\r
+    if((fValue >= -fEpsinon)&&(fValue <= fEpsinon))\r
+    {\r
+        nRet = 0;\r
+    }\r
+    else if(fValue < -fEpsinon)\r
+    {\r
+        nRet = (GS32)(fValue - 0.5f);\r
+    }\r
+    else if(fValue > fEpsinon)\r
+    {\r
+        nRet = (GS32)(fValue + 0.5f);\r
+    }\r
+    return nRet;\r
+}\r
+\r
+GU8 GH3x2x_BitCount(GU32 n)\r
+{\r
+    GU8 c =0 ; // 计数器\r
+    while (n >0)\r
+    {\r
+        if((n &1) ==1) // 当前位是1\r
+            ++c ; // 计数器加1\r
+        n >>=1 ; // 移位\r
+    }\r
+    return c ;\r
+}\r
+\r
+void GH3x2xSleepFlagSet(GU8 uchSleepFlag)\r
+{\r
+    g_uchGh3x2xSleepFlag = uchSleepFlag;\r
+}\r
+\r
+\r
+GU8 GH3x2xSleepFlagGet(void)\r
+{\r
+    return g_uchGh3x2xSleepFlag;\r
+}\r
+\r
+void GH3X2X_AlgoSensorEnable(GU8 uchAlgoGsensorEnable,\r
+                            GU8 uchAlgoCapEnable,\r
+                            GU8 uchAlgoTempEnable)\r
+{\r
+    g_uchAlgoGsensorEnable = uchAlgoGsensorEnable;\r
+    g_uchAlgoCapEnable = uchAlgoCapEnable;\r
+    g_uchAlgoTempEnable = uchAlgoTempEnable;\r
+}\r
+\r
+/**\r
+ * @fn     GS8 GH3X2X_BTAlgorithmRTConfig(GS32 nOutputTime)\r
+ *\r
+ * @brief  BT algorithm RT table\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   nRTtable          \r
+ * @param[out]  None\r
+ *\r
+ * @return  error code\r
+ * @retval  #GH3X2X_RET_OK                      return successfully\r
+ * @retval  #GH3X2X_RET_ALGO_NO_SUPPORTED       return algorithm no supported error\r
+ */\r
+\r
+GS8 GH3X2X_BTAlgorithmRTConfig(GU16 *nRTtable)\r
+{\r
+#if (__USE_GOODIX_BT_ALGORITHM__)\r
+\r
+    GH3X2X_DEBUG_ALGO_LOG("%s\r\n", __FUNCTION__);\r
+    GH3X2X_Memcpy(g_nBtParamsArr, nRTtable, GOODIX_BT_PARAMS_NUM_MAX * sizeof(GU16));\r
+    return GH3X2X_RET_OK;\r
+\r
+#else\r
+    GH3X2X_DEBUG_ALGO_LOG("BT algorithm no supported error!\r\n");\r
+    return GH3X2X_RET_ALGO_NO_SUPPORTED;\r
+\r
+#endif\r
+}\r
+/**\r
+ * @fn     void GH3X2X_SetNewDataFlag(EMChannelMapId emFuncId, GU8 uchFlag)\r
+ *\r
+ * @brief  Set new sampling data flag\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   emFuncId    function id\r
+ * @param[in]   uchFlag      new data or not\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_SetNewDataFlag(GU8 emFuncId, GU8 uchFlag)\r
+{\r
+    if (GH3X2X_IS_NOT_NEW_RAWDATA == uchFlag)\r
+    {\r
+        GH3X2X_VAL_CLEAR_LEFT_BIT(g_uchNewDataFlag, emFuncId);\r
+    }\r
+    else\r
+    {\r
+        GH3X2X_VAL_SET_BIT(g_uchNewDataFlag, GH3X2X_GET_LEFT_SHIFT_VAL(emFuncId));\r
+    }\r
+}\r
+\r
+/**\r
+ * @fn     GS8 GH3X2X_HbAlgorithmScenarioConfig(GU8 uchScenario)\r
+ *\r
+ * @brief  Hb algorithm scenario config\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]  uchScenario     @ref EMHbaScenesConfigType\r
+ *                             others: fixed 0(default) and return GH3X2X_RET_PARAMETER_ERROR\r
+ * @param[out]  None\r
+ *\r
+ * @return  error code\r
+ * @retval  #GH3X2X_RET_OK                      return successfully\r
+ * @retval  #GH3X2X_RET_PARAMETER_ERROR         return paramters error\r
+ * @retval  #GH3X2X_RET_ALGO_NO_SUPPORTED       return algorithm no supported error\r
+ */\r
+GS8 GH3X2X_HbAlgorithmScenarioConfig(GU8 uchScenario)\r
+{\r
+#if (__USE_GOODIX_HR_ALGORITHM__)\r
+\r
+    GS8 chRet = GH3X2X_RET_OK;\r
+    GH3X2X_DEBUG_ALGO_LOG("%s\r\n", __FUNCTION__);\r
+    if (uchScenario > GH3X2X_HBA_SCENARIO_CONFIG_MAX_VAL)\r
+    {\r
+        GH3X2X_DEBUG_ALGO_LOG("hb algorithm scenario param error!\r\n");\r
+        g_unHrParamsArr[1] = HBA_SCENES_DEFAULT;\r
+        chRet = GH3X2X_RET_PARAMETER_ERROR;\r
+    }\r
+    else\r
+    {\r
+        g_unHrParamsArr[1] = uchScenario;\r
+    }\r
+\r
+#else\r
+\r
+    GS8 chRet = GH3X2X_RET_ALGO_NO_SUPPORTED;\r
+    GH3X2X_DEBUG_ALGO_LOG("hba algorithm no supported error!\r\n");\r
+\r
+#endif\r
+\r
+    return chRet;\r
+}\r
+\r
+/**\r
+ * @fn     GS8 GH3X2X_HbAlgorithmOutputTimeConfig(GS32 nOutputTime)\r
+ *\r
+ * @brief  Hb algorithm output time config\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   nOutputTime          valid 7~GS32_MAX\r
+ * @param[out]  None\r
+ *\r
+ * @return  error code\r
+ * @retval  #GH3X2X_RET_OK                      return successfully\r
+ * @retval  #GH3X2X_RET_ALGO_NO_SUPPORTED       return algorithm no supported error\r
+ */\r
+GS8 GH3X2X_HbAlgorithmOutputTimeConfig(GS32 nLatestOutputTime, GS32 nEarliestOutputTime)\r
+{\r
+#if (__USE_GOODIX_HR_ALGORITHM__)\r
+\r
+    GH3X2X_DEBUG_ALGO_LOG("%s\r\n", __FUNCTION__);\r
+    g_unHrParamsArr[3] = nLatestOutputTime;\r
+    g_unHrParamsArr[4] = nEarliestOutputTime;\r
+    return GH3X2X_RET_OK;\r
+\r
+#else\r
+\r
+    GH3X2X_DEBUG_ALGO_LOG("hba algorithm no supported error!\r\n");\r
+    return GH3X2X_RET_ALGO_NO_SUPPORTED;\r
+\r
+#endif\r
+}\r
+\r
+GU16 GH3X2X_ReadSpo2CorrectionFactor(GU16 usVirtualRegAddr)\r
+{\r
+#if 0\r
+    GU16 usVirtualRegData = 0;\r
+    GU16 usValIndex = 0;\r
+\r
+    if(usVirtualRegAddr >= GH3X2X_VSPO2_CH0_CORFAC0_L_REG_ADDR && usVirtualRegAddr <= GH3X2X_VSPO2_CH0_CORFAC2_H_REG_ADDR)\r
+    {\r
+        usValIndex = (usVirtualRegAddr - GH3X2X_VSPO2_CH0_CORFAC0_L_REG_ADDR) / GH3X2X_REG_ADDR_SIZE;\r
+    }\r
+    else if(usVirtualRegAddr >= GH3X2X_VSPO2_CH0_CORFAC3_L_REG_ADDR && usVirtualRegAddr <= GH3X2X_VSPO2_CH3_CORFAC4_H_REG_ADDR)\r
+    {\r
+        usValIndex = (usVirtualRegAddr - GH3X2X_VSPO2_CH0_CORFAC3_L_REG_ADDR) / GH3X2X_REG_ADDR_SIZE + 6;\r
+    }\r
+    else\r
+    {\r
+        return usVirtualRegData;\r
+    }\r
+    \r
+   if ((usValIndex % GH3X2X_REG_ADDR_SIZE) == 0) // low word\r
+   {\r
+       usVirtualRegData = GH3X2X_GET_LOW_WORD_FROM_DWORD(\r
+                            g_nSpo2ParamssArr[usValIndex / (SP02_CORR_FAC_NUM * 2)][(usValIndex % (SP02_CORR_FAC_NUM * 2)) / GH3X2X_REG_ADDR_SIZE]);\r
+   }\r
+   else // high word\r
+   {\r
+       usVirtualRegData = GH3X2X_GET_HIGH_WORD_FROM_DWORD(\r
+                            g_nSpo2ParamssArr[usValIndex / (SP02_CORR_FAC_NUM * 2)][(usValIndex % (SP02_CORR_FAC_NUM * 2)) / GH3X2X_REG_ADDR_SIZE]);\r
+   }\r
+\r
+   \r
+   return usVirtualRegData;\r
+#else\r
+     return 0;\r
+#endif\r
+}\r
+\r
+/**\r
+ * @fn     void GH3X2X_AlgoChnlMapInit(STAlgoChnlMap stAlgoChnlMap)\r
+ *\r
+ * @brief  Init algo channel group struct\r
+ *\r
+ * @attention   \r
+ *\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_AlgoChnlMapInit(STAlgoChnlMap *pstAlgoChnlMap)\r
+{\r
+    (*pstAlgoChnlMap).uchFlag = 0;\r
+    (*pstAlgoChnlMap).uchNum = 0;\r
+    for (GU32 num = 0  ; num < ALGO_CHNL_NUM ; num ++)\r
+    {\r
+        (*pstAlgoChnlMap).uchAlgoChnlMap[num] = 0xff;\r
+    }\r
+}\r
+\r
+/**\r
+ * @fn     void GH3X2X_HbaAlgoChnlMapDefultSet(void)\r
+ \r
+ *\r
+ * @brief  Set algo channel group Defult value\r
+ *\r
+ * @attention   \r
+ *\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_HbaAlgoChnlMapDefultSet(void)\r
+{\r
+#if (__USE_GOODIX_HR_ALGORITHM__)\r
+    if (!g_stHbaAlgoChnlMap.uchFlag)\r
+    {\r
+        GH3X2X_AlgoChnlMapInit(&g_stHbaAlgoChnlMap);\r
+        g_stHbaAlgoChnlMap.uchNum = __HR_ALGORITHM_SUPPORT_CHNL_NUM__;\r
+        for (GU8 cnt = 0; cnt < __HR_ALGORITHM_SUPPORT_CHNL_NUM__; cnt++)\r
+        {\r
+            g_stHbaAlgoChnlMap.uchAlgoChnlMap[ALGO_GREEN_CHNL_POS + cnt] = cnt;\r
+        }\r
+    }\r
+#endif\r
+}\r
+\r
+/**\r
+ * @fn     void GH3X2X_HrvAlgoChnlMapDefultSet(void)\r
+ \r
+ *\r
+ * @brief  Set algo channel group Defult value\r
+ *\r
+ * @attention   \r
+ *\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_HrvAlgoChnlMapDefultSet(void)\r
+{\r
+#if (0)\r
+    if (!g_stHrvAlgoChnlMap.uchFlag)\r
+    {\r
+        GH3X2X_AlgoChnlMapInit(&g_stHrvAlgoChnlMap);\r
+        g_stHrvAlgoChnlMap.uchNum = 1;\r
+        g_stHrvAlgoChnlMap.uchAlgoChnlMap[ALGO_GREEN_CHNL_POS + 0] = 0;\r
+    }\r
+#endif\r
+}\r
+\r
+/**\r
+ * @fn     void GH3X2X_Spo2AlgoChnlMapDefultSet(void)\r
+ \r
+ *\r
+ * @brief  Set algo channel group Defult value\r
+ *\r
+ * @attention   \r
+ *\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_Spo2AlgoChnlMapDefultSet(void)\r
+{\r
+#if (__USE_GOODIX_SPO2_ALGORITHM__)\r
+    if (!g_stSpo2AlgoChnlMap.uchFlag)\r
+    {\r
+        GH3X2X_AlgoChnlMapInit(&g_stSpo2AlgoChnlMap);\r
+        g_stSpo2AlgoChnlMap.uchNum = 1;\r
+        g_stSpo2AlgoChnlMap.uchAlgoChnlMap[ALGO_RED_CHNL_POS + 0] = 0;\r
+        g_stSpo2AlgoChnlMap.uchAlgoChnlMap[ALGO_IR_CHNL_POS + 0] = __SPO2_ALGORITHM_SUPPORT_CHNL_NUM__;\r
+    }\r
+#endif\r
+}\r
+\r
+void GH3X2X_BpAlgoChnlMapDefultSet(void)\r
+{\r
+#if (__USE_GOODIX_BP_ALGORITHM__)\r
+    if (!g_stBpAlgoChnlMap.uchFlag)\r
+    {\r
+        GH3X2X_AlgoChnlMapInit(&g_stBpAlgoChnlMap);\r
+        g_stBpAlgoChnlMap.uchNum = 1;\r
+        g_stBpAlgoChnlMap.uchAlgoChnlMap[ALGO_GREEN_CHNL_POS + 0] = 1;\r
+        g_stBpAlgoChnlMap.uchEcgAlgoChnlMap = 0;\r
+    }\r
+#endif\r
+}\r
+\r
+\r
+void GH3X2X_WriteAlgParametersWithVirtualReg(GU8 uchParasIndex, GU32 unFunctionID, GS32* nAlgParametersBuffer, GU8 nBufferMaxLen, GU16 usVirtualRegAddr, GU16 usVirtualRegValue)\r
+{\r
+    GU16 usValIndex = (usVirtualRegAddr - (unFunctionID * GH3X2X_VREG_FUNCTION_OFFSET + GH3X2X_ADT_ALG_CFG_ADDR)) / GH3X2X_REG_ADDR_SIZE;\r
+    if ((GS16)((GS16)usValIndex / (GS16)GH3X2X_REG_ADDR_SIZE - (GS16)uchParasIndex < 0) ||\\r
+        (usValIndex / GH3X2X_REG_ADDR_SIZE - uchParasIndex >= nBufferMaxLen))\r
+    {\r
+        return;\r
+    }\r
+    if ((usValIndex % GH3X2X_REG_ADDR_SIZE) != 0) // high word\r
+    {\r
+        nAlgParametersBuffer[usValIndex / GH3X2X_REG_ADDR_SIZE - uchParasIndex] = \\r
+            GH3X2X_MAKEUP_DWORD2(usVirtualRegValue, GH3X2X_GET_LOW_WORD_FROM_DWORD(nAlgParametersBuffer[usValIndex / GH3X2X_REG_ADDR_SIZE - uchParasIndex]));\r
+\r
+    }\r
+    else // low word\r
+    {\r
+        nAlgParametersBuffer[usValIndex / GH3X2X_REG_ADDR_SIZE - uchParasIndex] = \\r
+            GH3X2X_MAKEUP_DWORD2(GH3X2X_GET_HIGH_WORD_FROM_DWORD(nAlgParametersBuffer[usValIndex / GH3X2X_REG_ADDR_SIZE - uchParasIndex]), usVirtualRegValue);\r
+    }\r
+}\r
+\r
+void GH3X2X_WriteAlgChnlMapWithVirtualReg(GU32 unFunctionID, STAlgoChnlMap* pstAlgChnlMap, GU16 usVirtualRegAddr, GU16 usVirtualRegValue)\r
+{\r
+    GU16 usVirtualRegAddrOffset = usVirtualRegAddr - (unFunctionID * GH3X2X_VREG_FUNCTION_OFFSET + GH3X2X_ADT_ALG_CFG_ADDR);\r
+    switch (usVirtualRegAddrOffset)\r
+    {\r
+    case GH3X2X_VREG_ALGO_CHNL_MAP_OFFSET:\r
+        GH3X2X_AlgoChnlMapInit(pstAlgChnlMap);\r
+        pstAlgChnlMap->uchNum = GH3X2X_GET_LOW_BYTE_FROM_WORD(usVirtualRegValue);\r
+        if (pstAlgChnlMap->uchNum)\r
+        {\r
+            pstAlgChnlMap->uchFlag = 1;\r
+        }\r
+        break;\r
+    case GH3X2X_VREG_ALGO_CHNL_MAP_OFFSET + GH3X2X_REG_ADDR_SIZE:\r
+        pstAlgChnlMap->uchEcgAlgoChnlMap = (GU8)(usVirtualRegValue & 0x000000FF);\r
+        break;\r
+    default:\r
+        pstAlgChnlMap->uchAlgoChnlMap[usVirtualRegAddrOffset - GH3X2X_VREG_ALGO_CHNL_MAP_OFFSET - 2 * GH3X2X_REG_ADDR_SIZE]\\r
+            = GH3X2X_GET_LOW_BYTE_FROM_WORD(usVirtualRegValue);\r
+        pstAlgChnlMap->uchAlgoChnlMap[usVirtualRegAddrOffset - GH3X2X_VREG_ALGO_CHNL_MAP_OFFSET - 2 * GH3X2X_REG_ADDR_SIZE + 1]\\r
+            = GH3X2X_GET_HIGH_BYTE_FROM_WORD(usVirtualRegValue);\r
+    }\r
+}\r
+\r
+void GH3X2X_WriteHrAlgConfigWithVirtualReg(GU16 usVirtualRegAddr, GU16 usVirtualRegValue)\r
+{\r
+#if (__USE_GOODIX_HR_ALGORITHM__) // hr\r
+    if (usVirtualRegAddr < GH3X2X_HR_ALGO_CHNL_NUM_ADDR)\r
+    {\r
+        if(!g_stHbaAlgoChnlMap.uchFlag)\r
+        {\r
+            GH3X2X_AlgoChnlMapInit(&g_stHbaAlgoChnlMap);\r
+        }\r
+        \r
+        //GH3X2X_WriteAlgParametersWithVirtualReg(0, GH3X2X_FUNC_OFFSET_HR, (GS32*)&g_unHrParamsArr, GOODIX_HR_PARAMS_NUM_MAX, usVirtualRegAddr,usVirtualRegValue);\r
+        //GH3X2X_DEBUG_ALGO_LOG("[%s]:Hba Scenario = %d\r\n", __FUNCTION__, g_unHrParamsArr[1]);\r
+        if(HBA_SCENES_SLEEP == g_unHrParamsArr[1])\r
+        {\r
+            GH3x2xSleepFlagSet(1);\r
+        }\r
+    }\r
+    else\r
+    {\r
+        GH3X2X_WriteAlgChnlMapWithVirtualReg(GH3X2X_FUNC_OFFSET_HR, &g_stHbaAlgoChnlMap, usVirtualRegAddr, usVirtualRegValue);\r
+    }\r
+#endif\r
+}\r
+\r
+void GH3X2X_WriteHrvAlgConfigWithVirtualReg(GU16 usVirtualRegAddr, GU16 usVirtualRegValue)\r
+{\r
+#if (__USE_GOODIX_HRV_ALGORITHM__) // hrv\r
+    GH3X2X_WriteAlgParametersWithVirtualReg(0, GH3X2X_FUNC_OFFSET_HRV, (GS32*)g_nHrvParamsArr, GOODIX_HRV_PARAMS_NUM_MAX, usVirtualRegAddr, usVirtualRegValue);\r
+#endif\r
+}\r
+\r
+void GH3X2X_WriteSpo2AlgConfigWithVirtualReg(GU16 usVirtualRegAddr, GU16 usVirtualRegValue)\r
+{\r
+#if (__USE_GOODIX_SPO2_ALGORITHM__) // spo2\r
+    if (usVirtualRegAddr < GH3X2X_SPO2_ALGO_CHNL_NUM_ADDR)\r
+    {\r
+        GH3X2X_AlgoChnlMapInit(&g_stSpo2AlgoChnlMap);\r
+        //GH3X2X_WriteAlgParametersWithVirtualReg(0, GH3X2X_FUNC_OFFSET_SPO2, (GS32*)g_nSpo2ParamssArr, GOODIX_SPO2_PARAMS_NUM_MAX, usVirtualRegAddr,usVirtualRegValue);\r
+    }\r
+    else\r
+    {\r
+        GH3X2X_WriteAlgChnlMapWithVirtualReg(GH3X2X_FUNC_OFFSET_SPO2, &g_stSpo2AlgoChnlMap, usVirtualRegAddr, usVirtualRegValue);\r
+    }\r
+#endif\r
+}\r
+\r
+void GH3X2X_WriteEcgAlgConfigWithVirtualReg(GU16 usVirtualRegAddr, GU16 usVirtualRegValue)\r
+{\r
+#if (__USE_GOODIX_ECG_ALGORITHM__) // ecg\r
+    GH3X2X_WriteAlgParametersWithVirtualReg(0, GH3X2X_FUNC_OFFSET_ECG, (GS32*)g_nEcgParamsArr, GOODIX_ECG_PARAMS_NUM_MAX, usVirtualRegAddr, usVirtualRegValue);\r
+#endif\r
+}\r
+\r
+void GH3X2X_WriteBtAlgConfigWithVirtualReg(GU16 usVirtualRegAddr, GU16 usVirtualRegValue)\r
+{\r
+#if (__USE_GOODIX_BT_ALGORITHM__) // bt\r
+    GH3X2X_WriteAlgParametersWithVirtualReg(0, GH3X2X_FUNC_OFFSET_BT, (GS32*)g_nBtParamsArr, GOODIX_BT_PARAMS_NUM_MAX, usVirtualRegAddr, usVirtualRegValue);\r
+#endif\r
+}\r
+\r
+void GH3X2X_WriteAfAlgConfigWithVirtualReg(GU16 usVirtualRegAddr, GU16 usVirtualRegValue)\r
+{\r
+#if (__USE_GOODIX_AF_ALGORITHM__) // af\r
+    GH3X2X_WriteAlgParametersWithVirtualReg(0, GH3X2X_FUNC_OFFSET_AF, (GS32*)&g_nAfParamsArr, GOODIX_AF_PARAMS_NUM_MAX, usVirtualRegAddr, usVirtualRegValue);\r
+#endif\r
+}\r
+\r
+void GH3X2X_WriteBpAlgConfigWithVirtualReg(GU16 usVirtualRegAddr, GU16 usVirtualRegValue)\r
+{\r
+#if (__USE_GOODIX_BP_ALGORITHM__) // fpbp\r
+\r
+#endif\r
+}\r
+\r
+\r
+/**\r
+ * @fn     GU16 GH3X2X_ReadAlgorithmConfigWithVirtualReg(GU16 usVirtualRegAddr)\r
+ *\r
+ * @brief  Read algorithm param config with virtual reg\r
+ *\r
+ * @attention   Virtual reg addr has del control bits, so reg addr is [0:11] valid.\r
+ *\r
+ * @param[in]   usVirtualRegAddr        virtual reg addr\r
+ * @param[out]  None\r
+ *\r
+ * @return  virtual reg val\r
+ */\r
+GU16 GH3X2X_ReadAlgorithmConfigWithVirtualReg(GU16 usVirtualRegAddr)\r
+{\r
+    GU16 usVirtualRegData = 0;\r
+\r
+    return usVirtualRegData;\r
+}\r
+\r
+void GH3X2X_WriteAlgConfigWithVirtualReg(GU16 usVirtualRegAddr, GU16 usVirtualRegValue)\r
+{\r
+    if (usVirtualRegAddr < GH3X2X_REG_IS_VIRTUAL0X3_BIT)\r
+    {\r
+        return;\r
+    }\r
+    GU32 unFunctionID = (usVirtualRegAddr - GH3X2X_REG_IS_VIRTUAL0X3_BIT) / GH3X2X_VREG_FUNCTION_OFFSET;\r
+    if (usVirtualRegAddr >= GH3X2X_ADT_ALG_CFG_ADDR + GH3X2X_VREG_FUNCTION_OFFSET * unFunctionID &&\\r
+             usVirtualRegAddr < GH3X2X_ADT_DRV_CFG_ADDR + GH3X2X_VREG_FUNCTION_OFFSET * (unFunctionID + 1))\r
+    {\r
+        switch (unFunctionID)\r
+        {\r
+        case GH3X2X_FUNC_OFFSET_HR:\r
+            GH3X2X_WriteHrAlgConfigWithVirtualReg(usVirtualRegAddr, usVirtualRegValue);\r
+            break;\r
+        case GH3X2X_FUNC_OFFSET_HRV:\r
+            GH3X2X_WriteHrvAlgConfigWithVirtualReg(usVirtualRegAddr, usVirtualRegValue);\r
+            break;\r
+        case GH3X2X_FUNC_OFFSET_FPBP:\r
+        case GH3X2X_FUNC_OFFSET_PWA:\r
+            //GH3X2X_WriteBpAlgConfigWithVirtualReg(usVirtualRegAddr, usVirtualRegValue);\r
+            break;\r
+        case GH3X2X_FUNC_OFFSET_SPO2:\r
+            GH3X2X_WriteSpo2AlgConfigWithVirtualReg(usVirtualRegAddr, usVirtualRegValue);\r
+            break;\r
+        case GH3X2X_FUNC_OFFSET_ECG:\r
+            GH3X2X_WriteEcgAlgConfigWithVirtualReg(usVirtualRegAddr, usVirtualRegValue);\r
+            break;\r
+        case GH3X2X_FUNC_OFFSET_BT:\r
+            GH3X2X_WriteBtAlgConfigWithVirtualReg(usVirtualRegAddr, usVirtualRegValue);\r
+            break;\r
+        case GH3X2X_FUNC_OFFSET_AF:\r
+            GH3X2X_WriteAfAlgConfigWithVirtualReg(usVirtualRegAddr, usVirtualRegValue);\r
+            break;\r
+        default:\r
+            break;\r
+        }\r
+    }\r
+}\r
+\r
+void GH3X2X_LoadGoodixAlgoRegConfigArr(const STGh3x2xInitConfig *pstGoodixAlgoCfgListArr)\r
+{\r
+    const STGh3x2xReg *pstRegConfigArr = pstGoodixAlgoCfgListArr->pstRegConfigArr;\r
+    GU16 usRegConfigLen = pstGoodixAlgoCfgListArr->usConfigArrLen;\r
+    GU16 usIndex = 0;\r
+    if ((pstRegConfigArr != GH3X2X_PTR_NULL) && (usRegConfigLen != 0))\r
+    {\r
+        for (usIndex = 0; usIndex < usRegConfigLen; usIndex++) // write GH3X2X reg.\r
+        {\r
+            GH3X2X_WriteAlgConfigWithVirtualReg(pstRegConfigArr[usIndex].usRegAddr, pstRegConfigArr[usIndex].usRegData);\r
+        }\r
+    }\r
+}\r
+\r
+#endif\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+/********END OF FILE********* Copyright (c) 2003 - 2022, Goodix Co., Ltd. ********/\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_application/src/gh3x2x_demo_algo_frame.c b/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_application/src/gh3x2x_demo_algo_frame.c
new file mode 100644 (file)
index 0000000..6bae1d8
--- /dev/null
@@ -0,0 +1,817 @@
+/**\r
+ * @copyright (c) 2003 - 2022, Goodix Co., Ltd. All rights reserved.\r
+ * \r
+ * @file    gh2x2x_demo_algo_frame.c\r
+ * \r
+ * @brief   gh3x2x algo frame info\r
+ * \r
+ * @author  Gooidx Iot Team\r
+ * \r
+ */\r
+\r
+/* includes */\r
+#include "gh3x2x_demo_algo_config.h"\r
+#include "gh_demo_config.h"\r
+#include "gh_drv.h"\r
+\r
+\r
+#if __GH_SEPARATE_ALGO_EN__\r
+\r
+#if __FUNC_RUN_SIMULTANEOUSLY_SUPPORT__\r
+#if __USE_GOODIX_HR_ALGORITHM__\r
+GU32 g_pun_HR_FrameIncompleteRawdata[GH3X2X_HR_CHNL_NUM];\r
+GU32 g_un_HR_FrameIncompleteChnlMapBit;\r
+GU8 g_puch_HR_FrameLastGain[GH3X2X_HR_CHNL_NUM];\r
+GU32 g_un_HR_TimeStamp;\r
+STGh3x2xDownSampleInfo g_stGh3x2xDownSampleInfo_HR;\r
+#endif\r
+#if __USE_GOODIX_HRV_ALGORITHM__\r
+GU32 g_pun_HRV_FrameIncompleteRawdata[GH3X2X_HRV_CHNL_NUM];\r
+GU32 g_un_HRV_FrameIncompleteChnlMapBit;\r
+GU8 g_puch_HRV_FrameLastGain[GH3X2X_HRV_CHNL_NUM];\r
+GU32 g_un_HRV_TimeStamp;\r
+STGh3x2xDownSampleInfo g_stGh3x2xDownSampleInfo_HRV;\r
+#endif\r
+#if __USE_GOODIX_HSM_ALGORITHM__\r
+GU32 g_pun_HSM_FrameIncompleteRawdata[GH3X2X_HSM_CHNL_NUM];\r
+GU32 g_un_HSM_FrameIncompleteChnlMapBit;\r
+GU8 g_puch_HSM_FrameLastGain[GH3X2X_HSM_CHNL_NUM];\r
+GU32 g_un_HSM_TimeStamp;\r
+STGh3x2xDownSampleInfo g_stGh3x2xDownSampleInfo_HSM;\r
+#endif\r
+#if __USE_GOODIX_SPO2_ALGORITHM__\r
+GU32 g_pun_SPO2_FrameIncompleteRawdata[GH3X2X_SPO2_CHNL_NUM];\r
+GU32 g_un_SPO2_FrameIncompleteChnlMapBit;\r
+GU8 g_puch_SPO2_FrameLastGain[GH3X2X_SPO2_CHNL_NUM];\r
+GU32 g_un_SPO2_TimeStamp;\r
+STGh3x2xDownSampleInfo g_stGh3x2xDownSampleInfo_SPO2;\r
+#endif\r
+#if __USE_GOODIX_ECG_ALGORITHM__\r
+GU32 g_pun_ECG_FrameIncompleteRawdata[GH3X2X_ECG_CHNL_NUM];\r
+GU32 g_un_ECG_FrameIncompleteChnlMapBit;\r
+GU8 g_puch_ECG_FrameLastGain[GH3X2X_ECG_CHNL_NUM];\r
+GU32 g_un_ECG_TimeStamp;\r
+STGh3x2xDownSampleInfo g_stGh3x2xDownSampleInfo_ECG;\r
+#endif\r
+#if 0\r
+GU32 g_pun_PWTT_FrameIncompleteRawdata[GH3X2X_PWTT_CHNL_NUM];\r
+GU32 g_un_PWTT_FrameIncompleteChnlMapBit;\r
+GU8 g_puch_PWTT_FrameLastGain[GH3X2X_PWTT_CHNL_NUM];\r
+GU32 g_un_PWTT_TimeStamp;\r
+STGh3x2xDownSampleInfo g_stGh3x2xDownSampleInfo_PWTT;\r
+#endif\r
+#if __USE_GOODIX_BT_ALGORITHM__\r
+GU32 g_pun_BT_FrameIncompleteRawdata[GH3X2X_BT_CHNL_NUM];\r
+GU32 g_un_BT_FrameIncompleteChnlMapBit;\r
+GU8 g_puch_BT_FrameLastGain[GH3X2X_BT_CHNL_NUM];\r
+GU32 g_un_BT_TimeStamp;\r
+STGh3x2xDownSampleInfo g_stGh3x2xDownSampleInfo_BT;\r
+#endif\r
+#if __USE_GOODIX_RESP_ALGORITHM__\r
+GU32 g_pun_RESP_FrameIncompleteRawdata[GH3X2X_RESP_CHNL_NUM];\r
+GU32 g_un_RESP_FrameIncompleteChnlMapBit;\r
+GU8 g_puch_RESP_FrameLastGain[GH3X2X_RESP_CHNL_NUM];\r
+GU32 g_un_RESP_TimeStamp;\r
+STGh3x2xDownSampleInfo g_stGh3x2xDownSampleInfo_RESP;\r
+#endif\r
+#if __USE_GOODIX_AF_ALGORITHM__\r
+GU32 g_pun_AF_FrameIncompleteRawdata[GH3X2X_AF_CHNL_NUM];\r
+GU32 g_un_AF_FrameIncompleteChnlMapBit;\r
+GU8 g_puch_AF_FrameLastGain[GH3X2X_AF_CHNL_NUM];\r
+GU32 g_un_AF_TimeStamp;\r
+STGh3x2xDownSampleInfo g_stGh3x2xDownSampleInfo_AF;\r
+#endif\r
+#if __USE_GOODIX_BP_ALGORITHM__\r
+GU32 g_pun_BP_FrameIncompleteRawdata[GH3X2X_BP_CHNL_NUM];\r
+GU32 g_un_BP_FrameIncompleteChnlMapBit;\r
+GU8 g_puch_BP_FrameLastGain[GH3X2X_BP_CHNL_NUM];\r
+GU32 g_un_BP_TimeStamp;\r
+STGh3x2xDownSampleInfo g_stGh3x2xDownSampleInfo_BP;\r
+#endif\r
+#if 0\r
+GU32 g_pun_TEST1_FrameIncompleteRawdata[GH3X2X_TEST_CHNL_NUM];\r
+GU32 g_un_TEST1_FrameIncompleteChnlMapBit;\r
+GU8 g_puch_TEST1_FrameLastGain[GH3X2X_TEST_CHNL_NUM];\r
+GU32 g_un_TEST1_TimeStamp;\r
+STGh3x2xDownSampleInfo g_stGh3x2xDownSampleInfo_TEST1;\r
+GU32 g_pun_TEST2_FrameIncompleteRawdata[GH3X2X_TEST_CHNL_NUM];\r
+GU32 g_un_TEST2_FrameIncompleteChnlMapBit;\r
+GU8 g_puch_TEST2_FrameLastGain[GH3X2X_TEST_CHNL_NUM];\r
+GU32 g_un_TEST2_TimeStamp;\r
+STGh3x2xDownSampleInfo g_stGh3x2xDownSampleInfo_TEST2;\r
+#endif\r
+#else\r
+GU32 g_pun_MAIN_FUNC_FrameIncompleteRawdata[GH3X2X_MAIN_FUNC_CHNL_NUM];\r
+GU32 g_un_MAIN_FUNC_FrameIncompleteChnlMapBit;\r
+GU8 g_puch_MAIN_FUNC_FrameLastGain[GH3X2X_MAIN_FUNC_CHNL_NUM];\r
+GU32 g_un_MAIN_FUNC_TimeStamp;\r
+STGh3x2xDownSampleInfo g_stGh3x2xDownSampleInfo_MAIN_FUNC;\r
+#endif\r
+#if  __USE_GOODIX_ADT_ALGORITHM__\r
+GU32 g_pun_ADT_FrameIncompleteRawdata[GH3X2X_ADT_CHNL_NUM];\r
+GU32 g_un_ADT_FrameIncompleteChnlMapBit;\r
+GU8 g_puch_ADT_FrameLastGain[GH3X2X_ADT_CHNL_NUM];\r
+GU32 g_un_ADT_TimeStamp;\r
+STGh3x2xDownSampleInfo g_stGh3x2xDownSampleInfo_ADT;\r
+#endif\r
+#if __USE_GOODIX_SOFT_ADT_ALGORITHM__\r
+GU32 g_pun_SOFT_ADT_GREEN_FrameIncompleteRawdata[GH3X2X_SOFT_ADT_CHNL_NUM];\r
+GU32 g_un_SOFT_ADT_GREEN_FrameIncompleteChnlMapBit;\r
+GU8 g_puch_SOFT_ADT_GREEN_FrameLastGain[GH3X2X_SOFT_ADT_CHNL_NUM];\r
+GU32 g_un_SOFT_ADT_GREEN_TimeStamp;\r
+STGh3x2xDownSampleInfo g_stGh3x2xDownSampleInfo_SOFT_ADT_GREEN;\r
+#endif\r
+\r
+\r
+\r
+\r
+#if __USE_GOODIX_HR_ALGORITHM__\r
+GU8 g_pch_HR_ChnlMap[GH3X2X_HR_CHNL_NUM];\r
+STGh3x2xFunctionInfo g_st_HR_FuncitonInfo;\r
+STGh3x2xAlgoResult g_st_HR_AlgoRecordResult;\r
+#endif\r
+#if __USE_GOODIX_HRV_ALGORITHM__\r
+GU8 g_pch_HRV_ChnlMap[GH3X2X_HRV_CHNL_NUM];\r
+STGh3x2xFunctionInfo g_st_HRV_FuncitonInfo;\r
+STGh3x2xAlgoResult g_st_HRV_AlgoRecordResult;\r
+#endif\r
+#if __USE_GOODIX_HSM_ALGORITHM__\r
+GU8 g_pch_HSM_ChnlMap[GH3X2X_HSM_CHNL_NUM];\r
+STGh3x2xFunctionInfo g_st_HSM_FuncitonInfo;\r
+#endif\r
+#if __USE_GOODIX_SPO2_ALGORITHM__\r
+GU8 g_pch_SPO2_ChnlMap[GH3X2X_SPO2_CHNL_NUM];\r
+STGh3x2xFunctionInfo g_st_SPO2_FuncitonInfo;\r
+STGh3x2xAlgoResult g_st_SPO2_AlgoRecordResult;\r
+#endif\r
+#if __USE_GOODIX_ECG_ALGORITHM__\r
+GU8 g_pch_ECG_ChnlMap[GH3X2X_ECG_CHNL_NUM];\r
+STGh3x2xFunctionInfo g_st_ECG_FuncitonInfo;\r
+#endif\r
+#if 0\r
+GU8 g_pch_PWTT_ChnlMap[GH3X2X_PWTT_CHNL_NUM];\r
+STGh3x2xFunctionInfo g_st_PWTT_FuncitonInfo;\r
+#endif\r
+#if __USE_GOODIX_BT_ALGORITHM__\r
+GU8 g_pch_BT_ChnlMap[GH3X2X_BT_CHNL_NUM];\r
+STGh3x2xFunctionInfo g_st_BT_FuncitonInfo;\r
+#endif\r
+#if __USE_GOODIX_RESP_ALGORITHM__\r
+GU8 g_pch_RESP_ChnlMap[GH3X2X_RESP_CHNL_NUM];\r
+STGh3x2xFunctionInfo g_st_RESP_FuncitonInfo;\r
+#endif\r
+#if __USE_GOODIX_AF_ALGORITHM__\r
+GU8 g_pch_AF_ChnlMap[GH3X2X_AF_CHNL_NUM];\r
+STGh3x2xFunctionInfo g_st_AF_FuncitonInfo;\r
+#endif\r
+#if __USE_GOODIX_ADT_ALGORITHM__\r
+GU8 g_pch_ADT_ChnlMap[GH3X2X_ADT_CHNL_NUM];\r
+STGh3x2xFunctionInfo g_st_ADT_FuncitonInfo;\r
+#endif\r
+#if __USE_GOODIX_SOFT_ADT_ALGORITHM__\r
+GU8 g_pch_SOFT_ADT_GREEN_ChnlMap[GH3X2X_SOFT_ADT_CHNL_NUM];\r
+STGh3x2xFunctionInfo g_st_SOFT_ADT_GREEN_FuncitonInfo;\r
+#endif\r
+#if __USE_GOODIX_SOFT_ADT_ALGORITHM__\r
+GU8 g_pch_SOFT_ADT_IR_ChnlMap[GH3X2X_SOFT_ADT_CHNL_NUM];\r
+STGh3x2xFunctionInfo g_st_SOFT_ADT_IR_FuncitonInfo;\r
+#endif\r
+#if __FUNC_TYPE_BP_ENABLE__\r
+GU8 g_pch_BP_ChnlMap[GH3X2X_BP_CHNL_NUM];\r
+STGh3x2xFunctionInfo g_st_BP_FuncitonInfo;\r
+#endif\r
+#if 0\r
+GU8 g_pch_TEST1_ChnlMap[GH3X2X_TEST_CHNL_NUM];\r
+STGh3x2xFunctionInfo g_st_TEST1_FuncitonInfo;\r
+GU8 g_pch_TEST2_ChnlMap[GH3X2X_TEST_CHNL_NUM];\r
+STGh3x2xFunctionInfo g_st_TEST2_FuncitonInfo;\r
+#endif\r
+\r
+GU32 g_punGh3x2xFrameRawdata[GH3X2X_FUNC_CHNL_NUM_MAX];\r
+#if __GS_GYRO_ENABLE__\r
+GS16 g_psGh3x2xFrameGsensorData[6];\r
+#else\r
+GS16 g_psGh3x2xFrameGsensorData[3];\r
+#endif\r
+GU32 g_punGh3x2xFrameAgcInfo[GH3X2X_FUNC_CHNL_NUM_MAX];\r
+GU32 g_punGh3x2xFrameFlag[8];\r
+STGh3x2xAlgoResult g_stGh3x2xAlgoResult;\r
+\r
+STCapRawdata g_pstGh3x2xFrameCapData;\r
+STTempRawdata g_pstGh3x2xFrameTempData;\r
+\r
+\r
+\r
+//HR data info\r
+#if __USE_GOODIX_HR_ALGORITHM__\r
+const STGh3x2xFrameInfo g_stHR_FrameInfo = \r
+{\r
+    .unFunctionID = GH3X2X_FUNCTION_HR,\r
+    .pstFunctionInfo = &g_st_HR_FuncitonInfo,\r
+    .pstAlgoResult   = &g_stGh3x2xAlgoResult,\r
+    .uchFuntionChnlLimit = GH3X2X_HR_CHNL_NUM,\r
+    .pchChnlMap = g_pch_HR_ChnlMap,\r
+    .punFrameRawdata = g_punGh3x2xFrameRawdata,\r
+    .pusFrameGsensordata = g_psGh3x2xFrameGsensorData,\r
+    .pstFrameCapdata = &g_pstGh3x2xFrameCapData,\r
+    .pstFrameTempdata = &g_pstGh3x2xFrameTempData,\r
+    .punFrameAgcInfo = g_punGh3x2xFrameAgcInfo,\r
+    .punFrameFlag = g_punGh3x2xFrameFlag,\r
+    .pstAlgoRecordResult = &g_st_HR_AlgoRecordResult,\r
+#if !__FUNC_RUN_SIMULTANEOUSLY_SUPPORT__\r
+    .punIncompleteRawdata = g_pun_MAIN_FUNC_FrameIncompleteRawdata,\r
+    .punIncompleteChnlMapBit = &g_un_MAIN_FUNC_FrameIncompleteChnlMapBit,\r
+    .puchFrameLastGain = g_puch_MAIN_FUNC_FrameLastGain,\r
+    .punFrameCnt = &g_un_MAIN_FUNC_TimeStamp,\r
+    .pstDownSampleInfo = &g_stGh3x2xDownSampleInfo_MAIN_FUNC,\r
+#else\r
+    .punIncompleteRawdata = g_pun_HR_FrameIncompleteRawdata,\r
+    .punIncompleteChnlMapBit = &g_un_HR_FrameIncompleteChnlMapBit,\r
+    .puchFrameLastGain = g_puch_HR_FrameLastGain,\r
+    .punFrameCnt = &g_un_HR_TimeStamp,\r
+    .pstDownSampleInfo = &g_stGh3x2xDownSampleInfo_HR,\r
+#endif\r
+};\r
+//const STGh3x2xFrameInfo * const  g_pstGh3x2xHR_FrameInfo = &g_stHR_FrameInfo;\r
+#else\r
+//const STGh3x2xFrameInfo * const  g_pstGh3x2xHR_FrameInfo = 0;\r
+#endif\r
+//HRV data info\r
+#if __USE_GOODIX_HRV_ALGORITHM__\r
+const STGh3x2xFrameInfo g_stHRV_FrameInfo =\r
+{\r
+    .unFunctionID = GH3X2X_FUNCTION_HRV,\r
+    .pstFunctionInfo = &g_st_HRV_FuncitonInfo,\r
+    .pstAlgoResult   = &g_stGh3x2xAlgoResult,\r
+    .uchFuntionChnlLimit = GH3X2X_HRV_CHNL_NUM,\r
+    .pchChnlMap = g_pch_HRV_ChnlMap,\r
+    .punFrameRawdata = g_punGh3x2xFrameRawdata,\r
+    .pusFrameGsensordata = g_psGh3x2xFrameGsensorData,\r
+    .pstFrameCapdata = &g_pstGh3x2xFrameCapData,\r
+    .pstFrameTempdata = &g_pstGh3x2xFrameTempData,\r
+    .punFrameAgcInfo = g_punGh3x2xFrameAgcInfo,\r
+    .punFrameFlag = g_punGh3x2xFrameFlag,\r
+    .pstAlgoRecordResult = &g_st_HRV_AlgoRecordResult,\r
+#if !__FUNC_RUN_SIMULTANEOUSLY_SUPPORT__\r
+    .punIncompleteRawdata = g_pun_MAIN_FUNC_FrameIncompleteRawdata,\r
+    .punIncompleteChnlMapBit = &g_un_MAIN_FUNC_FrameIncompleteChnlMapBit,\r
+    .puchFrameLastGain = g_puch_MAIN_FUNC_FrameLastGain,\r
+    .punFrameCnt = &g_un_MAIN_FUNC_TimeStamp,\r
+    .pstDownSampleInfo = &g_stGh3x2xDownSampleInfo_MAIN_FUNC,\r
+#else\r
+    .punIncompleteRawdata = g_pun_HRV_FrameIncompleteRawdata,\r
+    .punIncompleteChnlMapBit = &g_un_HRV_FrameIncompleteChnlMapBit,\r
+    .puchFrameLastGain = g_puch_HRV_FrameLastGain,\r
+    .punFrameCnt = &g_un_HRV_TimeStamp,\r
+    .pstDownSampleInfo = &g_stGh3x2xDownSampleInfo_HRV,\r
+#endif\r
+};\r
+//const STGh3x2xFrameInfo * const  g_pstGh3x2xHRV_FrameInfo = &g_stHRV_FrameInfo;\r
+#else\r
+//const STGh3x2xFrameInfo * const  g_pstGh3x2xHRV_FrameInfo = 0;\r
+#endif\r
+//HSM data info\r
+#if __USE_GOODIX_HSM_ALGORITHM__\r
+const STGh3x2xFrameInfo g_stHSM_FrameInfo =\r
+{\r
+    .unFunctionID = GH3X2X_FUNCTION_HSM,\r
+    .pstFunctionInfo = &g_st_HSM_FuncitonInfo,\r
+    .pstAlgoResult   = &g_stGh3x2xAlgoResult,\r
+    .uchFuntionChnlLimit = GH3X2X_HSM_CHNL_NUM,\r
+    .pchChnlMap = g_pch_HSM_ChnlMap,\r
+    .punFrameRawdata = g_punGh3x2xFrameRawdata,\r
+    .pusFrameGsensordata = g_psGh3x2xFrameGsensorData,\r
+    .pstFrameCapdata = &g_pstGh3x2xFrameCapData,\r
+    .pstFrameTempdata = &g_pstGh3x2xFrameTempData,\r
+    .punFrameAgcInfo = g_punGh3x2xFrameAgcInfo,\r
+    .punFrameFlag = g_punGh3x2xFrameFlag,\r
+    .pstAlgoRecordResult = 0,\r
+#if !__FUNC_RUN_SIMULTANEOUSLY_SUPPORT__\r
+    .punIncompleteRawdata = g_pun_MAIN_FUNC_FrameIncompleteRawdata,\r
+    .punIncompleteChnlMapBit = &g_un_MAIN_FUNC_FrameIncompleteChnlMapBit,\r
+    .puchFrameLastGain = g_puch_MAIN_FUNC_FrameLastGain,\r
+    .punFrameCnt = &g_un_MAIN_FUNC_TimeStamp,\r
+    .pstDownSampleInfo = &g_stGh3x2xDownSampleInfo_MAIN_FUNC,\r
+#else\r
+    .punIncompleteRawdata = g_pun_HSM_FrameIncompleteRawdata,\r
+    .punIncompleteChnlMapBit = &g_un_HSM_FrameIncompleteChnlMapBit,\r
+    .puchFrameLastGain = g_puch_HSM_FrameLastGain,\r
+    .punFrameCnt = &g_un_HSM_TimeStamp,\r
+    .pstDownSampleInfo = &g_stGh3x2xDownSampleInfo_HSM,\r
+#endif\r
+};\r
+//const STGh3x2xFrameInfo * const  g_pstGh3x2xHSM_FrameInfo = &g_stHSM_FrameInfo;\r
+#else\r
+//const STGh3x2xFrameInfo * const  g_pstGh3x2xHSM_FrameInfo = 0;\r
+#endif\r
+//SPO2 data info\r
+#if __USE_GOODIX_SPO2_ALGORITHM__\r
+const STGh3x2xFrameInfo g_stSPO2_FrameInfo = \r
+{\r
+    .unFunctionID = GH3X2X_FUNCTION_SPO2,\r
+    .pstFunctionInfo = &g_st_SPO2_FuncitonInfo,\r
+    .pstAlgoResult   = &g_stGh3x2xAlgoResult,\r
+    .uchFuntionChnlLimit = GH3X2X_SPO2_CHNL_NUM,\r
+    .pchChnlMap = g_pch_SPO2_ChnlMap,\r
+    .punFrameRawdata = g_punGh3x2xFrameRawdata,\r
+    .pusFrameGsensordata = g_psGh3x2xFrameGsensorData,\r
+    .pstFrameCapdata = &g_pstGh3x2xFrameCapData,\r
+    .pstFrameTempdata = &g_pstGh3x2xFrameTempData,\r
+    .punFrameAgcInfo = g_punGh3x2xFrameAgcInfo,\r
+    .punFrameFlag = g_punGh3x2xFrameFlag,\r
+    .pstAlgoRecordResult = &g_st_SPO2_AlgoRecordResult,\r
+#if !__FUNC_RUN_SIMULTANEOUSLY_SUPPORT__\r
+    .punIncompleteRawdata = g_pun_MAIN_FUNC_FrameIncompleteRawdata,\r
+    .punIncompleteChnlMapBit = &g_un_MAIN_FUNC_FrameIncompleteChnlMapBit,\r
+    .puchFrameLastGain = g_puch_MAIN_FUNC_FrameLastGain,\r
+    .punFrameCnt = &g_un_MAIN_FUNC_TimeStamp,\r
+    .pstDownSampleInfo = &g_stGh3x2xDownSampleInfo_MAIN_FUNC,\r
+#else\r
+    .punIncompleteRawdata = g_pun_SPO2_FrameIncompleteRawdata,\r
+    .punIncompleteChnlMapBit = &g_un_SPO2_FrameIncompleteChnlMapBit,\r
+    .puchFrameLastGain = g_puch_SPO2_FrameLastGain,\r
+    .punFrameCnt = &g_un_SPO2_TimeStamp,\r
+    .pstDownSampleInfo = &g_stGh3x2xDownSampleInfo_SPO2,\r
+#endif\r
+};\r
+//const STGh3x2xFrameInfo * const  g_pstGh3x2xSPO2_FrameInfo = &g_stSPO2_FrameInfo;\r
+#else\r
+//const STGh3x2xFrameInfo * const  g_pstGh3x2xSPO2_FrameInfo = 0;\r
+#endif\r
+//ECG data info\r
+#if __USE_GOODIX_ECG_ALGORITHM__\r
+const STGh3x2xFrameInfo g_stECG_FrameInfo = \r
+{\r
+    .unFunctionID = GH3X2X_FUNCTION_ECG,\r
+    .pstFunctionInfo = &g_st_ECG_FuncitonInfo,\r
+    .pstAlgoResult   = &g_stGh3x2xAlgoResult,\r
+    .uchFuntionChnlLimit = GH3X2X_ECG_CHNL_NUM,\r
+    .pchChnlMap = g_pch_ECG_ChnlMap,\r
+    .punFrameRawdata = g_punGh3x2xFrameRawdata,\r
+    .pusFrameGsensordata = g_psGh3x2xFrameGsensorData,\r
+    .pstFrameCapdata = &g_pstGh3x2xFrameCapData,\r
+    .pstFrameTempdata = &g_pstGh3x2xFrameTempData,\r
+    .punFrameAgcInfo = g_punGh3x2xFrameAgcInfo,\r
+    .punFrameFlag = g_punGh3x2xFrameFlag,\r
+    .pstAlgoRecordResult = 0,\r
+#if !__FUNC_RUN_SIMULTANEOUSLY_SUPPORT__\r
+    .punIncompleteRawdata = g_pun_MAIN_FUNC_FrameIncompleteRawdata,\r
+    .punIncompleteChnlMapBit = &g_un_MAIN_FUNC_FrameIncompleteChnlMapBit,\r
+    .puchFrameLastGain = g_puch_MAIN_FUNC_FrameLastGain,\r
+    .punFrameCnt = &g_un_MAIN_FUNC_TimeStamp,\r
+    .pstDownSampleInfo = &g_stGh3x2xDownSampleInfo_MAIN_FUNC,\r
+#else\r
+    .punIncompleteRawdata = g_pun_ECG_FrameIncompleteRawdata,\r
+    .punIncompleteChnlMapBit = &g_un_ECG_FrameIncompleteChnlMapBit,\r
+    .puchFrameLastGain = g_puch_ECG_FrameLastGain,\r
+    .punFrameCnt = &g_un_ECG_TimeStamp,\r
+    .pstDownSampleInfo = &g_stGh3x2xDownSampleInfo_ECG,\r
+#endif\r
+};\r
+//const STGh3x2xFrameInfo * const  g_pstGh3x2xECG_FrameInfo = &g_stECG_FrameInfo;\r
+#else\r
+//const STGh3x2xFrameInfo * const  g_pstGh3x2xECG_FrameInfo = 0;\r
+#endif\r
+#if 0\r
+const STGh3x2xFrameInfo g_stPWTT_FrameInfo = \r
+{\r
+    .unFunctionID = GH3X2X_FUNCTION_PWTT,\r
+    .pstFunctionInfo = &g_st_PWTT_FuncitonInfo,\r
+    .pstAlgoResult   = &g_stGh3x2xAlgoResult,\r
+    .uchFuntionChnlLimit = GH3X2X_PWTT_CHNL_NUM,\r
+    .pchChnlMap = g_pch_PWTT_ChnlMap,\r
+    .punFrameRawdata = g_punGh3x2xFrameRawdata,\r
+    .pusFrameGsensordata = g_psGh3x2xFrameGsensorData,\r
+    .pstFrameCapdata = &g_pstGh3x2xFrameCapData,\r
+    .pstFrameTempdata = &g_pstGh3x2xFrameTempData,\r
+    .punFrameAgcInfo = g_punGh3x2xFrameAgcInfo,\r
+    .punFrameFlag = g_punGh3x2xFrameFlag,\r
+    .pstAlgoRecordResult = 0,\r
+#if !__FUNC_RUN_SIMULTANEOUSLY_SUPPORT__\r
+    .punIncompleteRawdata = g_pun_MAIN_FUNC_FrameIncompleteRawdata,\r
+    .punIncompleteChnlMapBit = &g_un_MAIN_FUNC_FrameIncompleteChnlMapBit,\r
+    .puchFrameLastGain = g_puch_MAIN_FUNC_FrameLastGain,\r
+    .punFrameCnt = &g_un_MAIN_FUNC_TimeStamp,\r
+    .pstDownSampleInfo = &g_stGh3x2xDownSampleInfo_MAIN_FUNC,\r
+#else\r
+    .punIncompleteRawdata = g_pun_PWTT_FrameIncompleteRawdata,\r
+    .punIncompleteChnlMapBit = &g_un_PWTT_FrameIncompleteChnlMapBit,\r
+    .puchFrameLastGain = g_puch_PWTT_FrameLastGain,\r
+    .punFrameCnt = &g_un_PWTT_TimeStamp,\r
+    .pstDownSampleInfo = &g_stGh3x2xDownSampleInfo_PWTT,\r
+#endif\r
+};\r
+//const STGh3x2xFrameInfo * const  g_pstGh3x2xECG_FrameInfo = &g_stECG_FrameInfo;\r
+#else\r
+//const STGh3x2xFrameInfo * const  g_pstGh3x2xECG_FrameInfo = 0;\r
+#endif\r
+//BT data info\r
+#if __USE_GOODIX_BT_ALGORITHM__\r
+const STGh3x2xFrameInfo g_stBT_FrameInfo =\r
+{\r
+    .unFunctionID = GH3X2X_FUNCTION_BT,\r
+    .pstFunctionInfo = &g_st_BT_FuncitonInfo,\r
+    .pstAlgoResult   = &g_stGh3x2xAlgoResult,\r
+    .uchFuntionChnlLimit = GH3X2X_BT_CHNL_NUM,\r
+    .pchChnlMap = g_pch_BT_ChnlMap,\r
+    .punFrameRawdata = g_punGh3x2xFrameRawdata,\r
+    .pusFrameGsensordata = g_psGh3x2xFrameGsensorData,\r
+    .pstFrameCapdata = &g_pstGh3x2xFrameCapData,\r
+    .pstFrameTempdata = &g_pstGh3x2xFrameTempData,\r
+    .punFrameAgcInfo = g_punGh3x2xFrameAgcInfo,\r
+    .punFrameFlag = g_punGh3x2xFrameFlag,\r
+    .pstAlgoRecordResult = 0,\r
+#if !__FUNC_RUN_SIMULTANEOUSLY_SUPPORT__\r
+    .punIncompleteRawdata = g_pun_MAIN_FUNC_FrameIncompleteRawdata,\r
+    .punIncompleteChnlMapBit = &g_un_MAIN_FUNC_FrameIncompleteChnlMapBit,\r
+    .puchFrameLastGain = g_puch_MAIN_FUNC_FrameLastGain,\r
+    .punFrameCnt = &g_un_MAIN_FUNC_TimeStamp,\r
+    .pstDownSampleInfo = &g_stGh3x2xDownSampleInfo_MAIN_FUNC,\r
+#else\r
+    .punIncompleteRawdata = g_pun_BT_FrameIncompleteRawdata,\r
+    .punIncompleteChnlMapBit = &g_un_BT_FrameIncompleteChnlMapBit,\r
+    .puchFrameLastGain = g_puch_BT_FrameLastGain,\r
+    .punFrameCnt = &g_un_BT_TimeStamp,\r
+    .pstDownSampleInfo = &g_stGh3x2xDownSampleInfo_BT,\r
+#endif\r
+};\r
+//const STGh3x2xFrameInfo * const  g_pstGh3x2xBT_FrameInfo = &g_stBT_FrameInfo;\r
+#else\r
+//const STGh3x2xFrameInfo * const  g_pstGh3x2xBT_FrameInfo = 0;\r
+#endif\r
+//RESP data info\r
+#if __USE_GOODIX_RESP_ALGORITHM__\r
+const STGh3x2xFrameInfo g_stRESP_FrameInfo =\r
+{\r
+    .unFunctionID = GH3X2X_FUNCTION_RESP,\r
+    .pstFunctionInfo = &g_st_RESP_FuncitonInfo,\r
+    .pstAlgoResult   = &g_stGh3x2xAlgoResult,\r
+    .uchFuntionChnlLimit = GH3X2X_RESP_CHNL_NUM,\r
+    .pchChnlMap = g_pch_RESP_ChnlMap,\r
+    .punFrameRawdata = g_punGh3x2xFrameRawdata,\r
+    .pusFrameGsensordata = g_psGh3x2xFrameGsensorData,\r
+    .pstFrameCapdata = &g_pstGh3x2xFrameCapData,\r
+    .pstFrameTempdata = &g_pstGh3x2xFrameTempData,\r
+    .punFrameAgcInfo = g_punGh3x2xFrameAgcInfo,\r
+    .punFrameFlag = g_punGh3x2xFrameFlag,\r
+    .pstAlgoRecordResult = 0,\r
+#if !__FUNC_RUN_SIMULTANEOUSLY_SUPPORT__\r
+    .punIncompleteRawdata = g_pun_MAIN_FUNC_FrameIncompleteRawdata,\r
+    .punIncompleteChnlMapBit = &g_un_MAIN_FUNC_FrameIncompleteChnlMapBit,\r
+    .puchFrameLastGain = g_puch_MAIN_FUNC_FrameLastGain,\r
+    .punFrameCnt = &g_un_MAIN_FUNC_TimeStamp,\r
+    .pstDownSampleInfo = &g_stGh3x2xDownSampleInfo_MAIN_FUNC,\r
+#else\r
+    .punIncompleteRawdata = g_pun_RESP_FrameIncompleteRawdata,\r
+    .punIncompleteChnlMapBit = &g_un_RESP_FrameIncompleteChnlMapBit,\r
+    .puchFrameLastGain = g_puch_RESP_FrameLastGain,\r
+    .punFrameCnt = &g_un_RESP_TimeStamp,\r
+    .pstDownSampleInfo = &g_stGh3x2xDownSampleInfo_RESP,\r
+#endif\r
+};\r
+//const STGh3x2xFrameInfo * const  g_pstGh3x2xRESP_FrameInfo = &g_stRESP_FrameInfo;\r
+#else\r
+//const STGh3x2xFrameInfo * const  g_pstGh3x2xRESP_FrameInfo = 0;\r
+#endif\r
+//AF data info\r
+#if  __USE_GOODIX_AF_ALGORITHM__\r
+const STGh3x2xFrameInfo g_stAF_FrameInfo =\r
+{\r
+    .unFunctionID = GH3X2X_FUNCTION_AF,\r
+    .pstFunctionInfo = &g_st_AF_FuncitonInfo,\r
+    .pstAlgoResult   = &g_stGh3x2xAlgoResult,\r
+    .uchFuntionChnlLimit = GH3X2X_AF_CHNL_NUM,\r
+    .pchChnlMap = g_pch_AF_ChnlMap,\r
+    .punFrameRawdata = g_punGh3x2xFrameRawdata,\r
+    .pusFrameGsensordata = g_psGh3x2xFrameGsensorData,\r
+    .pstFrameCapdata = &g_pstGh3x2xFrameCapData,\r
+    .pstFrameTempdata = &g_pstGh3x2xFrameTempData,\r
+    .punFrameAgcInfo = g_punGh3x2xFrameAgcInfo,\r
+    .punFrameFlag = g_punGh3x2xFrameFlag,\r
+    .pstAlgoRecordResult = 0,\r
+#if !__FUNC_RUN_SIMULTANEOUSLY_SUPPORT__\r
+    .punIncompleteRawdata = g_pun_MAIN_FUNC_FrameIncompleteRawdata,\r
+    .punIncompleteChnlMapBit = &g_un_MAIN_FUNC_FrameIncompleteChnlMapBit,\r
+    .puchFrameLastGain = g_puch_MAIN_FUNC_FrameLastGain,\r
+    .punFrameCnt = &g_un_MAIN_FUNC_TimeStamp,\r
+    .pstDownSampleInfo = &g_stGh3x2xDownSampleInfo_MAIN_FUNC,\r
+#else\r
+    .punIncompleteRawdata = g_pun_AF_FrameIncompleteRawdata,\r
+    .punIncompleteChnlMapBit = &g_un_AF_FrameIncompleteChnlMapBit,\r
+    .puchFrameLastGain = g_puch_AF_FrameLastGain,\r
+    .punFrameCnt = &g_un_AF_TimeStamp,\r
+    .pstDownSampleInfo = &g_stGh3x2xDownSampleInfo_AF,\r
+#endif\r
+};\r
+//const STGh3x2xFrameInfo * const  g_pstGh3x2xAF_FrameInfo = &g_stAF_FrameInfo;\r
+#else\r
+//const STGh3x2xFrameInfo * const  g_pstGh3x2xAF_FrameInfo = 0;\r
+#endif\r
+#if __USE_GOODIX_BP_ALGORITHM__\r
+const STGh3x2xFrameInfo g_stFPBP_FrameInfo =\r
+{\r
+    .unFunctionID = GH3X2X_FUNCTION_FPBP,\r
+    .pstFunctionInfo = &g_st_BP_FuncitonInfo,\r
+    .pstAlgoResult   = &g_stGh3x2xAlgoResult,\r
+    .uchFuntionChnlLimit = GH3X2X_BP_CHNL_NUM,\r
+    .pchChnlMap = g_pch_BP_ChnlMap,\r
+    .punFrameRawdata = g_punGh3x2xFrameRawdata,\r
+    .pusFrameGsensordata = g_psGh3x2xFrameGsensorData,\r
+    .pstFrameCapdata = &g_pstGh3x2xFrameCapData,\r
+    .pstFrameTempdata = &g_pstGh3x2xFrameTempData,\r
+    .punFrameAgcInfo = g_punGh3x2xFrameAgcInfo,\r
+    .punFrameFlag = g_punGh3x2xFrameFlag,\r
+    .pstAlgoRecordResult = 0,\r
+#if !__FUNC_RUN_SIMULTANEOUSLY_SUPPORT__\r
+    .punIncompleteRawdata = g_pun_MAIN_FUNC_FrameIncompleteRawdata,\r
+    .punIncompleteChnlMapBit = &g_un_MAIN_FUNC_FrameIncompleteChnlMapBit,\r
+    .puchFrameLastGain = g_puch_MAIN_FUNC_FrameLastGain,\r
+    .punFrameCnt = &g_un_MAIN_FUNC_TimeStamp,\r
+    .pstDownSampleInfo = &g_stGh3x2xDownSampleInfo_MAIN_FUNC,\r
+#else\r
+    .punIncompleteRawdata = g_pun_BP_FrameIncompleteRawdata,\r
+    .punIncompleteChnlMapBit = &g_un_BP_FrameIncompleteChnlMapBit,\r
+    .puchFrameLastGain = g_puch_BP_FrameLastGain,\r
+    .punFrameCnt = &g_un_BP_TimeStamp,\r
+    .pstDownSampleInfo = &g_stGh3x2xDownSampleInfo_BP,\r
+#endif\r
+};\r
+const STGh3x2xFrameInfo g_stPWA_FrameInfo =\r
+{\r
+    .unFunctionID = GH3X2X_FUNCTION_PWA,\r
+    .pstFunctionInfo = &g_st_BP_FuncitonInfo,\r
+    .pstAlgoResult   = &g_stGh3x2xAlgoResult,\r
+    .uchFuntionChnlLimit = GH3X2X_PWA_CHNL_NUM,\r
+    .pchChnlMap = g_pch_BP_ChnlMap,\r
+    .punFrameRawdata = g_punGh3x2xFrameRawdata,\r
+    .pusFrameGsensordata = g_psGh3x2xFrameGsensorData,\r
+    .pstFrameCapdata = &g_pstGh3x2xFrameCapData,\r
+    .pstFrameTempdata = &g_pstGh3x2xFrameTempData,\r
+    .punFrameAgcInfo = g_punGh3x2xFrameAgcInfo,\r
+    .punFrameFlag = g_punGh3x2xFrameFlag,\r
+    .pstAlgoRecordResult = 0,\r
+#if !__FUNC_RUN_SIMULTANEOUSLY_SUPPORT__\r
+    .punIncompleteRawdata = g_pun_MAIN_FUNC_FrameIncompleteRawdata,\r
+    .punIncompleteChnlMapBit = &g_un_MAIN_FUNC_FrameIncompleteChnlMapBit,\r
+    .puchFrameLastGain = g_puch_MAIN_FUNC_FrameLastGain,\r
+    .punFrameCnt = &g_un_MAIN_FUNC_TimeStamp,\r
+    .pstDownSampleInfo = &g_stGh3x2xDownSampleInfo_MAIN_FUNC,\r
+#else\r
+    .punIncompleteRawdata = g_pun_BP_FrameIncompleteRawdata,\r
+    .punIncompleteChnlMapBit = &g_un_BP_FrameIncompleteChnlMapBit,\r
+    .puchFrameLastGain = g_puch_BP_FrameLastGain,\r
+    .punFrameCnt = &g_un_BP_TimeStamp,\r
+    .pstDownSampleInfo = &g_stGh3x2xDownSampleInfo_BP,\r
+#endif\r
+};\r
+//const STGh3x2xFrameInfo * const  g_pstGh3x2xFPBP_FrameInfo = &g_stFPBP_FrameInfo;\r
+//const STGh3x2xFrameInfo * const  g_pstGh3x2xPWA_FrameInfo = &g_stPWA_FrameInfo;\r
+#else\r
+//const STGh3x2xFrameInfo * const  g_pstGh3x2xFPBP_FrameInfo = 0;\r
+//const STGh3x2xFrameInfo * const  g_pstGh3x2xPWA_FrameInfo = 0;\r
+#endif\r
+#if 0\r
+const STGh3x2xFrameInfo g_stTEST1_FrameInfo =\r
+{\r
+    .unFunctionID = GH3X2X_FUNCTION_TEST1,\r
+    .pstFunctionInfo = &g_st_TEST1_FuncitonInfo,\r
+    .pstAlgoResult   = &g_stGh3x2xAlgoResult,\r
+    .uchFuntionChnlLimit = GH3X2X_TEST_CHNL_NUM,\r
+    .pchChnlMap = g_pch_TEST1_ChnlMap,\r
+    .punFrameRawdata = g_punGh3x2xFrameRawdata,\r
+    .pusFrameGsensordata = g_psGh3x2xFrameGsensorData,\r
+    .pstFrameCapdata = &g_pstGh3x2xFrameCapData,\r
+    .pstFrameTempdata = &g_pstGh3x2xFrameTempData,\r
+    .punFrameAgcInfo = g_punGh3x2xFrameAgcInfo,\r
+    .punFrameFlag = g_punGh3x2xFrameFlag,\r
+    .pstAlgoRecordResult = 0,\r
+#if !__FUNC_RUN_SIMULTANEOUSLY_SUPPORT__\r
+    .punIncompleteRawdata = g_pun_MAIN_FUNC_FrameIncompleteRawdata,\r
+    .punIncompleteChnlMapBit = &g_un_MAIN_FUNC_FrameIncompleteChnlMapBit,\r
+    .puchFrameLastGain = g_puch_MAIN_FUNC_FrameLastGain,\r
+    .punFrameCnt = &g_un_MAIN_FUNC_TimeStamp,\r
+    .pstDownSampleInfo = &g_stGh3x2xDownSampleInfo_MAIN_FUNC,\r
+#else\r
+    .punIncompleteRawdata = g_pun_TEST1_FrameIncompleteRawdata,\r
+    .punIncompleteChnlMapBit = &g_un_TEST1_FrameIncompleteChnlMapBit,\r
+    .puchFrameLastGain = g_puch_TEST1_FrameLastGain,\r
+    .punFrameCnt = &g_un_TEST1_TimeStamp,\r
+    .pstDownSampleInfo = &g_stGh3x2xDownSampleInfo_TEST1,\r
+#endif\r
+};\r
+const STGh3x2xFrameInfo g_stTEST2_FrameInfo =\r
+{\r
+    .unFunctionID = GH3X2X_FUNCTION_TEST2,\r
+    .pstFunctionInfo = &g_st_TEST2_FuncitonInfo,\r
+    .pstAlgoResult   = &g_stGh3x2xAlgoResult,\r
+    .uchFuntionChnlLimit = GH3X2X_TEST_CHNL_NUM,\r
+    .pchChnlMap = g_pch_TEST2_ChnlMap,\r
+    .punFrameRawdata = g_punGh3x2xFrameRawdata,\r
+    .pusFrameGsensordata = g_psGh3x2xFrameGsensorData,\r
+    .pstFrameCapdata = &g_pstGh3x2xFrameCapData,\r
+    .pstFrameTempdata = &g_pstGh3x2xFrameTempData,\r
+    .punFrameAgcInfo = g_punGh3x2xFrameAgcInfo,\r
+    .punFrameFlag = g_punGh3x2xFrameFlag,\r
+    .pstAlgoRecordResult = 0,\r
+#if !__FUNC_RUN_SIMULTANEOUSLY_SUPPORT__\r
+    .punIncompleteRawdata = g_pun_MAIN_FUNC_FrameIncompleteRawdata,\r
+    .punIncompleteChnlMapBit = &g_un_MAIN_FUNC_FrameIncompleteChnlMapBit,\r
+    .puchFrameLastGain = g_puch_MAIN_FUNC_FrameLastGain,\r
+    .punFrameCnt = &g_un_MAIN_FUNC_TimeStamp,\r
+    .pstDownSampleInfo = &g_stGh3x2xDownSampleInfo_MAIN_FUNC,\r
+#else\r
+    .punIncompleteRawdata = g_pun_TEST2_FrameIncompleteRawdata,\r
+    .punIncompleteChnlMapBit = &g_un_TEST2_FrameIncompleteChnlMapBit,\r
+    .puchFrameLastGain = g_puch_TEST2_FrameLastGain,\r
+    .punFrameCnt = &g_un_TEST2_TimeStamp,\r
+    .pstDownSampleInfo = &g_stGh3x2xDownSampleInfo_TEST2,\r
+#endif\r
+};\r
+//const STGh3x2xFrameInfo * const  g_pstGh3x2xTEST1_FrameInfo = &g_stTEST1_FrameInfo;\r
+//const STGh3x2xFrameInfo * const  g_pstGh3x2xTEST2_FrameInfo = &g_stTEST2_FrameInfo;\r
+#else\r
+//const STGh3x2xFrameInfo * const  g_pstGh3x2xTEST1_FrameInfo = 0;\r
+//const STGh3x2xFrameInfo * const  g_pstGh3x2xTEST2_FrameInfo = 0;\r
+#endif\r
+//ADT data info\r
+#if __USE_GOODIX_ADT_ALGORITHM__\r
+const STGh3x2xFrameInfo g_stADT_FrameInfo = \r
+{\r
+    .unFunctionID = GH3X2X_FUNCTION_ADT,\r
+    .pstFunctionInfo = &g_st_ADT_FuncitonInfo,\r
+    .pstAlgoResult   = &g_stGh3x2xAlgoResult,\r
+    .uchFuntionChnlLimit = GH3X2X_ADT_CHNL_NUM,\r
+    .pchChnlMap = g_pch_ADT_ChnlMap,\r
+    .punFrameRawdata = g_punGh3x2xFrameRawdata,\r
+    .pusFrameGsensordata = g_psGh3x2xFrameGsensorData,\r
+    .pstFrameCapdata = &g_pstGh3x2xFrameCapData,\r
+    .pstFrameTempdata = &g_pstGh3x2xFrameTempData,\r
+    .punFrameAgcInfo = g_punGh3x2xFrameAgcInfo,\r
+    .punFrameFlag = g_punGh3x2xFrameFlag,\r
+    .punIncompleteRawdata = g_pun_ADT_FrameIncompleteRawdata,\r
+    .punIncompleteChnlMapBit = &g_un_ADT_FrameIncompleteChnlMapBit,\r
+    .puchFrameLastGain = g_puch_ADT_FrameLastGain,\r
+    .punFrameCnt = &g_un_ADT_TimeStamp,\r
+    .pstDownSampleInfo = &g_stGh3x2xDownSampleInfo_ADT,\r
+    .pstAlgoRecordResult = 0,\r
+};\r
+//const STGh3x2xFrameInfo * const  g_pstGh3x2xADT_FrameInfo = &g_stADT_FrameInfo;\r
+#else\r
+//const STGh3x2xFrameInfo * const  g_pstGh3x2xADT_FrameInfo = 0;\r
+#endif\r
+//SOFT ADT data info\r
+#if __USE_GOODIX_SOFT_ADT_ALGORITHM__\r
+const STGh3x2xFrameInfo g_stSOFT_ADT_GREEN_FrameInfo = \r
+{\r
+    .unFunctionID = GH3X2X_FUNCTION_SOFT_ADT_GREEN,\r
+    .pstFunctionInfo = &g_st_SOFT_ADT_GREEN_FuncitonInfo,\r
+    .pstAlgoResult   = &g_stGh3x2xAlgoResult,\r
+    .uchFuntionChnlLimit = GH3X2X_SOFT_ADT_CHNL_NUM,\r
+    .pchChnlMap = g_pch_SOFT_ADT_GREEN_ChnlMap,\r
+    .punFrameRawdata = g_punGh3x2xFrameRawdata,\r
+    .pusFrameGsensordata = g_psGh3x2xFrameGsensorData,\r
+    .pstFrameCapdata = &g_pstGh3x2xFrameCapData,\r
+    .pstFrameTempdata = &g_pstGh3x2xFrameTempData,\r
+    .punFrameAgcInfo = g_punGh3x2xFrameAgcInfo,\r
+    .punFrameFlag = g_punGh3x2xFrameFlag,\r
+    .punIncompleteRawdata = g_pun_SOFT_ADT_GREEN_FrameIncompleteRawdata,\r
+    .punIncompleteChnlMapBit = &g_un_SOFT_ADT_GREEN_FrameIncompleteChnlMapBit,\r
+    .puchFrameLastGain = g_puch_SOFT_ADT_GREEN_FrameLastGain,\r
+    .punFrameCnt = &g_un_SOFT_ADT_GREEN_TimeStamp,\r
+    .pstDownSampleInfo = &g_stGh3x2xDownSampleInfo_SOFT_ADT_GREEN,\r
+    .pstAlgoRecordResult = 0,\r
+};\r
+//const STGh3x2xFrameInfo * const  g_pstGh3x2xSOFT_ADT_GREEN_FrameInfo = &g_stSOFT_ADT_GREEN_FrameInfo;\r
+#else\r
+//const STGh3x2xFrameInfo * const  g_pstGh3x2xSOFT_ADT_GREEN_FrameInfo = 0;\r
+#endif\r
+#if __USE_GOODIX_SOFT_ADT_ALGORITHM__\r
+const STGh3x2xFrameInfo g_stSOFT_ADT_IR_FrameInfo = \r
+{\r
+    .unFunctionID = GH3X2X_FUNCTION_SOFT_ADT_IR,\r
+    .pstFunctionInfo = &g_st_SOFT_ADT_IR_FuncitonInfo,\r
+    .pstAlgoResult   = &g_stGh3x2xAlgoResult,\r
+    .uchFuntionChnlLimit = GH3X2X_SOFT_ADT_CHNL_NUM,\r
+    .pchChnlMap = g_pch_SOFT_ADT_IR_ChnlMap,\r
+    .punFrameRawdata = g_punGh3x2xFrameRawdata,\r
+    .pusFrameGsensordata = g_psGh3x2xFrameGsensorData,\r
+    .pstFrameCapdata = &g_pstGh3x2xFrameCapData,\r
+    .pstFrameTempdata = &g_pstGh3x2xFrameTempData,\r
+    .punFrameAgcInfo = g_punGh3x2xFrameAgcInfo,\r
+    .punFrameFlag = g_punGh3x2xFrameFlag,\r
+    .punIncompleteRawdata = g_pun_SOFT_ADT_GREEN_FrameIncompleteRawdata,\r
+    .punIncompleteChnlMapBit = &g_un_SOFT_ADT_GREEN_FrameIncompleteChnlMapBit,\r
+    .puchFrameLastGain = g_puch_SOFT_ADT_GREEN_FrameLastGain,\r
+    .punFrameCnt = &g_un_SOFT_ADT_GREEN_TimeStamp,\r
+    .pstDownSampleInfo = &g_stGh3x2xDownSampleInfo_SOFT_ADT_GREEN,\r
+    .pstAlgoRecordResult = 0,\r
+};\r
+//const STGh3x2xFrameInfo * const  g_pstGh3x2xSOFT_ADT_IR_FrameInfo = &g_stSOFT_ADT_IR_FrameInfo;\r
+#else\r
+//const STGh3x2xFrameInfo * const  g_pstGh3x2xSOFT_ADT_IR_FrameInfo = 0;\r
+#endif\r
+\r
+\r
+//Function data info struct\r
+const STGh3x2xFrameInfo * const  g_pstGh3x2xFrameInfo[GH3X2X_FUNC_OFFSET_MAX] = \r
+{\r
+//adt\r
+#if __USE_GOODIX_ADT_ALGORITHM__\r
+    &g_stADT_FrameInfo,\r
+#else\r
+    0,\r
+#endif\r
+//hr\r
+#if __USE_GOODIX_HR_ALGORITHM__\r
+    &g_stHR_FrameInfo,\r
+#else\r
+    0,\r
+#endif\r
+//hrv\r
+#if __USE_GOODIX_HRV_ALGORITHM__\r
+    &g_stHRV_FrameInfo,\r
+#else\r
+    0,\r
+#endif\r
+//hsm\r
+#if __USE_GOODIX_HSM_ALGORITHM__\r
+    &g_stHSM_FrameInfo,\r
+#else\r
+    0,\r
+#endif\r
+//fpbp\r
+//pwa\r
+#if __USE_GOODIX_BP_ALGORITHM__\r
+    &g_stFPBP_FrameInfo,\r
+    &g_stPWA_FrameInfo,\r
+#else\r
+    0,\r
+    0,\r
+#endif   \r
+//spo2\r
+#if __USE_GOODIX_SPO2_ALGORITHM__\r
+    &g_stSPO2_FrameInfo,\r
+#else\r
+    0,\r
+#endif\r
+//ecg\r
+#if __USE_GOODIX_ECG_ALGORITHM__\r
+    &g_stECG_FrameInfo,\r
+#else\r
+    0,\r
+#endif\r
+//pwtt\r
+#if 0\r
+    &g_stPWTT_FrameInfo,\r
+#else\r
+    0,\r
+#endif\r
+//soft adt green\r
+#if __USE_GOODIX_SOFT_ADT_ALGORITHM__\r
+    &g_stSOFT_ADT_GREEN_FrameInfo,\r
+#else\r
+    0,\r
+#endif\r
+//bt\r
+#if __USE_GOODIX_BT_ALGORITHM__\r
+    &g_stBT_FrameInfo,\r
+#else\r
+    0,\r
+#endif\r
+//resp\r
+#if __USE_GOODIX_RESP_ALGORITHM__\r
+    &g_stRESP_FrameInfo,\r
+#else\r
+    0,\r
+#endif\r
+//af\r
+#if  __USE_GOODIX_AF_ALGORITHM__\r
+    &g_stAF_FrameInfo,\r
+#else\r
+    0,\r
+#endif\r
+#if 0\r
+    &g_stTEST1_FrameInfo,\r
+    &g_stTEST2_FrameInfo,\r
+#else\r
+    0,\r
+    0,\r
+#endif\r
+//soft adt ir\r
+#if __USE_GOODIX_SOFT_ADT_ALGORITHM__\r
+    &g_stSOFT_ADT_IR_FrameInfo,\r
+#else\r
+    0,\r
+#endif\r
+    0, //GH3X2X_FUNCTION_RS0\r
+    0, //GH3X2X_FUNCTION_RS1\r
+    0, //GH3X2X_FUNCTION_RS2\r
+    0, //GH3X2X_FUNCTION_LEAD_DET\r
+};\r
+\r
+\r
+\r
+#endif\r
+\r
+\r
+/********END OF FILE********* Copyright (c) 2003 - 2022, Goodix Co., Ltd. ********/\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_application/src/gh3x2x_demo_algo_hook.c b/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_application/src/gh3x2x_demo_algo_hook.c
new file mode 100644 (file)
index 0000000..6deef95
--- /dev/null
@@ -0,0 +1,263 @@
+#include <stdio.h>\r
+#include "gh3x2x_demo_common.h"\r
+#include "gh3x2x_demo_algo_call.h"\r
+#include "gh3x2x_demo_algo_config.h"\r
+#include "gh3x2x_demo_algo_hook.h"\r
+\r
+#if (__GOODIX_ALGO_CALL_MODE__)\r
+\r
+/**\r
+ * @fn     void GH3X2X_AlgoLog(char *log_string)\r
+ * \r
+ * @brief  for debug version, log\r
+ *\r
+ * @attention   this function must define that use debug version lib\r
+ *\r
+ * @param[in]   log_string      pointer to log string\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+\r
+void GH3X2X_AlgoLog(GCHAR *log_string)\r
+{\r
+    GOODIX_PLATFORM_LOG_ENTITY();\r
+}\r
+\r
+/**\r
+ * @fn     void GH3X2X_AdtAlgorithmResultReport(STHbAlgoResult stHbAlgoRes[], GU16 pusAlgoResIndexArr[], usAlgoResCnt)\r
+ *\r
+ * @brief  This function will be called after calculate hb algorithm.\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   stHbAlgoRes             hb algorithm result array\r
+ * @param[in]   pusAlgoResIndexArr      frame index of every algo result\r
+ * @param[in]   usAlgoResCnt            number of algo result\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_AdtAlgorithmResultReport(STGh3x2xAlgoResult * pstAlgoResult, GU32 lubFrameId)\r
+{\r
+#if (__USE_GOODIX_ADT_ALGORITHM__)\r
+    if (pstAlgoResult->uchUpdateFlag)\r
+    {\r
+        if (pstAlgoResult->snResult[0] == 1)     //wear on\r
+        {\r
+            #if __GH_MSG_WTIH_DRV_LAYER_EN__\r
+            GH_SEND_MSG_WEAR_EVENT(GH3X2X_SOFT_EVENT_WEAR_ON_ALGO_ADT);\r
+            #else\r
+            GH3X2X_ClearSoftEvent(GH3X2X_SOFT_EVENT_WEAR_OFF_ALGO_ADT);\r
+            GH3X2X_SetSoftEvent(GH3X2X_SOFT_EVENT_WEAR_ON_ALGO_ADT);\r
+            #endif\r
+            /* code implement by user */\r
+        }\r
+        else if (pstAlgoResult->snResult[0] == 2)   //wear off\r
+        {\r
+            #if __GH_MSG_WTIH_DRV_LAYER_EN__\r
+            GH_SEND_MSG_WEAR_EVENT(GH3X2X_SOFT_EVENT_WEAR_OFF_ALGO_ADT);\r
+            #else\r
+            GH3X2X_ClearSoftEvent(GH3X2X_SOFT_EVENT_WEAR_ON_ALGO_ADT);\r
+            GH3X2X_SetSoftEvent(GH3X2X_SOFT_EVENT_WEAR_OFF_ALGO_ADT);\r
+            #endif\r
+            /* code implement by user */\r
+        }\r
+    }\r
+#endif\r
+}\r
+\r
+/**\r
+ * @fn     void GH3X2X_HrAlgorithmResultReport(STHbAlgoResult stHbAlgoRes[], GU16 pusAlgoResIndexArr[], usAlgoResCnt)\r
+ *\r
+ * @brief  This function will be called after calculate hb algorithm.\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   stHbAlgoRes             hb algorithm result array\r
+ * @param[in]   pusAlgoResIndexArr      frame index of every algo result\r
+ * @param[in]   usAlgoResCnt            number of algo result\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_HrAlgorithmResultReport(STGh3x2xAlgoResult * pstAlgoResult, GU32 lubFrameId)\r
+{\r
+#if (__USE_GOODIX_HR_ALGORITHM__)\r
+    /* code implement by user */\r
+    //GOODIX_PLATFORM_HR_RESULT_REPORT_ENTITY();\r
+#endif\r
+}\r
+\r
+/**\r
+ * @fn     void GH3X2X_Spo2AlgorithmResultReport(STGh3x2xAlgoResult * pstAlgoResult)\r
+ *\r
+ *\r
+ * @brief  This function will be called after calculate spo2 algorithm.\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   stSpo2AlgoRes           spo2 algorithm result array\r
+ * @param[in]   pusAlgoResIndexArr      frame index of every algo result\r
+ * @param[in]   usAlgoResCnt            number of algo result\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_Spo2AlgorithmResultReport(STGh3x2xAlgoResult * pstAlgoResult, GU32 lubFrameId)\r
+{\r
+#if (__USE_GOODIX_SPO2_ALGORITHM__)\r
+\r
+    /* code implement by user */\r
+    //GOODIX_PLATFORM_SPO2_RESULT_REPORT_ENTITY();\r
+#endif\r
+}\r
+\r
+/**\r
+ * @fn     void GH3X2X_HrvAlgorithmResultReport(STHrvAlgoResult stHrvAlgoRes[], GU16 pusAlgoResIndexArr[], usAlgoResCnt)\r
+ *\r
+ * @brief  This function will be called after calculate hrv algorithm.\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   stHrvAlgoRes            hrv algorithm result array\r
+ * @param[in]   pusAlgoResIndexArr      frame index of every algo result\r
+ * @param[in]   usAlgoResCnt            number of algo result\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_HrvAlgorithmResultReport(STGh3x2xAlgoResult * pstAlgoResult, GU32 lubFrameId)\r
+{\r
+#if (__USE_GOODIX_HRV_ALGORITHM__)\r
+    /* code implement by user */\r
+    //SLAVER_LOG("snHrvOut0=%d,snHrvOut1=%d,snHrvOut2=%d,snHrvOut3=%d,snHrvNum=%d,snHrvConfi=%d\r\n",\r
+    //          stHrvAlgoRes[0].snHrvOut0,stHrvAlgoRes[0].snHrvOut1,stHrvAlgoRes[0].snHrvOut2,stHrvAlgoRes[0].snHrvOut3,stHrvAlgoRes[0].snHrvNum,stHrvAlgoRes[0].snHrvNum);\r
+    //GOODIX_PLATFORM_HRV_RESULT_REPORT_ENTITY();\r
+#endif\r
+}\r
+\r
+/**\r
+ * @fn     void GH3X2X_EcgAlgorithmResultReport(STEcgAlgoResult stEcgAlgoRes[], GU16 pusAlgoResIndexArr[], usAlgoResCnt)\r
+ *\r
+ * @brief  This function will be called after calculate ecg algorithm.\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   stEcgAlgoRes            ecg algorithm result array\r
+ * @param[in]   pusAlgoResIndexArr      frame index of every algo result\r
+ * @param[in]   usAlgoResCnt            number of algo result\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_EcgAlgorithmResultReport(STGh3x2xAlgoResult * pstAlgoResult, GU32 lubFrameId)\r
+{\r
+#if (__USE_GOODIX_ECG_ALGORITHM__)\r
+    /* code implement by user */\r
+    //GOODIX_PLATFORM_ECG_RESULT_REPORT_ENTITY();\r
+#endif\r
+}\r
+\r
+/**\r
+ * @fn     void GH3X2X_SoftAdtGreenAlgorithmResultReport(STGh3x2xAlgoResult * pstAlgoResult, GU32 lubFrameId)\r
+ *\r
+ * @brief  This function will be called after calculate ecg algorithm.\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   stEcgAlgoRes            ecg algorithm result array\r
+ * @param[in]   pusAlgoResIndexArr      frame index of every algo result\r
+ * @param[in]   usAlgoResCnt            number of algo result\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+\r
+GU8 g_SoftAdtWearState = GH3X2X_SOFT_ALGO_ADT_DEFAULT; // 0:default 1: wear on  1: wear off\r
+void GH3X2X_SoftAdtGreenAlgorithmResultReport(STGh3x2xAlgoResult * pstAlgoResult, GU32 lubFrameId)\r
+{\r
+#if (__USE_GOODIX_SOFT_ADT_ALGORITHM__)\r
+    GH3X2X_DEBUG_ALGO_LOG("[%s]:result = %d,%d\r\n", __FUNCTION__, pstAlgoResult->snResult[0], pstAlgoResult->snResult[1]);\r
+    //live object\r
+    if (pstAlgoResult->snResult[0] == 0x1 && g_SoftAdtWearState != GH3X2X_SOFT_ALGO_ADT_WEAR_ON)\r
+    {\r
+       GH3X2X_DEBUG_ALGO_LOG("[%s]:get algo wear on event\r\n", __FUNCTION__);\r
+       #if __GH_MSG_WTIH_DRV_LAYER_EN__\r
+       GH_SEND_MSG_WEAR_EVENT(GH3X2X_SOFT_EVENT_WEAR_ON);\r
+       #else\r
+       GH3X2X_ClearSoftEvent(GH3X2X_SOFT_EVENT_WEAR_OFF);\r
+       GH3X2X_SetSoftEvent(GH3X2X_SOFT_EVENT_WEAR_ON);\r
+       #endif\r
+       g_SoftAdtWearState = GH3X2X_SOFT_ALGO_ADT_WEAR_ON;\r
+        /* code implement by user */\r
+    }\r
+    //non live object\r
+    else if ((pstAlgoResult->snResult[0] & 0x2) && g_SoftAdtWearState != GH3X2X_SOFT_ALGO_ADT_WEAR_OFF)\r
+    {\r
+       GH3X2X_DEBUG_ALGO_LOG("[%s]:get algo wear off event\r\n", __FUNCTION__);\r
+        #if __GH_MSG_WTIH_DRV_LAYER_EN__\r
+       GH_SEND_MSG_WEAR_EVENT(GH3X2X_SOFT_EVENT_WEAR_OFF);\r
+       #else\r
+       GH3X2X_ClearSoftEvent(GH3X2X_SOFT_EVENT_WEAR_ON);\r
+       GH3X2X_SetSoftEvent(GH3X2X_SOFT_EVENT_WEAR_OFF);\r
+       #endif\r
+       g_SoftAdtWearState = GH3X2X_SOFT_ALGO_ADT_WEAR_OFF;\r
+        /* code implement by user */\r
+    }\r
+    GOODIX_PLATFORM_NADT_RESULT_HANDLE_ENTITY();\r
+#endif\r
+}\r
+\r
+/**\r
+ * @fn     void GH3X2X_SoftAdtIrAlgorithmResultReport(STGh3x2xAlgoResult * pstAlgoResult, GU32 lubFrameId)\r
+ *\r
+ * @brief  This function will be called after calculate ecg algorithm.\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   stEcgAlgoRes            ecg algorithm result array\r
+ * @param[in]   pusAlgoResIndexArr      frame index of every algo result\r
+ * @param[in]   usAlgoResCnt            number of algo result\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_SoftAdtIrAlgorithmResultReport(STGh3x2xAlgoResult * pstAlgoResult, GU32 lubFrameId)\r
+{\r
+#if (__USE_GOODIX_SOFT_ADT_ALGORITHM__)\r
+    GH3X2X_DEBUG_ALGO_LOG("[%s]:result = %d,%d\r\n", __FUNCTION__, pstAlgoResult->snResult[0], pstAlgoResult->snResult[1]);\r
+    //live object\r
+    if (pstAlgoResult->snResult[0] == 0x1 && g_SoftAdtWearState != GH3X2X_SOFT_ALGO_ADT_WEAR_ON)\r
+    {\r
+       GH3X2X_DEBUG_ALGO_LOG("[%s]:get algo wear on event\r\n", __FUNCTION__);\r
+        //Gh3x2xDemoStopSampling(GH3X2X_FUNCTION_SOFT_ADT_IR);\r
+        //Gh3x2xDemoStartSampling(GH3X2X_FUNCTION_SOFT_ADT_GREEN|GH3X2X_FUNCTION_HR);\r
+       #if __GH_MSG_WTIH_DRV_LAYER_EN__\r
+       GH_SEND_MSG_WEAR_EVENT(GH3X2X_SOFT_EVENT_WEAR_ON);\r
+       #else\r
+       GH3X2X_ClearSoftEvent(GH3X2X_SOFT_EVENT_WEAR_OFF);\r
+       GH3X2X_SetSoftEvent(GH3X2X_SOFT_EVENT_WEAR_ON);\r
+       #endif\r
+       g_SoftAdtWearState = GH3X2X_SOFT_ALGO_ADT_WEAR_ON;\r
+        /* code implement by user */\r
+    }\r
+    //non live object\r
+    else if ((pstAlgoResult->snResult[0] & 0x2) && g_SoftAdtWearState != GH3X2X_SOFT_ALGO_ADT_WEAR_OFF)\r
+    {\r
+       GH3X2X_DEBUG_ALGO_LOG("[%s]:get algo wear off event\r\n", __FUNCTION__);\r
+       #if __GH_MSG_WTIH_DRV_LAYER_EN__\r
+       GH_SEND_MSG_WEAR_EVENT(GH3X2X_SOFT_EVENT_WEAR_OFF);\r
+       #else\r
+       GH3X2X_ClearSoftEvent(GH3X2X_SOFT_EVENT_WEAR_ON);\r
+       GH3X2X_SetSoftEvent(GH3X2X_SOFT_EVENT_WEAR_OFF);\r
+       #endif\r
+       g_SoftAdtWearState = GH3X2X_SOFT_ALGO_ADT_WEAR_OFF;\r
+        /* code implement by user */\r
+    }\r
+    GOODIX_PLATFORM_NADT_RESULT_HANDLE_ENTITY();\r
+#endif\r
+}\r
+\r
+#endif // end else #if (__DRIVER_LIB_MODE__==__DRV_LIB_WITHOUT_ALGO__)\r
+\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_application/src/gh3x2x_demo_algo_memory.c b/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_application/src/gh3x2x_demo_algo_memory.c
new file mode 100644 (file)
index 0000000..5524f32
--- /dev/null
@@ -0,0 +1,334 @@
+/**\r
+ * @copyright (c) 2003 - 2022, Goodix Co., Ltd. All rights reserved.\r
+ * \r
+ * @file    gh3x2x_demo_algorithm.c\r
+ * \r
+ * @brief   gh3x2x driver lib demo code for algorithm\r
+ * \r
+ * @author  Gooidx Iot Team\r
+ * \r
+ */\r
+#include "gh3x2x_demo_algo_call.h"\r
+#include "gh3x2x_demo_algo_memory.h"\r
+#include "gh3x2x_demo_algo_config.h"\r
+#include "gh3x2x_demo_algorithm_calc.h"\r
+#include "goodix_algo.h"\r
+#include "goodix_mem.h"\r
+\r
+#if (__GOODIX_ALGO_CALL_MODE__)\r
+#if __USER_DYNAMIC_ALGO_MEM_EN__\r
+GU32 *g_punGh3x2xAlgoMemBufferPointer = GH3X2X_ALGORITHMS_MEMORY_SIZE_USERSET;\r
+#else\r
+GU32 g_punGh3x2xAlgoMemBuffer[GH3X2X_ALGORITHMS_MEMORY_SIZE_FINAL/4] = {0};\r
+GU32 *g_punGh3x2xAlgoMemBufferPointer = g_punGh3x2xAlgoMemBuffer;\r
+#endif\r
+#else  //without algorithm\r
+GU32 *g_punGh3x2xAlgoMemBufferPointer = 0;\r
+#endif\r
+\r
+void GH3X2X_MemFree(void* mem_addr)\r
+{\r
+    goodix_mem_free(mem_addr);\r
+}\r
+\r
+void* GH3X2X_MemMalloc(GS32 nSize)\r
+{\r
+    return goodix_mem_malloc(nSize);\r
+}\r
+\r
+void Gh3x2xPoolIsNotEnough(void)\r
+{\r
+    while(1)\r
+    {\r
+        GH3X2X_DEBUG_ALGO_LOG("MEMORY ERROR!!!PLEASE RESET HARDWARE!!!\n");\r
+    }\r
+}\r
+\r
+#if (__GOODIX_ALGO_CALL_MODE__)\r
+\r
+#if __GH3X2X_MEM_POOL_CHECK_EN__\r
+\r
+const GU32 g_unGh3z2xMemCheckAreaStart[17] =\r
+{\r
+    0,\r
+    GH3X2X_ALGORITHMS_MEMORY_SIZE_FINAL*1/16,\r
+    GH3X2X_ALGORITHMS_MEMORY_SIZE_FINAL*2/16,\r
+    GH3X2X_ALGORITHMS_MEMORY_SIZE_FINAL*3/16,\r
+    GH3X2X_ALGORITHMS_MEMORY_SIZE_FINAL*4/16,\r
+    GH3X2X_ALGORITHMS_MEMORY_SIZE_FINAL*5/16,\r
+    GH3X2X_ALGORITHMS_MEMORY_SIZE_FINAL*6/16,\r
+    GH3X2X_ALGORITHMS_MEMORY_SIZE_FINAL*7/16,\r
+    GH3X2X_ALGORITHMS_MEMORY_SIZE_FINAL*8/16,\r
+    GH3X2X_ALGORITHMS_MEMORY_SIZE_FINAL*9/16,\r
+    GH3X2X_ALGORITHMS_MEMORY_SIZE_FINAL*10/16,\r
+    GH3X2X_ALGORITHMS_MEMORY_SIZE_FINAL*11/16,\r
+    GH3X2X_ALGORITHMS_MEMORY_SIZE_FINAL*12/16,\r
+    GH3X2X_ALGORITHMS_MEMORY_SIZE_FINAL*13/16,\r
+    GH3X2X_ALGORITHMS_MEMORY_SIZE_FINAL*14/16,\r
+    GH3X2X_ALGORITHMS_MEMORY_SIZE_FINAL*15/16,\r
+    GH3X2X_ALGORITHMS_MEMORY_SIZE_FINAL,\r
+};\r
+\r
+GU32 g_unGh3x2xLastMemPoolCheckSumArea[16];\r
+\r
+\r
+\r
+GU8  g_uchGh3x2xMemPollHaveGetCheckSum = 0;\r
+GU16 g_usGh3x2xMemPollErrorFlag = 0;\r
+GU32 Gh3x2xGetMemPoolCheckSum(GU8 *lunMemPool, GU32 lunByteSize)\r
+{\r
+    GU32 lunCheckSum = 0;\r
+    for(GU32 lunByteCnt = 0; lunByteCnt < lunByteSize; lunByteCnt += 4)\r
+    {\r
+        lunCheckSum += *((GU32*)(lunMemPool+lunByteCnt));\r
+    }\r
+    \r
+    return lunCheckSum;\r
+}\r
+\r
+\r
+void Gh3x2xMemPoolCheckSumWrite(GU8 *lunMemPool)\r
+{\r
+    for(GU8 uchAreaCnt = 0; uchAreaCnt < 16; uchAreaCnt ++)\r
+    {\r
+        g_unGh3x2xLastMemPoolCheckSumArea[uchAreaCnt] = Gh3x2xGetMemPoolCheckSum(lunMemPool + ((g_unGh3z2xMemCheckAreaStart[uchAreaCnt]/4)*4), (g_unGh3z2xMemCheckAreaStart[uchAreaCnt + 1]/4)*4 - (g_unGh3z2xMemCheckAreaStart[uchAreaCnt]/4)*4);\r
+    }\r
+    g_uchGh3x2xMemPollHaveGetCheckSum = 1;\r
+}\r
+\r
+\r
+GU16 Gh3x2xMemPoolCheckSumCheck(GU8 *lunMemPool)\r
+{\r
+    GU16 usErrorFlag = 0;\r
+\r
+    if(0 == g_usGh3x2xMemPollErrorFlag)\r
+    {\r
+        for(GU8 uchAreaCnt = 0; uchAreaCnt < 16; uchAreaCnt ++)\r
+        {\r
+            if(g_unGh3x2xLastMemPoolCheckSumArea[uchAreaCnt] != Gh3x2xGetMemPoolCheckSum(lunMemPool + ((g_unGh3z2xMemCheckAreaStart[uchAreaCnt]/4)*4), (g_unGh3z2xMemCheckAreaStart[uchAreaCnt + 1]/4)*4 - (g_unGh3z2xMemCheckAreaStart[uchAreaCnt]/4)*4))\r
+            {\r
+                usErrorFlag |= (((GU16)1) << uchAreaCnt);\r
+            }\r
+        }\r
+    }\r
+\r
+    g_usGh3x2xMemPollErrorFlag = usErrorFlag;\r
+    return usErrorFlag;\r
+}\r
+\r
+\r
+void Gh3x2xCheckMemPollBeforeAlgoCal(void)\r
+{\r
+    if(g_uchGh3x2xMemPollHaveGetCheckSum)\r
+    {\r
+        if(Gh3x2xMemPoolCheckSumCheck((GU8*)g_punGh3x2xAlgoMemBufferPointer))\r
+        {\r
+            GH3X2X_DEBUG_ALGO_LOG("Gh3x2x mem check error!!!  error flag = 0x%X\r\n", g_usGh3x2xMemPollErrorFlag);\r
+            while(1);  //error !!!  mem pool is be destroy\r
+        }\r
+        GH3X2X_DEBUG_ALGO_LOG("Gh3x2x mem check ok, check sum 0  = 0x%X\r\n",g_unGh3x2xLastMemPoolCheckSumArea[0]);\r
+        GH3X2X_DEBUG_ALGO_LOG("Gh3x2x mem check ok, check sum 1  = 0x%X\r\n",g_unGh3x2xLastMemPoolCheckSumArea[1]);\r
+        GH3X2X_DEBUG_ALGO_LOG("Gh3x2x mem check ok, check sum 2  = 0x%X\r\n",g_unGh3x2xLastMemPoolCheckSumArea[2]);\r
+        GH3X2X_DEBUG_ALGO_LOG("Gh3x2x mem check ok, check sum 3  = 0x%X\r\n",g_unGh3x2xLastMemPoolCheckSumArea[3]);\r
+        GH3X2X_DEBUG_ALGO_LOG("Gh3x2x mem check ok, check sum 4  = 0x%X\r\n",g_unGh3x2xLastMemPoolCheckSumArea[4]);\r
+        GH3X2X_DEBUG_ALGO_LOG("Gh3x2x mem check ok, check sum 5  = 0x%X\r\n",g_unGh3x2xLastMemPoolCheckSumArea[5]);\r
+        GH3X2X_DEBUG_ALGO_LOG("Gh3x2x mem check ok, check sum 6  = 0x%X\r\n",g_unGh3x2xLastMemPoolCheckSumArea[6]);\r
+        GH3X2X_DEBUG_ALGO_LOG("Gh3x2x mem check ok, check sum 7  = 0x%X\r\n",g_unGh3x2xLastMemPoolCheckSumArea[7]);\r
+        GH3X2X_DEBUG_ALGO_LOG("Gh3x2x mem check ok, check sum 8  = 0x%X\r\n",g_unGh3x2xLastMemPoolCheckSumArea[8]);\r
+        GH3X2X_DEBUG_ALGO_LOG("Gh3x2x mem check ok, check sum 9  = 0x%X\r\n",g_unGh3x2xLastMemPoolCheckSumArea[9]);\r
+        GH3X2X_DEBUG_ALGO_LOG("Gh3x2x mem check ok, check sum 10  = 0x%X\r\n",g_unGh3x2xLastMemPoolCheckSumArea[10]);\r
+        GH3X2X_DEBUG_ALGO_LOG("Gh3x2x mem check ok, check sum 11  = 0x%X\r\n",g_unGh3x2xLastMemPoolCheckSumArea[11]);\r
+        GH3X2X_DEBUG_ALGO_LOG("Gh3x2x mem check ok, check sum 12  = 0x%X\r\n",g_unGh3x2xLastMemPoolCheckSumArea[12]);\r
+        GH3X2X_DEBUG_ALGO_LOG("Gh3x2x mem check ok, check sum 13  = 0x%X\r\n",g_unGh3x2xLastMemPoolCheckSumArea[13]);\r
+        GH3X2X_DEBUG_ALGO_LOG("Gh3x2x mem check ok, check sum 14  = 0x%X\r\n",g_unGh3x2xLastMemPoolCheckSumArea[14]);\r
+        GH3X2X_DEBUG_ALGO_LOG("Gh3x2x mem check ok, check sum 15  = 0x%X\r\n",g_unGh3x2xLastMemPoolCheckSumArea[15]);\r
+    }\r
+            \r
+}\r
+\r
+void Gh3x2xUpdataMemPollChkSumAfterAlgoCal(void)\r
+{\r
+    \r
+    Gh3x2xMemPoolCheckSumWrite((GU8*)g_punGh3x2xAlgoMemBufferPointer);\r
+    \r
+\r
+    //g_punGh3x2xAlgoMemBuffer[(GH3X2X_ALGORITHMS_MEMORY_SIZE_FINAL*1/16)/4 - 1] = 0x3333;   //test\r
+    //g_punGh3x2xAlgoMemBuffer[(GH3X2X_ALGORITHMS_MEMORY_SIZE_FINAL*2/16)/4 - 1] = 0x3333;   //test\r
+    //g_punGh3x2xAlgoMemBuffer[(GH3X2X_ALGORITHMS_MEMORY_SIZE_FINAL*3/16)/4 - 1] = 0x3333;   //test\r
+    //g_punGh3x2xAlgoMemBuffer[(GH3X2X_ALGORITHMS_MEMORY_SIZE_FINAL*4/16)/4 - 1] = 0x3333;   //test\r
+    //g_punGh3x2xAlgoMemBuffer[(GH3X2X_ALGORITHMS_MEMORY_SIZE_FINAL*5/16)/4 - 1] = 0x3333;   //test\r
+    //g_punGh3x2xAlgoMemBuffer[(GH3X2X_ALGORITHMS_MEMORY_SIZE_FINAL*6/16)/4 - 1] = 0x3333;   //test\r
+    //g_punGh3x2xAlgoMemBuffer[(GH3X2X_ALGORITHMS_MEMORY_SIZE_FINAL*7/16)/4 - 1] = 0x3333;   //test\r
+    //g_punGh3x2xAlgoMemBuffer[(GH3X2X_ALGORITHMS_MEMORY_SIZE_FINAL*8/16)/4 - 1] = 0x3333;   //test\r
+    //g_punGh3x2xAlgoMemBuffer[(GH3X2X_ALGORITHMS_MEMORY_SIZE_FINAL*9/16)/4 - 1] = 0x3333;   //test\r
+    //g_punGh3x2xAlgoMemBuffer[(GH3X2X_ALGORITHMS_MEMORY_SIZE_FINAL*10/16)/4 - 1] = 0x3333;   //test\r
+    //g_punGh3x2xAlgoMemBuffer[(GH3X2X_ALGORITHMS_MEMORY_SIZE_FINAL*11/16)/4 - 1] = 0x3333;   //test\r
+    //g_punGh3x2xAlgoMemBuffer[(GH3X2X_ALGORITHMS_MEMORY_SIZE_FINAL*12/16)/4 - 1] = 0x3333;   //test\r
+    //g_punGh3x2xAlgoMemBuffer[(GH3X2X_ALGORITHMS_MEMORY_SIZE_FINAL*13/16)/4 - 1] = 0x3333;   //test\r
+    //g_punGh3x2xAlgoMemBuffer[(GH3X2X_ALGORITHMS_MEMORY_SIZE_FINAL*14/16)/4 - 1] = 0x3333;   //test\r
+    //g_punGh3x2xAlgoMemBuffer[(GH3X2X_ALGORITHMS_MEMORY_SIZE_FINAL*15/16)/4 - 1] = 0x3333;   //test\r
+    //g_punGh3x2xAlgoMemBuffer[(GH3X2X_ALGORITHMS_MEMORY_SIZE_FINAL*16/16)/4 - 1] = 0x3333;   //test\r
+            \r
+}\r
+#endif\r
+\r
+\r
+\r
+#if __USER_DYNAMIC_ALGO_MEM_EN__\r
+void* Gh3x2xAlgoMemApply(GU32 unMemSize)\r
+{\r
+    return Gh3x2xMallocUser(unMemSize)\r
+}\r
+\r
+void Gh3x2xAlgoMemFree(void* MemAddr)\r
+{\r
+    Gh3x2xFreeUser(MemAddr);\r
+}\r
+#else\r
+void* Gh3x2xAlgoMemApply(GU32 unMemSize)\r
+{\r
+    return &g_punGh3x2xAlgoMemBuffer[0];\r
+}\r
+\r
+void Gh3x2xAlgoMemFree(void* MemAddr)\r
+{\r
+\r
+}\r
+#endif\r
+\r
+/// algorithm memory is inited or not\r
+GU8 g_uchAlgoMemStatus = ALGO_MEM_NO_INIT;\r
+\r
+/// buffer for algorithm, this addr is import from outer \r
+//void* g_unAlgorithmMemBuffer = 0;\r
+\r
+/// buffer size(byte) for algorithm, this size is import from outer\r
+GU32 g_unAlgorithmMemBufferSize = 0;\r
+\r
+/**\r
+ * @fn     GS8 GH3X2X_AlgoMemConfig( GU32 unMemSize)\r
+ *\r
+ * @brief  Config algorithm memory.\r
+ *\r
+ * @attention   Mem can only be static,such as global array\r
+ *\r
+ * @param[in]  unMemSize       memory size(unit:byte)\r
+ *\r
+ * @return  error code\r
+ * @retval  #GH3X2X_RET_OK                      return successfully\r
+ * @retval  #GH3X2X_RET_RESOURCE_ERROR          return algorithm mem config error\r
+ */\r
+GS8 GH3X2X_AlgoMemConfig( GU32 unMemSize)\r
+{\r
+    GS8 chRet = GH3X2X_RET_OK;\r
+    if (unMemSize > 0)\r
+    {\r
+        GH3X2X_AlgoDeinit(0xFFFFFFFF);\r
+        g_unAlgorithmMemBufferSize = unMemSize;\r
+        chRet = GH3X2X_RET_OK;\r
+        GH3X2X_DEBUG_ALGO_LOG("Algorithm mem Config complete!Size:%d\r\n", (int)unMemSize);\r
+        GH3X2X_DEBUG_ALGO_LOG("Algorithm mem init start...\r\n");\r
+        chRet = GH3X2X_AlgoMemInit();\r
+    }\r
+    else\r
+    {\r
+        GH3X2X_DEBUG_ALGO_LOG("Algorithm mem config fail!\r\n");\r
+        chRet = GH3X2X_RET_RESOURCE_ERROR;\r
+    }\r
+    return chRet;\r
+}\r
+\r
+/**\r
+ * @fn     GS8 GH3X2X_AlgoMemInit(void)\r
+ *\r
+ * @brief  algorithm memory init\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  error code\r
+ * @retval  #GH3X2X_RET_OK                      return successfully\r
+ * @retval  #GH3X2X_RET_RESOURCE_ERROR          return algorithm mem init error\r
+ */\r
+GS8 GH3X2X_AlgoMemInit(void)\r
+{\r
+    GS8 chRet = GH3X2X_RET_OK;\r
+    GH3X2X_DEBUG_ALGO_LOG("Algorithm mem init start...\r\n");\r
+    if (ALGO_MEM_NO_INIT == g_uchAlgoMemStatus)\r
+    {\r
+        g_punGh3x2xAlgoMemBufferPointer = (GU32*)Gh3x2xAlgoMemApply(g_unAlgorithmMemBufferSize);\r
+        if ((g_punGh3x2xAlgoMemBufferPointer != 0) && (g_unAlgorithmMemBufferSize > 0))\r
+        {\r
+            if(MEMPOOL_IS_OK_E != goodix_mem_init((void*)g_punGh3x2xAlgoMemBufferPointer, g_unAlgorithmMemBufferSize))\r
+            {\r
+                chRet = GH3X2X_RET_RESOURCE_ERROR;\r
+                GH3X2X_DEBUG_ALGO_LOG("Algorithm mem init error!\r\n");\r
+                \r
+            }\r
+            else\r
+            {\r
+                g_uchAlgoMemStatus = ALGO_MEM_INIT_OK;\r
+                chRet = GH3X2X_RET_OK;\r
+                GH3X2X_DEBUG_ALGO_LOG("Algorithm mem init success.Addr:0x%x,Size:%d\r\n", (unsigned int)g_punGh3x2xAlgoMemBufferPointer, \\r
+                                                                                        (int)g_unAlgorithmMemBufferSize);\r
+            }\r
+        }\r
+        else\r
+        {\r
+            GH3X2X_DEBUG_ALGO_LOG("Algorithm mem para error!\r\n");\r
+            chRet = GH3X2X_RET_RESOURCE_ERROR;\r
+        }\r
+    }\r
+    return chRet;\r
+}\r
+\r
+/**\r
+* @fn     void GH3X2X_AlgoMemDeinit(void)\r
+*\r
+* @brief  algorithm memory deinit\r
+*\r
+* @attention   None\r
+*\r
+* @param[in]   None\r
+* @param[out]  None\r
+*\r
+* @return  None\r
+*/\r
+void GH3X2X_AlgoMemDeinit(void)\r
+{\r
+    if (ALGO_MEM_INIT_OK == g_uchAlgoMemStatus)\r
+    {\r
+        goodix_mem_deinit();  //destroy all memory\r
+        if(g_punGh3x2xAlgoMemBufferPointer)\r
+        {\r
+            Gh3x2xAlgoMemFree((void*)g_punGh3x2xAlgoMemBufferPointer);\r
+            g_punGh3x2xAlgoMemBufferPointer = 0;\r
+        }\r
+        g_uchAlgoMemStatus = ALGO_MEM_NO_INIT;\r
+        GH3X2X_DEBUG_ALGO_LOG("Algorithm mem deinit!\r\n");\r
+    }    \r
+}\r
+\r
+GU8 GH3X2X_GetAlgoMemStatus(void)\r
+{\r
+    return g_uchAlgoMemStatus;\r
+}\r
+\r
+GU8 Gh3x2xGetHrAlgoSupportChnl(void)\r
+{\r
+    return __HR_ALGORITHM_SUPPORT_CHNL_NUM__;\r
+}\r
+\r
+GU8 Gh3x2xGetSpo2AlgoSupportChnl(void)\r
+{\r
+    return __SPO2_ALGORITHM_SUPPORT_CHNL_NUM__;\r
+}\r
+\r
+\r
+\r
+#endif\r
+\r
+\r
+\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_application/src/gh3x2x_demo_algo_reg_array.c b/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_application/src/gh3x2x_demo_algo_reg_array.c
new file mode 100644 (file)
index 0000000..7a9eb14
--- /dev/null
@@ -0,0 +1,101 @@
+/**\r
+ * @copyright (c) 2003 - 2022, Goodix Co., Ltd. All rights reserved.\r
+ * \r
+ * @file    gh3x2x_demo_reg_array.c\r
+ * \r
+ * @brief   gh3x2x driver lib reg config array\r
+ * \r
+ * @author  Gooidx Iot Team\r
+ * \r
+ */\r
+\r
+#include "gh3x2x_demo_algo_config.h"\r
+#include "gh_drv.h"\r
+\r
+/// HR\r
+const STGh3x2xReg gh3x2x_algo_reg_list0[] =\r
+{\r
+    {0x33C0, 0x0000}, {0x33C2, 0x0000}, {0x33C4, 0x0000}, {0x33C6, 0x0000}, {0x33C8, 0x0000}, {0x33CA, 0x0000},\r
+    {0x33CC, 0x0000}, {0x33CE, 0x0000}, {0x33D0, 0x0000}, {0x33D2, 0x0000}, {0x35C0, 0x0004}, {0x35C4, 0x0100},\r
+    {0x35C6, 0x0302}, {0x42C0, 0x846C}, {0x42C2, 0xFFFD}, {0x42C4, 0x87E3}, {0x42C6, 0xFFFF}, {0x42C8, 0xCC38},\r
+    {0x42CA, 0x000F}, {0x42CC, 0x0001}, {0x42CE, 0x0000}, {0x42D0, 0x0000}, {0x42D2, 0x0000}, {0x42D4, 0x001E},\r
+    {0x42D6, 0x0000}, {0x42D8, 0x000F}, {0x42DA, 0x0000}, {0x42DC, 0x0004}, {0x42DE, 0x0000}, {0x42E0, 0x0003},\r
+    {0x42E2, 0x0000}, {0x42E4, 0x0000}, {0x42E6, 0x0000}, {0x42E8, 0x0000}, {0x42EA, 0x0000}, {0x44C0, 0x0001},\r
+    {0x44CC, 0xFF01}, {0x44D4, 0xFF00}, {0xFFFF, 0x0001}\r
+};\r
+\r
+#if (__GOODIX_ALGO_CFG_LIST_MAX_NUM__ > 1)\r
+const STGh3x2xReg gh3x2x_algo_reg_list1[] =\r
+{\r
+    {0,0},\r
+};\r
+#endif /* (__GOODIX_ALGO_CFG_LIST_MAX_NUM__ > 1) */\r
+\r
+#if (__GOODIX_ALGO_CFG_LIST_MAX_NUM__ > 2)\r
+const STGh3x2xReg gh3x2x_algo_reg_list2[] =\r
+{\r
+    {0,0},\r
+};\r
+#endif /* (__GOODIX_ALGO_CFG_LIST_MAX_NUM__ > 2) */\r
+\r
+#if (__GOODIX_ALGO_CFG_LIST_MAX_NUM__ > 3)\r
+const STGh3x2xReg gh3x2x_algo_reg_list3[] =\r
+{\r
+    {0,0},\r
+};\r
+#endif /* (__GOODIX_ALGO_CFG_LIST_MAX_NUM__ > 3) */\r
+\r
+#if (__GOODIX_ALGO_CFG_LIST_MAX_NUM__ > 4)\r
+const STGh3x2xReg gh3x2x_algo_reg_list4[] =\r
+{\r
+    {0,0},\r
+};\r
+#endif /* (__GOODIX_ALGO_CFG_LIST_MAX_NUM__ > 4) */\r
+\r
+#if (__GOODIX_ALGO_CFG_LIST_MAX_NUM__ > 5)\r
+const STGh3x2xReg gh3x2x_algo_reg_list5[] =\r
+{\r
+    {0,0},\r
+};\r
+#endif /* (__GOODIX_ALGO_CFG_LIST_MAX_NUM__ > 5) */\r
+\r
+#if (__GOODIX_ALGO_CFG_LIST_MAX_NUM__ > 6)\r
+const STGh3x2xReg gh3x2x_algo_reg_list6[] =\r
+{\r
+    {0,0},\r
+};\r
+#endif /* (__GOODIX_ALGO_CFG_LIST_MAX_NUM__ > 6) */\r
+\r
+#if (__GOODIX_ALGO_CFG_LIST_MAX_NUM__ > 7)\r
+const STGh3x2xReg gh3x2x_algo_reg_list7[] =\r
+{\r
+    {0,0},\r
+};\r
+#endif /* (__GOODIX_ALGO_CFG_LIST_MAX_NUM__ > 7) */\r
+\r
+const STGh3x2xInitConfig g_stGoodixAlgoCfgListArr[__GOODIX_ALGO_CFG_LIST_MAX_NUM__] = \r
+{\r
+    {gh3x2x_algo_reg_list0,sizeof(gh3x2x_algo_reg_list0) / sizeof(gh3x2x_algo_reg_list0[0])},\r
+    #if (__GOODIX_ALGO_CFG_LIST_MAX_NUM__ > 1)\r
+    {gh3x2x_algo_reg_list1,sizeof(gh3x2x_algo_reg_list1) / sizeof(gh3x2x_algo_reg_list1[0])},\r
+    #endif /* (__GOODIX_ALGO_CFG_LIST_MAX_NUM__ > 1) */\r
+    #if (__GOODIX_ALGO_CFG_LIST_MAX_NUM__ > 2)\r
+    {gh3x2x_algo_reg_list2,sizeof(gh3x2x_algo_reg_list2) / sizeof(gh3x2x_algo_reg_list2[0])},\r
+    #endif /* (__GOODIX_ALGO_CFG_LIST_MAX_NUM__ > 2) */\r
+    #if (__GOODIX_ALGO_CFG_LIST_MAX_NUM__ > 3)\r
+    {gh3x2x_algo_reg_list3,sizeof(gh3x2x_algo_reg_list3) / sizeof(gh3x2x_algo_reg_list3[0])},\r
+    #endif /* (__GOODIX_ALGO_CFG_LIST_MAX_NUM__ > 3) */\r
+    #if (__GOODIX_ALGO_CFG_LIST_MAX_NUM__ > 4)\r
+    {gh3x2x_algo_reg_list4,sizeof(gh3x2x_algo_reg_list4) / sizeof(gh3x2x_algo_reg_list4[0])},\r
+    #endif /* (__GOODIX_ALGO_CFG_LIST_MAX_NUM__ > 4) */\r
+    #if (__GOODIX_ALGO_CFG_LIST_MAX_NUM__ > 5)\r
+    {gh3x2x_algo_reg_list5,sizeof(gh3x2x_algo_reg_list5) / sizeof(gh3x2x_algo_reg_list5[0])},\r
+    #endif /* (__GOODIX_ALGO_CFG_LIST_MAX_NUM__ > 5) */\r
+    #if (__GOODIX_ALGO_CFG_LIST_MAX_NUM__ > 6)\r
+    {gh3x2x_algo_reg_list6,sizeof(gh3x2x_algo_reg_list6) / sizeof(gh3x2x_algo_reg_list6[0])},\r
+    #endif /* (__GOODIX_ALGO_CFG_LIST_MAX_NUM__ > 6) */\r
+    #if (__GOODIX_ALGO_CFG_LIST_MAX_NUM__ > 7)\r
+    {gh3x2x_algo_reg_list7,sizeof(gh3x2x_algo_reg_list7) / sizeof(gh3x2x_algo_reg_list7[0])},\r
+    #endif /* (__GOODIX_ALGO_CFG_LIST_MAX_NUM__ > 7) */\r
+};\r
+\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_application/src/gh3x2x_demo_strategy.c b/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_application/src/gh3x2x_demo_strategy.c
new file mode 100644 (file)
index 0000000..c546b3e
--- /dev/null
@@ -0,0 +1,79 @@
+/**\r
+ * @copyright (c) 2003 - 2022, Goodix Co., Ltd. All rights reserved.\r
+ * \r
+ * @file    gh3x2x_demo_strategy.c\r
+ * \r
+ * @brief   \r
+ * \r
+ * @author  \r
+ * \r
+ */\r
+\r
+/* includes */\r
+#include "goodix_algo.h"\r
+#include "gh3x2x_demo_algo_config.h"\r
+#include "gh3x2x_demo_algo_call.h"\r
+\r
+\r
+GU8 g_uchPreHrValue = 0;\r
+\r
+\r
+void Gh3x2xOutputValueStrategyInit(GU32 unFunctionID)\r
+{\r
+#if __GH3X2X_HR_OUTPUT_VALUE_STRATEGY_EN__\r
+    if(GH3X2X_FUNCTION_HR & unFunctionID == GH3X2X_FUNCTION_HR)\r
+    {\r
+        g_uchPreHrValue = 0;\r
+    }\r
+#endif\r
+}\r
+\r
+\r
+#define GH3X2X_DIFF_ABS(x,y)  (x > y ? (x - y):(y - x))\r
+#if __GH3X2X_HR_OUTPUT_VALUE_STRATEGY_EN__\r
+void Gh3x2xHrOutputValueStrategyPro(STGh3x2xAlgoResult * pstAlgoResult, GU32 lubFrameId)\r
+{\r
+    GU8 uchCurrentOriginalHrValue = (GU8)(pstAlgoResult->snResult[0]);\r
+    GU8 uchConf = (GU8)(pstAlgoResult->snResult[1]);\r
+    GU8 uchNewHrValue = uchCurrentOriginalHrValue;\r
+    \r
+    if(0 == g_uchPreHrValue)\r
+    {\r
+        g_uchPreHrValue = uchCurrentOriginalHrValue;\r
+    }\r
+    else\r
+    {\r
+        if((GH3X2X_DIFF_ABS(g_uchPreHrValue,uchCurrentOriginalHrValue) > 50) &&(uchConf <= 50))   //there is big difference between pre hr and current orignal hr AND confidence is low\r
+        {\r
+            //smooth vaule\r
+            uchNewHrValue = (((GU16)g_uchPreHrValue) *2 + (GU16)uchCurrentOriginalHrValue)/3;\r
+        }\r
+        g_uchPreHrValue = uchNewHrValue;\r
+\r
+        //write back to result\r
+        pstAlgoResult->snResult[0] = uchNewHrValue;\r
+    }\r
+}\r
+#endif\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_call/inc/goodix_af.h b/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_call/inc/goodix_af.h
new file mode 100644 (file)
index 0000000..eec8f98
--- /dev/null
@@ -0,0 +1,20 @@
+#ifndef __GOODIX_AF_H\r
+#define __GOODIX_AF_H\r
+\r
+\r
+#include "goodix_type.h"\r
+#include "goodix_algo.h"\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+extern const GU8 *AFVersion(void);\r
+extern GS32 AFInit(GS32 g_s32WaitTime);\r
+extern GS32 AF_Detection_Module(GS32 *s32RRIRawdataArray,GU32* nResult);\r
+extern GS32 AFDeInit(void);\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_call/inc/goodix_algo.h b/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_call/inc/goodix_algo.h
new file mode 100644 (file)
index 0000000..299d40c
--- /dev/null
@@ -0,0 +1,106 @@
+#ifndef GOODIX_ALGO_H\r
+#define GOODIX_ALGO_H\r
+\r
+#include "stdint.h"\r
+#include "string.h"\r
+#include "stdio.h"\r
+#include "gh_drv.h"\r
+//\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif  /* __cplusplus */\r
+\r
+// typedef unsigned char       GU8;    /**< 8bit unsigned integer type */\r
+// typedef signed char         GS8;    /**< 8bit signed integer type */\r
+// typedef unsigned short      GU16;   /**< 16bit unsigned integer type */\r
+// typedef signed short        GS16;   /**< 16bit signed integer type */\r
+// typedef int                 GS32;   /**< 32bit signed integer type */\r
+// typedef unsigned int        GU32;   /**< 32bit unsigned integer type */\r
+// typedef float               GF32;   /**< float type */\r
+// typedef double              GD64;   /**< double type */\r
+// typedef char                GCHAR;  /**< char type */\r
+// typedef unsigned char       GBOOL; \r
+// typedef long long           GS64;   /**< 64bit signed integer type */\r
+\r
+#define   GH3X2X_PTR_NULL                           ((void *) 0)\r
+#define   GH3X2X_CHANNEL_MAP_MAX_CH                             (32)\r
+\r
+/* extern log function */\r
+extern void GH3X2X_PlatformLog(GCHAR *chLogString);\r
+\r
+/// log support len\r
+#define GH3X2X_LOG_ALGO_SUP_LEN     (128)\r
+#if 0\r
+//#define   GH3X2X_DEBUG_ALGO_LOG(...)       do {\\r
+                                                if(g_pSnprintfUserIn)\\r
+                                                {\\r
+                                                    GCHAR _7iwtO6qX0[GH3X2X_LOG_ALGO_SUP_LEN] = {0};\\r
+                                                    g_pSnprintfUserIn(_7iwtO6qX0, GH3X2X_LOG_ALGO_SUP_LEN, \\r
+                                                            "[gh3x2x_drv]: "__VA_ARGS__);\\r
+                                                    GH3X2X_PlatformLog(_7iwtO6qX0);\\r
+                                                 }\\r
+                                                 if(g_pPrintfUserIn)g_pPrintfUserIn("[gh3x2x_drv]: "__VA_ARGS__);\\r
+                                            } while (0)\r
+#endif\r
+/* ******************************************************************************************* */\r
+//public part\r
+typedef struct\r
+{\r
+    void *pnParametersBuffer;          //STGoodixAlgorithmXXXControlConfigParametersBuffer\r
+    GS32 nBaseBufferLen;\r
+    GS32 *pnBaseBuffer;\r
+}STGoodixAlgorithmControlConfig;\r
+\r
+typedef struct\r
+{\r
+    GU8  uchFrameId;                   //frame id 0x00~0xFF\r
+    /* suggest default struct : 0-7:green, 8-15:ir, 16-23:red, 24-31:other(bg) */\r
+    GU8  uchRawdataLen;                //rawdata number(<=32)\r
+    GS32 *pnRawdata;                   //rawdata buffer basic address\r
+    GU8  *puchCurAdjFlag;              //tx current adj flag buffer basic address\r
+    GU16 *pusCurAdjValue;             //tx current adj value buffer basic address, dr0:0-8bit dr1:9-16bit\r
+    GU8  *puchGainAdjValue;            //rx gain adj value buffer basic address\r
+    GU8  *puchChnlColorInfo;           //color info & enable flag buffer basic address 0:Not enable,1:Green,2:Ir,3:Red,4:Ecg,5:Bg\r
+    /* *********************************************************************** */\r
+    void *psAccdata;                   //STGoodixAlgorithmXXXCalculateInputAccdata\r
+    void *pnRefBuffer;                 //STGoodixAlgorithmXXXInputRefBuffer\r
+}STGoodixAlgorithmCalculateInput;\r
+\r
+/* Goodix Algorithm Output Struct */\r
+typedef struct\r
+{\r
+    void *pnResult;                    //STGoodixAlgorithmXXXCalculateOutputResult\r
+    GS32  nMiddleBaseBufferLen;\r
+    GS32 *pnMiddleBaseBuffer;\r
+}STGoodixAlgorithmCalculateOutput;\r
+\r
+/* Goodix Algorithm Deinit Struct */\r
+typedef struct\r
+{\r
+    void *pnFinalResult;               //STGoodixAlgorithmXXXFinalOutputResult\r
+    GS32 nBaseBufferLen;\r
+    GS32* pnBaseBuffer;\r
+}STGoodixAlgorithmFinalOutput;\r
+\r
+/**\r
+ * @brief Goodix Algorithm Whole struct\r
+ */\r
+typedef struct\r
+{\r
+    /* Application section malloc part */\r
+    STGoodixAlgorithmControlConfig stAlgorithmConfig;\r
+    STGoodixAlgorithmCalculateInput stAlgorithmCalcInput;\r
+\r
+    /* Algorithm section malloc part */\r
+    STGoodixAlgorithmCalculateOutput stAlgorithmCalcOutput;\r
+    STGoodixAlgorithmFinalOutput stAlgorithmFinalOutput;\r
+}STGoodixAlgorithmInfo;\r
+\r
+typedef GS32 (*pfnAlgoCallFunc)(STGoodixAlgorithmInfo* pstGoodixAlgorithmInfo); \r
+typedef GU8* (*pfnAlgoCallGetVersion)(void); \r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+#endif\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_call/inc/goodix_algo_bt.h b/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_call/inc/goodix_algo_bt.h
new file mode 100644 (file)
index 0000000..1f66023
--- /dev/null
@@ -0,0 +1,312 @@
+#ifndef GOODIX_ALGO_BT_H\r
+#define GOODIX_ALGO_BT_H\r
+#include <stdint.h>        \r
+#include "goodix_algo.h"\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif  /* __cplusplus */\r
+\r
+#if _WIN32 || _WIN64\r
+#define DLL_API_BODY_TEMPERATURE extern _declspec(dllexport)\r
+#else\r
+#define DLL_API_BODY_TEMPERATURE\r
+#endif\r
+\r
+       /* **************************************const value define*********************************************** */\r
+       /**\r
+        * @brief configuration virtual registers define\r
+       */\r
+#define BT_VIRTUAL_REG_UINIT             (sizeof(GU16))//length of virtual register\r
+#define BT_CFG_HEADER_LENGTH                 (0x06)    //length of header registers\r
+#define BT_CFG_HWINFO_LENGTH                 (0x2D)    //length of hardware information registers\r
+#define BT_CFG_THRES_LENGTH                  (0x14)    //length of threshold registers\r
+#define BT_CFG_ALGO_LENGTH                   (0x64)    //length of algorithm configuration registers\r
+#define BT_CFG_TOTAL_LENGTH                  (0xAB)    //length of configuration\r
+\r
+       /**\r
+        * @brief algorithm errorcode define\r
+       */\r
+       // common errorcode\r
+#define BT_ERRORCODE_OK                      (0x00)    //Errorcode: ok\r
+#define BT_ERRORCODE_UNINIT                  (0x01)    //Errorcode: the initialization function was not called\r
+//function errorcode\r
+#define BT_ERRORCODE_NULL_PTR                (0x03)    //Errorcode: called empty pointer\r
+#define BT_ERRORCODE_MALLOC_FAIL             (0x04)    //Errorcode: out of memory\r
+#define BT_ERRORCODE_INVALID_PARAM           (0x05)    //Errorcode: illegal parameter\r
+#define BT_ERRORCODE_FAIL                    (0x06)    //Errorcode: calculation failed\r
+//module base value   \r
+#define BT_ERRORCODE_BASE_VALUE_INIT         (0x10)    //Errorcode: preprocessing module\r
+#define BT_ERRORCODE_BASE_VALUE_PRE          (0x20)    //Errorcode: preprocessing module\r
+#define BT_ERRORCODE_BASE_VALUE_ALGO         (0x30)    //Errorcode: algorithm module\r
+\r
+#define BT_MAX_CH_NUM                        (0x02)    //Channel number\r
+\r
+/* ******************************************enum define************************************************** */\r
+\r
+/**\r
+ * @brief BT device type enum\r
+*/\r
+       typedef enum\r
+       {\r
+               CB62K928D = 0,      \r
+               CB62K552D,             \r
+               DT104D3950,           \r
+       }EM_BT_NTC_TYPE;\r
+       \r
+       /**\r
+ * @brief BT R_T convert flag\r
+*/\r
+       typedef enum\r
+       {\r
+               EM_CONVER_OK = 0,      \r
+               EM_TEMP_OUT_RANGE_H,             \r
+               EM_TEMP_OUT_RANGE_L,\r
+               EM_TEMP_OUT_RANGE_WRONG_INPUT, \r
+       }EM_BT_ALGO_OUT_RANGE;\r
+       \r
+       \r
+/**\r
+ * @brief BT device type enum\r
+*/\r
+       typedef enum\r
+       {\r
+               EM_BT_DEVICE_WATCH_BAND = 0x00,      //Device type: wearable watch or band\r
+               EM_BT_DEVICE_INEAR_DEEP,             //Device type: in-depth earphones\r
+               EM_BT_DEVICE_INEAR_NORMAL,           //Device type: shallow in-ear earphones\r
+               EM_BT_DEVICE_TYPE_MAX,               //Device type: device type total number\r
+       }EM_BT_DEVICE_TYPE;\r
+\r
+       /**\r
+        * @brief BT monitor mode\r
+       */\r
+       typedef enum\r
+       {\r
+               EM_MODE_ONCE = 0x00,                 //monitor mode: single measurement\r
+               EM_MODE_CONTINUE,                    //monitor mode: continue measurement\r
+               EM_MODE_TEST,                        //monitor mode: mass production testing\r
+               EM_MODE_MAX,                         //monitor mode: monitor mode total number\r
+       }EM_BT_MONITOR_MODE;\r
+\r
+       /**\r
+        * @brief BT monitor mode\r
+       */\r
+       typedef enum\r
+       {\r
+               EM_BT_TYPE_SHELL = 0x00,             //monitor body temperature type: single\r
+               EM_BT_TYPE_CORE,                     //monitor body temperature type: continue\r
+               EM_BT_TYPE_MAX,                      //monitor body temperature type: mode total number\r
+       }EM_BT_TYPE;\r
+\r
+       /**\r
+        * @brief BT rawdate type\r
+       */\r
+       typedef enum\r
+       {\r
+               EM_RAWDATA_ADC = 0x00,               //rawdata type: normal ADC code\r
+               EM_RAWDATA_RESIS,                    //rawdata type: NTC resistance  \r
+               EM_RAWDATA_TEMP,                     //rawdata type: temperature \r
+               EM_RAWDATA_MAX,                      //rawdata type: type total\r
+       }EM_BT_RAWDATA_TYPE;\r
+\r
+       /**\r
+        * @brief BT sensor type\r
+       */\r
+       typedef enum\r
+       {\r
+               EM_SENSOR_NTC = 0x00,               //sensor type: NTC\r
+               EM_SENSOR_IC,                       //sensor type: IC  \r
+               EM_SENSOR_MAX,                      //sensor type: type total\r
+       }EM_BT_SENSOR_TYPE;\r
+\r
+       /* ******************************************struct define************************************************ */\r
+       \r
+       /**\r
+        * @brief data min max average\r
+       */\r
+       typedef struct\r
+       {\r
+               GS16 nMin;                              \r
+               GS16 nMax;                          \r
+               GS32 nSum;                           \r
+       }STBtPreprocRwatemp;\r
+       \r
+       /**\r
+        * @brief final output struct\r
+       */\r
+       typedef struct\r
+       {\r
+               GU8 chFrameIndex;                                  // frame count\r
+               STBtPreprocRwatemp stRawTemp[BT_MAX_CH_NUM];\r
+               /* Body Temperature */\r
+               GS16 nFrameTemperature[BT_MAX_CH_NUM];                         //finaloutput: (included) shell body temperature\r
+               GS16 nSecTemperature[BT_MAX_CH_NUM];                           //finaloutput: (included) core body temperature\r
+               GU8 chOutRangeFlag;                                 //\r
+       }STGH3x2xDrvBtOutputResult;\r
+       \r
+       \r
+       /**\r
+        * @brief initialize configuration\r
+       */\r
+       typedef struct\r
+       {\r
+               /*********************** configuration header 6 words *****************************/\r
+               //config length & config version (up to the tool)\r
+               GU16 unCfgLen;                       //initialize configuration: size of struct\r
+               GU16 unCfgVer;                       //initialize configuration: version of configuration\r
+               GU16 unCfgTimL;                      //initialize configuration: configuration compiler time\r
+               GU16 unCfgTimH;                      //initialize configuration: configuration compiler time\r
+               GU16 unCfgProjCode;                  //initialize configuration: customer code\r
+               GU16 unCheckSum;                     //initialize configuration: configuration checksum\r
+\r
+               /*********************** hardware information 45 words ****************************/\r
+               //device information (up to the device hardware)\r
+               GU16 unDeviceType;                   //initialize configuration: type of device\r
+               GU16 unChannelNum;                   //initialize configuration: number of channels\r
+               GU16 unMonitorMode;                  //initialize configuration: monitor mode\r
+               GU16 unMonitorType;                  //initialize configuration: monitor type\r
+               GU16 unTempRangeUpper;               //initialize configuration: temperature upper limit\r
+               GU16 unTempRangeLower;               //initialize configuration: lower temperature limit\r
+               //rawdata information (up to the application)\r
+               GU16 unSampleFrequency;              //initialize configuration: sampling frequency \r
+               GU16 unRawdataType;                  //initialize configuration: rawdata meaning \r
+               //inherent deviation (up to the device)\r
+               GS16 nTempConstOffset0;              //initialize configuration: inherent deviation of device //GS16 force to GU16\r
+               GS16 nTempConstOffset1;              //initialize configuration: inherent deviation of device //GS16 force to GU16\r
+               //reserved\r
+               GU16 unDeviceReserved[2];            //initialize configuration: device info reserved\r
+\r
+               // temperature sensor information\r
+               GU16 unSensorType;                   //initialize configuration: sensor type\r
+               GU16 unSensorNtcRef;                 //initialize configuration: NTC ref resistance: unit:10ohm\r
+               GU16 unSensorNtcRT_Len;              //initialize configuration: NTC R-T table length \r
+               GU16 unSensorParameter[30];          //initialize configuration: sensor parameters buffer NTC_R:Order: unTempRangeLower to unTempRangeUpper \r
+                                                                                //unTempRangeLower step 2 celsius until 25 celsius, 25 celsius step 1 celsius to unTempRangeUpper\r
+               /*********************** threshold information 20 words ****************************/\r
+               // threshold \r
+               GU16 unBufferMax;                    //initialize configuration: data buffer length, unit is senconds, default:300s\r
+\r
+               GU16 unTimeWindow;                   //initialize configuration: data buffer window, unit is senconds, default: 20s\r
+               GU16 unTimeStep;                     //initialize configuration: step size of sliding window, unit is senconds, default: 5s\r
+               GU16 unTimeFast;                     //initialize configuration: fastest output time, unit is senconds, at least 60s \r
+               GU16 unTimeFastSlidWindow;           //initialize configuration: fastest output slid window size\r
+               GU16 unTimeFastSlidStep;             //initialize configuration: fastest output slid window step\r
+\r
+               GU16 unCntStable;                    //initialize configuration: stable time\r
+               GU16 chTempFluctuate;                //initialize configuration: fluctuate temperature\r
+               GU16 unCntFluctRecover;              //initialize configuration: recver time frome fluctuate\r
+               GU16 unTimeStable;                   //initialize configuration: minimum stable time requirement, unit is senconds, at least: 30s\r
+\r
+               GU16 unTimeRecover;                  //initialize configuration: minimum recover time requirement, unit is senconds, at least: 30s \r
+\r
+               GU16 unTempStable;                   //initialize configuration: minimum stable time requirement, unit is senconds, at least: 30s\r
+               GU16 unTempStableUpper;              //initialize configuration: minimum stable time requirement, unit is senconds, at least: 30s\r
+               GU16 unTempStableLower;              //initialize configuration: minimum stable time requirement, unit is senconds, at least: 30s\r
+               GU16 unThresReserved[6];             //initialize configuration: threshold reserved\r
+\r
+               /*********************** algorithm information 100 words ****************************/\r
+               // Please contact GOODIX\r
+               GU16 unConfig[100];                  //initialize configuration: algorithm   \r
+\r
+       }STGoodixAlgorithmBtControlConfigParametersBuffer;\r
+\r
+       /**\r
+        * @brief Gsensor information\r
+       */\r
+       typedef struct\r
+       {\r
+               GS16 nGSensorX;                       //refer: acc_x_axis, normalized to 512/g(9.80m/s^2)\r
+               GS16 nGSensorY;                       //refer: acc_y_axis, normalized to 512/g(9.80m/s^2)\r
+               GS16 nGSensorZ;                       //refer: acc_z_axis, normalized to 512/g(9.80m/s^2)\r
+       }STGoodixAlgorithmBtCalculateInputAccdata;\r
+\r
+       /**\r
+        * @brief external input reference\r
+       */\r
+       typedef struct\r
+       {\r
+               /* Personal information */\r
+               GU8 uchAge;                           //refer: (recommend) age (0-100)\r
+               GU8 uchGender;                        //refer: (recommend) gender (0- male, 1- female)\r
+               GU16 uchHeight;                       //refer: (recommend) height (unit: cm)\r
+               GU16 uchWeight;                       //refer: (recommend) weight (unit: kg)\r
+               /* physiological signal */\r
+               GU16 unHR;                            //refer: (required)  heart rate (unit: bpm)\r
+               GU16 unRRI;                           //refer: (recommend) RR interval (unit: ms)\r
+               GU16 unSPO2;                          //refer: (optional)  Oxygen saturation (unit: normalized to 0-100)\r
+               GS16 unET;                            //refer: (optional)  enviroment temperature (unit: 0.01 Celsius)\r
+               GU16 unBT;                            //refer: (optional)  core body temperature (unit: 0.01 Celsius)\r
+               GU16 unPI;                            //refer: (optional)  perfusion index (unit: normalized to 0-100)\r
+               /* wearing state */\r
+               GU16 unWear;                          //refer: (recommend) wearing quality (unit: normalized to 0-100)\r
+               /* device info */\r
+               GU16 unChargeFlag;                    //refer: (required)  the device was charged ten minutes ago,0- no  1- charged \r
+               GU16 unReserves[4];                   //refer: (reserved)  reserved\r
+       }STGoodixAlgorithmBtInputRef;\r
+\r
+       /**\r
+        * @brief output struct\r
+       */\r
+       typedef struct\r
+       {\r
+               /* flag of Body Temperature */\r
+               GU8 uchRefresh;                       //output: (included) refresh flag\r
+               GU8 uchCBTUpate;\r
+               GU8 uchConfidence;                    //output: (included) confidence level, normalized to 0-100\r
+               GU8 uchState;                         //output: (included) 0-default 1-rise 2-stable 3-under-stable 4-fluctuate\r
+               GU8 uchReserved[5];                   //output: (Reserved) reserved\r
+               /* Body Temperature */\r
+               GS16 nBT;                             //output: (included) shell body temperature\r
+               GS16 nCBT;                            //output: (included) core body temperature\r
+               GS16 nFPCBT;                          //output: (included) core body temperature of quick forecast result\r
+               GS16 nReserved[2];                    //output: (Reserved) reserved\r
+       }STGoodixAlgorithmBtCalculateOutputResult;\r
+\r
+       /**\r
+        * @brief final output struct\r
+       */\r
+       typedef struct\r
+       {\r
+               /* flag of Body Temperature */\r
+               GU8 uchRefresh;                       //finaloutput: (included) refresh flag\r
+               GU8 uchConfidence;                    //finaloutput: (included) confidence level, normalized to 0-100\r
+               GU8 uchState;                         //finaloutput: (included) 0-default 1-rise 2-stable 3-under-stable 4-fluctuate\r
+               GU8 uchReserved[5];                   //finaloutput: (Reserved) Reserved\r
+               /* Body Temperature */\r
+               GS16 nBT;                             //finaloutput: (included) shell body temperature\r
+               GU16 unCBT;                           //finaloutput: (included) core body temperature\r
+               GS16 nReserved[2];                    //finaloutput: (Reserved) reserved\r
+       }STGoodixAlgorithmBtFinalOutputResult;\r
+\r
+       /* *************************************Implemented by customer******************************************* */\r
+       /**\r
+     * @brief memory malloc function\r
+     * @param size\r
+     * @return pointer of memory\r
+    */\r
+       extern void* GoodixSensorAlgoMalloc(GS32 size);\r
+\r
+       /**\r
+        * @brief memory free function\r
+        * @param addr\r
+       */\r
+       extern void GoodixSensorAlgoFree(void* addr);\r
+\r
+       /**\r
+        * @brief algorithm log function\r
+        * @param addr\r
+       */\r
+       extern void GoodixSensorAlgoLog(GCHAR* pLogStr);\r
+\r
+       /* ******************************************API INTERFACE************************************************ */\r
+       DLL_API_BODY_TEMPERATURE GU8* GoodixBtAlgoVersion(void);\r
+       DLL_API_BODY_TEMPERATURE GS32 GoodixBtAlgoInit(STGoodixAlgorithmInfo* pstGoodixAlgorithmInfo);\r
+       DLL_API_BODY_TEMPERATURE GS32 GoodixBtAlgoCalculate(STGoodixAlgorithmInfo* pstGoodixAlgorithmInfo);\r
+       DLL_API_BODY_TEMPERATURE GS32 GoodixBtAlgoFinalCalculate(STGoodixAlgorithmInfo* pstGoodixAlgorithmInfo);\r
+       DLL_API_BODY_TEMPERATURE GS32 GoodixBtAlgoDeinit(STGoodixAlgorithmInfo* pstGoodixAlgorithmInfo);\r
+\r
+       /* ******************************************************************************************************* */\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+#endif //GOODIX_ALGO_BT_H\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_call/inc/goodix_ecg.h b/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_call/inc/goodix_ecg.h
new file mode 100644 (file)
index 0000000..e5a5197
--- /dev/null
@@ -0,0 +1,129 @@
+#ifndef __GOODIX_ECG_H\r
+#define __GOODIX_ECG_H\r
+\r
+#include "stdint.h"\r
+#include "goodix_type.h"\r
+\r
+#define ECG_INTERFACE_VERSION           "pv_v1.0.0"\r
+#define ECG_INTERFACE_VERSION_LEN_MAX   (20)\r
+#define ECG_CHANNEL_NUM                 (2)\r
+\r
+/**\r
+* @brief ECG �㷨��������״ֵ̬\r
+*/\r
+typedef enum\r
+{\r
+       GX_ALGO_ECG_SUCCESS = 0x00000000,               /**< �ɹ�     */\r
+       GX_ALGO_ECG_RWONG_INPUT = 0x00000001,           /**< �������ݸ�ʽ���Ϸ�     */\r
+       GX_ALGO_ECG_NO_MEMORY = 0x00000002,             /**< �ڴ�ռ䲻��     */\r
+}goodix_ecg_ret;\r
+\r
+typedef struct \r
+{\r
+       uint32_t fs;                                    // ������\r
+       uint32_t valid_channel_num;                     // ��Чͨ����\r
+       uint32_t qrs_flag;                              // QRS���flag��0�������������\r
+       uint32_t mode_type;                             // ECG��Ϸ�ʽ��0: AC mode,1: DC mode\r
+       uint32_t ic_type;                               // оƬ���ͣ�0��CardiffA��1��CardiffB\r
+}goodix_ecg_config;\r
+\r
+typedef struct\r
+{\r
+       uint32_t out_delay;                             // �˲��ӳ�\r
+}goodix_ecg_init_result;\r
+\r
+typedef struct\r
+{\r
+       uint32_t frameid;                               // ֡���\r
+       int32_t *ecg_rawdata;                           // ԭʼ����\r
+       int32_t acc_x;                                  // ���ٶȼ�x��\r
+       int32_t acc_y;                                  // ���ٶȼ�y��\r
+       int32_t acc_z;                                  // ���ٶȼ�z��\r
+       int32_t ecg_qc_flag;                            // ���ٻָ����\r
+       int32_t pace;                                   // pace����\r
+}goodix_ecg_input_rawdata;\r
+\r
+typedef struct\r
+{\r
+       float *ecg_out;                             // �ĵ�ֵ\r
+       goodix_stage *ecg_stage;                        // P-QRS-J-T ��״̬\r
+       float ecg_bpm;\r
+       float *ecg_snr;                             // �����\r
+       float *ecg_powerline_out;                   // �˳���Ƶ���� ���\r
+       float *ecg_blw_out;                         // �˳�����Ư�� ���\r
+       float *ecg_bpm_ch;                          // ����ֵ\r
+}goodix_ecg_result;\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+/**\r
+* @brief ECG �����㷨�汾��\r
+* @param[in]  version     �ⲿ����汾�ſռ䣬����20�ֽ�\r
+* @param[out] ��\r
+* @return     ����ִ�����\r
+*/\r
+DRVDLL_API goodix_ecg_ret goodix_ecg_version(uint8_t version[100]);\r
+\r
+\r
+/**\r
+* @brief ECG �����㷨��ʼ��\r
+* @param[in]  cfg         ������Ϣ\r
+* @param[in]  cfg_size    ������Ϣ��С\r
+* @param[out] res         ���صĽ��\r
+* @return     ����ִ�����\r
+*/\r
+DRVDLL_API goodix_ecg_ret goodix_ecg_init(const void *cfg_instance, goodix_ecg_init_result *res, int32_t cfg_size, const char *interface_ver);\r
+\r
+\r
+/**\r
+* @brief ECG �㷨����\r
+* @param[in] raw    ECG ����������Ϣ\r
+* @param[out] res    ECG ���صĽ��\r
+* @return     ����ִ�����\r
+*/\r
+DRVDLL_API goodix_ecg_ret goodix_ecg_update(goodix_ecg_input_rawdata* raw, goodix_ecg_result *res);\r
+\r
+/**\r
+*@brief ECG ��������\r
+* @param[in] ��\r
+* @param[out] res    ECG ������\r
+* @return     ����ִ�����\r
+*/\r
+DRVDLL_API goodix_ecg_ret goodix_ecg_classification_update(goodix_classification_flag *res);\r
+\r
+/**\r
+* @brief ECG �㷨���٣��ͷ��ڲ����ڴ�ռ䣬��������ģ���㷨ʱʹ��\r
+* @param[out] �� \r
+* @return     ����ִ�����\r
+*/\r
+DRVDLL_API goodix_ecg_ret goodix_ecg_deinit(void);\r
+\r
+/**\r
+* @brief ECG  ���ò�����ȡ����ʼ��ǰ���ã��������ýṹ���ڴ�\r
+* @param[out] ��\r
+* @return     ����ִ�����\r
+*/\r
+DRVDLL_API const void *goodix_ecg_config_get_arr(void);\r
+\r
+/**\r
+* @brief ECG  ���ò�����С��ȡ����ʼ��ǰ���ã������㷨�ڲ�����У��\r
+* @param[out] ��\r
+* @return     ��������ò�����С\r
+*/\r
+DRVDLL_API int32_t goodix_ecg_config_get_size(void);\r
+\r
+/**\r
+* @brief ECG  ���ð汾�Ż�ȡ����ʼ��ǰ���ã������㷨�ڲ�����У��\r
+* param[in] �汾�ų���\r
+* @param[out] ���ڴ��config�İ汾������\r
+* @return     ��\r
+*/\r
+DRVDLL_API void goodix_ecg_config_get_version(char* ver, uint8_t ver_len);\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_call/inc/goodix_hba.h b/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_call/inc/goodix_hba.h
new file mode 100644 (file)
index 0000000..8278802
--- /dev/null
@@ -0,0 +1,215 @@
+#ifndef __GOODIX_HBA_H\r
+#define __GOODIX_HBA_H\r
+\r
+#include <stdint.h>\r
+#ifndef _ARM_MATH_H\r
+#include "goodix_type.h"\r
+#endif\r
+#include "gh_drv.h"\r
+// HBA ������\r
+#ifndef HBA_FS\r
+#define HBA_FS 25\r
+#endif\r
+#define PPG_CHANNEL_NUM 4\r
+\r
+#define HBA_INTERFACE_VERSION "pv_v1.0.0"\r
+#define HBA_INTERFACE_VERSION_LEN_MAX (20)\r
+\r
+/**\r
+* @brief HBA ͨ������\r
+*/\r
+typedef enum\r
+{\r
+    CH_ENABLE_DEFAULT=0,//����Ĭ������\r
+    //��ͨ��\r
+    CH1_ENABLE_1000 = 1000,    \r
+    CH1_ENABLE_0100 = 100,\r
+    CH1_ENABLE_0010 = 10,\r
+    CH1_ENABLE_0001 = 1,\r
+    //˫ͨ��,�Բ�����\r
+    CH2_ENABLE_1010 = 1010,\r
+    CH2_ENABLE_0101 = 101,\r
+    //��ͨ��\r
+    CH3_ENABLE_0111 = 111,\r
+    CH3_ENABLE_1011 = 1011,\r
+    CH3_ENABLE_1101 = 1101,\r
+    CH3_ENABLE_1110 = 1110,\r
+    //��ͨ��\r
+    CH4_ENABLE_1111 = 1111,\r
+}goodix_hba_ch_enable;\r
+\r
+/**\r
+* @brief HBA �㷨��������״ֵ̬\r
+*/\r
+typedef enum\r
+{\r
+       GX_ALGO_HBA_SUCCESS = 0x00000000,                       /**< �ɹ�     */\r
+       GX_ALGO_HBA_RWONG_INPUT = 0x00000001,           /**< �������ݸ�ʽ���Ϸ�     */\r
+       GX_ALGO_HBA_NO_MEMORY = 0x00008000,                     /**< �ڴ�ռ䲻��     */\r
+}goodix_hba_ret;\r
+\r
+typedef enum {\r
+       HBA_SCENES_DEFAULT = 0,                         // Ĭ�ϣ����㷨�ڲ�ʶ����\r
+\r
+       HBA_SCENES_DAILY_LIFE = 1,                      // �ճ�����\r
+       HBA_SCENES_RUNNING_INSIDE = 2,          // �����ܲ���\r
+       HBA_SCENES_WALKING_INSIDE = 3,          // ���ڲ���\r
+       HBA_SCENES_STAIRS = 4,                          // ����¥��\r
+\r
+       HBA_SCENES_RUNNING_OUTSIDE = 5,         // �����ܲ�\r
+       HBA_SCENES_WALKING_OUTSIDE = 6,         // ���ⲽ��\r
+\r
+       HBA_SCENES_STILL_REST = 7,                      // ��Ϣ\r
+       HBA_SCENES_REST = 8,                            // ��Ϣ\r
+       HBA_SCENES_STILLRADON = 9,                      // ����\r
+\r
+       HBA_SCENES_BIKING_INSIDE = 10,          //�������г�\r
+       HBA_SCENES_BIKING_OUTSIDE = 11,         //�������г�\r
+       HBA_SCENES_BIKING_MOUNTAIN= 12,         //�������г�ԽҰ\r
+       HBA_SCENES_RUNNING_HIGH_HR = 13,        //�������ܲ�\r
+\r
+       HBA_SCENES_RUNNING_TREADMILL_CCOMBINE= 14,              // �ܲ��������\r
+\r
+       HBA_SCENES_HIGH_INTENSITY_COMBINE = 15,         // ��ǿ���˶����\r
+       HBA_SCENES_TRADITIONAL_STRENGTH_COMBINE = 16,           // ��ͳ����ѵ�����\r
+       HBA_SCENES_STEP_TEST = 17,                  // ̨�ײ���\r
+\r
+       HBA_SCENES_BALL_SPORTS = 18,            // �����˶�\r
+       HBA_SCENES_AEROBICS = 19,                   // ������\r
+\r
+    HBA_SCENES_SLEEP = 20,              // ˯�߳���\r
+    HBA_SCENES_JUMP = 21,               //����������LS ROMA��\r
+    HBA_SCENES_CORDLESS_JUMP = 22,         // ���������������\r
+       HBA_SCENES_SWIMMING = 23,           // ��Ӿ����\r
+    HBA_SCENES_SIZE = 24,               // ������Ŀ\r
+}hba_scenes_e;\r
+\r
+typedef enum {\r
+    HBA_TEST_DYNAMIC = 0,              // Ĭ�ϣ���̬����\r
+    HBA_TEST_DOT = 1,                  // ���\r
+    HBA_TEST_SENSELESS = 2,            // �޸�ģʽ\r
+}hba_test_mode;\r
+\r
+typedef struct {\r
+    hba_test_mode mode;                             // ����ģʽ\r
+       hba_scenes_e scence;                                                    // ����\r
+       uint32_t fs;                                                                    // ������\r
+       int32_t valid_channel_num;                                              // ��Чͨ����\r
+       // �����ⲿ�����㷨�����ԵIJ���\r
+    uint32_t back_track_len;                       // ���ݵ�ʱ��,Ĭ��30s,���ʱ������Ϊ120s�����ʱ������Ϊ30s\r
+       int32_t hba_latest_output_time;                                 // ������ֵʱ��\r
+       int32_t hba_earliest_output_time;                               // �����ֵʱ��\r
+    uint32_t hba_lowerest_confidence;                          // ��ͳ�ֵ���Ŷ�\r
+       uint32_t hba_out_step_second;                                   // ��ֵ���\r
+    uint32_t hba_convergence_rate;                                     // ׷�ٹ����е���������\r
+    uint32_t senseless_mode_step;                   // �޸м��ʱ��������Ϊ0��ʾδ֪\r
+    uint32_t senseless_mode_duration;               // �޸г���ʱ��������Ϊ0��ʾδ֪\r
+}goodix_hba_config;\r
+\r
+typedef struct\r
+{\r
+       uint32_t frameid;                                                               // ֡���\r
+       uint32_t total_channel_num;                     // ͨ������\r
+       int32_t *ppg_rawdata;           // PPGԭʼ���ݣ������̹�1234-����1234-���1234\r
+       int32_t *cur_adj_flg;           // ���������־λ\r
+       int32_t *gain_adj_flg;          // ��������־λ\r
+       int32_t *enable_flg;            // ͨ��ʹ�ܱ�־λ\r
+\r
+       int32_t acc_x;                                                                  // ���ٶȼ�x��\r
+       int32_t acc_y;                                                                  // ���ٶȼ�y��\r
+       int32_t acc_z;                                                                  // ���ٶȼ�z��\r
+\r
+    uint32_t sleep_flg;                             //˯��flg\r
+}goodix_hba_input_rawdata;\r
+\r
+typedef struct\r
+{\r
+       uint32_t hba_out_flag;                          // ��ֵ��ǣ�Ϊ 1 ��Ч\r
+       int32_t hba_out;                                        // ����ֵ\r
+       float hba_confi;                                // ���Ŷ�\r
+       float hba_snr;                                  // �����   : �˲�ȥ�����ź�Ƶ��������������������\r
+    uint32_t valid_level;                          // ���ŵȼ� : 0 -> 1 -> 2 ��Խ��Խ�ɿ�\r
+    uint32_t valid_score;                              // ���ŷ��� : 0->100 Խ��Խ�ɿ�\r
+    uint32_t hba_acc_info;              // �˶�״̬ : 0-��Ϣ��С�˶���1-����-���˶���2-�ܲ�-���˶���\r
+    hba_scenes_e hba_acc_scence;            // �˶����� : �ο� hba_scenes_e ö������\r
+       // ÿһ·������ֵ�����ڵ���\r
+       uint32_t *hba_out_flag_channel;                         // ��ֵ��ǣ�Ϊ 1 ��Ч\r
+       uint32_t *hba_out_channel;                                      // ����ֵ\r
+       float *hba_confi_channel;                               // ���Ŷ�\r
+       float *hba_snr_channel;                                 // �����\r
+       float **p_hba_td_filter;                                // ʱ���˲����ָ������\r
+       float **p_hba_fd_filter;                        // Ƶ��(ά��)�˲����ָ�����飬4·��1·����\r
+}goodix_hba_result;\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+\r
+/**\r
+* @brief HBA �����㷨�汾��\r
+* @param[in]  version     �ⲿ����汾�ſռ䣬����20�ֽ�\r
+* @param[out] ��\r
+* @return     ����ִ�����\r
+*/\r
+DRVDLL_API goodix_hba_ret goodix_hba_version(uint8_t version[120]);\r
+\r
+\r
+/**\r
+* @brief HBA �����㷨��ʼ��\r
+* @param[in]  scence     ʹ�ó���\r
+* @param[in]  fs         HBA �� ACC �IJ����ʡ�ע��������ҪͬƵ��\r
+* @param[out] ��\r
+* @return     ����ִ�����\r
+*/\r
+DRVDLL_API goodix_hba_ret  goodix_hba_init(const void *cfg_instance, uint32_t cfg_size, const char *interface_ver);\r
+\r
+\r
+/**\r
+* @brief HBA �㷨����\r
+* @param[in] raw    ��������\r
+* @param[out] res   ����������\r
+* @return     ����ִ�����\r
+*/\r
+DRVDLL_API goodix_hba_ret goodix_hba_update(goodix_hba_input_rawdata* raw, goodix_hba_result *res);\r
+\r
+/**\r
+* @brief HBA �㷨���٣��ͷ��ڲ����ڴ�ռ䣬��������ģ���㷨ʱʹ��\r
+* @param[out] ��\r
+* @return     ����ִ�����\r
+*/\r
+DRVDLL_API goodix_hba_ret goodix_hba_deinit(void);\r
+\r
+/**\r
+* @brief ��ȡhba��Ĭ�����ò���\r
+* @return     hba��Ĭ�����ò���\r
+*/\r
+DRVDLL_API const void *goodix_hba_config_get_arr(void);\r
+\r
+/**\r
+* @brief ��ȡhba������size\r
+* @return     hba������size\r
+*/\r
+DRVDLL_API int32_t  goodix_hba_config_get_size(void);\r
+\r
+/**\r
+* @brief ��ȡHBA�����ļ��İ汾��\r
+* @param[in/out]  ver       �汾�ű�������\r
+* @param[in]     ver_len   �汾�ų��ȣ�����ʹ��HBA_INTERFACE_VERSION_LEN_MAX\r
+* @return        ��\r
+*/\r
+DRVDLL_API void goodix_hba_config_get_version(char* ver, uint8_t ver_len);\r
+\r
+\r
+/**\r
+* @brief �û����ô�ӡHBA��Ҫ��Ϣ����Ҫ��ǰ��ʼ����ӡ����\r
+* @param[in]  raw    �����������ݣ�NULL == rawʱ������ӡ����\r
+* @return        ��\r
+*/\r
+DRVDLL_API void hba_essential_info_print(goodix_hba_input_rawdata* raw);\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_call/inc/goodix_hrv.h b/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_call/inc/goodix_hrv.h
new file mode 100644 (file)
index 0000000..565798b
--- /dev/null
@@ -0,0 +1,96 @@
+/*\r
+* HRVLib.h\r
+*/\r
+\r
+#ifndef _GOODIX_SYS_HRV_LIB_H_\r
+#define _GOODIX_SYS_HRV_LIB_H_\r
+\r
+#include <stdint.h>\r
+#include "iot_sys_def.h"\r
+#if DEBUG_HRV\r
+#include "..\..\HRVTest\goodix_debug.h"\r
+#endif\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+/* ·µ»Ø´íÎóÂë */\r
+typedef enum {\r
+    GX_HRV_ALGO_OK              = 0x00000000, // ³É¹¦·µ»Ø£¬»òÎÞ³öֵˢÐÂ\r
+    GX_HRV_ALGO_FAILED          = 0x10000001, // Ê§°Ü·µ»Ø\r
+    GX_HRV_ALGO_NULL_PTR        = 0x10000002, // Íⲿ´«ÈëµÄÖ¸ÕëΪ¿Õ\r
+    GX_HRV_ALGO_INVALID_PARAM   = 0x10000003, // ²ÎÊý·¶Î§ÎÞЧ\r
+    GX_HRV_ALGO_OUT_OF_MEM      = 0x10000004, // ÄÚ´æ·ÖÅäʧ°Ü\r
+    GX_HRV_ALGO_DEINIT_ABORT    = 0x10000005, // ÊÍ·Åʧ°Ü\r
+    GX_HRV_ALGO_UPDATE          = 0x10000006, // ÓгöֵˢÐÂ\r
+}goodix_hrv_ret;\r
+\r
+#define PPG_CHANNEL_NUM                            4\r
+#define RRI_NUM                         4\r
+#define ACC_THR_NUM                     4\r
+\r
+#define HRV_INTERFACE_VERSION "pv_v1.0.0"\r
+#define HRV_INTERFACE_VERSION_LEN_MAX (20)\r
+\r
+typedef struct {\r
+    int32_t need_ipl;                                   // ÊÇ·ñÐèÒª²åÖµµ½1KHz\r
+    int32_t fs;                                         // ²ÉÑùÂÊ\r
+    int32_t acc_thr[ACC_THR_NUM];                       // acc Ïà¹ØãÐÖµ£¬Ä¬ÈÏֵΪ£º20/10/3/3\r
+}goodix_hrv_config;\r
+\r
+typedef struct {\r
+       uint8_t bit_num;                       //Êý¾ÝλÊý\r
+    int32_t *ppg_rawdata;                 // PPGԭʼÐźţ¬×î¶àËÄͨµÀ\r
+    int32_t *cur_adj_flg;                 // µçÁ÷µ÷¹â±ê־λ\r
+    int32_t *gain_adj_flg;                // ÔöÒæµ÷¹â±ê־λ\r
+       int32_t acc_x;                        // ¼ÓËټƠx Öá\r
+    int32_t acc_y;                        // ¼ÓËټƠy Öá\r
+    int32_t acc_z;                       // ¼ÓËټƠz Öá\r
+    int32_t frame_id;                    // Ö¡ÐòºÅ\r
+    int32_t hr;                           // µ±Ç°ÐÄÂÊÖµ\r
+}goodix_hrv_input_rawdata;\r
+\r
+typedef struct {\r
+    int32_t rri[RRI_NUM];                               // RRI½á¹ûÊý×é\r
+    int32_t rri_confidence;                             // ½á¹ûÖÃÐŶÈ\r
+       int32_t rri_valid_num;                              // RRIÓÐЧ½á¹ûÊýÁ¿\r
+}goodix_hrv_result;\r
+\r
+IOT_SYS_DLL_API uint8_t *goodix_hrv_version(void);\r
+\r
+IOT_SYS_DLL_API goodix_hrv_ret goodix_hrv_init(const void *cfg_instance, uint32_t cfg_size, const char *interface_ver);\r
+\r
+IOT_SYS_DLL_API goodix_hrv_ret goodix_hrv_calc(goodix_hrv_input_rawdata *input_data, goodix_hrv_result *output_data);\r
+\r
+IOT_SYS_DLL_API goodix_hrv_ret goodix_hrv_deinit(void);\r
+\r
+/**\r
+* @brief »ñÈ¡hrvµÄĬÈÏÅäÖòÎÊý\r
+* @return     hrvµÄĬÈÏÅäÖòÎÊý\r
+*/\r
+IOT_SYS_DLL_API const void *goodix_hrv_config_get_arr(void);\r
+\r
+/**\r
+* @brief »ñÈ¡hrvµÄÅäÖÃsize\r
+* @return     hrvµÄÅäÖÃsize\r
+*/\r
+IOT_SYS_DLL_API int32_t  goodix_hrv_config_get_size(void);\r
+\r
+/**\r
+* @brief »ñÈ¡HRVÅäÖÃÎļþµÄ°æ±¾ºÅ\r
+* @param[in/out]  ver       °æ±¾ºÅ±£´æÊý×é\r
+* @param[in]     ver_len   °æ±¾ºÅ³¤¶È£¬½¨ÒéʹÓÃHRV_INTERFACE_VERSION_LEN_MAX\r
+* @return        ÎÞ\r
+*/\r
+IOT_SYS_DLL_API void goodix_hrv_config_get_version(char* ver, uint8_t ver_len);\r
+\r
+\r
+#if DEBUG_HRV\r
+IOT_SYS_DLL_API goodix_hrv_debug *copy_debug_addr();\r
+#endif\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif // _GOODIX_SYS_HRV_LIB_H_\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_call/inc/goodix_hsm.h b/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_call/inc/goodix_hsm.h
new file mode 100644 (file)
index 0000000..a89fcd7
--- /dev/null
@@ -0,0 +1,47 @@
+#ifndef __GOODIX_HSM_H\r
+#define __GOODIX_HSM_H\r
+\r
+\r
+#include "goodix_type.h"\r
+#include "goodix_algo.h"\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+extern int32_t HSMAlgoDeInit(void);\r
+extern int32_t HSMAlgoInit(int32_t *Fs);\r
+extern uint8_t *HSMAlgoVersion(void);\r
+typedef struct\r
+{\r
+       GU32 ulSleepInTime;\r
+       GU32 ulSleepOutTime;\r
+       GU16 nSleepLength;\r
+       GU16 nDeepRatio;\r
+       GU16 nLightRatio;\r
+       GU16 nRemRatio;\r
+       GU8 nWakeTimes;\r
+       GU8 nSleepScore;\r
+}ST_HSM_SCORE;\r
+typedef struct\r
+{\r
+       int32_t IPpgRaw;\r
+       int32_t IACCx;\r
+       int32_t IACCy;\r
+       int32_t IACCz;\r
+       int32_t IHeart;\r
+}ST_HSM_DATA_IN;\r
+#define GH3X2X_HSM_FLAG_BUFF_LEN (120)\r
+typedef struct\r
+{\r
+       uint8_t uchStageOutNum;\r
+       uint8_t uchStageDataFlag;\r
+       uint8_t puchHSMStageOut[GH3X2X_HSM_FLAG_BUFF_LEN];\r
+}ST_HSM_DATA_OUT;\r
+extern int32_t HSMProc(ST_HSM_DATA_IN* pstHSMDataIn, ST_HSM_DATA_OUT* pstHSMDataOut, ST_HSM_SCORE* pstHSMScore);\r
+extern int32_t HSMLastDataProc(ST_HSM_DATA_OUT* pstHSMDataOut, ST_HSM_SCORE* pstHSMScore);\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_call/inc/goodix_log.h b/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_call/inc/goodix_log.h
new file mode 100644 (file)
index 0000000..6076781
--- /dev/null
@@ -0,0 +1,39 @@
+#ifndef _GOODIX_LOG_H_\r
+#define _GOODIX_LOG_H_\r
+#include "goodix_type.h"\r
+\r
+typedef int32_t(*CallbackPrintfUser)(const char *, ...);\r
+typedef int32_t(*CallbackSnprintfUser)(char *str, size_t size, const char *format, ...);\r
+typedef void(*Callback_GH3X2X_Log)(GCHAR *log_string);\r
+\r
+DRVDLL_API void goodix_set_sprintFunc(CallbackPrintfUser g_pPrintfUserIn, CallbackSnprintfUser g_pSnprintfUserIn, Callback_GH3X2X_Log GH3X2X_Log_In);\r
+\r
+//log print\r
+//extern CallbackPrintfUser g_pPrintfUser;\r
+//extern CallbackSnprintfUser g_pSnprintfUser;\r
+//extern Callback_GH3X2X_Log GH3X2X_PlatformLog;\r
+\r
+///// log support len\r
+//#define GH3X2X_LOG_DEBUG_SUP_LEN     (128)\r
+\r
+//#define GH3X2X_INFO_LOG_PARAM(...) do {\\r
+//if(g_pSnprintfUser)\\r
+//{\\r
+//GCHAR chDebugStr[GH3X2X_LOG_DEBUG_SUP_LEN]={0};\\r
+//g_pSnprintfUser(chDebugStr, GH3X2X_LOG_DEBUG_SUP_LEN, \\r
+//"alg:"__VA_ARGS__);\\r
+//GH3X2X_PlatformLog(chDebugStr);\\r
+//}\\r
+//if(g_pPrintfUser)g_pPrintfUser("alg:"__VA_ARGS__);\\r
+//} while (0)//bp log\r
+\r
+// need to init goodix_set_sprintFunc() first\r
+/* LOG example:\r
+#if DEBUG_LOG\r
+#define LOG_PRINT       GH3X2X_INFO_LOG_PARAM\r
+#else\r
+#define LOG_PRINT\r
+#endif //#if DEBUG_LOG\r
+*/\r
+\r
+#endif // !_GOODIX_LOG_H_\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_call/inc/goodix_mem.h b/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_call/inc/goodix_mem.h
new file mode 100644 (file)
index 0000000..be14241
--- /dev/null
@@ -0,0 +1,78 @@
+#ifndef __GOODIX_MEM_H\r
+#define __GOODIX_MEM_H\r
+\r
+#include "stdint.h"\r
+#include "goodix_type.h"\r
+\r
+\r
+typedef enum\r
+{\r
+       MEMPOOL_IS_OK_E =                                               0, /*< MEM POOL is ok >*/\r
+       ERR_MEMPOOL_NOT_EXIST_E =                               -1, /*< mempool not exist >*/\r
+       ERR_PARAMS_MEMPOOL_SIZE_E =                     -2, /*< Input parameter is invalid: mempool size is invalid >*/\r
+       ERR_PARAMS_MALLOC_SIZE_E =                      -3, /*< Input parameter is invalid: malloc size is invalid >*/\r
+       ERR_MEMPOOL_NOT_ENOUGH_MEM_E =          -4, /*< Memory size does not meet the required memory >*/\r
+       ERR_PARAMS_ADDR_WRONG_E =                       -5, /*< Input parameter is invalid: free addr is invalid >*/\r
+       ERR_OP_CHUNK_TREAD_E =                          -6, /*< Occur memory tread >*/\r
+       ERR_OP_CHUNK_LEAKY_E =                          -7, /*< Occur memory leaky >*/\r
+}goodix_mem_ret;\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+//内存不足时的接口,只支持内存分配时候调用,不支持内存越界时调用\r
+#if !(_WIN32 || _WIN64)\r
+extern void Gh3x2xPoolIsNotEnough(void);\r
+#endif\r
+\r
+/**\r
+* @brief               内存池初始化操作\r
+* @param[in]   mem_addr 内存地址\r
+                               size 内存大小\r
+* @param[out]  无\r
+* @return              初始化情况  0   < Operation success.\r
+                                                       -1  < Input parameter is invalid\r
+                                                       -2  < Memory size does not meet the minimum required memory\r
+                                                       -3  < Memory manager has been initialized.\r
+*/\r
+DRVDLL_API int32_t goodix_mem_init(void* mem_addr, int32_t size);\r
+\r
+/**\r
+* @brief               内存池销毁操作\r
+* @param[in]   无\r
+* @param[out]  无\r
+* @return              无\r
+*/\r
+DRVDLL_API void goodix_mem_deinit(void);\r
+\r
+/**\r
+* @brief               内存申请操作\r
+* @param[in]   申请内存大小(字节)\r
+* @param[out]  无\r
+* @return              申请到的内存段首地址(在函数调用外做类型转换)\r
+*/\r
+DRVDLL_API void* goodix_mem_malloc(int32_t size);\r
+\r
+/**\r
+* @brief               释放内存操作\r
+* @param[in]   释放内存段的首地址\r
+* @param[out]  无\r
+* @return              无\r
+*/\r
+DRVDLL_API void goodix_mem_free(void* mem_addr);\r
+\r
+/**\r
+* @brief               获取内存池当前空闲内存容量\r
+* @param[in]   无\r
+* @param[out]  无\r
+* @return              内存池当前空闲容量(byte)\r
+*/\r
+DRVDLL_API uint32_t goodix_mem_get_free_size(void);\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+\r
+#endif\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_call/inc/goodix_nadt.h b/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_call/inc/goodix_nadt.h
new file mode 100644 (file)
index 0000000..f4a9910
--- /dev/null
@@ -0,0 +1,132 @@
+#ifndef _WWD_MAIN_H_\r
+#define _WWD_MAIN_H_\r
+#include <string.h>\r
+#include <stdlib.h>\r
+#include <math.h>\r
+#include <stdio.h>\r
+#include "goodix_type.h"\r
+#include "gh_drv.h"\r
+\r
+#define NADT_INTERFACE_VERSION "pv_v1.0.0"\r
+#define NADT_INTERFACE_VERSION_LEN_MAX (20)\r
+\r
+#define IOT_NADT_MAX(a,b)                ((a)<(b)?(b):(a))\r
+#define IOT_NADT_MIN(a,b)                ((a)>(b)?(b):(a))\r
+#define IOT_NADT_ABS(x)                  abs(x)\r
+#define IOT_NADT_ABS_GS32(x)             abs((GS32)(x))\r
+//#define IOT_NADT_ABS_GF32(x)             fabsf((GF32)(x))\r
+//#define IOT_NADT_ABS_GF64(x)             fabs((GF64)(x))\r
+//#define IOT_NADT_SQRT(x)                 sqrt(x)\r
+#define IOT_NADT_SQRTF(x)                sqrtf(x)\r
+#define IOT_NADT_ROUND(x)                round(x)\r
+#define NADT_PTR_NULL                   ((void *)0)\r
+\r
+typedef enum\r
+{\r
+       GX_ALGO_NADT_SUCCESS = 0x00000000,              /**< 成功     */\r
+       GX_ALGO_NADT_NO_MEMORY = 0x00000001,            /**< 内存空间不够     */\r
+       GX_ALGO_NADT_UNINIT = 0x00000002,\r
+       GX_ALGO_NADT_RWONG_INPUT = 0x00000003,          /**< 输入数据格式不合法     */\r
+}goodix_nadt_ret;\r
+\r
+#define NADT_MID_INFO_OUT 1\r
+\r
+//算法中间变量\r
+typedef struct\r
+{\r
+       //\r
+       GU8 wearResult;\r
+       GU8 moveFlag;\r
+       GU8 liveFlag;\r
+       GU8 bgJumpFlag;\r
+       GU8 bgPeriodFlag;\r
+       ////\r
+       ////ADT判断\r
+       //GS32 adtIRAvg;                                    //ADT值\r
+       //\r
+       //运动判断\r
+       GS32 accStd;                                            //ACC标准差\r
+       //\r
+       //活体检测\r
+       GS32 rawPVLen;                                          //波谷数\r
+       GS32 curHR;                                                     //心率\r
+       GS32 difRrInter;                                        //心率变化\r
+       GU8 heartBeatFlag;                  //心率标记\r
+       GU8 confiHeartBeatFlag;             //高置信度心率标记\r
+       GU8 wearAcfScore;                                       //自相关分数\r
+       GS32 signal;                                        //信号量\r
+       //基线判断\r
+       GU16 baseLineRatio;                                     //基线单调率\r
+       GS32 baseLineDiff;                                      //基线diff值\r
+       //\r
+       //高频背景光检测\r
+       GS16 jumpBgDiff;                                        //背景光diff\r
+       GU8 bgPeakNum;                                          //背景光波峰个数\r
+       //\r
+       //背景光周期检测\r
+       GS16 periodBgDiff;                                      //背景光变化量\r
+       GU16 bgPeriod;                                          //背景光周期\r
+       GU16 bgPeriodDiff;                                      //背景光周期差异\r
+}NADT_ST_MID_INFO;\r
+\r
+\r
+\r
+typedef struct\r
+{\r
+       GU16 sampleRateNADT;                            //采样率\r
+       GU8 unwearDetectLevel;                          //佩戴等级\r
+       GU8 sleepStatus;                                        //睡眠状态\r
+       //\r
+       GU16 checkTimeoutThr;                           //活体检测超时时间\r
+       GU8 unwearCheckCntThr;                          //脱落确认时间\r
+       GU8 wearCheckCntThr;                            //活体确认时间\r
+       //\r
+       //ADT判断\r
+       GS32 adtWearOnThr;                                      //ADT wear on阈值\r
+       GS32 adtWearOffThr;                                     //ADT wear off阈值\r
+       //\r
+       //运动判断\r
+       GS32 accStdThr;                                         //ACC标准差\r
+       //\r
+       //活体检测\r
+       GU8 liveDetectEnable;                           //活体检测使能\r
+       GS32 rawPVLenThr;                                       //高次谐波阈值\r
+       GU16 heartBeatThrLow;                           //心率下限\r
+       GU16 heartBeatThrHigh;                          //心率上限\r
+       GS32 difRrInterThr;                                     //心率变化阈值\r
+       GU8 wearAcfScoreThr;                            //自相关分数阈值\r
+       GU16 baseLinePosRatioThr;                       //基线单调率阈值\r
+       GS32 baseLineDiffThr;                       //基线平坦性阈值\r
+       GS32 sigScaleThr;\r
+       //\r
+       //高频背景光检测\r
+       GU8 bgJumpDetectEnable;                         //背景光突变检测使能\r
+       GS16 jumpBgDiffThr;                                     //背景光变化量阈值\r
+       GU8 bgPeakValleyNumThr;                         //背景光峰谷个数阈值\r
+       //\r
+       //背景光周期检测\r
+       GU8 bgPeriodDetectEnable;                       //背景光周期检测使能\r
+       GS16 periodBgDiffThr;                           //背景光变化量阈值\r
+       GU16 bgPeriodThr;                                       //背景光周期阈值\r
+       GU16 bgPeriodDiffThr;                           //背景光周期差异阈值\r
+}goodix_nadt_config;\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+DRVDLL_API goodix_nadt_ret NADTProcInit(const void *cfg_instance, GS32 cfg_size, const char *interface_ver);\r
+DRVDLL_API goodix_nadt_ret NADTProcDeinit(void);\r
+DRVDLL_API goodix_nadt_ret NADTProc(GS32 lPacketInfoArr[], GS32 lResult[], NADT_ST_MID_INFO *stMidInfo);\r
+DRVDLL_API goodix_nadt_ret GetNadtVersion(GU8 version[120]);\r
+DRVDLL_API GU8 NADTWearDetectByCap(GS32 lPacketInfoArr[]);\r
+\r
+DRVDLL_API const void *goodix_nadt_config_get_arr(void);\r
+DRVDLL_API GS32 goodix_nadt_config_get_size(void);\r
+DRVDLL_API void goodix_nadt_config_get_version(char* ver, GU8 ver_len);\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_call/inc/goodix_resp.h b/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_call/inc/goodix_resp.h
new file mode 100644 (file)
index 0000000..a7cbbb4
--- /dev/null
@@ -0,0 +1,35 @@
+#ifndef __GOODIX_RESP_H\r
+#define __GOODIX_RESP_H\r
+\r
+\r
+#include "goodix_type.h"\r
+#include "goodix_algo.h"\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+extern GS32 RespInit(GS32 *fs);\r
+extern void RespDeInit (void);\r
+typedef struct\r
+{\r
+       GS32 IPpgRaw;\r
+       GS32 IACCx;\r
+       GS32 IACCy;\r
+       GS32 IACCz;\r
+       GS32 IAdjFlag;\r
+}RESP_ST_DATA_IN;\r
+typedef struct\r
+{\r
+       GU8 nRespRate;\r
+       GU8 nBelieve;\r
+       GBOOL nRespOutFlag;\r
+}RESP_ST_DATA_OUT;\r
+extern GS32 RespProc(RESP_ST_DATA_IN* stRespDataIn, RESP_ST_DATA_OUT* stRespDataOut);\r
+extern GU8* RespAlgoVersion (void);\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_call/inc/goodix_spo2.h b/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_call/inc/goodix_spo2.h
new file mode 100644 (file)
index 0000000..28a898a
--- /dev/null
@@ -0,0 +1,179 @@
+#ifndef __GOODIX_SPO2_INTERFACE_H\r
+#define __GOODIX_SPO2_INTERFACE_H\r
+\r
+#include <stdint.h>\r
+#include "goodix_type.h"\r
+#include "gh3x2x_demo_algo_config.h"\r
+\r
+#if ((__GOODIX_SPO2_ALGO_VERISON__ == GOODIX_ALGO_BASIC) || (__GOODIX_SPO2_ALGO_VERISON__ == GOODIX_ALGO_MEDIUM))\r
+#define SPO2_INTERFACE_VERSION   "bas_pv_v1.0.0"\r
+#elif ((__GOODIX_SPO2_ALGO_VERISON__ == GOODIX_ALGO_PREMIUM) || (__GOODIX_SPO2_ALGO_VERISON__ == GOODIX_ALGO_EXCLUSIVE))\r
+#define SPO2_INTERFACE_VERSION   "pre_pv_v1.0.0"\r
+#endif\r
+#define SPO2_INTERFACE_VERSION_LEN_MAX  (20)\r
+#define CHIP_PPG_CHL_NUM                       (4)\r
+\r
+/**\r
+* @brief SPO2 Ëã·¨º¯Êý·µ»Ø×´Ì¬Öµ\r
+*/\r
+typedef enum\r
+{\r
+       GX_ALGO_SPO2_SUCCESS = 0x00000000,                      /**< ³É¹¦     */\r
+       GX_ALGO_SPO2_RWONG_INPUT = 0x00000001,          /**< ÊäÈëÊý¾Ý¸ñʽ²»ºÏ·¨     */\r
+       GX_ALGO_SPO2_NO_MEMORY = 0x00000002,        /**< ÄÚ´æ¿Õ¼ä²»¹»     */\r
+       GX_ALGO_SPO2_FRAME_UNCOMPLETE = 0x00000003, /**< ´¦ÓÚ½µ²ÉÑùƽ¾ù¹ý³ÌÖÐ*/\r
+       GX_ALGO_SPO2_WIN_UNCOMPLETE = 0x00000004,   /**< Î´µ½ÍêÕû»¬´°Ö¡Î»Öã¨ÕûÊýs£©     */\r
+       GX_ALGO_SPO2_UNEXPECTED = 0x00000005,       /*²»ºÏÉè¼ÆÂß¼­Òì³£ */\r
+       GX_ALGO_SPO2_CFG_ERROR = 0x00000006,        /*ÅäÖòÎÊýУÑ鲻ͨ¹ý*/\r
+       GX_ALGO_SPO2_INIT_FAILURE = 0x00000007,     /*³õʼ»¯Ê§°Ü*/\r
+}goodix_spo2_ret;\r
+\r
+typedef struct {\r
+    //raw ÅäÖÃÐÅÏ¢\r
+    uint32_t valid_chl_num;                    // ÓÐЧͨµÀÊý\r
+    uint32_t raw_fs;                       // Ô­Ê¼²ÉÑùÂÊ\r
+\r
+    int32_t cali_coef_a4;                      //У׼²ÎÊý4´ÎÏî\r
+    int32_t cali_coef_a3;                      //У׼²ÎÊý3´ÎÏî\r
+    int32_t cali_coef_a2;                      //У׼²ÎÊý2´ÎÏî\r
+    int32_t cali_coef_a1;                      //У׼²ÎÊý1´ÎÏî\r
+    int32_t cali_coef_a0;                      //У׼²ÎÊý³£ÊýÏî\r
+    //hbʹÄܱêÖ¾\r
+    uint32_t hb_en_flg;                                //hbʹÄܱêÖ¾\r
+    //Åå´÷״̬\r
+    uint32_t wear_mode;                                //Åå´÷״̬ 0:ÊÖ»·  1£ºÊÖÖ¸  2£º¶ú»ú\r
+    // acc move thr\r
+    uint32_t acc_thr_max;\r
+    uint32_t acc_thr_min;\r
+    uint32_t acc_thr_scale;\r
+    uint32_t acc_thr_num;\r
+    uint32_t acc_thr_angle;\r
+    //CTRÉèÖÃ\r
+    uint32_t ctr_en_flg;\r
+    uint32_t ctr_red_thr;\r
+\r
+    //ÐźÅÖÊÁ¿ÆÀ¹ÀÏà¹ØãÐÖµ\r
+    uint8_t ppg_jitter_thr;\r
+    uint8_t ppg_noise_thr;\r
+    uint8_t ppg_coeff_thr;\r
+    uint8_t quality_module_key;\r
+\r
+    //³öÖµ²ßÂÔ\r
+    uint8_t low_spo2_thr;\r
+    uint8_t fast_out_time;\r
+    uint8_t slow_out_time;\r
+    uint8_t min_stable_time_high;\r
+    uint8_t min_stable_time_low;\r
+    uint8_t max_spo2_variation_high;\r
+    uint8_t max_spo2_variation_low;\r
+    uint8_t ouput_module_key;\r
+}goodix_spo2_config;\r
+\r
+typedef struct\r
+{\r
+    uint32_t frameid;              // Ö¡ÐòºÅ\r
+    uint8_t bit_num;                // Êý¾ÝλÊý\r
+    uint8_t  ch_num;                // ¹àÈëÊý¾ÝµÄͨµÀÊý£¨1¸öͨµÀͬʱ°üº¬Â̹⡢ºìÍâ¡¢ºì¹âÊý¾Ý£©\r
+    int32_t *ppg_rawdata;                  // PPGԭʼÊý¾Ý£¬ÒÀ´ÎÂ̹â1234-ºìÍâ1234-ºì¹â1234\r
+    int8_t *cur_adj_flg;                   // µçÁ÷µ÷¹â±ê־룬 ÒÀ´ÎÂ̹â1234-ºìÍâ1234-ºì¹â1234\r
+    int8_t *gain_adj_flg;                  // ÔöÒæµ÷¹â±ê־룬 ÒÀ´ÎÂ̹â1234-ºìÍâ1234-ºì¹â1234\r
+    int8_t *enable_flg;                        // Í¨µÀʹÄܱê־룬 ÒÀ´ÎÂ̹â1234-ºìÍâ1234-ºì¹â1234\r
+    int32_t *ch_agc_drv0;                  // Çý¶¯µçÁ÷0-ÒÀ´ÎÂ̹â1234-ºìÍâ1234-ºì¹â1234\r
+    int32_t *ch_agc_drv1;                  // Çý¶¯µçÁ÷1-ÒÀ´ÎÂ̹â1234-ºìÍâ1234-ºì¹â1234\r
+    int8_t *ch_agc_gain;               // gainÖµ1-ÒÀ´ÎÂ̹â1234-ºìÍâ1234-ºì¹â1234\r
+    int32_t acc_x;                                 // ¼ÓËٶȼÆxÖá\r
+    int32_t acc_y;                                 // ¼ÓËٶȼÆyÖá\r
+    int32_t acc_z;                                 // ¼ÓËٶȼÆzÖá\r
+    int32_t wear_on_flag;                  // Åå´÷¼ì²â±êÖ¾\r
+}goodix_spo2_input_rawdata;\r
+\r
+typedef struct\r
+{\r
+    //**********************ËÄͨµÀÊä³ö×îÖÕÖµ***************************//\r
+    int32_t final_spo2;\r
+    int32_t final_valid_level;\r
+    int32_t final_confi_coeff;\r
+    int32_t final_WeightR;\r
+    int32_t final_hb_mean;\r
+    int32_t final_hb_confi_lvl;\r
+    int32_t final_invalidFlg;\r
+    int32_t final_piIR;\r
+    int32_t final_piRed;\r
+    int32_t final_snrIR;\r
+    int32_t final_snrRed;\r
+    int32_t final_r_val;\r
+    int32_t final_calc_flg;\r
+}goodix_spo2_result;\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+/**\r
+* @brief SPO2 ´¦ÀíËã·¨°æ±¾ºÅ\r
+* @param[in]  version     Íⲿ´¢´æ°æ±¾ºÅ¿Õ¼ä£¬·ÖÅä20×Ö½Ú\r
+* @param[out] ÎÞ\r
+* @return     º¯ÊýÖ´ÐÐÇé¿ö\r
+*/\r
+DRVDLL_API goodix_spo2_ret goodix_spo2_version(uint8_t version[150]);\r
+\r
+/**\r
+* @brief SPO2 ´¦ÀíËã·¨³õʼ»¯\r
+* @param[in]  cfg_instance   Íⲿ´«ÈëµÄÅäÖòÎÊý½á¹¹Ìå\r
+* @param[in]  cfg_size       ÅäÖýṹÌå´óС£¬ÓÃÓÚУÑéÍⲿ½Ó¿ÚÎļþÊÇ·ñ¶ÔÆë\r
+* @param[in]  interface_ver     ½Ó¿Ú°æ±¾ºÅ£¬ÓÃÓÚУÑéÍⲿ½Ó¿ÚÎļþÊÇ·ñ¶ÔÆë\r
+* @param[out] ÎÞ\r
+* @return     º¯ÊýÖ´ÐÐÇé¿ö\r
+*/\r
+DRVDLL_API goodix_spo2_ret goodix_spo2_init(const void *cfg_instance, int32_t cfg_size, char *interface_ver);\r
+\r
+/**\r
+* @brief SPO2 ÑªÑõ¼ÆËã\r
+* @param[in]  raw              ÊäÈëԭʼÊý¾Ý½á¹¹Ìå\r
+* @param[out] res              Êä³ö½á¹û½á¹¹Ìå\r
+* @return     º¯ÊýÖ´ÐÐÇé¿ö\r
+*/\r
+DRVDLL_API goodix_spo2_ret goodix_spo2_calc(goodix_spo2_input_rawdata* raw, goodix_spo2_result* res);\r
+\r
+\r
+/**\r
+* @brief ¹©¿Í»§µ÷ÊÔ¶ÔÆëʱµ÷Ó㬴òÓ¡Ëã·¨Æô¶¯ÔËÐкóµÄһЩ¹Ø¼ü±äÁ¿ÐÅÏ¢£¨ÔÚgoodix_spo2_calcºóµ÷Óã©\r
+* @param[in]  raw              ÊäÈëԭʼÊý¾Ý½á¹¹Ì壬NULL==rawdataʱ£¬²»´òÓ¡Êý¾ÝÐÅÏ¢\r
+* @param[out]              ÎÞ\r
+* @return               ÎÞ\r
+*/\r
+DRVDLL_API void goodix_spo2_essential_info_print(goodix_spo2_input_rawdata* raw_data);\r
+/**\r
+* @brief SPO2 Ëã·¨Ïú»Ù£¬ÊÍ·ÅÄÚ²¿µÄÄÚ´æ¿Õ¼ä£¬µ÷ÓÃÆäËûÄ£¿éË㷨ʱʹÓÃ\r
+* @param[out] ÎÞ\r
+* @return     º¯ÊýÖ´ÐÐÇé¿ö\r
+*/\r
+DRVDLL_API goodix_spo2_ret goodix_spo2_deinit(void);\r
+\r
+\r
+/**\r
+* @brief SPO2 ÅäÖòÎÊý»ñÈ¡£¬³õʼ»¯Ç°µ÷Ó㬵¼Èë´æ·ÅÅäÖýṹÌåÄÚÈݵÄÄÚ´æ\r
+* @param[out] ÎÞ\r
+* @return     Ö¸ÏòÅäÖýṹÌåʵÀýµÄÖ¸Õë\r
+*/\r
+const void *goodix_spo2_config_get_instance(void);\r
+\r
+/**\r
+* @brief SPO2 »ñÈ¡ÅäÖòÎÊý½á¹¹ÌåµÄÄÚ´æ¿Õ¼ä´óС£¬³õʼ»¯Ç°µ÷Óã¬ÓÃÓÚËã·¨ÄÚ²¿½øÐмìÑé\r
+* @param[out] ÎÞ\r
+* @return     ÅäÖòÎÊýÕ¼ÓõÄÄÚ´æ¿Õ¼ä´óС\r
+*/\r
+int32_t goodix_spo2_config_get_size(void);\r
+\r
+/**\r
+* @brief SPO2 »ñÈ¡½Ó¿ÚÎļþµÄ°æ±¾£¬³õʼ»¯Ç°µ÷Óã¬ÓÃÓÚËã·¨ÄÚ²¿½øÐмìÑ飨·ÀÖ¹Íⲿ±àÒëʱ½Ó¿ÚÎļþ¶¨Òåδ¶ÔÆë£©\r
+* @param[out] ÎÞ\r
+* @return     ÎÞ\r
+*/\r
+void goodix_spo2_config_get_version(char *ver, uint8_t ver_len);\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_call/inc/goodix_type.h b/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_call/inc/goodix_type.h
new file mode 100644 (file)
index 0000000..e35cd86
--- /dev/null
@@ -0,0 +1,104 @@
+/*\r
+ * @Author: penglei 1624952103@qq.com\r
+ * @Date: 2025-06-25 13:57:14\r
+ * @LastEditors: penglei 1624952103@qq.com\r
+ * @LastEditTime: 2025-06-25 15:23:36\r
+ * @FilePath: /FD230/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_call/inc/goodix_type.h\r
+ * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE\r
+ */\r
+#ifndef __GOODIX_TYPE\r
+#define __GOODIX_TYPE\r
+\r
+// 与零比较的公共阈值\r
+#ifndef EPS\r
+#define EPS            0.000001f\r
+#endif\r
+\r
+// 输出 lib 用\r
+#if _WIN32 || _WIN64\r
+#define  DRVDLL_API    extern  _declspec(dllexport)\r
+#else\r
+#define  DRVDLL_API\r
+#endif\r
+\r
+// 类型重定义\r
+#if _WIN32 || _WIN64\r
+typedef signed char                    int8_t;\r
+typedef short                          int16_t;\r
+typedef int                                    int32_t;\r
+typedef long long                      int64_t;\r
+typedef unsigned char          uint8_t;\r
+typedef unsigned short         uint16_t;\r
+typedef unsigned int           uint32_t;\r
+typedef unsigned long long     uint64_t;\r
+#else\r
+#include <stdint.h>\r
+#endif\r
+// #ifndef _ARM_MATH_H\r
+// typedef float                               float;\r
+// typedef double                              float64_t;\r
+// #endif\r
+\r
+// typedef unsigned char   GBOOL;\r
+// typedef          char   GCHAR;\r
+// typedef unsigned char   GUCHAR;\r
+// typedef signed   char   GS8;\r
+// typedef unsigned char   GU8;\r
+\r
+// typedef signed   short  GS16;\r
+// typedef unsigned short  GU16;\r
+\r
+// typedef signed   int                GS32;\r
+// typedef unsigned int                GU32;\r
+\r
+// typedef signed   long long  GS64;\r
+// typedef unsigned long long  GU64;\r
+\r
+// typedef          float              GF32;\r
+// typedef          double             GF64;\r
+// typedef long     double             GF128;\r
+\r
+#include <stddef.h>\r
+#include <string.h>\r
+\r
+typedef enum {\r
+       False = 0,\r
+       True = 1,\r
+}goodix_flag_e;\r
+\r
+// 当前点所处的状态:算法内部检测【目前输出 R 点】\r
+typedef enum {\r
+       // 输出值是否有效\r
+       stage_noneffect_out = 0,\r
+\r
+       // 默认值\r
+       stage_default,\r
+       \r
+\r
+       // 快速恢复相关\r
+       //stage_former_begin,\r
+       //stage_former_top,\r
+       //stage_former_downing,\r
+\r
+       // 波形特征点\r
+       stage_pqrst_p,\r
+       stage_pqrst_q,\r
+       stage_pqrst_r,\r
+       stage_pqrst_j,\r
+       stage_pqrst_j60,\r
+       stage_pqrst_s,\r
+       stage_pqrst_t_onset,\r
+       stage_pqrst_t,\r
+       stage_pqrst_t_offset,\r
+       stage_pqrst_u,\r
+}goodix_stage;\r
+\r
+// ECG信号病例分类标志\r
+typedef enum {\r
+       FLAG_NORMAL,                            // ECG信号检测为正常\r
+       FLAG_ATRIAL_FIBRILLATION,       // ECG信号检测为房颤\r
+       FLAG_OTHER,                                     // ECG信号检测为其它\r
+       FLAG_NOISE,                                     // ECG信号检测为噪声\r
+}goodix_classification_flag;\r
+\r
+#endif // !__GOODIX_TYPE\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_call/inc/iot_sys_def.h b/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_call/inc/iot_sys_def.h
new file mode 100644 (file)
index 0000000..a19902c
--- /dev/null
@@ -0,0 +1,164 @@
+/*\r
+* hrv_type_def.h\r
+*/\r
+\r
+#ifndef _GOODIX_IOT_SYS_TYPE_DEF_H_\r
+#define _GOODIX_IOT_SYS_TYPE_DEF_H_\r
+\r
+#include <stdint.h>\r
+#include <stddef.h>\r
+\r
+// typedef unsigned char                       GBOOL;\r
+// typedef          char                       GCHAR;\r
+// typedef unsigned char                       GUCHAR;\r
+// typedef signed   char                       GS8;\r
+// typedef unsigned char                       GU8;\r
+\r
+// typedef signed   short                      GS16;\r
+// typedef unsigned short                      GU16;\r
+\r
+// typedef signed   int                        GS32;\r
+// typedef unsigned int                        GU32;\r
+\r
+// typedef signed   long long          GS64;\r
+// typedef unsigned long long          GU64;\r
+\r
+// typedef          float                      GF32;\r
+// typedef          double                     GF64;\r
+// typedef long     double                     GF128;\r
+\r
+#if (_WIN32 || _WIN64)\r
+#define DEBUG_HRV  1\r
+#endif\r
+\r
+/* ��ӡ���� */\r
+#define IOT_SYS_DEBUG 1\r
+\r
+#if defined(_WIN32)    || defined(_WIN64)\r
+#define USE_MEMPOOL 1\r
+#else\r
+#define USE_MEMPOOL 0\r
+#endif\r
+#define UPDATEMEMINFO()\r
+#if defined(_WIN32)    || defined(_WIN64)\r
+\r
+#if USE_MEMPOOL\r
+#ifdef UPDATEMEMINFO()\r
+#undef UPDATEMEMINFO()\r
+#endif\r
+#include "goodix_memusage.h"\r
+#if DEBUG_MEMUSAGE\r
+#define IOT_SYS_REALLOC(p,x)    MEMSTAT_REALLOC(p,x)\r
+#define IOT_SYS_MALLOC(x)       MEMSTAT_MALLOC(x)\r
+#define IOT_SYS_FREE(x)         MEMSTAT_FREE(x)\r
+#define IOT_SYS_MEM_INIT(p,x)   GD_MEM_INIT((p),(x)); MEMSTAT_INIT(p);\r
+#define IOT_SYS_MEM_DESTORY()   GD_MEM_DESTORY();     MEMSTAT_COMP();\r
+#else\r
+#define IOT_SYS_MEM_INIT(p,x)   GD_MEM_INIT((p),(x));\r
+#define IOT_SYS_MEM_DESTORY()   GD_MEM_DESTORY();\r
+#define IOT_SYS_MALLOC(x)       GD_MEM_MALLOC(x)\r
+#define IOT_SYS_FREE(x)         GD_MEM_FREE(x)\r
+#define IOT_SYS_REALLOC(p,x)    GD_MEM_REALLOC(p,x)\r
+#endif\r
+\r
+#else  //USE_MEMPOOL\r
+#include <malloc.h>\r
+#ifndef IOT_SYS_MALLOC\r
+#define IOT_SYS_MALLOC         malloc\r
+#endif\r
+#ifndef IOT_SYS_FREE\r
+#define IOT_SYS_FREE                   free\r
+#endif\r
+#endif //!USE_MEMPOOL\r
+\r
+#ifndef IOT_SYS_DLL_API\r
+#define IOT_SYS_DLL_API                    extern _declspec(dllexport)\r
+#endif\r
+\r
+#if IOT_SYS_DEBUG\r
+#include <stdio.h>\r
+#ifndef IOT_SYS_PRINT\r
+#define IOT_SYS_PRINT                  printf\r
+#endif\r
+#endif\r
+\r
+#elif defined(__linux__) || defined(ANDROID)\r
+#include <malloc.h>\r
+#ifndef IOT_SYS_MALLOC\r
+#define IOT_SYS_MALLOC         malloc\r
+#endif\r
+#ifndef IOT_SYS_FREE\r
+#define IOT_SYS_FREE           free\r
+#endif\r
+#ifndef IOT_SYS_DLL_API\r
+#define IOT_SYS_DLL_API\r
+#endif\r
+\r
+#ifndef __ANDROID_NATIVE__ // for app\r
+#include <android/log.h>\r
+#ifndef IOT_SYS_LOG_TAG\r
+#define IOT_SYS_LOG_TAG "IoTSys"\r
+#ifndef IOT_SYS_PRINT\r
+#define IOT_SYS_PRINT(...)     __android_log_print(ANDROID_LOG_DEBUG, IOT_SYS_LOG_TAG, __VA_ARGS__)\r
+#endif\r
+#endif\r
+#else // for exe on cell phone\r
+#ifndef IOT_SYS_PRINT\r
+#define IOT_SYS_PRINT          printf\r
+#endif\r
+#endif\r
+\r
+#else\r
+/*\r
+* Roma-II\r
+*/\r
+//extern void *GmAlgMemMalloc(GU32 unSize);\r
+//extern void GmAlgMemFree(void *pmemaddr);\r
+//\r
+//#define IOT_SYS_MALLOC(x)            GmAlgMemMalloc((x))\r
+//#define IOT_SYS_FREE(p)                      GmAlgMemFree((p))\r
+//#define IOT_SYS_DLL_API\r
+\r
+/*\r
+* Cardiff\r
+*/\r
+extern void* goodix_mem_malloc(int32_t size);\r
+extern void goodix_mem_free(void* mem_addr);\r
+\r
+#ifndef IOT_SYS_MALLOC\r
+#define IOT_SYS_MALLOC(x)              goodix_mem_malloc((x))\r
+#endif\r
+#ifndef IOT_SYS_FREE\r
+#define IOT_SYS_FREE(p)                        goodix_mem_free((p))\r
+#endif\r
+#ifndef IOT_SYS_DLL_API\r
+#define IOT_SYS_DLL_API\r
+#endif\r
+\r
+#if IOT_SYS_DEBUG\r
+/* extern log function */\r
+extern void GH3X2X_PlatformLog(char *chLogString);\r
+\r
+/// log support len\r
+#define GH3X2X_LOG_DEBUG_SUP_LEN     (128)\r
+\r
+/// log string with param\r
+#define   GH3X2X_DEBUG_LOG_PARAM(...)       do {\\r
+                                                char chDebugStr[GH3X2X_LOG_DEBUG_SUP_LEN] = {0};\\r
+                                                snprintf(chDebugStr, GH3X2X_LOG_DEBUG_SUP_LEN, \\r
+                                                        "[gh3x2x_drv]: "__VA_ARGS__);\\r
+                                                GH3X2X_PlatformLog(chDebugStr);\\r
+                                            } while (0)\r
+\r
+#ifndef IOT_SYS_PRINT\r
+#define IOT_SYS_PRINT          GH3X2X_DEBUG_LOG_PARAM\r
+#endif\r
+#endif\r
+\r
+#endif\r
+\r
+// ����궨��\r
+#define SINGLE_PRECISION_SUPPORT       // ����ɿ�ʱʹ�ܣ���VS�����У�Ӱ�� LMS_FILTER_STEP_FACTOR������VS��MCU�Բ���\r
+\r
+/********END OF FILE********* (C) COPYRIGHT 2015-2025 .********/\r
+#endif  //_GOODIX_IOT_SYS_TYPE_DEF_H_\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_call/src/gh3x2x_demo_algo_call_adt.c b/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_call/src/gh3x2x_demo_algo_call_adt.c
new file mode 100644 (file)
index 0000000..9f6ccc7
--- /dev/null
@@ -0,0 +1,154 @@
+#include <stdio.h>\r
+#include "gh3x2x_demo_algo_call.h"\r
+#include "gh3x2x_demo_algorithm_calc.h"\r
+#include "gh3x2x_demo_algo_config.h"\r
+\r
+#if (__USE_GOODIX_ADT_ALGORITHM__)\r
+\r
+#define __HARD_ADT_WAER_ON_THRD__               9000000\r
+#define __HARD_ADT_WAER_OFF_THRD__              8800000\r
+#define __HARD_ADT_WAER_ON_DIFF_THRD__          -8000000\r
+#define __HARD_ADT_WAER_BIG_DIFF__              30000\r
+#define GH3X2X_MOVINF_AVA_WINDOW_SIZE           6\r
+\r
+static EMWearDetectType g_emAlgoWearStatus = WEAR_DETECT_WEAR_ON;\r
+static GU32 g_punGh3x2xMovingAvaFilterBuf[GH3X2X_MOVINF_AVA_WINDOW_SIZE];\r
+static GU8  g_uchGh3x2xMovingAvaFilterPointCnt;\r
+\r
+\r
+\r
+void Gh3x2xMovingAvaFilterInit(void)\r
+{\r
+    g_uchGh3x2xMovingAvaFilterPointCnt = 0;\r
+}\r
+\r
+GU8 Gh3x2xMovingAvaFilter(GU32 *Rawdata, GU8 uchBypass)\r
+{\r
+    GU32 unSum = 0;\r
+\r
+    if(uchBypass)\r
+    {\r
+        return 1;\r
+    }\r
+    else\r
+    {\r
+        if(g_uchGh3x2xMovingAvaFilterPointCnt >= GH3X2X_MOVINF_AVA_WINDOW_SIZE)\r
+        {\r
+            for(GU8 uchCnt = 1; uchCnt < GH3X2X_MOVINF_AVA_WINDOW_SIZE; uchCnt ++)\r
+            {\r
+                g_punGh3x2xMovingAvaFilterBuf[uchCnt - 1] = g_punGh3x2xMovingAvaFilterBuf[uchCnt];\r
+            }\r
+            g_uchGh3x2xMovingAvaFilterPointCnt = GH3X2X_MOVINF_AVA_WINDOW_SIZE - 1;\r
+        }\r
+        g_punGh3x2xMovingAvaFilterBuf[g_uchGh3x2xMovingAvaFilterPointCnt] = Rawdata[0];\r
+        g_uchGh3x2xMovingAvaFilterPointCnt ++;\r
+            \r
+        if(g_uchGh3x2xMovingAvaFilterPointCnt > 1)\r
+        {\r
+            for(GU8 uchCnt = 0; uchCnt < g_uchGh3x2xMovingAvaFilterPointCnt - 1; uchCnt ++)\r
+            {\r
+                unSum += g_punGh3x2xMovingAvaFilterBuf[uchCnt];\r
+            }\r
+            Rawdata[0] = unSum/(g_uchGh3x2xMovingAvaFilterPointCnt - 1);\r
+        }\r
+        return 1;\r
+    }\r
+}\r
+\r
+#define ADT_CHECK_ALGO_VERSION "GX_HARDADT_SOFTCHECK_v0.1"\r
+\r
+GU8* GH3x2xAdtVersion (void)\r
+{\r
+    return (GU8*)ADT_CHECK_ALGO_VERSION;\r
+}\r
+\r
+GS8  GH3x2xAdtAlgoInit(const STGh3x2xFrameInfo * const pstFrameInfo)\r
+{\r
+    Gh3x2xMovingAvaFilterInit();\r
+    g_emAlgoWearStatus = WEAR_DETECT_WEAR_ON;\r
+    return GH3X2X_RET_OK;\r
+}\r
+\r
+GS8 GH3x2xAdtAlgoDeinit(const STGh3x2xFrameInfo * const pstFrameInfo)\r
+{\r
+    Gh3x2xMovingAvaFilterInit();\r
+    g_emAlgoWearStatus = WEAR_DETECT_WEAR_ON;\r
+    return GH3X2X_RET_OK;\r
+}\r
+\r
+GS8 GH3x2xAdtAlgoExe(const STGh3x2xFrameInfo * const pstFrameInfo)\r
+{\r
+    GU32 unCurrentFrameRawdata = 0;\r
+    GS32 snDiffRawdata = 0;\r
+    GU32 unRawDataBeforeFilter = 0;\r
+\r
+    unCurrentFrameRawdata = pstFrameInfo->punFrameRawdata[0];\r
+    unRawDataBeforeFilter = pstFrameInfo->punFrameRawdata[0];\r
+    GH3X2X_DEBUG_ALGO_LOG("[GH3x2xAdtAlgoExe]:punFrameRawdata = %d\r\n", unCurrentFrameRawdata);\r
+    Gh3x2xMovingAvaFilter(&unCurrentFrameRawdata, 0);\r
+    GH3X2X_DEBUG_ALGO_LOG("[GH3x2xAdtAlgoExe]:punFrameRawdata after filter = %d\r\n", unCurrentFrameRawdata);\r
+    GH3X2X_DEBUG_ALGO_LOG("[GH3x2xAdtAlgoExe]:g_emAlgoWearStatus = %d, start check...\r\n",g_emAlgoWearStatus);\r
+\r
+    snDiffRawdata = (GS32)unRawDataBeforeFilter - (GS32)unCurrentFrameRawdata;\r
+    pstFrameInfo->pstAlgoResult->snResult[0] = ADT_ALGO_RESULT_DEFULT;\r
+\r
+\r
+    if(WEAR_DETECT_WEAR_ON == g_emAlgoWearStatus)\r
+    {\r
+        #if (__HARD_ADT_WAER_OFF_THRD__ > __HARD_ADT_WAER_ON_THRD__)   //penetration model\r
+        if(unRawDataBeforeFilter < __HARD_ADT_WAER_ON_THRD__)\r
+        #else  //reflex model\r
+        if((unRawDataBeforeFilter > __HARD_ADT_WAER_ON_THRD__)&&((snDiffRawdata > (GS32)__HARD_ADT_WAER_ON_DIFF_THRD__)))\r
+        #endif\r
+        {\r
+            g_emAlgoWearStatus = WEAR_DETECT_WEAR_OFF;\r
+            GH3X2X_INFO_ALGO_LOG("[GH3x2xAdtAlgoExe]:wear on event, Rawdata = %d, unRawdataDiff = %d\r\n",unCurrentFrameRawdata,snDiffRawdata);\r
+            pstFrameInfo->pstAlgoResult->uchUpdateFlag = 1;\r
+            pstFrameInfo->pstAlgoResult->snResult[0] = ADT_ALGO_RESULT_WAER_ON;\r
+        }\r
+        else\r
+        {\r
+            #if (__HARD_ADT_WAER_OFF_THRD__ > __HARD_ADT_WAER_ON_THRD__)  //penetration model\r
+            #else  //reflex model\r
+            if(unRawDataBeforeFilter > __HARD_ADT_WAER_ON_THRD__)\r
+            {\r
+                GH3X2X_INFO_ALGO_LOG("[GH3x2xAdtAlgoExe]:wear on condition is not match ! r = %d, r_diff = %d\r\n",unCurrentFrameRawdata,snDiffRawdata);\r
+            }\r
+            #endif\r
+        }\r
+        #if (__HARD_ADT_WAER_OFF_THRD__ > __HARD_ADT_WAER_ON_THRD__)  //penetration model\r
+        #else  //reflex model\r
+        if(snDiffRawdata > __HARD_ADT_WAER_BIG_DIFF__)\r
+        {\r
+            //pstFrameInfo->pstAlgoResult->uchUpdateFlag = 1;\r
+            //pstFrameInfo->pstAlgoResult->snResult[0] = ADT_ALGO_RESULT_DIFF_BIG;\r
+            GH3X2X_INFO_ALGO_LOG("[GH3x2xAdtAlgoExe]:ppg 5Hz diff big event, Rawdata = %d, unRawdataDiff = %d\r\n",unCurrentFrameRawdata,snDiffRawdata);\r
+        }\r
+        #endif\r
+    }\r
+    else if(WEAR_DETECT_WEAR_OFF == g_emAlgoWearStatus)\r
+    {\r
+        #if (__HARD_ADT_WAER_OFF_THRD__ > __HARD_ADT_WAER_ON_THRD__)  //penetration model\r
+        if(unRawDataBeforeFilter > __HARD_ADT_WAER_OFF_THRD__)\r
+        #else  //reflex model\r
+        if(unRawDataBeforeFilter < __HARD_ADT_WAER_OFF_THRD__)\r
+        #endif\r
+        {\r
+            g_emAlgoWearStatus = WEAR_DETECT_WEAR_ON;\r
+            GH3X2X_INFO_ALGO_LOG("[GH3x2xAdtAlgoExe]:wear off event, Rawdata = %d, unRawdataDiff = %d\r\n",unCurrentFrameRawdata,snDiffRawdata);\r
+            pstFrameInfo->pstAlgoResult->uchUpdateFlag = 1;\r
+            pstFrameInfo->pstAlgoResult->snResult[0] = ADT_ALGO_RESULT_WAER_OFF;\r
+        }\r
+    }\r
+\r
+    pstFrameInfo->pstAlgoResult->usResultBit = 0x7;\r
+    pstFrameInfo->pstAlgoResult->uchResultNum = GH3x2x_BitCount(pstFrameInfo->pstAlgoResult->usResultBit);\r
+    pstFrameInfo->pstAlgoResult->snResult[1] = snDiffRawdata;\r
+    pstFrameInfo->pstAlgoResult->snResult[2] = pstFrameInfo->punFrameCnt[0];\r
+    GH3X2X_AdtAlgorithmResultReport(pstFrameInfo->pstAlgoResult, pstFrameInfo->punFrameCnt[0]);\r
+\r
+    return GH3X2X_RET_OK;\r
+}\r
+\r
+#endif\r
+\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_call/src/gh3x2x_demo_algo_call_af.c b/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_call/src/gh3x2x_demo_algo_call_af.c
new file mode 100644 (file)
index 0000000..3fc2c65
--- /dev/null
@@ -0,0 +1,124 @@
+#include <stdio.h>\r
+#include "gh3x2x_demo_algo_call.h"\r
+#include "gh3x2x_demo_algorithm_calc.h"\r
+#include "gh3x2x_demo_algo_config.h"\r
+#include "goodix_hba.h"\r
+#include "goodix_hrv.h"\r
+#include "goodix_af.h"\r
+\r
+#if (__USE_GOODIX_HRV_ALGORITHM__ && __USE_GOODIX_AF_ALGORITHM__)\r
+\r
+extern GU32 g_unHrvLastHrResult;\r
+extern goodix_hrv_ret goodix_hrv_init_func(GU32 fs);\r
+extern goodix_hrv_ret goodix_hrv_deinit_func(void);\r
+\r
+GS8 GH3x2xAfAlgoInit(const STGh3x2xFrameInfo * const pstFrameInfo)\r
+{\r
+    GS8 chRet = GH3X2X_RET_GENERIC_ERROR;\r
+\r
+    GH3X2X_DEBUG_ALGO_LOG("%s\r\n", __FUNCTION__);    \r
+    for (GU8 uchChMapCnt = 0; uchChMapCnt < g_pstGh3x2xAlgoFrameInfo[GH3X2X_FUNC_OFFSET_AF]->pstFunctionInfo->uchChnlNum; ++uchChMapCnt)\r
+    {\r
+        g_pstGh3x2xAlgoFrameInfo[GH3X2X_FUNC_OFFSET_RESP]->puchFrameLastGain[uchChMapCnt] = GH3X2X_GAIN_VALUE_INVALID;\r
+    }\r
+    GH3X2X_INFO_ALGO_LOG("[%s]:params = %d,\r\n", __FUNCTION__, g_nAfParamsArr[0]);\r
+    if ((AFInit((GS32)g_nAfParamsArr[0]) == GX_ALGO_HBA_SUCCESS) &&\\r
+        (goodix_hrv_init_func(pstFrameInfo ->pstFunctionInfo ->usSampleRate) == GX_ALGO_HBA_SUCCESS))\r
+    {\r
+        pstFrameInfo->pstAlgoResult->usResultBit = 0xFF;\r
+        chRet = GH3X2X_RET_OK;\r
+    }\r
+    else\r
+    {\r
+        GH3X2X_DEBUG_ALGO_LOG("af deinit error!\r\n");\r
+    }\r
+    g_unHrvLastHrResult = 0;\r
+    return chRet;\r
+}\r
+\r
+GS8 GH3x2xAfAlgoDeinit(const STGh3x2xFrameInfo * const pstFrameInfo)\r
+{\r
+    GS8 chRet = GH3X2X_RET_GENERIC_ERROR;\r
+\r
+\r
+    GH3X2X_DEBUG_ALGO_LOG("%s\r\n", __FUNCTION__);\r
+    if ((goodix_hrv_deinit_func() == GX_ALGO_HBA_SUCCESS) && (AFDeInit() == GX_ALGO_HBA_SUCCESS))\r
+    {\r
+        chRet = GH3X2X_RET_OK;\r
+    }\r
+    else\r
+    {\r
+        GH3X2X_DEBUG_ALGO_LOG("af deinit error!\r\n");\r
+    }\r
+    return chRet;\r
+}\r
+\r
+GS8 GH3x2xAfAlgoExe(const STGh3x2xFrameInfo * const pstFrameInfo)\r
+{\r
+    if(0 == pstFrameInfo )\r
+    {\r
+        return GH3X2X_RET_GENERIC_ERROR;\r
+    }\r
+    GU32 unResult[3] = {0};\r
+    GS32 nOutputData[6]   = {0};\r
+    GS32 nAfInputData[6] = {0};\r
+    ST_HRV_INPUT_INFO siRawdataInput;\r
+    memset((GU8*)&siRawdataInput, 0, sizeof(ST_HRV_INPUT_INFO));\r
+    GU8 uchGainValue = 0;\r
+\r
+    for (int nRawdatacnt = 0 ; nRawdatacnt< HRV_CHNL_MAX_NUM ; nRawdatacnt ++)\r
+    {\r
+        siRawdataInput.ppg_green[nRawdatacnt] = GH3X2X_RAWDATA_CLEAR_ALL_FLAG(pstFrameInfo->punFrameRawdata[nRawdatacnt]);\r
+        siRawdataInput.ppg_green[nRawdatacnt] = GH3X2X_GET_RAWDATA_FOR_ALGO(siRawdataInput.ppg_green[nRawdatacnt]);\r
+        uchGainValue = GH3X2X_GET_LOW_4BITS(pstFrameInfo->punFrameAgcInfo[nRawdatacnt]);\r
+        if ((pstFrameInfo->puchFrameLastGain[nRawdatacnt] != uchGainValue) && \\r
+            (pstFrameInfo->puchFrameLastGain[nRawdatacnt] != GH3X2X_GAIN_VALUE_INVALID))\r
+        {\r
+            siRawdataInput.green_gain_adj_flag[nRawdatacnt] = 1;\r
+            pstFrameInfo->puchFrameLastGain[nRawdatacnt] = uchGainValue;\r
+        }\r
+            \r
+        siRawdataInput.green_cur_adj_flag[nRawdatacnt] = ((pstFrameInfo->punFrameFlag[0]) & 0x01);\r
+    }\r
+    siRawdataInput.acc_x = pstFrameInfo->pusFrameGsensordata[0];\r
+    siRawdataInput.acc_y = pstFrameInfo->pusFrameGsensordata[1];\r
+    siRawdataInput.acc_z = pstFrameInfo->pusFrameGsensordata[2];\r
+    siRawdataInput.frame_id = GH3X2X_GET_BYTE0_FROM_DWORD(*(pstFrameInfo->punFrameCnt));\r
+    if (g_pstGh3x2xAlgoFrameInfo[GH3X2X_FUNC_OFFSET_HR]->pstAlgoRecordResult->uchUpdateFlag)\r
+    {\r
+        g_unHrvLastHrResult = g_pstGh3x2xAlgoFrameInfo[GH3X2X_FUNC_OFFSET_HR]->pstAlgoRecordResult->snResult[0];\r
+    }\r
+    siRawdataInput.hr = g_unHrvLastHrResult;\r
+    \r
+    GU8 uchHrvUpdateFlag = HRVCalculateAlgo(&siRawdataInput, nOutputData);\r
+\r
+    if (uchHrvUpdateFlag && (nOutputData[5] != 0))\r
+    {\r
+        for (int i = 0 ; i < 6 ; i ++)\r
+        {\r
+            nAfInputData[i] = nOutputData[i];\r
+        }\r
+\r
+        pstFrameInfo->pstAlgoResult->uchUpdateFlag = AF_Detection_Module(nAfInputData, unResult);\r
+\r
+        if(pstFrameInfo->pstAlgoResult->uchUpdateFlag == 1)\r
+        {\r
+            pstFrameInfo->pstAlgoResult->snResult[0] = (GS32)unResult[0];\r
+            pstFrameInfo->pstAlgoResult->snResult[1] = (GS32)unResult[1];\r
+            pstFrameInfo->pstAlgoResult->snResult[2] = (GS32)unResult[2];\r
+            pstFrameInfo->pstAlgoResult->snResult[3] = (GS32)nOutputData[0];\r
+            pstFrameInfo->pstAlgoResult->snResult[4] = (GS32)nOutputData[1];\r
+            pstFrameInfo->pstAlgoResult->snResult[5] = (GS32)nOutputData[2];\r
+            pstFrameInfo->pstAlgoResult->snResult[6] = (GS32)nOutputData[3];\r
+            pstFrameInfo->pstAlgoResult->snResult[7] = (GS32)nOutputData[4];\r
+            pstFrameInfo->pstAlgoResult->usResultBit = 0xFF;\r
+            pstFrameInfo->pstAlgoResult->uchResultNum = GH3x2x_BitCount(pstFrameInfo->pstAlgoResult->usResultBit);\r
+            GH3X2X_DEBUG_ALGO_LOG("[%s]af = %d,UpdateFlag = %d\r\n",__FUNCTION__,(int)pstFrameInfo->pstAlgoResult->snResult[0],(int)pstFrameInfo->pstAlgoResult->uchUpdateFlag);\r
+            //GH3X2X_HrAlgorithmResultReport(pstFrameInfo->pstAlgoResult,stRawdata.frameid);\r
+        }\r
+    }\r
+    return GH3X2X_RET_OK;\r
+}\r
+\r
+#endif\r
+\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_call/src/gh3x2x_demo_algo_call_bt.c b/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_call/src/gh3x2x_demo_algo_call_bt.c
new file mode 100644 (file)
index 0000000..2e1d806
--- /dev/null
@@ -0,0 +1,293 @@
+#include "gh3x2x_demo_algorithm_calc.h"\r
+#include "gh3x2x_demo_algo_call.h"\r
+#include "goodix_mem.h"\r
+#include "goodix_algo.h"\r
+#include "goodix_algo_bt.h"\r
+\r
+#if (__USE_GOODIX_BT_ALGORITHM__)\r
+\r
+#define NTCSecondResult  0\r
+\r
+/*****体温全局变量*****/\r
+//NTC R-T table\r
+#define NTC_TYPE  CB62K552D\r
+#if (CB62K928D==NTC_TYPE)\r
+GU16 RT_Table[] = {25992,24742,23559,22437,21375,20367,19413,18507,17648,16833,16060,15325,14628,13965,13336,12738,12169,11629,11115,10625,10160,9717,9295,8894,8512,8147,7800,7469,7154,6853,6566,6293,6032,5783,5545,5318,5101,4894,4696,4507};\r
+#elif(CB62K552D==NTC_TYPE)\r
+GU16 RT_Table[] = {25837,24594,23418,22303,21247,20246,19297,18397,17543,16733,15964,15234,14540,13882,13256,12662,12097,11559,11048,10562,10099,9659,9240,8841,8461,8099,7754,7425,7111,6812,6527,6255,5996,5748,5512,5286,5071,4865,4668,4480};\r
+#elif(DT104D3950==NTC_TYPE)\r
+GU16 RT_Table[] = {26630,25340,24130,22980,21890,20850,19880,18950,18070,17240,16450,15700,14990,14320,13680,13070,12490,11940,11420,10920,10450,10000,9572,9165,8777,8408,8056,7720,7401,7096,6805,6528,6263,6011,5769,5539,5319,5109,4908,4717};\r
+#endif\r
+GU16 unSensorNtcRT_Len = sizeof(RT_Table)/sizeof(RT_Table[0]);\r
+GU16 unSensorNtcRef = 3000; // NTC ref resistance (unit : 10ohm)\r
+GS16 unTempRangeLower = 4*100;\r
+GS16 unTempRangeUpper = 43*100;\r
+GU8 unNTCChnalRes = 156;\r
+GU32 g_unBtLastHrResult = 0;\r
+GU16 uFs =0;\r
+\r
+#if !__USE_GOODIX_DRV_NTC_Convert\r
+STGoodixAlgorithmBtControlConfigParametersBuffer gstBtCFG;\r
+STGoodixAlgorithmBtInputRef                      gstBtInputRef;\r
+STGoodixAlgorithmBtCalculateOutputResult         gstBtAlgoOUT;\r
+//STGoodixAlgorithmBtFinalOutputResult             gstBtAlgoFinal;\r
+STGoodixAlgorithmInfo                            gstBtAlgoInfo;\r
+/**\r
+ * @brief memory malloc function\r
+ * @param size\r
+ * @return pointer of memory\r
+*/\r
+void* GoodixSensorAlgoMalloc(GS32 size)\r
+{\r
+    return goodix_mem_malloc(size);\r
+}\r
+\r
+/**\r
+ * @brief memory free function\r
+ * @param addr\r
+*/\r
+void GoodixSensorAlgoFree(void* addr)\r
+{\r
+    goodix_mem_free(addr);\r
+}\r
+\r
+/**\r
+ * @brief algorithm log function\r
+ * @param addr\r
+*/\r
+void GoodixSensorAlgoLog(GCHAR* pLogStr)\r
+{\r
+    //GH3X2X_DEBUG_ALGO_LOG("[%s]:%s\n", __FUNCTION__, pLogStr);\r
+}\r
+\r
+#else\r
+STGH3x2xDrvBtOutputResult                        gstDrvBtOutRes;\r
+\r
+GU16 GetRTIndex(GS32 R, GU16* pR, GU16 len)\r
+{\r
+       GU16 i =0;\r
+       while(R <= pR[i]*10)\r
+       {\r
+               i++;\r
+               if(len == i)\r
+               {\r
+                       i = 0xFFFF;\r
+                       break;\r
+               }\r
+       }\r
+       return i;\r
+}\r
+\r
+/**\r
+ * @fn   GS16 GH3x2xBtRTConvert(GS32* pnRawdata,STGH3x2xDrvBtOutputResult* pstDrvBtOutRes)\r
+ *\r
+ * @brief  calc byte check rawdata\r
+ *\r
+ * @attention\r
+ *\r
+ * @param[in]   punRawdata  one rawdata addr IDEL REF NTC0 NTC1\r
+ * @param[out]  None\r
+ *\r
+ * @return  target rawdata\r
+ */\r
+static GS16 GH3x2xBtRTConvert(GS32* pnRawdata,STGH3x2xDrvBtOutputResult* pstDrvBtOutRes)\r
+{\r
+       GU8 uchIdx = 0;\r
+       GU16 uRTIdx =0;\r
+       GS32 nRestemp0, nRestemp1;\r
+       GS16 nRawTemp =0;\r
+       GU8 chRet=0;\r
+\r
+       for(uchIdx=0;uchIdx <BT_MAX_CH_NUM;uchIdx++)\r
+       {\r
+               nRestemp0 = pnRawdata[1] - pnRawdata[0]; // ref - idle\r
+               nRestemp1 = pnRawdata[2+ uchIdx] - pnRawdata[0]; // ntc - idle\r
+               if(0==nRestemp1)\r
+               {\r
+                       GH3X2X_DEBUG_ALGO_LOG("BT input rawdata error: ZERO! \r\n");\r
+                       nRawTemp = 0;\r
+                       chRet = EM_TEMP_OUT_RANGE_WRONG_INPUT;\r
+               }\r
+               else\r
+               {\r
+                       nRestemp0 = ((GS64)nRestemp0 * (unSensorNtcRef*10 + unNTCChnalRes)) / nRestemp1 - unNTCChnalRes;\r
+                       if(nRestemp0<0)\r
+                       {\r
+                               GH3X2X_DEBUG_ALGO_LOG("BT input rawdata error: NEGATIVE! \r\n");\r
+                               nRawTemp = 0;\r
+                               chRet = EM_TEMP_OUT_RANGE_WRONG_INPUT;\r
+                       }\r
+                       else\r
+                       {\r
+                               uRTIdx = GetRTIndex(nRestemp0,RT_Table,unSensorNtcRT_Len);\r
+                               if(0 == uRTIdx)\r
+                               {\r
+                                       nRawTemp = 0;\r
+                                       chRet = EM_TEMP_OUT_RANGE_L;\r
+                               }\r
+                               else if(0xFFFF == uRTIdx)\r
+                               {\r
+                                       nRawTemp = 0;\r
+                                       chRet = EM_TEMP_OUT_RANGE_H;\r
+                               }\r
+                               else\r
+                               {\r
+                                       nRawTemp = (GS16)(100*(RT_Table[uRTIdx-1]*10 - nRestemp0)/(RT_Table[uRTIdx-1]*10-RT_Table[uRTIdx]*10)) + (GS16) unTempRangeLower + (GS16)(uRTIdx-1)*100;\r
+                               }\r
+                       }\r
+               }\r
+               pstDrvBtOutRes->nFrameTemperature[uchIdx] = nRawTemp;\r
+               if(0 == pstDrvBtOutRes->chFrameIndex)\r
+               {\r
+                       pstDrvBtOutRes->stRawTemp[uchIdx].nMin = nRawTemp;\r
+                       pstDrvBtOutRes->stRawTemp[uchIdx].nMax = nRawTemp;\r
+                       pstDrvBtOutRes->stRawTemp[uchIdx].nSum = nRawTemp;\r
+                       GH3X2X_DEBUG_ALGO_LOG("[%s]:index: %d rawdata sum %d: %d \n", __FUNCTION__,pstDrvBtOutRes->chFrameIndex,uchIdx, pstDrvBtOutRes->stRawTemp[uchIdx].nSum);\r
+               }\r
+               else\r
+               {\r
+                       pstDrvBtOutRes->stRawTemp[uchIdx].nMin = (pstDrvBtOutRes->stRawTemp[uchIdx].nMin>nRawTemp)?nRawTemp:pstDrvBtOutRes->stRawTemp[uchIdx].nMin;\r
+                       pstDrvBtOutRes->stRawTemp[uchIdx].nMax = (pstDrvBtOutRes->stRawTemp[uchIdx].nMax<nRawTemp)?nRawTemp:pstDrvBtOutRes->stRawTemp[uchIdx].nMax;\r
+                       pstDrvBtOutRes->stRawTemp[uchIdx].nSum += nRawTemp;\r
+                       GH3X2X_DEBUG_ALGO_LOG("[%s]:index: %d rawdata sum %d: %d \n", __FUNCTION__,pstDrvBtOutRes->chFrameIndex,uchIdx, pstDrvBtOutRes->stRawTemp[uchIdx].nSum);\r
+               }\r
+       }\r
+       ++pstDrvBtOutRes->chFrameIndex;\r
+       if(pstDrvBtOutRes->chFrameIndex == uFs)\r
+       {\r
+               pstDrvBtOutRes->chFrameIndex=0;\r
+               for(uchIdx=0;uchIdx <BT_MAX_CH_NUM;uchIdx++)\r
+               {\r
+                       if(chRet)\r
+                       {\r
+                               pstDrvBtOutRes->nSecTemperature[uchIdx] = 0;\r
+                       }\r
+                       else\r
+                       {\r
+                               if(uFs>2)\r
+                               {\r
+                                       GH3X2X_DEBUG_ALGO_LOG("[%s]:rawdata sum: %d \n", __FUNCTION__, pstDrvBtOutRes->stRawTemp[uchIdx].nSum);\r
+                                       pstDrvBtOutRes->nSecTemperature[uchIdx] = (pstDrvBtOutRes->stRawTemp[uchIdx].nSum - pstDrvBtOutRes->stRawTemp[uchIdx].nMin - pstDrvBtOutRes->stRawTemp[uchIdx].nMax +((uFs-2)>>1))/(uFs-2);\r
+                               }\r
+                               else\r
+                               {\r
+                                       pstDrvBtOutRes->nSecTemperature[uchIdx] = (pstDrvBtOutRes->stRawTemp[uchIdx].nMin + pstDrvBtOutRes->stRawTemp[uchIdx].nMax)>>1;\r
+                               }\r
+                               chRet = EM_CONVER_OK;\r
+                       }\r
+               }\r
+       }\r
+\r
+       return chRet;\r
+}\r
+#endif\r
+\r
+GS8 GH3x2xBtAlgoInit(const STGh3x2xFrameInfo * const pstFrameInfo)\r
+{\r
+       #if !__USE_GOODIX_DRV_NTC_Convert\r
+    //gstBtAlgoInfo.stAlgorithmConfig.pnParametersBuffer = &gstBtCFG;\r
+    gstBtAlgoInfo.stAlgorithmCalcOutput.pnResult = &gstBtAlgoOUT;\r
+    gstBtAlgoInfo.stAlgorithmCalcInput.pnRefBuffer = &gstBtInputRef;\r
+    gstBtCFG.unChannelNum = 2;\r
+\r
+    if(BT_ERRORCODE_OK != GoodixBtAlgoInit(&gstBtAlgoInfo))\r
+    {\r
+        return GH3X2X_RET_GENERIC_ERROR;\r
+    }\r
+\r
+    pstFrameInfo->pstAlgoResult->usResultBit = 0x1F;\r
+    g_unBtLastHrResult = 0;\r
+       uFs = pstFrameInfo ->pstFunctionInfo ->usSampleRate;\r
+    GH3X2X_Memset(&gstBtAlgoOUT, 0, sizeof(STGoodixAlgorithmBtCalculateOutputResult));\r
+    GH3X2X_Memset(&gstBtInputRef, 0, sizeof(STGoodixAlgorithmBtInputRef));\r
+       #else\r
+       //drv calculate bt\r
+       GH3X2X_Memset(&gstDrvBtOutRes, 0, sizeof(STGH3x2xDrvBtOutputResult));\r
+       //GH3X2X_Memcpy(RT_Table, g_nBtParamsArr, GOODIX_BT_PARAMS_NUM_MAX * sizeof(GU16));\r
+       //unSensorNtcRT_Len = sizeof(RT_Table)/sizeof(RT_Table[0]);\r
+       #endif\r
+    return GH3X2X_RET_OK;\r
+}\r
+\r
+GS8 GH3x2xBtAlgoDeinit(const STGh3x2xFrameInfo * const pstFrameInfo)\r
+{\r
+       #if !__USE_GOODIX_DRV_NTC_Convert\r
+    if(BT_ERRORCODE_OK != GoodixBtAlgoDeinit(&gstBtAlgoInfo))\r
+    {\r
+        return GH3X2X_RET_GENERIC_ERROR;\r
+    }\r
+       #endif\r
+    return GH3X2X_RET_OK;\r
+}\r
+\r
+GS8  GH3x2xBtAlgoExe(const STGh3x2xFrameInfo * const pstFrameInfo)\r
+{\r
+    GS32 TempRawdata[4] = {0};\r
+    GS8 chRet = GH3X2X_RET_GENERIC_ERROR;\r
+    for(GU8 i = 0; i < 4; i++)\r
+    {\r
+        TempRawdata[i] = (int)(pstFrameInfo->pstFrameTempdata->unTempData[i]);\r
+    }\r
+\r
+    if (g_uchAlgoTempEnable == 0)\r
+    {\r
+        for(GU8 i = 0; i < 4; i++)\r
+        {\r
+            TempRawdata[i] = (int)(pstFrameInfo->punFrameRawdata[i]);\r
+        }\r
+    }\r
+#if !__USE_GOODIX_DRV_NTC_Convert\r
+    gstBtAlgoInfo.stAlgorithmCalcInput.pnRawdata = TempRawdata;\r
+\r
+    if (g_pstGh3x2xAlgoFrameInfo[GH3X2X_FUNC_OFFSET_HR]->pstAlgoRecordResult->uchUpdateFlag)\r
+    {\r
+        g_unBtLastHrResult = g_pstGh3x2xAlgoFrameInfo[GH3X2X_FUNC_OFFSET_HR]->pstAlgoRecordResult->snResult[0];\r
+    }\r
+    gstBtInputRef.unHR = g_unBtLastHrResult;\r
+\r
+    //GH3X2X_DEBUG_ALGO_LOG("[%s]:%d,%d,%d,%d\n", __FUNCTION__, gstBtAlgoInfo.stAlgorithmCalcInput.pnRawdata[0], gstBtAlgoInfo.stAlgorithmCalcInput.pnRawdata[1], gstBtAlgoInfo.stAlgorithmCalcInput.pnRawdata[2], gstBtAlgoInfo.stAlgorithmCalcInput.pnRawdata[3]);\r
+\r
+\r
+    if(BT_ERRORCODE_OK == GoodixBtAlgoCalculate(&gstBtAlgoInfo))\r
+    {\r
+        //if(gstBtAlgoOUT.uchRefresh)\r
+        {\r
+            pstFrameInfo->pstAlgoResult->uchUpdateFlag = 1;\r
+            pstFrameInfo->pstAlgoResult->usResultBit = 0x3F;\r
+            pstFrameInfo->pstAlgoResult->uchResultNum = GH3x2x_BitCount(pstFrameInfo->pstAlgoResult->usResultBit);\r
+            if (0!=gstBtAlgoInfo.stAlgorithmCalcOutput.pnMiddleBaseBuffer)\r
+            {\r
+                for (int i =0; i < 2; i++)\r
+                {\r
+                    pstFrameInfo->pstAlgoResult->snResult[i] = gstBtAlgoInfo.stAlgorithmCalcOutput.pnMiddleBaseBuffer[i];//ntc0\r
+                    //pstFrameInfo->pstAlgoResult->snResult[1] = gstBtAlgoOUT.nFPCBT;//ntc1\r
+                }\r
+            }\r
+            pstFrameInfo->pstAlgoResult->snResult[2] = gstBtAlgoOUT.uchState;\r
+            pstFrameInfo->pstAlgoResult->snResult[3] = gstBtAlgoOUT.uchConfidence;\r
+            pstFrameInfo->pstAlgoResult->snResult[4] = gstBtAlgoOUT.nCBT;\r
+            pstFrameInfo->pstAlgoResult->snResult[5] = g_unBtLastHrResult;\r
+        }\r
+        chRet = GH3X2X_RET_OK;\r
+    }\r
+#else\r
+       // drv calculate bt\r
+       chRet =GH3x2xBtRTConvert( TempRawdata, &gstDrvBtOutRes);\r
+       pstFrameInfo->pstAlgoResult->uchUpdateFlag = 1;\r
+  pstFrameInfo->pstAlgoResult->usResultBit = 0x03;\r
+       pstFrameInfo->pstAlgoResult->uchResultNum = GH3x2x_BitCount(pstFrameInfo->pstAlgoResult->usResultBit);\r
+       for (int i =0; i < 2; i++)\r
+       {\r
+               #if NTCSecondResult\r
+               pstFrameInfo->pstAlgoResult->snResult[i] = gstDrvBtOutRes.nSecTemperature[i];//ntc0 ntc1 per second\r
+               GH3X2X_DEBUG_ALGO_LOG("[%s]:rawdata: %d %d %d %d.second temp: %d %d\n", __FUNCTION__, TempRawdata[0],TempRawdata[1],TempRawdata[2],TempRawdata[3],gstDrvBtOutRes.nSecTemperature[0],gstDrvBtOutRes.nSecTemperature[1]);\r
+               #else\r
+               pstFrameInfo->pstAlgoResult->snResult[i] = gstDrvBtOutRes.nFrameTemperature[i];//ntc0 ntc1 per frame\r
+               GH3X2X_DEBUG_ALGO_LOG("[%s]:rawdata: %d %d %d %d.frame temp: %d %d\n", __FUNCTION__, TempRawdata[0],TempRawdata[1],TempRawdata[2],TempRawdata[3],gstDrvBtOutRes.nFrameTemperature[0],gstDrvBtOutRes.nFrameTemperature[1]);\r
+               #endif\r
+       }\r
+#endif\r
+    return chRet;\r
+}\r
+\r
+#endif\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_call/src/gh3x2x_demo_algo_call_ecg.c b/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_call/src/gh3x2x_demo_algo_call_ecg.c
new file mode 100644 (file)
index 0000000..7fdbfbd
--- /dev/null
@@ -0,0 +1,207 @@
+\r
+#include <stdio.h>\r
+#include "gh3x2x_demo_algo_call.h"\r
+#include "gh3x2x_demo_algorithm_calc.h"\r
+#include "gh3x2x_demo_algo_config.h"\r
+#include "goodix_ecg.h"\r
+\r
+#if (__USE_GOODIX_ECG_ALGORITHM__)\r
+\r
+#define GH3X2X_SINGLE_CLASSIFICATION_TIME 32\r
+\r
+goodix_ecg_ret goodix_ecg_init_func(GU32 fs)\r
+{\r
+    goodix_ecg_config stEcgCfg = {0};\r
+    goodix_ecg_init_result stInitResult = {0};\r
+    GCHAR uchEcgVersion[100] = {0};\r
+\r
+    goodix_ecg_version((uint8_t*)uchEcgVersion);\r
+    GH3X2X_DEBUG_ALGO_LOG("ecg algorithm version : %s\r\n", uchEcgVersion);\r
+\r
+#if (__GOODIX_ECG_ALGO_CONFIG__ == GOODIX_ECG_ALGO_500FS_QRS_ENABLE) || (__GOODIX_ECG_ALGO_CONFIG__ == GOODIX_ECG_ALGO_500FS_QRS_DISABLE)\r
+    if (500 != fs)\r
+    {\r
+        GH3X2X_DEBUG_ALGO_LOG("[%s] fail! The sampling rate(%d) does not match the macro settings.\r\n", __FUNCTION__, fs);\r
+        return GX_ALGO_ECG_RWONG_INPUT;\r
+    }\r
+#elif (__GOODIX_ECG_ALGO_CONFIG__ == GOODIX_ECG_ALGO_250FS_QRS_ENABLE) || (__GOODIX_ECG_ALGO_CONFIG__ == GOODIX_ECG_ALGO_250FS_QRS_DISABLE)\r
+    if (250 != fs)\r
+    {\r
+        GH3X2X_DEBUG_ALGO_LOG("[%s] fail! The sampling rate(%d) does not match the macro settings.\r\n", __FUNCTION__, fs);\r
+        return GX_ALGO_ECG_RWONG_INPUT;\r
+    }\r
+#else\r
+#error "please define __GOODIX_ECG_ALGO_CONFIG__ in gh3x2x_demo_algo_config.h !"\r
+#endif\r
+\r
+#if (__GOODIX_ECG_ALGO_CONFIG__ == GOODIX_ECG_ALGO_500FS_QRS_ENABLE) || (__GOODIX_ECG_ALGO_CONFIG__ == GOODIX_ECG_ALGO_250FS_QRS_ENABLE)\r
+    stEcgCfg.qrs_flag = 1;\r
+#elif (__GOODIX_ECG_ALGO_CONFIG__ == GOODIX_ECG_ALGO_500FS_QRS_DISABLE) || (__GOODIX_ECG_ALGO_CONFIG__ == GOODIX_ECG_ALGO_250FS_QRS_DISABLE)\r
+    stEcgCfg.qrs_flag = 0;\r
+#else\r
+#error "please define __GOODIX_ECG_ALGO_CONFIG__ in gh3x2x_demo_algo_config.h !"\r
+#endif\r
+\r
+    stEcgCfg.fs = fs;\r
+    stEcgCfg.valid_channel_num = (uint32_t)g_nEcgParamsArr[1];\r
+    stEcgCfg.mode_type = (uint32_t)g_nEcgParamsArr[3];\r
+    stEcgCfg.ic_type = (uint32_t)g_nEcgParamsArr[4];\r
+\r
+    GH3X2X_INFO_ALGO_LOG("[%s]:params = %d,%d,%d,%d,%d\r\n", __FUNCTION__,\r
+                                    stEcgCfg.fs,\r
+                                    stEcgCfg.valid_channel_num,\r
+                                    stEcgCfg.qrs_flag,\r
+                                    stEcgCfg.mode_type,\r
+                                    stEcgCfg.ic_type);\r
+\r
+    const void *p_CfgInstance = (void *)&stEcgCfg;\r
+    char chVer[ECG_INTERFACE_VERSION_LEN_MAX] = {0};\r
+\r
+    goodix_ecg_config_get_version(chVer, ECG_INTERFACE_VERSION_LEN_MAX);\r
+    const char *p_InterfaceVer = chVer;\r
+\r
+    goodix_ecg_ret ret = goodix_ecg_init(p_CfgInstance, &stInitResult, sizeof(stEcgCfg), p_InterfaceVer);\r
+    g_uchClassificationFlag = 0;\r
+    g_unEcgTimeSeconds = 0;\r
+\r
+    return ret;\r
+}\r
+\r
+goodix_ecg_ret goodix_ecg_deinit_func(void)\r
+{\r
+    return goodix_ecg_deinit();\r
+}\r
+\r
+GS8 GH3x2xEcgAlgoInit(const STGh3x2xFrameInfo *const pstFrameInfo)\r
+{\r
+    GH3X2X_DEBUG_ALGO_LOG("%s\r\n", __FUNCTION__);\r
+\r
+    GS8 chRet = GH3X2X_RET_GENERIC_ERROR;\r
+    GU16 usSampleRate = pstFrameInfo->pstFunctionInfo->usSampleRate;\r
+\r
+    goodix_ecg_ret ret = goodix_ecg_init_func(usSampleRate);\r
+    if (GX_ALGO_ECG_SUCCESS == ret)\r
+    {\r
+        chRet = GH3X2X_RET_OK;\r
+    }\r
+    else\r
+    {\r
+        chRet = GH3X2X_RET_PARAMETER_ERROR;\r
+        GH3X2X_DEBUG_ALGO_LOG("ecg init error! ret = 0x%x\r\n", ret);\r
+    }\r
+    g_unEcgFrameCnt  = 0;\r
+    GH3X2X_SetNewDataFlag(GH3X2X_FUNC_OFFSET_ECG, GH3X2X_IS_NEW_RAWDATA);\r
+\r
+    *(pstFrameInfo->punFrameCnt) = 0;\r
+\r
+    return chRet;\r
+}\r
+\r
+GS8 GH3x2xEcgAlgoDeinit(const STGh3x2xFrameInfo *const pstFrameInfo)\r
+{\r
+    GH3X2X_DEBUG_ALGO_LOG("%s\r\n", __FUNCTION__);\r
+\r
+    GS8 chRet = GH3X2X_RET_GENERIC_ERROR;\r
+\r
+    goodix_ecg_ret ret = goodix_ecg_deinit_func();\r
+    if (ret == GX_ALGO_ECG_SUCCESS)\r
+    {\r
+        chRet = GH3X2X_RET_OK;\r
+    }\r
+    else\r
+    {\r
+        GH3X2X_DEBUG_ALGO_LOG("ecg deinit error! ret = 0x%x\r\n", ret);\r
+    }\r
+\r
+    return chRet;\r
+}\r
+\r
+GS8 GH3x2xEcgAlgoExe(const STGh3x2xFrameInfo *const pstFrameInfo)\r
+{\r
+    if (0 == pstFrameInfo)\r
+    {\r
+        return GH3X2X_RET_GENERIC_ERROR;\r
+    }\r
+\r
+    goodix_ecg_input_rawdata stRawdata = {0};\r
+    goodix_ecg_result stResult;\r
+    GS8 chAlgoRet = 0;\r
+    GU32 unRawdata[ECG_CHANNEL_NUM] = {0};\r
+    GF32 fEcgOutData[ECG_CHANNEL_NUM] = {0};\r
+    goodix_stage unEcgStage[ECG_CHANNEL_NUM] = {stage_noneffect_out, stage_noneffect_out};\r
+    GF32 fEcgSnr[ECG_CHANNEL_NUM] = {0};\r
+    GF32 fEcgPowerLineOut[ECG_CHANNEL_NUM] = {0};\r
+    GF32 fEcgBlwOut[ECG_CHANNEL_NUM] = {0};\r
+    GF32 fEcgBpmCh[ECG_CHANNEL_NUM] = {0};\r
+\r
+    stResult.ecg_out = fEcgOutData;\r
+    stResult.ecg_stage = unEcgStage;\r
+    stResult.ecg_snr = fEcgSnr;\r
+    stResult.ecg_powerline_out = fEcgPowerLineOut;\r
+    stResult.ecg_blw_out = fEcgBlwOut;\r
+    stResult.ecg_bpm_ch = fEcgBpmCh;\r
+\r
+    stRawdata.ecg_rawdata = (GS32 *)&unRawdata;\r
+    stRawdata.frameid = GH3X2X_GET_BYTE0_FROM_DWORD(*(pstFrameInfo->punFrameCnt));\r
+    stRawdata.acc_x = pstFrameInfo->pusFrameGsensordata[0];\r
+    stRawdata.acc_y = pstFrameInfo->pusFrameGsensordata[1];\r
+    stRawdata.acc_z = pstFrameInfo->pusFrameGsensordata[2];\r
+    stRawdata.ecg_rawdata[0] = pstFrameInfo->punFrameRawdata[0];\r
+    stRawdata.ecg_rawdata[1] = pstFrameInfo->punFrameRawdata[1];\r
+    stRawdata.ecg_qc_flag = GH3X2X_CHECK_BIT_IS_SET(pstFrameInfo->punFrameFlag[2], 0x01);\r
+    GH3X2X_DEBUG_ALGO_LOG("[%s]ecg ecg_rawdata = %d, %d, ecg_qc_flag = %d\r\n", __FUNCTION__, stRawdata.ecg_rawdata[0], stRawdata.ecg_rawdata[1], \\r
+        stRawdata.ecg_qc_flag);\r
+\r
+    if (g_unEcgFrameCnt <= ECG_FRAME_UNUSED) /* the first 5 frame data can't be used for algo */\r
+    {\r
+        g_unEcgFrameCnt++;\r
+        stRawdata.ecg_qc_flag = 1;\r
+    }\r
+\r
+    if (1 == stRawdata.ecg_qc_flag)     /* when fast recovery,data can't be used for algo */\r
+    {\r
+        return chAlgoRet;\r
+    }\r
+\r
+    goodix_ecg_ret stRet = goodix_ecg_update(&stRawdata, &stResult);\r
+\r
+    if (stRet == GX_ALGO_ECG_SUCCESS)\r
+    {\r
+        pstFrameInfo->pstAlgoResult->uchUpdateFlag = 1;\r
+        pstFrameInfo->pstAlgoResult->snResult[0] = GH3x2x_Round(stResult.ecg_out[0] * ECG_OUT_FACTOR);\r
+        pstFrameInfo->pstAlgoResult->snResult[2] = GH3x2x_Round(stResult.ecg_out[1] * ECG_OUT_FACTOR);\r
+\r
+        GH3X2X_DEBUG_ALGO_LOG("ecg out0 = %.3f\r\n", stResult.ecg_out[0]);\r
+        GH3X2X_DEBUG_ALGO_LOG("ecg out1 = %.3f\r\n", stResult.ecg_out[1]);\r
+        //GH3X2X_INFO_ALGO_LOG("bpm result = %d\r\n",(GS32)(stResult.ecg_bpm + 0.5f));\r
+\r
+        pstFrameInfo->pstAlgoResult->snResult[1] = (GS32)(stResult.ecg_bpm + 0.5f);\r
+        pstFrameInfo->pstAlgoResult->usResultBit = 0x1 | \\r
+                                                 ((0x1 << 1) * (pstFrameInfo->pstAlgoResult->snResult[1] != 0)) | \\r
+                                                 ((0x1 << 2) * (g_nEcgParamsArr[1] == 2));\r
+        pstFrameInfo->pstAlgoResult->uchResultNum = GH3x2x_BitCount(pstFrameInfo->pstAlgoResult->usResultBit);\r
+\r
+        GH3X2X_EcgAlgorithmResultReport(pstFrameInfo->pstAlgoResult, pstFrameInfo->punFrameCnt[0]);\r
+    }\r
+    else\r
+    {\r
+        GH3X2X_DEBUG_ALGO_LOG("GH3x2xEcgAlgoExe error! error code:0x%x\r\n", stRet);\r
+        GH3X2X_DEBUG_ALGO_LOG("please feedback to GOODIX!\r\n");\r
+        chAlgoRet = GH3X2X_RET_RESOURCE_ERROR;\r
+    }\r
+\r
+    return chAlgoRet;\r
+}\r
+\r
+GU8 GH3x2xEcgAlgoClassification(void)\r
+{\r
+    goodix_ecg_classification_update((goodix_classification_flag *)&g_uchClassificationFlag);\r
+    return g_uchClassificationFlag;\r
+}\r
+#else\r
+GU8 GH3x2xEcgAlgoClassification(void)\r
+{\r
+    return 0;\r
+}\r
+#endif\r
+\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_call/src/gh3x2x_demo_algo_call_hr.c b/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_call/src/gh3x2x_demo_algo_call_hr.c
new file mode 100644 (file)
index 0000000..01f6775
--- /dev/null
@@ -0,0 +1,224 @@
+/**\r
+ * @copyright (c) 2003 - 2024, Goodix Co., Ltd. All rights reserved.\r
+ *\r
+ * @file    gh3x2x_demo_algo_call_hr.c\r
+ *\r
+ * @brief   gh3x2x algo hr interface\r
+ *\r
+ */\r
+\r
+#include <stdio.h>\r
+#include "gh3x2x_demo_algo_call.h"\r
+#include "gh3x2x_demo_algorithm_calc.h"\r
+#include "gh3x2x_demo_algo_config.h"\r
+#include "goodix_hba.h"\r
+\r
+#if (__USE_GOODIX_HR_ALGORITHM__)\r
+\r
+void Gh3x2xSetHbaMode(GS32 nHbaScenario)\r
+{\r
+    g_unHrParamsArr[1] = nHbaScenario;\r
+}\r
+\r
+goodix_hba_ret goodix_hba_init_func(GU32 fs)\r
+{\r
+    goodix_hba_config stHbCfg;\r
+    goodix_hba_ret stAlgoRet = GX_ALGO_HBA_SUCCESS;\r
+    GCHAR uchHrVersion[120] = {0};\r
+\r
+    goodix_hba_ret ret = goodix_hba_version((uint8_t *)uchHrVersion);\r
+    if (GX_ALGO_HBA_SUCCESS != ret)\r
+    {\r
+        GH3X2X_DEBUG_ALGO_LOG("hba algorithm init fail : 0x%x\r\n", ret);\r
+        return ret;\r
+    }\r
+\r
+    GH3X2X_HbaAlgoChnlMapDefultSet();\r
+\r
+    GH3X2X_DEBUG_ALGO_LOG("hba algorithm version : %s\r\n", uchHrVersion);\r
+    GH3X2X_DEBUG_ALGO_LOG("hba algorithm legal chnl num : %d\r\n", g_stHbaAlgoChnlMap.uchNum);\r
+\r
+    if (g_stHbaAlgoChnlMap.uchNum > Gh3x2xGetHrAlgoSupportChnl())\r
+    {\r
+        GH3X2X_DEBUG_ALGO_LOG("ERROR: hr algorithm legal chnl num is too big, check cfg !!! \r\n");\r
+        return GX_ALGO_HBA_RWONG_INPUT;\r
+    }\r
+\r
+    stHbCfg.mode = (hba_test_mode)g_unHrParamsArr[0];\r
+    stHbCfg.scence = (hba_scenes_e)g_unHrParamsArr[1];\r
+    stHbCfg.fs = fs;\r
+    stHbCfg.valid_channel_num = g_stHbaAlgoChnlMap.uchNum;\r
+    stHbCfg.back_track_len = g_unHrParamsArr[2];\r
+    stHbCfg.hba_latest_output_time = g_unHrParamsArr[3];\r
+    stHbCfg.hba_earliest_output_time = g_unHrParamsArr[4];\r
+    stHbCfg.hba_lowerest_confidence = g_unHrParamsArr[5];\r
+    stHbCfg.hba_out_step_second = g_unHrParamsArr[6];\r
+    stHbCfg.hba_convergence_rate = g_unHrParamsArr[7];\r
+    stHbCfg.senseless_mode_step = g_unHrParamsArr[8];\r
+    stHbCfg.senseless_mode_duration = g_unHrParamsArr[9];\r
+\r
+    GH3X2X_INFO_ALGO_LOG("[%s]:params = %d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\r\n", __FUNCTION__,\r
+                                    stHbCfg.mode,\r
+                                    stHbCfg.scence,\r
+                                    stHbCfg.fs,\r
+                                    stHbCfg.valid_channel_num,\r
+                                    stHbCfg.back_track_len,\r
+                                    stHbCfg.hba_latest_output_time,\r
+                                    stHbCfg.hba_earliest_output_time,\r
+                                    stHbCfg.hba_lowerest_confidence,\r
+                                    stHbCfg.hba_out_step_second,\r
+                                    stHbCfg.hba_convergence_rate,\r
+                                    stHbCfg.senseless_mode_step,\r
+                                    stHbCfg.senseless_mode_duration);\r
+\r
+    const void *p_CfgInstance = (void *)&stHbCfg;\r
+    char chVer[HBA_INTERFACE_VERSION_LEN_MAX] = {0};\r
+\r
+    goodix_hba_config_get_version(chVer, HBA_INTERFACE_VERSION_LEN_MAX);\r
+    const char *p_InterfaceVer = chVer;\r
+\r
+    stAlgoRet = goodix_hba_init(p_CfgInstance, sizeof(stHbCfg), p_InterfaceVer);\r
+\r
+    return stAlgoRet;\r
+}\r
+\r
+goodix_hba_ret goodix_hba_deinit_func(void)\r
+{\r
+    return goodix_hba_deinit();\r
+}\r
+\r
+GS8 GH3x2xHrAlgoInit(const STGh3x2xFrameInfo *const pstFrameInfo)\r
+{\r
+    GS8 chRet = GH3X2X_RET_GENERIC_ERROR;\r
+\r
+    GH3X2X_DEBUG_ALGO_LOG("%s\r\n", __FUNCTION__);\r
+\r
+    goodix_hba_ret ret = goodix_hba_init_func(pstFrameInfo->pstFunctionInfo->usSampleRate);\r
+\r
+    if (GX_ALGO_HBA_SUCCESS == ret)\r
+    {\r
+        chRet = GH3X2X_RET_OK;\r
+        GH3X2X_DEBUG_ALGO_LOG("[%s]GH3X2X_HbaInit success!!\r\n", __FUNCTION__);\r
+    }\r
+    else\r
+    {\r
+        GH3X2X_DEBUG_ALGO_LOG("hba init error! error code:0x%x\r\n", ret);\r
+    }\r
+\r
+    pstFrameInfo->pstAlgoRecordResult->uchUpdateFlag = 0;\r
+    pstFrameInfo->pstAlgoRecordResult->snResult[0] = 0;\r
+\r
+    return chRet;\r
+}\r
+\r
+GS8 GH3x2xHrAlgoDeinit(const STGh3x2xFrameInfo *const pstFrameInfo)\r
+{\r
+    GS8 chRet = GH3X2X_RET_GENERIC_ERROR;\r
+\r
+    GH3X2X_DEBUG_ALGO_LOG("%s\r\n", __FUNCTION__);\r
+\r
+    goodix_hba_ret ret = goodix_hba_deinit_func();\r
+    if (GX_ALGO_HBA_SUCCESS == ret)\r
+    {\r
+        chRet = GH3X2X_RET_OK;\r
+    }\r
+    else\r
+    {\r
+        GH3X2X_DEBUG_ALGO_LOG("hba deinit error! error code:0x%x\r\n", ret);\r
+    }\r
+\r
+    return chRet;\r
+}\r
+\r
+//call algo 2-level interface\r
+GS8 GH3x2xHrAlgoExe(const STGh3x2xFrameInfo *const pstFrameInfo)\r
+{\r
+    if (0 == pstFrameInfo)\r
+    {\r
+        return GH3X2X_RET_GENERIC_ERROR;\r
+    }\r
+\r
+       GS32 ppg_rawdata[3 * PPG_CHANNEL_NUM] = {0};\r
+       GS32 cur_adj_flg[3 * PPG_CHANNEL_NUM] = {0};\r
+       GS32 gain_adj_flg[3 * PPG_CHANNEL_NUM] = {0};\r
+       GS32 enable_flg[3 * PPG_CHANNEL_NUM] = {0};\r
+\r
+    goodix_hba_input_rawdata stRawdata = {0};\r
+    goodix_hba_result stResult = {0};\r
+\r
+    stRawdata.ppg_rawdata = ppg_rawdata;\r
+    stRawdata.cur_adj_flg = cur_adj_flg;\r
+    stRawdata.gain_adj_flg = gain_adj_flg;\r
+    stRawdata.enable_flg = enable_flg;\r
+\r
+    stRawdata.frameid = GH3X2X_GET_BYTE0_FROM_DWORD(*(pstFrameInfo->punFrameCnt));\r
+    stRawdata.acc_x = pstFrameInfo->pusFrameGsensordata[0];\r
+    stRawdata.acc_y = pstFrameInfo->pusFrameGsensordata[1];\r
+    stRawdata.acc_z = pstFrameInfo->pusFrameGsensordata[2];\r
+    stRawdata.sleep_flg = GH3x2xSleepFlagGet();\r
+\r
+    GU8 uchChMapCnt = 0;\r
+    GU8 uchRawdataIndex = 0;\r
+    GU8 uchTotalChannelNum = 0;\r
+    GS8 chAlgoRet = GH3X2X_RET_OK;\r
+\r
+    for (uchChMapCnt = 0; uchChMapCnt < 3 * PPG_CHANNEL_NUM; ++uchChMapCnt)\r
+    {\r
+        if (g_stHbaAlgoChnlMap.uchAlgoChnlMap[uchChMapCnt + 4 * (uchChMapCnt / 4)] < 0xff)\r
+        {\r
+            uchRawdataIndex = g_stHbaAlgoChnlMap.uchAlgoChnlMap[uchChMapCnt + 4 * (uchChMapCnt / 4)];\r
+\r
+            //make gain_adj_flg and cur_adj_flg to 0 for algo 1.0.5.0(alpha).\r
+            stRawdata.gain_adj_flg[uchChMapCnt] = 0;\r
+            stRawdata.cur_adj_flg[uchChMapCnt] = 0;\r
+            stRawdata.enable_flg[uchChMapCnt]  = 1;\r
+            stRawdata.ppg_rawdata[uchChMapCnt] = pstFrameInfo->punFrameRawdata[uchRawdataIndex];\r
+            uchTotalChannelNum++;\r
+\r
+            GH3X2X_DEBUG_ALGO_LOG("[%s]ppg_rawdata = %d,gain_adj_flg = %d,cur_adj_flg = %d\r\n", __FUNCTION__, \\r
+                (int)stRawdata.ppg_rawdata[uchChMapCnt], (int)stRawdata.gain_adj_flg[uchChMapCnt], \\r
+                (int)stRawdata.cur_adj_flg[uchChMapCnt]);\r
+        }\r
+    }\r
+    stRawdata.total_channel_num = uchTotalChannelNum;\r
+\r
+    /* call algorithm, update result */\r
+    goodix_hba_ret ret = goodix_hba_update(&stRawdata, &stResult);\r
+    if (GX_ALGO_HBA_SUCCESS == ret)\r
+    {\r
+        if (1 == stResult.hba_out_flag)\r
+        {\r
+            pstFrameInfo->pstAlgoResult->uchUpdateFlag = (GU8)stResult.hba_out_flag;\r
+            pstFrameInfo->pstAlgoResult->snResult[0] = (GS32)stResult.hba_out;\r
+            pstFrameInfo->pstAlgoResult->snResult[1] = (GS32)stResult.valid_score;\r
+            pstFrameInfo->pstAlgoResult->snResult[2] = GH3X2X_ALGORITHM_GF32_2_GS32(stResult.hba_snr);\r
+            pstFrameInfo->pstAlgoResult->snResult[3] = (GS32)stResult.valid_level;\r
+            pstFrameInfo->pstAlgoResult->snResult[4] = (GS32)stResult.hba_acc_info;\r
+            pstFrameInfo->pstAlgoResult->snResult[5] = (GS32)stResult.hba_acc_scence;\r
+\r
+            GH3X2X_DEBUG_ALGO_LOG("[%s]hr = %d,UpdateFlag = %d\r\n", __FUNCTION__, \\r
+                (int)pstFrameInfo->pstAlgoResult->snResult[0], (int)pstFrameInfo->pstAlgoResult->uchUpdateFlag);\r
+\r
+            pstFrameInfo->pstAlgoResult->usResultBit = 0x3F;\r
+            pstFrameInfo->pstAlgoResult->uchResultNum = GH3x2x_BitCount(pstFrameInfo->pstAlgoResult->usResultBit);\r
+#if __GH3X2X_HR_OUTPUT_VALUE_STRATEGY_EN__\r
+            Gh3x2xHrOutputValueStrategyPro(pstFrameInfo->pstAlgoResult,pstFrameInfo->punFrameCnt[0]);\r
+#endif\r
+            GH3X2X_HrAlgorithmResultReport(pstFrameInfo->pstAlgoResult,pstFrameInfo->punFrameCnt[0]);\r
+            \r
+            pstFrameInfo->pstAlgoRecordResult->uchUpdateFlag = (GU8)stResult.hba_out_flag;\r
+            pstFrameInfo->pstAlgoRecordResult->snResult[0] = (GS32)stResult.hba_out;\r
+        }\r
+    }\r
+    else\r
+    {\r
+        chAlgoRet = GH3X2X_RET_RESOURCE_ERROR;\r
+        GH3X2X_DEBUG_ALGO_LOG("GH3x2xHrAlgoExe error! error code = 0x%x\r\n", ret);\r
+        GH3X2X_DEBUG_ALGO_LOG("please feedback to GOODIX!\r\n");\r
+    }\r
+\r
+    return chAlgoRet;\r
+}\r
+\r
+#endif\r
+\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_call/src/gh3x2x_demo_algo_call_hrv.c b/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_call/src/gh3x2x_demo_algo_call_hrv.c
new file mode 100644 (file)
index 0000000..f88f7ec
--- /dev/null
@@ -0,0 +1,172 @@
+#include <stdio.h>\r
+#include "gh3x2x_demo_algo_call.h"\r
+#include "gh3x2x_demo_algorithm_calc.h"\r
+#include "goodix_hba.h"\r
+#include "goodix_hrv.h"\r
+\r
+#if (__USE_GOODIX_HRV_ALGORITHM__)\r
+\r
+GU32 g_unHrvLastHrResult = 0;\r
+\r
+//hrv\r
+goodix_hrv_ret goodix_hrv_init_func(GU32 fs)\r
+{\r
+    goodix_hrv_ret stAlgoRet = GX_HRV_ALGO_OK;\r
+    goodix_hrv_config stHrvConfig = {\r
+                                        g_nHrvParamsArr[0],\r
+                                        fs,\r
+                                        {g_nHrvParamsArr[1] * 10000, g_nHrvParamsArr[2] * 10000, g_nHrvParamsArr[3] * 10000, g_nHrvParamsArr[4] * 10000}\r
+                                    };\r
+\r
+    GCHAR uchHrvVersion[100] = {0};\r
+    GH3X2X_Memcpy(uchHrvVersion, goodix_hrv_version(), strlen((GCHAR *)goodix_hrv_version()) + 1);\r
+    GH3X2X_DEBUG_ALGO_LOG("hrv algorithm version : %s\r\n", uchHrvVersion);\r
+\r
+    GH3X2X_INFO_ALGO_LOG("[%s]:params = %d,%d,%d,%d,%d,%d,\r\n", __FUNCTION__,\r
+                                    stHrvConfig.need_ipl,\r
+                                    stHrvConfig.fs,\r
+                                    stHrvConfig.acc_thr[0],\r
+                                    stHrvConfig.acc_thr[1],\r
+                                    stHrvConfig.acc_thr[2],\r
+                                    stHrvConfig.acc_thr[3]);\r
+\r
+    const void *p_CfgInstance = (void *)&stHrvConfig;\r
+    char chVer[HRV_INTERFACE_VERSION_LEN_MAX] = {0};\r
+\r
+    goodix_hrv_config_get_version(chVer, HRV_INTERFACE_VERSION_LEN_MAX);\r
+    const char *p_InterfaceVer = chVer;\r
+\r
+    stAlgoRet = goodix_hrv_init(p_CfgInstance, sizeof(stHrvConfig), p_InterfaceVer);\r
+\r
+    return stAlgoRet;\r
+}\r
+\r
+goodix_hrv_ret goodix_hrv_deinit_func(void)\r
+{\r
+    goodix_hrv_ret nRet = GX_HRV_ALGO_OK;\r
+\r
+    nRet = goodix_hrv_deinit();\r
+    if (GX_HRV_ALGO_OK != nRet)\r
+    {\r
+        GH3X2X_DEBUG_ALGO_LOG("hrv init errorcode : 0x%x\r\n", nRet);\r
+    }\r
+\r
+    return nRet;\r
+}\r
+\r
+GS8 GH3x2xHrvAlgoInit(const STGh3x2xFrameInfo *const pstFrameInfo)\r
+{\r
+    GH3X2X_DEBUG_ALGO_LOG("%s\r\n", __FUNCTION__);\r
+\r
+    GS8 chRet = GH3X2X_RET_GENERIC_ERROR;\r
+\r
+    goodix_hrv_ret ret = goodix_hrv_init_func(pstFrameInfo->pstFunctionInfo->usSampleRate);\r
+    if (GX_ALGO_HBA_SUCCESS == ret)\r
+    {\r
+        pstFrameInfo->pstAlgoResult->usResultBit = 0x7F;\r
+        chRet = GH3X2X_RET_OK;\r
+    }\r
+    else\r
+    {\r
+        GH3X2X_DEBUG_ALGO_LOG("hrv init error! error code = 0x%x\r\n", ret);\r
+    }\r
+    g_pstGh3x2xAlgoFrameInfo[GH3X2X_FUNC_OFFSET_HR]->pstAlgoRecordResult->uchUpdateFlag = 0;\r
+    g_unHrvLastHrResult = 0;\r
+\r
+    return chRet;\r
+}\r
+\r
+GS8 GH3x2xHrvAlgoDeinit(const STGh3x2xFrameInfo *const pstFrameInfo)\r
+{\r
+    GH3X2X_DEBUG_ALGO_LOG("%s\r\n", __FUNCTION__);\r
+\r
+    GS8 chRet = GH3X2X_RET_GENERIC_ERROR;\r
+\r
+    if (GX_ALGO_HBA_SUCCESS == goodix_hrv_deinit_func())\r
+    {\r
+        chRet = GH3X2X_RET_OK;\r
+    }\r
+    else\r
+    {\r
+        GH3X2X_DEBUG_ALGO_LOG("hrv deinit error!\r\n");\r
+    }\r
+\r
+    return chRet;\r
+}\r
+\r
+GS8 GH3x2xHrvAlgoExe(const STGh3x2xFrameInfo *const pstFrameInfo)\r
+{\r
+    if (0 == pstFrameInfo)\r
+    {\r
+        return GH3X2X_RET_GENERIC_ERROR;\r
+    }\r
+\r
+    GS8 chAlgoRet = GH3X2X_RET_OK;\r
+    GU8 uchGainValue = 0;\r
+    GS32 ppg_rawdata[PPG_CHANNEL_NUM] = {0};\r
+    GS32 cur_adj_flg[PPG_CHANNEL_NUM] = {0};\r
+    GS32 gain_adj_flg[PPG_CHANNEL_NUM] = {0};\r
+    goodix_hrv_result stResult = {0};\r
+    goodix_hrv_input_rawdata stRawdataInput = {0};\r
+\r
+    stRawdataInput.ppg_rawdata = ppg_rawdata;\r
+    stRawdataInput.cur_adj_flg = cur_adj_flg;\r
+    stRawdataInput.gain_adj_flg = gain_adj_flg;\r
+\r
+    stRawdataInput.bit_num = 24;\r
+    stRawdataInput.acc_x = pstFrameInfo->pusFrameGsensordata[0];\r
+    stRawdataInput.acc_y = pstFrameInfo->pusFrameGsensordata[1];\r
+    stRawdataInput.acc_z = pstFrameInfo->pusFrameGsensordata[2];\r
+    stRawdataInput.frame_id = GH3X2X_GET_BYTE0_FROM_DWORD(*(pstFrameInfo->punFrameCnt));\r
+    if (g_pstGh3x2xAlgoFrameInfo[GH3X2X_FUNC_OFFSET_HR]->pstAlgoRecordResult->uchUpdateFlag)\r
+    {\r
+        g_unHrvLastHrResult = g_pstGh3x2xAlgoFrameInfo[GH3X2X_FUNC_OFFSET_HR]->pstAlgoRecordResult->snResult[0];\r
+    }\r
+    stRawdataInput.hr = g_unHrvLastHrResult;\r
+\r
+    for (GS32 nRawdatacnt = 0; nRawdatacnt < PPG_CHANNEL_NUM; nRawdatacnt++)\r
+    {\r
+        stRawdataInput.ppg_rawdata[nRawdatacnt] = pstFrameInfo->punFrameRawdata[nRawdatacnt];\r
+        uchGainValue = GH3X2X_GET_LOW_4BITS(pstFrameInfo->punFrameAgcInfo[nRawdatacnt]);\r
+        if ((pstFrameInfo->puchFrameLastGain[nRawdatacnt] != uchGainValue) && \\r
+            (pstFrameInfo->puchFrameLastGain[nRawdatacnt] != GH3X2X_GAIN_VALUE_INVALID))\r
+        {\r
+            stRawdataInput.gain_adj_flg[nRawdatacnt] = 1;\r
+            pstFrameInfo->puchFrameLastGain[nRawdatacnt] = uchGainValue;\r
+        }\r
+        stRawdataInput.cur_adj_flg[nRawdatacnt] = ((pstFrameInfo->punFrameFlag[0]) & 0x01);\r
+\r
+        GH3X2X_DEBUG_ALGO_LOG("[%s]ppg_rawdata = %d, gain_adj_flg = %d, cur_adj_flg = %d\r\n", __FUNCTION__, \\r
+            (int)stRawdataInput.ppg_rawdata[nRawdatacnt], (int)stRawdataInput.gain_adj_flg[nRawdatacnt], \\r
+            (int)stRawdataInput.cur_adj_flg[nRawdatacnt]);\r
+    }\r
+\r
+    goodix_hrv_ret ret = goodix_hrv_calc(&stRawdataInput, &stResult);\r
+    if (GX_HRV_ALGO_OK == ret || GX_HRV_ALGO_UPDATE == ret)\r
+    {\r
+        if (GX_HRV_ALGO_UPDATE == ret)\r
+        {\r
+            pstFrameInfo->pstAlgoResult->uchUpdateFlag = 1;\r
+            pstFrameInfo->pstAlgoResult->snResult[0] = (GS32)stResult.rri[0];\r
+            pstFrameInfo->pstAlgoResult->snResult[1] = (GS32)stResult.rri[1];\r
+            pstFrameInfo->pstAlgoResult->snResult[2] = (GS32)stResult.rri[2];\r
+            pstFrameInfo->pstAlgoResult->snResult[3] = (GS32)stResult.rri[3];\r
+            pstFrameInfo->pstAlgoResult->snResult[4] = (GS32)stResult.rri_confidence;\r
+            pstFrameInfo->pstAlgoResult->snResult[5] = (GS32)stResult.rri_valid_num;\r
+            pstFrameInfo->pstAlgoResult->usResultBit = 0x7F;\r
+            pstFrameInfo->pstAlgoResult->uchResultNum = GH3x2x_BitCount(pstFrameInfo->pstAlgoResult->usResultBit);\r
+            GH3X2X_HrvAlgorithmResultReport(pstFrameInfo->pstAlgoResult, pstFrameInfo->punFrameCnt[0]);\r
+        }\r
+    }\r
+    else\r
+    {\r
+        chAlgoRet = GH3X2X_RET_RESOURCE_ERROR;\r
+        GH3X2X_DEBUG_ALGO_LOG("GH3x2xHrAlgoExe error! error code = 0x%x\r\n", ret);\r
+        GH3X2X_DEBUG_ALGO_LOG("please feedback to GOODIX!\r\n");\r
+    }\r
+\r
+    return chAlgoRet;\r
+}\r
+\r
+#endif\r
+\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_call/src/gh3x2x_demo_algo_call_hsm.c b/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_call/src/gh3x2x_demo_algo_call_hsm.c
new file mode 100644 (file)
index 0000000..6372a06
--- /dev/null
@@ -0,0 +1,131 @@
+#include <stdio.h>\r
+#include "gh3x2x_demo_algo_call.h"\r
+#include "gh3x2x_demo_algorithm_calc.h"\r
+#include "gh3x2x_demo_algo_config.h"\r
+#include "goodix_hsm.h"\r
+\r
+#if (__USE_GOODIX_HSM_ALGORITHM__)\r
+\r
+GS8 GH3x2xHsmAlgoInit(const STGh3x2xFrameInfo * const pstFrameInfo)\r
+{\r
+    int32_t nRet = GH3X2X_RET_GENERIC_ERROR;\r
+#if (GH3X2X_ALGORITHM_HSM_SUPPORT)\r
+\r
+\r
+    GH3X2X_DEBUG_ALGO_LOG("%s\r\n", __FUNCTION__);\r
+    //g_uchLastGainOfChannel[0] = GH3X2X_GAIN_VALUE_INVALID;\r
+    //int nHSMFs = (int)pstFrameInfo ->pstFunctionInfo ->usSampleRate;\r
+    int32_t nHSMFs = 25;\r
+    nRet = HSMAlgoInit(&nHSMFs);\r
+    if (nRet != GH3X2X_RET_OK)\r
+    {\r
+        GH3X2X_DEBUG_ALGO_LOG("hsm process error! error code : %d\r\n", (int)nRet);\r
+    }\r
+    else\r
+    {\r
+        pstFrameInfo->pstAlgoResult->usResultBit = 0x1;\r
+    }\r
+    g_unHsmLastHrResult = 0;\r
+#else\r
+    nRet = GH3X2X_RET_ALGO_NO_SUPPORTED;\r
+    GH3X2X_DEBUG_ALGO_LOG("hsm algorithm no supported error!\r\n");\r
+#endif\r
+    return (GS8)nRet;\r
+}\r
+\r
+GS8 GH3x2xHsmAlgoDeinit(const STGh3x2xFrameInfo * const pstFrameInfo)\r
+{\r
+#if (GH3X2X_ALGORITHM_HSM_SUPPORT)\r
+    GS8 chRet = GH3X2X_RET_GENERIC_ERROR;\r
+\r
+\r
+    ST_HSM_DATA_OUT stHSMDataOut;\r
+    ST_HSM_SCORE stHSMScore;\r
+    GH3X2X_DEBUG_ALGO_LOG("%s\r\n", __FUNCTION__);\r
+    GU8 uchHsmResultSendBuffer[235] = {0};\r
+    GU8 uchHsmPackLen = 140;\r
+    if (HSMLastDataProc(&stHSMDataOut, &stHSMScore) == GH3X2X_RET_OK)\r
+    {    \r
+        uchHsmResultSendBuffer[4] = 2;\r
+        if (stHSMDataOut.uchStageDataFlag != 0)\r
+        {\r
+            GH3X2X_Memcpy(uchHsmResultSendBuffer + 1 + 4, (GU8*)&stHSMScore, 18);\r
+            uchHsmResultSendBuffer[23] = stHSMDataOut.uchStageOutNum;\r
+            GH3X2X_Memcpy(uchHsmResultSendBuffer + 1 + 4 + 19, stHSMDataOut.puchHSMStageOut, 120);\r
+        }\r
+        GU16 usRespondLen = GH3X2X_UprotocolPacketFormat(GH3X2X_UPROTOCOL_CMD_HSM_RESULT_UPDATE, uchHsmResultSendBuffer,\r
+                            &uchHsmResultSendBuffer[4], uchHsmPackLen);\r
+        Gh3x2xDemoSendProtocolData(uchHsmResultSendBuffer,usRespondLen);\r
+        chRet = HSMAlgoDeInit();\r
+    }\r
+    else\r
+    {\r
+        chRet = HSMAlgoDeInit();\r
+        GH3X2X_RET_ERROR_CHECK(chRet);\r
+        chRet = GH3X2X_RET_GENERIC_ERROR;\r
+    }\r
+#else\r
+    GS8 chRet = GH3X2X_RET_ALGO_NO_SUPPORTED;\r
+    GH3X2X_DEBUG_ALGO_LOG("hsm algorithm no supported error!\r\n");\r
+#endif\r
+    return chRet;\r
+}\r
+\r
+GS8 GH3x2xHsmAlgoExe(const STGh3x2xFrameInfo * const pstFrameInfo)\r
+{\r
+    if(0 == pstFrameInfo )\r
+    {\r
+        return 0;\r
+    }\r
+#if (GH3X2X_ALGORITHM_HSM_SUPPORT)\r
+    ST_HSM_DATA_IN stHSMDataIn;\r
+    ST_HSM_DATA_OUT stHSMDataOut;\r
+    ST_HSM_SCORE stHSMScore;\r
+\r
+    if(GH3X2X_RET_OK != GH3x2xCheckAndFreeMem(pstFrameInfo))\r
+    {\r
+        return;\r
+    }\r
+\r
+    stHSMDataIn.IPpgRaw = (int)GH3X2X_GET_RAWDATA_FOR_ALGO((int)pstFrameInfo->punFrameRawdata[0] - GH3X2X_RAWDATA_BASE_VALUE);\r
+    stHSMDataIn.IACCx = pstFrameInfo->pusFrameGsensordata[0];\r
+    stHSMDataIn.IACCy = pstFrameInfo->pusFrameGsensordata[1];\r
+    stHSMDataIn.IACCz = pstFrameInfo->pusFrameGsensordata[2];    \r
+    if (g_pstGh3x2xAlgoFrameInfo[GH3X2X_FUNC_OFFSET_HR]->pstAlgoRecordResult->uchUpdateFlag)\r
+    {\r
+        pstFrameInfo->pstAlgoResult->uchUpdateFlag = 1;\r
+        pstFrameInfo->pstAlgoResult->usResultBit = 0x1;\r
+        pstFrameInfo->pstAlgoResult->uchResultNum = GH3x2x_BitCount(pstFrameInfo->pstAlgoResult->usResultBit);\r
+        pstFrameInfo->pstAlgoResult->snResult[0] = (GS32)g_unHsmLastHrResult;\r
+        g_unHsmLastHrResult = g_pstGh3x2xAlgoFrameInfo[GH3X2X_FUNC_OFFSET_HR]->pstAlgoRecordResult->snResult[0];\r
+    }\r
+    stHSMDataIn.IHeart = g_unHsmLastHrResult;\r
+\r
+    if (HSMProc(&stHSMDataIn, &stHSMDataOut, &stHSMScore) == GH3X2X_RET_OK)\r
+    {\r
+        if (stHSMDataOut.uchStageDataFlag != 0)\r
+        {\r
+            pstFrameInfo->pstAlgoResult->uchUpdateFlag = 1;\r
+            pstFrameInfo->pstAlgoResult->snResult[0] = 1;\r
+            GU8 uchHsmResultSendBuffer[235] = {0};\r
+            GU8 uchHsmPackLen = 140;\r
+            uchHsmResultSendBuffer[4] = stHSMDataOut.uchStageDataFlag;\r
+            GH3X2X_Memcpy(uchHsmResultSendBuffer + 1 + 4, (GU8*)&stHSMScore, 18);\r
+            uchHsmResultSendBuffer[23] = stHSMDataOut.uchStageOutNum;\r
+            GH3X2X_Memcpy(uchHsmResultSendBuffer + 1 + 4 + 19, stHSMDataOut.puchHSMStageOut, 120);\r
+            GU16 usRespondLen = GH3X2X_UprotocolPacketFormat(GH3X2X_UPROTOCOL_CMD_HSM_RESULT_UPDATE, uchHsmResultSendBuffer,\r
+                                                    &uchHsmResultSendBuffer[4], uchHsmPackLen);\r
+            Gh3x2xDemoSendProtocolData(uchHsmResultSendBuffer,usRespondLen);\r
+        }\r
+    }\r
+    else\r
+    {\r
+        GH3X2X_DEBUG_ALGO_LOG("hsm process error!\r\n");\r
+    }\r
+#else\r
+    return;\r
+#endif\r
+}\r
+\r
+#endif\r
+\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_call/src/gh3x2x_demo_algo_call_nadt.c b/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_call/src/gh3x2x_demo_algo_call_nadt.c
new file mode 100644 (file)
index 0000000..a1da183
--- /dev/null
@@ -0,0 +1,282 @@
+#include "gh3x2x_demo_algo_call.h"\r
+#include "gh3x2x_demo_algorithm_calc.h"\r
+#include "goodix_mem.h"\r
+#include "goodix_nadt.h"\r
+\r
+#if (__USE_GOODIX_SOFT_ADT_ALGORITHM__)\r
+\r
+#define NADT_CONFIG_SAMPLE_RATE_TYPE                (0)\r
+#define NADT_CONFIG_MULTI_SAMPLE_RATE_TYPE          (0)\r
+\r
+#define SOFT_WEAR_INPUT_DATA_CHNL0_INDEX            (0)\r
+#define SOFT_WEAR_INPUT_DATA_ACCX_INDEX             (1)\r
+#define SOFT_WEAR_INPUT_DATA_ACCY_INDEX             (2)\r
+#define SOFT_WEAR_INPUT_DATA_ACCZ_INDEX             (3)\r
+#define SOFT_WEAR_INPUT_COLOR_INDEX                 (4)\r
+#define SOFT_WEAR_INPUT_DATA_ADT_INDEX              (5) //ir  adt data\r
+#define SOFT_WEAR_INPUT_DATA_BG_INDEX               (6)\r
+#define SOFT_WEAR_INPUT_DATA_CAP0_INDEX             (7)\r
+#define SOFT_WEAR_INPUT_DATA_CAP1_INDEX             (8)\r
+#define SOFT_WEAR_INPUT_DATA_CAP2_INDEX             (9)\r
+#define SOFT_WEAR_INPUT_DATA_CAP3_INDEX             (10)\r
+#define SOFT_WEAR_INPUT_DATA_INDEX_TOTAL            (11)\r
+#define SOFT_WEAR_OUTPUT_DATA_INDEX_TOTAL           (8)\r
+#define WATCH_NUM                                   (3)\r
+\r
+#if (WATCH_NUM == 1)\r
+static GS32 lWearCap1 = 16400;\r
+static GS32 lUnwearCap1 = 12400;\r
+static GS32 lNoise1 = 300;\r
+static GS32 lWearCap2 = 0;\r
+static GS32 lUnwearCap2 = 0;\r
+static GS32 lNoise2 = 0;\r
+#elif (WATCH_NUM == 2)\r
+static GS32 lWearCap1 = 20000;\r
+static GS32 lUnwearCap1 = 16000;\r
+static GS32 lNoise1 = 200;\r
+static GS32 lWearCap2 = 3700;\r
+static GS32 lUnwearCap2 = 1200;\r
+static GS32 lNoise2 = 200;\r
+#elif (WATCH_NUM == 3)\r
+static GS32 lWearCap1 = 42500;\r
+static GS32 lUnwearCap1 = 39500;\r
+//static GS32 lNoise1 = 150;\r
+static GS32 lWearCap2 = 42500;\r
+static GS32 lUnwearCap2 = 39500;\r
+//static GS32 lNoise2 = 150;\r
+#endif\r
+\r
+//static GS32 ghbrelsult[10];\r
+//static GS32 glConfig[3] = { 0 };\r
+static GU8  g_uchSoftAdtChannl0Color;   // 0: green   1: ir\r
+static GU32 g_unNadtIrDefaultTimeOutRecord = 0;\r
+static GU32 g_unNadtIrDefaultTimeOutSecondsThrd = __SOFT_ADT_IR_DETECT_TIMEOUT__;\r
+static GU8 g_SoftWearQuality = 0;\r
+NADT_ST_MID_INFO stMidInfo;\r
+extern GU8 g_SoftAdtWearState;\r
+\r
+void Gh3x2x_SetIRDetectTimeThreshold(GU32 unIRDetectTimeThreshold)\r
+{\r
+    g_unNadtIrDefaultTimeOutSecondsThrd = unIRDetectTimeThreshold;\r
+}\r
+\r
+void SoftWearControlInit(const STGh3x2xFrameInfo *const pstFrameInfo)\r
+{\r
+    g_SoftAdtWearState = GH3X2X_SOFT_ALGO_ADT_DEFAULT;\r
+    GCHAR uchNadtVersion[100] = {0};\r
+\r
+    GetNadtVersion((uint8_t *)uchNadtVersion);\r
+    GH3X2X_DEBUG_ALGO_LOG("[%s]nadt algorithm version : %s\r\n", __FUNCTION__, uchNadtVersion);\r
+\r
+    goodix_nadt_config stNadtCfg = {\r
+                                        pstFrameInfo->pstFunctionInfo->usSampleRate, // 采样率\r
+                                        3,                                           // 佩戴等级\r
+                                        0,                                           // 睡眠状态\r
+                                        1200,                                        // 活体检测超时时间\r
+                                        4,                                           // 脱落确认时间\r
+                                        2,                                           // 活体确认时间\r
+                                        8638608,                                     // ADT wear on阈值\r
+                                        8588608,                                     // ADT wear off阈值\r
+                                        25,                                          // ACC阈值\r
+                                        1,                                           // 活体检测使能标记\r
+                                        300,                                         // 高次谐波含量阈值\r
+                                        50,                                          // 心率下限\r
+                                        140,                                         // 心率上限\r
+                                        8,                                           // 心率周期差异阈值\r
+                                        50,                                          // 信号平稳性分数阈值\r
+                                        30,                                          // 基线单调性阈值\r
+                                        15,                                          // 基线平坦性阈值\r
+                                        1000,                                        // 归一化信号阈值放大系数\r
+                                        1,                                           // 环境光突变检测使能标记\r
+                                        100,                                         // 突变环境光变化量阈值\r
+                                        12,                                          // 突变环境光峰谷个数阈值\r
+                                        1,                                           // 环境光周期检测使能标记\r
+                                        10,                                          // 周期环境光变化量阈值\r
+                                        10,                                          // 环境光周期阈值\r
+                                        5                                            // 环境光周期差异阈值\r
+                                   };\r
+    GH3X2X_DEBUG_ALGO_LOG("[%s]nadt param0 : %d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,\r\n", __FUNCTION__, stNadtCfg.sampleRateNADT, \\r
+        stNadtCfg.unwearDetectLevel, stNadtCfg.sleepStatus, stNadtCfg.checkTimeoutThr, stNadtCfg.unwearCheckCntThr, stNadtCfg.wearCheckCntThr, \\r
+        stNadtCfg.adtWearOnThr, stNadtCfg.adtWearOffThr, stNadtCfg.accStdThr, stNadtCfg.liveDetectEnable, stNadtCfg.rawPVLenThr, \\r
+        stNadtCfg.heartBeatThrLow, stNadtCfg.heartBeatThrHigh, stNadtCfg.difRrInterThr, stNadtCfg.wearAcfScoreThr);\r
+    GH3X2X_DEBUG_ALGO_LOG("[%s]nadt param1 : %d,%d,%d,%d,%d,%d,%d,%d,%d,%d,\r\n", __FUNCTION__, stNadtCfg.baseLinePosRatioThr, \\r
+        stNadtCfg.baseLineDiffThr, stNadtCfg.sigScaleThr, stNadtCfg.bgJumpDetectEnable, stNadtCfg.jumpBgDiffThr, stNadtCfg.bgPeakValleyNumThr, \\r
+        stNadtCfg.bgPeriodDetectEnable, stNadtCfg.periodBgDiffThr, stNadtCfg.bgPeriodThr, stNadtCfg.bgPeriodDiffThr);\r
+\r
+    const void *p_CfgInstance = (void *)&stNadtCfg;\r
+    char chVer[NADT_INTERFACE_VERSION_LEN_MAX] = {0};\r
+\r
+    goodix_nadt_config_get_version(chVer, NADT_INTERFACE_VERSION_LEN_MAX);\r
+    const char *p_InterfaceVer = chVer;\r
+\r
+    NADTProcInit(p_CfgInstance, sizeof(stNadtCfg), p_InterfaceVer);\r
+    memset(&stMidInfo, 0, sizeof(NADT_ST_MID_INFO));\r
+}\r
+\r
+void GH3x2xCapNadtResultPro(const STGh3x2xFrameInfo * const pstFrameInfo,GS32  pnSoftWearOffDetResult[])\r
+{\r
+    if (pnSoftWearOffDetResult[3])            // 电容更新标记,更新佩戴检测阈值\r
+    {\r
+        pstFrameInfo->pstAlgoResult->uchUpdateFlag = 1;\r
+        lUnwearCap1 = pnSoftWearOffDetResult[4];\r
+        lWearCap1 = pnSoftWearOffDetResult[5];\r
+        lUnwearCap2 = pnSoftWearOffDetResult[6];\r
+        lWearCap2 = pnSoftWearOffDetResult[7];\r
+    }\r
+    if(g_SoftWearQuality != pnSoftWearOffDetResult[2])\r
+    {\r
+        pstFrameInfo->pstAlgoResult->uchUpdateFlag = 1;\r
+        g_SoftWearQuality = pnSoftWearOffDetResult[2];\r
+    }\r
+    if(pstFrameInfo->punFrameCnt == 0)\r
+    {\r
+        pstFrameInfo->pstAlgoResult->uchUpdateFlag = 1;\r
+    }\r
+    if(pstFrameInfo->pstAlgoResult->uchUpdateFlag == 1)\r
+    {\r
+        pstFrameInfo->pstAlgoResult->usResultBit = 0x7;\r
+        pstFrameInfo->pstAlgoResult->uchResultNum = GH3x2x_BitCount(pstFrameInfo->pstAlgoResult->usResultBit);      \r
+        pstFrameInfo->pstAlgoResult->snResult[0] = pnSoftWearOffDetResult[0]; // (bit0-bit1):佩戴状态(0默认,1佩戴,2脱落,3非活体); (bit2):疑似脱落标记(0正常,1疑似脱落);\r
+        pstFrameInfo->pstAlgoResult->snResult[1] = pnSoftWearOffDetResult[1]; //活体检测置信度\r
+        pstFrameInfo->pstAlgoResult->snResult[2] = pnSoftWearOffDetResult[2]; //佩戴质量(1紧佩戴,2松佩戴,3极度松佩戴,4脱落);\r
+        if(pstFrameInfo->punFrameCnt == 0)\r
+        {\r
+            pstFrameInfo->pstAlgoResult->usResultBit = 0x7F;\r
+            pstFrameInfo->pstAlgoResult->snResult[3] = lUnwearCap1; //脱落电容值1;\r
+            pstFrameInfo->pstAlgoResult->snResult[4] = lWearCap1; //佩戴电容值1;\r
+            pstFrameInfo->pstAlgoResult->snResult[5] = lUnwearCap2; //脱落电容值2;\r
+            pstFrameInfo->pstAlgoResult->snResult[6] = lWearCap2; //佩戴电容值2;\r
+        }\r
+        else\r
+        {\r
+            pstFrameInfo->pstAlgoResult->usResultBit = 0x7F;\r
+            pstFrameInfo->pstAlgoResult->snResult[3] = pnSoftWearOffDetResult[4]; //脱落电容值1;\r
+            pstFrameInfo->pstAlgoResult->snResult[4] = pnSoftWearOffDetResult[5]; //佩戴电容值1;\r
+            pstFrameInfo->pstAlgoResult->snResult[5] = pnSoftWearOffDetResult[6]; //脱落电容值2;\r
+            pstFrameInfo->pstAlgoResult->snResult[6] = pnSoftWearOffDetResult[7]; //佩戴电容值2;\r
+        }\r
+    }\r
+}\r
+\r
+GS8 GH3x2xSoftAdtAlgoExe(const STGh3x2xFrameInfo * const pstFrameInfo)\r
+{\r
+    GS32 nSoftWearOffInputBuf[SOFT_WEAR_INPUT_DATA_INDEX_TOTAL] = {0};\r
+    GS32 pnSoftWearOffDetResult[SOFT_WEAR_OUTPUT_DATA_INDEX_TOTAL] = {0};\r
+\r
+    if(pstFrameInfo)\r
+    {\r
+        GU32 unLedAdjFlag = 0;\r
+\r
+        if(pstFrameInfo->punFrameFlag[0]&0x00000001)  //led current change\r
+        {\r
+            unLedAdjFlag = 1;\r
+        }\r
+        if((0xFF != pstFrameInfo->puchFrameLastGain[0])&&((pstFrameInfo->punFrameAgcInfo[0]&0x0000000F) != pstFrameInfo->puchFrameLastGain[0]))  //tia gain change\r
+        {\r
+            unLedAdjFlag = 1;\r
+        }\r
+\r
+        nSoftWearOffInputBuf[SOFT_WEAR_INPUT_DATA_ACCX_INDEX] = pstFrameInfo->pusFrameGsensordata[0];\r
+        nSoftWearOffInputBuf[SOFT_WEAR_INPUT_DATA_ACCY_INDEX] = pstFrameInfo->pusFrameGsensordata[1];\r
+        nSoftWearOffInputBuf[SOFT_WEAR_INPUT_DATA_ACCZ_INDEX] = pstFrameInfo->pusFrameGsensordata[2];\r
+        nSoftWearOffInputBuf[SOFT_WEAR_INPUT_DATA_CHNL0_INDEX] = pstFrameInfo->punFrameRawdata[0];\r
+        nSoftWearOffInputBuf[SOFT_WEAR_INPUT_DATA_CHNL0_INDEX] |= (unLedAdjFlag << 26);  //led adj flag\r
+        nSoftWearOffInputBuf[SOFT_WEAR_INPUT_COLOR_INDEX]      =  g_uchSoftAdtChannl0Color;      //0:GREEN  1:IR\r
+        nSoftWearOffInputBuf[SOFT_WEAR_INPUT_DATA_ADT_INDEX]   = pstFrameInfo->punFrameRawdata[1];\r
+        nSoftWearOffInputBuf[SOFT_WEAR_INPUT_DATA_BG_INDEX]    = pstFrameInfo->punFrameRawdata[2];\r
+\r
+        if (g_uchAlgoCapEnable == 1)\r
+        {\r
+            for (int k = 0; k < 4; k++)\r
+            {\r
+                nSoftWearOffInputBuf[SOFT_WEAR_INPUT_DATA_CAP0_INDEX + k] = pstFrameInfo->pstFrameCapdata->unCapData[k];//  [PPGACCLEN + ALGOLEN + guchCompareNum + k]; //电容\r
+            }\r
+        }\r
+\r
+        goodix_nadt_ret uchRet = NADTProc(nSoftWearOffInputBuf, pnSoftWearOffDetResult, &stMidInfo);\r
+        GU32 unNadtIrDefaultTimeOutThrd = g_unNadtIrDefaultTimeOutSecondsThrd * pstFrameInfo->pstFunctionInfo->usSampleRate;\r
+        if (g_unNadtIrDefaultTimeOutRecord >= unNadtIrDefaultTimeOutThrd && ((pnSoftWearOffDetResult[0] & 0x3) == 0))\r
+        {\r
+            pnSoftWearOffDetResult[0] = pnSoftWearOffDetResult[0] | 0x1;\r
+            g_unNadtIrDefaultTimeOutRecord = 0;\r
+        }\r
+\r
+        if ((pnSoftWearOffDetResult[0] & 0x2) == 0)\r
+        {\r
+            if (GH3X2X_FUNCTION_SOFT_ADT_IR == pstFrameInfo->unFunctionID)\r
+            {\r
+                g_unNadtIrDefaultTimeOutRecord++;\r
+            }\r
+        }\r
+\r
+        if (GX_ALGO_NADT_SUCCESS != uchRet)\r
+        {\r
+            GH3X2X_DEBUG_ALGO_LOG("[GH3x2xSoftAdtAlgoExe]NADTProc: error! error code = 0x%x\r\n", uchRet);\r
+        }\r
+\r
+        if (g_uchAlgoCapEnable == 1)\r
+        {\r
+            GH3x2xCapNadtResultPro(pstFrameInfo, pnSoftWearOffDetResult);\r
+        }\r
+        else\r
+        {\r
+            pstFrameInfo->pstAlgoResult->uchUpdateFlag = 1;\r
+            pstFrameInfo->pstAlgoResult->usResultBit = 0x3;\r
+            pstFrameInfo->pstAlgoResult->uchResultNum = GH3x2x_BitCount(pstFrameInfo->pstAlgoResult->usResultBit);\r
+            pstFrameInfo->pstAlgoResult->snResult[0] = pnSoftWearOffDetResult[0]; // (bit0-bit1):佩戴状态(0默认,1佩戴,2脱落,3非活体); (bit2):疑似脱落标记(0正常,1疑似脱落);\r
+            pstFrameInfo->pstAlgoResult->snResult[1] = pnSoftWearOffDetResult[1]; // 活体检测置信度\r
+            GH3X2X_DEBUG_ALGO_LOG("[nadt] wear status:%d %d, confiidence = %d\r\n", pstFrameInfo->pstAlgoResult->snResult[0] & 0x3, \\r
+                (pstFrameInfo->pstAlgoResult->snResult[0] >> 2) & 0x1, pstFrameInfo->pstAlgoResult->snResult[1]);\r
+        }\r
+\r
+        //report\r
+        if (g_uchSoftAdtChannl0Color == 0)\r
+        {\r
+            GH3X2X_SoftAdtGreenAlgorithmResultReport(pstFrameInfo->pstAlgoResult, GH3X2X_GET_BYTE0_FROM_DWORD(*(pstFrameInfo->punFrameCnt)));\r
+        }\r
+        else if(g_uchSoftAdtChannl0Color == 1)\r
+        {\r
+            GH3X2X_SoftAdtIrAlgorithmResultReport(pstFrameInfo->pstAlgoResult, GH3X2X_GET_BYTE0_FROM_DWORD(*(pstFrameInfo->punFrameCnt)));\r
+        }\r
+    }\r
+    return GH3X2X_RET_OK;\r
+}\r
+\r
+\r
+GS8 GH3x2xSoftAdtAlgoInit(const STGh3x2xFrameInfo *const pstFrameInfo)\r
+{\r
+    if (pstFrameInfo)\r
+    {\r
+        g_SoftWearQuality  = 0;\r
+        g_uchSoftAdtChannl0Color = 1 * (GH3X2X_FUNCTION_SOFT_ADT_IR == (pstFrameInfo ->unFunctionID));\r
+\r
+        GH3X2X_DEBUG_ALGO_LOG("[SoftAdt]CH0 slot = %d, rx = %d\r\n", GH3X2X_BYTE_RAWDATA_GET_SLOT_NUM(pstFrameInfo ->pchChnlMap[0]), \\r
+            GH3X2X_BYTE_RAWDATA_GET_ADC_NUM(pstFrameInfo ->pchChnlMap[0]));\r
+        GH3X2X_DEBUG_ALGO_LOG("[SoftAdt]CH1 slot = %d, rx = %d\r\n", GH3X2X_BYTE_RAWDATA_GET_SLOT_NUM(pstFrameInfo ->pchChnlMap[1]), \\r
+            GH3X2X_BYTE_RAWDATA_GET_ADC_NUM(pstFrameInfo ->pchChnlMap[1]));\r
+        GH3X2X_DEBUG_ALGO_LOG("[SoftAdt]CH2 slot = %d, rx = %d\r\n", GH3X2X_BYTE_RAWDATA_GET_SLOT_NUM(pstFrameInfo ->pchChnlMap[2]), \\r
+            GH3X2X_BYTE_RAWDATA_GET_ADC_NUM(pstFrameInfo ->pchChnlMap[2]));\r
+        GH3X2X_DEBUG_ALGO_LOG("[SoftAdt]g_uchSoftAdtChannl0Color = %d\r\n", g_uchSoftAdtChannl0Color);\r
+\r
+        SoftWearControlInit(pstFrameInfo);\r
+    }\r
+\r
+    return GH3X2X_RET_OK;\r
+}\r
+\r
+GS8 GH3x2xSoftAdtAlgoDeinit(const STGh3x2xFrameInfo *const pstFrameInfo)\r
+{\r
+    GH3X2X_DEBUG_ALGO_LOG("[SoftAdt]%s\r\n", __FUNCTION__);\r
+\r
+    goodix_nadt_ret ret = NADTProcDeinit();\r
+    g_unNadtIrDefaultTimeOutRecord = 0;\r
+    if (GX_ALGO_NADT_SUCCESS != ret)\r
+    {\r
+        GH3X2X_DEBUG_ALGO_LOG("[%s] fail! error code = 0x%x\r\n", __FUNCTION__, ret);\r
+        return GH3X2X_RET_GENERIC_ERROR;\r
+    }\r
+\r
+    return GH3X2X_RET_OK;\r
+}\r
+\r
+#endif\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_call/src/gh3x2x_demo_algo_call_resp.c b/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_call/src/gh3x2x_demo_algo_call_resp.c
new file mode 100644 (file)
index 0000000..fdb829c
--- /dev/null
@@ -0,0 +1,72 @@
+#include <stdio.h>\r
+#include "gh3x2x_demo_algo_call.h"\r
+#include "gh3x2x_demo_algorithm_calc.h"\r
+#include "gh3x2x_demo_algo_config.h"\r
+#include "goodix_resp.h"\r
+\r
+#if (__USE_GOODIX_RESP_ALGORITHM__)\r
+\r
+GS8 GH3x2xRespAlgoInit(const STGh3x2xFrameInfo * const pstFrameInfo)\r
+{\r
+    GS8 chRet = GH3X2X_RET_GENERIC_ERROR;\r
+    GH3X2X_DEBUG_ALGO_LOG("%s\r\n", __FUNCTION__);\r
+    g_pstGh3x2xAlgoFrameInfo[GH3X2X_FUNC_OFFSET_RESP]->puchFrameLastGain[0] = GH3X2X_GAIN_VALUE_INVALID;\r
+    GS32 nRespFs = ((GS32)(pstFrameInfo ->pstFunctionInfo ->usSampleRate) & 0xFFFF);\r
+    chRet = RespInit(&nRespFs);\r
+    if (chRet == GH3X2X_RET_OK)\r
+    {\r
+        pstFrameInfo->pstAlgoResult->usResultBit = 0x3;\r
+    }\r
+    return chRet;\r
+}\r
+\r
+GS8 GH3x2xRespAlgoDeinit(const STGh3x2xFrameInfo * const pstFrameInfo)\r
+{\r
+    GS8 chRet = GH3X2X_RET_GENERIC_ERROR;\r
+\r
+    GH3X2X_DEBUG_ALGO_LOG("%s\r\n", __FUNCTION__);\r
+    RespDeInit();\r
+    chRet = GH3X2X_RET_OK;\r
+    return chRet;\r
+}\r
+\r
+GS8 GH3x2xRespAlgoExe(const STGh3x2xFrameInfo * const pstFrameInfo)\r
+{\r
+    if(0 == pstFrameInfo )\r
+    {\r
+        return GH3X2X_RET_GENERIC_ERROR;\r
+    }\r
+    RESP_ST_DATA_IN stRespDataIn = {0};\r
+    RESP_ST_DATA_OUT stRespDataOut = {0};\r
+    GU8 uchGainValue = 0;\r
+    \r
+    stRespDataIn.IPpgRaw = GH3X2X_GET_RAWDATA_FOR_ALGO(pstFrameInfo->punFrameRawdata[0] - GH3X2X_RAWDATA_BASE_VALUE);\r
+    stRespDataIn.IACCx = pstFrameInfo->pusFrameGsensordata[0];\r
+    stRespDataIn.IACCy = pstFrameInfo->pusFrameGsensordata[1];\r
+    stRespDataIn.IACCz = pstFrameInfo->pusFrameGsensordata[2];\r
+    \r
+    uchGainValue = GH3X2X_GET_LOW_4BITS(pstFrameInfo->punFrameAgcInfo[0]);\r
+    if (((pstFrameInfo->puchFrameLastGain[0] != uchGainValue) && \\r
+        (pstFrameInfo->puchFrameLastGain[0] != GH3X2X_GAIN_VALUE_INVALID)) ||\\r
+        ((pstFrameInfo->punFrameFlag[0]) & 0x01))\r
+    {\r
+        stRespDataIn.IAdjFlag = 1;\r
+        pstFrameInfo->puchFrameLastGain[0] = uchGainValue;\r
+    }\r
+\r
+    GU8 chRet = RespProc(&stRespDataIn, &stRespDataOut);\r
+\r
+    if (1 == stRespDataOut.nRespOutFlag && chRet == 0)\r
+    {\r
+        pstFrameInfo->pstAlgoResult->uchUpdateFlag = 1;\r
+        pstFrameInfo->pstAlgoResult->snResult[0]   = (GS32)stRespDataOut.nRespRate;\r
+        pstFrameInfo->pstAlgoResult->snResult[1]   = (GS32)stRespDataOut.nBelieve;        \r
+        pstFrameInfo->pstAlgoResult->usResultBit = 0x3;\r
+        pstFrameInfo->pstAlgoResult->uchResultNum = GH3x2x_BitCount(pstFrameInfo->pstAlgoResult->usResultBit);\r
+        //GH3X2X_HrvAlgorithmResultReport(pstFrameInfo->pstAlgoResult,stRawdata.frameid);\r
+    }\r
+    return chRet;\r
+}\r
+\r
+#endif\r
+\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_call/src/gh3x2x_demo_algo_call_spo2.c b/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_algo_code/goodix_algo_call/src/gh3x2x_demo_algo_call_spo2.c
new file mode 100644 (file)
index 0000000..1ea4ab0
--- /dev/null
@@ -0,0 +1,218 @@
+#include "gh3x2x_demo_algo_call.h"\r
+#include "gh3x2x_demo_algorithm_calc.h"\r
+#include "gh3x2x_demo_algo_config.h"\r
+#include "goodix_algo.h"\r
+#include "goodix_spo2.h"\r
+\r
+#if (__USE_GOODIX_SPO2_ALGORITHM__)\r
+\r
+goodix_spo2_ret goodix_spo2_init_func(GU32 fs)\r
+{\r
+    goodix_spo2_ret stAlgoRet = GX_ALGO_SPO2_SUCCESS;\r
+    GCHAR uchSpo2Version[150] = {0};\r
+\r
+    GH3X2X_Spo2AlgoChnlMapDefultSet();\r
+    goodix_spo2_version((uint8_t *)uchSpo2Version);\r
+    GH3X2X_DEBUG_ALGO_LOG("spo2 algorithm version : %s\r\n", uchSpo2Version);\r
+    GH3X2X_DEBUG_ALGO_LOG("spo2 algorithm legal chnl num : %d\r\n", g_stSpo2AlgoChnlMap.uchNum);\r
+\r
+    if (g_stSpo2AlgoChnlMap.uchNum > Gh3x2xGetSpo2AlgoSupportChnl())\r
+    {\r
+        GH3X2X_DEBUG_ALGO_LOG("ERROR: spo2 algorithm legal chnl num is too big, check cfg !!! \r\n");\r
+        return GX_ALGO_SPO2_RWONG_INPUT;\r
+    }\r
+\r
+    goodix_spo2_config stSpo2Cfg = {\r
+            g_stSpo2AlgoChnlMap.uchNum, // 有效通道数\r
+            fs,                         // 采样率\r
+            g_nSpo2ParamssArr[0], g_nSpo2ParamssArr[1], g_nSpo2ParamssArr[2], g_nSpo2ParamssArr[3],\r
+            g_nSpo2ParamssArr[4], g_nSpo2ParamssArr[5], g_nSpo2ParamssArr[6], g_nSpo2ParamssArr[7],\r
+            g_nSpo2ParamssArr[8], g_nSpo2ParamssArr[9], g_nSpo2ParamssArr[10], g_nSpo2ParamssArr[11],\r
+            g_nSpo2ParamssArr[12], g_nSpo2ParamssArr[13], g_nSpo2ParamssArr[14], g_nSpo2ParamssArr[15],\r
+            g_nSpo2ParamssArr[16], g_nSpo2ParamssArr[17], g_nSpo2ParamssArr[18], g_nSpo2ParamssArr[19],\r
+            g_nSpo2ParamssArr[20], g_nSpo2ParamssArr[21], g_nSpo2ParamssArr[22], g_nSpo2ParamssArr[23],\r
+            g_nSpo2ParamssArr[24], g_nSpo2ParamssArr[25]\r
+    };\r
+\r
+    GH3X2X_INFO_ALGO_LOG("[%s]: params1 = %d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\r\n", __FUNCTION__,\r
+                                    stSpo2Cfg.valid_chl_num,\r
+                                    stSpo2Cfg.raw_fs,\r
+                                    stSpo2Cfg.cali_coef_a4,\r
+                                    stSpo2Cfg.cali_coef_a3,\r
+                                    stSpo2Cfg.cali_coef_a2,\r
+                                    stSpo2Cfg.cali_coef_a1,\r
+                                    stSpo2Cfg.cali_coef_a0,\r
+                                    stSpo2Cfg.hb_en_flg,\r
+                                    stSpo2Cfg.wear_mode,\r
+                                    stSpo2Cfg.acc_thr_max,\r
+                                    stSpo2Cfg.acc_thr_min,\r
+                                    stSpo2Cfg.acc_thr_scale,\r
+                                    stSpo2Cfg.acc_thr_num,\r
+                                    stSpo2Cfg.acc_thr_angle,\r
+                                    stSpo2Cfg.ctr_en_flg,\r
+                                    stSpo2Cfg.ctr_red_thr);\r
+\r
+    GH3X2X_INFO_ALGO_LOG("[%s]: params2 = %d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\r\n", __FUNCTION__,\r
+                                    stSpo2Cfg.ppg_jitter_thr,\r
+                                    stSpo2Cfg.ppg_noise_thr,\r
+                                    stSpo2Cfg.ppg_coeff_thr,\r
+                                    stSpo2Cfg.quality_module_key,\r
+                                    stSpo2Cfg.low_spo2_thr,\r
+                                    stSpo2Cfg.fast_out_time,\r
+                                    stSpo2Cfg.slow_out_time,\r
+                                    stSpo2Cfg.min_stable_time_high,\r
+                                    stSpo2Cfg.min_stable_time_low,\r
+                                    stSpo2Cfg.max_spo2_variation_high,\r
+                                    stSpo2Cfg.max_spo2_variation_low,\r
+                                    stSpo2Cfg.ouput_module_key);\r
+\r
+    const void *p_CfgInstance = (void *)&stSpo2Cfg;\r
+    char chVer[SPO2_INTERFACE_VERSION_LEN_MAX] = {0};\r
+\r
+    goodix_spo2_config_get_version(chVer, SPO2_INTERFACE_VERSION_LEN_MAX);\r
+    //const char *p_InterfaceVer = chVer;\r
+\r
+    stAlgoRet = goodix_spo2_init(p_CfgInstance, sizeof(stSpo2Cfg), chVer);\r
+\r
+    return stAlgoRet;\r
+}\r
+\r
+goodix_spo2_ret goodix_spo2_deinit_func(void)\r
+{\r
+    return goodix_spo2_deinit();\r
+}\r
+\r
+GS8 GH3x2xSpo2AlgoInit(const STGh3x2xFrameInfo *const pstFrameInfo)\r
+{\r
+    GS8 chRet = GH3X2X_RET_GENERIC_ERROR;\r
+\r
+    GH3X2X_DEBUG_ALGO_LOG("%s\r\n", __FUNCTION__);\r
+\r
+    goodix_spo2_ret ret = goodix_spo2_init_func(pstFrameInfo->pstFunctionInfo->usSampleRate);\r
+    if (GX_ALGO_SPO2_SUCCESS == ret)\r
+    {\r
+        chRet = GH3X2X_RET_OK;\r
+    }\r
+    else\r
+    {\r
+        GH3X2X_DEBUG_ALGO_LOG("spo2 init error! error code:0x%x\r\n", ret);\r
+    }\r
+\r
+    return chRet;\r
+}\r
+\r
+GS8 GH3x2xSpo2AlgoDeinit(const STGh3x2xFrameInfo *const pstFrameInfo)\r
+{\r
+    GS8 chRet = GH3X2X_RET_GENERIC_ERROR;\r
+\r
+    GH3X2X_DEBUG_ALGO_LOG("%s\r\n", __FUNCTION__);\r
+\r
+    goodix_spo2_ret ret = goodix_spo2_deinit_func();\r
+    if (GX_ALGO_SPO2_SUCCESS == ret)\r
+    {\r
+        chRet = GH3X2X_RET_OK;\r
+    }\r
+    else\r
+    {\r
+        GH3X2X_DEBUG_ALGO_LOG("spo2 deinit error! error code:0x%x\r\n", ret);\r
+    }\r
+\r
+    return chRet;\r
+}\r
+\r
+GS8 GH3x2xSpo2AlgoExe(const STGh3x2xFrameInfo *const pstFrameInfo)\r
+{\r
+    if (0 == pstFrameInfo)\r
+    {\r
+        return GH3X2X_RET_GENERIC_ERROR;\r
+    }\r
+\r
+    GU8 uchChannelNum = 0;\r
+       GS32 ppg_rawdata[3 * CHIP_PPG_CHL_NUM] = {0};\r
+       GS8 cur_adj_flg[3 * CHIP_PPG_CHL_NUM] = {0};\r
+       GS8 gain_adj_flg[3 * CHIP_PPG_CHL_NUM] = {0};\r
+       GS8 enable_flg[3 * CHIP_PPG_CHL_NUM] = {0};\r
+       GS32 ch_agc_drv0[3 * CHIP_PPG_CHL_NUM] = {0};\r
+       GS32 ch_agc_drv1[3 * CHIP_PPG_CHL_NUM] = {0};\r
+       GS8 ch_agc_gain[3 * CHIP_PPG_CHL_NUM] = {0};\r
+\r
+    goodix_spo2_input_rawdata stRawdata = {0};\r
+    goodix_spo2_result stResult = {0};\r
+    GS8 emAlgoRet = GH3X2X_RET_OK;\r
+\r
+    stRawdata.frameid = GH3X2X_GET_BYTE0_FROM_DWORD(*(pstFrameInfo->punFrameCnt));\r
+    stRawdata.bit_num = 24;\r
+    stRawdata.ppg_rawdata = ppg_rawdata;\r
+    stRawdata.cur_adj_flg = cur_adj_flg;\r
+    stRawdata.gain_adj_flg = gain_adj_flg;\r
+    stRawdata.enable_flg = enable_flg;\r
+    stRawdata.ch_agc_drv0 = ch_agc_drv0;\r
+    stRawdata.ch_agc_drv1 = ch_agc_drv1;\r
+    stRawdata.ch_agc_gain = ch_agc_gain;\r
+    stRawdata.acc_x = pstFrameInfo->pusFrameGsensordata[0]; // 46\r
+    stRawdata.acc_y = pstFrameInfo->pusFrameGsensordata[1]; // -183\r
+    stRawdata.acc_z = pstFrameInfo->pusFrameGsensordata[2]; // 482\r
+    stRawdata.wear_on_flag = 1;\r
+\r
+    /* call algorithm, update result */\r
+    for (GU8 uchChMapCnt = 0; uchChMapCnt < CHIP_PPG_CHL_NUM * 3; ++uchChMapCnt)\r
+    {\r
+        if (g_stSpo2AlgoChnlMap.uchAlgoChnlMap[uchChMapCnt + 4 * (uchChMapCnt / 4)] < 0xff)\r
+        {\r
+            GU8 uchRawdataIndex = g_stSpo2AlgoChnlMap.uchAlgoChnlMap[uchChMapCnt + 4 * (uchChMapCnt / 4)];\r
+\r
+            stRawdata.ch_agc_drv0[uchChMapCnt]  = ((pstFrameInfo->punFrameAgcInfo[uchRawdataIndex] >> 8) & 0xFF);\r
+            stRawdata.ch_agc_drv1[uchChMapCnt]  = ((pstFrameInfo->punFrameAgcInfo[uchRawdataIndex] >> 16) & 0xFF);\r
+            stRawdata.ch_agc_gain[uchChMapCnt]  = (pstFrameInfo->punFrameAgcInfo[uchRawdataIndex] & 0xF);\r
+\r
+            if (((pstFrameInfo->puchFrameLastGain[uchRawdataIndex] != stRawdata.ch_agc_gain[uchChMapCnt]) && \\r
+                (pstFrameInfo->puchFrameLastGain[uchRawdataIndex] != GH3X2X_GAIN_VALUE_INVALID)) || \\r
+                ((pstFrameInfo->punFrameFlag[0]) & 0x01))\r
+            {\r
+                stRawdata.gain_adj_flg[uchChMapCnt] = 1;\r
+                pstFrameInfo->puchFrameLastGain[uchRawdataIndex] = stRawdata.ch_agc_gain[uchChMapCnt];\r
+            }\r
+            stRawdata.cur_adj_flg[uchChMapCnt] = (((pstFrameInfo->punFrameFlag[0]) >> uchRawdataIndex) & 0x01);\r
+            stRawdata.enable_flg[uchChMapCnt]  = 1;\r
+            stRawdata.ppg_rawdata[uchChMapCnt] = pstFrameInfo->punFrameRawdata[uchRawdataIndex];\r
+            uchChannelNum++;\r
+\r
+            GH3X2X_DEBUG_ALGO_LOG("[%s] ch%d ppg_rawdata = %d,gain_adj_flg = %d,cur_adj_flg = %d\r\n", __FUNCTION__, uchChMapCnt, \\r
+                (int)stRawdata.ppg_rawdata[uchChMapCnt], (int)stRawdata.gain_adj_flg[uchChMapCnt], \\r
+                (int)stRawdata.cur_adj_flg[uchChMapCnt]);\r
+        }\r
+    }\r
+    stRawdata.ch_num = CHIP_PPG_CHL_NUM;\r
+\r
+    goodix_spo2_ret ret = goodix_spo2_calc(&stRawdata, &stResult);\r
+    // goodix_spo2_essential_info_print(&stRawdata);\r
+\r
+    if (GX_ALGO_SPO2_SUCCESS == ret || GX_ALGO_SPO2_FRAME_UNCOMPLETE == ret || GX_ALGO_SPO2_WIN_UNCOMPLETE == ret)\r
+    {\r
+        if (1 == stResult.final_calc_flg)\r
+        {\r
+            pstFrameInfo->pstAlgoResult->uchUpdateFlag = (GU8)stResult.final_calc_flg;\r
+            pstFrameInfo->pstAlgoResult->snResult[0] = (GS32)(GH3x2x_Round((float)stResult.final_spo2 / 10000));\r
+            pstFrameInfo->pstAlgoResult->snResult[1] = (GS32)stResult.final_r_val;\r
+            pstFrameInfo->pstAlgoResult->snResult[2] = (GS32)stResult.final_confi_coeff;\r
+            pstFrameInfo->pstAlgoResult->snResult[3] = (GS32)stResult.final_valid_level;\r
+            pstFrameInfo->pstAlgoResult->snResult[4] = (GS32)stResult.final_hb_mean;\r
+            pstFrameInfo->pstAlgoResult->snResult[5] = (GS32)stResult.final_invalidFlg;\r
+            pstFrameInfo->pstAlgoResult->usResultBit = 0x7F;\r
+            pstFrameInfo->pstAlgoResult->uchResultNum = GH3x2x_BitCount(pstFrameInfo->pstAlgoResult->usResultBit);\r
+            GH3X2X_Spo2AlgorithmResultReport(pstFrameInfo->pstAlgoResult, pstFrameInfo->punFrameCnt[0]);\r
+            GH3X2X_DEBUG_ALGO_LOG("[%s] final_spo2:%d, r = %d, final_valid_level:%d\r\n", __FUNCTION__, pstFrameInfo->pstAlgoResult->snResult[0], \\r
+                pstFrameInfo->pstAlgoResult->snResult[1], pstFrameInfo->pstAlgoResult->snResult[3]);\r
+        }\r
+    }\r
+    else\r
+    {\r
+        emAlgoRet = GH3X2X_RET_RESOURCE_ERROR;\r
+        GH3X2X_DEBUG_ALGO_LOG("GH3x2xSpo2AlgoExe error! error code = 0x%x\r\n", ret);\r
+        GH3X2X_DEBUG_ALGO_LOG("please feedback to GOODIX!\r\n");\r
+    }\r
+\r
+    return (GS8)emAlgoRet;\r
+}\r
+\r
+#endif\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/driver/inc/gh_drv.h b/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/driver/inc/gh_drv.h
new file mode 100644 (file)
index 0000000..3b12fcc
--- /dev/null
@@ -0,0 +1,2849 @@
+/**\r
+ * @copyright (c) 2003 - 2022, Goodix Co., Ltd. All rights reserved.\r
+ *\r
+ * @file    gh_drv.h\r
+ *\r
+ * @brief   gh3x2x driver functions\r
+ *\r
+ * @version v4.0.1.2\r
+ *\r
+ * @author  Gooidx Iot Team\r
+ *\r
+ */\r
+\r
+\r
+#ifndef _GH3X2X_DRV_H_\r
+#define _GH3X2X_DRV_H_\r
+\r
+#include <stddef.h>\r
+#include <stdint.h>\r
+\r
+#ifndef UNUSED_VAR\r
+#define UNUSED_VAR(X) ((void)(X))\r
+#endif  // UNUSED_VAR\r
+\r
+/* type redefine */\r
+typedef uint8_t             GU8;    /**< 8bit unsigned integer type */\r
+typedef int8_t              GS8;    /**< 8bit signed integer type */\r
+typedef uint16_t            GU16;   /**< 16bit unsigned integer type */\r
+typedef int16_t             GS16;   /**< 16bit signed integer type */\r
+typedef int32_t             GS32;   /**< 32bit signed integer type */\r
+typedef uint32_t            GU32;   /**< 32bit unsigned integer type */\r
+typedef float               GF32;   /**< float type */\r
+typedef double              GD64;   /**< double type */\r
+typedef char                GCHAR;  /**< char type */\r
+typedef unsigned char       GBOOL;  /**< bool type */\r
+typedef int64_t             GS64;   /**< 64bit signed integer type */\r
+typedef uint64_t            GU64;   /**< 64bit unsigned integer type */\r
+\r
+\r
+\r
+/* communicate interface macro */\r
+#define __GH3X2X_INTERFACE_I2C__            (1)     /**< interface use i2c */\r
+#define __GH3X2X_INTERFACE_SPI__            (2)     /**< interface use spi */\r
+\r
+/* spi cs type macro */\r
+#define __GH3X2X_SPI_TYPE_SOFTWARE_CS__     (1)     /** cs is software controled in spi module  **/\r
+#define __GH3X2X_SPI_TYPE_HARDWARE_CS__     (2)     /** cs is hardtware controled in spi module **/\r
+\r
+/* int process type macro */\r
+#define __NORMAL_INT_PROCESS_MODE__         (0)     /** int event handle int mode **/\r
+#define __POLLING_INT_PROCESS_MODE__        (1)     /** int event handle polling mode **/\r
+#define __MIX_INT_PROCESS_MODE__            (2)     /** int event handle polling+int mode **/\r
+\r
+/* protocol serial type macro */\r
+#define __PROTOCOL_SERIAL_USE_UART__        (1)     /**< protocol communicate use UART */\r
+#define __PROTOCOL_SERIAL_USE_BLE__         (2)     /**< protocol communicate use BLE */\r
+\r
+/* application mode of driver lib */\r
+#define __DRV_LIB_WITHOUT_ALGO__            (1)    /**< not use driver lib interface about algo */\r
+#define __DRV_LIB_WITH_ALGO__               (2)    /**< use driver lib interface about algo */\r
+\r
+/* algo section run mode*/\r
+#define __SINGLE_THREAD_MODE__               (0)    /** section run in one thread **/\r
+#define __MULTI_THREAD_MODE__                (1)    /** section run in two thread **/\r
+#define __MULTI_CORE_MODE__                  (2)    /** section run in two core **/\r
+\r
+/* log method*/\r
+#define __GH3X2X_INFO_LOG_DISABLE__             (0)\r
+#define __GH3X2X_INFO_LOG_METHOD_0__            (1)    /** need to achieve GH3X2X_PlatformLog, and relay on snprintf in <stdio.h> **/\r
+#define __GH3X2X_INFO_LOG_METHOD_1__            (2)    /** need register printf in <stdio.h> via GH3X2X_RegisterPrintf **/\r
+\r
+/* log lv*/\r
+#define __GH3X2X_INFO_LOG_LV_0__                (0)    /** no log **/\r
+#define __GH3X2X_INFO_LOG_LV_1__                (1)    /** include EXAMPLE LOG information **/\r
+#define __GH3X2X_INFO_LOG_LV_2__                (2)    /** include EXAMPLE LOG debug **/\r
+#define __GH3X2X_INFO_LOG_LV_3__                (4)    /** include EXAMPLE LOG waring **/\r
+#define __GH3X2X_INFO_LOG_LV_4__                (8)    /** include EXAMPLE LOG error **/\r
+\r
+/* algorithm config */\r
+/**\r
+ * @brief support multi algorithm run simultaneously type enum\r
+ */\r
+#define SUPPORT_NO_MULTI_ALGORITHM             (0)\r
+#define SUPPORT_MULTI_ALGORITHM                (1)\r
+#define SUPPORT_GROUP_MULTI_ALGORITHM          (2)\r
+\r
+\r
+\r
+/**\r
+ * @brief universal protocol cmd enum\r
+ */\r
+typedef enum\r
+{\r
+    UPROTOCOL_CMD_START = 0x00,             /**< start */\r
+    UPROTOCOL_CMD_STOP,                     /**< stop */\r
+    UPROTOCOL_CMD_EVK_MODE,                 /**< evk work mode */\r
+    UPROTOCOL_CMD_APP_MODE,                 /**< app work mode */\r
+    UPROTOCOL_CMD_MCU_ONLINE_MODE,          /**< mcu online work mode */\r
+    UPROTOCOL_CMD_MCU_OFFLINE_MODE,         /**< mcu offline work mode */\r
+    UPROTOCOL_CMD_TEST_TUNE_MODE,           /**< test tune work mode */\r
+    UPROTOCOL_CMD_PASS_THROUGH_MODE,\r
+    UPROTOCOL_CMD_IRQ_STATUS_REPORT_ACK,    /**< irq status report ack */\r
+    UPROTOCOL_CMD_MPT_MODE,\r
+    UPROTOCOL_CMD_IGNORE = 0xFF,            /**< ignore */\r
+} EMUprotocolParseCmdType;\r
+\r
+/**\r
+ * @brief i2c addr (7bits) low two bit select enum\r
+ */\r
+enum EMGh3x2xI2cIdSelect\r
+{\r
+    GH3X2X_I2C_ID_SEL_1L0L = 0,     /**< i2c ID0 & ID1 pin low */\r
+    GH3X2X_I2C_ID_SEL_1L0H,         /**< i2c ID0 pin high & ID1 pin low */\r
+    GH3X2X_I2C_ID_SEL_1H0L,         /**< i2c ID0 pin low & ID1 pin high */\r
+    GH3X2X_I2C_ID_SEL_1H0H,         /**< i2c ID0 & ID1 pin high */\r
+    GH3X2X_I2C_ID_INVALID,          /**< invalid val */\r
+};\r
+\r
+/**\r
+ * @brief gsensor sensitivity(counts/g) enum\r
+ */\r
+typedef enum\r
+{\r
+    GSENSOR_SENSITIVITY_512_COUNTS_PER_G = 0,   /**< sensitivity = 512/g */\r
+    GSENSOR_SENSITIVITY_1024_COUNTS_PER_G,      /**< sensitivity = 1024/g */\r
+    GSENSOR_SENSITIVITY_2048_COUNTS_PER_G,      /**< sensitivity = 2048/g */\r
+    GSENSOR_SENSITIVITY_4096_COUNTS_PER_G,      /**< sensitivity = 4096/g */\r
+    GSENSOR_SENSITIVITY_8192_COUNTS_PER_G,      /**< sensitivity = 8192/g */\r
+} EMGsensorSensitivity;\r
+\r
+/**\r
+ * @brief slot index enable config enum\r
+ */\r
+typedef enum\r
+{\r
+    GH3X2X_SET_SLOT_ENABLE = 0,        /**< enable slot and last set slot enable */\r
+    GH3X2X_SET_SLOT_DISABLE,           /**< disable slot by set */\r
+    GH3X2X_SET_SLOT_DIRECT_ENABLE,     /**< only enable slot by set */\r
+} EMSlotEnableConfigType;\r
+\r
+/**\r
+ * @brief irq mode config\r
+ */\r
+typedef enum \r
+{ \r
+    IRQ_MODE_LEVEL_HIGH = 0x00,         /**< int pin output high level */\r
+    IRQ_MODE_LEVEL_LOW = 0x01,          /**< int pin output low level */\r
+    IRQ_MODE_EDGE_RISING = 0x02,        /**< int pin output rising edge */\r
+    IRQ_MODE_EDGE_FALLING = 0x03,       /**< int pin output falling edge */\r
+} EMIrqModeConfig;\r
+\r
+\r
+\r
+/**\r
+ * @brief wear detect enable type enum\r
+ */\r
+typedef enum\r
+{\r
+    WEAR_DETECT_DISABLE = 0,   /**< wear detect disable */\r
+    WEAR_DETECT_ENABLE,        /**< wear detect enable */\r
+} EMWearDetectEnableType;\r
+\r
+/**\r
+ * @brief wear detect type enum\r
+ */\r
+typedef enum\r
+{\r
+    WEAR_DETECT_WEAR_ON = 0,   /**< detect wear on */\r
+    WEAR_DETECT_WEAR_OFF,      /**< detect wear off */\r
+} EMWearDetectType;\r
+\r
+/**\r
+ * @brief wear detect force switch enum\r
+ */\r
+typedef enum\r
+{\r
+    WEAR_DETECT_DONT_FORCE_SWITCH = 0,  /**< don't force switch */\r
+    WEAR_DETECT_FORCE_SWITCH,           /**< force switch  */\r
+} EMWearDetectForceSwitch;\r
+\r
+/**\r
+ * @brief skin color status enum\r
+ */\r
+typedef enum\r
+{\r
+    SKIN_COLOR_STATUS_DARK = 0,     /**< dark skin status */\r
+    SKIN_COLOR_STATUS_BROWN,        /**< brown skin status */\r
+    SKIN_COLOR_STATUS_YELLOW,       /**< yellow skin status */\r
+    SKIN_COLOR_STATUS_FAIR,         /**< fair skin status */\r
+} EMSkinColorStatusType;\r
+\r
+/**\r
+ * @brief register struct\r
+ */\r
+typedef struct\r
+{\r
+    GU16 usRegAddr;     /**< register address */\r
+    GU16 usRegData;     /**< register val */\r
+} STGh3x2xReg;\r
+\r
+/**\r
+ * @brief init config struct type\r
+ */\r
+typedef struct\r
+{\r
+    const STGh3x2xReg *pstRegConfigArr;   /**< pointer of register config array */\r
+    GU16        usConfigArrLen;     /**< register config array length */\r
+} STGh3x2xInitConfig;\r
+\r
+/**\r
+ * @brief slot rawwdata struct type\r
+ */\r
+typedef struct\r
+{\r
+    GU32 (*punRawdata)[4];   /**< pointer of buffer store 4 adc rawdata, if slot no use, can set NULL */\r
+    GU16 usRawdataCnt;       /**< slot rawdata count */\r
+} STGh3x2xSlotRawdata;\r
+\r
+/**\r
+ * @brief get rawwdata struct type\r
+ */\r
+typedef struct\r
+{\r
+    GU8 *puchReadBuffer;                        /**< pointer of buffer for read rawdata */\r
+    STGh3x2xSlotRawdata stSlotRawdataArr[8];    /**< 8 slot rawdata array */\r
+} STGh3x2xRawdata;\r
+\r
+/**\r
+ * @brief gsensor rawwdata struct type\r
+ */\r
+\r
+\r
+/**\r
+ * @brief channnel rawwdata struct type\r
+ */\r
+typedef struct\r
+{\r
+    GU32 *punChRawdataArr;              /**< pointer to buffer store channel data, data map e.g. ch0 ch1...chx ch0 */\r
+    GU16 usChRawdataCnt;                /**< channel rawdata count output */\r
+    GU32 *punIncompleteChRawdataArr;    /**< pointer to last incomplete packet buffer */\r
+    GU32  unIncompleteChMark;           /**< last channel rawdata incomplete mark, if chx incomplete bit[x] set 1 */\r
+} STGh3x2xChannelRawdata;\r
+\r
+/**\r
+ * @brief soft lead result\r
+ */\r
+typedef struct\r
+{\r
+    GU16 usEvent;                       /**< event */  \r
+    GU8 uchNeedForceReadFifo;           /**< need force read fifo after call GH3X2X_LeadHandle(...) */\r
+} STSoftLeadResult;\r
+\r
+/**\r
+ * @brief HB algorithm output result\r
+ */\r
+typedef struct\r
+{\r
+    GS32 snHbOut;                       /**< hb algorithm output value */\r
+    GS32 snHbConfi;                     /**< hb algorithm output confidence */\r
+    GS32 snHbSnr;                       /**< hb snr */\r
+    GS32 snHbValidLv;                   /**< hb confidence valid level */\r
+} STHbAlgoResult;\r
+\r
+/**\r
+ * @brief HRV algorithm output result\r
+ */\r
+typedef struct\r
+{\r
+    GS32 snHrvOut0;                     /**< hrv algorithm output 0 */\r
+    GS32 snHrvOut1;                     /**< hrv algorithm output 1 */\r
+    GS32 snHrvOut2;                     /**< hrv algorithm output 2 */\r
+    GS32 snHrvOut3;                     /**< hrv algorithm output 3 */\r
+    GS32 snHrvNum;                      /**< hrv effective result num of snHrvOut */\r
+    GS32 snHrvConfi;                    /**< hrv algorithm output confidence */\r
+} STHrvAlgoResult;\r
+\r
+/**\r
+ * @brief SPO2 algorithm output result\r
+ */\r
+typedef struct\r
+{\r
+    GS32 snSpo2Out;                     /**< spo2 algorithm output value */\r
+    GS32 snSpo2Rvalue;                  /**< R value */\r
+    GS32 snSpo2Confi;                   /**< confidence */\r
+    GS32 snSpo2ValidLevel;              /**< valid level */\r
+} STSpo2AlgoResult;\r
+\r
+/**\r
+ * @brief ECG algorithm output result\r
+ */\r
+typedef struct\r
+{\r
+    GS32 snEcgOut;                      /**< ecg algorithm output value */\r
+    GS32 snEcgBpm;                      /**< bpm */\r
+    GS32 snEcgSnr;                      /**< snr */\r
+} STEcgAlgoResult;\r
+\r
+/**\r
+ * @brief algorithm result stuct\r
+ */\r
+typedef struct\r
+{\r
+    GS32* pnAlgoCalcResult;     //pointer to algorithm result array\r
+    GU16* pusAlgoResIndex;      //pointer to frame index array corresponding to algorithm result\r
+    GU16  usAlgoResCnt;         //number of algorithm result\r
+    GU8   uchAlgoResSize;       //item number of every algorithm result\r
+} STAlgoCalculateRes;\r
+\r
+typedef struct\r
+{\r
+    GU32 unCapData[4];\r
+\r
+}STCapRawdata;\r
+\r
+typedef struct\r
+{\r
+    GU32 unTempData[4];\r
+}STTempRawdata;\r
+\r
+/* byte false or true */\r
+#define BYTE_FALSE                                  (0)             /**< byte false */\r
+#define BYTE_TRUE                                   (1)             /**< byte true */\r
+\r
+/* return code definitions list */\r
+#define   GH3X2X_RET_READ_FIFO_CONTINUE             (4)             /**< Fifo not read empty,should read it again */\r
+#define   GH3X2X_RET_RAW_DATA_PKG_OVER              (3)             /**< already read all of rawdata package data */\r
+#define   GH3X2X_RET_RAW_DATA_PKG_CONTINUE          (2)             /**< there is rawdata package data left */\r
+#define   GH3X2X_RET_ALGO_HAS_REFRESHED             (1)             /**< algorithm has refreshed */\r
+#define   GH3X2X_RET_OK                             (0)             /**< there is no error */\r
+#define   GH3X2X_RET_GENERIC_ERROR                  (-1)            /**< a generic error happens */\r
+#define   GH3X2X_RET_PARAMETER_ERROR                (-2)            /**< parameter error */\r
+#define   GH3X2X_RET_COMM_NOT_REGISTERED_ERROR      (-3)            /**< i2c/spi operation not registered error */\r
+#define   GH3X2X_RET_COMM_ERROR                     (-4)            /**< i2c/spi communication error */\r
+#define   GH3X2X_RET_RESOURCE_ERROR                 (-5)            /**< resource full or not available error */\r
+#define   GH3X2X_RET_NO_INITED_ERROR                (-6)            /**< no inited error */\r
+#define   GH3X2X_RET_ALGO_NO_SUPPORTED              (-7)            /**< the algorithm no supported error */\r
+\r
+/* irq status mask. */\r
+#define   GH3X2X_IRQ_MSK_CHIP_WAKEUP_BIT            (0x0001)        /**< chip wakeup */\r
+#define   GH3X2X_IRQ_MSK_LEAD_ON_DET_BIT            (0x0002)        /**< lead on */\r
+#define   GH3X2X_IRQ_MSK_LEAD_OFF_DET_BIT           (0x0004)        /**< lead off */\r
+#define   GH3X2X_IRQ_MSK_FAST_RECOVERY_BIT          (0x0008)        /**< fast recovery */\r
+#define   GH3X2X_IRQ_MSK_ADC_DONE_BIT               (0x0010)        /**< adc sampling done */\r
+#define   GH3X2X_IRQ_MSK_FIFO_WATERMARK_BIT         (0x0020)        /**< fifo watermark */\r
+#define   GH3X2X_IRQ_MSK_FIFO_FULL_BIT              (0x0040)        /**< fifo full */\r
+#define   GH3X2X_IRQ_MSK_TUNNING_FAIL_BIT           (0x0100)        /**< tunning fail */\r
+#define   GH3X2X_IRQ_MSK_TUNNING_DONE_BIT           (0x0200)        /**< tuning done */\r
+#define   GH3X2X_IRQ_MSK_WEAR_ON_BIT                (0x0400)        /**< wear on */\r
+#define   GH3X2X_IRQ_MSK_WEAR_OFF_BIT               (0x0800)        /**< wear off */\r
+#define   GH3X2X_IRQ_MSK_SLOT_TIMEOUT_BIT           (0x1000)        /**< slot timeout */\r
+#define   GH3X2X_IRQ_MSK_SAMPLE_RATE_ERR_BIT        (0x2000)        /**< sample rate error */\r
+#define   GH3X2X_IRQ_MSK_CHIP_RESET_BIT             (0x4000)        /**< chip reset */\r
+\r
+/* evnet ex*/\r
+#define GH3X2X_EVENT_EX_BIT_WEAR_LIVING_TYPE  ((GU8)1<<0)     //0: object/no objiect   1: living/nonliving object\r
+#define GH3X2X_EVENT_EX_BIT_CHIP0_LEAD_ON     ((GU8)1<<1)     //0: None                1: chip0 lead on\r
+#define GH3X2X_EVENT_EX_BIT_CHIP0_LEAD_OFF    ((GU8)1<<2)     //0: None                1: chip0 lead off\r
+#define GH3X2X_EVENT_EX_BIT_CHIP1_LEAD_ON     ((GU8)1<<3)     //0: None                1: chip1 lead on\r
+#define GH3X2X_EVENT_EX_BIT_CHIP1_LEAD_OFF    ((GU8)1<<4)     //0: None                1: chip1 lead off\r
+#define GH3X2X_EVENT_EX_BIT_MULTI_SENSOR      ((GU8)1<<5)     //0: None                1: multi-sensor\r
+#define GH3X2X_EVENT_EX_BIT_RS1               ((GU8)1<<6)\r
+#define GH3X2X_EVENT_EX_BIT_RS2               ((GU8)1<<7)\r
+\r
+\r
+/*some reg addr*/\r
+#define   GH3X2X_INT_FIFO_UR_REG_ADDR               (0x050A)        /**< fifo use cnt */\r
+\r
+/**\r
+ * @brief channel map for function id\r
+ */\r
+#define GH3X2X_FUNC_OFFSET_ADT              (0)    /**<0 ADT FUNC_OFFSET */\r
+#define GH3X2X_FUNC_OFFSET_HR               (1)    /**<1 HR FUNC_OFFSET */\r
+#define GH3X2X_FUNC_OFFSET_HRV              (2)    /**<2 HRV FUNC_OFFSET */\r
+#define GH3X2X_FUNC_OFFSET_HSM              (3)    /**<3 HSM FUNC_OFFSET */\r
+#define GH3X2X_FUNC_OFFSET_FPBP             (4)    /**<4 BPD FUNC_OFFSET */\r
+#define GH3X2X_FUNC_OFFSET_PWA              (5)    /**<5 PFA FUNC_OFFSET */\r
+#define GH3X2X_FUNC_OFFSET_SPO2             (6)    /**<6 SPO2 FUNC_OFFSET */\r
+#define GH3X2X_FUNC_OFFSET_ECG              (7)    /**<7 ECG FUNC_OFFSET */\r
+#define GH3X2X_FUNC_OFFSET_PWTT             (8)    /**<8 PWTT FUNC_OFFSET */\r
+#define GH3X2X_FUNC_OFFSET_SOFT_ADT_GREEN   (9)    /**<9 SOFT ADT GREEN FUNC_OFFSET */\r
+#define GH3X2X_FUNC_OFFSET_BT               (10)   /**<10 BT FUNC_OFFSET */\r
+#define GH3X2X_FUNC_OFFSET_RESP             (11)   /**<11 RESP FUNC_OFFSET */\r
+#define GH3X2X_FUNC_OFFSET_AF               (12)   /**<12 AF ADT FUNC_OFFSET */\r
+#define GH3X2X_FUNC_OFFSET_TEST1            (13)   /**<13 TEST1 FUNC_OFFSET */\r
+#define GH3X2X_FUNC_OFFSET_TEST2            (14)   /**<14 TEST2 ADT FUNC_OFFSET */\r
+#define GH3X2X_FUNC_OFFSET_SOFT_ADT_IR      (15)   /**<15 SOFT ADT IR FUNC_OFFSET */\r
+#define GH3X2X_FUNC_OFFSET_RS0              (16)   /**<16 */\r
+#define GH3X2X_FUNC_OFFSET_RS1              (17)   /**<17 */\r
+#define GH3X2X_FUNC_OFFSET_RS2              (18)   /**<18 */\r
+#define GH3X2X_FUNC_OFFSET_LEAD_DET         (19)   /**<19 */\r
+#define GH3X2X_FUNC_OFFSET_MAX              (20)  \r
+\r
+/* Function mode. */\r
+#define   GH3X2X_NO_FUNCTION                        (0)                                             /**<0x00000000 NO function */\r
+#define   GH3X2X_FUNCTION_ADT                       ((0x1) << (GH3X2X_FUNC_OFFSET_ADT))             /**<0x00000001 ADT function */\r
+#define   GH3X2X_FUNCTION_HR                        ((0x1) << (GH3X2X_FUNC_OFFSET_HR))              /**<0x00000002 HR function */\r
+#define   GH3X2X_FUNCTION_HRV                       ((0x1) << (GH3X2X_FUNC_OFFSET_HRV))             /**<0x00000004 HRV function */\r
+#define   GH3X2X_FUNCTION_HSM                       ((0x1) << (GH3X2X_FUNC_OFFSET_HSM))             /**<0x00000008 HSM function */\r
+#define   GH3X2X_FUNCTION_FPBP                      ((0x1) << (GH3X2X_FUNC_OFFSET_FPBP))            /**<0x00000010 FPBP function */\r
+#define   GH3X2X_FUNCTION_PWA                       ((0x1) << (GH3X2X_FUNC_OFFSET_PWA))             /**<0x00000020 PWA function */\r
+#define   GH3X2X_FUNCTION_SPO2                      ((0x1) << (GH3X2X_FUNC_OFFSET_SPO2))            /**<0x00000040 SPO2 function */\r
+#define   GH3X2X_FUNCTION_ECG                       ((0x1) << (GH3X2X_FUNC_OFFSET_ECG))             /**<0x00000080 ECG function */\r
+#define   GH3X2X_FUNCTION_PWTT                      ((0x1) << (GH3X2X_FUNC_OFFSET_PWTT))            /**<0x00000100 PWTT function */\r
+#define   GH3X2X_FUNCTION_SOFT_ADT_GREEN            ((0x1) << (GH3X2X_FUNC_OFFSET_SOFT_ADT_GREEN))  /**<0x00000200 SOFT ADT GREEN function */\r
+#define   GH3X2X_FUNCTION_BT                        ((0x1) << (GH3X2X_FUNC_OFFSET_BT))              /**<0x00000400 BT function */\r
+#define   GH3X2X_FUNCTION_RESP                      ((0x1) << (GH3X2X_FUNC_OFFSET_RESP))            /**<0x00000800 RESP function */\r
+#define   GH3X2X_FUNCTION_AF                        ((0x1) << (GH3X2X_FUNC_OFFSET_AF))              /**<0x00001000 AF function */\r
+#define   GH3X2X_FUNCTION_TEST1                     ((0x1) << (GH3X2X_FUNC_OFFSET_TEST1))           /**<0x00002000 TEST1 function */\r
+#define   GH3X2X_FUNCTION_TEST2                     ((0x1) << (GH3X2X_FUNC_OFFSET_TEST2))           /**<0x00004000 TEST2 function */\r
+#define   GH3X2X_FUNCTION_SOFT_ADT_IR               ((0x1) << (GH3X2X_FUNC_OFFSET_SOFT_ADT_IR))     /**<0x00008000 SOFT ADT IR function */\r
+#define   GH3X2X_FUNCTION_RS0                       ((0x1) << (GH3X2X_FUNC_OFFSET_RS0))\r
+#define   GH3X2X_FUNCTION_RS1                       ((0x1) << (GH3X2X_FUNC_OFFSET_RS1))\r
+#define   GH3X2X_FUNCTION_RS2                       ((0x1) << (GH3X2X_FUNC_OFFSET_RS2))\r
+#define   GH3X2X_FUNCTION_LEAD_DET                  ((0x1) << (GH3X2X_FUNC_OFFSET_LEAD_DET))\r
+\r
+\r
+\r
+\r
+\r
+\r
+/* slot index . */\r
+#define   GH3X2X_SLOT_INDEX_0                       (0x0001)        /**< slot index 0 */\r
+#define   GH3X2X_SLOT_INDEX_1                       (0x0002)        /**< slot index 1 */\r
+#define   GH3X2X_SLOT_INDEX_2                       (0x0004)        /**< slot index 2 */\r
+#define   GH3X2X_SLOT_INDEX_3                       (0x0008)        /**< slot index 3 */\r
+#define   GH3X2X_SLOT_INDEX_4                       (0x0010)        /**< slot index 4 */\r
+#define   GH3X2X_SLOT_INDEX_5                       (0x0020)        /**< slot index 5 */\r
+#define   GH3X2X_SLOT_INDEX_6                       (0x0040)        /**< slot index 6 */\r
+#define   GH3X2X_SLOT_INDEX_7                       (0x0080)        /**< slot index 7 */\r
+#define   GH3X2X_SLOT_INDEX_ALL                     (0x00FF)        /**< all slot */\r
+\r
+/* led driver index . */\r
+#define   GH3X2X_LED_DRV_INDEX_0                    (0x0000)        /**< led driver index 0 */\r
+#define   GH3X2X_LED_DRV_INDEX_1                    (0x0001)        /**< led driver index 1 */\r
+\r
+/* channel map to slot & adc for algorithm */\r
+#define   GH3X2X_CHANNEL_MAP_SLOT0                  (0x00)          /**< channel map to slot 0 */\r
+#define   GH3X2X_CHANNEL_MAP_SLOT1                  (0x20)          /**< channel map to slot 1 */\r
+#define   GH3X2X_CHANNEL_MAP_SLOT2                  (0x40)          /**< channel map to slot 2 */\r
+#define   GH3X2X_CHANNEL_MAP_SLOT3                  (0x60)          /**< channel map to slot 3 */\r
+#define   GH3X2X_CHANNEL_MAP_SLOT4                  (0x80)          /**< channel map to slot 4 */\r
+#define   GH3X2X_CHANNEL_MAP_SLOT5                  (0xA0)          /**< channel map to slot 5 */\r
+#define   GH3X2X_CHANNEL_MAP_SLOT6                  (0xC0)          /**< channel map to slot 6 */\r
+#define   GH3X2X_CHANNEL_MAP_SLOT7                  (0xE0)          /**< channel map to slot 7 */\r
+#define   GH3X2X_CHANNEL_MAP_ADC0                   (0x00)          /**< channel map to adc 0 */\r
+#define   GH3X2X_CHANNEL_MAP_ADC1                   (0x08)          /**< channel map to adc 1 */\r
+#define   GH3X2X_CHANNEL_MAP_ADC2                   (0x10)          /**< channel map to adc 2 */\r
+#define   GH3X2X_CHANNEL_MAP_ADC3                   (0x18)          /**< channel map to adc 3 */\r
+#define   GH3X2X_CHANNEL_MAP(slot, adc)             ((slot) | (adc))    /**< calc channel map */\r
+\r
+#define   GH3X2X_DEMO_WORK_MODE_EVK                 (0)\r
+#define   GH3X2X_DEMO_WORK_MODE_APP                 (1)\r
+#define   GH3X2X_DEMO_WORK_MODE_MCU_ONLINE          (2)\r
+#define   GH3X2X_DEMO_WORK_MODE_MCU_OFFLINE         (3)\r
+#define   GH3X2X_DEMO_WORK_MODE_TEST_TUNE           (4)\r
+#define   GH3X2X_DEMO_WORK_MODE_PASS_THROUGH        (5)\r
+#define   GH3X2X_DEMO_GET_WORK_MODE                 (6)\r
+#define   GH3X2X_DEMO_WORK_MODE_MPT                 (7)\r
+\r
+/* soft event list*/\r
+#define GH3X2X_SOFT_EVENT_NEED_FORCE_READ_FIFO      ((GU8)1)\r
+#define GH3X2X_SOFT_EVENT_WEAR_OFF                  ((GU8)2)    //event generated by nadt algo\r
+#define GH3X2X_SOFT_EVENT_NEED_TRY_READ_FIFO        ((GU8)4)\r
+#define GH3X2X_SOFT_EVENT_WEAR_ON                   ((GU8)8)    //event generated by nadt algo\r
+#define GH3X2X_SOFT_EVENT_WEAR_ON_ALGO_ADT          ((GU8)16)   //event generated by adt algo\r
+#define GH3X2X_SOFT_EVENT_WEAR_OFF_ALGO_ADT         ((GU8)32)   //event generated by adt algo\r
+/* adt confirm status */\r
+#define GH3X2X_SENSOR_IS_NOT_MOVING                 ((GU8)0)\r
+#define GH3X2X_SENSOR_IS_MOVING                     ((GU8)1)\r
+/* soft nadt algo adt status */\r
+#define GH3X2X_SOFT_ALGO_ADT_DEFAULT                 ((GU8)0)\r
+#define GH3X2X_SOFT_ALGO_ADT_WEAR_ON                 ((GU8)1)    \r
+#define GH3X2X_SOFT_ALGO_ADT_WEAR_OFF                ((GU8)2)\r
+\r
+#define GH3X2X_ALGO_INFO_RECORD_GSENSOR_NUM               (3)\r
+#define GH3X2X_ALGO_INFO_RECORD_RAWDARA_NUM               (4)\r
+#define GH3X2X_ALGO_INFO_RECORD_AGC_INFO_NUM              (4)\r
+#define GH3X2X_ALGO_INFO_RECORD_FALG_NUM                  (3)\r
+#define GH3X2X_ALGO_INFO_RECORD_RESULT_NUM                (8)\r
+\r
+#define GH3X2X_ALGO_RESULT_MAX_NUM                        (16)\r
+\r
+/// universal protocol packet max len support\r
+#define  GH3X2X_UPROTOCOL_PACKET_LEN_MAX                  (243)\r
+\r
+#define  GH3X2X_UPROTOCOL_PACKET_HEADER_LEN               (4u)        /**< packet header len */\r
+#define  GH3X2X_UPROTOCOL_PACKET_TAIL_LEN                 (1u)        /**< packet tail len */\r
+\r
+\r
+/// packet header&tail len\r
+#define  GH3X2X_UPROTOCOL_PACKET_HEADER_TAIL_LEN          (GH3X2X_UPROTOCOL_PACKET_HEADER_LEN + \\r
+                                                            GH3X2X_UPROTOCOL_PACKET_TAIL_LEN)\r
+\r
+\r
+/// universal protocol payload max len\r
+#define  GH3X2X_UPROTOCOL_PAYLOAD_LEN_MAX                 (GH3X2X_UPROTOCOL_PACKET_LEN_MAX - \\r
+                                                            GH3X2X_UPROTOCOL_PACKET_HEADER_TAIL_LEN)\r
+\r
+/// Overflow protocol payload max len\r
+#define  GH3X2X_UPROTOCOL_OVERFLOW_PAYLOAD_HEADER_LEN           (10)\r
+#define  GH3X2X_UPROTOCOL_OVERFLOW_PAYLOAD_LEN_MAX              (220)\r
+\r
+/// number of channel map id\r
+#define  CHANNEL_MAP_ID_NUM                               (32)\r
+\r
+/// number of channel map id\r
+#define  CHANNEL_SLOT_NUM                                 (8)\r
+\r
+/// null val\r
+#define   GH3X2X_PTR_NULL                                 ((void *) 0)\r
+\r
+/* ecg sample event type */\r
+#define  ECG_SAMPLE_EVENT_TYPE_SAMPLE                     (0x01)     /**< sample evt type sample config */\r
+#define  ECG_SAMPLE_EVENT_TYPE_SLOT                       (0x02)     /**< sample evt type slot config */\r
+#define  ECG_SAMPLE_EVENT_TYPE_LEAD                       (0x04)     /**< sample evt type lead irq */\r
+#define  ECG_SAMPLE_EVENT_ALL                             (ECG_SAMPLE_EVENT_TYPE_SAMPLE | ECG_SAMPLE_EVENT_TYPE_SLOT | \\r
+                                                            ECG_SAMPLE_EVENT_TYPE_LEAD)     /**< sample evt all */\r
+\r
+/* ecg sample event type */\r
+#define  ECG_SAMPLE_EVENT_INFO_SAMPLE_STOP                (0)      /**< sample evt info sample stop */\r
+#define  ECG_SAMPLE_EVENT_INFO_SAMPLE_START               (1)      /**< sample evt info sample start */\r
+#define  ECG_SAMPLE_EVENT_INFO_LEAD_OFF                   (0)      /**< sample evt info lead off */\r
+#define  ECG_SAMPLE_EVENT_INFO_LEAD_ON                    (1)      /**< sample evt info lead on */\r
+\r
+\r
+\r
+\r
+typedef struct\r
+{\r
+   GU32  unFunctionID;  //Function id     use maroc exp: GH3X2X_FUNCTION_HR\r
+   GU8  ubChnlNum;\r
+   GU8  ubFrameId;\r
+   GS16 usGsensor[GH3X2X_ALGO_INFO_RECORD_GSENSOR_NUM];\r
+   GU32 unRawdata[GH3X2X_ALGO_INFO_RECORD_RAWDARA_NUM];\r
+   GU32 unAgcInfo[GH3X2X_ALGO_INFO_RECORD_AGC_INFO_NUM];\r
+   GU32 unFlag[GH3X2X_ALGO_INFO_RECORD_FALG_NUM];\r
+   GU32 unResult[GH3X2X_ALGO_INFO_RECORD_RESULT_NUM];\r
+} STGh3x2xAlgoInfoRecordData;\r
+\r
+\r
+\r
+\r
+typedef struct\r
+{\r
+    // void (*DumpInit) (void);\r
+    //void (*BgLevelSet)(GU16);\r
+    //void (*DumpModeSet)(GU16);\r
+    //void (*MemSetSpo2IncompleteArr)(void);\r
+    //void (*MemSetHbaIncompleteArr)(void);\r
+    void (*AlgoInfoRecordInputData)(GS32* ,GU8 ,GU32 ,GU8* ,GU32 );\r
+    void (*AlgoInfoRecordOutputData)(GS32 *, GU8 );\r
+} STGh3x2xModuleFunList;\r
+\r
+\r
+\r
+\r
+\r
+typedef struct\r
+{\r
+   GU8 puchPacketPayloadArr[GH3X2X_UPROTOCOL_PAYLOAD_LEN_MAX + 8];\r
+   GU8 uchFrameIdArr[CHANNEL_MAP_ID_NUM];\r
+} STGh3x2xProtocolData;\r
+\r
+\r
+\r
+\r
+#define GH3X2X_AGC_REG_AGC_EN                     0\r
+#define GH3X2X_AGC_REG_LED_CURRENT_UP_LIMIT       1\r
+#define GH3X2X_AGC_REG_LED_CURRENT_DOWN_LIMIT     2\r
+#define GH3X2X_AGC_REG_LED_CURRENT_DRV0           3\r
+#define GH3X2X_AGC_REG_LED_CURRENT_DRV1           4\r
+#define GH3X2X_AGC_REG_TIA_GAIN_RX0               5\r
+#define GH3X2X_AGC_REG_TIA_GAIN_RX1               6\r
+#define GH3X2X_AGC_REG_TIA_GAIN_RX2               7\r
+#define GH3X2X_AGC_REG_TIA_GAIN_RX3               8\r
+#define GH3X2X_AGC_REG_AGC_SRC                    9\r
+#define GH3X2X_AGC_REG_BG_CANCEL_RX0              10\r
+#define GH3X2X_AGC_REG_BG_CANCEL_RX1              11\r
+#define GH3X2X_AGC_REG_BG_CANCEL_RX2              12\r
+#define GH3X2X_AGC_REG_BG_CANCEL_RX3              13\r
+#define GH3X2X_AGC_REG_SR_MULIPLIPER              14\r
+#define GH3X2X_AGC_ECG_PPG_RX_EN                  15\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+#define GH3X2X_ENGINEERING_MODE_CHNL_NUM_MAX      32\r
+\r
+#define GH3X2X_ENGINEERING_MODE_INT_TIME_10_US    0\r
+#define GH3X2X_ENGINEERING_MODE_INT_TIME_20_US    1\r
+#define GH3X2X_ENGINEERING_MODE_INT_TIME_30_US    2\r
+#define GH3X2X_ENGINEERING_MODE_INT_TIME_39_US    3\r
+#define GH3X2X_ENGINEERING_MODE_INT_TIME_79_US    4\r
+#define GH3X2X_ENGINEERING_MODE_INT_TIME_158_US   5\r
+#define GH3X2X_ENGINEERING_MODE_INT_TIME_316_US   6\r
+\r
+\r
+#define GH3X2X_ENGINEERING_MODE_TIA_GAIN_10_K     0\r
+#define GH3X2X_ENGINEERING_MODE_TIA_GAIN_25_K     1\r
+#define GH3X2X_ENGINEERING_MODE_TIA_GAIN_50_K     2\r
+#define GH3X2X_ENGINEERING_MODE_TIA_GAIN_75_K     3\r
+#define GH3X2X_ENGINEERING_MODE_TIA_GAIN_100_K    4\r
+#define GH3X2X_ENGINEERING_MODE_TIA_GAIN_250_K    5\r
+#define GH3X2X_ENGINEERING_MODE_TIA_GAIN_500_K    6\r
+#define GH3X2X_ENGINEERING_MODE_TIA_GAIN_750_K    7\r
+#define GH3X2X_ENGINEERING_MODE_TIA_GAIN_1000_K   8\r
+#define GH3X2X_ENGINEERING_MODE_TIA_GAIN_1250_K   9\r
+#define GH3X2X_ENGINEERING_MODE_TIA_GAIN_1500_K   10\r
+#define GH3X2X_ENGINEERING_MODE_TIA_GAIN_1750_K   11\r
+#define GH3X2X_ENGINEERING_MODE_TIA_GAIN_2000_K   12\r
+\r
+#define GH3X2X_FRAME_FLAG_NUM                     8\r
+#define GH3X2X_AGC_MAIN_SLOT_NUM                  8\r
+\r
+typedef struct\r
+{\r
+    /// save gain\r
+               GU8  uchTiaGainRecord[CHANNEL_MAP_ID_NUM];\r
+               GU8  uchTiaGainAfterSoftAgc[CHANNEL_MAP_ID_NUM];\r
+               /// save current of drv0 and drv1\r
+               GU16  uchDrvCurrentAfterSoftAgc[CHANNEL_SLOT_NUM];\r
+               GU16 uchDrvCurrentRecord[CHANNEL_SLOT_NUM];\r
+} STGh3x2xAgcInfo;\r
+\r
+typedef struct\r
+{\r
+   GU32 unFunctionID;            //Function id     use maroc exp: GH3X2X_FUNCTION_HR\r
+   GU8  uchSampleRateChangeEn;   // 0: do not need change sample rate   1: need change sample rate\r
+   GU16 usSampleRate;            // sample rate (unit Hz  range 5Hz~1000Hz)\r
+   GU8  uchIntTimeChangeEn;      // 0: do not need change integrator time  1: need change intergrator time\r
+   GU8  uchIntTime;              // use maroc exp: GH3X2X_ENGINEERING_MODE_INT_TIME_10_US\r
+   GU8  uchTiaGainChangeEn;      // 0: do not need change TIA gain    1: need change TIA gain \r
+   GU8  uchTiaGain[GH3X2X_ENGINEERING_MODE_CHNL_NUM_MAX];  //TIA gain for every channel, use maroc GH3X2X_ENGINEERING_MODE_TIA_GAIN_10_K\r
+   GU8  uchLedCurrentChangeEn;      // 0: do not need change LED current    1: need change change LED current \r
+   GU8  uchLedDrv0Current[GH3X2X_ENGINEERING_MODE_CHNL_NUM_MAX];  //LED driver0 current for every channel (unit: mA   range: 0~200) \r
+   GU8  uchLedDrv1Current[GH3X2X_ENGINEERING_MODE_CHNL_NUM_MAX];  //LED driver1 current for every channel (unit: mA   range: 0~200)\r
+} STGh3x2xEngineeringModeSampleParam;\r
+\r
+\r
+typedef struct\r
+{\r
+    GU8 uchEnable;\r
+    GU8 uchSpo2ChnlIndex;      //0: is not spo2 channel   N(N > 0):  is spo2 channl  \r
+    GU8 uchSlotAdc;\r
+    GU8  uchCurrentTiaGain;\r
+    GU8  uchCurrentDrv;\r
+    GU8  uchTiaGainUpLimit;\r
+    GU8  uchHaveBakRegFlag;\r
+    GU8  uchBakRegAgcEn;\r
+    GU8  uchBakRegAgcSrc;\r
+    GU8  uchBakRegLedCurrentMin;\r
+    GU8  uchBakRegLedCurrentMax;\r
+    GU8  uchBakTiaGain;\r
+} STGh3x2xNewAgcMainChnlInfo;\r
+\r
+\r
+\r
+typedef struct \r
+{\r
+    GU16 Sat_CheckCnt[GH3X2X_AGC_MAIN_SLOT_NUM];  /* num of data checked*/\r
+    GU16 Sat_cnt[GH3X2X_AGC_MAIN_SLOT_NUM]; /* sat num of each channel*/\r
+    GU8 Sat_flag; /* sat flag one bit each channel*/\r
+} STGh3x2xNewAgcMainChnlSat;\r
+\r
+typedef struct\r
+{\r
+    GU32 unMaxRawdata;\r
+    GU32 unMinRawdata;\r
+    GU32 unSumAdjust;     //  cacluate drv current and gain\r
+    GU32 unSumTrige;      //  judge whether AGC\r
+    GU32 unRawdataMean;\r
+    GU32 unLastRawdataMean;\r
+    GU16 usSampleRate;\r
+    GU16 usAnalysisCnt;   // numble of nalysis data\r
+    GU8 uchHaveAgcAtLastReadPrd;    //0: no agc action at last fifo read period  1: have agc action at last fifo read preiod\r
+    GU8 uchDropFlag;\r
+} STGh3x2xNewAgcMainChnlMeanInfo;\r
+\r
+typedef struct\r
+{\r
+    GU8  uchIniteFirst;   // inite first time   0:yes   1:not\r
+    GU8  uchSeconsCnt;    // \r
+} STGh3x2xNewAgcMainChnlIdaelAdjInfo;\r
+\r
+typedef struct\r
+{\r
+    GU32 unLastRawdata;\r
+    GU32 unLastLastRawdata;\r
+    GU32 unRawdataSum;\r
+    GU16 usAnalysisCnt;\r
+    GU16 usMoreThanUpLimitPointCnt;\r
+    GU16 usMoreThanUpLimitPointCntForBiggerGain;\r
+    GU16 usTrigeUpLimitForBiggerGain;   //  rawdate/256\r
+    GU8 uchEn;\r
+    GU8 uchSlotAdcNo;\r
+    GU8 uchCurrentGain;\r
+}STGh3x2xNewAgcSubChnlRxInfo;\r
+\r
+\r
+typedef struct\r
+{\r
+    GS32 snCounter;\r
+    GS32 sniqCounter;\r
+    long long snniVal;\r
+    long long snnqVal;\r
+    GU8 uchFlagFrPrev;\r
+    GU8 uchFastRecoryHistory;\r
+    long long snniqAmp[5];\r
+} STGh3x2xSoftLeadOffDetInfo;\r
+\r
+\r
+typedef struct\r
+{\r
+    GS32 snRsXbuf[100/1 + 1];\r
+    GS32 snBufHead;\r
+    GS32 snRsFirState;\r
+    GU32 nRsIcounter;\r
+    GU32 nRrsDcounter;\r
+    GU8 uchFlagFrPrev;\r
+    GU32 nRsLastRaw;\r
+    GU32 fDownStep;\r
+    GU8  uchLinearInterState;\r
+    GU8  uchLinearDataUpdate;\r
+} STGh3x2xRsInfo;\r
+\r
+\r
+typedef struct\r
+{\r
+    GU16 usSampleRate;                  //current sample rate\r
+    GU16 usSampleRateForUserSetting;    //0:  use default sample rate via cfg array    others: use usSampleRateForUserSetting\r
+    GU32 unChnlEnForUserSetting;        //BitN = 1: channel N is enable     BitN = 0: channel N is disable\r
+    GU8  uchChnlNum;\r
+    GU8 uchSlotBit;\r
+} STGh3x2xFunctionInfo;\r
+\r
+typedef struct\r
+{\r
+    GU8 uchUpdateFlag;\r
+    GU8 uchResultNum;\r
+    GU16 usResultBit;\r
+    GS32 snResult[GH3X2X_ALGO_RESULT_MAX_NUM];\r
+} STGh3x2xAlgoResult;\r
+\r
+\r
+\r
+typedef struct\r
+{\r
+    GU8 uchDownSampleFactor;   //0: down sample disable    N(N != 0):  down sample radio = (N + 1) : 1\r
+    GU8 uchDownSampleCnt;      // data will output when uchDownSampleFactor = uchDownSampleCnt\r
+} STGh3x2xDownSampleInfo;\r
+\r
+\r
+\r
+typedef struct\r
+{\r
+    GU32 unFunctionID ;\r
+    STGh3x2xFunctionInfo *pstFunctionInfo;\r
+    STGh3x2xDownSampleInfo *pstDownSampleInfo;\r
+    GU8  uchFuntionChnlLimit;   //max chnl num\r
+    GU8  *pchChnlMap;\r
+    GU32 *punFrameRawdata;\r
+    GS16 *pusFrameGsensordata;\r
+    STCapRawdata *pstFrameCapdata;\r
+    STTempRawdata *pstFrameTempdata;\r
+    GU32 *punFrameAgcInfo;\r
+    GU32 *punFrameFlag;\r
+    GU32 *punIncompleteRawdata;\r
+    GU32 *punIncompleteChnlMapBit;\r
+    GU8 * puchFrameLastGain;\r
+    GU32 * punFrameCnt;\r
+    STGh3x2xAlgoResult * pstAlgoResult;\r
+    STGh3x2xAlgoResult * pstAlgoRecordResult;\r
+} STGh3x2xFrameInfo;\r
+\r
+\r
+extern GU8 NewAgcMainChelFlag ;\r
+\r
+\r
+void ResisterpGh3x2xModuleFunList(STGh3x2xModuleFunList *pGh3x2xModuleFunList);\r
+\r
+#if 0\r
+void GH3X2X_DumpInit(void);\r
+void GH3X2X_DumpInitNullFun(void);\r
+void GH3X2X_BgLevelSet(GU16 usRegVal);\r
+void GH3X2X_BgLevelSetNullFun(GU16 usRegVal);\r
+void GH3X2X_DumpModeSet(GU16 usRegVal);\r
+void GH3X2X_DumpModeSetNullFun(GU16 usRegVal);\r
+void GH3X2X_MemSetSpo2IncompleteArr(void);\r
+void GH3X2X_MemSetSpo2IncompleteArrNullFun(void);\r
+void GH3X2X_MemSetHbaIncompleteArr(void);\r
+void GH3X2X_MemSetHbaIncompleteArrNullFun(void);\r
+#endif\r
+\r
+\r
+\r
+\r
+\r
+//extern GU8 * const g_uchPacketPayloadArr;//[GH3X2X_UPROTOCOL_PAYLOAD_LEN_MAX];\r
+\r
+extern STGh3x2xProtocolData * const g_pstGh3x2xProtocolData;//[GH3X2X_UPROTOCOL_PAYLOAD_LEN_MAX];\r
+\r
+\r
+extern void GH3X2X_ProtocolFrameIdClean(GU8 uchFunctionID);\r
+\r
+\r
+\r
+\r
+/**\r
+ * @fn     void GH3X2X_RegisterHookFunc(void (*pInitHookFunc)(void),\r
+ *                          void (*pStartHookFunc)(void),\r
+ *                             void (*pStopHookFunc)(void),\r
+ *                           void (*pGetRawdataHookFunc)(GU8 *puchReadDataBuffer, GU16 usReadDataLen))\r
+ *\r
+ * @brief  Register hook function callback.\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   pInitHookFunc           pointer to init hook function\r
+ * @param[in]   pStartHookFunc          pointer to start hook function\r
+ * @param[in]   pStopHookFunc           pointer to stop hook function\r
+ * @param[in]   pGetRawdataHookFunc     pointer to get rawdata hook function\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_RegisterHookFunc(void (*pInitHookFunc)(void),\r
+                             void (*pStartHookFunc)(void),\r
+                             void (*pStopHookFunc)(void),\r
+                             void (*pGetRawdataHookFunc)(GU8 *puchReadDataBuffer, GU16 usReadDataLen),\r
+                             void (*pGetIoStructInfoHookFunc)(const STGh3x2xFrameInfo * const pstFrameInfo),\r
+                             void (*pResetByProtocolHookFunc)(void),\r
+                             void (*pConfigSetStartHookFunc)(void),\r
+                             void (*pConfigSetStopHookFunc)(void),\r
+                             void (*pfnWriteAlgConfigWithVirtualReg)(GU16 usVirtualRegAddr, GU16 usVirtualRegValue));\r
+\r
+/**\r
+ * @fn     void GH3X2X_RegisterDelayUsCallback(void (*pPlatformDelayUsFunc)(GU16 usUsec))\r
+ *\r
+ * @brief  Register delay us callback function, should register delay us function in platforms\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   pPlatformDelayUsFunc      pointer to delay us function\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_RegisterDelayUsCallback(void (*pPlatformDelayUsFunc)(GU16 usUsec));\r
+\r
+/**\r
+ * @fn     void GH3X2X_WriteReg(GU16 usRegAddr, GU16 usRegValue)\r
+ *\r
+ * @brief  Write register via i2c or spi\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   usRegAddr       register addr\r
+ * @param[in]   usRegValue      register data\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_WriteReg(GU16 usRegAddr, GU16 usRegValue);\r
+\r
+/**\r
+ * @fn     GU16 GH3X2X_ReadReg(GU16 usRegAddr)\r
+ *\r
+ * @brief  Read register via i2c or spi\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   usRegAddr      register addr\r
+ * @param[out]  None\r
+ *\r
+ * @return  register data\r
+ */\r
+GU16 GH3X2X_ReadReg(GU16 usRegAddr);\r
+\r
+/**\r
+ * @fn     GU32 GH3X2X_ReadRegs(GU16 usRegAddr, GU16 *pusRegValueBuffer, GU16 usLen)\r
+ *\r
+ * @brief  Read multi register via i2c or spi\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   usRegAddr           register addr\r
+ * @param[in]   pusRegValueBuffer   pointer to register value buffer\r
+ * @param[in]   uchLen              registers len\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+GU32 GH3X2X_ReadRegs(GU16 usRegAddr, GU16 *pusRegValueBuffer, GU16 usLen);\r
+\r
+/**\r
+ * @fn     void GH3X2X_ReadFifo(GU8 *puchDataBuffer, GU16 usLen)\r
+ *\r
+ * @brief  Read fifo via i2c or spi\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   puchDataBuffer      pointer to buffer for fifo rawdata\r
+ * @param[in]   usLen               fifo bytes len\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_ReadFifo(GU8 *puchDataBuffer, GU16 usLen);\r
+\r
+/**\r
+ * @fn     void GH3X2X_WriteRegBitField(GU16 usRegAddr, GU8 uchLsb, GU8 uchMsb, GU16 usValue)\r
+ *\r
+ * @brief  write register bit field via i2c or spi\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   usRegAddr      register addr\r
+ * @param[in]   uchLsb         lsb of bit field\r
+ * @param[in]   uchMsb         msb of bit field\r
+ * @param[in]   usRegValue     register data\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_WriteRegBitField(GU16 usRegAddr, GU8 uchLsb, GU8 uchMsb, GU16 usValue);\r
+\r
+/**\r
+ * @fn     GU16 GH3X2X_ReadRegBitField(GU16 usRegAddr, GU8 uchLsb, GU8 uchMsb)\r
+ *\r
+ * @brief  Read register bit field via i2c or spi\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   usRegAddr      register addr\r
+ * @param[in]   uchLsb         lsb of bit field\r
+ * @param[in]   uchMsb         msb of bit field\r
+ * @param[out]  None\r
+ *\r
+ * @return  register bit field data\r
+ */\r
+GU16 GH3X2X_ReadRegBitField(GU16 usRegAddr, GU8 uchLsb, GU8 uchMsb);\r
+\r
+/**\r
+ * @fn     GS8 GH3X2X_RegisterSpiOperationFunc(GU8 (*pSpiWriteFunc)(GU8 uchWriteBytesArr[], GU16 usWriteLen),\r
+ *                                     GU8 (*pSpiReadFunc)(GU8 uchReadBytesArr[], GU16 usMaxReadLen),\r
+ *                                   void (*pSpiCsCtrlFunc)(GU8 uchCsLevelHigh))\r
+ *\r
+ * @brief  Register spi operation function callback\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   pSpiWriteFunc       pointer to spi write function\r
+ * @param[in]   pSpiReadFunc        pointer to spi read function\r
+ * @param[in]   pSpiCsCtrlFunc      pointer to spi cs operation function\r
+ * @param[out]  None\r
+ *\r
+ * @return  errcode\r
+ * @retval  #GH3X2X_RET_OK               return successfully\r
+ * @retval  #GH3X2X_RET_PARAMETER_ERROR  spi operation function pointer parameter error\r
+ */\r
+GS8 GH3X2X_RegisterSpiOperationFunc(GU8 (*pSpiWriteFunc)(GU8 uchWriteBytesArr[], GU16 usWriteLen),\r
+                                    GU8 (*pSpiReadFunc)(GU8 uchReadBytesArr[], GU16 usMaxReadLen),\r
+                                    void (*pSpiCsCtrlFunc)(GU8 uchCsLevelHigh));\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+/**\r
+ * @fn     GS8 GH3X2X_RegisterSpiHwCsOperationFunc(GU8 (*pSpiWriteFunc)(GU8 uchWriteBytesArr[], GU16 usWriteLen),\r
+ *                                   GU8 (*pSpiWriteF0ReadFunc)(GU8 uchReadBytesArr[], GU16 usMaxReadLen)\r
+ *                                  )\r
+ *\r
+ * @brief  Register spi operation function callback\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   pSpiWriteFunc                pointer to spi write function\r
+ * @param[in]   pSpiWriteF1ReadFunc        pointer to spi write f1 and read function\r
+ * @param[out]  None\r
+ *\r
+ * @return  errcode\r
+ * @retval  #GH3X2X_RET_OK               return successfully\r
+ * @retval  #GH3X2X_RET_PARAMETER_ERROR  spi operation function pointer parameter error\r
+ */\r
+GS8 GH3X2X_RegisterSpiHwCsOperationFunc(GU8 (*pSpiWriteFunc)(GU8 uchWriteBytesArr[], GU16 usWriteLen),\r
+                                    GU8 (*pSpiWriteF1ReadFunc)(GU8 uchReadBytesArr[], GU16 usMaxReadLen)\r
+                                    );\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+/**\r
+ * @fn     GS8 GH3X2X_RegisterI2cOperationFunc(GU8 uchI2cIdLowTwoBitsSelect,\r
+ *                                GU8 (*pI2cWriteFunc)(GU8 uchDeviceId, const GU8 uchWriteBytesArr[], GU16 usWriteLen),\r
+ *                                GU8 (*pI2cReadFunc)(GU8 uchDeviceId, const GU8 uchCmddBytesArr[], GU16 usCmddLen,\r
+ *                                                      GU8 uchReadBytesArr[], GU16 usMaxReadLen))\r
+ *\r
+ * @brief  Register i2c operation function callback\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   uchI2cIdLowTwoBitsSelect    i2c low two bits addr selected, ref EMGh3x2xI2cIdSelect\r
+ * @param[in]   pI2cWriteFunc               pointer to i2c write function\r
+ * @param[in]   pI2cReadFunc                pointer to i2c read function\r
+ * @param[out]  None\r
+ *\r
+ * @return  errcode\r
+ * @retval  #GH3X2X_RET_OK               return successfully\r
+ * @retval  #GH3X2X_RET_PARAMETER_ERROR  i2c operation function pointer parameter error\r
+ */\r
+GS8 GH3X2X_RegisterI2cOperationFunc(GU8 uchI2cIdLowTwoBitsSelect,\r
+                                GU8 (*pI2cWriteFunc)(GU8 uchDeviceId, const GU8 uchWriteBytesArr[], GU16 usWriteLen),\r
+                                GU8 (*pI2cReadFunc)(GU8 uchDeviceId, const GU8 uchCmddBytesArr[], GU16 usCmddLen,\r
+                                                        GU8 uchReadBytesArr[], GU16 usMaxReadLen));\r
+\r
+/************Start,Ecg Cascade API*************************/\r
+#if 1\r
+\r
+\r
+\r
+void GH3X2X_CascadeOperationMasterChip(void);\r
+void GH3X2X_CascadeOperationSlaverChip(void);\r
+void GH3X2X_CascadeSetLogicMasterChip(GU8 uchPhysicsChipIndex);\r
+\r
+\r
+void GH3X2X_SendCmd(GU8 uchCmd);\r
+\r
+/// uchChip2ChannelMap: must set 0x08\r
+GS16 GH3X2X_CascadeReadFifodata(GU8 *puchGh3x2xReadFifoDataCascade, GU8 *puchGh3x2xReadFifoDataSingleBuf, GU16* pusReadFifoDataLen ,GU16 usFifoReadByteNum, GU8 uchChip2ChannelMap);\r
+\r
+///1: set Ecg Cascade enable.   0: set Ecg Cascade disable  \r
+void GH3X2X_CascadeSetEcgEnFlag(GU8 uchCascadeEnFlag);\r
+void GH3X2X_CascadeSetEcgSlaveInitSuccess(GU8 uchCascadeInitSuccess);\r
+                                \r
+///return 1: Ecg Cascade enable.  return 0: Ecg Cascade disable  \r
+GU8 GH3X2X_CascadeGetEcgEnFlag(void);\r
+\r
+///the initialization state of the second chip in the cascade\r
+///return 1: Init Success.  return 0: Init fail or not init \r
+GU8 GH3X2X_CascadeGetEcgSlaveInitSuccess(void);\r
+\r
+GS8 GH3X2X_CascadeCalibrateECGGain(GU8 *puchReadFifoBuffer, GU16 usFifoBufferLen);\r
+\r
+void GH3X2X_CascadeEcgSlaverLeadDectDis(void);\r
+void GH3X2X_CascadeEcgSlaverLeadDectEn(void);\r
+\r
+GU8 GH3X2X_CascadeGetEcgMasterLeadStatus(GU8 *puchEvent);\r
+GU8 GH3X2X_CascadeGetEcgSlaverLeadStatus(GU8 *puchEvent);\r
+\r
+GU16 GH3X2X_CascadeLeadOnEventPreDeal(GU16 usIrqStatus,GU16 usIrqStatusChip2,GU8 *puchEventEx);\r
+void Gh3x2xEnterCascadeMode(void);\r
+void Gh3x2xExitCascadeMode(void);\r
+#endif\r
+/************End:Ecg Cascade API*************************/\r
+\r
+/**\r
+ * @fn     GS8 GH3X2X_ExitLowPowerMode(void)\r
+ *\r
+ * @brief  Exit lowpower mode, in this mode, can read&write reg with gh3x2x\r
+ *\r
+ * @attention   Power consumption bigger than lowpower mode, detaile ref gh3x2x datasheet\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  errcode\r
+ * @retval  #GH3X2X_RET_OK               return successfully\r
+ * @retval  #GH3X2X_RET_GENERIC_ERROR    exit low power mode error\r
+ */\r
+GS8 GH3X2X_ExitLowPowerMode(void);\r
+\r
+/**\r
+ * @fn     GS8 GH3X2X_EnterLowPowerMode(void)\r
+ *\r
+ * @brief  Enter lowpower mode, in this mode, can't read&write reg with gh3x2x\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  errcode\r
+ * @retval  #GH3X2X_RET_OK               return successfully\r
+ * @retval  #GH3X2X_RET_GENERIC_ERROR    enter low power mode error\r
+ */\r
+GS8 GH3X2X_EnterLowPowerMode(void);\r
+\r
+/**\r
+ * @fn     void GH3X2X_RegisterResetPinControlFunc(void (*pResetPinLevelControlFunc)(GU8 uchPinLevel))\r
+ *\r
+ * @brief  Register reset pin level control function \r
+ *\r
+ * @attention   Pin level set val should define as 1 [high level] or 0 [low level];\r
+ *\r
+ * @param[in]   pResetPinLevelControlFunc       pointer to set reset pin level function\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_RegisterResetPinControlFunc(void (*pResetPinLevelControlFunc)(GU8 uchPinLevel));\r
+\r
+/**\r
+ * @fn     GS8 GH3X2X_HardReset(void)\r
+ *\r
+ * @brief  Gh3x2x softreset via i2c/spi, can read&write reg with gh3x2x after reset\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  errcode\r
+ * @retval  #GH3X2X_RET_OK               return successfully\r
+ * @retval  #GH3X2X_RET_GENERIC_ERROR    reset pin control function not register\r
+ */\r
+GS8 GH3X2X_HardReset(void);\r
+\r
+/**\r
+ * @fn     void GH3X2X_SendCmd(GU8 uchCmd)\r
+ *\r
+ * @brief  Send cmd via i2c or spi\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   uchCmd      cmd\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_SendCmd(GU8 uchCmd);\r
+\r
+/**\r
+ * @fn     void GH3X2X_WearDetectEnable(EMWearDetectEnableType emWearDetectEnable)\r
+ *\r
+ * @brief  enable or disable wear detect\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   emWearDetectEnable      enable or disable @ref EMWearDetectEnableType\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_WearDetectEnable(EMWearDetectEnableType emWearDetectEnable);\r
+\r
+/**\r
+ * @fn     void GH3X2X_ResetHardAdt(void)\r
+ *\r
+ * @brief  Gh3x2x reset hard adt  \r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_ResetHardAdt(void);\r
+       \r
+/**\r
+ * @fn     GS8 GH3X2X_WearDetectSwitchTo(EMWearDetectType emWearDetectType, EMWearDetectForceSwitch emForceSwitch)\r
+ *\r
+ * @brief  Gh3x2x switch to detect wear on/off type \r
+ *\r
+ * @attention   Should follow that use WEAR_DETECT_DONT_FORCE_SWITCH @wear on/off irq status process.\r
+ *              If want force switch to detect on/off, should use WEAR_DETECT_FORCE_SWITCH. careful!!!\r
+ *\r
+ * @param[in]   emWearDetectType        switch to detect type @ref EMWearDetectType\r
+ * @param[in]   emForceSwitch           force switch type @ref EMWearDetectForceSwitch\r
+ * @param[out]  None\r
+ *\r
+ * @return  errcode\r
+ * @retval  #GH3X2X_RET_OK                  return successfully\r
+ * @retval  #GH3X2X_RET_GENERIC_ERROR       detect type equal last type, don't need to switch\r
+ * @retval  #GH3X2X_RET_PARAMETER_ERROR     return param error\r
+ */\r
+GS8 GH3X2X_WearDetectSwitchTo(EMWearDetectType emWearDetectType, EMWearDetectForceSwitch emForceSwitch);\r
+\r
+/**\r
+ * @fn     EMSkinColorStatusType GH3X2X_GetSkinStatus(void)\r
+ *\r
+ * @brief  Get gh3x2x skin color status\r
+ *\r
+ * @attention   Must using when chip hard wear detect module enable, if not always return 0\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  skin color status @ref EMSkinColorStatusType\r
+ */\r
+EMSkinColorStatusType GH3X2X_GetSkinStatus(void);\r
+\r
+/**\r
+ * @fn     GS8 GH3X2X_SoftReset(void)\r
+ *\r
+ * @brief  Gh3x2x softreset via i2c/spi, can read&write reg with gh3x2x after reset\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  errcode\r
+ * @retval  #GH3X2X_RET_OK               return successfully\r
+ * @retval  #GH3X2X_RET_GENERIC_ERROR    exit low power mode error\r
+ */\r
+GS8 GH3X2X_SoftReset(void);\r
+\r
+/**\r
+ * @fn     GS8 GH3X2X_LoadNewRegConfigArr(const STGh3x2xReg *pstRegConfigArr, GU16 usRegConfigLen)\r
+ *\r
+ * @brief  Load new gh3x2x reg config array\r
+ *\r
+ * @attention   If reg val don't need verify, should set reg addr bit 12;\r
+ *              If reg is virtual reg, should set reg addr bit 13;\r
+ *              e.g.      need config reg 0x0000: 0x0611\r
+ *                        {0x0000, 0x0611} //verify write by read reg\r
+ *                        {0x1000, 0x0611} //don't need verify write val\r
+ *                        {0x2000, 0x0611} //set virtual reg\r
+ *\r
+ * @param[in]   pstRegConfigArr       pointer to the reg struct array\r
+ * @param[in]   usRegConfigLen        reg struct array length\r
+ * @param[out]  None\r
+ *\r
+ * @return  errcode\r
+ * @retval  #GH3X2X_RET_OK               return successfully\r
+ * @retval  #GH3X2X_RET_COMM_ERROR       gh3x2x communicate error\r
+ */\r
+GS8 GH3X2X_LoadNewRegConfigArr(const STGh3x2xReg *pstRegConfigArr, GU16 usRegConfigLen, GU8 uchChipIndex);\r
+\r
+/**\r
+ * @fn     GS8 GH3X2X_DumpRegs(STGh3x2xReg *pstDumpRegsArr, GU16 usDumpRegsStartAddr, GU16 usDumpRegsLen)\r
+ *\r
+ * @brief  Dump gh3x2x regs\r
+ *\r
+ * @attention   usDumpRegsStartAddr only allow even address, if param set odd address val that val & 0xFFFE in api;\r
+ *              If address greater than reg max addres 0xFFFE, it will return GH3X2X_RET_GENERIC_ERROR.\r
+ *\r
+ * @param[out]  pstDumpRegsArr           pointer to the dump reg struct output\r
+ * @param[in]   usDumpRegsStartAddr     dump reg address\r
+ * @param[in]   usDumpRegsLen           dump reg length\r
+ * @param[out]  None\r
+ *\r
+ * @return  errcode\r
+ * @retval  #GH3X2X_RET_OK               return successfully\r
+ * @retval  #GH3X2X_RET_GENERIC_ERROR    dump gh3x2x address out of bounds\r
+ */\r
+GS8 GH3X2X_DumpRegs(STGh3x2xReg *pstDumpRegsArr, GU16 usDumpRegsStartAddr, GU16 usDumpRegsLen);\r
+\r
+/**\r
+ * @fn     void *GH3X2X_Memcpy(void *pDest, const void *pSrc, GU32 unByteSize)\r
+ *\r
+ * @brief  memcpy() Re-implementation\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   pSrc        pointer to source buffer\r
+ * @param[in]   unByteSize  source buffer byte size\r
+ * @param[out]  pDest       pointer to destination buffer\r
+ *\r
+ * @return  pointer to destination buffer\r
+ */\r
+void *GH3X2X_Memcpy(void *pDest, const void *pSrc, GU32 unByteSize);\r
+\r
+/**\r
+ * @fn     void *GH3X2X_Memset(void* pDest, GCHAR chVal, GU32 unByteSize)\r
+ *\r
+ * @brief  memset() Re-implementation\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   chVal       char val for set\r
+ * @param[in]   unByteSize       source buffer len\r
+ * @param[out]  pDest       pointer to destination buffer\r
+ *\r
+ * @return  pointer to destination buffer\r
+ */\r
+void *GH3X2X_Memset(void* pDest, GCHAR chVal, GU32 unByteSize);\r
+\r
+/**\r
+ * @fn     GU32 GH3X2X_Strlen(const GCHAR *pszSrc)\r
+ *\r
+ * @brief  strlen() Re-implementation\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   pszSrc      pointer to string\r
+ * @param[out]  None\r
+ *\r
+ * @return  string len\r
+ */\r
+GU32 GH3X2X_Strlen(const GCHAR *pszSrc);\r
+\r
+/**\r
+ * @fn     GS8 GH3X2X_CommunicateConfirm(void)\r
+ *\r
+ * @brief  Communication operation interface confirm\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  errcode\r
+ * @retval  #GH3X2X_RET_OK               return successfully\r
+ * @retval  #GH3X2X_RET_COMM_ERROR       gh3x2x communicate error\r
+ */\r
+GS8 GH3X2X_CommunicateConfirm(void);\r
+\r
+/**\r
+ * @fn     GS8 GH3X2X_Init(const STGh3x2xInitConfig *pstGh3x2xInitConfigParam)\r
+ *\r
+ * @brief  Init gh3x2x with configure parameters\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   pstGh3x2xInitConfigParam      pointer to gh3x2x init config param\r
+ * @param[out]  None\r
+ *\r
+ * @return  errcode\r
+ * @retval  #GH3X2X_RET_OK               return successfully\r
+ * @retval  #GH3X2X_RET_COMM_ERROR       gh3x2x communicate error\r
+ */\r
+GS8 GH3X2X_Init(const STGh3x2xInitConfig *pstGh3x2xInitConfigParam);\r
+\r
+/**\r
+ * @fn     GS8 GH3X2X_StartSampling(void)\r
+ *\r
+ * @brief  Start gh3x2x sampling\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  errcode\r
+ * @retval  #GH3X2X_RET_OK                  return successfully\r
+ * @retval  #GH3X2X_RET_NO_INITED_ERROR     gh3x2x has not inited\r
+ * @retval  #GH3X2X_RET_GENERIC_ERROR       gh3x2x has started, need restart should call GH3X2X_StopSampling then start\r
+ */\r
+GS8 GH3X2X_StartSampling(void);\r
+\r
+/**\r
+ * @fn     GS8 GH3X2X_StopSampling(void)\r
+ *\r
+ * @brief  Stop gh3x2x sampling\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ * \r
+ * @return  errcode\r
+ * @retval  #GH3X2X_RET_OK                  return successfully\r
+ * @retval  #GH3X2X_RET_NO_INITED_ERROR     gh3x2x has not inited\r
+ */\r
+GS8 GH3X2X_StopSampling(void);\r
+\r
+/**\r
+ * @fn     GU16 GH3X2X_GetIrqStatus(void)\r
+ *\r
+ * @brief  Get irq status reg val\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  irq status val, ref irq status mask\r
+ */\r
+GU16 GH3X2X_GetIrqStatus(void);\r
+\r
+/**\r
+ * @fn     GS16 GH3X2X_ReadFifodata(GU8 *puchGh3x2xReadFifoData, GU16* pusReadFifoDataLen)\r
+ *\r
+ * @brief  Read Gh3x2x Fifo Data\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  puchGh3x2xReadFifoData      pointer to Gh3x2x fifo data\r
+ * @param[out]  pusReadFifoDataLen          pointer to Gh3x2x fifo data length in byte\r
+ *\r
+ * @return  error code\r
+ * @retval  #GH3X2X_RET_OK                      return read fifo successful\r
+ * @retval  #GH3X2X_RET_PARAMETER_ERROR         return param error\r
+ * @retval  #GH3X2X_RET_READ_FIFO_CONTINUE      return fifo is not empty\r
+ */\r
+GS16 GH3X2X_ReadFifodata(GU8 *puchGh3x2xReadFifoData, GU16* pusReadFifoDataLen ,GU16 usFifoReadByteNum);\r
+\r
+\r
+/**\r
+ * @fn     GS16 GH3X2X_GetRawdata(STGh3x2xRawdata *pstGh3x2xRawdata, GU16* usFifoLength)\r
+ *\r
+ * @brief  Get rawdata from fifo\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  pstGh3x2xRawdata     pointer to rawdata struct output\r
+ * @param[out]  usFifoLength         pointer to read fifo bytes\r
+ *\r
+ * @return  error code\r
+ * @retval  #GH3X2X_RET_PARAMETER_ERROR         return param error\r
+ * @retval  #GH3X2X_RET_READ_FIFO_CONTINUE      return fifo not empty\r
+ */\r
+GS16 GH3X2X_GetRawdata(STGh3x2xRawdata *pstGh3x2xRawdata, GU16* usFifoLength);\r
+\r
+/**\r
+ * @fn     void GH3X2X_UnpackRawdataPackage(STGh3x2xSlotRawdata *pstSlotRawdataArr,\r
+ *                                    GU8 *puchReadRawdataBuffer, GU16 usReadRawdataLen)\r
+ *\r
+ * @brief  Unpack to 8 slot rawdata from read fifo data buffer\r
+ *\r
+ * @attention   This function should use in get rawdata hook;\r
+ *              param pstSlotRawdataArr size must equal 8, defile like stSlotRawdataArr[8].\r
+ *\r
+ * @param[out]  pstSlotRawdataArr       pointer to 8 slot rawdata struct output\r
+ * @param[in]   puchReadRawdataBuffer   pointer to read fifo buffer\r
+ * @param[in]   usReadRawdataLen        read fifo rawdata data len (bytes)\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_UnpackRawdataPackage(STGh3x2xSlotRawdata *pstSlotRawdataArr,\r
+                                    GU8 *puchReadRawdataBuffer, GU16 usReadRawdataLen);\r
+\r
+/**\r
+ * @fn     GS16 GH3X2X_GetRawdataWithChannelMap(STGh3x2xChannelRawdata *pstGh3x2xChannelRawdata, \r
+ *                                       GU8 *puchReadRawdataBuffer, GU16* usFifoLength, GU8 uchChannelMapCnt, \r
+ *                                       GU8 *puchChannelMapArr)\r
+ *\r
+ * @brief  Get rawdata from fifo with channel map\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   puchReadRawdataBuffer       pointer to read data buffer\r
+ * @param[in]   uchChannelMapCnt            channel map array cnt, max:32\r
+ * @param[in]   puchChannelMapArr           pointer to channel map array\r
+ * @param[out]  pstGh3x2xChannelRawdata     pointer to channel rawdata struct output\r
+ * @param[out]  usFifoLength                pointer to read fifo data length in bytes\r
+ *\r
+ * @return  GH3X2X_RET_OK                       return read fifo successful\r
+ * @retval  #GH3X2X_RET_READ_FIFO_CONTINUE      return fifo is not empty\r
+ * @retval  #GH3X2X_RET_PARAMETER_ERROR         return param error\r
+ */\r
+GS16 GH3X2X_GetRawdataWithChannelMap(STGh3x2xChannelRawdata *pstGh3x2xChannelRawdata, \r
+                                        GU8 *puchReadRawdataBuffer, GU16* usFifoLength, GU8 uchChannelMapCnt, \r
+                                        GU8 *puchChannelMapArr);\r
+\r
+/**\r
+ * @fn     GS8 GH3X2X_ChannelMapRawdataClear(STGh3x2xChannelRawdata *pstGh3x2xChannelRawdata)\r
+ *\r
+ * @brief  clear channel map rawdata struct\r
+ *\r
+ * @attention   This function must use before get rawdata by onne kind channel map\r
+ *              e.g. channel map start/stop need clear\r
+ *\r
+ * @param[in]   pstGh3x2xChannelRawdata     pointer to channel rawdata struct\r
+ * @param[out]  None\r
+ *\r
+ * @return  error code\r
+ * @retval  #GH3X2X_RET_OK                      return successfully\r
+ * @retval  #GH3X2X_RET_PARAMETER_ERROR         return param error\r
+ */\r
+GS8 GH3X2X_ChannelMapRawdataClear(STGh3x2xChannelRawdata *pstGh3x2xChannelRawdata);\r
+\r
+/**\r
+ * @fn     GS8 GH3X2X_UnpackRawdataWithChannelMap(STGh3x2xChannelRawdata *pstGh3x2xChannelRawdata, \r
+ *               GU8 *puchReadRawdataBuffer, GU16 usReadRawdataLen, GU8 uchChannelMapCnt, GU8 *puchChannelMapArr)\r
+ *\r
+ * @brief  Unpack to channel rawdata from read fifo data buffer;\r
+ *         if last channel rawdata incomplete, should change fifo watermark\r
+ *\r
+ * @attention   This function should use in get rawdata hook\r
+ * \r
+ * @param[in]   puchReadRawdataBuffer       pointer to read data buffer\r
+ * @param[in]   usReadRawdataLen            read data length\r
+ * @param[in]   uchChannelMapCnt            channel map array cnt, max:32\r
+ * @param[in]   puchChannelMapArr           pointer to channel map array\r
+ * @param[out]  pstGh3x2xChannelRawdata     pointer to channel rawdata struct\r
+ *\r
+ * @return  error code\r
+ * @retval  #GH3X2X_RET_OK                      return successfully\r
+ * @retval  #GH3X2X_RET_PARAMETER_ERROR         return param error\r
+ */\r
+GS8 GH3X2X_UnpackRawdataWithChannelMap(STGh3x2xChannelRawdata *pstGh3x2xChannelRawdata, \r
+                GU8 *puchReadRawdataBuffer, GU16 usReadRawdataLen, GU8 uchChannelMapCnt, GU8 *puchChannelMapArr);\r
+\r
+/**\r
+ * @fn     GS8 GH3X2X_SlotEnableConfig(GU16 usSlotEnableConfig, EMSlotEnableConfigType emSlotEnableConfigType)\r
+ *\r
+ * @brief  Slot enable config\r
+ *\r
+ * @attention  Set slot enable or disable, if just need enable slot by enable config param\r
+ *\r
+ * @param[in]  usSlotEnableConfig         slot enable index , @ref GH3X2X_SLOT_INDEX_0 ... GH3X2X_SLOT_INDEX_ALL\r
+ * @param[in]  emSlotEnableConfigType     slot config type, @ref EMSlotEnableConfigType\r
+ * @param[out]  None\r
+ * \r
+ * @return  errcode\r
+ * @retval  #GH3X2X_RET_OK                  return successfully\r
+ * @retval  #GH3X2X_RET_PARAMETER_ERROR     return param error\r
+ */\r
+GS8 GH3X2X_SlotEnableConfig(GU16 usSlotEnableConfig, EMSlotEnableConfigType emSlotEnableConfigType);\r
+\r
+/**\r
+ * @fn     GS8 GH3X2X_FifoWatermarkThrConfig(GU16 usFifoWatermarkThr)\r
+ *\r
+ * @brief  Fifo water mark threshold config\r
+ *\r
+ * @attention   Watermark threshold val must in (2, 800]. if val <= 2, will set 3, if val > 800, set 800;\r
+ *              Be careful that fifo_use_cnt greater than val, gh3x2x willn't generate fifo_watermark interrupt after!\r
+ *\r
+ * @param[in]  usFifoWatermarkThr         watermark threshold val\r
+ * @param[out]  None\r
+ *\r
+ * @return  errcode\r
+ * @retval  #GH3X2X_RET_OK               return successfully\r
+ */\r
+GS8 GH3X2X_FifoWatermarkThrConfig(GU16 usFifoWatermarkThr);\r
+\r
+/**\r
+ * @fn     GU16 GH3X2X_GetFifoWatermarkThr(void)\r
+ *\r
+ * @brief  Get fifo water mark threshold\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  fifo water mark threshold\r
+ */\r
+GU16 GH3X2X_GetFifoWatermarkThr(void);\r
+\r
+/**\r
+ * @fn     void GH3X2X_SetMaxNumWhenReadFifo(GU16 usMaxNum)\r
+ *\r
+ * @brief  Set max number of rawdata read from fifo every time\r
+ *\r
+ * @attention   None.\r
+ *\r
+ * @param[in]   usMaxNum        max number of rawdata read from fifo\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_SetMaxNumWhenReadFifo(GU16 usMaxNum);\r
+\r
+/**\r
+ * @fn     GS8 GH3X2X_SlotLedCurrentConfig(GU8 uchSlotIndex, GU8 uchDrvIndex, GU8 uchCurrentVal)\r
+ *\r
+ * @brief  Slot led current config\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   uchSlotIndex        slot index [0-7]\r
+ * @param[in]   uchDrvIndex         driver index @ref GH3X2X_LED_DRV_INDEX_0 ... GH3X2X_LED_DRV_INDEX_1\r
+ * @param[in]   uchCurrentVal       current val\r
+ * @param[out]  None\r
+ *\r
+ * @return  errcode\r
+ * @retval  #GH3X2X_RET_OK               return successfully\r
+ * @retval  #GH3X2X_RET_PARAMETER_ERROR     return param error\r
+ */\r
+GS8 GH3X2X_SlotLedCurrentConfig(GU8 uchSlotIndex, GU8 uchDrvIndex, GU8 uchCurrentVal);\r
+\r
+/**\r
+ * @fn     GU8 GH3X2X_GetSlotLedCurrent(GU8 uchSlotIndex, GU8 uchDrvIndex)\r
+ *\r
+ * @brief  Get slot led current config\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   uchSlotIndex        slot index [0-7]\r
+ * @param[in]   uchDrvIndex         driver index @ref GH3X2X_LED_DRV_INDEX_0 ... GH3X2X_LED_DRV_INDEX_1\r
+ * @param[out]  None\r
+ *\r
+ * @return  current val. if param error, return val always equal 0\r
+ */\r
+GU8 GH3X2X_GetSlotLedCurrent(GU8 uchSlotIndex, GU8 uchDrvIndex);\r
+\r
+/**\r
+ * @fn     GS8 GH3X2X_SlotLedTiaGainConfig(GU8 uchSlotIndex, GU8 uchAdcIndex, GU8 uchGainVal)\r
+ *\r
+ * @brief  Slot gain config\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   uchSlotIndex        slot index [0-7]\r
+ * @param[in]   uchAdcIndex         adc index [0-3]\r
+ * @param[in]   uchGainVal          tia gain val [0-12]\r
+ * @param[out]  None\r
+ *\r
+ * @return  errcode\r
+ * @retval  #GH3X2X_RET_OK                  return successfully\r
+ * @retval  #GH3X2X_RET_PARAMETER_ERROR     return param error\r
+ */\r
+GS8 GH3X2X_SlotLedTiaGainConfig(GU8 uchSlotIndex, GU8 uchAdcIndex, GU8 uchGainVal);\r
+\r
+/**\r
+ * @fn     GU8 GH3X2X_GetSlotLedTiaGain(GU8 uchSlotIndex, GU8 uchAdcIndex)\r
+ *\r
+ * @brief  Get slot gain config\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   uchSlotIndex        slot index [0-7]\r
+ * @param[in]   uchAdcIndex         adc index [0-3]\r
+ * @param[out]  None\r
+ *\r
+ * @return  tia gain val. if param error, return val always equal 0\r
+ */\r
+GU8 GH3X2X_GetSlotLedTiaGain(GU8 uchSlotIndex, GU8 uchAdcIndex);\r
+\r
+/**\r
+ * @fn     GS8 GH3X2X_AdcBgcThrConfig(GU8 uchAdcIndex, GU8 uchBgcThrVal)\r
+ *\r
+ * @brief  adc bgc thr config\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   uchAdcIndex         adc index [0-3]\r
+ * @param[in]   uchBgcThrVal        bgc thr val [0-7]\r
+ * @param[out]  None\r
+ *\r
+ * @return  errcode\r
+ * @retval  #GH3X2X_RET_OK                  return successfully\r
+ * @retval  #GH3X2X_RET_PARAMETER_ERROR     return param error\r
+ */\r
+GS8 GH3X2X_AdcBgcThrConfig(GU8 uchAdcIndex, GU8 uchBgcThrVal);\r
+\r
+/**\r
+ * @fn     GU8 GH3X2X_GetAdcBgcThr(GU8 uchAdcIndex)\r
+ *\r
+ * @brief  Get adc bgc thr config\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   uchAdcIndex         adc index [0-3]\r
+ * @param[out]  None\r
+ *\r
+ * @return  tia gain val. if param error, return val always equal 0\r
+ */\r
+GU8 GH3X2X_GetAdcBgcThr(GU8 uchAdcIndex);\r
+\r
+/**\r
+ * @fn     GS8 GH3X2X_IrqWidthConfig(GU16 usIrqPulseWidth, GU16 usIrqColdWidth)\r
+ *\r
+ * @brief  Irq width config\r
+ *\r
+ * @attention   Irq val must in [0, 2047]. real_width = (val + 1) * low_clk_tick;\r
+ *              low_clk default 32k, if set ext clk enable that use low_ext_clk;\r
+ *\r
+ * @param[in]  usIrqPulseWidth         irq pulse width val\r
+ * @param[in]  usIrqColdWidth          irq cold width val\r
+ * @param[out]  None\r
+ *\r
+ * @return  errcode\r
+ * @retval  #GH3X2X_RET_OK               return successfully\r
+ */\r
+GS8 GH3X2X_IrqWidthConfig(GU16 usIrqPulseWidth, GU16 usIrqColdWidth);\r
+\r
+/**\r
+ * @fn     GS8 GH3X2X_IrqModeConfig(EMIrqModeConfig emIrqMode)\r
+ *\r
+ * @brief  Irq mode config\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   emIrqMode         irq mode config @ref EMIrqModeConfig\r
+ * @param[out]  None\r
+ *\r
+ * @return  errcode\r
+ * @retval  #GH3X2X_RET_OK               return successfully\r
+ */\r
+GS8 GH3X2X_IrqModeConfig(EMIrqModeConfig emIrqMode);\r
+\r
+/**\r
+ * @fn     GS8 GH3X2X_HsiClockCalibration(void)\r
+ *\r
+ * @brief  Calibration Hsi(high-speed internal) clock\r
+ *\r
+ * @attention   must use 4M clock input @OSCIN pin\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  errcode\r
+ * @retval  #GH3X2X_RET_OK                  return successfully\r
+ * @retval  #GH3X2X_RET_GENERIC_ERROR       input clock is unstable, or sampling was started\r
+ */\r
+GS8 GH3X2X_HsiClockCalibration(void);\r
+\r
+/**\r
+ * @fn     GS8 GH3X2X_LsiClockCalibration(void)\r
+ *\r
+ * @brief  Calibration Lsi(low-speed internal) clock\r
+ *\r
+ * @attention   must use 4M clock input @OSCIN pin, take case that will consume about 100ms\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  errcode\r
+ * @retval  #GH3X2X_RET_OK                  return successfully\r
+ * @retval  #GH3X2X_RET_GENERIC_ERROR       input clock is unstable, or sampling was started\r
+ */\r
+GS8 GH3X2X_LsiClockCalibration(void);\r
+\r
+\r
+\r
+\r
+/**\r
+ * @fn     void GH3X2X_SoftLedADJAutoADJInt(void)\r
+ * \r
+ * @brief  init some agc parameter\r
+ *\r
+ * @attention   \r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_SoftLedADJAutoADJInt(void);\r
+\r
+/**\r
+ * @fn     void GH3X2X_LedAgcProcess(GU8* puchReadFifoBuffer, GU16 usFifoLen, STGh3x2xAgcInfo *STGh3x2xAgcInfo)\r
+ * \r
+ * @brief  led agc process function\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   puchReadFifoBuffer         pointer to read fifo data buffer\r
+ * @param[in]   usFifoLen           read fifo data buffer length\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_LedAgcProcess(GU8* puchReadFifoBuffer, GU16 usFifoLen, STGh3x2xAgcInfo *STGh3x2xAgcInfo);\r
+\r
+/**\r
+ * @fn     void GH3X2X_LedAgcProcessEx(GU8* puchReadFifoBuffer)\r
+ * \r
+ * @brief  led agc process function\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   puchReadFifoBuffer      pointer to read fifo data buffer\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_LedAgcProcessEx(GU8* puchReadFifoBuffer);\r
+\r
+void GH3x2xNewAgcMeanInfoReset(GU8 uchSlotEnChange);\r
+\r
+/**\r
+ * @fn     void GH3X2X_RegisterReadPinStatusFunc(GU8 (*pReadIntPinStatusFunc)(void),\r
+ *                                       GU8 (*pReadResetPinStatusFunc)(void),\r
+ *                                      GU8 (*pReadSpcsPinStatusFunc)(void),\r
+ *                                     GU8 (*pReadSpdoPinStatusFunc)(void))\r
+ *\r
+ * @brief  Register read pin status function\r
+ *\r
+ * @attention   Only use for debug, read gh3x2x some pin status can debug some hardware errors;\r
+ *              Pin status return should define as 1 [high level] or 0 [low level];\r
+ *\r
+ * @param[in]   pReadIntPinStatusFunc       pointer to read int pin staus function\r
+ * @param[in]   pReadResetPinStatusFunc     pointer to read reset pin staus function\r
+ * @param[in]   pReadSpcsPinStatusFunc      pointer to read spcs pin staus function\r
+ * @param[in]   pReadSpdoPinStatusFunc      pointer to read spdo pin staus function\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_RegisterReadPinStatusFunc(GU8 (*pReadIntPinStatusFunc)(void),\r
+                                      GU8 (*pReadResetPinStatusFunc)(void),\r
+                                      GU8 (*pReadSpcsPinStatusFunc)(void),\r
+                                      GU8 (*pReadSpdoPinStatusFunc)(void));\r
+\r
+/**\r
+ * @fn     GCHAR *GH3X2X_GetDriverLibVersion(void)\r
+ *\r
+ * @brief  Get driver version\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  library version string\r
+ */\r
+GCHAR *GH3X2X_GetDriverLibVersion(void);\r
+GCHAR *GH3X2X_GetProtocolVersion(void);\r
+GCHAR *GH3X2X_GetVirtualRegVersion(void);\r
+\r
+/**\r
+ * @fn     void GH3X2X_RegisterGetFirmwareVersionFunc(GCHAR* (*pGetFirmwareVersionFunc)(void))\r
+ *\r
+ * @brief  Register get firmware version function\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]    pGetFirmwareVersionFunc    pointer to get firmware versionn function\r
+ * @param[out]   None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_RegisterGetFirmwareVersionFunc(GCHAR* (*pGetFirmwareVersionFunc)(void),\r
+                                           GCHAR* (*pGetDemoVersionFunc)(void),\r
+                                           GCHAR* (*pGetBootloaderVersionFunc)(void));\r
+\r
+/**\r
+ * @fn     EMUprotocolParseCmdType GH3X2X_UprotocolParseHandler(GU8 *puchRespondBuffer, GU16 *pusRespondLen,\r
+ *                                                     GU8 *puchRecvDataBuffer, GU16 usRecvLen)\r
+ *\r
+ * @brief  universal protocol parse handler, parse protocol receive data\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[out]   puchRespondBuffer    pointer to respond buffer\r
+ * @param[out]   pusRespondLen        pointer to respond length\r
+ * @param[in]    puchRecvDataBuffer   pointer to receive data buffer\r
+ * @param[in]    usRecvLen            receive data len\r
+ *\r
+ * @return  @ref EMUprotocolParseCmdType\r
+ */\r
+EMUprotocolParseCmdType GH3X2X_UprotocolParseHandler(GU8 *puchRespondBuffer, GU16 *pusRespondLen,\r
+                                                     GU8 *puchRecvDataBuffer, GU16 usRecvLen);\r
+\r
+/**\r
+ * @fn     GU8 GH3X2X_UprotocolPacketMaxLenConfig(GU8 uchPacketMaxLen)\r
+ *\r
+ * @brief  packet max len support, default len is 243\r
+ *\r
+ * @attention   uchPacketMaxLen val must at [20, 243]\r
+ *\r
+ * @param[out]   None\r
+ * @param[in]    uchPacketMaxLen      packet max len\r
+ *\r
+ * @return  packet max len after config\r
+ */\r
+GU8 GH3X2X_UprotocolPacketMaxLenConfig(GU8 uchPacketMaxLen);\r
+\r
+/**\r
+ * @fn     GS8 GH3X2X_SendRawDataPkg(GU8 *puchRespondBuffer, GU16 *pusRespondLen, GU8 *puchFifoRawdata, \r
+ *                    GU16 usFifoRawdataLen, GU8 uchChannelMapArr[], GU8 uchChannelMapCnt, \r
+ *                   STGsensorRawdata *pstGsAxisValueArr, GU16 usGsDataNum, EMGsensorSensitivity emGsSensitivity, \r
+ *                   GU8 uchChannelMapId, GU32 *punLastIncompleteMark, GU32 *punIncompleteRawdataArr)\r
+ *\r
+ * @brief  Pack rawdata with g sensor data\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[out]  puchRespondBuffer       pointer to protocol pkg data.\r
+ * @param[out]  pusRespondLen           pointer to protocol pkg data length\r
+ * @param[in]   puchFifoRawdata         pointer to data buffer of rawdata\r
+ * @param[in]   usFifoRawdataLen        data num of rawdata buf\r
+ * @param[in]   uchChannelMapArr        pointer to channel map array\r
+ * @param[in]   uchChannelMapCnt        channel map array cnt, max:32\r
+ * @param[in]   pstGsAxisValueArr       pointer to g sensor data\r
+ * @param[in]   usGsDataNum             g sensor data number\r
+ * @param[in]   emGsSensitivity         g sensor sensitivity\r
+ * @param[in]   uchChannelMapId         channel map id(0 - 5)\r
+ * @param[in]   punLastIncompleteMark   incomplete mark\r
+ * @param[in]   punIncompleteRawdataArr incomplete data array\r
+ * @return  error code\r
+ * @retval  #GH3X2X_RET_PARAMETER_ERROR         return param error\r
+ * @retval  #GH3X2X_RET_RAW_DATA_PKG_OVER       return already read all the package data \r
+ * @retval  #GH3X2X_RET_RAW_DATA_PKG_CONTINUE   return should read rawdata package data again\r
+ * @retval  #GH3X2X_RET_RESOURCE_ERROR          return not enough data\r
+ */\r
+\r
+\r
+/**\r
+ * @fn     GS8 GH3X2X_CustomizeFuncStartedBitSet(void)\r
+ *\r
+ * @brief  Set Customize started bitmap\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[out]  None\r
+ * @param[in]   None\r
+ *\r
+ * @return  error code\r
+ * @retval  #GH3X2X_RET_OK                      return algorithm run successfully\r
+ */\r
+GS8 GH3X2X_CustomizeFuncStartedBitSet(void);\r
+\r
+/**\r
+ * @fn     GS8 GH3X2X_CustomizeFuncStartedBitClear(void)\r
+ *\r
+ * @brief  Clear Customize started bitmap\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[out]  None\r
+ * @param[in]   None\r
+ *\r
+ * @return  error code\r
+ * @retval  #GH3X2X_RET_OK                      return algorithm run successfully\r
+ */\r
+GS8 GH3X2X_CustomizeFuncStartedBitClear(void);\r
+\r
+/**\r
+ * @fn     GS8 GH3X2X_GetRawdataForAlgorithmEx(GU8 *puchPackageDataBuffer)\r
+ *\r
+ * @brief  Get rawdata package for algorithm\r
+ *\r
+ * @attention   buffer size must define greater or equal to ((fifo_thr + n) * 4 + 5)\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  puchPackageDataBuffer   pointer to package data output\r
+ *\r
+ * @return  error code\r
+ * @retval  #GH3X2X_RET_OK               return successfully\r
+ * @retval  #GH3X2X_RET_RESOURCE_ERROR   resource error\r
+ */\r
+GS8 GH3X2X_GetRawdataForAlgorithmEx(GU8 *puchPackageDataBuffer ,GU16 uchFifoReadByteNum);\r
+\r
+/**\r
+ * @fn     GS8 GH3X2X_AllFuncDeinit(void)\r
+ *\r
+ * @brief  deinit all func\r
+ *\r
+ * @attention   if disable all or chip reset, need call this api\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  error code\r
+ * @retval  #GH3X2X_RET_OK                      return successfully\r
+ * @retval  #GH3X2X_RET_GENERIC_ERROR           return algorithm deinit error\r
+ * @retval  #GH3X2X_RET_ALGO_NO_SUPPORTED       return algorithm no supported error\r
+ */\r
+GS8 GH3X2X_AllFuncDeinit(void);\r
+\r
+/**\r
+ * @fn     GS8 GH3X2X_AllFuncDeinitEx(void)\r
+ *\r
+ * @brief  deinit all func\r
+ *\r
+ * @attention   this api not deinit algorithm\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  error code\r
+ * @retval  #GH3X2X_RET_OK                      return successfully\r
+ * @retval  #GH3X2X_RET_GENERIC_ERROR           return algorithm deinit error\r
+ * @retval  #GH3X2X_RET_ALGO_NO_SUPPORTED       return algorithm no supported error\r
+ */\r
+GS8 GH3X2X_AllFuncDeinitEx(void);\r
+\r
+/**\r
+ * @fn     void GH3X2X_ReportIrqStatus(GU8 *puchRespondBuffer, GU16 *pusRespondLen, GU16 usIrqStatus)\r
+ *\r
+ * @brief  report irq status of Gh3x2x\r
+ *\r
+ * @attention   none\r
+ *\r
+ * @param[out]  puchRespondBuffer       pointer to protocol pkg data.\r
+ * @param[out]  pusRespondLen           pointer to protocol pkg data length\r
+ * @param[in]   usIrqStatus             irq status need report\r
+ * @return  none\r
+ */\r
+void GH3X2X_ReportIrqStatus(GU8 *puchRespondBuffer, GU16 *pusRespondLen, GU16 usIrqStatus);\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+/**\r
+ * @fn      void GhMoveDetectByGsData(STGsensorRawdata* stGsData, GU16 usGsDataCnt, GU8 uchCheckWindowSize)\r
+ \r
+ *\r
+ * @brief  Move detection by software.\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   stGsData        gsensor data buffer\r
+ * @param[in]   usGsDataCnt     gsensor data count\r
+ * @param[in]   uchCheckWindowSize      the window size of cheak moving peak num \r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GhMoveDetectByGsData(GS16* pusGsData, GU16 usGsDataCnt);\r
+\r
+\r
+\r
+\r
+\r
+/**\r
+ * @fn     GU8 Gh3x2x_GetMoveDetStatus(void)\r
+ *\r
+ * @brief  Get status of movement detected\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  GH3X2X_SENSOR_IS_NOT_MOVING/GH3X2X_SENSOR_IS_MOVING\r
+ */\r
+GU8 Gh3x2x_GetMoveDetStatus(void);\r
+\r
+/**\r
+ * @fn     GU8 Gh3x2x_GetAdtGsensorDetectStatus(void)\r
+ *\r
+ * @brief  Get status of Gsensor detect status \r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  g_uchGsensorDetectEn 0:disable 1:enable\r
+ */\r
+GU8 Gh3x2x_GetAdtGsensorDetectStatus(void);\r
+\r
+/**\r
+ * @fn     void Gh3x2x_SetAdtGsensorDetectStatus(void)\r
+ * @brief  set g_uchGsensorDetectEn\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ * @return  None\r
+  */\r
+void Gh3x2x_SetAdtGsensorDetectStatus(void);\r
+\r
+/**\r
+ * @fn     void Gh3x2x_ClearAdtGsensorDetectStatus(void)\r
+ * @brief  clear g_uchGsensorDetectEn\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ * @return  None\r
+  */\r
+void Gh3x2x_ClearAdtGsensorDetectStatus(void);\r
+\r
+/**\r
+ * @fn     GS8 GH3X2X_SendAdtRawdataPkg(GU8 *puchRespondBuffer, GU16 *pusRespondLen, GU8 *puchFifoRawdata,\r
+ *                       STAlgoCalculateRes* pstAlgoRes, STGsensorRawdata *pstGsAxisValueArr,\r
+ *                       GU16 usGsDataNum, EMGsensorSensitivity emGsSensitivity)\r
+ *                  \r
+ * @brief  pack GH3X2X adt rawdata and other type of data according to specific protocol\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[out]  puchRespondBuffer       pointer to frame data package\r
+ * @param[out]  pusRespondLen           pointer to data length of package\r
+ * @param[in]   puchFifoRawdata         pointer to encrypted rawdata\r
+ * @param[in]   pstAlgoRes              pointer to algorithm result\r
+ * @param[in]   pstGsAxisValueArr       pointer to g sensor data\r
+ * @param[in]   usGsDataNum             number of g sensor data\r
+ * @param[in]   emGsSensitivity         sensitivity of g sensor\r
+ *\r
+ * @return  error code\r
+ * @retval  #GH3X2X_RET_OK                      return successfully\r
+ * @retval  #GH3X2X_RET_GENERIC_ERROR           return func start error\r
+ * @retval  #GH3X2X_RET_NO_INITED_ERROR         gh3x2x has not inited\r
+ */\r
+\r
+\r
+\r
+\r
+/**\r
+ * @fn     GS8 GH3X2X_SendAdtRawdataPkgEx(GU8 *puchRespondBuffer, GU16 *pusRespondLen, GU8 *puchFifoRawdata, \r
+ *                      GU16 usFifoDataLen, STAlgoCalculateRes* pstAlgoRes, STGsensorRawdata *pstGsAxisValueArr,\r
+                        GU16 usGsDataNum, EMGsensorSensitivity emGsSensitivity);\r
+ *                  \r
+ * @brief  pack GH3X2X adt rawdata and other type of data according to specific protocol\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[out]  puchRespondBuffer       pointer to frame data package\r
+ * @param[out]  pusRespondLen           pointer to data length of package\r
+ * @param[in]   puchFifoRawdata         pointer to encrypted rawdata\r
+ * @param[in]   usFifoDataLen           gh3x2x fifo data len in byte\r
+ * @param[in]   pstAlgoRes              pointer to algorithm result\r
+ * @param[in]   pstGsAxisValueArr       pointer to g sensor data\r
+ * @param[in]   usGsDataNum             number of g sensor data\r
+ * @param[in]   emGsSensitivity         sensitivity of g sensor\r
+ *\r
+ * @return  error code\r
+ * @retval  #GH3X2X_RET_OK                      return successfully\r
+ * @retval  #GH3X2X_RET_GENERIC_ERROR           return func start error\r
+ * @retval  #GH3X2X_RET_NO_INITED_ERROR         gh3x2x has not inited\r
+ */\r
+\r
+\r
+\r
+\r
+/**\r
+ * @fn     GS8 GH3X2X_SendZipAdtRawdataPkg(GU8 *puchRespondBuffer, GU16 *pusRespondLen, GU8 *puchFifoRawdata,\r
+ *                       STAlgoCalculateRes* pstAlgoRes, STGsensorRawdata *pstGsAxisValueArr,\r
+ *                       GU16 usGsDataNum, EMGsensorSensitivity emGsSensitivity)\r
+ *                  \r
+ * @brief  pack GH3X2X Zip adt rawdata and other type of data according to specific protocol\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[out]  puchRespondBuffer       pointer to frame data package\r
+ * @param[out]  pusRespondLen           pointer to data length of package\r
+ * @param[in]   puchFifoRawdata         pointer to encrypted rawdata\r
+ * @param[in]   pstAlgoRes              pointer to algorithm result\r
+ * @param[in]   pstGsAxisValueArr       pointer to g sensor data\r
+ * @param[in]   usGsDataNum             number of g sensor data\r
+ * @param[in]   emGsSensitivity         sensitivity of g sensor\r
+ *\r
+ * @return  error code\r
+ * @retval  #GH3X2X_RET_OK                      return successfully\r
+ * @retval  #GH3X2X_RET_GENERIC_ERROR           return func start error\r
+ * @retval  #GH3X2X_RET_NO_INITED_ERROR         gh3x2x has not inited\r
+ */\r
+\r
+\r
+\r
+\r
+/**\r
+ * @fn     GS8 GH3X2X_SendZipAdtRawdataPkgEx(GU8 *puchRespondBuffer, GU16 *pusRespondLen, GU8 *puchFifoRawdata, \r
+ *                      GU16 usFifoDataLen, STAlgoCalculateRes* pstAlgoRes, STGsensorRawdata *pstGsAxisValueArr,\r
+                        GU16 usGsDataNum, EMGsensorSensitivity emGsSensitivity);\r
+ *                  \r
+ * @brief  pack GH3X2X Zip adt rawdata and other type of data according to specific protocol\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[out]  puchRespondBuffer       pointer to frame data package\r
+ * @param[out]  pusRespondLen           pointer to data length of package\r
+ * @param[in]   puchFifoRawdata         pointer to encrypted rawdata\r
+ * @param[in]   usFifoDataLen           gh3x2x fifo data len in byte\r
+ * @param[in]   pstAlgoRes              pointer to algorithm result\r
+ * @param[in]   pstGsAxisValueArr       pointer to g sensor data\r
+ * @param[in]   usGsDataNum             number of g sensor data\r
+ * @param[in]   emGsSensitivity         sensitivity of g sensor\r
+ *\r
+ * @return  error code\r
+ * @retval  #GH3X2X_RET_OK                      return successfully\r
+ * @retval  #GH3X2X_RET_GENERIC_ERROR           return func start error\r
+ * @retval  #GH3X2X_RET_NO_INITED_ERROR         gh3x2x has not inited\r
+ */\r
+\r
+\r
+\r
+\r
+/**\r
+ * @fn     GU32 GH3X2X_GetFuncModeAvailable(void)\r
+ *\r
+ * @brief  Get all function mode available\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[out]  None\r
+ * @param[in]   None\r
+ * @return  function mode, @ref GH3X2X_NO_FUNCTION ... GH3X2X_FUNCTION_PWTT\r
+ */\r
+GU32 GH3X2X_GetFuncModeAvailable(void);\r
+\r
+/**\r
+ * @fn     GU32 GH3X2X_GetFuncModeOpened(void)\r
+ *\r
+ * @brief  Get function mode that already opened\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[out]  None\r
+ * @param[in]   None\r
+ * @return  function mode, @ref GH3X2X_NO_FUNCTION ... GH3X2X_FUNCTION_PWTT\r
+ */\r
+GU32 GH3X2X_GetFuncModeOpened(void);\r
+\r
+/**\r
+ * @fn     GU32 GH3X2X_GetTargetFuncMode(void)\r
+ *\r
+ * @brief  Get function mode that will be opened or closed\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[out]  None\r
+ * @param[in]   None\r
+ * @return  function mode, @ref GH3X2X_NO_FUNCTION ... GH3X2X_FUNCTION_PWTT\r
+ */\r
+GU32 GH3X2X_GetTargetFuncMode(void);\r
+\r
+/**\r
+ * @fn     GS8 GH3X2X_DecodeRegCfgArr(GU32* punRunMode, const STGh3x2xReg *pstRegConfigArr, GU16 usRegConfigLen)\r
+ *\r
+ * @brief  Analyze reg cfg array to get the run mode.\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   pstRegConfigArr             pointer to reg config array\r
+ * @param[in]   usRegConfigLen              reg config array length\r
+ * @param[out]  punRunMode                  pointer to run mode contained in reg config array\r
+ *\r
+ * @retval  #GH3X2X_RET_OK                      return successfully\r
+ * @retval  #GH3X2X_RET_PARAMETER_ERROR         return parameter error\r
+ */\r
+GS8 GH3X2X_DecodeRegCfgArr(GU32* punRunMode, const STGh3x2xReg *pstRegConfigArr, GU16 usRegConfigLen);\r
+\r
+/**\r
+ * @fn     GU8 GH3X2X_GetGsensorEnableFlag(void)\r
+ *\r
+ * @brief  Inquire if need gsensor data\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  1: need gsensor data  0: not need gsensor data\r
+ */\r
+GU8 GH3X2X_GetGsensorEnableFlag(void);\r
+GU8 GH3X2X_GetCapEnableFlag(void);\r
+GU8 GH3X2X_GetTempEnableFlag(void);\r
+/**\r
+ * @fn     STSoftLeadResult GH3X2X_LeadHandle(GU16 usIrqStatus, GU8 *puchReadFifoBuffer, GU16* pusFifoBufferLen)\r
+ *\r
+ * @brief  ecg soft lead handle\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   usIrqStatus               irq status\r
+ * @param[in]   puchReadFifoBuffer         pointer to read fifo data buffer\r
+ * @param[in]   usFifoBufferLen           read fifo buffer len\r
+ * @param[out]  None\r
+ *\r
+ * @return  soft lead handle process, @ref STSoftLeadResult\r
+ */\r
+STSoftLeadResult GH3X2X_LeadHandle(GU16 usIrqStatus, GU8 *puchReadFifoBuffer, GU16* pusFifoBufferLen);\r
+\r
+/**\r
+ * @fn     STSoftLeadResult GH3X2X_LeadHandleEx(GU16 usIrqStatus, GU8 *puchReadFifoBuffer)\r
+ *\r
+ * @brief  ecg soft lead handle\r
+ *\r
+ * @attention   use after GH3X2X_GetRawdataForAlgorithm or GH3X2X_GetRawdataForAlgorithmEx\r
+ *\r
+ * @param[in]   usIrqStatus               irq status\r
+ * @param[in]   puchReadFifoBuffer         pointer to read fifo data buffer\r
+ * @param[out]  None\r
+ *\r
+ * @return  soft lead handle process, @ref STSoftLeadResult\r
+ */\r
+//STSoftLeadResult GH3X2X_LeadHandleEx(GU16 usIrqStatus, GU8 *puchReadFifoBuffer);\r
+\r
+/**\r
+ * @fn     GU32 GH3X2X_GetSoftEvent(void)\r
+ * @brief  Get soft event\r
+ * @param[in]   None\r
+ * @param[out]  Soft event\r
+ *\r
+ * @return  soft event\r
+ */\r
+GU32 GH3X2X_GetSoftEvent(void);\r
+\r
+/**\r
+ * @fn     void GH3X2X_SetSoftEvent(GU32 unEvent)\r
+ * @brief  set soft event\r
+ * @param[in]   uchEvent\r
+ * @param[out]  None\r
+ * @return  None\r
+ */\r
+void GH3X2X_SetSoftEvent(GU32 unEvent);\r
+\r
+/**\r
+ * @fn     void GH3X2X_ClearSoftEvent(GU32 unEvent)\r
+ * @brief  clear soft event\r
+ * @param[in]   uchEvent\r
+ * @param[out]  None\r
+ * @return  None\r
+ */\r
+void GH3X2X_ClearSoftEvent(GU32 unEvent);\r
+\r
+\r
+/**\r
+ * @fn     void GH3X2X_AddElectrodeWearRevCnt(void)\r
+ *\r
+ * @brief  GH3X2X_AddElectrodeWearRevCnt\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_AddElectrodeWearRevCnt(void);\r
+\r
+/**\r
+ * @fn     GU8 GH3X2X_ElectrodeWearRevertDebugModeIsEnabled(void)\r
+ *\r
+ * @brief  Check if electrode wear revert debug mode is enabled\r
+ *\r
+ * @attention   In this mode,not need report wear event,need report the number of wear electrode revert.\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  1: enabled, 0:disabled\r
+ */\r
+GU8 GH3X2X_ElectrodeWearRevertDebugModeIsEnabled(void);\r
+\r
+\r
+\r
+/**\r
+ * @fn     void GH3X2X_SoftWearOffDetInit(void)\r
+ *\r
+ * @brief  Soft wear off detect init\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_SoftWearOffDetInit(void);\r
+\r
+\r
+\r
+void GH3X2X_SetSoftWearOffDetEn(GU8 uchSoftWearOffDetEn);\r
+void GH3X2X_SetHardAdtAlgoCheckEn(GU8 uchHardAdtCheckByAlgo);\r
+\r
+/**\r
+ * @fn     GU8 GH3X2X_UpdateSoftWearOffStatus(GU16 *pusEvent)\r
+ *\r
+ * @brief  update wear status\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   old event point\r
+ * @param[out]  0: no soft wear off det event  1: have soft wear off det event\r
+ *\r
+ * @return  new event\r
+ */\r
+GU8 GH3X2X_UpdateSoftWearOffStatus(GU16 *pusEvent, GU8 *puchSoftAdtFlag ,GU8 *puchLivingConfi);\r
+\r
+/**\r
+ * @fn     GU16 GH3X2X_GetCurrentFifoWaterLine(void)\r
+ *\r
+ * @brief  get current fifo water line setting\r
+ *\r
+ * @attention   None.\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  fifo water line\r
+ *\r
+ * @return  None\r
+ */\r
+GU16 GH3X2X_GetCurrentFifoWaterLine(void);\r
+\r
+\r
+\r
+/**\r
+ * @fn     GS8 GH3X2X_CalibrateECGGainEx(GU8 *puchReadFifoBuffer)\r
+ *\r
+ * @brief  Calibrate ECG Gain\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   puchReadFifoBuffer      pointer read data buffer from GH3X2X_GetRawdataForAlgorithm\r
+ *\r
+ * @return  error code\r
+ * @retval  #GH3X2X_RET_OK                      return algorithm run successfully, but output hasn't refreshed\r
+ * @retval  #GH3X2X_RET_GENERIC_ERROR           return algorithm generic error\r
+ */\r
+\r
+GS8 GH3X2X_CalibrateECGGainEx(GU8 *puchReadFifoBuffer);\r
+\r
+\r
+/**\r
+ * @fn     GS8 GH3X2X_CalibrateECGGain(GU8 *puchReadFifoBuffer)\r
+ *\r
+ * @brief  Calibrate ECG Gain\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]       puchReadFifoBuffer      pointer read data buffer\r
+ * @param[in]       usFifoBufferLen         fifo byte length \r
+ * @return  error code\r
+ * @retval  #GH3X2X_RET_OK                      return algorithm run successfully, but output hasn't refreshed\r
+ * @retval  #GH3X2X_RET_GENERIC_ERROR           return algorithm generic error\r
+ */\r
+\r
+GS8 GH3X2X_CalibrateECGGain(GU8 *puchReadFifoBuffer, GU16 usFifoBufferLen);\r
+\r
+\r
+\r
+/**\r
+ * @fn       GU8 GH3x2x_SetChipResetRecoveringFlag(void)\r
+ \r
+ \r
+ *\r
+ * @brief  \r
+ *\r
+ * @attention   None.\r
+ *\r
+ * @param[in]   chip reset recovering flag  0: is not in chip reset recovering flag  1: is in chip reset recovering\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3x2x_SetChipResetRecoveringFlag(GU8 uchChipResetRecoeringFlag);\r
+\r
+\r
+/**\r
+ * @fn       GU8 GH3x2x_GetChipResetRecoveringFlag(void)\r
+ \r
+ \r
+ *\r
+ * @brief  \r
+ *\r
+ * @attention   None.\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  chip reset recovering flag  0: is not in chip reset recovering flag  1: is in chip reset recovering\r
+ *\r
+ * @return  None\r
+ */\r
+GU8 GH3x2x_GetChipResetRecoveringFlag(void);\r
+\r
+\r
+\r
+\r
+/**\r
+ * @fn       GU8 GH3x2x_GetActiveChipResetFlag(void)\r
+ \r
+ \r
+ *\r
+ * @brief  \r
+ *\r
+ * @attention   None.\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  ActiveChipResetFlag  1: user have done chip reset(soft reset and hardwear reset) actively   gh3x2x_init will clear it \r
+ *\r
+ * @return  None\r
+ */\r
+GU8 GH3x2x_GetActiveChipResetFlag(void);\r
+\r
+\r
+/**\r
+ * @fn     void GH3X2X_UpdateAgcInfo(void)\r
+ *\r
+ * @brief  record tia gain drv information\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_UpdateAgcInfo(void);\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+/**\r
+ * @fn     void GH3X2X_SlotEnRegSet(GU8 uchSetValue)\r
+ *\r
+ * @brief  Slot enable reg set\r
+ *\r
+ * @attention  None\r
+ *\r
+ * @param[in]  set value\r
+ * @param[out]  None\r
+ * \r
+ * @return  None\r
+ */\r
+void GH3X2X_SlotEnRegSet(GU8 uchSetValue);\r
+\r
+/**\r
+ * @fn     void GH3X2X_ModifyFunctionFrequency(GU8 uchFunctionID, GU16 usFrequencyValue)\r
+ *\r
+ * @brief  Modify fs for each function\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   uchFunctionID               function offset\r
+ * @param[in]   usFrequencyValue         5Hz-1000Hz\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_ModifyFunctionFrequency(GU8 uchFunctionID, GU16 usFrequencyValue);\r
+\r
+/**\r
+ * @fn     void GH3X2X_ModifyFunctionLedCurrent(GU8 uchFunctionID, GU16 usLedDrv0Current, GU16 usLedDrv1Current)\r
+ *\r
+ * @brief  Modify led current for each function\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   uchFunctionID               function offset\r
+ * @param[in]   usLedDrv0Current         0mA-200mA\r
+ * @param[in]   usLedDrv1Current         0mA-200mA\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_ModifyFunctionLedCurrent(GU8 uchFunctionID, GU16 usLedDrv0Current, GU16 usLedDrv1Current);\r
+\r
+extern const GU8 g_uchGyroEnable;\r
+\r
+//extern void GH3X2X_SetFifoPackageMode(GU8 uchMode, GU8 *puchFifoBuffer);\r
+extern void GH3X2X_SendRawdataFifoPackage(GU8 *puchGh3x2xReadFifoData, GU16 usFifoReadByteNum);\r
+//extern void GH3X2X_PackRawdataFifoPackage(GU8 *puchGh3x2xReadFifoData, GU16 usFifoReadByteNum);\r
+extern GU8 GH3X2X_GetFifoPackageMode(void);\r
+\r
+\r
+/**\r
+ * @fn      void GH3x2x_ChangeSampleParmForEngineeringMode(GU32 unFunctionMode, STGh3x2xEngineeringModeSampleParam *pstSampleParaGroup , GU8 uchSampleParaGroupNum)\r
+ \r
+ *\r
+ * @brief  \r
+ *\r
+ * @attention   None.\r
+ *\r
+ * @param[in]   unFunctionMode: function group exp: GH3X2X_FUNCTION_ADT|GH3X2X_FUNCTION_HR\r
+ * @param[in]   pstSampleParaGroup   the pointer of engineering mode sample param group struct array base\r
+ * @param[in]   uchSampleParaGroupNum   engineering mode sample param group number\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3x2x_ChangeSampleParmForEngineeringMode(const STGh3x2xFrameInfo * const  pstGh3x2xFrameInfo[], GU32 unFunctionMode, STGh3x2xEngineeringModeSampleParam *pstSampleParaGroup , GU8 uchSampleParaGroupNum);\r
+\r
+\r
+GS8 GH3X2X_FunctionStart(const STGh3x2xFrameInfo * const pstFrameInfo);\r
+GS8 GH3X2X_FunctionStop(const STGh3x2xFrameInfo * const pstFrameInfo);\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+void GH3x2xFunctionProcess(GU8 *puchRawdataBuf, GU16 usRawDataByteLen, GS16 *pusGsValueArr, GU16 usGsDataNum, \r
+                        STCapRawdata* pstCapValueArr,GU16 usCapDataNum,STTempRawdata* pstTempValueArr,GU16 usTempDataNum,\r
+                        const STGh3x2xFrameInfo * const pstFrameInfo);\r
+GU8* GH3x2xGetFunctionChnlMap(const STGh3x2xFrameInfo * const pstFrameInfo);\r
+void GH3x2xSetFunctionChnlNum(const STGh3x2xFrameInfo * const pstFrameInfo, GU8 uchChnlNum);\r
+void GH3x2xSetFunctionChnlMap(const STGh3x2xFrameInfo * const pstFrameInfo, GU8 uchChnlId, GU8 uchChnlTag);\r
+void GH3x2xCalFunctionSlotBit(const STGh3x2xFrameInfo * const pstFrameInfo);\r
+GU32 GH3X2X_GetFuncStartedBitmap(void);\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+extern const STGh3x2xFrameInfo * const g_pstGh3x2xFrameInfo[];\r
+\r
+\r
+/**\r
+ * @fn     void GH3X2X_EcgSampleHookHandle(GU8 uchEventType, GU8 uchEventInfo)\r
+ *\r
+ * @brief  ecg sample  hook handle\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   uchEventType         ecg sample event type, @ref ECG_SAMPLE_EVENT_TYPE_SAMPLE etc\r
+ * @param[in]   uchEventInfo         ecg sample event info, @ref ECG_SAMPLE_EVENT_INFO_SAMPLE_STOP etc\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_EcgSampleHookHandle(GU8 uchEventType, GU8 uchEventInfo);\r
+\r
+\r
+void GH3X2X_LeadDetEnInHardAdt(GU8 uchEn);\r
+\r
+/**\r
+ * @fn     GH3X2X_LeadDetEnControl(GU8 uchEventInfo)\r
+ *\r
+ * @brief  lead detect enable control\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   uchEventInfo         control event, only ecg start/stop evt \r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_LeadDetEnControl(GU8 uchEventInfo);\r
+/**\r
+ * @fn     void GH3X2X_SlaverSoftLeadPramSet(GU16 usRegVal, GU8 uchRegPosi)\r
+ *\r
+ * @brief  slave soft lead off param set from virtual reg\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   usRegVal          reg value\r
+ * @param[in]   uchRegPosi        reg position\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_SlaverSoftLeadPramSet(GU16 usRegVal, GU8 uchRegPosi);\r
+\r
+/**\r
+ * @fn     void GH3X2X_SlaverSoftLeadPramInit(void)\r
+ *\r
+ * @brief  slave soft lead off param init to default value\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_SlaverSoftLeadPramInit(void);\r
+\r
+/**\r
+ * @fn     void GH3X2X_FindGu16MaxMinVal(GU16 *pusMaxVal, GU16 *pusMinVal, GU16 *pusBuffer, GU8 uchLen)\r
+ *\r
+ * @brief  Find min val & max val\r
+ *\r
+ * @attention   len must > 0, ptr not null\r
+ * \r
+ * @param[in]   pusBuffer        pointer to buffer\r
+ * @param[in]   uchLen           buffer length\r
+ * @param[out]  pusMaxVal        pointer to max val\r
+ * @param[out]  pusMinVal        pointer to min val\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_FindGu16MaxMinVal(GU16 *pusMaxVal, GU16 *pusMinVal, GU16 *pusBuffer, GU8 uchLen);\r
+\r
+/**\r
+ * @fn     GU16 GH3X2X_FindGu16MaxVal(GU16 *pusBuffer, GU8 uchLen)\r
+ *\r
+ * @brief  Find max val\r
+ *\r
+ * @attention   len must > 0\r
+ * \r
+ * @param[in]   pusBuffer        pointer to buffer\r
+ * @param[in]   uchLen           buffer length\r
+ * @param[out]  None\r
+ *\r
+ * @return  max val, if len = 0, return 0\r
+ */\r
+GU16 GH3X2X_FindGu16MaxVal(GU16 *pusBuffer, GU8 uchLen);\r
+\r
+/**\r
+ * @fn     GU16 GH3X2X_FindGu16MinVal(GU16 *pusBuffer, GU8 uchLen)\r
+ *\r
+ * @brief  Find min val\r
+ *\r
+ * @attention   len must > 0\r
+ * \r
+ * @param[in]   pusBuffer        pointer to buffer\r
+ * @param[in]   uchLen           buffer length\r
+ * @param[out]  None\r
+ *\r
+ * @return  min val, if len = 0, return 0\r
+ */\r
+GU16 GH3X2X_FindGu16MinVal(GU16 *pusBuffer, GU8 uchLen);\r
+\r
+/**\r
+ * @fn     GU8 GH3x2xGetChipOperateIndexRealtime(void)\r
+ *\r
+ * @brief  get current chip operate index\r
+ *\r
+ * @attention   None\r
+ * @param[in]   None\r
+ * @param[out]  0: chip0   1: chip1\r
+ *\r
+ * @return  None\r
+ */\r
+GU8 GH3x2xGetChipOperateIndexRealtime(void);\r
+\r
+\r
+void GH3X2X_StartHardAdtAndResetGsDetect(void);\r
+void GH3X2X_StopHardAdtAndStartGsDetect(void);\r
+GU8 GH3X2X_GetSoftLeadDetMode(void);\r
+GU8 GH3X2X_GetAdtElectrodeAdtEn(void);\r
+\r
+/**\r
+ * @fn     void Gh3x2x_DemoSendProtocolData(GU8* puchProtocolDataBuffer, GU16 usProtocolDataLen)\r
+ *\r
+ * @brief  Copy protocol data to buffer that will be sent out to APP/EVK.\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   puchProtocolDataBuffer      point to protocol data\r
+ * @param[in]   usProtocolDataLen           protocol data length\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+extern void Gh3x2xDemoSendProtocolData(GU8* puchProtocolDataBuffer, GU16 usProtocolDataLen);\r
+extern GU8 GH3X2X_UprotocolPacketFormat(GU8 uchCmd, GU8 *puchPacketBuffer, GU8 *puchPayloadData, GU8 uchPayloadDataLen);\r
+\r
+extern void Gh2x2xUploadDataToMaster(const STGh3x2xFrameInfo * const pstFrameInfo, GU16 usFrameCnt, GU16 usFrameNum, GU8* puchTagArray);\r
+extern void Gh2x2xUploadZipDataToMaster(const STGh3x2xFrameInfo * const pstFrameInfo, GU16 usFrameCnt, GU16 usFrameNum, GU8* puchTagArray);\r
+\r
+extern GU16 GH3x2xGetFrameNum(GU8 *puchRawdataBuf, GU16 usRawDataByteLen, const STGh3x2xFrameInfo * const pstFrameInfo);\r
+GU8  GH3X2X_CalcArrayCrc8Val(GU8 uchDataArr[], GU16 usDataIndex, GU16 usDataLen);\r
+\r
+void Gh3x2xSetProtocolEventAck(void);\r
+GU8 Gh3x2xGetProtocolEventReportId(void);\r
+\r
+extern void Gh3x2xSetFrameFlag2(const STGh3x2xFrameInfo * const pstFrameInfo);\r
+\r
+extern GU8 Gh3x2xGetHrAlgoSupportChnl(void);\r
+extern GU8 Gh3x2xGetSpo2AlgoSupportChnl(void);\r
+\r
+extern void GH3X2X_ReadIntTime(void);\r
+extern GU8 GH3X2X_GetIntTimeInArray(GU8 uchSlotIndex);\r
+\r
+\r
+extern void Gh3x2xFunctionInfoForUserInit(void);\r
+\r
+extern void GH3x2xCalFunctionSlotBit(const STGh3x2xFrameInfo * const pstFrameInfo);\r
+\r
+extern void GH3x2xSetAgcReg(GU8 uchAgcReg,  GU8 uchSlot, GU16 usValue);\r
+\r
+extern GU16 GH3x2xGetAgcReg(GU8 uchAgcReg,  GU8 uchSlot);\r
+\r
+extern void GH3x2xSendAllVersion(void);\r
+\r
+\r
+extern void GH3X2X_SetAlgoEnableFlag(GU8 uchAlgoEnableFlag);\r
+extern GU8 GH3X2X_GetAlgoEnableFlag(void);\r
+extern GU8 GH3X2X_GetSingleChipModeEnableFlag(void);\r
+extern void GH3X2X_SetSingleChipModeEnableFlag(GU8 uchAlgoEnableFlag);\r
+\r
+extern void GH3X2X_UprotocolFpbpDataReceiveCmd(GU8 *puchRespondBuffer, GU16 *pusRespondLen);\r
+extern void GH3x2xBpAlgoInitSetting(GU8 *puchRespondBuffer);\r
+\r
+extern GS32 GH3X2X_LeadOffDetectInit(void);\r
+extern GU8 GH3X2X_LeadOffDetect(GU8* puchFifoBuffer, GU16* pusFifoBufferLen);\r
+\r
+extern GU8 GH3X2X_EcgRsHandle(GU8 *puchFifoBuffer, GU16 *pusFifoBufferLen);\r
+extern void Gh3x2xSetGh3x2xSoftWearOffDetFunctionId(GU32 unFunctionId);\r
+extern void Gh3x2xIntPinTriggerModePro(void);\r
+extern void GH3X2X_ECGResampleConfig(GU16 usEcgSampleRate);\r
+extern void GH3X2X_PPGResampleConfig(GU16 usEcgSampleRate);\r
+extern void Gh3x2xNewAgcSubChnlModuleReset(void);\r
+extern GU8 GH3x2xNewAgcSetNewSubChnl(GU8 uchSlotNo, GU8 uchRxEn, STGh3x2xAgcInfo *STGh3x2xAgcInfo);\r
+extern void GH3X2X_NewAgcSubChnlGainAdj(GU8* puchReadFifoBuffer, GU16 usFifoLen, STGh3x2xAgcInfo *STGh3x2xAgcInfo);\r
+extern void GH3x2xNewAgcSubChnlClearAnalysisCntAndSetGain(GU8 uchSlotNo, GU8 uchRxEn ,GU8 uchNextGain);\r
+extern void GH3x2xNewAgcSetSubChnlSlotInfo(GU8 uchSlotCnt, GU16 usSampleRate);\r
+extern void GH3x2xWriteCapToFlash(void);\r
+extern void GH3x2xReadCapFromFlash(void);\r
+extern void GH3X2X_MoveDetectByCapData(STCapRawdata* pusCapData, GU16 usCapDataCnt);\r
+extern void GH3x2xSlotTimeInfo(void);\r
+extern void GH3X2X_NewAgcMainChnlPro(GU8* puchReadFifoBuffer, GU16 usFifoLen, STGh3x2xAgcInfo *STGh3x2xAgcInfo);\r
+\r
+extern void GH3X2X_RegisterI2cDeviceChip1(GU8 uchI2cIdLowTwoBitsSelect);\r
+\r
+extern void GH3X2X_LoadSlaveCfgForCascadeMode(void);\r
+extern void GH3X2X_CascadeEcgSlaverLeadDectDisEx(void);\r
+extern void GH3X2X_CascadeEcgSlaverFastRecTrigEx(void);\r
+extern void GH3X2X_SoftResetSlaveChip(void);\r
+extern void GH3X2X_StartSamplingSlaveChip(void);\r
+extern void GH3X2X_StopSamplingSlaveChip(void);\r
+extern void GH3X2X_EcgCascadeSlotEnRegSet(GU8 uchSetValue);\r
+extern STGh3x2xSoftLeadOffDetInfo * const g_pstGh3x2xSoftLeadOffDetInfo;\r
+extern STGh3x2xRsInfo * const g_pstGh3x2xEcgRsInfo;\r
+extern STGh3x2xRsInfo * const g_pstGh3x2xPPGRsInfo;\r
+extern const GU8 g_uchGh3x2xEcgChnlNumLimit;\r
+extern const GU32 g_uchPPGDownSampleChnlNumLimit;\r
+\r
+extern const STGh3x2xReg stGh3x2xEcgCascadeSlaveRealReglist[];\r
+extern const GU16 g_usEcgCascadeSlaveRealRegLen;\r
+extern GS32 g_nEcgParamsArr[5];\r
+extern void Gh3x2x_CHECK_0x0088_Ex(void);\r
+extern int (*g_pPrintfUserIn)(const char *format, ...);\r
+extern int (*g_pSnprintfUserIn)(char *str, size_t size, const char *format, ...);\r
+extern void GH3X2X_ConfigLeadOffThr(GU32 uIQAmpThr, GU32 uIQAmpDiffThr,GU32 uValThr);\r
+extern void GH3x2x_GetLedCurrentFullScal(GU8 *puchDrv0Fs, GU8 *puchDrv1Fs);\r
+\r
+extern GU32 GH3X2X_GetConfigFuncMode(void);\r
+extern void GH3X2X_SetConfigFuncMode(GU32 unConfigFuncMode);\r
+extern void Gh3x2xFifoRecovery(void);\r
+extern void GH3X2X_SetDivZeroFlag(void);\r
+extern void GH3X2X_ClearDivZeroFlag(void);\r
+\r
+extern void GH3X2X_AdtPramInit(void);\r
+extern void GH3X2X_AdtPramSet(GU16 usRegVal, GU8 uchRegPosi);\r
+\r
+/**\r
+ * @fn     void GH3X2X_ClearChipSleepFlag(GU8 uchChipIndex)\r
+ *\r
+ * @brief  clear chip sleep flag\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   uchChipIndex  0: chip0  1: chip1\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+extern void GH3X2X_ClearChipSleepFlag(GU8 uchChipIndex);\r
+\r
+/**\r
+ * @fn     void GH3X2X_SetChipSleepFlag(GU8 uchChipIndex)\r
+ *\r
+ * @brief  set chip sleep flag\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   uchChipIndex  0: chip0  1: chip1\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+extern void GH3X2X_SetChipSleepFlag(GU8 uchChipIndex);\r
+\r
+\r
+\r
+extern void GhDrvConfigManagerInit(void);\r
+extern GU32 GhDrvConfigManagerGetCurFunctionSupprort(void);\r
+\r
+\r
+\r
+#endif /* _GH3X2X_DRV_H_ */\r
+\r
+/********END OF FILE********* Copyright (c) 2003 - 2022, Goodix Co., Ltd. ********/\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/driver/inc/gh_drv_common.h b/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/driver/inc/gh_drv_common.h
new file mode 100644 (file)
index 0000000..c954607
--- /dev/null
@@ -0,0 +1,463 @@
+/**\r
+ * @copyright (c) 2003 - 2022, Goodix Co., Ltd. All rights reserved.\r
+ *\r
+ * @file    gh3x2x_drv_common.h\r
+ *\r
+ * @brief   gh3x2x driver common define\r
+ *\r
+ * @version ref gh3x2x_drv_version.h\r
+ *\r
+ */\r
+\r
+#ifndef _GH3X2X_DRV_COMMON_H_\r
+#define _GH3X2X_DRV_COMMON_H_\r
+\r
+\r
+#include "gh_drv_config.h"\r
+#include "gh_drv_registers.h"\r
+#include "gh_drv.h"\r
+\r
+\r
+#if defined ( __GNUC__ ) && !defined (__CC_ARM) /* GNU Compiler */\r
+  #ifndef __packed\r
+    #define __packed __attribute__((__packed__))\r
+  #endif /* __packed */\r
+#endif /* __GNUC__ */\r
+\r
+\r
+/* extern log function */\r
+extern void GH3X2X_PlatformLog(GCHAR *chLogString);\r
+\r
+//sample log enable flag\r
+#define SAMPLE_DEBUG_ENABLE (1)\r
+#if SAMPLE_DEBUG_ENABLE\r
+//sample log open\r
+/// log support len\r
+#define GH3X2X_LOG_DEBUG_SUP_LEN     (128)\r
+//enable flag\r
+#define SAMPLE_DEBUG_ENABLE_BP  (0)\r
+#define SAMPLE_DEBUG_ENABLE_AGC (0)\r
+//log define\r
+#define   GH3X2X_INFO_LOG_PARAM(...)        do {\\r
+                                                    if(g_pSnprintfUserIn)\\r
+                                                    {\\r
+                                                        GCHAR chDebugStr[GH3X2X_LOG_DEBUG_SUP_LEN] = {0};\\r
+                                                        g_pSnprintfUserIn(chDebugStr, GH3X2X_LOG_DEBUG_SUP_LEN, \\r
+                                                                "[LOG_DRV_I]: "__VA_ARGS__);\\r
+                                                        GH3X2X_PlatformLog(chDebugStr);\\r
+                                                    }\\r
+                                                    if(g_pPrintfUserIn)g_pPrintfUserIn("[LOG_DRV_I]: "__VA_ARGS__);\\r
+                                            } while (0)\r
+\r
+//agc log\r
+#if (SAMPLE_DEBUG_ENABLE_AGC)\r
+#define   GH3X2X_INFO_LOG_PARAM_AGC(...)   { GH3X2X_INFO_LOG_PARAM(__VA_ARGS__); }\r
+#else\r
+#define   GH3X2X_INFO_LOG_PARAM_AGC(...)\r
+#endif\r
+#else\r
+//sample log close\r
+#define   GH3X2X_INFO_LOG_PARAM(...)\r
+#define   GH3X2X_INFO_LOG_PARAM_AGC(...)\r
+#endif\r
+\r
+#define DRVLIB_GOODIX_DEMO_PLANFORM_DEBUG  0\r
+#ifdef GOODIX_DEMO_PLATFORM\r
+#ifdef GH3X2X_LOG_DEBUG\r
+#undef GH3X2X_LOG_DEBUG\r
+#endif\r
+#define GH3X2X_LOG_DEBUG DRVLIB_GOODIX_DEMO_PLANFORM_DEBUG\r
+#endif\r
+\r
+\r
+/* debug log control, if enable debug, GH3X2X_PlatformLog must define in platforms code */\r
+#if defined(GH3X2X_LOG_DEBUG) && (GH3X2X_LOG_DEBUG > 0) // debug level > 0\r
+\r
+\r
+#if 1\r
+/// log string with param\r
+#define   GH3X2X_DEBUG_LOG_PARAM(...)       do {\\r
+                                                if(g_pSnprintfUserIn)\\r
+                                                {\\r
+                                                    GCHAR chDebugStr[GH3X2X_LOG_DEBUG_SUP_LEN] = {0};\\r
+                                                    g_pSnprintfUserIn(chDebugStr, GH3X2X_LOG_DEBUG_SUP_LEN, \\r
+                                                            "[LOG_DRV_D]: "__VA_ARGS__);\\r
+                                                    GH3X2X_PlatformLog(chDebugStr);\\r
+                                                }\\r
+                                                if(g_pPrintfUserIn)g_pPrintfUserIn("[LOG_DRV_D]: "__VA_ARGS__);\\r
+                                            } while (0)\r
+\r
+#else\r
+#define   GH3X2X_DEBUG_LOG_PARAM(...)\r
+#endif\r
+\r
+\r
+\r
+\r
+\r
+#if (GH3X2X_LOG_DEBUG > 1) // debug level > 1\r
+\r
+/// internal log\r
+#define   GH3X2X_DEBUG_LOG_INTERNAL(...)        { GH3X2X_DEBUG_LOG_PARAM(__VA_ARGS__); }\r
+\r
+#else\r
+\r
+/// internal log\r
+#define   GH3X2X_DEBUG_LOG_INTERNAL(...)\r
+\r
+#endif\r
+\r
+#else   // debug level <= 0\r
+\r
+/// log string with param\r
+#define   GH3X2X_DEBUG_LOG_PARAM(...)\r
+\r
+/// internal log\r
+#define   GH3X2X_DEBUG_LOG_INTERNAL(...)\r
+\r
+#endif\r
+\r
+/// fifo rawdata bytes max len\r
+#define   GH3X2X_FIFO_DATA_BYTES_MAX_LEN    (3200)    // GH3X2X_FIFO_CNT_CALC(800)\r
+\r
+/// fifo rawdata size\r
+#define   GH3X2X_FIFO_RAWDATA_SIZE          (4)\r
+\r
+/// fifo rawdataindex size\r
+#define   GH3X2X_FIFO_RAWDATAINDEX_SIZE     (2)\r
+\r
+/// fifo gsensordata size\r
+#define   GH3X2X_FIFO_GSENSORDATA_SIZE      (6)\r
+\r
+/// fifo agcdata size\r
+#define   GH3X2X_FIFO_AGCDATA_SIZE          (4)\r
+\r
+/// fifo cnt calc\r
+#define   GH3X2X_FIFO_CNT_CALC(x)           ((x) * GH3X2X_FIFO_RAWDATA_SIZE)\r
+\r
+/// g sensor data size\r
+#define   GH3X2X_GSENSOR_DATA_SIZE          (6)\r
+\r
+/// agc data size\r
+#define   GH3X2X_AGC_DATA_SIZE              (4)\r
+\r
+/// agc data cnt calc\r
+#define   GH3X2X_AGC_CNT_CALC(x)           ((x) * GH3X2X_AGC_DATA_SIZE)\r
+\r
+/// algorithm result size\r
+#define   GH3X2X_ALGO_RESULT_SIZE           (4)\r
+\r
+/// algorithm result calc\r
+#define   GH3X2X_ALGO_RESULT_CALC(x)           ((x) * GH3X2X_ALGO_RESULT_SIZE)\r
+\r
+/// algorithm result with tag calc.\r
+#define   GH3X2X_ALGO_RESULT_WITH_TAG_CALC(x)           ((x) * (GH3X2X_ALGO_RESULT_SIZE + 1))\r
+\r
+/* rawdata macro */\r
+\r
+/// rawdata clear slot & adc num\r
+#define   GH3X2X_RAWDATA_CLEAR_SLOT_ADC_NUM(x)          ((x) & 0x07FFFFFF)\r
+\r
+/// rawdata get slot num from dword\r
+#define   GH3X2X_DWORD_RAWDATA_GET_SLOT_NUM(x)          (((x) & 0xE0000000) >> 29)\r
+\r
+/// rawdata get adc num from dword\r
+#define   GH3X2X_DWORD_RAWDATA_GET_ADC_NUM(x)           (((x) & 0x18000000) >> 27)\r
+\r
+/// rawdata get slot&adc num from dword\r
+#define   GH3X2X_DWORD_RAWDATA_GET_SLOT_ADC_NUM(x)      (((x) & 0xF8000000) >> 27)\r
+\r
+/// rawdata get slot num from byte\r
+#define   GH3X2X_BYTE_RAWDATA_GET_SLOT_NUM(x)           (((x) & 0xE0) >> 5)\r
+\r
+/// rawdata get adc num from byte\r
+#define   GH3X2X_BYTE_RAWDATA_GET_ADC_NUM(x)            (((x) & 0x18) >> 3)\r
+\r
+/// slot & adc num bits of rawdata byte\r
+#define   GH3X2X_SLOT_ADC_NUM_BITS                      (0xF8)\r
+\r
+/// rawdata get slot adc num from byte\r
+#define   GH3X2X_BYTE_RAWDATA_GET_SLOT_ADC_NUM(x)       (((x) & GH3X2X_SLOT_ADC_NUM_BITS) >> 3)\r
+\r
+/// get slot index from channel num\r
+#define   GH3X2X_GET_SLOT_FROM_CHANNEL_NUM(x)           (((x) & 0x1F) >> 2)\r
+\r
+/// get adc index from channel num\r
+#define   GH3X2X_GET_ADC_FROM_CHANNEL_NUM(x)            ((x) & 0x3)\r
+\r
+/// rawdata clear all flag\r
+#define   GH3X2X_RAWDATA_CLEAR_ALL_FLAG(x)              ((x) & 0x00FFFFFF)\r
+\r
+/// rawdata clear data\r
+#define   GH3X2X_RAWDATA_CLEAR_DATA(x)                  ((x) & 0xFF000000)\r
+\r
+/// rawdata get adj flag0\r
+#define   GH3X2X_RAWDATA_GET_ADJ_FLAG0(x)               (((x) & 0x4000000) >> 26)\r
+\r
+/// rawdata get adj flag1\r
+#define   GH3X2X_RAWDATA_GET_ADJ_FLAG1(x)               (((x) & 0x2000000) >> 25)\r
+\r
+/// get rawdata for algorithm\r
+#define   GH3X2X_GET_RAWDATA_FOR_ALGO(x)                ((x) >> 7)\r
+\r
+/// rawdata get fast recovery flag\r
+#define   GH3X2X_RAWDATA_GET_FAST_RECOVERY_FLAG(x)      (((x) & 0x4000000) >> 26)\r
+\r
+/// rawdata real offset\r
+#define   GH3X2X_RAWDATA_REAL_OFFSET                    (0x00800000)\r
+\r
+\r
+/* algorithm config */\r
+\r
+/// ecg algorithm default sampling frequency\r
+#define   GH3X2X_ALGORITHM_ADT_DEFAULT_FS                       (5)\r
+\r
+/// ram for algorithms bytes align\r
+#define   GH3X2X_ALGORITHMS_MEMORY_ALIGN                        (4)\r
+\r
+/// ram for algorithms bytes to align size\r
+#define   GH3X2X_ALGORITHMS_MEMORY_BYTES_2_ALGIN_SIZE(x)        ((x) / GH3X2X_ALGORITHMS_MEMORY_ALIGN)\r
+\r
+/// hba algorithm support\r
+#define   GH3X2X_ALGORITHM_HBA_SUPPORT                          (1)\r
+\r
+/// hba algorithm default sampling frequency\r
+#define   GH3X2X_ALGORITHM_HBA_DEFAULT_FS                       (25)\r
+\r
+/// hrv algorithm support\r
+#define   GH3X2X_ALGORITHM_HRV_SUPPORT                          (0)\r
+\r
+/// hrv algorithm default sampling frequency\r
+#define   GH3X2X_ALGORITHM_HRV_DEFAULT_FS                       (100)\r
+\r
+/// spo2 algorithm support\r
+#define   GH3X2X_ALGORITHM_SPO2_SUPPORT                         (1)\r
+\r
+/// spo2 algorithm default sampling frequency\r
+#define   GH3X2X_ALGORITHM_SPO2_DEFAULT_FS                      (100)\r
+\r
+/// ecg algorithm support\r
+#define   GH3X2X_ALGORITHM_ECG_SUPPORT                          (1)\r
+\r
+\r
+/// ecg algorithm default sampling frequency\r
+#define   GH3X2X_ALGORITHM_ECG_DEFAULT_FS                       (500)\r
+\r
+/// hsm algorithm support\r
+#define   GH3X2X_ALGORITHM_HSM_SUPPORT                          (0)\r
+/// bt algorithm support\r
+#define   GH3X2X_ALGORITHM_BT_SUPPORT                           (0)\r
+/// resp algorithm support\r
+#define   GH3X2X_ALGORITHM_RESP_SUPPORT                         (0)\r
+/// af algorithm support\r
+#define   GH3X2X_ALGORITHM_AF_SUPPORT                           (0)\r
+/// nadt algorithm support\r
+#define   GH3X2X_ALGORITHM_NADT_SUPPORT                         (1)\r
+/// fpbp algorithm support\r
+#define   GH3X2X_ALGORITHM_BP_SUPPORT                           (0)\r
+\r
+\r
+/* utils macro */\r
+\r
+/// byte true flag val\r
+#define   GH3X2X_BYTE_FLAG_TRUE                     (1)\r
+\r
+/// byte false flag val\r
+#define   GH3X2X_BYTE_FLAG_FALSE                    (0)\r
+\r
+/// GF32 0 val\r
+#define   GH3X2X_GF32_0                             (0.0f)\r
+\r
+/// null val\r
+//#define   GH3X2X_PTR_NULL                           ((void *) 0)\r
+\r
+/// get high 4bits from byte\r
+#define   GH3X2X_GET_HIGH_4BITS(val)                ((val) & 0xF0)\r
+\r
+/// get low 4bits from byte\r
+#define   GH3X2X_GET_LOW_4BITS(val)                 ((val) & 0x0F)\r
+\r
+/// get first 4bits from byte\r
+#define   GH3X2X_GET_FIRST_4BITS(val)               ((val) & 0x0000000FU)\r
+\r
+/// get high byte from word\r
+#define   GH3X2X_GET_HIGH_BYTE_FROM_WORD(sValue)    ((GU8)(((sValue) >> 8) & 0xFFU))\r
+\r
+/// get low byte from word\r
+#define   GH3X2X_GET_LOW_BYTE_FROM_WORD(sValue)     ((GU8)((sValue) & 0xFFU))\r
+\r
+/// get byte3 from dword\r
+#define   GH3X2X_GET_BYTE3_FROM_DWORD(unValue)      ((GU8)(((unValue) >> 24) & 0x000000FFU))\r
+\r
+/// get byte2 from dword\r
+#define   GH3X2X_GET_BYTE2_FROM_DWORD(unValue)      ((GU8)(((unValue) >> 16) & 0x000000FFU))\r
+\r
+/// get byte1 from dword\r
+#define   GH3X2X_GET_BYTE1_FROM_DWORD(unValue)      ((GU8)(((unValue) >> 8) & 0x000000FFU))\r
+\r
+/// get byte0 from dword\r
+#define   GH3X2X_GET_BYTE0_FROM_DWORD(unValue)      ((GU8)((unValue) & 0x000000FFU))\r
+\r
+/// get high word from dword\r
+#define   GH3X2X_GET_HIGH_WORD_FROM_DWORD(unValue)      ((GU16)(((unValue) >> 16) & 0x0000FFFFU))\r
+\r
+/// get low word from dword\r
+#define   GH3X2X_GET_LOW_WORD_FROM_DWORD(unValue)       ((GU16)((unValue) & 0x0000FFFFU))    \r
+\r
+/// makeup word from bytes\r
+#define   GH3X2X_MAKEUP_WORD(uchHighByte, uchLowByte)              ((GU16)(((((GU16)(uchHighByte)) << 8)& 0xFF00) |\\r
+                                                                            (((GU16)(uchLowByte))& 0x00FF)))\r
+\r
+/// makeup dword from bytes\r
+#define   GH3X2X_MAKEUP_DWORD(uchByte3, uchByte2, uchByte1, uchByte0)     (((((GU32)(uchByte3)) << 24) & 0xFF000000U)|\\r
+                                                                          ((((GU32)(uchByte2)) << 16) & 0x00FF0000U) |\\r
+                                                                          ((((GU32)(uchByte1)) << 8) & 0x0000FF00U) |\\r
+                                                                          (((GU32)(uchByte0)) & 0x000000FFU))\r
+\r
+/// makeup dword from words\r
+#define   GH3X2X_MAKEUP_DWORD2(usHighWord, usLowWord)                  (((((GU32)(usHighWord)) << 16) & 0xFFFF0000U) |\\r
+                                                                            (((GU32)(usLowWord)) & 0x0000FFFFU))\r
+\r
+/// macro of hook function call\r
+/* NOLINTNEXTLINE(501) */\r
+#define   HOOK_FUNC_CALL(func, argv)        do { if ((func) != GH3X2X_PTR_NULL) { func argv; } } while (0)\r
+\r
+/// macro of handle function call\r
+/* NOLINTNEXTLINE(501) */\r
+#define   HANDLE_FUNC_CALL(func, argv)      do { if ((func) != GH3X2X_PTR_NULL) { func argv; } } while (0)\r
+\r
+/// macro of set val via ptr\r
+#define   SET_VAL_VIA_PTR(ptr, val)     do { if ((ptr) != GH3X2X_PTR_NULL) { (*(ptr)) = (val); } } while (0)\r
+\r
+/**\r
+ * @brief macro of read pin status, e.g. READ_PIN_STATUS_CALL(g_pGh3x2xReadIntPinStatus, uchPinStatus)\r
+ *        func() should retrun 0(low level) or 1(high), if not register func, return 0xFF(invalid)\r
+ */\r
+#define   READ_PIN_STATUS_CALL(func, status)    do {\\r
+                                                    if ((func) != GH3X2X_PTR_NULL)\\r
+                                                    {\\r
+                                                        (status) = (func)();\\r
+                                                    }\\r
+                                                    else\\r
+                                                    {\\r
+                                                        (status) = 0xFF;\\r
+                                                    }\\r
+                                                } while (0)\r
+\r
+\r
+/* bit operation macro */\r
+\r
+/// macro of set bits\r
+#define   GH3X2X_SET_BIT(x, b)              ((x) | (b))\r
+\r
+/// macro of val set bits\r
+#define   GH3X2X_VAL_SET_BIT(x, b)          ((x) |= (b))\r
+\r
+/// macro of clear bits\r
+#define   GH3X2X_CLEAR_BIT(x, b)            ((x) & (~(b)))\r
+\r
+/// macro of val clear bits\r
+#define   GH3X2X_VAL_CLEAR_BIT(x, b)        ((x) &= (~(b)))\r
+\r
+/// macro of val get bits\r
+#define   GH3X2X_VAL_GET_BIT(x, b)          ((x) &= (b))\r
+\r
+/// macro of check bits set\r
+#define   GH3X2X_CHECK_BIT_SET(x, b)        (((x) & (b)) == (b))\r
+\r
+/// macro of check bits not set\r
+#define   GH3X2X_CHECK_BIT_NOT_SET(x, b)    (((x) & (b)) != (b))\r
+\r
+/// macro of check bits is set\r
+#define   GH3X2X_CHECK_BIT_IS_SET(x, b)     (((x) & (b)) == (b))\r
+\r
+/// macro of get bits is set\r
+#define   GH3X2X_GET_BIT_IS_SET(x)          ((x) & 0xf000)\r
+\r
+/// macro of bit number in one byte\r
+#define   GH3X2X_BIT_PER_BYTE    (4)\r
+\r
+/// macro of bit in reg addr for check\r
+#define   GH3X2X_REG_MODE_BIT    (3)\r
+\r
+/// macro of check bits zero\r
+#define   GH3X2X_CHECK_REG_MODE_BIT_ZERO(x)    (((x) >> (GH3X2X_BIT_PER_BYTE * GH3X2X_REG_MODE_BIT)) == (0))\r
+\r
+/// macro of check lsb set\r
+#define   GH3X2X_CHECK_LSB_SET(x)           (GH3X2X_CHECK_BIT_SET((x), 0x01))\r
+\r
+/// macro of check left shift bit set\r
+#define   GH3X2X_CHECK_LEFT_BIT_SET(x, l)           (GH3X2X_CHECK_BIT_SET((x), (1u << (l))))\r
+\r
+/// macro of check left shift bit not set\r
+#define   GH3X2X_CHECK_LEFT_BIT_NOT_SET(x, l)       (GH3X2X_CHECK_BIT_NOT_SET((x), (1u << (l))))\r
+\r
+/// macro of val clear left shift bit\r
+#define   GH3X2X_VAL_CLEAR_LEFT_BIT(x, l)                ((x) &= (~((1u << (l)))))\r
+\r
+/// check ret error\r
+#define   GH3X2X_RET_ERROR_CHECK(x)             do { \\r
+                                                    if ((x) != GH3X2X_RET_OK)\\r
+                                                    {\\r
+                                                        GH3X2X_DEBUG_LOG_PARAM("[%s]:error code = 0x%x\r\n", __FUNCTION__, x);\\r
+                                                        return (x);\\r
+                                                    }\\r
+                                                } while (0)\r
+\r
+/// check ret the error\r
+#define   GH3X2X_RET_ERROR_CHECK_E(x, e)        do { \\r
+                                                    if ((x) == (e))\\r
+                                                    {\\r
+                                                        return (x);\\r
+                                                    }\\r
+                                                } while (0)\r
+\r
+/// check ret the error\r
+#define   GH3X2X_RET_ERROR_CHECK_ER(x, e, r)    do { \\r
+                                                    if ((x) == (e))\\r
+                                                    {\\r
+                                                        return (r);\\r
+                                                    }\\r
+                                                } while (0)\r
+\r
+/// val rigth shfit\r
+#define   GH3X2X_SET_VAL_RIGTH_SHIFT(x, r)      ((x) >>= (r))\r
+\r
+/// val rigth shfit 1bit\r
+#define   GH3X2X_SET_VAL_RIGTH_SHIFT_1BIT(x)    (GH3X2X_SET_VAL_RIGTH_SHIFT((x), 1u))\r
+\r
+/// val left shfit\r
+#define   GH3X2X_SET_VAL_LEFT_SHIFT(x, l)       ((x) <<= (l))\r
+\r
+/// val left shfit 1bit\r
+#define   GH3X2X_SET_VAL_LEFT_SHIFT_1BIT(x)     (GH3X2X_SET_VAL_LEFT_SHIFT((x), 1u))\r
+\r
+/// get left shfit val\r
+#define   GH3X2X_GET_LEFT_SHIFT_VAL(l)          (1u << (l))\r
+\r
+/// val left shfit\r
+#define   GH3X2X_VAL_LEFT_SHIFT(x, l)           ((x) << (l))\r
+\r
+/// val cal diff value\r
+#define   GH3X2X_VAL_DIFF_VALUE(a, b)           ((a) > (b) ? ((a) - (b)) : ((b) - (a)))\r
+\r
+/// val cal diff status\r
+#define   GH3X2X_VAL_DIFF_STA(a, b)             ((a) > (b) ? (0) : (1))\r
+\r
+/// val cal diff ABS\r
+#define   GH3X2X_VAL_ABS(x)                     ((x) >= 0 ? (x) : - (x))\r
+\r
+/// val zip rawdata send cmd EVEN or ODD\r
+#define   GH3X2X_VAL_ZIPSENDCMD(x)              ((x) == 1 ? (GH3X2X_UPROTOCOL_CMD_ZIPEVENRAWDATA) \\r
+                                                 : (GH3X2X_UPROTOCOL_CMD_ZIPODDRAWDATA))\r
+\r
+\r
+extern const STGh3x2xModuleFunList g_Gh3x2xModuleFunList;\r
+\r
+\r
+\r
+\r
+\r
+#endif /* _GH3X2X_DRV_COMMON_H_ */\r
+\r
+/********END OF FILE********* Copyright (c) 2003 - 2022, Goodix Co., Ltd. ********/\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/driver/inc/gh_drv_config.h b/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/driver/inc/gh_drv_config.h
new file mode 100644 (file)
index 0000000..b16757f
--- /dev/null
@@ -0,0 +1,668 @@
+/**\r
+ * @copyright (c) 2003 - 2022, Goodix Co., Ltd. All rights reserved.\r
+ *\r
+ * @file    gh3x2x_drv_config.h\r
+ *\r
+ * @brief   gh3x2x driver configurations\r
+ *\r
+ * @version ref gh3x2x_drv_version.h\r
+ *\r
+ */\r
+\r
+#ifndef _GH3X2X_DRV_CONFIG_H_\r
+#define _GH3X2X_DRV_CONFIG_H_\r
+#include "gh_drv.h"\r
+\r
+/* started bitmap */\r
+\r
+#define  GH3X2X_STARTED_BITMAP_ALL_OFF              (0x0000)    /**< fnction started bitmap, all off bit */\r
+#define  GH3X2X_STARTED_BITMAP_HBA                  (0x0001)    /**< fnction started bitmap, hba bit */\r
+#define  GH3X2X_STARTED_BITMAP_SPO2                 (0x0002)    /**< fnction started bitmap, spo2 bit */\r
+#define  GH3X2X_STARTED_BITMAP_ECG                  (0x0004)    /**< fnction started bitmap, ecg bit */\r
+#define  GH3X2X_STARTED_BITMAP_ADT                  (0x0008)    /**< fnction started bitmap, adt bit */\r
+#define  GH3X2X_STARTED_BITMAP_HRV                  (0x0010)    /**< fnction started bitmap, hrv bit */\r
+#define  GH3X2X_STARTED_BITMAP_CUSTOMIZE            (0x0080)    /**< fnction started bitmap, customize bit */\r
+\r
+\r
+#define  GH3X2X_REG_IS_VIRTUAL0X0_BIT               (0x0000)\r
+#define  GH3X2X_REG_IS_VIRTUAL0X1_BIT               (0x1000)\r
+#define  GH3X2X_REG_IS_VIRTUAL0X2_BIT               (0x2000)\r
+#define  GH3X2X_REG_IS_VIRTUAL0X3_BIT               (0x3000)\r
+#define  GH3X2X_REG_IS_VIRTUAL0X4_BIT               (0x4000)\r
+#define  GH3X2X_REG_IS_VIRTUAL0X5_BIT               (0x5000)\r
+#define  GH3X2X_REG_IS_VIRTUAL0X6_BIT               (0x6000)\r
+#define  GH3X2X_REG_IS_VIRTUAL0X7_BIT               (0x7000)\r
+#define  GH3X2X_REG_IS_VIRTUAL0X8_BIT               (0x8000)\r
+#define  GH3X2X_REG_IS_VIRTUAL0X9_BIT               (0x9000)\r
+#define  GH3X2X_REG_IS_VIRTUAL0XA_BIT               (0xA000)\r
+#define  GH3X2X_REG_IS_VIRTUAL0XB_BIT               (0xB000)\r
+#define  GH3X2X_REG_IS_VIRTUAL0XC_BIT               (0xC000)\r
+#define  GH3X2X_REG_IS_VIRTUAL0XE_BIT               (0xE000)\r
+#define  GH3X2X_REG_IS_VIRTUAL0XF_BIT               (0xF000)\r
+\r
+\r
+//vitual addr version\r
+#define GH3X2X_VIRTUAL_REG_VERSION_STRING "Gh3x2x_Virtual_Reg_v3.4"\r
+//top\r
+#define GH3X2X_TOP_INFO_ADDR 0x1000\r
+#define GH3X2X_TOP_INFO_ADDR_END  (0x10E0 - 1)\r
+\r
+#define GH3X2X_SLOT_LEDDRV_ADDR 0x10E0\r
+#define GH3X2X_SLOT_LEDDRV_ADDR_END (0x1100 - 1)\r
+\r
+#define GH3X2X_DUMP_CFG_ADDR 0x1100\r
+#define GH3X2X_DUMP_CFG_ADDR_END (0x1120 - 1)\r
+\r
+#define GH3X2X_FIFO_CTRL_ADDR 0x1120\r
+#define GH3X2X_FIFO_CTRL_ADDR_END (0x1140 - 1)\r
+\r
+#define GH3X2X_G_SENSOR_CFG_ADDR 0x1140\r
+#define GH3X2X_G_SENSOR_CFG_ADDR_END (0x1160 -1)\r
+\r
+#define GH3X2X_SOFT_AGC_PARA_ADDR 0x1160\r
+#define GH3X2X_SOFT_AGC_PARA_ADDR_END       (0x1180 - 1)\r
+\r
+#define GH3X2X_CAP_CFG_ADDR       0x1180\r
+#define GH3X2X_CAP_CFG_ADDR_END      (0x11A0 - 1)\r
+\r
+#define GH3X2X_TEMP_CFG_ADDR      0x11A0\r
+#define GH3X2X_TEMP_CFG_ADDR_END  (0x2000 - 1)\r
+\r
+\r
+#define GH3X2X_CHNL_MAP_ADDR 0x2000\r
+#define GH3X2X_CHNL_MAP_ADDR_END (0x2880 - 1)\r
+\r
+#define GH3X2X_FS_PARA_ADDR 0x2880\r
+#define GH3X2X_FS_PARA_ADDR_END (0x3000 - 1)\r
+\r
+#define GH3X2X_ADT_DRV_CFG_ADDR 0x3000\r
+#define GH3X2X_ADT_ALG_CFG_ADDR 0x30C0\r
+#define GH3X2X_HR_DRV_CFG_ADDR 0x3300\r
+#define GH3X2X_HR_ALG_CFG_ADDR 0x33C0\r
+#define GH3X2X_HRV_DRV_CFG_ADDR 0x3600\r
+#define GH3X2X_HRV_ALG_CFG_ADDR 0x36C0\r
+#define GH3X2X_HSM_DRV_CFG_ADDR 0x3900\r
+#define GH3X2X_HSM_ALG_CFG_ADDR 0x39C0\r
+#define GH3X2X_FPBP_DRV_CFG_ADDR 0x3C00\r
+#define GH3X2X_FPBP_ALG_CFG_ADDR 0x3CC0\r
+#define GH3X2X_PWA_DRV_CFG_ADDR 0x3F00\r
+#define GH3X2X_PWA_ALG_CFG_ADDR 0x3FC0\r
+#define GH3X2X_SPO2_DRV_CFG_ADDR 0x4200\r
+#define GH3X2X_SPO2_ALG_CFG_ADDR 0x42C0\r
+#define GH3X2X_ECG_DRV_CFG_ADDR 0x4500\r
+#define GH3X2X_ECG_ALG_CFG_ADDR 0x45C0\r
+#define GH3X2X_PWTT_DRV_CFG_ADDR 0x4800\r
+#define GH3X2X_PWTT_ALG_CFG_ADDR 0x48C0\r
+#define GH3X2X_SOFTADTGREEN_DRV_CFG_ADDR 0x4B00\r
+#define GH3X2X_SOFTADTGREEN_ALG_CFG_ADDR 0x4BC0\r
+#define GH3X2X_BT_DRV_CFG_ADDR 0x4E00\r
+#define GH3X2X_BT_ALG_CFG_ADDR 0x4EC0\r
+#define GH3X2X_RESP_DRV_CFG_ADDR 0x5100\r
+#define GH3X2X_RESP_ALG_CFG_ADDR 0x51C0\r
+#define GH3X2X_AF_DRV_CFG_ADDR 0x5400\r
+#define GH3X2X_AF_ALG_CFG_ADDR 0x54C0\r
+#define GH3X2X_TEST1_DRV_CFG_ADDR 0x5700\r
+#define GH3X2X_TEST1_ALG_CFG_ADDR 0x57C0\r
+#define GH3X2X_TEST2_DRV_CFG_ADDR 0x5A00\r
+#define GH3X2X_TEST2_ALG_CFG_ADDR 0x5AC0\r
+#define GH3X2X_SOFTADTIR_DRV_CFG_ADDR 0x5D00\r
+#define GH3X2X_SOFTADTIR_ALG_CFG_ADDR 0x5DC0\r
+#define GH3X2X_FINISH_FLAG_ADDR 0xFF00\r
+//top_info\r
+#define GH3X2X_TOP_INFO_OFFSET 0x00DF\r
+#define GH3X2X_CFG_VER_ADDR 0x1000\r
+#define GH3X2X_CFG_TOOL_VER_ADDR 0x1002\r
+#define GH3X2X_PROJECT_ID_ADDR 0x1004\r
+#define GH3X2X_TIMESTAMP_L_ADDR 0x1006\r
+#define GH3X2X_TIMESTAMP_H_ADDR 0x1008\r
+#define GH3X2X_REINIT_PARAM_ADDR 0x100A\r
+//slot_leddrv\r
+#define GH3X2X_SLOT_LEDDRV_OFFSET 0x001F\r
+#define GH3X2X_SLOT0_1_LEDDRV_ADDR 0x10E0\r
+#define GH3X2X_SLOT2_3_LEDDRV_ADDR 0x10E2\r
+#define GH3X2X_SLOT4_5_LEDDRV_ADDR 0x10E4\r
+#define GH3X2X_SLOT6_7_LEDDRV_ADDR 0x10E6\r
+//dump_cfg\r
+#define GH3X2X_DUMP_CFG_OFFSET 0x001F\r
+#define GH3X2X_PPG_DUMP_MODE_ADDR 0x1100\r
+#define GH3X2X_BG_LEVEL_SET_ADDR 0x1102\r
+//fifo_ctrl\r
+#define GH3X2X_FIFO_CTRL_OFFSET 0x001F\r
+#define GH3X2X_NORMAL_FIFO_WATER_LINE_ADDR 0x1120\r
+#define GH3X2X_ADT_FIFO_WATER_LINE_ADDR 0x1122\r
+#define GH3X2X_FIFO_PACKAGE_SEND_MODE_ADDR 0x1124\r
+//g_sensor_cfg\r
+#define GH3X2X_G_SENSOR_CFG_OFFSET 0x001F\r
+#define GH3X2X_GSENSOR_VENDOR_ID_ADDR 0x1140\r
+#define GH3X2X_GSENSOR_SAMPLE_RATE_ADDR 0x1142\r
+#define GH3X2X_GSENSOR_CTRL_ADDR 0x1144\r
+//soft_agc_para\r
+#define GH3X2X_SOFT_AGC_PARA_OFFSET 0x001F\r
+#define GH3X2X_AGC_BG_CANCEL_ADJUST_SLOT_EN_ADDR 0x1160\r
+#define GH3X2X_AGC_AMB_SLOT_CTRL_ADDR 0x1162\r
+#define GH3X2X_AGC_CONFIG_RES 0x1164\r
+#define GH3X2X_AGC_GAIN_LIMIT_ADDR 0x1166\r
+#define GH3X2X_AGC_TRIG_THD_H_LSB_16_ADDR 0x1168\r
+#define GH3X2X_AGC_TRIG_THD_H_MSB_16_ADDR 0x116A\r
+#define GH3X2X_AGC_TRIG_THD_L_LSB_16_ADDR 0x116C\r
+#define GH3X2X_AGC_TRIG_THD_L_MSB_16_ADDR 0x116E\r
+#define GH3X2X_AGC_RESTRAIN_THD_H_LSB_16_ADDR 0x1170\r
+#define GH3X2X_AGC_RESTRAIN_THD_H_MSB_16_ADDR 0x1172\r
+#define GH3X2X_AGC_RESTRAIN_THD_L_LSB_16_ADDR 0x1174\r
+#define GH3X2X_AGC_RESTRAIN_THD_L_MSB_16_ADDR 0x1176\r
+//cap_cfg\r
+#define GH3X2X_CAP_CFG_OFFSET 0x001F\r
+#define GH3X2X_CAP_CTRL_ADDR  0x1180\r
+//Temp_cfg\r
+#define GH3X2X_TEMP_CFG_OFFSET 0x001F\r
+#define GH3X2X_TEMP_CTRL_ADDR  0x11A0\r
+\r
+\r
+//chnl_map\r
+#define GH3X2X_CHNL_MAP_OFFSET 0x087F\r
+#define GH3X2X_ADT_CHMAP_CNT_ADDR 0x2000\r
+#define GH3X2X_ADT_CHMAP_CH0_1_ADDR 0x2002\r
+#define GH3X2X_HR_CHMAP_CNT_ADDR 0x2022\r
+#define GH3X2X_HR_CHMAP_CH0_1_ADDR 0x2024\r
+#define GH3X2X_HRV_CHMAP_CNT_ADDR 0x2044\r
+#define GH3X2X_HRV_CHMAP_CH0_1_ADDR 0x2046\r
+#define GH3X2X_HSM_CHMAP_CNT_ADDR 0x2066\r
+#define GH3X2X_HSM_CHMAP_CH0_1_ADDR 0x2068\r
+#define GH3X2X_FPBP_CHMAP_CNT_ADDR 0x2088\r
+#define GH3X2X_FPBP_CHMAP_CH0_1_ADDR 0x208A\r
+#define GH3X2X_PWA_CHMAP_CNT_ADDR 0x20AA\r
+#define GH3X2X_PWA_CHMAP_CH0_1_ADDR 0x20AC\r
+#define GH3X2X_SPO2_CHMAP_CNT_ADDR 0x20CC\r
+#define GH3X2X_SPO2_CHMAP_CH0_1_ADDR 0x20CE\r
+#define GH3X2X_ECG_CHMAP_CNT_ADDR 0x20EE\r
+#define GH3X2X_ECG_CHMAP_CH0_1_ADDR 0x20F0\r
+#define GH3X2X_PWTT_CHMAP_CNT_ADDR 0x2110\r
+#define GH3X2X_PWTT_CHMAP_CH0_1_ADDR 0x2112\r
+#define GH3X2X_SOFT_ADT_GREEN_CHMAP_CNT_ADDR 0x2132\r
+#define GH3X2X_SOFT_ADT_GREEN_CHMAP_CH0_1_ADDR 0x2134\r
+#define GH3X2X_BT_CHMAP_CNT_ADDR 0x2154\r
+#define GH3X2X_BT_CHMAP_CH0_1_ADDR 0x2156\r
+#define GH3X2X_RESP_CHMAP_CNT_ADDR 0x2176\r
+#define GH3X2X_RESP_CHMAP_CH0_1_ADDR 0x2178\r
+#define GH3X2X_AF_CHMAP_CNT_ADDR 0x2198\r
+#define GH3X2X_AF_CHMAP_CH0_1_ADDR 0x219A\r
+#define GH3X2X_TEST1_CHMAP_CNT_ADDR 0x21BA\r
+#define GH3X2X_TEST1_CHMAP_CH0_1_ADDR 0x21BC\r
+#define GH3X2X_TEST2_CHMAP_CNT_ADDR 0x21DC\r
+#define GH3X2X_TEST2_CHMAP_CH0_1_ADDR 0x21DE\r
+#define GH3X2X_SOFT_ADT_IR_CHMAP_CNT_ADDR 0x21FE\r
+#define GH3X2X_SOFT_ADT_IR_CHMAP_CH0_1_ADDR 0x2200\r
+//fs_para\r
+#define GH3X2X_FS_PARA_OFFSET 0x007F\r
+#define GH3X2X_ADT_FS_ADDR 0x2880\r
+#define GH3X2X_HR_FS_ADDR 0x2882\r
+#define GH3X2X_HRV_FS_ADDR 0x2884\r
+#define GH3X2X_HSM_FS_ADDR 0x2886\r
+#define GH3X2X_FPBP_FS_ADDR 0x2888\r
+#define GH3X2X_PWA_FS_ADDR 0x288A\r
+#define GH3X2X_SPO2_FS_ADDR 0x288C\r
+#define GH3X2X_ECG_FS_ADDR 0x288E\r
+#define GH3X2X_PWTT_FS_ADDR 0x2890\r
+#define GH3X2X_SOFT_ADT_GREEN_FS_ADDR 0x2892\r
+#define GH3X2X_BT_FS_ADDR 0x2894\r
+#define GH3X2X_RESP_FS_ADDR 0x2896\r
+#define GH3X2X_AF_FS_ADDR 0x2898\r
+#define GH3X2X_TEST1_FS_ADDR 0x289A\r
+#define GH3X2X_TEST2_FS_ADDR 0x289C\r
+#define GH3X2X_SOFT_ADT_IR_FS_ADDR 0x289E\r
+//adt_drv_cfg\r
+#define GH3X2X_ADT_DRV_CFG_OFFSET 0x00C7\r
+#define GH3X2X_ADT_CONFIG0_ADDR 0x3000\r
+#define GH3X2X_ADT_CONFIG1_ADDR 0x3002\r
+//adt_alg_cfg\r
+#define GH3X2X_ADT_ALG_CFG_OFFSET 0x023F\r
+//hr_drv_cfg\r
+#define GH3X2X_HR_DRV_CFG_OFFSET 0x00C7\r
+//hr_alg_cfg\r
+#define GH3X2X_HR_ALG_CFG_OFFSET 0x023F\r
+#define GH3X2X_HR_SCENARIO_CFG_L_ADDR 0x33C0\r
+#define GH3X2X_HR_SCENARIO_CFG_H_ADDR 0x33C2\r
+#define GH3X2X_HR_OUTPUT_TIME_L_ADDR 0x33C4\r
+#define GH3X2X_HR_OUTPUT_TIME_H_ADDR 0x33C6\r
+#define GH3X2X_HR_FS_L_ADDR 0x33C8\r
+#define GH3X2X_HR_FS_H_ADDR 0x33CA\r
+#define GH3X2X_HR_ALGO_CHNL_NUM_ADDR 0x35C0\r
+#define GH3X2X_ALGO_CHNL_MAP_HR_GREEN_CHNL0_1_ADDR 0x35C4\r
+#define GH3X2X_ALGO_CHNL_MAP_HR_GREEN_CHNL2_3_ADDR 0x35C6\r
+#define GH3X2X_ALGO_CHNL_MAP_HR_IR_CHNL0_1_ADDR 0x35CC\r
+#define GH3X2X_ALGO_CHNL_MAP_HR_IR_CHNL2_3_ADDR 0x35CE\r
+#define GH3X2X_ALGO_CHNL_MAP_HR_RED_CHNL0_1_ADDR 0x35D4\r
+#define GH3X2X_ALGO_CHNL_MAP_HR_RED_CHNL2_3_ADDR 0x35D6\r
+//hrv_drv_cfg\r
+#define GH3X2X_HRV_DRV_CFG_OFFSET 0x00C7\r
+//hrv_alg_cfg\r
+#define GH3X2X_HRV_ALG_CFG_OFFSET 0x023F\r
+#define GH3X2X_HRV_INTERPOLATION_ENABLE_L_ADDR 0x36C0\r
+#define GH3X2X_HRV_INTERPOLATION_ENABLE_H_ADDR 0x36C2\r
+#define GH3X2X_HRV_ACC_THR_MAX_L_ADDR 0x36C4\r
+#define GH3X2X_HRV_ACC_THR_MAX_H_ADDR 0x36C6\r
+#define GH3X2X_HRV_ACC_THR_MIN_L_ADDR 0x36C8\r
+#define GH3X2X_HRV_ACC_THR_MIN_H_ADDR 0x36CA\r
+#define GH3X2X_HRV_ACC_THR_NUM_L_ADDR 0x36CC\r
+#define GH3X2X_HRV_ACC_THR_NUM_H_ADDR 0x36D0\r
+#define GH3X2X_HRV_ACC_THR_SCALE_L_ADDR 0x36D2\r
+#define GH3X2X_HRV_ACC_THR_SCALE_H_ADDR 0x36D4\r
+//hsm_drv_cfg\r
+#define GH3X2X_HSM_DRV_CFG_OFFSET 0x00C7\r
+//hsm_alg_cfg\r
+#define GH3X2X_HSM_ALG_CFG_OFFSET 0x023F\r
+//fpbp_drv_cfg\r
+#define GH3X2X_FPBP_DRV_CFG_OFFSET 0x00C7\r
+//fpbp_alg_cfg \r
+#define GH3X2X_FPBP_ALG_CFG_OFFSET 0x023F\r
+#define GH3X2X_FPBP_CALC_MODE_L_ADDR 0x3CC0\r
+#define GH3X2X_FPBP_CALC_MODE_H_ADDR 0x3CC2\r
+#define GH3X2X_FPBP_CALI_WAVE_REPLEVEL_THRD_L_ADDR 0x3CC4\r
+#define GH3X2X_FPBP_CALI_WAVE_REPLEVEL_THRD_H_ADDR 0x3CC6\r
+#define GH3X2X_FPBP_CALI_WAVE_STBLEVEL_THRD_L_ADDR 0x3CC8\r
+#define GH3X2X_FPBP_CALI_WAVE_STBLEVEL_THRD_H_ADDR 0x3CCA\r
+#define GH3X2X_FPBP_CALI_CONFSCORE_THRD_L_ADDR 0x3CCC\r
+#define GH3X2X_FPBP_CALI_CONFSCORE_THRD_H_ADDR 0x3CCE\r
+#define GH3X2X_FPBP_CALC_WAVE_REPLEVEL_THRD_L_ADDR 0x3CD0\r
+#define GH3X2X_FPBP_CALC_WAVE_REPLEVEL_THRD_H_ADDR 0x3CD2\r
+#define GH3X2X_FPBP_CALC_WAVE_STBLEVEL_THRD_L_ADDR 0x3CD4\r
+#define GH3X2X_FPBP_CALC_WAVE_STBLEVEL_THRD_H_ADDR 0x3CD6\r
+#define GH3X2X_FPBP_CALC_CONFSCORE_THRD_L_ADDR 0x3CD8\r
+#define GH3X2X_FPBP_CALC_CONFSCORE_THRD_H_ADDR 0x3CDA\r
+#define GH3X2X_FPBP_RESULT_CHECK_FLAG_L_ADDR 0x3CDC\r
+#define GH3X2X_FPBP_RESULT_CHECK_FLAG_H_ADDR 0x3CDE\r
+#define GH3X2X_FPBP_PROGRAM_SELECT_L_ADDR 0x3CE0\r
+#define GH3X2X_FPBP_PROGRAM_SELECT_H_ADDR 0x3CE2\r
+#define GH3X2X_FPBP_PRESSURE_OFFSET_L_ADDR 0x3CE4\r
+#define GH3X2X_FPBP_PRESSURE_OFFSET_H_ADDR 0x3CE6\r
+#define GH3X2X_FPBP_PRESSURE_FACTOR_L_ADDR 0x3CE8\r
+#define GH3X2X_FPBP_PRESSURE_FACTOR_H_ADDR 0x3CEA\r
+#define GH3X2X_FPBP_PRESSURE_AREA_L_ADDR 0x3CEC\r
+#define GH3X2X_FPBP_PRESSURE_AREA_H_ADDR 0x3CEE\r
+#define GH3X2X_FPBP_ALGO_CHNL_NUM_ADDR 0x3EC0\r
+#define GH3X2X_ALGO_CHNL_MAP_FPBP_ECG_CHNL_ADDR 0x3EC2\r
+#define GH3X2X_ALGO_CHNL_MAP_FPBP_GREEN_CHNL0_1_ADDR 0x3EC4\r
+#define GH3X2X_ALGO_CHNL_MAP_FPBP_GREEN_CHNL2_3_ADDR 0x3EC6\r
+#define GH3X2X_ALGO_CHNL_MAP_FPBP_IR_CHNL0_1_ADDR 0x3ECC\r
+#define GH3X2X_ALGO_CHNL_MAP_FPBP_IR_CHNL2_3_ADDR 0x3ECE\r
+#define GH3X2X_ALGO_CHNL_MAP_FPBP_RED_CHNL0_1_ADDR 0x3ED4\r
+#define GH3X2X_ALGO_CHNL_MAP_FPBP_RED_CHNL2_3_ADDR 0x3ED6\r
+//pwa_drv_cfg\r
+#define GH3X2X_PWA_DRV_CFG_OFFSET 0x00C7\r
+//pwa_alg_cfg\r
+#define GH3X2X_PWA_ALG_CFG_OFFSET 0x023F\r
+#define GH3X2X_PWA_CALC_MODE_L_ADDR 0x3FC0\r
+#define GH3X2X_PWA_CALC_MODE_H_ADDR 0x3FC2\r
+#define GH3X2X_PWA_CALI_WAVE_REPLEVEL_THRD_L_ADDR 0x3FC4\r
+#define GH3X2X_PWA_CALI_WAVE_REPLEVEL_THRD_H_ADDR 0x3FC6\r
+#define GH3X2X_PWA_CALI_WAVE_STBLEVEL_THRD_L_ADDR 0x3FC8\r
+#define GH3X2X_PWA_CALI_WAVE_STBLEVEL_THRD_H_ADDR 0x3FCA\r
+#define GH3X2X_PWA_CALI_CONFSCORE_THRD_L_ADDR 0x3FCC\r
+#define GH3X2X_PWA_CALI_CONFSCORE_THRD_H_ADDR 0x3FCE\r
+#define GH3X2X_PWA_CALC_WAVE_REPLEVEL_THRD_L_ADDR 0x3FD0\r
+#define GH3X2X_PWA_CALC_WAVE_REPLEVEL_THRD_H_ADDR 0x3FD2\r
+#define GH3X2X_PWA_CALC_WAVE_STBLEVEL_THRD_L_ADDR 0x3FD4\r
+#define GH3X2X_PWA_CALC_WAVE_STBLEVEL_THRD_H_ADDR 0x3FD6\r
+#define GH3X2X_PWA_CALC_CONFSCORE_THRD_L_ADDR 0x3FD8\r
+#define GH3X2X_PWA_CALC_CONFSCORE_THRD_H_ADDR 0x3FDA\r
+#define GH3X2X_PWA_RESULT_CHECK_FLAG_L_ADDR 0x3FDC\r
+#define GH3X2X_PWA_RESULT_CHECK_FLAG_H_ADDR 0x3FDE\r
+#define GH3X2X_PWA_PROGRAM_SELECT_L_ADDR 0x3FE0\r
+#define GH3X2X_PWA_PROGRAM_SELECT_H_ADDR 0x3FE2\r
+#define GH3X2X_PWA_PRESSURE_OFFSET_L_ADDR 0x3FE4\r
+#define GH3X2X_PWA_PRESSURE_OFFSET_H_ADDR 0x3FE6\r
+#define GH3X2X_PWA_PRESSURE_FACTOR_L_ADDR 0x3FE8\r
+#define GH3X2X_PWA_PRESSURE_FACTOR_H_ADDR 0x3FEA\r
+#define GH3X2X_PWA_PRESSURE_AREA_L_ADDR 0x3FEC\r
+#define GH3X2X_PWA_PRESSURE_AREA_H_ADDR 0x3FEE\r
+#define GH3X2X_PWA_ALGO_CHNL_NUM_ADDR 0x41C0\r
+#define GH3X2X_ALGO_CHNL_MAP_PWA_ECG_CHNL_ADDR 0x41C2\r
+#define GH3X2X_ALGO_CHNL_MAP_PWA_GREEN_CHNL0_1_ADDR 0x41C4\r
+#define GH3X2X_ALGO_CHNL_MAP_PWA_GREEN_CHNL2_3_ADDR 0x41C6\r
+#define GH3X2X_ALGO_CHNL_MAP_PWA_IR_CHNL0_1_ADDR 0x41CC\r
+#define GH3X2X_ALGO_CHNL_MAP_PWA_IR_CHNL2_3_ADDR 0x41CE\r
+#define GH3X2X_ALGO_CHNL_MAP_PWA_RED_CHNL0_1_ADDR 0x41D4\r
+#define GH3X2X_ALGO_CHNL_MAP_PWA_RED_CHNL2_3_ADDR 0x41D6\r
+//spo2_drv_cfg\r
+#define GH3X2X_SPO2_DRV_CFG_OFFSET 0x00C7\r
+//spo2_alg_cfg\r
+#define GH3X2X_SPO2_ALG_CFG_OFFSET 0x023F\r
+#define GH3X2X_SPO2_CH0_CORRECTION_FACTOR0_L_ADDR 0x42C0\r
+#define GH3X2X_SPO2_CH0_CORRECTION_FACTOR0_H_ADDR 0x42C2\r
+#define GH3X2X_SPO2_CH0_CORRECTION_FACTOR1_L_ADDR 0x42C4\r
+#define GH3X2X_SPO2_CH0_CORRECTION_FACTOR1_H_ADDR 0x42C6\r
+#define GH3X2X_SPO2_CH0_CORRECTION_FACTOR2_L_ADDR 0x42C8\r
+#define GH3X2X_SPO2_CH0_CORRECTION_FACTOR2_H_ADDR 0x42CA\r
+#define GH3X2X_SPO2_CH0_CORRECTION_FACTOR3_L_ADDR 0x42CC\r
+#define GH3X2X_SPO2_CH0_CORRECTION_FACTOR3_H_ADDR 0x42CE\r
+#define GH3X2X_SPO2_CH0_CORRECTION_FACTOR4_L_ADDR 0x42D0\r
+#define GH3X2X_SPO2_CH0_CORRECTION_FACTOR4_H_ADDR 0x42D2\r
+#define GH3X2X_SPO2_CH1_CORRECTION_FACTOR0_L_ADDR 0x42D4\r
+#define GH3X2X_SPO2_CH1_CORRECTION_FACTOR0_H_ADDR 0x42D6\r
+#define GH3X2X_SPO2_CH1_CORRECTION_FACTOR1_L_ADDR 0x42D8\r
+#define GH3X2X_SPO2_CH1_CORRECTION_FACTOR1_H_ADDR 0x42DA\r
+#define GH3X2X_SPO2_CH1_CORRECTION_FACTOR2_L_ADDR 0x42DC\r
+#define GH3X2X_SPO2_CH1_CORRECTION_FACTOR2_H_ADDR 0x42DE\r
+#define GH3X2X_SPO2_CH1_CORRECTION_FACTOR3_L_ADDR 0x42E0\r
+#define GH3X2X_SPO2_CH1_CORRECTION_FACTOR3_H_ADDR 0x42E2\r
+#define GH3X2X_SPO2_CH1_CORRECTION_FACTOR4_L_ADDR 0x42E4\r
+#define GH3X2X_SPO2_CH1_CORRECTION_FACTOR4_H_ADDR 0x42E6\r
+#define GH3X2X_SPO2_CH2_CORRECTION_FACTOR0_L_ADDR 0x42E8\r
+#define GH3X2X_SPO2_CH2_CORRECTION_FACTOR0_H_ADDR 0x42EA\r
+#define GH3X2X_SPO2_CH2_CORRECTION_FACTOR1_L_ADDR 0x42EC\r
+#define GH3X2X_SPO2_CH2_CORRECTION_FACTOR1_H_ADDR 0x42EE\r
+#define GH3X2X_SPO2_CH2_CORRECTION_FACTOR2_L_ADDR 0x42F0\r
+#define GH3X2X_SPO2_CH2_CORRECTION_FACTOR2_H_ADDR 0x42F2\r
+#define GH3X2X_SPO2_CH2_CORRECTION_FACTOR3_L_ADDR 0x42F4\r
+#define GH3X2X_SPO2_CH2_CORRECTION_FACTOR3_H_ADDR 0x42F6\r
+#define GH3X2X_SPO2_CH2_CORRECTION_FACTOR4_L_ADDR 0x42F8\r
+#define GH3X2X_SPO2_CH2_CORRECTION_FACTOR4_H_ADDR 0x42FA\r
+#define GH3X2X_SPO2_CH3_CORRECTION_FACTOR0_L_ADDR 0x42FC\r
+#define GH3X2X_SPO2_CH3_CORRECTION_FACTOR0_H_ADDR 0x42FE\r
+#define GH3X2X_SPO2_CH3_CORRECTION_FACTOR1_L_ADDR 0x4300\r
+#define GH3X2X_SPO2_CH3_CORRECTION_FACTOR1_H_ADDR 0x4302\r
+#define GH3X2X_SPO2_CH3_CORRECTION_FACTOR2_L_ADDR 0x4304\r
+#define GH3X2X_SPO2_CH3_CORRECTION_FACTOR2_H_ADDR 0x4306\r
+#define GH3X2X_SPO2_CH3_CORRECTION_FACTOR3_L_ADDR 0x4308\r
+#define GH3X2X_SPO2_CH3_CORRECTION_FACTOR3_H_ADDR 0x430A\r
+#define GH3X2X_SPO2_CH3_CORRECTION_FACTOR4_L_ADDR 0x430C\r
+#define GH3X2X_SPO2_CH3_CORRECTION_FACTOR4_H_ADDR 0x430E\r
+#define GH3X2X_SPO2_ALGO_CHNL_NUM_ADDR 0x44C0\r
+#define GH3X2X_ALGO_CHNL_MAP_SPO2_GREEN_CHNL0_1_ADDR 0x44C4\r
+#define GH3X2X_ALGO_CHNL_MAP_SPO2_GREEN_CHNL2_3_ADDR 0x44C6\r
+#define GH3X2X_ALGO_CHNL_MAP_SPO2_IR_CHNL0_1_ADDR 0x44CC\r
+#define GH3X2X_ALGO_CHNL_MAP_SPO2_IR_CHNL2_3_ADDR 0x44CE\r
+#define GH3X2X_ALGO_CHNL_MAP_SPO2_RED_CHNL0_1_ADDR 0x44D4\r
+#define GH3X2X_ALGO_CHNL_MAP_SPO2_RED_CHNL2_3_ADDR 0x44D6\r
+//ecg_drv_cfg\r
+#define GH3X2X_ECG_DRV_CFG_OFFSET 0x00C7\r
+#define GH3X2X_ECG_SETTING0_ADDR 0x4500\r
+#define GH3X2X_ECG_SETTING1_ADDR 0x4502\r
+#define GH3X2X_ECG_SETTING2_ADDR 0x4504\r
+#define GH3X2X_ECG_SETTING3_ADDR 0x4506\r
+//ecg_alg_cfg\r
+#define GH3X2X_ECG_ALG_CFG_OFFSET 0x023F\r
+//pwtt_drv_cfg\r
+#define GH3X2X_PWTT_DRV_CFG_OFFSET 0x00C7\r
+//pwtt_alg_cfg\r
+#define GH3X2X_PWTT_ALG_CFG_OFFSET 0x023F\r
+//softadtgreen_drv_cfg\r
+#define GH3X2X_SOFTADTGREEN_DRV_CFG_OFFSET 0x00C7\r
+//softadtgreen_alg_cfg\r
+#define GH3X2X_SOFTADTGREEN_ALG_CFG_OFFSET 0x023F\r
+#define GH3X2X_SOFTADT_GREEN_ALGO_CHNL_NUM_ADDR 0x4DC0\r
+#define GH3X2X_ALGO_CHNL_MAP_SOFTADTGREEN_GREEN_CHNL0_1_ADDR 0x4DC4\r
+#define GH3X2X_ALGO_CHNL_MAP_SOFTADTGREEN_GREEN_CHNL2_3_ADDR 0x4DC6\r
+#define GH3X2X_ALGO_CHNL_MAP_SOFTADTGREEN_GREEN_BG_CHNL0_1_ADDR 0x4DCC\r
+#define GH3X2X_ALGO_CHNL_MAP_SOFTADTGREEN_BG_CHNL2_3_ADDR 0x4DCE\r
+#define GH3X2X_ALGO_CHNL_MAP_SOFTADTGREEN_ADT_CHNL0_1_ADDR 0x4DD4\r
+#define GH3X2X_ALGO_CHNL_MAP_SOFTADTGREEN_ADT_CHNL2_3_ADDR 0x4DD6\r
+//bt_drv_cfg\r
+#define GH3X2X_BT_DRV_CFG_OFFSET 0x00C7\r
+//bt_alg_cfg\r
+#define GH3X2X_BT_ALG_CFG_OFFSET 0x023F\r
+#define GH3X2X_BT_NTC0_CALIRESISTANCE1_L_ADDR 0x4EC0\r
+#define GH3X2X_BT_NTC0_CALIRESISTANCE1_H_ADDR 0x4EC2\r
+#define GH3X2X_BT_NTC0_CALIRESISTANCE2_L_ADDR 0x4EC4\r
+#define GH3X2X_BT_NTC0_CALIRESISTANCE2_H_ADDR 0x4EC6\r
+#define GH3X2X_BT_NTC0_CALIRESISTANCE3_L_ADDR 0x4EC8\r
+#define GH3X2X_BT_NTC0_CALIRESISTANCE3_H_ADDR 0x4ECA\r
+#define GH3X2X_BT_NTC0_BASERESISTANCE_L_ADDR 0x4ECC\r
+#define GH3X2X_BT_NTC0_BASERESISTANCE_H_ADDR 0x4ECE\r
+#define GH3X2X_BT_NTC0_CALITEMPERATURE1_L_ADDR 0x4ED0\r
+#define GH3X2X_BT_NTC0_CALITEMPERATURE1_H_ADDR 0x4ED2\r
+#define GH3X2X_BT_NTC0_CALITEMPERATURE2_L_ADDR 0x4ED4\r
+#define GH3X2X_BT_NTC0_CALITEMPERATURE2_H_ADDR 0x4ED6\r
+#define GH3X2X_BT_NTC0_CALITEMPERATURE3_L_ADDR 0x4ED8\r
+#define GH3X2X_BT_NTC0_CALITEMPERATURE3_H_ADDR 0x4EDA\r
+#define GH3X2X_BT_NTC1_CALIRESISTANCE1_L_ADDR 0x4EDC\r
+#define GH3X2X_BT_NTC1_CALIRESISTANCE1_H_ADDR 0x4EDE\r
+#define GH3X2X_BT_NTC1_CALIRESISTANCE2_L_ADDR 0x4EE0\r
+#define GH3X2X_BT_NTC1_CALIRESISTANCE2_H_ADDR 0x4EE2\r
+#define GH3X2X_BT_NTC1_CALIRESISTANCE3_L_ADDR 0x4EE4\r
+#define GH3X2X_BT_NTC1_CALIRESISTANCE3_H_ADDR 0x4EE6\r
+#define GH3X2X_BT_NTC1_BASERESISTANCE_L_ADDR 0x4EE8\r
+#define GH3X2X_BT_NTC1_BASERESISTANCE_H_ADDR 0x4EEA\r
+#define GH3X2X_BT_NTC1_CALITEMPERATURE1_L_ADDR 0x4EEC\r
+#define GH3X2X_BT_NTC1_CALITEMPERATURE1_H_ADDR 0x4EEE\r
+#define GH3X2X_BT_NTC1_CALITEMPERATURE2_L_ADDR 0x4EF0\r
+#define GH3X2X_BT_NTC1_CALITEMPERATURE2_H_ADDR 0x4EF2\r
+#define GH3X2X_BT_NTC1_CALITEMPERATURE3_L_ADDR 0x4EF4\r
+#define GH3X2X_BT_NTC1_CALITEMPERATURE3_H_ADDR 0x4EF6\r
+//resp_drv_cfg\r
+#define GH3X2X_RESP_DRV_CFG_OFFSET 0x00C7\r
+//resp_alg_cfg\r
+#define GH3X2X_RESP_ALG_CFG_OFFSET 0x023F\r
+//af_drv_cfg\r
+#define GH3X2X_AF_DRV_CFG_OFFSET 0x00C7\r
+//af_alg_cfg\r
+#define GH3X2X_AF_ALG_CFG_OFFSET 0x023F\r
+#define GH3X2X_AF_WAIT_TIME_L_ADDR 0x54C0\r
+#define GH3X2X_AF_WAIT_TIME_H_ADDR 0x54C2\r
+//test1_drv_cfg\r
+#define GH3X2X_TEST1_DRV_CFG_OFFSET 0x00C7\r
+//test1_alg_cfg\r
+#define GH3X2X_TEST1_ALG_CFG_OFFSET 0x023F\r
+//test2_drv_cfg\r
+#define GH3X2X_TEST2_DRV_CFG_OFFSET 0x00C7\r
+//test2_alg_cfg\r
+#define GH3X2X_TEST2_ALG_CFG_OFFSET 0x023F\r
+//softadtir_drv_cfg\r
+#define GH3X2X_SOFTADTIR_DRV_CFG_OFFSET 0x00C7\r
+//softadtir_alg_cfg\r
+#define GH3X2X_SOFTADTIR_ALG_CFG_OFFSET 0x023F\r
+#define GH3X2X_SOFTADT_ALGO_IR_CHNL_NUM_ADDR 0x5FC0\r
+#define GH3X2X_ALGO_CHNL_MAP_SOFTADTIR_IR_CHNL0_1_ADDR 0x5FC4\r
+#define GH3X2X_ALGO_CHNL_MAP_SOFTADTIR_IR_CHNL2_3_ADDR 0x5FC6\r
+#define GH3X2X_ALGO_CHNL_MAP_SOFTADTIR_BG_CHNL0_1_ADDR 0x5FCC\r
+#define GH3X2X_ALGO_CHNL_MAP_SOFTADTIR_BG_CHNL2_3_ADDR 0x5FCE\r
+#define GH3X2X_ALGO_CHNL_MAP_SOFTADTIR_ADT_CHNL0_1_ADDR 0x5FD4\r
+#define GH3X2X_ALGO_CHNL_MAP_SOFTADTIR_ADT_CHNL2_3_ADDR 0x5FD6\r
+//finish_flag\r
+#define GH3X2X_FINISH_FLAG_OFFSET 0x00FF\r
+#define GH3X2X_CHECKSUM_ADDR 0xFFFE\r
+#define GH3X2X_END_FLAG_ADDR 0xFFFF\r
+\r
+\r
+\r
+#define GH3X2X_CHNLMAP_OFFSET 0X0022\r
+#define GH3X2X_VREG_ALGO_PARA_OFFSET 0X00C0\r
+#define GH3X2X_VREG_FUNCTION_OFFSET 0X0300\r
+#define GH3X2X_VREG_FUNCTION_ALGO_OFFSET 0X00C0\r
+#define GH3X2X_VREG_ALGO_CHNL_MAP_OFFSET 0X0200\r
+\r
+\r
+\r
+/* control config */\r
+\r
+#define GH3X2X_DUMP_MODE_EN     (0)\r
+\r
+#define GH3X2X_ELECTRO_RRECER_OBSERVE_EN     (0)\r
+\r
+#define GH3X2X_AGC_BG_CANCEL_ADJ_EN (0)\r
+\r
+#define GH3X2X_AGC_2X2_GAIN_ADJ_EN (0)\r
+\r
+#define GH3X2X_SUPPORT_READ_BACK_VIRTUAL_REG (0)\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+/// wakeup and sleep every control api\r
+#define   GH3X2X_CTRL_API_INSERT_WAKEUP_AND_DSLP_ENABLED        (0)\r
+\r
+/// instructions chip inited by reg val, using reg chip_sw_backup[1:0]\r
+#define   GH3X2X_INSTRUCTIONS_CHIP_INIED_ENABLED                (1)\r
+\r
+/// wait power pulse mode off effective\r
+#define   GH3X2X_PMU_WAIT_PULSE_OFF_ENABLED                     (0)\r
+\r
+/// fifo power cut before sleep\r
+#define   GH3X2X_PMU_FIFO_POWER_CTRL_ENABLED                    (1)\r
+\r
+/// init communicate confirm max cnt\r
+#define   GH3X2X_COMMUNICATE_CONFIRM_MAX_CNT                    (3)\r
+\r
+/// virtual reg support config software\r
+#define   GH3X2X_VIRTUAL_REG_SW_CONFIG_SUPPORT                  (1)\r
+\r
+/// channel map max channel support to unpack rawdata\r
+#define   GH3X2X_CHANNEL_MAP_MAX_CH                             (32)\r
+\r
+/// gsensor data num\r
+#define   GH3X2X_GSENSOR_MAX_SIZE                               (3)\r
+\r
+/// wear on force switch with adt logic sel\r
+#define   GH3X2X_WEAR_ON_FORCE_SWITCH_WITH_LOGIC_SEL            (1)\r
+\r
+/// ex control slot enable bit form virtual reg config\r
+#define   GH3X2X_EX_SLOT_EN_FROM_CONFIG                         (0)\r
+\r
+/// ex control channel map cnt follow algorithm\r
+#define   GH3X2X_EX_CHANNEL_CNT_FOLLOW_ALGORITHMS               (0)\r
+\r
+\r
+/* protocol config */\r
+\r
+/// universal protocol packet min len support\r
+#define  GH3X2X_UPROTOCOL_PACKET_LEN_MIN                        (20)\r
+\r
+\r
+\r
+/// cmd support config: fifo thr cmd support\r
+#define  GH3X2X_UPROTOCOL_FIFO_THR_CFG_CMD_SUP                  (1)\r
+\r
+/// cmd support config: chip ctrl cmd support wakeup & sleep\r
+#define  GH3X2X_UPROTOCOL_CHIP_CTRL_CMD_WAKEUP_SLEEP_SUP        (1)\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+typedef struct\r
+{\r
+    GU16 usAddrStart;\r
+    GU16 usAddrEnd;\r
+    void (*ParmSet)(GU16 usVirtualRegAddr, GU16 usVirtualRegValue);\r
+}STGhVirRegSwModuleInfo;\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+/**\r
+ * @fn     GU16 GH3X2X_ReadSwConfigWithVirtualReg(GU16 usVirtualRegAddr)\r
+ *\r
+ * @brief  Read software config with virtual reg\r
+ *\r
+ * @attention   Virtual reg addr has del control bits, so reg addr is [0:11] valid.\r
+ *\r
+ * @param[in]   usVirtualRegAddr        virtual reg addr\r
+ * @param[out]  None\r
+ *\r
+ * @return  virtual reg val\r
+ */\r
+GU16 GH3X2X_ReadSwConfigWithVirtualReg(GU16 usVirtualRegAddr);\r
+\r
+/**\r
+ * @fn     GS8 GH3X2X_WriteSwConfigWithVirtualReg(GU16 usVirtualRegAddr, GU16 usVirtualRegValue)\r
+ *\r
+ * @brief  Write software param config with virtual reg\r
+ *\r
+ * @attention   Virtual reg addr has del control bits, so reg addr is [0:11] valid.\r
+ *\r
+ * @param[in]   usVirtualRegAddr        virtual reg addr\r
+ * @param[in]   usVirtualRegValue       virtual reg value\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_WriteSwConfigWithVirtualReg(GU16 usVirtualRegAddr, GU16 usVirtualRegValue);\r
+\r
+/**\r
+ * @fn     GU16 GH3X2X_ReadChnlMapConfigWithVirtualReg(GU16 usVirtualRegAddr)\r
+ *\r
+ * @brief  Read software config with virtual reg\r
+ *\r
+ * @attention   Virtual reg addr has del control bits, so reg addr is [0:11] valid.\r
+ *\r
+ * @param[in]   usVirtualRegAddr        virtual reg addr\r
+ * @param[out]  None\r
+ *\r
+ * @return  virtual reg val\r
+ */\r
+GU16 GH3X2X_ReadChnlMapConfigWithVirtualReg(GU16 usVirtualRegAddr);\r
+\r
+/**\r
+ * @fn     GS8 GH3X2X_WriteChnlMapConfigWithVirtualReg(GU16 usVirtualRegAddr, GU16 usVirtualRegValue)\r
+ *\r
+ * @brief  Write software param config with virtual reg\r
+ *\r
+ * @attention   Virtual reg addr has del control bits, so reg addr is [0:11] valid.\r
+ *\r
+ * @param[in]   usVirtualRegAddr        virtual reg addr\r
+ * @param[in]   usVirtualRegValue       virtual reg value\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_WriteChnlMapConfigWithVirtualReg(GU16 usVirtualRegAddr, GU16 usVirtualRegValue);\r
+\r
+/**\r
+ * @fn     GS8 GH3X2X_WriteVirtualReg(GU16 usVirtualRegAddr, GU16 usVirtualRegValue)\r
+ *\r
+ * @brief  Write virtual reg val, for software param config\r
+ *\r
+ * @attention   Virtual reg addr has del control bits, so reg addr is [0:11] valid.\r
+ *\r
+ * @param[in]   usVirtualRegAddr        virtual reg addr\r
+ * @param[in]   usVirtualRegValue       virtual reg value\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_WriteVirtualReg(GU16 usVirtualRegAddr, GU16 usVirtualRegValue);\r
+\r
+/**\r
+ * @fn     GU16 GH3X2X_ReadVirtualReg(GU16 usVirtualRegAddr)\r
+ *\r
+ * @brief  Read virtual reg val, for software param config\r
+ *\r
+ * @attention   Virtual reg addr has del control bits, so reg addr is [0:11] valid.\r
+ *\r
+ * @param[in]   usVirtualRegAddr        virtual reg addr\r
+ * @param[out]  None\r
+ *\r
+ * @return  virtual reg val\r
+ */\r
+GU16 GH3X2X_ReadVirtualReg(GU16 usVirtualRegAddr);\r
+\r
+\r
+\r
+\r
+\r
+\r
+GU32 GhGetFunctionIdViaVirReg(GU16 usVirRegAddr, GU16 usVirRegData);\r
+\r
+#endif /* _GH3X2X_DRV_CONFIG_H_ */\r
+\r
+/********END OF FILE********* Copyright (c) 2003 - 2022, Goodix Co., Ltd. ********/\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/driver/inc/gh_drv_control.h b/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/driver/inc/gh_drv_control.h
new file mode 100644 (file)
index 0000000..7dc07fb
--- /dev/null
@@ -0,0 +1,576 @@
+/**\r
+ * @copyright (c) 2003 - 2022, Goodix Co., Ltd. All rights reserved.\r
+ *\r
+ * @file    gh3x2x_drv_control.h\r
+ *\r
+ * @brief   gh3x2x control define & declaration\r
+ *\r
+ * @version ref gh3x2x_drv_version.h\r
+ *\r
+ */\r
+\r
+#ifndef _GH3X2X_DRV_CONTROL_H_\r
+#define _GH3X2X_DRV_CONTROL_H_\r
+\r
+\r
+#include "gh_drv_config.h"\r
+#include "gh_drv.h"\r
+#include "gh_drv_registers.h"\r
+#include "gh_demo_config.h"\r
+\r
+\r
+/**\r
+ * @brief status flag enum\r
+ */\r
+enum EMGh3x2xStatus\r
+{\r
+    GH3X2X_STATUS_NO_INIT = 0,  /**< no init status */\r
+    GH3X2X_STATUS_INITED,       /**< inited status */\r
+    GH3X2X_STATUS_STARTED,      /**< started status */\r
+    GH3X2X_STATUS_INVALID,      /**< invaild status */\r
+};\r
+\r
+\r
+/* function ptr typedef */\r
+\r
+typedef void (*pfnNormalHookFunc)(void);                                                 /**< normal hook type */\r
+typedef void (*pfnGetRawdataHookFunc)(GU8 *puchDataBuffer, GU16 usLen);                  /**< get rawdata hook type */\r
+typedef GU8 (*pfnReadPinStatus)(void);                                                   /**< read pin status type */\r
+typedef void (*pfnSetPinLevel)(GU8 uchPinLevel);                                         /**< set pin status type */\r
+typedef void (*pfnGetIoStructInfo)(const STGh3x2xFrameInfo * const pstFrameInfo);\r
+typedef void (*pfnWriteAlgConfigWithVirtualReg)(GU16 usVirtualRegAddr, GU16 usVirtualRegValue);\r
+\r
+extern GU8 g_uchGh3x2xChipOperateIndexRealtime;\r
+\r
+\r
+\r
+/// send wakeup(resume) cmd\r
+#define   GH3X2X_SEND_WAKEUP_CMD()          do { GH3X2X_SendCmd(GH3X2X_CMD_RESUME); } while (0)\r
+\r
+/// send sleep cmd\r
+#define   GH3X2X_SEND_DSLEEP_CMD()          do { GH3X2X_SendCmd(GH3X2X_CMD_SLEEP); } while (0)\r
+\r
+/// send reset cmd\r
+#define   GH3X2X_SEND_RESET_CMD()           do { GH3X2X_SendCmd(GH3X2X_CMD_RESET); } while (0)\r
+\r
+/// wait send cmd done\r
+#define   GH3X2X_SEND_WAIT_CMD_DONE()       do { GH3X2X_DelayUs(GH3X2X_CMD_DELAY_X_US); } while (0)\r
+\r
+/// wait send sleep done\r
+#define   GH3X2X_SEND_WAIT_SLEEP_CMD_DONE() do { GH3X2X_DelayUs(50); } while (0)\r
+\r
+\r
+\r
+\r
+#define GH3X2X_CHECK_0x0088()             GH3X2X_SEND_WAKEUP_CMD();\\r
+                                          GH3X2X_SEND_WAIT_CMD_DONE();\\r
+                                          GH3X2X_DEBUG_LOG_PARAM("Master: 0x088:%04x\r\n",GH3X2X_ReadReg(0x88));\r
+\r
+/// chip wakeup\r
+#define   GH3X2X_CHIP_WAKEUP(ret)       do {\\r
+                                            GH3X2X_SEND_WAKEUP_CMD();\\r
+                                            GH3X2X_SEND_WAIT_CMD_DONE();\\r
+                                            GH3X2X_PMU_FIFO_POWER_RECOVERY();\\r
+                                            (ret) = GH3X2X_RET_OK;\\r
+                                        } while (0)\r
+\r
+/// chip sleep\r
+#define   GH3X2X_CHIP_SLEEP(ret)        do {\\r
+                                            GH3X2X_PMU_FIFO_POWER_OFF();\\r
+                                            GH3X2X_SEND_DSLEEP_CMD();\\r
+                                            GH3X2X_SEND_WAIT_SLEEP_CMD_DONE();\\r
+                                            (ret) = GH3X2X_RET_OK;\\r
+                                        } while (0)\r
+\r
+/// chip reset\r
+#define   GH3X2X_CHIP_RESET(ret)        do {\\r
+                                            GH3X2X_SEND_RESET_CMD();\\r
+                                            (ret) = GH3X2X_RET_OK;\\r
+                                        } while (0)\r
+\r
+/// chip wakeup\r
+#define   GH3X2X_CHIP_WAKEUP_NORET()    \r
+\r
+/// chip sleep\r
+#define   GH3X2X_CHIP_SLEEP_NORET()     do {\\r
+                                            GH3X2X_PMU_FIFO_POWER_OFF();\\r
+                                            GH3X2X_SEND_DSLEEP_CMD();\\r
+                                            GH3X2X_SEND_WAIT_SLEEP_CMD_DONE();\\r
+                                                                                                                                                                               GH3X2X_SetChipSleepFlag(g_uchGh3x2xChipOperateIndexRealtime);\\r
+                                        } while (0)\r
+\r
+\r
+\r
+\r
+/// chip wakeup\r
+#define   GH3X2X_CHIP_WAKEUP_PROTOCOL()    \r
+\r
+/// chip sleep\r
+#define   GH3X2X_CHIP_SLEEP_PROTOCOL()     do {\\r
+                                            GH3X2X_SEND_DSLEEP_CMD();\\r
+                                            GH3X2X_SEND_WAIT_SLEEP_CMD_DONE();\\r
+                                                                                                                                                                               GH3X2X_SetChipSleepFlag(g_uchGh3x2xChipOperateIndexRealtime);\\r
+                                        } while (0)\r
+\r
+\r
+\r
+\r
+\r
+/// chip reset\r
+#define   GH3X2X_CHIP_RESET_NORET()     do {\\r
+                                            GH3X2X_SEND_RESET_CMD();\\r
+                                        } while (0)\r
+\r
+\r
+\r
+/// chip wakeup\r
+#define   GH3X2X_WAIT_CHIP_WAKEUP()\r
+\r
+/// chip sleep\r
+#define   GH3X2X_WAIT_CHIP_DSLP()\r
+\r
+\r
+\r
+#if GH3X2X_PMU_WAIT_PULSE_OFF_ENABLED\r
+\r
+/// wait pulse mode off\r
+#define GH3X2X_PMU_WAIT_PULSE_MODE_OFF()    do {\\r
+                                                GH3X2X_SEND_DSLEEP_CMD();\\r
+                                                GH3X2X_SEND_WAIT_SLEEP_CMD_DONE();\\r
+                                                GH3X2X_SEND_WAKEUP_CMD();\\r
+                                                GH3X2X_SEND_WAIT_CMD_DONE();\\r
+                                                GH3X2X_SEND_WAIT_CMD_DONE();\\r
+                                            } while (0)\r
+\r
+#else\r
+\r
+/// wait pulse mode off\r
+#define GH3X2X_PMU_WAIT_PULSE_MODE_OFF()    do {} while (0)\r
+\r
+#endif\r
+\r
+/* reg addr control bit macro */\r
+\r
+/// reg addr[11:0] valid\r
+#define   GH3X2X_GET_REG_REAL_ADRR(x)       ((x) & 0x0FFF)\r
+\r
+/* virtual reg addr mcaro */\r
+\r
+/// software config reg end addr, software addr map [0x0000~0x09FE]\r
+#define   GH3X2X_VIRTUAL_REG_SW_CONFIG_END_ADDR         (0x29FF)\r
+\r
+/// algorithm config reg end addr, algorithm addr map [0x0A00~0x0EFE]\r
+#define   GH3X2X_VIRTUAL_REG_ALGO_CONFIG_END_ADDR       (0x2EFF)\r
+\r
+/// write algorithm config function\r
+#define   GH3X2X_FUNCTION_CONFIG_WRITE(...)       do { GH3X2X_WriteFunctionConfigWithVirtualReg(__VA_ARGS__); } while (0)\r
+/// write algorithm config function\r
+#define   GH3X2X_FUNCTION_CONFIG_READ(...)      //(GH3X2X_ReadAlgorithmConfigWithVirtualReg(__VA_ARGS__))\r
+\r
+/// write software config function\r
+#define   GH3X2X_SW_CONFIG_WRITE(...)         do { GH3X2X_WriteSwConfigWithVirtualReg(__VA_ARGS__); } while (0)\r
+/// write software config function\r
+#define   GH3X2X_SW_CONFIG_READ(...)        //(GH3X2X_ReadSwConfigWithVirtualReg(__VA_ARGS__))\r
+\r
+/* reg instructions chip inited macro */\r
+#if   GH3X2X_INSTRUCTIONS_CHIP_INIED_ENABLED\r
+\r
+/// set chip inited flag into reg\r
+#define   GH3X2X_SET_CHIP_INIED()    do {\\r
+                                        GU16 usChipIniedRegValTmp =\\r
+                                            GH3X2X_ReadReg(GH3X2X_INSTRUCTIONS_CHIP_INIED_REG_ADDR);\\r
+                                            GH3X2X_WriteReg(GH3X2X_INSTRUCTIONS_CHIP_INIED_REG_ADDR, \\r
+                                                usChipIniedRegValTmp | GH3X2X_INSTRUCTIONS_CHIP_INIED_REG_VAL);\\r
+                                     } while (0)\r
+\r
+/// read chip inited flag from reg\r
+#define   GH3X2X_IS_CHIP_INIED()    ((GH3X2X_ReadReg(GH3X2X_INSTRUCTIONS_CHIP_INIED_REG_ADDR) &\\r
+                                        GH3X2X_INSTRUCTIONS_CHIP_INIED_REG_VAL) == \\r
+                                        GH3X2X_INSTRUCTIONS_CHIP_INIED_REG_VAL)\r
+#else\r
+\r
+/// set chip inited flag into reg\r
+#define   GH3X2X_SET_CHIP_INIED()\r
+\r
+/// read chip inited flag from reg\r
+#define   GH3X2X_IS_CHIP_INIED()    (1)\r
+\r
+#endif\r
+\r
+#if     GH3X2X_PMU_FIFO_POWER_CTRL_ENABLED\r
+\r
+/// store fifo power status\r
+#define  GH3X2X_PMU_FIFO_POWER_OFF()    do {\\r
+                                            if (g_puchPmuFifoModuleCtrlCacheStatus[g_uchGh3x2xChipOperateIndexRealtime] == 0)\\r
+                                            {\\r
+                                                if ((g_uchGh3x2xStatus == GH3X2X_STATUS_INITED) || \\r
+                                                    (g_uchGh3x2xStatus == GH3X2X_STATUS_NO_INIT)) \\r
+                                                {\\r
+                                                    g_pusPmuFifoModuleCtrlVal[g_uchGh3x2xChipOperateIndexRealtime] = \\r
+                                                            GH3X2X_ReadReg(GH3X2X_PMU_CTRL4_REG_ADDR);\\r
+                                                    GH3X2X_WriteReg(GH3X2X_PMU_CTRL4_REG_ADDR, \\r
+                                                     (g_pusPmuFifoModuleCtrlVal[g_uchGh3x2xChipOperateIndexRealtime] | GH3X2X_PMU_CTRL4_FIFO_DISABLE_MASK));\\r
+                                                    g_puchPmuFifoModuleCtrlCacheStatus[g_uchGh3x2xChipOperateIndexRealtime] = 1;\\r
+                                                    GH3X2X_DEBUG_LOG_INTERNAL("save pmu fifo module status!\r\n");\\r
+                                                }\\r
+                                            }\\r
+                                        } while (0)\r
+\r
+/// set chip inited flag into reg\r
+#define  GH3X2X_PMU_FIFO_POWER_RECOVERY()       do {\\r
+                                                    if (g_puchPmuFifoModuleCtrlCacheStatus[g_uchGh3x2xChipOperateIndexRealtime] == 1)\\r
+                                                    {\\r
+                                                        GH3X2X_WriteReg(GH3X2X_PMU_CTRL4_REG_ADDR, \\r
+                                                                            g_pusPmuFifoModuleCtrlVal[g_uchGh3x2xChipOperateIndexRealtime]);\\r
+                                                        GH3X2X_DEBUG_LOG_PARAM("write pmu: 0x%X\r\n",g_pusPmuFifoModuleCtrlVal[g_uchGh3x2xChipOperateIndexRealtime]);\\r
+                                                        GH3X2X_PMU_WAIT_PULSE_MODE_OFF();\\r
+                                                        g_puchPmuFifoModuleCtrlCacheStatus[g_uchGh3x2xChipOperateIndexRealtime] = 0;\\r
+                                                        GH3X2X_DEBUG_LOG_INTERNAL(\\r
+                                                                            "recovery pmu fifo module status!\r\n");\\r
+                                                    }\\r
+                                                } while (0)\r
+\r
+#else\r
+\r
+/// store fifo power status\r
+#define   GH3X2X_PMU_FIFO_POWER_OFF()\r
+\r
+/// set chip inited flag into reg\r
+#define   GH3X2X_PMU_FIFO_POWER_RECOVERY()\r
+\r
+#endif\r
+\r
+/// wear detect force switch delay\r
+#define GH3X2X_WEAR_DETECT_SWITCH_WAIT_X_US             (150)\r
+\r
+/// hard reset delay\r
+#define   GH3X2X_HARD_RESET_DELAY_X_US                  (100)\r
+\r
+/// fifo watermark thr min val\r
+#define   GH3X2X_FIFO_WATERMARK_THR_MIN                 (3)\r
+\r
+/// fifo watermark thr max val\r
+#define   GH3X2X_FIFO_WATERMARK_THR_MAX                 (800)\r
+\r
+/// irq width val\r
+#define   GH3X2X_IRQ_WIDTH_VAL_MAX                      (2047)\r
+\r
+/* osc cali */\r
+\r
+/// osc calibration code lock flag\r
+#define   GH3X2X_OSC_CALI_CODE_LOACKED                  (0x0001)\r
+\r
+/// osc calibration Ctrl disable\r
+#define   GH3X2X_OSC_CALI_CTRL_DIS_VAL                  (0x0000)\r
+\r
+/// hsi osc calibration delay\r
+#define   GH3X2X_HSI_CALI_DELAY_VAL                     (1000u)\r
+\r
+/// hsi osc calibration theroy count\r
+#define   GH3X2X_HSI_CALI_THR_CNT_VAL                   (0x0196)\r
+\r
+/// hsi osc calibration Ctrl enable\r
+#define   GH3X2X_HSI_CALI_CTRL_EN_VAL                   (0x0271)\r
+\r
+/// lsi osc calibration theroy count\r
+#define   GH3X2X_LSI_CALI_THR_CNT_VAL                   (0x1F40)\r
+\r
+/// lsi osc calibration ctrl coarse enable\r
+#define   GH3X2X_LSI_CALI_CTRL_C_EN_VAL                 (0x09D7)\r
+\r
+/// lsi osc calibration ctrl fine enable\r
+#define   GH3X2X_LSI_CALI_CTRL_F_EN_VAL                 (0x19D3)\r
+\r
+/// lsi osc calibration error val max\r
+#define   GH3X2X_LSI_CALI_ERR_MAX_VAL                   (0x3FFF)\r
+\r
+/// lsi osc calibration error val fixed val\r
+#define   GH3X2X_LSI_CALI_ERR_FIXED_VAL                 (0x8000)\r
+\r
+/// lsi osc calibration fine error max\r
+#define   GH3X2X_LSI_CALI_FINE_VAL_MAX                  (255u)\r
+\r
+/// lsi osc calibration fine tune max cnt\r
+#define   GH3X2X_LSI_CALI_FINE_TUNE_MAX                 (9u)\r
+\r
+/// lsi osc calibration fine div num\r
+#define   GH3X2X_LSI_CALI_FINE_DIV_NUM                  (2u)\r
+\r
+/// lsi osc calibration delay\r
+#define   GH3X2X_LSI_COR_CALI_DELAY_VAL                 (50000u)\r
+\r
+/// lsi osc calibration delay\r
+#define   GH3X2X_LSI_FINE_CALI_DELAY_VAL                (5000u)\r
+\r
+/**< rawdata buffer size in byte */\r
+#define   GH3X2X_RAWDATA_BUFFER_SIZE                    (200*4)\r
+\r
+/// get slot & adc num from rawdata flag byte, equal channel map formats\r
+#define   GH3X2X_CHANNEL_MAP_GET(x)                     ((x) & GH3X2X_SLOT_ADC_NUM_BITS)\r
+\r
+\r
+\r
+// fifo monitor start\r
+\r
+typedef struct\r
+{\r
+    GU8 uchDecimaionChnlNum;   //0~8\r
+    GU8 puchSlotAdcIdx[GH3X2X_DECIMAION_CHNL_MAX];        //slot and adc index for valid decimation channel\r
+    GU8 puchDecimationOption[GH3X2X_DECIMAION_CHNL_MAX];   //1: 2x decimation   2: 4x decimaiton  3: 8x deccimaion  others: is illegal\r
+} STGh3x2xDecimationInfo;\r
+\r
+\r
+\r
+\r
+#define EVERY_CHNL_REAL_TIME_SAMPLE_CNT_RX0_INDEX 0\r
+#define EVERY_CHNL_REAL_TIME_SAMPLE_CNT_RX1_INDEX 1\r
+#define EVERY_CHNL_REAL_TIME_SAMPLE_CNT_RX2_INDEX 2\r
+#define EVERY_CHNL_REAL_TIME_SAMPLE_CNT_RX3_INDEX 3\r
+\r
+\r
+#define GH3X2X_FIFO_MONITOR_RAM_OPTIMIZE       1\r
+#define GH3X2X_FIFO_MONITOR_DEBUG              0\r
+\r
+\r
+typedef struct\r
+{\r
+    GU8  uchLowestChnlSlotAdcIdx;   // slot and adc index of lowest channel,  0xFF means: there is no channel output to fifo\r
+    GU8  uchLowestChnlAppearedFlag;   //0£ºnever appeared   1: appeared\r
+    GU16 usNeedSkipFifoByteNum;      //the number which we need skip before formal monitor\r
+#if 0 == GH3X2X_FIFO_MONITOR_RAM_OPTIMIZE\r
+    GU16 usRealTimeSampleCnt[GH3X2X_SLOT_NUM_MAX];   //real time counter of sample of every slot between two lowest channels sample\r
+    #if GH3X2X_FIFO_MONITOR_DECIMATION_SUPPORT\r
+    GU16 uchEstiSampleCntUplimit[GH3X2X_SLOT_NUM_MAX];   //estimate up limit counter of sample of every slot between two lowest channels sample\r
+    #endif\r
+    GU16 usEstiSampleCntlimit [GH3X2X_SLOT_NUM_MAX];   //estimate down limit counter of sample of every slot between two lowest channels sample\r
+#endif\r
+    GU16 usAllChnlRealTimeSampleCnt;\r
+    #if GH3X2X_FIFO_MONITOR_DECIMATION_SUPPORT\r
+    GU16 usEstiAllChnlSampleCntUplimit;\r
+    #endif\r
+    GU16 usEstiAllChnlSampleCntlimit;\r
+#if GH3X2X_FIFO_MONITOR_DEBUG\r
+    GU16 usEveryChnlRealTimeSampleCnt[GH3X2X_SLOT_NUM_MAX][GH3X2X_RX_NUM_MAX];\r
+#endif\r
+} STGh3x2xFifoMonitorInfo;\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+/* extern variables declaration */\r
+\r
+/// get rawdata hook func ptr\r
+extern pfnGetRawdataHookFunc g_pGh3x2xGetRawdataHookFunc;\r
+\r
+/// read int pin status func ptr\r
+extern pfnReadPinStatus g_pGh3x2xReadIntPinStatusFunc;\r
+\r
+/// read reset pin status func ptr\r
+extern pfnReadPinStatus g_pGh3x2xReadResetPinStatusFunc;\r
+\r
+/// read spcs pin status func ptr\r
+extern pfnReadPinStatus g_pGh3x2xReadSpcsPinStatusFunc;\r
+\r
+/// read spdo pin status func ptr\r
+extern pfnReadPinStatus g_pGh3x2xReadSpdoPinStatusFunc;\r
+\r
+/// set algo config hook func ptr\r
+extern pfnWriteAlgConfigWithVirtualReg g_pGh3x2xWriteAlgConfigWithVirtualRegHookFunc;\r
+\r
+/// config start set hook func ptr\r
+extern pfnNormalHookFunc g_pGh3x2xConfigSetStartHookFunc;\r
+\r
+/// config stop set hook func ptr\r
+extern pfnNormalHookFunc g_pGh3x2xConfigSetStopHookFunc;\r
+\r
+#if GH3X2X_PMU_FIFO_POWER_CTRL_ENABLED\r
+\r
+/// fifo power ctrl fifo control reg cache var\r
+extern GU16 g_pusPmuFifoModuleCtrlVal[];\r
+\r
+/// for fifo power ctrl cache status\r
+extern GU8 g_puchPmuFifoModuleCtrlCacheStatus[];\r
+\r
+#endif\r
+\r
+/// gh3x2x status\r
+extern GU8 g_uchGh3x2xStatus;\r
+\r
+/// max rawdata num read from fifo every time\r
+extern GU16 g_usMaxNumReadFromFifo;\r
+\r
+\r
+\r
+extern GU8 g_uchGsensorEnable;\r
+/// Cap enable flag\r
+extern GU8 g_uchCapEnable;\r
+\r
+/// Temp enable flag\r
+extern GU8 g_uchTempEnable;\r
+\r
+/// function started bitmap, use for sampling control\r
+extern GU32 g_unFuncStartedBitmap ;\r
+\r
+/**\r
+ * @fn     GU16 GH3X2X_FindGu16MinVal(GU16 *pusBuffer, GU8 uchLen)\r
+ *\r
+ * @brief  Find min val\r
+ *\r
+ * @attention   len must > 0\r
+ * \r
+ * @param[in]   pusBuffer        pointer to buffer\r
+ * @param[in]   uchLen           buffer length\r
+ * @param[out]  None\r
+ *\r
+ * @return  min val, if len = 0, return 0\r
+ */\r
+GU16 GH3X2X_FindGu16MinVal(GU16 *pusBuffer, GU8 uchLen);\r
+\r
+/**\r
+ * @fn     GU16 GH3X2X_FindGu16MaxVal(GU16 *pusBuffer, GU8 uchLen)\r
+ *\r
+ * @brief  Find max val\r
+ *\r
+ * @attention   len must > 0\r
+ * \r
+ * @param[in]   pusBuffer        pointer to buffer\r
+ * @param[in]   uchLen           buffer length\r
+ * @param[out]  None\r
+ *\r
+ * @return  max val, if len = 0, return 0\r
+ */\r
+GU16 GH3X2X_FindGu16MaxVal(GU16 *pusBuffer, GU8 uchLen);\r
+\r
+/**\r
+ * @fn     void GH3X2X_FindGu16MaxMinVal(GU16 *pusMaxVal, GU16 *pusMinVal, GU16 *pusBuffer, GU8 uchLen)\r
+ *\r
+ * @brief  Find min val & max val\r
+ *\r
+ * @attention   len must > 0, ptr not null\r
+ * \r
+ * @param[in]   pusBuffer        pointer to buffer\r
+ * @param[in]   uchLen           buffer length\r
+ * @param[out]  pusMaxVal        pointer to max val\r
+ * @param[out]  pusMinVal        pointer to min val\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_FindGu16MaxMinVal(GU16 *pusMaxVal, GU16 *pusMinVal, GU16 *pusBuffer, GU8 uchLen);\r
+\r
+/**\r
+ * @fn       GU8 GH3x2x_GetChipResetRecoveringFlag(void)\r
+ \r
+ \r
+ *\r
+ * @brief  \r
+ *\r
+ * @attention   None.\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  chip reset recovering flag  0: is not in chip reset recovering flag  1: is in chip reset recovering\r
+ *\r
+ * @return  None\r
+ */\r
+GU8 GH3x2x_GetChipResetRecoveringFlag(void);\r
+\r
+\r
+/**\r
+ * @fn     void GH3X2X_ReinitAllSwModuleParam(GU16 usReinitFlag)\r
+ *\r
+ * @brief  reinit all software param config\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   usReinitFlag        reinit flag, #0 don't reinit, #others reinit all\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_ReinitAllSwModuleParam(GU16 usReinitFlag);\r
+\r
+GU8 GH3x2xGetProtocolMode(void);\r
+void GH3x2xCreatTagArray(GU8 *puchTagArray, GU16 usArrayLen,GU32 *unCompeletMask, const STGh3x2xFrameInfo * const pstFrameInfo);\r
+void GH3x2xHandleFrameData(const STGh3x2xFrameInfo * const pstFrameInfo, GU32 *punTempIncompeletFlag,\r
+                                GU32 *punFunctionID, GU8 uchChnlNum, GU8 *puchRawdataBuf, GU32 *punFrameRawdata,\r
+                                GU8 *puchTag, GS16 *pusGsValueArr, float fGsensorIndex,\r
+                                STCapRawdata* pstCapValueArr,float fCapIndex,STTempRawdata* pstTempValueArr,float fTempIndex);\r
+\r
+GU8 GH3X2X_CheckRawdataBuf(GU8 *puchRawdata, GU16 usRawdataLen);\r
+float GH3x2xCalGsensorStep(GU16 usGsDataNum, GU16 usFrameNum);\r
+void GH3X2X_SendOverflowLengthBuffer(GU8 *puchBuffer, GS32 nBufferLen, GU8 uchCmd, GU8 uchSignID);\r
+GU8 GH3X2X_ReceiveOverflowLengthBuffer(GU8 *puchRespondBuffer, GU16 *pusRespondLen, GU8 *puchReceiveBuffer, GS32 *pnReceiveBufferLen);\r
+\r
+                                                                                                                               \r
+/**\r
+ * @fn     GU32 DRV_DSP_RawdataCalc(GU32 *punRawdata)\r
+ *\r
+ * @brief  calc byte check rawdata\r
+ *\r
+ * @attention\r
+ *\r
+ * @param[in]   punRawdata  one rawdata addr\r
+ * @param[out]  None\r
+ *\r
+ * @return  target rawdata\r
+ */\r
+GU32 DRV_DSP_RawdataCalc(GU32 unRawdata);\r
+\r
+/**\r
+ * @fn     GU8 DRV_DSP_RawdataCheck(GU32 unRawdata)\r
+ *\r
+ * @brief  rawdata check last byte in algo lib\r
+ *\r
+ * @attention   none\r
+ *\r
+ * @param[in]   unRawdata   single rawdata\r
+ * @param[out]  None\r
+ *\r
+ * @return  errcode\r
+ * @retval  0               check success\r
+ * @retval  1               check failed\r
+ */\r
+GU8 DRV_DSP_RawdataCheck(GU32 unRawdata);\r
+\r
+/**\r
+ * @fn     void DRV_DSP_RawdataTransform(GU32 *punRawdata)\r
+ *\r
+ * @brief  calc new rawdata\r
+ *\r
+ * @attention\r
+ *\r
+ * @param[in]   punRawdata\r
+ *\r
+ * @return  none\r
+ */\r
+void DRV_DSP_RawdataTransform(GU32 *punRawdata);\r
+\r
+/**\r
+ * @fn     GU8 GH3X2X_GetSoftWearColor(void)\r
+ *\r
+ * @brief  GetSoftWearColor\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  SoftWearColor 0: green  1:ir\r
+ */\r
+\r
+GU8 GH3X2X_GetSoftWearColor(void);\r
+void GH3X2X_SetConfigDrvEcode(const STGh3x2xInitConfig *pstGh3x2xInitConfigParam);\r
+void GH3X2X_SetDrvEcode(GS8 chECode);\r
+\r
+#if (GH3X2X_FIFO_MONITOR_EN&(__GH3X2X_INTERFACE__ == __GH3X2X_INTERFACE_I2C__))\r
+void Gh3x2xFifoMonitorInit(STGh3x2xFifoMonitorInfo *pstMonitorInfo);\r
+void Gh3x2xFifoMonitorPro(STGh3x2xFifoMonitorInfo *pstMonitorInfo, GU8 *pFifo, GU16 FifoByteNum);\r
+#endif\r
+\r
+#endif /* _GH3X2X_DRV_CONTROL_H_ */\r
+\r
+/********END OF FILE********* Copyright (c) 2003 - 2022, Goodix Co., Ltd. ********/\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/driver/inc/gh_drv_dump.h b/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/driver/inc/gh_drv_dump.h
new file mode 100644 (file)
index 0000000..ee4c8d1
--- /dev/null
@@ -0,0 +1,463 @@
+/**\r
+ * @copyright (c) 2003 - 2022, Goodix Co., Ltd. All rights reserved.\r
+ *\r
+ * @file    gh3x2x_drv_dump.h\r
+ *\r
+ * @brief   gh3x2x dump data define & declaration\r
+ *\r
+ * @version ref gh3x2x_drv_version.h\r
+ *\r
+ */\r
+\r
+#ifndef _GH3X2X_DRV_DUMP_H_\r
+#define _GH3X2X_DRV_DUMP_H_\r
+\r
+\r
+#include "gh_drv_config.h"\r
+#include "gh_drv.h"\r
+\r
+\r
+typedef struct\r
+{\r
+    GU8 uchAddrOffset;\r
+    GU8 uchMsb;\r
+    GU8 uchLsb;\r
+} STGh3x2xAgcReg;\r
+\r
+\r
+\r
+/**\r
+ * @brief dump data bg lvl select enum\r
+ */\r
+enum EMGh3x2xDumpRawdataBgLvlSelect\r
+{\r
+    GH3X2X_DUMP_RAWDATA_BGLVL0 = 0,         /**< dump rawdata bg 0 lvl */\r
+    GH3X2X_DUMP_RAWDATA_BGLVL1,             /**< dump rawdata bg 1 lvl */\r
+    GH3X2X_DUMP_RAWDATA_BGLVL2,             /**< dump rawdata bg 2 lvl */\r
+    GH3X2X_DUMP_RAWDATA_BGLVL2X2,           /**< dump rawdata bg 2x2 lvl */\r
+};\r
+\r
+/**\r
+ * @brief channnel dump data struct type\r
+ */\r
+typedef struct\r
+{\r
+    GU32 *punPkgNoAndCurrentArr;        /**< pointer to buffer store PkgNo&current data, map e.g. ch0 ch1...chx ch0 */\r
+    GU32 *punChBgRawdataArr;            /**< pointer to buffer store channel bg data, map e.g. ch0 ch1...chx ch0 */\r
+    GU32 *punChRawdataArr;              /**< pointer to buffer store channel data, map e.g. ch0 ch1...chx ch0 */\r
+    GU16 usChRawdataCnt;                /**< channel rawdata count output */\r
+    GU32 (*punIncompleteChRawdataArr)[6];    /**< pointer to last incomplete packet buffer */\r
+    GU8  uchChIncompleteFlagArr[32];    /**< channel incomplete flag, max 32 channel */\r
+} STGh3x2xChannelDumpData;\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+/// rawdata filter array length in byte\r
+#define RAWDATA_FILTER_ARRAY_BYTE_LENGTH            (200 * GH3X2X_FIFO_RAWDATA_SIZE)\r
+\r
+/// dump data max num\r
+#define DUMP_DATA_MAX_NUM                           (6)\r
+\r
+/// max slot num\r
+#define   GH3X2X_MAX_SLOT_NUM                       (8)    \r
+\r
+/// ADC num\r
+#define   GH3X2X_ADC_NUM                            (4)\r
+\r
+/// offset of slot0 ~ slot8 regs address\r
+#define   SLOT_ADDR_OFFSET                          (0x001C)\r
+\r
+/// mask of adc0 ~ adc3 tia gain\r
+#define   GH3X2X_DRV_CURRENT_BIT_MASK               (0xFF)\r
+\r
+/// left shift bit of drv0 current in drv current data\r
+#define   GH3X2X_DRV0_CURRENT_LEFT_SHIFT_BIT_NUM    (0x0)\r
+\r
+/// left shift bit of drv1 current in drv current data\r
+#define   GH3X2X_DRV1_CURRENT_LEFT_SHIFT_BIT_NUM    (0x8)\r
+\r
+/// bit num of adc0 ~ adc3 bg cancel\r
+#define   GH3X2X_ADC_TIA_GAIN_BIT_NUM               (0x4)\r
+\r
+/// mask of adc0 ~ adc3 tia gain\r
+#define   GH3X2X_ADC_TIA_GAIN_BIT_MASK              (0xF)\r
+\r
+/// bit num of adc0 ~ adc3 bg cancel\r
+#define   GH3X2X_ADC_BG_CANCEL_BIT_NUM              (0x2)\r
+\r
+/// mask of adc0 ~ adc3 bg cancel\r
+#define   GH3X2X_ADC_BG_CANCEL_BIT_MASK             (0x3)\r
+\r
+/// left shift bit of gain in gain&bgcancel data\r
+#define   GH3X2X_ADC_TIA_GAIN_LEFT_SHIFT_BIT_NUM    (0x0)\r
+\r
+/// left shift bit of bg cancel in gain&bgcancel data\r
+#define   GH3X2X_ADC_BG_CANCEL_LEFT_SHIFT_BIT_NUM   (0x4)\r
+\r
+/// mask of slot bg level\r
+#define   GH3X2X_SLOT_BG_LEVEL_BIT_MASK             (0x03)    \r
+\r
+/// dump data offset\r
+#define   GH3X2X_DUMP_DATA_OFFSET                   (8388608)\r
+\r
+/// max dump data num of every channel\r
+#define   GH3X2X_MAX_DUMP_DATA_NUM_CHANNEL          (4)  \r
+\r
+/// max dump data num of every channel that will upload\r
+#define   GH3X2X_MAX_DUMP_DATA_NUM_UPLOAD           (3)  \r
+\r
+/// dump gain & current enable\r
+#define   GH3X2X_DUMP_GAIN_CURRENT_ENABLE_BIT       (0)      \r
+\r
+/// dump ambiance enable\r
+#define   GH3X2X_DUMP_AMBIANCE_ENABLE_BIT           (1)\r
+\r
+/// dump electrode wear enable\r
+#define   GH3X2X_DUMP_ELECTR_WEAR_ENABLE_BIT        (2)\r
+\r
+/// ECG enable bit\r
+#define   GH3X2X_ECG_ENABLE_BIT                     (0x1)\r
+\r
+/// ECG ADC index\r
+#define   GH3X2X_ECG_ADC_INDEX                      (0x3)\r
+\r
+/// dump electrode wear status bit field\r
+#define   GH3X2X_ELECTR_WEAR_STATUS_BIT_FIELD       (0x1)\r
+\r
+/// dump electrode wear status bit in data tag of rawdata\r
+#define   GH3X2X_ELECTR_WEAR_STATUS_BIT_IN_DATA_TAG (0x1)\r
+\r
+/// dump data ppg index in buffer after filter\r
+#define   GH3X2X_DUMP_DATA_PPG_INDEX                (0)\r
+\r
+/// dump data gain current index in buffer after filter\r
+#define   GH3X2X_DUMP_DATA_GAIN_CURRENT_INDEX       (1)\r
+\r
+/// dump data ambiance index in buffer after filter\r
+#define   GH3X2X_DUMP_DATA_AMBIANCE_INDEX           (2)\r
+\r
+/// gain & current data size\r
+#define   GH3X2X_DUMP_GAIN_CURRENT_DATA_SIZE        (4)\r
+\r
+/// ambiance data size\r
+#define   GH3X2X_DUMP_AMBIANCE_DATA_SIZE            (3)\r
+\r
+/// gain & current data calc\r
+#define   GH3X2X_DUMP_GAIN_CURRENT_CALC(x)          ((x) * GH3X2X_DUMP_GAIN_CURRENT_DATA_SIZE)\r
+\r
+/// ambiance data calc\r
+#define   GH3X2X_DUMP_AMBIANCE_CALC(x)              ((x) * GH3X2X_DUMP_AMBIANCE_DATA_SIZE)\r
+\r
+/// gain value in dump data\r
+#define DUMP_GAIN(x)      ((((GU8*)(&(x)))[1]) >> 4)\r
+\r
+/// current0 in dump data\r
+#define DUMP_CUREENT0(x)   (((GU8*)(&(x)))[3])\r
+\r
+/// current1 in dump data\r
+#define DUMP_CUREENT1(x)   (((GU8*)(&(x)))[2])\r
+\r
+/// PPG data in dump data\r
+#define DUMP_PPG_DATA(x)   ((((GU32)(((GU8*)(&(x)))[1])) << 16) + (((GU32)(((GU8*)(&(x)))[2])) << 8)\\r
+                                                                    + (((GU32)(((GU8*)(&(x)))[3])) << 0))\r
+\r
+/// current data index in raw data buf\r
+extern GU16 g_usGh3x2xDataIndexInBuf;\r
+\r
+/// current data index in raw data buf of every channel\r
+extern GU16 g_usRawdataByteIndexArr[];\r
+\r
+/// packet payload\r
+//extern GU8 g_uchPacketPayloadArr[];\r
+\r
+/// current data index in raw data buf\r
+extern GF32 g_fGsDataIndexInBuf;\r
+\r
+/// packet max len support\r
+extern GU8 g_uchPacketMaxLenSupport;\r
+\r
+/// function started bitmap, use for sampling control\r
+extern GU32 g_unFuncStartedBitmap;\r
+\r
+//save bg cancel value of every channel\r
+extern GU8  g_puchGainBgCancelRecord[];\r
+\r
+//save current of drv0 and drv1\r
+extern STGh3x2xAgcInfo *g_pstGh3x2xAgcInfo;\r
+\r
+/**\r
+ * @fn     void GH3X2X_DumpInit(void)\r
+ *\r
+ * @brief  init dump moudle\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_DumpInit(void);\r
+\r
+/**\r
+ * @fn     void GH3X2X_DumpModeSet(GU16 usRegVal)\r
+ *\r
+ * @brief  set dump mode\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   usRegVal          reg value\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_DumpModeSet(GU16 usRegVal);\r
+\r
+/**\r
+ * @fn     GU16 GH3X2X_DumpModeGet(void)\r
+ *\r
+ * @brief  get dump mode\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  dump mode\r
+ */\r
+GU16 GH3X2X_DumpModeGet(void);\r
+\r
+/**\r
+ * @fn     void GH3X2X_BgLevelSet(GU16 usRegVal)\r
+ *\r
+ * @brief  set bg level of every slot\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   usRegVal          reg value\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_BgLevelSet(GU16 usRegVal);\r
+\r
+/**\r
+ * @fn     void GH3X2X_RecordDumpData(void)\r
+ *\r
+ * @brief  read some dump data, and save them\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_RecordDumpData(void);\r
+\r
+/**\r
+ * @fn     void GH3X2X_ReadElectrodeWearDumpData(void)\r
+ *\r
+ * @brief  read eletrode wear status\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  dump mode\r
+ */\r
+void GH3X2X_ReadElectrodeWearDumpData(void);\r
+\r
+/**\r
+ * @fn     void GH3X2X_BgLevelDecode(GU8 puchBgLvArr[], GU8 uchChannelCnt, GU8 *puchChannelMapArray, GU16 usBgLevel)\r
+ *\r
+ * @brief  decode function's bg level array according to channel map and slot bg level\r
+ *\r
+ * @attention   if there is 2x2 bg level,set the first slot to level 2\r
+ *\r
+ * @param[in]   uchChannelCnt                channel cnt\r
+ * @param[in]   puchChannelMapArray          channel map array\r
+ * @param[in]   usBgLevel                    bg level of slot\r
+ * @param[out]  puchBgLvArr                  bg level array\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_BgLevelDecode(GU8 puchBgLvArr[], GU8 uchChannelCnt, GU8 *puchChannelMapArray, GU16 usBgLevel);\r
+\r
+/**\r
+ * @fn     GS8 GH3X2X_GetDumpDataInfo(GF32 *pfGsFloatIncVal, GU16 *pusChannelDataCnt,\r
+ *                                    GU8 *puchNextIncompleteFlag,GU8 *puchDumpDataIndexArr,\r
+ *                                    GU8 *puchIncompleteFlagArr, GU16 usFifoLength, GU8 *puchDataBuffer,\r
+ *                                    GU8 uchChannelCnt, GU8 *puchChannelMapArray, GU8 *puchChannelBgLvlArr, \r
+ *                                    GU16 usReadGsensorArrCnt)\r
+ *\r
+ * @brief  Get information from rawdata\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[out]  pfGsFloatIncVal             pointer to gsensor inc value output\r
+ * @param[out]  pusChannelDataCnt           pointer to slot data cnt output\r
+ * @param[out]  puchNextIncompleteFlag      pointer to next incomplete flag arr output\r
+ * @param[out]  puchDumpDataIndexArr        pointer to dump data index output\r
+ * @param[in]   puchIncompleteFlagArr       incomplete flag array of last rawdata frame\r
+ * @param[in]   usFifoLength                read fifo buffer data len\r
+ * @param[in]   puchDataBuffer              pointer to read fifo buffer\r
+ * @param[in]   uchChannelCnt               channel map arr cnt\r
+ * @param[in]   puchChannelMapArray         pointer to channel map arr\r
+ * @param[in]   puchChannelBgLvlArr         pointer to bg lvl arr\r
+ * @param[in]   usReadGsensorArrCnt         read gsensor array cnt\r
+ *\r
+ * @return  error code\r
+ * @retval  #GH3X2X_RET_OK               return successfully\r
+ * @retval  #GH3X2X_RET_GENERIC_ERROR    generic error when size is 0\r
+ * @retval  #GH3X2X_RET_RESOURCE_ERROR   resource error when doesn't correspond to channel map\r
+ */\r
+GS8 GH3X2X_GetDumpDataInfo(GF32 *pfGsFloatIncVal, GU16 *pusChannelDataCnt,\r
+                            GU8 *puchNextIncompleteFlag, GU8 *puchDumpDataIndexArr,\r
+                            GU8 *puchIncompleteFlagArr, GU16 usFifoLength, GU8 *puchDataBuffer,\r
+                            GU8 uchChannelCnt, GU8 *puchChannelMapArray, GU8 *puchChannelBgLvlArr, \r
+                            GU16 usReadGsensorArrCnt);\r
+\r
+/**\r
+ * @fn     GS8 GH3X2X_UnpackDumpDataWithChannelMap(STGh3x2xChannelDumpData *pstGh3x2xChannelDumpData,\r
+ *                    GU8 *puchReadRawdataBuffer, GU16 usReadRawdataLen, GU8 uchChannelMapCnt, GU8 *puchChannelMapArr,\r
+ *                    GU8 *puchChannelBgLvlArr)\r
+ *\r
+ * @brief  Unpack to channel dump data from read fifo data buffer;\r
+ *         if dump data incomplete, should change fifo watermark\r
+ *\r
+ * @attention   This function should use in get rawdata hook\r
+ * \r
+ * @param[in]   puchReadRawdataBuffer           pointer to read data buffer\r
+ * @param[in]   usReadRawdataLen                read data length\r
+ * @param[in]   uchChannelMapCnt                channel map array cnt, max:32\r
+ * @param[in]   puchChannelMapArr               pointer to channel map array\r
+ * @param[in]   puchChannelBgLvlArr             pointer to channel lvl array, @ref EMGh3x2xDumpRawdataBgLvlSelect\r
+ * @param[out]  pstGh3x2xChannelDumpData        pointer to channel rawdata struct\r
+ *\r
+ * @return  error code\r
+ * @retval  #GH3X2X_RET_OK                      return successfully\r
+ * @retval  #GH3X2X_RET_PARAMETER_ERROR         return param error\r
+ */\r
+GS8 GH3X2X_UnpackDumpDataWithChannelMap(STGh3x2xChannelDumpData *pstGh3x2xChannelDumpData,\r
+                    GU8 *puchReadRawdataBuffer, GU16 usReadRawdataLen, GU8 uchChannelMapCnt, GU8 *puchChannelMapArr,\r
+                    GU8 *puchChannelBgLvlArr);\r
+\r
+/**\r
+ * @fn     GS16 GH3X2X_GetDumpdataWithChannelMap(STGh3x2xChannelDumpData *pstGh3x2xChannelDumpData, \r
+ *                       GU8 *puchReadRawdataBuffer, GU8 uchChannelMapCnt, GU8 *puchChannelMapArr, GU8 *puchBglvlArr)\r
+ *\r
+ * @brief  Get dump data from fifo with channel map\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   puchReadRawdataBuffer       pointer to read data buffer\r
+ * @param[in]   uchChannelMapCnt            channel map array cnt, max:32\r
+ * @param[in]   puchChannelMapArr           pointer to channel map array\r
+ * @param[in]   puchBglvlArr                pointer to bg lvl array, @ref EMGh3x2xDumpRawdataBgLvlSelect\r
+ * @param[out]  pstGh3x2xChannelDumpData    pointer to channel rawdata struct output\r
+ *\r
+ * @return  GH3X2X_RET_OK                       return get data successful\r
+ * @retval  #GH3X2X_RET_PARAMETER_ERROR         return param error\r
+ * @retval  #GH3X2X_RET_READ_FIFO_CONTINUE      return fifo is not empty\r
+ */\r
+GS16 GH3X2X_GetDumpdataWithChannelMap(STGh3x2xChannelDumpData *pstGh3x2xChannelDumpData, \r
+                        GU8 *puchReadRawdataBuffer, GU8 uchChannelMapCnt, GU8 *puchChannelMapArr, GU8 *puchBglvlArr);\r
+\r
+/**\r
+ * @fn     GS8 GH3X2X_ChannelMapDumpDataClear(STGh3x2xChannelDumpData *pstGh3x2xChannelDumpData)\r
+ *\r
+ * @brief  clear channel map dump data struct\r
+ *\r
+ * @attention   This function must use before get dump data by one kind channel map\r
+ *              e.g. channel map start/stop need clear\r
+ *\r
+ * @param[in]   pstGh3x2xChannelDumpData     pointer to channel dump data struct\r
+ * @param[out]  None\r
+ *\r
+ * @return  error code\r
+ * @retval  #GH3X2X_RET_OK                      return successfully\r
+ * @retval  #GH3X2X_RET_PARAMETER_ERROR         return param error\r
+ */\r
+GS8 GH3X2X_ChannelMapDumpDataClear(STGh3x2xChannelDumpData *pstGh3x2xChannelDumpData);\r
+\r
+/**\r
+ * @fn       void GH3X2X_ElectrWearDumpDataPro(GU8* puchRawdataTag, GU8 uchChMapIndex)\r
+ *\r
+ * @brief    electrode wear dump data pro\r
+ *\r
+ * @attention    None\r
+ *\r
+ * @param[in]    puchRawdataTag      data tag of rawdata\r
+ * @param[in]    uchChMapIndex       channel map index\r
+ * @param[out]   None\r
+ *\r
+ * @return    None\r
+ */\r
+void GH3X2X_ElectrWearDumpDataPro(GU8* puchRawdataTag, GU8 uchChMapIndex);\r
+\r
+/**\r
+ * @fn       GS8 GH3X2X_SendSpo2DumpDataPkg(GU8 *puchRespondBuffer, GU16 *pusRespondLen, GU8 *puchFifoRawdata,\r
+                                            GS32 nAlgoResultArr[], STGsensorRawdata *pstGsAxisValueArr,\r
+                                            GU16 usGsDataNum, EMGsensorSensitivity emGsSensitivity)\r
+ *                    \r
+ * @brief  pack GH3X2X hb rawdata and other type of data according to specific protocol\r
+ *\r
+ * @attention    None\r
+ *\r
+ * @param[out]    puchRespondBuffer        pointer to frame data package\r
+ * @param[out]    pusRespondLen            pointer to data length of package\r
+ * @param[in]     puchFifoRawdata          pointer to encrypted rawdata\r
+ * @param[in]     nAlgoResultArr           pointer to algorithm result\r
+ * @param[in]     pstGsAxisValueArr        pointer to g sensor data\r
+ * @param[in]     usGsDataNum              number of g sensor data\r
+ * @param[in]     emGsSensitivity          sensitivity of g sensor\r
+ *\r
+ * @return    error code\r
+ * @retval    #GH3X2X_RET_OK                       return successfully\r
+ * @retval    #GH3X2X_RET_GENERIC_ERROR            return func start error\r
+ * @retval    #GH3X2X_RET_NO_INITED_ERROR          gh3x2x has not inited\r
+ */\r
+\r
+/**\r
+ * @fn     GS8 GH3X2X_SendHbDumpDataPkg(GU8 *puchRespondBuffer, GU16 *pusRespondLen, GU8 *puchFifoRawdata,\r
+                                        GS32 nAlgoResultArr[], STGsensorRawdata *pstGsAxisValueArr,\r
+                                        GU16 usGsDataNum, EMGsensorSensitivity emGsSensitivity)\r
+ *                  \r
+ * @brief  pack GH3X2X hb rawdata and other type of data according to specific protocol\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[out]  puchRespondBuffer       pointer to frame data package\r
+ * @param[out]  pusRespondLen           pointer to data length of package\r
+ * @param[in]   puchFifoRawdata         pointer to encrypted rawdata\r
+ * @param[in]   nAlgoResultArr          pointer to algorithm result\r
+ * @param[in]   pstGsAxisValueArr       pointer to g sensor data\r
+ * @param[in]   usGsDataNum             number of g sensor data\r
+ * @param[in]   emGsSensitivity         sensitivity of g sensor\r
+ *\r
+ * @return  error code\r
+ * @retval  #GH3X2X_RET_OK                      return successfully\r
+ * @retval  #GH3X2X_RET_GENERIC_ERROR           return func start error\r
+ * @retval  #GH3X2X_RET_NO_INITED_ERROR         gh3x2x has not inited\r
+ */\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+#endif /* _GH3X2X_DRV_DUMP_H_ */\r
+\r
+/********END OF FILE********* Copyright (c) 2003 - 2022, Goodix Co., Ltd. ********/\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/driver/inc/gh_drv_interface.h b/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/driver/inc/gh_drv_interface.h
new file mode 100644 (file)
index 0000000..9784f8a
--- /dev/null
@@ -0,0 +1,118 @@
+/**\r
+ * @copyright (c) 2003 - 2022, Goodix Co., Ltd. All rights reserved.\r
+ *\r
+ * @file    gh3x2x_drv_interface.h\r
+ *\r
+ * @brief   gh3x2x interface define & declaration\r
+ *\r
+ * @version ref gh3x2x_drv_version.h\r
+ *\r
+ */\r
+\r
+#ifndef _GH3X2X_DRV_INTERFACE_H_\r
+#define _GH3X2X_DRV_INTERFACE_H_\r
+\r
+\r
+#include "gh_drv_config.h"\r
+#include "gh_drv.h"\r
+\r
+\r
+/* function ptr typedef */\r
+\r
+typedef GU8 (*pfnI2cWrite)(GU8 uchDeviceId, const GU8 uchWriteBytesArr[], GU16 usWriteLen); /**< i2c write type */\r
+typedef GU8 (*pfnI2cRead)(GU8 uchDeviceId, const GU8 uchCmddBytesArr[], GU16 usCmddLen,\r
+                          GU8 uchReadBytesArr[], GU16 usMaxReadLen);                        /**< i2c read type */\r
+typedef void (*pfnDelayUs)(GU16 usUsec);                                                    /**< delay us type */\r
+typedef GU8 (*pfnSpiRWCtrl)(GU8 uchBufferArrArr[], GU16 usLen);                             /**< spi rw type */\r
+typedef void (*pfnSpiCsCtrl)(GU8 uchCsLevel);                                               /**< spi cs ctrl type */\r
+typedef void (*pfnSendCmd)(GU8 uchCmd);                                                     /**< send cmd type */\r
+typedef void (*pfnWriteReg)(GU16 usAddr, GU16 usValue);                                     /**< write reg type */\r
+typedef GU16 (*pfnReadReg)(GU16 usAddr);                                                    /**< read reg type */\r
+typedef void (*pfnReadRegs)(GU16 usRegAddr, GU16 *pusRegValueBuffer, GU16 uchLen);           /**< read regs type */\r
+typedef void (*pfnReadFifo)(GU8 *puchDataBuffer, GU16 usLen);                               /**< read fifo type */\r
+\r
+\r
+\r
+/// i2c ctrl interface, base device addr\r
+#define   GH3X2X_I2C_DEVICE_ID_BASE         (0x28)\r
+\r
+/// spi seq write cmd val\r
+#define   GH3X2X_SPI_CMD_WRITE              (0xF0)\r
+\r
+/// spi seq read cmd val\r
+#define   GH3X2X_SPI_CMD_READ               (0xF1)\r
+\r
+/// spi cs ctrl high level val\r
+#define   GH3X2X_SPI_CS_CTRL_HIGH           (0x01)\r
+\r
+/// spi cs ctrl low level val\r
+#define   GH3X2X_SPI_CS_CTRL_LOW            (0x00)\r
+\r
+/// spi seq wait delay, 4us\r
+#define   GH3X2X_SPI_WAIT_DELAY_X_US        (4)\r
+\r
+/// spi seq end delay, 2us\r
+#define   GH3X2X_SPI_END_DELAY_X_US         (3)\r
+\r
+/// send cmd delay, 500us\r
+#define   GH3X2X_CMD_DELAY_X_US             (500)\r
+\r
+/// sleep cmd val\r
+#define   GH3X2X_CMD_SLEEP                  (0xC4)\r
+\r
+/// resume cmd val\r
+#define   GH3X2X_CMD_RESUME                 (0xC3)\r
+\r
+/// reset cmd val\r
+#define   GH3X2X_CMD_RESET                  (0xC2)\r
+\r
+/// use for delay 1us, must test in more platforms, only test in stm32f412\r
+#define   GH3X2X_DELAY_ONE_US_CNT           (9u)\r
+\r
+\r
+/**\r
+ * @fn     void GH3X2X_SwapLittleBigEndianData(GU8 *puchDataBuffer, GU16 usDataLength)\r
+ *\r
+ * @brief  Swap little big endian data\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   puchDataBuffer   pointer to data buffer.\r
+ * @param[in]   usDataLength    data buffer len.\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_SwapLittleBigEndianData(GU8 *puchDataBuffer, GU16 usDataLength);\r
+\r
+/**\r
+ * @fn     void GH3X2X_DelayUs(GU16 usUsCnt)\r
+ *\r
+ * @brief  Delay N Us for gh3x2x\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   usUsCnt     count need to delay(Us)\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_DelayUs(GU16 usUsCnt);\r
+\r
+/**\r
+ * @fn     void GH3X2X_SendCmd(GU8 uchCmd)\r
+ *\r
+ * @brief  Send cmd via i2c or spi\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   uchCmd      cmd\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_SendCmd(GU8 uchCmd);\r
+\r
+#endif /* _GH3X2X_DRV_INTERFACE_H_ */\r
+\r
+/********END OF FILE********* Copyright (c) 2003 - 2022, Goodix Co., Ltd. ********/\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/driver/inc/gh_drv_registers.h b/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/driver/inc/gh_drv_registers.h
new file mode 100644 (file)
index 0000000..0faa206
--- /dev/null
@@ -0,0 +1,460 @@
+/**\r
+ * @copyright (c) 2003 - 2022, Goodix Co., Ltd. All rights reserved.\r
+ *\r
+ * @file    gh3x2x_drv_registers.h\r
+ *\r
+ * @brief   gh3x2x driver registers define\r
+ *\r
+ * @version ref gh3x2x_drv_version.h\r
+ *\r
+ */\r
+\r
+#ifndef _GH3X2X_DRV_REGISTERS_H_\r
+#define _GH3X2X_DRV_REGISTERS_H_\r
+\r
+/* register mapping definition */\r
+\r
+// top ctrl block, start addr: 0x0000\r
+#define   GH3X2X_CARDIFF_CTRL_REG_ADDR                  (0x0000)    /**< start ctrl */\r
+#define   GH3X2X_SYSCLK_CTRL_REG_ADDR                   (0x0002)\r
+#define   GH3X2X_SYS_SAMPLE_RATE_CTRL_REG_ADDR          (0x0004)\r
+#define   GH3X2X_DATA_CTRL0_REG_ADDR                    (0x0006)\r
+#define   GH3X2X_DATA_CTRL1_REG_ADDR                    (0x0008)\r
+#define   GH3X2X_FIFO_WATERLINE_REG_ADDR                (0x000A)    /**< fifo watermark thr */\r
+#define   GH3X2X_WKUP_TMR_REG_ADDR                      (0x000E)\r
+#define   GH3X2X_ADC0_DATA_L_REG_ADDR                   (0x0010)\r
+#define   GH3X2X_ADC0_DATA_H_REG_ADDR                   (0x0012)\r
+#define   GH3X2X_ADC1_DATA_L_REG_ADDR                   (0x0014)\r
+#define   GH3X2X_ADC1_DATA_H_REG_ADDR                   (0x0016)\r
+#define   GH3X2X_ADC2_DATA_L_REG_ADDR                   (0x0018)\r
+#define   GH3X2X_ADC2_DATA_H_REG_ADDR                   (0x001A)\r
+#define   GH3X2X_ADC3_DATA_L_REG_ADDR                   (0x001C)\r
+#define   GH3X2X_ADC3_DATA_H_REG_ADDR                   (0x001E)\r
+#define   GH3X2X_PAD_CTRL0_REG_ADDR                     (0x0020)\r
+#define   GH3X2X_PAD_CTRL1_REG_ADDR                     (0x0022)\r
+#define   GH3X2X_PAD_CTRL2_REG_ADDR                     (0x0024)\r
+#define   GH3X2X_PAD_CTRL3_REG_ADDR                     (0x0026)\r
+#define   GH3X2X_PAD_CTRL4_REG_ADDR                     (0x0028)\r
+#define   GH3X2X_PAD_CTRL5_REG_ADDR                     (0x002A)\r
+#define   GH3X2X_PRODUCT_L_REG_ADDR                     (0x0030)    /**< product id l */\r
+#define   GH3X2X_PRODUCT_H_REG_ADDR                     (0x0032)    /**< product id h */\r
+#define   GH3X2X_CHIP_ID_REG_ADDR                       (0x0034)    /**< chip id */\r
+#define   GH3X2X_CHIP_READY_CODE_REG_ADDR               (0x0036)\r
+#define   GH3X2X_DYN_CKGT_CTRL_REG_ADDR                 (0x0038)\r
+#define   GH3X2X_ACCESS_READY_CODE_ADDR                 (0x0050)\r
+#define   GH3X2X_CHIP_ECG_BACKDOOR_REG_ADDR             (0x0070)\r
+#define   GH3X2X_INSTRUCTIONS_CHIP_INIED_REG_ADDR       (0x0072)    /**< reg addr 0x72:rg_chip_sw_backup. */\r
+#define   GH3X2X_CHIP_ECO_RESERVE_REG_ADDR              (0x0074)\r
+\r
+// pmu block, start addr: 0x0080\r
+#define   GH3X2X_PMU_CTRL0_REG_ADDR                     (0x0080)\r
+#define   GH3X2X_PMU_CTRL1_REG_ADDR                     (0x0082)\r
+#define   GH3X2X_PMU_CTRL2_REG_ADDR                     (0x0084)\r
+#define   GH3X2X_PMU_CTRL3_REG_ADDR                     (0x0086)\r
+#define   GH3X2X_PMU_CTRL4_REG_ADDR                     (0x0088)    /**< pmu fifo power ctrl */\r
+#define   GH3X2X_PMU_CTRL5_REG_ADDR                     (0x008A)\r
+#define   GH3X2X_PMU_CTRL6_REG_ADDR                     (0x008C)\r
+#define   GH3X2X_PMU_CTRL7_REG_ADDR                     (0x008E)\r
+#define   GH3X2X_PMU_CTRL8_REG_ADDR                     (0x0090)\r
+\r
+// timeslot block, start addr: 0x0100\r
+#define   GH3X2X_SLOT_INDEX_CTRL0_REG_ADDR              (0x0100)\r
+#define   GH3X2X_SLOT_INDEX_CTRL1_REG_ADDR              (0x0102)\r
+#define   GH3X2X_SLOT_INDEX_CTRL2_REG_ADDR              (0x0104)\r
+#define   GH3X2X_SLOT_INDEX_CTRL3_REG_ADDR              (0x0106)\r
+#define   GH3X2X_SLOT_ENABLE_CFG_REG_ADDR               (0x0108)    /**< slot enable config */\r
+#define   GH3X2X_SLOT_ENABLE_CFG_REG_LSB                (0)\r
+#define   GH3X2X_SLOT_ENABLE_CFG_REG_MSB                (7)\r
+#define   GH3X2X_SLOT_RX_EN_FIFO_EN_LSB                 (2)\r
+#define   GH3X2X_SLOT_RX_EN_FIFO_EN_MSB                 (6)\r
+#define   GH3X2X_SLOT_FIFO_EN_LSB                       (6)\r
+#define   GH3X2X_SLOT_FIFO_EN_MSB                       (6)\r
+#define   GH3X2X_SLOT_CTRL_ADDR_INTERVAL                (0x1C)\r
+#define   GH3X2X_SLOT_SR_MULTIPLIER_LSB                 (8)\r
+#define   GH3X2X_SLOT_SR_MULTIPLIER_MSB                 (15)\r
+#define   GH3X2X_SLOT0_CTRL_0_REG_ADDR                  (0x010A)    /**< slot 0 */\r
+#define   GH3X2X_SLOT0_CTRL_1_REG_ADDR                  (0x010C)\r
+#define   GH3X2X_SLOT0_CTRL_2_REG_ADDR                  (0x010E)\r
+#define   GH3X2X_SLOT0_CTRL_3_REG_ADDR                  (0x0110)\r
+#define   GH3X2X_SLOT0_CTRL_4_REG_ADDR                  (0x0112)\r
+#define   GH3X2X_SLOT0_CTRL_5_REG_ADDR                  (0x0114)\r
+#define   GH3X2X_SLOT0_CTRL_6_REG_ADDR                  (0x0116)\r
+#define   GH3X2X_SLOT0_CTRL_7_REG_ADDR                  (0x0118)\r
+#define   GH3X2X_SLOT0_CTRL_8_REG_ADDR                  (0x011A)\r
+#define   GH3X2X_SLOT0_CTRL_9_REG_ADDR                  (0x011C)\r
+#define   GH3X2X_SLOT0_CTRL_10_REG_ADDR                 (0x011E)\r
+#define   GH3X2X_SLOT0_CTRL_11_REG_ADDR                 (0x0120)\r
+#define   GH3X2X_SLOT0_CTRL_12_REG_ADDR                 (0x0122)\r
+#define   GH3X2X_SLOT0_CTRL_13_REG_ADDR                 (0x0124)\r
+#define   GH3X2X_SLOT1_CTRL_0_REG_ADDR                  (0x0126)    /**< slot 1 */\r
+#define   GH3X2X_SLOT1_CTRL_1_REG_ADDR                  (0x0128)\r
+#define   GH3X2X_SLOT1_CTRL_2_REG_ADDR                  (0x012A)\r
+#define   GH3X2X_SLOT1_CTRL_3_REG_ADDR                  (0x012C)\r
+#define   GH3X2X_SLOT1_CTRL_4_REG_ADDR                  (0x012E)\r
+#define   GH3X2X_SLOT1_CTRL_5_REG_ADDR                  (0x0130)\r
+#define   GH3X2X_SLOT1_CTRL_6_REG_ADDR                  (0x0132)\r
+#define   GH3X2X_SLOT1_CTRL_7_REG_ADDR                  (0x0134)\r
+#define   GH3X2X_SLOT1_CTRL_8_REG_ADDR                  (0x0136)\r
+#define   GH3X2X_SLOT1_CTRL_9_REG_ADDR                  (0x0138)\r
+#define   GH3X2X_SLOT1_CTRL_10_REG_ADDR                 (0x013A)\r
+#define   GH3X2X_SLOT1_CTRL_11_REG_ADDR                 (0x013C)\r
+#define   GH3X2X_SLOT1_CTRL_12_REG_ADDR                 (0x013E)\r
+#define   GH3X2X_SLOT1_CTRL_13_REG_ADDR                 (0x0140)\r
+#define   GH3X2X_SLOT2_CTRL_0_REG_ADDR                  (0x0142)    /**< slot 2 */\r
+#define   GH3X2X_SLOT2_CTRL_1_REG_ADDR                  (0x0144)\r
+#define   GH3X2X_SLOT2_CTRL_2_REG_ADDR                  (0x0146)\r
+#define   GH3X2X_SLOT2_CTRL_3_REG_ADDR                  (0x0148)\r
+#define   GH3X2X_SLOT2_CTRL_4_REG_ADDR                  (0x014A)\r
+#define   GH3X2X_SLOT2_CTRL_5_REG_ADDR                  (0x014C)\r
+#define   GH3X2X_SLOT2_CTRL_6_REG_ADDR                  (0x014E)\r
+#define   GH3X2X_SLOT2_CTRL_7_REG_ADDR                  (0x0150)\r
+#define   GH3X2X_SLOT2_CTRL_8_REG_ADDR                  (0x0152)\r
+#define   GH3X2X_SLOT2_CTRL_9_REG_ADDR                  (0x0154)\r
+#define   GH3X2X_SLOT2_CTRL_10_REG_ADDR                 (0x0156)\r
+#define   GH3X2X_SLOT2_CTRL_11_REG_ADDR                 (0x0158)\r
+#define   GH3X2X_SLOT2_CTRL_12_REG_ADDR                 (0x015A)\r
+#define   GH3X2X_SLOT2_CTRL_13_REG_ADDR                 (0x015C)\r
+#define   GH3X2X_SLOT3_CTRL_0_REG_ADDR                  (0x015E)    /**< slot 3 */\r
+#define   GH3X2X_SLOT3_CTRL_1_REG_ADDR                  (0x0160)\r
+#define   GH3X2X_SLOT3_CTRL_2_REG_ADDR                  (0x0162)\r
+#define   GH3X2X_SLOT3_CTRL_3_REG_ADDR                  (0x0164)\r
+#define   GH3X2X_SLOT3_CTRL_4_REG_ADDR                  (0x0166)\r
+#define   GH3X2X_SLOT3_CTRL_5_REG_ADDR                  (0x0168)\r
+#define   GH3X2X_SLOT3_CTRL_6_REG_ADDR                  (0x016A)\r
+#define   GH3X2X_SLOT3_CTRL_7_REG_ADDR                  (0x016C)\r
+#define   GH3X2X_SLOT3_CTRL_8_REG_ADDR                  (0x016E)\r
+#define   GH3X2X_SLOT3_CTRL_9_REG_ADDR                  (0x0170)\r
+#define   GH3X2X_SLOT3_CTRL_10_REG_ADDR                 (0x0172)\r
+#define   GH3X2X_SLOT3_CTRL_11_REG_ADDR                 (0x0174)\r
+#define   GH3X2X_SLOT3_CTRL_12_REG_ADDR                 (0x0176)\r
+#define   GH3X2X_SLOT3_CTRL_13_REG_ADDR                 (0x0178)\r
+#define   GH3X2X_SLOT4_CTRL_0_REG_ADDR                  (0x017A)    /**< slot 4 */\r
+#define   GH3X2X_SLOT4_CTRL_1_REG_ADDR                  (0x017C)\r
+#define   GH3X2X_SLOT4_CTRL_2_REG_ADDR                  (0x017E)\r
+#define   GH3X2X_SLOT4_CTRL_3_REG_ADDR                  (0x0180)\r
+#define   GH3X2X_SLOT4_CTRL_4_REG_ADDR                  (0x0182)\r
+#define   GH3X2X_SLOT4_CTRL_5_REG_ADDR                  (0x0184)\r
+#define   GH3X2X_SLOT4_CTRL_6_REG_ADDR                  (0x0186)\r
+#define   GH3X2X_SLOT4_CTRL_7_REG_ADDR                  (0x0188)\r
+#define   GH3X2X_SLOT4_CTRL_8_REG_ADDR                  (0x018A)\r
+#define   GH3X2X_SLOT4_CTRL_9_REG_ADDR                  (0x018C)\r
+#define   GH3X2X_SLOT4_CTRL_10_REG_ADDR                 (0x018E)\r
+#define   GH3X2X_SLOT4_CTRL_11_REG_ADDR                 (0x0190)\r
+#define   GH3X2X_SLOT4_CTRL_12_REG_ADDR                 (0x0192)\r
+#define   GH3X2X_SLOT4_CTRL_13_REG_ADDR                 (0x0194)\r
+#define   GH3X2X_SLOT5_CTRL_0_REG_ADDR                  (0x0196)    /**< slot 5 */\r
+#define   GH3X2X_SLOT5_CTRL_1_REG_ADDR                  (0x0198)\r
+#define   GH3X2X_SLOT5_CTRL_2_REG_ADDR                  (0x019A)\r
+#define   GH3X2X_SLOT5_CTRL_3_REG_ADDR                  (0x019C)\r
+#define   GH3X2X_SLOT5_CTRL_4_REG_ADDR                  (0x019E)\r
+#define   GH3X2X_SLOT5_CTRL_5_REG_ADDR                  (0x01A0)\r
+#define   GH3X2X_SLOT5_CTRL_6_REG_ADDR                  (0x01A2)\r
+#define   GH3X2X_SLOT5_CTRL_7_REG_ADDR                  (0x01A4)\r
+#define   GH3X2X_SLOT5_CTRL_8_REG_ADDR                  (0x01A6)\r
+#define   GH3X2X_SLOT5_CTRL_9_REG_ADDR                  (0x01A8)\r
+#define   GH3X2X_SLOT5_CTRL_10_REG_ADDR                 (0x01AA)\r
+#define   GH3X2X_SLOT5_CTRL_11_REG_ADDR                 (0x01AC)\r
+#define   GH3X2X_SLOT5_CTRL_12_REG_ADDR                 (0x01AE)\r
+#define   GH3X2X_SLOT5_CTRL_13_REG_ADDR                 (0x01B0)\r
+#define   GH3X2X_SLOT6_CTRL_0_REG_ADDR                  (0x01B2)    /**< slot 6 */\r
+#define   GH3X2X_SLOT6_CTRL_1_REG_ADDR                  (0x01B4)\r
+#define   GH3X2X_SLOT6_CTRL_2_REG_ADDR                  (0x01B6)\r
+#define   GH3X2X_SLOT6_CTRL_3_REG_ADDR                  (0x01B8)\r
+#define   GH3X2X_SLOT6_CTRL_4_REG_ADDR                  (0x01BA)\r
+#define   GH3X2X_SLOT6_CTRL_5_REG_ADDR                  (0x01BC)\r
+#define   GH3X2X_SLOT6_CTRL_6_REG_ADDR                  (0x01BE)\r
+#define   GH3X2X_SLOT6_CTRL_7_REG_ADDR                  (0x01C0)\r
+#define   GH3X2X_SLOT6_CTRL_8_REG_ADDR                  (0x01C2)\r
+#define   GH3X2X_SLOT6_CTRL_9_REG_ADDR                  (0x01C4)\r
+#define   GH3X2X_SLOT6_CTRL_10_REG_ADDR                 (0x01C6)\r
+#define   GH3X2X_SLOT6_CTRL_11_REG_ADDR                 (0x01C8)\r
+#define   GH3X2X_SLOT6_CTRL_12_REG_ADDR                 (0x01CA)\r
+#define   GH3X2X_SLOT6_CTRL_13_REG_ADDR                 (0x01CC)\r
+#define   GH3X2X_SLOT7_CTRL_0_REG_ADDR                  (0x01CE)    /**< slot 7 */\r
+#define   GH3X2X_SLOT7_CTRL_1_REG_ADDR                  (0x01D0)\r
+#define   GH3X2X_SLOT7_CTRL_2_REG_ADDR                  (0x01D2)\r
+#define   GH3X2X_SLOT7_CTRL_3_REG_ADDR                  (0x01D4)\r
+#define   GH3X2X_SLOT7_CTRL_4_REG_ADDR                  (0x01D6)\r
+#define   GH3X2X_SLOT7_CTRL_5_REG_ADDR                  (0x01D8)\r
+#define   GH3X2X_SLOT7_CTRL_6_REG_ADDR                  (0x01DA)\r
+#define   GH3X2X_SLOT7_CTRL_7_REG_ADDR                  (0x01DC)\r
+#define   GH3X2X_SLOT7_CTRL_8_REG_ADDR                  (0x01DE)\r
+#define   GH3X2X_SLOT7_CTRL_9_REG_ADDR                  (0x01E0)\r
+#define   GH3X2X_SLOT7_CTRL_10_REG_ADDR                 (0x01E2)\r
+#define   GH3X2X_SLOT7_CTRL_11_REG_ADDR                 (0x01E4)\r
+#define   GH3X2X_SLOT7_CTRL_12_REG_ADDR                 (0x01E6)\r
+#define   GH3X2X_SLOT7_CTRL_13_REG_ADDR                 (0x01E8)\r
+#define   GH3X2X_ECG_CTRL_REG_ADDR                      (0x01EA)\r
+#define   GH3X2X_RG_SLOT_TMR0_REG_ADDR                  (0x01EC)\r
+#define   GH3X2X_RG_SLOT_TMR1_REG_ADDR                  (0x01EE)\r
+#define   GH3X2X_RG_SLOT_TMR2_REG_ADDR                  (0x01F0)\r
+#define   GH3X2X_RG_SLOT_TMR3_REG_ADDR                  (0x01F2)\r
+#define   GH3X2X_RG_SLOT_TMR4_REG_ADDR                  (0x01F4)\r
+#define   GH3X2X_RG_SLOT_TMR5_REG_ADDR                  (0x01F6)\r
+#define   GH3X2X_RG_SLOT_TMR6_REG_ADDR                  (0x01F8)\r
+#define   GH3X2X_RG_SLOT_TMR7_REG_ADDR                  (0x01FA)\r
+\r
+// afe_top block, start addr: 0x0200\r
+#define   GH3X2X_AFE_REG0_REG_ADDR                      (0x0200)\r
+#define   GH3X2X_AFE_REG1_REG_ADDR                      (0x0202)\r
+#define   GH3X2X_AFE_REG2_REG_ADDR                      (0x0204)\r
+#define   GH3X2X_AFE_REG3_REG_ADDR                      (0x0206)\r
+#define   GH3X2X_AFE_REG4_REG_ADDR                      (0x0208)\r
+#define   GH3X2X_AFE_REG5_REG_ADDR                      (0x020A)\r
+#define   GH3X2X_AFE_REG6_REG_ADDR                      (0x020C)\r
+#define   GH3X2X_AFE_REG7_REG_ADDR                      (0x020E)\r
+#define   GH3X2X_AFE_REG8_REG_ADDR                      (0x0210)\r
+#define   GH3X2X_AFE_REG9_REG_ADDR                      (0x0212)\r
+#define   GH3X2X_AFE_REG10_REG_ADDR                     (0x0214)\r
+\r
+// led_agc block, start addr: 0x0280\r
+#define   GH3X2X_LED_AGC_CTRL0_REG_ADDR                 (0x0280)\r
+#define   GH3X2X_LED_AGC_CTRL1_REG_ADDR                 (0x0282)\r
+#define   GH3X2X_LED_AGC_CTRL2_REG_ADDR                 (0x0284)\r
+#define   GH3X2X_LED_AGC_CTRL3_REG_ADDR                 (0x0286)\r
+#define   GH3X2X_LED_AGC_CTRL4_REG_ADDR                 (0x0288)\r
+#define   GH3X2X_LED_AGC_CTRL5_REG_ADDR                 (0x028A)\r
+#define   GH3X2X_LED_AGC_CTRL6_REG_ADDR                 (0x028C)\r
+#define   GH3X2X_LED_AGC_CTRL7_REG_ADDR                 (0x028E)\r
+#define   GH3X2X_LED_AGC_CTRL8_REG_ADDR                 (0x0290)\r
+#define   GH3X2X_LED_AGC_CTRL9_REG_ADDR                 (0x0292)\r
+\r
+// decimation block, start addr: 0x0300\r
+#define   GH3X2X_DCMT_CTRL0_REG_ADDR                    (0x0300)\r
+#define   GH3X2X_DCMT_CTRL1_REG_ADDR                    (0x0302)\r
+#define   GH3X2X_DCMT_CTRL2_REG_ADDR                    (0x0304)\r
+#define   GH3X2X_DCMT_CTRL3_REG_ADDR                    (0x0306)\r
+#define   GH3X2X_DCMT_CTRL4_REG_ADDR                    (0x0308)\r
+#define   GH3X2X_DCMT_CTRL5_REG_ADDR                    (0x030A)\r
+#define   GH3X2X_DCMT_CTRL6_REG_ADDR                    (0x030C)\r
+#define   GH3X2X_DCMT_CTRL7_REG_ADDR                    (0x0310)\r
+#define   GH3X2X_DCMT_CTRL8_REG_ADDR                    (0x0312)\r
+\r
+\r
+#define GH3X2X_DCMT_EN_LSB  (0)\r
+#define GH3X2X_DCMT_EN_MSB  (7)\r
+#define GH3X2X_DCMT_DNSAMPLE_DIS_LSB  (8)\r
+#define GH3X2X_DCMT_DNSAMPLE_DIS_MSB  (15)\r
+#define GH3X2X_DCMT_HEAD_LSB  (0)\r
+#define GH3X2X_DCMT_HEAD_MSB  (4)\r
+#define GH3X2X_DCMT_RND_SEL_LSB  (8)\r
+#define GH3X2X_DCMT_RND_SEL_MSB  (9)\r
+\r
+\r
+// spi_i2c block, start addr: 0x0380\r
+#define   GH3X2X_SPI_CTRL0_REG_ADDR                     (0x0380)\r
+\r
+// adt block, start addr: 0x0400\r
+#define   GH3X2X_ADT_LEADON_CR_REG_ADDR                 (0x0400)\r
+#define   GH3X2X_ADT_LEADON_TR_REG_ADDR                 (0x0402)\r
+#define   GH3X2X_ADT_LEADON_PR_REG_ADDR                 (0x0404)\r
+#define   GH3X2X_ADT_LEADON_PR1_REG_ADDR                (0x0406)\r
+#define   GH3X2X_ADT_WEARON_CR_REG_ADDR                 (0x0408)\r
+#define   GH3X2X_ADT_WEARON1_THU_L_REG_ADDR             (0x0410)\r
+#define   GH3X2X_ADT_WEARON1_THU_H_REG_ADDR             (0x0412)\r
+#define   GH3X2X_ADT_WEARON1_THD_L_REG_ADDR             (0x0414)\r
+#define   GH3X2X_ADT_WEARON1_THD_H_REG_ADDR             (0x0416)\r
+#define   GH3X2X_ADT_WEARON2_THU_L_REG_ADDR             (0x0418)\r
+#define   GH3X2X_ADT_WEARON2_THU_H_REG_ADDR             (0x041A)\r
+#define   GH3X2X_ADT_WEARON2_THD_L_REG_ADDR             (0x041C)\r
+#define   GH3X2X_ADT_WEARON2_THD_H_REG_ADDR             (0x041E)\r
+#define   GH3X2X_ADT_LEADON_CR2_REG_ADDR                (0x0420)\r
+#define   GH3X2X_ADT_WEARON_PR_REG_ADDR                 (0x0422)\r
+#define   GH3X2X_ADT_WEARON_CONFIRM_TIME_REG_ADDR       (0x0424)\r
+#define   GH3X2X_ADT_WEARON_LOGIC_SEL_REG_ADDR          (0x0426)\r
+#define   GH3X2X_ADT_WEAROFF_LOGIC_SEL_REG_ADDR         (0x0428)\r
+#define   GH3X2X_ADT_LEADON_STR_REG_ADDR                (0x042A)\r
+\r
+// ecg_recovery block, start addr: 0x0480\r
+#define   GH3X2X_ECG_RECOVERY_CR_REG_ADDR               (0x0480)\r
+#define   GH3X2X_ECG_RECOVERY_DMCR_REG_ADDR             (0x0482)\r
+\r
+// int_ctrl block, start addr: 0x0500\r
+#define   GH3X2X_INT_CR_REG_ADDR                        (0x0500)\r
+#define   GH3X2X_INT_CR2_REG_ADDR                       (0x0502)\r
+#define   GH3X2X_INT_PWR_REG_ADDR                       (0x0504)\r
+#define   GH3X2X_INT_CTR_REG_ADDR                       (0x0506)\r
+#define   GH3X2X_INT_STR_REG_ADDR                       (0x0508)\r
+//#define   GH3X2X_INT_FIFO_UR_REG_ADDR                   (0x050A)     /**< fifo use cnt */\r
+#define   GH3X2X_INT_STR2_REG_ADDR                      (0x050C)\r
+\r
+// osc_cal block, start addr: 0x0580\r
+#define   GH3X2X_OSC_CR_REG_ADDR                        (0x0580)\r
+#define   GH3X2X_OSC_THR_REG_ADDR                       (0x0582)\r
+#define   GH3X2X_OSC13M_TUNE_REG_ADDR                   (0x0584)\r
+#define   GH3X2X_OSC32K_TUNE_REG_ADDR                   (0x0586)\r
+#define   GH3X2X_OSC32K_TEMP_REG_ADDR                   (0x0588)\r
+#define   GH3X2X_OSC_FREQ_ERR_UR_REG_ADDR               (0x058A)\r
+#define   GH3X2X_OSC_FLAG_REG_ADDR                      (0x058C)\r
+\r
+// skin_color block, start addr: 0x0600\r
+#define   GH3X2X_SKIN_BLR_REG_ADDR                      (0x0600)\r
+#define   GH3X2X_SKIN_BHR_REG_ADDR                      (0x0602)\r
+#define   GH3X2X_SKIN_YLR_REG_ADDR                      (0x0604)\r
+#define   GH3X2X_SKIN_YHR_REG_ADDR                      (0x0606)\r
+#define   GH3X2X_SKIN_FLR_REG_ADDR                      (0x0608)\r
+#define   GH3X2X_SKIN_FHR_REG_ADDR                      (0x060A)\r
+#define   GH3X2X_SKIN_CR_REG_ADDR                       (0x060C)\r
+#define   GH3X2X_SKIN_STR_REG_ADDR                      (0x060E)\r
+\r
+// sys_afe block, start addr: 0x0680\r
+#define   GH3X2X_PPG_TIA_AD_REG_REG_ADDR                (0x0680)\r
+#define   GH3X2X_PPG_DAC_AD_REG0_REG_ADDR               (0x0682)\r
+#define   GH3X2X_PPG_DAC_AD_REG1_REG_ADDR               (0x0684)\r
+#define   GH3X2X_PPG_DAC_AD_REG2_REG_ADDR               (0x0686)\r
+#define   GH3X2X_PPG_DAC_AD_REG3_REG_ADDR               (0x0688)\r
+#define   GH3X2X_PPG_ADC_AD_REG_REG_ADDR                (0x0690)\r
+#define   GH3X2X_LED_DRV_AD_REG_REG_ADDR                (0x0692)\r
+#define   GH3X2X_ECG_IA_AD_REG_REG_ADDR                 (0x0694)\r
+#define   GH3X2X_ECG_IA_AD_REG1_REG_ADDR                (0x0696)\r
+#define   GH3X2X_ECG_IA_AD_REG2_REG_ADDR                (0x0698)\r
+#define   GH3X2X_ECG_IA_AD_REG3_REG_ADDR                (0x069A)\r
+#define   GH3X2X_ECG_IA_AD_REG4_REG_ADDR                (0x069C)\r
+#define   GH3X2X_ECG_IA_AD_REG5_REG_ADDR                (0x06A0)\r
+#define   GH3X2X_ECG_IA_AD_REG6_REG_ADDR                (0x06A2)\r
+#define   GH3X2X_SYS_AFE_REG0_REG_ADDR                  (0x06B0)\r
+#define   GH3X2X_SYS_AD_REG_REG_ADDR                    (0x06B2)\r
+\r
+// efuse_ctrl block, start addr: 0x0700\r
+#define   GH3X2X_EFUSE_CTRL_CMD_REG_ADDR                (0x0700)\r
+#define   GH3X2X_EFUSE_CTRL_PASSWORD_REG_ADDR           (0x0702)\r
+#define   GH3X2X_EFUSE_CTRL_TIMING_CFG_0_REG_ADDR       (0x0704)\r
+#define   GH3X2X_EFUSE_CTRL_TIMING_CFG_1_REG_ADDR       (0x0706)\r
+#define   GH3X2X_EFUSE_CTRL_WDATA_0_REG_ADDR            (0x0708)\r
+#define   GH3X2X_EFUSE_CTRL_WDATA_1_REG_ADDR            (0x070A)\r
+#define   GH3X2X_EFUSE_CTRL_WDATA_2_REG_ADDR            (0x070C)\r
+#define   GH3X2X_EFUSE_CTRL_WDATA_3_REG_ADDR            (0x070E)\r
+#define   GH3X2X_EFUSE_CTRL_RDATA_0_REG_ADDR            (0x0710)\r
+#define   GH3X2X_EFUSE_CTRL_RDATA_1_REG_ADDR            (0x0712)\r
+#define   GH3X2X_EFUSE_CTRL_RDATA_2_REG_ADDR            (0x0714)\r
+#define   GH3X2X_EFUSE_CTRL_RDATA_3_REG_ADDR            (0x0716)\r
+#define   GH3X2X_EFUSE_CTRL_STATUS_REG_ADDR             (0x0718)\r
+#define   GH3X2X_EFUSE_CTRL_REG_MODE_REG_ADDR           (0x071A)\r
+#define   GH3X2X_EFUSE_CTRL_EFUSE0_AUTOLOAD_0_ADDR      (0x071C)\r
+#define   GH3X2X_EFUSE_CTRL_EFUSE0_AUTOLOAD_1_ADDR      (0x071E)\r
+#define   GH3X2X_EFUSE_CTRL_EFUSE0_AUTOLOAD_2_ADDR      (0x0720)\r
+#define   GH3X2X_EFUSE_CTRL_EFUSE0_AUTOLOAD_3_ADDR      (0x0722)\r
+#define   GH3X2X_EFUSE_CTRL_EFUSE1_AUTOLOAD_0_ADDR      (0x0724)\r
+#define   GH3X2X_EFUSE_CTRL_EFUSE1_AUTOLOAD_1_ADDR      (0x0726)\r
+#define   GH3X2X_EFUSE_CTRL_EFUSE1_AUTOLOAD_2_ADDR      (0x0728)\r
+#define   GH3X2X_EFUSE_CTRL_EFUSE1_AUTOLOAD_3_ADDR      (0x072A)\r
+#define   GH3X2X_EFUSE_CTRL_EFUSE2_AUTOLOAD_0_ADDR      (0x072C)\r
+#define   GH3X2X_EFUSE_CTRL_EFUSE2_AUTOLOAD_1_ADDR      (0x072E)\r
+#define   GH3X2X_EFUSE_CTRL_EFUSE2_AUTOLOAD_2_ADDR      (0x0730)\r
+#define   GH3X2X_EFUSE_CTRL_EFUSE2_AUTOLOAD_3_ADDR      (0x0732)\r
+\r
+// special reg addr\r
+#define   GH3X2X_FIFO_REG_ADDR                      (0xAAAA)    /**< fifo reg addr */\r
+#define   GH3X2X_I2C_CMD_ADDR                       (0xDDDD)    /**< i2c cmd reg addr */\r
+\r
+\r
+#define   GH3X2X_REG_ADDR_SIZE                      (0x0002)    /**< reg addr size */\r
+#define   GH3X2X_REG_ADDR_EVEN_FIXED                (0xFFFE)    /**< reg addr even fixed */\r
+#define   GH3X2X_REG_ADDR_MAX                       (0xFFFF)    /**< reg addr max */\r
+\r
+/* Register bit definition */ \r
+\r
+#define   GH3X2X_CARDIFF_CTRL_START_BIT             (0x0001u)   /**< start bit msk */\r
+\r
+#define   GH3X2X_CHIP_ID_REG_VAL                    (0x0011)    /**< chip id value  */\r
+#define   GH3X2X_PRODUCT_L_REG_VAL                  (0x0201)    /**< product l value */\r
+#define   GH3X2X_PRODUCT_H_REG_VAL                  (0x0301)    /**< product l value */\r
+#define   GH3X2X_CHIP_READY_REG_VAL                 (0xAA55)    /**< chip ready value */\r
+\r
+#define   GH3X2X_INT_STR_MSK_ALL_BIT                (0x7FFFu)   /**< irq status mask */\r
+#define   GH3X2X_INT_CTRL_MODE_MSK_BIT              (0x0003u)   /**< int ctrl mode bit msk */\r
+\r
+#define   GH3X2X_PMU_CTRL4_FIFO_DISABLE_MASK        (0x0003u)   /**< fifo module disable mask */\r
+\r
+#define   GH3X2X_INSTRUCTIONS_CHIP_INIED_REG_VAL    (0x0011)    /**< reg rg_chip_sw_backup bit4&bit0 set 1(0x0011) */\r
+\r
+#define   GH3X2X_SLOT_CTRL_OFFSET                   (0x001C)    /**< slot ctrl reg offset */\r
+\r
+#define   GH3X2X_ADT_WEAR_STATUS_MASK_BIT           (0x0010u)   /**< wear status bit mask */\r
+#define   GH3X2X_ADT_WEAR_DET_EN_MASK_BIT           (0x0001u)   /**< wear detect enable bit mask */\r
+#define   GH3X2X_ADT_WEAR_CR_WEAR_ON_VAL            (0x0A00u)   /**< wear detect ctrl reg wear on val! cardful ! */\r
+#define   GH3X2X_ADT_WEAR_CR_WEAR_OFF_VAL           (0x0500u)   /**< wear detect ctrl reg wear off val! cardful ! */\r
+\r
+#define   GH3X2X_SKIN_COLOR_STATUS_MASK_BIT         (0x0003u)   /**< skin color status bit mask */\r
+\r
+#define   GH3X2X_SLOT_LED_CURRENT_CLEAR_MASK        (0x00FFu)   /**< slot led current clear mask */\r
+\r
+/* utils reg macro */\r
+\r
+#define   GH3X2X_SLOT_NUM_MAX                       (8)         /**< slot num max */\r
+\r
+#define   GH3X2X_RX_NUM_MAX                         (4)\r
+\r
+#define   GH3X2X_DECIMAION_CHNL_MAX                 (8)         /** max channel number supported by decimaiton module in chip**/\r
+\r
+#define   GH3X2X_SLOT_LED_DRV_NUM_MAX               (2)         /**< slot led driver max */\r
+\r
+#define   GH3X2X_SLOT_TIA_GAIN_NUM_MAX              (4)         /**< slot tia gain num max */\r
+\r
+#define   GH3X2X_SLOT_TIA_GAIN_VAL_MAX              (13)        /**< slot tia gain val max */\r
+\r
+#define   GH3X2X_SLOT_TIA_GAIN_BITS_SIZE            (4)         /**< slot tia gain val bits size */\r
+\r
+#define   GH3X2X_SLOT_TIA_GAIN_BITS_MARK            (0x000F)    /**< slot tia gain val bits mark */\r
+\r
+#define   GH3X2X_SLOT_KDC_THR_VAL_MAX               (8)         /**< kdc thr val max */\r
+\r
+#define   GH3X2X_SLOT_KDC_THR_BITS_SIZE             (4)         /**< kdc thr bits size */\r
+\r
+#define   GH3X2X_SLOT_KDC_THR_BITS_MARK             (0x0007)    /**< kdc thr bits mark */\r
+\r
+#define   GH3X2X_SLOT_KDC_THR_ADC_INDEX_MAX         (3)         /**< kdc thr adc index max */\r
+\r
+\r
+/* reg bit field index */\r
+\r
+#define   GH3X2X_ECG_FAST_RECV_EN_LSB               (10)        /**< ecg fast recv en lsb @GH3X2X_ECG_CTRL_REG */\r
+#define   GH3X2X_ECG_FAST_RECV_EN_MSB               (10)        /**< ecg fast recv en msb @GH3X2X_ECG_CTRL_REG */\r
+\r
+#define   GH3X2X_ECG_LEAD_DET_EN_LSB                (0)         /**< ecg lead det en lsb @GH3X2X_ADT_LEADON_CR_REG */\r
+#define   GH3X2X_ECG_LEAD_DET_EN_MSB                (0)         /**< ecg lead det en msb @GH3X2X_ADT_LEADON_CR_REG */\r
+\r
+#define   GH3X2X_LEAD_ON_AUTO_SWITCH_LSB            (8)         /**< lead on auto switch lsb @GH3X2X_ECG_CTRL_REG */\r
+#define   GH3X2X_LEAD_ON_AUTO_SWITCH_MSB            (8)         /**< lead on auto switch msb @GH3X2X_ECG_CTRL_REG */\r
+\r
+#define   GH3X2X_LEAD_OFF_AUTO_SWITCH_LSB           (9)         /**< lead off auto switch lsb @GH3X2X_ECG_CTRL_REG */\r
+#define   GH3X2X_LEAD_OFF_AUTO_SWITCH_MSB           (9)         /**< lead off auto switch msb @GH3X2X_ECG_CTRL_REG */\r
+\r
+\r
+#define  GH3X2X_WEAR_ON_EVENT_EN_LSB                (10)        /**< wear on event en lsb*/\r
+#define  GH3X2X_WEAR_ON_EVENT_EN_MSB                (10)        /**< wear on event en msb*/\r
+\r
+#define  GH3X2X_WEAR_OFF_EVENT_EN_LSB               (11)        /**< wear off event en lsb*/\r
+#define  GH3X2X_WEAR_OFF_EVENT_EN_MSB               (11)        /**< wear off event en msb*/\r
+\r
+\r
+#define  GH3X2X_DRV0_FULL_SCAL_CURRENT_LSB          (0)\r
+#define  GH3X2X_DRV0_FULL_SCAL_CURRENT_MSB          (1)\r
+\r
+#define  GH3X2X_DRV1_FULL_SCAL_CURRENT_LSB          (4)\r
+#define  GH3X2X_DRV1_FULL_SCAL_CURRENT_MSB          (5)\r
+\r
+\r
+#define  GH3X2X_SLOT_AGC_EN_LSB                     (8)\r
+#define  GH3X2X_SLOT_AGC_EN_MSB                     (9)\r
+\r
+#define  GH3X2X_SLOT_BG_LEVEL_LSB                   (4)\r
+#define  GH3X2X_SLOT_BG_LEVEL_MSB                   (5)\r
+\r
+#define  GH3X2X_SLOT_BG_CANCEL_LSB                  (10)\r
+#define  GH3X2X_SLOT_BG_CANCEL_MSB                  (10)\r
+\r
+#define  GH3X2X_SLOT_ADC_INT_TIME_LSB               (0)\r
+#define  GH3X2X_SLOT_ADC_INT_TIME_MSB               (3)\r
+\r
+#define  GH3X2X_SLOT_SR_LSB                         (8)\r
+#define  GH3X2X_SLOT_SR_MSB                         (15)\r
+\r
+\r
+\r
+\r
+\r
+\r
+#endif /* _GH3X2X_DRV_REGISTERS_H_ */\r
+\r
+/********END OF FILE********* Copyright (c) 2003 - 2022, Goodix Co., Ltd. ********/\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/driver/inc/gh_drv_version.h b/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/driver/inc/gh_drv_version.h
new file mode 100644 (file)
index 0000000..a62d0ad
--- /dev/null
@@ -0,0 +1,291 @@
+/**\r
+ * @copyright (c) 2003 - 2022, Goodix Co., Ltd. All rights reserved.\r
+ *\r
+ * @file    gh3x2x_drv_version.h\r
+ *\r
+ * @brief   gh3x2x driver version and change log\r
+ *\r
+ * @par  history:\r
+ * @verbatim\r
+ * Date          Author       Version     Notes\r
+ * 2019-10-21    Chris-Chan   v0.0.1.0    1.First version\r
+ * 2019-11-04    Chris-Chan   v0.0.1.1    1.Change name to GH31XX\r
+ * 2019-12-17    Chris-Chan   v0.0.1.2    1.Fix some bugs\r
+ * 2019-12-25    Chris-Chan   v0.0.1.3    1.Add hook function\r
+ * 2019-12-31    Chris-Chan   v0.0.1.4    1.Add hb algorithm support, but use roma ii algorithm now\r
+ * 2020-01-19    Chris-Chan   v0.0.1.5    1.Add inited confirm support\r
+ *                                        2.Add some control api\r
+ * 2020-02-12    Chris-Chan   v0.0.1.6    1.Add debug log support\r
+ *                                        2.Add some control api and some easy to debug\r
+ * 2020-02-17    Chris-Chan   v0.0.1.7    1.Add some control api\r
+ * 2020-02-28    Chris-Chan   v0.0.1.8    1.Add some control api\r
+ * 2020-03-06    Chris-Chan   v0.0.1.9    1.Add universal protocol\r
+ * 2020-03-20    Chris-Chan   v0.0.2.0    1.Add more cmd handler\r
+ *                                        2.Add all header files & move some code to *.h from common.h\r
+ *                                        3.Change to new algorithm api\r
+ * 2020-03-27    Chris-Chan   v0.0.2.1    1.Fix cryp header that distinguish data is encrypted or not\r
+ *                                        2.Add some control api\r
+ *                                        3.Add virtual regs control\r
+ * 2020-04-03    Chris-Chan   v0.1.0.0    1.Add send pkg api with universal protocol\r
+ *                                        2.Add Soft Adjust api\r
+ * 2020-04-07    Chris-Chan   v0.1.0.1    1.Fix algorithm calc hook call, need prevent buffer reverse modification!\r
+ *                                        2.Fix unpack rawdata api, when using 1slot1adc unpack bug\r
+ * 2020-04-08    Chris-Chan   v0.1.0.2    1.Change name to GH3X2X\r
+ * 2020-04-17    Chris-Chan   v0.1.1.0    1.Add incomplete rawdata support\r
+ *                                        2.Change spo2 channel map handle\r
+ * 2020-04-24    Chris-Chan   v0.1.2.0    1.Add dump rawdata support\r
+ *                                        2.Add wait pulse mode off code when exit low power mode, but disable now\r
+ *                                        3.Add verify for encrypt input, input buffer must has magic bytes\r
+ *                                        4.Fix protocol cmd handle and add some cmd\r
+ * 2020-04-30    Chris-Chan   v0.1.3.0    1.Add lead handle support\r
+ * 2020-05-09    Chris-Chan   v0.1.4.0    1.Add macro ctrl channel cnt\r
+ * 2020-05-09    Chris-Chan   v0.1.4.1    1.Fix some bugs\r
+ * 2020-05-12    Chris-Chan   v0.1.4.2    1.Fix some code style\r
+ * 2020-05-13    Chris-Chan   v0.1.4.3    1.Fix slot unpack bug\r
+ *                                        2.Fix wear detect switch\r
+ * 2020-05-18    Chris-Chan   v0.1.4.4    1.Fix all function deinit by add api\r
+ * 2020-05-26    Chris-Chan   v0.1.4.5    1.Change don't send cmd @ start sampling\r
+ * 2020-07-21    wangtao      v0.1.4.6    1.Add AGC code\r
+ *                                        2.Fix some bugs\r
+ * 2020-08-05    wangtao      v0.1.5.0    1.add zip code\r
+ *                                        2.add code for single driver\r
+ * 2020-08-18    wangtao      v0.1.6.0    1.add communicate test code\r
+ *                                        2.change some macro default value\r
+ * 2020-08-20    wangtao      v0.1.6.1    1.fix bug of GH3X2X_Spo2AlgorithmStop,which lost call stop sampling\r
+ * 2020-08-20    wangtao      v0.1.6.2    1.fix bug when confirm connect status\r
+ * 2020-08-20    wanpeng      v0.1.6.3    1.add Itype 0nA code\r
+ * 2020-08-20    zhengxiaoyu  v0.1.6.4    1.add app interface of zip function\r
+ * 2020-08-30    wangtao      v0.1.6.5    1.change method of upload flag data\r
+ *                                        2.fix bug of zip interface when pack g sensor data\r
+ * 2020-08-30    wangtao      v0.1.6.6    1.fix bug of tag value of flag data\r
+ * 2020-08-30    wangtao      v0.1.6.7    1.change  method of upload algorithm result,need upload every algorithm result\r
+ *                                        2.change format of algorithm result and related interfaces\r
+ ************************************************************************************\r
+ * 2020-09-10    wangtao      v1.0.0.0    1.update new algorithm lib of ECG HR and SPO2\r
+ * 2020-09-10    wangtao      v1.0.0.1    1.open spo2 and ecg\r
+ * 2020-09-19    zhengxiaoyu  v1.0.0.2    1.change channel map virtual reg addr\r
+ * 2020-09-21    wangtao      v1.0.1.0    1.add soft wear on/off function & alg\r
+ * 2020-09-21    wangtao      v1.0.2.0    1.add movement detection by gsensor\r
+ * 2020-09-21    wangtao      v1.1.0.0    1.config algorithm memory by user,delete code about algorithm memory\r
+ * 2020-09-27    wangtao      v1.1.1.0    1.fix bug of soft ADT,which will overstep the boundary of array\r
+ * 2020-09-29    wangtao      v1.1.2.0    1.fix bug of memory init\r
+ * 2020-09-29    wangtao      v1.1.3.0    1.update new algorithm\r
+ * 2020-09-29    zhengxiaoyu  v1.1.3.1    1.update function frequency reg virtual receive and analysis\r
+ * 2020-09-29    wanpeng      v1.1.3.2    1.fix softwearoff bug that g_nPpgIdx bigger than 99\r
+ * 2020-09-29    wanpeng      v1.1.3.3    1.change logic soft adt\r
+ * 2020-10-13    wangtao      v1.1.4.0    1.fix bug of soft adt\r
+ * 2020-10-14    wangtao      v1.1.4.1    1.fix some code style\r
+ *                                        2.change some threshold of soft adt\r
+ * 2020-10-15    wangtao      v1.1.4.2    1.cancel restrict of adt enable\r
+ *                                        2.fix hb algorithm bug\r
+ * 2020-10-15    wangtao      v1.1.5.0    1.fix bug of soft adt\r
+ * 2020-10-22    wangtao      v1.1.6.0    1.add HRV algorithm\r
+ * 2020-10-26    zhengxiaoyu  v1.1.6.1    1.fix protocol bug\r
+ * 2020-10-22    wangtao      v1.1.7.0    1.add new algo lib\r
+ *                                        2.fix bug of acc data dislocation when channel map cnt is larger than 8\r
+ * 2020-11-03    zhengxiaoyu  v1.1.7.1    1.Add spo2 Correction Factor input\r
+ * 2020-11-03    zhengxiaoyu  v1.1.7.2    1.Fix HRV error result bug\r
+ * 2020-11-05    zengjiemin   v1.1.8.0    1.Add Android Compile\r
+ * 2020-11-05    wanpeng      v1.1.8.1    1.In ECG 5nA mode, reset ecg module when stop ecg sample\r
+ * 2020-11-11    zhengxiaoyu  v1.1.9.0    1.Add Algo Channel map\r
+ * 2020-11-11    zhengxiaoyu  v1.1.9.1    1.Add Algo Version print\r
+ * 2020-11-17    zhengxiaoyu  v1.1.9.2    1.Fix Ecg 0nA mode lead bug\r
+ * 2020-11-17    zhengxiaoyu  v1.3.0.0    1.Fix Ecg 0nA mode lead bug\r
+ * 2020-11-17    zhengxiaoyu  v1.3.0.1    1.Fix Gsnesor Bug\r
+ * 2020-11-17    qiuchuitong  v1.3.0.2    1.Fix Ecg Rowdata to algorithm bug\r
+ * 2020-12-16    wanpeng      v1.3.0.2    save code and disable ecg and dump mode /change spo2 hr result struct\r
+ * 2020-12-22    wanpeng      v1.3.0.3    add engineering mode sample interface\r
+ * 2020-12-24    wanpeng      v1.3.0.4    add chip reset recovery code\r
+ ************************************************************************************\r
+ * 2021-01-07    wanpeng      v3.0.0.0    modify compile script and start new drvlib\r
+ * 2021-01-08    wanpeng      v3.0.0.1    add frame process code and start function code\r
+ * 2021-01-11    wanpeng      v3.0.0.2    add some code in ecg.c/config.c\r
+ * 2021-01-12    wanpeng      v3.0.0.8    1.add some code about soft agc\r
+ *                                        2.remove code in control_ex.c\r
+ *                                        3.add some code in config.c\r
+ *                                        4.add 2nd level algo api\r
+ *                                        5.use frameinfo pointer array instead of pointers\r
+ *                                        6.add algo init and deinit api\r
+ * 2021-01-13    wanpeng      v3.0.1.1    1.free alo protect arr in alo call api\r
+ *                                        2.set last gain\r
+ *                                        3.add rawdata buffer feature value calculate and check\r
+ * 2021-01-14    wanpeng      v3.0.1.4    1.send flag msg to alg\r
+ *                                        2.send flag msg to alg从\r
+ *                                        3.fix algo call and agc lib\r
+ * 2021-01-15    wanpeng      v3.0.1.5    add upload function\r
+ * 2021-01-19    qiuchuitong  v3.0.1.8    1.modify algo call lib\r
+ *                                        2.fix ecg bug\r
+ *                                        3.fix ecg func return bug\r
+ * 2021-01-20    qiuchuitong  v3.0.1.9    upload algo result\r
+ * 2021-01-21    qiuchuitong  v3.0.2.2    1.fix data pkg bug\r
+ *                                        2.fix hrv channel map config bug\r
+ *                                        3.fix soft adt bug\r
+ * 2021-01-22    wanpeng      v3.0.2.3    separate fucntion GetFrameNum\r
+ * 2021-01-29    qiuchuitong  v3.0.2.6    1.fix ECG bug\r
+ *                                        2.add app work mode\r
+ *                                        3.modify algo result hook func\r
+ * 2021-01-29    zhengxiaoyu  v3.0.2.8    1.Update Zip Protocol\r
+ *                                        2.Fix spo2 Alg bug\r
+ * 2021-02-02    zhengxiaoyu  v3.0.3.1    1.Update zip Protocol\r
+ *                                        2.Fix ECG Flag2 bugs\r
+ *                                        3.Fix Spo2 Rawdata bug\r
+ * 2021-02-02    zhengxiaoyu  v3.0.3.3    1.Update code format\r
+ *                                        2.Update softwear wear on detect\r
+ * 2021-02-08    zhengxiaoyu  v3.0.3.5    1.Update Zip protocol\r
+ *                                        2.Change ResultHook to ResultReport \r
+ * 2021-02-09    zhengxiaoyu  v3.0.3.6    1.Fix Zip Protocol bug\r
+ * 2021-02-09    zhengxiaoyu  v3.0.3.8    1.Fix Engineering Mode mode\r
+ *                                        2.Fix Decode reg bug & add HRV function Decode\r
+ * 2021-02-25    zhengxiaoyu  v3.0.4.2    1.Fix Build bug when close goodix alg\r
+ *                                        2.Add 0x0b new rawdata protocol\r
+ *                                        3.Add protocol version\r
+ *                                        4.Add Amb section in new rawdata protocol\r
+ * 2021-03-09    qiuchuitong  v3.0.5.0    1.Update soft adt algo lib\r
+ *                                        2.add lead off detect 2 for 800Hz sample rate\r
+ * 2021-03-09    zhengxiaoyu  v3.0.6.0    1.Add AF/HSM/RESP/BT lib\r
+ *                                        2.Update code struct\r
+ * 2021-03-09    zhengxiaoyu  v3.0.6.2    1.Update HSM/AF lib\r
+ *                                        2.Update HSM/AF API\r
+ * 2021-03-10    zhengxiaoyu  v3.0.6.5    1.Update HSM/AF function lib\r
+ *                                        2.Update HSM result protocol\r
+ *                                        3.Update code structure\r
+ * 2021-03-11    qiuchuitong  v3.0.6.6    1.Update HR/SPO2/ECG/ ALGO lib\r
+ *                                        2.add virtual reg for spo2 and soft adt\r
+ * 2021-03-12    zhengxiaoyu  v3.0.6.7    1.Update HSM Report Send\r
+ * 2021-03-12    qiuchuitong  v3.0.6.8    1.Add bootloader version function \r
+ * 2021-03-12    qiuchuitong  v3.0.6.9    1.fix spo2 corret factor bug\r
+ * 2021-03-17    qiuchuitong  v3.0.7.1    1.Update HSM ALGO lib\r
+ *                                        2.fix warnings \r
+ * 2021-03-19    qiuchuitong  v3.0.7.3    1.Update HR ALGO lib\r
+ *                                        2.modify spo2 default factor \r
+ * 2021-03-19    qiuchuitong  v3.0.7.4    1.Update af ALGO lib\r
+ * 2021-03-22    qiuchuitong  v3.0.7.5    1.Update af,HSM,RESP ALGO lib\r
+ * 2021-03-22    zhengxiaoyu  v3.0.7.9    1.Update HSM lib\r
+ *                                        2.Update float cal\r
+ *                                        3.Add FPBP/PWA functions \r
+ * 2021-03-23    qiuchuitong  v3.0.8.0    1.fix spo2 upload results bug\r
+ * 2021-03-23    qiuchuitong  v3.0.8.1    1.fix ECG  results bug\r
+ * 2021-03-24    wanpeng      v3.0.8.2    1.fix movement detect bug\r
+                                          2.add multi chnl memsize maroc(HR and SPO2)\r
+ * 2021-03-30    zhengxiaoyu  v3.0.8.6    1.Change function id to u32\r
+ *                                        2.Add init/deinit/update error check\r
+ *                                        3.Add test1/2 functions\r
+ *                                        4.Add virtual-reg setting\r
+ * 2021-03-30    zhengxiaoyu  v3.0.8.8    1.Fix RESP gain flag bug\r
+ *                                        2.Add write reg check\r
+ * 2021-04-01    zhengxiaoyu  v3.0.9.1    1.Fix PWA chnl map bug\r
+ *                                        2.Add Hr result get\r
+ *                                        3.Fix gain-get bug\r
+ *                                        4.Add Android define\r
+ * 2021-04-01    zhengxiaoyu  v3.0.9.2    1.Fix PT mode ADT bug\r
+ * 2021-04-06    zhengxiaoyu  v3.0.9.3    1.Update hr result input hrv/hsm\r
+ * 2021-04-16    zhengxiaoyu  v3.0.9.6    1.Fix control bug\r
+ * 2021-04-17    zhengxiaoyu  v3.0.9.8    1.Update softadt alg\r
+ *                                        2.Fix bug & Update struct\r
+ * 2021-04-19    zhengxiaoyu  v3.0.9.9    1.Fix bug\r
+ * 2021-04-20    wanpeng      v3.1.0.0    1.Fix agc bug\r
+ * 2021-05-11    zhengxiaoyu  v3.2.0.0    1.Update FPBP Alg & VirtualReg & something else\r
+ * 2021-05-11    zhengxiaoyu  v3.2.0.1    1.Update Algo Version Update\r
+ * 2021-05-15    zhengxiaoyu  v3.2.0.2    1.Add FPBP Algo chnl init\r
+ * 2021-05-17    zhengxiaoyu  v3.2.0.3    1.Fix FPBP bug\r
+ * 2021-05-17    zhengxiaoyu  v3.2.0.4    1.Update FPBP Input&Output API\r
+ * 2021-05-18    zhengxiaoyu  v3.2.0.5    1.Fix some FPBP bug\r
+ * 2021-05-19    zhengxiaoyu  v3.2.0.6    1.Add FPBP error code update\r
+ * 2021-05-20    zhengxiaoyu  v3.2.0.7    1.Add FPBP result pressure data\r
+ * 2021-05-20    zhengxiaoyu  v3.2.0.8    1.Add update FPBP pressure parameters setting\r
+ * 2021-05-24    zhengxiaoyu  v3.2.1.0    1.Add eeprom handle\r
+ *                                                           2.Fix zip protocol bug\r
+ * 2021-05-25    zhengxiaoyu  v3.2.1.1    1.Change rawdata a0/a1 read\r
+ * 2021-05-26    zhengxiaoyu  v3.2.1.2    1.Update FPBP hook logic\r
+ * 2021-05-27    zhengxiaoyu  v3.2.1.4    1.Update FPBP pressure parameters setting\r
+ *                                                           2.Add PWA program & Alglib\r
+ * 2021-05-28    zhengxiaoyu  v3.2.1.5    1.Fix decode cfg list bug\r
+ * 2021-05-31    zhengxiaoyu  v3.2.1.6    1.Add PWA algo function\r
+ * 2021-06-01    zhengxiaoyu  v3.2.1.7    1.Add SoftAdt IR function\r
+ * 2021-06-01    zhengxiaoyu  v3.2.1.8    1.Add function freauency control api\r
+ * 2021-06-02    zhengxiaoyu  v3.2.1.9    1.Fix virtual alg chnl map bug\r
+ * 2021-06-03    zhengxiaoyu  v3.2.2.0    1.Update PWA new program\r
+ * 2021-06-04    zhengxiaoyu  v3.2.2.1    1.Update some algo weak api\r
+ * 2021-06-08    zhengxiaoyu  v3.2.2.2    1.Add function led current\r
+ * 2021-06-08    wanpeng      v3.2.2.4    1.add hardware spi\r
+ *                                        2.add sample rate modify function\r
+ * 2021-06-19    qiuchuitong  v3.2.2.5    1.add ecg 800Hz to 250Hz resample code\r
+ *                                        2.add Gs gyro code\r
+ *                                        3.disable rx2 and rx3 for 3026\r
+ * 2021-06-21    zhengxiaoyu  v3.2.2.6    1.Fix fifo send progress bug\r
+ * 2021-06-22    zhengxiaoyu  v3.2.2.7    1.Fix zip protocol & fifo send bug\r
+ * 2021-06-22    zhengxiaoyu  v3.2.2.8    1.Update hrv input struct\r
+ * 2021-06-24    zhengxiaoyu  v3.2.2.9    1.Add function infomation send protocol\r
+ * 2021-06-25    zhengxiaoyu  v3.2.3.0    1.Add config protect handle \r
+ * 2021-06-29    qiuchuitong  v3.2.3.1    1.divide ecg lead off det and resample\r
+ * 2021-06-29    qiuchuitong  v3.2.3.2    1.fix check chip Model bug\r
+ * 2021-06-29    qiuchuitong  v3.2.3.3    1.fix ecg resample bug\r
+ * 2021-06-29    zhengxiaoyu  v3.2.3.4    1.fix spo2 algo channel bug\r
+ * 2021-07-16    zhengxiaoyu  v3.2.3.5    1.update zip protocol\r
+ * 2021-07-21    zhengxiaoyu  v3.2.3.7    1.update hr&spo2 api&struct\r
+ * 2021-07-21    zhengxiaoyu  v3.2.3.8    1.update hr&spo2 memory\r
+ * 2021-07-21    qiuchuitong  v3.2.3.9    1. add bt version code\r
+ * 2021-07-21    qiuchuitong  v3.2.4.0    1. update nadt\r
+ * 2021-08-12    zhengxiaoyu  v3.2.4.1    1.update bp and other\r
+ * 2021-08-12    zhengxiaoyu  v3.2.4.7    1.update algo lib\r
+ * 2021-08-12    qiuchuitong  v3.2.4.8    1.update bt algo lib\r
+ * 2021-12-16    zhengxiaoyu  v3.2.4.9    1.update hr/spo2/ecg/nadt algo lib\r
+ * 2021-12-16    zhengxiaoyu  v3.2.5.0    1.interrupt mode change func\r
+ *                                        2.result select and protocol update\r
+ *                                        3.change some code format\r
+ *                                        4.add Gh3x2xDemoStartSamplingWithCfgSwitch api\r
+ *                                        5.fix some note error\r
+ * 2021-12-16    zhengxiaoyu  v3.2.5.1    1.fix hrv algo hr result bug\r
+ *                                        2.add check start sample func if exist in config\r
+ * 2022-01-13    zhengxiaoyu  v3.2.5.2    1.rewrite nadt application process\r
+ *                                        2.fix some bug\r
+ * 2022-01-13    zhengxiaoyu  v3.2.5.3    1.update log define\r
+ *                                        2.fix some bug\r
+ ************************************************************************************\r
+ * 2022-02-11    zhengxiaoyu  v4.0.0.0    1.delete all algo related section\r
+ *                                        2.fix some format bug\r
+ *                                        3.add some hook function\r
+ * 2022-02-11    zhengxiaoyu  v4.0.0.1    1.change some funcs addr\r
+ * 2022-02-16    zhengxiaoyu  v4.0.0.2    1.update format\r
+ * 2022-03-24    zhengxiaoyu  v4.0.0.5    1.fix build bug\r
+ *                                        2.add gain read when disable agc func\r
+ * 2022-03-29    qiuchuitong  v4.0.0.6    1.fix mp mode bug\r
+ * 2022-03-29    qiuchuitong  v4.0.0.7    1.update bt algo\r
+ * 2022-03-29    qiuchuitong  v4.0.0.8    1.update algo call code\r
+ *                                        2.add datatrans code\r
+ * 2022-04-13    zhengxiaoyu  v4.0.0.9    1.update nadt process code\r
+ * 2022-04-13    zhengxiaoyu  v4.0.1.0    1.add agcinfo reset\r
+ *                                        2.add ecode current set\r
+ * 2022-05-19    zhengxiaoyu  v4.0.1.1    1.delete some code\r
+ *                                        2.update soft event\r
+ * 2023-04-06    wenyongfeng  v4.1.0.1    1.fix bug\r
+ *     \r
+ * 2023-04-25    wenyongfeng  v4.1.0.2    1.add drv calculate bt \r
+ *\r
+ * 2023-05-16    wenyongfeng  v4.2.0.0    1.open source \r
+ *\r
+ * 2024-01-05    wenyongfeng  v4.2.0.1    1.fix compilation issue\r
+ * @endverbatim  */\r
+\r
+#ifndef _GH3X2X_DRV_VERSION_H_\r
+#define _GH3X2X_DRV_VERSION_H_\r
+\r
+\r
+#define   GH3X2X_DRV_MAJOR_VERSION_NUMBER        4      /**< major version number */\r
+#define   GH3X2X_DRV_MINOR_VERSION_NUMBER        2      /**< minor version number */\r
+#define   GH3X2X_DRV_REVISION_VERSION_NUMBER     0      /**< revision version number */\r
+#define   GH3X2X_DRV_FIXED_VERSION_NUMBER        1      /**< fixed version number */\r
+\r
+#define   GH3X2X_TO_STRING(x)       #x                      /**< number to char */\r
+#define   GH3X2X_STR(x)             GH3X2X_TO_STRING(x)     /**< number to char */\r
+\r
+/// makeup version string\r
+#define   GH3X2X_VERSION_STRING     "v"GH3X2X_STR(GH3X2X_DRV_MAJOR_VERSION_NUMBER)\\r
+                                    "."GH3X2X_STR(GH3X2X_DRV_MINOR_VERSION_NUMBER)\\r
+                                    "."GH3X2X_STR(GH3X2X_DRV_REVISION_VERSION_NUMBER)\\r
+                                    "."GH3X2X_STR(GH3X2X_DRV_FIXED_VERSION_NUMBER)\\r
+                                    " (build:"__DATE__"_"__TIME__")"\r
+\r
+#endif /* _GH3X2X_DRV_VERSION_H_ */\r
+\r
+/********END OF FILE********* Copyright (c) 2003 - 2022, Goodix Co., Ltd. ********/\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/driver/src/gh_drv_config.c b/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/driver/src/gh_drv_config.c
new file mode 100644 (file)
index 0000000..96b8ec2
--- /dev/null
@@ -0,0 +1,880 @@
+/**\r
+ * @copyright (c) 2003 - 2022, Goodix Co., Ltd. All rights reserved.\r
+ *\r
+ * @file    gh3x2x_drv_control_ex.c\r
+ *\r
+ * @brief   gh3x2x extension control functions, using function map like evk\r
+ *\r
+ * @version ref gh3x2x_drv_version.h\r
+ *\r
+ */\r
+\r
+\r
+#include "gh_drv_version.h"\r
+#include "gh_drv_common.h"\r
+#include "gh_drv.h"\r
+#include "gh_drv_interface.h"\r
+#include "gh_drv_control.h"\r
+#include "gh_uprotocol.h"\r
+#include "gh_agc.h"\r
+#include "gh_drv_dump.h"\r
+#include "gh_drv_config.h"\r
+#include "gh_ecg.h"\r
+#include "gh_demo_config.h"\r
+\r
+\r
+\r
+typedef struct \r
+{\r
+       GU8 usCurrentConfigFlag;\r
+#if 0\r
+    GU16 usInfoConfigArrVer;  /// info: reg config array version\r
+    GU16 usInfoConfigToolVer;   /// info: reg config create tool version\r
+    GU16 usInfoProjectId;  /// info: project id\r
+    GU32 unInfoCreatedTimestamp;  /// info: reg config created timestamp\r
+#endif\r
+    GU32 unGhFuncSupportedAtCurCfg;  //function combination supported by current config\r
+}STGhDrvConfigManger;\r
+\r
+STGhDrvConfigManger g_stGhDrvConfigManger;\r
+/// function started bitmap, use for sampling control\r
+GU32 g_unFuncStartedBitmap = 0;\r
+\r
+\r
+\r
+\r
+void GhDrvConfigManagerInit(void)\r
+{\r
+    GH3X2X_Memset((void *)(&g_stGhDrvConfigManger), 0, sizeof(g_stGhDrvConfigManger));\r
+}\r
+\r
+GU32 GhDrvConfigManagerGetCurFunctionSupprort(void)\r
+{\r
+    return g_stGhDrvConfigManger.unGhFuncSupportedAtCurCfg;\r
+}\r
+\r
+\r
+\r
+\r
+\r
+\r
+GS32 g_nAdtWearonThrd = 0;\r
+extern GU8 g_uchFifoPackageMode;\r
+extern GU8 g_uchGsensorEnable;\r
+/// Cap enable flag\r
+extern GU8 g_uchCapEnable;\r
+\r
+/// Temp enable flag\r
+extern GU8 g_uchTempEnable;\r
+\r
+\r
+GCHAR *GH3X2X_GetVirtualRegVersion(void)\r
+{\r
+    return (GCHAR *)GH3X2X_VIRTUAL_REG_VERSION_STRING;\r
+}\r
+\r
+\r
+\r
+void GH3X2X_InitSensorParameters(void)\r
+{\r
+    g_uchGsensorEnable = 0;\r
+    g_uchCapEnable = 0;\r
+    g_uchTempEnable = 0;\r
+}\r
+\r
+\r
+/// if support algorithm run simultaneously\r
+//GU8 g_uchAlgoRunMode = GH3X2X_ALGORITHM_RUN_ALONE;\r
+\r
+\r
+\r
+/// @brief get function id via virtual register\r
+/// @param usVirRegAddr virtual register addr\r
+/// @param usVirRegData virtual register value\r
+/// @return fucntion ID , such as: GH3X2X_FUNCTION_ADT\r
+GU32 GhGetFunctionIdViaVirReg(GU16 usVirRegAddr, GU16 usVirRegData)\r
+{\r
+    GU32 unTempFunctionId = 0;\r
+    if(usVirRegAddr >= GH3X2X_REG_IS_VIRTUAL0X2_BIT && usVirRegAddr < 0x2880)  \r
+    {\r
+        if(0 == ((usVirRegAddr - GH3X2X_REG_IS_VIRTUAL0X2_BIT)%GH3X2X_CHNLMAP_OFFSET))  //addr = 0x2000,0x2022,0x2044...\r
+        {\r
+            if(usVirRegData)\r
+            {\r
+                unTempFunctionId = ((GU32)1 << ((usVirRegAddr - GH3X2X_REG_IS_VIRTUAL0X2_BIT)/GH3X2X_CHNLMAP_OFFSET));\r
+                GH3X2X_DEBUG_LOG_PARAM("[GhGetFunctionIdViaVirReg]:Got valid function, ID = 0x%X\r\n", unTempFunctionId);\r
+            }\r
+        }\r
+    }\r
+    return unTempFunctionId;\r
+}\r
+/**\r
+ * @fn     GS8 GH3X2X_DecodeRegCfgArr(GU32* punRunMode, const STGh3x2xReg *pstRegConfigArr, GU16 usRegConfigLen)\r
+ *\r
+ * @brief  Analyze reg cfg array to get the run mode.\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   pstRegConfigArr             pointer to reg config array\r
+ * @param[in]   usRegConfigLen              reg config array length\r
+ * @param[out]  punRunMode                  pointer to run mode contained in reg config array\r
+ *\r
+ * @retval  #GH3X2X_RET_OK                      return successfully\r
+ * @retval  #GH3X2X_RET_PARAMETER_ERROR         return parameter error\r
+ */\r
+GS8 GH3X2X_DecodeRegCfgArr(GU32* punRunMode, const STGh3x2xReg *pstRegConfigArr, GU16 usRegConfigLen)\r
+{\r
+    GS8  chRet = GH3X2X_RET_OK;\r
+\r
+    *punRunMode = GH3X2X_NO_FUNCTION;\r
+    //polling every regs in reg cfg array to get functions\r
+    if ((GH3X2X_PTR_NULL != punRunMode) && (GH3X2X_PTR_NULL != pstRegConfigArr) && (0 != usRegConfigLen))\r
+    {\r
+        for (GU16 usArrCnt = 0; usArrCnt < usRegConfigLen ; usArrCnt ++)\r
+        {\r
+            *punRunMode |= GhGetFunctionIdViaVirReg(pstRegConfigArr[usArrCnt].usRegAddr, pstRegConfigArr[usArrCnt].usRegData);\r
+        }\r
+    }\r
+    else\r
+    {\r
+        chRet = GH3X2X_RET_PARAMETER_ERROR;\r
+    }\r
+    return chRet;\r
+}\r
+\r
+/**\r
+ * @fn     GU16 GH3X2X_ReadSwConfigWithVirtualReg(GU16 usVirtualRegAddr)\r
+ *\r
+ * @brief  Read software config with virtual reg\r
+ *\r
+ * @attention   Virtual reg addr has del control bits, so reg addr is [0:11] valid.\r
+ *\r
+ * @param[in]   usVirtualRegAddr        virtual reg addr\r
+ * @param[out]  None\r
+ *\r
+ * @return  virtual reg val\r
+ */\r
+GU16 GH3X2X_ReadSwConfigWithVirtualReg(GU16 usVirtualRegAddr)\r
+{\r
+    GU16 usVirtualRegData = 0;\r
+#if 0\r
+    GU16 usValIndex = 0;\r
+    GH3X2X_DEBUG_LOG_PARAM("%s\r\n", __FUNCTION__);\r
+    if (usVirtualRegAddr < GH3X2X_VINFO_END_REG_ADDR) // config arr info\r
+    {\r
+        switch (usVirtualRegAddr)\r
+        {\r
+        case GH3X2X_VINFO_CFG_VER_REG_ADDR:\r
+            usVirtualRegData = g_stGhDrvConfigManger.usInfoConfigArrVer;\r
+            break;\r
+        case GH3X2X_VINFO_TOOL_VER_REG_ADDR:\r
+            usVirtualRegData = g_stGhDrvConfigManger.usInfoConfigToolVer;\r
+            break;\r
+        case GH3X2X_VINFO_PROJ_ID_REG_ADDR:\r
+            usVirtualRegData = g_stGhDrvConfigManger.usInfoProjectId;\r
+            break;\r
+        case GH3X2X_VINFO_TIMSTAMP_L_REG_ADDR:\r
+            usVirtualRegData = GH3X2X_GET_LOW_WORD_FROM_DWORD(g_stGhDrvConfigManger.unInfoCreatedTimestamp);\r
+            break;\r
+        case GH3X2X_VINFO_TIMSTAMP_H_REG_ADDR:\r
+            usVirtualRegData = GH3X2X_GET_HIGH_WORD_FROM_DWORD(g_stGhDrvConfigManger.unInfoCreatedTimestamp);\r
+            break;\r
+        default: // do nothing\r
+            break;\r
+        }\r
+    } // end of if (usVirtualRegAddr < GH3X2X_VINFO_END_REG_ADDR) \r
+    else if (usVirtualRegAddr < GH3X2X_VCHM_END_REG_ADDR) // config channel map\r
+    {\r
+        if (usVirtualRegAddr < GH3X2X_VCHM_HBA_CH_END_REG_ADDR) // hba\r
+        {\r
+            switch (usVirtualRegAddr)\r
+            {\r
+            case GH3X2X_VCHM_HBA_CNT_REG_ADDR:\r
+                usVirtualRegData = g_uchHbaChannelMapCnt;\r
+                break;\r
+            default:\r
+                usValIndex = (GU16)(usVirtualRegAddr - GH3X2X_VCHM_HBA_CH0_1_REG_ADDR);\r
+                if (usValIndex < GH3X2X_HBA_CHANNEL_MAP_MAX_CNT)\r
+                {\r
+                    usVirtualRegData = GH3X2X_MAKEUP_WORD(g_uchHbaChannelMapArr[usValIndex + 1], \\r
+                                                        g_uchHbaChannelMapArr[usValIndex]);\r
+                }\r
+                break;\r
+            }\r
+        }\r
+        else if (usVirtualRegAddr < GH3X2X_VCHM_SPO2_CH_END_REG_ADDR) // spo2\r
+        {\r
+            switch (usVirtualRegAddr)\r
+            {\r
+            case GH3X2X_VCHM_SPO2_CNT_REG_ADDR:\r
+                usVirtualRegData = g_uchSpo2ChannelMapCnt;\r
+                break;\r
+            default:\r
+                usValIndex = (GU16)(usVirtualRegAddr - GH3X2X_VCHM_SPO2_CH0_1_REG_ADDR);\r
+                if (usValIndex < GH3X2X_SPO2_CHANNEL_MAP_MAX_CNT)\r
+                {\r
+                    usVirtualRegData = GH3X2X_MAKEUP_WORD(g_uchSpo2ChannelMapArr[usValIndex + 1], \\r
+                                                        g_uchSpo2ChannelMapArr[usValIndex]);\r
+                }\r
+                break;\r
+            }\r
+        }\r
+        else\r
+        {\r
+            switch (usVirtualRegAddr)\r
+            {\r
+            case GH3X2X_VCHM_ECG_CH0_REG_ADDR:\r
+                usVirtualRegData = g_uchEcgChannelMap;\r
+                break;\r
+            case GH3X2X_VCHM_ADT_CNT_REG_ADDR:\r
+                usVirtualRegData = g_uchAdtChannelMapCnt;\r
+                break;\r
+            case GH3X2X_VCHM_ADT_CH0_1_REG_ADDR:\r
+                usVirtualRegData = GH3X2X_MAKEUP_WORD(g_uchAdtChannelMapArr[1], g_uchAdtChannelMapArr[0]);\r
+                break;\r
+            case GH3X2X_VCHM_ADT_CH2_3_REG_ADDR:\r
+                usVirtualRegData = GH3X2X_MAKEUP_WORD(g_uchAdtChannelMapArr[3], g_uchAdtChannelMapArr[2]);\r
+                break;\r
+            default: // do nothing\r
+                break;\r
+            } // end of switch (usVirtualRegAddr)\r
+        }\r
+    } // end of else if (usVirtualRegAddr < GH3X2X_VCHM_END_REG_ADDR)\r
+    else if (usVirtualRegAddr < GH3X2X_VDUMP_END_REG_ADDR) // dump module\r
+    {\r
+        switch (usVirtualRegAddr)\r
+        {\r
+        case GH3X2X_VDUMP_DUMP_MODE_REG_ADDR:\r
+            break;\r
+        case GH3X2X_VDUMP_BG_LEVEL_REG_ADDR:\r
+            break;\r
+        default: // do nothing\r
+            break;\r
+        }\r
+    }\r
+    else if (usVirtualRegAddr < GH3X2X_VECG_END_REG_ADDR) // ecg module\r
+    {\r
+        switch (usVirtualRegAddr)\r
+        {\r
+        case GH3X2X_VECG_0_REG_ADDR:\r
+        case GH3X2X_VECG_1_REG_ADDR:\r
+        case GH3X2X_VECG_2_REG_ADDR:\r
+            usValIndex = (usVirtualRegAddr - GH3X2X_VECG_0_REG_ADDR) / GH3X2X_REG_ADDR_SIZE;\r
+            break;\r
+        default: // do nothing\r
+            break;\r
+        }\r
+    } // end of else if (usVirtualRegAddr < GH3X2X_VECG_END_REG_ADDR)\r
+    else if (usVirtualRegAddr < GH3X2X_VAGC_END_REG_ADDR) // agc config\r
+    {\r
+        switch (usVirtualRegAddr)\r
+        {\r
+        case GH3X2X_VAGC_AGC_BG_SLOT_ENABLE_REG_ADDR:\r
+            break;\r
+        case GH3X2X_VAGC_AMB_SLOT_CTRL_REG_ADDR:\r
+            break;\r
+        case GH3X2X_VAGC_RES_REG_ADDR:\r
+            break;\r
+        default: // do nothing\r
+            break;\r
+        }\r
+    } // end of else if (usVirtualRegAddr < GH3X2X_VAGC_END_REG_ADDR)\r
+#endif\r
+    return usVirtualRegData;\r
+}\r
+\r
+void GH3X2X_WriteFsConfigWithVirtualReg(GU16 usVirtualRegAddr, GU16 usVirtualRegValue)\r
+{\r
+    GU8 uchFuncOffsetIndex =  (usVirtualRegAddr - GH3X2X_ADT_FS_ADDR) / 2;\r
+    if(g_pstGh3x2xFrameInfo[uchFuncOffsetIndex] != 0)\r
+    {\r
+        g_pstGh3x2xFrameInfo[uchFuncOffsetIndex] ->pstFunctionInfo ->usSampleRate = GH3X2X_GET_LOW_WORD_FROM_DWORD(usVirtualRegValue);\r
+    }\r
+}\r
+\r
+\r
+\r
+void GH3X2X_WriteChnlMapConfigWithVirtualReg(GU16 usVirtualRegAddr, GU16 usVirtualRegValue)\r
+{\r
+    GU16 usValIndex = 0;\r
+    usVirtualRegAddr = GH3X2X_GET_REG_REAL_ADRR(usVirtualRegAddr);\r
+    switch (usVirtualRegAddr % GH3X2X_CHNLMAP_OFFSET)\r
+    {\r
+    case 0:\r
+        GH3x2xSetFunctionChnlNum(g_pstGh3x2xFrameInfo[usVirtualRegAddr / GH3X2X_CHNLMAP_OFFSET],GH3X2X_GET_LOW_BYTE_FROM_WORD(usVirtualRegValue));\r
+        break;\r
+    default:\r
+        usValIndex = (GU16)((usVirtualRegAddr % GH3X2X_CHNLMAP_OFFSET) - 2);\r
+        if (usValIndex < GH3X2X_CHANNEL_MAP_MAX_CH)\r
+        {\r
+            GH3x2xSetFunctionChnlMap(g_pstGh3x2xFrameInfo[usVirtualRegAddr / GH3X2X_CHNLMAP_OFFSET],usValIndex + 1,GH3X2X_GET_HIGH_BYTE_FROM_WORD(usVirtualRegValue));\r
+            GH3x2xSetFunctionChnlMap(g_pstGh3x2xFrameInfo[usVirtualRegAddr / GH3X2X_CHNLMAP_OFFSET],usValIndex,GH3X2X_GET_LOW_BYTE_FROM_WORD(usVirtualRegValue));\r
+        }\r
+        break;\r
+    }\r
+}\r
+\r
+#if __SUPPORT_SOFT_AGC_CONFIG__\r
+void GH3X2X_WriteAgcConfigWithVirtualReg(GU16 usVirtualRegAddr, GU16 usVirtualRegValue)\r
+{\r
+    GU16 usValIndex;\r
+    switch (usVirtualRegAddr)\r
+    {\r
+    case GH3X2X_AGC_BG_CANCEL_ADJUST_SLOT_EN_ADDR:\r
+    case GH3X2X_AGC_AMB_SLOT_CTRL_ADDR:\r
+    case GH3X2X_AGC_CONFIG_RES:\r
+    case GH3X2X_AGC_GAIN_LIMIT_ADDR:\r
+    case GH3X2X_AGC_TRIG_THD_H_LSB_16_ADDR:\r
+    case GH3X2X_AGC_TRIG_THD_H_MSB_16_ADDR:\r
+    case GH3X2X_AGC_TRIG_THD_L_LSB_16_ADDR:\r
+    case GH3X2X_AGC_TRIG_THD_L_MSB_16_ADDR:\r
+    case GH3X2X_AGC_RESTRAIN_THD_H_LSB_16_ADDR:\r
+    case GH3X2X_AGC_RESTRAIN_THD_H_MSB_16_ADDR:\r
+    case GH3X2X_AGC_RESTRAIN_THD_L_LSB_16_ADDR:\r
+    case GH3X2X_AGC_RESTRAIN_THD_L_MSB_16_ADDR:\r
+        usValIndex = (usVirtualRegAddr - GH3X2X_AGC_BG_CANCEL_ADJUST_SLOT_EN_ADDR) / GH3X2X_REG_ADDR_SIZE;\r
+        GH3X2X_LedAgcPramWrite(usVirtualRegValue, usValIndex);\r
+        break;\r
+    default: // do nothing\r
+        break;\r
+    }\r
+}\r
+#endif\r
+\r
+\r
+#if 1\r
+\r
+\r
+void GhConfigSwModuleConfigInfoParmSet(GU16 usVirtualRegAddr, GU16 usVirtualRegValue)\r
+{\r
+        switch (usVirtualRegAddr)\r
+        {\r
+#if 0    //wanpeng this info is not using, delet them to save code\r
+        case GH3X2X_CFG_VER_ADDR:\r
+            g_stGhDrvConfigManger.usInfoConfigArrVer = usVirtualRegValue;\r
+            break;\r
+        case GH3X2X_CFG_TOOL_VER_ADDR:\r
+            g_stGhDrvConfigManger.usInfoConfigToolVer = usVirtualRegValue;\r
+            break;\r
+        case GH3X2X_PROJECT_ID_ADDR:\r
+            g_stGhDrvConfigManger.usInfoProjectId = usVirtualRegValue;\r
+            break;\r
+        case GH3X2X_TIMESTAMP_L_ADDR:\r
+            g_stGhDrvConfigManger.unInfoCreatedTimestamp = GH3X2X_MAKEUP_DWORD2(GH3X2X_GET_HIGH_WORD_FROM_DWORD(g_stGhDrvConfigManger.unInfoCreatedTimestamp),\r
+                                                                usVirtualRegValue);\r
+            break;\r
+        case GH3X2X_TIMESTAMP_H_ADDR:\r
+            g_stGhDrvConfigManger.unInfoCreatedTimestamp = GH3X2X_MAKEUP_DWORD2(usVirtualRegValue,\r
+                                                            GH3X2X_GET_LOW_WORD_FROM_DWORD(g_stGhDrvConfigManger.unInfoCreatedTimestamp));\r
+            break;\r
+#endif\r
+        case GH3X2X_REINIT_PARAM_ADDR:\r
+            GH3X2X_ReinitAllSwModuleParam(usVirtualRegValue);\r
+            break;\r
+        default: // do nothing\r
+            break;\r
+        }\r
+}\r
+\r
+void GhConfigSwModuleDumpInit(void)\r
+{\r
+    GH3X2X_DumpModeSet(0); \r
+}\r
+\r
+void GhConfigSwModuleDumpParmSet(GU16 usVirtualRegAddr, GU16 usVirtualRegValue)\r
+{\r
+    switch (usVirtualRegAddr)\r
+    {\r
+    case GH3X2X_PPG_DUMP_MODE_ADDR:\r
+        GH3X2X_DumpModeSet(usVirtualRegValue);\r
+        break;\r
+    case GH3X2X_BG_LEVEL_SET_ADDR:\r
+        //GH3X2X_BgLevelSet(usVirtualRegValue);\r
+        break;\r
+    default: // do nothing\r
+        break;\r
+    }\r
+}\r
+\r
+void GhConfigSwModuleFifoInfoParmSet(GU16 usVirtualRegAddr, GU16 usVirtualRegValue)\r
+{\r
+    switch (usVirtualRegAddr)\r
+    {\r
+    case GH3X2X_FIFO_PACKAGE_SEND_MODE_ADDR:\r
+        g_uchFifoPackageMode = usVirtualRegValue;\r
+        break;\r
+    default: // do nothing\r
+        break;\r
+    }\r
+}\r
+\r
+\r
+\r
+void GhConfigSwModuleGsParmSet(GU16 usVirtualRegAddr, GU16 usVirtualRegValue)\r
+{\r
+    switch (usVirtualRegAddr)\r
+    {\r
+    case GH3X2X_GSENSOR_CTRL_ADDR:\r
+        g_uchGsensorEnable = GH3X2X_GET_LOW_BYTE_FROM_WORD(usVirtualRegValue);\r
+        break;\r
+    default: // do nothing\r
+        break;\r
+    }\r
+}\r
+\r
+\r
+\r
+\r
+#if __CAP_ENABLE__\r
+void GhConfigSwModuleCapParmSet(GU16 usVirtualRegAddr, GU16 usVirtualRegValue)\r
+{\r
+    switch (usVirtualRegAddr)\r
+    {\r
+    case GH3X2X_CAP_CTRL_ADDR:\r
+        g_uchCapEnable = GH3X2X_GET_LOW_BYTE_FROM_WORD(usVirtualRegValue);\r
+        break;\r
+    default: // do nothing\r
+        break;\r
+    }\r
+}\r
+#endif\r
+\r
+#if __TEMP_ENABLE__\r
+void GhConfigSwModuleTempParmSet(GU16 usVirtualRegAddr, GU16 usVirtualRegValue)\r
+{\r
+    switch (usVirtualRegAddr)\r
+    {\r
+        case GH3X2X_TEMP_CTRL_ADDR:\r
+            g_uchTempEnable = GH3X2X_GET_LOW_BYTE_FROM_WORD(usVirtualRegValue);\r
+            break;\r
+        default: // do nothing\r
+            break;\r
+    }\r
+}\r
+#endif\r
+\r
+\r
+\r
+\r
+const STGhVirRegSwModuleInfo g_stGhVirRegSwModuleInfo[] = \r
+{\r
+    /**                   usAddrStart                 usAddrEnd                      ParmSet  *****/\r
+    /*config info*/       {GH3X2X_TOP_INFO_ADDR,       GH3X2X_TOP_INFO_ADDR_END,      GhConfigSwModuleConfigInfoParmSet},\r
+    /*dump*/              {GH3X2X_DUMP_CFG_ADDR,       GH3X2X_DUMP_CFG_ADDR_END,      GhConfigSwModuleDumpParmSet},\r
+    /*fifo info*/         {GH3X2X_FIFO_CTRL_ADDR,      GH3X2X_FIFO_CTRL_ADDR_END,     GhConfigSwModuleFifoInfoParmSet},\r
+    /*gsensor*/           {GH3X2X_G_SENSOR_CFG_ADDR,   GH3X2X_G_SENSOR_CFG_ADDR_END,  GhConfigSwModuleGsParmSet},\r
+#if __SUPPORT_SOFT_AGC_CONFIG__ \r
+    /*agc*/               {GH3X2X_SOFT_AGC_PARA_ADDR,  GH3X2X_SOFT_AGC_PARA_ADDR_END, GH3X2X_WriteAgcConfigWithVirtualReg},\r
+#endif\r
+#if __CAP_ENABLE__  \r
+    /*cap*/               {GH3X2X_CAP_CFG_ADDR,        GH3X2X_CAP_CFG_ADDR_END,       GhConfigSwModuleCapParmSet},\r
+#endif\r
+#if __TEMP_ENABLE__ \r
+    /*temp*/              {GH3X2X_TEMP_CFG_ADDR,       GH3X2X_TEMP_CFG_ADDR_END,      GhConfigSwModuleTempParmSet},\r
+#endif    \r
+    /*ChnlMap*/           {GH3X2X_CHNL_MAP_ADDR,       GH3X2X_CHNL_MAP_ADDR_END,      GH3X2X_WriteChnlMapConfigWithVirtualReg},\r
+    /*Fs*/                {GH3X2X_FS_PARA_ADDR,        GH3X2X_FS_PARA_ADDR_END,       GH3X2X_WriteFsConfigWithVirtualReg},\r
+};\r
+\r
+\r
+\r
+\r
+void GH3X2X_WriteSwConfigWithVirtualReg(GU16 usVirtualRegAddr, GU16 usVirtualRegValue)\r
+{\r
+    for(GU8 ubModuleCnt = 0; ubModuleCnt < sizeof(g_stGhVirRegSwModuleInfo)/sizeof(STGhVirRegSwModuleInfo); ubModuleCnt ++)\r
+    {\r
+        if((usVirtualRegAddr >= g_stGhVirRegSwModuleInfo[ubModuleCnt].usAddrStart)&&(usVirtualRegAddr < g_stGhVirRegSwModuleInfo[ubModuleCnt].usAddrEnd))\r
+        {\r
+            if(g_stGhVirRegSwModuleInfo[ubModuleCnt].ParmSet)\r
+            {\r
+                g_stGhVirRegSwModuleInfo[ubModuleCnt].ParmSet(usVirtualRegAddr, usVirtualRegValue);\r
+            }\r
+        }\r
+    }\r
+}\r
+\r
+#else\r
+\r
+/**\r
+ * @fn     GS8 GH3X2X_WriteSwConfigWithVirtualReg(GU16 usVirtualRegAddr, GU16 usVirtualRegValue)\r
+ *\r
+ * @brief  Write software param config with virtual reg\r
+ *\r
+ * @attention   Virtual reg addr has del control bits, so reg addr is [0:11] valid.\r
+ *\r
+ * @param[in]   usVirtualRegAddr        virtual reg addr\r
+ * @param[in]   usVirtualRegValue       virtual reg value\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_WriteSwConfigWithVirtualReg(GU16 usVirtualRegAddr, GU16 usVirtualRegValue)\r
+{\r
+    if (usVirtualRegAddr < GH3X2X_SLOT_LEDDRV_ADDR) // config arr info         0x1F\r
+    {\r
+        switch (usVirtualRegAddr)\r
+        {\r
+        #if 0\r
+        case GH3X2X_CFG_VER_ADDR:\r
+            g_stGhDrvConfigManger.usInfoConfigArrVer = usVirtualRegValue;\r
+            break;\r
+        case GH3X2X_CFG_TOOL_VER_ADDR:\r
+            g_stGhDrvConfigManger.usInfoConfigToolVer = usVirtualRegValue;\r
+            break;\r
+        case GH3X2X_PROJECT_ID_ADDR:\r
+            g_stGhDrvConfigManger.usInfoProjectId = usVirtualRegValue;\r
+            break;\r
+        case GH3X2X_TIMESTAMP_L_ADDR:\r
+            g_stGhDrvConfigManger.unInfoCreatedTimestamp = GH3X2X_MAKEUP_DWORD2(GH3X2X_GET_HIGH_WORD_FROM_DWORD(g_stGhDrvConfigManger.unInfoCreatedTimestamp),\r
+                                                                usVirtualRegValue);\r
+            break;\r
+        case GH3X2X_TIMESTAMP_H_ADDR:\r
+            g_stGhDrvConfigManger.unInfoCreatedTimestamp = GH3X2X_MAKEUP_DWORD2(usVirtualRegValue,\r
+                                                            GH3X2X_GET_LOW_WORD_FROM_DWORD(g_stGhDrvConfigManger.unInfoCreatedTimestamp));\r
+            break;\r
+        #endif\r
+        case GH3X2X_REINIT_PARAM_ADDR:\r
+            GH3X2X_ReinitAllSwModuleParam(usVirtualRegValue);\r
+            break;\r
+        default: // do nothing\r
+            break;\r
+        }\r
+    } // end of if (usVirtualRegAddr < GH3X2X_VINFO_END_REG_ADDR) \r
+    else if (usVirtualRegAddr < GH3X2X_DUMP_CFG_ADDR) // slot drv map module\r
+    {\r
+        //TO BE DONE\r
+    }\r
+    else if (usVirtualRegAddr < GH3X2X_FIFO_CTRL_ADDR) // dump module\r
+    {\r
+        switch (usVirtualRegAddr)\r
+        {\r
+        case GH3X2X_PPG_DUMP_MODE_ADDR:\r
+            GH3X2X_DumpModeSet(usVirtualRegValue);\r
+            break;\r
+        case GH3X2X_BG_LEVEL_SET_ADDR:\r
+            //GH3X2X_BgLevelSet(usVirtualRegValue);\r
+            break;\r
+        default: // do nothing\r
+            break;\r
+        }\r
+    } // end of else if (usVirtualRegAddr < GH3X2X_VDUMP_END_REG_ADDR)\r
+    else if (usVirtualRegAddr < GH3X2X_G_SENSOR_CFG_ADDR) // fifo info\r
+    {\r
+        switch (usVirtualRegAddr)\r
+        {\r
+        case GH3X2X_FIFO_PACKAGE_SEND_MODE_ADDR:\r
+            g_uchFifoPackageMode = usVirtualRegValue;\r
+            break;\r
+        default: // do nothing\r
+            break;\r
+        }\r
+    }\r
+    else if (usVirtualRegAddr < GH3X2X_SOFT_AGC_PARA_ADDR)\r
+    {\r
+        switch (usVirtualRegAddr)\r
+        {\r
+        case GH3X2X_GSENSOR_CTRL_ADDR:\r
+            g_uchGsensorEnable = GH3X2X_GET_LOW_BYTE_FROM_WORD(usVirtualRegValue);\r
+            break;\r
+        default: // do nothing\r
+            break;\r
+        }\r
+    } // end of else if (usVirtualRegAddr < GH3X2X_VGS_END_REG_ADDR)\r
+    else if (usVirtualRegAddr < GH3X2X_CAP_CFG_ADDR) // agc config\r
+    {\r
+        #if __SUPPORT_SOFT_AGC_CONFIG__\r
+        GH3X2X_WriteAgcConfigWithVirtualReg(usVirtualRegAddr, usVirtualRegValue);\r
+        #endif\r
+\r
+    } // end of else if (usVirtualRegAddr < GH3X2X_VAGC_END_REG_ADDR)\r
+    else if (usVirtualRegAddr < GH3X2X_TEMP_CFG_ADDR)\r
+    {\r
+        switch (usVirtualRegAddr)\r
+        {\r
+        case GH3X2X_CAP_CTRL_ADDR:\r
+            g_uchCapEnable = GH3X2X_GET_LOW_BYTE_FROM_WORD(usVirtualRegValue);\r
+            break;\r
+        default: // do nothing\r
+            break;\r
+        }\r
+    } \r
+    else if (usVirtualRegAddr < GH3X2X_CHNL_MAP_ADDR)\r
+    {\r
+        switch (usVirtualRegAddr)\r
+        {\r
+        case GH3X2X_TEMP_CTRL_ADDR:\r
+            g_uchTempEnable = GH3X2X_GET_LOW_BYTE_FROM_WORD(usVirtualRegValue);\r
+            break;\r
+        default: // do nothing\r
+            break;\r
+        }\r
+    } \r
+    else if (usVirtualRegAddr < GH3X2X_FS_PARA_ADDR)\r
+    {\r
+        GH3X2X_WriteChnlMapConfigWithVirtualReg(usVirtualRegAddr, usVirtualRegValue);\r
+    }\r
+    else if (usVirtualRegAddr < GH3X2X_REG_IS_VIRTUAL0X3_BIT)\r
+    {\r
+        GH3X2X_WriteFsConfigWithVirtualReg(usVirtualRegAddr, usVirtualRegValue);\r
+    }\r
+}\r
+\r
+#endif\r
+\r
+#if __FUNC_TYPE_ECG_ENABLE__\r
+void GH3X2X_WriteEcgDrvConfigWithVirtualReg(GU16 usVirtualRegAddr, GU16 usVirtualRegValue)\r
+{\r
+    GU16 usValIndex;\r
+    switch (usVirtualRegAddr)\r
+    {\r
+    case GH3X2X_ECG_SETTING0_ADDR:\r
+    case GH3X2X_ECG_SETTING1_ADDR:\r
+    case GH3X2X_ECG_SETTING2_ADDR:\r
+        usValIndex = (usVirtualRegAddr - GH3X2X_ECG_SETTING0_ADDR) / GH3X2X_REG_ADDR_SIZE;\r
+        GH3X2X_SlaverSoftLeadPramSet(usVirtualRegValue, usValIndex);   \r
+        break;\r
+    case GH3X2X_ECG_SETTING3_ADDR:\r
+        GH3x2xSetEcgOutputFs(usVirtualRegValue);\r
+        break;\r
+    default: // do nothing\r
+        break;\r
+    }\r
+}\r
+#endif\r
+\r
+\r
+void GH3X2X_WriteDrvConfigWithVirtualReg(GU32 unFunctionID, GU16 usVirtualRegAddr, GU16 usVirtualRegValue)\r
+{\r
+    switch (unFunctionID)\r
+    {\r
+    case GH3X2X_FUNC_OFFSET_ADT:\r
+               #if __FUNC_TYPE_ECG_ENABLE__   //only for ADT by using ecg-electronic\r
+        GH3X2X_WriteAdtDrvConfigWithVirtualReg(usVirtualRegAddr, usVirtualRegValue);\r
+               #endif\r
+        break;\r
+    case GH3X2X_FUNC_OFFSET_ECG:\r
+               #if __FUNC_TYPE_ECG_ENABLE__\r
+        GH3X2X_WriteEcgDrvConfigWithVirtualReg(usVirtualRegAddr, usVirtualRegValue);\r
+               #endif\r
+        break;\r
+    default:\r
+        break;\r
+    }\r
+}\r
+\r
+/**\r
+ * @fn     GS8 GH3X2X_WriteAlgorithmConfigWithVirtualReg(GU16 usVirtualRegAddr, GU16 usVirtualRegValue)\r
+ *\r
+ * @brief  Write algorithm param config with virtual reg\r
+ *\r
+ * @attention   Virtual reg addr has del control bits, so reg addr is [0:11] valid.\r
+ *\r
+ * @param[in]   usVirtualRegAddr        virtual reg addr\r
+ * @param[in]   usVirtualRegValue       virtual reg value\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_WriteFunctionConfigWithVirtualReg(GU16 usVirtualRegAddr, GU16 usVirtualRegValue)\r
+{\r
+    GH3X2X_DEBUG_LOG_PARAM("%s\r\n", __FUNCTION__);\r
+    GU32 unFunctionID = (usVirtualRegAddr - GH3X2X_REG_IS_VIRTUAL0X3_BIT) / GH3X2X_VREG_FUNCTION_OFFSET;\r
+    if (usVirtualRegAddr >= GH3X2X_ADT_DRV_CFG_ADDR + GH3X2X_VREG_FUNCTION_OFFSET * unFunctionID &&\\r
+        usVirtualRegAddr < GH3X2X_ADT_ALG_CFG_ADDR + GH3X2X_VREG_FUNCTION_OFFSET * unFunctionID)\r
+    {\r
+        GH3X2X_WriteDrvConfigWithVirtualReg(unFunctionID, usVirtualRegAddr, usVirtualRegValue);\r
+    }\r
+    else if (usVirtualRegAddr >= GH3X2X_ADT_ALG_CFG_ADDR + GH3X2X_VREG_FUNCTION_OFFSET * unFunctionID &&\\r
+             usVirtualRegAddr < GH3X2X_ADT_DRV_CFG_ADDR + GH3X2X_VREG_FUNCTION_OFFSET * (unFunctionID + 1))\r
+    {\r
+        /* call hook */\r
+        HOOK_FUNC_CALL(g_pGh3x2xWriteAlgConfigWithVirtualRegHookFunc, (usVirtualRegAddr, usVirtualRegValue) );\r
+    }\r
+}\r
+\r
+\r
+\r
+/**\r
+ * @fn     GS8 GH3X2X_WriteVirtualReg(GU16 usVirtualRegAddr, GU16 usVirtualRegValue)\r
+ *\r
+ * @brief  Write virtual reg val, for software param config\r
+ *\r
+ * @attention   Virtual reg addr has del control bits, so reg addr is [0:11] valid.\r
+ *\r
+ * @param[in]   usVirtualRegAddr        virtual reg addr\r
+ * @param[in]   usVirtualRegValue       virtual reg value\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_WriteVirtualReg(GU16 usVirtualRegAddr, GU16 usVirtualRegValue)\r
+{\r
+    if (usVirtualRegAddr < GH3X2X_REG_IS_VIRTUAL0X3_BIT)\r
+    {\r
+        if (usVirtualRegAddr > GH3X2X_TOP_INFO_ADDR && 0 == g_stGhDrvConfigManger.usCurrentConfigFlag)\r
+        {\r
+            GH3X2X_DEBUG_LOG_PARAM("[%s]:Config version error!!!\r\n", __FUNCTION__);\r
+        }\r
+        else\r
+        {\r
+            GH3X2X_SW_CONFIG_WRITE(usVirtualRegAddr, usVirtualRegValue);\r
+        }\r
+    }\r
+    else if (usVirtualRegAddr < GH3X2X_FINISH_FLAG_ADDR)\r
+    {\r
+        GH3X2X_FUNCTION_CONFIG_WRITE(usVirtualRegAddr, usVirtualRegValue);\r
+    }\r
+    \r
+    switch (usVirtualRegAddr)\r
+    {\r
+        case GH3X2X_END_FLAG_ADDR: // virtual reg write finish\r
+            if (g_stGhDrvConfigManger.usCurrentConfigFlag == 1)\r
+            {\r
+                g_stGhDrvConfigManger.usCurrentConfigFlag = 0;\r
+            }\r
+            else\r
+            {\r
+                GH3X2X_DEBUG_LOG_PARAM("[%s]:Config version error!!!\r\n", __FUNCTION__);\r
+            }\r
+            GH3X2X_DEBUG_LOG_PARAM("[GH3X2X_WriteVirtualReg]: unGhFuncSupportedAtCurCfg = 0x%X.\r\n", g_stGhDrvConfigManger.unGhFuncSupportedAtCurCfg);\r
+            HOOK_FUNC_CALL(g_pGh3x2xConfigSetStopHookFunc, ());\r
+            break;\r
+        case GH3X2X_TOP_INFO_ADDR:\r
+            GhDrvConfigManagerInit();\r
+            HOOK_FUNC_CALL(g_pGh3x2xConfigSetStartHookFunc, ());\r
+            g_stGhDrvConfigManger.usCurrentConfigFlag = 1;\r
+            GH3X2X_InitSensorParameters();\r
+            GH3X2X_SetConfigFuncMode(0);\r
+            break;\r
+        default:\r
+            break;\r
+    }\r
+    g_stGhDrvConfigManger.unGhFuncSupportedAtCurCfg |= GhGetFunctionIdViaVirReg(usVirtualRegAddr, usVirtualRegValue);\r
+}\r
+\r
+/**\r
+ * @fn     GU16 GH3X2X_ReadVirtualReg(GU16 usVirtualRegAddr)\r
+ *\r
+ * @brief  Read virtual reg val, for software param config\r
+ *\r
+ * @attention   Virtual reg addr has del control bits, so reg addr is [0:11] valid.\r
+ *\r
+ * @param[in]   usVirtualRegAddr        virtual reg addr\r
+ * @param[out]  None\r
+ *\r
+ * @return  virtual reg val\r
+ */\r
+GU16 GH3X2X_ReadVirtualReg(GU16 usVirtualRegAddr)\r
+{\r
+    GU16 usVirtualRegData = 0;\r
+#if GH3X2X_SUPPORT_READ_BACK_VIRTUAL_REG\r
+\r
+#endif\r
+    return usVirtualRegData;\r
+}\r
+\r
+void GH3X2X_CheckChipModel(void)\r
+{\r
+    GU16 usRegVal = 0;\r
+    usRegVal = GH3X2X_ReadReg(GH3X2X_EFUSE_CTRL_EFUSE1_AUTOLOAD_0_ADDR);\r
+    //if chip is 3026,disable rx2 and rx3\r
+    if(((usRegVal >> 5)&0x07) == 1)\r
+    {\r
+        for(GU8 uchSlotNo = 0; uchSlotNo < 8; uchSlotNo++)\r
+        {\r
+            GH3X2X_WriteRegBitField(GH3X2X_SLOT0_CTRL_0_REG_ADDR + GH3X2X_SLOT_CTRL_OFFSET*uchSlotNo,4,5, 0);\r
+        }\r
+    }\r
+}\r
+\r
+/**\r
+ * @fn     GS8 GH3X2X_LoadNewRegConfigArr(const STGh3x2xReg *pstRegConfigArr, GU16 usRegConfigLen)\r
+ *\r
+ * @brief  Load new gh3x2x reg config array\r
+ *\r
+ * @attention   If reg val don't need verify, should set reg addr bit 12;\r
+ *              If reg is virtual reg, should set reg addr bit 13;\r
+ *              e.g.      need config reg 0x0000: 0x0611\r
+ *                        {0x0000, 0x0611} //verify write by read reg\r
+ *                        {0x1000, 0x0611} //don't need verify write val\r
+ *                        {0x2000, 0x0611} //set virtual reg\r
+ *\r
+ * @param[in]   pstRegConfigArr       pointer to the reg struct array\r
+ * @param[in]   usRegConfigLen        reg struct array length\r
+ * @param[out]  None\r
+ *\r
+ * @return  errcode\r
+ * @retval  #GH3X2X_RET_OK               return successfully\r
+ * @retval  #GH3X2X_RET_COMM_ERROR       gh3x2x communicate error\r
+ */\r
+GS8 GH3X2X_LoadNewRegConfigArr(const STGh3x2xReg *pstRegConfigArr, GU16 usRegConfigLen , GU8 uchChipIndex)\r
+{\r
+    GS8 chRet = GH3X2X_RET_OK;\r
+    GU16 usIndex = 0;\r
+    GU16 usReadRegVal = 0;\r
+\r
+    GH3X2X_DEBUG_LOG_PARAM("%s\r\n", __FUNCTION__);\r
+    if ((pstRegConfigArr != GH3X2X_PTR_NULL) && (usRegConfigLen != 0))\r
+    {\r
+        GH3X2X_WAIT_CHIP_WAKEUP();\r
+        for (usIndex = 0; usIndex < usRegConfigLen; usIndex++) // write GH3X2X reg.\r
+        {\r
+            switch (GH3X2X_GET_BIT_IS_SET(pstRegConfigArr[usIndex].usRegAddr))\r
+            {\r
+            case 0:\r
+                GH3X2X_WriteReg(pstRegConfigArr[usIndex].usRegAddr, pstRegConfigArr[usIndex].usRegData);\r
+                usReadRegVal = GH3X2X_ReadReg(pstRegConfigArr[usIndex].usRegAddr);\r
+                if (usReadRegVal != pstRegConfigArr[usIndex].usRegData)\r
+                {\r
+                    GH3X2X_DEBUG_LOG_PARAM("[%s]:reg verify error! addr:0x%.4x,w_val:0x%.4x,r_val:0x%.4x\r\n", __FUNCTION__,\r
+                                            GH3X2X_GET_REG_REAL_ADRR(pstRegConfigArr[usIndex].usRegAddr),\r
+                                            pstRegConfigArr[usIndex].usRegData, usReadRegVal);\r
+                    chRet = GH3X2X_RET_COMM_ERROR;\r
+                }\r
+                break;\r
+            default:\r
+                if(0 == uchChipIndex)\r
+                {\r
+                    /* write & verify virtual reg, if verify error, only log error, shouldn't return error */\r
+                    GH3X2X_WriteVirtualReg(pstRegConfigArr[usIndex].usRegAddr, pstRegConfigArr[usIndex].usRegData);\r
+                }\r
+                #if 0\r
+                usReadRegVal = GH3X2X_ReadVirtualReg(pstRegConfigArr[usIndex].usRegAddr);\r
+                if (usReadRegVal != pstRegConfigArr[usIndex].usRegData)\r
+                {\r
+                    GH3X2X_DEBUG_LOG_PARAM("[%s]:vreg reg verify error! addr:0x%.4x,w_val:0x%.4x,r_val:0x%.4x\r\n", __FUNCTION__,\r
+                                            pstRegConfigArr[usIndex].usRegAddr,\r
+                                            pstRegConfigArr[usIndex].usRegData, usReadRegVal);\r
+                }\r
+                #endif\r
+                break;\r
+            }\r
+        } // end of for (usIndex = 0; usIndex < usRegConfigLen; usIndex++)\r
+        GH3X2X_WAIT_CHIP_DSLP();\r
+    } // end of if ((pstRegConfigArr != GH3X2X_PTR_NULL) && (usRegConfigLen != 0))\r
+    GH3X2X_CheckChipModel();\r
+    return chRet;\r
+}\r
+\r
+\r
+\r
+\r
+void GH3X2X_SetCurrentConfigFlag(GU8 value)\r
+{\r
+    g_stGhDrvConfigManger.usCurrentConfigFlag = value;\r
+}\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/driver/src/gh_drv_control.c b/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/driver/src/gh_drv_control.c
new file mode 100644 (file)
index 0000000..d76c7ce
--- /dev/null
@@ -0,0 +1,4314 @@
+/**\r
+ * @copyright (c) 2003 - 2022, Goodix Co., Ltd. All rights reserved.\r
+ *\r
+ * @file    gh3x2x_drv_control.c\r
+ *\r
+ * @brief   gh3x2x control functions\r
+ *\r
+ * @version ref gh3x2x_drv_version.h\r
+ *\r
+ */\r
+\r
+#include "gh_drv_version.h"\r
+#include "gh_drv_common.h"\r
+#include "gh_drv.h"\r
+#include "gh_drv_interface.h"\r
+#include "gh_drv_control.h"\r
+\r
+#include "gh_uprotocol.h"\r
+#include "gh_ecg.h"\r
+#include "gh_drv_dump.h"\r
+#include "gh_agc.h"\r
+#include "gh_drv_config.h"\r
+#include "gh_zip.h"\r
+#include "gh_demo.h"\r
+#include "gh_demo_config.h"\r
+#include "gh_demo_inner.h"\r
+#include "gh_demo_version.h"\r
+#include "gh_drv.h"\r
+#include "gh_multi_sen_pro.h"\r
+#include "gh_agc.h"\r
+\r
+GU8 g_uchFifoPackageID = 0xFF;\r
+GU8 g_uchFifoPackageMode = 0;\r
+//GU8 *gpuchSendFifoPackage = GH3X2X_PTR_NULL;\r
+GU32 g_unSendFifoPackageCnt = 0;\r
+\r
+//function set in config\r
+GU32 g_unConfigFuncMode = 0;\r
+\r
+GU8 g_uchAlgoEnableFlag = 1;\r
+\r
+GU8 g_uchSingleChipModeEnableFlag = 0; //1��spi/iic only operate one chip\r
+\r
+GU8 g_uchOddEvenChangeFlag = 1;\r
+\r
+/// soft event\r
+GU32 g_unSoftEvent = 0;  //G202008231001 wanpeng\r
+\r
+/// G sensor enable flag\r
+GU8 g_uchGsensorEnable = 0;\r
+\r
+/// Cap enable flag\r
+GU8 g_uchCapEnable = 0;\r
+\r
+/// Temp enable flag\r
+GU8 g_uchTempEnable = 0;\r
+\r
+GU8 g_uchResetFromProtocolFlag = 0;\r
+\r
+/// gh3x2x status\r
+GU8 g_uchGh3x2xStatus = GH3X2X_STATUS_NO_INIT;\r
+\r
+/// current fifo water line\r
+GU16 g_usCurrentFiFoWaterLine = 0;\r
+\r
+/// init hook func ptr\r
+pfnNormalHookFunc g_pGh3x2xInitHookFunc = GH3X2X_PTR_NULL;\r
+\r
+/// start hook func ptr\r
+pfnNormalHookFunc g_pGh3x2xStartHookFunc = GH3X2X_PTR_NULL;\r
+\r
+/// stop hook func ptr\r
+pfnNormalHookFunc g_pGh3x2xStopHookFunc = GH3X2X_PTR_NULL;\r
+\r
+/// get rawdata hook func ptr\r
+pfnGetRawdataHookFunc g_pGh3x2xGetRawdataHookFunc = GH3X2X_PTR_NULL;\r
+\r
+/// get struct hook func ptr\r
+pfnGetIoStructInfo g_pGh3x2xGetIoStructInfoHookFunc = GH3X2X_PTR_NULL;\r
+\r
+/// set algo config hook func ptr\r
+pfnWriteAlgConfigWithVirtualReg g_pGh3x2xWriteAlgConfigWithVirtualRegHookFunc = GH3X2X_PTR_NULL;\r
+\r
+/// config start set hook func ptr\r
+pfnNormalHookFunc g_pGh3x2xConfigSetStartHookFunc = GH3X2X_PTR_NULL;\r
+\r
+/// config stop set hook func ptr\r
+pfnNormalHookFunc g_pGh3x2xConfigSetStopHookFunc = GH3X2X_PTR_NULL;\r
+\r
+/// start hook func ptr\r
+pfnNormalHookFunc g_pGh3x2xResetByProtocolHookFunc = GH3X2X_PTR_NULL;\r
+\r
+/// read int pin status func ptr\r
+pfnReadPinStatus g_pGh3x2xReadIntPinStatusFunc = GH3X2X_PTR_NULL;\r
+\r
+/// read reset pin status func ptr\r
+pfnReadPinStatus g_pGh3x2xReadResetPinStatusFunc = GH3X2X_PTR_NULL;\r
+\r
+/// read spcs pin status func ptr\r
+pfnReadPinStatus g_pGh3x2xReadSpcsPinStatusFunc = GH3X2X_PTR_NULL;\r
+\r
+/// read spdo pin status func ptr\r
+pfnReadPinStatus g_pGh3x2xReadSpdoPinStatusFunc = GH3X2X_PTR_NULL;\r
+\r
+/// set reset pin level spi\r
+pfnSetPinLevel g_pGh3x2xResetPinLevelControlFunc = GH3X2X_PTR_NULL;\r
+\r
+#if     GH3X2X_PMU_FIFO_POWER_CTRL_ENABLED\r
+\r
+/// fifo power ctrl fifo control reg cache var\r
+GU16 g_pusPmuFifoModuleCtrlVal[2] = {0x0000, 0x0000};\r
+\r
+/// for fifo power ctrl cache status\r
+GU8 g_puchPmuFifoModuleCtrlCacheStatus[2] = {0,0};\r
+\r
+/// max rawdata num read from fifo every time\r
+GU16 g_usMaxNumReadFromFifo = GH3X2X_FIFO_DATA_BYTES_MAX_LEN;\r
+\r
+#endif\r
+\r
+\r
+GU8 g_uchActiveChipResetFlag = 0;   //1: user have done chip reset(soft reset and hardwear reset) actively   gh3x2x_init will clear it \r
+GU8 g_uchChipResetRecoveringFlag = 0;  //0: is not in chip reset recovering flag  1: is in chip reset recovering\r
+\r
+extern GU32 g_unFuncStartedBitmap;\r
+extern GU8 g_uchGhx2xChipSleepFlag;\r
+extern GU8 g_uchChipDivZeroFlag;\r
+/**\r
+ * @fn     void GH3X2X_RegisterHookFunc(void (*pInitHookFunc)(void),\r
+ *                            void (*pStartHookFunc)(void),\r
+ *                           void (*pStopHookFunc)(void),\r
+ *                            void (*pGetRawdataHookFunc)(GU8 *puchReadDataBuffer, GU16 usReadDataLen))\r
+ *\r
+ * @brief  Register hook function callback\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   pInitHookFunc           pointer to init hook function \r
+ * @param[in]   pStartHookFunc          pointer to start hook function \r
+ * @param[in]   pStopHookFunc           pointer to stop hook function \r
+ * @param[in]   pGetRawdataHookFunc     pointer to get rawdata hook function\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_RegisterHookFunc(void (*pInitHookFunc)(void),\r
+                             void (*pStartHookFunc)(void),\r
+                             void (*pStopHookFunc)(void),\r
+                             void (*pGetRawdataHookFunc)(GU8 *puchReadDataBuffer, GU16 usReadDataLen),\r
+                             void (*pGetIoStructInfoHookFunc)(const STGh3x2xFrameInfo * const pstFrameInfo),\r
+                             void (*pResetByProtocolHookFunc)(void),\r
+                             void (*pConfigSetStartHookFunc)(void),\r
+                             void (*pConfigSetStopHookFunc)(void),\r
+                             void (*pfnWriteAlgConfigWithVirtualReg)(GU16 usVirtualRegAddr, GU16 usVirtualRegValue))\r
+{\r
+    g_pGh3x2xInitHookFunc = pInitHookFunc;\r
+    g_pGh3x2xStartHookFunc = pStartHookFunc;\r
+    g_pGh3x2xStopHookFunc = pStopHookFunc;\r
+    g_pGh3x2xGetRawdataHookFunc = pGetRawdataHookFunc;\r
+    g_pGh3x2xGetIoStructInfoHookFunc = pGetIoStructInfoHookFunc;\r
+    g_pGh3x2xResetByProtocolHookFunc = pResetByProtocolHookFunc;\r
+    g_pGh3x2xConfigSetStartHookFunc = pConfigSetStartHookFunc;\r
+    g_pGh3x2xConfigSetStopHookFunc = pConfigSetStopHookFunc;\r
+    g_pGh3x2xWriteAlgConfigWithVirtualRegHookFunc = pfnWriteAlgConfigWithVirtualReg;\r
+    GH3X2X_DEBUG_LOG_PARAM("%s\r\n", __FUNCTION__);\r
+}\r
+\r
+/**\r
+ * @fn     GS8 GH3X2X_ExitLowPowerMode(void)\r
+ *\r
+ * @brief  Exit lowpower mode, in this mode, can read&write reg with gh3x2x\r
+ *\r
+ * @attention   Power consumption bigger than lowpower mode, detaile ref gh3x2x datasheet\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  errcode\r
+ * @retval  #GH3X2X_RET_OK               return successfully\r
+ * @retval  #GH3X2X_RET_GENERIC_ERROR    exit low power mode error\r
+ */\r
+GS8 GH3X2X_ExitLowPowerMode(void)\r
+{\r
+    GS8 chRet = GH3X2X_RET_GENERIC_ERROR;\r
+    GH3X2X_DEBUG_LOG_PARAM("%s\r\n", __FUNCTION__);\r
+    GH3X2X_CHIP_WAKEUP(chRet);\r
+    return chRet;\r
+}\r
+\r
+/**\r
+ * @fn     GS8 GH3X2X_EnterLowPowerMode(void)\r
+ *\r
+ * @brief  Enter lowpower mode, in this mode, can't read&write reg with gh3x2x.\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  errcode\r
+ * @retval  #GH3X2X_RET_OK               return successfully\r
+ * @retval  #GH3X2X_RET_GENERIC_ERROR    enter low power mode error\r
+ */\r
+GS8 GH3X2X_EnterLowPowerMode(void)\r
+{\r
+    GS8 chRet = GH3X2X_RET_GENERIC_ERROR;\r
+    GH3X2X_DEBUG_LOG_PARAM("%s\r\n", __FUNCTION__);\r
+    GH3X2X_CHIP_SLEEP(chRet);\r
+    g_uchGhx2xChipSleepFlag |= (1 << g_uchGh3x2xChipOperateIndexRealtime);  //set sleep flag\r
+    return chRet;\r
+}\r
+\r
+/**\r
+ * @fn     GS8 GH3X2X_SoftReset(void)\r
+ *\r
+ * @brief  Gh3x2x softreset via i2c/spi, can read&write reg with gh3x2x after reset \r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  errcode\r
+ * @retval  #GH3X2X_RET_OK               return successfully\r
+ * @retval  #GH3X2X_RET_GENERIC_ERROR    exit low power mode error\r
+ */\r
+GS8 GH3X2X_SoftReset(void)\r
+{\r
+    GS8 chRet = GH3X2X_RET_GENERIC_ERROR;\r
+    GH3X2X_DEBUG_LOG_PARAM("%s\r\n", __FUNCTION__);\r
+    GH3X2X_CHIP_RESET(chRet);\r
+    if(0 == GH3X2X_GetSingleChipModeEnableFlag())\r
+    {\r
+        GH3X2X_SoftResetSlaveChip();\r
+    }\r
+    g_uchActiveChipResetFlag = 1;\r
+    if (g_uchResetFromProtocolFlag == 1)\r
+    {\r
+        g_uchResetFromProtocolFlag = 0;\r
+        HOOK_FUNC_CALL(g_pGh3x2xResetByProtocolHookFunc, () );  /* call hook */\r
+    }\r
+    return chRet;\r
+}\r
+\r
+#if !__GH3X2X_CASCADE_EN__\r
+void GH3X2X_SoftResetSlaveChip(void){}\r
+#else\r
+void GH3X2X_SoftResetSlaveChip(void)\r
+{\r
+    GH3X2X_CascadeOperationSlaverChip();\r
+    GH3X2X_SEND_RESET_CMD();\r
+    GH3X2X_CascadeOperationMasterChip();\r
+}\r
+#endif\r
+\r
+#if defined(GH3X2X_LOG_DEBUG) && (GH3X2X_LOG_DEBUG > 0) // debug level > 0\r
+/**\r
+ * @fn     void GH3X2X_LogConfigArr(STGh3x2xReg *pstRegConfigArr, GU16 usRegConfigLen)\r
+ *\r
+ * @brief  log gh3x2x reg config array\r
+ *\r
+ * @attention   Only use for dbg version;\r
+ *\r
+ * @param[in]   pstRegConfigArr       pointer to the reg struct array\r
+ * @param[in]   usRegConfigLen        reg struct array length\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_LogConfigArr(STGh3x2xReg *pstRegConfigArr, GU16 usRegConfigLen)\r
+{\r
+    GU16 usIndex = 0;\r
+    GH3X2X_DEBUG_LOG_PARAM("Log reg config arr:\r\n");\r
+    if ((pstRegConfigArr != GH3X2X_PTR_NULL) && (usRegConfigLen != 0))\r
+    {\r
+        for (usIndex = 0; usIndex < usRegConfigLen; usIndex++)\r
+        {\r
+            GH3X2X_DEBUG_LOG_PARAM("addr:0x%.4x, val:0x%.4x\r\n", pstRegConfigArr[usIndex].usRegAddr,\r
+                                                                pstRegConfigArr[usIndex].usRegData);\r
+        }\r
+    }\r
+}\r
+#endif\r
+\r
+/**\r
+ * @fn     GS8 GH3X2X_DumpRegs(STGh3x2xReg *pstDumpRegsArr, GU16 usDumpRegsStartAddr, GU16 usDumpRegsLen)\r
+ *\r
+ * @brief  Dump gh3x2x regs\r
+ *\r
+ * @attention   usDumpRegsStartAddr only allow even address, if param set odd address val that val & 0xFFFE in api;\r
+ *              If address greater than reg max addres 0xFFFE, it will return GH3X2X_RET_GENERIC_ERROR.\r
+ *\r
+ * @param[out]  pstDumpRegsArr           pointer to the dump reg struct output\r
+ * @param[in]   usDumpRegsStartAddr     dump reg address\r
+ * @param[in]   usDumpRegsLen           dump reg length\r
+ * @param[out]  None\r
+ *\r
+ * @return  errcode\r
+ * @retval  #GH3X2X_RET_OK               return successfully\r
+ * @retval  #GH3X2X_RET_GENERIC_ERROR    dump gh3x2x address out of bounds\r
+ */\r
+GS8 GH3X2X_DumpRegs(STGh3x2xReg *pstDumpRegsArr, GU16 usDumpRegsStartAddr, GU16 usDumpRegsLen)\r
+{\r
+    GS8 chRet = GH3X2X_RET_OK;\r
+    GU16 usIndex = 0;\r
+    GU16 usDumpRegsAddr = usDumpRegsStartAddr & GH3X2X_REG_ADDR_EVEN_FIXED; // just allow even addr val\r
+\r
+    GH3X2X_DEBUG_LOG_PARAM("%s\r\n", __FUNCTION__);\r
+    if ((pstDumpRegsArr != GH3X2X_PTR_NULL) && (usDumpRegsLen != 0))\r
+    {\r
+        GH3X2X_WAIT_CHIP_WAKEUP();\r
+        for (usIndex = 0; usIndex < usDumpRegsLen; usIndex++) // read GH3X2X reg.\r
+        {\r
+            pstDumpRegsArr[usIndex].usRegAddr = usDumpRegsAddr;\r
+            pstDumpRegsArr[usIndex].usRegData = GH3X2X_ReadReg(usDumpRegsAddr);\r
+            if (usDumpRegsAddr < GH3X2X_REG_ADDR_MAX) // last reg addr : 0xfffe\r
+            {\r
+                usDumpRegsAddr += GH3X2X_REG_ADDR_SIZE;\r
+            }\r
+            else\r
+            {\r
+                GH3X2X_DEBUG_LOG_PARAM("Dump reg address out of bounds!\r\n");\r
+                chRet = GH3X2X_RET_GENERIC_ERROR;\r
+                break;\r
+            }\r
+        }\r
+        GH3X2X_WAIT_CHIP_DSLP();\r
+    }\r
+    return chRet;\r
+}\r
+\r
+/**\r
+ * @fn     GS8 GH3X2X_CommunicateConfirm(void)\r
+ *\r
+ * @brief  Communication operation interface confirm\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  errcode\r
+ * @retval  #GH3X2X_RET_OK               return successfully\r
+ * @retval  #GH3X2X_RET_COMM_ERROR       gh3x2x communicate error\r
+ */\r
+GS8 GH3X2X_CommunicateConfirm(void)\r
+{\r
+    GU8 uchIndex = GH3X2X_COMMUNICATE_CONFIRM_MAX_CNT;\r
+    GS8 chRet = GH3X2X_RET_COMM_ERROR;\r
+    GU16 uchReadData;\r
+    GU16 uchWriteData;\r
+\r
+    GH3X2X_DEBUG_LOG_PARAM("%s\r\n", __FUNCTION__);\r
+    do\r
+    {\r
+        GH3X2X_WAIT_CHIP_WAKEUP();\r
+        if (GH3X2X_ReadReg(GH3X2X_CHIP_READY_CODE_REG_ADDR) == GH3X2X_CHIP_READY_REG_VAL)\r
+        {\r
+            uchReadData = GH3X2X_ReadReg(GH3X2X_RG_SLOT_TMR0_REG_ADDR);\r
+            GH3X2X_DEBUG_LOG_PARAM("slot_time0 reg = %d\r\n", (int)uchReadData);\r
+            uchWriteData = ~uchReadData;\r
+            GH3X2X_WriteReg(GH3X2X_RG_SLOT_TMR0_REG_ADDR, uchWriteData);\r
+            uchReadData = GH3X2X_ReadReg(GH3X2X_RG_SLOT_TMR0_REG_ADDR);\r
+            GH3X2X_DEBUG_LOG_PARAM("slot_time0 reg = %d\r\n", (int)uchReadData);\r
+            if (uchWriteData == uchReadData)\r
+            {\r
+                chRet = GH3X2X_RET_OK;\r
+                uchWriteData = ~uchReadData;\r
+                GH3X2X_WriteReg(GH3X2X_RG_SLOT_TMR0_REG_ADDR, uchWriteData);\r
+                break;\r
+            }\r
+        }\r
+        else\r
+        {\r
+            GH3X2X_DEBUG_LOG_PARAM("ready code reg is error !!! %s\r\n", __FUNCTION__);\r
+        }\r
+        uchIndex--;\r
+    } while (uchIndex > 0);\r
+    GH3X2X_WAIT_CHIP_DSLP();\r
+\r
+    return chRet;\r
+}\r
+\r
+\r
+extern GU8 g_uchEcgCascadeEn;\r
+extern GU8 g_uchEcgCascadeWriteRegVerifyEn;\r
+///0: not init  1: initialized\r
+GU8 g_uchEcgCascadeSlaveInitSuccess;\r
+\r
+void Gh3x2x_CHECK_0x0088_Ex(void)\r
+{\r
+    GH3X2X_CHECK_0x0088();\r
+}\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+#if !__GH3X2X_CASCADE_EN__\r
+void GH3X2X_LoadSlaveCfgForCascadeMode(void)\r
+{}\r
+#else\r
+void GH3X2X_LoadSlaveCfgForCascadeMode(void)\r
+{\r
+\r
+    GH3X2X_CascadeOperationSlaverChip();\r
+\r
+    /* clear int status. */\r
+    GH3X2X_WAIT_CHIP_WAKEUP();\r
+    GH3X2X_WriteReg(GH3X2X_INT_STR_REG_ADDR, GH3X2X_INT_STR_MSK_ALL_BIT);\r
+    GH3X2X_WAIT_CHIP_DSLP();\r
+    if(GH3X2X_CascadeGetEcgEnFlag())\r
+    {\r
+        GH3X2X_DEBUG_LOG_PARAM("Slaver is enable!\r\n");\r
+        //g_uchEcgCascadeEn = 1;\r
+        g_uchEcgCascadeSlaveInitSuccess = 0;\r
+        //Write the others chip's reg\r
+        \r
+        // GU16 lusRegLen = sizeof(stGh3x2xEcgCascadeSlaveRealReglist) / sizeof(STGh3x2xReg);\r
+        GU16 lusRegLen = g_usEcgCascadeSlaveRealRegLen;\r
+        //GH3X2X_WAIT_CHIP_WAKEUP();   \r
+#if 0\r
+        GU16 usReadRegVal = 0;\r
+        for (GU16 lusIndex = 0; lusIndex < lusRegLen; lusIndex++)\r
+        {\r
+            GH3X2X_WriteReg(stGh3x2xEcgCascadeSlaveRealReglist[lusIndex].usRegAddr,\r
+                                     stGh3x2xEcgCascadeSlaveRealReglist[lusIndex].usRegData);\r
+\r
+            /* need verify val. */\r
+            if (g_uchEcgCascadeWriteRegVerifyEn)\r
+            {\r
+                usReadRegVal = GH3X2X_ReadReg(stGh3x2xEcgCascadeSlaveRealReglist[lusIndex].usRegAddr);\r
+                if (usReadRegVal != stGh3x2xEcgCascadeSlaveRealReglist[lusIndex].usRegData)\r
+                {\r
+                    GH3X2X_DEBUG_LOG_PARAM("reg verify error! addr:0x%.4x,w_val:0x%.4x,r_val:0x%.4x\r\n",\r
+                                            stGh3x2xEcgCascadeSlaveRealReglist[lusIndex].usRegAddr,\r
+                                            stGh3x2xEcgCascadeSlaveRealReglist[lusIndex].usRegData, usReadRegVal);\r
+                    //chRet = GH3X2X_RET_COMM_ERROR;\r
+                    g_uchEcgCascadeSlaveInitSuccess = 0;\r
+                    break;\r
+                }\r
+            }\r
+            else\r
+            {\r
+                GH3X2X_DEBUG_LOG_PARAM("reg don't verify! addr:0x%.4x,w_val:0x%.4x\r\n",\r
+                                            stGh3x2xEcgCascadeSlaveRealReglist[lusIndex].usRegAddr,\r
+                                            stGh3x2xEcgCascadeSlaveRealReglist[lusIndex].usRegData);\r
+            }\r
+            if ((lusRegLen -1)  == lusIndex)\r
+            {\r
+                g_uchEcgCascadeSlaveInitSuccess = 1;\r
+            }\r
+        }\r
+#else\r
+        if (GH3X2X_RET_OK == GH3X2X_LoadNewRegConfigArr(stGh3x2xEcgCascadeSlaveRealReglist, lusRegLen, 1))\r
+        {\r
+            g_uchEcgCascadeSlaveInitSuccess = 1;\r
+        }\r
+        else\r
+        {\r
+            g_uchEcgCascadeSlaveInitSuccess = 0;\r
+        }\r
+#endif\r
+       //GH3X2X_WAIT_CHIP_DSLP();\r
+      \r
+       //modify ecg chnl map and chnl num\r
+       g_pstGh3x2xFrameInfo[GH3X2X_FUNC_OFFSET_ECG]->pstFunctionInfo->uchChnlNum = 2;\r
+       if(g_pstGh3x2xFrameInfo[GH3X2X_FUNC_OFFSET_ECG]->uchFuntionChnlLimit > 1)\r
+       {\r
+            g_pstGh3x2xFrameInfo[GH3X2X_FUNC_OFFSET_ECG]->pchChnlMap[1] = 0x08;\r
+       }\r
+   }\r
+    GH3X2X_CascadeOperationMasterChip();\r
+\r
+}\r
+#endif\r
+\r
+void GH3X2X_SensorPramInit(void)\r
+{\r
+    g_uchGsensorEnable = 0; \r
+    g_uchCapEnable = 0;     \r
+    g_uchTempEnable = 0;    \r
+}\r
+\r
+void GH3X2X_DrvControlInit(void)\r
+{\r
+    g_uchAlgoEnableFlag = 1;   \r
+    g_unSoftEvent = 0;\r
+    g_unConfigFuncMode = 0;\r
+    g_unFuncStartedBitmap = 0;\r
+    g_uchGh3x2xStatus = GH3X2X_STATUS_NO_INIT;\r
+    g_uchSingleChipModeEnableFlag = 0; \r
+    g_uchActiveChipResetFlag = 0;\r
+    g_uchGhx2xChipSleepFlag = 0x03;   \r
+    g_uchChipDivZeroFlag = 0;    \r
+}\r
+\r
+void GH3X2X_FifoControlInit(void)\r
+{\r
+    g_uchFifoPackageID = 0xFF; \r
+    g_uchFifoPackageMode = 0;\r
+    g_unSendFifoPackageCnt = 0;\r
+    g_usCurrentFiFoWaterLine = 0;             \r
+}\r
+\r
+void GH3X2X_ProtocolFlagInit(void)\r
+{\r
+    g_uchResetFromProtocolFlag = 0;               \r
+}\r
+\r
+\r
+void GH3X2XDrvConfigInit(void)\r
+{\r
+    GH3X2X_ProtocolFlagInit();\r
+    GH3X2X_FifoControlInit();\r
+    #if __FUNC_TYPE_ECG_ENABLE__\r
+    GH3X2X_AdtPramInit();\r
+    #endif\r
+    GH3X2X_SensorPramInit();\r
+    GH3X2X_DrvControlInit();\r
+}\r
+\r
+/**\r
+ * @fn     GS8 GH3X2X_Init(const STGh3x2xInitConfig *pstGh3x2xInitConfigParam)\r
+ *\r
+ * @brief  Init gh3x2x with configure parameters\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   pstGh3x2xInitConfigParam      pointer to gh3x2x init config param\r
+ * @param[out]  None\r
+ *\r
+ * @return  errcode\r
+ * @retval  #GH3X2X_RET_OK               return successfully\r
+ * @retval  #GH3X2X_RET_COMM_ERROR       gh3x2x communicate error\r
+ */\r
+GS8 GH3X2X_Init(const STGh3x2xInitConfig *pstGh3x2xInitConfigParam)\r
+{\r
+\r
+    GH3X2XDrvConfigInit();\r
+    GH3X2X_DEBUG_LOG_PARAM("%s : Lib Version : %s\r\n", __FUNCTION__, GH3X2X_GetDriverLibVersion());\r
+    if (GH3X2X_CommunicateConfirm() != GH3X2X_RET_OK) /* confirm GH3X2X communicate. */\r
+    {\r
+        GH3X2X_DEBUG_LOG_PARAM("communicate confirm error!\r\n");\r
+        return GH3X2X_RET_COMM_ERROR;\r
+    }\r
+\r
+    /* clear int status. */\r
+    GH3X2X_WAIT_CHIP_WAKEUP();\r
+    GH3X2X_WriteReg(GH3X2X_INT_STR_REG_ADDR, GH3X2X_INT_STR_MSK_ALL_BIT);\r
+    GH3X2X_WAIT_CHIP_DSLP();\r
+\r
+    if (pstGh3x2xInitConfigParam != GH3X2X_PTR_NULL)\r
+    {\r
+        /* load config */\r
+        if (GH3X2X_LoadNewRegConfigArr(pstGh3x2xInitConfigParam->pstRegConfigArr,\r
+            pstGh3x2xInitConfigParam->usConfigArrLen, 0) != GH3X2X_RET_OK)\r
+        {\r
+            return GH3X2X_RET_COMM_ERROR;\r
+        }\r
+        /* load slave chip config for cascade mode */\r
+        if(0 == GH3X2X_GetSingleChipModeEnableFlag())\r
+        {\r
+            GH3X2X_LoadSlaveCfgForCascadeMode();\r
+        }\r
+    }\r
+    else\r
+    {\r
+        GH3X2X_DEBUG_LOG_PARAM("gh init param is null!\r\n");\r
+    }\r
+\r
+    GH3X2X_WriteReg(0x0700,0x0020);\r
+    GH3X2X_WriteReg(0x0700,0x0030);\r
+    while(!(GH3X2X_ReadReg(0x0718)&0x0001));\r
+    GS8 err_code = (GS8)(GH3X2X_ReadReg(0x0712) & 0xFF);\r
+    GH3X2X_SetDrvEcode(err_code);\r
+    GH3X2X_SetConfigDrvEcode(pstGh3x2xInitConfigParam);\r
+\r
+    /* @ fix chip error code below here.\r
+     * e.g. otp clk err\r
+     */\r
+\r
+    /* @end of fix chip error. */\r
+\r
+    /* call hook */\r
+    GH3X2X_WAIT_CHIP_WAKEUP();\r
+    HOOK_FUNC_CALL(g_pGh3x2xInitHookFunc, () );\r
+    GH3X2X_WAIT_CHIP_DSLP();\r
+\r
+    /* set chip status inited. */\r
+    GH3X2X_SET_CHIP_INIED();\r
+    g_uchGh3x2xStatus = GH3X2X_STATUS_INITED;\r
+    return GH3X2X_RET_OK;\r
+}\r
+\r
+\r
+void GH3X2X_RecordAgcInfo(void)\r
+{\r
+    GU16 usDrv0CurRegData = 0;\r
+    GU16 usDrv0CurRegAddr = 0;    \r
+    GU16 usDrv1CurRegData = 0;\r
+    GU16 usDrv1CurRegAddr = 0;\r
+    GU16 uchTIAData = 0;\r
+\r
+    // record TIA\r
+    for (GU8 uchSlotIndex = 0; uchSlotIndex < 8; uchSlotIndex++)\r
+    {\r
+        GH3X2X_WAIT_CHIP_WAKEUP();\r
+        uchTIAData = GH3X2X_ReadReg(GH3X2X_SLOT0_CTRL_4_REG_ADDR + (uchSlotIndex * GH3X2X_SLOT_CTRL_OFFSET));\r
+        GH3X2X_WAIT_CHIP_DSLP();\r
+\r
+        for (GU8 nAdcCnt = 0; nAdcCnt < 4; nAdcCnt++)\r
+        {\r
+            GU8 uchTempTIAData = (GU8)(((uchTIAData) >> (GH3X2X_SLOT_TIA_GAIN_BITS_SIZE * nAdcCnt)) & GH3X2X_SLOT_TIA_GAIN_BITS_MARK);\r
+            g_pstGh3x2xAgcInfo->uchTiaGainAfterSoftAgc[uchSlotIndex*4 + nAdcCnt] = uchTempTIAData;\r
+        }    \r
+    }\r
+\r
+    //Record Drv        \r
+    GH3X2X_WAIT_CHIP_WAKEUP();\r
+    usDrv0CurRegAddr = GH3X2X_SLOT0_CTRL_10_REG_ADDR;\r
+    usDrv1CurRegAddr = GH3X2X_SLOT0_CTRL_11_REG_ADDR;\r
+    for (GU8 uchSlotIndexCnt = 0; uchSlotIndexCnt < GH3X2X_MAX_SLOT_NUM; uchSlotIndexCnt++)\r
+    {\r
+        usDrv0CurRegData = (GH3X2X_ReadReg(usDrv0CurRegAddr + (uchSlotIndexCnt * GH3X2X_SLOT_CTRL_OFFSET)) & GH3X2X_DRV_CURRENT_BIT_MASK);\r
+        usDrv1CurRegData = (GH3X2X_ReadReg(usDrv1CurRegAddr + (uchSlotIndexCnt * GH3X2X_SLOT_CTRL_OFFSET)) & GH3X2X_DRV_CURRENT_BIT_MASK);\r
+        g_pstGh3x2xAgcInfo->uchDrvCurrentAfterSoftAgc[uchSlotIndexCnt] =  (GU16)(usDrv0CurRegData << GH3X2X_DRV0_CURRENT_LEFT_SHIFT_BIT_NUM);\r
+        g_pstGh3x2xAgcInfo->uchDrvCurrentAfterSoftAgc[uchSlotIndexCnt] |= (GU16)(usDrv1CurRegData << GH3X2X_DRV1_CURRENT_LEFT_SHIFT_BIT_NUM);\r
+    }\r
+    GH3X2X_WAIT_CHIP_DSLP();\r
+}\r
+\r
+/**\r
+ * @fn     GS8 GH3X2X_StartSampling(void)\r
+ *\r
+ * @brief  Start gh3x2x sampling\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  errcode\r
+ * @retval  #GH3X2X_RET_OK                  return successfully\r
+ * @retval  #GH3X2X_RET_NO_INITED_ERROR     gh3x2x has not inited\r
+ * @retval  #GH3X2X_RET_GENERIC_ERROR       gh3x2x has started, need restart should call GH3X2X_StopSampling then start\r
+ */\r
+GS8 GH3X2X_StartSampling(void)\r
+{\r
+    GS8 chRet = GH3X2X_RET_GENERIC_ERROR;\r
+    GH3X2X_DEBUG_LOG_PARAM("%s\r\n", __FUNCTION__);\r
+    if (g_uchGh3x2xStatus != GH3X2X_STATUS_STARTED)\r
+    {\r
+        g_uchFifoPackageID = 0xFF;\r
+        if (GH3X2X_IS_CHIP_INIED() && (g_uchGh3x2xStatus == GH3X2X_STATUS_INITED))\r
+        {\r
+            GU16 usRegVal = 0;\r
+            GH3X2X_WAIT_CHIP_WAKEUP();\r
+            g_usCurrentFiFoWaterLine = GH3X2X_ReadReg(GH3X2X_FIFO_WATERLINE_REG_ADDR);  //record water line\r
+            usRegVal = GH3X2X_ReadReg(GH3X2X_CARDIFF_CTRL_REG_ADDR);\r
+            GH3X2X_WriteReg(GH3X2X_CARDIFF_CTRL_REG_ADDR, GH3X2X_SET_BIT(usRegVal, GH3X2X_CARDIFF_CTRL_START_BIT));\r
+            #if GH3X2X_ALGORITHM_ECG_SUPPORT && __FUNC_TYPE_ECG_ENABLE__\r
+            GH3X2X_LeadDetEnControl(ECG_SAMPLE_EVENT_INFO_SAMPLE_START);\r
+            #endif\r
+\r
+            GH3X2X_RecordAgcInfo(); //record agc info\r
+            #if __SUPPORT_SOFT_AGC_CONFIG__\r
+            GH3X2X_LedAgcInit(g_pstGh3x2xAgcInfo);\r
+            #endif\r
+        #if GH3X2X_DUMP_MODE_EN\r
+            GH3X2X_DumpInit();\r
+        #endif\r
+            g_uchGh3x2xStatus = GH3X2X_STATUS_STARTED;\r
+            HOOK_FUNC_CALL(g_pGh3x2xStartHookFunc, () );  /* call hook */\r
+            GH3X2X_WAIT_CHIP_DSLP(); //  GH3X2X_SEND_DSLEEP_CMD(); // enter sleep mode in application code\r
+            GH3X2X_StartSamplingSlaveChip();\r
+            chRet = GH3X2X_RET_OK;\r
+        }\r
+        else\r
+        {\r
+            g_uchGh3x2xStatus = GH3X2X_STATUS_NO_INIT;\r
+            chRet = GH3X2X_RET_NO_INITED_ERROR;\r
+            GH3X2X_DEBUG_LOG_PARAM("gh start error that don't inited!\r\n");\r
+        }\r
+    }\r
+    else\r
+    {\r
+        GH3X2X_DEBUG_LOG_PARAM("gh started,restart call stop->start!\r\n");\r
+    }\r
+\r
+    return chRet;\r
+}\r
+\r
+#if !__GH3X2X_CASCADE_EN__\r
+void GH3X2X_StartSamplingSlaveChip(void){}\r
+void GH3X2X_StopSamplingSlaveChip(void){}\r
+#else\r
+void GH3X2X_StartSamplingSlaveChip(void)\r
+{\r
+    GU16 usRegVal = 0;\r
+    if(GH3X2X_CascadeGetEcgEnFlag())\r
+    {\r
+        GH3X2X_CascadeOperationSlaverChip();\r
+        GH3X2X_WAIT_CHIP_WAKEUP();\r
+        if (g_usCurrentFiFoWaterLine != GH3X2X_ReadReg(GH3X2X_FIFO_WATERLINE_REG_ADDR))  //record water line\r
+        {\r
+            GH3X2X_WriteReg(GH3X2X_FIFO_WATERLINE_REG_ADDR, g_usCurrentFiFoWaterLine);\r
+            GH3X2X_DEBUG_LOG_PARAM("gh chip2 and chip1 fifowater linie not equal!\r\n");\r
+        }         \r
+        usRegVal = GH3X2X_ReadReg(GH3X2X_CARDIFF_CTRL_REG_ADDR);\r
+        GH3X2X_WriteReg(GH3X2X_CARDIFF_CTRL_REG_ADDR, GH3X2X_SET_BIT(usRegVal, GH3X2X_CARDIFF_CTRL_START_BIT));\r
+//                #if GH3X2X_ALGORITHM_ECG_SUPPORT\r
+//                GH3X2X_LeadDetEnControl(ECG_SAMPLE_EVENT_INFO_SAMPLE_START);\r
+//                #endif\r
+        GH3X2X_CascadeOperationMasterChip();\r
+        GH3X2X_DEBUG_LOG_PARAM("gh chip2 ecg start!\r\n");\r
+    }\r
+}\r
+\r
+void GH3X2X_StopSamplingSlaveChip(void)\r
+{\r
+    GU16 usRegVal = 0;\r
+    if (GH3X2X_CascadeGetEcgEnFlag())\r
+    {\r
+        GH3X2X_CascadeOperationSlaverChip();\r
+        GH3X2X_WAIT_CHIP_WAKEUP();\r
+        //g_uchGh3x2xStatus = GH3X2X_STATUS_INITED;\r
+        usRegVal = GH3X2X_ReadReg(GH3X2X_CARDIFF_CTRL_REG_ADDR);\r
+        GH3X2X_WriteReg(GH3X2X_CARDIFF_CTRL_REG_ADDR, GH3X2X_CLEAR_BIT(usRegVal, GH3X2X_CARDIFF_CTRL_START_BIT));\r
+//            #if GH3X2X_ALGORITHM_ECG_SUPPORT\r
+//            GH3X2X_LeadDetEnControl(ECG_SAMPLE_EVENT_INFO_SAMPLE_STOP);\r
+//            #endif\r
+        //HOOK_FUNC_CALL(g_pGh3x2xStopHookFunc, () );  /* call hook */\r
+        GH3X2X_WAIT_CHIP_DSLP();            \r
+        GH3X2X_CascadeOperationMasterChip();\r
+    }\r
+}\r
+#endif\r
+/**\r
+ * @fn     GS8 GH3X2X_StopSampling(void)\r
+ *\r
+ * @brief  Stop gh3x2x sampling\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ * \r
+ * @return  errcode\r
+ * @retval  #GH3X2X_RET_OK                  return successfully\r
+ * @retval  #GH3X2X_RET_NO_INITED_ERROR     gh3x2x has not inited\r
+ */\r
+GS8 GH3X2X_StopSampling(void)\r
+{\r
+    GS8 chRet = GH3X2X_RET_NO_INITED_ERROR;\r
+\r
+    GH3X2X_DEBUG_LOG_PARAM("%s\r\n", __FUNCTION__);\r
+    if ((g_uchGh3x2xStatus == GH3X2X_STATUS_INITED) || (g_uchGh3x2xStatus == GH3X2X_STATUS_STARTED))\r
+    {\r
+        GU16 usRegVal = 0;\r
+        GH3X2X_WAIT_CHIP_WAKEUP();\r
+        g_uchGh3x2xStatus = GH3X2X_STATUS_INITED;\r
+        usRegVal = GH3X2X_ReadReg(GH3X2X_CARDIFF_CTRL_REG_ADDR);\r
+        GH3X2X_WriteReg(GH3X2X_CARDIFF_CTRL_REG_ADDR, GH3X2X_CLEAR_BIT(usRegVal, GH3X2X_CARDIFF_CTRL_START_BIT));\r
+        #if GH3X2X_ALGORITHM_ECG_SUPPORT && __FUNC_TYPE_ECG_ENABLE__\r
+        GH3X2X_LeadDetEnControl(ECG_SAMPLE_EVENT_INFO_SAMPLE_STOP);\r
+        #endif\r
+        HOOK_FUNC_CALL(g_pGh3x2xStopHookFunc, () );  /* call hook */\r
+        GH3X2X_WAIT_CHIP_DSLP();\r
+        GH3X2X_StopSamplingSlaveChip();\r
+        chRet = GH3X2X_RET_OK;\r
+    }\r
+    else\r
+    {\r
+        GH3X2X_DEBUG_LOG_PARAM("gh stop error that don't inited!\r\n");\r
+    }\r
+\r
+    return chRet;\r
+}\r
+\r
+\r
+\r
+/**\r
+ * @fn     GU16 GH3X2X_GetIrqStatus(void)\r
+ *\r
+ * @brief  Get irq status reg val\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  irq status val, ref irq status mask\r
+ */\r
+GU16 GH3X2X_GetIrqStatus(void)\r
+{\r
+    GU16 usIrqRegVal = 0;\r
+    GH3X2X_DEBUG_LOG_PARAM("%s\r\n", __FUNCTION__);\r
+    GH3X2X_WAIT_CHIP_WAKEUP();\r
+    usIrqRegVal = GH3X2X_ReadReg(GH3X2X_INT_STR_REG_ADDR);\r
+    GH3X2X_WriteReg(GH3X2X_INT_STR_REG_ADDR, usIrqRegVal);\r
+    GH3X2X_WAIT_CHIP_DSLP();\r
+    return (GU16)(usIrqRegVal & (GU16)GH3X2X_INT_STR_MSK_ALL_BIT);\r
+}\r
+\r
+/**\r
+ * @fn     void GH3X2X_UnpackRawdataPackage(STGh3x2xSlotRawdata *pstSlotRawdataArr,\r
+ *                                    GU8 *puchReadRawdataBuffer, GU16 usReadRawdataLen)\r
+ *\r
+ * @brief  Unpack to 8 slot rawdata from read fifo data buffer\r
+ *\r
+ * @attention   This function should use in get rawdata hook;\r
+ *              param pstSlotRawdataArr size must equal 8, define like stSlotRawdataArr[8]. If not define 8,\r
+ *              that mcu will occur array out of bounds error, careful!!!\r
+ *\r
+ * @param[out]  pstSlotRawdataArr       pointer to 8 slot rawdata struct output\r
+ * @param[in]   puchReadRawdataBuffer   pointer to read fifo buffer\r
+ * @param[in]   usReadRawdataLen        read fifo rawdata data len (bytes)\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_UnpackRawdataPackage(STGh3x2xSlotRawdata *pstSlotRawdataArr,\r
+                                    GU8 *puchReadRawdataBuffer, GU16 usReadRawdataLen)\r
+{\r
+    GU16 usIndex = 0;\r
+    GU8  uchSlotNum = 0;\r
+    GU8  uchAdcNum = 0;\r
+    GU8  uchLastSlotNum = 0;\r
+    GU8  uchLastAdcNum = 0;\r
+    GU16 usRawdataIndex = 0;\r
+    GH3X2X_DEBUG_LOG_PARAM("%s\r\n", __FUNCTION__);\r
+    for (usIndex = 0; usIndex < GH3X2X_SLOT_NUM_MAX; usIndex ++)\r
+    {\r
+        pstSlotRawdataArr[usIndex].usRawdataCnt = 0; // clear cnt\r
+    }\r
+    for (usIndex = 0; usIndex < usReadRawdataLen; usIndex += GH3X2X_FIFO_RAWDATA_SIZE)\r
+    {\r
+        uchSlotNum = GH3X2X_BYTE_RAWDATA_GET_SLOT_NUM(puchReadRawdataBuffer[usIndex]);\r
+        uchAdcNum = GH3X2X_BYTE_RAWDATA_GET_ADC_NUM(puchReadRawdataBuffer[usIndex]);\r
+        if (usIndex == 0) // fixed started\r
+        {\r
+            uchLastSlotNum = uchSlotNum;\r
+            uchLastAdcNum = uchAdcNum;\r
+        }\r
+        if ((uchLastSlotNum != uchSlotNum)\r
+            || ((uchLastSlotNum == uchSlotNum) && (uchAdcNum <= uchLastAdcNum) && (usIndex != 0)))\r
+        {\r
+            pstSlotRawdataArr[uchLastSlotNum].usRawdataCnt++;\r
+        }\r
+        usRawdataIndex = pstSlotRawdataArr[uchSlotNum].usRawdataCnt;\r
+        if (pstSlotRawdataArr[uchSlotNum].punRawdata != GH3X2X_PTR_NULL)\r
+        {\r
+            pstSlotRawdataArr[uchSlotNum].punRawdata[usRawdataIndex][uchAdcNum] = \\r
+                                                        GH3X2X_RAWDATA_CLEAR_SLOT_ADC_NUM(\\r
+                                                            GH3X2X_MAKEUP_DWORD(puchReadRawdataBuffer[usIndex],\r
+                                                                                puchReadRawdataBuffer[usIndex + 1],\r
+                                                                                puchReadRawdataBuffer[usIndex + 2],\r
+                                                                                puchReadRawdataBuffer[usIndex + 3]));\r
+        }\r
+        uchLastSlotNum = uchSlotNum;\r
+        uchLastAdcNum = uchAdcNum;\r
+        if ((usIndex + GH3X2X_FIFO_RAWDATA_SIZE) == usReadRawdataLen)\r
+        {\r
+            pstSlotRawdataArr[uchSlotNum].usRawdataCnt++;\r
+        }\r
+    } // for (usIndex = 0; usIndex < usReadRawdataLen; usIndex += 4)\r
+}\r
+\r
+/**\r
+ * @fn     GS16 GH3X2X_GetRawdata(STGh3x2xRawdata *pstGh3x2xRawdata, GU16* usFifoLength)\r
+ *\r
+ * @brief  Get rawdata from fifo\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  pstGh3x2xRawdata     pointer to rawdata struct output\r
+ * @param[out]  usFifoLength         pointer to read fifo bytes\r
+ *\r
+ * @return  error code\r
+ * @retval  #GH3X2X_RET_PARAMETER_ERROR         return param error\r
+ * @retval  #GH3X2X_RET_READ_FIFO_CONTINUE      return fifo is not empty\r
+ */\r
+GS16 GH3X2X_GetRawdata(STGh3x2xRawdata *pstGh3x2xRawdata, GU16* usFifoLength)\r
+{\r
+    GU16 usIndex = 0;\r
+    GS16 sRet = GH3X2X_RET_PARAMETER_ERROR;\r
+\r
+    GH3X2X_DEBUG_LOG_PARAM("%s\r\n", __FUNCTION__);\r
+    if (pstGh3x2xRawdata != GH3X2X_PTR_NULL)\r
+    {\r
+        if (pstGh3x2xRawdata->puchReadBuffer != GH3X2X_PTR_NULL)\r
+        {\r
+            GH3X2X_WAIT_CHIP_WAKEUP();\r
+            *usFifoLength = GH3X2X_FIFO_CNT_CALC(GH3X2X_ReadReg(GH3X2X_INT_FIFO_UR_REG_ADDR));\r
+\r
+            if (*usFifoLength > g_usMaxNumReadFromFifo)\r
+            {\r
+                *usFifoLength = g_usMaxNumReadFromFifo;\r
+                sRet = GH3X2X_RET_READ_FIFO_CONTINUE;\r
+            }\r
+\r
+            if ((*usFifoLength > 0) && (*usFifoLength <= GH3X2X_FIFO_DATA_BYTES_MAX_LEN))\r
+            {\r
+                GH3X2X_ReadFifo(pstGh3x2xRawdata->puchReadBuffer, *usFifoLength);\r
+            }\r
+            else\r
+            {\r
+                if (*usFifoLength > GH3X2X_FIFO_DATA_BYTES_MAX_LEN)\r
+                {\r
+                    *usFifoLength = 0;\r
+                    GH3X2X_DEBUG_LOG_PARAM("get rawdata fifo len greater than max, pelease check i2c/spi!\r\n");\r
+                }\r
+                else\r
+                {\r
+                    GH3X2X_DEBUG_LOG_PARAM("get rawdata fifo equl 0!\r\n");\r
+                }\r
+            }\r
+            \r
+            /* call hook */\r
+            HOOK_FUNC_CALL(g_pGh3x2xGetRawdataHookFunc, (pstGh3x2xRawdata->puchReadBuffer, *usFifoLength) );\r
+            GH3X2X_WAIT_CHIP_DSLP();\r
+            GH3X2X_UnpackRawdataPackage(pstGh3x2xRawdata->stSlotRawdataArr,\r
+                                        pstGh3x2xRawdata->puchReadBuffer, *usFifoLength);\r
+        }// if (pstGh3x2xRawdata->puchReadBuffer != GH3X2X_PTR_NULL)\r
+        else // fixed clear cnt if readbuffer ptr is null\r
+        {\r
+            GH3X2X_DEBUG_LOG_PARAM("get rawdata error that readbuffer is null!\r\n");\r
+            for (usIndex = 0; usIndex < GH3X2X_SLOT_NUM_MAX; usIndex ++)\r
+            {\r
+                pstGh3x2xRawdata->stSlotRawdataArr[usIndex].usRawdataCnt = 0; // clear cnt\r
+            }\r
+        }\r
+    }// if (pstGh3x2xRawdata != GH3X2X_PTR_NULL)\r
+    \r
+    return sRet;\r
+}\r
+\r
+#if 0\r
+void GH3X2X_SetFifoPackageMode(GU8 uchMode, GU8 *puchFifoBuffer)\r
+{\r
+    g_uchFifoPackageMode = uchMode;\r
+    gpuchSendFifoPackage = puchFifoBuffer;\r
+}\r
+#endif\r
+\r
+\r
+#if (0 == __FIFO_PACKAGE_SEND_ENABLE__)\r
+GU8 GH3X2X_GetFifoPackageMode(void)\r
+{\r
+    return 0;\r
+}\r
+void GH3X2X_SendRawdataFifoPackage(GU8 *puchGh3x2xReadFifoData, GU16 usFifoReadByteNum){}\r
+#else\r
+GU8 GH3X2X_GetFifoPackageMode(void)\r
+\r
+{\r
+    return g_uchFifoPackageMode;\r
+}\r
+\r
+void GH3X2X_SendRawdataFifoPackage(GU8 *puchGh3x2xReadFifoData, GU16 usFifoReadByteNum)\r
+{\r
+    if (usFifoReadByteNum == 0)\r
+    {\r
+        return;\r
+    }\r
+    g_uchFifoPackageID ++;\r
+    GU8 unRawdataFifoBuffer[220] = {0};\r
+    GU8 unSendRawdataFifoBuffer[235] = {0};\r
+    GU32 uRawdataBufCnt = 0;\r
+    GU8 uchIdChangeFlag = 0;\r
+    GU16 usPackageNum = usFifoReadByteNum / 200;\r
+    GU16 usLastRawdataFifoBufNum = usFifoReadByteNum % 200;\r
+    if (usLastRawdataFifoBufNum == 0)\r
+    {\r
+        usLastRawdataFifoBufNum = 200;\r
+        usPackageNum--;\r
+    }\r
+    for (uRawdataBufCnt = 0 ; uRawdataBufCnt < usPackageNum ; uRawdataBufCnt ++)\r
+    {\r
+        unRawdataFifoBuffer[0] = g_uchFifoPackageID;\r
+        unRawdataFifoBuffer[1] = 200;\r
+        unRawdataFifoBuffer[2] = uchIdChangeFlag;\r
+        uchIdChangeFlag ++;\r
+        GH3X2X_Memcpy(&unRawdataFifoBuffer[5], &puchGh3x2xReadFifoData[uRawdataBufCnt * 200], (GU32)200);\r
+        GU16 usRespondLen = GH3X2X_UprotocolPacketFormat(GH3X2X_UPROTOCOL_CMD_RAWDATA_FIFO_UPDATE, unSendRawdataFifoBuffer,\r
+                                                unRawdataFifoBuffer, 200 + 5);\r
+        Gh3x2xDemoSendProtocolData(unSendRawdataFifoBuffer, usRespondLen);\r
+    }\r
+    unRawdataFifoBuffer[0] = g_uchFifoPackageID;\r
+    unRawdataFifoBuffer[1] = (GU8)(usLastRawdataFifoBufNum);\r
+    unRawdataFifoBuffer[2] = 0x10 | uchIdChangeFlag;\r
+    GH3X2X_Memcpy(&unRawdataFifoBuffer[5], &puchGh3x2xReadFifoData[usPackageNum * 200], (GU32)usLastRawdataFifoBufNum);\r
+    GU16 usRespondLen = GH3X2X_UprotocolPacketFormat(GH3X2X_UPROTOCOL_CMD_RAWDATA_FIFO_UPDATE, unSendRawdataFifoBuffer,\r
+                                            unRawdataFifoBuffer, usLastRawdataFifoBufNum + 5);\r
+    Gh3x2xDemoSendProtocolData(unSendRawdataFifoBuffer, usRespondLen);\r
+}\r
+#endif\r
+\r
+#if 0\r
+void GH3X2X_PackRawdataFifoPackage(GU8 *puchGh3x2xReadFifoData, GU16 usFifoReadByteNum)\r
+{\r
+    if (usFifoReadByteNum == 0)\r
+    {\r
+        return;\r
+    }\r
+\r
+    if (usFifoReadByteNum + g_unSendFifoPackageCnt >= GH3X2X_RAWDATA_BUFFER_SIZE)\r
+    {\r
+        GU32 usFifoReadExternByteNum = GH3X2X_RAWDATA_BUFFER_SIZE - g_unSendFifoPackageCnt;\r
+        GH3X2X_Memcpy(&gpuchSendFifoPackage[g_unSendFifoPackageCnt], puchGh3x2xReadFifoData, usFifoReadExternByteNum);\r
+        g_unSendFifoPackageCnt += usFifoReadExternByteNum;\r
+\r
+        GH3X2X_SendRawdataFifoPackage(gpuchSendFifoPackage, g_unSendFifoPackageCnt);\r
+\r
+        g_unSendFifoPackageCnt = 0;\r
+        \r
+        GH3X2X_Memcpy(&gpuchSendFifoPackage[g_unSendFifoPackageCnt],\\r
+            &puchGh3x2xReadFifoData[usFifoReadByteNum - (GH3X2X_RAWDATA_BUFFER_SIZE - g_unSendFifoPackageCnt)],\\r
+            usFifoReadByteNum + g_unSendFifoPackageCnt - GH3X2X_RAWDATA_BUFFER_SIZE);\r
+        g_unSendFifoPackageCnt += usFifoReadByteNum + g_unSendFifoPackageCnt - GH3X2X_RAWDATA_BUFFER_SIZE;\r
+    }\r
+    else\r
+    {\r
+        GH3X2X_Memcpy(&gpuchSendFifoPackage[g_unSendFifoPackageCnt], puchGh3x2xReadFifoData, usFifoReadByteNum);\r
+        g_unSendFifoPackageCnt += usFifoReadByteNum;\r
+    }\r
+}\r
+#endif\r
+\r
+\r
+/**\r
+ * @fn     GU16 GH3X2X_FindGu16MinVal(GU16 *pusBuffer, GU8 uchLen)\r
+ *\r
+ * @brief  Find min val\r
+ *\r
+ * @attention   len must > 0\r
+ * \r
+ * @param[in]   pusBuffer        pointer to buffer\r
+ * @param[in]   uchLen           buffer length\r
+ * @param[out]  None\r
+ *\r
+ * @return  min val, if len = 0, return 0\r
+ */\r
+GU16 GH3X2X_FindGu16MinVal(GU16 *pusBuffer, GU8 uchLen)\r
+{\r
+    GU16 usMinVal = pusBuffer[0];\r
+    GU8 uchIndex = 1;\r
+\r
+    for (uchIndex = 1; uchIndex < uchLen; uchIndex++)\r
+    {\r
+        if (pusBuffer[uchIndex] < usMinVal)\r
+        {\r
+            usMinVal = pusBuffer[uchIndex];\r
+        }\r
+    }\r
+    return usMinVal; \r
+}\r
+\r
+/**\r
+ * @fn     GU16 GH3X2X_FindGu16MaxVal(GU16 *pusBuffer, GU8 uchLen)\r
+ *\r
+ * @brief  Find max val\r
+ *\r
+ * @attention   len must > 0\r
+ * \r
+ * @param[in]   pusBuffer        pointer to buffer\r
+ * @param[in]   uchLen           buffer length\r
+ * @param[out]  None\r
+ *\r
+ * @return  max val, if len = 0, return 0\r
+ */\r
+GU16 GH3X2X_FindGu16MaxVal(GU16 *pusBuffer, GU8 uchLen)\r
+{\r
+    GU16 usMaxVal = pusBuffer[0];\r
+    GU8 uchIndex = 1;\r
+\r
+    for (uchIndex = 1; uchIndex < uchLen; uchIndex++)\r
+    {\r
+        if (pusBuffer[uchIndex] > usMaxVal)\r
+        {\r
+            usMaxVal = pusBuffer[uchIndex];\r
+        }\r
+    }\r
+    return usMaxVal; \r
+}\r
+\r
+/**\r
+ * @fn     void GH3X2X_FindGu16MaxMinVal(GU16 *pusMaxVal, GU16 *pusMinVal, GU16 *pusBuffer, GU8 uchLen)\r
+ *\r
+ * @brief  Find min val & max val\r
+ *\r
+ * @attention   len must > 0, ptr not null\r
+ * \r
+ * @param[in]   pusBuffer        pointer to buffer\r
+ * @param[in]   uchLen           buffer length\r
+ * @param[out]  pusMaxVal        pointer to max val\r
+ * @param[out]  pusMinVal        pointer to min val\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_FindGu16MaxMinVal(GU16 *pusMaxVal, GU16 *pusMinVal, GU16 *pusBuffer, GU8 uchLen)\r
+{\r
+    GU16 usMaxVal = pusBuffer[0];\r
+    GU16 usMinVal = pusBuffer[0];\r
+    GU8 uchIndex = 1;\r
+\r
+    for (uchIndex = 1; uchIndex < uchLen; uchIndex++)\r
+    {\r
+        if (pusBuffer[uchIndex] > usMaxVal)\r
+        {\r
+            usMaxVal = pusBuffer[uchIndex];\r
+        }\r
+        if (pusBuffer[uchIndex] < usMinVal)\r
+        {\r
+            usMinVal = pusBuffer[uchIndex];\r
+        }\r
+    }\r
+    SET_VAL_VIA_PTR(pusMaxVal, usMaxVal);\r
+    SET_VAL_VIA_PTR(pusMinVal, usMinVal);\r
+}\r
+\r
+/**\r
+ * @fn     GS8 GH3X2X_UnpackRawdataWithChannelMap(STGh3x2xChannelRawdata *pstGh3x2xChannelRawdata, \r
+ *               GU8 *puchReadRawdataBuffer, GU16 usReadRawdataLen, GU8 uchChannelMapCnt, GU8 *puchChannelMapArr)\r
+ *\r
+ * @brief  Unpack to channel rawdata from read fifo data buffer;\r
+ *         if last channel rawdata incomplete, should change fifo watermark\r
+ *\r
+ * @attention   This function should use in get rawdata hook\r
+ * \r
+ * @param[in]   puchReadRawdataBuffer       pointer to read data buffer\r
+ * @param[in]   usReadRawdataLen            read data length\r
+ * @param[in]   uchChannelMapCnt            channel map array cnt, max:32\r
+ * @param[in]   puchChannelMapArr           pointer to channel map array\r
+ * @param[out]  pstGh3x2xChannelRawdata     pointer to channel rawdata struct\r
+ *\r
+ * @return  error code\r
+ * @retval  #GH3X2X_RET_OK                      return successfully\r
+ * @retval  #GH3X2X_RET_PARAMETER_ERROR         return param error\r
+ */\r
+GS8 GH3X2X_UnpackRawdataWithChannelMap(STGh3x2xChannelRawdata *pstGh3x2xChannelRawdata, \r
+                GU8 *puchReadRawdataBuffer, GU16 usReadRawdataLen, GU8 uchChannelMapCnt, GU8 *puchChannelMapArr)\r
+{\r
+    GU8  uchChCntIndex = 0;\r
+    GU16 usRawdataIndex = 0;\r
+    GU16 usRawdataCnt = 0;\r
+    GU16 usRawdataCntMin = 0;\r
+    GU16 usRawdataCntMax = 0;\r
+    GU16 usRawdataIndexArr[GH3X2X_CHANNEL_MAP_MAX_CH] = {0}; // use for rawdata cnt & rawdata bytes index\r
+    GU16 usRawdataByteIndexTmp = 0;\r
+    GU16 usRawdataBaseIndex = 0;\r
+\r
+    GH3X2X_DEBUG_LOG_PARAM("%s\r\n", __FUNCTION__);\r
+\r
+    /* check pram */\r
+    if ((pstGh3x2xChannelRawdata->punIncompleteChRawdataArr == GH3X2X_PTR_NULL)\r
+        || (pstGh3x2xChannelRawdata->punChRawdataArr == GH3X2X_PTR_NULL) || (puchReadRawdataBuffer == GH3X2X_PTR_NULL)\r
+        || (pstGh3x2xChannelRawdata == GH3X2X_PTR_NULL) || (puchChannelMapArr == GH3X2X_PTR_NULL))\r
+    {\r
+        GH3X2X_DEBUG_LOG_PARAM("pointer param set null error!\r\n");\r
+        return GH3X2X_RET_PARAMETER_ERROR;\r
+    }\r
+    for (uchChCntIndex = 0; uchChCntIndex < uchChannelMapCnt; uchChCntIndex++)\r
+    {\r
+        if (GH3X2X_CLEAR_BIT(puchChannelMapArr[uchChCntIndex], GH3X2X_SLOT_ADC_NUM_BITS) != 0)\r
+        {\r
+            GH3X2X_DEBUG_LOG_PARAM("channel map error! set @ref GH3X2X_CHANNEL_MAP!\r\n");\r
+            return GH3X2X_RET_PARAMETER_ERROR;\r
+        }\r
+    }\r
+    if (uchChannelMapCnt > GH3X2X_CHANNEL_MAP_MAX_CH)\r
+    {\r
+        GH3X2X_DEBUG_LOG_PARAM("channel cnt greater than max!\r\n");\r
+        return GH3X2X_RET_PARAMETER_ERROR;\r
+    }\r
+\r
+    /* calc rawdata len */\r
+    for (uchChCntIndex = 0; uchChCntIndex < uchChannelMapCnt; uchChCntIndex++)\r
+    {\r
+        if (GH3X2X_CHECK_LEFT_BIT_SET(pstGh3x2xChannelRawdata->unIncompleteChMark, uchChCntIndex))\r
+        {\r
+            usRawdataIndexArr[uchChCntIndex]++;\r
+        }\r
+        for (usRawdataIndex = 0; usRawdataIndex < usReadRawdataLen; usRawdataIndex += GH3X2X_FIFO_RAWDATA_SIZE)\r
+        {\r
+            if (puchChannelMapArr[uchChCntIndex] == GH3X2X_CHANNEL_MAP_GET(puchReadRawdataBuffer[usRawdataIndex]))\r
+            {\r
+                usRawdataIndexArr[uchChCntIndex]++; // if rawdata channel map equal config(included slot&adc)\r
+            }\r
+        }\r
+    }\r
+    GH3X2X_FindGu16MaxMinVal(&usRawdataCntMax, &usRawdataCntMin, usRawdataIndexArr, uchChannelMapCnt); // calc min&max\r
+    if (usRawdataCntMax == usRawdataCntMin)\r
+    {\r
+        usRawdataCnt = usRawdataCntMax; // whatever last data complete or incomplete\r
+    }\r
+    else\r
+    {\r
+        if ((usRawdataCntMax - usRawdataCntMin) > 1)\r
+        {\r
+            GH3X2X_DEBUG_LOG_PARAM("rawdata doesn't correspond to channel map error!\r\n");\r
+            usRawdataCnt = 0;\r
+            pstGh3x2xChannelRawdata->unIncompleteChMark = 0;\r
+            GH3X2X_Memset(pstGh3x2xChannelRawdata->punIncompleteChRawdataArr, 0, uchChannelMapCnt * sizeof(GU32));\r
+        }\r
+        else // cnt tolerable deviation is 1\r
+        {\r
+            usRawdataCnt = GH3X2X_FindGu16MinVal(usRawdataIndexArr, uchChannelMapCnt);\r
+        }\r
+    } // end of if (usRawdataCntMax == usRawdataCntMin)\r
+    GH3X2X_Memset(usRawdataIndexArr, 0, uchChannelMapCnt * sizeof(GU16)); // clear index array, before next use\r
+\r
+    if (usRawdataCnt != 0)\r
+    {\r
+        for (usRawdataIndex = 0; usRawdataIndex < usRawdataCnt; usRawdataIndex++)\r
+        {\r
+            usRawdataBaseIndex = (GU16)(usRawdataIndex * uchChannelMapCnt);\r
+            for (uchChCntIndex = 0; uchChCntIndex < uchChannelMapCnt; uchChCntIndex++) // search each channel\r
+            {\r
+                if (GH3X2X_CHECK_LEFT_BIT_SET(pstGh3x2xChannelRawdata->unIncompleteChMark, uchChCntIndex))\r
+                {\r
+                    pstGh3x2xChannelRawdata->punChRawdataArr[usRawdataBaseIndex + uchChCntIndex] = \\r
+                                                    pstGh3x2xChannelRawdata->punIncompleteChRawdataArr[uchChCntIndex];\r
+                    pstGh3x2xChannelRawdata->punIncompleteChRawdataArr[uchChCntIndex] = 0;\r
+                    GH3X2X_VAL_CLEAR_LEFT_BIT(pstGh3x2xChannelRawdata->unIncompleteChMark, uchChCntIndex);\r
+                }\r
+                else\r
+                {\r
+                    usRawdataByteIndexTmp = usRawdataIndexArr[uchChCntIndex];\r
+                    while (usRawdataByteIndexTmp < usReadRawdataLen) // search each\r
+                    {\r
+                        if (GH3X2X_CHANNEL_MAP_GET(puchReadRawdataBuffer[usRawdataByteIndexTmp]) == \\r
+                                                                    puchChannelMapArr[uchChCntIndex]) // if map equal\r
+                        {\r
+                            pstGh3x2xChannelRawdata->punChRawdataArr[usRawdataBaseIndex + uchChCntIndex] = \\r
+                                                GH3X2X_RAWDATA_CLEAR_SLOT_ADC_NUM(\r
+                                                    GH3X2X_MAKEUP_DWORD(puchReadRawdataBuffer[usRawdataByteIndexTmp],\r
+                                                                    puchReadRawdataBuffer[usRawdataByteIndexTmp + 1],\r
+                                                                    puchReadRawdataBuffer[usRawdataByteIndexTmp + 2],\r
+                                                                    puchReadRawdataBuffer[usRawdataByteIndexTmp + 3]));\r
+                            usRawdataByteIndexTmp += GH3X2X_FIFO_RAWDATA_SIZE;\r
+                            break;\r
+                        }\r
+                        usRawdataByteIndexTmp += GH3X2X_FIFO_RAWDATA_SIZE;\r
+                    }\r
+                    usRawdataIndexArr[uchChCntIndex] = usRawdataByteIndexTmp; // write back byte index\r
+                }\r
+            } // end of for (uchChCntIndex = 0; uchChCntIndex < uchChannelMapCnt; uchChCntIndex++)\r
+        } // end of for (usRawdataIndex = 0; usRawdataIndex < usRawdataCnt; usRawdataIndex++)\r
+        if (usRawdataCntMax != usRawdataCnt)\r
+        {\r
+            for (uchChCntIndex = 0; uchChCntIndex < uchChannelMapCnt; uchChCntIndex++) // search each channel\r
+            {\r
+                usRawdataByteIndexTmp = usRawdataIndexArr[uchChCntIndex];\r
+                while (usRawdataByteIndexTmp < usReadRawdataLen) // search each\r
+                {\r
+                    if (GH3X2X_CHANNEL_MAP_GET(puchReadRawdataBuffer[usRawdataByteIndexTmp]) == \\r
+                                                                puchChannelMapArr[uchChCntIndex]) // if map equal\r
+                    {\r
+                        pstGh3x2xChannelRawdata->punIncompleteChRawdataArr[uchChCntIndex] = \\r
+                                            GH3X2X_RAWDATA_CLEAR_SLOT_ADC_NUM(\r
+                                                GH3X2X_MAKEUP_DWORD(puchReadRawdataBuffer[usRawdataByteIndexTmp],\r
+                                                                puchReadRawdataBuffer[usRawdataByteIndexTmp + 1],\r
+                                                                puchReadRawdataBuffer[usRawdataByteIndexTmp + 2],\r
+                                                                puchReadRawdataBuffer[usRawdataByteIndexTmp + 3]));\r
+                        pstGh3x2xChannelRawdata->unIncompleteChMark |= GH3X2X_GET_LEFT_SHIFT_VAL(uchChCntIndex);\r
+                        break;\r
+                    }\r
+                    usRawdataByteIndexTmp += GH3X2X_FIFO_RAWDATA_SIZE;\r
+                }\r
+                if (GH3X2X_CHECK_LEFT_BIT_NOT_SET(pstGh3x2xChannelRawdata->unIncompleteChMark, uchChCntIndex))\r
+                {\r
+                    pstGh3x2xChannelRawdata->punIncompleteChRawdataArr[uchChCntIndex] = 0;\r
+                }\r
+            }\r
+        } // end of if (usRawdataCntMax != usRawdataCnt)\r
+    } // end of if (usRawdataCnt != 0)\r
+    pstGh3x2xChannelRawdata->usChRawdataCnt = usRawdataCnt;\r
+    return GH3X2X_RET_OK;\r
+}\r
+\r
+/**\r
+ * @fn     GS16 GH3X2X_GetRawdataWithChannelMap(STGh3x2xChannelRawdata *pstGh3x2xChannelRawdata, \r
+ *                                       GU8 *puchReadRawdataBuffer, GU16* usFifoLength, GU8 uchChannelMapCnt, \r
+ *                                       GU8 *puchChannelMapArr)\r
+ *\r
+ * @brief  Get rawdata from fifo with channel map\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   puchReadRawdataBuffer       pointer to read data buffer\r
+ * @param[in]   uchChannelMapCnt            channel map array cnt, max:32\r
+ * @param[in]   puchChannelMapArr           pointer to channel map array\r
+ * @param[out]  pstGh3x2xChannelRawdata     pointer to channel rawdata struct output\r
+ * @param[out]  usFifoLength                pointer to read fifo data length in bytes\r
+ *\r
+ * @return  GH3X2X_RET_OK                       return read fifo successful\r
+ * @retval  #GH3X2X_RET_READ_FIFO_CONTINUE      return fifo is not empty\r
+ * @retval  #GH3X2X_RET_PARAMETER_ERROR         return param error\r
+ */\r
+GS16 GH3X2X_GetRawdataWithChannelMap(STGh3x2xChannelRawdata *pstGh3x2xChannelRawdata, \r
+                                        GU8 *puchReadRawdataBuffer, GU16* usFifoLength, GU8 uchChannelMapCnt, \r
+                                        GU8 *puchChannelMapArr)\r
+{\r
+    GS16 sRet = GH3X2X_RET_OK;\r
+\r
+    GH3X2X_DEBUG_LOG_PARAM("%s\r\n", __FUNCTION__);\r
+\r
+    if ((puchReadRawdataBuffer != GH3X2X_PTR_NULL) && (usFifoLength != GH3X2X_PTR_NULL))\r
+    {\r
+        GH3X2X_WAIT_CHIP_WAKEUP();\r
+        *usFifoLength = GH3X2X_FIFO_CNT_CALC(GH3X2X_ReadReg(GH3X2X_INT_FIFO_UR_REG_ADDR));\r
+        if (*usFifoLength > g_usMaxNumReadFromFifo)\r
+        {\r
+            *usFifoLength = g_usMaxNumReadFromFifo;\r
+            sRet = GH3X2X_RET_READ_FIFO_CONTINUE;\r
+        }\r
+        if ((*usFifoLength > 0) && (*usFifoLength <= GH3X2X_FIFO_DATA_BYTES_MAX_LEN))\r
+        {\r
+            GH3X2X_ReadFifo(puchReadRawdataBuffer, *usFifoLength);\r
+        }\r
+        else\r
+        {\r
+            if (*usFifoLength > GH3X2X_FIFO_DATA_BYTES_MAX_LEN)\r
+            {\r
+                *usFifoLength = 0;\r
+                GH3X2X_DEBUG_LOG_PARAM("get rawdata fifo len greater than max, pelease check i2c/spi!\r\n");\r
+            }\r
+            else\r
+            {\r
+                GH3X2X_DEBUG_LOG_PARAM("get rawdata fifo equl 0!\r\n");\r
+            }\r
+        }\r
+        \r
+        /* call hook */\r
+        HOOK_FUNC_CALL(g_pGh3x2xGetRawdataHookFunc, (puchReadRawdataBuffer, *usFifoLength));\r
+        GH3X2X_WAIT_CHIP_DSLP();\r
+        sRet = GH3X2X_UnpackRawdataWithChannelMap(pstGh3x2xChannelRawdata, puchReadRawdataBuffer, *usFifoLength, \r
+                                                    uchChannelMapCnt, puchChannelMapArr);\r
+    }\r
+    else // fixed clear cnt if readbuffer ptr is null\r
+    {\r
+        GH3X2X_DEBUG_LOG_PARAM("get rawdata error that readbuffer is null!\r\n");\r
+        sRet = GH3X2X_RET_PARAMETER_ERROR;\r
+    }\r
+\r
+    return sRet;\r
+}\r
+\r
+/**\r
+ * @fn     GS8 GH3X2X_ChannelMapRawdataClear(STGh3x2xChannelRawdata *pstGh3x2xChannelRawdata)\r
+ *\r
+ * @brief  clear channel map rawdata struct\r
+ *\r
+ * @attention   This function must use before get rawdata by onne kind channel map\r
+ *              e.g. channel map start/stop need clear\r
+ *\r
+ * @param[in]   pstGh3x2xChannelRawdata     pointer to channel rawdata struct\r
+ * @param[out]  None\r
+ *\r
+ * @return  error code\r
+ * @retval  #GH3X2X_RET_OK                      return successfully\r
+ * @retval  #GH3X2X_RET_PARAMETER_ERROR         return param error\r
+ */\r
+GS8 GH3X2X_ChannelMapRawdataClear(STGh3x2xChannelRawdata *pstGh3x2xChannelRawdata)\r
+{\r
+    GS8 chRet = GH3X2X_RET_PARAMETER_ERROR;\r
+\r
+    GH3X2X_DEBUG_LOG_PARAM("%s\r\n", __FUNCTION__);\r
+    if (pstGh3x2xChannelRawdata != GH3X2X_PTR_NULL)\r
+    {\r
+        pstGh3x2xChannelRawdata->unIncompleteChMark = 0;\r
+        pstGh3x2xChannelRawdata->usChRawdataCnt = 0;\r
+        chRet = GH3X2X_RET_OK;\r
+    }\r
+    else\r
+    {\r
+        GH3X2X_DEBUG_LOG_PARAM("channel rawdata param is null!\r\n");\r
+    }\r
+    return chRet;\r
+}\r
+\r
+/**\r
+ * @fn     GS8 GH3X2X_SlotEnableConfig(GU16 usSlotEnableConfig, EMSlotEnableConfigType emSlotEnableConfigType)\r
+ *\r
+ * @brief  Slot enable config\r
+ *\r
+ * @attention  Set slot enable or disable, if just need enable slot by enable config param\r
+ *\r
+ * @param[in]  usSlotEnableConfig         slot enable index , @ref GH3X2X_SLOT_INDEX_0 ... GH3X2X_SLOT_INDEX_ALL\r
+ * @param[in]  emSlotEnableConfigType     slot config type, @ref EMSlotEnableConfigType\r
+ * @param[out]  None\r
+ * \r
+ * @return  errcode\r
+ * @retval  #GH3X2X_RET_OK                  return successfully\r
+ * @retval  #GH3X2X_RET_PARAMETER_ERROR     return param error\r
+ */\r
+GS8 GH3X2X_SlotEnableConfig(GU16 usSlotEnableConfig, EMSlotEnableConfigType emSlotEnableConfigType)\r
+{\r
+    GS8 chRet = GH3X2X_RET_OK;\r
+    GU16 usSlotEnableCfgRegVal = 0;\r
+    \r
+    GH3X2X_DEBUG_LOG_PARAM("%s\r\n", __FUNCTION__);\r
+    if (GH3X2X_CHECK_BIT_SET(GH3X2X_SLOT_INDEX_ALL, usSlotEnableConfig))\r
+    {\r
+        GH3X2X_WAIT_CHIP_WAKEUP();\r
+        switch (emSlotEnableConfigType)\r
+        {\r
+        case GH3X2X_SET_SLOT_ENABLE:\r
+            usSlotEnableCfgRegVal = GH3X2X_ReadReg(GH3X2X_SLOT_ENABLE_CFG_REG_ADDR);\r
+            GH3X2X_WriteReg(GH3X2X_SLOT_ENABLE_CFG_REG_ADDR,\r
+                            GH3X2X_SET_BIT(usSlotEnableCfgRegVal, usSlotEnableConfig) & GH3X2X_SLOT_INDEX_ALL);\r
+            break;\r
+        case GH3X2X_SET_SLOT_DISABLE:\r
+            usSlotEnableCfgRegVal = GH3X2X_ReadReg(GH3X2X_SLOT_ENABLE_CFG_REG_ADDR);\r
+            GH3X2X_WriteReg(GH3X2X_SLOT_ENABLE_CFG_REG_ADDR,\r
+                            GH3X2X_CLEAR_BIT(usSlotEnableCfgRegVal, usSlotEnableConfig) & GH3X2X_SLOT_INDEX_ALL);\r
+            break;\r
+        default: // include GH3X2X_SET_SLOT_DIRECT_ENABLE mode\r
+            GH3X2X_WriteReg(GH3X2X_SLOT_ENABLE_CFG_REG_ADDR, usSlotEnableConfig & GH3X2X_SLOT_INDEX_ALL);\r
+            break;\r
+        }\r
+        GH3X2X_WAIT_CHIP_DSLP();\r
+    }\r
+    else\r
+    {\r
+        GH3X2X_DEBUG_LOG_PARAM("slot enable config error!\r\n");\r
+        chRet = GH3X2X_RET_PARAMETER_ERROR;\r
+    }\r
+    return chRet;\r
+}\r
+\r
+/**\r
+ * @fn     void GH3X2X_SlotEnRegSet(GU8 uchSetValue)\r
+ *\r
+ * @brief  Slot enable reg set\r
+ *\r
+ * @attention  None\r
+ *\r
+ * @param[in]  set value\r
+ * @param[out]  None\r
+ * \r
+ * @return  None\r
+ */\r
+void GH3X2X_SlotEnRegSet(GU8 uchSetValue)\r
+{\r
+    \r
+    \r
+    GH3X2X_DEBUG_LOG_PARAM("[SlotEnRegSet] set slot en: 0x%X\r\n",uchSetValue);\r
+    GH3X2X_WriteReg(GH3X2X_SLOT_ENABLE_CFG_REG_ADDR,\r
+                (GU16)uchSetValue);\r
+}\r
+\r
+\r
+void GH3X2X_EcgCascadeSlotEnRegSet(GU8 uchSetValue)\r
+{\r
+        //chip1 disable ecg_slot\r
+        GH3X2X_WriteReg(GH3X2X_SLOT_ENABLE_CFG_REG_ADDR,\r
+                (GU16)0);\r
+        GU16 usRegVal = 0;\r
+        //chip1 clear fifo\r
+        usRegVal = GH3X2X_ReadReg(GH3X2X_CARDIFF_CTRL_REG_ADDR);\r
+        GH3X2X_WriteReg(GH3X2X_CARDIFF_CTRL_REG_ADDR, GH3X2X_CLEAR_BIT(usRegVal, GH3X2X_CARDIFF_CTRL_START_BIT));\r
+        GH3X2X_WriteReg(GH3X2X_CARDIFF_CTRL_REG_ADDR, usRegVal);\r
+        \r
+\r
+        GH3X2X_CascadeOperationSlaverChip();\r
+        //chip2 clear fifo, chip2 reset lead status\r
+        usRegVal = GH3X2X_ReadReg(GH3X2X_CARDIFF_CTRL_REG_ADDR);\r
+        GH3X2X_WriteReg(GH3X2X_CARDIFF_CTRL_REG_ADDR, GH3X2X_CLEAR_BIT(usRegVal, GH3X2X_CARDIFF_CTRL_START_BIT));\r
+        GH3X2X_WriteReg(GH3X2X_CARDIFF_CTRL_REG_ADDR, usRegVal);\r
+        \r
+        GH3X2X_WriteReg(GH3X2X_SLOT_ENABLE_CFG_REG_ADDR,\r
+        (GU16)uchSetValue);\r
+        GH3X2X_CascadeOperationMasterChip();\r
+        \r
+        //chip1 enable ecg_slot\r
+        GH3X2X_WriteReg(GH3X2X_SLOT_ENABLE_CFG_REG_ADDR,\r
+        (GU16)uchSetValue);\r
+\r
+}\r
+\r
+\r
+\r
+\r
+\r
+/**\r
+ * @fn     GS8 GH3X2X_FifoWatermarkThrConfig(GU16 usFifoWatermarkThr)\r
+ *\r
+ * @brief  Fifo water mark threshold config\r
+ *\r
+ * @attention   Watermark threshold val must in (2, 800]. if val <= 2, will set 3, if val > 800, set 800;\r
+ *              Be careful that fifo_use_cnt greater than val, gh3x2x willn't generate fifo_watermark interrupt after!\r
+ *\r
+ * @param[in]   usFifoWatermarkThr         watermark threshold val\r
+ * @param[out]  None\r
+ *\r
+ * @return  errcode\r
+ * @retval  #GH3X2X_RET_OK               return successfully\r
+ */\r
+GS8 GH3X2X_FifoWatermarkThrConfig(GU16 usFifoWatermarkThr)\r
+{\r
+    GU16 usFifoWatermarkThrVal = usFifoWatermarkThr;\r
+    GH3X2X_DEBUG_LOG_PARAM("%s\r\n", __FUNCTION__);\r
+    if (usFifoWatermarkThrVal < GH3X2X_FIFO_WATERMARK_THR_MIN)\r
+    {\r
+        GH3X2X_DEBUG_LOG_PARAM("fifo wateramrk thr param less than min!\r\n");\r
+        usFifoWatermarkThrVal = GH3X2X_FIFO_WATERMARK_THR_MIN;\r
+    }\r
+    else if (usFifoWatermarkThrVal > GH3X2X_FIFO_WATERMARK_THR_MAX)\r
+    {\r
+        GH3X2X_DEBUG_LOG_PARAM("fifo wateramrk thr param greater than max!\r\n");\r
+        usFifoWatermarkThrVal = GH3X2X_FIFO_WATERMARK_THR_MAX;\r
+    }\r
+    GH3X2X_WAIT_CHIP_WAKEUP();\r
+    GH3X2X_WriteReg(GH3X2X_FIFO_WATERLINE_REG_ADDR, usFifoWatermarkThrVal);\r
+    GH3X2X_WAIT_CHIP_DSLP();\r
+    g_usCurrentFiFoWaterLine = usFifoWatermarkThrVal;\r
+    return GH3X2X_RET_OK;\r
+}\r
+\r
+/**\r
+ * @fn     GU16 GH3X2X_GetFifoWatermarkThr(void)\r
+ *\r
+ * @brief  Get fifo water mark threshold\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  fifo water mark threshold\r
+ */\r
+GU16 GH3X2X_GetFifoWatermarkThr(void)\r
+{\r
+    GU16 usFifoWatermarkThrVal = 0;\r
+    GH3X2X_DEBUG_LOG_PARAM("%s\r\n", __FUNCTION__);\r
+    GH3X2X_WAIT_CHIP_WAKEUP();\r
+    usFifoWatermarkThrVal = GH3X2X_ReadReg(GH3X2X_FIFO_WATERLINE_REG_ADDR);\r
+    GH3X2X_WAIT_CHIP_DSLP();\r
+    return usFifoWatermarkThrVal;\r
+}\r
+\r
+/**\r
+ * @fn     GS8 GH3X2X_SlotLedCurrentConfig(GU8 uchSlotIndex, GU8 uchDrvIndex, GU8 uchCurrentVal)\r
+ *\r
+ * @brief  Slot led current config\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   uchSlotIndex        slot index [0-7]\r
+ * @param[in]   uchDrvIndex         driver index @ref GH3X2X_LED_DRV_INDEX_0 ... GH3X2X_LED_DRV_INDEX_1\r
+ * @param[in]   uchCurrentVal       current val\r
+ * @param[out]  None\r
+ *\r
+ * @return  errcode\r
+ * @retval  #GH3X2X_RET_OK               return successfully\r
+ * @retval  #GH3X2X_RET_PARAMETER_ERROR     return param error\r
+ */\r
+GS8 GH3X2X_SlotLedCurrentConfig(GU8 uchSlotIndex, GU8 uchDrvIndex, GU8 uchCurrentVal)\r
+{\r
+    GU16 usCurrentRegVal = 0;\r
+    GU16 usSlotDrvRegAddr = 0;\r
+    GS8 chRet = GH3X2X_RET_PARAMETER_ERROR;\r
+    GH3X2X_DEBUG_LOG_PARAM("%s\r\n", __FUNCTION__);\r
+    if ((uchSlotIndex < GH3X2X_SLOT_NUM_MAX) && (uchDrvIndex < GH3X2X_SLOT_LED_DRV_NUM_MAX))\r
+    {\r
+        usSlotDrvRegAddr = GH3X2X_SLOT0_CTRL_10_REG_ADDR + (uchSlotIndex * GH3X2X_SLOT_CTRL_OFFSET)\\r
+                             + (uchDrvIndex * GH3X2X_REG_ADDR_SIZE);\r
+        GH3X2X_WAIT_CHIP_WAKEUP();\r
+        usCurrentRegVal = GH3X2X_ReadReg(usSlotDrvRegAddr);\r
+        GH3X2X_VAL_CLEAR_BIT(usCurrentRegVal, (GU16)GH3X2X_SLOT_LED_CURRENT_CLEAR_MASK);\r
+        GH3X2X_VAL_SET_BIT(usCurrentRegVal, (GU16)uchCurrentVal);\r
+        GH3X2X_WriteReg(usSlotDrvRegAddr, usCurrentRegVal);\r
+        GH3X2X_WAIT_CHIP_DSLP();\r
+        chRet = GH3X2X_RET_OK;\r
+    }\r
+    else\r
+    {\r
+        if (uchSlotIndex >= GH3X2X_SLOT_NUM_MAX)\r
+        {\r
+            GH3X2X_DEBUG_LOG_PARAM("slot index param greater than max!\r\n");\r
+        }\r
+        else // uchDrvIndex >= GH3X2X_SLOT_LED_DRV_NUM_MAX\r
+        {\r
+            GH3X2X_DEBUG_LOG_PARAM("drv index param greater than max!\r\n");\r
+        }\r
+    }\r
+    return chRet;\r
+}\r
+\r
+/**\r
+ * @fn     GU8 GH3X2X_GetSlotLedCurrent(GU8 uchSlotIndex, GU8 uchDrvIndex)\r
+ *\r
+ * @brief  Get slot led current config\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   uchSlotIndex        slot index [0-7]\r
+ * @param[in]   uchDrvIndex         driver index @ref GH3X2X_LED_DRV_INDEX_0 ... GH3X2X_LED_DRV_INDEX_1\r
+ * @param[out]  None\r
+ *\r
+ * @return  current val. if param error, return val always equal 0\r
+ */\r
+GU8 GH3X2X_GetSlotLedCurrent(GU8 uchSlotIndex, GU8 uchDrvIndex)\r
+{\r
+    GU16 usCurrentRegVal = 0;\r
+    GU16 usSlotDrvRegAddr = 0;\r
+    GH3X2X_DEBUG_LOG_PARAM("%s\r\n", __FUNCTION__);\r
+    if ((uchSlotIndex < GH3X2X_SLOT_NUM_MAX) && (uchDrvIndex < GH3X2X_SLOT_LED_DRV_NUM_MAX))\r
+    {\r
+        usSlotDrvRegAddr = GH3X2X_SLOT0_CTRL_10_REG_ADDR + (uchSlotIndex * GH3X2X_SLOT_CTRL_OFFSET)\\r
+                             + (uchDrvIndex * GH3X2X_REG_ADDR_SIZE);\r
+        GH3X2X_WAIT_CHIP_WAKEUP();\r
+        usCurrentRegVal = GH3X2X_ReadReg(usSlotDrvRegAddr);\r
+        GH3X2X_WAIT_CHIP_DSLP();\r
+    }\r
+    else\r
+    {\r
+        if (uchSlotIndex >= GH3X2X_SLOT_NUM_MAX)\r
+        {\r
+            GH3X2X_DEBUG_LOG_PARAM("slot index param greater than max!\r\n");\r
+        }\r
+        else // uchDrvIndex >= GH3X2X_SLOT_LED_DRV_NUM_MAX\r
+        {\r
+            GH3X2X_DEBUG_LOG_PARAM("drv index param greater than max!\r\n");\r
+        }\r
+    }\r
+    return GH3X2X_GET_LOW_BYTE_FROM_WORD(usCurrentRegVal);\r
+}\r
+\r
+/**\r
+ * @fn     GS8 GH3X2X_SlotLedTiaGainConfig(GU8 uchSlotIndex, GU8 uchAdcIndex, GU8 uchGainVal)\r
+ *\r
+ * @brief  Slot gain config\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   uchSlotIndex        slot index [0-7]\r
+ * @param[in]   uchAdcIndex         adc index [0-3]\r
+ * @param[in]   uchGainVal          tia gain val [0-12]\r
+ * @param[out]  None\r
+ *\r
+ * @return  errcode\r
+ * @retval  #GH3X2X_RET_OK                  return successfully\r
+ * @retval  #GH3X2X_RET_PARAMETER_ERROR     return param error\r
+ */\r
+GS8 GH3X2X_SlotLedTiaGainConfig(GU8 uchSlotIndex, GU8 uchAdcIndex, GU8 uchGainVal)\r
+{\r
+    GU16 usGainRegVal = 0;\r
+    GU16 usSlotTiaGainRegAddr = 0;\r
+    GS8 chRet = GH3X2X_RET_PARAMETER_ERROR;\r
+    GH3X2X_DEBUG_LOG_PARAM("%s\r\n", __FUNCTION__);\r
+    if ((uchSlotIndex < GH3X2X_SLOT_NUM_MAX) && (uchAdcIndex < GH3X2X_SLOT_TIA_GAIN_NUM_MAX)\r
+        && (uchGainVal < GH3X2X_SLOT_TIA_GAIN_VAL_MAX))\r
+    {\r
+        usSlotTiaGainRegAddr = GH3X2X_SLOT0_CTRL_4_REG_ADDR + (uchSlotIndex * GH3X2X_SLOT_CTRL_OFFSET);\r
+        GH3X2X_WAIT_CHIP_WAKEUP();\r
+        usGainRegVal = GH3X2X_ReadReg(usSlotTiaGainRegAddr);\r
+        GH3X2X_VAL_CLEAR_BIT(usGainRegVal,\r
+                                (GH3X2X_SLOT_TIA_GAIN_BITS_MARK << (GH3X2X_SLOT_TIA_GAIN_BITS_SIZE * uchAdcIndex)));\r
+        GH3X2X_VAL_SET_BIT(usGainRegVal, (((GU16)uchGainVal) << (GH3X2X_SLOT_TIA_GAIN_BITS_SIZE * uchAdcIndex)));\r
+        GH3X2X_WriteReg(usSlotTiaGainRegAddr, usGainRegVal);\r
+        GH3X2X_WAIT_CHIP_DSLP();\r
+        chRet = GH3X2X_RET_OK;\r
+    }\r
+    else\r
+    {\r
+        if (uchSlotIndex >= GH3X2X_SLOT_NUM_MAX)\r
+        {\r
+            GH3X2X_DEBUG_LOG_PARAM("slot index param greater than max!\r\n");\r
+        }\r
+        else if (uchAdcIndex >= GH3X2X_SLOT_TIA_GAIN_NUM_MAX)\r
+        {\r
+            GH3X2X_DEBUG_LOG_PARAM("adc index param greater than max!\r\n");\r
+        }\r
+        else\r
+        {\r
+            GH3X2X_DEBUG_LOG_PARAM("gain val param greater than max!\r\n");\r
+        }\r
+    }\r
+    return chRet;\r
+}\r
+\r
+/**\r
+ * @fn     GU8 GH3X2X_GetSlotLedTiaGain(GU8 uchSlotIndex, GU8 uchAdcIndex)\r
+ *\r
+ * @brief  Get slot gain config\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   uchSlotIndex        slot index [0-7]\r
+ * @param[in]   uchAdcIndex         adc index [0-3]\r
+ * @param[out]  None\r
+ *\r
+ * @return  tia gain val. if param error, return val always equal 0\r
+ */\r
+GU8 GH3X2X_GetSlotLedTiaGain(GU8 uchSlotIndex, GU8 uchAdcIndex)\r
+{\r
+    GU16 usGainRegVal = 0;\r
+    GU16 usSlotTiaGainRegAddr = 0;\r
+    GH3X2X_DEBUG_LOG_PARAM("%s\r\n", __FUNCTION__);\r
+    if ((uchSlotIndex < GH3X2X_SLOT_NUM_MAX) && (uchAdcIndex < GH3X2X_SLOT_TIA_GAIN_NUM_MAX))\r
+    {\r
+        usSlotTiaGainRegAddr = GH3X2X_SLOT0_CTRL_4_REG_ADDR + (uchSlotIndex * GH3X2X_SLOT_CTRL_OFFSET);\r
+        GH3X2X_WAIT_CHIP_WAKEUP();\r
+        usGainRegVal = GH3X2X_ReadReg(usSlotTiaGainRegAddr);\r
+        GH3X2X_WAIT_CHIP_DSLP();\r
+    }\r
+    else\r
+    {\r
+        if (uchSlotIndex >= GH3X2X_SLOT_NUM_MAX)\r
+        {\r
+            GH3X2X_DEBUG_LOG_PARAM("slot index param greater than max!\r\n");\r
+        }\r
+        else // uchAdcIndex >= GH3X2X_SLOT_TIA_GAIN_NUM_MAX\r
+        {\r
+            GH3X2X_DEBUG_LOG_PARAM("adc index param greater than max!\r\n");\r
+        }\r
+    }\r
+    return (GU8)(((usGainRegVal) >> (GH3X2X_SLOT_TIA_GAIN_BITS_SIZE * uchAdcIndex)) & GH3X2X_SLOT_TIA_GAIN_BITS_MARK);\r
+}\r
+\r
+/**\r
+ * @fn     GS8 GH3X2X_AdcBgcThrConfig(GU8 uchAdcIndex, GU8 uchBgcThrVal)\r
+ *\r
+ * @brief  adc bgc thr config\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   uchAdcIndex         adc index [0-3]\r
+ * @param[in]   uchBgcThrVal        bgc thr val [0-7]\r
+ * @param[out]  None\r
+ *\r
+ * @return  errcode\r
+ * @retval  #GH3X2X_RET_OK                  return successfully\r
+ * @retval  #GH3X2X_RET_PARAMETER_ERROR     return param error\r
+ */\r
+GS8 GH3X2X_AdcBgcThrConfig(GU8 uchAdcIndex, GU8 uchBgcThrVal)\r
+{\r
+    GU16 usBgcThregVal = 0;\r
+    GS8 chRet = GH3X2X_RET_PARAMETER_ERROR;\r
+    GU8 uchKdcCh = (GU8)(GH3X2X_SLOT_KDC_THR_ADC_INDEX_MAX - uchAdcIndex);\r
+    GH3X2X_DEBUG_LOG_PARAM("%s\r\n", __FUNCTION__);\r
+    if ((uchAdcIndex < GH3X2X_SLOT_TIA_GAIN_NUM_MAX) && (uchBgcThrVal < GH3X2X_SLOT_KDC_THR_VAL_MAX))\r
+    {\r
+        GH3X2X_WAIT_CHIP_WAKEUP();\r
+        usBgcThregVal = GH3X2X_ReadReg(GH3X2X_PPG_DAC_AD_REG1_REG_ADDR);\r
+        GH3X2X_VAL_CLEAR_BIT(usBgcThregVal,\r
+                                (GH3X2X_SLOT_KDC_THR_BITS_MARK << (GH3X2X_SLOT_KDC_THR_BITS_SIZE * uchKdcCh)));\r
+        GH3X2X_VAL_SET_BIT(usBgcThregVal, (((GU16)uchBgcThrVal) << (GH3X2X_SLOT_KDC_THR_BITS_SIZE * uchKdcCh)));\r
+        GH3X2X_WriteReg(GH3X2X_PPG_DAC_AD_REG1_REG_ADDR, usBgcThregVal);\r
+        GH3X2X_WAIT_CHIP_DSLP();\r
+        chRet = GH3X2X_RET_OK;\r
+    }\r
+    else\r
+    {\r
+        if (uchAdcIndex >= GH3X2X_SLOT_TIA_GAIN_NUM_MAX)\r
+        {\r
+            GH3X2X_DEBUG_LOG_PARAM("adc index param greater than max!\r\n");\r
+        }\r
+        else\r
+        {\r
+            GH3X2X_DEBUG_LOG_PARAM("bgc thr val param greater than max!\r\n");\r
+        }\r
+    }\r
+    return chRet;\r
+}\r
+\r
+/**\r
+ * @fn     GU8 GH3X2X_GetAdcBgcThr(GU8 uchAdcIndex)\r
+ *\r
+ * @brief  Get adc bgc thr config\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   uchAdcIndex         adc index [0-3]\r
+ * @param[out]  None\r
+ *\r
+ * @return  tia gain val. if param error, return val always equal 0\r
+ */\r
+GU8 GH3X2X_GetAdcBgcThr(GU8 uchAdcIndex)\r
+{\r
+    GU16 usBgcThregVal = 0;\r
+    GU8 uchKdcCh = 0;\r
+    GH3X2X_DEBUG_LOG_PARAM("%s\r\n", __FUNCTION__);\r
+    if (uchAdcIndex < GH3X2X_SLOT_TIA_GAIN_NUM_MAX)\r
+    {\r
+        uchKdcCh = (GU8)(GH3X2X_SLOT_KDC_THR_ADC_INDEX_MAX - uchAdcIndex);\r
+        GH3X2X_WAIT_CHIP_WAKEUP();\r
+        usBgcThregVal = GH3X2X_ReadReg(GH3X2X_PPG_DAC_AD_REG1_REG_ADDR);\r
+        GH3X2X_WAIT_CHIP_DSLP();\r
+    }\r
+    else\r
+    {\r
+        GH3X2X_DEBUG_LOG_PARAM("adc index param greater than max!\r\n");\r
+    }\r
+    return (GU8)(((usBgcThregVal) >> (GH3X2X_SLOT_KDC_THR_BITS_SIZE * uchKdcCh)) & GH3X2X_SLOT_KDC_THR_BITS_MARK);\r
+}\r
+\r
+/**\r
+ * @fn     GS8 GH3X2X_IrqWidthConfig(GU16 usIrqPulseWidth, GU16 usIrqColdWidth)\r
+ *\r
+ * @brief  Irq width config\r
+ *\r
+ * @attention   Irq val must in [0, 2047]. real_width = (val + 1) * low_clk_tick;\r
+ *              low_clk default 32k, if set ext clk enable that use low_ext_clk;\r
+ *\r
+ * @param[in]   usIrqPulseWidth         irq pulse width val\r
+ * @param[in]   usIrqColdWidth          irq cold width val\r
+ * @param[out]  None\r
+ *\r
+ * @return  errcode\r
+ * @retval  #GH3X2X_RET_OK               return successfully\r
+ */\r
+GS8 GH3X2X_IrqWidthConfig(GU16 usIrqPulseWidth, GU16 usIrqColdWidth)\r
+{\r
+    GU16 usIrqPulseWidthVal = usIrqPulseWidth;\r
+    GU16 usIrqColdWidthVal = usIrqColdWidth;\r
+    GH3X2X_DEBUG_LOG_PARAM("%s\r\n", __FUNCTION__);\r
+    if (usIrqPulseWidthVal > GH3X2X_IRQ_WIDTH_VAL_MAX)\r
+    {\r
+        GH3X2X_DEBUG_LOG_PARAM("irq pulse width param greater than max!\r\n");\r
+        usIrqPulseWidthVal = GH3X2X_IRQ_WIDTH_VAL_MAX;\r
+    }\r
+    if (usIrqColdWidthVal > GH3X2X_IRQ_WIDTH_VAL_MAX)\r
+    {\r
+        GH3X2X_DEBUG_LOG_PARAM("irq cold width param greater than max!\r\n");\r
+        usIrqColdWidthVal = GH3X2X_IRQ_WIDTH_VAL_MAX;\r
+    }\r
+    GH3X2X_WAIT_CHIP_WAKEUP();\r
+    GH3X2X_WriteReg(GH3X2X_INT_PWR_REG_ADDR, usIrqPulseWidthVal);\r
+    GH3X2X_WriteReg(GH3X2X_INT_CTR_REG_ADDR, usIrqColdWidthVal);\r
+    GH3X2X_WAIT_CHIP_DSLP();\r
+    return GH3X2X_RET_OK;\r
+}\r
+\r
+/**\r
+ * @fn     GS8 GH3X2X_IrqModeConfig(EMIrqModeConfig emIrqMode)\r
+ *\r
+ * @brief  Irq mode config\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   emIrqMode         irq mode config @ref EMIrqModeConfig\r
+ * @param[out]  None\r
+ *\r
+ * @return  errcode\r
+ * @retval  #GH3X2X_RET_OK               return successfully\r
+ */\r
+GS8 GH3X2X_IrqModeConfig(EMIrqModeConfig emIrqMode)\r
+{\r
+    GU16 usIrqCtrlRegVal = 0;\r
+    GH3X2X_DEBUG_LOG_PARAM("%s\r\n", __FUNCTION__);\r
+    GH3X2X_WAIT_CHIP_WAKEUP();\r
+    usIrqCtrlRegVal = GH3X2X_ReadReg(GH3X2X_INT_CR_REG_ADDR);\r
+    GH3X2X_VAL_CLEAR_BIT(usIrqCtrlRegVal, (GU16)GH3X2X_INT_CTRL_MODE_MSK_BIT);\r
+    GH3X2X_VAL_SET_BIT(usIrqCtrlRegVal, ((GU16)emIrqMode) & GH3X2X_INT_CTRL_MODE_MSK_BIT);\r
+    GH3X2X_WriteReg(GH3X2X_INT_CR_REG_ADDR, usIrqCtrlRegVal);\r
+    GH3X2X_WAIT_CHIP_DSLP();\r
+    return GH3X2X_RET_OK;\r
+}\r
+\r
+/**\r
+ * @fn     void GH3X2X_RegisterResetPinControlFunc(void (*pResetPinLevelControlFunc)(GU8 uchPinLevel))\r
+ *\r
+ * @brief  Register reset pin level control function\r
+ *\r
+ * @attention   Pin level set val should define as 1 [high level] or 0 [low level];\r
+ *\r
+ * @param[in]   pResetPinLevelControlFunc       pointer to set reset pin level function\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_RegisterResetPinControlFunc(void (*pResetPinLevelControlFunc)(GU8 uchPinLevel))\r
+{\r
+    g_pGh3x2xResetPinLevelControlFunc = pResetPinLevelControlFunc;\r
+    GH3X2X_DEBUG_LOG_PARAM("%s\r\n", __FUNCTION__);\r
+}\r
+\r
+/**\r
+ * @fn     GS8 GH3X2X_HardReset(void)\r
+ *\r
+ * @brief  Gh3x2x softreset via i2c/spi, can read&write reg with gh3x2x after reset\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  errcode\r
+ * @retval  #GH3X2X_RET_OK               return successfully\r
+ * @retval  #GH3X2X_RET_GENERIC_ERROR    reset pin control function not register\r
+ */\r
+GS8 GH3X2X_HardReset(void)\r
+{\r
+    GS8 chRet = GH3X2X_RET_GENERIC_ERROR;\r
+    GH3X2X_DEBUG_LOG_PARAM("%s\r\n", __FUNCTION__);\r
+    if (g_pGh3x2xResetPinLevelControlFunc != GH3X2X_PTR_NULL)\r
+    {\r
+        g_pGh3x2xResetPinLevelControlFunc(0);\r
+        GH3X2X_DelayUs(GH3X2X_HARD_RESET_DELAY_X_US); /* hard reset delay 20us. */\r
+        g_pGh3x2xResetPinLevelControlFunc(1);\r
+        chRet = GH3X2X_RET_OK;\r
+    }\r
+    else\r
+    {\r
+        GH3X2X_DEBUG_LOG_PARAM("reset pin ctrl func has not register!\r\n");\r
+    }\r
+    g_uchActiveChipResetFlag = 1;\r
+    if (g_uchResetFromProtocolFlag == 1)\r
+    {\r
+        g_uchResetFromProtocolFlag = 0;\r
+        HOOK_FUNC_CALL(g_pGh3x2xResetByProtocolHookFunc, () );  /* call hook */\r
+    }\r
+    return chRet;\r
+}\r
+\r
+/**\r
+ * @fn     void GH3X2X_WearDetectEnable(EMWearDetectEnableType emWearDetectEnable)\r
+ *\r
+ * @brief  enable or disable wear detect\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   emWearDetectEnable      enable or disable @ref EMWearDetectEnableType\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_WearDetectEnable(EMWearDetectEnableType emWearDetectEnable)\r
+{\r
+    GU16 usWearStatus = 0;\r
+\r
+    GH3X2X_WAIT_CHIP_WAKEUP();\r
+    usWearStatus = GH3X2X_ReadReg(GH3X2X_ADT_WEARON_CR_REG_ADDR);\r
+    \r
+    if (WEAR_DETECT_ENABLE == emWearDetectEnable)\r
+    {\r
+        GH3X2X_VAL_SET_BIT(usWearStatus, GH3X2X_ADT_WEAR_DET_EN_MASK_BIT);\r
+    }\r
+    else\r
+    {\r
+        GH3X2X_VAL_CLEAR_BIT(usWearStatus, (GU16)GH3X2X_ADT_WEAR_DET_EN_MASK_BIT);\r
+    }\r
+\r
+    GH3X2X_WriteReg(GH3X2X_ADT_WEARON_CR_REG_ADDR, usWearStatus); \r
+    GH3X2X_WAIT_CHIP_DSLP();\r
+}\r
+\r
+/**\r
+ * @fn     void GH3X2X_ResetHardAdt(void)\r
+ *\r
+ * @brief  Gh3x2x reset hard adt  \r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_ResetHardAdt(void)\r
+{\r
+    /* clear int status. restart adt */\r
+    GH3X2X_ExitLowPowerMode();\r
+    GH3X2X_WriteRegBitField(GH3X2X_ADT_WEARON_CR_REG_ADDR,0,0,0);\r
+    GH3X2X_WriteReg(GH3X2X_INT_STR_REG_ADDR, GH3X2X_IRQ_MSK_WEAR_ON_BIT | GH3X2X_IRQ_MSK_WEAR_OFF_BIT);\r
+    GH3X2X_WriteRegBitField(GH3X2X_ADT_WEARON_CR_REG_ADDR,0,0,1);\r
+    GH3X2X_EnterLowPowerMode();\r
+}\r
+\r
+\r
+/**\r
+ * @fn     GS8 GH3X2X_WearDetectSwitchTo(EMWearDetectType emWearDetectType, EMWearDetectForceSwitch emForceSwitch)\r
+ *\r
+ * @brief  Gh3x2x switch to detect wear on/off type \r
+ *\r
+ * @attention   Should follow that use WEAR_DETECT_DONT_FORCE_SWITCH @wear on/off irq status process.\r
+ *              If want force switch to detect on/off, should use WEAR_DETECT_FORCE_SWITCH. careful!!!\r
+ *\r
+ * @param[in]   emWearDetectType        switch to detect type @ref EMWearDetectType\r
+ * @param[in]   emForceSwitch           force switch type @ref EMWearDetectForceSwitch\r
+ * @param[out]  None\r
+ *\r
+ * @return  errcode\r
+ * @retval  #GH3X2X_RET_OK                  return successfully\r
+ * @retval  #GH3X2X_RET_GENERIC_ERROR       detect type equal last type, don't need to switch\r
+ * @retval  #GH3X2X_RET_PARAMETER_ERROR     return param error\r
+ */\r
+GS8 GH3X2X_WearDetectSwitchTo(EMWearDetectType emWearDetectType, EMWearDetectForceSwitch emForceSwitch)\r
+{\r
+    GS8 chRet = GH3X2X_RET_GENERIC_ERROR;\r
+    GU16 usWearStatus = 0;\r
+    GU16 usWearLogicSel = 0;\r
+\r
+    GH3X2X_DEBUG_LOG_PARAM("%s:type = %d\r\n", __FUNCTION__, emWearDetectType);\r
+    if (emWearDetectType > WEAR_DETECT_WEAR_OFF)\r
+    {\r
+        GH3X2X_DEBUG_LOG_PARAM("param set error! @ref EMWearDetectType\r\n");\r
+        chRet = GH3X2X_RET_PARAMETER_ERROR;\r
+    }\r
+    else\r
+    {\r
+        GH3X2X_WAIT_CHIP_WAKEUP();\r
+        usWearStatus = GH3X2X_ReadReg(GH3X2X_ADT_WEARON_CR_REG_ADDR);\r
+        GH3X2X_DEBUG_LOG_PARAM("[GH3X2X_WearDetectSwitchTo] usWearStatus = %d\r\n",(int)usWearStatus);\r
+        if (emWearDetectType == WEAR_DETECT_WEAR_ON) // switch to detect wear on (got wear off evt)\r
+        {\r
+            if ((GH3X2X_CHECK_BIT_SET(usWearStatus, GH3X2X_ADT_WEAR_STATUS_MASK_BIT)) \\r
+                || (emForceSwitch != WEAR_DETECT_DONT_FORCE_SWITCH)) // system is wear on\r
+            {\r
+                GH3X2X_DEBUG_LOG_PARAM("[GH3X2X_WearDetectSwitchTo] WEAR_DETECT_WEAR_ON\r\n");\r
+#if (GH3X2X_WEAR_ON_FORCE_SWITCH_WITH_LOGIC_SEL) // wear on force switch with adt logic sel\r
+                GH3X2X_VAL_CLEAR_BIT(usWearStatus, (GU16)GH3X2X_ADT_WEAR_STATUS_MASK_BIT);\r
+                if (emForceSwitch != WEAR_DETECT_DONT_FORCE_SWITCH)\r
+                {\r
+                    usWearLogicSel = GH3X2X_ReadReg(GH3X2X_ADT_WEARON_LOGIC_SEL_REG_ADDR);\r
+                    GH3X2X_WriteReg(GH3X2X_ADT_WEARON_LOGIC_SEL_REG_ADDR, 0); // clear all logic\r
+                    GH3X2X_WriteReg(GH3X2X_ADT_WEARON_CR_REG_ADDR, usWearStatus); // set system into wear off\r
+                    GH3X2X_WriteReg(GH3X2X_ADT_WEARON_CR_REG_ADDR, \\r
+                                    GH3X2X_SET_BIT(usWearStatus, GH3X2X_ADT_WEAR_CR_WEAR_ON_VAL));\r
+                    GH3X2X_DelayUs(GH3X2X_WEAR_DETECT_SWITCH_WAIT_X_US);\r
+                    GH3X2X_WriteReg(GH3X2X_ADT_WEARON_LOGIC_SEL_REG_ADDR, usWearLogicSel); // re-sel wear on logic\r
+                }\r
+                else\r
+                {\r
+                    GH3X2X_WriteReg(GH3X2X_ADT_WEARON_CR_REG_ADDR, usWearStatus); // set system into wear off\r
+                }\r
+#else\r
+                GH3X2X_VAL_CLEAR_BIT(usWearStatus, (GU16)GH3X2X_ADT_WEAR_STATUS_MASK_BIT);\r
+                if ((GH3X2X_CHECK_BIT_SET(usWearStatus, GH3X2X_ADT_WEAR_DET_EN_MASK_BIT))\r
+                    && (emForceSwitch != WEAR_DETECT_DONT_FORCE_SWITCH))\r
+                {\r
+                    GH3X2X_WriteReg(GH3X2X_ADT_WEARON_CR_REG_ADDR, \\r
+                                        GH3X2X_CLEAR_BIT(usWearStatus, GH3X2X_ADT_WEAR_DET_EN_MASK_BIT));\r
+\r
+                              GH3X2X_DEBUG_LOG_PARAM("[GH3X2X_WearDetectSwitchTo] write det en to 0 !!!\r\n");\r
+                }\r
+                GH3X2X_WriteReg(GH3X2X_ADT_WEARON_CR_REG_ADDR, usWearStatus); // set system into wear off\r
+\r
+                        GH3X2X_DEBUG_LOG_PARAM("[GH3X2X_WearDetectSwitchTo] usWearStatus = %d\r\n",(int)usWearStatus);\r
+\r
+                \r
+#endif\r
+                chRet = GH3X2X_RET_OK;\r
+            } // end of if (GH3X2X_CHECK_BIT_SET(usWearStatus, GH3X2X_ADT_WEAR_STATUS_MASK_BIT))\r
+        } // end of if (emWearDetectType == WEAR_DETECT_WEAR_ON)\r
+        else // switch to detect wear off (got wear on evt)\r
+        {\r
+            if (GH3X2X_CHECK_BIT_NOT_SET(usWearStatus, GH3X2X_ADT_WEAR_STATUS_MASK_BIT) \\r
+                || (emForceSwitch != WEAR_DETECT_DONT_FORCE_SWITCH)) // system is wear off\r
+            {\r
+                GH3X2X_DEBUG_LOG_PARAM("[GH3X2X_WearDetectSwitchTo] WEAR_DETECT_WEAR_OFF\r\n");\r
+                GH3X2X_VAL_SET_BIT(usWearStatus, GH3X2X_ADT_WEAR_STATUS_MASK_BIT);\r
+                if (emForceSwitch != WEAR_DETECT_DONT_FORCE_SWITCH)\r
+                {\r
+                    usWearLogicSel = GH3X2X_ReadReg(GH3X2X_ADT_WEAROFF_LOGIC_SEL_REG_ADDR);\r
+                    GH3X2X_WriteReg(GH3X2X_ADT_WEAROFF_LOGIC_SEL_REG_ADDR, 0); // clear all logic\r
+                    GH3X2X_WriteReg(GH3X2X_ADT_WEARON_CR_REG_ADDR, usWearStatus); // set system into wear on\r
+                    GH3X2X_WriteReg(GH3X2X_ADT_WEARON_CR_REG_ADDR, \\r
+                                    GH3X2X_SET_BIT(usWearStatus, GH3X2X_ADT_WEAR_CR_WEAR_OFF_VAL));\r
+                    GH3X2X_DelayUs(GH3X2X_WEAR_DETECT_SWITCH_WAIT_X_US);\r
+                    GH3X2X_WriteReg(GH3X2X_ADT_WEAROFF_LOGIC_SEL_REG_ADDR, usWearLogicSel); // re-sel wear off logic\r
+                }\r
+                else\r
+                {\r
+                    GH3X2X_WriteReg(GH3X2X_ADT_WEARON_CR_REG_ADDR, usWearStatus); // set system into wear on\r
+                }\r
+                chRet = GH3X2X_RET_OK;\r
+            }\r
+        }\r
+        GH3X2X_WAIT_CHIP_DSLP();\r
+    } // end of else if (emWearDetectType > WEAR_DETECT_WEAR_OFF)\r
+    return chRet;\r
+}\r
+\r
+/**\r
+ * @fn     EMSkinColorStatusType GH3X2X_GetSkinStatus(void)\r
+ *\r
+ * @brief  Get gh3x2x skin color status\r
+ *\r
+ * @attention   Must using when chip hard wear detect module enable, if not always return 0\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  skin color status @ref EMSkinColorStatusType\r
+ */\r
+EMSkinColorStatusType GH3X2X_GetSkinStatus(void)\r
+{\r
+    GU16 usSkinStatus = 0;\r
+    GH3X2X_DEBUG_LOG_PARAM("%s\r\n", __FUNCTION__);\r
+    GH3X2X_WAIT_CHIP_WAKEUP();\r
+    usSkinStatus = GH3X2X_ReadReg(GH3X2X_SKIN_STR_REG_ADDR);\r
+    GH3X2X_WAIT_CHIP_DSLP();\r
+    return ((EMSkinColorStatusType) GH3X2X_VAL_GET_BIT(usSkinStatus, GH3X2X_SKIN_COLOR_STATUS_MASK_BIT));\r
+}\r
+\r
+/**\r
+ * @fn     GS8 GH3X2X_HsiClockCalibration(void)\r
+ *\r
+ * @brief  Calibration Hsi(high-speed internal) clock\r
+ *\r
+ * @attention   must use 4M clock input @OSCIN pin\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  errcode\r
+ * @retval  #GH3X2X_RET_OK                  return successfully\r
+ * @retval  #GH3X2X_RET_GENERIC_ERROR       input clock is unstable, or sampling was started\r
+ */\r
+GS8 GH3X2X_HsiClockCalibration(void)\r
+{\r
+    GS8 chRet = GH3X2X_RET_GENERIC_ERROR;\r
+\r
+    GH3X2X_DEBUG_LOG_PARAM("%s\r\n", __FUNCTION__);\r
+    if (g_uchGh3x2xStatus < GH3X2X_STATUS_STARTED)\r
+    {\r
+        GH3X2X_WAIT_CHIP_WAKEUP();\r
+        GH3X2X_WriteReg(GH3X2X_OSC_THR_REG_ADDR, GH3X2X_HSI_CALI_THR_CNT_VAL);\r
+        GH3X2X_WriteReg(GH3X2X_OSC_CR_REG_ADDR, GH3X2X_HSI_CALI_CTRL_EN_VAL);\r
+        GH3X2X_DelayUs(GH3X2X_HSI_CALI_DELAY_VAL);\r
+        if (GH3X2X_CHECK_BIT_SET(GH3X2X_ReadReg(GH3X2X_OSC_FLAG_REG_ADDR), GH3X2X_OSC_CALI_CODE_LOACKED))\r
+        {\r
+            chRet = GH3X2X_RET_OK;\r
+        }\r
+        GH3X2X_DEBUG_LOG_PARAM("Hsi: 0x%.4x\r\n", GH3X2X_ReadReg(GH3X2X_OSC13M_TUNE_REG_ADDR));\r
+        GH3X2X_WriteReg(GH3X2X_OSC_CR_REG_ADDR, GH3X2X_OSC_CALI_CTRL_DIS_VAL);\r
+        GH3X2X_WAIT_CHIP_DSLP();\r
+    }\r
+    \r
+    return chRet;\r
+}\r
+\r
+/**\r
+ * @fn     GS8 GH3X2X_LsiClockCalibration(void)\r
+ *\r
+ * @brief  Calibration Lsi(low-speed internal) clock\r
+ *\r
+ * @attention   must use 4M clock input @OSCIN pin, take case that will consume about 100ms\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  errcode\r
+ * @retval  #GH3X2X_RET_OK                  return successfully\r
+ * @retval  #GH3X2X_RET_GENERIC_ERROR       input clock is unstable, or sampling was started\r
+ */\r
+GS8 GH3X2X_LsiClockCalibration(void)\r
+{\r
+    GS8 chRet = GH3X2X_RET_GENERIC_ERROR;\r
+    GU16 usCaliVal = 0;\r
+    GS16 sFreqErrVal = 0;\r
+    GS16 sLastFreqErrVal = GH3X2X_LSI_CALI_ERR_MAX_VAL;\r
+    GU8 uchIndex = 0;\r
+    GU8 uchMinVal = 0;\r
+    GU8 uchMaxVal = GH3X2X_LSI_CALI_FINE_VAL_MAX;\r
+    GU8 uchCalcVal = 0;\r
+    GU8 uchLastCalcVal = GH3X2X_LSI_CALI_FINE_VAL_MAX;\r
+\r
+    GH3X2X_DEBUG_LOG_PARAM("%s\r\n", __FUNCTION__);\r
+    if (g_uchGh3x2xStatus < GH3X2X_STATUS_STARTED)\r
+    {\r
+        GH3X2X_WAIT_CHIP_WAKEUP();\r
+        GH3X2X_WriteReg(GH3X2X_OSC_THR_REG_ADDR, GH3X2X_LSI_CALI_THR_CNT_VAL);\r
+        GH3X2X_WriteReg(GH3X2X_OSC_CR_REG_ADDR, GH3X2X_LSI_CALI_CTRL_C_EN_VAL);\r
+        GH3X2X_DelayUs(GH3X2X_LSI_COR_CALI_DELAY_VAL);\r
+        if (GH3X2X_CHECK_BIT_SET(GH3X2X_ReadReg(GH3X2X_OSC_FLAG_REG_ADDR), GH3X2X_OSC_CALI_CODE_LOACKED))\r
+        {\r
+            usCaliVal = GH3X2X_ReadReg(GH3X2X_OSC32K_TUNE_REG_ADDR);\r
+            uchCalcVal = GH3X2X_GET_HIGH_BYTE_FROM_WORD(usCaliVal);\r
+            for (uchIndex = 0; uchIndex < GH3X2X_LSI_CALI_FINE_TUNE_MAX; uchIndex++)\r
+            {\r
+                usCaliVal = GH3X2X_MAKEUP_WORD(uchCalcVal, GH3X2X_GET_LOW_BYTE_FROM_WORD(usCaliVal));\r
+                GH3X2X_WriteReg(GH3X2X_OSC32K_TUNE_REG_ADDR, usCaliVal);\r
+                GH3X2X_WriteReg(GH3X2X_OSC_CR_REG_ADDR, GH3X2X_LSI_CALI_CTRL_F_EN_VAL);\r
+                GH3X2X_DelayUs(GH3X2X_LSI_FINE_CALI_DELAY_VAL);\r
+                sFreqErrVal = GH3X2X_ReadReg(GH3X2X_OSC_FREQ_ERR_UR_REG_ADDR);\r
+                if (sFreqErrVal > GH3X2X_LSI_CALI_ERR_MAX_VAL)\r
+                {\r
+                    sFreqErrVal = (GS16)(GH3X2X_LSI_CALI_ERR_FIXED_VAL - sFreqErrVal);\r
+                    uchMinVal = uchCalcVal;\r
+                }\r
+                else\r
+                {\r
+                    uchMaxVal = uchCalcVal;\r
+                }\r
+                uchCalcVal = ((GU16)uchMaxVal + (GU16)uchMinVal) / GH3X2X_LSI_CALI_FINE_DIV_NUM;\r
+                if (uchLastCalcVal == uchCalcVal)\r
+                {\r
+                    chRet = GH3X2X_RET_OK;\r
+                    if (sLastFreqErrVal < sFreqErrVal)\r
+                    {\r
+                        usCaliVal = GH3X2X_MAKEUP_WORD(uchMaxVal, GH3X2X_GET_LOW_BYTE_FROM_WORD(usCaliVal));\r
+                        GH3X2X_WriteReg(GH3X2X_OSC32K_TUNE_REG_ADDR, usCaliVal);\r
+                    }\r
+                    break;\r
+                }\r
+                uchLastCalcVal = uchCalcVal;\r
+                if (sLastFreqErrVal > sFreqErrVal)\r
+                {\r
+                    sLastFreqErrVal = sFreqErrVal;\r
+                }\r
+            } // end of for (uchIndex = 0; uchIndex < GH3X2X_LSI_CALI_FINE_TUNE_MAX; uchIndex++)\r
+        } // end of if (GH3X2X_CHECK_BIT_SET(GH3X2X_ReadReg(GH3X2X_OSC_FLAG_REG_ADDR), GH3X2X_OSC_CALI_CODE_LOACKED))\r
+        GH3X2X_DEBUG_LOG_PARAM("Lsi: 0x%.4x\r\n", GH3X2X_ReadReg(GH3X2X_OSC32K_TUNE_REG_ADDR));\r
+        GH3X2X_WriteReg(GH3X2X_OSC_CR_REG_ADDR, GH3X2X_OSC_CALI_CTRL_DIS_VAL);\r
+        GH3X2X_WAIT_CHIP_DSLP();\r
+    } // end of if (g_uchGh3x2xStatus < GH3X2X_STATUS_STARTED)\r
+    return chRet;\r
+}\r
+\r
+/**\r
+ * @fn     void GH3X2X_RegisterReadPinStatusFunc(GU8 (*pReadIntPinStatusFunc)(void),\r
+ *                                     GU8 (*pReadResetPinStatusFunc)(void),\r
+ *                                     GU8 (*pReadSpcsPinStatusFunc)(void),\r
+ *                                     GU8 (*pReadSpdoPinStatusFunc)(void))\r
+ *\r
+ * @brief  Register read pin status function\r
+ *\r
+ * @attention   Only use for debug, read gh3x2x some pin status can debug some hardware errors;\r
+ *              Pin status return should define as 1 [high level] or 0 [low level];\r
+ *\r
+ * @param[in]   pReadIntPinStatusFunc       pointer to read int pin staus function\r
+ * @param[in]   pReadResetPinStatusFunc     pointer to read reset pin staus function\r
+ * @param[in]   pReadSpcsPinStatusFunc      pointer to read spcs pin staus function\r
+ * @param[in]   pReadSpdoPinStatusFunc      pointer to read spdo pin staus function\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_RegisterReadPinStatusFunc(GU8 (*pReadIntPinStatusFunc)(void),\r
+                                      GU8 (*pReadResetPinStatusFunc)(void),\r
+                                      GU8 (*pReadSpcsPinStatusFunc)(void),\r
+                                      GU8 (*pReadSpdoPinStatusFunc)(void))\r
+{\r
+    g_pGh3x2xReadIntPinStatusFunc = pReadIntPinStatusFunc;\r
+    g_pGh3x2xReadResetPinStatusFunc = pReadResetPinStatusFunc;\r
+    g_pGh3x2xReadSpcsPinStatusFunc = pReadSpcsPinStatusFunc;\r
+    g_pGh3x2xReadSpdoPinStatusFunc = pReadSpdoPinStatusFunc;\r
+    GH3X2X_DEBUG_LOG_PARAM("%s\r\n", __FUNCTION__);\r
+}\r
+\r
+/**\r
+ * @fn     GCHAR *GH3X2X_GetDriverLibVersion(void)\r
+ *\r
+ * @brief  Get driver version\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  library version string\r
+ */\r
+GCHAR *GH3X2X_GetDriverLibVersion(void)\r
+{\r
+    return (GCHAR *)GH3X2X_VERSION_STRING;\r
+}\r
+\r
+/**\r
+ * @fn     void GH3X2X_SetMaxNumWhenReadFifo(GU16 usMaxNum)\r
+ *\r
+ * @brief  Set max number of rawdata read from fifo every time\r
+ *\r
+ * @attention   None.\r
+ *\r
+ * @param[in]   usMaxNum        max number of rawdata read from fifo\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_SetMaxNumWhenReadFifo(GU16 usMaxNum)\r
+{\r
+    if (usMaxNum <= GH3X2X_FIFO_DATA_BYTES_MAX_LEN)\r
+    {\r
+        g_usMaxNumReadFromFifo = (usMaxNum/4) * 4;\r
+    }    \r
+}\r
+\r
+\r
+/**\r
+ * @fn     GU16 GH3X2X_GetCurrentFifoWaterLine(void)\r
+ *\r
+ * @brief  get current fifo water line setting\r
+ *\r
+ * @attention   None.\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  fifo water line\r
+ *\r
+ * @return  None\r
+ */\r
+GU16 GH3X2X_GetCurrentFifoWaterLine(void)\r
+{\r
+    return g_usCurrentFiFoWaterLine;\r
+}\r
+\r
+\r
+\r
+const GU8 g_uchLedCurrentFullScal[4] = {25,50,100,200};\r
+\r
+\r
+\r
+\r
+/**\r
+ * @fn      GU8  Gh3x2x_GetLedCurrentFullScal(void)\r
+ \r
+ *\r
+ * @brief  \r
+ *\r
+ * @attention   None.\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  Drv 0/1Current fs (mA)\r
+ *\r
+ * @return  None\r
+ */\r
+\r
+void  GH3x2x_GetLedCurrentFullScal(GU8 *puchDrv0Fs, GU8 *puchDrv1Fs)\r
+{\r
+    (*puchDrv0Fs)= GH3X2X_ReadRegBitField(GH3X2X_LED_DRV_AD_REG_REG_ADDR,GH3X2X_DRV0_FULL_SCAL_CURRENT_LSB,GH3X2X_DRV0_FULL_SCAL_CURRENT_MSB);\r
+    (*puchDrv1Fs)= GH3X2X_ReadRegBitField(GH3X2X_LED_DRV_AD_REG_REG_ADDR,GH3X2X_DRV1_FULL_SCAL_CURRENT_LSB,GH3X2X_DRV1_FULL_SCAL_CURRENT_MSB);\r
+\r
+    \r
+    (*puchDrv0Fs) = g_uchLedCurrentFullScal[*puchDrv0Fs];\r
+    (*puchDrv1Fs) = g_uchLedCurrentFullScal[*puchDrv1Fs];\r
+\r
+}\r
+\r
+\r
+\r
+void GH3x2x_DisableHardwareAgc(void)\r
+{\r
+    for(GU8 uchSlotCnt = 0; uchSlotCnt < 8; uchSlotCnt ++)\r
+    {\r
+        GH3X2X_WriteRegBitField(GH3X2X_SLOT0_CTRL_3_REG_ADDR + GH3X2X_SLOT_CTRL_OFFSET*uchSlotCnt,GH3X2X_SLOT_AGC_EN_LSB,GH3X2X_SLOT_AGC_EN_MSB, 0);\r
+    }\r
+}\r
+\r
+\r
+void GH3x2x_GetBgLevel(GU8 *puchBglevel)\r
+{    \r
+    for(GU8 uchSlotCnt = 0; uchSlotCnt < 8; uchSlotCnt ++)\r
+    {\r
+        puchBglevel[uchSlotCnt] = GH3X2X_ReadRegBitField(GH3X2X_SLOT0_CTRL_3_REG_ADDR + GH3X2X_SLOT_CTRL_OFFSET*uchSlotCnt,GH3X2X_SLOT_BG_LEVEL_LSB,GH3X2X_SLOT_BG_LEVEL_MSB);\r
+    }\r
+}\r
+\r
+void GH3x2x_GetBgCancel(GU8 *puchBgCancel)\r
+{    \r
+    for(GU8 uchSlotCnt = 0; uchSlotCnt < 8; uchSlotCnt ++)\r
+    {\r
+        puchBgCancel[uchSlotCnt] = GH3X2X_ReadRegBitField(GH3X2X_SLOT0_CTRL_3_REG_ADDR + GH3X2X_SLOT_CTRL_OFFSET*uchSlotCnt,GH3X2X_SLOT_BG_CANCEL_LSB,GH3X2X_SLOT_BG_CANCEL_MSB);\r
+    }\r
+}\r
+\r
+\r
+\r
+void GH3x2x_SetIntTime(GU8 uchSlotNo, GU8 uchIntTimeIndex)\r
+{    \r
+    GH3X2X_WriteRegBitField(GH3X2X_SLOT0_CTRL_3_REG_ADDR + GH3X2X_SLOT_CTRL_OFFSET*uchSlotNo,GH3X2X_SLOT_ADC_INT_TIME_LSB,GH3X2X_SLOT_ADC_INT_TIME_MSB, uchIntTimeIndex);\r
+}\r
+\r
+void GH3x2x_SetSlotTime(GU8 uchSlotNo, GU16 usSlotTime)\r
+{    \r
+    GH3X2X_WriteReg(GH3X2X_RG_SLOT_TMR0_REG_ADDR + 2*uchSlotNo, usSlotTime);\r
+}\r
+\r
+\r
+void GH3x2x_SetSlotSampleRate(GU8 uchSlotNo, GU16 usSampleRate)\r
+{    \r
+    GU16 usDivReg;\r
+    if(usSampleRate > 1000)\r
+    {\r
+        usSampleRate = 1000;\r
+    }\r
+    if(usSampleRate < 5)\r
+    {\r
+        usSampleRate = 5;\r
+    }\r
+\r
+    usDivReg = (1000/usSampleRate) - 1;\r
+\r
+\r
+    GH3X2X_WriteRegBitField(GH3X2X_SLOT0_CTRL_0_REG_ADDR + GH3X2X_SLOT_CTRL_OFFSET*uchSlotNo,GH3X2X_SLOT_SR_LSB,GH3X2X_SLOT_SR_MSB, usDivReg);\r
+\r
+    \r
+    GH3X2X_DEBUG_LOG_PARAM("GH3x2x_SetSlotSampleRate: uchSlotNo = %d, usSampleRate = %d, usDivReg = %d \r\n",(int)uchSlotNo,(int)usSampleRate,(int)usDivReg);\r
+}\r
+\r
+\r
+\r
+\r
+\r
+const GU16 gusSlotTimeList[3][7] = {\r
+{26,    36,    46,    56,    95,    174,    331},\r
+{48,    67,    87,    107,    186,    343,    658},\r
+{69,    99,    128,    158,    276,    512,    985}\r
+};\r
+\r
+\r
+GU16 GH3x2x_CalSlotTime(GU8 uchBgLevel, GU8 uchBgCancel ,GU8 uchIntTimeIndex)\r
+{\r
+    GU16 usSlotTime;\r
+    if(uchBgLevel > 2)\r
+    {\r
+        uchBgLevel = 2;\r
+    }\r
+    usSlotTime = gusSlotTimeList[uchBgLevel][uchIntTimeIndex];\r
+    if(uchBgCancel > 0)\r
+    {\r
+        usSlotTime += 104;\r
+    }\r
+\r
+    usSlotTime += 80;  //fix pd remain problem\r
+\r
+    GH3X2X_DEBUG_LOG_PARAM("GH3x2x_CalSlotTime: bg level = %d, bg cancel = %d, IntTimeIndex = %d, TimeSlot = %d \r\n",(int)uchBgLevel,(int)uchBgCancel,(int)uchIntTimeIndex,(int)usSlotTime);\r
+\r
+    return usSlotTime;\r
+}\r
+\r
+GS8 g_chDrvECode = 0;\r
+\r
+void GH3X2X_SetDrvEcode(GS8 chECode)\r
+{\r
+    g_chDrvECode = chECode;\r
+}\r
+\r
+#if (0 == __CURRENT_ECODE_CALIBRATE__)\r
+GU16 GH3X2X_SetLedDrvCurrentByEcode(GU8 uchCurrent_mA, GU8 uchDrvNum, GS8 chECODE)\r
+{\r
+    GU8 uchDrFs[2] = {0};\r
+    GH3x2x_GetLedCurrentFullScal(&uchDrFs[0], &uchDrFs[1]);\r
+    GU16 usDrvReg = ((GU16)uchCurrent_mA) * 255 /uchDrFs[uchDrvNum];\r
+    return usDrvReg;\r
+}\r
+void GH3X2X_SetConfigDrvEcode(const STGh3x2xInitConfig *pstGh3x2xInitConfigParam){}\r
+#else\r
+GU16 GH3X2X_SetLedDrvCurrentByEcode(GU8 uchCurrent_mA, GU8 uchDrvNum, GS8 chECODE)\r
+{\r
+    GF32 fEr;\r
+    GF32 fY;\r
+    GU8  uchN;\r
+    GU16 usDrvCode;\r
+    GU16 usDrvScale;\r
+    \r
+    if(uchDrvNum == 0)\r
+    {\r
+        fY = 0.1;\r
+        usDrvScale = GH3X2X_ReadRegBitField(GH3X2X_LED_DRV_AD_REG_REG_ADDR,GH3X2X_DRV0_FULL_SCAL_CURRENT_LSB,GH3X2X_DRV0_FULL_SCAL_CURRENT_MSB);\r
+    }\r
+    else\r
+    {\r
+        fY = 0.01;\r
+        usDrvScale = GH3X2X_ReadRegBitField(GH3X2X_LED_DRV_AD_REG_REG_ADDR,GH3X2X_DRV1_FULL_SCAL_CURRENT_LSB,GH3X2X_DRV1_FULL_SCAL_CURRENT_MSB);\r
+        \r
+    }\r
+    uchN = 1 << (3 - usDrvScale);   \r
+\r
+    fEr = (GF32)((GF32)chECODE/256) + 1.0f;\r
+    usDrvCode = (GU16)(0.5f+((GF32)fEr*255*(GF32)uchN)/(0.225f/((GF32)uchCurrent_mA/1000) - fY));\r
+    \r
+    return usDrvCode;\r
+}\r
+\r
+void GH3X2X_SetConfigDrvEcode(const STGh3x2xInitConfig *pstGh3x2xInitConfigParam)\r
+{\r
+    if (pstGh3x2xInitConfigParam == GH3X2X_PTR_NULL)\r
+    {\r
+        return;\r
+    }\r
+    GU8 uchDr0Fs = 0;\r
+    GU8 uchDr1Fs = 0;\r
+    GH3x2x_GetLedCurrentFullScal(&uchDr0Fs, &uchDr1Fs);\r
+    for (GU16 usArrCnt = 0; usArrCnt < pstGh3x2xInitConfigParam->usConfigArrLen ; usArrCnt ++)\r
+    {\r
+        GU16 usRegData = pstGh3x2xInitConfigParam->pstRegConfigArr[usArrCnt].usRegData;\r
+        GU16 usRegAddr = pstGh3x2xInitConfigParam->pstRegConfigArr[usArrCnt].usRegAddr;\r
+        if ((pstGh3x2xInitConfigParam->pstRegConfigArr[usArrCnt].usRegAddr & 0xF000) == 0)\r
+        {\r
+            for (int uchSlotIndex = 0; uchSlotIndex < 8; uchSlotIndex++)\r
+            {\r
+                if ((pstGh3x2xInitConfigParam->pstRegConfigArr[usArrCnt].usRegAddr) == 0x011E + (uchSlotIndex * 0x001C) + (0 * 0x0002))\r
+                {\r
+                    GU8 uchCurrent = (GU8)((double)(usRegData&0xFF) * (double)uchDr0Fs / 255 + 0.5);\r
+                    GU16 usDrv0Reg = ((usRegData & 0xFF00) | GH3X2X_SetLedDrvCurrentByEcode(uchCurrent, 0, g_chDrvECode));\r
+                    GH3X2X_INFO_LOG_PARAM("[%s]:slot%d DRV0 addr=0x%04x CURvalue=0x%04x change2 0x%04x\n", __FUNCTION__, uchSlotIndex, usRegAddr, usRegData, usDrv0Reg);\r
+                    GH3X2X_WriteReg(pstGh3x2xInitConfigParam->pstRegConfigArr[usArrCnt].usRegAddr, usDrv0Reg);\r
+                    if (usDrv0Reg != GH3X2X_ReadReg(usRegAddr))\r
+                    {\r
+                        GH3X2X_INFO_LOG_PARAM("[%s]:reg verify error!!!\r\n", __FUNCTION__);\r
+                    }\r
+                }\r
+                else if ((pstGh3x2xInitConfigParam->pstRegConfigArr[usArrCnt].usRegAddr) == 0x011E + (uchSlotIndex * 0x001C) + (1 * 0x0002))\r
+                {\r
+                    GU8 uchCurrent = (GU8)((double)(usRegData&0xFF) * (double)uchDr1Fs / 255 + 0.5);\r
+                    GU16 usDrv1Reg = ((usRegData & 0xFF00) | GH3X2X_SetLedDrvCurrentByEcode(uchCurrent, 1, g_chDrvECode));\r
+                    GH3X2X_INFO_LOG_PARAM("[%s]:slot%d DRV1 addr=0x%04x CURvalue=0x%04x change2 0x%04x\n", __FUNCTION__, uchSlotIndex, usRegAddr, usRegData, usDrv1Reg);\r
+                    GH3X2X_WriteReg(pstGh3x2xInitConfigParam->pstRegConfigArr[usArrCnt].usRegAddr, usDrv1Reg);\r
+                    if (usDrv1Reg != GH3X2X_ReadReg(usRegAddr))\r
+                    {\r
+                        GH3X2X_INFO_LOG_PARAM("[%s]:reg verify error!!!\r\n", __FUNCTION__);\r
+                    }\r
+                }\r
+            }\r
+        }\r
+    }\r
+}\r
+\r
+#endif\r
+    \r
+\r
+\r
+/**\r
+ * @fn      void GH3x2x_ChangeSampleParmForEngineeringMode(GU32 unFunctionMode, STGh3x2xEngineeringModeSampleParam *pstSampleParaGroup , GU8 uchSampleParaGroupNum)\r
+ \r
+ *\r
+ * @brief  \r
+ *\r
+ * @attention   None.\r
+ *\r
+ * @param[in]   unFunctionMode: function group exp: GH3X2X_FUNCTION_ADT|GH3X2X_FUNCTION_HR\r
+ * @param[in]   pstSampleParaGroup   the pointer of engineering mode sample param group struct array base\r
+ * @param[in]   uchSampleParaGroupNum   engineering mode sample param group number\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3x2x_ChangeSampleParmForEngineeringMode(const STGh3x2xFrameInfo * const  pstGh3x2xFrameInfo[], GU32 unFunctionMode, STGh3x2xEngineeringModeSampleParam *pstSampleParaGroup , GU8 uchSampleParaGroupNum)\r
+{\r
+    GU32 unFunctionID;\r
+    GU8 uchFunctionCnt;\r
+    GU8 *puchChnlMap;\r
+    GU8 uchChnlNum;\r
+    GU8 uchDr0Fs;\r
+    GU8 uchDr1Fs;\r
+    GU8 puchBglevel[8];    //slot0 ~ slot1 bg level\r
+    GU8 puchBgCancel[8];   //slot0 ~ slot1 bg cancel\r
+\r
+    if(0 == pstSampleParaGroup) //is the point is invalid, do nothing\r
+    {\r
+        return ;\r
+    }\r
+\r
+    //read current full scale\r
+    GH3x2x_GetLedCurrentFullScal(&uchDr0Fs, &uchDr1Fs);\r
+\r
+    //read bg level\r
+    GH3x2x_GetBgLevel(puchBglevel);\r
+\r
+    //read bg cancel\r
+    GH3x2x_GetBgCancel(puchBgCancel);\r
+\r
+    //disable all hardware age slot\r
+    GH3x2x_DisableHardwareAgc();\r
+\r
+\r
+\r
+    //process every sample parm group\r
+    for(GU8 uchSampleParaGroupCnt = 0; uchSampleParaGroupCnt < uchSampleParaGroupNum; uchSampleParaGroupCnt ++)\r
+    {\r
+        STGh3x2xEngineeringModeSampleParam *pstTempSampleParam = pstSampleParaGroup + uchSampleParaGroupCnt;\r
+        unFunctionID = pstTempSampleParam->unFunctionID;\r
+        if(0 == unFunctionID)\r
+        {\r
+            continue;\r
+        }\r
+        puchChnlMap = 0;\r
+        uchChnlNum = 0;\r
+        \r
+        if(unFunctionID == (unFunctionMode&unFunctionID))   //unFunctionMode have cover unFunctionID\r
+        {\r
+            // get channl map and chnl num\r
+            for (uchFunctionCnt = 0 ; uchFunctionCnt < GH3X2X_FUNC_OFFSET_MAX ; uchFunctionCnt ++)\r
+            {\r
+                if(pstGh3x2xFrameInfo[uchFunctionCnt])\r
+                {\r
+                    if(unFunctionID == (((GU32)1) << uchFunctionCnt))\r
+                    {\r
+                        break;\r
+                    }\r
+                }\r
+            }\r
+            if(GH3X2X_FUNC_OFFSET_MAX == uchFunctionCnt)\r
+            {\r
+                GH3X2X_DEBUG_LOG_PARAM("ChangeSampleParmForEngineeringMode: can not find valid pstGh3x2xFrameInfo !!! unFunctionID = %d\r\n", (int)unFunctionID);\r
+                continue;\r
+            }\r
+            GH3X2X_DEBUG_LOG_PARAM("ChangeSampleParmForEngineeringMode: pstGh3x2xFrameInfo uchFunctionCnt = %d\r\n", (int)uchFunctionCnt);\r
+            puchChnlMap = pstGh3x2xFrameInfo[uchFunctionCnt]->pchChnlMap;\r
+            uchChnlNum = pstGh3x2xFrameInfo[uchFunctionCnt]->pstFunctionInfo->uchChnlNum;\r
+\r
+            if((0 != puchChnlMap)&&(0 != uchChnlNum)) //channel map and channel num is all valid\r
+            {\r
+                \r
+                GH3X2X_DEBUG_LOG_PARAM("ChangeSampleParmForEngineeringMode: ParaGroupCnt = %d, uchFunctionID = %d, uchChnlNum = %d\r\n", (int)uchSampleParaGroupCnt, (int)unFunctionID, (int)uchChnlNum);\r
+                for(GU8 uchChnlCnt = 0; uchChnlCnt < uchChnlNum; uchChnlCnt ++)\r
+                {\r
+                    GU8  uchTempSlotNo = GH3X2X_BYTE_RAWDATA_GET_SLOT_NUM(puchChnlMap[uchChnlCnt]);\r
+                    GU8  uchTempAdtNo = GH3X2X_BYTE_RAWDATA_GET_ADC_NUM(puchChnlMap[uchChnlCnt]);\r
+                    if(pstTempSampleParam->uchIntTimeChangeEn)\r
+                    {    \r
+                        GU16 usTimeSlot;\r
+                        GH3X2X_DEBUG_LOG_PARAM("ChangeSampleParm[int time]: need change int time. \r\n");\r
+                        usTimeSlot = GH3x2x_CalSlotTime(puchBglevel[uchTempSlotNo],puchBgCancel[uchTempSlotNo], pstTempSampleParam->uchIntTime);\r
+                        GH3x2x_SetIntTime(uchTempSlotNo,pstTempSampleParam->uchIntTime);\r
+                        GH3x2x_SetSlotTime(uchTempSlotNo,usTimeSlot);\r
+                    }\r
+                    if(pstTempSampleParam->uchSampleRateChangeEn)\r
+                    {    \r
+                        GH3X2X_DEBUG_LOG_PARAM("ChangeSampleParm[sample rate]\r\n");\r
+\r
+                        GH3x2x_SetSlotSampleRate(uchTempSlotNo,pstTempSampleParam->usSampleRate);\r
+                    }\r
+                    if(pstTempSampleParam->uchTiaGainChangeEn)\r
+                    {\r
+                        GH3X2X_SlotLedTiaGainConfig(uchTempSlotNo, uchTempAdtNo, pstTempSampleParam->uchTiaGain[uchChnlCnt]);\r
+                        GH3X2X_DEBUG_LOG_PARAM("ChangeSampleParm[tia gain]: uchSlotNo = %d, uchTempAdtNo = %d, TiaGain = %d \r\n",(int)uchTempSlotNo,(int)uchTempAdtNo,(int)pstTempSampleParam->uchTiaGain[uchChnlCnt]);\r
+                    }\r
+                    if(pstTempSampleParam->uchLedCurrentChangeEn)\r
+                    {    \r
+\r
+                        GU16 usDrv0Reg;\r
+                        \r
+                        GU16 usDrv1Reg;\r
+\r
+                        GH3X2X_DEBUG_LOG_PARAM("ChangeSampleParm[led current]\r\n");\r
+\r
+                        usDrv0Reg = GH3X2X_SetLedDrvCurrentByEcode(pstTempSampleParam->uchLedDrv0Current[uchChnlCnt], 0, (GS8)g_chDrvECode);\r
+                        //usDrv0Reg = ((GU16)pstTempSampleParam->uchLedDrv0Current[uchChnlCnt]) * 255 /uchDr0Fs;\r
+\r
+                        if(usDrv0Reg > 255)\r
+                        {\r
+                            usDrv0Reg = 255;\r
+                        }\r
+\r
+                        usDrv1Reg = GH3X2X_SetLedDrvCurrentByEcode(pstTempSampleParam->uchLedDrv1Current[uchChnlCnt], 1, (GS8)g_chDrvECode);\r
+                        //usDrv1Reg = ((GU16)pstTempSampleParam->uchLedDrv1Current[uchChnlCnt]) * 255 /uchDr1Fs;\r
+\r
+                        if(usDrv1Reg > 255)\r
+                        {\r
+                            usDrv1Reg = 255;\r
+                        }\r
+\r
+                        GH3X2X_SlotLedCurrentConfig(uchTempSlotNo, 0, usDrv0Reg);\r
+                        GH3X2X_SlotLedCurrentConfig(uchTempSlotNo, 1, usDrv1Reg);\r
+\r
+                        GH3X2X_DEBUG_LOG_PARAM("ChangeSampleParmForEngineeringMode: uchSlotNo = %d, uchTempAdtNo = %d, Drv0 = %d mA, Drv1 = %d mA \r\n",(int)uchTempSlotNo,(int)uchTempAdtNo,(int)pstTempSampleParam->uchLedDrv0Current[uchChnlCnt],(int)pstTempSampleParam->uchLedDrv1Current[uchChnlCnt]);\r
+                        GH3X2X_DEBUG_LOG_PARAM("ChangeSampleParmForEngineeringMode: Drv0_reg = %d, Drv1_reg = %d \r\n",(int)usDrv0Reg,(int)usDrv1Reg);\r
+                    }\r
+                \r
+                }\r
+\r
+\r
+            }\r
+            \r
+            \r
+            \r
+        }\r
+    }\r
+\r
+    \r
+}\r
+\r
+/**\r
+ * @fn       GU8 GH3x2x_GetActiveChipResetFlag(void)\r
+ \r
+ \r
+ *\r
+ * @brief  \r
+ *\r
+ * @attention   None.\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  ActiveChipResetFlag  1: user have done chip reset(soft reset and hardwear reset) actively    gh3x2x_init will clear it \r
+ *\r
+ * @return  None\r
+ */\r
+GU8 GH3x2x_GetActiveChipResetFlag(void)\r
+{\r
+    return g_uchActiveChipResetFlag;\r
+}\r
+\r
+\r
+/**\r
+ * @fn       GU8 GH3x2x_GetChipResetRecoveringFlag(void)\r
+ \r
+ \r
+ *\r
+ * @brief  \r
+ *\r
+ * @attention   None.\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  chip reset recovering flag  0: is not in chip reset recovering flag  1: is in chip reset recovering\r
+ *\r
+ * @return  None\r
+ */\r
+GU8 GH3x2x_GetChipResetRecoveringFlag(void)\r
+{\r
+    return g_uchChipResetRecoveringFlag;\r
+}\r
+\r
+\r
+\r
+/**\r
+ * @fn       GU8 GH3x2x_SetChipResetRecoveringFlag(void)\r
+ \r
+ \r
+ *\r
+ * @brief  \r
+ *\r
+ * @attention   None.\r
+ *\r
+ * @param[in]   chip reset recovering flag  0: is not in chip reset recovering flag  1: is in chip reset recovering\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3x2x_SetChipResetRecoveringFlag(GU8 uchChipResetRecoeringFlag)\r
+{\r
+    g_uchChipResetRecoveringFlag = uchChipResetRecoeringFlag;\r
+}\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+void GH3x2xCreatTagArray(GU8 *puchTagArray, GU16 usArrayLen,GU32 *unCompeletMask, const STGh3x2xFrameInfo * const pstFrameInfo)\r
+{\r
+    GU8  uchChnlNum;\r
+    GU8 *puchChnlMap;\r
+    \r
+    uchChnlNum = pstFrameInfo->pstFunctionInfo->uchChnlNum; \r
+    puchChnlMap = pstFrameInfo->pchChnlMap;\r
+\r
+    //create tag array\r
+    GH3X2X_Memset(puchTagArray,0xFF,usArrayLen);\r
+    \r
+    for(GU8 uchChnlCnt = 0; uchChnlCnt < uchChnlNum; uchChnlCnt ++)\r
+    {\r
+        GU8 uchTag;\r
+        uchTag = puchChnlMap[uchChnlCnt] >> 3;\r
+        puchTagArray[uchTag] = uchChnlCnt;\r
+    }\r
+    //crete compelet mask\r
+    (*unCompeletMask) = ((((long long)1) << uchChnlNum) - 1)&pstFrameInfo->pstFunctionInfo->unChnlEnForUserSetting;\r
+}\r
+\r
+\r
+\r
+\r
+\r
+\r
+GU16 GH3x2xGetFrameNum(GU8 *puchRawdataBuf, GU16 usRawDataByteLen, const STGh3x2xFrameInfo * const pstFrameInfo)\r
+{\r
+    GU32 unTempIncompeletFlag;\r
+    GU8  puchTagArray[32];\r
+    GU32 unCompeletMask;\r
+    GU16 usFrameNum = 0;\r
+    \r
+    \r
+    unTempIncompeletFlag = *(pstFrameInfo->punIncompleteChnlMapBit);\r
+\r
+    GH3x2xCreatTagArray(puchTagArray, 32,&unCompeletMask, pstFrameInfo);\r
+\r
+    //set incomplete flag\r
+    for (GU16 usSearchStartPosi = 0; usSearchStartPosi < usRawDataByteLen; usSearchStartPosi += GH3X2X_FIFO_RAWDATA_SIZE)\r
+    {\r
+        GU8 uchTag;\r
+        GU8 uchChnlId;\r
+        uchTag = puchRawdataBuf[usSearchStartPosi] >> 3;\r
+        uchChnlId =  puchTagArray[uchTag];\r
+        if(0xFF != uchChnlId)\r
+        {        \r
+            unTempIncompeletFlag |= (1 << uchChnlId);\r
+        }\r
+\r
+        if(unCompeletMask == (unCompeletMask&unTempIncompeletFlag))  //got one frame\r
+        {\r
+            unTempIncompeletFlag = 0;\r
+            usFrameNum ++;\r
+        }\r
+        \r
+    }\r
+\r
+    return usFrameNum;\r
+    \r
+}\r
+\r
+\r
+float GH3x2xCalGsensorStep(GU16 usGsDataNum, GU16 usFrameNum)\r
+{\r
+    float fGsensorStep = 0;\r
+    \r
+    if ((usFrameNum > 0) && (usGsDataNum > 0)) // calc gs index\r
+    {\r
+        fGsensorStep = ((GF32)(usGsDataNum)) / (usFrameNum);\r
+    }\r
+    \r
+    return  fGsensorStep;\r
+\r
+    \r
+}\r
+\r
+void GH3x2xSendAllVersion(void)\r
+{\r
+    GU8 uchPacketPayloadArr[240] = {0};\r
+    GU8 uchCmdArr[7 + GH3X2X_FUNC_OFFSET_MAX] = {(0x01),(0x0B),(0x0C),(0x0E),(0x0F),(0x10),(0x11)};\r
+    GU8 uchCmdLen = 7;\r
+    \r
+    if (g_uchAlgoEnableFlag)\r
+    {\r
+        for (int nCnt = 0 ; nCnt < GH3X2X_FUNC_OFFSET_MAX ; nCnt++)\r
+        {\r
+            uchCmdArr[7 + nCnt] = 0x12 + nCnt;\r
+        }\r
+        uchCmdLen = 7 + GH3X2X_FUNC_OFFSET_MAX;\r
+    }\r
+    \r
+    for (GU8 uchOffset = 0 ; uchOffset < uchCmdLen ; uchOffset ++)\r
+    {\r
+        GU8 uchGetVersionType = UPROTOCOL_GET_VER_TYPE_ALGO_VER + uchOffset;\r
+        GCHAR pszVersionString[150] = {0};\r
+        GH3X2X_GetVersion(uchCmdArr[uchOffset], pszVersionString);\r
+        GU8 uchVersionStringLen = (GU8)GH3X2X_Strlen(pszVersionString);\r
+        uchPacketPayloadArr[UPROTOCOL_GET_VER_TYPE_INDEX + 4] = uchGetVersionType;\r
+        uchPacketPayloadArr[UPROTOCOL_GET_VER_STRING_LEN_INDEX + 4] = uchVersionStringLen;\r
+        GH3X2X_Memcpy((GCHAR *)&uchPacketPayloadArr[UPROTOCOL_GET_VER_STRING_INDEX + 4], pszVersionString, uchVersionStringLen);\r
+        GU16 usRespondLen = GH3X2X_UprotocolPacketFormat(GH3X2X_UPROTOCOL_CMD_BP_DATA_TRANS, uchPacketPayloadArr, &uchPacketPayloadArr[4], uchVersionStringLen + 2);\r
+        Gh3x2xDemoSendProtocolData(uchPacketPayloadArr,usRespondLen);\r
+    }\r
+}\r
+\r
+\r
+GU8 Gh3x2xFunctionID2Offset(GU32 unFunctionID)\r
+{\r
+    for(GU8 uchOffset = 0; uchOffset < 32; uchOffset ++)\r
+    {\r
+        if(unFunctionID == (((GU32)1) << uchOffset))\r
+        {\r
+            return uchOffset;\r
+        }\r
+    }\r
+    return 0;\r
+}\r
+\r
+void Gh3x2xFunctionInfoForUserInit(void)\r
+{\r
+    for(GU8 uchFuncitonCnt = 0; uchFuncitonCnt < GH3X2X_FUNC_OFFSET_MAX; uchFuncitonCnt ++)\r
+    {\r
+        if(g_pstGh3x2xFrameInfo[uchFuncitonCnt])\r
+        {\r
+            g_pstGh3x2xFrameInfo[uchFuncitonCnt] -> pstFunctionInfo -> usSampleRateForUserSetting = 0;\r
+            g_pstGh3x2xFrameInfo[uchFuncitonCnt] -> pstFunctionInfo -> unChnlEnForUserSetting = 0xFFFFFFFF;\r
+        }\r
+    }\r
+}\r
+\r
+void GH3x2xHandleFrameData(const STGh3x2xFrameInfo * const pstFrameInfo, GU32 *punTempIncompeletFlag,\r
+                                GU32 *punFunctionID, GU8 uchChnlNum, GU8 *puchRawdataBuf, GU32 *punFrameRawdata,\r
+                                GU8 *puchTag, GS16 *pusGsValueArr, float fGsensorIndex,\r
+                                STCapRawdata* pstCapValueArr,float fCapIndex,STTempRawdata* pstTempValueArr,float fTempIndex)\r
+\r
+{\r
+    GU32 unTempIncompeletFlag = *punTempIncompeletFlag;\r
+    GU8 uchTag = *puchTag;\r
+    GU32 unFunctionID = *punFunctionID;\r
+    GU8  uchGyroEnable = g_uchGyroEnable;\r
+\r
+    GH3X2X_DEBUG_LOG_PARAM("[%s]got one frame,funcID = %d\r\n",__FUNCTION__,(int)unFunctionID);\r
+    unTempIncompeletFlag = 0;\r
+    GH3X2X_Memset((GU8*)(pstFrameInfo->punFrameFlag), 0, GH3X2X_FRAME_FLAG_NUM*4);       //clear flag\r
+    GH3X2X_Memset((GU8*)(pstFrameInfo ->pstAlgoResult), 0, sizeof(STGh3x2xAlgoResult)); //clear result\r
+    GH3X2X_Memset((GU8*)(pstFrameInfo ->punFrameAgcInfo), 0, uchChnlNum * 4);            //clear agc info\r
+\r
+    for(GU8 uchChnlCnt = 0; uchChnlCnt < uchChnlNum; uchChnlCnt ++)\r
+    {\r
+        GU32 unRawdataAndTag;\r
+        unRawdataAndTag = pstFrameInfo->punIncompleteRawdata[uchChnlCnt];\r
+        uchTag = GH3X2X_DWORD_RAWDATA_GET_SLOT_ADC_NUM(unRawdataAndTag);\r
+    \r
+        //rawdata\r
+        punFrameRawdata[uchChnlCnt] = unRawdataAndTag&0x00FFFFFF;\r
+\r
+        //flag0 flag1 \r
+        pstFrameInfo->punFrameFlag[0] |= (((GU32)GH3X2X_RAWDATA_GET_ADJ_FLAG0(unRawdataAndTag) << uchChnlCnt));\r
+        pstFrameInfo->punFrameFlag[1] |= (((GU32)GH3X2X_RAWDATA_GET_ADJ_FLAG1(unRawdataAndTag) << uchChnlCnt));\r
+    \r
+        //flag2 bit 0    fast recovery flag\r
+        if ((GH3X2X_FUNCTION_ECG == unFunctionID)||(GH3X2X_FUNCTION_PWTT == unFunctionID))\r
+        {\r
+            if(0 == uchChnlCnt)\r
+            {\r
+                if(GH3X2X_RAWDATA_GET_FAST_RECOVERY_FLAG(unRawdataAndTag))\r
+                {\r
+                    pstFrameInfo->punFrameFlag[2] |= 0x01;\r
+                }\r
+            }\r
+        }\r
+\r
+                #if GH3X2X_DIVIDE_ZERO_FLAG_UPLODE_EN\r
+                //flag4\r
+                if(g_uchChipDivZeroFlag)\r
+                {\r
+                    pstFrameInfo->punFrameFlag[4] |= 0x01;\r
+                    GH3X2X_ClearDivZeroFlag();\r
+                }\r
+                #endif \r
+                \r
+        // agc (gain/drv0/drv1)\r
+                pstFrameInfo->punFrameAgcInfo[uchChnlCnt] |= g_pstGh3x2xAgcInfo->uchTiaGainRecord[uchTag] & 0xF;    //gain\r
+        pstFrameInfo->punFrameAgcInfo[uchChnlCnt] |= ((GU32)g_pstGh3x2xAgcInfo->uchDrvCurrentRecord[(GU8)(uchTag/4)]) << 8; // drv 0/1 current\r
+                                \r
+    }\r
+\r
+    //g-sensor\r
+    for( int i=0;i<3;i++)\r
+    {\r
+        if(fGsensorIndex != (GU16)fGsensorIndex)\r
+        {\r
+            pstFrameInfo->pusFrameGsensordata[i] = pusGsValueArr[(GU16)fGsensorIndex*(3+3*uchGyroEnable)+i]*(1-fGsensorIndex+(GU16)fGsensorIndex) + pusGsValueArr[((GU16)fGsensorIndex+1)*(3+3*uchGyroEnable)+i]*(fGsensorIndex-(GU16)fGsensorIndex);\r
+        }\r
+        else\r
+        {\r
+            pstFrameInfo->pusFrameGsensordata[i] = pusGsValueArr[(GU16)fGsensorIndex*(3+3*uchGyroEnable)+i];\r
+        }\r
+    }\r
+    if(uchGyroEnable)\r
+    {\r
+        for( int i=0;i<3;i++)\r
+        {\r
+            if(fGsensorIndex != (GU16)fGsensorIndex)\r
+            {\r
+                pstFrameInfo->pusFrameGsensordata[i+3] = pusGsValueArr[(GU16)fGsensorIndex*(3+3*uchGyroEnable)+i+3]*(1-fGsensorIndex+(GU16)fGsensorIndex) + pusGsValueArr[((GU16)fGsensorIndex+1)*(3+3*uchGyroEnable)+i+3]*(fGsensorIndex-(GU16)fGsensorIndex);\r
+            }\r
+            else\r
+            {\r
+                pstFrameInfo->pusFrameGsensordata[i+3] = pusGsValueArr[(GU16)fGsensorIndex*(3+3*uchGyroEnable)+i+3];\r
+            }\r
+        }\r
+    }\r
+    //cap and temp\r
+    if(GH3X2X_GetCapEnableFlag())\r
+    {\r
+        GH3X2X_Memcpy(pstFrameInfo->pstFrameCapdata,&pstCapValueArr[(GU16)fCapIndex],sizeof(STCapRawdata));\r
+    }\r
+    if(GH3X2X_GetTempEnableFlag())\r
+    {\r
+        GH3X2X_Memcpy(pstFrameInfo->pstFrameTempdata,&pstTempValueArr[(GU16)fTempIndex],sizeof(STTempRawdata));\r
+    }\r
+\r
+    //flag 2 bit1  first frame flag\r
+\r
+    Gh3x2xSetFrameFlag2(pstFrameInfo);\r
+    /*\r
+    pstFrameInfo->punFrameFlag[2] &= (~(((GU32)1) << 1));\r
+    if(0 == (*(pstFrameInfo->punFrameCnt)))\r
+    {\r
+        pstFrameInfo->punFrameFlag[2] |= 0x02;\r
+    }\r
+    */\r
+    if(GH3X2X_FUNCTION_SOFT_ADT_IR == unFunctionID)\r
+    {\r
+        pstFrameInfo->punFrameFlag[2] |= ((GU32)1)<<4;\r
+    }\r
+\r
+    GH3X2X_DEBUG_LOG_PARAM("[GetFrameData] function id: 0x%X,  rawdata0 = %d, rawdata1 = %d\r\n",(int)pstFrameInfo->unFunctionID, (int)(pstFrameInfo->punFrameRawdata[0]), (int)(pstFrameInfo->punFrameRawdata[1]));\r
+    \r
+    GH3X2X_DEBUG_LOG_PARAM("[GetFrameData] TimeStamp = %d\r\n",(int)(*(pstFrameInfo->punFrameCnt)));\r
+    \r
+    \r
+    //call algo 2-level interface\r
+    unFunctionID = pstFrameInfo->unFunctionID;\r
+    pstFrameInfo->pstAlgoResult->uchUpdateFlag = 0;\r
+    \r
+    //get algo io data hook\r
+    HOOK_FUNC_CALL(g_pGh3x2xGetIoStructInfoHookFunc, (pstFrameInfo));\r
+\r
+    SET_VAL_VIA_PTR(punFunctionID, unFunctionID);\r
+    SET_VAL_VIA_PTR(puchTag, uchTag);\r
+    SET_VAL_VIA_PTR(punTempIncompeletFlag, unTempIncompeletFlag);\r
+}\r
+\r
+void GH3x2xGetFrameDataAndProcess(GU8 *puchRawdataBuf, GU16 usRawDataByteLen,\r
+                                        GS16 *pusGsValueArr, GU16 usGsDataNum,STCapRawdata* pstCapValueArr,GU16 usCapDataNum,STTempRawdata* pstTempValueArr,GU16 usTempDataNum,\r
+                                        const STGh3x2xFrameInfo * const pstFrameInfo, float fGensorStep, float fCapStep, float fTempStep, GU16 usFrameNum)\r
+{\r
+    GU32 unTempIncompeletFlag;\r
+    GU8  puchTagArray[32];\r
+    GU8  uchChnlNum;\r
+    GU32 unCompeletMask;\r
+    GU32 *punFrameRawdata;\r
+    float fGsensorIndex = 0;\r
+    float fCapIndex = 0;\r
+    float fTempIndex = 0;\r
+    GU32 unFunctionID;\r
+    GU16 usFrameCnt = 0;\r
+\r
+    unTempIncompeletFlag = *(pstFrameInfo->punIncompleteChnlMapBit);\r
+    uchChnlNum = pstFrameInfo->pstFunctionInfo->uchChnlNum; \r
+    punFrameRawdata = pstFrameInfo->punFrameRawdata;\r
+    unFunctionID = pstFrameInfo->unFunctionID;\r
+\r
+    GH3x2xCreatTagArray(puchTagArray, 32, &unCompeletMask, pstFrameInfo);\r
+\r
+    //set incomplete flag\r
+    for (GU16 usSearchStartPosi = 0; usSearchStartPosi < usRawDataByteLen; usSearchStartPosi += GH3X2X_FIFO_RAWDATA_SIZE)\r
+    {\r
+        GU8 uchTag;\r
+        GU8 uchChnlId;\r
+        uchTag = puchRawdataBuf[usSearchStartPosi] >> 3;\r
+        uchChnlId =  puchTagArray[uchTag];\r
+        if(0xFF != uchChnlId)\r
+        {        \r
+            GU32 unRawdataAndTag;                \r
+            unTempIncompeletFlag |= (1 << uchChnlId);\r
+            unRawdataAndTag = GH3X2X_MAKEUP_DWORD(puchRawdataBuf[usSearchStartPosi],\r
+                                                                    puchRawdataBuf[usSearchStartPosi + 1],\r
+                                                                    puchRawdataBuf[usSearchStartPosi + 2],\r
+                                                                    puchRawdataBuf[usSearchStartPosi + 3]);\r
+            //store incomplete rawdata \r
+            pstFrameInfo->punIncompleteRawdata[uchChnlId] = unRawdataAndTag;\r
+            \r
+        }\r
+\r
+        if(unCompeletMask == (unCompeletMask&unTempIncompeletFlag))  //got one frame\r
+        {\r
+            if((0 == pstFrameInfo->pstDownSampleInfo->uchDownSampleFactor)||(pstFrameInfo->pstDownSampleInfo->uchDownSampleFactor == pstFrameInfo->pstDownSampleInfo->uchDownSampleCnt))\r
+            {\r
+                GH3x2xHandleFrameData(pstFrameInfo, &unTempIncompeletFlag,\r
+                                    &unFunctionID, uchChnlNum, puchRawdataBuf, punFrameRawdata,\r
+                                    &uchTag, pusGsValueArr, fGsensorIndex,\r
+                                    pstCapValueArr,fCapIndex,pstTempValueArr,fTempIndex);\r
+\r
+                //send BLE package\r
+                            #if (__SUPPORT_ZIP_PROTOCOL__)\r
+                Gh2x2xUploadZipDataToMaster(pstFrameInfo, usFrameCnt, usFrameNum, puchTagArray);\r
+                            #else\r
+                Gh2x2xUploadDataToMaster(pstFrameInfo, usFrameCnt, usFrameNum, puchTagArray);\r
+                            #endif \r
+                // timestamp\r
+                (*(pstFrameInfo->punFrameCnt)) ++;\r
+                // bak last gain\r
+                for(GU8 uchChnlCnt = 0; uchChnlCnt < uchChnlNum; uchChnlCnt ++)\r
+                {\r
+                    pstFrameInfo ->puchFrameLastGain[uchChnlCnt] = ((pstFrameInfo->punFrameAgcInfo[uchChnlCnt]) & 0x0000000F);\r
+                }\r
+                \r
+\r
+                usFrameCnt ++;\r
+            }\r
+            unTempIncompeletFlag = 0;\r
+            if(pstFrameInfo->pstDownSampleInfo->uchDownSampleFactor)\r
+            {\r
+                if(pstFrameInfo->pstDownSampleInfo->uchDownSampleFactor <= pstFrameInfo->pstDownSampleInfo->uchDownSampleCnt)\r
+                {\r
+                    pstFrameInfo->pstDownSampleInfo->uchDownSampleCnt = 0;\r
+                }\r
+                else\r
+                {\r
+                    pstFrameInfo->pstDownSampleInfo->uchDownSampleCnt ++;\r
+                }\r
+            }\r
+\r
+            //calculate next fGsensorIndex\r
+            fGsensorIndex += fGensorStep;\r
+            fCapIndex  += fCapStep;\r
+            fTempIndex  += fTempStep;\r
+        }\r
+    }\r
+\r
+    //save IncompeletFlag\r
+    *(pstFrameInfo->punIncompleteChnlMapBit) = unTempIncompeletFlag;\r
+}\r
+\r
+void GH3x2xFunctionProcess(GU8 *puchRawdataBuf, GU16 usRawDataByteLen, GS16 *pusGsValueArr, GU16 usGsDataNum, \r
+                        STCapRawdata* pstCapValueArr,GU16 usCapDataNum,STTempRawdata* pstTempValueArr,GU16 usTempDataNum,\r
+                        const STGh3x2xFrameInfo * const pstFrameInfo)\r
+{\r
+    GU16 usFrameNum;\r
+    float fGsensorStep;\r
+    float fCapStep;\r
+    float fTempStep;\r
+\r
+    if(0 == pstFrameInfo)\r
+    {\r
+        return ;\r
+    }\r
+\r
+    /*****  check feature value  *********/\r
+    if(GH3X2X_CheckRawdataBuf(puchRawdataBuf, usRawDataByteLen) || pstFrameInfo->pstFunctionInfo->uchChnlNum == 0)\r
+    {\r
+        return;\r
+    }\r
+        \r
+    /***  cal how many frames in this fifo  ***/\r
+    usFrameNum = GH3x2xGetFrameNum(puchRawdataBuf, usRawDataByteLen, pstFrameInfo);\r
+\r
+    /***  cal g-sensor step ***/\r
+    fGsensorStep = GH3x2xCalGsensorStep(usGsDataNum, usFrameNum);\r
+    fCapStep     = GH3x2xCalGsensorStep(usCapDataNum, usFrameNum);\r
+    fTempStep    = GH3x2xCalGsensorStep(usTempDataNum, usFrameNum);\r
+    \r
+    GH3X2X_DEBUG_LOG_PARAM("[GetFrameNum]FunctionID: %d FrameNum: %d, GsensorStep: %.3f\r\n",(int)pstFrameInfo->unFunctionID, usFrameNum, fGsensorStep);\r
+\r
+    /***  get one frame data and process***/\r
+    GH3x2xGetFrameDataAndProcess(puchRawdataBuf,usRawDataByteLen,pusGsValueArr,usGsDataNum,pstCapValueArr,usCapDataNum,pstTempValueArr,usTempDataNum,\r
+                                            pstFrameInfo,fGsensorStep,fCapStep,fTempStep,usFrameNum);\r
+    \r
+\r
+}\r
+\r
+\r
+void GH3X2X_ZipmodeInit(void)\r
+{\r
+    g_uchOddEvenChangeFlag = 1;\r
+}\r
+\r
+GS8 GH3X2X_FunctionStart(const STGh3x2xFrameInfo * const pstFrameInfo)\r
+{\r
+    GS8 chRet = GH3X2X_RET_OK;\r
+    GU32 unFunctionID;\r
+    if(0 == pstFrameInfo)\r
+    {\r
+        return chRet;\r
+    }\r
+\r
+    GH3X2X_ZipmodeInit();\r
+\r
+    unFunctionID = pstFrameInfo->unFunctionID;\r
+\r
+    GH3x2xCalFunctionSlotBit(pstFrameInfo);\r
+\r
+    \r
+    \r
+    /* if all func off, start sampling */\r
+    if (GH3X2X_NO_FUNCTION == g_unFuncStartedBitmap)\r
+    {\r
+        chRet = GH3X2X_StartSampling();\r
+        GH3X2X_DEBUG_LOG_PARAM("[FunctionStart] function id: 0x%X, start result: %d\r\n",(int)pstFrameInfo->unFunctionID, chRet);\r
+        GH3X2X_RET_ERROR_CHECK_E(chRet, GH3X2X_RET_NO_INITED_ERROR);\r
+    }\r
+\r
+    \r
+        #if GH3X2X_ALGORITHM_ECG_SUPPORT && __FUNC_TYPE_ECG_ENABLE__\r
+    if (GH3X2X_FUNCTION_ECG == unFunctionID)\r
+    {\r
+        GH3X2X_EcgSampleHookHandle(ECG_SAMPLE_EVENT_TYPE_SAMPLE, ECG_SAMPLE_EVENT_INFO_SAMPLE_START);  //G202008231001 wanpeng\r
+        GH3X2X_LeadOffDetectInit();\r
+        GH3X2X_ECGResampleConfig(g_pstGh3x2xFrameInfo[GH3X2X_FUNC_OFFSET_ECG]->pstFunctionInfo->usSampleRate);\r
+        //GH3X2X_ECGResampleConfig(250);\r
+        GH3X2X_DEBUG_LOG_PARAM("[FunctionStart] sample rate: %d\r\n",(int)g_pstGh3x2xFrameInfo[GH3X2X_FUNC_OFFSET_ECG]->pstFunctionInfo->usSampleRate);\r
+    }\r
+        #endif\r
+\r
+    #if __SUPPORT_PPG_DOWNSAMP__\r
+    if(g_uchPPGDownSampleChnlNumLimit>0)\r
+    {\r
+        if (GH3X2X_FUNCTION_HR == unFunctionID)\r
+        {\r
+            GH3X2X_PPGResampleConfig(g_pstGh3x2xFrameInfo[GH3X2X_FUNC_OFFSET_HR]->pstFunctionInfo->usSampleRate);\r
+            GH3X2X_DEBUG_LOG_PARAM("[FunctionStart] sample rate: %d\r\n",(int)g_pstGh3x2xFrameInfo[GH3X2X_FUNC_OFFSET_HR]->pstFunctionInfo->usSampleRate);\r
+        }\r
+\r
+        else if (GH3X2X_FUNCTION_SPO2 == unFunctionID)\r
+        {\r
+            GH3X2X_PPGResampleConfig(g_pstGh3x2xFrameInfo[GH3X2X_FUNC_OFFSET_SPO2]->pstFunctionInfo->usSampleRate);\r
+            GH3X2X_DEBUG_LOG_PARAM("[FunctionStart] sample rate: %d\r\n",(int)g_pstGh3x2xFrameInfo[GH3X2X_FUNC_OFFSET_SPO2]->pstFunctionInfo->usSampleRate);\r
+        }\r
+        else if (GH3X2X_FUNCTION_SOFT_ADT_GREEN == unFunctionID)\r
+        {\r
+            GH3X2X_PPGResampleConfig(g_pstGh3x2xFrameInfo[GH3X2X_FUNC_OFFSET_SOFT_ADT_GREEN]->pstFunctionInfo->usSampleRate);\r
+            GH3X2X_DEBUG_LOG_PARAM("[FunctionStart] sample rate: %d\r\n",(int)g_pstGh3x2xFrameInfo[GH3X2X_FUNC_OFFSET_SOFT_ADT_GREEN]->pstFunctionInfo->usSampleRate);\r
+        }\r
+        else if (GH3X2X_FUNCTION_SOFT_ADT_IR == unFunctionID)\r
+        {\r
+            GH3X2X_PPGResampleConfig(g_pstGh3x2xFrameInfo[GH3X2X_FUNC_OFFSET_SOFT_ADT_IR]->pstFunctionInfo->usSampleRate);\r
+            GH3X2X_DEBUG_LOG_PARAM("[FunctionStart] sample rate: %d\r\n",(int)g_pstGh3x2xFrameInfo[GH3X2X_FUNC_OFFSET_SOFT_ADT_IR]->pstFunctionInfo->usSampleRate);\r
+        }\r
+    }\r
+    #endif\r
+\r
+    if (GH3X2X_FUNCTION_ADT == unFunctionID)\r
+    {\r
+        #if __FUNC_TYPE_ECG_ENABLE__\r
+        GH3X2X_LeadDetEnInHardAdt(1);\r
+        #endif\r
+    }\r
+\r
+    /* set started bit */\r
+    g_unFuncStartedBitmap |= unFunctionID;\r
+\r
+    /* clear incompelet flag */\r
+    (*(pstFrameInfo->punIncompleteChnlMapBit)) = 0;\r
+\r
+    /* clear timestamp */\r
+    (*(pstFrameInfo->punFrameCnt)) = 0;\r
+\r
+    /* set last gain */\r
+    GH3X2X_Memset(pstFrameInfo->puchFrameLastGain, 0xFF, pstFrameInfo->pstFunctionInfo->uchChnlNum);\r
+    \r
+    return chRet;\r
+}\r
+\r
+GS8 GH3X2X_FunctionStop(const STGh3x2xFrameInfo * const pstFrameInfo)\r
+{\r
+    GS8 chRet = GH3X2X_RET_OK;\r
+    GU32 unFunctionID;\r
+    if(0 == pstFrameInfo)\r
+    {\r
+        return chRet;\r
+    }\r
+    \r
+    unFunctionID = pstFrameInfo->unFunctionID;\r
+    GH3x2xCalFunctionSlotBit(pstFrameInfo);\r
+    \r
+    /* clear started bit */\r
+    g_unFuncStartedBitmap &= (~unFunctionID);\r
+\r
+    /* set result flag */\r
+    if (pstFrameInfo->pstAlgoRecordResult != GH3X2X_PTR_NULL)\r
+    {\r
+        pstFrameInfo->pstAlgoRecordResult->uchUpdateFlag = 0;\r
+        pstFrameInfo->pstAlgoRecordResult->usResultBit = 0;\r
+    }\r
+\r
+    /* if all func off, stop sampling */\r
+    if (GH3X2X_NO_FUNCTION == g_unFuncStartedBitmap)\r
+    {\r
+        chRet = GH3X2X_StopSampling();\r
+        GH3X2X_DEBUG_LOG_PARAM("[FunctionStop] function id: 0x%X, start result: %d\r\n",(int)pstFrameInfo->unFunctionID, chRet);\r
+        GH3X2X_RET_ERROR_CHECK(chRet);\r
+\r
+        /* fixed fifo watermark thr */\r
+        //GH3X2X_FIXED_FIFO_WATERMARK_THR();\r
+    }\r
+\r
+    return chRet;\r
+}\r
+\r
+GU32 GH3X2X_GetFuncStartedBitmap(void)\r
+{\r
+    return g_unFuncStartedBitmap;\r
+}\r
+\r
+GU8* GH3x2xGetFunctionChnlMap(const STGh3x2xFrameInfo * const pstFrameInfo)\r
+{\r
+    if(0 == pstFrameInfo)\r
+    {\r
+        return 0;\r
+    }\r
+    else\r
+    {        \r
+        return pstFrameInfo->pchChnlMap;\r
+    }\r
+}\r
+\r
+void GH3x2xSetFunctionChnlNum(const STGh3x2xFrameInfo * const pstFrameInfo, GU8 uchChnlNum)\r
+{\r
+    GU8 uchChnlLimit;\r
+    if(pstFrameInfo)\r
+    {\r
+        uchChnlLimit = pstFrameInfo->uchFuntionChnlLimit;\r
+        if(uchChnlNum > uchChnlLimit)\r
+        {\r
+            uchChnlNum = uchChnlLimit;\r
+        }\r
+        pstFrameInfo ->pstFunctionInfo->uchChnlNum = uchChnlNum;\r
+        if (uchChnlNum > 0)\r
+        {\r
+            g_unConfigFuncMode |= pstFrameInfo->unFunctionID;\r
+        }\r
+        GH3X2X_DEBUG_LOG_PARAM("[SetFunctionChnlNum] function id: 0x%X, ChnlNum: %d\r\n",(int)pstFrameInfo->unFunctionID, uchChnlNum);\r
+    }\r
+}\r
+\r
+void GH3x2xSetFunctionChnlMap(const STGh3x2xFrameInfo * const pstFrameInfo, GU8 uchChnlId, GU8 uchChnlTag)\r
+{\r
+    if(pstFrameInfo)\r
+    {\r
+        if(uchChnlId < (pstFrameInfo->uchFuntionChnlLimit))\r
+        {\r
+            pstFrameInfo ->pchChnlMap[uchChnlId] = uchChnlTag;\r
+\r
+            \r
+            GH3X2X_DEBUG_LOG_PARAM("[SetFunctionChnlMap] function id: 0x%X, SlotAdc: %d\r\n",(int)pstFrameInfo->unFunctionID, uchChnlTag>>3);\r
+        }\r
+        \r
+    }\r
+}\r
+\r
+\r
+void GH3x2xCalFunctionSlotBit(const STGh3x2xFrameInfo * const pstFrameInfo)\r
+{\r
+    GU8 uchSlotBit = 0;\r
+    GU8 uchChnlTag;\r
+    if(pstFrameInfo)\r
+    {\r
+        for(GU8 uchChnlCnt = 0; uchChnlCnt < pstFrameInfo->pstFunctionInfo->uchChnlNum; uchChnlCnt ++)\r
+        {\r
+            if(pstFrameInfo->pstFunctionInfo->unChnlEnForUserSetting & (((GU32)1) << uchChnlCnt))\r
+            {\r
+                uchChnlTag = pstFrameInfo->pchChnlMap[uchChnlCnt];\r
+                uchSlotBit |= (1 << (GH3X2X_BYTE_RAWDATA_GET_SLOT_NUM(uchChnlTag)));\r
+            }\r
+        }\r
+    }\r
+\r
+\r
+\r
+    \r
+    pstFrameInfo ->pstFunctionInfo->uchSlotBit = uchSlotBit;\r
+\r
+    \r
+    GH3X2X_DEBUG_LOG_PARAM("[GH3x2xCalFunctionSlotBit] function id: 0x%X, slot bit: 0x%X\r\n",(int)pstFrameInfo->unFunctionID, pstFrameInfo->pstFunctionInfo->uchSlotBit);\r
+}\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+//G202008031001 wanpeng START\r
+/**\r
+ * @fn     GU32 GH3X2X_GetSoftEvent(void)\r
+ * @brief  Get soft event\r
+ * @param[in]   None\r
+ * @param[out]  Soft event\r
+ *\r
+ * @return  soft event\r
+ */\r
+GU32 GH3X2X_GetSoftEvent(void)\r
+{\r
+    return g_unSoftEvent;\r
+}\r
+\r
+/**\r
+ * @fn     void GH3X2X_SetSoftEvent(GU32 unEvent)\r
+ * @brief  set soft event\r
+ * @param[in]   uchEvent\r
+ * @param[out]  None\r
+ * @return  None\r
+ */\r
+void GH3X2X_SetSoftEvent(GU32 unEvent)\r
+{\r
+    g_unSoftEvent |= unEvent;\r
+}\r
+/**\r
+ * @fn     void GH3X2X_ClearSoftEvent(GU32 unEvent)\r
+ * @brief  clear soft event\r
+ * @param[in]   uchEvent\r
+ * @param[out]  None\r
+ * @return  None\r
+ */\r
+\r
+void GH3X2X_ClearSoftEvent(GU32 unEvent)\r
+{\r
+    g_unSoftEvent &= (~unEvent);\r
+}\r
+//G202008031001 wanpeng END\r
+\r
+\r
+/**\r
+ * @fn     GU8 GH3X2X_GetGsensorEnableFlag(void)\r
+ *\r
+ * @brief  Inquire if need gsensor data\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  1: need gsensor data  0: not need gsensor data\r
+ */\r
+GU8 GH3X2X_GetGsensorEnableFlag(void)\r
+{\r
+    return g_uchGsensorEnable;\r
+}\r
+\r
+#if (0 == __CAP_ENABLE__)\r
+GU8 GH3X2X_GetCapEnableFlag(void)\r
+{\r
+    return 0;\r
+}\r
+#else\r
+GU8 GH3X2X_GetCapEnableFlag(void)\r
+{\r
+    return g_uchCapEnable;\r
+}\r
+#endif\r
+\r
+#if (0 == __TEMP_ENABLE__)\r
+GU8 GH3X2X_GetTempEnableFlag(void)\r
+{\r
+    return 0;\r
+}\r
+#else\r
+GU8 GH3X2X_GetTempEnableFlag(void)\r
+{\r
+    return g_uchTempEnable;\r
+}\r
+#endif\r
+\r
+void Gh3x2xFunctionInit(void)\r
+{\r
+    for(GU8 uchFuncitonCnt = 0; uchFuncitonCnt < GH3X2X_FUNC_OFFSET_MAX; uchFuncitonCnt ++)\r
+    {\r
+        if(g_pstGh3x2xFrameInfo[uchFuncitonCnt])\r
+        {\r
+            GH3x2xSetFunctionChnlNum(g_pstGh3x2xFrameInfo[uchFuncitonCnt], 0);   //chnl num\r
+            g_pstGh3x2xFrameInfo[uchFuncitonCnt] -> pstFunctionInfo -> usSampleRate = 0; //set sample rate to invalid value\r
+            g_pstGh3x2xFrameInfo[uchFuncitonCnt] -> pstDownSampleInfo -> uchDownSampleFactor = 0; \r
+            g_pstGh3x2xFrameInfo[uchFuncitonCnt] -> pstDownSampleInfo -> uchDownSampleCnt = 0; \r
+        }\r
+    }\r
+}\r
+\r
+/**\r
+ * @fn     void GH3X2X_ReinitAllSwModuleParam(GU16 usReinitFlag)\r
+ *\r
+ * @brief  reinit all software param config\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   usReinitFlag        reinit flag, #0 don't reinit, #others reinit all\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_ReinitAllSwModuleParam(GU16 usReinitFlag)\r
+{\r
+    if (usReinitFlag != 0) // if != 0, that need reinit all software module param\r
+    {\r
+\r
+        GH3x2xSetFunctionChnlNum(g_pstGh3x2xFrameInfo[GH3X2X_FUNC_OFFSET_HR], 0);\r
+        GH3x2xSetFunctionChnlNum(g_pstGh3x2xFrameInfo[GH3X2X_FUNC_OFFSET_HRV], 0);\r
+        GH3x2xSetFunctionChnlNum(g_pstGh3x2xFrameInfo[GH3X2X_FUNC_OFFSET_SPO2], 0);\r
+        GH3x2xSetFunctionChnlNum(g_pstGh3x2xFrameInfo[GH3X2X_FUNC_OFFSET_ECG], 0);\r
+        GH3x2xSetFunctionChnlNum(g_pstGh3x2xFrameInfo[GH3X2X_FUNC_OFFSET_SOFT_ADT_GREEN], 0);\r
+        GH3x2xSetFunctionChnlNum(g_pstGh3x2xFrameInfo[GH3X2X_FUNC_OFFSET_SOFT_ADT_IR], 0);\r
+        GH3x2xSetFunctionChnlNum(g_pstGh3x2xFrameInfo[GH3X2X_FUNC_OFFSET_ADT], 0);\r
+\r
+        #if __SUPPORT_SOFT_AGC_CONFIG__\r
+        GH3X2X_LedAgcReset();            // agc moudle param reinit\r
+        #endif\r
+        #if __FUNC_TYPE_ECG_ENABLE__ \r
+        GH3X2X_SlaverSoftLeadPramInit();// lead moudle param reinit\r
+        #endif\r
+\r
+        GH3X2X_DumpModeSet(0);          // dump module param reinit\r
+\r
+        #if __FUNC_TYPE_ECG_ENABLE__\r
+        GH3X2X_AdtPramInit();   ////G202008231001 wanpeng\r
+        #endif\r
+        g_uchGsensorEnable = 0;\r
+        // soft adt param reinit\r
+    }\r
+}\r
+\r
+\r
+/* util function, memcpy & memset & strlen */\r
+\r
+/**\r
+ * @fn     void *GH3X2X_Memcpy(void *pDest, const void *pSrc, GU32 unByteSize)\r
+ *\r
+ * @brief  memcpy() Re-implementation\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   pSrc        pointer to source buffer\r
+ * @param[in]   unByteSize  source buffer byte size\r
+ * @param[out]  pDest       pointer to destination buffer\r
+ *\r
+ * @return  pointer to destination buffer\r
+ */\r
+void *GH3X2X_Memcpy(void *pDest, const void *pSrc, GU32 unByteSize)\r
+{\r
+    GU8 *puchSrc = (GU8 *)pSrc;\r
+    GU8 *puchDest = (GU8 *)pDest;\r
+    GU32 unAlign = ((GU32)puchDest | (GU32)puchSrc) << GH3X2X_UPROTOCOL_ALIGN_LEFTSHIFT;\r
+\r
+    if ((pDest == GH3X2X_PTR_NULL) || (pSrc == GH3X2X_PTR_NULL) || (0 == unByteSize))\r
+    {\r
+        return GH3X2X_PTR_NULL;\r
+    }\r
+    if (unAlign == 0) // if align 4\r
+    {\r
+        while (unByteSize >= GH3X2X_UPROTOCOL_SIZE_T)\r
+        {\r
+            *(GU32 *)puchDest = *(GU32 *)puchSrc;\r
+            puchSrc += GH3X2X_UPROTOCOL_SIZE_T;\r
+            puchDest += GH3X2X_UPROTOCOL_SIZE_T;\r
+            unByteSize -= GH3X2X_UPROTOCOL_SIZE_T;\r
+        }\r
+    }\r
+    while (unByteSize) // bytes\r
+    {\r
+        *(GU8 *)puchDest = *(GU8 *)puchSrc;\r
+        puchSrc++;\r
+        puchDest++;\r
+        unByteSize--;\r
+    }\r
+    return pDest;\r
+}\r
+\r
+/**\r
+ * @fn     void *GH3X2X_Memset(void* pDest, GCHAR chVal, GU32 unByteSize)\r
+ *\r
+ * @brief  memset() Re-implementation\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   chVal       char val for set\r
+ * @param[in]   unByteSize       source buffer len\r
+ * @param[out]  pDest       pointer to destination buffer\r
+ *\r
+ * @return  pointer to destination buffer\r
+ */\r
+void *GH3X2X_Memset(void* pDest, GCHAR chVal, GU32 unByteSize)\r
+{\r
+    GU8 *puchDest = (GU8 *)pDest;\r
+    GU32 unAlign = ((GU32)puchDest) << GH3X2X_UPROTOCOL_ALIGN_LEFTSHIFT;\r
+    GU32 unWordVal = GH3X2X_MAKEUP_DWORD(chVal, chVal, chVal, chVal);\r
+\r
+    if (pDest == GH3X2X_PTR_NULL)\r
+    {\r
+        return GH3X2X_PTR_NULL;\r
+    }\r
+    if (unAlign == 0) // if align 4\r
+    {\r
+        while (unByteSize >= GH3X2X_UPROTOCOL_SIZE_T)\r
+        {\r
+            *(GU32 *)puchDest = unWordVal;\r
+            puchDest += GH3X2X_UPROTOCOL_SIZE_T;\r
+            unByteSize -= GH3X2X_UPROTOCOL_SIZE_T;\r
+        }\r
+    }\r
+    while (unByteSize) // bytes\r
+    {\r
+        *(GU8 *)puchDest = (GU8)chVal;\r
+        puchDest++;\r
+        unByteSize--;\r
+    }\r
+    return pDest;\r
+}\r
+\r
+/**\r
+ * @fn     GU32 GH3X2X_Strlen(const GCHAR *pszSrc)\r
+ *\r
+ * @brief  strlen() Re-implementation\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   pszSrc      pointer to string\r
+ * @param[out]  None\r
+ *\r
+ * @return  string len\r
+ */\r
+GU32 GH3X2X_Strlen(const GCHAR *pszSrc)\r
+{\r
+    GU32 unCnt = 0;\r
+    if (pszSrc != GH3X2X_PTR_NULL)\r
+    {\r
+        while ((*pszSrc) != 0) // if not equal '\0'\r
+        {\r
+            unCnt++;\r
+            pszSrc++;\r
+        }\r
+    }\r
+    return unCnt;\r
+}\r
+\r
+\r
+\r
+GU8 GH3X2X_GetAlgoEnableFlag(void)\r
+{\r
+    return g_uchAlgoEnableFlag;\r
+}\r
+\r
+void GH3X2X_SetAlgoEnableFlag(GU8 uchAlgoEnableFlag)\r
+{\r
+    g_uchAlgoEnableFlag = uchAlgoEnableFlag;\r
+}\r
+\r
+\r
+GU8 GH3X2X_GetSingleChipModeEnableFlag(void)\r
+{\r
+    return g_uchSingleChipModeEnableFlag;\r
+}\r
+\r
+void GH3X2X_SetSingleChipModeEnableFlag(GU8 uchAlgoEnableFlag)\r
+{\r
+    g_uchSingleChipModeEnableFlag = uchAlgoEnableFlag;\r
+}\r
+\r
+/**\r
+ * @fn     void GH3X2X_ModifyFunctionFrequency(GU8 uchFunctionID, GU16 usFrequencyValue) \r
+ *\r
+ * @brief  Modify fs for each function\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   uchFunctionID               function offset\r
+ * @param[in]   usFrequencyValue         5Hz-1000Hz\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_ModifyFunctionFrequency(GU8 uchFunctionID, GU16 usFrequencyValue)\r
+{\r
+    GU8 uchTempSlotNo = 0;\r
+    GU8 uchTempSlotLastNo = 0xff;\r
+    GU8 uchChnlCnt = 0;\r
+    for(uchChnlCnt = 0; uchChnlCnt < g_pstGh3x2xFrameInfo[uchFunctionID]->pstFunctionInfo->uchChnlNum; uchChnlCnt ++)\r
+    {\r
+        uchTempSlotNo = GH3X2X_BYTE_RAWDATA_GET_SLOT_NUM(g_pstGh3x2xFrameInfo[uchFunctionID]->pchChnlMap[uchChnlCnt]);\r
+        if (uchTempSlotLastNo != uchTempSlotNo)\r
+        {\r
+            GH3x2x_SetSlotSampleRate(uchTempSlotNo, usFrequencyValue);\r
+            uchTempSlotLastNo = uchTempSlotNo;\r
+        }\r
+    }\r
+    g_pstGh3x2xFrameInfo[uchFunctionID]->pstFunctionInfo->usSampleRate = usFrequencyValue;\r
+}\r
+\r
+/**\r
+ * @fn     void GH3X2X_ModifyFunctionLedCurrent(GU8 uchFunctionID, GU16 usLedDrv0Current, GU16 usLedDrv1Current)\r
+ *\r
+ * @brief  Modify led current for each function\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   uchFunctionID               function offset\r
+ * @param[in]   usLedDrv0Current         0mA-200mA\r
+ * @param[in]   usLedDrv1Current         0mA-200mA\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_ModifyFunctionLedCurrent(GU8 uchFunctionID, GU16 usLedDrv0Current, GU16 usLedDrv1Current)\r
+{\r
+    GU8 uchTempSlotNo = 0;\r
+    GU8 uchTempSlotLastNo = 0xff;\r
+    GU8 uchChnlCnt = 0;\r
+    GU16 usDrv0Reg = 0;\r
+    GU16 usDrv1Reg = 0;\r
+    GU16 usDr0Fs = 0;\r
+    GU16 usDr1Fs = 0;\r
+\r
+    GH3x2x_GetLedCurrentFullScal((GU8*)&usDr0Fs, (GU8*)&usDr1Fs);\r
+    \r
+    for(uchChnlCnt = 0; uchChnlCnt < g_pstGh3x2xFrameInfo[uchFunctionID]->pstFunctionInfo->uchChnlNum; uchChnlCnt ++)\r
+    {\r
+        uchTempSlotNo = GH3X2X_BYTE_RAWDATA_GET_SLOT_NUM(g_pstGh3x2xFrameInfo[uchFunctionID]->pchChnlMap[uchChnlCnt]);\r
+        if (uchTempSlotLastNo != uchTempSlotNo)\r
+        {\r
+            usDrv0Reg = (GU16)usLedDrv0Current * 255 /usDr0Fs;\r
+            if(usDrv0Reg > 255)\r
+            {\r
+                usDrv0Reg = 255;\r
+            }\r
+            usDrv1Reg = (GU16)usLedDrv1Current * 255 /usDr1Fs;\r
+            if(usDrv1Reg > 255)\r
+            {\r
+                usDrv1Reg = 255;\r
+            }\r
+\r
+            GH3X2X_SlotLedCurrentConfig(uchTempSlotNo, 0, usDrv0Reg);\r
+            GH3X2X_SlotLedCurrentConfig(uchTempSlotNo, 1, usDrv1Reg);\r
+            uchTempSlotLastNo = uchTempSlotNo;\r
+        }\r
+    }\r
+}\r
+\r
+GU32 GH3X2X_GetConfigFuncMode(void)\r
+{\r
+    return g_unConfigFuncMode;\r
+}\r
+\r
+void GH3X2X_SetConfigFuncMode(GU32 unConfigFuncMode)\r
+{\r
+    g_unConfigFuncMode = unConfigFuncMode;\r
+}\r
+\r
+void Gh3x2xFifoRecovery(void)\r
+{\r
+    GU16 uchSampleStateBak;\r
+    uchSampleStateBak = GH3X2X_ReadRegBitField(0x0000, 0, 0);\r
+    GH3X2X_WriteRegBitField(0x0000, 0, 0, 0);\r
+    Gh3x2x_BspDelayMs(10);\r
+    GH3X2X_WriteRegBitField(0x0000, 0, 0, uchSampleStateBak);\r
+}\r
+\r
+#if (GH3X2X_FIFO_MONITOR_EN&(__GH3X2X_INTERFACE__ == __GH3X2X_INTERFACE_I2C__))\r
+\r
+void Gh3x2xModifiyDecimation(GU8 uchDecimationChnl, GU8 uchSlotAdc, GU8 uchOption)\r
+{\r
+    GU16 uchSampleStateBak;\r
+    uchSampleStateBak = GH3X2X_ReadRegBitField(0x0000, 0, 0);\r
+    GH3X2X_WriteRegBitField(0x0000, 0, 0, 0);\r
+    Gh3x2x_BspDelayMs(10);\r
+\r
+    GH3X2X_WriteRegBitField(GH3X2X_DCMT_CTRL0_REG_ADDR, GH3X2X_DCMT_EN_LSB + uchDecimationChnl, GH3X2X_DCMT_EN_LSB + uchDecimationChnl, 1);\r
+    GH3X2X_WriteRegBitField(GH3X2X_DCMT_CTRL0_REG_ADDR, GH3X2X_DCMT_DNSAMPLE_DIS_LSB + uchDecimationChnl, GH3X2X_DCMT_DNSAMPLE_DIS_LSB + uchDecimationChnl, 0);\r
+\r
+    GH3X2X_WriteRegBitField(GH3X2X_DCMT_CTRL1_REG_ADDR + uchDecimationChnl * 2, GH3X2X_DCMT_HEAD_LSB, GH3X2X_DCMT_HEAD_MSB, uchSlotAdc);\r
+    GH3X2X_WriteRegBitField(GH3X2X_DCMT_CTRL1_REG_ADDR + uchDecimationChnl * 2, GH3X2X_DCMT_RND_SEL_LSB, GH3X2X_DCMT_RND_SEL_MSB, uchOption);\r
+\r
+    GH3X2X_WriteRegBitField(0x0000, 0, 0, uchSampleStateBak);\r
+}\r
+\r
+\r
+\r
+\r
+/// @brief get channel output en\r
+/// @param  \r
+/// @return output enable flagx, 0: slot0 adc0 output flag  1: slot0 adc1 output flag ... 31: slot7 adc3 output flag\r
+GU32 Gh3x2xGetChnlOutputEn(void)\r
+{\r
+    GU32 unChnlEn = 0;\r
+    GU8 uchSlotCfgEn = GH3X2X_ReadRegBitField(GH3X2X_SLOT_ENABLE_CFG_REG_ADDR, GH3X2X_SLOT_ENABLE_CFG_REG_LSB, GH3X2X_SLOT_ENABLE_CFG_REG_MSB);\r
+    //get channel en, need eliminate no-output channel\r
+    for(GU8 uchSlotCnt = 0; uchSlotCnt < GH3X2X_SLOT_NUM_MAX; uchSlotCnt ++)\r
+    {\r
+        if(uchSlotCfgEn&(1 << uchSlotCnt))\r
+        {\r
+            GU8 uchRxEnFifoEn = GH3X2X_ReadRegBitField(GH3X2X_SLOT0_CTRL_0_REG_ADDR + ((GU16)uchSlotCnt * GH3X2X_SLOT_CTRL_ADDR_INTERVAL), GH3X2X_SLOT_RX_EN_FIFO_EN_LSB, GH3X2X_SLOT_RX_EN_FIFO_EN_MSB);\r
+            if(uchRxEnFifoEn & (1 << (GH3X2X_SLOT_FIFO_EN_LSB - GH3X2X_SLOT_RX_EN_FIFO_EN_LSB)))  // if fifo en = 1\r
+            {\r
+                for(GU8 uchRxCnt = 0; uchRxCnt < GH3X2X_RX_NUM_MAX; uchRxCnt ++)\r
+                {\r
+                    if(uchRxEnFifoEn&(1 << uchRxCnt))\r
+                    {\r
+                        unChnlEn |= 1 << (uchSlotCnt * GH3X2X_RX_NUM_MAX + uchRxCnt);\r
+                    }\r
+                }\r
+            }\r
+        }\r
+    }\r
+    return unChnlEn; \r
+}\r
+\r
+/// @brief get sample rate factor for every slot\r
+/// @param puchSlotSampleRateFactor   [0]: slot0 sample rate factor  [1]: slot1 sample rate factor ... [7]: slot7 sample rate factor\r
+void Gh3x2xGetSlotSampleRateFactor(GU8 *puchSlotSampleRateFactor)\r
+{\r
+    for(GU8 uchSlotCnt = 0; uchSlotCnt < GH3X2X_SLOT_NUM_MAX; uchSlotCnt ++)\r
+    {\r
+        puchSlotSampleRateFactor[uchSlotCnt] = GH3X2X_ReadRegBitField(GH3X2X_SLOT0_CTRL_0_REG_ADDR + ((GU16)uchSlotCnt * GH3X2X_SLOT_CTRL_ADDR_INTERVAL), GH3X2X_SLOT_SR_MULTIPLIER_LSB, GH3X2X_SLOT_SR_MULTIPLIER_MSB);\r
+    }\r
+}\r
+\r
+\r
+#if  (0 == GH3X2X_FIFO_MONITOR_DECIMATION_SUPPORT)\r
+\r
+/// @brief get decimation enable (decimation en = 1 and downsample disable = 0)\r
+/// @param  none\r
+/// @return decimation\r
+GU8 Gh3x2xGetDecimationEn(void)\r
+{\r
+    GU8 uchDecimationEn;\r
+    GU8 uchDownSampleEn;\r
+    uchDecimationEn = GH3X2X_ReadRegBitField(GH3X2X_DCMT_CTRL0_REG_ADDR, GH3X2X_DCMT_EN_LSB, GH3X2X_DCMT_EN_MSB);\r
+    uchDownSampleEn = GH3X2X_ReadRegBitField(GH3X2X_DCMT_CTRL0_REG_ADDR, GH3X2X_DCMT_DNSAMPLE_DIS_LSB, GH3X2X_DCMT_DNSAMPLE_DIS_MSB);\r
+    return uchDecimationEn &= (~uchDownSampleEn);\r
+}\r
+\r
+#else\r
+\r
+\r
+/// @brief get decimaiton information in current chip registers\r
+/// @param pstDecimationInfo the decimation infomation that we get\r
+void Gh3x2xGetDecimationInfo(STGh3x2xDecimationInfo *pstDecimationInfo)\r
+{\r
+    GU8 uchDecimationEn;\r
+    GU8 uchDownSampleEn;\r
+    GU8 uchValidChnlCnt;\r
+    uchDecimationEn = GH3X2X_ReadRegBitField(GH3X2X_DCMT_CTRL0_REG_ADDR, GH3X2X_DCMT_EN_LSB, GH3X2X_DCMT_EN_MSB);\r
+    uchDownSampleEn = GH3X2X_ReadRegBitField(GH3X2X_DCMT_CTRL0_REG_ADDR, GH3X2X_DCMT_DNSAMPLE_DIS_LSB, GH3X2X_DCMT_DNSAMPLE_DIS_MSB);\r
+\r
+    uchDecimationEn &= (~uchDownSampleEn);  //we need channel which uchDecimationEn = 1 and uchDownSampleEn = 0\r
+    uchValidChnlCnt = 0;\r
+    for(GU8 uchChnlCnt = 0; uchChnlCnt < GH3X2X_DECIMAION_CHNL_MAX; uchChnlCnt ++)\r
+    {\r
+        if(uchDecimationEn&(1 << uchChnlCnt))\r
+        {\r
+            pstDecimationInfo->puchSlotAdcIdx[uchValidChnlCnt] = GH3X2X_ReadRegBitField(GH3X2X_DCMT_CTRL1_REG_ADDR + uchChnlCnt * 2, GH3X2X_DCMT_HEAD_LSB, GH3X2X_DCMT_HEAD_MSB);\r
+            pstDecimationInfo->puchDecimationOption[uchValidChnlCnt] = GH3X2X_ReadRegBitField(GH3X2X_DCMT_CTRL1_REG_ADDR + uchChnlCnt * 2, GH3X2X_DCMT_RND_SEL_LSB, GH3X2X_DCMT_RND_SEL_MSB);\r
+            uchValidChnlCnt ++;\r
+        }\r
+    }\r
+    pstDecimationInfo->uchDecimaionChnlNum = uchValidChnlCnt;\r
+}\r
+\r
+/// @brief get decimaion option of a specific channel\r
+/// @param uchSlotAdcIdx \r
+/// @return Decimaion option.   0: no decimtion  1: 2x decimation  2: 4x decimation 3: 8x decimation\r
+GU8 Gh3x2xGetChannelDecimationOption(GU8 uchSlotAdcIdx, STGh3x2xDecimationInfo *pstDecimationInfo)\r
+{\r
+    for(GU8 uchChnlCnt = 0; uchChnlCnt < pstDecimationInfo->uchDecimaionChnlNum; uchChnlCnt ++)\r
+    {\r
+        if(pstDecimationInfo->puchSlotAdcIdx[uchChnlCnt] == uchSlotAdcIdx)\r
+        {\r
+            return pstDecimationInfo->puchDecimationOption[uchChnlCnt];\r
+        }\r
+    }\r
+    return 0;\r
+}\r
+\r
+#endif\r
+\r
+#if  (0 == GH3X2X_FIFO_MONITOR_DECIMATION_SUPPORT)\r
+GU16 Gh3x2xGetDividerOfChnl(GU8 uchSlotAdcIdx, GU8 *puchSlotSampleRateFactor)\r
+#else\r
+GU16 Gh3x2xGetDividerOfChnl(GU8 uchSlotAdcIdx, STGh3x2xDecimationInfo *pstDecimationInfo, GU8 *puchSlotSampleRateFactor)\r
+#endif\r
+{\r
+    GU16 usTempDivider;\r
+    #if  (0 == GH3X2X_FIFO_MONITOR_DECIMATION_SUPPORT)\r
+    usTempDivider = ((GU16)puchSlotSampleRateFactor[uchSlotAdcIdx >> 2] + 1);\r
+    #else\r
+    GU8 uchDecimationOption;\r
+    uchDecimationOption = Gh3x2xGetChannelDecimationOption(uchSlotAdcIdx, pstDecimationInfo);\r
+    usTempDivider = ((GU16)puchSlotSampleRateFactor[uchSlotAdcIdx >> 2] + 1) << uchDecimationOption;\r
+    #endif\r
+    return usTempDivider;\r
+}\r
+\r
+/// @brief get slot adc index of the lowest frequence channel\r
+/// @param pstDecimationInfo \r
+/// @param puchSlotSampleRateFactor the register value of rg_slotX_sr_multiplier(X = 0~7), the array length is 8\r
+/// @param unSlotAdcChnlEn bi0: slot0adc0 is en or not   bit1: slot0adc1 is en or not  ...  bit31: is slot7adc3 is en or not\r
+/// @return slot adc index of this channel\r
+#if  (0 == GH3X2X_FIFO_MONITOR_DECIMATION_SUPPORT)\r
+GU8 Gh3x2xGetLowestChnl(GU8 *puchSlotSampleRateFactor, GU32 unSlotAdcChnlEn)\r
+#else\r
+GU8 Gh3x2xGetLowestChnl(STGh3x2xDecimationInfo *pstDecimationInfo, GU8 *puchSlotSampleRateFactor, GU32 unSlotAdcChnlEn)\r
+#endif\r
+{\r
+    GU16 usLowestChnlDivider = 0;\r
+    GU8  uchLowestChnlSlotAdc = 0xFF;\r
+    for(GU8 uchChnlCnt = 0; uchChnlCnt < (GH3X2X_RX_NUM_MAX * GH3X2X_SLOT_NUM_MAX); uchChnlCnt ++)\r
+    {\r
+        if(unSlotAdcChnlEn&(1 << uchChnlCnt))\r
+        {\r
+\r
+            GU16 usTempDivider;\r
+            #if  (0 == GH3X2X_FIFO_MONITOR_DECIMATION_SUPPORT)\r
+            usTempDivider = Gh3x2xGetDividerOfChnl(uchChnlCnt, puchSlotSampleRateFactor);\r
+            #else\r
+            usTempDivider = Gh3x2xGetDividerOfChnl(uchChnlCnt, pstDecimationInfo, puchSlotSampleRateFactor);\r
+            #endif\r
+            GH3X2X_DEBUG_LOG_PARAM("[Gh3x2xFifoMonitorInit] slot%d, adc%d, usTempDivider = %d.\r\n",(int)(GH3X2X_GET_SLOT_FROM_CHANNEL_NUM(uchChnlCnt)), (int)(GH3X2X_GET_ADC_FROM_CHANNEL_NUM(uchChnlCnt)), (int)usTempDivider);\r
+            if(usTempDivider > usLowestChnlDivider)\r
+            {\r
+                usLowestChnlDivider = usTempDivider;\r
+                uchLowestChnlSlotAdc = uchChnlCnt;\r
+            }\r
+        }\r
+    }\r
+    return uchLowestChnlSlotAdc;\r
+}\r
+\r
+\r
+/// @brief get sample rate radio(integer part) of target channel and reference channel\r
+/// @param pstDecimationInfo \r
+/// @param puchSlotSampleRateFactor the register value of rg_slotX_sr_multiplier(X = 0~7), the array length is 8\r
+/// @param uchTargetChnlSlotAdcIdx slot adc index of target channel\r
+/// @param uchRefChnlSlotAdcIdx slot adc index of reference channel\r
+/// @param puchDecimalFlag if decimal part is not zero, the flag will be set\r
+/// @return \r
+#if  (0 == GH3X2X_FIFO_MONITOR_DECIMATION_SUPPORT)\r
+GU16 Gh3x2xGetTargetChnlSampleRateRadio(GU8 *puchSlotSampleRateFactor, GU8 uchTargetChnlSlotAdcIdx, GU8 uchRefChnlSlotAdcIdx)\r
+#else\r
+GU16 Gh3x2xGetTargetChnlSampleRateRadio(STGh3x2xDecimationInfo *pstDecimationInfo, GU8 *puchSlotSampleRateFactor, GU8 uchTargetChnlSlotAdcIdx, GU8 uchRefChnlSlotAdcIdx, GU8 *puchDecimalFlag)\r
+#endif\r
+{\r
+    GU16 usTargetChnlDivder;\r
+    GU16 usRefChnlDivder;\r
+    GU16 usSampleRateRadio;\r
+    #if  (0 == GH3X2X_FIFO_MONITOR_DECIMATION_SUPPORT)\r
+    usTargetChnlDivder = Gh3x2xGetDividerOfChnl(uchTargetChnlSlotAdcIdx, puchSlotSampleRateFactor);\r
+    usRefChnlDivder = Gh3x2xGetDividerOfChnl(uchRefChnlSlotAdcIdx, puchSlotSampleRateFactor);\r
+    #else\r
+    usTargetChnlDivder = Gh3x2xGetDividerOfChnl(uchTargetChnlSlotAdcIdx, pstDecimationInfo, puchSlotSampleRateFactor);\r
+    usRefChnlDivder = Gh3x2xGetDividerOfChnl(uchRefChnlSlotAdcIdx, pstDecimationInfo, puchSlotSampleRateFactor);\r
+    #endif\r
+    usSampleRateRadio = usRefChnlDivder/usTargetChnlDivder;\r
+    #if  (GH3X2X_FIFO_MONITOR_DECIMATION_SUPPORT)\r
+    puchDecimalFlag[0] = 0;\r
+    if(usSampleRateRadio*usTargetChnlDivder < usRefChnlDivder)\r
+    {\r
+        puchDecimalFlag[0] = 1;\r
+    }\r
+    #endif\r
+    return usSampleRateRadio;\r
+}\r
+\r
+\r
+/// @brief fifo monitor module init\r
+/// @param pstMonitorInfo \r
+void Gh3x2xFifoMonitorInit(STGh3x2xFifoMonitorInfo *pstMonitorInfo)\r
+{\r
+    GU32 unChnlEn;\r
+    #if  (GH3X2X_FIFO_MONITOR_DECIMATION_SUPPORT)\r
+    STGh3x2xDecimationInfo stDecimationInfo;\r
+    GU8 uchDecimalFlag;\r
+    #endif\r
+    GU8 puchSlotSampleRateFactor[GH3X2X_SLOT_NUM_MAX];\r
+    GU16 usSampleRateRadio;\r
+\r
+    //Gh3x2xModifiyDecimation(3,(1 << 2)|(0 << 0),3);\r
+\r
+\r
+\r
+\r
+    GH3X2X_Memset((void*)pstMonitorInfo, 0, sizeof(STGh3x2xFifoMonitorInfo));\r
+\r
+    unChnlEn = Gh3x2xGetChnlOutputEn();\r
+    GH3X2X_DEBUG_LOG_PARAM("[Gh3x2xFifoMonitorInit] unChnlEn = 0x%X.\r\n",unChnlEn);\r
+    #if  (0 == GH3X2X_FIFO_MONITOR_DECIMATION_SUPPORT)\r
+    if(Gh3x2xGetDecimationEn())\r
+    {\r
+        GH3X2X_DEBUG_LOG_PARAM("[Gh3x2xFifoMonitorInit] error! decimation is detected, please set GH3X2X_FIFO_MONITOR_DECIMATION_SUPPORT to 1\r\n");\r
+        while(1);\r
+    }\r
+    #else\r
+    Gh3x2xGetDecimationInfo(&stDecimationInfo);\r
+    #endif\r
+    Gh3x2xGetSlotSampleRateFactor(puchSlotSampleRateFactor);\r
+\r
+    #if  (0 == GH3X2X_FIFO_MONITOR_DECIMATION_SUPPORT)\r
+    pstMonitorInfo->uchLowestChnlSlotAdcIdx = Gh3x2xGetLowestChnl(puchSlotSampleRateFactor, unChnlEn);\r
+    #else\r
+    pstMonitorInfo->uchLowestChnlSlotAdcIdx = Gh3x2xGetLowestChnl(&stDecimationInfo, puchSlotSampleRateFactor, unChnlEn);\r
+    #endif\r
+    \r
+    GH3X2X_DEBUG_LOG_PARAM("[Gh3x2xFifoMonitorInit] lowest chnl is slot%d, adc%d.\r\n",(int)(GH3X2X_GET_SLOT_FROM_CHANNEL_NUM(pstMonitorInfo->uchLowestChnlSlotAdcIdx)), (int)(GH3X2X_GET_ADC_FROM_CHANNEL_NUM(pstMonitorInfo->uchLowestChnlSlotAdcIdx)));\r
+    for(GU8 uchChnlCnt = 0; uchChnlCnt < (GH3X2X_RX_NUM_MAX * GH3X2X_SLOT_NUM_MAX); uchChnlCnt ++)\r
+    {\r
+        #if  (GH3X2X_FIFO_MONITOR_DECIMATION_SUPPORT)\r
+        uchDecimalFlag = 0;\r
+        #endif\r
+        if(unChnlEn & (1 << uchChnlCnt))\r
+        {\r
+            #if  (0 == GH3X2X_FIFO_MONITOR_DECIMATION_SUPPORT)\r
+            usSampleRateRadio = Gh3x2xGetTargetChnlSampleRateRadio(puchSlotSampleRateFactor, uchChnlCnt, pstMonitorInfo->uchLowestChnlSlotAdcIdx);\r
+            #else\r
+            usSampleRateRadio = Gh3x2xGetTargetChnlSampleRateRadio(&stDecimationInfo, puchSlotSampleRateFactor, uchChnlCnt, pstMonitorInfo->uchLowestChnlSlotAdcIdx, &uchDecimalFlag);\r
+            #endif\r
+            \r
+            #if 0 == GH3X2X_FIFO_MONITOR_RAM_OPTIMIZE\r
+            pstMonitorInfo -> usEstiSampleCntlimit[GH3X2X_GET_SLOT_FROM_CHANNEL_NUM(uchChnlCnt)] += usSampleRateRadio;\r
+            #endif\r
+            pstMonitorInfo -> usEstiAllChnlSampleCntlimit += usSampleRateRadio;\r
+            \r
+            #if  (GH3X2X_FIFO_MONITOR_DECIMATION_SUPPORT)\r
+            #if 0 == GH3X2X_FIFO_MONITOR_RAM_OPTIMIZE\r
+            pstMonitorInfo -> uchEstiSampleCntUplimit[GH3X2X_GET_SLOT_FROM_CHANNEL_NUM(uchChnlCnt)] += usSampleRateRadio + uchDecimalFlag;\r
+            #endif\r
+            pstMonitorInfo -> usEstiAllChnlSampleCntUplimit += usSampleRateRadio + uchDecimalFlag;\r
+            #endif\r
+\r
+            #if  (GH3X2X_FIFO_MONITOR_DECIMATION_SUPPORT)\r
+            GH3X2X_DEBUG_LOG_PARAM("[Gh3x2xFifoMonitorInit] slot%dadc%d usSampleRateRadio = %d, uchDecimalFlag = %d.\r\n",\r
+            (int)(GH3X2X_GET_SLOT_FROM_CHANNEL_NUM(uchChnlCnt)), \r
+            (int)(GH3X2X_GET_ADC_FROM_CHANNEL_NUM(uchChnlCnt)),\r
+            (int)(usSampleRateRadio), \r
+            (int)(uchDecimalFlag)\r
+            );\r
+            #else\r
+            GH3X2X_DEBUG_LOG_PARAM("[Gh3x2xFifoMonitorInit] slot%dadc%d usSampleRateRadio = %d.\r\n",\r
+            (int)(GH3X2X_GET_SLOT_FROM_CHANNEL_NUM(uchChnlCnt)), \r
+            (int)(GH3X2X_GET_ADC_FROM_CHANNEL_NUM(uchChnlCnt)),\r
+            (int)(usSampleRateRadio)\r
+            );\r
+            #endif\r
+\r
+\r
+\r
+        }\r
+    }\r
+\r
+    pstMonitorInfo -> usNeedSkipFifoByteNum = GH3X2X_ReadReg(GH3X2X_INT_FIFO_UR_REG_ADDR) * GH3X2X_FIFO_RAWDATA_SIZE;\r
+}\r
+\r
+\r
+/// @brief recovry process function which is using after abnormal fifo data is monitored\r
+/// @param pstMonitorInfo \r
+void Gh3x2xFifoMonitorRecovery(STGh3x2xFifoMonitorInfo *pstMonitorInfo)\r
+{\r
+    Gh3x2xFifoRecovery();\r
+    Gh3x2xFifoMonitorInit(pstMonitorInfo);\r
+}\r
+\r
+extern volatile GU32 g_unDebugFifoMonitor;\r
+\r
+/// @brief fifo monitor module process function\r
+/// @param pstMonitorInfo \r
+/// @param pFifo fifo data byte stream\r
+/// @param FifoByteNum  fifo date byte number\r
+void Gh3x2xFifoMonitorPro(STGh3x2xFifoMonitorInfo *pstMonitorInfo, GU8 *pFifo, GU16 FifoByteNum)\r
+{\r
+    GU8 uchSlotAdc;\r
+    GU16 usAllChnlUpLimit;\r
+    GU16 usAllChnlDownLimit;\r
+    GU8 uchIsAbnormal = 0;\r
+    #if 0 == GH3X2X_FIFO_MONITOR_RAM_OPTIMIZE\r
+    GU8 uchSlotIdx;\r
+    GU16 *pusUpLimit;\r
+    GU16 *pusDownLimit;\r
+    pusDownLimit = pstMonitorInfo ->usEstiSampleCntlimit;\r
+    #if  (0 == GH3X2X_FIFO_MONITOR_DECIMATION_SUPPORT)\r
+    pusUpLimit = pstMonitorInfo ->usEstiSampleCntlimit;\r
+    #else\r
+    pusUpLimit = pstMonitorInfo ->uchEstiSampleCntUplimit;\r
+    #endif\r
+    #endif\r
+    usAllChnlDownLimit = pstMonitorInfo ->usEstiAllChnlSampleCntlimit;\r
+    #if  (0 == GH3X2X_FIFO_MONITOR_DECIMATION_SUPPORT)\r
+    usAllChnlUpLimit = pstMonitorInfo ->usEstiAllChnlSampleCntlimit;\r
+    #else\r
+    usAllChnlUpLimit = pstMonitorInfo ->usEstiAllChnlSampleCntUplimit;\r
+    #endif\r
+\r
+\r
+    for(GU16 usFifoByteCnt = 0; usFifoByteCnt < FifoByteNum; usFifoByteCnt += GH3X2X_FIFO_RAWDATA_SIZE)\r
+    {\r
+        if(0 == pstMonitorInfo ->usNeedSkipFifoByteNum)\r
+        {\r
+            uchSlotAdc = GH3X2X_BYTE_RAWDATA_GET_SLOT_ADC_NUM(pFifo[usFifoByteCnt]);\r
+            #if 0 == GH3X2X_FIFO_MONITOR_RAM_OPTIMIZE\r
+            uchSlotIdx = GH3X2X_GET_SLOT_FROM_CHANNEL_NUM(uchSlotAdc);\r
+            #endif\r
+            //GH3X2X_DEBUG_LOG_PARAM("[Gh3x2xFifoMonitorPro]Got data :Slot%dAdc%d.\r\n",(int)uchSlotIdx, (int)(GH3X2X_GET_ADC_FROM_CHANNEL_NUM(uchSlotAdc)));\r
+            #if 0 == GH3X2X_FIFO_MONITOR_RAM_OPTIMIZE\r
+            pstMonitorInfo ->usRealTimeSampleCnt[uchSlotIdx] += 1;\r
+            #endif\r
+            pstMonitorInfo ->usAllChnlRealTimeSampleCnt += 1;\r
+            #if GH3X2X_FIFO_MONITOR_DEBUG\r
+            pstMonitorInfo ->usEveryChnlRealTimeSampleCnt[uchSlotIdx][GH3X2X_GET_ADC_FROM_CHANNEL_NUM(uchSlotAdc)] += 1;\r
+            #endif\r
+            #if 0 == GH3X2X_FIFO_MONITOR_RAM_OPTIMIZE\r
+            if(pstMonitorInfo -> usRealTimeSampleCnt[uchSlotIdx] > pusUpLimit[uchSlotIdx])  // is abnormal\r
+            {\r
+                uchIsAbnormal = 1;\r
+                GH3X2X_DEBUG_LOG_PARAM("[Gh3x2xFifoMonitorPro]RealTimeSampleCnt is too big,uchSlotIdx = %d,RealTimeSampleCnt = %d, limit = %d\r\n",(int)uchSlotIdx, (int)pstMonitorInfo -> usRealTimeSampleCnt[uchSlotIdx], pusUpLimit[uchSlotIdx]);\r
+            }\r
+            \r
+            if((pstMonitorInfo ->uchLowestChnlAppearedFlag) &&(uchSlotAdc == pstMonitorInfo->uchLowestChnlSlotAdcIdx) && (uchSlotAdc == pstMonitorInfo->uchLowestChnlSlotAdcIdx))\r
+            {\r
+                for(GU8 uchSlotCnt = 0; uchSlotCnt < GH3X2X_SLOT_NUM_MAX; uchSlotCnt ++)\r
+                {\r
+                    if(pstMonitorInfo -> usRealTimeSampleCnt[uchSlotCnt] < pusDownLimit[uchSlotCnt])\r
+                    {\r
+                        uchIsAbnormal = 1;\r
+                        GH3X2X_DEBUG_LOG_PARAM("[Gh3x2xFifoMonitorPro]RealTimeSampleCnt is too small,uchSlotCnt = %d,RealTimeSampleCnt = %d, limit = %d\r\n",(int)uchSlotCnt, (int)pstMonitorInfo -> usRealTimeSampleCnt[uchSlotCnt], pusDownLimit[uchSlotCnt]);\r
+                    }\r
+                }\r
+            }\r
+            #endif\r
+\r
+            if(pstMonitorInfo -> usAllChnlRealTimeSampleCnt > usAllChnlUpLimit)  // is abnormal\r
+            {\r
+                uchIsAbnormal = 2;\r
+                GH3X2X_DEBUG_LOG_PARAM("[Gh3x2xFifoMonitorPro]AllChnlRealTimeSampleCnt is too big,RealTimeSampleCnt = %d, limit = %d.\r\n", (int)pstMonitorInfo -> usAllChnlRealTimeSampleCnt, usAllChnlUpLimit);\r
+            }\r
+            if((pstMonitorInfo ->uchLowestChnlAppearedFlag)&&(uchSlotAdc == pstMonitorInfo->uchLowestChnlSlotAdcIdx) && (pstMonitorInfo -> usAllChnlRealTimeSampleCnt < usAllChnlDownLimit))  // is abnormal\r
+            {\r
+                GH3X2X_DEBUG_LOG_PARAM("[Gh3x2xFifoMonitorPro]AllChnlRealTimeSampleCnt is too samll,RealTimeSampleCnt = %d, limit = %d.\r\n", (int)pstMonitorInfo -> usAllChnlRealTimeSampleCnt, usAllChnlDownLimit);\r
+                uchIsAbnormal = 2;\r
+            }\r
+\r
+            if(2 == uchIsAbnormal)\r
+            {\r
+                GH3X2X_DEBUG_LOG_PARAM("[Gh3x2xFifoMonitorPro] ***************every channel information START************\r\n");\r
+                for(GU8 uchSlotCnt = 0; uchSlotCnt < GH3X2X_SLOT_NUM_MAX; uchSlotCnt ++)\r
+                {\r
+                    #if GH3X2X_FIFO_MONITOR_DEBUG\r
+                    GH3X2X_DEBUG_LOG_PARAM(\r
+                    "[Gh3x2xFifoMonitorPro] Real time every channel sample num: Slot%d: %d, %d, %d, %d.\r\n", \r
+                    (int)uchSlotCnt, \r
+                    (int)pstMonitorInfo ->usEveryChnlRealTimeSampleCnt[uchSlotCnt][EVERY_CHNL_REAL_TIME_SAMPLE_CNT_RX0_INDEX],\r
+                    (int)pstMonitorInfo ->usEveryChnlRealTimeSampleCnt[uchSlotCnt][EVERY_CHNL_REAL_TIME_SAMPLE_CNT_RX1_INDEX],\r
+                    (int)pstMonitorInfo ->usEveryChnlRealTimeSampleCnt[uchSlotCnt][EVERY_CHNL_REAL_TIME_SAMPLE_CNT_RX2_INDEX],\r
+                    (int)pstMonitorInfo ->usEveryChnlRealTimeSampleCnt[uchSlotCnt][EVERY_CHNL_REAL_TIME_SAMPLE_CNT_RX3_INDEX]\r
+                    );\r
+                    #endif\r
+\r
+                    #if 0 == GH3X2X_FIFO_MONITOR_RAM_OPTIMIZE\r
+                    GH3X2X_DEBUG_LOG_PARAM("[Gh3x2xFifoMonitorPro] Real time slot sample num up: Slot%d: %d.\r\n", (int)uchSlotCnt, (int)pstMonitorInfo ->usRealTimeSampleCnt[uchSlotCnt]);\r
+                    GH3X2X_DEBUG_LOG_PARAM("[Gh3x2xFifoMonitorPro] slot sample num up limit: Slot%d: %d.\r\n", (int)uchSlotCnt, (int)pstMonitorInfo ->uchEstiSampleCntUplimit[uchSlotCnt]);\r
+                    GH3X2X_DEBUG_LOG_PARAM("[Gh3x2xFifoMonitorPro] slot sample num down limit: Slot%d: %d.\r\n", (int)uchSlotCnt, (int)pstMonitorInfo ->usEstiSampleCntlimit[uchSlotCnt]);\r
+                    #endif\r
+\r
+                }\r
+                GH3X2X_DEBUG_LOG_PARAM("[Gh3x2xFifoMonitorPro] Real time all-chnl sample num: %d.\r\n", (int)pstMonitorInfo ->usAllChnlRealTimeSampleCnt);\r
+                #if  (GH3X2X_FIFO_MONITOR_DECIMATION_SUPPORT)\r
+                GH3X2X_DEBUG_LOG_PARAM("[Gh3x2xFifoMonitorPro] all-chnl sample up limit num: %d.\r\n", (int)pstMonitorInfo ->usEstiAllChnlSampleCntUplimit);\r
+                #endif\r
+                GH3X2X_DEBUG_LOG_PARAM("[Gh3x2xFifoMonitorPro] all-chnl sample down limit num: %d.\r\n", (int)pstMonitorInfo ->usEstiAllChnlSampleCntlimit);\r
+                GH3X2X_DEBUG_LOG_PARAM("[Gh3x2xFifoMonitorPro] ***************every channel information END************\r\n");\r
+            }\r
+\r
+            if(2 == uchIsAbnormal)\r
+            {\r
+                \r
+                GH3X2X_DEBUG_LOG_PARAM("[Gh3x2xFifoMonitorPro]recover fifo start...\r\n");\r
+                Gh3x2xFifoMonitorRecovery(pstMonitorInfo);  //go to recovery process\r
+                GH3X2X_DEBUG_LOG_PARAM("[Gh3x2xFifoMonitorPro]recover fifo end.\r\n");\r
+                break;\r
+            }\r
+\r
+            if(uchSlotAdc == pstMonitorInfo->uchLowestChnlSlotAdcIdx)\r
+            {\r
+                pstMonitorInfo ->uchLowestChnlAppearedFlag = 1;\r
+                #if 0 == GH3X2X_FIFO_MONITOR_RAM_OPTIMIZE\r
+                GH3X2X_Memset((void*)pstMonitorInfo -> usRealTimeSampleCnt, 0, sizeof(pstMonitorInfo -> usRealTimeSampleCnt));\r
+                #endif\r
+                pstMonitorInfo -> usAllChnlRealTimeSampleCnt = 0;\r
+                #if GH3X2X_FIFO_MONITOR_DEBUG\r
+                GH3X2X_Memset((void*)pstMonitorInfo -> usEveryChnlRealTimeSampleCnt, 0, sizeof(pstMonitorInfo -> usEveryChnlRealTimeSampleCnt));\r
+                #endif\r
+                pstMonitorInfo->usAllChnlRealTimeSampleCnt = 0;\r
+            }\r
+        }\r
+        else\r
+        {\r
+            if(pstMonitorInfo ->usNeedSkipFifoByteNum < GH3X2X_FIFO_RAWDATA_SIZE)\r
+            {\r
+                pstMonitorInfo ->usNeedSkipFifoByteNum = 0;\r
+            }\r
+            else\r
+            {\r
+                pstMonitorInfo ->usNeedSkipFifoByteNum -= GH3X2X_FIFO_RAWDATA_SIZE;\r
+            }\r
+        }\r
+    }\r
+}\r
+\r
+#endif\r
+\r
+\r
+#if  __DRIVER_OPEN_ALL_SOURCE__\r
+void GH3X2X_CalRawdataBuf(GU8 *puchRawdata, GU16 usRawdataLen)\r
+{\r
+\r
+}\r
+\r
+GU8 GH3X2X_CheckRawdataBuf(GU8 *puchRawdata, GU16 usRawdataLen)\r
+{\r
+    return 0;\r
+}\r
+\r
+\r
+/**\r
+ * @fn     GS16 GH3X2X_ReadFifodata(GU8 *puchGh3x2xReadFifoData, GU16* pusReadFifoDataLen)\r
+ *\r
+ * @brief  Read Gh3x2x Fifo Data for open source\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  puchGh3x2xReadFifoData      pointer to Gh3x2x fifo data\r
+ * @param[out]  pusReadFifoDataLen          pointer to Gh3x2x fifo data length in byte\r
+ *\r
+ * @return  error code\r
+ * @retval  #GH3X2X_RET_OK                      return read fifo successful\r
+ * @retval  #GH3X2X_RET_PARAMETER_ERROR         return param error\r
+ * @retval  #GH3X2X_RET_READ_FIFO_CONTINUE      return fifo is not empty\r
+ */\r
+GS16 GH3X2X_ReadFifodata(GU8 *puchGh3x2xReadFifoData, GU16* pusReadFifoDataLen ,GU16 usFifoReadByteNum)\r
+{\r
+    //GU16 usFifoLength = 0;\r
+    GS16 sRet = GH3X2X_RET_OK;\r
+\r
+    GH3X2X_DEBUG_LOG_PARAM("%s\r\n", __FUNCTION__);\r
+    if ((puchGh3x2xReadFifoData != GH3X2X_PTR_NULL) && (pusReadFifoDataLen != GH3X2X_PTR_NULL))\r
+    {\r
+        GH3X2X_WAIT_CHIP_WAKEUP();\r
+        /*\r
+        usFifoLength = GH3X2X_FIFO_CNT_CALC(GH3X2X_ReadReg(GH3X2X_INT_FIFO_UR_REG_ADDR));\r
+        */\r
+        if (usFifoReadByteNum > g_usMaxNumReadFromFifo)\r
+        {\r
+            usFifoReadByteNum = g_usMaxNumReadFromFifo;\r
+            sRet = GH3X2X_RET_READ_FIFO_CONTINUE;\r
+        }\r
+\r
+        if ((usFifoReadByteNum > 0) && (usFifoReadByteNum <= GH3X2X_FIFO_DATA_BYTES_MAX_LEN))\r
+        {\r
+            GH3X2X_ReadFifo(puchGh3x2xReadFifoData, usFifoReadByteNum);\r
+        }\r
+        else\r
+        {\r
+            if (usFifoReadByteNum > GH3X2X_FIFO_DATA_BYTES_MAX_LEN)\r
+            {\r
+                usFifoReadByteNum = 0;\r
+                GH3X2X_DEBUG_LOG_PARAM("get rawdata fifo len greater than max, pelease check i2c/spi!\r\n");\r
+            }\r
+            else\r
+            {\r
+                GH3X2X_DEBUG_LOG_PARAM("get rawdata fifo equl 0!\r\n");\r
+            }\r
+        }\r
+        \r
+        /* call hook */\r
+        HOOK_FUNC_CALL(g_pGh3x2xGetRawdataHookFunc, (puchGh3x2xReadFifoData, usFifoReadByteNum) );\r
+        GH3X2X_WAIT_CHIP_DSLP();\r
+        (*pusReadFifoDataLen) = usFifoReadByteNum;\r
+    }// if (pstGh3x2xRawdata->puchReadBuffer != GH3X2X_PTR_NULL)\r
+    else\r
+    {\r
+        GH3X2X_DEBUG_LOG_PARAM("get rawdata error that pointer is null!\r\n");\r
+        sRet = GH3X2X_RET_PARAMETER_ERROR;\r
+    }\r
+\r
+    //SET_VAL_VIA_PTR(usFifoReadByteNum, usFifoLength);\r
+    return sRet;\r
+}\r
+\r
+GS16 GH3X2X_CascadeReadFifodata(GU8 *puchGh3x2xReadFifoDataCascade, GU8 *puchGh3x2xReadFifoDataSingleBuf, GU16* pusReadFifoDataLen ,GU16 usFifoReadByteNum, GU8 uchChip2ChannelMap)\r
+{\r
+    //GU16 usFifoLength = 0;\r
+    GS16 sRet = GH3X2X_RET_OK;\r
+    GU16 usIndex = 0;\r
+\r
+    GH3X2X_DEBUG_LOG_PARAM("%s\r\n", __FUNCTION__);\r
+    if ((puchGh3x2xReadFifoDataCascade != GH3X2X_PTR_NULL) && (puchGh3x2xReadFifoDataSingleBuf != GH3X2X_PTR_NULL) \\r
+                                                            && (pusReadFifoDataLen != GH3X2X_PTR_NULL))\r
+    {\r
+        GH3X2X_WAIT_CHIP_WAKEUP();\r
+    /*\r
+        usFifoLength = GH3X2X_FIFO_CNT_CALC(GH3X2X_ReadReg(GH3X2X_INT_FIFO_UR_REG_ADDR));\r
+        */\r
+        if (usFifoReadByteNum > g_usMaxNumReadFromFifo)\r
+        {\r
+            usFifoReadByteNum = g_usMaxNumReadFromFifo;\r
+            sRet = GH3X2X_RET_READ_FIFO_CONTINUE;\r
+        }\r
+        \r
+        if ((usFifoReadByteNum > 0) && (usFifoReadByteNum <= GH3X2X_FIFO_DATA_BYTES_MAX_LEN))\r
+        {\r
+            //GH3X2X_CascadeOperationMasterChip();\r
+            GH3X2X_ReadFifo(puchGh3x2xReadFifoDataSingleBuf, (usFifoReadByteNum / 4) * 4);\r
+            GU32* punGh3x2xReadFifoDataCascade = (GU32* )puchGh3x2xReadFifoDataCascade;\r
+            GU32* punGh3x2xReadFifoDataSingleBuf =(GU32* ) puchGh3x2xReadFifoDataSingleBuf;\r
+            for (usIndex = 0; usIndex< usFifoReadByteNum / 4; usIndex++)\r
+            {\r
+                punGh3x2xReadFifoDataCascade[2*usIndex] = punGh3x2xReadFifoDataSingleBuf[usIndex];\r
+            }\r
+            \r
+            GH3X2X_CascadeOperationSlaverChip();\r
+            GH3X2X_ReadFifo(puchGh3x2xReadFifoDataSingleBuf, (usFifoReadByteNum / 4) * 4);\r
+            GH3X2X_CascadeOperationMasterChip();\r
+            for (usIndex = 0; usIndex< usFifoReadByteNum / 4; usIndex++)\r
+            {\r
+                punGh3x2xReadFifoDataSingleBuf[usIndex] &= 0xffffff07;\r
+                punGh3x2xReadFifoDataSingleBuf[usIndex] |= uchChip2ChannelMap;\r
+                punGh3x2xReadFifoDataCascade[2*usIndex + 1] = punGh3x2xReadFifoDataSingleBuf[usIndex];\r
+            }\r
+        }\r
+        else\r
+        {\r
+            if (usFifoReadByteNum > GH3X2X_FIFO_DATA_BYTES_MAX_LEN)\r
+            {\r
+                usFifoReadByteNum = 0;\r
+                GH3X2X_DEBUG_LOG_PARAM("get rawdata fifo len greater than max, pelease check i2c/spi!\r\n");\r
+            }\r
+            else\r
+            {\r
+                GH3X2X_DEBUG_LOG_PARAM("get rawdata fifo equl 0!\r\n");\r
+            }\r
+        }\r
+        \r
+        /* call hook */\r
+        HOOK_FUNC_CALL(g_pGh3x2xGetRawdataHookFunc, (puchGh3x2xReadFifoDataCascade, usFifoReadByteNum * 2) );\r
+        GH3X2X_WAIT_CHIP_DSLP();\r
+    }// if (pstGh3x2xRawdata->puchReadBuffer != GH3X2X_PTR_NULL)\r
+    else\r
+    {\r
+        GH3X2X_DEBUG_LOG_PARAM("get rawdata error that pointer is null!\r\n");\r
+        sRet = GH3X2X_RET_PARAMETER_ERROR;\r
+    }\r
+\r
+    //SET_VAL_VIA_PTR(usFifoReadByteNum, usFifoLength);\r
+    (*pusReadFifoDataLen) = usFifoReadByteNum * 2;\r
+    return sRet;\r
+}\r
+#endif\r
+\r
+\r
+\r
+/********END OF FILE********* Copyright (c) 2003 - 2022, Goodix Co., Ltd. ********/\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/driver/src/gh_drv_dump.c b/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/driver/src/gh_drv_dump.c
new file mode 100644 (file)
index 0000000..2159fc9
--- /dev/null
@@ -0,0 +1,2721 @@
+/**\r
+ * @copyright (c) 2003 - 2022, Goodix Co., Ltd. All rights reserved.\r
+ *\r
+ * @file    gh3x2x_drv_dump.c\r
+ *\r
+ * @brief   gh3x2x dump data functions\r
+ *\r
+ * @version ref gh3x2x_drv_version.h\r
+ *\r
+ */\r
+\r
+\r
+#include "gh_drv_version.h"\r
+#include "gh_drv_common.h"\r
+#include "gh_drv.h"\r
+#include "gh_drv_interface.h"\r
+#include "gh_drv_control.h"\r
+#include "gh_uprotocol.h"\r
+#include "gh_drv_dump.h"\r
+#include "gh_agc.h"\r
+\r
+/// dump mode\r
+GU16 g_usDumpMode;   //bit0: GH3X2X_DUMP_GAIN_CURRENT_ENABLE_BIT  bit1: GH3X2X_DUMP_AMBIANCE_ENABLE_BIT  bit2: GH3X2X_DUMP_ELECTR_WEAR_ENABLE_BIT\r
+\r
+/// electrode wear status\r
+GU8 g_uchElectrodeWearStatus;\r
+\r
+/// save bg cancel value of every channel\r
+extern GU8  g_puchGainBgCancelRecord[GH3X2X_CHANNEL_MAP_MAX_CH];\r
+/// save agc info of every channel\r
+// extern STGh3x2xAgcInfo g_stGh3x2xAgcInfo;\r
+/**\r
+ * @fn     GU16 GH3X2X_DumpModeGet(void)\r
+ *\r
+ * @brief  get dump mode\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  dump mode\r
+ */\r
+GU16 GH3X2X_DumpModeGet(void)\r
+{\r
+    return g_usDumpMode;\r
+}\r
+\r
+/**\r
+ * @fn     void GH3X2X_DumpModeSet(GU16 usRegVal)\r
+ *\r
+ * @brief  set dump mode\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   usRegVal          reg value\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_DumpModeSet(GU16 usRegVal)\r
+{\r
+    g_usDumpMode = usRegVal;\r
+}\r
+\r
+\r
+const GU16 g_usGH3x2xSlotRegBase[8] = \r
+{\r
+    0x0100,\r
+    0x011C,\r
+    0x0138,\r
+    0x0154,\r
+    0x0170,\r
+    0x018C,\r
+    0x01A8,\r
+    0x01C4,\r
+};\r
+\r
+const STGh3x2xAgcReg g_pstGH3x2xAgcReg[] = \r
+{\r
+    {0x10, 9, 8},              //0: agc en\r
+    {0x22, 7, 0},              //1: led current up limit\r
+    {0x22, 15, 8},               //2: led current down limit\r
+    {0x1E, 7, 0},               //3: led current drv0\r
+    {0x20, 7, 0},               //4: led current drv1\r
+    {0x12, 3, 0},               //5: rx0 tia gain\r
+    {0x12, 7, 4},               //6: rx1 tia gain\r
+    {0x12, 11, 8},               //7: rx2 tia gain\r
+    {0x12, 15, 12},               //8: rx3 tia gain\r
+    {0x10, 7,6},               //9: agc src\r
+    {0x1A, 1,0},               //10: rx0 bg cancel\r
+    {0x1A, 3,2},               //11: rx1 bg cancel    \r
+    {0x1A, 5,4},               //12: rx2 bg cancel\r
+    {0x1A, 7,6},               //13: rx2 bg cancel\r
+    {0x0A, 15,8},               //14: sr mulipliper\r
+    {0x0A, 5,1},               //15: ecg en& rx0~rx1 en\r
+};\r
+\r
+const GU16 g_usGH3x2xTiaGainR[] = \r
+{\r
+    10,\r
+    25,\r
+    50,\r
+    75,\r
+    100,\r
+    250,\r
+    500,\r
+    750,\r
+    1000,\r
+    1250,\r
+    1500,\r
+    1750,\r
+    2000,\r
+};\r
+\r
+void GH3x2xSetAgcReg(GU8 uchAgcReg,  GU8 uchSlot, GU16 usValue)\r
+{\r
+    GH3X2X_WriteRegBitField(g_usGH3x2xSlotRegBase[uchSlot] + g_pstGH3x2xAgcReg[uchAgcReg].uchAddrOffset, g_pstGH3x2xAgcReg[uchAgcReg].uchLsb, g_pstGH3x2xAgcReg[uchAgcReg].uchMsb, usValue);\r
+}\r
+\r
+GU16 GH3x2xGetAgcReg(GU8 uchAgcReg,  GU8 uchSlot)\r
+{\r
+    return GH3X2X_ReadRegBitField(g_usGH3x2xSlotRegBase[uchSlot] + g_pstGH3x2xAgcReg[uchAgcReg].uchAddrOffset, g_pstGH3x2xAgcReg[uchAgcReg].uchLsb, g_pstGH3x2xAgcReg[uchAgcReg].uchMsb);\r
+}\r
+\r
+\r
+/**\r
+ * @fn       void GH3X2X_ElectrWearDumpDataPro(GU8* puchRawdataTag, GU8 uchChMapIndex)\r
+ *\r
+ * @brief    electrode wear dump data pro\r
+ *\r
+ * @attention    None\r
+ *\r
+ * @param[in]    puchRawdataTag      data tag of rawdata\r
+ * @param[in]    uchChMapIndex       channel map index\r
+ * @param[out]   None\r
+ *\r
+ * @return       None\r
+ */\r
+ /*\r
+void GH3X2X_ElectrWearDumpDataPro(GU8* puchRawdataTag, GU8 uchChMapIndex)\r
+{\r
+    if (GH3X2X_CHECK_LEFT_BIT_SET(GH3X2X_DumpModeGet(), GH3X2X_DUMP_ELECTR_WEAR_ENABLE_BIT))\r
+    {\r
+        GH3X2X_WAIT_CHIP_WAKEUP();\r
+        g_uchElectrodeWearStatus = GH3X2X_ReadRegBitField(GH3X2X_INT_STR2_REG_ADDR, \\r
+                                    GH3X2X_ELECTR_WEAR_STATUS_BIT_FIELD, GH3X2X_ELECTR_WEAR_STATUS_BIT_FIELD);\r
+        GH3X2X_WAIT_CHIP_DSLP();\r
+    }\r
+}\r
+*/\r
+\r
+/**\r
+ * @fn     void GH3X2X_RecordGainBgCancelValue(void)\r
+ *\r
+ * @brief  read gain and bg cancel value, and save them\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+ /*\r
+void GH3X2X_RecordGainBgCancelValue(void)\r
+{\r
+    GU8  uchSlotIndexCnt   = 0;\r
+    GU8  uchAdcIndexCnt    = 0;\r
+    GU8  uchSlotAdcIndex   = 0;\r
+    GU8  uchBgCancelValue  = 0;\r
+    GU8  uchGainValue      = 0;\r
+    GU16 usBgCancelRegData = 0;\r
+    GU16 usBgCancelRegAddr = 0;    \r
+    GU16 usTiaGainRegData  = 0;\r
+    GU16 usTiaGainRegAddr  = 0;    \r
+\r
+    GH3X2X_WAIT_CHIP_WAKEUP();\r
+    usBgCancelRegAddr = GH3X2X_SLOT0_CTRL_8_REG_ADDR;\r
+    usTiaGainRegAddr  = GH3X2X_SLOT0_CTRL_4_REG_ADDR;\r
+    for (uchSlotIndexCnt = 0; uchSlotIndexCnt < GH3X2X_MAX_SLOT_NUM; uchSlotIndexCnt++)\r
+    {\r
+        usBgCancelRegData = GH3X2X_ReadReg(usBgCancelRegAddr);\r
+        usTiaGainRegData  = GH3X2X_ReadReg(usTiaGainRegAddr);\r
+        for (uchAdcIndexCnt = 0; uchAdcIndexCnt < GH3X2X_ADC_NUM; uchAdcIndexCnt++)\r
+        {\r
+            uchBgCancelValue = (usBgCancelRegData >> (uchAdcIndexCnt * GH3X2X_ADC_BG_CANCEL_BIT_NUM)) \\r
+                                & GH3X2X_ADC_BG_CANCEL_BIT_MASK;\r
+            uchGainValue     = (usTiaGainRegData >> (uchAdcIndexCnt * GH3X2X_ADC_TIA_GAIN_BIT_NUM)) \\r
+                                & GH3X2X_ADC_TIA_GAIN_BIT_MASK;\r
+            g_puchGainBgCancelRecord[uchSlotAdcIndex] = (GU8)(uchBgCancelValue << \\r
+                                                                GH3X2X_ADC_BG_CANCEL_LEFT_SHIFT_BIT_NUM);\r
+            g_puchGainBgCancelRecord[uchSlotAdcIndex] |= (GU8)(uchGainValue << GH3X2X_ADC_TIA_GAIN_LEFT_SHIFT_BIT_NUM);\r
+            uchSlotAdcIndex++;\r
+        }\r
+        usBgCancelRegAddr += SLOT_ADDR_OFFSET;\r
+        usTiaGainRegAddr  += SLOT_ADDR_OFFSET;\r
+    }\r
+    GH3X2X_WAIT_CHIP_DSLP();\r
+}\r
+*/\r
+\r
+/**\r
+ * @fn     void GH3X2X_RecordDrvCurrentValue(void)\r
+ *\r
+ * @brief  read current value of drv0 and drv1, and save them\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_RecordDrvCurrentValue(void)\r
+{\r
+    GU8  uchSlotIndexCnt  = 0;\r
+    GU16 usDrv0CurRegData = 0;\r
+    GU16 usDrv0CurRegAddr = 0;    \r
+    GU16 usDrv1CurRegData = 0;\r
+    GU16 usDrv1CurRegAddr = 0;\r
+\r
+    if ((GH3X2X_CHECK_LEFT_BIT_NOT_SET(g_usDumpMode, GH3X2X_DUMP_GAIN_CURRENT_ENABLE_BIT)) && \\r
+        (GH3X2X_CHECK_LEFT_BIT_NOT_SET(g_usDumpMode, GH3X2X_DUMP_AMBIANCE_ENABLE_BIT)))\r
+    {\r
+        GH3X2X_WAIT_CHIP_WAKEUP();\r
+        usDrv0CurRegAddr = GH3X2X_SLOT0_CTRL_10_REG_ADDR;\r
+        usDrv1CurRegAddr = GH3X2X_SLOT0_CTRL_11_REG_ADDR;\r
+        for (uchSlotIndexCnt = 0; uchSlotIndexCnt < GH3X2X_MAX_SLOT_NUM; uchSlotIndexCnt++)\r
+        {\r
+            usDrv0CurRegData = (GH3X2X_ReadReg(usDrv0CurRegAddr + (uchSlotIndexCnt * GH3X2X_SLOT_CTRL_OFFSET)) & GH3X2X_DRV_CURRENT_BIT_MASK);\r
+            usDrv1CurRegData = (GH3X2X_ReadReg(usDrv1CurRegAddr + (uchSlotIndexCnt * GH3X2X_SLOT_CTRL_OFFSET)) & GH3X2X_DRV_CURRENT_BIT_MASK);\r
+                                               g_pstGh3x2xAgcInfo->uchDrvCurrentRecord[uchSlotIndexCnt] =  (GU16)(usDrv0CurRegData << GH3X2X_DRV0_CURRENT_LEFT_SHIFT_BIT_NUM);\r
+            g_pstGh3x2xAgcInfo->uchDrvCurrentRecord[uchSlotIndexCnt] |= (GU16)(usDrv1CurRegData << GH3X2X_DRV1_CURRENT_LEFT_SHIFT_BIT_NUM);\r
+        }\r
+        GH3X2X_WAIT_CHIP_DSLP();\r
+    }\r
+}\r
+\r
+/**\r
+ * @fn     void GH3X2X_RecordDumpData(void)\r
+ *\r
+ * @brief  read some dump data, and save them\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_RecordDumpData(void)\r
+{\r
+    GH3X2X_RecordDrvCurrentValue();\r
+}\r
+\r
+/**\r
+ * @fn     void GH3X2X_UpdateAgcInfo(void)\r
+ *\r
+ * @brief  record tia gain and drv information\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_UpdateAgcInfo(void)\r
+{\r
+    GH3X2X_Memcpy(g_pstGh3x2xAgcInfo->uchTiaGainRecord, g_pstGh3x2xAgcInfo->uchTiaGainAfterSoftAgc, sizeof(g_pstGh3x2xAgcInfo->uchTiaGainRecord));\r
+    GH3X2X_Memcpy(g_pstGh3x2xAgcInfo->uchDrvCurrentRecord, g_pstGh3x2xAgcInfo->uchDrvCurrentAfterSoftAgc, sizeof(g_pstGh3x2xAgcInfo->uchDrvCurrentRecord));\r
+    GH3X2X_DEBUG_LOG_PARAM("RecordTiaGainInfo slot0: rx0 = %d, rx1 = %d, rx2 = %d, rx3 = %d\r\n" ,g_pstGh3x2xAgcInfo->uchTiaGainRecord[0],g_pstGh3x2xAgcInfo->uchTiaGainRecord[1],g_pstGh3x2xAgcInfo->uchTiaGainRecord[2],g_pstGh3x2xAgcInfo->uchTiaGainRecord[3]);    \r
+    GH3X2X_DEBUG_LOG_PARAM("uchDrvCurrentRecord slot0: drv = %d\r\n" ,g_pstGh3x2xAgcInfo->uchDrvCurrentRecord[0]);    \r
+}\r
+\r
+\r
+#if GH3X2X_DUMP_MODE_EN \r
+\r
+/// dump data cnt map @ref EMGh3x2xDumpRawdataBgLvlSelect\r
+const GU8 g_uchDumpDataCntMapArr[] = \r
+{\r
+    2, // lvl 0\r
+    3, // lvl 1\r
+    4, // lvl 2\r
+    2  // lvl 2x2  /* regard the second slot of 2x2 as a separate slot*/\r
+};\r
+\r
+/// div num of dump data map @ref EMGh3x2xDumpRawdataBgLvlSelect\r
+const GU8 g_uchRawdataDivOfDumpDataMapArr[] = \r
+{\r
+    1, // lvl 0\r
+    1, // lvl 1\r
+    2, // lvl 2\r
+    2  // lvl 2x2\r
+};\r
+\r
+/// rawdata index of dump data map @ref EMGh3x2xDumpRawdataBgLvlSelect\r
+const GU8 g_uchRawdataIndexOfDumpDataMapArr[] = \r
+{\r
+    1, // lvl 0\r
+    2, // lvl 1\r
+    2, // lvl 2\r
+    0  // lvl 2x2\r
+};\r
+\r
+\r
+\r
+/// bg level\r
+GU16 g_usBgLevel;\r
+\r
+/// hbd rawdata incomplete array\r
+GU8 g_uchHbaIncompleteArr[GH3X2X_HBA_CHANNEL_MAP_MAX_CNT];\r
+\r
+/// hbd dumpdata incomplete buffer\r
+GU32 g_unHbaIncompleteDumpdataArr[GH3X2X_HBA_CHANNEL_MAP_MAX_CNT][GH3X2X_MAX_DUMP_DATA_NUM_CHANNEL] = {{0}};\r
+\r
+/// hrv rawdata incomplete array\r
+GU8 g_uchHrvIncompleteArr[GH3X2X_HRV_CHANNEL_MAP_MAX_CNT];\r
+\r
+/// hrv dumpdata incomplete buffer\r
+GU32 g_unHrvIncompleteDumpdataArr[GH3X2X_HRV_CHANNEL_MAP_MAX_CNT][GH3X2X_MAX_DUMP_DATA_NUM_CHANNEL] = {{0}};\r
+\r
+/// spo2 rawdata incomplete array\r
+GU8 g_uchSpo2IncompleteArr[GH3X2X_SPO2_CHANNEL_MAP_MAX_CNT];\r
+\r
+/// spo2 dumpdata incomplete buffer\r
+GU32 g_unSpo2IncompleteDumpdataArr[GH3X2X_SPO2_CHANNEL_MAP_MAX_CNT][GH3X2X_MAX_DUMP_DATA_NUM_CHANNEL] = {{0}};\r
+\r
+/// dump data after filter from rawdata which will be uploaded\r
+GU32 g_punDumpDataUploadArr[GH3X2X_MAX_DUMP_DATA_NUM_UPLOAD] = {0};\r
+\r
+\r
+\r
+/// incomplete rawdata flag array for filter data\r
+GU8 g_uchDumpIncompleteFlagArr[GH3X2X_CHANNEL_MAP_MAX_CH];\r
+\r
+/// incomplete rawdata buffer for filter data\r
+GU32 g_unDumpIncompleteRawdataArr[GH3X2X_CHANNEL_MAP_MAX_CH][GH3X2X_MAX_DUMP_DATA_NUM_CHANNEL] = {{0}};\r
+\r
+/// save rawdata after filter\r
+GU8 g_uchRawdataFilterArr[RAWDATA_FILTER_ARRAY_BYTE_LENGTH];\r
+\r
+/// bg level of every channel\r
+GU8 g_uchChannelBgLvlArr[GH3X2X_CHANNEL_MAP_MAX_CH];\r
+\r
+/// save slot which used for ECG\r
+GU8 g_uchEcgSlot;\r
+\r
+// Zipdumpmode Tempdata\r
+STZipLastDataTemp g_stZipDumpTempData;\r
+\r
+//  Zip Package Num Even/Odd Flag\r
+GU8 g_uchDumpOddEvenChangeFlag = 1;\r
+\r
+\r
+\r
+\r
+\r
+\r
+/**\r
+ * @fn     void GH3X2X_ReadElectrodeWearDumpData(void)\r
+ *\r
+ * @brief  read eletrode wear status\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  dump mode\r
+ */\r
+ /*\r
+void GH3X2X_ReadElectrodeWearDumpData(void)\r
+{\r
+    if (GH3X2X_CHECK_LEFT_BIT_SET(g_usDumpMode, GH3X2X_DUMP_ELECTR_WEAR_ENABLE_BIT))\r
+    {\r
+        GH3X2X_WAIT_CHIP_WAKEUP();\r
+        g_uchElectrodeWearStatus = GH3X2X_ReadRegBitField(GH3X2X_INT_STR2_REG_ADDR, \\r
+                                    GH3X2X_ELECTR_WEAR_STATUS_BIT_FIELD, GH3X2X_ELECTR_WEAR_STATUS_BIT_FIELD);\r
+        GH3X2X_WAIT_CHIP_DSLP();\r
+    }\r
+}\r
+*/\r
+\r
+\r
+\r
+\r
+\r
+/**\r
+ * @fn     void GH3X2X_BgLevelDecode(GU8 puchBgLvArr[], GU8 uchChannelCnt, GU8 *puchChannelMapArray, GU16 usBgLevel)\r
+ *\r
+ * @brief  decode function's bg level array according to channel map and slot bg level\r
+ *\r
+ * @attention   if there is 2x2 bg level,set the first slot to level 2\r
+ *\r
+ * @param[in]   uchChannelCnt                channel cnt\r
+ * @param[in]   puchChannelMapArray          channel map array\r
+ * @param[in]   usBgLevel                    bg level of slot\r
+ * @param[out]  puchBgLvArray                bg level array\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_BgLevelDecode(GU8 puchBgLvArr[], GU8 uchChannelCnt, GU8 *puchChannelMapArray, GU16 usBgLevel)\r
+{\r
+    GU8 uchChCnt      = 0;\r
+    GU8 uchSlotCnt    = 0;\r
+    GU8 uchBgLv2x2Cnt = 0;\r
+    GU8 uchSlotNum    = 0;\r
+    GU16 usBgLvTemp = usBgLevel;\r
+\r
+    //if BgLevel has level 2x2,change the first slot of 2x2 slot to level 2\r
+    for (uchSlotCnt = 0; uchSlotCnt < GH3X2X_MAX_SLOT_NUM; uchSlotCnt++)\r
+    {\r
+        if (GH3X2X_DUMP_RAWDATA_BGLVL2X2 == ((usBgLevel >> (uchSlotCnt << 1)) & GH3X2X_SLOT_BG_LEVEL_BIT_MASK))\r
+        {\r
+            if (0 == uchBgLv2x2Cnt)\r
+            {\r
+                uchBgLv2x2Cnt++;\r
+            }\r
+            else\r
+            {\r
+                //set last slot bg level as GH3X2X_DUMP_RAWDATA_BGLVL2\r
+                usBgLvTemp &= ~(GH3X2X_SLOT_BG_LEVEL_BIT_MASK << ((uchSlotCnt - 1) << 1));\r
+                usBgLvTemp |= GH3X2X_DUMP_RAWDATA_BGLVL2 << ((uchSlotCnt - 1) << 1);\r
+                uchBgLv2x2Cnt = 0;\r
+            }                \r
+        }\r
+        else\r
+        {\r
+            uchBgLv2x2Cnt = 0;\r
+        }\r
+    }\r
+    \r
+    for (uchChCnt = 0; uchChCnt < uchChannelCnt; uchChCnt++)\r
+    {\r
+        uchSlotNum = GH3X2X_BYTE_RAWDATA_GET_SLOT_NUM(puchChannelMapArray[uchChCnt]);\r
+        puchBgLvArr[uchChCnt] = (usBgLvTemp >> (uchSlotNum << 1)) & GH3X2X_SLOT_BG_LEVEL_BIT_MASK;\r
+    }\r
+}\r
+\r
+/**\r
+ * @fn     void GH3X2X_GetChannelBgLevel(GU16 usBgLevel)\r
+ *\r
+ * @brief  get bg level of every channel\r
+ *\r
+ * @attention   if there is two 2x2 bg level,set the first 2x2 slot to bg level 2\r
+ *\r
+ * @param[in]   usBgLevel                    slot bg level\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_GetChannelBgLevel(GU16 usBgLevel)\r
+{\r
+    GU8 uchSlotCnt           = 0;    \r
+    GU8 uchChBgLvl           = 0;\r
+    GU8 uchBhLvl2x2FirstSlot = 1;\r
+\r
+    GH3X2X_Memset(g_uchChannelBgLvlArr, 0, sizeof(g_uchChannelBgLvlArr[0]) * GH3X2X_CHANNEL_MAP_MAX_CH);\r
+    \r
+    for (uchSlotCnt = 0; uchSlotCnt < GH3X2X_MAX_SLOT_NUM; ++uchSlotCnt)\r
+    {\r
+        uchChBgLvl = (usBgLevel >> (uchSlotCnt << 1)) & GH3X2X_SLOT_BG_LEVEL_BIT_MASK;\r
+        if (GH3X2X_DUMP_RAWDATA_BGLVL2X2 == uchChBgLvl)\r
+        {\r
+            if (uchBhLvl2x2FirstSlot)\r
+            {\r
+                uchChBgLvl = GH3X2X_DUMP_RAWDATA_BGLVL2;\r
+                uchBhLvl2x2FirstSlot = 0;\r
+            }\r
+            else\r
+            {\r
+                uchBhLvl2x2FirstSlot = 1;\r
+            }\r
+        }\r
+        else\r
+        {\r
+            if (0 == uchBhLvl2x2FirstSlot)\r
+            {\r
+                GH3X2X_DEBUG_LOG_PARAM("%s 2x2 Bg Level set error.\r\n", __FUNCTION__);\r
+                uchBhLvl2x2FirstSlot = 1;\r
+            }            \r
+        }\r
+\r
+        GH3X2X_Memset(&g_uchChannelBgLvlArr[uchSlotCnt * GH3X2X_ADC_NUM], uchChBgLvl, \\r
+                    sizeof(g_uchChannelBgLvlArr[0]) * GH3X2X_ADC_NUM);\r
+    }\r
+}\r
+\r
+/**\r
+ * @fn     void GH3X2X_BgLevelSet(GU16 usRegVal)\r
+ *\r
+ * @brief  set bg level of every slot\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   usRegVal          reg value\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_BgLevelSet(GU16 usRegVal)\r
+{\r
+    g_usBgLevel = usRegVal;\r
+}\r
+\r
+/**\r
+ * @fn     void GH3X2X_GetEcgSlot(void)\r
+ *\r
+ * @brief  get slot used for ecg\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_GetEcgSlot(void)\r
+{\r
+    GU16 usEcgEnRegData  = 0;\r
+    GU16 usEcgEnRegAddr  = 0;\r
+    GU8  uchSlotIndexCnt = 0;\r
+\r
+    GH3X2X_WAIT_CHIP_WAKEUP();\r
+    g_uchEcgSlot = 0;\r
+    usEcgEnRegAddr = GH3X2X_SLOT0_CTRL_0_REG_ADDR;    \r
+    for (uchSlotIndexCnt = 0; uchSlotIndexCnt < GH3X2X_MAX_SLOT_NUM; ++uchSlotIndexCnt)\r
+    {\r
+        usEcgEnRegData = GH3X2X_ReadReg(usEcgEnRegAddr);\r
+        if (GH3X2X_CHECK_BIT_SET(usEcgEnRegData, GH3X2X_ECG_ENABLE_BIT))\r
+        {\r
+            GH3X2X_VAL_SET_BIT(g_uchEcgSlot, (GU16)GH3X2X_GET_LEFT_SHIFT_VAL(uchSlotIndexCnt));\r
+        }\r
+        usEcgEnRegAddr += SLOT_ADDR_OFFSET;\r
+    }\r
+    GH3X2X_WAIT_CHIP_DSLP();\r
+}\r
+\r
+/**\r
+ * @fn     void GH3X2X_DumpInit(void)\r
+ *\r
+ * @brief  init dump moudle\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_DumpInit(void)\r
+{\r
+    //if dump mode is not enable,just return\r
+    if (GH3X2X_CHECK_LEFT_BIT_NOT_SET(g_usDumpMode, GH3X2X_DUMP_GAIN_CURRENT_ENABLE_BIT) && \\r
+        GH3X2X_CHECK_LEFT_BIT_NOT_SET(g_usDumpMode, GH3X2X_DUMP_AMBIANCE_ENABLE_BIT))\r
+    {\r
+        return;\r
+    }\r
+\r
+    //when dump mode and agc are both enabled,should do this  \r
+    //if (GH3X2X_LED_AGC_ENABLE == GH3X2X_GetLedAgcState())\r
+    {\r
+        GH3X2X_Memset(g_uchDumpIncompleteFlagArr, 0, \\r
+                        sizeof(g_uchDumpIncompleteFlagArr[0]) * GH3X2X_CHANNEL_MAP_MAX_CH);\r
+        GH3X2X_GetChannelBgLevel(g_usBgLevel);\r
+        GH3X2X_GetEcgSlot();\r
+    }\r
+}\r
+\r
+/**\r
+ * @fn     GU8 GH3X2X_FindLastSlotChMapIndex(GU8* puchTargetChMapIndex, GU8 puchChMapArr[], \r
+                                                 GU8 uchChMapCnt,GU8 uchChMapIndex)\r
+ *\r
+ * @brief  Find target channel map index which slot id minus 1 than input channel map\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[out]  puchTargetChMapIndex            target channel map index\r
+ * @param[in]   puchChMapArr[]                  channel map array\r
+ * @param[in]   uchChMapCnt                     channel map cnt\r
+ * @param[in]   uchChCntIndex                   channel cnt index\r
+ *\r
+ * @return  error code\r
+ * @retval  #GH3X2X_RET_OK                      return successfully\r
+ * @retval  #GH3X2X_RET_PARAMETER_ERROR         return param error\r
+ */\r
+GS8 GH3X2X_FindLastSlotChMapIndex(GU8* puchTargetChMapIndex, GU8 puchChMapArr[], GU8 uchChMapCnt, GU8 uchChCntIndex)\r
+{\r
+    GU8 uchSlotNum;\r
+    GU8 uchSlotNumTemp;\r
+    GU8 uchAdcNum;\r
+    GU8 uchAdcNumTemp;\r
+    GU8 i;\r
+    GS8 chRet = GH3X2X_RET_OK;\r
+\r
+    if (GH3X2X_PTR_NULL == puchTargetChMapIndex)\r
+    {\r
+        return GH3X2X_RET_PARAMETER_ERROR;\r
+    }\r
+    \r
+    uchSlotNum = GH3X2X_BYTE_RAWDATA_GET_SLOT_NUM(puchChMapArr[uchChCntIndex]);\r
+    uchAdcNum  = GH3X2X_BYTE_RAWDATA_GET_ADC_NUM(puchChMapArr[uchChCntIndex]);\r
+    \r
+    for (i = 0; i < uchChMapCnt; i++)\r
+    {\r
+        uchSlotNumTemp = GH3X2X_BYTE_RAWDATA_GET_SLOT_NUM(puchChMapArr[i]);\r
+        uchAdcNumTemp  = GH3X2X_BYTE_RAWDATA_GET_ADC_NUM(puchChMapArr[i]);\r
+        if ((uchSlotNumTemp == (uchSlotNum - 1)) && (uchAdcNumTemp == uchAdcNum))\r
+        {\r
+            *puchTargetChMapIndex = i;\r
+            break;\r
+        }\r
+    }\r
+\r
+    if (i >= uchChMapCnt)\r
+    {\r
+        *puchTargetChMapIndex = uchChCntIndex;\r
+        GH3X2X_DEBUG_LOG_PARAM("Find channel map error!!!can not find last slot channel map\r\n");\r
+        chRet = GH3X2X_RET_PARAMETER_ERROR;\r
+    }\r
+\r
+    return chRet;\r
+}\r
+\r
+/**\r
+ * @fn     void GH3X2X_CacheIncompleteDumpdata(GU8 punLastIncompleteArr[], \r
+ *                                   GU32 punIncompleteDumpdataArr[][GH3X2X_MAX_DUMP_DATA_NUM_CHANNEL],\r
+ *                                   GU8  uchNextIncompleteFlag, GU8 *puchFifoRawdata, GU16 usFifoRawdataLen,\r
+ *                                   GU8 uchChannelMapArr[], GU8 uchChannelMapCnt,\r
+ *                                   GU16 usRawdataByteIndexArr[GH3X2X_CHANNEL_MAP_MAX_CH])\r
+ *\r
+ * @brief  cache incomplete rawdata packet for algorithm\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[out]  puchIncompleteFlagArr       incomplete flag array of every channel\r
+ * @param[out]  punIncompleteDumpdataArr    incomplete data array\r
+ * @param[in]   uchNextIncompleteFlag       incomplete flag to indicate if cache incomplete data\r
+ * @param[in]   puchFifoRawdata             fifo rawdata\r
+ * @param[in]   usFifoRawdataLen            fifo data length\r
+ * @param[in]   uchChannelMapArr            channel map array\r
+ * @param[in]   uchChannelMapCnt            channel map array cnt\r
+ * @param[in]   usRawdataByteIndexArr       start index of every channel to search data\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_CacheIncompleteDumpdata(GU8 puchIncompleteFlagArr[], \r
+                            GU32 punIncompleteDumpdataArr[][GH3X2X_MAX_DUMP_DATA_NUM_CHANNEL],\r
+                            GU8  uchNextIncompleteFlag, GU8 *puchFifoRawdata, GU16 usFifoRawdataLen,\r
+                            GU8 uchChannelMapArr[], GU8 uchChannelMapCnt,\r
+                            GU16 usRawdataByteIndexArr[GH3X2X_CHANNEL_MAP_MAX_CH])\r
+{\r
+    GU16 usRawdataByteIndexTmp = 0;\r
+    GU8  uchChCntIndex         = 0;\r
+    GU8  uchDumpDataIndexArr[GH3X2X_CHANNEL_MAP_MAX_CH] = {0};\r
+    \r
+    GH3X2X_Memset(puchIncompleteFlagArr, 0, sizeof(puchIncompleteFlagArr[0]) * GH3X2X_CHANNEL_MAP_MAX_CH);\r
+    \r
+    if (uchNextIncompleteFlag != 0)\r
+    {\r
+        for (uchChCntIndex = 0; uchChCntIndex < uchChannelMapCnt; uchChCntIndex++) // search each channel\r
+        {\r
+            usRawdataByteIndexTmp = usRawdataByteIndexArr[uchChCntIndex];\r
+            while (usRawdataByteIndexTmp < usFifoRawdataLen) // search each\r
+            {\r
+                if (GH3X2X_CHANNEL_MAP_GET(puchFifoRawdata[usRawdataByteIndexTmp]) == \\r
+                                                            uchChannelMapArr[uchChCntIndex]) // if map equal\r
+                {\r
+                    GH3X2X_Memcpy(&punIncompleteDumpdataArr[uchChCntIndex][uchDumpDataIndexArr[uchChCntIndex]],\r
+                                    &puchFifoRawdata[usRawdataByteIndexTmp], GH3X2X_FIFO_RAWDATA_SIZE);\r
+                    puchIncompleteFlagArr[uchChCntIndex] |= \\r
+                                        (GU8)GH3X2X_GET_LEFT_SHIFT_VAL(uchDumpDataIndexArr[uchChCntIndex]);\r
+                    uchDumpDataIndexArr[uchChCntIndex]++;\r
+                }\r
+                usRawdataByteIndexTmp += GH3X2X_FIFO_RAWDATA_SIZE;\r
+            }\r
+        }\r
+    }\r
+}\r
+\r
+/**\r
+ * @fn     GS8 GH3X2X_GetDumpDataInfo(GF32 *pfGsFloatIncVal, GU16 *pusChannelDataCnt,\r
+ *                                GU8 *puchNextIncompleteFlag,GU8 *puchDumpDataIndexArr,\r
+ *                                GU8 *puchIncompleteFlagArr, GU16 usFifoLength, GU8 *puchDataBuffer,\r
+ *                                GU8 uchChannelCnt, GU8 *puchChannelMapArray, GU8 *puchChannelBgLvlArr, \r
+ *                                GU16 usReadGsensorArrCnt)\r
+ *\r
+ * @brief  Get information from rawdata\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[out]  pfGsFloatIncVal             pointer to gsensor inc value output\r
+ * @param[out]  pusChannelDataCnt           pointer to slot data cnt output\r
+ * @param[out]  puchNextIncompleteFlag      pointer to next incomplete flag arr output\r
+ * @param[out]  puchDumpDataIndexArr        pointer to dump data index output\r
+ * @param[in]   puchIncompleteFlagArr       incomplete flag array of last rawdata frame\r
+ * @param[in]   usFifoLength                read fifo buffer data len\r
+ * @param[in]   puchDataBuffer              pointer to read fifo buffer\r
+ * @param[in]   uchChannelCnt               channel map arr cnt\r
+ * @param[in]   puchChannelMapArray         pointer to channel map arr\r
+ * @param[in]   puchChannelBgLvlArr         pointer to bg lvl arr\r
+ * @param[in]   usReadGsensorArrCnt         read gsensor array cnt\r
+ *\r
+ * @return  error code\r
+ * @retval  #GH3X2X_RET_OK               return successfully\r
+ * @retval  #GH3X2X_RET_GENERIC_ERROR    generic error when size is 0\r
+ * @retval  #GH3X2X_RET_RESOURCE_ERROR   resource error when doesn't correspond to channel map\r
+ */\r
+GS8 GH3X2X_GetDumpDataInfo(GF32 *pfGsFloatIncVal, GU16 *pusChannelDataCnt,\r
+                                GU8 *puchNextIncompleteFlag, GU8 *puchDumpDataIndexArr,\r
+                                GU8 *puchIncompleteFlagArr, GU16 usFifoLength, GU8 *puchDataBuffer,\r
+                                GU8 uchChannelCnt, GU8 *puchChannelMapArray, GU8 *puchChannelBgLvlArr, \r
+                                GU16 usReadGsensorArrCnt)\r
+{\r
+    GF32 fGsensorFloatIncTmp = GH3X2X_GF32_0;\r
+    GU16 usRawdataCntArr[GH3X2X_CHANNEL_MAP_MAX_CH] = {0};\r
+    GU16 usRawdataCntTmp    = 0;\r
+    GU16 usRawdataCntMaxTmp = 0;\r
+    GU16 usRawdataCntMinTmp = 0;\r
+    GU16 usRawdataAllCntMax = 0;\r
+    GU8  uchChCntIndexTmp   = 0;\r
+    GU8  uchCalcCntIndexTmp = 0;\r
+    GU8  uchDumpDataCalcTmp = 0;\r
+    GU16 usRawdataIndexTmp  = 0;\r
+    GU8  uchDumpDataCntCalcErrFlag = 0;\r
+    GU8 uchNextIncompleteFlagTmp   = 0;\r
+    GU16 usDumpDataCntArr[DUMP_DATA_MAX_NUM] = {0};\r
+    GS8  chRet = GH3X2X_RET_GENERIC_ERROR;\r
+\r
+    if ((pfGsFloatIncVal == GH3X2X_PTR_NULL) || (pusChannelDataCnt == GH3X2X_PTR_NULL)\r
+        || (puchNextIncompleteFlag == GH3X2X_PTR_NULL) || (puchDumpDataIndexArr == GH3X2X_PTR_NULL)\r
+        || (puchIncompleteFlagArr == GH3X2X_PTR_NULL) || (puchDataBuffer == GH3X2X_PTR_NULL)\r
+        || (puchChannelMapArray == GH3X2X_PTR_NULL) || (puchChannelBgLvlArr == GH3X2X_PTR_NULL))\r
+    {\r
+        return GH3X2X_RET_PARAMETER_ERROR;\r
+    }\r
+\r
+    for (uchChCntIndexTmp = 0; uchChCntIndexTmp < uchChannelCnt; uchChCntIndexTmp++)\r
+    {\r
+        GH3X2X_Memset(usDumpDataCntArr, 0, sizeof(GU16) * DUMP_DATA_MAX_NUM);\r
+        uchCalcCntIndexTmp = 0;\r
+        uchDumpDataCalcTmp = g_uchDumpDataCntMapArr[puchChannelBgLvlArr[uchChCntIndexTmp]];\r
+        for (usRawdataIndexTmp = 0; usRawdataIndexTmp < uchDumpDataCalcTmp; usRawdataIndexTmp ++)\r
+        {\r
+            if (GH3X2X_CHECK_LEFT_BIT_SET(puchIncompleteFlagArr[uchChCntIndexTmp], uchCalcCntIndexTmp))\r
+            {\r
+                usDumpDataCntArr[uchCalcCntIndexTmp]++;\r
+                uchCalcCntIndexTmp++;\r
+                puchDumpDataIndexArr[uchChCntIndexTmp]++; // calc start index for get data\r
+            }\r
+        }\r
+        for (usRawdataIndexTmp = 0; usRawdataIndexTmp < usFifoLength; usRawdataIndexTmp += GH3X2X_FIFO_RAWDATA_SIZE)\r
+        {\r
+            if (puchChannelMapArray[uchChCntIndexTmp] == GH3X2X_CHANNEL_MAP_GET(puchDataBuffer[usRawdataIndexTmp]))\r
+            {\r
+                usDumpDataCntArr[uchCalcCntIndexTmp%uchDumpDataCalcTmp]++;\r
+                uchCalcCntIndexTmp++;\r
+            }\r
+        }\r
+        GH3X2X_FindGu16MaxMinVal(&usRawdataCntMaxTmp, &usRawdataCntMinTmp, usDumpDataCntArr, uchDumpDataCalcTmp);\r
+        if (usRawdataAllCntMax < usRawdataCntMaxTmp)\r
+        {\r
+            usRawdataAllCntMax = usRawdataCntMaxTmp; // calc all data cnt max \r
+        }\r
+        if (usRawdataCntMinTmp == usRawdataCntMaxTmp)\r
+        {\r
+            usRawdataCntArr[uchChCntIndexTmp] = usRawdataCntMinTmp;\r
+        }\r
+        else\r
+        {\r
+            for (usRawdataIndexTmp = 0; usRawdataIndexTmp < (uchDumpDataCalcTmp - 1); usRawdataIndexTmp ++) // checkcnt\r
+            {\r
+                if (usDumpDataCntArr[usRawdataIndexTmp] < usDumpDataCntArr[usRawdataIndexTmp + 1]) // if next>this, err\r
+                {\r
+                    uchDumpDataCntCalcErrFlag = 1;\r
+                    break;\r
+                }\r
+            }\r
+            if (uchDumpDataCntCalcErrFlag == 0)\r
+            {\r
+                usRawdataCntArr[uchChCntIndexTmp] = usRawdataCntMinTmp;\r
+                uchNextIncompleteFlagTmp = 1;\r
+            }\r
+            else\r
+            {\r
+                GH3X2X_DEBUG_LOG_PARAM("dump data of buffer error!\r\n");\r
+                break;\r
+            }\r
+        }\r
+    } // end of for (uchChCntIndexTmp = 0; uchChCntIndexTmp < uchChannelCnt; uchChCntIndexTmp++)\r
+    if (uchDumpDataCntCalcErrFlag == 0)\r
+    {\r
+        GH3X2X_FindGu16MaxMinVal(&usRawdataCntMaxTmp, &usRawdataCntMinTmp, usRawdataCntArr, uchChannelCnt);\r
+        if (usRawdataCntMaxTmp == usRawdataCntMinTmp)\r
+        {\r
+            usRawdataCntTmp = usRawdataCntMaxTmp; // whatever last data complete or incomplete\r
+        }\r
+        else\r
+        {\r
+            if (((usRawdataCntMaxTmp - usRawdataCntMinTmp) == 1) && (usRawdataAllCntMax == usRawdataCntMaxTmp))\r
+            {\r
+                usRawdataCntTmp = usRawdataCntMinTmp;\r
+                uchNextIncompleteFlagTmp = 1;\r
+            }\r
+            else // cnt tolerable deviation is 1\r
+            {\r
+                GH3X2X_DEBUG_LOG_PARAM("dump data doesn't correspond to channel map error!\r\n");\r
+                usRawdataCntTmp = 0;\r
+                uchNextIncompleteFlagTmp = 0;\r
+                chRet = GH3X2X_RET_RESOURCE_ERROR;\r
+            }\r
+        } // end of if (usRawdataCntMaxTmp == usRawdataCntMinTmp)\r
+\r
+        if (usRawdataCntTmp > 0)\r
+        {\r
+            chRet = GH3X2X_RET_OK;\r
+            if ((usRawdataCntTmp > 1) && (usReadGsensorArrCnt > 0)) // calc gs index\r
+            {\r
+                fGsensorFloatIncTmp = ((GF32)(usReadGsensorArrCnt - 1)) / (usRawdataCntTmp - 1);\r
+            }\r
+        }\r
+    } // end of if (uchDumpDataCntCalcErrFlag == 0)\r
+    SET_VAL_VIA_PTR(pfGsFloatIncVal, fGsensorFloatIncTmp); // set gsensor increasing val\r
+    SET_VAL_VIA_PTR(pusChannelDataCnt, usRawdataCntTmp); // channel data count\r
+    SET_VAL_VIA_PTR(puchNextIncompleteFlag, uchNextIncompleteFlagTmp); // channel data count max\r
+    return chRet;\r
+}\r
+\r
+/**\r
+ * @fn     GS8 GH3X2X_UnpackDumpDataWithChannelMap(STGh3x2xChannelDumpData *pstGh3x2xChannelDumpData,\r
+ *                    GU8 *puchReadRawdataBuffer, GU16 usReadRawdataLen, GU8 uchChannelMapCnt, GU8 *puchChannelMapArr,\r
+ *                    GU8 *puchChannelBgLvlArr)\r
+ *\r
+ * @brief  Unpack to channel dump data from read fifo data buffer;\r
+ *         if dump data incomplete, should change fifo watermark\r
+ *\r
+ * @attention   This function should use in get rawdata hook\r
+ * \r
+ * @param[in]   puchReadRawdataBuffer           pointer to read data buffer\r
+ * @param[in]   usReadRawdataLen                read data length\r
+ * @param[in]   uchChannelMapCnt                channel map array cnt, max:32\r
+ * @param[in]   puchChannelMapArr               pointer to channel map array\r
+ * @param[in]   puchChannelBgLvlArr             pointer to channel lvl array, @ref EMGh3x2xDumpRawdataBgLvlSelect\r
+ * @param[out]  pstGh3x2xChannelDumpData        pointer to channel rawdata struct\r
+ *\r
+ * @return  error code\r
+ * @retval  #GH3X2X_RET_OK                      return successfully\r
+ * @retval  #GH3X2X_RET_PARAMETER_ERROR         return param error\r
+ */\r
+GS8 GH3X2X_UnpackDumpDataWithChannelMap(STGh3x2xChannelDumpData *pstGh3x2xChannelDumpData,\r
+                    GU8 *puchReadRawdataBuffer, GU16 usReadRawdataLen, GU8 uchChannelMapCnt, GU8 *puchChannelMapArr,\r
+                    GU8 *puchChannelBgLvlArr)\r
+{\r
+    GU8  uchChCntIndex = 0;\r
+    GU16 usRawdataIndex = 0;\r
+    GU16 usRawdataCnt = 0;\r
+    GU16 usRawdataIndexArr[GH3X2X_CHANNEL_MAP_MAX_CH] = {0}; // use for rawdata cnt & rawdata bytes index\r
+    GU16 usRawdataByteIndexTmp = 0;\r
+    GU16 usRawdataBaseIndex = 0;\r
+    GU8  uchCalcCntIndex = 0;\r
+    GU8  uchDumpDataCalcTmp = 0;\r
+    GU8 uchNextIncompleteFlag = 0;\r
+    GU8 uchDumpDataIndexArr[GH3X2X_CHANNEL_MAP_MAX_CH] = {0};\r
+    GU32 unRawdataSum = 0;\r
+    GF32 fGsensorFloatIndexInc = GH3X2X_GF32_0;\r
+    GU8 uchLastSlotChIndex = 0;\r
+    GS8 chRet = GH3X2X_RET_OK;\r
+    \r
+    GH3X2X_DEBUG_LOG_PARAM("%s\r\n", __FUNCTION__);\r
+\r
+    /* check pram */\r
+    if ((pstGh3x2xChannelDumpData->punIncompleteChRawdataArr == GH3X2X_PTR_NULL)\r
+        || (pstGh3x2xChannelDumpData->punChBgRawdataArr == GH3X2X_PTR_NULL)\r
+        || (pstGh3x2xChannelDumpData->punChRawdataArr == GH3X2X_PTR_NULL)\r
+        || (pstGh3x2xChannelDumpData->punPkgNoAndCurrentArr == GH3X2X_PTR_NULL)\r
+        || (puchReadRawdataBuffer == GH3X2X_PTR_NULL)\r
+        || (puchChannelBgLvlArr == GH3X2X_PTR_NULL)\r
+        || (pstGh3x2xChannelDumpData == GH3X2X_PTR_NULL) || (puchChannelMapArr == GH3X2X_PTR_NULL))\r
+    {\r
+        GH3X2X_DEBUG_LOG_PARAM("pointer param set null error!\r\n");\r
+        return GH3X2X_RET_PARAMETER_ERROR;\r
+    }\r
+    for (uchChCntIndex = 0; uchChCntIndex < uchChannelMapCnt; uchChCntIndex++)\r
+    {\r
+        if (GH3X2X_CLEAR_BIT(puchChannelMapArr[uchChCntIndex], GH3X2X_SLOT_ADC_NUM_BITS) != 0)\r
+        {\r
+            GH3X2X_DEBUG_LOG_PARAM("channel map error! set @ref GH3X2X_CHANNEL_MAP!\r\n");\r
+            return GH3X2X_RET_PARAMETER_ERROR;\r
+        }\r
+        if (puchChannelBgLvlArr[uchChCntIndex] > GH3X2X_DUMP_RAWDATA_BGLVL2X2)\r
+        {\r
+            GH3X2X_DEBUG_LOG_PARAM("dump lvl error! set @ref EMGh3x2xDumpRawdataBgLvlSelect!\r\n");\r
+            return GH3X2X_RET_PARAMETER_ERROR;\r
+        }\r
+    }\r
+    if (uchChannelMapCnt > GH3X2X_CHANNEL_MAP_MAX_CH)\r
+    {\r
+        GH3X2X_DEBUG_LOG_PARAM("channel cnt greater than max!\r\n");\r
+        return GH3X2X_RET_PARAMETER_ERROR;\r
+    }\r
+\r
+    /* calc rawdata len */\r
+    chRet = GH3X2X_GetDumpDataInfo(&fGsensorFloatIndexInc, &usRawdataCnt, &uchNextIncompleteFlag, uchDumpDataIndexArr, \r
+                        pstGh3x2xChannelDumpData->uchChIncompleteFlagArr, usReadRawdataLen, puchReadRawdataBuffer, \r
+                        uchChannelMapCnt, puchChannelMapArr, puchChannelBgLvlArr, 0);\r
+    if (chRet == GH3X2X_RET_OK)\r
+    {\r
+        for (usRawdataIndex = 0; usRawdataIndex < usRawdataCnt; usRawdataIndex++)\r
+        {\r
+            usRawdataBaseIndex = usRawdataIndex * (GU16)uchChannelMapCnt;\r
+            for (uchChCntIndex = 0; uchChCntIndex < uchChannelMapCnt; uchChCntIndex++) // search each channel\r
+            {\r
+                uchDumpDataCalcTmp = g_uchDumpDataCntMapArr[puchChannelBgLvlArr[uchChCntIndex]];\r
+                if (uchDumpDataIndexArr[uchChCntIndex] < uchDumpDataCalcTmp)\r
+                {\r
+                    usRawdataByteIndexTmp = usRawdataIndexArr[uchChCntIndex];\r
+                    while (usRawdataByteIndexTmp < usReadRawdataLen) // search each\r
+                    {\r
+                        if (GH3X2X_CHANNEL_MAP_GET(puchReadRawdataBuffer[usRawdataByteIndexTmp]) == \\r
+                                                                    puchChannelMapArr[uchChCntIndex]) // if map equal\r
+                        {\r
+                            pstGh3x2xChannelDumpData->punIncompleteChRawdataArr[uchChCntIndex]\\r
+                                                                            [uchDumpDataIndexArr[uchChCntIndex]] = \\r
+                                                GH3X2X_RAWDATA_CLEAR_SLOT_ADC_NUM(\r
+                                                    GH3X2X_MAKEUP_DWORD(puchReadRawdataBuffer[usRawdataByteIndexTmp],\r
+                                                                    puchReadRawdataBuffer[usRawdataByteIndexTmp + 1],\r
+                                                                    puchReadRawdataBuffer[usRawdataByteIndexTmp + 2],\r
+                                                                    puchReadRawdataBuffer[usRawdataByteIndexTmp + 3]));\r
+                            uchDumpDataIndexArr[uchChCntIndex]++;\r
+                            if (uchDumpDataIndexArr[uchChCntIndex] >= uchDumpDataCalcTmp)\r
+                            {\r
+                                usRawdataByteIndexTmp += GH3X2X_FIFO_RAWDATA_SIZE;\r
+                                break;\r
+                            }\r
+                        }\r
+                        usRawdataByteIndexTmp += GH3X2X_FIFO_RAWDATA_SIZE;\r
+                    }\r
+                }                \r
+                uchDumpDataIndexArr[uchChCntIndex] = 0;\r
+\r
+                usRawdataIndexArr[uchChCntIndex] = usRawdataByteIndexTmp; // write back byte index\r
+            } // end of for (uchChCntIndex = 0; uchChCntIndex < uchChannelMapCnt; uchChCntIndex++)\r
+\r
+            for (uchChCntIndex = 0; uchChCntIndex < uchChannelMapCnt; uchChCntIndex++) // process each channel dump data\r
+            {\r
+                if (GH3X2X_DUMP_RAWDATA_BGLVL2X2 != puchChannelBgLvlArr[uchChCntIndex])\r
+                {\r
+                    pstGh3x2xChannelDumpData->punPkgNoAndCurrentArr[usRawdataBaseIndex + uchChCntIndex] = \\r
+                                        pstGh3x2xChannelDumpData->punIncompleteChRawdataArr[uchChCntIndex][0];\r
+                    pstGh3x2xChannelDumpData->punChRawdataArr[usRawdataBaseIndex + uchChCntIndex] = \\r
+                        pstGh3x2xChannelDumpData->punIncompleteChRawdataArr[uchChCntIndex]\\r
+                                [g_uchRawdataIndexOfDumpDataMapArr[puchChannelBgLvlArr[uchChCntIndex]]];\r
+                    unRawdataSum = 0;\r
+                    for (uchCalcCntIndex = 1;\r
+                        uchCalcCntIndex < g_uchDumpDataCntMapArr[puchChannelBgLvlArr[uchChCntIndex]]; \r
+                        uchCalcCntIndex++)\r
+                    {\r
+                        if (uchCalcCntIndex != g_uchRawdataIndexOfDumpDataMapArr[puchChannelBgLvlArr[uchChCntIndex]])\r
+                        {\r
+                            unRawdataSum += \\r
+                                GH3X2X_RAWDATA_CLEAR_ALL_FLAG(\\r
+                                  pstGh3x2xChannelDumpData->punIncompleteChRawdataArr[uchChCntIndex][uchCalcCntIndex]);\r
+                        }\r
+                    }\r
+                    pstGh3x2xChannelDumpData->punChBgRawdataArr[usRawdataBaseIndex + uchChCntIndex] = \\r
+                               (unRawdataSum / g_uchRawdataDivOfDumpDataMapArr[puchChannelBgLvlArr[uchChCntIndex]]) | \\r
+                                    GH3X2X_RAWDATA_CLEAR_DATA(\\r
+                                        pstGh3x2xChannelDumpData->punChRawdataArr[usRawdataBaseIndex + uchChCntIndex]);\r
+                }\r
+                else\r
+                {\r
+                    GH3X2X_FindLastSlotChMapIndex(&uchLastSlotChIndex, puchChannelMapArr, \\r
+                                                    uchChannelMapCnt, uchChCntIndex);\r
+                    pstGh3x2xChannelDumpData->punPkgNoAndCurrentArr[usRawdataBaseIndex + uchChCntIndex] = \\r
+                                        pstGh3x2xChannelDumpData->punIncompleteChRawdataArr[uchLastSlotChIndex][0];\r
+                    pstGh3x2xChannelDumpData->punChRawdataArr[usRawdataBaseIndex + uchChCntIndex] = \\r
+                        pstGh3x2xChannelDumpData->punIncompleteChRawdataArr[uchChCntIndex][0];\r
+                    unRawdataSum = pstGh3x2xChannelDumpData->punIncompleteChRawdataArr[uchLastSlotChIndex]\\r
+                                [g_uchRawdataIndexOfDumpDataMapArr[puchChannelBgLvlArr[uchLastSlotChIndex]] + 1]\r
+                                +  pstGh3x2xChannelDumpData->punIncompleteChRawdataArr[uchChCntIndex]\\r
+                                [g_uchRawdataIndexOfDumpDataMapArr[puchChannelBgLvlArr[uchChCntIndex]] + 1];\r
+                    pstGh3x2xChannelDumpData->punChBgRawdataArr[usRawdataBaseIndex + uchChCntIndex] = \\r
+                               (unRawdataSum / g_uchRawdataDivOfDumpDataMapArr[puchChannelBgLvlArr[uchChCntIndex]]) | \\r
+                                    GH3X2X_RAWDATA_CLEAR_DATA(\\r
+                                        pstGh3x2xChannelDumpData->punChRawdataArr[usRawdataBaseIndex + uchChCntIndex]);\r
+                }\r
+            } // end of for (uchChCntIndex = 0; uchChCntIndex < uchChannelMapCnt; uchChCntIndex++)\r
+        } // end of for (usRawdataIndex = 0; usRawdataIndex < usRawdataCnt; usRawdataIndex++)\r
+        GH3X2X_Memset(pstGh3x2xChannelDumpData->uchChIncompleteFlagArr, 0, GH3X2X_CHANNEL_MAP_MAX_CH);\r
+    } // end of if (chRet == GH3X2X_RET_OK)\r
+    if (uchNextIncompleteFlag != 0)\r
+    {\r
+        for (uchChCntIndex = 0; uchChCntIndex < uchChannelMapCnt; uchChCntIndex++) // search each channel\r
+        {\r
+            usRawdataByteIndexTmp = usRawdataIndexArr[uchChCntIndex];\r
+            while (usRawdataByteIndexTmp < usReadRawdataLen) // search each\r
+            {\r
+                if (GH3X2X_CHANNEL_MAP_GET(puchReadRawdataBuffer[usRawdataByteIndexTmp]) == \\r
+                                                            puchChannelMapArr[uchChCntIndex]) // if map equal\r
+                {\r
+                    pstGh3x2xChannelDumpData->punIncompleteChRawdataArr[uchChCntIndex]\\r
+                                                                        [uchDumpDataIndexArr[uchChCntIndex]] = \\r
+                                            GH3X2X_RAWDATA_CLEAR_SLOT_ADC_NUM(\r
+                                                GH3X2X_MAKEUP_DWORD(puchReadRawdataBuffer[usRawdataByteIndexTmp],\r
+                                                                puchReadRawdataBuffer[usRawdataByteIndexTmp + 1],\r
+                                                                puchReadRawdataBuffer[usRawdataByteIndexTmp + 2],\r
+                                                                puchReadRawdataBuffer[usRawdataByteIndexTmp + 3]));\r
+                    pstGh3x2xChannelDumpData->uchChIncompleteFlagArr[uchChCntIndex] |= \\r
+                                        (GU8)GH3X2X_GET_LEFT_SHIFT_VAL(uchDumpDataIndexArr[uchChCntIndex]);\r
+                    uchDumpDataIndexArr[uchChCntIndex]++;\r
+                }\r
+                usRawdataByteIndexTmp += GH3X2X_FIFO_RAWDATA_SIZE;\r
+            }\r
+        }\r
+    } // end of if (uchNextIncompleteFlag != 0)\r
+    pstGh3x2xChannelDumpData->usChRawdataCnt = usRawdataCnt;\r
+    return GH3X2X_RET_OK;\r
+}\r
+\r
+/**\r
+ * @fn     GS16 GH3X2X_GetDumpdataWithChannelMap(STGh3x2xChannelDumpData *pstGh3x2xChannelDumpData, \r
+ *                       GU8 *puchReadRawdataBuffer, GU8 uchChannelMapCnt, GU8 *puchChannelMapArr, GU8 *puchBglvlArr)\r
+ *\r
+ * @brief  Get dump data from fifo with channel map\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   puchReadRawdataBuffer       pointer to read data buffer\r
+ * @param[in]   uchChannelMapCnt            channel map array cnt, max:32\r
+ * @param[in]   puchChannelMapArr           pointer to channel map array\r
+ * @param[in]   puchBglvlArr                pointer to bg lvl array, @ref EMGh3x2xDumpRawdataBgLvlSelect\r
+ * @param[out]  pstGh3x2xChannelDumpData    pointer to channel rawdata struct output\r
+ *\r
+ * @return  GH3X2X_RET_OK                       return get data successful\r
+ * @retval  #GH3X2X_RET_PARAMETER_ERROR         return param error\r
+ * @retval  #GH3X2X_RET_READ_FIFO_CONTINUE      return fifo is not empty\r
+ */\r
+GS16 GH3X2X_GetDumpdataWithChannelMap(STGh3x2xChannelDumpData *pstGh3x2xChannelDumpData, \r
+                        GU8 *puchReadRawdataBuffer, GU8 uchChannelMapCnt, GU8 *puchChannelMapArr, GU8 *puchBglvlArr)\r
+{\r
+    GU16 usFifoLength = 0;\r
+    GS16 sRet = GH3X2X_RET_OK;\r
+\r
+    GH3X2X_DEBUG_LOG_PARAM("%s\r\n", __FUNCTION__);\r
+\r
+    if (puchReadRawdataBuffer != GH3X2X_PTR_NULL)\r
+    {\r
+        GH3X2X_WAIT_CHIP_WAKEUP();\r
+        usFifoLength = GH3X2X_FIFO_CNT_CALC(GH3X2X_ReadReg(GH3X2X_INT_FIFO_UR_REG_ADDR));\r
+        if (usFifoLength > g_usMaxNumReadFromFifo)\r
+        {\r
+            usFifoLength = g_usMaxNumReadFromFifo;\r
+            sRet = GH3X2X_RET_READ_FIFO_CONTINUE;\r
+        }\r
+\r
+        if ((usFifoLength > 0) && (usFifoLength <= GH3X2X_FIFO_DATA_BYTES_MAX_LEN))\r
+        {\r
+            GH3X2X_ReadFifo(puchReadRawdataBuffer, usFifoLength);\r
+        }\r
+        else\r
+        {\r
+            if (usFifoLength > GH3X2X_FIFO_DATA_BYTES_MAX_LEN)\r
+            {\r
+                usFifoLength = 0;\r
+                GH3X2X_DEBUG_LOG_PARAM("get rawdata fifo len greater than max, pelease check i2c/spi!\r\n");\r
+            }\r
+            else\r
+            {\r
+                GH3X2X_DEBUG_LOG_PARAM("get rawdata fifo equl 0!\r\n");\r
+            }\r
+        }\r
+        \r
+        /* call hook */\r
+        HOOK_FUNC_CALL(g_pGh3x2xGetRawdataHookFunc, (puchReadRawdataBuffer, usFifoLength));\r
+        GH3X2X_WAIT_CHIP_DSLP();\r
+        sRet = GH3X2X_UnpackDumpDataWithChannelMap(pstGh3x2xChannelDumpData, puchReadRawdataBuffer, usFifoLength, \r
+                                                    uchChannelMapCnt, puchChannelMapArr, puchBglvlArr);\r
+    }\r
+    else // fixed clear cnt if readbuffer ptr is null\r
+    {\r
+        GH3X2X_DEBUG_LOG_PARAM("get rawdata error that readbuffer is null!\r\n");\r
+        sRet = GH3X2X_RET_PARAMETER_ERROR;\r
+    }\r
+\r
+    return sRet;\r
+}\r
+\r
+/**\r
+ * @fn     GS8 GH3X2X_ChannelMapDumpDataClear(STGh3x2xChannelDumpData *pstGh3x2xChannelDumpData)\r
+ *\r
+ * @brief  clear channel map dump data struct\r
+ *\r
+ * @attention   This function must use before get dump data by one kind channel map\r
+ *              e.g. channel map start/stop need clear\r
+ *\r
+ * @param[in]   pstGh3x2xChannelDumpData     pointer to channel dump data struct\r
+ * @param[out]  None\r
+ *\r
+ * @return  error code\r
+ * @retval  #GH3X2X_RET_OK                      return successfully\r
+ * @retval  #GH3X2X_RET_PARAMETER_ERROR         return param error\r
+ */\r
+GS8 GH3X2X_ChannelMapDumpDataClear(STGh3x2xChannelDumpData *pstGh3x2xChannelDumpData)\r
+{\r
+    GS8 chRet = GH3X2X_RET_PARAMETER_ERROR;\r
+\r
+    GH3X2X_DEBUG_LOG_PARAM("%s\r\n", __FUNCTION__);\r
+    if ((pstGh3x2xChannelDumpData->uchChIncompleteFlagArr != GH3X2X_PTR_NULL)\r
+        && (pstGh3x2xChannelDumpData != GH3X2X_PTR_NULL))\r
+    {\r
+        GH3X2X_Memset(pstGh3x2xChannelDumpData->uchChIncompleteFlagArr, 0, GH3X2X_CHANNEL_MAP_MAX_CH);\r
+        pstGh3x2xChannelDumpData->usChRawdataCnt = 0;\r
+        chRet = GH3X2X_RET_OK;\r
+    }\r
+    else\r
+    {\r
+        GH3X2X_DEBUG_LOG_PARAM("channel rawdata param is null!\r\n");\r
+    }\r
+    return chRet;\r
+}\r
+\r
+/**\r
+ * @fn     GU32 GH3X2X_DumpRawDataPro(GU32 punRawdata, GU32 unAmb1, GU32 unAmb2)\r
+ *\r
+ * @brief  transfer dump data to true rawdata\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   punRawdata          led data\r
+ * @param[in]   unAmb1              ambiance data1\r
+ * @param[in]   unAmb2              ambiance data2\r
+ * @param[out]  None\r
+ *\r
+ * @return  rawdata after process\r
+ */\r
+GU32 GH3X2X_DumpRawDataPro(GU32 punRawdata, GU32 unAmb1, GU32 unAmb2)\r
+{\r
+    GU32 unLedValue  = 0;\r
+    \r
+    unLedValue = (GU32)((GS32)DUMP_PPG_DATA(punRawdata) - (((GS32)DUMP_PPG_DATA(unAmb1) + \\r
+                        (GS32)DUMP_PPG_DATA(unAmb2)) >> 1) + GH3X2X_DUMP_DATA_OFFSET);\r
+    \r
+    return GH3X2X_MAKEUP_DWORD(GH3X2X_GET_BYTE0_FROM_DWORD(unLedValue), GH3X2X_GET_BYTE1_FROM_DWORD(unLedValue), \\r
+                                GH3X2X_GET_BYTE2_FROM_DWORD(unLedValue), GH3X2X_GET_BYTE0_FROM_DWORD(punRawdata));\r
+    \r
+}\r
+\r
+/**\r
+ * @fn     void GH3X2X_DumpDataPro(GU32 punDumpDataArr[][GH3X2X_MAX_DUMP_DATA_NUM_CHANNEL], GU8 puchChMapArr[], \r
+                                    GU8 uchChMapCnt, GU8 puchChBgLvlArr[], GU8 uchChCntIndex)\r
+ *\r
+ * @brief  transfer dump data to true rawdata\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   punDumpData[][]     dump data of all channel\r
+ * @param[in]   uchChMapArr[]       channel map array\r
+ * @param[in]   uchChMapCnt         channel map cnt\r
+ * @param[in]   puchChBgLvlArr[]    channel bg level array\r
+ * @param[in]   uchChCntIndex       channel index\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_DumpDataPro(GU32 punDumpDataArr[][GH3X2X_MAX_DUMP_DATA_NUM_CHANNEL], GU8 puchChMapArr[], \r
+                        GU8 uchChMapCnt, GU8 puchChBgLvlArr[], GU8 uchChCntIndex)\r
+{\r
+    GU8 emBgLevel = puchChBgLvlArr[uchChCntIndex];\r
+    GU8 uchLastIndex = 0;\r
+    GU8 uchAgcData = 0;\r
+\r
+    uchAgcData = g_puchGainBgCancelRecord[GH3X2X_BYTE_RAWDATA_GET_SLOT_ADC_NUM(puchChMapArr[uchChCntIndex])];\r
+    switch (emBgLevel)\r
+    {\r
+    case GH3X2X_DUMP_RAWDATA_BGLVL0:\r
+        g_punDumpDataUploadArr[GH3X2X_DUMP_DATA_PPG_INDEX]          = punDumpDataArr[uchChCntIndex][1];\r
+        g_punDumpDataUploadArr[GH3X2X_DUMP_DATA_GAIN_CURRENT_INDEX] = GH3X2X_MAKEUP_DWORD(0, \\r
+                                                                    DUMP_CUREENT1(punDumpDataArr[uchChCntIndex][0]), \\r
+                                                                    DUMP_CUREENT0(punDumpDataArr[uchChCntIndex][0]), \\r
+                                                                    uchAgcData);\r
+        g_punDumpDataUploadArr[GH3X2X_DUMP_DATA_AMBIANCE_INDEX]     = 0;\r
+        break;\r
+    case GH3X2X_DUMP_RAWDATA_BGLVL1:\r
+        g_punDumpDataUploadArr[GH3X2X_DUMP_DATA_PPG_INDEX] = GH3X2X_DumpRawDataPro(punDumpDataArr[uchChCntIndex][2], \\r
+                                                                    punDumpDataArr[uchChCntIndex][1], \\r
+                                                                    punDumpDataArr[uchChCntIndex][1]);\r
+        g_punDumpDataUploadArr[GH3X2X_DUMP_DATA_GAIN_CURRENT_INDEX] = GH3X2X_MAKEUP_DWORD(0, \\r
+                                                                    DUMP_CUREENT1(punDumpDataArr[uchChCntIndex][0]), \\r
+                                                                    DUMP_CUREENT0(punDumpDataArr[uchChCntIndex][0]), \\r
+                                                                    uchAgcData);\r
+        g_punDumpDataUploadArr[GH3X2X_DUMP_DATA_AMBIANCE_INDEX]     = DUMP_PPG_DATA(punDumpDataArr[uchChCntIndex][1]);\r
+        break;\r
+    case GH3X2X_DUMP_RAWDATA_BGLVL2:\r
+        g_punDumpDataUploadArr[GH3X2X_DUMP_DATA_PPG_INDEX] = GH3X2X_DumpRawDataPro(punDumpDataArr[uchChCntIndex][2], \\r
+                                                                    punDumpDataArr[uchChCntIndex][1], \\r
+                                                                    punDumpDataArr[uchChCntIndex][3]);\r
+        g_punDumpDataUploadArr[GH3X2X_DUMP_DATA_GAIN_CURRENT_INDEX] = GH3X2X_MAKEUP_DWORD(0, \\r
+                                                                    DUMP_CUREENT1(punDumpDataArr[uchChCntIndex][0]), \\r
+                                                                    DUMP_CUREENT0(punDumpDataArr[uchChCntIndex][0]), \\r
+                                                                    uchAgcData);\r
+        g_punDumpDataUploadArr[GH3X2X_DUMP_DATA_AMBIANCE_INDEX] = (DUMP_PPG_DATA(punDumpDataArr[uchChCntIndex][1]) + \\r
+                                                                DUMP_PPG_DATA(punDumpDataArr[uchChCntIndex][3])) >> 1;\r
+        break;\r
+    case GH3X2X_DUMP_RAWDATA_BGLVL2X2:\r
+        GH3X2X_FindLastSlotChMapIndex(&uchLastIndex, puchChMapArr, uchChMapCnt, uchChCntIndex);\r
+\r
+        g_punDumpDataUploadArr[GH3X2X_DUMP_DATA_PPG_INDEX] = GH3X2X_DumpRawDataPro(punDumpDataArr[uchChCntIndex][0], \\r
+                                                                    punDumpDataArr[uchLastIndex][3], \\r
+                                                                    punDumpDataArr[uchChCntIndex][1]);\r
+        g_punDumpDataUploadArr[GH3X2X_DUMP_DATA_GAIN_CURRENT_INDEX] = GH3X2X_MAKEUP_DWORD(0, \\r
+                                                                    DUMP_CUREENT1(punDumpDataArr[uchLastIndex][0]), \\r
+                                                                    DUMP_CUREENT0(punDumpDataArr[uchLastIndex][0]), \\r
+                                                                    uchAgcData);\r
+        g_punDumpDataUploadArr[GH3X2X_DUMP_DATA_AMBIANCE_INDEX] = (DUMP_PPG_DATA(punDumpDataArr[uchLastIndex][3]) + \\r
+                                                                DUMP_PPG_DATA(punDumpDataArr[uchChCntIndex][1])) >> 1;\r
+        break;\r
+    default:\r
+        break;\r
+    } // end of switch (emBgLevel)\r
+}\r
+\r
+/**\r
+ * @fn       void GH3X2X_ElectrWearDumpDataPro(GU8* puchRawdataTag, GU8 uchChMapIndex)\r
+ *\r
+ * @brief    electrode wear dump data pro\r
+ *\r
+ * @attention    None\r
+ *\r
+ * @param[in]    puchRawdataTag      data tag of rawdata\r
+ * @param[in]    uchChMapIndex       channel map index\r
+ * @param[out]   None\r
+ *\r
+ * @return       None\r
+ */\r
+ \r
+void GH3X2X_ElectrWearDumpDataPro(GU8* puchRawdataTag, GU8 uchChMapIndex)\r
+{\r
+    if (GH3X2X_CHECK_LEFT_BIT_SET(GH3X2X_DumpModeGet(), GH3X2X_DUMP_ELECTR_WEAR_ENABLE_BIT))\r
+    {\r
+        if (0 == uchChMapIndex)\r
+        {\r
+            if (0 == g_uchElectrodeWearStatus)\r
+            {\r
+                GH3X2X_VAL_CLEAR_BIT(*puchRawdataTag, (GU8)GH3X2X_ELECTR_WEAR_STATUS_BIT_IN_DATA_TAG);\r
+            }\r
+            else\r
+            {\r
+                GH3X2X_VAL_SET_BIT(*puchRawdataTag, GH3X2X_ELECTR_WEAR_STATUS_BIT_IN_DATA_TAG);\r
+            }\r
+        }\r
+    }\r
+}\r
+\r
+\r
+/**\r
+ * @fn       void GH3X2X_FillDumpData(GU16* usPayloadIndex, GU8* uchGainCurAddr, GU8* uchAmbiAddr, \r
+ *                                    GU8 uchChannelMapArr[], GU8 uchChannelMapCnt,GU8 *puchChannelBgLvlArr, \r
+ *                                    GU16 usDumpMode, GU32 punIncompleteDumpdataArr[][GH3X2X_MAX_DUMP_DATA_NUM_CHANNEL])\r
+ *\r
+ * @brief  fill dump data to protocol data\r
+ *\r
+ * @attention    None\r
+ *\r
+ * @param[in]    uchChMapArr[]        channel map array\r
+ * @param[in]    uchChMapCnt          channel map cnt\r
+ * @param[in]    puchChBgLvlArr[]     channel bg level array\r
+ * @param[in]    usDumpMode           dump mode\r
+ * @param[in]    punDumpData[][]      dump data of all channel\r
+ * @param[out]    usPayloadIndex      current payload index\r
+ * @param[out]    uchGainCurAddr      current payload index\r
+ * @param[out]    uchAmbiAddr         current payload index\r
+ *\r
+ * @return    None\r
+ */\r
+void GH3X2X_FillDumpData(GU16* usPayloadIndex, GU8* uchGainCurAddr, GU8* uchAmbiAddr, GU8 uchChannelMapArr[], \r
+                            GU8 uchChannelMapCnt, GU8 *puchChannelBgLvlArr, GU16 usDumpMode, \r
+                            GU32 punIncompleteDumpdataArr[][GH3X2X_MAX_DUMP_DATA_NUM_CHANNEL])\r
+{\r
+    GU8  uchChCntIndex = 0;\r
+\r
+    for (uchChCntIndex = 0; uchChCntIndex < uchChannelMapCnt; uchChCntIndex++)\r
+    {\r
+        //dump data filter process\r
+        GH3X2X_DumpDataPro(punIncompleteDumpdataArr, uchChannelMapArr, uchChannelMapCnt, \\r
+                            puchChannelBgLvlArr, uchChCntIndex);\r
+        \r
+        GH3X2X_Memcpy(&g_pstGh3x2xProtocolData->puchPacketPayloadArr[*usPayloadIndex], \\r
+                        &g_punDumpDataUploadArr[GH3X2X_DUMP_DATA_PPG_INDEX], GH3X2X_FIFO_RAWDATA_SIZE);\r
+        GH3X2X_ElectrWearDumpDataPro(&g_pstGh3x2xProtocolData->puchPacketPayloadArr[*usPayloadIndex], uchChCntIndex);\r
+        *usPayloadIndex += GH3X2X_FIFO_RAWDATA_SIZE;\r
+        \r
+        if (GH3X2X_CHECK_LEFT_BIT_SET(usDumpMode, GH3X2X_DUMP_GAIN_CURRENT_ENABLE_BIT))\r
+        {\r
+            GH3X2X_Memcpy(&g_pstGh3x2xProtocolData->puchPacketPayloadArr[*uchGainCurAddr], \\r
+                            &g_punDumpDataUploadArr[GH3X2X_DUMP_DATA_GAIN_CURRENT_INDEX], \\r
+                            GH3X2X_DUMP_GAIN_CURRENT_DATA_SIZE);\r
+            *uchGainCurAddr += GH3X2X_DUMP_GAIN_CURRENT_DATA_SIZE;\r
+        }\r
+        \r
+        if (GH3X2X_CHECK_LEFT_BIT_SET(usDumpMode, GH3X2X_DUMP_AMBIANCE_ENABLE_BIT))\r
+        {\r
+            GH3X2X_Memcpy(&g_pstGh3x2xProtocolData->puchPacketPayloadArr[*uchAmbiAddr], \\r
+                            &g_punDumpDataUploadArr[GH3X2X_DUMP_DATA_AMBIANCE_INDEX], \\r
+                            GH3X2X_DUMP_AMBIANCE_DATA_SIZE);\r
+            *uchAmbiAddr += GH3X2X_DUMP_AMBIANCE_DATA_SIZE;\r
+        }\r
+    } //end of for (uchChCntIndex = 0; uchChCntIndex < uchChannelMapCnt; uchChCntIndex++)\r
+}\r
+\r
+#if 0\r
+/**\r
+ * @fn    GS8 GH3X2X_SendDumpDataPkgWithAlgo(GU8 *puchRespondBuffer, GU16 *pusRespondLen, GU8 punLastIncompleteArr[], \r
+                        GU32 punIncompleteDumpdataArr[][GH3X2X_MAX_DUMP_DATA_NUM_CHANNEL], GU8 *puchFifoRawdata, \r
+                        GU16 usFifoRawdataLen, GU8 uchChannelMapArr[], GU8 uchChannelMapCnt, GU8 *puchChannelBgLvlArr, \r
+                        STGsensorRawdata *pstGsAxisValueArr, GU16 usGsDataNum, EMGsensorSensitivity emGsSensitivity, \r
+                        GS32 nAlgoCalcResultArr[], GU8 uchAlgoResNum, GU8 uchChannelMapId)\r
+ *\r
+ * @brief  Pack rawdata with g sensor data and algorithm data\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[out]  puchRespondBuffer       pointer to protocol pkg data.\r
+ * @param[out]  pusRespondLen           pointer to protocol pkg data length\r
+ * @param[out]  punLastIncompleteArr    incomplete array\r
+ * @param[out]  punIncompleteRawdataArr incomplete data array used for cache data\r
+ * @param[in]   puchFifoRawdata         pointer to data buffer of rawdata\r
+ * @param[in]   usFifoRawdataLen        data num of rawdata buf\r
+ * @param[in]   uchChannelMapArr        pointer to channel map array\r
+ * @param[in]   uchChannelMapCnt        channel map array cnt, max:32\r
+ * @param[in]   puchChannelBgLvlArr     bg level array\r
+ * @param[in]   pstGsAxisValueArr       pointer to g sensor data\r
+ * @param[in]   usGsDataNum             g sensor data number\r
+ * @param[in]   emGsSensitivity         g sensor sensitivity\r
+ * @param[in]   nAlgoCalcResultArr      algorithm result\r
+ * @param[in]   uchAlgoResNum           number of algorithm result\r
+ * @param[in]   uchChannelMapId         channel map id (0 ~ 15)\r
+ * @return  error code\r
+ * @retval  #GH3X2X_RET_PARAMETER_ERROR         return param error\r
+ * @retval  #GH3X2X_RET_RAW_DATA_PKG_OVER       return already read all the package data \r
+ * @retval  #GH3X2X_RET_RAW_DATA_PKG_CONTINUE   return should read rawdata package data again\r
+ * @retval  #GH3X2X_RET_RESOURCE_ERROR          return not enough data\r
+ */\r
+GS8 GH3X2X_SendDumpDataPkgWithAlgo(GU8 *puchRespondBuffer, GU16 *pusRespondLen, GU8 punLastIncompleteArr[], \r
+                        GU32 punIncompleteDumpdataArr[][GH3X2X_MAX_DUMP_DATA_NUM_CHANNEL], GU8 *puchFifoRawdata, \r
+                        GU16 usFifoRawdataLen, GU8 uchChannelMapArr[], GU8 uchChannelMapCnt, GU8 *puchChannelBgLvlArr, \r
+                        STGsensorRawdata *pstGsAxisValueArr, GU16 usGsDataNum, EMGsensorSensitivity emGsSensitivity, \r
+                        GS32 nAlgoCalcResultArr[], GU8 uchAlgoResNum, GU8 uchChannelMapId)\r
+{\r
+    GS8  chRet = GH3X2X_RET_OK;\r
+    GU8  uchChCntIndex   = 0;\r
+    GF32 fIndexInc       = GH3X2X_GF32_0;            //step of g sensor data\r
+    GU16 usDataCnt       = 0;    \r
+    GU16 usDataIndex     = 0;\r
+    GU16 usPayloadIndex  = 0;                        //payload data index\r
+    GU8  uchGsEnable     = 0;\r
+    GU8  uchAlgoResFlag  = 0;\r
+    GU8  uchFrameDataNum = GH3X2X_FIFO_CNT_CALC(uchChannelMapCnt) + 1; //number of one frame data\r
+    GU8  uchGainCurDataNum     = 0;                                    //gain current data number of one frame data\r
+    GU8  uchAmbiDataNum        = 0;                                    //ambiance data number of one frame data\r
+    GU16 usRawdataByteIndexTmp = 0;\r
+    GU8  uchDumpDataIndexArr[GH3X2X_CHANNEL_MAP_MAX_CH] = {0};\r
+    GU8  uchNextIncompleteFlag = 0;\r
+    GU8  uchDumpDataCalcTmp    = 0;\r
+    GU8  uchGainCurAddr        = 0;                                        // gain & current data addr when pack them\r
+    GU8  uchAmbiAddr           = 0;                                        // ambiance data addr when pack them    \r
+    \r
+    if ((puchRespondBuffer == GH3X2X_PTR_NULL) || (pusRespondLen == GH3X2X_PTR_NULL)\r
+         || (puchFifoRawdata == GH3X2X_PTR_NULL) || (uchChannelMapArr == GH3X2X_PTR_NULL))\r
+    {\r
+        GH3X2X_DEBUG_LOG_PARAM("pointer param set null error!\r\n");\r
+        return GH3X2X_RET_PARAMETER_ERROR;\r
+    }\r
+\r
+    for (uchChCntIndex = 0; uchChCntIndex < uchChannelMapCnt; uchChCntIndex++)\r
+    {\r
+        if (GH3X2X_CLEAR_BIT(uchChannelMapArr[uchChCntIndex], GH3X2X_SLOT_ADC_NUM_BITS) != 0)\r
+        {\r
+            GH3X2X_DEBUG_LOG_PARAM("channel map error! set @ref GH3X2X_CHANNEL_MAP!\r\n");\r
+            return GH3X2X_RET_PARAMETER_ERROR;\r
+        }\r
+    }\r
+    \r
+    if (0 == g_usGh3x2xDataIndexInBuf)\r
+    {\r
+        GH3X2X_Memset(g_usRawdataByteIndexArr, 0, sizeof(g_usRawdataByteIndexArr[0]) * GH3X2X_CHANNEL_MAP_MAX_CH);\r
+    }    \r
+\r
+    if (nAlgoCalcResultArr == GH3X2X_PTR_NULL)\r
+    {\r
+        uchAlgoResNum = 0;\r
+    }\r
+\r
+    if ((0 == g_usGh3x2xDataIndexInBuf) && (GH3X2X_ElectrodeWearRevertDebugModeIsEnabled()))\r
+    {\r
+        uchAlgoResNum++;\r
+        uchFrameDataNum += GH3X2X_ALGO_RESULT_WITH_TAG_CALC(1) + 1;\r
+        uchAlgoResFlag = 1;\r
+        \r
+    }\r
+\r
+    if (GH3X2X_CHECK_LEFT_BIT_SET(g_usDumpMode, GH3X2X_DUMP_GAIN_CURRENT_ENABLE_BIT))\r
+    {\r
+        uchGainCurDataNum = (GU8)GH3X2X_DUMP_GAIN_CURRENT_CALC(uchChannelMapCnt);\r
+        uchFrameDataNum  += uchGainCurDataNum;\r
+    }\r
+\r
+    if (GH3X2X_CHECK_LEFT_BIT_SET(g_usDumpMode, GH3X2X_DUMP_AMBIANCE_ENABLE_BIT))\r
+    {\r
+        uchAmbiDataNum    = (GU8)GH3X2X_DUMP_AMBIANCE_CALC(uchChannelMapCnt);\r
+        uchFrameDataNum  += uchAmbiDataNum;\r
+    }\r
+    \r
+    if ((pstGsAxisValueArr == GH3X2X_PTR_NULL) || (0 == usGsDataNum))\r
+    {\r
+        uchGsEnable = 0;\r
+    }\r
+    else\r
+    {\r
+        uchGsEnable = 1;\r
+        uchFrameDataNum += GH3X2X_GSENSOR_DATA_SIZE;\r
+    }    \r
+    \r
+    chRet = GH3X2X_GetDumpDataInfo(&fIndexInc, &usDataCnt, &uchNextIncompleteFlag, uchDumpDataIndexArr, \r
+                        punLastIncompleteArr, usFifoRawdataLen, puchFifoRawdata, \r
+                        uchChannelMapCnt, uchChannelMapArr, puchChannelBgLvlArr, usGsDataNum);\r
+    \r
+    if (0 != g_usGh3x2xDataIndexInBuf)\r
+    {\r
+        GH3X2X_Memset(uchDumpDataIndexArr, 0, sizeof(uchDumpDataIndexArr));\r
+    }\r
+    \r
+    if (GH3X2X_RET_OK == chRet)\r
+    {\r
+        g_pstGh3x2xProtocolData->puchPacketPayloadArr[UPROTOCOL_RAWDATA_TYPE_INDEX] = \\r
+                                                GH3X2X_VAL_LEFT_SHIFT(uchChannelMapId, UPROTOCOL_FUNC_ID_FIELD)\r
+                                                | GH3X2X_VAL_LEFT_SHIFT(uchGsEnable, UPROTOCOL_GS_ENABLE_FIELD)\r
+                                                | GH3X2X_VAL_LEFT_SHIFT(uchAlgoResFlag, UPROTOCOL_ALGO_ENABLE_FIELD);\r
+        \r
+        if (GH3X2X_CHECK_LEFT_BIT_SET(g_usDumpMode, GH3X2X_DUMP_GAIN_CURRENT_ENABLE_BIT))\r
+        {\r
+            g_pstGh3x2xProtocolData->puchPacketPayloadArr[UPROTOCOL_RAWDATA_TYPE_INDEX] |= \\r
+                                                GH3X2X_GET_LEFT_SHIFT_VAL(UPROTOCOL_AGC_ENABLE_FIELD);\r
+        }\r
+\r
+        if (GH3X2X_CHECK_LEFT_BIT_SET(g_usDumpMode, GH3X2X_DUMP_AMBIANCE_ENABLE_BIT))\r
+        {\r
+            g_pstGh3x2xProtocolData->puchPacketPayloadArr[UPROTOCOL_RAWDATA_TYPE_INDEX] |= \\r
+                                                GH3X2X_GET_LEFT_SHIFT_VAL(UPROTOCOL_AMBIANCE_ENABLE_FIELD);\r
+        }\r
+        \r
+        usPayloadIndex = UPROTOCOL_FRAME_DATA_INDEX;\r
+        for (usDataIndex = g_usGh3x2xDataIndexInBuf; usDataIndex < usDataCnt; usDataIndex++)\r
+        {        \r
+            //judge if will exceed payload length limit\r
+            if (usPayloadIndex + uchFrameDataNum >= GH3X2X_UPROTOCOL_GET_PAYLOAD_LEN_SUPPORT(g_uchPacketMaxLenSupport))\r
+            {\r
+                break;\r
+            }\r
+            g_pstGh3x2xProtocolData->puchPacketPayloadArr[usPayloadIndex] = g_uchFrameIdArr[uchChannelMapId];  //FrameID\r
+            g_pstGh3x2xProtocolData->uchFrameIdArr[uchChannelMapId]++;\r
+            usPayloadIndex++;\r
+            if (1 == uchGsEnable)\r
+            {\r
+                GH3X2X_FillGsensorData(&usPayloadIndex, &pstGsAxisValueArr[(GU16)g_fGsDataIndexInBuf]);\r
+                g_fGsDataIndexInBuf += fIndexInc;\r
+            }\r
+\r
+            if (GH3X2X_CHECK_LEFT_BIT_SET(g_usDumpMode, GH3X2X_DUMP_GAIN_CURRENT_ENABLE_BIT))\r
+            {\r
+                uchGainCurAddr = usPayloadIndex + GH3X2X_FIFO_CNT_CALC(uchChannelMapCnt);\r
+            }\r
+\r
+            if (GH3X2X_CHECK_LEFT_BIT_SET(g_usDumpMode, GH3X2X_DUMP_AMBIANCE_ENABLE_BIT))\r
+            {\r
+                if (GH3X2X_CHECK_LEFT_BIT_SET(g_usDumpMode, GH3X2X_DUMP_GAIN_CURRENT_ENABLE_BIT))\r
+                {\r
+                    uchAmbiAddr = (GU8)uchGainCurAddr + uchGainCurDataNum;\r
+                }\r
+                else\r
+                {\r
+                    uchAmbiAddr = usPayloadIndex + GH3X2X_FIFO_CNT_CALC(uchChannelMapCnt);\r
+                }\r
+            }\r
+            \r
+            for (uchChCntIndex = 0; uchChCntIndex < uchChannelMapCnt; uchChCntIndex++) // search each channel\r
+            {\r
+                uchDumpDataCalcTmp = g_uchDumpDataCntMapArr[puchChannelBgLvlArr[uchChCntIndex]];\r
+                if (uchDumpDataIndexArr[uchChCntIndex] < uchDumpDataCalcTmp)\r
+                {\r
+                    usRawdataByteIndexTmp = g_usRawdataByteIndexArr[uchChCntIndex];\r
+                    while (usRawdataByteIndexTmp < usFifoRawdataLen) // search each\r
+                    {\r
+                        if (GH3X2X_CHANNEL_MAP_GET(puchFifoRawdata[usRawdataByteIndexTmp]) == \\r
+                                                                    uchChannelMapArr[uchChCntIndex]) // if map equal\r
+                        {\r
+                            punIncompleteDumpdataArr[uchChCntIndex][uchDumpDataIndexArr[uchChCntIndex]] = \\r
+                                                GH3X2X_MAKEUP_DWORD(puchFifoRawdata[usRawdataByteIndexTmp + 3],\r
+                                                                    puchFifoRawdata[usRawdataByteIndexTmp + 2],\r
+                                                                    puchFifoRawdata[usRawdataByteIndexTmp + 1],\r
+                                                                    puchFifoRawdata[usRawdataByteIndexTmp]);\r
+                            uchDumpDataIndexArr[uchChCntIndex]++;\r
+                            if (uchDumpDataIndexArr[uchChCntIndex] >= uchDumpDataCalcTmp)\r
+                            {\r
+                                usRawdataByteIndexTmp += GH3X2X_FIFO_RAWDATA_SIZE;\r
+                                break;\r
+                            }\r
+                        }\r
+                        usRawdataByteIndexTmp += GH3X2X_FIFO_RAWDATA_SIZE;\r
+                    }\r
+                }\r
+\r
+                uchDumpDataIndexArr[uchChCntIndex] = 0;\r
+                g_usRawdataByteIndexArr[uchChCntIndex] = usRawdataByteIndexTmp; // write back byte index\r
+            } // end of for (uchChCntIndex = 0; uchChCntIndex < uchChannelMapCnt; uchChCntIndex++)\r
+\r
+            GH3X2X_FillDumpData(&usPayloadIndex, &uchGainCurAddr, &uchAmbiAddr, uchChannelMapArr, uchChannelMapCnt, \\r
+                                puchChannelBgLvlArr, g_usDumpMode, punIncompleteDumpdataArr);\r
+            \r
+            usPayloadIndex += uchGainCurDataNum + uchAmbiDataNum;\r
+            \r
+            if (1 == uchAlgoResFlag)\r
+            {\r
+                g_pstGh3x2xProtocolData->puchPacketPayloadArr[usPayloadIndex] = GH3X2X_ALGO_RESULT_WITH_TAG_CALC(uchAlgoResNum);\r
+                usPayloadIndex++;\r
+                if ((GH3X2X_ElectrodeWearRevertDebugModeIsEnabled()) && (0 == usDataIndex))\r
+                {\r
+                    GH3X2X_FillElectrodeWearRevertData(&usPayloadIndex);\r
+                    uchAlgoResNum -= 1;  //only the first frame data has Flag data\r
+                    uchFrameDataNum -= GH3X2X_ALGO_RESULT_WITH_TAG_CALC(1);\r
+                }                \r
+            } // end of if (1 == uchAlgoResFlag)\r
+        } // end of for (usDataIndex = g_usGh3x2xDataIndexInBuf; usDataIndex < usDataCnt; usDataIndex++)\r
+        \r
+        if (usDataIndex < usDataCnt)\r
+        {\r
+            g_usGh3x2xDataIndexInBuf = usDataIndex;\r
+            chRet = GH3X2X_RET_RAW_DATA_PKG_CONTINUE;\r
+        }\r
+        else\r
+        {\r
+            g_usGh3x2xDataIndexInBuf = 0;\r
+            g_fGsDataIndexInBuf = 0;\r
+            chRet = GH3X2X_RET_RAW_DATA_PKG_OVER;\r
+            GH3X2X_CacheIncompleteDumpdata(punLastIncompleteArr, punIncompleteDumpdataArr, uchNextIncompleteFlag, \\r
+                                            puchFifoRawdata, usFifoRawdataLen, uchChannelMapArr, uchChannelMapCnt, \\r
+                                            g_usRawdataByteIndexArr);\r
+        } // end else\r
+\r
+        g_pstGh3x2xProtocolData->puchPacketPayloadArr[UPROTOCOL_RAWDATA_LEN_INDEX] = (GU8)(usPayloadIndex - UPROTOCOL_FRAME_DATA_INDEX);\r
+        /* respond packet format */\r
+        SET_VAL_VIA_PTR(pusRespondLen, GH3X2X_UprotocolPacketFormat(GH3X2X_UPROTOCOL_CMD_RAWDATA, puchRespondBuffer,\r
+                                    g_pstGh3x2xProtocolData->puchPacketPayloadArr, usPayloadIndex));\r
+    } // end of if (GH3X2X_RET_OK == chRet)\r
+    else\r
+    {\r
+        pusRespondLen = 0;\r
+    }    \r
+\r
+    return chRet;\r
+}\r
+\r
+\r
+/**\r
+ * @fn       void GH3X2X_FillZipDumpData(GU16* usPayloadIndex, GU8* uchGainCurAddr, GU8* uchAmbiAddr, \r
+ *                                    GU8 uchChannelMapArr[], GU8 uchChannelMapCnt,GU8 *puchChannelBgLvlArr, \r
+ *                                    GU16 usDumpMode, GU32 punIncompleteDumpdataArr[][GH3X2X_MAX_DUMP_DATA_NUM_CHANNEL])\r
+ *\r
+ * @brief  fill zip dump data to protocol data\r
+ *\r
+ * @attention    None\r
+ *\r
+ * @param[in]    uchChMapArr[]        channel map array\r
+ * @param[in]    uchChMapCnt          channel map cnt\r
+ * @param[in]    puchChBgLvlArr[]     channel bg level array\r
+ * @param[in]    usDumpMode           dump mode\r
+ * @param[in]    punDumpData[][]      dump data of all channel\r
+ * @param[out]    usPayloadIndex      current payload index\r
+ * @param[out]    uchGainCurAddr      current payload index\r
+ * @param[out]    uchAmbiAddr         current payload index\r
+ *\r
+ * @return    None\r
+ */\r
+GU8 GH3X2X_FillZipDumpData(GU16* usPayloadIndex, GU8 uchChannelMapArr[], \r
+                            GU8 uchChannelMapCnt, GU8 *puchChannelBgLvlArr, GU16 usDumpMode, \r
+                            GU32 punIncompleteDumpdataArr[][GH3X2X_MAX_DUMP_DATA_NUM_CHANNEL], \r
+                            GU8 uchZipDataFirstFrameSta, GU8 *uchZipDiffDataSize,\r
+                            GU8 uchGainCurDataNum, GU8 uchAmbiDataNum)\r
+{\r
+    GU8  uchChCntIndex = 0;\r
+    GU32 unFifoLastRawdataArr[GH3X2X_CHANNEL_MAP_MAX_CH];\r
+    GU8 uchFifoLastRawdataTagArr[GH3X2X_CHANNEL_MAP_MAX_CH];\r
+    GU32 unFifoLastAgcdataArr[GH3X2X_CHANNEL_MAP_MAX_CH];\r
+    GU32 unFifoLastAmbdataArr[GH3X2X_CHANNEL_MAP_MAX_CH];\r
+\r
+    GU8 uchZipDataArr[GH3X2X_UPROTOCOL_PACKET_LEN_MAX];\r
+    GU16 usZipDataArrSize = 0;\r
+\r
+    GU8 uchZipRawdataArr[GH3X2X_UPROTOCOL_PACKET_LEN_MAX];\r
+    GU8 uchZipRawdataArrSize = 0;\r
+    GU8 uchZipAgcDataArr[GH3X2X_UPROTOCOL_PACKET_LEN_MAX];\r
+    GU8 uchZipAgcDataArrSize = 0;\r
+    GU8 uchZipAmbDataArr[GH3X2X_UPROTOCOL_PACKET_LEN_MAX];\r
+    GU8 uchZipAmbDataArrSize = 0;\r
+\r
+\r
+    if (g_uchDumpOddEvenChangeFlag && uchZipDataFirstFrameSta)\r
+    {\r
+        if (*usPayloadIndex + (GU16)usZipDataArrSize > \\r
+            (GU16)GH3X2X_UPROTOCOL_GET_PAYLOAD_LEN_SUPPORT(g_uchPacketMaxLenSupport))\r
+        {\r
+            return 1;\r
+        }\r
+        \r
+        usZipDataArrSize = uchGainCurDataNum + uchAmbiDataNum;\r
+\r
+        for (uchChCntIndex = 0; uchChCntIndex < uchChannelMapCnt; uchChCntIndex++)\r
+        {\r
+            //dump data filter process\r
+            GH3X2X_DumpDataPro(punIncompleteDumpdataArr, uchChannelMapArr, uchChannelMapCnt, \\r
+                                puchChannelBgLvlArr, uchChCntIndex);\r
+            GH3X2X_Memcpy(&g_pstGh3x2xProtocolData->puchPacketPayloadArr[*usPayloadIndex], \\r
+                            &g_punDumpDataUploadArr[GH3X2X_DUMP_DATA_PPG_INDEX], GH3X2X_FIFO_RAWDATA_SIZE);\r
+            GH3X2X_ElectrWearDumpDataPro(&g_pstGh3x2xProtocolData->puchPacketPayloadArr[*usPayloadIndex], uchChCntIndex);\r
+            *usPayloadIndex += GH3X2X_FIFO_RAWDATA_SIZE;\r
+            g_stZipDumpTempData.unFifoLastRawdataArr[uchChCntIndex] = GH3X2X_MAKEUP_DWORD\\r
+                (0, \\r
+                 GH3X2X_GET_BYTE1_FROM_DWORD(g_punDumpDataUploadArr[GH3X2X_DUMP_DATA_PPG_INDEX]), \\r
+                 GH3X2X_GET_BYTE2_FROM_DWORD(g_punDumpDataUploadArr[GH3X2X_DUMP_DATA_PPG_INDEX]), \\r
+                 GH3X2X_GET_BYTE3_FROM_DWORD(g_punDumpDataUploadArr[GH3X2X_DUMP_DATA_PPG_INDEX]));\r
+            g_stZipDumpTempData.uchFifoLastRawdataTagArr[uchChCntIndex] = \\r
+                GH3X2X_GET_BYTE0_FROM_DWORD(g_punDumpDataUploadArr[GH3X2X_DUMP_DATA_PPG_INDEX]);            \r
+        }// end of for (uchChCntIndex = 0; uchChCntIndex < uchChannelMapCnt; uchChCntIndex++)\r
+\r
+        if (GH3X2X_CHECK_LEFT_BIT_SET(usDumpMode, GH3X2X_DUMP_GAIN_CURRENT_ENABLE_BIT))\r
+        {\r
+            for (uchChCntIndex = 0; uchChCntIndex < uchChannelMapCnt; uchChCntIndex++)\r
+            {\r
+                GH3X2X_DumpDataPro(punIncompleteDumpdataArr, uchChannelMapArr, uchChannelMapCnt, \\r
+                                puchChannelBgLvlArr, uchChCntIndex);\r
+                GH3X2X_Memcpy(&g_pstGh3x2xProtocolData->puchPacketPayloadArr[*usPayloadIndex], \\r
+                                &g_punDumpDataUploadArr[GH3X2X_DUMP_DATA_GAIN_CURRENT_INDEX], \\r
+                                GH3X2X_DUMP_GAIN_CURRENT_DATA_SIZE);\r
+                *usPayloadIndex += GH3X2X_DUMP_GAIN_CURRENT_DATA_SIZE;\r
+                GH3X2X_Memcpy(&g_stZipDumpTempData.unFifoLastAgcdataArr[uchChCntIndex], \\r
+                                &g_punDumpDataUploadArr[GH3X2X_DUMP_DATA_GAIN_CURRENT_INDEX], \\r
+                                GH3X2X_DUMP_GAIN_CURRENT_DATA_SIZE);\r
+            }\r
+        }\r
+            \r
+        if (GH3X2X_CHECK_LEFT_BIT_SET(usDumpMode, GH3X2X_DUMP_AMBIANCE_ENABLE_BIT))\r
+        {\r
+            for (uchChCntIndex = 0; uchChCntIndex < uchChannelMapCnt; uchChCntIndex++)\r
+            {\r
+                GH3X2X_DumpDataPro(punIncompleteDumpdataArr, uchChannelMapArr, uchChannelMapCnt, \\r
+                                puchChannelBgLvlArr, uchChCntIndex);\r
+                GH3X2X_Memcpy(&g_pstGh3x2xProtocolData->puchPacketPayloadArr[*usPayloadIndex], \\r
+                                &g_punDumpDataUploadArr[GH3X2X_DUMP_DATA_AMBIANCE_INDEX], \\r
+                                GH3X2X_DUMP_AMBIANCE_DATA_SIZE);\r
+                *usPayloadIndex += GH3X2X_DUMP_AMBIANCE_DATA_SIZE;\r
+                GH3X2X_Memcpy(&g_stZipDumpTempData.unFifoLastAmbdataArr[uchChCntIndex], \\r
+                                &g_punDumpDataUploadArr[GH3X2X_DUMP_DATA_AMBIANCE_INDEX], \\r
+                                GH3X2X_DUMP_AMBIANCE_DATA_SIZE);\r
+            }\r
+        } //end of if (GH3X2X_CHECK_LEFT_BIT_SET(usDumpMode, GH3X2X_DUMP_AMBIANCE_ENABLE_BIT))\r
+    }//end of if (g_uchDumpOddEvenChangeFlag && uchZipDataFirstFrameSta)\r
+    else\r
+    {\r
+        for (uchChCntIndex = 0; uchChCntIndex < uchChannelMapCnt; uchChCntIndex++)\r
+        {\r
+            //dump data filter process\r
+            GH3X2X_DumpDataPro(punIncompleteDumpdataArr, uchChannelMapArr, uchChannelMapCnt, \\r
+                                puchChannelBgLvlArr, uchChCntIndex);\r
+            GH3X2X_ElectrWearDumpDataPro(&g_pstGh3x2xProtocolData->puchPacketPayloadArr[*usPayloadIndex], uchChCntIndex);\r
+            unFifoLastRawdataArr[uchChCntIndex] = 0;\r
+            uchFifoLastRawdataTagArr[uchChCntIndex] = 0;\r
+            unFifoLastRawdataArr[uchChCntIndex] = GH3X2X_MAKEUP_DWORD\\r
+                (0, \\r
+                 GH3X2X_GET_BYTE1_FROM_DWORD(g_punDumpDataUploadArr[GH3X2X_DUMP_DATA_PPG_INDEX]), \\r
+                 GH3X2X_GET_BYTE2_FROM_DWORD(g_punDumpDataUploadArr[GH3X2X_DUMP_DATA_PPG_INDEX]), \\r
+                 GH3X2X_GET_BYTE3_FROM_DWORD(g_punDumpDataUploadArr[GH3X2X_DUMP_DATA_PPG_INDEX]));\r
+            uchFifoLastRawdataTagArr[uchChCntIndex] = \\r
+                GH3X2X_GET_BYTE0_FROM_DWORD(g_punDumpDataUploadArr[GH3X2X_DUMP_DATA_PPG_INDEX]);          \r
+        }\r
+\r
+        if (GH3X2X_CHECK_LEFT_BIT_SET(usDumpMode, GH3X2X_DUMP_GAIN_CURRENT_ENABLE_BIT))\r
+        {\r
+            for (uchChCntIndex = 0; uchChCntIndex < uchChannelMapCnt; uchChCntIndex++)\r
+            {\r
+                GH3X2X_DumpDataPro(punIncompleteDumpdataArr, uchChannelMapArr, uchChannelMapCnt, \\r
+                                puchChannelBgLvlArr, uchChCntIndex);\r
+                unFifoLastAgcdataArr[uchChCntIndex] = 0;\r
+                GH3X2X_Memcpy(&unFifoLastAgcdataArr[uchChCntIndex], \\r
+                                &g_punDumpDataUploadArr[GH3X2X_DUMP_DATA_GAIN_CURRENT_INDEX], \\r
+                                GH3X2X_DUMP_GAIN_CURRENT_DATA_SIZE);\r
+            }\r
+        }\r
+            \r
+        if (GH3X2X_CHECK_LEFT_BIT_SET(usDumpMode, GH3X2X_DUMP_AMBIANCE_ENABLE_BIT))\r
+        {\r
+            for (uchChCntIndex = 0; uchChCntIndex < uchChannelMapCnt; uchChCntIndex++)\r
+            {\r
+                GH3X2X_DumpDataPro(punIncompleteDumpdataArr, uchChannelMapArr, uchChannelMapCnt, \\r
+                                puchChannelBgLvlArr, uchChCntIndex);\r
+                unFifoLastAmbdataArr[uchChCntIndex] = 0;\r
+                GH3X2X_Memcpy(&unFifoLastAmbdataArr[uchChCntIndex], \\r
+                                &g_punDumpDataUploadArr[GH3X2X_DUMP_DATA_AMBIANCE_INDEX], \\r
+                                GH3X2X_DUMP_AMBIANCE_DATA_SIZE);\r
+            }\r
+        } //end of for (uchChCntIndex = 0; uchChCntIndex < uchChannelMapCnt; uchChCntIndex++)\r
+\r
+        GH3X2X_Memset(uchZipRawdataArr, 0, sizeof(uchZipRawdataArr[0]) * GH3X2X_UPROTOCOL_PACKET_LEN_MAX);\r
+        GH3X2X_GetRawDataDiff(unFifoLastRawdataArr, uchFifoLastRawdataTagArr, \\r
+                        uchChannelMapCnt, uchZipRawdataArr, &uchZipRawdataArrSize, \\r
+                        g_stZipDumpTempData.uchFifoLastRawdataTagArr, g_stZipDumpTempData.unFifoLastRawdataArr);\r
+        GH3X2X_Memcpy(&uchZipDataArr[usZipDataArrSize], uchZipRawdataArr, uchZipRawdataArrSize);\r
+        usZipDataArrSize += uchZipRawdataArrSize;\r
+\r
+        if (GH3X2X_CHECK_LEFT_BIT_SET(usDumpMode, GH3X2X_DUMP_GAIN_CURRENT_ENABLE_BIT))\r
+        {\r
+            GH3X2X_Memset(uchZipAgcDataArr, 0, sizeof(uchZipAgcDataArr[0]) * GH3X2X_UPROTOCOL_PACKET_LEN_MAX);\r
+            GH3X2X_GetDataDiff(unFifoLastAgcdataArr, uchChannelMapCnt, uchZipAgcDataArr, &uchZipAgcDataArrSize, \\r
+                g_stZipDumpTempData.unFifoLastAgcdataArr);\r
+            GH3X2X_Memcpy(&uchZipDataArr[usZipDataArrSize], uchZipAgcDataArr, uchZipAgcDataArrSize);\r
+            usZipDataArrSize += uchZipAgcDataArrSize;\r
+        }\r
+        \r
+        if (GH3X2X_CHECK_LEFT_BIT_SET(usDumpMode, GH3X2X_DUMP_AMBIANCE_ENABLE_BIT))\r
+        {\r
+            GH3X2X_Memset(uchZipAmbDataArr, 0, sizeof(uchZipAmbDataArr[0]) * GH3X2X_UPROTOCOL_PACKET_LEN_MAX);\r
+            GH3X2X_GetDataDiff(unFifoLastAmbdataArr, uchChannelMapCnt, uchZipAmbDataArr, &uchZipAmbDataArrSize, \\r
+                g_stZipDumpTempData.unFifoLastAmbdataArr);\r
+            GH3X2X_Memcpy(&uchZipDataArr[usZipDataArrSize], uchZipAmbDataArr, uchZipAmbDataArrSize);\r
+            usZipDataArrSize += uchZipAmbDataArrSize;\r
+        }\r
+        \r
+        if (*usPayloadIndex + (GU16)usZipDataArrSize > \\r
+            (GU16)GH3X2X_UPROTOCOL_GET_PAYLOAD_LEN_SUPPORT(g_uchPacketMaxLenSupport))\r
+        {\r
+            return 1;\r
+        }\r
+        else\r
+        {                \r
+            GH3X2X_Memcpy(g_stZipDumpTempData.unFifoLastRawdataArr, unFifoLastRawdataArr, \\r
+                        uchChannelMapCnt*GH3X2X_FIFO_RAWDATA_SIZE);\r
+            GH3X2X_Memcpy(g_stZipDumpTempData.uchFifoLastRawdataTagArr, uchFifoLastRawdataTagArr, \\r
+                        uchChannelMapCnt);\r
+            GH3X2X_Memcpy(g_stZipDumpTempData.unFifoLastAgcdataArr, unFifoLastAgcdataArr, \\r
+                        uchChannelMapCnt*GH3X2X_FIFO_RAWDATA_SIZE);\r
+            GH3X2X_Memcpy(g_stZipDumpTempData.unFifoLastAmbdataArr, unFifoLastAmbdataArr, \\r
+                        uchChannelMapCnt*GH3X2X_FIFO_RAWDATA_SIZE);\r
+\r
+            GH3X2X_Memcpy(&g_pstGh3x2xProtocolData->puchPacketPayloadArr[*usPayloadIndex], uchZipDataArr, usZipDataArrSize);\r
+            *usPayloadIndex += (GU16)usZipDataArrSize;\r
+        }\r
+    }// end of else\r
+\r
+    return 0;\r
+}\r
+\r
+/**\r
+ * @fn    GS8 GH3X2X_SendZipDumpDataPkgWithAlgo(GU8 *puchRespondBuffer, GU16 *pusRespondLen, GU8 punLastIncompleteArr[], \r
+                        GU32 punIncompleteDumpdataArr[][GH3X2X_MAX_DUMP_DATA_NUM_CHANNEL], GU8 *puchFifoRawdata, \r
+                        GU16 usFifoRawdataLen, GU8 uchChannelMapArr[], GU8 uchChannelMapCnt, GU8 *puchChannelBgLvlArr, \r
+                        STGsensorRawdata *pstGsAxisValueArr, GU16 usGsDataNum, EMGsensorSensitivity emGsSensitivity, \r
+                        GS32 nAlgoCalcResultArr[], GU8 uchAlgoResNum, GU8 uchChannelMapId)\r
+ *\r
+ * @brief  Pack Zip rawdata with g sensor data and algorithm data\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[out]  puchRespondBuffer       pointer to protocol pkg data.\r
+ * @param[out]  pusRespondLen           pointer to protocol pkg data length\r
+ * @param[out]  punLastIncompleteArr    incomplete array\r
+ * @param[out]  punIncompleteRawdataArr incomplete data array used for cache data\r
+ * @param[in]   puchFifoRawdata         pointer to data buffer of rawdata\r
+ * @param[in]   usFifoRawdataLen        data num of rawdata buf\r
+ * @param[in]   uchChannelMapArr        pointer to channel map array\r
+ * @param[in]   uchChannelMapCnt        channel map array cnt, max:32\r
+ * @param[in]   puchChannelBgLvlArr     bg level array\r
+ * @param[in]   pstGsAxisValueArr       pointer to g sensor data\r
+ * @param[in]   usGsDataNum             g sensor data number\r
+ * @param[in]   emGsSensitivity         g sensor sensitivity\r
+ * @param[in]   nAlgoCalcResultArr      algorithm result\r
+ * @param[in]   uchAlgoResNum           number of algorithm result\r
+ * @param[in]   uchChannelMapId         channel map id (0 ~ 15)\r
+ * @return  error code\r
+ * @retval  #GH3X2X_RET_PARAMETER_ERROR         return param error\r
+ * @retval  #GH3X2X_RET_RAW_DATA_PKG_OVER       return already read all the package data \r
+ * @retval  #GH3X2X_RET_RAW_DATA_PKG_CONTINUE   return should read rawdata package data again\r
+ * @retval  #GH3X2X_RET_RESOURCE_ERROR          return not enough data\r
+ */\r
+GS8 GH3X2X_SendZipDumpDataPkgWithAlgo(GU8 *puchRespondBuffer, GU16 *pusRespondLen, GU8 punLastIncompleteArr[], \r
+                        GU32 punIncompleteDumpdataArr[][GH3X2X_MAX_DUMP_DATA_NUM_CHANNEL], GU8 *puchFifoRawdata, \r
+                        GU16 usFifoRawdataLen, GU8 uchChannelMapArr[], GU8 uchChannelMapCnt, GU8 *puchChannelBgLvlArr, \r
+                        STGsensorRawdata *pstGsAxisValueArr, GU16 usGsDataNum, EMGsensorSensitivity emGsSensitivity, \r
+                        GS32 nAlgoCalcResultArr[], GU8 uchAlgoResNum, GU8 uchChannelMapId)\r
+{\r
+    GS8  chRet = GH3X2X_RET_OK;\r
+    GU8  uchChCntIndex   = 0;\r
+    GF32 fIndexInc       = GH3X2X_GF32_0;            //step of g sensor data\r
+    GU16 usDataCnt       = 0;    \r
+    GU16 usDataIndex     = 0;\r
+    GU16 usPayloadIndex  = 0;                        //payload data index\r
+    GU8  uchGsEnable     = 0;\r
+    GU8  uchAlgoResFlag  = 0;\r
+    GU8  uchFrameDataNum = GH3X2X_FIFO_CNT_CALC(uchChannelMapCnt) + 1; //number of one frame data\r
+    GU8  uchGainCurDataNum     = 0;                                    //gain current data number of one frame data\r
+    GU8  uchAmbiDataNum        = 0;                                    //ambiance data number of one frame data\r
+    GU16 usRawdataByteIndexTmp = 0;\r
+    GU8  uchDumpDataIndexArr[GH3X2X_CHANNEL_MAP_MAX_CH] = {0};\r
+    GU8  uchNextIncompleteFlag = 0;\r
+    GU8  uchDumpDataCalcTmp    = 0;\r
+    GU8  uchSendCmd            = 0;                                        // zip cmd (0x09/0x0a)\r
+    GU8  uchZipDataFirstFrameSta = 1;\r
+    GU8  uchZipDiffDataSize = 0;\r
+    GU8  uchZipRet = 0;\r
+    GU16 usRawdataByteIndexTmpBeforeHandleArr[GH3X2X_CHANNEL_MAP_MAX_CH];\r
+    GU16 usFrameidIndex;\r
+    \r
+    if ((puchRespondBuffer == GH3X2X_PTR_NULL) || (pusRespondLen == GH3X2X_PTR_NULL)\r
+         || (puchFifoRawdata == GH3X2X_PTR_NULL) || (uchChannelMapArr == GH3X2X_PTR_NULL))\r
+    {\r
+        GH3X2X_DEBUG_LOG_PARAM("pointer param set null error!\r\n");\r
+        return GH3X2X_RET_PARAMETER_ERROR;\r
+    }\r
+\r
+    for (uchChCntIndex = 0; uchChCntIndex < uchChannelMapCnt; uchChCntIndex++)\r
+    {\r
+        if (GH3X2X_CLEAR_BIT(uchChannelMapArr[uchChCntIndex], GH3X2X_SLOT_ADC_NUM_BITS) != 0)\r
+        {\r
+            GH3X2X_DEBUG_LOG_PARAM("channel map error! set @ref GH3X2X_CHANNEL_MAP!\r\n");\r
+            return GH3X2X_RET_PARAMETER_ERROR;\r
+        }\r
+    }\r
+    \r
+    if (0 == g_usGh3x2xDataIndexInBuf)\r
+    {\r
+        GH3X2X_Memset(g_usRawdataByteIndexArr, 0, sizeof(g_usRawdataByteIndexArr[0]) * GH3X2X_CHANNEL_MAP_MAX_CH);\r
+    }    \r
+\r
+    if (nAlgoCalcResultArr == GH3X2X_PTR_NULL)\r
+    {\r
+        uchAlgoResNum = 0;\r
+    }\r
+\r
+    if ((0 == g_usGh3x2xDataIndexInBuf) && (GH3X2X_ElectrodeWearRevertDebugModeIsEnabled()))\r
+    {\r
+        uchAlgoResNum++;\r
+        uchFrameDataNum += GH3X2X_ALGO_RESULT_WITH_TAG_CALC(1) + 1;\r
+        uchAlgoResFlag = 1;\r
+    }\r
+\r
+    if (GH3X2X_CHECK_LEFT_BIT_SET(g_usDumpMode, GH3X2X_DUMP_GAIN_CURRENT_ENABLE_BIT))\r
+    {\r
+        uchGainCurDataNum = (GU8)GH3X2X_DUMP_GAIN_CURRENT_CALC(uchChannelMapCnt);\r
+        uchFrameDataNum  += uchGainCurDataNum;\r
+    }\r
+\r
+    if (GH3X2X_CHECK_LEFT_BIT_SET(g_usDumpMode, GH3X2X_DUMP_AMBIANCE_ENABLE_BIT))\r
+    {\r
+        uchAmbiDataNum    = (GU8)GH3X2X_DUMP_AMBIANCE_CALC(uchChannelMapCnt);\r
+        uchFrameDataNum  += uchAmbiDataNum;\r
+    }\r
+    \r
+    if ((pstGsAxisValueArr == GH3X2X_PTR_NULL) || (0 == usGsDataNum))\r
+    {\r
+        uchGsEnable = 0;\r
+    }\r
+    else\r
+    {\r
+        uchGsEnable = 1;\r
+        uchFrameDataNum += GH3X2X_GSENSOR_DATA_SIZE;\r
+    }    \r
+    \r
+    chRet = GH3X2X_GetDumpDataInfo(&fIndexInc, &usDataCnt, &uchNextIncompleteFlag, uchDumpDataIndexArr, \r
+                        punLastIncompleteArr, usFifoRawdataLen, puchFifoRawdata, \r
+                        uchChannelMapCnt, uchChannelMapArr, puchChannelBgLvlArr, usGsDataNum);\r
+    \r
+    if (0 != g_usGh3x2xDataIndexInBuf)\r
+    {\r
+        GH3X2X_Memset(uchDumpDataIndexArr, 0, sizeof(uchDumpDataIndexArr));\r
+    }\r
+    \r
+    if (GH3X2X_RET_OK == chRet)\r
+    {\r
+        g_pstGh3x2xProtocolData->puchPacketPayloadArr[UPROTOCOL_RAWDATA_TYPE_INDEX] = \\r
+                                                GH3X2X_VAL_LEFT_SHIFT(uchChannelMapId, UPROTOCOL_FUNC_ID_FIELD)\r
+                                                | GH3X2X_VAL_LEFT_SHIFT(uchGsEnable, UPROTOCOL_GS_ENABLE_FIELD)\r
+                                                | GH3X2X_VAL_LEFT_SHIFT(uchAlgoResFlag, UPROTOCOL_ALGO_ENABLE_FIELD);\r
+        \r
+        if (GH3X2X_CHECK_LEFT_BIT_SET(g_usDumpMode, GH3X2X_DUMP_GAIN_CURRENT_ENABLE_BIT))\r
+        {\r
+            g_pstGh3x2xProtocolData->puchPacketPayloadArr[UPROTOCOL_RAWDATA_TYPE_INDEX] |= \\r
+                                                GH3X2X_GET_LEFT_SHIFT_VAL(UPROTOCOL_AGC_ENABLE_FIELD);\r
+        }\r
+\r
+        if (GH3X2X_CHECK_LEFT_BIT_SET(g_usDumpMode, GH3X2X_DUMP_AMBIANCE_ENABLE_BIT))\r
+        {\r
+            g_pstGh3x2xProtocolData->puchPacketPayloadArr[UPROTOCOL_RAWDATA_TYPE_INDEX] |= \\r
+                                                GH3X2X_GET_LEFT_SHIFT_VAL(UPROTOCOL_AMBIANCE_ENABLE_FIELD);\r
+        }\r
+        \r
+        usPayloadIndex = UPROTOCOL_FRAME_DATA_INDEX;\r
+        for (usDataIndex = g_usGh3x2xDataIndexInBuf; usDataIndex < usDataCnt; usDataIndex++)\r
+        {        \r
+            uchZipDataFirstFrameSta = (usDataIndex == g_usGh3x2xDataIndexInBuf);\r
+            //judge if will exceed payload length limit\r
+            g_pstGh3x2xProtocolData->puchPacketPayloadArr[usPayloadIndex] = g_pstGh3x2xProtocolData->uchFrameIdArr[uchChannelMapId];  //FrameID\r
+            usFrameidIndex = usPayloadIndex;\r
+            g_pstGh3x2xProtocolData->uchFrameIdArr[uchChannelMapId]++;\r
+            usPayloadIndex++;\r
+            if (1 == uchGsEnable)\r
+            {\r
+                GH3X2X_FillGsensorData(&usPayloadIndex, &pstGsAxisValueArr[(GU16)g_fGsDataIndexInBuf]);\r
+                g_fGsDataIndexInBuf += fIndexInc;\r
+            }\r
+            \r
+            for (uchChCntIndex = 0; uchChCntIndex < uchChannelMapCnt; uchChCntIndex++) // search each channel\r
+            {\r
+                uchDumpDataCalcTmp = g_uchDumpDataCntMapArr[puchChannelBgLvlArr[uchChCntIndex]];\r
+                usRawdataByteIndexTmpBeforeHandleArr[uchChCntIndex] = g_usRawdataByteIndexArr[uchChCntIndex];\r
+                if (uchDumpDataIndexArr[uchChCntIndex] < uchDumpDataCalcTmp)\r
+                {\r
+                    usRawdataByteIndexTmp = g_usRawdataByteIndexArr[uchChCntIndex];\r
+                    while (usRawdataByteIndexTmp < usFifoRawdataLen) // search each\r
+                    {\r
+                        if (GH3X2X_CHANNEL_MAP_GET(puchFifoRawdata[usRawdataByteIndexTmp]) == \\r
+                                                                    uchChannelMapArr[uchChCntIndex]) // if map equal\r
+                        {\r
+                            punIncompleteDumpdataArr[uchChCntIndex][uchDumpDataIndexArr[uchChCntIndex]] = \\r
+                                                GH3X2X_MAKEUP_DWORD(puchFifoRawdata[usRawdataByteIndexTmp + 3],\r
+                                                                    puchFifoRawdata[usRawdataByteIndexTmp + 2],\r
+                                                                    puchFifoRawdata[usRawdataByteIndexTmp + 1],\r
+                                                                    puchFifoRawdata[usRawdataByteIndexTmp]);\r
+                            uchDumpDataIndexArr[uchChCntIndex]++;\r
+                            if (uchDumpDataIndexArr[uchChCntIndex] >= uchDumpDataCalcTmp)\r
+                            {\r
+                                usRawdataByteIndexTmp += GH3X2X_FIFO_RAWDATA_SIZE;\r
+                                break;\r
+                            }\r
+                        }\r
+                        usRawdataByteIndexTmp += GH3X2X_FIFO_RAWDATA_SIZE;\r
+                    }\r
+                }\r
+\r
+                uchDumpDataIndexArr[uchChCntIndex] = 0;\r
+                g_usRawdataByteIndexArr[uchChCntIndex] = usRawdataByteIndexTmp; // write back byte index\r
+            } // end of for (uchChCntIndex = 0; uchChCntIndex < uchChannelMapCnt; uchChCntIndex++)\r
+\r
+            uchZipRet = GH3X2X_FillZipDumpData(&usPayloadIndex, uchChannelMapArr, uchChannelMapCnt, \\r
+                                puchChannelBgLvlArr, g_usDumpMode, punIncompleteDumpdataArr, uchZipDataFirstFrameSta, \\r
+                                &uchZipDiffDataSize, uchGainCurDataNum, uchAmbiDataNum);\r
+\r
+            if (1 == uchZipRet)\r
+            {\r
+                GH3X2X_ZipPackFullStatusHandle(uchChannelMapId, usFrameidIndex, fIndexInc, \\r
+                            &usPayloadIndex, &usRawdataByteIndexTmp, \\r
+                            uchChannelMapCnt, usRawdataByteIndexTmpBeforeHandleArr);\r
+                break;\r
+            }\r
+            \r
+            if (1 == uchAlgoResFlag)\r
+            {\r
+                if (usPayloadIndex + (GU16)GH3X2X_ALGO_RESULT_WITH_TAG_CALC(uchAlgoResNum) + 1 >= \\r
+                        (GU16)GH3X2X_UPROTOCOL_GET_PAYLOAD_LEN_SUPPORT(g_uchPacketMaxLenSupport))\r
+                {\r
+                    GH3X2X_ZipPackFullStatusHandle(uchChannelMapId, usFrameidIndex, fIndexInc, \\r
+                            &usPayloadIndex, &usRawdataByteIndexTmp, \\r
+                            uchChannelMapCnt, usRawdataByteIndexTmpBeforeHandleArr);\r
+                    break;\r
+                }\r
+                g_pstGh3x2xProtocolData->puchPacketPayloadArr[usPayloadIndex] = GH3X2X_ALGO_RESULT_WITH_TAG_CALC(uchAlgoResNum);\r
+                usPayloadIndex++;\r
+                #if 0\r
+                if (nAlgoCalcResultArr != GH3X2X_PTR_NULL)\r
+                {\r
+                    if (GH3X2X_ElectrodeWearRevertDebugModeIsEnabled())\r
+                    {\r
+                        GH3X2X_FillAlgoData(&usPayloadIndex, nAlgoCalcResultArr, uchAlgoResNum - 1);\r
+                    }\r
+                    else\r
+                    {\r
+                        GH3X2X_FillAlgoData(&usPayloadIndex, nAlgoCalcResultArr, uchAlgoResNum);\r
+                    }\r
+                }\r
+                #endif\r
+                \r
+                if ((GH3X2X_ElectrodeWearRevertDebugModeIsEnabled()) && (0 == usDataIndex))\r
+                {\r
+                    GH3X2X_FillElectrodeWearRevertData(&usPayloadIndex);\r
+                    uchAlgoResNum -= 1;  //only the first frame data has Flag data\r
+                }\r
+                \r
+                //uchAlgoResFlag = 0;\r
+                //uchFrameDataNum -= (GH3X2X_ALGO_RESULT_WITH_TAG_CALC(uchAlgoResNum) + 1);\r
+            } // end of if (1 == uchAlgoResFlag)\r
+        } // end of for (usDataIndex = g_usGh3x2xDataIndexInBuf; usDataIndex < usDataCnt; usDataIndex++)\r
+        \r
+        if (usDataIndex < usDataCnt)\r
+        {\r
+            g_usGh3x2xDataIndexInBuf = usDataIndex;\r
+            chRet = GH3X2X_RET_RAW_DATA_PKG_CONTINUE;\r
+        }\r
+        else\r
+        {\r
+            g_usGh3x2xDataIndexInBuf = 0;\r
+            g_fGsDataIndexInBuf = 0;\r
+            chRet = GH3X2X_RET_RAW_DATA_PKG_OVER;\r
+            GH3X2X_CacheIncompleteDumpdata(punLastIncompleteArr, punIncompleteDumpdataArr, uchNextIncompleteFlag, \\r
+                                            puchFifoRawdata, usFifoRawdataLen, uchChannelMapArr, uchChannelMapCnt, \\r
+                                            g_usRawdataByteIndexArr);\r
+        } // end else\r
+\r
+        g_pstGh3x2xProtocolData->puchPacketPayloadArr[UPROTOCOL_RAWDATA_LEN_INDEX] = (GU8)(usPayloadIndex - UPROTOCOL_FRAME_DATA_INDEX);\r
+        uchSendCmd = GH3X2X_VAL_ZIPSENDCMD(g_uchDumpOddEvenChangeFlag);\r
+        /* respond packet format */\r
+        SET_VAL_VIA_PTR(pusRespondLen, GH3X2X_UprotocolPacketFormat(uchSendCmd, puchRespondBuffer,\r
+                                    g_pstGh3x2xProtocolData->puchPacketPayloadArr, usPayloadIndex));\r
+        g_uchDumpOddEvenChangeFlag = !g_uchDumpOddEvenChangeFlag;\r
+    } // end of if (GH3X2X_RET_OK == chRet)\r
+    else\r
+    {\r
+        pusRespondLen = 0;\r
+    }    \r
+\r
+    return chRet;\r
+}\r
+\r
+/**\r
+ * @fn     GS8 GH3X2X_SendHbDumpDataPkg(GU8 *puchRespondBuffer, GU16 *pusRespondLen, GU8 *puchFifoRawdata,\r
+                                            GS32 nAlgoResultArr[], STGsensorRawdata *pstGsAxisValueArr,\r
+                                            GU16 usGsDataNum, EMGsensorSensitivity emGsSensitivity)\r
+ *                  \r
+ * @brief  pack GH3X2X hb rawdata and other type of data according to specific protocol\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[out]  puchRespondBuffer       pointer to frame data package\r
+ * @param[out]  pusRespondLen           pointer to data length of package\r
+ * @param[in]   puchFifoRawdata         pointer to encrypted rawdata\r
+ * @param[in]   nAlgoResultArr          pointer to algorithm result\r
+ * @param[in]   pstGsAxisValueArr       pointer to g sensor data\r
+ * @param[in]   usGsDataNum             number of g sensor data\r
+ * @param[in]   emGsSensitivity         sensitivity of g sensor\r
+ *\r
+ * @return  error code\r
+ * @retval  #GH3X2X_RET_OK                      return successfully\r
+ * @retval  #GH3X2X_RET_GENERIC_ERROR           return func start error\r
+ * @retval  #GH3X2X_RET_NO_INITED_ERROR         gh3x2x has not inited\r
+ */\r
+GS8 GH3X2X_SendHbDumpDataPkg(GU8 *puchRespondBuffer, GU16 *pusRespondLen, GU8 *puchFifoRawdata,\r
+                                            GS32 nAlgoResultArr[], STGsensorRawdata *pstGsAxisValueArr,\r
+                                            GU16 usGsDataNum, EMGsensorSensitivity emGsSensitivity)\r
+{\r
+    GS8 chRet = GH3X2X_RET_OK;\r
+    GU8 uchHbaBgLevelArr[GH3X2X_HBA_CHANNEL_MAP_MAX_CNT] = {0};\r
+    if (GH3X2X_CHECK_BIT_SET(g_usFuncStartedBitmap, GH3X2X_STARTED_BITMAP_HBA))\r
+    {\r
+        GU16 usReadDataLen = 0;\r
+        GH3X2X_BgLevelDecode(uchHbaBgLevelArr, g_uchHbaChannelMapCnt, g_uchHbaChannelMapArr, g_usBgLevel);\r
+        GH3X2X_DecryptRawdataBuffer(puchFifoRawdata, &usReadDataLen);\r
+        chRet = GH3X2X_SendDumpDataPkgWithAlgo(puchRespondBuffer, pusRespondLen, g_uchHbaIncompleteArr, \r
+                                        g_unHbaIncompleteDumpdataArr, puchFifoRawdata, usReadDataLen,\r
+                                        g_uchHbaChannelMapArr, g_uchHbaChannelMapCnt, uchHbaBgLevelArr, \r
+                                        pstGsAxisValueArr, usGsDataNum,\r
+                                        emGsSensitivity, GH3X2X_PTR_NULL, GH3X2X_HB_ALGO_OUTPUT_NUM, GH3X2X_FUNC_OFFSET_HR);\r
+        GH3X2X_EncryptRawdataBuffer(puchFifoRawdata, usReadDataLen);\r
+    }\r
+    else\r
+    {\r
+        chRet = GH3X2X_RET_GENERIC_ERROR;\r
+        GH3X2X_DEBUG_LOG_PARAM("hba hasn't started error!\r\n");\r
+    }\r
+    return chRet;\r
+}\r
+\r
+/**\r
+ * @fn     GS8 GH3X2X_SendHbDumpDataPkgEx(GU8 *puchRespondBuffer, GU16 *pusRespondLen, GU8 *puchFifoRawdata, \r
+ *                                          GU16 usFifoDataLen, GS32 nAlgoResultArr[], \r
+ *                                          STGsensorRawdata *pstGsAxisValueArr, GU16 usGsDataNum, \r
+ *                                          EMGsensorSensitivity emGsSensitivity)\r
+ *                  \r
+ * @brief  pack GH3X2X hb rawdata and other type of data according to specific protocol\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[out]  puchRespondBuffer       pointer to frame data package\r
+ * @param[out]  pusRespondLen           pointer to data length of package\r
+ * @param[in]   puchFifoRawdata         pointer to encrypted rawdata\r
+ * @param[in]   usFifoDataLen           gh3x2x fifo data len in byte\r
+ * @param[in]   nAlgoResultArr          pointer to algorithm result\r
+ * @param[in]   pstGsAxisValueArr       pointer to g sensor data\r
+ * @param[in]   usGsDataNum             number of g sensor data\r
+ * @param[in]   emGsSensitivity         sensitivity of g sensor\r
+ *\r
+ * @return  error code\r
+ * @retval  #GH3X2X_RET_OK                      return successfully\r
+ * @retval  #GH3X2X_RET_GENERIC_ERROR           return func start error\r
+ * @retval  #GH3X2X_RET_NO_INITED_ERROR         gh3x2x has not inited\r
+ */\r
+GS8 GH3X2X_SendHbDumpDataPkgEx(GU8 *puchRespondBuffer, GU16 *pusRespondLen, GU8 *puchFifoRawdata, GU16 usFifoDataLen,\r
+                                            GS32 nAlgoResultArr[], STGsensorRawdata *pstGsAxisValueArr,\r
+                                            GU16 usGsDataNum, EMGsensorSensitivity emGsSensitivity)\r
+{\r
+    GS8 chRet = GH3X2X_RET_OK;\r
+    GU8 uchHbaBgLevelArr[GH3X2X_HBA_CHANNEL_MAP_MAX_CNT] = {0};\r
+    if (GH3X2X_CHECK_BIT_SET(g_usFuncStartedBitmap, GH3X2X_STARTED_BITMAP_HBA))\r
+    {\r
+        GH3X2X_BgLevelDecode(uchHbaBgLevelArr, g_uchHbaChannelMapCnt, g_uchHbaChannelMapArr, g_usBgLevel);\r
+        chRet = GH3X2X_SendDumpDataPkgWithAlgo(puchRespondBuffer, pusRespondLen, g_uchHbaIncompleteArr, \r
+                                        g_unHbaIncompleteDumpdataArr, puchFifoRawdata, usFifoDataLen,\r
+                                        g_uchHbaChannelMapArr, g_uchHbaChannelMapCnt, uchHbaBgLevelArr, \r
+                                        pstGsAxisValueArr, usGsDataNum,\r
+                                        emGsSensitivity, GH3X2X_PTR_NULL, GH3X2X_HB_ALGO_OUTPUT_NUM, GH3X2X_FUNC_OFFSET_HR);\r
+    }\r
+    else\r
+    {\r
+        chRet = GH3X2X_RET_GENERIC_ERROR;\r
+        GH3X2X_DEBUG_LOG_PARAM("hba hasn't started error!\r\n");\r
+    }\r
+    return chRet;\r
+}\r
+\r
+GS8 GH3X2X_SendHrvDumpDataPkg(GU8 *puchRespondBuffer, GU16 *pusRespondLen, GU8 *puchFifoRawdata,\r
+                                            GS32 nAlgoResultArr[], STGsensorRawdata *pstGsAxisValueArr,\r
+                                            GU16 usGsDataNum, EMGsensorSensitivity emGsSensitivity)\r
+{\r
+    GS8 chRet = GH3X2X_RET_OK;\r
+    GU8 uchHrvBgLevelArr[GH3X2X_HRV_CHANNEL_MAP_MAX_CNT] = {0};\r
+    if (GH3X2X_CHECK_BIT_SET(g_usFuncStartedBitmap, GH3X2X_STARTED_BITMAP_HRV))\r
+    {\r
+        GU16 usReadDataLen = 0;\r
+        GH3X2X_BgLevelDecode(uchHrvBgLevelArr, g_uchHrvChannelMapCnt, g_uchHrvChannelMapArr, g_usBgLevel);\r
+        GH3X2X_DecryptRawdataBuffer(puchFifoRawdata, &usReadDataLen);\r
+        chRet = GH3X2X_SendDumpDataPkgWithAlgo(puchRespondBuffer, pusRespondLen, g_uchHrvIncompleteArr, \r
+                                        g_unHrvIncompleteDumpdataArr, puchFifoRawdata, usReadDataLen,\r
+                                        g_uchHrvChannelMapArr, g_uchHrvChannelMapCnt, uchHrvBgLevelArr, \r
+                                        pstGsAxisValueArr, usGsDataNum,\r
+                                        emGsSensitivity, GH3X2X_PTR_NULL, GH3X2X_HRV_ALGO_OUTPUT_NUM, GH3X2X_FUNC_OFFSET_HRV);\r
+        GH3X2X_EncryptRawdataBuffer(puchFifoRawdata, usReadDataLen);\r
+    }\r
+    else\r
+    {\r
+        chRet = GH3X2X_RET_GENERIC_ERROR;\r
+        GH3X2X_DEBUG_LOG_PARAM("hrv hasn't started error!\r\n");\r
+    }\r
+    return chRet;\r
+}\r
+\r
+GS8 GH3X2X_SendHrvDumpDataPkgEx(GU8 *puchRespondBuffer, GU16 *pusRespondLen, GU8 *puchFifoRawdata, GU16 usFifoDataLen,\r
+                                            GS32 nAlgoResultArr[], STGsensorRawdata *pstGsAxisValueArr,\r
+                                            GU16 usGsDataNum, EMGsensorSensitivity emGsSensitivity)\r
+{\r
+    GS8 chRet = GH3X2X_RET_OK;\r
+    GU8 uchHrvBgLevelArr[GH3X2X_HRV_CHANNEL_MAP_MAX_CNT] = {0};\r
+    if (GH3X2X_CHECK_BIT_SET(g_usFuncStartedBitmap, GH3X2X_STARTED_BITMAP_HRV))\r
+    {\r
+        GH3X2X_BgLevelDecode(uchHrvBgLevelArr, g_uchHrvChannelMapCnt, g_uchHrvChannelMapArr, g_usBgLevel);\r
+        chRet = GH3X2X_SendDumpDataPkgWithAlgo(puchRespondBuffer, pusRespondLen, g_uchHrvIncompleteArr, \r
+                                        g_unHrvIncompleteDumpdataArr, puchFifoRawdata, usFifoDataLen,\r
+                                        g_uchHrvChannelMapArr, g_uchHrvChannelMapCnt, uchHrvBgLevelArr, \r
+                                        pstGsAxisValueArr, usGsDataNum,\r
+                                        emGsSensitivity, GH3X2X_PTR_NULL, GH3X2X_HRV_ALGO_OUTPUT_NUM, GH3X2X_FUNC_OFFSET_HRV);\r
+    }\r
+    else\r
+    {\r
+        chRet = GH3X2X_RET_GENERIC_ERROR;\r
+        GH3X2X_DEBUG_LOG_PARAM("hrv hasn't started error!\r\n");\r
+    }\r
+    return chRet;\r
+}\r
+\r
+/**\r
+ * @fn       GS8 GH3X2X_SendSpo2DumpDataPkg(GU8 *puchRespondBuffer, GU16 *pusRespondLen, GU8 *puchFifoRawdata,\r
+                                            GS32 nAlgoResultArr[], STGsensorRawdata *pstGsAxisValueArr,\r
+                                            GU16 usGsDataNum, EMGsensorSensitivity emGsSensitivity)\r
+ *                    \r
+ * @brief  pack GH3X2X hb rawdata and other type of data according to specific protocol\r
+ *\r
+ * @attention    None\r
+ *\r
+ * @param[out]   puchRespondBuffer         pointer to frame data package\r
+ * @param[out]   pusRespondLen             pointer to data length of package\r
+ * @param[in]    puchFifoRawdata           pointer to encrypted rawdata\r
+ * @param[in]    nAlgoResultArr            pointer to algorithm result\r
+ * @param[in]    pstGsAxisValueArr         pointer to g sensor data\r
+ * @param[in]    usGsDataNum               number of g sensor data\r
+ * @param[in]    emGsSensitivity           sensitivity of g sensor\r
+ *\r
+ * @return    error code\r
+ * @retval    #GH3X2X_RET_OK                        return successfully\r
+ * @retval    #GH3X2X_RET_GENERIC_ERROR             return func start error\r
+ * @retval    #GH3X2X_RET_NO_INITED_ERROR           gh3x2x has not inited\r
+ */\r
+GS8 GH3X2X_SendSpo2DumpDataPkg(GU8 *puchRespondBuffer, GU16 *pusRespondLen, GU8 *puchFifoRawdata,\r
+                                GS32 nAlgoResultArr[], STGsensorRawdata *pstGsAxisValueArr,\r
+                                GU16 usGsDataNum, EMGsensorSensitivity emGsSensitivity)\r
+{\r
+    GS8 chRet = GH3X2X_RET_OK;\r
+    GU8 uchSpo2LevelArr[GH3X2X_SPO2_CHANNEL_MAP_MAX_CNT] = {0};\r
+    if (GH3X2X_CHECK_BIT_SET(g_usFuncStartedBitmap, GH3X2X_STARTED_BITMAP_SPO2))\r
+    {\r
+        GU16 usReadDataLen = 0;\r
+        GH3X2X_BgLevelDecode(uchSpo2LevelArr, g_uchSpo2ChannelMapCnt, g_uchSpo2ChannelMapArr, g_usBgLevel);\r
+        GH3X2X_DecryptRawdataBuffer(puchFifoRawdata, &usReadDataLen);\r
+        chRet = GH3X2X_SendDumpDataPkgWithAlgo(puchRespondBuffer, pusRespondLen, g_uchSpo2IncompleteArr, \r
+                                        g_unSpo2IncompleteDumpdataArr, puchFifoRawdata, usReadDataLen,\r
+                                        g_uchSpo2ChannelMapArr, g_uchSpo2ChannelMapCnt, uchSpo2LevelArr, \r
+                                        pstGsAxisValueArr, usGsDataNum, emGsSensitivity, GH3X2X_PTR_NULL, \r
+                                        GH3X2X_SPO2_ALGO_OUTPUT_NUM, GH3X2X_FUNC_OFFSET_SPO2);\r
+        GH3X2X_EncryptRawdataBuffer(puchFifoRawdata, usReadDataLen);\r
+    }\r
+    else\r
+    {\r
+        chRet = GH3X2X_RET_GENERIC_ERROR;\r
+        GH3X2X_DEBUG_LOG_PARAM("spo2 hasn't started error!\r\n");\r
+    }\r
+    return chRet;\r
+}\r
+\r
+/**\r
+ * @fn       GS8 GH3X2X_SendSpo2DumpDataPkgEx(GU8 *puchRespondBuffer, GU16 *pusRespondLen, GU8 *puchFifoRawdata, \r
+ *                              GU16 usFifoDataLen, GS32 nAlgoResultArr[], STGsensorRawdata *pstGsAxisValueArr,\r
+                                GU16 usGsDataNum, EMGsensorSensitivity emGsSensitivity)\r
+ *                    \r
+ * @brief  pack GH3X2X hb rawdata and other type of data according to specific protocol\r
+ *\r
+ * @attention    None\r
+ *\r
+ * @param[out]   puchRespondBuffer         pointer to frame data package\r
+ * @param[out]   pusRespondLen             pointer to data length of package\r
+ * @param[in]    puchFifoRawdata           pointer to encrypted rawdata\r
+ * @param[in]    usFifoDataLen             gh3x2x fifo data len in byte\r
+ * @param[in]    nAlgoResultArr            pointer to algorithm result\r
+ * @param[in]    pstGsAxisValueArr         pointer to g sensor data\r
+ * @param[in]    usGsDataNum               number of g sensor data\r
+ * @param[in]    emGsSensitivity           sensitivity of g sensor\r
+ *\r
+ * @return    error code\r
+ * @retval    #GH3X2X_RET_OK                        return successfully\r
+ * @retval    #GH3X2X_RET_GENERIC_ERROR             return func start error\r
+ * @retval    #GH3X2X_RET_NO_INITED_ERROR           gh3x2x has not inited\r
+ */\r
+GS8 GH3X2X_SendSpo2DumpDataPkgEx(GU8 *puchRespondBuffer, GU16 *pusRespondLen, GU8 *puchFifoRawdata, GU16 usFifoDataLen, \r
+                                GS32 nAlgoResultArr[], STGsensorRawdata *pstGsAxisValueArr,\r
+                                GU16 usGsDataNum, EMGsensorSensitivity emGsSensitivity)\r
+{\r
+    GS8 chRet = GH3X2X_RET_OK;\r
+    GU8 uchSpo2LevelArr[GH3X2X_SPO2_CHANNEL_MAP_MAX_CNT] = {0};\r
+    if (GH3X2X_CHECK_BIT_SET(g_usFuncStartedBitmap, GH3X2X_STARTED_BITMAP_SPO2))\r
+    {\r
+        GH3X2X_BgLevelDecode(uchSpo2LevelArr, g_uchSpo2ChannelMapCnt, g_uchSpo2ChannelMapArr, g_usBgLevel);\r
+        chRet = GH3X2X_SendDumpDataPkgWithAlgo(puchRespondBuffer, pusRespondLen, g_uchSpo2IncompleteArr, \r
+                                        g_unSpo2IncompleteDumpdataArr, puchFifoRawdata, usFifoDataLen,\r
+                                        g_uchSpo2ChannelMapArr, g_uchSpo2ChannelMapCnt, uchSpo2LevelArr, \r
+                                        pstGsAxisValueArr, usGsDataNum, emGsSensitivity, GH3X2X_PTR_NULL, \r
+                                        GH3X2X_SPO2_ALGO_OUTPUT_NUM, GH3X2X_FUNC_OFFSET_SPO2);\r
+    }\r
+    else\r
+    {\r
+        chRet = GH3X2X_RET_GENERIC_ERROR;\r
+        GH3X2X_DEBUG_LOG_PARAM("spo2 hasn't started error!\r\n");\r
+    }\r
+    return chRet;\r
+}      \r
+\r
+/**\r
+ * @fn     GS8 GH3X2X_SendZipHbDumpDataPkg(GU8 *puchRespondBuffer, GU16 *pusRespondLen, GU8 *puchFifoRawdata,\r
+                                            GS32 nAlgoResultArr[], STGsensorRawdata *pstGsAxisValueArr,\r
+                                            GU16 usGsDataNum, EMGsensorSensitivity emGsSensitivity)\r
+ *                  \r
+ * @brief  pack GH3X2X Zip hb rawdata and other type of data according to specific protocol\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[out]  puchRespondBuffer       pointer to frame data package\r
+ * @param[out]  pusRespondLen           pointer to data length of package\r
+ * @param[in]   puchFifoRawdata         pointer to encrypted rawdata\r
+ * @param[in]   nAlgoResultArr          pointer to algorithm result\r
+ * @param[in]   pstGsAxisValueArr       pointer to g sensor data\r
+ * @param[in]   usGsDataNum             number of g sensor data\r
+ * @param[in]   emGsSensitivity         sensitivity of g sensor\r
+ *\r
+ * @return  error code\r
+ * @retval  #GH3X2X_RET_OK                      return successfully\r
+ * @retval  #GH3X2X_RET_GENERIC_ERROR           return func start error\r
+ * @retval  #GH3X2X_RET_NO_INITED_ERROR         gh3x2x has not inited\r
+ */\r
+GS8 GH3X2X_SendZipHbDumpDataPkg(GU8 *puchRespondBuffer, GU16 *pusRespondLen, GU8 *puchFifoRawdata,\r
+                                            GS32 nAlgoResultArr[], STGsensorRawdata *pstGsAxisValueArr,\r
+                                            GU16 usGsDataNum, EMGsensorSensitivity emGsSensitivity)\r
+{\r
+    GS8 chRet = GH3X2X_RET_OK;\r
+    GU8 uchHbaBgLevelArr[GH3X2X_HBA_CHANNEL_MAP_MAX_CNT] = {0};\r
+    if (GH3X2X_CHECK_BIT_SET(g_usFuncStartedBitmap, GH3X2X_STARTED_BITMAP_HBA))\r
+    {\r
+        GU16 usReadDataLen = 0;\r
+        GH3X2X_BgLevelDecode(uchHbaBgLevelArr, g_uchHbaChannelMapCnt, g_uchHbaChannelMapArr, g_usBgLevel);\r
+        GH3X2X_DecryptRawdataBuffer(puchFifoRawdata, &usReadDataLen);\r
+        chRet = GH3X2X_SendZipDumpDataPkgWithAlgo(puchRespondBuffer, pusRespondLen, g_uchHbaIncompleteArr, \r
+                                        g_unHbaIncompleteDumpdataArr, puchFifoRawdata, usReadDataLen,\r
+                                        g_uchHbaChannelMapArr, g_uchHbaChannelMapCnt, uchHbaBgLevelArr, \r
+                                        pstGsAxisValueArr, usGsDataNum,\r
+                                        emGsSensitivity, GH3X2X_PTR_NULL, GH3X2X_HB_ALGO_OUTPUT_NUM, GH3X2X_FUNC_OFFSET_HR);\r
+        GH3X2X_EncryptRawdataBuffer(puchFifoRawdata, usReadDataLen);\r
+    }\r
+    else\r
+    {\r
+        chRet = GH3X2X_RET_GENERIC_ERROR;\r
+        GH3X2X_DEBUG_LOG_PARAM("hba hasn't started error!\r\n");\r
+    }\r
+    return chRet;\r
+}\r
+\r
+/**\r
+ * @fn     GS8 GH3X2X_SendZipHbDumpDataPkgEx(GU8 *puchRespondBuffer, GU16 *pusRespondLen, GU8 *puchFifoRawdata, \r
+ *                                          GU16 usFifoDataLen, GS32 nAlgoResultArr[], \r
+ *                                          STGsensorRawdata *pstGsAxisValueArr, GU16 usGsDataNum, \r
+ *                                          EMGsensorSensitivity emGsSensitivity)\r
+ *                  \r
+ * @brief  pack GH3X2X Zip hb rawdata and other type of data according to specific protocol\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[out]  puchRespondBuffer       pointer to frame data package\r
+ * @param[out]  pusRespondLen           pointer to data length of package\r
+ * @param[in]   puchFifoRawdata         pointer to encrypted rawdata\r
+ * @param[in]   usFifoDataLen           gh3x2x fifo data len in byte\r
+ * @param[in]   nAlgoResultArr          pointer to algorithm result\r
+ * @param[in]   pstGsAxisValueArr       pointer to g sensor data\r
+ * @param[in]   usGsDataNum             number of g sensor data\r
+ * @param[in]   emGsSensitivity         sensitivity of g sensor\r
+ *\r
+ * @return  error code\r
+ * @retval  #GH3X2X_RET_OK                      return successfully\r
+ * @retval  #GH3X2X_RET_GENERIC_ERROR           return func start error\r
+ * @retval  #GH3X2X_RET_NO_INITED_ERROR         gh3x2x has not inited\r
+ */\r
+GS8 GH3X2X_SendZipHbDumpDataPkgEx(GU8 *puchRespondBuffer, GU16 *pusRespondLen, GU8 *puchFifoRawdata, GU16 usFifoDataLen,\r
+                                            GS32 nAlgoResultArr[], STGsensorRawdata *pstGsAxisValueArr,\r
+                                            GU16 usGsDataNum, EMGsensorSensitivity emGsSensitivity)\r
+{\r
+    GS8 chRet = GH3X2X_RET_OK;\r
+    GU8 uchHbaBgLevelArr[GH3X2X_HBA_CHANNEL_MAP_MAX_CNT] = {0};\r
+    if (GH3X2X_CHECK_BIT_SET(g_usFuncStartedBitmap, GH3X2X_STARTED_BITMAP_HBA))\r
+    {\r
+        GH3X2X_BgLevelDecode(uchHbaBgLevelArr, g_uchHbaChannelMapCnt, g_uchHbaChannelMapArr, g_usBgLevel);\r
+        chRet = GH3X2X_SendZipDumpDataPkgWithAlgo(puchRespondBuffer, pusRespondLen, g_uchHbaIncompleteArr, \r
+                                        g_unHbaIncompleteDumpdataArr, puchFifoRawdata, usFifoDataLen,\r
+                                        g_uchHbaChannelMapArr, g_uchHbaChannelMapCnt, uchHbaBgLevelArr, \r
+                                        pstGsAxisValueArr, usGsDataNum,\r
+                                        emGsSensitivity, GH3X2X_PTR_NULL, GH3X2X_HB_ALGO_OUTPUT_NUM, GH3X2X_FUNC_OFFSET_HR);\r
+    }\r
+    else\r
+    {\r
+        chRet = GH3X2X_RET_GENERIC_ERROR;\r
+        GH3X2X_DEBUG_LOG_PARAM("hba hasn't started error!\r\n");\r
+    }\r
+    return chRet;\r
+}\r
+                                            /**\r
+ * @fn     GS8 GH3X2X_SendZipHrvDumpDataPkg(GU8 *puchRespondBuffer, GU16 *pusRespondLen, GU8 *puchFifoRawdata,\r
+                                            GS32 nAlgoResultArr[], STGsensorRawdata *pstGsAxisValueArr,\r
+                                            GU16 usGsDataNum, EMGsensorSensitivity emGsSensitivity)\r
+ *                  \r
+ * @brief  pack GH3X2X Zip hrv rawdata and other type of data according to specific protocol\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[out]  puchRespondBuffer       pointer to frame data package\r
+ * @param[out]  pusRespondLen           pointer to data length of package\r
+ * @param[in]   puchFifoRawdata         pointer to encrypted rawdata\r
+ * @param[in]   nAlgoResultArr          pointer to algorithm result\r
+ * @param[in]   pstGsAxisValueArr       pointer to g sensor data\r
+ * @param[in]   usGsDataNum             number of g sensor data\r
+ * @param[in]   emGsSensitivity         sensitivity of g sensor\r
+ *\r
+ * @return  error code\r
+ * @retval  #GH3X2X_RET_OK                      return successfully\r
+ * @retval  #GH3X2X_RET_GENERIC_ERROR           return func start error\r
+ * @retval  #GH3X2X_RET_NO_INITED_ERROR         gh3x2x has not inited\r
+ */\r
+GS8 GH3X2X_SendZipHrvDumpDataPkg(GU8 *puchRespondBuffer, GU16 *pusRespondLen, GU8 *puchFifoRawdata,\r
+                                            GS32 nAlgoResultArr[], STGsensorRawdata *pstGsAxisValueArr,\r
+                                            GU16 usGsDataNum, EMGsensorSensitivity emGsSensitivity)\r
+{\r
+    GS8 chRet = GH3X2X_RET_OK;\r
+    GU8 uchHrvBgLevelArr[GH3X2X_HRV_CHANNEL_MAP_MAX_CNT] = {0};\r
+    if (GH3X2X_CHECK_BIT_SET(g_usFuncStartedBitmap, GH3X2X_STARTED_BITMAP_HRV))\r
+    {\r
+        GU16 usReadDataLen = 0;\r
+        GH3X2X_BgLevelDecode(uchHrvBgLevelArr, g_uchHrvChannelMapCnt, g_uchHrvChannelMapArr, g_usBgLevel);\r
+        GH3X2X_DecryptRawdataBuffer(puchFifoRawdata, &usReadDataLen);\r
+        chRet = GH3X2X_SendZipDumpDataPkgWithAlgo(puchRespondBuffer, pusRespondLen, g_uchHrvIncompleteArr, \r
+                                        g_unHrvIncompleteDumpdataArr, puchFifoRawdata, usReadDataLen,\r
+                                        g_uchHrvChannelMapArr, g_uchHrvChannelMapCnt, uchHrvBgLevelArr, \r
+                                        pstGsAxisValueArr, usGsDataNum,\r
+                                        emGsSensitivity, GH3X2X_PTR_NULL, GH3X2X_HRV_ALGO_OUTPUT_NUM, GH3X2X_FUNC_OFFSET_HRV);\r
+        GH3X2X_EncryptRawdataBuffer(puchFifoRawdata, usReadDataLen);\r
+    }\r
+    else\r
+    {\r
+        chRet = GH3X2X_RET_GENERIC_ERROR;\r
+        GH3X2X_DEBUG_LOG_PARAM("hba hasn't started error!\r\n");\r
+    }\r
+    return chRet;\r
+}\r
+\r
+/**\r
+ * @fn     GS8 GH3X2X_SendZipHrvDumpDataPkgEx(GU8 *puchRespondBuffer, GU16 *pusRespondLen, GU8 *puchFifoRawdata, \r
+ *                                          GU16 usFifoDataLen, GS32 nAlgoResultArr[], \r
+ *                                          STGsensorRawdata *pstGsAxisValueArr, GU16 usGsDataNum, \r
+ *                                          EMGsensorSensitivity emGsSensitivity)\r
+ *                  \r
+ * @brief  pack GH3X2X Zip hrv rawdata and other type of data according to specific protocol\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[out]  puchRespondBuffer       pointer to frame data package\r
+ * @param[out]  pusRespondLen           pointer to data length of package\r
+ * @param[in]   puchFifoRawdata         pointer to encrypted rawdata\r
+ * @param[in]   usFifoDataLen           gh3x2x fifo data len in byte\r
+ * @param[in]   nAlgoResultArr          pointer to algorithm result\r
+ * @param[in]   pstGsAxisValueArr       pointer to g sensor data\r
+ * @param[in]   usGsDataNum             number of g sensor data\r
+ * @param[in]   emGsSensitivity         sensitivity of g sensor\r
+ *\r
+ * @return  error code\r
+ * @retval  #GH3X2X_RET_OK                      return successfully\r
+ * @retval  #GH3X2X_RET_GENERIC_ERROR           return func start error\r
+ * @retval  #GH3X2X_RET_NO_INITED_ERROR         gh3x2x has not inited\r
+ */\r
+GS8 GH3X2X_SendZipHrvDumpDataPkgEx(GU8 *puchRespondBuffer, GU16 *pusRespondLen, GU8 *puchFifoRawdata, GU16 usFifoDataLen,\r
+                                            GS32 nAlgoResultArr[], STGsensorRawdata *pstGsAxisValueArr,\r
+                                            GU16 usGsDataNum, EMGsensorSensitivity emGsSensitivity)\r
+{\r
+    GS8 chRet = GH3X2X_RET_OK;\r
+    GU8 uchHrvBgLevelArr[GH3X2X_HRV_CHANNEL_MAP_MAX_CNT] = {0};\r
+    if (GH3X2X_CHECK_BIT_SET(g_usFuncStartedBitmap, GH3X2X_STARTED_BITMAP_HRV))\r
+    {\r
+        GH3X2X_BgLevelDecode(uchHrvBgLevelArr, g_uchHrvChannelMapCnt, g_uchHrvChannelMapArr, g_usBgLevel);\r
+        chRet = GH3X2X_SendZipDumpDataPkgWithAlgo(puchRespondBuffer, pusRespondLen, g_uchHrvIncompleteArr, \r
+                                        g_unHrvIncompleteDumpdataArr, puchFifoRawdata, usFifoDataLen,\r
+                                        g_uchHrvChannelMapArr, g_uchHrvChannelMapCnt, uchHrvBgLevelArr, \r
+                                        pstGsAxisValueArr, usGsDataNum,\r
+                                        emGsSensitivity, GH3X2X_PTR_NULL, GH3X2X_HRV_ALGO_OUTPUT_NUM, GH3X2X_FUNC_OFFSET_HRV);\r
+    }\r
+    else\r
+    {\r
+        chRet = GH3X2X_RET_GENERIC_ERROR;\r
+        GH3X2X_DEBUG_LOG_PARAM("hrv hasn't started error!\r\n");\r
+    }\r
+    return chRet;\r
+}\r
+\r
+/**\r
+ * @fn       GS8 GH3X2X_SendZipSpo2DumpDataPkg(GU8 *puchRespondBuffer, GU16 *pusRespondLen, GU8 *puchFifoRawdata,\r
+                                            GS32 nAlgoResultArr[], STGsensorRawdata *pstGsAxisValueArr,\r
+                                            GU16 usGsDataNum, EMGsensorSensitivity emGsSensitivity)\r
+ *                    \r
+ * @brief  pack GH3X2X Zip spo2 rawdata and other type of data according to specific protocol\r
+ *\r
+ * @attention    None\r
+ *\r
+ * @param[out]   puchRespondBuffer         pointer to frame data package\r
+ * @param[out]   pusRespondLen             pointer to data length of package\r
+ * @param[in]    puchFifoRawdata           pointer to encrypted rawdata\r
+ * @param[in]    nAlgoResultArr            pointer to algorithm result\r
+ * @param[in]    pstGsAxisValueArr         pointer to g sensor data\r
+ * @param[in]    usGsDataNum               number of g sensor data\r
+ * @param[in]    emGsSensitivity           sensitivity of g sensor\r
+ *\r
+ * @return    error code\r
+ * @retval    #GH3X2X_RET_OK                        return successfully\r
+ * @retval    #GH3X2X_RET_GENERIC_ERROR             return func start error\r
+ * @retval    #GH3X2X_RET_NO_INITED_ERROR           gh3x2x has not inited\r
+ */\r
+GS8 GH3X2X_SendZipSpo2DumpDataPkg(GU8 *puchRespondBuffer, GU16 *pusRespondLen, GU8 *puchFifoRawdata,\r
+                                GS32 nAlgoResultArr[], STGsensorRawdata *pstGsAxisValueArr,\r
+                                GU16 usGsDataNum, EMGsensorSensitivity emGsSensitivity)\r
+{\r
+    GS8 chRet = GH3X2X_RET_OK;\r
+    GU8 uchSpo2LevelArr[GH3X2X_SPO2_CHANNEL_MAP_MAX_CNT] = {0};\r
+    if (GH3X2X_CHECK_BIT_SET(g_usFuncStartedBitmap, GH3X2X_STARTED_BITMAP_SPO2))\r
+    {\r
+        GU16 usReadDataLen = 0;\r
+        GH3X2X_BgLevelDecode(uchSpo2LevelArr, g_uchSpo2ChannelMapCnt, g_uchSpo2ChannelMapArr, g_usBgLevel);\r
+        GH3X2X_DecryptRawdataBuffer(puchFifoRawdata, &usReadDataLen);\r
+        chRet = GH3X2X_SendZipDumpDataPkgWithAlgo(puchRespondBuffer, pusRespondLen, g_uchSpo2IncompleteArr, \r
+                                        g_unSpo2IncompleteDumpdataArr, puchFifoRawdata, usReadDataLen,\r
+                                        g_uchSpo2ChannelMapArr, g_uchSpo2ChannelMapCnt, uchSpo2LevelArr, \r
+                                        pstGsAxisValueArr, usGsDataNum, emGsSensitivity, GH3X2X_PTR_NULL, \r
+                                        GH3X2X_SPO2_ALGO_OUTPUT_NUM, GH3X2X_FUNC_OFFSET_SPO2);\r
+        GH3X2X_EncryptRawdataBuffer(puchFifoRawdata, usReadDataLen);\r
+    }\r
+    else\r
+    {\r
+        chRet = GH3X2X_RET_GENERIC_ERROR;\r
+        GH3X2X_DEBUG_LOG_PARAM("spo2 hasn't started error!\r\n");\r
+    }\r
+    return chRet;\r
+}\r
+\r
+/**\r
+ * @fn       GS8 GH3X2X_SendZipSpo2DumpDataPkgEx(GU8 *puchRespondBuffer, GU16 *pusRespondLen, GU8 *puchFifoRawdata, \r
+ *                              GU16 usFifoDataLen, GS32 nAlgoResultArr[], STGsensorRawdata *pstGsAxisValueArr,\r
+                                GU16 usGsDataNum, EMGsensorSensitivity emGsSensitivity)\r
+ *                    \r
+ * @brief  pack GH3X2X Zip spo2 rawdata and other type of data according to specific protocol\r
+ *\r
+ * @attention    None\r
+ *\r
+ * @param[out]   puchRespondBuffer         pointer to frame data package\r
+ * @param[out]   pusRespondLen             pointer to data length of package\r
+ * @param[in]    puchFifoRawdata           pointer to encrypted rawdata\r
+ * @param[in]    usFifoDataLen             gh3x2x fifo data len in byte\r
+ * @param[in]    nAlgoResultArr            pointer to algorithm result\r
+ * @param[in]    pstGsAxisValueArr         pointer to g sensor data\r
+ * @param[in]    usGsDataNum               number of g sensor data\r
+ * @param[in]    emGsSensitivity           sensitivity of g sensor\r
+ *\r
+ * @return    error code\r
+ * @retval    #GH3X2X_RET_OK                        return successfully\r
+ * @retval    #GH3X2X_RET_GENERIC_ERROR             return func start error\r
+ * @retval    #GH3X2X_RET_NO_INITED_ERROR           gh3x2x has not inited\r
+ */\r
+GS8 GH3X2X_SendZipSpo2DumpDataPkgEx(GU8 *puchRespondBuffer, GU16 *pusRespondLen, GU8 *puchFifoRawdata, GU16 usFifoDataLen, \r
+                                GS32 nAlgoResultArr[], STGsensorRawdata *pstGsAxisValueArr,\r
+                                GU16 usGsDataNum, EMGsensorSensitivity emGsSensitivity)\r
+{\r
+    GS8 chRet = GH3X2X_RET_OK;\r
+    GU8 uchSpo2LevelArr[GH3X2X_SPO2_CHANNEL_MAP_MAX_CNT] = {0};\r
+    if (GH3X2X_CHECK_BIT_SET(g_usFuncStartedBitmap, GH3X2X_STARTED_BITMAP_SPO2))\r
+    {\r
+        GH3X2X_BgLevelDecode(uchSpo2LevelArr, g_uchSpo2ChannelMapCnt, g_uchSpo2ChannelMapArr, g_usBgLevel);\r
+        chRet = GH3X2X_SendZipDumpDataPkgWithAlgo(puchRespondBuffer, pusRespondLen, g_uchSpo2IncompleteArr, \r
+                                        g_unSpo2IncompleteDumpdataArr, puchFifoRawdata, usFifoDataLen,\r
+                                        g_uchSpo2ChannelMapArr, g_uchSpo2ChannelMapCnt, uchSpo2LevelArr, \r
+                                        pstGsAxisValueArr, usGsDataNum, emGsSensitivity, GH3X2X_PTR_NULL, \r
+                                        GH3X2X_SPO2_ALGO_OUTPUT_NUM, GH3X2X_FUNC_OFFSET_SPO2);\r
+    }\r
+    else\r
+    {\r
+        chRet = GH3X2X_RET_GENERIC_ERROR;\r
+        GH3X2X_DEBUG_LOG_PARAM("spo2 hasn't started error!\r\n");\r
+    }\r
+    return chRet;\r
+}     \r
+#endif\r
+/**\r
+ * @fn         GS8 GH3X2X_DumpRawdataFilter(GU8* puchRawDataBuffer, GU16* usRawDataLen, GU8 punLastIncompleteFlagArr[], \r
+                            GU32 punIncompleteDumpdataArr[][GH3X2X_MAX_DUMP_DATA_NUM_CHANNEL], GU8* puchReadFifoBuffer, \r
+                            GU16 usFifoLen, GU16 usBgLevel)\r
+ *                      \r
+ * @brief  filter dump fifo data to get rawdata\r
+ *\r
+ * @attention     None\r
+ *\r
+ * @param[out]     puchRawDataBuffer           pointer to rawdata buffer\r
+ * @param[out]     usRawDataLen               pointer to rawdata number\r
+ * @param[out]     punLastIncompleteFlagArr  pointer to incomplete flag array\r
+ * @param[out]     punIncompleteDumpdataArr  pointer to incomplete data\r
+ * @param[in]     puchReadFifoBuffer           pointer to fifo data buffer\r
+ * @param[in]     usFifoLen                 fifo data num\r
+ * @param[in]     usBgLevel                 slot bg level\r
+ *\r
+ * @return      error code\r
+ * @retval      #GH3X2X_RET_OK                        return successfully\r
+ * @retval      #GH3X2X_RET_PARAMETER_ERROR             return parameter error\r
+ */\r
+GS8 GH3X2X_DumpRawdataFilter(GU8* puchRawDataBuffer, GU16* usRawDataLen, GU8 punLastIncompleteFlagArr[], \r
+                            GU32 punIncompleteDumpdataArr[][GH3X2X_MAX_DUMP_DATA_NUM_CHANNEL], GU8* puchReadFifoBuffer, \r
+                            GU16 usFifoLen, GU16 usBgLevel)\r
+{\r
+    GS8  schRetValue           = GH3X2X_RET_OK;\r
+    GU16 usDataIndex           = 0;\r
+    GU8  uchSlotIndex          = 0;\r
+    GU8  uchAdcIndex           = 0;\r
+    GU8  uchChIndex            = 0;\r
+    GU8  uchBgLevel            = 0;\r
+    GU8  puchDumpDataCntArr[GH3X2X_CHANNEL_MAP_MAX_CH] = {0};        //save dump data number of every channel\r
+    GU8  uchDumpDataCnt        = 0;\r
+    GU8  uchDumpDataNum        = 0;                                  //dump data num of correspond bg level\r
+    GU32 unPpgDataFilter       = 0;\r
+\r
+    if ((GH3X2X_PTR_NULL == puchRawDataBuffer) || (GH3X2X_PTR_NULL == usRawDataLen) || \\r
+        (GH3X2X_PTR_NULL == punLastIncompleteFlagArr) || (GH3X2X_PTR_NULL == punIncompleteDumpdataArr) || \\r
+        (GH3X2X_PTR_NULL ==  puchReadFifoBuffer) || (0 ==  usFifoLen))\r
+    {\r
+        usRawDataLen = 0;\r
+        schRetValue = GH3X2X_RET_PARAMETER_ERROR;\r
+        return schRetValue;\r
+    }\r
+        \r
+    //get current dump data index of every channel by count incomplete data\r
+    for (uchChIndex = 0; uchChIndex < GH3X2X_CHANNEL_MAP_MAX_CH; ++uchChIndex)\r
+    {\r
+        //loop time can be decided by bg level\r
+        uchBgLevel = g_uchChannelBgLvlArr[uchChIndex];\r
+        uchDumpDataNum = g_uchDumpDataCntMapArr[uchBgLevel];\r
+        for (uchDumpDataCnt = 0; uchDumpDataCnt < uchDumpDataNum; ++uchDumpDataCnt)\r
+        {\r
+            //if imcomplete bit flag is 1\r
+            if (GH3X2X_CHECK_LEFT_BIT_SET(punLastIncompleteFlagArr[uchChIndex], uchDumpDataCnt))\r
+            {\r
+                puchDumpDataCntArr[uchChIndex]++;\r
+                if (puchDumpDataCntArr[uchChIndex] >= uchDumpDataNum)\r
+                {\r
+                    GH3X2X_DEBUG_LOG_PARAM("Cache incomplete data too much!\r\n");\r
+                }\r
+            }\r
+            else\r
+            {\r
+                break;\r
+            }\r
+        }\r
+    }\r
+\r
+    *usRawDataLen = 0;\r
+    \r
+    //filter every rawdata\r
+    for (usDataIndex = 0; usDataIndex < usFifoLen; usDataIndex += GH3X2X_FIFO_RAWDATA_SIZE)\r
+    {\r
+        //decode slot adc index\r
+        uchChIndex   = GH3X2X_BYTE_RAWDATA_GET_SLOT_ADC_NUM(puchReadFifoBuffer[usDataIndex]);\r
+        uchSlotIndex = GH3X2X_BYTE_RAWDATA_GET_SLOT_NUM(puchReadFifoBuffer[usDataIndex]);\r
+        uchAdcIndex  = GH3X2X_BYTE_RAWDATA_GET_ADC_NUM(puchReadFifoBuffer[usDataIndex]);\r
+        \r
+        if (GH3X2X_CHECK_LEFT_BIT_SET(g_uchEcgSlot, uchSlotIndex))\r
+        {\r
+            //ECG data not need to filter\r
+            if (uchAdcIndex == GH3X2X_ECG_ADC_INDEX)\r
+            {\r
+                GH3X2X_Memcpy(&puchRawDataBuffer[*usRawDataLen], &puchReadFifoBuffer[usDataIndex], \\r
+                                GH3X2X_FIFO_RAWDATA_SIZE);\r
+                *usRawDataLen += GH3X2X_FIFO_RAWDATA_SIZE;\r
+                continue;\r
+            }\r
+        }\r
+        //decode bg level\r
+        uchBgLevel     = g_uchChannelBgLvlArr[uchChIndex];\r
+        uchDumpDataNum = g_uchDumpDataCntMapArr[uchBgLevel];\r
+        //save them to implete array\r
+        GH3X2X_Memcpy(&punIncompleteDumpdataArr[uchChIndex][puchDumpDataCntArr[uchChIndex]], \\r
+                        &puchReadFifoBuffer[usDataIndex], GH3X2X_FIFO_RAWDATA_SIZE);\r
+        //set incomplete flag\r
+        punLastIncompleteFlagArr[uchChIndex] |= (GU8)GH3X2X_GET_LEFT_SHIFT_VAL(puchDumpDataCntArr[uchChIndex]);\r
+        puchDumpDataCntArr[uchChIndex]++;        \r
+        //if save enough,calculate it,and save it to g_uchRawdataFilterArr,and clear incomplete flag\r
+        if (puchDumpDataCntArr[uchChIndex] >= uchDumpDataNum)\r
+        {\r
+            switch (uchBgLevel)\r
+            {\r
+            case GH3X2X_DUMP_RAWDATA_BGLVL0:\r
+                GH3X2X_Memcpy(&puchRawDataBuffer[*usRawDataLen], &punIncompleteDumpdataArr[uchChIndex][1], \\r
+                        GH3X2X_FIFO_RAWDATA_SIZE);\r
+                break;\r
+            case GH3X2X_DUMP_RAWDATA_BGLVL1:\r
+                unPpgDataFilter = GH3X2X_DumpRawDataPro(punIncompleteDumpdataArr[uchChIndex][2], \\r
+                                                        punIncompleteDumpdataArr[uchChIndex][1], \\r
+                                                        punIncompleteDumpdataArr[uchChIndex][1]);\r
+                GH3X2X_Memcpy(&puchRawDataBuffer[*usRawDataLen], &unPpgDataFilter, GH3X2X_FIFO_RAWDATA_SIZE);\r
+                break;\r
+            case GH3X2X_DUMP_RAWDATA_BGLVL2:\r
+                unPpgDataFilter = GH3X2X_DumpRawDataPro(punIncompleteDumpdataArr[uchChIndex][2], \\r
+                                                        punIncompleteDumpdataArr[uchChIndex][1], \\r
+                                                        punIncompleteDumpdataArr[uchChIndex][3]);\r
+                GH3X2X_Memcpy(&puchRawDataBuffer[*usRawDataLen], &unPpgDataFilter, GH3X2X_FIFO_RAWDATA_SIZE);\r
+                break;\r
+            case GH3X2X_DUMP_RAWDATA_BGLVL2X2:\r
+                unPpgDataFilter = GH3X2X_DumpRawDataPro(punIncompleteDumpdataArr[uchChIndex][0], \\r
+                                                        punIncompleteDumpdataArr[uchChIndex - GH3X2X_ADC_NUM][3], \\r
+                                                        punIncompleteDumpdataArr[uchChIndex][1]);\r
+                GH3X2X_Memcpy(&puchRawDataBuffer[*usRawDataLen], &unPpgDataFilter, GH3X2X_FIFO_RAWDATA_SIZE);\r
+                break;\r
+            default:\r
+                break;\r
+            }\r
+            *usRawDataLen += GH3X2X_FIFO_RAWDATA_SIZE;\r
+            puchDumpDataCntArr[uchChIndex] = 0;\r
+            punLastIncompleteFlagArr[uchChIndex] = 0;\r
+        }  // end if (puchDumpDataCntArr[uchChIndex] >= uchDumpDataNum)  \r
+    } // end for (usDataIndex = 0; usDataIndex < usFifoLen; usDataIndex += GH3X2X_FIFO_RAWDATA_SIZE)\r
+    return schRetValue;\r
+}\r
+\r
+/**\r
+ * @fn     void GH3X2X_LedAgcProcessExDump(GU8* puchReadFifoBuffer)\r
+ * \r
+ * @brief  led agc process function\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   puchReadFifoBuffer         pointer to read fifo data buffer\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_LedAgcProcessExDump(GU8* puchReadFifoBuffer)\r
+{\r
+    GU16 usFifoLen    = 0;\r
+    GU16 usRawdataLen = 0;\r
+    GS8  schRetValue  = GH3X2X_RET_OK;\r
+    //if (GH3X2X_LED_AGC_ENABLE != GH3X2X_GetLedAgcState())\r
+    //{\r
+    //    return;\r
+    //}\r
+    GH3X2X_Memset(g_uchRawdataFilterArr, 0, RAWDATA_FILTER_ARRAY_BYTE_LENGTH * sizeof(g_uchRawdataFilterArr[0]));\r
+    //filter dump data,because AGC only process raw data\r
+    schRetValue = GH3X2X_DumpRawdataFilter(g_uchRawdataFilterArr, &usRawdataLen, g_uchDumpIncompleteFlagArr, \\r
+                            g_unDumpIncompleteRawdataArr, puchReadFifoBuffer, usFifoLen, g_usBgLevel);\r
+    if (GH3X2X_RET_OK == schRetValue)\r
+    {\r
+        GH3X2X_LedAgcProcess(g_uchRawdataFilterArr, usRawdataLen);\r
+    }    \r
+}\r
+\r
+#endif\r
+/********END OF FILE********* Copyright (c) 2003 - 2022, Goodix Co., Ltd. ********/\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/driver/src/gh_drv_interface.c b/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/driver/src/gh_drv_interface.c
new file mode 100644 (file)
index 0000000..6941ef5
--- /dev/null
@@ -0,0 +1,957 @@
+/**\r
+ * @copyright (c) 2003 - 2022, Goodix Co., Ltd. All rights reserved.\r
+ *\r
+ * @file    gh3x2x_drv_interface.c\r
+ *\r
+ * @brief   gh3x2x interface functions\r
+ *\r
+ * @version ref gh3x2x_drv_version.h\r
+ *\r
+ */\r
+\r
+#include "gh_drv_version.h"\r
+#include "gh_drv_common.h"\r
+#include "gh_drv.h"\r
+#include "gh_drv_interface.h"\r
+#include "gh_drv_control.h"\r
+#include "gh_demo.h"\r
+#include "gh_demo_config.h"\r
+#include "gh_demo_inner.h"\r
+\r
+/// swap size of GU16\r
+#define SWAP_SIZE_OF_GU16               (2)\r
+\r
+/// swap index of next byte\r
+#define SWAP_INDEX_OF_NEXT_BYTE         (1)\r
+\r
+/* index of interface buffer */\r
+#define INTERFACE_INDEX_0_BUFFER        (0)     /**< index 0 of buffer */\r
+#define INTERFACE_INDEX_1_BUFFER        (1)     /**< index 1 of buffer */\r
+#define INTERFACE_INDEX_2_BUFFER        (2)     /**< index 2 of buffer */\r
+#define INTERFACE_INDEX_3_BUFFER        (3)     /**< index 3 of buffer */\r
+#define INTERFACE_INDEX_4_BUFFER        (4)     /**< index 4 of buffer */\r
+#define INTERFACE_INDEX_5_BUFFER        (5)     /**< index 5 of buffer */\r
+#define INTERFACE_INDEX_6_BUFFER        (6)     /**< index 6 of buffer */\r
+#define INTERFACE_INDEX_7_BUFFER        (7)     /**< index 7 of buffer */\r
+\r
+/* spi operation */\r
+#define SPI_CMD_BUFFER_LEN              (1)     /**< spi cmd buffer len */\r
+#define SPI_WRITE_REG_BUFFER_LEN        (7)     /**< spi write reg buffer len */\r
+#define SPI_WRITE_REG_LEN_H             (0x00)  /**< spi write reg len high byte */ \r
+#define SPI_WRITE_REG_LEN_L             (0x02)  /**< spi write reg len low byte */\r
+#define SPI_READ_REG_BUFFER_LEN         (3)     /**< spi read reg buffer len */\r
+#define SPI_READ_REG_CMD_LEN            (1)     /**< spi read reg buffer len */\r
+#define SPI_READ_REG_DATA_LEN           (2)     /**< spi read reg buffer len */\r
+\r
+/* i2c operation */\r
+#define I2C_CMD_BUFFER_LEN              (3)     /**< i2c cmd buffer len */\r
+#define I2C_WRITE_REG_BUFFER_LEN        (4)     /**< i2c write reg buffer len */\r
+#define I2C_READ_REG_ADDR_LEN           (2)     /**< i2c read reg buffer len */\r
+#define I2C_READ_REG_DATA_LEN           (2)     /**< i2c read reg buffer len */\r
+\r
+\r
+/// \r
+GU8 g_uchGh3x2xChipOperateIndexRealtime = 0;   //0: chip0  1: chip1\r
+GU8 g_uchGh3x2xLogicMasterChipIndex = 0;   //0: default master chip index    1: chip1(for mp test)\r
+\r
+\r
+GU8 g_uchGhx2xChipSleepFlag = 0x03;  // bit0: 0: chip0 wake up  1: chip0 sleep   bit1: 0: chip1 wake up  1: chip1 sleep\r
+\r
+GU8 g_uchChipDivZeroFlag= 0; // 1: divde 0 happen\r
+\r
+/// i2c device addr\r
+GU8 g_puchI2cDeviceIdList[2] = {GH3X2X_I2C_DEVICE_ID_BASE, GH3X2X_I2C_DEVICE_ID_BASE};\r
+\r
+/// delay us func ptr\r
+static pfnDelayUs   g_pDelayUsFunc      = GH3X2X_PTR_NULL;\r
+\r
+/// spi write func ptr\r
+static pfnSpiRWCtrl g_pSpiWriteFunc     = GH3X2X_PTR_NULL;\r
+\r
+/// spi read func ptr\r
+static pfnSpiRWCtrl g_pSpiReadFunc      = GH3X2X_PTR_NULL;\r
+\r
+/// spi cs ctrl func ptr\r
+static pfnSpiCsCtrl g_pSpiCsCtrlFunc    = GH3X2X_PTR_NULL;\r
+\r
+/// i2c write func ptr\r
+static pfnI2cWrite  g_pI2cWriteFunc     = GH3X2X_PTR_NULL;\r
+\r
+/// i2c read func ptr\r
+static pfnI2cRead   g_pI2cReadFunc      = GH3X2X_PTR_NULL;\r
+\r
+/// gh3x2x send cmd func ptr\r
+static pfnSendCmd   g_pGh3x2xSendCmdFunc  = GH3X2X_PTR_NULL;\r
+\r
+/// gh3x2x write reg func ptr\r
+static pfnWriteReg  g_pGh3x2xWriteRegFunc = GH3X2X_PTR_NULL;\r
+\r
+/// gh3x2x read reg func ptr\r
+static pfnReadReg   g_pGh3x2xReadRegFunc  = GH3X2X_PTR_NULL;\r
+\r
+/// gh3x2x read regs func ptr\r
+static pfnReadRegs  g_pGh3x2xReadRegsFunc = GH3X2X_PTR_NULL;\r
+\r
+/// gh3x2x read fifo func ptr\r
+static pfnReadFifo  g_pGh3x2xReadFifoFunc = GH3X2X_PTR_NULL;\r
+\r
+\r
+/**\r
+ * @fn     void GH3X2X_SwapLittleBigEndianData(GU8 *puchDataBuffer, GU16 usDataLength)\r
+ *\r
+ * @brief  Swap little big endian data\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   puchDataBuffer   pointer to data buffer.\r
+ * @param[in]   usDataLength    data buffer len.\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_SwapLittleBigEndianData(GU8 *puchDataBuffer, GU16 usDataLength)\r
+{\r
+    GU16 usIndex = 0;\r
+\r
+    for (usIndex = 0; usIndex < (usDataLength / SWAP_SIZE_OF_GU16); usIndex++)\r
+    {\r
+        puchDataBuffer[usIndex * SWAP_SIZE_OF_GU16] ^= \\r
+                                                puchDataBuffer[usIndex * SWAP_SIZE_OF_GU16 + SWAP_INDEX_OF_NEXT_BYTE];\r
+        puchDataBuffer[usIndex * SWAP_SIZE_OF_GU16 + SWAP_INDEX_OF_NEXT_BYTE] ^= \\r
+                                                puchDataBuffer[usIndex * SWAP_SIZE_OF_GU16];\r
+        puchDataBuffer[usIndex * SWAP_SIZE_OF_GU16] ^= \\r
+                                                puchDataBuffer[usIndex * SWAP_SIZE_OF_GU16 + SWAP_INDEX_OF_NEXT_BYTE];\r
+    }\r
+}\r
+\r
+/**\r
+ * @fn     void GH3X2X_DelayUs(GU16 usUsCnt)\r
+ *\r
+ * @brief  Delay N Us for gh3x2x\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   usUsCnt     count need to delay(Us)\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_DelayUs(GU16 usUsCnt)\r
+{\r
+    if (g_pDelayUsFunc != GH3X2X_PTR_NULL)\r
+    {\r
+        g_pDelayUsFunc(usUsCnt);\r
+    }\r
+    else\r
+    {\r
+        volatile GU8 uchIndex;\r
+        while (usUsCnt > 0)\r
+        {\r
+            for (uchIndex = 0; uchIndex < GH3X2X_DELAY_ONE_US_CNT; uchIndex++)\r
+            {\r
+                // do nothing, like _nop(); \r
+            }\r
+            usUsCnt--;\r
+        }\r
+    }\r
+}\r
+\r
+/**\r
+ * @fn     void GH3X2X_RegisterDelayUsCallback(void (*pPlatformDelayUsFunc)(GU16 usUsec))\r
+ *\r
+ * @brief  Register delay us callback function\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   pPlatformDelayUsFunc      pointer to delay us function\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_RegisterDelayUsCallback(void (*pPlatformDelayUsFunc)(GU16 usUsec))\r
+{\r
+    GH3X2X_DEBUG_LOG_PARAM("%s\r\n", __FUNCTION__);\r
+    g_pDelayUsFunc = pPlatformDelayUsFunc;\r
+}\r
+\r
+/**\r
+ * @fn     static void GH3X2X_SpiSendCmd(GU8 uchCmd)\r
+ *\r
+ * @brief  Send cmd via spi\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   uchCmd      spi cmd\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+static void GH3X2X_SpiSendCmd(GU8 uchCmd)\r
+{\r
+    GU8 uchBuffArr[SPI_CMD_BUFFER_LEN];\r
+\r
+    g_pSpiCsCtrlFunc(GH3X2X_SPI_CS_CTRL_LOW);\r
+    uchBuffArr[INTERFACE_INDEX_0_BUFFER] = uchCmd;\r
+    g_pSpiWriteFunc(uchBuffArr, SPI_CMD_BUFFER_LEN);\r
+    g_pSpiCsCtrlFunc(GH3X2X_SPI_CS_CTRL_HIGH);\r
+    GH3X2X_DelayUs(GH3X2X_SPI_END_DELAY_X_US);\r
+}\r
+\r
+\r
+static void GH3X2X_SpiSendCmdHardwareCs(GU8 uchCmd)\r
+{\r
+    GU8 uchBuffArr[SPI_CMD_BUFFER_LEN];\r
+\r
+    uchBuffArr[INTERFACE_INDEX_0_BUFFER] = uchCmd;\r
+    g_pSpiWriteFunc(uchBuffArr, SPI_CMD_BUFFER_LEN);\r
+}\r
+\r
+\r
+/**\r
+ * @fn     static void GH3X2X_SpiWriteReg(GU16 usRegAddr, GU16 usRegValue)\r
+ *\r
+ * @brief  Write register via spi\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   usRegAddr       register addr\r
+ * @param[in]   usRegValue      register data\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+static void GH3X2X_SpiWriteReg(GU16 usRegAddr, GU16 usRegValue)\r
+{\r
+    GU8 uchBuffArr[SPI_WRITE_REG_BUFFER_LEN];\r
+\r
+    g_pSpiCsCtrlFunc(GH3X2X_SPI_CS_CTRL_LOW);\r
+    uchBuffArr[INTERFACE_INDEX_0_BUFFER] = GH3X2X_SPI_CMD_WRITE;\r
+    uchBuffArr[INTERFACE_INDEX_1_BUFFER] = GH3X2X_GET_HIGH_BYTE_FROM_WORD(usRegAddr);\r
+    uchBuffArr[INTERFACE_INDEX_2_BUFFER] = GH3X2X_GET_LOW_BYTE_FROM_WORD(usRegAddr);\r
+    uchBuffArr[INTERFACE_INDEX_3_BUFFER] = SPI_WRITE_REG_LEN_H;\r
+    uchBuffArr[INTERFACE_INDEX_4_BUFFER] = SPI_WRITE_REG_LEN_L;\r
+    uchBuffArr[INTERFACE_INDEX_5_BUFFER] = GH3X2X_GET_HIGH_BYTE_FROM_WORD(usRegValue);\r
+    uchBuffArr[INTERFACE_INDEX_6_BUFFER] = GH3X2X_GET_LOW_BYTE_FROM_WORD(usRegValue);\r
+    g_pSpiWriteFunc(uchBuffArr, SPI_WRITE_REG_BUFFER_LEN);\r
+    GH3X2X_DelayUs(GH3X2X_SPI_WAIT_DELAY_X_US);\r
+    g_pSpiCsCtrlFunc(GH3X2X_SPI_CS_CTRL_HIGH);\r
+    GH3X2X_DelayUs(GH3X2X_SPI_END_DELAY_X_US);\r
+}\r
+\r
+\r
+static void GH3X2X_SpiWriteRegHardwareCs(GU16 usRegAddr, GU16 usRegValue)\r
+{\r
+    GU8 puchWriteBuf[7];\r
+    puchWriteBuf[0] = 0xF0;\r
+    puchWriteBuf[1] = usRegAddr>>8;\r
+    puchWriteBuf[2] = usRegAddr&0x00FF;\r
+    puchWriteBuf[3] = 0;\r
+    puchWriteBuf[4] = 2;\r
+    puchWriteBuf[5] = usRegValue>>8;\r
+    puchWriteBuf[6] = usRegValue&0x00FF;\r
+    g_pSpiWriteFunc(puchWriteBuf, SPI_WRITE_REG_BUFFER_LEN);\r
+}\r
+\r
+\r
+\r
+\r
+\r
+\r
+/**\r
+ * @fn     static GU16 GH3X2X_SpiReadReg(GU16 usRegAddr)\r
+ *\r
+ * @brief  Read register via spi\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   usRegAddr      register addr\r
+ * @param[out]  None\r
+ *\r
+ * @return  register data\r
+ */\r
+static GU16 GH3X2X_SpiReadReg(GU16 usRegAddr)\r
+{\r
+    GU8 uchBuffArr[SPI_READ_REG_BUFFER_LEN] = {0};\r
+\r
+    g_pSpiCsCtrlFunc(GH3X2X_SPI_CS_CTRL_LOW);\r
+    uchBuffArr[INTERFACE_INDEX_0_BUFFER] = GH3X2X_SPI_CMD_WRITE;\r
+    uchBuffArr[INTERFACE_INDEX_1_BUFFER] = GH3X2X_GET_HIGH_BYTE_FROM_WORD(usRegAddr);\r
+    uchBuffArr[INTERFACE_INDEX_2_BUFFER] = GH3X2X_GET_LOW_BYTE_FROM_WORD(usRegAddr);\r
+    g_pSpiWriteFunc(uchBuffArr, SPI_READ_REG_BUFFER_LEN);\r
+    GH3X2X_DelayUs(GH3X2X_SPI_WAIT_DELAY_X_US);\r
+    g_pSpiCsCtrlFunc(GH3X2X_SPI_CS_CTRL_HIGH);\r
+    GH3X2X_DelayUs(GH3X2X_SPI_END_DELAY_X_US);\r
+    g_pSpiCsCtrlFunc(GH3X2X_SPI_CS_CTRL_LOW);\r
+    uchBuffArr[INTERFACE_INDEX_0_BUFFER] = GH3X2X_SPI_CMD_READ;\r
+    g_pSpiWriteFunc(uchBuffArr, SPI_READ_REG_CMD_LEN);\r
+    g_pSpiReadFunc(uchBuffArr, SPI_READ_REG_DATA_LEN);\r
+    GH3X2X_DelayUs(GH3X2X_SPI_WAIT_DELAY_X_US);\r
+    g_pSpiCsCtrlFunc(GH3X2X_SPI_CS_CTRL_HIGH);\r
+    GH3X2X_DelayUs(GH3X2X_SPI_END_DELAY_X_US);\r
+    return GH3X2X_MAKEUP_WORD(uchBuffArr[INTERFACE_INDEX_0_BUFFER], uchBuffArr[INTERFACE_INDEX_1_BUFFER]);\r
+}\r
+\r
+\r
+static GU16 GH3X2X_SpiReadRegHardwareCs(GU16 usRegAddr)\r
+{\r
+    GU8 puchWriteBuf[7];\r
+    GU8 puchReadBuf[2];\r
+    puchWriteBuf[0] = 0xF0;\r
+    puchWriteBuf[1] = usRegAddr>>8;\r
+    puchWriteBuf[2] = usRegAddr&0x00FF;\r
+    g_pSpiWriteFunc(puchWriteBuf, 3);\r
+    g_pSpiReadFunc(puchReadBuf, 2);\r
+    return ((((GU16)puchReadBuf[0])<<8) + puchReadBuf[1]);\r
+}\r
+\r
+\r
+\r
+\r
+\r
+/**\r
+ * @fn     static void GH3X2X_SpiReadRegs(GU16 usRegAddr, GU16 *pusRegValueBuffer, GU16 uchLen)\r
+ *\r
+ * @brief  Read multi register via spi\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   usRegAddr           register addr\r
+ * @param[in]   pusRegValueBuffer   pointer to register value buffer\r
+ * @param[in]   uchLen              registers len\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+static void GH3X2X_SpiReadRegs(GU16 usRegAddr, GU16 *pusRegValueBuffer, GU16 uchLen)\r
+{\r
+    GU8 uchBuffArr[SPI_READ_REG_BUFFER_LEN] = {0};\r
+\r
+    g_pSpiCsCtrlFunc(GH3X2X_SPI_CS_CTRL_LOW);\r
+    uchBuffArr[INTERFACE_INDEX_0_BUFFER] = GH3X2X_SPI_CMD_WRITE;\r
+    uchBuffArr[INTERFACE_INDEX_1_BUFFER] = GH3X2X_GET_HIGH_BYTE_FROM_WORD(usRegAddr);\r
+    uchBuffArr[INTERFACE_INDEX_2_BUFFER] = GH3X2X_GET_LOW_BYTE_FROM_WORD(usRegAddr);\r
+    g_pSpiWriteFunc(uchBuffArr, SPI_READ_REG_BUFFER_LEN);\r
+    GH3X2X_DelayUs(GH3X2X_SPI_WAIT_DELAY_X_US);\r
+    g_pSpiCsCtrlFunc(GH3X2X_SPI_CS_CTRL_HIGH);\r
+    GH3X2X_DelayUs(GH3X2X_SPI_END_DELAY_X_US);\r
+    g_pSpiCsCtrlFunc(GH3X2X_SPI_CS_CTRL_LOW);\r
+    uchBuffArr[INTERFACE_INDEX_0_BUFFER] = GH3X2X_SPI_CMD_READ;\r
+    g_pSpiWriteFunc(uchBuffArr, SPI_READ_REG_CMD_LEN);\r
+    g_pSpiReadFunc((GU8 *)pusRegValueBuffer, uchLen * SPI_READ_REG_DATA_LEN);\r
+    GH3X2X_SwapLittleBigEndianData((GU8 *)pusRegValueBuffer, (GU16)((GU16)uchLen * SPI_READ_REG_DATA_LEN));\r
+    GH3X2X_DelayUs(GH3X2X_SPI_WAIT_DELAY_X_US);\r
+    g_pSpiCsCtrlFunc(GH3X2X_SPI_CS_CTRL_HIGH);\r
+    GH3X2X_DelayUs(GH3X2X_SPI_END_DELAY_X_US);\r
+}\r
+\r
+\r
+\r
+static void GH3X2X_SpiReadRegsHardwareCs(GU16 usRegAddr, GU16 *pusRegValueBuffer, GU16 uchLen)\r
+{\r
+    GU8 puchWriteBuf[3];\r
+    puchWriteBuf[0] = 0xF0;\r
+    puchWriteBuf[1] = usRegAddr>>8;\r
+    puchWriteBuf[2] = usRegAddr&0x00FF;\r
+    g_pSpiWriteFunc(puchWriteBuf, 3);\r
+    g_pSpiReadFunc((GU8 *)pusRegValueBuffer, uchLen * SPI_READ_REG_DATA_LEN);\r
+    GH3X2X_SwapLittleBigEndianData((GU8 *)pusRegValueBuffer, (GU16)((GU16)uchLen * SPI_READ_REG_DATA_LEN));\r
+    \r
+}\r
+\r
+\r
+\r
+\r
+\r
+/**\r
+ * @fn     static void GH3X2X_SpiReadFifo(GU8 *puchDataBuffer, GU16 usLen)\r
+ *\r
+ * @brief  Read fifo via spi\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   puchDataBuffer      pointer to buffer for fifo rawdata\r
+ * @param[in]   usLen               fifo bytes len\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+static void GH3X2X_SpiReadFifo(GU8 *puchDataBuffer, GU16 usLen)\r
+{\r
+    GU8 uchBuffArr[SPI_READ_REG_BUFFER_LEN] = {0};\r
+\r
+    g_pSpiCsCtrlFunc(GH3X2X_SPI_CS_CTRL_LOW);\r
+    uchBuffArr[INTERFACE_INDEX_0_BUFFER] = GH3X2X_SPI_CMD_WRITE;\r
+    uchBuffArr[INTERFACE_INDEX_1_BUFFER] = GH3X2X_GET_HIGH_BYTE_FROM_WORD(GH3X2X_FIFO_REG_ADDR);\r
+    uchBuffArr[INTERFACE_INDEX_2_BUFFER] = GH3X2X_GET_LOW_BYTE_FROM_WORD(GH3X2X_FIFO_REG_ADDR);\r
+    g_pSpiWriteFunc(uchBuffArr, SPI_READ_REG_BUFFER_LEN);\r
+    GH3X2X_DelayUs(GH3X2X_SPI_WAIT_DELAY_X_US);\r
+    g_pSpiCsCtrlFunc(GH3X2X_SPI_CS_CTRL_HIGH);\r
+    GH3X2X_DelayUs(GH3X2X_SPI_END_DELAY_X_US);\r
+    g_pSpiCsCtrlFunc(GH3X2X_SPI_CS_CTRL_LOW);\r
+    uchBuffArr[INTERFACE_INDEX_0_BUFFER] = GH3X2X_SPI_CMD_READ;\r
+    g_pSpiWriteFunc(uchBuffArr, SPI_READ_REG_CMD_LEN);\r
+    g_pSpiReadFunc(puchDataBuffer, usLen);\r
+    GH3X2X_DelayUs(GH3X2X_SPI_WAIT_DELAY_X_US);\r
+    g_pSpiCsCtrlFunc(GH3X2X_SPI_CS_CTRL_HIGH);\r
+    GH3X2X_DelayUs(GH3X2X_SPI_END_DELAY_X_US);\r
+}\r
+\r
+static void GH3X2X_SpiReadFifoHardwareCs(GU8 *puchDataBuffer, GU16 usLen)\r
+{\r
+    GU8 puchWriteBuf[3];\r
+    puchWriteBuf[0] = 0xF0;\r
+    puchWriteBuf[1] = 0xAAAA>>8;\r
+    puchWriteBuf[2] = 0xAAAA&0x00FF;\r
+    g_pSpiWriteFunc(puchWriteBuf, 3);\r
+    g_pSpiReadFunc(puchDataBuffer, usLen);\r
+}\r
+\r
+\r
+/**\r
+ * @fn     static void GH3X2X_I2cSendCmd(GU8 uchCmd)\r
+ *\r
+ * @brief  Send cmd via i2c\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   uchCmd      i2c cmd\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+static void GH3X2X_I2cSendCmd(GU8 uchCmd)\r
+{\r
+    GU8 uchBuffArr[I2C_CMD_BUFFER_LEN] = {0};\r
+\r
+    uchBuffArr[INTERFACE_INDEX_0_BUFFER] = GH3X2X_GET_HIGH_BYTE_FROM_WORD(GH3X2X_I2C_CMD_ADDR);\r
+    uchBuffArr[INTERFACE_INDEX_1_BUFFER] = GH3X2X_GET_LOW_BYTE_FROM_WORD(GH3X2X_I2C_CMD_ADDR);\r
+    uchBuffArr[INTERFACE_INDEX_2_BUFFER] = uchCmd;\r
+    g_pI2cWriteFunc(g_puchI2cDeviceIdList[g_uchGh3x2xChipOperateIndexRealtime], uchBuffArr, I2C_CMD_BUFFER_LEN);\r
+}\r
+\r
+/**\r
+ * @fn     static void GH3X2X_I2cWriteReg(GU16 usRegAddr, GU16 usRegValue)\r
+ *\r
+ * @brief  Write register via i2c\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   usRegAddr       register addr\r
+ * @param[in]   usRegValue      register data\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+static void GH3X2X_I2cWriteReg(GU16 usRegAddr, GU16 usRegValue)\r
+{\r
+    GU8 uchBuffArr[I2C_WRITE_REG_BUFFER_LEN] = {0};\r
+\r
+    uchBuffArr[INTERFACE_INDEX_0_BUFFER] = GH3X2X_GET_HIGH_BYTE_FROM_WORD(usRegAddr);\r
+    uchBuffArr[INTERFACE_INDEX_1_BUFFER] = GH3X2X_GET_LOW_BYTE_FROM_WORD(usRegAddr);\r
+    uchBuffArr[INTERFACE_INDEX_2_BUFFER] = GH3X2X_GET_HIGH_BYTE_FROM_WORD(usRegValue);\r
+    uchBuffArr[INTERFACE_INDEX_3_BUFFER] = GH3X2X_GET_LOW_BYTE_FROM_WORD(usRegValue);\r
+    g_pI2cWriteFunc(g_puchI2cDeviceIdList[g_uchGh3x2xChipOperateIndexRealtime], uchBuffArr, I2C_WRITE_REG_BUFFER_LEN);\r
+}\r
+\r
+/**\r
+ * @fn     static GU16 GH3X2X_I2cReadReg(GU16 usRegAddr)\r
+ *\r
+ * @brief  Read register via i2c\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   usRegAddr      register addr\r
+ * @param[out]  None\r
+ *\r
+ * @return  register data\r
+ */\r
+static GU16 GH3X2X_I2cReadReg(GU16 usRegAddr)\r
+{\r
+    GU8 uchCmdBuffArr[I2C_READ_REG_ADDR_LEN] = {0};\r
+    GU8 uchReadBuffArr[I2C_READ_REG_DATA_LEN] = {0};\r
+\r
+    uchCmdBuffArr[INTERFACE_INDEX_0_BUFFER] = GH3X2X_GET_HIGH_BYTE_FROM_WORD(usRegAddr);\r
+    uchCmdBuffArr[INTERFACE_INDEX_1_BUFFER] = GH3X2X_GET_LOW_BYTE_FROM_WORD(usRegAddr);\r
+    g_pI2cReadFunc(g_puchI2cDeviceIdList[g_uchGh3x2xChipOperateIndexRealtime], uchCmdBuffArr, I2C_READ_REG_ADDR_LEN, uchReadBuffArr, I2C_READ_REG_DATA_LEN);\r
+    return GH3X2X_MAKEUP_WORD(uchReadBuffArr[INTERFACE_INDEX_0_BUFFER], uchReadBuffArr[INTERFACE_INDEX_1_BUFFER]);\r
+}\r
+\r
+/**\r
+ * @fn     static void GH3X2X_I2cReadRegs(GU16 usRegAddr, GU16 *pusRegValueArr, GU16 uchLen)\r
+ *\r
+ * @brief  Read multi register via i2c\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   usRegAddr           register addr\r
+ * @param[in]   pusRegValueBuffer   pointer to register value buffer\r
+ * @param[in]   uchLen              registers len\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+static void GH3X2X_I2cReadRegs(GU16 usRegAddr, GU16 *pusRegValueArr, GU16 uchLen)\r
+{\r
+    GU8 uchBuffArr[I2C_READ_REG_ADDR_LEN] = {0};\r
+\r
+    uchBuffArr[INTERFACE_INDEX_0_BUFFER] = GH3X2X_GET_HIGH_BYTE_FROM_WORD(usRegAddr);\r
+    uchBuffArr[INTERFACE_INDEX_1_BUFFER] = GH3X2X_GET_LOW_BYTE_FROM_WORD(usRegAddr);\r
+    g_pI2cReadFunc(g_puchI2cDeviceIdList[g_uchGh3x2xChipOperateIndexRealtime], uchBuffArr, I2C_READ_REG_ADDR_LEN, \\r
+                        (GU8 *)pusRegValueArr, uchLen * I2C_READ_REG_DATA_LEN);\r
+    GH3X2X_SwapLittleBigEndianData((GU8 *)pusRegValueArr, (GU16)uchLen * I2C_READ_REG_DATA_LEN);\r
+}\r
+\r
+/**\r
+ * @fn     static void GH3X2X_I2cReadFifo(GU8 *puchDataBuffer, GU16 usLen)\r
+ *\r
+ * @brief  Read fifo via i2c\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   puchDataBuffer      pointer to buffer for fifo rawdata\r
+ * @param[in]   usLen               fifo bytes len\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+static void GH3X2X_I2cReadFifo(GU8 *puchDataBuffer, GU16 usLen)\r
+{\r
+    GU8 uchCmdBuffArr[I2C_READ_REG_ADDR_LEN] = {0};\r
+\r
+    uchCmdBuffArr[INTERFACE_INDEX_0_BUFFER] = GH3X2X_GET_HIGH_BYTE_FROM_WORD(GH3X2X_FIFO_REG_ADDR);\r
+    uchCmdBuffArr[INTERFACE_INDEX_1_BUFFER] = GH3X2X_GET_LOW_BYTE_FROM_WORD(GH3X2X_FIFO_REG_ADDR);\r
+    g_pI2cReadFunc(g_puchI2cDeviceIdList[g_uchGh3x2xChipOperateIndexRealtime], uchCmdBuffArr, I2C_READ_REG_ADDR_LEN, puchDataBuffer, usLen);\r
+}\r
+\r
+/**\r
+ * @fn     void GH3X2X_SendCmd(GU8 uchCmd)\r
+ *\r
+ * @brief  Send cmd via i2c or spi\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   uchCmd      cmd\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_SendCmd(GU8 uchCmd)\r
+{\r
+    if (g_pGh3x2xSendCmdFunc != GH3X2X_PTR_NULL)\r
+    {\r
+        g_pGh3x2xSendCmdFunc(uchCmd);\r
+    }\r
+    else\r
+    {\r
+        GH3X2X_DEBUG_LOG_PARAM("communicate interface register error!\r\n");\r
+    }\r
+}\r
+\r
+\r
+void GH3X2X_TryWakeUp(void)\r
+{\r
+    GU8 uchSleepFlag;\r
+    uchSleepFlag = (g_uchGhx2xChipSleepFlag&(1 << g_uchGh3x2xChipOperateIndexRealtime));\r
+    if(uchSleepFlag)\r
+    {\r
+        g_uchGhx2xChipSleepFlag &= (~(1 << g_uchGh3x2xChipOperateIndexRealtime));  //clear sleep flag\r
+        GH3X2X_ExitLowPowerMode();\r
+    }\r
+}\r
+\r
+\r
+\r
+/**\r
+ * @fn     void GH3X2X_ClearChipSleepFlag(GU8 uchChipIndex)\r
+ *\r
+ * @brief  clear chip sleep flag\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   uchChipIndex  0: chip0  1: chip1\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_ClearChipSleepFlag(GU8 uchChipIndex)\r
+{\r
+    g_uchGhx2xChipSleepFlag &= (~(1 << uchChipIndex)); \r
+}\r
+\r
+\r
+/**\r
+ * @fn     void GH3X2X_SetChipSleepFlag(GU8 uchChipIndex)\r
+ *\r
+ * @brief  set chip sleep flag\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   uchChipIndex  0: chip0  1: chip1\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_SetChipSleepFlag(GU8 uchChipIndex)\r
+{\r
+    g_uchGhx2xChipSleepFlag |= ((1 << uchChipIndex)); \r
+}\r
+\r
+#if GH3X2X_DIVIDE_ZERO_FLAG_UPLODE_EN\r
+void GH3X2X_SetDivZeroFlag()\r
+{\r
+    g_uchChipDivZeroFlag = 1;\r
+}\r
+\r
+void GH3X2X_ClearDivZeroFlag()\r
+{\r
+    g_uchChipDivZeroFlag = 0;\r
+    GOODIX_PLATFORM_INT_DIVIDE_ZERO_ENABLE_ENTITY();\r
+}\r
+#endif\r
+\r
+/**\r
+ * @fn     void GH3X2X_WriteReg(GU16 usRegAddr, GU16 usRegValue)\r
+ *\r
+ * @brief  Write register via i2c or spi\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   usRegAddr       register addr\r
+ * @param[in]   usRegValue      register data\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_WriteReg(GU16 usRegAddr, GU16 usRegValue)\r
+{\r
+    if (g_pGh3x2xWriteRegFunc != GH3X2X_PTR_NULL)\r
+    {\r
+        GH3X2X_TryWakeUp();\r
+        g_pGh3x2xWriteRegFunc(usRegAddr, usRegValue);\r
+    }\r
+    else\r
+    {\r
+        GH3X2X_DEBUG_LOG_PARAM("communicate interface register error!\r\n");\r
+    }\r
+}\r
+\r
+/**\r
+ * @fn     GU16 GH3X2X_ReadReg(GU16 usRegAddr)\r
+ *\r
+ * @brief  Read register via i2c or spi\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   usRegAddr      register addr\r
+ * @param[out]  None\r
+ *\r
+ * @return  register data\r
+ */\r
+GU16 GH3X2X_ReadReg(GU16 usRegAddr)\r
+{\r
+    GU16 usRegData = 0;\r
+\r
+    \r
+    if (g_pGh3x2xReadRegFunc != GH3X2X_PTR_NULL)\r
+    {\r
+        GH3X2X_TryWakeUp();\r
+        usRegData = g_pGh3x2xReadRegFunc(usRegAddr);\r
+    }\r
+    else\r
+    {\r
+        GH3X2X_DEBUG_LOG_PARAM("communicate interface register error!\r\n");\r
+    }\r
+    return usRegData;\r
+}\r
+\r
+/**\r
+ * @fn     GU32 GH3X2X_ReadRegs(GU16 usRegAddr, GU16 *pusRegValueBuffer, GU16 usLen)\r
+ *\r
+ * @brief  Read multi register via i2c or spi\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   usRegAddr           register addr\r
+ * @param[in]   pusRegValueBuffer   pointer to register value buffer\r
+ * @param[in]   uchLen              registers len\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+GU32 GH3X2X_ReadRegs(GU16 usRegAddr, GU16 *pusRegValueBuffer, GU16 usLen)\r
+{\r
+    GU32 unRegData = 0;\r
+    if (g_pGh3x2xReadRegsFunc != GH3X2X_PTR_NULL)\r
+    {\r
+        GH3X2X_TryWakeUp();\r
+        g_pGh3x2xReadRegsFunc(usRegAddr, pusRegValueBuffer, usLen);\r
+    }\r
+    else\r
+    {\r
+        GH3X2X_DEBUG_LOG_PARAM("communicate interface register error!\r\n");\r
+    }\r
+    return unRegData;\r
+}\r
+\r
+/**\r
+ * @fn     void GH3X2X_ReadFifo(GU8 *puchDataBuffer, GU16 usLen)\r
+ *\r
+ * @brief  Read fifo via i2c or spi\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   puchDataBuffer      pointer to buffer for fifo rawdata\r
+ * @param[in]   usLen               fifo bytes len\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_ReadFifo(GU8 *puchDataBuffer, GU16 usLen)\r
+{\r
+    if (g_pGh3x2xReadFifoFunc != GH3X2X_PTR_NULL)\r
+    {\r
+        GH3X2X_TryWakeUp();\r
+        g_pGh3x2xReadFifoFunc(puchDataBuffer, usLen);\r
+    }\r
+    else\r
+    {\r
+        GH3X2X_DEBUG_LOG_PARAM("communicate interface register error!\r\n");\r
+    }\r
+}\r
+\r
+/**\r
+ * @fn     void GH3X2X_WriteRegBitField(GU16 usRegAddr, GU8 uchLsb, GU8 uchMsb, GU16 usValue)\r
+ *\r
+ * @brief  write register bit field via i2c or spi\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   usRegAddr      register addr\r
+ * @param[in]   uchLsb         lsb of bit field\r
+ * @param[in]   uchMsb         msb of bit field\r
+ * @param[in]   usRegValue     register data\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_WriteRegBitField(GU16 usRegAddr, GU8 uchLsb, GU8 uchMsb, GU16 usValue)\r
+{\r
+    GU16 usMakData = ((((GU16)0x0001) << (uchMsb - uchLsb + 1)) - 1) << uchLsb;\r
+    GU16 usRegData = 0;\r
+    if ((g_pGh3x2xReadRegFunc != GH3X2X_PTR_NULL) && (g_pGh3x2xWriteRegFunc != GH3X2X_PTR_NULL))\r
+    {\r
+        GH3X2X_TryWakeUp();\r
+        usRegData = g_pGh3x2xReadRegFunc(usRegAddr);\r
+        GH3X2X_VAL_CLEAR_BIT(usRegData, usMakData);\r
+        GH3X2X_VAL_SET_BIT(usRegData, (usValue << uchLsb) & usMakData);\r
+        g_pGh3x2xWriteRegFunc(usRegAddr, usRegData);\r
+    }\r
+    else\r
+    {\r
+        GH3X2X_DEBUG_LOG_PARAM("communicate interface register error!\r\n");\r
+    }\r
+}\r
+\r
+/**\r
+ * @fn     GU16 GH3X2X_ReadRegBitField(GU16 usRegAddr, GU8 uchLsb, GU8 uchMsb)\r
+ *\r
+ * @brief  Read register bit field via i2c or spi\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   usRegAddr      register addr\r
+ * @param[in]   uchLsb         lsb of bit field\r
+ * @param[in]   uchMsb         msb of bit field\r
+ * @param[out]  None\r
+ *\r
+ * @return  register bit field data\r
+ */\r
+GU16 GH3X2X_ReadRegBitField(GU16 usRegAddr, GU8 uchLsb, GU8 uchMsb)\r
+{\r
+    GU16 usMakData = ((((GU16)0x0001) << (uchMsb - uchLsb + 1)) - 1) << uchLsb;\r
+    GU16 usRegData = 0;\r
+    if (g_pGh3x2xReadRegFunc != GH3X2X_PTR_NULL)\r
+    {\r
+        GH3X2X_TryWakeUp();\r
+        usRegData = g_pGh3x2xReadRegFunc(usRegAddr);\r
+        GH3X2X_VAL_GET_BIT(usRegData, usMakData);\r
+        usRegData >>= uchLsb;\r
+    }\r
+    else\r
+    {\r
+        GH3X2X_DEBUG_LOG_PARAM("communicate interface register error!\r\n");\r
+    }\r
+    return usRegData;\r
+}\r
+\r
+/**\r
+ * @fn     GS8 GH3X2X_RegisterSpiOperationFunc(GU8 (*pSpiWriteFunc)(GU8 uchWriteBytesArr[], GU16 usWriteLen),\r
+ *                                  GU8 (*pSpiReadFunc)(GU8 uchReadBytesArr[], GU16 usMaxReadLen),\r
+ *                                   void (*pSpiCsCtrlFunc)(GU8 uchCsLevelHigh))\r
+ *\r
+ * @brief  Register spi operation function callback\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   pSpiWriteFunc       pointer to spi write function\r
+ * @param[in]   pSpiReadFunc        pointer to spi read function\r
+ * @param[in]   pSpiCsCtrlFunc      pointer to spi cs operation function\r
+ * @param[out]  None\r
+ *\r
+ * @return  errcode\r
+ * @retval  #GH3X2X_RET_OK               return successfully\r
+ * @retval  #GH3X2X_RET_PARAMETER_ERROR  spi operation function pointer parameter error\r
+ */\r
+GS8 GH3X2X_RegisterSpiOperationFunc(GU8 (*pSpiWriteFunc)(GU8 uchWriteBytesArr[], GU16 usWriteLen),\r
+                                    GU8 (*pSpiReadFunc)(GU8 uchReadBytesArr[], GU16 usMaxReadLen),\r
+                                    void (*pSpiCsCtrlFunc)(GU8 uchCsLevelHigh))\r
+{\r
+    GS8 chRet = GH3X2X_RET_PARAMETER_ERROR;\r
+    GH3X2X_DEBUG_LOG_PARAM("%s\r\n", __FUNCTION__);\r
+    if ((pSpiWriteFunc != GH3X2X_PTR_NULL) && (pSpiReadFunc != GH3X2X_PTR_NULL) && (pSpiCsCtrlFunc != GH3X2X_PTR_NULL))\r
+    {\r
+        g_pSpiWriteFunc  = pSpiWriteFunc;\r
+        g_pSpiReadFunc   = pSpiReadFunc;\r
+        g_pSpiCsCtrlFunc = pSpiCsCtrlFunc;\r
+\r
+        g_pGh3x2xSendCmdFunc  = GH3X2X_SpiSendCmd;\r
+        g_pGh3x2xWriteRegFunc = GH3X2X_SpiWriteReg;\r
+        g_pGh3x2xReadRegFunc  = GH3X2X_SpiReadReg;\r
+        g_pGh3x2xReadRegsFunc = GH3X2X_SpiReadRegs;\r
+        g_pGh3x2xReadFifoFunc = GH3X2X_SpiReadFifo;\r
+        chRet = GH3X2X_RET_OK;\r
+    }\r
+    else\r
+    {\r
+        GH3X2X_DEBUG_LOG_PARAM("spi register param error!\r\n");\r
+    }\r
+    return chRet;\r
+}\r
+\r
+GS8 GH3X2X_RegisterSpiHwCsOperationFunc(GU8 (*pSpiWriteFunc)(GU8 uchWriteBytesArr[], GU16 usWriteLen),\r
+                                    GU8 (*pSpiWriteF1ReadFunc)(GU8 uchReadBytesArr[], GU16 usMaxReadLen)\r
+                                    )\r
+{\r
+    GS8 chRet = GH3X2X_RET_PARAMETER_ERROR;\r
+    GH3X2X_DEBUG_LOG_PARAM("%s\r\n", __FUNCTION__);\r
+    if ((pSpiWriteFunc != GH3X2X_PTR_NULL) && (pSpiWriteF1ReadFunc != GH3X2X_PTR_NULL) )\r
+    {\r
+        g_pSpiWriteFunc  = pSpiWriteFunc;\r
+        g_pSpiReadFunc   = pSpiWriteF1ReadFunc;\r
+\r
+        g_pGh3x2xSendCmdFunc  = GH3X2X_SpiSendCmdHardwareCs;\r
+        g_pGh3x2xWriteRegFunc = GH3X2X_SpiWriteRegHardwareCs;\r
+        g_pGh3x2xReadRegFunc  = GH3X2X_SpiReadRegHardwareCs;\r
+        g_pGh3x2xReadRegsFunc = GH3X2X_SpiReadRegsHardwareCs;\r
+        g_pGh3x2xReadFifoFunc = GH3X2X_SpiReadFifoHardwareCs;\r
+        chRet = GH3X2X_RET_OK;\r
+    }\r
+    else\r
+    {\r
+        GH3X2X_DEBUG_LOG_PARAM("spi register param error!\r\n");\r
+    }\r
+    return chRet;\r
+}\r
+\r
+\r
+/**\r
+ * @fn     GS8 GH3X2X_RegisterI2cOperationFunc(GU8 uchI2cIdLowTwoBitsSelect,\r
+ *                              GU8 (*pI2cWriteFunc)(GU8 uchDeviceId, const GU8 uchWriteBytesArr[], GU16 usWriteLen),\r
+ *                              GU8 (*pI2cReadFunc)(GU8 uchDeviceId, const GU8 uchCmddBytesArr[], GU16 usCmddLen,\r
+ *                                                      GU8 uchReadBytesArr[], GU16 usMaxReadLen))\r
+ *\r
+ * @brief  Register i2c operation function callback\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   uchI2cIdLowTwoBitsSelect    i2c low two bits addr selected, ref EMGh3x2xI2cIdSelect\r
+ * @param[in]   pI2cWriteFunc               pointer to i2c write function\r
+ * @param[in]   pI2cReadFunc                pointer to i2c read function\r
+ * @param[out]  None\r
+ *\r
+ * @return  errcode\r
+ * @retval  #GH3X2X_RET_OK               return successfully\r
+ * @retval  #GH3X2X_RET_PARAMETER_ERROR  i2c operation function pointer parameter error\r
+ */\r
+GS8 GH3X2X_RegisterI2cOperationFunc(GU8 uchI2cIdLowTwoBitsSelect,\r
+                                GU8 (*pI2cWriteFunc)(GU8 uchDeviceId, const GU8 uchWriteBytesArr[], GU16 usWriteLen),\r
+                                GU8 (*pI2cReadFunc)(GU8 uchDeviceId, const GU8 uchCmddBytesArr[], GU16 usCmddLen,\r
+                                                        GU8 uchReadBytesArr[], GU16 usMaxReadLen))\r
+{\r
+    GS8 chRet = GH3X2X_RET_PARAMETER_ERROR;\r
+    GH3X2X_DEBUG_LOG_PARAM("%s\r\n", __FUNCTION__);\r
+    if ((pI2cWriteFunc != GH3X2X_PTR_NULL) && (pI2cReadFunc != GH3X2X_PTR_NULL)\r
+        && (uchI2cIdLowTwoBitsSelect < GH3X2X_I2C_ID_INVALID))\r
+    {\r
+        g_puchI2cDeviceIdList[0] = GH3X2X_I2C_DEVICE_ID_BASE | (uchI2cIdLowTwoBitsSelect << 1);\r
+        g_pI2cWriteFunc  = pI2cWriteFunc;\r
+        g_pI2cReadFunc   = pI2cReadFunc;\r
+\r
+        g_pGh3x2xSendCmdFunc  = GH3X2X_I2cSendCmd;\r
+        g_pGh3x2xWriteRegFunc = GH3X2X_I2cWriteReg;\r
+        g_pGh3x2xReadRegFunc  = GH3X2X_I2cReadReg;\r
+        g_pGh3x2xReadRegsFunc = GH3X2X_I2cReadRegs;\r
+        g_pGh3x2xReadFifoFunc = GH3X2X_I2cReadFifo;\r
+        chRet = GH3X2X_RET_OK;\r
+    }\r
+    else\r
+    {\r
+        GH3X2X_DEBUG_LOG_PARAM("i2c register param error!\r\n");\r
+    }\r
+    return chRet;\r
+}\r
+                                                        \r
+\r
+/**\r
+ * @fn     GU8 GH3x2xGetChipOperateIndexRealtime(void)\r
+ *\r
+ * @brief  get current chip operate index\r
+ *\r
+ * @attention   None\r
+ * @param[in]   None\r
+ * @param[out]  0: chip0   1: chip1\r
+ *\r
+ * @return  None\r
+ */\r
+GU8 GH3x2xGetChipOperateIndexRealtime(void)\r
+{\r
+    return g_uchGh3x2xChipOperateIndexRealtime;\r
+}\r
+\r
+\r
+/**\r
+ * @fn     void GH3X2X_RegisterI2cDeviceChip1(GU8 uchI2cIdLowTwoBitsSelect)\r
+ *\r
+ * @brief  Register chip1 i2c device addr\r
+ *\r
+ * @attention   None\r
+ * @param[in]   uchI2cIdLowTwoBitsSelect    i2c low two bits addr selected, ref EMGh3x2xI2cIdSelect\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_RegisterI2cDeviceChip1(GU8 uchI2cIdLowTwoBitsSelect)\r
+{\r
+    g_puchI2cDeviceIdList[1] = GH3X2X_I2C_DEVICE_ID_BASE | (uchI2cIdLowTwoBitsSelect << 1);\r
+}\r
+\r
+void GH3X2X_CascadeOperationMasterChip(void)\r
+{\r
+    g_uchGh3x2xChipOperateIndexRealtime = g_uchGh3x2xLogicMasterChipIndex;\r
+}\r
+\r
+void GH3X2X_CascadeOperationSlaverChip(void)\r
+{\r
+    g_uchGh3x2xChipOperateIndexRealtime = 1;\r
+}\r
+\r
+void GH3X2X_CascadeSetLogicMasterChip(GU8 uchPhysicsChipIndex)\r
+{\r
+    g_uchGh3x2xLogicMasterChipIndex = uchPhysicsChipIndex;\r
+    GH3X2X_CascadeOperationMasterChip();\r
+}\r
+\r
+\r
+\r
+\r
+/********END OF FILE********* Copyright (c) 2003 - 2022, Goodix Co., Ltd. ********/\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/kernel/gh_demo.c b/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/kernel/gh_demo.c
new file mode 100644 (file)
index 0000000..5f88dca
--- /dev/null
@@ -0,0 +1,3611 @@
+/**\r
+ * @copyright (c) 2003 - 2022, Goodix Co., Ltd. All rights reserved.\r
+ * \r
+ * @file    gh3x2x_demo.c\r
+ * \r
+ * @brief   gh3x2x driver example\r
+ * \r
+ * @author  Gooidx Iot Team\r
+ * \r
+ */\r
+\r
+/* includes */\r
+#include "gh_demo.h"\r
+#include "gh_demo_config.h"\r
+#include "gh_demo_inner.h"\r
+#include "gh_multi_sen_pro.h"\r
+#include "gh_demo_version.h"\r
+#include "gh3x2x_demo_algo_config.h"\r
+#include "gh_drv.h"\r
+#include "goodix_log.h"\r
+#include "gh_drv_control.h"\r
+\r
+#if (__DRIVER_LIB_MODE__ == __DRV_LIB_WITH_ALGO__)\r
+#include "gh3x2x_demo_algo_call.h"\r
+#endif\r
+\r
+#define GH3X2X_INT_PROCESS_SUCCESS              (0)         /**< gh3x2x interrupt process success */\r
+#define GH3X2X_INT_PROCESS_REPEAT               (1)         /**< need process gh3x2x interrupt process again */\r
+\r
+\r
+#if (__SUPPORT_HARD_ADT_CONFIG__)\r
+#define __GH3X2X_ADT_EVENT_MASK__               (GH3X2X_IRQ_MSK_WEAR_ON_BIT | GH3X2X_IRQ_MSK_WEAR_OFF_BIT)\r
+#else\r
+#define __GH3X2X_ADT_EVENT_MASK__               (0)\r
+#endif\r
+\r
+\r
+#if (__ADT_ONLY_PARTICULAR_WM_CONFIG__)\r
+GU16 g_usCurrentConfigListFifoWmBak = 0;\r
+extern GU16 g_usCurrentFiFoWaterLine;\r
+#endif\r
+\r
+\r
+#if (__FUNC_TYPE_ECG_ENABLE__)\r
+#define __GH3X2X_ECG_EVENT_MASK__               (GH3X2X_IRQ_MSK_LEAD_ON_DET_BIT)\r
+#else\r
+#define __GH3X2X_ECG_EVENT_MASK__               (0)\r
+#endif\r
+\r
+/* GH3X2X event that need to process */\r
+#define __GH3X2X_EVENT_PROCESS_MASK__   (\\r
+                                            __GH3X2X_ADT_EVENT_MASK__ | __GH3X2X_ECG_EVENT_MASK__ | \\r
+                                            GH3X2X_IRQ_MSK_FIFO_WATERMARK_BIT | GH3X2X_IRQ_MSK_FIFO_FULL_BIT | \\r
+                                            GH3X2X_IRQ_MSK_TUNNING_FAIL_BIT | GH3X2X_IRQ_MSK_TUNNING_DONE_BIT | \\r
+                                            GH3X2X_IRQ_MSK_CHIP_RESET_BIT \\r
+                                        )\r
+#define DRV_LIB_REG_CFG_EMPTY           (0x00)    //there is no reg config array loaded into driver lib\r
+#define DRV_LIB_REG_CFG_MIN_LEN         (0x5)     //minimum length of reg config array\r
+\r
+int (*g_pPrintfUserIn)(const char *, ...) = 0;\r
+int (*g_pSnprintfUserIn)(char *str, size_t size, const char *format, ...) = 0;\r
+\r
+\r
+\r
+\r
+#if __GS_GYRO_ENABLE__\r
+const GU8 g_uchGyroEnable = 1;\r
+#else\r
+const GU8 g_uchGyroEnable = 0;\r
+#endif\r
+/// gsensor fifo index\r
+static GU16 gsensor_soft_fifo_buffer_index = 0;\r
+\r
+/// gsensor fifo\r
+static STGsensorRawdata gsensor_soft_fifo_buffer[__GSENSOR_DATA_BUFFER_SIZE__ + __GS_EXTRA_BUF_LEN__];\r
+#if __CAP_ENABLE__\r
+static GU16 cap_soft_fifo_buffer_index = 0;\r
+static STCapRawdata cap_soft_fifo_buffer[__CAP_DATA_BUFFER_SIZE__];\r
+#else\r
+static GU16 cap_soft_fifo_buffer_index = 0;\r
+static STCapRawdata* cap_soft_fifo_buffer = 0;\r
+#endif\r
+#if __TEMP_ENABLE__\r
+static GU16 temp_soft_fifo_buffer_index = 0;\r
+static STTempRawdata temp_soft_fifo_buffer[__TEMP_DATA_BUFFER_SIZE__];\r
+#else\r
+static GU16 temp_soft_fifo_buffer_index = 0;\r
+static STTempRawdata* temp_soft_fifo_buffer = 0;\r
+#endif\r
+\r
+GU32 g_unDemoFuncMode = 0;\r
+GU8 g_uchDemoWorkMode = GH3X2X_DEMO_WORK_MODE_MCU_ONLINE;\r
+GU8 g_uchDemoAlgoEnableFlag = 1;\r
+#if __SLOT_SEQUENCE_DYNAMIC_ADJUST_EN__\r
+GU16 g_usGh3x2xSlotTime[8];\r
+#endif\r
+\r
+\r
+#if (__SUPPORT_ELECTRODE_WEAR_STATUS_DUMP__)\r
+GU8 g_uchGh3x2xElectrodeWearStatus;\r
+#endif\r
+EMWearDetectType g_uchWearDetectStatus = WEAR_DETECT_WEAR_ON;\r
+/// save bg cancel value of every channel\r
+GU8 g_puchGainBgCancelRecord[CHANNEL_MAP_ID_NUM];\r
+\r
+//save agc info\r
+STGh3x2xAgcInfo g_stGh3x2xAgcInfo = {0};\r
+STGh3x2xAgcInfo *g_pstGh3x2xAgcInfo = &g_stGh3x2xAgcInfo;\r
+\r
+#if __FUNC_RUN_SIMULTANEOUSLY_SUPPORT__\r
+#if __FUNC_TYPE_HR_ENABLE__\r
+GU32 g_pun_HR_FrameIncompleteRawdata[GH3X2X_HR_CHNL_NUM];\r
+GU32 g_un_HR_FrameIncompleteChnlMapBit;\r
+GU8 g_puch_HR_FrameLastGain[GH3X2X_HR_CHNL_NUM];\r
+GU32 g_un_HR_TimeStamp;\r
+STGh3x2xDownSampleInfo g_stGh3x2xDownSampleInfo_HR;\r
+#endif\r
+#if __FUNC_TYPE_HRV_ENABLE__\r
+GU32 g_pun_HRV_FrameIncompleteRawdata[GH3X2X_HRV_CHNL_NUM];\r
+GU32 g_un_HRV_FrameIncompleteChnlMapBit;\r
+GU8 g_puch_HRV_FrameLastGain[GH3X2X_HRV_CHNL_NUM];\r
+GU32 g_un_HRV_TimeStamp;\r
+STGh3x2xDownSampleInfo g_stGh3x2xDownSampleInfo_HRV;\r
+#endif\r
+#if __FUNC_TYPE_HSM_ENABLE__\r
+GU32 g_pun_HSM_FrameIncompleteRawdata[GH3X2X_HSM_CHNL_NUM];\r
+GU32 g_un_HSM_FrameIncompleteChnlMapBit;\r
+GU8 g_puch_HSM_FrameLastGain[GH3X2X_HSM_CHNL_NUM];\r
+GU32 g_un_HSM_TimeStamp;\r
+STGh3x2xDownSampleInfo g_stGh3x2xDownSampleInfo_HSM;\r
+#endif\r
+#if __FUNC_TYPE_SPO2_ENABLE__\r
+GU32 g_pun_SPO2_FrameIncompleteRawdata[GH3X2X_SPO2_CHNL_NUM];\r
+GU32 g_un_SPO2_FrameIncompleteChnlMapBit;\r
+GU8 g_puch_SPO2_FrameLastGain[GH3X2X_SPO2_CHNL_NUM];\r
+GU32 g_un_SPO2_TimeStamp;\r
+STGh3x2xDownSampleInfo g_stGh3x2xDownSampleInfo_SPO2;\r
+#endif\r
+#if __FUNC_TYPE_ECG_ENABLE__\r
+GU32 g_pun_ECG_FrameIncompleteRawdata[GH3X2X_ECG_CHNL_NUM];\r
+GU32 g_un_ECG_FrameIncompleteChnlMapBit;\r
+GU8 g_puch_ECG_FrameLastGain[GH3X2X_ECG_CHNL_NUM];\r
+GU32 g_un_ECG_TimeStamp;\r
+STGh3x2xDownSampleInfo g_stGh3x2xDownSampleInfo_ECG;\r
+#endif\r
+#if __FUNC_TYPE_PWTT_ENABLE__\r
+GU32 g_pun_PWTT_FrameIncompleteRawdata[GH3X2X_PWTT_CHNL_NUM];\r
+GU32 g_un_PWTT_FrameIncompleteChnlMapBit;\r
+GU8 g_puch_PWTT_FrameLastGain[GH3X2X_PWTT_CHNL_NUM];\r
+GU32 g_un_PWTT_TimeStamp;\r
+STGh3x2xDownSampleInfo g_stGh3x2xDownSampleInfo_PWTT;\r
+#endif\r
+#if __FUNC_TYPE_BT_ENABLE__\r
+GU32 g_pun_BT_FrameIncompleteRawdata[GH3X2X_BT_CHNL_NUM];\r
+GU32 g_un_BT_FrameIncompleteChnlMapBit;\r
+GU8 g_puch_BT_FrameLastGain[GH3X2X_BT_CHNL_NUM];\r
+GU32 g_un_BT_TimeStamp;\r
+STGh3x2xDownSampleInfo g_stGh3x2xDownSampleInfo_BT;\r
+#endif\r
+#if __FUNC_TYPE_RESP_ENABLE__\r
+GU32 g_pun_RESP_FrameIncompleteRawdata[GH3X2X_RESP_CHNL_NUM];\r
+GU32 g_un_RESP_FrameIncompleteChnlMapBit;\r
+GU8 g_puch_RESP_FrameLastGain[GH3X2X_RESP_CHNL_NUM];\r
+GU32 g_un_RESP_TimeStamp;\r
+STGh3x2xDownSampleInfo g_stGh3x2xDownSampleInfo_RESP;\r
+#endif\r
+#if __FUNC_TYPE_AF_ENABLE__\r
+GU32 g_pun_AF_FrameIncompleteRawdata[GH3X2X_AF_CHNL_NUM];\r
+GU32 g_un_AF_FrameIncompleteChnlMapBit;\r
+GU8 g_puch_AF_FrameLastGain[GH3X2X_AF_CHNL_NUM];\r
+GU32 g_un_AF_TimeStamp;\r
+STGh3x2xDownSampleInfo g_stGh3x2xDownSampleInfo_AF;\r
+#endif\r
+#if __FUNC_TYPE_BP_ENABLE__\r
+GU32 g_pun_BP_FrameIncompleteRawdata[GH3X2X_BP_CHNL_NUM];\r
+GU32 g_un_BP_FrameIncompleteChnlMapBit;\r
+GU8 g_puch_BP_FrameLastGain[GH3X2X_BP_CHNL_NUM];\r
+GU32 g_un_BP_TimeStamp;\r
+STGh3x2xDownSampleInfo g_stGh3x2xDownSampleInfo_BP;\r
+#endif\r
+#if __FUNC_TYPE_TEST_ENABLE__\r
+GU32 g_pun_TEST1_FrameIncompleteRawdata[GH3X2X_TEST_CHNL_NUM];\r
+GU32 g_un_TEST1_FrameIncompleteChnlMapBit;\r
+GU8 g_puch_TEST1_FrameLastGain[GH3X2X_TEST_CHNL_NUM];\r
+GU32 g_un_TEST1_TimeStamp;\r
+STGh3x2xDownSampleInfo g_stGh3x2xDownSampleInfo_TEST1;\r
+GU32 g_pun_TEST2_FrameIncompleteRawdata[GH3X2X_TEST_CHNL_NUM];\r
+GU32 g_un_TEST2_FrameIncompleteChnlMapBit;\r
+GU8 g_puch_TEST2_FrameLastGain[GH3X2X_TEST_CHNL_NUM];\r
+GU32 g_un_TEST2_TimeStamp;\r
+STGh3x2xDownSampleInfo g_stGh3x2xDownSampleInfo_TEST2;\r
+#endif\r
+#else\r
+GU32 g_pun_MAIN_FUNC_FrameIncompleteRawdata[GH3X2X_MAIN_FUNC_CHNL_NUM];\r
+GU32 g_un_MAIN_FUNC_FrameIncompleteChnlMapBit;\r
+GU8 g_puch_MAIN_FUNC_FrameLastGain[GH3X2X_MAIN_FUNC_CHNL_NUM];\r
+GU32 g_un_MAIN_FUNC_TimeStamp;\r
+STGh3x2xDownSampleInfo g_stGh3x2xDownSampleInfo_MAIN_FUNC;\r
+#endif\r
+#if __SUPPORT_HARD_ADT_CONFIG__\r
+GU32 g_pun_ADT_FrameIncompleteRawdata[GH3X2X_ADT_CHNL_NUM];\r
+GU32 g_un_ADT_FrameIncompleteChnlMapBit;\r
+GU8 g_puch_ADT_FrameLastGain[GH3X2X_ADT_CHNL_NUM];\r
+GU32 g_un_ADT_TimeStamp;\r
+STGh3x2xDownSampleInfo g_stGh3x2xDownSampleInfo_ADT;\r
+#endif\r
+#if __FUNC_TYPE_SOFT_ADT_ENABLE__\r
+GU32 g_pun_SOFT_ADT_GREEN_FrameIncompleteRawdata[GH3X2X_SOFT_ADT_CHNL_NUM];\r
+GU32 g_un_SOFT_ADT_GREEN_FrameIncompleteChnlMapBit;\r
+GU8 g_puch_SOFT_ADT_GREEN_FrameLastGain[GH3X2X_SOFT_ADT_CHNL_NUM];\r
+GU32 g_un_SOFT_ADT_GREEN_TimeStamp;\r
+STGh3x2xDownSampleInfo g_stGh3x2xDownSampleInfo_SOFT_ADT_GREEN;\r
+#endif\r
+\r
+\r
+\r
+\r
+#if __FUNC_TYPE_HR_ENABLE__\r
+GU8 g_pch_HR_ChnlMap[GH3X2X_HR_CHNL_NUM];\r
+STGh3x2xFunctionInfo g_st_HR_FuncitonInfo;\r
+STGh3x2xAlgoResult g_st_HR_AlgoRecordResult;\r
+#endif\r
+#if __FUNC_TYPE_HRV_ENABLE__\r
+GU8 g_pch_HRV_ChnlMap[GH3X2X_HRV_CHNL_NUM];\r
+STGh3x2xFunctionInfo g_st_HRV_FuncitonInfo;\r
+STGh3x2xAlgoResult g_st_HRV_AlgoRecordResult;\r
+#endif\r
+#if __FUNC_TYPE_HSM_ENABLE__\r
+GU8 g_pch_HSM_ChnlMap[GH3X2X_HSM_CHNL_NUM];\r
+STGh3x2xFunctionInfo g_st_HSM_FuncitonInfo;\r
+#endif\r
+#if __FUNC_TYPE_SPO2_ENABLE__\r
+GU8 g_pch_SPO2_ChnlMap[GH3X2X_SPO2_CHNL_NUM];\r
+STGh3x2xFunctionInfo g_st_SPO2_FuncitonInfo;\r
+STGh3x2xAlgoResult g_st_SPO2_AlgoRecordResult;\r
+#endif\r
+#if __FUNC_TYPE_ECG_ENABLE__\r
+GU8 g_pch_ECG_ChnlMap[GH3X2X_ECG_CHNL_NUM];\r
+STGh3x2xFunctionInfo g_st_ECG_FuncitonInfo;\r
+#endif\r
+#if __FUNC_TYPE_PWTT_ENABLE__\r
+GU8 g_pch_PWTT_ChnlMap[GH3X2X_PWTT_CHNL_NUM];\r
+STGh3x2xFunctionInfo g_st_PWTT_FuncitonInfo;\r
+#endif\r
+#if __FUNC_TYPE_BT_ENABLE__\r
+GU8 g_pch_BT_ChnlMap[GH3X2X_BT_CHNL_NUM];\r
+STGh3x2xFunctionInfo g_st_BT_FuncitonInfo;\r
+#endif\r
+#if __FUNC_TYPE_RESP_ENABLE__\r
+GU8 g_pch_RESP_ChnlMap[GH3X2X_RESP_CHNL_NUM];\r
+STGh3x2xFunctionInfo g_st_RESP_FuncitonInfo;\r
+#endif\r
+#if __FUNC_TYPE_AF_ENABLE__\r
+GU8 g_pch_AF_ChnlMap[GH3X2X_AF_CHNL_NUM];\r
+STGh3x2xFunctionInfo g_st_AF_FuncitonInfo;\r
+#endif\r
+#if __SUPPORT_HARD_ADT_CONFIG__\r
+GU8 g_pch_ADT_ChnlMap[GH3X2X_ADT_CHNL_NUM];\r
+STGh3x2xFunctionInfo g_st_ADT_FuncitonInfo;\r
+#endif\r
+#if __FUNC_TYPE_SOFT_ADT_ENABLE__\r
+GU8 g_pch_SOFT_ADT_GREEN_ChnlMap[GH3X2X_SOFT_ADT_CHNL_NUM];\r
+STGh3x2xFunctionInfo g_st_SOFT_ADT_GREEN_FuncitonInfo;\r
+#endif\r
+#if __FUNC_TYPE_SOFT_ADT_ENABLE__\r
+GU8 g_pch_SOFT_ADT_IR_ChnlMap[GH3X2X_SOFT_ADT_CHNL_NUM];\r
+STGh3x2xFunctionInfo g_st_SOFT_ADT_IR_FuncitonInfo;\r
+#endif\r
+#if __FUNC_TYPE_BP_ENABLE__\r
+GU8 g_pch_BP_ChnlMap[GH3X2X_BP_CHNL_NUM];\r
+STGh3x2xFunctionInfo g_st_BP_FuncitonInfo;\r
+#endif\r
+#if __FUNC_TYPE_TEST_ENABLE__\r
+GU8 g_pch_TEST1_ChnlMap[GH3X2X_TEST_CHNL_NUM];\r
+STGh3x2xFunctionInfo g_st_TEST1_FuncitonInfo;\r
+GU8 g_pch_TEST2_ChnlMap[GH3X2X_TEST_CHNL_NUM];\r
+STGh3x2xFunctionInfo g_st_TEST2_FuncitonInfo;\r
+#endif\r
+\r
+GU32 g_punGh3x2xFrameRawdata[GH3X2X_FUNC_CHNL_NUM_MAX];\r
+#if __GS_GYRO_ENABLE__\r
+GS16 g_psGh3x2xFrameGsensorData[6];\r
+#else\r
+GS16 g_psGh3x2xFrameGsensorData[3];\r
+#endif\r
+GU32 g_punGh3x2xFrameAgcInfo[GH3X2X_FUNC_CHNL_NUM_MAX];\r
+GU32 g_punGh3x2xFrameFlag[8];\r
+STGh3x2xAlgoResult g_stGh3x2xAlgoResult;\r
+\r
+STCapRawdata g_pstGh3x2xFrameCapData;\r
+STTempRawdata g_pstGh3x2xFrameTempData;\r
+\r
+\r
+\r
+//HR data info\r
+#if __FUNC_TYPE_HR_ENABLE__\r
+const STGh3x2xFrameInfo g_stHR_FrameInfo = \r
+{\r
+    .unFunctionID = GH3X2X_FUNCTION_HR,\r
+    .pstFunctionInfo = &g_st_HR_FuncitonInfo,\r
+    .pstAlgoResult   = &g_stGh3x2xAlgoResult,\r
+    .uchFuntionChnlLimit = GH3X2X_HR_CHNL_NUM,\r
+    .pchChnlMap = g_pch_HR_ChnlMap,\r
+    .punFrameRawdata = g_punGh3x2xFrameRawdata,\r
+    .pusFrameGsensordata = g_psGh3x2xFrameGsensorData,\r
+    .pstFrameCapdata = &g_pstGh3x2xFrameCapData,\r
+    .pstFrameTempdata = &g_pstGh3x2xFrameTempData,\r
+    .punFrameAgcInfo = g_punGh3x2xFrameAgcInfo,\r
+    .punFrameFlag = g_punGh3x2xFrameFlag,\r
+    .pstAlgoRecordResult = &g_st_HR_AlgoRecordResult,\r
+#if !__FUNC_RUN_SIMULTANEOUSLY_SUPPORT__\r
+    .punIncompleteRawdata = g_pun_MAIN_FUNC_FrameIncompleteRawdata,\r
+    .punIncompleteChnlMapBit = &g_un_MAIN_FUNC_FrameIncompleteChnlMapBit,\r
+    .puchFrameLastGain = g_puch_MAIN_FUNC_FrameLastGain,\r
+    .punFrameCnt = &g_un_MAIN_FUNC_TimeStamp,\r
+    .pstDownSampleInfo = &g_stGh3x2xDownSampleInfo_MAIN_FUNC,\r
+#else\r
+    .punIncompleteRawdata = g_pun_HR_FrameIncompleteRawdata,\r
+    .punIncompleteChnlMapBit = &g_un_HR_FrameIncompleteChnlMapBit,\r
+    .puchFrameLastGain = g_puch_HR_FrameLastGain,\r
+    .punFrameCnt = &g_un_HR_TimeStamp,\r
+    .pstDownSampleInfo = &g_stGh3x2xDownSampleInfo_HR,\r
+#endif\r
+};\r
+//const STGh3x2xFrameInfo * const  g_pstGh3x2xHR_FrameInfo = &g_stHR_FrameInfo;\r
+#else\r
+//const STGh3x2xFrameInfo * const  g_pstGh3x2xHR_FrameInfo = 0;\r
+#endif\r
+//HRV data info\r
+#if __FUNC_TYPE_HRV_ENABLE__\r
+const STGh3x2xFrameInfo g_stHRV_FrameInfo =\r
+{\r
+    .unFunctionID = GH3X2X_FUNCTION_HRV,\r
+    .pstFunctionInfo = &g_st_HRV_FuncitonInfo,\r
+    .pstAlgoResult   = &g_stGh3x2xAlgoResult,\r
+    .uchFuntionChnlLimit = GH3X2X_HRV_CHNL_NUM,\r
+    .pchChnlMap = g_pch_HRV_ChnlMap,\r
+    .punFrameRawdata = g_punGh3x2xFrameRawdata,\r
+    .pusFrameGsensordata = g_psGh3x2xFrameGsensorData,\r
+    .pstFrameCapdata = &g_pstGh3x2xFrameCapData,\r
+    .pstFrameTempdata = &g_pstGh3x2xFrameTempData,\r
+    .punFrameAgcInfo = g_punGh3x2xFrameAgcInfo,\r
+    .punFrameFlag = g_punGh3x2xFrameFlag,\r
+    .pstAlgoRecordResult = &g_st_HRV_AlgoRecordResult,\r
+#if !__FUNC_RUN_SIMULTANEOUSLY_SUPPORT__\r
+    .punIncompleteRawdata = g_pun_MAIN_FUNC_FrameIncompleteRawdata,\r
+    .punIncompleteChnlMapBit = &g_un_MAIN_FUNC_FrameIncompleteChnlMapBit,\r
+    .puchFrameLastGain = g_puch_MAIN_FUNC_FrameLastGain,\r
+    .punFrameCnt = &g_un_MAIN_FUNC_TimeStamp,\r
+    .pstDownSampleInfo = &g_stGh3x2xDownSampleInfo_MAIN_FUNC,\r
+#else\r
+    .punIncompleteRawdata = g_pun_HRV_FrameIncompleteRawdata,\r
+    .punIncompleteChnlMapBit = &g_un_HRV_FrameIncompleteChnlMapBit,\r
+    .puchFrameLastGain = g_puch_HRV_FrameLastGain,\r
+    .punFrameCnt = &g_un_HRV_TimeStamp,\r
+    .pstDownSampleInfo = &g_stGh3x2xDownSampleInfo_HRV,\r
+#endif\r
+};\r
+//const STGh3x2xFrameInfo * const  g_pstGh3x2xHRV_FrameInfo = &g_stHRV_FrameInfo;\r
+#else\r
+//const STGh3x2xFrameInfo * const  g_pstGh3x2xHRV_FrameInfo = 0;\r
+#endif\r
+//HSM data info\r
+#if __FUNC_TYPE_HSM_ENABLE__\r
+const STGh3x2xFrameInfo g_stHSM_FrameInfo =\r
+{\r
+    .unFunctionID = GH3X2X_FUNCTION_HSM,\r
+    .pstFunctionInfo = &g_st_HSM_FuncitonInfo,\r
+    .pstAlgoResult   = &g_stGh3x2xAlgoResult,\r
+    .uchFuntionChnlLimit = GH3X2X_HSM_CHNL_NUM,\r
+    .pchChnlMap = g_pch_HSM_ChnlMap,\r
+    .punFrameRawdata = g_punGh3x2xFrameRawdata,\r
+    .pusFrameGsensordata = g_psGh3x2xFrameGsensorData,\r
+    .pstFrameCapdata = &g_pstGh3x2xFrameCapData,\r
+    .pstFrameTempdata = &g_pstGh3x2xFrameTempData,\r
+    .punFrameAgcInfo = g_punGh3x2xFrameAgcInfo,\r
+    .punFrameFlag = g_punGh3x2xFrameFlag,\r
+    .pstAlgoRecordResult = 0,\r
+#if !__FUNC_RUN_SIMULTANEOUSLY_SUPPORT__\r
+    .punIncompleteRawdata = g_pun_MAIN_FUNC_FrameIncompleteRawdata,\r
+    .punIncompleteChnlMapBit = &g_un_MAIN_FUNC_FrameIncompleteChnlMapBit,\r
+    .puchFrameLastGain = g_puch_MAIN_FUNC_FrameLastGain,\r
+    .punFrameCnt = &g_un_MAIN_FUNC_TimeStamp,\r
+    .pstDownSampleInfo = &g_stGh3x2xDownSampleInfo_MAIN_FUNC,\r
+#else\r
+    .punIncompleteRawdata = g_pun_HSM_FrameIncompleteRawdata,\r
+    .punIncompleteChnlMapBit = &g_un_HSM_FrameIncompleteChnlMapBit,\r
+    .puchFrameLastGain = g_puch_HSM_FrameLastGain,\r
+    .punFrameCnt = &g_un_HSM_TimeStamp,\r
+    .pstDownSampleInfo = &g_stGh3x2xDownSampleInfo_HSM,\r
+#endif\r
+};\r
+//const STGh3x2xFrameInfo * const  g_pstGh3x2xHSM_FrameInfo = &g_stHSM_FrameInfo;\r
+#else\r
+//const STGh3x2xFrameInfo * const  g_pstGh3x2xHSM_FrameInfo = 0;\r
+#endif\r
+//SPO2 data info\r
+#if __FUNC_TYPE_SPO2_ENABLE__\r
+const STGh3x2xFrameInfo g_stSPO2_FrameInfo = \r
+{\r
+    .unFunctionID = GH3X2X_FUNCTION_SPO2,\r
+    .pstFunctionInfo = &g_st_SPO2_FuncitonInfo,\r
+    .pstAlgoResult   = &g_stGh3x2xAlgoResult,\r
+    .uchFuntionChnlLimit = GH3X2X_SPO2_CHNL_NUM,\r
+    .pchChnlMap = g_pch_SPO2_ChnlMap,\r
+    .punFrameRawdata = g_punGh3x2xFrameRawdata,\r
+    .pusFrameGsensordata = g_psGh3x2xFrameGsensorData,\r
+    .pstFrameCapdata = &g_pstGh3x2xFrameCapData,\r
+    .pstFrameTempdata = &g_pstGh3x2xFrameTempData,\r
+    .punFrameAgcInfo = g_punGh3x2xFrameAgcInfo,\r
+    .punFrameFlag = g_punGh3x2xFrameFlag,\r
+    .pstAlgoRecordResult = &g_st_SPO2_AlgoRecordResult,\r
+#if !__FUNC_RUN_SIMULTANEOUSLY_SUPPORT__\r
+    .punIncompleteRawdata = g_pun_MAIN_FUNC_FrameIncompleteRawdata,\r
+    .punIncompleteChnlMapBit = &g_un_MAIN_FUNC_FrameIncompleteChnlMapBit,\r
+    .puchFrameLastGain = g_puch_MAIN_FUNC_FrameLastGain,\r
+    .punFrameCnt = &g_un_MAIN_FUNC_TimeStamp,\r
+    .pstDownSampleInfo = &g_stGh3x2xDownSampleInfo_MAIN_FUNC,\r
+#else\r
+    .punIncompleteRawdata = g_pun_SPO2_FrameIncompleteRawdata,\r
+    .punIncompleteChnlMapBit = &g_un_SPO2_FrameIncompleteChnlMapBit,\r
+    .puchFrameLastGain = g_puch_SPO2_FrameLastGain,\r
+    .punFrameCnt = &g_un_SPO2_TimeStamp,\r
+    .pstDownSampleInfo = &g_stGh3x2xDownSampleInfo_SPO2,\r
+#endif\r
+};\r
+//const STGh3x2xFrameInfo * const  g_pstGh3x2xSPO2_FrameInfo = &g_stSPO2_FrameInfo;\r
+#else\r
+//const STGh3x2xFrameInfo * const  g_pstGh3x2xSPO2_FrameInfo = 0;\r
+#endif\r
+//ECG data info\r
+#if __FUNC_TYPE_ECG_ENABLE__\r
+const STGh3x2xFrameInfo g_stECG_FrameInfo = \r
+{\r
+    .unFunctionID = GH3X2X_FUNCTION_ECG,\r
+    .pstFunctionInfo = &g_st_ECG_FuncitonInfo,\r
+    .pstAlgoResult   = &g_stGh3x2xAlgoResult,\r
+    .uchFuntionChnlLimit = GH3X2X_ECG_CHNL_NUM,\r
+    .pchChnlMap = g_pch_ECG_ChnlMap,\r
+    .punFrameRawdata = g_punGh3x2xFrameRawdata,\r
+    .pusFrameGsensordata = g_psGh3x2xFrameGsensorData,\r
+    .pstFrameCapdata = &g_pstGh3x2xFrameCapData,\r
+    .pstFrameTempdata = &g_pstGh3x2xFrameTempData,\r
+    .punFrameAgcInfo = g_punGh3x2xFrameAgcInfo,\r
+    .punFrameFlag = g_punGh3x2xFrameFlag,\r
+    .pstAlgoRecordResult = 0,\r
+#if !__FUNC_RUN_SIMULTANEOUSLY_SUPPORT__\r
+    .punIncompleteRawdata = g_pun_MAIN_FUNC_FrameIncompleteRawdata,\r
+    .punIncompleteChnlMapBit = &g_un_MAIN_FUNC_FrameIncompleteChnlMapBit,\r
+    .puchFrameLastGain = g_puch_MAIN_FUNC_FrameLastGain,\r
+    .punFrameCnt = &g_un_MAIN_FUNC_TimeStamp,\r
+    .pstDownSampleInfo = &g_stGh3x2xDownSampleInfo_MAIN_FUNC,\r
+#else\r
+    .punIncompleteRawdata = g_pun_ECG_FrameIncompleteRawdata,\r
+    .punIncompleteChnlMapBit = &g_un_ECG_FrameIncompleteChnlMapBit,\r
+    .puchFrameLastGain = g_puch_ECG_FrameLastGain,\r
+    .punFrameCnt = &g_un_ECG_TimeStamp,\r
+    .pstDownSampleInfo = &g_stGh3x2xDownSampleInfo_ECG,\r
+#endif\r
+};\r
+//const STGh3x2xFrameInfo * const  g_pstGh3x2xECG_FrameInfo = &g_stECG_FrameInfo;\r
+#else\r
+//const STGh3x2xFrameInfo * const  g_pstGh3x2xECG_FrameInfo = 0;\r
+#endif\r
+#if __FUNC_TYPE_PWTT_ENABLE__\r
+const STGh3x2xFrameInfo g_stPWTT_FrameInfo = \r
+{\r
+    .unFunctionID = GH3X2X_FUNCTION_PWTT,\r
+    .pstFunctionInfo = &g_st_PWTT_FuncitonInfo,\r
+    .pstAlgoResult   = &g_stGh3x2xAlgoResult,\r
+    .uchFuntionChnlLimit = GH3X2X_PWTT_CHNL_NUM,\r
+    .pchChnlMap = g_pch_PWTT_ChnlMap,\r
+    .punFrameRawdata = g_punGh3x2xFrameRawdata,\r
+    .pusFrameGsensordata = g_psGh3x2xFrameGsensorData,\r
+    .pstFrameCapdata = &g_pstGh3x2xFrameCapData,\r
+    .pstFrameTempdata = &g_pstGh3x2xFrameTempData,\r
+    .punFrameAgcInfo = g_punGh3x2xFrameAgcInfo,\r
+    .punFrameFlag = g_punGh3x2xFrameFlag,\r
+    .pstAlgoRecordResult = 0,\r
+#if !__FUNC_RUN_SIMULTANEOUSLY_SUPPORT__\r
+    .punIncompleteRawdata = g_pun_MAIN_FUNC_FrameIncompleteRawdata,\r
+    .punIncompleteChnlMapBit = &g_un_MAIN_FUNC_FrameIncompleteChnlMapBit,\r
+    .puchFrameLastGain = g_puch_MAIN_FUNC_FrameLastGain,\r
+    .punFrameCnt = &g_un_MAIN_FUNC_TimeStamp,\r
+    .pstDownSampleInfo = &g_stGh3x2xDownSampleInfo_MAIN_FUNC,\r
+#else\r
+    .punIncompleteRawdata = g_pun_PWTT_FrameIncompleteRawdata,\r
+    .punIncompleteChnlMapBit = &g_un_PWTT_FrameIncompleteChnlMapBit,\r
+    .puchFrameLastGain = g_puch_PWTT_FrameLastGain,\r
+    .punFrameCnt = &g_un_PWTT_TimeStamp,\r
+    .pstDownSampleInfo = &g_stGh3x2xDownSampleInfo_PWTT,\r
+#endif\r
+};\r
+//const STGh3x2xFrameInfo * const  g_pstGh3x2xECG_FrameInfo = &g_stECG_FrameInfo;\r
+#else\r
+//const STGh3x2xFrameInfo * const  g_pstGh3x2xECG_FrameInfo = 0;\r
+#endif\r
+//BT data info\r
+#if __FUNC_TYPE_BT_ENABLE__\r
+const STGh3x2xFrameInfo g_stBT_FrameInfo =\r
+{\r
+    .unFunctionID = GH3X2X_FUNCTION_BT,\r
+    .pstFunctionInfo = &g_st_BT_FuncitonInfo,\r
+    .pstAlgoResult   = &g_stGh3x2xAlgoResult,\r
+    .uchFuntionChnlLimit = GH3X2X_BT_CHNL_NUM,\r
+    .pchChnlMap = g_pch_BT_ChnlMap,\r
+    .punFrameRawdata = g_punGh3x2xFrameRawdata,\r
+    .pusFrameGsensordata = g_psGh3x2xFrameGsensorData,\r
+    .pstFrameCapdata = &g_pstGh3x2xFrameCapData,\r
+    .pstFrameTempdata = &g_pstGh3x2xFrameTempData,\r
+    .punFrameAgcInfo = g_punGh3x2xFrameAgcInfo,\r
+    .punFrameFlag = g_punGh3x2xFrameFlag,\r
+    .pstAlgoRecordResult = 0,\r
+#if !__FUNC_RUN_SIMULTANEOUSLY_SUPPORT__\r
+    .punIncompleteRawdata = g_pun_MAIN_FUNC_FrameIncompleteRawdata,\r
+    .punIncompleteChnlMapBit = &g_un_MAIN_FUNC_FrameIncompleteChnlMapBit,\r
+    .puchFrameLastGain = g_puch_MAIN_FUNC_FrameLastGain,\r
+    .punFrameCnt = &g_un_MAIN_FUNC_TimeStamp,\r
+    .pstDownSampleInfo = &g_stGh3x2xDownSampleInfo_MAIN_FUNC,\r
+#else\r
+    .punIncompleteRawdata = g_pun_BT_FrameIncompleteRawdata,\r
+    .punIncompleteChnlMapBit = &g_un_BT_FrameIncompleteChnlMapBit,\r
+    .puchFrameLastGain = g_puch_BT_FrameLastGain,\r
+    .punFrameCnt = &g_un_BT_TimeStamp,\r
+    .pstDownSampleInfo = &g_stGh3x2xDownSampleInfo_BT,\r
+#endif\r
+};\r
+//const STGh3x2xFrameInfo * const  g_pstGh3x2xBT_FrameInfo = &g_stBT_FrameInfo;\r
+#else\r
+//const STGh3x2xFrameInfo * const  g_pstGh3x2xBT_FrameInfo = 0;\r
+#endif\r
+//RESP data info\r
+#if __FUNC_TYPE_RESP_ENABLE__\r
+const STGh3x2xFrameInfo g_stRESP_FrameInfo =\r
+{\r
+    .unFunctionID = GH3X2X_FUNCTION_RESP,\r
+    .pstFunctionInfo = &g_st_RESP_FuncitonInfo,\r
+    .pstAlgoResult   = &g_stGh3x2xAlgoResult,\r
+    .uchFuntionChnlLimit = GH3X2X_RESP_CHNL_NUM,\r
+    .pchChnlMap = g_pch_RESP_ChnlMap,\r
+    .punFrameRawdata = g_punGh3x2xFrameRawdata,\r
+    .pusFrameGsensordata = g_psGh3x2xFrameGsensorData,\r
+    .pstFrameCapdata = &g_pstGh3x2xFrameCapData,\r
+    .pstFrameTempdata = &g_pstGh3x2xFrameTempData,\r
+    .punFrameAgcInfo = g_punGh3x2xFrameAgcInfo,\r
+    .punFrameFlag = g_punGh3x2xFrameFlag,\r
+    .pstAlgoRecordResult = 0,\r
+#if !__FUNC_RUN_SIMULTANEOUSLY_SUPPORT__\r
+    .punIncompleteRawdata = g_pun_MAIN_FUNC_FrameIncompleteRawdata,\r
+    .punIncompleteChnlMapBit = &g_un_MAIN_FUNC_FrameIncompleteChnlMapBit,\r
+    .puchFrameLastGain = g_puch_MAIN_FUNC_FrameLastGain,\r
+    .punFrameCnt = &g_un_MAIN_FUNC_TimeStamp,\r
+    .pstDownSampleInfo = &g_stGh3x2xDownSampleInfo_MAIN_FUNC,\r
+#else\r
+    .punIncompleteRawdata = g_pun_RESP_FrameIncompleteRawdata,\r
+    .punIncompleteChnlMapBit = &g_un_RESP_FrameIncompleteChnlMapBit,\r
+    .puchFrameLastGain = g_puch_RESP_FrameLastGain,\r
+    .punFrameCnt = &g_un_RESP_TimeStamp,\r
+    .pstDownSampleInfo = &g_stGh3x2xDownSampleInfo_RESP,\r
+#endif\r
+};\r
+//const STGh3x2xFrameInfo * const  g_pstGh3x2xRESP_FrameInfo = &g_stRESP_FrameInfo;\r
+#else\r
+//const STGh3x2xFrameInfo * const  g_pstGh3x2xRESP_FrameInfo = 0;\r
+#endif\r
+//AF data info\r
+#if __FUNC_TYPE_AF_ENABLE__\r
+const STGh3x2xFrameInfo g_stAF_FrameInfo =\r
+{\r
+    .unFunctionID = GH3X2X_FUNCTION_AF,\r
+    .pstFunctionInfo = &g_st_AF_FuncitonInfo,\r
+    .pstAlgoResult   = &g_stGh3x2xAlgoResult,\r
+    .uchFuntionChnlLimit = GH3X2X_AF_CHNL_NUM,\r
+    .pchChnlMap = g_pch_AF_ChnlMap,\r
+    .punFrameRawdata = g_punGh3x2xFrameRawdata,\r
+    .pusFrameGsensordata = g_psGh3x2xFrameGsensorData,\r
+    .pstFrameCapdata = &g_pstGh3x2xFrameCapData,\r
+    .pstFrameTempdata = &g_pstGh3x2xFrameTempData,\r
+    .punFrameAgcInfo = g_punGh3x2xFrameAgcInfo,\r
+    .punFrameFlag = g_punGh3x2xFrameFlag,\r
+    .pstAlgoRecordResult = 0,\r
+#if !__FUNC_RUN_SIMULTANEOUSLY_SUPPORT__\r
+    .punIncompleteRawdata = g_pun_MAIN_FUNC_FrameIncompleteRawdata,\r
+    .punIncompleteChnlMapBit = &g_un_MAIN_FUNC_FrameIncompleteChnlMapBit,\r
+    .puchFrameLastGain = g_puch_MAIN_FUNC_FrameLastGain,\r
+    .punFrameCnt = &g_un_MAIN_FUNC_TimeStamp,\r
+    .pstDownSampleInfo = &g_stGh3x2xDownSampleInfo_MAIN_FUNC,\r
+#else\r
+    .punIncompleteRawdata = g_pun_AF_FrameIncompleteRawdata,\r
+    .punIncompleteChnlMapBit = &g_un_AF_FrameIncompleteChnlMapBit,\r
+    .puchFrameLastGain = g_puch_AF_FrameLastGain,\r
+    .punFrameCnt = &g_un_AF_TimeStamp,\r
+    .pstDownSampleInfo = &g_stGh3x2xDownSampleInfo_AF,\r
+#endif\r
+};\r
+//const STGh3x2xFrameInfo * const  g_pstGh3x2xAF_FrameInfo = &g_stAF_FrameInfo;\r
+#else\r
+//const STGh3x2xFrameInfo * const  g_pstGh3x2xAF_FrameInfo = 0;\r
+#endif\r
+#if __FUNC_TYPE_BP_ENABLE__\r
+const STGh3x2xFrameInfo g_stFPBP_FrameInfo =\r
+{\r
+    .unFunctionID = GH3X2X_FUNCTION_FPBP,\r
+    .pstFunctionInfo = &g_st_BP_FuncitonInfo,\r
+    .pstAlgoResult   = &g_stGh3x2xAlgoResult,\r
+    .uchFuntionChnlLimit = GH3X2X_BP_CHNL_NUM,\r
+    .pchChnlMap = g_pch_BP_ChnlMap,\r
+    .punFrameRawdata = g_punGh3x2xFrameRawdata,\r
+    .pusFrameGsensordata = g_psGh3x2xFrameGsensorData,\r
+    .pstFrameCapdata = &g_pstGh3x2xFrameCapData,\r
+    .pstFrameTempdata = &g_pstGh3x2xFrameTempData,\r
+    .punFrameAgcInfo = g_punGh3x2xFrameAgcInfo,\r
+    .punFrameFlag = g_punGh3x2xFrameFlag,\r
+    .pstAlgoRecordResult = 0,\r
+#if !__FUNC_RUN_SIMULTANEOUSLY_SUPPORT__\r
+    .punIncompleteRawdata = g_pun_MAIN_FUNC_FrameIncompleteRawdata,\r
+    .punIncompleteChnlMapBit = &g_un_MAIN_FUNC_FrameIncompleteChnlMapBit,\r
+    .puchFrameLastGain = g_puch_MAIN_FUNC_FrameLastGain,\r
+    .punFrameCnt = &g_un_MAIN_FUNC_TimeStamp,\r
+    .pstDownSampleInfo = &g_stGh3x2xDownSampleInfo_MAIN_FUNC,\r
+#else\r
+    .punIncompleteRawdata = g_pun_BP_FrameIncompleteRawdata,\r
+    .punIncompleteChnlMapBit = &g_un_BP_FrameIncompleteChnlMapBit,\r
+    .puchFrameLastGain = g_puch_BP_FrameLastGain,\r
+    .punFrameCnt = &g_un_BP_TimeStamp,\r
+    .pstDownSampleInfo = &g_stGh3x2xDownSampleInfo_BP,\r
+#endif\r
+};\r
+const STGh3x2xFrameInfo g_stPWA_FrameInfo =\r
+{\r
+    .unFunctionID = GH3X2X_FUNCTION_PWA,\r
+    .pstFunctionInfo = &g_st_BP_FuncitonInfo,\r
+    .pstAlgoResult   = &g_stGh3x2xAlgoResult,\r
+    .uchFuntionChnlLimit = GH3X2X_PWA_CHNL_NUM,\r
+    .pchChnlMap = g_pch_BP_ChnlMap,\r
+    .punFrameRawdata = g_punGh3x2xFrameRawdata,\r
+    .pusFrameGsensordata = g_psGh3x2xFrameGsensorData,\r
+    .pstFrameCapdata = &g_pstGh3x2xFrameCapData,\r
+    .pstFrameTempdata = &g_pstGh3x2xFrameTempData,\r
+    .punFrameAgcInfo = g_punGh3x2xFrameAgcInfo,\r
+    .punFrameFlag = g_punGh3x2xFrameFlag,\r
+    .pstAlgoRecordResult = 0,\r
+#if !__FUNC_RUN_SIMULTANEOUSLY_SUPPORT__\r
+    .punIncompleteRawdata = g_pun_MAIN_FUNC_FrameIncompleteRawdata,\r
+    .punIncompleteChnlMapBit = &g_un_MAIN_FUNC_FrameIncompleteChnlMapBit,\r
+    .puchFrameLastGain = g_puch_MAIN_FUNC_FrameLastGain,\r
+    .punFrameCnt = &g_un_MAIN_FUNC_TimeStamp,\r
+    .pstDownSampleInfo = &g_stGh3x2xDownSampleInfo_MAIN_FUNC,\r
+#else\r
+    .punIncompleteRawdata = g_pun_BP_FrameIncompleteRawdata,\r
+    .punIncompleteChnlMapBit = &g_un_BP_FrameIncompleteChnlMapBit,\r
+    .puchFrameLastGain = g_puch_BP_FrameLastGain,\r
+    .punFrameCnt = &g_un_BP_TimeStamp,\r
+    .pstDownSampleInfo = &g_stGh3x2xDownSampleInfo_BP,\r
+#endif\r
+};\r
+//const STGh3x2xFrameInfo * const  g_pstGh3x2xFPBP_FrameInfo = &g_stFPBP_FrameInfo;\r
+//const STGh3x2xFrameInfo * const  g_pstGh3x2xPWA_FrameInfo = &g_stPWA_FrameInfo;\r
+#else\r
+//const STGh3x2xFrameInfo * const  g_pstGh3x2xFPBP_FrameInfo = 0;\r
+//const STGh3x2xFrameInfo * const  g_pstGh3x2xPWA_FrameInfo = 0;\r
+#endif\r
+#if __FUNC_TYPE_TEST_ENABLE__\r
+const STGh3x2xFrameInfo g_stTEST1_FrameInfo =\r
+{\r
+    .unFunctionID = GH3X2X_FUNCTION_TEST1,\r
+    .pstFunctionInfo = &g_st_TEST1_FuncitonInfo,\r
+    .pstAlgoResult   = &g_stGh3x2xAlgoResult,\r
+    .uchFuntionChnlLimit = GH3X2X_TEST_CHNL_NUM,\r
+    .pchChnlMap = g_pch_TEST1_ChnlMap,\r
+    .punFrameRawdata = g_punGh3x2xFrameRawdata,\r
+    .pusFrameGsensordata = g_psGh3x2xFrameGsensorData,\r
+    .pstFrameCapdata = &g_pstGh3x2xFrameCapData,\r
+    .pstFrameTempdata = &g_pstGh3x2xFrameTempData,\r
+    .punFrameAgcInfo = g_punGh3x2xFrameAgcInfo,\r
+    .punFrameFlag = g_punGh3x2xFrameFlag,\r
+    .pstAlgoRecordResult = 0,\r
+#if !__FUNC_RUN_SIMULTANEOUSLY_SUPPORT__\r
+    .punIncompleteRawdata = g_pun_MAIN_FUNC_FrameIncompleteRawdata,\r
+    .punIncompleteChnlMapBit = &g_un_MAIN_FUNC_FrameIncompleteChnlMapBit,\r
+    .puchFrameLastGain = g_puch_MAIN_FUNC_FrameLastGain,\r
+    .punFrameCnt = &g_un_MAIN_FUNC_TimeStamp,\r
+    .pstDownSampleInfo = &g_stGh3x2xDownSampleInfo_MAIN_FUNC,\r
+#else\r
+    .punIncompleteRawdata = g_pun_TEST1_FrameIncompleteRawdata,\r
+    .punIncompleteChnlMapBit = &g_un_TEST1_FrameIncompleteChnlMapBit,\r
+    .puchFrameLastGain = g_puch_TEST1_FrameLastGain,\r
+    .punFrameCnt = &g_un_TEST1_TimeStamp,\r
+    .pstDownSampleInfo = &g_stGh3x2xDownSampleInfo_TEST1,\r
+#endif\r
+};\r
+const STGh3x2xFrameInfo g_stTEST2_FrameInfo =\r
+{\r
+    .unFunctionID = GH3X2X_FUNCTION_TEST2,\r
+    .pstFunctionInfo = &g_st_TEST2_FuncitonInfo,\r
+    .pstAlgoResult   = &g_stGh3x2xAlgoResult,\r
+    .uchFuntionChnlLimit = GH3X2X_TEST_CHNL_NUM,\r
+    .pchChnlMap = g_pch_TEST2_ChnlMap,\r
+    .punFrameRawdata = g_punGh3x2xFrameRawdata,\r
+    .pusFrameGsensordata = g_psGh3x2xFrameGsensorData,\r
+    .pstFrameCapdata = &g_pstGh3x2xFrameCapData,\r
+    .pstFrameTempdata = &g_pstGh3x2xFrameTempData,\r
+    .punFrameAgcInfo = g_punGh3x2xFrameAgcInfo,\r
+    .punFrameFlag = g_punGh3x2xFrameFlag,\r
+    .pstAlgoRecordResult = 0,\r
+#if !__FUNC_RUN_SIMULTANEOUSLY_SUPPORT__\r
+    .punIncompleteRawdata = g_pun_MAIN_FUNC_FrameIncompleteRawdata,\r
+    .punIncompleteChnlMapBit = &g_un_MAIN_FUNC_FrameIncompleteChnlMapBit,\r
+    .puchFrameLastGain = g_puch_MAIN_FUNC_FrameLastGain,\r
+    .punFrameCnt = &g_un_MAIN_FUNC_TimeStamp,\r
+    .pstDownSampleInfo = &g_stGh3x2xDownSampleInfo_MAIN_FUNC,\r
+#else\r
+    .punIncompleteRawdata = g_pun_TEST2_FrameIncompleteRawdata,\r
+    .punIncompleteChnlMapBit = &g_un_TEST2_FrameIncompleteChnlMapBit,\r
+    .puchFrameLastGain = g_puch_TEST2_FrameLastGain,\r
+    .punFrameCnt = &g_un_TEST2_TimeStamp,\r
+    .pstDownSampleInfo = &g_stGh3x2xDownSampleInfo_TEST2,\r
+#endif\r
+};\r
+//const STGh3x2xFrameInfo * const  g_pstGh3x2xTEST1_FrameInfo = &g_stTEST1_FrameInfo;\r
+//const STGh3x2xFrameInfo * const  g_pstGh3x2xTEST2_FrameInfo = &g_stTEST2_FrameInfo;\r
+#else\r
+//const STGh3x2xFrameInfo * const  g_pstGh3x2xTEST1_FrameInfo = 0;\r
+//const STGh3x2xFrameInfo * const  g_pstGh3x2xTEST2_FrameInfo = 0;\r
+#endif\r
+//ADT data info\r
+#if __SUPPORT_HARD_ADT_CONFIG__\r
+const STGh3x2xFrameInfo g_stADT_FrameInfo = \r
+{\r
+    .unFunctionID = GH3X2X_FUNCTION_ADT,\r
+    .pstFunctionInfo = &g_st_ADT_FuncitonInfo,\r
+    .pstAlgoResult   = &g_stGh3x2xAlgoResult,\r
+    .uchFuntionChnlLimit = GH3X2X_ADT_CHNL_NUM,\r
+    .pchChnlMap = g_pch_ADT_ChnlMap,\r
+    .punFrameRawdata = g_punGh3x2xFrameRawdata,\r
+    .pusFrameGsensordata = g_psGh3x2xFrameGsensorData,\r
+    .pstFrameCapdata = &g_pstGh3x2xFrameCapData,\r
+    .pstFrameTempdata = &g_pstGh3x2xFrameTempData,\r
+    .punFrameAgcInfo = g_punGh3x2xFrameAgcInfo,\r
+    .punFrameFlag = g_punGh3x2xFrameFlag,\r
+    .punIncompleteRawdata = g_pun_ADT_FrameIncompleteRawdata,\r
+    .punIncompleteChnlMapBit = &g_un_ADT_FrameIncompleteChnlMapBit,\r
+    .puchFrameLastGain = g_puch_ADT_FrameLastGain,\r
+    .punFrameCnt = &g_un_ADT_TimeStamp,\r
+    .pstDownSampleInfo = &g_stGh3x2xDownSampleInfo_ADT,\r
+    .pstAlgoRecordResult = 0,\r
+};\r
+//const STGh3x2xFrameInfo * const  g_pstGh3x2xADT_FrameInfo = &g_stADT_FrameInfo;\r
+#else\r
+//const STGh3x2xFrameInfo * const  g_pstGh3x2xADT_FrameInfo = 0;\r
+#endif\r
+//SOFT ADT data info\r
+#if __FUNC_TYPE_SOFT_ADT_ENABLE__\r
+const STGh3x2xFrameInfo g_stSOFT_ADT_GREEN_FrameInfo = \r
+{\r
+    .unFunctionID = GH3X2X_FUNCTION_SOFT_ADT_GREEN,\r
+    .pstFunctionInfo = &g_st_SOFT_ADT_GREEN_FuncitonInfo,\r
+    .pstAlgoResult   = &g_stGh3x2xAlgoResult,\r
+    .uchFuntionChnlLimit = GH3X2X_SOFT_ADT_CHNL_NUM,\r
+    .pchChnlMap = g_pch_SOFT_ADT_GREEN_ChnlMap,\r
+    .punFrameRawdata = g_punGh3x2xFrameRawdata,\r
+    .pusFrameGsensordata = g_psGh3x2xFrameGsensorData,\r
+    .pstFrameCapdata = &g_pstGh3x2xFrameCapData,\r
+    .pstFrameTempdata = &g_pstGh3x2xFrameTempData,\r
+    .punFrameAgcInfo = g_punGh3x2xFrameAgcInfo,\r
+    .punFrameFlag = g_punGh3x2xFrameFlag,\r
+    .punIncompleteRawdata = g_pun_SOFT_ADT_GREEN_FrameIncompleteRawdata,\r
+    .punIncompleteChnlMapBit = &g_un_SOFT_ADT_GREEN_FrameIncompleteChnlMapBit,\r
+    .puchFrameLastGain = g_puch_SOFT_ADT_GREEN_FrameLastGain,\r
+    .punFrameCnt = &g_un_SOFT_ADT_GREEN_TimeStamp,\r
+    .pstDownSampleInfo = &g_stGh3x2xDownSampleInfo_SOFT_ADT_GREEN,\r
+    .pstAlgoRecordResult = 0,\r
+};\r
+//const STGh3x2xFrameInfo * const  g_pstGh3x2xSOFT_ADT_GREEN_FrameInfo = &g_stSOFT_ADT_GREEN_FrameInfo;\r
+#else\r
+//const STGh3x2xFrameInfo * const  g_pstGh3x2xSOFT_ADT_GREEN_FrameInfo = 0;\r
+#endif\r
+#if __FUNC_TYPE_SOFT_ADT_ENABLE__\r
+const STGh3x2xFrameInfo g_stSOFT_ADT_IR_FrameInfo = \r
+{\r
+    .unFunctionID = GH3X2X_FUNCTION_SOFT_ADT_IR,\r
+    .pstFunctionInfo = &g_st_SOFT_ADT_IR_FuncitonInfo,\r
+    .pstAlgoResult   = &g_stGh3x2xAlgoResult,\r
+    .uchFuntionChnlLimit = GH3X2X_SOFT_ADT_CHNL_NUM,\r
+    .pchChnlMap = g_pch_SOFT_ADT_IR_ChnlMap,\r
+    .punFrameRawdata = g_punGh3x2xFrameRawdata,\r
+    .pusFrameGsensordata = g_psGh3x2xFrameGsensorData,\r
+    .pstFrameCapdata = &g_pstGh3x2xFrameCapData,\r
+    .pstFrameTempdata = &g_pstGh3x2xFrameTempData,\r
+    .punFrameAgcInfo = g_punGh3x2xFrameAgcInfo,\r
+    .punFrameFlag = g_punGh3x2xFrameFlag,\r
+    .punIncompleteRawdata = g_pun_SOFT_ADT_GREEN_FrameIncompleteRawdata,\r
+    .punIncompleteChnlMapBit = &g_un_SOFT_ADT_GREEN_FrameIncompleteChnlMapBit,\r
+    .puchFrameLastGain = g_puch_SOFT_ADT_GREEN_FrameLastGain,\r
+    .punFrameCnt = &g_un_SOFT_ADT_GREEN_TimeStamp,\r
+    .pstDownSampleInfo = &g_stGh3x2xDownSampleInfo_SOFT_ADT_GREEN,\r
+    .pstAlgoRecordResult = 0,\r
+};\r
+//const STGh3x2xFrameInfo * const  g_pstGh3x2xSOFT_ADT_IR_FrameInfo = &g_stSOFT_ADT_IR_FrameInfo;\r
+#else\r
+//const STGh3x2xFrameInfo * const  g_pstGh3x2xSOFT_ADT_IR_FrameInfo = 0;\r
+#endif\r
+\r
+\r
+//Function data info struct\r
+const STGh3x2xFrameInfo * const  g_pstGh3x2xFrameInfo[GH3X2X_FUNC_OFFSET_MAX] = \r
+{\r
+//adt\r
+#if __SUPPORT_HARD_ADT_CONFIG__\r
+    &g_stADT_FrameInfo,\r
+#else\r
+    0,\r
+#endif\r
+//hr\r
+#if __FUNC_TYPE_HR_ENABLE__\r
+    &g_stHR_FrameInfo,\r
+#else\r
+    0,\r
+#endif\r
+//hrv\r
+#if __FUNC_TYPE_HRV_ENABLE__\r
+    &g_stHRV_FrameInfo,\r
+#else\r
+    0,\r
+#endif\r
+//hsm\r
+#if __FUNC_TYPE_HSM_ENABLE__\r
+    &g_stHSM_FrameInfo,\r
+#else\r
+    0,\r
+#endif\r
+//fpbp\r
+//pwa\r
+#if __FUNC_TYPE_BP_ENABLE__\r
+    &g_stFPBP_FrameInfo,\r
+    &g_stPWA_FrameInfo,\r
+#else\r
+    0,\r
+    0,\r
+#endif   \r
+//spo2\r
+#if __FUNC_TYPE_SPO2_ENABLE__\r
+    &g_stSPO2_FrameInfo,\r
+#else\r
+    0,\r
+#endif\r
+//ecg\r
+#if __FUNC_TYPE_ECG_ENABLE__\r
+    &g_stECG_FrameInfo,\r
+#else\r
+    0,\r
+#endif\r
+//pwtt\r
+#if __FUNC_TYPE_PWTT_ENABLE__\r
+    &g_stPWTT_FrameInfo,\r
+#else\r
+    0,\r
+#endif\r
+//soft adt green\r
+#if __FUNC_TYPE_SOFT_ADT_ENABLE__\r
+    &g_stSOFT_ADT_GREEN_FrameInfo,\r
+#else\r
+    0,\r
+#endif\r
+//bt\r
+#if __FUNC_TYPE_BT_ENABLE__\r
+    &g_stBT_FrameInfo,\r
+#else\r
+    0,\r
+#endif\r
+//resp\r
+#if __FUNC_TYPE_RESP_ENABLE__\r
+    &g_stRESP_FrameInfo,\r
+#else\r
+    0,\r
+#endif\r
+//af\r
+#if __FUNC_TYPE_AF_ENABLE__\r
+    &g_stAF_FrameInfo,\r
+#else\r
+    0,\r
+#endif\r
+#if __FUNC_TYPE_TEST_ENABLE__\r
+    &g_stTEST1_FrameInfo,\r
+    &g_stTEST2_FrameInfo,\r
+#else\r
+    0,\r
+    0,\r
+#endif\r
+//soft adt ir\r
+#if __FUNC_TYPE_SOFT_ADT_ENABLE__\r
+    &g_stSOFT_ADT_IR_FrameInfo,\r
+#else\r
+    0,\r
+#endif\r
+    0, //GH3X2X_FUNCTION_RS0\r
+    0, //GH3X2X_FUNCTION_RS1\r
+    0, //GH3X2X_FUNCTION_RS2\r
+    0, //GH3X2X_FUNCTION_LEAD_DET\r
+};\r
+\r
+/// read data buffer\r
+\r
+#if __USER_DYNAMIC_DRV_BUF_EN__\r
+static GU8 *g_puchGh3x2xReadRawdataBuffer = 0;\r
+#if __GH3X2X_CASCADE_EN__\r
+static GU8 *g_puchGh3x2xReadRawdataBufferSlaveChip = 0;\r
+#endif\r
+#else\r
+#if __GH3X2X_CASCADE_EN__\r
+static GU8 g_puchGh3x2xReadRawdataBuffer[2 * __GH3X2X_RAWDATA_BUFFER_SIZE__];\r
+static GU8 g_puchGh3x2xReadRawdataBufferSlaveChip[__GH3X2X_RAWDATA_SLAVE_BUFFER_SIZE__];\r
+#else\r
+static GU8 g_puchGh3x2xReadRawdataBuffer[__GH3X2X_RAWDATA_BUFFER_SIZE__];\r
+#endif\r
+#endif\r
+\r
+/// read data buffer len\r
+GU16 g_usGh3x2xReadRawdataLen = 0;\r
+\r
+\r
+extern void Gh3x2xDemoStopSamplingInner(GU32 unFuncMode);\r
+extern void Gh3x2xDemoStartSamplingInner(GU32 unFuncMode, GU8 uchSwitchEnable);\r
+\r
+\r
+/// driver lib demo init flag\r
+static GU8 g_uchGh3x2xInitFlag = 0;\r
+\r
+\r
+static GU8 g_uchGh3x2xInterruptProNotFinishFlag = 0;\r
+\r
+#if (__NORMAL_INT_PROCESS_MODE__ == __INTERRUPT_PROCESS_MODE__ || __MIX_INT_PROCESS_MODE__ == __INTERRUPT_PROCESS_MODE__)\r
+//hal_gh3x2x_int_handler_call_back is called, this value is 1\r
+GU8 g_uchGh3x2xIntCallBackIsCalled = 0; \r
+#endif\r
+\r
+#if (__SUPPORT_ENGINEERING_MODE__)\r
+GU8 g_uchEngineeringModeStatus = 0;  // 0: is not in engineering mode   1: is in engineering mode\r
+STGh3x2xEngineeringModeSampleParam *g_pstSampleParaGroup = 0;\r
+GU8 g_uchEngineeringModeSampleParaGroupNum = 0;\r
+#endif\r
+\r
+/// current gh3x2x reg config array index\r
+GU8 g_uchGh3x2xRegCfgArrIndex = DRV_LIB_REG_CFG_EMPTY;\r
+\r
+/// int mode\r
+GU8 g_uchGh3x2xIntMode = __INTERRUPT_PROCESS_MODE__;\r
+\r
+\r
+#if __FUNC_TYPE_ECG_ENABLE__\r
+#if __GH3X2X_CASCADE_EN__\r
+STGh3x2xSoftLeadOffDetInfo  g_pstGh3x2xSoftLeadOffDetInfoEntity[2];\r
+STGh3x2xRsInfo  g_pstGh3x2xEcgRsInfoEntity[2];\r
+const GU8 g_uchGh3x2xEcgChnlNumLimit = 2;\r
+#else\r
+STGh3x2xSoftLeadOffDetInfo  g_pstGh3x2xSoftLeadOffDetInfoEntity[1];\r
+STGh3x2xRsInfo  g_pstGh3x2xEcgRsInfoEntity[1];\r
+const GU8 g_uchGh3x2xEcgChnlNumLimit = 1;\r
+#endif\r
+STGh3x2xSoftLeadOffDetInfo * const g_pstGh3x2xSoftLeadOffDetInfo = g_pstGh3x2xSoftLeadOffDetInfoEntity;\r
+STGh3x2xRsInfo * const g_pstGh3x2xEcgRsInfo = g_pstGh3x2xEcgRsInfoEntity;\r
+#else\r
+STGh3x2xSoftLeadOffDetInfo * const g_pstGh3x2xSoftLeadOffDetInfo = 0;\r
+STGh3x2xRsInfo * const g_pstGh3x2xEcgRsInfo = 0;\r
+const GU8 g_uchGh3x2xEcgChnlNumLimit = 0;\r
+#endif\r
+\r
+#if (__FUNC_TYPE_HR_ENABLE__&& __SUPPORT_PPG_DOWNSAMP__)\r
+const GU32 g_uchPPGDownSampleChnlNumLimit = GH3X2X_PPG_DOWNSAMP_CHNL_NUM;\r
+STGh3x2xRsInfo  g_pstGh3x2xPPGRsInfoEntity[GH3X2X_PPG_DOWNSAMP_CHNL_NUM];\r
+STGh3x2xRsInfo * const g_pstGh3x2xPPGRsInfo = g_pstGh3x2xPPGRsInfoEntity;\r
+#else\r
+const GU32 g_uchPPGDownSampleChnlNumLimit = 0;\r
+STGh3x2xRsInfo * const g_pstGh3x2xPPGRsInfo = 0;\r
+#endif\r
+\r
+#if (GH3X2X_FIFO_MONITOR_EN&(__GH3X2X_INTERFACE__ == __GH3X2X_INTERFACE_I2C__))\r
+STGh3x2xFifoMonitorInfo g_stFifoMonitorInfo;\r
+#endif\r
+\r
+void Gh3x2xGetConfigVersion(const STGh3x2xInitConfig *pstGh3x2xInitConfigParam)\r
+{\r
+    GU32 unCfgTimeStamp = 0;\r
+\r
+    if (pstGh3x2xInitConfigParam->usConfigArrLen <= 1)\r
+    {\r
+        return;\r
+    }\r
+    else\r
+    {\r
+        for (GU16 usCnt = 0 ; usCnt < pstGh3x2xInitConfigParam->usConfigArrLen ; usCnt ++)\r
+        {\r
+            switch(pstGh3x2xInitConfigParam->pstRegConfigArr[usCnt].usRegAddr)\r
+            {\r
+            case 0x1006:\r
+                unCfgTimeStamp |=  pstGh3x2xInitConfigParam->pstRegConfigArr[usCnt].usRegData;\r
+                break;\r
+            case 0x1008:\r
+                unCfgTimeStamp |=  (pstGh3x2xInitConfigParam->pstRegConfigArr[usCnt].usRegData << 16);\r
+                break;\r
+            }\r
+        }\r
+    }\r
+    if (unCfgTimeStamp != 0)\r
+    {\r
+        GH3X2X_INFO_LOG("%s : Config Version : %x\n", __FUNCTION__, (unsigned int)unCfgTimeStamp);\r
+    }\r
+    else\r
+    {\r
+        GH3X2X_INFO_LOG("%s : No Config Version !!!\n", __FUNCTION__);\r
+    }\r
+}\r
+\r
+#if __GS_NONSYNC_READ_EN__\r
+GU8 g_uchGh3x2xGsenosrExtralBufLen = __GS_EXTRA_BUF_LEN__;\r
+GS16 g_sGh3x2xGsenorCurrentRemainPointNum;\r
+GU16 g_usGsenorRefFunction = 0;\r
+float g_fGh3x2xNonSyncGsensorStep;\r
+\r
+\r
+void Gh3x2xNonSyncGsensorInit(void)\r
+{\r
+    g_sGh3x2xGsenorCurrentRemainPointNum = 0;\r
+    GH3X2X_INFO_LOG("[Non-Sync Gsensor]non-sync gsensor init.\r\n");\r
+}\r
+\r
+GU16 Gh3x2xGetCurrentRefFunction(void)\r
+{\r
+    GU16 usSampleRateMax = 0;\r
+    GU16 usRefFucntion = 0;\r
+    //find max sample rate function in opened function\r
+    for(GU8 uchFunCnt = 0; uchFunCnt < GH3X2X_FUNC_OFFSET_MAX; uchFunCnt ++)\r
+    {\r
+        if(g_pstGh3x2xFrameInfo[uchFunCnt])\r
+        {\r
+            if(g_unDemoFuncMode & (((GU32)1)<< uchFunCnt))\r
+            {\r
+                if(usSampleRateMax < g_pstGh3x2xFrameInfo[uchFunCnt]->pstFunctionInfo->usSampleRate)\r
+                {\r
+                    usSampleRateMax = g_pstGh3x2xFrameInfo[uchFunCnt]->pstFunctionInfo->usSampleRate;\r
+                    usRefFucntion = g_pstGh3x2xFrameInfo[uchFunCnt]->unFunctionID;\r
+                }\r
+            }\r
+        }\r
+    }\r
+    \r
+    GH3X2X_INFO_LOG("[Non-Sync Gsensor]usRefFucntion = 0x%X.\r\n",usRefFucntion);\r
+    //calculate step\r
+    if(usSampleRateMax)\r
+    {\r
+        g_fGh3x2xNonSyncGsensorStep = __GS_SAMPLE_RATE_HZ__ / usSampleRateMax;\r
+    }\r
+    else\r
+    {\r
+        g_fGh3x2xNonSyncGsensorStep = 0;\r
+        GH3X2X_INFO_LOG("[Non-Sync Gsensor]Error !!! usSampleRateMax = 0.\r\n");\r
+    }\r
+    GH3X2X_INFO_LOG("[Non-Sync Gsensor]g_fGh3x2xNonSyncGsensorStep = %.3f.\r\n",g_fGh3x2xNonSyncGsensorStep);\r
+    \r
+    GH3X2X_INFO_LOG("[Non-Sync Gsensor]usRefFucntion = 0x%d,usSampleRateMax = %d.\r\n",usRefFucntion,usSampleRateMax);\r
+    return usRefFucntion;\r
+}\r
+\r
+GU16 Gh3x2xGetGsensorNeedPointNum(GU16 usCurrentGsenosrPoint,GU8* puchReadFifoBuffer, GU16 usFifoBuffLen)\r
+{\r
+    GU8 uchFunctionOfst = 0xFF;\r
+    GU16 usFrameNum = 0;\r
+    GU16 usTempGsensorPointNum = 0;\r
+    GU16 usTempGsensorPointNumFloat = 0;\r
+    static GU16 usTempGsensorPointNumFractPart = 0;\r
+\r
+    for(GU8 uchFunCnt = 0; uchFunCnt < GH3X2X_FUNC_OFFSET_MAX; uchFunCnt ++)\r
+    {\r
+        if (g_usGsenorRefFunction == (((GU32)1)<< uchFunCnt))\r
+        {\r
+            uchFunctionOfst = uchFunCnt;\r
+            break;\r
+        }\r
+    }\r
+    if(0xFF == uchFunctionOfst)\r
+    {\r
+        return 0;\r
+    }\r
+\r
+    //get ref function frame num in this fifo data\r
+    if(g_pstGh3x2xFrameInfo[uchFunctionOfst])\r
+    {\r
+        usFrameNum = GH3x2xGetFrameNum(puchReadFifoBuffer,usFifoBuffLen,g_pstGh3x2xFrameInfo[uchFunctionOfst]);\r
+    }\r
+    \r
+    \r
+\r
+    usTempGsensorPointNumFloat = (float)usFrameNum * g_fGh3x2xNonSyncGsensorStep;\r
+    usTempGsensorPointNum = (GU16)(usTempGsensorPointNumFloat + usTempGsensorPointNumFractPart);\r
+    usTempGsensorPointNumFractPart = usTempGsensorPointNumFloat - (GU16)usTempGsensorPointNumFloat;\r
+\r
+    if(usTempGsensorPointNum > (__GS_EXTRA_BUF_LEN__ + usCurrentGsenosrPoint))\r
+    {\r
+        usTempGsensorPointNum = __GS_EXTRA_BUF_LEN__ + usCurrentGsenosrPoint;\r
+    }\r
+\r
+    \r
+    GH3X2X_INFO_LOG("[Non-Sync Gsensor]GsensorNeedPointNum = %d.\r\n",usTempGsensorPointNum);\r
+\r
+    return usTempGsensorPointNum;\r
+}\r
+\r
+GS16 Gh3x2xGetGsensorHeadPos(GU16 usCurrentGsenosrPoint,GU16 usNeedPoinNum)\r
+{\r
+    GS16 sPos1;\r
+    GS16 sPos2;\r
+    GH3X2X_INFO_LOG("[Non-Sync Gsensor]usCurrentGsenosrPoint = %d.\r\n",usCurrentGsenosrPoint);\r
+    sPos1 = (GS16)usCurrentGsenosrPoint - (GS16)usNeedPoinNum;\r
+    sPos2= (GS16)0 - g_sGh3x2xGsenorCurrentRemainPointNum;\r
+\r
+    if(sPos1 < sPos2)\r
+    {\r
+        GS16 sOldestPosi;\r
+        GU8  uchExistOldData = 1;\r
+        GS16 sDesPosi = sPos1;\r
+        if(g_sGh3x2xGsenorCurrentRemainPointNum) //exist remain data\r
+        {\r
+            sOldestPosi = (GS16)0 - (GS16)g_sGh3x2xGsenorCurrentRemainPointNum;    \r
+        }\r
+        else if(usCurrentGsenosrPoint)   //use new gsensor data\r
+        {\r
+            sOldestPosi = 0; \r
+        }\r
+        else\r
+        {\r
+            uchExistOldData = 0;\r
+        }\r
+        GH3X2X_INFO_LOG("[Non-Sync Gsensor]Gsensor data is not enough,add oldest point num = %d, uchExistOldData = %d.****\r\n",sPos2 - sPos1,uchExistOldData);\r
+        GH3X2X_INFO_LOG("[Non-Sync Gsensor]GsensorHeadPos = %d.\r\n",sPos1);\r
+        if(uchExistOldData)\r
+        {\r
+            for(sDesPosi = sPos1; sDesPosi < sOldestPosi;  sDesPosi++)  //copy oldest point value \r
+            {\r
+                GH3X2X_Memcpy((GU8*)(gsensor_soft_fifo_buffer + __GS_EXTRA_BUF_LEN__ + sDesPosi),(GU8*)(gsensor_soft_fifo_buffer + __GS_EXTRA_BUF_LEN__ + sOldestPosi),sizeof(STGsensorRawdata));\r
+            }\r
+        }\r
+        else  //copy 0\r
+        {\r
+            GH3X2X_Memset((GU8*)gsensor_soft_fifo_buffer+ __GS_EXTRA_BUF_LEN__ + sDesPosi,0, usNeedPoinNum * sizeof(STGsensorRawdata));\r
+        }\r
+\r
+        return sPos1;\r
+    }\r
+    GH3X2X_INFO_LOG("[Non-Sync Gsensor]GsensorHeadPos = %d.\r\n",sPos2);\r
+    return sPos2;\r
+}\r
+\r
+void Gh3x2xNonSyncGsenosrPostProcess(GU16 usCurrentGsenosrPoint,GU16 usNeedPoinNum ,GS16 sHeadPos)\r
+{\r
+    GS16 sRemainPointSrcStartPosi;\r
+    GS16 sRemainPointDesStartPosi;\r
+    GU16 usRemainPoinNum;\r
+    sRemainPointSrcStartPosi = (GS16)usNeedPoinNum + sHeadPos;\r
+    usRemainPoinNum = usCurrentGsenosrPoint - sRemainPointSrcStartPosi;\r
+    GH3X2X_INFO_LOG("[Non-Sync Gsensor]raw usRemainPoinNum = %d.\r\n",usRemainPoinNum);\r
+    if(usRemainPoinNum > __GS_EXTRA_BUF_LEN__)\r
+    {\r
+        \r
+        GH3X2X_INFO_LOG("[Non-Sync Gsensor]******Gsensor data is too much, give up oldest point num = %d.****************\r\n",(usRemainPoinNum - __GS_EXTRA_BUF_LEN__));\r
+        sRemainPointSrcStartPosi += (usRemainPoinNum - __GS_EXTRA_BUF_LEN__);  //give up oldest data\r
+        usRemainPoinNum = __GS_EXTRA_BUF_LEN__;\r
+    }\r
+    sRemainPointDesStartPosi = ((GS16)0) - usRemainPoinNum;\r
+    //copy remain data to extral buf\r
+    if(usRemainPoinNum)\r
+    {\r
+        GH3X2X_Memcpy((GU8*)(gsensor_soft_fifo_buffer + __GS_EXTRA_BUF_LEN__ + sRemainPointDesStartPosi),(GU8*)(gsensor_soft_fifo_buffer + __GS_EXTRA_BUF_LEN__ + sRemainPointSrcStartPosi),usRemainPoinNum*sizeof(STGsensorRawdata));\r
+    }\r
+    //update g_sGh3x2xGsenorCurrentRemainPointNum\r
+    g_sGh3x2xGsenorCurrentRemainPointNum = usRemainPoinNum;\r
+    GH3X2X_INFO_LOG("[Non-Sync Gsensor]GsenosrPostProcess: RemainPointNum= %d.\r\n",g_sGh3x2xGsenorCurrentRemainPointNum);\r
+}\r
+#endif\r
+\r
+void Gh3x2xDemoHardConfigReset(const STGh3x2xInitConfig *pstGh3x2xInitConfigParam)\r
+{\r
+    GH3X2X_INFO_LOG("[%s]:g_uchGh3x2xRegCfgArrIndex = %d\n", __FUNCTION__, g_uchGh3x2xRegCfgArrIndex);\r
+    for (GU16 usArrCnt = 0; usArrCnt < (pstGh3x2xInitConfigParam)->usConfigArrLen ; usArrCnt ++)\r
+    {\r
+        if (((pstGh3x2xInitConfigParam)->pstRegConfigArr[usArrCnt].usRegAddr & 0xF000) == 0)\r
+        {\r
+            for (int uchSlotIndex = 0; uchSlotIndex < 8; uchSlotIndex++)\r
+            {\r
+                if (((pstGh3x2xInitConfigParam)->pstRegConfigArr[usArrCnt].usRegAddr) ==\\r
+                        0x011E + (uchSlotIndex * 0x001C) + (0 * 0x0002)||\r
+                    ((pstGh3x2xInitConfigParam)->pstRegConfigArr[usArrCnt].usRegAddr) ==\\r
+                        0x011E + (uchSlotIndex * 0x001C) + (1 * 0x0002) ||\r
+                    ((pstGh3x2xInitConfigParam)->pstRegConfigArr[usArrCnt].usRegAddr) ==\\r
+                        0x0112 + (uchSlotIndex * 0x001C))\r
+                {\r
+                    GH3X2X_INFO_LOG("[%s]:addr-value = 0x%04x-0x%04x\n", __FUNCTION__, (pstGh3x2xInitConfigParam)->pstRegConfigArr[usArrCnt].usRegAddr, (pstGh3x2xInitConfigParam)->pstRegConfigArr[usArrCnt].usRegData);\r
+                    GH3X2X_WriteReg((pstGh3x2xInitConfigParam)->pstRegConfigArr[usArrCnt].usRegAddr,\\r
+                                (pstGh3x2xInitConfigParam)->pstRegConfigArr[usArrCnt].usRegData);\r
+                    if ((pstGh3x2xInitConfigParam)->pstRegConfigArr[usArrCnt].usRegData != \\r
+                        GH3X2X_ReadReg((pstGh3x2xInitConfigParam)->pstRegConfigArr[usArrCnt].usRegAddr))\r
+                    {\r
+                        GH3X2X_INFO_LOG("[%s]:reg verify error!!!\r\n", __FUNCTION__);\r
+                    }\r
+                }\r
+            }\r
+        }\r
+    }\r
+    GH3X2X_EnterLowPowerMode();\r
+}\r
+\r
+#if (__SUPPORT_HARD_ADT_CONFIG__)\r
+/**\r
+ * @fn     void Gh3x2xDemoWearEventProcess(u16* usEvent,EMWearDetectForceSwitch emForceSwitch)\r
+ *\r
+ * @brief  Process wear on/off event\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   usEvent             gh3x2x irq status\r
+ * @param[in]   emForceSwitch       switch wear detect status by force or not\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+#if (0 == __HARD_ADT_ALGO_CHECK_EN__)\r
+void Gh3x2xDemoWearEventProcess(GU16* usEvent,EMWearDetectForceSwitch emForceSwitch)\r
+{\r
+    if ((g_unDemoFuncMode & GH3X2X_FUNCTION_ADT) == GH3X2X_FUNCTION_ADT)\r
+    {\r
+        if((0 != (*usEvent & GH3X2X_IRQ_MSK_WEAR_ON_BIT)) || (0 != (*usEvent & GH3X2X_IRQ_MSK_WEAR_OFF_BIT)))\r
+        {\r
+            if(0 != (*usEvent & GH3X2X_IRQ_MSK_WEAR_ON_BIT))\r
+            {\r
+                g_uchWearDetectStatus = WEAR_DETECT_WEAR_OFF;\r
+                if(GH3X2X_RET_OK != GH3X2X_WearDetectSwitchTo(WEAR_DETECT_WEAR_OFF,emForceSwitch))\r
+                {\r
+                    *usEvent &= ~GH3X2X_IRQ_MSK_WEAR_ON_BIT;\r
+                }\r
+                else\r
+                {\r
+                    GH3X2X_INFO_LOG("[%s]:switch to wear off\r\n", __FUNCTION__);\r
+                }\r
+            }\r
+            else\r
+            {\r
+                g_uchWearDetectStatus = WEAR_DETECT_WEAR_ON;\r
+                if(GH3X2X_RET_OK != GH3X2X_WearDetectSwitchTo(WEAR_DETECT_WEAR_ON,emForceSwitch))\r
+                {\r
+                    *usEvent &= ~GH3X2X_IRQ_MSK_WEAR_OFF_BIT;\r
+                }\r
+                else\r
+                {\r
+                    GH3X2X_INFO_LOG("[%s]:switch to wear on\r\n", __FUNCTION__);\r
+                }\r
+                \r
+            }\r
+        }\r
+    }\r
+    else\r
+    {\r
+        *usEvent &= ~(GH3X2X_IRQ_MSK_WEAR_OFF_BIT|GH3X2X_IRQ_MSK_WEAR_ON_BIT);\r
+    }\r
+}\r
+#endif\r
+#endif\r
+\r
+GCHAR* GH3X2X_GetFirmwareVersion(void)\r
+{\r
+#ifdef GOODIX_DEMO_PLATFORM\r
+    return GetEvkVersion();\r
+#else\r
+    return GH3X2X_DEMO_VERSION_STRING;\r
+#endif\r
+}\r
+\r
+GCHAR* GH3X2X_GetDemoVersion(void)\r
+{\r
+    return GH3X2X_DEMO_VERSION_STRING;\r
+}\r
+\r
+#if (__SUPPORT_PROTOCOL_ANALYZE__)\r
+GCHAR* GH3X2X_GetEvkBootloaderVersion(void)\r
+{\r
+#ifdef GOODIX_DEMO_PLATFORM\r
+    return GetBootloaderVersion();\r
+#else\r
+    return GH3X2X_DEMO_VERSION_STRING;\r
+#endif\r
+}\r
+#endif\r
+\r
+/**\r
+ * @fn     void Gh3x2x_NormalizeGsensorSensitivity(STGsensorRawdata gsensor_buffer[], GU16 gsensor_point_num) \r
+ *\r
+ * @brief  normalize gsensor sensitivity to  512LSB/g\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]    gsensor_buffer          gsensor rawdata buffer\r
+ * @param[in]   gsensor_point_num     gsensor rawdata point num\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void Gh3x2x_NormalizeGsensorSensitivity(STGsensorRawdata gsensor_buffer[], GU16 gsensor_point_num)\r
+{\r
+    GU8 uchRightShift;\r
+    uchRightShift = __GS_SENSITIVITY_CONFIG__;\r
+    for(GU16 uchCnt = 0; uchCnt < gsensor_point_num; uchCnt++)\r
+    {\r
+        gsensor_buffer[uchCnt].sXAxisVal >>= uchRightShift;\r
+        gsensor_buffer[uchCnt].sYAxisVal >>= uchRightShift;\r
+        gsensor_buffer[uchCnt].sZAxisVal >>= uchRightShift;\r
+    }\r
+}\r
+\r
+\r
+void Gh3x2xFunctionCtrlModuleInit(void)\r
+{\r
+    g_unDemoFuncMode = 0;\r
+}\r
+/**\r
+ * @fn     void Gh3x2xDemoFunctionSampleRateSet(GU32 unFunctionID,  GU16 usSampleRate)\r
+ *\r
+ * @brief  \r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   unFunctionID   such as: GH3X2X_FUNCTION_HR   or  GH3X2X_FUNCTION_HR|GH3X2X_FUNCTION_HRV\r
+ * @param[in]   usSampleRate   only 25Hz times supported  (25/50/75...)\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+#if __SUPPORT_FUNCTION_SAMPLE_RATE_MODIFY__\r
+void Gh3x2xDemoFunctionSampleRateSet(GU32 unFunctionID,  GU16 usSampleRate)\r
+{\r
+    if((0 == usSampleRate)||(0 !=(usSampleRate%25)))\r
+    {\r
+        GH3X2X_INFO_LOG("%s : usSampleRate is invalid !!!\r\n", __FUNCTION__);\r
+        while(1);\r
+    }\r
+\r
+    for(GU8 uchFunctionCnt = 0; uchFunctionCnt < GH3X2X_FUNC_OFFSET_MAX; uchFunctionCnt++)\r
+    {\r
+        if(unFunctionID&(((GU32)1)<<uchFunctionCnt))\r
+        {\r
+            if(g_pstGh3x2xFrameInfo[uchFunctionCnt])\r
+            {\r
+                g_pstGh3x2xFrameInfo[uchFunctionCnt]->pstFunctionInfo->usSampleRateForUserSetting = usSampleRate;\r
+            }\r
+        }\r
+    }\r
+}\r
+#endif\r
+\r
+\r
+\r
+/**\r
+ * @fn      void Gh3x2xDemoFunctionChannelEnSet(GU32 unFunctionID,  GU32 unChnlEn)\r
+ *\r
+ * @brief  \r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   unFunctionID   such as: GH3X2X_FUNCTION_HR   or  GH3X2X_FUNCTION_HR|GH3X2X_FUNCTION_HRV\r
+ * @param[in]   unChnlEn   BitN = 0: channel N is disable        BitN = 1: channel N is enable\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void Gh3x2xDemoFunctionChannelEnSet(GU32 unFunctionID,  GU32 unChnlEn)\r
+{\r
+    for(GU8 uchFunctionCnt = 0; uchFunctionCnt < GH3X2X_FUNC_OFFSET_MAX; uchFunctionCnt++)\r
+    {\r
+        if(unFunctionID&(((GU32)1)<<uchFunctionCnt))\r
+        {\r
+            if(g_pstGh3x2xFrameInfo[uchFunctionCnt])\r
+            {\r
+                g_pstGh3x2xFrameInfo[uchFunctionCnt]->pstFunctionInfo->unChnlEnForUserSetting = unChnlEn;\r
+            }\r
+        }\r
+    }\r
+}\r
+\r
+/**\r
+ * @fn     void Gh3x2xDemoFunctionProcess(GU8* puchReadFifoBuffer, STGsensorRawdata *pstGsAxisValueArr, \r
+ *                                              GU16 usGsDataNum, EMGsensorSensitivity emGsSensitivity)\r
+ *\r
+ * @brief  Function process.This function will be called in Gh3x2xDemoInterruptProcess()\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   puchReadFifoBuffer      point to gh3x2x fifo data buffer\r
+ * @param[in]   pstGsAxisValueArr       point to gsensor data buffer\r
+ * @param[in]   usGsDataNum             gsensor data cnt\r
+ * @param[in]   emGsSensitivity         sensitivity of gsensor\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void Gh3x2xDemoFunctionProcess(GU8* puchReadFifoBuffer, GU16 usFifoBuffLen,STGsensorRawdata *pstGsAxisValueArr, GU16 usGsDataNum,\r
+                                   STCapRawdata* pstCapValueArr,GU16 usCapDataNum,STTempRawdata* pstTempValueArr,GU16 usTempDataNum)\r
+{\r
+    for(GU8 uchFunCnt = 0; uchFunCnt < GH3X2X_FUNC_OFFSET_MAX; uchFunCnt ++)\r
+    {\r
+        if(g_pstGh3x2xFrameInfo[uchFunCnt])\r
+        {\r
+            \r
+            if(g_unDemoFuncMode & (((GU32)1)<< uchFunCnt))\r
+            {\r
+                GH3x2xFunctionProcess(puchReadFifoBuffer,usFifoBuffLen,(GS16*)pstGsAxisValueArr,usGsDataNum,\r
+                                        pstCapValueArr,usCapDataNum,pstTempValueArr,usTempDataNum,\r
+                                        g_pstGh3x2xFrameInfo[uchFunCnt]);\r
+            }\r
+        }\r
+    }\r
+}\r
+\r
+\r
+#if __USER_DYNAMIC_DRV_BUF_EN__\r
+/**\r
+ * @fn     GU8 Gh3x2xDemoMemCheckValid(void)\r
+ *\r
+ * @brief  check dynamic memory is valid or not\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  0: invalid  1: valid\r
+ */\r
+GU8 Gh3x2xDemoMemCheckValid(void)\r
+{\r
+    if(0 == g_puchGh3x2xReadRawdataBuffer)\r
+    {\r
+        GH3X2X_INFO_LOG("%s : g_puchGh3x2xReadRawdataBuffer is invalid !!!\r\n", __FUNCTION__);\r
+        return 0;\r
+    }\r
+    #if __GH3X2X_CASCADE_EN__\r
+    if (GH3X2X_CascadeGetEcgEnFlag())\r
+    {\r
+        if(0 == g_puchGh3x2xReadRawdataBufferSlaveChip)\r
+        {\r
+            GH3X2X_INFO_LOG("%s : g_puchGh3x2xReadRawdataBufferSlaveChip is invalid !!!\r\n", __FUNCTION__);\r
+            return 0;\r
+        }\r
+    }\r
+    #endif\r
+    return 1;\r
+}\r
+\r
+\r
+void Gh3x2xDemoMemInit(void)\r
+{\r
+    if(0 == g_puchGh3x2xReadRawdataBuffer)\r
+    {\r
+        #if __GH3X2X_CASCADE_EN__\r
+        g_puchGh3x2xReadRawdataBuffer = Gh3x2xMallocUser(2 * __GH3X2X_RAWDATA_BUFFER_SIZE__);\r
+        #else\r
+        g_puchGh3x2xReadRawdataBuffer = Gh3x2xMallocUser(__GH3X2X_RAWDATA_BUFFER_SIZE__);\r
+        #endif\r
+    }\r
+    if(0 == Gh3x2xDemoMemCheckValid())\r
+    {\r
+        while(1);\r
+    }\r
+}\r
+#endif\r
+/**\r
+ * @fn     int Gh3x2xDemoInit(void)\r
+ *\r
+ * @brief  Init GH3x2x module\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  error code\r
+ */\r
+int Gh3x2xDemoInit(void)\r
+{\r
+\r
+    /// int mode default check\r
+    if (g_uchGh3x2xIntMode == __MIX_INT_PROCESS_MODE__)\r
+    {\r
+        g_uchGh3x2xIntMode = __POLLING_INT_PROCESS_MODE__;\r
+    }\r
+\r
+    GS8 schret = GH3X2X_RET_OK;\r
+\r
+    #if __GH3X2X_INFO_LOG_TYPE__ == __GH3X2X_INFO_LOG_METHOD_0__\r
+    g_pSnprintfUserIn = snprintf;\r
+    #if (__ALGO_LOG_CONFIG__)\r
+    goodix_set_sprintFunc(NULL, g_pSnprintfUserIn, GH3X2X_PlatformLog);\r
+    #endif\r
+    #elif __GH3X2X_INFO_LOG_TYPE__ == __GH3X2X_INFO_LOG_METHOD_1__\r
+    GH3X2X_RegisterPrintf(&g_pPrintfUserIn);\r
+    #endif\r
+\r
+    #if __USER_DYNAMIC_DRV_BUF_EN__\r
+    Gh3x2xDemoMemInit();\r
+    #endif\r
+\r
+    #ifdef GOODIX_DEMO_PLATFORM\r
+    GH3X2X_INFO_LOG("%s : Firmware Version : %s\r\n", __FUNCTION__, GH3X2X_GetFirmwareVersion());\r
+    #endif\r
+    GH3X2X_INFO_LOG("%s : Democode Version : %s\r\n", __FUNCTION__, GH3X2X_GetDemoVersion());\r
+    GH3X2X_INFO_LOG("%s : DrvLib Version : %s\r\n", __FUNCTION__, GH3X2X_GetDriverLibVersion());\r
+    #if (__SUPPORT_PROTOCOL_ANALYZE__)\r
+    GH3X2X_INFO_LOG("%s : Protocol Version : %s\r\n", __FUNCTION__, GH3X2X_GetProtocolVersion());\r
+    #endif\r
+    GH3X2X_INFO_LOG("%s : Config Version : %s\r\n", __FUNCTION__, GH3X2X_GetVirtualRegVersion());\r
+    #if (__DRIVER_LIB_MODE__ == __DRV_LIB_WITH_ALGO__)\r
+    GCHAR algo_version[120] = {0};\r
+    for (int i=0;i<GH3X2X_FUNC_OFFSET_MAX;i++)\r
+    {\r
+        GH3X2X_AlgoVersion(i, algo_version);\r
+        GH3X2X_INFO_LOG("%s : Algo Version : %s\r\n", __FUNCTION__, algo_version);\r
+    }\r
+    #endif\r
+\r
+\r
+    /* Step 1: init communicate interface. */\r
+    if(0 == g_uchGh3x2xInitFlag)\r
+    {\r
+        #if ( __GH3X2X_INTERFACE__ == __GH3X2X_INTERFACE_I2C__ )\r
+        hal_gh3x2x_i2c_init();\r
+        GH3X2X_RegisterI2cOperationFunc(__GH3X2X_I2C_DEVICE_ID__, hal_gh3x2x_i2c_write, hal_gh3x2x_i2c_read);\r
+        #if __GH3X2X_CASCADE_EN__\r
+        GH3X2X_RegisterI2cDeviceChip1(__GH3X2X_I2C_DEVICE_SLAVER_ID__);\r
+        #endif\r
+        #else //__GH3X2X_INTERFACE__ == __GH3X2X_INTERFACE_SPI__\r
+        hal_gh3x2x_spi_init();\r
+        #if (__GH3X2X_SPI_TYPE__ == __GH3X2X_SPI_TYPE_HARDWARE_CS__) \r
+        GH3X2X_RegisterSpiHwCsOperationFunc(hal_gh3x2x_spi_write, hal_gh3x2x_spi_write_F1_and_read);\r
+        #else\r
+        GH3X2X_RegisterSpiOperationFunc(hal_gh3x2x_spi_write, hal_gh3x2x_spi_read, hal_gh3x2x_spi_cs_ctrl);\r
+        #endif\r
+        #endif\r
+    }\r
+\r
+    #if __SUPPORT_HOOK_FUNC_CONFIG__\r
+    /* set hook */\r
+    GH3X2X_RegisterHookFunc(gh3x2x_init_hook_func, \r
+                            gh3x2x_sampling_start_hook_func,\r
+                            gh3x2x_sampling_stop_hook_func, \r
+                            gh3x2x_get_rawdata_hook_func,\r
+                            gh3x2x_frame_data_hook_func,\r
+                            gh3x2x_reset_by_protocol_hook,\r
+                            gh3x2x_config_set_start_hook,\r
+                            gh3x2x_config_set_stop_hook,\r
+                            gh3x2x_write_algo_config_hook);\r
+    #endif\r
+    \r
+\r
+    \r
+    #if 0\r
+\r
+\r
+    /* Step 2: Reset gh3x2x chip */\r
+    GH3X2X_RegisterDelayUsCallback(Gh3x2x_BspDelayUs);\r
+\r
+    #if __GH3X2X_CASCADE_EN__\r
+    GH3X2X_SetChipSleepFlag(0);\r
+    GH3X2X_SetChipSleepFlag(1);\r
+    #else\r
+    GH3X2X_SetChipSleepFlag(0);\r
+    #endif\r
+    \r
+    \r
+    #if __SUPPORT_HARD_RESET_CONFIG__    \r
+    if(0 == g_uchGh3x2xInitFlag)\r
+    {\r
+        hal_gh3x2x_reset_pin_init();\r
+    }    \r
+    GH3X2X_RegisterResetPinControlFunc(hal_gh3x2x_reset_pin_ctrl);\r
+    GH3X2X_HardReset();\r
+    #else\r
+    GH3X2X_SoftReset();\r
+    #endif\r
+\r
+    Gh3x2x_BspDelayMs(30);   \r
+    #if __GH3X2X_CASCADE_EN__\r
+    GH3X2X_CascadeOperationSlaverChip();\r
+    Gh3x2x_CHECK_0x0088_Ex();\r
+    Gh3x2x_CHECK_0x0088_Ex();\r
+    GH3X2X_CascadeOperationMasterChip();\r
+    #endif\r
+\r
+    /* Step 3: Init gh3x2x chip */\r
+    GhDrvConfigManagerInit();\r
+    g_uchGh3x2xRegCfgArrIndex = 0;\r
+    schret = GH3X2X_Init(&g_stGh3x2xCfgListArr[0]);\r
+    Gh3x2xDemoStopSampling(0xFFFFFFFF);   //stop all function\r
+\r
+    if (GH3X2X_RET_OK == schret)\r
+    {\r
+        Gh3x2xGetConfigVersion(&g_stGh3x2xCfgListArr[0]);\r
+        GH3X2X_INFO_LOG("Gh3x2xDemoInit:init success\r\n");\r
+    }\r
+    else\r
+    {\r
+        g_uchGh3x2xRegCfgArrIndex = DRV_LIB_REG_CFG_EMPTY;\r
+        GH3X2X_INFO_LOG("Gh3x2xDemoInit:init fail, error code: %d\r\n", schret);\r
+        return schret;\r
+    }\r
+    GH3X2X_SetMaxNumWhenReadFifo(__GH3X2X_RAWDATA_BUFFER_SIZE__);\r
+    GH3X2X_EnterLowPowerMode();\r
+    #if __GH3X2X_CASCADE_EN__\r
+    GH3X2X_CascadeOperationSlaverChip();\r
+    GH3X2X_EnterLowPowerMode();\r
+    GH3X2X_CascadeOperationMasterChip();\r
+    #endif\r
+\r
+    /* Step 4: setup EX INT for GH3X2X INT pin */\r
+    #if (__NORMAL_INT_PROCESS_MODE__ == __INTERRUPT_PROCESS_MODE__ || __MIX_INT_PROCESS_MODE__ == __INTERRUPT_PROCESS_MODE__)\r
+    if (g_uchGh3x2xIntMode == __NORMAL_INT_PROCESS_MODE__)\r
+    {\r
+        g_uchGh3x2xIntCallBackIsCalled = 0;\r
+        if(0 == g_uchGh3x2xInitFlag)\r
+        {\r
+            hal_gh3x2x_int_init();\r
+        }\r
+    }\r
+    #endif\r
+\r
+    #if (__SUPPORT_PROTOCOL_ANALYZE__)\r
+    Gh3x2x_HalSerialFifoInit();\r
+    GH3X2X_UprotocolPacketMaxLenConfig(GH3X2X_UPROTOCOL_PAYLOAD_LEN_MAX);\r
+    GH3X2X_RegisterGetFirmwareVersionFunc(GH3X2X_GetFirmwareVersion,\r
+                                          GH3X2X_GetDemoVersion,\r
+                                          GH3X2X_GetEvkBootloaderVersion);\r
+    #endif\r
+\r
+    /* Step 6: move detection module init */\r
+    #if (__GSENSOE_MOVE_DETECT_SUPPORT__)\r
+    #endif\r
+\r
+    Gh3x2xFunctionInfoForUserInit();\r
+    Gh3x2xFunctionCtrlModuleInit();\r
+               #if __FUNC_TYPE_ECG_ENABLE__\r
+    GH3X2X_ConfigLeadOffThr(LEADOFF_DET_IQ_AMP_THR_uV, LEADOFF_DET_IQ_AMP_DIFF_THR_uV,LEADOFF_DET_IQ_VAL_THR_mV);\r
+               #endif\r
+    g_uchGh3x2xInitFlag = 1;\r
+    #if __GH3X2X_MEM_POOL_CHECK_EN__\r
+    g_uchGh3x2xMemPollHaveGetCheckSum = 0;\r
+    #endif\r
+#endif\r
+    return (int)schret;\r
+}\r
+\r
+/**\r
+ * @fn     void Gh3x2xInterruptModeSwitch(GU8 uchIntModeType)\r
+ *\r
+ * @brief  change Interrupt process mode of GH3x2x.\r
+ *\r
+ * @attention   do not input 2\r
+ *\r
+ * @param[in]   emIntModeType 0:int pin 1: polling\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void Gh3x2xInterruptModeSwitch(GU8 uchIntModeType)\r
+{\r
+#if (__MIX_INT_PROCESS_MODE__ == __INTERRUPT_PROCESS_MODE__)\r
+    GH3X2X_INFO_LOG("[%s]:int process switch to = %d\r\n", __FUNCTION__, uchIntModeType);\r
+    g_uchGh3x2xIntMode = uchIntModeType;\r
+    g_uchGh3x2xInitFlag = 0;\r
+#else\r
+    GH3X2X_INFO_LOG("[%s]:do not allow int mode switch!!!\r\n", __FUNCTION__);\r
+#endif\r
+}\r
+\r
+GU8 Gh3x2xGetInterruptMode(void)\r
+{\r
+    return g_uchGh3x2xIntMode;\r
+}\r
+\r
+/**\r
+ * @fn     GU8 Gh3x2xDemoInterruptProcess(void)\r
+ *\r
+ * @brief  Interrupt process of GH3x2x.\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void Gh3x2xDemoInterruptProcess(void)\r
+{\r
+\r
+               if(0 == g_uchGh3x2xInitFlag)\r
+    {\r
+        GH3X2X_INFO_LOG("[%s]:gh3x2x is not init!!!\r\n", __FUNCTION__);\r
+        return;\r
+    }\r
+\r
+    GU8 uchRet = 0;\r
+    GU16 usGotEvent = 0;\r
+    GU8 uchIntRepeatNum = 0;\r
+    GU8 uchIsForceRead = 0;\r
+#if (__GH3X2X_CASCADE_EN__)\r
+    GU16 usGotSlaverEvent = 0;\r
+#endif\r
+    GU8 uchEventEx = 0;     //bit0:  0: object/no objiect   1: living/nonliving object\r
+                            //bit1:  0: None                1: chip0 lead on\r
+                            //bit2:  0: None                1: chip0 lead off\r
+                            //bit3:  0: None                1: chip1 lead on\r
+                            //bit4:  0: None                1: chip1 lead off\r
+\r
+    g_uchGh3x2xInterruptProNotFinishFlag = 1;\r
+\r
+#if (__FUNC_TYPE_ECG_ENABLE__)\r
+    STSoftLeadResult stLeadResult = {0, 0};\r
+#endif\r
+\r
+    if(GH3X2X_DEMO_WORK_MODE_MPT == g_uchDemoWorkMode)\r
+    {\r
+        return;\r
+    }\r
+\r
+#if __USER_DYNAMIC_DRV_BUF_EN__\r
+    if(0 == Gh3x2xDemoMemCheckValid())    //dynamic mem is not valid\r
+    {\r
+        GH3X2X_INFO_LOG("[%s]Warning, dynamic mem is not valid !!!\r\n",__FUNCTION__);\r
+        return;\r
+    }\r
+#endif\r
+\r
+\r
+\r
+#if __GH_MSG_WITH_ALGO_LAYER_EN__\r
+        GH3X2X_PRO_MSG_SOFT_WEAR_EVEVT();\r
+#endif\r
+\r
+    //check "Gh3x2xDemoInterruptProcess" call is legal or not\r
+#if (__NORMAL_INT_PROCESS_MODE__ == __INTERRUPT_PROCESS_MODE__ || __MIX_INT_PROCESS_MODE__ == __INTERRUPT_PROCESS_MODE__)\r
+    if (g_uchGh3x2xIntMode == __NORMAL_INT_PROCESS_MODE__)\r
+    {\r
+        if((0 == GH3X2X_GetSoftEvent())&&(0 == g_uchGh3x2xIntCallBackIsCalled))\r
+        {\r
+    #if (0 == __PLATFORM_WITHOUT_OS__)\r
+            GH3X2X_INFO_LOG("InterruptProcess: plese check hal_gh3x2x_int_handler_call_back is called or not !!!\r\n");\r
+    #endif\r
+            GH3X2X_INFO_LOG("InterruptProcess:invalid call, do not process.\r\n");\r
+            return;\r
+        }\r
+    }\r
+#endif\r
+\r
+#if (__NORMAL_INT_PROCESS_MODE__ == __INTERRUPT_PROCESS_MODE__ || __MIX_INT_PROCESS_MODE__ == __INTERRUPT_PROCESS_MODE__)\r
+    if (g_uchGh3x2xIntMode == __NORMAL_INT_PROCESS_MODE__)\r
+    {\r
+        g_uchGh3x2xIntCallBackIsCalled = 0;\r
+    }  \r
+#endif\r
+\r
+    do{\r
+        uchRet = GH3X2X_INT_PROCESS_SUCCESS;\r
+        usGotEvent = 0;\r
+    #if __GH3X2X_CASCADE_EN__\r
+         usGotSlaverEvent = 0;\r
+    #endif\r
+\r
+        /* Step 1: read irq status */\r
+\r
+    #if (__FUNC_TYPE_ECG_ENABLE__)\r
+        GH3X2X_Memset((GU8*)(&stLeadResult),0,sizeof(stLeadResult));\r
+    #endif\r
+\r
+        usGotEvent = GH3X2X_GetIrqStatus();\r
+    #if (__GH3X2X_CASCADE_EN__)\r
+         if (GH3X2X_CascadeGetEcgEnFlag())\r
+         {\r
+             GH3X2X_CascadeOperationSlaverChip();\r
+             usGotSlaverEvent = GH3X2X_GetIrqStatus();\r
+             GH3X2X_CascadeOperationMasterChip();\r
+             if((usGotEvent|usGotSlaverEvent)&(GH3X2X_IRQ_MSK_WEAR_ON_BIT|GH3X2X_IRQ_MSK_WEAR_OFF_BIT|GH3X2X_IRQ_MSK_LEAD_ON_DET_BIT|GH3X2X_IRQ_MSK_LEAD_ON_DET_BIT))\r
+             {\r
+                GH3X2X_INFO_LOG("usGotMasterEvent:0x%04x usGotSlaverEvent:0x%04x\r\n",usGotEvent, usGotSlaverEvent);\r
+             }\r
+         }\r
+         else\r
+         {\r
+            GH3X2X_INFO_LOG("usGotMasterEvent:0x%04x \r\n",usGotEvent);\r
+         }\r
+    #endif\r
+        usGotEvent &= __GH3X2X_EVENT_PROCESS_MASK__;\r
+        //GH3X2X_INFO_LOG("usGotEvent = 0x%x\r\n", usGotEvent);\r
+\r
+    #if (__SUPPORT_HARD_ADT_CONFIG__)                           \r
+        /* Step 2: if hard adt enabled, do wear event process */\r
+        /* 1) if algo hard adt, delete adt event */\r
+        #if __HARD_ADT_ALGO_CHECK_EN__\r
+            usGotEvent &= (~__GH3X2X_ADT_EVENT_MASK__);\r
+        #else\r
+        /* 2) adt event handle for chip*/\r
+        Gh3x2xDemoWearEventProcess(&usGotEvent, WEAR_DETECT_DONT_FORCE_SWITCH);\r
+        #if (__GH3X2X_INFO_LOG_TYPE__ > __GH3X2X_INFO_LOG_DISABLE__)\r
+        if(0 != (usGotEvent & GH3X2X_IRQ_MSK_WEAR_ON_BIT))\r
+        {\r
+            GH3X2X_INFO_LOG("Got hardware wear on !!! \r\n");\r
+        }\r
+        if(0 != (usGotEvent & GH3X2X_IRQ_MSK_WEAR_OFF_BIT))\r
+        {\r
+            GH3X2X_INFO_LOG("Got hardware wear off !!! \r\n");\r
+        }\r
+        #endif\r
+        #endif\r
+    #if 0\r
+        (&usGotEvent, &uchEventEx);\r
+    #endif\r
+    \r
+\r
+        /* 3) check soft adt event */\r
+        //nadt event\r
+        if(GH3X2X_GetSoftEvent() & GH3X2X_SOFT_EVENT_WEAR_OFF)\r
+        {\r
+            uchEventEx |= GH3X2X_EVENT_EX_BIT_WEAR_LIVING_TYPE;\r
+            usGotEvent |= GH3X2X_IRQ_MSK_WEAR_OFF_BIT;\r
+            GH3X2X_ClearSoftEvent(GH3X2X_SOFT_EVENT_WEAR_OFF);\r
+        }\r
+        else if(GH3X2X_GetSoftEvent() & GH3X2X_SOFT_EVENT_WEAR_ON)\r
+        {\r
+            uchEventEx |= GH3X2X_EVENT_EX_BIT_WEAR_LIVING_TYPE;\r
+            usGotEvent |= GH3X2X_IRQ_MSK_WEAR_ON_BIT;\r
+            GH3X2X_ClearSoftEvent(GH3X2X_SOFT_EVENT_WEAR_ON);\r
+        }\r
+        #if __HARD_ADT_ALGO_CHECK_EN__\r
+        //algo adt event\r
+        if(GH3X2X_GetSoftEvent() & GH3X2X_SOFT_EVENT_WEAR_OFF_ALGO_ADT)\r
+        {\r
+            usGotEvent |= GH3X2X_IRQ_MSK_WEAR_OFF_BIT;\r
+            GH3X2X_ClearSoftEvent(GH3X2X_SOFT_EVENT_WEAR_OFF_ALGO_ADT);\r
+        }\r
+        else if(GH3X2X_GetSoftEvent() & GH3X2X_SOFT_EVENT_WEAR_ON_ALGO_ADT)\r
+        {\r
+            usGotEvent |= GH3X2X_IRQ_MSK_WEAR_ON_BIT;\r
+            GH3X2X_ClearSoftEvent(GH3X2X_SOFT_EVENT_WEAR_ON_ALGO_ADT);\r
+        }\r
+        #else\r
+        GH3X2X_ClearSoftEvent(GH3X2X_SOFT_EVENT_WEAR_OFF_ALGO_ADT|GH3X2X_SOFT_EVENT_WEAR_ON_ALGO_ADT);  //if use ADT module in chip, we need ignore these soft event\r
+        #endif\r
+    #endif\r
+\r
+        /****** Start: Ecg Cascade Debug information********/\r
+#if (__GH3X2X_CASCADE_EN__)\r
+        if (GH3X2X_CascadeGetEcgEnFlag())\r
+        {\r
+            GH3X2X_CascadeOperationMasterChip();\r
+            //GH3X2X_INFO_LOG("Master: 0x00:%04x 0x108:%d  0x400:%04x 0x50c:%04x 0x088:%04x\r\n",GH3X2X_ReadReg(0x00),GH3X2X_ReadReg(0x108),GH3X2X_ReadReg(0x400),GH3X2X_ReadReg(0x74),GH3X2X_ReadReg(0x88));\r
+            GH3X2X_CascadeOperationSlaverChip();\r
+            //GH3X2X_INFO_LOG("Slaver: 0x00:%04x 0x108:%d  0x400:%04x 0x50c:%04x 0x088:%04x\r\n",GH3X2X_ReadReg(0x00),GH3X2X_ReadReg(0x108),GH3X2X_ReadReg(0x400),GH3X2X_ReadReg(0x74),GH3X2X_ReadReg(0x88));\r
+            GH3X2X_CascadeOperationMasterChip();\r
+        }\r
+        else\r
+        {\r
+            GH3X2X_INFO_LOG("Master: 0x00:%04x 0x108:%d  0x400:%04x 0x50c:%04x 0x088:%04x\r\n",GH3X2X_ReadReg(0x00),GH3X2X_ReadReg(0x108),GH3X2X_ReadReg(0x400),GH3X2X_ReadReg(0x74),GH3X2X_ReadReg(0x88));\r
+        }\r
+#endif\r
+        /****** End: Ecg Cascade Debug information********/\r
+\r
+        /* Step 3: if it's FIFO interrupt, read gh3x2x fifo data, read gsensor data*/\r
+    #if (__POLLING_INT_PROCESS_MODE__ == __INTERRUPT_PROCESS_MODE__ || __MIX_INT_PROCESS_MODE__ == __INTERRUPT_PROCESS_MODE__)\r
+        if (g_uchGh3x2xIntMode == __POLLING_INT_PROCESS_MODE__)\r
+        {\r
+            usGotEvent |= GH3X2X_IRQ_MSK_FIFO_WATERMARK_BIT;\r
+        }\r
+    #endif\r
+        g_usGh3x2xReadRawdataLen = 0;\r
+        if ((usGotEvent & (GH3X2X_IRQ_MSK_FIFO_WATERMARK_BIT | GH3X2X_IRQ_MSK_FIFO_FULL_BIT)) \\r
+            || (GH3X2X_GetSoftEvent() & (GH3X2X_SOFT_EVENT_NEED_FORCE_READ_FIFO|GH3X2X_SOFT_EVENT_NEED_TRY_READ_FIFO)))\r
+        {\r
+            GU16 usFifoByteNum = ((GU16)4)*GH3X2X_ReadReg(GH3X2X_INT_FIFO_UR_REG_ADDR); //read fifo use\r
+            //GH3X2X_INFO_LOG("usFifoByteNum = %d\r\n", usFifoByteNum);\r
+        #if (__GH3X2X_CASCADE_EN__)\r
+            //vTaskDelay(5);\r
+            GU16 usFifoByteNumSlaver = 0;\r
+            if (GH3X2X_CascadeGetEcgEnFlag())\r
+            {\r
+                GH3X2X_CascadeOperationSlaverChip();\r
+                usFifoByteNumSlaver = ((GU16)4)*GH3X2X_ReadReg(GH3X2X_INT_FIFO_UR_REG_ADDR);\r
+                GH3X2X_CascadeOperationMasterChip();\r
+            }\r
+\r
+        #endif\r
+        #if (__NORMAL_INT_PROCESS_MODE__ == __INTERRUPT_PROCESS_MODE__ || __MIX_INT_PROCESS_MODE__ == __INTERRUPT_PROCESS_MODE__)\r
+            if (g_uchGh3x2xIntMode == __NORMAL_INT_PROCESS_MODE__)\r
+            {\r
+                uchIsForceRead = (GH3X2X_GetSoftEvent() & (GH3X2X_SOFT_EVENT_NEED_FORCE_READ_FIFO|GH3X2X_SOFT_EVENT_NEED_TRY_READ_FIFO));\r
+                if(0 == uchIsForceRead)\r
+                {\r
+                    if(usFifoByteNum < ((GU16)4)*GH3X2X_GetCurrentFifoWaterLine())  //data is too less\r
+                    {\r
+                        usFifoByteNum = 0;   //no need read\r
+                        GH3X2X_INFO_LOG("Data is too less, no need read\r\n");\r
+                    }\r
+                }\r
+            }\r
+        #endif\r
+\r
+            GH3X2X_ClearSoftEvent(GH3X2X_SOFT_EVENT_NEED_FORCE_READ_FIFO|GH3X2X_SOFT_EVENT_NEED_TRY_READ_FIFO);\r
+            if (usFifoByteNum != 0)\r
+            {\r
+            #if (__DRIVER_LIB_MODE__ == __DRV_LIB_WITH_ALGO__)\r
+                GH3X2X_TimestampSyncSetPpgIntFlag(1);\r
+            #endif\r
+            #if !(__GH3X2X_CASCADE_EN__)\r
+                if (GH3X2X_RET_READ_FIFO_CONTINUE == GH3X2X_ReadFifodata(g_puchGh3x2xReadRawdataBuffer, &g_usGh3x2xReadRawdataLen, usFifoByteNum))\r
+                {\r
+                    GH3X2X_SetSoftEvent(GH3X2X_SOFT_EVENT_NEED_TRY_READ_FIFO);\r
+                }\r
+            #else\r
+                if (GH3X2X_CascadeGetEcgEnFlag())\r
+                {\r
+                    //GH3X2X_INFO_LOG("Master fifo:%d  Slaver Fifo:%d CurrentFifoWaterLine:%d\r\n", usFifoByteNum/4, usFifoByteNumSlaver/4, GH3X2X_GetCurrentFifoWaterLine());\r
+                    if (usFifoByteNum > usFifoByteNumSlaver)\r
+                    {\r
+                        usFifoByteNum = usFifoByteNumSlaver;\r
+                    }\r
+                    if (usFifoByteNum > __GH3X2X_RAWDATA_SLAVE_BUFFER_SIZE__)\r
+                    {\r
+                        usFifoByteNum = __GH3X2X_RAWDATA_SLAVE_BUFFER_SIZE__;\r
+                    }\r
+                    if (GH3X2X_RET_READ_FIFO_CONTINUE == GH3X2X_CascadeReadFifodata(g_puchGh3x2xReadRawdataBuffer,g_puchGh3x2xReadRawdataBufferSlaveChip, &g_usGh3x2xReadRawdataLen ,usFifoByteNum, 0x08))\r
+                    {\r
+                        GH3X2X_SetSoftEvent(GH3X2X_SOFT_EVENT_NEED_TRY_READ_FIFO);\r
+                    }\r
+                }\r
+\r
+                else\r
+                {\r
+                    if (GH3X2X_RET_READ_FIFO_CONTINUE == GH3X2X_ReadFifodata(g_puchGh3x2xReadRawdataBuffer, &g_usGh3x2xReadRawdataLen, usFifoByteNum))\r
+                    {\r
+                        GH3X2X_SetSoftEvent(GH3X2X_SOFT_EVENT_NEED_TRY_READ_FIFO);\r
+                    }\r
+                }\r
+            #endif\r
+            #if ((__SUPPORT_PROTOCOL_ANALYZE__)||(__SUPPORT_ALGO_INPUT_OUTPUT_DATA_HOOK_CONFIG__))\r
+            #if (__SUPPORT_ELECTRODE_WEAR_STATUS_DUMP__)\r
+                GH3X2X_ReadElectrodeWearDumpData();\r
+            #endif\r
+                #if !__SUPPORT_SOFT_AGC_CONFIG__\r
+                GH3X2X_RecordDumpData();\r
+                #endif\r
+            #endif\r
+                if( uchIntRepeatNum == 0)\r
+                {\r
+                    GH3X2X_UpdateAgcInfo();\r
+                }\r
+            }\r
+        }\r
+\r
+    #if (__FUNC_TYPE_ECG_ENABLE__)\r
+        /* extra step: ECG Gain calibration*/\r
+        #if !(__GH3X2X_CASCADE_EN__)\r
+        GH3X2X_CalibrateECGGain(g_puchGh3x2xReadRawdataBuffer,g_usGh3x2xReadRawdataLen);\r
+        #else\r
+        if (GH3X2X_CascadeGetEcgEnFlag())\r
+        {\r
+            GH3X2X_CascadeCalibrateECGGain(g_puchGh3x2xReadRawdataBuffer,g_usGh3x2xReadRawdataLen);\r
+        }\r
+        else\r
+        {\r
+            GH3X2X_CalibrateECGGain(g_puchGh3x2xReadRawdataBuffer,g_usGh3x2xReadRawdataLen);\r
+        }\r
+        #endif\r
+\r
+        /* Step 4: if ECG enabled, do soft lead off process */\r
+        #if (__GH3X2X_CASCADE_EN__)\r
+        if (GH3X2X_CascadeGetEcgEnFlag())\r
+        {\r
+            usGotEvent = GH3X2X_CascadeLeadOnEventPreDeal(usGotEvent, usGotSlaverEvent,&uchEventEx);\r
+        }\r
+        #endif\r
+        stLeadResult = GH3X2X_LeadHandle(usGotEvent, g_puchGh3x2xReadRawdataBuffer, &g_usGh3x2xReadRawdataLen);\r
+        usGotEvent = stLeadResult.usEvent;\r
+\r
+        if(stLeadResult.uchNeedForceReadFifo)\r
+        {\r
+            GH3X2X_SetSoftEvent(GH3X2X_SOFT_EVENT_NEED_FORCE_READ_FIFO);\r
+        }\r
+        GH3X2X_EcgRsHandle(g_puchGh3x2xReadRawdataBuffer, &g_usGh3x2xReadRawdataLen);\r
+    #endif\r
+\r
+        /* Step 5: do soft agc process*/\r
+        Gh3x2x_UserHandleCurrentInfo();\r
+    #if (__SUPPORT_ENGINEERING_MODE__)\r
+        if(0 == g_uchEngineeringModeStatus)  //in engineering mode,  disable soft agc function\r
+    #endif\r
+            {\r
+            if(0 != (usGotEvent & (GH3X2X_IRQ_MSK_TUNNING_FAIL_BIT | GH3X2X_IRQ_MSK_TUNNING_DONE_BIT)))\r
+            {\r
+//                GH3X2X_SoftLedADJAutoADJInt();\r
+            }\r
+        #if (__SUPPORT_SAMPLE_DEBUG_MODE__)\r
+            if((g_usDumpMode & 0x3) != 0)\r
+            {\r
+                GH3X2X_LedAgcProcessExDump(g_puchGh3x2xReadRawdataBuffer);\r
+            }\r
+            else\r
+        #endif\r
+            {    \r
+                #if __SUPPORT_SOFT_AGC_CONFIG__\r
+                if( uchIntRepeatNum == 0)\r
+                {\r
+                    GH3X2X_LedAgcProcess(g_puchGh3x2xReadRawdataBuffer, g_usGh3x2xReadRawdataLen, g_pstGh3x2xAgcInfo);\r
+                }\r
+                #endif\r
+            }\r
+        }\r
+\r
+        /* Extern Step: send fifo*/\r
+    #if (__FIFO_PACKAGE_SEND_ENABLE__)\r
+        if (GH3X2X_GetFifoPackageMode())\r
+        {\r
+            GH3X2X_SendRawdataFifoPackage(g_puchGh3x2xReadRawdataBuffer, g_usGh3x2xReadRawdataLen);\r
+        }\r
+    #endif\r
+\r
+        /* Step 6: chip reset event process*/\r
+        if(0 != (usGotEvent & GH3X2X_IRQ_MSK_CHIP_RESET_BIT))\r
+        {\r
+            if(0 == GH3x2x_GetChipResetRecoveringFlag())  //do nothing in recover period\r
+            {\r
+                GH3X2X_INFO_LOG("Got chip reset event !!! ActiveChipResetFlag = %d, g_unDemoFuncMode = %d, recovering flag = %d\r\n",(int)GH3x2x_GetActiveChipResetFlag(), (int)g_unDemoFuncMode, (int)GH3x2x_GetChipResetRecoveringFlag());\r
+                if((GH3x2x_GetActiveChipResetFlag()))  //it will enter this "if" after loading cfg in EVK mode\r
+                {\r
+                    Gh3x2xDemoSamplingControl(0xFFFFFFFF, UPROTOCOL_CMD_STOP);\r
+                    GH3X2X_Init(GH3X2X_PTR_NULL);   //It should not init any config in array.c, because PC tool will send config after this process in EVK mode\r
+                }\r
+                \r
+                #ifdef GOODIX_DEMO_PLATFORM\r
+                else if(g_uchDemoWorkMode <= GH3X2X_DEMO_WORK_MODE_MCU_ONLINE)  //in APP/EVK/MCU online mode, do not support recovery from abnormal reset\r
+                {\r
+                    Gh3x2xDemoSamplingControl(0xFFFFFFFF, UPROTOCOL_CMD_STOP);\r
+                    GH3X2X_Init(GH3X2X_PTR_NULL);\r
+                }\r
+                #endif\r
+                else\r
+                {\r
+                    //need recovery for chip reset\r
+                    GU8 uchTryCnt = 5;   //retry max count\r
+                    GS8 schret = GH3X2X_RET_GENERIC_ERROR;\r
+                    GU32 unDemoFuncModeBeforeChipReset;\r
+                    GH3X2X_INFO_LOG("Gh3x2xDemoInterruptProcess:start chip reset recovery...\r\n");\r
+                    GH3x2x_SetChipResetRecoveringFlag(1);\r
+\r
+                    \r
+                    unDemoFuncModeBeforeChipReset = g_unDemoFuncMode;\r
+                    do{\r
+                            #if __SUPPORT_HARD_RESET_CONFIG__\r
+                                GH3X2X_HardReset();\r
+                            #else\r
+                                GH3X2X_SoftReset();\r
+                            #endif \r
+                                Gh3x2x_BspDelayMs(30);\r
+                                \r
+                                Gh3x2xDemoStopSampling(g_unDemoFuncMode);\r
+                                GH3X2X_INFO_LOG("Gh3x2xDemoInterruptProcess:use cfg%d to recover.\r\n",g_uchGh3x2xRegCfgArrIndex);\r
+                                \r
+                                schret = GH3X2X_Init(g_stGh3x2xCfgListArr+g_uchGh3x2xRegCfgArrIndex);\r
+                                \r
+                                if (GH3X2X_RET_OK == schret)\r
+                                {\r
+                                    GH3X2X_INFO_LOG("Gh3x2xDemoInterruptProcess:recovery init success\r\n");\r
+                                }\r
+                                else\r
+                                {\r
+                                    //g_uchGh3x2xRegCfgArrIndex = DRV_LIB_REG_CFG_EMPTY;\r
+                                    GH3X2X_INFO_LOG("Gh3x2xDemoInterruptProcess:recovery init fail, error code: %d\r\n", schret);\r
+                                }\r
+                                uchTryCnt --;\r
+                        }while((GH3X2X_RET_OK != schret)&&(0 < uchTryCnt));\r
+\r
+                    GH3X2X_EnterLowPowerMode();\r
+                #if __GH3X2X_CASCADE_EN__\r
+                    GH3X2X_CascadeOperationSlaverChip();\r
+                    GH3X2X_EnterLowPowerMode();\r
+                    GH3X2X_CascadeOperationMasterChip();\r
+                #endif\r
+\r
+                #if (__SUPPORT_ENGINEERING_MODE__)\r
+                    if(1 == g_uchEngineeringModeStatus)\r
+                    {\r
+                        Gh3x2xDemoStartSamplingForEngineeringMode(unDemoFuncModeBeforeChipReset, g_uchGh3x2xRegCfgArrIndex, g_pstSampleParaGroup, g_uchEngineeringModeSampleParaGroupNum);\r
+                    }\r
+                    else\r
+                #endif\r
+                    {\r
+                        Gh3x2xDemoStartSampling(unDemoFuncModeBeforeChipReset);\r
+                    }\r
+                    GH3x2x_SetChipResetRecoveringFlag(0);\r
+                }\r
+            }\r
+        }\r
+\r
+    #if !(__GH3X2X_CASCADE_EN__)\r
+        GH3X2X_EnterLowPowerMode();\r
+        #else\r
+        if (GH3X2X_CascadeGetEcgEnFlag())\r
+        {\r
+            GH3X2X_EnterLowPowerMode();\r
+            GH3X2X_CascadeOperationSlaverChip();\r
+            GH3X2X_EnterLowPowerMode();\r
+            GH3X2X_CascadeOperationMasterChip();\r
+        }\r
+        else\r
+        {\r
+            GH3X2X_EnterLowPowerMode();\r
+        }\r
+    #endif\r
+\r
+        /* Step 7: report event */\r
+    #if (__SUPPORT_PROTOCOL_ANALYZE__)\r
+        Gh3x2xDemoReportEvent(usGotEvent,uchEventEx);\r
+                               \r
+        if(uchEventEx&GH3X2X_EVENT_EX_BIT_CHIP0_LEAD_ON)\r
+        {\r
+            GH3X2X_INFO_LOG("chip0 lead on\r\n");\r
+            //while(1);\r
+        }\r
+        if(uchEventEx&GH3X2X_EVENT_EX_BIT_CHIP1_LEAD_ON)\r
+        {\r
+            GH3X2X_INFO_LOG("chip1 lead on\r\n");\r
+            //while(1);\r
+        }\r
+    #endif\r
+        if ((usGotEvent & (GH3X2X_IRQ_MSK_FIFO_WATERMARK_BIT | GH3X2X_IRQ_MSK_FIFO_FULL_BIT)) \\r
+             || uchIsForceRead)\r
+        {\r
+        #if __GS_NONSYNC_READ_EN__\r
+            GU16 usGsensorNeedPointNum;\r
+            GS16 sGsensorHeadPosi;\r
+        #endif\r
+            if (GH3X2X_GetGsensorEnableFlag())\r
+            {\r
+            #if (__GSENSOE_MOVE_DETECT_SUPPORT__)\r
+                if(0 == GhGsMoveDetecterIsEnable())\r
+            #endif\r
+                {\r
+                    hal_gsensor_drv_get_fifo_data(gsensor_soft_fifo_buffer + __GS_EXTRA_BUF_LEN__, &gsensor_soft_fifo_buffer_index);        \r
+                    Gh3x2x_NormalizeGsensorSensitivity(gsensor_soft_fifo_buffer + __GS_EXTRA_BUF_LEN__ ,gsensor_soft_fifo_buffer_index);\r
+                }\r
+            }\r
+            /*extra step: get cap and temp data from other sensor*/\r
+            #if __CAP_ENABLE__\r
+            if (GH3X2X_GetCapEnableFlag())\r
+            {\r
+                hal_cap_drv_get_fifo_data(cap_soft_fifo_buffer, &cap_soft_fifo_buffer_index);\r
+            }\r
+            #endif\r
+            #if __TEMP_ENABLE__\r
+            if (GH3X2X_GetTempEnableFlag())\r
+            {\r
+                hal_temp_drv_get_fifo_data(temp_soft_fifo_buffer, &temp_soft_fifo_buffer_index);\r
+            }\r
+            #endif\r
+            /* Step 8: algorithm process*/\r
+            #if __GH3X2X_MEM_POOL_CHECK_EN__\r
+            Gh3x2xCheckMemPollBeforeAlgoCal();\r
+            #endif\r
+\r
+        #ifdef GOODIX_DEMO_PLATFORM\r
+            if (((GH3X2X_DEMO_WORK_MODE_MCU_ONLINE == g_uchDemoWorkMode) ||\\r
+                        (GH3X2X_DEMO_WORK_MODE_PASS_THROUGH == g_uchDemoWorkMode) ||\\r
+                        (GH3X2X_DEMO_WORK_MODE_APP == g_uchDemoWorkMode) ||\\r
+                        (GH3X2X_DEMO_WORK_MODE_EVK == g_uchDemoWorkMode)) &&\\r
+                        ((g_usDumpMode & 0x3) == 0))\r
+        #endif\r
+            {\r
+            #if __GS_NONSYNC_READ_EN__\r
+                usGsensorNeedPointNum = Gh3x2xGetGsensorNeedPointNum(gsensor_soft_fifo_buffer_index, g_puchGh3x2xReadRawdataBuffer, g_usGh3x2xReadRawdataLen);\r
+                sGsensorHeadPosi = Gh3x2xGetGsensorHeadPos(gsensor_soft_fifo_buffer_index,usGsensorNeedPointNum);    \r
+                Gh3x2xDemoFunctionProcess(g_puchGh3x2xReadRawdataBuffer,g_usGh3x2xReadRawdataLen, gsensor_soft_fifo_buffer + __GS_EXTRA_BUF_LEN__ + sGsensorHeadPosi, usGsensorNeedPointNum,\r
+                                                cap_soft_fifo_buffer,cap_soft_fifo_buffer_index,temp_soft_fifo_buffer,temp_soft_fifo_buffer_index);\r
+\r
+\r
+                for(GU16 usPointCnt = 0; usPointCnt < usGsensorNeedPointNum; usPointCnt++)\r
+                {\r
+                    STGsensorRawdata * temp_gsensor = gsensor_soft_fifo_buffer + __GS_EXTRA_BUF_LEN__ + sGsensorHeadPosi;\r
+                    GH3X2X_INFO_LOG("[Gsensor show]x = %d,y = %d, z = %d\r\n",temp_gsensor[usPointCnt].sXAxisVal,temp_gsensor[usPointCnt].sYAxisVal,temp_gsensor[usPointCnt].sZAxisVal);\r
+                }\r
+\r
+                \r
+                Gh3x2xNonSyncGsenosrPostProcess(gsensor_soft_fifo_buffer_index, usGsensorNeedPointNum, sGsensorHeadPosi); \r
+            #else\r
+                Gh3x2xDemoFunctionProcess(g_puchGh3x2xReadRawdataBuffer,g_usGh3x2xReadRawdataLen, gsensor_soft_fifo_buffer + __GS_EXTRA_BUF_LEN__, gsensor_soft_fifo_buffer_index,\r
+                                                cap_soft_fifo_buffer,cap_soft_fifo_buffer_index,temp_soft_fifo_buffer,temp_soft_fifo_buffer_index);\r
+            #endif\r
+            }\r
+            #if __GH3X2X_MEM_POOL_CHECK_EN__\r
+            Gh3x2xUpdataMemPollChkSumAfterAlgoCal();\r
+            #endif\r
+        }\r
+\r
+        /* Step 9: event hook */\r
+    #if (__FUNC_TYPE_ECG_ENABLE__)\r
+        if (usGotEvent & GH3X2X_IRQ_MSK_LEAD_ON_DET_BIT)\r
+        {\r
+            Gh3x2x_LeadOnEventHook();\r
+            GH3X2X_INFO_LOG("Lead on!!!\r\n");\r
+        }\r
+        if (usGotEvent & GH3X2X_IRQ_MSK_LEAD_OFF_DET_BIT)\r
+        {\r
+            Gh3x2x_LeadOffEventHook();\r
+            GH3X2X_INFO_LOG("Lead off!!!\r\n");\r
+        }\r
+    #endif\r
+\r
+    #if (__SUPPORT_HARD_ADT_CONFIG__)\r
+        if ((usGotEvent & GH3X2X_IRQ_MSK_WEAR_ON_BIT) || (usGotEvent & GH3X2X_IRQ_MSK_WEAR_OFF_BIT))\r
+        {\r
+        #if (__GH3X2X_CASCADE_EN__)\r
+            Gh3x2x_WearEventCascadeEcgHandle(usGotEvent);\r
+        #endif\r
+            Gh3x2x_WearEventHook(usGotEvent, uchEventEx);\r
+        }\r
+    #endif\r
+\r
+        if (GH3X2X_GetSoftEvent())  //have new soft event\r
+        {\r
+            uchRet = GH3X2X_INT_PROCESS_REPEAT;\r
+            GH3X2X_INFO_LOG("InterruptProcess: process need repeat, soft evt = 0x%X\r\n", GH3X2X_GetSoftEvent());\r
+        }\r
+\r
+        if (uchIntRepeatNum > 20)\r
+        {\r
+            GH3X2X_INFO_LOG("InterruptProcess: 0 Warning!!!!GetEvent Error!!!0x%x\r\n", usGotEvent);\r
+            GH3X2X_INFO_LOG("InterruptProcess: 1 Warning!!!!GetEvent Error!!!0x%x\r\n", usGotEvent);\r
+            GH3X2X_INFO_LOG("InterruptProcess: 2 Warning!!!!GetEvent Error!!!0x%x\r\n", usGotEvent);\r
+            GH3X2X_ClearSoftEvent(GH3X2X_SOFT_EVENT_NEED_TRY_READ_FIFO);\r
+            Gh3x2xFifoRecovery();\r
+            break;\r
+        }\r
+        else\r
+        {\r
+            uchIntRepeatNum++;\r
+        }\r
+    }while(GH3X2X_INT_PROCESS_REPEAT == uchRet);\r
+\r
+    g_uchGh3x2xInterruptProNotFinishFlag = 0;\r
+}\r
+\r
+#if __GH3X2X_CASCADE_EN__\r
+GU8 Gh3x2xCheckCfgValidForCascade(GU8 uchCfgIndex)\r
+{\r
+    if(GH3X2X_CascadeGetEcgEnFlag())\r
+    {\r
+        if(2 != uchCfgIndex)   //In cascade mode, only cfg2 is valid\r
+        {\r
+            return 0;\r
+        }\r
+    }\r
+    else\r
+    {\r
+        if(2 == uchCfgIndex)   //Not in cascade mode, cfg2 is invalid\r
+        {\r
+            return 0;\r
+        }\r
+    }\r
+    return 1;\r
+}\r
+#endif\r
+\r
+/**\r
+ * @fn     GS8 GH3x2xDemoSearchCfgListByFunc(GU8* puchCfgIndex, GU32 unFuncMode, GU32 unFuncModeFilter)\r
+ *\r
+ * @brief  Search reg config array by function mode\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   unFuncMode              function mode\r
+ * @param[in]   unFuncModeFilter        ignored function mode\r
+ * @param[out]  puchCfgIndex            reg config array index\r
+ *\r
+ * @return  GH3X2X_RET_OK:switch application mode success\r
+ * @return  GH3X2X_RET_RESOURCE_ERROR:can't find corresponding reg config array\r
+ */\r
+GS8 GH3x2xDemoSearchCfgListByFunc(GU8* puchCfgIndex, GU32 unFuncMode, GU32 unFuncModeFilter)\r
+{\r
+    GS8  chRet = GH3X2X_RET_OK;\r
+    GU8  uchIndex = 0;\r
+    GU32 unFuncModeTemp = GH3X2X_NO_FUNCTION;\r
+    //find reg config array that match unFuncMode\r
+    GH3X2X_INFO_LOG("target app mode:0x%x\r\n",unFuncMode);\r
+    for (uchIndex = 0; uchIndex < __GH3X2X_CFG_LIST_MAX_NUM__; uchIndex++)\r
+    {\r
+        if (\r
+            (((g_stGh3x2xCfgListArr+uchIndex)->usConfigArrLen) > DRV_LIB_REG_CFG_MIN_LEN)\r
+            #if __GH3X2X_CASCADE_EN__\r
+            &&(1 == Gh3x2xCheckCfgValidForCascade(uchIndex))\r
+            #endif\r
+            )\r
+        {\r
+            GH3X2X_DecodeRegCfgArr(&unFuncModeTemp,(g_stGh3x2xCfgListArr+uchIndex)->pstRegConfigArr, \\r
+                                (g_stGh3x2xCfgListArr+uchIndex)->usConfigArrLen);\r
+\r
+            \r
+            GH3X2X_INFO_LOG("search cfg app mode:0x%x\r\n",unFuncModeTemp);\r
+                                \r
+            if((unFuncMode | unFuncModeFilter) == ((unFuncModeTemp&unFuncMode) | unFuncModeFilter))\r
+            {\r
+                (*puchCfgIndex) = uchIndex;\r
+                GH3X2X_INFO_LOG("Got right cfg ,index = %d\r\n",uchIndex);\r
+                break;\r
+            }\r
+        }\r
+    }\r
+\r
+    if (uchIndex >= __GH3X2X_CFG_LIST_MAX_NUM__)\r
+    {\r
+        chRet = GH3X2X_RET_RESOURCE_ERROR;\r
+    }\r
+    return chRet;\r
+}\r
+\r
+\r
+/**\r
+ * @fn     GS8 Gh3x2xDemoArrayCfgSwitch(GU8 uchArrayCfgIndex)\r
+ *\r
+ * @brief  array cfg switch (call by user)\r
+ *\r
+ * @attention   you should switch array cfg manually before calling Gh3x2xDemoStartSampling\r
+ *\r
+ * @param[in]   uchArrayCfgIndex    0: gh3x2x_reg_list0    1: gh3x2x_reg_list0 ...\r
+ * @param[out]  None\r
+ *\r
+ * @return  GH3X2X_RET_OK:switch application mode success\r
+ * @return  GH3X2X_RET_RESOURCE_ERROR:can't find corresponding reg config array\r
+ */\r
+GS8 Gh3x2xDemoArrayCfgSwitch(GU8 uchArrayCfgIndex)\r
+{\r
+    GS8  chRet = GH3X2X_RET_OK;\r
+\r
+    if(g_uchGh3x2xRegCfgArrIndex == uchArrayCfgIndex)\r
+    {\r
+        GH3X2X_INFO_LOG("Current cfg is already cfg%d, no need switch.\r\n",(int)uchArrayCfgIndex);\r
+    }\r
+    else if(uchArrayCfgIndex < __GH3X2X_CFG_LIST_MAX_NUM__)\r
+    {\r
+        Gh3x2xDemoSamplingControl(0xFFFFFFFF, UPROTOCOL_CMD_STOP);\r
+        #if __SUPPORT_HARD_RESET_CONFIG__\r
+        GH3X2X_HardReset();\r
+        #else\r
+        GH3X2X_SoftReset();\r
+        #endif   \r
+        Gh3x2x_BspDelayMs(15);  \r
+        #if __GH3X2X_CASCADE_EN__\r
+        GH3X2X_CascadeOperationSlaverChip();\r
+        GH3X2X_CascadeOperationMasterChip();\r
+        #endif\r
+\r
+        g_uchGh3x2xRegCfgArrIndex = uchArrayCfgIndex;\r
+        if (GH3X2X_RET_OK == GH3X2X_Init(g_stGh3x2xCfgListArr + uchArrayCfgIndex))\r
+        {\r
+            GH3X2X_INFO_LOG("cfg%d switch success !!!.\r\n",(int)uchArrayCfgIndex);\r
+        }\r
+        else\r
+        {\r
+            g_uchGh3x2xRegCfgArrIndex = DRV_LIB_REG_CFG_EMPTY;\r
+            chRet = GH3X2X_RET_RESOURCE_ERROR;\r
+            GH3X2X_INFO_LOG("Error ! cfg%d switch fail !!!\r\n",(int)uchArrayCfgIndex);\r
+        }\r
+        GH3X2X_EnterLowPowerMode();\r
+        #if __GH3X2X_CASCADE_EN__\r
+        GH3X2X_CascadeOperationSlaverChip();\r
+        GH3X2X_EnterLowPowerMode();\r
+        GH3X2X_CascadeOperationMasterChip();\r
+        #endif\r
+        \r
+    }\r
+    else\r
+    {\r
+        GH3X2X_INFO_LOG("Error! uchArrayCfgIndex(%d) is invalid !!!\r\n",(int)uchArrayCfgIndex);\r
+        chRet = GH3X2X_RET_RESOURCE_ERROR;\r
+    }\r
+    return chRet;\r
+}\r
+\r
+GU8 guchSlotEn = 0;\r
+\r
+void Gh3x2xSetCurrentSlotEnReg(GU32 unFuncMode)\r
+{\r
+    GU8 uchSlotEn = 0;\r
+\r
+    #if __SLOT_SEQUENCE_DYNAMIC_ADJUST_EN__\r
+    GU8  uchSlotSeq[8];\r
+    GU8  uchValidSlotNum = 0;\r
+    GU16 usStartReg;\r
+    GU8 uchSlotSrDiver[8];\r
+    GU8 uchSlotCfgHaveSortedFlag[8] = {0};\r
+    GU8 uchSlotCfgIndexFast2Low[8];\r
+    #endif\r
+    for(GU8 uchFunCnt = 0; uchFunCnt < GH3X2X_FUNC_OFFSET_MAX; uchFunCnt ++)\r
+    {\r
+        if(g_pstGh3x2xFrameInfo[uchFunCnt])\r
+        {\r
+            if(g_unDemoFuncMode & (((GU32)1)<< uchFunCnt))\r
+            {\r
+                uchSlotEn |= g_pstGh3x2xFrameInfo[uchFunCnt]->pstFunctionInfo->uchSlotBit;\r
+            }\r
+        }\r
+    }\r
+    #if __SLOT_SEQUENCE_DYNAMIC_ADJUST_EN__\r
+    for(GU8 uchSlotCnt = 0; uchSlotCnt < 8; uchSlotCnt ++)\r
+    {\r
+        //get diver for every slot cfg\r
+        uchSlotSrDiver[uchSlotCnt] = GH3x2xGetAgcReg(GH3X2X_AGC_REG_SR_MULIPLIPER, uchSlotCnt);\r
+    }\r
+    \r
+    //GH3X2X_INFO_LOG("%s : Slot cfg Sort fast to slow: \r\n", __FUNCTION__);\r
+    for(GU8 uchSlotCnt = 0; uchSlotCnt < 8; uchSlotCnt ++)\r
+    {\r
+        //find min diver\r
+        GU16 usCurrentMinDiver = 0xFFFF;\r
+        GU8 uchCurrentMinDiverCfgIndex = 0xFF;\r
+        for(GU8 uchSearchCnt = 0; uchSearchCnt < 8; uchSearchCnt ++)\r
+        {\r
+            if(0 == uchSlotCfgHaveSortedFlag[uchSearchCnt])\r
+            {\r
+                if(usCurrentMinDiver > uchSlotSrDiver[uchSearchCnt])\r
+                {\r
+                    usCurrentMinDiver = uchSlotSrDiver[uchSearchCnt];\r
+                    uchCurrentMinDiverCfgIndex = uchSearchCnt;\r
+                }\r
+            }\r
+        }\r
+        if(0xFF != uchCurrentMinDiverCfgIndex)\r
+        {\r
+            uchSlotCfgHaveSortedFlag[uchCurrentMinDiverCfgIndex] = 1;\r
+            uchSlotCfgIndexFast2Low[uchSlotCnt] = uchCurrentMinDiverCfgIndex;\r
+            \r
+            //GH3X2X_INFO_LOG("%d \r\n", uchCurrentMinDiverCfgIndex);\r
+        }\r
+    }\r
+    //GH3X2X_INFO_LOG("\r\n");\r
+\r
+\r
+    //find slot cfg from fastest to lowest\r
+    for(GU8 uchSlotCnt = 0; uchSlotCnt < 8; uchSlotCnt ++)\r
+    {\r
+        GU8 uchCurrentFastSlotCfgIndex = uchSlotCfgIndexFast2Low[uchSlotCnt];\r
+        for(GU8 uchSlotSearchCnt = 0; uchSlotSearchCnt < 8; uchSlotSearchCnt ++)\r
+        {\r
+            if(uchSlotEn&(1<<uchSlotSearchCnt))\r
+            {\r
+                if(uchSlotSearchCnt == uchCurrentFastSlotCfgIndex)\r
+                {\r
+                    uchSlotSeq[uchValidSlotNum] = uchSlotSearchCnt;\r
+                    uchValidSlotNum ++;\r
+                }\r
+            }\r
+        }\r
+    }\r
+    if(uchValidSlotNum < 8)\r
+    {\r
+        uchSlotSeq[uchValidSlotNum] = 8;\r
+        uchValidSlotNum ++;\r
+    }\r
+    else\r
+    {\r
+        uchValidSlotNum = 8;\r
+    }\r
+\r
+    \r
+    usStartReg = GH3X2X_ReadReg(0x0000);  //bak start reg\r
+    GH3X2X_WriteReg(0x0000,usStartReg&(0xFFFE));   //stop sample\r
+    //write 0x0100~0x0106 and 0x01EC\r
+    for(GU8 uchSlotCnt = 0; uchSlotCnt < uchValidSlotNum; uchSlotCnt ++)\r
+    {\r
+        if(0 == (uchSlotCnt&0x01)) //0,2,4,6\r
+        {\r
+            GH3X2X_WriteRegBitField(0x0100 + (uchSlotCnt&0xFE), 0,3, uchSlotSeq[uchSlotCnt]);\r
+        }\r
+        else  //1,3,5,7\r
+        {\r
+            GH3X2X_WriteRegBitField(0x0100 + (uchSlotCnt&0xFE), 8,11,  uchSlotSeq[uchSlotCnt]);\r
+        }\r
+        if(uchSlotSeq[uchSlotCnt] < 8)\r
+        {\r
+            GH3X2X_WriteReg(0x01EC + uchSlotCnt*2, g_usGh3x2xSlotTime[uchSlotSeq[uchSlotCnt]]);\r
+            //GH3X2X_INFO_LOG("uchSlotCnt = %d, uchSlotSeq = %d, slottime = %d\r\n",uchSlotCnt,uchSlotSeq[uchSlotCnt],g_usGh3x2xSlotTime[uchSlotSeq[uchSlotCnt]]);\r
+        }\r
+    }\r
+    GH3X2X_WriteReg(0x0000,usStartReg);   //recover sample reg\r
+    #endif\r
+    GH3X2X_SlotEnRegSet(uchSlotEn);\r
+\r
+    #if __SUPPORT_SOFT_AGC_CONFIG__\r
+    GU8 uchSlotEnChange = uchSlotEn ^ guchSlotEn;\r
+    GH3x2xNewAgcMeanInfoReset(uchSlotEnChange);\r
+    guchSlotEn = uchSlotEn;\r
+    #endif\r
+\r
+    #if __GH3X2X_CASCADE_EN__\r
+    if(GH3X2X_CascadeGetEcgEnFlag())\r
+    {\r
+        GH3X2X_EcgCascadeSlotEnRegSet(uchSlotEn);\r
+    }\r
+    #endif\r
+\r
+    \r
+    GH3X2X_INFO_LOG("Current uchSlotEn= 0x%x\r\n",uchSlotEn);\r
+}\r
+\r
+#define GH3X2X_ECG_CTRL_FLAG_START 1\r
+#define GH3X2X_ECG_CTRL_FLAG_STOP  2\r
+\r
+#define GH3X2X_HARD_ADT_CTRL_FLAG_START 1\r
+#define GH3X2X_HARD_ADT_CTRL_FLAG_STOP  2\r
+#if __SUPPORT_FUNCTION_SAMPLE_RATE_MODIFY__\r
+void Gh3x2xSampleRateUpdate(GU32 unFuncMode)\r
+{\r
+    GU16 usLastSampleRate[8] = {0};  // last sample rate for every slot\r
+    GU16 usTargetSampleRate[8] = {0};\r
+    GU8  uchHaveStopSample = 0;\r
+    GU16 usStartReg;\r
+\r
+\r
+    //read sample rate reg\r
+    for(GU8 uchSlotCnt = 0; uchSlotCnt < 8; uchSlotCnt ++)\r
+    {\r
+        usLastSampleRate[uchSlotCnt] = 32000/(GH3x2xReadReg(GH3X2X_SYS_SAMPLE_RATE_CTRL_REG_ADDR) + 1)/(GH3x2xGetAgcReg(GH3X2X_AGC_REG_SR_MULIPLIPER, uchSlotCnt) + 1);\r
+    }\r
+\r
+\r
+    \r
+    //get every slot target sample rate\r
+    for(GU8 uchFunctionCnt = 0; uchFunctionCnt < GH3X2X_FUNC_OFFSET_MAX; uchFunctionCnt++)\r
+    {\r
+        if((g_pstGh3x2xFrameInfo[uchFunctionCnt])&&(unFuncMode&((GU32)1<<uchFunctionCnt)))     //function is valid and opened\r
+        {\r
+            GU16 usTempTargetSampleRate = g_pstGh3x2xFrameInfo[uchFunctionCnt]->pstFunctionInfo->usSampleRateForUserSetting;\r
+            if(0 == usTempTargetSampleRate)\r
+            {\r
+                usTempTargetSampleRate = g_pstGh3x2xFrameInfo[uchFunctionCnt]->pstFunctionInfo->usSampleRate;\r
+            }\r
+            GU8 uchTempSlotBit = g_pstGh3x2xFrameInfo[uchFunctionCnt]->pstFunctionInfo->uchSlotBit;            \r
+            GH3X2X_INFO_LOG("[Gh3x2xSampleRateUpdate]FunctionId = 0x%X, slot bit = 0x%X,usSampleRateUser = %d\r\n",g_pstGh3x2xFrameInfo[uchFunctionCnt]->unFunctionID,uchTempSlotBit, usTempTargetSampleRate);\r
+            for(GU8 uchSlotCnt = 0; uchSlotCnt < 8; uchSlotCnt ++)\r
+            {\r
+                if(uchTempSlotBit&(1<<uchSlotCnt))\r
+                {\r
+                    if(usTempTargetSampleRate > usTargetSampleRate[uchSlotCnt])  \r
+                    {\r
+                        usTargetSampleRate[uchSlotCnt] = usTempTargetSampleRate;   //store faster sample rate\r
+                    }\r
+                }\r
+            }\r
+        }\r
+    }\r
+\r
+\r
+    //update sample rate registers\r
+    for(GU8 uchSlotCnt = 0; uchSlotCnt < 8; uchSlotCnt ++)\r
+    {\r
+        if((usTargetSampleRate[uchSlotCnt] != usLastSampleRate[uchSlotCnt])&&(0 != usTargetSampleRate[uchSlotCnt]))\r
+        {\r
+            if(0 == uchHaveStopSample)\r
+            {\r
+                usStartReg = GH3X2X_ReadReg(0x0000);  //bak start reg\r
+                GH3X2X_WriteReg(0x0000,usStartReg&(0xFFFE));   //stop sample\r
+                uchHaveStopSample = 1;\r
+            }\r
+            GH3x2xSetAgcReg(GH3X2X_AGC_REG_SR_MULIPLIPER, uchSlotCnt, (1000/usTargetSampleRate[uchSlotCnt]) - 1);\r
+            GH3X2X_INFO_LOG("[Gh3x2xSampleRateUpdate]Slot%d sample rate need change: Last = %d, Target = %d\r\n",uchSlotCnt, usLastSampleRate[uchSlotCnt], usTargetSampleRate[uchSlotCnt]);\r
+        }\r
+    }\r
+    if(uchHaveStopSample)\r
+    {\r
+        GH3X2X_WriteReg(0x0000,usStartReg);   //recover sample reg\r
+    }\r
+    \r
+\r
+\r
+    //update usSampleRate value,and down sample check\r
+    for(GU8 uchFunctionCnt = 0; uchFunctionCnt < GH3X2X_FUNC_OFFSET_MAX; uchFunctionCnt++)\r
+    {\r
+        GU16 usSlowestSlotSampleRate = 0xFFFF;\r
+        \r
+        if((g_pstGh3x2xFrameInfo[uchFunctionCnt])&&(unFuncMode&((GU32)1<<uchFunctionCnt)))     //function is valid and opened\r
+        {\r
+            GU8 uchTempSlotBit = g_pstGh3x2xFrameInfo[uchFunctionCnt]->pstFunctionInfo->uchSlotBit;\r
+            //update update usSampleRate value\r
+            if(g_pstGh3x2xFrameInfo[uchFunctionCnt]->pstFunctionInfo->usSampleRateForUserSetting)\r
+            {\r
+                g_pstGh3x2xFrameInfo[uchFunctionCnt]->pstFunctionInfo->usSampleRate = g_pstGh3x2xFrameInfo[uchFunctionCnt]->pstFunctionInfo->usSampleRateForUserSetting;\r
+            }\r
+            //get slowest slot in  function (target sample rate)\r
+            for(GU8 uchSlotCnt = 0; uchSlotCnt < 8; uchSlotCnt ++)\r
+            {\r
+                if(uchTempSlotBit&(1<<uchSlotCnt))\r
+                {\r
+                    if(usSlowestSlotSampleRate > usTargetSampleRate[uchSlotCnt])\r
+                    {\r
+                        usSlowestSlotSampleRate = usTargetSampleRate[uchSlotCnt];\r
+                    }\r
+                }\r
+            }\r
+            if(usSlowestSlotSampleRate > g_pstGh3x2xFrameInfo[uchFunctionCnt]->pstFunctionInfo->usSampleRate)   //need down sample\r
+            {\r
+                g_pstGh3x2xFrameInfo[uchFunctionCnt]->pstDownSampleInfo->uchDownSampleFactor = (usSlowestSlotSampleRate/g_pstGh3x2xFrameInfo[uchFunctionCnt]->pstFunctionInfo->usSampleRate) - 1;\r
+            }\r
+            else\r
+            {\r
+                g_pstGh3x2xFrameInfo[uchFunctionCnt]->pstDownSampleInfo->uchDownSampleFactor = 0;\r
+            }\r
+            g_pstGh3x2xFrameInfo[uchFunctionCnt]->pstDownSampleInfo->uchDownSampleCnt = 0;    \r
+            GH3X2X_INFO_LOG("[Gh3x2xSampleRateUpdate]Down sample: FunctionID = 0x%X,: SlowestSlotSR = %d, Factor = %d\r\n",g_pstGh3x2xFrameInfo[uchFunctionCnt]->unFunctionID, usSlowestSlotSampleRate, g_pstGh3x2xFrameInfo[uchFunctionCnt]->pstDownSampleInfo->uchDownSampleFactor);\r
+\r
+        }\r
+        \r
+    }\r
+    \r
+}\r
+#endif\r
+\r
+void GH3x2xMaserControlFunctionLog(GU32 unFuncMode, EMUprotocolParseCmdType emCmdType)\r
+{\r
+    if(UPROTOCOL_CMD_START == emCmdType)\r
+    {\r
+        GH3X2X_INFO_LOG("Master start function = 0x%x\r\n",unFuncMode);\r
+    }\r
+    else\r
+    {\r
+        GH3X2X_INFO_LOG("Master stop function = 0x%x\r\n",unFuncMode);\r
+    }\r
+}\r
+\r
+\r
+\r
+\r
+/**\r
+ * @fn     void Gh3x2xDemoSamplingControl(EMUprotocolParseCmdType emSwitch)\r
+ *\r
+ * @brief  Start/stop sampling of gh3x2x and sensor\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   unFuncMode      function that will be started or stopped\r
+ * @param[in]   emSwitch        stop/start sampling\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void Gh3x2xDemoSamplingControl(GU32 unFuncMode, EMUprotocolParseCmdType emSwitch)\r
+{\r
+\r
+    if ((GH3X2X_GetConfigFuncMode() & unFuncMode) != unFuncMode)\r
+    {\r
+        GH3X2X_INFO_LOG("[%s]:config has no target function!!!config function = 0x%08x,unFuncMode = 0x%08x\r\n", __FUNCTION__, GH3X2X_GetConfigFuncMode(),unFuncMode);\r
+        unFuncMode = (GH3X2X_GetConfigFuncMode() & unFuncMode);\r
+    }\r
+    if(unFuncMode == 0)\r
+    {\r
+        return;\r
+    }\r
+    #if (__FUNC_TYPE_ECG_ENABLE__)\r
+    GU8 uchEcgCtrlFlag = 0;\r
+    #endif\r
+    #if __GS_NONSYNC_READ_EN__\r
+    GU16 usTempFunction;\r
+    #endif\r
+    #if __FUNC_TYPE_ECG_ENABLE__\r
+    GU32 unLastDemoFuncMode = g_unDemoFuncMode;\r
+    #endif\r
+\r
+    #if !(__GH3X2X_CASCADE_EN__)\r
+    #else\r
+    if (GH3X2X_CascadeGetEcgEnFlag())\r
+    {\r
+        GH3X2X_CascadeOperationSlaverChip();\r
+        GH3X2X_CascadeOperationMasterChip();\r
+\r
+    }\r
+    else\r
+    {\r
+    }\r
+    #endif\r
+    for(GU8 uchFunCnt = 0; uchFunCnt < GH3X2X_FUNC_OFFSET_MAX; uchFunCnt ++)\r
+    {\r
+        if(g_pstGh3x2xFrameInfo[uchFunCnt])\r
+        {\r
+            if(unFuncMode & (((GU32)1)<< uchFunCnt))\r
+            {\r
+                if((UPROTOCOL_CMD_START == emSwitch)&&((g_unDemoFuncMode & (((GU32)1)<< uchFunCnt)) != (((GU32)1)<< uchFunCnt)))\r
+                {\r
+                    #if (__SUPPORT_HARD_ADT_CONFIG__)\r
+                    if(GH3X2X_FUNC_OFFSET_ADT == uchFunCnt)\r
+                    {\r
+                        GH3X2X_ResetHardAdt();  //reset hard adt module before every ADT function openning \r
+                    }\r
+                    #endif\r
+                    GH3X2X_FunctionStart(g_pstGh3x2xFrameInfo[uchFunCnt]);\r
+                    #if __FUNC_TYPE_ECG_ENABLE__\r
+                        if(GH3X2X_FUNC_OFFSET_ECG == uchFunCnt)\r
+                        {\r
+                            uchEcgCtrlFlag = GH3X2X_ECG_CTRL_FLAG_START;\r
+                        }\r
+                    #endif\r
+                    }\r
+                else if ((UPROTOCOL_CMD_STOP == emSwitch)&&((g_unDemoFuncMode & (((GU32)1)<< uchFunCnt)) == (((GU32)1)<< uchFunCnt)))\r
+                {\r
+                    if(GH3X2X_FUNC_OFFSET_ADT == uchFunCnt)\r
+                    {\r
+                    #if (__SUPPORT_HARD_ADT_CONFIG__)\r
+                        GH3X2X_FunctionStop(g_pstGh3x2xFrameInfo[uchFunCnt]);\r
+                        #if (0 == __HARD_ADT_ALGO_CHECK_EN__)\r
+                        g_uchWearDetectStatus = WEAR_DETECT_WEAR_ON;\r
+                        GH3X2X_WearDetectSwitchTo(WEAR_DETECT_WEAR_ON,WEAR_DETECT_FORCE_SWITCH);\r
+                                               #endif\r
+                    #endif\r
+                    #if (__SUPPORT_PROTOCOL_ANALYZE__)\r
+                        Gh3x2xDemoReportEvent(WEAR_DETECT_WEAR_OFF,0);\r
+                    #endif\r
+                    }\r
+                    else\r
+                    {\r
+                        GH3X2X_FunctionStop(g_pstGh3x2xFrameInfo[uchFunCnt]);\r
+                    #if __FUNC_TYPE_ECG_ENABLE__\r
+                        if(GH3X2X_FUNC_OFFSET_ECG == uchFunCnt)\r
+                        {\r
+                            uchEcgCtrlFlag = GH3X2X_ECG_CTRL_FLAG_STOP;\r
+                        }\r
+                    #endif\r
+                    }\r
+                }\r
+            }\r
+        }\r
+    }\r
+\r
+    /* Enable gsensor sampling */\r
+    if (UPROTOCOL_CMD_START == emSwitch)\r
+    {\r
+#if (__DRIVER_LIB_MODE__ == __DRV_LIB_WITH_ALGO__)\r
+        GH3X2X_TimestampSyncPpgInit(unFuncMode);\r
+#endif\r
+        if (GH3X2X_GetGsensorEnableFlag() && (GH3X2X_NO_FUNCTION == g_unDemoFuncMode))\r
+        {\r
+            hal_gsensor_start_cache_data();\r
+        }\r
+#if (__CAP_ENABLE__)\r
+        if (GH3X2X_GetCapEnableFlag() && ((unFuncMode & (GH3X2X_FUNCTION_SOFT_ADT_GREEN | GH3X2X_FUNCTION_SOFT_ADT_IR)) != GH3X2X_NO_FUNCTION))\r
+        {\r
+            GH3x2xReadCapFromFlash();\r
+        }\r
+        if (GH3X2X_GetCapEnableFlag() && (GH3X2X_NO_FUNCTION == g_unDemoFuncMode))\r
+        {\r
+            hal_cap_start_cache_data();\r
+        }\r
+#endif\r
+#if (__TEMP_ENABLE__)\r
+        if (GH3X2X_GetTempEnableFlag() && (GH3X2X_NO_FUNCTION == g_unDemoFuncMode))\r
+        {\r
+            hal_temp_start_cache_data();\r
+        }\r
+#endif\r
+        g_unDemoFuncMode |= unFuncMode;\r
+    }\r
+    else\r
+    {\r
+        g_unDemoFuncMode &= ~unFuncMode;\r
+        if (GH3X2X_GetGsensorEnableFlag()  && (GH3X2X_NO_FUNCTION == g_unDemoFuncMode))\r
+        {\r
+            //hal_gsensor_stop_cache_data();\r
+        }\r
+#if (__CAP_ENABLE__)\r
+        if (GH3X2X_GetCapEnableFlag() && (GH3X2X_NO_FUNCTION == g_unDemoFuncMode))\r
+        {\r
+            if((unFuncMode & (GH3X2X_FUNCTION_SOFT_ADT_GREEN | GH3X2X_FUNCTION_SOFT_ADT_IR)) != GH3X2X_NO_FUNCTION)\r
+            {\r
+                GH3x2xWriteCapToFlash();\r
+            }\r
+            hal_cap_stop_cache_data();\r
+        }\r
+#endif\r
+#if (__TEMP_ENABLE__)\r
+        if (GH3X2X_GetTempEnableFlag() && (GH3X2X_NO_FUNCTION == g_unDemoFuncMode))\r
+        {\r
+            hal_temp_stop_cache_data();\r
+        }\r
+#endif\r
+        GH3X2X_SetSoftEvent(GH3X2X_SOFT_EVENT_NEED_FORCE_READ_FIFO);\r
+    }\r
+    \r
+#if __FUNC_TYPE_ECG_ENABLE__\r
+            if(unLastDemoFuncMode&(GH3X2X_FUNCTION_ADT|GH3X2X_FUNCTION_LEAD_DET))  //have adt/lead function before change\r
+            {\r
+                if(0 == (g_unDemoFuncMode&(GH3X2X_FUNCTION_ADT|GH3X2X_FUNCTION_LEAD_DET))) //have no adt/lead function after change\r
+                {\r
+                    GH3X2X_LeadDetEnInHardAdt(0);\r
+                }\r
+            }\r
+            else  //have no adt/lead function before change\r
+            {\r
+                if((g_unDemoFuncMode&(GH3X2X_FUNCTION_ADT|GH3X2X_FUNCTION_LEAD_DET))) //have adt/lead function after change\r
+                {\r
+                    GH3X2X_LeadDetEnInHardAdt(1);\r
+                }\r
+            }\r
+#endif\r
+\r
+#if __ADT_ONLY_PARTICULAR_WM_CONFIG__\r
+    if(GH3X2X_FUNCTION_ADT == g_unDemoFuncMode) // only ADT function is opening\r
+    {\r
+        g_usCurrentConfigListFifoWmBak = GH3X2X_ReadReg(0x000A);     //bak current reg\r
+        GH3X2X_WriteReg(0x000A, __ADT_ONLY_PARTICULAR_WM_CONFIG__);  //set particular watermark for ADT only\r
+        g_usCurrentFiFoWaterLine = __ADT_ONLY_PARTICULAR_WM_CONFIG__;\r
+        GH3X2X_INFO_LOG("set particular watermark for ADT only. value = %d.\r\n",(int)__ADT_ONLY_PARTICULAR_WM_CONFIG__);\r
+    }\r
+    else\r
+    {\r
+        if(g_usCurrentConfigListFifoWmBak)  // if bak value is exist\r
+        {\r
+            GH3X2X_WriteReg(0x000A, g_usCurrentConfigListFifoWmBak);  // recover the watermark\r
+            g_usCurrentFiFoWaterLine = g_usCurrentConfigListFifoWmBak;\r
+            g_usCurrentConfigListFifoWmBak = 0;                        //clear bak value\r
+            GH3X2X_INFO_LOG("recover watermark. value = %d.\r\n",(int)g_usCurrentConfigListFifoWmBak);\r
+        }\r
+    }\r
+    GH3X2X_SetSoftEvent(GH3X2X_SOFT_EVENT_NEED_FORCE_READ_FIFO);  //need force read fifo after setting watermark\r
+#endif\r
+\r
+\r
+\r
+\r
+#if __SUPPORT_FUNCTION_SAMPLE_RATE_MODIFY__&& (!__SUPPORT_PPG_DOWNSAMP__) &&(!__SUPPORT_ECG_DOWNSAMP__)\r
+    Gh3x2xSampleRateUpdate(g_unDemoFuncMode);\r
+#endif\r
+    Gh3x2xSetCurrentSlotEnReg(g_unDemoFuncMode);\r
+#if (GH3X2X_FIFO_MONITOR_EN&(__GH3X2X_INTERFACE__ == __GH3X2X_INTERFACE_I2C__))\r
+    Gh3x2xFifoMonitorInit(&g_stFifoMonitorInfo);\r
+#endif\r
+\r
+    GH3X2X_INFO_LOG("Current g_unDemoFuncMode= 0x%x\r\n",g_unDemoFuncMode);\r
+#if (__FUNC_TYPE_ECG_ENABLE__)\r
+    if(GH3X2X_ECG_CTRL_FLAG_START == uchEcgCtrlFlag)\r
+    {\r
+        GH3X2X_EcgSampleHookHandle(ECG_SAMPLE_EVENT_TYPE_SLOT,g_pstGh3x2xFrameInfo[GH3X2X_FUNC_OFFSET_ECG]->pstFunctionInfo->uchSlotBit);\r
+    }\r
+    else if(GH3X2X_ECG_CTRL_FLAG_STOP == uchEcgCtrlFlag)\r
+    {\r
+        GH3X2X_EcgSampleHookHandle(ECG_SAMPLE_EVENT_TYPE_SLOT,~(g_pstGh3x2xFrameInfo[GH3X2X_FUNC_OFFSET_ECG]->pstFunctionInfo->uchSlotBit));\r
+    }\r
+#endif\r
+\r
+#if __GS_NONSYNC_READ_EN__\r
+    usTempFunction = Gh3x2xGetCurrentRefFunction();\r
+    if(usTempFunction != g_usGsenorRefFunction)\r
+    {\r
+        g_usGsenorRefFunction = usTempFunction;\r
+        Gh3x2xNonSyncGsensorInit();\r
+    }\r
+#endif\r
+\r
+    if(GH3X2X_GetSoftEvent()&&(0 == g_uchGh3x2xInterruptProNotFinishFlag))   //avoid nesting\r
+    {\r
+        Gh3x2xDemoInterruptProcess();\r
+    }\r
+\r
+#if !(__GH3X2X_CASCADE_EN__)\r
+    GH3X2X_EnterLowPowerMode();\r
+#else\r
+    if (GH3X2X_CascadeGetEcgEnFlag())\r
+    {\r
+        GH3X2X_EnterLowPowerMode();\r
+        GH3X2X_CascadeOperationSlaverChip();\r
+        GH3X2X_EnterLowPowerMode();\r
+        GH3X2X_CascadeOperationMasterChip();\r
+\r
+    }\r
+    else\r
+    {\r
+        GH3X2X_EnterLowPowerMode();\r
+    }\r
+#endif\r
+}\r
+\r
+\r
+\r
+\r
+void Gh3x2xFunctionSlotBitInit(void)\r
+{\r
+    for(GU8 uchFunctionCnt = 0; uchFunctionCnt < GH3X2X_FUNC_OFFSET_MAX; uchFunctionCnt++)\r
+    {\r
+        if(g_pstGh3x2xFrameInfo[uchFunctionCnt])\r
+        {\r
+            GH3x2xCalFunctionSlotBit(g_pstGh3x2xFrameInfo[uchFunctionCnt]);\r
+        }\r
+    }\r
+}\r
+\r
+\r
+\r
+void Gh3x2xEnterCascadeMode(void)\r
+{\r
+#if __GH3X2X_CASCADE_EN__\r
+    Gh3x2xDemoStopSampling(0xFFFFFFFF);   //stop all function\r
+#if __USER_DYNAMIC_DRV_BUF_EN__\r
+    if(0 == g_puchGh3x2xReadRawdataBufferSlaveChip)\r
+    {\r
+        g_puchGh3x2xReadRawdataBufferSlaveChip = Gh3x2xMallocUser(__GH3X2X_RAWDATA_BUFFER_SIZE__);\r
+    }\r
+    if(0 == Gh3x2xDemoMemCheckValid())\r
+    {\r
+        while(1);\r
+    }\r
+#endif\r
+    GH3X2X_CascadeSetEcgEnFlag(1);\r
+    GH3X2X_CascadeOperationSlaverChip();\r
+    GH3X2X_CascadeOperationMasterChip();\r
+\r
+    g_uchGh3x2xRegCfgArrIndex = 2;\r
+    if (GH3X2X_RET_OK != GH3X2X_Init(g_stGh3x2xCfgListArr+2))   //load ecg master and slave cfg\r
+    {\r
+        g_uchGh3x2xRegCfgArrIndex = DRV_LIB_REG_CFG_EMPTY;\r
+    }\r
+    GH3X2X_EnterLowPowerMode();\r
+    GH3X2X_CascadeOperationSlaverChip();\r
+    GH3X2X_EnterLowPowerMode();\r
+    GH3X2X_CascadeOperationMasterChip();\r
+#endif\r
+}\r
+void Gh3x2xExitCascadeMode(void)\r
+{\r
+#if __GH3X2X_CASCADE_EN__\r
+    Gh3x2xDemoStopSampling(0xFFFFFFFF);   //stop all function\r
+    GH3X2X_CascadeSetEcgEnFlag(0);\r
+    if(0 == GH3X2X_GetSingleChipModeEnableFlag())\r
+    {\r
+        GH3X2X_CascadeOperationSlaverChip();\r
+        GH3X2X_CascadeOperationMasterChip();\r
+    }\r
+\r
+    g_uchGh3x2xRegCfgArrIndex = 2;\r
+    if (GH3X2X_RET_OK != GH3X2X_Init(g_stGh3x2xCfgListArr+0))\r
+    {\r
+        g_uchGh3x2xRegCfgArrIndex = DRV_LIB_REG_CFG_EMPTY;\r
+    }\r
+    GH3X2X_EnterLowPowerMode();\r
+    if(0 == GH3X2X_GetSingleChipModeEnableFlag())\r
+    {\r
+        GH3X2X_CascadeOperationSlaverChip();\r
+        GH3X2X_EnterLowPowerMode();\r
+        GH3X2X_CascadeOperationMasterChip();\r
+    }\r
+#if __USER_DYNAMIC_DRV_BUF_EN__\r
+    if(g_puchGh3x2xReadRawdataBufferSlaveChip)\r
+    {\r
+        Gh3x2xFreeUser(g_puchGh3x2xReadRawdataBufferSlaveChip);\r
+        g_puchGh3x2xReadRawdataBufferSlaveChip = 0;\r
+    }\r
+#endif\r
+#endif\r
+}\r
+\r
+\r
+\r
+\r
+/**\r
+ * @fn     void Gh3x2xDemoStartSampling()\r
+ *\r
+ * @brief  Start sampling of GH3x2x\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   unFuncMode      function mode that will start\r
+ *                              GH3X2X_FUNCTION_ADT/GH3X2X_FUNCTION_HR/GH3X2X_FUNCTION_SPO2/GH3X2X_FUNCTION_ECG and etc.\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void Gh3x2xDemoStartSamplingInner(GU32 unFuncMode, GU8 uchSwitchEnable)\r
+{\r
+               GH3X2X_INFO_LOG("[Gh3x2xDemoStartSampling] unFuncMode = 0x%X\r\n",(int)unFuncMode);\r
+    GU32 unFuncModeTemp1 = GH3X2X_NO_FUNCTION;\r
+    GU32 unFuncModeTemp2 = GH3X2X_NO_FUNCTION;\r
+    GU32  unTargetFunMode;\r
+    GU8  uchIndex = 0;\r
+    GS8  chRet = GH3X2X_RET_OK;\r
+#if __FUNC_TYPE_ECG_ENABLE__\r
+    GU8 uchNeedSwitchToEcgCfg = 0;\r
+#endif\r
+#if __FUNC_TYPE_ECG_ENABLE__\r
+    if(unFuncMode&GH3X2X_FUNCTION_LEAD_DET)\r
+    {\r
+        uchNeedSwitchToEcgCfg = 1;\r
+    }\r
+#endif\r
+\r
+#if (__SUPPORT_HARD_ADT_CONFIG__)\r
+    if (GH3X2X_FUNCTION_ADT == unFuncMode)\r
+    {\r
+        unFuncModeTemp2 = unFuncMode;\r
+    }\r
+    else\r
+    {\r
+        unFuncModeTemp2 = unFuncMode & (~GH3X2X_FUNCTION_ADT);\r
+    }\r
+#else\r
+    unFuncModeTemp2 = unFuncMode;\r
+#endif\r
+\r
+    unTargetFunMode = unFuncMode;\r
+#if __FUNC_TYPE_ECG_ENABLE__\r
+    if(uchNeedSwitchToEcgCfg)\r
+    {\r
+        unFuncModeTemp2 |= GH3X2X_FUNCTION_ECG;  //add ecg function to demand function\r
+        unFuncModeTemp2 &= (~GH3X2X_FUNCTION_LEAD_DET);\r
+        unTargetFunMode |= GH3X2X_FUNCTION_ECG;\r
+        unTargetFunMode &= (~GH3X2X_FUNCTION_LEAD_DET);\r
+    }\r
+#endif\r
+\r
+    //decode functions in current reg config array\r
+    \r
+    unFuncModeTemp1 = GhDrvConfigManagerGetCurFunctionSupprort();  // get current function combination supported\r
+    //if this function not exist in current reg cfg array,need switch reg cfg array\r
+    if (\r
+        ((unFuncModeTemp2 & unFuncModeTemp1) != unFuncModeTemp2)\r
+        #if __GH3X2X_CASCADE_EN__\r
+        ||(0 == Gh3x2xCheckCfgValidForCascade(g_uchGh3x2xRegCfgArrIndex))\r
+        #endif\r
+        )\r
+    {\r
+        if (uchSwitchEnable)\r
+        {\r
+            GH3X2X_INFO_LOG("Cfg Error:Reg cfg file not exist!!!APP mode:0x%x\r\n",unFuncMode);\r
+            GH3X2X_INFO_LOG("Please check cfg switched manually is correct or not !!!\r\n");\r
+            while(1);\r
+        }\r
+        else\r
+        {\r
+            chRet = GH3x2xDemoSearchCfgListByFunc(&uchIndex, unTargetFunMode, GH3X2X_FUNCTION_ADT);\r
+            if (GH3X2X_RET_OK == chRet)\r
+            {\r
+                #if (__SUPPORT_HARD_ADT_CONFIG__)\r
+                GU32 unDemoFuncModeBeforeReset = g_unDemoFuncMode;\r
+                EMWearDetectType  uchWearDetectStatusBeforeReset = g_uchWearDetectStatus;\r
+                GH3X2X_INFO_LOG("unDemoFuncModeBeforeReset = %d\r\n",unDemoFuncModeBeforeReset);\r
+                #endif\r
+                Gh3x2xDemoSamplingControl(0xFFFFFFFF, UPROTOCOL_CMD_STOP);\r
+\r
+            #if __SUPPORT_HARD_RESET_CONFIG__\r
+                GH3X2X_HardReset();\r
+            #else\r
+                GH3X2X_SoftReset();\r
+            #endif   \r
+\r
+                Gh3x2x_BspDelayMs(15);\r
+            #if !(__GH3X2X_CASCADE_EN__)\r
+            #else\r
+                GH3X2X_CascadeOperationSlaverChip();\r
+                GH3X2X_CascadeOperationMasterChip();\r
+            #endif\r
+                g_uchGh3x2xRegCfgArrIndex = uchIndex;\r
+                if (GH3X2X_RET_OK != GH3X2X_Init(g_stGh3x2xCfgListArr+uchIndex))\r
+                {\r
+                    g_uchGh3x2xRegCfgArrIndex = DRV_LIB_REG_CFG_EMPTY;\r
+                }\r
+\r
+                Gh3x2xFunctionCtrlModuleInit();\r
+\r
+            #if (__SUPPORT_HARD_ADT_CONFIG__)\r
+                //if ADT is running,recover ADT status\r
+                GH3X2X_INFO_LOG("temp unDemoFuncModeBeforeReset = %d\r\n",(unDemoFuncModeBeforeReset & GH3X2X_FUNCTION_ADT));\r
+                if (GH3X2X_FUNCTION_ADT == (unDemoFuncModeBeforeReset & GH3X2X_FUNCTION_ADT))\r
+                {\r
+                    GH3X2X_INFO_LOG("g_uchWearDetectStatus = %d\r\n",g_uchWearDetectStatus);\r
+                    g_uchWearDetectStatus = uchWearDetectStatusBeforeReset;\r
+                    unFuncMode |= GH3X2X_FUNCTION_ADT;\r
+                    GH3X2X_FunctionStart(g_pstGh3x2xFrameInfo[GH3X2X_FUNC_OFFSET_ADT]);\r
+\r
+                    #if (0 == __HARD_ADT_ALGO_CHECK_EN__)\r
+                    if(WEAR_DETECT_WEAR_OFF == g_uchWearDetectStatus)\r
+                    {\r
+                        g_uchWearDetectStatus = WEAR_DETECT_WEAR_OFF;\r
+                        GH3X2X_WearDetectSwitchTo(WEAR_DETECT_WEAR_OFF,WEAR_DETECT_FORCE_SWITCH);\r
+                    }\r
+                    #endif\r
+                }\r
+            #endif\r
+\r
+                GH3X2X_EnterLowPowerMode();\r
+                #if __GH3X2X_CASCADE_EN__           //need enter low power mode after chip reset(master and slave chip may all be reset)\r
+                GH3X2X_CascadeOperationSlaverChip();\r
+                GH3X2X_EnterLowPowerMode();\r
+                GH3X2X_CascadeOperationMasterChip();\r
+                #endif\r
+            }\r
+            else\r
+            {\r
+                GH3X2X_INFO_LOG("APP Mode Switch Error:Reg cfg file not exist!!!APP mode:0x%x\r\n",unFuncMode);\r
+            }\r
+        }\r
+    }\r
+\r
+    //function slot bit init\r
+    Gh3x2xFunctionSlotBitInit();\r
+\r
+#if (__SUPPORT_ENGINEERING_MODE__)\r
+    if(1 == g_uchEngineeringModeStatus)\r
+    {\r
+        #if (__GH3X2X_CASCADE_EN__)\r
+        if (GH3X2X_CascadeGetEcgEnFlag())\r
+        {\r
+            \r
+            GH3X2X_CascadeOperationSlaverChip();\r
+            GH3X2X_CascadeOperationMasterChip();\r
+        }\r
+        #endif\r
+        GH3x2x_ChangeSampleParmForEngineeringMode(g_pstGh3x2xFrameInfo, unFuncMode, g_pstSampleParaGroup, g_uchEngineeringModeSampleParaGroupNum);\r
+        GH3X2X_EnterLowPowerMode();\r
+        #if (__GH3X2X_CASCADE_EN__)\r
+        if (GH3X2X_CascadeGetEcgEnFlag())\r
+        {\r
+            \r
+            GH3X2X_CascadeOperationSlaverChip();\r
+            GH3X2X_EnterLowPowerMode();\r
+            GH3X2X_CascadeOperationMasterChip();\r
+        }\r
+        #endif\r
+    }\r
+#endif\r
+    Gh3x2xDemoSamplingControl(unFuncMode, UPROTOCOL_CMD_START);\r
+}\r
+\r
+\r
+\r
+\r
+void Gh3x2xDemoStartAlgoInner(GU32 unFuncMode)\r
+{\r
+#if (__DRIVER_LIB_MODE__ == __DRV_LIB_WITH_ALGO__)\r
+    if(0 == GH3x2x_GetChipResetRecoveringFlag())\r
+    {\r
+        GH3X2X_AlgoInit(unFuncMode);\r
+        #if __GH3X2X_MEM_POOL_CHECK_EN__\r
+            Gh3x2xUpdataMemPollChkSumAfterAlgoCal();\r
+        #endif\r
+    }\r
+#endif\r
+\r
+#if __GH_MSG_WITH_ALGO_LAYER_EN__\r
+    if(0 == GH3x2x_GetChipResetRecoveringFlag())\r
+    {\r
+        GH3X2X_SEND_MSG_ALGO_START(unFuncMode);\r
+       \r
+    }\r
+#endif\r
+}\r
+\r
+\r
+/**\r
+ * @fn     void Gh3x2xDemoStartSampling()\r
+ *\r
+ * @brief  Start sampling of GH3x2x\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   unFuncMode      function mode that will start\r
+ *                              GH3X2X_FUNCTION_ADT/GH3X2X_FUNCTION_HR/GH3X2X_FUNCTION_SPO2/GH3X2X_FUNCTION_ECG and etc.\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void Gh3x2xDemoStartSampling(GU32 unFuncMode)\r
+{\r
+    Gh3x2xDemoStartSamplingInner(unFuncMode, 0);\r
+    Gh3x2xDemoStartAlgoInner(unFuncMode);\r
+}\r
+\r
+/**\r
+ * @fn     void Gh3x2xDemoStartSamplingWithCfgSwitch(GU32 unFuncMode, GU8 uchArrayCfgIndex)\r
+ *\r
+ * @brief  Start sampling of GH3x2x\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   unFuncMode      function mode that will start\r
+ *                              GH3X2X_FUNCTION_ADT/GH3X2X_FUNCTION_HR/GH3X2X_FUNCTION_SPO2/GH3X2X_FUNCTION_ECG and etc.\r
+ * @param[in]   uchArrayCfgIndex      cfg id\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void Gh3x2xDemoStartSamplingWithCfgSwitch(GU32 unFuncMode, GU8 uchArrayCfgIndex)\r
+{\r
+    if (uchArrayCfgIndex == DRV_LIB_REG_CFG_EMPTY)\r
+    {\r
+        GH3X2X_INFO_LOG("[%s]:Array None!!!\r\n", __FUNCTION__);\r
+    }\r
+    Gh3x2xDemoArrayCfgSwitch(uchArrayCfgIndex);\r
+    Gh3x2xDemoStartSamplingInner(unFuncMode, 1);\r
+    Gh3x2xDemoStartAlgoInner(unFuncMode);\r
+}\r
+\r
+\r
+\r
+\r
+\r
+#if (__SUPPORT_ENGINEERING_MODE__)\r
+\r
+/**\r
+ * @fn     void Gh3x2xDemoStartSamplingForEngineeringMode()\r
+ *\r
+ * @brief  Start sampling of GH3x2x for engineering mode\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   unFuncMode      function mode that will start\r
+ *                              GH3X2X_FUNCTION_ADT/GH3X2X_FUNCTION_HR/GH3X2X_FUNCTION_SPO2/GH3X2X_FUNCTION_ECG and etc.\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void Gh3x2xDemoStartSamplingForEngineeringMode(GU32 unFuncMode, GU8 uchArrayCfgIndex, STGh3x2xEngineeringModeSampleParam *pstSampleParaGroup , GU8 uchSampleParaGroupNum)\r
+{\r
+    Gh3x2xDemoArrayCfgSwitch(uchArrayCfgIndex);\r
+    g_pstSampleParaGroup = pstSampleParaGroup;\r
+    g_uchEngineeringModeSampleParaGroupNum = uchSampleParaGroupNum;\r
+    g_uchEngineeringModeStatus = 1;\r
+    Gh3x2xDemoStartSamplingInner(unFuncMode, 1);\r
+}\r
+#else\r
+void Gh3x2xDemoStartSamplingForEngineeringMode(GU32 unFuncMode, GU8 uchArrayCfgIndex, STGh3x2xEngineeringModeSampleParam *pstSampleParaGroup , GU8 uchSampleParaGroupNum){}\r
+#endif\r
+\r
+\r
+\r
+/**\r
+ * @fn     void Gh3x2xDemoStopSampling(GU32 unFuncMode)\r
+ *\r
+ * @brief  Stop sampling of GH3x2x\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   unFuncMode      function mode that will start\r
+ *                              GH3X2X_FUNCTION_ADT/GH3X2X_FUNCTION_HR/GH3X2X_FUNCTION_SPO2/GH3X2X_FUNCTION_ECG and etc.\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void Gh3x2xDemoStopSamplingInner(GU32 unFuncMode)\r
+{\r
+    GH3X2X_INFO_LOG("[Gh3x2xDemoStopSampling] unFuncMode = 0x%X\r\n",(int)unFuncMode);\r
+    Gh3x2xDemoSamplingControl(unFuncMode, UPROTOCOL_CMD_STOP);\r
+#if (__RESET_AGCINFO_BEFORE_SAMPLE__ && __SUPPORT_SOFT_AGC_CONFIG__)\r
+    if ((g_unDemoFuncMode & (~GH3X2X_FUNCTION_ADT)) == 0)\r
+    {\r
+        Gh3x2xDemoHardConfigReset(g_stGh3x2xCfgListArr + g_uchGh3x2xRegCfgArrIndex);\r
+    }\r
+#endif\r
+}\r
+\r
+\r
+void Gh3x2xDemoStopAlgoInner(GU32 unFuncMode)\r
+{\r
+#if (__DRIVER_LIB_MODE__ == __DRV_LIB_WITH_ALGO__)\r
+    if(0 == GH3x2x_GetChipResetRecoveringFlag())\r
+    {\r
+        GH3X2X_AlgoDeinit(unFuncMode);\r
+    }\r
+#endif\r
+\r
+#if __GH_MSG_WITH_ALGO_LAYER_EN__\r
+    if(0 == GH3x2x_GetChipResetRecoveringFlag())\r
+    {\r
+        GH3X2X_SEND_MSG_ALGO_STOP(unFuncMode);\r
+    }\r
+#endif\r
+}\r
+\r
+\r
+\r
+\r
+void Gh3x2xDemoStopSampling(GU32 unFuncMode)\r
+{\r
+    Gh3x2xDemoStopSamplingInner(unFuncMode);\r
+    Gh3x2xDemoStopAlgoInner(unFuncMode);\r
+}\r
+\r
+\r
+#if 0\r
+void GH3X2X_RedetectWearOn(void)\r
+{\r
+    if (g_uchWearDetectStatus == WEAR_DETECT_WEAR_OFF)   \r
+    {\r
+        GU16 usGotEvent = 0;\r
+        GH3X2X_INFO_LOG("[%s]switch to dectecting wear on\r\n", __FUNCTION__);\r
+        usGotEvent |= GH3X2X_IRQ_MSK_WEAR_OFF_BIT;\r
+        Gh3x2xDemoWearEventProcess(&usGotEvent,WEAR_DETECT_FORCE_SWITCH);\r
+\r
+        #if __HARD_ADT_ALGO_CHECK_EN__\r
+        GH3X2X_INFO_LOG("[%s]reset adt algo.\r\n", __FUNCTION__);\r
+        Gh3x2xDemoStopAlgoInner(GH3X2X_FUNCTION_ADT);\r
+        Gh3x2xDemoStartAlgoInner(GH3X2X_FUNCTION_ADT);\r
+        #endif\r
+        \r
+        \r
+    }\r
+                    \r
+}\r
+#endif\r
+\r
+\r
+\r
+#if (__SUPPORT_ENGINEERING_MODE__)\r
+\r
+/**\r
+ * @fn     void Gh3x2xDemoStopSamplingForEngineeringMode(void)\r
+ *\r
+ * @brief  Stop sampling of GH3x2x for engineering mode\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void Gh3x2xDemoStopSamplingForEngineeringMode(void)\r
+{\r
+    Gh3x2xDemoStopSamplingInner(g_unDemoFuncMode);\r
+\r
+    Gh3x2xDemoSamplingControl(0xFFFFFFFF, UPROTOCOL_CMD_STOP);\r
+    \r
+    #if __SUPPORT_HARD_RESET_CONFIG__\r
+    GH3X2X_HardReset();\r
+    #else\r
+    GH3X2X_SoftReset();\r
+    #endif   \r
+\r
+    Gh3x2x_BspDelayMs(15);\r
+    #if __GH3X2X_CASCADE_EN__\r
+    GH3X2X_CascadeOperationSlaverChip();\r
+    GH3X2X_CascadeOperationMasterChip();\r
+    #endif\r
+    g_uchGh3x2xRegCfgArrIndex = 0;\r
+    if (GH3X2X_RET_OK != GH3X2X_Init(&g_stGh3x2xCfgListArr[0]))\r
+    {\r
+        g_uchGh3x2xRegCfgArrIndex = DRV_LIB_REG_CFG_EMPTY;\r
+    }\r
+    \r
+    GH3X2X_EnterLowPowerMode();\r
+    #if __GH3X2X_CASCADE_EN__\r
+    GH3X2X_CascadeOperationSlaverChip();\r
+    GH3X2X_EnterLowPowerMode();\r
+    GH3X2X_CascadeOperationMasterChip();\r
+    #endif\r
+\r
+    Gh3x2xFunctionCtrlModuleInit();\r
+\r
+    g_uchEngineeringModeStatus = 0;\r
+}\r
+#endif\r
+\r
+\r
+/**\r
+ * @fn     void Gh3x2xDemoMoveDetectTimerHandler(GU32 unTimeIntervalMs)\r
+ *\r
+ * @brief  Move detect timer handler callback\r
+ *\r
+ * @attention   if use adt with confirm mode,must call this function to detect movement\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void Gh3x2xDemoMoveDetectTimerHandler(GU32 unTimeIntervalMs)\r
+{\r
+    GH3X2X_INFO_LOG("Gh3x2xDemoMoveDetectTimerHandler.\r\n");\r
+    #if (__GSENSOE_MOVE_DETECT_SUPPORT__)\r
+    //check CAP\r
+    #if (__CAP_ENABLE__)\r
+    hal_cap_drv_get_fifo_data(cap_soft_fifo_buffer, &cap_soft_fifo_buffer_index);\r
+    #endif\r
+    GH3X2X_MoveDetectByCapData(cap_soft_fifo_buffer, cap_soft_fifo_buffer_index);\r
+    //check GS\r
+    hal_gsensor_drv_get_fifo_data(gsensor_soft_fifo_buffer + __GS_EXTRA_BUF_LEN__, &gsensor_soft_fifo_buffer_index);\r
+    Gh3x2x_NormalizeGsensorSensitivity(gsensor_soft_fifo_buffer + __GS_EXTRA_BUF_LEN__,gsensor_soft_fifo_buffer_index);\r
+    GhMoveDetectByGsData((GS16*)(gsensor_soft_fifo_buffer + __GS_EXTRA_BUF_LEN__), gsensor_soft_fifo_buffer_index);\r
+#endif\r
+}\r
+\r
+/**\r
+ * @fn     void Gh3x2xDemoSetFuncionFrequency(GU8 uchFunctionID, GU16 usFrequencyValue)\r
+ *\r
+ * @brief  Set function frequency\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   uchFunctionID\r
+ * @param[in]   usFrequencyValue\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void Gh3x2xDemoSetFuncionFrequency(GU8 uchFunctionID, GU16 usFrequencyValue)\r
+{\r
+    GU32 unFuncModeTemp = 0;\r
+    \r
+    GH3X2X_DecodeRegCfgArr(&unFuncModeTemp, (g_stGh3x2xCfgListArr + g_uchGh3x2xRegCfgArrIndex)->pstRegConfigArr, \\r
+                            (g_stGh3x2xCfgListArr + g_uchGh3x2xRegCfgArrIndex)->usConfigArrLen);\r
+    \r
+    if (((1 << uchFunctionID) & unFuncModeTemp) == 0)\r
+    {\r
+        GH3X2X_INFO_LOG("[%s]:Current cfg cannot support !!! cfgfunc = 0x%x, selectfuncs = 0x%x\r\n", __FUNCTION__, (int)unFuncModeTemp, (1 << uchFunctionID));\r
+        return;\r
+    }\r
+\r
+    if (usFrequencyValue % 25 || usFrequencyValue > 1000)\r
+    {\r
+        GH3X2X_INFO_LOG("[%s]:The SR is not a multiple of 25!!!srvalue = %d\r\n", __FUNCTION__, usFrequencyValue);\r
+        return;\r
+    }\r
+    \r
+    GU32 unDemoFuncModeBeforeChipReset = g_unDemoFuncMode;\r
+    \r
+    if (unDemoFuncModeBeforeChipReset != 0)\r
+    {\r
+        Gh3x2xDemoStopSampling(unDemoFuncModeBeforeChipReset);\r
+        GH3X2X_INFO_LOG("[%s]:Stop.\r\n", __FUNCTION__);\r
+        Gh3x2x_BspDelayMs(30);\r
+    }\r
+    \r
+    GH3X2X_ModifyFunctionFrequency(uchFunctionID, usFrequencyValue);\r
+    GH3X2X_INFO_LOG("[%s]:Change fs !!! func = 0x%x, fs = %d\r\n", __FUNCTION__, (1 << uchFunctionID), usFrequencyValue);\r
+    \r
+    if (unDemoFuncModeBeforeChipReset != 0)\r
+    {\r
+        Gh3x2x_BspDelayMs(30);\r
+        Gh3x2xDemoStartSampling(unDemoFuncModeBeforeChipReset);\r
+        GH3X2X_INFO_LOG("[%s]:Restart.\r\n", __FUNCTION__);\r
+    }\r
+}\r
+\r
+/**\r
+ * @fn     void Gh3x2xDemoSetFuncionLedCurrent(GU8 uchFunctionID, GU16 usLedDrv0Current, GU16 usLedDrv1Current)\r
+ *\r
+ * @brief  Set function led current\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   uchFunctionID               function offset\r
+ * @param[in]   usLedDrv0Current         0mA-200mA\r
+ * @param[in]   usLedDrv1Current         0mA-200mA\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void Gh3x2xDemoSetFuncionLedCurrent(GU8 uchFunctionID, GU16 usLedDrv0Current, GU16 usLedDrv1Current)\r
+{\r
+    GU32 unFuncModeTemp = 0;\r
+    \r
+    GH3X2X_DecodeRegCfgArr(&unFuncModeTemp, (g_stGh3x2xCfgListArr + g_uchGh3x2xRegCfgArrIndex)->pstRegConfigArr, \\r
+                            (g_stGh3x2xCfgListArr + g_uchGh3x2xRegCfgArrIndex)->usConfigArrLen);\r
+\r
+    if (((1 << uchFunctionID) & unFuncModeTemp) == 0)\r
+    {\r
+        GH3X2X_INFO_LOG("[%s]:Current cfg cannot support !!! cfgfunc = 0x%x, selectfuncs = 0x%x\r\n", __FUNCTION__, (int)unFuncModeTemp, (1 << uchFunctionID));\r
+        return;\r
+    }\r
+\r
+    GH3X2X_ModifyFunctionLedCurrent(uchFunctionID, usLedDrv0Current, usLedDrv1Current);\r
+    GH3X2X_INFO_LOG("[%s]:Change led current !!! func = 0x%x, drv0 current = %d, drv1 current = %d\r\n",  __FUNCTION__, (1 << uchFunctionID), (int)usLedDrv0Current, (int)usLedDrv1Current);\r
+}\r
+\r
+\r
+#if (__SUPPORT_ELECTRODE_WEAR_STATUS_DUMP__)\r
+void GH3X2X_ReadElectrodeWearDumpData(void)\r
+{\r
+    g_uchGh3x2xElectrodeWearStatus = GH3X2X_ReadRegBitField(0x050C, 1, 1);\r
+}\r
+#endif\r
+\r
+void Gh3x2xSetFrameFlag2(const STGh3x2xFrameInfo * const pstFrameInfo)\r
+{\r
+    if(0 == (*(pstFrameInfo->punFrameCnt)))\r
+    {\r
+        pstFrameInfo->punFrameFlag[2] |= 0x02;\r
+    }\r
+    #if (__SUPPORT_ELECTRODE_WEAR_STATUS_DUMP__)\r
+    if(g_uchGh3x2xElectrodeWearStatus)\r
+    {\r
+        pstFrameInfo->punFrameFlag[2] |= 0x04;\r
+    }\r
+    #endif\r
+}\r
+\r
+\r
+void Gh3x2xIntPinTriggerModePro(void)\r
+{\r
+#if (!(__NORMAL_INT_PROCESS_MODE__ == __INTERRUPT_PROCESS_MODE__ || __MIX_INT_PROCESS_MODE__ == __INTERRUPT_PROCESS_MODE__))\r
+    GH3X2X_WriteReg(0x0502,0); //disable INT\r
+#endif\r
+    GH3X2X_WriteRegBitField(0x0000,10, 10, 0); //rg_int_pwrup = 0:do not chip auto wake-up before int pin trigger\r
+}\r
+\r
+\r
+void GH3x2xSlotTimeInfo(void)\r
+{\r
+#if 1 == __SLOT_SEQUENCE_DYNAMIC_ADJUST_EN__\r
+    for(GU8 uchSlotCnt = 0; uchSlotCnt < 8; uchSlotCnt ++)\r
+    {\r
+        GU8 uchCfgIndex;\r
+        //get slot time infomation\r
+        if(0 == (uchSlotCnt&0x01)) //0,2,4,6\r
+        {\r
+            uchCfgIndex = GH3X2X_ReadRegBitField(0x0100 + (uchSlotCnt&0xFE), 0,3);\r
+        }\r
+        else  //1,3,5,7\r
+        {\r
+            uchCfgIndex = GH3X2X_ReadRegBitField(0x0100 + (uchSlotCnt&0xFE), 8,11);\r
+        }\r
+        if(uchCfgIndex < 8)\r
+        {\r
+            g_usGh3x2xSlotTime[uchCfgIndex] = GH3X2X_ReadReg(0x01EC + uchCfgIndex *2);\r
+            GH3X2X_INFO_LOG("[%s]:CfgIndex[%d]:Slot time = %d\r\n", __FUNCTION__, uchCfgIndex, g_usGh3x2xSlotTime[uchCfgIndex]);\r
+        }\r
+    }\r
+#endif\r
+}\r
+\r
+#if (__GH3X2X_CASCADE_EN__)\r
+GS8 Gh3x2xEcgCascadeCommunicationTest(void)\r
+{\r
+    GS8  chRet = GH3X2X_RET_OK;\r
+    GH3X2X_CascadeOperationMasterChip();\r
+    GU16 usChipReadyCode = GH3X2X_ReadReg(0x36);\r
+    if (0xaa55 == usChipReadyCode)\r
+    {\r
+        GH3X2X_INFO_LOG("Master Communication success!!! 0x36:0x%04x\r\n",usChipReadyCode);\r
+    }\r
+    else\r
+    {\r
+        GH3X2X_INFO_LOG("Master Communication FAIL!!! 0x36:0x%04x\r\n",usChipReadyCode);\r
+        chRet = GH3X2X_RET_COMM_ERROR;\r
+    }\r
+    \r
+    \r
+    GH3X2X_CascadeOperationSlaverChip();\r
+    usChipReadyCode = GH3X2X_ReadReg(0x36);\r
+    if (0xaa55 == usChipReadyCode)\r
+    {\r
+        GH3X2X_INFO_LOG("Slaver Communication success!!! 0x36:0x%04x\r\n",usChipReadyCode);\r
+    }\r
+    else\r
+    {\r
+        GH3X2X_INFO_LOG("Slaver Communication FAIL!!! 0x36:0x%04x\r\n",usChipReadyCode);\r
+        chRet = GH3X2X_RET_COMM_ERROR;\r
+    }\r
+    GH3X2X_CascadeOperationMasterChip();\r
+    \r
+    return chRet;\r
+\r
+}\r
+\r
+#endif\r
+\r
+\r
+\r
+// void gh3x2x_control(char* mode, uint8_t enable)\r
+// {\r
+\r
+//     uint32_t md = 1;\r
+//     if (strcmp(mode, "hrs") == 0) {\r
+//         md = 0;\r
+//     } else if (strcmp(mode, "hrv") == 0) {\r
+//         md = 1;\r
+//     } else if (strcmp(mode, "spo2") == 0) {\r
+//         md = 2;\r
+//     } else if (strcmp(mode, "leaklight") == 0) {\r
+//         md = 4;\r
+//     } else if (strcmp(mode, "graycard") == 0) {\r
+//         md = 8;\r
+//     } else if (strcmp(mode, "ledoff") == 0) {\r
+//         md = 16;\r
+//     } else if (strcmp(mode, "wear") == 0) {\r
+//         md = 32;\r
+//     } else if (strcmp(mode, "single") == 0) {\r
+//         md = 64;\r
+//     }else if (strcmp(mode, "factory") == 0) {\r
+//         md = 128;\r
+//     }else if (strcmp(mode, "fpc") == 0) {\r
+//         // md = WORK_MODE_UNDEFINED;\r
+//     }else if (strcmp(mode, "int") == 0) {\r
+//     } \r
+\r
+//     if (enable == 1)\r
+//     {\r
+//         // ppg_service_running_stat = true;\r
+//         // uapi_pm_control(PM_APP_WAKE_NEEDED);\r
+//         // GH3X2X_AFE_StartFunction(mode);\r
+//         // GH3X2X_AFE_Init();\r
+//         // GH3X2X_AFE_StartSampling(1);\r
+//     } else {\r
+        \r
+//         // uapi_pm_control(PM_APP_WAKE_NONEED);\r
+//         // GH3X2X_AFE_StopSampling();\r
+//     } \r
+// }\r
+\r
+// /********END OF FILE********* Copyright (c) 2003 - 2022, Goodix Co., Ltd. ********/\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/kernel/gh_demo.h b/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/kernel/gh_demo.h
new file mode 100644 (file)
index 0000000..c7d7668
--- /dev/null
@@ -0,0 +1,265 @@
+/**\r
+ * @copyright (c) 2003 - 2022, Goodix Co., Ltd. All rights reserved.\r
+ *\r
+ * @file    gh3x_demo.h\r
+ *\r
+ * @brief   header file of gh3x2x driver lib demo\r
+ *\r
+ * @version GH(M)3X2X_DRV_LIB_DEMO_1.0\r
+ *\r
+ * @author  Gooidx Iot Team\r
+ *\r
+ */\r
+\r
+\r
+#ifndef _GH_DEMO_H_\r
+#define _GH_DEMO_H_\r
+\r
+#include "gh_drv.h"\r
+\r
+#include "gh_multi_sen_pro.h"\r
+\r
+/**\r
+ * @fn     int Gh3x2xDemoInit(void)\r
+ *\r
+ * @brief  Init GH3x2x module.\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+int Gh3x2xDemoInit(void);\r
+\r
+/**\r
+ * @fn     GU8 Gh3x2xDemoInterruptProcess(void)\r
+ *\r
+ * @brief  Interrupt process of GH3x2x.\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void Gh3x2xDemoInterruptProcess(void);\r
+\r
+/**\r
+ * @fn     void hal_gh3x2x_int_handler_call_back(void)\r
+ * \r
+ * @brief  call back of gh3x2x int handler\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void hal_gh3x2x_int_handler_call_back(void);\r
+\r
+/**\r
+ * @fn     GS8 Gh3x2xDemoArrayCfgSwitch(GU8 uchArrayCfgIndex)\r
+ *\r
+ * @brief  array cfg switch (call by user)\r
+ *\r
+ * @attention  you should switch array cfg manually before calling Gh3x2xDemoStartSampling\r
+ *\r
+ * @param[in]   uchArrayCfgIndex    0: gh3x2x_reg_list0    1: gh3x2x_reg_list0 ...\r
+ * @param[out]  None\r
+ *\r
+ * @return  GH3X2X_RET_OK:switch application mode success\r
+ * @return  GH3X2X_RET_RESOURCE_ERROR:can't find corresponding reg config array\r
+ */\r
+GS8 Gh3x2xDemoArrayCfgSwitch(GU8 uchArrayCfgIndex);\r
+\r
+\r
+/**\r
+ * @fn     void Gh3x2xDemoStartSamplingWithCfgSwitch(GU32 unFuncMode, GU8 uchArrayCfgIndex)\r
+ *\r
+ * @brief  Start sampling of GH3x2x\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   unFuncMode      function mode that will start\r
+ *                              GH3X2X_FUNCTION_ADT/GH3X2X_FUNCTION_HR/GH3X2X_FUNCTION_SPO2/GH3X2X_FUNCTION_ECG and etc.\r
+ * @param[in]   uchArrayCfgIndex      cfg id\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void Gh3x2xDemoStartSamplingWithCfgSwitch(GU32 unFuncMode, GU8 uchArrayCfgIndex);\r
+\r
+/**\r
+ * @fn     void Gh3x2xDemoStartSampling()\r
+ *\r
+ * @brief  Start sampling of GH3x2x\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   unFuncMode      function mode that will start\r
+ *                              GH3X2X_FUNCTION_ADT/GH3X2X_FUNCTION_HR/GH3X2X_FUNCTION_SPO2/GH3X2X_FUNCTION_ECG and etc.\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void Gh3x2xDemoStartSampling(GU32 unFuncMode);\r
+\r
+/**\r
+ * @fn     void Gh3x2xDemoStartSamplingForEngineeringMode()\r
+ *\r
+ * @brief  Start sampling of GH3x2x for engineering mode\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   unFuncMode      function mode that will start\r
+ *                              GH3X2X_FUNCTION_ADT/GH3X2X_FUNCTION_HR/GH3X2X_FUNCTION_SPO2/GH3X2X_FUNCTION_ECG and etc.\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void Gh3x2xDemoStartSamplingForEngineeringMode(GU32 unFuncMode, GU8 uchArrayCfgIndex, STGh3x2xEngineeringModeSampleParam *pstSampleParaGroup , GU8 uchSampleParaGroupNum);\r
+\r
+\r
+/**\r
+ * @fn     void Gh3x2xDemoStopSampling(GU32 unFuncMode)\r
+ *\r
+ * @brief  Stop sampling of GH3x2x\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   unFuncMode      function mode that will start\r
+ *                              GH3X2X_FUNCTION_ADT/GH3X2X_FUNCTION_HR/GH3X2X_FUNCTION_SPO2/GH3X2X_FUNCTION_ECG and etc.\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void Gh3x2xDemoStopSampling(GU32 unFuncMode);\r
+\r
+\r
+\r
+/**\r
+ * @fn     void Gh3x2xDemoStopSamplingForEngineeringMode(void)\r
+ *\r
+ * @brief  Stop sampling of GH3x2x for engineering mode\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void Gh3x2xDemoStopSamplingForEngineeringMode(void);\r
+\r
+\r
+\r
+/**\r
+ * @fn     void Gh3x2x_CreateMoveDetTimer(void)\r
+ * \r
+ * @brief  Create a timer for adt confirm which will read gsensor data periodically\r
+ *\r
+ * @attention   Period of timer can be set by \r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void Gh3x2xCreateMoveDetTimer(void);\r
+\r
+\r
+\r
+/**\r
+ * @fn     void Gh3x2xDemoProtocolProcess(GU8* puchProtocolDataBuffer, GU16 usRecvLen)\r
+ *\r
+ * @brief  Analyze protocol about GH3x2x,and pack protocol data to reply\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]  puchProtocolDataBuffer   pointer to received protocol data buffer\r
+ * @param[in]  usRecvLen                protocol data buffer length\r
+ *\r
+ * @return  None\r
+ */\r
+void Gh3x2xDemoProtocolProcess(GU8* puchProtocolDataBuffer, GU16 usRecvLen);\r
+\r
+/**\r
+ * @fn     void Gh3x2xDemoFunctionSampleRateSet(GU32 unFunctionID,  GU16 usSampleRate)\r
+ *\r
+ * @brief  \r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   unFunctionID   such as: GH3X2X_FUNCTION_HR   or  GH3X2X_FUNCTION_HR|GH3X2X_FUNCTION_HRV\r
+ * @param[in]   usSampleRate   only 25Hz times supported  (25/50/75...)\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void Gh3x2xDemoFunctionSampleRateSet(GU32 unFunctionID,  GU16 usSampleRate);\r
+\r
+\r
+\r
+\r
+/**\r
+ * @fn     void Gh3x2xDemoSetFuncionLedCurrent(GU8 uchFunctionID, GU16 usLedDrv0Current, GU16 usLedDrv1Current)\r
+ *\r
+ * @brief  Set function led current\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   uchFunctionID               function offset\r
+ * @param[in]   usLedDrv0Current         0mA-200mA\r
+ * @param[in]   usLedDrv1Current         0mA-200mA\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void Gh3x2xDemoSetFuncionLedCurrent(GU8 uchFunctionID, GU16 usLedDrv0Current, GU16 usLedDrv1Current);\r
+\r
+\r
+/**\r
+ * @fn      void Gh3x2xDemoFunctionChannelEnSet(GU32 unFunctionID,  GU32 unChnlEn)\r
+ *\r
+ * @brief  \r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   unFunctionID   such as: GH3X2X_FUNCTION_HR   or  GH3X2X_FUNCTION_HR|GH3X2X_FUNCTION_HRV\r
+ * @param[in]   unChnlEn   BitN = 0: channel N is disable        BitN = 1: channel N is enable\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void Gh3x2xDemoFunctionChannelEnSet(GU32 unFunctionID,  GU32 unChnlEn);\r
+\r
+/**\r
+ * @fn     void Gh3x2xInterruptModeSwitch(EMInterruptModeType emIntModeType)\r
+ *\r
+ * @brief  change Interrupt process mode of GH3x2x.\r
+ *\r
+ * @attention   do not input 2\r
+ *\r
+ * @param[in]   emIntModeType 0:int pin 1: polling\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void Gh3x2xInterruptModeSwitch(GU8 uchIntModeType);\r
+GU8 Gh3x2xGetInterruptMode(void);\r
+void Gh3x2xSerialSendTimerHandle(void);\r
+\r
+// void gh3x2x_control(char* mode, uint8_t enable);\r
+\r
+\r
+#if (__GH3X2X_CASCADE_EN__)\r
+GS8 Gh3x2xEcgCascadeCommunicationTest(void);\r
+#endif\r
+\r
+#endif /* _GH_DEMO_H_ */\r
+\r
+/********END OF FILE********* Copyright (c) 2003 - 2022, Goodix Co., Ltd. ********/\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/kernel/gh_demo_config.h b/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/kernel/gh_demo_config.h
new file mode 100644 (file)
index 0000000..a6ede66
--- /dev/null
@@ -0,0 +1,366 @@
+/**\r
+ * @copyright (c) 2003 - 2022, Goodix Co., Ltd. All rights reserved.\r
+ *\r
+ * @file    gh_demo_config.h\r
+ *\r
+ * @brief   gh3x2x driver lib demo configuration file\r
+ *\r
+ * @author  Gooidx Iot Team\r
+ *\r
+ */\r
+#ifndef _GH_DEMO_CONFIG_H_\r
+#define _GH_DEMO_CONFIG_H_\r
+#include "gh_drv.h"\r
+#include "stdio.h"\r
+\r
+\r
+/* bsp config */\r
+/**< interface config __GH3X2X_INTERFACE_I2C__ /__GH3X2X_INTERFACE_SPI__ */\r
+// #define __GH3X2X_INTERFACE__                (__GH3X2X_INTERFACE_SPI__)\r
+#define __GH3X2X_INTERFACE__                (__GH3X2X_INTERFACE_I2C__)\r
+#if(__GH3X2X_INTERFACE__ == __GH3X2X_INTERFACE_SPI__)\r
+#define __GH3X2X_SPI_TYPE__                 (__GH3X2X_SPI_TYPE_SOFTWARE_CS__)\r
+#endif\r
+#if(__GH3X2X_INTERFACE__ == __GH3X2X_INTERFACE_I2C__)\r
+#define __GH3X2X_I2C_DEVICE_ID__            (GH3X2X_I2C_ID_SEL_1L0L)\r
+#endif\r
+#define __GS_SENSITIVITY_CONFIG__           (GSENSOR_SENSITIVITY_512_COUNTS_PER_G)  /**< gsensor sensitivity config */\r
+#define __GS_GYRO_ENABLE__                  (0)        /*Gyro enable*/\r
+#define __GS_NONSYNC_READ_EN__              (0)\r
+#if __GS_NONSYNC_READ_EN__\r
+#define __GS_SAMPLE_RATE_HZ__               (25)        /*gsenor sample rate(Hz)*/\r
+#define __GS_READ_POINT_NUM__               (6)         /* host read gsensor sample num in one time */\r
+#define __GS_READ_POINT_NUM_JITTER__        (3)         /* host read gsensor sample num jitter */\r
+#endif\r
+\r
+#define __CAP_ENABLE__                      (0)         /*Cap enable*/\r
+#define __TEMP_ENABLE__                     (0)         /*Temperature sensor enable*/\r
+\r
+#define __SUPPORT_HARD_RESET_CONFIG__       (1)         /**< support hard reset config */\r
+#define __INTERRUPT_PROCESS_MODE__          (__NORMAL_INT_PROCESS_MODE__)  /**< 2:polling+int 1:use polling 0:use interrupt */\r
+#define __PLATFORM_WITHOUT_OS__             (0)         /**< 1:not use os  0:use os */\r
+#define __PASS_THROUGH_MODE__               (0)\r
+#define __GH3X2X_MP_MODE__                  (0)         /**< 1:enable mp mode  0:unable mp mode */\r
+#define __GH3X2X_CASCADE_EN__               (0)         /** dual-ecg function enable **/\r
+#if (__GH3X2X_CASCADE_EN__ && __GH3X2X_INTERFACE_I2C__)\r
+#define __GH3X2X_I2C_DEVICE_SLAVER_ID__     (GH3X2X_I2C_ID_SEL_1H0L)\r
+#endif\r
+#define __GH3X2X_ECG_RTYPE_5M__             (0)\r
+#define __RESET_AGCINFO_BEFORE_SAMPLE__     (0)\r
+#define __CURRENT_ECODE_CALIBRATE__         (0)\r
+\r
+/* app config */\r
+#define __USER_DYNAMIC_DRV_BUF_EN__         (0)        /*get rawdata buf via malloc*/\r
+#define __DRIVER_LIB_MODE__                 (__DRV_LIB_WITH_ALGO__)\r
+#define __DRIVER_OPEN_ALL_SOURCE__          (0)  //0: do not open all driver source(this mode can support goodix algorithm)   1: open all driver source (this mode may can NOT support goodix algorithm) \r
+#define __FUNC_RUN_SIMULTANEOUSLY_SUPPORT__ (1)\r
+#define __GH_MSG_WITH_ALGO_LAYER_EN__       (0)        /** enable message with algorithm send/recive process **/\r
+\r
+/* ppg function type */\r
+#define __FUNC_TYPE_HR_ENABLE__             (1)    /**< hb function tye */\r
+#define __FUNC_TYPE_HRV_ENABLE__            (1)    /**< hrv function tye */\r
+#define __FUNC_TYPE_HSM_ENABLE__            (1)    /**< hsm function tye */\r
+#define __FUNC_TYPE_SPO2_ENABLE__           (1)    /**< spo2 function tye */\r
+#define __FUNC_TYPE_BT_ENABLE__             (1)    /**< bt function tye */\r
+#define __FUNC_TYPE_RESP_ENABLE__           (1)    /**< resp function tye */\r
+#define __FUNC_TYPE_AF_ENABLE__             (1)    /**< af function tye */\r
+#define __FUNC_TYPE_TEST_ENABLE__           (1)    /**< test function tye */\r
+#define __SUPPORT_HARD_ADT_CONFIG__         (1)    /**< support hard adt config */\r
+#define __FUNC_TYPE_SOFT_ADT_ENABLE__       (1)    /**< support soft adt config */\r
+#define __SUPPORT_SOFT_AGC_CONFIG__         (1)    /**< support soft agc config */\r
+\r
+#define __HARD_ADT_ALGO_CHECK_EN__          (0)   //0: do not use algo to replace hard adt module in chip  1: use algo to replace hard adt mudule in chip\r
+#define __ADT_ONLY_PARTICULAR_WM_CONFIG__   (5)  //0: Do not set particular watermark at openning function is ADT only  N (N>3&&N<800): set particular watermark, and this value is N at openning function is ADT only\r
+\r
+/* ecg function type */\r
+#define __FUNC_TYPE_ECG_ENABLE__            (1)    /**< ecg algorithm tye */\r
+#if __FUNC_TYPE_ECG_ENABLE__\r
+#define __FUNC_TYPE_PWTT_ENABLE__           (1)    /**< pwtt algorithm tye */\r
+#define __FUNC_TYPE_BP_ENABLE__             (0)    /**< bp algorithm tye */\r
+#define __SUPPORT_ECG_LEAD_OFF_DET_800HZ__  (1)    \r
+#define GH3X2X_ECG_DOWNSAMP_CHNL_NUM        (1)    /**< ECG downsample chn number */\r
+\r
+#if ( __FUNC_TYPE_HR_ENABLE__)\r
+#define __SUPPORT_PPG_DOWNSAMP__            (1)    /**< PPG downsample algorithm tye */\r
+#define GH3X2X_PPG_DOWNSAMP_CHNL_NUM        (1)    /**< PPG downsample chn number */\r
+#endif\r
+#endif\r
+\r
+/*lead off parameters setting*/\r
+#define LEADOFF_DET_IQ_AMP_THR_uV           (1500)\r
+#define LEADOFF_DET_IQ_AMP_DIFF_THR_uV      (1000)\r
+#define LEADOFF_DET_IQ_VAL_THR_mV           (80)\r
+\r
+/* config about mult-sensor event process*/\r
+#define __GH_MULTI_SENSOR_EVENT_PRO_CONIG__              (1)        /**0: no support multi-sensor event process  1: support multi-sensor event process*/\r
+#define __GH_MULTI_SENSOR_TIMER_PERIOD_MS__              (1000)     /** period of multi-sensor timer, unit: ms*/\r
+#define __GH_MULTI_SENSOR_WEAR_EXAMPLE_EN__              (0)        /** this is example for using multi-senosr process to check wear on, you can set 1 to enable this example process*/\r
+\r
+/* config about g-sensor move detection */\r
+#define __GSENSOE_MOVE_DETECT_SUPPORT__                 (1)         /**0: no NOT support move detection 1: support move detection*/\r
+#define __GSENSOR_MOVE_THRESHOLD__                      (65)        /**< DIFF of sqrt(x^2+y^2+z^2) */\r
+#define __GSENSOR_MOVE_CNT_THRESHOLD__                  (1)         /**< (recomended value = 1) more than how many times of movement can be judged as effective moveing*/\r
+#define __GSENSOR_NOT_MOVE_CNT_THRESHOLD__              (150)       /**< (recommended value = 1.5 * sample rate of g-sensor ) more than how many times of movement can be judged as effective non-moveing*/    \r
+#define __GSENSOR_MOVE_TIME_OUT_THRESHOLD_MS__          (5000)      /**range 1~5000, the time of not move > __GSENSOR_MOVE_TIME_OUT_THRESHOLD_MS__, event : GH3X2X_MULTI_SENSOR_EVENT_GS_MOVE_TIME_OUT will be generated*/\r
+\r
+/*sofe agc config*/\r
+#if __SUPPORT_SOFT_AGC_CONFIG__\r
+#define GH3X2X_NEW_AGC_SLOT_NUM_LIMIT       (8u)\r
+#define GH3X2X_NEW_AGC_SUB_CHNL_NUM_LIMIT   (32u)\r
+#endif\r
+\r
+/* marco of divide zero flag enable*/\r
+#define   GH3X2X_DIVIDE_ZERO_FLAG_UPLODE_EN        (1)\r
+\r
+/*sample config*/\r
+#define __SLOT_SEQUENCE_DYNAMIC_ADJUST_EN__             (1)\r
+\r
+/*debug config*/\r
+#define __SUPPORT_PROTOCOL_ANALYZE__                    (1)         /**< driver lib support protocol analyze */\r
+#if (__SUPPORT_PROTOCOL_ANALYZE__)\r
+#define __UPLOAD_ALGO_RESULT__                          (1)         /**< upload algorithm result or not */\r
+#define __PROTOCOL_SERIAL_TYPE__                        (__PROTOCOL_SERIAL_USE_BLE__)  /**< protocol communicate serial port type */\r
+#define __SUPPORT_ZIP_PROTOCOL__                        (1)\r
+#define __FIFO_PACKAGE_SEND_ENABLE__                    (0)         /** 1: fifo package send mode enable  0: cannot open fifo package send mode */\r
+#define __GH3X2X_PROTOCOL_SEND_TIMER_PERIOD__           (10)        /** (unit : ms ) protocal data send timer period */\r
+#define __GH3X2X_PROTOCOL_DATA_FIFO_LEN__               (64)        /** protocal data send fifo length **/\r
+#define __GH3X2X_PROTOCOL_EVENT_FIFO_LEN__              (16)        /** protocal event send fifo length **/\r
+#define __GH3X2X_PROTOCOL_EVENT_WAITING_ACK_TIME__      (500)       /** (unit : ms ) protocal data waiting ack time, if time out, we will resend */\r
+#define __GH3X2X_PROTOCOL_EVENT_RESEND_NUM__            (255)       /***** 0~255  protocal resend num (255: evenlasting resending) */\r
+#define __GH3X2X_PROTOCOL_DATA_FUNCTION_INTERCEPT__     (GH3X2X_NO_FUNCTION) /* GH3X2X_NO_FUNCTION: none function date will be intercepted     (GH3X2X_FUNCTION_HR|GH3X2X_FUNCTION_HRV):  HR and HRV function data will be intercepted, those data will not output via protocal */\r
+#endif\r
+#define __SUPPORT_SAMPLE_DEBUG_MODE__                   (0)         /**< use sample debug mode */\r
+#define __SUPPORT_ELECTRODE_WEAR_STATUS_DUMP__          (1)         /** use electrode wear status dump */\r
+#define __GH3X2X_INFO_LOG_TYPE__                            (__GH3X2X_INFO_LOG_METHOD_0__) /**< example log config */\r
+#define __GH3X2X_INFO_LOG_LEVEL__                           (__GH3X2X_INFO_LOG_LV_1__ |__GH3X2X_INFO_LOG_LV_2__) /**< example log config */\r
+#define   GH3X2X_INFO_LOG_MAX_LEN                       (180)\r
+#define __SUPPORT_ENGINEERING_MODE__                    (1)         /**< enginerring mode*/\r
+#define __GH3X2X_MEM_POOL_CHECK_EN__                    (0)         /** 1: drv lib checks algo mem pool befor every time of algo calculating   0: do not check  **/\r
+\r
+/* operate config */\r
+#define __SUPPORT_FUNCTION_SAMPLE_RATE_MODIFY__         (0)         /** 0: only use default sample rate in array cfg  1: modifying function sample rate is supported via API: Gh3x2xDemoFunctionSampleRateSet */\r
+\r
+/*config list*/\r
+#define __GH3X2X_CFG_LIST_MAX_NUM__                     (8)         /**< max num of config list(1 ~ 8) */\r
+\r
+/* other config */\r
+#define __SUPPORT_HOOK_FUNC_CONFIG__                    (1)         /**< support hook func config */\r
+#define __SUPPORT_ALGO_INPUT_OUTPUT_DATA_HOOK_CONFIG__  (1)         /**< enable it ,we can get algo input and output data **/\r
+\r
+/* gh3x2x data buffer size config,this is related to gh3x2x fifo water mark config */\r
+#define __GH3X2X_RAWDATA_BUFFER_SIZE__                  (100 * 4)     /**< rawdata buffer size in byte */\r
+#define __GH3X2X_RAWDATA_SLAVE_BUFFER_SIZE__            (1 * 4)     /**< rawdata buffer size in byte for slave chip*/\r
+\r
+/* gsensor data buffer size config,every g sensor data has 6 bytes(x,y,z) */\r
+#define __GSENSOR_DATA_BUFFER_SIZE__                    (100)       /**< max num of gsensor data */\r
+\r
+#define __CAP_DATA_BUFFER_SIZE__                        (100)       /**< max num of CAP data */\r
+#define __TEMP_DATA_BUFFER_SIZE__                       (100)       /**< max num of TEMP data */\r
+\r
+/* function channel nunber config*/\r
+#define   GH3X2X_ADT_CHNL_NUM         (8)        /**< ADT function channel num */\r
+#define   GH3X2X_HR_CHNL_NUM          (32)        /**< HR function channel num */\r
+#define   GH3X2X_HRV_CHNL_NUM         (16)        /**< HRV function channel num */\r
+#define   GH3X2X_HSM_CHNL_NUM         (16)        /**< HSM function channel num */\r
+#define   GH3X2X_BP_CHNL_NUM          (16)        /**< BP function channel num */\r
+#define   GH3X2X_PWA_CHNL_NUM         (16)        /**< PWA function channel num */\r
+#define   GH3X2X_SPO2_CHNL_NUM        (32)        /**< SPO2 function channel num */\r
+#define   GH3X2X_ECG_CHNL_NUM         (8)        /**< ECG function channel num */\r
+#define   GH3X2X_PWTT_CHNL_NUM        (32)        /**< PWTT function channel num */\r
+#define   GH3X2X_SOFT_ADT_CHNL_NUM    (16)        /**< soft adt function channel num */\r
+#define   GH3X2X_BT_CHNL_NUM          (16)        /**< BT function channel num */\r
+#define   GH3X2X_RESP_CHNL_NUM        (16)        /**< RESP function channel num */\r
+#define   GH3X2X_AF_CHNL_NUM          (16)        /**< AF function channel num */\r
+#define   GH3X2X_TEST_CHNL_NUM        (16)        /**< TEST1 function channel num */\r
+\r
+/*fifo monitor*/\r
+#define GH3X2X_FIFO_MONITOR_EN                  (1)\r
+#define GH3X2X_FIFO_MONITOR_DECIMATION_SUPPORT  (0)\r
+\r
+\r
+\r
+#define GH3X2X_SEND_MSG_ALGO_CFG_INIT(g_pstGh3x2xFrameInfo, g_uchGh3x2xRegCfgArrIndex)         //add your code to send message to algorithm layer\r
+#define GH3X2X_SEND_MSG_ALGO_START(unFuncMode)  //add your code to send message to algorithm layer\r
+#define GH3X2X_SEND_MSG_ALGO_STOP(unFuncMode)   //add your code to send message to algorithm layer\r
+#define GH3X2X_SEND_MSG_ALGO_CAL(unFunctionID)              //add your code to send message to algorithm layer\r
+#define GH3X2X_PRO_MSG_SOFT_WEAR_EVEVT()        // if got soft wear event, GH3X2X_SetSoftEvent(GH3X2X_SOFT_EVENT_WEAR_OFF/GH3X2X_SOFT_EVENT_WEAR_ON)\r
+\r
+\r
+\r
+\r
+/***********************************  DO NOT MODIFY FOLLOWING CODE *******************************/\r
+/* log def*/\r
+#if (__GH3X2X_INFO_LOG_LEVEL__ > __GH3X2X_INFO_LOG_LV_0__)\r
+#if (__GH3X2X_INFO_LOG_LEVEL__ & __GH3X2X_INFO_LOG_LV_1__)\r
+#define   GH3X2X_INFO_LOG(...)              do{\\r
+                                            if(g_pSnprintfUserIn)\\r
+                                            {\\r
+                                                char gh3x2x_GH3X2X_INFO_LOG[GH3X2X_INFO_LOG_MAX_LEN] = {0};\\r
+                                                g_pSnprintfUserIn(gh3x2x_GH3X2X_INFO_LOG, GH3X2X_INFO_LOG_MAX_LEN, "[LOG_I] " __VA_ARGS__);\\r
+                                                GH3X2X_PlatformLog((GCHAR *)gh3x2x_GH3X2X_INFO_LOG);\\r
+                                            }\\r
+                                            if(g_pPrintfUserIn)g_pPrintfUserIn("[LOG_I] " __VA_ARGS__);\\r
+                                        } while(0)\r
+#else\r
+#define   GH3X2X_INFO_LOG(...)\r
+#endif\r
+\r
+#if (__GH3X2X_INFO_LOG_LEVEL__ & __GH3X2X_INFO_LOG_LV_2__)\r
+#define   GH3X2X_DEBUG_LOG(...)              do{\\r
+                                            if(g_pSnprintfUserIn)\\r
+                                            {\\r
+                                                char gh3x2x_GH3X2X_INFO_LOG[GH3X2X_INFO_LOG_MAX_LEN] = {0};\\r
+                                                g_pSnprintfUserIn(gh3x2x_GH3X2X_INFO_LOG, GH3X2X_INFO_LOG_MAX_LEN, "[LOG_D] " __VA_ARGS__);\\r
+                                                GH3X2X_PlatformLog((GCHAR *)gh3x2x_GH3X2X_INFO_LOG);\\r
+                                            }\\r
+                                            if(g_pPrintfUserIn)g_pPrintfUserIn("[LOG_D] " __VA_ARGS__);\\r
+                                        } while(0)\r
+#else\r
+#define   GH3X2X_DEBUG_LOG(...)        \r
+#endif\r
+\r
+#if (__GH3X2X_INFO_LOG_LEVEL__ & __GH3X2X_INFO_LOG_LV_3__)\r
+#define   GH3X2X_WARNING_LOG(...)              do{\\r
+                                            if(g_pSnprintfUserIn)\\r
+                                            {\\r
+                                                char gh3x2x_GH3X2X_INFO_LOG[GH3X2X_INFO_LOG_MAX_LEN] = {0};\\r
+                                                g_pSnprintfUserIn(gh3x2x_GH3X2X_INFO_LOG, GH3X2X_INFO_LOG_MAX_LEN, "[LOG_W] " __VA_ARGS__);\\r
+                                                GH3X2X_PlatformLog((GCHAR *)gh3x2x_GH3X2X_INFO_LOG);\\r
+                                            }\\r
+                                            if(g_pPrintfUserIn)g_pPrintfUserIn("[LOG_W] " __VA_ARGS__);\\r
+                                        } while(0)\r
+#else\r
+#define   GH3X2X_WARNING_LOG(...)      \r
+#endif\r
+\r
+#if (__GH3X2X_INFO_LOG_LEVEL__ & __GH3X2X_INFO_LOG_LV_4__)\r
+#define   GH3X2X_ERROR_LOG(...)              do{\\r
+                                            if(g_pSnprintfUserIn)\\r
+                                            {\\r
+                                                char gh3x2x_GH3X2X_INFO_LOG[GH3X2X_INFO_LOG_MAX_LEN] = {0};\\r
+                                                g_pSnprintfUserIn(gh3x2x_GH3X2X_INFO_LOG, GH3X2X_INFO_LOG_MAX_LEN,"[LOG_E] "  __VA_ARGS__);\\r
+                                                GH3X2X_PlatformLog((GCHAR *)gh3x2x_GH3X2X_INFO_LOG);\\r
+                                            }\\r
+                                            if(g_pPrintfUserIn)g_pPrintfUserIn("[LOG_E] "  __VA_ARGS__);\\r
+                                        } while(0)\r
+#else\r
+#define   GH3X2X_ERROR_LOG(...)        \r
+#endif\r
+\r
+#else\r
+#define   GH3X2X_INFO_LOG(...)\r
+#define   GH3X2X_ERROR_LOG(...)    \r
+#define   GH3X2X_DEBUG_LOG(...)  \r
+#define   GH3X2X_WARNING_LOG(...)\r
+#endif\r
+\r
+\r
+#if (__DRIVER_LIB_MODE__ == __DRV_LIB_WITH_ALGO__)\r
+#define __GH3X2X_MEM_POOL_CHECK_EN__ (0)\r
+#endif\r
+\r
+#ifndef __FUNC_TYPE_SOFT_ADT_ENABLE__\r
+#define __FUNC_TYPE_SOFT_ADT_ENABLE__  (0)\r
+#endif\r
+\r
+\r
+#if __FUNC_TYPE_ECG_ENABLE__ == 0\r
+#define __FUNC_TYPE_PWTT_ENABLE__           (0)    /**< pwtt algorithm tye */\r
+#define __FUNC_TYPE_BP_ENABLE__             (0)    /**< bp algorithm tye */\r
+#define __SUPPORT_ECG_LEAD_OFF_DET_800HZ__  (0)\r
+#endif\r
+\r
+#if(__GH3X2X_INTERFACE__ != __GH3X2X_INTERFACE_SPI__)\r
+#define __GH3X2X_SPI_TYPE__                 (__GH3X2X_SPI_TYPE_SOFTWARE_CS__)              \r
+#endif\r
+#if(__GH3X2X_INTERFACE__ != __GH3X2X_INTERFACE_I2C__)\r
+#define __GH3X2X_I2C_DEVICE_ID__            (GH3X2X_I2C_ID_SEL_1L0L)\r
+#endif\r
+\r
+#ifdef GH3X2X_MAIN_FUNC_CHNL_NUM\r
+#undef GH3X2X_MAIN_FUNC_CHNL_NUM\r
+#endif\r
+#define GH3X2X_MAIN_FUNC_CHNL_NUM 1\r
+#if __SUPPORT_HARD_ADT_CONFIG__\r
+#if GH3X2X_ADT_CHNL_NUM > GH3X2X_MAIN_FUNC_CHNL_NUM\r
+#undef GH3X2X_MAIN_FUNC_CHNL_NUM\r
+#define GH3X2X_MAIN_FUNC_CHNL_NUM GH3X2X_ADT_CHNL_NUM\r
+#endif\r
+#endif\r
+#if __FUNC_TYPE_HR_ENABLE__\r
+#if GH3X2X_HR_CHNL_NUM > GH3X2X_MAIN_FUNC_CHNL_NUM\r
+#undef GH3X2X_MAIN_FUNC_CHNL_NUM\r
+#define GH3X2X_MAIN_FUNC_CHNL_NUM GH3X2X_HR_CHNL_NUM\r
+#endif\r
+#endif\r
+#if __FUNC_TYPE_HRV_ENABLE__\r
+#if GH3X2X_HRV_CHNL_NUM > GH3X2X_MAIN_FUNC_CHNL_NUM\r
+#undef GH3X2X_MAIN_FUNC_CHNL_NUM\r
+#define GH3X2X_MAIN_FUNC_CHNL_NUM GH3X2X_HRV_CHNL_NUM\r
+#endif\r
+#endif\r
+#if __FUNC_TYPE_SPO2_ENABLE__\r
+#if GH3X2X_SPO2_CHNL_NUM > GH3X2X_MAIN_FUNC_CHNL_NUM\r
+#undef GH3X2X_MAIN_FUNC_CHNL_NUM\r
+#define GH3X2X_MAIN_FUNC_CHNL_NUM GH3X2X_SPO2_CHNL_NUM\r
+#endif\r
+#endif\r
+#if __FUNC_TYPE_ECG_ENABLE__\r
+#if GH3X2X_ECG_CHNL_NUM > GH3X2X_MAIN_FUNC_CHNL_NUM\r
+#undef GH3X2X_MAIN_FUNC_CHNL_NUM\r
+#define GH3X2X_MAIN_FUNC_CHNL_NUM GH3X2X_ECG_CHNL_NUM\r
+#endif\r
+#endif\r
+#if __FUNC_TYPE_TEST_ENABLE__\r
+#if GH3X2X_TEST_CHNL_NUM > GH3X2X_MAIN_FUNC_CHNL_NUM\r
+#undef GH3X2X_MAIN_FUNC_CHNL_NUM\r
+#define GH3X2X_MAIN_FUNC_CHNL_NUM GH3X2X_TEST_CHNL_NUM\r
+#endif\r
+#endif\r
+\r
+\r
+#ifdef GH3X2X_FUNC_CHNL_NUM_MAX\r
+#undef GH3X2X_FUNC_CHNL_NUM_MAX\r
+#endif\r
+#define GH3X2X_FUNC_CHNL_NUM_MAX GH3X2X_MAIN_FUNC_CHNL_NUM\r
+#if __FUNC_TYPE_SOFT_ADT_ENABLE__\r
+#if GH3X2X_SOFT_ADT_CHNL_NUM > GH3X2X_MAIN_FUNC_CHNL_NUM\r
+#undef GH3X2X_FUNC_CHNL_NUM_MAX\r
+#define GH3X2X_FUNC_CHNL_NUM_MAX GH3X2X_SOFT_ADT_CHNL_NUM\r
+#endif\r
+#endif\r
+\r
+\r
+#define __GS_EXTRA_BUF_LEN__    (0)\r
+#if __GS_NONSYNC_READ_EN__\r
+#undef __GS_EXTRA_BUF_LEN__\r
+#define __GS_EXTRA_BUF_LEN__    (__GS_READ_POINT_NUM__ + __GS_READ_POINT_NUM_JITTER__)\r
+#endif\r
+\r
+\r
+#ifndef __GH3X2X_PROTOCOL_DATA_FUNCTION_INTERCEPT__\r
+#define __GH3X2X_PROTOCOL_DATA_FUNCTION_INTERCEPT__   0\r
+#endif\r
+\r
+#ifndef __FIFO_PACKAGE_SEND_ENABLE__\r
+#define __FIFO_PACKAGE_SEND_ENABLE__   0\r
+#endif\r
+\r
+\r
+\r
+\r
+#if __ADT_ONLY_PARTICULAR_WM_CONFIG__\r
+#if __ADT_ONLY_PARTICULAR_WM_CONFIG__ < 4\r
+#error __ADT_ONLY_PARTICULAR_WM_CONFIG__ must be zero or bigger than 3 !!!\r
+#endif\r
+#endif\r
+\r
+\r
+\r
+#ifdef GOODIX_DEMO_PLATFORM\r
+#include "Goodix_Platform_config.h"\r
+#endif\r
+\r
+#endif /* _GH_DEMO_CONFIG_H_ */\r
+\r
+/********END OF FILE********* Copyright (c) 2003 - 2022, Goodix Co., Ltd. ********/\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/kernel/gh_demo_hook.c b/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/kernel/gh_demo_hook.c
new file mode 100644 (file)
index 0000000..8535f55
--- /dev/null
@@ -0,0 +1,470 @@
+/**\r
+ * @copyright (c) 2003 - 2022, Goodix Co., Ltd. All rights reserved.\r
+ * \r
+ * @file    gh3x2x_demo_hook.c\r
+ * \r
+ * @brief   gh3x2x driver lib demo code for hook\r
+ * \r
+ * @author  Gooidx Iot Team\r
+ * \r
+ */\r
+\r
+#include "gh_demo.h"\r
+#include "gh_demo_config.h"\r
+#include "gh_demo_inner.h"\r
+\r
+#if (__DRIVER_LIB_MODE__ == __DRV_LIB_WITH_ALGO__)\r
+#include "gh3x2x_demo_algo_call.h"\r
+#endif\r
+\r
+/* hook functions */\r
+\r
+/**\r
+ * @fn     void gh3x2x_init_hook_func(void)\r
+ * \r
+ * @brief  gh3x2x init hook\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void gh3x2x_init_hook_func(void)\r
+{\r
+#if (__ADT_ONLY_PARTICULAR_WM_CONFIG__)\r
+    g_usCurrentConfigListFifoWmBak = 0;\r
+#endif\r
+\r
+#if (__DRIVER_LIB_MODE__ == __DRV_LIB_WITH_ALGO__)\r
+    if(0 == GH3x2x_GetChipResetRecoveringFlag())\r
+    {\r
+        GH3X2X_AlgoCallConfigInit(g_pstGh3x2xFrameInfo, g_uchGh3x2xRegCfgArrIndex);\r
+    }\r
+#endif\r
+\r
+#if __GH_MSG_WITH_ALGO_LAYER_EN__\r
+    if(0 == GH3x2x_GetChipResetRecoveringFlag())\r
+    {\r
+        GH3X2X_SEND_MSG_ALGO_CFG_INIT(g_pstGh3x2xFrameInfo, g_uchGh3x2xRegCfgArrIndex);\r
+    }\r
+#endif\r
+\r
+}\r
+\r
+/**\r
+ * @fn     void gh3x2x_sampling_start_hook_func(void)\r
+ * \r
+ * @brief  gh3x2x start hook\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void gh3x2x_sampling_start_hook_func(void)\r
+{\r
+    GOODIX_PLATFORM_SAMPLING_START_HOOK_ENTITY();\r
+}\r
+\r
+/**\r
+ * @fn     void gh3x2x_sampling_stop_hook_func(void)\r
+ * \r
+ * @brief  gh3x2x stop hook\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void gh3x2x_sampling_stop_hook_func(void)\r
+{\r
+\r
+    GOODIX_PLATFORM_SAMPLING_STOP_HOOK_ENTITY();\r
+}\r
+\r
+/**\r
+ * @fn     void gh3x2x_get_rawdata_hook_func(GU8 *read_buffer_ptr, GU16 length)\r
+ * \r
+ * @brief  gh3x2x get rawdata hook\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   read_buffer_ptr     pointer to read rawdata buffer\r
+ * @param[in]   length              length\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+ typedef struct\r
+{\r
+    GU32 uiAdcCode;                      //sampling rawdata of ADC\r
+    GU8  ubSlotNo;                       //slot number\r
+    GU8  ubAdcNo;                        //adc number\r
+    GU8  ubFlagLedAdjIsAgc_EcgRecover;   //adj flag of ppg data or fast recover flag of ecg data\r
+    GU8  ubFlagLedAdjAgcUp;            //adj down flag of ppg data   0: down  1:up\r
+}StFifoDataInformation;\r
+void gh3x2x_get_rawdata_hook_func(GU8 *read_buffer_ptr, GU16 length)\r
+{\r
+#if (GH3X2X_FIFO_MONITOR_EN&(__GH3X2X_INTERFACE__ == __GH3X2X_INTERFACE_I2C__))\r
+     Gh3x2xFifoMonitorPro(&g_stFifoMonitorInfo, read_buffer_ptr, length);\r
+#endif\r
+\r
+    \r
+    /* code implement by user */\r
+    /****************** FOLLOWING CODE IS EXAMPLE **********************************/\r
+#if 0\r
+    StFifoDataInformation stTempFifoInfo = {0};\r
+    if (length/4 > 0)\r
+    {\r
+            for (int i = 0; i < length; i += 4)\r
+            {\r
+                GU32 temp = 0;\r
+                // big endian to little endian\r
+                temp =  ((GU32)read_buffer_ptr[i+ 0]) << 24;\r
+                temp += ((GU32)read_buffer_ptr[i+ 1])<< 16;\r
+                temp += ((GU32)read_buffer_ptr[i+ 2]) << 8;\r
+                temp += ((GU32)read_buffer_ptr[i+ 3]);    \r
+                // pick rawdata and flag\r
+                stTempFifoInfo.uiAdcCode = ((temp >> 0) & 0x00FFFFFF);\r
+                stTempFifoInfo.ubSlotNo =  ((temp >> 29) & 0x00000007);\r
+                stTempFifoInfo.ubAdcNo = ((temp >> 27) & 0x00000003);\r
+                stTempFifoInfo.ubFlagLedAdjIsAgc_EcgRecover = ((temp >> 26) & 0x00000001);\r
+                stTempFifoInfo.ubFlagLedAdjAgcUp = ((temp >> 25) & 0x00000001);\r
+                GH3X2X_INFO_LOG("Received rawdata:slot%d,adc%d,AdcCode = %d\r\n", stTempFifoInfo.ubSlotNo, stTempFifoInfo.ubAdcNo, \\r
+                                                                    stTempFifoInfo.uiAdcCode);\r
+            }\r
+    }\r
+#endif\r
+}\r
+\r
+/**\r
+ * @fn      void gh3x2x_algorithm_get_io_data_hook_func(const STGh3x2xFrameInfo * const pstFrameInfo)\r
+ * \r
+ * @brief  get algorithm input and output data\r
+ *\r
+ * @attention   None        \r
+ *\r
+ * @param[in]   pstFrameInfo\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void gh3x2x_algorithm_get_io_data_hook_func(const STGh3x2xFrameInfo * const pstFrameInfo)\r
+{\r
+    /* algo calculate */\r
+#if (__DRIVER_LIB_MODE__ == __DRV_LIB_WITH_ALGO__)\r
+    //GOODIX_PLATFORM_SAMPLING_START_HOOK_ENTITY();\r
+    GH3X2X_AlgoCalculate(pstFrameInfo->unFunctionID);\r
+#endif\r
+\r
+#if __GH_MSG_WITH_ALGO_LAYER_EN__\r
+    GH3X2X_SEND_MSG_ALGO_CAL(pstFrameInfo->unFunctionID);\r
+#endif\r
+\r
+#if (__SUPPORT_ALGO_INPUT_OUTPUT_DATA_HOOK_CONFIG__)\r
+    /****************** FOLLOWING CODE IS EXAMPLE **********************************/\r
+#if 0\r
+    //function id and channel num\r
+    GH3X2X_INFO_LOG("[IO_DATA]Function ID: 0x%X, channel num = %d, frame cnt = %d\r\n",(int)(pstFrameInfo->unFunctionID),(int)(pstFrameInfo->pstFunctionInfo->uchChnlNum),(int)(pstFrameInfo->punFrameCnt[0]));\r
+    //gsensor data\r
+    GH3X2X_INFO_LOG("[IO_DATA]Gsensor: x = %d, y = %d, z = %d\r\n",\\r
+                        (int)(pstFrameInfo->pusFrameGsensordata[0]),\\r
+                        (int)(pstFrameInfo->pusFrameGsensordata[1]),\\r
+                        (int)(pstFrameInfo->pusFrameGsensordata[2])\\r
+                );\r
+    //rawdata\r
+    for(GU8 uchChnlCnt = 0; uchChnlCnt < pstFrameInfo->pstFunctionInfo->uchChnlNum; uchChnlCnt ++)\r
+    {\r
+        GH3X2X_INFO_LOG("[IO_DATA]Ch%d rawdata= %d\r\n",(int)(uchChnlCnt),(int)(pstFrameInfo->punFrameRawdata[uchChnlCnt]));\r
+    }\r
+#endif\r
+#endif\r
+}\r
+\r
+void gh3x2x_frame_data_hook_func(const STGh3x2xFrameInfo * const pstFrameInfo)\r
+{\r
+#if (__DRIVER_LIB_MODE__ == __DRV_LIB_WITH_ALGO__)\r
+    if (GH3X2X_TimestampSyncGetFrameDataFlag() == 0 && GH3X2X_GetGsensorEnableFlag())\r
+    {\r
+        /* user set time stamp code here */\r
+        GU32 unTimeStamp = 0;\r
+        //GU8 uchFuncOffsetID = 0;\r
+        //for(GU8 uchFunCnt = 0; uchFunCnt < __SYNC_FUNC_MAX__; uchFunCnt ++)\r
+        //{\r
+        //    if (((1<<uchFunCnt) & pstFrameInfo->unFunctionID) == (1<<uchFunCnt))\r
+        //    {\r
+        //        uchFuncOffsetID = uchFunCnt;\r
+        //        break;\r
+        //    }\r
+        //}\r
+        //unTimeStamp = func_ppg_timestamp[uchFuncOffsetID];\r
+        GH3X2X_TimestampSyncFillPpgSyncBuffer(unTimeStamp, pstFrameInfo);\r
+        //func_ppg_timestamp[uchFuncOffsetID] += 40;\r
+    }\r
+    else\r
+    {\r
+#endif\r
+        gh3x2x_algorithm_get_io_data_hook_func(pstFrameInfo);\r
+#if (__DRIVER_LIB_MODE__ == __DRV_LIB_WITH_ALGO__)\r
+    }\r
+#endif\r
+}\r
+\r
+void gh3x2x_reset_by_protocol_hook(void)\r
+{\r
+    //Gh3x2x_BspDelayMs(20);\r
+    //Gh3x2xDemoInterruptProcess();\r
+    GH3X2X_INFO_LOG("[%s]:handle protocol reset\r\n", __FUNCTION__);\r
+}\r
+\r
+void gh3x2x_config_set_start_hook(void)\r
+{\r
+    /* code implement by user */\r
+}\r
+\r
+void gh3x2x_config_set_stop_hook(void)\r
+{\r
+    Gh3x2xIntPinTriggerModePro();\r
+    GH3x2xSlotTimeInfo();\r
+#if (__DRIVER_LIB_MODE__ == __DRV_LIB_WITH_ALGO__)\r
+    GH3X2X_AlgoSensorEnable(GH3X2X_GetGsensorEnableFlag(),GH3X2X_GetCapEnableFlag(),GH3X2X_GetTempEnableFlag());\r
+#endif\r
+}\r
+\r
+void gh3x2x_write_algo_config_hook(GU16 usVirtualRegAddr, GU16 usVirtualRegValue)\r
+{\r
+#if (__DRIVER_LIB_MODE__ == __DRV_LIB_WITH_ALGO__)\r
+    GH3X2X_WriteAlgConfigWithVirtualReg(usVirtualRegAddr, usVirtualRegValue);\r
+#endif\r
+}\r
+\r
+\r
+#if (__FUNC_TYPE_ECG_ENABLE__)\r
+/**\r
+ * @fn     void Gh3x2x_LeadOnEventHook(void)\r
+ * \r
+ * @brief  Lead on event hook\r
+ *\r
+ * @attention   None        \r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void Gh3x2x_LeadOnEventHook(void)\r
+{\r
+    GOODIX_PLATFORM_LEAD_ON_EVENT();\r
+}\r
+\r
+/**\r
+ * @fn     void Gh3x2x_LeadOffEventHook(void)\r
+ * \r
+ * @brief  Lead off event hook\r
+ *\r
+ * @attention   None        \r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void Gh3x2x_LeadOffEventHook(void)\r
+{\r
+    GOODIX_PLATFORM_LEAD_OFF_EVENT();\r
+}\r
+#endif\r
+\r
+\r
+\r
+#if __GH_MULTI_SENSOR_EVENT_PRO_CONIG__\r
+\r
+extern const STGhMultiSensorTimerOps g_stGhMultiSensorTimerOps;\r
+\r
+void GhMultiSensorWearDetStop(void)\r
+{\r
+       GhMultiSensorTimerStop();\r
+    GhMultiSensorTimerOpsUnregister();\r
+\r
+       GhMultSensorWearEventManagerDisable();\r
+       GhGsMoveDetecterDisable();\r
+}\r
+\r
+\r
+/** @brief hook when new multi sensor wear event is generated,\r
+ you can do operation as below in this hook. \r
+firstly, you can check event record in Event list via API Gh3x2xMultiSensorConditionCheckInWindow or Gh3x2xMultiSensorConditionCheckIsNew;\r
+soconly, you can disable multi sensor event manager via API GhMultSensorWearEventManagerDisable\r
+thirdly, you can open/close function via API Gh3x2xDemoStartSampling/Gh3x2xDemoStopSampling according event record \r
+**/\r
+/// @param uchNewEvent such as: GH3X2X_MULTI_SENSOR_EVENT_GH_WEAR_ON\r
+void GhMultiSensorEventHook(GU32 uchNewEvent)\r
+{\r
+    #if 1\r
+    if(GH3X2X_MULTI_SENSOR_EVENT_GS_MOVE_TIME_OUT == uchNewEvent)\r
+    {\r
+        GH3X2X_DEBUG_LOG("[GhMultiSensorEventHook] gs move time out, stop adt\r\n");\r
+        Gh3x2xDemoStopSampling(GH3X2X_FUNCTION_ADT);\r
+    }\r
+    if(GH3X2X_MULTI_SENSOR_EVENT_GS_MOVE == uchNewEvent)\r
+    {\r
+        GH3X2X_DEBUG_LOG("[GhMultiSensorEventHook] sensor gs move, start adt\r\n");\r
+        Gh3x2xDemoStartSampling(GH3X2X_FUNCTION_ADT);\r
+    }\r
+    if(GhMultiSensorConditionCheckIsNew(GH3X2X_MULTI_SENSOR_EVENT_GH_WEAR_ON, GH3X2X_MULTI_SENSOR_EVENT_GH_WEAR_OFF))\r
+    {\r
+        if(GhMultiSensorConditionCheckInWindow(GH3X2X_MULTI_SENSOR_EVENT_GS_MOVE, 3000, 1))\r
+        {\r
+            //final wear on\r
+            GH3X2X_INFO_LOG("[GhMultiSensorEventHook] final wear on !!!! \r\n");\r
+            GhMultiSensorWearDetStop();\r
+            #if (__SUPPORT_PROTOCOL_ANALYZE__)\r
+            Gh3x2xDemoReportEvent(GH3X2X_IRQ_MSK_WEAR_ON_BIT, GH3X2X_EVENT_EX_BIT_MULTI_SENSOR);\r
+            #endif\r
+            /****************START:   add your handle you want after final wear on ***************/\r
+            #if (__GH_MULTI_SENSOR_WEAR_EXAMPLE_EN__&&__GH_MULTI_SENSOR_EVENT_PRO_CONIG__)\r
+            Gh3x2xDemoStartSampling(GH3X2X_FUNCTION_HR|GH3X2X_FUNCTION_SOFT_ADT_GREEN);\r
+            #endif\r
+\r
+            /****************END:   add your handle you want after final wear on ***************/\r
+\r
+        }\r
+    }\r
+    #endif\r
+}\r
+\r
+void GhMultiSensorWearDetStart(void)\r
+{\r
+    GH3X2X_DEBUG_LOG("[GhMultiSensorWearDetStart] Multi Sensor Wear Detect Start\r\n");\r
+    Gh3x2xDemoStopSampling(GH3X2X_FUNCTION_ADT);\r
+\r
+    GhMultiSensorTimerInit();\r
+    GhMultiSensorTimerOpsRegister(&g_stGhMultiSensorTimerOps);\r
+    GhMultiSensorTimerStart();\r
+\r
+    GhMultSensorWearEventManagerInit();\r
+    GhMultSensorWearEventManagerHookRegister(GhMultiSensorEventHook);\r
+    GhMultSensorWearEventManagerEnable();\r
+\r
+    GhGsMoveDetecterInit();\r
+    GhGsMoveDetecterEnable();\r
+}\r
+#endif\r
+\r
+\r
+#if (__SUPPORT_HARD_ADT_CONFIG__)\r
+/**\r
+ * @fn     extern void Gh3x2x_WearEventHook(GU16 usGotEvent, GU8 uchWearOffType);\r
+ * \r
+ * @brief  Wear event hook\r
+ *\r
+ * @attention   None        \r
+ *\r
+ * @param[in]   wear event\r
+ * @param[in]   wear off type  0: no object  1: nonliving object    wear on type   0: object     1: living object\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+\r
+\r
+\r
+extern GU8 g_uchNeedStartMultiSensorWearOn;\r
+void Gh3x2x_WearEventHook(GU16 usGotEvent, GU8 uchExentEx)\r
+{\r
+    if (usGotEvent & GH3X2X_IRQ_MSK_WEAR_OFF_BIT)\r
+    {\r
+        \r
+        GOODIX_PLATFORM_WEAR_OFF_EVENT();\r
+        if(uchExentEx&GH3X2X_EVENT_EX_BIT_WEAR_LIVING_TYPE)\r
+        {\r
+            GOODIX_PLATFORM_NONLIVING_WEAR_OFF_EVENT();\r
+            GH3X2X_INFO_LOG("Wear off, no living-object!!!\r\n");\r
+            #if (__GH_MULTI_SENSOR_WEAR_EXAMPLE_EN__&&__GH_MULTI_SENSOR_EVENT_PRO_CONIG__)\r
+            Gh3x2xDemoStopSampling(GH3X2X_FUNCTION_HR|GH3X2X_FUNCTION_SOFT_ADT_GREEN);\r
+            GhMultiSensorWearDetStart();\r
+            #endif\r
+\r
+        }\r
+        else\r
+        {\r
+            GH3X2X_INFO_LOG("Wear off, no object!!!\r\n");\r
+            #if (__GH_MULTI_SENSOR_WEAR_EXAMPLE_EN__&&__GH_MULTI_SENSOR_EVENT_PRO_CONIG__)\r
+            if(0 == GhMultSensorWearEventManagerIsEnable())   // multi-sensor wear detection is not opened\r
+            {\r
+                                                               GH3X2X_DEBUG_LOG("[Gh3x2x_WearEventHook] no object!!! stop hr and soft_adt\r\n");\r
+                Gh3x2xDemoStopSampling(GH3X2X_FUNCTION_HR|GH3X2X_FUNCTION_SOFT_ADT_GREEN);\r
+            }\r
+            #endif\r
+            #if __GH_MULTI_SENSOR_EVENT_PRO_CONIG__\r
+            GhMultSensorWearEventSend(GH3X2X_MULTI_SENSOR_EVENT_GH_WEAR_OFF);\r
+            #endif\r
+        }\r
+\r
+    }\r
+    else if (usGotEvent & GH3X2X_IRQ_MSK_WEAR_ON_BIT)\r
+    {\r
+\r
+        GOODIX_PLATFORM_WEAR_ON_EVENT();\r
+\r
+        if(uchExentEx&GH3X2X_EVENT_EX_BIT_WEAR_LIVING_TYPE)\r
+        {\r
+            GH3X2X_INFO_LOG("Wear on, living-object!!!\r\n");\r
+        }\r
+        else\r
+        {\r
+            GH3X2X_INFO_LOG("Wear on, object !!!\r\n");\r
+\r
+            #if (__GH_MULTI_SENSOR_WEAR_EXAMPLE_EN__&&__GH_MULTI_SENSOR_EVENT_PRO_CONIG__)\r
+            if(0 == GhMultSensorWearEventManagerIsEnable())   // multi-sensor wear detection is not opened\r
+            {\r
+                Gh3x2xDemoStartSampling(GH3X2X_FUNCTION_HR|GH3X2X_FUNCTION_SOFT_ADT_GREEN);  // open main function\r
+            }\r
+            #endif\r
+            #if __GH_MULTI_SENSOR_EVENT_PRO_CONIG__\r
+            GhMultSensorWearEventSend(GH3X2X_MULTI_SENSOR_EVENT_GH_WEAR_ON);\r
+            #endif\r
+        }\r
+\r
+    }\r
+}\r
+#endif\r
+\r
+#if (__GH3X2X_CASCADE_EN__)\r
+void Gh3x2x_WearEventCascadeEcgHandle(GU16 usGotEvent)\r
+{\r
+    if (usGotEvent & GH3X2X_IRQ_MSK_WEAR_OFF_BIT)\r
+    {\r
+        if (GH3X2X_CascadeGetEcgEnFlag())\r
+        {\r
+            GH3X2X_CascadeEcgSlaverLeadDectDis();\r
+        }\r
+    }\r
+    else if (usGotEvent & GH3X2X_IRQ_MSK_WEAR_ON_BIT)\r
+    {\r
+        if (GH3X2X_CascadeGetEcgEnFlag())\r
+        {\r
+            GH3X2X_CascadeEcgSlaverLeadDectEn();\r
+            \r
+        }\r
+    }\r
+}\r
+#endif\r
+\r
+void Gh3x2x_BeforeWakeUpHook(void)\r
+{\r
+    GOODIX_PLATFORM_BEFORE_WAKE_UP_HOOK_ENTITY();\r
+}\r
+void Gh3x2x_WakeUpHook(void)\r
+{\r
+    GOODIX_PLATFORM_WAKE_UP_HOOK_ENTITY();\r
+}\r
+\r
+\r
+\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/kernel/gh_demo_inner.h b/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/kernel/gh_demo_inner.h
new file mode 100644 (file)
index 0000000..ec56a9c
--- /dev/null
@@ -0,0 +1,586 @@
+/**\r
+ * @copyright (c) 2003 - 2022, Goodix Co., Ltd. All rights reserved.\r
+ *\r
+ * @file    gh_demo_inner.h\r
+ *\r
+ * @brief   gh3x2x driver lib demo inner header file\r
+ *\r
+ * @author  Gooidx Iot Team\r
+ *\r
+ */\r
+\r
+#ifndef _GH_DEMO_INNER_H_\r
+#define _GH_DEMO_INNER_H_\r
+#include "gh_demo_config.h"\r
+#include "gh_drv_control.h"\r
+\r
+\r
+#ifdef GOODIX_DEMO_PLATFORM\r
+#include "gh3x2x_demo_goodix_platform.h"\r
+#else\r
+#define GOODIX_PLATFORM_SAMPLING_START_HOOK_ENTITY()\r
+#define GOODIX_PLATFORM_SAMPLING_STOP_HOOK_ENTITY()\r
+#define GOODIX_PLATFORM_SPI_WRITE_ENTITY(write_buffer, length)\r
+#define GOODIX_PLATFORM_PROTOCOL_ANALYZE()\r
+#define GOODIX_PLATFORM_REPORT_EVRENT_ENTITY()\r
+#define GOODIX_PLATFORM_SPI_READ_ENTITY()\r
+#define GOODIX_PLATFORM_SPI_CS_CTRL_ENTITY()\r
+#define GOODIX_PLATFORM_SPI_RESET_PIN_ENTITY()\r
+#define GOODIX_PLATFORM_INT_HANDLER_CALL_BACK_ENTITY()\r
+#define GOODIX_PLATFORM_INT_GS_START_CACHE_ENTITY()\r
+#define GOODIX_PLATFORM_INT_GS_STOP_CACHE_ENTITY()\r
+#define GOODIX_PLATFORM_INT_GET_GS_DATA_ENTITY()\r
+#define GOODIX_PLATFORM_LOG_ENTITY()\r
+#define GOODIX_PLATFORM_DELAY_US_ENTITY()\r
+#define GOODIX_PLATFORM_DELAY_MS_ENTITY()\r
+#define GOODIX_PLATFORM_DELAY_MS_ENTITY()\r
+#define GOODIX_PLATFORM_SERIAL_SEND_ENTITY()\r
+#define GOODIX_PLATFORM_INT_INIT_ENTITY()\r
+#define GOODIX_PLATFORM_RESET_PIN_INIT_ENTITY()\r
+#define GOODIX_PLATFORM_SPI_INIT_ENTITY()\r
+#define GOODIX_PLATFORM_CREAT_ADT_CONFIRM_ENTITY(unPeriodMs)\r
+#define GOODIX_PLATFORM_START_TIMER_ENTITY()\r
+#define GOODIX_PLATFORM_STOP_TIMER_ENTITY()\r
+#define GOODIX_PLATFORM_DEL_TIMER_ENTITY()\r
+#define GOODIX_PLATFORM_WEAR_ON_EVENT()\r
+#define GOODIX_PLATFORM_WEAR_OFF_EVENT()\r
+#define GOODIX_PLATFORM_NONLIVING_WEAR_OFF_EVENT()\r
+#define GOODIX_PLATFORM_LEAD_ON_EVENT()\r
+#define GOODIX_PLATFORM_LEAD_OFF_EVENT()\r
+#define GOODIX_PLATFORM_HR_RESULT_REPORT_ENTITY()\r
+#define GOODIX_PLATFORM_SPO2_RESULT_REPORT_ENTITY()\r
+#define GOODIX_PLATFORM_SERIAL_TIMER_STOP_ENTITY()\r
+#define GOODIX_PLATFORM_SERIAL_TIMER_START_ENTITY()\r
+#define GOODIX_PLATFORM_I2C_WRITE_ENTITY(device_id, write_buffer,length)\r
+#define GOODIX_PLATFORM_I2C_INIT_ENTITY()\r
+#define GOODIX_PLATFORM_I2C_READ_ENTITY(device_id, write_buffer, write_length, read_buffer, read_length)\r
+#define GOODIX_PLATFORM_INT_CAP_START_CACHE_ENTITY()\r
+#define GOODIX_PLATFORM_INT_CAP_STOP_CACHE_ENTITY()\r
+#define GOODIX_PLATFORM_INT_GET_CAP_DATA_ENTITY()\r
+#define GOODIX_PLATFORM_INT_TEMP_START_CACHE_ENTITY()\r
+#define GOODIX_PLATFORM_INT_TEMP_STOP_CACHE_ENTITY()\r
+#define GOODIX_PLATFORM_INT_GET_TEMP_DATA_ENTITY()\r
+#define GOODIX_PLATFORM_WRITE_CAP_TO_FLASH_ENTITY()\r
+#define GOODIX_PLATFORM_READ_CAP_FROM_FLASH_ENTITY()\r
+#define GOODIX_PLATFORM_BEFORE_WAKE_UP_HOOK_ENTITY()\r
+#define GOODIX_PLATFORM_WAKE_UP_HOOK_ENTITY()\r
+#define GOODIX_PLATFORM_PT_CONFIG_HOOK_ENTITY()\r
+#define GOODIX_PLATFORM_START_WITH_CONFIRM_HOOK_ENTITY()\r
+#define GOODIX_PLATFORM_PRESSURE_PARAS_READ_ENTITY()\r
+#define GOODIX_PLATFORM_PRESSURE_PARAS_WRITE_ENTITY()\r
+#define GOODIX_PLATFORM_PRINTF_ENTITY()\r
+#define GOODIX_PLATFORM_MALLOC_USER_ENTITY()\r
+#define GOODIX_PLATFORM_FREE_USER_ENTITY()\r
+#define GOODIX_PLATFORM_NADT_RESULT_HANDLE_ENTITY()\r
+#define GOODIX_PLATFORM_GOODIX_ALGO_CALL_ENTITY()\r
+#define GOODIX_PLATFORM_INT_DIVIDE_ZERO_ENABLE_ENTITY()\r
+#endif\r
+\r
+#define __PROTOCOL_DATA_LEN__       235\r
+\r
+#if defined ( __GNUC__ ) && !defined (__CC_ARM) /* GNU Compiler */\r
+  #ifndef __packed\r
+    #define __packed __attribute__((__packed__))\r
+  #endif /* __packed */\r
+#endif /* __GNUC__ */\r
+\r
+typedef struct\r
+{\r
+    GS16 sXAxisVal; // X-Axis Value\r
+    GS16 sYAxisVal; // Y-Axis Value\r
+    GS16 sZAxisVal; // Z-Axis Value\r
+#if __GS_GYRO_ENABLE__\r
+    GS16 sXGyroVal;\r
+    GS16 sYGyroVal;\r
+    GS16 sZGyroVal;\r
+#endif\r
+}STGsensorRawdata;\r
+\r
+#if __GH3X2X_MEM_POOL_CHECK_EN__\r
+extern GU8  g_uchGh3x2xMemPollHaveGetCheckSum;\r
+#endif\r
+extern GU8 g_uchDemoWorkMode;\r
+#if (__NORMAL_INT_PROCESS_MODE__ == __INTERRUPT_PROCESS_MODE__ || __MIX_INT_PROCESS_MODE__ == __INTERRUPT_PROCESS_MODE__)\r
+//hal_gh3x2x_int_handler_call_back is called, this value is 1\r
+extern GU8 g_uchGh3x2xIntCallBackIsCalled; \r
+#endif\r
+/// save function opened of driver lib\r
+extern GU32 g_unDemoFuncMode;\r
+/* config list array */\r
+extern const STGh3x2xInitConfig g_stGh3x2xCfgListArr[];\r
+\r
+\r
+extern STGh3x2xFifoMonitorInfo g_stFifoMonitorInfo;\r
+\r
+/* i2c interface */\r
+/**\r
+ * @fn     void hal_gh3x2x_i2c_init(void)\r
+ * \r
+ * @brief  hal i2c init for gh3x2x\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+extern void hal_gh3x2x_i2c_init(void);\r
+\r
+/**\r
+ * @fn     uint8_t hal_gh3x2x_i2c_write(uint8_t device_id, const uint8_t write_buffer[], uint16_t length)\r
+ * \r
+ * @brief  hal i2c write for gh3x2x\r
+ *\r
+ * @attention   device_id is 8bits, if platform i2c use 7bits addr, should use (device_id >> 1)\r
+ *\r
+ * @param[in]   device_id       device addr\r
+ * @param[in]   write_buffer    write data buffer\r
+ * @param[in]   length          write data len\r
+ * @param[out]  None\r
+ *\r
+ * @return  status\r
+ * @retval  #1      return successfully\r
+ * @retval  #0      return error\r
+ */\r
+GU8 hal_gh3x2x_i2c_write(GU8 device_id, const GU8 write_buffer[], GU16 length);\r
+\r
+/**\r
+ * @fn     uint8_t hal_gh3x2x_i2c_read(uint8_t device_id, const uint8_t write_buffer[], uint16_t write_length,\r
+ *                            uint8_t read_buffer[], uint16_t read_length)\r
+ * \r
+ * @brief  hal i2c read for gh3x2x\r
+ *\r
+ * @attention   device_id is 8bits, if platform i2c use 7bits addr, should use (device_id >> 1)\r
+ *\r
+ * @param[in]   device_id       device addr\r
+ * @param[in]   write_buffer    write data buffer\r
+ * @param[in]   write_length    write data len\r
+ * @param[in]   read_length     read data len\r
+ * @param[out]  read_buffer     pointer to read buffer\r
+ *\r
+ * @return  status\r
+ * @retval  #1      return successfully\r
+ * @retval  #0      return error\r
+ */\r
+GU8 hal_gh3x2x_i2c_read(GU8 device_id, const GU8 write_buffer[], GU16 write_length, GU8 read_buffer[], GU16 read_length);                       \r
+\r
+/* spi interface */\r
+/**\r
+ * @fn     void hal_gh3x2x_spi_init(void)\r
+ * \r
+ * @brief  hal spi init for gh3x2x\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+extern void hal_gh3x2x_spi_init(void);\r
+\r
+/**\r
+ * @fn     GU8 hal_gh3x2x_spi_write(GU8 write_buffer[], GU16 length)\r
+ * \r
+ * @brief  hal spi write for gh3x2x\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   write_buffer    write data buffer\r
+ * @param[in]   length          write data len\r
+ * @param[out]  None\r
+ *\r
+ * @return  status\r
+ * @retval  #1      return successfully\r
+ * @retval  #0      return error\r
+ */\r
+extern GU8 hal_gh3x2x_spi_write(GU8 write_buffer[], GU16 length);\r
+\r
+/**\r
+ * @fn     GU8 hal_gh3x2x_spi_read(GU8 read_buffer[], GU16 length)\r
+ * \r
+ * @brief  hal spi read for gh3x2x\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   read_length     read data len\r
+ * @param[out]  read_buffer     pointer to read buffer\r
+ *\r
+ * @return  status\r
+ * @retval  #1      return successfully\r
+ * @retval  #0      return error\r
+ */\r
+extern GU8 hal_gh3x2x_spi_read(GU8 read_buffer[], GU16 length);\r
+\r
+extern GU8 hal_gh3x2x_spi_write_F1_and_read(GU8 read_buf[], GU16 length);\r
+\r
+\r
+/**\r
+ * @fn     void hal_gh3x2x_spi_cs_ctrl(GU8 cs_pin_level)\r
+ * \r
+ * @brief  hal spi cs pin ctrl for gh3x2x\r
+ *\r
+ * @attention   pin level set 1 [high level] or 0 [low level]\r
+ *\r
+ * @param[in]   cs_pin_level     spi cs pin level\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+extern void hal_gh3x2x_spi_cs_ctrl(GU8 cs_pin_level);\r
+\r
+/**\r
+ * @fn     void hal_gh3x2x_int_init(void)\r
+ * \r
+ * @brief  gh3x2x int init\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+extern void hal_gh3x2x_reset_pin_init(void);\r
+\r
+/**\r
+ * @fn     void hal_gh3x2x_reset_pin_ctrl(GU8 pin_level)\r
+ * \r
+ * @brief  hal reset pin ctrl for gh3x2x\r
+ *\r
+ * @attention   pin level set 1 [high level] or 0 [low level]\r
+ *\r
+ * @param[in]   pin_level     reset pin level\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+extern void hal_gh3x2x_reset_pin_ctrl(GU8 pin_level);\r
+\r
+/**\r
+ * @fn     void hal_gh3x2x_int_init(void)\r
+ * \r
+ * @brief  gh3x2x int init\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+extern void hal_gh3x2x_int_init(void);\r
+\r
+/**\r
+ * @fn     void hal_gsensor_start_cache_data(void)\r
+ * \r
+ * @brief  Start cache gsensor data for gh3x2x\r
+ *\r
+ * @attention   This function will be called when start gh3x2x sampling.\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+extern void hal_gsensor_start_cache_data(void);\r
+\r
+/**\r
+ * @fn     void hal_gsensor_stop_cache_data(void)\r
+ * \r
+ * @brief  Stop cache gsensor data for gh3x2x\r
+ *\r
+ * @attention   This function will be called when stop gh3x2x sampling.\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+extern void hal_gsensor_stop_cache_data(void);\r
+extern void hal_cap_start_cache_data(void);\r
+extern void hal_cap_stop_cache_data(void);\r
+extern void hal_temp_start_cache_data(void);\r
+extern void hal_temp_stop_cache_data(void);\r
+/**\r
+ * @fn     void hal_gsensor_drv_get_fifo_data(STGsensorRawdata gsensor_buffer[], GU16 *gsensor_buffer_index)\r
+ * \r
+ * @brief  get gsensor fifo data\r
+ *\r
+ * @attention   When read fifo data of GH3x2x,user should call this function to get gsensor data.And user must\r
+ *              assure that these gsensor data is corresponding to GH3x2x fifo data\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  gsensor_buffer          pointer to gsensor data buffer\r
+ * @param[out]  gsensor_buffer_index    pointer to number of gsensor data\r
+ *\r
+ * @return  None\r
+ */\r
+extern void hal_gsensor_drv_get_fifo_data(STGsensorRawdata gsensor_buffer[], GU16 *gsensor_buffer_index);\r
+extern void hal_cap_drv_get_fifo_data(STCapRawdata cap_data_buffer[], GU16 *cap_buffer_index);\r
+extern void hal_temp_drv_get_fifo_data(STTempRawdata Temp_data_buffer[], GU16 *temp_buffer_index);\r
+/**\r
+ * @fn     void GH3X2X_PlatformLog(char *log_string)\r
+ * \r
+ * @brief  for debug version, log\r
+ *\r
+ * @attention   this function must define that use debug version lib\r
+ *\r
+ * @param[in]   log_string      pointer to log string\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+extern void GH3X2X_PlatformLog(GCHAR *log_string);\r
+extern void GH3X2X_RegisterPrintf(int (**pPrintfUser)(const char *format, ...));\r
+\r
+/**\r
+ * @fn     void Gh3x2x_BspDelayUs(GU16 usUsec)\r
+ * \r
+ * @brief  Delay in us,user should register this function into driver lib\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+extern void Gh3x2x_BspDelayUs(GU16 usUsec);\r
+\r
+/**\r
+ * @fn     void Gh3x2x_BspDelayMs(GU16 usMsec)\r
+ * \r
+ * @brief  Delay in ms\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+extern void Gh3x2x_BspDelayMs(GU16 usMsec);\r
+\r
+/**\r
+ * @fn     void Gh3x2x_LeadOnEventHook(void)\r
+ * \r
+ * @brief  Lead on event hook\r
+ *\r
+ * @attention   None        \r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+extern void Gh3x2x_LeadOnEventHook(void);\r
+\r
+/**\r
+ * @fn     void Gh3x2x_LeadOffEventHook(void)\r
+ * \r
+ * @brief  Lead off event hook\r
+ *\r
+ * @attention   None        \r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+extern void Gh3x2x_LeadOffEventHook(void);\r
+/**\r
+ * @fn     void Gh3x2x_BeforeWakeUpHook(void)\r
+ * \r
+ * @brief  Before WakeUp Hook\r
+ *\r
+ * @attention   None        \r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+extern void Gh3x2x_BeforeWakeUpHook(void);\r
+\r
+/**\r
+ * @fn     void Gh3x2x_WakeUpHook(void)\r
+ * \r
+ * @brief  WakeUp Hook\r
+ *\r
+ * @attention   None        \r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+extern void Gh3x2x_WakeUpHook(void);\r
+\r
+/**\r
+ * @fn     void Gh3x2x_WearEventHook(GU16 usGotEvent, GU8 uchType)\r
+ * \r
+ * @brief  Wear event hook\r
+ *\r
+ * @attention   None        \r
+ *\r
+ * @param[in]   wear event\r
+ * @param[in]   wear off type  0: no object  1: nonliving object\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+extern void Gh3x2x_WearEventHook(GU16 usGotEvent, GU8 uchType);\r
+#if (__GH3X2X_CASCADE_EN__)\r
+extern void Gh3x2x_WearEventCascadeEcgHandle(GU16 usGotEvent);\r
+#endif\r
+\r
+/**\r
+ * @fn     void Gh3x2x_UserHandleCurrentInfo(void)\r
+ * \r
+ * @brief  handle gh3x2x chip current information for user\r
+ *\r
+ * @attention   None        \r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void Gh3x2x_UserHandleCurrentInfo(void);\r
+\r
+/**\r
+ * @fn     void Gh3x2xDemoAlgorithmCalculate(GU8* puchReadFifoBuffer, STGsensorRawdata *pstGsAxisValueArr, \r
+ *                                              GU16 usGsDataNum, EMGsensorSensitivity emGsSensitivity)\r
+ *\r
+ * @brief  Algorithm calculate.This function will be called in Gh3x2xDemoInterruptProcess()\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   puchReadFifoBuffer      point to gh3x2x fifo data buffer\r
+ * @param[in]   pstGsAxisValueArr       point to gsensor data buffer\r
+ * @param[in]   usGsDataNum             gsensor data cnt\r
+ * @param[in]   emGsSensitivity         sensitivity of gsensor\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+\r
+void Gh3x2xDemoFunctionProcess(GU8* puchReadFifoBuffer, GU16 usFifoBuffLen,STGsensorRawdata *pstGsAxisValueArr, GU16 usGsDataNum,\r
+                                   STCapRawdata* pstCapValueArr,GU16 usCapDataNum,STTempRawdata* pstTempValueArr,GU16 usTempDataNum);\r
+\r
+/**\r
+ * @fn     void Gh3x2xDemoSamplingControl(EMUprotocolParseCmdType emSwitch)\r
+ *\r
+ * @brief  Start/stop sampling of gh3x2x and sensor\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   unFuncMode      function that will be started or stopped\r
+ * @param[in]   emSwitch        stop/start sampling\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+extern void Gh3x2xDemoSamplingControl(GU32 unFuncMode, EMUprotocolParseCmdType emSwitch);\r
+\r
+/// dump mode\r
+extern GU16 g_usDumpMode;\r
+extern GU8 g_uchGh3x2xRegCfgArrIndex;\r
+extern GU16 g_usCurrentConfigListFifoWmBak;\r
+extern void GH3X2X_LedAgcProcessExDump(GU8* puchReadFifoBuffer);\r
+extern void GH3X2X_ReadElectrodeWearDumpData(void);\r
+extern void GH3X2X_RecordDumpData(void);\r
+extern void gh3x2x_init_hook_func(void);\r
+extern void gh3x2x_sampling_start_hook_func(void);\r
+extern void gh3x2x_sampling_stop_hook_func(void);\r
+extern void gh3x2x_get_rawdata_hook_func(GU8 *read_buffer_ptr, GU16 length);\r
+extern void gh3x2x_algorithm_get_io_data_hook_func(const STGh3x2xFrameInfo * const pstFrameInfo);\r
+extern void gh3x2x_frame_data_hook_func(const STGh3x2xFrameInfo * const pstFrameInfo);\r
+extern void gh3x2x_reset_by_protocol_hook(void);\r
+extern void gh3x2x_config_set_start_hook(void);\r
+extern void gh3x2x_config_set_stop_hook(void);\r
+extern void gh3x2x_write_algo_config_hook(GU16 usVirtualRegAddr, GU16 usVirtualRegValue);\r
+\r
+/**\r
+ * @fn     void Gh3x2xDemoReportEvent(GU16 usEvent,GU8 uchWearType)\r
+ *\r
+ * @brief  Report event to APP/EVK\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   usEvent      GH3x2x event\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+extern void Gh3x2xDemoReportEvent(GU16 usEvent,GU8 uchWearType);\r
+\r
+/**\r
+ * @fn     void Gh3x2x_HalSerialSendData(GU8* uchTxDataBuf, GU16 usBufLen)\r
+ *\r
+ * @brief  Serial send data\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   uchTxDataBuf        pointer to data buffer to be transmitted\r
+ * @param[in]   usBufLen            data buffer length\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+extern void Gh3x2x_HalSerialSendData(GU8* uchTxDataBuf, GU16 usBufLen);\r
+\r
+/**\r
+ * @fn     void Gh3x2x_StartAdtConfirmTimer(void)\r
+ * \r
+ * @brief  Start time of adt confirm to get g sensor\r
+ *\r
+ * @attention   None        \r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+extern void Gh3x2xSerialSendTimerStop(void);\r
+extern void Gh3x2xSerialSendTimerStart(void);\r
+extern void Gh3x2x_StartMultiSensorTimer(void);\r
+extern void Gh3x2xSerialSendTimerInit(GU8 uchPeriodMs);\r
+/**\r
+ * @fn     void Gh3x2x_StopAdtConfirmTimer(void)\r
+ * \r
+ * @brief  Stop time of adt confirm\r
+ *\r
+ * @attention   None        \r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+extern void Gh3x2x_StopMultiSensorTimer(void);\r
+extern void Gh3x2xDemoSendWearOrLeadStateToUI(GU8 state);\r
+extern void Gh3x2x_HalSerialFifoInit(void);\r
+extern void Gh3x2xMemPoolCheckSumWrite(GU8 *lunMemPool);\r
+extern GU16 Gh3x2xMemPoolCheckSumCheck(GU8 *lunMemPool);\r
+extern void Gh3x2xCheckMemPollBeforeAlgoCal(void);\r
+extern void Gh3x2xUpdataMemPollChkSumAfterAlgoCal(void);\r
+extern void GH3x2xMaserControlFunctionLog(GU32 unFuncMode, EMUprotocolParseCmdType emCmdType);\r
+#if ( __FUNC_TYPE_BP_ENABLE__ && (__GH3X2X_INTERFACE__ == __GH3X2X_INTERFACE_I2C__))\r
+extern GS8 gh3x2x_write_pressure_parameters(GS32 *buffer);\r
+extern GS8 gh3x2x_read_pressure_parameters(GS32 *buffer);\r
+#endif\r
+extern void* Gh3x2xMallocUser(GU32 unMemSize);\r
+extern void Gh3x2xFreeUser(void* MemAddr);\r
+\r
+extern void Gh3x2xDemoStopAlgoInner(GU32 unFuncMode);\r
+extern void Gh3x2xDemoStartAlgoInner(GU32 unFuncMode);\r
+\r
+extern void Gh3x2xDemoMoveDetectTimerHandler(GU32 unTimeIntervalMs);\r
+\r
+\r
+#endif /* _GH3X2X_DEMO_INNER_H_ */\r
+\r
+/********END OF FILE********* Copyright (c) 2003 - 2022, Goodix Co., Ltd. ********/\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/kernel/gh_demo_protocol.c b/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/kernel/gh_demo_protocol.c
new file mode 100644 (file)
index 0000000..e1d591c
--- /dev/null
@@ -0,0 +1,687 @@
+/**\r
+ * @copyright (c) 2003 - 2022, Goodix Co., Ltd. All rights reserved.\r
+ * \r
+ * @file    gh3x2x_demo_protocol.c\r
+ * \r
+ * @brief   gh3x2x driver lib demo code for protocol\r
+ * \r
+ * @author  Gooidx Iot Team\r
+ * \r
+ */\r
+\r
+#include "gh_demo_inner.h"\r
+#include "gh_multi_sen_pro.h"\r
+\r
+\r
+GU8 gubUseZipProtocol = 0;\r
+\r
+GU32 Gh3x2xGetProtocolDataFunctionIntercept(void)\r
+{\r
+    return __GH3X2X_PROTOCOL_DATA_FUNCTION_INTERCEPT__ ;\r
+}\r
+\r
+#if (__SUPPORT_PROTOCOL_ANALYZE__)\r
+\r
+#define GH3X2X_PROTOCOL_BUF_LEN             (255)\r
+#define GH3X2X_DEMO_USE_SERIAL_UART         (1)\r
+#define GH3X2X_DEMO_USE_SERIAL_BLE          (2)\r
+\r
+/* use BLE */\r
+#define RX_BYTE_STREAM_STATE_WAIT_HEADER    (0)\r
+#define RX_BYTE_STREAM_STATE_WAIT_VERSION   (1)\r
+#define RX_BYTE_STREAM_STATE_WAIT_CMD       (2)\r
+#define RX_BYTE_STREAM_STATE_WAIT_LEN       (3)\r
+#define RX_BYTE_STREAM_STATE_WAIT_DATA      (4)\r
+#define RX_BYTE_STREAM_STATE_WAIT_CRC8      (5)\r
+\r
+#define GH3X2X_PROTOCOL_HEADER              (0xAA)\r
+#define GH3X2X_PROTOCOL_VERSION             (0x11)\r
+#define GH3X2X_PROTOCOL_LEN_INDEX           (3)\r
+#define GH3X2X_PROTOCOL_HEADER_LEN          (4)\r
+\r
+/* use UART */\r
+#define RX_STREAM_STATE_WAIT_UART_HEADER_47 (0)\r
+#define RX_STREAM_STATE_WAIT_UART_HEADER_44 (1)\r
+#define RX_STREAM_STATE_WAIT_UART_LEN       (2)\r
+#define RX_STREAM_STATE_WAIT_UART_DATA      (3)\r
+#define RX_STREAM_STATE_WAIT_TAIL           (4)\r
+\r
+#define GH3X2X_PROTOCOL_BLE_UART_47         (0x47)\r
+#define GH3X2X_PROTOCOL_BLE_UART_44         (0x44)\r
+#define GH3X2X_PROTOCOL_BLE_TAIL            (0x0A)\r
+\r
+GU8  g_uchRxByteStreamState  = 0;\r
+GU16 g_usUartPayloadLen      = 0;\r
+GU16 g_usRxProtocolDataIndex = 0;\r
+GU8  g_puchProtocolBufferRecv[GH3X2X_PROTOCOL_BUF_LEN] = {0};\r
+\r
+\r
+\r
+\r
+\r
+STGh3x2xProtocolData  g_stGh3x2xProtocolData ={0};\r
+STGh3x2xProtocolData * const g_pstGh3x2xProtocolData = &g_stGh3x2xProtocolData;\r
+\r
+#define GH3X2X_PROTOCOL_DATA_PKG_SIZE (255)\r
+#define GH3X2X_PROTOCOL_EVENT_PKG_SIZE (4)\r
+#define GH3X2X_ROTOCOL_TEMP_EVENT_BUF_SIZE  (20)\r
+\r
+\r
+\r
+#define GH3X2X_SERIALSEND_TIMER_STATUS_STOP       0\r
+#define GH3X2X_SERIALSEND_TIMER_STATUS_START      1\r
+\r
+\r
+#define GH3X2X_PROTOCOL_EVENT_ACK_STATUS_NO_ACK   0\r
+#define GH3X2X_PROTOCOL_EVENT_ACK_STATUS_ACK      1\r
+\r
+\r
+volatile GU8 g_uchGh3x2xSerialSendTimerStatus;\r
+GU8 g_puchGh3x2xProtocolDataSendBuf[__GH3X2X_PROTOCOL_DATA_FIFO_LEN__][GH3X2X_PROTOCOL_DATA_PKG_SIZE];\r
+volatile GU8 g_uchGh3x2xProtocolDataSendFifoWp;\r
+GU8 g_uchGh3x2xProtocolDataSendFifoRp;\r
+\r
+GU8 g_puchGh3x2xProtocolEventSendBuf[__GH3X2X_PROTOCOL_EVENT_FIFO_LEN__][GH3X2X_PROTOCOL_EVENT_PKG_SIZE];\r
+volatile GU8 g_puchGh3x2xProtocolEventSendFifoWp;\r
+GU8 g_uchGh3x2xProtocolEventSendFifoRp;\r
+GU8 g_uchGh3x2xProtocolEventReportId;\r
+GU8 g_uchGh3x2xProtocolEventReportRetryCnt;\r
+GU8 g_uchGh3x2xProtocolEventAckStatus;\r
+GU16 g_usGh3x2xProtocolEventWaitingAckTime;\r
+GU8 g_uchGh3x2xProtocolEventAckId;\r
+GU8 g_uchGh3x2xProtocolIdleFlag;\r
+\r
+\r
+\r
+\r
+\r
+void Gh3x2x_HalSerialFifoInit(void)\r
+{\r
+    g_uchGh3x2xSerialSendTimerStatus = GH3X2X_SERIALSEND_TIMER_STATUS_STOP;\r
+    g_uchGh3x2xProtocolDataSendFifoWp = 0;\r
+    g_uchGh3x2xProtocolDataSendFifoRp = 0;\r
+    g_uchGh3x2xProtocolEventReportId = 0;\r
+    g_uchGh3x2xProtocolEventReportRetryCnt = 0;\r
+    g_uchGh3x2xProtocolEventAckStatus = GH3X2X_PROTOCOL_EVENT_ACK_STATUS_NO_ACK;\r
+    g_usGh3x2xProtocolEventWaitingAckTime = 0;\r
+    g_uchGh3x2xProtocolIdleFlag = 0;\r
+    Gh3x2xSerialSendTimerInit(__GH3X2X_PROTOCOL_SEND_TIMER_PERIOD__);\r
+}\r
+\r
+\r
+\r
+\r
+#ifdef GOODIX_DEMO_PLATFORM\r
+extern SemaphoreHandle_t UartTxFifoWritePower;\r
+extern void UartSendIdlePkgGoodixPlanform(void);\r
+\r
+#endif\r
+\r
+\r
+void Gh3x2x_HalSerialWriteDataToFifo(GU8 * lpubSource, GU8 lubLen)\r
+{\r
+    GU8 uchBufCnt;\r
+    if(0 == lubLen)\r
+    {\r
+        return ;\r
+    }\r
+\r
+    if(g_uchGh3x2xProtocolDataSendFifoWp >= g_uchGh3x2xProtocolDataSendFifoRp)\r
+    {\r
+        uchBufCnt = g_uchGh3x2xProtocolDataSendFifoWp - g_uchGh3x2xProtocolDataSendFifoRp;\r
+    }\r
+    else\r
+    {\r
+        uchBufCnt = __GH3X2X_PROTOCOL_DATA_FIFO_LEN__ - (g_uchGh3x2xProtocolDataSendFifoRp - g_uchGh3x2xProtocolDataSendFifoWp);\r
+    }\r
+\r
+#ifdef GOODIX_DEMO_PLATFORM\r
+    if((uchBufCnt >= (__GH3X2X_PROTOCOL_DATA_FIFO_LEN__ - 1)) || (LP_MODE_DSLEEP == LP_GetLowPwrMode()))\r
+#else\r
+    if((uchBufCnt >= (__GH3X2X_PROTOCOL_DATA_FIFO_LEN__ - 1)) )\r
+#endif\r
+    {\r
+        //GH3X2X_INFO_LOG("Warnning: Protocol Data fifo is overflow !!!\r\n");\r
+        return ;\r
+    }\r
+\r
+\r
+#ifdef GOODIX_DEMO_PLATFORM\r
+    xSemaphoreTake(UartTxFifoWritePower,portMAX_DELAY);\r
+#endif\r
+\r
+    if(lubLen > (GH3X2X_PROTOCOL_DATA_PKG_SIZE - 4))\r
+    {\r
+        lubLen = (GH3X2X_PROTOCOL_DATA_PKG_SIZE - 4);\r
+    }\r
+\r
+#ifdef GOODIX_DEMO_PLATFORM\r
+    #if (!defined(GR5515_SK)) && (__PROTOCOL_SERIAL_TYPE__ != __PROTOCOL_SERIAL_USE_UART__)\r
+    GH3X2X_Memset(((u8*)(g_puchGh3x2xProtocolDataSendBuf[g_uchGh3x2xProtocolDataSendFifoWp])), 0xA0,GH3X2X_PROTOCOL_DATA_PKG_SIZE);\r
+    GH3X2X_Memcpy(((u8*)(g_puchGh3x2xProtocolDataSendBuf[g_uchGh3x2xProtocolDataSendFifoWp])) + 3,lpubSource,lubLen);\r
+    g_puchGh3x2xProtocolDataSendBuf[g_uchGh3x2xProtocolDataSendFifoWp][0] = 0x47;\r
+    g_puchGh3x2xProtocolDataSendBuf[g_uchGh3x2xProtocolDataSendFifoWp][1] = 0x44;\r
+    g_puchGh3x2xProtocolDataSendBuf[g_uchGh3x2xProtocolDataSendFifoWp][2] = GH3X2X_PROTOCOL_DATA_PKG_SIZE - 4;\r
+    g_puchGh3x2xProtocolDataSendBuf[g_uchGh3x2xProtocolDataSendFifoWp][254] = 0x0A;\r
+    #else\r
+    GH3X2X_Memset(((u8*)(g_puchGh3x2xProtocolDataSendBuf[g_uchGh3x2xProtocolDataSendFifoWp])), 0xA0,GH3X2X_PROTOCOL_DATA_PKG_SIZE);\r
+    GH3X2X_Memcpy(((u8*)(g_puchGh3x2xProtocolDataSendBuf[g_uchGh3x2xProtocolDataSendFifoWp])),lpubSource,lubLen);\r
+    #endif\r
+#else\r
+    GH3X2X_Memcpy(((GU8*)(g_puchGh3x2xProtocolDataSendBuf[g_uchGh3x2xProtocolDataSendFifoWp])) + 0,lpubSource,lubLen);\r
+#endif\r
+        \r
+    \r
+    \r
+\r
+    g_uchGh3x2xProtocolDataSendFifoWp ++;\r
+    if(g_uchGh3x2xProtocolDataSendFifoWp >= __GH3X2X_PROTOCOL_DATA_FIFO_LEN__)\r
+    {\r
+        g_uchGh3x2xProtocolDataSendFifoWp = 0;\r
+    }\r
+    if(GH3X2X_SERIALSEND_TIMER_STATUS_STOP == g_uchGh3x2xSerialSendTimerStatus)\r
+    {\r
+        Gh3x2xSerialSendTimerStart();\r
+        g_uchGh3x2xSerialSendTimerStatus = GH3X2X_SERIALSEND_TIMER_STATUS_START;\r
+    }\r
+\r
+\r
+#ifdef GOODIX_DEMO_PLATFORM\r
+    xSemaphoreGive(UartTxFifoWritePower);\r
+#endif\r
+\r
+    return ;\r
+}\r
+\r
+\r
+void Gh3x2xSetProtocolEventAck(void)\r
+{\r
+    g_uchGh3x2xProtocolEventAckStatus = GH3X2X_PROTOCOL_EVENT_ACK_STATUS_ACK;\r
+}\r
+\r
+GU8 Gh3x2xGetProtocolEventReportId(void)\r
+{\r
+    return g_puchGh3x2xProtocolEventSendBuf[g_uchGh3x2xProtocolEventSendFifoRp][2];\r
+}\r
+\r
+\r
+\r
+\r
+\r
+void Gh3x2x_HalSerialWriteEventToFifo(GU16 luwEvent,GU8 uchEventEx)\r
+{\r
+    GU8 uchBufCnt;\r
+    \r
+    if(g_puchGh3x2xProtocolEventSendFifoWp >= g_uchGh3x2xProtocolEventSendFifoRp)\r
+    {\r
+        uchBufCnt = g_puchGh3x2xProtocolEventSendFifoWp - g_uchGh3x2xProtocolEventSendFifoRp;\r
+    }\r
+    else\r
+    {\r
+        uchBufCnt = __GH3X2X_PROTOCOL_EVENT_FIFO_LEN__ - (g_uchGh3x2xProtocolEventSendFifoRp - g_puchGh3x2xProtocolEventSendFifoWp);\r
+    }\r
+\r
+#ifdef GOODIX_DEMO_PLATFORM\r
+    if((uchBufCnt >= (__GH3X2X_PROTOCOL_EVENT_FIFO_LEN__ - 1)) || (LP_MODE_DSLEEP == LP_GetLowPwrMode()))\r
+#else\r
+    if((uchBufCnt >= (__GH3X2X_PROTOCOL_EVENT_FIFO_LEN__ - 1)))\r
+#endif\r
+    {\r
+        GH3X2X_INFO_LOG("Warnning: Protocol event fifo is overflow !!!\r\n");\r
+        return ;\r
+    }\r
+\r
+    g_uchGh3x2xProtocolEventReportId ++;\r
+    g_puchGh3x2xProtocolEventSendBuf[g_puchGh3x2xProtocolEventSendFifoWp][0] = ((GU8*)(&luwEvent))[1];\r
+    g_puchGh3x2xProtocolEventSendBuf[g_puchGh3x2xProtocolEventSendFifoWp][1] = ((GU8*)(&luwEvent))[0];\r
+    g_puchGh3x2xProtocolEventSendBuf[g_puchGh3x2xProtocolEventSendFifoWp][2] = g_uchGh3x2xProtocolEventReportId;\r
+    g_puchGh3x2xProtocolEventSendBuf[g_puchGh3x2xProtocolEventSendFifoWp][3] = uchEventEx;\r
+\r
+\r
+\r
+    g_puchGh3x2xProtocolEventSendFifoWp ++;\r
+    if(g_puchGh3x2xProtocolEventSendFifoWp >= __GH3X2X_PROTOCOL_EVENT_FIFO_LEN__)\r
+    {\r
+        g_puchGh3x2xProtocolEventSendFifoWp = 0;\r
+    }\r
+    if(GH3X2X_SERIALSEND_TIMER_STATUS_STOP == g_uchGh3x2xSerialSendTimerStatus)\r
+    {\r
+        Gh3x2xSerialSendTimerStart();\r
+        g_uchGh3x2xSerialSendTimerStatus = GH3X2X_SERIALSEND_TIMER_STATUS_START;\r
+    }\r
+\r
+    return ;\r
+}\r
+\r
+\r
+\r
+\r
+\r
+void Gh3x2xSerialSendTimerHandle(void)\r
+{\r
+    GU8 uchHaveSendPkg = 0;\r
+#ifdef GOODIX_DEMO_PLATFORM\r
+    GU8 puchTempEventSendBuf[GH3X2X_ROTOCOL_TEMP_EVENT_BUF_SIZE];\r
+#endif\r
+    GU8 uchStopTimerFlag = 0;\r
+    GU8 puchTempBuf2[GH3X2X_PROTOCOL_EVENT_PKG_SIZE + 5];\r
+\r
+    //check event fifo is empyty or not\r
+    if(g_puchGh3x2xProtocolEventSendFifoWp != g_uchGh3x2xProtocolEventSendFifoRp)\r
+    {\r
+        if(GH3X2X_PROTOCOL_EVENT_ACK_STATUS_ACK == g_uchGh3x2xProtocolEventAckStatus)  //got ack\r
+        {\r
+            g_uchGh3x2xProtocolEventSendFifoRp ++;\r
+            if(g_uchGh3x2xProtocolEventSendFifoRp >= __GH3X2X_PROTOCOL_EVENT_FIFO_LEN__)\r
+            {\r
+                g_uchGh3x2xProtocolEventSendFifoRp = 0;\r
+            }\r
+            g_uchGh3x2xProtocolEventAckStatus = GH3X2X_PROTOCOL_EVENT_ACK_STATUS_NO_ACK;\r
+            g_usGh3x2xProtocolEventWaitingAckTime = 0;\r
+        }\r
+        else   //have not got ack\r
+        {\r
+            if(g_usGh3x2xProtocolEventWaitingAckTime > __GH3X2X_PROTOCOL_EVENT_WAITING_ACK_TIME__)\r
+            {\r
+                if(g_uchGh3x2xProtocolEventReportRetryCnt < 255)\r
+                {\r
+                    g_uchGh3x2xProtocolEventReportRetryCnt ++;\r
+                }\r
+                g_usGh3x2xProtocolEventWaitingAckTime = 0;\r
+            }\r
+            if(g_uchGh3x2xProtocolEventReportRetryCnt > __GH3X2X_PROTOCOL_EVENT_RESEND_NUM__)  //retry cnt is enough\r
+            {\r
+                g_uchGh3x2xProtocolEventSendFifoRp ++;\r
+                if(g_uchGh3x2xProtocolEventSendFifoRp >= __GH3X2X_PROTOCOL_EVENT_FIFO_LEN__)\r
+                {\r
+                    g_uchGh3x2xProtocolEventSendFifoRp = 0;\r
+                }\r
+                g_uchGh3x2xProtocolEventReportRetryCnt = 0;\r
+            }\r
+        }\r
+    }\r
+\r
+    if(g_puchGh3x2xProtocolEventSendFifoWp != g_uchGh3x2xProtocolEventSendFifoRp)\r
+    {\r
+        if(0 == g_usGh3x2xProtocolEventWaitingAckTime)\r
+        {\r
+            if(0 == g_uchGh3x2xProtocolEventReportRetryCnt)\r
+            {\r
+                g_uchGh3x2xProtocolEventAckStatus = GH3X2X_PROTOCOL_EVENT_ACK_STATUS_NO_ACK;\r
+            }\r
+\r
+            //send next event or no-ack event\r
+            \r
+            \r
+            puchTempBuf2[0] = 0xAA;\r
+            puchTempBuf2[1] = 0x11;\r
+            puchTempBuf2[2] = 0x16;\r
+            puchTempBuf2[3] = GH3X2X_PROTOCOL_EVENT_PKG_SIZE;            \r
+            GH3X2X_Memcpy(puchTempBuf2 + 4,g_puchGh3x2xProtocolEventSendBuf[g_uchGh3x2xProtocolEventSendFifoRp],GH3X2X_PROTOCOL_EVENT_PKG_SIZE);\r
+            puchTempBuf2[GH3X2X_PROTOCOL_EVENT_PKG_SIZE + 5 - 1] = GH3X2X_CalcArrayCrc8Val(&(puchTempBuf2[0]),0,GH3X2X_PROTOCOL_EVENT_PKG_SIZE + 4);\r
+            \r
+#ifdef GOODIX_DEMO_PLATFORM\r
+            #if (!defined(GR5515_SK)) && (__PROTOCOL_SERIAL_TYPE__ != __PROTOCOL_SERIAL_USE_UART__)\r
+            GH3X2X_Memcpy(puchTempEventSendBuf + 3,puchTempBuf2,GH3X2X_PROTOCOL_EVENT_PKG_SIZE + 5);\r
+            puchTempEventSendBuf[0] = 0x47;\r
+            puchTempEventSendBuf[1] = 0x44;\r
+            puchTempEventSendBuf[2] = GH3X2X_ROTOCOL_TEMP_EVENT_BUF_SIZE - 4;\r
+            puchTempEventSendBuf[GH3X2X_ROTOCOL_TEMP_EVENT_BUF_SIZE - 1] = 0x0A;\r
+            Gh3x2x_HalSerialSendData((u8*)puchTempEventSendBuf,GH3X2X_ROTOCOL_TEMP_EVENT_BUF_SIZE);\r
+            g_uchGh3x2xProtocolIdleFlag = 1;\r
+            #else\r
+            GH3X2X_Memcpy(puchTempEventSendBuf,puchTempBuf2,GH3X2X_PROTOCOL_EVENT_PKG_SIZE + 5);\r
+            Gh3x2x_HalSerialSendData((GU8*)puchTempBuf2,GH3X2X_PROTOCOL_EVENT_PKG_SIZE + 5);\r
+            g_uchGh3x2xProtocolIdleFlag = 1;\r
+            #endif\r
+#else\r
+            Gh3x2x_HalSerialSendData((GU8*)puchTempBuf2,GH3X2X_PROTOCOL_EVENT_PKG_SIZE + 5);\r
+#endif\r
+            uchHaveSendPkg = 1;\r
+        }\r
+        g_usGh3x2xProtocolEventWaitingAckTime += __GH3X2X_PROTOCOL_SEND_TIMER_PERIOD__;\r
+    }\r
+\r
+\r
+\r
+\r
+\r
+    if(0 == uchHaveSendPkg)\r
+    {\r
+        if(g_uchGh3x2xProtocolDataSendFifoWp != g_uchGh3x2xProtocolDataSendFifoRp)\r
+        {\r
+            \r
+            \r
+            /**************  send to  master ************/\r
+#ifdef GOODIX_DEMO_PLATFORM\r
+            #if (!defined(GR5515_SK)) && (__PROTOCOL_SERIAL_TYPE__ != __PROTOCOL_SERIAL_USE_UART__)\r
+            Gh3x2x_HalSerialSendData(((u8*)(g_puchGh3x2xProtocolDataSendBuf[g_uchGh3x2xProtocolDataSendFifoRp])),GH3X2X_PROTOCOL_DATA_PKG_SIZE);\r
+            #else\r
+            Gh3x2x_HalSerialSendData(((u8*)(g_puchGh3x2xProtocolDataSendBuf[g_uchGh3x2xProtocolDataSendFifoRp])),5 + g_puchGh3x2xProtocolDataSendBuf[g_uchGh3x2xProtocolDataSendFifoRp][3]);\r
+            #endif\r
+            g_uchGh3x2xProtocolIdleFlag = 1;\r
+#else \r
+            Gh3x2x_HalSerialSendData(((GU8*)(g_puchGh3x2xProtocolDataSendBuf[g_uchGh3x2xProtocolDataSendFifoRp])),5 + g_puchGh3x2xProtocolDataSendBuf[g_uchGh3x2xProtocolDataSendFifoRp][3]);\r
+#endif\r
+            g_uchGh3x2xProtocolDataSendFifoRp ++;\r
+            if(g_uchGh3x2xProtocolDataSendFifoRp >= __GH3X2X_PROTOCOL_DATA_FIFO_LEN__)\r
+            {\r
+                g_uchGh3x2xProtocolDataSendFifoRp = 0;\r
+            }\r
+            uchHaveSendPkg = 1;\r
+        }\r
+    }\r
+    \r
+#ifdef GOODIX_DEMO_PLATFORM\r
+    if(0 == uchHaveSendPkg)\r
+    {\r
+        if(g_uchGh3x2xProtocolIdleFlag)\r
+        {\r
+            g_uchGh3x2xProtocolIdleFlag = 0;\r
+            UartSendIdlePkgGoodixPlanform();\r
+            \r
+        }\r
+    }\r
+#endif\r
+    if((g_puchGh3x2xProtocolEventSendFifoWp == g_uchGh3x2xProtocolEventSendFifoRp)&&(g_uchGh3x2xProtocolDataSendFifoWp == g_uchGh3x2xProtocolDataSendFifoRp))  //event fifo and data fifo is empyt\r
+    {\r
+        //close timer\r
+#ifdef GOODIX_DEMO_PLATFORM\r
+        if(0 == g_uchGh3x2xProtocolIdleFlag)\r
+#endif\r
+        {\r
+            if(GH3X2X_SERIALSEND_TIMER_STATUS_START == g_uchGh3x2xSerialSendTimerStatus)\r
+            {\r
+                Gh3x2xSerialSendTimerStop();\r
+                g_uchGh3x2xSerialSendTimerStatus = GH3X2X_SERIALSEND_TIMER_STATUS_STOP;\r
+                uchStopTimerFlag = 1;\r
+            }\r
+        }\r
+        \r
+    }\r
+    //check again for mulit-thread confict\r
+    if(uchStopTimerFlag)\r
+    {\r
+        if((g_puchGh3x2xProtocolEventSendFifoWp != g_uchGh3x2xProtocolEventSendFifoRp)||(g_uchGh3x2xProtocolDataSendFifoWp != g_uchGh3x2xProtocolDataSendFifoRp))  //event fifo and data fifo is empyt\r
+        {\r
+            Gh3x2xSerialSendTimerStart();\r
+            g_uchGh3x2xSerialSendTimerStatus = GH3X2X_SERIALSEND_TIMER_STATUS_START;\r
+        }\r
+    }\r
+    \r
+    \r
+}\r
+\r
+/**\r
+ * @fn     void Gh3x2xDemoSendProtocolData(GU8* puchProtocolDataBuffer, GU16 usProtocolDataLen)\r
+ *\r
+ * @brief  Copy protocol data to buffer that will be sent out to APP/EVK.\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   puchProtocolDataBuffer      point to protocol data\r
+ * @param[in]   usProtocolDataLen           protocol data length\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void Gh3x2xDemoSendProtocolData(GU8* puchProtocolDataBuffer, GU16 usProtocolDataLen)\r
+{\r
+    if ((usProtocolDataLen > GH3X2X_UPROTOCOL_PAYLOAD_LEN_MAX) || (0 == usProtocolDataLen))\r
+    {\r
+        return;\r
+    }\r
+    #if __SUPPORT_PROTOCOL_ANALYZE__\r
+    Gh3x2x_HalSerialWriteDataToFifo(puchProtocolDataBuffer, usProtocolDataLen);\r
+    #endif\r
+}\r
+\r
+/**\r
+ * @fn     void Gh3x2xDemoOneFrameDataProcess(GU8* puchProtocolDataBuffer, GU16 usRecvLen)\r
+ *\r
+ * @brief  Analyze protocol about GH3x2x,and pack protocol data to reply\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[out]  puchProtocolDataBuffer      pointer to protocol data buffer\r
+ * @param[out]  usRecvLen                   protocol data buffer len\r
+ *\r
+ * @return  None\r
+ */\r
+void Gh3x2xDemoOneFrameDataProcess(GU8* puchProtocolDataBuffer, GU16 usRecvLen)\r
+{\r
+    EMUprotocolParseCmdType emCmdType = UPROTOCOL_CMD_IGNORE;\r
+    GU8  puchRespondBuffer[GH3X2X_UPROTOCOL_PAYLOAD_LEN_MAX] = {0};\r
+    GU16 usRespondLen = 0;\r
+    GU32 unFuncMode   = 0;\r
+    emCmdType = GH3X2X_UprotocolParseHandler(puchRespondBuffer, &usRespondLen, puchProtocolDataBuffer, usRecvLen);\r
+    /* if respond buffer len is 0, and return value is UPROTOCOL_CMD_IGNORE,\r
+        it means driver lib can't analyze this protocol data */\r
+    if ((0 == puchRespondBuffer[3]) && (UPROTOCOL_CMD_IGNORE == emCmdType))\r
+    {\r
+#ifdef GOODIX_DEMO_PLATFORM\r
+        GOODIX_PLATFORM_PROTOCOL_ANALYZE_ENTITY();\r
+#else\r
+        GH3X2X_INFO_LOG("Driver lib can't analyze this protocol,skip it,or you can add code to process it.\r\n");\r
+        return;\r
+#endif\r
+    }\r
+    else\r
+    {\r
+#ifdef GOODIX_DEMO_PLATFORM\r
+        GOODIX_PLATFORM_CMD_PROCESS_ENTITY();\r
+#else\r
+        if ((UPROTOCOL_CMD_START == emCmdType) || (UPROTOCOL_CMD_STOP == emCmdType))\r
+        {\r
+            unFuncMode = GH3X2X_GetTargetFuncMode();\r
+            Gh3x2xDemoSamplingControl(unFuncMode, emCmdType);\r
+            GH3X2X_INFO_LOG("[%s]:function = 0x%08x, ctrl = %d\r\n", __FUNCTION__, unFuncMode, emCmdType);\r
+        }\r
+#endif\r
+        if (UPROTOCOL_CMD_MPT_MODE == emCmdType)\r
+        {\r
+            g_uchDemoWorkMode = GH3X2X_DEMO_WORK_MODE_MPT;\r
+            GH3X2X_SetSingleChipModeEnableFlag(1);\r
+        }\r
+        if(g_uchDemoWorkMode != GH3X2X_DEMO_WORK_MODE_MPT)\r
+        {\r
+            GH3X2X_SetSingleChipModeEnableFlag(0);\r
+        }\r
+        Gh3x2xDemoSendProtocolData(puchRespondBuffer, usRespondLen);\r
+    }\r
+}\r
+\r
+void Gh3x2xDemoHandleRecvUartData(GU8 uchRecvByte)\r
+{\r
+    switch (g_uchRxByteStreamState)\r
+    {\r
+    case RX_STREAM_STATE_WAIT_UART_HEADER_47:\r
+        if (GH3X2X_PROTOCOL_BLE_UART_47 == uchRecvByte)\r
+        {\r
+            g_uchRxByteStreamState++;\r
+        }\r
+        else\r
+        {\r
+            g_uchRxByteStreamState = RX_STREAM_STATE_WAIT_UART_HEADER_47;\r
+        }\r
+        break;\r
+    case RX_STREAM_STATE_WAIT_UART_HEADER_44:\r
+        if (GH3X2X_PROTOCOL_BLE_UART_44 == uchRecvByte)\r
+        {\r
+            g_uchRxByteStreamState++;\r
+        }\r
+        else\r
+        {\r
+            g_uchRxByteStreamState = RX_STREAM_STATE_WAIT_UART_HEADER_47;\r
+        }\r
+        /* code */\r
+        break;\r
+    case RX_STREAM_STATE_WAIT_UART_LEN:\r
+        if (uchRecvByte > 0)\r
+        {\r
+            g_usUartPayloadLen = uchRecvByte;\r
+            g_usRxProtocolDataIndex = 0;\r
+            g_uchRxByteStreamState++;\r
+        }\r
+        else\r
+        {\r
+            g_uchRxByteStreamState = RX_STREAM_STATE_WAIT_UART_HEADER_47;\r
+        }        \r
+        break;\r
+    case RX_STREAM_STATE_WAIT_UART_DATA:\r
+        g_puchProtocolBufferRecv[g_usRxProtocolDataIndex] = uchRecvByte;\r
+        g_usRxProtocolDataIndex++;\r
+        if (g_usRxProtocolDataIndex >= g_usUartPayloadLen)\r
+        {\r
+            g_uchRxByteStreamState++;\r
+        }        \r
+        break;\r
+    case RX_STREAM_STATE_WAIT_TAIL:\r
+        if (GH3X2X_PROTOCOL_BLE_TAIL == uchRecvByte)\r
+        {\r
+            Gh3x2xDemoOneFrameDataProcess(g_puchProtocolBufferRecv, g_usRxProtocolDataIndex);\r
+        }\r
+        g_uchRxByteStreamState  = RX_STREAM_STATE_WAIT_UART_HEADER_47;       \r
+        break;\r
+    default:\r
+        g_usRxProtocolDataIndex = 0;\r
+        g_usUartPayloadLen       = 0;\r
+        g_uchRxByteStreamState  = RX_STREAM_STATE_WAIT_UART_HEADER_47;\r
+        break;\r
+    }\r
+}\r
+\r
+void Gh3x2xDemoHandleRecvBleData(GU8 uchRecvByte)\r
+{\r
+    switch (g_uchRxByteStreamState)\r
+    {\r
+    case RX_BYTE_STREAM_STATE_WAIT_HEADER:\r
+       if (GH3X2X_PROTOCOL_HEADER == uchRecvByte)\r
+       {\r
+           g_puchProtocolBufferRecv[g_usRxProtocolDataIndex] = uchRecvByte;\r
+           g_uchRxByteStreamState++;\r
+           g_usRxProtocolDataIndex++;\r
+       }\r
+       else\r
+       {\r
+           g_usRxProtocolDataIndex = 0; \r
+           g_uchRxByteStreamState  = RX_BYTE_STREAM_STATE_WAIT_HEADER;\r
+       }\r
+       break;\r
+    case RX_BYTE_STREAM_STATE_WAIT_VERSION:\r
+       if (GH3X2X_PROTOCOL_VERSION == uchRecvByte)\r
+       {\r
+           g_puchProtocolBufferRecv[g_usRxProtocolDataIndex] = uchRecvByte;\r
+           g_uchRxByteStreamState++;\r
+           g_usRxProtocolDataIndex++;\r
+       }\r
+       else\r
+       {\r
+           g_usRxProtocolDataIndex = 0; \r
+           g_uchRxByteStreamState  = RX_BYTE_STREAM_STATE_WAIT_HEADER;\r
+       }\r
+       break;\r
+    case RX_BYTE_STREAM_STATE_WAIT_CMD:\r
+        g_puchProtocolBufferRecv[g_usRxProtocolDataIndex] = uchRecvByte;\r
+        g_uchRxByteStreamState++;\r
+        g_usRxProtocolDataIndex++;\r
+        break;\r
+    case RX_BYTE_STREAM_STATE_WAIT_LEN:\r
+        if (uchRecvByte > 0)\r
+        {\r
+            g_puchProtocolBufferRecv[g_usRxProtocolDataIndex] = uchRecvByte;\r
+            g_uchRxByteStreamState++;\r
+            g_usRxProtocolDataIndex++;\r
+        }\r
+        else\r
+        {\r
+            g_usRxProtocolDataIndex = 0;\r
+            g_uchRxByteStreamState  = RX_BYTE_STREAM_STATE_WAIT_HEADER;\r
+        }        \r
+        break;       \r
+    case RX_BYTE_STREAM_STATE_WAIT_DATA:\r
+        g_puchProtocolBufferRecv[g_usRxProtocolDataIndex] = uchRecvByte;\r
+        g_usRxProtocolDataIndex++;\r
+        if (g_usRxProtocolDataIndex >= g_puchProtocolBufferRecv[GH3X2X_PROTOCOL_LEN_INDEX] + GH3X2X_PROTOCOL_HEADER_LEN)\r
+        {\r
+            g_uchRxByteStreamState++;\r
+        }\r
+        break;\r
+    case RX_BYTE_STREAM_STATE_WAIT_CRC8:\r
+        g_puchProtocolBufferRecv[g_usRxProtocolDataIndex] = uchRecvByte;\r
+        g_usRxProtocolDataIndex++;\r
+        Gh3x2xDemoOneFrameDataProcess(g_puchProtocolBufferRecv, g_usRxProtocolDataIndex);\r
+        g_usRxProtocolDataIndex = 0;\r
+        g_uchRxByteStreamState  = RX_BYTE_STREAM_STATE_WAIT_HEADER;\r
+        break;\r
+    default:\r
+        g_usRxProtocolDataIndex = 0;\r
+        g_uchRxByteStreamState  = RX_BYTE_STREAM_STATE_WAIT_HEADER;\r
+        break;\r
+    }\r
+}\r
+\r
+/**\r
+ * @fn     void Gh3x2xDemoProtocolProcess(GU8* puchProtocolDataBuffer, GU16 usRecvLen)\r
+ *\r
+ * @brief  Analyze protocol about GH3x2x,and pack protocol data to reply\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]  puchProtocolDataBuffer   pointer to received protocol data buffer\r
+ * @param[in]  usRecvLen                protocol data buffer length\r
+ *\r
+ * @return  None\r
+ */\r
+void Gh3x2xDemoProtocolProcess(GU8* puchProtocolDataBuffer, GU16 usRecvLen)\r
+{\r
+    GU16 uchIndex = 0;\r
+    for (uchIndex = 0; uchIndex < usRecvLen; uchIndex++)\r
+    {\r
+        #if (__PROTOCOL_SERIAL_TYPE__ == __PROTOCOL_SERIAL_USE_UART__)\r
+        //Gh3x2xDemoHandleRecvUartData(puchProtocolDataBuffer[uchIndex]);\r
+        Gh3x2xDemoHandleRecvBleData(puchProtocolDataBuffer[uchIndex]);\r
+        #else\r
+        Gh3x2xDemoHandleRecvBleData(puchProtocolDataBuffer[uchIndex]);\r
+        #endif\r
+    }\r
+}\r
+\r
+/**\r
+ * @fn     void Gh3x2xDemoReportEvent(GU16 usEvent,GU8 uchWearType)\r
+ *\r
+ * @brief  Report event to APP/EVK\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   usEvent      GH3x2x event\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+\r
+void Gh3x2xDemoReportEvent(GU16 usEvent,GU8 uchEventEx)\r
+{\r
+    //GOODIX_PLATFORM_REPORT_EVRENT_ENTITY();\r
+    //u16 usEventTemp = usEvent & (~GH3X2X_IRQ_MSK_FIFO_FULL_BIT);  // fifo full event no need to report\r
+\r
+    if(GhGsMoveDetecterIsEnable())   //is in multi-sensor wear det mode\r
+    {\r
+        usEvent &= ~(GH3X2X_IRQ_MSK_WEAR_ON_BIT);   //ignore wear on event\r
+    }\r
+    usEvent &= (GH3X2X_IRQ_MSK_LEAD_ON_DET_BIT|GH3X2X_IRQ_MSK_LEAD_OFF_DET_BIT|GH3X2X_IRQ_MSK_WEAR_ON_BIT|GH3X2X_IRQ_MSK_WEAR_OFF_BIT|GH3X2X_IRQ_MSK_CHIP_RESET_BIT|GH3X2X_IRQ_MSK_FIFO_FULL_BIT);\r
+\r
+               if((usEvent != 0)||(uchEventEx & (GH3X2X_EVENT_EX_BIT_CHIP0_LEAD_ON|GH3X2X_EVENT_EX_BIT_CHIP0_LEAD_OFF|GH3X2X_EVENT_EX_BIT_CHIP1_LEAD_ON|GH3X2X_EVENT_EX_BIT_CHIP1_LEAD_OFF)))\r
+    {\r
+        Gh3x2x_HalSerialWriteEventToFifo(usEvent,uchEventEx);\r
+    }\r
+}\r
+\r
+#else\r
+\r
+STGh3x2xProtocolData * const g_pstGh3x2xProtocolData = 0;\r
+void Gh3x2xDemoSendProtocolData(GU8* puchProtocolDataBuffer, GU16 usProtocolDataLen){}\r
+void Gh3x2x_HalSerialWriteDataToFifo(GU8 * lpubSource, GU8 lubLen){}\r
+#endif\r
+\r
+\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/kernel/gh_demo_reg_array.c b/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/kernel/gh_demo_reg_array.c
new file mode 100644 (file)
index 0000000..16cd293
--- /dev/null
@@ -0,0 +1,219 @@
+/**\r
+ * @copyright (c) 2003 - 2022, Goodix Co., Ltd. All rights reserved.\r
+ * \r
+ * @file    gh3x2x_demo_reg_array.c\r
+ * \r
+ * @brief   gh3x2x driver lib reg config array\r
+ * \r
+ * @author  Gooidx Iot Team\r
+ * \r
+ */\r
+\r
+#include "gh_demo_config.h"\r
+#include "gh_demo_inner.h"\r
+\r
+/// HR+SPO2+NADT+ADT\r
+const STGh3x2xReg gh3x2x_reg_list0[] =\r
+{\r
+    {0x0004, 0x001F}, {0x0006, 0x0005}, {0x000A, 0x00A0}, {0x000E, 0x000D}, {0x0100, 0x0100}, {0x0102, 0x0302},\r
+    {0x0104, 0x0504}, {0x010A, 0x277C}, {0x0110, 0x0D14}, {0x0112, 0x5555}, {0x0114, 0x00AA}, {0x011E, 0x0019},\r
+    {0x0120, 0x0400}, {0x0122, 0x0CBF}, {0x0126, 0x2744}, {0x0128, 0x0001}, {0x012A, 0x0000}, {0x012C, 0x0D16},\r
+    {0x012E, 0x4441}, {0x0130, 0x0002}, {0x013A, 0x0219}, {0x013C, 0x0400}, {0x013E, 0x197F}, {0x0142, 0x2744},\r
+    {0x0144, 0x0001}, {0x0146, 0x0000}, {0x0148, 0x0D16}, {0x014A, 0x4441}, {0x014C, 0x0002}, {0x0156, 0x0119},\r
+    {0x0158, 0x0400}, {0x015A, 0x197F}, {0x015E, 0x2744}, {0x0160, 0x0001}, {0x0162, 0x0000}, {0x0164, 0x0C10},\r
+    {0x0166, 0x4442}, {0x0168, 0x0002}, {0x0172, 0x010C}, {0x0174, 0x0400}, {0x017A, 0x2744}, {0x017C, 0x0001},\r
+    {0x017E, 0x0000}, {0x0180, 0x0000}, {0x0182, 0x4442}, {0x0184, 0x0002}, {0x018E, 0x0400}, {0x0190, 0x0400},\r
+    {0x0196, 0xC704}, {0x0198, 0x0001}, {0x019A, 0x0000}, {0x019C, 0x0C10}, {0x019E, 0x4442}, {0x01A0, 0x0002},\r
+    {0x01A6, 0x0003}, {0x01AA, 0x010C}, {0x01AC, 0x0400}, {0x01EC, 0x0172}, {0x01EE, 0x034A}, {0x01F0, 0x034A},\r
+    {0x01F2, 0x00E8}, {0x01F4, 0x006A}, {0x01F6, 0x00E8}, {0x0200, 0x0120}, {0x0280, 0x0A00}, {0x0282, 0xF530},\r
+    {0x0284, 0x9388}, {0x0286, 0xC45C}, {0x0288, 0xA328}, {0x0408, 0x0001}, {0x0410, 0x49F0}, {0x0412, 0x0082},\r
+    {0x0414, 0x49F0}, {0x0416, 0x0082}, {0x0422, 0x0011}, {0x0424, 0x0901}, {0x0426, 0x0102}, {0x0428, 0x0102},\r
+    {0x0502, 0x4F60}, {0x0504, 0x000A}, {0x0506, 0x00A1}, {0x0588, 0x0008}, {0x0692, 0x0233}, {0x0694, 0x0400},\r
+    {0x0698, 0x2310}, {0x0700, 0x0000}, {0x1000, 0x0000}, {0x1002, 0x3197}, {0x1004, 0x0000}, {0x1006, 0x6925},\r
+    {0x1008, 0x2D17}, {0x100A, 0x0001}, {0x10E0, 0x0000}, {0x10E2, 0x0000}, {0x10E4, 0x00FF}, {0x10E6, 0xFFFF},\r
+    {0x10E8, 0x0202}, {0x10EA, 0x0202}, {0x10EC, 0x0202}, {0x10EE, 0x0202}, {0x1120, 0x00A0}, {0x1122, 0x0005},\r
+    {0x1124, 0x0000}, {0x1140, 0x0000}, {0x1142, 0x00C8}, {0x1144, 0x0001}, {0x1160, 0x0007}, {0x1162, 0x0000},\r
+    {0x1164, 0x0402}, {0x1166, 0x4568}, {0x1168, 0x9940}, {0x116A, 0x00D9}, {0x116C, 0x8800}, {0x116E, 0x0093},\r
+    {0x1170, 0x5C00}, {0x1172, 0x00C4}, {0x1174, 0x2800}, {0x1176, 0x00A3}, {0x2000, 0x0001}, {0x2002, 0x00A2},\r
+    {0x2022, 0x0004}, {0x2024, 0x0901}, {0x2026, 0x1911}, {0x20CC, 0x0002}, {0x20CE, 0x4223}, {0x2132, 0x0003},\r
+    {0x2134, 0x6201}, {0x2136, 0x0085}, {0x2880, 0x0005}, {0x2882, 0x0019}, {0x288C, 0x0019}, {0x2892, 0x0019},\r
+    {0x3000, 0x0001}, {0x3002, 0x0000}, {0x3004, 0x49F0}, {0x3006, 0x0082}, {0xFFFF, 0x0001}\r
+};\r
+\r
+#if (__GH3X2X_CFG_LIST_MAX_NUM__ > 1)\r
+//ecg\r
+const STGh3x2xReg gh3x2x_reg_list1[] =\r
+{\r
+    //ecg single chip(256hz)\r
+    {0x0000, 0x0602}, {0x0004, 0x0018}, {0x0006, 0x0001}, {0x000A, 0x005F}, {0x000E, 0x000D}, {0x0074, 0x0050},\r
+    {0x0100, 0x0100}, {0x010A, 0x0462}, {0x010C, 0x0000}, {0x010E, 0x0000}, {0x0110, 0x0000}, {0x011E, 0x0400},\r
+    {0x0120, 0x0400}, {0x0126, 0xC704}, {0x0128, 0x0001}, {0x012A, 0x0000}, {0x012C, 0x0C10}, {0x012E, 0x4442},\r
+    {0x0130, 0x0002}, {0x0136, 0x0003}, {0x013A, 0x010C}, {0x013C, 0x0400}, {0x01EA, 0x0033}, {0x01EC, 0x0030},\r
+    {0x01EE, 0x00E8}, {0x0200, 0x1020}, {0x0402, 0x5555}, {0x0404, 0x4120}, {0x0406, 0x0041}, {0x0408, 0x0001},\r
+    {0x0410, 0x49F0}, {0x0412, 0x0082}, {0x0414, 0x49F0}, {0x0416, 0x0082}, {0x0422, 0x0011}, {0x0424, 0x0901},\r
+    {0x0426, 0x0109}, {0x0428, 0x0108}, {0x0480, 0x6550}, {0x0502, 0x4C66}, {0x0506, 0x0020}, {0x0588, 0x0008},\r
+    {0x0692, 0x0233}, {0x0694, 0x0404}, {0x0698, 0x3310}, {0x069A, 0x1101}, {0x0700, 0x0000}, {0x0400, 0x5557},\r
+    {0x1000, 0x0000}, {0x1002, 0x3197}, {0x1004, 0x0000}, {0x1006, 0xE016}, {0x1008, 0x2D04}, {0x100A, 0x0001},\r
+    {0x10E0, 0x00FF}, {0x10E2, 0xFFFF}, {0x10E4, 0xFFFF}, {0x10E6, 0xFFFF}, {0x10E8, 0x0202}, {0x10EA, 0x0202},\r
+    {0x10EC, 0x0202}, {0x10EE, 0x0202}, {0x1120, 0x005F}, {0x1122, 0x0005}, {0x1124, 0x0000}, {0x2000, 0x0001},\r
+    {0x2002, 0x0022}, {0x20EE, 0x0001}, {0x20F0, 0x001C}, {0x2880, 0x0005}, {0x288E, 0x00FA}, {0x3000, 0x0101},\r
+    {0x3002, 0x0000}, {0x3004, 0x49F0}, {0x3006, 0x0082}, {0x4500, 0x46C9}, {0x4502, 0x0F0F}, {0x4504, 0x0002},\r
+    {0x4506, 0x0100}, {0xFFFF, 0x0001}\r
+};\r
+#endif /* (__GH3X2X_CFG_LIST_MAX_NUM__ > 1) */\r
+\r
+#if (__GH3X2X_CFG_LIST_MAX_NUM__ > 2)\r
+const STGh3x2xReg gh3x2x_reg_list2[] =\r
+{\r
+    //ecg master 500Hz  Rtype 5M\r
+    #if __GH3X2X_ECG_RTYPE_5M__\r
+    {0x0000, 0x0610}, {0x0004, 0x0013}, {0x000A, 0x005F}, {0x000E, 0x000D}, {0x0074, 0x0050}, {0x0100, 0x0100},\r
+    {0x010A, 0x01E2}, {0x010C, 0x0000}, {0x010E, 0x0000}, {0x0110, 0x0000}, {0x0120, 0x0400}, {0x0126, 0xC73C},\r
+    {0x012C, 0x0C10}, {0x012E, 0x2222}, {0x0130, 0x00AA}, {0x0136, 0x00FF}, {0x013C, 0x0400}, {0x01EA, 0x0033},\r
+    {0x01EC, 0x0030}, {0x01EE, 0x0098}, {0x0200, 0x1020}, {0x0208, 0x0001}, {0x0402, 0x5555}, {0x0404, 0x4130},\r
+    {0x0406, 0x0041}, {0x0408, 0x0001}, {0x0426, 0x0101}, {0x0428, 0x0101}, {0x0480, 0x6550}, {0x0502, 0x4C66},\r
+    {0x0588, 0x0008}, {0x0692, 0x0233}, {0x0694, 0x0404}, {0x0698, 0x3310}, {0x069A, 0x1101}, {0x0700, 0x0000},\r
+    {0x0400, 0x5557}, {0x1000, 0x0000}, {0x1002, 0x3190}, {0x1004, 0x0000}, {0x1006, 0xAB08}, {0x1008, 0x2937},\r
+    {0x100A, 0x0001}, {0x10E0, 0x0000}, {0x10E2, 0xFFFF}, {0x10E4, 0xFFFF}, {0x10E6, 0xFFFF}, {0x10E8, 0x0202},\r
+    {0x10EA, 0x0202}, {0x10EC, 0x0202}, {0x10EE, 0x0202}, {0x1120, 0x005F}, {0x1122, 0x0005}, {0x1124, 0x0000},\r
+    {0x2000, 0x0004}, {0x2002, 0x2D25}, {0x2004, 0x3D35}, {0x20EE, 0x0001}, {0x20F0, 0x001C}, {0x2880, 0x0005},\r
+    {0x288E, 0x01F4}, {0x3000, 0x0101}, {0x3002, 0x0000}, {0x3004, 0x0000}, {0x3006, 0x0000}, {0x4500, 0x46C9},\r
+    {0x4502, 0x0F0F}, {0x4504, 0x000A}, {0x4506, 0x0320}, {0x45C0, 0x0000}, {0x45C2, 0x0000}, {0x45C4, 0x0000},\r
+    {0x45C6, 0x0000}, {0xFFFF, 0x0001}, \r
+    #else\r
+    {0x0000, 0x0610}, {0x0004, 0x0013}, {0x000A, 0x005F}, {0x000E, 0x000D}, {0x0074, 0x0050}, {0x0100, 0x0100},\r
+    {0x010A, 0x01E2}, {0x010C, 0x0000}, {0x010E, 0x0000}, {0x0110, 0x0000}, {0x0120, 0x0400}, {0x0126, 0xC73C},\r
+    {0x012C, 0x0C10}, {0x012E, 0x2222}, {0x0130, 0x00AA}, {0x0136, 0x00FF}, {0x013C, 0x0400}, {0x01EA, 0x0033},\r
+    {0x01EC, 0x0030}, {0x01EE, 0x0098}, {0x0200, 0x1020}, {0x0208, 0x0001}, {0x0402, 0x5555}, {0x0404, 0x4120},\r
+    {0x0406, 0x0041}, {0x0408, 0x0001}, {0x0426, 0x0101}, {0x0428, 0x0101}, {0x0480, 0x6550}, {0x0502, 0x4C66},\r
+    {0x0588, 0x0008}, {0x0692, 0x0233}, {0x0694, 0x0404}, {0x0698, 0x3310}, {0x069A, 0x1101}, {0x0700, 0x0000},\r
+    {0x0400, 0x5557}, {0x1000, 0x0000}, {0x1002, 0x3190}, {0x1004, 0x0000}, {0x1006, 0x212D}, {0x1008, 0x293A},\r
+    {0x100A, 0x0001}, {0x10E0, 0x0000}, {0x10E2, 0xFFFF}, {0x10E4, 0xFFFF}, {0x10E6, 0xFFFF}, {0x10E8, 0x0202},\r
+    {0x10EA, 0x0202}, {0x10EC, 0x0202}, {0x10EE, 0x0202}, {0x1120, 0x005F}, {0x1122, 0x0005}, {0x1124, 0x0000},\r
+    {0x2000, 0x0004}, {0x2002, 0x2D25}, {0x2004, 0x3D35}, {0x20EE, 0x0001}, {0x20F0, 0x001C}, {0x2880, 0x0005},\r
+    {0x288E, 0x01F4}, {0x3000, 0x0101}, {0x3002, 0x0000}, {0x3004, 0x0000}, {0x3006, 0x0000}, {0x4500, 0x46C9},\r
+    {0x4502, 0x0F0F}, {0x4504, 0x000A}, {0x4506, 0x0320}, {0x45C0, 0x0000}, {0x45C2, 0x0000}, {0x45C4, 0x0000},\r
+    {0x45C6, 0x0000}, {0xFFFF, 0x0001}, \r
+\r
+    #endif\r
+\r
+};\r
+#endif /* (__GH3X2X_CFG_LIST_MAX_NUM__ > 2) */\r
+\r
+#if (__GH3X2X_CFG_LIST_MAX_NUM__ > 3)\r
+const STGh3x2xReg gh3x2x_reg_list3[] =\r
+{\r
+    {0,0},\r
+};\r
+#endif /* (__GH3X2X_CFG_LIST_MAX_NUM__ > 3) */\r
+\r
+#if (__GH3X2X_CFG_LIST_MAX_NUM__ > 4)\r
+const STGh3x2xReg gh3x2x_reg_list4[] =\r
+{\r
+    {0,0},\r
+};\r
+#endif /* (__GH3X2X_CFG_LIST_MAX_NUM__ > 4) */\r
+\r
+#if (__GH3X2X_CFG_LIST_MAX_NUM__ > 5)\r
+const STGh3x2xReg gh3x2x_reg_list5[] =\r
+{\r
+    {0,0},\r
+};\r
+#endif /* (__GH3X2X_CFG_LIST_MAX_NUM__ > 5) */\r
+\r
+#if (__GH3X2X_CFG_LIST_MAX_NUM__ > 6)\r
+const STGh3x2xReg gh3x2x_reg_list6[] =\r
+{\r
+    {0,0},\r
+};\r
+#endif /* (__GH3X2X_CFG_LIST_MAX_NUM__ > 6) */\r
+\r
+#if (__GH3X2X_CFG_LIST_MAX_NUM__ > 7)\r
+const STGh3x2xReg gh3x2x_reg_list7[] =\r
+{\r
+    {0,0},\r
+};\r
+#endif /* (__GH3X2X_CFG_LIST_MAX_NUM__ > 7) */\r
+\r
+const STGh3x2xInitConfig g_stGh3x2xCfgListArr[__GH3X2X_CFG_LIST_MAX_NUM__] = \r
+{\r
+    {gh3x2x_reg_list0,sizeof(gh3x2x_reg_list0) / sizeof(gh3x2x_reg_list0[0])},\r
+    #if (__GH3X2X_CFG_LIST_MAX_NUM__ > 1)\r
+    {gh3x2x_reg_list1,sizeof(gh3x2x_reg_list1) / sizeof(gh3x2x_reg_list1[0])},\r
+    #endif /* (__GH3X2X_CFG_LIST_MAX_NUM__ > 1) */\r
+    #if (__GH3X2X_CFG_LIST_MAX_NUM__ > 2)\r
+    {gh3x2x_reg_list2,sizeof(gh3x2x_reg_list2) / sizeof(gh3x2x_reg_list2[0])},\r
+    #endif /* (__GH3X2X_CFG_LIST_MAX_NUM__ > 2) */\r
+    #if (__GH3X2X_CFG_LIST_MAX_NUM__ > 3)\r
+    {gh3x2x_reg_list3,sizeof(gh3x2x_reg_list3) / sizeof(gh3x2x_reg_list3[0])},\r
+    #endif /* (__GH3X2X_CFG_LIST_MAX_NUM__ > 3) */\r
+    #if (__GH3X2X_CFG_LIST_MAX_NUM__ > 4)\r
+    {gh3x2x_reg_list4,sizeof(gh3x2x_reg_list4) / sizeof(gh3x2x_reg_list4[0])},\r
+    #endif /* (__GH3X2X_CFG_LIST_MAX_NUM__ > 4) */\r
+    #if (__GH3X2X_CFG_LIST_MAX_NUM__ > 5)\r
+    {gh3x2x_reg_list5,sizeof(gh3x2x_reg_list5) / sizeof(gh3x2x_reg_list5[0])},\r
+    #endif /* (__GH3X2X_CFG_LIST_MAX_NUM__ > 5) */\r
+    #if (__GH3X2X_CFG_LIST_MAX_NUM__ > 6)\r
+    {gh3x2x_reg_list6,sizeof(gh3x2x_reg_list6) / sizeof(gh3x2x_reg_list6[0])},\r
+    #endif /* (__GH3X2X_CFG_LIST_MAX_NUM__ > 6) */\r
+    #if (__GH3X2X_CFG_LIST_MAX_NUM__ > 7)\r
+    {gh3x2x_reg_list7,sizeof(gh3x2x_reg_list7) / sizeof(gh3x2x_reg_list7[0])},\r
+    #endif /* (__GH3X2X_CFG_LIST_MAX_NUM__ > 7) */\r
+};\r
+\r
+\r
+#if (__GH3X2X_CASCADE_EN__)\r
+const STGh3x2xReg stGh3x2xEcgCascadeSlaveRealReglist[] = \r
+{\r
+\r
+/***Ecg Cascade Slaver: No lead detected****/\r
+#if 0\r
+    {0x0000, 0x06B0}, {0x0004, 0x001F}, {0x000A, 0x0064}, {0x000E, 0x000D}, {0x0100, 0x0800}, {0x010A, 0x01E2},\r
+    {0x010E, 0x0004}, {0x01EA, 0x0033}, {0x01EC, 0x0030}, {0x0200, 0x1020}, {0x0208, 0x0001}, {0x0480, 0x6550},\r
+    {0x0502, 0x4060}, {0x0588, 0x0008}, {0x0692, 0x0233}, {0x0694, 0x0404}, {0x0698, 0x3310}, {0x069A, 0x1101},\r
+    {0x0700, 0x0000},\r
+#endif\r
+    \r
+/***Ecg Cascade Slaver: lead detected****/\r
+#if 1\r
+    //internal 32K :{0x0000, 0x0630},  {0x0074, 0x0050},\r
+    //external 32K :{0x0000, 0x06b0},  {0x0074, 0x00D0},\r
+    #if __GH3X2X_ECG_RTYPE_5M__\r
+    {0x0000, 0x0630}, {0x0004, 0x0013}, {0x000A, 0x005F}, {0x000E, 0x000D}, {0x0074, 0x0050}, {0x0100, 0x0100},\r
+    {0x010A, 0x0162}, {0x010C, 0x0000}, {0x010E, 0x0000}, {0x0110, 0x0000}, {0x0120, 0x0400}, {0x0126, 0xC73C},\r
+    {0x012C, 0x0C10}, {0x012E, 0x2222}, {0x0130, 0x00AA}, {0x0136, 0x00FF}, {0x013C, 0x0400}, {0x01EA, 0x0033},\r
+    {0x01EC, 0x0030}, {0x01EE, 0x0098}, {0x0200, 0x1020}, {0x0402, 0x5555}, {0x0404, 0x4130}, {0x0406, 0x0041},\r
+    {0x0408, 0x0001}, {0x0426, 0x0101}, {0x0428, 0x0101}, {0x0480, 0x6550}, {0x0502, 0x4C66}, {0x0588, 0x0008},\r
+    {0x0692, 0x0233}, {0x0694, 0x0404}, {0x0698, 0x3310}, {0x069A, 0x1101}, {0x0700, 0x0000}, {0x0400, 0x5554},\r
+    {0x1000, 0x0000}, {0x1002, 0x3190}, {0x1004, 0x0000}, {0x1006, 0x72E8}, {0x1008, 0x292F}, {0x100A, 0x0001},\r
+    {0x10E0, 0x0000}, {0x10E2, 0xFFFF}, {0x10E4, 0xFFFF}, {0x10E6, 0xFFFF}, {0x10E8, 0x0202}, {0x10EA, 0x0202},\r
+    {0x10EC, 0x0202}, {0x10EE, 0x0202}, {0x1120, 0x005F}, {0x1122, 0x0005}, {0x1124, 0x0000}, {0x2000, 0x0004},\r
+    {0x2002, 0x2D25}, {0x2004, 0x3D35}, {0x20EE, 0x0001}, {0x20F0, 0x001C}, {0x2880, 0x0005}, {0x288E, 0x01F4},\r
+    {0x3000, 0x0101}, {0x3002, 0x0000}, {0x3004, 0x0000}, {0x3006, 0x0000}, {0x4500, 0x46C9}, {0x4502, 0x0F0F},\r
+    {0x4504, 0x000A}, {0x4506, 0x0320}, {0x45C0, 0x0000}, {0x45C2, 0x0000}, {0x45C4, 0x0000}, {0x45C6, 0x0000},\r
+    {0xFFFF, 0x0001}, \r
+    #else\r
+    {0x0000, 0x0630}, {0x0004, 0x0013}, {0x000A, 0x005F}, {0x000E, 0x000D}, {0x0074, 0x0050}, {0x0100, 0x0100},\r
+    {0x010A, 0x0162}, {0x010C, 0x0000}, {0x010E, 0x0000}, {0x0110, 0x0000}, {0x0120, 0x0400}, {0x0126, 0xC73C},\r
+    {0x012C, 0x0C10}, {0x012E, 0x2222}, {0x0130, 0x00AA}, {0x0136, 0x00FF}, {0x013C, 0x0400}, {0x01EA, 0x0033},\r
+    {0x01EC, 0x0030}, {0x01EE, 0x0098}, {0x0200, 0x1020}, {0x0402, 0x5555}, {0x0404, 0x4120}, {0x0406, 0x0041},\r
+    {0x0408, 0x0001}, {0x0426, 0x0101}, {0x0428, 0x0101}, {0x0480, 0x6550}, {0x0502, 0x4C66}, {0x0588, 0x0008},\r
+    {0x0692, 0x0233}, {0x0694, 0x0404}, {0x0698, 0x3310}, {0x069A, 0x1101}, {0x0700, 0x0000}, {0x0400, 0x5554},\r
+    {0x1000, 0x0000}, {0x1002, 0x3190}, {0x1004, 0x0000}, {0x1006, 0x2184}, {0x1008, 0x293A}, {0x100A, 0x0001},\r
+    {0x10E0, 0x0000}, {0x10E2, 0xFFFF}, {0x10E4, 0xFFFF}, {0x10E6, 0xFFFF}, {0x10E8, 0x0202}, {0x10EA, 0x0202},\r
+    {0x10EC, 0x0202}, {0x10EE, 0x0202}, {0x1120, 0x005F}, {0x1122, 0x0005}, {0x1124, 0x0000}, {0x2000, 0x0004},\r
+    {0x2002, 0x2D25}, {0x2004, 0x3D35}, {0x20EE, 0x0001}, {0x20F0, 0x001C}, {0x2880, 0x0005}, {0x288E, 0x01F4},\r
+    {0x3000, 0x0101}, {0x3002, 0x0000}, {0x3004, 0x0000}, {0x3006, 0x0000}, {0x4500, 0x46C9}, {0x4502, 0x0F0F},\r
+    {0x4504, 0x000A}, {0x4506, 0x0320}, {0x45C0, 0x0000}, {0x45C2, 0x0000}, {0x45C4, 0x0000}, {0x45C6, 0x0000},\r
+    {0xFFFF, 0x0001}, \r
+    #endif\r
+#endif\r
+    \r
+\r
+};\r
+const GU16 g_usEcgCascadeSlaveRealRegLen = sizeof(stGh3x2xEcgCascadeSlaveRealReglist) / sizeof(STGh3x2xReg);\r
+\r
+#else\r
+const GU16 g_usEcgCascadeSlaveRealRegLen = 1;\r
+const STGh3x2xReg stGh3x2xEcgCascadeSlaveRealReglist[1];\r
+#endif\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/kernel/gh_demo_user.c b/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/kernel/gh_demo_user.c
new file mode 100644 (file)
index 0000000..7c291fc
--- /dev/null
@@ -0,0 +1,774 @@
+/**\r
+ * @copyright (c) 2003 - 2022, Goodix Co., Ltd. All rights reserved.\r
+ * \r
+ * @file    gh3x2x_demo_user.c\r
+ * \r
+ * @brief   gh3x2x driver lib demo code that user defined\r
+ * \r
+ * @author  \r
+ * \r
+ */\r
+\r
+/* includes */\r
+#include "stdint.h"\r
+#include "string.h"\r
+#include "gh_drv.h"\r
+#include "gh_demo_config.h"\r
+#include "gh_demo_inner.h"\r
+#include "gh_demo.h"\r
+\r
+#include "pinctrl_porting.h"\r
+#include "hal_gpio.h"\r
+#include "i2c.h"\r
+#include "custom_utils.h"\r
+\r
+#if (__DRIVER_LIB_MODE__ == __DRV_LIB_WITH_ALGO__)\r
+#include "gh3x2x_demo_algo_call.h"\r
+#endif\r
+\r
+#if (__GH3X2X_MP_MODE__)\r
+#include "gh3x2x_mp_common.h"\r
+#endif\r
+\r
+#if ( __GH3X2X_INTERFACE__ == __GH3X2X_INTERFACE_I2C__ )\r
+\r
+#define GH3220_I2C_ADDR 0x14\r
+#define GH3220_I2C_BUS I2C_BUS_2\r
+\r
+#define H_INT S_AGPIO_R6\r
+\r
+/* i2c interface */\r
+/**\r
+ * @fn     void hal_gh3x2x_i2c_init(void)\r
+ * \r
+ * @brief  hal i2c init for gh3x2x\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void hal_gh3x2x_i2c_init(void)\r
+{\r
+\r
+    /* code implement by user */\r
+    GOODIX_PLATFORM_I2C_INIT_ENTITY();\r
+\r
+}\r
+\r
+/**\r
+ * @fn     uint8_t hal_gh3x2x_i2c_write(uint8_t device_id, const uint8_t write_buffer[], uint16_t length)\r
+ * \r
+ * @brief  hal i2c write for gh3x2x\r
+ *\r
+ * @attention   device_id is 8bits, if platform i2c use 7bits addr, should use (device_id >> 1)\r
+ *\r
+ * @param[in]   device_id       device addr\r
+ * @param[in]   write_buffer    write data buffer\r
+ * @param[in]   length          write data len\r
+ * @param[out]  None\r
+ *\r
+ * @return  status\r
+ * @retval  #1      return successfully\r
+ * @retval  #0      return error\r
+ */\r
+GU8 hal_gh3x2x_i2c_write(GU8 device_id, const GU8 write_buffer[], GU16 length)\r
+{\r
+    uint8_t ret = 1;\r
+\r
+    /* code implement by user */\r
+\r
+    // GOODIX_PLATFORM_I2C_WRITE_ENTITY(device_id, write_buffer,length);\r
+    ret = custom_i2c_write_reg(GH3220_I2C_ADDR, 0, 0, write_buffer, length, GH3220_I2C_BUS);\r
+    if(ret == 0)\r
+        ret = 1;\r
+    else\r
+        ret = 0;\r
+    return ret;\r
+}\r
+\r
+/**\r
+ * @fn     uint8_t hal_gh3x2x_i2c_read(uint8_t device_id, const uint8_t write_buffer[], uint16_t write_length,\r
+ *                            uint8_t read_buffer[], uint16_t read_length)\r
+ * \r
+ * @brief  hal i2c read for gh3x2x\r
+ *\r
+ * @attention   device_id is 8bits, if platform i2c use 7bits addr, should use (device_id >> 1)\r
+ *\r
+ * @param[in]   device_id       device addr\r
+ * @param[in]   write_buffer    write data buffer\r
+ * @param[in]   write_length    write data len\r
+ * @param[in]   read_length     read data len\r
+ * @param[out]  read_buffer     pointer to read buffer\r
+ *\r
+ * @return  status\r
+ * @retval  #1      return successfully\r
+ * @retval  #0      return error\r
+ */\r
+GU8 hal_gh3x2x_i2c_read(GU8 device_id, const GU8 write_buffer[], GU16 write_length, GU8 read_buffer[], GU16 read_length)\r
+{\r
+    uint8_t ret = 1;\r
+\r
+    /* code implement by user */\r
+    // custom_i2c_transfer(0x14,write_buffer, write_length, read_buffer, read_length, GH3X2X_I2C_BUS);\r
+    ret = custom_i2c_read_regs(GH3220_I2C_ADDR,write_buffer, write_length, read_buffer, read_length, GH3220_I2C_BUS);\r
+    // GOODIX_PLATFORM_I2C_READ_ENTITY(device_id, write_buffer, write_length, read_buffer, read_length);\r
+    if(ret == 0)\r
+        ret = 1;\r
+    else\r
+        ret = 0;\r
+    return ret;\r
+}\r
+\r
+#else // __GH3X2X_INTERFACE__ == __GH3X2X_INTERFACE_SPI__\r
+\r
+/* spi interface */\r
+/**\r
+ * @fn     void hal_gh3x2x_spi_init(void)\r
+ * \r
+ * @brief  hal spi init for gh3x2x\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+\r
+void hal_gh3x2x_spi_init(void)\r
+{\r
+    /* init spi and cs pin */\r
+    GOODIX_PLATFORM_SPI_INIT_ENTITY();\r
+}\r
+\r
+/**\r
+ * @fn     GU8 hal_gh3x2x_spi_write(GU8 write_buffer[], GU16 length)\r
+ * \r
+ * @brief  hal spi write for gh3x2x\r
+ *\r
+ * @attention   if __GH3X2X_SPI_TYPE__ == __GH3X2X_SPI_TYPE_SOFTWARE_CS__  , user need generate timming: write_buf[0](W) + write_buf[1](W) + ...\r
+ * @attention   if __GH3X2X_SPI_TYPE__ == __GH3X2X_SPI_TYPE_HARDWARE_CS__  , user need generate timming: CS LOW  + write_buf[0](W) + write_buf[1](W) + ... + CS HIGH\r
+ *\r
+ * @param[in]   write_buffer    write data buffer\r
+ * @param[in]   length          write data len\r
+ * @param[out]  None\r
+ *\r
+ * @return  status\r
+ * @retval  #1      return successfully\r
+ * @retval  #0      return error\r
+ */\r
+GU8 hal_gh3x2x_spi_write(GU8 write_buffer[], GU16 length)\r
+{\r
+    GU8 ret = 1;\r
+\r
+    \r
+      GOODIX_PLATFORM_SPI_WRITE_ENTITY(write_buffer, length);\r
+\r
+    return ret;\r
+}\r
+\r
+\r
+#if (__GH3X2X_SPI_TYPE__ == __GH3X2X_SPI_TYPE_SOFTWARE_CS__) \r
+/**\r
+ * @fn     GU8 hal_gh3x2x_spi_read(GU8 read_buffer[], GU16 length)\r
+ * \r
+ * @brief  hal spi read for gh3x2x\r
+ *\r
+ * @attention   user need generate timming: read_buf[0](R) + write_buf[1](R) + ... \r
+ *\r
+ * @param[in]   read_length     read data len\r
+ * @param[out]  read_buffer     pointer to read buffer\r
+ *\r
+ * @return  status\r
+ * @retval  #1      return successfully\r
+ * @retval  #0      return error\r
+ */\r
+GU8 hal_gh3x2x_spi_read(GU8 read_buffer[], GU16 length)\r
+{\r
+    GU8 ret = 1;\r
+\r
+    GOODIX_PLATFORM_SPI_READ_ENTITY();\r
+\r
+    return ret;\r
+}\r
+#elif (__GH3X2X_SPI_TYPE__ == __GH3X2X_SPI_TYPE_HARDWARE_CS__)\r
+/**\r
+ * @fn     GU8 hal_gh3x2x_spi_write_F1_and_read(GU8 read_buffer[], GU16 length)\r
+ * \r
+ * @brief  hal spi write F1 and read for gh3x2x\r
+ *\r
+ * @attention    user need generate timming: CS LOW + F1(W) + read_buf[0](R) + read_buf[1](R) + ... + CS HIGH\r
+ *\r
+ * @param[in]   write_buf     write data\r
+ * @param[in]   length     write data len\r
+ *\r
+ * @return  status\r
+ * @retval  #1      return successfully\r
+ * @retval  #0      return error\r
+ */\r
+GU8 hal_gh3x2x_spi_write_F1_and_read(GU8 read_buffer[], GU16 length)\r
+{\r
+    GU8 ret = 1;\r
+    \r
+     GOODIX_PLATFORM_SPI_READ_ENTITY();\r
+    \r
+    return ret;\r
+}\r
+#endif\r
+\r
+/**\r
+ * @fn     void hal_gh3x2x_spi_cs_ctrl(GU8 cs_pin_level)\r
+ * \r
+ * @brief  hal spi cs pin ctrl for gh3x2x\r
+ *\r
+ * @attention   pin level set 1 [high level] or 0 [low level]\r
+ *\r
+ * @param[in]   cs_pin_level     spi cs pin level\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+#if (__GH3X2X_SPI_TYPE__ == __GH3X2X_SPI_TYPE_SOFTWARE_CS__) \r
+void hal_gh3x2x_spi_cs_ctrl(GU8 cs_pin_level)\r
+{\r
+\r
+    GOODIX_PLATFORM_SPI_CS_CTRL_ENTITY();\r
+\r
+}\r
+#endif\r
+\r
+#endif\r
+\r
+#if __SUPPORT_HARD_RESET_CONFIG__\r
+\r
+/**\r
+ * @fn     void hal_gh3x2x_int_init(void)\r
+ * \r
+ * @brief  gh3x2x int init\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+\r
+\r
+\r
+void hal_gh3x2x_reset_pin_init(void)\r
+{\r
+    GOODIX_PLATFORM_RESET_PIN_INIT_ENTITY();\r
+}\r
+\r
+/**\r
+ * @fn     void hal_gh3x2x_reset_pin_ctrl(GU8 pin_level)\r
+ * \r
+ * @brief  hal reset pin ctrl for gh3x2x\r
+ *\r
+ * @attention   pin level set 1 [high level] or 0 [low level]\r
+ *\r
+ * @param[in]   pin_level     reset pin level\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+\r
+void hal_gh3x2x_reset_pin_ctrl(GU8 pin_level)\r
+{\r
+\r
+   GOODIX_PLATFORM_SPI_RESET_PIN_ENTITY();\r
+}\r
+\r
+#endif\r
+\r
+/**\r
+ * @fn     void hal_gh3x2x_int_init(void)\r
+ * \r
+ * @brief  gh3x2x int init\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void hal_gh3x2x_int_init(void)\r
+{\r
+    // GOODIX_PLATFORM_INT_INIT_ENTITY();\r
+    uapi_pin_set_ie(H_INT,HAL_PIO_IE_ENBALE);\r
+}\r
+\r
+#if (__NORMAL_INT_PROCESS_MODE__ == __INTERRUPT_PROCESS_MODE__ || __MIX_INT_PROCESS_MODE__ == __INTERRUPT_PROCESS_MODE__)\r
+/**\r
+ * @fn     void hal_gh3x2x_int_handler_call_back(void)\r
+ * \r
+ * @brief  call back of gh3x2x int handler\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void hal_gh3x2x_int_handler_call_back(void)\r
+{\r
+    if (Gh3x2xGetInterruptMode() == __NORMAL_INT_PROCESS_MODE__)\r
+    {\r
+        if(GH3X2X_DEMO_WORK_MODE_MPT != g_uchDemoWorkMode)\r
+        {\r
+            g_uchGh3x2xIntCallBackIsCalled = 1;\r
+        }\r
+#if (__GH3X2X_MP_MODE__)\r
+        GH3X2X_MP_SET_INT_FLAG();  //gh3x2x mp test must call it\r
+#endif\r
+        GOODIX_PLATFORM_INT_HANDLER_CALL_BACK_ENTITY();\r
+    }\r
+}\r
+#endif\r
+\r
+/**\r
+ * @fn     void hal_gsensor_start_cache_data(void)\r
+ * \r
+ * @brief  Start cache gsensor data for gh3x2x\r
+ *\r
+ * @attention   This function will be called when start gh3x2x sampling.\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void hal_gsensor_start_cache_data(void)\r
+{\r
+#if (__DRIVER_LIB_MODE__ == __DRV_LIB_WITH_ALGO__)\r
+    GH3X2X_TimestampSyncAccInit();\r
+#endif\r
+    GOODIX_PLATFORM_INT_GS_START_CACHE_ENTITY();\r
+}\r
+\r
+/**\r
+ * @fn     void hal_gsensor_stop_cache_data(void)\r
+ * \r
+ * @brief  Stop cache gsensor data for gh3x2x\r
+ *\r
+ * @attention   This function will be called when stop gh3x2x sampling.\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void hal_gsensor_stop_cache_data(void)\r
+{\r
+        \r
+    GOODIX_PLATFORM_INT_GS_STOP_CACHE_ENTITY();\r
+}\r
+\r
+void hal_cap_start_cache_data(void)\r
+{\r
+    GOODIX_PLATFORM_INT_CAP_START_CACHE_ENTITY();\r
+}\r
+\r
+void hal_cap_stop_cache_data(void)\r
+{\r
+    GOODIX_PLATFORM_INT_CAP_STOP_CACHE_ENTITY();\r
+}\r
+\r
+void hal_temp_start_cache_data(void)\r
+{\r
+    GOODIX_PLATFORM_INT_TEMP_START_CACHE_ENTITY();\r
+}\r
+\r
+void hal_temp_stop_cache_data(void)\r
+{\r
+    GOODIX_PLATFORM_INT_TEMP_STOP_CACHE_ENTITY();\r
+}\r
+\r
+void hal_gh3x2x_write_cap_to_flash(GS32 WearCap1,GS32 UnwearCap1,GS32 WearCap2,GS32 UnwearCap2)\r
+{\r
+    GOODIX_PLATFORM_WRITE_CAP_TO_FLASH_ENTITY();\r
+}\r
+void hal_gh3x2x_read_cap_from_flash(GS32* WearCap1,GS32* UnwearCap1,GS32* WearCap2,GS32* UnwearCap2)\r
+{\r
+    GOODIX_PLATFORM_READ_CAP_FROM_FLASH_ENTITY();\r
+}\r
+\r
+/**\r
+ * @fn     void hal_gsensor_drv_get_fifo_data(STGsensorRawdata gsensor_buffer[], GU16 *gsensor_buffer_index)\r
+ * \r
+ * @brief  get gsensor fifo data\r
+ *\r
+ * @attention   When read fifo data of GH3x2x, will call this function to get corresponding cached gsensor data.\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  gsensor_buffer          pointer to gsensor data buffer\r
+ * @param[out]  gsensor_buffer_index    pointer to number of gsensor data(every gsensor data include x,y,z axis data)\r
+ *\r
+ * @return  None\r
+ */\r
+void hal_gsensor_drv_get_fifo_data(STGsensorRawdata gsensor_buffer[], GU16 *gsensor_buffer_index)\r
+{\r
+/**************************** WARNNING  START***************************************************/\r
+/*  (*gsensor_buffer_index) can not be allowed bigger than __GSENSOR_DATA_BUFFER_SIZE__  ****************/\r
+/* Be care for copying data to gsensor_buffer, length of gsensor_buffer is __GSENSOR_DATA_BUFFER_SIZE__ *****/\r
+/**************************** WARNNING END*****************************************************/\r
+\r
+#if (__DRIVER_LIB_MODE__ == __DRV_LIB_WITH_ALGO__)\r
+    for (int i = 0; i < *gsensor_buffer_index; i++)\r
+    {\r
+        GU32 unTimeStamp = 0;\r
+        /* user set time stamp code here */\r
+        GH3X2X_TimestampSyncFillAccSyncBuffer(unTimeStamp, gsensor_buffer[i].sXAxisVal, gsensor_buffer[i].sYAxisVal, gsensor_buffer[i].sZAxisVal);\r
+    }\r
+#endif\r
+\r
+    GOODIX_PLATFORM_INT_GET_GS_DATA_ENTITY();\r
+\r
+\r
+/**************************** WARNNING: DO NOT REMOVE OR MODIFY THIS CODE   ---START***************************************************/\r
+    if((*gsensor_buffer_index) > (__GSENSOR_DATA_BUFFER_SIZE__))\r
+    {\r
+        while(1);   // Fatal error !!!\r
+    }\r
+/**************************** WARNNING: DO NOT REMOVE OR MODIFY THIS CODE   ---END***************************************************/\r
+}\r
+\r
+void hal_cap_drv_get_fifo_data(STCapRawdata cap_data_buffer[], GU16 *cap_buffer_index)\r
+{\r
+    GOODIX_PLATFORM_INT_GET_CAP_DATA_ENTITY()  ;\r
+    if((*cap_buffer_index) > (__CAP_DATA_BUFFER_SIZE__))\r
+    {\r
+        while(1);   // Fatal error !!!\r
+    }\r
+}\r
+\r
+void hal_temp_drv_get_fifo_data(STTempRawdata temp_data_buffer[], GU16 *temp_buffer_index)\r
+{\r
+    GOODIX_PLATFORM_INT_GET_TEMP_DATA_ENTITY();\r
+    if((*temp_buffer_index) > (__TEMP_DATA_BUFFER_SIZE__))\r
+    {\r
+        while(1);   // Fatal error !!!\r
+    }\r
+}\r
+\r
+#if (__GH3X2X_INFO_LOG_TYPE__)\r
+/**\r
+ * @fn     void GH3X2X_PlatformLog(char *log_string)\r
+ * \r
+ * @brief  for debug version, log\r
+ *\r
+ * @attention   this function must define that use debug version lib\r
+ *\r
+ * @param[in]   log_string      pointer to log string\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+\r
+#if __GH3X2X_INFO_LOG_TYPE__ == __GH3X2X_INFO_LOG_METHOD_0__\r
+void GH3X2X_PlatformLog(GCHAR *log_string)\r
+{\r
+    printf("%s",log_string);\r
+    // GOODIX_PLATFORM_LOG_ENTITY();\r
+}\r
+#endif\r
+\r
+#if __GH3X2X_INFO_LOG_TYPE__ == __GH3X2X_INFO_LOG_METHOD_1__\r
+void GH3X2X_RegisterPrintf(int (**pPrintfUser)(const char *format, ...))\r
+{\r
+    //(*pPrintfUser) = printf;   //use printf in <stdio.h>  or use equivalent function in your platform\r
+    GOODIX_PLATFORM_PRINTF_ENTITY();\r
+}\r
+#endif\r
+\r
+\r
+\r
+\r
+#endif\r
+\r
+/**\r
+ * @fn     void Gh3x2x_BspDelayUs(GU16 usUsec)\r
+ * \r
+ * @brief  Delay in us,user should register this function into driver lib\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+\r
+void Gh3x2x_BspDelayUs(GU16 usUsec)\r
+{\r
+    // GOODIX_PLATFORM_DELAY_US_ENTITY();\r
+    LOS_Udelay(usUsec);\r
+}\r
+\r
+\r
+/**\r
+ * @fn     void Gh3x2x_BspDelayMs(GU16 usMsec)\r
+ * \r
+ * @brief  Delay in ms\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void Gh3x2x_BspDelayMs(GU16 usMsec)\r
+{\r
+    // GOODIX_PLATFORM_DELAY_MS_ENTITY();\r
+    LOS_Mdelay(usMsec);\r
+}\r
+\r
+#if (__GH_MULTI_SENSOR_EVENT_PRO_CONIG__)\r
+\r
+\r
+void Gh3x2x_CreateMultiSensorTimer(GU32 unPeriodMs)\r
+{\r
+    GOODIX_PLATFORM_CREAT_ADT_CONFIRM_ENTITY(unPeriodMs);\r
+}\r
+\r
+\r
+\r
+/**\r
+ * @fn     void Gh3x2x_StartMultiSensorTimer(void)\r
+ * \r
+ * @brief  Start time of adt confirm to get g sensor\r
+ *\r
+ * @attention   None        \r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void Gh3x2x_StartMultiSensorTimer(void)\r
+{\r
+    GH3X2X_DEBUG_LOG("Gh3x2x_StartMultiSensorTimer\r\n");\r
+    GOODIX_PLATFORM_START_TIMER_ENTITY();\r
+}\r
+\r
+\r
+/**\r
+ * @fn     void Gh3x2x_StopMultiSensorTimer(void)\r
+ * \r
+ * @brief  Stop time of adt confirm\r
+ *\r
+ * @attention   None        \r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void Gh3x2x_StopMultiSensorTimer(void)\r
+{\r
+    GH3X2X_DEBUG_LOG("Gh3x2x_StopMultiSensorTimer\r\n");\r
+    GOODIX_PLATFORM_STOP_TIMER_ENTITY();\r
+}\r
+\r
+void Gh3x2x_DeleteMultiSensorTimer(void)\r
+{\r
+    GOODIX_PLATFORM_DEL_TIMER_ENTITY();\r
+}\r
+\r
+\r
+const STGhMultiSensorTimerOps g_stGhMultiSensorTimerOps =\r
+{\r
+    .TimerCreate = Gh3x2x_CreateMultiSensorTimer,\r
+    .TimerStart = Gh3x2x_StartMultiSensorTimer,\r
+    .TimerStop = Gh3x2x_StopMultiSensorTimer,\r
+    .TimerDelete = Gh3x2x_DeleteMultiSensorTimer,\r
+};\r
+#endif\r
+\r
+\r
+\r
+\r
+/**\r
+ * @fn     void Gh3x2x_UserHandleCurrentInfo(void)\r
+ * \r
+ * @brief  handle gh3x2x chip current information for user\r
+ *\r
+ * @attention   None        \r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void Gh3x2x_UserHandleCurrentInfo(void)\r
+{\r
+    //read or write  slotx current\r
+\r
+    //GH3X2X_GetSlotLedCurrent(0,0); //read slot 0  drv 0\r
+    //GH3X2X_GetSlotLedCurrent(1,0); // read  slot 1  drv 0\r
+\r
+    //GH3X2X_SlotLedCurrentConfig(0,0,50);  //set slot0 drv0 50 LSB\r
+    //GH3X2X_SlotLedCurrentConfig(1,0,50);  //set slot1 drv0 50 LSB\r
+}\r
+\r
+#if (__SUPPORT_PROTOCOL_ANALYZE__)\r
+/**\r
+ * @fn     void Gh3x2x_HalSerialSendData(GU8* uchTxDataBuf, GU16 usBufLen)\r
+ *\r
+ * @brief  Serial send data\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   uchTxDataBuf        pointer to data buffer to be transmitted\r
+ * @param[in]   usBufLen            data buffer length\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void Gh3x2x_HalSerialSendData(GU8* uchTxDataBuf, GU16 usBufLen)\r
+{\r
+    GOODIX_PLATFORM_SERIAL_SEND_ENTITY();\r
+}\r
+\r
+\r
+/**\r
+ * @fn      void Gh3x2xSerialSendTimerInit(GU8 uchPeriodMs)\r
+ *\r
+ * @brief  Gh3x2xSerialSendTimerInit\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   uchPeriodMs    timer period (ms)\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void Gh3x2xSerialSendTimerInit(GU8 uchPeriodMs)\r
+{\r
+    \r
+}\r
+\r
+\r
+/**\r
+ * @fn     void Gh3x2xSerialSendTimerStop(void)\r
+ *\r
+ * @brief  Serial send timer stop\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void Gh3x2xSerialSendTimerStop(void)\r
+{\r
+    GOODIX_PLATFORM_SERIAL_TIMER_STOP_ENTITY();\r
+}\r
+\r
+\r
+\r
+/**\r
+ * @fn     void Gh3x2xSerialSendTimerStart(void)\r
+ *\r
+ * @brief  Serial send timer start\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void Gh3x2xSerialSendTimerStart(void)\r
+{\r
+    GOODIX_PLATFORM_SERIAL_TIMER_START_ENTITY();\r
+}\r
+\r
+#endif\r
+\r
+\r
+\r
+\r
+\r
+void* Gh3x2xMallocUser(GU32 unMemSize)\r
+{\r
+#if (__USER_DYNAMIC_DRV_BUF_EN__)\r
+#ifdef GOODIX_DEMO_PLATFORM\r
+    GOODIX_PLATFORM_MALLOC_USER_ENTITY();\r
+#else\r
+    //return malloc(unMemSize);\r
+    return 0;\r
+#endif\r
+#else\r
+    return 0;\r
+#endif\r
+}\r
+\r
+void Gh3x2xFreeUser(void* MemAddr)\r
+{\r
+#if (__USER_DYNAMIC_DRV_BUF_EN__)\r
+    GOODIX_PLATFORM_FREE_USER_ENTITY();\r
+    //free(MemAddr);\r
+#endif\r
+}\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+#if ( __FUNC_TYPE_BP_ENABLE__ && (__GH3X2X_INTERFACE__ == __GH3X2X_INTERFACE_I2C__))\r
+/**\r
+ * @fn     GS8 gh3x2x_write_pressure_parameters(GS32 *buffer)\r
+ * \r
+ * @brief  gh3x2x get pressure value\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[out]   buffer     buffer[0] = rawdata_a0,\r
+ *                          buffer[1] = rawdata_a1,\r
+ *                          buffer[2] = pressure g value of rawdata_a1,\r
+ *\r
+ * @return  error code\r
+ */\r
+GS8 gh3x2x_write_pressure_parameters(GS32 *buffer)\r
+{\r
+    return GOODIX_PLATFORM_PRESSURE_PARAS_WRITE_ENTITY();\r
+}\r
+\r
+/**\r
+ * @fn     GS8 gh3x2x_read_pressure_parameters(GS32 *buffer)\r
+ * \r
+ * @brief  gh3x2x get pressure value\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[out]   buffer     buffer[0] = area,\r
+ *                          buffer[1] = rawdata_a0,\r
+ *                          buffer[2] = rawdata_a1,\r
+ *                          buffer[3] = pressure g value,\r
+ *\r
+ * @return  error code\r
+ */\r
+GS8 gh3x2x_read_pressure_parameters(GS32 *buffer)\r
+{\r
+    return GOODIX_PLATFORM_PRESSURE_PARAS_READ_ENTITY();\r
+}\r
+#endif\r
+\r
+\r
+\r
+\r
+\r
+/********END OF FILE********* Copyright (c) 2003 - 2022, Goodix Co., Ltd. ********/\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/kernel/gh_demo_version.h b/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/kernel/gh_demo_version.h
new file mode 100644 (file)
index 0000000..9c897ee
--- /dev/null
@@ -0,0 +1,41 @@
+/**\r
+ * @copyright (c) 2003 - 2022, Goodix Co., Ltd. All rights reserved.\r
+ *\r
+ * @file    gh3x2x_demo_version.h\r
+ *\r
+ * @brief   gh3x2x demo code version\r
+ *\r
+ * @version ref gh3x2x_demo_version.h\r
+ *\r
+ */\r
+\r
+#ifndef _GH3X2X_DEMO_VERSION_H_\r
+#define _GH3X2X_DEMO_VERSION_H_\r
+\r
+#include "gh_demo_config.h"\r
+\r
+#if (__DRIVER_LIB_MODE__ == __DRV_LIB_WITH_ALGO__)\r
+#include "gh3x2x_demo_algo_call_version.h"\r
+#endif\r
+\r
+#define   GH3X2X_DEMO_MAJOR_VERSION_NUMBER        1      /**< major version number */\r
+#define   GH3X2X_DEMO_MINOR_VERSION_NUMBER        6      /**< minor version number */\r
+\r
+#define   GH3X2X_TO_STRING(x)       #x                      /**< number to char */\r
+#define   GH3X2X_STR(x)             GH3X2X_TO_STRING(x)     /**< number to char */\r
+\r
+#if (__DRIVER_LIB_MODE__ == __DRV_LIB_WITH_ALGO__)\r
+#define   GH3X2X_ALGOCALL_EXTRA_VERSION_STRING      "_AC_"\\r
+                                                    "v"GH3X2X_STR(GOODIX_DEMO_MAJOR_VERSION_NUMBER)\\r
+                                                    "."GH3X2X_STR(GOODIX_DEMO_MINOR_VERSION_NUMBER)\r
+#else\r
+#define   GH3X2X_ALGOCALL_EXTRA_VERSION_STRING      "noAlgo"\r
+#endif\r
+\r
+/// makeup version string\r
+#define   GH3X2X_DEMO_VERSION_STRING    "GH(M)3X2X_DEMO_"\\r
+                                        "v"GH3X2X_STR(GH3X2X_DEMO_MAJOR_VERSION_NUMBER)\\r
+                                        "."GH3X2X_STR(GH3X2X_DEMO_MINOR_VERSION_NUMBER)\\r
+                                        GH3X2X_ALGOCALL_EXTRA_VERSION_STRING\\r
+                                        "(build:"__DATE__"_"__TIME__")"\r
+#endif\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/module/gh_agc/gh_agc.c b/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/module/gh_agc/gh_agc.c
new file mode 100644 (file)
index 0000000..6ad1920
--- /dev/null
@@ -0,0 +1,1125 @@
+/**\r
+ * @copyright (c) 2003 - 2022, Goodix Co., Ltd. All rights reserved.\r
+ *\r
+ * @file    gh3x2x_drv_soft_led_agc.c\r
+ *\r
+ * @brief   gh3x2x led agc process functions\r
+ *\r
+ * @version see gh3x2x_drv_version.h\r
+ *\r
+ */\r
+ \r
+#include <stdio.h>\r
+#include "gh_drv_version.h"\r
+#include "gh_drv_common.h"\r
+#include "gh_drv.h"\r
+#include "gh_drv_interface.h"\r
+#include "gh_drv_control.h"\r
+#include "gh_uprotocol.h"\r
+#include "gh_agc.h"\r
+\r
+#include "gh_drv_dump.h"\r
+#include "gh_demo_config.h"\r
+\r
+//#define __SUPPORT_SOFT_AGC_CONFIG__    1\r
+\r
+#define __GH3X2X_AGC_GENERAL_TRIG_H_THD__  ((8388608 + 8388608*0.85f))\r
+#define __GH3X2X_AGC_GENERAL_TRIG_L_THD__  ((8388608 + 8388608*0.15f))\r
+#define __GH3X2X_AGC_GENERAL_IDEAL_VALUE__ ((8388608 + 8388608*0.56f))\r
+#define __GH3X2X_AGC_SPO2_TRIG_H_THD__  ((8388608 + 8388608*0.9f))\r
+#define __GH3X2X_AGC_SPO2_TRIG_L_THD__  ((8388608 + 8388608*0.5f))\r
+#define __GH3X2X_AGC_SPO2_IDEAL_VALUE__  ((8388608 + 8388608*0.7f))\r
+#define __GH3X2X_AGC_CONVERGENCE_LEVEL__  (8)  // The values that can be set are 8, 16 and 32, and the recommended value is 16. The larger the value, the smaller the convergence range of AGC. \r
+\r
+//sub channel\r
+\r
+#define GH3X2X_NEW_AGC_SUB_CHNNL_ANAYLSIS_TIME_SEC 1\r
+\r
+#define GH3X2X_AGC_REG_AGC_EN                     0\r
+#define GH3X2X_AGC_REG_LED_CURRENT_UP_LIMIT       1\r
+#define GH3X2X_AGC_REG_LED_CURRENT_DOWN_LIMIT     2\r
+#define GH3X2X_AGC_REG_LED_CURRENT_DRV0           3\r
+#define GH3X2X_AGC_REG_LED_CURRENT_DRV1           4\r
+#define GH3X2X_AGC_REG_TIA_GAIN_RX0               5\r
+#define GH3X2X_AGC_REG_TIA_GAIN_RX1               6\r
+#define GH3X2X_AGC_REG_TIA_GAIN_RX2               7\r
+#define GH3X2X_AGC_REG_TIA_GAIN_RX3               8\r
+#define GH3X2X_AGC_REG_AGC_SRC                    9\r
+#define GH3X2X_AGC_REG_BG_CANCEL_RX0              10\r
+#define GH3X2X_AGC_REG_BG_CANCEL_RX1              11\r
+#define GH3X2X_AGC_REG_BG_CANCEL_RX2              12\r
+#define GH3X2X_AGC_REG_BG_CANCEL_RX3              13\r
+#define GH3X2X_AGC_REG_SR_MULIPLIPER              14\r
+#define GH3X2X_AGC_ECG_PPG_RX_EN                  15\r
+\r
+\r
+#if __SUPPORT_SOFT_AGC_CONFIG__\r
+//main chnl\r
+STGh3x2xNewAgcMainChnlInfo  g_pstGh3x2xNewAgcMainChnlInfoEntity[GH3X2X_NEW_AGC_SLOT_NUM_LIMIT];\r
+STGh3x2xNewAgcMainChnlMeanInfo g_pstGh3x2xNewAgcMainChnlMeanInfoEntity[GH3X2X_NEW_AGC_SLOT_NUM_LIMIT];\r
+STGh3x2xNewAgcMainChnlIdaelAdjInfo g_pstGh3x2xNewAgcMainChnlIdaelAdjInfoEntity[GH3X2X_NEW_AGC_SLOT_NUM_LIMIT];\r
+//sub chnl\r
+#if GH3X2X_NEW_AGC_SUB_CHNL_NUM_LIMIT > 0\r
+STGh3x2xNewAgcSubChnlRxInfo    g_pstGh3x2xNewAgcSubChnlRxInfoEntity[GH3X2X_NEW_AGC_SUB_CHNL_NUM_LIMIT];\r
+#endif\r
+\r
+\r
+STGh3x2xNewAgcMainChnlSat g_pstGh3x2xNewAgcMainChnlSat;\r
+const GU32 g_unNewAgcSpo2Trig_H_Thd = __GH3X2X_AGC_SPO2_TRIG_H_THD__;\r
+const GU32 g_unNewAgcSpo2Trig_L_Thd = __GH3X2X_AGC_SPO2_TRIG_L_THD__;\r
+const GU32 g_unNewAgcSpo2Ideal_value = __GH3X2X_AGC_SPO2_IDEAL_VALUE__;\r
+const GU32 g_unNewAgcGeneTrig_H_Thd = __GH3X2X_AGC_GENERAL_TRIG_H_THD__;\r
+const GU32 g_unNewAgcGeneTrig_L_Thd = __GH3X2X_AGC_GENERAL_TRIG_L_THD__;\r
+const GU32 g_unNewAgcGeneIdeal_value = __GH3X2X_AGC_GENERAL_IDEAL_VALUE__;\r
+const GU8  g_uchAgcConvergence_level = __GH3X2X_AGC_CONVERGENCE_LEVEL__;\r
+\r
+// soft agc parameter\r
+static STSoftAgcCfg g_stSoftAgcCfg;\r
+extern const GU16 g_usGH3x2xSlotRegBase[8];\r
+extern const STGh3x2xAgcReg g_pstGH3x2xAgcReg[];\r
+extern const GU16 g_usGH3x2xTiaGainR[];\r
+\r
+GU8 g_Gh3x2xNewAgcInitFlag = 0;\r
+\r
+void GH3X2X_StoreRxTiaGainAfterAgc(GU8 uchGain, GU8 uchSlotNo, GU8 uchAdcNo, GU8* puchGainRecord)\r
+{\r
+    puchGainRecord[uchSlotNo*4 + uchAdcNo] = uchGain;\r
+}\r
+\r
+void GH3X2X_StoreDrvCurrentAfterAgc(GU8 DrvCurrent, GU8 uchSlotNo, GU8 uchDrvIndex, GU16* puchDrvCurrentRecord)\r
+{\r
+       if(!uchDrvIndex)\r
+       {\r
+               puchDrvCurrentRecord[uchSlotNo] = (puchDrvCurrentRecord[uchSlotNo]&0xFF00)|DrvCurrent;\r
+       }\r
+       else\r
+       {\r
+         puchDrvCurrentRecord[uchSlotNo] = (puchDrvCurrentRecord[uchSlotNo]&0x00FF)|(DrvCurrent<<8);\r
+       }       \r
+}\r
+\r
+\r
+void GH3x2xNewAgcModuleReset(void)\r
+{\r
+    g_Gh3x2xNewAgcInitFlag = 0;\r
+    GH3X2X_Memset((GU8*)g_pstGh3x2xNewAgcMainChnlInfoEntity,0,(GU16)GH3X2X_NEW_AGC_SLOT_NUM_LIMIT*sizeof(STGh3x2xNewAgcMainChnlInfo));\r
+    GH3X2X_Memset( (GU8*)(&g_pstGh3x2xNewAgcMainChnlSat),0,sizeof(STGh3x2xNewAgcMainChnlSat)); // init  variable\r
+    GH3X2X_Memset((GU8*)g_pstGh3x2xNewAgcMainChnlMeanInfoEntity,0,(GU16)GH3X2X_NEW_AGC_SLOT_NUM_LIMIT*sizeof(STGh3x2xNewAgcMainChnlMeanInfo)); \r
+    GH3X2X_Memset((GU8*)g_pstGh3x2xNewAgcMainChnlIdaelAdjInfoEntity,0,(GU16)GH3X2X_NEW_AGC_SLOT_NUM_LIMIT*sizeof(STGh3x2xNewAgcMainChnlIdaelAdjInfo));                           \r
+               \r
+         #if GH3X2X_NEW_AGC_SUB_CHNL_NUM_LIMIT > 0\r
+    Gh3x2xNewAgcSubChnlModuleReset();   \r
+               #endif\r
+}\r
+ \r
+void GH3X2X_NewAgcRecoveryAgcRegToMainChnl(GU8 uchSlotIdx, STGh3x2xNewAgcMainChnlInfo *pstAgcMainChnlInfo)\r
+{\r
+    GH3x2xSetAgcReg(GH3X2X_AGC_REG_LED_CURRENT_UP_LIMIT, uchSlotIdx, pstAgcMainChnlInfo ->uchBakRegLedCurrentMax);\r
+    GH3x2xSetAgcReg(GH3X2X_AGC_REG_LED_CURRENT_DOWN_LIMIT, uchSlotIdx, pstAgcMainChnlInfo ->uchBakRegLedCurrentMin);\r
+    GH3x2xSetAgcReg(GH3X2X_AGC_REG_AGC_SRC, uchSlotIdx, pstAgcMainChnlInfo ->uchBakRegAgcSrc);\r
+    GH3X2X_INFO_LOG_PARAM_AGC("[NewAgc] recover agc src:agc_src = %d, SlotNo = %d\r\n",pstAgcMainChnlInfo ->uchBakRegAgcSrc,uchSlotIdx);\r
+}\r
+\r
+GU8 GH3X2X_NewAgcFindSubChnlSlotInfo(GU8 uchSlot)\r
+{\r
+    for(GU8 uchSlotCnt = 0; uchSlotCnt < GH3X2X_NEW_AGC_SLOT_NUM_LIMIT; uchSlotCnt ++)\r
+    {\r
+        STGh3x2xNewAgcMainChnlInfo *pstAgcMainChnlInfo = &g_pstGh3x2xNewAgcMainChnlInfoEntity[uchSlotCnt];\r
+        if(pstAgcMainChnlInfo ->uchEnable)\r
+        {\r
+            if(uchSlot == (pstAgcMainChnlInfo ->uchSlotAdc >> 2))\r
+            {\r
+                return uchSlotCnt;\r
+            }\r
+        }\r
+    }\r
+    return 0;\r
+}\r
+\r
+GU16 GH3x2xCalTrigerUpLimitForBiggerGain(GU8 uchCurrentGain ,GU8 uchSlotNo)\r
+{\r
+    GU32 unTempRawdata;\r
+    GU32 unTempTrigThd_H;\r
+\r
+    GU8 uchSlotCnt = GH3X2X_NewAgcFindSubChnlSlotInfo(uchSlotNo);\r
+    STGh3x2xNewAgcMainChnlInfo *pstAgcMainChnlInfo = &g_pstGh3x2xNewAgcMainChnlInfoEntity[uchSlotCnt];\r
+    if(pstAgcMainChnlInfo->uchSpo2ChnlIndex)\r
+    {\r
+        unTempTrigThd_H = g_unNewAgcSpo2Trig_H_Thd;\r
+    }else\r
+    {\r
+        unTempTrigThd_H = g_unNewAgcGeneTrig_H_Thd;\r
+    }\r
+        \r
+    if(12 <= uchCurrentGain)\r
+    {\r
+        return 0xFFFF;\r
+    }\r
+    else\r
+    {\r
+        unTempRawdata = unTempTrigThd_H - 8388608;\r
+        unTempRawdata = 8388608 + (GU32)(((float)unTempRawdata)/(float)1.3*(float)g_usGH3x2xTiaGainR[uchCurrentGain]/(float)g_usGH3x2xTiaGainR[uchCurrentGain + 1]);\r
+        return unTempRawdata>>8;\r
+    }\r
+}\r
+\r
+\r
+#if GH3X2X_NEW_AGC_SUB_CHNL_NUM_LIMIT > 0\r
+void GH3x2xNewAgcSubChnlClearAnalysisCntAndSetGain(GU8 uchSlotNo, GU8 uchRxEn ,GU8 uchNextGain)\r
+{\r
+    for(GU8 uchRxCnt = 0; uchRxCnt < 4; uchRxCnt ++)\r
+    {\r
+        if(uchRxEn&(1 << uchRxCnt))\r
+        {\r
+            for(GU8 uchChnlCnt = 0; uchChnlCnt < GH3X2X_NEW_AGC_SUB_CHNL_NUM_LIMIT; uchChnlCnt ++)\r
+            {\r
+                STGh3x2xNewAgcSubChnlRxInfo *pstSTGh3x2xNewAgcSubChnlRxInfo = &(g_pstGh3x2xNewAgcSubChnlRxInfoEntity[uchChnlCnt]);\r
+                if(pstSTGh3x2xNewAgcSubChnlRxInfo->uchEn)\r
+                {\r
+                    if(((uchSlotNo << 2) + uchRxCnt) == pstSTGh3x2xNewAgcSubChnlRxInfo ->uchSlotAdcNo)\r
+                    {\r
+                        pstSTGh3x2xNewAgcSubChnlRxInfo ->usAnalysisCnt = 0;\r
+                        if(0xFF != uchNextGain)\r
+                        {\r
+                            GH3x2xSetAgcReg(GH3X2X_AGC_REG_TIA_GAIN_RX0 + uchRxCnt, uchSlotNo, 0);\r
+                            pstSTGh3x2xNewAgcSubChnlRxInfo ->uchCurrentGain = uchNextGain;\r
+                            pstSTGh3x2xNewAgcSubChnlRxInfo ->usTrigeUpLimitForBiggerGain = GH3x2xCalTrigerUpLimitForBiggerGain(uchNextGain,pstSTGh3x2xNewAgcSubChnlRxInfo->uchSlotAdcNo >> 2);\r
+                        }\r
+                    }    \r
+                }\r
+            }\r
+        }\r
+    }\r
+}\r
+#endif\r
+  \r
+  \r
+void GH3x2xNewAgcMeanInfoReset(GU8 uchSlotEnChange)\r
+{\r
+     for(GU8 uchSlotCnt = 0; uchSlotCnt < 8; uchSlotCnt++)\r
+     {\r
+        if( uchSlotEnChange & (1<<uchSlotCnt)) // SlotEn Change \r
+        {\r
+            for(GU8 uchAgcSlotCnt = 0; uchAgcSlotCnt < GH3X2X_NEW_AGC_SLOT_NUM_LIMIT; uchAgcSlotCnt ++) //// uchAgcSlotCntʹ�ܵ����slot����\r
+            {\r
+                GU8  uchSlotIdx = ((g_pstGh3x2xNewAgcMainChnlInfoEntity[uchAgcSlotCnt].uchSlotAdc >> 2) & 0x0f);\r
+                GU8  uchEnable = g_pstGh3x2xNewAgcMainChnlInfoEntity[uchAgcSlotCnt].uchEnable;\r
+                if( uchEnable )  \r
+                { \r
+                   if( uchSlotIdx == uchSlotCnt)  \r
+                   {\r
+                       g_pstGh3x2xNewAgcMainChnlMeanInfoEntity[uchAgcSlotCnt].usAnalysisCnt = 0;\r
+                       #if GH3X2X_NEW_AGC_SUB_CHNL_NUM_LIMIT > 0\r
+                       GH3x2xNewAgcSubChnlClearAnalysisCntAndSetGain(uchSlotIdx, 0x0F, 0xFF); //clear all rx analysis cnt in this slot\r
+                       #endif \r
+                   }\r
+                }\r
+            }\r
+        }\r
+     }\r
+}    \r
+\r
+GU8 GH3x2xGetDrvCurrent(GU8 uchSlotIdx ,GU8 uchAgcEn)\r
+{\r
+    GU8 uchTempDrv;\r
+    if(2 == uchAgcEn)\r
+    {    \r
+        uchTempDrv = GH3x2xGetAgcReg(GH3X2X_AGC_REG_LED_CURRENT_DRV1, uchSlotIdx);\r
+    }\r
+    else\r
+    {\r
+        uchTempDrv = GH3x2xGetAgcReg(GH3X2X_AGC_REG_LED_CURRENT_DRV0, uchSlotIdx);\r
+    }\r
+    return uchTempDrv;\r
+}\r
+\r
+void GH3x2xNewAgcChnlInfoInit(STGh3x2xAgcInfo *STGh3x2xAgcInfo)\r
+{\r
+    if(0 == GH3X2X_NEW_AGC_SLOT_NUM_LIMIT)\r
+    {\r
+        return;\r
+    }\r
+    if(0 == g_Gh3x2xNewAgcInitFlag)\r
+    {\r
+        GU8 uchNewAgcSlotCnt = 0;\r
+        for(GU8 uchSlotCnt = 0; uchSlotCnt < 8; uchSlotCnt ++)\r
+        {\r
+            if((g_stSoftAgcCfg.uchSlotxSoftAgcAdjEn & (1 << uchSlotCnt)))\r
+            {\r
+                if(uchNewAgcSlotCnt < GH3X2X_NEW_AGC_SLOT_NUM_LIMIT)\r
+                {\r
+                    g_pstGh3x2xNewAgcMainChnlInfoEntity[uchNewAgcSlotCnt].uchEnable = 1;\r
+                    g_pstGh3x2xNewAgcMainChnlInfoEntity[uchNewAgcSlotCnt].uchSlotAdc = (uchSlotCnt << 2); \r
+                                    \r
+                    /******* slot function Distinguish   START******************************************************/          \r
+                    if((g_stSoftAgcCfg.uchSpo2RedSlotCfgEn & (1 << uchSlotCnt))||(g_stSoftAgcCfg.uchSpo2IrSlotCfgEn & (1 << uchSlotCnt)))\r
+                    {\r
+                        g_pstGh3x2xNewAgcMainChnlInfoEntity[uchNewAgcSlotCnt].uchSpo2ChnlIndex =  1;\r
+                        GH3X2X_INFO_LOG_PARAM_AGC("[NewAgc] uchNewAgcSpo2SlotCnt = %d\r\n",uchNewAgcSlotCnt);\r
+                    }\r
+                    /******* slot function Distinguish   END******************************************************/\r
+                    GH3X2X_INFO_LOG_PARAM_AGC("[NewAgc] uchNewAgcSlotCnt = %d\r\n",uchNewAgcSlotCnt);\r
+                    uchNewAgcSlotCnt ++;\r
+                }\r
+                else\r
+                {\r
+                    GH3X2X_DEBUG_LOG_PARAM("[NewAgc] error !!! main chnl info is no enough! \r\n");\r
+                    while(1);\r
+                }\r
+            }\r
+        }\r
+        g_Gh3x2xNewAgcInitFlag = 1;\r
+    }\r
+\r
+    for(GU8 uchSlotCnt = 0; uchSlotCnt < GH3X2X_NEW_AGC_SLOT_NUM_LIMIT; uchSlotCnt ++)\r
+    {    \r
+        STGh3x2xNewAgcMainChnlInfo *pstAgcMainChnlInfo = &g_pstGh3x2xNewAgcMainChnlInfoEntity[uchSlotCnt];\r
+        GH3X2X_INFO_LOG_PARAM_AGC("AGC_InitValue %d: Enable = %d, AgcAdjEn = %d\r\n",uchSlotCnt, pstAgcMainChnlInfo->uchEnable,g_stSoftAgcCfg.uchSlotxSoftAgcAdjEn);\r
+        if(pstAgcMainChnlInfo->uchEnable)\r
+        {\r
+            GU8 uchSlotIdx;\r
+            uchSlotIdx = pstAgcMainChnlInfo ->uchSlotAdc >> 2;\r
+            GH3X2X_INFO_LOG_PARAM_AGC("AGC_InitFlag%d: SlotCfgX=%d, Vaule = %d\r\n",uchSlotCnt, uchSlotIdx, pstAgcMainChnlInfo->uchHaveBakRegFlag);\r
+            if(0 == pstAgcMainChnlInfo ->uchHaveBakRegFlag)\r
+            {\r
+                GU8 uchBgCancel;\r
+                GU8 uchGainLimit;\r
+                GU16 usSampleRate;\r
+                GU16 usEcgPpgRxEn;\r
+\r
+                //bak reg\r
+                pstAgcMainChnlInfo ->uchBakRegAgcEn = GH3x2xGetAgcReg(GH3X2X_AGC_REG_AGC_EN, uchSlotIdx);\r
+                pstAgcMainChnlInfo ->uchBakRegAgcSrc = GH3x2xGetAgcReg(GH3X2X_AGC_REG_AGC_SRC, uchSlotIdx);\r
+                pstAgcMainChnlInfo ->uchSlotAdc = (uchSlotIdx << 2) + pstAgcMainChnlInfo ->uchBakRegAgcSrc;\r
+                pstAgcMainChnlInfo ->uchBakRegLedCurrentMax = GH3x2xGetAgcReg(GH3X2X_AGC_REG_LED_CURRENT_UP_LIMIT, uchSlotIdx);                \r
+                pstAgcMainChnlInfo ->uchBakRegLedCurrentMin = GH3x2xGetAgcReg(GH3X2X_AGC_REG_LED_CURRENT_DOWN_LIMIT, uchSlotIdx);    \r
+                pstAgcMainChnlInfo ->uchBakTiaGain = GH3x2xGetAgcReg(GH3X2X_AGC_REG_TIA_GAIN_RX0 + pstAgcMainChnlInfo ->uchBakRegAgcSrc, uchSlotIdx);\r
+                pstAgcMainChnlInfo ->uchCurrentTiaGain = pstAgcMainChnlInfo ->uchBakTiaGain;\r
+                pstAgcMainChnlInfo ->uchCurrentDrv =  GH3x2xGetDrvCurrent(uchSlotIdx, pstAgcMainChnlInfo->uchBakRegAgcEn); \r
+                //GH3X2X_StoreDrvCurrentAfterAgc(pstAgcMainChnlInfo ->uchCurrentDrv, uchSlotIdx,g_pstGh3x2xAgcInfo->uchDrvCurrentAfterSoftAgc);                                                        \r
+                uchBgCancel = GH3x2xGetAgcReg(GH3X2X_AGC_REG_BG_CANCEL_RX0 + pstAgcMainChnlInfo ->uchBakRegAgcSrc, uchSlotIdx);\r
+                GH3X2X_StoreRxTiaGainAfterAgc(pstAgcMainChnlInfo->uchBakTiaGain, uchSlotIdx, pstAgcMainChnlInfo->uchBakRegAgcSrc, STGh3x2xAgcInfo->uchTiaGainAfterSoftAgc);\r
+                if(0 == uchBgCancel)\r
+                {\r
+                    uchGainLimit = g_stSoftAgcCfg.stSoftAgcGainLimit.uchGainLimitBg32uA;\r
+                }\r
+                else if(1 == uchBgCancel)\r
+                {\r
+                    uchGainLimit = g_stSoftAgcCfg.stSoftAgcGainLimit.uchGainLimitBg64uA;\r
+                }\r
+                else if(2 == uchBgCancel)\r
+                {\r
+                    uchGainLimit = g_stSoftAgcCfg.stSoftAgcGainLimit.uchGainLimitBg128uA;\r
+                }\r
+                else\r
+                {\r
+                    uchGainLimit = g_stSoftAgcCfg.stSoftAgcGainLimit.uchGainLimitBg256uA;\r
+                }\r
+                GH3X2X_INFO_LOG_PARAM_AGC("[NewAgc] uchGainLimit = %d, uchSlotIdx = %d\r\n",uchGainLimit, uchSlotIdx);\r
+                pstAgcMainChnlInfo ->uchTiaGainUpLimit = uchGainLimit;\r
+                \r
+                usEcgPpgRxEn = GH3x2xGetAgcReg(GH3X2X_AGC_ECG_PPG_RX_EN, uchSlotIdx);\r
+                GH3X2X_INFO_LOG_PARAM_AGC("[NewAgc] usEcgPpgRxEn = 0x%X\r\n",usEcgPpgRxEn);\r
+                if(usEcgPpgRxEn&0x0001)  // ecg is enable\r
+                {\r
+                    usEcgPpgRxEn = ((usEcgPpgRxEn>>1) & (~0x0008));  //clear RX3 enable bit\r
+                }\r
+                else\r
+                {\r
+                    usEcgPpgRxEn = (usEcgPpgRxEn>>1);\r
+                }\r
+                usEcgPpgRxEn &= (~(1 << pstAgcMainChnlInfo ->uchBakRegAgcSrc));   //clear main channel RX enable bit\r
+                \r
+                GU16 usFastestSampleRate =  GH3X2X_ReadRegBitField(GH3X2X_FASTEST_SAMPLERATE_ADDR,0,7);\r
+                usSampleRate = GH3X2X_SYS_SAMPLE_RATE/(usFastestSampleRate + 1)/(GH3x2xGetAgcReg(GH3X2X_AGC_REG_SR_MULIPLIPER, uchSlotIdx) + 1);\r
+                g_pstGh3x2xNewAgcMainChnlMeanInfoEntity[uchSlotCnt].usSampleRate = usSampleRate;  //init\r
+                //sub channel slot\r
+#if GH3X2X_NEW_AGC_SUB_CHNL_NUM_LIMIT > 0\r
+                GH3x2xNewAgcSetNewSubChnl(uchSlotIdx,usEcgPpgRxEn,STGh3x2xAgcInfo);\r
+#endif\r
+                pstAgcMainChnlInfo ->uchHaveBakRegFlag = 1;                \r
+                GH3x2xSetAgcReg(GH3X2X_AGC_REG_AGC_EN, uchSlotIdx, 0);   // disable hardware agc \r
+            }\r
+            else\r
+            {\r
+              pstAgcMainChnlInfo ->uchCurrentTiaGain = GH3x2xGetAgcReg(GH3X2X_AGC_REG_TIA_GAIN_RX0 + pstAgcMainChnlInfo ->uchBakRegAgcSrc, uchSlotIdx);\r
+              pstAgcMainChnlInfo ->uchCurrentDrv =  GH3x2xGetDrvCurrent(uchSlotIdx, pstAgcMainChnlInfo->uchBakRegAgcEn);\r
+              GH3X2X_INFO_LOG_PARAM_AGC("Drv Gian inite read %d: IniteDrv = %d, IniteGain = %d\r\n",uchSlotIdx, pstAgcMainChnlInfo ->uchCurrentDrv, pstAgcMainChnlInfo ->uchCurrentTiaGain);\r
+              ////get initial DRV and current in case them change before StartSampling()\r
+//              GH3X2X_NewAgcRecoveryAgcRegToMainChnl(uchSlotIdx,pstAgcMainChnlInfo);\r
+            }\r
+        }\r
+    }\r
+}\r
+\r
+\r
+GU32 GH32x2xMedSel(GU32 unData0, GU32 unData1, GU32 unData2)\r
+{\r
+    if((unData0 >= unData1)&&(unData0 <= unData2))\r
+    {\r
+        return unData0;\r
+    }\r
+    if((unData0 >= unData2)&&(unData0 <= unData1))\r
+    {\r
+        return unData0;\r
+    }\r
+    if((unData1 >= unData0)&&(unData1 <= unData2))\r
+    {\r
+        return unData1;\r
+    }\r
+    if((unData1 >= unData2)&&(unData1 <= unData0))\r
+    {\r
+        return unData1;\r
+    }\r
+    return unData2;\r
+}\r
+\r
+float GH3X2X_CalcfRelativeVpp(GU32 unRawdata, GU8 uchDrv, GU8 uchGain)\r
+{\r
+    return ((float)unRawdata/(float)uchDrv/(float)g_usGH3x2xTiaGainR[uchGain]);\r
+}\r
+\r
+void GH3X2X_StoreTiaGainAfterAgc(GU16 usGainRegValue, GU8 uchSlotNo, GU8* puchGainRecord)\r
+{\r
+    for(GU8 uchAdcCnt = 0; uchAdcCnt < 4; uchAdcCnt ++)\r
+    {\r
+        puchGainRecord[uchSlotNo*4 + uchAdcCnt] = (usGainRegValue>>(uchAdcCnt*4))&0x000F;\r
+        GH3X2X_INFO_LOG_PARAM_AGC("StoreTiaGainAfterAgc slot no = %d, adc no = %d, usGainRegValue = %d\r\n", uchSlotNo,uchAdcCnt,usGainRegValue);\r
+    }\r
+}\r
+\r
+void GH3X_AgcGetThreshold( GU8 uchSpo2ChnlIndex, GU32* punTemp_H_Thd, GU32* punTemp_L_Thd )\r
+{  \r
+   if(uchSpo2ChnlIndex) // is  spo2 slot\r
+   {\r
+      *punTemp_H_Thd = g_unNewAgcSpo2Trig_H_Thd; \r
+      *punTemp_L_Thd = g_unNewAgcSpo2Trig_L_Thd; \r
+   }else\r
+   { \r
+      *punTemp_H_Thd = g_unNewAgcGeneTrig_H_Thd;\r
+      *punTemp_L_Thd = g_unNewAgcGeneTrig_L_Thd;      \r
+   }\r
+}\r
+\r
+#if GH3X2X_NEW_AGC_SUB_CHNL_NUM_LIMIT > 0\r
+void Gh3x2xNewAgcSubChnlModuleReset(void)\r
+{\r
+    #if GH3X2X_NEW_AGC_SUB_CHNL_NUM_LIMIT > 0\r
+    GH3X2X_Memset((GU8*)g_pstGh3x2xNewAgcSubChnlRxInfoEntity,0,(GU16)GH3X2X_NEW_AGC_SUB_CHNL_NUM_LIMIT*sizeof(STGh3x2xNewAgcSubChnlRxInfo));\r
+    #endif\r
+}\r
+\r
+\r
+GU8 GH3x2xNewAgcSetNewSubChnl(GU8 uchSlotNo, GU8 uchRxEn, STGh3x2xAgcInfo *STGh3x2xAgcInfo)\r
+{\r
+    GU8 uchSetSuccess = 1;\r
+    for(GU8 uchRxCnt = 0; uchRxCnt < 4; uchRxCnt ++)\r
+    {\r
+        if(uchRxEn&(1 << uchRxCnt))\r
+        {\r
+            uchSetSuccess = 0;\r
+            for(GU8 uchChnlCnt = 0; uchChnlCnt < GH3X2X_NEW_AGC_SUB_CHNL_NUM_LIMIT; uchChnlCnt ++)\r
+            {\r
+                STGh3x2xNewAgcSubChnlRxInfo *pstSTGh3x2xNewAgcSubChnlRxInfo = &(g_pstGh3x2xNewAgcSubChnlRxInfoEntity[uchChnlCnt]);\r
+                if(0 ==  pstSTGh3x2xNewAgcSubChnlRxInfo->uchEn)\r
+                {\r
+                    pstSTGh3x2xNewAgcSubChnlRxInfo->uchEn = 1;\r
+                    pstSTGh3x2xNewAgcSubChnlRxInfo->uchSlotAdcNo = (uchSlotNo << 2) + uchRxCnt;\r
+                    //read current gain\r
+                    pstSTGh3x2xNewAgcSubChnlRxInfo ->uchCurrentGain = GH3x2xGetAgcReg(GH3X2X_AGC_REG_TIA_GAIN_RX0 + uchRxCnt, uchSlotNo);\r
+                    GH3X2X_INFO_LOG_PARAM_AGC("[NewAgc] Sub chnl current Gain = %d, Slot = %d, Rx = %d\r\n",pstSTGh3x2xNewAgcSubChnlRxInfo ->uchCurrentGain,uchSlotNo,uchRxCnt);\r
+                    pstSTGh3x2xNewAgcSubChnlRxInfo ->usTrigeUpLimitForBiggerGain = GH3x2xCalTrigerUpLimitForBiggerGain(pstSTGh3x2xNewAgcSubChnlRxInfo ->uchCurrentGain, uchSlotNo);\r
+                    GH3X2X_INFO_LOG_PARAM_AGC("[NewAgc] usTrigeUpLimitForBiggerGain = %d, Slot = %d, Rx = %d\r\n",((GU32)pstSTGh3x2xNewAgcSubChnlRxInfo ->usTrigeUpLimitForBiggerGain)<<8,uchSlotNo,uchRxCnt);\r
+                    GH3X2X_StoreRxTiaGainAfterAgc(pstSTGh3x2xNewAgcSubChnlRxInfo ->uchCurrentGain, uchSlotNo, uchRxCnt, STGh3x2xAgcInfo->uchTiaGainAfterSoftAgc);\r
+                    uchSetSuccess = 1;\r
+                    break;\r
+                }\r
+            }\r
+            if(0 == uchSetSuccess)\r
+            {\r
+                GH3X2X_DEBUG_LOG_PARAM("[NewAgc] Set new sub chnl fail !!! Slot = %d, Rx = %d\r\n",uchSlotNo,uchRxCnt);\r
+                while(1);\r
+            }\r
+        }\r
+    }\r
+    return uchSetSuccess;\r
+}\r
+\r
+#if GH3X2X_NEW_AGC_SUB_CHNL_NUM_LIMIT > 0\r
+void GH3X2X_NewAgcSubChnlGainAdj(GU8* puchReadFifoBuffer, GU16 usFifoLen, STGh3x2xAgcInfo *STGh3x2xAgcInfo)\r
+{\r
+    for(GU8 uchChnlCnt = 0; uchChnlCnt < GH3X2X_NEW_AGC_SUB_CHNL_NUM_LIMIT; uchChnlCnt ++)\r
+    {    \r
+        GU16 usAnalysisDiscardLen;\r
+        GU16 usAnalysisEndLen;\r
+        GU8  uchSlotCnt;\r
+        GU8  uchSlotIdx;\r
+        GU8  uchAdcNo;\r
+        GU32 unTempTrigThd_L;\r
+        GU32 unTempTrigThd_H;\r
+        STGh3x2xNewAgcSubChnlRxInfo *pstSTGh3x2xNewAgcSubChnlRxInfo = &(g_pstGh3x2xNewAgcSubChnlRxInfoEntity[uchChnlCnt]);\r
+        uchSlotIdx = pstSTGh3x2xNewAgcSubChnlRxInfo ->uchSlotAdcNo >> 2;\r
+        uchAdcNo = pstSTGh3x2xNewAgcSubChnlRxInfo ->uchSlotAdcNo&0x03;\r
+        uchSlotCnt = GH3X2X_NewAgcFindSubChnlSlotInfo(uchSlotIdx);\r
+        GU16 usSampleRate = g_pstGh3x2xNewAgcMainChnlMeanInfoEntity[uchSlotCnt].usSampleRate;\r
+        GU8 uchTiaGainLimit = g_pstGh3x2xNewAgcMainChnlInfoEntity[uchSlotCnt].uchTiaGainUpLimit;\r
+        usAnalysisDiscardLen = (usSampleRate<<1)/5;    //  2/5 Fs\r
+        usAnalysisEndLen = usAnalysisDiscardLen + usSampleRate * GH3X2X_NEW_AGC_SUB_CHNNL_ANAYLSIS_TIME_SEC;\r
+ \r
+        GH3X_AgcGetThreshold(g_pstGh3x2xNewAgcMainChnlInfoEntity[uchSlotCnt].uchSpo2ChnlIndex,&unTempTrigThd_H, &unTempTrigThd_L);    \r
+             \r
+        if(pstSTGh3x2xNewAgcSubChnlRxInfo ->uchEn)\r
+        {\r
+           // prevent unRawdataSum(GU32) overflow\r
+           if( (usAnalysisEndLen - usAnalysisDiscardLen) > 200 )  \r
+           {\r
+              usAnalysisDiscardLen = usAnalysisEndLen - 200;   // maximum number of accumulated rawdata is 200\r
+           }\r
+   \r
+            for (GU16 usIndex = 0; usIndex < usFifoLen; usIndex += GH3X2X_FIFO_RAWDATA_SIZE) \r
+            {\r
+                GU32 unFifoVal;\r
+                GU8  uchSlotAdcNo;\r
+                GU32 unDataRaw; \r
+                unFifoVal = GH3X2X_MAKEUP_DWORD(puchReadFifoBuffer[usIndex], puchReadFifoBuffer[usIndex + 1], \r
+                                                puchReadFifoBuffer[usIndex + 2], puchReadFifoBuffer[usIndex + 3]);\r
+                uchSlotAdcNo = ((unFifoVal >> 27)&0x0000001F);\r
+                unDataRaw = GH3X2X_RAWDATA_CLEAR_ALL_FLAG(unFifoVal);\r
+                if(uchSlotAdcNo == pstSTGh3x2xNewAgcSubChnlRxInfo ->uchSlotAdcNo)\r
+                {\r
+                    if(usAnalysisDiscardLen == pstSTGh3x2xNewAgcSubChnlRxInfo->usAnalysisCnt) //init\r
+                    {\r
+                        pstSTGh3x2xNewAgcSubChnlRxInfo ->unRawdataSum = 0;\r
+                        pstSTGh3x2xNewAgcSubChnlRxInfo ->unLastLastRawdata = unDataRaw;\r
+                        pstSTGh3x2xNewAgcSubChnlRxInfo ->unLastRawdata = unDataRaw;\r
+                        pstSTGh3x2xNewAgcSubChnlRxInfo ->usMoreThanUpLimitPointCnt = 0;\r
+                        pstSTGh3x2xNewAgcSubChnlRxInfo ->usMoreThanUpLimitPointCntForBiggerGain = 0;\r
+                    }\r
+                    if(pstSTGh3x2xNewAgcSubChnlRxInfo->usAnalysisCnt < usAnalysisEndLen)  //analysising\r
+                    {                \r
+                        GU32 unTempRawdata = GH32x2xMedSel(pstSTGh3x2xNewAgcSubChnlRxInfo ->unLastLastRawdata, pstSTGh3x2xNewAgcSubChnlRxInfo ->unLastRawdata, unDataRaw);\r
+                        if(usAnalysisDiscardLen == pstSTGh3x2xNewAgcSubChnlRxInfo->usAnalysisCnt)\r
+                        {\r
+                            GH3X2X_INFO_LOG_PARAM_AGC("[NewAgc] sub chnl unTempRawdata  = %d, Slot = %d, rx = %d\r\n",unTempRawdata, uchSlotIdx, uchAdcNo);\r
+                        }\r
+                        pstSTGh3x2xNewAgcSubChnlRxInfo ->unRawdataSum += unTempRawdata;\r
+                        if(unTempRawdata > unTempTrigThd_H)\r
+                        {\r
+                            pstSTGh3x2xNewAgcSubChnlRxInfo->usMoreThanUpLimitPointCnt ++;\r
+                        }\r
+                        if((unTempRawdata >> 8) > pstSTGh3x2xNewAgcSubChnlRxInfo->usTrigeUpLimitForBiggerGain)\r
+                        {\r
+                            pstSTGh3x2xNewAgcSubChnlRxInfo->usMoreThanUpLimitPointCntForBiggerGain ++;\r
+                        }\r
+                        pstSTGh3x2xNewAgcSubChnlRxInfo ->unLastLastRawdata = pstSTGh3x2xNewAgcSubChnlRxInfo ->unLastRawdata;\r
+                        pstSTGh3x2xNewAgcSubChnlRxInfo ->unLastRawdata = unDataRaw;\r
+                        pstSTGh3x2xNewAgcSubChnlRxInfo->usAnalysisCnt ++;                    \r
+                    }\r
+                    else //anlysis finished\r
+                    {\r
+                        GU32 unAvaRawdata;\r
+                        GU16 unRealAnaylsisNum = usAnalysisEndLen - usAnalysisDiscardLen;\r
+                        GU8  uchNextGain = 0xFF;\r
+                        GU8  uchCurrentGain = pstSTGh3x2xNewAgcSubChnlRxInfo ->uchCurrentGain;\r
+                        unAvaRawdata = pstSTGh3x2xNewAgcSubChnlRxInfo ->unRawdataSum/unRealAnaylsisNum;\r
+                        GH3X2X_INFO_LOG_PARAM_AGC("[NewAgc] sub chnl rawdata ava  = %d,DownLimit = %d, Slot = %d, rx = %d\r\n",unAvaRawdata, unTempTrigThd_L,uchSlotIdx, uchAdcNo);\r
+                        GH3X2X_INFO_LOG_PARAM_AGC("[NewAgc] usMoreThanUpLimitPointCnt  = %d,UpLimit = %d, Slot = %d, rx = %d\r\n",pstSTGh3x2xNewAgcSubChnlRxInfo ->usMoreThanUpLimitPointCnt, unTempTrigThd_H,uchSlotIdx, uchAdcNo);\r
+                        GH3X2X_INFO_LOG_PARAM_AGC("[NewAgc] usMoreThanUpLimitPointCntForBiggerGain = %d,UpLimit = %d, Slot = %d, rx = %d\r\n",pstSTGh3x2xNewAgcSubChnlRxInfo ->usMoreThanUpLimitPointCntForBiggerGain, ((GU32)pstSTGh3x2xNewAgcSubChnlRxInfo->usTrigeUpLimitForBiggerGain)<<8, uchSlotIdx, uchAdcNo);\r
+                        if(pstSTGh3x2xNewAgcSubChnlRxInfo ->usMoreThanUpLimitPointCnt > (unRealAnaylsisNum >> 3))  // 1/8 points is bigger than trige up limit\r
+                        {\r
+                            if(uchCurrentGain > 0)\r
+                            {\r
+                                uchNextGain = uchCurrentGain - 1;\r
+                            }\r
+                        }\r
+                        if((pstSTGh3x2xNewAgcSubChnlRxInfo ->usMoreThanUpLimitPointCntForBiggerGain < (unRealAnaylsisNum >> 3))&&(unAvaRawdata < unTempTrigThd_L))\r
+                        {\r
+                            if(uchCurrentGain < uchTiaGainLimit)\r
+                            {\r
+                                uchNextGain = uchCurrentGain + 1;\r
+                            }\r
+                        }\r
+                        if(0xFF != uchNextGain)\r
+                        {                            \r
+                            GH3X2X_INFO_LOG_PARAM_AGC("[NewAgc] sub chnl gain change: NewGain = %d, OldGain = %d, Slot = %d, rx = %d\r\n",uchNextGain,uchCurrentGain, uchSlotIdx, uchAdcNo);\r
+                            GH3x2xSetAgcReg(GH3X2X_AGC_REG_TIA_GAIN_RX0 + uchAdcNo, uchSlotIdx, uchNextGain);\r
+                            pstSTGh3x2xNewAgcSubChnlRxInfo ->uchCurrentGain = uchNextGain;\r
+                            pstSTGh3x2xNewAgcSubChnlRxInfo ->usTrigeUpLimitForBiggerGain = GH3x2xCalTrigerUpLimitForBiggerGain(uchNextGain, uchSlotIdx);                                    \r
+                            GH3X2X_StoreRxTiaGainAfterAgc(uchNextGain, uchSlotIdx, uchAdcNo, STGh3x2xAgcInfo->uchTiaGainAfterSoftAgc);\r
+                        }\r
+                        pstSTGh3x2xNewAgcSubChnlRxInfo->usAnalysisCnt = 0;  \r
+                        break;// 完成一次均值计算后面的数据丢弃\r
+                    }\r
+                }\r
+            }\r
+        }\r
+    }\r
+}\r
+\r
+#endif\r
+#endif\r
+\r
+\r
+/*********************************************self-test function start*****************************************/\r
+#define GH3X2X_SPO2_SELF_TEST 0\r
+\r
+#if GH3X2X_SPO2_SELF_TEST\r
+const GU32 g_uchSpo2AgcSelftestSlotAdc = 0x01;  //slot0, adc1\r
+const GU32 g_usSpo2AgcFifoLen = 25*4;\r
+const GU32 g_unSpo2AgcRawdata[] = \r
+{\r
+    10111744,9818116,10074798,9832931,10038819,9812989,10067119,9791632,10220862,9843610,9888564,9974512,10041146,10117796,9858828,10260863,9900963,10159857,10259720,10054459,10247477,9957985,10078474,9916146,9821879\r
+};\r
+\r
+GU8 g_uchSpo2AgcFifoBuffer[4*100];\r
+\r
+void GH3X2X_Spo2AgcFifoDataGen(void)\r
+{\r
+    for (GU16 usIndex = 0; usIndex < g_usSpo2AgcFifoLen; usIndex += GH3X2X_FIFO_RAWDATA_SIZE) \r
+    {\r
+        if(usIndex >= sizeof(g_uchSpo2AgcFifoBuffer))\r
+        {\r
+            break;\r
+        }\r
+        g_uchSpo2AgcFifoBuffer[usIndex + 0] = (g_uchSpo2AgcSelftestSlotAdc<<3);\r
+        g_uchSpo2AgcFifoBuffer[usIndex + 1] = (0x000000FF&(g_unSpo2AgcRawdata[usIndex/4] >> 16));\r
+        g_uchSpo2AgcFifoBuffer[usIndex + 2] = (0x000000FF&(g_unSpo2AgcRawdata[usIndex/4] >> 8));\r
+        g_uchSpo2AgcFifoBuffer[usIndex + 3] = (0x000000FF&(g_unSpo2AgcRawdata[usIndex/4] >> 0));\r
+    }\r
+}\r
+#endif\r
+/*********************************************self-test function end*****************************************/\r
+\r
+\r
+/****************************************************************\r
+* Description: calculate mean value of main channel  \r
+* Input:  rawdata  \r
+* Return: none\r
+******************************************************************/\r
+static void GH3X2X_NewAgcMainChnlMeanValueCal(GU8* puchReadFifoBuffer, GU16 usFifoLen, GU32 *punRawdataMean, GU8 *pAdjFlag)\r
+{\r
+    for(GU8 uchSlotCnt = 0; uchSlotCnt < GH3X2X_NEW_AGC_SLOT_NUM_LIMIT; uchSlotCnt ++)\r
+    {\r
+        STGh3x2xNewAgcMainChnlInfo *pstAgcMainChnlInfo = &g_pstGh3x2xNewAgcMainChnlInfoEntity[uchSlotCnt];\r
+        GU8 uchMainChnlSlotAdcNo = pstAgcMainChnlInfo ->uchSlotAdc;\r
+        \r
+        if(pstAgcMainChnlInfo ->uchEnable)   // is  enabled  slot\r
+        {        \r
+            GU32 unTemp_Trig_H_Thd;    \r
+            GU32 unTemp_Trig_L_Thd;    \r
+            GU32 unTemp_Ideal_value;\r
+            GU16 usAnalysisEndLen; \r
+            GU16 usAnalysisDiscardLenAdjust = 0;\r
+            GU16 usAnalysisDiscardLenTrige;\r
+            GU32 TrigeMean  = 0; \r
+\r
+            if(pstAgcMainChnlInfo->uchSpo2ChnlIndex) // is  spo2 slot\r
+            {\r
+                unTemp_Ideal_value= g_unNewAgcSpo2Ideal_value;\r
+            }else\r
+            {                        \r
+                unTemp_Ideal_value= g_unNewAgcGeneIdeal_value;\r
+            }\r
+            GH3X_AgcGetThreshold( pstAgcMainChnlInfo->uchSpo2ChnlIndex, &unTemp_Trig_H_Thd, &unTemp_Trig_L_Thd);  \r
+                      \r
+            STGh3x2xNewAgcMainChnlMeanInfo *pstNewAgcMainChnlMeanInfo = &g_pstGh3x2xNewAgcMainChnlMeanInfoEntity[uchSlotCnt];\r
+            STGh3x2xNewAgcMainChnlIdaelAdjInfo *pstNewAgcMainChnlIdaelAdjInfo = &g_pstGh3x2xNewAgcMainChnlIdaelAdjInfoEntity[uchSlotCnt];\r
+            GU16 usSampleRate =  pstNewAgcMainChnlMeanInfo->usSampleRate;\r
+            usAnalysisEndLen = (usSampleRate<<2)/5;            // 4/5 Fs  \r
+            usAnalysisDiscardLenTrige =  (usSampleRate<<1)/5;  // drop the first 2/5 data    \r
+            //have agc motion at last fifo read period or first init                        \r
+            if(pstNewAgcMainChnlMeanInfo->uchHaveAgcAtLastReadPrd)   \r
+            {\r
+                usAnalysisDiscardLenAdjust = (usSampleRate<<1)/5;  // drop the first 2/5 data\r
+                //// After AGC, the previous data is drop to calcluate precise mean\r
+                if(!pstNewAgcMainChnlMeanInfo->uchDropFlag)\r
+                {  // The frame count is only cleared for the first time to prevent data num cannot to be SampleRate\r
+                    pstNewAgcMainChnlMeanInfo->usAnalysisCnt = 0;  \r
+                    pstNewAgcMainChnlMeanInfo->uchDropFlag = 1;\r
+                }         \r
+            }\r
+            //The data fluctuates when initializing the early stage  \r
+            if(!pstNewAgcMainChnlIdaelAdjInfo->uchIniteFirst)  \r
+            {\r
+                usAnalysisDiscardLenAdjust =  (usSampleRate<<1)/5;  // drop the first 2/5 data\r
+            }\r
+\r
+           // prevent unSumAdjust(GU32) overflow\r
+           if( (usAnalysisEndLen - usAnalysisDiscardLenAdjust) > 200 )\r
+           {\r
+              usAnalysisDiscardLenAdjust = usAnalysisEndLen - 200; // maximum number of accumulated rawdata is 200\r
+           }\r
+           \r
+           if( (usAnalysisEndLen - usAnalysisDiscardLenTrige) > 200 )\r
+           {\r
+              usAnalysisDiscardLenTrige = usAnalysisEndLen - 200;\r
+           }\r
+\r
+            for (GU16 usIndex = 0; usIndex < usFifoLen; usIndex += GH3X2X_FIFO_RAWDATA_SIZE) \r
+            {\r
+                GU32 unFifoVal;\r
+                GU8  uchSlotAdcNo;\r
+                GU32 unDataRaw; \r
+                unFifoVal = GH3X2X_MAKEUP_DWORD(puchReadFifoBuffer[usIndex], puchReadFifoBuffer[usIndex + 1], \r
+                                                puchReadFifoBuffer[usIndex + 2], puchReadFifoBuffer[usIndex + 3]);\r
+                uchSlotAdcNo = ((unFifoVal >> 27)&0x0000001F);\r
+                unDataRaw = GH3X2X_RAWDATA_CLEAR_ALL_FLAG(unFifoVal); \r
+ \r
+                if(uchSlotAdcNo == uchMainChnlSlotAdcNo)\r
+                {\r
+                    // begin Saturation judge   \r
+                    {  \r
+                        GU16 usSat_Check_Num_Max =   (usSampleRate<<2) + usSampleRate;   //// 5 seconds window\r
+                        g_pstGh3x2xNewAgcMainChnlSat.Sat_CheckCnt[uchSlotCnt]++;\r
+                        if( unDataRaw > unTemp_Trig_H_Thd)\r
+                        {\r
+                            g_pstGh3x2xNewAgcMainChnlSat.Sat_cnt[uchSlotCnt]++;\r
+                        }\r
+                        //// as soon as posible set the Saturation flag \r
+                        if( g_pstGh3x2xNewAgcMainChnlSat.Sat_cnt[uchSlotCnt] >= (usSat_Check_Num_Max>>4) ) // about 8% of all checked data\r
+                        {\r
+                            g_pstGh3x2xNewAgcMainChnlSat.Sat_flag |= (1<<uchSlotCnt);  \r
+                            g_pstGh3x2xNewAgcMainChnlSat.Sat_cnt[uchSlotCnt] = 0; \r
+                        }     \r
+\r
+                        if(g_pstGh3x2xNewAgcMainChnlSat.Sat_CheckCnt[uchSlotCnt] >= usSat_Check_Num_Max ) \r
+                        {                                      \r
+                            g_pstGh3x2xNewAgcMainChnlSat.Sat_cnt[uchSlotCnt] = 0;\r
+                            g_pstGh3x2xNewAgcMainChnlSat.Sat_CheckCnt[uchSlotCnt] = 0;  \r
+                        }                                 \r
+                    } \r
+                    // end Saturation judge   \r
+                    \r
+                    //// begin mean calculate    \r
+                   GH3X2X_INFO_LOG_PARAM_AGC("slotCnt=%d,MainChnlSlotAdc=%d,SlotAdc=%d,Raw=%d\r\n",uchSlotCnt,uchMainChnlSlotAdcNo,uchSlotAdcNo,unDataRaw);\r
+                    \r
+                   if(usAnalysisDiscardLenAdjust == pstNewAgcMainChnlMeanInfo->usAnalysisCnt) //init\r
+                    {\r
+                        pstNewAgcMainChnlMeanInfo->unSumAdjust =  0;\r
+                        pstNewAgcMainChnlMeanInfo->unMaxRawdata =  0;      \r
+                        pstNewAgcMainChnlMeanInfo->unMinRawdata =  16777216;\r
+                    }\r
+                                        \r
+                    if(usAnalysisDiscardLenTrige == pstNewAgcMainChnlMeanInfo->usAnalysisCnt) //init\r
+                    {\r
+                        pstNewAgcMainChnlMeanInfo->unSumTrige  =  0;\r
+                    }    \r
+                                        \r
+                    if(pstNewAgcMainChnlMeanInfo->usAnalysisCnt  < usAnalysisEndLen)   //analysising\r
+                    {\r
+                    pstNewAgcMainChnlMeanInfo->unSumAdjust +=  unDataRaw;\r
+                    pstNewAgcMainChnlMeanInfo->unSumTrige +=  unDataRaw;\r
+                    pstNewAgcMainChnlMeanInfo->usAnalysisCnt++;   \r
+                    pstNewAgcMainChnlMeanInfo->unMaxRawdata = ((unDataRaw > pstNewAgcMainChnlMeanInfo->unMaxRawdata)? unDataRaw: pstNewAgcMainChnlMeanInfo->unMaxRawdata ); // Max of  rawdata\r
+                    pstNewAgcMainChnlMeanInfo->unMinRawdata = ((unDataRaw < pstNewAgcMainChnlMeanInfo->unMinRawdata)? unDataRaw: pstNewAgcMainChnlMeanInfo->unMinRawdata ); // Min of  rawdata\r
+                    }\r
+                    else //anlysis finished   calculate mean and judge whether AGC\r
+                    {    \r
+                        // mean value to calculate gain and current\r
+                        if(usAnalysisEndLen > usAnalysisDiscardLenAdjust)\r
+                        {\r
+                            punRawdataMean[uchSlotCnt] = pstNewAgcMainChnlMeanInfo->unSumAdjust/(usAnalysisEndLen - usAnalysisDiscardLenAdjust);    \r
+                            TrigeMean = pstNewAgcMainChnlMeanInfo->unSumTrige / (usAnalysisEndLen - usAnalysisDiscardLenTrige);\r
+                        }else //  The normal case will not be executed, in case the division by 0 in abnormal case\r
+                        {\r
+                            punRawdataMean[uchSlotCnt] =   unDataRaw; \r
+                            TrigeMean =   unDataRaw; \r
+                        }\r
+                        pstNewAgcMainChnlMeanInfo ->unRawdataMean = punRawdataMean[uchSlotCnt];\r
+                        pstNewAgcMainChnlMeanInfo->usAnalysisCnt=0;\r
+                        // The mean calculation key variable is cleared    (Prevent mean calculation from being too small:Accumulation lost some data, but numble of raw is all)    \r
+                        usAnalysisDiscardLenAdjust = 0; \r
+                        pstNewAgcMainChnlMeanInfo->uchHaveAgcAtLastReadPrd = 0; //  clear  after caculate mean!!!       \r
+                        //// end mean calculate\r
+\r
+                        ///////////////////// whether AGC  and adjust the mean value to calculate gain and current\r
+                        if( (TrigeMean < unTemp_Trig_L_Thd) || (TrigeMean > unTemp_Trig_H_Thd) )\r
+                        {\r
+                            *pAdjFlag |= (1<<uchSlotCnt);  //need adjust gain and current \r
+                        }\r
+                        \r
+                        if( g_pstGh3x2xNewAgcMainChnlSat.Sat_flag & (1<<uchSlotCnt)) //if the channel is saturation\r
+                        {\r
+                            GU32 unTempMean = 0;         //Pay attention to initialization of local variables\r
+                            if( pstNewAgcMainChnlMeanInfo->unMaxRawdata > unTemp_Trig_H_Thd)\r
+                            {\r
+                                /////////// Pay attention to data truncation, use 64-bi\r
+                                unTempMean =   (GS64)unTemp_Ideal_value*(GS64)(pstNewAgcMainChnlMeanInfo->unMaxRawdata)/15099494;  // to adjust the max data to (0.8*2^23 + 2^23)\r
+                                *pAdjFlag |= (1<<uchSlotCnt);  //need adjust gain and current \r
+                            }\r
+                            \r
+                            if( punRawdataMean[uchSlotCnt] > unTemp_Ideal_value)\r
+                            {\r
+                                // adjust the mean value to calculate gain and current (reduce the DC amount)\r
+                                punRawdataMean[uchSlotCnt] = ( (punRawdataMean[uchSlotCnt]>unTempMean)? punRawdataMean[uchSlotCnt]:unTempMean );\r
+                                *pAdjFlag |= (1<<uchSlotCnt);  //need adjust gain and current \r
+                            } \r
+                            else if( pstNewAgcMainChnlMeanInfo->unMaxRawdata > unTemp_Trig_H_Thd)\r
+                            {\r
+                                punRawdataMean[uchSlotCnt] = unTempMean; //  Increasing the mean value to reduce the DC amount\r
+                            } \r
+                        }\r
+                        ////////////////////////////////////////////////////\r
+                        //////////////begin ideal value adjust \r
+                        if( (!((*pAdjFlag) & (1<<uchSlotCnt))) && (!( g_pstGh3x2xNewAgcMainChnlSat.Sat_flag & (1<<uchSlotCnt))))//if the channel not adjust and satuartion\r
+                        {\r
+                            //// The deviation of the mean and the ideal target value is above 1/16  and   Data fluctuation is less than a certain value\r
+                            if(((pstNewAgcMainChnlMeanInfo->unRawdataMean*g_uchAgcConvergence_level < (unTemp_Ideal_value*(g_uchAgcConvergence_level-1)) ) \\r
+                                || (pstNewAgcMainChnlMeanInfo->unRawdataMean*g_uchAgcConvergence_level > (unTemp_Ideal_value*(g_uchAgcConvergence_level+1)))) \\r
+                                &&( 10*pstNewAgcMainChnlMeanInfo->unMaxRawdata< 12*pstNewAgcMainChnlMeanInfo->unMinRawdata) ) \r
+                            {\r
+                                if( !pstNewAgcMainChnlIdaelAdjInfo->uchIniteFirst ) //// Inite First time \r
+                                {\r
+                                    pstNewAgcMainChnlIdaelAdjInfo->uchIniteFirst = 1;\r
+                                    *pAdjFlag |= (1<<uchSlotCnt);  //need adjust gain and current \r
+                                }\r
+                                else\r
+                                {\r
+                                    pstNewAgcMainChnlIdaelAdjInfo->uchSeconsCnt++;\r
+                                    if(pstNewAgcMainChnlIdaelAdjInfo->uchSeconsCnt >= 19)\r
+                                    {\r
+                                        *pAdjFlag |= (1<<uchSlotCnt);  //need adjust gain and current \r
+                                        pstNewAgcMainChnlIdaelAdjInfo->uchSeconsCnt  = 0; \r
+                                    }    \r
+                                }             \r
+                            }\r
+                            else\r
+                            {\r
+                                 pstNewAgcMainChnlIdaelAdjInfo->uchSeconsCnt  = 0;\r
+                            }                    \r
+                        }\r
+                        else\r
+                        {\r
+                             pstNewAgcMainChnlIdaelAdjInfo->uchSeconsCnt  = 0;\r
+                        }\r
+                        pstNewAgcMainChnlIdaelAdjInfo->uchIniteFirst = 1;  //// Must be set to 1 after the first second!!!    \r
+                        ////end ideal value adjust \r
+                        GH3X2X_INFO_LOG_PARAM_AGC("Mean cal: Slot_num = %d, Rawmean = %d, Adjmean = %d \r\n", uchSlotCnt,pstNewAgcMainChnlMeanInfo->unRawdataMean, punRawdataMean[uchSlotCnt]);\r
+                        GH3X2X_INFO_LOG_PARAM_AGC("Sat flag: SatCnt = %d, SatCheck = %d, Satflag = %d\r\n", g_pstGh3x2xNewAgcMainChnlSat.Sat_cnt[uchSlotCnt], g_pstGh3x2xNewAgcMainChnlSat.Sat_CheckCnt[uchSlotCnt], g_pstGh3x2xNewAgcMainChnlSat.Sat_flag);\r
+                        GH3X2X_INFO_LOG_PARAM_AGC("Ideal adjust: SeconsCnt = %d\r\n", pstNewAgcMainChnlIdaelAdjInfo->uchSeconsCnt);\r
+                        GH3X2X_INFO_LOG_PARAM_AGC("Adj flag: Slot_num = %d, Trigmean = %d, L_Thd = %d, H_Thd = %d, Adjflag = %d\r\n", uchSlotCnt,TrigeMean, unTemp_Trig_L_Thd, unTemp_Trig_H_Thd, *pAdjFlag);                                     \r
+                        g_pstGh3x2xNewAgcMainChnlSat.Sat_flag &= (~(1<<uchSlotCnt)) ; ////clear the Sat flag  \r
+                        break; //完成一次均值计算后面的数据丢弃\r
+                    }\r
+                }  \r
+             }\r
+        }\r
+        \r
+    }\r
+}\r
+\r
+/**\r
+ * @fn     GU8 GH3X2X_NewAgcCalDrvCurrentAndGain(GU32 CurRawdata, GU32 IdealRawdata, STGh3x2xNewAgcMainChnlInfo *pstAgcMainChnlInfo, GU8* puchIdealDrvCurrent, GU8* puchIdealGain)\r
+ *\r
+ * @brief  mark abnormal chnl\r
+ *\r
+ * @attention   \r
+ *\r
+ * @param[in]   CurRawdata, IdealRawdata, uchMainChnlInfoIndex\r
+ * @param[out]  puchIdealDrvCurrent, puchIdealGain\r
+ *\r
+ * @return  0:DrvCurrent or gain will NOT change  1: DrvCurrent or gain will  change\r
+ */\r
+GU8 GH3X2X_NewAgcCalDrvCurrentAndGain(GU32 CurRawdata, GU8 uchMainChnlInfoIndex,  GU8* puchIdealDrvCurrent, GU8* puchIdealGain)\r
+{\r
+    STGh3x2xNewAgcMainChnlInfo *pstAgcMainChnlInfo = &g_pstGh3x2xNewAgcMainChnlInfoEntity[uchMainChnlInfoIndex];\r
+    STGh3x2xNewAgcMainChnlMeanInfo *pstMainChnlExtralInfo = &g_pstGh3x2xNewAgcMainChnlMeanInfoEntity[uchMainChnlInfoIndex];\r
+\r
+    GU8 uchDefaultGain = pstAgcMainChnlInfo->uchBakTiaGain;\r
+    GU8 uchGainUpLimit = pstAgcMainChnlInfo->uchTiaGainUpLimit;\r
+    GU8 uchLedCurrentMin = pstAgcMainChnlInfo->uchBakRegLedCurrentMin;\r
+    GU8 uchLedCurrentMax = pstAgcMainChnlInfo->uchBakRegLedCurrentMax;\r
+    GU8 uchCurrentDrv = pstAgcMainChnlInfo->uchCurrentDrv;\r
+    GU8 uchCurrentTiaGain = pstAgcMainChnlInfo->uchCurrentTiaGain;\r
+ \r
+    GU8 uchNewGain = uchDefaultGain;\r
+    GU32 unIdealRawdata_no;\r
+    GU32 unTempDrvCurrent;\r
+    GU8 uchChangeFlag = 0;  //bit0: drv current flag  bit1: gain flag\r
+    GU8 uchCalFinish = 0;\r
+    GU32 unTrigUpLimit;\r
+    GU8  unCalNum = 12;\r
+  \r
+    if(0 != pstAgcMainChnlInfo->uchSpo2ChnlIndex) // is  spo2 slot\r
+    {\r
+        unTrigUpLimit = g_unNewAgcSpo2Trig_H_Thd;\r
+        unIdealRawdata_no= g_unNewAgcSpo2Ideal_value - 8388608;\r
+    }else\r
+    {\r
+        unTrigUpLimit = g_unNewAgcGeneTrig_H_Thd;\r
+        unIdealRawdata_no = g_unNewAgcGeneIdeal_value - 8388608;\r
+    }\r
+    \r
+    GH3X2X_INFO_LOG_PARAM_AGC("Drv cal: UpLimit = %d, Mean = %d, LastMean = %d\r\n",unTrigUpLimit, pstMainChnlExtralInfo->unRawdataMean, pstMainChnlExtralInfo->unLastRawdataMean);\r
+    // reduce rawdata as soon as posible\r
+    if((unTrigUpLimit < pstMainChnlExtralInfo->unRawdataMean)&&(unTrigUpLimit < pstMainChnlExtralInfo->unLastRawdataMean)&&(uchCurrentTiaGain > 0)) \r
+    {             \r
+       uchNewGain = 0;  \r
+       unTempDrvCurrent =  uchLedCurrentMin;\r
+       uchCalFinish = 1;\r
+    }\r
+    pstMainChnlExtralInfo ->unLastRawdataMean = pstMainChnlExtralInfo ->unRawdataMean;\r
+         \r
+    if(0 == uchCalFinish)\r
+    {\r
+        //remove offset\r
+        if(CurRawdata > (8388608 + 2048))  //// Can't open DC Cance !!!\r
+        {\r
+            CurRawdata -= 8388608;\r
+        }\r
+        else\r
+        {\r
+            //The value may be less than 2^23, preventing division by 0\r
+            CurRawdata = 2048;  // Take an appropriately large number to prevent calculated DRV current overflow 32bit\r
+        }\r
+        //Rawdata stretch  (The principle of magnification: the mean divided by the ideal target value is the data reduction factor )\r
+        if(CurRawdata < 8000000)\r
+        {\r
+        }\r
+        else if(CurRawdata < 8100000)\r
+        {\r
+            CurRawdata = 8000000 + (CurRawdata - 8000000)*6;\r
+        }\r
+        else if(CurRawdata < 8200000)\r
+        {\r
+            CurRawdata = 8000000 + ((CurRawdata - 8000000)<<3);\r
+        }\r
+        else\r
+        {\r
+            // The more saturated the data, the bigger the stretch, the key is that the data is really saturated\r
+            CurRawdata = 8000000 + (CurRawdata - 8000000)*14;   //  Blood oxygen drops 1 times, heart rate drops 2.5 times  \r
+        }\r
+\r
+        //find new drv current and gain\r
+        do\r
+        {   \r
+            unTempDrvCurrent = (GS64)(((GU32)uchCurrentDrv*(GU32)g_usGH3x2xTiaGainR[uchCurrentTiaGain]))* \\r
+            (GS64)unIdealRawdata_no/g_usGH3x2xTiaGainR[uchNewGain]/CurRawdata;\r
+\r
+           GH3X2X_INFO_LOG_PARAM_AGC("Drv cal %d: CurrentDrv=%d, CurrentGain=%d, IdealRawdata_no=%d\r\n",uchMainChnlInfoIndex, uchCurrentDrv, uchCurrentTiaGain, unIdealRawdata_no);\r
+           GH3X2X_INFO_LOG_PARAM_AGC("Drv cal %d: TempDrvCurrent=%d, NewGain=%d, Meanraw=%d, CurRawdata=%d\r\n",uchMainChnlInfoIndex,\\r
+                                   unTempDrvCurrent, uchNewGain, pstMainChnlExtralInfo->unRawdataMean, CurRawdata);\r
+          \r
+            if(unTempDrvCurrent > uchLedCurrentMax)  //drv is too big, need increase gain\r
+            {\r
+                if(uchNewGain < uchGainUpLimit)\r
+                {\r
+                    uchNewGain ++ ;\r
+                }\r
+                else\r
+                {\r
+                    unTempDrvCurrent = uchLedCurrentMax;\r
+                    break;\r
+                }\r
+            }\r
+            else if(unTempDrvCurrent < uchLedCurrentMin)  //drv is too small, need dncrease gain\r
+            {\r
+                if(uchNewGain > 0)\r
+                {\r
+                    uchNewGain -- ;\r
+                }\r
+                else\r
+                {\r
+                    unTempDrvCurrent = uchLedCurrentMin;\r
+                    break;\r
+                }\r
+            }\r
+            else   //got right drv\r
+            {\r
+                break;\r
+            }\r
+            unCalNum --;\r
+        }\r
+        while (unCalNum);\r
+    }\r
+\r
+    puchIdealDrvCurrent[0] = (GU8)unTempDrvCurrent;\r
+    puchIdealGain[0] = (GU8)uchNewGain;\r
+\r
+    if(puchIdealDrvCurrent[0] != uchCurrentDrv)\r
+    {\r
+        uchChangeFlag |= 0x01;\r
+//        GH3X2X_INFO_LOG_PARAM_AGC("Drv change %d: CurrentDrv=%d,  IdealDrv=%d\r\n",uchMainChnlInfoIndex, uchCurrentDrv, puchIdealDrvCurrent[0]);\r
+    }\r
+    if(puchIdealGain[0] != uchCurrentTiaGain)\r
+    {\r
+        uchChangeFlag |= 0x02;\r
+//        GH3X2X_INFO_LOG_PARAM_AGC("Gain change %d: CurrentGain=%d,  IdealGain=%d\r\n",uchMainChnlInfoIndex, uchCurrentTiaGain, puchIdealGain[0]);\r
+    }\r
+        \r
+    return uchChangeFlag;\r
+}\r
+\r
+GU8 NewAgcMainChelFlag = 0;\r
+\r
+void GH3X2X_NewAgcMainChnlPro(GU8* puchReadFifoBuffer, GU16 usFifoLen, STGh3x2xAgcInfo *STGh3x2xAgcInfo)\r
+{\r
+    GU32 unNewAgcRawdataMeanChnl[8] = {0};\r
+    GU8 uchAdjFlag = 0;     // Local variables used as judgments must be initialized to 0\r
+    GU8 uchNewDrvCurrent;\r
+    GU8 uchNewGain;    \r
+    GU8 uchChangeFlag = 0;  //bit0: drv current flag  bit1: gain flag\r
+    \r
+    if(0 == GH3X2X_NEW_AGC_SLOT_NUM_LIMIT)\r
+    {\r
+        return;\r
+    }\r
+\r
+#if GH3X2X_SPO2_SELF_TEST\r
+\r
+    GH3X2X_Spo2AgcFifoDataGen();\r
+    puchReadFifoBuffer = g_uchSpo2AgcFifoBuffer;\r
+    usFifoLen = g_usSpo2AgcFifoLen;\r
+#endif\r
+           \r
+    GH3X2X_NewAgcMainChnlMeanValueCal( puchReadFifoBuffer,usFifoLen,unNewAgcRawdataMeanChnl,&uchAdjFlag); // caculate mean and whther adjust gain  current \r
+               \r
+    for(GU8 uchSlotCnt = 0; uchSlotCnt < GH3X2X_NEW_AGC_SLOT_NUM_LIMIT; uchSlotCnt ++)\r
+    {\r
+        if( uchAdjFlag & (1<<uchSlotCnt)) // need to AGC\r
+        {\r
+            STGh3x2xNewAgcMainChnlInfo *pstAgcMainChnlInfo = &g_pstGh3x2xNewAgcMainChnlInfoEntity[uchSlotCnt];\r
+            uchChangeFlag = GH3X2X_NewAgcCalDrvCurrentAndGain(unNewAgcRawdataMeanChnl[uchSlotCnt], uchSlotCnt, &uchNewDrvCurrent,&uchNewGain);\r
+            GU8  uchSlotIdx = ((pstAgcMainChnlInfo ->uchSlotAdc >> 2) & 0x0f);\r
+            if(uchChangeFlag&0x02)  //write tia gain to chip\r
+            {    \r
+                GH3x2xSetAgcReg(GH3X2X_AGC_REG_TIA_GAIN_RX0 + pstAgcMainChnlInfo ->uchBakRegAgcSrc, uchSlotIdx, uchNewGain);    \r
+                pstAgcMainChnlInfo->uchCurrentTiaGain = uchNewGain;\r
+                GH3X2X_StoreRxTiaGainAfterAgc(uchNewGain, uchSlotIdx, pstAgcMainChnlInfo ->uchBakRegAgcSrc, STGh3x2xAgcInfo->uchTiaGainAfterSoftAgc);\r
+                GH3X2X_INFO_LOG_PARAM_AGC("AGC Change gain Slotcfg=%d, AgcSrc=%d, NewGain=%d\r\n", uchSlotIdx,pstAgcMainChnlInfo->uchBakRegAgcSrc, uchNewGain); \r
+            }\r
+            if(uchChangeFlag&0x01)  //write drv current to chip\r
+            {\r
+                //change drv0/1\r
+                pstAgcMainChnlInfo ->uchCurrentDrv = uchNewDrvCurrent;\r
+                \r
+                if((pstAgcMainChnlInfo ->uchBakRegAgcEn)&0x01)\r
+                {\r
+                    GH3x2xSetAgcReg(GH3X2X_AGC_REG_LED_CURRENT_DRV0, uchSlotIdx, uchNewDrvCurrent);    \r
+                    GH3X2X_StoreDrvCurrentAfterAgc(pstAgcMainChnlInfo ->uchCurrentDrv, uchSlotIdx,0,STGh3x2xAgcInfo->uchDrvCurrentAfterSoftAgc); \r
+                }\r
+                if((pstAgcMainChnlInfo ->uchBakRegAgcEn)&0x02)\r
+                {\r
+                    GH3x2xSetAgcReg(GH3X2X_AGC_REG_LED_CURRENT_DRV1, uchSlotIdx, uchNewDrvCurrent);    \r
+                    GH3X2X_StoreDrvCurrentAfterAgc(pstAgcMainChnlInfo ->uchCurrentDrv, uchSlotIdx,1,STGh3x2xAgcInfo->uchDrvCurrentAfterSoftAgc);  \r
+                }\r
+                #if GH3X2X_NEW_AGC_SUB_CHNL_NUM_LIMIT > 0\r
+                GH3x2xNewAgcSubChnlClearAnalysisCntAndSetGain(uchSlotIdx, 0x0F, 0xFF); //clear all rx analysis cnt in this slot\r
+                #endif\r
+                GH3X2X_INFO_LOG_PARAM_AGC("AGC Change Current Slotcfg=%d, AgcEn=%d, NewCurrent=%d\r\n", uchSlotIdx,pstAgcMainChnlInfo->uchBakRegAgcEn, uchNewDrvCurrent); \r
+            }\r
+            if(uchChangeFlag)\r
+            {\r
+                g_pstGh3x2xNewAgcMainChnlMeanInfoEntity[uchSlotCnt].uchHaveAgcAtLastReadPrd = 1; // current or  gain change at last time\r
+                g_pstGh3x2xNewAgcMainChnlMeanInfoEntity[uchSlotCnt].uchDropFlag = 0;\r
+                NewAgcMainChelFlag |= (1<<uchSlotCnt); // ADjFlag write to CSV file\r
+            }                          \r
+        }                   \r
+    }     \r
+}\r
+\r
+#if  __SUPPORT_SOFT_AGC_CONFIG__\r
+/**\r
+ * @fn     static void GH3X2X_LedAgcInit(STGh3x2xAgcInfo *STGh3x2xAgcInfo)\r
+ * \r
+ * @brief  init led agc\r
+ *\r
+ * @attention   just use to show function support\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_LedAgcInit(STGh3x2xAgcInfo *STGh3x2xAgcInfo)\r
+{\r
+    GH3x2xNewAgcChnlInfoInit(STGh3x2xAgcInfo);\r
+}\r
+/**\r
+ * @fn     void GH3X2X_LedAgcPramWrite(GU16 usRegVal, GU16 usRegPosi)\r
+ *\r
+ * @brief  write AGC parameter\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   usRegVal         reg value\r
+ * @param[in]   uchRegPosi         reg posi\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_LedAgcPramWrite(GU16 usRegVal, GU16 usRegPosi)\r
+{\r
+\r
+    GU16 usByteOffset;\r
+    GU8 uchByteVal;\r
+    GU8 uchByteCnt;\r
+    for(uchByteCnt = 0; uchByteCnt < 2; uchByteCnt ++)\r
+    {\r
+        uchByteVal = ((usRegVal >> (8*uchByteCnt))&0x00FF);\r
+        usByteOffset = (usRegPosi * 2) + uchByteCnt;\r
+        if(usByteOffset < sizeof(g_stSoftAgcCfg))\r
+        {\r
+            GH3X2X_Memcpy(((GU8 *)(&g_stSoftAgcCfg)) + usByteOffset, (GU8*)(&uchByteVal), 1);\r
+        }      \r
+    }\r
+}\r
+\r
+/**\r
+ * @fn  void GH3X2X_LedAgcReset(void)\r
+ *\r
+ * @brief   reset agc parameter\r
+ *\r
+ * @attention    None\r
+ *\r
+ * @param[in]    None\r
+ * @param[out]   None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_LedAgcReset(void)\r
+{\r
+    GH3X2X_Memset(&g_stSoftAgcCfg, 0, sizeof(STSoftAgcCfg));\r
+    GH3x2xNewAgcModuleReset();\r
+}\r
+\r
+/**\r
+ * @fn     void GH3X2X_LedAgcProcess(GU8* puchReadFifoBuffer, GU16 usFifoLen)\r
+ * \r
+ * @brief  led agc process function\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   puchReadFifoBuffer         pointer to read fifo data buffer\r
+ * @param[in]   usFifoLen           read fifo data buffer length\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+\r
+void GH3X2X_LedAgcProcess(GU8* puchReadFifoBuffer, GU16 usFifoLen, STGh3x2xAgcInfo *STGh3x2xAgcInfo)\r
+{\r
+    GH3X2X_INFO_LOG_PARAM_AGC("GH3X2X_LedAgcProcess call \n");\r
+    if(usFifoLen==0)\r
+    {\r
+        return;\r
+    }\r
+    \r
+    GH3X2X_NewAgcMainChnlPro(puchReadFifoBuffer, usFifoLen,STGh3x2xAgcInfo);\r
+    \r
+#if GH3X2X_NEW_AGC_SUB_CHNL_NUM_LIMIT > 0\r
+    GH3X2X_NewAgcSubChnlGainAdj(puchReadFifoBuffer, usFifoLen,STGh3x2xAgcInfo);\r
+#endif\r
+               \r
+}\r
+\r
+#define GH3X2X_SOFT_AGC_VERSION "SoftAgc_V4.2.0.0"\r
+\r
+char* GH3X2X_GetSoftAgcVersion(void)\r
+{\r
+       return GH3X2X_SOFT_AGC_VERSION;\r
+}\r
+#endif\r
+\r
+#endif\r
+/********END OF FILE********* Copyright (c) 2003 - 2022, Goodix Co., Ltd. ********/\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/module/gh_agc/gh_agc.h b/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/module/gh_agc/gh_agc.h
new file mode 100644 (file)
index 0000000..a99ecab
--- /dev/null
@@ -0,0 +1,178 @@
+/**\r
+ * @copyright (c) 2003 - 2022, Goodix Co., Ltd. All rights reserved.\r
+ *\r
+ * @file    gh3x2x_drv_soft_led_agc.h\r
+ *\r
+ * @brief   gh3x2x led agc process functions\r
+ *\r
+ * @version ref gh3x2x_drv_version.h\r
+ *\r
+ */\r
+\r
+\r
+#ifndef _GH3X2X_DRV_SOFT_LED_AGC_H_\r
+#define _GH3X2X_DRV_SOFT_LED_AGC_H_\r
+ \r
+ \r
+#include "gh_drv_config.h"\r
+#include "gh_drv.h"\r
+\r
+#define  GH3X2X_LED_AGC_DISABLE             (0)\r
+#define  GH3X2X_LED_AGC_ENABLE              (1)\r
+\r
+\r
+/// led agc adc num max\r
+#define  GH3X2X_AGC_ADC_NUM_MAX             (4u)\r
+\r
+/// led agc gain limit number\r
+#define  GH3X2X_AGC_LIMIT_NUM_MAX           (4u)\r
+\r
+/// raw data base line value\r
+#define  GH3X2X_DATA_BASE_LINE              (8388608)   //2^23 \r
+\r
+/// sys sample rate, 32kHz\r
+#define  GH3X2X_SYS_SAMPLE_RATE             (32000)\r
+#define GH3X2X_FASTEST_SAMPLERATE_ADDR          0x0004\r
+\r
+/**\r
+ * @brief soft lead result\r
+ */\r
+typedef struct\r
+{\r
+    GU8 uchAmbSampleEn  : 2;                /**< AMB sampling enable */\r
+    GU8 uchAmbSlot      : 3;                /**< slot of amb sampling */\r
+    GU8 uchRes          : 3;                /**< reserved */\r
+} STAmbSlotCtrl;\r
+ \r
+ /**\r
+ * @brief gain limit\r
+ */\r
+typedef struct\r
+{\r
+    GU8 uchGainLimitBg32uA  : 4;          /**< gain limit bg current */\r
+    GU8 uchGainLimitBg64uA  : 4;          \r
+    GU8 uchGainLimitBg128uA : 4;        \r
+    GU8 uchGainLimitBg256uA : 4;\r
+} STSoftAgcGainLimit;\r
+\r
+ /**\r
+  * @brief soft agc parameter\r
+  */\r
+typedef struct\r
+{\r
+    GU8 uchSlotxSoftAgcAdjEn;              /**< soft agc enable */\r
+    GU8 uchSlotxSoftBgAdjEn;               /**< soft bg cancel adjust enable */\r
+    STAmbSlotCtrl stAmbSlotCtrl;           /**< amb slot ctrl */\r
+    GU8 uchRes0;                           /**< reserved */\r
+    GU8 uchSpo2RedSlotCfgEn;\r
+    GU8 uchSpo2IrSlotCfgEn;\r
+    STSoftAgcGainLimit stSoftAgcGainLimit; /**< soft gain limit */\r
+    GU32 unAgcTrigThd_H;                   /**< trig threshold(high) of soft agc */\r
+    GU32 unAgcTrigThd_L;                   /**< trig threshold(low) of soft agc */\r
+    GU32 unAgcRestrainThd_H;               /**< restrain threshold(high) of soft agc */\r
+    GU32 unAgcRestrainThd_L;               /**< restrain threshold(low) of soft agc */\r
+} STSoftAgcCfg;\r
+\r
+\r
+void GH3X2X_LedAgcReset(void);\r
+void GH3X2X_LedAgcPramWrite(GU16 usRegAddr, GU16 usRegData);\r
+void GH3X2X_LedAgcInit(STGh3x2xAgcInfo *STGh3x2xAgcInfo);\r
+void GH3X2X_LedAgcProcess(GU8* puchReadFifoBuffer, GU16 usFifoLen, STGh3x2xAgcInfo *STGh3x2xAgcInfo);\r
+void GH3X2X_LedAgc_Close(void);\r
+void GH3X2X_LedAgc_Open(void);\r
+\r
+\r
+///* slot register ctrl index */\r
+//#define  GH3X2X_SLOT_REG_CTRL_0             (0)    /**< slot x ctrl 0 reg */\r
+//#define  GH3X2X_SLOT_REG_CTRL_1             (1)    /**< slot x ctrl 1 reg */\r
+//#define  GH3X2X_SLOT_REG_CTRL_2             (2)    /**< slot x ctrl 2 reg */\r
+//#define  GH3X2X_SLOT_REG_CTRL_3             (3)    /**< slot x ctrl 3 reg */\r
+//#define  GH3X2X_SLOT_REG_CTRL_4             (4)    /**< slot x ctrl 4 reg */\r
+//#define  GH3X2X_SLOT_REG_CTRL_5             (5)    /**< slot x ctrl 5 reg */\r
+//#define  GH3X2X_SLOT_REG_CTRL_6             (6)    /**< slot x ctrl 6 reg */\r
+//#define  GH3X2X_SLOT_REG_CTRL_7             (7)    /**< slot x ctrl 7 reg */\r
+//#define  GH3X2X_SLOT_REG_CTRL_8             (8)    /**< slot x ctrl 8 reg */\r
+//#define  GH3X2X_SLOT_REG_CTRL_9             (9)    /**< slot x ctrl 9 reg */\r
+//#define  GH3X2X_SLOT_REG_CTRL_10            (10)   /**< slot x ctrl 10 reg */\r
+//#define  GH3X2X_SLOT_REG_CTRL_11            (11)   /**< slot x ctrl 11 reg */\r
+//#define  GH3X2X_SLOT_REG_CTRL_12            (12)   /**< slot x ctrl 12 reg */\r
+//#define  GH3X2X_SLOT_REG_CTRL_13            (13)   /**< slot x ctrl 13 reg */\r
+\r
+//#define GH3X2X_BG_LEVEL_BIT_MASK            (0x0030)\r
+//#define GH3X2X_ADC_BG_CANCEL_32_UA          (0x0)\r
+//#define GH3X2X_ADC_BG_CANCEL_64_UA          (0x1)\r
+//#define GH3X2X_ADC_BG_CANCEL_128_UA         (0x2)\r
+//#define GH3X2X_ADC_BG_CANCEL_256_UA         (0x3)\r
+\r
+///// amb slot select\r
+//#define GH3X2X_AGC_AMB_SLOT_DISABLE         (0x0)\r
+//#define GH3X2X_AGC_AMB_SLOT_USER_DEFINED    (0x1)\r
+//#define GH3X2X_AGC_AMB_SLOT_FOLLOW_CFG      (0x2)\r
+\r
+///// get bits data\r
+//#define GH3X2X_GET_REG_BITS_U16(reg_data, lsb, msb)       (((reg_data) & ((0xFFFF << (lsb)) & \\r
+//                                                            (0xFFFF >> (15 - (msb))))) >> (lsb))\r
+\r
+///// set bits data\r
+//#define GH3X2X_SET_REG_BITS_U16(reg, lsb, msb, value)     ((reg) = (((reg) & ((0xFFFF << (lsb)) ^ \\r
+//                                                                  (0xFFFF >> (15 - (msb))))) | ((value) << (lsb))))\r
+\r
+///// get adc gain\r
+//#define GH3X2X_GET_ADC_GAIN(reg_data, adc_no)             GH3X2X_GET_REG_BITS_U16((reg_data), ((adc_no) * 4), \\r
+//                                                                ((adc_no) * 4 + 3))\r
+\r
+///// set adc gain\r
+//#define GH3X2X_SET_ADC_GAIN(reg_data, adc_no, gain)       GH3X2X_SET_REG_BITS_U16((reg_data), ((adc_no) * 4), \\r
+//                                                                ((adc_no) * 4 + 3), (gain))\r
+\r
+///// get bg cancel i_dacfs\r
+//#define GH3X2X_GET_BGC_I_DACFS(reg_data, adc_no)          GH3X2X_GET_REG_BITS_U16((reg_data), ((adc_no) << 1), \\r
+//                                                                ((adc_no) * 2 + 1))\r
+\r
+///// set bg cancel i_dacfs\r
+//#define GH3X2X_SET_BGC_I_DACFS(reg_data, adc_no, i_dacfs) GH3X2X_SET_REG_BITS_U16((reg_data), ((adc_no) * 2), \\r
+//                                                              ((adc_no) * 2 + 1), (i_dacfs))\r
+//                                                                                         \r
+//#define ABS(x) ((x) > 0 ? (x) : -(x))\r
+\r
+///// transfer int to float\r
+//#define GH3X2X_TRANS_INT_TO_FLOAT           (1.0f)\r
+\r
+///// agc calc seconds (250ms)\r
+//#define GH3X2X_AGC_CALC_SECONDS             (0.25f)\r
+\r
+///// agc bgc donw cnt, 5s\r
+//#define GH3X2X_AGC_BGC_DOWN_CNT             (20)\r
+\r
+///// slot tia gain val min\r
+//#define GH3X2X_AGC_GAIN_MIN_VAL             (0)\r
+\r
+///// slot tia gain val max, 5s, equal (GH3X2X_SLOT_TIA_GAIN_VAL_MAX - 1)\r
+//#define GH3X2X_AGC_GAIN_MAX_VAL             (12)\r
+\r
+///// Less than thr, include rawdata < thr\r
+//#define GH3X2X_AGC_EXCD_FLAG_LESS           (0x01)\r
+\r
+///// greater than thr, include rawdatamix > thr | rawdata > thr\r
+//#define GH3X2X_AGC_EXCD_FLAG_GREATER        (0x06)\r
+\r
+///// AGC failure reason\r
+//#define GH3X2X_AGC_FAILURE_REASON_1         (0x1) \r
+//#define GH3X2X_AGC_FAILURE_REASON_2         (0x2)\r
+//#define GH3X2X_AGC_FAILURE_REASON_4         (0x4)\r
+//#define GH3X2X_AGC_FAILURE_REASON_5         (0x5)\r
+//#define GH3X2X_AGC_FAILURE_REASON_6         (0x6)\r
+\r
+//#define GH3X2X_AGC_CHECK_EN_BITS(x)         (((x) & (0x03 << 8)) != 0)      /**< check enable bits of ctrl3 */\r
+//#define GH3X2X_AGC_GET_SRC_BITS(x)          (((x) >> 6) & 0x03)             /**< get agc src bits of ctrl3 */\r
+//#define GH3X2X_AGC_CHECK_BG_2X2_BITS(x)     (((x) & (0x03 << 4)) == 0x03)   /**< check 2x2 bg lvl bits of ctrl3 */\r
+//#define GH3X2X_AGC_SET_SRC_BITS(x, n)       (((x) & 0xFF3Fu) | ((n) << 6u)) /**< set agc src bits of ctrl3 */\r
+\r
+//#define GH3X2X_AGC_GET_DONE_FAIL_BIT(x, i)  (((x) >> (i)) & 0x01)           /**< get tune done/fail bit of flag */\r
+//#define GH3X2X_AGC_REG_BIT(x, i)            (((x) >> (i)) & 0x01)           /**< get reg bit value */\r
+//#define GH3X2X_AGC_GET_RESULT_BITS(x, i)    (((x) >> (i)) & 0x07)           /**< get result bits of flag  */\r
+//#define GH3X2X_AGC_RESULT_BITS_SIZE         (3u)                           /**< one result 3 bits size of flag  */\r
+\r
+#endif  // _GH3X2X_DRV_SOFT_LED_AGC_H_\r
+\r
+/********END OF FILE********* Copyright (c) 2003 - 2022, Goodix Co., Ltd. ********/\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/module/gh_ecg/gh_ecg.c b/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/module/gh_ecg/gh_ecg.c
new file mode 100644 (file)
index 0000000..e77ef1b
--- /dev/null
@@ -0,0 +1,1691 @@
+/**\r
+ * @copyright (c) 2003 - 2022, Goodix Co., Ltd. All rights reserved.\r
+ *\r
+ * @file    gh3x2x_drv_soft_lead.c\r
+ *\r
+ * @brief   gh3x2x lead process functions\r
+ *\r
+ * @version ref gh3x2x_drv_version.h\r
+ *\r
+ */\r
+\r
+#include <stdio.h>\r
+#include "gh_drv_version.h"\r
+#include "gh_drv_common.h"\r
+#include "gh_drv.h"\r
+#include "gh_drv_interface.h"\r
+#include "gh_drv_control.h"\r
+#include "gh_uprotocol.h"\r
+#include "gh_ecg.h"\r
+#include "gh_demo_config.h"\r
+#include "gh_multi_sen_pro.h"\r
+\r
+#define GH3X2X_LEAD_OFF_SUPPORT_ECG (1)\r
+#if GH3X2X_LEAD_OFF_SUPPORT_ECG\r
+#define GH3X2X_LEAD_OFF_VERSION_DOUBLE         0\r
+#define GH3X2X_LEAD_OFF_VERSION_FLOAT          1\r
+#define GH3X2X_LEAD_OFF_VERSION_FIX_POINT      2\r
+\r
+#define GH3X2X_LEAD_OFF_VERSION         GH3X2X_LEAD_OFF_VERSION_FIX_POINT\r
+#endif\r
+\r
+#define __SUPPORT_ECG_PPG_DOWNSAMP__  1\r
+\r
+#ifdef GOODIX_DEMO_PLATFORM\r
+#define GH3X2X_DOWNSAMPLE_OPENALL     1\r
+#else\r
+#define GH3X2X_DOWNSAMPLE_OPENALL     0\r
+#endif\r
+\r
+\r
+\r
+#if __FUNC_TYPE_ECG_ENABLE__\r
+\r
+GU8 g_uchEcgCascadeEn = 0;\r
+GU8 g_uchEcgCascadeWriteRegVerifyEn = 0;\r
+///0: not init  1: initialized\r
+extern GU8 g_uchEcgCascadeSlaveInitSuccess;\r
+\r
+//Ecg sample rate from hardware\r
+static GU16 g_usEcgOutputFs = 0;\r
+\r
+/// LEADOFF_DET_DIF_THR_MV*Gain*RAWMAX/ADCRef, if GH3100 VDDTx=3.3V,ADCRef=1800,if VDDTx=1.8,ADCRef=1600;\r
+__attribute__((used)) static GS32 g_nLeadoffDiffThrdRawData = SOFT_LEAD_OFF_DIFF_THR_DEFAULT_VAL;\r
+\r
+/// LEADOFF_DET_VAL_THR_MV*Gain*RAWMAX/ADCRef, if GH3100 VDDTx=3.3V,ADCRef=1800,if VDDTx=1.8,ADCRef=1600;\r
+__attribute__((used)) static GS32 g_nLeadoffPeakThrdRawData = SOFT_LEAD_OFF_PEAK_THR_DEFAULT_VAL;\r
+\r
+/// lead off base thr\r
+__attribute__((used)) static GS32 g_nLeadoffBaseThrdRawData = SOFT_LEAD_OFF_BASE_THR_DEFAULT_VAL;\r
+\r
+/// lead off detect moving buffer\r
+GS32 g_nLeadOffDetEcgBuffer2Arr[LEADOFF_MOVING_NUM];\r
+\r
+/// buffer to head\r
+GS32 g_nBuf2Head = 0;\r
+\r
+/// valid counter\r
+GU32 g_unValidCounter = 0;\r
+\r
+/// reset counter\r
+GU32 g_unResetCounter = 0;\r
+\r
+/// current sum\r
+GS32 g_nCurEcgSum = 0;\r
+\r
+/// lead off det init status\r
+GU32 g_unLeadOffDetInitState2 = 0;\r
+\r
+/// ecg gain map, amplify 10x\r
+static const GU8 g_uchEcgGainMapArr[] =\r
+{\r
+    10, 25, 50, 100, 200\r
+};\r
+\r
+/// adc ref map, amplify 10x\r
+static const GU8 g_uchAdcRefMapArr[] =\r
+{\r
+    16, 18\r
+};\r
+\r
+/// lead state in soft lead module\r
+static GU8 g_uchLeadStateInSoftLeadModule = LEAD_STATE_LEAD_OFF;\r
+\r
+/// down sample lead module(ECG PPG BT)\r
+static GU8 g_uchDownSampleModule = DOWNSAMPLE_ECG;\r
+\r
+/// ecg or pwtt function enable \r
+static GU8 g_uchEcgOrPwttFunctionEn = 0;\r
+\r
+/// ecg sampling status\r
+GU8 g_uchEcgSampleStatus = 0;\r
+GU8 g_uchLastEcgSampleFlag = 0;    // 0: last time ecg is  not sampling  1:  last time ecg is sampling  //G202008031001 wanpeng\r
+GU8 g_uchIsItyp0nAPeriod = 0;   // 0: current is not itype 0nA period  //1: current is itype 0nA period  //G202010311001 wanpeng\r
+/// R type mode enable flag\r
+GU8 g_uchRtypeModeEn = 1;\r
+\r
+STEcgLeadCfg g_stEcgLeadCfg;\r
+\r
+#endif\r
+\r
+extern void GH3X2X_CalRawdataBuf(GU8 *puchRawdata, GU16 usRawdataLen);\r
+extern GU8 GH3X2X_CheckRawdataBuf(GU8 *puchRawdata, GU16 usRawdataLen);\r
+\r
+#if __FUNC_TYPE_ECG_ENABLE__\r
+\r
+STAdtCfg g_stAdtModuleCfg;\r
+\r
+/**\r
+ * @fn     void GH3X2X_AdtPramInit(void)\r
+ *\r
+ * @brief  GH3X2X_AdtPramInit\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+\r
+void GH3X2X_AdtPramInit(void)\r
+{\r
+    GH3X2X_Memset(((GU8 *)(&g_stAdtModuleCfg)),0, sizeof(g_stAdtModuleCfg));\r
+}\r
+\r
+/**\r
+ * @fn     void GH3X2X_AdtPramSet(GU16 usRegVal, GU8 uchRegPosi)\r
+ *\r
+ * @brief  GH3X2X_AdtPramSet\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   usRegVal\r
+ * @param[in]   uchRegPosi\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_AdtPramSet(GU16 usRegVal, GU8 uchRegPosi)\r
+{    \r
+\r
+    GU8 uchByteOffset;\r
+    GU8 uchByteVal;\r
+    GU8 uchByteCnt;\r
+    for(uchByteCnt = 0; uchByteCnt < 2; uchByteCnt ++)\r
+    {\r
+        uchByteVal = ((usRegVal >> (8*uchByteCnt))&0x00FF);\r
+        uchByteOffset = (uchRegPosi * 2) + uchByteCnt;\r
+        if(uchByteOffset < sizeof(g_stAdtModuleCfg))\r
+        {\r
+            GH3X2X_Memcpy(((GU8 *)(&g_stAdtModuleCfg)) + uchByteOffset, (GU8*)(&uchByteVal), 1);\r
+        }\r
+    }\r
+}\r
+\r
+void GH3X2X_WriteAdtDrvConfigWithVirtualReg(GU16 usVirtualRegAddr, GU16 usVirtualRegValue)\r
+{\r
+    GU16 usValIndex;\r
+    switch (usVirtualRegAddr)\r
+    {\r
+    case 0x0144:\r
+      break;\r
+    case 0x0146:\r
+      break;\r
+    default:\r
+      usValIndex = (usVirtualRegAddr - GH3X2X_ADT_CONFIG0_ADDR) / GH3X2X_REG_ADDR_SIZE;\r
+      GH3X2X_AdtPramSet(usVirtualRegValue, usValIndex);\r
+      break;\r
+    }\r
+}\r
+\r
+/**\r
+ * @fn     GU8 GH3X2X_ElectrodeWearRevertDebugModeIsEnabled(void)\r
+ *\r
+ * @brief  Check if electrode wear revert debug mode is enabled\r
+ *\r
+ * @attention   In this mode,not need report wear event,need report the number of wear electrode revert.\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  1: enabled, 0:disabled\r
+ */\r
+GU8 GH3X2X_ElectrodeWearRevertDebugModeIsEnabled(void)\r
+{\r
+    return g_stAdtModuleCfg.stAdtCfgByte0.uchElectrodeWearRevCntEn;\r
+}\r
+\r
+#if ((defined(GH3X2X_LEAD_OFF_VERSION)) && (GH3X2X_LEAD_OFF_VERSION == GH3X2X_LEAD_OFF_VERSION_DOUBLE))\r
+#elif ((defined(GH3X2X_LEAD_OFF_VERSION)) && (GH3X2X_LEAD_OFF_VERSION == GH3X2X_LEAD_OFF_VERSION_FIX_POINT))\r
+\r
+#define ADCREF 1800   \r
+#define ADC_OFFSET (1<<23)\r
+//#define IS_BIG_ENDIAN 1  //data read from GH3100 FIFO is big endian?\r
+#define PI 3.14159265\r
+#define  ABS(x) ( (x)>0?(x):(-(x)) ) \r
+\r
+#define NEEDRESAMPLE 1\r
+#if GH3X2X_DOWNSAMPLE_OPENALL\r
+#define RESAMPLE_800HZ_TO_500HZ 1\r
+#define RESAMPLE_800HZ_TO_250HZ 1\r
+#define RESAMPLE_320HZ_TO_250HZ 1 \r
+#define RESAMPLE_256HZ_TO_250HZ 1 \r
+#else\r
+#define RESAMPLE_800HZ_TO_500HZ 1\r
+#define RESAMPLE_800HZ_TO_250HZ 0\r
+#define RESAMPLE_320HZ_TO_250HZ 0 \r
+#define RESAMPLE_256HZ_TO_250HZ 0 \r
+#endif\r
+\r
+#if __SUPPORT_ECG_PPG_DOWNSAMP__\r
+#define RESAMPLE_400HZ_TO_250HZ 1 \r
+#else\r
+#define RESAMPLE_400HZ_TO_250HZ 0 \r
+#endif\r
+\r
+#define AMP_NUM 5  \r
+\r
+#if  RESAMPLE_256HZ_TO_250HZ\r
+#define IQ_NUM 48  \r
+#else\r
+#define IQ_NUM 48  \r
+#endif\r
+\r
+const int winCoef[IQ_NUM / 2] = { 0, 9580474, 38150933, 85201535, 149892663, 231069901, 327284639, 436819923, 557721094, 687830666, 824826833, 966264894, 1109620882, 1252336609, 1391865307, 1525717084, 1651503351, 1766979451, 1870084709, 1958979209, 2032076627, 2088072537, 2125967693, 2145085852};\r
+#define winAmpCoef  4082 \r
+//unsigned char gscFlagFrPrev = 0; \r
+GU32 g_nLeadOffDetIqAmpThr;//unit: uv\r
+long long g_lLeadOffDetIqAmp;\r
+long long  g_lLeadOffDetIqAmpThrRaw;\r
+long long  g_lLeadOffDetIqAmpFrThrRaw;\r
+\r
+GU32 g_nLeadOffDetIqAmpDiffThr;//unit: uv\r
+long long g_lLeadOffDetIqAmpDiff;\r
+long long g_lLeadOffDetIqAmpDiffThrRaw;\r
+long long g_lLeadOffDetIqAmpDiffFrThrRaw;\r
+\r
+int COND_VAL_VALID_TIME = 1; \r
+GU32 g_nLeadOffDetValThr;//unit: mv\r
+int g_LeadOffDetValThrRaw;\r
+\r
+#if NEEDRESAMPLE\r
+\r
+#define SHIFTBITS 30\r
+\r
+#if RESAMPLE_800HZ_TO_500HZ\r
+    const int rsFirCoef_800_500hz[] = { 58200, 102435, 156130, 215460, 274735, 326585, 362380, 372790, 348645, 281870, 166550, 0, -216285, -475850, -766815, -1071825, -1368460, -1630170, -1827760, -1931325, -1912605,\r
+                                -1747635, -1419445, -920670, -255820, 557070, 1485515, 2482735, 3488860, 4433375, 5238695, 5824850, 6114965, 6041350, 5551740, 4615280, 3227790, 1415785, -761100, -3209770, -5805610, -8396875, -10811545, -12866385,\r
+                                -14377925, -15174745, -15110485, -14076620, -12014295, -8924190, -4873605, 0, 5489625, 11323885, 17176845, 22682405, 27452740, 31100030, 33260510, 33619540, 31936265, 28066360, 21981325, 13782945, 3711580, -7852615,\r
+                                -20396185, -33286830, -45795550, -57125820, -66448630, -72941905, -75832375, -74437800, -68207360, -56757870, -39903755, -17678885, 9651270, 41588185, 77410100, 116192965, 156841955, 198132190, 238757000, 277381455, 312698655, 343486005, 368658785, 387318230, 398791740, 402663190 };\r
+#endif\r
+#if RESAMPLE_800HZ_TO_250HZ\r
+    const int rsFirCoef_800_250hz[] = { -74905, -95385, -116975, -138740, -159540, -178080, -192900, -202440, -205060, -199120, -183040, -155365, -114830, -60455, 8370, 91845, 189655, 300920, 424150, 557225, 697345, 841065, 984315, 1122440, 1250290, 1362325,\r
+                                1452720, 1515555, 1544935, 1535220, 1481220, 1378385, 1223050, 1012615, 745780, 422705, 45175, -383265, -857210, -1369370, -1910565, -2469770, -3034240, -3589685, -4120510, -4610090, -5041145, -5396125, -5657660, -5809045, -5834740, -5720895, -5455890,\r
+                                -5030825, -4440010, -3681420, -2757070, -1673325, -441140, 923805, 2401100, 3965690, 5588100, 7234765, 8868540, 10449275, 11934545, 13280495, 14442770, 15377525, 16042520, 16398240, 16409055, 16044325, 15279560, 14097430, 12488725, 10453225, 8000385,\r
+                                5149865, 1931900, -1612575, -5431990, -9464450, -13638290, -17872830, -22079425, -26162660, -30021820, -33552510, -36648435, -39203325, -41112955, -42277200, -42602135, -42002095, -40401670, -37737600, -33960495, -29036370, -22947970, -15695790,\r
+                                -7298825, 2204995, 12758710, 24286615, 36694830, 49872305, 63692080, 78012930, 92681285, 107533410, 122397830, 137097950, 151454790, 165289835, 178427925, 190700125, 201946505, 212018845, 220783110, 228121755, 233935695, 238146055, 240695490, 241549195 };\r
+#endif\r
+\r
+#if RESAMPLE_400HZ_TO_250HZ\r
+//const int rsFirCoef_250hz1[] = { 0,-24495,-56710,-95045,-136775,-178125,-214440,-240490,-250920,-240760,-205965,-144050,-54555,60475,196250,345190,497105,639650,759070,841160,872410,841285,739500,563245,314150,0,-365010,-760510,-1160685,-1535620,-1853070,-2080745,-2188790,-2152475,-1954770,-1588670,-1058960,-383360,407260,1269625,2149850,2986210,3712890,4264415,4580525,4611280,4321835,3696680,2742865,1491895,0,-1653335,-3368750,-5032125,-6521320,-7714135,-8497040,-8774130,-8475685,-7565610,-6047220,-3966715,-1413955,1479820,4547350,7593800,10407850,12774895,14491705,15381495,15308470,14190830,12011055,8822720,4752940,0,-5174080,-10455925,-15497715,-19937805,-23423930,-25637735,-26318950,-25287690,-22463185,-17877445,-11682610,-4150955,4332910,13287805,22159230,30349170,37251070,42288110,44952645,44844420,41705155,35447110,26173540,14189250,0,-15699840,-32051440,-48066690,-62673020,-74765800,-83265770,-87178475,-85652480,-78033065,-63908265,-43144325,-15908305,17323970,55775495,98391360,143876925,190749335,237400000,282164985,323399855,359555130,389248460,411329760,424935830,429531605};\r
+const int rsFirCoef_250hz2[] = {-20165,29190,117750,248970,420650,623445,839855,1044105,1203060,1278285,1229350,1018175,614220,0,-823490,-1832200,-2975865,-4177020,-5332555,-6318335,-6996880,-7227970,-6881615,-5852620,-4075600,-1539030,1703020,5523035,9717440,14010255,18063685,21495860,23905235,24900525,24134595,21339975,16363405,9196555,0,-10882185,-22919440,-35404830,-47478995,-58167535,-66430495,-71221570,-71553685,-66566985,-55594615,-38221750,-14333265,15853795,51776230,92531020,136902815,183411755,230379530,276010140,318480795,356037520,387089565,410296710,424643805,429497860,};\r
+#endif\r
+        \r
+#if RESAMPLE_320HZ_TO_250HZ\r
+    const int rsFirCoef_320_250hz[] = {79095,936340,341760,-2712470,-2547785,4817105,8099190,-5170865,-17933790,0,30974265,15517780,-42765395,-45670380,44706790,92106715,-24021395,-152053275,-36768905,217784250,166596045,-277901355,-451953470,320248390,1667310365,2147483647,};\r
+#endif\r
+#if RESAMPLE_256HZ_TO_250HZ\r
+    const int rsFirCoef_256_250hz[]={194000,77770,-331070,-632290,-254280,769680,1439880,622640,-1454740,-2779600,-1303600,2436730,4847325,2461115,-3753755,-7872475,-4310105,5424840,12120690,7126740,-7444180,-17902495,-11265025,9777230,25594875,17187555,-12359260,-35689230,-25526795,15096890,48893725,37213545,-17872685,-66356185,-53763065,20552645,90184745,77974330,-22995885,-124828195,-115908245,25065740,181561700,183974820,-26641130,-299102515,-347934030,27626950,749679370,1463910805,1761638120,};\r
+#endif\r
+\r
+GS32* rsFirCoef;\r
+GS32* rsFirCoef1;\r
+        \r
+STGh3x2xDownSampleCalParamInfo pstECGDownSampCalParamInfo[1];\r
+#if __SUPPORT_ECG_PPG_DOWNSAMP__\r
+STGh3x2xDownSampleCalParamInfo pstPPGDownSampCalParamInfo[1];\r
+#endif\r
+\r
+void GH3X2X_DownSampleMarcoIni(GU16 usEcgSampleRate)\r
+{\r
+    switch (g_usEcgOutputFs)\r
+    {\r
+    case 800:\r
+        if( usEcgSampleRate == 500)\r
+        {\r
+            pstECGDownSampCalParamInfo->uchDownSampleType = DOWNSAMPLE_800HZ_TO_500HZ;\r
+        }\r
+        else\r
+        {\r
+            pstECGDownSampCalParamInfo->uchDownSampleType = DOWNSAMPLE_800HZ_TO_250HZ;\r
+        }\r
+        break;\r
+    case 320:\r
+        if( usEcgSampleRate == 250)\r
+        {\r
+            pstECGDownSampCalParamInfo->uchDownSampleType = DOWNSAMPLE_320HZ_TO_250HZ;\r
+        }\r
+        break;\r
+    case 256:\r
+        if( usEcgSampleRate == 250)\r
+        {\r
+            pstECGDownSampCalParamInfo->uchDownSampleType = DOWNSAMPLE_256HZ_TO_250HZ;\r
+        }\r
+        break;\r
+    default: // do nothing\r
+        break;\r
+    }\r
+\r
+    // ppg downsample ini\r
+    #if __SUPPORT_ECG_PPG_DOWNSAMP__\r
+        pstPPGDownSampCalParamInfo->uchDownSampleType = DOWNSAMPLE_400HZ_TO_250HZ;\r
+    #endif\r
+}\r
+\r
+void RsFirResetSingle(GU8 uchChipIndex, GU8 uchMode)\r
+{\r
+    STGh3x2xRsInfo * pstRsInfo = NULL;\r
+    GU8 uchChnNum = 0;\r
+    #if __SUPPORT_ECG_PPG_DOWNSAMP__\r
+    if(DOWNSAMPLE_PPG == uchMode)\r
+    {\r
+        pstRsInfo = g_pstGh3x2xPPGRsInfo;\r
+        uchChnNum = g_uchPPGDownSampleChnlNumLimit;\r
+    }\r
+    #endif\r
+\r
+    if(DOWNSAMPLE_ECG == uchMode)\r
+    {\r
+        pstRsInfo = g_pstGh3x2xEcgRsInfo;\r
+        uchChnNum = uchChipIndex+1;\r
+    }\r
+\r
+    for( GU8 i=0; i<uchChnNum;i++)\r
+    {\r
+        pstRsInfo[i].snBufHead = -1;\r
+        pstRsInfo[i].snRsFirState = 0;\r
+        pstRsInfo[i].nRsIcounter = 0;\r
+        pstRsInfo[i].nRrsDcounter = 0;\r
+        pstRsInfo[i].uchFlagFrPrev = 1;\r
+        pstRsInfo[i].nRsLastRaw = 0;\r
+        pstRsInfo[i].fDownStep = 0;\r
+        pstRsInfo[i].uchLinearInterState = 0;\r
+        pstRsInfo[i].uchLinearDataUpdate = 0;\r
+    }\r
+}\r
+\r
+\r
+void RsFirReset(GU8 uchMode)\r
+{\r
+    RsFirResetSingle(0,uchMode);\r
+    if((g_pstGh3x2xFrameInfo[GH3X2X_FUNC_OFFSET_ECG]->pstFunctionInfo->uchChnlNum > 1)&&(g_uchGh3x2xEcgChnlNumLimit > 1))\r
+    {\r
+        RsFirResetSingle(1,uchMode);\r
+    }\r
+}\r
+\r
+void GH3X2X_ECGResampleConfig(GU16 usEcgSampleRate)\r
+{\r
+    RsFirReset(DOWNSAMPLE_ECG);\r
+    GH3X2X_DownSampleMarcoIni(usEcgSampleRate);\r
+    if(usEcgSampleRate == 500)\r
+    {\r
+        #if RESAMPLE_800HZ_TO_500HZ\r
+        if(DOWNSAMPLE_800HZ_TO_500HZ == pstECGDownSampCalParamInfo->uchDownSampleType)\r
+        {\r
+            pstECGDownSampCalParamInfo->rsFirCoef= (GS32*)rsFirCoef_800_500hz;\r
+            pstECGDownSampCalParamInfo->uchRsFirOrder = 182;\r
+            pstECGDownSampCalParamInfo->uchRsI = 5;\r
+            pstECGDownSampCalParamInfo->uchRsD = 8;\r
+            pstECGDownSampCalParamInfo->uchRsEnable = 1;\r
+        }\r
+        #endif\r
+    }\r
+    else if(usEcgSampleRate == 250)\r
+    {\r
+        #if RESAMPLE_800HZ_TO_250HZ\r
+        if(DOWNSAMPLE_800HZ_TO_250HZ == pstECGDownSampCalParamInfo->uchDownSampleType)\r
+        {\r
+            pstECGDownSampCalParamInfo->rsFirCoef= (GS32*)rsFirCoef_800_250hz;\r
+            pstECGDownSampCalParamInfo->uchRsFirOrder = 250;\r
+            pstECGDownSampCalParamInfo->uchRsI = 5;\r
+            pstECGDownSampCalParamInfo->uchRsD = 16;\r
+            pstECGDownSampCalParamInfo->uchRsEnable = 1;\r
+        }\r
+        #endif\r
+\r
+        #if RESAMPLE_320HZ_TO_250HZ\r
+        if(DOWNSAMPLE_320HZ_TO_250HZ == pstECGDownSampCalParamInfo->uchDownSampleType)\r
+        {\r
+            pstECGDownSampCalParamInfo->rsFirCoef= (GS32*)rsFirCoef_320_250hz;\r
+            pstECGDownSampCalParamInfo->uchRsFirOrder = 50;\r
+            pstECGDownSampCalParamInfo->uchRsI = 1;\r
+            pstECGDownSampCalParamInfo->uchRsD = 1;\r
+            pstECGDownSampCalParamInfo->uchRsEnable = 1;\r
+            pstECGDownSampCalParamInfo->ufStep = 128;\r
+        }\r
+        #endif\r
+\r
+        #if RESAMPLE_256HZ_TO_250HZ\r
+        if(DOWNSAMPLE_256HZ_TO_250HZ == pstECGDownSampCalParamInfo->uchDownSampleType)\r
+        {\r
+            pstECGDownSampCalParamInfo->rsFirCoef= (GS32*)rsFirCoef_256_250hz;\r
+            pstECGDownSampCalParamInfo->uchRsFirOrder = 100;\r
+            pstECGDownSampCalParamInfo->uchRsI = 1;\r
+            pstECGDownSampCalParamInfo->uchRsD = 1;\r
+            pstECGDownSampCalParamInfo->uchRsEnable = 1;\r
+            pstECGDownSampCalParamInfo->ufStep = 1024;\r
+        }\r
+        #endif\r
+    }\r
+    else\r
+    {\r
+        pstECGDownSampCalParamInfo->uchRsEnable = 0;\r
+        return;\r
+    }\r
+\r
+    if(pstECGDownSampCalParamInfo->uchRsFirOrder % 2)\r
+    {\r
+        pstECGDownSampCalParamInfo->uchRsFirCoefNum = ((pstECGDownSampCalParamInfo->uchRsFirOrder+1)/2) ;\r
+    }\r
+    else\r
+    {\r
+        pstECGDownSampCalParamInfo->uchRsFirCoefNum = ((pstECGDownSampCalParamInfo->uchRsFirOrder+2)/2);\r
+    }\r
+    pstECGDownSampCalParamInfo->uchRsBufSize = (pstECGDownSampCalParamInfo->uchRsFirOrder / pstECGDownSampCalParamInfo->uchRsI + 1);\r
+}\r
+#if __SUPPORT_ECG_PPG_DOWNSAMP__\r
+void GH3X2X_PPGResampleConfig(GU16 usPPGSampleRate)\r
+{\r
+    RsFirReset(DOWNSAMPLE_PPG);\r
+    GH3X2X_DownSampleMarcoIni(usPPGSampleRate);\r
+    if(usPPGSampleRate == 250)\r
+    {\r
+        #if RESAMPLE_400HZ_TO_250HZ\r
+        pstPPGDownSampCalParamInfo->rsFirCoef = (GS32*)rsFirCoef_250hz2;\r
+        pstPPGDownSampCalParamInfo->uchRsFirOrder = 126;\r
+        pstPPGDownSampCalParamInfo->uchRsI = 5;\r
+        pstPPGDownSampCalParamInfo->uchRsD = 8;\r
+        pstPPGDownSampCalParamInfo->uchRsEnable = 1;\r
+        #else\r
+        pstPPGDownSampCalParamInfo->uchRsEnable = 0;\r
+        #endif\r
+    }\r
+    else\r
+    {\r
+        pstPPGDownSampCalParamInfo->uchRsEnable = 0;\r
+        return;\r
+    }\r
+\r
+    if(pstPPGDownSampCalParamInfo->uchRsFirOrder % 2)\r
+    {\r
+        pstPPGDownSampCalParamInfo->uchRsFirCoefNum = ((pstPPGDownSampCalParamInfo->uchRsFirOrder+1)/2) ;\r
+    }\r
+    else\r
+    {\r
+        pstPPGDownSampCalParamInfo->uchRsFirCoefNum = ((pstPPGDownSampCalParamInfo->uchRsFirOrder+2)/2);\r
+    }\r
+    pstPPGDownSampCalParamInfo->uchRsBufSize = (pstPPGDownSampCalParamInfo->uchRsFirOrder / pstPPGDownSampCalParamInfo->uchRsI + 1);\r
+}\r
+#else\r
+void GH3X2X_PPGResampleConfig(GU16 usPPGSampleRate)\r
+{\r
+    return;\r
+}\r
+#endif\r
+\r
+void GH3X2X_LeadOffDetectResetSingleChip(GU8 uchChipIndex)\r
+{\r
+    int i;\r
+    STGh3x2xSoftLeadOffDetInfo * pstSoftLeadOffDetInfo = g_pstGh3x2xSoftLeadOffDetInfo + uchChipIndex;\r
+    pstSoftLeadOffDetInfo -> snCounter = 0;\r
+    pstSoftLeadOffDetInfo -> sniqCounter = 0;\r
+    pstSoftLeadOffDetInfo -> snniVal = 0;\r
+    pstSoftLeadOffDetInfo -> snnqVal = 0;\r
+    pstSoftLeadOffDetInfo -> uchFastRecoryHistory = 0;\r
+    for (i = 0; i < AMP_NUM; i++)\r
+        pstSoftLeadOffDetInfo -> snniqAmp[i] = 0;\r
+}\r
+\r
+void GH3X2X_LeadOffDetectReset(void)\r
+{\r
+    GH3X2X_LeadOffDetectResetSingleChip(0);\r
+    if((g_pstGh3x2xFrameInfo[GH3X2X_FUNC_OFFSET_ECG]->pstFunctionInfo->uchChnlNum > 1)&&(g_uchGh3x2xEcgChnlNumLimit > 1))\r
+    {\r
+        GH3X2X_LeadOffDetectResetSingleChip(1);\r
+    }\r
+}\r
+\r
+GS32 GH3X2X_LeadOffDetectInit(void)\r
+{\r
+    GH3X2X_ECGResampleConfig(g_usEcgOutputFs);\r
+    GH3X2X_LeadOffDetectReset();\r
+    return 0;\r
+}\r
+\r
+/**\r
+ * @fn     GU8 GH3X2X_LeadOffDetect(GU8* puchFifoBuffer, GU16 usFifoBufferLen)\r
+ *\r
+ * @brief  Lead off Detection, suppose the increment of  normal ECG value in LEADOFF_DET_POINT_NUM+1 samples point \r
+ *         not exceed   LEADOFF_DET_THR_mV\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   puchFifoBuffer           pointer to read fifo data buffer\r
+ * @param[in]   usFifoBufferLen          read fifo buffer len\r
+ * @param[out]  None\r
+ *\r
+ * @return  lead off status output \r
+ * @retval  #0          not detect lead off\r
+ * @retval  bit0=1      AdcValue larger than thresh\r
+ * @retval  bit1=1      IQ Value larger than thresh\r
+ */\r
+\r
+GU8 GH3X2X_LeadOffDetectSingleChip(GU8* puchFifoBuffer, GU16* pusFifoBufferLen, GU8 unChipIndex)\r
+{\r
+    GU16 usByteIndexTmp = 0;\r
+    GS32 j = 0;\r
+    GU8 uchRet = 0;\r
+    GU32 fifoVal = 0;\r
+    GS32 adcVal = 0;\r
+    GU8  flagFastRecovery = 0;\r
+    GS32 absAdcVal = 0; //ABS of adcVal\r
+    GS64 temp = 0;\r
+\r
+    STGh3x2xSoftLeadOffDetInfo * pstSoftLeadOffDetInfo = g_pstGh3x2xSoftLeadOffDetInfo + unChipIndex;\r
+\r
+    for (usByteIndexTmp = 0; usByteIndexTmp < *pusFifoBufferLen; usByteIndexTmp += GH3X2X_FIFO_RAWDATA_SIZE)\r
+    {\r
+        if (GH3X2X_CHANNEL_MAP_GET(puchFifoBuffer[usByteIndexTmp]) == (g_pstGh3x2xFrameInfo[GH3X2X_FUNC_OFFSET_ECG]->pchChnlMap[unChipIndex] & GH3X2X_SLOT_ADC_NUM_BITS))\r
+        {\r
+            fifoVal = GH3X2X_MAKEUP_DWORD(puchFifoBuffer[usByteIndexTmp], puchFifoBuffer[usByteIndexTmp + 1],puchFifoBuffer[usByteIndexTmp + 2], puchFifoBuffer[usByteIndexTmp + 3]);\r
+            adcVal = (GS32)((fifoVal & 0x00FFFFFF)) - ADC_OFFSET; \r
+            flagFastRecovery = (fifoVal >> 26) & 0x01;\r
+            if(flagFastRecovery)\r
+            {\r
+                pstSoftLeadOffDetInfo->uchFastRecoryHistory = 1;\r
+                GH3X2X_DEBUG_LOG_PARAM("has fast recovery!!!!\r\n");\r
+            }\r
+            if(0 == pstSoftLeadOffDetInfo->uchFastRecoryHistory)\r
+            {\r
+                GH3X2X_DEBUG_LOG_PARAM("Warning: No fast recovery!!!!\r\n");\r
+                continue;\r
+            }\r
+            if (pstSoftLeadOffDetInfo-> uchFlagFrPrev != flagFastRecovery)\r
+            {\r
+                GH3X2X_LeadOffDetectReset();\r
+                pstSoftLeadOffDetInfo->uchFastRecoryHistory = 1;\r
+            }\r
+            pstSoftLeadOffDetInfo-> uchFlagFrPrev = flagFastRecovery;\r
+\r
+            //sample counter\r
+            if (pstSoftLeadOffDetInfo -> snCounter < 20000)\r
+                pstSoftLeadOffDetInfo -> snCounter++;\r
+            \r
+            if (flagFastRecovery == 0 && pstSoftLeadOffDetInfo -> snCounter>COND_VAL_VALID_TIME)\r
+            {\r
+                absAdcVal = ABS(adcVal);\r
+                if (absAdcVal > g_LeadOffDetValThrRaw)\r
+                    uchRet |= 0x01;\r
+            }\r
+            if (pstSoftLeadOffDetInfo -> sniqCounter < IQ_NUM / 2)\r
+            {\r
+                temp = (GS64)adcVal*winCoef[pstSoftLeadOffDetInfo -> sniqCounter];\r
+            }\r
+            else\r
+            {\r
+                temp = (GS64)adcVal*winCoef[IQ_NUM-1 - pstSoftLeadOffDetInfo -> sniqCounter];\r
+            }\r
+            switch (pstSoftLeadOffDetInfo -> sniqCounter%4)\r
+            {\r
+            case 0:\r
+                pstSoftLeadOffDetInfo -> snniVal += temp;\r
+                break;\r
+            case 1:\r
+                pstSoftLeadOffDetInfo -> snnqVal += temp;\r
+                break;\r
+            case 2:\r
+                pstSoftLeadOffDetInfo -> snniVal -= temp;\r
+                break;\r
+            case 3:\r
+                pstSoftLeadOffDetInfo -> snnqVal -= temp;\r
+                break;\r
+            default:\r
+                break;\r
+            }\r
+            if (pstSoftLeadOffDetInfo -> sniqCounter == (IQ_NUM - 1))\r
+            {\r
+                for (j = AMP_NUM-1; j >0; j--)\r
+                {\r
+                    pstSoftLeadOffDetInfo -> snniqAmp[j] = pstSoftLeadOffDetInfo -> snniqAmp[j - 1];\r
+                }\r
+                pstSoftLeadOffDetInfo -> snniVal = pstSoftLeadOffDetInfo -> snniVal >> 31;\r
+                pstSoftLeadOffDetInfo -> snnqVal = pstSoftLeadOffDetInfo -> snnqVal >> 31;\r
+                pstSoftLeadOffDetInfo -> snniqAmp[0] = pstSoftLeadOffDetInfo -> snniVal*(int)pstSoftLeadOffDetInfo -> snniVal + pstSoftLeadOffDetInfo -> snnqVal*(int)pstSoftLeadOffDetInfo -> snnqVal;\r
+                pstSoftLeadOffDetInfo -> snniVal = 0;\r
+                pstSoftLeadOffDetInfo -> snnqVal = 0;\r
+    \r
+                if (flagFastRecovery == 0)\r
+                {\r
+                    if (pstSoftLeadOffDetInfo -> snniqAmp[0] > g_lLeadOffDetIqAmpThrRaw && pstSoftLeadOffDetInfo -> snniqAmp[1] > g_lLeadOffDetIqAmpThrRaw)\r
+                        uchRet |= 0x02;\r
+\r
+                    if ((pstSoftLeadOffDetInfo -> snniqAmp[0] - pstSoftLeadOffDetInfo -> snniqAmp[2]) > g_lLeadOffDetIqAmpDiffThrRaw && (pstSoftLeadOffDetInfo -> snniqAmp[1] - pstSoftLeadOffDetInfo -> snniqAmp[2]) > g_lLeadOffDetIqAmpDiffThrRaw)\r
+                    {\r
+                        if(pstSoftLeadOffDetInfo ->snCounter > 2 * IQ_NUM)\r
+                        {\r
+                            uchRet |= 0x04;\r
+                        }\r
+                    }\r
+                }\r
+                else\r
+                {\r
+                    if (pstSoftLeadOffDetInfo -> snniqAmp[0] > g_lLeadOffDetIqAmpFrThrRaw && pstSoftLeadOffDetInfo -> snniqAmp[1] > g_lLeadOffDetIqAmpFrThrRaw)\r
+                        uchRet |= 0x08;\r
+                }\r
+            }\r
+            pstSoftLeadOffDetInfo -> sniqCounter++;\r
+            pstSoftLeadOffDetInfo -> sniqCounter = pstSoftLeadOffDetInfo -> sniqCounter%(IQ_NUM);\r
+        } // end of if (GH3X2X_CHANNEL_MAP_GET(puchFifoBuffer[usByteIndexTmp]) == g_uchEcgLeadChannelMap)\r
+    } // end of for (usByteIndexTmp = 0; usByteIndexTmp < usFifoBufferLen; usByteIndexTmp += GH3X2X_FIFO_RAWDATA_SIZE)\r
+\r
+    return uchRet;\r
+}\r
+\r
+#endif//end #elif((defined(GH3X2X_LEAD_OFF_VERSION)) && (GH3X2X_LEAD_OFF_VERSION == GH3X2X_LEAD_OFF_VERSION_FIX_POINT))\r
+\r
+\r
+GU8 GH3X2X_GetSoftLeadDetMode(void)\r
+{\r
+    return g_stEcgLeadCfg.uchEcgLeadCtrlFlag1.uchSoftLeadDetMode;\r
+}\r
+\r
+/**\r
+ * @fn     void GH3X2X_SoftLeadOffEventProManalMode(void)\r
+ *\r
+ * @brief  soft lead off evt process @ manal mode\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_SoftLeadOffEventProManalMode(void)\r
+{\r
+    ECG_LEAD_DET_EN_CONFIG(0);  \r
+    ECG_LEAD_DET_EN_CONFIG(1);\r
+    GH3X2X_CascadeEcgSlaverLeadDectDisEx();\r
+}\r
+\r
+void GH3X2X_ConfigLeadOffThr(GU32 uIQAmpThr, GU32 uIQAmpDiffThr,GU32 uValThr)\r
+{\r
+    g_nLeadOffDetIqAmpThr = uIQAmpThr;\r
+    g_lLeadOffDetIqAmp = ((long long)g_nLeadOffDetIqAmpThr * 20 * ADC_OFFSET / ADCREF/1000*IQ_NUM*1000/winAmpCoef);\r
+    g_lLeadOffDetIqAmpThrRaw = (g_lLeadOffDetIqAmp*g_lLeadOffDetIqAmp);\r
+    g_lLeadOffDetIqAmpFrThrRaw = (g_lLeadOffDetIqAmp*g_lLeadOffDetIqAmp / 20 / 20); \r
+\r
+    g_nLeadOffDetIqAmpDiffThr = uIQAmpDiffThr;\r
+    g_lLeadOffDetIqAmpDiff = ((long long)g_nLeadOffDetIqAmpDiffThr * 20 * ADC_OFFSET / ADCREF/1000*IQ_NUM*1000/winAmpCoef);\r
+    g_lLeadOffDetIqAmpDiffThrRaw = (g_lLeadOffDetIqAmpDiff*g_lLeadOffDetIqAmpDiff);\r
+    g_lLeadOffDetIqAmpDiffFrThrRaw = (g_lLeadOffDetIqAmpDiff*g_lLeadOffDetIqAmpDiff / 20 / 20); \r
+\r
+    g_nLeadOffDetValThr = uValThr;\r
+    g_LeadOffDetValThrRaw = (g_nLeadOffDetValThr * (20 * ADC_OFFSET / ADCREF)); \r
+}\r
+\r
+void GH3x2xSetEcgOutputFs(GU16 usEcgOutputFs)\r
+{\r
+    g_usEcgOutputFs = usEcgOutputFs;\r
+}\r
+\r
+/**\r
+ * @fn     void GH3X2X_SoftLeadOffEventPro(void)\r
+ *\r
+ * @brief  soft lead off evt process\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_SoftLeadOffEventPro(void)\r
+{\r
+    if(1 == g_stEcgLeadCfg.uchEcgLeadCtrlFlag2.uchDisItypeWhenEcgSample)\r
+    {\r
+                \r
+    }\r
+    else if (GET_LEAD_ON_AUTO_SWITCH_VAL())\r
+    {\r
+        GH3X2X_SlotEnableConfig(g_pstGh3x2xFrameInfo[GH3X2X_FUNC_OFFSET_ECG]->pstFunctionInfo->uchSlotBit, GH3X2X_SET_SLOT_DISABLE); // disable ecg or pwtt slot\r
+        ECG_LEAD_DET_EN_CONFIG(0); // disable lead detect\r
+        ECG_LEAD_DET_EN_CONFIG(1);// enable lead detect\r
+        GH3X2X_SlotEnableConfig(g_pstGh3x2xFrameInfo[GH3X2X_FUNC_OFFSET_ECG]->pstFunctionInfo->uchSlotBit, GH3X2X_SET_SLOT_ENABLE); // enable ecg or pwtt slot\r
+        GH3X2X_CascadeEcgSlaverLeadDectDisEx();\r
+    }\r
+}\r
+\r
+/**\r
+ * @fn     GU16 GH3X2X_SoftLeadOffDetPro(GU16 usCurrentIrqStatus, GU8 *puchFifoBuffer, GU16* pusFifoBufferLen)\r
+ *\r
+ * @brief  soft lead detect process\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   usCurrentIrqStatus     current irq status\r
+ * @param[in]   puchFifoBuffer         pointer to read fifo data buffer\r
+ * @param[in]   usFifoBufferLen        read fifo buffer len\r
+ * @param[out]  None\r
+ *\r
+ * @return  irq status ouput after handle\r
+ */\r
+GU16 GH3X2X_SoftLeadOffDetPro(GU16 usCurrentIrqStatus, GU8 *puchFifoBuffer, GU16* pusFifoBufferLen)\r
+{\r
+    if ((SOFT_LEAD_OFF_DET_MODE_DISABLE == g_stEcgLeadCfg.uchEcgLeadCtrlFlag1.uchSoftLeadDetMode) || (0 == g_uchEcgOrPwttFunctionEn))\r
+    {\r
+        //return usCurrentIrqStatus;\r
+    }\r
+    else\r
+    {\r
+        if (0 != (usCurrentIrqStatus & GH3X2X_IRQ_MSK_LEAD_ON_DET_BIT))  //lead on event\r
+        {\r
+            #if GH3X2X_LEAD_OFF_SUPPORT_ECG\r
+            if(g_usEcgOutputFs == 800 || g_usEcgOutputFs == 320 || g_usEcgOutputFs == 256)\r
+            {\r
+                GH3X2X_LeadOffDetectInit();\r
+            }\r
+            #endif\r
+        }\r
+\r
+        if (g_uchRtypeModeEn)\r
+        {\r
+            return usCurrentIrqStatus;\r
+        }\r
+\r
+        if (SOFT_LEAD_OFF_DET_MODE_SW_AND_HW == g_stEcgLeadCfg.uchEcgLeadCtrlFlag1.uchSoftLeadDetMode)\r
+        {\r
+        }\r
+        else\r
+        {\r
+            if (0 != (usCurrentIrqStatus & GH3X2X_IRQ_MSK_LEAD_OFF_DET_BIT))  //lead off event\r
+            {\r
+                if (SOFT_LEAD_OFF_DET_MODE_SW_ONLY == g_stEcgLeadCfg.uchEcgLeadCtrlFlag1.uchSoftLeadDetMode)  // SW only\r
+                {\r
+                    GH3X2X_VAL_CLEAR_BIT(usCurrentIrqStatus, (GU16)GH3X2X_IRQ_MSK_LEAD_OFF_DET_BIT); // don't need lead off evt\r
+                }\r
+            }\r
+            if ((*pusFifoBufferLen) && (LEAD_STATE_LEAD_ON == g_uchLeadStateInSoftLeadModule))\r
+            {\r
+                GU8 uchDetResult = 0;\r
+                if(g_usEcgOutputFs == 800 || g_usEcgOutputFs == 320 || g_usEcgOutputFs == 256)\r
+                {\r
+                    uchDetResult = GH3X2X_LeadOffDetect(puchFifoBuffer, pusFifoBufferLen);\r
+                }\r
+                if (uchDetResult)\r
+                {\r
+                    GH3X2X_DEBUG_LOG_PARAM("soft lead off, detect result = %d !\r\n", uchDetResult);\r
+                    GH3X2X_VAL_SET_BIT(usCurrentIrqStatus, GH3X2X_IRQ_MSK_LEAD_OFF_DET_BIT);\r
+                    GH3X2X_SoftLeadOffEventPro();\r
+                }\r
+            }\r
+        }\r
+\r
+        if(1 == g_stEcgLeadCfg.uchEcgLeadCtrlFlag2.uchWearOffLogic)  // wear off logic is ecg only\r
+        {\r
+            if((1 == g_uchLastEcgSampleFlag)&&(1 == g_stEcgLeadCfg.uchEcgLeadCtrlFlag2.uchDisItypeWhenEcgSample))  //is ecg samping  and itype is disable\r
+            {        \r
+                usCurrentIrqStatus &= (~(GH3X2X_IRQ_MSK_WEAR_OFF_BIT));   //mask wear off event\r
+            }\r
+        }\r
+    }\r
+\r
+    return usCurrentIrqStatus;\r
+}\r
+/**\r
+ * @fn     STSoftLeadResult GH3X2X_LeadHandle(GU16 usIrqStatus, GU8 *puchReadFifoBuffer, GU16 usFifoBufferLen)\r
+ *\r
+ * @brief  ecg soft lead handle\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   usIrqStatus               irq status\r
+ * @param[in]   puchReadFifoBuffer         pointer to read fifo data buffer\r
+ * @param[in]   usFifoBufferLen           read fifo buffer len\r
+ * @param[out]  None\r
+ *\r
+ * @return  soft lead handle process, @ref STSoftLeadResult\r
+ */\r
+STSoftLeadResult GH3X2X_LeadHandle(GU16 usIrqStatus, GU8 *puchReadFifoBuffer, GU16* pusFifoBufferLen)\r
+{\r
+    STSoftLeadResult stLeadResult = {0, 0};\r
+\r
+    GH3X2X_DEBUG_LOG_PARAM("%s\r\n", __FUNCTION__);\r
+    if (0 != (usIrqStatus & GH3X2X_IRQ_MSK_LEAD_ON_DET_BIT))  //got lead on event\r
+    {\r
+        GH3X2X_DEBUG_LOG_PARAM("handle lead on \r\n");\r
+        GH3X2X_EcgSampleHookHandle(ECG_SAMPLE_EVENT_TYPE_LEAD, ECG_SAMPLE_EVENT_INFO_LEAD_ON);\r
+    }\r
+    if (0 != (usIrqStatus & GH3X2X_IRQ_MSK_LEAD_OFF_DET_BIT))  //got lead off event\r
+    {\r
+        GH3X2X_DEBUG_LOG_PARAM("handle lead off \r\n");\r
+        GH3X2X_EcgSampleHookHandle(ECG_SAMPLE_EVENT_TYPE_LEAD, ECG_SAMPLE_EVENT_INFO_LEAD_OFF);\r
+    }\r
+    if (0 != (usIrqStatus & GH3X2X_IRQ_MSK_LEAD_ON_DET_BIT))\r
+    {\r
+        g_uchLeadStateInSoftLeadModule = LEAD_STATE_LEAD_ON;\r
+    }\r
+    usIrqStatus = GH3X2X_SoftLeadOffDetPro(usIrqStatus, puchReadFifoBuffer, pusFifoBufferLen);\r
+    \r
+    if (0 != (usIrqStatus & GH3X2X_IRQ_MSK_LEAD_OFF_DET_BIT))\r
+    {\r
+        g_uchLeadStateInSoftLeadModule = LEAD_STATE_LEAD_OFF;\r
+        if(1 == g_stEcgLeadCfg.uchEcgLeadCtrlFlag2.uchAutoCtrlMode)\r
+        {\r
+            stLeadResult.uchNeedForceReadFifo = 1;\r
+        }\r
+    }\r
+    stLeadResult.usEvent = usIrqStatus;\r
+    return stLeadResult;\r
+}\r
+\r
+GU8 GH3X2X_LeadOffDetect(GU8* puchFifoBuffer, GU16* pusFifoBufferLen)\r
+{\r
+    GU8 uchRet = 0;\r
+    if(0 == g_pstGh3x2xFrameInfo[GH3X2X_FUNC_OFFSET_ECG] || GH3X2X_CheckRawdataBuf(puchFifoBuffer, *pusFifoBufferLen))\r
+    {\r
+        return uchRet;\r
+    }\r
+    uchRet |= GH3X2X_LeadOffDetectSingleChip(puchFifoBuffer, pusFifoBufferLen, 0);\r
+    if((g_pstGh3x2xFrameInfo[GH3X2X_FUNC_OFFSET_ECG]->pstFunctionInfo->uchChnlNum > 1)&&(g_uchGh3x2xEcgChnlNumLimit > 1))\r
+    {\r
+        uchRet |= GH3X2X_LeadOffDetectSingleChip(puchFifoBuffer, pusFifoBufferLen, 1);\r
+    }\r
+        return uchRet;\r
+}\r
+\r
+/**\r
+ * @fn     void GH3X2X_SlaverSoftLeadPramInit(void)\r
+ *\r
+ * @brief  slave soft lead off param init to default value\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_SlaverSoftLeadPramInit(void)\r
+{\r
+    g_uchEcgOrPwttFunctionEn = 0;\r
+    GH3X2X_Memset((GU8 *)(&g_stEcgLeadCfg), 0, sizeof(g_stEcgLeadCfg));\r
+    g_uchEcgSampleStatus = 0;\r
+    g_uchLastEcgSampleFlag = 0;\r
+    g_uchRtypeModeEn = 1;\r
+    g_uchIsItyp0nAPeriod = 0;\r
+}\r
+\r
+/**\r
+ * @fn     void GH3X2X_SlaverSoftLeadPramSet(GU16 usRegVal, GU8 uchRegPosi)\r
+ *\r
+ * @brief  slave soft lead off param set from virtual reg\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   usRegVal          reg value\r
+ * @param[in]   uchRegPosi        reg position\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_SlaverSoftLeadPramSet(GU16 usRegVal, GU8 uchRegPosi)\r
+{    \r
+\r
+    GU8 uchByteOffset;\r
+    GU8 uchByteVal;\r
+    GU8 uchByteCnt;\r
+    for(uchByteCnt = 0; uchByteCnt < 2; uchByteCnt ++)\r
+    {\r
+        uchByteVal = ((usRegVal >> (8*uchByteCnt))&0x00FF);\r
+        uchByteOffset = (uchRegPosi * 2) + uchByteCnt;\r
+        if(uchByteOffset < sizeof(g_stEcgLeadCfg))\r
+        {\r
+            GH3X2X_Memcpy(((GU8 *)(&g_stEcgLeadCfg)) + uchByteOffset, (GU8*)(&uchByteVal), 1);\r
+            if(uchByteOffset == (GU8)((GU8*)(&(g_stEcgLeadCfg.uchLeadOffBaseVolt))- (GU8*)(&(g_stEcgLeadCfg))))\r
+            {\r
+                g_nLeadoffPeakThrdRawData = (GS32)((GS64)g_stEcgLeadCfg.uchLeadOffPeakVolt * (((GS64)g_uchEcgGainMapArr[g_stEcgLeadCfg.uchEcgLeadCtrlFlag1.uchEcgGainGrade] \\r
+                                * GH3X2X_RAWDATA_REAL_OFFSET) \\r
+                                / (GS64)(((GU16)g_uchAdcRefMapArr[g_stEcgLeadCfg.uchEcgLeadCtrlFlag1.uchAdcRefGrade]) * (GU16)SOFT_LEAD_ADC_REF_AMP_NUM)));\r
+                g_nLeadoffDiffThrdRawData = (GS32)((GS64)g_stEcgLeadCfg.uchLeadOffDiffVolt * (((GS64)g_uchEcgGainMapArr[g_stEcgLeadCfg.uchEcgLeadCtrlFlag1.uchEcgGainGrade] \\r
+                                * GH3X2X_RAWDATA_REAL_OFFSET) \\r
+                                / (GS64)(((GU16)g_uchAdcRefMapArr[g_stEcgLeadCfg.uchEcgLeadCtrlFlag1.uchAdcRefGrade]) * (GU16)SOFT_LEAD_ADC_REF_AMP_NUM)));\r
+                g_nLeadoffBaseThrdRawData = (GS32)((GS64)g_stEcgLeadCfg.uchLeadOffBaseVolt * (((GS64)g_uchEcgGainMapArr[g_stEcgLeadCfg.uchEcgLeadCtrlFlag1.uchEcgGainGrade] \\r
+                                * GH3X2X_RAWDATA_REAL_OFFSET) \\r
+                                / (GS64)(((GU16)g_uchAdcRefMapArr[g_stEcgLeadCfg.uchEcgLeadCtrlFlag1.uchAdcRefGrade]) * (GU16)SOFT_LEAD_ADC_REF_AMP_NUM)));\r
+                \r
+            }\r
+            g_uchEcgOrPwttFunctionEn = 1;\r
+        }\r
+    \r
+    }\r
+}\r
+\r
+/**\r
+ * @fn     void GH3X2X_EcgSampleHookHandle(GU8 uchEventType, GU8 uchEventInfo)\r
+ *\r
+ * @brief  ecg sample hook handle\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   uchEventType         ecg sample event type, @ref ECG_SAMPLE_EVENT_TYPE_SAMPLE etc\r
+ * @param[in]   uchEventInfo         ecg sample event info, @ref ECG_SAMPLE_EVENT_INFO_SAMPLE_STOP etc\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_EcgSampleHookHandle(GU8 uchEventType, GU8 uchEventInfo)\r
+{\r
+    GU8 uchHandleCondition;\r
+\r
+    GH3X2X_DEBUG_LOG_PARAM("%s\r\n", __FUNCTION__);\r
+    if (0 == g_uchEcgOrPwttFunctionEn) // check flag\r
+    {\r
+        return;\r
+    }\r
+\r
+    if (ECG_SAMPLE_EVENT_TYPE_SAMPLE == uchEventType)  // if evt type equal sample config\r
+    {\r
+        if (ECG_SAMPLE_EVENT_INFO_SAMPLE_STOP == uchEventInfo)\r
+        {\r
+            GH3X2X_VAL_CLEAR_BIT(g_uchEcgSampleStatus, (GU8)ECG_SAMPLE_EVENT_TYPE_SAMPLE); // clear sample bit\r
+        }\r
+        else\r
+        {\r
+            GH3X2X_VAL_SET_BIT(g_uchEcgSampleStatus, ECG_SAMPLE_EVENT_TYPE_SAMPLE); // set sample bit\r
+        }\r
+    }\r
+    else if (ECG_SAMPLE_EVENT_TYPE_SLOT == uchEventType) // if evt type equal slot config\r
+    {\r
+        if ((uchEventInfo & g_pstGh3x2xFrameInfo[GH3X2X_FUNC_OFFSET_ECG]->pstFunctionInfo->uchSlotBit) != 0)  // if slot enable bit equal\r
+        {\r
+            GH3X2X_VAL_SET_BIT(g_uchEcgSampleStatus, ECG_SAMPLE_EVENT_TYPE_SLOT);\r
+        }\r
+        else\r
+        {\r
+            GH3X2X_VAL_CLEAR_BIT(g_uchEcgSampleStatus, (GU8)ECG_SAMPLE_EVENT_TYPE_SLOT);\r
+        }\r
+    }\r
+    else if (ECG_SAMPLE_EVENT_TYPE_LEAD == uchEventType)\r
+    {\r
+        if (ECG_SAMPLE_EVENT_INFO_LEAD_OFF == uchEventInfo)\r
+        {\r
+            GH3X2X_VAL_CLEAR_BIT(g_uchEcgSampleStatus, (GU8)ECG_SAMPLE_EVENT_TYPE_LEAD);\r
+        }\r
+        else\r
+        {\r
+            GH3X2X_VAL_SET_BIT(g_uchEcgSampleStatus, ECG_SAMPLE_EVENT_TYPE_LEAD);\r
+        }\r
+    }\r
+\r
+    if ((0 == g_stEcgLeadCfg.uchEcgLeadCtrlFlag2.uchAutoCtrlMode) || (2 == g_stEcgLeadCfg.uchEcgLeadCtrlFlag2.uchAutoCtrlMode))  //disable or software\r
+    {\r
+        uchHandleCondition = (ECG_SAMPLE_EVENT_TYPE_SAMPLE | ECG_SAMPLE_EVENT_TYPE_SLOT);\r
+    }\r
+    else\r
+    {\r
+        uchHandleCondition = (ECG_SAMPLE_EVENT_TYPE_SAMPLE | ECG_SAMPLE_EVENT_TYPE_SLOT | ECG_SAMPLE_EVENT_TYPE_LEAD);\r
+    }\r
+\r
+    if (uchHandleCondition == (uchHandleCondition & g_uchEcgSampleStatus)) //condition is match\r
+    {\r
+        if(0 == g_uchLastEcgSampleFlag)\r
+        {\r
+            if(1 == g_stEcgLeadCfg.uchEcgLeadCtrlFlag1.uchForceRecover)\r
+            {\r
+                ECG_FAST_RECV_EN_CONFIG(1);\r
+                GH3X2X_CascadeEcgSlaverFastRecTrigEx();\r
+                GH3X2X_DEBUG_LOG_PARAM("Fast recover !!! last event is %d\r\n", uchEventType);\r
+            }\r
+            if(1 == g_stEcgLeadCfg.uchEcgLeadCtrlFlag2.uchDisItypeWhenEcgSample)\r
+            {\r
+                g_uchIsItyp0nAPeriod = 1;\r
+                ECG_LEAD_DET_EN_CONFIG(0); // disable lead detect\r
+                GH3X2X_CascadeEcgSlaverLeadDectDisEx();\r
+            }\r
+            g_uchRtypeModeEn = 0;\r
+            g_uchLastEcgSampleFlag = 1;\r
+        }\r
+    }\r
+    else\r
+    {\r
+        if(1 == g_uchLastEcgSampleFlag)  //ecg sample will be from sampling to stop sample\r
+        {\r
+            if(1 == g_stEcgLeadCfg.uchEcgLeadCtrlFlag2.uchDisItypeWhenEcgSample)\r
+            {\r
+                if((g_uchEcgSampleStatus&ECG_SAMPLE_EVENT_TYPE_SAMPLE))// if sample is opening\r
+                {\r
+                    ECG_LEAD_DET_EN_CONFIG(1);  // enable lead detect\r
+                    GH3X2X_CascadeEcgSlaverLeadDectDisEx();\r
+                }\r
+                if((1 == g_stEcgLeadCfg.uchEcgLeadCtrlFlag2.uchWearOffLogic))\r
+                {\r
+                    GH3X2X_SetSoftEvent(GH3X2X_SOFT_EVENT_WEAR_OFF);\r
+                }    \r
+            }\r
+            else\r
+            {\r
+                if(GET_ECG_LEAD_DET_EN_VAL())   //if detcet module is enable , reset detecet module\r
+                {\r
+                    ECG_LEAD_DET_EN_CONFIG(0);\r
+                    ECG_LEAD_DET_EN_CONFIG(1);\r
+                    GH3X2X_CascadeEcgSlaverLeadDectDisEx();\r
+                }\r
+            }\r
+            g_uchIsItyp0nAPeriod = 0;\r
+        }\r
+        g_uchLastEcgSampleFlag = 0;\r
+        g_uchRtypeModeEn = 1;\r
+    }\r
+}\r
+\r
+/**\r
+ * @fn     GH3X2X_LeadDetEnControl(GU8 uchEventInfo)\r
+ *\r
+ * @brief  lead detect enable control\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   uchEventInfo         control event, only ecg start/stop evt \r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_LeadDetEnControl(GU8 uchEventInfo)\r
+{\r
+    if(1 == g_stEcgLeadCfg.uchEcgLeadCtrlFlag1.uchNeedHostEnableLeadDet)\r
+    {\r
+        if (ECG_SAMPLE_EVENT_INFO_SAMPLE_STOP == uchEventInfo)\r
+        {\r
+            ECG_LEAD_DET_EN_CONFIG(0);// disable lead detect\r
+        }\r
+        else\r
+        {\r
+            ECG_LEAD_DET_EN_CONFIG(1);// enable lead detect\r
+        }\r
+        GH3X2X_CascadeEcgSlaverLeadDectDisEx();\r
+    }\r
+}\r
+\r
+\r
+void GH3X2X_LeadDetEnInHardAdt(GU8 uchEn)\r
+{\r
+    if(g_stAdtModuleCfg.stAdtCfgByte0.uchElectrodeAdtEn)\r
+    {\r
+        if(1 == uchEn)\r
+        {\r
+            if(0 == g_uchIsItyp0nAPeriod)\r
+            {\r
+                ECG_LEAD_DET_EN_CONFIG(1);// enable lead detect\r
+            }\r
+        }\r
+        else\r
+        {\r
+            ECG_LEAD_DET_EN_CONFIG(0);// disable lead detect\r
+        }\r
+    }\r
+    GH3X2X_CascadeEcgSlaverLeadDectDisEx();\r
+}\r
+\r
+/**\r
+ * @fn     void GH3X2X_EcgSampleHookHandleAfterSlotCtrl(GU16 usSlotEnableConfig, GU8 uchSlotEnable)\r
+ *\r
+ * @brief  ecg sample hook handle after ecg slot ctrl\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   usSlotEnableConfig         slot enable index , @ref GH3X2X_SLOT_INDEX_0 ... GH3X2X_SLOT_INDEX_ALL\r
+ * @param[in]   uchSlotEnable              enable flag, #0 slot disable, #others slot enable\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_EcgSampleHookHandleAfterSlotCtrl(GU16 usSlotEnableConfig, GU8 uchSlotEnable)\r
+{\r
+    GU8 uchSlotEnableBitsTmp = (GU8)usSlotEnableConfig;\r
+    if (uchSlotEnable == 0)\r
+    {\r
+        uchSlotEnableBitsTmp = ~uchSlotEnableBitsTmp; // if disable\r
+    }\r
+    GH3X2X_EcgSampleHookHandle(ECG_SAMPLE_EVENT_TYPE_SLOT, uchSlotEnableBitsTmp);\r
+}\r
+\r
+/**\r
+ * @fn       GS8 GH3X2X_CalibrateECGGain(GU8 *puchReadFifoBuffer)\r
+ *\r
+ * @brief  Calibrate ECG Gain\r
+ *\r
+ * @attention    None\r
+ *\r
+ * @param[in]        puchReadFifoBuffer        pointer read data buffer\r
+ * @param[in]        usFifoBufferLen         fifo byte length \r
+ * @return    error code\r
+ * @retval    #GH3X2X_RET_OK                        return algorithm run successfully, but output hasn't refreshed\r
+ * @retval    #GH3X2X_RET_GENERIC_ERROR            return algorithm generic error\r
+ */\r
+GS8 GH3X2X_CalibrateECGGain(GU8 *puchReadFifoBuffer, GU16 usFifoBufferLen)\r
+{\r
+    GU16 usByteIndexTmp = 0;\r
+    GS8  chGainCode = 0;\r
+    GU32 unRawdataVal = 0;\r
+    GS64 nRawdatalVal = 0;\r
+    GS64 nRawdataRealVal = 0;\r
+    GS8 chRet = GH3X2X_RET_OK;\r
+    chGainCode = (GS8)GH3X2X_GET_LOW_BYTE_FROM_WORD(GH3X2X_ReadReg(GH3X2X_EFUSE_CTRL_EFUSE0_AUTOLOAD_2_ADDR));\r
+    if (GH3X2X_CHECK_BIT_SET(g_unFuncStartedBitmap, GH3X2X_FUNCTION_ECG))\r
+    {\r
+        if(GH3X2X_CheckRawdataBuf(puchReadFifoBuffer, usFifoBufferLen))\r
+        {\r
+            return chRet;\r
+        }\r
+    \r
+        for(usByteIndexTmp = 0; usByteIndexTmp < usFifoBufferLen; usByteIndexTmp += GH3X2X_FIFO_RAWDATA_SIZE)\r
+        {\r
+            if(GH3X2X_CHANNEL_MAP_GET(puchReadFifoBuffer[usByteIndexTmp]) == (g_pstGh3x2xFrameInfo[GH3X2X_FUNC_OFFSET_ECG]->pchChnlMap[0] & GH3X2X_SLOT_ADC_NUM_BITS))\r
+            {\r
+                unRawdataVal = GH3X2X_MAKEUP_DWORD(puchReadFifoBuffer[usByteIndexTmp], puchReadFifoBuffer[usByteIndexTmp + 1],\r
+                                              puchReadFifoBuffer[usByteIndexTmp + 2], puchReadFifoBuffer[usByteIndexTmp + 3]);\r
+\r
+                nRawdatalVal = GH3X2X_RAWDATA_CLEAR_ALL_FLAG(unRawdataVal);\r
+\r
+                nRawdataRealVal = ((GS64)nRawdatalVal - GH3X2X_RAWDATA_REAL_OFFSET) * 1024/((GS64)chGainCode + 1024) + GH3X2X_RAWDATA_REAL_OFFSET;\r
+\r
+                puchReadFifoBuffer[usByteIndexTmp + 1] = GH3X2X_GET_BYTE2_FROM_DWORD(nRawdataRealVal);\r
+                puchReadFifoBuffer[usByteIndexTmp + 2] = GH3X2X_GET_BYTE1_FROM_DWORD(nRawdataRealVal);\r
+                puchReadFifoBuffer[usByteIndexTmp + 3] = GH3X2X_GET_BYTE0_FROM_DWORD(nRawdataRealVal);\r
+            }\r
+        }\r
+        GH3X2X_CalRawdataBuf(puchReadFifoBuffer, usFifoBufferLen);\r
+    }\r
+    else\r
+    {\r
+         chRet = GH3X2X_RET_GENERIC_ERROR;\r
+         GH3X2X_DEBUG_LOG_PARAM("ecg hasn't started error!\r\n");\r
+    }\r
+    return chRet;\r
+}\r
+\r
+\r
+\r
+void GH3X2X_DownSampleCal( GU8 *puchFifoBuffer, GU16 usByteIndexTmp, GU16 *usRawdataBufIdx, STGh3x2xRsInfo * pstRsInfo ,STGh3x2xDownSampleCalParamInfo * pstDownSampCalParamInfo)\r
+{\r
+    GU32 unfifoVal = 0;\r
+    GS32 usadcVal = 0;\r
+    GU8  chNo = 0;\r
+    GU8  uchflagFastRecovery = 0;\r
+    GU32 unFirCoefIndex = 0;\r
+    unfifoVal = GH3X2X_MAKEUP_DWORD(puchFifoBuffer[usByteIndexTmp], puchFifoBuffer[usByteIndexTmp + 1], puchFifoBuffer[usByteIndexTmp + 2], puchFifoBuffer[usByteIndexTmp + 3]);\r
+    chNo = (unfifoVal >> 27); \r
+    usadcVal = (GS32)((unfifoVal & 0x00FFFFFF)) - ADC_OFFSET; \r
+\r
+    if(g_uchDownSampleModule == DOWNSAMPLE_ECG)\r
+    {\r
+        uchflagFastRecovery = (unfifoVal >> 26) & 0x01;\r
+        if (pstRsInfo ->uchFlagFrPrev != uchflagFastRecovery)\r
+        {\r
+            GH3X2X_ECGResampleConfig(g_pstGh3x2xFrameInfo[GH3X2X_FUNC_OFFSET_ECG]->pstFunctionInfo->usSampleRate);\r
+        }\r
+        pstRsInfo ->uchFlagFrPrev = uchflagFastRecovery;\r
+    }\r
+\r
+    #if __SUPPORT_ECG_PPG_DOWNSAMP__\r
+    else if(g_uchDownSampleModule == DOWNSAMPLE_PPG)\r
+    {\r
+        uchflagFastRecovery = (unfifoVal >> 26) & 0x01;\r
+        if (pstRsInfo ->uchFlagFrPrev != 1)\r
+        {\r
+            if(g_pstGh3x2xFrameInfo[GH3X2X_FUNC_OFFSET_HR]->pstFunctionInfo->usSampleRate)\r
+            {\r
+                GH3X2X_PPGResampleConfig(g_pstGh3x2xFrameInfo[GH3X2X_FUNC_OFFSET_HR]->pstFunctionInfo->usSampleRate);\r
+            }\r
+            else if(g_pstGh3x2xFrameInfo[GH3X2X_FUNC_OFFSET_SPO2]->pstFunctionInfo->usSampleRate)\r
+            {\r
+                GH3X2X_PPGResampleConfig(g_pstGh3x2xFrameInfo[GH3X2X_FUNC_OFFSET_SPO2]->pstFunctionInfo->usSampleRate);\r
+            }\r
+        }\r
+        pstRsInfo ->uchFlagFrPrev = 1;\r
+    }\r
+    #endif\r
+\r
+    // ECG downsample\r
+    #if RESAMPLE_320HZ_TO_250HZ || RESAMPLE_256HZ_TO_250HZ\r
+    if((DOWNSAMPLE_320HZ_TO_250HZ == pstECGDownSampCalParamInfo->uchDownSampleType) || (DOWNSAMPLE_256HZ_TO_250HZ == pstECGDownSampCalParamInfo->uchDownSampleType))\r
+    {\r
+        GS32 snLinerAdcVal;\r
+        if(pstDownSampCalParamInfo->uchRsEnable)\r
+        {\r
+            GS32 snRsXbufIndex;\r
+            GS64 snFirValueSum;\r
+                       GS32 snFirValue;\r
+\r
+            //滤波\r
+            if (pstRsInfo ->snRsFirState > 0)\r
+            {\r
+                pstRsInfo ->snBufHead = pstRsInfo ->snBufHead - 1;\r
+                pstRsInfo ->snBufHead = pstRsInfo ->snBufHead < 0 ? (pstDownSampCalParamInfo->uchRsBufSize - 1) : pstRsInfo ->snBufHead;\r
+                pstRsInfo ->snRsXbuf[pstRsInfo ->snBufHead] = usadcVal;\r
+            }\r
+            else\r
+            {\r
+                for (GU8 i = 0; i < pstDownSampCalParamInfo->uchRsFirOrder / pstDownSampCalParamInfo->uchRsI + 1; i++)\r
+                        pstRsInfo ->snRsXbuf[i] = usadcVal;\r
+                pstRsInfo ->snBufHead = pstDownSampCalParamInfo->uchRsBufSize - 1;\r
+            }\r
+                              \r
+            snRsXbufIndex = pstRsInfo ->snBufHead;\r
+            snFirValueSum = 0;\r
+                       snFirValue = 0;\r
+            for (unFirCoefIndex = 1; unFirCoefIndex < pstDownSampCalParamInfo->uchRsFirCoefNum; unFirCoefIndex = unFirCoefIndex + 1) //\r
+            {\r
+                snFirValueSum += ((GS64)pstRsInfo ->snRsXbuf[snRsXbufIndex] * pstDownSampCalParamInfo->rsFirCoef[unFirCoefIndex]);\r
+                snRsXbufIndex = (snRsXbufIndex + 1) % pstDownSampCalParamInfo->uchRsBufSize;\r
+            }\r
+            for (; unFirCoefIndex <(pstDownSampCalParamInfo->uchRsFirOrder+1); unFirCoefIndex = unFirCoefIndex + 1) //\r
+            {\r
+                snFirValueSum += ((GS64)pstRsInfo ->snRsXbuf[snRsXbufIndex] * pstDownSampCalParamInfo->rsFirCoef[pstDownSampCalParamInfo->uchRsFirOrder - unFirCoefIndex]);\r
+                snRsXbufIndex = (snRsXbufIndex + 1) % pstDownSampCalParamInfo->uchRsBufSize;\r
+            }\r
+\r
+            snFirValue = (GS32)(snFirValueSum >> SHIFTBITS);\r
+            snFirValue = snFirValue + ADC_OFFSET; //\r
+            if (snFirValue < 0)\r
+                snFirValue = 0;\r
+            else if (snFirValue>=(ADC_OFFSET * 2))\r
+                snFirValue = (ADC_OFFSET * 2-1);\r
+\r
+            // 线性插值降采样\r
+            if(pstRsInfo->uchLinearInterState >0)\r
+            {\r
+                #if RESAMPLE_320HZ_TO_250HZ\r
+                if(DOWNSAMPLE_320HZ_TO_250HZ == pstECGDownSampCalParamInfo->uchDownSampleType)\r
+                {\r
+                    if(pstRsInfo->fDownStep <=100)\r
+                    {\r
+                        snLinerAdcVal = ((GU32)snFirValue*pstRsInfo->fDownStep + (100-pstRsInfo->fDownStep)*pstRsInfo->nRsLastRaw)/100;\r
+                        pstRsInfo->nRsLastRaw = (GU32)snFirValue;\r
+                        pstRsInfo->fDownStep = pstRsInfo->fDownStep + pstDownSampCalParamInfo->ufStep - 100;\r
+                        pstRsInfo->uchLinearDataUpdate = 1;\r
+                    }\r
+                    else\r
+                    {\r
+                        pstRsInfo->nRsLastRaw = (GU32)snFirValue;\r
+                        pstRsInfo->fDownStep = pstRsInfo->fDownStep - 100;\r
+                        pstRsInfo->uchLinearDataUpdate = 0;\r
+                    }\r
+                }\r
+                #endif\r
+\r
+                #if RESAMPLE_256HZ_TO_250HZ\r
+                if(DOWNSAMPLE_256HZ_TO_250HZ == pstECGDownSampCalParamInfo->uchDownSampleType)\r
+                {\r
+                    if(pstRsInfo->fDownStep <=1000)\r
+                    {\r
+                        snLinerAdcVal = (GU32)(((GS64)(snFirValue)*(GS64)(pstRsInfo->fDownStep) + (GS64)((1000-pstRsInfo->fDownStep)*(GS64)(pstRsInfo->nRsLastRaw)))/1000);\r
+                        pstRsInfo->nRsLastRaw = (GU32)snFirValue;\r
+                        pstRsInfo->fDownStep = pstRsInfo->fDownStep + pstDownSampCalParamInfo->ufStep - 1000;\r
+                        pstRsInfo->uchLinearDataUpdate = 1;\r
+                    }\r
+                    else\r
+                    {\r
+                        pstRsInfo->nRsLastRaw = (GU32)snFirValue;\r
+                        pstRsInfo->fDownStep = pstRsInfo->fDownStep - 1000;\r
+                        pstRsInfo->uchLinearDataUpdate = 0;\r
+                    }\r
+                }\r
+                #endif\r
+            }\r
+            else\r
+            {\r
+                snLinerAdcVal = (GU32)snFirValue;\r
+                pstRsInfo->nRsLastRaw = (GU32)snFirValue;\r
+                pstRsInfo->fDownStep = pstRsInfo->fDownStep + pstDownSampCalParamInfo->ufStep;\r
+                pstRsInfo->uchLinearInterState =1;\r
+                pstRsInfo->uchLinearDataUpdate = 1;\r
+            }\r
+\r
+            if(pstRsInfo->uchLinearDataUpdate == 1)\r
+            {\r
+                unfifoVal = (((GU8)chNo)<<27) + (((GU8)uchflagFastRecovery)<<26) + ((GU32)snLinerAdcVal/5);\r
+                puchFifoBuffer[*usRawdataBufIdx]     = GH3X2X_GET_BYTE3_FROM_DWORD(unfifoVal);\r
+                puchFifoBuffer[*usRawdataBufIdx + 1] = GH3X2X_GET_BYTE2_FROM_DWORD(unfifoVal);\r
+                puchFifoBuffer[*usRawdataBufIdx + 2] = GH3X2X_GET_BYTE1_FROM_DWORD(unfifoVal);\r
+                puchFifoBuffer[*usRawdataBufIdx + 3] = GH3X2X_GET_BYTE0_FROM_DWORD(unfifoVal);\r
+\r
+                *usRawdataBufIdx += GH3X2X_FIFO_RAWDATA_SIZE;\r
+            }\r
+        }\r
+    }\r
+    #endif\r
+\r
+    #if  RESAMPLE_800HZ_TO_500HZ ||RESAMPLE_800HZ_TO_250HZ || (RESAMPLE_400HZ_TO_250HZ & (__SUPPORT_ECG_PPG_DOWNSAMP__))\r
+    if((DOWNSAMPLE_800HZ_TO_500HZ == pstECGDownSampCalParamInfo->uchDownSampleType)||(DOWNSAMPLE_800HZ_TO_250HZ == pstECGDownSampCalParamInfo->uchDownSampleType)||(DOWNSAMPLE_400HZ_TO_250HZ == pstECGDownSampCalParamInfo->uchDownSampleType))\r
+    {\r
+        if(pstDownSampCalParamInfo->uchRsEnable)\r
+        {\r
+            GS32 snRsXbufIndex;\r
+            GS64 snFirValueSum;\r
+                       GS32 snFirValue;\r
+            GS32 sndelta;\r
+            if (pstRsInfo ->snRsFirState > 0)\r
+            {\r
+                pstRsInfo ->snBufHead = pstRsInfo ->snBufHead - 1;\r
+                pstRsInfo ->snBufHead = pstRsInfo ->snBufHead < 0 ? (pstDownSampCalParamInfo->uchRsBufSize - 1) : pstRsInfo ->snBufHead;\r
+                pstRsInfo ->snRsXbuf[pstRsInfo ->snBufHead] = usadcVal;\r
+                pstRsInfo ->nRsIcounter += pstDownSampCalParamInfo->uchRsI;\r
+            }\r
+            else\r
+            {\r
+                for (GU8 i = 0; i < pstDownSampCalParamInfo->uchRsFirOrder / pstDownSampCalParamInfo->uchRsI + 1; i++)\r
+                        pstRsInfo ->snRsXbuf[i] = usadcVal;\r
+                pstRsInfo ->nRsIcounter = 0;\r
+                pstRsInfo ->snRsFirState = 1;\r
+                pstRsInfo ->snBufHead = pstDownSampCalParamInfo->uchRsBufSize - 1;\r
+            }\r
+\r
+            if (pstRsInfo ->nRrsDcounter >= pstRsInfo ->nRsIcounter && pstRsInfo ->nRrsDcounter < (pstRsInfo ->nRsIcounter + pstDownSampCalParamInfo->uchRsI))\r
+            {\r
+                sndelta = pstRsInfo ->nRrsDcounter - pstRsInfo ->nRsIcounter;\r
+                snRsXbufIndex = pstRsInfo ->snBufHead;\r
+                snFirValue = 0;\r
+                               snFirValueSum = 0;\r
+                for (unFirCoefIndex = sndelta; unFirCoefIndex < pstDownSampCalParamInfo->uchRsFirCoefNum; unFirCoefIndex = unFirCoefIndex + pstDownSampCalParamInfo->uchRsI)\r
+                {\r
+                    snFirValueSum += ((GS64)pstRsInfo ->snRsXbuf[snRsXbufIndex] * pstDownSampCalParamInfo->rsFirCoef[unFirCoefIndex]);\r
+                    snRsXbufIndex = (snRsXbufIndex + 1) % pstDownSampCalParamInfo->uchRsBufSize;\r
+                }\r
+                for (; unFirCoefIndex <(pstDownSampCalParamInfo->uchRsFirOrder+1); unFirCoefIndex = unFirCoefIndex + pstDownSampCalParamInfo->uchRsI)\r
+                {\r
+                    snFirValueSum += ((GS64)pstRsInfo ->snRsXbuf[snRsXbufIndex] * pstDownSampCalParamInfo->rsFirCoef[pstDownSampCalParamInfo->uchRsFirOrder - unFirCoefIndex]);\r
+                    snRsXbufIndex = (snRsXbufIndex + 1) % pstDownSampCalParamInfo->uchRsBufSize;\r
+                }\r
+                pstRsInfo ->nRrsDcounter += pstDownSampCalParamInfo->uchRsD;\r
+\r
+                snFirValue = (GS32)(snFirValueSum >> SHIFTBITS);\r
+                snFirValue = snFirValue + ADC_OFFSET;\r
+                if (snFirValue < 0)\r
+                        snFirValue = 0;\r
+                else if (snFirValue>=(ADC_OFFSET * 2))\r
+                        snFirValue = (ADC_OFFSET * 2-1); \r
+                unfifoVal = (((GU8)chNo)<<27) + (((GU8)uchflagFastRecovery)<<26) + ((GU32)snFirValue);\r
+                puchFifoBuffer[*usRawdataBufIdx]     = GH3X2X_GET_BYTE3_FROM_DWORD(unfifoVal);\r
+                puchFifoBuffer[*usRawdataBufIdx + 1] = GH3X2X_GET_BYTE2_FROM_DWORD(unfifoVal);\r
+                puchFifoBuffer[*usRawdataBufIdx + 2] = GH3X2X_GET_BYTE1_FROM_DWORD(unfifoVal);\r
+                puchFifoBuffer[*usRawdataBufIdx + 3] = GH3X2X_GET_BYTE0_FROM_DWORD(unfifoVal);\r
+                *usRawdataBufIdx += GH3X2X_FIFO_RAWDATA_SIZE;\r
+            }\r
+        }\r
+    }\r
+#endif\r
+}\r
+#endif\r
+\r
+void GH3X2X_EcgPPGRsHandleSingleChip(GU8 *puchFifoBuffer, GU16 *pusFifoBufferLen, GU8 uchChipIndex)\r
+{\r
+    GU16 usByteIndexTmp = 0;\r
+    GU16 usRawdataBufIdx = 0;\r
+    GU8  usCheckDataType = 0; // 1:ECG 2:PPG 0:other\r
+\r
+    for (usByteIndexTmp = 0; usByteIndexTmp < *pusFifoBufferLen; usByteIndexTmp += GH3X2X_FIFO_RAWDATA_SIZE)\r
+    { \r
+        if(GH3X2X_CHANNEL_MAP_GET(puchFifoBuffer[usByteIndexTmp]) == (g_pstGh3x2xFrameInfo[GH3X2X_FUNC_OFFSET_ECG]->pchChnlMap[uchChipIndex] & GH3X2X_SLOT_ADC_NUM_BITS))\r
+        {\r
+            STGh3x2xRsInfo * pstRsInfo_ECG = g_pstGh3x2xEcgRsInfo + uchChipIndex;\r
+            g_uchDownSampleModule = DOWNSAMPLE_ECG;\r
+            GH3X2X_DownSampleCal( puchFifoBuffer, usByteIndexTmp, &usRawdataBufIdx, pstRsInfo_ECG,pstECGDownSampCalParamInfo);\r
+            usCheckDataType =1;\r
+        }\r
+\r
+        #if __SUPPORT_ECG_PPG_DOWNSAMP__\r
+        if(g_uchPPGDownSampleChnlNumLimit && pstPPGDownSampCalParamInfo->uchRsEnable==1)\r
+        {\r
+            for(GU8 uchPPGSlotNumTmp = 0; uchPPGSlotNumTmp < g_uchPPGDownSampleChnlNumLimit; uchPPGSlotNumTmp++)\r
+            {\r
+                if(GH3X2X_CHANNEL_MAP_GET(puchFifoBuffer[usByteIndexTmp]) == (g_pstGh3x2xFrameInfo[GH3X2X_FUNC_OFFSET_HR]->pchChnlMap[uchPPGSlotNumTmp] & GH3X2X_SLOT_ADC_NUM_BITS)\r
+//                             || GH3X2X_CHANNEL_MAP_GET(puchFifoBuffer[usByteIndexTmp]) == (g_pstGh3x2xFrameInfo[GH3X2X_FUNC_OFFSET_SPO2]->pchChnlMap[uchPPGSlotNumTmp] & GH3X2X_SLOT_ADC_NUM_BITS)\r
+//                                || GH3X2X_CHANNEL_MAP_GET(puchFifoBuffer[usByteIndexTmp]) == (g_pstGh3x2xFrameInfo[GH3X2X_FUNC_OFFSET_SOFT_ADT_GREEN]->pchChnlMap[uchPPGSlotNumTmp] & GH3X2X_SLOT_ADC_NUM_BITS)\r
+//                                || GH3X2X_CHANNEL_MAP_GET(puchFifoBuffer[usByteIndexTmp]) == (g_pstGh3x2xFrameInfo[GH3X2X_FUNC_OFFSET_SOFT_ADT_IR]->pchChnlMap[uchPPGSlotNumTmp] & GH3X2X_SLOT_ADC_NUM_BITS)\r
+                )\r
+                {\r
+                    STGh3x2xRsInfo * pstRsInfo_PPG = g_pstGh3x2xPPGRsInfo + uchPPGSlotNumTmp;\r
+                    g_uchDownSampleModule = DOWNSAMPLE_PPG;\r
+                    GH3X2X_DownSampleCal(puchFifoBuffer, usByteIndexTmp, &usRawdataBufIdx, pstRsInfo_PPG,pstPPGDownSampCalParamInfo);\r
+                    usCheckDataType =2;\r
+                }\r
+            }\r
+        }\r
+        #endif\r
+        if(!usCheckDataType)\r
+        {\r
+            if(pstECGDownSampCalParamInfo->uchRsEnable)\r
+            {\r
+                //this rawdata is not ECG data\r
+                puchFifoBuffer[usRawdataBufIdx]     = puchFifoBuffer[usByteIndexTmp];\r
+                puchFifoBuffer[usRawdataBufIdx + 1] = puchFifoBuffer[usByteIndexTmp + 1];\r
+                puchFifoBuffer[usRawdataBufIdx + 2] = puchFifoBuffer[usByteIndexTmp + 2];\r
+                puchFifoBuffer[usRawdataBufIdx + 3] = puchFifoBuffer[usByteIndexTmp + 3];\r
+                usRawdataBufIdx += GH3X2X_FIFO_RAWDATA_SIZE;\r
+            }\r
+        }\r
+        usCheckDataType = 0;\r
+    } // end of for (usByteIndexTmp = 0; usByteIndexTmp < usFifoBufferLen; usByteIndexTmp += GH3X2X_FIFO_RAWDATA_SIZE)\r
+    *pusFifoBufferLen = usRawdataBufIdx;\r
+}\r
+\r
+GU8 GH3X2X_EcgRsHandle(GU8* puchFifoBuffer, GU16* pusFifoBufferLen)\r
+{\r
+    if(pstECGDownSampCalParamInfo->uchRsEnable == 1)\r
+    {\r
+        GH3X2X_EcgPPGRsHandleSingleChip(puchFifoBuffer, pusFifoBufferLen, 0);\r
+        GH3X2X_CalRawdataBuf(puchFifoBuffer, *pusFifoBufferLen);\r
+        return 1;\r
+    }\r
+    else\r
+    {\r
+        return 0;\r
+    }\r
+}\r
+\r
+#endif\r
+\r
+//---------------------cascade-----------------------------\r
+\r
+#if !__GH3X2X_CASCADE_EN__\r
+GU8 GH3X2X_CascadeGetEcgEnFlag(void){return 0;}\r
+void GH3X2X_CascadeEcgSlaverLeadDectDisEx(void){}\r
+void GH3X2X_CascadeEcgSlaverFastRecTrigEx(void){}\r
+#else\r
+GU8 guchChip1EcgLeadFlag = 0;   //0:lead off 1:lead on\r
+GU8 guchChip2EcgLeadFlag = 0;   //0:lead off 1:lead on\r
+\r
+GS8 GH3X2X_CascadeCalibrateECGGain(GU8 *puchReadFifoBuffer, GU16 usFifoBufferLen)\r
+{\r
+    GU16 usByteIndexTmp = 0;\r
+    GS8  chGainCodeMaster = 0;\r
+    GS8  chGainCodeSlaver = 0;\r
+    GU32 unRawdataVal = 0;\r
+    GS64 nRawdatalVal = 0;\r
+    GS64 nRawdataRealVal = 0;\r
+    GS8 chRet = GH3X2X_RET_OK;\r
+\r
+    \r
+    chGainCodeMaster = (GS8)GH3X2X_GET_LOW_BYTE_FROM_WORD(GH3X2X_ReadReg(GH3X2X_EFUSE_CTRL_EFUSE0_AUTOLOAD_2_ADDR));\r
+    GH3X2X_CascadeOperationSlaverChip();\r
+    chGainCodeSlaver = (GS8)GH3X2X_GET_LOW_BYTE_FROM_WORD(GH3X2X_ReadReg(GH3X2X_EFUSE_CTRL_EFUSE0_AUTOLOAD_2_ADDR));\r
+    GH3X2X_CascadeOperationMasterChip();\r
+    \r
+    //if (GH3X2X_CHECK_BIT_SET(GH3X2X_GET_FUNC_START_BITMAP, GH3X2X_STARTED_BITMAP_ECG))\r
+    if (GH3X2X_CHECK_BIT_SET(g_unFuncStartedBitmap, GH3X2X_FUNCTION_ECG))\r
+    {\r
+        if(GH3X2X_CheckRawdataBuf(puchReadFifoBuffer, usFifoBufferLen))\r
+        {\r
+            return chRet;\r
+        }\r
+    \r
+        for(usByteIndexTmp = 0; usByteIndexTmp < usFifoBufferLen; usByteIndexTmp += GH3X2X_FIFO_RAWDATA_SIZE)\r
+        {\r
+            //if(GH3X2X_CHANNEL_MAP_GET(puchReadFifoBuffer[usByteIndexTmp]) == g_uchEcgChannelMap)\r
+            if(GH3X2X_CHANNEL_MAP_GET(puchReadFifoBuffer[usByteIndexTmp]) == (g_pstGh3x2xFrameInfo[GH3X2X_FUNC_OFFSET_ECG]->pchChnlMap[0]& GH3X2X_SLOT_ADC_NUM_BITS))\r
+            \r
+            {\r
+                unRawdataVal = GH3X2X_MAKEUP_DWORD(puchReadFifoBuffer[usByteIndexTmp], puchReadFifoBuffer[usByteIndexTmp + 1],\r
+                                              puchReadFifoBuffer[usByteIndexTmp + 2], puchReadFifoBuffer[usByteIndexTmp + 3]);\r
+\r
+                nRawdatalVal = GH3X2X_RAWDATA_CLEAR_ALL_FLAG(unRawdataVal);\r
+\r
+                nRawdataRealVal = ((GS64)nRawdatalVal - GH3X2X_RAWDATA_REAL_OFFSET) * 1024/((GS64)chGainCodeMaster + 1024) + GH3X2X_RAWDATA_REAL_OFFSET;\r
+\r
+                puchReadFifoBuffer[usByteIndexTmp + 1] = GH3X2X_GET_BYTE2_FROM_DWORD(nRawdataRealVal);\r
+                puchReadFifoBuffer[usByteIndexTmp + 2] = GH3X2X_GET_BYTE1_FROM_DWORD(nRawdataRealVal);\r
+                puchReadFifoBuffer[usByteIndexTmp + 3] = GH3X2X_GET_BYTE0_FROM_DWORD(nRawdataRealVal);\r
+                \r
+            }\r
+            else  if(GH3X2X_CHANNEL_MAP_GET(puchReadFifoBuffer[usByteIndexTmp]) == (g_pstGh3x2xFrameInfo[GH3X2X_FUNC_OFFSET_ECG]->pchChnlMap[1]& GH3X2X_SLOT_ADC_NUM_BITS))\r
+            {\r
+                unRawdataVal = GH3X2X_MAKEUP_DWORD(puchReadFifoBuffer[usByteIndexTmp], puchReadFifoBuffer[usByteIndexTmp + 1],\r
+                                              puchReadFifoBuffer[usByteIndexTmp + 2], puchReadFifoBuffer[usByteIndexTmp + 3]);\r
+\r
+                nRawdatalVal = GH3X2X_RAWDATA_CLEAR_ALL_FLAG(unRawdataVal);\r
+\r
+                nRawdataRealVal = ((GS64)nRawdatalVal - GH3X2X_RAWDATA_REAL_OFFSET) * 1024/((GS64)chGainCodeSlaver + 1024) + GH3X2X_RAWDATA_REAL_OFFSET;\r
+\r
+                puchReadFifoBuffer[usByteIndexTmp + 1] = GH3X2X_GET_BYTE2_FROM_DWORD(nRawdataRealVal);\r
+                puchReadFifoBuffer[usByteIndexTmp + 2] = GH3X2X_GET_BYTE1_FROM_DWORD(nRawdataRealVal);\r
+                puchReadFifoBuffer[usByteIndexTmp + 3] = GH3X2X_GET_BYTE0_FROM_DWORD(nRawdataRealVal);\r
+            }\r
+        }\r
+        GH3X2X_CalRawdataBuf(puchReadFifoBuffer, usFifoBufferLen);\r
+    }\r
+    else\r
+    {\r
+         chRet = GH3X2X_RET_GENERIC_ERROR;\r
+         GH3X2X_DEBUG_LOG_PARAM("ecg hasn't started error!\r\n");\r
+    }\r
+    return chRet;\r
+}\r
+\r
+void GH3X2X_CascadeEcgSlaverLeadDectDis(void)\r
+{\r
+    GH3X2X_DEBUG_LOG_PARAM("Chip222 Lead Dec Stop\r\n");\r
+    GH3X2X_CascadeOperationSlaverChip();\r
+    ECG_LEAD_DET_EN_CONFIG(0);\r
+    GH3X2X_CascadeOperationMasterChip();\r
+}\r
+\r
+void GH3X2X_CascadeEcgSlaverLeadDectEn(void)\r
+{\r
+    //ECG_LEAD_DET_EN_CONFIG(1);\r
+    GH3X2X_DEBUG_LOG_PARAM("Chip222 Lead Dec Start\r\n");\r
+    GH3X2X_CascadeOperationSlaverChip();\r
+    ECG_LEAD_DET_EN_CONFIG(1);\r
+    GH3X2X_CascadeOperationMasterChip();\r
+}\r
+\r
+void GH3X2X_CascadeSetChip1LeadSta(GU8 uchLeadOnStatus)\r
+{\r
+    guchChip1EcgLeadFlag = uchLeadOnStatus;\r
+}\r
+\r
+GU8 GH3X2X_CascadeGetEcgMasterLeadStatus(GU8 *puchEvent)\r
+{\r
+    GU8 uchLastLeadFlag = guchChip1EcgLeadFlag;\r
+    guchChip1EcgLeadFlag =  GH3X2X_ReadReg(0x50c) & 0x01;\r
+    if(uchLastLeadFlag != guchChip1EcgLeadFlag)\r
+    {\r
+        if(guchChip1EcgLeadFlag)\r
+        {\r
+            (*puchEvent) |= GH3X2X_EVENT_EX_BIT_CHIP0_LEAD_ON;\r
+        }\r
+        else\r
+        {\r
+            (*puchEvent) |= GH3X2X_EVENT_EX_BIT_CHIP0_LEAD_OFF;\r
+        }\r
+    }\r
+    return guchChip1EcgLeadFlag;\r
+}\r
+\r
+void GH3X2X_CascadeSetChip2LeadSta(GU8 uchLeadOnStatus)\r
+{\r
+    guchChip2EcgLeadFlag = uchLeadOnStatus;\r
+}\r
+\r
+GU8 GH3X2X_CascadeGetEcgSlaverLeadStatus(GU8 *puchEvent)\r
+{\r
+     GU8 uchLastLeadFlag = guchChip2EcgLeadFlag;\r
+     GH3X2X_CascadeOperationSlaverChip();\r
+     guchChip2EcgLeadFlag =  GH3X2X_ReadReg(0x50c) & 0x01;\r
+     if(uchLastLeadFlag != guchChip2EcgLeadFlag)\r
+     {\r
+       if(guchChip2EcgLeadFlag)\r
+       {\r
+           (*puchEvent) |= GH3X2X_EVENT_EX_BIT_CHIP1_LEAD_ON;\r
+       }\r
+       else\r
+       {\r
+           (*puchEvent) |= GH3X2X_EVENT_EX_BIT_CHIP1_LEAD_OFF;\r
+       }\r
+     }\r
+    GH3X2X_CascadeOperationMasterChip();\r
+    \r
+    return guchChip2EcgLeadFlag;\r
+}\r
+\r
+GU16 GH3X2X_CascadeLeadOnEventPreDeal(GU16 usIrqStatus,GU16 usIrqStatusChip2,GU8 *puchEventEx)\r
+{\r
+    GH3X2X_DEBUG_LOG_PARAM("GH3X2X_CascadeLeadOnEventPreDeal!!!!\r\n");\r
+    GU8 uchMasterLeadStatus;  //0: lead off   1: lead on\r
+    GU8 uchSlaveLeadStatus;  //0: lead off   1: lead on\r
+    \r
+    if (0 != (usIrqStatus & GH3X2X_IRQ_MSK_LEAD_ON_DET_BIT))  //chip1 got lead on event\r
+    {\r
+        GH3X2X_CascadeEcgSlaverLeadDectEn();\r
+        GH3X2X_DEBUG_LOG_PARAM("chip1 lead on!!!!\r\n");\r
+    }\r
+    \r
+    if (0 != (usIrqStatusChip2 & GH3X2X_IRQ_MSK_LEAD_ON_DET_BIT))  //chip2 got lead on event\r
+    {\r
+        GH3X2X_DEBUG_LOG_PARAM("chip2 lead on!!!!\r\n");\r
+    }\r
+\r
+    uchMasterLeadStatus = GH3X2X_CascadeGetEcgMasterLeadStatus(puchEventEx);\r
+    uchSlaveLeadStatus = GH3X2X_CascadeGetEcgSlaverLeadStatus(puchEventEx);\r
+    \r
+    if ((0 != (usIrqStatus & GH3X2X_IRQ_MSK_LEAD_ON_DET_BIT)) || (0 != (usIrqStatusChip2 & GH3X2X_IRQ_MSK_LEAD_ON_DET_BIT)))\r
+    {\r
+        if ( uchMasterLeadStatus & uchSlaveLeadStatus)\r
+        {\r
+            usIrqStatus |= GH3X2X_IRQ_MSK_LEAD_ON_DET_BIT;\r
+            GH3X2X_DEBUG_LOG_PARAM("2ecg Lead On\r\n");\r
+        }\r
+        else\r
+        {\r
+            usIrqStatus &= ~GH3X2X_IRQ_MSK_LEAD_ON_DET_BIT;\r
+        }\r
+    }\r
+    //GH3X2X_CascadeLeadEventReport();\r
+    return usIrqStatus;\r
+}\r
+\r
+void GH3X2X_CascadeLeadOffResultDeal(GU8 uchLeadoffRes)\r
+{\r
+    if(uchLeadoffRes == 0)\r
+    {\r
+        return;\r
+    }\r
+\r
+    if( 0 != (uchLeadoffRes & 0x0f))  //chip1 lead off\r
+    {\r
+        GH3X2X_DEBUG_LOG_PARAM("chip1 Leadoff!!!!\r\n");\r
+    }\r
+\r
+    if( 0 != (uchLeadoffRes & 0xf0)) //chip2 lead off\r
+    {\r
+        GH3X2X_DEBUG_LOG_PARAM("Chip2 Leadoff!!!!\r\n");\r
+    }\r
+\r
+    if (0 != uchLeadoffRes) //As long as there is one chip lead off; restart\r
+    {\r
+        GH3X2X_CascadeEcgSlaverLeadDectDis();\r
+        GH3X2X_DEBUG_LOG_PARAM("Leadoff uchLeadoffRes:0x%02x!!!!\r\n", uchLeadoffRes);\r
+    }\r
+    //report lead status\r
+    //GH3X2X_CascadeLeadEventReport();\r
+}\r
+\r
+void GH3X2X_CascadeSetEcgEnFlag(GU8 uchCascadeEnFlag)\r
+{\r
+    g_uchEcgCascadeEn = uchCascadeEnFlag;\r
+      GH3X2X_LeadOffDetectInit();\r
+}\r
+// 1: init success  0: init fail\r
+void GH3X2X_CascadeSetEcgSlaveInitSuccess(GU8 uchCascadeInitSuccess)\r
+{\r
+    g_uchEcgCascadeSlaveInitSuccess = uchCascadeInitSuccess;\r
+}\r
+\r
+\r
+GU8 GH3X2X_CascadeGetEcgSlaveInitSuccess(void)\r
+{\r
+    return g_uchEcgCascadeSlaveInitSuccess;\r
+}\r
+\r
+GU8 GH3X2X_CascadeGetEcgEnFlag(void)\r
+{\r
+    return g_uchEcgCascadeEn;\r
+}\r
+\r
+void GH3X2X_CascadeEcgSlaverLeadDectDisEx(void)\r
+{\r
+    if (GH3X2X_CascadeGetEcgEnFlag())\r
+    {\r
+        GH3X2X_CascadeEcgSlaverLeadDectDis();\r
+    }\r
+}\r
+\r
+void GH3X2X_CascadeEcgSlaverFastRecTrigEx(void)\r
+{\r
+    if (GH3X2X_CascadeGetEcgEnFlag())\r
+    {\r
+        GH3X2X_CascadeOperationSlaverChip();\r
+        ECG_FAST_RECV_EN_CONFIG(1);\r
+        GH3X2X_CascadeOperationSlaverChip();\r
+    }\r
+}\r
+\r
+#endif\r
+\r
+/********END OF FILE********* Copyright (c) 2003 - 2022, Goodix Co., Ltd. ********/\r
+\r
+\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/module/gh_ecg/gh_ecg.h b/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/module/gh_ecg/gh_ecg.h
new file mode 100644 (file)
index 0000000..6730eb4
--- /dev/null
@@ -0,0 +1,268 @@
+/**\r
+ * @copyright (c) 2003 - 2022, Goodix Co., Ltd. All rights reserved.\r
+ *\r
+ * @file    gh3x2x_drv_ecg.h\r
+ *\r
+ * @brief   gh3x2x lead process functions\r
+ *\r
+ * @version ref gh3x2x_drv_version.h\r
+ *\r
+ */\r
+\r
+\r
+#ifndef _GH3X2X_DRV_ECG_H_\r
+#define _GH3X2X_DRV_ECG_H_\r
+\r
+\r
+#include "gh_drv_config.h"\r
+#include "gh_drv.h"\r
+\r
+\r
+\r
+\r
+/// difference threshold, unit: mV\r
+#define  LEADOFF_DET_DIF_THR_MV             (15)\r
+\r
+/// Val threshold, unit:mV\r
+#define  LEADOFF_DET_VAL_THR_MV             (70)\r
+\r
+/// detect sample point, if input volt v(n)-v(n- LEADOFF_DET_POINT_NUM) >  LEADOFF_DET_THR_mV,  assert lead off\r
+#define  LEADOFF_DET_POINT_NUM              (3)\r
+\r
+/// base offset detect, unit:mV\r
+#define LEADOFF_BASE_THR1_MV                (5)\r
+\r
+/// lead off base hold samp\r
+#define LEADOFF_BASE_HOLD_SAMP              (400)\r
+\r
+/// lead off base rst samp\r
+#define LEADOFF_BASE_RST_SAMP               (100)\r
+\r
+/// lead off moving num\r
+#define LEADOFF_MOVING_NUM                  (20)\r
+\r
+/* lead state */\r
+#define LEAD_STATE_LEAD_ON                  (1)     /**< lead state lead on */\r
+#define LEAD_STATE_LEAD_OFF                 (0)     /**< lead state lead off */\r
+\r
+/* soft lead type */\r
+#define SOFT_LEAD_NULL_TYPE                 (0)     /**< soft lead null type */\r
+#define SOFT_LEAD_RTYPE                     (1)     /**< soft lead R type */\r
+#define SOFT_LEAD_ITYPE                     (2)     /**< soft lead I type */\r
+\r
+/* soft lead off detect mode */\r
+#define SOFT_LEAD_OFF_DET_MODE_DISABLE      (0)     /**< soft lead off detect mode disable */\r
+#define SOFT_LEAD_OFF_DET_MODE_SW_AND_HW    (1)     /**< soft lead off detect mode sw and hw */\r
+#define SOFT_LEAD_OFF_DET_MODE_SW_ONLY      (2)     /**< soft lead off detect mode sw only */\r
+\r
+/// get ecg lead channel map from slot num\r
+#define  ECG_LEAD_GET_CHANNEL_MAP(n)        (GH3X2X_CHANNEL_MAP(GH3X2X_VAL_LEFT_SHIFT((n), 5), \\r
+                                                                GH3X2X_CHANNEL_MAP_ADC3))\r
+\r
+#define GET_ECG_LEAD_DET_EN_VAL()              (GH3X2X_ReadRegBitField(GH3X2X_ADT_LEADON_CR_REG_ADDR, \\r
+                                                    GH3X2X_ECG_LEAD_DET_EN_LSB, GH3X2X_ECG_LEAD_DET_EN_MSB))\r
+/// ecg lead detect enable config\r
+#define  ECG_LEAD_DET_EN_CONFIG(en)         do {\\r
+                                                GH3X2X_WriteRegBitField(GH3X2X_ADT_LEADON_CR_REG_ADDR, \\r
+                                                    GH3X2X_ECG_LEAD_DET_EN_LSB, GH3X2X_ECG_LEAD_DET_EN_MSB, (en)); \\r
+                                            } while (0)\r
+\r
+/// ecg fast recover enable config\r
+#define  ECG_FAST_RECV_EN_CONFIG(en)        do {\\r
+                                                GH3X2X_WriteRegBitField(GH3X2X_ECG_CTRL_REG_ADDR, \\r
+                                                    GH3X2X_ECG_FAST_RECV_EN_LSB, GH3X2X_ECG_FAST_RECV_EN_MSB, (en)); \\r
+                                            } while (0)\r
+\r
+/// lead on auto switch bit field val\r
+#define  GET_LEAD_ON_AUTO_SWITCH_VAL()      (GH3X2X_ReadRegBitField(GH3X2X_ECG_CTRL_REG_ADDR, \\r
+                                                    GH3X2X_LEAD_ON_AUTO_SWITCH_LSB, GH3X2X_LEAD_ON_AUTO_SWITCH_MSB))\r
+\r
+/// lead off auto switch bit field val\r
+#define  GET_LEAD_OFF_AUTO_SWITCH_VAL()     (GH3X2X_ReadRegBitField(GH3X2X_ECG_CTRL_REG_ADDR, \\r
+                                                    GH3X2X_LEAD_OFF_AUTO_SWITCH_LSB, GH3X2X_LEAD_OFF_AUTO_SWITCH_MSB))\r
+\r
+/// soft lead adc ref amplify num\r
+#define SOFT_LEAD_ADC_REF_AMP_NUM               (1000)\r
+\r
+/// lead off diff thr default val\r
+#define SOFT_LEAD_OFF_DIFF_THR_DEFAULT_VAL      ((GS32)(15 * (20 * GH3X2X_RAWDATA_REAL_OFFSET / 1600)))\r
+\r
+/// lead off peak thr default val\r
+#define SOFT_LEAD_OFF_PEAK_THR_DEFAULT_VAL      ((GS32)(70 * (20 * GH3X2X_RAWDATA_REAL_OFFSET / 1600)))\r
+\r
+/// lead off base thr default val\r
+#define SOFT_LEAD_OFF_BASE_THR_DEFAULT_VAL      ((GS32)(5 * (20 * GH3X2X_RAWDATA_REAL_OFFSET / 1600)))\r
+\r
+/// soft lead buffer head index init val\r
+#define SOFT_LEAD_BUFFER_HEAD_INIT_INDEX        (-1)\r
+\r
+/* soft lead off detect function ret bit val */\r
+#define SOFT_LEAD_OFF_DETECT_RET_BIT0           (0x01)      /**< bit0=1 absAdcValue larger than thresh */\r
+#define SOFT_LEAD_OFF_DETECT_RET_BIT1           (0x02)      /**< bit1=1 diff larger than thresh */\r
+#define SOFT_LEAD_OFF_DETECT_RET_BIT2           (0x04)      /**< bit2=1 adc value continuously larger than thresh */\r
+\r
+/* soft lead cfg param reg posi */\r
+#define SOFT_LEAD_CFG_PARAM_REG_POSI_0          (0u)        /**< soft lead cfg param reg posi 0 */\r
+#define SOFT_LEAD_CFG_PARAM_REG_POSI_1          (1u)        /**< soft lead cfg param reg posi 1 */\r
+#define SOFT_LEAD_CFG_PARAM_REG_POSI_2          (2u)        /**< soft lead cfg param reg posi 2 */\r
+\r
+/* soft lead cfg of bit filed */\r
+#define SOFT_LEAD_CFG_ECG_FORCE_RECV_LSB        (0)         /**< cfg index for g_uchEcgForceRecover */\r
+#define SOFT_LEAD_CFG_ECG_FORCE_RECV_MASK       (0x01)      /**< cfg mask for g_uchEcgForceRecover */\r
+#define SOFT_LEAD_CFG_EX_EN_VIA_HOST_LSB        (1)         /**< cfg index for g_uchExtraLeadDetectEnableViaHost */\r
+#define SOFT_LEAD_CFG_EX_EN_VIA_HOST_MASK       (0x01)      /**< cfg mask for g_uchExtraLeadDetectEnableViaHost */\r
+#define SOFT_LEAD_CFG_OFF_DET_MODE_LSB          (2)         /**< cfg index for g_uchSoftLeadOffDetMode */\r
+#define SOFT_LEAD_CFG_OFF_DET_MODE_MASK         (0x03)      /**< cfg mask for g_uchSoftLeadOffDetMode */\r
+#define SOFT_LEAD_CFG_ECG_GAIN_GRADE_LSB        (4)         /**< cfg index for g_uchEcgGainGrade */\r
+#define SOFT_LEAD_CFG_ECG_GAIN_GRADE_MASK       (0x07)      /**< cfg mask for g_uchEcgGainGrade */\r
+#define SOFT_LEAD_CFG_ADC_REF_GRADE_LSB         (7)         /**< cfg index for g_uchAdcRefGrade */\r
+#define SOFT_LEAD_CFG_ADC_REF_GRADE_MASK        (0x01)      /**< cfg mask for g_uchAdcRefGrade */\r
+#define SOFT_LEAD_CFG_ECG_AUTO_CTRL_LSB         (0)         /**< cfg index for g_uchEcgAutoCtrlMode */\r
+#define SOFT_LEAD_CFG_ECG_AUTO_CTRL_MASK        (0x03)      /**< cfg mask for g_uchEcgAutoCtrlMode */\r
+\r
+//G202008231001 wanpeng START\r
+/****************************** ecg lead cfg ****************************************/\r
+\r
+/**\r
+ * @brief Downsample Function\r
+*/\r
+typedef enum\r
+{\r
+       DOWNSAMPLE_ECG = 0,\r
+       DOWNSAMPLE_PPG,\r
+}EmDownSampleFunction;\r
+\r
+/**\r
+ * @brief Downsample type\r
+*/\r
+typedef enum\r
+{\r
+       DOWNSAMPLE_DEFAULT = 0,\r
+       DOWNSAMPLE_800HZ_TO_500HZ = 1,\r
+       DOWNSAMPLE_800HZ_TO_250HZ = 2,\r
+       DOWNSAMPLE_400HZ_TO_250HZ = 3,\r
+       DOWNSAMPLE_320HZ_TO_250HZ = 4,\r
+       DOWNSAMPLE_256HZ_TO_250HZ = 5,\r
+}EmDownSampleType;\r
+\r
+typedef struct \r
+{\r
+    GU8 uchElectrodeAdtEn          : 1;  //0:disable electrode adt  1:enable electrode adt\r
+    GU8 uchElectrodeWearRevCntEn   : 1;  //elctrode wear state reverse counter dis/en    0: disable  1: enable\r
+    GU8 uchSoftWearOffDetEn        : 1;  //software wear off detction enable   0: disable  1: enable\r
+    GU8 uchElectrodeSoftWearColor  : 1;  //software wear led color             0:green     1:ir\r
+    GU8 uchHardAdtCheckByAlgo      : 1;  //0: do not use algo to judge adt   1: use algo to judge adt\r
+    GU8 uchRes                     : 3;\r
+}STAdtCfgByte0;\r
+\r
+\r
+\r
+typedef struct t_adt_cfg\r
+{\r
+    GU8 uchAdtSampleCtrlMode;     // 0: wear state do not affect sample  1:  wear off only open adt slot     2: wear on/off need switch cfg    \r
+    STAdtCfgByte0 stAdtCfgByte0;   \r
+    GU8 ubResByte2;\r
+    GU8 ubResByte3;\r
+}STAdtCfg;\r
+\r
+\r
+\r
+\r
+typedef struct\r
+{\r
+    GU8 uchForceRecover           :1;  /* 0: do not force recover when ecg starting sample   1: do force recover when ecg starting sample */\r
+    GU8 uchNeedHostEnableLeadDet  :1;  /* 0: host no need extra enable lead detecting  1:  host need extra enable lead detecting */\r
+    GU8 uchSoftLeadDetMode        :2;  /* 0: disable  lead off detect  1: SW&HW 2: SW only    */\r
+    GU8 uchEcgGainGrade           :3;  /* 0: 1x  1: 2.5x  2: 5x  3: 10x  4: 20x */\r
+    GU8 uchAdcRefGrade            :1;  /* 0: 1.6 V  1: 1.8 V */\r
+} STEcgLeadCtrlFlag1;\r
+\r
+\r
+typedef struct\r
+{\r
+    GU8 uchAutoCtrlMode           :2;  /* 0: disable   1: hardware 2: software */\r
+    GU8 uchDisItypeWhenEcgSample  :1;  /* 0: do not disable Itype  when ecg sample stating  1:  disable Itype  when ecg sample stating */\r
+    GU8 uchWearOffLogic           :1;  /* 0:do not rest with ecg elctronde only  1: rest with ecg elctronde only    */\r
+    GU8 Res                       :4;  \r
+} STEcgLeadCtrlFlag2;\r
+\r
+\r
+\r
+\r
+typedef struct\r
+{\r
+    STEcgLeadCtrlFlag1 uchEcgLeadCtrlFlag1;             \r
+    GU8 uchLeadOffPeakVolt;              \r
+    GU8 uchLeadOffDiffVolt; \r
+    GU8 uchLeadOffBaseVolt; \r
+    STEcgLeadCtrlFlag2 uchEcgLeadCtrlFlag2;                            \r
+    GU8 uchRes1;             \r
+} STEcgLeadCfg;\r
+\r
+typedef struct\r
+{\r
+    GU8   uchRsFirOrder;\r
+    GU8   uchRsI;\r
+    GU8   uchRsD;\r
+    GU8   uchRsFirCoefNum;\r
+    GU8   uchRsBufSize;\r
+    GU8   uchRsEnable;\r
+    GU32  ufStep;\r
+    GS32* rsFirCoef;\r
+               GU8   uchDownSampleType;\r
+} STGh3x2xDownSampleCalParamInfo;\r
+\r
+\r
+\r
+/**\r
+ * @fn     void GH3X2X_EcgForceRecoverAfterSlotCtrl(GU16 usSlotEnableConfig, GU8 uchSlotEnable)\r
+ *\r
+ * @brief  ecg sample  hook handle after ecg slot ctrl\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   usSlotEnableConfig         slot enable index , @ref GH3X2X_SLOT_INDEX_0 ... GH3X2X_SLOT_INDEX_ALL\r
+ * @param[in]   uchSlotEnable              enable flag, #0 slot disable, #others slot enable\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_EcgSampleHookHandleAfterSlotCtrl(GU16 usSlotEnableConfig, GU8 uchSlotEnable);\r
+\r
+\r
+\r
+/**\r
+ * @fn     void GH3X2X_EcgLeadSlotConfig(GU8 uchEcgSlotBit)\r
+ *\r
+ * @brief  ecg lead slot config\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   uchEcgSlotBit                      ecg slot bit, @ref GH3X2X_SLOT_INDEX_0...\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_EcgLeadSlotConfig(GU8 uchEcgSlotBit);\r
+\r
+/**\r
+ * @fn     GH3X2X_LeadDetEnControl(GU8 uchEventInfo)\r
+ *\r
+ * @brief  lead detect enable control\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   uchEventInfo         control event, only ecg start/stop evt \r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_LeadDetEnControl(GU8 uchEventInfo);\r
+\r
+void GH3x2xSetEcgOutputFs(GU16 usEcgOutputFs);\r
+void GH3X2X_WriteAdtDrvConfigWithVirtualReg(GU16 usVirtualRegAddr, GU16 usVirtualRegValue);\r
+\r
+#endif /* _GH3X2X_DRV_SOFT_LEAD_H_ */\r
+\r
+/********END OF FILE********* Copyright (c) 2003 - 2022, Goodix Co., Ltd. ********/\r
+\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/module/gh_other/gh_changeinttime.c b/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/module/gh_other/gh_changeinttime.c
new file mode 100644 (file)
index 0000000..32c20f8
--- /dev/null
@@ -0,0 +1,106 @@
+#include "gh_drv.h"\r
+\r
+#define  GH3X2X_SLOT0_CTRL_3_REG_ADDR               (0x0110)\r
+#define  GH3X2X_SLOT_CTRL_OFFSET                    (0x001C)    \r
+#define  GH3X2X_RG_SLOT_TMR0_REG_ADDR               (0x01EC)\r
+#define  GH3X2X_SLOT_ADC_INT_TIME_LSB               (0)\r
+#define  GH3X2X_SLOT_ADC_INT_TIME_MSB               (3)\r
+#define  GH3X2X_SLOT_BG_LEVEL_LSB                   (4)\r
+#define  GH3X2X_SLOT_BG_LEVEL_MSB                   (5)\r
+#define  GH3X2X_SLOT_BG_CANCEL_LSB                  (10)\r
+#define  GH3X2X_SLOT_BG_CANCEL_MSB                  (10)\r
+\r
+static const GU16 gusSlotTimeList[3][7] = {\r
+{26,    36,    46,    56,    95,    174,    331},\r
+{48,    67,    87,    107,    186,    343,    658},\r
+{69,    99,    128,    158,    276,    512,    985}\r
+};\r
+\r
+\r
+static void GH3x2x_SetIntTime(GU8 uchSlotNo, GU8 uchIntTimeIndex)\r
+{    \r
+    GH3X2X_WriteRegBitField(GH3X2X_SLOT0_CTRL_3_REG_ADDR + GH3X2X_SLOT_CTRL_OFFSET*uchSlotNo,GH3X2X_SLOT_ADC_INT_TIME_LSB,GH3X2X_SLOT_ADC_INT_TIME_MSB, uchIntTimeIndex);\r
+}\r
+\r
+static void GH3x2x_SetSlotTime(GU8 uchSlotNo, GU16 usSlotTime)\r
+{    \r
+    GH3X2X_WriteReg(GH3X2X_RG_SLOT_TMR0_REG_ADDR + 2*uchSlotNo, usSlotTime);\r
+}\r
+\r
+/**\r
+ * @fn      void GH3x2x_ChangeIntTime(GU8 uchSlotNo , GU8  chIntTimeIndex)\r
+ * @brief  change slot int time \r
+ *\r
+ * @attention   None.\r
+ *\r
+ * @param[in]   uchSlotNo: slot number\r
+ * @param[in]   uchIntTimeIndex: Int time index,0:10us 1:20us 2:30us 3:39us 4:79us 5:158us 6:316us\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3x2x_ChangeIntTime(GU8 uchSlotNo, GU8 uchIntTimeIndex)\r
+{\r
+    GU8 uchBglevel = 0;    //slot bg level\r
+    GU8 uchBgCancel = 0;   //slot bg cancel\r
+    GU16 usTimeSlot = 0;\r
+    GU8 uchCfgIndex = 0;   \r
+    GU8 uchSlotIndex = 0;\r
+\r
+    //read bg level\r
+    uchBglevel = GH3X2X_ReadRegBitField(GH3X2X_SLOT0_CTRL_3_REG_ADDR + GH3X2X_SLOT_CTRL_OFFSET*uchSlotNo,GH3X2X_SLOT_BG_LEVEL_LSB,GH3X2X_SLOT_BG_LEVEL_MSB);\r
+    //read bg cancel\r
+    uchBgCancel= GH3X2X_ReadRegBitField(GH3X2X_SLOT0_CTRL_3_REG_ADDR + GH3X2X_SLOT_CTRL_OFFSET*uchSlotNo,GH3X2X_SLOT_BG_CANCEL_LSB,GH3X2X_SLOT_BG_CANCEL_MSB);\r
+\r
+    if(uchBglevel > 2)\r
+    {\r
+        uchBglevel = 2;\r
+    }\r
+    usTimeSlot = gusSlotTimeList[uchBglevel][uchIntTimeIndex];\r
+    if(uchBgCancel > 0)\r
+    {\r
+        usTimeSlot += 104;\r
+    }\r
+    usTimeSlot += 80;  \r
+\r
+    //find cfg index\r
+    for(GU8 uchSlotCnt = 0; uchSlotCnt < 8; uchSlotCnt ++)\r
+    {\r
+        if(0 == (uchSlotCnt&0x01)) //0,2,4,6\r
+        {\r
+            uchCfgIndex = GH3X2X_ReadRegBitField(0x0100 + (uchSlotCnt&0xFE), 0,3);\r
+        }\r
+        else  //1,3,5,7\r
+        {\r
+           uchCfgIndex = GH3X2X_ReadRegBitField(0x0100 + (uchSlotCnt&0xFE), 8,11);\r
+        }\r
+\r
+        if(uchCfgIndex == uchSlotNo)\r
+        {\r
+            uchSlotIndex = uchSlotCnt;\r
+        }\r
+    }\r
+\r
+    GH3x2x_SetIntTime(uchSlotNo,uchIntTimeIndex);\r
+    GH3x2x_SetSlotTime(uchSlotIndex,usTimeSlot);\r
+}\r
+\r
+//示例代码\r
+#if 0\r
+void main()\r
+{\r
+    GU8 usStartReg;\r
+    usStartReg = GH3X2X_ReadReg(0x0000);  //read start reg\r
+    \r
+    if(usStartReg & 0x0001)\r
+    {\r
+        GH3X2X_WriteReg(0x0000,usStartReg&(0xFFFE));   //停止采样,确保更改积分时间前停止采样\r
+        GH3x2x_ChangeIntTime(0,1);\r
+        GH3X2X_WriteReg(0x0000,usStartReg|0x0001);   //重新采样,更改积分时间后重新开始采样\r
+    }\r
+    else\r
+    {\r
+        GH3x2x_ChangeIntTime(0,1);\r
+    }\r
+}\r
+#endif\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/module/gh_other/gh_movedetect.c b/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/module/gh_other/gh_movedetect.c
new file mode 100644 (file)
index 0000000..9ce8854
--- /dev/null
@@ -0,0 +1,192 @@
+/**\r
+* @copyright (c) 2003 - 2022, Goodix Co., Ltd. All rights reserved.\r
+*\r
+* @file    gh_movedetect.c\r
+*\r
+* @brief   gh move detect functions\r
+*\r
+* @version ref gh3x2x_drv_version.h\r
+*\r
+*/\r
+\r
+\r
+#include <math.h>\r
+#include "gh_demo_config.h"\r
+#include "gh_demo_inner.h"\r
+#include "gh_drv.h"\r
+#include "gh_movedetect.h"\r
+\r
+\r
+//-----------------------------------------------------\r
+typedef struct\r
+{\r
+    GS16 sXAxisVal;     /**< x-axis value */\r
+    GS16 sYAxisVal;     /**< y-axis value */\r
+    GS16 sZAxisVal;     /**< z-axis value */\r
+} STGsAccRawdata;\r
+\r
+STGsAccRawdata g_LastPointAdtGsenorRawdata;\r
+\r
+typedef struct\r
+{\r
+    GS16 sXAxisVal;     /**< x-axis value */\r
+    GS16 sYAxisVal;     /**< y-axis value */\r
+    GS16 sZAxisVal;     /**< z-axis value */\r
+    GS16 sAccVal;       /**< acc-axis value */\r
+    GS16 sLastAccVal;       /**< acc-axis value */\r
+    GS16 sAccDifBuf[125];\r
+    GU16  sAccThrNum;       /**< acc-axis value */\r
+    GU16  sAccThrMax;       /**< acc-axis value */\r
+    GU16  sAccThrMin;       /**< acc-axis value */\r
+    GU16  sAccThrScale;       /**< acc-axis value */\r
+    GU8  uchGsensorDifBufIndex;\r
+} STGsAccMoverEventCheck;\r
+\r
+STGsAccMoverEventCheck g_MoveEventCheckStruct;\r
+GU16 g_bufferlen;\r
+GS32 g_siLastDirectionAngle = 0;\r
+\r
+/**\r
+* @fn      GetGsensorMoveEventCheckIni(GU8 usAccThrMax, GU8 usAccThrMin,GU8 usAccThrScale,GU8 usAccThrNum)\r
+*\r
+* @brief  initialzation of GetGsensorMoveEventCheckExe.\r
+*\r
+* @attention   None\r
+*\r
+* @param[in]   Thr param\r
+* @param[out]   none\r
+*\r
+* @return  none\r
+*/\r
+\r
+void GetGsensorMoveEventCheckIni(GU16 usAccThrMax, GU16 usAccThrMin, GU16 usAccThrScale, GU16 usAccThrNum)\r
+{\r
+    GH3X2X_Memset(g_MoveEventCheckStruct.sAccDifBuf, 0, 125 * sizeof(GS16));\r
+    g_MoveEventCheckStruct.sAccThrMax = usAccThrMax;\r
+    g_MoveEventCheckStruct.sAccThrMin = usAccThrMin;\r
+    g_MoveEventCheckStruct.sAccThrNum = usAccThrNum;\r
+    g_MoveEventCheckStruct.sAccThrScale = usAccThrScale;\r
+    g_MoveEventCheckStruct.sAccVal = 0;\r
+    g_MoveEventCheckStruct.sLastAccVal = 0;\r
+    g_MoveEventCheckStruct.sXAxisVal = 0;\r
+    g_MoveEventCheckStruct.sYAxisVal = 0;\r
+    g_MoveEventCheckStruct.sZAxisVal = 0;\r
+    g_MoveEventCheckStruct.uchGsensorDifBufIndex = 0;\r
+    g_bufferlen = 125;\r
+    g_siLastDirectionAngle = 0;\r
+}\r
+\r
+/**\r
+* @fn      GU8 GetGsensorMoveEventCheckExe(GS16* pusGsData)\r
+\r
+*\r
+* @brief  Get the movement event by software.\r
+*\r
+* @attention   None\r
+*\r
+* @param[in]   pusGsData         gsensor data buffer\r
+* @param[out]  mN >= g_MoveEventCheckStruct.sAccThrNum\r
+*\r
+* @return  //bit0 move flag  bit1 direct abnormal flag\r
+*/\r
+GU8 GetGsensorMoveEventCheckExe(GS16* pusGsData)\r
+{\r
+    GS32 sRmsAcc = 0.0;\r
+    GF32 fMeanAcc = 0.0;\r
+    GF32 fStdAcc = 0.0;\r
+    GF32 fSumX = 0.0;\r
+    GF32 fSumX2 = 0.0;\r
+    GU8 mN = 0;\r
+    GU8 lubMoveFlag = 0; //bit0 move flag  bit1 direct abnormal flag\r
+    GS32 lsiDirectionAngle = 0;\r
+    GU8 uchFirstFrameFlag = 0;\r
+    g_MoveEventCheckStruct.sXAxisVal = pusGsData[0];\r
+    g_MoveEventCheckStruct.sYAxisVal = pusGsData[0 + 1];\r
+    g_MoveEventCheckStruct.sZAxisVal = pusGsData[0 + 2];\r
+\r
+    sRmsAcc = sqrt((GS32)g_MoveEventCheckStruct.sXAxisVal*g_MoveEventCheckStruct.sXAxisVal + (GS32)g_MoveEventCheckStruct.sYAxisVal*g_MoveEventCheckStruct.sYAxisVal + (GS32)g_MoveEventCheckStruct.sZAxisVal*g_MoveEventCheckStruct.sZAxisVal) / 3;\r
+\r
+    if (0 == g_MoveEventCheckStruct.uchGsensorDifBufIndex)\r
+    {\r
+        uchFirstFrameFlag = 1;\r
+        g_MoveEventCheckStruct.sAccDifBuf[g_MoveEventCheckStruct.uchGsensorDifBufIndex] = 0;\r
+        ++g_MoveEventCheckStruct.uchGsensorDifBufIndex;\r
+    }\r
+    else\r
+    {\r
+        uchFirstFrameFlag = 0;\r
+        if (g_MoveEventCheckStruct.uchGsensorDifBufIndex < g_bufferlen)\r
+        {\r
+            g_MoveEventCheckStruct.sAccDifBuf[g_MoveEventCheckStruct.uchGsensorDifBufIndex] = (GS16)sRmsAcc - g_MoveEventCheckStruct.sLastAccVal;\r
+            ++g_MoveEventCheckStruct.uchGsensorDifBufIndex;\r
+        }\r
+        else\r
+        {\r
+            memmove(g_MoveEventCheckStruct.sAccDifBuf, g_MoveEventCheckStruct.sAccDifBuf + 1, (g_bufferlen - 1)*sizeof(GS16));\r
+            g_MoveEventCheckStruct.sAccDifBuf[g_bufferlen - 1] = (GS16)sRmsAcc - g_MoveEventCheckStruct.sLastAccVal;\r
+        }\r
+    }\r
+    g_MoveEventCheckStruct.sLastAccVal = sRmsAcc;\r
+\r
+    for (GU8 i = 0; i < g_MoveEventCheckStruct.uchGsensorDifBufIndex; i++)\r
+    {\r
+        fSumX = fSumX + g_MoveEventCheckStruct.sAccDifBuf[i];\r
+        fSumX2 = fSumX2 + (GF32)g_MoveEventCheckStruct.sAccDifBuf[i] * g_MoveEventCheckStruct.sAccDifBuf[i];\r
+    }\r
+    fMeanAcc = fSumX / g_MoveEventCheckStruct.uchGsensorDifBufIndex;\r
+    fStdAcc = sqrtf(((fSumX2 / g_MoveEventCheckStruct.uchGsensorDifBufIndex - fMeanAcc*fMeanAcc) >(0) ? (fSumX2 / g_MoveEventCheckStruct.uchGsensorDifBufIndex - fMeanAcc*fMeanAcc) : (0)));\r
+\r
+    GF32 ftemp = ((g_MoveEventCheckStruct.sAccThrScale*fStdAcc) > (g_MoveEventCheckStruct.sAccThrMin) ? (g_MoveEventCheckStruct.sAccThrScale*fStdAcc) : (g_MoveEventCheckStruct.sAccThrMin));\r
+    GF32 fThr = ((g_MoveEventCheckStruct.sAccThrMax) < (ftemp) ? (g_MoveEventCheckStruct.sAccThrMax) : (ftemp));\r
+\r
+    for (GU8 i = 0; i < g_MoveEventCheckStruct.uchGsensorDifBufIndex; i++)\r
+    {\r
+        if ((GF32)g_MoveEventCheckStruct.sAccDifBuf[i] - fMeanAcc > fThr || (GF32)fMeanAcc - g_MoveEventCheckStruct.sAccDifBuf[i] > fThr)\r
+        {\r
+            mN++;\r
+        }\r
+    }\r
+    //return (mN >= g_MoveEventCheckStruct.sAccThrNum);\r
+    if (mN >= g_MoveEventCheckStruct.sAccThrNum)\r
+    {\r
+        lubMoveFlag |= (((GU8)1) << 0);   //set bit0 : move flag\r
+    }\r
+\r
+\r
+    //checak calculate direct is abnormal or not\r
+    lsiDirectionAngle = atan(sqrt(((GS32)g_MoveEventCheckStruct.sXAxisVal*g_MoveEventCheckStruct.sXAxisVal + (GS32)g_MoveEventCheckStruct.sYAxisVal*g_MoveEventCheckStruct.sYAxisVal)) / g_MoveEventCheckStruct.sZAxisVal) * 180 / 3.1416;\r
+    if (uchFirstFrameFlag)  // first frame\r
+    {\r
+        g_siLastDirectionAngle = lsiDirectionAngle; //use the rawdata\r
+    }\r
+    else  // do IIR filter\r
+    {\r
+        g_siLastDirectionAngle = (lsiDirectionAngle * 1 + g_siLastDirectionAngle * 3) / 4;  // current data weight is 0.25\r
+    }\r
+    if ((g_siLastDirectionAngle > 40) || (g_siLastDirectionAngle < 0)) // angle is too big or  watch screen is downward\r
+    {\r
+        lubMoveFlag |= (((GU8)1) << 1);   //set bit1 : abnormale angel\r
+    }\r
+\r
+    return lubMoveFlag;\r
+}\r
+\r
+\r
+//source code\r
+#if 0\r
+void main()\r
+{\r
+    GU16 usAccThrMax=30;\r
+    GU16 usAccThrMin=15;\r
+    GU16 usAccThrScale=4;\r
+    GU16 usAccThrNum=3;\r
+    GetGsensorMoveEventCheckIni(usAccThrMax, usAccThrMin, usAccThrScale, usAccThrNum);\r
+\r
+    GS16 pusGsData[3] = {0};\r
+    pusGsData[0] = 1; //x\r
+    pusGsData[1] = 2; //y\r
+    pusGsData[2] = 512; //z\r
+    GU8 result = GetGsensorMoveEventCheckExe(pusGsData);\r
+\r
+}\r
+#endif\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/module/gh_other/gh_movedetect.h b/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/module/gh_other/gh_movedetect.h
new file mode 100644 (file)
index 0000000..c8ed125
--- /dev/null
@@ -0,0 +1,24 @@
+/**\r
+ * @copyright (c) 2003 - 2022, Goodix Co., Ltd. All rights reserved.\r
+ *\r
+ * @file    gh_movedetect.h\r
+ *\r
+ * @brief   move detect\r
+ *\r
+ * @version ref gh_drv_version.h\r
+ *\r
+ */\r
+\r
+\r
+#ifndef _GH_MOVEDETECT_H_\r
+#define _GH_MOVEDETECT_H_\r
+\r
+#include "gh_drv.h"\r
+\r
+void GetGsensorMoveEventCheckIni(GU16 usAccThrMax, GU16 usAccThrMin,GU16 usAccThrScale,GU16 usAccThrNum);\r
+GU8 GetGsensorMoveEventCheckExe(GS16* pusGsData);\r
+\r
+#endif /* _GH_MOVEDETECT_H_ */\r
+\r
+/********END OF FILE********* Copyright (c) 2003 - 2022, Goodix Co., Ltd. ********/\r
+\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/module/gh_protocol/gh_datatrans.c b/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/module/gh_protocol/gh_datatrans.c
new file mode 100644 (file)
index 0000000..df566fe
--- /dev/null
@@ -0,0 +1,536 @@
+#include "gh_drv.h"\r
+#include "gh_drv_common.h"\r
+#include "gh_datatrans.h"\r
+//#include "goodix_mem.h"\r
+\r
+static GU8 g_uchPayloadHandleInitFlag = 0;\r
+static GU8 g_uchProtocolCmd = 0;\r
+static GU16 g_usPayloadBufferLength = 0;\r
+static GU16 g_usPayloadBufferOffset = 0;\r
+static GU8 *g_puchPayloadBuffer = GH3X2X_PTR_NULL;\r
+static pfnSendProtocolDataFunc g_pGh3x2xProtocolSendFunc;\r
+static pfnFrameDataOutputFunc g_pGh3x2xProtocolFrameDataOutputFunc;\r
+\r
+void* GH3X2X_UserMalloc(GU32 mem_len)\r
+{\r
+    void* addr = 0;//goodix_mem_malloc(mem_len);\r
+    return addr;\r
+}\r
+\r
+void GH3X2X_UserFree(void* mem_addr)\r
+{\r
+    //goodix_mem_free(mem_addr);\r
+}\r
+\r
+EMPayloadHandleRet GH3X2X_ProtocolSectionInit(GU8 uchProtocolCmd,\r
+                                              GU8 *puchPayloadDataBuffer,\r
+                                              GU16 usPayloadDataBufferLength,\r
+                                              void (*pfnSendProtocolDataFunc)(GU8 uchCmd, GU8* puchBuffer, GU16 usLen),\r
+                                              void (*pfnFrameDataOutputFunc)(GU8* puchFunctionID,\r
+                                                                             GU8* puchFrameID,\r
+                                                                             STProtocolPackInfo** pstReceivePackInfo,\r
+                                                                             GU8* puchPackNum))\r
+{\r
+    if ((pfnSendProtocolDataFunc != GH3X2X_PTR_NULL) ||\r
+        (pfnFrameDataOutputFunc != GH3X2X_PTR_NULL) ||\r
+        (usPayloadDataBufferLength != 0) ||\r
+        (g_puchPayloadBuffer != GH3X2X_PTR_NULL))\r
+    {\r
+        g_uchProtocolCmd = uchProtocolCmd;\r
+        g_pGh3x2xProtocolSendFunc = pfnSendProtocolDataFunc;\r
+        g_puchPayloadBuffer = puchPayloadDataBuffer;\r
+        g_usPayloadBufferLength = usPayloadDataBufferLength;\r
+        g_usPayloadBufferOffset = usPayloadDataBufferLength;\r
+        g_pGh3x2xProtocolFrameDataOutputFunc = pfnFrameDataOutputFunc;\r
+        g_uchPayloadHandleInitFlag = 1;\r
+        return GH_PAYLOAD_HANDLE_CONTINUE;\r
+    }\r
+    else\r
+    {\r
+        g_uchPayloadHandleInitFlag = 0;\r
+        return GH_PAYLOAD_HANDLE_NOINIT;\r
+    }\r
+}\r
+\r
+EMPayloadHandleRet GH3X2X_ProtocolPackCheck(STProtocolPackInfo *pstPackInfo)\r
+{\r
+    if (pstPackInfo != GH3X2X_PTR_NULL)\r
+    {\r
+        if ((pstPackInfo->uchByteType != 0) &&\r
+            (pstPackInfo->uchDataNum != 0) &&\r
+            (pstPackInfo->pSrc != GH3X2X_PTR_NULL))\r
+        {\r
+            return GH_PAYLOAD_HANDLE_CONTINUE;\r
+        }\r
+        else\r
+        {\r
+            if (pstPackInfo->pSrc == GH3X2X_PTR_NULL)\r
+            {\r
+                return GH_PAYLOAD_HANDLE_ADDRNULL;\r
+            }\r
+            else\r
+            {\r
+                return GH_PAYLOAD_HANDLE_DATAERR;\r
+            }\r
+        }\r
+    }\r
+    else\r
+    {\r
+        return GH_PAYLOAD_HANDLE_ADDRNULL;\r
+    }\r
+}\r
+\r
+EMPayloadHandleRet GH3X2X_ProtocolPackHandle(STProtocolPackInfo *pstPackInfo,\r
+                                             GU8 *puchPayloadDest,\r
+                                             GU16 *pusPayloadMaxLen,\r
+                                             GU8 uchSeparateFlag,\r
+                                             GU32 *punSeparateDataOffset)\r
+{\r
+    GU16 usPayloadMaxLen = *pusPayloadMaxLen;\r
+    GU32 unSeparateDataOffset = *punSeparateDataOffset;\r
+    GU8 uchHeaderLength = 0;\r
+    //pack id\r
+    puchPayloadDest[GH_PAYLOAD_PACKHEADER_OFFSET_PACKID] = pstPackInfo->uchPackID;\r
+    uchHeaderLength++;\r
+    //pack flag\r
+    puchPayloadDest[GH_PAYLOAD_PACKHEADER_OFFSET_FLAG] = pstPackInfo->uchFlag;\r
+    uchHeaderLength++;\r
+    //byte type\r
+    if (GH3X2X_CHECK_LEFT_BIT_SET(pstPackInfo->uchFlag, GH_PACK_FLAG_BYTETYPE))\r
+    {\r
+        puchPayloadDest[GH_PAYLOAD_PACKHEADER_OFFSET_BYTETYPE] = pstPackInfo->uchByteType;\r
+        uchHeaderLength++;\r
+    }\r
+    //data num\r
+    if (GH3X2X_CHECK_LEFT_BIT_SET(pstPackInfo->uchFlag, GH_PACK_FLAG_DATANUM))\r
+    {\r
+        puchPayloadDest[GH_PAYLOAD_PACKHEADER_OFFSET_DATANUM] = pstPackInfo->uchDataNum;\r
+        uchHeaderLength++;\r
+    }\r
+    if (uchHeaderLength >= usPayloadMaxLen)\r
+    {\r
+        SET_VAL_VIA_PTR(pusPayloadMaxLen, usPayloadMaxLen);\r
+        SET_VAL_VIA_PTR(punSeparateDataOffset, unSeparateDataOffset);\r
+        return GH_PAYLOAD_HANDLE_PAYLOADFULL;\r
+    }\r
+    usPayloadMaxLen -= uchHeaderLength;\r
+    GU16 usDataLength = pstPackInfo->uchByteType * pstPackInfo->uchDataNum;\r
+    if ((usPayloadMaxLen >= usDataLength) && (unSeparateDataOffset == 0))\r
+    {\r
+        GH3X2X_Memcpy((puchPayloadDest + uchHeaderLength),\r
+                pstPackInfo->pSrc,\r
+                usDataLength);\r
+        usPayloadMaxLen -= usDataLength;\r
+        SET_VAL_VIA_PTR(pusPayloadMaxLen, usPayloadMaxLen);\r
+        SET_VAL_VIA_PTR(punSeparateDataOffset, unSeparateDataOffset);\r
+        return GH_PAYLOAD_HANDLE_CONTINUE;\r
+    }\r
+    else\r
+    {\r
+        if (uchSeparateFlag)\r
+        {\r
+            GU16 usCpyLength = 0;\r
+            usCpyLength = (usDataLength - unSeparateDataOffset) > usPayloadMaxLen ? usPayloadMaxLen : (usDataLength - unSeparateDataOffset);\r
+            GH3X2X_Memcpy((puchPayloadDest + uchHeaderLength),\r
+                    &(((GU8*)pstPackInfo->pSrc)[unSeparateDataOffset]),\r
+                    usCpyLength);\r
+            unSeparateDataOffset += usCpyLength;\r
+            usPayloadMaxLen -= usCpyLength;\r
+            if (unSeparateDataOffset == usDataLength)\r
+            {\r
+                unSeparateDataOffset = 0;\r
+                SET_VAL_VIA_PTR(pusPayloadMaxLen, usPayloadMaxLen);\r
+                SET_VAL_VIA_PTR(punSeparateDataOffset, unSeparateDataOffset);\r
+                return GH_PAYLOAD_HANDLE_CONTINUE;\r
+            }\r
+        }\r
+        SET_VAL_VIA_PTR(pusPayloadMaxLen, usPayloadMaxLen);\r
+        SET_VAL_VIA_PTR(punSeparateDataOffset, unSeparateDataOffset);\r
+        return GH_PAYLOAD_HANDLE_PAYLOADFULL;\r
+    }\r
+}\r
+\r
+EMPayloadHandleRet GH3X2X_ProtocolPayloadHandle(EMProtocolSendMode emSendMode,\r
+                                                EMProtocolSendHandle emSendHandle,\r
+                                                GU8 uchFunctionID,\r
+                                                GU8 uchFrameID,\r
+                                                STProtocolPackInfo *pstPackInfo,\r
+                                                GU8 uchPackNum)\r
+{\r
+    if (g_uchPayloadHandleInitFlag != 1)\r
+    {\r
+        return GH_PAYLOAD_HANDLE_NOINIT;\r
+    }\r
+\r
+    static GU8 uchSeparateID = 0;\r
+\r
+    GU8 uchSeparateFlag = 0;\r
+    GU8 uchPackCnt = 0;\r
+    GU8 uchPackCntRecord = 0;\r
+    GU8 uchSeparateStatus = 1;\r
+    GU8 uchFrameHeaderLength = 0;\r
+    GU32 unPackSrcByteRecord = 0;\r
+    GU32 unAllPackByteNum = 0;\r
+    EMPayloadHandleRet emRet = GH_PAYLOAD_HANDLE_CONTINUE;\r
+    EMPayloadHandleProcess emHandleFlag = GH_PAYLOAD_HANDLE_FULL_HEADER;\r
+\r
+    //check all packs\r
+    for (GU8 PackCnt = 0; PackCnt < uchPackNum;  PackCnt++)\r
+    {\r
+        emRet = GH3X2X_ProtocolPackCheck(&pstPackInfo[PackCnt]);\r
+        if (emRet)\r
+        {\r
+            GH3X2X_DEBUG_LOG_PARAM("[%s]:pack %d is err, ret = %d\r\n", __FUNCTION__, uchPackCnt, (int)emRet);\r
+            return emRet;\r
+        }\r
+        STProtocolPackInfo* pstPackInfoTemp = &pstPackInfo[PackCnt];\r
+        GU8 uchPackHeaderLength = 2 + \\r
+            (GH3X2X_CHECK_LEFT_BIT_SET(pstPackInfoTemp->uchFlag, GH_PACK_FLAG_BYTETYPE)) + \\r
+            (GH3X2X_CHECK_LEFT_BIT_SET(pstPackInfoTemp->uchFlag, GH_PACK_FLAG_DATANUM));\r
+        unAllPackByteNum += (pstPackInfoTemp->uchByteType * pstPackInfoTemp->uchDataNum + uchPackHeaderLength);\r
+    }\r
+\r
+    //pack\r
+    while(emHandleFlag != GH_PAYLOAD_HANDLE_OVER)\r
+    {\r
+        switch (emHandleFlag)\r
+        {\r
+        case GH_PAYLOAD_HANDLE_FULL_HEADER://full header\r
+            //flag\r
+            g_puchPayloadBuffer[GH_PAYLOADHEADER_OFFSET_FLAG] = 0;\r
+            g_usPayloadBufferOffset--;\r
+            //frame id\r
+            if (emSendMode != GH_PROTOCOL_SENDMODE_FAST)\r
+            {\r
+                g_puchPayloadBuffer[GH_PAYLOADHEADER_OFFSET_FLAG] |= ((0x1) << GH_PAYLOAD_FLAG_SEND_MODE);\r
+                g_puchPayloadBuffer[GH_PAYLOADHEADER_OFFSET_FUNCID] = uchFunctionID;\r
+                g_usPayloadBufferOffset--;\r
+            }\r
+            //check size\r
+            uchFrameHeaderLength = 2;\r
+            //separate flag\r
+            uchSeparateFlag = (unAllPackByteNum + uchFrameHeaderLength > g_usPayloadBufferOffset);\r
+            //separate payload id\r
+            if (uchSeparateFlag)\r
+            {\r
+                g_puchPayloadBuffer[GH_PAYLOADHEADER_OFFSET_FLAG] |= (0x1 << GH_PAYLOAD_FLAG_SEPARATE_ENABLE);\r
+                g_puchPayloadBuffer[GH_PAYLOADHEADER_OFFSET_FLAG] |= (uchSeparateStatus << GH_PAYLOAD_FLAG_SEPARATE_STATUS);\r
+                uchSeparateStatus = 0;\r
+                g_puchPayloadBuffer[g_usPayloadBufferLength - g_usPayloadBufferOffset] = uchSeparateID;\r
+                uchSeparateID++;\r
+                g_usPayloadBufferOffset--;\r
+            }\r
+            emHandleFlag = GH_PAYLOAD_HANDLE_FULL_DATA;\r
+            break;\r
+        case GH_PAYLOAD_HANDLE_FULL_DATA://full data\r
+            //frame id\r
+            if (emSendMode != GH_PROTOCOL_SENDMODE_FAST)\r
+            {\r
+                g_puchPayloadBuffer[g_usPayloadBufferLength - g_usPayloadBufferOffset] = uchFrameID;\r
+                g_usPayloadBufferOffset--;\r
+            }\r
+            g_puchPayloadBuffer[g_usPayloadBufferLength - g_usPayloadBufferOffset] = uchPackNum;\r
+            g_usPayloadBufferOffset--;\r
+            //pack pack\r
+            for (uchPackCnt = uchPackCntRecord; uchPackCnt < uchPackNum;  uchPackCnt++)\r
+            {\r
+                emRet = GH3X2X_ProtocolPackHandle(&pstPackInfo[uchPackCnt],\r
+                                                  &g_puchPayloadBuffer[g_usPayloadBufferLength - g_usPayloadBufferOffset],\r
+                                                  &g_usPayloadBufferOffset,\r
+                                                  uchSeparateFlag,\r
+                                                  &unPackSrcByteRecord);\r
+                if (emRet == GH_PAYLOAD_HANDLE_PAYLOADFULL)\r
+                {\r
+                    if (uchSeparateFlag)\r
+                    {\r
+                        uchPackCntRecord = uchPackCnt;\r
+                    }\r
+                    HOOK_FUNC_CALL(g_pGh3x2xProtocolSendFunc, (g_uchProtocolCmd, g_puchPayloadBuffer, g_usPayloadBufferLength - g_usPayloadBufferOffset));\r
+                    g_usPayloadBufferOffset = g_usPayloadBufferLength;\r
+                    emHandleFlag = GH_PAYLOAD_HANDLE_FULL_HEADER;\r
+                    break;\r
+                }\r
+            }\r
+            if (uchPackCnt == uchPackNum)\r
+            {\r
+                if (emSendMode != GH_PROTOCOL_SENDMODE_FRAME || (unAllPackByteNum + uchFrameHeaderLength > g_usPayloadBufferOffset))\r
+                {\r
+                    uchSeparateStatus = 2;\r
+                    g_puchPayloadBuffer[GH_PAYLOADHEADER_OFFSET_FLAG] |= (uchSeparateStatus << GH_PAYLOAD_FLAG_SEPARATE_STATUS);\r
+                    if (emRet == GH_PAYLOAD_HANDLE_CONTINUE)\r
+                    {\r
+                        HOOK_FUNC_CALL(g_pGh3x2xProtocolSendFunc, (g_uchProtocolCmd, g_puchPayloadBuffer, g_usPayloadBufferLength - g_usPayloadBufferOffset));\r
+                        g_usPayloadBufferOffset = g_usPayloadBufferLength;\r
+                    }\r
+                    uchSeparateStatus = 0;\r
+                    uchPackCntRecord = 0;\r
+                    uchSeparateID = 0;\r
+                    emHandleFlag = GH_PAYLOAD_HANDLE_OVER;\r
+                }\r
+            }\r
+            break;\r
+        default:\r
+            break;\r
+        }\r
+    }\r
+    return GH_PAYLOAD_HANDLE_CONTINUE;\r
+}\r
+\r
+GU8 malloc_flag = 0;\r
+\r
+EMPacyloadLostRet GH3X2X_PacketLossCheck(GU8 uchSeparateStatusRecord,\r
+                                         GU8 uchSeparateStatus,\r
+                                         GU8 uchSeparateIDRecord,\r
+                                         GU8 uchSeparateID, \r
+                                         GU8 uchFrameIDRecord,\r
+                                         GU8 uchFrameID)\r
+{\r
+    if (uchFrameID == 0 && uchSeparateID == 0 && uchFrameIDRecord == 0 && uchSeparateIDRecord == 0)\r
+    {\r
+        return GH_PAYLOAD_LOST_NOLOST;\r
+    }\r
+    if ((uchFrameID != uchFrameIDRecord && uchSeparateStatusRecord == 2 && uchSeparateStatus != 1)||\r
+        (uchFrameID == uchFrameIDRecord && uchSeparateStatusRecord == 2))\r
+    {\r
+        GH3X2X_DEBUG_LOG_PARAM("GH_PAYLOAD_LOST_PREVIOUS_LOST\n");\r
+        return GH_PAYLOAD_LOST_PREVIOUS_LOST;\r
+    }\r
+    if (uchFrameID != uchFrameIDRecord && uchSeparateStatusRecord == 1 && (uchSeparateID != uchSeparateIDRecord + 1 || uchSeparateStatus == 1))\r
+    {\r
+        GH3X2X_DEBUG_LOG_PARAM("GH_PAYLOAD_LOST_LAST_LOST\n");\r
+        return GH_PAYLOAD_LOST_LAST_LOST;\r
+    }\r
+    if (uchFrameID == uchFrameIDRecord && uchSeparateID != uchSeparateIDRecord + 1)\r
+    {\r
+        GH3X2X_DEBUG_LOG_PARAM("GH_PAYLOAD_LOST_MID_LOST\n");\r
+        return GH_PAYLOAD_LOST_MID_LOST;\r
+    }\r
+    if (uchFrameID != uchFrameIDRecord && uchSeparateStatusRecord != 2 && uchSeparateStatus != 1)\r
+    {\r
+        GH3X2X_DEBUG_LOG_PARAM("GH_PAYLOAD_LOST_DOUBLE_LOST\n");\r
+        return GH_PAYLOAD_LOST_DOUBLE_LOST;\r
+    }\r
+    return GH_PAYLOAD_LOST_NOLOST;\r
+}\r
+\r
+void GH3X2X_MallocPackStruct(GU8 uchPackNum,  GU8* puchPackCntRecord, STProtocolPackInfo*** pstPackInfo, GU8** puchPackMallocFlag)\r
+{\r
+    *puchPackCntRecord = 0;\r
+    *pstPackInfo = GH3X2X_UserMalloc(uchPackNum * sizeof(STProtocolPackInfo*));\r
+    GH3X2X_Memset(*pstPackInfo, 0, uchPackNum * sizeof(STProtocolPackInfo*));\r
+    *puchPackMallocFlag = GH3X2X_UserMalloc(uchPackNum * sizeof(GU8));\r
+    GH3X2X_Memset(*puchPackMallocFlag, 0, uchPackNum * sizeof(GU8));\r
+    for (GU8 uchPackCnt = 0; uchPackCnt < uchPackNum; uchPackCnt++)\r
+    {\r
+        (*pstPackInfo)[uchPackCnt] = GH3X2X_UserMalloc(sizeof(STProtocolPackInfo));\r
+        GH3X2X_Memset((*pstPackInfo)[uchPackCnt], 0, sizeof(STProtocolPackInfo));\r
+    }\r
+}\r
+\r
+void GH3X2X_FreePackStruct(GU8 uchPackNum, GU8* puchPackCntRecord, STProtocolPackInfo*** pstPackInfo, GU8** puchPackMallocFlag)\r
+{\r
+    for (GS8 uchPackCnt = uchPackNum - 1; uchPackCnt >= 0; uchPackCnt--)\r
+    {\r
+\r
+        GH3X2X_UserFree((*pstPackInfo)[uchPackCnt]->pSrc);\r
+    }\r
+    for (GS8 uchPackCnt = uchPackNum - 1; uchPackCnt >= 0; uchPackCnt--)\r
+    {\r
+        GH3X2X_UserFree((*pstPackInfo)[uchPackCnt]);\r
+    }\r
+    GH3X2X_UserFree(*puchPackMallocFlag);\r
+    GH3X2X_UserFree(*pstPackInfo);\r
+    *pstPackInfo = GH3X2X_PTR_NULL;\r
+    *puchPackCntRecord = 0;\r
+}\r
+\r
+EMPayloadReceiveRet GH3X2X_ProtocolPayloadDecode(GU8 *puchPayloadBuffer,\r
+                                                 GU16 usPayloadLen)\r
+{\r
+    static GU8 uchPackCntRecord = 0;\r
+    static GU16 unPackSrcByteRecord = 0;\r
+    static GU8 *puchPackMallocFlag = 0;\r
+    static STProtocolPackInfo** pstPackInfo = GH3X2X_PTR_NULL;\r
+\r
+    static GU8 uchFrameIDRecord = 0;\r
+    static GU8 uchSeparateIDRecord = 0;\r
+    static GU8 uchSeparateStatusRecord = 2;\r
+    static EMPacyloadLostRet emLostRet = GH_PAYLOAD_LOST_NOLOST;\r
+\r
+    GU16 usPayloadOffset = 0;\r
+    GU8 uchSeparateID = 0;\r
+    GU8 uchPackNum = 0;\r
+    GU8 uchPackCnt = 0;\r
+    GU8 uchFunctionID = 0;\r
+    GU8 uchFrameID = 0;\r
+\r
+    GU8 uchPayloadFlag = puchPayloadBuffer[GH_PAYLOADHEADER_OFFSET_FLAG];\r
+    usPayloadOffset++;\r
+    GU8 uchSeparateFlag = GH3X2X_CHECK_LEFT_BIT_SET(uchPayloadFlag, GH_PAYLOAD_FLAG_SEPARATE_ENABLE);\r
+    GU8 uchSeparateStatus = GH3X2X_CHECK_LEFT_BIT_SET(uchPayloadFlag, GH_PAYLOAD_FLAG_SEPARATE_STATUS)| (GH3X2X_CHECK_LEFT_BIT_SET(uchPayloadFlag, GH_PAYLOAD_FLAG_SEPARATE_STATUS + 1) << 1);\r
+    EMProtocolSendMode emPayloadMode = (EMProtocolSendMode)GH3X2X_CHECK_LEFT_BIT_SET(uchPayloadFlag, GH_PAYLOAD_FLAG_SEND_MODE);\r
+\r
+    if (emPayloadMode != GH_PROTOCOL_SENDMODE_FAST)\r
+    {\r
+        uchFunctionID = puchPayloadBuffer[usPayloadOffset];\r
+        usPayloadOffset++;\r
+    }\r
+\r
+    if (uchSeparateFlag)\r
+    {\r
+        uchSeparateID = puchPayloadBuffer[usPayloadOffset];\r
+        usPayloadOffset++;\r
+    }\r
+\r
+    if (emPayloadMode != GH_PROTOCOL_SENDMODE_FAST)\r
+    {\r
+        uchFrameID = puchPayloadBuffer[usPayloadOffset];\r
+        usPayloadOffset++;\r
+    }\r
+\r
+    //check lost payload\r
+    if (uchSeparateFlag)\r
+    {\r
+        EMPayloadReceiveRet emRet = GH_PAYLOAD_HANDLE_FRAME_LOST_PAYLOAD;\r
+\r
+        if (uchSeparateID == 0)\r
+        {\r
+            emRet = GH_PAYLOAD_HANDLE_FRAME_NOT_FINISH;;\r
+        }\r
+\r
+        switch (emLostRet)\r
+        {\r
+        case GH_PAYLOAD_LOST_MID_LOST:\r
+        case GH_PAYLOAD_LOST_DOUBLE_LOST:\r
+        case GH_PAYLOAD_LOST_PREVIOUS_LOST:\r
+            break;\r
+        default:\r
+            emRet = GH_PAYLOAD_HANDLE_FRAME_NOT_FINISH;\r
+            break;\r
+        }\r
+\r
+        if (emRet == GH_PAYLOAD_HANDLE_FRAME_LOST_PAYLOAD)\r
+        {\r
+            return emRet;\r
+        }\r
+\r
+        emLostRet = GH3X2X_PacketLossCheck(uchSeparateStatusRecord,\r
+                                           uchSeparateStatus,\r
+                                           uchSeparateIDRecord,\r
+                                           uchSeparateID,\r
+                                           uchFrameIDRecord,\r
+                                           uchFrameID);\r
+\r
+        emRet = GH_PAYLOAD_HANDLE_FRAME_LOST_PAYLOAD;\r
+        switch (emLostRet)\r
+        {\r
+        case GH_PAYLOAD_LOST_LAST_LOST:\r
+            emRet = GH_PAYLOAD_HANDLE_FRAME_NOT_FINISH;\r
+        case GH_PAYLOAD_LOST_MID_LOST:\r
+        case GH_PAYLOAD_LOST_DOUBLE_LOST:\r
+            GH3X2X_FreePackStruct(uchPackNum, &uchPackCntRecord, &pstPackInfo, &puchPackMallocFlag);\r
+            if (malloc_flag == 1)\r
+            {\r
+                malloc_flag = 0;\r
+            }\r
+            unPackSrcByteRecord = 0;\r
+            break;\r
+        case GH_PAYLOAD_LOST_PREVIOUS_LOST:\r
+            break;\r
+        default:\r
+            emRet = GH_PAYLOAD_HANDLE_FRAME_NOT_FINISH;\r
+            break;\r
+        }\r
+\r
+        if (emRet == GH_PAYLOAD_HANDLE_FRAME_LOST_PAYLOAD)\r
+        {\r
+            return emRet;\r
+        }\r
+\r
+        uchSeparateStatusRecord = uchSeparateStatus;\r
+        uchFrameIDRecord = uchFrameID;\r
+        uchSeparateIDRecord = uchSeparateID;\r
+    }\r
+\r
+    uchPackNum = puchPayloadBuffer[usPayloadOffset];\r
+    \r
+    if ((uchSeparateFlag && uchSeparateStatus == 1) || (uchSeparateFlag == 0))\r
+    {\r
+        GH3X2X_MallocPackStruct(uchPackNum, &uchPackCntRecord, &pstPackInfo, &puchPackMallocFlag);\r
+        if (malloc_flag == 0)\r
+        {\r
+            malloc_flag = 1;\r
+        }\r
+    }\r
+\r
+    usPayloadOffset++;\r
+\r
+    for (uchPackCnt = uchPackCntRecord; uchPackCnt < uchPackNum; uchPackCnt++)\r
+    {\r
+        //pack id\r
+        pstPackInfo[uchPackCnt]->uchPackID = puchPayloadBuffer[usPayloadOffset];\r
+        usPayloadOffset++;\r
+        //pack flag\r
+        pstPackInfo[uchPackCnt]->uchFlag = puchPayloadBuffer[usPayloadOffset];\r
+        usPayloadOffset++;\r
+        //byte type\r
+        if (GH3X2X_CHECK_LEFT_BIT_SET(pstPackInfo[uchPackCnt]->uchFlag, GH_PACK_FLAG_BYTETYPE))\r
+        {\r
+            pstPackInfo[uchPackCnt]->uchByteType = puchPayloadBuffer[usPayloadOffset];\r
+            usPayloadOffset++;\r
+        }\r
+        //data num\r
+        if (GH3X2X_CHECK_LEFT_BIT_SET(pstPackInfo[uchPackCnt]->uchFlag, GH_PACK_FLAG_DATANUM))\r
+        {\r
+            pstPackInfo[uchPackCnt]->uchDataNum = puchPayloadBuffer[usPayloadOffset];\r
+            usPayloadOffset++;\r
+        }\r
+        if (puchPackMallocFlag[uchPackCnt] == 0)\r
+        {\r
+            pstPackInfo[uchPackCnt]->pSrc = GH3X2X_UserMalloc(pstPackInfo[uchPackCnt]->uchByteType * pstPackInfo[uchPackCnt]->uchDataNum);\r
+            GH3X2X_Memset(pstPackInfo[uchPackCnt]->pSrc, 0, pstPackInfo[uchPackCnt]->uchByteType * pstPackInfo[uchPackCnt]->uchDataNum);\r
+            puchPackMallocFlag[uchPackCnt] = 1;\r
+        }\r
+        //src\r
+        GU16 usCpyLength = 0;\r
+        usCpyLength = ((pstPackInfo[uchPackCnt]->uchByteType * pstPackInfo[uchPackCnt]->uchDataNum - unPackSrcByteRecord) > (usPayloadLen - usPayloadOffset)\\r
+                        ? (usPayloadLen - usPayloadOffset) : (pstPackInfo[uchPackCnt]->uchByteType * pstPackInfo[uchPackCnt]->uchDataNum - unPackSrcByteRecord));\r
+        GH3X2X_Memcpy(&(((GU8*)pstPackInfo[uchPackCnt]->pSrc)[unPackSrcByteRecord]), &puchPayloadBuffer[usPayloadOffset], usCpyLength);\r
+        unPackSrcByteRecord += usCpyLength;\r
+        usPayloadOffset += usCpyLength;\r
+        uchPackCntRecord = uchPackCnt;\r
+        if (pstPackInfo[uchPackCnt]->uchByteType * pstPackInfo[uchPackCnt]->uchDataNum == unPackSrcByteRecord)\r
+        {\r
+            if (usPayloadOffset == usPayloadLen)\r
+            {\r
+                uchPackCntRecord++;\r
+            }\r
+            unPackSrcByteRecord = 0;\r
+        }        \r
+        if (pstPackInfo[uchPackCnt]->uchByteType * pstPackInfo[uchPackCnt]->uchDataNum == (usPayloadLen - usPayloadOffset))\r
+        {\r
+            uchPackCntRecord++;\r
+        }\r
+        if (usPayloadOffset == usPayloadLen)\r
+        {\r
+            break;\r
+        }\r
+    }\r
+    if (uchPackCnt == uchPackNum || (unPackSrcByteRecord == 0 && uchPackCnt == (uchPackNum - 1)))\r
+    {\r
+        HOOK_FUNC_CALL(g_pGh3x2xProtocolFrameDataOutputFunc, (&uchFunctionID, &uchFrameID, pstPackInfo, &uchPackNum));\r
+        GH3X2X_FreePackStruct(uchPackNum, &uchPackCntRecord, &pstPackInfo, &puchPackMallocFlag);\r
+        uchSeparateStatusRecord = 2;\r
+        uchFrameIDRecord = 0;\r
+        uchSeparateIDRecord = 0;\r
+        unPackSrcByteRecord = 0;\r
+        if (malloc_flag == 1)\r
+        {\r
+            malloc_flag = 0;\r
+        }\r
+        return GH_PAYLOAD_HANDLE_FRAME_FINISH;\r
+    }\r
+    return GH_PAYLOAD_HANDLE_FRAME_NOT_FINISH;\r
+}\r
+\r
+\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/module/gh_protocol/gh_datatrans.h b/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/module/gh_protocol/gh_datatrans.h
new file mode 100644 (file)
index 0000000..0db9f4f
--- /dev/null
@@ -0,0 +1,154 @@
+/**\r
+ * @copyright (c) 2003 - 2022, Goodix Co., Ltd. All rights reserved.\r
+ *\r
+ * @file    gh3x2x_drv_dump.h\r
+ *\r
+ * @brief   gh3x2x data transform\r
+ *\r
+ * @version ref gh3x2x_drv_datatrans.h\r
+ *\r
+ */\r
+\r
+#ifndef _GH3X2X_DEMO_COMMUNICATE_H_\r
+#define _GH3X2X_DEMO_COMMUNICATE_H_\r
+\r
+#include "gh_drv.h"\r
+\r
+#define __PROTOCOL_PACK_ZIP_DISABLE__ (0)\r
+#define __PROTOCOL_PACK_ZIP_ENABLE__ (1)\r
+\r
+#define PROTOCOL_RET_NEED_TO_SEND (1)\r
+#define PROTOCOL_RET_CONTINUE (0)\r
+#define PROTOCOL_RET_BUFFER_FULL (-1)\r
+\r
+#define PAYLOAD_INFO_FLAG_OFFSET_FUNCID     (0)\r
+#define PAYLOAD_INFO_FLAG_OFFSET_FLAG       (1)\r
+#define PAYLOAD_INFO_FLAG_OFFSET_FRAMEID    (2)\r
+#define PAYLOAD_INFO_FLAG_OFFSET_PAYLOADID  (3)\r
+\r
+typedef enum\r
+{\r
+    GH_PROTOCOL_FUNCID_TOP_PACKTYPE_ID = 0,\r
+    GH_PROTOCOL_FUNCINFO_TOP_PACKTYPE_ID,\r
+    GH_PROTOCOL_CHNLMAP_TOP_PACKTYPE_ID,\r
+    GH_PROTOCOL_RAWDATA_FRAME_PACKTYPE_ID,\r
+    GH_PROTOCOL_AGC_INFO_FRAME_PACKTYPE_ID,\r
+    GH_PROTOCOL_AMB_DATA_FRAME_PACKTYPE_ID,\r
+    GH_PROTOCOL_FLAG_FRAME_PACKTYPE_ID,\r
+    GH_PROTOCOL_ALGO_RESULT_FRAME_PACKTYPE_ID,\r
+    GH_PROTOCOL_GS_FRAME_PACKTYPE_ID,\r
+    GH_PROTOCOL_CAP_FRAME_PACKTYPE_ID,\r
+    GH_PROTOCOL_TEMP_FRAME_PACKTYPE_ID,\r
+    GH_PROTOCOL_PACK_NUM_MAX,\r
+} EMProtocolPacktypeID;\r
+\r
+typedef enum\r
+{\r
+    GH_PROTOCOL_SENDMODE_FAST = 0,\r
+    GH_PROTOCOL_SENDMODE_FRAME = 1,\r
+    GH_PROTOCOL_SENDMODE_FRAME_FAST = 2,\r
+} EMProtocolSendMode;\r
+\r
+typedef enum\r
+{\r
+    GH_PROTOCOL_SENDHANDLE_FULLSEND = 0,\r
+    GH_PROTOCOL_SENDHANDLE_NOWSEND = 1,\r
+} EMProtocolSendHandle;\r
+\r
+typedef enum\r
+{\r
+    GH_PAYLOAD_HANDLE_CONTINUE = 0,\r
+    GH_PAYLOAD_HANDLE_PAYLOADFULL,\r
+    GH_PAYLOAD_HANDLE_NOINIT,\r
+    GH_PAYLOAD_HANDLE_DATAERR,\r
+    GH_PAYLOAD_HANDLE_ADDRNULL,\r
+} EMPayloadHandleRet;\r
+\r
+typedef enum\r
+{\r
+    GH_PAYLOAD_HANDLE_FRAME_NOT_FINISH = 0,\r
+    GH_PAYLOAD_HANDLE_FRAME_FINISH,\r
+    GH_PAYLOAD_HANDLE_FRAME_LOST_PAYLOAD,\r
+} EMPayloadReceiveRet;\r
+\r
+typedef enum\r
+{\r
+    GH_PAYLOAD_LOST_NOLOST = 0,\r
+    GH_PAYLOAD_LOST_PREVIOUS_LOST,\r
+    GH_PAYLOAD_LOST_LAST_LOST,\r
+    GH_PAYLOAD_LOST_MID_LOST,\r
+    GH_PAYLOAD_LOST_DOUBLE_LOST,\r
+} EMPacyloadLostRet;\r
+\r
+typedef enum\r
+{\r
+    GH_PAYLOAD_PACKHEADER_OFFSET_PACKID = 0,\r
+    GH_PAYLOAD_PACKHEADER_OFFSET_FLAG,\r
+    GH_PAYLOAD_PACKHEADER_OFFSET_BYTETYPE,\r
+    GH_PAYLOAD_PACKHEADER_OFFSET_DATANUM,\r
+} EMPackHeaderByteOffset;\r
+\r
+typedef enum\r
+{\r
+    GH_PACK_FLAG_FRAME_START = 0,\r
+    GH_PACK_FLAG_ZIP_FLAG,\r
+    GH_PACK_FLAG_ZIP_TYPE,\r
+    GH_PACK_FLAG_BYTETYPE,\r
+    GH_PACK_FLAG_DATANUM,\r
+} EMPackFlagBitOffset;\r
+\r
+typedef enum\r
+{\r
+    GH_PAYLOADHEADER_OFFSET_FLAG= 0,\r
+    GH_PAYLOADHEADER_OFFSET_FUNCID,\r
+    GH_PAYLOADHEADER_OFFSET_SEPARATEID,\r
+} EMPayloadHeaderByteOffset;\r
+\r
+typedef enum\r
+{\r
+    GH_PAYLOAD_FLAG_SEPARATE_ENABLE = 0,\r
+    GH_PAYLOAD_FLAG_SEPARATE_STATUS = 1,\r
+    GH_PAYLOAD_FLAG_SEND_MODE = 3,\r
+} EMPayloadFlagBitOffset;\r
+\r
+typedef enum\r
+{\r
+    GH_PAYLOAD_HANDLE_OVER = 0,\r
+    GH_PAYLOAD_HANDLE_FULL_HEADER,\r
+    GH_PAYLOAD_HANDLE_FULL_DATA,\r
+} EMPayloadHandleProcess;\r
+\r
+typedef struct\r
+{\r
+    GU8 uchPackID;\r
+    GU8 uchFlag;\r
+    GU8 uchByteType;\r
+    GU8 uchDataNum;\r
+    GU8 *pSrc;\r
+} STProtocolPackInfo;\r
+\r
+typedef void (*pfnSendProtocolDataFunc)(GU8 uchCmd, GU8* puchProtocolDataBuffer, GU16 usProtocolDataLen);\r
+typedef void (*pfnFrameDataOutputFunc)(GU8* puchFunctionID, GU8* puchFrameID, STProtocolPackInfo** pstReceivePackInfo, GU8* puchPackNum);\r
+\r
+EMPayloadHandleRet GH3X2X_ProtocolSectionInit(GU8 uchProtocolCmd,\r
+                                              GU8 *puchPayloadDataBuffer,\r
+                                              GU16 usPayloadDataBufferLength,\r
+                                              void (*pfnSendProtocolDataFunc)(GU8 uchCmd, GU8* puchBuffer, GU16 usLen),\r
+                                              void (*pfnFrameDataOutputFunc)(GU8* puchFunctionID,\r
+                                                                             GU8* puchFrameID,\r
+                                                                             STProtocolPackInfo** pstReceivePackInfo,\r
+                                                                             GU8* puchPackNum));\r
+\r
+EMPayloadHandleRet GH3X2X_ProtocolPayloadHandle(EMProtocolSendMode emSendMode,\r
+    EMProtocolSendHandle emSendHandle,\r
+    GU8 uchFunctionID,\r
+    GU8 uchFrameID,\r
+    STProtocolPackInfo* pstPackInfo,\r
+    GU8 uchPackNum);\r
+\r
+EMPayloadReceiveRet GH3X2X_ProtocolPayloadDecode(GU8 *puchPayloadBuffer,\r
+                                                 GU16 usPayloadLen);\r
+\r
+#endif /* _GH3X2X_DRV_DUMP_H_ */\r
+\r
+/********END OF FILE********* Copyright (c) 2003 - 2022, Goodix Co., Ltd. ********/\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/module/gh_protocol/gh_uprotocol.c b/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/module/gh_protocol/gh_uprotocol.c
new file mode 100644 (file)
index 0000000..640ea2d
--- /dev/null
@@ -0,0 +1,2067 @@
+/**\r
+ * @copyright (c) 2003 - 2022, Goodix Co., Ltd. All rights reserved.\r
+ *\r
+ * @file    gh3x2x_drv_uprotocol.c\r
+ *\r
+ * @brief   gh3x2x universal protocol functions\r
+ *\r
+ * @version ref gh3x2x_drv_version.h\r
+ *\r
+ */\r
+\r
+\r
+#include <stdio.h>\r
+#include "gh_drv_version.h"\r
+#include "gh_drv_common.h"\r
+#include "gh_drv.h"\r
+#include "gh_uprotocol.h"\r
+#include "gh_drv_interface.h"\r
+#include "gh_drv_control.h"\r
+#include "gh_drv_dump.h"\r
+#include "gh_agc.h"\r
+#include "gh_demo_config.h"\r
+\r
+/// packet payload\r
+//GU8 g_pstGh3x2xProtocolData->puchPacketPayloadArr[GH3X2X_UPROTOCOL_PAYLOAD_LEN_MAX] = {0};\r
+\r
+\r
+// Zipmode Tempdata\r
+#if 0\r
+STZipLastDataTemp g_stZipTempData;\r
+#endif\r
+\r
+\r
+#define GH3X2X_PROTOCOL_VERSION_STRING "Gh3x2x_Uprotocol_v0.4"\r
+extern GU8 g_uchFifoPackageID;\r
+extern GU8 g_uchFifoPackageMode;\r
+extern GU8 g_uchResetFromProtocolFlag;\r
+\r
+/// packet payload\r
+GU8 g_uchPacketPayloadIndex = 0;\r
+\r
+/// packet payload\r
+GU8 g_uchPacketPayloadLen = 0;\r
+\r
+/// packet payload\r
+GU8 g_uchPacketCmd = 0;\r
+\r
+/// packet crc8 val\r
+GU8 g_uchPacketCalcCrc8Val = GH3X2X_CRC8_CLEAR_VAL;\r
+\r
+/// packet payload\r
+EMUprotocolParseStatus g_emPacketParseStatus = UPROTOCOL_STATUS_IDLE;\r
+\r
+/// packet max len support\r
+GU8 g_uchPacketMaxLenSupport = GH3X2X_UPROTOCOL_PACKET_LEN_MAX;\r
+\r
+/// chip version string\r
+GCHAR  g_szChipVerString[GH3X2X_CHIP_VER_STR_LEN] = {0};\r
+\r
+/// get firmware version func ptr\r
+static pfnGetFirmwareVersion g_pGh3x2xGetFirmwareVersionFunc = GH3X2X_PTR_NULL;\r
+static pfnGetFirmwareVersion g_pGh3x2xGetDemoVersionFunc = GH3X2X_PTR_NULL;\r
+static pfnGetFirmwareVersion g_pGh3x2xGetBootloaderVersionFunc = GH3X2X_PTR_NULL;\r
+\r
+/// current data index in raw data buf\r
+GU16 g_usGh3x2xDataIndexInBuf = 0;\r
+\r
+GU8  g_uchGh3x2xUploadStatus = 0;\r
+GU8  g_uchGh3x2xUploadBufUse = 0;\r
+\r
+/// current data index in raw data buf of every channel\r
+GU16 g_usRawdataByteIndexArr[GH3X2X_CHANNEL_MAP_MAX_CH];\r
+\r
+/// current g sensor data index in g sensor data buf\r
+GF32 g_fGsDataIndexInBuf = 0;\r
+\r
+/// current algo result index\r
+GU16 g_usAlgoResIndex = 0;\r
+\r
+///frame id array\r
+//GU8 g_uchFrameIdArr[CHANNEL_MAP_ID_NUM] = {0};\r
+\r
+/// all function mode available\r
+GU32 g_unAllFuncMode = 0;\r
+\r
+/// already opened function mode\r
+GU32 g_unFuncModeOpened = 0;\r
+\r
+/// function mode will be closed or opened\r
+GU32 g_unTargetFuncMode = 0;\r
+\r
+/// LastIncompleteMark\r
+GU32 g_unLastIncompleteMark = 0;\r
+\r
+/// event need report\r
+GU16 g_usGh3x2xEventNeedReport = 0;\r
+\r
+/// event report id\r
+GU8 g_uchEventReportId = 0;\r
+\r
+/// received event report id\r
+GU8 g_uchEventReportIdReceive = UPROTOCOL_REPORT_EVENT_ID_INIT;\r
+\r
+/// crc8 table\r
+static const GU8 g_uchCrc8TabArr[] = \r
+{\r
+    0x00, 0x07, 0x0E, 0x09, 0x1C, 0x1B, 0x12, 0x15, 0x38, 0x3F, 0x36, 0x31, 0x24, 0x23, 0x2A, 0x2D,\r
+    0x70, 0x77, 0x7E, 0x79, 0x6C, 0x6B, 0x62, 0x65, 0x48, 0x4F, 0x46, 0x41, 0x54, 0x53, 0x5A, 0x5D,\r
+    0xE0, 0xE7, 0xEE, 0xE9, 0xFC, 0xFB, 0xF2, 0xF5, 0xD8, 0xDF, 0xD6, 0xD1, 0xC4, 0xC3, 0xCA, 0xCD,\r
+    0x90, 0x97, 0x9E, 0x99, 0x8C, 0x8B, 0x82, 0x85, 0xA8, 0xAF, 0xA6, 0xA1, 0xB4, 0xB3, 0xBA, 0xBD,\r
+    0xC7, 0xC0, 0xC9, 0xCE, 0xDB, 0xDC, 0xD5, 0xD2, 0xFF, 0xF8, 0xF1, 0xF6, 0xE3, 0xE4, 0xED, 0xEA,\r
+    0xB7, 0xB0, 0xB9, 0xBE, 0xAB, 0xAC, 0xA5, 0xA2, 0x8F, 0x88, 0x81, 0x86, 0x93, 0x94, 0x9D, 0x9A,\r
+    0x27, 0x20, 0x29, 0x2E, 0x3B, 0x3C, 0x35, 0x32, 0x1F, 0x18, 0x11, 0x16, 0x03, 0x04, 0x0D, 0x0A,\r
+    0x57, 0x50, 0x59, 0x5E, 0x4B, 0x4C, 0x45, 0x42, 0x6F, 0x68, 0x61, 0x66, 0x73, 0x74, 0x7D, 0x7A,\r
+    0x89, 0x8E, 0x87, 0x80, 0x95, 0x92, 0x9B, 0x9C, 0xB1, 0xB6, 0xBF, 0xB8, 0xAD, 0xAA, 0xA3, 0xA4,\r
+    0xF9, 0xFE, 0xF7, 0xF0, 0xE5, 0xE2, 0xEB, 0xEC, 0xC1, 0xC6, 0xCF, 0xC8, 0xDD, 0xDA, 0xD3, 0xD4,\r
+    0x69, 0x6E, 0x67, 0x60, 0x75, 0x72, 0x7B, 0x7C, 0x51, 0x56, 0x5F, 0x58, 0x4D, 0x4A, 0x43, 0x44,\r
+    0x19, 0x1E, 0x17, 0x10, 0x05, 0x02, 0x0B, 0x0C, 0x21, 0x26, 0x2F, 0x28, 0x3D, 0x3A, 0x33, 0x34,\r
+    0x4E, 0x49, 0x40, 0x47, 0x52, 0x55, 0x5C, 0x5B, 0x76, 0x71, 0x78, 0x7F, 0x6A, 0x6D, 0x64, 0x63,\r
+    0x3E, 0x39, 0x30, 0x37, 0x22, 0x25, 0x2C, 0x2B, 0x06, 0x01, 0x08, 0x0F, 0x1A, 0x1D, 0x14, 0x13,\r
+    0xAE, 0xA9, 0xA0, 0xA7, 0xB2, 0xB5, 0xBC, 0xBB, 0x96, 0x91, 0x98, 0x9F, 0x8A, 0x8D, 0x84, 0x83,\r
+    0xDE, 0xD9, 0xD0, 0xD7, 0xC2, 0xC5, 0xCC, 0xCB, 0xE6, 0xE1, 0xE8, 0xEF, 0xFA, 0xFD, 0xF4, 0xF3,\r
+};\r
+\r
+\r
+GCHAR *GH3X2X_GetProtocolVersion(void)\r
+{\r
+    return (GCHAR *)GH3X2X_PROTOCOL_VERSION_STRING;\r
+}\r
+\r
+\r
+/**\r
+ * @fn     GCHAR *GH3X2X_GetChipVersion(void)\r
+ *\r
+ * @brief  Get chip version, only for protocol, format like v11_ev01(11: chip id, 01 efuse ver)\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  chip version string\r
+ */\r
+GCHAR *GH3X2X_GetChipVersion(void)\r
+{\r
+    GU8 uchChipVer = 0;\r
+    GU8 uchEfuseVer = 0;\r
+\r
+    GH3X2X_CHIP_WAKEUP_NORET();\r
+    uchChipVer = GH3X2X_GET_LOW_BYTE_FROM_WORD(GH3X2X_ReadReg(GH3X2X_CHIP_ID_REG_ADDR));\r
+    uchEfuseVer = GH3X2X_GET_LOW_BYTE_FROM_WORD(GH3X2X_ReadReg(GH3X2X_EFUSE_CTRL_EFUSE0_AUTOLOAD_3_ADDR));\r
+    GH3X2X_CHIP_SLEEP_NORET();\r
+    \r
+    if(g_pSnprintfUserIn)\r
+    {\r
+        g_pSnprintfUserIn(g_szChipVerString, GH3X2X_CHIP_VER_STR_LEN, "v%.2x_ev%.2x\r\n", uchChipVer, uchEfuseVer);\r
+        return (GCHAR *)g_szChipVerString;\r
+    }\r
+    return "no snprintf";\r
+    \r
+}\r
+\r
+\r
+\r
+\r
+\r
+\r
+/**\r
+ * @fn     GU8  GH3X2X_CalcArrayCrc8Val(GU8 uchDataArr[], GU16 usDataIndex, GU16 usDataLen)\r
+ *\r
+ * @brief  Get crc8 data, only for protocol\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   uchDataArr      pointer to data array\r
+ * @param[in]   usDataIndex     data index need to calc crc8\r
+ * @param[in]   usDataLen       data len need to calc crc8\r
+ * @param[out]  None\r
+ *\r
+ * @return  crc8 value\r
+ */\r
+GU8  GH3X2X_CalcArrayCrc8Val(GU8 uchDataArr[], GU16 usDataIndex, GU16 usDataLen)\r
+{\r
+    GU8 uchCrc8TabIndex;\r
+    GU8 uchCrc8 = GH3X2X_CRC8_CLEAR_VAL;\r
+    GU16 usIndex = 0;\r
+    for (usIndex = usDataIndex; usIndex < usDataLen; usIndex++)\r
+    {\r
+        uchCrc8TabIndex = (uchCrc8 ^ (uchDataArr[GH3X2X_GET_LOW_BYTE_FROM_WORD(usIndex)])) & GH3X2X_CRC8_CLEAR_VAL;\r
+        uchCrc8 = g_uchCrc8TabArr[uchCrc8TabIndex];\r
+    }\r
+    return uchCrc8;\r
+}\r
+\r
+/**\r
+ * @fn     void  GH3X2X_CalcByteCrc8Val(GU8 *puchCrc8Val, GU8  uchNeedCalcByte)\r
+ *\r
+ * @brief  real time calc crc8 val, only for protocol,\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   uchNeedCalcByte      data need calc crc8\r
+ * @param[out]  puchCrc8Val          pointer to crc8 output & last val input\r
+ *\r
+ * @return  crc8 value\r
+ */\r
+void  GH3X2X_CalcByteCrc8Val(GU8 *puchCrc8Val, GU8  uchNeedCalcByte)\r
+{\r
+    GU8 uchCrc8TabIndex;\r
+    uchCrc8TabIndex = ((*puchCrc8Val) ^  uchNeedCalcByte) & GH3X2X_CRC8_CLEAR_VAL;\r
+    SET_VAL_VIA_PTR(puchCrc8Val, g_uchCrc8TabArr[uchCrc8TabIndex]);\r
+}\r
+\r
+/**\r
+ * @fn     static GU8 GH3X2X_UprotocolParseBuffer(GU16 *pusHasParseLen, GU8 uchRecvDataBufferArr[], GU16 usDataLen)\r
+ *\r
+ * @brief  parse recv buffer data\r
+ *\r
+ * @attention   only support parse 1 cmd\r
+ *\r
+ * @param[in]   uchRecvDataBufferArr    pointer to data array\r
+ * @param[in]   usDataLen               data length\r
+ * @param[out]  pusHasParseLen           pointer to has parse len of buffer\r
+ *\r
+ * @return  got cmd or not\r
+ * @retval  #GH3X2X_RET_GENERIC_ERROR   no cmd has parse done\r
+ * @retval  #GH3X2X_RET_OK              a cmd has parse done\r
+ */\r
+static GS8 GH3X2X_UprotocolParseBuffer(GU16 *pusHasParseLen, GU8 uchRecvDataBufferArr[], GU16 usDataLen)\r
+{\r
+    GU16 usIndex  = 0;\r
+    GS8 chRet = GH3X2X_RET_GENERIC_ERROR;\r
+\r
+    GH3X2X_DEBUG_LOG_PARAM("%s\r\n", __FUNCTION__);\r
+    for (usIndex = 0; usIndex < usDataLen; usIndex++)\r
+    {\r
+        switch (g_emPacketParseStatus)\r
+        {\r
+        case UPROTOCOL_STATUS_IDLE:\r
+            if (uchRecvDataBufferArr[usIndex] == GH3X2X_UPROTOCOL_FIXED_HEADER)\r
+            {\r
+                GH3X2X_CalcByteCrc8Val(&g_uchPacketCalcCrc8Val, uchRecvDataBufferArr[usIndex]);\r
+                g_emPacketParseStatus = UPROTOCOL_STATUS_GOT_FIXED;\r
+            }\r
+            break;\r
+\r
+        case UPROTOCOL_STATUS_GOT_FIXED:\r
+            if (uchRecvDataBufferArr[usIndex] == GH3X2X_UPROTOCOL_VERSION)\r
+            {\r
+                GH3X2X_CalcByteCrc8Val(&g_uchPacketCalcCrc8Val, uchRecvDataBufferArr[usIndex]);\r
+                g_emPacketParseStatus = UPROTOCOL_STATUS_GOT_VER;\r
+            }\r
+            else\r
+            {\r
+                GH3X2X_CRC8_VAL_CLEAR(g_uchPacketCalcCrc8Val);\r
+                g_emPacketParseStatus = UPROTOCOL_STATUS_IDLE;\r
+            }\r
+            break;\r
+\r
+        case UPROTOCOL_STATUS_GOT_VER:\r
+            g_uchPacketCmd = uchRecvDataBufferArr[usIndex];\r
+            GH3X2X_CalcByteCrc8Val(&g_uchPacketCalcCrc8Val, uchRecvDataBufferArr[usIndex]);\r
+            g_emPacketParseStatus = UPROTOCOL_STATUS_GOT_CMD;\r
+            break;\r
+\r
+        case UPROTOCOL_STATUS_GOT_CMD:\r
+            g_uchPacketPayloadIndex = 0;\r
+            if (uchRecvDataBufferArr[usIndex] == 0)\r
+            {\r
+                g_uchPacketPayloadLen = 0;\r
+                GH3X2X_CalcByteCrc8Val(&g_uchPacketCalcCrc8Val, uchRecvDataBufferArr[usIndex]);\r
+                g_emPacketParseStatus = UPROTOCOL_STATUS_GOT_PAYLOAD; // if payload len equl 0, goto verify crc8\r
+            }\r
+            else if (uchRecvDataBufferArr[usIndex] <= GH3X2X_UPROTOCOL_PAYLOAD_LEN_MAX)\r
+            {\r
+                g_uchPacketPayloadLen = uchRecvDataBufferArr[usIndex];\r
+                GH3X2X_CalcByteCrc8Val(&g_uchPacketCalcCrc8Val, uchRecvDataBufferArr[usIndex]);\r
+                g_emPacketParseStatus = UPROTOCOL_STATUS_GOT_LEN;\r
+            }\r
+            else\r
+            {\r
+                GH3X2X_CRC8_VAL_CLEAR(g_uchPacketCalcCrc8Val);\r
+                g_emPacketParseStatus = UPROTOCOL_STATUS_IDLE;\r
+            }\r
+            break;\r
+\r
+        case UPROTOCOL_STATUS_GOT_LEN:\r
+            g_pstGh3x2xProtocolData->puchPacketPayloadArr[g_uchPacketPayloadIndex] = uchRecvDataBufferArr[usIndex];\r
+            g_uchPacketPayloadIndex++;\r
+            GH3X2X_CalcByteCrc8Val(&g_uchPacketCalcCrc8Val, uchRecvDataBufferArr[usIndex]);\r
+            if (g_uchPacketPayloadIndex >= g_uchPacketPayloadLen)\r
+            {\r
+                g_emPacketParseStatus = UPROTOCOL_STATUS_GOT_PAYLOAD;\r
+            }\r
+            break;\r
+\r
+        case UPROTOCOL_STATUS_GOT_PAYLOAD:\r
+            if (uchRecvDataBufferArr[usIndex] == g_uchPacketCalcCrc8Val)\r
+            {\r
+                chRet = GH3X2X_RET_OK;\r
+            }\r
+            GH3X2X_CRC8_VAL_CLEAR(g_uchPacketCalcCrc8Val);\r
+            g_emPacketParseStatus = UPROTOCOL_STATUS_IDLE;\r
+            break;\r
+\r
+        default:\r
+            GH3X2X_CRC8_VAL_CLEAR(g_uchPacketCalcCrc8Val);\r
+            g_emPacketParseStatus = UPROTOCOL_STATUS_IDLE;\r
+            GH3X2X_DEBUG_LOG_PARAM("goto default error, crc8:0x%x\r\n", g_uchPacketCalcCrc8Val);\r
+            break;\r
+        } // end switch (stParseStatus.ParseState)\r
+\r
+        /* if parse cmd done, break */\r
+        if (chRet == GH3X2X_RET_OK)\r
+        {\r
+            break;\r
+        }\r
+    } // end for (usIndex = 0; usIndex < usDataLen; usIndex++)\r
+\r
+    SET_VAL_VIA_PTR(pusHasParseLen, (GU16)(usIndex + 1)); // set has parse length\r
+\r
+    return chRet;\r
+}\r
+\r
+/**\r
+ * @fn     GU8 GH3X2X_UprotocolPacketFormat(GU8 uchCmd, GU8 *puchPacketBuffer,\r
+ *                                          GU8 *puchPayloadData, GU8 uchPayloadDataLen)\r
+ *\r
+ * @brief  universal protocol format packet\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[out]   puchPacketBuffer    pointer to respond packet buffer\r
+ * @param[in]    uchCmd              cmd id\r
+ * @param[in]    puchPayloadData     pointer to payload buffer\r
+ * @param[in]    uchPayloadDataLen   payload len\r
+ *\r
+ * @return  len after make packet\r
+ */\r
+GU8 GH3X2X_UprotocolPacketFormat(GU8 uchCmd, GU8 *puchPacketBuffer, GU8 *puchPayloadData, GU8 uchPayloadDataLen)\r
+{\r
+    GU8 uchPacketIndex = 0;\r
+    GU8 uchPacketPayloadRealLen = GH3X2X_UPROTOCOL_GET_PAYLOAD_LEN_SUPPORT(g_uchPacketMaxLenSupport);\r
+\r
+    /* fixed real len */\r
+    if (uchPacketPayloadRealLen > uchPayloadDataLen)\r
+    {\r
+        uchPacketPayloadRealLen = uchPayloadDataLen;\r
+    }\r
+\r
+    puchPacketBuffer[GH3X2X_UPROTOCOL_PACKET_FIXED_INDEX] = GH3X2X_UPROTOCOL_FIXED_HEADER;\r
+    puchPacketBuffer[GH3X2X_UPROTOCOL_PACKET_VER_INDEX]   = GH3X2X_UPROTOCOL_VERSION;\r
+    puchPacketBuffer[GH3X2X_UPROTOCOL_PACKET_CMD_INDEX]   = uchCmd;\r
+    puchPacketBuffer[GH3X2X_UPROTOCOL_PACKET_LEN_INDEX]   = uchPacketPayloadRealLen;\r
+    uchPacketIndex += GH3X2X_UPROTOCOL_PACKET_HEADER_LEN;\r
+    if (uchPacketPayloadRealLen != 0)\r
+    {\r
+        GH3X2X_Memcpy(&puchPacketBuffer[uchPacketIndex], puchPayloadData, uchPacketPayloadRealLen);\r
+        uchPacketIndex += uchPacketPayloadRealLen;\r
+    }\r
+    puchPacketBuffer[uchPacketIndex] = GH3X2X_CalcArrayCrc8Val(puchPacketBuffer, 0,\r
+                                uchPacketPayloadRealLen + GH3X2X_UPROTOCOL_PACKET_HEADER_LEN);\r
+    uchPacketIndex++;\r
+\r
+    return (uchPacketIndex);\r
+}\r
+\r
+/**\r
+ * @fn     static void GH3X2X_UprotocolHandleRegRwCmd(GU8 *puchRespondBuffer, GU16 *pusRespondLen)\r
+ *\r
+ * @brief  handle reg rw cmd\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]    None\r
+ * @param[out]   puchRespondBuffer    pointer to respond buffer\r
+ * @param[out]   pusRespondLen        pointer to respond length\r
+ *\r
+ * @return  None\r
+ */\r
+static void GH3X2X_UprotocolHandleRegRwCmd(GU8 *puchRespondBuffer, GU16 *pusRespondLen)\r
+{\r
+    if (g_uchPacketPayloadLen >= UPROTOCOL_REG_RW_HEADER_LENGTH)\r
+    {\r
+        GU8 uchIndex;\r
+        GU16 usRegDataTmp = 0;\r
+        GU8 uchRegRwMode =  g_pstGh3x2xProtocolData->puchPacketPayloadArr[UPROTOCOL_REG_RW_MODE_INDEX];\r
+        GU8 uchRegRwLen =  g_pstGh3x2xProtocolData->puchPacketPayloadArr[UPROTOCOL_REG_RW_CNT_INDEX];\r
+        GU16 usRegAddr = GH3X2X_MAKEUP_WORD(g_pstGh3x2xProtocolData->puchPacketPayloadArr[UPROTOCOL_REG_RW_ADDR_H_INDEX],\r
+                                            g_pstGh3x2xProtocolData->puchPacketPayloadArr[UPROTOCOL_REG_RW_ADDR_L_INDEX]);\r
+\r
+        if (uchRegRwMode ==  UPROTOCOL_REG_RW_WRITE_MODE)\r
+        {\r
+            if ((uchRegRwLen > 0)\r
+                && ((uchRegRwLen * GH3X2X_REG_ADDR_SIZE) == (g_uchPacketPayloadLen - UPROTOCOL_REG_RW_HEADER_LENGTH)))\r
+            {\r
+                switch (GH3X2X_GET_BIT_IS_SET(usRegAddr))\r
+                {\r
+                case GH3X2X_REG_IS_VIRTUAL0X0_BIT:\r
+                    GH3X2X_CHIP_WAKEUP_PROTOCOL();\r
+                    for (uchIndex = 0; uchIndex < uchRegRwLen; uchIndex++)\r
+                    {\r
+                        usRegDataTmp = \\r
+                            GH3X2X_MAKEUP_WORD(g_pstGh3x2xProtocolData->puchPacketPayloadArr[UPROTOCOL_REG_RW_DATA_INDEX \\r
+                                                                    + (uchIndex * GH3X2X_REG_ADDR_SIZE)],\r
+                                            g_pstGh3x2xProtocolData->puchPacketPayloadArr[UPROTOCOL_REG_RW_DATA_INDEX + 1 \\r
+                                                                    + (uchIndex * GH3X2X_REG_ADDR_SIZE)]);\r
+                        GH3X2X_WriteReg(GH3X2X_GET_REG_REAL_ADRR(usRegAddr + (uchIndex * GH3X2X_REG_ADDR_SIZE)), \\r
+                                        usRegDataTmp);\r
+                        GU16 usReadRegVal = GH3X2X_ReadReg(GH3X2X_GET_REG_REAL_ADRR(usRegAddr + (uchIndex * GH3X2X_REG_ADDR_SIZE)));\r
+                        if (usReadRegVal != usRegDataTmp)\r
+                        {\r
+                                GH3X2X_DEBUG_LOG_PARAM("reg verify error! addr:0x%.4x,w_val:0x%.4x,r_val:0x%.4x\r\n",\r
+                                                                                GH3X2X_GET_REG_REAL_ADRR(usRegAddr + (uchIndex * GH3X2X_REG_ADDR_SIZE)),\r
+                                                                                usRegDataTmp, usReadRegVal);\r
+                        }\r
+                    }\r
+                    GH3X2X_CHIP_SLEEP_PROTOCOL();\r
+                    break;                \r
+                default:\r
+                    for (uchIndex = 0; uchIndex < uchRegRwLen; uchIndex++)\r
+                    {\r
+                        usRegDataTmp = \\r
+                            GH3X2X_MAKEUP_WORD(g_pstGh3x2xProtocolData->puchPacketPayloadArr[UPROTOCOL_REG_RW_DATA_INDEX \\r
+                                                                    + (uchIndex * GH3X2X_REG_ADDR_SIZE)],\r
+                                            g_pstGh3x2xProtocolData->puchPacketPayloadArr[UPROTOCOL_REG_RW_DATA_INDEX + 1 \\r
+                                                                    + (uchIndex * GH3X2X_REG_ADDR_SIZE)]);\r
+                        GH3X2X_WriteVirtualReg(usRegAddr + (uchIndex * GH3X2X_REG_ADDR_SIZE),\r
+                                               usRegDataTmp);\r
+                    }\r
+                    break;\r
+                }\r
+            } // end of if ((uchRegRwLen > 0) && ...\r
+            else\r
+            {\r
+                GH3X2X_DEBUG_LOG_PARAM("reg rw write len error!\r\n");\r
+            }\r
+\r
+            /* respond packet format */\r
+            SET_VAL_VIA_PTR(pusRespondLen, GH3X2X_UprotocolPacketFormat(g_uchPacketCmd, puchRespondBuffer,\r
+                                                            g_pstGh3x2xProtocolData->puchPacketPayloadArr, g_uchPacketPayloadLen));\r
+        } // end of if (uchRegRwMode ==  UPROTOCOL_REG_RW_WRITE_MODE)\r
+        else if (uchRegRwMode ==  UPROTOCOL_REG_RW_READ_MODE)\r
+        {\r
+            if (uchRegRwLen > 0)\r
+            {\r
+                GU8 uchMaxRegLen = (GH3X2X_UPROTOCOL_GET_PAYLOAD_LEN_SUPPORT(g_uchPacketMaxLenSupport)\r
+                                    - UPROTOCOL_REG_RW_HEADER_LENGTH) / GH3X2X_REG_ADDR_SIZE;\r
+                GU16 usRegType = 0;\r
+                if (uchRegRwLen > uchMaxRegLen)\r
+                {\r
+                    uchRegRwLen = uchMaxRegLen; // fixed max len\r
+                    g_pstGh3x2xProtocolData->puchPacketPayloadArr[UPROTOCOL_REG_RW_CNT_INDEX] = uchRegRwLen;\r
+                }\r
+                usRegType = GH3X2X_GET_BIT_IS_SET(usRegAddr);\r
+                if(0xAAAA == usRegAddr)\r
+                {\r
+                    usRegType = GH3X2X_REG_IS_VIRTUAL0X0_BIT;\r
+                }\r
+                switch (usRegType)\r
+                {\r
+                case GH3X2X_REG_IS_VIRTUAL0X0_BIT:\r
+                    GH3X2X_CHIP_WAKEUP_PROTOCOL();\r
+\r
+                    if(0xAAAA == usRegAddr)\r
+                    {\r
+                        GH3X2X_ReadFifo(&(g_pstGh3x2xProtocolData->puchPacketPayloadArr[UPROTOCOL_REG_RW_DATA_INDEX]), uchRegRwLen*2);\r
+                    }\r
+                    else\r
+                    {\r
+                        for (uchIndex = 0; uchIndex < uchRegRwLen; uchIndex++)\r
+                        {\r
+                            \r
+                            usRegDataTmp = GH3X2X_ReadReg(GH3X2X_GET_REG_REAL_ADRR(usRegAddr\\r
+                                                            + (uchIndex * GH3X2X_REG_ADDR_SIZE)));\r
+                            g_pstGh3x2xProtocolData->puchPacketPayloadArr[UPROTOCOL_REG_RW_DATA_INDEX + (uchIndex * GH3X2X_REG_ADDR_SIZE)] = \\r
+                                                                        GH3X2X_GET_HIGH_BYTE_FROM_WORD(usRegDataTmp);\r
+                            g_pstGh3x2xProtocolData->puchPacketPayloadArr[UPROTOCOL_REG_RW_DATA_INDEX + 1 + (uchIndex * GH3X2X_REG_ADDR_SIZE)] = \\r
+                                                                        GH3X2X_GET_LOW_BYTE_FROM_WORD(usRegDataTmp);\r
+                        }\r
+                    }\r
+                    GH3X2X_CHIP_SLEEP_PROTOCOL();\r
+                    break;\r
+                default:\r
+                #if GH3X2X_SUPPORT_READ_BACK_VIRTUAL_REG\r
+                    for (uchIndex = 0; uchIndex < uchRegRwLen; uchIndex++)\r
+                    {\r
+                        usRegDataTmp = GH3X2X_ReadVirtualReg(usRegAddr\\r
+                                                               + (uchIndex * GH3X2X_REG_ADDR_SIZE));\r
+                        g_pstGh3x2xProtocolData->puchPacketPayloadArr[UPROTOCOL_REG_RW_DATA_INDEX + (uchIndex * GH3X2X_REG_ADDR_SIZE)] = \\r
+                                                                    GH3X2X_GET_HIGH_BYTE_FROM_WORD(usRegDataTmp);\r
+                        g_pstGh3x2xProtocolData->puchPacketPayloadArr[UPROTOCOL_REG_RW_DATA_INDEX + 1 + (uchIndex * GH3X2X_REG_ADDR_SIZE)] = \\r
+                                                                    GH3X2X_GET_LOW_BYTE_FROM_WORD(usRegDataTmp);\r
+                    }\r
+                #endif\r
+                    break;\r
+                }\r
+            } // end of if (uchRegRwLen > 0)\r
+            else\r
+            {\r
+                GH3X2X_DEBUG_LOG_PARAM("reg rw read len error!\r\n");\r
+            }\r
+\r
+            /* respond packet format */\r
+            SET_VAL_VIA_PTR(pusRespondLen, GH3X2X_UprotocolPacketFormat(g_uchPacketCmd, puchRespondBuffer,\r
+                        g_pstGh3x2xProtocolData->puchPacketPayloadArr, UPROTOCOL_REG_RW_HEADER_LENGTH + uchRegRwLen * GH3X2X_REG_ADDR_SIZE));\r
+        } // end of else if (uchRegRwMode ==  UPROTOCOL_REG_RW_WRITE_MODE)\r
+    } // end if (g_uchPacketPayloadLen >= UPROTOCOL_REG_RW_HEADER_LENGTH)\r
+    else\r
+    {\r
+        GH3X2X_DEBUG_LOG_PARAM("reg rw payload error!\r\n");\r
+    }\r
+}\r
+\r
+/**\r
+ * @fn     void GH3X2X_RegisterGetFirmwareVersionFunc(GCHAR* (*pGetFirmwareVersionFunc)(void))\r
+ *\r
+ * @brief  Register get firmware version function\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]    pGetFirmwareVersionFunc    pointer to get firmware versionn function\r
+ * @param[out]   None\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_RegisterGetFirmwareVersionFunc(GCHAR* (*pGetFirmwareVersionFunc)(void),\r
+                                           GCHAR* (*pGetDemoVersionFunc)(void),\r
+                                           GCHAR* (*pGetBootloaderVersionFunc)(void))\r
+{\r
+    g_pGh3x2xGetFirmwareVersionFunc = pGetFirmwareVersionFunc;\r
+    g_pGh3x2xGetDemoVersionFunc = pGetDemoVersionFunc;\r
+    g_pGh3x2xGetBootloaderVersionFunc = pGetBootloaderVersionFunc;\r
+    GH3X2X_DEBUG_LOG_PARAM("%s\r\n", __FUNCTION__);\r
+}\r
+\r
+static void GH3X2X_UprotocolHandleGetOpenedFuncCmd(GU8 *puchRespondBuffer, GU16 *pusRespondLen)\r
+{\r
+    g_pstGh3x2xProtocolData->puchPacketPayloadArr[UPROTOCOL_GET_MAX_LEN_RESP_VAL_INDEX] = g_uchPacketMaxLenSupport;\r
+\r
+    GU32 unFuncModeOpened = GH3X2X_GetFuncModeOpened();\r
+    GU8 uchPayload[5];\r
+    uchPayload[0] = 0;\r
+    uchPayload[1] = GH3X2X_GET_BYTE3_FROM_DWORD(unFuncModeOpened);\r
+    uchPayload[2] = GH3X2X_GET_BYTE2_FROM_DWORD(unFuncModeOpened);\r
+    uchPayload[3] = GH3X2X_GET_BYTE1_FROM_DWORD(unFuncModeOpened);\r
+    uchPayload[4] = GH3X2X_GET_BYTE0_FROM_DWORD(unFuncModeOpened);\r
+\r
+    /* respond packet format */\r
+    SET_VAL_VIA_PTR(pusRespondLen, GH3X2X_UprotocolPacketFormat(g_uchPacketCmd, puchRespondBuffer,\r
+                                uchPayload, 5));\r
+}\r
+\r
+extern void GH3X2X_AlgoVersion(GU8 uchFunctionID, GCHAR version[120]);\r
+/**\r
+ * @fn     static void GH3X2X_UprotocolHandleGetVerCmd(GU8 *puchRespondBuffer, GU16 *pusRespondLen)\r
+ *\r
+ * @brief  handle get version cmd\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]   puchRespondBuffer    pointer to respond buffer\r
+ * @param[out]   pusRespondLen        pointer to respond length\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_GetVersion(GU8 uchGetVersionType, GCHAR pszVersionString[150])\r
+{\r
+    //GCHAR *pszVersionString = GH3X2X_PTR_NULL;\r
+    GH3X2X_Memcpy(pszVersionString, UPROTOCOL_GET_VER_DEFAULT_VER_STRING, GH3X2X_Strlen((const GCHAR *)UPROTOCOL_GET_VER_DEFAULT_VER_STRING) + 1);\r
+    switch (uchGetVersionType)\r
+    {\r
+    case UPROTOCOL_GET_VER_TYPE_FW_VER:\r
+        if (g_pGh3x2xGetFirmwareVersionFunc != GH3X2X_PTR_NULL)\r
+        {\r
+            GH3X2X_Memcpy(pszVersionString, g_pGh3x2xGetFirmwareVersionFunc(), GH3X2X_Strlen((const GCHAR *)g_pGh3x2xGetFirmwareVersionFunc()) + 1);\r
+        }\r
+        break;\r
+    case UPROTOCOL_GET_VER_TYPE_DEMO_VER:\r
+        if (g_pGh3x2xGetDemoVersionFunc != GH3X2X_PTR_NULL)\r
+        {\r
+            GH3X2X_Memcpy(pszVersionString, g_pGh3x2xGetDemoVersionFunc(), GH3X2X_Strlen((const GCHAR *)g_pGh3x2xGetDemoVersionFunc()) + 1);\r
+        }\r
+        break;\r
+    case UPROTOCOL_GET_VER_TYPE_BOOTLOADER_VER:\r
+        if (g_pGh3x2xGetBootloaderVersionFunc != GH3X2X_PTR_NULL)\r
+        {\r
+            GH3X2X_Memcpy(pszVersionString, g_pGh3x2xGetBootloaderVersionFunc(), GH3X2X_Strlen((const GCHAR *)g_pGh3x2xGetBootloaderVersionFunc()) + 1);\r
+        }\r
+        break;\r
+    case UPROTOCOL_GET_VER_TYPE_FUNC_SUPPORT:\r
+        break;\r
+    case UPROTOCOL_GET_VER_TYPE_CHIP_VER:\r
+        GH3X2X_Memcpy(pszVersionString, GH3X2X_GetChipVersion(), GH3X2X_Strlen((const GCHAR *)GH3X2X_GetChipVersion()) + 1);\r
+        break;\r
+    case UPROTOCOL_GET_VER_TYPE_PROTOCOL_VER:\r
+        GH3X2X_Memcpy(pszVersionString, GH3X2X_GetProtocolVersion(), GH3X2X_Strlen((const GCHAR *)GH3X2X_GetProtocolVersion()) + 1);\r
+        break;\r
+    case UPROTOCOL_GET_VER_TYPE_VIRTUAL_REG_VER:\r
+        GH3X2X_Memcpy(pszVersionString, GH3X2X_GetVirtualRegVersion(), GH3X2X_Strlen((const GCHAR *)GH3X2X_GetVirtualRegVersion()) + 1);\r
+        break;\r
+    case UPROTOCOL_GET_VER_TYPE_DRV_VER:\r
+        GH3X2X_Memcpy(pszVersionString, GH3X2X_GetDriverLibVersion(), GH3X2X_Strlen((const GCHAR *)GH3X2X_GetDriverLibVersion()) + 1);\r
+        break;\r
+    default:\r
+        #if __GOODIX_ALGO_CALL_MODE__\r
+        if (uchGetVersionType >= UPROTOCOL_GET_VER_TYPE_ALGO_VER && uchGetVersionType <= UPROTOCOL_GET_VER_TYPE_ALGO_VER_END)\r
+        {\r
+            GU32 unFunctionOffset = (GU32)(uchGetVersionType - UPROTOCOL_GET_VER_TYPE_ALGO_VER);\r
+            GCHAR uchVersion[120] = {0};\r
+            GH3X2X_AlgoVersion(unFunctionOffset, uchVersion);\r
+            GU32 len = GH3X2X_Strlen((const GCHAR *)uchVersion) + 1;\r
+            GH3X2X_Memcpy(pszVersionString, uchVersion, len);\r
+        }\r
+        #endif\r
+        break;\r
+    }\r
+}\r
+\r
+static void GH3X2X_UprotocolHandleGetVerCmd(GU8 *puchRespondBuffer, GU16 *pusRespondLen)\r
+{\r
+    GU8 uchGetVersionType = g_pstGh3x2xProtocolData->puchPacketPayloadArr[UPROTOCOL_GET_VER_TYPE_INDEX];\r
+    GCHAR pszVersionString[150] = {0};\r
+    GU8 uchVersionStringLen = 0;\r
+    if (g_uchPacketPayloadLen == 0)\r
+    {\r
+        uchGetVersionType = UPROTOCOL_GET_VER_TYPE_FW_VER; // fixed to get firmware version\r
+    }\r
+    GH3X2X_GetVersion(uchGetVersionType, (GCHAR*)pszVersionString);\r
+    uchVersionStringLen = (GU8)GH3X2X_Strlen(pszVersionString);\r
+    if (uchVersionStringLen > (GH3X2X_UPROTOCOL_GET_PAYLOAD_LEN_SUPPORT(g_uchPacketMaxLenSupport) \\r
+                                   - UPROTOCOL_GET_VER_STRING_INDEX))\r
+    {\r
+        uchVersionStringLen = GH3X2X_UPROTOCOL_GET_PAYLOAD_LEN_SUPPORT(g_uchPacketMaxLenSupport) \\r
+                                   - UPROTOCOL_GET_VER_STRING_INDEX; // fixed max len\r
+    }\r
+    g_pstGh3x2xProtocolData->puchPacketPayloadArr[UPROTOCOL_GET_VER_TYPE_INDEX] = uchGetVersionType;\r
+    g_pstGh3x2xProtocolData->puchPacketPayloadArr[UPROTOCOL_GET_VER_STRING_LEN_INDEX] = uchVersionStringLen;\r
+    GH3X2X_Memcpy((GCHAR *)&g_pstGh3x2xProtocolData->puchPacketPayloadArr[UPROTOCOL_GET_VER_STRING_INDEX],\r
+                            pszVersionString, uchVersionStringLen);\r
+\r
+    /* respond packet format */\r
+    SET_VAL_VIA_PTR(pusRespondLen, GH3X2X_UprotocolPacketFormat(g_uchPacketCmd, puchRespondBuffer,\r
+                                g_pstGh3x2xProtocolData->puchPacketPayloadArr, UPROTOCOL_GET_VER_STRING_INDEX + uchVersionStringLen));\r
+}\r
+\r
+/**\r
+ * @fn     static void GH3X2X_UprotocolHandleFifoThrConfig(GU8 *puchRespondBuffer, GU16 *pusRespondLen)\r
+ *\r
+ * @brief  handle fifo thr config cmd\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]    None\r
+ * @param[out]   puchRespondBuffer    pointer to respond buffer\r
+ * @param[out]   pusRespondLen        pointer to respond length\r
+ *\r
+ * @return  None\r
+ */\r
+static void GH3X2X_UprotocolHandleFifoThrConfig(GU8 *puchRespondBuffer, GU16 *pusRespondLen)\r
+{\r
+    if (g_uchPacketPayloadLen == GH3X2X_REG_ADDR_SIZE)\r
+    {\r
+        GH3X2X_CHIP_WAKEUP_NORET();\r
+        GH3X2X_FifoWatermarkThrConfig(GH3X2X_MAKEUP_WORD(g_pstGh3x2xProtocolData->puchPacketPayloadArr[UPROTOCOL_FIFO_THR_CFG_H_INDEX],\r
+                                      g_pstGh3x2xProtocolData->puchPacketPayloadArr[UPROTOCOL_FIFO_THR_CFG_L_INDEX]));\r
+        GH3X2X_CHIP_SLEEP_NORET();\r
+        g_pstGh3x2xProtocolData->puchPacketPayloadArr[UPROTOCOL_FIFO_THR_CFG_RESP_STATUS_INDEX] = UPROTOCOL_FIFO_THR_CFG_RESP_CFG_SUCCESS;\r
+    }\r
+    else\r
+    {\r
+        g_pstGh3x2xProtocolData->puchPacketPayloadArr[UPROTOCOL_FIFO_THR_CFG_RESP_STATUS_INDEX] = UPROTOCOL_FIFO_THR_CFG_RESP_CFG_FAIL;\r
+    }\r
+\r
+    /* respond packet format */\r
+    SET_VAL_VIA_PTR(pusRespondLen, GH3X2X_UprotocolPacketFormat(g_uchPacketCmd, puchRespondBuffer,\r
+                                g_pstGh3x2xProtocolData->puchPacketPayloadArr, UPROTOCOL_FIFO_THR_CFG_RESP_LEN));\r
+}\r
+\r
+/**\r
+ * @fn     static void GH3X2X_UprotocolHandleChipCtrl(GU8 *puchRespondBuffer, GU16 *pusRespondLen)\r
+ *\r
+ * @brief  handle chip ctrl cmd\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]    None\r
+ * @param[out]   puchRespondBuffer    pointer to respond buffer\r
+ * @param[out]   pusRespondLen        pointer to respond length\r
+ *\r
+ * @return  None\r
+ */\r
+static void GH3X2X_UprotocolHandleChipCtrl(GU8 *puchRespondBuffer, GU16 *pusRespondLen)\r
+{\r
+    if (g_uchPacketPayloadLen == 1)\r
+    {\r
+        GU8 uchCtrlType = g_pstGh3x2xProtocolData->puchPacketPayloadArr[UPROTOCOL_CHIP_CTRL_VAL_INDEX];\r
+        g_pstGh3x2xProtocolData->puchPacketPayloadArr[UPROTOCOL_CHIP_CTRL_RESP_STATUS_INDEX] = UPROTOCOL_CHIP_CTRL_RESP_NULL;\r
+        switch (uchCtrlType)\r
+        {\r
+        case UPROTOCOL_CHIP_CTRL_TYPE_HARD_RESET:\r
+            g_uchResetFromProtocolFlag = 1;\r
+            if (GH3X2X_HardReset() == GH3X2X_RET_OK)\r
+            {\r
+                g_pstGh3x2xProtocolData->puchPacketPayloadArr[UPROTOCOL_CHIP_CTRL_RESP_STATUS_INDEX] = UPROTOCOL_CHIP_CTRL_RESP_CFG_SUCCESS;\r
+            }\r
+            break;\r
+\r
+        case UPROTOCOL_CHIP_CTRL_TYPE_SOFT_RESET:\r
+            g_uchResetFromProtocolFlag = 1;\r
+            if (GH3X2X_SoftReset() == GH3X2X_RET_OK)\r
+            {\r
+                g_pstGh3x2xProtocolData->puchPacketPayloadArr[UPROTOCOL_CHIP_CTRL_RESP_STATUS_INDEX] = UPROTOCOL_CHIP_CTRL_RESP_CFG_SUCCESS;\r
+            }\r
+            break;\r
+\r
+#if (GH3X2X_UPROTOCOL_CHIP_CTRL_CMD_WAKEUP_SLEEP_SUP)\r
+        case UPROTOCOL_CHIP_CTRL_TYPE_WAKEUP:\r
+            if (GH3X2X_ExitLowPowerMode() == GH3X2X_RET_OK)\r
+            {\r
+                g_pstGh3x2xProtocolData->puchPacketPayloadArr[UPROTOCOL_CHIP_CTRL_RESP_STATUS_INDEX] = UPROTOCOL_CHIP_CTRL_RESP_CFG_SUCCESS;\r
+            }\r
+            break;\r
+\r
+        case UPROTOCOL_CHIP_CTRL_TYPE_SLEEP:\r
+            if (GH3X2X_EnterLowPowerMode() == GH3X2X_RET_OK)\r
+            {\r
+                g_pstGh3x2xProtocolData->puchPacketPayloadArr[UPROTOCOL_CHIP_CTRL_RESP_STATUS_INDEX] = UPROTOCOL_CHIP_CTRL_RESP_CFG_SUCCESS;\r
+            }\r
+            break;\r
+#endif\r
+\r
+        default:\r
+            g_pstGh3x2xProtocolData->puchPacketPayloadArr[UPROTOCOL_CHIP_CTRL_RESP_STATUS_INDEX] = UPROTOCOL_CHIP_CTRL_RESP_CFG_FAIL;\r
+            break;\r
+        } // end of switch (uchCtrlType)\r
+    } // end of if (g_uchPacketPayloadLen == 1)\r
+    else\r
+    {\r
+        g_pstGh3x2xProtocolData->puchPacketPayloadArr[UPROTOCOL_CHIP_CTRL_RESP_STATUS_INDEX] = UPROTOCOL_CHIP_CTRL_RESP_CFG_FAIL;\r
+    }\r
+\r
+    /* respond packet format */\r
+    SET_VAL_VIA_PTR(pusRespondLen, GH3X2X_UprotocolPacketFormat(g_uchPacketCmd, puchRespondBuffer,\r
+                                g_pstGh3x2xProtocolData->puchPacketPayloadArr, UPROTOCOL_CHIP_CTRL_RESP_LEN));\r
+}\r
+\r
+/**\r
+ * @fn     static void GH3X2X_UprotocolHandleGetSupprtLenCmd(GU8 *puchRespondBuffer, GU16 *pusRespondLen)\r
+ *\r
+ * @brief  handle get max len support cmd\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]    None\r
+ * @param[out]   puchRespondBuffer    pointer to respond buffer\r
+ * @param[out]   pusRespondLen        pointer to respond length\r
+ *\r
+ * @return  None\r
+ */\r
+static void GH3X2X_UprotocolHandleGetSupprtLenCmd(GU8 *puchRespondBuffer, GU16 *pusRespondLen)\r
+{\r
+    g_pstGh3x2xProtocolData->puchPacketPayloadArr[UPROTOCOL_GET_MAX_LEN_RESP_VAL_INDEX] = g_uchPacketMaxLenSupport;\r
+\r
+    /* respond packet format */\r
+    SET_VAL_VIA_PTR(pusRespondLen, GH3X2X_UprotocolPacketFormat(g_uchPacketCmd, puchRespondBuffer,\r
+                                g_pstGh3x2xProtocolData->puchPacketPayloadArr, UPROTOCOL_GET_MAX_LEN_RESP_LEN));\r
+}\r
+\r
+/**\r
+ * @fn     static void GH3X2X_UprotocolHandleSwFunctionCmd(GU8 *puchRespondBuffer, GU16 *pusRespondLen)\r
+ *\r
+ * @brief  handle switch slot and function cmd\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]    None\r
+ * @param[out]   puchRespondBuffer    pointer to respond buffer\r
+ * @param[out]   pusRespondLen        pointer to respond length\r
+ *\r
+ * @return  None\r
+ */\r
+static EMUprotocolParseCmdType GH3X2X_UprotocolHandleSwFunctionCmd(GU8 *puchRespondBuffer, GU16 *pusRespondLen)\r
+{\r
+    EMUprotocolParseCmdType emUprotocolCmdType = UPROTOCOL_CMD_IGNORE;\r
+        \r
+    g_unTargetFuncMode = GH3X2X_MAKEUP_DWORD(g_pstGh3x2xProtocolData->puchPacketPayloadArr[UPROTOCOL_SW_FUNC_FUNC_INDEX + 3], \\r
+                                            g_pstGh3x2xProtocolData->puchPacketPayloadArr[UPROTOCOL_SW_FUNC_FUNC_INDEX + 2], \\r
+                                            g_pstGh3x2xProtocolData->puchPacketPayloadArr[UPROTOCOL_SW_FUNC_FUNC_INDEX + 1], \\r
+                                            g_pstGh3x2xProtocolData->puchPacketPayloadArr[UPROTOCOL_SW_FUNC_FUNC_INDEX]);\r
+\r
+    if (g_unAllFuncMode == (g_unTargetFuncMode | g_unAllFuncMode))\r
+    {\r
+        if (UPROTOCOL_START_SAMPLING == g_pstGh3x2xProtocolData->puchPacketPayloadArr[UPROTOCOL_SW_FUNC_ONOFF_INDEX])\r
+        {\r
+            g_unFuncModeOpened |= g_unTargetFuncMode;\r
+            emUprotocolCmdType = UPROTOCOL_CMD_START;\r
+        }\r
+        else\r
+        {\r
+            g_unFuncModeOpened &= (~g_unTargetFuncMode);\r
+            emUprotocolCmdType = UPROTOCOL_CMD_STOP;\r
+        }\r
+        \r
+        g_pstGh3x2xProtocolData->puchPacketPayloadArr[UPROTOCOL_SW_FUNC_RESP_INDEX] = UPROTOCOL_SW_FUNC_SUCCESS;\r
+    }\r
+    else\r
+    {\r
+        g_pstGh3x2xProtocolData->puchPacketPayloadArr[UPROTOCOL_SW_FUNC_RESP_INDEX] = UPROTOCOL_SW_FUNC_FAIL;\r
+    }   \r
+    \r
+    GH3X2X_DEBUG_LOG_PARAM("[%s]:g_unTargetFuncMode = 0x%08x\r\n", __FUNCTION__, g_unTargetFuncMode);\r
+\r
+    /* respond packet format */\r
+    SET_VAL_VIA_PTR(pusRespondLen, GH3X2X_UprotocolPacketFormat(g_uchPacketCmd, puchRespondBuffer,\r
+                                g_pstGh3x2xProtocolData->puchPacketPayloadArr, UPROTOCOL_SW_FUNC_RESP_LEN));\r
+    return emUprotocolCmdType;\r
+}\r
+\r
+/**\r
+ * @fn     static void GH3X2X_UprotocolHandleLoadRegListCmd(GU8 *puchRespondBuffer, GU16 *pusRespondLen)\r
+ *\r
+ * @brief  handle load reg list cmd\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]    None\r
+ * @param[out]   puchRespondBuffer    pointer to respond buffer\r
+ * @param[out]   pusRespondLen        pointer to respond length\r
+ *\r
+ * @return  None\r
+ */\r
+static void GH3X2X_UprotocolHandleLoadRegListCmd(GU8 *puchRespondBuffer, GU16 *pusRespondLen)\r
+{\r
+    GU8 uchReglistCnt = g_uchPacketPayloadLen / UPROTOCOL_LOAD_REG_LIST_SIZEOF;\r
+    STGh3x2xReg *pstReglist = (STGh3x2xReg *)g_pstGh3x2xProtocolData->puchPacketPayloadArr;\r
+    GH3X2X_SwapLittleBigEndianData(g_pstGh3x2xProtocolData->puchPacketPayloadArr, g_uchPacketPayloadLen);\r
+    GH3X2X_CHIP_WAKEUP_PROTOCOL();\r
+    if (GH3X2X_LoadNewRegConfigArr(pstReglist, uchReglistCnt, 0) == GH3X2X_RET_OK)\r
+    {\r
+        g_pstGh3x2xProtocolData->puchPacketPayloadArr[UPROTOCOL_LOAD_REG_LIST_RESP_STATUS_INDEX] = \\r
+                                                                UPROTOCOL_LOAD_REG_LIST_RESP_CFG_SUCCESS;\r
+    }\r
+    else\r
+    {\r
+        g_pstGh3x2xProtocolData->puchPacketPayloadArr[UPROTOCOL_LOAD_REG_LIST_RESP_STATUS_INDEX] = UPROTOCOL_LOAD_REG_LIST_RESP_CFG_FAIL;\r
+    }\r
+    GH3X2X_CHIP_SLEEP_PROTOCOL();\r
+\r
+    /* respond packet format */\r
+    SET_VAL_VIA_PTR(pusRespondLen, GH3X2X_UprotocolPacketFormat(g_uchPacketCmd, puchRespondBuffer,\r
+                                g_pstGh3x2xProtocolData->puchPacketPayloadArr, UPROTOCOL_LOAD_REG_LIST_RESP_LEN));\r
+}\r
+\r
+/**\r
+ * @fn     static void GH3X2X_UprotocolHandleDebugStatusCmd(GU8 *puchRespondBuffer, GU16 *pusRespondLen)\r
+ *\r
+ * @brief  handle debug status cmd\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]    None\r
+ * @param[out]   puchRespondBuffer    pointer to respond buffer\r
+ * @param[out]   pusRespondLen        pointer to respond length\r
+ *\r
+ * @return  None\r
+ */\r
+static void GH3X2X_UprotocolHandleDebugStatusCmd(GU8 *puchRespondBuffer, GU16 *pusRespondLen)\r
+{\r
+    GU8 uchDebugType = g_pstGh3x2xProtocolData->puchPacketPayloadArr[UPROTOCOL_DEBUG_STATUS_TYPE_INDEX];\r
+    GU8 uchBytesLen = UPROTOCOL_DEBUG_STATUS_RESP_BYTES_8;\r
+    GH3X2X_Memset(&g_pstGh3x2xProtocolData->puchPacketPayloadArr[UPROTOCOL_DEBUG_STATUS_RESP_BYTES_INDEX], 0,\r
+                                                                        UPROTOCOL_DEBUG_STATUS_RESP_LEN - 1);\r
+    switch (uchDebugType)\r
+    {\r
+    case UPROTOCOL_DEBUG_STATUS_READ_INT_PIN:\r
+        READ_PIN_STATUS_CALL(g_pGh3x2xReadIntPinStatusFunc,\r
+                                g_pstGh3x2xProtocolData->puchPacketPayloadArr[UPROTOCOL_DEBUG_STATUS_RESP_DATA_INDEX]);\r
+        break;\r
+    case UPROTOCOL_DEBUG_STATUS_READ_RST_PIN:\r
+        READ_PIN_STATUS_CALL(g_pGh3x2xReadResetPinStatusFunc,\r
+                                g_pstGh3x2xProtocolData->puchPacketPayloadArr[UPROTOCOL_DEBUG_STATUS_RESP_DATA_INDEX]);\r
+        break;\r
+    case UPROTOCOL_DEBUG_STATUS_READ_SPCS_PIN:\r
+        READ_PIN_STATUS_CALL(g_pGh3x2xReadSpcsPinStatusFunc,\r
+                                g_pstGh3x2xProtocolData->puchPacketPayloadArr[UPROTOCOL_DEBUG_STATUS_RESP_DATA_INDEX]);\r
+        break;\r
+    case UPROTOCOL_DEBUG_STATUS_READ_SPDO_PIN:\r
+        READ_PIN_STATUS_CALL(g_pGh3x2xReadSpdoPinStatusFunc,\r
+                                g_pstGh3x2xProtocolData->puchPacketPayloadArr[UPROTOCOL_DEBUG_STATUS_RESP_DATA_INDEX]);\r
+        break;\r
+    case UPROTOCOL_DEBUG_STATUS_COMM_CONFIRM:\r
+        GH3X2X_CHIP_WAKEUP_NORET();\r
+        if (GH3X2X_CommunicateConfirm() == GH3X2X_RET_OK)\r
+        {\r
+            g_pstGh3x2xProtocolData->puchPacketPayloadArr[UPROTOCOL_DEBUG_STATUS_RESP_DATA_INDEX] = 0x01;\r
+        }\r
+        GH3X2X_CHIP_SLEEP_NORET();\r
+        break;\r
+\r
+    default: // include UPROTOCOL_DEBUG_STATUS_READ_WORK_STATUS\r
+        g_pstGh3x2xProtocolData->puchPacketPayloadArr[UPROTOCOL_DEBUG_STATUS_RESP_DATA_INDEX] = g_uchGh3x2xStatus;\r
+        break;\r
+    } // end of switch (uchDebugType)\r
+    g_pstGh3x2xProtocolData->puchPacketPayloadArr[UPROTOCOL_DEBUG_STATUS_RESP_BYTES_INDEX] = uchBytesLen;\r
+\r
+    /* respond packet format */\r
+    SET_VAL_VIA_PTR(pusRespondLen, GH3X2X_UprotocolPacketFormat(g_uchPacketCmd, puchRespondBuffer,\r
+                                g_pstGh3x2xProtocolData->puchPacketPayloadArr, UPROTOCOL_DEBUG_STATUS_RESP_LEN));\r
+}\r
+\r
+/**\r
+ * @fn     static EMUprotocolParseCmdType GH3X2X_UprotocolHandleStartCtrlCmd(GU8 *puchRespondBuffer,\r
+ *                              GU16 *pusRespondLen)\r
+ *\r
+ * @brief  handle start ctrl cmd\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]    None\r
+ * @param[out]   puchRespondBuffer    pointer to respond buffer\r
+ * @param[out]   pusRespondLen        pointer to respond length\r
+ *\r
+ * @return  @ref EMUprotocolParseCmdType\r
+ */\r
+static EMUprotocolParseCmdType GH3X2X_UprotocolHandleStartCtrlCmd(GU8 *puchRespondBuffer, GU16 *pusRespondLen)\r
+{\r
+    EMUprotocolParseCmdType emUprotocolCmdType = UPROTOCOL_CMD_IGNORE;\r
+    g_unTargetFuncMode = GH3X2X_MAKEUP_DWORD(g_pstGh3x2xProtocolData->puchPacketPayloadArr[UPROTOCOL_START_CTRL_FUNCTION_INDEX + 3], \\r
+                                            g_pstGh3x2xProtocolData->puchPacketPayloadArr[UPROTOCOL_START_CTRL_FUNCTION_INDEX + 2], \\r
+                                            g_pstGh3x2xProtocolData->puchPacketPayloadArr[UPROTOCOL_START_CTRL_FUNCTION_INDEX + 1], \\r
+                                            g_pstGh3x2xProtocolData->puchPacketPayloadArr[UPROTOCOL_START_CTRL_FUNCTION_INDEX]);\r
+\r
+    if (g_unAllFuncMode == (g_unTargetFuncMode | g_unAllFuncMode))\r
+    {\r
+        if (UPROTOCOL_START_SAMPLING == g_pstGh3x2xProtocolData->puchPacketPayloadArr[UPROTOCOL_START_CTRL_INDEX])\r
+        {\r
+            g_unFuncModeOpened |= g_unTargetFuncMode;\r
+            emUprotocolCmdType = UPROTOCOL_CMD_START;\r
+        }\r
+        else\r
+        {\r
+            g_unFuncModeOpened &= (~g_unTargetFuncMode);\r
+            emUprotocolCmdType = UPROTOCOL_CMD_STOP;\r
+        }\r
+        \r
+        g_pstGh3x2xProtocolData->puchPacketPayloadArr[UPROTOCOL_START_CTRL_RESP_INDEX] = UPROTOCOL_START_CTRL_SUCCESS;\r
+    }\r
+    else\r
+    {\r
+        g_pstGh3x2xProtocolData->puchPacketPayloadArr[UPROTOCOL_START_CTRL_RESP_INDEX] = UPROTOCOL_START_CTRL_FAIL;\r
+    }   \r
+\r
+    GH3X2X_DEBUG_LOG_PARAM("[%s]:g_unTargetFuncMode = 0x%08x, emUprotocolCmdType = %d\r\n", __FUNCTION__, g_unTargetFuncMode, emUprotocolCmdType);\r
+\r
+    /* respond packet format */\r
+    SET_VAL_VIA_PTR(pusRespondLen, GH3X2X_UprotocolPacketFormat(g_uchPacketCmd, puchRespondBuffer,\r
+                                g_pstGh3x2xProtocolData->puchPacketPayloadArr, UPROTOCOL_START_CTRL_RESP_LEN));\r
+    return emUprotocolCmdType;\r
+}\r
+\r
+/**\r
+ * @fn     static EMUprotocolParseCmdType GH3X2X_UprotocolHandleWorkModeCmd(GU8 *puchRespondBuffer,\r
+ *              GU16 *pusRespondLen)\r
+ *\r
+ * @brief  handle work mode cmd\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]    None\r
+ * @param[out]   puchRespondBuffer    pointer to respond buffer\r
+ * @param[out]   pusRespondLen        pointer to respond length\r
+ *\r
+ * @return  @ref EMUprotocolParseCmdType\r
+ */\r
+static EMUprotocolParseCmdType GH3X2X_UprotocolHandleWorkModeCmd(GU8 *puchRespondBuffer, GU16 *pusRespondLen)\r
+{\r
+    EMUprotocolParseCmdType emUprotocolCmdType = UPROTOCOL_CMD_IGNORE;\r
+\r
+    emUprotocolCmdType = (EMUprotocolParseCmdType)(g_pstGh3x2xProtocolData->puchPacketPayloadArr[UPROTOCOL_WORK_MODE_INDEX] + \\r
+                                                    UPROTOCOL_CMD_EVK_MODE);\r
+\r
+    g_unAllFuncMode = GH3X2X_MAKEUP_DWORD(g_pstGh3x2xProtocolData->puchPacketPayloadArr[UPROTOCOL_FUNC_MODE_INDEX + 3], \\r
+                                            g_pstGh3x2xProtocolData->puchPacketPayloadArr[UPROTOCOL_FUNC_MODE_INDEX + 2], \\r
+                                            g_pstGh3x2xProtocolData->puchPacketPayloadArr[UPROTOCOL_FUNC_MODE_INDEX + 1], \\r
+                                            g_pstGh3x2xProtocolData->puchPacketPayloadArr[UPROTOCOL_FUNC_MODE_INDEX]);\r
+\r
+    GH3X2X_DEBUG_LOG_PARAM("[%s]:work mode = %d, function_enable = 0x%08x\r\n", __FUNCTION__, g_pstGh3x2xProtocolData->puchPacketPayloadArr[UPROTOCOL_WORK_MODE_INDEX], (int)g_unAllFuncMode);\r
+\r
+    g_unFuncModeOpened = 0;\r
+    g_unTargetFuncMode = 0;\r
+\r
+    g_pstGh3x2xProtocolData->puchPacketPayloadArr[UPROTOCOL_WORK_MODE_RESP_INDEX] = UPROTOCOL_WORK_MODE_SET_SUCCESS;\r
+\r
+    /* respond packet format */\r
+    SET_VAL_VIA_PTR(pusRespondLen, GH3X2X_UprotocolPacketFormat(g_uchPacketCmd, puchRespondBuffer, \\r
+                                g_pstGh3x2xProtocolData->puchPacketPayloadArr, UPROTOCOL_WORK_MODE_RESP_LEN));\r
+\r
+    return emUprotocolCmdType;\r
+}\r
+\r
+/**\r
+ * @fn     static void GH3X2X_UprotocolHandleReportEventSetCmd(GU8 *puchRespondBuffer, GU16 *pusRespondLen)\r
+ *\r
+ * @brief  handle event report set cmd\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]    None\r
+ * @param[out]   puchRespondBuffer    pointer to respond buffer\r
+ * @param[out]   pusRespondLen        pointer to respond length\r
+ *\r
+ * @return  None\r
+ */\r
+static void GH3X2X_UprotocolHandleReportEventSetCmd(GU8 *puchRespondBuffer, GU16 *pusRespondLen)\r
+{\r
+    g_usGh3x2xEventNeedReport = GH3X2X_MAKEUP_WORD(g_pstGh3x2xProtocolData->puchPacketPayloadArr[UPROTOCOL_REPORT_EVENT_SET_INDEX], \\r
+                                                    g_pstGh3x2xProtocolData->puchPacketPayloadArr[UPROTOCOL_REPORT_EVENT_SET_INDEX + 1]);\r
+\r
+    g_pstGh3x2xProtocolData->puchPacketPayloadArr[UPROTOCOL_REPORT_EVENT_SET_RESP_INDEX] = UPROTOCOL_REPORT_EVENT_SET_SUCCESS;\r
+\r
+    /* respond packet format */\r
+    SET_VAL_VIA_PTR(pusRespondLen, GH3X2X_UprotocolPacketFormat(g_uchPacketCmd, puchRespondBuffer,\r
+                                g_pstGh3x2xProtocolData->puchPacketPayloadArr, UPROTOCOL_REPORT_EVENT_SET_RESP_LEN));\r
+}\r
+\r
+/**\r
+ * @fn     static void GH3X2X_UprotocolPackageTestCmd(GU8 *puchRespondBuffer, GU16 *pusRespondLen)\r
+ *\r
+ * @brief  handle test package\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]    None\r
+ * @param[out]   puchRespondBuffer    pointer to respond buffer\r
+ * @param[out]   pusRespondLen        pointer to respond length\r
+ *\r
+ * @return  None\r
+ */\r
+static void GH3X2X_UprotocolPackageTestCmd(GU8 *puchRespondBuffer, GU16 *pusRespondLen)\r
+{\r
+    GU8 uchPackageLen = g_pstGh3x2xProtocolData->puchPacketPayloadArr[0];\r
+\r
+    /* respond packet format */\r
+    SET_VAL_VIA_PTR(pusRespondLen, GH3X2X_UprotocolPacketFormat(g_uchPacketCmd, puchRespondBuffer,\r
+                                g_pstGh3x2xProtocolData->puchPacketPayloadArr, uchPackageLen));\r
+}\r
+\r
+/**\r
+ * @fn     static void GH3X2X_UprotocolEcgClassificationCmd(GU8 *puchRespondBuffer, GU16 *pusRespondLen)\r
+ *\r
+ * @brief  handle test package\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]    None\r
+ * @param[out]   puchRespondBuffer    pointer to respond buffer\r
+ * @param[out]   pusRespondLen        pointer to respond length\r
+ *\r
+ * @return  None\r
+ */\r
+extern GU8 GH3x2xEcgAlgoClassification(void);\r
+static void GH3X2X_UprotocolEcgClassificationCmd(GU8 *puchRespondBuffer, GU16 *pusRespondLen)\r
+{\r
+    //if (g_pstGh3x2xProtocolData->puchPacketPayloadArr[0] == 1)\r
+    {\r
+        g_pstGh3x2xProtocolData->puchPacketPayloadArr[UPROTOCOL_CONN_ECG_CLASSIFICATION_INDEX] = GH3x2xEcgAlgoClassification();\r
+        /* respond packet format */\r
+        SET_VAL_VIA_PTR(pusRespondLen, GH3X2X_UprotocolPacketFormat(g_uchPacketCmd, puchRespondBuffer,\r
+                                    g_pstGh3x2xProtocolData->puchPacketPayloadArr, UPROTOCOL_CONN_ECG_CLASSIFICATION_LEN));\r
+    }\r
+    //else if (puchRespondBuffer[0] == 2)\r
+    {\r
+        \r
+    }\r
+}\r
+static void GH3X2X_UprotocolEcgCascadeCmd(GU8 *puchRespondBuffer, GU16 *pusRespondLen)\r
+{\r
+    GU8 uchOpCmd = g_pstGh3x2xProtocolData->puchPacketPayloadArr[0];\r
+    switch (uchOpCmd)\r
+    {\r
+        //op0x01: set ecg cascade en; 1: enable, 0 :disable\r
+        case 0x01:\r
+            //GH3X2X_CascadeSetEcgEnFlag(g_pstGh3x2xProtocolData->puchPacketPayloadArr[1]);\r
+            GH3X2X_DEBUG_LOG_PARAM("pc set g_uchEcgCascadeEn:%d\r\n",GH3X2X_CascadeGetEcgEnFlag());\r
+            if(g_pstGh3x2xProtocolData->puchPacketPayloadArr[1])\r
+            {\r
+                Gh3x2xEnterCascadeMode();\r
+            }\r
+            else\r
+            {\r
+                Gh3x2xExitCascadeMode();\r
+            }\r
+            break;\r
+        case 0x02:\r
+            GH3X2X_CascadeSetLogicMasterChip(0);   //chip0\r
+            break;\r
+        case 0x03:\r
+            GH3X2X_CascadeSetLogicMasterChip(1);   //chip1\r
+            break;\r
+        default:\r
+            break;\r
+    }\r
+\r
+    /* respond packet format */\r
+    //SET_VAL_VIA_PTR(pusRespondLen, GH3X2X_UprotocolPacketFormat(g_uchPacketCmd, puchRespondBuffer,g_pstGh3x2xProtocolData->puchPacketPayloadArr, UPROTOCOL_CONN_ECG_CLASSIFICATION_LEN));\r
+}\r
+\r
+/**\r
+ * @fn     static void GH3X2X_UprotocolFpbpDataReceiveCmd(GU8 *puchRespondBuffer, GU16 *pusRespondLen)\r
+ *\r
+ * @brief  handle test package\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]    None\r
+ * @param[out]   puchRespondBuffer    pointer to respond buffer\r
+ * @param[out]   pusRespondLen        pointer to respond length\r
+ *\r
+ * @return  None\r
+ */\r
+void GH3X2X_UprotocolFpbpDataReceiveCmd(GU8 *puchRespondBuffer, GU16 *pusRespondLen)\r
+{\r
+    //GH3x2xBpAlgoInitSetting(g_pstGh3x2xProtocolData->puchPacketPayloadArr);\r
+\r
+    g_pstGh3x2xProtocolData->puchPacketPayloadArr[UPROTOCOL_REPORT_EVENT_SET_RESP_INDEX] = UPROTOCOL_REPORT_EVENT_SET_SUCCESS;\r
+    /* respond packet format */\r
+    SET_VAL_VIA_PTR(pusRespondLen, GH3X2X_UprotocolPacketFormat(g_uchPacketCmd, puchRespondBuffer,\r
+                                g_pstGh3x2xProtocolData->puchPacketPayloadArr, UPROTOCOL_WORK_MODE_RESP_LEN));\r
+}\r
+\r
+\r
+\r
+/**\r
+ * @fn     static EMUprotocolParseCmdType GH3X2X_UprotocolHandleEventReportAckCmd(GU8 *puchRespondBuffer,\r
+ *                                                  GU16 *pusRespondLen)\r
+ *\r
+ * @brief  handle event report cmd\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]    None\r
+ * @param[out]   puchRespondBuffer    pointer to respond buffer\r
+ * @param[out]   pusRespondLen        pointer to respond length\r
+ *\r
+ * @return  None\r
+ */\r
+static EMUprotocolParseCmdType GH3X2X_UprotocolHandleEventReportAckCmd(GU8 *puchRespondBuffer, GU16 *pusRespondLen)\r
+{\r
+    /*\r
+    EMUprotocolParseCmdType emUprotocolCmdType = UPROTOCOL_CMD_IGNORE;\r
+\r
+    if (g_uchEventReportIdReceive != g_pstGh3x2xProtocolData->puchPacketPayloadArr[UPROTOCOL_CHIP_EVENT_REPORT_ACK_INDEX])\r
+    {\r
+        if ((GU8)(g_uchEventReportId - 0x01) == g_pstGh3x2xProtocolData->puchPacketPayloadArr[UPROTOCOL_CHIP_EVENT_REPORT_ACK_INDEX])\r
+        {\r
+            emUprotocolCmdType = UPROTOCOL_CMD_IRQ_STATUS_REPORT_ACK;\r
+            g_uchEventReportIdReceive = g_pstGh3x2xProtocolData->puchPacketPayloadArr[UPROTOCOL_CHIP_EVENT_REPORT_ACK_INDEX];\r
+        }\r
+            \r
+        puchRespondBuffer[0] = g_pstGh3x2xProtocolData->puchPacketPayloadArr[UPROTOCOL_CHIP_EVENT_REPORT_ACK_INDEX];\r
+        puchRespondBuffer[1] = (GU8)(g_uchEventReportId - 0x01);\r
+    } \r
+    */\r
+    if(Gh3x2xGetProtocolEventReportId() == g_pstGh3x2xProtocolData->puchPacketPayloadArr[UPROTOCOL_CHIP_EVENT_REPORT_ACK_INDEX])\r
+    {\r
+        Gh3x2xSetProtocolEventAck();\r
+    }\r
+    SET_VAL_VIA_PTR(pusRespondLen, 0);\r
+    return UPROTOCOL_CMD_IGNORE;\r
+}\r
+\r
+\r
+\r
+extern void Gh3x2xSetProtocolEventAck(void);\r
+extern GU8 Gh3x2xGetProtocolEventReportId(void);\r
+\r
+\r
+/**\r
+ * @fn     static void GH3X2X_UprotocolHandleChipSetConnStaCmd(GU8 *puchRespondBuffer, GU16 *pusRespondLen)\r
+ *\r
+ * @brief  handle get chipset connect status cmd\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]    None\r
+ * @param[out]   puchRespondBuffer    pointer to respond buffer\r
+ * @param[out]   pusRespondLen        pointer to respond length\r
+ *\r
+ * @return  None\r
+ */\r
+static void GH3X2X_UprotocolHandleChipSetConnStaCmd(GU8 *puchRespondBuffer, GU16 *pusRespondLen)\r
+{\r
+    GU8 uchRet = UPROTOCOL_CONN_STA_FAIL;\r
+\r
+    GH3X2X_CHIP_WAKEUP_NORET();\r
+    if (GH3X2X_RET_OK == GH3X2X_CommunicateConfirm())\r
+    {\r
+        uchRet = UPROTOCOL_CONN_STA_SUCCESS;\r
+    }\r
+    GH3X2X_CHIP_SLEEP_NORET();\r
+    \r
+    g_pstGh3x2xProtocolData->puchPacketPayloadArr[UPROTOCOL_CONN_STA_RESP_INDEX] = uchRet;\r
+    \r
+    /* respond packet format */\r
+    SET_VAL_VIA_PTR(pusRespondLen, GH3X2X_UprotocolPacketFormat(g_uchPacketCmd, puchRespondBuffer,\r
+                                g_pstGh3x2xProtocolData->puchPacketPayloadArr, UPROTOCOL_CONN_STA_RESP_LEN));\r
+}\r
+\r
+/**\r
+ * @fn     EMUprotocolParseCmdType GH3X2X_UprotocolCmdHandler(GU8 *puchRespondBuffer, GU16 *pusRespondLen)\r
+ *\r
+ * @brief  handle all cmds\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]    None\r
+ * @param[out]   puchRespondBuffer    pointer to respond buffer\r
+ * @param[out]   pusRespondLen        pointer to respond length\r
+ *\r
+ * @return  @ref EMUprotocolParseCmdType\r
+ */\r
+EMUprotocolParseCmdType GH3X2X_UprotocolCmdHandler(GU8 *puchRespondBuffer, GU16 *pusRespondLen)\r
+{\r
+    EMUprotocolParseCmdType emUprotocolCmdType = UPROTOCOL_CMD_IGNORE;\r
+\r
+    GH3X2X_DEBUG_LOG_PARAM("%s\r\n", __FUNCTION__);\r
+    switch (g_uchPacketCmd)\r
+    {\r
+    case GH3X2X_UPROTOCOL_CMD_REG_RW:\r
+        GH3X2X_UprotocolHandleRegRwCmd(puchRespondBuffer, pusRespondLen);\r
+        break;\r
+\r
+    case GH3X2X_UPROTOCOL_CMD_GET_VER:\r
+        GH3X2X_UprotocolHandleGetVerCmd(puchRespondBuffer, pusRespondLen);\r
+        break;\r
+    case GH3X2X_UPROTOCOL_CMD_GET_OPENED_FUNC:\r
+        GH3X2X_UprotocolHandleGetOpenedFuncCmd(puchRespondBuffer, pusRespondLen);\r
+        break;\r
+    // case GH3X2X_UPROTOCOL_CMD_LOAD_CONFIG:\r
+    //     break;\r
+    case GH3X2X_UPROTOCOL_CMD_START_CTRL:\r
+        emUprotocolCmdType = GH3X2X_UprotocolHandleStartCtrlCmd(puchRespondBuffer, pusRespondLen);\r
+        break;\r
+    case GH3X2X_UPROTOCOL_CMD_WORK_MODE:\r
+        emUprotocolCmdType = GH3X2X_UprotocolHandleWorkModeCmd(puchRespondBuffer, pusRespondLen);\r
+        break;\r
+    case GH3X2X_UPROTOCOL_CMD_REPORT_EVENT_SET:\r
+        GH3X2X_UprotocolHandleReportEventSetCmd(puchRespondBuffer, pusRespondLen);\r
+        break;\r
+    case GH3X2X_UPROTOCOL_CMD_GET_CHIPSET_CONN_STA:\r
+        GH3X2X_UprotocolHandleChipSetConnStaCmd(puchRespondBuffer, pusRespondLen);\r
+        break;\r
+#if (GH3X2X_UPROTOCOL_FIFO_THR_CFG_CMD_SUP)\r
+    case GH3X2X_UPROTOCOL_CMD_FIFO_THR_CONFIG:\r
+        GH3X2X_UprotocolHandleFifoThrConfig(puchRespondBuffer, pusRespondLen);\r
+        break;\r
+#endif\r
+\r
+    // case GH3X2X_UPROTOCOL_CMD_FUNC_MAP:\r
+    //     break;\r
+    case GH3X2X_UPROTOCOL_CMD_CHIP_EVENT_REPORT:\r
+        emUprotocolCmdType = GH3X2X_UprotocolHandleEventReportAckCmd(puchRespondBuffer, pusRespondLen);\r
+        break;\r
+    case GH3X2X_UPROTOCOL_CMD_CHIP_CTRL:\r
+        GH3X2X_UprotocolHandleChipCtrl(puchRespondBuffer, pusRespondLen);\r
+        break;\r
+\r
+    case GH3X2X_UPROTOCOL_CMD_GET_MAX_LEN:\r
+        GH3X2X_UprotocolHandleGetSupprtLenCmd(puchRespondBuffer, pusRespondLen);\r
+        break;\r
+    case GH3X2X_UPROTOCOL_CMD_SWITCH_SLOT_FUNC:\r
+        emUprotocolCmdType = GH3X2X_UprotocolHandleSwFunctionCmd(puchRespondBuffer, pusRespondLen);\r
+        break;\r
+    case GH3X2X_UPROTOCOL_CMD_LOAD_REG_LIST:\r
+        GH3X2X_UprotocolHandleLoadRegListCmd(puchRespondBuffer, pusRespondLen);\r
+        break;\r
+\r
+    case GH3X2X_UPROTOCOL_CMD_DEBUG_STATUS:\r
+        GH3X2X_UprotocolHandleDebugStatusCmd(puchRespondBuffer, pusRespondLen);\r
+        break;\r
+\r
+    case GH3X2X_UPROTOCOL_CMD_PACKAGE_TEST:\r
+        GH3X2X_UprotocolPackageTestCmd(puchRespondBuffer, pusRespondLen);\r
+        break;\r
+\r
+    case GH3X2X_UPROTOCOL_CMD_ECG_CLASSIFICATION:\r
+        GH3X2X_UprotocolEcgClassificationCmd(puchRespondBuffer, pusRespondLen);\r
+        break;\r
+    case GH3X2X_UPROTOCOL_CMD_SET_ECG_CASCADE:\r
+        GH3X2X_UprotocolEcgCascadeCmd(puchRespondBuffer, pusRespondLen);\r
+        break;\r
+    case GH3X2X_UPROTOCOL_CMD_BP_DATA_TRANS:\r
+        GH3X2X_UprotocolFpbpDataReceiveCmd(puchRespondBuffer, pusRespondLen);\r
+        break;\r
+\r
+    default:\r
+        GH3X2X_DEBUG_LOG_PARAM("unsupported cmd error!\r\n");\r
+\r
+        /* respond packet format */\r
+        SET_VAL_VIA_PTR(pusRespondLen, GH3X2X_UprotocolPacketFormat(g_uchPacketCmd, puchRespondBuffer,\r
+                                            g_pstGh3x2xProtocolData->puchPacketPayloadArr, 0));\r
+        break;\r
+    } // end of switch (g_uchPacketCmd)\r
+    return emUprotocolCmdType;\r
+}\r
+\r
+/**\r
+ * @fn     EMUprotocolParseCmdType GH3X2X_UprotocolParseHandler(GU8 *puchRespondBuffer, GU16 *pusRespondLen,\r
+ *                                                     GU8 *puchRecvDataBuffer, GU16 usRecvLen)\r
+ *\r
+ * @brief  universal protocol parse handler, parse protocol receive data\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[out]   puchRespondBuffer    pointer to respond buffer\r
+ * @param[out]   pusRespondLen        pointer to respond length\r
+ * @param[in]    puchRecvDataBuffer   pointer to receive data buffer\r
+ * @param[in]    usRecvLen            receive data len\r
+ *\r
+ * @return  @ref EMUprotocolParseCmdType\r
+ */\r
+EMUprotocolParseCmdType GH3X2X_UprotocolParseHandler(GU8 *puchRespondBuffer, GU16 *pusRespondLen,\r
+                                                     GU8 *puchRecvDataBuffer, GU16 usRecvLen)\r
+{\r
+    EMUprotocolParseCmdType emUprotocolCmdType = UPROTOCOL_CMD_IGNORE;\r
+    GU16 usParseIndex = 0;\r
+    GU16 usHasParseLenOfBuffer = 0;\r
+    GU16 usRespondIndex = 0;\r
+    GU16 usCmdRespondLen = 0;\r
+\r
+    GH3X2X_DEBUG_LOG_PARAM("%s\r\n", __FUNCTION__);\r
+    while (usParseIndex < usRecvLen)\r
+    {\r
+        if (GH3X2X_UprotocolParseBuffer(&usHasParseLenOfBuffer, &puchRecvDataBuffer[usParseIndex],\r
+                                        usRecvLen - usParseIndex) == GH3X2X_RET_OK)\r
+        {\r
+            emUprotocolCmdType = GH3X2X_UprotocolCmdHandler(&puchRespondBuffer[usRespondIndex], &usCmdRespondLen);\r
+            usRespondIndex += usCmdRespondLen;\r
+        }\r
+        else\r
+        {\r
+            if (g_emPacketParseStatus == UPROTOCOL_STATUS_IDLE)\r
+            {\r
+                GH3X2X_DEBUG_LOG_PARAM("protocol parse buffer error!");\r
+            }\r
+        }\r
+        usParseIndex += usHasParseLenOfBuffer;\r
+    } // end while (usParseIndex < usRecvLen)\r
+\r
+    SET_VAL_VIA_PTR(pusRespondLen, usRespondIndex);\r
+\r
+    return emUprotocolCmdType;\r
+}\r
+\r
+/**\r
+ * @fn     GU8 GH3X2X_UprotocolPacketMaxLenConfig(GU8 uchPacketMaxLen)\r
+ *\r
+ * @brief  packet max len support, default len is 243\r
+ *\r
+ * @attention   uchPacketMaxLen val must at [20, 243]\r
+ *\r
+ * @param[out]   None\r
+ * @param[in]    uchPacketMaxLen      packet max len\r
+ *\r
+ * @return  packet max len after config\r
+ */\r
+GU8 GH3X2X_UprotocolPacketMaxLenConfig(GU8 uchPacketMaxLen)\r
+{\r
+    GH3X2X_DEBUG_LOG_PARAM("%s\r\n", __FUNCTION__);\r
+\r
+    if (uchPacketMaxLen < GH3X2X_UPROTOCOL_PACKET_LEN_MIN)\r
+    {\r
+        g_uchPacketMaxLenSupport = GH3X2X_UPROTOCOL_PACKET_LEN_MIN;\r
+    }\r
+    else if (uchPacketMaxLen > GH3X2X_UPROTOCOL_PACKET_LEN_MAX)\r
+    {\r
+        g_uchPacketMaxLenSupport = GH3X2X_UPROTOCOL_PACKET_LEN_MAX;\r
+    }\r
+    else\r
+    {\r
+        g_uchPacketMaxLenSupport = uchPacketMaxLen;\r
+    }\r
+\r
+    return g_uchPacketMaxLenSupport;\r
+}\r
+\r
+/**\r
+ * @fn       void GH3X2X_FillGsensorData(GU16* pusPayloadIndex, STGsensorRawdata* pstGsAxisValue, \r
+ *                                        )\r
+ *d\r
+ * @brief  fill g sensor data to protocol data\r
+ *\r
+ * @attention    None\r
+ *\r
+ * @param[in]    pstGsAxisValue       g sensor data\r
+ * @param[out]   pusPayloadIndex      current index of payload\r
+ *\r
+ * @return    None\r
+ */\r
+#if 0\r
+void GH3X2X_FillGsensorData(GU16* pusPayloadIndex, STGsensorRawdata* pstGsAxisValue)\r
+{\r
+    //GS16 sGsensorRightShift = (1 << emGsSensitivity);\r
+    STGsensorRawdata stGsensorData = *pstGsAxisValue;\r
+\r
+    //stGsensorData.sXAxisVal = (GS16)(stGsensorData.sXAxisVal / sGsensorRightShift);\r
+    //stGsensorData.sYAxisVal = (GS16)(stGsensorData.sYAxisVal / sGsensorRightShift);\r
+    //stGsensorData.sZAxisVal = (GS16)(stGsensorData.sZAxisVal / sGsensorRightShift);\r
+    g_pstGh3x2xProtocolData->puchPacketPayloadArr[*pusPayloadIndex] = GH3X2X_GET_HIGH_BYTE_FROM_WORD(stGsensorData.sXAxisVal); //gs\r
+    *pusPayloadIndex += 1;\r
+    g_pstGh3x2xProtocolData->puchPacketPayloadArr[*pusPayloadIndex] = GH3X2X_GET_LOW_BYTE_FROM_WORD(stGsensorData.sXAxisVal);\r
+    *pusPayloadIndex += 1;\r
+    g_pstGh3x2xProtocolData->puchPacketPayloadArr[*pusPayloadIndex] = GH3X2X_GET_HIGH_BYTE_FROM_WORD(stGsensorData.sYAxisVal);\r
+    *pusPayloadIndex += 1;\r
+    g_pstGh3x2xProtocolData->puchPacketPayloadArr[*pusPayloadIndex] = GH3X2X_GET_LOW_BYTE_FROM_WORD(stGsensorData.sYAxisVal);\r
+    *pusPayloadIndex += 1;\r
+    g_pstGh3x2xProtocolData->puchPacketPayloadArr[*pusPayloadIndex] = GH3X2X_GET_HIGH_BYTE_FROM_WORD(stGsensorData.sZAxisVal);\r
+    *pusPayloadIndex += 1;\r
+    g_pstGh3x2xProtocolData->puchPacketPayloadArr[*pusPayloadIndex] = GH3X2X_GET_LOW_BYTE_FROM_WORD(stGsensorData.sZAxisVal);\r
+    *pusPayloadIndex += 1;\r
+}\r
+#endif\r
+/**\r
+ * @fn       void GH3X2X_FillAlgoData(GU16* pusPayloadIndex, GS32 nAlgoCalcResultArr[], GU8 uchAlgoResNum)\r
+ *\r
+ * @brief  fill algorithm data to protocol data\r
+ *\r
+ * @attention    None\r
+ *\r
+ * @param[in]    nAlgoCalcResultArr  pointer to algorithm result\r
+ * @param[in]    uchAlgoResNum       algorithm data num\r
+ * @param[out]   pusPayloadIndex     current index of payload\r
+ *\r
+ * @return    None\r
+ */\r
+void GH3X2X_FillAlgoData(GU16* pusPayloadIndex, GS32 nAlgoCalcResultArr[], GU8 uchAlgoResNum)\r
+{\r
+    GU8  uchAlgoCnt    = 0;  \r
+    GU8  uchResTagData = 0;\r
+    uchResTagData = GH3X2X_GET_LEFT_SHIFT_VAL(UPROTOCOL_RESULT_TYPE_BIT_FIELD);\r
+    for (uchAlgoCnt = 0; uchAlgoCnt < uchAlgoResNum; uchAlgoCnt++)\r
+    {\r
+        g_pstGh3x2xProtocolData->puchPacketPayloadArr[*pusPayloadIndex] = GH3X2X_SET_BIT(uchResTagData, uchAlgoCnt);\r
+        *pusPayloadIndex += 1;\r
+        g_pstGh3x2xProtocolData->puchPacketPayloadArr[*pusPayloadIndex] = GH3X2X_GET_BYTE0_FROM_DWORD(nAlgoCalcResultArr[uchAlgoCnt]);\r
+        *pusPayloadIndex += 1;\r
+        g_pstGh3x2xProtocolData->puchPacketPayloadArr[*pusPayloadIndex] = GH3X2X_GET_BYTE1_FROM_DWORD(nAlgoCalcResultArr[uchAlgoCnt]);\r
+        *pusPayloadIndex += 1;\r
+        g_pstGh3x2xProtocolData->puchPacketPayloadArr[*pusPayloadIndex] = GH3X2X_GET_BYTE2_FROM_DWORD(nAlgoCalcResultArr[uchAlgoCnt]);\r
+        *pusPayloadIndex += 1;\r
+        g_pstGh3x2xProtocolData->puchPacketPayloadArr[*pusPayloadIndex] = GH3X2X_GET_BYTE3_FROM_DWORD(nAlgoCalcResultArr[uchAlgoCnt]);\r
+        *pusPayloadIndex += 1;\r
+    }\r
+}\r
+\r
+#if GH3X2X_ELECTRO_RRECER_OBSERVE_EN\r
+\r
+\r
+/**\r
+ * @fn       void GH3X2X_FillElectrodeWearRevertData(GU16* pusPayloadIndex)\r
+ *\r
+ * @brief  fill electrode wear revert data to protocol data buf\r
+ *\r
+ * @attention    None\r
+ *\r
+ * @param[in]    pusPayloadIndex      current index of payload\r
+ * @param[out]   None\r
+ *\r
+ * @return    None\r
+ */\r
+void GH3X2X_FillElectrodeWearRevertData(GU16* pusPayloadIndex)\r
+{\r
+    GU8  uchTagData = 0;\r
+    GU32 unWearRevertCnt = 0;\r
+    GH3X2X_VAL_CLEAR_LEFT_BIT(uchTagData, (GU8)UPROTOCOL_RESULT_TYPE_BIT_FIELD);\r
+    GH3X2X_VAL_SET_BIT(uchTagData, UPROTOCOL_UPLOAD_FLAG_INDEX3);\r
+    unWearRevertCnt = GH3X2X_GetAndClearElectrodeWearRevCnt();\r
+    g_pstGh3x2xProtocolData->puchPacketPayloadArr[*pusPayloadIndex] = uchTagData;\r
+    *pusPayloadIndex += 1;\r
+    g_pstGh3x2xProtocolData->puchPacketPayloadArr[*pusPayloadIndex] = GH3X2X_GET_BYTE0_FROM_DWORD(unWearRevertCnt);\r
+    *pusPayloadIndex += 1;\r
+    g_pstGh3x2xProtocolData->puchPacketPayloadArr[*pusPayloadIndex] = GH3X2X_GET_BYTE1_FROM_DWORD(unWearRevertCnt);\r
+    *pusPayloadIndex += 1;\r
+    g_pstGh3x2xProtocolData->puchPacketPayloadArr[*pusPayloadIndex] = GH3X2X_GET_BYTE2_FROM_DWORD(unWearRevertCnt);\r
+    *pusPayloadIndex += 1;\r
+    g_pstGh3x2xProtocolData->puchPacketPayloadArr[*pusPayloadIndex] = GH3X2X_GET_BYTE3_FROM_DWORD(unWearRevertCnt);\r
+    *pusPayloadIndex += 1;\r
+}\r
+\r
+#endif\r
+\r
+void GH3x2xSendFunctionInfo(const STGh3x2xFrameInfo * const pstFrameInfo)\r
+{\r
+    if ((*(pstFrameInfo->punFrameCnt)) == 0)\r
+    {\r
+        GU8 uchFunctionInfoBufferLen = 0;\r
+        GU8 *puchUploadBuf = g_pstGh3x2xProtocolData->puchPacketPayloadArr + 4;\r
+        GU8 uchFunctionIDForMaster = 0;\r
+\r
+        for (int uchOffsetCnt = 0 ; uchOffsetCnt < GH3X2X_FUNC_OFFSET_MAX ; uchOffsetCnt ++)\r
+        {\r
+            if ((pstFrameInfo->unFunctionID >> uchOffsetCnt) & 0x1)\r
+            {\r
+                uchFunctionIDForMaster = uchOffsetCnt;\r
+            }\r
+        }\r
+        puchUploadBuf[uchFunctionInfoBufferLen] = uchFunctionIDForMaster;\r
+        uchFunctionInfoBufferLen += 1;\r
+\r
+        GH3X2X_Memcpy(&puchUploadBuf[uchFunctionInfoBufferLen], pstFrameInfo->pstFunctionInfo, sizeof(STGh3x2xFunctionInfo));\r
+        uchFunctionInfoBufferLen += sizeof(STGh3x2xFunctionInfo);\r
+\r
+        GH3X2X_Memcpy(&puchUploadBuf[uchFunctionInfoBufferLen], pstFrameInfo->pchChnlMap, pstFrameInfo->pstFunctionInfo->uchChnlNum * sizeof(GU8));\r
+        uchFunctionInfoBufferLen += pstFrameInfo->pstFunctionInfo->uchChnlNum * sizeof(GU8);\r
+        \r
+        GU16 usRespondLen = GH3X2X_UprotocolPacketFormat(GH3X2X_UPROTOCOL_CMD_FUNCTION_INFO_UPDATE, puchUploadBuf - 4,\r
+                            puchUploadBuf, uchFunctionInfoBufferLen);\r
+        Gh3x2xDemoSendProtocolData(puchUploadBuf, usRespondLen);\r
+    }\r
+}\r
+\r
+void Gh2x2xPackPakcageHeader(GU8 *puchNeedContinue, GU8 uchFunctionIDForMaster, GU8 *puchUploadBuf, GU8 *puchTagArray,\r
+                                            GU8 uchGsEnable, GU8 uchAlgoResFlag, GU8 uchAgcEnable, GU8 uchAmbEnable, GU8 uchGsGyroEnable,GU8 uchCapEnable,GU8 uchTempEnable,\r
+                                            GU8 uchZipEnableFlag, GU8 uchOddEvenChangeFlag)\r
+{\r
+    *puchNeedContinue = 0;\r
+    g_uchGh3x2xUploadBufUse = 0;\r
+    g_uchGh3x2xUploadStatus = GH3X2X_UPLOAD_STATUS_HAVE_STORE_DATA;\r
+\r
+    //section DATA_TYPE\r
+    puchUploadBuf[UPROTOCOL_FUNCTION_ID_INDEX] = uchFunctionIDForMaster;\r
+    g_uchGh3x2xUploadBufUse ++;\r
+    puchUploadBuf[UPROTOCOL_RAWDATA_TYPE_INDEX] = \\r
+                                            GH3X2X_VAL_LEFT_SHIFT(uchGsEnable, UPROTOCOL_GS_ENABLE_FIELD)\r
+                                            | GH3X2X_VAL_LEFT_SHIFT(uchAlgoResFlag, UPROTOCOL_ALGO_ENABLE_FIELD)\r
+                                            | GH3X2X_VAL_LEFT_SHIFT(uchAgcEnable, UPROTOCOL_AGC_ENABLE_FIELD)\r
+                                            | GH3X2X_VAL_LEFT_SHIFT(uchAmbEnable, UPROTOCOL_AMBIANCE_ENABLE_FIELD)\r
+                                            | GH3X2X_VAL_LEFT_SHIFT(uchGsGyroEnable,UPROTOCOL_GS_GYRO_ENABLE_FIELD)\r
+                                            | GH3X2X_VAL_LEFT_SHIFT(uchCapEnable,UPROTOCOL_CAP_ENABLE_ENABLE_FIELD)\r
+                                            | GH3X2X_VAL_LEFT_SHIFT(uchTempEnable,UPROTOCOL_TEMP_ENABLE_ENABLE_FIELD);\r
+\r
+    g_uchGh3x2xUploadBufUse ++;\r
+\r
+    GU32 unCompeletMask = 0;\r
+    for (GU32 unCnt = 0 ; unCnt < 32 ; unCnt ++)\r
+    {\r
+        if (puchTagArray[unCnt] != 0xFF)\r
+        {\r
+            unCompeletMask |= (1 << unCnt);\r
+        }\r
+    }\r
+\r
+    //chnl num\r
+    puchUploadBuf[UPROTOCOL_RAWDATA_CHNL_NUM] = (unCompeletMask >> 24) & 0xFF;\r
+    puchUploadBuf[UPROTOCOL_RAWDATA_CHNL_NUM + 1] = (unCompeletMask >> 16) & 0xFF;\r
+    puchUploadBuf[UPROTOCOL_RAWDATA_CHNL_NUM + 2] = (unCompeletMask >> 8) & 0xFF;\r
+    puchUploadBuf[UPROTOCOL_RAWDATA_CHNL_NUM + 3] = (unCompeletMask) & 0xFF;\r
+    g_uchGh3x2xUploadBufUse += 4;\r
+\r
+    //pack type flag\r
+    puchUploadBuf[UPROTOCOL_PACKAGE_TYPE_INDEX] = \\r
+                                            GH3X2X_VAL_LEFT_SHIFT(uchZipEnableFlag, UPROTOCOL_ZIP_ENABLE_FIELD)\r
+                                            | GH3X2X_VAL_LEFT_SHIFT(uchOddEvenChangeFlag, UPROTOCOL_ODDEVEN_FLAG_FIELD)\r
+                                            | GH3X2X_VAL_LEFT_SHIFT(GH3X2X_GetFifoPackageMode(), UPROTOCOL_FUNCTION_MODE_FIELD);\r
+    g_uchGh3x2xUploadBufUse ++;\r
+\r
+    //section DATA_LEN\r
+    puchUploadBuf[UPROTOCOL_RAWDATA_LEN_INDEX] = 0;\r
+    g_uchGh3x2xUploadBufUse ++;\r
+}\r
+\r
+#if (__SUPPORT_PROTOCOL_ANALYZE__)\r
+void Gh2x2xUploadDataToMaster(const STGh3x2xFrameInfo * const pstFrameInfo, GU16 usFrameCnt, GU16 usFrameNum, GU8* puchTagArray)\r
+{\r
+    GU8  uchChnlNum;\r
+    GU32 unFunctionID;\r
+    GU8  uchFunctionIDForMaster = 0xFF;\r
+    GU8  uchGsEnable;\r
+    GU8  uchGsGyroEnable;\r
+    GU8  uchCapEnable;\r
+    GU8  uchTempEnable;\r
+    GU8  uchAgcEnable;\r
+    GU8  uchAmbEnable;\r
+    GU8  uchAlgoResFlag;\r
+    GU16 uchOneFrameByteNum;\r
+    GU8  uchReslutByteNum;\r
+    GU8  uchNeedContinue;\r
+    GU8  *puchUploadBuf = g_pstGh3x2xProtocolData->puchPacketPayloadArr + 4;\r
+    GU16 usRespondLen;\r
+    GU8 uchFramePosi;\r
+    if(0 == pstFrameInfo)\r
+    {\r
+        return;\r
+    }\r
+    unFunctionID = pstFrameInfo->unFunctionID;\r
+    uchChnlNum = pstFrameInfo->pstFunctionInfo->uchChnlNum;\r
+    uchFramePosi = 0;\r
+    if(0 == usFrameCnt)\r
+    {\r
+        uchFramePosi |= GH3X2X_FRAME_POSI_HEAD;\r
+    }\r
+    if((usFrameNum - 1) == usFrameCnt)\r
+    {\r
+        uchFramePosi |= GH3X2X_FRAME_POSI_TAIL;\r
+    }\r
+    if((GH3X2X_FUNCTION_SOFT_ADT_GREEN | GH3X2X_FUNCTION_SOFT_ADT_IR) & unFunctionID)\r
+    {\r
+        //return;\r
+    }\r
+\r
+    //function id transform\r
+    for (int uchOffsetCnt = 0 ; uchOffsetCnt < GH3X2X_FUNC_OFFSET_MAX ; uchOffsetCnt ++)\r
+    {\r
+        if ((unFunctionID >> uchOffsetCnt) & 0x1)\r
+        {\r
+            uchFunctionIDForMaster = uchOffsetCnt;\r
+        }\r
+    }\r
+\r
+    if(0xFF == uchFunctionIDForMaster)  //invalid function id\r
+    {\r
+        return;\r
+    }\r
+    uchGsEnable = g_uchGsensorEnable;\r
+    uchGsGyroEnable = (g_uchGyroEnable & uchGsEnable);\r
+    uchCapEnable =  GH3X2X_GetCapEnableFlag();\r
+    uchTempEnable = GH3X2X_GetTempEnableFlag();\r
+    uchAgcEnable = 1;\r
+    if(unFunctionID == GH3X2X_FUNC_OFFSET_ECG)\r
+    {\r
+        uchAgcEnable = 0;\r
+    }\r
+    uchAmbEnable = 0;\r
+    uchAlgoResFlag = 1;\r
+\r
+    /********  calculate how many bytes in one frame  ******/\r
+    uchOneFrameByteNum = 0;\r
+    //section FRAME_ID\r
+    uchOneFrameByteNum += 1;\r
+    //section GSENSOR_DATA\r
+    if(uchGsEnable)\r
+    {\r
+        uchOneFrameByteNum += 6;\r
+    }\r
+    if(uchGsEnable && uchGsGyroEnable)\r
+    {\r
+        uchOneFrameByteNum += 6;\r
+    }\r
+\r
+    //section Cap and temp\r
+    if(uchCapEnable)\r
+    {\r
+        uchOneFrameByteNum += 12;\r
+    }\r
+    if(uchTempEnable)\r
+    {\r
+        uchOneFrameByteNum += 12;\r
+    }\r
+\r
+    //section RAWDATA\r
+    if (g_uchFifoPackageMode)\r
+    {\r
+        uchOneFrameByteNum ++;\r
+    }\r
+    else\r
+    {\r
+        uchOneFrameByteNum += uchChnlNum*4;\r
+    }\r
+    //section AGC_INFO\r
+    if(uchAgcEnable)\r
+    {\r
+        uchOneFrameByteNum += uchChnlNum*4;\r
+    }\r
+    //section RESLUT\r
+    //result byte num\r
+    uchReslutByteNum = 0;\r
+    uchOneFrameByteNum += 1;\r
+    uchReslutByteNum += 1;\r
+    //FLAG 2\r
+    uchOneFrameByteNum += 5;\r
+    uchReslutByteNum += 5;\r
+    //FLAG 3 (need upload on only first frame)\r
+    if(uchFramePosi&GH3X2X_FRAME_POSI_HEAD)\r
+    {\r
+        uchOneFrameByteNum += 5;\r
+        uchReslutByteNum += 5;\r
+    }\r
+    if (uchAlgoResFlag && 1 == pstFrameInfo->pstAlgoResult->uchUpdateFlag)\r
+    {\r
+        uchOneFrameByteNum += (5*pstFrameInfo->pstAlgoResult->uchResultNum);\r
+        uchReslutByteNum += (5*pstFrameInfo->pstAlgoResult->uchResultNum);\r
+    }\r
+\r
+    #if GH3X2X_DIVIDE_ZERO_FLAG_UPLODE_EN\r
+    //flag4\r
+    uchOneFrameByteNum += 5;\r
+    uchReslutByteNum += 5;\r
+    #endif\r
+\r
+    GH3x2xSendFunctionInfo(pstFrameInfo);  //send function info when first frame\r
+    \r
+    uchNeedContinue = 1;\r
+    while(uchNeedContinue)\r
+    {\r
+        if(GH3X2X_UPLOAD_STATUS_NULL == g_uchGh3x2xUploadStatus)\r
+        {\r
+            Gh2x2xPackPakcageHeader(&uchNeedContinue, uchFunctionIDForMaster,\\r
+                                    puchUploadBuf, puchTagArray, uchGsEnable, uchAlgoResFlag,\\r
+                                    uchAgcEnable, uchAmbEnable, uchGsGyroEnable,uchCapEnable,uchTempEnable, 0, 0);\r
+        }\r
+        if(GH3X2X_UPLOAD_STATUS_HAVE_STORE_DATA == g_uchGh3x2xUploadStatus)\r
+        {\r
+            if(((GU16)g_uchGh3x2xUploadBufUse + uchOneFrameByteNum) >= GH3X2X_UPROTOCOL_GET_PAYLOAD_LEN_SUPPORT(g_uchPacketMaxLenSupport))  //can not store more data\r
+            {\r
+                //send data\r
+                usRespondLen = GH3X2X_UprotocolPacketFormat(GH3X2X_UPROTOCOL_CMD_NEW_STRUCT_RAWDATA, puchUploadBuf - 4,\r
+                                    puchUploadBuf, g_uchGh3x2xUploadBufUse);\r
+                Gh3x2xDemoSendProtocolData(puchUploadBuf - 4,usRespondLen);\r
+                \r
+                \r
+                g_uchGh3x2xUploadStatus = GH3X2X_UPLOAD_STATUS_NULL;\r
+                continue;\r
+            }\r
+            else\r
+            {\r
+                uchNeedContinue = 0;\r
+                puchUploadBuf[UPROTOCOL_RAWDATA_LEN_INDEX] += uchOneFrameByteNum;\r
+                    \r
+                //section FRAME_ID\r
+                puchUploadBuf[g_uchGh3x2xUploadBufUse] = ((*(pstFrameInfo->punFrameCnt))&0x000000FF);\r
+                g_uchGh3x2xUploadBufUse ++;\r
+                //section GSENSOR_DATA\r
+                if(uchGsEnable)\r
+                {\r
+                    GS16 *psGsensorData;\r
+                    psGsensorData = pstFrameInfo->pusFrameGsensordata;\r
+                    puchUploadBuf[g_uchGh3x2xUploadBufUse] = GH3X2X_GET_HIGH_BYTE_FROM_WORD(psGsensorData[0]); //gsx\r
+                    g_uchGh3x2xUploadBufUse += 1;\r
+                    puchUploadBuf[g_uchGh3x2xUploadBufUse] = GH3X2X_GET_LOW_BYTE_FROM_WORD(psGsensorData[0]);\r
+                    g_uchGh3x2xUploadBufUse += 1;\r
+                    \r
+                    puchUploadBuf[g_uchGh3x2xUploadBufUse] = GH3X2X_GET_HIGH_BYTE_FROM_WORD(psGsensorData[1]); //gsy\r
+                    g_uchGh3x2xUploadBufUse += 1;\r
+                    puchUploadBuf[g_uchGh3x2xUploadBufUse] = GH3X2X_GET_LOW_BYTE_FROM_WORD(psGsensorData[1]);\r
+                    g_uchGh3x2xUploadBufUse += 1;\r
+                    \r
+                    puchUploadBuf[g_uchGh3x2xUploadBufUse] = GH3X2X_GET_HIGH_BYTE_FROM_WORD(psGsensorData[2]); //gsz\r
+                    g_uchGh3x2xUploadBufUse += 1;\r
+                    puchUploadBuf[g_uchGh3x2xUploadBufUse] = GH3X2X_GET_LOW_BYTE_FROM_WORD(psGsensorData[2]);\r
+                    g_uchGh3x2xUploadBufUse += 1;\r
+                    if(uchGsGyroEnable)\r
+                    {\r
+                        puchUploadBuf[g_uchGh3x2xUploadBufUse] = GH3X2X_GET_HIGH_BYTE_FROM_WORD(psGsensorData[3]); //gyrox\r
+                        g_uchGh3x2xUploadBufUse += 1;\r
+                        puchUploadBuf[g_uchGh3x2xUploadBufUse] = GH3X2X_GET_LOW_BYTE_FROM_WORD(psGsensorData[3]);\r
+                        g_uchGh3x2xUploadBufUse += 1;\r
+                        \r
+                        puchUploadBuf[g_uchGh3x2xUploadBufUse] = GH3X2X_GET_HIGH_BYTE_FROM_WORD(psGsensorData[4]); //gyroy\r
+                        g_uchGh3x2xUploadBufUse += 1;\r
+                        puchUploadBuf[g_uchGh3x2xUploadBufUse] = GH3X2X_GET_LOW_BYTE_FROM_WORD(psGsensorData[4]);\r
+                        g_uchGh3x2xUploadBufUse += 1;\r
+                        \r
+                        puchUploadBuf[g_uchGh3x2xUploadBufUse] = GH3X2X_GET_HIGH_BYTE_FROM_WORD(psGsensorData[5]); //gyroz\r
+                        g_uchGh3x2xUploadBufUse += 1;\r
+                        puchUploadBuf[g_uchGh3x2xUploadBufUse] = GH3X2X_GET_LOW_BYTE_FROM_WORD(psGsensorData[5]);\r
+                        g_uchGh3x2xUploadBufUse += 1;\r
+                    }\r
+                }\r
+                //section Cap and Temp\r
+                if(uchCapEnable)\r
+                {\r
+\r
+                    puchUploadBuf[g_uchGh3x2xUploadBufUse] = GH3X2X_GET_BYTE2_FROM_DWORD(pstFrameInfo->pstFrameCapdata->unCapData[0]); \r
+                    g_uchGh3x2xUploadBufUse += 1;\r
+                    puchUploadBuf[g_uchGh3x2xUploadBufUse] = GH3X2X_GET_BYTE1_FROM_DWORD(pstFrameInfo->pstFrameCapdata->unCapData[0]); \r
+                    g_uchGh3x2xUploadBufUse += 1;\r
+                    puchUploadBuf[g_uchGh3x2xUploadBufUse] = GH3X2X_GET_BYTE0_FROM_DWORD(pstFrameInfo->pstFrameCapdata->unCapData[0]); \r
+                    g_uchGh3x2xUploadBufUse += 1;\r
+                    \r
+                    puchUploadBuf[g_uchGh3x2xUploadBufUse] = GH3X2X_GET_BYTE2_FROM_DWORD(pstFrameInfo->pstFrameCapdata->unCapData[1]); \r
+                    g_uchGh3x2xUploadBufUse += 1;\r
+                    puchUploadBuf[g_uchGh3x2xUploadBufUse] = GH3X2X_GET_BYTE1_FROM_DWORD(pstFrameInfo->pstFrameCapdata->unCapData[1]); \r
+                    g_uchGh3x2xUploadBufUse += 1;\r
+                    puchUploadBuf[g_uchGh3x2xUploadBufUse] = GH3X2X_GET_BYTE0_FROM_DWORD(pstFrameInfo->pstFrameCapdata->unCapData[1]); \r
+                    g_uchGh3x2xUploadBufUse += 1;\r
+\r
+                    puchUploadBuf[g_uchGh3x2xUploadBufUse] = GH3X2X_GET_BYTE2_FROM_DWORD(pstFrameInfo->pstFrameCapdata->unCapData[2]); \r
+                    g_uchGh3x2xUploadBufUse += 1;\r
+                    puchUploadBuf[g_uchGh3x2xUploadBufUse] = GH3X2X_GET_BYTE1_FROM_DWORD(pstFrameInfo->pstFrameCapdata->unCapData[2]); \r
+                    g_uchGh3x2xUploadBufUse += 1;\r
+                    puchUploadBuf[g_uchGh3x2xUploadBufUse] = GH3X2X_GET_BYTE0_FROM_DWORD(pstFrameInfo->pstFrameCapdata->unCapData[2]); \r
+                    g_uchGh3x2xUploadBufUse += 1;\r
+\r
+                    puchUploadBuf[g_uchGh3x2xUploadBufUse] = GH3X2X_GET_BYTE2_FROM_DWORD(pstFrameInfo->pstFrameCapdata->unCapData[3]); \r
+                    g_uchGh3x2xUploadBufUse += 1;\r
+                    puchUploadBuf[g_uchGh3x2xUploadBufUse] = GH3X2X_GET_BYTE1_FROM_DWORD(pstFrameInfo->pstFrameCapdata->unCapData[3]); \r
+                    g_uchGh3x2xUploadBufUse += 1;\r
+                    puchUploadBuf[g_uchGh3x2xUploadBufUse] = GH3X2X_GET_BYTE0_FROM_DWORD(pstFrameInfo->pstFrameCapdata->unCapData[3]); \r
+                    g_uchGh3x2xUploadBufUse += 1;\r
+\r
+                }\r
+                if(uchTempEnable)\r
+                {\r
+                    puchUploadBuf[g_uchGh3x2xUploadBufUse] = GH3X2X_GET_BYTE2_FROM_DWORD(pstFrameInfo->pstFrameTempdata->unTempData[0]); \r
+                    g_uchGh3x2xUploadBufUse += 1;\r
+                    puchUploadBuf[g_uchGh3x2xUploadBufUse] = GH3X2X_GET_BYTE1_FROM_DWORD(pstFrameInfo->pstFrameTempdata->unTempData[0]); \r
+                    g_uchGh3x2xUploadBufUse += 1;\r
+                    puchUploadBuf[g_uchGh3x2xUploadBufUse] = GH3X2X_GET_BYTE0_FROM_DWORD(pstFrameInfo->pstFrameTempdata->unTempData[0]); \r
+                    g_uchGh3x2xUploadBufUse += 1;\r
+                    \r
+                    puchUploadBuf[g_uchGh3x2xUploadBufUse] = GH3X2X_GET_BYTE2_FROM_DWORD(pstFrameInfo->pstFrameTempdata->unTempData[1]); \r
+                    g_uchGh3x2xUploadBufUse += 1;\r
+                    puchUploadBuf[g_uchGh3x2xUploadBufUse] = GH3X2X_GET_BYTE1_FROM_DWORD(pstFrameInfo->pstFrameTempdata->unTempData[1]); \r
+                    g_uchGh3x2xUploadBufUse += 1;\r
+                    puchUploadBuf[g_uchGh3x2xUploadBufUse] = GH3X2X_GET_BYTE0_FROM_DWORD(pstFrameInfo->pstFrameTempdata->unTempData[1]); \r
+                    g_uchGh3x2xUploadBufUse += 1;\r
+\r
+                    puchUploadBuf[g_uchGh3x2xUploadBufUse] = GH3X2X_GET_BYTE2_FROM_DWORD(pstFrameInfo->pstFrameTempdata->unTempData[2]); \r
+                    g_uchGh3x2xUploadBufUse += 1;\r
+                    puchUploadBuf[g_uchGh3x2xUploadBufUse] = GH3X2X_GET_BYTE1_FROM_DWORD(pstFrameInfo->pstFrameTempdata->unTempData[2]); \r
+                    g_uchGh3x2xUploadBufUse += 1;\r
+                    puchUploadBuf[g_uchGh3x2xUploadBufUse] = GH3X2X_GET_BYTE0_FROM_DWORD(pstFrameInfo->pstFrameTempdata->unTempData[2]); \r
+                    g_uchGh3x2xUploadBufUse += 1;\r
+\r
+                    puchUploadBuf[g_uchGh3x2xUploadBufUse] = GH3X2X_GET_BYTE2_FROM_DWORD(pstFrameInfo->pstFrameTempdata->unTempData[3]); \r
+                    g_uchGh3x2xUploadBufUse += 1;\r
+                    puchUploadBuf[g_uchGh3x2xUploadBufUse] = GH3X2X_GET_BYTE1_FROM_DWORD(pstFrameInfo->pstFrameTempdata->unTempData[3]); \r
+                    g_uchGh3x2xUploadBufUse += 1;\r
+                    puchUploadBuf[g_uchGh3x2xUploadBufUse] = GH3X2X_GET_BYTE0_FROM_DWORD(pstFrameInfo->pstFrameTempdata->unTempData[3]); \r
+                    g_uchGh3x2xUploadBufUse += 1;\r
+              \r
+                }\r
+\r
+\r
+                //section RAWDATA\r
+                //set flag ,copy rawdata, clear flag\r
+\r
+                if (GH3X2X_GetFifoPackageMode() == 1)\r
+                {\r
+                    puchUploadBuf[g_uchGh3x2xUploadBufUse] = g_uchFifoPackageID;\r
+                    g_uchGh3x2xUploadBufUse ++;\r
+                }\r
+                else\r
+                {\r
+                    for(GU8 uchChnlCnt = 0; uchChnlCnt < uchChnlNum; uchChnlCnt ++)\r
+                    {\r
+                        //led adj flag 0 \r
+                        if(pstFrameInfo->punFrameFlag[0]&((((GU32)1)) << uchChnlCnt))\r
+                        {\r
+                            pstFrameInfo->punFrameRawdata[uchChnlCnt] |= ((((GU32)1)) << 26);\r
+                        }\r
+                        // fast recovery\r
+                        if ((GH3X2X_FUNCTION_ECG == unFunctionID)||(GH3X2X_FUNCTION_PWTT == unFunctionID))\r
+                        {\r
+                            if(0 == uchChnlCnt)\r
+                            {\r
+                                if(pstFrameInfo->punFrameFlag[2]&((((GU32)1)) << 0))\r
+                                {\r
+                                    pstFrameInfo->punFrameRawdata[uchChnlCnt] |= ((((GU32)1)) << 26);\r
+                                }\r
+                            }\r
+                        }\r
+                        //led adj flag 1 \r
+                        if(pstFrameInfo->punFrameFlag[1]&((((GU32)1)) << uchChnlCnt))\r
+                        {\r
+                            pstFrameInfo->punFrameRawdata[uchChnlCnt] |= ((((GU32)1)) << 25);\r
+                        }\r
+\r
+                        puchUploadBuf[g_uchGh3x2xUploadBufUse] = (pstFrameInfo->punFrameRawdata[uchChnlCnt] >> 24)&0x000000FF;\r
+                        g_uchGh3x2xUploadBufUse ++;\r
+                        puchUploadBuf[g_uchGh3x2xUploadBufUse] = (pstFrameInfo->punFrameRawdata[uchChnlCnt] >> 16)&0x000000FF;\r
+                        g_uchGh3x2xUploadBufUse ++;\r
+                        puchUploadBuf[g_uchGh3x2xUploadBufUse] = (pstFrameInfo->punFrameRawdata[uchChnlCnt] >> 8)&0x000000FF;\r
+                        g_uchGh3x2xUploadBufUse ++;\r
+                        puchUploadBuf[g_uchGh3x2xUploadBufUse] = (pstFrameInfo->punFrameRawdata[uchChnlCnt] >> 0)&0x000000FF;\r
+                        g_uchGh3x2xUploadBufUse ++;\r
+\r
+                        pstFrameInfo->punFrameRawdata[uchChnlCnt] &= 0x00FFFFFF;\r
+                    }\r
+                }\r
+                //section AGC_INFO\r
+                if(uchAgcEnable)\r
+                {\r
+                    GH3X2X_Memcpy((GU8*)&(puchUploadBuf[g_uchGh3x2xUploadBufUse]), (GU8*)(pstFrameInfo->punFrameAgcInfo), uchChnlNum*4);\r
+                    g_uchGh3x2xUploadBufUse += uchChnlNum*4;\r
+                }\r
+                //section AmbData\r
+                if(uchAmbEnable)\r
+                {\r
+                    GH3X2X_Memcpy((GU8*)&(puchUploadBuf[g_uchGh3x2xUploadBufUse]), (GU8*)(pstFrameInfo->punFrameAgcInfo), uchChnlNum*3);\r
+                    g_uchGh3x2xUploadBufUse += uchChnlNum*3;\r
+                }\r
+                \r
+                //section RESLUT_DATA\r
+                \r
+                //result byte num\r
+                puchUploadBuf[g_uchGh3x2xUploadBufUse] = uchReslutByteNum;\r
+                g_uchGh3x2xUploadBufUse ++;\r
+                \r
+                //flag2\r
+                puchUploadBuf[g_uchGh3x2xUploadBufUse] = 2;\r
+                g_uchGh3x2xUploadBufUse ++;        \r
+                GH3X2X_Memcpy((GU8*)&(puchUploadBuf[g_uchGh3x2xUploadBufUse]), (GU8*)(&(pstFrameInfo->punFrameFlag[2])), 4);\r
+                g_uchGh3x2xUploadBufUse += 4;    \r
+                //flag3\r
+                if(uchFramePosi&GH3X2X_FRAME_POSI_HEAD)\r
+                {\r
+                    puchUploadBuf[g_uchGh3x2xUploadBufUse] = 3;\r
+                    g_uchGh3x2xUploadBufUse ++;     \r
+                    GH3X2X_Memcpy((GU8*)&(puchUploadBuf[g_uchGh3x2xUploadBufUse]), (GU8*)(&(pstFrameInfo->punFrameFlag[3])), 4);\r
+                    g_uchGh3x2xUploadBufUse += 4;    \r
+                }\r
+\r
+                #if GH3X2X_DIVIDE_ZERO_FLAG_UPLODE_EN\r
+                //flag4\r
+                puchUploadBuf[g_uchGh3x2xUploadBufUse] = 4;\r
+                g_uchGh3x2xUploadBufUse ++;     \r
+                GH3X2X_Memcpy((GU8*)&(puchUploadBuf[g_uchGh3x2xUploadBufUse]), (GU8*)(&(pstFrameInfo->punFrameFlag[4])), 4);\r
+                g_uchGh3x2xUploadBufUse += 4;   \r
+                #endif\r
+\r
+                //alg result\r
+                if (1 == uchAlgoResFlag)\r
+                {\r
+                    //puchUploadBuf[g_uchGh3x2xUploadBufUse] = 0;\r
+                    //g_uchGh3x2xUploadBufUse++;\r
+                    if (1 == pstFrameInfo->pstAlgoResult->uchUpdateFlag)\r
+                    {                                                                             \r
+                        GU8 uchResTagData = GH3X2X_GET_LEFT_SHIFT_VAL(UPROTOCOL_RESULT_TYPE_BIT_FIELD);\r
+                        GU8 uchResultNumTemp = 0;\r
+                        for(GU8 uchResultCnt = 0;uchResultCnt < GH3X2X_ALGO_RESULT_MAX_NUM;uchResultCnt++)\r
+                        {\r
+                            if ((pstFrameInfo->pstAlgoResult->usResultBit >> uchResultCnt) & 0x1)\r
+                            {\r
+                                puchUploadBuf[g_uchGh3x2xUploadBufUse] = GH3X2X_SET_BIT(uchResTagData, uchResultCnt);\r
+                                g_uchGh3x2xUploadBufUse ++ ;\r
+                                puchUploadBuf[g_uchGh3x2xUploadBufUse] = GH3X2X_GET_BYTE0_FROM_DWORD(pstFrameInfo->pstAlgoResult->snResult[uchResultCnt]);\r
+                                g_uchGh3x2xUploadBufUse ++ ;\r
+                                puchUploadBuf[g_uchGh3x2xUploadBufUse] = GH3X2X_GET_BYTE1_FROM_DWORD(pstFrameInfo->pstAlgoResult->snResult[uchResultCnt]);\r
+                                g_uchGh3x2xUploadBufUse ++ ;\r
+                                puchUploadBuf[g_uchGh3x2xUploadBufUse] = GH3X2X_GET_BYTE2_FROM_DWORD(pstFrameInfo->pstAlgoResult->snResult[uchResultCnt]);\r
+                                g_uchGh3x2xUploadBufUse ++ ;\r
+                                puchUploadBuf[g_uchGh3x2xUploadBufUse] = GH3X2X_GET_BYTE3_FROM_DWORD(pstFrameInfo->pstAlgoResult->snResult[uchResultCnt]);\r
+                                g_uchGh3x2xUploadBufUse ++ ;\r
+                                uchResultNumTemp ++;\r
+                                if (uchResultNumTemp >= pstFrameInfo->pstAlgoResult->uchResultNum)\r
+                                {\r
+                                    break;\r
+                                }\r
+                            }\r
+                        }\r
+                    }\r
+                    // end of if (1 == uchAlgoResFlag)\r
+                }\r
+\r
+                //modify uchReslutByteNum\r
+                puchUploadBuf[g_uchGh3x2xUploadBufUse - uchReslutByteNum] = uchReslutByteNum - 1;\r
+\r
+                if(uchFramePosi&GH3X2X_FRAME_POSI_TAIL)\r
+                {\r
+                    //send data\r
+                    usRespondLen = GH3X2X_UprotocolPacketFormat(GH3X2X_UPROTOCOL_CMD_NEW_STRUCT_RAWDATA, puchUploadBuf - 4,\r
+                                        puchUploadBuf, g_uchGh3x2xUploadBufUse);\r
+                    Gh3x2xDemoSendProtocolData(puchUploadBuf - 4,usRespondLen);\r
+\r
+                    g_uchGh3x2xUploadStatus = GH3X2X_UPLOAD_STATUS_NULL;\r
+                }\r
+            }\r
+        }\r
+    }\r
+}\r
+\r
+\r
+\r
+#else\r
+void Gh2x2xUploadDataToMaster(const STGh3x2xFrameInfo * const pstFrameInfo, GU16 usFrameCnt, GU16 usFrameNum, GU8* puchTagArray){}\r
+#endif\r
+\r
+/**\r
+ * @fn     GU32 GH3X2X_GetFuncModeAvailable(void)\r
+ *\r
+ * @brief  Get all function mode available\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[out]  None\r
+ * @param[in]   None\r
+ * @return  function mode, @ref GH3X2X_NO_FUNCTION ... GH3X2X_FUNCTION_PWTT\r
+ */\r
+GU32 GH3X2X_GetFuncModeAvailable(void)\r
+{\r
+    return g_unAllFuncMode;\r
+}\r
+\r
+/**\r
+ * @fn     GU32 GH3X2X_GetFuncModeOpened(void)\r
+ *\r
+ * @brief  Get function mode that already opened\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[out]  None\r
+ * @param[in]   None\r
+ * @return  function mode, @ref GH3X2X_NO_FUNCTION ... GH3X2X_FUNCTION_PWTT\r
+ */\r
+GU32 GH3X2X_GetFuncModeOpened(void)\r
+{\r
+    return g_unFuncModeOpened;\r
+}\r
+\r
+/**\r
+ * @fn     GU32 GH3X2X_GetTargetFuncMode(void)\r
+ *\r
+ * @brief  Get function mode that will be opened or closed\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[out]  None\r
+ * @param[in]   None\r
+ * @return  function mode, @ref GH3X2X_NO_FUNCTION ... GH3X2X_FUNCTION_PWTT\r
+ */\r
+GU32 GH3X2X_GetTargetFuncMode(void)\r
+{\r
+    return g_unTargetFuncMode;\r
+}\r
+\r
+/**\r
+ * @fn     void GH3X2X_ReportIrqStatus(GU8 *puchRespondBuffer, GU16 *pusRespondLen, GU16 usIrqStatus)\r
+ *\r
+ * @brief  report irq status of Gh3x2x\r
+ *\r
+ * @attention   none\r
+ *\r
+ * @param[out]  puchRespondBuffer       pointer to protocol pkg data.\r
+ * @param[out]  pusRespondLen           pointer to protocol pkg data length\r
+ * @param[in]   usIrqStatus             irq status need report\r
+ * @return  none\r
+ */\r
+void GH3X2X_ReportIrqStatus(GU8 *puchRespondBuffer, GU16 *pusRespondLen, GU16 usIrqStatus)\r
+{\r
+    GU16 usIrqStatusTmp = usIrqStatus & g_usGh3x2xEventNeedReport;\r
+\r
+    if (usIrqStatusTmp != 0)\r
+    {\r
+        g_pstGh3x2xProtocolData->puchPacketPayloadArr[UPROTOCOL_CHIP_EVENT_REPORT_INDEX]     = GH3X2X_GET_HIGH_BYTE_FROM_WORD(usIrqStatus);\r
+        g_pstGh3x2xProtocolData->puchPacketPayloadArr[UPROTOCOL_CHIP_EVENT_REPORT_INDEX + 1] = GH3X2X_GET_LOW_BYTE_FROM_WORD(usIrqStatus);\r
+\r
+        g_pstGh3x2xProtocolData->puchPacketPayloadArr[UPROTOCOL_CHIP_EVENT_REPORT_ID_INDEX]  = g_uchEventReportId;\r
+        g_uchEventReportId++;\r
+        SET_VAL_VIA_PTR(pusRespondLen, GH3X2X_UprotocolPacketFormat(GH3X2X_UPROTOCOL_CMD_CHIP_EVENT_REPORT,\r
+                            puchRespondBuffer, g_pstGh3x2xProtocolData->puchPacketPayloadArr, UPROTOCOL_CHIP_EVENT_REPORT_LEN));\r
+    }\r
+    else\r
+    {\r
+        SET_VAL_VIA_PTR(pusRespondLen, 0);\r
+    }   \r
+}\r
+\r
+//__attribute__((weak)) void GH3X2X_PROTOCOL_FRAMID_CLEAN(GU8 uchFunctionID)\r
+void GH3X2X_ProtocolFrameIdClean(GU8 uchFunctionID)\r
+{\r
+    g_pstGh3x2xProtocolData->uchFrameIdArr[uchFunctionID] = 0;\r
+}\r
+\r
+/********END OF FILE********* Copyright (c) 2003 - 2022, Goodix Co., Ltd. ********/\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/module/gh_protocol/gh_uprotocol.h b/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/module/gh_protocol/gh_uprotocol.h
new file mode 100644 (file)
index 0000000..351d16a
--- /dev/null
@@ -0,0 +1,385 @@
+/**\r
+ * @copyright (c) 2003 - 2022, Goodix Co., Ltd. All rights reserved.\r
+ *\r
+ * @file    gh3x2x_drv_uprotocol.h\r
+ *\r
+ * @brief   gh3x2x universal protocol define & declaration\r
+ *\r
+ * @version ref gh3x2x_drv_version.h\r
+ *\r
+ */\r
+\r
+#ifndef _GH3X2X_DRV_UPROTOCOL_H_\r
+#define _GH3X2X_DRV_UPROTOCOL_H_\r
+\r
+\r
+#include "gh_drv_config.h"\r
+#include "gh_drv.h"\r
+\r
+\r
+/* function ptr typedef */\r
+typedef GCHAR* (*pfnGetFirmwareVersion)(void);                           /**< read pin status type */\r
+\r
+\r
+#define GH3X2X_FRAME_POSI_HEAD  (0x01)\r
+#define GH3X2X_FRAME_POSI_TAIL  (0x02)\r
+#define GH3X2X_UPLOAD_STATUS_NULL  0\r
+#define GH3X2X_UPLOAD_STATUS_HAVE_STORE_DATA 1\r
+#define GH3X2X_UPLOAD_PACKAGE_HEAD_SIZE 8\r
+\r
+#define GH3X2X_SEND_STATUS_TAIL_MODE 1\r
+#define GH3X2X_SEND_STATUS_FULL_MODE 2\r
+#define GH3X2X_SEND_STATUS_SPLIC_PACK_MODE 3\r
+\r
+/**\r
+ * @brief ZipMode Lastdata Temp\r
+ */\r
+typedef struct\r
+{\r
+    GU8 uchFlag;\r
+    GS16 sGsensorLastDataArr[GH3X2X_GSENSOR_MAX_SIZE];\r
+    GU8 uchFifoLastRawdataTagArr[GH3X2X_CHANNEL_MAP_MAX_CH];\r
+    GU32 unFifoLastRawdataArr[GH3X2X_CHANNEL_MAP_MAX_CH];\r
+    GU32 unFifoLastAgcdataArr[GH3X2X_CHANNEL_MAP_MAX_CH];\r
+    GU32 unFifoLastAmbdataArr[GH3X2X_CHANNEL_MAP_MAX_CH];\r
+    GU32 unFifoLastResult;\r
+} STZipLastDataTemp;\r
+\r
+/* universal protocol packet, but index no use */\r
+#define  GH3X2X_UPROTOCOL_PACKET_FIXED_INDEX                (0u)        /**< fixed header index */\r
+#define  GH3X2X_UPROTOCOL_PACKET_VER_INDEX                  (1u)        /**< version index */\r
+#define  GH3X2X_UPROTOCOL_PACKET_CMD_INDEX                  (2u)        /**< cmd index */\r
+#define  GH3X2X_UPROTOCOL_PACKET_LEN_INDEX                  (3u)        /**< payload len index */\r
+#define  GH3X2X_UPROTOCOL_PACKET_PAYLOAD_INDEX              (4u)        /**< payload index */\r
+#define  GH3X2X_UPROTOCOL_PACKET_CRC8_INDEX                 (4u)        /**< crc8 index not equl 4, index = len+4 */\r
+//#define  GH3X2X_UPROTOCOL_PACKET_HEADER_LEN                 (4u)        /**< packet header len */\r
+//#define  GH3X2X_UPROTOCOL_PACKET_TAIL_LEN                   (1u)        /**< packet tail len */\r
+\r
+\r
+\r
+/// get packet payload len support\r
+#define  GH3X2X_UPROTOCOL_GET_PAYLOAD_LEN_SUPPORT(val)      ((val) - GH3X2X_UPROTOCOL_PACKET_HEADER_TAIL_LEN)\r
+\r
+\r
+/* cmd id */\r
+#define  GH3X2X_UPROTOCOL_CMD_NOP                       (0x00)     /**< nop operation */\r
+#define  GH3X2X_UPROTOCOL_CMD_CTRL_ACK                  (0x01)     /**< ctrl ack */\r
+#define  GH3X2X_UPROTOCOL_CMD_GET_STATUS                (0x02)     /**< get status */\r
+#define  GH3X2X_UPROTOCOL_CMD_REG_RW                    (0x03)     /**< register RW */\r
+#define  GH3X2X_UPROTOCOL_CMD_LOAD_CONFIG               (0x04)     /**< load config array */\r
+#define  GH3X2X_UPROTOCOL_CMD_PACKAGE_TEST              (0x05)     /**< package test */\r
+#define  GH3X2X_UPROTOCOL_CMD_READ_OTP_REG              (0x07)     /**< Read Otp Reg */\r
+#define  GH3X2X_UPROTOCOL_CMD_RAWDATA                   (0x08)     /**< raw data package, only output */\r
+\r
+#define  GH3X2X_UPROTOCOL_CMD_ZIPEVENRAWDATA            (0x09)     /**< raw data package, only output */\r
+#define  GH3X2X_UPROTOCOL_CMD_ZIPODDRAWDATA             (0x0A)     /**< raw data package, only output */\r
+#define  GH3X2X_UPROTOCOL_CMD_NEW_STRUCT_RAWDATA        (0x0B)     /**< raw data package, only output */\r
+\r
+#define  GH3X2X_UPROTOCOL_CMD_START_CTRL                (0x0C)     /**< start ctrl */\r
+#define  GH3X2X_UPROTOCOL_CMD_WORK_MODE                 (0x10)     /**< work mode */\r
+#define  GH3X2X_UPROTOCOL_CMD_FIFO_THR_CONFIG           (0x12)     /**< fifo thr config */\r
+#define  GH3X2X_UPROTOCOL_CMD_REPORT_EVENT_SET          (0x13)     /**< set GH3X2X event need reporting */\r
+#define  GH3X2X_UPROTOCOL_CMD_ECG_CLASSIFICATION        (0x14)     /**< ecg classification */\r
+#define  GH3X2X_UPROTOCOL_CMD_FUNC_MAP                  (0x15)     /**< function map */\r
+#define  GH3X2X_UPROTOCOL_CMD_CHIP_EVENT_REPORT         (0x16)     /**< GH3X2X event report */\r
+#define  GH3X2X_UPROTOCOL_CMD_CHIP_CTRL                 (0x17)     /**< chip ctrl */\r
+#define  GH3X2X_UPROTOCOL_CMD_GET_VER                   (0x19)     /**< get ver */\r
+#define  GH3X2X_UPROTOCOL_CMD_GET_CHIPSET_CONN_STA      (0x1A)     /**< get GH3X2X connect status */\r
+#define  GH3X2X_UPROTOCOL_CMD_SWITCH_SLOT_FUNC          (0x1C)     /**< switch on or off some function */\r
+#define  GH3X2X_UPROTOCOL_CMD_GET_OPENED_FUNC           (0x25)     /**< get Opened function */\r
+#define  GH3X2X_UPROTOCOL_CMD_SET_ECG_CASCADE           (0x26)     /**< get Opened function */\r
+#define  GH3X2X_UPROTOCOL_CMD_HSM_RESULT_UPDATE         (0x29)     /**< switch on or off some function */\r
+#define  GH3X2X_UPROTOCOL_CMD_RAWDATA_FIFO_UPDATE       (0x2A)     /**< rawdata fifo update function */\r
+#define  GH3X2X_UPROTOCOL_CMD_BP_DATA_TRANS             (0x2B)     /**< fpbp data transmit function */\r
+#define  GH3X2X_UPROTOCOL_CMD_FUNCTION_INFO_UPDATE      (0x2C)     /**< function info transmit function */\r
+#define  GH3X2X_UPROTOCOL_CMD_GET_MAX_LEN               (0xA0)     /**< get packet max len support */\r
+#define  GH3X2X_UPROTOCOL_CMD_LOAD_REG_LIST             (0xA1)     /**< get load reg list */\r
+#define  GH3X2X_UPROTOCOL_CMD_DEBUG_STATUS              (0xA2)     /**< debug status */\r
+\r
+/* macro of reg rw cmd */\r
+#define  UPROTOCOL_REG_RW_READ_MODE                     (0x00)      /**< read mode */\r
+#define  UPROTOCOL_REG_RW_WRITE_MODE                    (0x01)      /**< write mode */\r
+#define  UPROTOCOL_REG_RW_MODE_INDEX                    (0u)        /**< mode */\r
+#define  UPROTOCOL_REG_RW_CNT_INDEX                     (1u)        /**< count */\r
+#define  UPROTOCOL_REG_RW_ADDR_H_INDEX                  (2u)        /**< addr_h */\r
+#define  UPROTOCOL_REG_RW_ADDR_L_INDEX                  (3u)        /**< addr_l */\r
+#define  UPROTOCOL_REG_RW_DATA_INDEX                    (4u)        /**< data */\r
+#define  UPROTOCOL_REG_RW_HEADER_LENGTH                 (4u)        /**< header len */\r
+\r
+\r
+/* macro of get version cmd */\r
+#define  UPROTOCOL_GET_VER_TYPE_FW_VER                  (0x01)      /**< get firmware version type */\r
+#define  UPROTOCOL_GET_VER_TYPE_DEMO_VER                (0x0A)      /**< get algo call demo version type */\r
+#define  UPROTOCOL_GET_VER_TYPE_VIRTUAL_REG_VER         (0x0B)      /**< get virtual reg version type */\r
+#define  UPROTOCOL_GET_VER_TYPE_BOOTLOADER_VER          (0x0C)      /**< get BOOTLOADER version type */\r
+#define  UPROTOCOL_GET_VER_TYPE_PROTOCOL_VER            (0x0E)      /**< get protocol version type */\r
+#define  UPROTOCOL_GET_VER_TYPE_FUNC_SUPPORT            (0x0F)      /**< get driver func support type */\r
+#define  UPROTOCOL_GET_VER_TYPE_DRV_VER                 (0x10)      /**< get driver version type */\r
+#define  UPROTOCOL_GET_VER_TYPE_CHIP_VER                (0x11)      /**< get chip version type */\r
+#define  UPROTOCOL_GET_VER_TYPE_ALGO_VER                (0x12)      /**< get algorithm version type */\r
+#define  UPROTOCOL_GET_VER_TYPE_ALGO_VER_END            (0x12 + GH3X2X_FUNC_OFFSET_MAX)      /**< get algorithm version type END*/\r
+\r
+#define  UPROTOCOL_GET_VER_TYPE_INDEX                   (0u)        /**< type index */\r
+#define  UPROTOCOL_GET_VER_STRING_LEN_INDEX             (1u)        /**< version string len index */\r
+#define  UPROTOCOL_GET_VER_STRING_INDEX                 (2u)        /**< version string index */\r
+#define  UPROTOCOL_GET_VER_DEFAULT_VER_STRING           "no_ver"    /**< default version string */\r
+#define  UPROTOCOL_GET_VER_CACHE_VER_MAX_LEN            (64)        /**< cache algo ver string, max len */\r
+#define  UPROTOCOL_GET_VER_CACHE_VER_PAYLOAD_INDEX      (GH3X2X_UPROTOCOL_PAYLOAD_LEN_MAX - \\r
+                                                         UPROTOCOL_GET_VER_CACHE_VER_MAX_LEN) /**< cache index */\r
+\r
+\r
+/* macro of get max len */\r
+#define  UPROTOCOL_GET_MAX_LEN_RESP_VAL_INDEX            (0u)      /**< len index */\r
+#define  UPROTOCOL_GET_MAX_LEN_RESP_LEN                  (1u)      /**< respond len */\r
+\r
+\r
+/* macro of load reg list */\r
+#define  UPROTOCOL_LOAD_REG_LIST_SIZEOF                 (4u)      /**< sizeof reg */\r
+#define  UPROTOCOL_LOAD_REG_LIST_RESP_STATUS_INDEX      (0u)      /**< respond status inex */\r
+#define  UPROTOCOL_LOAD_REG_LIST_RESP_LEN               (1u)      /**< respond len */\r
+#define  UPROTOCOL_LOAD_REG_LIST_RESP_CFG_SUCCESS       (0u)      /**< config success */\r
+#define  UPROTOCOL_LOAD_REG_LIST_RESP_CFG_FAIL          (1u)      /**< config fail */\r
+\r
+\r
+/* macro of fifo thr config */\r
+#define  UPROTOCOL_FIFO_THR_CFG_H_INDEX                 (0u)      /**< config val high byte inex */\r
+#define  UPROTOCOL_FIFO_THR_CFG_L_INDEX                 (1u)      /**< config val low byte inex */\r
+#define  UPROTOCOL_FIFO_THR_CFG_RESP_STATUS_INDEX       (0u)      /**< respond status inex */\r
+#define  UPROTOCOL_FIFO_THR_CFG_RESP_LEN                (1u)      /**< respond len */\r
+#define  UPROTOCOL_FIFO_THR_CFG_RESP_CFG_SUCCESS        (0u)      /**< config success */\r
+#define  UPROTOCOL_FIFO_THR_CFG_RESP_CFG_FAIL           (1u)      /**< config fail */\r
+\r
+/* macro of report event set */\r
+#define  UPROTOCOL_REPORT_EVENT_SET_INDEX                (0u)      /**< report event set inex */\r
+#define  UPROTOCOL_REPORT_EVENT_SET_RESP_LEN             (1u)      /**< respond len */\r
+#define  UPROTOCOL_REPORT_EVENT_SET_RESP_INDEX           (0u)      /**< report event set respond inex */\r
+#define  UPROTOCOL_REPORT_EVENT_SET_SUCCESS              (0u)      /**< set success */\r
+#define  UPROTOCOL_REPORT_EVENT_SET_FAIL                 (1u)      /**< set fail */\r
+#define  UPROTOCOL_REPORT_EVENT_ID_INIT                  (0xFF)    /**< set fail */\r
+\r
+/* macro of chip ctrl */\r
+#define  UPROTOCOL_CHIP_CTRL_VAL_INDEX                  (0u)      /**< ctrl val inex */\r
+#define  UPROTOCOL_CHIP_CTRL_RESP_STATUS_INDEX          (0u)      /**< respond status inex */\r
+#define  UPROTOCOL_CHIP_CTRL_RESP_LEN                   (1u)      /**< respond len */\r
+#define  UPROTOCOL_CHIP_CTRL_RESP_CFG_SUCCESS           (0u)      /**< config success */\r
+#define  UPROTOCOL_CHIP_CTRL_RESP_CFG_FAIL              (1u)      /**< config fail */\r
+#define  UPROTOCOL_CHIP_CTRL_RESP_NULL                  (0xFF)    /**< function ptr null */\r
+#define  UPROTOCOL_CHIP_CTRL_TYPE_HARD_RESET            (0x5A)    /**< hard reset type */\r
+#define  UPROTOCOL_CHIP_CTRL_TYPE_SOFT_RESET            (0xC2)    /**< soft reset type */\r
+#define  UPROTOCOL_CHIP_CTRL_TYPE_WAKEUP                (0xC3)    /**< wakeup type */\r
+#define  UPROTOCOL_CHIP_CTRL_TYPE_SLEEP                 (0xC4)    /**< sleep type */\r
+\r
+/* macro of chip event report */\r
+#define  UPROTOCOL_CHIP_EVENT_REPORT_ACK_INDEX           (0u)      /**< event report ack inex */\r
+#define  UPROTOCOL_CHIP_EVENT_REPORT_INDEX               (0u)      /**< event report inex */\r
+#define  UPROTOCOL_CHIP_EVENT_REPORT_ID_INDEX            (2u)      /**< event report id inex */\r
+#define  UPROTOCOL_CHIP_EVENT_REPORT_LEN                 (3u)      /**< event report data length */\r
+\r
+/* macro of debug status */\r
+#define  UPROTOCOL_DEBUG_STATUS_TYPE_INDEX              (0u)      /**< type inex */\r
+#define  UPROTOCOL_DEBUG_STATUS_RESP_BYTES_INDEX        (1u)      /**< respond bytes len inex */\r
+#define  UPROTOCOL_DEBUG_STATUS_RESP_DATA_INDEX         (2u)      /**< respond data inex */\r
+#define  UPROTOCOL_DEBUG_STATUS_RESP_LEN                (6u)      /**< respond len */\r
+#define  UPROTOCOL_DEBUG_STATUS_RESP_BYTES_8            (1u)      /**< respond bytes len 8 bits */\r
+#define  UPROTOCOL_DEBUG_STATUS_RESP_BYTES_16           (2u)      /**< respond bytes len 16 bits */\r
+#define  UPROTOCOL_DEBUG_STATUS_RESP_BYTES_32           (4u)      /**< respond bytes len 32 bits */\r
+#define  UPROTOCOL_DEBUG_STATUS_READ_INT_PIN            (0x00)    /**< read int pin type */\r
+#define  UPROTOCOL_DEBUG_STATUS_READ_RST_PIN            (0x01)    /**< read reset pin type */\r
+#define  UPROTOCOL_DEBUG_STATUS_READ_SPCS_PIN           (0x02)    /**< read spcs pin type */\r
+#define  UPROTOCOL_DEBUG_STATUS_READ_SPDO_PIN           (0x03)    /**< read spdo pin type */\r
+#define  UPROTOCOL_DEBUG_STATUS_COMM_CONFIRM            (0x04)    /**< communicate confirm type */\r
+#define  UPROTOCOL_DEBUG_STATUS_READ_WORK_STATUS        (0x10)    /**< read work status type */\r
+\r
+/* macro of rawdata package*/\r
+#define  UPROTOCOL_FUNCTION_ID_INDEX                    (0u)      /**< function id inex */\r
+#define  UPROTOCOL_RAWDATA_TYPE_INDEX                   (1u)      /**< rawdata type inex */\r
+#define  UPROTOCOL_RAWDATA_CHNL_NUM                     (2u)      /**< rawdata channel num */\r
+#define  UPROTOCOL_PACKAGE_TYPE_INDEX                   (6u)      /**< package type index */\r
+#define  UPROTOCOL_RAWDATA_LEN_INDEX                    (7u)      /**< rawdata len index */\r
+#define  UPROTOCOL_FRAME_DATA_INDEX                     (2u)      /**< frame data inex */\r
+#define  UPROTOCOL_GS_ENABLE_FIELD                      (0u)      /**< g sensor enable field in data type */\r
+#define  UPROTOCOL_ALGO_ENABLE_FIELD                    (1u)      /**< algorithm result enable field in data type */\r
+#define  UPROTOCOL_AGC_ENABLE_FIELD                     (2u)      /**< gain current enable field in data type */\r
+#define  UPROTOCOL_AMBIANCE_ENABLE_FIELD                (3u)      /**< ambiance enable field in data type */\r
+#define  UPROTOCOL_GS_GYRO_ENABLE_FIELD                 (4u)      /**< GYRO enable field in data type */\r
+#define  UPROTOCOL_CAP_ENABLE_ENABLE_FIELD              (5u)      /**< CAP enable field in data type */\r
+#define  UPROTOCOL_TEMP_ENABLE_ENABLE_FIELD             (6u)      /**< TEMP enable field in data type */\r
+#define  UPROTOCOL_ZIP_ENABLE_FIELD                     (0u)      /**< zip enable field in data type */\r
+#define  UPROTOCOL_ODDEVEN_FLAG_FIELD                   (1u)      /**< odd-even flag field in data type */\r
+#define  UPROTOCOL_FUNCTION_MODE_FIELD                  (2u)      /**< function mode field in data type */\r
+#define  UPROTOCOL_SPLIC_PACK_CNT_FIELD                 (3u)      /**< splic pack cnt in data type */\r
+#define  UPROTOCOL_SPLIC_PACK_OVER_FIELD                (5u)      /**< splic pack over in data type */\r
+#define  UPROTOCOL_NEW_DATA_FIELD                       (7u)      /**< algorithm result enable field in data type */\r
+#define  UPROTOCOL_RESULT_TYPE_BIT_FIELD                (7u)      /**< result type bit field in protocol data */\r
+#define  UPROTOCOL_UPLOAD_FLAG_INDEX0                   (0u)      /**< flag index0 that will upload */\r
+#define  UPROTOCOL_UPLOAD_FLAG_INDEX1                   (1u)      /**< flag index1 that will upload */\r
+#define  UPROTOCOL_UPLOAD_FLAG_INDEX2                   (2u)      /**< flag index2 that will upload */\r
+#define  UPROTOCOL_UPLOAD_FLAG_INDEX3                   (3u)      /**< flag index3 that will upload */\r
+#define  UPROTOCOL_UPLOAD_FLAG_INDEX4                   (4u)      /**< flag index4 that will upload */\r
+#define  UPROTOCOL_UPLOAD_FLAG_INDEX5                   (5u)      /**< flag index5 that will upload */\r
+#define  UPROTOCOL_UPLOAD_FLAG_INDEX6                   (6u)      /**< flag index6 that will upload */\r
+#define  UPROTOCOL_UPLOAD_FLAG_INDEX7                   (7u)      /**< flag index7 that will upload */\r
+\r
+/* macro of work mode set */\r
+#define  UPROTOCOL_WORK_MODE_INDEX                      (0u)      /**< work mode inex */\r
+#define  UPROTOCOL_FUNC_MODE_INDEX                      (1u)      /**< function mode inex */\r
+#define  UPROTOCOL_WORK_MODE_RESP_INDEX                 (0u)      /**< work mode respond index */\r
+#define  UPROTOCOL_WORK_MODE_RESP_LEN                   (1u)      /**< respond len */\r
+#define  UPROTOCOL_WORK_MODE_SET_SUCCESS                (0u)      /**< config success */\r
+#define  UPROTOCOL_WORK_MODE_SET_FAIL                   (1u)      /**< config fail */\r
+\r
+/* macro of switch slot & function */\r
+#define  UPROTOCOL_SW_FUNC_SLOT_INDEX                   (0u)      /**< slot inex */\r
+#define  UPROTOCOL_SW_FUNC_EXTRA_CMD_INDEX              (1u)      /**< extra cmd inex */\r
+#define  UPROTOCOL_SW_FUNC_FUNC_INDEX                   (2u)      /**< function inex */\r
+#define  UPROTOCOL_SW_FUNC_ONOFF_INDEX                  (6u)      /**< on or off index */\r
+#define  UPROTOCOL_SW_FUNC_RESP_INDEX                   (0u)      /**< switch function respond index */\r
+#define  UPROTOCOL_SW_FUNC_RESP_LEN                     (1u)      /**< respond len */\r
+#define  UPROTOCOL_SW_FUNC_SUCCESS                      (0u)      /**< switch function success */\r
+#define  UPROTOCOL_SW_FUNC_FAIL                         (1u)      /**< switch function fail */\r
+\r
+/* macro of start ctrl set */\r
+#define  UPROTOCOL_START_CTRL_INDEX                     (0u)      /**< start or stop index */\r
+#define  UPROTOCOL_START_CTRL_MODE_INDEX                (1u)      /**< mode index */\r
+#define  UPROTOCOL_START_CTRL_SLOT_EN_INDEX             (2u)      /**< slot en index */\r
+#define  UPROTOCOL_START_CTRL_FUNCTION_INDEX            (3u)      /**< function index */\r
+#define  UPROTOCOL_START_CTRL_RESP_INDEX                (0u)      /**< chipset connect status respond index */\r
+#define  UPROTOCOL_START_CTRL_RESP_LEN                  (1u)      /**< respond len */\r
+#define  UPROTOCOL_START_SAMPLING                       (0u)      /**< start sampling */\r
+#define  UPROTOCOL_STOP_SAMPLING                        (1u)      /**< stop sampling */\r
+#define  UPROTOCOL_START_CTRL_SUCCESS                   (0u)      /**< start ctrl success */\r
+#define  UPROTOCOL_START_CTRL_FAIL                      (1u)      /**< start ctrl fail */\r
+\r
+/* macro of chipset connect status set */\r
+#define  UPROTOCOL_CONN_STA_RESP_INDEX                  (0u)      /**< chipset connect status respond index */\r
+#define  UPROTOCOL_CONN_STA_RESP_LEN                    (1u)      /**< respond len */\r
+#define  UPROTOCOL_CONN_STA_SUCCESS                     (0u)      /**< connect ok*/\r
+#define  UPROTOCOL_CONN_STA_FAIL                        (1u)      /**< connect error */\r
+\r
+/* macro of ecg classification set */\r
+#define  UPROTOCOL_CONN_ECG_CLASSIFICATION_LEN          (1u)      /**< respond len */\r
+#define  UPROTOCOL_CONN_ECG_CLASSIFICATION_INDEX        (0u)      /**< data index */\r
+\r
+/* macro of GH3X2X_UprotocolEcgCascadeCmd set */\r
+#define  UPROTOCOL_CONN_ECG_CASCADE_LEN                 (1u)      /**< respond len */\r
+#define  UPROTOCOL_CONN_ECG_CASCADE_INDEX               (0u)      /**< data index */\r
+\r
+/// universal protocol fixed header\r
+#define  GH3X2X_UPROTOCOL_FIXED_HEADER       (0xAA)\r
+\r
+/// universal protocol version byte\r
+#define  GH3X2X_UPROTOCOL_VERSION            (0x11)\r
+\r
+/// chip version string len\r
+#define  GH3X2X_CHIP_VER_STR_LEN             (24)\r
+\r
+/// crc8 clear val\r
+#define  GH3X2X_CRC8_CLEAR_VAL               (0xFF)\r
+\r
+/// crc8 val clear\r
+#define  GH3X2X_CRC8_VAL_CLEAR(x)            do { (x) = GH3X2X_CRC8_CLEAR_VAL; } while (0)\r
+\r
+/// size_t size\r
+#define  GH3X2X_UPROTOCOL_SIZE_T             (4u)\r
+\r
+/// align num\r
+#define  GH3X2X_UPROTOCOL_ALIGN_LEFTSHIFT    (30u)\r
+\r
+/// channel map id for user defined @ref EMFunctionID\r
+#define  GH3X2X_FUNC_OFFSET_USER_DEF_BASE       (10)\r
+\r
+/// number of channel map id\r
+//#define  CHANNEL_MAP_ID_NUM                  (16)\r
+\r
+/// rawdata diff size\r
+#define  RAWDATA_DIFF_SIZE                   (8)\r
+\r
+/// rawdata diff byte size\r
+#define  RAWDATA_DIFF_BYTE_SIZE              (4)\r
+\r
+/// rawdata diff type even\r
+#define  RAWDATA_DIFF_EVEN                   (2)\r
+\r
+/// rawdata diff type odd\r
+#define  RAWDATA_DIFF_ODD                    (1)\r
+\r
+/* universal protocol parse status */\r
+typedef enum\r
+{\r
+    UPROTOCOL_STATUS_IDLE = 0,          /**< idle */\r
+    UPROTOCOL_STATUS_GOT_FIXED,         /**< got fixed header */\r
+    UPROTOCOL_STATUS_GOT_VER,           /**< got version */\r
+    UPROTOCOL_STATUS_GOT_CMD,           /**< got cmd */\r
+    UPROTOCOL_STATUS_GOT_LEN,           /**< got data len */\r
+    UPROTOCOL_STATUS_GOT_PAYLOAD,       /**< got pyload data */\r
+    UPROTOCOL_STATUS_GOT_CRC8,          /**< got crc8, but never goto this enum */\r
+} EMUprotocolParseStatus;\r
+\r
+/**\r
+ * @fn     GU8 GH3X2X_UprotocolPacketFormat(GU8 uchCmd, GU8 *puchPacketBuffer,\r
+ *                                          GU8 *puchPayloadData, GU8 uchPayloadDataLen)\r
+ *\r
+ * @brief  universal protocol format packet\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[out]   puchPacketBuffer    pointer to respond packet buffer\r
+ * @param[in]    uchCmd              cmd id\r
+ * @param[in]    puchPayloadData     pointer to payload buffer\r
+ * @param[in]    uchPayloadDataLen   payload len\r
+ *\r
+ * @return  len after make packet\r
+ */\r
+GU8 GH3X2X_UprotocolPacketFormat(GU8 uchCmd, GU8 *puchPacketBuffer, GU8 *puchPayloadData, GU8 uchPayloadDataLen);\r
+\r
+/**\r
+ * @fn       void GH3X2X_FillGsensorData(GU16* pusPayloadIndex, STGsensorRawdata* pstGsAxisValue \r
+ *                                        y)\r
+ *\r
+ * @brief  fill g sensor data to protocol data\r
+ *\r
+ * @attention    None\r
+ *\r
+ * @param[in]    pstGsAxisValue       g sensor data\r
+ * @param[in]    emGsSensitivity     g sensor sensitivity\r
+ * @param[out]   pusPayloadIndex      current index of payload\r
+ *\r
+ * @return    None\r
+ */\r
+//void GH3X2X_FillGsensorData(GU16* pusPayloadIndex, STGsensorRawdata* pstGsAxisValue);\r
+\r
+/**\r
+ * @fn       void GH3X2X_FillAlgoData(GU16* pusPayloadIndex, GS32 nAlgoCalcResultArr[], GU8 uchAlgoResNum)\r
+ *\r
+ * @brief  fill algorithm data to protocol data\r
+ *\r
+ * @attention    None\r
+ *\r
+ * @param[in]    nAlgoCalcResultArr  pointer to algorithm result array\r
+ * @param[in]    uchAlgoResNum       algorithm data num\r
+ * @param[out]   pusPayloadIndex      current index of payload\r
+ *\r
+ * @return    None\r
+ */\r
+void GH3X2X_FillAlgoData(GU16* pusPayloadIndex, GS32 nAlgoCalcResultArr[], GU8 uchAlgoResNum);\r
+\r
+/**\r
+ * @fn       void GH3X2X_FillElectrodeWearRevertData(GU16* pusPayloadIndex)\r
+ *\r
+ * @brief  fill electrode wear revert data to protocol data buf\r
+ *\r
+ * @attention    None\r
+ *\r
+ * @param[in]    pusPayloadIndex      current index of payload\r
+ * @param[out]   None\r
+ *\r
+ * @return    None\r
+ */\r
+void GH3X2X_FillElectrodeWearRevertData(GU16* pusPayloadIndex);\r
+\r
+void GH3X2X_GetVersion(GU8 uchGetVersionType, GCHAR pszVersionString[100]);\r
+\r
+\r
+#endif /* _GH3X2X_DRV_UPROTOCOL_H_ */\r
+\r
+/********END OF FILE********* Copyright (c) 2003 - 2022, Goodix Co., Ltd. ********/\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/module/gh_protocol/gh_zip.c b/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/module/gh_protocol/gh_zip.c
new file mode 100644 (file)
index 0000000..fe3ffe2
--- /dev/null
@@ -0,0 +1,828 @@
+/**\r
+ * @copyright (c) 2003 - 2022, Goodix Co., Ltd. All rights reserved.\r
+ *\r
+ * @file    gh3x2x_drv_zip.c\r
+ *\r
+ * @brief   gh3x2x extension control functions, using function map like evk\r
+ *\r
+ * @version ref gh3x2x_drv_ziphandle.h\r
+ *\r
+ */\r
+\r
+#include <stdio.h>\r
+#include "gh_drv_version.h"\r
+#include "gh_drv_common.h"\r
+#include "gh_drv.h"\r
+#include "gh_uprotocol.h"\r
+#include "gh_drv_interface.h"\r
+#include "gh_drv_control.h"\r
+#include "gh_drv_dump.h"\r
+#include "gh_agc.h"\r
+#include "gh_zip.h"\r
+#include "gh_demo_config.h"\r
+\r
+// Zipmode Tempdata\r
+STZipLastDataStruct g_stZipLastData;\r
+\r
+GU32 g_unLastFrameFlag2 = 0;\r
+\r
+//  Zip Package Num Even/Odd Flag\r
+extern GU8 g_uchOddEvenChangeFlag;\r
+extern GU8  g_puchGainBgCancelRecord[];\r
+extern GU16 g_pusDrvCurrentRecord[];\r
+extern GU8 g_uchPacketMaxLenSupport;\r
+extern GU16 g_usGh3x2xDataIndexInBuf;\r
+extern GF32 g_fGsDataIndexInBuf;\r
+extern GU16 g_usAlgoResIndex;\r
+extern GU32 g_unLastIncompleteMark;\r
+extern GU8 g_uchFifoPackageID;\r
+extern GU8 g_uchFifoPackageMode;\r
+extern void Gh2x2xPackPakcageHeader(GU8 *puchNeedContinue, GU8 uchFunctionIDForMaster, GU8 *puchUploadBuf, GU8 *puchTagArray,\r
+                                            GU8 uchGsEnable, GU8 uchAlgoResFlag, GU8 uchAgcEnable, GU8 uchAmbEnable, GU8 uchGsGyroEnable,GU8 uchCapEnable,GU8 uchTempEnable,\r
+                                            GU8 uchZipEnableFlag, GU8 uchOddEvenChangeFlag);\r
+extern void GH3x2xSendFunctionInfo(const STGh3x2xFrameInfo * const pstFrameInfo);\r
+\r
+/**\r
+ * @fn     void GH3X2X_GetRawDataDiff(GU32 *punRawData, GU8 *puchRawdataTagTempArr, \r
+                                     GU8 uchChannelMapCnt, GU8 *puchZipDataArr, GU8 *puchZipDataArrSize)\r
+*\r
+* @brief  Pack and Generate Zip RawData Data.\r
+*\r
+* @attention   None\r
+*\r
+* @param[out]  puchZipDataArr          Zip Paclage Data.\r
+* @param[out]  puchZipDataArrSize      Zip Package Size.\r
+* @param[in]   punRawData              Current Gsensor Data.\r
+* @param[in]   puchRawdataTagTempArr   Current Gsensor Data.\r
+* @param[in]   uchChannelMapCnt        Current Gsensor Data.\r
+\r
+* @return  None\r
+*/\r
+void GH3X2X_GetRawDataDiff(GU32 *punRawData, GU8 *puchRawdataTagTempArr, \r
+                            GU8 uchChannelMapCnt, GU8 *puchZipArr, GU8 *puchZipDataArrSize, \r
+                            GU8 *uchFifoLastRawdataTagArr, GU32 *unFifoLastRawdataArr)\r
+{\r
+    GU8 uchDiffunittemp;\r
+    GS8 chNum;\r
+    GU8 uchChnum;\r
+    GU32 unChnum;\r
+    GU8 uchDifftemp;\r
+    GU8 uchDiffarrcnt8bit = 0;\r
+    GU8 uchDiffarrcnt4bit = 0;\r
+    GU8 uchDataType = 0;\r
+\r
+    GU8 puchZipDataArr[255];\r
+    GH3X2X_Memset(puchZipDataArr, 0, 255);\r
+\r
+    if (puchRawdataTagTempArr[0] != uchFifoLastRawdataTagArr[0])\r
+    {\r
+        uchDiffarrcnt8bit++;\r
+        puchZipDataArr[uchDiffarrcnt8bit] = RAWDATA_DIFF_ODD;\r
+        GH3X2X_Memcpy(&puchZipDataArr[uchDiffarrcnt8bit+RAWDATA_DIFF_ODD], puchRawdataTagTempArr, uchChannelMapCnt);\r
+        uchDiffarrcnt8bit += uchChannelMapCnt;\r
+        uchDiffarrcnt4bit += (GU8)(uchChannelMapCnt*RAWDATA_DIFF_EVEN);\r
+    }\r
+    else\r
+    {\r
+        uchDiffarrcnt8bit++;\r
+        puchZipDataArr[uchDiffarrcnt8bit] = 0;\r
+    }\r
+\r
+    for (uchChnum = 0 ; uchChnum < uchChannelMapCnt ; uchChnum++)\r
+    {\r
+        if (punRawData[uchChnum] >= unFifoLastRawdataArr[uchChnum])\r
+        {\r
+            unChnum = punRawData[uchChnum] - unFifoLastRawdataArr[uchChnum];\r
+        }\r
+        else\r
+        {\r
+            unChnum = unFifoLastRawdataArr[uchChnum] - punRawData[uchChnum];\r
+        }\r
+\r
+        for (chNum = RAWDATA_DIFF_SIZE ; chNum >= 0 ; chNum--)\r
+        {\r
+            if (unChnum == 0)\r
+            {\r
+                uchDataType = 0;\r
+                break;\r
+            }\r
+            uchDifftemp = ((GU8)(GH3X2X_GET_FIRST_4BITS((unChnum) >> (chNum*RAWDATA_DIFF_BYTE_SIZE))));\r
+            if (uchDifftemp != 0)\r
+            {\r
+                uchDataType = chNum * RAWDATA_DIFF_EVEN + GH3X2X_VAL_DIFF_STA(punRawData[uchChnum], \\r
+                    unFifoLastRawdataArr[uchChnum]);\r
+                break;\r
+            }\r
+        }\r
+\r
+        if (uchDiffarrcnt4bit%RAWDATA_DIFF_EVEN)\r
+        {\r
+            puchZipDataArr[uchDiffarrcnt8bit] |= uchDataType;\r
+        }\r
+\r
+        else\r
+        {\r
+            uchDiffarrcnt8bit++;\r
+            puchZipDataArr[uchDiffarrcnt8bit] |= (GU8)(uchDataType << RAWDATA_DIFF_BYTE_SIZE);\r
+        }\r
+        uchDiffarrcnt4bit++;\r
+        \r
+        for (chNum = (GU8)(uchDataType/RAWDATA_DIFF_EVEN) ; chNum >= 0 ; chNum--)\r
+        {\r
+            uchDiffunittemp = (GU8)(GH3X2X_GET_FIRST_4BITS((unChnum) >> (chNum*RAWDATA_DIFF_BYTE_SIZE)));\r
+            if (uchDiffarrcnt4bit%RAWDATA_DIFF_EVEN)\r
+            {\r
+                puchZipDataArr[uchDiffarrcnt8bit] |= uchDiffunittemp;\r
+            }\r
+            else\r
+            {\r
+                uchDiffarrcnt8bit++;\r
+                puchZipDataArr[uchDiffarrcnt8bit] |= (GU8)(uchDiffunittemp << RAWDATA_DIFF_BYTE_SIZE);\r
+            }\r
+            uchDiffarrcnt4bit++;\r
+        }\r
+    }// end of (for uchChnum=0;uchChnum<uchChannelMapCnt;uchChnum++)\r
+    \r
+    uchDiffarrcnt8bit = (uchDiffarrcnt4bit + RAWDATA_DIFF_ODD) / RAWDATA_DIFF_EVEN + RAWDATA_DIFF_ODD;\r
+    puchZipDataArr[0] = uchDiffarrcnt8bit;\r
+    *puchZipDataArrSize = (GU8)(uchDiffarrcnt8bit + RAWDATA_DIFF_ODD);\r
+    GH3X2X_Memcpy(puchZipArr, puchZipDataArr, uchDiffarrcnt8bit + 1);\r
+}\r
+\r
+/**\r
+ * @fn     void GH3X2X_GetDataDiff(GU32 *punData, GU8 uchChannelMapCnt, GU8 *puchZipDataArr, \r
+                            GU8 *puchZipDataArrSize, GU32 *punZipTempData)\r
+*\r
+* @brief  Pack and Generate Zip RawData Data.\r
+*\r
+* @attention   None\r
+*\r
+* @param[out]  puchZipDataArr          Zip Paclage Data.\r
+* @param[out]  puchZipDataArrSize      Zip Package Size.\r
+* @param[in]   punData              Current Gsensor Data.\r
+* @param[in]   punZipTempData   Current Gsensor Data.\r
+* @param[in]   uchChannelMapCnt        Current Gsensor Data.\r
+\r
+* @return  None\r
+*/\r
+void GH3X2X_GetDataDiff(GU32 *punData, GU8 uchChannelMapCnt, GU8 *puchZipDataArr, \r
+                        GU8 *puchZipDataArrSize, GU32 *punZipTempData)\r
+{\r
+    GU8 uchDiffunittemp;\r
+    GS8 chNum;\r
+    GU8 uchChnum;\r
+    GU32 unChnum;\r
+    GU8 uchDifftemp;\r
+    GU8 uchDiffarrcnt8bit = 0;\r
+    GU8 uchDiffarrcnt4bit = 0;\r
+    GU8 uchDataType = 0;\r
+\r
+    //GU8 puchZipDataArr[255];\r
+    //GH3X2X_Memset(puchZipDataArr, 0, 255);\r
+\r
+    for (uchChnum = 0 ; uchChnum < uchChannelMapCnt ; uchChnum++)\r
+    {\r
+        if (punData[uchChnum] >= punZipTempData[uchChnum])\r
+        {\r
+            unChnum = punData[uchChnum] - punZipTempData[uchChnum];\r
+        }\r
+        else\r
+        {\r
+            unChnum = punZipTempData[uchChnum] - punData[uchChnum];\r
+        }\r
+        \r
+        for (chNum = RAWDATA_DIFF_SIZE ; chNum >= 0 ; chNum--)\r
+        {\r
+            if (unChnum == 0)\r
+            {\r
+                uchDataType = 0;\r
+                break;\r
+            }\r
+            uchDifftemp = ((GU8)(GH3X2X_GET_FIRST_4BITS((unChnum) >> (chNum*RAWDATA_DIFF_BYTE_SIZE))));\r
+            if (uchDifftemp != 0)\r
+            {\r
+                uchDataType = chNum * RAWDATA_DIFF_EVEN + GH3X2X_VAL_DIFF_STA(punData[uchChnum], \\r
+                    punZipTempData[uchChnum]);\r
+                break;\r
+            }\r
+        }\r
+\r
+        if (uchDiffarrcnt4bit%RAWDATA_DIFF_EVEN)\r
+        {\r
+            puchZipDataArr[uchDiffarrcnt8bit] |= uchDataType;\r
+        }\r
+\r
+        else\r
+        {\r
+            uchDiffarrcnt8bit++;\r
+            puchZipDataArr[uchDiffarrcnt8bit] |= (GU8)(uchDataType << RAWDATA_DIFF_BYTE_SIZE);\r
+        }\r
+        uchDiffarrcnt4bit++;\r
+        \r
+        for (chNum = (GS8)(uchDataType/RAWDATA_DIFF_EVEN) ; chNum >= 0 ; chNum--)\r
+        {\r
+            uchDiffunittemp = (GU8)(GH3X2X_GET_FIRST_4BITS((unChnum) >> (chNum*RAWDATA_DIFF_BYTE_SIZE)));\r
+            if (uchDiffarrcnt4bit%RAWDATA_DIFF_EVEN)\r
+            {\r
+                puchZipDataArr[uchDiffarrcnt8bit] |= uchDiffunittemp;\r
+            }\r
+            else\r
+            {\r
+                uchDiffarrcnt8bit++;\r
+                puchZipDataArr[uchDiffarrcnt8bit] |= (GU8)(uchDiffunittemp << RAWDATA_DIFF_BYTE_SIZE);\r
+            }\r
+            uchDiffarrcnt4bit++;\r
+        }\r
+    }// end of (for uchChnum=0;uchChnum<uchChannelMapCnt;uchChnum++)\r
+    \r
+    uchDiffarrcnt8bit = (uchDiffarrcnt4bit + RAWDATA_DIFF_ODD) / RAWDATA_DIFF_EVEN + RAWDATA_DIFF_ODD;\r
+    puchZipDataArr[0] = uchDiffarrcnt8bit;\r
+    *puchZipDataArrSize = (GU8)(uchDiffarrcnt8bit + RAWDATA_DIFF_ODD);\r
+//    GH3X2X_Memcpy(puchZipArr, puchZipDataArr, uchDiffarrcnt8bit + 1);\r
+}\r
+\r
+void GH3X2X_ZipFillLastRawdataBuffer(const STGh3x2xFrameInfo * const pstFrameInfo, GU32 unFunctionID, \r
+                                            GU8 uchChnlNum, GU8 *uchFifoLastRawdataTagArr, GU32 *unFifoLastRawdataArr)\r
+{\r
+    for(GU8 uchChnlCnt = 0; uchChnlCnt < uchChnlNum; uchChnlCnt ++)\r
+    {\r
+        //led adj flag 0 \r
+        if(pstFrameInfo->punFrameFlag[0]&((((GU32)1)) << uchChnlCnt))\r
+        {\r
+            pstFrameInfo->punFrameRawdata[uchChnlCnt] |= ((((GU32)1)) << 26);\r
+        }\r
+        // fast recovery\r
+        if ((GH3X2X_FUNCTION_ECG == unFunctionID)||(GH3X2X_FUNCTION_PWTT == unFunctionID))\r
+        {\r
+            if(0 == uchChnlCnt)\r
+            {\r
+                if(pstFrameInfo->punFrameFlag[2]&((((GU32)1)) << 0))\r
+                {\r
+                    pstFrameInfo->punFrameRawdata[uchChnlCnt] |= ((((GU32)1)) << 26);\r
+                }\r
+            }\r
+        }\r
+        //led adj flag 1 \r
+        if(pstFrameInfo->punFrameFlag[1]&((((GU32)1)) << uchChnlCnt))\r
+        {\r
+            pstFrameInfo->punFrameRawdata[uchChnlCnt] |= ((((GU32)1)) << 25);\r
+        }\r
+        \r
+        uchFifoLastRawdataTagArr[uchChnlCnt] = (pstFrameInfo->punFrameRawdata[uchChnlCnt] >> 24)&0x000000FF;\r
+        unFifoLastRawdataArr[uchChnlCnt] = pstFrameInfo->punFrameRawdata[uchChnlCnt]&0x00FFFFFF;\r
+\r
+        pstFrameInfo->punFrameRawdata[uchChnlCnt] &= 0x00FFFFFF;\r
+    }\r
+}\r
+\r
+void GH3X2X_ZipFillLastDataBuffer(GU32 *unCurrentData, GU8 uchChnlNum, GU32 *unLastdata)\r
+{\r
+    for(GU8 uchChnlCnt = 0; uchChnlCnt < uchChnlNum; uchChnlCnt ++)\r
+    {\r
+        unLastdata[uchChnlCnt] = unCurrentData[uchChnlCnt];\r
+    }\r
+}\r
+\r
+\r
+extern GU8 g_uchGh3x2xUploadStatus;\r
+extern GU8 g_uchGh3x2xUploadBufUse;\r
+GU8 g_uchCurrentFunctionID = 0;\r
+\r
+#if (__SUPPORT_PROTOCOL_ANALYZE__)\r
+void Gh2x2xUploadZipDataToMaster(const STGh3x2xFrameInfo * const pstFrameInfo, GU16 usFrameCnt, GU16 usFrameNum, GU8* puchTagArray)\r
+{\r
+    GU8  uchChnlNum;\r
+    GU32 unFunctionID;\r
+    GU8  uchFunctionIDForMaster = 0xFF;\r
+    GU8  uchGsEnable;\r
+    GU8  uchCapEnable;\r
+    GU8  uchTempEnable;\r
+    GU8  uchGsGyroEnable;\r
+    GU8  uchAgcEnable;\r
+    GU8  uchAmbEnable;\r
+    GU8  uchAlgoResFlag;\r
+    GU16 uchOneFrameByteNum = 0;\r
+    GU8  uchReslutByteNum;\r
+    GU8  uchNeedContinue;\r
+    GU8  *puchUploadBuf = g_pstGh3x2xProtocolData->puchPacketPayloadArr + 4;\r
+    GU8 puchTempFrameDataBuf[2 * (GH3X2X_UPROTOCOL_PAYLOAD_LEN_MAX + 8)];\r
+    GU16 usRespondLen;\r
+    GU8 uchFramePosi;\r
+    GU8 uchEvenFirstFrameFlag = 0;\r
+\r
+    GU8 uchZipRawdataArr[GH3X2X_UPROTOCOL_PAYLOAD_LEN_MAX] = {0};\r
+    GU8 uchZipRawdataArrSize = 0;\r
+    GU8 uchZipAgcdataArr[GH3X2X_UPROTOCOL_PAYLOAD_LEN_MAX] = {0};\r
+    GU8 uchZipAgcdataArrSize = 0;\r
+    GU8 uchFifoLastRawdataTagArr[CHANNEL_MAP_ID_NUM] = {0};\r
+    GU32 unFrameRawdataArr[CHANNEL_MAP_ID_NUM] = {0};\r
+    GU32 unAgcdataArr[CHANNEL_MAP_ID_NUM] = {0};\r
+\r
+    GU8 uchFirstFrameLen = 0;\r
+    GU8 uchFillLastFrameDataFlag = 0;\r
+\r
+    GU8 uchFlag2ChangeFlag = 0;\r
+\r
+    if(0 == pstFrameInfo)\r
+    {\r
+        return;\r
+    }\r
+    unFunctionID = pstFrameInfo->unFunctionID;\r
+    uchChnlNum = pstFrameInfo->pstFunctionInfo->uchChnlNum;\r
+    uchFramePosi = 0;\r
+    if(0 == usFrameCnt)\r
+    {\r
+        uchFramePosi |= GH3X2X_FRAME_POSI_HEAD;\r
+    }\r
+    if((usFrameNum - 1) == usFrameCnt)\r
+    {\r
+        uchFramePosi |= GH3X2X_FRAME_POSI_TAIL;\r
+    }\r
+    /*\r
+    if(GH3X2X_FUNCTION_SOFT_ADT_IR == unFunctionID)\r
+    {\r
+        unFunctionID = GH3X2X_FUNCTION_SOFT_ADT_GREEN;  //adt ir and adt green store in one csv file\r
+    }\r
+    */\r
+\r
+    //function id transform\r
+    for (int uchOffsetCnt = 0 ; uchOffsetCnt < GH3X2X_FUNC_OFFSET_MAX ; uchOffsetCnt ++)\r
+    {\r
+        if ((unFunctionID >> uchOffsetCnt) & 0x1)\r
+        {\r
+            uchFunctionIDForMaster = uchOffsetCnt;\r
+        }\r
+    }\r
+\r
+    \r
+    if (g_uchCurrentFunctionID != uchFunctionIDForMaster)\r
+    {\r
+        g_uchCurrentFunctionID = uchFunctionIDForMaster;\r
+        g_uchOddEvenChangeFlag = 1;\r
+    }\r
+\r
+    if(0xFF == uchFunctionIDForMaster)  //invalid function id\r
+    {\r
+        return;\r
+    }\r
+    uchGsEnable = g_uchGsensorEnable;\r
+    uchGsGyroEnable = (g_uchGyroEnable & uchGsEnable);\r
+    uchCapEnable =  GH3X2X_GetCapEnableFlag();\r
+    uchTempEnable = GH3X2X_GetTempEnableFlag();\r
+    uchAgcEnable = 1;\r
+    if(unFunctionID == GH3X2X_FUNC_OFFSET_ECG)\r
+    {\r
+        uchAgcEnable = 0;\r
+    }\r
+    uchAmbEnable = 0;\r
+    uchAlgoResFlag = 1;\r
+\r
+\r
+    /********  calculate how many bytes in one frame  ******/\r
+    //result byte num\r
+    uchReslutByteNum = 0;\r
+    uchReslutByteNum += 1;\r
+    //flag 0 softAGC\r
+    uchReslutByteNum += 5;\r
+    //FLAG 2\r
+    uchReslutByteNum += 5;\r
+    //FLAG 3 (need upload on only first frame)\r
+    if(uchFramePosi&GH3X2X_FRAME_POSI_HEAD)\r
+    {\r
+        uchReslutByteNum += 5;\r
+    }\r
+\r
+    #if GH3X2X_DIVIDE_ZERO_FLAG_UPLODE_EN\r
+    //flag4\r
+    uchReslutByteNum += 5;\r
+    #endif\r
+\r
+    //section FRAME_ID\r
+    uchFirstFrameLen += 2;\r
+    uchFirstFrameLen += 1;\r
+    //section GSENSOR_DATA\r
+    if(uchGsEnable)\r
+    {\r
+        uchFirstFrameLen += 6;\r
+        if(uchGsGyroEnable)\r
+        {\r
+            uchFirstFrameLen += 6;\r
+        }\r
+    }\r
+    //section Cap and temp\r
+    if(uchCapEnable)\r
+    {\r
+        uchFirstFrameLen += 12;\r
+    }\r
+    if(uchTempEnable)\r
+    {\r
+        uchFirstFrameLen += 12;\r
+    }\r
+    \r
+    if (uchAlgoResFlag && 1 == pstFrameInfo->pstAlgoResult->uchUpdateFlag)\r
+    {\r
+        uchOneFrameByteNum += (5*pstFrameInfo->pstAlgoResult->uchResultNum);\r
+        uchReslutByteNum += (5*pstFrameInfo->pstAlgoResult->uchResultNum);\r
+    }\r
+\r
+    GH3x2xSendFunctionInfo(pstFrameInfo); //send function info when first frame\r
+    \r
+    uchNeedContinue = 1;\r
+    while(uchNeedContinue)\r
+    {\r
+        if(GH3X2X_UPLOAD_STATUS_NULL == g_uchGh3x2xUploadStatus)\r
+        {\r
+            Gh2x2xPackPakcageHeader(&uchNeedContinue, uchFunctionIDForMaster,\\r
+                            puchUploadBuf, puchTagArray, uchGsEnable, uchAlgoResFlag,\\r
+                            uchAgcEnable, uchAmbEnable, uchGsGyroEnable, uchCapEnable,uchTempEnable,1, g_uchOddEvenChangeFlag);\r
+        }\r
+\r
+        \r
+        if(GH3X2X_UPLOAD_STATUS_HAVE_STORE_DATA == g_uchGh3x2xUploadStatus && uchFillLastFrameDataFlag == 0)\r
+        {\r
+            \r
+            uchNeedContinue = 0;\r
+            uchOneFrameByteNum = 0;\r
+            \r
+            //section FRAME_ID\r
+            puchTempFrameDataBuf[uchOneFrameByteNum] = ((*(pstFrameInfo->punFrameCnt))&0x000000FF);\r
+        \r
+            \r
+            uchOneFrameByteNum ++;\r
+            //section GSENSOR_DATA\r
+            if(uchGsEnable)\r
+            {\r
+                GS16 *psGsensorData;\r
+                psGsensorData = pstFrameInfo->pusFrameGsensordata;\r
+                puchTempFrameDataBuf[uchOneFrameByteNum] = GH3X2X_GET_HIGH_BYTE_FROM_WORD(psGsensorData[0]); //gsx\r
+                uchOneFrameByteNum += 1;\r
+                puchTempFrameDataBuf[uchOneFrameByteNum] = GH3X2X_GET_LOW_BYTE_FROM_WORD(psGsensorData[0]);\r
+                uchOneFrameByteNum += 1;\r
+                \r
+                puchTempFrameDataBuf[uchOneFrameByteNum] = GH3X2X_GET_HIGH_BYTE_FROM_WORD(psGsensorData[1]); //gsy\r
+                uchOneFrameByteNum += 1;\r
+                puchTempFrameDataBuf[uchOneFrameByteNum] = GH3X2X_GET_LOW_BYTE_FROM_WORD(psGsensorData[1]);\r
+                uchOneFrameByteNum += 1;\r
+                \r
+                puchTempFrameDataBuf[uchOneFrameByteNum] = GH3X2X_GET_HIGH_BYTE_FROM_WORD(psGsensorData[2]); //gsz\r
+                uchOneFrameByteNum += 1;\r
+                puchTempFrameDataBuf[uchOneFrameByteNum] = GH3X2X_GET_LOW_BYTE_FROM_WORD(psGsensorData[2]);\r
+                uchOneFrameByteNum += 1;\r
+                if(uchGsGyroEnable)\r
+                {\r
+                    puchTempFrameDataBuf[uchOneFrameByteNum] = GH3X2X_GET_HIGH_BYTE_FROM_WORD(psGsensorData[3]); //gyrox\r
+                    uchOneFrameByteNum += 1;\r
+                    puchTempFrameDataBuf[uchOneFrameByteNum] = GH3X2X_GET_LOW_BYTE_FROM_WORD(psGsensorData[3]);\r
+                    uchOneFrameByteNum += 1;\r
+                    \r
+                    puchTempFrameDataBuf[uchOneFrameByteNum] = GH3X2X_GET_HIGH_BYTE_FROM_WORD(psGsensorData[4]); //gyroy\r
+                    uchOneFrameByteNum += 1;\r
+                    puchTempFrameDataBuf[uchOneFrameByteNum] = GH3X2X_GET_LOW_BYTE_FROM_WORD(psGsensorData[4]);\r
+                    uchOneFrameByteNum += 1;\r
+                    \r
+                    puchTempFrameDataBuf[uchOneFrameByteNum] = GH3X2X_GET_HIGH_BYTE_FROM_WORD(psGsensorData[5]); //gyroz\r
+                    uchOneFrameByteNum += 1;\r
+                    puchTempFrameDataBuf[uchOneFrameByteNum] = GH3X2X_GET_LOW_BYTE_FROM_WORD(psGsensorData[5]);\r
+                    uchOneFrameByteNum += 1;\r
+                }\r
+            }\r
+            if(uchCapEnable)\r
+            {\r
+            \r
+                puchTempFrameDataBuf[uchOneFrameByteNum] = GH3X2X_GET_BYTE2_FROM_DWORD(pstFrameInfo->pstFrameCapdata->unCapData[0]); \r
+                uchOneFrameByteNum += 1;\r
+                puchTempFrameDataBuf[uchOneFrameByteNum] = GH3X2X_GET_BYTE1_FROM_DWORD(pstFrameInfo->pstFrameCapdata->unCapData[0]); \r
+                uchOneFrameByteNum += 1;\r
+                puchTempFrameDataBuf[uchOneFrameByteNum] = GH3X2X_GET_BYTE0_FROM_DWORD(pstFrameInfo->pstFrameCapdata->unCapData[0]); \r
+                uchOneFrameByteNum += 1;\r
+\r
+                puchTempFrameDataBuf[uchOneFrameByteNum] = GH3X2X_GET_BYTE2_FROM_DWORD(pstFrameInfo->pstFrameCapdata->unCapData[1]); \r
+                uchOneFrameByteNum += 1;\r
+                puchTempFrameDataBuf[uchOneFrameByteNum] = GH3X2X_GET_BYTE1_FROM_DWORD(pstFrameInfo->pstFrameCapdata->unCapData[1]); \r
+                uchOneFrameByteNum += 1;\r
+                puchTempFrameDataBuf[uchOneFrameByteNum] = GH3X2X_GET_BYTE0_FROM_DWORD(pstFrameInfo->pstFrameCapdata->unCapData[1]); \r
+                uchOneFrameByteNum += 1;\r
+\r
+                puchTempFrameDataBuf[uchOneFrameByteNum] = GH3X2X_GET_BYTE2_FROM_DWORD(pstFrameInfo->pstFrameCapdata->unCapData[2]); \r
+                uchOneFrameByteNum += 1;\r
+                puchTempFrameDataBuf[uchOneFrameByteNum] = GH3X2X_GET_BYTE1_FROM_DWORD(pstFrameInfo->pstFrameCapdata->unCapData[2]); \r
+                uchOneFrameByteNum += 1;\r
+                puchTempFrameDataBuf[uchOneFrameByteNum] = GH3X2X_GET_BYTE0_FROM_DWORD(pstFrameInfo->pstFrameCapdata->unCapData[2]); \r
+                uchOneFrameByteNum += 1;\r
+\r
+                puchTempFrameDataBuf[uchOneFrameByteNum] = GH3X2X_GET_BYTE2_FROM_DWORD(pstFrameInfo->pstFrameCapdata->unCapData[3]); \r
+                uchOneFrameByteNum += 1;\r
+                puchTempFrameDataBuf[uchOneFrameByteNum] = GH3X2X_GET_BYTE1_FROM_DWORD(pstFrameInfo->pstFrameCapdata->unCapData[3]); \r
+                uchOneFrameByteNum += 1;\r
+                puchTempFrameDataBuf[uchOneFrameByteNum] = GH3X2X_GET_BYTE0_FROM_DWORD(pstFrameInfo->pstFrameCapdata->unCapData[3]); \r
+                uchOneFrameByteNum += 1;\r
+\r
+            }\r
+            if(uchTempEnable)\r
+            {\r
+            \r
+                puchTempFrameDataBuf[uchOneFrameByteNum] = GH3X2X_GET_BYTE2_FROM_DWORD(pstFrameInfo->pstFrameTempdata->unTempData[0]); \r
+                uchOneFrameByteNum += 1;\r
+                puchTempFrameDataBuf[uchOneFrameByteNum] = GH3X2X_GET_BYTE1_FROM_DWORD(pstFrameInfo->pstFrameTempdata->unTempData[0]); \r
+                uchOneFrameByteNum += 1;\r
+                puchTempFrameDataBuf[uchOneFrameByteNum] = GH3X2X_GET_BYTE0_FROM_DWORD(pstFrameInfo->pstFrameTempdata->unTempData[0]); \r
+                uchOneFrameByteNum += 1;\r
+                \r
+                puchTempFrameDataBuf[uchOneFrameByteNum] = GH3X2X_GET_BYTE2_FROM_DWORD(pstFrameInfo->pstFrameTempdata->unTempData[1]); \r
+                uchOneFrameByteNum += 1;\r
+                puchTempFrameDataBuf[uchOneFrameByteNum] = GH3X2X_GET_BYTE1_FROM_DWORD(pstFrameInfo->pstFrameTempdata->unTempData[1]); \r
+                uchOneFrameByteNum += 1;\r
+                puchTempFrameDataBuf[uchOneFrameByteNum] = GH3X2X_GET_BYTE0_FROM_DWORD(pstFrameInfo->pstFrameTempdata->unTempData[1]); \r
+                uchOneFrameByteNum += 1;\r
+            \r
+                puchTempFrameDataBuf[uchOneFrameByteNum] = GH3X2X_GET_BYTE2_FROM_DWORD(pstFrameInfo->pstFrameTempdata->unTempData[2]); \r
+                uchOneFrameByteNum += 1;\r
+                puchTempFrameDataBuf[uchOneFrameByteNum] = GH3X2X_GET_BYTE1_FROM_DWORD(pstFrameInfo->pstFrameTempdata->unTempData[2]); \r
+                uchOneFrameByteNum += 1;\r
+                puchTempFrameDataBuf[uchOneFrameByteNum] = GH3X2X_GET_BYTE0_FROM_DWORD(pstFrameInfo->pstFrameTempdata->unTempData[2]); \r
+                uchOneFrameByteNum += 1;\r
+            \r
+                puchTempFrameDataBuf[uchOneFrameByteNum] = GH3X2X_GET_BYTE2_FROM_DWORD(pstFrameInfo->pstFrameTempdata->unTempData[3]); \r
+                uchOneFrameByteNum += 1;\r
+                puchTempFrameDataBuf[uchOneFrameByteNum] = GH3X2X_GET_BYTE1_FROM_DWORD(pstFrameInfo->pstFrameTempdata->unTempData[3]); \r
+                uchOneFrameByteNum += 1;\r
+                puchTempFrameDataBuf[uchOneFrameByteNum] = GH3X2X_GET_BYTE0_FROM_DWORD(pstFrameInfo->pstFrameTempdata->unTempData[3]); \r
+                uchOneFrameByteNum += 1;\r
+            \r
+            }\r
+            //section RAWDATA\r
+            //set flag ,copy rawdata, clear flag\r
+            \r
+            if (GH3X2X_GetFifoPackageMode() == 1)\r
+            {\r
+                if (g_uchOddEvenChangeFlag && g_uchGh3x2xUploadBufUse <= GH3X2X_UPLOAD_PACKAGE_HEAD_SIZE)\r
+                {\r
+                    uchEvenFirstFrameFlag = 1;\r
+                }\r
+                puchTempFrameDataBuf[uchOneFrameByteNum] = g_uchFifoPackageID;\r
+                uchOneFrameByteNum ++;\r
+            }\r
+            else\r
+            {\r
+                if (g_uchOddEvenChangeFlag && g_uchGh3x2xUploadBufUse <= GH3X2X_UPLOAD_PACKAGE_HEAD_SIZE)\r
+                {\r
+                    uchEvenFirstFrameFlag = 1;\r
+                    for(GU8 uchChnlCnt = 0; uchChnlCnt < uchChnlNum; uchChnlCnt ++)\r
+                    {\r
+                        //led adj flag 0 \r
+                        if(pstFrameInfo->punFrameFlag[0]&((((GU32)1)) << uchChnlCnt))\r
+                        {\r
+                            pstFrameInfo->punFrameRawdata[uchChnlCnt] |= ((((GU32)1)) << 26);\r
+                        }\r
+                        // fast recovery\r
+                        if ((GH3X2X_FUNCTION_ECG == unFunctionID)||(GH3X2X_FUNCTION_PWTT == unFunctionID))\r
+                        {\r
+                            if(0 == uchChnlCnt)\r
+                            {\r
+                                if(pstFrameInfo->punFrameFlag[2]&((((GU32)1)) << 0))\r
+                                {\r
+                                    pstFrameInfo->punFrameRawdata[uchChnlCnt] |= ((((GU32)1)) << 26);\r
+                                }\r
+                            }\r
+                        }\r
+                        //led adj flag 1 \r
+                        if(pstFrameInfo->punFrameFlag[1]&((((GU32)1)) << uchChnlCnt))\r
+                        {\r
+                            pstFrameInfo->punFrameRawdata[uchChnlCnt] |= ((((GU32)1)) << 25);\r
+                        }\r
+\r
+                        puchTempFrameDataBuf[uchOneFrameByteNum] = (pstFrameInfo->punFrameRawdata[uchChnlCnt] >> 24)&0x000000FF;\r
+                        uchOneFrameByteNum ++;\r
+                        \r
+                        puchTempFrameDataBuf[uchOneFrameByteNum] = (pstFrameInfo->punFrameRawdata[uchChnlCnt] >> 16)&0x000000FF;\r
+                        uchOneFrameByteNum ++;\r
+                        \r
+                        puchTempFrameDataBuf[uchOneFrameByteNum] = (pstFrameInfo->punFrameRawdata[uchChnlCnt] >> 8)&0x000000FF;\r
+                        uchOneFrameByteNum ++;\r
+                        \r
+                        puchTempFrameDataBuf[uchOneFrameByteNum] = (pstFrameInfo->punFrameRawdata[uchChnlCnt] >> 0)&0x000000FF;\r
+                        uchOneFrameByteNum ++;\r
+\r
+                        g_stZipLastData.uchFifoLastRawdataTagArr[uchFunctionIDForMaster][uchChnlCnt] = (pstFrameInfo->punFrameRawdata[uchChnlCnt] >> 24)&0x000000FF;\r
+                        g_stZipLastData.unFifoLastRawdataArr[uchChnlCnt] = pstFrameInfo->punFrameRawdata[uchChnlCnt]&0x00FFFFFF;\r
+\r
+                        pstFrameInfo->punFrameRawdata[uchChnlCnt] &= 0x00FFFFFF;\r
+                    }\r
+                }\r
+                else\r
+                {\r
+                    GH3X2X_ZipFillLastRawdataBuffer(pstFrameInfo, unFunctionID, uchChnlNum, uchFifoLastRawdataTagArr, unFrameRawdataArr);\r
+                    GH3X2X_GetRawDataDiff(unFrameRawdataArr, uchFifoLastRawdataTagArr,\\r
+                        uchChnlNum, uchZipRawdataArr, &uchZipRawdataArrSize,\\r
+                        g_stZipLastData.uchFifoLastRawdataTagArr[uchFunctionIDForMaster], g_stZipLastData.unFifoLastRawdataArr);\r
+                    GH3X2X_Memcpy(&puchTempFrameDataBuf[uchOneFrameByteNum], uchZipRawdataArr, uchZipRawdataArrSize);\r
+                                    uchOneFrameByteNum += uchZipRawdataArrSize;\r
+                }\r
+            }\r
+            //section AGC_INFO\r
+            if(uchAgcEnable)\r
+            {\r
+                if (uchEvenFirstFrameFlag)\r
+                {\r
+                    GH3X2X_ZipFillLastDataBuffer(pstFrameInfo->punFrameAgcInfo, uchChnlNum, g_stZipLastData.unFifoLastAgcdataArr);\r
+                    GH3X2X_Memcpy((GU8*)&(puchTempFrameDataBuf[uchOneFrameByteNum]), (GU8*)(pstFrameInfo->punFrameAgcInfo), uchChnlNum*4);\r
+                    uchOneFrameByteNum += uchChnlNum*4;\r
+                }\r
+                else\r
+                {\r
+                    GH3X2X_ZipFillLastDataBuffer(pstFrameInfo->punFrameAgcInfo, uchChnlNum, unAgcdataArr);\r
+                    GH3X2X_GetDataDiff(unAgcdataArr, uchChnlNum, uchZipAgcdataArr, \r
+                                    &uchZipAgcdataArrSize, g_stZipLastData.unFifoLastAgcdataArr);\r
+                    GH3X2X_Memcpy(&puchTempFrameDataBuf[uchOneFrameByteNum], uchZipAgcdataArr, uchZipAgcdataArrSize);\r
+                    uchOneFrameByteNum += uchZipAgcdataArrSize;\r
+                }\r
+            }\r
+\r
+            //section AmbData\r
+            if(uchAmbEnable)\r
+            {\r
+                GH3X2X_Memcpy((GU8*)&(puchUploadBuf[uchOneFrameByteNum]), (GU8*)(pstFrameInfo->punFrameAgcInfo), uchChnlNum*3);\r
+                uchOneFrameByteNum += uchChnlNum*3;\r
+            }\r
+            \r
+            //section RESLUT_DATA\r
+            //result byte num\r
+            //puchTempFrameDataBuf[g_uchGh3x2xUploadBufUse] = 0;\r
+            GU8 uchRealReslutByteNum = uchReslutByteNum;\r
+            uchOneFrameByteNum ++;\r
+            // Soft AGC Flag\r
+            if (GH3X2X_FUNCTION_ECG != unFunctionID)\r
+            {\r
+                puchTempFrameDataBuf[uchOneFrameByteNum] = 0;\r
+                uchOneFrameByteNum ++;  \r
+                #if __SUPPORT_SOFT_AGC_CONFIG__  \r
+                pstFrameInfo->punFrameFlag[0] = NewAgcMainChelFlag;\r
+                #endif\r
+                GH3X2X_Memcpy((GU8*)&(puchTempFrameDataBuf[uchOneFrameByteNum]), (GU8*)(&(pstFrameInfo->punFrameFlag[0])), 4);\r
+                uchOneFrameByteNum += 4;\r
+                #if __SUPPORT_SOFT_AGC_CONFIG__\r
+                NewAgcMainChelFlag = 0;\r
+                #endif\r
+                \r
+            }\r
+            else\r
+            {\r
+                uchRealReslutByteNum -= 5;\r
+            }\r
+            //flag2\r
+            if ((*(pstFrameInfo->punFrameCnt)) == 0 || pstFrameInfo->punFrameFlag[2] != g_unLastFrameFlag2 || uchFlag2ChangeFlag)\r
+            {\r
+                puchTempFrameDataBuf[uchOneFrameByteNum] = 2;\r
+                uchOneFrameByteNum ++;\r
+                GH3X2X_Memcpy((GU8*)&(puchTempFrameDataBuf[uchOneFrameByteNum]), (GU8*)(&(pstFrameInfo->punFrameFlag[2])), 4);\r
+                uchOneFrameByteNum += 4;\r
+                g_unLastFrameFlag2 = pstFrameInfo->punFrameFlag[2];\r
+                uchFlag2ChangeFlag = 1;\r
+            }\r
+            else\r
+            {\r
+                uchFlag2ChangeFlag = 0;\r
+                uchRealReslutByteNum -= 5;\r
+            }\r
+            //flag3\r
+            if(uchFramePosi&GH3X2X_FRAME_POSI_HEAD)\r
+            {\r
+                puchTempFrameDataBuf[uchOneFrameByteNum] = 3;\r
+                uchOneFrameByteNum ++;     \r
+                GH3X2X_Memcpy((GU8*)&(puchTempFrameDataBuf[uchOneFrameByteNum]), (GU8*)(&(pstFrameInfo->punFrameFlag[3])), 4);\r
+                uchOneFrameByteNum += 4;    \r
+            }\r
+\r
+            #if GH3X2X_DIVIDE_ZERO_FLAG_UPLODE_EN\r
+            // flag4 div 0 flag\r
+            puchTempFrameDataBuf[uchOneFrameByteNum] = 4;\r
+            uchOneFrameByteNum ++;    \r
+            GH3X2X_Memcpy((GU8*)&(puchTempFrameDataBuf[uchOneFrameByteNum]), (GU8*)(&(pstFrameInfo->punFrameFlag[4])), 4);\r
+            uchOneFrameByteNum += 4;    \r
+            #endif\r
+\r
+            //alg result\r
+\r
+            if (1 == uchAlgoResFlag)\r
+            {\r
+                if (1 == pstFrameInfo->pstAlgoResult->uchUpdateFlag)\r
+                {                                                                             \r
+                    GU8 uchResTagData = GH3X2X_GET_LEFT_SHIFT_VAL(UPROTOCOL_RESULT_TYPE_BIT_FIELD);\r
+                    GU8 uchResultNumTemp = 0;\r
+                    for(GU8 uchResultCnt = 0;uchResultCnt < GH3X2X_ALGO_RESULT_MAX_NUM;uchResultCnt++)\r
+                    {\r
+                        if ((pstFrameInfo->pstAlgoResult->usResultBit >> uchResultCnt) & 0x1)\r
+                        {\r
+                            puchTempFrameDataBuf[uchOneFrameByteNum] = GH3X2X_SET_BIT(uchResTagData, uchResultCnt);\r
+                            uchOneFrameByteNum ++ ;\r
+                            puchTempFrameDataBuf[uchOneFrameByteNum] = GH3X2X_GET_BYTE0_FROM_DWORD(pstFrameInfo->pstAlgoResult->snResult[uchResultCnt]);\r
+                            uchOneFrameByteNum ++ ;\r
+                            puchTempFrameDataBuf[uchOneFrameByteNum] = GH3X2X_GET_BYTE1_FROM_DWORD(pstFrameInfo->pstAlgoResult->snResult[uchResultCnt]);\r
+                            uchOneFrameByteNum ++ ;\r
+                            puchTempFrameDataBuf[uchOneFrameByteNum] = GH3X2X_GET_BYTE2_FROM_DWORD(pstFrameInfo->pstAlgoResult->snResult[uchResultCnt]);\r
+                            uchOneFrameByteNum ++ ;\r
+                            puchTempFrameDataBuf[uchOneFrameByteNum] = GH3X2X_GET_BYTE3_FROM_DWORD(pstFrameInfo->pstAlgoResult->snResult[uchResultCnt]);\r
+                            uchOneFrameByteNum ++ ;\r
+                            uchResultNumTemp ++;\r
+                            if (uchResultNumTemp >= pstFrameInfo->pstAlgoResult->uchResultNum)\r
+                            {\r
+                                break;\r
+                            }\r
+                        }\r
+                    }\r
+                } // end of if (1 == uchAlgoResFlag)\r
+            }\r
+            \r
+            //modify uchReslutByteNum\r
+            puchTempFrameDataBuf[uchOneFrameByteNum - uchRealReslutByteNum] = uchRealReslutByteNum - 1;\r
+\r
+#if 1\r
+            GU8 uchSendFlag = 0; \r
+            if(((GU16)g_uchGh3x2xUploadBufUse + uchOneFrameByteNum) >= GH3X2X_UPROTOCOL_GET_PAYLOAD_LEN_SUPPORT(g_uchPacketMaxLenSupport))  //can not store more data\r
+            {\r
+                if (g_uchGh3x2xUploadBufUse <= GH3X2X_UPLOAD_PACKAGE_HEAD_SIZE)\r
+                {\r
+                    uchSendFlag = GH3X2X_SEND_STATUS_SPLIC_PACK_MODE;\r
+                }\r
+                else\r
+                {\r
+                    uchSendFlag = GH3X2X_SEND_STATUS_FULL_MODE;\r
+                }\r
+            }\r
+            else if (uchFramePosi&GH3X2X_FRAME_POSI_TAIL)\r
+            {\r
+                uchSendFlag = GH3X2X_SEND_STATUS_TAIL_MODE;\r
+            }\r
+\r
+            if (uchSendFlag == GH3X2X_SEND_STATUS_SPLIC_PACK_MODE)\r
+            {\r
+                GU16 usMaxPackLen = GH3X2X_UPROTOCOL_GET_PAYLOAD_LEN_SUPPORT(g_uchPacketMaxLenSupport) - g_uchGh3x2xUploadBufUse;\r
+                GU16 usPackNum = uchOneFrameByteNum / usMaxPackLen;\r
+                GU16 usPackByteCnt = 0;\r
+                GU16 usExternPackLen = uchOneFrameByteNum % usMaxPackLen;\r
+                GU16 usPackCnt = 1;\r
+                \r
+                for (usPackCnt = 1 ; usPackCnt < usPackNum + 1 ; usPackCnt ++)\r
+                {\r
+                    puchUploadBuf[UPROTOCOL_RAWDATA_LEN_INDEX] = g_uchGh3x2xUploadBufUse + usMaxPackLen;\r
+                    puchUploadBuf[UPROTOCOL_PACKAGE_TYPE_INDEX] &= 0x7;\r
+                    puchUploadBuf[UPROTOCOL_PACKAGE_TYPE_INDEX] |= GH3X2X_VAL_LEFT_SHIFT((GU8)usPackCnt, UPROTOCOL_SPLIC_PACK_CNT_FIELD);\r
+                    GH3X2X_Memcpy(&puchUploadBuf[g_uchGh3x2xUploadBufUse], &puchTempFrameDataBuf[usPackByteCnt], usMaxPackLen);\r
+                    usPackByteCnt += usMaxPackLen;\r
+                    usRespondLen = GH3X2X_UprotocolPacketFormat(GH3X2X_UPROTOCOL_CMD_NEW_STRUCT_RAWDATA, puchUploadBuf - 4,\r
+                                        puchUploadBuf, g_uchGh3x2xUploadBufUse + usMaxPackLen);\r
+                    Gh3x2xDemoSendProtocolData(puchUploadBuf - 4,usRespondLen);\r
+                }\r
+                puchUploadBuf[UPROTOCOL_RAWDATA_LEN_INDEX] = g_uchGh3x2xUploadBufUse + usExternPackLen;\r
+                puchUploadBuf[UPROTOCOL_PACKAGE_TYPE_INDEX] &= 0x7;\r
+                puchUploadBuf[UPROTOCOL_PACKAGE_TYPE_INDEX] |= GH3X2X_VAL_LEFT_SHIFT((GU8)usPackCnt, UPROTOCOL_SPLIC_PACK_CNT_FIELD);\r
+                puchUploadBuf[UPROTOCOL_PACKAGE_TYPE_INDEX] |= GH3X2X_VAL_LEFT_SHIFT(1, UPROTOCOL_SPLIC_PACK_OVER_FIELD);\r
+                GH3X2X_Memcpy(&puchUploadBuf[g_uchGh3x2xUploadBufUse], &puchTempFrameDataBuf[usPackByteCnt], usExternPackLen);\r
+                usPackByteCnt += usExternPackLen;\r
+                usRespondLen = GH3X2X_UprotocolPacketFormat(GH3X2X_UPROTOCOL_CMD_NEW_STRUCT_RAWDATA, puchUploadBuf - 4,\r
+                                    puchUploadBuf, g_uchGh3x2xUploadBufUse + usExternPackLen);\r
+                Gh3x2xDemoSendProtocolData(puchUploadBuf - 4,usRespondLen);\r
+                \r
+                g_uchOddEvenChangeFlag =! g_uchOddEvenChangeFlag;\r
+                g_uchGh3x2xUploadStatus = GH3X2X_UPLOAD_STATUS_NULL;\r
+                return;\r
+            }\r
+#endif\r
+\r
+            if(((GU16)g_uchGh3x2xUploadBufUse + uchOneFrameByteNum) >= GH3X2X_UPROTOCOL_GET_PAYLOAD_LEN_SUPPORT(g_uchPacketMaxLenSupport))  //can not store more data\r
+            {\r
+                //send data\r
+                usRespondLen = GH3X2X_UprotocolPacketFormat(GH3X2X_UPROTOCOL_CMD_NEW_STRUCT_RAWDATA, puchUploadBuf - 4,\r
+                                    puchUploadBuf, g_uchGh3x2xUploadBufUse);\r
+                Gh3x2xDemoSendProtocolData(puchUploadBuf - 4,usRespondLen);\r
+                g_uchOddEvenChangeFlag = !g_uchOddEvenChangeFlag;\r
+                g_uchGh3x2xUploadStatus = GH3X2X_UPLOAD_STATUS_NULL;\r
+                uchNeedContinue = 1;\r
+                continue;\r
+            }\r
+            \r
+            GH3X2X_Memcpy(&puchUploadBuf[g_uchGh3x2xUploadBufUse], puchTempFrameDataBuf, uchOneFrameByteNum);\r
+            g_uchGh3x2xUploadBufUse += uchOneFrameByteNum;\r
+            if (uchEvenFirstFrameFlag != 1)\r
+            {\r
+                GH3X2X_Memcpy(g_stZipLastData.unFifoLastRawdataArr, unFrameRawdataArr, uchChnlNum*4);\r
+                GH3X2X_Memcpy(g_stZipLastData.uchFifoLastRawdataTagArr[uchFunctionIDForMaster], uchFifoLastRawdataTagArr, uchChnlNum);\r
+                GH3X2X_Memcpy(g_stZipLastData.unFifoLastAgcdataArr, unAgcdataArr, uchChnlNum*4);\r
+            }\r
+            puchUploadBuf[UPROTOCOL_RAWDATA_LEN_INDEX] += uchOneFrameByteNum;\r
+\r
+            if(uchFramePosi&GH3X2X_FRAME_POSI_TAIL)\r
+            {\r
+                //send data\r
+                usRespondLen = GH3X2X_UprotocolPacketFormat(GH3X2X_UPROTOCOL_CMD_NEW_STRUCT_RAWDATA, puchUploadBuf - 4,\r
+                                    puchUploadBuf, g_uchGh3x2xUploadBufUse);\r
+                Gh3x2xDemoSendProtocolData(puchUploadBuf - 4,usRespondLen);\r
+                g_uchOddEvenChangeFlag = !g_uchOddEvenChangeFlag;\r
+                g_uchGh3x2xUploadStatus = GH3X2X_UPLOAD_STATUS_NULL;\r
+            }\r
+        }\r
+    }\r
+}\r
+#else\r
+void Gh2x2xUploadZipDataToMaster(const STGh3x2xFrameInfo * const pstFrameInfo, GU16 usFrameCnt, GU16 usFrameNum, GU8* puchTagArray){}\r
+#endif\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/module/gh_protocol/gh_zip.h b/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/module/gh_protocol/gh_zip.h
new file mode 100644 (file)
index 0000000..c2efe3e
--- /dev/null
@@ -0,0 +1,38 @@
+/**\r
+ * @copyright (c) 2003 - 2022, Goodix Co., Ltd. All rights reserved.\r
+ *\r
+ * @file    gh3x2x_drv_zip.h\r
+ *\r
+ * @brief   gh3x2x universal protocol define & declaration\r
+ *\r
+ * @version ref gh3x2x_drv_zip.h\r
+ *\r
+ */\r
+#ifndef _GH3X2X_DRV_ZIPHANDLE_H_\r
+#define _GH3X2X_DRV_ZIPHANDLE_H_\r
+\r
+\r
+/**\r
+ * @brief ZipMode Lastdata Temp\r
+ */\r
+typedef struct\r
+{\r
+    GU8 uchFifoLastRawdataTagArr[GH3X2X_FUNC_OFFSET_MAX][GH3X2X_CHANNEL_MAP_MAX_CH];\r
+    GU32 unFifoLastRawdataArr[GH3X2X_CHANNEL_MAP_MAX_CH];\r
+    GU32 unFifoLastAgcdataArr[GH3X2X_CHANNEL_MAP_MAX_CH];\r
+} STZipLastDataStruct;\r
+\r
+\r
+\r
+\r
+extern void GH3X2X_GetRawDataDiff(GU32 *punRawData, GU8 *puchRawdataTagTempArr, \r
+                            GU8 uchChannelMapCnt, GU8 *puchZipDataArr, GU8 *puchZipDataArrSize, \r
+                            GU8 *uchFifoLastRawdataTagArr, GU32 *unFifoLastRawdataArr);\r
+\r
+extern void GH3X2X_GetDataDiff(GU32 *punData, GU8 uchChannelMapCnt, GU8 *puchZipDataArr, \r
+                        GU8 *puchZipDataArrSize, GU32 *punZipTempData);\r
+\r
+extern void GH3X2X_ZipmodeInit(void);\r
+\r
+#endif\r
+\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/module/gh_soft_adt/gh_multi_sen_pro.c b/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/module/gh_soft_adt/gh_multi_sen_pro.c
new file mode 100644 (file)
index 0000000..25c29e7
--- /dev/null
@@ -0,0 +1,691 @@
+/**\r
+ * @copyright (c) 2003 - 2022, Goodix Co., Ltd. All rights reserved.\r
+ *\r
+ * @file    gh3x2x_drv_adt.c\r
+ *\r
+ * @brief   gh3x2x adt functions\r
+ *\r
+ * @version ref gh3x2x_drv_version.h\r
+ *\r
+ */\r
+\r
+\r
+#include <math.h>\r
+#include "gh_demo_config.h"\r
+#include "gh_demo_inner.h"\r
+#include "gh_drv.h"\r
+#include "gh_multi_sen_pro.h"\r
+\r
+#if __GH_MULTI_SENSOR_EVENT_PRO_CONIG__\r
+\r
+STGhMultiSensorTimer g_stGhMultiSensorTimer;\r
+\r
+void GhMultiSensorTimerInit(void)\r
+{\r
+       GH3X2X_Memset((GU8*)(&g_stGhMultiSensorTimer), 0, sizeof(g_stGhMultiSensorTimer));\r
+}\r
+\r
+void GhMultiSensorTimerOpsRegister(const STGhMultiSensorTimerOps *pstTimerOps)\r
+{\r
+       g_stGhMultiSensorTimer.pstTimerOps = pstTimerOps;\r
+\r
+       if(g_stGhMultiSensorTimer.pstTimerOps)\r
+       {\r
+               g_stGhMultiSensorTimer.pstTimerOps->TimerCreate(__GH_MULTI_SENSOR_TIMER_PERIOD_MS__);\r
+       }\r
+}\r
+\r
+void GhMultiSensorTimerOpsUnregister(void)\r
+{\r
+       if(g_stGhMultiSensorTimer.pstTimerOps)\r
+       {\r
+               g_stGhMultiSensorTimer.pstTimerOps->TimerDelete();\r
+       }\r
+       g_stGhMultiSensorTimer.pstTimerOps = 0;\r
+}\r
+\r
+void GhMultiSensorTimerStart(void)\r
+{\r
+       if(g_stGhMultiSensorTimer.pstTimerOps)\r
+       {\r
+               g_stGhMultiSensorTimer.pstTimerOps->TimerStart();\r
+       }\r
+}\r
+\r
+void GhMultiSensorTimerStop(void)\r
+{\r
+       if(g_stGhMultiSensorTimer.pstTimerOps)\r
+       {\r
+               g_stGhMultiSensorTimer.pstTimerOps->TimerStop();\r
+       }\r
+}\r
+\r
+void GhMultiSensorTimerUserRegister(GU8 uchUserId, void (*TimerHandle) (GU32))\r
+{\r
+       if(uchUserId < GH_MULTI_SENSOR_TIMER_USER_NUM_MAX)\r
+       {\r
+               g_stGhMultiSensorTimer.stTimerUsers[uchUserId].TimerHandle = TimerHandle;\r
+       }\r
+}\r
+\r
+void GhMultiSensorTimerUserUnregister(GU8 uchUserId)\r
+{\r
+       if(uchUserId < GH_MULTI_SENSOR_TIMER_USER_NUM_MAX)\r
+       {\r
+               g_stGhMultiSensorTimer.stTimerUsers[uchUserId].TimerHandle = 0;\r
+       }\r
+}\r
+\r
+void GhMultiSensorTimerHandle(void)\r
+{\r
+       for(GU8 uchUserCnt = 0; uchUserCnt < GH_MULTI_SENSOR_TIMER_USER_NUM_MAX; uchUserCnt ++)\r
+       {\r
+               if(g_stGhMultiSensorTimer.stTimerUsers[uchUserCnt].TimerHandle)\r
+               {\r
+                       g_stGhMultiSensorTimer.stTimerUsers[uchUserCnt].TimerHandle(__GH_MULTI_SENSOR_TIMER_PERIOD_MS__);\r
+               }\r
+       }\r
+}\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+typedef struct \r
+{\r
+    GU64 unnTimeStamp;    //64bit unix timestamp\r
+    GU8  uchNext;        // 0~254 point to newer event  255:invalid  \r
+}STMultiSensorWearEvent;\r
+\r
+typedef struct \r
+{\r
+    GU8 En;       // 0: Manager is disabled    1:  Manger is enabled\r
+       GU8 uchHead;   // linked list head\r
+       volatile GU64 unnCurrentTimeStamp;\r
+    STMultiSensorWearEvent  pstMultiSensorWearEvent[GH3X2X_MULTI_SENSOR_EVENT_NUM_MAX];   //linked list members\r
+       void (*WearEventHook) (GU32 uchNewEvent);\r
+}STMultiSensorWearEventManager;  //linked list\r
+\r
+STMultiSensorWearEventManager g_stMultiSensorWearEventManager;\r
+\r
+/// @brief get current timestamp\r
+/// @param  \r
+/// @return \r
+static GU64 GhMultSensorWearEventManagerGetCurTs(void)\r
+{\r
+       return g_stMultiSensorWearEventManager.unnCurrentTimeStamp;  //it maybe is not atomic opration, this function must add lock !!!\r
+}\r
+\r
+/// @brief update timestamp for wear event manager, this function will be call at timer handle\r
+/// @param unTimeIntervalMs the interval of timer (unit: ms)\r
+static void GhMultSensorWearEventManagerUpdataCurTs(GU32 unTimeIntervalMs)\r
+{\r
+       g_stMultiSensorWearEventManager.unnCurrentTimeStamp += unTimeIntervalMs;  //it maybe is not atomic opration, this function must add lock !!!\r
+}\r
+\r
+static void GhMultSensorWearEventManagerTimerHandle(GU32 unTimeIntervalMs)\r
+{\r
+    GH3X2X_INFO_LOG("GhMultSensorWearEventManagerTimerHandle.\r\n");\r
+    GhMultSensorWearEventManagerUpdataCurTs(unTimeIntervalMs);\r
+}\r
+\r
+/// @brief Init multi-sensor wear event manager\r
+/// @param  \r
+void GhMultSensorWearEventManagerInit(void)\r
+{\r
+       GH3X2X_Memset((GU8*)(&g_stMultiSensorWearEventManager), 0, sizeof(STMultiSensorWearEventManager));\r
+       g_stMultiSensorWearEventManager.uchHead = GH3X2X_MULTI_SENSOR_EVENT_LL_INDEX_INVALID;  // point to NULL\r
+       //clear linked list members\r
+       for(GU8 uchEventCnt = 0; uchEventCnt < GH3X2X_MULTI_SENSOR_EVENT_NUM_MAX; uchEventCnt ++)\r
+       {\r
+               g_stMultiSensorWearEventManager.pstMultiSensorWearEvent[uchEventCnt].uchNext = GH3X2X_MULTI_SENSOR_EVENT_LL_INDEX_INVALID;\r
+       }\r
+\r
+}\r
+\r
+/// @brief register hook function for wear event hook\r
+/// @param WearEventHook hook funcion\r
+void GhMultSensorWearEventManagerHookRegister(void (*WearEventHook) (GU32 uchNewEvent))\r
+{\r
+       g_stMultiSensorWearEventManager.WearEventHook = WearEventHook;\r
+}\r
+\r
+/// @brief enable wear event manager\r
+/// @param  \r
+void GhMultSensorWearEventManagerEnable(void)\r
+{\r
+       g_stMultiSensorWearEventManager.En = 1; \r
+       GhMultiSensorTimerUserRegister(GH_MULTI_SENSOR_TIMER_USER_TIME_STAMP, GhMultSensorWearEventManagerTimerHandle); //register timer user\r
+}\r
+\r
+/// @brief disable wear event manager\r
+/// @param  \r
+void GhMultSensorWearEventManagerDisable(void)\r
+{\r
+       GhMultSensorWearEventManagerInit();\r
+       GhMultiSensorTimerUserUnregister(GH_MULTI_SENSOR_TIMER_USER_TIME_STAMP);\r
+}\r
+\r
+GU8 GhMultSensorWearEventManagerIsEnable(void)\r
+{\r
+       return g_stMultiSensorWearEventManager.En;\r
+}\r
+\r
+\r
+\r
+\r
+\r
+/// @brief get the pointer of next member\r
+/// @param[in] uchCurEventPointer this point points current event member's uchNext\r
+/// @return the pointer of next member, this point points next event member's uchNext\r
+static GU8* GetNextEventPointer(GU8* uchCurEventPointer)\r
+{\r
+       if(0 != uchCurEventPointer)\r
+       {\r
+               return &(g_stMultiSensorWearEventManager.pstMultiSensorWearEvent[*uchCurEventPointer].uchNext);\r
+       }\r
+       else\r
+       {\r
+               return 0;\r
+       }\r
+}\r
+\r
+/// @brief get the pointer of previous member of event uchEvtOffset\r
+/// @param uchEvtOffset offset of event\r
+/// @return the pointer of previous member of event uchEvtOffset, this point points uchHead or previous member's uchNext. 0: can not find this member\r
+static GU8* GetPreviousEventPointer(GU8 uchEvtOffset)\r
+{\r
+       GU8* pTemp = 0;\r
+\r
+       GU8* pNext = &(g_stMultiSensorWearEventManager.uchHead);\r
+\r
+       do{\r
+               if(GH3X2X_MULTI_SENSOR_EVENT_LL_INDEX_INVALID == *pNext)\r
+               {\r
+                       break;\r
+               }\r
+               if(uchEvtOffset == (*pNext))\r
+               {\r
+                       pTemp = pNext;\r
+                       break;\r
+               }\r
+               pNext = GetNextEventPointer(pNext);\r
+       }while(1);\r
+\r
+       return pTemp;\r
+}\r
+\r
+/// @brief get the pointer of tail in linker list \r
+/// @param  \r
+/// @return the pointer of tail in linker list, the poiniter points to g_stMultiSensorWearEventManager.uchHead or pstMultiSensorWearEvent[N].uchNext\r
+static GU8* GetTailEventPointer(void)\r
+{\r
+       GU8* pTemp = &(g_stMultiSensorWearEventManager.uchHead);\r
+\r
+       do{\r
+               if(GH3X2X_MULTI_SENSOR_EVENT_LL_INDEX_INVALID == *pTemp)\r
+               {\r
+                       break;\r
+               }\r
+               pTemp = GetNextEventPointer(pTemp);\r
+       }while(1);\r
+\r
+       return pTemp;\r
+}\r
+\r
+/// @brief get oldest and newest event(in range of unEventComb) information\r
+/// @param unEventComb Event combination you need check\r
+/// @param[out] pOldestTs pointer of oldest event timestamp\r
+/// @param[out] pNewestTs pointer of newest event timestamp\r
+/// @param[out] pOldestEvt pointer of oldest event,  *pOldestEvt = 0 means this event cannot find \r
+/// @param[out] pONewestEvt pointer of newest event, *pONewestEvt = 0 means this event cannot find \r
+/// @return \r
+static void GetOldestAndNewestEvtInfo(GU32 unEventComb, GU64* pOldestTs, GU64* pNewestTs, GU32* pOldestEvt, GU32* pONewestEvt)\r
+{\r
+       GU32 unCurEvt;\r
+       GU32 unRemainEventComb = unEventComb;\r
+       (*pOldestEvt) = 0;\r
+       (*pONewestEvt) = 0;\r
+\r
+       GU8* pTemp = &(g_stMultiSensorWearEventManager.uchHead);\r
+\r
+       do{\r
+               if(GH3X2X_MULTI_SENSOR_EVENT_LL_INDEX_INVALID == *pTemp)\r
+               {\r
+                       break;\r
+               }\r
+               unCurEvt = ((GU32)1 << (*pTemp));\r
+               if(unEventComb & unCurEvt)\r
+               {\r
+                       if(unEventComb == unRemainEventComb)  //first event we finded\r
+                       {\r
+                               (*pOldestTs) = (g_stMultiSensorWearEventManager.pstMultiSensorWearEvent[*pTemp].unnTimeStamp);\r
+                               (*pOldestEvt) = unCurEvt;\r
+                       }\r
+                       (*pNewestTs) = (g_stMultiSensorWearEventManager.pstMultiSensorWearEvent[*pTemp].unnTimeStamp);\r
+                       (*pONewestEvt) = unCurEvt;\r
+                       unRemainEventComb &= (~unCurEvt);  //clear event we finded\r
+                       if(0 == unRemainEventComb)   //last event we finded\r
+                       {\r
+                               break;\r
+                       }\r
+               }\r
+               pTemp = GetNextEventPointer(pTemp);\r
+       }while(1);\r
+\r
+}\r
+\r
+/// @brief print all events in linked list\r
+/// @param  \r
+static void GhMultiSensorPrintAllEvt(void)\r
+{\r
+       GU8* pTemp = &(g_stMultiSensorWearEventManager.uchHead);\r
+       GU8 uchEvtNum = 0;\r
+       GH3X2X_INFO_LOG("[MultiSensor] print events start...\r\n");\r
+       do{\r
+               if(GH3X2X_MULTI_SENSOR_EVENT_LL_INDEX_INVALID == *pTemp)\r
+               {\r
+                       break;\r
+               }\r
+               GH3X2X_INFO_LOG("[MultiSensor] EvtPosi = %d, Evt = 0x%X, Ts = %llu.\r\n", (int)uchEvtNum, (((GU32)1) << (*pTemp)), g_stMultiSensorWearEventManager.pstMultiSensorWearEvent[*pTemp].unnTimeStamp);\r
+               uchEvtNum ++;\r
+               pTemp = GetNextEventPointer(pTemp);\r
+       }while(1);\r
+       GH3X2X_INFO_LOG("[MultiSensor] print events end, uchEvtNum = %d.\r\n", (int)uchEvtNum);\r
+}\r
+\r
+/// @brief check event combination is in this time window or not\r
+/// @param unEventComb event combination\r
+/// @param unWindow   time window (unit: ms)\r
+/// @param uchNowTimeNeedInWin  current timestamp is include or not  (0: is include  1: is NOT include)\r
+/// @return 0: no  1: yes\r
+GU8 GhMultiSensorConditionCheckInWindow (GU32 unEventComb, GU32 unWindow, GU8 uchNowTimeNeedInWin)\r
+{\r
+       GU64 nnOldestTs;\r
+       GU64 nnNewestTs;\r
+       GU32 nnOldestEvt;\r
+       GU32 nnNewestEvt;\r
+\r
+       GetOldestAndNewestEvtInfo(unEventComb, &nnOldestTs, &nnNewestTs, &nnOldestEvt, &nnNewestEvt);\r
+       if((0 == nnOldestEvt)||(0 == nnNewestEvt))   //can NOT find any event in unEventComb\r
+       {\r
+               return 0;\r
+       }\r
+       if(1 == uchNowTimeNeedInWin)\r
+       {\r
+               nnNewestTs = GhMultSensorWearEventManagerGetCurTs();\r
+       }\r
+       if((nnNewestTs - nnOldestTs) < unWindow)\r
+       {\r
+               return 1;\r
+       }\r
+       else\r
+       {\r
+               return 0;\r
+       }\r
+}\r
+\r
+/// @brief check unEventNew is new than unEventOld or not\r
+/// @param unEventNew new event we hope for\r
+/// @param unEventOld old event we hope for\r
+/// @return 0: no or there is no unEventNew   1: yes or there is only unEventNew\r
+GU8 GhMultiSensorConditionCheckIsNew (GU32 unEventNew, GU32 unEventOld)\r
+{\r
+       GU64 nntTs;\r
+       GU32 unOldestEvt;\r
+       GU32 unNewestEvt;\r
+       GetOldestAndNewestEvtInfo(unEventNew|unEventOld, &nntTs, &nntTs, &unOldestEvt, &unNewestEvt);\r
+       if(unNewestEvt == unEventNew)\r
+       {\r
+               return 1;\r
+       }\r
+       else\r
+       {\r
+               return 0;\r
+       }\r
+}\r
+\r
+/// @brief send evet to Multi-sensor wear event manager\r
+/// @param unEvent such as: GH3X2X_MULTI_SENSOR_EVENT_GH_WEAR_ON\r
+void GhMultSensorWearEventSend(GU32 unEvent) \r
+{\r
+       GU64 unnCurTs;\r
+       GU8*  puchPreMemberPointer; \r
+       GU8*  puchTailPointer; \r
+       GU8  uchNewEvtOffset = GH3X2X_MULTI_SENSOR_EVENT_LL_INDEX_INVALID;\r
+\r
+       //get current time stamp\r
+       unnCurTs = GhMultSensorWearEventManagerGetCurTs();\r
+       //get offset of this new event\r
+       for(GU8 uchEvtCnt = 0; uchEvtCnt < GH3X2X_MULTI_SENSOR_EVENT_NUM_MAX; uchEvtCnt ++)\r
+       {\r
+               if(((GU32)1 << uchEvtCnt) == unEvent)\r
+               {\r
+                       uchNewEvtOffset = uchEvtCnt;\r
+                       break; \r
+               }\r
+       }\r
+       if((GH3X2X_MULTI_SENSOR_EVENT_LL_INDEX_INVALID == uchNewEvtOffset) || (0 == g_stMultiSensorWearEventManager.En))  //invalid event or event manager is disable\r
+       {\r
+               return;\r
+       }\r
+       //remove outdated event member in linked list\r
+       puchPreMemberPointer = GetPreviousEventPointer(uchNewEvtOffset);\r
+       if(puchPreMemberPointer)\r
+       {\r
+               (*puchPreMemberPointer) = g_stMultiSensorWearEventManager.pstMultiSensorWearEvent[uchNewEvtOffset].uchNext;\r
+       }\r
+       //add new event to link tail\r
+       puchTailPointer = GetTailEventPointer();\r
+       (*puchTailPointer) = uchNewEvtOffset;\r
+       //fill timestamp and next for this new event\r
+       g_stMultiSensorWearEventManager.pstMultiSensorWearEvent[uchNewEvtOffset].unnTimeStamp = unnCurTs;\r
+       g_stMultiSensorWearEventManager.pstMultiSensorWearEvent[uchNewEvtOffset].uchNext = GH3X2X_MULTI_SENSOR_EVENT_LL_INDEX_INVALID;\r
+       //print new event\r
+       GH3X2X_INFO_LOG("[MultiSensor] new event received, Evt = 0x%X.\r\n", unEvent);\r
+       //print all event\r
+       GhMultiSensorPrintAllEvt();\r
+       //call event hook\r
+       if(g_stMultiSensorWearEventManager.WearEventHook)g_stMultiSensorWearEventManager.WearEventHook(unEvent);\r
+}\r
+\r
+\r
+#endif\r
+\r
+typedef struct\r
+{\r
+    GS16 sXAxisVal;     /**< x-axis value */\r
+    GS16 sYAxisVal;     /**< y-axis value */\r
+    GS16 sZAxisVal;     /**< z-axis value */\r
+} STGsAccRawdata;\r
+\r
+\r
+#if __GSENSOE_MOVE_DETECT_SUPPORT__\r
+\r
+\r
+typedef struct \r
+{\r
+       GU8 uchMoveDetEnable;  //enable gs movement detect or not\r
+       GU8 uchGsensorStatus;  // movement status of g sensor\r
+       GU16 usGsMoveDetectCnt;  // count how many times of movement detected by g sensor \r
+       GU16 usGsNotMoveDetectCnt;  // count how many times of not movement detected by g sensor \r
+       GU8 uchGsMoveDetectNotFirstTime;  // 0: the first time of G sensor move detection  1: is not first time of G sensor move detection\r
+       STGsAccRawdata stLastPointMoveDetGsenorRawdata;\r
+       GU16 usNotMoveTimeCnt;   //the counter of not move, 0: time out has trigled  or initial state, 1: is moving state, >1: the conter of not move, unit: ms \r
+}STGsMoveDetecter;  \r
+\r
+STGsMoveDetecter g_stGhGsMoveDetecter;\r
+\r
+\r
+\r
+\r
+extern void GH3X2X_RedetectWearOn(void);\r
+\r
+\r
+\r
+void GhGsMoveDetecterInit(void)\r
+{\r
+       GH3X2X_Memset((GU8*)(&g_stGhGsMoveDetecter), 0, sizeof(STGsMoveDetecter));\r
+\r
+}\r
+\r
+void GhGsMoveDetecterEnable(void)\r
+{\r
+       g_stGhGsMoveDetecter.uchMoveDetEnable = 1;\r
+       #if __GH_MULTI_SENSOR_EVENT_PRO_CONIG__\r
+       GhMultiSensorTimerUserRegister(GH_MULTI_SENSOR_TIMER_USER_MOVE_DET, Gh3x2xDemoMoveDetectTimerHandler); //register timer user\r
+       #endif\r
+}\r
+\r
+void GhGsMoveDetecterDisable(void)\r
+{\r
+       GhGsMoveDetecterInit();\r
+       #if __GH_MULTI_SENSOR_EVENT_PRO_CONIG__\r
+       GhMultiSensorTimerUserUnregister(GH_MULTI_SENSOR_TIMER_USER_MOVE_DET);\r
+       #endif\r
+}\r
+\r
+GU8 GhGsMoveDetecterIsEnable(void)\r
+{\r
+       return g_stGhGsMoveDetecter.uchMoveDetEnable;\r
+}\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+/// function started bitmap, use for sampling control\r
+#if 1\r
+#if (__DRIVER_LIB_MODE__ == __DRV_LIB_WITH_ALGO__) && __USE_GOODIX_SOFT_ADT_ALGORITHM__\r
+extern GU8 NADTWearDetectByCap(GS32 lPacketInfoArr[]);\r
+void GH3X2X_MoveDetectByCapData(STCapRawdata* pusCapData, GU16 usCapDataCnt)\r
+{\r
+    if( 0 == GH3X2X_GetCapEnableFlag())\r
+    {\r
+        return;\r
+    }\r
+    GS32 lPacketInfoArr[4];\r
+    for(GU16 i = 0; i < usCapDataCnt;i++)\r
+    {\r
+        lPacketInfoArr[0] = pusCapData[i].unCapData[0];\r
+        lPacketInfoArr[1] = pusCapData[i].unCapData[1];\r
+        lPacketInfoArr[2] = pusCapData[i].unCapData[2];\r
+        lPacketInfoArr[3] = pusCapData[i].unCapData[3];\r
+\r
+        if(1 == NADTWearDetectByCap(lPacketInfoArr))\r
+        {\r
+            return;\r
+        }\r
+    }\r
+}\r
+#else\r
+void GH3X2X_MoveDetectByCapData(STCapRawdata* pusCapData, GU16 usCapDataCnt)\r
+{\r
+    return;\r
+}\r
+#endif\r
+#endif\r
+/**\r
+ * @fn      void GhMoveDetectByGsData(STGsensorRawdata* stGsData, GU16 usGsDataCnt, GU8 uchCheckWindowSize)\r
+ \r
+ *\r
+ * @brief  Move detection by software.\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   stGsData        gsensor data buffer\r
+ * @param[in]   usGsDataCnt        gsensor data count\r
+ * @param[in]   uchCheckWindowSize        the window size of cheak moving peak num \r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+//extern void SlaverLog(const char * lpsbLog, ...);\r
+void GhMoveDetectByGsData(GS16* pusGsData, GU16 usGsDataCnt)\r
+{\r
+    GS16 sXAxisVal = 0;\r
+    GS16 sYAxisVal = 0;\r
+    GS16 sZAxisVal = 0;\r
+    GU8  uchGyroEnable = g_uchGyroEnable;\r
+    GU32 unSumOfSquare = 0;    \r
+    GU16  usGsDataIndex = 0;\r
+    if ((GH3X2X_PTR_NULL == pusGsData) || (0 == usGsDataCnt))\r
+    {\r
+        GH3X2X_DEBUG_LOG("[GhMoveDetectByGsData] return; pusGsData[0] = %d , usGsDataCnt = %d \r\n",pusGsData[0],usGsDataCnt);\r
+        return;\r
+    }\r
+    \r
+               {                                                               \r
+                       if (g_stGhGsMoveDetecter.uchMoveDetEnable)\r
+                       {\r
+                                       if(0 == g_stGhGsMoveDetecter.uchGsMoveDetectNotFirstTime)\r
+                                       {\r
+                                                       g_stGhGsMoveDetecter.stLastPointMoveDetGsenorRawdata.sXAxisVal = pusGsData[0];\r
+                                                       g_stGhGsMoveDetecter.stLastPointMoveDetGsenorRawdata.sYAxisVal = pusGsData[0+1];\r
+                                                       g_stGhGsMoveDetecter.stLastPointMoveDetGsenorRawdata.sZAxisVal = pusGsData[0+2];\r
+                                                       g_stGhGsMoveDetecter.uchGsMoveDetectNotFirstTime = 1;\r
+                                       }\r
+                                       //calculate average of x, y, z\r
+                                       for (usGsDataIndex = 0; usGsDataIndex < usGsDataCnt; usGsDataIndex++)\r
+                                       {\r
+                                                       //GH3X2X_DEBUG_LOG("[GhMoveDetectByGsData] x=%d, y=%d, z =%d\r\n", pusGsData[usGsDataIndex*(3+3*uchGyroEnable)], pusGsData[usGsDataIndex*(3+3*uchGyroEnable) + 1], pusGsData[usGsDataIndex*(3+3*uchGyroEnable) + 2]);\r
+                                                       sXAxisVal = pusGsData[usGsDataIndex*(3+3*uchGyroEnable)] - g_stGhGsMoveDetecter.stLastPointMoveDetGsenorRawdata.sXAxisVal;\r
+                                                       sYAxisVal = pusGsData[usGsDataIndex*(3+3*uchGyroEnable) + 1] - g_stGhGsMoveDetecter.stLastPointMoveDetGsenorRawdata.sYAxisVal;\r
+                                                       sZAxisVal = pusGsData[usGsDataIndex*(3+3*uchGyroEnable) + 2] - g_stGhGsMoveDetecter.stLastPointMoveDetGsenorRawdata.sZAxisVal;\r
+\r
+                                                       g_stGhGsMoveDetecter.stLastPointMoveDetGsenorRawdata.sXAxisVal = pusGsData[usGsDataIndex*(3+3*uchGyroEnable)];\r
+                                                       g_stGhGsMoveDetecter.stLastPointMoveDetGsenorRawdata.sYAxisVal = pusGsData[usGsDataIndex*(3+3*uchGyroEnable) + 1];\r
+                                                       g_stGhGsMoveDetecter.stLastPointMoveDetGsenorRawdata.sZAxisVal = pusGsData[usGsDataIndex*(3+3*uchGyroEnable) + 2];\r
+\r
+\r
+                                                       unSumOfSquare = (GU32)((GS32)sXAxisVal * sXAxisVal) + (GU32)((GS32)sYAxisVal * sYAxisVal) + (GU32)((GS32)sZAxisVal * sZAxisVal);\r
+\r
+                                                       if(unSumOfSquare > ((GU32)__GSENSOR_MOVE_THRESHOLD__ * __GSENSOR_MOVE_THRESHOLD__))\r
+                                                       {\r
+                                                                       GH3X2X_DEBUG_LOG("[GhMoveDetectByGsData] g_stGhGsMoveDetecter.usGsMoveDetectCnt = %d \r\n", g_stGhGsMoveDetecter.usGsMoveDetectCnt);\r
+                                                                       g_stGhGsMoveDetecter.usGsNotMoveDetectCnt = 0;\r
+                                                                       if (g_stGhGsMoveDetecter.usGsMoveDetectCnt >= __GSENSOR_MOVE_CNT_THRESHOLD__)\r
+                                                                       {\r
+                                                                                       GH3X2X_DEBUG_LOG("[GhMoveDetectByGsData] over __GSENSOR_MOVE_CNT_THRESHOLD__!!! \r\n");\r
+                                                                                       g_stGhGsMoveDetecter.uchGsensorStatus = GH3X2X_SENSOR_IS_MOVING;\r
+                                                                                       GH3X2X_DEBUG_LOG("[GhMoveDetectByGsData] Move detect effect!!! \r\n");\r
+                                                                       }\r
+                                                                       else\r
+                                                                       {\r
+                                                                               g_stGhGsMoveDetecter.usGsMoveDetectCnt ++;\r
+                                                                       }\r
+                                                       }\r
+                                                       else\r
+                                                       {\r
+                                                                       if (g_stGhGsMoveDetecter.usGsMoveDetectCnt != 0)\r
+                                                                       {\r
+                                                                                       GH3X2X_DEBUG_LOG("[GhMoveDetectByGsData] g_stGhGsMoveDetecter.usGsNotMoveDetectCnt = %d \r\n", g_stGhGsMoveDetecter.usGsNotMoveDetectCnt);\r
+                                                                                       \r
+                                                                                       if (g_stGhGsMoveDetecter.usGsNotMoveDetectCnt >= __GSENSOR_NOT_MOVE_CNT_THRESHOLD__)\r
+                                                                                       {\r
+                                                                                               g_stGhGsMoveDetecter.usGsMoveDetectCnt = 0;\r
+                                                                                               g_stGhGsMoveDetecter.uchGsensorStatus = GH3X2X_SENSOR_IS_NOT_MOVING;\r
+                                                                                               GH3X2X_DEBUG_LOG("[GhMoveDetectByGsData] Move detect is not effect!!! \r\n");\r
+                                                                                       }\r
+                                                                                       else\r
+                                                                                       {\r
+                                                                                               g_stGhGsMoveDetecter.usGsNotMoveDetectCnt ++;\r
+                                                                                       }\r
+                                                                       }\r
+                                                       }\r
+                                       }\r
+\r
+\r
+\r
+                                       if(GH3X2X_SENSOR_IS_MOVING == g_stGhGsMoveDetecter.uchGsensorStatus)\r
+                                       {\r
+                                               #if __GH_MULTI_SENSOR_EVENT_PRO_CONIG__\r
+                                               GhMultSensorWearEventSend(GH3X2X_MULTI_SENSOR_EVENT_GS_MOVE);\r
+                                               #endif\r
+                                               g_stGhGsMoveDetecter.usNotMoveTimeCnt = 1;\r
+                                       }\r
+                                       if((GH3X2X_SENSOR_IS_NOT_MOVING == g_stGhGsMoveDetecter.uchGsensorStatus) && (g_stGhGsMoveDetecter.usNotMoveTimeCnt >= 1))\r
+                                       {\r
+                                               GU32 unTempCnt;\r
+                                               unTempCnt = ((GU32)g_stGhGsMoveDetecter.usNotMoveTimeCnt + __GH_MULTI_SENSOR_TIMER_PERIOD_MS__);\r
+                                               if(unTempCnt > 0xFFFF)\r
+                                               {\r
+                                                       unTempCnt = 0xFFFF;\r
+                                               }\r
+                                               if(unTempCnt > __GSENSOR_MOVE_TIME_OUT_THRESHOLD_MS__)\r
+                                               {\r
+                                                       #if __GH_MULTI_SENSOR_EVENT_PRO_CONIG__\r
+                                                       GhMultSensorWearEventSend(GH3X2X_MULTI_SENSOR_EVENT_GS_MOVE_TIME_OUT);\r
+                                                       #endif\r
+                                                       unTempCnt = 0;\r
+                                               }\r
+                                               g_stGhGsMoveDetecter.usNotMoveTimeCnt = (GU16)unTempCnt;\r
+                                       }\r
+                       }\r
+               }\r
+}\r
+\r
+\r
+\r
+\r
+/**\r
+ * @fn     GU8 Gh3x2x_GetMoveDetStatus(void)\r
+ *\r
+ * @brief  Get status of movement detected\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  GH3X2X_SENSOR_IS_NOT_MOVING/GH3X2X_SENSOR_IS_MOVING\r
+ */\r
+GU8 Gh3x2x_GetMoveDetStatus(void)\r
+{\r
+    return g_stGhGsMoveDetecter.uchGsensorStatus;\r
+}\r
+\r
+\r
+\r
+\r
+\r
+#endif\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+/********END OF FILE********* Copyright (c) 2003 - 2022, Goodix Co., Ltd. ********/\r
+\r
+\r
+\r
+\r
+\r
+\r
+extern  void hal_gh3x2x_write_cap_to_flash(GS32 WearCap1,GS32 UnwearCap1,GS32 WearCap2,GS32 UnwearCap2);\r
+extern  void hal_gh3x2x_read_cap_from_flash(GS32* WearCap1,GS32* UnwearCap1,GS32* WearCap2,GS32* UnwearCap2);\r
+\r
+void GH3x2xWriteCapToFlash(void)\r
+{\r
+//    hal_gh3x2x_write_cap_to_flash(lWearCap1,lUnwearCap1,lWearCap2,lUnwearCap2);\r
+}\r
+\r
+void GH3x2xReadCapFromFlash(void)\r
+{\r
+//    hal_gh3x2x_read_cap_from_flash(&lWearCap1,&lUnwearCap1,&lWearCap2,&lUnwearCap2);\r
+}\r
+\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/module/gh_soft_adt/gh_multi_sen_pro.h b/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_kernel_code/module/gh_soft_adt/gh_multi_sen_pro.h
new file mode 100644 (file)
index 0000000..8e55180
--- /dev/null
@@ -0,0 +1,208 @@
+/**\r
+ * @copyright (c) 2003 - 2022, Goodix Co., Ltd. All rights reserved.\r
+ *\r
+ * @file    gh_demo_multi_sen_pro.h\r
+ *\r
+ * @brief   gh3x2x adt\r
+ *\r
+ * @version ref gh3x2x_drv_version.h\r
+ *\r
+ */\r
+\r
+\r
+#ifndef _gh_demo_multi_sen_pro_H_\r
+#define _gh_demo_multi_sen_pro_H_\r
+\r
+\r
+#include "gh_drv.h"\r
+\r
+/// wear on event en set\r
+#define  WEAR_ON_EVENT_EN_CONFIG(en)        do {\\r
+                                                GH3X2X_WriteRegBitField(GH3X2X_INT_CR2_REG_ADDR, \\r
+                                                    GH3X2X_WEAR_ON_EVENT_EN_LSB, GH3X2X_WEAR_ON_EVENT_EN_MSB, (en)); \\r
+                                            } while (0)\r
+\r
+/// wear off event en set\r
+#define  WEAR_OFF_EVENT_EN_CONFIG(en)        do {\\r
+                                                GH3X2X_WriteRegBitField(GH3X2X_INT_CR2_REG_ADDR, \\r
+                                                    GH3X2X_WEAR_OFF_EVENT_EN_LSB, GH3X2X_WEAR_OFF_EVENT_EN_MSB, (en)); \\r
+                                            } while (0)\r
+\r
+\r
+\r
+#define SOFT_WEAR_INPUT_DATA_CHNL0_INDEX   (0)\r
+#define SOFT_WEAR_INPUT_DATA_ACCX_INDEX    (1)\r
+#define SOFT_WEAR_INPUT_DATA_ACCY_INDEX    (2)\r
+#define SOFT_WEAR_INPUT_DATA_ACCZ_INDEX    (3)\r
+#define SOFT_WEAR_INPUT_COLOR_INDEX        (4)\r
+#define SOFT_WEAR_INPUT_DATA_ADT_INDEX     (5) //ir  adt data\r
+#define SOFT_WEAR_INPUT_DATA_BG_INDEX      (6)\r
+#define SOFT_WEAR_INPUT_DATA_CAP0_INDEX    (7)\r
+#define SOFT_WEAR_INPUT_DATA_CAP1_INDEX    (8)\r
+#define SOFT_WEAR_INPUT_DATA_CAP2_INDEX    (9)\r
+#define SOFT_WEAR_INPUT_DATA_CAP3_INDEX    (10)\r
+\r
+\r
+#define SOFT_WEAR_INPUT_DATA_INDEX_TOTAL (11)\r
+#define SOFT_WEAR_OUTPUT_DATA_INDEX_TOTAL (8)\r
+\r
+\r
+#define SOFT_WEAR_OUTPUT_WEAR_STATE_BIT  (3)   \r
+\r
+\r
+#define NADTCAP_BYTE_TRUE       (GU8)1\r
+#define NADTCAP_BYTE_FALSE      (GU8)0\r
+\r
+\r
+\r
+#define NADT_SAMPLE_FREQ  25\r
+#define NADT_WWD_IIR_LEN  4\r
+\r
+#define NADT_WEAR_LIVE_DETECTION\r
+#ifdef  NADT_WEAR_LIVE_DETECTION // this is wear live dection, full wear dection,can distinguish body and other thing; more Ram\r
+#define NADT_PPG_BUFF_LEN (4) //4\r
+#else\r
+#define NADT_PPG_BUFF_LEN (2) //lite\r
+#endif // NADT_WEAR_LIVE_DETECTION\r
+\r
+#define NADT_WWD_FILTER_BUFF_LEN (NADT_PPG_BUFF_LEN*NADT_SAMPLE_FREQ)\r
+#define NADT_MATH_ROUND(v) round(v)\r
+#define NADT_MATH_ABSF(v)  fabs(v)\r
+#define NADT_MATH_ABS(v)   abs(v)\r
+#define NADT_MATH_ROUNDF(v) roundf(v)\r
+#define NADT_ABS_GS32(v) abs((GS32)(v))\r
+#define NADT_MIN(a,b) ((a) > (b) ? (b) : (a))\r
+\r
+\r
+\r
+#define NADT_PV_PEAK (1)\r
+#define NADT_PV_VALLEY (2)\r
+#define NADT_PV_PV_INTER (4)\r
+#define NADT_ACC_TRUNCATE (5)\r
+\r
+#define GH3X2X_MULTI_SENSOR_EVENT_LL_INDEX_GH_WEAR_ON            0   //index of member in linked list for gh senosr wear on\r
+#define GH3X2X_MULTI_SENSOR_EVENT_LL_INDEX_GH_WEAR_OFF           1   //index of member in linked list for gh senosr wear off\r
+#define GH3X2X_MULTI_SENSOR_EVENT_LL_INDEX_GS_MOVE               2   //index of member in linked list for gsensor move\r
+#define GH3X2X_MULTI_SENSOR_EVENT_LL_INDEX_GS_MOVE_TIME_OUT      3   //index of member in linked list for gsenosr move time out\r
+\r
+#define GH3X2X_MULTI_SENSOR_EVENT_NUM_MAX           4\r
+#define GH3X2X_MULTI_SENSOR_EVENT_LL_INDEX_INVALID     255\r
+\r
+#define GH3X2X_MULTI_SENSOR_EVENT_GH_WEAR_ON        (1 << GH3X2X_MULTI_SENSOR_EVENT_LL_INDEX_GH_WEAR_ON)        // gh sensor wear on\r
+#define GH3X2X_MULTI_SENSOR_EVENT_GH_WEAR_OFF       (1 << GH3X2X_MULTI_SENSOR_EVENT_LL_INDEX_GH_WEAR_OFF)       // gh sensor wear off\r
+#define GH3X2X_MULTI_SENSOR_EVENT_GS_MOVE           (1 << GH3X2X_MULTI_SENSOR_EVENT_LL_INDEX_GS_MOVE)           // gsensor move\r
+#define GH3X2X_MULTI_SENSOR_EVENT_GS_MOVE_TIME_OUT  (1 << GH3X2X_MULTI_SENSOR_EVENT_LL_INDEX_GS_MOVE_TIME_OUT)  //gs  move time out\r
+\r
+\r
+\r
+\r
+\r
+typedef struct\r
+{\r
+    GS32 *pData;\r
+    GS32 nLength;\r
+    GS32 nPos;\r
+}NADT_QUEUE_BUFFER_S32;\r
+\r
+typedef struct\r
+{\r
+    GS16 *pData;\r
+    GS32 nLength;\r
+    GS32 nPos;\r
+}NADT_QUEUE_BUFFER_S16;\r
+\r
+typedef struct\r
+{\r
+    const GF32 *pfCoefB;\r
+    const GF32 *pfCoefA;\r
+    GF32 *pfXbuff;\r
+    GF32 *pfYbuff;\r
+    GS32 lLen;\r
+    GF32 fThr;\r
+}NADT_ST_IIR_PARAM;\r
+\r
+typedef struct\r
+{\r
+    GS32 *pfFftValue;\r
+    GS16 *psPeakIndex;\r
+    GS16 *psValleyIndex;\r
+    GS16 *psPeakValleyIndex;\r
+    GS32 lPeakValleyLen;\r
+    GS32 lPeakLen;\r
+    GS32 lValleyLen;\r
+    GS32 lDataLen;\r
+}NADT_ST_PEAK_VALLEY_INFO;\r
+\r
+typedef struct\r
+{\r
+    GBOOL bSearchMax;\r
+    GS32 fExtremumValue;\r
+    GS32 lPreExtremumPos;\r
+    GS32 lExtremumPos;\r
+    GS32 lDataCount;\r
+}NADT_ST_PEAKX_DET;\r
+\r
+\r
+\r
+\r
+\r
+void GhMultSensorWearEventManagerInit(void);\r
+void GhMultSensorWearEventManagerHookRegister(void (*WearEventHook) (GU32 uchNewEvent));\r
+void GhMultSensorWearEventManagerEnable(void);\r
+void GhMultSensorWearEventManagerDisable(void);\r
+GU8 GhMultSensorWearEventManagerIsEnable(void);\r
+void GhMultSensorWearEventSend(GU32 unEvent);\r
+GU8 GhMultiSensorConditionCheckIsNew (GU32 unEventNew, GU32 unEventOld);\r
+GU8 GhMultiSensorConditionCheckInWindow (GU32 unEventComb, GU32 unWindow, GU8 uchNowTimeNeedInWin);\r
+\r
+\r
+\r
+\r
+\r
+#define GH_MULTI_SENSOR_TIMER_USER_TIME_STAMP 0\r
+#define GH_MULTI_SENSOR_TIMER_USER_MOVE_DET   1\r
+\r
+#define GH_MULTI_SENSOR_TIMER_USER_NUM_MAX 2\r
+\r
+\r
+typedef struct\r
+{\r
+       void (*TimerCreate)(GU32 unTimerPeriodMs);\r
+    void (*TimerStart)(void);\r
+       void (*TimerStop)(void);\r
+    void (*TimerDelete)(void);\r
+}STGhMultiSensorTimerOps;\r
+\r
+typedef struct\r
+{\r
+       void (*TimerHandle)(GU32 unTimeIntervalMs);\r
+}STGhMultiSensorTimerUser;\r
+\r
+\r
+typedef struct\r
+{\r
+       const STGhMultiSensorTimerOps *pstTimerOps;\r
+       STGhMultiSensorTimerUser stTimerUsers[GH_MULTI_SENSOR_TIMER_USER_NUM_MAX];\r
+}STGhMultiSensorTimer;\r
+\r
+\r
+\r
+\r
+void GhMultiSensorTimerInit(void);\r
+void GhMultiSensorTimerStart(void);\r
+void GhMultiSensorTimerStop(void);\r
+void GhMultiSensorTimerOpsRegister(const STGhMultiSensorTimerOps *pstTimerOps);\r
+void GhMultiSensorTimerOpsUnregister(void);\r
+void GhMultiSensorTimerHandle(void);\r
+\r
+\r
+\r
+void GhGsMoveDetecterInit(void);\r
+void GhGsMoveDetecterEnable(void);\r
+void GhGsMoveDetecterDisable(void);\r
+GU8 GhGsMoveDetecterIsEnable(void);\r
+\r
+#endif /* _GH3X2X_DRV_SOFT_LEAD_H_ */\r
+\r
+/********END OF FILE********* Copyright (c) 2003 - 2022, Goodix Co., Ltd. ********/\r
+\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_mp_code/inc/gh3x2x_demo_mp.h b/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_mp_code/inc/gh3x2x_demo_mp.h
new file mode 100644 (file)
index 0000000..bbd57d9
--- /dev/null
@@ -0,0 +1,193 @@
+/**\r
+ * @copyright (c) 2003 - 2022, Goodix Co., Ltd. All rights reserved.\r
+ *\r
+ * @file    gh3x2x_demo_mp.h\r
+ *\r
+ * @brief   header file of gh3x2x demo mp test\r
+ *\r
+ * @author  Goodix Product Tools Development Team\r
+ *\r
+ */\r
+ \r
+#ifndef _GH3X2X_DEMO_MP_H_\r
+#define _GH3X2X_DEMO_MP_H_\r
+\r
+#include "gh3x2x_mp_config.h"\r
+#include "gh3x2x_mp_define.h"\r
+\r
+#ifndef GH3X2X_MP_UNUSED_VAR\r
+#define GH3X2X_MP_UNUSED_VAR(X) ((void)(X))\r
+#endif  // GH3X2X_UNUSED_VAR\r
+\r
+/**\r
+ * @fn     void Gh3x2xDemoMp_Init()\r
+ *\r
+ * @brief  GH3x2x mp init\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   none\r
+ * @param[out]  None\r
+ *\r
+ * @return  none\r
+ */\r
+void Gh3x2xDemoMp_Init(void);\r
+\r
+/**\r
+ * @fn     GU8 Gh3x2xDemoMp_StartTest()\r
+ *\r
+ * @brief  GH3x2x mp start test\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   none\r
+ * @param[out]  None\r
+ *\r
+ * @return  0:test ok, other:error code\r
+ */\r
+GU8 Gh3x2xDemoMp_StartTest(void);\r
+\r
+/**\r
+ * @fn     void Gh3x2xDemoMp_SetTestParam_PPG(stGh3x2xMp_TestParam *stTestParam)\r
+ *\r
+ * @brief  GH3x2x MP set PPG test items param\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   stGh3x2xMp_PPGTestParam *stPPG_TestParam\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void Gh3x2xDemoMp_SetTestParam_PPG(stGh3x2xMp_PPGTestParam *stPPG_TestParam);\r
+\r
+/**\r
+ * @fn     void Gh3x2xDemoMp_SetTestParam_ECG(stGh3x2xMp_ECGTestParam *stECG_TestParam)\r
+ *\r
+ * @brief  GH3x2x MP set ECG test items param\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   stGh3x2xMp_ECGTestParam *stECG_TestParam\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void Gh3x2xDemoMp_SetTestParam_ECG(stGh3x2xMp_ECGTestParam *stECG_TestParam);\r
+\r
+/**\r
+ * @fn     void Gh3x2xDemoMp_SetTestParam(stGh3x2xMp_TestParam *stTestParam)\r
+ *\r
+ * @brief  GH3x2x MP set all test items param.\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   stGh3x2xMp_TestParam *stTestParam\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void Gh3x2xDemoMp_SetTestParam(stGh3x2xMp_TestParam *stTestParam);\r
+\r
+/**\r
+ * @fn     void Gh3x2xDemoMp_PrintTestResult(stGh3x2xMp_TestParam *stTestParam, stGh3x2xMp_TestResult *stTestResult)\r
+ *\r
+ * @brief  GH3x2x mp print all test result\r
+ *\r
+ * @attention   It must be called after the test ends\r
+ *\r
+ * @param[in]   stGh3x2xMp_TestParam *stTestParam, stGh3x2xMp_TestResult *stTestResult\r
+ * @param[out]  None\r
+ *\r
+ * @return  none\r
+ */\r
+void Gh3x2xDemoMp_PrintTestResult(stGh3x2xMp_TestParam *stTestParam, stGh3x2xMp_TestResult *stTestResult);\r
+\r
+/**\r
+ * @fn     GU8 Gh3x2xDemoMp_CommunicationTest(GCHAR *para, GCHAR *TestResult)\r
+ *\r
+ * @brief  GH3x2x MP Communication Test.\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   GU8 *puchPara, GU8 *pushTestResult\r
+ * @param[out]  None\r
+ *\r
+ * @return  error code\r
+ */\r
+GU8 Gh3x2xDemoMp_CommunicationTest(GU8 *puchPara, GU8 *pstTestResult);\r
+\r
+/**\r
+ * @fn     GU8 Gh3x2xDemoMp_CheckChipIDTest(GU8 *puchPara, GU8 *puchTestResult)\r
+ *\r
+ * @brief  GH3x2x MP Check Chip ID Test.\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   GU8 *puchPara, GU8 *pushTestResult\r
+ * @param[out]  None\r
+ *\r
+ * @return  error code\r
+ */\r
+GU8 Gh3x2xDemoMp_CheckChipIDTest(GU8 *puchPara, GU8 *puchTestResult);\r
+\r
+/**\r
+ * @fn     GU8 Gh3x2xDemoMp_RstIntTest(GCHAR *para, GCHAR *TestResult)\r
+ *\r
+ * @brief  GH3x2x MP Communication Test.\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   GU8 *puchPara, GU8 *pushTestResult\r
+ * @param[out]  None\r
+ *\r
+ * @return  error code\r
+ */\r
+GU8 Gh3x2xDemoMp_RstIntTest(GU8 *puchPara, GU8 *pstTestResult);\r
+\r
+/**\r
+ * @fn     GU8 Gh3x2xDemoMp_EfuseTest(GU8 *puchPara, stGh3x2xMp_EfuseTestResult *pstTestResult)\r
+ *\r
+ * @brief  GH3x2x MP efuse Test, check FT/CP and crc, and get chipUid\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   GU8 *puchPara, stGh3x2xMp_EfuseTestResult *pstTestResult\r
+ * @param[out]  None\r
+ *\r
+ * @return  error code\r
+ */\r
+GU8 Gh3x2xDemoMp_EfuseTest(GU8 *puchPara, stGh3x2xMp_EfuseTestResult *pstTestResult);\r
+\r
+/**\r
+ * @fn     GU8 Gh3x2xDemoMp_PPGTest(stGh3x2xMp_PPGTestParam *pstTestPara, stGh3x2xMp_PPGTestResult *pstTestResult)\r
+ *\r
+ * @brief  GH3x2x MP PPG Test\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   stGh3x2xMp_PPGTestParam *pstTestPara, stGh3x2xMp_PPGTestResult *pstTestResult\r
+ * @param[out]  None\r
+ *\r
+ * @return  error code\r
+ */\r
+GU8 Gh3x2xDemoMp_PPGTest(stGh3x2xMp_PPGTestParam *pstTestPara, stGh3x2xMp_PPGTestResult *pstTestResult);\r
+\r
+/**\r
+ * @fn     GU8 Gh3x2xDemoMp_ECGTest(stGh3x2xMp_ECGTestParam *pstTestPara, stGh3x2xMp_ECGTestResult *pstTestResult)\r
+ *\r
+ * @brief  GH3x2x MP ECG Test\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   stGh3x2xMp_ECGTestParam *pstTestPara, stGh3x2xMp_ECGTestResult *pstTestResult\r
+ * @param[out]  None\r
+ *\r
+ * @return  error code\r
+ */\r
+GU8 Gh3x2xDemoMp_ECGTest(stGh3x2xMp_ECGTestParam *pstTestPara, stGh3x2xMp_ECGTestResult *pstTestResult);\r
+\r
+\r
+#endif /* _GH3X2X_DEMO_MP_H_ */\r
+\r
+/********END OF FILE********* Copyright (c) 2003 - 2022, Goodix Co., Ltd. ********/\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_mp_code/inc/gh3x2x_demo_mp_process.h b/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_mp_code/inc/gh3x2x_demo_mp_process.h
new file mode 100644 (file)
index 0000000..7563272
--- /dev/null
@@ -0,0 +1,537 @@
+/**\r
+ * @copyright (c) 2003 - 2022, Goodix Co., Ltd. All rights reserved.\r
+ *\r
+ * @file    gh3x2x_demo_mp_process.h\r
+ *\r
+ * @brief   header file of gh3x2x_demo_mp_process\r
+ *\r
+ * @author  Goodix Product Tools Development Team\r
+ *\r
+ */\r
+ \r
+#ifndef _GH3X2X_DEMO_MP_PROCESS_H_\r
+#define _GH3X2X_DEMO_MP_PROCESS_H_\r
+\r
+#include "gh3x2x_mp_config.h"\r
+#include "gh3x2x_mp_reg_config.h"\r
+#include "gh3x2x_mp_define.h"\r
+\r
+\r
+/**\r
+ * @fn     gh3x2x_demo_mp_write_reg(GU16 usReg_Addr, GU16 usReg_Value)\r
+ *\r
+ * @brief  GH3x2x mp write reg\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   GU16 usReg_Addr, GU16 usReg_Value\r
+ * @param[out]  None\r
+ *\r
+ * @return  ret\r
+ */\r
+GU8 gh3x2x_demo_mp_write_reg(GU16 usReg_Addr, GU16 usReg_Value);\r
+\r
+/**\r
+ * @fn     GU16 gh3x2x_demo_mp_read_reg(GU16 usReg_Addr)\r
+ *\r
+ * @brief  GH3x2x mp read reg\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   GU16 usReg_Addr\r
+ * @param[out]  None\r
+ *\r
+ * @return  read reg value\r
+ */\r
+GU16 gh3x2x_demo_mp_read_reg(GU16 usReg_Addr);\r
+\r
+/**\r
+ * @fn    GU8 gh3x2x_demo_mp_write_regs(GU16 usReg_Addr, GU8 uchRegs_Write[], GU16 usLength)\r
+ *\r
+ * @brief  GH3x2x mp write regs\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   GU16 usReg_Addr, GU8 uchRegs_Write[], GU16 usLength\r
+ * @param[out]  None\r
+ *\r
+ * @return  ret\r
+ */\r
+GU8 gh3x2x_demo_mp_write_regs(GU16 usReg_Addr, GU8 uchRegs_Write[], GU16 usLength);\r
+\r
+/**\r
+ * @fn    GU8 gh3x2x_demo_mp_read_regs(GU16 usReg_Addr, GU8 uchRegs_Read[], GU16 usLength)\r
+ *\r
+ * @brief  GH3x2x mp read regs\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   GU16 usReg_Addr, GU16 usLength\r
+ * @param[out]  GU8 uchRegs_Read[]\r
+ *\r
+ * @return  ret\r
+ */\r
+GU8 gh3x2x_demo_mp_read_regs(GU16 usReg_Addr, GU8 uchRegs_Read[], GU16 usLength);\r
+\r
+/**\r
+ * @fn     GU8 gh3x2x_demo_mp_write_reg_mask(GU16 usRegAddr, GU16 usMask, GU16 usRegVal)\r
+ *\r
+ * @brief  GH3x2x mp write reg mask\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   GU16 usReg_Addr\r
+ * @param[out]  None\r
+ *\r
+ * @return  ret\r
+ */\r
+GU8 gh3x2x_demo_mp_write_reg_mask(GU16 usRegAddr, GU16 usMask, GU16 usRegVal);\r
+\r
+/**\r
+ * @fn     void gh3x2x_demo_mp_send_cmd(GU8 uchCmd)\r
+ *\r
+ * @brief  send cmd to gh3x2x chip\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   GU8 uchCmd\r
+ * @param[out]  None\r
+ *\r
+ * @return  ret\r
+ */\r
+void gh3x2x_demo_mp_send_cmd(GU8 uchCmd);\r
+\r
+/**\r
+ * @fn     void gh3x2x_demo_mp_reset_operation(void)\r
+ *\r
+ * @brief  reset gh3x2x chip\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void gh3x2x_demo_mp_reset_operation(void);\r
+\r
+/**\r
+ * @fn    GU8 gh3x2x_demo_mp_wait_for_int(GU16 usDutFlag, GU16 usTimeOut_ms)\r
+ *\r
+ * @brief  wait for int \r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   GU16 usDutFlag, GU16 usTimeOut\r
+ * @param[out]  none\r
+ *\r
+ * @return  ret\r
+ */\r
+GU8 gh3x2x_demo_mp_wait_for_int(GU16 usDutFlag, GU16 usTimeOut_ms);\r
+\r
+/**\r
+ * @fn     GU8 gh3x2x_demo_mp_set_chip_config(const stGh3x2xReg stGh3x2xMpRegConfig[], GU16 usConfigLen)\r
+ *\r
+ * @brief  GH3x2x mp write chip reg config\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   const stGh3x2xReg stGh3x2xMpRegConfig[], GU16 usConfigLen\r
+ * @param[out]  None\r
+ *\r
+ * @return  ret\r
+ */\r
+GU8 gh3x2x_demo_mp_set_chip_config(const stGh3x2xReg stGh3x2xMpRegConfig[], GU16 usConfigLen);\r
+\r
+/**\r
+ * @fn     GU8 gh3x2x_demo_mp_set_slot_config(stGh3x2xMp_SlotConfig stSlotConfig)\r
+ *\r
+ * @brief  GH3x2x mp set slot config\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   stGh3x2xMp_SlotConfig stSlotConfig\r
+ * @param[out]  None\r
+ *\r
+ * @return  ret\r
+ */\r
+GU8 gh3x2x_demo_mp_set_slot_config(stGh3x2xMp_SlotConfig stSlotConfig);\r
+\r
+/**\r
+ * @fn     GU8 gh3x2x_demo_mp_set_slot_enable(GU8 uchSlotConfigEnable)\r
+ *\r
+ * @brief  Calculate which slots need to be enabled according to SLOT_CFG_EN, \r
+ * @brief  enable the corresponding slot, and output the number of enabled slots\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   GU8 uchSlotConfigEnable\r
+ * @param[out]  GU8 *uchSlotEnableNum\r
+ *\r
+ * @return  ret\r
+ */\r
+GU8 gh3x2x_demo_mp_set_slot_enable(GU8 uchSlotConfigEnable, GU8 *uchSlotEnableNum);\r
+\r
+/**\r
+ * @fn     GU8 gh3x2x_demo_mp_set_LED_ACG_cfg(GU8 uchLED_N, GU8 uchLED_ACG_FS, stGh3x2xMp_PPGTestParam *pstTestPara)\r
+ *\r
+ * @brief  The automatic dimming test needs to adjust the LED driver gear to avoid the failure of the automatic dimming step by too large\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   GU8 uchSlotConfigEnable\r
+ * @param[out]  GU8 *uchSlotEnableNum\r
+ *\r
+ * @return  ret\r
+ */\r
+GU8 gh3x2x_demo_mp_set_LED_ACG_cfg(GU8 uchLED_N, GU8 uchLED_ACG_FS, stGh3x2xMp_PPGTestParam *pstTestPara);\r
+\r
+/**\r
+ * @fn     void gh3x2x_demo_mp_sampling_mode(GU8 uchMode)\r
+ *\r
+ * @brief  rawdata sampling start / stop\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   GU8 uchMode\r
+ * @param[out] \r
+ *\r
+ * @return  None\r
+ */\r
+void gh3x2x_demo_mp_sampling_mode(GU8 uchMode);\r
+\r
+/**\r
+ * @fn     GU8 gh3x2x_demo_mp_get_rawdata(GU16 uchRegAddr, GU8 uchRawdataArr[], GU32 usLength)\r
+ *\r
+ * @brief  get rawdata\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   GU16 uchRegAddr, GU32 usLength\r
+ * @param[out]  GU8 uchRawdataArr[]\r
+ *\r
+ * @return  ret\r
+ */\r
+GU8 gh3x2x_demo_mp_get_rawdata(GU16 uchRegAddr, GU8 uchRawdataArr[], GU32 usLength);\r
+\r
+/**\r
+ * @fn     GU8 gh3x2x_demo_mp_handle_rawdata(GU8 uchMode, GS32 nHandleRawdataArr[], GU32 unHandleRawdataSkipLength, GU8 uchSlot_N, GU8 uchADC_N, \\r
+                                                                               GU8 uchRawdataArr[], GU32 unRawdataArrLength, GU8 uchSampleStep)\r
+ *\r
+ * @brief  handle rawdata\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]  GU8 uchMode, GU32 unHandleRawdataSkipLength, GU8 uchSlot_N, GU8 uchADC_N, GU8 uchRawdataArr[], GU32 unRawdataArrLength, GU8 uchSampleStep\r
+ * @param[out]  GS32 nHandleRawdataArr[]\r
+ *\r
+ * @return  ret\r
+ */\r
+GU8 gh3x2x_demo_mp_handle_rawdata(GU8 uchMode, GS32 nHandleRawdataArr[], GU32 unHandleRawdataSkipLength, GU8 uchSlot_N, GU8 uchADC_N, \\r
+                                                                               GU8 uchRawdataArr[], GU32 unRawdataArrLength, GU8 uchSampleStep);\r
+\r
+/**\r
+ * @fn     gh3x2x_demo_mp_ppg_get_rawdata(GU8 uchMode, GU32 uchRawdataArr[][MAX_ADC_NUM][MAX_PPG_RAWDATA_SAMPLE_NUM], GU16 usRawdataLen, GU16 usRawdataSkipLen, GU16 usLED_PD_Num)\r
+ *\r
+ * @brief  ppg test get rawdata\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   GU16 usRawdataLen, GU16 usRawdataSkipLen, GU16 usLED_PD_Num\r
+ * @param[out]  GU32 unRawdataArr[][MAX_ADC_NUM][MAX_PPG_RAWDATA_SAMPLE_NUM]\r
+ *\r
+ * @return  ret\r
+ */\r
+GU8 gh3x2x_demo_mp_ppg_get_rawdata(GS32 unRawdataArr[][MAX_ADC_NUM][MAX_PPG_RAWDATA_SAMPLE_NUM], GU16 usRawdataLen, GU16 usRawdataSkipLen, GU16 usLED_PD_Num);\r
+\r
+/**\r
+ * @fn     void gh3x2x_demo_mp_calc_noise(GS32 nRawdataArr[], GU16 usLength, GF32 *fAvergeRawdata, GF32 *fNoise)\r
+ *\r
+ * @brief  cal noise\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   GS32 nRawdataArr[], GU16 usLength\r
+ * @param[out]  GF32 *fAvergeRawdata, GF32 *fNoise\r
+ *\r
+ * @return  none\r
+ */\r
+void gh3x2x_demo_mp_calc_noise(GS32 nRawdataArr[], GU16 usLength, GF32 *fAvergeRawdata, GF32 *fNoise);\r
+\r
+/**\r
+ * @fn     GF32 gh3x2x_demo_mp_calc_LPCTR(GF32 fAverageRawdata, GU32 unTIA, GU32 unILed)\r
+ *\r
+ * @brief  cal LP CTR\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   GF32 fAverageRawdata, GU32 unTIA, GU32 unILed\r
+ * @param[out]  \r
+ *\r
+ * @return  CTR\r
+ */\r
+GF32 gh3x2x_demo_mp_calc_LPCTR(GF32 fAverageRawdata, GU32 unTIA, GU32 unILed);\r
+\r
+/**\r
+ * @fn     GU8 gh3x2x_demo_mp_ecg_signal_filter(GS32 nRawdataArr[], GU16 usLength, GU8 uchLpType, GU8 uchHpType, GU8 uchFsType)\r
+ *\r
+ * @brief  ECG signal filter\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   GS32 nRawdataArr[], GU16 usLength, GU8 uchLpType, GU8 uchHpType, GU8 uchFsType\r
+                               uchLpType:Low pass filter cut-off frequency\r
+                               uchHpType:High pass filter cut-off frequency\r
+                               uchFsType:Sampling rate of rawdata,0,250Hz; 1,500Hz; 2,1000Hz; others, 500Hz\r
+ * @param[out]  GS32 nRawdataArr[]: filter data\r
+ *\r
+ * @return  ret\r
+ */\r
+GU8 gh3x2x_demo_mp_ecg_signal_filter(GS32 nRawdataArr[], GU16 usLength, GU8 uchLpType, GU8 uchHpType, GU8 uchFsType);\r
+\r
+/**\r
+ * @fn     GF32 gh3x2x_demo_mp_ecg_cal_HPF_Ratio(GS32 nRawdataArr[], GU16 usLength)\r
+ *\r
+ * @brief  cal HPF amplitude ratio\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   GS32 nRawdataArr[], GU16 usLength\r
+ * @param[out]  \r
+ *\r
+ * @return  HPF_Ratio\r
+ */\r
+GF32 gh3x2x_demo_mp_ecg_cal_HPF_Ratio(GS32 nRawdataArr[], GU16 usLength);\r
+\r
+/**\r
+ * @fn     GU8 gh3x2x_demo_mp_ecg_cal_signal_amp_freq(GS32 nRawdataArr[], GU16 usLength, GF32 *fAmp, GF32 *fFreq, \\r
+                                                                                                       GU8 uchLpType, GU8 uchHpType, GU8 uchFsType, GS16 sCalStart, GS16 sCalEnd, GF32 fRefFreq, GU8 uchStep)\r
+ *\r
+ * @brief  Cal the amplitude and frequency of the signal\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   GS32 nRawdataArr[], GU16 usLength, GU8 uchLpType, GU8 uchHpType, GU8 uchFsType, GS16 sCalStart, GS16 sCalEnd, GF32 fRefFreq, GU8 uchStep\r
+                               nRawdataArr:Data to be processed\r
+                               usLength:Data len\r
+                               uchLpType:Low pass filter cut-off frequency\r
+                               uchHpType:High pass filter cut-off frequency\r
+                               uchFsType:Sampling rate type of rawdata, 0,250Hz; 1,500Hz; 2,1000Hz; others, 500Hz\r
+                               sCalStart:FFT start begin point\r
+                               sCalEnd:FFT start end point\r
+                               fRefFreq:For reference frequency, find the maximum value near fref±5hz; if <0, find the maximum value between 0.1hz~fs/2\r
+ * @param[out]  GF32 *fAmp, GF32 *fFreq\r
+ *\r
+ * @return  ret\r
+ */\r
+GU8 gh3x2x_demo_mp_ecg_cal_signal_amp_freq(GS32 nRawdataArr[], GU16 usLength, GF32 *fAmp, GF32 *fFreq, GU8 uchLpType, \\r
+                                                                                       GU8 uchHpType, GU8 uchFsType, GS16 sCalStart, GS16 sCalEnd, GF32 fRefFreq, GU8 uchStep);\r
+                                                                                       \r
+/**\r
+ * @fn     GU8 gh3x2x_demo_mp_ecg_cmmr_calculate(GS32 nRawdataArr[], GU16 usLength, GF32 *fCmmr, GU8 uchFsType, GF32 fRefFreq)\r
+ *\r
+ * @brief  Cal the ecg-cmmr\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   GS32 nRawdataArr[], GU16 usLength, GU8 uchFsType, GF32 fRefFreq\r
+                               nRawdataArr:Data to be processed\r
+                               usLength:Data len\r
+                               uchFsType:Sampling rate type of rawdata, 0,250Hz; 1,500Hz; 2,1000Hz; others, 500Hz\r
+                               fRefFreq:For reference frequency, find the maximum value near fref±5hz; if <0, find the maximum value between 0.1hz~fs/2\r
+ * @param[out]  GF32 *fCmmr\r
+ *\r
+ * @return  ret\r
+ */\r
+GU8 gh3x2x_demo_mp_ecg_cmmr_calculate(GS32 nRawdataArr[], GU16 usLength, GF32 *fCmmr, GU8 uchFsType, GF32 fRefFreq);\r
+\r
+/**\r
+ * @fn     GU8 gh3x2x_demo_mp_ecg_cal_signal_WaveTimeDomin_Amp(GS32 nRawdataArr[], GU16 usLength, GF32 *fAmp, GU8 uchFsType, GF32 fRefFreq)\r
+ *\r
+ * @brief  Cal ecg-DCRange WaveTimeDomin Amp\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   GS32 nRawdataArr[], GU16 usLength, GF32 *fAmp, GU8 uchFsType, GF32 fRefFreq\r
+                               nRawdataArr:Data to be processed\r
+                               usLength:Data len\r
+                               uchFsType:Sampling rate type of rawdata, 0,250Hz; 1,500Hz; 2,1000Hz; others, 500Hz\r
+                               fRefFreq: Reference frequency\r
+ * @param[out]  GF32 *fAmp\r
+ *\r
+ * @return  ret\r
+ */\r
+GU8 gh3x2x_demo_mp_ecg_cal_signal_WaveTimeDomin_Amp(GS32 nRawdataArr[], GU16 usLength, GF32 *fAmp, GU8 uchFsType, GF32 fRefFreq);\r
+\r
+/**\r
+ * @fn     GU8 gh3x2x_demo_mp_PPG_LPCTR_Test(stGh3x2xMp_PPGTestParam *pstTestPara, stGh3x2xMp_PPGTestResult *pstTestResult)\r
+ *\r
+ * @brief  PPG test items ---- LP CTR test\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   stGh3x2xMp_PPGTestParam *pstTestPara, stGh3x2xMp_PPGTestResult *pstTestResult\r
+ * @param[out]  \r
+ *\r
+ * @return  error code\r
+ */\r
+GU8 gh3x2x_demo_mp_PPG_LPCTR_Test(stGh3x2xMp_PPGTestParam *pstTestPara, stGh3x2xMp_PPGTestResult *pstTestResult);\r
+\r
+/**\r
+ * @fn     GU8 gh3x2x_demo_mp_PPG_Noise_Test(stGh3x2xMp_PPGTestParam *pstTestPara, stGh3x2xMp_PPGTestResult *pstTestResult)\r
+ *\r
+ * @brief  PPG test items ---- noise test\r
+ *\r
+ * @attention   PPG Noise test requires automatic dimming. \r
+ * @attention   It is not possible to test all leds in parallel using multi-channel mode, only serial test\r
+ *\r
+ * @param[in]   stGh3x2xMp_PPGTestParam *pstTestPara, stGh3x2xMp_PPGTestResult *pstTestResult\r
+ * @param[out]  \r
+ *\r
+ * @return  error code\r
+ */\r
+GU8 gh3x2x_demo_mp_PPG_Noise_Test(stGh3x2xMp_PPGTestParam *pstTestPara, stGh3x2xMp_PPGTestResult *pstTestResult);\r
+\r
+/**\r
+ * @fn     GU8 gh3x2x_demo_mp_PPG_BaseNoise_Test(stGh3x2xMp_PPGTestParam *pstTestPara, stGh3x2xMp_PPGTestResult *pstTestResult)\r
+ *\r
+ * @brief  PPG test items ----base noise test\r
+ *\r
+ * @attention   base noise test has nothing to do with LEDs, so only one slot is needed to test the data of 4 PDs.\r
+ *\r
+ * @param[in]   stGh3x2xMp_PPGTestParam *pstTestPara, stGh3x2xMp_PPGTestResult *pstTestResult\r
+ * @param[out]  \r
+ *\r
+ * @return  error code\r
+ */\r
+GU8 gh3x2x_demo_mp_PPG_BaseNoise_Test(stGh3x2xMp_PPGTestParam *pstTestPara, stGh3x2xMp_PPGTestResult *pstTestResult);\r
+\r
+/**\r
+ * @fn     GU8 gh3x2x_demo_mp_PPG_LeakLight_Test(stGh3x2xMp_PPGTestParam *pstTestPara, stGh3x2xMp_PPGTestResult *pstTestResult)\r
+ *\r
+ * @brief  PPG test items ----leak light test\r
+ *\r
+ * @attention  \r
+ *\r
+ * @param[in]   stGh3x2xMp_PPGTestParam *pstTestPara, stGh3x2xMp_PPGTestResult *pstTestResult\r
+ * @param[out]  \r
+ *\r
+ * @return  error code\r
+ */\r
+GU8 gh3x2x_demo_mp_PPG_LeakLight_Test(stGh3x2xMp_PPGTestParam *pstTestPara, stGh3x2xMp_PPGTestResult *pstTestResult);\r
+\r
+/**\r
+ * @fn     GU8 gh3x2x_demo_mp_ECG_LeadOnOff_Test(stGh3x2xMp_ECGTestParam *pstTestPara, stGh3x2xMp_ECGTestResult *pstTestResult)\r
+ *\r
+ * @brief  ECG test items ----Lead on/off test\r
+ *\r
+ * @attention  \r
+ *\r
+ * @param[in]   stGh3x2xMp_ECGTestParam *pstTestPara, stGh3x2xMp_ECGTestResult *pstTestResult\r
+ * @param[out]  \r
+ *\r
+ * @return  error code\r
+ */\r
+GU8 gh3x2x_demo_mp_ECG_LeadOnOff_Test(stGh3x2xMp_ECGTestParam *pstTestPara, stGh3x2xMp_ECGTestResult *pstTestResult);\r
+\r
+/**\r
+ * @fn     GU8 gh3x2x_demo_mp_ECG_Noise_Test(stGh3x2xMp_ECGTestParam *pstTestPara, stGh3x2xMp_ECGTestResult *pstTestResult)\r
+ *\r
+ * @brief  ECG test items ----Noise test\r
+ *\r
+ * @attention  \r
+ *\r
+ * @param[in]   stGh3x2xMp_ECGTestParam *pstTestPara, stGh3x2xMp_ECGTestResult *pstTestResult\r
+ * @param[out]  \r
+ *\r
+ * @return  error code\r
+ */\r
+GU8 gh3x2x_demo_mp_ECG_Noise_Test(stGh3x2xMp_ECGTestParam *pstTestPara, stGh3x2xMp_ECGTestResult *pstTestResult);\r
+\r
+/**\r
+ * @fn     GU8 gh3x2x_demo_mp_ECG_HPF_Test(stGh3x2xMp_ECGTestParam *pstTestPara, stGh3x2xMp_ECGTestResult *pstTestResult)\r
+ *\r
+ * @brief  ECG test items ----HPF test\r
+ *\r
+ * @attention  \r
+ *\r
+ * @param[in]   stGh3x2xMp_ECGTestParam *pstTestPara, stGh3x2xMp_ECGTestResult *pstTestResult\r
+ * @param[out]  \r
+ *\r
+ * @return  error code\r
+ */\r
+GU8 gh3x2x_demo_mp_ECG_HPF_Test(stGh3x2xMp_ECGTestParam *pstTestPara, stGh3x2xMp_ECGTestResult *pstTestResult);\r
+\r
+/**\r
+ * @fn     GU8 gh3x2x_demo_mp_ECG_SIGNAL_Test(stGh3x2xMp_ECGTestParam *pstTestPara, stGh3x2xMp_ECGTestResult *pstTestResult)\r
+ *\r
+ * @brief  ECG test items ----SIGNAL test\r
+ *\r
+ * @attention  \r
+ *\r
+ * @param[in]   stGh3x2xMp_ECGTestParam *pstTestPara, stGh3x2xMp_ECGTestResult *pstTestResult\r
+ * @param[out]  \r
+ *\r
+ * @return  error code\r
+ */\r
+GU8 gh3x2x_demo_mp_ECG_SIGNAL_Test(stGh3x2xMp_ECGTestParam *pstTestPara, stGh3x2xMp_ECGTestResult *pstTestResult);\r
+\r
+/**\r
+ * @fn     GU8 gh3x2x_demo_mp_ECG_RLD_Test(stGh3x2xMp_ECGTestParam *pstTestPara, stGh3x2xMp_ECGTestResult *pstTestResult)\r
+ *\r
+ * @brief  ECG test items ----RLD test\r
+ *\r
+ * @attention  \r
+ *\r
+ * @param[in]   stGh3x2xMp_ECGTestParam *pstTestPara, stGh3x2xMp_ECGTestResult *pstTestResult\r
+ * @param[out]  \r
+ *\r
+ * @return  error code\r
+ */\r
+GU8 gh3x2x_demo_mp_ECG_RLD_Test(stGh3x2xMp_ECGTestParam *pstTestPara, stGh3x2xMp_ECGTestResult *pstTestResult);\r
+\r
+/**\r
+ * @fn     GU8 gh3x2x_demo_mp_ECG_CMRR_Test(stGh3x2xMp_ECGTestParam *pstTestPara, stGh3x2xMp_ECGTestResult *pstTestResult)\r
+ *\r
+ * @brief  ECG test items ----CMRR test\r
+ *\r
+ * @attention  \r
+ *\r
+ * @param[in]   stGh3x2xMp_ECGTestParam *pstTestPara, stGh3x2xMp_ECGTestResult *pstTestResult\r
+ * @param[out]  \r
+ *\r
+ * @return  error code\r
+ */\r
+GU8 gh3x2x_demo_mp_ECG_CMRR_Test(stGh3x2xMp_ECGTestParam *pstTestPara, stGh3x2xMp_ECGTestResult *pstTestResult);\r
+\r
+/**\r
+ * @fn     GU8 gh3x2x_demo_mp_ECG_LIN_Test(stGh3x2xMp_ECGTestParam *pstTestPara, stGh3x2xMp_ECGTestResult *pstTestResult)\r
+ *\r
+ * @brief  ECG test items ----LIN test\r
+ *\r
+ * @attention  \r
+ *\r
+ * @param[in]   stGh3x2xMp_ECGTestParam *pstTestPara, stGh3x2xMp_ECGTestResult *pstTestResult\r
+ * @param[out]  \r
+ *\r
+ * @return  error code\r
+ */\r
+GU8 gh3x2x_demo_mp_ECG_LIN_Test(stGh3x2xMp_ECGTestParam *pstTestPara, stGh3x2xMp_ECGTestResult *pstTestResult);\r
+\r
+/**\r
+ * @fn     GU8 gh3x2x_demo_mp_ECG_DCRange_Test(stGh3x2xMp_ECGTestParam *pstTestPara, stGh3x2xMp_ECGTestResult *pstTestResult)\r
+ *\r
+ * @brief  ECG test items ----DCRange test\r
+ *\r
+ * @attention  \r
+ *\r
+ * @param[in]   stGh3x2xMp_ECGTestParam *pstTestPara, stGh3x2xMp_ECGTestResult *pstTestResult\r
+ * @param[out]  \r
+ *\r
+ * @return  error code\r
+ */\r
+GU8 gh3x2x_demo_mp_ECG_DCRange_Test(stGh3x2xMp_ECGTestParam *pstTestPara, stGh3x2xMp_ECGTestResult *pstTestResult);\r
+\r
+#endif /* _GH3X2X_DEMO_MP_PROCESS_H_ */\r
+\r
+/********END OF FILE********* Copyright (c) 2003 - 2022, Goodix Co., Ltd. ********/\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_mp_code/inc/gh3x2x_mp_algorithm.h b/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_mp_code/inc/gh3x2x_mp_algorithm.h
new file mode 100644 (file)
index 0000000..59d1bdb
--- /dev/null
@@ -0,0 +1,184 @@
+/**\r
+ * @copyright (c) 2003 - 2022, Goodix Co., Ltd. All rights reserved.\r
+ *\r
+ * @file    gh3x2x_mp_algorithm.h\r
+ *\r
+ * @brief   header file of gh3x2x_mp_algorithm\r
+ *\r
+ * @author  Goodix Product Tools Development Team\r
+ *\r
+ */\r
+ \r
+#ifndef _GH3X2X_MP_ALGORITHM_H_\r
+#define _GH3X2X_MP_ALGORITHM_H_\r
+\r
+#include "gh3x2x_mp_config.h"\r
+#include "gh3x2x_mp_define.h"\r
+\r
+//IIR struct\r
+typedef struct\r
+{\r
+       GS32 stages;\r
+       const GD64(*sos)[6];\r
+       const GD64 *gain;\r
+       double x[8][3];\r
+       double y[8][2];\r
+}IIR_State_Def;\r
+\r
+\r
+/**\r
+ * @fn     GU8 gh3x2x_mp_crc_cal(GU8 *puchData, GU32 unLen)\r
+ *\r
+ * @brief  GH3x2x mp start test\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   none\r
+ * @param[out]  None\r
+ *\r
+ * @return  CRC\r
+ */\r
+GU8 gh3x2x_mp_crc_cal(GU8 *puchData, GU32 unLen);\r
+\r
+/**\r
+ * @fn     GD64 gh3x2x_mp_high_pass_filter(GD64 fData)\r
+ *\r
+ * @brief  GH3x2x mp high-pass filter\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   GD64 fData\r
+ * @param[out]  None\r
+ *\r
+ * @return  Filtered data\r
+ */\r
+GD64 gh3x2x_mp_high_pass_filter(GD64 fData);\r
+\r
+/**\r
+ * @fn     GU8 gh3x2x_mp_ecg_lead_off_dectection(GS32 nRawdataArr[], GU16 usRawdataLen, GU8 uchECGChannel_N, GU16 *usReSampleData_Len)\r
+ *\r
+ * @brief  dectect ecg lead off algorithm\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   GS32 nRawdataArr[], GU16 usRawdataLen, GU8 uchECGChannel_N, GU16 usReSampleData_Len\r
+ * @param[out]  None\r
+ *\r
+ * @return  ret\r
+ */\r
+GU8 gh3x2x_mp_ecg_lead_off_dectection(GS32 nRawdataArr[], GU16 usRawdataLen, GU8 uchECGChannel_N, GU16 *usReSampleData_Len);\r
+\r
+/**\r
+ * @fn     GD64 gh3x2x_mp_signal_IIR_filter(IIR_State_Def *stIIR_State, GD64 dData)\r
+ *\r
+ * @brief  GH3x2x mp signal IIR filter\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   IIR_State_Def *stIIR_State, GD64 dData\r
+ * @param[out]  None\r
+ *\r
+ * @return  Filtered data\r
+ */\r
+GD64 gh3x2x_mp_signal_IIR_filter(IIR_State_Def *stIIR_State, GD64 dData);\r
+\r
+/**\r
+ * @fn     void gh3x2x_mp_signal_filter(GS32 nFilterArr[], GU16 usLength, GU8 uchHpType, GU8 uchLpType, GU8 uchFsType)\r
+ *\r
+ * @brief  GH3x2x mp signal hp and lp filter for ecg\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   GS32 nFilterArr[], GU16 usLength, GU8 uchHpType, GU8 uchLpType, GU8 uchFsType\r
+                               uchLpType:Low pass filter cut-off frequency\r
+                               uchHpType:High pass filter cut-off frequency\r
+                               uchFsType:Sampling rate of rawdata\r
+ * @param[out]  GS32 nFilterArr[]\r
+ *\r
+ * @return  None\r
+ */\r
+void gh3x2x_mp_signal_filter(GS32 nFilterArr[], GU16 usLength, GU8 uchHpType, GU8 uchLpType, GU8 uchFsType);\r
+\r
+/**\r
+ * @fn     gh3x2x_mp_signal_fft(GS32 nFFT_InArr[], GS32 nFFT_OutArr[], GU32 unLength, GU32 step)\r
+ *\r
+ * @brief  fft\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   GD64 dFFT_InArr[], GS32 nFFT_OutArr[], GU32 unLength, GU32 step\r
+ * @param[out]  GD64 dFFTArr[]\r
+ *\r
+ * @return  ret\r
+ */\r
+void gh3x2x_mp_signal_fft(GF32 nFFT_InArr[], GF32 nFFT_OutArr[], GU32 unLength, GU32 unStep);\r
+\r
+/**\r
+ * @fn     void gh3x2x_mp_signal_quick_fft(GF32 fFFTInArr_real[], GF32 fFFTInArr_image[], GU32 unLength, GU32 unPower_2, \\r
+                                                                               GF32 fFFTOutArr_real[], GF32 fFFTOutArr_image[], GU8 uchFFTMode, GU32 uchCalModulus_Angle)\r
+ *\r
+ * @brief  more quick do fft process\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   GF32 fFFTInArr_real[], GF32 fFFTInArr_image[], GU32 unLength, GU32 unPower_2, GU8 uchFFTMode, GU32 uchCalModulus_Angle\r
+                               uchFFTMode: 0, Fourier transform; 1, inverse Fourier transform\r
+                               uchCalModulus_Angle: 0, do not calculate Fourier transform or inverse transform mode and amplitude Angle;1, calculate the modulus and amplitude Angle\r
+                               unLength: the number of points entered, which is an even number, is generally 32,64,128...1024, etc.\r
+                               unPower_2: satisfy n=2^unPower_2(unPower_2>0)\r
+                               fFFTInArr_real: 0,store the real part of the sampled data at N points; 1,store N real parts of the Fourier transform\r
+                               fFFTInArr_image: 0,store the imaginary part of the sampled data at N points; 1,store N imaginary parts of the Fourier transform\r
+\r
+ * @param[out]  GF32 fFFTInArr_real[], GF32 fFFTInArr_image[], \r
+                               fFFTOutArr_real: uchFFTMode=0, return the real part of the Fourier transform\r
+                                                               uchFFTMode=1, return the real part of the inverse Fourier transform\r
+                               fFFTOutArr_image:uchFFTMode=0, return the imaginary part of the Fourier transform\r
+                                                               uchFFTMode=1, return the imaginary part of the inverse Fourier transform\r
+                               fFFTInArr_real: uchCalModulus_Angle = 1, uchFFTMode = 0, return the modulus of Fourier transform\r
+                                                               uchCalModulus_Angle = 1, uchFFTMode = 1, return the inverse Fourier transform modulus\r
+                               fFFTInArr_image:uchCalModulus_Angle = 1, uchFFTMode = 0, return the amplitude Angle of the Fourier transform\r
+                                                               uchCalModulus_Angle = 1, uchFFTMode = 1, return the amplitude Angle of the inverse Fourier transform\r
+ *\r
+ * @return  none\r
+ */\r
+void gh3x2x_mp_signal_quick_fft(GF32 fFFTInArr_real[], GF32 fFFTInArr_image[], GU32 unLength, GU32 unPower_2, \\r
+                                                                               GF32 fFFTOutArr_real[], GF32 fFFTOutArr_image[], GU8 uchFFTMode, GU32 uchCalModulus_Angle);\r
+\r
+/**\r
+ * @fn     GU8 gh3x2x_mp_signal_fft_process(GS32 nFFTArr[] GU32 unLength)\r
+ *\r
+ * @brief  Perform FFT transformation on the data and then calculate the power spectrum\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   GS32 nFFTArr[], GU32 unLength\r
+ * @param[out]  GS32 nFFTArr[]\r
+ *\r
+ * @return  ret\r
+ */\r
+GU8 gh3x2x_mp_signal_fft_process(GF32 nFFTArr[], GU32 unLength);\r
+\r
+/**\r
+ * @fn     GU8 gh3x2x_demo_mp_ecg_fft_cal_amp_freq(GF32 fRawdataArr[], GU16 usLength,  GU32 unFFTLength, GU32 unSampleRate, GF32 *fAmp, GF32 *fFreq, \\r
+                                                                                                               GF32 fRefFreq, GU8 uchWintype)\r
+ *\r
+ * @brief  cal amp and freq after fft\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   GF32 fRawdataArr[], GU16 usLength, GU32 unFFTLength, GU32 unSampleRate, GU8 uchWintype, GF32 fRefFreq\r
+                               unSampleRate: Sampling frequency\r
+                               winType:Window type, 0: rectangular window; 1: flattop window, used to accurately estimate the amplitude; 2: hanning window\r
+                               fRefFreq:For reference frequency, find the maximum value near fref±5hz; if <0, find the maximum value between 0.1hz~fs/2\r
+ * @param[out]  GF32 *fAmp, GF32 *fFreq\r
+                               fAmp: peak-to-peak value\r
+                               fFreq:freq, unit Hz\r
+ *                             \r
+ * @return  ret\r
+ */\r
+GU8 gh3x2x_demo_mp_ecg_fft_cal_amp_freq(GF32 fRawdataArr[], GU16 usLength,  GU32 unFFTLength, GU32 unSampleRate, GF32 *fAmp, GF32 *fFreq, \\r
+                                                                                                               GF32 fRefFreq, GU8 uchWintype);\r
+\r
+#endif /* _GH3X2X_MP_ALGORITHM_H_ */\r
+\r
+/********END OF FILE********* Copyright (c) 2003 - 2022, Goodix Co., Ltd. ********/\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_mp_code/inc/gh3x2x_mp_common.h b/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_mp_code/inc/gh3x2x_mp_common.h
new file mode 100644 (file)
index 0000000..a49044e
--- /dev/null
@@ -0,0 +1,459 @@
+/**\r
+ * @copyright (c) 2003 - 2022, Goodix Co., Ltd. All rights reserved.\r
+ *\r
+ * @file    gh3x2x_mp_common.h\r
+ *\r
+ * @brief   header file of gh3x2x mp test common port\r
+ *\r
+ * @author  Goodix Product Tools Development Team\r
+ *\r
+ */\r
+ \r
+#ifndef _GH3X2X_MP_COMMON_H_\r
+#define _GH3X2X_MP_COMMON_H_\r
+\r
+#include "gh3x2x_mp_config.h"\r
+#include "gh3x2x_mp_define.h"\r
+#include <stdio.h>\r
+\r
+#if ( __GH3X2X_MP_USE_DRV_INTERFACE__ == __GH3X2X_DRV_MODE__ )\r
+       #if (__GH3X2X_MP_USE_DRV_INTERFACE_TYPE__ == __GH3X2X_DRV_LIB_INTERFACE__)\r
+               #include "gh_demo_inner.h"\r
+       #else //__GH3X2X_MP_USE_DRV_INTERFACE_TYPE__ == __GH3X2X_AFE_DRV_INTERFACE__\r
+               #include "gh3x2x_afe_drv.h"\r
+       #endif\r
+       \r
+#endif\r
+\r
+#if (__GH3X2X_MP_USE_DRV_INTERFACE_TYPE__ == __GH3X2X_DRV_LIB_INTERFACE__)\r
+#define GH3X2X_MP_DRV_LIB_LOG(...)  do{\\r
+                                            if(g_pSnprintfUserIn)\\r
+                                            {\\r
+                                                char gh3x2x_GH3X2X_INFO_LOG[GH3X2X_INFO_LOG_MAX_LEN] = {0};\\r
+                                                g_pSnprintfUserIn(gh3x2x_GH3X2X_INFO_LOG, GH3X2X_INFO_LOG_MAX_LEN, __VA_ARGS__);\\r
+                                                GH3X2X_PlatformLog((GCHAR *)gh3x2x_GH3X2X_INFO_LOG);\\r
+                                            }\\r
+                                            if(g_pPrintfUserIn)g_pPrintfUserIn(__VA_ARGS__);\\r
+                                        } while(0)\r
+\r
+\r
+#define GH3X2X_MP_LOG_L1_INNER(...)  GH3X2X_MP_DRV_LIB_LOG("[gh3x2x mp error]: "__VA_ARGS__)\r
+#define GH3X2X_MP_LOG_L2_INNER(...)  GH3X2X_MP_DRV_LIB_LOG("[gh3x2x mp info]: "__VA_ARGS__)\r
+#define GH3X2X_MP_LOG_INNER(...)  GH3X2X_MP_DRV_LIB_LOG(__VA_ARGS__)\r
+\r
+\r
+#else\r
+#define GH3X2X_MP_AFE_LOG(...)  do {\\r
+                                                    char gh3x2x_log_string[GH3X2X_MP_LOG_MAX_LEN] = {0};\\r
+                                                    snprintf(gh3x2x_log_string, GH3X2X_MP_LOG_MAX_LEN, __VA_ARGS__);\\r
+                                                    gh3x2x_mp_log((GCHAR *)gh3x2x_log_string);\\r
+                                    } while(0)\r
+\r
+\r
+\r
+#define GH3X2X_MP_LOG_L1_INNER(...)  GH3X2X_MP_AFE_LOG("[gh3x2x mp error]: "__VA_ARGS__)\r
+#define GH3X2X_MP_LOG_L2_INNER(...)  GH3X2X_MP_AFE_LOG("[gh3x2x mp info]: "__VA_ARGS__)\r
+#define GH3X2X_MP_LOG_INNER(...)     GH3X2X_MP_AFE_LOG(__VA_ARGS__)\r
+\r
+\r
+#endif\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+/* log def*/\r
+#if (__GH3X2X_MP_LOG_LVL__) //log level, =0 not print log\r
+\r
+       #define   GH3X2X_MP_LOG_L1(...)                 GH3X2X_MP_LOG_L1_INNER(__VA_ARGS__)\r
+       #if(__GH3X2X_MP_LOG_LVL__ > 1)\r
+               #define GH3X2X_MP_LOG_L2(...)           GH3X2X_MP_LOG_L2_INNER(__VA_ARGS__)\r
+       #else\r
+               #define GH3X2X_MP_LOG_L2(...)\r
+       #endif\r
+       \r
+#else //log level == 0, not print log\r
+       #define   GH3X2X_MP_LOG_L1(...)  \r
+       #define   GH3X2X_MP_LOG_L2(...)\r
+#endif\r
+\r
+#define   GH3X2X_MP_LOG(...)                   GH3X2X_MP_LOG_INNER(__VA_ARGS__)                                                        \r
+\r
+extern GU8 GH3x2xMp_IntFlag; //use for mp\r
+#define GH3X2X_MP_SET_INT_FLAG()                       {GH3x2xMp_IntFlag = 1;}\r
+\r
+#ifdef GOODIX_DEMO_MP_PLANFORM\r
+#include "gh3x2x_demo_mp_goodix_platform.h"\r
+#else\r
+#define GOODIX_MP_PLATFORM_I2C_INIT_ENTITY()\r
+#define GOODIX_MP_PLATFORM_I2C_WRITE_ENTITY(device_id, write_buffer, length)\r
+#define GOODIX_MP_PLATFORM_I2C_READ_ENTITY(device_id, write_buffer, write_length, read_buffer, read_length)\r
+#define GOODIX_MP_PLATFORM_I2C_SEND_CMD_ENTITY(device_id, uchCmd)\r
+#define GOODIX_MP_PLATFORM_SPI_INIT_ENTITY()\r
+#define GOODIX_MP_PLATFORM_SPI_WRITE_ENTITY(write_buffer, length)\r
+#define GOODIX_MP_PLATFORM_SPI_READ_ENTITY(uchWriteBuffer, usWriteLength, uchReadBuffer, usReadLength)\r
+#define GOODIX_MP_PLATFORM_SPI_SEND_CMD_ENTITY(uchCmd)\r
+#define GOODIX_MP_PLATFORM_RESET_PIN_INIT_ENTITY()\r
+#define GOODIX_MP_PLATFORM_RESET_PIN_CTRL_ENTITY(pin_level)\r
+#define GOODIX_MP_PLATFORM_INT_INIT_ENTITY()\r
+#define GOODIX_MP_PLATFORM_INT_HANDLER_CALL_BACK_ENTITY()\r
+#define GOODIX_MP_PLATFORM_LED_POWER_PIN_INIT_ENTITY()\r
+#define GOODIX_MP_PLATFORM_LED_POWER_ON_ENTITY()\r
+#define GOODIX_MP_PLATFORM_LED_POWER_OFF_ENTITY()\r
+#define GOODIX_MP_PLATFORM_PROMPT_UP_RUBBER_ENTITY()\r
+#define GOODIX_MP_PLATFORM_PROMPT_TEST_OK_ENTITY()\r
+#define GOODIX_MP_PLATFORM_PROMPT_TEST_NG_ENTITY()\r
+#define GOODIX_MP_PLATFORM_ECG_UART_SEND_ENTITY(uchSendBuffer, usLength)                                                                               1\r
+#define GOODIX_MP_PLATFORM_ECG_UART_RECEIVE_ENTITY(uchRevBuffer, usTimeout_ms)                                                                 1\r
+#define GOODIX_MP_PLATFORM_ECG_SIGNAL_AND_IO_STATUS_SET_ENTITY(emECG_Status, stECGSignalSetting, uchSpec)              1\r
+#define GOODIX_MP_PLATFORM_LOG_ENTITY(log_string)\r
+#define GOODIX_MP_PLATFORM_DELAY_US_ENTITY(usUsec)\r
+#define GOODIX_MP_PLATFORM_DELAY_MS_ENTITY(usMsec)\r
+\r
+\r
+#endif\r
+\r
+/* i2c interface */\r
+/**\r
+ * @fn     void gh3x2x_mp_i2c_init(void)\r
+ * \r
+ * @brief  i2c init for gh3x2x mp\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void gh3x2x_mp_i2c_init(void);\r
+\r
+/**\r
+ * @fn    GU8 gh3x2x_mp_i2c_write(GU8 device_id, const GU8 write_buffer[], GU16 length)\r
+ * \r
+ * @brief  i2c write for gh3x2x mp\r
+ *\r
+ * @attention  \r
+ *\r
+ * @param[in]   write_buffer    write data buffer\r
+ * @param[in]   length          write data len\r
+ * @param[out]  None\r
+ *\r
+ * @return  status\r
+ * @retval  #1      return successfully\r
+ * @retval  #0      return error\r
+ */\r
+GU8 gh3x2x_mp_i2c_write(GU8 device_id, const GU8 write_buffer[], GU16 length);\r
+\r
+/**\r
+ * @fn     uint8_t gh3x2x_mp_i2c_read(uint8_t device_id, const uint8_t write_buffer[], uint16_t write_length,\r
+ *                            uint8_t read_buffer[], uint16_t read_length)\r
+ * \r
+ * @brief  i2c read for gh3x2x mp\r
+ *\r
+ * @attention   \r
+ *\r
+ * @param[in]   device_id       device addr\r
+ * @param[in]   write_buffer    write data buffer\r
+ * @param[in]   write_length    write data len\r
+ * @param[in]   read_length     read data len\r
+ * @param[out]  read_buffer     pointer to read buffer\r
+ *\r
+ * @return  status\r
+ * @retval  #1      return successfully\r
+ * @retval  #0      return error\r
+ */\r
+GU8 gh3x2x_mp_i2c_read(GU8 device_id, const GU8 write_buffer[], GU16 write_length, GU8 read_buffer[], GU16 read_length);\r
+\r
+/**\r
+ * @fn    GU8 gh3x2x_mp_i2c_send_cmd(GU8 device_id, GU8 uchCmd)\r
+ * \r
+ * @brief  i2c send cmd to gh3x2x mp\r
+ *\r
+ * @attention  \r
+ *\r
+ * @param[in]   GU8 device_id, GU8 uchCmd\r
+ * @param[out]  None\r
+ *\r
+ * @return  status\r
+ * @retval  #1      return successfully\r
+ * @retval  #0      return error\r
+ */\r
+GU8 gh3x2x_mp_i2c_send_cmd(GU8 device_id, GU8 uchCmd);\r
+\r
+/* spi interface */\r
+/**\r
+ * @fn     void gh3x2x_mp_spi_init(void)\r
+ * \r
+ * @brief  spi init for gh3x2x mp\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void gh3x2x_mp_spi_init(void);\r
+\r
+/**\r
+ * @fn     GU8 gh3x2x_mp_spi_write(GU8 write_buffer[], GU16 length)\r
+ * \r
+ * @brief  spi write for gh3x2x mp\r
+ *\r
+ * @param[in]   write_buffer    write data buffer\r
+ * @param[in]   length          write data len\r
+ * @param[out]  None\r
+ *\r
+ * @return  status\r
+ * @retval  #1      return successfully\r
+ * @retval  #0      return error\r
+ */\r
+GU8 gh3x2x_mp_spi_write(GU8 write_buffer[], GU16 length);\r
+\r
+/**\r
+ * @fn     GU8 gh3x2x_mp_spi_read(GU8 uchWriteBuffer[], GU16 usWriteLength, GU8 uchReadBuffer[], GU16 usReadLength)\r
+ * \r
+ * @brief  spi read for gh3x2x mp\r
+ *\r
+ * @attention   \r
+ *\r
+ * @param[in]   GU8 uchWriteBuffer[], GU16 usWriteLength\r
+ * @param[out]  GU8 uchReadBuffer[], GU16 usReadLength\r
+ *\r
+ * @return  status\r
+ * @retval  #1      return successfully\r
+ * @retval  #0      return error\r
+ */\r
+GU8 gh3x2x_mp_spi_read(GU8 uchWriteBuffer[], GU16 usWriteLength, GU8 uchReadBuffer[], GU16 usReadLength);\r
+\r
+/**\r
+ * @fn    GU8 gh3x2x_mp_spi_send_cmd(GU8 uchCmd)\r
+ * \r
+ * @brief  spi send cmd to gh3x2x\r
+ *\r
+ * @attention  \r
+ *\r
+ * @param[in]   GU8 uchCmd\r
+ * @param[out]  None\r
+ *\r
+ * @return  status\r
+ * @retval  #1      return successfully\r
+ * @retval  #0      return error\r
+ */\r
+GU8 gh3x2x_mp_spi_send_cmd(GU8 uchCmd);\r
+\r
+/**\r
+ * @fn     void gh3x2x_mp_reset_pin_init(void)\r
+ * \r
+ * @brief  reset pin init for gh3x2x mp\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void gh3x2x_mp_reset_pin_init(void);\r
+\r
+/**\r
+ * @fn     void gh3x2x_mp_reset_pin_ctrl(GU8 pin_level)\r
+ * \r
+ * @brief  hal reset pin ctrl for gh3x2x\r
+ *\r
+ * @attention   pin level set 1 [high level] or 0 [low level]\r
+ *\r
+ * @param[in]   pin_level     reset pin level\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+\r
+void gh3x2x_mp_reset_pin_ctrl(GU8 pin_level);\r
+\r
+\r
+/**\r
+ * @fn     void gh3x2x_mp_int_init(void)\r
+ * \r
+ * @brief  gh3x2x int init\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void gh3x2x_mp_int_init(void);\r
+\r
+/**\r
+ * @fn     void gh3x2x_mp_int_handler_call_back(void)\r
+ * \r
+ * @brief  call back of gh3x2x int handler, mp lib need make GH3x2xMp_IntFlag = 1\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void gh3x2x_mp_int_handler_call_back(void);\r
+\r
+/**\r
+ * @fn     void gh3x2x_mp_led_power_pin_init(void)\r
+ * \r
+ * @brief  init led power pin\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void gh3x2x_mp_led_power_pin_init(void);\r
+\r
+/**\r
+ * @fn     gh3x2x_mp_led_power_on(void)\r
+ * \r
+ * @brief  led power on\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void gh3x2x_mp_led_power_on(void);\r
+\r
+/**\r
+ * @fn     void gh3x2x_mp_led_power_off(void)\r
+ * \r
+ * @brief  led power off\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void gh3x2x_mp_led_power_off(void);\r
+\r
+/**\r
+ * @fn     GU8 gh3x2x_mp_ecg_uart_send(GU8 uchSendBuffer[], GU16 usLength)\r
+ * \r
+ * @brief  Communicates with the ECG signal generator board through uart\r
+ *\r
+ * @attention  None\r
+ *\r
+ * @param[in]   GU8 uchSendBuffer[], GU16 usLength\r
+                               \r
+ * @param[out]  None\r
+ *\r
+ * @return  ret\r
+ */\r
+GU8 gh3x2x_mp_ecg_uart_send(GU8 uchSendBuffer[], GU16 usLength);\r
+\r
+/**\r
+ * @fn     GU8 gh3x2x_mp_ecg_uart_receive(GU8 uchRevBuffer[], GU16 Timeout_ms)\r
+ * \r
+ * @brief  Communicates with the ECG signal generator board through uart\r
+ *\r
+ * @attention  None\r
+ *\r
+ * @param[in]   GU8 uchRevBuffer[], GU16 Timeout_ms\r
+                               \r
+ * @param[out]  None\r
+ *\r
+ * @return  usLength: The length of the data rev\r
+ */\r
+GU16 gh3x2x_mp_ecg_uart_receive(GU8 uchRevBuffer[], GU16 usTimeout_ms);\r
+\r
+\r
+/**\r
+ * @fn     GU8 gh3x2x_mp_ecg_signal_and_io_status_set(emECG_SIGNAL_AND_IO_STATUS_SET emECG_Status, stGh3x2xMp_ECGSignalSetting stECGSignalSetting, emECG_SET_SIGNAL_SPEC uchSpec)\r
+ * \r
+ * @brief  Set ECG signal and IO status according to ECG test item\r
+ *\r
+ * @attention\r
+ *\r
+ * @param[in]   emECG_SIGNAL_AND_IO_STATUS_SET emECG_Status, stGh3x2xMp_ECGSignalSetting stECGSignalSetting, emECG_SET_SIGNAL_SPEC uchSpec\r
+ * @param[out]  None\r
+ *\r
+ * @return  ret\r
+ */\r
+GU8 gh3x2x_mp_ecg_signal_and_io_status_set(emECG_SIGNAL_AND_IO_STATUS_SET emECG_Status, stGh3x2xMp_ECGSignalSetting stECGSignalSetting, emECG_SET_SIGNAL_SPEC uchSpec);\r
+\r
+/**\r
+ * @fn     void gh3x2x_mp_prompt_message(GU8 uchMsg[], GU16 usMsglen)\r
+ * \r
+ * @brief  prompt message to do something\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   GU8 uchMsg, GU16 usMsglen\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void gh3x2x_mp_prompt_message(GU8 uchMsg[], GU16 usMsglen);\r
+\r
+/**\r
+ * @fn     void gh3x2x_mp_log(char *log_string)\r
+ * \r
+ * @brief  for print mp log\r
+ *\r
+ * @attention   this function must define that print mp test log\r
+ *\r
+ * @param[in]   log_string      pointer to log string\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void gh3x2x_mp_log(GCHAR *log_string);\r
+\r
+/**\r
+ * @fn     void gh3x2x_mp_delay_us(GU16 usUsec)\r
+ * \r
+ * @brief  Delay in us,user must register this function\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+\r
+void gh3x2x_mp_delay_us(GU16 usUsec);\r
+\r
+\r
+/**\r
+ * @fn     void Gh3x2x_mp_delay_ms(GU16 usMsec)\r
+ * \r
+ * @brief  Delay in ms\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void gh3x2x_mp_delay_ms(GU16 usMsec);\r
+\r
+\r
+\r
+#endif /* _GH3X2X_MP_COMMON_H_ */\r
+\r
+/********END OF FILE********* Copyright (c) 2003 - 2022, Goodix Co., Ltd. ********/\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_mp_code/inc/gh3x2x_mp_config.h b/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_mp_code/inc/gh3x2x_mp_config.h
new file mode 100644 (file)
index 0000000..d886fc6
--- /dev/null
@@ -0,0 +1,86 @@
+/*\r
+ * @Author: penglei 1624952103@qq.com\r
+ * @Date: 2025-06-25 13:57:13\r
+ * @LastEditors: penglei 1624952103@qq.com\r
+ * @LastEditTime: 2025-06-25 15:52:04\r
+ * @FilePath: /FD230/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_mp_code/inc/gh3x2x_mp_config.h\r
+ * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE\r
+ */\r
+/**\r
+ * @copyright (c) 2003 - 2022, Goodix Co., Ltd. All rights reserved.\r
+ *\r
+ * @file    gh3x2x_mp_config.h\r
+ *\r
+ * @brief   header file of gh3x2x_mp_config.c\r
+ *\r
+ * @author  Goodix Product Tools Development Team\r
+ *\r
+ */\r
+#include "gh_drv.h"\r
+\r
+#ifndef _GH3X2X_MP_CONFIG_H_\r
+#define _GH3X2X_MP_CONFIG_H_\r
+\r
+/* communicate interface macro */\r
+#define __GH3X2X_MP_INTERFACE_I2C__                                      (1)                                                           /**< interface use i2c >**/\r
+#define __GH3X2X_MP_INTERFACE_SPI__                                      (2)                                                           /**< interface use spi >**/\r
+\r
+/* code type type macro */\r
+#define __GH3X2X_DRV_MODE__                                      (1)                                                           /**< include drv code >**/\r
+#define __GH3X2X_MP_MODE_                                        (0)                                                           /**< just mp code >**/\r
+\r
+/* drv interface type macro */\r
+#define __GH3X2X_DRV_LIB_INTERFACE__                                     (1)                                                           /**< mp test use drv lib interface >**/\r
+#define __GH3X2X_AFE_DRV_INTERFACE__                                     (2)                                                           /**< mp test use afe drv interface >**/\r
+\r
+/* type redefine */\r
+// typedef unsigned char       GU8;    /**< 8bit unsigned integer type */\r
+// typedef signed char         GS8;    /**< 8bit signed integer type */\r
+// typedef unsigned short      GU16;   /**< 16bit unsigned integer type */\r
+// typedef signed short        GS16;   /**< 16bit signed integer type */\r
+// typedef int                 GS32;   /**< 32bit signed integer type */\r
+// typedef unsigned int        GU32;   /**< 32bit unsigned integer type */\r
+// typedef float               GF32;   /**< float type */\r
+// typedef double              GD64;   /**< double type */\r
+// typedef char                GCHAR;  /**< char type */\r
+// typedef unsigned char       GBOOL;  /**< bool type */\r
+// typedef long long           GS64;   /**< 64bit signed integer type */\r
+\r
+\r
+//config\r
+#define __GH3X2X_MP_USE_DRV_INTERFACE__                                          (__GH3X2X_DRV_MODE__)                                                         /**< use drv or mp iterface define, 0:use mp lib interface i2c/spi,  1:use drv interface i2c/spi >**/\r
+\r
+#if(__GH3X2X_MP_USE_DRV_INTERFACE__)\r
+#define __GH3X2X_MP_USE_DRV_INTERFACE_TYPE__              (__GH3X2X_DRV_LIB_INTERFACE__)    /**< drv interface config __GH3X2X_DRV_LIB_INTERFACE__ /__GH3X2X_AFE_DRV_INTERFACE__ >**/           \r
+#else\r
+#define __GH3X2X_MP_USE_DRV_INTERFACE_TYPE__              (0)    /**< drv interface config __GH3X2X_DRV_LIB_INTERFACE__ /__GH3X2X_AFE_DRV_INTERFACE__ >**/           \r
+#endif\r
+\r
+#define __GH3X2X_MP_INTERFACE__                                          (__GH3X2X_MP_INTERFACE_SPI__)     /**< interface config __GH3X2X_MP_INTERFACE_I2C__ /__GH3X2X_MP_INTERFACE_SPI__ >**/\r
+\r
+#define __GH3X2X_MP_LOG_LVL__                                    (2)                                   /**< gh3x2x mp log level, <==0>off, <==1>error log, <==2>info log >**/\r
+\r
+#define __GH3X2X_MP_PRINT_RAWDATA__                                              (0)                                                           /**< 0:close print rawdata,  1:open print rawdata >**/\r
+#define __GH3X2X_MP_PRINT_TEST_RESULT__                                          (1)                                                           /**< 0:close print test result,  1:open print test result >**/\r
+\r
+#define GH3X2X_MP_LOG_MAX_LEN                             (256)                                        /**< gh3x2x mp log max len >**/\r
+\r
+#define MAX_PPG_RAWDATA_SAMPLE_NUM                                               (550)                                                         /**< ppg max rawdata sample, not more than MAX_RAWDATA_SAMPLE_NUM >**/\r
+#define MAX_RAWDATA_SAMPLE_NUM                                                   (4096)                                                        /**< ECG max rawdata sample >**/\r
+#define MAX_FFT_LENGTH                                                                   (4096)                                                        /**< ECG FFT process data max length, must(MAX_FFT_LENGTH*2*4) < (RAWDATA_BUF_SIZE / 2) >**/\r
+\r
+/***********************************  DO NOT MODIFY FOLLOWING CODE *******************************/\r
+\r
+#ifdef GOODIX_DEMO_PLATFORM\r
+#undef __GH3X2X_MP_USE_DRV_INTERFACE_TYPE__\r
+#define __GH3X2X_MP_USE_DRV_INTERFACE_TYPE__ (__GH3X2X_DRV_LIB_INTERFACE__)\r
+#endif\r
+\r
+#ifdef GH3X2X_AFE_DRV_CODE\r
+#undef __GH3X2X_MP_USE_DRV_INTERFACE_TYPE__\r
+#define __GH3X2X_MP_USE_DRV_INTERFACE_TYPE__ (__GH3X2X_AFE_DRV_INTERFACE__)\r
+#endif\r
+\r
+#endif /* _GH3X2X_MP_CONFIG_H_ */\r
+\r
+/********END OF FILE********* Copyright (c) 2003 - 2022, Goodix Co., Ltd. ********/\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_mp_code/inc/gh3x2x_mp_define.h b/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_mp_code/inc/gh3x2x_mp_define.h
new file mode 100644 (file)
index 0000000..8861aee
--- /dev/null
@@ -0,0 +1,297 @@
+/**\r
+ * @copyright (c) 2003 - 2022, Goodix Co., Ltd. All rights reserved.\r
+ *\r
+ * @file    gh3x2x_mp_define.h\r
+ *\r
+ * @brief   define test items para, error code and so on\r
+ *\r
+ * @author  Goodix Product Tools Development Team\r
+ *\r
+ */\r
+ \r
+#ifndef _GH3X2X_MP_DEFINE_H_\r
+#define _GH3X2X_MP_DEFINE_H_\r
+\r
+#include "gh3x2x_mp_config.h"\r
+\r
+/*******GH3x2x test fw version define************/\r
+#define GH3X2X_MP_LIB_VERSION                                                          ("GH3x2x_MP_Lib_V1.0.0.0.0")\r
+/***END****GH3x2x test fw version define*********/\r
+\r
+/*******test error code define************/\r
+#define MT_TEST_PASS                                                                                                                   0x00\r
+\r
+#define MT_ERROR_COMMUNICATION_TEST_ERROR                                                                              0x01\r
+#define        MT_ERROR_EFUSE_ERROR                                                                                                    0x04\r
+#define MT_ERROR_LP_NOISE_ABNORMAL                                                                                             0x07\r
+#define MT_ERROR_LPBASE_NOISE_ABNORMAL                                                                                 0x08\r
+#define MT_ERROR_LPBASE_DC_OFFSET_ABNORMAL                                                                             0x09\r
+#define MT_ERROR_LED_LP_RAWDATA_ABNORMAL                                                                               0x10\r
+\r
+#define MT_ERROR_LEAK_LEDLP_RAWDATA_ABNORMAL                                                                   0x30\r
+#define MT_ERROR_LEAK_AVGER_ERR                                                                                                0x40\r
+\r
+#define MT_ERROR_COMMUNICATE_FAIL                                                                                              0x18\r
+#define MT_ERROR_CHECK_CHIPID_ERROR                                                                                            0x20\r
+\r
+#define MT_ERROR_ECG_LEADONOFF_ERR                                                                                             0x60\r
+#define MT_ERROR_ECG_NOISE_ERR                                                                                                 0x61\r
+#define MT_ERROR_ECG_HPF_ERR                                                                                                   0x62\r
+#define MT_ERROR_ECG_SIGNAL_ERR                                                                                                        0x63\r
+#define MT_ERROR_ECG_CMMR_ERR                                                                                                  0x64\r
+#define MT_ERROR_ECG_RLD_ERR                                                                                                   0x65\r
+#define MT_ERROR_ECG_LIN_ERR                                                                                                   0x66\r
+#define MT_ERROR_ECG_DCRANGE_ERR                                                                                               0x67\r
+/***END****test error code define*********/\r
+\r
+\r
+/*******test cmd define************/\r
+#define GH3X2X_MP_CMD_RESUME                                           (0xC3)  //chip resume cmd\r
+/***END****test cmd define*********/\r
+\r
+\r
+/*******test related information define************/\r
+#define READ_RAWDATA_FIFO_MAX_BYTE_NUM                                 3200\r
+#define RAWDATA_BUF_SIZE                                                               MAX_SLOT_NUM*MAX_ADC_NUM*MAX_PPG_RAWDATA_SAMPLE_NUM*4\r
+\r
+\r
+#define GH3X2X_DEMO_MP_EFUSE_MAX_LEN           32\r
+#define CHIP_UID_LENGTH                                                12\r
+\r
+#define START_SAMPLING                                         0\r
+#define STOP_SAMPLING                                          1\r
+\r
+#define MAX_SLOT_NUM                                                   8\r
+#define MAX_LED_NUM                                            8\r
+#define MAX_ADC_NUM                                            4\r
+\r
+#define SPEC_MODE_PPG                          0\r
+#define SPEC_MODE_ECG                          1\r
+\r
+#define SLOT_ONECH_MODE                                0        //Using single-channel mode, only one PD is collected per slot\r
+#define SLOT_MULTICH_MODE                              1        //Using multi-channel mode, each slot can collect multiple PDs, but does not support automatic dimming\r
+#define SLOT_CFG_INDEX                                         0x1C     //Each slot register address offset\r
+\r
+#define ADC_OFFSET                                                                     8388608\r
+#define RAWDATA_TO_VOL(x)                                                      ((x)*1.8*1000000 / ADC_OFFSET)  //rawdata to voltage value, unit uV\r
+#define ADC_MAX                                                                                        (GF32)(0x800000)        // ADC full offset value\r
+#define ADC_REFER                                                                      1800.0f                         // ADC reference voltage\r
+#define GAIN                                                                           20.0f                           // System gain\r
+\r
+#define LED_POWER_OFF                                                                  0\r
+#define LED_POWER_ON                                                                   1\r
+\r
+#define        LED0_LLPRAWDATA_INDEX                                                   32\r
+\r
+#define ECG_MAX_SIGNAL_NUM                                                             5\r
+#define ECGBOARD_DAC_CHANNELA                                          0x01\r
+#define ECGBOARD_DAC_CHANNELB                                          0x08\r
+#define UART_CMD_GETADC                                                                0x13\r
+/***END****test related information define*********/\r
+\r
+/*******test prompt message define************/\r
+#define PPG_PROMPT_UP_RUBBER_MSG                                                                               "Please up the Rubber!"\r
+#define GH3X2X_MP_TEST_OK_MSG                                                                                  "Gh3x2x mp test is OK!"\r
+#define GH3X2X_MP_TEST_NG_MSG                                                                                  "Gh3x2x mp test is NG!"\r
+/***END****test prompt message define*********/\r
+\r
+\r
+/*******test param define************/\r
+//define gh3x2x mp slot config struct\r
+typedef struct\r
+{\r
+       GU8 Slot_Cfg_N;                                                 //Configure the corresponding slot cfg number\r
+       GU8 Slot_Mutiple;                                               //Current slot period multiple\r
+       GU8 ADC_N;                                                              //ADC number used\r
+       GU8 ADC_IntTimes;                                               //ADC integration times\r
+       GU8 PD_N;                                                               //PD number, can be set to multi-channel, such as PD0|PD1\r
+       GU8 LED_N;                                                              //LED number, greater than 8 means not connect any LED\r
+       GU8 LED_ACG;                                                    //Automatic dimming enable configuration\r
+       GU8 LED_Drv;                                                    //LED current configuration, this configuration is invalid after turning on automatic dimming\r
+       GU8 TIA_RF;                                                     //TIA gain resistor configuration\r
+       GU8 TIA_CF;                                                     //TIA capacitor configuration\r
+       GU8 BG_Level;                                                   //bg suppression level, 0:only led, 1:1st order amb cancel, 2:2nd order amb cancel, 3:2x 2nd order amb cancel, 4: ECG mode\r
+       GU16 Slot_TMR;                                                  //Slot running time, unit 1us\r
+       GU8 Slot_Mode;                                                  //SLOT_MULTICH_MODE or SLOT_ONECH_MODE\r
+}stGh3x2xMp_SlotConfig;\r
+\r
+//LED&PD channel enable config struct\r
+typedef struct{\r
+    GU8 PD_Channel[MAX_LED_NUM];     //PD location to be tested for each slot\r
+    GU8 PD_Num[MAX_LED_NUM];         //The number of PDs to be tested for each slot, the maximum is MAX_ADC_NUM\r
+    GU8 PD_Channel_AllSlot;          //PD positions to be tested for all slots\r
+    GU8 PD_Num_AllSlot;              //The number of PDs to be tested for all slots, the maximum is MAX_ADC_NUM\r
+    GU8 LED_PD_Num;                  //The number of LED*PD to be tested, the maximum is MAX_ADC_NUM*MAX_LED_NUM\r
+    GU8 LED_Channel;                 //LED location to be tested\r
+    GU8 LED_Num;                     //The number of LEDs to be tested, the maximum is MAX_LED_NUM\r
+}stGh3x2xMp_LEDPDConfig;\r
+\r
+\r
+//define gh3x2x mp PPG test param\r
+typedef struct\r
+{\r
+       GU32 PPG_CTRRawdata_Num;                                                //need get nums, max is MAX_PPG_RAWDATA_SAMPLE_NUM\r
+       GU32 PPG_CTRRawdata_SkipNum;                                    //need skip num\r
+       GU32 PPG_NoiseRawdata_Num;\r
+       GU32 PPG_NoiseRawdata_SkipNum;\r
+       GU32 PPG_BaseNoiseRawdata_Num;\r
+       GU32 PPG_BaseNoiseRawdata_SkipNum;\r
+       GU32 PPG_LeakLightRawdata_Num;\r
+       GU32 PPG_LeakLightRawdata_SkipNum;\r
+       \r
+       //test items slot config\r
+       stGh3x2xMp_SlotConfig stCTRSlotConfig;  \r
+       stGh3x2xMp_SlotConfig stNoiseSlotConfig;\r
+       stGh3x2xMp_SlotConfig stBaseNoiseSlotConfig;\r
+       stGh3x2xMp_SlotConfig stLeakLightSlotConfig;\r
+       \r
+       stGh3x2xMp_LEDPDConfig stLEDPDConfig; //LED&PD channel enable config\r
+       \r
+}stGh3x2xMp_PPGTestParam;\r
+\r
+\r
+//Set ECG IO status according to ECG test item\r
+typedef enum\r
+{\r
+       ECG_SIGNAL_AND_IO_STATUS_DEFAULT = 0x00,\r
+       ECG_SIGNAL_AND_IO_STATUS_LEAD_ON = 0x01,\r
+       ECG_SIGNAL_AND_IO_STATUS_LEAD_OFF = 0x02,\r
+       ECG_SIGNAL_AND_IO_STATUS_NOISE = 0x03,\r
+       ECG_SIGNAL_AND_IO_STATUS_HPF = 0x04,\r
+       ECG_SIGNAL_AND_IO_STATUS_SIGNAL = 0x05,\r
+       ECG_SIGNAL_AND_IO_STATUS_RLD = 0x06,\r
+       ECG_SIGNAL_AND_IO_STATUS_CMMR = 0x07,\r
+       ECG_SIGNAL_AND_IO_STATUS_LIN = 0x08,\r
+       ECG_SIGNAL_AND_IO_STATUS_DC_RANGE = 0x09,\r
+       \r
+}emECG_SIGNAL_AND_IO_STATUS_SET;\r
+\r
+//define Special treatment for ECG items set signal and io status \r
+typedef enum\r
+{\r
+       NONE_SPEC = 0,\r
+       ECG_HPF_SPEC = 1,\r
+       \r
+}emECG_SET_SIGNAL_SPEC;\r
+\r
+//Set ECG signal type\r
+typedef enum\r
+{\r
+       NONE_MODE = 0,\r
+       DC_MODE,\r
+       AC_MODE,\r
+       ANG_MODE,\r
+       \r
+}emECG_Signal_Type;\r
+\r
+//define gh3x2x mp ECG signal struct param\r
+typedef struct\r
+{\r
+       GU16 Rawdata_Num;\r
+       GU16 Rawdata_SkipNum;\r
+       GU8 Sampling_Step; //rawdata sampling step length, must need > 0\r
+       \r
+       GBOOL bECG_NegativeSignal;//Positive or negative signals\r
+       GBOOL bECG_HighImpedance;//whether High impedance\r
+       GF32  ECG_Freq;//signal freq\r
+       GF32  ECG_Vol; //Signal amplitude\r
+       GF32  ECG_ACOffset;//AC signal offset\r
+       GF32  ECG_DCOffset;//DC signal offset\r
+       emECG_Signal_Type   ECG_SignalType;//Signal type, sine wave, triangle wave\r
+}stGh3x2xMp_ECGSignalSetting;\r
+\r
+//define gh3x2x mp ECG test param\r
+typedef struct\r
+{\r
+       //test item signal num setting, only setting HPF,SIGNAL,CMRR,LIN and DCRange\r
+       GU8 HPF_ECGSignalNum; //must 2 signals in a group\r
+       GU8 SIGNAL_ECGSignalNum;\r
+       GU8 CMRR_ECGSignalNum;\r
+       GU8 LIN_ECGSignalNum; //must 2 signals in a group\r
+       GU8 DCRange_ECGSignalNum; //must 3 signals in a group\r
+       \r
+       //setting HPF,SIGNAL,CMRR,LIN and DCRange signal config\r
+       stGh3x2xMp_ECGSignalSetting stECGSignal_HPF[ECG_MAX_SIGNAL_NUM]; //rawdata num need >= 200\r
+       stGh3x2xMp_ECGSignalSetting stECGSignal_SIGNAL[ECG_MAX_SIGNAL_NUM];\r
+       stGh3x2xMp_ECGSignalSetting stECGSignal_CMRR[ECG_MAX_SIGNAL_NUM]; //rawdata num need >= 200\r
+       stGh3x2xMp_ECGSignalSetting stECGSignal_LIN[ECG_MAX_SIGNAL_NUM];\r
+       stGh3x2xMp_ECGSignalSetting stECGSignal_DCRange[ECG_MAX_SIGNAL_NUM];\r
+       \r
+       //setting LeadOnOff, Noise and RLD signal config, only need set Rawdata_Num and Rawdata_SkipNum\r
+       stGh3x2xMp_ECGSignalSetting stECGSignal_LeadOnOff;\r
+       stGh3x2xMp_ECGSignalSetting stECGSignal_Noise; //rawdata num need >= 600\r
+       stGh3x2xMp_ECGSignalSetting stECGSignal_RLD;\r
+\r
+}stGh3x2xMp_ECGTestParam;\r
+\r
+//define gh3x2x mp all test param\r
+typedef struct\r
+{\r
+       //PPG and ECG test param set\r
+       stGh3x2xMp_PPGTestParam stPPG_TestParam;\r
+       stGh3x2xMp_ECGTestParam stECG_TestParam;\r
+\r
+}stGh3x2xMp_TestParam;\r
+/***END****test param define*********/\r
+\r
+\r
+/*******test result define************/\r
+//define gh3x2x mp Efuse test result\r
+typedef struct\r
+{\r
+       GU8     uchChipUid[CHIP_UID_LENGTH];\r
+\r
+}stGh3x2xMp_EfuseTestResult;\r
+\r
+//define gh3x2x mp rawdata handle data result\r
+typedef struct\r
+{\r
+       GF32 Noise[MAX_LED_NUM*MAX_SLOT_NUM];\r
+       GF32 AvergeRawdata[MAX_LED_NUM*MAX_SLOT_NUM];\r
+\r
+}stGh3x2xMp_RawdataHandleResult;\r
+\r
+//define gh3x2x mp PPG test result\r
+typedef struct\r
+{\r
+       GF32 LED_Noise[MAX_LED_NUM*MAX_ADC_NUM];\r
+       GF32 LED_BaseNoise[MAX_LED_NUM*MAX_ADC_NUM];\r
+       GF32 LED_LPCTR[MAX_LED_NUM*MAX_ADC_NUM];\r
+       GF32 LED_DCOffset[MAX_LED_NUM*MAX_ADC_NUM];\r
+       GF32 LED_LLPCTR[MAX_LED_NUM*MAX_ADC_NUM];\r
+       GF32 LED_LeakRatio[MAX_LED_NUM*MAX_ADC_NUM];\r
+       \r
+       stGh3x2xMp_RawdataHandleResult stCTRRawHandleResult;\r
+       stGh3x2xMp_RawdataHandleResult stNoiseRawHandleResult;\r
+       stGh3x2xMp_RawdataHandleResult stBaseNoiseRawHandleResult;\r
+       stGh3x2xMp_RawdataHandleResult stLeakLightRawHandleResult;\r
+\r
+}stGh3x2xMp_PPGTestResult;\r
+\r
+//define gh3x2x mp ECG test result\r
+typedef struct\r
+{\r
+       GF32 ECG_Noise;\r
+       GF32 ECG_HPFRatio[ECG_MAX_SIGNAL_NUM];\r
+       GF32 ECG_Amp[ECG_MAX_SIGNAL_NUM];\r
+       GF32 ECG_Freq[ECG_MAX_SIGNAL_NUM];\r
+       GF32 ECG_RLD;\r
+       GF32 ECG_CMRR[ECG_MAX_SIGNAL_NUM];\r
+       GF32 ECG_LIN_Ratio[ECG_MAX_SIGNAL_NUM];\r
+       GF32 ECG_DCRange_Ratio[ECG_MAX_SIGNAL_NUM];\r
+       GF32 ECG_DCRange_Amp[ECG_MAX_SIGNAL_NUM];\r
+       \r
+}stGh3x2xMp_ECGTestResult;\r
+\r
+//define gh3x2x mp all test result\r
+typedef struct\r
+{\r
+       stGh3x2xMp_EfuseTestResult stEfuse_TestResult;\r
+       stGh3x2xMp_PPGTestResult stPPG_TestResult;\r
+       stGh3x2xMp_ECGTestResult stECG_TestResult;\r
+}stGh3x2xMp_TestResult;\r
+/***END****test result define************/\r
+\r
+#endif /* _GH3X2X_MP_DEFINE_H_ */\r
+\r
+/********END OF FILE********* Copyright (c) 2003 - 2022, Goodix Co., Ltd. ********/\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_mp_code/inc/gh3x2x_mp_param_config.h b/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_mp_code/inc/gh3x2x_mp_param_config.h
new file mode 100644 (file)
index 0000000..45a87d0
--- /dev/null
@@ -0,0 +1,130 @@
+/**\r
+ * @copyright (c) 2003 - 2022, Goodix Co., Ltd. All rights reserved.\r
+ *\r
+ * @file    gh3x2x_mp_param_config.h\r
+ *\r
+ * @brief   header file of gh3x2x_mp_param_config.c\r
+ *\r
+ * @author  Goodix Product Tools Development Team\r
+ *\r
+ */\r
+#ifndef _GH3X2X_MP_PARAM_CONFIG_H_\r
+#define _GH3X2X_MP_PARAM_CONFIG_H_\r
+\r
+#include "gh3x2x_mp_define.h"\r
+\r
+//define test items select/not select test\r
+typedef enum\r
+{\r
+       SKIP = 0,\r
+       TEST = 1,\r
+       NG_CONTINUE = 2,\r
+}emMpTestItemStatus;\r
+\r
+//define enable/disable\r
+typedef enum\r
+{\r
+       MP_DISABLE = 0,\r
+       MP_ENABLE = 1,\r
+}emMp_Enable;\r
+\r
+//define LED full-scale gear\r
+typedef enum\r
+{\r
+       LED_DRIVE_25MA = 0x00,\r
+       LED_DRIVE_50MA = 0x01,\r
+       LED_DRIVE_100MA = 0x10,\r
+       LED_DRIVE_200MA = 0x11,\r
+}emAutoDimming_Gear;\r
+\r
+//define gh3x2x all test items\r
+typedef struct\r
+{\r
+       //all test items\r
+    emMpTestItemStatus COMMUNICATION_TEST;\r
+       emMpTestItemStatus CHECK_CHIPID_TEST;\r
+       emMpTestItemStatus RST_INT_TEST;\r
+       emMpTestItemStatus EFUSE_TEST;\r
+       emMpTestItemStatus PPG_TEST;\r
+       emMpTestItemStatus ECG_TEST;\r
+\r
+}stMpItemsConfig;\r
+\r
+//define PPG test items\r
+typedef struct\r
+{\r
+       emMpTestItemStatus PPG_LPCTR_TEST;\r
+       emMpTestItemStatus PPG_NOISE_TEST;\r
+       emMpTestItemStatus PPG_BASENOISE_TEST;\r
+       emMpTestItemStatus PPG_LEAKLIGHT_TEST;\r
+       \r
+}stMpPPGItemsConfig;\r
+\r
+//define ECG test items\r
+typedef struct\r
+{\r
+       \r
+       emMpTestItemStatus ECG_LEADONOFF_TEST;\r
+       emMpTestItemStatus ECG_NOISE_TEST;\r
+       emMpTestItemStatus ECG_HPF_TEST;\r
+       emMpTestItemStatus ECG_SIGNAL_TEST;\r
+       emMpTestItemStatus ECG_RLD_TEST;\r
+       emMpTestItemStatus ECG_CMRR_TEST;\r
+       emMpTestItemStatus ECG_LIN_TEST;\r
+       emMpTestItemStatus ECG_DCRANGE_TEST;\r
+       \r
+}stMpECGItemsConfig;\r
+\r
+//define LED automatic dimming config\r
+typedef struct\r
+{\r
+       emAutoDimming_Gear LED_ACG_FS[MAX_LED_NUM];//set LED full-scale gear ,00:25mA,01:50mA,10:100mA,11:200mA,\r
+       GU32 LED_Max_Rawdata;//LED automatic dimming threshold dimming\r
+    GU32 LED_Min_Rawdata;\r
+    GU32 LED_Ref_Up;\r
+    GU32 LED_Ref_Down;\r
+\r
+}stMpAutoDimmingConfig;\r
+\r
+\r
+//define gh3x2x test limit\r
+typedef struct\r
+{\r
+    GF32 PPG_CTR_MinLimit[MAX_SLOT_NUM*MAX_ADC_NUM];\r
+       GF32 PPG_LeakCTR_MaxLimit[MAX_SLOT_NUM*MAX_ADC_NUM];\r
+       GF32 PPG_LeakRatio_Throld[MAX_SLOT_NUM*MAX_ADC_NUM];\r
+       GF32 PPG_Noise_MaxLimit;\r
+       GF32 PPG_BaseNoise_MaxLimit;\r
+       GF32 PPG_DCOffset_MaxLimit;\r
+       GF32 PPG_DCOffset_MinLimit;\r
+\r
+       \r
+       GF32 ECG_Noise_MaxLimit;\r
+       GF32 ECG_HPF_MinLimit;\r
+       GF32 ECG_HPF_MaxLimit;\r
+       GF32 ECG_MaxAMP;\r
+       GF32 ECG_MaxFreq;\r
+       GF32 ECG_SIGNAL_MaxLimit;\r
+       GF32 ECG_RLD_MaxAmp;\r
+       GF32 ECG_CMRR_MinLimit;\r
+       GF32 ECG_LIN_MaxLimit;\r
+       GF32 ECG_DCRange_MaxLimit;\r
+       \r
+}stMpItemsLimitConfig;\r
+\r
+extern const stMpItemsConfig stGh3x2xMpTestItemsSatus;\r
+\r
+extern const stMpPPGItemsConfig stGh3x2xMpPPGItemsSatus;\r
+\r
+extern const stMpECGItemsConfig stGh3x2xMpECGItemsSatus;\r
+\r
+extern const emMp_Enable PPG_LEDPD_EN[MAX_LED_NUM][MAX_ADC_NUM];\r
+\r
+//LED automatic dimming threshold dimming\r
+extern const stMpAutoDimmingConfig stGh3x2xPPG_AutoDimming;\r
+\r
+extern const stMpItemsLimitConfig stGh3x2xMpLimit;\r
+\r
+#endif /* _GH3X2X_MP_PARAM_CONFIG_H_ */\r
+\r
+/********END OF FILE********* Copyright (c) 2003 - 2022, Goodix Co., Ltd. ********/\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_mp_code/inc/gh3x2x_mp_reg_config.h b/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_mp_code/inc/gh3x2x_mp_reg_config.h
new file mode 100644 (file)
index 0000000..53f4387
--- /dev/null
@@ -0,0 +1,31 @@
+/**\r
+ * @copyright (c) 2003 - 2022, Goodix Co., Ltd. All rights reserved.\r
+ *\r
+ * @file    gh3x2x_mp_reg_config.h\r
+ *\r
+ * @brief   header file of gh3x2x_mp_reg_config.c\r
+ *\r
+ * @author  Goodix Product Tools Development Team\r
+ *\r
+ */\r
+#ifndef _GH3X2X_MP_REG_CONFIG_H_\r
+#define _GH3X2X_MP_REG_CONFIG_H_\r
+\r
+#include "gh3x2x_mp_config.h"\r
+\r
+typedef struct\r
+{\r
+    GU16 usRegAddr;\r
+    GU16 usRegValue;\r
+       \r
+}stGh3x2xReg;\r
+\r
+\r
+extern const stGh3x2xReg stGh3x2xMpRegConfigDefault[24];\r
+extern const stGh3x2xReg stGh3x2xMpRegPPGConfig[15];\r
+extern const stGh3x2xReg stGh3x2xMpRegECGLeadConfg[41];\r
+extern const stGh3x2xReg stGh3x2xMpRegECGConfgDefault[23];\r
+\r
+#endif /* _GH3X2X_MP_REG_CONFIG_H_ */\r
+\r
+/********END OF FILE********* Copyright (c) 2003 - 2022, Goodix Co., Ltd. ********/\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_mp_code/src/gh3x2x_demo_mp.c b/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_mp_code/src/gh3x2x_demo_mp.c
new file mode 100644 (file)
index 0000000..54c7be7
--- /dev/null
@@ -0,0 +1,1210 @@
+/**\r
+ * @copyright (c) 2003 - 2022, Goodix Co., Ltd. All rights reserved.\r
+ * \r
+ * @file    gh3x2x_demo_mp.c\r
+ * \r
+ * @brief   gh3x2x mp test example\r
+ * \r
+ * @author  Goodix Product Tools Development Team\r
+ * \r
+ */\r
+ \r
+/* includes */\r
+#include <stdio.h>\r
+#include <string.h>\r
+#include "gh3x2x_demo_mp.h"\r
+#include "gh3x2x_mp_reg_config.h"\r
+#include "gh3x2x_mp_common.h"\r
+#include "gh3x2x_mp_algorithm.h"\r
+#include "gh3x2x_demo_mp_process.h"\r
+#include "gh3x2x_mp_param_config.h"\r
+\r
+extern GU8 GH3x2xMp_IntFlag;\r
+\r
+/**\r
+ * @fn     void Gh3x2xDemoMp_Init()\r
+ *\r
+ * @brief  GH3x2x mp init\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   none\r
+ * @param[out]  None\r
+ *\r
+ * @return  none\r
+ */\r
+void Gh3x2xDemoMp_Init(void)\r
+{\r
+\r
+#if( __GH3X2X_MP_USE_DRV_INTERFACE__ )\r
+       //use drv lib interface\r
+       \r
+#else\r
+#if ( __GH3X2X_MP_INTERFACE__ == __GH3X2X_MP_INTERFACE_I2C__ )\r
+       gh3x2x_mp_i2c_init();\r
+#else\r
+       gh3x2x_mp_spi_init();\r
+#endif //__GH3X2X_MP_INTERFACE__\r
+       \r
+       gh3x2x_mp_reset_pin_init();\r
+       gh3x2x_mp_int_init();\r
+#endif //__GH3X2X_MP_USE_DRV_INTERFACE__\r
+       \r
+       gh3x2x_mp_led_power_pin_init();\r
+       gh3x2x_mp_led_power_off(); //need do it\r
+       \r
+}\r
+\r
+/**\r
+ * @fn     GU8 Gh3x2xDemoMp_StartTest()\r
+ *\r
+ * @brief  GH3x2x mp start test\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   none\r
+ * @param[out]  None\r
+ *\r
+ * @return  0:test ok, other:error code\r
+ */\r
+\r
+GU8 Gh3x2xDemoMp_StartTest()\r
+{\r
+       GU8 gh3x2x_mp_test_code = 0; //Save the first NG error code\r
+       GU8 test_code_tmp = 0;\r
+       GH3X2X_MP_LOG_L2("Gh3x2x mp start! \r\n");\r
+       //print version\r
+       GH3X2X_MP_LOG_L2("Gh3x2x mp lib version: %s \r\n", GH3X2X_MP_LIB_VERSION);\r
+\r
+       stGh3x2xMp_TestParam stTestParam;\r
+       stGh3x2xMp_TestResult stTestResult;\r
+       memset(&stTestParam, 0, sizeof(stGh3x2xMp_TestParam));\r
+       memset(&stTestResult, 0, sizeof(stGh3x2xMp_TestResult));\r
+       \r
+       //set test param\r
+       Gh3x2xDemoMp_SetTestParam(&stTestParam);\r
+       \r
+       //reset\r
+       gh3x2x_demo_mp_reset_operation();\r
+       \r
+       do\r
+       {\r
+               // Communication Test\r
+               if(stGh3x2xMpTestItemsSatus.COMMUNICATION_TEST)\r
+               {\r
+                       test_code_tmp = Gh3x2xDemoMp_CommunicationTest(NULL, NULL);\r
+                       if(!gh3x2x_mp_test_code) //Save the first NG error code\r
+                               gh3x2x_mp_test_code = test_code_tmp;\r
+                       if(test_code_tmp && (NG_CONTINUE != stGh3x2xMpTestItemsSatus.COMMUNICATION_TEST))\r
+                               break;\r
+               }\r
+\r
+               //Check Chip ID Test\r
+               //need use drv interface to check, at present Only need to test this item when the driver is AFE\r
+#if ( __GH3X2X_MP_USE_DRV_INTERFACE__ == __GH3X2X_DRV_MODE__ )\r
+       #if (__GH3X2X_MP_USE_DRV_INTERFACE_TYPE__ == __GH3X2X_DRV_LIB_INTERFACE__)\r
+               //No need to do at the moment\r
+       #else //__GH3X2X_MP_USE_DRV_INTERFACE_TYPE__ == __GH3X2X_AFE_DRV_INTERFACE__\r
+               if(stGh3x2xMpTestItemsSatus.CHECK_CHIPID_TEST)\r
+               {\r
+                       test_code_tmp = Gh3x2xDemoMp_CheckChipIDTest(NULL, NULL);\r
+                       if(!gh3x2x_mp_test_code) //Save the first NG error code\r
+                               gh3x2x_mp_test_code = test_code_tmp;\r
+                       if(test_code_tmp)\r
+                               break;\r
+               }\r
+       #endif\r
+#endif         \r
+\r
+               //RstInt Test\r
+               if(stGh3x2xMpTestItemsSatus.RST_INT_TEST)\r
+               {\r
+                       test_code_tmp = Gh3x2xDemoMp_RstIntTest(NULL, NULL);\r
+                       if(!gh3x2x_mp_test_code) //Save the first NG error code\r
+                               gh3x2x_mp_test_code = test_code_tmp;\r
+                       if(test_code_tmp && (NG_CONTINUE != stGh3x2xMpTestItemsSatus.RST_INT_TEST))\r
+                               break;\r
+               }\r
+               \r
+               //Efuse Test\r
+               if(stGh3x2xMpTestItemsSatus.EFUSE_TEST)\r
+               {\r
+                       test_code_tmp = Gh3x2xDemoMp_EfuseTest(NULL, &stTestResult.stEfuse_TestResult);\r
+                       if(!gh3x2x_mp_test_code) //Save the first NG error code\r
+                               gh3x2x_mp_test_code = test_code_tmp;\r
+                       if(test_code_tmp && (NG_CONTINUE != stGh3x2xMpTestItemsSatus.EFUSE_TEST))\r
+                               break;\r
+               }\r
+               \r
+               //PPG Test \r
+               if(stGh3x2xMpTestItemsSatus.PPG_TEST)\r
+               {\r
+                       test_code_tmp = Gh3x2xDemoMp_PPGTest(&stTestParam.stPPG_TestParam, &stTestResult.stPPG_TestResult);\r
+                       if(!gh3x2x_mp_test_code) //Save the first NG error code\r
+                               gh3x2x_mp_test_code = test_code_tmp;\r
+                       if(test_code_tmp && (NG_CONTINUE != stGh3x2xMpTestItemsSatus.PPG_TEST))\r
+                               break;\r
+               }\r
+               \r
+               //ECGTest\r
+               if(stGh3x2xMpTestItemsSatus.ECG_TEST)\r
+               {\r
+                       test_code_tmp = Gh3x2xDemoMp_ECGTest(&stTestParam.stECG_TestParam, &stTestResult.stECG_TestResult);\r
+                       if(!gh3x2x_mp_test_code) //Save the first NG error code\r
+                               gh3x2x_mp_test_code = test_code_tmp;\r
+                       if(test_code_tmp && (NG_CONTINUE != stGh3x2xMpTestItemsSatus.ECG_TEST))\r
+                               break;\r
+               }\r
+               \r
+       }while(0);\r
+       \r
+       GH3X2X_MP_LOG_L2("Gh3x2x mp end! \r\n");\r
+       \r
+       if(!gh3x2x_mp_test_code)\r
+       {\r
+               //test ok,OK light comes on\r
+               GU8 prompt_msg[] = GH3X2X_MP_TEST_OK_MSG;\r
+               gh3x2x_mp_prompt_message(prompt_msg, sizeof(prompt_msg) / sizeof(GU8));\r
+               GH3X2X_MP_LOG_L2("\r\n ************************************************************ \r\n");\r
+               GH3X2X_MP_LOG_L2("\r\n Gh3x2x mp test is OK! \r\n");\r
+               GH3X2X_MP_LOG_L2("\r\n ************************************************************ \r\n");\r
+       }\r
+       else\r
+       {\r
+               //test NG,NG light comes on\r
+               GU8 prompt_msg[] = GH3X2X_MP_TEST_NG_MSG;\r
+               gh3x2x_mp_prompt_message(prompt_msg, sizeof(prompt_msg) / sizeof(GU8));\r
+               GH3X2X_MP_LOG_L2("\r\n ************************************************************ \r\n");\r
+               GH3X2X_MP_LOG_L2("\r\n Gh3x2x mp test is NG, error code is: %d!\r\n", gh3x2x_mp_test_code);\r
+               GH3X2X_MP_LOG_L2("\r\n ************************************************************ \r\n");\r
+       }\r
+       \r
+       if(__GH3X2X_MP_PRINT_TEST_RESULT__)\r
+               Gh3x2xDemoMp_PrintTestResult(&stTestParam, &stTestResult);\r
+       \r
+       return gh3x2x_mp_test_code;\r
+}\r
+\r
+/**\r
+ * @fn     void Gh3x2xDemoMp_SetTestParam_PPG(stGh3x2xMp_TestParam *stTestParam)\r
+ *\r
+ * @brief  GH3x2x MP set PPG test items param\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   stGh3x2xMp_PPGTestParam *stPPG_TestParam\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void Gh3x2xDemoMp_SetTestParam_PPG(stGh3x2xMp_PPGTestParam *stPPG_TestParam)\r
+{\r
+       GU8 i = 0;\r
+       GU8 j = 0;\r
+       GH3X2X_MP_LOG_L2("Gh3x2x mp start set ppg test param! \r\n");\r
+       \r
+       //CTR test slot config\r
+       memset(&stPPG_TestParam->stCTRSlotConfig, 0, sizeof(stGh3x2xMp_SlotConfig));\r
+       stPPG_TestParam->stCTRSlotConfig.Slot_Mutiple = 9;\r
+       stPPG_TestParam->stCTRSlotConfig.TIA_RF = 0;\r
+       stPPG_TestParam->stCTRSlotConfig.TIA_CF = 0;\r
+       stPPG_TestParam->stCTRSlotConfig.ADC_N = 5;\r
+       stPPG_TestParam->stCTRSlotConfig.ADC_IntTimes = stPPG_TestParam->stCTRSlotConfig.ADC_N;\r
+       stPPG_TestParam->stCTRSlotConfig.BG_Level = 2;\r
+       stPPG_TestParam->stCTRSlotConfig.LED_ACG = 0;\r
+       stPPG_TestParam->stCTRSlotConfig.LED_Drv = 51;\r
+       stPPG_TestParam->stCTRSlotConfig.Slot_TMR = 985;\r
+       stPPG_TestParam->stCTRSlotConfig.Slot_Mode = SLOT_MULTICH_MODE;\r
+       \r
+       //Noise test slot config\r
+       memset(&stPPG_TestParam->stNoiseSlotConfig, 0, sizeof(stGh3x2xMp_SlotConfig));\r
+       stPPG_TestParam->stNoiseSlotConfig.Slot_Mutiple = 9;\r
+       stPPG_TestParam->stNoiseSlotConfig.TIA_RF = 4;\r
+       stPPG_TestParam->stNoiseSlotConfig.TIA_CF = 0;\r
+       stPPG_TestParam->stNoiseSlotConfig.ADC_N = 5;\r
+       stPPG_TestParam->stNoiseSlotConfig.ADC_IntTimes = stPPG_TestParam->stNoiseSlotConfig.ADC_N;\r
+       stPPG_TestParam->stNoiseSlotConfig.BG_Level = 1;\r
+       stPPG_TestParam->stNoiseSlotConfig.LED_ACG = 3;\r
+       stPPG_TestParam->stNoiseSlotConfig.LED_Drv = 0;\r
+       stPPG_TestParam->stNoiseSlotConfig.Slot_TMR = 985;\r
+       stPPG_TestParam->stNoiseSlotConfig.Slot_Mode = SLOT_ONECH_MODE; //Single channel mode is required when using automatic dimming\r
+       \r
+       //BaseNoise test slot config\r
+       memset(&stPPG_TestParam->stBaseNoiseSlotConfig, 0, sizeof(stGh3x2xMp_SlotConfig));\r
+       stPPG_TestParam->stBaseNoiseSlotConfig.Slot_Mutiple = 9;\r
+       stPPG_TestParam->stBaseNoiseSlotConfig.TIA_RF = 4;\r
+       stPPG_TestParam->stBaseNoiseSlotConfig.TIA_CF = 0;\r
+       stPPG_TestParam->stBaseNoiseSlotConfig.ADC_N = 6;\r
+       stPPG_TestParam->stBaseNoiseSlotConfig.ADC_IntTimes = stPPG_TestParam->stBaseNoiseSlotConfig.ADC_N;\r
+       stPPG_TestParam->stBaseNoiseSlotConfig.BG_Level = 0;\r
+       stPPG_TestParam->stBaseNoiseSlotConfig.LED_ACG = 0;\r
+       stPPG_TestParam->stBaseNoiseSlotConfig.LED_Drv = 0;\r
+       stPPG_TestParam->stBaseNoiseSlotConfig.Slot_TMR = 985;\r
+       stPPG_TestParam->stBaseNoiseSlotConfig.Slot_Mode = SLOT_MULTICH_MODE;\r
+       \r
+       //LeakLight test slot config\r
+       memset(&stPPG_TestParam->stLeakLightSlotConfig, 0, sizeof(stGh3x2xMp_SlotConfig));\r
+       stPPG_TestParam->stLeakLightSlotConfig.Slot_Mutiple = 9;\r
+       stPPG_TestParam->stLeakLightSlotConfig.TIA_RF = 4;\r
+       stPPG_TestParam->stLeakLightSlotConfig.TIA_CF = 0;\r
+       stPPG_TestParam->stLeakLightSlotConfig.ADC_N = 5;\r
+       stPPG_TestParam->stLeakLightSlotConfig.ADC_IntTimes = stPPG_TestParam->stLeakLightSlotConfig.ADC_N;\r
+       stPPG_TestParam->stLeakLightSlotConfig.BG_Level = 2;\r
+       stPPG_TestParam->stLeakLightSlotConfig.LED_ACG = 0;\r
+       stPPG_TestParam->stLeakLightSlotConfig.LED_Drv = 51;\r
+       stPPG_TestParam->stLeakLightSlotConfig.Slot_TMR = 985;\r
+       stPPG_TestParam->stLeakLightSlotConfig.Slot_Mode = SLOT_MULTICH_MODE;\r
+       \r
+       //get rawdata num\r
+       stPPG_TestParam->PPG_CTRRawdata_Num = 100; //not more than MAX_PPG_RAWDATA_SAMPLE_NUM\r
+       stPPG_TestParam->PPG_NoiseRawdata_Num = 100; //not more than MAX_PPG_RAWDATA_SAMPLE_NUM\r
+       stPPG_TestParam->PPG_BaseNoiseRawdata_Num = 100; //not more than MAX_PPG_RAWDATA_SAMPLE_NUM\r
+       stPPG_TestParam->PPG_LeakLightRawdata_Num = 20; //not more than MAX_PPG_RAWDATA_SAMPLE_NUM\r
+       stPPG_TestParam->PPG_CTRRawdata_SkipNum = 0;\r
+       stPPG_TestParam->PPG_NoiseRawdata_SkipNum = 100;\r
+       stPPG_TestParam->PPG_BaseNoiseRawdata_SkipNum = 0;\r
+       stPPG_TestParam->PPG_LeakLightRawdata_SkipNum = 0;\r
+       \r
+       //LEDPDConfig\r
+       memset(stPPG_TestParam->stLEDPDConfig.PD_Channel, 0, sizeof(stPPG_TestParam->stLEDPDConfig.PD_Channel));\r
+    memset(stPPG_TestParam->stLEDPDConfig.PD_Num, 0, sizeof(stPPG_TestParam->stLEDPDConfig.PD_Channel));\r
+       stPPG_TestParam->stLEDPDConfig.PD_Channel_AllSlot = 0;\r
+       stPPG_TestParam->stLEDPDConfig.PD_Num_AllSlot = 0;\r
+       stPPG_TestParam->stLEDPDConfig.LED_PD_Num = 0;\r
+       stPPG_TestParam->stLEDPDConfig.LED_Channel = 0;\r
+       stPPG_TestParam->stLEDPDConfig.LED_Num = 0;\r
+       for (i = 0; i < MAX_LED_NUM; i++)\r
+    {\r
+        for (j = 0; j < MAX_ADC_NUM; j++)\r
+        {\r
+            if (PPG_LEDPD_EN[i][j])\r
+            {\r
+                stPPG_TestParam->stLEDPDConfig.PD_Channel[i] |= 1 << j;\r
+                stPPG_TestParam->stLEDPDConfig.PD_Num[i]++;\r
+                stPPG_TestParam->stLEDPDConfig.LED_Channel |= 1 << i;\r
+                stPPG_TestParam->stLEDPDConfig.LED_PD_Num++;\r
+            }\r
+        }\r
+        stPPG_TestParam->stLEDPDConfig.PD_Channel_AllSlot |= stPPG_TestParam->stLEDPDConfig.PD_Channel[i];\r
+    }\r
+    for (i = 0; i < MAX_LED_NUM; i++)\r
+    {\r
+        if (stPPG_TestParam->stLEDPDConfig.PD_Channel_AllSlot & (1 << i))\r
+                       stPPG_TestParam->stLEDPDConfig.PD_Num_AllSlot++;\r
+        if (stPPG_TestParam->stLEDPDConfig.LED_Channel & (1 << i))\r
+                       stPPG_TestParam->stLEDPDConfig.LED_Num++;\r
+    }\r
+\r
+}\r
+\r
+/**\r
+ * @fn     void Gh3x2xDemoMp_SetTestParam_ECG(stGh3x2xMp_ECGTestParam *stECG_TestParam)\r
+ *\r
+ * @brief  GH3x2x MP set ECG test items param\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   stGh3x2xMp_ECGTestParam *stECG_TestParam\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void Gh3x2xDemoMp_SetTestParam_ECG(stGh3x2xMp_ECGTestParam *stECG_TestParam)\r
+{\r
+       GH3X2X_MP_LOG_L2("Gh3x2x mp start set ecg test param! \r\n");\r
+       \r
+       //ecg signal num\r
+       stECG_TestParam->HPF_ECGSignalNum = 2;\r
+       stECG_TestParam->SIGNAL_ECGSignalNum = 3;\r
+       stECG_TestParam->CMRR_ECGSignalNum = 1;\r
+       stECG_TestParam->LIN_ECGSignalNum = 2;\r
+       stECG_TestParam->DCRange_ECGSignalNum = 3;\r
+       \r
+       //LeadOnOff param set\r
+       stECG_TestParam->stECGSignal_LeadOnOff.Rawdata_Num = 1000;\r
+       stECG_TestParam->stECGSignal_LeadOnOff.Rawdata_SkipNum = 100;\r
+       \r
+       //Noise param set\r
+       stECG_TestParam->stECGSignal_Noise.Rawdata_Num = 1000; //need >= 600\r
+       stECG_TestParam->stECGSignal_Noise.Rawdata_SkipNum = 500;\r
+       \r
+       //HPF0 signal param set\r
+       stECG_TestParam->stECGSignal_HPF[0].Rawdata_Num = 200; //num need >= 200\r
+       stECG_TestParam->stECGSignal_HPF[0].Rawdata_SkipNum = 0;\r
+       stECG_TestParam->stECGSignal_HPF[0].bECG_NegativeSignal = 0;\r
+       stECG_TestParam->stECGSignal_HPF[0].bECG_HighImpedance = 0;\r
+       stECG_TestParam->stECGSignal_HPF[0].ECG_SignalType = NONE_MODE;\r
+       stECG_TestParam->stECGSignal_HPF[0].ECG_Freq = 0;\r
+       stECG_TestParam->stECGSignal_HPF[0].ECG_Vol = 0;\r
+       stECG_TestParam->stECGSignal_HPF[0].ECG_ACOffset = 57;\r
+       stECG_TestParam->stECGSignal_HPF[0].ECG_DCOffset = 810;\r
+       //HPF1 signal param set\r
+       stECG_TestParam->stECGSignal_HPF[1].Rawdata_Num = 200; //num need >= 200\r
+       stECG_TestParam->stECGSignal_HPF[1].Rawdata_SkipNum = 0;\r
+       stECG_TestParam->stECGSignal_HPF[1].bECG_NegativeSignal = 0;\r
+       stECG_TestParam->stECGSignal_HPF[1].bECG_HighImpedance = 0;\r
+       stECG_TestParam->stECGSignal_HPF[1].ECG_SignalType = NONE_MODE;\r
+       stECG_TestParam->stECGSignal_HPF[1].ECG_Freq = 0;\r
+       stECG_TestParam->stECGSignal_HPF[1].ECG_Vol = 0;\r
+       stECG_TestParam->stECGSignal_HPF[1].ECG_ACOffset = 57;\r
+       stECG_TestParam->stECGSignal_HPF[1].ECG_DCOffset = 860;\r
+       \r
+       //SIGNAL TEST signal0 param set\r
+       stECG_TestParam->stECGSignal_SIGNAL[0].Rawdata_Num = 2048;\r
+       stECG_TestParam->stECGSignal_SIGNAL[0].Rawdata_SkipNum = 300;\r
+       stECG_TestParam->stECGSignal_SIGNAL[0].Sampling_Step = 4; //must > 0\r
+       stECG_TestParam->stECGSignal_SIGNAL[0].bECG_NegativeSignal = 0;\r
+       stECG_TestParam->stECGSignal_SIGNAL[0].bECG_HighImpedance = 0;\r
+       stECG_TestParam->stECGSignal_SIGNAL[0].ECG_SignalType = AC_MODE;\r
+       stECG_TestParam->stECGSignal_SIGNAL[0].ECG_Freq = 5;\r
+       stECG_TestParam->stECGSignal_SIGNAL[0].ECG_Vol = 57;\r
+       stECG_TestParam->stECGSignal_SIGNAL[0].ECG_ACOffset = 57;\r
+       stECG_TestParam->stECGSignal_SIGNAL[0].ECG_DCOffset = 815;\r
+       //SIGNAL TEST signal1 param set\r
+       stECG_TestParam->stECGSignal_SIGNAL[1].Rawdata_Num = 14336;\r
+       stECG_TestParam->stECGSignal_SIGNAL[1].Rawdata_SkipNum = 300;\r
+       stECG_TestParam->stECGSignal_SIGNAL[1].Sampling_Step = 4; //must > 0\r
+       stECG_TestParam->stECGSignal_SIGNAL[1].bECG_NegativeSignal = 0;\r
+       stECG_TestParam->stECGSignal_SIGNAL[1].bECG_HighImpedance = 0;\r
+       stECG_TestParam->stECGSignal_SIGNAL[1].ECG_SignalType = AC_MODE;\r
+       stECG_TestParam->stECGSignal_SIGNAL[1].ECG_Freq = 0.67;\r
+       stECG_TestParam->stECGSignal_SIGNAL[1].ECG_Vol = 57;\r
+       stECG_TestParam->stECGSignal_SIGNAL[1].ECG_ACOffset = 57;\r
+       stECG_TestParam->stECGSignal_SIGNAL[1].ECG_DCOffset = 815;\r
+       //SIGNAL TEST signal2 param set\r
+       stECG_TestParam->stECGSignal_SIGNAL[2].Rawdata_Num = 512;\r
+       stECG_TestParam->stECGSignal_SIGNAL[2].Rawdata_SkipNum = 300;\r
+       stECG_TestParam->stECGSignal_SIGNAL[2].Sampling_Step = 1; //must > 0\r
+       stECG_TestParam->stECGSignal_SIGNAL[2].bECG_NegativeSignal = 0;\r
+       stECG_TestParam->stECGSignal_SIGNAL[2].bECG_HighImpedance = 0;\r
+       stECG_TestParam->stECGSignal_SIGNAL[2].ECG_SignalType = AC_MODE;\r
+       stECG_TestParam->stECGSignal_SIGNAL[2].ECG_Freq = 40;\r
+       stECG_TestParam->stECGSignal_SIGNAL[2].ECG_Vol = 57;\r
+       stECG_TestParam->stECGSignal_SIGNAL[2].ECG_ACOffset = 57;\r
+       stECG_TestParam->stECGSignal_SIGNAL[2].ECG_DCOffset = 815;\r
+       \r
+       //RLD param set\r
+       stECG_TestParam->stECGSignal_RLD.Rawdata_Num = 100;\r
+       stECG_TestParam->stECGSignal_RLD.Rawdata_SkipNum = 0;\r
+       \r
+       //CMRR0 signal param set\r
+       stECG_TestParam->stECGSignal_CMRR[0].Rawdata_Num = 712; //need >= 200\r
+       stECG_TestParam->stECGSignal_CMRR[0].Rawdata_SkipNum = 300;\r
+       stECG_TestParam->stECGSignal_CMRR[0].bECG_NegativeSignal = 1;\r
+       stECG_TestParam->stECGSignal_CMRR[0].bECG_HighImpedance = 0;\r
+       stECG_TestParam->stECGSignal_CMRR[0].ECG_SignalType = AC_MODE;\r
+       stECG_TestParam->stECGSignal_CMRR[0].ECG_Freq = 50;\r
+       stECG_TestParam->stECGSignal_CMRR[0].ECG_Vol = 1000;\r
+       stECG_TestParam->stECGSignal_CMRR[0].ECG_ACOffset = 410;\r
+       stECG_TestParam->stECGSignal_CMRR[0].ECG_DCOffset = 10;\r
+       \r
+       //LIN0 signal param set\r
+       stECG_TestParam->stECGSignal_LIN[0].Rawdata_Num = 512;\r
+       stECG_TestParam->stECGSignal_LIN[0].Rawdata_SkipNum = 300;\r
+       stECG_TestParam->stECGSignal_LIN[0].bECG_NegativeSignal = 0;\r
+       stECG_TestParam->stECGSignal_LIN[0].bECG_HighImpedance = 0;\r
+       stECG_TestParam->stECGSignal_LIN[0].ECG_SignalType = AC_MODE;\r
+       stECG_TestParam->stECGSignal_LIN[0].ECG_Freq = 5;\r
+       stECG_TestParam->stECGSignal_LIN[0].ECG_Vol = 285;\r
+       stECG_TestParam->stECGSignal_LIN[0].ECG_ACOffset = 57;\r
+       stECG_TestParam->stECGSignal_LIN[0].ECG_DCOffset = 835;\r
+       //LIN1 signal param set\r
+       stECG_TestParam->stECGSignal_LIN[1].Rawdata_Num = 512;\r
+       stECG_TestParam->stECGSignal_LIN[1].Rawdata_SkipNum = 300;\r
+       stECG_TestParam->stECGSignal_LIN[1].bECG_NegativeSignal = 0;\r
+       stECG_TestParam->stECGSignal_LIN[1].bECG_HighImpedance = 0;\r
+       stECG_TestParam->stECGSignal_LIN[1].ECG_SignalType = AC_MODE;\r
+       stECG_TestParam->stECGSignal_LIN[1].ECG_Freq = 5;\r
+       stECG_TestParam->stECGSignal_LIN[1].ECG_Vol = 285;\r
+       stECG_TestParam->stECGSignal_LIN[1].ECG_ACOffset = 57;\r
+       stECG_TestParam->stECGSignal_LIN[1].ECG_DCOffset = 835;\r
+       \r
+       //DCRange0 signal param set\r
+       stECG_TestParam->stECGSignal_DCRange[0].Rawdata_Num = 500;\r
+       stECG_TestParam->stECGSignal_DCRange[0].Rawdata_SkipNum = 500;\r
+       stECG_TestParam->stECGSignal_DCRange[0].bECG_NegativeSignal = 0;\r
+       stECG_TestParam->stECGSignal_DCRange[0].bECG_HighImpedance = 0;\r
+       stECG_TestParam->stECGSignal_DCRange[0].ECG_SignalType = ANG_MODE;\r
+       stECG_TestParam->stECGSignal_DCRange[0].ECG_Freq = 10.4;\r
+       stECG_TestParam->stECGSignal_DCRange[0].ECG_Vol = 57;\r
+       stECG_TestParam->stECGSignal_DCRange[0].ECG_ACOffset = 57;\r
+       stECG_TestParam->stECGSignal_DCRange[0].ECG_DCOffset = 815;\r
+       //DCRange1 signal param set\r
+       stECG_TestParam->stECGSignal_DCRange[1].Rawdata_Num = 500;\r
+       stECG_TestParam->stECGSignal_DCRange[1].Rawdata_SkipNum = 500;\r
+       stECG_TestParam->stECGSignal_DCRange[1].bECG_NegativeSignal = 0;\r
+       stECG_TestParam->stECGSignal_DCRange[1].bECG_HighImpedance = 0;\r
+       stECG_TestParam->stECGSignal_DCRange[1].ECG_SignalType = ANG_MODE;\r
+       stECG_TestParam->stECGSignal_DCRange[1].ECG_Freq = 10.4;\r
+       stECG_TestParam->stECGSignal_DCRange[1].ECG_Vol = 57;\r
+       stECG_TestParam->stECGSignal_DCRange[1].ECG_ACOffset = 57;\r
+       stECG_TestParam->stECGSignal_DCRange[1].ECG_DCOffset = 315;\r
+       //DCRange2 signal param set\r
+       stECG_TestParam->stECGSignal_DCRange[2].Rawdata_Num = 500;\r
+       stECG_TestParam->stECGSignal_DCRange[2].Rawdata_SkipNum = 500;\r
+       stECG_TestParam->stECGSignal_DCRange[2].bECG_NegativeSignal = 0;\r
+       stECG_TestParam->stECGSignal_DCRange[2].bECG_HighImpedance = 0;\r
+       stECG_TestParam->stECGSignal_DCRange[2].ECG_SignalType = ANG_MODE;\r
+       stECG_TestParam->stECGSignal_DCRange[2].ECG_Freq = 10.4;\r
+       stECG_TestParam->stECGSignal_DCRange[2].ECG_Vol = 57;\r
+       stECG_TestParam->stECGSignal_DCRange[2].ECG_ACOffset = 57;\r
+       stECG_TestParam->stECGSignal_DCRange[2].ECG_DCOffset = 1315;\r
+       \r
+\r
+}\r
+\r
+/**\r
+ * @fn     GU8 Gh3x2xDemoMp_SetTestParam(stGh3x2xMp_TestParam *stTestParam)\r
+ *\r
+ * @brief  GH3x2x MP set all test items param.\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   stGh3x2xMp_TestParam *stTestParam\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void Gh3x2xDemoMp_SetTestParam(stGh3x2xMp_TestParam *stTestParam)\r
+{\r
+       \r
+       Gh3x2xDemoMp_SetTestParam_PPG(&stTestParam->stPPG_TestParam);\r
+       Gh3x2xDemoMp_SetTestParam_ECG(&stTestParam->stECG_TestParam);\r
+       \r
+}\r
+\r
+/**\r
+ * @fn     void Gh3x2xDemoMp_PrintTestResult(stGh3x2xMp_TestParam *stTestParam, stGh3x2xMp_TestResult *stTestResult)\r
+ *\r
+ * @brief  GH3x2x mp print all test result\r
+ *\r
+ * @attention   It must be called after the test ends\r
+ *\r
+ * @param[in]   stGh3x2xMp_TestParam *stTestParam, stGh3x2xMp_TestResult *stTestResult\r
+ * @param[out]  None\r
+ *\r
+ * @return  none\r
+ */\r
+void Gh3x2xDemoMp_PrintTestResult(stGh3x2xMp_TestParam *stTestParam, stGh3x2xMp_TestResult *stTestResult)\r
+{\r
+       GU32 i = 0;\r
+       //GCHAR Gh3x2xDemoMp_TestResultLog[GH3X2X_MP_LOG_MAX_LEN] = {0};\r
+       GH3X2X_MP_LOG("\r\n *************************Start print Gh3x2x mp test all result info!*********************************** \r\n");\r
+       \r
+       //print efuse test result\r
+       if(stGh3x2xMpTestItemsSatus.EFUSE_TEST)\r
+       {\r
+               \r
+               GH3X2X_MP_LOG("\r\n *************************Start print chip uid*********************************** \r\n");\r
+               GH3X2X_MP_LOG("\r\n Gh3x2x mp efuse test result, chip uid is: ");\r
+               for(i = 0; i < CHIP_UID_LENGTH; i++)\r
+               {\r
+                       GH3X2X_MP_LOG("%02X \r\n", stTestResult->stEfuse_TestResult.uchChipUid[i]);\r
+               }\r
+               GH3X2X_MP_LOG("\r\n");\r
+               GH3X2X_MP_LOG("\r\n *************************End print chip uid*********************************** \r\n");\r
+       }\r
+       \r
+       //print ppg tset result\r
+       if(stGh3x2xMpTestItemsSatus.PPG_TEST)\r
+       {\r
+               GH3X2X_MP_LOG("\r\n *************************Start print ppg test result*********************************** \r\n");\r
+               if(stGh3x2xMpPPGItemsSatus.PPG_LPCTR_TEST)\r
+               {\r
+                       GH3X2X_MP_LOG("\r\n");\r
+                       for(i = 0; i < MAX_LED_NUM*MAX_ADC_NUM; i++)\r
+                       {\r
+                               GH3X2X_MP_LOG("LPCTR[%d]: %.5f, \r\n", i, stTestResult->stPPG_TestResult.LED_LPCTR[i]);\r
+                       }\r
+               }\r
+               \r
+               if(stGh3x2xMpPPGItemsSatus.PPG_NOISE_TEST)\r
+               {\r
+                       GH3X2X_MP_LOG("\r\n");\r
+                       for(i = 0; i < MAX_LED_NUM*MAX_ADC_NUM; i++)\r
+                       {\r
+                               GH3X2X_MP_LOG("Noise[%d]: %.5f, \r\n", i, stTestResult->stPPG_TestResult.LED_Noise[i]);\r
+                       }\r
+               }\r
+               \r
+               if(stGh3x2xMpPPGItemsSatus.PPG_BASENOISE_TEST)\r
+               {\r
+                       GH3X2X_MP_LOG("\r\n");\r
+                       for(i = 0; i < MAX_LED_NUM*MAX_ADC_NUM; i++)\r
+                       {\r
+                               GH3X2X_MP_LOG("BaseNoise[%d]: %.5f, \r\n", i, stTestResult->stPPG_TestResult.LED_BaseNoise[i]);\r
+                       }\r
+                       GH3X2X_MP_LOG("\r\n");\r
+                       for(i = 0; i < MAX_LED_NUM*MAX_ADC_NUM; i++)\r
+                       {\r
+                               GH3X2X_MP_LOG("DC_Offset[%d]: %.5f, \r\n", i, stTestResult->stPPG_TestResult.LED_DCOffset[i]);\r
+                       }\r
+               }\r
+               \r
+               if(stGh3x2xMpPPGItemsSatus.PPG_LEAKLIGHT_TEST)\r
+               {\r
+                       GH3X2X_MP_LOG("\r\n");\r
+                       for(i = 0; i < MAX_LED_NUM*MAX_ADC_NUM; i++)\r
+                       {\r
+                               GH3X2X_MP_LOG("LeakLight_CTR[%d]: %.5f, \r\n", i, stTestResult->stPPG_TestResult.LED_LLPCTR[i]);\r
+                       }\r
+                       GH3X2X_MP_LOG("\r\n");\r
+                       for(i = 0; i < MAX_LED_NUM*MAX_ADC_NUM; i++)\r
+                       {\r
+                               GH3X2X_MP_LOG("LeakLight_Ratio[%d]: %.5f, \r\n", i, stTestResult->stPPG_TestResult.LED_LeakRatio[i]);\r
+                       }\r
+               }\r
+               GH3X2X_MP_LOG("\r\n *************************End print ppg test result*********************************** \r\n");\r
+       }\r
+       \r
+       \r
+       \r
+       //print ppg tset result\r
+       if(stGh3x2xMpTestItemsSatus.ECG_TEST)\r
+       {\r
+               GH3X2X_MP_LOG("\r\n *************************Start print ecg test result*********************************** \r\n");\r
+               if(stGh3x2xMpECGItemsSatus.ECG_NOISE_TEST)\r
+               {\r
+                       GH3X2X_MP_LOG("\r\n");\r
+                       GH3X2X_MP_LOG("ECG_Noise: %.5f, \r\n", stTestResult->stECG_TestResult.ECG_Noise);\r
+               }\r
+               \r
+               if(stGh3x2xMpECGItemsSatus.ECG_HPF_TEST)\r
+               {\r
+                       if(stTestParam->stECG_TestParam.HPF_ECGSignalNum < ECG_MAX_SIGNAL_NUM)\r
+                       {\r
+                               GH3X2X_MP_LOG("\r\n");\r
+                               for(i = 0; i < stTestParam->stECG_TestParam.HPF_ECGSignalNum / 2; i++) //2 signals in a group, ratio is Calculate the latter one \r
+                               {\r
+                                       GH3X2X_MP_LOG("ECG_HPFRatio[%d]: %.5f, \r\n", i, stTestResult->stECG_TestResult.ECG_HPFRatio[i]);\r
+                               }               \r
+                       }\r
+               }\r
+               \r
+               if(stGh3x2xMpECGItemsSatus.ECG_SIGNAL_TEST)\r
+               {\r
+                       if(stTestParam->stECG_TestParam.SIGNAL_ECGSignalNum < ECG_MAX_SIGNAL_NUM)\r
+                       {\r
+                               GH3X2X_MP_LOG("\r\n");\r
+                               for(i = 0; i < stTestParam->stECG_TestParam.SIGNAL_ECGSignalNum; i++)\r
+                               {\r
+                                       GH3X2X_MP_LOG("ECG_SIGNAL_Amp[%d]: %.5fmV, \r\n", i, stTestResult->stECG_TestResult.ECG_Amp[i]);\r
+                               }\r
+                               GH3X2X_MP_LOG("\r\n");\r
+                               for(i = 0; i < stTestParam->stECG_TestParam.SIGNAL_ECGSignalNum; i++) \r
+                               {\r
+                                       GH3X2X_MP_LOG("ECG_SIGNAL_Freq[%d]: %.5fHz, \r\n", i, stTestResult->stECG_TestResult.ECG_Freq[i]);\r
+                               }\r
+                       }               \r
+               }\r
+               \r
+               if(stGh3x2xMpECGItemsSatus.ECG_RLD_TEST)\r
+               {\r
+                       GH3X2X_MP_LOG("\r\n");\r
+                       GH3X2X_MP_LOG("ECG_RLD_Amp: %.5fmV, \r\n", stTestResult->stECG_TestResult.ECG_RLD);\r
+               }\r
+               \r
+               if(stGh3x2xMpECGItemsSatus.ECG_CMRR_TEST)\r
+               {\r
+                       if(stTestParam->stECG_TestParam.CMRR_ECGSignalNum < ECG_MAX_SIGNAL_NUM)\r
+                       {\r
+                               GH3X2X_MP_LOG("\r\n");\r
+                               for(i = 0; i < stTestParam->stECG_TestParam.CMRR_ECGSignalNum; i++) \r
+                               {\r
+                                       GH3X2X_MP_LOG("ECG_CMRR[%d]: %.5f, \r\n", i, stTestResult->stECG_TestResult.ECG_CMRR[i]);\r
+                               }\r
+                       }               \r
+               }\r
+               \r
+               if(stGh3x2xMpECGItemsSatus.ECG_LIN_TEST)\r
+               {\r
+                       if(stTestParam->stECG_TestParam.LIN_ECGSignalNum < ECG_MAX_SIGNAL_NUM)\r
+                       {\r
+                               GH3X2X_MP_LOG("\r\n");\r
+                               for(i = 0; i < stTestParam->stECG_TestParam.LIN_ECGSignalNum / 2; i++) //2 signals in a group to cal one ratio\r
+                               {\r
+                                       GH3X2X_MP_LOG("ECG_LIN_Ratio[%d]: %.5f, \r\n", i, stTestResult->stECG_TestResult.ECG_LIN_Ratio[i]);\r
+                               }\r
+                       }\r
+               }\r
+               \r
+               if(stGh3x2xMpECGItemsSatus.ECG_DCRANGE_TEST)\r
+               {\r
+                       if(stTestParam->stECG_TestParam.DCRange_ECGSignalNum < ECG_MAX_SIGNAL_NUM)\r
+                       {\r
+                               GH3X2X_MP_LOG("\r\n");\r
+                               for(i = 0; i < stTestParam->stECG_TestParam.DCRange_ECGSignalNum; i++) //3 signals in a group to cal two ratio\r
+                               {\r
+                                       GH3X2X_MP_LOG("ECG_DCRange_Ratio[%d]: %.5f, \r\n", i, stTestResult->stECG_TestResult.ECG_DCRange_Ratio[i]);\r
+                               }\r
+                               GH3X2X_MP_LOG("\r\n");\r
+                               for(i = 0; i < stTestParam->stECG_TestParam.DCRange_ECGSignalNum; i++) //3 signals in a group to cal two ratio\r
+                               {\r
+                                       GH3X2X_MP_LOG("ECG_DCRange_Amp[%d]: %.5f, \r\n", i, stTestResult->stECG_TestResult.ECG_DCRange_Amp[i]);\r
+                               }\r
+                       }\r
+               }\r
+               GH3X2X_MP_LOG("\r\n *************************End print ecg test result*********************************** \r\n");\r
+       \r
+       }\r
+       \r
+       \r
+       \r
+       GH3X2X_MP_LOG("\r\n *************************End print Gh3x2x mp test all result info!*********************************** \r\n");\r
+}\r
+\r
+/**\r
+ * @fn     GU8 Gh3x2xDemoMp_CommunicationTest(GU8 *puchPara, GU8 *puchTestResult)\r
+ *\r
+ * @brief  GH3x2x MP Communication Test.\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   GU8 *puchPara, GU8 *pushTestResult\r
+ * @param[out]  None\r
+ *\r
+ * @return  error code\r
+ */\r
+GU8 Gh3x2xDemoMp_CommunicationTest(GU8 *puchPara, GU8 *puchTestResult)\r
+{\r
+    GU8 test_code = 0;\r
+       GU8 i = 0;\r
+       GU8 retry_time = 3;\r
+    GH3X2X_MP_LOG_L2("Gh3x2x mp Communication test start! \r\n");\r
+       \r
+       for(i = 0; i < retry_time; i++)\r
+       {\r
+               //tset before operation, chip resume\r
+               gh3x2x_demo_mp_send_cmd(GH3X2X_MP_CMD_RESUME);\r
+               gh3x2x_mp_delay_ms(5);\r
+               \r
+               //communication test\r
+               for(GU32 i = 0; i < sizeof(stGh3x2xMpRegConfigDefault) / sizeof(stGh3x2xMpRegConfigDefault[0]); i++)\r
+               {\r
+                       if(stGh3x2xMpRegConfigDefault[i].usRegAddr && (stGh3x2xMpRegConfigDefault[i].usRegAddr < 0x780))\r
+                       {\r
+                               gh3x2x_demo_mp_write_reg(stGh3x2xMpRegConfigDefault[i].usRegAddr, stGh3x2xMpRegConfigDefault[i].usRegValue);\r
+                               gh3x2x_mp_delay_ms(2);\r
+       \r
+                               if(stGh3x2xMpRegConfigDefault[i].usRegValue != gh3x2x_demo_mp_read_reg(stGh3x2xMpRegConfigDefault[i].usRegAddr))\r
+                               {\r
+                                       test_code = MT_ERROR_COMMUNICATION_TEST_ERROR;\r
+                                       GH3X2X_MP_LOG_L1("Gh3x2x mp Communication test fail, error code is: %d!\r\n", test_code);\r
+                                       break;\r
+                               }\r
+                       }\r
+               }\r
+               if(!test_code)\r
+               {\r
+                       GH3X2X_MP_LOG_L2("Gh3x2x mp Communication test is pass! \r\n");\r
+                       break;\r
+               }\r
+                       \r
+       }\r
+       if(i == retry_time)\r
+       {\r
+               test_code = MT_ERROR_COMMUNICATION_TEST_ERROR;\r
+               GH3X2X_MP_LOG_L1("Gh3x2x mp Communication test fail, error code is: %d!\r\n", test_code);\r
+       }\r
+\r
+       GH3X2X_MP_LOG_L2("Gh3x2x mp Communication test end! \r\n");\r
+       \r
+       return test_code;\r
+}\r
+\r
+/**\r
+ * @fn     GU8 Gh3x2xDemoMp_CheckChipIDTest(GU8 *puchPara, GU8 *puchTestResult)\r
+ *\r
+ * @brief  GH3x2x MP Check Chip ID Test.\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   GU8 *puchPara, GU8 *pushTestResult\r
+ * @param[out]  None\r
+ *\r
+ * @return  error code\r
+ */\r
+GU8 Gh3x2xDemoMp_CheckChipIDTest(GU8 *puchPara, GU8 *puchTestResult)\r
+{\r
+       GU8 test_code = 0;\r
+       GU8 i = 0;\r
+       GU8 retry_time = 3;\r
+       GH3X2X_MP_LOG_L2("Gh3x2x mp Check ChipID test start! \r\n");\r
+       \r
+       for(i = 0; i < retry_time; i++)\r
+       {\r
+               //need use drv interface to check, at present Only need to test this item when the driver is AFE\r
+       #if ( __GH3X2X_MP_USE_DRV_INTERFACE__ == __GH3X2X_DRV_MODE__ )\r
+               #if (__GH3X2X_MP_USE_DRV_INTERFACE_TYPE__ == __GH3X2X_DRV_LIB_INTERFACE__)\r
+                       //No need to do at the moment\r
+               #else //__GH3X2X_MP_USE_DRV_INTERFACE_TYPE__ == __GH3X2X_AFE_DRV_INTERFACE__\r
+               if(GH3X2X_CHIP_ID == GH3X2X_AFE_GetChipId())\r
+               {\r
+                       GH3X2X_MP_LOG_L2("Gh3x2x mp Check ChipID test is pass! \r\n");\r
+                       break;\r
+               }\r
+               else\r
+                       continue;\r
+               #endif\r
+       #endif\r
+               \r
+       }\r
+       if(i == retry_time)\r
+       {\r
+               test_code = MT_ERROR_CHECK_CHIPID_ERROR;\r
+               GH3X2X_MP_LOG_L1("Gh3x2x mp Check ChipID test fail--Chip ID error, error code is: %d!\r\n", test_code);\r
+       }\r
+       \r
+       \r
+       GH3X2X_MP_LOG_L2("Gh3x2x mp Check ChipID test end! \r\n");\r
+       \r
+       return test_code;\r
+       \r
+}\r
+\r
+/**\r
+ * @fn     GU8 Gh3x2xDemoMp_RstIntTest(GU8 *puchPara, GU8 *puchTestResult)\r
+ *\r
+ * @brief  GH3x2x MP Communication Test.\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   GU8 *puchPara, GU8 *pushTestResult\r
+ * @param[out]  None\r
+ *\r
+ * @return  error code\r
+ */\r
+GU8 Gh3x2xDemoMp_RstIntTest(GU8 *puchPara, GU8 *puchTestResult)\r
+{\r
+       GU8 test_code = 0;\r
+       GU8 i = 0;\r
+       GU8 retry_time = 3;\r
+       GU16 time_out = 200;\r
+       GH3X2X_MP_LOG_L2("Gh3x2x mp RST&INT test start! \r\n");\r
+       \r
+       for(i = 0; i < retry_time; i++)\r
+       {\r
+               //tset before operation, chip resume\r
+               gh3x2x_demo_mp_send_cmd(GH3X2X_MP_CMD_RESUME);\r
+               gh3x2x_mp_delay_ms(5);\r
+               \r
+               //rst gh3x2x,set low and set high later\r
+               gh3x2x_demo_mp_reset_operation();\r
+       \r
+               //wait int\r
+               if(gh3x2x_demo_mp_wait_for_int(0x4000, time_out))\r
+               {\r
+                       GH3X2X_MP_LOG_L2("Gh3x2x mp RST&INT test is pass! \r\n");\r
+                       break;\r
+               }\r
+       }\r
+       if(i == retry_time)\r
+       {\r
+               test_code = MT_ERROR_COMMUNICATION_TEST_ERROR;\r
+               GH3X2X_MP_LOG_L1("Gh3x2x mp RST&INT test fail, error code is: %d!\r\n", test_code);\r
+       }\r
+       \r
+       \r
+       GH3X2X_MP_LOG_L2("Gh3x2x mp RST&INT test end! \r\n");\r
+       \r
+       return test_code;\r
+       \r
+}\r
+\r
+/**\r
+ * @fn     GU8 Gh3x2xDemoMp_EfuseTest(GU8 *puchPara, stGh3x2xMp_EfuseTestResult *pstTestResult)\r
+ *\r
+ * @brief  GH3x2x MP efuse Test, check FT/CP and crc, and get chipUid\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   GU8 *puchPara, stGh3x2xMp_EfuseTestResult *pstTestResult\r
+ * @param[out]  None\r
+ *\r
+ * @return  error code\r
+ */\r
+GU8 Gh3x2xDemoMp_EfuseTest(GU8 *puchPara, stGh3x2xMp_EfuseTestResult *pstTestResult)\r
+{\r
+       GU8 test_code = 0;\r
+       GU8 retry_time = 3;\r
+       GU8 i = 0;\r
+       GU8 j = 0;\r
+       GU16 usTimeOut_ms = 0;\r
+       GH3X2X_MP_LOG_L2("Gh3x2x mp eFuse test start! \r\n");\r
+       \r
+       memset(pstTestResult->uchChipUid, 0, 12);\r
+       \r
+       //read efuse, check FT/CP and get chip uid\r
+       GU8 eFuse_data[GH3X2X_DEMO_MP_EFUSE_MAX_LEN] = {0};\r
+       GU16 eFuse_block[3] = {0x0030, 0x0034, 0x0038};\r
+       GU8 eFuseReadPass = 1;\r
+       for(i = 0; i < retry_time; i++)\r
+       {\r
+               eFuseReadPass = 1;\r
+               //tset before operation, chip resume\r
+               gh3x2x_demo_mp_send_cmd(GH3X2X_MP_CMD_RESUME);\r
+               gh3x2x_mp_delay_ms(5);\r
+               \r
+               gh3x2x_demo_mp_write_reg(0x700, 0x0020);\r
+               GU8 tmp_data[24] = {0};\r
+               for(j = 0; j < 3; j++)\r
+               {\r
+                       gh3x2x_demo_mp_write_reg(0x700, eFuse_block[j]);\r
+                       usTimeOut_ms = 200;\r
+                       while(usTimeOut_ms--)\r
+                       {\r
+                               if((gh3x2x_demo_mp_read_reg(0x718) & 0x0001))\r
+                                       break;\r
+                               gh3x2x_mp_delay_ms(1);\r
+                       }\r
+                       if(0 == usTimeOut_ms)\r
+                       {\r
+                               eFuseReadPass = 0;\r
+                               break;\r
+                       }\r
+                       memset(tmp_data, 0, 24);\r
+                       gh3x2x_demo_mp_read_regs(0x710, tmp_data, 8);\r
+                       for(GU16 k = 0; k < 4; k++)\r
+                       {\r
+                               eFuse_data[8*j + 2*k] = tmp_data[2*k + 1];\r
+                               eFuse_data[8*j + 2*k + 1] = tmp_data[2*k];\r
+                       }\r
+               }\r
+               if(!eFuseReadPass)\r
+                       continue;\r
+               \r
+               //check FT/CP\r
+               GU8 FT_Result = eFuse_data[23] & (0x0C >> 2);\r
+               GU8 CP_Result = eFuse_data[23] & 0x03;\r
+               if((0x01 == FT_Result) && (0x01 == CP_Result))\r
+               {\r
+                       GU8 FT_CRC = eFuse_data[7];\r
+                       GU8 CP_CRC = eFuse_data[11];            \r
+                       GU8 FT_CRC_Check[24] = {0};\r
+                       GU8 CP_CRC_Check[24] = {0};\r
+                       GH3X2X_Memcpy(&FT_CRC_Check[1], eFuse_data, 7);\r
+                       GH3X2X_Memcpy(&CP_CRC_Check[1], &eFuse_data[8], 3);\r
+                       FT_CRC_Check[0] = gh3x2x_mp_crc_cal(&FT_CRC_Check[1], 7); //cal FT crc\r
+                       CP_CRC_Check[0] = gh3x2x_mp_crc_cal(&CP_CRC_Check[1], 3); //cal CP crc\r
+                       \r
+                       if((FT_CRC != FT_CRC_Check[0]) || (CP_CRC != CP_CRC_Check[0]))\r
+                       {\r
+                               GH3X2X_MP_LOG_L1("Gh3x2x mp efuse test fail, FT or CP check crc error\r\n ");\r
+                       }\r
+                       else\r
+                       {\r
+                               GH3X2X_MP_LOG_L2("Gh3x2x mp eFuse test is pass! \r\n");\r
+                               break;\r
+                       }\r
+               }\r
+               else\r
+                       GH3X2X_MP_LOG_L1("Gh3x2x mp efuse test fail, FT or CP check result error\r\n ");\r
+       }\r
+       if(i == retry_time)\r
+       {\r
+               test_code = MT_ERROR_EFUSE_ERROR;\r
+               GH3X2X_MP_LOG_L1("Gh3x2x mp efuse test fail, error code is: %d!\r\n", test_code);\r
+       }\r
+       \r
+       //get chip uid\r
+       for(GU8 j = 0; j < 12; j++)\r
+       {\r
+               if(GH3X2X_DEMO_MP_EFUSE_MAX_LEN > 12)\r
+                       pstTestResult->uchChipUid[j] = eFuse_data[j];\r
+       }\r
+       \r
+       GH3X2X_MP_LOG_L2("Gh3x2x mp eFuse test end! \r\n");\r
+       return test_code;\r
+}\r
+\r
+/**\r
+ * @fn     GU8 Gh3x2xDemoMp_PPGTest(stGh3x2xMp_PPGTestParam *pstTestPara, stGh3x2xMp_PPGTestResult *pstTestResult)\r
+ *\r
+ * @brief  GH3x2x MP PPG Test\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   stGh3x2xMp_PPGTestParam *pstTestPara, stGh3x2xMp_PPGTestResult *pstTestResult\r
+ * @param[out]  None\r
+ *\r
+ * @return  error code\r
+ */\r
+GU8 Gh3x2xDemoMp_PPGTest(stGh3x2xMp_PPGTestParam *pstTestPara, stGh3x2xMp_PPGTestResult *pstTestResult)\r
+{\r
+       GU8 test_code = 0; //Save the first NG error code\r
+       GU8 test_code_tmp = 0;\r
+       GU8 retry_times = 3;\r
+       GU8 i = 0;\r
+       GH3X2X_MP_LOG_L2("Gh3x2x mp PPG test start! \r\n");\r
+       \r
+       //init pstTestResult\r
+       for(i = 0; i < (MAX_LED_NUM*MAX_ADC_NUM); i++)\r
+       {\r
+               pstTestResult->LED_BaseNoise[i] = 0.0;\r
+               pstTestResult->LED_Noise[i] = 0.0;\r
+               pstTestResult->LED_LPCTR[i] = 0.0;\r
+               pstTestResult->LED_DCOffset[i] = 0.0;\r
+               pstTestResult->LED_LLPCTR[i] = 0.0;\r
+               pstTestResult->LED_LeakRatio[i] = 0.0;\r
+       }\r
+       memset(&pstTestResult->stCTRRawHandleResult, 0, sizeof(stGh3x2xMp_RawdataHandleResult));\r
+       memset(&pstTestResult->stNoiseRawHandleResult, 0, sizeof(stGh3x2xMp_RawdataHandleResult));\r
+       memset(&pstTestResult->stBaseNoiseRawHandleResult, 0, sizeof(stGh3x2xMp_RawdataHandleResult));\r
+       memset(&pstTestResult->stLeakLightRawHandleResult, 0, sizeof(stGh3x2xMp_RawdataHandleResult));\r
+       \r
+       //power on led,\r
+       gh3x2x_mp_led_power_on();\r
+       \r
+       do\r
+       {\r
+               //LP_CTR test\r
+               if(stGh3x2xMpPPGItemsSatus.PPG_LPCTR_TEST)\r
+               {\r
+                       for(i = 0; i < retry_times; i++)\r
+                       {\r
+                               test_code_tmp = gh3x2x_demo_mp_PPG_LPCTR_Test(pstTestPara, pstTestResult);\r
+                               if(!test_code_tmp)\r
+                                       break;\r
+                               else\r
+                                       GH3X2X_MP_LOG_L2("Gh3x2x mp PPG-CTR test retry:%d !\r\n", i+1);\r
+                       }\r
+                       if(!test_code) //Save the first NG error code\r
+                               test_code = test_code_tmp;\r
+                       if((i == retry_times) && (NG_CONTINUE != stGh3x2xMpPPGItemsSatus.PPG_LPCTR_TEST))\r
+                               break;\r
+               }\r
+               //Noise test\r
+               if(stGh3x2xMpPPGItemsSatus.PPG_NOISE_TEST)\r
+               {\r
+                       for(i = 0; i < retry_times; i++)\r
+                       {\r
+                               test_code_tmp = gh3x2x_demo_mp_PPG_Noise_Test(pstTestPara, pstTestResult);\r
+                               if(!test_code_tmp)\r
+                                       break;\r
+                               else\r
+                                       GH3X2X_MP_LOG_L2("Gh3x2x mp PPG-Noise test retry:%d !\r\n", i+1);\r
+                       }\r
+                       if(!test_code) //Save the first NG error code\r
+                               test_code = test_code_tmp;\r
+                       if((i == retry_times) && (NG_CONTINUE != stGh3x2xMpPPGItemsSatus.PPG_NOISE_TEST))\r
+                               break;\r
+               }\r
+               //Base_Noise test\r
+               if(stGh3x2xMpPPGItemsSatus.PPG_BASENOISE_TEST)\r
+               {\r
+                       for(i = 0; i < retry_times; i++)\r
+                       {\r
+                               test_code_tmp = gh3x2x_demo_mp_PPG_BaseNoise_Test(pstTestPara, pstTestResult);\r
+                               if(!test_code_tmp)\r
+                                       break;\r
+                               else\r
+                                       GH3X2X_MP_LOG_L2("Gh3x2x mp PPG-BaseNoise test retry:%d !\r\n", i+1);\r
+                       }\r
+                       if(!test_code) //Save the first NG error code\r
+                               test_code = test_code_tmp;\r
+                       if((i == retry_times) && (NG_CONTINUE != stGh3x2xMpPPGItemsSatus.PPG_BASENOISE_TEST))\r
+                               break;\r
+               }\r
+               //LeakLight test\r
+               if(stGh3x2xMpPPGItemsSatus.PPG_LEAKLIGHT_TEST)\r
+               {\r
+                       for(i = 0; i < retry_times; i++)\r
+                       {\r
+                               test_code_tmp = gh3x2x_demo_mp_PPG_LeakLight_Test(pstTestPara, pstTestResult);\r
+                               if(!test_code_tmp)\r
+                                       break;\r
+                               else\r
+                                       GH3X2X_MP_LOG_L2("Gh3x2x mp PPG-LeakLight test retry:%d !\r\n", i+1);\r
+                       }\r
+                       if(!test_code) //Save the first NG error code\r
+                               test_code = test_code_tmp;\r
+                       if((i == retry_times) && (NG_CONTINUE != stGh3x2xMpPPGItemsSatus.PPG_LEAKLIGHT_TEST))\r
+                               break;\r
+               }\r
+               \r
+       }while(0);\r
+       \r
+       //power off led\r
+       gh3x2x_mp_led_power_off();\r
+       \r
+       GH3X2X_MP_LOG_L2("Gh3x2x mp PPG test end! \r\n");\r
+       return test_code;\r
+}\r
+\r
+/**\r
+ * @fn     GU8 Gh3x2xDemoMp_ECGTest(stGh3x2xMp_ECGTestParam *pstTestPara, stGh3x2xMp_ECGTestResult *pstTestResult)\r
+ *\r
+ * @brief  GH3x2x MP ECG Test\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   stGh3x2xMp_ECGTestParam *pstTestPara, stGh3x2xMp_ECGTestResult *pstTestResult\r
+ * @param[out]  None\r
+ *\r
+ * @return  error code\r
+ */\r
+GU8 Gh3x2xDemoMp_ECGTest(stGh3x2xMp_ECGTestParam *pstTestPara, stGh3x2xMp_ECGTestResult *pstTestResult)\r
+{\r
+       GU8 test_code = 0; //Save the first NG error code\r
+       GU8 test_code_tmp = 0;\r
+       GU8 retry_times = 3;\r
+       GU8 i = 0;\r
+       GH3X2X_MP_LOG_L2("Gh3x2x mp ECG test start! \r\n");\r
+       \r
+       //init pstTestResult\r
+       pstTestResult->ECG_Noise = 0;\r
+       pstTestResult->ECG_RLD = 0;\r
+       for(i = 0; i < ECG_MAX_SIGNAL_NUM; i++)\r
+       {\r
+               pstTestResult->ECG_HPFRatio[i] = 0;\r
+               pstTestResult->ECG_Amp[i] = 0;\r
+               pstTestResult->ECG_CMRR[i] = 0;\r
+               pstTestResult->ECG_DCRange_Amp[i] = 0;\r
+               pstTestResult->ECG_DCRange_Ratio[i] = 0;\r
+               pstTestResult->ECG_Freq[i] = 0;\r
+               pstTestResult->ECG_LIN_Ratio[i] = 0;\r
+       }\r
+       \r
+       //rst gh3x2x,set low and set high later\r
+       gh3x2x_demo_mp_reset_operation();\r
+       \r
+       do\r
+       {\r
+               //Lead on/off test\r
+               if(stGh3x2xMpECGItemsSatus.ECG_LEADONOFF_TEST)\r
+               {\r
+                       for(i = 0; i < retry_times; i++)\r
+                       {\r
+                               test_code_tmp = gh3x2x_demo_mp_ECG_LeadOnOff_Test(pstTestPara, pstTestResult);\r
+                               if(!test_code_tmp)\r
+                                       break;\r
+                               else\r
+                                       GH3X2X_MP_LOG_L2("Gh3x2x mp ECG-LeadOnOff test retry:%d !\r\n", i+1);\r
+                       }\r
+                       if(!test_code) //Save the first NG error code\r
+                               test_code = test_code_tmp;\r
+                       if((i == retry_times) && (NG_CONTINUE != stGh3x2xMpECGItemsSatus.ECG_LEADONOFF_TEST))\r
+                               break;\r
+               }\r
+               //Noise test\r
+               if(stGh3x2xMpECGItemsSatus.ECG_NOISE_TEST)\r
+               {\r
+                       for(i = 0; i < retry_times; i++)\r
+                       {\r
+                               test_code_tmp = gh3x2x_demo_mp_ECG_Noise_Test(pstTestPara, pstTestResult);\r
+                               if(!test_code_tmp)\r
+                                       break;\r
+                               else\r
+                                       GH3X2X_MP_LOG_L2("Gh3x2x mp ECG-Noise test retry:%d !\r\n", i+1);\r
+                       }\r
+                       if(!test_code) //Save the first NG error code\r
+                               test_code = test_code_tmp;\r
+                       if((i == retry_times) && (NG_CONTINUE != stGh3x2xMpECGItemsSatus.ECG_NOISE_TEST))\r
+                               break;\r
+               }\r
+               //HPF test\r
+               if(stGh3x2xMpECGItemsSatus.ECG_HPF_TEST)\r
+               {\r
+                       for(i = 0; i < retry_times; i++)\r
+                       {\r
+                               test_code_tmp = gh3x2x_demo_mp_ECG_HPF_Test(pstTestPara, pstTestResult);\r
+                               if(!test_code_tmp)\r
+                                       break;\r
+                               else\r
+                                       GH3X2X_MP_LOG_L2("Gh3x2x mp ECG-HPF test retry:%d !\r\n", i+1);\r
+                       }\r
+                       if(!test_code) //Save the first NG error code\r
+                               test_code = test_code_tmp;\r
+                       if((i == retry_times) && (NG_CONTINUE != stGh3x2xMpECGItemsSatus.ECG_HPF_TEST))\r
+                               break;\r
+               }\r
+               //SIGNAL test\r
+               if(stGh3x2xMpECGItemsSatus.ECG_SIGNAL_TEST)\r
+               {\r
+                       for(i = 0; i < retry_times; i++)\r
+                       {\r
+                               test_code_tmp = gh3x2x_demo_mp_ECG_SIGNAL_Test(pstTestPara, pstTestResult);\r
+                               if(!test_code_tmp)\r
+                                       break;\r
+                               else\r
+                                       GH3X2X_MP_LOG_L2("Gh3x2x mp ECG-SIGNAL test retry:%d !\r\n", i+1);\r
+                       }\r
+                       if(!test_code) //Save the first NG error code\r
+                               test_code = test_code_tmp;\r
+                       if((i == retry_times) && (NG_CONTINUE != stGh3x2xMpECGItemsSatus.ECG_SIGNAL_TEST))\r
+                               break;\r
+               }\r
+               //RLD test\r
+               if(stGh3x2xMpECGItemsSatus.ECG_RLD_TEST)\r
+               {\r
+                       for(i = 0; i < retry_times; i++)\r
+                       {\r
+                               test_code_tmp = gh3x2x_demo_mp_ECG_RLD_Test(pstTestPara, pstTestResult);\r
+                               if(!test_code_tmp)\r
+                                       break;\r
+                               else\r
+                                       GH3X2X_MP_LOG_L2("Gh3x2x mp ECG-RLD test retry:%d !\r\n", i+1);\r
+                       }\r
+                       if(!test_code) //Save the first NG error code\r
+                               test_code = test_code_tmp;\r
+                       if((i == retry_times) && (NG_CONTINUE != stGh3x2xMpECGItemsSatus.ECG_RLD_TEST))\r
+                               break;\r
+               }\r
+               //CMRR test\r
+               if(stGh3x2xMpECGItemsSatus.ECG_CMRR_TEST)\r
+               {\r
+                       for(i = 0; i < retry_times; i++)\r
+                       {\r
+                               test_code_tmp = gh3x2x_demo_mp_ECG_CMRR_Test(pstTestPara, pstTestResult);\r
+                               if(!test_code_tmp)\r
+                                       break;\r
+                               else\r
+                                       GH3X2X_MP_LOG_L2("Gh3x2x mp ECG-CMRR test retry:%d !\r\n", i+1);\r
+                       }\r
+                       if(!test_code) //Save the first NG error code\r
+                               test_code = test_code_tmp;\r
+                       if((i == retry_times) && (NG_CONTINUE != stGh3x2xMpECGItemsSatus.ECG_CMRR_TEST))\r
+                               break;\r
+               }\r
+               //LIN test\r
+               if(stGh3x2xMpECGItemsSatus.ECG_LIN_TEST)\r
+               {\r
+                       for(i = 0; i < retry_times; i++)\r
+                       {\r
+                               test_code_tmp = gh3x2x_demo_mp_ECG_LIN_Test(pstTestPara, pstTestResult);\r
+                               if(!test_code_tmp)\r
+                                       break;\r
+                               else\r
+                                       GH3X2X_MP_LOG_L2("Gh3x2x mp ECG-LIN test retry:%d !\r\n", i+1);\r
+                       }\r
+                       if(!test_code) //Save the first NG error code\r
+                               test_code = test_code_tmp;\r
+                       if((i == retry_times) && (NG_CONTINUE != stGh3x2xMpECGItemsSatus.ECG_LIN_TEST))\r
+                               break;\r
+               }\r
+               //DC_Range test\r
+               if(stGh3x2xMpECGItemsSatus.ECG_DCRANGE_TEST)\r
+               {\r
+                       for(i = 0; i < retry_times; i++)\r
+                       {\r
+                               test_code_tmp = gh3x2x_demo_mp_ECG_DCRange_Test(pstTestPara, pstTestResult);\r
+                               if(!test_code_tmp)\r
+                                       break;\r
+                               else\r
+                                       GH3X2X_MP_LOG_L2("Gh3x2x mp ECG-DCRange test retry:%d !\r\n", i+1);\r
+                       }\r
+                       if(!test_code) //Save the first NG error code\r
+                               test_code = test_code_tmp;\r
+                       if((i == retry_times) && (NG_CONTINUE != stGh3x2xMpECGItemsSatus.ECG_DCRANGE_TEST))\r
+                               break;\r
+               }\r
+\r
+               \r
+       }while(0);\r
+       \r
+       \r
+       GH3X2X_MP_LOG_L2("Gh3x2x mp ECG test end! \r\n");\r
+       return test_code;\r
+}\r
+\r
+/********END OF FILE********* Copyright (c) 2003 - 2022, Goodix Co., Ltd. ********/\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_mp_code/src/gh3x2x_demo_mp_process.c b/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_mp_code/src/gh3x2x_demo_mp_process.c
new file mode 100644 (file)
index 0000000..13ddf80
--- /dev/null
@@ -0,0 +1,2852 @@
+/**\r
+ * @copyright (c) 2003 - 2022, Goodix Co., Ltd. All rights reserved.\r
+ * \r
+ * @file    gh3x2x_demo_mp_process.c\r
+ * \r
+ * @brief   process function of mp test\r
+ * \r
+ * @author  Goodix Product Tools Development Team\r
+ * \r
+ */\r
+\r
+#include <stdio.h>\r
+#include <string.h>\r
+#include <math.h>\r
+#include "gh3x2x_demo_mp_process.h"\r
+#include "gh3x2x_mp_common.h"\r
+#include "gh3x2x_mp_algorithm.h"\r
+#include "gh3x2x_mp_param_config.h"\r
+\r
+#if ( __GH3X2X_MP_USE_DRV_INTERFACE__ == __GH3X2X_DRV_MODE__ )\r
+       #if (__GH3X2X_MP_USE_DRV_INTERFACE_TYPE__ == __GH3X2X_DRV_LIB_INTERFACE__)\r
+               #include "gh_drv.h"\r
+       #else //__GH3X2X_MP_USE_DRV_INTERFACE_TYPE__ == __GH3X2X_AFE_DRV_INTERFACE__\r
+               #include "gh3x2x_afe_drv.h"\r
+       #endif\r
+#endif\r
+\r
+\r
+GU8 GH3x2xMp_IntFlag = 0;  //int event flag\r
+\r
+GS32 GH3x2xMp_RawdataHandleArr[MAX_RAWDATA_SAMPLE_NUM] = {0};\r
+GU8 GH3x2xMp_RawdataBuf[RAWDATA_BUF_SIZE] = {0};\r
+GF32 *fArrHandle_Temp = NULL;\r
+\r
+GU32 Tia_Switch(GU32 tia)\r
+{\r
+       switch (tia)\r
+       {\r
+       case 0:\r
+               return 10 ;\r
+       case 1:\r
+               return 25 ;\r
+       case 2:\r
+               return 50 ;\r
+       case 3:\r
+               return 75 ;\r
+       case 4:\r
+               return 100 ;\r
+       case 5:\r
+               return 250 ;\r
+       case 6:\r
+               return 500 ;\r
+       case 7:\r
+               return 750 ;\r
+       case 8:\r
+               return 1000;\r
+       case 9:\r
+               return 1250 ;\r
+       case 10:\r
+               return 1500 ;\r
+       case 11:\r
+               return 1750 ;\r
+       case 12:\r
+               return 2000 ;\r
+\r
+       default:\r
+               return 1;\r
+       }\r
+}\r
+\r
+\r
+/**\r
+ * @fn     gh3x2x_demo_mp_write_reg(GU16 usReg_Addr, GU16 usReg_Value)\r
+ *\r
+ * @brief  GH3x2x mp write reg\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   GU16 usReg_Addr, GU16 usReg_Value\r
+ * @param[out]  None\r
+ *\r
+ * @return  ret\r
+ */\r
+GU8 gh3x2x_demo_mp_write_reg(GU16 usReg_Addr, GU16 usReg_Value)\r
+{\r
+       GU8 ret = 1;\r
+\r
+       \r
+       #if(__GH3X2X_MP_USE_DRV_INTERFACE__)\r
+               #if (__GH3X2X_MP_USE_DRV_INTERFACE_TYPE__ == __GH3X2X_DRV_LIB_INTERFACE__)\r
+                       GH3X2X_WriteReg(usReg_Addr, usReg_Value);\r
+               #else //__GH3X2X_MP_USE_DRV_INTERFACE_TYPE__ == __GH3X2X_AFE_DRV_INTERFACE__\r
+                       GH3X2X_AFE_WRITE_REG(usReg_Addr, usReg_Value);\r
+               #endif\r
+               \r
+       #else //__GH3X2X_MP_USE_DRV_INTERFACE__ == 0, use mp lib interface\r
+               GU8 uchBuffArr[4] = {0};\r
+               uchBuffArr[0] = usReg_Addr >> 8;\r
+               uchBuffArr[1] = usReg_Addr & 0xFF;\r
+               uchBuffArr[2] = usReg_Value & 0xFF;\r
+               uchBuffArr[3] = usReg_Value >> 8;\r
+               #if ( __GH3X2X_MP_INTERFACE__ == __GH3X2X_INTERFACE_I2C__ )\r
+                       gh3x2x_mp_i2c_write(device_id, uchBuffArr, 4);\r
+               #else //__GH3X2X_INTERFACE__ == __GH3X2X_INTERFACE_SPI__\r
+                       gh3x2x_mp_spi_write(uchBuffArr, 4);\r
+               #endif\r
+       #endif\r
+       \r
+       return ret;\r
+}\r
+\r
+/**\r
+ * @fn     GU16 gh3x2x_demo_mp_read_reg(GU16 usReg_Addr)\r
+ *\r
+ * @brief  GH3x2x mp read reg\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   GU16 usReg_Addr\r
+ * @param[out]  None\r
+ *\r
+ * @return  read reg value\r
+ */\r
+GU16 gh3x2x_demo_mp_read_reg(GU16 usReg_Addr)\r
+{\r
+       GU16 usRegData = 0;\r
+       \r
+       #if(__GH3X2X_MP_USE_DRV_INTERFACE__)\r
+               #if (__GH3X2X_MP_USE_DRV_INTERFACE_TYPE__ == __GH3X2X_DRV_LIB_INTERFACE__)\r
+                       usRegData = GH3X2X_ReadReg(usReg_Addr);\r
+               #else //__GH3X2X_MP_USE_DRV_INTERFACE_TYPE__ == __GH3X2X_AFE_DRV_INTERFACE__\r
+                       usRegData = GH3X2X_AFE_READ_REG(usReg_Addr);\r
+               #endif\r
+       #else //__GH3X2X_MP_USE_DRV_INTERFACE__ == 0, use mp lib interface\r
+               GU8 uchCmdBuffArr[2] = {0};\r
+               GU8 uchReadBuffArr[2] = {0};\r
+               \r
+               uchCmdBuffArr[0] = usReg_Addr >> 8;\r
+               uchCmdBuffArr[1] = usReg_Addr & 0xFF;\r
+       \r
+               #if ( __GH3X2X_MP_INTERFACE__ == __GH3X2X_INTERFACE_I2C__ )\r
+                       gh3x2x_mp_i2c_read(device_id, uchCmdBuffArr, 2,  uchReadBuffArr, 2);\r
+               #else //__GH3X2X_INTERFACE__ == __GH3X2X_INTERFACE_SPI__\r
+                       gh3x2x_mp_spi_read(uchCmdBuffArr, 2,  uchReadBuffArr, 2);\r
+               #endif\r
+               usRegData = (uchReadBuffArr[0] << 8) + uchReadBuffArr[1];\r
+       #endif\r
+       \r
+       return usRegData;\r
+}\r
+\r
+/**\r
+ * @fn    GU8 gh3x2x_demo_mp_read_regs(GU16 usReg_Addr, GU8 uchRegs_Read[], GU16 usLength)\r
+ *\r
+ * @brief  GH3x2x mp read regs\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   GU16 usReg_Addr, GU16 usLength\r
+ * @param[out]  GU8 uchRegs_Read[]\r
+ *\r
+ * @return  ret\r
+ */\r
+GU8 gh3x2x_demo_mp_read_regs(GU16 usReg_Addr, GU8 uchRegs_Read[], GU16 usLength)\r
+{\r
+       GU8 ret = 1;\r
+       \r
+       #if(__GH3X2X_MP_USE_DRV_INTERFACE__)\r
+               GU16 length_temp = usLength / 2;\r
+               \r
+               #if (__GH3X2X_MP_USE_DRV_INTERFACE_TYPE__ == __GH3X2X_DRV_LIB_INTERFACE__)\r
+                       GH3X2X_ReadRegs(usReg_Addr, (GU16 *)uchRegs_Read, length_temp);\r
+               #else //__GH3X2X_MP_USE_DRV_INTERFACE_TYPE__ == __GH3X2X_AFE_DRV_INTERFACE__\r
+                       GH3X2X_AFE_READ_REGS(usReg_Addr, (GU16 *)uchRegs_Read, length_temp);\r
+               #endif\r
+               for(GU16 i = 0; i < length_temp; i++)\r
+               {\r
+                       GU8 swap_val = uchRegs_Read[2*i];\r
+                       uchRegs_Read[2*i] = uchRegs_Read[2*i + 1];\r
+                       uchRegs_Read[2*i + 1] = swap_val;\r
+               }\r
+       #else //__GH3X2X_MP_USE_DRV_INTERFACE__ == 0, use mp lib interface\r
+               GU8 uchCmdBuffArr[2] = {0};\r
+       \r
+               uchCmdBuffArr[0] = usReg_Addr >> 8;\r
+               uchCmdBuffArr[1] = usReg_Addr & 0xFF;\r
+               #if ( __GH3X2X_MP_INTERFACE__ == __GH3X2X_INTERFACE_I2C__ )\r
+                       gh3x2x_mp_i2c_read(uchCmdBuffArr, 2,  uchReadBuffArr, 2);\r
+               #else //__GH3X2X_INTERFACE__ == __GH3X2X_INTERFACE_SPI__\r
+                       gh3x2x_mp_spi_read(uchCmdBuffArr, 2,  uchRegs_Read, usLength);\r
+               #endif\r
+       #endif\r
+       \r
+       \r
+       return ret;\r
+}\r
+\r
+/**\r
+ * @fn     GU8 gh3x2x_demo_mp_write_reg_mask(GU16 usRegAddr, GU16 usMask, GU16 usRegVal)\r
+ *\r
+ * @brief  GH3x2x mp write reg mask\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   GU16 usReg_Addr\r
+ * @param[out]  None\r
+ *\r
+ * @return  ret\r
+ */\r
+GU8 gh3x2x_demo_mp_write_reg_mask(GU16 usRegAddr, GU16 usMask, GU16 usRegVal)\r
+{\r
+       GU8 ret = 1;\r
+    \r
+       GU16 temp_val = gh3x2x_demo_mp_read_reg(usRegAddr);\r
+       \r
+       //temp_val |= 0x0602;//no sleep\r
+       temp_val &= ~usMask;\r
+       temp_val |= usRegVal & usMask;\r
+       \r
+       gh3x2x_demo_mp_write_reg(usRegAddr, temp_val);\r
+\r
+    return ret;\r
+}\r
+\r
+/**\r
+ * @fn     void gh3x2x_demo_mp_send_cmd(GU8 uchCmd)\r
+ *\r
+ * @brief  send cmd to gh3x2x chip\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   GU8 uchCmd\r
+ * @param[out]  None\r
+ *\r
+ * @return  ret\r
+ */\r
+void gh3x2x_demo_mp_send_cmd(GU8 uchCmd)\r
+{\r
+       #if(__GH3X2X_MP_USE_DRV_INTERFACE__)\r
+               #if (__GH3X2X_MP_USE_DRV_INTERFACE_TYPE__ == __GH3X2X_DRV_LIB_INTERFACE__)\r
+                       GH3X2X_SendCmd(uchCmd);\r
+               #else //__GH3X2X_MP_USE_DRV_INTERFACE_TYPE__ == __GH3X2X_AFE_DRV_INTERFACE__\r
+                       GH3X2X_AFE_SEND_CMD(uchCmd);\r
+               #endif\r
+       #else //__GH3X2X_MP_USE_DRV_INTERFACE__ == 0, use mp lib interface\r
+               #if ( __GH3X2X_MP_INTERFACE__ == __GH3X2X_INTERFACE_I2C__ )\r
+                       gh3x2x_mp_i2c_send_cmd(device_id, uchCmd);\r
+               #else //__GH3X2X_INTERFACE__ == __GH3X2X_INTERFACE_SPI__\r
+                       gh3x2x_mp_spi_send_cmd(uchCmd);\r
+               #endif\r
+       #endif\r
+}\r
+\r
+/**\r
+ * @fn     void gh3x2x_demo_mp_reset_operation(void)\r
+ *\r
+ * @brief  reset gh3x2x chip\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void gh3x2x_demo_mp_reset_operation(void)\r
+{\r
+       //rst gh3x2x,set low and set high later\r
+       #if ( __GH3X2X_MP_USE_DRV_INTERFACE__ == __GH3X2X_DRV_MODE__ )\r
+               #if (__GH3X2X_MP_USE_DRV_INTERFACE_TYPE__ == __GH3X2X_DRV_LIB_INTERFACE__)\r
+                       #if __SUPPORT_HARD_RESET_CONFIG__\r
+                               GH3X2X_HardReset();\r
+                       #else\r
+                               GH3X2X_SoftReset();\r
+                       #endif\r
+               #else //__GH3X2X_MP_USE_DRV_INTERFACE_TYPE__ == __GH3X2X_AFE_DRV_INTERFACE__\r
+                       GH3X2X_AFE_Reset();\r
+               #endif\r
+       \r
+       #else   \r
+               gh3x2x_mp_reset_pin_ctrl(0);\r
+               gh3x2x_mp_delay_ms(5);\r
+               gh3x2x_mp_reset_pin_ctrl(1);\r
+       #endif\r
+       \r
+       gh3x2x_mp_delay_ms(10); //must delay\r
+}\r
+\r
+/**\r
+ * @fn    GU8 gh3x2x_demo_mp_wait_for_int(GU16 usDutFlag, GU16 usTimeOut_ms)\r
+ *\r
+ * @brief  wait for int \r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   GU16 usDutFlag, GU16 usTimeOut\r
+ * @param[out]  none\r
+ *\r
+ * @return  ret\r
+ */\r
+GU8 gh3x2x_demo_mp_wait_for_int(GU16 usDutFlag, GU16 usTimeOut_ms)\r
+{\r
+       GU8 ret = 1;\r
+       GU32 time_count = 0;\r
+       usTimeOut_ms *= 100;\r
+       GH3x2xMp_IntFlag = 0;\r
+       \r
+       while(time_count++ < usTimeOut_ms)\r
+       {\r
+               gh3x2x_mp_delay_us(10);\r
+               if(GH3x2xMp_IntFlag)\r
+               {\r
+                       GH3x2xMp_IntFlag = 0;\r
+                       //clear int\r
+                       GU16 temp_read_val = gh3x2x_demo_mp_read_reg(0x508);\r
+                       gh3x2x_demo_mp_write_reg(0x508, temp_read_val);\r
+                       \r
+                       if(usDutFlag & temp_read_val)\r
+                       {\r
+                               return ret;\r
+                       }\r
+               }\r
+       }\r
+       \r
+       ret = 0;\r
+       GH3X2X_MP_LOG_L1("Gh3x2x mp no interruption!\r\n ");\r
+       return ret;\r
+}\r
+\r
+/**\r
+ * @fn     GU8 gh3x2x_demo_mp_set_chip_config(const stGh3x2xReg stGh3x2xMpRegConfig[], GU16 usConfigLen)\r
+ *\r
+ * @brief  GH3x2x mp write chip reg config\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   const stGh3x2xReg stGh3x2xMpRegConfig[], GU16 usConfigLen\r
+ * @param[out]  None\r
+ *\r
+ * @return  ret\r
+ */\r
+GU8 gh3x2x_demo_mp_set_chip_config(const stGh3x2xReg stGh3x2xMpRegConfig[], GU16 usConfigLen)\r
+{\r
+       GU8 ret = 1;\r
+       GU8 retry_times = 3;\r
+       GU8 i = 0;\r
+       GU8 isWriteNormal = 1;\r
+       \r
+       for(i = 0; i < retry_times; i++)\r
+       {\r
+               isWriteNormal = 1;\r
+               for(GU32 j = 0; j < usConfigLen; j++)\r
+               {\r
+                       if((0 == stGh3x2xMpRegConfig[j].usRegAddr) && (0 == stGh3x2xMpRegConfig[j].usRegValue))\r
+                               continue;\r
+                       \r
+                       gh3x2x_demo_mp_write_reg(stGh3x2xMpRegConfig[j].usRegAddr, stGh3x2xMpRegConfig[j].usRegValue);\r
+                       \r
+                       if(stGh3x2xMpRegConfig[j].usRegValue != gh3x2x_demo_mp_read_reg(stGh3x2xMpRegConfig[j].usRegAddr))\r
+                       {\r
+                               isWriteNormal = 0;\r
+                               break;\r
+                       }\r
+               }\r
+               if(isWriteNormal)\r
+               {\r
+                       break;\r
+               }\r
+       }\r
+       if(i == retry_times)\r
+       {\r
+               GH3X2X_MP_LOG_L1("Gh3x2x mp set chip reg config fail! \r\n ");\r
+               ret = 0;\r
+       }\r
+       \r
+       \r
+       return ret;\r
+}\r
+\r
+/**\r
+ * @fn     GU8 gh3x2x_demo_mp_set_slot_config(stGh3x2xMp_SlotConfig stSlotConfig)\r
+ *\r
+ * @brief  GH3x2x mp set slot config\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   stGh3x2xMp_SlotConfig stSlotConfig\r
+ * @param[out]  None\r
+ *\r
+ * @return  ret\r
+ */\r
+GU8 gh3x2x_demo_mp_set_slot_config(stGh3x2xMp_SlotConfig stSlotConfig)\r
+{\r
+       GU8 ret = 1;\r
+       GU8 index = 0;\r
+       GU16 i = 0;\r
+       stGh3x2xReg stCofigRegArr[20] = {0};\r
+       \r
+       if(SLOT_ONECH_MODE == stSlotConfig.Slot_Mode)\r
+       {\r
+               //Slot_cfgN refresh cycle is the system (sr_multiplier+1) times, RxN (ADCN) channel is enabled, data is written into FIFO\r
+               stCofigRegArr[index].usRegAddr = 0x010A + SLOT_CFG_INDEX*stSlotConfig.Slot_Cfg_N;\r
+               stCofigRegArr[index++].usRegValue = 0x0040 | (stSlotConfig.Slot_Mutiple << 8) | (1 << (stSlotConfig.ADC_N + 2));\r
+               \r
+               //Clear all ADC channel connections\r
+               stCofigRegArr[index].usRegAddr = 0x010C + SLOT_CFG_INDEX*stSlotConfig.Slot_Cfg_N;\r
+        stCofigRegArr[index++].usRegValue = 0x0000;\r
+               \r
+               stCofigRegArr[index].usRegAddr = 0x010E + SLOT_CFG_INDEX*stSlotConfig.Slot_Cfg_N;\r
+        stCofigRegArr[index++].usRegValue = 0x0000;\r
+               \r
+               //ADC_N is mapped to PD_N, only one PD channel can be opened at a time\r
+               stCofigRegArr[index].usRegAddr = 0x010C + SLOT_CFG_INDEX*stSlotConfig.Slot_Cfg_N + (stSlotConfig.ADC_N / 2) * 2;\r
+        stCofigRegArr[index++].usRegValue = stSlotConfig.PD_N << ((stSlotConfig.ADC_N % 2) * 8);\r
+        \r
+               //slot_cfgN ADCN TIA gain is TIA_RF\r
+               stCofigRegArr[index].usRegAddr = 0x0112 + SLOT_CFG_INDEX*stSlotConfig.Slot_Cfg_N;\r
+               stCofigRegArr[index++].usRegValue = (stSlotConfig.TIA_RF & 0x0F) << (stSlotConfig.ADC_N * 4);\r
+        \r
+               //slot_cfgN ADCN TIA capacitance is TIA_CF\r
+               stCofigRegArr[index].usRegAddr = 0x0114 + SLOT_CFG_INDEX*stSlotConfig.Slot_Cfg_N;\r
+               stCofigRegArr[index++].usRegValue = (stSlotConfig.TIA_CF & 0x0F) << (stSlotConfig.ADC_N * 4);\r
+       }\r
+       else //SLOT_MULTICH_MODE\r
+       {\r
+               //Slot_cfgN refresh cycle is the system (sr_multiplier+1) times, PDN (RxN) channel is enabled, data is written into FIFO\r
+               stCofigRegArr[index].usRegAddr = 0x010A + SLOT_CFG_INDEX*stSlotConfig.Slot_Cfg_N;\r
+               stCofigRegArr[index++].usRegValue = 0x0040 | (stSlotConfig.Slot_Mutiple << 8) | (stSlotConfig.PD_N << 2);\r
+        \r
+               //Set ADC and PD one-to-one correspondence connection, ADCx is connected to PDx\r
+               stCofigRegArr[index].usRegAddr = 0x010C + SLOT_CFG_INDEX*stSlotConfig.Slot_Cfg_N;\r
+               stCofigRegArr[index++].usRegValue = 0x0201;\r
+               \r
+               stCofigRegArr[index].usRegAddr = 0x010E + SLOT_CFG_INDEX*stSlotConfig.Slot_Cfg_N;\r
+        stCofigRegArr[index++].usRegValue = 0x0804;\r
+               \r
+               GU16 temp = 0;\r
+        for (temp = 0, i = 0; i < MAX_ADC_NUM; i++) \r
+                       temp |= stSlotConfig.TIA_RF << (4 * i);\r
+               //slot_cfgN ADCN TIA gain is TIA_RF\r
+               stCofigRegArr[index].usRegAddr = 0x0112 + SLOT_CFG_INDEX*stSlotConfig.Slot_Cfg_N;\r
+               stCofigRegArr[index++].usRegValue = temp;\r
+               \r
+        for (temp = 0, i = 0; i < MAX_ADC_NUM; i++) \r
+                       temp |= stSlotConfig.TIA_CF << (4 * i);\r
+               //slot_cfgN ADCN TIA capacitance is TIA_CF\r
+               stCofigRegArr[index].usRegAddr = 0x0114 + SLOT_CFG_INDEX*stSlotConfig.Slot_Cfg_N;\r
+               stCofigRegArr[index++].usRegValue = temp;\r
+       }\r
+       \r
+       //ADC integration times is ADC_int, bg suppression is bg_level, automatically dimming LED_ACG, turning off DC cancel and BG cancel\r
+       stCofigRegArr[index].usRegAddr = 0x0110 + SLOT_CFG_INDEX*stSlotConfig.Slot_Cfg_N;\r
+       stCofigRegArr[index++].usRegValue = (stSlotConfig.LED_ACG << 8) | (stSlotConfig.ADC_N << 6) | (stSlotConfig.BG_Level << 4) | stSlotConfig.ADC_IntTimes;\r
+    \r
+       //LED DRV0 current is 0, not mapped to led\r
+       stCofigRegArr[index].usRegAddr = 0x011E + SLOT_CFG_INDEX*stSlotConfig.Slot_Cfg_N;\r
+       stCofigRegArr[index++].usRegValue = 0x0400;\r
+       \r
+       //LED DRV1 current is 0, not mapped to led\r
+       stCofigRegArr[index].usRegAddr = 0x0120 + SLOT_CFG_INDEX*stSlotConfig.Slot_Cfg_N;\r
+    stCofigRegArr[index++].usRegValue = 0x0400; \r
+       \r
+       //LEDN current is LED_DRV\r
+       stCofigRegArr[index].usRegAddr = 0x011E + SLOT_CFG_INDEX*stSlotConfig.Slot_Cfg_N + (stSlotConfig.LED_N / 4) * 2;\r
+    stCofigRegArr[index++].usRegValue = ((stSlotConfig.LED_N % 4) << 8) | stSlotConfig.LED_Drv;\r
+    \r
+       //slot running time\r
+       stCofigRegArr[index].usRegAddr = 0x01EC + 2 * stSlotConfig.Slot_Cfg_N;\r
+       stCofigRegArr[index++].usRegValue = stSlotConfig.Slot_TMR;\r
+       \r
+       ret = gh3x2x_demo_mp_set_chip_config(stCofigRegArr, index);\r
+       \r
+       return ret;\r
+}\r
+\r
+/**\r
+ * @fn     GU8 gh3x2x_demo_mp_set_slot_enable(GU8 uchSlotConfigEnable)\r
+ *\r
+ * @brief  Calculate which slots need to be enabled according to SLOT_CFG_EN, \r
+ * @brief  enable the corresponding slot, and output the number of enabled slots\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   GU8 uchSlotConfigEnable\r
+ * @param[out]  GU8 uchSlotEnableNum\r
+ *\r
+ * @return  ret\r
+ */\r
+GU8 gh3x2x_demo_mp_set_slot_enable(GU8 uchSlotConfigEnable, GU8 *uchSlotEnableNum)\r
+{\r
+       GU8 ret = 1;\r
+       GU16 i = 0;\r
+       GU8 index = 0;\r
+       GU8 SlotMap[MAX_SLOT_NUM];\r
+       stGh3x2xReg stCofigRegArr[20] = {0};\r
+       \r
+       memset(SlotMap, 0x08, MAX_SLOT_NUM); //init close all slot\r
+       \r
+       for (i = 0; i < MAX_SLOT_NUM; i++)\r
+    {\r
+               //Enable the corresponding slot according to the value of SLOT_CFG_EN\r
+        if (uchSlotConfigEnable & (1 << i)) \r
+                       SlotMap[(*uchSlotEnableNum)++] = i;\r
+    }\r
+       \r
+       for (i = 0; i < MAX_SLOT_NUM / 2; i++)\r
+       {\r
+               //set slot_index\r
+               stCofigRegArr[index].usRegAddr = 0x0100 + i * 2;\r
+               stCofigRegArr[index++].usRegValue = ((SlotMap[1 + 2 * i] & 0x0F) << 8) | (SlotMap[0 + 2 * i] & 0x0F);\r
+       }\r
+       //slot_cfg enable\r
+       stCofigRegArr[index].usRegAddr = 0x0108;\r
+    stCofigRegArr[index++].usRegValue = uchSlotConfigEnable;\r
+       \r
+       if(!gh3x2x_demo_mp_set_chip_config(stCofigRegArr, index))\r
+       {\r
+               ret = 0;\r
+               GH3X2X_MP_LOG_L1("Gh3x2x mp set chip reg config fail! \r\n ");\r
+       }\r
+       \r
+       return ret;\r
+       \r
+}\r
+\r
+/**\r
+ * @fn     GU8 gh3x2x_demo_mp_set_LED_ACG_cfg(GU8 uchLED_N, GU8 uchLED_ACG_FS, stGh3x2xMp_PPGTestParam *pstTestPara)\r
+ *\r
+ * @brief  The automatic dimming test needs to adjust the LED driver gear to avoid the failure of the automatic dimming step by too large\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   GU8 uchSlotConfigEnable\r
+ * @param[out]  GU8 *uchSlotEnableNum\r
+ *\r
+ * @return  ret\r
+ */\r
+GU8 gh3x2x_demo_mp_set_LED_ACG_cfg(GU8 uchLED_N, GU8 uchLED_ACG_FS, stGh3x2xMp_PPGTestParam *pstTestPara)\r
+{\r
+       GU8 ret = 1;\r
+       GU8 fs_temp = uchLED_ACG_FS & 0x03;//LED_ACG_FS range is 0~3\r
+    stGh3x2xReg stCofigRegArr[20] = { 0 };\r
+    int index = 0;\r
+       \r
+    if (uchLED_N < 4)\r
+       {\r
+               stCofigRegArr[index].usRegAddr = 0x0692;\r
+        stCofigRegArr[index++].usRegValue = 0x0202 | (fs_temp << 4);\r
+       }\r
+    else\r
+       {\r
+               stCofigRegArr[index].usRegAddr = 0x0692;\r
+        stCofigRegArr[index++].usRegValue = 0x0220 | fs_temp ;\r
+       }\r
+       \r
+       //mixdata trigger down dimming threshold\r
+       stCofigRegArr[index].usRegAddr = 0x0282;\r
+    stCofigRegArr[index++].usRegValue = stGh3x2xPPG_AutoDimming.LED_Max_Rawdata;\r
+       \r
+       //rawdata triggers the upward dimming threshold\r
+       stCofigRegArr[index].usRegAddr = 0x0284;\r
+    stCofigRegArr[index++].usRegValue = stGh3x2xPPG_AutoDimming.LED_Min_Rawdata;\r
+       \r
+       //Dimming end upper threshold\r
+       stCofigRegArr[index].usRegAddr = 0x0286;\r
+    stCofigRegArr[index++].usRegValue = stGh3x2xPPG_AutoDimming.LED_Ref_Up;\r
+       \r
+       //Lower threshold of dimming end\r
+       stCofigRegArr[index].usRegAddr = 0x0288;\r
+    stCofigRegArr[index++].usRegValue = stGh3x2xPPG_AutoDimming.LED_Ref_Down;\r
+       \r
+       ret = gh3x2x_demo_mp_set_chip_config(stCofigRegArr, index);\r
+       \r
+       return ret;\r
+}\r
+\r
+/**\r
+ * @fn     void gh3x2x_demo_mp_sampling_mode(GU8 uchMode)\r
+ *\r
+ * @brief  rawdata sampling start / stop\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   GU8 uchMode\r
+ * @param[out] \r
+ *\r
+ * @return  None\r
+ */\r
+void gh3x2x_demo_mp_sampling_mode(GU8 uchMode)\r
+{\r
+       if(START_SAMPLING == uchMode) //start\r
+       {\r
+               gh3x2x_demo_mp_write_reg(0x0508, 0x7FFF); //clear int\r
+               gh3x2x_mp_delay_ms(10);\r
+               GH3x2xMp_IntFlag = 0;\r
+               gh3x2x_demo_mp_write_reg_mask(0x00, 0x01, 0x01); //Trigger the chip to start collecting rawdata\r
+       }\r
+       else //stop\r
+       {\r
+               gh3x2x_demo_mp_write_reg_mask(0x00, 0x01, 0x00); //stop get rawdata\r
+       }\r
+}\r
+\r
+/**\r
+ * @fn     GU8 gh3x2x_demo_mp_get_rawdata(GU16 uchRegAddr, GU8 uchRawdataArr[], GU32 usLength)\r
+ *\r
+ * @brief  get rawdata\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   GU16 uchRegAddr, GU32 usLength\r
+ * @param[out]  GU8 uchRawdataArr[]\r
+ *\r
+ * @return  ret\r
+ */\r
+GU8 gh3x2x_demo_mp_get_rawdata(GU16 uchRegAddr, GU8 uchRawdataArr[], GU32 usLength)\r
+{\r
+       GU8 ret = 1;\r
+       GU32 i = 0;\r
+       GU16 read_len = 0;\r
+       GU16 read_byte_num = 0;\r
+       \r
+       if(usLength > RAWDATA_BUF_SIZE)\r
+       {\r
+               //error, over max read_byte_num\r
+               GH3X2X_MP_LOG_L1("Gh3x2x mp get rawdata error, over read rawdata max num! \r\n ");\r
+               ret = 0;\r
+               return ret;\r
+       }\r
+               \r
+       \r
+       //get rawdata\r
+       for(i = 0; i < usLength; i += read_byte_num)\r
+       {\r
+               if(!gh3x2x_demo_mp_wait_for_int(0x30, 200))\r
+               {\r
+                       //error, wait for no int, exit the loop \r
+                       GH3X2X_MP_LOG_L1("Gh3x2x mp get rawdata error, wait int over time! \r\n ");\r
+                       ret = 0;\r
+                       break;\r
+               }\r
+               read_len = gh3x2x_demo_mp_read_reg(0x050A); //read rawdata len from fifo cache  \r
+               read_byte_num = read_len*4; //One sample rawdata has 4 bytes            \r
+               gh3x2x_demo_mp_read_regs(uchRegAddr, uchRawdataArr + i, read_byte_num);\r
+\r
+               if(0 == read_byte_num)\r
+               {\r
+                       //error, read num ==0\r
+                       GH3X2X_MP_LOG_L1("Gh3x2x mp get rawdata error, read rawdata num equal 0! \r\n ");\r
+                       ret = 0;\r
+                       break;\r
+               }\r
+               if(read_byte_num > READ_RAWDATA_FIFO_MAX_BYTE_NUM)\r
+               {\r
+                       //error, over max read_byte_num\r
+                       GH3X2X_MP_LOG_L1("Gh3x2x mp get rawdata error, over max read rawdata fifo byte num! \r\n ");\r
+                       ret = 0;\r
+                       break;\r
+               }\r
+       }\r
+       \r
+       \r
+       return ret;\r
+}\r
+\r
+/**\r
+ * @fn     GU8 gh3x2x_demo_mp_handle_rawdata(GU8 uchMode, GS32 nHandleRawdataArr[], GU32 unHandleRawdataSkipLength, GU8 uchSlot_N, GU8 uchADC_N, \\r
+                                                                               GU8 uchRawdataArr[], GU32 unRawdataArrLength, GU8 uchSampleStep)\r
+ *\r
+ * @brief  handle rawdata\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]  GU8 uchMode, GU32 unHandleRawdataSkipLength, GU8 uchSlot_N, GU8 uchADC_N, GU8 uchRawdataArr[], GU32 unRawdataArrLength,GU8 uchSampleStep\r
+ * @param[out]  GS32 nHandleRawdataArr[]\r
+ *\r
+ * @return  ret\r
+ */\r
+GU8 gh3x2x_demo_mp_handle_rawdata(GU8 uchMode, GS32 nHandleRawdataArr[], GU32 unHandleRawdataSkipLength, GU8 uchSlot_N, GU8 uchADC_N, \\r
+                                                                               GU8 uchRawdataArr[], GU32 unRawdataArrLength, GU8 uchSampleStep)\r
+{\r
+       GU8 ret = 1;\r
+       GU32 i = 0;\r
+       GU8 cfg_temp = 0;\r
+       GU8 ADC_temp = 0;\r
+       GU8 ACG_temp = 0;\r
+       GU32 rawdata_buf_pt[MAX_SLOT_NUM][MAX_ADC_NUM] = {0};\r
+       \r
+       \r
+       for(i = 0; i < unRawdataArrLength; i++)\r
+       {\r
+               cfg_temp = (uchRawdataArr[4 * i] >> 5) & 0x07;\r
+               ADC_temp = (uchRawdataArr[4 * i] >> 3) & 0x03;\r
+               ACG_temp = (uchRawdataArr[4 * i] >> 1) & 0x03;\r
+               \r
+               if((cfg_temp == uchSlot_N) && (ADC_temp == uchADC_N))\r
+               {\r
+                       if (cfg_temp >= MAX_SLOT_NUM || ADC_temp >= MAX_ADC_NUM)//Check if the rawdata format read is correct\r
+                       {\r
+                               ret = 0;\r
+                               break;\r
+                       }\r
+                       if(__GH3X2X_MP_PRINT_RAWDATA__)\r
+                               GH3X2X_MP_LOG("Gh3x2x mp handle rawdata, cfg: %d, adc: %d, acg: %d, rawdata number %d is: %d \r\n", cfg_temp, ADC_temp, ACG_temp, rawdata_buf_pt[cfg_temp][ADC_temp], (uchRawdataArr[4 * i + 1] << 16) | (uchRawdataArr[4 * i + 2] << 8) | (uchRawdataArr[4 * i + 3]));\r
+                       \r
+                       if (rawdata_buf_pt[cfg_temp][ADC_temp] >= unHandleRawdataSkipLength)\r
+                       {\r
+                               if(uchMode == SPEC_MODE_PPG)\r
+                               {\r
+                                       if((rawdata_buf_pt[cfg_temp][ADC_temp] - unHandleRawdataSkipLength) < MAX_PPG_RAWDATA_SAMPLE_NUM)\r
+                                               nHandleRawdataArr[rawdata_buf_pt[cfg_temp][ADC_temp] - unHandleRawdataSkipLength] = (uchRawdataArr[4 * i + 1] << 16) | (uchRawdataArr[4 * i + 2] << 8) | (uchRawdataArr[4 * i + 3]);\r
+                                       else\r
+                                       {\r
+                                               GH3X2X_MP_LOG_L1("Gh3x2x mp handle ppg rawdata error, over max number of the rawdata sample! \r\n");\r
+                                               ret = 0;\r
+                                               break;\r
+                                       }\r
+                               }\r
+                               else\r
+                               {\r
+                                       if((rawdata_buf_pt[cfg_temp][ADC_temp] - unHandleRawdataSkipLength) < MAX_RAWDATA_SAMPLE_NUM)\r
+                                               nHandleRawdataArr[rawdata_buf_pt[cfg_temp][ADC_temp] - unHandleRawdataSkipLength] = (uchRawdataArr[4 * i + 1] << 16) | (uchRawdataArr[4 * i + 2] << 8) | (uchRawdataArr[4 * i + 3]);\r
+                                       else\r
+                                       {\r
+                                               GH3X2X_MP_LOG_L1("Gh3x2x mp handle ecg rawdata error, over max number of the rawdata sample! \r\n");\r
+                                               ret = 0;\r
+                                               break;\r
+                                       }\r
+                                       i += (uchSampleStep - 1);\r
+                               }\r
+                       }\r
+                       \r
+                       (rawdata_buf_pt[cfg_temp][ADC_temp])++;\r
+               }\r
+               \r
+       }\r
+       \r
+       return ret;\r
+}\r
+\r
+/**\r
+ * @fn     gh3x2x_demo_mp_ppg_get_rawdata(GS32 unRawdataArr[][MAX_ADC_NUM][MAX_PPG_RAWDATA_SAMPLE_NUM], GU16 usRawdataLen, GU16 usRawdataSkipLen, GU16 usLED_PD_Num)\r
+ *\r
+ * @brief  ppg test get rawdata\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   GU16 usRawdataLen, GU16 usRawdataSkipLen, GU16 usLED_PD_Num\r
+ * @param[out]  GU32 unRawdataArr[][MAX_ADC_NUM][MAX_PPG_RAWDATA_SAMPLE_NUM]\r
+ *\r
+ * @return  ret\r
+ */\r
+//GU8 cfg_temp[1200] = {0};\r
+//GU8 ADC_temp[1200] = {0};\r
+//GU8 ACG_temp[1200] = {0};\r
+//GU8 gh3x2x_demo_mp_ppg_get_rawdata(GS32 unRawdataArr[][MAX_ADC_NUM][MAX_PPG_RAWDATA_SAMPLE_NUM], GU16 usRawdataLen, GU16 usRawdataSkipLen, GU16 usLED_PD_Num)\r
+//{\r
+//     GU8 ret = 1;\r
+//     GU32 i = 0;\r
+//     GU32 rawdata_buf_pt[MAX_SLOT_NUM][MAX_ADC_NUM] = {0};\r
+//     GU8 rawdata_buf[RAWDATA_BUF_SIZE] = {0};\r
+//     if(usRawdataLen > MAX_PPG_RAWDATA_SAMPLE_NUM)\r
+//             usRawdataLen = MAX_PPG_RAWDATA_SAMPLE_NUM; //max is 500\r
+//     GU32 rawdata_total_len = (usRawdataLen + usRawdataSkipLen)*usLED_PD_Num;\r
+\r
+//     do\r
+//     {\r
+//             gh3x2x_demo_mp_sampling_mode(START_SAMPLING); //start\r
+//             if(!gh3x2x_demo_mp_get_rawdata(0xAAAA, rawdata_buf, rawdata_total_len*4)) //every rawdata have 4 bytes\r
+//             {\r
+//                     ret = 0;\r
+//                     gh3x2x_demo_mp_sampling_mode(STOP_SAMPLING); //stop\r
+//                     GH3X2X_MP_LOG_L1("Gh3x2x mp ppg get rawdata error! \r\n ");\r
+//                     break;\r
+//             }\r
+//             gh3x2x_demo_mp_sampling_mode(STOP_SAMPLING); //stop\r
+//             \r
+//             //handle rawdata_buf\r
+//             GU8 cfg_temp = 0;\r
+//             GU8 ADC_temp = 0;\r
+//             GU8 ACG_temp = 0;\r
+//             \r
+//             for(i = 0; i < rawdata_total_len; i++)\r
+//             {\r
+//                     cfg_temp = (rawdata_buf[4 * i] >> 5) & 0x07;\r
+//                     ADC_temp = (rawdata_buf[4 * i] >> 3) & 0x03;\r
+//                     ACG_temp = (rawdata_buf[4 * i] >> 1) & 0x03;\r
+//                     \r
+//                     if (cfg_temp >= MAX_SLOT_NUM || ADC_temp >= MAX_ADC_NUM)//Check if the rawdata format read is correct\r
+//                     {\r
+//                             ret = 0;\r
+//                             break;\r
+//                     }\r
+//                     if(__GH3X2X_MP_PRINT_RAWDATA__)\r
+//                             GH3X2X_MP_LOG("Gh3x2x mp rawdata cfg: %d, adc: %d, acg: %d, rawdata: %d \r\n", cfg_temp, ADC_temp, ACG_temp, (rawdata_buf[4 * i + 1] << 16) | (rawdata_buf[4 * i + 2] << 8) | (rawdata_buf[4 * i + 3]));\r
+//                     \r
+//                     if (rawdata_buf_pt[cfg_temp][ADC_temp] >= usRawdataSkipLen)\r
+//                             unRawdataArr[cfg_temp][ADC_temp][rawdata_buf_pt[cfg_temp][ADC_temp] - usRawdataSkipLen] = (rawdata_buf[4 * i + 1] << 16) | (rawdata_buf[4 * i + 2] << 8) | (rawdata_buf[4 * i + 3]);\r
+//                     \r
+//                     (rawdata_buf_pt[cfg_temp][ADC_temp])++;\r
+//             }\r
+//             \r
+//     }while(0);\r
+//     \r
+//     return ret;\r
+//}\r
+\r
+/**\r
+ * @fn     void gh3x2x_demo_mp_calc_noise(GS32 nRawdataArr[], GU16 usLength, GF32 *fAvergeRawdata, GF32 *fNoise)\r
+ *\r
+ * @brief  cal noise\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   GS32 nRawdataArr[], GU16 usLength\r
+ * @param[out]  GF32 *fAvergeRawdata, GF32 *fNoise\r
+ *\r
+ * @return  none\r
+ */\r
+void gh3x2x_demo_mp_calc_noise(GS32 nRawdataArr[], GU16 usLength, GF32 *fAvergeRawdata, GF32 *fNoise)\r
+{\r
+       GU32 i = 0;\r
+       \r
+       GD64 rawdata_sum = 0;\r
+       GD64 tmp_sum = 0.0;\r
+       \r
+       if(0 == usLength)\r
+       {\r
+               GH3X2X_MP_LOG_L1("Gh3x2x mp cal noise error, rawdata length == 0! \r\n");\r
+               *fNoise = (float)0x7FFFFFFF;\r
+               return;\r
+       }\r
+       \r
+       for(i = 0; i < usLength; i++)\r
+       {\r
+               rawdata_sum += nRawdataArr[i];\r
+       }\r
+       *fAvergeRawdata = 1.0 * rawdata_sum / usLength;\r
+       \r
+       for(i = 0; i < usLength; i++)\r
+       {\r
+               tmp_sum += pow(nRawdataArr[i] - (*fAvergeRawdata), 2);\r
+       }\r
+       *fNoise = 6.0 * sqrt(tmp_sum / usLength);\r
+       \r
+}\r
+\r
+/**\r
+ * @fn     GU8 gh3x2x_demo_mp_ecg_signal_filter(GS32 nRawdataArr[], GU16 usLength, GU8 uchLpType, GU8 uchHpType, GU8 uchFsType)\r
+ *\r
+ * @brief  ECG signal filter\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   GS32 nRawdataArr[], GU16 usLength, GU8 uchLpType, GU8 uchHpType, GU8 uchFsType\r
+                               uchLpType:Low pass filter cut-off frequency\r
+                               uchHpType:High pass filter cut-off frequency\r
+                               uchFsType:Sampling rate of rawdata,0,250Hz; 1,500Hz; 2,1000Hz; others, 500Hz\r
+ * @param[out]  GS32 nRawdataArr[]: filter data\r
+ *\r
+ * @return  ret\r
+ */\r
+GU8 gh3x2x_demo_mp_ecg_signal_filter(GS32 nRawdataArr[], GU16 usLength, GU8 uchLpType, GU8 uchHpType, GU8 uchFsType)\r
+{\r
+       GU32 i = 0;\r
+       GU8 ret = 1;\r
+       \r
+       GD64 filter_temp = nRawdataArr[0];\r
+       for(i = 0; i < usLength; i++)\r
+       {\r
+               nRawdataArr[i] = nRawdataArr[i] - filter_temp; \r
+       }\r
+\r
+       //filter\r
+       gh3x2x_mp_signal_filter(nRawdataArr, usLength, uchHpType, uchLpType, uchFsType);\r
+       \r
+       return ret;\r
+}\r
+\r
+/**\r
+ * @fn     GF32 gh3x2x_demo_mp_calc_LPCTR(GF32 fAverageRawdata, GU32 unTIA, GU32 unILed)\r
+ *\r
+ * @brief  cal LP CTR\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   GF32 fAverageRawdata, GU32 unTIA, GU32 unILed\r
+ * @param[out]  \r
+ *\r
+ * @return  CTR\r
+ */\r
+GF32 gh3x2x_demo_mp_calc_LPCTR(GF32 fAverageRawdata, GU32 unTIA, GU32 unILed)\r
+{\r
+       GF32 fLP_CTR = 0.0;\r
+       fLP_CTR = 1.0 * (RAWDATA_TO_VOL((GD64)fAverageRawdata - ADC_OFFSET) / (2*Tia_Switch(unTIA)) / (unILed*100.0 / 255));\r
+       \r
+       if((GD64)fLP_CTR < 0.00001)\r
+               fLP_CTR = 0.0;\r
+       \r
+       return fLP_CTR;\r
+}\r
+\r
+/**\r
+ * @fn     GF32 gh3x2x_demo_mp_ecg_cal_HPF_Ratio(GS32 nRawdataArr[], GU16 usLength)\r
+ *\r
+ * @brief  cal HPF amplitude ratio\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   GS32 nRawdataArr[], GU16 usLength\r
+ * @param[out]  \r
+ *\r
+ * @return  HPF_Ratio\r
+ */\r
+GF32 gh3x2x_demo_mp_ecg_cal_HPF_Ratio(GS32 nRawdataArr[], GU16 usLength)\r
+{\r
+       GU16 i = 0;\r
+       GF32 fHPF_Ratio = 0.0;\r
+       GU32 sum[2] = { 0 };\r
+    GU32 max = 0;\r
+    \r
+       GU16 start_index = 0;\r
+\r
+    max = nRawdataArr[0];\r
+    for (i = 0; i < usLength / 2 - 10; i++)\r
+    {\r
+        if (nRawdataArr[i] > max)\r
+        {\r
+            max = nRawdataArr[i];\r
+            start_index = i;\r
+        }\r
+    }\r
+    for (i = start_index; i < start_index + 3; i++)\r
+    {\r
+        sum[0] += nRawdataArr[i];\r
+        sum[1] += nRawdataArr[usLength / 2 + i];\r
+    }\r
+    sum[0] = sum[0] / 3;\r
+    sum[1] = sum[1] / 3;\r
+\r
+    fHPF_Ratio = (GF32)(sum[1] - 8388608.0) / (GF32)(sum[0] - 8388608);\r
+       \r
+       return fHPF_Ratio;\r
+}\r
+\r
+/**\r
+ * @fn     GU8 gh3x2x_demo_mp_ecg_cal_signal_amp_freq(GS32 nRawdataArr[], GU16 usLength, GF32 *fAmp, GF32 *fFreq, \\r
+                                                                                                       GU8 uchLpType, GU8 uchHpType, GU8 uchFsType, GS16 sCalStart, GS16 sCalEnd, GF32 fRefFreq, GU8 uchStep)\r
+ *\r
+ * @brief  Cal the amplitude and frequency of the signal\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   GS32 nRawdataArr[], GU16 usLength, GU8 uchLpType, GU8 uchHpType, GU8 uchFsType, GS16 sCalStart, GS16 sCalEnd, GF32 fRefFreq, GU8 uchStep\r
+                               nRawdataArr:Data to be processed\r
+                               usLength:Data len\r
+                               uchLpType:Low pass filter cut-off frequency\r
+                               uchHpType:High pass filter cut-off frequency\r
+                               uchFsType:Sampling rate type of rawdata, 0,250Hz; 1,500Hz; 2,1000Hz; others, 500Hz\r
+                               sCalStart:FFT start begin point\r
+                               sCalEnd:FFT start end point\r
+                               fRefFreq:For reference frequency, find the maximum value near fref±5hz; if <0, find the maximum value between 0.1hz~fs/2\r
+ * @param[out]  GF32 *fAmp, GF32 *fFreq\r
+ *\r
+ * @return  ret\r
+ */\r
+GU8 gh3x2x_demo_mp_ecg_cal_signal_amp_freq(GS32 nRawdataArr[], GU16 usLength, GF32 *fAmp, GF32 *fFreq, GU8 uchLpType, \\r
+                                                                                       GU8 uchHpType, GU8 uchFsType, GS16 sCalStart, GS16 sCalEnd, GF32 fRefFreq, GU8 uchStep)\r
+{\r
+       GU16 i = 0;\r
+       GU8 ret = 1;\r
+       GU16 fftlen = 0;\r
+       memset(GH3x2xMp_RawdataBuf, 0, RAWDATA_BUF_SIZE*sizeof(GU8)); //Reuse GH3x2xMp_RawdataBuf memory\r
+       fArrHandle_Temp = (GF32 *)GH3x2xMp_RawdataBuf; //Reuse GH3x2xMp_RawdataBuf memory\r
+       \r
+       if(uchStep <= 0)\r
+               uchStep = 1;\r
+       \r
+       usLength = usLength / uchStep; //sampling\r
+       \r
+       if(usLength > MAX_RAWDATA_SAMPLE_NUM)\r
+               usLength = MAX_RAWDATA_SAMPLE_NUM;\r
+       \r
+       gh3x2x_demo_mp_ecg_signal_filter(nRawdataArr, usLength, uchLpType, uchHpType, uchFsType);\r
+       \r
+       for(i = 0; i < usLength; i++)\r
+       {\r
+               nRawdataArr[i] *= 100; //in order to keep two decimal places\r
+       }\r
+       \r
+       for(i = 0; i < usLength; i++)\r
+       {\r
+               nRawdataArr[i] = nRawdataArr[i]* ADC_REFER / ADC_MAX / GAIN * 1000; //uV\r
+       }\r
+       \r
+\r
+       GU32 sampleRate = 500;\r
+       if (uchFsType == 0)\r
+       {\r
+               sampleRate = 250;\r
+       }\r
+       else if (uchFsType == 1)\r
+       {\r
+               sampleRate = 500;\r
+       }\r
+       else if (uchFsType == 2)\r
+       {\r
+               sampleRate = 1000;\r
+       }\r
+       else\r
+       {\r
+               sampleRate = 500;\r
+       }\r
+       sampleRate /= uchStep;\r
+       \r
+       \r
+       if (sCalEnd >= usLength || sCalEnd < sCalStart)\r
+               fftlen = usLength - sCalStart;\r
+       else\r
+               fftlen = sCalEnd - sCalStart;\r
+       \r
+       for(i = 0; i < fftlen; i++)\r
+       {\r
+               fArrHandle_Temp[i] = (GF32)nRawdataArr[i + sCalStart] / 100;\r
+       }\r
+       \r
+       //cal amp\r
+       GF32 amp_1=0;\r
+       GF32 freq_1=0;\r
+       gh3x2x_demo_mp_ecg_fft_cal_amp_freq(fArrHandle_Temp, fftlen, fftlen, sampleRate, &amp_1, &freq_1, fRefFreq, 1);\r
+       \r
+       //memset(fArrHandle_Temp, 0, 2*MAX_FFT_LENGTH*sizeof(GF32));\r
+       memset(GH3x2xMp_RawdataBuf, 0, RAWDATA_BUF_SIZE*sizeof(GU8)); //fArrHandle_Temp reuse GH3x2xMp_RawdataBuf memory\r
+       for(i = 0; i < fftlen; i++)\r
+       {\r
+               fArrHandle_Temp[i] = (GF32)nRawdataArr[i + sCalStart] / 100;\r
+       }\r
+       \r
+       //cal freq\r
+       GF32 amp_2=0;\r
+       GF32 freq_2=0;\r
+       GU32 fftlen_2 = MAX_FFT_LENGTH;\r
+       gh3x2x_demo_mp_ecg_fft_cal_amp_freq(fArrHandle_Temp, fftlen, fftlen_2, sampleRate, &amp_2, &freq_2, fRefFreq, 2);\r
+       \r
+       *fAmp = amp_1;\r
+       *fFreq = freq_2;\r
+       \r
+       fArrHandle_Temp = NULL;\r
+       return ret;\r
+}\r
+\r
+/**\r
+ * @fn     GU8 gh3x2x_demo_mp_ecg_cmmr_calculate(GS32 nRawdataArr[], GU16 usLength, GF32 *fCmmr, GU8 uchFsType, GF32 fRefFreq)\r
+ *\r
+ * @brief  Cal the ecg-cmmr\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   GS32 nRawdataArr[], GU16 usLength, GU8 uchFsType, GF32 fRefFreq\r
+                               nRawdataArr:Data to be processed\r
+                               usLength:Data len\r
+                               uchFsType:Sampling rate type of rawdata, 0,250Hz; 1,500Hz; 2,1000Hz; others, 500Hz\r
+                               fRefFreq:For reference frequency, find the maximum value near fref±5hz; if <0, find the maximum value between 0.1hz~fs/2\r
+ * @param[out]  GF32 *fCmmr\r
+ *\r
+ * @return  ret\r
+ */\r
+GU8 gh3x2x_demo_mp_ecg_cmmr_calculate(GS32 nRawdataArr[], GU16 usLength, GF32 *fCmmr, GU8 uchFsType, GF32 fRefFreq)\r
+{\r
+       GU8 ret = 1;\r
+       \r
+       GF32 amp = 0;\r
+       GF32 freq = 0;\r
+       \r
+       gh3x2x_demo_mp_ecg_cal_signal_amp_freq(nRawdataArr, usLength, &amp, &freq, 1, 5, uchFsType, 200, -1, fRefFreq, 1);\r
+       \r
+       if (amp)\r
+        *fCmmr = (20 * log10((GF32)1e6 / amp));\r
+    else\r
+        *fCmmr = 0;\r
+       GH3X2X_MP_LOG_L2("Gh3x2x mp cal cmmr freq: %.5f \r\n", freq);\r
+       \r
+       return ret;\r
+}\r
+\r
+/**\r
+ * @fn     GU8 gh3x2x_demo_mp_ecg_cal_signal_WaveTimeDomin_Amp(GS32 nRawdataArr[], GU16 usLength, GF32 *fAmp, GU8 uchFsType, GF32 fRefFreq)\r
+ *\r
+ * @brief  Cal ecg-DCRange WaveTimeDomin Amp\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   GS32 nRawdataArr[], GU16 usLength, GF32 *fAmp, GU8 uchFsType, GF32 fRefFreq\r
+                               nRawdataArr:Data to be processed\r
+                               usLength:Data len\r
+                               uchFsType:Sampling rate type of rawdata, 0,250Hz; 1,500Hz; 2,1000Hz; others, 500Hz\r
+                               fRefFreq: Reference frequency\r
+ * @param[out]  GF32 *fAmp\r
+ *\r
+ * @return  ret\r
+ */\r
+GU8 gh3x2x_demo_mp_ecg_cal_signal_WaveTimeDomin_Amp(GS32 nRawdataArr[], GU16 usLength, GF32 *fAmp, GU8 uchFsType, GF32 fRefFreq)\r
+{\r
+       GU8 ret = 1;\r
+       GS32 i = 0;\r
+       GS32 j = 0;\r
+       \r
+       GU32 peakMax = 0;\r
+       GU32 peakMin = 0;\r
+       GU32 counter = 0;\r
+       GU32 temp = 0;\r
+       GU32 unT = 0, unT_0 = 0;\r
+\r
+       memset(GH3x2xMp_RawdataBuf, 0, RAWDATA_BUF_SIZE*sizeof(GU8)); //Reuse GH3x2xMp_RawdataBuf memory\r
+       fArrHandle_Temp = (GF32 *)GH3x2xMp_RawdataBuf; //Reuse GH3x2xMp_RawdataBuf memory\r
+       \r
+       \r
+       //Sampling rate selection\r
+       GU32 sampleRate = 500;\r
+       if(uchFsType == 0)\r
+       {\r
+               sampleRate = 250;\r
+       }\r
+       else if (uchFsType == 1)\r
+       {\r
+               sampleRate = 500;\r
+       }\r
+       else if(uchFsType == 2)\r
+       {\r
+               sampleRate = 1000;\r
+       }\r
+       else\r
+       {\r
+               sampleRate = 500;\r
+       }\r
+       \r
+       unT_0 = (GU32)sampleRate / fRefFreq;\r
+       unT = unT_0 + unT_0 / 4;\r
+       //find from the end\r
+       for (i = usLength - 1; i >= unT; i -= unT_0)\r
+       {\r
+               counter++;\r
+               //find min and max\r
+               peakMax = nRawdataArr[i];\r
+               peakMin = nRawdataArr[i];\r
+               for (j = 0; j < unT; j++)\r
+               {\r
+                       temp = nRawdataArr[i - j];\r
+                       if (temp > peakMax)\r
+                               peakMax = temp;\r
+                       if (temp < peakMin)\r
+                               peakMin = temp;\r
+               }\r
+               fArrHandle_Temp[counter - 1] = (GF32)(peakMax - peakMin);\r
+       }\r
+       \r
+       \r
+       //Minimum output amplitude\r
+       GF32 ampMin = 0;\r
+       for(i = 0; i < counter; i++)\r
+       {\r
+               ampMin += fArrHandle_Temp[i];\r
+       }\r
+       ampMin = ampMin / counter;\r
+       \r
+       *fAmp = (GF32)ampMin * ADC_REFER / ADC_MAX / GAIN * 1000; //uV\r
+       \r
+       fArrHandle_Temp = NULL;\r
+       \r
+       return ret;\r
+}\r
+\r
+/**\r
+ * @fn     GU8 gh3x2x_demo_mp_PPG_LPCTR_Test(stGh3x2xMp_PPGTestParam *pstTestPara, stGh3x2xMp_PPGTestResult *pstTestResult)\r
+ *\r
+ * @brief  PPG test items ---- LP CTR test\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   stGh3x2xMp_PPGTestParam *pstTestPara, stGh3x2xMp_PPGTestResult *pstTestResult\r
+ * @param[out]  \r
+ *\r
+ * @return  error code\r
+ */\r
+GU8 gh3x2x_demo_mp_PPG_LPCTR_Test(stGh3x2xMp_PPGTestParam *pstTestPara, stGh3x2xMp_PPGTestResult *pstTestResult)\r
+{\r
+       GU8 test_code = 0;\r
+       GU8 retry_time = 3;\r
+       GU8 i = 0;\r
+       GU8 LP_CTR_is_ok = 1;\r
+       GH3X2X_MP_LOG_L2("Gh3x2x mp PPG CTR test start! \r\n");\r
+       \r
+       //GS32 PPG_RawdataArr[MAX_PPG_RAWDATA_SAMPLE_NUM] = {0};\r
+       GU32 RawdataBuf_Len = 0;\r
+       if((pstTestPara->PPG_CTRRawdata_Num > MAX_PPG_RAWDATA_SAMPLE_NUM) \\r
+               || (0 == pstTestPara->PPG_CTRRawdata_Num)) //max is MAX_PPG_RAWDATA_SAMPLE_NUM\r
+       {\r
+               test_code = MT_ERROR_LED_LP_RAWDATA_ABNORMAL;\r
+               GH3X2X_MP_LOG_L1("Gh3x2x mp PPG test fail, CTR test set the number of samples over limit, error code is: %d! \r\n", test_code);\r
+               return test_code;\r
+       }\r
+       \r
+       memset(GH3x2xMp_RawdataBuf, 0, RAWDATA_BUF_SIZE*sizeof(GU8));\r
+       \r
+       GU8 Slot_Cfg_EN = pstTestPara->stLEDPDConfig.LED_Channel;\r
+       GU8 LED_PD_NUM = 0; //Number of LED*PD to be tested\r
+       \r
+       if(SLOT_ONECH_MODE == pstTestPara->stCTRSlotConfig.Slot_Mode)\r
+               LED_PD_NUM = pstTestPara->stLEDPDConfig.PD_Num[0];\r
+       else //SLOT_MULTICH_MODE\r
+               LED_PD_NUM = pstTestPara->stLEDPDConfig.LED_PD_Num;\r
+       \r
+       //tset before operation, chip resume\r
+       gh3x2x_demo_mp_send_cmd(GH3X2X_MP_CMD_RESUME);\r
+       gh3x2x_mp_delay_ms(5);\r
+       \r
+       //write config to gh3x2x\r
+       for(i = 0; i < retry_time; i++)\r
+       {\r
+               if(gh3x2x_demo_mp_set_chip_config(stGh3x2xMpRegPPGConfig, sizeof(stGh3x2xMpRegPPGConfig) / sizeof(stGh3x2xMpRegPPGConfig[0])))\r
+               {\r
+                       break;\r
+               }\r
+       }\r
+       if( i == retry_time)\r
+       {\r
+               test_code = MT_ERROR_COMMUNICATE_FAIL;\r
+               GH3X2X_MP_LOG_L1("Gh3x2x mp PPG test fail, CTR test set reg config fail, error code is: %d! \r\n", test_code);\r
+               return test_code;\r
+       }\r
+       \r
+       //according to SLOT_CFG_EN cal which slots need to be enabled, and enable slot\r
+       GU8 SlotEnableNum = 0;\r
+       if(!gh3x2x_demo_mp_set_slot_enable(Slot_Cfg_EN, &SlotEnableNum) || SlotEnableNum < 1)\r
+       {\r
+               test_code = MT_ERROR_COMMUNICATE_FAIL;\r
+               GH3X2X_MP_LOG_L1("Gh3x2x mp PPG test fail, CTR test set slot enable fail, error code is: %d! \r\n", test_code);\r
+               return test_code;\r
+       }\r
+       \r
+       //set slot config\r
+       for(i = 0; i < MAX_SLOT_NUM; i++)\r
+       {\r
+               //set the enabled slot config\r
+               if((Slot_Cfg_EN >> i) & 0x01)\r
+               {\r
+                       pstTestPara->stCTRSlotConfig.Slot_Cfg_N = i;\r
+                       pstTestPara->stCTRSlotConfig.PD_N = pstTestPara->stLEDPDConfig.PD_Channel[i];\r
+                       pstTestPara->stCTRSlotConfig.ADC_N = i % 4; //ADC value can only be 0~3\r
+                       pstTestPara->stCTRSlotConfig.LED_N = i;\r
+                       \r
+                       if(!gh3x2x_demo_mp_set_slot_config(pstTestPara->stCTRSlotConfig))\r
+                       {\r
+                               test_code = MT_ERROR_COMMUNICATE_FAIL;\r
+                               GH3X2X_MP_LOG_L1("Gh3x2x mp PPG test fail, CTR test set slot config fail, error code is: %d! \r\n", test_code);\r
+                               return test_code;\r
+                       }\r
+               }\r
+       }\r
+       \r
+       //get rawdata\r
+       gh3x2x_demo_mp_sampling_mode(START_SAMPLING); //start\r
+       RawdataBuf_Len = (pstTestPara->PPG_CTRRawdata_Num + pstTestPara->PPG_CTRRawdata_SkipNum)*LED_PD_NUM;\r
+       if(!gh3x2x_demo_mp_get_rawdata(0xAAAA, GH3x2xMp_RawdataBuf, RawdataBuf_Len*4)) //every rawdata have 4 bytes\r
+       {\r
+               gh3x2x_demo_mp_sampling_mode(STOP_SAMPLING); //stop\r
+               test_code = MT_ERROR_COMMUNICATE_FAIL;\r
+               GH3X2X_MP_LOG_L1("Gh3x2x mp PPG test fail, CTR test read rawdata error, error code is: %d! \r\n", test_code);\r
+               return test_code;\r
+       }\r
+       gh3x2x_demo_mp_sampling_mode(STOP_SAMPLING); //stop\r
+\r
+       //start cal noise and CTR, check CTR\r
+       GU16 usChannel = 0; //only 0~31, LED(x) PD(y) channel is:x*MAX_ADC_NUM + y\r
+       for(i = 0; i < MAX_SLOT_NUM; i++)\r
+       {\r
+                if(!((Slot_Cfg_EN >> i) & 0x01))//Only cal the slots that need to be tested\r
+                {\r
+                       continue;\r
+                }\r
+                for(GU32 j = 0; j < MAX_ADC_NUM; j++)\r
+                {\r
+                       if (!((pstTestPara->stLEDPDConfig.PD_Channel[i] >> j) & 0x01))//Only cal the PD that needs to be tested\r
+                       {\r
+                               continue;\r
+                       }\r
+                       \r
+                       if(SLOT_MULTICH_MODE == pstTestPara->stCTRSlotConfig.Slot_Mode)\r
+                               usChannel = i*MAX_ADC_NUM + j;\r
+                       else\r
+                               usChannel = j;\r
+                       \r
+                       //handle rawdata\r
+                       memset(GH3x2xMp_RawdataHandleArr, 0, MAX_PPG_RAWDATA_SAMPLE_NUM*sizeof(GS32));\r
+                       if(!gh3x2x_demo_mp_handle_rawdata(SPEC_MODE_PPG, GH3x2xMp_RawdataHandleArr, pstTestPara->PPG_CTRRawdata_SkipNum, \\r
+                                                                                                               i, j, GH3x2xMp_RawdataBuf, RawdataBuf_Len, 1))\r
+                       {\r
+                               test_code = MT_ERROR_LED_LP_RAWDATA_ABNORMAL;\r
+                               GH3X2X_MP_LOG_L1("Gh3x2x mp PPG test fail, LP CTR handle rawdata error, error code is: %d! \r\n", test_code);\r
+                               return test_code;\r
+                       }\r
+                       //calc noise, averge rawdata                    \r
+                       gh3x2x_demo_mp_calc_noise(GH3x2xMp_RawdataHandleArr, pstTestPara->PPG_CTRRawdata_Num, \\r
+                                                                               &pstTestResult->stCTRRawHandleResult.AvergeRawdata[usChannel], &pstTestResult->stCTRRawHandleResult.Noise[usChannel]);\r
+                       //calc CTR\r
+                       pstTestResult->LED_LPCTR[usChannel] = gh3x2x_demo_mp_calc_LPCTR(pstTestResult->stCTRRawHandleResult.AvergeRawdata[usChannel], \\r
+                                                                                                               pstTestPara->stCTRSlotConfig.TIA_RF, pstTestPara->stCTRSlotConfig.LED_Drv);\r
+                       \r
+                       //check\r
+                       if(pstTestResult->LED_LPCTR[usChannel] < stGh3x2xMpLimit.PPG_CTR_MinLimit[usChannel])\r
+                       {\r
+                               LP_CTR_is_ok = 0;\r
+                               GH3X2X_MP_LOG_L1("Gh3x2x mp PPG test fail, LP_CTR[%d]: %.5f less than min limit: %.5f !\r\n", usChannel, \\r
+                                                                               pstTestResult->LED_LPCTR[usChannel], stGh3x2xMpLimit.PPG_CTR_MinLimit[usChannel]);\r
+                       }\r
+                       else\r
+                       {\r
+                               GH3X2X_MP_LOG_L2("Gh3x2x mp PPG test result info, LP_CTR[%d] is: %.5f, min limit is: %.5f, LP_CTR test is pass! \r\n", usChannel, \\r
+                                                                               pstTestResult->LED_LPCTR[usChannel], stGh3x2xMpLimit.PPG_CTR_MinLimit[usChannel]);\r
+                       }\r
+                }\r
+       }\r
+       if(!LP_CTR_is_ok)\r
+       {\r
+               test_code = MT_ERROR_LED_LP_RAWDATA_ABNORMAL;\r
+               GH3X2X_MP_LOG_L1("Gh3x2x mp PPG test fail, LP CTR over limit, error code is: %d! \r\n", test_code);\r
+               return test_code;\r
+       }\r
+       \r
+       GH3X2X_MP_LOG_L2("Gh3x2x mp PPG--CTR test end! \r\n");\r
+       return test_code;\r
+}\r
+\r
+/**\r
+ * @fn     GU8 gh3x2x_demo_mp_PPG_Noise_Test(stGh3x2xMp_PPGTestParam *pstTestPara, stGh3x2xMp_PPGTestResult *pstTestResult)\r
+ *\r
+ * @brief  PPG test items ---- noise test\r
+ *\r
+ * @attention   PPG Noise test requires automatic dimming. \r
+ * @attention   It is not possible to test all leds in parallel using multi-channel mode, only serial test\r
+ *\r
+ * @param[in]   stGh3x2xMp_PPGTestParam *pstTestPara, stGh3x2xMp_PPGTestResult *pstTestResult\r
+ * @param[out]  \r
+ *\r
+ * @return  error code\r
+ */\r
+extern GU8 HPF_FirstFlag;\r
+GU8 gh3x2x_demo_mp_PPG_Noise_Test(stGh3x2xMp_PPGTestParam *pstTestPara, stGh3x2xMp_PPGTestResult *pstTestResult)\r
+{\r
+       GU8 test_code = 0;\r
+       GU8 i = 0;\r
+       GU8 L = 0;\r
+       GH3X2X_MP_LOG_L2("Gh3x2x mp PPG--Noise test start! \r\n");\r
+       \r
+       //GS32 PPG_RawdataArr[MAX_PPG_RAWDATA_SAMPLE_NUM] = {0};\r
+       GU32 RawdataBuf_Len = 0;\r
+       if((pstTestPara->PPG_NoiseRawdata_Num > MAX_PPG_RAWDATA_SAMPLE_NUM) \\r
+               || (0 == pstTestPara->PPG_NoiseRawdata_Num)) //max is MAX_PPG_RAWDATA_SAMPLE_NUM\r
+       {\r
+               test_code = MT_ERROR_LP_NOISE_ABNORMAL;\r
+               GH3X2X_MP_LOG_L1("Gh3x2x mp PPG test fail, Noise test set the number of samples over limit, error code is: %d! \r\n", test_code);\r
+               return test_code;\r
+       }\r
+       \r
+       GU8 Slot_Cfg_EN = 0;\r
+       GU8 LED_PD_NUM = 0; //Number of LED*PD to be tested\r
+       \r
+       //tset before operation, chip resume\r
+       gh3x2x_demo_mp_send_cmd(GH3X2X_MP_CMD_RESUME);\r
+       gh3x2x_mp_delay_ms(5);\r
+       \r
+       if(!gh3x2x_demo_mp_set_chip_config(stGh3x2xMpRegPPGConfig, sizeof(stGh3x2xMpRegPPGConfig) / sizeof(stGh3x2xMpRegPPGConfig[0])))\r
+       {\r
+               test_code = MT_ERROR_COMMUNICATE_FAIL;\r
+               GH3X2X_MP_LOG_L1("Gh3x2x mp PPG test fail, Noise test set reg config fail, error code is: %d! \r\n", test_code);\r
+               return test_code;\r
+       }\r
+       \r
+       for(L = 0; L < MAX_LED_NUM; L++)\r
+       {\r
+               memset(GH3x2xMp_RawdataBuf, 0, RAWDATA_BUF_SIZE*sizeof(GU8));\r
+               Slot_Cfg_EN = pstTestPara->stLEDPDConfig.PD_Channel[L];\r
+               if(0 == Slot_Cfg_EN) //judge current LED whether need test\r
+                       continue;\r
+               LED_PD_NUM = pstTestPara->stLEDPDConfig.PD_Num[L];\r
+               \r
+               //according to SLOT_CFG_EN cal which slots need to be enabled, and enable slot\r
+               GU8 SlotEnableNum = 0;\r
+               if(!gh3x2x_demo_mp_set_slot_enable(Slot_Cfg_EN, &SlotEnableNum) || SlotEnableNum < 1)\r
+               {\r
+                       test_code = MT_ERROR_COMMUNICATE_FAIL;\r
+                       GH3X2X_MP_LOG_L1("Gh3x2x mp PPG test fail, Noise test set slot enable fail, error code is: %d! \r\n", test_code);\r
+                       return test_code;\r
+               }\r
+               \r
+               \r
+               if(!gh3x2x_demo_mp_set_LED_ACG_cfg(L, stGh3x2xPPG_AutoDimming.LED_ACG_FS[L], pstTestPara))\r
+               {\r
+                       test_code = MT_ERROR_COMMUNICATE_FAIL;\r
+                       GH3X2X_MP_LOG_L1("Gh3x2x mp PPG test fail, Noise test set LED ACG config fail, error code is: %d! \r\n", test_code);\r
+                       return test_code;\r
+               }\r
+               \r
+               for (int j = 0; j < MAX_ADC_NUM; j++)//Configure each slot reg, because there are 4 PDs at most, so 4 slots are used at most\r
+        {\r
+            if ((Slot_Cfg_EN >> j) & 0x01)\r
+            {\r
+                               pstTestPara->stNoiseSlotConfig.Slot_Cfg_N = j;\r
+                               pstTestPara->stNoiseSlotConfig.PD_N = 1 << j;\r
+                               pstTestPara->stNoiseSlotConfig.ADC_N = j % 4; //ADC only value is 0~3\r
+                               pstTestPara->stNoiseSlotConfig.LED_N = L; //Use the same LED for different slots in the same test\r
+\r
+                if(!gh3x2x_demo_mp_set_slot_config(pstTestPara->stNoiseSlotConfig))\r
+                               {\r
+                                       test_code = MT_ERROR_COMMUNICATE_FAIL;\r
+                                       GH3X2X_MP_LOG_L1("Gh3x2x mp PPG test fail, Noise test set slot config fail, error code is: %d! \r\n", test_code);\r
+                                       return test_code;\r
+                               } \r
+            }\r
+        }\r
+               \r
+               //get rawdata\r
+               gh3x2x_demo_mp_sampling_mode(START_SAMPLING); //start\r
+               RawdataBuf_Len = (pstTestPara->PPG_NoiseRawdata_Num + pstTestPara->PPG_NoiseRawdata_SkipNum)*LED_PD_NUM;\r
+               if(!gh3x2x_demo_mp_get_rawdata(0xAAAA, GH3x2xMp_RawdataBuf, RawdataBuf_Len*4)) //every rawdata have 4 bytes\r
+               {\r
+                       gh3x2x_demo_mp_sampling_mode(STOP_SAMPLING); //stop\r
+                       test_code = MT_ERROR_COMMUNICATE_FAIL;\r
+                       GH3X2X_MP_LOG_L1("Gh3x2x mp PPG test fail, Noise test read rawdata error, error code is: %d! \r\n", test_code);\r
+                       return test_code;\r
+               }\r
+               gh3x2x_demo_mp_sampling_mode(STOP_SAMPLING); //stop\r
+               \r
+               GU16 usChannel = 0; //only 0~31, LED(x) PD(y) channel is:x*MAX_ADC_NUM + y\r
+               GF32 Noise_temp = 0;\r
+               GF32 AvergeRawdata_temp = 0;\r
+               for (i = 0; i < MAX_SLOT_NUM; i++)\r
+               {\r
+                       if((Slot_Cfg_EN >> i) & 0x01)\r
+                       {\r
+                               usChannel = L*MAX_ADC_NUM + i;\r
+                               //handle rawdata\r
+                               memset(GH3x2xMp_RawdataHandleArr, 0, MAX_PPG_RAWDATA_SAMPLE_NUM*sizeof(GS32));\r
+                               if(!gh3x2x_demo_mp_handle_rawdata(SPEC_MODE_PPG, GH3x2xMp_RawdataHandleArr, pstTestPara->PPG_NoiseRawdata_SkipNum, \\r
+                                                                                                               i, i, GH3x2xMp_RawdataBuf, RawdataBuf_Len, 1))\r
+                               {\r
+                                       test_code = MT_ERROR_LP_NOISE_ABNORMAL;\r
+                                       GH3X2X_MP_LOG_L1("Gh3x2x mp PPG test fail, Noise test handle rawdata error, error code is: %d! \r\n", test_code);\r
+                                       return test_code;\r
+                               }\r
+                               //calc noise, averge rawdata\r
+                               gh3x2x_demo_mp_calc_noise(GH3x2xMp_RawdataHandleArr, pstTestPara->PPG_NoiseRawdata_Num, &pstTestResult->stNoiseRawHandleResult.AvergeRawdata[usChannel], \\r
+                                                                                                               &pstTestResult->stNoiseRawHandleResult.Noise[usChannel]);\r
+                               HPF_FirstFlag = 1;\r
+                               for(int k = 0; k < pstTestPara->PPG_NoiseRawdata_Num; k++)\r
+                               {\r
+                                       GH3x2xMp_RawdataHandleArr[k] = gh3x2x_mp_high_pass_filter((GD64)GH3x2xMp_RawdataHandleArr[k]); //filter\r
+                               }\r
+                               //calc noise, averge rawdata after filter\r
+                               gh3x2x_demo_mp_calc_noise(GH3x2xMp_RawdataHandleArr, pstTestPara->PPG_NoiseRawdata_Num, &AvergeRawdata_temp, &Noise_temp);\r
+                               \r
+                               //only need noise in filter  \r
+                               pstTestResult->stNoiseRawHandleResult.Noise[usChannel] = RAWDATA_TO_VOL((GD64)Noise_temp);\r
+                               pstTestResult->LED_Noise[usChannel] = pstTestResult->stNoiseRawHandleResult.Noise[usChannel];\r
+                               \r
+                               //check noise whether over limit\r
+                               if((pstTestResult->LED_Noise[usChannel] > stGh3x2xMpLimit.PPG_Noise_MaxLimit) \\r
+                                       || ((GD64)pstTestResult->LED_Noise[usChannel] <= 0.00001))\r
+                               {\r
+                                       test_code = MT_ERROR_LP_NOISE_ABNORMAL;\r
+                                       GH3X2X_MP_LOG_L1("Gh3x2x mp PPG test fail, Noise[%d]: %.5f more than max limit: %.5f or less than 0.00001, error code is: %d! \r\n", usChannel, \\r
+                                                                                       pstTestResult->LED_Noise[usChannel], stGh3x2xMpLimit.PPG_Noise_MaxLimit, test_code);\r
+                               }\r
+                               else\r
+                               {\r
+                                       GH3X2X_MP_LOG_L2("Gh3x2x mp PPG test result info, Noise[%d] is: %.5f, max limit is: %.5f, Noise test is pass! \r\n", usChannel, \\r
+                                                                                       pstTestResult->LED_Noise[usChannel], stGh3x2xMpLimit.PPG_Noise_MaxLimit);\r
+                               }\r
+                       }\r
+               }\r
+       }\r
+\r
+       GH3X2X_MP_LOG_L2("Gh3x2x mp PPG--Noise test end! \r\n");\r
+       return test_code;\r
+}\r
+\r
+/**\r
+ * @fn     GU8 gh3x2x_demo_mp_PPG_BaseNoise_Test(stGh3x2xMp_PPGTestParam *pstTestPara, stGh3x2xMp_PPGTestResult *pstTestResult)\r
+ *\r
+ * @brief  PPG test items ----base noise test\r
+ *\r
+ * @attention   base noise test has nothing to do with LEDs, so only one slot is needed to test the data of 4 PDs.\r
+ *\r
+ * @param[in]   stGh3x2xMp_PPGTestParam *pstTestPara, stGh3x2xMp_PPGTestResult *pstTestResult\r
+ * @param[out]  \r
+ *\r
+ * @return  error code\r
+ */\r
+GU8 gh3x2x_demo_mp_PPG_BaseNoise_Test(stGh3x2xMp_PPGTestParam *pstTestPara, stGh3x2xMp_PPGTestResult *pstTestResult)\r
+{\r
+       GU8 test_code = 0;\r
+       GU8 i = 0;\r
+       GU8 j = 0;\r
+       GH3X2X_MP_LOG_L2("Gh3x2x mp PPG--BaseNoise test start! \r\n");\r
+\r
+       //GS32 PPG_RawdataArr[MAX_PPG_RAWDATA_SAMPLE_NUM] = {0};\r
+       GU32 RawdataBuf_Len = 0;\r
+       memset(GH3x2xMp_RawdataBuf, 0, RAWDATA_BUF_SIZE*sizeof(GU8));\r
+       if((pstTestPara->PPG_BaseNoiseRawdata_Num > MAX_PPG_RAWDATA_SAMPLE_NUM) \\r
+               || (0 == pstTestPara->PPG_BaseNoiseRawdata_Num)) //max is MAX_PPG_RAWDATA_SAMPLE_NUM\r
+       {\r
+               test_code = MT_ERROR_LPBASE_NOISE_ABNORMAL;\r
+               GH3X2X_MP_LOG_L1("Gh3x2x mp PPG test fail, BaseNoise test set the number of samples over limit, error code is: %d! \r\n", test_code);\r
+               return test_code;\r
+       }\r
+       \r
+       GU8 Slot_Cfg_EN = 0x01; //only open one slot\r
+       GU8 PD_Channel_EN = pstTestPara->stLEDPDConfig.PD_Channel_AllSlot; //PD channel to be tested\r
+       GU8 LED_PD_NUM = pstTestPara->stLEDPDConfig.PD_Num_AllSlot; //Number of PD to be tested\r
+       \r
+       //tset before operation, chip resume\r
+       gh3x2x_demo_mp_send_cmd(GH3X2X_MP_CMD_RESUME);\r
+       gh3x2x_mp_delay_ms(5);\r
+       \r
+       if(!gh3x2x_demo_mp_set_chip_config(stGh3x2xMpRegPPGConfig, sizeof(stGh3x2xMpRegPPGConfig) / sizeof(stGh3x2xMpRegPPGConfig[0])))\r
+       {\r
+               test_code = MT_ERROR_COMMUNICATE_FAIL;\r
+               GH3X2X_MP_LOG_L1("Gh3x2x mp PPG test fail, BaseNoise test set reg config fail, error code is: %d! \r\n", test_code);\r
+               return test_code;\r
+       }\r
+       //according to SLOT_CFG_EN cal which slots need to be enabled, and enable slot\r
+       GU8 SlotEnableNum = 0;\r
+       if(!gh3x2x_demo_mp_set_slot_enable(Slot_Cfg_EN, &SlotEnableNum) || SlotEnableNum < 1)\r
+       {\r
+               test_code = MT_ERROR_COMMUNICATE_FAIL;\r
+               GH3X2X_MP_LOG_L1("Gh3x2x mp PPG test fail, BaseNoise test set slot enable fail, error code is: %d! \r\n", test_code);\r
+               return test_code;\r
+       }\r
+       \r
+       for(i = 0; i < MAX_SLOT_NUM; i++) //Timeslot register configuration, slot_cfgx corresponds to LEDx\r
+       {\r
+               if ((Slot_Cfg_EN >> i) & 0x01)\r
+        {\r
+                       pstTestPara->stBaseNoiseSlotConfig.Slot_Cfg_N = i;\r
+                       pstTestPara->stBaseNoiseSlotConfig.PD_N = PD_Channel_EN;\r
+                       pstTestPara->stBaseNoiseSlotConfig.ADC_N = i % 4; //ADC only value is 0~3\r
+                       pstTestPara->stBaseNoiseSlotConfig.LED_N = i; //Use the same LED for different slots in the same test\r
+\r
+            if(!gh3x2x_demo_mp_set_slot_config(pstTestPara->stBaseNoiseSlotConfig))\r
+                       {\r
+                               test_code = MT_ERROR_COMMUNICATE_FAIL;\r
+                               GH3X2X_MP_LOG_L1("Gh3x2x mp PPG test fail, BaseNoise test set slot config fail, error code is: %d! \r\n", test_code);\r
+                               return test_code;\r
+                       } \r
+               }\r
+       }\r
+       \r
+       //get rawdata\r
+       gh3x2x_demo_mp_sampling_mode(START_SAMPLING); //start\r
+       RawdataBuf_Len = (pstTestPara->PPG_BaseNoiseRawdata_Num + pstTestPara->PPG_BaseNoiseRawdata_SkipNum)*LED_PD_NUM;\r
+       if(!gh3x2x_demo_mp_get_rawdata(0xAAAA, GH3x2xMp_RawdataBuf, RawdataBuf_Len*4)) //every rawdata have 4 bytes\r
+       {\r
+               gh3x2x_demo_mp_sampling_mode(STOP_SAMPLING); //stop\r
+               test_code = MT_ERROR_COMMUNICATE_FAIL;\r
+               GH3X2X_MP_LOG_L1("Gh3x2x mp PPG test fail, BaseNoise test read rawdata error, error code is: %d! \r\n", test_code);\r
+               return test_code;\r
+       }\r
+       gh3x2x_demo_mp_sampling_mode(STOP_SAMPLING); //stop\r
+\r
+       GU16 usChannel = 0; //only 0~31, LED(x) PD(y) channel is:x*MAX_ADC_NUM + y\r
+       for (i = 0; i < MAX_SLOT_NUM; i++)\r
+       {\r
+               if (!((Slot_Cfg_EN >> i) & 0x01))//Only calculate the slots that need to be tested\r
+               {\r
+                       continue;\r
+               }\r
+               for(j = 0; j < MAX_ADC_NUM; j++)\r
+               {\r
+                       if((PD_Channel_EN >> j) & 0x01) //Only calculate the PD that needs to be tested\r
+                       {\r
+                               if(SLOT_MULTICH_MODE == pstTestPara->stBaseNoiseSlotConfig.Slot_Mode)\r
+                                       usChannel = i*MAX_ADC_NUM + j;\r
+                               else\r
+                                       usChannel = j;\r
+                               \r
+                               //handle rawdata\r
+                               memset(GH3x2xMp_RawdataHandleArr, 0, MAX_PPG_RAWDATA_SAMPLE_NUM*sizeof(GS32));\r
+                               if(!gh3x2x_demo_mp_handle_rawdata(SPEC_MODE_PPG, GH3x2xMp_RawdataHandleArr, pstTestPara->PPG_BaseNoiseRawdata_SkipNum, \\r
+                                                                                                                       i, j, GH3x2xMp_RawdataBuf, RawdataBuf_Len, 1))\r
+                               {\r
+                                       test_code = MT_ERROR_LPBASE_NOISE_ABNORMAL;\r
+                                       GH3X2X_MP_LOG_L1("Gh3x2x mp PPG test fail, BaseNoise test handle rawdata error, error code is: %d! \r\n", test_code);\r
+                                       return test_code;\r
+                               }\r
+                               //calc noise, averge rawdata\r
+                               gh3x2x_demo_mp_calc_noise(GH3x2xMp_RawdataHandleArr, pstTestPara->PPG_BaseNoiseRawdata_Num, \\r
+                                                                                 &pstTestResult->stBaseNoiseRawHandleResult.AvergeRawdata[usChannel], &pstTestResult->stBaseNoiseRawHandleResult.Noise[usChannel]);\r
+                               pstTestResult->stBaseNoiseRawHandleResult.Noise[usChannel] = RAWDATA_TO_VOL((GD64)pstTestResult->stBaseNoiseRawHandleResult.Noise[usChannel]);\r
+                               \r
+                               pstTestResult->LED_BaseNoise[usChannel] = pstTestResult->stBaseNoiseRawHandleResult.Noise[usChannel];\r
+                               pstTestResult->LED_DCOffset[usChannel] = RAWDATA_TO_VOL((GD64)pstTestResult->stBaseNoiseRawHandleResult.AvergeRawdata[usChannel] - ADC_OFFSET) / 1000; //Unit is mV\r
+                               \r
+                               //check base noise\r
+                               if((pstTestResult->LED_BaseNoise[usChannel] > stGh3x2xMpLimit.PPG_BaseNoise_MaxLimit) \\r
+                                       || ((GD64)pstTestResult->LED_BaseNoise[usChannel] <= 0.00001))\r
+                               {\r
+                                       test_code = MT_ERROR_LPBASE_NOISE_ABNORMAL;\r
+                                       GH3X2X_MP_LOG_L1("Gh3x2x mp PPG test fail, BaseNoise[%d]: %.5f more than max limit: %.5f or less than 0.00001, error code is: %d! \r\n", usChannel, \\r
+                                                                                       pstTestResult->LED_BaseNoise[usChannel], stGh3x2xMpLimit.PPG_BaseNoise_MaxLimit, test_code);\r
+                               }\r
+                               else\r
+                               {\r
+                                       GH3X2X_MP_LOG_L2("Gh3x2x mp PPG test result info, BaseNoise[%d] is: %.5f, max limit is: %.5f, BaseNoise test is pass! \r\n", usChannel, \\r
+                                                                                       pstTestResult->LED_BaseNoise[usChannel], stGh3x2xMpLimit.PPG_BaseNoise_MaxLimit);\r
+                               }\r
+                               \r
+                               //check dc_offset\r
+                               if((pstTestResult->LED_DCOffset[usChannel] < stGh3x2xMpLimit.PPG_DCOffset_MinLimit) \\r
+                                       || (pstTestResult->LED_DCOffset[usChannel] > stGh3x2xMpLimit.PPG_DCOffset_MaxLimit))\r
+                               {\r
+                                       test_code = MT_ERROR_LPBASE_DC_OFFSET_ABNORMAL;\r
+                                       GH3X2X_MP_LOG_L1("Gh3x2x mp PPG test fail, BaseDCOffset[%d]: %.5f more than max limit: %.5f or less than min limit: %.5f, error code is: %d! \r\n", \\r
+                                                                                       usChannel, pstTestResult->LED_DCOffset[usChannel], stGh3x2xMpLimit.PPG_DCOffset_MaxLimit, \\r
+                                                                                       stGh3x2xMpLimit.PPG_DCOffset_MinLimit, test_code);\r
+                               }\r
+                               else\r
+                               {\r
+                                       GH3X2X_MP_LOG_L2("Gh3x2x mp PPG test result info, BaseDCOffset[%d] is: %.5f, max limit is: %.5f and min limit is: %.5f, BaseDCOffset test is pass! \r\n", \\r
+                                                                               usChannel, pstTestResult->LED_DCOffset[usChannel], stGh3x2xMpLimit.PPG_DCOffset_MaxLimit, stGh3x2xMpLimit.PPG_DCOffset_MinLimit);\r
+                               }\r
+                       }\r
+               }\r
+       }\r
+       \r
+       GH3X2X_MP_LOG_L2("Gh3x2x mp PPG--BaseNoise test end! \r\n");\r
+       return test_code;\r
+}\r
+\r
+/**\r
+ * @fn     GU8 gh3x2x_demo_mp_PPG_LeakLight_Test(stGh3x2xMp_PPGTestParam *pstTestPara, stGh3x2xMp_PPGTestResult *pstTestResult)\r
+ *\r
+ * @brief  PPG test items ----leak light test\r
+ *\r
+ * @attention  \r
+ *\r
+ * @param[in]   stGh3x2xMp_PPGTestParam *pstTestPara, stGh3x2xMp_PPGTestResult *pstTestResult\r
+ * @param[out]  \r
+ *\r
+ * @return  error code\r
+ */\r
+GU8 gh3x2x_demo_mp_PPG_LeakLight_Test(stGh3x2xMp_PPGTestParam *pstTestPara, stGh3x2xMp_PPGTestResult *pstTestResult)\r
+{\r
+       GU8 test_code = 0;\r
+       GU8 i = 0;\r
+       GU8 j = 0;\r
+       GH3X2X_MP_LOG_L2("Gh3x2x mp PPG--LeakLight test start! \r\n");\r
+       \r
+       //GS32 PPG_RawdataArr[MAX_PPG_RAWDATA_SAMPLE_NUM] = {0};\r
+       GU32 RawdataBuf_Len = 0;\r
+       memset(GH3x2xMp_RawdataBuf, 0, RAWDATA_BUF_SIZE*sizeof(GU8));\r
+       if((pstTestPara->PPG_LeakLightRawdata_Num > MAX_PPG_RAWDATA_SAMPLE_NUM) \\r
+               || (0 == pstTestPara->PPG_LeakLightRawdata_Num)) //max is MAX_PPG_RAWDATA_SAMPLE_NUM\r
+       {\r
+               test_code = MT_ERROR_LEAK_LEDLP_RAWDATA_ABNORMAL;\r
+               GH3X2X_MP_LOG_L1("Gh3x2x mp PPG test fail, LeakLight test set the number of samples over limit, error code is: %d! \r\n", test_code);\r
+               return test_code;\r
+       }\r
+       \r
+       GU8 Slot_Cfg_EN = 0;\r
+       GU8 LED_PD_NUM = 0; //Number of LED*PD to be tested\r
+       if(SLOT_ONECH_MODE == pstTestPara->stLeakLightSlotConfig.Slot_Mode)\r
+               LED_PD_NUM = pstTestPara->stLEDPDConfig.PD_Num[0];\r
+       else //SLOT_MULTICH_MODE\r
+               LED_PD_NUM = pstTestPara->stLEDPDConfig.LED_PD_Num;\r
+       \r
+       //must up the rubber before test\r
+       GU8 prompt_msg[] = PPG_PROMPT_UP_RUBBER_MSG;\r
+       gh3x2x_mp_prompt_message(prompt_msg, sizeof(prompt_msg) / sizeof(GU8));\r
+       \r
+       //tset before operation, chip resume\r
+       gh3x2x_demo_mp_send_cmd(GH3X2X_MP_CMD_RESUME);\r
+       gh3x2x_mp_delay_ms(5);\r
+       \r
+       if(!gh3x2x_demo_mp_set_chip_config(stGh3x2xMpRegPPGConfig, sizeof(stGh3x2xMpRegPPGConfig) / sizeof(stGh3x2xMpRegPPGConfig[0])))\r
+       {\r
+               test_code = MT_ERROR_COMMUNICATE_FAIL;\r
+               GH3X2X_MP_LOG_L1("Gh3x2x mp PPG test fail, LeakLight test set reg config fail, error code is: %d! \r\n", test_code);\r
+               return test_code;\r
+       }\r
+       \r
+       //according to SLOT_CFG_EN cal which slots need to be enabled, and enable slot\r
+       GU8 SlotEnableNum = 0;\r
+       Slot_Cfg_EN = pstTestPara->stLEDPDConfig.LED_Channel;\r
+       if(!gh3x2x_demo_mp_set_slot_enable(Slot_Cfg_EN, &SlotEnableNum) || SlotEnableNum < 1)\r
+       {\r
+               test_code = MT_ERROR_COMMUNICATE_FAIL;\r
+               GH3X2X_MP_LOG_L1("Gh3x2x mp PPG test fail, LeakLight test set slot enable fail, error code is: %d! \r\n", test_code);\r
+               return test_code;\r
+       }\r
+       \r
+       for (i = 0; i < MAX_SLOT_NUM; i++) ////Timeslot register configuration, slot_cfgx corresponds to LEDx\r
+       {\r
+               if ((Slot_Cfg_EN >> i) & 0x01)\r
+               {\r
+                       pstTestPara->stLeakLightSlotConfig.Slot_Cfg_N = i;\r
+                       pstTestPara->stLeakLightSlotConfig.PD_N = pstTestPara->stLEDPDConfig.PD_Channel[i];\r
+                       pstTestPara->stLeakLightSlotConfig.ADC_N = i % 4; //ADC only value is 0~3\r
+                       pstTestPara->stLeakLightSlotConfig.LED_N = i; //Use the same LED for different slots in the same test\r
+\r
+            if(!gh3x2x_demo_mp_set_slot_config(pstTestPara->stLeakLightSlotConfig))\r
+                       {\r
+                               test_code = MT_ERROR_COMMUNICATE_FAIL;\r
+                               GH3X2X_MP_LOG_L1("Gh3x2x mp PPG test fail, LeakLight test set slot config fail, error code is: %d! \r\n", test_code);\r
+                               return test_code;\r
+                       } \r
+               }\r
+       }\r
+       \r
+       //get rawdata\r
+       gh3x2x_demo_mp_sampling_mode(START_SAMPLING); //start\r
+       RawdataBuf_Len = (pstTestPara->PPG_LeakLightRawdata_Num + pstTestPara->PPG_LeakLightRawdata_SkipNum)*LED_PD_NUM;\r
+       if(!gh3x2x_demo_mp_get_rawdata(0xAAAA, GH3x2xMp_RawdataBuf, RawdataBuf_Len*4)) //every rawdata have 4 bytes\r
+       {\r
+               gh3x2x_demo_mp_sampling_mode(STOP_SAMPLING); //stop\r
+               test_code = MT_ERROR_COMMUNICATE_FAIL;\r
+               GH3X2X_MP_LOG_L1("Gh3x2x mp PPG test fail, LeakLight test read rawdata error, error code is: %d! \r\n", test_code);\r
+               return test_code;\r
+       }\r
+       gh3x2x_demo_mp_sampling_mode(STOP_SAMPLING); //stop\r
+       \r
+       GU16 usChannel = 0; //only 0~31, LED(x) PD(y) channel is:x*MAX_ADC_NUM + y\r
+       for (i = 0; i < MAX_SLOT_NUM; i++)\r
+       {\r
+               if (!((Slot_Cfg_EN >> i) & 0x01))//Only calculate the slots that need to be tested\r
+               {\r
+                       continue;\r
+               }\r
+               for(j = 0; j < MAX_ADC_NUM; j++)\r
+               {\r
+                       if((pstTestPara->stLEDPDConfig.PD_Channel[i] >> j) & 0x01) //Only calculate the PD that needs to be tested\r
+                       {\r
+                               if(SLOT_MULTICH_MODE == pstTestPara->stLeakLightSlotConfig.Slot_Mode)\r
+                                       usChannel = i*MAX_ADC_NUM + j;\r
+                               else\r
+                                       usChannel = j;\r
+                               \r
+                               //handle rawdata\r
+                               memset(GH3x2xMp_RawdataHandleArr, 0, MAX_PPG_RAWDATA_SAMPLE_NUM*sizeof(GS32));\r
+                               if(!gh3x2x_demo_mp_handle_rawdata(SPEC_MODE_PPG, GH3x2xMp_RawdataHandleArr, pstTestPara->PPG_LeakLightRawdata_SkipNum, \\r
+                                                                                                               i, j, GH3x2xMp_RawdataBuf, RawdataBuf_Len, 1))\r
+                               {\r
+                                       test_code = MT_ERROR_LEAK_LEDLP_RAWDATA_ABNORMAL;\r
+                                       GH3X2X_MP_LOG_L1("Gh3x2x mp PPG test fail, LeakLight test handle rawdata error, error code is: %d! \r\n", test_code);\r
+                                       return test_code;\r
+                               }\r
+                               \r
+                               //calc noise, averge rawdata\r
+                               gh3x2x_demo_mp_calc_noise(GH3x2xMp_RawdataHandleArr, pstTestPara->PPG_LeakLightRawdata_Num, \\r
+                                                                                 &pstTestResult->stLeakLightRawHandleResult.AvergeRawdata[usChannel + LED0_LLPRAWDATA_INDEX], &pstTestResult->stLeakLightRawHandleResult.Noise[usChannel + LED0_LLPRAWDATA_INDEX]);\r
+                               //calc leak light CTR\r
+                               pstTestResult->LED_LLPCTR[usChannel] = gh3x2x_demo_mp_calc_LPCTR(pstTestResult->stLeakLightRawHandleResult.AvergeRawdata[usChannel + LED0_LLPRAWDATA_INDEX], \\r
+                                                                                                                                                               pstTestPara->stLeakLightSlotConfig.TIA_RF, pstTestPara->stLeakLightSlotConfig.LED_Drv);\r
+                               \r
+                               if(((GD64)pstTestResult->LED_LPCTR[usChannel] > 0.00001) \\r
+                                       && ((GD64)stGh3x2xMpLimit.PPG_LeakRatio_Throld[usChannel] > 0.00001)) //check LPCTR and LeakRatio limit whether > 0\r
+                               {\r
+                                       pstTestResult->LED_LeakRatio[usChannel] = pstTestResult->LED_LLPCTR[usChannel] / pstTestResult->LED_LPCTR[usChannel];\r
+                                       if(pstTestResult->LED_LeakRatio[usChannel] > stGh3x2xMpLimit.PPG_LeakRatio_Throld[usChannel] \\r
+                                               && pstTestResult->LED_LLPCTR[usChannel] > stGh3x2xMpLimit.PPG_LeakCTR_MaxLimit[usChannel])\r
+                                       {\r
+                                               //Requires two conditions to over limit, the test is fail\r
+                                               test_code = MT_ERROR_LEAK_AVGER_ERR;\r
+                                               GH3X2X_MP_LOG_L1("Gh3x2x mp PPG test fail, LeakCTR[%d]: %.5f more than max limit: %.5f and LeakRadio[%d]: %.5f more than max limit: %.5f, error code is: %d! \r\n", \\r
+                                                                                       usChannel, pstTestResult->LED_LLPCTR[usChannel], stGh3x2xMpLimit.PPG_LeakCTR_MaxLimit[usChannel], \\r
+                                                                                       usChannel, pstTestResult->LED_LeakRatio[usChannel], stGh3x2xMpLimit.PPG_LeakRatio_Throld[usChannel], test_code);\r
+                                       }\r
+                                       else\r
+                                       {\r
+                                               GH3X2X_MP_LOG_L2("Gh3x2x mp PPG test result info, LeakCTR[%d] is: %.5f, max limit is: %.5f, and LeakRadio[%d] is: %.5f, max limit: %.5f, LeakLight test is pass! \r\n", \\r
+                                                                                       usChannel, pstTestResult->LED_LLPCTR[usChannel], stGh3x2xMpLimit.PPG_LeakCTR_MaxLimit[usChannel], \\r
+                                                                                       usChannel, pstTestResult->LED_LeakRatio[usChannel], stGh3x2xMpLimit.PPG_LeakRatio_Throld[usChannel]);\r
+                                       }\r
+                               }\r
+                               else\r
+                               {\r
+                                       test_code = MT_ERROR_LEAK_AVGER_ERR;\r
+                                       GH3X2X_MP_LOG_L1("Gh3x2x mp PPG test fail, LPCTR: %.5f or LeakRatio_Throld: %.3f less than 0.00001, error code is: %d! \r\n", \\r
+                                                                               pstTestResult->LED_LPCTR[usChannel], stGh3x2xMpLimit.PPG_LeakRatio_Throld[usChannel], test_code);\r
+                                       pstTestResult->LED_LeakRatio[usChannel] = 0;\r
+                               }\r
+                               \r
+                       }\r
+               }\r
+       }\r
+       \r
+       GH3X2X_MP_LOG_L2("Gh3x2x mp PPG--LeakLight test end! \r\n");\r
+       return test_code;\r
+\r
+}\r
+\r
+/**\r
+ * @fn     GU8 gh3x2x_demo_mp_ECG_LeadOnOff_Test(stGh3x2xMp_ECGTestParam *pstTestPara, stGh3x2xMp_ECGTestResult *pstTestResult)\r
+ *\r
+ * @brief  ECG test items ----Lead on/off test\r
+ *\r
+ * @attention  \r
+ *\r
+ * @param[in]   stGh3x2xMp_ECGTestParam *pstTestPara, stGh3x2xMp_ECGTestResult *pstTestResult\r
+ * @param[out]  \r
+ *\r
+ * @return  error code\r
+ */\r
+GU8 gh3x2x_demo_mp_ECG_LeadOnOff_Test(stGh3x2xMp_ECGTestParam *pstTestPara, stGh3x2xMp_ECGTestResult *pstTestResult)\r
+{\r
+       GU8 test_code = 0;\r
+       GU8 i = 0;\r
+       GU8 retry_times = 3;\r
+       GU8 ret_lead_on = 1;\r
+       GU8 ret_lead_off = 1;\r
+       GH3X2X_MP_LOG_L2("Gh3x2x mp ECG--LeadOnOff test start! \r\n");\r
+       \r
+       GU32 sample_num = pstTestPara->stECGSignal_LeadOnOff.Rawdata_Num;\r
+       GU32 skip_num = pstTestPara->stECGSignal_LeadOnOff.Rawdata_SkipNum;\r
+       GU32 RawdataBuf_Len = 0;\r
+       memset(GH3x2xMp_RawdataBuf, 0, RAWDATA_BUF_SIZE*sizeof(GU8));\r
+       memset(GH3x2xMp_RawdataHandleArr, 0, MAX_RAWDATA_SAMPLE_NUM*sizeof(GS32));\r
+       \r
+       if((sample_num > MAX_RAWDATA_SAMPLE_NUM) || (sample_num <= 0))\r
+       {\r
+               test_code = MT_ERROR_ECG_LEADONOFF_ERR;\r
+               GH3X2X_MP_LOG_L1("Gh3x2x mp ECG test fail, lead on/off test set the number of samples over limit, error code is: %d! \r\n", test_code);\r
+               return test_code;\r
+       }\r
+       \r
+       //lead on test\r
+       //set ecg relay io status---lead on\r
+       if(!gh3x2x_mp_ecg_signal_and_io_status_set(ECG_SIGNAL_AND_IO_STATUS_LEAD_ON, pstTestPara->stECGSignal_LeadOnOff, NONE_SPEC))\r
+       {\r
+               test_code = MT_ERROR_ECG_NOISE_ERR;\r
+               GH3X2X_MP_LOG_L1("Gh3x2x mp ECG test fail, lead on test set ecg io status fail, error code is: %d! \r\n", test_code);\r
+               return test_code;\r
+       }\r
+       \r
+       //rst gh3x2x,set low and set high later\r
+       gh3x2x_demo_mp_reset_operation();\r
+       \r
+       //wait int\r
+       //ret_lead_on = gh3x2x_demo_mp_wait_for_int(0x00, 100);\r
+       \r
+       if(!gh3x2x_demo_mp_set_chip_config(stGh3x2xMpRegECGLeadConfg, sizeof(stGh3x2xMpRegECGLeadConfg) / sizeof(stGh3x2xReg)))\r
+       {\r
+               test_code = MT_ERROR_COMMUNICATE_FAIL;\r
+               GH3X2X_MP_LOG_L1("Gh3x2x mp ECG test fail, lead on/off test set reg config fail, error code is: %d! \r\n", test_code);\r
+               return test_code;\r
+       }\r
+       \r
+       \r
+       if(!gh3x2x_demo_mp_wait_for_int(0x02, 500))\r
+       {\r
+               ret_lead_on = 0;\r
+               GH3X2X_MP_LOG_L1("Gh3x2x mp ECG test fail, lead on fail! \r\n");\r
+       }\r
+       \r
+       //lead off test\r
+       //write reg\r
+       for(i = 0; i < retry_times; i++)\r
+       {\r
+               gh3x2x_demo_mp_write_reg(0x000A, 0x0020); //Test FIFO threshold can be adjusted down\r
+               gh3x2x_demo_mp_write_reg(0x0108, 0x0001); //slotcfg0 enable\r
+               if((0x0020 == gh3x2x_demo_mp_read_reg(0x000A)) && (0x0001 == gh3x2x_demo_mp_read_reg(0x0108)))\r
+               {\r
+                       break;\r
+               }\r
+       }\r
+       if( i == retry_times)\r
+       {\r
+               test_code = MT_ERROR_COMMUNICATE_FAIL;\r
+               GH3X2X_MP_LOG_L1("Gh3x2x mp ECG test fail, lead on/off test write reg fail, error code is: %d! \r\n", test_code);\r
+               return test_code;\r
+       }\r
+       \r
+       //set ecg relay io status---lead off\r
+       if(!gh3x2x_mp_ecg_signal_and_io_status_set(ECG_SIGNAL_AND_IO_STATUS_LEAD_OFF, pstTestPara->stECGSignal_LeadOnOff, NONE_SPEC))\r
+       {\r
+               test_code = MT_ERROR_ECG_NOISE_ERR;\r
+               GH3X2X_MP_LOG_L1("Gh3x2x mp ECG test fail, lead off test set ecg io status fail, error code is: %d! \r\n", test_code);\r
+               return test_code;\r
+       }\r
+       \r
+       //get rawdata\r
+       gh3x2x_demo_mp_sampling_mode(START_SAMPLING); //start\r
+       RawdataBuf_Len = sample_num + skip_num;\r
+       if(!gh3x2x_demo_mp_get_rawdata(0xAAAA, GH3x2xMp_RawdataBuf, RawdataBuf_Len*4)) //every rawdata have 4 bytes\r
+       {\r
+               gh3x2x_demo_mp_sampling_mode(STOP_SAMPLING); //stop\r
+               test_code = MT_ERROR_COMMUNICATE_FAIL;\r
+               GH3X2X_MP_LOG_L1("Gh3x2x mp ECG test fail, lead on/off test read rawdata error, error code is: %d! \r\n", test_code);\r
+               return test_code;\r
+       }\r
+       gh3x2x_demo_mp_sampling_mode(STOP_SAMPLING); //stop\r
+       \r
+       //lead off test according to GH3x2xMp_RawdataBuf\r
+       GH3X2X_Memcpy(GH3x2xMp_RawdataHandleArr, GH3x2xMp_RawdataBuf + skip_num*4, sample_num*sizeof(GS32));\r
+       GU16 temp = 0;\r
+       if(0 == gh3x2x_mp_ecg_lead_off_dectection(GH3x2xMp_RawdataHandleArr, sample_num, 3, &temp))\r
+       {\r
+               ret_lead_off = 0;\r
+               GH3X2X_MP_LOG_L1("Gh3x2x mp ECG test fail, lead off detect fail! \r\n");\r
+       }\r
+       \r
+       //print rawdata\r
+       gh3x2x_demo_mp_handle_rawdata(SPEC_MODE_ECG, GH3x2xMp_RawdataHandleArr, skip_num, 0, 3, GH3x2xMp_RawdataBuf, RawdataBuf_Len, 1);\r
+       \r
+       if(!ret_lead_on || !ret_lead_off)\r
+       {\r
+               test_code = MT_ERROR_ECG_LEADONOFF_ERR;\r
+               GH3X2X_MP_LOG_L1("Gh3x2x mp ECG test fail, lead on/off test fail, error code is: %d! \r\n", test_code);\r
+       }\r
+       else\r
+       {\r
+               GH3X2X_MP_LOG_L2("Gh3x2x mp ECG test result info, lead on/off test pass! \r\n");\r
+       }\r
+       \r
+       \r
+       GH3X2X_MP_LOG_L2("Gh3x2x mp ECG--LeadOnOff test end! \r\n");\r
+       return test_code;\r
+\r
+}\r
+\r
+/**\r
+ * @fn     GU8 gh3x2x_demo_mp_ECG_Noise_Test(stGh3x2xMp_ECGTestParam *pstTestPara, stGh3x2xMp_ECGTestResult *pstTestResult)\r
+ *\r
+ * @brief  ECG test items ----Noise test\r
+ *\r
+ * @attention  \r
+ *\r
+ * @param[in]   stGh3x2xMp_ECGTestParam *pstTestPara, stGh3x2xMp_ECGTestResult *pstTestResult\r
+ * @param[out]  \r
+ *\r
+ * @return  error code\r
+ */\r
+GU8 gh3x2x_demo_mp_ECG_Noise_Test(stGh3x2xMp_ECGTestParam *pstTestPara, stGh3x2xMp_ECGTestResult *pstTestResult)\r
+{\r
+       GU8 test_code = 0;\r
+       //GU8 i = 0;\r
+       GH3X2X_MP_LOG_L2("Gh3x2x mp ECG--Noise test start! \r\n");\r
+       \r
+       GU32 sample_num = pstTestPara->stECGSignal_Noise.Rawdata_Num;\r
+       GU32 skip_num = pstTestPara->stECGSignal_Noise.Rawdata_SkipNum;\r
+       GU32 RawdataBuf_Len = 0;\r
+       memset(GH3x2xMp_RawdataBuf, 0, RAWDATA_BUF_SIZE*sizeof(GU8));\r
+       memset(GH3x2xMp_RawdataHandleArr, 0, MAX_RAWDATA_SAMPLE_NUM*sizeof(GS32));\r
+       \r
+       //check noise test sample num must > 500 or < MAX_RAWDATA_SAMPLE_NUM\r
+       if((sample_num <= 500) || (sample_num > MAX_RAWDATA_SAMPLE_NUM))\r
+       {\r
+               test_code = MT_ERROR_ECG_NOISE_ERR;\r
+               GH3X2X_MP_LOG_L1("Gh3x2x mp ECG test fail, Noise test set the number of samples over limit(must greater than 500, \\r
+                                                       less than MAX_RAWDATA_SAMPLE_NUM), error code is: %d! \r\n", test_code);\r
+               return test_code;\r
+       }\r
+       \r
+       //set ecg io status---noise test\r
+       if(!gh3x2x_mp_ecg_signal_and_io_status_set(ECG_SIGNAL_AND_IO_STATUS_NOISE, pstTestPara->stECGSignal_Noise, NONE_SPEC))\r
+       {\r
+               test_code = MT_ERROR_ECG_NOISE_ERR;\r
+               GH3X2X_MP_LOG_L1("Gh3x2x mp ECG test fail, Noise test set ecg io status fail, error code is: %d! \r\n", test_code);\r
+               return test_code;\r
+       }\r
+       \r
+       gh3x2x_mp_delay_ms(100);\r
+       \r
+       //tset before operation, chip resume\r
+       gh3x2x_demo_mp_send_cmd(GH3X2X_MP_CMD_RESUME);\r
+       gh3x2x_mp_delay_ms(5);\r
+       \r
+       if(!gh3x2x_demo_mp_set_chip_config(stGh3x2xMpRegECGLeadConfg, sizeof(stGh3x2xMpRegECGLeadConfg) / sizeof(stGh3x2xReg)))\r
+       {\r
+               test_code = MT_ERROR_COMMUNICATE_FAIL;\r
+               GH3X2X_MP_LOG_L1("Gh3x2x mp ECG test fail, Noise test set reg lead config fail, error code is: %d! \r\n", test_code);\r
+               return test_code;\r
+       }\r
+       \r
+       if(!gh3x2x_demo_mp_set_chip_config(stGh3x2xMpRegECGConfgDefault, sizeof(stGh3x2xMpRegECGConfgDefault) / sizeof(stGh3x2xReg)))\r
+       {\r
+               test_code = MT_ERROR_COMMUNICATE_FAIL;\r
+               GH3X2X_MP_LOG_L1("Gh3x2x mp ECG test fail, Noise test set reg default config fail, error code is: %d! \r\n", test_code);\r
+               return test_code;\r
+       }\r
+       \r
+       gh3x2x_demo_mp_write_reg(0x0108, 0x0001); //slotcfg0 enable\r
+       \r
+       //get rawdata, The ECG test only collects data from one slot and ADC at a time, and LEDPDnum is fixed at 1.\r
+       gh3x2x_demo_mp_sampling_mode(START_SAMPLING); //start\r
+       gh3x2x_demo_mp_write_reg(0x1EA, 0x433); //Fast recovery, after sampling starts\r
+       RawdataBuf_Len = sample_num + skip_num;\r
+       if(!gh3x2x_demo_mp_get_rawdata(0xAAAA, GH3x2xMp_RawdataBuf, RawdataBuf_Len*4)) //every rawdata have 4 bytes\r
+       {\r
+               gh3x2x_demo_mp_sampling_mode(STOP_SAMPLING); //stop\r
+               test_code = MT_ERROR_COMMUNICATE_FAIL;\r
+               GH3X2X_MP_LOG_L1("Gh3x2x mp ECG test fail, noise test read rawdata error, error code is: %d! \r\n", test_code);\r
+               return test_code;\r
+       }\r
+       gh3x2x_demo_mp_sampling_mode(STOP_SAMPLING); //stop\r
+       \r
+       //ECG collection is fixed to slot0 ADC3, \r
+       if(!gh3x2x_demo_mp_handle_rawdata(SPEC_MODE_ECG, GH3x2xMp_RawdataHandleArr, skip_num, 0, 3, \\r
+                                                                                       GH3x2xMp_RawdataBuf, RawdataBuf_Len, 1))\r
+       {\r
+               test_code = MT_ERROR_ECG_NOISE_ERR;\r
+               GH3X2X_MP_LOG_L1("Gh3x2x mp ECG test fail, noise test handle rawdata error, error code is: %d! \r\n", test_code);\r
+               return test_code;\r
+       }\r
+       \r
+       //filter\r
+       gh3x2x_demo_mp_ecg_signal_filter(GH3x2xMp_RawdataHandleArr, sample_num, 1, 4, 1);\r
+       \r
+       //cal noise\r
+       GF32 avg_temp = 0;\r
+       gh3x2x_demo_mp_calc_noise(&GH3x2xMp_RawdataHandleArr[500], sample_num - 500, &avg_temp, &pstTestResult->ECG_Noise);\r
+       pstTestResult->ECG_Noise = pstTestResult->ECG_Noise * ADC_REFER / ADC_MAX * 1000 / GAIN;// /20; //? /GAIN\r
+       \r
+       //judge ECG_Noise whether over limit\r
+       if(pstTestResult->ECG_Noise > stGh3x2xMpLimit.ECG_Noise_MaxLimit)\r
+       {\r
+               test_code = MT_ERROR_ECG_NOISE_ERR;\r
+               GH3X2X_MP_LOG_L1("Gh3x2x mp ECG test fail, Noise: %.5f more than max limit: %.5f, error code is: %d! \r\n", \\r
+                                                       pstTestResult->ECG_Noise, stGh3x2xMpLimit.ECG_Noise_MaxLimit, test_code);\r
+               return test_code;\r
+       }\r
+       else\r
+       {\r
+               GH3X2X_MP_LOG_L2("Gh3x2x mp ECG test result info, Noise is: %.5f, max limit is: %.5f, Noise test is pass! \r\n", \\r
+                                                       pstTestResult->ECG_Noise, stGh3x2xMpLimit.ECG_Noise_MaxLimit);\r
+       }\r
+       \r
+       GH3X2X_MP_LOG_L2("Gh3x2x mp ECG--Noise test end! \r\n");\r
+       return test_code;\r
+       \r
+}\r
+\r
+/**\r
+ * @fn     GU8 gh3x2x_demo_mp_ECG_HPF_Test(stGh3x2xMp_ECGTestParam *pstTestPara, stGh3x2xMp_ECGTestResult *pstTestResult)\r
+ *\r
+ * @brief  ECG test items ----HPF test\r
+ *\r
+ * @attention  \r
+ *\r
+ * @param[in]   stGh3x2xMp_ECGTestParam *pstTestPara, stGh3x2xMp_ECGTestResult *pstTestResult\r
+ * @param[out]  \r
+ *\r
+ * @return  error code\r
+ */\r
+GU8 gh3x2x_demo_mp_ECG_HPF_Test(stGh3x2xMp_ECGTestParam *pstTestPara, stGh3x2xMp_ECGTestResult *pstTestResult)\r
+{\r
+       GU8 test_code = 0;\r
+       GU8 i = 0;\r
+       GH3X2X_MP_LOG_L2("Gh3x2x mp ECG--HPF test start! \r\n");\r
+       \r
+       GU16 sample_num = 0;\r
+       GU16 skip_num = 0;\r
+\r
+       GU32 RawdataBuf_Len = 0;\r
+       memset(GH3x2xMp_RawdataBuf, 0, RAWDATA_BUF_SIZE*sizeof(GU8));\r
+       memset(GH3x2xMp_RawdataHandleArr, 0, MAX_RAWDATA_SAMPLE_NUM*sizeof(GS32));\r
+       GU8 HPFRatio_cnt = 0;\r
+       \r
+       //HPF test must 2 signals in a group\r
+       if((pstTestPara->HPF_ECGSignalNum > ECG_MAX_SIGNAL_NUM) || (0 == pstTestPara->HPF_ECGSignalNum) \\r
+               || (0 != (pstTestPara->HPF_ECGSignalNum % 2))) //must greater than 0 and a multiple of 2, not greater than ECG_MAX_SIGNAL_NUM\r
+       {\r
+               test_code = MT_ERROR_ECG_HPF_ERR;\r
+               GH3X2X_MP_LOG_L1("Gh3x2x mp ECG test fail, HPF test set signal num error, error code is: %d! \r\n", test_code);\r
+               return test_code;\r
+       }\r
+       \r
+       \r
+       for(i = 0; i < pstTestPara->HPF_ECGSignalNum; i++)\r
+       {\r
+               sample_num = pstTestPara->stECGSignal_HPF[i].Rawdata_Num;\r
+               skip_num = pstTestPara->stECGSignal_HPF[i].Rawdata_SkipNum;\r
+               //check HPF test sample num must > 200\r
+               if((sample_num < 200) || (sample_num > MAX_RAWDATA_SAMPLE_NUM))\r
+               {\r
+                       test_code = MT_ERROR_ECG_HPF_ERR;\r
+                       GH3X2X_MP_LOG_L1("Gh3x2x mp ECG test fail, HPF test set the number of samples over limit(must greater than 200, less than MAX_RAWDATA_SAMPLE_NUM), error code is: %d! \r\n", test_code);\r
+                       return test_code;\r
+               }\r
+       \r
+               \r
+               //set ecg io status---HPF test\r
+               if(!gh3x2x_mp_ecg_signal_and_io_status_set(ECG_SIGNAL_AND_IO_STATUS_HPF, pstTestPara->stECGSignal_HPF[i], NONE_SPEC))\r
+               {\r
+                       test_code = MT_ERROR_ECG_HPF_ERR;\r
+                       GH3X2X_MP_LOG_L1("Gh3x2x mp ECG test fail, HPF test set ecg io status or signal voltage error, error code is: %d! \r\n", test_code);\r
+                       return test_code;\r
+               }\r
+               \r
+               //tset before operation, chip resume\r
+               gh3x2x_demo_mp_send_cmd(GH3X2X_MP_CMD_RESUME);\r
+               gh3x2x_mp_delay_ms(5);\r
+               \r
+               if(!gh3x2x_demo_mp_set_chip_config(stGh3x2xMpRegECGLeadConfg, sizeof(stGh3x2xMpRegECGLeadConfg) / sizeof(stGh3x2xReg)))\r
+               {\r
+                       test_code = MT_ERROR_COMMUNICATE_FAIL;\r
+                       GH3X2X_MP_LOG_L1("Gh3x2x mp ECG test fail, HPF test set reg lead config fail, error code is: %d! \r\n", test_code);\r
+                       return test_code;\r
+               }\r
+               \r
+               if(!gh3x2x_demo_mp_set_chip_config(stGh3x2xMpRegECGConfgDefault, sizeof(stGh3x2xMpRegECGConfgDefault) / sizeof(stGh3x2xReg)))\r
+               {\r
+                       test_code = MT_ERROR_COMMUNICATE_FAIL;\r
+                       GH3X2X_MP_LOG_L1("Gh3x2x mp ECG test fail, HPF test set reg default config fail, error code is: %d! \r\n", test_code);\r
+                       return test_code;\r
+               }\r
+               \r
+               gh3x2x_demo_mp_write_reg(0x0108, 0x0001); //slotcfg0 enable\r
+               \r
+               //get rawdata, The ECG test only collects data from one slot and ADC at a time, and LEDPDnum is fixed at 1.\r
+               memset(GH3x2xMp_RawdataBuf, 0, RAWDATA_BUF_SIZE*sizeof(GU8));\r
+               memset(GH3x2xMp_RawdataHandleArr, 0, MAX_RAWDATA_SAMPLE_NUM*sizeof(GS32));\r
+               gh3x2x_demo_mp_sampling_mode(START_SAMPLING); //start\r
+               //generation the other one signal channel \r
+               if(!gh3x2x_mp_ecg_signal_and_io_status_set(ECG_SIGNAL_AND_IO_STATUS_HPF, pstTestPara->stECGSignal_HPF[i], ECG_HPF_SPEC))\r
+               {\r
+                       test_code = MT_ERROR_ECG_HPF_ERR;\r
+                       GH3X2X_MP_LOG_L1("Gh3x2x mp ECG test fail, HPF test set signal voltage fail, error code is: %d! \r\n", test_code);\r
+                       return test_code;\r
+               }\r
+               RawdataBuf_Len = sample_num + skip_num;\r
+               if(!gh3x2x_demo_mp_get_rawdata(0xAAAA, GH3x2xMp_RawdataBuf, RawdataBuf_Len*4)) //every rawdata have 4 bytes\r
+               {\r
+                       gh3x2x_demo_mp_sampling_mode(STOP_SAMPLING); //stop\r
+                       test_code = MT_ERROR_COMMUNICATE_FAIL;\r
+                       GH3X2X_MP_LOG_L1("Gh3x2x mp ECG test fail, HPF test read rawdata error, error code is: %d! \r\n", test_code);\r
+                       return test_code;\r
+               }\r
+               gh3x2x_demo_mp_sampling_mode(STOP_SAMPLING); //stop\r
+       \r
+               //ECG collection is fixed to slot0 ADC3, \r
+               if(!gh3x2x_demo_mp_handle_rawdata(SPEC_MODE_ECG, GH3x2xMp_RawdataHandleArr, skip_num, 0, 3, \\r
+                                                                                               GH3x2xMp_RawdataBuf, RawdataBuf_Len, 1))\r
+               {\r
+                       test_code = MT_ERROR_ECG_HPF_ERR;\r
+                       GH3X2X_MP_LOG_L1("Gh3x2x mp ECG test fail, HPF test handle rawdata error, error code is: %d! \r\n", test_code);\r
+                       return test_code;\r
+               }\r
+               \r
+               //2 signals in a group, Calculate the latter one\r
+               if (0 == ((i + 1) % 2))\r
+               {\r
+                       GF32 ratio = gh3x2x_demo_mp_ecg_cal_HPF_Ratio(GH3x2xMp_RawdataHandleArr, sample_num);\r
+                       pstTestResult->ECG_HPFRatio[HPFRatio_cnt++] = ratio;\r
+                       if((ratio < stGh3x2xMpLimit.ECG_HPF_MinLimit) \\r
+                               || (ratio > stGh3x2xMpLimit.ECG_HPF_MaxLimit))\r
+                       {\r
+                               test_code = MT_ERROR_ECG_HPF_ERR;\r
+                               GH3X2X_MP_LOG_L1("Gh3x2x mp ECG test fail, HPF ratio%d: %.5f less than min limit: %.5f or more than max limit: %.5f, error code is: %d! \r\n", \\r
+                                                                       HPFRatio_cnt-1, ratio, stGh3x2xMpLimit.ECG_HPF_MinLimit, stGh3x2xMpLimit.ECG_HPF_MaxLimit, test_code);\r
+                       }\r
+                       else\r
+                       {\r
+                               GH3X2X_MP_LOG_L2("Gh3x2x mp ECG test result info, HPF ratio%d is: %.5f, min limit is: %.5f and max limit is: %.5f, HPF test is pass! \r\n", \\r
+                                                                       HPFRatio_cnt-1, ratio, stGh3x2xMpLimit.ECG_HPF_MinLimit, stGh3x2xMpLimit.ECG_HPF_MaxLimit);\r
+                       }\r
+               }\r
+       }\r
+       \r
+       GH3X2X_MP_LOG_L2("Gh3x2x mp ECG--HPF test end! \r\n");\r
+       return test_code;\r
+}\r
+\r
+/**\r
+ * @fn     GU8 gh3x2x_demo_mp_ECG_SIGNAL_Test(stGh3x2xMp_ECGTestParam *pstTestPara, stGh3x2xMp_ECGTestResult *pstTestResult)\r
+ *\r
+ * @brief  ECG test items ----SIGNAL test\r
+ *\r
+ * @attention  \r
+ *\r
+ * @param[in]   stGh3x2xMp_ECGTestParam *pstTestPara, stGh3x2xMp_ECGTestResult *pstTestResult\r
+ * @param[out]  \r
+ *\r
+ * @return  error code\r
+ */\r
+GU8 gh3x2x_demo_mp_ECG_SIGNAL_Test(stGh3x2xMp_ECGTestParam *pstTestPara, stGh3x2xMp_ECGTestResult *pstTestResult)\r
+{\r
+       GU8 test_code = 0;\r
+       GU32 i = 0;\r
+       GH3X2X_MP_LOG_L2("Gh3x2x mp ECG--SIGNAL test start! \r\n");\r
+       \r
+       GU16 sample_num = 0;\r
+       GU16 skip_num = 0;\r
+       GU16 sampling_step = 1;\r
+       \r
+       GU32 RawdataBuf_Len[ECG_MAX_SIGNAL_NUM] = {0};\r
+       memset(GH3x2xMp_RawdataBuf, 0, RAWDATA_BUF_SIZE*sizeof(GU8));\r
+       memset(GH3x2xMp_RawdataHandleArr, 0, MAX_RAWDATA_SAMPLE_NUM*sizeof(GS32));\r
+       \r
+       GF32 nStandardAmp = 0.0;\r
+       \r
+       //not greater than ECG_MAX_SIGNAL_NUM\r
+       if((pstTestPara->SIGNAL_ECGSignalNum > ECG_MAX_SIGNAL_NUM) || (0 == pstTestPara->SIGNAL_ECGSignalNum))\r
+       {\r
+               test_code = MT_ERROR_ECG_SIGNAL_ERR;\r
+               GH3X2X_MP_LOG_L1("Gh3x2x mp ECG test fail, SIGNAL test set signal num error, error code is: %d! \r\n", test_code);\r
+               return test_code;\r
+       }\r
+       \r
+       \r
+       for(i = 0; i < pstTestPara->SIGNAL_ECGSignalNum; i++)\r
+       {\r
+               sample_num = pstTestPara->stECGSignal_SIGNAL[i].Rawdata_Num;\r
+               skip_num = pstTestPara->stECGSignal_SIGNAL[i].Rawdata_SkipNum;\r
+               sampling_step = pstTestPara->stECGSignal_SIGNAL[i].Sampling_Step;\r
+               \r
+               //check noise test sample num\r
+               if((sample_num <= 0) || (sampling_step <= 0))\r
+               {\r
+                       test_code = MT_ERROR_ECG_SIGNAL_ERR;\r
+                       GH3X2X_MP_LOG_L1("Gh3x2x mp ECG test fail, SIGNAL test set the number of samples or sampling step <= 0, error code is: %d! \r\n", test_code);\r
+                   return test_code;\r
+               }\r
+               \r
+               //Check whether fft array need used space is in the range of GH3x2xMp_RawdataBuf\r
+               //fft array space reuse GH3x2xMp_RawdataBuf memory\r
+               if((MAX_FFT_LENGTH * 2 * 4) > (RAWDATA_BUF_SIZE / 2))\r
+               {\r
+                       test_code = MT_ERROR_ECG_SIGNAL_ERR;\r
+                       GH3X2X_MP_LOG_L1("Gh3x2x mp ECG test fail, SIGNAL test fft array need used space more than GH3x2xMp_RawdataBuf memory, error code is: %d! \r\n", test_code);\r
+                       return test_code;\r
+               }\r
+               \r
+               //set ecg io status---SIGNAL test\r
+               if(!gh3x2x_mp_ecg_signal_and_io_status_set(ECG_SIGNAL_AND_IO_STATUS_SIGNAL, pstTestPara->stECGSignal_SIGNAL[i], NONE_SPEC))\r
+               {\r
+                       test_code = MT_ERROR_ECG_SIGNAL_ERR;\r
+                       GH3X2X_MP_LOG_L1("Gh3x2x mp ECG test fail, SIGNAL test set ecg io status or signal fail, error code is: %d! \r\n", test_code);\r
+                       return test_code;\r
+               }\r
+               gh3x2x_mp_delay_ms(20); //wait\r
+               \r
+               //chip resume\r
+               gh3x2x_demo_mp_send_cmd(GH3X2X_MP_CMD_RESUME);\r
+               gh3x2x_mp_delay_ms(5);\r
+               \r
+               if(!gh3x2x_demo_mp_set_chip_config(stGh3x2xMpRegECGLeadConfg, sizeof(stGh3x2xMpRegECGLeadConfg) / sizeof(stGh3x2xReg)))\r
+               {\r
+                       test_code = MT_ERROR_COMMUNICATE_FAIL;\r
+                       GH3X2X_MP_LOG_L1("Gh3x2x mp ECG test fail, SIGNAL test set reg lead config fail, error code is: %d! \r\n", test_code);\r
+                       return test_code;\r
+               }\r
+               \r
+               if(!gh3x2x_demo_mp_set_chip_config(stGh3x2xMpRegECGConfgDefault, sizeof(stGh3x2xMpRegECGConfgDefault) / sizeof(stGh3x2xReg)))\r
+               {\r
+                       test_code = MT_ERROR_COMMUNICATE_FAIL;\r
+                       GH3X2X_MP_LOG_L1("Gh3x2x mp ECG test fail, SIGNAL test set reg default config fail, error code is: %d! \r\n", test_code);\r
+                       return test_code;\r
+               }\r
+               \r
+               gh3x2x_demo_mp_write_reg(0x0108, 0x0001); //slotcfg0 enable\r
+       \r
+               //get rawdata, The ECG test only collects data from one slot and ADC at a time, and LEDPDnum is fixed at 1.\r
+               memset(GH3x2xMp_RawdataBuf, 0, RAWDATA_BUF_SIZE*sizeof(GU8));\r
+               memset(GH3x2xMp_RawdataHandleArr, 0, MAX_RAWDATA_SAMPLE_NUM*sizeof(GS32));\r
+               gh3x2x_demo_mp_sampling_mode(START_SAMPLING); //start\r
+               gh3x2x_demo_mp_write_reg(0x1EA, 0x433); //Fast recovery, after sampling starts\r
+               RawdataBuf_Len[i] = sample_num + skip_num;\r
+               \r
+               if(!gh3x2x_demo_mp_get_rawdata(0xAAAA, GH3x2xMp_RawdataBuf, RawdataBuf_Len[i]*4)) //every rawdata have 4 bytes\r
+               {\r
+                       gh3x2x_demo_mp_sampling_mode(STOP_SAMPLING); //stop\r
+                       test_code = MT_ERROR_COMMUNICATE_FAIL;\r
+                       GH3X2X_MP_LOG_L1("Gh3x2x mp ECG test fail, SIGNAL test read rawdata error, error code is: %d! \r\n", test_code);\r
+                       return test_code;\r
+               }\r
+               gh3x2x_demo_mp_sampling_mode(STOP_SAMPLING); //stop\r
+               \r
+               //ECG collection is fixed to slot0 ADC3, \r
+               if(!gh3x2x_demo_mp_handle_rawdata(SPEC_MODE_ECG, GH3x2xMp_RawdataHandleArr, skip_num, 0, 3, GH3x2xMp_RawdataBuf, \\r
+                                                                                                       RawdataBuf_Len[i], sampling_step))\r
+               {\r
+                       test_code = MT_ERROR_ECG_SIGNAL_ERR;\r
+                       GH3X2X_MP_LOG_L1("Gh3x2x mp ECG test fail, SIGNAL test handle rawdata error, error code is: %d! \r\n", test_code);\r
+                       return test_code;\r
+               }\r
+                       \r
+               //cal\r
+               gh3x2x_demo_mp_ecg_cal_signal_amp_freq(GH3x2xMp_RawdataHandleArr, sample_num, &pstTestResult->ECG_Amp[i], &pstTestResult->ECG_Freq[i], \\r
+                                                                                                       0, 0, 1, 0, sample_num, pstTestPara->stECGSignal_SIGNAL[i].ECG_Freq, sampling_step);\r
+               \r
+               //check limit\r
+               if(i==0) //The first frequency data is processed separately\r
+        {\r
+            GF32 fTargetVpp = pstTestPara->stECGSignal_SIGNAL[i].ECG_Vol * 1000 / (GF32)5.7;\r
+                       GF32 amp_difference = fabs(1 - pstTestResult->ECG_Amp[i] / fTargetVpp);\r
+                       GF32 freq_difference = fabs(1 - pstTestResult->ECG_Freq[i] / pstTestPara->stECGSignal_SIGNAL[i].ECG_Freq);\r
+                       nStandardAmp = pstTestResult->ECG_Amp[i];\r
+            if((amp_difference > stGh3x2xMpLimit.ECG_MaxAMP) \\r
+                               || (freq_difference > stGh3x2xMpLimit.ECG_MaxFreq))\r
+                       {\r
+                               test_code = MT_ERROR_ECG_SIGNAL_ERR;\r
+                               GH3X2X_MP_LOG_L1("Gh3x2x mp ECG test fail, SIGNAL %.2fHz test difference between amp: %.5fmV or freq: %.5fHz with target amp: %.5fmV or freq: %.2f more than MaxAmpRange: %.5f or MaxFreqRange: %.5f, error code is: %d! \r\n", \\r
+                                                                       pstTestPara->stECGSignal_SIGNAL[i].ECG_Freq, pstTestResult->ECG_Amp[i], pstTestResult->ECG_Freq[i], fTargetVpp, \\r
+                                                                       pstTestPara->stECGSignal_SIGNAL[i].ECG_Freq, stGh3x2xMpLimit.ECG_MaxAMP, stGh3x2xMpLimit.ECG_MaxFreq, test_code);\r
+                       }\r
+                       else\r
+                       {\r
+                               GH3X2X_MP_LOG_L2("Gh3x2x mp ECG test result info, SIGNAL %.2fHz test difference between amp: %.5fmV freq: %.5fHz with target amp: %.5fmV freq: %.2f is pass, MaxAmpRange is: %.5f or MaxFreqRange is: %.5f !\r\n", \\r
+                                                                       pstTestPara->stECGSignal_SIGNAL[i].ECG_Freq, pstTestResult->ECG_Amp[i], pstTestResult->ECG_Freq[i], fTargetVpp, \\r
+                                                                       pstTestPara->stECGSignal_SIGNAL[i].ECG_Freq, stGh3x2xMpLimit.ECG_MaxAMP, stGh3x2xMpLimit.ECG_MaxFreq);\r
+                       }\r
+            \r
+        }\r
+        else\r
+        {\r
+                       GF32 amp_difference = fabs(1 - pstTestResult->ECG_Amp[i] / nStandardAmp);\r
+            if(amp_difference > stGh3x2xMpLimit.ECG_SIGNAL_MaxLimit)\r
+            {\r
+                               test_code = MT_ERROR_ECG_SIGNAL_ERR;\r
+                               GH3X2X_MP_LOG_L1("Gh3x2x mp ECG test fail, SIGNAL %.2fHz test difference between amp: %.5fmV with Standard amp: %.5fmV over more than MaxRange: %.5f, freq cal is: %.5fHz, error code is: %d! \r\n", \\r
+                                                                       pstTestPara->stECGSignal_SIGNAL[i].ECG_Freq, pstTestResult->ECG_Amp[i], nStandardAmp, \\r
+                                                                       stGh3x2xMpLimit.ECG_SIGNAL_MaxLimit, pstTestResult->ECG_Freq[i], test_code);\r
+                       }\r
+                       else\r
+                       {\r
+                               GH3X2X_MP_LOG_L2("Gh3x2x mp ECG test result info, SIGNAL %.2fHz test difference between amp: %.5fmV with Standard amp: %.5fmV is pass, MaxRange is: %.5f, freq cal is: %.5fHz! \r\n", \\r
+                                                                       pstTestPara->stECGSignal_SIGNAL[i].ECG_Freq, pstTestResult->ECG_Amp[i], nStandardAmp, \\r
+                                                                       stGh3x2xMpLimit.ECG_SIGNAL_MaxLimit, pstTestResult->ECG_Freq[i]);\r
+                       }\r
+        }\r
+       }\r
+       \r
+       \r
+       GH3X2X_MP_LOG_L2("Gh3x2x mp ECG--SIGNAL test end! \r\n");\r
+       return test_code;\r
+}\r
+\r
+/**\r
+ * @fn     GU8 gh3x2x_demo_mp_ECG_RLD_Test(stGh3x2xMp_ECGTestParam *pstTestPara, stGh3x2xMp_ECGTestResult *pstTestResult)\r
+ *\r
+ * @brief  ECG test items ----RLD test\r
+ *\r
+ * @attention  \r
+ *\r
+ * @param[in]   stGh3x2xMp_ECGTestParam *pstTestPara, stGh3x2xMp_ECGTestResult *pstTestResult\r
+ * @param[out]  \r
+ *\r
+ * @return  error code\r
+ */\r
+GU8 gh3x2x_demo_mp_ECG_RLD_Test(stGh3x2xMp_ECGTestParam *pstTestPara, stGh3x2xMp_ECGTestResult *pstTestResult)\r
+{\r
+       GU8 test_code = 0;\r
+       GH3X2X_MP_LOG_L2("Gh3x2x mp ECG--RLD test start! \r\n");\r
+       \r
+       GU32 sample_num = pstTestPara->stECGSignal_RLD.Rawdata_Num;\r
+       //GU32 skip_num = pstTestPara->stECGSignal_RLD.Rawdata_SkipNum;\r
+       //GU32 RawdataBuf_Len = 0;\r
+       memset(GH3x2xMp_RawdataBuf, 0, RAWDATA_BUF_SIZE*sizeof(GU8));\r
+       memset(GH3x2xMp_RawdataHandleArr, 0, MAX_RAWDATA_SAMPLE_NUM*sizeof(GS32));\r
+       \r
+       //check RLD test sample num \r
+       if((sample_num > MAX_RAWDATA_SAMPLE_NUM) || (sample_num <= 0))\r
+       {\r
+               test_code = MT_ERROR_ECG_RLD_ERR;\r
+               GH3X2X_MP_LOG_L1("Gh3x2x mp ECG test fail, RLD test set the number of samples over limit, error code is: %d! \r\n", test_code);\r
+               return test_code;\r
+       }\r
+       \r
+       //set ecg io status---RLD test\r
+       if(!gh3x2x_mp_ecg_signal_and_io_status_set(ECG_SIGNAL_AND_IO_STATUS_RLD, pstTestPara->stECGSignal_RLD, NONE_SPEC))\r
+       {\r
+               test_code = MT_ERROR_ECG_RLD_ERR;\r
+               GH3X2X_MP_LOG_L1("Gh3x2x mp ECG test fail, RLD test set ecg io status fail, error code is: %d! \r\n", test_code);\r
+               return test_code;\r
+       }\r
+       \r
+       //chip resume\r
+       gh3x2x_demo_mp_send_cmd(GH3X2X_MP_CMD_RESUME);\r
+       gh3x2x_mp_delay_ms(5);\r
+       if(!gh3x2x_demo_mp_set_chip_config(stGh3x2xMpRegECGLeadConfg, sizeof(stGh3x2xMpRegECGLeadConfg) / sizeof(stGh3x2xReg)))\r
+       {\r
+               test_code = MT_ERROR_COMMUNICATE_FAIL;\r
+               GH3X2X_MP_LOG_L1("Gh3x2x mp ECG test fail, RLD test set reg lead config fail, error code is: %d! \r\n", test_code);\r
+               return test_code;\r
+       }\r
+       \r
+       gh3x2x_demo_mp_write_reg(0x0108, 0x0001); //slotcfg0 enable\r
+       \r
+       gh3x2x_demo_mp_sampling_mode(START_SAMPLING); //start\r
+       gh3x2x_mp_delay_ms(100); //Discard a frame of data\r
+       \r
+       //send cmd to ecg_board for get adc, reuse GH3x2xMp_RawdataBuf array\r
+       GH3x2xMp_RawdataBuf[0] = 0x55;\r
+       GH3x2xMp_RawdataBuf[1] = UART_CMD_GETADC;\r
+       GH3x2xMp_RawdataBuf[2] = 0;\r
+       GH3x2xMp_RawdataBuf[3] = 0;\r
+       gh3x2x_mp_ecg_uart_send(GH3x2xMp_RawdataBuf, 4);\r
+       memset(GH3x2xMp_RawdataBuf, 0, RAWDATA_BUF_SIZE*sizeof(GU8));\r
+       //time out 10ms for rev data\r
+       GU16 rev_len = gh3x2x_mp_ecg_uart_receive(GH3x2xMp_RawdataBuf, 10);\r
+       gh3x2x_demo_mp_sampling_mode(STOP_SAMPLING); //stop\r
+       if(rev_len < 4)\r
+       {\r
+               test_code = MT_ERROR_COMMUNICATE_FAIL;\r
+               GH3X2X_MP_LOG_L1("Gh3x2x mp ECG test fail, RLD test rev data error through uart, error code is: %d! \r\n", test_code);\r
+               return test_code;\r
+       }\r
+       \r
+       //check limit\r
+       pstTestResult->ECG_RLD = (GF32)(GH3x2xMp_RawdataBuf[5] << 8) + GH3x2xMp_RawdataBuf[4];\r
+       GF32 MinRLDThrshold = stGh3x2xMpLimit.ECG_RLD_MaxAmp * (1 - 0.2);\r
+       GF32 MaxRLDThrshold = stGh3x2xMpLimit.ECG_RLD_MaxAmp * (1 + 0.2);\r
+       if((pstTestResult->ECG_RLD > MaxRLDThrshold) || (pstTestResult->ECG_RLD < MinRLDThrshold))\r
+       {\r
+               test_code = MT_ERROR_ECG_RLD_ERR;\r
+               GH3X2X_MP_LOG_L1("Gh3x2x mp ECG test fail, RLD test amp: %.2fmV less than min limit: %.2fmV or more than max limit: %.2fmV, error code is: %d! \r\n", \\r
+                                                       pstTestResult->ECG_RLD, MinRLDThrshold, MaxRLDThrshold, test_code);\r
+       }\r
+       else\r
+       {\r
+               GH3X2X_MP_LOG_L2("Gh3x2x mp ECG test result info, RLD amp is: %.2fmV, min limit is: %.2fmV and max limit is: %.2fmV, RLD test is pass! \r\n", \\r
+                                                       pstTestResult->ECG_RLD, MinRLDThrshold, MaxRLDThrshold);\r
+       }\r
+       \r
+       GH3X2X_MP_LOG_L2("Gh3x2x mp ECG--RLD test end! \r\n");\r
+       return test_code;\r
+}\r
+\r
+/**\r
+ * @fn     GU8 gh3x2x_demo_mp_ECG_CMRR_Test(stGh3x2xMp_ECGTestParam *pstTestPara, stGh3x2xMp_ECGTestResult *pstTestResult)\r
+ *\r
+ * @brief  ECG test items ----CMRR test\r
+ *\r
+ * @attention  \r
+ *\r
+ * @param[in]   stGh3x2xMp_ECGTestParam *pstTestPara, stGh3x2xMp_ECGTestResult *pstTestResult\r
+ * @param[out]  \r
+ *\r
+ * @return  error code\r
+ */\r
+GU8 gh3x2x_demo_mp_ECG_CMRR_Test(stGh3x2xMp_ECGTestParam *pstTestPara, stGh3x2xMp_ECGTestResult *pstTestResult)\r
+{\r
+       GU8 test_code = 0;\r
+       GU8 i = 0;\r
+       GH3X2X_MP_LOG_L2("Gh3x2x mp ECG--CMRR test start! \r\n");\r
+       \r
+       GU32 sample_num = 0;\r
+       GU32 skip_num =  0;\r
+       GU32 RawdataBuf_Len = 0;\r
+       memset(GH3x2xMp_RawdataBuf, 0, RAWDATA_BUF_SIZE*sizeof(GU8));\r
+       memset(GH3x2xMp_RawdataHandleArr, 0, MAX_RAWDATA_SAMPLE_NUM*sizeof(GS32));\r
+       \r
+       //not greater than ECG_MAX_SIGNAL_NUM\r
+       if((pstTestPara->CMRR_ECGSignalNum > ECG_MAX_SIGNAL_NUM) || (0 == pstTestPara->CMRR_ECGSignalNum))\r
+       {\r
+               test_code = MT_ERROR_ECG_CMMR_ERR;\r
+               GH3X2X_MP_LOG_L1("Gh3x2x mp ECG test fail, CMRR test set signal num error, error code is: %d! \r\n", test_code);\r
+               return test_code;\r
+       }\r
+       \r
+       //Check whether fft array need used space is in the range of GH3x2xMp_RawdataBuf\r
+       //fft array space reuse GH3x2xMp_RawdataBuf memory\r
+       if((MAX_FFT_LENGTH * 2 * 4) > (RAWDATA_BUF_SIZE / 2))\r
+       {\r
+               test_code = MT_ERROR_ECG_CMMR_ERR;\r
+               GH3X2X_MP_LOG_L1("Gh3x2x mp ECG test fail, CMRR test fft array need used space more than GH3x2xMp_RawdataBuf memory, error code is: %d! \r\n", test_code);\r
+               return test_code;\r
+       }\r
+       \r
+       \r
+       for(i = 0; i < pstTestPara->CMRR_ECGSignalNum; i++)\r
+       {\r
+               sample_num = pstTestPara->stECGSignal_CMRR[i].Rawdata_Num;\r
+               skip_num = pstTestPara->stECGSignal_CMRR[i].Rawdata_SkipNum;\r
+               //check RLD test sample num must > 200, < MAX_RAWDATA_SAMPLE_NUM\r
+               if((sample_num > MAX_RAWDATA_SAMPLE_NUM) || (sample_num <= 200))\r
+               {\r
+                       test_code = MT_ERROR_ECG_CMMR_ERR;\r
+                       GH3X2X_MP_LOG_L1("Gh3x2x mp ECG test fail, CMRR test set the number of samples over limit(must greater than 200, less than MAX_RAWDATA_SAMPLE_NUM), error code is: %d! \r\n", test_code);\r
+                       return test_code;\r
+               }\r
+               \r
+               //set ecg io status---CMRR test\r
+               if(!gh3x2x_mp_ecg_signal_and_io_status_set(ECG_SIGNAL_AND_IO_STATUS_CMMR, pstTestPara->stECGSignal_CMRR[i], NONE_SPEC))\r
+               {\r
+                       test_code = MT_ERROR_ECG_CMMR_ERR;\r
+                       GH3X2X_MP_LOG_L1("Gh3x2x mp ECG test fail, CMRR test set io status or signal fail, error code is: %d! \r\n", test_code);\r
+                       return test_code;\r
+               }\r
+               gh3x2x_mp_delay_ms(20); //wait\r
+               \r
+               //chip resume\r
+               gh3x2x_demo_mp_send_cmd(GH3X2X_MP_CMD_RESUME);\r
+               gh3x2x_mp_delay_ms(5);\r
+               \r
+               if(!gh3x2x_demo_mp_set_chip_config(stGh3x2xMpRegECGLeadConfg, sizeof(stGh3x2xMpRegECGLeadConfg) / sizeof(stGh3x2xReg)))\r
+               {\r
+                       test_code = MT_ERROR_COMMUNICATE_FAIL;\r
+                       GH3X2X_MP_LOG_L1("Gh3x2x mp ECG test fail, CMRR test set reg lead config fail, error code is: %d! \r\n", test_code);\r
+                       return test_code;\r
+               }\r
+               \r
+               if(!gh3x2x_demo_mp_set_chip_config(stGh3x2xMpRegECGConfgDefault, sizeof(stGh3x2xMpRegECGConfgDefault) / sizeof(stGh3x2xReg)))\r
+               {\r
+                       test_code = MT_ERROR_COMMUNICATE_FAIL;\r
+                       GH3X2X_MP_LOG_L1("Gh3x2x mp ECG test fail, CMRR test set reg default config fail, error code is: %d! \r\n", test_code);\r
+                       return test_code;\r
+               }\r
+               \r
+               gh3x2x_demo_mp_write_reg(0x0108, 0x0001); //slotcfg0 enable\r
+       \r
+               //get rawdata, The ECG test only collects data from one slot and ADC at a time, and LEDPDnum is fixed at 1.\r
+               memset(GH3x2xMp_RawdataBuf, 0, RAWDATA_BUF_SIZE*sizeof(GU8));\r
+               memset(GH3x2xMp_RawdataHandleArr, 0, MAX_RAWDATA_SAMPLE_NUM*sizeof(GS32));\r
+               gh3x2x_demo_mp_sampling_mode(START_SAMPLING); //start\r
+               gh3x2x_demo_mp_write_reg(0x1EA, 0x433); //Fast recovery, after sampling starts\r
+               RawdataBuf_Len = sample_num + skip_num;\r
+               if(!gh3x2x_demo_mp_get_rawdata(0xAAAA, GH3x2xMp_RawdataBuf, RawdataBuf_Len*4)) //every rawdata have 4 bytes\r
+               {\r
+                       gh3x2x_demo_mp_sampling_mode(STOP_SAMPLING); //stop\r
+                       test_code = MT_ERROR_COMMUNICATE_FAIL;\r
+                       GH3X2X_MP_LOG_L1("Gh3x2x mp ECG test fail, CMRR test read rawdata error, error code is: %d! \r\n", test_code);\r
+                       return test_code;\r
+               }\r
+               gh3x2x_demo_mp_sampling_mode(STOP_SAMPLING); //stop\r
+               \r
+               //ECG collection is fixed to slot0 ADC3, \r
+               if(!gh3x2x_demo_mp_handle_rawdata(SPEC_MODE_ECG, GH3x2xMp_RawdataHandleArr, skip_num, 0, 3, \\r
+                                                                                               GH3x2xMp_RawdataBuf, RawdataBuf_Len, 1))\r
+               {\r
+                       test_code = MT_ERROR_ECG_CMMR_ERR;\r
+                       GH3X2X_MP_LOG_L1("Gh3x2x mp ECG test fail, CMRR test handle rawdata error, error code is: %d! \r\n", test_code);\r
+                       return test_code;\r
+               }\r
+               \r
+               gh3x2x_demo_mp_ecg_cmmr_calculate(GH3x2xMp_RawdataHandleArr, sample_num, &pstTestResult->ECG_CMRR[i], \\r
+                                                                                               1, pstTestPara->stECGSignal_CMRR[i].ECG_Freq);\r
+               \r
+               //check limit\r
+               if ((pstTestResult->ECG_CMRR[i] < stGh3x2xMpLimit.ECG_CMRR_MinLimit) \\r
+                       || (pstTestResult->ECG_CMRR[i] >= 1000))\r
+               {\r
+                       test_code = MT_ERROR_ECG_CMMR_ERR;\r
+                       GH3X2X_MP_LOG_L1("Gh3x2x mp ECG test fail, CMRR%d is: %.5f less than min limit:%.5f or more than 1000, error code is: %d! \r\n", \\r
+                                                               i, pstTestResult->ECG_CMRR[i], stGh3x2xMpLimit.ECG_CMRR_MinLimit, test_code);\r
+               }\r
+               else\r
+               {\r
+                       GH3X2X_MP_LOG_L2("Gh3x2x mp ECG test result info, CMRR%d is: %.5f, min limit is:%.5f and max limit is 1000, CMRR test is pass! \r\n", \\r
+                                                               i, pstTestResult->ECG_CMRR[i], stGh3x2xMpLimit.ECG_CMRR_MinLimit);\r
+               }\r
+       }\r
+       \r
+       GH3X2X_MP_LOG_L2("Gh3x2x mp ECG--CMRR test end! \r\n");\r
+       return test_code;\r
+}\r
+\r
+/**\r
+ * @fn     GU8 gh3x2x_demo_mp_ECG_LIN_Test(stGh3x2xMp_ECGTestParam *pstTestPara, stGh3x2xMp_ECGTestResult *pstTestResult)\r
+ *\r
+ * @brief  ECG test items ----LIN test\r
+ *\r
+ * @attention  \r
+ *\r
+ * @param[in]   stGh3x2xMp_ECGTestParam *pstTestPara, stGh3x2xMp_ECGTestResult *pstTestResult\r
+ * @param[out]  \r
+ *\r
+ * @return  error code\r
+ */\r
+GU8 gh3x2x_demo_mp_ECG_LIN_Test(stGh3x2xMp_ECGTestParam *pstTestPara, stGh3x2xMp_ECGTestResult *pstTestResult)\r
+{\r
+       GU8 test_code = 0;\r
+       GU8 i = 0;\r
+       GH3X2X_MP_LOG_L2("Gh3x2x mp ECG--LIN test start! \r\n");\r
+       \r
+       GU32 sample_num = 0;\r
+       GU32 skip_num =  0;\r
+       GU32 RawdataBuf_Len = 0;\r
+       memset(GH3x2xMp_RawdataBuf, 0, RAWDATA_BUF_SIZE*sizeof(GU8));\r
+       memset(GH3x2xMp_RawdataHandleArr, 0, MAX_RAWDATA_SAMPLE_NUM*sizeof(GS32));\r
+       \r
+       GF32 LIN_Amp[ECG_MAX_SIGNAL_NUM] = {0}; //LIN test must two signals in a group\r
+       GF32 LIN_Freq = 0;\r
+       GF32 LIN_Ratio = 0;\r
+       GU8 LIN_RatioCnt = 0;\r
+       \r
+       if((pstTestPara->LIN_ECGSignalNum > ECG_MAX_SIGNAL_NUM) || (0 == pstTestPara->LIN_ECGSignalNum) \\r
+               || (0 != (pstTestPara->LIN_ECGSignalNum % 2))) //must greater than 0 and a multiple of 2, not greater than ECG_MAX_SIGNAL_NUM\r
+       {\r
+               test_code = MT_ERROR_ECG_LIN_ERR;\r
+               GH3X2X_MP_LOG_L1("Gh3x2x mp ECG test fail, LIN test set signal num error, error code is: %d! \r\n", test_code);\r
+               return test_code;\r
+       }\r
+       \r
+       //Check whether fft array need used space is in the range of GH3x2xMp_RawdataBuf\r
+       //fft array space reuse GH3x2xMp_RawdataBuf memory\r
+       if((MAX_FFT_LENGTH * 2 * 4) > (RAWDATA_BUF_SIZE / 2))\r
+       {\r
+               test_code = MT_ERROR_ECG_LIN_ERR;\r
+               GH3X2X_MP_LOG_L1("Gh3x2x mp ECG test fail, LIN test fft array need used space more than GH3x2xMp_RawdataBuf memory, error code is: %d! \r\n", test_code);\r
+               return test_code;\r
+       }\r
+       \r
+       for(i = 0; i < pstTestPara->LIN_ECGSignalNum; i++)\r
+       {\r
+               sample_num = pstTestPara->stECGSignal_LIN[i].Rawdata_Num;\r
+               skip_num = pstTestPara->stECGSignal_LIN[i].Rawdata_SkipNum;\r
+               //check LIN test sample num \r
+               if((sample_num > MAX_RAWDATA_SAMPLE_NUM) || (sample_num <= 0))\r
+               {\r
+                       test_code = MT_ERROR_ECG_LIN_ERR;\r
+                       GH3X2X_MP_LOG_L1("Gh3x2x mp ECG test fail, LIN test set the number of samples over limit, error code is: %d! \r\n", test_code);\r
+                       return test_code;\r
+               }\r
+               \r
+               //set ecg io status---LIN test\r
+               GU16 HighImpedance =  (i % 2) ? 1 : 0;\r
+               pstTestPara->stECGSignal_LIN[i].bECG_HighImpedance = HighImpedance;\r
+               if(!gh3x2x_mp_ecg_signal_and_io_status_set(ECG_SIGNAL_AND_IO_STATUS_LIN, pstTestPara->stECGSignal_LIN[i], NONE_SPEC))\r
+               {\r
+                       test_code = MT_ERROR_ECG_LIN_ERR;\r
+                       GH3X2X_MP_LOG_L1("Gh3x2x mp ECG test fail, LIN test set io status or signal fail, error code is: %d! \r\n", test_code);\r
+                       return test_code;\r
+               }\r
+               gh3x2x_mp_delay_ms(20); //wait\r
+               \r
+               //chip resume\r
+               gh3x2x_demo_mp_send_cmd(GH3X2X_MP_CMD_RESUME);\r
+               gh3x2x_mp_delay_ms(5);\r
+               \r
+               if(!gh3x2x_demo_mp_set_chip_config(stGh3x2xMpRegECGLeadConfg, sizeof(stGh3x2xMpRegECGLeadConfg) / sizeof(stGh3x2xReg)))\r
+               {\r
+                       test_code = MT_ERROR_COMMUNICATE_FAIL;\r
+                       GH3X2X_MP_LOG_L1("Gh3x2x mp ECG test fail, LIN test set reg lead config fail, error code is: %d! \r\n", test_code);\r
+                       return test_code;\r
+               }\r
+               \r
+               if(!gh3x2x_demo_mp_set_chip_config(stGh3x2xMpRegECGConfgDefault, sizeof(stGh3x2xMpRegECGConfgDefault) / sizeof(stGh3x2xReg)))\r
+               {\r
+                       test_code = MT_ERROR_COMMUNICATE_FAIL;\r
+                       GH3X2X_MP_LOG_L1("Gh3x2x mp ECG test fail, LIN test set reg default config fail, error code is: %d! \r\n", test_code);\r
+                       return test_code;\r
+               }\r
+               \r
+               gh3x2x_demo_mp_write_reg(0x0108, 0x0001); //slotcfg0 enable\r
+       \r
+               //get rawdata, The ECG test only collects data from one slot and ADC at a time, and LEDPDnum is fixed at 1.\r
+               memset(GH3x2xMp_RawdataBuf, 0, RAWDATA_BUF_SIZE*sizeof(GU8));\r
+               memset(GH3x2xMp_RawdataHandleArr, 0, MAX_RAWDATA_SAMPLE_NUM*sizeof(GS32));\r
+               gh3x2x_demo_mp_sampling_mode(START_SAMPLING); //start\r
+               gh3x2x_demo_mp_write_reg(0x1EA, 0x433); //Fast recovery, after sampling starts\r
+               RawdataBuf_Len = sample_num + skip_num;\r
+               if(!gh3x2x_demo_mp_get_rawdata(0xAAAA, GH3x2xMp_RawdataBuf, RawdataBuf_Len*4)) //every rawdata have 4 bytes\r
+               {\r
+                       gh3x2x_demo_mp_sampling_mode(STOP_SAMPLING); //stop\r
+                       test_code = MT_ERROR_COMMUNICATE_FAIL;\r
+                       GH3X2X_MP_LOG_L1("Gh3x2x mp ECG test fail, LIN test read rawdata error, error code is: %d! \r\n", test_code);\r
+                       return test_code;\r
+               }\r
+               gh3x2x_demo_mp_sampling_mode(STOP_SAMPLING); //stop\r
+               \r
+               //ECG collection is fixed to slot0 ADC3, \r
+               if(!gh3x2x_demo_mp_handle_rawdata(SPEC_MODE_ECG, GH3x2xMp_RawdataHandleArr, skip_num, 0, 3, \\r
+                                                                                               GH3x2xMp_RawdataBuf, RawdataBuf_Len, 1))\r
+               {\r
+                       test_code = MT_ERROR_ECG_LIN_ERR;\r
+                       GH3X2X_MP_LOG_L1("Gh3x2x mp ECG test fail, LIN test handle rawdata error, error code is: %d! \r\n", test_code);\r
+                       return test_code;\r
+               }\r
+               \r
+               //cal\r
+               gh3x2x_demo_mp_ecg_cal_signal_amp_freq(GH3x2xMp_RawdataHandleArr, sample_num, &LIN_Amp[i], &LIN_Freq, 0, 0, 1, \\r
+                                                                                               0, sample_num, pstTestPara->stECGSignal_LIN[i].ECG_Freq, 1);\r
+               \r
+               GH3X2X_MP_LOG_L2("Gh3x2x mp LIN freq:%.5f \r\n", LIN_Freq);\r
+               if(i && (i % 2))\r
+               {\r
+                       if(LIN_Amp[i] > 0)\r
+                               LIN_Ratio = fabs(LIN_Amp[i - 1] - LIN_Amp[i]) / LIN_Amp[i];\r
+                       else\r
+                               LIN_Ratio = 1;\r
+                       pstTestResult->ECG_LIN_Ratio[LIN_RatioCnt++] = LIN_Ratio;\r
+                       \r
+                       //check limit\r
+                       if(LIN_Ratio > stGh3x2xMpLimit.ECG_LIN_MaxLimit)\r
+                       {\r
+                               test_code = MT_ERROR_ECG_LIN_ERR;\r
+                               GH3X2X_MP_LOG_L1("Gh3x2x mp ECG test fail, LIN ratio%d: %.5f more than max limit: %.5f, amp[0] is: %.3f and amp[1] is: %.3f, error code is: %d! \r\n", \\r
+                                                                               LIN_RatioCnt-1, LIN_Ratio, stGh3x2xMpLimit.ECG_LIN_MaxLimit, LIN_Amp[i - 1], LIN_Amp[i], test_code);\r
+                       }\r
+                       else\r
+                       {\r
+                               GH3X2X_MP_LOG_L2("Gh3x2x mp ECG test result info, LIN ratio%d is: %.5f, max limit is: %.5f, LIN test is pass, amp[0] is: %.3f and amp[1] is: %.3f ! \r\n", \\r
+                                                                               LIN_RatioCnt-1, LIN_Ratio, stGh3x2xMpLimit.ECG_LIN_MaxLimit, LIN_Amp[i - 1], LIN_Amp[i]);\r
+                       }\r
+               }\r
+       }\r
+       \r
+       GH3X2X_MP_LOG_L2("Gh3x2x mp ECG--LIN test end! \r\n");\r
+       return test_code;\r
+}\r
+\r
+/**\r
+ * @fn     GU8 gh3x2x_demo_mp_ECG_DCRange_Test(stGh3x2xMp_ECGTestParam *pstTestPara, stGh3x2xMp_ECGTestResult *pstTestResult)\r
+ *\r
+ * @brief  ECG test items ----DCRange test\r
+ *\r
+ * @attention  \r
+ *\r
+ * @param[in]   stGh3x2xMp_ECGTestParam *pstTestPara, stGh3x2xMp_ECGTestResult *pstTestResult\r
+ * @param[out]  \r
+ *\r
+ * @return  error code\r
+ */\r
+GU8 gh3x2x_demo_mp_ECG_DCRange_Test(stGh3x2xMp_ECGTestParam *pstTestPara, stGh3x2xMp_ECGTestResult *pstTestResult)\r
+{\r
+       GU8 test_code = 0;\r
+       GU8 i = 0;\r
+       GH3X2X_MP_LOG_L2("Gh3x2x mp ECG--DCRange test start! \r\n");\r
+       \r
+       GU32 sample_num = 0;\r
+       GU32 skip_num =  0;\r
+       GU32 RawdataBuf_Len = 0;\r
+       memset(GH3x2xMp_RawdataBuf, 0, RAWDATA_BUF_SIZE*sizeof(GU8));\r
+       memset(GH3x2xMp_RawdataHandleArr, 0, MAX_RAWDATA_SAMPLE_NUM*sizeof(GS32));\r
+       \r
+       GF32 DCRange_Amp[ECG_MAX_SIGNAL_NUM] = {0}; //DCRange test must 3 signals in a group\r
+       GU8 DCRange_AmpCnt = 0;\r
+       //GF32 DCRange_Freq = 0;\r
+       GF32 DCRange_Ratio[2] = {0};\r
+       GU8 DCRange_RatioCnt = 0;\r
+       \r
+       \r
+       //DCRange test must 3 signals in a group\r
+       if((pstTestPara->DCRange_ECGSignalNum > ECG_MAX_SIGNAL_NUM) || (0 == pstTestPara->DCRange_ECGSignalNum) \\r
+               || (0 != (pstTestPara->DCRange_ECGSignalNum % 3))) //must greater than 0 and a multiple of 3, not greater than ECG_MAX_SIGNAL_NUM\r
+       {\r
+               test_code = MT_ERROR_ECG_DCRANGE_ERR;\r
+               GH3X2X_MP_LOG_L1("Gh3x2x mp ECG test fail, DCRange test set signal num error, error code is: %d! \r\n", test_code);\r
+               return test_code;\r
+       }\r
+       \r
+       for(i = 0; i < pstTestPara->DCRange_ECGSignalNum; i++)\r
+       {\r
+               sample_num = pstTestPara->stECGSignal_DCRange[i].Rawdata_Num;\r
+               skip_num = pstTestPara->stECGSignal_DCRange[i].Rawdata_SkipNum;\r
+               //check DCRange test sample num\r
+               if((sample_num > MAX_RAWDATA_SAMPLE_NUM) || (sample_num <= 0))\r
+               {\r
+                       test_code = MT_ERROR_ECG_DCRANGE_ERR;\r
+                       GH3X2X_MP_LOG_L1("Gh3x2x mp ECG test fail, DCRange test set the number of samples over limit, error code is: %d! \r\n", test_code);\r
+                       return test_code;\r
+               }\r
+               \r
+               //set ecg io status---LIN test\r
+               if(!gh3x2x_mp_ecg_signal_and_io_status_set(ECG_SIGNAL_AND_IO_STATUS_DC_RANGE, pstTestPara->stECGSignal_DCRange[i], NONE_SPEC))\r
+               {\r
+                       test_code = MT_ERROR_ECG_DCRANGE_ERR;\r
+                       GH3X2X_MP_LOG_L1("Gh3x2x mp ECG test fail, DCRange test set io status or signal fail, error code is: %d! \r\n", test_code);\r
+                       return test_code;\r
+               }\r
+               gh3x2x_mp_delay_ms(20); //wait\r
+               \r
+               //chip resume\r
+               gh3x2x_demo_mp_send_cmd(GH3X2X_MP_CMD_RESUME);\r
+               gh3x2x_mp_delay_ms(5);\r
+               \r
+               if(!gh3x2x_demo_mp_set_chip_config(stGh3x2xMpRegECGLeadConfg, sizeof(stGh3x2xMpRegECGLeadConfg) / sizeof(stGh3x2xReg)))\r
+               {\r
+                       test_code = MT_ERROR_COMMUNICATE_FAIL;\r
+                       GH3X2X_MP_LOG_L1("Gh3x2x mp ECG test fail, DCRange test set reg lead config fail, error code is: %d! \r\n", test_code);\r
+                       return test_code;\r
+               }\r
+               \r
+               if(!gh3x2x_demo_mp_set_chip_config(stGh3x2xMpRegECGConfgDefault, sizeof(stGh3x2xMpRegECGConfgDefault) / sizeof(stGh3x2xReg)))\r
+               {\r
+                       test_code = MT_ERROR_COMMUNICATE_FAIL;\r
+                       GH3X2X_MP_LOG_L1("Gh3x2x mp ECG test fail, DCRange test set reg default config fail, error code is: %d! \r\n", test_code);\r
+                       return test_code;\r
+               }\r
+               \r
+               gh3x2x_demo_mp_write_reg(0x0108, 0x0001); //slotcfg0 enable\r
+       \r
+               //get rawdata, The ECG test only collects data from one slot and ADC at a time, and LEDPDnum is fixed at 1.\r
+               memset(GH3x2xMp_RawdataBuf, 0, RAWDATA_BUF_SIZE*sizeof(GU8));\r
+               memset(GH3x2xMp_RawdataHandleArr, 0, MAX_RAWDATA_SAMPLE_NUM*sizeof(GS32));\r
+               gh3x2x_demo_mp_sampling_mode(START_SAMPLING); //start\r
+               gh3x2x_demo_mp_write_reg(0x1EA, 0x433); //Fast recovery, after sampling starts\r
+               RawdataBuf_Len = sample_num + skip_num;\r
+               if(!gh3x2x_demo_mp_get_rawdata(0xAAAA, GH3x2xMp_RawdataBuf, RawdataBuf_Len*4)) //every rawdata have 4 bytes\r
+               {\r
+                       gh3x2x_demo_mp_sampling_mode(STOP_SAMPLING); //stop\r
+                       test_code = MT_ERROR_COMMUNICATE_FAIL;\r
+                       GH3X2X_MP_LOG_L1("Gh3x2x mp ECG test fail, DCRange test read rawdata error, error code is: %d! \r\n", test_code);\r
+                       return test_code;\r
+               }\r
+               gh3x2x_demo_mp_sampling_mode(STOP_SAMPLING); //stop\r
+               \r
+               //ECG collection is fixed to slot0 ADC3, \r
+               if(!gh3x2x_demo_mp_handle_rawdata(SPEC_MODE_ECG, GH3x2xMp_RawdataHandleArr, skip_num, 0, 3, \\r
+                                                                                               GH3x2xMp_RawdataBuf, RawdataBuf_Len, 1))\r
+               {\r
+                       test_code = MT_ERROR_ECG_DCRANGE_ERR;\r
+                       GH3X2X_MP_LOG_L1("Gh3x2x mp ECG test fail, DCRange test handle rawdata error, error code is: %d! \r\n", test_code);\r
+                       return test_code;\r
+               }\r
+               \r
+               //cal amp\r
+               gh3x2x_demo_mp_ecg_cal_signal_WaveTimeDomin_Amp(GH3x2xMp_RawdataHandleArr, sample_num, &DCRange_Amp[i], 1, \\r
+                                                                                                                       pstTestPara->stECGSignal_DCRange[i].ECG_Freq);\r
+               if(0 == ((i + 1) % 3))\r
+               {\r
+                       if(DCRange_Amp[i - 2] > (GF32)0.1)\r
+                       {\r
+                               DCRange_Ratio[0] = fabs(DCRange_Amp[i - 2] - DCRange_Amp[i - 1]) / DCRange_Amp[i - 2];\r
+                               DCRange_Ratio[1] = fabs(DCRange_Amp[i - 2] - DCRange_Amp[i]) / DCRange_Amp[i - 2];\r
+                       }\r
+                       else\r
+                       {\r
+                               DCRange_Ratio[0] = 1;\r
+                               DCRange_Ratio[1] = 1;\r
+                       }\r
+                       pstTestResult->ECG_DCRange_Ratio[DCRange_RatioCnt++] = DCRange_Ratio[0];\r
+                       pstTestResult->ECG_DCRange_Ratio[DCRange_RatioCnt++] = DCRange_Ratio[1];\r
+                       pstTestResult->ECG_DCRange_Amp[DCRange_AmpCnt++] = DCRange_Amp[i - 2];\r
+                       pstTestResult->ECG_DCRange_Amp[DCRange_AmpCnt++] = DCRange_Amp[i - 1];\r
+                       pstTestResult->ECG_DCRange_Amp[DCRange_AmpCnt++] = DCRange_Amp[i];\r
+                       \r
+                       if(DCRange_Ratio[0] > stGh3x2xMpLimit.ECG_DCRange_MaxLimit \\r
+                               || DCRange_Ratio[1] > stGh3x2xMpLimit.ECG_DCRange_MaxLimit)\r
+                       {\r
+                               test_code = MT_ERROR_ECG_DCRANGE_ERR;\r
+                               GH3X2X_MP_LOG_L1("Gh3x2x mp ECG test fail, DCRange ratio[%d]: %.5f and ratio[%d]: %.5f more than max limit: %.5f, amp[0] is: %.3f and amp[1] is: %.3f and amp[2] is: %.3f, error code is: %d! \r\n", \\r
+                                                                       DCRange_RatioCnt-2, DCRange_Ratio[0], DCRange_RatioCnt-1, DCRange_Ratio[1], stGh3x2xMpLimit.ECG_DCRange_MaxLimit, \\r
+                                                                       DCRange_Amp[i - 2], DCRange_Amp[i - 1], DCRange_Amp[i], test_code);\r
+                       }\r
+                       else\r
+                       {\r
+                               GH3X2X_MP_LOG_L2("Gh3x2x mp ECG test result info, DCRange ratio[%d] is: %.5f and ratio[%d] is: %.5f, max limit is: %.5f, DCRange test is pass, amp[0] is: %.3f and amp[1] is: %.3f and amp[2] is: %.3f! \r\n", \\r
+                                                                       DCRange_RatioCnt-2, DCRange_Ratio[0], DCRange_RatioCnt-1, DCRange_Ratio[1], stGh3x2xMpLimit.ECG_DCRange_MaxLimit, \\r
+                                                                       DCRange_Amp[i - 2], DCRange_Amp[i - 1], DCRange_Amp[i]);\r
+                       }\r
+               }\r
+       }\r
+       \r
+       \r
+       GH3X2X_MP_LOG_L2("Gh3x2x mp ECG--DCRange test end! \r\n");\r
+       return test_code;\r
+       \r
+}\r
+\r
+/********END OF FILE********* Copyright (c) 2003 - 2022, Goodix Co., Ltd. ********/\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_mp_code/src/gh3x2x_demo_mp_user.c b/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_mp_code/src/gh3x2x_demo_mp_user.c
new file mode 100644 (file)
index 0000000..a4af303
--- /dev/null
@@ -0,0 +1,558 @@
+/**\r
+ * @copyright (c) 2003 - 2022, Goodix Co., Ltd. All rights reserved.\r
+ * \r
+ * @file    gh3x2x_demo_mp_user.c\r
+ * \r
+ * @brief   gh3x2x mp code must implemented interface by user\r
+ * \r
+ * @author  Goodix Product Tools Development Team\r
+ * \r
+ */\r
+\r
+/* includes */\r
+#include "stdint.h"\r
+#include "string.h"\r
+#include "gh3x2x_mp_config.h"\r
+#include "gh3x2x_mp_common.h"\r
+\r
+#if ( __GH3X2X_MP_USE_DRV_INTERFACE__ == __GH3X2X_DRV_MODE__ )\r
+\r
+       //use drv lib some interface\r
+       \r
+#else //__GH3X2X_MP_USE_DRV_INTERFACE__ == 0, use mp lib interface define\r
+\r
+#if ( __GH3X2X_MP_INTERFACE__ == __GH3X2X_MP_INTERFACE_I2C__ )\r
+\r
+/* i2c interface */\r
+/**\r
+ * @fn     void gh3x2x_mp_i2c_init(void)\r
+ * \r
+ * @brief  i2c init for gh3x2x mp\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void gh3x2x_mp_i2c_init(void)\r
+{\r
+\r
+    /* code implement by user */\r
+    GH3X2X_MP_LOG_L2("gh3x2x_mp i2c start init!");\r
+       \r
+       GOODIX_MP_PLATFORM_I2C_INIT_ENTITY();\r
+       \r
+       \r
+}\r
+\r
+/**\r
+ * @fn    GU8 gh3x2x_mp_i2c_write(GU8 device_id, const GU8 write_buffer[], GU16 length)\r
+ * \r
+ * @brief  i2c write for gh3x2x mp\r
+ *\r
+ * @attention   \r
+ *\r
+ * @param[in]   write_buffer    write data buffer\r
+ * @param[in]   length          write data len\r
+ * @param[out]  None\r
+ *\r
+ * @return  status\r
+ * @retval  #1      return successfully\r
+ * @retval  #0      return error\r
+ */\r
+GU8 gh3x2x_mp_i2c_write(GU8 device_id, const GU8 write_buffer[], GU16 length);\r
+{\r
+    GU8 ret = 1;\r
+\r
+    /* code implement by user */\r
+       \r
+       GOODIX_MP_PLATFORM_I2C_WRITE_ENTITY(device_id, write_buffer, length);\r
+\r
+    return ret;\r
+}\r
+\r
+\r
+/**\r
+ * @fn     uint8_t gh3x2x_mp_i2c_read(uint8_t device_id, const uint8_t write_buffer[], uint16_t write_length,\r
+ *                            uint8_t read_buffer[], uint16_t read_length)\r
+ * \r
+ * @brief  i2c read for gh3x2x mp\r
+ *\r
+ * @attention   \r
+ *\r
+ * @param[in]   device_id       device addr\r
+ * @param[in]   write_buffer    write data buffer\r
+ * @param[in]   write_length    write data len\r
+ * @param[in]   read_length     read data len\r
+ * @param[out]  read_buffer     pointer to read buffer\r
+ *\r
+ * @return  status\r
+ * @retval  #1      return successfully\r
+ * @retval  #0      return error\r
+ */\r
+GU8 gh3x2x_mp_i2c_read(GU8 device_id, const GU8 write_buffer[], GU16 write_length, GU8 read_buffer[], GU16 read_length)\r
+{\r
+    GU8 ret = 1;\r
+\r
+    /* code implement by user */\r
+       \r
+       GOODIX_MP_PLATFORM_I2C_READ_ENTITY(device_id, write_buffer, write_length, read_buffer, read_length);\r
+    \r
+       return ret;\r
+}\r
+\r
+/**\r
+ * @fn    GU8 gh3x2x_mp_i2c_send_cmd(GU8 device_id, GU8 uchCmd)\r
+ * \r
+ * @brief  i2c send cmd to gh3x2x mp\r
+ *\r
+ * @attention  \r
+ *\r
+ * @param[in]   GU8 device_id, GU8 uchCmd\r
+ * @param[out]  None\r
+ *\r
+ * @return  status\r
+ * @retval  #1      return successfully\r
+ * @retval  #0      return error\r
+ */\r
+GU8 gh3x2x_mp_i2c_send_cmd(GU8 device_id, GU8 uchCmd)\r
+{\r
+       GU8 ret = 1;\r
+       /* code implement by user */\r
+       \r
+       GOODIX_MP_PLATFORM_I2C_SEND_CMD_ENTITY(device_id, uchCmd);\r
+       \r
+       return ret;\r
+}\r
+\r
+#else // __GH3X2X_MP_INTERFACE__ == __GH3X2X_MP_INTERFACE_SPI__\r
+\r
+/* spi interface */\r
+/**\r
+ * @fn     void gh3x2x_mp_spi_init(void)\r
+ * \r
+ * @brief  spi init for gh3x2x mp\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void gh3x2x_mp_spi_init(void)\r
+{\r
+       /* code implement by user */\r
+       GH3X2X_MP_LOG_L2("gh3x2x_mp spi start init! \r\n");\r
+       \r
+       GOODIX_MP_PLATFORM_SPI_INIT_ENTITY();\r
+}\r
+\r
+/**\r
+ * @fn     GU8 gh3x2x_mp_spi_write(GU8 write_buffer[], GU16 length)\r
+ * \r
+ * @brief  spi write for gh3x2x mp\r
+ *\r
+ * @param[in]   write_buffer    write data buffer\r
+ * @param[in]   length          write data len\r
+ * @param[out]  None\r
+ *\r
+ * @return  status\r
+ * @retval  #1      return successfully\r
+ * @retval  #0      return error\r
+ */\r
+GU8 gh3x2x_mp_spi_write(GU8 write_buffer[], GU16 length)\r
+{\r
+       GU8 ret = 1;\r
+       /* code implement by user */\r
+\r
+       \r
+       GOODIX_MP_PLATFORM_SPI_WRITE_ENTITY(write_buffer, length);\r
+\r
+    return ret;\r
+}\r
+\r
+ \r
+/**\r
+ * @fn     GU8 gh3x2x_mp_spi_read(GU8 uchWriteBuffer[], GU16 usWriteLength, GU8 uchReadBuffer[], GU16 usReadLength)\r
+ * \r
+ * @brief  spi read for gh3x2x mp\r
+ *\r
+ * @attention   \r
+ *\r
+ * @param[in]   GU8 uchWriteBuffer[], GU16 usWriteLength\r
+ * @param[out]  GU8 uchReadBuffer[], GU16 usReadLength\r
+ *\r
+ * @return  status\r
+ * @retval  #1      return successfully\r
+ * @retval  #0      return error\r
+ */\r
+GU8 gh3x2x_mp_spi_read(GU8 uchWriteBuffer[], GU16 usWriteLength, GU8 uchReadBuffer[], GU16 usReadLength)\r
+{\r
+       GU8 ret = 1;\r
+       \r
+       /* code implement by user */\r
+       \r
+       GOODIX_MP_PLATFORM_SPI_READ_ENTITY(uchWriteBuffer, usWriteLength, uchReadBuffer, usReadLength);\r
+\r
+    return ret;\r
+}\r
+\r
+\r
+/**\r
+ * @fn    GU8 gh3x2x_mp_spi_send_cmd(GU8 uchCmd)\r
+ * \r
+ * @brief  spi send cmd to gh3x2x\r
+ *\r
+ * @attention  \r
+ *\r
+ * @param[in]   GU8 uchCmd\r
+ * @param[out]  None\r
+ *\r
+ * @return  status\r
+ * @retval  #1      return successfully\r
+ * @retval  #0      return error\r
+ */\r
+GU8 gh3x2x_mp_spi_send_cmd(GU8 uchCmd)\r
+{\r
+       GU8 ret = 1;\r
+       /* code implement by user */\r
+       \r
+       GOODIX_MP_PLATFORM_SPI_SEND_CMD_ENTITY(uchCmd);\r
+       \r
+       return ret;\r
+       \r
+}\r
+\r
+#endif // __GH3X2X_MP_INTERFACE__\r
+\r
+\r
+/**\r
+ * @fn     void gh3x2x_mp_reset_pin_init(void)\r
+ * \r
+ * @brief  reset pin init for gh3x2x mp\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void gh3x2x_mp_reset_pin_init(void)\r
+{\r
+    /* code implement by user */\r
+       GH3X2X_MP_LOG_L2("gh3x2x_mp reset pin start init! \r\n");\r
+       \r
+       GOODIX_MP_PLATFORM_RESET_PIN_INIT_ENTITY();\r
+}\r
+\r
+/**\r
+ * @fn     void gh3x2x_mp_reset_pin_ctrl(GU8 pin_level)\r
+ * \r
+ * @brief  reset pin ctrl for gh3x2x\r
+ *\r
+ * @attention   pin level set 1 [high level] or 0 [low level]\r
+ *\r
+ * @param[in]   pin_level     reset pin level\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void gh3x2x_mp_reset_pin_ctrl(GU8 pin_level)\r
+{\r
+   /* code implement by user */\r
+   \r
+   GOODIX_MP_PLATFORM_RESET_PIN_CTRL_ENTITY(pin_level);        \r
+       \r
+}\r
+\r
+/**\r
+ * @fn     void gh3x2x_mp_int_init(void)\r
+ * \r
+ * @brief  gh3x2x int init\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void gh3x2x_mp_int_init(void)\r
+{\r
+    /* code implement by user */\r
+       GH3X2X_MP_LOG_L2("gh3x2x_mp int pin start init! \r\n");\r
+       \r
+       GOODIX_MP_PLATFORM_INT_INIT_ENTITY();\r
+\r
+}\r
+\r
+/**\r
+ * @fn     void gh3x2x_mp_int_handler_call_back(void)\r
+ * \r
+ * @brief  call back of gh3x2x int handler, mp lib need make GH3x2xMp_IntFlag = 1\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void gh3x2x_mp_int_handler_call_back(void)\r
+{\r
+/****************** DO NOT MODITY ****************************************************************/\r
+       GH3x2xMp_IntFlag = 1; //need do this\r
+/****************** DO NOT MODITY ****************************************************************/\r
+       \r
+       GOODIX_MP_PLATFORM_INT_HANDLER_CALL_BACK_ENTITY();//do nothing currently\r
+}\r
+\r
+#endif //__GH3X2X_MP_USE_DRV_INTERFACE__\r
+\r
+/**\r
+ * @fn     void gh3x2x_mp_led_power_pin_init(void)\r
+ * \r
+ * @brief  init led power pin\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void gh3x2x_mp_led_power_pin_init()\r
+{\r
+       /* code implement by user */\r
+       \r
+       GOODIX_MP_PLATFORM_LED_POWER_PIN_INIT_ENTITY();\r
+}\r
+\r
+/**\r
+ * @fn     gh3x2x_mp_led_power_on(void)\r
+ * \r
+ * @brief  led power on\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void gh3x2x_mp_led_power_on()\r
+{\r
+       /* code implement by user */\r
+       \r
+       GOODIX_MP_PLATFORM_LED_POWER_ON_ENTITY();\r
+}\r
+\r
+/**\r
+ * @fn     void gh3x2x_mp_led_power_off(void)\r
+ * \r
+ * @brief  led power off\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void gh3x2x_mp_led_power_off(void)\r
+{\r
+       /* code implement by user */\r
+       \r
+       GOODIX_MP_PLATFORM_LED_POWER_OFF_ENTITY();\r
+}\r
+\r
+/**\r
+ * @fn     void gh3x2x_mp_prompt_message(GU8 uchMsg[], GU16 usMsglen)\r
+ * \r
+ * @brief  prompt message to do something\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   GU8 uchMsg[], GU16 usMsglen\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void gh3x2x_mp_prompt_message(GU8 uchMsg[], GU16 usMsglen)\r
+{\r
+       /* code implement by user */\r
+       \r
+       GH3X2X_MP_LOG_L2("gh3x2x_mp prompt message: %s! \r\n", uchMsg);\r
+       \r
+       if(0 == memcmp(uchMsg, PPG_PROMPT_UP_RUBBER_MSG, usMsglen))\r
+               GOODIX_MP_PLATFORM_PROMPT_UP_RUBBER_ENTITY(); /* code implement by user */\r
+       \r
+       //test is OK msg\r
+       if(0 == memcmp(uchMsg, GH3X2X_MP_TEST_OK_MSG, usMsglen))\r
+               GOODIX_MP_PLATFORM_PROMPT_TEST_OK_ENTITY(); /* code implement by user */\r
+       \r
+       //test is NG msg\r
+       if(0 == memcmp(uchMsg, GH3X2X_MP_TEST_NG_MSG, usMsglen))\r
+               GOODIX_MP_PLATFORM_PROMPT_TEST_NG_ENTITY(); /* code implement by user */\r
+}\r
+\r
+/**\r
+ * @fn     GU8 gh3x2x_mp_ecg_uart_send(GU8 uchSendBuffer[], GU16 usLength)\r
+ * \r
+ * @brief  Communicates with the ECG signal generator board through uart\r
+ *\r
+ * @attention  None\r
+ *\r
+ * @param[in]   GU8 uchSendBuffer[], GU16 usLength\r
+                               \r
+ * @param[out]  None\r
+ *\r
+ * @return  ret\r
+ */\r
+GU8 gh3x2x_mp_ecg_uart_send(GU8 uchSendBuffer[], GU16 usLength)\r
+{\r
+       GU8 ret = 1;\r
+       /* code implement by user */\r
+       \r
+\r
+       ret = GOODIX_MP_PLATFORM_ECG_UART_SEND_ENTITY(uchSendBuffer, usLength);\r
+       \r
+       return ret;\r
+       \r
+}\r
+\r
+/**\r
+ * @fn     GU8 gh3x2x_mp_ecg_uart_receive(GU8 uchRevBuffer[], GU16 Timeout_ms)\r
+ * \r
+ * @brief  Communicates with the ECG signal generator board through uart\r
+ *\r
+ * @attention  None\r
+ *\r
+ * @param[in]   GU8 uchRevBuffer[], GU16 Timeout_ms\r
+                               \r
+ * @param[out]  None\r
+ *\r
+ * @return  usLength: The length of the data rev\r
+ */\r
+GU16 gh3x2x_mp_ecg_uart_receive(GU8 uchRevBuffer[], GU16 usTimeout_ms)\r
+{\r
+       GU16 usRevLength = 0;\r
+       /* code implement by user */\r
+       \r
+       usRevLength = GOODIX_MP_PLATFORM_ECG_UART_RECEIVE_ENTITY(uchRevBuffer, usTimeout_ms);\r
+       \r
+       return usRevLength;\r
+}\r
+\r
+/**\r
+ * @fn     GU8 gh3x2x_mp_ecg_signal_and_io_status_set(emECG_SIGNAL_AND_IO_STATUS_SET emECG_Status, stGh3x2xMp_ECGSignalSetting stECGSignalSetting, emECG_SET_SIGNAL_SPEC uchSpec)\r
+ * \r
+ * @brief  Set ECG signal and IO status according to ECG test item\r
+ *\r
+ * @attention\r
+ *\r
+ * @param[in]   emECG_SIGNAL_AND_IO_STATUS_SET emECG_Status, stGh3x2xMp_ECGSignalSetting stECGSignalSetting, emECG_SET_SIGNAL_SPEC uchSpec\r
+ * @param[out]  None\r
+ *\r
+ * @return  ret\r
+ */\r
+GU8 gh3x2x_mp_ecg_signal_and_io_status_set(emECG_SIGNAL_AND_IO_STATUS_SET emECG_Status, stGh3x2xMp_ECGSignalSetting stECGSignalSetting, emECG_SET_SIGNAL_SPEC uchSpec)\r
+{\r
+       GU8 ret = 1;\r
+       /* code implement by user */\r
+       \r
+       ret = GOODIX_MP_PLATFORM_ECG_SIGNAL_AND_IO_STATUS_SET_ENTITY(emECG_Status, stECGSignalSetting, uchSpec);\r
+       \r
+       return ret;\r
+}\r
+\r
+/**\r
+ * @fn     void gh3x2x_mp_log(GCHAR *log_string)\r
+ * \r
+ * @brief  for print mp log\r
+ *\r
+ * @attention   this function must define that print mp test log\r
+ *\r
+ * @param[in]   log_string      pointer to log string\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void gh3x2x_mp_log(GCHAR *log_string)\r
+{\r
+       \r
+#if ( __GH3X2X_MP_USE_DRV_INTERFACE__ == __GH3X2X_DRV_MODE__ )\r
+       #if (__GH3X2X_MP_USE_DRV_INTERFACE_TYPE__ == __GH3X2X_DRV_LIB_INTERFACE__)\r
+               GH3X2X_PlatformLog(log_string);\r
+       #else //__GH3X2X_MP_USE_DRV_INTERFACE_TYPE__ == __GH3X2X_AFE_DRV_INTERFACE__\r
+               GH3X2X_AFE_Log(log_string);\r
+       #endif\r
+#else\r
+       GOODIX_MP_PLATFORM_LOG_ENTITY(log_string);\r
+#endif\r
+\r
+}\r
+\r
+/**\r
+ * @fn     void gh3x2x_mp_delay_us(GU16 usUsec)\r
+ * \r
+ * @brief  Delay in us,user must register this function\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void gh3x2x_mp_delay_us(GU16 usUsec)\r
+{\r
+       \r
+#if ( __GH3X2X_MP_USE_DRV_INTERFACE__ == __GH3X2X_DRV_MODE__ )\r
+       #if (__GH3X2X_MP_USE_DRV_INTERFACE_TYPE__ == __GH3X2X_DRV_LIB_INTERFACE__)\r
+               Gh3x2x_BspDelayUs(usUsec);\r
+       #else //__GH3X2X_MP_USE_DRV_INTERFACE_TYPE__ == __GH3X2X_AFE_DRV_INTERFACE__\r
+               hal_gh3x2x_afe_DelayUs(usUsec);\r
+       #endif\r
+#else\r
+       GOODIX_MP_PLATFORM_DELAY_US_ENTITY(usUsec);\r
+#endif\r
+       \r
+}\r
+\r
+\r
+/**\r
+ * @fn     void Gh3x2x_mp_delay_ms(GU16 usMsec)\r
+ * \r
+ * @brief  Delay in ms\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   None\r
+ * @param[out]  None\r
+ *\r
+ * @return  None\r
+ */\r
+void gh3x2x_mp_delay_ms(GU16 usMsec)\r
+{\r
+       \r
+#if ( __GH3X2X_MP_USE_DRV_INTERFACE__ == __GH3X2X_DRV_MODE__ )\r
+       #if (__GH3X2X_MP_USE_DRV_INTERFACE_TYPE__ == __GH3X2X_DRV_LIB_INTERFACE__)\r
+               Gh3x2x_BspDelayMs(usMsec);\r
+       #else //__GH3X2X_MP_USE_DRV_INTERFACE_TYPE__ == __GH3X2X_AFE_DRV_INTERFACE__\r
+               hal_gh3x2x_afe_DelayMs(usMsec);\r
+       #endif\r
+#else\r
+       GOODIX_MP_PLATFORM_DELAY_MS_ENTITY(usMsec);\r
+#endif\r
+       \r
+\r
+}\r
+\r
+\r
+\r
+/********END OF FILE********* Copyright (c) 2003 - 2022, Goodix Co., Ltd. ********/\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_mp_code/src/gh3x2x_mp_algorithm.c b/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_mp_code/src/gh3x2x_mp_algorithm.c
new file mode 100644 (file)
index 0000000..cb154f9
--- /dev/null
@@ -0,0 +1,1516 @@
+/**\r
+ * @copyright (c) 2003 - 2022, Goodix Co., Ltd. All rights reserved.\r
+ * \r
+ * @file    gh3x2x_mp_algorithm.c\r
+ * \r
+ * @brief   algorithms needed for gh3x2x mp test\r
+ * \r
+ * @author  Goodix Product Tools Development Team\r
+ * \r
+ */\r
+\r
+#include "gh3x2x_mp_algorithm.h"\r
+#include <string.h>\r
+#include <math.h>\r
+#include <stdlib.h>\r
+\r
+//high-pass-filter config\r
+#define HIGH_PASS_FILTER_COEF_SIZE                             7\r
+GU8 HPF_FirstFlag = 0;\r
+GD64 HPF_CoefA[HIGH_PASS_FILTER_COEF_SIZE + 1] = {1.00000000000000, -5.80579309703828, 14.04773386830920, -18.13186088426856, 13.16715655966765, -5.10069928436602, 0.82346285235115, 0};\r
+GD64 HPF_CoefB[HIGH_PASS_FILTER_COEF_SIZE + 1] = {0.90744853978126, -5.44469123868758, 13.61172809671895, -18.14897079562527, 13.61172809671895, -5.44469123868758, 0.90744853978126, 0};\r
+GD64 HPF_ArrDataIn[HIGH_PASS_FILTER_COEF_SIZE] = {0};\r
+GD64 HPF_ArrDataOut[HIGH_PASS_FILTER_COEF_SIZE] = {0};\r
+\r
+#define PI 3.14159265358979\r
+\r
+//ECG signal filter define\r
+// static const GS32 LP150HZ_STAGE_FS500 = 4;\r
+#define LP150HZ_STAGE_FS500 4\r
+static const GD64 LP150HZ_SOS_FS500[LP150HZ_STAGE_FS500][6] = {\r
+       { 1,2,1,1,0.521309265637001,0.686992220901831 },\r
+       { 1,2,1,1,0.404372288519084,0.308576213864916 },\r
+       { 1,2,1,1,0.345121039357246,0.116835143825427 },\r
+       { 1,2,1,1,0.319763902271563,0.034777724501379 },\r
+};\r
+static const GD64 LP150HZ_G_FS500[LP150HZ_STAGE_FS500 + 1] = {\r
+       0.552075371634708,\r
+       0.428237125596000,\r
+       0.365489045795668,\r
+       0.338635406693236,\r
+       1.000000000000000\r
+};\r
+\r
+// static const GS32 LP150HZ_STAGE_FS1000 = 4;\r
+#define LP150HZ_STAGE_FS1000 4\r
+static const GD64 LP150HZ_SOS_FS1000[LP150HZ_STAGE_FS1000][6] = {\r
+       { 1,2,1,1,-1.015320986156612,0.727367235221825 },\r
+       { 1,2,1,1,-0.811037098605681,0.379818727064831 },\r
+       { 1,2,1,1,-0.702809498205855,0.195690935532604 },\r
+       { 1,2,1,1,-0.655471917606866,0.115155433128685 },\r
+};\r
+static const GD64 LP150HZ_G_FS1000[LP150HZ_STAGE_FS1000 + 1] = {\r
+       0.178011562266303,\r
+       0.142195407114788,\r
+       0.123220359331687,\r
+       0.114920878880455,\r
+       1.000000000000000\r
+};\r
+\r
+static const GS32 LP120HZ_STAGE_FS1000 = 4;\r
+#define LP120HZ_STAGE_FS1000 4\r
+static const GD64 LP120HZ_SOS_FS1000[LP120HZ_STAGE_FS1000][6] = {\r
+       { 1,2,1,1,-1.286171024111227,0.764370887483613 },\r
+       { 1,2,1,1,-1.056235943388000,0.448945679767090 },\r
+       { 1,2,1,1,-0.929107652628456,0.274550944551617 },\r
+       { 1,2,1,1,-0.872288338066881,0.196606143603788 },\r
+};\r
+static const GD64 LP120HZ_G_FS1000[LP120HZ_STAGE_FS1000 + 1] = {\r
+       0.119549965843096,\r
+       0.098177434094773,\r
+       0.086360822980790,\r
+       0.081079451384227,\r
+       1.000000000000000\r
+};\r
+\r
+// static const GS32 LP120HZ_STAGE_FS500 = 4;\r
+#define LP120HZ_STAGE_FS500 4\r
+static const GD64 LP120HZ_SOS_FS500[LP120HZ_STAGE_FS500][6] = {\r
+       {1,2,1,1,-0.105114653119978,0.674052928816841},\r
+       {1,2,1,1,-0.080786840911068,0.286608894410455},\r
+       {1,2,1,1,-0.068629935436961,0.092998369043934},\r
+       {1,2,1,1,-0.063461628641803,0.010688064337096},\r
+};\r
+static const GD64 LP120HZ_G_FS500[LP120HZ_STAGE_FS500 + 1] = {\r
+       0.392234568924216,\r
+       0.301455513374847,\r
+       0.256092108401743,\r
+       0.236806608923823,\r
+       1.000000000000000\r
+};\r
+\r
+// static const GS32 LP120HZ_STAGE_FS250 = 4;\r
+#define LP120HZ_STAGE_FS250 4\r
+static const GD64 LP120HZ_SOS_FS250[LP120HZ_STAGE_FS250][6] = {\r
+       { 1,2,1,1,1.936870401643021,0.952264591056672 },\r
+       { 1,2,1,1,1.855059020399814,0.869802975343476 },\r
+       { 1,2,1,1,1.796966165642348,0.811248400272168 },\r
+       { 1,2,1,1,1.767018651463263,0.781062864124577 },\r
+};\r
+static const GD64 LP120HZ_G_FS250[LP120HZ_STAGE_FS250 + 1] = {\r
+       0.972283748174923,\r
+       0.931215498935822,\r
+       0.902053641478629,\r
+       0.887020378896960,\r
+       1.000000000000000\r
+};\r
+\r
+// static const GS32 LP55HZ_STAGE_FS1000 = 4;\r
+#define LP55HZ_STAGE_FS1000 4\r
+static const GD64 LP55HZ_SOS_FS1000[LP55HZ_STAGE_FS1000][6] = {\r
+       { 1,2,1,1,-1.765114825012452,0.876023916371837 },\r
+       { 1,2,1,1,-1.583717463961252,0.683228647261576 },\r
+       { 1,2,1,1,-1.468233227639895,0.560488083173189 },\r
+       { 1,2,1,1,-1.412490873045438,0.501243217687826 },\r
+};\r
+static const GD64 LP55HZ_G_FS1000[LP55HZ_STAGE_FS1000 + 1] = {\r
+       0.027727272839846,\r
+       0.024877795825081,\r
+       0.023063713883323,\r
+       0.022188086160597,\r
+       1.000000000000000,\r
+};\r
+\r
+// static const GS32 LP55HZ_STAGE_FS500 = 4;\r
+#define LP55HZ_STAGE_FS500 4\r
+static const GD64 LP55HZ_SOS_FS500[LP55HZ_STAGE_FS500][6] = {\r
+       { 1,2,1,1,-1.370586817292972,0.778797223984633 },\r
+       { 1,2,1,1,-1.138016414472014,0.476958929832650 },\r
+       { 1,2,1,1,-1.007207723826262,0.307190672281993 },\r
+       { 1,2,1,1,-0.948221252636367,0.230635893057958 },\r
+};\r
+static const GD64 LP55HZ_G_FS500[LP55HZ_STAGE_FS500 + 1] = {\r
+       0.102052601672915,\r
+       0.084735628840159,\r
+       0.074995737113933,\r
+       0.070603660105398,\r
+       1.000000000000000,\r
+};\r
+\r
+// static const GS32 LP55HZ_STAGE_FS250 = 4;\r
+#define LP55HZ_STAGE_FS250 4\r
+static const GD64 LP55HZ_SOS_FS250[LP55HZ_STAGE_FS250][6] = {\r
+       { 1,2,1,1,-0.314494549237044,0.678366650017106 },\r
+       { 1,2,1,1,-0.242450322262230,0.293887401730828 },\r
+       { 1,2,1,1,-0.206282801447734,0.100871780645782 },\r
+       { 1,2,1,1,-0.190873062731622,0.018634452179060 },\r
+};\r
+static const GD64 LP55HZ_G_FS250[LP55HZ_STAGE_FS250 + 1] = {\r
+       0.340968025195015,\r
+       0.262859269867149,\r
+       0.223647244799512,\r
+       0.206940347361860,\r
+       1.000000000000000,\r
+};\r
+\r
+// static const GS32 LP45HZ_STAGE_FS1000 = 4;\r
+#define LP45HZ_STAGE_FS1000 4\r
+static const GD64 LP45HZ_SOS_FS1000[LP45HZ_STAGE_FS1000][6] = {\r
+       { 1,2,1,1,-0.314494549237044,0.678366650017106 },\r
+       { 1,2,1,1,-0.242450322262230,0.293887401730828 },\r
+       { 1,2,1,1,-0.206282801447734,0.100871780645782 },\r
+       { 1,2,1,1,-0.190873062731622,0.018634452179060 },\r
+};\r
+static const GD64 LP45HZ_G_FS1000[LP45HZ_STAGE_FS1000 + 1] = {\r
+       0.340968025195015,\r
+       0.262859269867149,\r
+       0.223647244799512,\r
+       0.206940347361860,\r
+       1.000000000000000\r
+};\r
+\r
+// static const GS32 LP45HZ_STAGE_FS500 = 4;\r
+#define LP45HZ_STAGE_FS500 4\r
+static const GD64 LP45HZ_SOS_FS500[LP45HZ_STAGE_FS500][6] = {\r
+       { 1,2,1,1,-1.528839220975276,0.810717346659200 },\r
+       { 1,2,1,1,-1.301278894960406,0.541200824533548 },\r
+       { 1,2,1,1,-1.168196587814481,0.383581606779027 },\r
+       { 1,2,1,1,-1.106929858571015,0.311018888677482 },\r
+};\r
+static const GD64 LP45HZ_G_FS500[LP45HZ_STAGE_FS500 + 1] = {\r
+       0.070469531420981,\r
+       0.059980482393286,\r
+       0.053846254741137,\r
+       0.051022257526617,\r
+       1.000000000000000\r
+};\r
+\r
+// static const GS32 LP45HZ_STAGE_FS250 = 4;\r
+#define LP45HZ_STAGE_FS250 4\r
+static const GD64 LP45HZ_SOS_FS250[LP45HZ_STAGE_FS250][6] = {\r
+       { 1,2,1,1,-0.314494549237044,0.678366650017106 },\r
+       { 1,2,1,1,-0.242450322262230,0.293887401730828 },\r
+       { 1,2,1,1,-0.206282801447734,0.100871780645782 },\r
+       { 1,2,1,1,-0.190873062731622,0.018634452179060 },\r
+};\r
+static const GD64 LP45HZ_G_FS250[LP45HZ_STAGE_FS250 + 1] = {\r
+       0.340968025195015,\r
+       0.262859269867149,\r
+       0.223647244799512,\r
+       0.206940347361860,\r
+       1.000000000000000\r
+};\r
+\r
+// static const GS32 HP0D05HZ_STAGE_FS1000 = 2;\r
+#define HP0D05HZ_STAGE_FS1000 2\r
+static const GD64 HP0D05HZ_SOS_FS1000[HP0D05HZ_STAGE_FS1000][6] = {\r
+       { 1,-2,1,1,-1.999759483131749,0.999759581815928 },\r
+       { 1,-2,1,1,-1.999419579147508,0.999419677814913 },\r
+};\r
+static const GD64 HP0D05HZ_G_FS1000[HP0D05HZ_STAGE_FS1000 + 1] = {\r
+       0.999879766236919,\r
+       0.999709814240605,\r
+       1.000000000000000\r
+};\r
+\r
+// static const GS32 HP0D05HZ_STAGE_FS500 = 2;\r
+#define HP0D05HZ_STAGE_FS500 2\r
+static const GD64 HP0D05HZ_SOS_FS500[HP0D05HZ_STAGE_FS500][6] = {\r
+       { 1,-2,1,1,-1.999518826760270,0.999519221449531 },\r
+       { 1,-2,1,1,-1.998839297808073,0.998839692363201 },\r
+};\r
+static const GD64 HP0D05HZ_G_FS500[HP0D05HZ_STAGE_FS500 + 1] = {\r
+       0.999759512052450,\r
+       0.999419747542819,\r
+       1.000000000000000\r
+};\r
+\r
+// static const GS32 HP0D05HZ_STAGE_FS250 = 2;\r
+#define HP0D05HZ_STAGE_FS250 2\r
+static const GD64 HP0D05HZ_SOS_FS250[HP0D05HZ_STAGE_FS250][6] = {\r
+       { 1,-2,1,1,-1.999037095803727,0.999038674181191 },\r
+       { 1,-2,1,1,-1.997679153411597,0.997680730716872 },\r
+};\r
+static const GD64 HP0D05HZ_G_FS250[HP0D05HZ_STAGE_FS250 + 1] = {\r
+       0.999518942496230,\r
+       0.998839971032118,\r
+       1.000000000000000\r
+};\r
+\r
+// static const GS32 HP0D5HZ_STAGE_FS1000 = 2;\r
+#define HP0D5HZ_STAGE_FS1000 2\r
+static const GD64 HP0D5HZ_SOS_FS1000[HP0D5HZ_STAGE_FS1000][6] = {\r
+       { 1,-2,1,1,-1.997588562550215,0.997598420295188 },\r
+       { 1,-2,1,1,-1.994202061864258,0.994211902897450 },\r
+};\r
+static const GD64 HP0D5HZ_G_FS1000[HP0D5HZ_STAGE_FS1000 + 1] = {\r
+       0.998796745711351,\r
+       0.997103491190427,\r
+       1.000000000000000\r
+};\r
+\r
+// static const GS32 HP0D5HZ_STAGE_FS500 = 2;\r
+#define HP0D5HZ_STAGE_FS500 2\r
+static const GD64 HP0D5HZ_SOS_FS500[HP0D5HZ_STAGE_FS500][6] = {\r
+       { 1,-2,1,1,-1.995163241283863,0.995202624875511 },\r
+       { 1,-2,1,1,-1.988418017374659,0.988457267818733 },\r
+};\r
+static const GD64 HP0D5HZ_G_FS500[HP0D5HZ_STAGE_FS500 + 1] = {\r
+       0.997591466539843,\r
+       0.994218821298348,\r
+       1.000000000000000\r
+};\r
+\r
+// static const GS32 HP0D5HZ_STAGE_FS250 = 2;\r
+#define HP0D5HZ_STAGE_FS250 2\r
+static const GD64 HP0D5HZ_SOS_FS250[HP0D5HZ_STAGE_FS250][6] = {\r
+       { 1,-2,1,1,-1.990271241661729,0.990428397520602 },\r
+       { 1,-2,1,1,-1.976891354287120,0.977047453642916 },\r
+};\r
+static const GD64 HP0D5HZ_G_FS250[HP0D5HZ_STAGE_FS250 + 1] = {\r
+       0.995174909795583,\r
+       0.988484701982509,\r
+       1.000000000000000\r
+};\r
+\r
+// static const GS32 HP0D67HZ_STAGE_FS1000 = 2;\r
+#define HP0D67HZ_STAGE_FS1000 2\r
+static const GD64 HP0D67HZ_SOS_FS1000[HP0D67HZ_STAGE_FS1000][6] = {\r
+       { 1,-2,1,1,-1.996765507386640,0.996783200718337 },\r
+       { 1,-2,1,1,-1.992233931075327,0.992251584252743 },\r
+};\r
+static const GD64 HP0D67HZ_G_FS1000[HP0D67HZ_STAGE_FS1000 + 1] = {\r
+       0.998387177026244,\r
+       0.996121378832018,\r
+       1.000000000000000\r
+};\r
+\r
+// static const GS32 HP0D67HZ_STAGE_FS500 = 2;\r
+#define HP0D67HZ_STAGE_FS500 2\r
+static const GD64 HP0D67HZ_SOS_FS500[HP0D67HZ_STAGE_FS500][6] = {\r
+       { 1,-2,1,1,-1.993506129984135,0.993576789350877 },\r
+       { 1,-2,1,1,-1.984492770590399,0.984563110480689 },\r
+};\r
+static const GD64 HP0D67HZ_G_FS500[HP0D67HZ_STAGE_FS500 + 1] = {\r
+       0.996770729833753,\r
+       0.992263970267772,\r
+       1.000000000000000\r
+};\r
+\r
+// static const GS32 HP0D67HZ_STAGE_FS250 = 2;\r
+#define HP0D67HZ_STAGE_FS250 2\r
+static const GD64 HP0D67HZ_SOS_FS250[HP0D67HZ_STAGE_FS250][6] = {\r
+       { 1,-2,1,1,-1.986913427492570,0.987195155216588 },\r
+       { 1,-2,1,1,-1.969084562840559,0.969363762580524 },\r
+};\r
+static const GD64 HP0D67HZ_G_FS250[HP0D67HZ_STAGE_FS250 + 1] = {\r
+       0.993527145677289,\r
+       0.984612081355271,\r
+       1.000000000000000\r
+};\r
+\r
+// static const GS32 HP3HZ_STAGE_FS1000 = 2;\r
+#define HP3HZ_STAGE_FS1000 2\r
+static const GD64 HP3HZ_SOS_FS1000[HP3HZ_STAGE_FS1000][6] = {\r
+       { 1, - 2,       1,      1, - 1.98532458709362,  0.985677337945189 },\r
+       { 1, - 2,       1,      1, - 1.96541950338359,  0.965768717516138 }\r
+\r
+};\r
+static const GD64 HP3HZ_G_FS1000[HP3HZ_STAGE_FS1000 + 1] = {\r
+       0.992750481259703,\r
+       0.982797055224932,\r
+       1\r
+};\r
+\r
+// static const GS32 HP3HZ_STAGE_FS500 = 2;\r
+#define HP3HZ_STAGE_FS500 2\r
+static const GD64 HP3HZ_SOS_FS500[HP3HZ_STAGE_FS500][6] = {\r
+       {1, - 2,        1,      1, - 1.97016248697805,  0.971563336669560 },\r
+       {1, - 2,        1,      1, - 1.93132781565559,  0.932701052631051 }\r
+\r
+};\r
+static const GD64 HP3HZ_G_FS500[HP3HZ_STAGE_FS500 + 1] = {\r
+       0.985431455911901,\r
+       0.966007217071661,\r
+       1\r
+};\r
+\r
+// static const GS32 HP3HZ_STAGE_FS250 = 2;\r
+#define HP3HZ_STAGE_FS250 2\r
+static const GD64 HP3HZ_SOS_FS250[HP3HZ_STAGE_FS250][6] = {\r
+       {1, - 2,        1,      1, - 1.93843971601956,  0.943962707962528 },\r
+       {1, - 2,        1,      1, - 1.86455782563483,  0.869870313695752 }\r
+\r
+};\r
+static const GD64 HP3HZ_G_FS250[HP3HZ_STAGE_FS250 + 1] = {\r
+       0.970600605995522,\r
+       0.933607034832644,\r
+       1\r
+};\r
+\r
+// static const GS32 HP5HZ_STAGE_FS1000 = 2;\r
+#define HP5HZ_STAGE_FS1000 2\r
+static const GD64 HP5HZ_SOS_FS1000[HP5HZ_STAGE_FS1000][6] = {\r
+       {1, - 2,        1,      1, - 1.97526963485187,  0.976244792359440 },\r
+       {1, - 2,        1,      1, - 1.94263823054011,  0.943597278470367 }\r
+\r
+};\r
+static const GD64 HP5HZ_G_FS1000[HP5HZ_STAGE_FS1000 + 1] = {\r
+       0.987878606802828,\r
+       0.971558877252620,\r
+       1\r
+};\r
+\r
+// static const GS32 HP5HZ_STAGE_FS500 = 2;\r
+#define HP5HZ_STAGE_FS500 2\r
+static const GD64 HP5HZ_SOS_FS500[HP5HZ_STAGE_FS500][6] = {\r
+       {1, - 2,        1,      1, - 1.97526963485187,  0.976244792359440 },\r
+       {1, - 2,        1,      1, - 1.94263823054011,  0.943597278470367 }\r
+\r
+};\r
+static const GD64 HP5HZ_G_FS500[HP5HZ_STAGE_FS500 + 1] = {\r
+       0.987878606802828,\r
+       0.971558877252620,\r
+       1\r
+};\r
+\r
+// static const GS32 HP5HZ_STAGE_FS250 = 2;\r
+#define HP5HZ_STAGE_FS250 2\r
+static const GD64 HP5HZ_SOS_FS250[HP5HZ_STAGE_FS250][6] = {\r
+       { 1, - 2,       1,      1, - 1.89341560102250,  0.908464412949295 },\r
+       { 1, - 2,       1,      1, - 1.77831348813944,  0.792447471832947 }\r
+};\r
+static const GD64 HP5HZ_G_FS250[HP5HZ_STAGE_FS250 + 1] = {\r
+       0.950470003492949,\r
+       0.892690239993096,\r
+       1\r
+}; \r
+//END define ecg signal filter\r
+\r
+\r
+/**\r
+ * @fn     GU8 gh3x2x_mp_crc_cal(GU8 *puchData, GU32 unLen)\r
+ *\r
+ * @brief  GH3x2x mp start test\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   none\r
+ * @param[out]  None\r
+ *\r
+ * @return  CRC\r
+ */\r
+GU8 gh3x2x_mp_crc_cal(GU8 *puchData, GU32 unLen)\r
+{\r
+       int i;\r
+       GU8 crc = 0x00;\r
+\r
+       while (unLen--)\r
+       {\r
+               crc ^= *puchData++;\r
+               for (i = 8; i>0; --i)\r
+               {\r
+                       if (crc & 0x80)\r
+                       {\r
+                               crc = (crc << 1) ^ 0x31;\r
+                       }\r
+                       else\r
+                       {\r
+                               crc = (crc << 1);\r
+                       }\r
+                       crc = crc & 0xff;\r
+               }\r
+       }\r
+       return(crc);\r
+}\r
+\r
+/**\r
+ * @fn     GD64 gh3x2x_mp_high_pass_filter(GD64 fData)\r
+ *\r
+ * @brief  GH3x2x mp high-pass filter\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   GD64 fData\r
+ * @param[out]  None\r
+ *\r
+ * @return  Filtered data\r
+ */\r
+GD64 gh3x2x_mp_high_pass_filter(GD64 fData)\r
+{\r
+       GU32 i = 0;\r
+       \r
+       if(HPF_FirstFlag)\r
+       {\r
+               memset(HPF_ArrDataIn, 0, HIGH_PASS_FILTER_COEF_SIZE*sizeof(GD64));\r
+               memset(HPF_ArrDataOut, 0, HIGH_PASS_FILTER_COEF_SIZE*sizeof(GD64));\r
+               \r
+               GD64 skip = fData - HPF_ArrDataIn[HIGH_PASS_FILTER_COEF_SIZE - 1];\r
+               for(i = 0; i < HIGH_PASS_FILTER_COEF_SIZE; i++)\r
+               {\r
+                       HPF_ArrDataIn[i] += skip;\r
+               }\r
+               HPF_FirstFlag = 0;\r
+       }\r
+\r
+       GD64 sum = 0;\r
+       for (i = 0; i < HIGH_PASS_FILTER_COEF_SIZE; i++) \r
+       {\r
+               sum += (HPF_CoefB[i + 1] * HPF_ArrDataIn[HIGH_PASS_FILTER_COEF_SIZE - i - 1]);\r
+       }\r
+       GD64 dataBuffer_1 = HPF_CoefB[0] * fData + sum;\r
+\r
+       sum = 0;\r
+       for (i = 0; i < HIGH_PASS_FILTER_COEF_SIZE; i++) \r
+       {\r
+               sum += (HPF_CoefA[i + 1] * HPF_ArrDataOut[HIGH_PASS_FILTER_COEF_SIZE - i - 1]);\r
+       }\r
+       GD64 dataBuffer_2 = sum;\r
+\r
+       GD64 dataOut = (dataBuffer_1 - dataBuffer_2) / HPF_CoefA[0];\r
+\r
+       for(i = 0; i < HIGH_PASS_FILTER_COEF_SIZE - 1; i++)\r
+       {\r
+               HPF_ArrDataIn[i] = HPF_ArrDataIn[i + 1];\r
+       }\r
+       HPF_ArrDataIn[i] = fData;\r
+\r
+       for(i = 0; i < HIGH_PASS_FILTER_COEF_SIZE - 1; i++)\r
+       {\r
+               HPF_ArrDataOut[i] = HPF_ArrDataOut[i + 1];\r
+       }\r
+       HPF_ArrDataOut[i] = dataOut;\r
+\r
+       return dataOut;\r
+}\r
+\r
+/**\r
+ * @fn     GU8 gh3x2x_mp_ecg_lead_off_dectection(GS32 nRawdataArr[], GU16 usRawdataLen, GU8 uchECGChannel_N, GU16 *usReSampleData_Len)\r
+ *\r
+ * @brief  dectect ecg lead off algorithm\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   GS32 nRawdataArr[], GU16 usRawdataLen, GU8 uchECGChannel_N, GU16 usReSampleData_Len\r
+ * @param[out]  None\r
+ *\r
+ * @return  ret\r
+ */\r
+GU8 gh3x2x_mp_ecg_lead_off_dectection(GS32 nRawdataArr[], GU16 usRawdataLen, GU8 uchECGChannel_N, GU16 *usReSampleData_Len)\r
+{\r
+       \r
+       //ECG LeadOff detection algorithm define\r
+#define ADCREF 1800   //ref\r
+#define IS_BIG_ENDIAN 1  //data read from GH3100 FIFO is big endian?\r
+//#define PI 3.14159265\r
+\r
+#define  ABS(x) ( (x)>0?(x):(-(x)) ) //Abs value\r
+\r
+#define AMP_NUM                                                                        5   //IQ amplitude      \r
+#define IQ_NUM                                                                                 48  //IQ cumulative points\r
+#define winAmpCoef                                                             4082 //\r
+#define LEADOFF_DET_IQ_AMP_THR_uV                                      1500 //IQ lead off threshold (Vpp/2), unit uV\r
+#define LEADOFF_DET_IQ_AMP                                                     ((long long)LEADOFF_DET_IQ_AMP_THR_uV * 20 * ADC_OFFSET / ADCREF/1000*IQ_NUM*1000/winAmpCoef)\r
+#define LEADOFF_DET_IQ_AMP_DIFF_THR_uV                         1000 //IQ lead off jump threshold (Vpp/2), unit uV\r
+#define LEADOFF_DET_IQ_AMP_DIFF                                        ((long long)LEADOFF_DET_IQ_AMP_DIFF_THR_uV * 20 * ADC_OFFSET / ADCREF/1000*IQ_NUM*1000/winAmpCoef)\r
+#define LEADOFF_DET_VAL_THR_mV                                         80 //Amplitude detection threshold, unit mV, more than 80mV is considered leadoff,\r
+#define RESAMPLE_800HZ_TO_500HZ                                        1       //re-sampling switch    \r
+\r
+\r
+#if RESAMPLE_800HZ_TO_500HZ\r
+\r
+#define RS_FIR_ORDER 182  //Resample FIR filter order\r
+#define RS_I 5 //Insertion factor\r
+#define RS_D 8 //Decimation factor\r
+\r
+#if RS_FIR_ORDER%2 //Odd order, even coefficients\r
+\r
+#define RS_FIR_COEF_NUM ((RS_FIR_ORDER+1)/2) //The number of coefficients that need to be stored\r
+#else//Even order, odd coefficients\r
+#define RS_FIR_COEF_NUM ((RS_FIR_ORDER+2)/2)\r
+\r
+#endif\r
+//Resampling filter coefficients\r
+#define SHIFTBITS 30\r
+       const GS32 rsFirCoef[RS_FIR_COEF_NUM] = { 58200, 102435, 156130, 215460, 274735, 326585, 362380, 372790, 348645, 281870, 166550, 0, -216285, -475850, \\r
+                                                                                       -766815, -1071825, -1368460, -1630170, -1827760, -1931325, -1912605, -1747635, -1419445, -920670, -255820, \\r
+                                                                                       557070, 1485515, 2482735, 3488860, 4433375, 5238695, 5824850, 6114965, 6041350, 5551740, 4615280, 3227790, \\r
+                                                                                       1415785, -761100, -3209770, -5805610, -8396875, -10811545, -12866385, -14377925, -15174745, -15110485, -14076620, \\r
+                                                                                       -12014295, -8924190, -4873605, 0, 5489625, 11323885, 17176845, 22682405, 27452740, 31100030, 33260510, 33619540, \\r
+                                                                                       31936265, 28066360, 21981325, 13782945, 3711580, -7852615, -20396185, -33286830, -45795550, -57125820, -66448630, \\r
+                                                                                       -72941905, -75832375, -74437800, -68207360, -56757870, -39903755, -17678885, 9651270, 41588185, 77410100, 116192965, \\r
+                                                                                       156841955, 198132190, 238757000, 277381455, 312698655, 343486005, 368658785, 387318230, 398791740, 402663190 };\r
+#define RS_BUF_SIZE (RS_FIR_ORDER / RS_I + 1)\r
+       GS32 rsXbuf[RS_BUF_SIZE];//Filtered data buffer\r
+       GS32 bufHead = -1; //Reverse circular buffer head position\r
+       GS32 rsFirState = 0; //Resampling filter state\r
+       GU32 rsIcounter = 0; //Insert data sequence number count,4khz sample rate\r
+       GU32 rsDcounter = 0; //Extracted data sequence number count,4khz sample rate\r
+\r
+#endif \r
+       \r
+       //IQ detection variables\r
+       GU32 guiCounter = 0;  //Global counter\r
+       GU32 iqCounter = 0; //iq integral counter\r
+       GS64 iVal = 0; //I Accumulate\r
+       GS64 qVal = 0; //Q Accumulate\r
+       GS64 iqAmp[AMP_NUM] = {0}; //IQ amplitude value buffer\r
+       const GS32 winCoef[IQ_NUM / 2] = { 0, 9580474, 38150933, 85201535, 149892663, 231069901, 327284639, 436819923, 557721094, 687830666, 824826833, 966264894, \\r
+                                                                          1109620882, 1252336609, 1391865307, 1525717084, 1651503351, 1766979451, 1870084709, 1958979209, 2032076627, 2088072537, \\r
+                                                                          2125967693, 2145085852 };\r
+\r
+       GU8 gscFlagFrPrev = 0; // Fast recovery marks the cache, after fast recovery, reset the IQ detection and resampling module\r
+       GS64  LEADOFF_DET_IQ_AMP_THR_RAW = (LEADOFF_DET_IQ_AMP*LEADOFF_DET_IQ_AMP); //Threshold during normal sampling\r
+       GS64  LEADOFF_DET_IQ_AMP_FR_THR_RAW = (LEADOFF_DET_IQ_AMP*LEADOFF_DET_IQ_AMP / 20 / 20); //Threshold during Fast recovery, at this time the gain is only 1\r
+\r
+       GS64 LEADOFF_DET_IQ_AMP_DIFF_THR_RAW = (LEADOFF_DET_IQ_AMP_DIFF*LEADOFF_DET_IQ_AMP_DIFF);//Threshold during normal sampling\r
+       GS64 LEADOFF_DET_IQ_AMP_DIFF_FR_THR_RAW = (LEADOFF_DET_IQ_AMP_DIFF*LEADOFF_DET_IQ_AMP_DIFF / 20 / 20); //Threshold during Fast recovery, at this time the gain is only 1\r
+\r
+       // Amplitude detection variable\r
+       GS32 COND_VAL_VALID_TIME = 1; //Effective time of amplitude detection\r
+       GS32  LEADOFF_DET_VAL_THR_RAW = (LEADOFF_DET_VAL_THR_mV * (20 * ADC_OFFSET / ADCREF)); //\r
+\r
+\r
+       //start\r
+       GU32 i = 0;\r
+       GU32 j = 0;\r
+       \r
+       //reset \r
+       guiCounter = 0;\r
+    iqCounter = 0;\r
+    iVal = 0;\r
+    qVal = 0;\r
+    for (i = 0; i < AMP_NUM; i++)\r
+        iqAmp[i] = 0;\r
+               \r
+#if RESAMPLE_800HZ_TO_500HZ\r
+    bufHead = -1;\r
+    rsFirState = 0;\r
+    rsIcounter = 0;\r
+    rsDcounter = 0;\r
+#endif\r
+\r
+       //detect\r
+       GU32 fifoVal;\r
+    GS32 adcVal;\r
+    GU8 flagFastRecovery;\r
+    GU8 chNo;\r
+    GS32 absAdcVal; //ABS of adcVal\r
+    GS64 temp;\r
+    GS32 rstValue = 0;\r
+       \r
+#if RESAMPLE_800HZ_TO_500HZ\r
+    GU16 rsFifoDataNum = 0;\r
+    GS32 k;\r
+    GS64 y;\r
+    GS32 delta;\r
+#endif\r
+\r
+       for(i = 0; i < usRawdataLen; i++)\r
+       {\r
+               fifoVal = (GU32)nRawdataArr[i];\r
+       #if IS_BIG_ENDIAN\r
+               //big endian to little endian\r
+               fifoVal = ((fifoVal & 0xFF) << 24) | ((fifoVal & 0x0000FF00) << 8) | ((fifoVal & 0x00FF0000) >> 8) | ((fifoVal & 0xFF000000) >> 24);\r
+       #endif\r
+               chNo = (fifoVal >> 27); //Channel number\r
+        if(chNo != uchECGChannel_N)\r
+        {\r
+            continue;\r
+        }\r
+               adcVal = (int)(fifoVal & 0x00FFFFFF) - ADC_OFFSET; //adc Sample value extraction\r
+        flagFastRecovery = (fifoVal >> 26) & 0x01;\r
+               \r
+               //Reset IQ test after fast recovery is over\r
+        if(gscFlagFrPrev != flagFastRecovery)\r
+        {\r
+            //reset \r
+                       guiCounter = 0;\r
+                       iqCounter = 0;\r
+                       iVal = 0;\r
+                       qVal = 0;\r
+                       for (i = 0; i < AMP_NUM; i++)\r
+                               iqAmp[i] = 0;\r
+               \r
+               #if RESAMPLE_800HZ_TO_500HZ\r
+                       bufHead = -1;\r
+                       rsFirState = 0;\r
+                       rsIcounter = 0;\r
+                       rsDcounter = 0;\r
+               #endif\r
+        }\r
+        gscFlagFrPrev = flagFastRecovery;\r
+               \r
+               //sample counter\r
+        if(guiCounter < 20000)\r
+            guiCounter++;\r
+\r
+        //Absolute value judgment of amplitude\r
+        if(flagFastRecovery == 0 && guiCounter>COND_VAL_VALID_TIME)\r
+        {\r
+            absAdcVal = ABS(adcVal);\r
+            if(absAdcVal > LEADOFF_DET_VAL_THR_RAW)\r
+                rstValue |= 0x01;\r
+        }\r
+               \r
+               //Add window\r
+        if(iqCounter < IQ_NUM / 2) //Front half window\r
+        {\r
+            temp = (long long)adcVal*winCoef[iqCounter];\r
+        }\r
+        else //Back half window\r
+        {\r
+            temp = (long long)adcVal*winCoef[IQ_NUM - 1 - iqCounter];\r
+        }\r
+               \r
+               //IQ integral\r
+        switch (iqCounter % 4)\r
+        {\r
+        case 0:\r
+            iVal += temp;\r
+            break;\r
+        case 1:\r
+            qVal += temp;\r
+            break;\r
+        case 2:\r
+            iVal -= temp;\r
+            break;\r
+        case 3:\r
+            qVal -= temp;\r
+            break;\r
+        default:\r
+            break;\r
+        }\r
+               \r
+               if(iqCounter == (IQ_NUM - 1))\r
+        {\r
+            for (j = AMP_NUM - 1; j >0; j--)\r
+            {\r
+                iqAmp[j] = iqAmp[j - 1];\r
+            }\r
+            iVal = iVal >> 31;\r
+            qVal = qVal >> 31;\r
+            iqAmp[0] = iVal*(int)iVal + qVal*(int)qVal;\r
+            iVal = 0;\r
+            qVal = 0;\r
+\r
+            //judge leadoff\r
+            if(flagFastRecovery == 0) // During normal ECG\r
+            {\r
+                //IQ Absolute amplitude\r
+                if(iqAmp[0] > LEADOFF_DET_IQ_AMP_THR_RAW && iqAmp[1] > LEADOFF_DET_IQ_AMP_THR_RAW)\r
+                    rstValue |= 0x02;\r
+                //IQ Jump amplitude\r
+                if((iqAmp[0] - iqAmp[2]) > LEADOFF_DET_IQ_AMP_DIFF_THR_RAW && (iqAmp[1] - iqAmp[2]) > LEADOFF_DET_IQ_AMP_DIFF_THR_RAW)\r
+                    rstValue |= 0x04;\r
+\r
+            }\r
+            else//during Fast Recovery\r
+            {\r
+                //IQ Absolute amplitude\r
+                if(iqAmp[0] > LEADOFF_DET_IQ_AMP_FR_THR_RAW && iqAmp[1] > LEADOFF_DET_IQ_AMP_FR_THR_RAW)\r
+                    rstValue |= 0x02;\r
+                //IQ Jump amplitude\r
+                if((iqAmp[0] - iqAmp[1]) > LEADOFF_DET_IQ_AMP_DIFF_FR_THR_RAW)\r
+                    rstValue |= 0x04;\r
+            }\r
+               }\r
+               \r
+               //IQ counter\r
+        iqCounter++;\r
+        iqCounter = iqCounter % (IQ_NUM);\r
+               \r
+                //re samping\r
+       #if RESAMPLE_800HZ_TO_500HZ\r
+        //Data cache\r
+        if(rsFirState > 0)\r
+        {\r
+            bufHead = bufHead - 1;\r
+            bufHead = bufHead < 0 ? (RS_BUF_SIZE - 1) : bufHead;\r
+            rsXbuf[bufHead] = adcVal;\r
+            rsIcounter += RS_I;\r
+        }\r
+        else //The first point fills the data array\r
+        {\r
+            for (j = 0; j < RS_FIR_ORDER / RS_I + 1; j++)\r
+                rsXbuf[j] = adcVal;\r
+            rsIcounter = 0;\r
+            rsFirState = 1;\r
+            bufHead = RS_BUF_SIZE - 1;\r
+        }\r
+\r
+        //Extract\r
+        if(rsDcounter >= rsIcounter && rsDcounter < (rsIcounter + RS_I)) //Meet the extraction conditions\r
+        {\r
+\r
+            delta = rsDcounter - rsIcounter;\r
+            k = bufHead;\r
+            y = 0;\r
+            for(j = delta; j < RS_FIR_COEF_NUM; j = j + RS_I) //Multiply and add the first half of the filter\r
+            {\r
+                y += ((long long)rsXbuf[k] * rsFirCoef[j]);\r
+                k = (k + 1) % RS_BUF_SIZE;\r
+            }\r
+            for(; j <(RS_FIR_ORDER + 1); j = j + RS_I) //Multiply and add the second half\r
+            {\r
+                y += ((long long)rsXbuf[k] * rsFirCoef[RS_FIR_ORDER - j]);\r
+                k = (k + 1) % RS_BUF_SIZE;\r
+            }\r
+            //y *= RS_I; \r
+            rsDcounter += RS_D;\r
+\r
+            y = y >> SHIFTBITS;\r
+            k = (int)y + ADC_OFFSET; //k is used as a temporary variable\r
+            if(k < 0)\r
+                k = 0;\r
+            else if(k >= (ADC_OFFSET * 2))\r
+                k = (ADC_OFFSET * 2 - 1);\r
+            fifoVal = (((unsigned int)chNo) << 27) + (((unsigned int)flagFastRecovery) << 26) + ((unsigned int)k); //Assemble output data\r
+               #if IS_BIG_ENDIAN\r
+            fifoVal = ((fifoVal & 0xFF) << 24) | ((fifoVal & 0x0000FF00) << 8) | ((fifoVal & 0x00FF0000) >> 8) | ((fifoVal & 0xFF000000) >> 24); //endian reverse\r
+               #endif\r
+            nRawdataArr[rsFifoDataNum] = fifoVal;\r
+            rsFifoDataNum++; //Add 1 to the extracted data count\r
+        }//Complete extraction\r
+\r
+       #endif //RESAMPLE_800HZ_TO_500HZ\r
+               \r
+       \r
+       }\r
+       \r
+\r
+#if RESAMPLE_800HZ_TO_500HZ    \r
+    *usReSampleData_Len = rsFifoDataNum;\r
+#else\r
+    *usReSampleData_Len = usRawdataLen;\r
+#endif \r
+\r
+\r
+       return rstValue;\r
+\r
+}\r
+\r
+/**\r
+ * @fn     GD64 gh3x2x_mp_signal_IIR_filter(IIR_State_Def *stIIR_State, GD64 dData)\r
+ *\r
+ * @brief  GH3x2x mp signal IIR filter\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   IIR_State_Def *stIIR_State, GD64 dData\r
+ * @param[out]  None\r
+ *\r
+ * @return  Filtered data\r
+ */\r
+GD64 gh3x2x_mp_signal_IIR_filter(IIR_State_Def *stIIR_State, GD64 dData)\r
+{\r
+       GD64 x = dData;\r
+       GD64 y = 0;\r
+       \r
+       for (int i = 0; i < stIIR_State->stages; i++)\r
+       {\r
+               stIIR_State->x[i][2] = stIIR_State->x[i][1];\r
+               stIIR_State->x[i][1] = stIIR_State->x[i][0];\r
+               stIIR_State->x[i][0] = x;\r
+\r
+               y = (stIIR_State->x[i][0] * stIIR_State->sos[i][0] + stIIR_State->x[i][1] * stIIR_State->sos[i][1] +\r
+                       stIIR_State->x[i][2] * stIIR_State->sos[i][2]) * stIIR_State->gain[i] - stIIR_State->y[i][0] * stIIR_State->sos[i][4] -\r
+                       stIIR_State->y[i][1] * stIIR_State->sos[i][5];\r
+               stIIR_State->y[i][1] = stIIR_State->y[i][0];\r
+               stIIR_State->y[i][0] = y;\r
+\r
+               x = y;  // Output to the next node\r
+       }\r
+\r
+       return y;\r
+}\r
+\r
+/**\r
+ * @fn     void gh3x2x_mp_signal_filter(GS32 nFilterArr[], GU16 usLength, GU8 uchHpType, GU8 uchLpType, GU8 uchFsType)\r
+ *\r
+ * @brief  GH3x2x mp signal hp and lp filter for ecg\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   GS32 nFilterArr[], GU16 usLength, GU8 uchHpType, GU8 uchLpType, GU8 uchFsType\r
+                               uchLpType:Low pass filter cut-off frequency\r
+                               uchHpType:High pass filter cut-off frequency\r
+                               uchFsType:Sampling rate of rawdata\r
+ * @param[out]  GS32 nFilterArr[]\r
+ *\r
+ * @return  None\r
+ */\r
+void gh3x2x_mp_signal_filter(GS32 nFilterArr[], GU16 usLength, GU8 uchHpType, GU8 uchLpType, GU8 uchFsType)\r
+{\r
+       GU16 i = 0;\r
+       IIR_State_Def stState;\r
+       \r
+       \r
+       if(uchLpType != 0)\r
+       {\r
+               //init lp filter\r
+               memset(&stState, 0, sizeof(IIR_State_Def));\r
+               if(uchLpType == 1)      // LP150Hz\r
+               {\r
+                       if(uchFsType == 0)      //150Hz cut-off frequency cannot be selected for 250Hz sampling, here is forced to choose 120Hz\r
+                       {\r
+                               stState.gain = LP120HZ_G_FS250;\r
+                               stState.sos = LP120HZ_SOS_FS250;\r
+                               stState.stages = LP120HZ_STAGE_FS250;\r
+                       }\r
+                       else if(uchFsType == 1)\r
+                       {\r
+                               stState.gain = LP150HZ_G_FS500;\r
+                               stState.sos = LP150HZ_SOS_FS500;\r
+                               stState.stages = LP150HZ_STAGE_FS500;\r
+                       }\r
+                       else if(uchFsType == 2)\r
+                       {\r
+                               stState.gain = LP150HZ_G_FS1000;\r
+                               stState.sos = LP150HZ_SOS_FS1000;\r
+                               stState.stages = LP150HZ_STAGE_FS1000;\r
+                       }\r
+                       else\r
+                       {\r
+                               stState.gain = LP150HZ_G_FS500;\r
+                               stState.sos = LP150HZ_SOS_FS500;\r
+                               stState.stages = LP150HZ_STAGE_FS500;\r
+                       }\r
+               }\r
+               else if(uchLpType == 2) // LP120Hz\r
+               {\r
+                       if(uchFsType == 0)\r
+                       {\r
+                               stState.gain = LP120HZ_G_FS250;\r
+                               stState.sos = LP120HZ_SOS_FS250;\r
+                               stState.stages = LP120HZ_STAGE_FS250;\r
+                               \r
+                       }\r
+                       else if(uchFsType == 1)\r
+                       {\r
+                               stState.gain = LP120HZ_G_FS500;\r
+                               stState.sos = LP120HZ_SOS_FS500;\r
+                               stState.stages = LP120HZ_STAGE_FS500;\r
+                       }\r
+                       else if(uchFsType == 2)\r
+                       {\r
+                               stState.gain = LP120HZ_G_FS1000;\r
+                               stState.sos = LP120HZ_SOS_FS1000;\r
+                               stState.stages = LP120HZ_STAGE_FS1000;\r
+                       }\r
+                       else\r
+                       {\r
+                               stState.gain = LP120HZ_G_FS500;\r
+                               stState.sos = LP120HZ_SOS_FS500;\r
+                               stState.stages = LP120HZ_STAGE_FS500;\r
+                       }\r
+               }\r
+               else if(uchLpType == 3)\r
+               {\r
+                       if (uchFsType == 0)\r
+                       {\r
+                               stState.gain = LP55HZ_G_FS250;\r
+                               stState.sos = LP55HZ_SOS_FS250;\r
+                               stState.stages = LP55HZ_STAGE_FS250;\r
+                       }\r
+                       else if(uchFsType == 1)\r
+                       {\r
+                               stState.gain = LP55HZ_G_FS500;\r
+                               stState.sos = LP55HZ_SOS_FS500;\r
+                               stState.stages = LP55HZ_STAGE_FS500;\r
+                       }\r
+                       else if(uchFsType == 2)\r
+                       {\r
+                               stState.gain = LP55HZ_G_FS1000;\r
+                               stState.sos = LP55HZ_SOS_FS1000;\r
+                               stState.stages = LP55HZ_STAGE_FS1000;\r
+                       }\r
+                       else\r
+                       {\r
+                               stState.gain = LP55HZ_G_FS500;\r
+                               stState.sos = LP55HZ_SOS_FS500;\r
+                               stState.stages = LP55HZ_STAGE_FS500;\r
+                       }\r
+               }\r
+               else if(uchLpType == 4) // LP45Hz\r
+               {\r
+                       if(uchFsType == 0)\r
+                       {\r
+                               stState.gain = LP45HZ_G_FS250;\r
+                               stState.sos = LP45HZ_SOS_FS250;\r
+                               stState.stages = LP45HZ_STAGE_FS250;\r
+                       }\r
+                       else if(uchFsType == 1)\r
+                       {\r
+                               stState.gain = LP45HZ_G_FS500;\r
+                               stState.sos = LP45HZ_SOS_FS500;\r
+                               stState.stages = LP45HZ_STAGE_FS500;\r
+                       }\r
+                       else if(uchFsType == 2)\r
+                       {\r
+                               stState.gain = LP45HZ_G_FS1000;\r
+                               stState.sos = LP45HZ_SOS_FS1000;\r
+                               stState.stages = LP45HZ_STAGE_FS1000;\r
+                       }\r
+                       else\r
+                       {\r
+                               stState.gain = LP45HZ_G_FS500;\r
+                               stState.sos = LP45HZ_SOS_FS500;\r
+                               stState.stages = LP45HZ_STAGE_FS500;\r
+                       }\r
+               }\r
+               else\r
+               {\r
+                       if(uchFsType == 0)\r
+                       {\r
+                               stState.gain = LP120HZ_G_FS500;\r
+                               stState.sos = LP120HZ_SOS_FS500;\r
+                               stState.stages = LP120HZ_STAGE_FS500;\r
+                       }\r
+                       else if(uchFsType == 1)\r
+                       {\r
+                               stState.gain = LP150HZ_G_FS500;\r
+                               stState.sos = LP150HZ_SOS_FS500;\r
+                               stState.stages = LP150HZ_STAGE_FS500;\r
+                       }\r
+                       else if(uchFsType == 2)\r
+                       {\r
+                               stState.gain = LP150HZ_G_FS1000;\r
+                               stState.sos = LP150HZ_SOS_FS1000;\r
+                               stState.stages = LP150HZ_STAGE_FS1000;\r
+                       }\r
+                       else\r
+                       {\r
+                               stState.gain = LP150HZ_G_FS500;\r
+                               stState.sos = LP150HZ_SOS_FS500;\r
+                               stState.stages = LP150HZ_STAGE_FS500;\r
+                       }\r
+               }\r
+               \r
+               \r
+               for(i = 0; i < usLength; i++)\r
+               {\r
+                       nFilterArr[i] = gh3x2x_mp_signal_IIR_filter(&stState, (GD64)nFilterArr[i]);\r
+               }\r
+       \r
+       }\r
+       \r
+       if(uchHpType != 0)\r
+       {\r
+               //init hp filter\r
+               memset(&stState, 0, sizeof(IIR_State_Def));\r
+               if(uchHpType == 1) //0.05hz\r
+               {\r
+                       if(uchFsType == 0)\r
+                       {\r
+                               stState.gain = HP0D05HZ_G_FS250;\r
+                               stState.sos = HP0D05HZ_SOS_FS250;\r
+                               stState.stages = HP0D05HZ_STAGE_FS250;\r
+                       }\r
+                       else if(uchFsType == 1)\r
+                       {\r
+                               stState.gain = HP0D05HZ_G_FS500;\r
+                               stState.sos = HP0D05HZ_SOS_FS500;\r
+                               stState.stages = HP0D05HZ_STAGE_FS500;\r
+                       }\r
+                       else if(uchFsType == 2)\r
+                       {\r
+                               stState.gain = HP0D05HZ_G_FS1000;\r
+                               stState.sos = HP0D05HZ_SOS_FS1000;\r
+                               stState.stages = HP0D05HZ_STAGE_FS1000;\r
+                       }\r
+                       else\r
+                       {\r
+                               stState.gain = HP0D05HZ_G_FS500;\r
+                               stState.sos = HP0D05HZ_SOS_FS500;\r
+                               stState.stages = HP0D05HZ_STAGE_FS500;\r
+                       }\r
+               }\r
+               else if(uchHpType == 2)//0.5hz\r
+               {\r
+                       if(uchFsType == 0)\r
+                       {\r
+                               stState.gain = HP0D5HZ_G_FS250;\r
+                               stState.sos = HP0D5HZ_SOS_FS250;\r
+                               stState.stages = HP0D5HZ_STAGE_FS250;\r
+                       }\r
+                       else if(uchFsType == 1)\r
+                       {\r
+                               stState.gain = HP0D5HZ_G_FS500;\r
+                               stState.sos = HP0D5HZ_SOS_FS500;\r
+                               stState.stages = HP0D5HZ_STAGE_FS500;\r
+                       }\r
+                       else if(uchFsType == 2)\r
+                       {\r
+                               stState.gain = HP0D5HZ_G_FS1000;\r
+                               stState.sos = HP0D5HZ_SOS_FS1000;\r
+                               stState.stages = HP0D5HZ_STAGE_FS1000;\r
+                       }\r
+                       else\r
+                       {\r
+                               stState.gain = HP0D5HZ_G_FS500;\r
+                               stState.sos = HP0D5HZ_SOS_FS500;\r
+                               stState.stages = HP0D5HZ_STAGE_FS500;\r
+                       }\r
+               }\r
+               else if(uchHpType == 3)//0.67hz\r
+               {\r
+                       if(uchFsType == 0)\r
+                       {\r
+                               stState.gain = HP0D67HZ_G_FS250;\r
+                               stState.sos = HP0D67HZ_SOS_FS250;\r
+                               stState.stages = HP0D67HZ_STAGE_FS250;\r
+                       }\r
+                       else if(uchFsType == 1)\r
+                       {\r
+                               stState.gain = HP0D67HZ_G_FS500;\r
+                               stState.sos = HP0D67HZ_SOS_FS500;\r
+                               stState.stages = HP0D67HZ_STAGE_FS500;\r
+                       }\r
+                       else if(uchFsType == 2)\r
+                       {\r
+                               stState.gain = HP0D67HZ_G_FS1000;\r
+                               stState.sos = HP0D67HZ_SOS_FS1000;\r
+                               stState.stages = HP0D67HZ_STAGE_FS1000;\r
+                       }\r
+                       else\r
+                       {\r
+                               stState.gain = HP0D67HZ_G_FS500;\r
+                               stState.sos = HP0D67HZ_SOS_FS500;\r
+                               stState.stages = HP0D67HZ_STAGE_FS500;\r
+                       }\r
+               }\r
+               else if(uchHpType == 4)//3hz\r
+               {\r
+                       if(uchFsType == 0)\r
+                       {\r
+                               stState.gain = HP3HZ_G_FS250;\r
+                               stState.sos = HP3HZ_SOS_FS250;\r
+                               stState.stages = HP3HZ_STAGE_FS250;\r
+                       }\r
+                       else if(uchFsType == 1)\r
+                       {\r
+                               stState.gain = HP3HZ_G_FS500;\r
+                               stState.sos = HP3HZ_SOS_FS500;\r
+                               stState.stages = HP3HZ_STAGE_FS500;\r
+                       }\r
+                       else if(uchFsType == 2)\r
+                       {\r
+                               stState.gain = HP3HZ_G_FS1000;\r
+                               stState.sos = HP3HZ_SOS_FS1000;\r
+                               stState.stages = HP3HZ_STAGE_FS1000;\r
+                       }\r
+                       else\r
+                       {\r
+                               stState.gain = HP3HZ_G_FS500;\r
+                               stState.sos = HP3HZ_SOS_FS500;\r
+                               stState.stages = HP3HZ_STAGE_FS500;\r
+                       }\r
+               }\r
+               else if(uchHpType == 5)//5hz\r
+               {\r
+                       if(uchFsType == 0)\r
+                       {\r
+                               stState.gain = HP5HZ_G_FS250;\r
+                               stState.sos = HP5HZ_SOS_FS250;\r
+                               stState.stages = HP5HZ_STAGE_FS250;\r
+                       }\r
+                       else if(uchFsType == 1)\r
+                       {\r
+                               stState.gain = HP5HZ_G_FS500;\r
+                               stState.sos = HP5HZ_SOS_FS500;\r
+                               stState.stages = HP5HZ_STAGE_FS500;\r
+                       }\r
+                       else if(uchFsType == 2)\r
+                       {\r
+                               stState.gain = HP5HZ_G_FS1000;\r
+                               stState.sos = HP5HZ_SOS_FS1000;\r
+                               stState.stages = HP5HZ_STAGE_FS1000;\r
+                       }\r
+                       else\r
+                       {\r
+                               stState.gain = HP5HZ_G_FS500;\r
+                               stState.sos = HP5HZ_SOS_FS500;\r
+                               stState.stages = HP5HZ_STAGE_FS500;\r
+                       }\r
+               }\r
+               else\r
+               {\r
+                       if(uchFsType == 0)\r
+                       {\r
+                               stState.gain = HP0D05HZ_G_FS250;\r
+                               stState.sos = HP0D05HZ_SOS_FS250;\r
+                               stState.stages = HP0D05HZ_STAGE_FS250;\r
+                       }\r
+                       else if(uchFsType == 1)\r
+                       {\r
+                               stState.gain = HP0D05HZ_G_FS500;\r
+                               stState.sos = HP0D05HZ_SOS_FS500;\r
+                               stState.stages = HP0D05HZ_STAGE_FS500;\r
+                       }\r
+                       else if(uchFsType == 2)\r
+                       {\r
+                               stState.gain = HP0D05HZ_G_FS1000;\r
+                               stState.sos = HP0D05HZ_SOS_FS1000;\r
+                               stState.stages = HP0D05HZ_STAGE_FS1000;\r
+                       }\r
+                       else\r
+                       {\r
+                               stState.gain = HP0D05HZ_G_FS500;\r
+                               stState.sos = HP0D05HZ_SOS_FS500;\r
+                               stState.stages = HP0D05HZ_STAGE_FS500;\r
+                       }\r
+               }\r
+       \r
+               for(i = 0; i < usLength; i++)\r
+               {\r
+                       nFilterArr[i] = gh3x2x_mp_signal_IIR_filter(&stState, (GD64)nFilterArr[i]);\r
+               }\r
+       \r
+       }\r
+\r
+}\r
+\r
+/**\r
+ * @fn     void gh3x2x_mp_signal_fft(GF32 fFFT_InArr[], GF32 fFFT_OutArr[], GU32 unLength, GU32 unStep)\r
+ *\r
+ * @brief  fft\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   GF32 fFFT_InArr[], GS32 nFFT_OutArr[], GU32 unLength, GU32 step\r
+ * @param[out]  GF32 fFFT_InArr[]\r
+ *\r
+ * @return  ret\r
+ */\r
+void gh3x2x_mp_signal_fft(GF32 fFFT_InArr[], GF32 fFFT_OutArr[], GU32 unLength, GU32 unStep)\r
+{\r
+       GU32 i;\r
+       GF32 real = 0.0;\r
+       GF32 image = 0.0;\r
+       GF32 a, b, c, d, theta;\r
+\r
+       if (unStep < unLength)\r
+       {\r
+               gh3x2x_mp_signal_fft(fFFT_OutArr, fFFT_InArr, unLength, unStep * 2);\r
+               gh3x2x_mp_signal_fft(fFFT_OutArr + 2*unStep, fFFT_InArr + 2*unStep, unLength, unStep * 2);\r
+               \r
+               for (i = 0; i < unLength; i += 2 * unStep)\r
+               {\r
+                       theta = -PI * i / unLength;\r
+                       a = cos(theta);\r
+                       b = sin(theta);\r
+                       c = fFFT_OutArr[2*(i + unStep)];\r
+                       d = fFFT_OutArr[2*(i + unStep) + 1];\r
+                       real = a * c - b * d;\r
+                       image = b * c + a * d;\r
+                       fFFT_InArr[i] = fFFT_OutArr[2*i] + real;\r
+                       fFFT_InArr[i+1] = fFFT_OutArr[2*i + 1] + image;\r
+                       fFFT_InArr[i + unLength] = fFFT_OutArr[2*i] - real;\r
+                       fFFT_InArr[i + unLength + 1] = fFFT_OutArr[2*i + 1] - image;\r
+               }\r
+       }\r
+\r
+}\r
+\r
+/**\r
+ * @fn     void gh3x2x_mp_signal_quick_fft(GF32 fFFTInArr_real[], GF32 fFFTInArr_image[], GU32 unLength, GU32 unPower_2, \\r
+                                                                               GF32 fFFTOutArr_real[], GF32 fFFTOutArr_image[], GU8 uchFFTMode, GU32 uchCalModulus_Angle)\r
+ *\r
+ * @brief  more quick do fft process\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   GF32 fFFTInArr_real[], GF32 fFFTInArr_image[], GU32 unLength, GU32 unPower_2, GU8 uchFFTMode, GU32 uchCalModulus_Angle\r
+                               uchFFTMode: 0, Fourier transform; 1, inverse Fourier transform\r
+                               uchCalModulus_Angle: 0, do not calculate Fourier transform or inverse transform mode and amplitude Angle;1, calculate the modulus and amplitude Angle\r
+                               unLength: the number of points entered, which is an even number, is generally 32,64,128...1024, etc.\r
+                               unPower_2: satisfy n=2^unPower_2(unPower_2>0)\r
+                               fFFTInArr_real: 0,store the real part of the sampled data at N points; 1,store N real parts of the Fourier transform\r
+                               fFFTInArr_image: 0,store the imaginary part of the sampled data at N points; 1,store N imaginary parts of the Fourier transform\r
+\r
+ * @param[out]  GF32 fFFTInArr_real[], GF32 fFFTInArr_image[], \r
+                               fFFTOutArr_real: uchFFTMode=0, return the real part of the Fourier transform\r
+                                                               uchFFTMode=1, return the real part of the inverse Fourier transform\r
+                               fFFTOutArr_image:uchFFTMode=0, return the imaginary part of the Fourier transform\r
+                                                               uchFFTMode=1, return the imaginary part of the inverse Fourier transform\r
+                               fFFTInArr_real: uchCalModulus_Angle = 1, uchFFTMode = 0, return the modulus of Fourier transform\r
+                                                               uchCalModulus_Angle = 1, uchFFTMode = 1, return the inverse Fourier transform modulus\r
+                               fFFTInArr_image:uchCalModulus_Angle = 1, uchFFTMode = 0, return the amplitude Angle of the Fourier transform\r
+                                                               uchCalModulus_Angle = 1, uchFFTMode = 1, return the amplitude Angle of the inverse Fourier transform\r
+ *\r
+ * @return  none\r
+ */\r
+void gh3x2x_mp_signal_quick_fft(GF32 fFFTInArr_real[], GF32 fFFTInArr_image[], GU32 unLength, GU32 unPower_2, \\r
+                                                                               GF32 fFFTOutArr_real[], GF32 fFFTOutArr_image[], GU8 uchFFTMode, GU32 uchCalModulus_Angle)\r
+{\r
+       GS32 it,m,is,i,j,nv,l0;\r
+       GF32 p,q,s,vr,vi,poddr,poddi;\r
+       \r
+       for (it=0; it<=unLength-1; it++)\r
+       {\r
+               m = it;\r
+               is = 0;\r
+               for(i=0; i<=unPower_2-1; i++)\r
+               {\r
+                       j = m/2;\r
+                       is = 2*is+(m-2*j);\r
+                       m = j;\r
+               }\r
+               fFFTOutArr_real[it] = fFFTInArr_real[is];\r
+               fFFTOutArr_image[it] = fFFTInArr_image[is];\r
+       }\r
+       \r
+       fFFTInArr_real[0] = 1.0;\r
+       fFFTInArr_image[0] = 0.0;\r
+       p = 6.283185306/(1.0*unLength);\r
+       fFFTInArr_real[1] = cos(p);\r
+       fFFTInArr_image[1] = -sin(p);\r
+       \r
+       if (uchFFTMode!=0)\r
+       fFFTInArr_image[1]=-fFFTInArr_image[1];\r
+       \r
+       for (i=2; i<=unLength-1; i++)\r
+       {\r
+               p = fFFTInArr_real[i-1]*fFFTInArr_real[1];\r
+               q = fFFTInArr_image[i-1]*fFFTInArr_image[1];\r
+               s = (fFFTInArr_real[i-1]+fFFTInArr_image[i-1])*(fFFTInArr_real[1]+fFFTInArr_image[1]);\r
+               fFFTInArr_real[i] = p-q;\r
+               fFFTInArr_image[i] = s-p-q;\r
+       }\r
+       \r
+       for (it=0; it<=unLength-2; it=it+2)\r
+       {\r
+               vr = fFFTOutArr_real[it];\r
+               vi = fFFTOutArr_image[it];\r
+               fFFTOutArr_real[it] = vr+fFFTOutArr_real[it+1];\r
+               fFFTOutArr_image[it] = vi+fFFTOutArr_image[it+1];\r
+               fFFTOutArr_real[it+1] = vr-fFFTOutArr_real[it+1];\r
+               fFFTOutArr_image[it+1] = vi-fFFTOutArr_image[it+1];\r
+       }\r
+       m = unLength/2;\r
+       nv = 2;\r
+       \r
+       for (l0=unPower_2-2; l0>=0; l0--)\r
+       {\r
+               m = m/2;\r
+               nv = 2*nv;\r
+               for(it=0; it<=(m-1)*nv; it=it+nv)\r
+               for (j=0; j<=(nv/2)-1; j++)\r
+               {\r
+                       p = fFFTInArr_real[m*j]*fFFTOutArr_real[it+j+nv/2];\r
+                       q = fFFTInArr_image[m*j]*fFFTOutArr_image[it+j+nv/2];\r
+                       s = fFFTInArr_real[m*j]+fFFTInArr_image[m*j];\r
+                       s = s*(fFFTOutArr_real[it+j+nv/2]+fFFTOutArr_image[it+j+nv/2]);\r
+                       poddr = p-q;\r
+                       poddi = s-p-q;\r
+                       fFFTOutArr_real[it+j+nv/2] = fFFTOutArr_real[it+j]-poddr;\r
+                       fFFTOutArr_image[it+j+nv/2] = fFFTOutArr_image[it+j]-poddi;\r
+                       fFFTOutArr_real[it+j] = fFFTOutArr_real[it+j]+poddr;\r
+                       fFFTOutArr_image[it+j] = fFFTOutArr_image[it+j]+poddi;\r
+               }\r
+       }\r
+       \r
+       if(uchFFTMode!=0)\r
+       for(i=0; i<=unLength-1; i++)\r
+       {\r
+               fFFTOutArr_real[i] = fFFTOutArr_real[i]/(1.0*unLength);\r
+               fFFTOutArr_image[i] = fFFTOutArr_image[i]/(1.0*unLength);\r
+       }\r
+       \r
+       if(uchCalModulus_Angle!=0)\r
+       for(i=0; i<=unLength-1; i++)\r
+       {\r
+               fFFTInArr_real[i] = sqrt(fFFTOutArr_real[i]*fFFTOutArr_real[i]+fFFTOutArr_image[i]*fFFTOutArr_image[i]);\r
+               if(fabs(fFFTOutArr_real[i])<0.000001*fabs(fFFTOutArr_image[i]))\r
+               {\r
+                       if ((fFFTOutArr_image[i]*fFFTOutArr_real[i])>0)\r
+                       fFFTInArr_image[i] = 90.0;\r
+                       else\r
+                       fFFTInArr_image[i] = -90.0;\r
+               }\r
+               else\r
+                       fFFTInArr_image[i] = atan(fFFTOutArr_image[i]/fFFTOutArr_real[i])*360.0/6.283185306;\r
+       }\r
+       return;\r
+}\r
+\r
+/**\r
+ * @fn     GU8 gh3x2x_mp_signal_fft_process(GS32 nFFTArr[] GU32 unLength)\r
+ *\r
+ * @brief  Perform FFT transformation on the data and then calculate the power spectrum\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   GS32 nFFTArr[], GU32 unLength\r
+ * @param[out]  GS32 nFFTArr[]\r
+ *\r
+ * @return  ret\r
+ */\r
+GF32 *fFFT_HandleArr = NULL;\r
+extern GU8 GH3x2xMp_RawdataBuf[RAWDATA_BUF_SIZE];\r
+GU8 gh3x2x_mp_signal_fft_process(GF32 fFFTArr[], GU32 unLength)\r
+{\r
+       GU8 ret = 1;\r
+       GS32 i = 0;\r
+       //memset(fFFT_HandleArr, 0, 2*MAX_FFT_LENGTH*sizeof(GF32));\r
+       fFFT_HandleArr = (GF32 *)(GH3x2xMp_RawdataBuf) + 2*MAX_FFT_LENGTH + 1; //Reuse GH3x2xMp_RawdataBuf memory\r
+       \r
+       //find the smallest 2^n from unLength\r
+       GU32 fft_len = 0;\r
+       i = 0;\r
+       while(fft_len < MAX_FFT_LENGTH)\r
+       {\r
+               if(fft_len >= unLength)\r
+                       break;\r
+               fft_len = pow(2, i);\r
+               i++;\r
+       }\r
+       unLength =      fft_len;\r
+\r
+//     for(i = 2*unLength - 2; i >= 0; i -= 2)\r
+//     {\r
+//             fFFTArr[i] = fFFTArr[i / 2];\r
+//             fFFTArr[i+1] = 0;\r
+//     }\r
+//     \r
+//     for(i = 0; i < 2*unLength; i++)\r
+//     {\r
+//             fFFT_HandleArr[i] = fFFTArr[i];\r
+//     }\r
+       \r
+\r
+//     gh3x2x_mp_signal_fft(fFFTArr, fFFT_HandleArr, unLength, 1);\r
+\r
+//     for(i = 0; i < unLength; i++)\r
+//             fFFTArr[i] = sqrt(fFFTArr[2*i] * fFFTArr[2*i] + fFFTArr[2*i + 1] * fFFTArr[2*i + 1]);\r
+       \r
+       gh3x2x_mp_signal_quick_fft(fFFTArr, fFFTArr+MAX_FFT_LENGTH, unLength, i-1, fFFT_HandleArr, fFFT_HandleArr+MAX_FFT_LENGTH, 0, 1);\r
+       \r
+       fFFT_HandleArr = NULL;\r
+       return ret;\r
+}\r
+\r
+/**\r
+ * @fn     GU8 gh3x2x_demo_mp_ecg_fft_cal_amp_freq(GF32 fRawdataArr[], GU16 usLength, GU32 unFFTLength, GU32 unSampleRate, GF32 *fAmp, GF32 *fFreq, \\r
+                                                                                                               GF32 fRefFreq, GU8 uchWintype)\r
+ *\r
+ * @brief  cal amp and freq after fft\r
+ *\r
+ * @attention   None\r
+ *\r
+ * @param[in]   GF32 fRawdataArr[], GU16 usLength,  GU32 unFFTLength, GU32 unSampleRate, GU8 uchWintype, GF32 fRefFreq\r
+                               unSampleRate: Sampling frequency\r
+                               winType:Window type, 0: rectangular window; 1: flattop window, used to accurately estimate the amplitude; 2: hanning window\r
+                               fRefFreq:For reference frequency, find the maximum value near fref±5hz; if <0, find the maximum value between 0.1hz~fs/2\r
+ * @param[out]  GF32 *fAmp, GF32 *fFreq\r
+                               fAmp: peak-to-peak value\r
+                               fFreq:freq, unit Hz\r
+ *                             \r
+ * @return  ret\r
+ */\r
+GU8 gh3x2x_demo_mp_ecg_fft_cal_amp_freq(GF32 fRawdataArr[], GU16 usLength, GU32 unFFTLength, GU32 unSampleRate, GF32 *fAmp, GF32 *fFreq, \\r
+                                                                                                               GF32 fRefFreq, GU8 uchWintype)\r
+{\r
+       GU8 ret = 1;\r
+       GU32 i = 0;\r
+       \r
+       GD64 sum = 0;\r
+       GD64 mean = 0;\r
+       \r
+       if(unFFTLength > MAX_FFT_LENGTH)\r
+               unFFTLength = MAX_FFT_LENGTH;\r
+       \r
+       if(usLength > unFFTLength)\r
+               usLength = unFFTLength;\r
+       \r
+       \r
+       for(i = 0; i < usLength; i++)\r
+               sum += fRawdataArr[i];\r
+       mean = sum / usLength;\r
+       \r
+       // Subtract the mean value of the signal and add a window\r
+       GD64 N = usLength - 1;\r
+       GD64 win = 0;\r
+       GD64 a0 = 0.21557895;\r
+       GD64 a1 = 0.41663158;\r
+       GD64 a2 = 0.277263158;\r
+       GD64 a3 = 0.083578947;\r
+       GD64 a4 = 0.006947368;\r
+       \r
+       if(uchWintype == 1)\r
+       {\r
+               for (i = 0; i < usLength; i++)\r
+               {\r
+                       win = a0 - a1*cos(2 * PI*i / N) + a2*cos(4 * PI*i / N) - a3*cos(6 * PI*i / N) + a4*cos(8 * PI*i / N); //flattopwin\r
+                       fRawdataArr[i] = (fRawdataArr[i] - mean)*win;\r
+               }\r
+       }\r
+       else if(uchWintype == 2)\r
+       {\r
+               for(i = 0; i < usLength; i++)\r
+               {\r
+                       win = 0.5*(1-cos(2*PI*i/N)); //hanning\r
+                       fRawdataArr[i] = (fRawdataArr[i] - mean)*win;\r
+               }\r
+\r
+       }\r
+       else\r
+       {\r
+               for(i = 0; i < usLength; i++)\r
+               {\r
+                       fRawdataArr[i] = (fRawdataArr[i] - mean);\r
+               }\r
+\r
+       }\r
+\r
+       \r
+       gh3x2x_mp_signal_fft_process(fRawdataArr, unFFTLength);\r
+       \r
+       //find peak \r
+       GS32 start = 0;\r
+       GS32 end = 0;\r
+       \r
+       if(fRefFreq > 0) //If the frequency is specified, look for it near the frequency\r
+       {\r
+               if((fRefFreq - 5) > (GF32)0.1)\r
+                       start = (GS32)((fRefFreq - 5)* unFFTLength / unSampleRate);\r
+               else\r
+                       start = (GS32)(0.1*unFFTLength / unSampleRate);\r
+\r
+               if((fRefFreq + 5) * 2 < unSampleRate)\r
+                       end = (GS32)((fRefFreq + 5) * unFFTLength / unSampleRate);\r
+               else\r
+                       end = (GS32)(0.5*unFFTLength);\r
+       }\r
+       else //If the frequency is not specified, it will be found in the full frequency range.\r
+       {\r
+               start = (GS32)(0.1*unFFTLength / unSampleRate);\r
+               end = (GS32)(0.5*unFFTLength);\r
+       }\r
+       \r
+       GS32 peakPos = start;\r
+       GD64 peak = fRawdataArr[start];\r
+       for(i = start + 1; i <= end; i++)\r
+       {\r
+               if (peak < fRawdataArr[i])\r
+               {\r
+                       peakPos = i;\r
+                       peak = fRawdataArr[i];\r
+               }\r
+       }\r
+       \r
+       //cal freq\r
+       *fFreq =  (GF32)peakPos* unSampleRate / unFFTLength;\r
+       \r
+       //calculate signal amplitude through frequency domain\r
+       if (uchWintype == 1)\r
+               peak = peak / unFFTLength * 9.2792;     // Cal the amp, 9.2792 is amp correction coefficient of flattopwin\r
+       else\r
+               peak = peak / unFFTLength * 2;     //2 is rectangular window amplitude correction factor\r
+       *fAmp = peak * 2;               // To calculate the peak-to-peak value must be multiplied by 2\r
+       \r
+       return ret;\r
+}\r
+\r
+/********END OF FILE********* Copyright (c) 2003 - 2022, Goodix Co., Ltd. ********/\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_mp_code/src/gh3x2x_mp_param_config.c b/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_mp_code/src/gh3x2x_mp_param_config.c
new file mode 100644 (file)
index 0000000..9538569
--- /dev/null
@@ -0,0 +1,144 @@
+/**\r
+ * @copyright (c) 2003 - 2022, Goodix Co., Ltd. All rights reserved.\r
+ * \r
+ * @file    gh3x2x_mp_param_config.c\r
+ * \r
+ * @brief   gh3x2x mp test param config\r
+ * \r
+ * @author  Goodix Product Tools Development Team\r
+ * \r
+ */\r
+\r
+#include "gh3x2x_mp_param_config.h"\r
+\r
+//test items select SKIP or TEST or NG_CONTINUE\r
+const stMpItemsConfig stGh3x2xMpTestItemsSatus = \r
+{\r
+       //SKIP:item skip, not test; TEST:item need test;  NG_CONTINUE: test item NG, continue to test\r
+       .COMMUNICATION_TEST =           TEST,\r
+       .CHECK_CHIPID_TEST =            TEST,  //need use drv interface to check, at present Only need to test this item when the driver is AFE\r
+       .RST_INT_TEST =                         TEST,\r
+       .EFUSE_TEST =                           TEST,\r
+       .PPG_TEST =                             TEST,\r
+       .ECG_TEST =                             TEST,\r
+};\r
+\r
+//PPG test items select SKIP or TEST or NG_CONTINUE\r
+const stMpPPGItemsConfig stGh3x2xMpPPGItemsSatus = \r
+{\r
+       .PPG_LPCTR_TEST =                       TEST,\r
+       .PPG_NOISE_TEST =                       TEST,\r
+       .PPG_BASENOISE_TEST =           TEST,\r
+       .PPG_LEAKLIGHT_TEST =           SKIP,\r
+       \r
+};\r
+\r
+//ECG test items select SKIP or TEST or NG_CONTINUE\r
+const stMpECGItemsConfig stGh3x2xMpECGItemsSatus = \r
+{\r
+       \r
+       .ECG_LEADONOFF_TEST =           TEST,\r
+       .ECG_NOISE_TEST =                       TEST,\r
+       .ECG_HPF_TEST =                         TEST,\r
+       .ECG_SIGNAL_TEST =                      TEST,\r
+       .ECG_RLD_TEST =                         TEST,\r
+       .ECG_CMRR_TEST =                        TEST,\r
+       .ECG_LIN_TEST =                         TEST,\r
+       .ECG_DCRANGE_TEST =             TEST,\r
+};\r
+\r
+//LED and PD enable/disable config\r
+const emMp_Enable PPG_LEDPD_EN[MAX_LED_NUM][MAX_ADC_NUM] = \r
+{\r
+       //every led can enable/disable 4 pd\r
+       //PD0,   PD1,    PD2,    PD3\r
+       {MP_ENABLE, MP_ENABLE, MP_ENABLE, MP_ENABLE},           //led 0\r
+       {MP_ENABLE, MP_ENABLE, MP_ENABLE, MP_ENABLE},           //led 1\r
+       {MP_ENABLE, MP_ENABLE, MP_ENABLE, MP_ENABLE},           //led 2\r
+       {MP_DISABLE, MP_DISABLE, MP_DISABLE, MP_DISABLE},       //led 3\r
+       {MP_DISABLE, MP_DISABLE, MP_DISABLE, MP_DISABLE},       //led 4\r
+       {MP_DISABLE, MP_DISABLE, MP_DISABLE, MP_DISABLE},       //led 5\r
+       {MP_DISABLE, MP_DISABLE, MP_DISABLE, MP_DISABLE},       //led 6\r
+       {MP_DISABLE, MP_DISABLE, MP_DISABLE, MP_DISABLE}        //led 7\r
+};\r
+\r
+//PPG test auto Dimming Config\r
+const stMpAutoDimmingConfig stGh3x2xPPG_AutoDimming = \r
+{\r
+       .LED_ACG_FS = {\r
+                                               LED_DRIVE_50MA,   //led 0\r
+                                               LED_DRIVE_25MA,   //led 1\r
+                                               LED_DRIVE_25MA,   //led 2\r
+                                               LED_DRIVE_25MA,   //led 3\r
+                                               LED_DRIVE_25MA,   //led 4\r
+                                               LED_DRIVE_25MA,   //led 5\r
+                                               LED_DRIVE_25MA,   //led 6\r
+                                               LED_DRIVE_25MA,   //led 7\r
+                                       },\r
+       .LED_Max_Rawdata = 48787,\r
+       .LED_Min_Rawdata = 45874,\r
+       .LED_Ref_Up = 47816,\r
+       .LED_Ref_Down = 46845,\r
+};\r
+\r
+//test limit config\r
+const stMpItemsLimitConfig stGh3x2xMpLimit = \r
+{\r
+       //PPG test limit\r
+       .PPG_CTR_MinLimit = { //PPG CTR test limit\r
+                                                 //PD0,  PD1,  PD2,  PD3\r
+                                                       11.0, 11.0, 11.0, 11.0,         //led 0\r
+                                                       24.0, 24.0, 24.0, 24.0,         //led 1\r
+                                                       24.0, 24.0, 24.0, 24.0,         //led 2\r
+                                                       24.0, 24.0, 24.0, 24.0,         //led 3\r
+                                                       24.0, 24.0, 24.0, 24.0,         //led 4\r
+                                                       24.0, 24.0, 24.0, 24.0,         //led 5\r
+                                                       24.0, 24.0, 24.0, 24.0,         //led 6\r
+                                                       24.0, 24.0, 24.0, 24.0,         //led 7\r
+                                               },\r
+       \r
+       .PPG_LeakCTR_MaxLimit = { //PPG leak light test limit\r
+                                                         //PD0, PD1, PD2, PD3\r
+                                                               1.0, 1.0, 1.0, 1.0,             //led 0\r
+                                                               0.8, 0.8, 0.8, 0.8,             //led 1\r
+                                                               0.8, 0.8, 0.8, 0.8,             //led 2\r
+                                                               0.8, 0.8, 0.8, 0.8,             //led 3\r
+                                                               0.8, 0.8, 0.8, 0.8,             //led 4\r
+                                                               0.8, 0.8, 0.8, 0.8,             //led 5\r
+                                                               0.8, 0.8, 0.8, 0.8,             //led 6\r
+                                                               0.8, 0.8, 0.8, 0.8,             //led 7\r
+                                                       },\r
+       \r
+       .PPG_LeakRatio_Throld = {  //PPG leak light test limit\r
+                                                               //PD0, PD1,   PD2,   PD3\r
+                                                               0.037, 0.037, 0.037, 0.037,             //led 0\r
+                                                               0.015, 0.015, 0.015, 0.015,             //led 1\r
+                                                               0.015, 0.015, 0.015, 0.015,             //led 2\r
+                                                               0.015, 0.015, 0.015, 0.015,             //led 3\r
+                                                               0.015, 0.015, 0.015, 0.015,             //led 4\r
+                                                               0.015, 0.015, 0.015, 0.015,             //led 5\r
+                                                               0.015, 0.015, 0.015, 0.015,             //led 6\r
+                                                               0.015, 0.015, 0.015, 0.015,             //led 7\r
+                                                       },\r
+       \r
+       .PPG_Noise_MaxLimit = 280,     //PPG Noise test limit\r
+       .PPG_BaseNoise_MaxLimit = 97,  //PPG BaseNoise noise test limit\r
+       .PPG_DCOffset_MaxLimit = 1.60, //PPG BaseNoise test limit\r
+       .PPG_DCOffset_MinLimit = -7.7, //PPG BaseNoise test limit\r
+\r
+                                                       \r
+       //ECG test limit\r
+       .ECG_Noise_MaxLimit = 35,          //ECG Noise test limit\r
+       .ECG_HPF_MaxLimit = 0.87,          //ECG HPF test limit\r
+       .ECG_HPF_MinLimit = 0.67,          //ECG HPF test limit\r
+       .ECG_MaxAMP = 0.05,                        //ECG SIGNAL test limit\r
+       .ECG_MaxFreq = 0.012,          //ECG SIGNAL test limit\r
+       .ECG_SIGNAL_MaxLimit = 0.25,   //ECG SIGNAL test limit\r
+       .ECG_RLD_MaxAmp = 900.0,           //ECG RLD test limit\r
+       .ECG_CMRR_MinLimit = 85.0,         //ECG CMRR test limit\r
+       .ECG_LIN_MaxLimit = 0.0470,        //ECG LIN test limit\r
+       .ECG_DCRange_MaxLimit = 0.060, //ECG DCRange test limit\r
+                                       \r
+};\r
+\r
+/********END OF FILE********* Copyright (c) 2003 - 2022, Goodix Co., Ltd. ********/\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_mp_code/src/gh3x2x_mp_reg_config.c b/code/sdk/drivers/peripheral/ppg/gh3x2x/demo_mp_code/src/gh3x2x_mp_reg_config.c
new file mode 100644 (file)
index 0000000..e039728
--- /dev/null
@@ -0,0 +1,48 @@
+/**\r
+ * @copyright (c) 2003 - 2022, Goodix Co., Ltd. All rights reserved.\r
+ * \r
+ * @file    gh3x2x_mp_reg_config.c\r
+ * \r
+ * @brief   gh3x2x mp test reg config\r
+ * \r
+ * @author  Goodix Product Tools Development Team\r
+ * \r
+ */\r
+\r
+#include "gh3x2x_mp_reg_config.h"\r
+\r
+const stGh3x2xReg stGh3x2xMpRegConfigDefault[] =\r
+{\r
+       { 0x0004, 0x001F }, { 0x000A, 0x000A }, { 0x000E, 0x000D }, { 0x0100, 0x0800 }, { 0x010A, 0x0644 }, { 0x010C, 0x0001 },\r
+       { 0x010E, 0x0000 }, { 0x0110, 0x0015 }, { 0x0112, 0x4440 }, { 0x011E, 0x0200 }, { 0x0120, 0x0100 }, { 0x01EC, 0x03D9 },\r
+       { 0x0280, 0x0A00 }, { 0x0282, 0xBE93 }, { 0x0284, 0xB332 }, { 0x0286, 0xBAC8 }, { 0x0288, 0xB6FD }, { 0x0502, 0x4F60 },\r
+       { 0x0504, 0x000A }, { 0x0588, 0x0008 }, { 0x0692, 0x0222 }, { 0x0694, 0x0400 }, { 0x0698, 0x2310 }, { 0x0700, 0x0000 },\r
+};\r
+\r
+const stGh3x2xReg stGh3x2xMpRegPPGConfig[] = \r
+{\r
+    { 0x0004, 0x001F }, { 0x000A, 0x0020 }, { 0x000E, 0x000D }, { 0x0280, 0x0A00 }, { 0x0282, 0xBE93 }, { 0x0284, 0xB332 },\r
+    { 0x0286, 0xBAC8 }, { 0x0288, 0xB6FD }, { 0x0502, 0x4F60 }, { 0x0504, 0x000A }, { 0x0588, 0x0008 }, { 0x0692, 0x0222 },\r
+    { 0x0694, 0x0400 }, { 0x0698, 0x2310 }, { 0x0700, 0x0000 },\r
+};\r
+\r
+const stGh3x2xReg stGh3x2xMpRegECGLeadConfg[] = \r
+{\r
+       { 0x0004, 0x0013 }, { 0x0006, 0x0101 }, { 0x000A, 0x0096 }, { 0x000E, 0x000D }, { 0x0074, 0x0050 }, { 0x0100, 0x0100 },\r
+    { 0x010A, 0x0162 }, { 0x010C, 0x0000 }, { 0x010E, 0x0000 }, { 0x0126, 0xC73C }, { 0x012C, 0x0C10 }, { 0x012E, 0x2222 },\r
+    { 0x0130, 0x00AA }, { 0x0136, 0x00FF }, { 0x013A, 0x000C }, { 0x013C, 0x0400 }, { 0x01EA, 0x0033 }, { 0x01EC, 0x0030 },\r
+    { 0x01EE, 0x0098 }, { 0x0200, 0x1020 }, { 0x0402, 0x5555 }, { 0x0404, 0x4130 }, { 0x0406, 0x0041 }, { 0x0408, 0x0001 },\r
+    { 0x0410, 0x49F0 }, { 0x0412, 0x0082 }, { 0x0414, 0x49F0 }, { 0x0416, 0x0082 }, { 0x0422, 0x0011 }, { 0x0424, 0x0901 },\r
+    { 0x0426, 0x0101 }, { 0x0428, 0x0104 }, { 0x0480, 0x6550 }, { 0x0502, 0x4C66 }, { 0x0588, 0x0008 }, { 0x0692, 0x0233 },\r
+    { 0x0694, 0x0404 }, { 0x0698, 0x3310 }, { 0x069A, 0x1101 }, { 0x0700, 0x0000 }, { 0x0400, 0x5557 }, \r
+};\r
+\r
+const stGh3x2xReg stGh3x2xMpRegECGConfgDefault[] = \r
+{\r
+       { 0x0004, 0x001F }, { 0x000A, 0x0019 }, { 0x0074, 0x0058 }, { 0x0100, 0x0800 }, { 0x010A, 0x0062 }, { 0x010E, 0x0004 },\r
+    { 0x01EA, 0x0033 }, { 0x01EC, 0x0064 }, { 0x0300, 0x0001 }, { 0x0302, 0x0103 }, { 0x0400, 0x5550 }, { 0x0402, 0x5555 },\r
+    { 0x0404, 0x4120 }, { 0x0406, 0x0051 }, { 0x0408, 0x0001 }, { 0x0426, 0x0101 }, { 0x0428, 0x0101 }, { 0x0480, 0x6551 },\r
+    { 0x0504, 0x001E }, { 0x0506, 0x001E }, { 0x0694, 0x0404 }, { 0x0698, 0x2310 }, { 0x0700, 0x0000 },\r
+};\r
+\r
+/********END OF FILE********* Copyright (c) 2003 - 2022, Goodix Co., Ltd. ********/\r
index 95f900c..09703eb 100644 (file)
@@ -176,7 +176,7 @@ typedef long long           GS64;   /**< 64bit signed integer type */
 #define   GH3X2X_VAL_GET_BIT(x, b)          ((x) &= (b))\r
 \r
 \r
-#define GH3X2X_AFE_I2C_DEVICE_BASE        (0x28)\r
+#define GH3X2X_AFE_I2C_DEVICE_BASE        (0x14)\r
 #define GH3X2X_AFE_I2C_DEVICE_ADDR        (GH3X2X_AFE_I2C_DEVICE_BASE | (GH3X2X_AFE_I2C_DEVICE_CTRL_PIN_STATUS << 1))\r
 \r
 \r
@@ -423,7 +423,7 @@ void *GH3X2X_Memset(void* pDest, GCHAR chVal, GU32 unByteSize);
 void GH3X2X_RecordAgcInfo(void);\r
 void GH3X2X_UpdateAgcInfo(void);\r
 \r
-void gh3x2x_control(char* mode, uint8_t enable);\r
+// void gh3x2x_control(char* mode, uint8_t enable);\r
 \r
 /*********************************************** master-slaver interface lib function *********************************/\r
 #define GH3X2X_INFO_LOG(...)                    do {\\r
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/lib/dl.a b/code/sdk/drivers/peripheral/ppg/gh3x2x/lib/dl.a
new file mode 100644 (file)
index 0000000..12e9124
Binary files /dev/null and b/code/sdk/drivers/peripheral/ppg/gh3x2x/lib/dl.a differ
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/lib/drv_common.a b/code/sdk/drivers/peripheral/ppg/gh3x2x/lib/drv_common.a
new file mode 100644 (file)
index 0000000..f88e7fa
Binary files /dev/null and b/code/sdk/drivers/peripheral/ppg/gh3x2x/lib/drv_common.a differ
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/lib/dsp.a b/code/sdk/drivers/peripheral/ppg/gh3x2x/lib/dsp.a
new file mode 100644 (file)
index 0000000..936d2ca
Binary files /dev/null and b/code/sdk/drivers/peripheral/ppg/gh3x2x/lib/dsp.a differ
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/lib/ecg.a b/code/sdk/drivers/peripheral/ppg/gh3x2x/lib/ecg.a
new file mode 100644 (file)
index 0000000..d42d0c8
Binary files /dev/null and b/code/sdk/drivers/peripheral/ppg/gh3x2x/lib/ecg.a differ
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/lib/hr.a b/code/sdk/drivers/peripheral/ppg/gh3x2x/lib/hr.a
new file mode 100644 (file)
index 0000000..f53ad27
Binary files /dev/null and b/code/sdk/drivers/peripheral/ppg/gh3x2x/lib/hr.a differ
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/lib/hrv.a b/code/sdk/drivers/peripheral/ppg/gh3x2x/lib/hrv.a
new file mode 100644 (file)
index 0000000..eaaf4de
Binary files /dev/null and b/code/sdk/drivers/peripheral/ppg/gh3x2x/lib/hrv.a differ
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/lib/nadt.a b/code/sdk/drivers/peripheral/ppg/gh3x2x/lib/nadt.a
new file mode 100644 (file)
index 0000000..0612b9a
Binary files /dev/null and b/code/sdk/drivers/peripheral/ppg/gh3x2x/lib/nadt.a differ
diff --git a/code/sdk/drivers/peripheral/ppg/gh3x2x/lib/spo2.a b/code/sdk/drivers/peripheral/ppg/gh3x2x/lib/spo2.a
new file mode 100644 (file)
index 0000000..ab2516f
Binary files /dev/null and b/code/sdk/drivers/peripheral/ppg/gh3x2x/lib/spo2.a differ
index 5fe8a90..5ccb75c 100644 (file)
@@ -19,7 +19,7 @@
 #include "gh3x2x_afe_demo.h"\r
 \r
 #include "custom_utils.h"\r
-\r
+// #include "gh_demo.h"\r
  \r
 #define SWAP_SIZE_OF_GU16               (2)\r
 #define SWAP_INDEX_OF_NEXT_BYTE         (1)\r
@@ -1311,7 +1311,16 @@ GCHAR *GH3X2X_GetAfeLibVersion(void)
 \r
 GU8 GH3X2X_AFE_GetChipId(void)\r
 {\r
-       return (GU8)GH3X2X_AFE_ReadRegBitField(GH3X2X_WHO_AM_I_REG_ADDR,GH3X2X_WHO_AM_I_LSB,GH3X2X_WHO_AM_I_MSB);\r
+    GU8 chipd_id = (GU8)GH3X2X_AFE_ReadRegBitField(GH3X2X_WHO_AM_I_REG_ADDR,GH3X2X_WHO_AM_I_LSB,GH3X2X_WHO_AM_I_MSB);\r
+       if(GH3X2X_CHIP_ID != chipd_id)\r
+       {\r
+               GH3X2X_INFO_LOG("wrong chip id!! 0x%x\r\n",chipd_id);\r
+       }\r
+    else\r
+    {\r
+        GH3X2X_INFO_LOG("check chip id success!!  0x%x\r\n",chipd_id);\r
+    }\r
+       return chipd_id;\r
 }\r
 \r
 GS8 GH3X2X_AFE_CheckChipId(void)\r
@@ -1498,44 +1507,44 @@ GS8 GH3X2X_AFE_CheckEfuseCrc(void)
     return chRet;\r
 }\r
 \r
-void gh3x2x_control(char* mode, uint8_t enable)\r
-{\r
-\r
-    uint32_t md = 1;\r
-    if (strcmp(mode, "hrs") == 0) {\r
-        md = 0;\r
-    } else if (strcmp(mode, "hrv") == 0) {\r
-        md = 1;\r
-    } else if (strcmp(mode, "spo2") == 0) {\r
-        md = 2;\r
-    } else if (strcmp(mode, "leaklight") == 0) {\r
-        md = 4;\r
-    } else if (strcmp(mode, "graycard") == 0) {\r
-        md = 8;\r
-    } else if (strcmp(mode, "ledoff") == 0) {\r
-        md = 16;\r
-    } else if (strcmp(mode, "wear") == 0) {\r
-        md = 32;\r
-    } else if (strcmp(mode, "single") == 0) {\r
-        md = 64;\r
-    }else if (strcmp(mode, "factory") == 0) {\r
-        md = 128;\r
-    }else if (strcmp(mode, "fpc") == 0) {\r
-        // md = WORK_MODE_UNDEFINED;\r
-    }else if (strcmp(mode, "int") == 0) {\r
-    } \r
-\r
-    if (enable == 1)\r
-    {\r
-        // ppg_service_running_stat = true;\r
-        // uapi_pm_control(PM_APP_WAKE_NEEDED);\r
-        // GH3X2X_AFE_StartFunction(mode);\r
-        GH3X2X_AFE_Init();\r
-        GH3X2X_AFE_StartSampling(1);\r
-\r
-    } else {\r
+// void gh3x2x_control(char* mode, uint8_t enable)\r
+// {\r
+\r
+//     uint32_t md = 1;\r
+//     if (strcmp(mode, "hrs") == 0) {\r
+//         md = 0;\r
+//     } else if (strcmp(mode, "hrv") == 0) {\r
+//         md = 1;\r
+//     } else if (strcmp(mode, "spo2") == 0) {\r
+//         md = 2;\r
+//     } else if (strcmp(mode, "leaklight") == 0) {\r
+//         md = 4;\r
+//     } else if (strcmp(mode, "graycard") == 0) {\r
+//         md = 8;\r
+//     } else if (strcmp(mode, "ledoff") == 0) {\r
+//         md = 16;\r
+//     } else if (strcmp(mode, "wear") == 0) {\r
+//         md = 32;\r
+//     } else if (strcmp(mode, "single") == 0) {\r
+//         md = 64;\r
+//     }else if (strcmp(mode, "factory") == 0) {\r
+//         md = 128;\r
+//     }else if (strcmp(mode, "fpc") == 0) {\r
+//         // md = WORK_MODE_UNDEFINED;\r
+//     }else if (strcmp(mode, "int") == 0) {\r
+//     } \r
+\r
+//     if (enable == 1)\r
+//     {\r
+//         // ppg_service_running_stat = true;\r
+//         // uapi_pm_control(PM_APP_WAKE_NEEDED);\r
+//         // GH3X2X_AFE_StartFunction(mode);\r
+//         // GH3X2X_AFE_Init();\r
+//         // GH3X2X_AFE_StartSampling(1);\r
+//         Gh3x2xDemoInit();\r
+//     } else {\r
         \r
-        // uapi_pm_control(PM_APP_WAKE_NONEED);\r
-        GH3X2X_AFE_StopSampling();\r
-    } \r
-}
\ No newline at end of file
+//         // uapi_pm_control(PM_APP_WAKE_NONEED);\r
+//         // GH3X2X_AFE_StopSampling();\r
+//     } \r
+// }
\ No newline at end of file
index 72781f9..fd28f68 100644 (file)
@@ -466,6 +466,6 @@ void GH3X2X_AFE_Log(GCHAR *log_string)
 {\r
     // GH3X2X_AFE_UNUSED_VAR(log_string);\r
     // GOODIX_PLATFORM_LOG_ENTITY();\r
-    PRINT("%s", log_string);\r
+    printf("%s", log_string);\r
 }\r
 \r
index aa7e24c..770034a 100644 (file)
@@ -2,7 +2,7 @@
  * @Author: penglei 1624952103@qq.com
  * @Date: 2024-03-13 15:08:38
  * @LastEditors: penglei 1624952103@qq.com
- * @LastEditTime: 2025-07-16 15:34:10
+ * @LastEditTime: 2025-08-21 18:01:32
  * @FilePath: /FD230/code/sdk/drivers/peripheral/ppg/hx3695/hx3695_hal.c
  * @Description: 
  * 
@@ -35,6 +35,7 @@
 
 #ifdef PPG_GH3X2X
 #include "gh3x2x_afe_drv.h"
+// #include "gh_demo.h"
 #endif
 
 
@@ -111,7 +112,7 @@ uint16_t ppg_get_chip_id(void)
 #elif defined PPG_PAH8009
     chip_id = pah8009_get_chip_id();
 #elif defined PPG_GH3X2X
-    // chip_id = GH3X2X_AFE_GetChipId();
+    chip_id = GH3X2X_AFE_GetChipId();
 #endif
     ppg_power_off();
     return chip_id;
@@ -137,9 +138,6 @@ void ppg_int_handler(void)
 {
 #ifdef PPG_PAH8009
     pah8009_int_handler();
-#elif defined PPG_PAH8009
-    hal_gh3x2x_afe_int_handler_call_back();
-    GH3X2X_AFE_ChipPro();
 #endif
 }
 
@@ -153,7 +151,7 @@ void ppg_send_cmd_to_driver(char* mode, uint8_t enable)
 #elif defined PPG_PAH8009
     pah8009_control(mode,enable);
 #elif defined PPG_GH3X2X
-    gh3x2x_control(mode,enable);
+    // gh3x2x_control(mode,enable);
 #endif
     if(!enable)
         ppg_power_off();
index a1623de..d9346d3 100644 (file)
@@ -2,7 +2,7 @@
  * @Author: penglei 1624952103@qq.com
  * @Date: 2024-06-07 11:18:26
  * @LastEditors: penglei 1624952103@qq.com
- * @LastEditTime: 2025-07-16 15:35:58
+ * @LastEditTime: 2025-07-25 17:25:29
  * @FilePath: /FD230/code/sdk/drivers/peripheral/ppg/ppg/ppg_hal.h
  * @Description: 
  * 
index 6147c82..b1659c9 100644 (file)
@@ -86,11 +86,25 @@ static uint8_t work_mode = 0;
 static osTimerId_t g_pah8009_timer = NULL;\r
 \r
 static uint8_t time_cnt = 0;\r
+static uint8_t wear_cnt = 0;\r
 \r
 static int history_wear_status = -1;\r
 \r
 static int data_cnt = 0;\r
 \r
+#if POLLING_MODE\r
+static int time_out = 40;\r
+#endif\r
+\r
+static uint8_t hrs_num = 0;\r
+static int32_t sum_hrs = 0;\r
+static int8_t hrs_data[7] = {0};\r
+static uint8_t left = 0;\r
+static uint8_t right = -1;\r
+static uint8_t avg_hrs = 0;\r
+\r
+static uint8_t timeout = 0;\r
+\r
 //============================================================================\r
 // Private function\r
 //============================================================================\r
@@ -112,34 +126,47 @@ static void error_handle(void);
 \r
 static void pah8009_unwearstatus_update(void)\r
 {\r
-#ifdef SUPPORT_PPG_SERVICE\r
-    ppg_msg_callback_t func =  ppg_get_send_msg_callback_func();\r
     uint8_t data = 0;\r
-    if(func != NULL && !uapi_dev_runtime_get_train_status())\r
+    printf("uapi_dev_runtime_get_train_status() : %d\n",uapi_dev_runtime_get_train_status());    \r
+    if(uapi_dev_runtime_get_train_status())\r
     {\r
-        //为了主界面脱腕灵敏;需要增加未佩戴\r
-        func(PPG_MSG_TYPE_HRS_UPDATE, &data, 1);\r
-        func(PPG_MSG_TYPE_WEARSTAT_UPDATE, &data,1);\r
-        func(PPG_MSG_TYPE_WEARSTAT_UPDATE,&data,1);\r
-        func(PPG_MSG_TYPE_WEARSTAT_UPDATE,&data,1);\r
+#ifdef SUPPORT_CYWEE_SERVICE\r
+        do_cywee_service_check_msg(CYWEE_SERVICE_CMD_HRS_CHANGE,&data);\r
+#endif\r
     }\r
+    else\r
+    {\r
+#ifdef SUPPORT_PPG_SERVICE\r
+        ppg_msg_callback_t func =  ppg_get_send_msg_callback_func();\r
+        if(func != NULL)\r
+        {\r
+            //为了主界面脱腕灵敏;需要增加未佩戴\r
+            func(PPG_MSG_TYPE_HRS_UPDATE, &data, 1);\r
+            func(PPG_MSG_TYPE_WEARSTAT_UPDATE, &data,1);\r
+            func(PPG_MSG_TYPE_WEARSTAT_UPDATE,&data,1);\r
+            func(PPG_MSG_TYPE_WEARSTAT_UPDATE,&data,1);\r
+        }\r
 #endif\r
+    }\r
+\r
 }   \r
 \r
 static void pah8009_wearstatus_update(int wear_status)\r
 {\r
     if(history_wear_status != wear_status)\r
     {\r
+        wear_cnt++;\r
+        \r
         history_wear_status = wear_status;\r
 #ifdef SUPPORT_CYWEE_SERVICE\r
         do_cywee_service_check_msg(CYWEE_SERVICE_CMD_WEAR_STATUS_CHANGE,(uint8_t *)&history_wear_status);\r
 #endif\r
+        if(wear_status != 1)\r
+        {\r
+            pah8009_unwearstatus_update();\r
+        }\r
     }\r
 \r
-    if(wear_status != 1)\r
-    {\r
-        pah8009_unwearstatus_update();\r
-    }\r
 }\r
 \r
 static void bubblesort(float *input,int count) \r
@@ -358,6 +385,13 @@ void pah_sensor_stop(void)
     pah_800x_deinit(&_main.pah_800x);   \r
 \r
     hr = 0;   \r
+    hrs_num = 0;\r
+    sum_hrs = 0;\r
+    memset(hrs_data,0,7);\r
+\r
+    left = 0;\r
+    right = -1;\r
+    avg_hrs = 0;\r
 }\r
 \r
 void ppg_interrupt_handle(void)\r
@@ -447,7 +481,41 @@ void hr_algorithm_disable(void)
     _main.hr_is_enabled = false;\r
 }\r
 \r
+static void get_avg_hrs(uint8_t hrs)\r
+{\r
+    int32_t min_hrs = 0;\r
+    int32_t max_hrs = 0;\r
+    if(hrs_num == 7)\r
+    {\r
+        sum_hrs -= hrs_data[left];\r
+        hrs_data[left] = 0;\r
+        left++;\r
+        left = left % 7;\r
+        hrs_num--;\r
+    }\r
 \r
+    hrs_num++;\r
+    right++;\r
+    right = right % 7;\r
+\r
+    hrs_data[right] = hrs;\r
+    sum_hrs += hrs_data[right];   \r
+\r
+    if(hrs_num > 2)\r
+    {\r
+        min_hrs = hrs_data[0];\r
+        max_hrs = hrs_data[0];\r
+        for (int i = 0;i < hrs_num; i++)\r
+        {\r
+            if (hrs_data[i] < min_hrs)\r
+                min_hrs = hrs_data[i];\r
+            if (hrs_data[i] > max_hrs)\r
+                max_hrs = hrs_data[i];\r
+        }\r
+        avg_hrs = (sum_hrs - max_hrs - min_hrs) / (hrs_num - 2);\r
+        // printf("max_hrs[%d],min_hrs[%d],avg_hrs[%d]\n",max_hrs,min_hrs,avg_hrs);\r
+    }\r
+}\r
 \r
 void hr_alg_task(void)\r
 {\r
@@ -468,7 +536,12 @@ void hr_alg_task(void)
         if(pah_pop(&ppg_mems_data_alg))    //Get data from FIFO\r
         {\r
             if(_main.hr_is_enabled)\r
-            {\r
+            { \r
+                ppg_mems_data_alg.ppg_data.has_overflow = 0;\r
+                ppg_mems_data_alg.ppg_data.overflow_num = 0;\r
+\r
+                \r
+\r
                 // 13Bytes format to hr lib;\r
                 sRaw_Data_13Bytes hr_data;\r
 \r
@@ -483,8 +556,7 @@ void hr_alg_task(void)
                 hr_data.rsv = 0;\r
                 hr_data.touch = (ppg_mems_data_alg.touch_flag > 0 ? 0x80 : 0x00);\r
                 hr_data.rsv2 = 0;\r
-  \r
-  \r
+\r
                 int32_t ret = PxiAlg_Process_Expo((uint8_t*)&hr_data, ppg_mems_data_alg.MEMS_Data, ppg_mems_data_alg.ppg_data.exposure_time[1]);\r
   \r
 \r
@@ -504,56 +576,33 @@ void hr_alg_task(void)
 #ifdef SUPPORT_PPG_SERVICE\r
                 time_cnt++;\r
 \r
-                ppg_msg_callback_t func =  ppg_get_send_msg_callback_func();\r
-                int ii=0;\r
-                if(func != NULL && time_cnt >= 25)\r
+                if(time_cnt >= 25) \r
                 {\r
-                    uint8_t data = (uint8_t)hr;\r
-                    func(PPG_MSG_TYPE_HRS_UPDATE, &data, 1);\r
-                    // data = cywee_wear_status;\r
-                    // func(PPG_MSG_TYPE_WEARSTAT_UPDATE, &data, 1);\r
-                    time_cnt = 0;\r
+                    ppg_msg_callback_t func =  ppg_get_send_msg_callback_func();\r
 \r
-                    data_cnt+=8;\r
-                \r
-                if(uapi_dev_runtime_get_hrs_ble_status())\r
-                {\r
-                    uint8_t encoded_hrm[17] = {0};//PPG_DATA_LEN_MAX>17会导致APP连接提示定义设备与所选类型不匹配\r
-  \r
-                    for(ii = 0; ii<8; ii++)\r
+                    if(func != NULL)\r
                     {\r
+                        uint8_t data = (uint8_t)hr;\r
 \r
-                        encoded_hrm[0] = 0x55;//心率标志位,一定要设置正确\r
-                        encoded_hrm[1] = (uint8_t)(data_cnt - 8 + ii) % 256;//原始data_cnt会一直自加,但是这里只有一个字节,0-255循环\r
-                        encoded_hrm[2] = (uint8_t)hr;//心率值\r
-\r
-                        encoded_hrm[3] = 0;    //绿灯原始数据\r
-                        encoded_hrm[4] = 0;                            //绿灯原始数据\r
-                        encoded_hrm[5] = 0;                                                    //绿灯原始数据\r
-\r
-                        encoded_hrm[6] = 0;            //ir原始数据\r
-                        encoded_hrm[7] = 0;                                    //ir原始数据\r
-                        encoded_hrm[8] = 0;                                                    //ir原始数据\r
+                        if(data > 30 && data < 220)\r
+                                   get_avg_hrs(data);\r
 \r
-                        encoded_hrm[9] = 0;//模拟x,1234换成填入自己的x数据\r
-                        encoded_hrm[10] = 0;\r
-                        encoded_hrm[11] = 0;//模拟y,-1234换成填入自己的y数据\r
-                        encoded_hrm[12] = 0;\r
-                        encoded_hrm[13] = 0;//模拟z,3987换成填入自己的z数据\r
-                        encoded_hrm[14] = 0;       \r
-                        \r
-                        encoded_hrm[15] = 0;//绿灯电流\r
-                        encoded_hrm[16] = 0;//红外电流\r
+                        // printf("func(PPG_MSG_TYPE_HRS_UPDATE, &avg_hrs, 1); :%d\n",avg_hrs);\r
+                        // func(PPG_MSG_TYPE_HRS_UPDATE, &avg_hrs, 1);\r
 \r
-                        // if(cm_custom_ble_service_on_flag())\r
-                            ble_ppgtest_server_send_input_report(encoded_hrm,17);\r
+                        // data = cywee_wear_status;\r
+                        // func(PPG_MSG_TYPE_WEARSTAT_UPDATE, &data, 1);\r
+                        time_cnt = 0;\r
+              \r
+                        if(uapi_dev_runtime_get_hrs_ble_status())\r
+                        {\r
+                            ble_ppgtest_server_send_input_report(&avg_hrs,1);\r
+                        }\r
 \r
-                        // ble_op_att_send_data(ATT_CHARACTERISTIC_2a37_01_VALUE_HANDLE,encoded_hrm, \\r
-                        //     sizeof(encoded_hrm)/sizeof(encoded_hrm[0]), ATT_OP_NOTIFY);//heartrate \r
                     }\r
                 }\r
 \r
-                }\r
+                \r
 \r
                     \r
 #endif\r
@@ -1667,6 +1716,7 @@ int32_t pah8009_get_factory_data(void)
 \r
 void pah8009_int_handler(void)\r
 {\r
+    timeout = 1;\r
     ppg_interrupt_handle();\r
     ppg_sensor_task_interrupt();\r
     \r
@@ -1702,6 +1752,7 @@ void pah8009_timer_handler(void)
 \r
 static void pah8009_timer_callback(void)\r
 {\r
+    // printf("pah8009_timer_callback \n");\r
 #ifdef SUPPORT_PPG_SERVICE\r
     send_ppg_cmd_msg(PPG_SERVICE_CMD_TYPE_DO_PPG_HRS_TIMER_CALLBACK);\r
 #endif\r
@@ -1713,6 +1764,33 @@ static void pah8009_timer_init(void)
         g_pah8009_timer = osTimerNew((osTimerFunc_t)pah8009_timer_callback, osTimerPeriodic, NULL, NULL);\r
 }\r
 \r
+void pah8009_check_int(void)\r
+{\r
+#if INTERRUPT_MODE\r
+    if(work_mode != 1)\r
+    {\r
+        // printf("work_mode != 1\n");\r
+        return;\r
+    }\r
+\r
+    if(!timeout)\r
+    {\r
+        // printf("pah8009_check_int \n");\r
+        pah8009_int_handler();\r
+    }\r
+    else\r
+    {\r
+        timeout = 0;\r
+    }\r
+#endif\r
+}\r
+\r
+void pah8009_reset(void)\r
+{\r
+    pah_sensor_stop();\r
+    pah_sensor_init(diw_4mm_g_ir_hrd);\r
+    ppg_only_sensor_start();\r
+}\r
 \r
 void pah8009_control(char *mode,uint8_t enable)\r
 {\r
@@ -1724,6 +1802,7 @@ void pah8009_control(char *mode,uint8_t enable)
             osTimerStop(g_pah8009_timer);\r
 #endif\r
         pah_sensor_stop();\r
+        work_mode = 0;\r
         if(uapi_dev_runtime_get_sleep_monitoring_status() && uapi_dev_runtime_get_hrs_passivity_flag())\r
         {\r
             pah8009_wearstatus_update(history_wear_status);   \r
@@ -1744,6 +1823,9 @@ void pah8009_control(char *mode,uint8_t enable)
             work_mode = 1;\r
             // touch_only_sensor_start();\r
             ppg_only_sensor_start();\r
+#if POLLING_MODE\r
+            time_out = 20;\r
+#endif\r
         } else if (strcmp(mode, "hrv") == 0) {\r
             // md = HRV_MODE;\r
         } else if (strcmp(mode, "spo2") == 0) {\r
@@ -1751,6 +1833,9 @@ void pah8009_control(char *mode,uint8_t enable)
             pah_sensor_init(diw_4mm_ir_r_ir_spo2);\r
             ppg_only_sensor_start();\r
             work_mode = 2;\r
+#if POLLING_MODE\r
+            time_out = 20;\r
+#endif\r
         } else if (strcmp(mode, "leaklight") == 0) {\r
             // md = FT_LEAK_LIGHT_MODE;\r
             factory_test_mode(factory_test_leak_light_target_sample, 0, 0, 0, 0);\r
@@ -1759,10 +1844,13 @@ void pah8009_control(char *mode,uint8_t enable)
         } else if (strcmp(mode, "wear") == 0) {\r
             pah_sensor_init(diw_4mm_g_ir_hrd);\r
             touch_only_sensor_start();\r
+#if POLLING_MODE\r
+            time_out = 5000;\r
+#endif\r
         }\r
 #if POLLING_MODE\r
         if(g_pah8009_timer != NULL)\r
-            osTimerStart(g_pah8009_timer,40);\r
+            osTimerStart(g_pah8009_timer,time_out);\r
 #endif\r
     }\r
 }
\ No newline at end of file
index 170110e..eb3a5ea 100644 (file)
@@ -64,8 +64,8 @@
  * This definition will enable the corresponding demo functionin main.c\r
  * If select INT mode, then slect following INT configuration type\r
  */\r
-#define INTERRUPT_MODE      1\r
-#define POLLING_MODE        0\r
+#define INTERRUPT_MODE      0\r
+#define POLLING_MODE        1\r
 #define Test_pattern_mode   0\r
 \r
 /*\r
index fc1668d..9ae4132 100644 (file)
@@ -114,13 +114,13 @@ errcode_t ble_ppgtest_server_send_input_report(const uint8_t *data, uint8_t len)
     // printf("ble_hid_server_send_input_report:%d %d %d",data[0],data[1],len);\r
     gatts_ntf_ind_t param = {0};\r
     param.attr_handle = (uint16_t)g_ppgtest_notify_report_att_hdl;\r
-    param.value_len = len;\r
-    param.value = bt_os_new(len);\r
+    param.value_len = len + 1;\r
+    param.value = bt_os_new(param.value_len);\r
     if (param.value == NULL) {\r
         printf(  "[ppgtest][ERROR]send input report new fail\r\n");\r
         return ERRCODE_BT_MALLOC_FAIL;\r
     }\r
-    if (memcpy_s(param.value, param.value_len, data, len) != EOK) {\r
+    if (memcpy_s(param.value + 1, param.value_len, data, len) != EOK) {\r
         printf( "[ppgtest][ERROR]send input report memcpy fail\r\n");\r
         bt_os_free(param.value);\r
         return ERRCODE_BT_FAIL;\r
index 08cb733..4d858ca 100644 (file)
@@ -396,11 +396,7 @@ errcode_t uapi_ppg_service_init(void)
     app_task_definition_t taskcfg={0};
     taskcfg.create_queue_handle = create_ppg_queue;
     taskcfg.attr.name="ppg_service";
-#ifdef BOARD_FD230
     taskcfg.attr.priority = osPriorityBelowNormal4;
-#else
-    taskcfg.attr.priority = osPriorityAboveNormal3;
-#endif
     taskcfg.attr.stack_size = PPG_SERVICE_TASK_SIZE;
     taskcfg.func = ppg_service_check_task;
     taskcfg.use_mem = USE_EXTEND_MEM;
index dd891de..b77e991 100644 (file)
@@ -2035,10 +2035,10 @@ void get_gsensor_single(uint8_t *databuf)
 {
     gsenson_t t;
     get_gsonsen_xyz(&t);
-    uint16_t x,y,z;
-    x = t.x*2048;
-    y = t.y*2048;
-    z = t.z*2048;
+    int16_t x, y, z;
+    x = (int16_t)(t.x * 2048);
+    y = (int16_t)(t.y * 2048);
+    z = (int16_t)(t.z * 2048);
 
     databuf[0] = (uint8_t)((x & 0xFF00) >> 8);
     databuf[1] = (uint8_t)(x & 0x00FF);
index d165483..104a6d0 100644 (file)
@@ -2,7 +2,7 @@
  * @Author: penglei 1624952103@qq.com
  * @Date: 2024-08-08 16:33:23
  * @LastEditors: penglei 1624952103@qq.com
- * @LastEditTime: 2024-12-19 18:04:22
+ * @LastEditTime: 2025-08-21 16:11:55
  * @FilePath: /FD230/code/sdk/drivers/peripheral/vibrator/service/vibrator_service.cpp
  * @Description: 
  * 
@@ -29,28 +29,8 @@ extern "C" {
 #endif /* __cplusplus */
 
 
-#include "pinctrl.h"
 #include "debug_print.h"
-#include "soc_osal.h"
-#include "tcxo.h"
-#include "irmalloc.h"
-#include "errcode.h"
 #include "common_def.h"
-
-#include "chip_core_irq.h"
-#include "chip_io.h"
-#include "gpio.h"
-#include "pm_veto.h"
-
-#include "rtc.h"
-#include "timer.h"
-#include "systick.h"
-
-
-static bool g_batter_service_initialled = false;
-
-#include "tcxo.h"
-
 #include "cmsis_os2.h"
 #include "input_app.h"
 
@@ -223,7 +203,7 @@ errcode_t uapi_vibrator_service_init(void)
     OHOS::VibratorManager::GetInstance()->RegisterVibratorFunc(custom_VibratorFunc);
 
     /* ---------------------------------- 开机震动一次 ---------------------------------- */
-    ui_api_vibrate_once_func();
+    custom_VibratorFunc_int(0);
     /* -------------------------------------------------------------------------- */
     
     return ERRCODE_SUCC;
index 9e10070..8462544 100755 (executable)
@@ -191,8 +191,11 @@ static int32_t AIDevOpen(td_handle *aiHandle, enum AudioCategory audioCategory)
         uapi_ai_gain gain = {};
         MEDIA_HAL_DOFUNC_TIME(ret = uapi_ai_get_volume(*aiHandle, &gain));
         CHK_FAILED_RETURN(ret, MEDIA_HAL_OK, ret, "uapi_ai_get_volume failed");
-
+#if defined(BOARD_N9) || defined(BOARD_W9)
+        gain.integer = gain.integer + 10; // 前端mic灵敏度不同可通过此处调增,增加4db增益  默认gain.integer = gain.integer+4
+#elif defined(BOARD_FD230)
         gain.integer = gain.integer - 9; // 前端mic灵敏度不同可通过此处调增,增加4db增益  默认gain.integer = gain.integer+4
+#endif
         MEDIA_HAL_DOFUNC_TIME(ret = uapi_ai_set_volume(*aiHandle, &gain));
         CHK_FAILED_RETURN(ret, MEDIA_HAL_OK, ret, "uapi_ai_set_volume failed");
         g_subPortTrackInOpened = true;