更新原相8311驱动,优化UI漏光测试显示 3442/1 3442/head
author1624952103 <pl@DESKTOP-EN9LKR5.localdomain>
Mon, 8 Jun 2026 08:23:30 +0000 (16:23 +0800)
committer1624952103 <pl@DESKTOP-EN9LKR5.localdomain>
Mon, 8 Jun 2026 08:23:30 +0000 (16:23 +0800)
86 files changed:
code/sdk/application/wearable/n9/nativeapp/nativeui/bloodoxygen/src/BloodOxygenModel.cpp
code/sdk/build/config/target_config/brandy/config.py
code/sdk/zhihui/UI/producttest/src/testhrsenson.cpp
code/sdk/zhihui/drivers/cywee/dml/cywee_dml.c
code/sdk/zhihui/drivers/ppg/CMakeLists.txt
code/sdk/zhihui/drivers/ppg/hal/ppg_hal.c
code/sdk/zhihui/drivers/ppg/hal/ppg_hal.h
code/sdk/zhihui/drivers/ppg/hx3695/hx3695.c
code/sdk/zhihui/drivers/ppg/pah831x/CMakeLists.txt [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/ECG_AFIB/V2022/libecgafib_v2022_5.a [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/ECG_AFIB/V2022/libecgafib_v2022_6.a [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/ECG_AFIB/V2022/pah_ecg_afib_alg.c [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/ECG_AFIB/V2022/pah_ecg_afib_alg.h [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/ECG_AFIB/V2022/pah_ecg_afib_api.h [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/ECG_HRV/V103/hcp_ecg_hrv_api.h [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/ECG_HRV/V103/libecghrv_v103_4.a [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/ECG_PPG_BP/v3070/libecgbp_v3070_1.a [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/ECG_PPG_BP/v3070/pah_ecg_bp_alg.c [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/ECG_PPG_BP/v3070/pah_ecg_bp_alg.h [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/ECG_PPG_BP/v3070/pxi_bp_api.h [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/HRD/v5653/libhr_v5653_3.a [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/HRD/v5653/pah831x_testpattern_HRD.h [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/HRD/v5653/pah8series_api_c.h [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/HRD/v5653/pah8series_data_c.h [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/HRD/v5653/pah_hrd_alg.c [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/HRD/v5653/pah_hrd_alg.h [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/HRD/v5653/test_library_HRD.c [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/RAW_ECG/hrv_api.h [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/RAW_ECG/libecgdenoise_v7010_3.a [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/RAW_ECG/libecgdenoise_v7010_5.a [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/RAW_ECG/pah_ecg_raw.c [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/RAW_ECG/pah_ecg_raw.h [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/RAW_PPG/pah_ppg_raw.c [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/RAW_PPG/pah_ppg_raw.h [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/RR_HRV_STRESS_RRI/V3131/libhrv_v3131_0.a [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/RR_HRV_STRESS_RRI/V3131/pah831X_testpattern_stress.h [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/RR_HRV_STRESS_RRI/V3131/pah831x_testpattern_HRV.h [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/RR_HRV_STRESS_RRI/V3131/pah831x_testpattern_RR_2.h [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/RR_HRV_STRESS_RRI/V3131/pah_RRI_alg.c [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/RR_HRV_STRESS_RRI/V3131/pah_RRI_alg.h [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/RR_HRV_STRESS_RRI/V3131/pah_RR_alg_V30x.c [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/RR_HRV_STRESS_RRI/V3131/pah_RR_alg_V30x.h [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/RR_HRV_STRESS_RRI/V3131/pah_hrv_alg.c [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/RR_HRV_STRESS_RRI/V3131/pah_hrv_alg.h [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/RR_HRV_STRESS_RRI/V3131/pah_stress_alg.c [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/RR_HRV_STRESS_RRI/V3131/pah_stress_alg.h [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/RR_HRV_STRESS_RRI/V3131/pxialg_hrv_v3.h [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/RR_HRV_STRESS_RRI/V3131/test_library_HRV.c [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/RR_HRV_STRESS_RRI/V3131/test_library_RR2.c [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/RR_HRV_STRESS_RRI/V3131/test_library_stress.c [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/SHRD/V307009/libv307009_4.a [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/SHRD/V307009/pah_shrd_alg.c [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/SHRD/V307009/pah_shrd_alg.h [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/SHRD/V307009/pxialg.h [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/SHRD/V307009/pxivar.h [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/SPO2/V587/libspo2_v587_20.a [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/SPO2/V587/pah831x_testpattern_V587_1.h [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/SPO2/V587/pah_spo2_alg.c [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/SPO2/V587/pah_spo2_alg.h [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/SPO2/V587/pxialg_spo2.h [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/SPO2/V587/test_library_SPO2_V587.c [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah831x/pah/pah_plat.h [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah831x/pah/pah_plat_inc.h [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah831x/pah/pah_reg.h [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah831x/pah/pah_ret.h [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah831x/pah/pah_util.h [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah831x/pah831x_factory_20251217/demo_factory_v3.c [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah831x/pah831x_factory_20251217/pah831x_factory_test_v3.c [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah831x/pah831x_factory_20251217/pah831x_factory_test_v3.h [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah831x/pah831x_factory_20251217/pah831x_verify_cal_v3.h [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah831x/pah831x_factory_20251217/pah831x_verify_reg_v3.h [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah831x/pah_sensor/pah831x.c [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah831x/pah_sensor/pah831x.h [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah831x/pah_sensor/pah831x_comm.c [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah831x/pah_sensor/pah831x_comm.h [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah831x/pah_sensor/pah831x_config.h [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah831x/pah_sensor/pah831x_define.h [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah831x/pah_sensor/pah831x_main.c [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah831x/pah_sensor/pah831x_main.h [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah831x/pah_sensor/pah831x_reg_default_note_0109_1LED.h [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah831x/pah_sensor/pah831x_reg_default_note_0109_2LED_20251223.h [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/pah831x/pah_sensor/pah831x_reg_default_note_0109_2LED_20251226.h [new file with mode: 0644]
code/sdk/zhihui/drivers/ppg/service/ppg_at_cmd.cpp
code/sdk/zhihui/drivers/ppg/service/ppg_service.cpp
code/sdk/zhihui/drivers/ppg/service/ppg_service.h
code/sdk/zhihui/services/gnss/src/gnss_http_server.c

index 2e58ded..c3d9299 100644 (file)
@@ -24,8 +24,8 @@
 #include "health/BloodCardView.h"
 #include <custom_save_runtime.h>
 
-#define MAX_UNWARE_COUNT 10
-#define MAX_VALID_SPO2_COUNT 30
+#define MAX_UNWARE_COUNT 1
+#define MAX_VALID_SPO2_COUNT 15
 #define MAX_DISVALID_SPO2_COUNT 60
 #define BLOOD_TIMER_DATA 1
 
@@ -261,7 +261,7 @@ void BloodOxygenModel::UpSPO2data(uint8_t spo2) {
   if (valid_counter_ >= MAX_VALID_SPO2_COUNT) {
     if(displayspo2 == 100)
     {
-      displayspo2 == 99;
+      displayspo2 = 99;
     }
     currentspo2 = displayspo2;
     WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP,  "检测结果: 成功 valid_counter: %d currentspo2: %d",  valid_counter_, currentspo2);
index 5e46608..f959ea1 100644 (file)
@@ -1002,7 +1002,9 @@ target = {
             'ROTARYENCODER_MIXO',
             'NANDFLASH_F35UQA',
             'BLE_INSTRUCT',
-            'PPG_PAH8009',
+            # 'PPG_PAH8009',
+            'PPG_PAH831X',
+            # 'PPG_HX3695',
             # 'AILPAY_SUPPORT',
             'SUPPORT_FACTORY_SERVICE',
             # 'MEMORY_CORRUPTION',
@@ -1020,7 +1022,9 @@ target = {
             'audio_at_service', 
             'media_at_service', 
             'bt_manager_at_service',
-            "ppg_sensor_pah8009",
+            # "ppg_sensor_pah8009",
+            "ppg_sensor_pah831x",
+            # "ppg_sensor_hx3695",
             "ppgBleService",
             "mag_sensor_mmc5603",
             "vibrator",
index 8ca66da..e71885b 100644 (file)
@@ -115,19 +115,30 @@ namespace OHOS
     }
     void testhrsenson1View:: setlightvalue(void)
     {
-        char buf[124]={0};
+        char fail_buf[512] = {0};
+        char buf[576] = {0};
         if(label_hrsenson_value_vison!=nullptr)
         {
 #ifdef SUPPORT_PPG_SERVICE   
             send_ppg_cmd_msg(PPG_SERVICE_CMD_TYPE_DO_LEAKLIGHT_TEST); 
             LOS_Msleep(1000);
+#ifdef PPG_PAH831X
+            uint16_t fail_len = ppg_get_leaklight_fail_str(fail_buf, sizeof(fail_buf));
+            if (fail_len == 0) {
+                snprintf(buf, sizeof(buf), "漏光测试通过");
+            } else {
+                snprintf(buf, sizeof(buf), "漏光测试失败 失败项如下\n%s\n", fail_buf);
+            }
+#else
             uint32_t ch0 = 0;
             uint32_t ch1 = 0;
             uint32_t ch2 = 0;
-            ppg_get_factory_data(&ch0,&ch1,&ch2);
+            ppg_get_factory_data(&ch0, &ch1, &ch2);
+            snprintf(buf, sizeof(buf), "leaklight:\ngreen:%u\nred:%u\nir:%u",
+                (unsigned int)ch0, (unsigned int)ch1, (unsigned int)ch2);
+#endif
             send_ppg_cmd_msg(PPG_SERVICE_CMD_TYPE_STOP_PPG_TEST);
-            sprintf(buf,"leaklight:\ngreen:%d\nred:%d\nir:%d",ch0,ch1,ch2);
-            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "%s",buf);
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "%s", buf);
             label_hrsenson_value_vison->SetText(buf);
             RootView::GetInstance()->Invalidate();
             button_falg=true;
@@ -270,7 +281,7 @@ namespace OHOS
 
         buttonconfig.x = 300;
         buttonconfig.ViewId="leeklight";
-        buttonconfig.str="光照";
+        buttonconfig.str="测试";
         button_2=SetTheButton_ext(buttonconfig);
         testhrsensonScrollView->Add(button_2);
 
@@ -301,7 +312,7 @@ namespace OHOS
         labelButton_next= testAboutView::GetInstance()->init_button_next(167,378,Test_ViewMapper_t[id].viewid_str_next);
         testhrsensonScrollView->Add(labelButton_next);
 
-        Title= testAboutView::GetInstance()->init_title(102,45,"心率传感器测试");
+        Title= testAboutView::GetInstance()->init_title(102,45,"心率漏光测试");
         testhrsensonScrollView->Add(Title);
 
 
index 55ad7b4..b467faa 100644 (file)
@@ -79,6 +79,8 @@ static uint8_t acc_check_cnt = 0;
 
 static uint8_t abs_solute_time = 90;
 
+// static osal_mutex g_mutex = { 0 };
+
 /**
  * @brief 更新燃脂时间
  * @param current_mhr_zone 当前心率区间 (2表示燃脂区间)
@@ -343,9 +345,16 @@ static void clean_sleep_data(void)
     memset(status_file_path, 0, sizeof(status_file_path));
     memset(dir_path, 0, sizeof(dir_path));
     memset(nap_file_path, 0, sizeof(nap_file_path));
+
     wake_up_flag = 0;
 }
 
+static void cywee_clean_ui_sleep_data(void)
+{
+    memset(&ui_nap_data, 0, sizeof(ui_nap_data));
+    memset(&ui_sleep_data, 0, sizeof(ui_nap_data));
+}
+
 void cywee_read_nap_data(void)
 {
     char day[12] = {0};
@@ -1019,6 +1028,11 @@ void cywee_set_stand_flag(void)
     stand_flag = 1;
 }
 
+void cywee_reset_stand_flag(void)
+{
+    stand_flag = 0;
+}
+
 uint8_t cywee_get_stand_flag(void)
 {
     return stand_flag;
@@ -1168,6 +1182,19 @@ void cywee_wearstatus_update(int wearstatus)
                 cywee_inactivity_mode_change(INACTIVITY_MODE_SEDENTARY_AND_NAP);
             }
         }
+        // else if(uapi_dev_runtime_get_sleep_monitoring_status())
+        // {
+        //     if(uapi_dev_runtime_get_sleep_status())
+        //     {
+        //         uapi_dev_runtime_set_absolute_static_status(1);
+        //         cywee_get_sleep_data(1);
+        //     }
+        //     else
+        //     {
+        //         cywee_inactivity_mode_change(INACTIVITY_MODE_NOTHING);
+        //         cywee_inactivity_mode_change(INACTIVITY_MODE_SLEEPING);
+        //     }
+        // }
 
         wearstatus = 0;
     }
@@ -1238,7 +1265,7 @@ void cywee_inactivity_mode_change(int mode)
         //睡眠
         case INACTIVITY_MODE_SLEEPING:
             // CWM_OS_dbgPrintf("INACTIVITY_MODE_SLEEPING\r\n");  
-            
+            cywee_clean_ui_sleep_data();
             //设置睡眠
             memset(&scl, 0, sizeof(scl));
             scl.iData[0] = 1;
@@ -1297,6 +1324,8 @@ void cywee_activity_mode_change(int mode)
     else
         cywee_sport_timer_stop_check();
     
+    last_fat_burn_timestamp = 0;
+
     if(mode == SPORT_ACTIVE_MODE_FREE_TRAINING)
         is_free_trainning_mode = 1;
     else
@@ -1363,37 +1392,82 @@ void cywee_activity_mode_change(int mode)
     }
 }
 
-void cywee_get_gsensor_data(uint8_t cnt,gsenson_t t[])
+// 缓存最近一次的有效GSensor数据(最多9组,适配1~9组取数)
+static gsenson_t g_gsensor_history[9] = {0};
+// 标记缓存是否有效(避免初始状态复用空缓存)
+static uint8_t g_history_valid = 0;
+
+void cywee_get_gsensor_data(uint8_t cnt, gsenson_t t[])
 {
-    if(t == NULL)
+    if(t == NULL || cnt < 1 || cnt > 9) {
+        CWM_OS_dbgPrintf("[GET_DATA] 参数异常 - cnt=%d\n", cnt);
+        // 参数异常时,复用历史数据(避免返回0值)
+        if(t != NULL && g_history_valid) {
+            memcpy(t, g_gsensor_history, sizeof(gsenson_t) * cnt);
+        }
         return;
+    }
 
-    for(int i=0;i<cnt;i++)
+    // 初始化输出数组(避免脏数据)
+    memset(t, 0, sizeof(gsenson_t) * cnt);
+    // if(g_mutex.mutex != NULL)
+        // osal_mutex_lock(&g_mutex);
+    uint8_t actual_read = 0; // 实际读取的新数据组数
+    // CWM_OS_dbgPrintf("[GET_DATA] 取数前 - num_flag=%d, left_flag=%d, cnt=%d\n", num_flag, left_flag, cnt);
+
+    // 1. 读取可用的新数据(最多cnt组)
+    for(int i=0; i<cnt && num_flag > 0; i++)
     {
-        // if(osal_mutex_trylock(&mutex_gsenson_queue)==0)
-        // {
-        //     CWM_OS_dbgPrintf("get_gsonsen_xyz_fail\n");
-        //     return;
-        // }
-        //CWM_OS_dbgPrintf("x=%.3f, y=%.3f, z=%.3f\n", gxyz_t_queue[left_flag].x, gxyz_t_queue[left_flag].y, gxyz_t_queue[left_flag].z);
-        t[i].x= gxyz_t_queue[left_flag].x;
-        t[i].y= gxyz_t_queue[left_flag].y;
-        t[i].z= gxyz_t_queue[left_flag].z;
+        t[i].x = gxyz_t_queue[left_flag].x;
+        t[i].y = gxyz_t_queue[left_flag].y;
+        t[i].z = gxyz_t_queue[left_flag].z;
+        
+        // CWM_OS_dbgPrintf("[GET_DATA] 第%d组(新数据)- left_flag=%d, 数据(x=%.3f,y=%.3f,z=%.3f)\n",
+        //                  i, left_flag, t[i].x, t[i].y, t[i].z);
 
+        // 清空已读数据
         gxyz_t_queue[left_flag].x = 0.0f;
         gxyz_t_queue[left_flag].y = 0.0f;
         gxyz_t_queue[left_flag].z = 0.0f;
         
-        if(num_flag)
-        {
-            left_flag++;
-            left_flag=left_flag%GSENSON_MSG_COUNT;
-            num_flag--;
+        left_flag = (left_flag + 1) % GSENSON_MSG_COUNT;
+        num_flag--;
+        actual_read++;
+    }
+    // if(g_mutex.mutex != NULL)
+        // osal_mutex_unlock(&g_mutex);
 
-        }   
-        // osal_mutex_unlock(&mutex_gsenson_queue);
+    // 2. 数据不足时,复用历史数据补全
+    if(actual_read < cnt) {
+        // CWM_OS_dbgPrintf("[GET_DATA] 新数据不足(仅%d组),复用历史数据补全剩余%d组\n", actual_read, cnt - actual_read);
+        
+        // 有有效历史数据:补全剩余组数
+        if(g_history_valid) {
+            for(int i=actual_read; i<cnt; i++) {
+                // 复用历史数据(循环复用,保证数据连续性)
+                t[i] = g_gsensor_history[i % cnt];
+                // CWM_OS_dbgPrintf("[GET_DATA] 第%d组(历史数据)- 数据(x=%.3f,y=%.3f,z=%.3f)\n",
+                //                  i, t[i].x, t[i].y, t[i].z);
+            }
+        }
+        // 无历史数据(初始状态):用最后一条新数据补全(避免0值)
+        else if(actual_read > 0) {
+            for(int i=actual_read; i<cnt; i++) {
+                t[i] = t[actual_read - 1];
+                // CWM_OS_dbgPrintf("[GET_DATA] 第%d组(补全数据)- 数据(x=%.3f,y=%.3f,z=%.3f)\n",
+                //                  i, t[i].x, t[i].y, t[i].z);
+            }
+        }
     }
 
+    // 3. 更新历史数据缓存(仅当有新数据时更新)
+    if(actual_read > 0) {
+        memcpy(g_gsensor_history, t, sizeof(gsenson_t) * cnt);
+        g_history_valid = 1; // 标记缓存有效
+        // CWM_OS_dbgPrintf("[GET_DATA] 更新历史数据缓存(%d组)\n", cnt);
+    }
+
+    // CWM_OS_dbgPrintf("[GET_DATA] 取数完成 - 实际读取新数据%d组,返回总数%d组\n", actual_read, cnt);
 }
 
 //static int flag=32;
@@ -1782,7 +1856,7 @@ void CWM_AP_SensorListen(pSensorEVT_t sensorEVT) {
                 // hrs = 0; //每次上报完 清除心率值
                 // cywee_func(CYWEE_MSG_TYPE_ACTIVITY_UPDATE,&c_act_result_t,sizeof(act_result_t));
                 //CustomEventPublish(TOPIC_EVENT_ACTIVITY_UPDATE, &c_act_result_t, sizeof(act_result_t));
-                //CustomEventPublish(TOPIC_EVENT_STEPDATA_UPDATE,&stepcount,sizeof(int)); 
+                CustomEventPublish(TOPIC_EVENT_STEPDATA_UPDATE,&stepcount,sizeof(int)); 
                 // CWM_OS_dbgPrintf("PAH:normal mode activit_mode[%d], steps[%d], distance[%d], calories[%d], step frequency[%d], step length[%.2f], pace[%d]\n",
                 //     c_act_result_t.activity_mode, c_act_result_t.steps, c_act_result_t.distance, c_act_result_t.calories, 
                 //     c_act_result_t.step_frequency,c_act_result_t.step_length, c_act_result_t.pace);
@@ -1886,54 +1960,82 @@ struct AccelerationData {
 };
 static struct AccelerationData rawdata[25];  //自定义buffer,用来缓存sensor数据
 static int AccdataCount = 0;                           //fifo长度
-
 void CWM_APSensorDataOutput_listen(const dml_sensorData_t * pSdo) 
 {
+
+    
     if(AccdataCount < 25)
     {
+        // if(g_mutex.mutex != NULL)
+            // osal_mutex_lock(&g_mutex);
+
         if (pSdo->validData & DML_SENSOR_DATA_VALID_DT)
         {
-            //CWM_OS_dbgPrintf("dt: %d us\n", pSdo->dt_us);
+            // 保留原有dt_us存储逻辑
             rawdata[AccdataCount].dt = pSdo->dt_us;
         }      
         if (pSdo->validData & DML_SENSOR_DATA_VALID_ACC)
         {
-            if(cywee_factory_log)
-                CWM_OS_dbgPrintf("acc: x=%.3f, y=%.3f, z=%.3f\n",pSdo->acc_data[0], pSdo->acc_data[1], pSdo->acc_data[2]);
+            // // 保留原有原始数据打印
+            // CWM_OS_dbgPrintf("[WRITE_DATA] 原始数据 - x=%.3f,y=%.3f,z=%.3f\n",
+            //                  pSdo->acc_data[0], pSdo->acc_data[1], pSdo->acc_data[2]);
+            
+            // // 保留原有写入前状态打印
+            // CWM_OS_dbgPrintf("[WRITE_DATA] 写入前 - num_flag=%d, left_flag=%d, right_flag=%d\n",
+            //                  num_flag, left_flag, right_flag);
+
+            // 保留原有rawdata存储逻辑
             rawdata[AccdataCount].acc_x = pSdo->acc_data[0];
             rawdata[AccdataCount].acc_y = pSdo->acc_data[1];
             rawdata[AccdataCount].acc_z = pSdo->acc_data[2];
 
-            if(num_flag==GSENSON_MSG_COUNT)
+            // ========== 改造点1:统一指针边界校验,适配环形队列 ==========
+            if(num_flag == GSENSON_MSG_COUNT)
             {
-                left_flag++;
-                right_flag++;
-                right_flag=right_flag%GSENSON_MSG_COUNT;
-                left_flag=left_flag%GSENSON_MSG_COUNT;
+                // 优化:用%做边界校验,避免left_flag/right_flag越界(比如64→0)
+                left_flag = (left_flag + 1) % GSENSON_MSG_COUNT;
+                right_flag = (right_flag + 1) % GSENSON_MSG_COUNT;
                 gxyz_t_queue[right_flag].x= pSdo->acc_data[0];
                 gxyz_t_queue[right_flag].y= pSdo->acc_data[1];
                 gxyz_t_queue[right_flag].z= pSdo->acc_data[2];
+
+                // // 保留原有队列满打印
+                // CWM_OS_dbgPrintf("[WRITE_DATA] 队列满 - 写入right_flag=%d, left_flag同步至%d\n",
+                //                  right_flag, left_flag);
             }    
             else 
             {
-                //left_flag++;
-                right_flag++;
-                right_flag=right_flag%GSENSON_MSG_COUNT;
-                //left_flag=left_flag%16;
+                // 优化:用%做边界校验,统一指针操作逻辑
+                right_flag = (right_flag + 1) % GSENSON_MSG_COUNT;
                 num_flag++;
                 gxyz_t_queue[right_flag].x= pSdo->acc_data[0];
                 gxyz_t_queue[right_flag].y= pSdo->acc_data[1];
                 gxyz_t_queue[right_flag].z= pSdo->acc_data[2];
-                //CWM_OS_dbgPrintf("write: x=%d, y=%d, z=%d\n", gxyz_t_queue[right_flag].x ,gxyz_t_queue[right_flag].y ,gxyz_t_queue[right_flag].z);
-            
+
+                // 保留原有队列未满打印
+                // CWM_OS_dbgPrintf("[WRITE_DATA] 队列未满 - 写入right_flag=%d, num_flag=%d\n",
+                //                  right_flag, num_flag);
             }
             
+            // ========== 改造点2:新增环形绕回日志,便于排查错位问题 ==========
+            // if(right_flag < left_flag) {
+            //     CWM_OS_dbgPrintf("[WRITE_DATA] 环形绕回 - right_flag=%d < left_flag=%d, 新数据积压在队列头部\n",
+            //                      right_flag, left_flag);
+            // }
 
+            // // 保留原有写入后状态打印
+            // CWM_OS_dbgPrintf("[WRITE_DATA] 写入后 - num_flag=%d, left_flag=%d, right_flag=%d\n",
+            //                  num_flag, left_flag, right_flag);
+            
+            // 保留原有AccdataCount自增逻辑
             AccdataCount++;
         }     
-    }     
-}
+        // if(g_mutex.mutex != NULL)
+            // osal_mutex_unlock(&g_mutex);
+    }    
+    
 
+}
 #endif
 
 int cywee_start(void) 
@@ -2267,6 +2369,11 @@ int cywee_start(void)
     cywee_oncharging_update(get_charge_stat()); //初始化时检查充电状态
 
     g_sport_timer = osTimerNew((osTimerFunc_t)cywee_service_check_timer_callback, osTimerPeriodic, NULL, NULL);
+
+    // int ret = osal_mutex_init(&g_mutex);
+    // if (ret != 0) {
+    //     printf("osal_mutex_init g_mutex failed\n");
+    // }
     //cywee_inactivity_mode_change(INACTIVITY_MODE_SEDENTARY_AND_NAP);
 
     //cywee_inactivity_mode_change(INACTIVITY_MODE_SLEEPING);
index e90ddc9..6830c0a 100644 (file)
@@ -2,5 +2,6 @@ add_subdirectory_if_exist(service)
 add_subdirectory_if_exist(hx3695)
 add_subdirectory_if_exist(ppgBleService)
 add_subdirectory_if_exist(pah8009)
+add_subdirectory_if_exist(pah831x)
 add_subdirectory_if_exist(gh3x2x)
 add_subdirectory_if_exist(hal)
\ No newline at end of file
index 488ed50..a294eec 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-11-13 14:46:25
+ * @LastEditTime: 2025-12-29 09:45:25
  * @FilePath: /FD230/code/sdk/drivers/peripheral/ppg/hx3695/hx3695_hal.c
  * @Description: 
  * 
 #include "pah800x_main.h"
 #endif
 
+#ifdef PPG_PAH831X
+#include "pah831x_main.h"
+#include "pah831x_factory_test_v3.h"
+#endif
+
 #ifdef PPG_GH3X2X
 #include "gh3x2x_afe_drv.h"
 // #include "gh_demo.h"
@@ -98,6 +103,8 @@ uint8_t ppg_get_hrs(void)
     hrs = hx3695_get_hrs();
 #elif defined PPG_PAH8009
     hrs = pah8009_get_hrs();
+#elif defined PPG_PAH831X
+    hrs = pah831x_get_hrs();
 #endif
 
     // printf("ppg_get_hrs : %d\n",hrs);
@@ -111,6 +118,8 @@ uint8_t ppg_get_spo2(void)
     spo2 = hx3695_get_spo2();
 #elif defined PPG_PAH8009
     spo2 = pah8009_get_spo2();
+#elif defined PPG_PAH831X
+    spo2 = pah831x_get_spo2();
 #endif
     return spo2;
 }
@@ -122,10 +131,33 @@ uint8_t ppg_get_hrv(void)
     hrv = hx3695_get_hrv();
 #elif defined PPG_PAH8009
 
+#elif defined PPG_PAH831X
+    hrv = pah831x_get_hrv();
 #endif
     return hrv;
 }
 
+void ppg_get_bp(int *sbp,int *dbp)
+{
+#if defined PPG_PAH831X
+    pah8311_get_bp(sbp,dbp);
+#endif
+}
+
+void ppg_set_bp_cali_data(int *sbp,int *dbp)
+{
+#if defined PPG_PAH831X
+    pah831x_set_bp_cali_data(sbp,dbp);
+#endif
+}
+
+bool is_ppg_bp_need_cali(void)
+{
+#if defined PPG_PAH831X
+    return is_pah831x_need_cali();
+#endif
+    return 1;
+}
 
 uint8_t ppg_get_wear_status(void)
 {
@@ -134,6 +166,8 @@ uint8_t ppg_get_wear_status(void)
     wear_status = hx3695_get_wear_status();
 #elif defined PPG_PAH8009
     wear_status = pah8009_get_wear_status();
+#elif defined PPG_PAH831X
+    wear_status = pah831x_get_wear_status();
 #endif
     return wear_status;
 }
@@ -148,6 +182,8 @@ uint16_t ppg_get_chip_id(void)
     chip_id = pah8009_get_chip_id();
 #elif defined PPG_GH3X2X
     chip_id = GH3X2X_AFE_GetChipId();
+#elif defined PPG_PAH831X
+    chip_id = pah831x_get_chip_id();
 #endif
     ppg_power_off();
     return chip_id;
@@ -165,6 +201,8 @@ void ppg_timer_handler(uint8_t mode)
         wear_mode_timeout_handler(NULL);
 #elif defined PPG_PAH8009
     pah8009_timer_handler();
+#elif defined PPG_PAH831X
+    pah831x_timer_handler();
 #endif
 }
 
@@ -178,13 +216,14 @@ void ppg_int_handler(void)
 
 void ppg_send_cmd_to_driver(char* mode, uint8_t enable)
 {
-    // printf("ppg_send_cmd_to_driver \n");
     if(enable)
         ppg_power_on();
 #ifdef PPG_HX3695
     hx3695_control(mode,enable);
 #elif defined PPG_PAH8009
     pah8009_control(mode,enable);
+#elif defined PPG_PAH831X
+    pah831x_control(mode,enable);
 #elif defined PPG_GH3X2X
     // gh3x2x_control(mode,enable);
 #endif
@@ -212,6 +251,18 @@ void ppg_get_factory_data(uint32_t *ch0,uint32_t *ch1,uint32_t *ch2)
 #endif
 }
 
+uint16_t ppg_get_leaklight_fail_str(char *buf, uint16_t buf_size)
+{
+#ifdef PPG_PAH831X
+    return pah831x_get_leaklight_fail_str(buf, buf_size);
+#else
+    if (buf != NULL && buf_size > 0) {
+        buf[0] = '\0';
+    }
+    return 0;
+#endif
+}
+
 int32_t ppg_get_led_data(void)
 {
     int32_t data = 0;
index cc30047..c221c31 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-10-27 16:00:09
+ * @LastEditTime: 2025-12-25 14:20:36
  * @FilePath: /FD230/code/sdk/drivers/peripheral/ppg/ppg/ppg_hal.h
  * @Description: 
  * 
@@ -29,6 +29,8 @@ extern "C" {
 #define PPG_CHIP_ID 0x8008
 #elif defined PPG_GH3X2X
 #define PPG_CHIP_ID 0x3
+#elif defined PPG_PAH831X
+#define PPG_CHIP_ID 0x8311
 #else
 #define PPG_CHIP_ID 0
 #endif
@@ -58,6 +60,7 @@ void ppg_power_on(void);
 void ppg_power_off(void);
 void ppg_int_handler(void);
 void ppg_get_factory_data(uint32_t *ch0,uint32_t *ch1,uint32_t *ch2);
+uint16_t ppg_get_leaklight_fail_str(char *buf, uint16_t buf_size);
 int32_t ppg_get_led_data(void);
 void ppg_ble_send(uint8_t hr);
 void ppg_check_int(void);
@@ -66,6 +69,14 @@ void ppg_set_factory_log_switch(uint8_t cmd);
 uint8_t ppg_get_factory_log_switch(void);
 uint8_t ppg_get_hrv(void);
 
+void ppg_get_bp(int *sbp,int *dbp);
+
+//输入校准血压
+void ppg_set_bp_cali_data(int *sbp,int *dbp);
+
+//是否需要血压校准 1是 0否
+bool is_ppg_bp_need_cali(void);
+
 #ifdef __cplusplus
 #if __cplusplus
 }
index 24009f8..879ae6b 100644 (file)
 #ifdef SUPPORT_CYWEE_SERVICE\r
 #include "cywee_hal.h"\r
 #include "cywee_service.h"\r
+#endif\r
+\r
+#ifdef CUSTOM_UTILS\r
 #include "custom_utils.h"\r
 #include "custom_runtime.h"\r
 #endif\r
 \r
+#ifdef SUPPORT_PPG_BLE_SERVICE\r
+#include "ppgBleService.h"\r
+#endif\r
+\r
 #include "ppg_hal.h"\r
 \r
 uint8_t read_fifo_first_flg = 0;\r
@@ -43,8 +50,8 @@ uint8_t s_cal_state = 0;
 uint8_t check_touch_cnt = 0;\r
 static wear_msg_code_t wear_status = MSG_NO_WEAR;\r
 static wear_msg_code_t wear_status_pre = MSG_NO_INIT;\r
-WORK_MODE_T work_mode_flag = HRS_MODE;\r
-ppg_sensor_data_t ppg_sensor_data;\r
+static WORK_MODE_T work_mode_flag = HRS_MODE;\r
+static ppg_sensor_data_t ppg_sensor_data;\r
 int16_t gsen_data_x_fifo[64];\r
 int16_t gsen_data_y_fifo[64];\r
 int16_t gsen_data_z_fifo[64];\r
@@ -62,16 +69,19 @@ static uint8_t living_status = 0;
 static gsenson_t gsensordata[32];\r
 #endif\r
 \r
-#define HRS_WINDOW_SIZE 5\r
+#define HRS_WINDOW_SIZE 7\r
 static uint8_t hrs_num = 0;\r
 static int32_t sum_hrs = 0;\r
 static int32_t hrs_data[7] = {0};\r
 static uint8_t left = 0;\r
 static uint8_t right = 0;\r
 static uint8_t avg_hrs = 0;\r
-\r
+static uint8_t time_cnt = 0;\r
 // static uint8_t his_wear = 2;\r
 // static uint8_t wear_cnt = 0;\r
+static uint32_t last_system_time = 0;\r
+\r
+static uint8_t last_hrs = 0;\r
 \r
 uint8_t alg_ram[11 * 1024] __attribute__((aligned(4)));\r
 \r
@@ -180,6 +190,7 @@ void hx3695_320ms_timer_cfg(bool en)
     if(en)\r
     {\r
         hx3695_timers_start();\r
+        uapi_get_timestampe_ms(&last_system_time);\r
     }\r
     else\r
     {\r
@@ -326,9 +337,11 @@ uint16_t hx3695_led_data_analysis(ppg_sensor_data_t *ppg_sensor_dat, uint16_t fi
     }\r
     for(ii=0;ii<4;ii++)\r
     {\r
+        // printf("led_data[%d].led_state:%d\n",ii,ppg_sensor_dat->led_data[ii].led_state);\r
         if(ppg_sensor_dat->led_data[ii].led_state == Activated)\r
         {\r
             ppg_sensor_dat->led_data[ii].data_count = count+1;\r
+            // printf("ppg_sensor_dat->led_data[%d].data_count:%d\n",ii,ppg_sensor_dat->led_data[ii].data_count);\r
         }\r
     }\r
        return count+1;\r
@@ -348,10 +361,11 @@ void hx3695_get_led_para(ppg_sensor_data_t *ppg_sensor_dat)
                }\r
        }\r
 }\r
-\r
 uint16_t hx3695_read_fifo_data(ppg_sensor_data_t *ppg_sensor_dat)\r
 {\r
     uint8_t databuf[3];\r
+       uint8_t data_right = 0;\r
+       uint8_t exp_group = 0;\r
 //    uint32_t ii=0;\r
     uint16_t data_len_h = 0;\r
     uint16_t data_len_l = 0;\r
@@ -359,17 +373,42 @@ uint16_t hx3695_read_fifo_data(ppg_sensor_data_t *ppg_sensor_dat)
     uint16_t fifo_read_length = 0;\r
     uint16_t fifo_read_bytes = 0;\r
        uint16_t fifo_out_count = 0;\r
+       uint32_t now_system_time = 0;\r
 \r
     data_len_h = hx3695_read_reg(0x21);\r
     data_len_l = hx3695_read_reg(0x20);\r
     fifo_data_length = (((data_len_h&0x01)<<8)|data_len_l);\r
-\r
-               DEBUG_PRINTF("fifo_data_length: %d\r\n", fifo_data_length);\r
+       uapi_get_timestampe_ms(&now_system_time);\r
+       exp_group = (now_system_time - last_system_time) / (1000 / ppg_sensor_dat->fs);\r
        \r
-               if (fifo_data_length>FIFO_DATA_LENGTH)\r
+    // printf("exp_group:%d, now_system_time:%d, exp_group:%d, fifo_data_length:%d\n",exp_group,now_system_time,exp_group,fifo_data_length);\r
+\r
+\r
+       for(uint8_t index = 0; index < 3; index++)\r
+       {\r
+               if(fifo_data_length > (exp_group + 4) * ppg_sensor_dat->led_activated)\r
+               {\r
+                       data_len_h = hx3695_read_reg(0x21);\r
+                       data_len_l = hx3695_read_reg(0x20);\r
+                       fifo_data_length = (((data_len_h&0x01)<<8)|data_len_l);\r
+               }\r
+               else\r
                {\r
-                               fifo_data_length = FIFO_DATA_LENGTH;\r
+                       data_right = 1;\r
+                       break;\r
                }\r
+       }\r
+       \r
+       if(data_right != 1)\r
+       {\r
+               fifo_data_length = (exp_group + 1) * ppg_sensor_dat->led_activated;\r
+       }\r
+       last_system_time = now_system_time;\r
+       \r
+       if (fifo_data_length>FIFO_DATA_LENGTH)\r
+       {\r
+               fifo_data_length = FIFO_DATA_LENGTH;\r
+       }\r
                \r
     if(fifo_data_length<2*ppg_sensor_dat->led_activated)\r
     {\r
@@ -387,6 +426,8 @@ uint16_t hx3695_read_fifo_data(ppg_sensor_data_t *ppg_sensor_dat)
 \r
        hx3695_get_led_para(ppg_sensor_dat);\r
 \r
+    // printf("fifo_out_count:%d\n",fifo_out_count);\r
+\r
     return fifo_out_count;\r
 }\r
 \r
@@ -471,11 +512,11 @@ void hx3695_software_reset(void)
        #endif\r
 }\r
 \r
-bool hx3695_check_wear(ppg_sensor_data_t *ppg_sensor_dat)\r
+bool hx3695_check_wear(ppg_sensor_data_t *ppg_sensor_dat,uint8_t count)\r
 {\r
     uint8_t ii = 0;\r
     \r
-    for(ii=0;ii<ppg_sensor_dat->led_data[3].data_count;ii++)\r
+    for(ii=0;ii<count;ii++)\r
     {\r
         if(ppg_sensor_dat->led_data[3].data_val[ii] > CHECK_WEAR_THRE)\r
         {\r
@@ -490,6 +531,8 @@ bool hx3695_check_wear(ppg_sensor_data_t *ppg_sensor_dat)
         }\r
         else if(ppg_sensor_dat->led_data[3].data_val[ii] < CHECK_UNWEAR_THRE)\r
         {\r
+            // printf("ppg_sensor_dat->led_data[3].data_val[ii] < CHECK_UNWEAR_THRE\n");\r
+            // printf("ppg_sensor_dat->led_data[3].data_val[ii] :%d \n",ppg_sensor_dat->led_data[3].data_val[ii]);\r
             if(check_touch_cnt>0)\r
             {\r
                 check_touch_cnt--;\r
@@ -507,23 +550,50 @@ bool hx3695_check_wear(ppg_sensor_data_t *ppg_sensor_dat)
             if(uapi_dev_runtime_get_train_status() && !wear_status)\r
                 avg_hrs = 0;\r
 \r
-            if(living_status != 2)\r
+            wear_status_pre = wear_status;\r
+\r
+            if(uapi_dev_runtime_get_sleep_monitoring_status())\r
             {\r
-                wear_status_pre = wear_status;\r
-#ifdef SUPPORT_CYWEE_SERVICE\r
-                cywee_wear_status_update(&wear_status);\r
-#endif\r
+                if(!wear_status)\r
+                {\r
+                    #ifdef SUPPORT_CYWEE_SERVICE\r
+                    cywee_wear_status_update(&wear_status);\r
+                    #endif\r
+                }\r
+                else if(living_status == 1 && wear_status)\r
+                {\r
+                    #ifdef SUPPORT_CYWEE_SERVICE\r
+                    cywee_wear_status_update(&wear_status);\r
+                    #endif\r
+                }\r
+            }\r
+            else\r
+            {\r
+                if(living_status != 2)\r
+                {\r
+\r
+    #ifdef SUPPORT_CYWEE_SERVICE\r
+                    cywee_wear_status_update(&wear_status);\r
+    #endif\r
+                }\r
             }\r
+\r
+\r
             // printf("wear_status:%d\n",wear_status);\r
 \r
-            // if(wear_status == MSG_NO_WEAR)\r
-            // {\r
-            //     hx3695_wear_low_power(ppg_sensor_dat);                 \r
-            // }\r
-            // else if(wear_status == MSG_WEAR)\r
-            // {\r
-            //     hx3695_init(work_mode_flag);\r
-            // }  \r
+            if(!uapi_dev_runtime_get_factory_test_status_flag())\r
+            {\r
+                if(wear_status == MSG_NO_WEAR)\r
+                {\r
+                    hx3695_wear_low_power(ppg_sensor_dat);                 \r
+                }\r
+                else if(wear_status == MSG_WEAR)\r
+                {\r
+                    hx3695_init(work_mode_flag);\r
+                }  \r
+            }\r
+\r
+\r
         }  \r
     }\r
        return 1;\r
@@ -1058,7 +1128,7 @@ void hx3695_ppg_set_mode(uint8_t mode_cmd)
                        hx3695_ppg_para_init(&ppg_sensor_data);\r
                s_ppg_state = 1;\r
                        s_cal_state = 0;\r
-            if(work_mode_flag == HRS_MODE)\r
+            if(work_mode_flag != WEAR_MODE)\r
             {\r
                 #if defined(TIMMER_MODE)\r
                 hx3695_320ms_timer_cfg(true);\r
@@ -1144,7 +1214,14 @@ bool hx3695_init(WORK_MODE_T mode)
     switch (work_mode_flag)\r
     {\r
                case HRS_MODE:\r
-            tyhx_hrs_set_living(1, 15, 30);\r
+            if(uapi_dev_runtime_get_train_status())\r
+            {\r
+                tyhx_hrs_set_living(0, 0, 0);\r
+            }\r
+            else\r
+            {\r
+                tyhx_hrs_set_living(1, 15, 30);\r
+            }\r
                        hx3695_hrs_enable(&ppg_sensor_data);\r
                        break;\r
         \r
@@ -1289,6 +1366,19 @@ static void get_avg_hrs(uint8_t hrs)
         uint8_t valid_count = hrs_num - 2;\r
         avg_hrs = (sum_hrs - max_hrs - min_hrs) / valid_count;\r
 \r
+\r
+        // if (last_hrs >= 30 && last_hrs <= 210) \r
+        // {\r
+        //     int16_t diff = avg_hrs - last_hrs;\r
+        //     if (abs(diff) > 10) \r
+        //     {\r
+        //         if (diff > 0) \r
+        //             avg_hrs = last_hrs + 5;\r
+        //         else \r
+        //             avg_hrs = last_hrs - 5;\r
+        //     }\r
+        // }\r
+        // last_hrs = avg_hrs;\r
         // printf("max_hrs[%d],min_hrs[%d],avg_hrs[%d]\n",max_hrs,min_hrs,avg_hrs);\r
     }\r
 }\r
@@ -1383,44 +1473,121 @@ void hx3695_alg_send_data(ppg_sensor_data_t *ppg_sensor_dat, WORK_MODE_T mode, u
                        //tyhx_hrs_alg_send_data(ppg_sensor_dat->led_data[0].data_val,data_count, gsen_data_x_fifo, gsen_data_y_fifo, gsen_data_z_fifo);\r
                        hrs_result = tyhx_hrs_alg_get_results();\r
                        DEBUG_PRINTF("HRS: %d %d\r\n",hrs_result.data_cnt, hrs_result.hr_result);\r
-                       // printf("hr:%d, living:%d, wear_status:%d\n", hrs_result.hr_result,hrs_result.living_status,wear_status);\r
+                       // printf("ppg_sensor_dat->led_data[0].led_current:%d, ppg_sensor_dat->led_data[3].led_current:%d\n", ppg_sensor_dat->led_data[0].led_current,ppg_sensor_dat->led_data[3].led_current);\r
    \r
-            if(uapi_dev_runtime_get_train_status())\r
-            {\r
-                if(hrs_result.hr_result >= 30 && hrs_result.hr_result <= 210)\r
-                    get_avg_hrs(hrs_result.hr_result);\r
-            }\r
-            else\r
+            time_cnt++;\r
+\r
+            if(time_cnt >= 3)\r
             {\r
-                if(hrs_result.living_status == MSG_LIVING_TRUE)\r
+                time_cnt = 0;\r
+                if(uapi_dev_runtime_get_train_status())\r
                 {\r
-                    living_wear_cnt = 0;\r
-\r
                     if(hrs_result.hr_result >= 30 && hrs_result.hr_result <= 210)\r
                         get_avg_hrs(hrs_result.hr_result);\r
-\r
-                    living_status = 1;\r
                 }\r
-                else if(hrs_result.living_status == MSG_LIVING_FAIL)\r
+                else\r
                 {\r
-                    living_wear_cnt++;\r
-                    if(living_wear_cnt >= 5)\r
+                    if(hrs_result.living_status == MSG_LIVING_TRUE)\r
+                    {\r
+                        living_wear_cnt = 0;\r
+\r
+                        if(hrs_result.hr_result >= 30 && hrs_result.hr_result <= 210)\r
+                            get_avg_hrs(hrs_result.hr_result);\r
+\r
+                        living_status = 1;\r
+                        #ifdef SUPPORT_CYWEE_SERVICE\r
+                        cywee_wear_status_update(&living_status);\r
+                        #endif\r
+                    }\r
+                    else if(hrs_result.living_status == MSG_LIVING_FAIL)\r
+                    {\r
+                        living_wear_cnt++;\r
+                        if(living_wear_cnt >= 5)\r
+                        {\r
+                            avg_hrs = 0;\r
+                            living_status = 2;\r
+                            wear_status = 0;\r
+                            wear_status_pre = 0;\r
+                            // hx3695_unwearstatus_update();\r
+\r
+                            #ifdef SUPPORT_CYWEE_SERVICE\r
+                            cywee_wear_status_update(&living_status);\r
+                            #endif\r
+                            living_wear_cnt = 0;\r
+                        }\r
+                    }\r
+                    else\r
                     {\r
-                        avg_hrs = 0;\r
-                        living_status = 2;\r
-                        wear_status = 0;\r
-                        wear_status_pre = 0;\r
-                        hx3695_unwearstatus_update();\r
                         living_wear_cnt = 0;\r
+                        living_status = 0;\r
                     }\r
                 }\r
-                else\r
+            }\r
+            // time_cnt++;\r
+            // if(time_cnt >= 3)\r
+            {\r
+                // time_cnt = 0;\r
+#ifdef SUPPORT_PPG_BLE_SERVICE \r
+#if 0\r
+\r
+                if(uapi_dev_runtime_get_hrs_ble_status())\r
                 {\r
-                    living_wear_cnt = 0;\r
-                    living_status = 0;\r
+                    uint8_t ble_data = (uint8_t)avg_hrs;\r
+                    ble_ppgtest_server_send_input_report(&ble_data,1);\r
+                }\r
+#else\r
+            if(uapi_dev_runtime_get_hrs_ble_status())\r
+            {\r
+                uint8_t encoded_hrm[17] = {0};//PPG_DATA_LEN_MAX>17会导致APP连接提示定义设备与所选类型不匹配\r
+                uint8_t red_bit = 0;\r
+                uint8_t ir_bit = 0;\r
+                uint8_t green_bit = 0;\r
+                // HRS_CAL_SET_T cal= get_hrs_agc_status();\r
+        \r
+                for(int ii=0; ii<data_count; ii++)\r
+                {\r
+                    // c\r
+                    if(ppg_sensor_dat->led_data[0].data_val[ii]<0)\r
+                    {\r
+                        red_bit = 0x80;\r
+                        ppg_sensor_dat->led_data[0].data_val[ii] =  -ppg_sensor_dat->led_data[0].data_val[ii];\r
+                    }\r
+                    // ppg_sensor_dat->led_data[2].data_val[ii]\r
+                    if(ppg_sensor_dat->led_data[3].data_val[ii]<0)\r
+                    {\r
+                        ir_bit = 0x80;\r
+                        ppg_sensor_dat->led_data[3].data_val[ii] =  -ppg_sensor_dat->led_data[3].data_val[ii];\r
+                    }\r
+        \r
+                    encoded_hrm[0] = 0x55;//心率标志位,一定要设置正确\r
+                    encoded_hrm[1] = (uint8_t)(hrs_result.data_cnt - data_count + ii) % 256;//原始data_cnt会一直自加,但是这里只有一个字节,0-255循环\r
+                    encoded_hrm[2] = (uint8_t)(hrs_result.hr_result & 0xFF);//心率值\r
+        \r
+                    encoded_hrm[3] = (uint8_t)((ppg_sensor_dat->led_data[0].data_val[ii] & 0xFF0000) >> 16) | red_bit; //绿灯原始数据\r
+                    encoded_hrm[4] = (uint8_t)((ppg_sensor_dat->led_data[0].data_val[ii] & 0xFF00) >> 8);                              //绿灯原始数据\r
+                    encoded_hrm[5] = (uint8_t)(ppg_sensor_dat->led_data[0].data_val[ii] & 0xFF);                                                       //绿灯原始数据\r
+        \r
+                    encoded_hrm[6] = (uint8_t)((ppg_sensor_dat->led_data[3].data_val[ii] & 0xFF0000) >> 16) | ir_bit;          //ir原始数据\r
+                    encoded_hrm[7] = (uint8_t)((ppg_sensor_dat->led_data[3].data_val[ii] & 0xFF00) >> 8);                                      //ir原始数据\r
+                    encoded_hrm[8] = (uint8_t)(ppg_sensor_dat->led_data[3].data_val[ii] & 0xFF);                                                       //ir原始数据\r
+        \r
+                    encoded_hrm[9] = (uint8_t)((gsen_data_x_fifo[ii]&0xFF00)>>8);//模拟x,1234换成填入自己的x数据\r
+                    encoded_hrm[10] = (uint8_t)(gsen_data_x_fifo[ii]&0xFF);\r
+                    encoded_hrm[11] = (uint8_t)((gsen_data_y_fifo[ii]&0xFF00)>>8);//模拟y,-1234换成填入自己的y数据\r
+                    encoded_hrm[12] = (uint8_t)(gsen_data_y_fifo[ii]&0xFF);\r
+                    encoded_hrm[13] = (uint8_t)((gsen_data_z_fifo[ii]&0xFF00)>>8);//模拟z,3987换成填入自己的z数据\r
+                    encoded_hrm[14] = (uint8_t)(gsen_data_z_fifo[ii]&0xFF);       \r
+                    \r
+                    encoded_hrm[15] = ppg_sensor_dat->led_data[0].led_current;//绿灯电流\r
+                    encoded_hrm[16] = ppg_sensor_dat->led_data[3].led_current;//红外电流\r
+\r
+                    ble_ppgtest_server_send_input_report(encoded_hrm,17);\r
                 }\r
-            }\r
 \r
+            }\r
+#endif  \r
+#endif\r
+        }\r
                        break;\r
                }\r
                case SPO2_MODE:\r
@@ -1454,6 +1621,9 @@ void hx3695_alg_send_data(ppg_sensor_data_t *ppg_sensor_dat, WORK_MODE_T mode, u
 \r
 void hx3695_ppg_Int_handle(ppg_sensor_data_t *ppg_sensor_dat)\r
 {\r
+    // uint32_t time = 0;\r
+    // uapi_get_timestampe_ms(&time);\r
+    // printf("time:%d\n",time);\r
        uint16_t count = 0;\r
        uint16_t ii = 0;\r
        if(s_ppg_state == 0)\r
@@ -1461,20 +1631,25 @@ void hx3695_ppg_Int_handle(ppg_sensor_data_t *ppg_sensor_dat)
                return;\r
        }\r
        count = hx3695_read_fifo_data(ppg_sensor_dat);\r
+    // printf("count:%d\n",count);\r
     if(count > 0)\r
     {\r
-        hx3695_check_wear(ppg_sensor_dat);\r
+        if(work_mode_flag == HRS_MODE && count > 9)\r
+        {\r
+            count = 8;\r
+        }\r
+        hx3695_check_wear(ppg_sensor_dat,count);\r
         if(wear_status == MSG_WEAR)\r
         {\r
             hx3695_alg_send_data(ppg_sensor_dat,work_mode_flag,count);\r
         }\r
     }\r
 \r
-       for(ii=0;ii<count;ii++)\r
-       {\r
-               DEBUG_PRINTF("%d/%d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d\r\n", ii+1, count, ppg_sensor_dat->led_data[0].data_val[ii], ppg_sensor_dat->led_data[1].data_val[ii],ppg_sensor_dat->led_data[2].data_val[ii], ppg_sensor_dat->led_data[3].data_val[ii],  \\r
-               ppg_sensor_dat->led_data[0].led_current, ppg_sensor_dat->led_data[0].offset_idac, ppg_sensor_dat->led_data[1].led_current, ppg_sensor_dat->led_data[1].offset_idac,ppg_sensor_dat->led_data[2].led_current, ppg_sensor_dat->led_data[2].offset_idac);\r
-       }\r
+       // for(ii=0;ii<count;ii++)\r
+       // {\r
+       //      printf("%d/%d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d,%d,%d\r\n", ii+1, count, ppg_sensor_dat->led_data[0].data_val[ii], ppg_sensor_dat->led_data[1].data_val[ii],ppg_sensor_dat->led_data[2].data_val[ii], ppg_sensor_dat->led_data[3].data_val[ii],  \\r
+       //      ppg_sensor_dat->led_data[0].led_current, ppg_sensor_dat->led_data[0].offset_idac, ppg_sensor_dat->led_data[1].led_current, ppg_sensor_dat->led_data[1].offset_idac,ppg_sensor_dat->led_data[2].led_current, ppg_sensor_dat->led_data[2].offset_idac,gsen_data_x_fifo[ii], gsen_data_y_fifo[ii], gsen_data_z_fifo[ii]);\r
+       // }\r
 }\r
 \r
 uint8_t hx3695_get_hrs(void)\r
@@ -1533,11 +1708,11 @@ void wear_mode_timeout_handler(void * p_context)
 {\r
     // printf("wear_mode_timeout_handler \n");\r
     if(work_mode_flag == WEAR_MODE)\r
-    {\r
-        #ifdef CHECK_TOUCH_LIB\r
+    {  \r
+        #ifdef CHECK_TOUCH_LIB \r
           hx3695_ppg_Int_handle(&ppg_sensor_data);\r
         #endif\r
-    }\r
+    } \r
 }\r
 \r
 void hx3695_spo2_disable(void)\r
diff --git a/code/sdk/zhihui/drivers/ppg/pah831x/CMakeLists.txt b/code/sdk/zhihui/drivers/ppg/pah831x/CMakeLists.txt
new file mode 100644 (file)
index 0000000..63ac230
--- /dev/null
@@ -0,0 +1,97 @@
+#===============================================================================
+# @brief    cmake file
+# Copyright (c) @CompanyNameMagicTag 2022-2023. All rights reserved.
+#===============================================================================
+set(COMPONENT_NAME "ppg_sensor_pah831x")
+
+set(SOURCES ${SOURCES}
+    ${CMAKE_CURRENT_SOURCE_DIR}/pah_sensor/pah831x_comm.c
+    ${CMAKE_CURRENT_SOURCE_DIR}/pah_sensor/pah831x_main.c
+    ${CMAKE_CURRENT_SOURCE_DIR}/pah_sensor/pah831x.c
+    ${CMAKE_CURRENT_SOURCE_DIR}/pah831x_factory_20251217/pah831x_factory_test_v3.c
+    ${CMAKE_CURRENT_SOURCE_DIR}/pah831x_factory_20251217/demo_factory_v3.c
+    ${CMAKE_CURRENT_SOURCE_DIR}/PXI_ALG/ECG_AFIB/V2022/pah_ecg_afib_alg.c
+    ${CMAKE_CURRENT_SOURCE_DIR}/PXI_ALG/ECG_PPG_BP/v3070/pah_ecg_bp_alg.c
+    ${CMAKE_CURRENT_SOURCE_DIR}/PXI_ALG/HRD/v5653/pah_hrd_alg.c
+    ${CMAKE_CURRENT_SOURCE_DIR}/PXI_ALG/HRD/v5653/test_library_HRD.c
+    ${CMAKE_CURRENT_SOURCE_DIR}/PXI_ALG/RAW_ECG/pah_ecg_raw.c
+    ${CMAKE_CURRENT_SOURCE_DIR}/PXI_ALG/RAW_PPG/pah_ppg_raw.c
+    ${CMAKE_CURRENT_SOURCE_DIR}/PXI_ALG/RR_HRV_STRESS_RRI/V3131/pah_hrv_alg.c
+    ${CMAKE_CURRENT_SOURCE_DIR}/PXI_ALG/RR_HRV_STRESS_RRI/V3131/pah_RR_alg_V30x.c
+    ${CMAKE_CURRENT_SOURCE_DIR}/PXI_ALG/RR_HRV_STRESS_RRI/V3131/pah_RRI_alg.c
+    ${CMAKE_CURRENT_SOURCE_DIR}/PXI_ALG/RR_HRV_STRESS_RRI/V3131/pah_stress_alg.c
+    ${CMAKE_CURRENT_SOURCE_DIR}/PXI_ALG/RR_HRV_STRESS_RRI/V3131/test_library_HRV.c
+    ${CMAKE_CURRENT_SOURCE_DIR}/PXI_ALG/RR_HRV_STRESS_RRI/V3131/test_library_RR2.c
+    ${CMAKE_CURRENT_SOURCE_DIR}/PXI_ALG/RR_HRV_STRESS_RRI/V3131/test_library_stress.c
+    ${CMAKE_CURRENT_SOURCE_DIR}/PXI_ALG/SHRD/V307009/pah_shrd_alg.c
+    ${CMAKE_CURRENT_SOURCE_DIR}/PXI_ALG/SPO2/V587/pah_spo2_alg.c
+    
+)
+set(PUBLIC_HEADER
+    ${CMAKE_CURRENT_SOURCE_DIR}/pah
+    ${CMAKE_CURRENT_SOURCE_DIR}/pah_sensor
+    ${CMAKE_CURRENT_SOURCE_DIR}/pah831x_factory_20251217
+    ${CMAKE_CURRENT_SOURCE_DIR}/PXI_ALG/ECG_AFIB/V2022
+    ${CMAKE_CURRENT_SOURCE_DIR}/PXI_ALG/ECG_HRV/V103
+    ${CMAKE_CURRENT_SOURCE_DIR}/PXI_ALG/ECG_PPG_BP/v3070
+    ${CMAKE_CURRENT_SOURCE_DIR}/PXI_ALG/HRD/v5653
+    ${CMAKE_CURRENT_SOURCE_DIR}/PXI_ALG/RAW_ECG
+    ${CMAKE_CURRENT_SOURCE_DIR}/PXI_ALG/RAW_PPG
+    ${CMAKE_CURRENT_SOURCE_DIR}/PXI_ALG/RR_HRV_STRESS_RRI/V3131
+    ${CMAKE_CURRENT_SOURCE_DIR}/PXI_ALG/SHRD/V307009
+    ${CMAKE_CURRENT_SOURCE_DIR}/PXI_ALG/SPO2/V587
+    
+)
+
+set(PRIVATE_HEADER
+)
+
+set(PRIVATE_DEFINES
+)
+
+set(PUBLIC_DEFINES
+
+)
+
+# use this when you want to add ccflags like -include xxx
+set(COMPONENT_PUBLIC_CCFLAGS
+)
+
+set(COMPONENT_CCFLAGS
+)
+
+set(WHOLE_LINK
+    true
+)
+
+set(MAIN_COMPONENT
+    false
+)
+
+if("PPG_PAH831X" IN_LIST DEFINES)
+
+find_library(LIB_PATH_ECGAFIB PXI_ALG/ECG_AFIB/V2022/libecgafib_v2022_6.a ${CMAKE_CURRENT_SOURCE_DIR})
+find_library(LIB_PATH_HRV PXI_ALG/ECG_HRV/V103/libecghrv_v103_4.a ${CMAKE_CURRENT_SOURCE_DIR})
+find_library(LIB_PATH_BP PXI_ALG/ECG_PPG_BP/v3070/libecgbp_v3070_1.a ${CMAKE_CURRENT_SOURCE_DIR})
+find_library(LIB_PATH_HR PXI_ALG/HRD/v5653/libhr_v5653_3.a ${CMAKE_CURRENT_SOURCE_DIR})
+find_library(LIB_PATH_ECG PXI_ALG/RAW_ECG/libecgdenoise_v7010_5.a ${CMAKE_CURRENT_SOURCE_DIR})
+find_library(LIB_PATH_STRESS_RRI PXI_ALG/RR_HRV_STRESS_RRI/V3131/libhrv_v3131_0.a ${CMAKE_CURRENT_SOURCE_DIR})
+find_library(LIB_PATH_SHRD PXI_ALG/SHRD/V307009/libv307009_4.a ${CMAKE_CURRENT_SOURCE_DIR})
+find_library(LIB_PATH_SPO2 PXI_ALG/SPO2/V587/libspo2_v587_20.a ${CMAKE_CURRENT_SOURCE_DIR})
+
+
+target_link_libraries(${TARGET_NAME} PRIVATE -Wl,--whole-archive 
+${LIB_PATH_ECGAFIB} 
+${LIB_PATH_HRV} 
+${LIB_PATH_BP} 
+${LIB_PATH_HR} 
+${LIB_PATH_ECG} 
+${LIB_PATH_STRESS_RRI} 
+${LIB_PATH_SHRD} 
+${LIB_PATH_SPO2} 
+PRIVATE -Wl,--whole-archive)
+
+endif()
+
+build_component()
+
diff --git a/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/ECG_AFIB/V2022/libecgafib_v2022_5.a b/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/ECG_AFIB/V2022/libecgafib_v2022_5.a
new file mode 100644 (file)
index 0000000..7df5f5d
Binary files /dev/null and b/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/ECG_AFIB/V2022/libecgafib_v2022_5.a differ
diff --git a/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/ECG_AFIB/V2022/libecgafib_v2022_6.a b/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/ECG_AFIB/V2022/libecgafib_v2022_6.a
new file mode 100644 (file)
index 0000000..aa8d746
Binary files /dev/null and b/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/ECG_AFIB/V2022/libecgafib_v2022_6.a differ
diff --git a/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/ECG_AFIB/V2022/pah_ecg_afib_alg.c b/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/ECG_AFIB/V2022/pah_ecg_afib_alg.c
new file mode 100644 (file)
index 0000000..6c365cd
--- /dev/null
@@ -0,0 +1,419 @@
+// c\r
+#include <string.h>\r
+#include <stdint.h>\r
+#include <stdbool.h>\r
+#include <stdlib.h>\r
+#include <stdio.h>\r
+#include <string.h>\r
+\r
+#include "pah831x_comm.h"\r
+#include "pah831x_config.h"\r
+#include "pah831x_main.h"\r
+\r
+#include "pah_ecg_afib_alg.h"\r
+#include "pah_ecg_afib_api.h"\r
+#include "hcp_ecg_hrv_api.h"\r
+\r
+#if defined(ENABLE_PXI_ALG_ECG_HRD)\r
+#include "hcp_ecg_hrv_api.h"\r
+#endif\r
+\r
+#if defined(ENABLE_PXI_ALG_HRD)\r
+#include "pah8series_api_c.h"\r
+#endif\r
+\r
+#ifndef ENABLE_PXI_ALG_HRD\r
+typedef struct {\r
+    uint8_t                     frame_count;\r
+    uint32_t                    time;\r
+    uint8_t                     touch_flag;\r
+    uint32_t                    nf_ppg_channel;\r
+    uint32_t                    nf_ppg_per_channel;\r
+    int32_t                     *ppg_data;\r
+    uint32_t                    nf_mems;\r
+    int16_t                     *mems_data;\r
+} pah8series_data_t;\r
+#endif\r
+\r
+typedef struct\r
+{\r
+     // pxialg\r
+    void*                pxialg_buffer_afib;\r
+    void*                pxialg_state_afib;\r
+    void*                pxialg_buffer_hrv;    \r
+    pah8series_data_t    pxialg_data;\r
+    bool                pxialg_has_init;\r
+    uint64_t            last_report_time;\r
+    uint8_t*             ecg_tag_data;\r
+    //float           collect_duration;\r
+    uint8_t             has_got_AFIB;\r
+    uint8_t             has_time_out;\r
+} main_ecg_afib_state_s;\r
+\r
+static bool need_log_header = true;\r
+static main_ecg_afib_state_s _state;\r
+\r
+static float alg_value =0.0f;\r
+\r
+#define K_sampling_rate 256\r
+static uint16_t     ECG_FS = 256; // ECG Afib function support : 128, 256 , 512 ,1024 Hz \r
+static uint16_t     ECG_time = 30; // Sec\r
+\r
+static uint8_t  ReadyFlag = 0;\r
+static uint8_t  AFIB_ReadyFlag = 0;\r
+static uint8_t  ecg_afib_result = 0;\r
+static uint16_t ecg_ready_count = 0;\r
+static int32_t  ecg_frame_count = 0;\r
+\r
+static int16_t ecg_p_number = 0;\r
+static int16_t ecg_r_number = 0;\r
+static int16_t ecg_t_number = 0;\r
+static int16_t ecg_rri_number = 0;\r
+\r
+//static int16_t* ecg_rri_buf = NULL;\r
+//static int16_t* ecg_r_buf = NULL;\r
+//static int16_t* ecg_p_buf = NULL;\r
+//static int16_t* ecg_t_buf = NULL;\r
+\r
+static float ecg_prt = 0.0f;\r
+static float nrmssd_real = 0.0f;\r
+static float ecg_readysqi = 0.0f;\r
+\r
+/*============================================================================\r
+STATIC FUNCTION PROTOTYPES\r
+============================================================================*/\r
+\r
+\r
+static void log_pah8series_data_header(uint32_t ch_num, uint32_t ir_ch_num, uint32_t g_sensor_mode);\r
+static void log_pah8series_data(const pah8series_data_t *data);\r
+static bool ecg_afib_algorithm_process(pah8series_data_t *pxialg_data, uint32_t ch_num);\r
+static bool ecg_afib_algorithm_calculate(pah8series_data_t *pxialg_data, uint32_t ch_num);\r
+static uint8_t run_afib_pxialg(uint32_t duration, const uint32_t* ecg_data, uint16_t ecg_data_num, uint8_t touch_flag);\r
+\r
+static void log_pah8series_data_header(uint32_t ch_num, uint32_t ir_ch_num, uint32_t g_sensor_mode)\r
+{\r
+    //log pah8series data header\r
+    LOG_PRINT("ECG CH#, %d, %d, %d, %d\n", \r
+                ch_num,   /*(1)Using total channel numbers;*/ \\r
+                     0,   /*(2)reserved;*/ \\r
+             ir_ch_num,   /*(3)IR channel number;*/ \\r
+             g_sensor_mode/*(4)MEMS mode 0:2G, 1:4G, 2:8G*/ \\r
+            );\r
+}\r
+\r
+static void log_pah8series_data(const pah8series_data_t *pxialg_data)\r
+{\r
+    int i = 0;\r
+    uint32_t *ppg_data = (uint32_t *)pxialg_data->ppg_data;\r
+    \r
+    uint8_t *ecg_tag_data = _state.ecg_tag_data;\r
+    \r
+    int16_t *mems_data = pxialg_data->mems_data;\r
+    int data_num = pxialg_data->nf_ppg_channel * pxialg_data->nf_ppg_per_channel;\r
+    \r
+    LOG_PRINT("Frame Count, %d \n", pxialg_data->frame_count);\r
+    LOG_PRINT("Time, %d \n", pxialg_data->time);\r
+    LOG_PRINT("ECG, %d, %d, ", pxialg_data->touch_flag, data_num);\r
+    for (i = 0; i < data_num; ++i)\r
+    {\r
+        LOG_PRINT("%d, ", *ppg_data);\r
+        ppg_data++;\r
+    }\r
+    LOG_PRINT("\n");\r
+    LOG_PRINT("MEMS, %d, ", pxialg_data->nf_mems);\r
+    for (i = 0; i < (pxialg_data->nf_mems * 3); ++i)\r
+    {\r
+        LOG_PRINT("%d, ", *mems_data);\r
+        mems_data++;\r
+    }\r
+    LOG_PRINT("\n");\r
+    LOG_PRINT("ECG_TAG,  %d, ",  data_num);\r
+    for (i = 0; i < data_num; ++i)\r
+    {\r
+        LOG_PRINT("%d, ", *ecg_tag_data);\r
+        ecg_tag_data++;\r
+    }\r
+    LOG_PRINT("\n");\r
+}\r
+\r
+\r
+bool  report_fifo_data_ecg_afib(\r
+uint32_t ppg_timestamp,     \r
+uint32_t time_period, \r
+uint32_t *ppg_data,\r
+uint8_t  *tag_data,\r
+uint16_t ppg_size,\r
+uint8_t ch_num,\r
+int16_t *acc_data,\r
+uint16_t acc_size, \r
+uint8_t *alg_value_out,\r
+uint8_t *got_AFIB,\r
+uint8_t *got_time_out,\r
+uint8_t is_touched  \r
+)\r
+{\r
+//    ALG_PRINT("time_period = %d  timestamp =%d \n", time_period , ppg_timestamp);\r
+    \r
+    _state.pxialg_data.mems_data = acc_data ;\r
+    _state.pxialg_data.nf_mems =   acc_size  ;\r
+    _state.pxialg_data.touch_flag = is_touched<2 ? 1 : 0;\r
+    _state.pxialg_data.time = time_period;\r
+    _state.pxialg_data.ppg_data = (int32_t*)ppg_data;\r
+ \r
+    _state.pxialg_data.nf_ppg_channel = ch_num;\r
+    _state.pxialg_data.nf_ppg_per_channel = ppg_size;\r
+    ++_state.pxialg_data.frame_count;\r
+    _state.ecg_tag_data = tag_data;\r
+\r
+    //if(is_touched)\r
+    {\r
+        ecg_afib_algorithm_process(&_state.pxialg_data, _state.pxialg_data.nf_ppg_channel);\r
+        *alg_value_out = (uint8_t) alg_value ;\r
+    }\r
+    \r
+    *got_AFIB = _state.has_got_AFIB;\r
+    *got_time_out = _state.has_time_out;\r
+    return true ;\r
+}\r
+\r
+static bool ecg_afib_algorithm_process(pah8series_data_t *pxialg_data, uint32_t ch_num)\r
+{\r
+    // log header\r
+    if (need_log_header)\r
+    {\r
+        need_log_header = false;\r
+        log_pah8series_data_header(ch_num, PPG_IR_CH_NUM, ALG_GSENSOR_MODE);\r
+    }\r
+    // log\r
+    log_pah8series_data(&_state.pxialg_data);  \r
+    // alg_value\r
+    \r
+    ecg_afib_algorithm_calculate(&_state.pxialg_data, ch_num);\r
+\r
+    return true;\r
+}\r
+static bool ecg_afib_algorithm_calculate(pah8series_data_t *pxialg_data, uint32_t ch_num)\r
+{\r
+    bool has_updated = false;\r
+#if defined(ENABLE_PXI_ALG_ECG_AFIB)\r
+     // Initialize algorithm\r
+    if (!_state.pxialg_has_init)\r
+    {\r
+        uint32_t state_size = 0;\r
+        uint32_t afib_buffer_size = 0;\r
+        uint32_t hrv_buffer_size = 0;\r
+        \r
+        state_size = PXIAFIB_GetStateSize();\r
+        ALG_PRINT("ECG_AFIB_state_query_open_size() = %d \n", state_size);\r
+\r
+  #if defined(ENABLE_PXI_ALG_ECG_HRD)\r
+        hrv_buffer_size = ECG_Analysis_Get_Memory_Size();\r
+        ALG_PRINT("ECG_HRV_query_open_size() = %d \n", hrv_buffer_size);\r
+  #endif  //ENABLE_PXI_ALG_ECG_HRD\r
+        \r
+        _state.pxialg_state_afib = (void*)malloc(state_size);\r
+        if (!_state.pxialg_state_afib){\r
+            ALG_PRINT("ECG_AFIB_state_buffer_size_not enough \n");\r
+              return false;\r
+        }\r
+        afib_buffer_size= PXIAFIB_GetMemorySize(_state.pxialg_state_afib, 1, (int)ECG_time, (int)ECG_FS);\r
+        ALG_PRINT("AFIB_Buffer_query_open_size() = %d \n", afib_buffer_size);\r
+        _state.pxialg_buffer_afib = (void*)malloc(afib_buffer_size);\r
+        if (!_state.pxialg_buffer_afib){\r
+            ALG_PRINT("ECG_AFIB_state_buffer_size_not enough \n");\r
+              return false;\r
+        }\r
+        if (!PXIAFIB_Open(_state.pxialg_state_afib,_state.pxialg_buffer_afib,(int)ECG_FS,ECG_time)){\r
+                ALG_PRINT("PXIAFIB_Open failed. \n");\r
+                return false;   \r
+        }\r
+  #if defined(ENABLE_PXI_ALG_ECG_HRD)\r
+            _state.pxialg_buffer_hrv = (void*)malloc(hrv_buffer_size);\r
+            if (!_state.pxialg_buffer_hrv){\r
+                ALG_PRINT("ECG_HR_buffer_size_not enough \n");\r
+                return false;\r
+            }\r
+            if (!ECG_Analysis_Open(_state.pxialg_buffer_hrv)){\r
+                ALG_PRINT("ECG_Analysis_Open failed. \n");\r
+                return false;\r
+            }\r
+            ECG_Analysis_SetSamplingRate(_state.pxialg_buffer_hrv, K_sampling_rate);\r
+  #endif  //    ENABLE_PXI_ALG_ECG_HRD\r
+        _state.pxialg_has_init = true;\r
+    }\r
+    \r
+    uint32_t cal_start = pxi_get_tick_count();\r
+    #endif // ENABLE_PXI_ALG_ECG_AFIB\r
+    run_afib_pxialg(pxialg_data->time, \\r
+                    (const uint32_t*)pxialg_data->ppg_data, \\r
+                    (pxialg_data->nf_ppg_channel * pxialg_data->nf_ppg_per_channel),\r
+                    pxialg_data->touch_flag);\r
+\r
+    return has_updated;\r
+}\r
+static uint8_t run_afib_pxialg(uint32_t duration, const uint32_t* ecg_data, uint16_t ecg_data_num, uint8_t touch_flag)\r
+{\r
+#if defined(ENABLE_PXI_ALG_ECG_AFIB)\r
+    uint32_t i = 0;\r
+    \r
+    if (_state.has_got_AFIB)\r
+        return 1;\r
+  #if defined(ENABLE_PXI_ALG_ECG_HRD)\r
+    float  interval_time=0;\r
+    interval_time=(float)duration/ecg_data_num;\r
+    for(uint16_t j=0; j < ecg_data_num; j++){\r
+        ECG_Analysis_Process(_state.pxialg_buffer_hrv, touch_flag, ecg_data[j], interval_time);\r
+    }\r
+    float HR =ECG_Analysis_Get_HR(_state.pxialg_buffer_hrv);\r
+    ALG_PRINT("ECG Heart Rate = %d  \n", (int)HR);\r
+  #endif  //    ENABLE_PXI_ALG_ECG_HRD\r
+    \r
+    for(i=0; i < ecg_data_num; i++){\r
+        ReadyFlag = PXIAFIB_GetReady(_state.pxialg_state_afib, \\r
+                                     (int)ecg_data[i],  \\r
+                                     1/*touch flag*/, \\r
+                                     1);\r
+                                     \r
+        ecg_ready_count = PXIAFIB_GetIReadyCountECG(_state.pxialg_state_afib);\r
+        ecg_ready_count--;\r
+                                     \r
+        ecg_readysqi = PXIAFIB_GetECGReadySQI(_state.pxialg_state_afib);\r
+        if((ReadyFlag == 1) && (PXIAFIB_GETEcgStopFlag(_state.pxialg_state_afib) == 0)){ // count-down 30sec to collect data.\r
+            int16_t peak_filter_output = PXIAFIB_Process(_state.pxialg_state_afib,1,(int)ecg_data[i]);\r
+            ecg_frame_count = PXIAFIB_GetICountECG(_state.pxialg_state_afib);\r
+            ecg_frame_count -- ;\r
+            \r
+            if(ecg_frame_count == (uint16_t)(ECG_time*ECG_FS)){\r
+                _state.has_got_AFIB=1;\r
+                ALG_PRINT("collect 30sec \n");\r
+                AFIB_ReadyFlag = 1;\r
+                }\r
+        }else {\r
+            if(PXIAFIB_GETEcgStopFlag(_state.pxialg_state_afib) == 1) {//ready sqi > 0, need to stop .\r
+                _state.has_got_AFIB=1;\r
+                ecg_afib_algorithm_close();\r
+                 ALG_PRINT("ready sqi > 0, need to stop \n");\r
+              return 1;\r
+            }\r
+            if(ecg_ready_count >= (25*ECG_FS) && (PXIAFIB_GetICountECG(_state.pxialg_state_afib) == 0)){ //Ready time have already more than 25 sec, need to stop .\r
+                _state.has_got_AFIB=1; \r
+                ecg_afib_algorithm_close();\r
+                _state.has_time_out=1;\r
+                ALG_PRINT("Ready time have already more than 25 sec, need to stop \n");\r
+              return 1;\r
+            }\r
+        }\r
+    }\r
+    \r
+    if((ReadyFlag == 1)&&(AFIB_ReadyFlag)){\r
+        PXIAFIB_ComputeRRI(_state.pxialg_state_afib);\r
+\r
+#if 1       // Use ECG HRV realtime HR. for get mean HR\r
+            int16_t mean_hr = 0;\r
+            mean_hr = PXIAFIB_ComputeMeanHR(_state.pxialg_state_afib); //need to instead hrv lib hr.\r
+            ALG_PRINT("mean_hr=%d\n", mean_hr);\r
+#endif\r
+            //for check p,r,t number\r
+            ecg_r_number   = PXIAFIB_GetEcgRNumber(_state.pxialg_state_afib);\r
+            ecg_p_number   = PXIAFIB_GetEcgPNumber(_state.pxialg_state_afib);\r
+            ecg_t_number   = PXIAFIB_GetEcgTNumber(_state.pxialg_state_afib);\r
+            ecg_rri_number = PXIAFIB_GetRawRRINum(_state.pxialg_state_afib);\r
+//            ecg_rri_buf = (int16_t *)PXIAFIB_GetRawRRIBuf(_state.pxialg_state_afib);\r
+//                // log RRI data\r
+//                for(i=0;i<hrv_result.ecg_rri_number;i++)\r
+//                    fprintf(pFile_offline_rri, "%d\n", (int)hrv_result.ecg_rri_buf[i]);\r
+\r
+            //for check p,r,t  buffer\r
+//            ecg_r_buf = (int16_t *)PXIAFIB_GetEcgRIndex(_state.pxialg_state_afib);\r
+//            ecg_p_buf = (int16_t *)PXIAFIB_GetEcgPIndex(_state.pxialg_state_afib);\r
+//            ecg_t_buf = (int16_t *)PXIAFIB_GetEcgTIndex(_state.pxialg_state_afib);\r
+//            //log p, r, t peaks indx\r
+//            for(i=0;i<hrv_result.ecg_r_number;i++)\r
+//                fprintf(pFile_offline_r, "%d\n", (int)hrv_result.ecg_r_buf[i]);\r
+//            for(i=0;i<hrv_result.ecg_r_number;i++)\r
+//                fprintf(pFile_offline_p, "%d\n", (int)hrv_result.ecg_p_buf[i]);\r
+//            for(i=0;i<hrv_result.ecg_r_number;i++)\r
+//                fprintf(pFile_offline_t, "%d\n", (int)hrv_result.ecg_t_buf[i]);\r
+\r
+            //for NRMSSDresult\r
+            nrmssd_real = PXIAFIB_GetRealNRMSSD(_state.pxialg_state_afib);\r
+            ALG_PRINT("nrmssd_real=%.3f\n", nrmssd_real);\r
+            //for check PRT result\r
+            ecg_prt = (float)ecg_p_number/ecg_r_number;\r
+            ALG_PRINT("ecg_prt=%f\n", ecg_prt);\r
+                    if(mean_hr < 50){\r
+                        ecg_afib_result = 4;\r
+                        ALG_PRINT("low heart rate(<50bpm) \n");\r
+                    }else if(mean_hr > 120){\r
+                        ecg_afib_result = 5;\r
+                        ALG_PRINT("high heart rate(>120bpm) \n");\r
+                    }else {\r
+                        if(ecg_prt >= 0.55f && nrmssd_real < 0.052f){\r
+                            ecg_afib_result = 0; \r
+                            ALG_PRINT("Sinus Rhythm \n"); \r
+                        }else if(ecg_prt >= 0.55f && nrmssd_real >= 0.052f){\r
+                            ecg_afib_result = 1;\r
+                            ALG_PRINT("Inconclusive(Irregular) \n");\r
+                        }else if(ecg_prt < 0.55f && nrmssd_real >= 0.052f){\r
+                            ecg_afib_result = 2;\r
+                            ALG_PRINT("Possible AFIB \n"); \r
+                        }else {\r
+                            ecg_afib_result = 3;\r
+                            ALG_PRINT("Inconclusive(Feature & SQ issue) \n"); \r
+                        }\r
+                    }\r
+                    ALG_PRINT("ecg_afib_result = %d\n", ecg_afib_result);\r
+            ecg_afib_algorithm_close();\r
+            }else {\r
+                ALG_PRINT("Signal not ready! \n");\r
+            }\r
+#endif // ENABLE_PXI_ALG_ECG_AFIB\r
+            return 1;\r
+}\r
+\r
+\r
+\r
+void ecg_afib_algorithm_close(void)\r
+{\r
+    \r
+#if defined(ENABLE_PXI_ALG_ECG_AFIB)\r
+    if (_state.pxialg_has_init)\r
+    {\r
+        _state.pxialg_has_init = false;\r
+        PXIAFIB_Close(_state.pxialg_state_afib, _state.pxialg_buffer_afib);\r
+        free(_state.pxialg_buffer_afib);\r
+        free(_state.pxialg_state_afib);\r
+   #if defined(ENABLE_PXI_ALG_ECG_HRD) \r
+        free(_state.pxialg_buffer_hrv);\r
+   #endif // ENABLE_PXI_ALG_ECG_HRD \r
+        need_log_header = true;\r
+        _state.pxialg_data.frame_count = 0 ;\r
+        LOG_PRINT("ecg_afib_algorithm_close \n");\r
+    }\r
+#endif // ENABLE_PXI_ALG_ECG_AFIB\r
+}\r
+\r
+void ecg_afib_algorithm_init(void)\r
+{\r
+    _state.pxialg_has_init = false;\r
+    need_log_header = true;\r
+    AFIB_ReadyFlag = 0;\r
+    _state.has_got_AFIB=0;\r
+    _state.has_time_out=0;\r
+    _state.pxialg_data.frame_count = 0 ;\r
+\r
+#if defined(ENABLE_PXI_ALG_ECG_AFIB)\r
+    if (_state.pxialg_has_init)\r
+    {\r
+        _state.pxialg_has_init = false;\r
+        free(_state.pxialg_buffer_afib);\r
+        free(_state.pxialg_state_afib);\r
+   #if defined(ENABLE_PXI_ALG_ECG_HRD) \r
+        free(_state.pxialg_buffer_hrv);\r
+   #endif // ENABLE_PXI_ALG_ECG_HRD \r
+        need_log_header = true;\r
+        _state.pxialg_data.frame_count = 0 ;\r
+        LOG_PRINT("ecg_afib_algorithm_init \n");\r
+    }\r
+#endif // ENABLE_PXI_ALG_ECG_AFIB\r
+}\r
diff --git a/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/ECG_AFIB/V2022/pah_ecg_afib_alg.h b/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/ECG_AFIB/V2022/pah_ecg_afib_alg.h
new file mode 100644 (file)
index 0000000..10d69c9
--- /dev/null
@@ -0,0 +1,44 @@
+/*==============================================================================\r
+* Edit History\r
+* \r
+* This section contains comments describing changes made to the module. Notice\r
+* that changes are listed in reverse chronological order. Please use ISO format\r
+* for dates.\r
+* \r
+* when       who       what, where, why\r
+* ---------- ---       -----------------------------------------------------------\r
+* 2016-04-29 bell      Initial revision.\r
+==============================================================================*/\r
+\r
+#ifndef __pah_ecg_afib_alg_h__\r
+#define __pah_ecg_afib_alg_h__\r
+\r
+\r
+#include <stdbool.h>\r
+#include <stdint.h>\r
+#include <string.h>\r
+\r
+\r
+bool  report_fifo_data_ecg_afib(\r
+uint32_t ppg_timestamp,        \r
+uint32_t time_period, \r
+uint32_t *ppg_data,\r
+uint8_t  *tag_data,\r
+uint16_t ppg_size,\r
+uint8_t ch_num,\r
+int16_t *acc_data,\r
+uint16_t acc_size, \r
+uint8_t *alg_value_out,\r
+uint8_t *got_AFIB,\r
+uint8_t *got_time_out,\r
+uint8_t is_touched  \r
+);\r
+\r
+\r
+void ecg_afib_algorithm_init(void);\r
+\r
+void ecg_afib_algorithm_close(void);\r
+\r
+\r
+#endif  // header guard\r
+\r
diff --git a/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/ECG_AFIB/V2022/pah_ecg_afib_api.h b/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/ECG_AFIB/V2022/pah_ecg_afib_api.h
new file mode 100644 (file)
index 0000000..b33a7f9
--- /dev/null
@@ -0,0 +1,61 @@
+#ifndef ECG_AFIB_API_H_\r
+#define ECG_AFIB_API_H_\r
+\r
+#if defined(WIN32) && !defined(PXIALG_STATIC_LIB)\r
+#   ifdef PXIALG_EXPORTS\r
+#       define PXIALG_API   __declspec(dllexport)\r
+#   else\r
+#       define PXIALG_API   __declspec(dllimport)\r
+#endif\r
+#else\r
+#   define PXIALG_API\r
+#endif // WIN32\r
+\r
+\r
+#ifdef __cplusplus\r
+extern "C"\r
+{\r
+#endif\r
+       //PXIALG_API int ATOReset(void);\r
+       PXIALG_API int PXIAFIB_GetMemorySize(void *p_state,int enable_lhr, int test_seconds, int sampling_rate);\r
+       PXIALG_API int PXIAFIB_GetStateSize(void);\r
+       PXIALG_API int PXIAFIB_Open(void *p_state,void *p_buffer,int ECG_FS,int ECG_time);\r
+       PXIALG_API int PXIAFIB_Reset(void *p_state,int ecg_fs);\r
+       PXIALG_API int PXIAFIB_Process(void *p_state,int data_ready, int data);\r
+       PXIALG_API int PXIAFIB_GetReady(void *p_state,int data,short touch_flag,int frame_sum);\r
+       PXIALG_API void PXIAFIB_ComputeRRI(void *p_state);\r
+       PXIALG_API int PXIAFIB_ComputeMeanHR(void *p_state);    \r
+       PXIALG_API void PXIAFIB_ExtractECG(int count);\r
+       PXIALG_API int PXIAFIB_GetICountECG(void *p_state);\r
+       PXIALG_API int PXIAFIB_GetIReadyCountECG(void *p_state);\r
+       PXIALG_API int PXIAFIB_Close(void *p_state,void *p_buffer);\r
+       PXIALG_API int PXIAFIB_rawADC(void *p_state,float dac_raw);\r
+       PXIALG_API int PXIAFIB_GetVersion(void);\r
+       PXIALG_API float PXIAFIB_GetNRMSSD(void *p_state);\r
+       PXIALG_API float PXIAFIB_GetRealNRMSSD(void *p_state);\r
+       PXIALG_API float PXIAFIB_GetNSDNN(void *p_state);\r
+       PXIALG_API int PXIAFIB_GetEcgRNumber(void *p_state);\r
+       PXIALG_API int PXIAFIB_GetEcgPNumber(void *p_state);\r
+       PXIALG_API int PXIAFIB_GetEcgTNumber(void *p_state);\r
+       PXIALG_API int* PXIAFIB_GetEcgRIndex(void *p_state);\r
+       PXIALG_API int* PXIAFIB_GetEcgPIndex(void *p_state);\r
+       PXIALG_API int* PXIAFIB_GetEcgTIndex(void *p_state);\r
+       PXIALG_API float PXIAFIB_GetEcgkSQI(void *p_state);\r
+       PXIALG_API float PXIAFIB_GetEcgsSQI(void *p_state);\r
+       PXIALG_API float PXIAFIB_GetEcgcSQI(void *p_state);\r
+       PXIALG_API float PXIAFIB_GetEcgpSQI(void *p_state);\r
+       PXIALG_API float PXIAFIB_GetEcgbasSQI(void *p_state);\r
+       PXIALG_API float PXIAFIB_GetEcgaSQI(void *p_state);\r
+       PXIALG_API int PXIAFIB_GETEcgStopFlag(void *p_state);\r
+       PXIALG_API float PXIAFIB_GetShannonEntropy(void *p_state);      \r
+       PXIALG_API int PXIAFIB_GetRawRRINum(void *p_state);\r
+       PXIALG_API float PXIAFIB_GetSTDResult(void *p_state);\r
+       PXIALG_API int * PXIAFIB_GetRawRRIBuf(void *p_state);\r
+       PXIALG_API float  PXIAFIB_GetECGBpfRealTimeData(void *p_state);\r
+       PXIALG_API float  PXIAFIB_GetECGReadySQI(void *p_state);\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif /* HRV_API_H_ */\r
+\r
diff --git a/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/ECG_HRV/V103/hcp_ecg_hrv_api.h b/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/ECG_HRV/V103/hcp_ecg_hrv_api.h
new file mode 100644 (file)
index 0000000..8ff7b28
--- /dev/null
@@ -0,0 +1,40 @@
+#ifndef __HCP_ECG_HRV_API_H__\r
+#define __HCP_ECG_HRV_API_H__\r
+\r
+#include "stdint.h"\r
+\r
+#if defined(WIN32) && !defined(PXIALG_STATIC_LIB)\r
+#   ifdef PXIALG_EXPORTS\r
+#       define PXIALG_API   __declspec(dllexport)\r
+#   else\r
+#       define PXIALG_API   __declspec(dllimport)\r
+#   endif\r
+#else\r
+#   define PXIALG_API\r
+#endif // WIN32\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif \r
+\r
+PXIALG_API int32_t ECG_Analysis_Get_Memory_Size(void);\r
+PXIALG_API int32_t ECG_Analysis_Open(void *ecg_ram);\r
+PXIALG_API void ECG_Analysis_Reset(void *ecg_ram);\r
+PXIALG_API void ECG_Analysis_Process(void *ecg_ram, int32_t touch_flag, int32_t data, float time);\r
+PXIALG_API void ECG_Analysis_Process_float(void *ecg_ram, int32_t touch_flag, float data, float time);\r
+PXIALG_API void ECG_Analysis_Close(void *ecg_ram);\r
+PXIALG_API void ECG_Analysis_GetHRV(void *ecg_ram, float *hr_avg, float *sdnn, float *sq);\r
+PXIALG_API void ECG_Analysis_SetSamplingRate(void *ecg_ram, int32_t fs);\r
+PXIALG_API void ECG_Analysis_SetQRSConstrain(void *ecg_ram, int32_t phase_length_th);\r
+PXIALG_API void ECG_Analysis_SetRRIConstrain(void *ecg_ram, float rri_max, float rri_min, int32_t sq_win, float rri_error_th);\r
+PXIALG_API int32_t ECG_Analysis_Get_Ready_Flag(void* ecg_ram);\r
+PXIALG_API int32_t ECG_Analysis_Get_RTOR(void* ecg_ram, int32_t* rtor);\r
+PXIALG_API float ECG_Analysis_Get_HR(void* ecg_ram);\r
+PXIALG_API float ECG_Analysis_Get_Stress(void* ecg_ram, float score);\r
+PXIALG_API int ECG_Analysis_Get_Version(void);\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif // __cplusplus\r
+\r
+#endif\r
diff --git a/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/ECG_HRV/V103/libecghrv_v103_4.a b/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/ECG_HRV/V103/libecghrv_v103_4.a
new file mode 100644 (file)
index 0000000..30725ad
Binary files /dev/null and b/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/ECG_HRV/V103/libecghrv_v103_4.a differ
diff --git a/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/ECG_PPG_BP/v3070/libecgbp_v3070_1.a b/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/ECG_PPG_BP/v3070/libecgbp_v3070_1.a
new file mode 100644 (file)
index 0000000..e7e30bd
Binary files /dev/null and b/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/ECG_PPG_BP/v3070/libecgbp_v3070_1.a differ
diff --git a/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/ECG_PPG_BP/v3070/pah_ecg_bp_alg.c b/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/ECG_PPG_BP/v3070/pah_ecg_bp_alg.c
new file mode 100644 (file)
index 0000000..1d47ae1
--- /dev/null
@@ -0,0 +1,507 @@
+// c\r
+\r
+#include <string.h>\r
+#include <stdint.h>\r
+#include <stdbool.h>\r
+#include <stdlib.h>\r
+#include <stdio.h>\r
+#include <string.h>\r
+\r
+#include "pah831x_comm.h"\r
+#include "pah831x_config.h"\r
+#include "pah831x_main.h"\r
+\r
+#include "pah_ecg_bp_alg.h"\r
+#include "pxi_bp_api.h"\r
+\r
+//#include "flashDataRW.h"\r
+\r
+\r
+#if defined(ENABLE_PXI_ALG_ECG_HRD)\r
+#include "hcp_ecg_hrv_api.h"\r
+#endif\r
+\r
+#include "custom_utils.h"\r
+\r
+typedef struct {\r
+    uint8_t                     frame_count;\r
+    uint32_t                    time;\r
+    uint8_t                     touch_flag;\r
+    uint32_t                    nf_ppg_channel;\r
+    uint32_t                    nf_ppg_per_channel;\r
+    int32_t                     *ppg_data;\r
+    int32_t                     *ecg_data;    \r
+    uint32_t                    nf_mems;\r
+    int16_t                     *mems_data;\r
+} pah8series_data_t;\r
+\r
+\r
+typedef struct\r
+{\r
+     // pxialg\r
+    void*                pxialg_buffer_bp;\r
+    void*                pxialg_state_bp;\r
+    void*                pxialg_buffer_hrv;\r
+    pah8series_data_t    pxialg_data;\r
+    bool                 pxialg_has_init;\r
+    uint64_t             last_report_time;\r
+    uint8_t*             ppg_dac_data;\r
+    uint8_t*             ecg_tag_data;\r
+    float                collect_duration;\r
+    uint8_t              has_got_BP;\r
+    uint8_t              has_time_out;\r
+    int                  cal_value;\r
+    int                  mean_hr;\r
+} main_ecg_bp_state_s;\r
+\r
+static bool need_log_header = true;\r
+static main_ecg_bp_state_s _state;\r
+\r
+static struct ECG_result ecg_result;\r
+\r
+static int alg_value[2];\r
+\r
+static uint16_t ecg_ready_count = 0;\r
+\r
+\r
+int ppg_pf_output;\r
+\r
+\r
+\r
+\r
+/*****\r
+ * @brief Each user needs blood pressure monitor to calibrated. after obtaining these \r
+          four values (calibration_bp[4]) from the algorithm can we measure blood pressure.\r
+          Save each user's algo value in Flash.\r
+ *****/\r
+/***** Save User Profile data to Flash ***/\r
+//static bool bp_cal_ready = true ;\r
+//int calibration_bp[4] = {-1,-22,28,64};\r
+static bool bp_cal_ready = false ;\r
+int calibration_bp[4] = {0};\r
+uint16_t    omron_sbp = 0;\r
+uint16_t    omron_dbp = 0;\r
+uint8_t     cal_mode = 0;\r
+int         cal_sbp = 0;\r
+int         cal_dbp = 0;\r
+uint8_t     Age = 39;\r
+float       height = 0;\r
+\r
+int         CalValue = 0;\r
+int         CalValue1 = 0;\r
+\r
+\r
+float hrv_hr=0.0f;\r
+\r
+float pwv;\r
+int pwv_result;\r
+int NoCal_SBP,NoCal_DBP,Out_SBP,Out_DBP;\r
+\r
+static uint8_t  BP_ReadyFlag = 0;\r
+\r
+#define K_sampling_rate 256\r
+\r
+/*============================================================================\r
+STATIC FUNCTION PROTOTYPES\r
+============================================================================*/\r
+\r
+\r
+static void log_pah8series_data_header(uint32_t ch_num, uint32_t ir_ch_num, uint32_t g_sensor_mode);\r
+static void log_pah8series_data(const pah8series_data_t *data);\r
+static bool ecg_bp_algorithm_process(pah8series_data_t *pxialg_data, uint32_t ch_num);\r
+static bool ecg_bp_algorithm_calculate(pah8series_data_t *pxialg_data, uint32_t ch_num);\r
+static uint8_t run_ecg_bp_pxialg(uint32_t duration, const uint32_t* ecg_data,  const uint32_t* ppg_data, uint16_t ecg_data_num, uint8_t touch_flag);\r
+\r
+static void log_pah8series_data_header(uint32_t ch_num, uint32_t ir_ch_num, uint32_t g_sensor_mode)\r
+{\r
+    //log pah8series data header\r
+    LOG_PRINT("ECG CH#, %d, %d, %d, %d\n", \r
+                ch_num,      /*(1)Using total channel numbers;*/ \\r
+                0,           /*(2)reserved;*/ \\r
+                ir_ch_num,   /*(3)IR channel number;*/ \\r
+                g_sensor_mode/*(4)MEMS mode 0:2G, 1:4G, 2:8G*/ \\r
+                );\r
+}\r
+//#define JS_PRINT_LOG\r
+static void log_pah8series_data(const pah8series_data_t *pxialg_data)\r
+{\r
+    #define PAH_DEBUG_MODE\r
+    int i = 0;\r
+    uint32_t *ppg_data = (uint32_t *)pxialg_data->ppg_data;\r
+    uint32_t *ecg_data = (uint32_t *)pxialg_data->ecg_data;\r
+    uint8_t *dac_data = _state.ppg_dac_data;\r
+    uint8_t *ecg_tag_data = _state.ecg_tag_data;\r
+    \r
+    int16_t *mems_data = pxialg_data->mems_data;\r
+    int data_num = pxialg_data->nf_ppg_channel * pxialg_data->nf_ppg_per_channel;\r
+    int ecg_data_num = 1 * pxialg_data->nf_ppg_per_channel;\r
+    \r
+    LOG_PRINT("Frame Count, %d \n", pxialg_data->frame_count);\r
+    LOG_PRINT("Time, %d \n", pxialg_data->time);\r
+    LOG_PRINT("PPG, %d, %d, ", pxialg_data->touch_flag, data_num);\r
+    #ifdef PAH_DEBUG_MODE\r
+    for (i = 0; i < data_num; ++i)\r
+    {\r
+        LOG_PRINT("%d, ", *ppg_data);\r
+        ppg_data++;\r
+    }\r
+    LOG_PRINT("\n");\r
+    #endif\r
+    LOG_PRINT("ECG, %d, %d, ", pxialg_data->touch_flag, ecg_data_num);\r
+    #ifdef PAH_DEBUG_MODE\r
+    for (i = 0; i < ecg_data_num; ++i)\r
+    {\r
+        LOG_PRINT("%d, ", *ecg_data);\r
+        ecg_data++;\r
+    }\r
+    LOG_PRINT("\n");\r
+    #endif\r
+    LOG_PRINT("MEMS, %d, ", pxialg_data->nf_mems);\r
+    #ifdef PAH_DEBUG_MODE\r
+    for (i = 0; i < (pxialg_data->nf_mems * 3); ++i)\r
+    {\r
+        LOG_PRINT("%d, ", *mems_data);\r
+        mems_data++;\r
+    }\r
+    LOG_PRINT("\n");\r
+    #endif\r
+    LOG_PRINT("DAC, %d, ", data_num);\r
+    #ifdef PAH_DEBUG_MODE\r
+    for (i = 0; i < data_num; ++i)\r
+    {\r
+        LOG_PRINT("%d, ", *dac_data);\r
+        dac_data++;\r
+    }\r
+    LOG_PRINT("\n");\r
+    #endif\r
+    LOG_PRINT("ECG_TAG,  %d, ",  ecg_data_num);\r
+    #ifdef PAH_DEBUG_MODE\r
+    for (i = 0; i < data_num; ++i)\r
+    {\r
+        LOG_PRINT("%d, ", *ecg_tag_data);\r
+        ecg_tag_data++;\r
+    }\r
+    LOG_PRINT("\n");\r
+    #endif\r
+}\r
+\r
+\r
+bool  report_fifo_data_ecg_bp(\r
+uint32_t ppg_timestamp,     \r
+uint32_t time_period, \r
+uint32_t *ppg_data,\r
+uint32_t *ecg_data,\r
+uint8_t  *dac_data,\r
+uint8_t  *tag_data,\r
+uint16_t ppg_size,\r
+uint8_t ch_num,\r
+int16_t *acc_data,\r
+uint16_t acc_size, \r
+int *alg_value_out,\r
+uint8_t *got_BP,\r
+uint8_t *got_time_out,\r
+uint8_t is_touched,\r
+uint8_t calibration_mode,\r
+uint8_t user_age,\r
+uint16_t Benchmark_SBP,\r
+uint16_t Benchmark_DBP,\r
+float   user_height,\r
+bool bp_cal_ready ,\r
+int cal_sbp_in    ,   \r
+int cal_dbp_in    ,\r
+int CalValue_in   ,\r
+int CalValue1_in     \r
+)\r
+{\r
+//    ALG_PRINT("time_period = %d  timestamp =%d \n", time_period , ppg_timestamp);\r
+    _state.pxialg_data.mems_data = acc_data ;\r
+    _state.pxialg_data.nf_mems =   acc_size  ;\r
+    _state.pxialg_data.touch_flag = is_touched<2 ? 1 : 0;\r
+    _state.pxialg_data.time = time_period;\r
+    _state.pxialg_data.ppg_data = (int32_t*)ppg_data;\r
+    _state.pxialg_data.ecg_data = (int32_t*)ecg_data;\r
+ \r
+    _state.pxialg_data.nf_ppg_channel = ch_num;\r
+    _state.pxialg_data.nf_ppg_per_channel = ppg_size;\r
+    ++_state.pxialg_data.frame_count;\r
+    _state.ecg_tag_data = tag_data ;\r
+    _state.ppg_dac_data = dac_data ;\r
+    \r
+    cal_mode = calibration_mode;\r
+    Age = user_age;\r
+    omron_sbp = Benchmark_SBP;\r
+    omron_dbp = Benchmark_DBP;\r
+    if(bp_cal_ready)\r
+    {\r
+        cal_sbp   =   cal_sbp_in  ;\r
+        cal_dbp   =   cal_dbp_in  ;\r
+        CalValue  =   CalValue_in ;\r
+        CalValue1 =   CalValue1_in;\r
+    }\r
+//    cal_sbp   =   calibration_bp[0];\r
+//    cal_dbp   =   calibration_bp[1];\r
+//    CalValue  =   calibration_bp[2];\r
+//    CalValue1 =   calibration_bp[3];\r
+    \r
+    height = user_height;\r
+    \r
+    //if(is_touched)\r
+    {\r
+        ecg_bp_algorithm_process(&_state.pxialg_data, _state.pxialg_data.nf_ppg_channel);\r
+        memcpy(alg_value_out,alg_value,sizeof(alg_value));\r
+    }\r
+    *got_time_out = _state.has_time_out ;\r
+    *got_BP = _state.has_got_BP;\r
+    return true ;\r
+}\r
+\r
+#define PPG_ECG_PPG_LOG_EN 1\r
+static bool ecg_bp_algorithm_process(pah8series_data_t *pxialg_data, uint32_t ch_num)\r
+{\r
+    // log header\r
+    if(PPG_ECG_PPG_LOG_EN)\r
+    {\r
+        if (need_log_header)\r
+        {\r
+            need_log_header = false;\r
+            log_pah8series_data_header(ch_num, PPG_IR_CH_NUM, ALG_GSENSOR_MODE);\r
+        }\r
+        // log\r
+        log_pah8series_data(&_state.pxialg_data);  \r
+    }\r
+    \r
+    ecg_bp_algorithm_calculate(&_state.pxialg_data, ch_num);\r
+    return true;\r
+}\r
+\r
+static bool ecg_bp_algorithm_calculate(pah8series_data_t *pxialg_data, uint32_t ch_num)\r
+{\r
+    bool has_updated = false;\r
+     // Initialize algorithm\r
+    if (!_state.pxialg_has_init)\r
+    {\r
+        uint32_t BP_state_size = 0;\r
+        uint32_t bp_buffer_size = 0;\r
+        uint32_t hrv_buffer_size = 0;\r
+#if defined(ENABLE_PXI_ALG_ECG_BP)       \r
+        BP_state_size = PXIBP_GetStateSize();\r
+        ALG_PRINT("ECG_BP_state_query_open_size() = %d \n", BP_state_size);\r
+\r
+                _state.pxialg_state_bp = (void*)malloc(BP_state_size);\r
+         if (!_state.pxialg_state_bp){\r
+             ALG_PRINT("ECG_BP_state_size_not enough \n");\r
+               return false;\r
+         }        \r
+        \r
+        bp_buffer_size= PXIBP_GetMemorySize(_state.pxialg_state_bp, \\r
+                                            1, \\r
+                                            (int)30/*MEAS._time Sec.*/, \\r
+                                            (int)256/*ECG_FS 256Hz*/);\r
+        ALG_PRINT("BP_Buffer_query_open_size() = %d\n", bp_buffer_size);\r
+               _state.pxialg_buffer_bp = (void*)malloc(bp_buffer_size);\r
+        if (!_state.pxialg_buffer_bp){\r
+            ALG_PRINT("ECG_BP_buffer_size_not enough \n");\r
+              return false;\r
+        }\r
+       \r
+\r
+        if (!PXIBP_Open(_state.pxialg_state_bp, _state.pxialg_buffer_bp, (int)256/*ECG_FS 256Hz*/, (int)30/*MEAS._time Sec.*/, height)){\r
+                ALG_PRINT("PXIBP_Open failed. \n");\r
+                return false;   \r
+        }\r
+        \r
+            PXIBP_SetModel(_state.pxialg_state_bp, \\r
+                           omron_sbp/*Benchmark */, \\r
+                           omron_dbp/*Benchmark  */, \\r
+                           cal_sbp/**/, \\r
+                           cal_dbp/**/, \\r
+                           cal_mode/*Calibration Enable*/);\r
+        \r
+        ALG_PRINT("PXIBP_SetModel = %d%,%d,%d,%d,%d,%d,\n", omron_sbp,omron_dbp,cal_sbp,cal_dbp,CalValue,CalValue1);\r
+    #if defined(ENABLE_PXI_ALG_ECG_HRD)\r
+        hrv_buffer_size = ECG_Analysis_Get_Memory_Size();\r
+        ALG_PRINT("ECG_HRV_query_open_size() = %d\n", hrv_buffer_size);\r
+         _state.pxialg_buffer_hrv = (void*)malloc(hrv_buffer_size);\r
+         if (!_state.pxialg_buffer_hrv){\r
+             ALG_PRINT("ECG_HR_buffer_size_not enough \n");\r
+             return false;\r
+         }\r
+        if (!ECG_Analysis_Open(_state.pxialg_buffer_hrv)){\r
+            ALG_PRINT("ECG_Analysis_Open failed. \n");\r
+            return false;\r
+        }\r
+        ECG_Analysis_SetSamplingRate(_state.pxialg_buffer_hrv, K_sampling_rate);\r
+    #endif  //    ENABLE_PXI_ALG_ECG_HRD\r
+#endif\r
+        \r
+        _state.pxialg_has_init = true;\r
+    }\r
+    \r
+    run_ecg_bp_pxialg(pxialg_data->time, \\r
+                    (const uint32_t*)pxialg_data->ecg_data, \\r
+                    (const uint32_t*)pxialg_data->ppg_data, \\r
+                    (pxialg_data->nf_ppg_channel * pxialg_data->nf_ppg_per_channel), \\r
+                    pxialg_data->touch_flag);\r
+\r
+    return has_updated;\r
+}\r
+\r
+static uint8_t run_ecg_bp_pxialg(uint32_t duration, const uint32_t* ecg_data, const uint32_t* ppg_data, uint16_t ecg_data_num, uint8_t touch_flag)\r
+{\r
+\r
+#if defined(ENABLE_PXI_ALG_ECG_BP)\r
+    // if (_state.has_got_BP)\r
+    //     return 1;\r
+    float HR = 0.0f;\r
+  #if defined(ENABLE_PXI_ALG_ECG_HRD)\r
+    float interval_time=(float)duration/ecg_data_num;\r
+    for(uint16_t j=0; j < ecg_data_num; j++){\r
+        ECG_Analysis_Process(_state.pxialg_buffer_hrv, touch_flag, ecg_data[j], interval_time);\r
+    }\r
+    HR =ECG_Analysis_Get_HR(_state.pxialg_buffer_hrv);\r
+    ALG_PRINT("ECG Heart Rate = %d  ready_flag = %d\n", (int)HR,ecg_result.ready_flag);\r
+  #endif  //    ENABLE_PXI_ALG_ECG_HRD\r
+\r
+    for(uint32_t i=0; i < ecg_data_num; i++){\r
+        ecg_result.ready_flag = PXIBP_GetReady(_state.pxialg_state_bp, \\r
+                                               (float)ecg_data[i], \\r
+                                               touch_flag/*touch flag*/, \\r
+                                               1);                  \r
+  \r
+        ecg_result.ecg_ready_count = PXIBP_GetIReadyCountECG(_state.pxialg_state_bp);\r
+  \r
+        ecg_result.ecg_readysqi = PXIBP_GetECGReadySQI(_state.pxialg_state_bp);\r
+                                               \r
+        if((ecg_result.ready_flag == 1) && (PXIBP_GETEcgStopFlag(_state.pxialg_state_bp) == 0)){ // count-down 30sec to collect data.\r
+            int16_t P_output = PXIBP_Process(_state.pxialg_state_bp, \\r
+                                             1, \\r
+                                             (int)ecg_data[i], \\r
+                                             (int)ppg_data[i], \\r
+                                             &ppg_pf_output);\r
+            ecg_result.ecg_frame_count = PXIBP_GetICountECG(_state.pxialg_state_bp);\r
+            \r
+            if(ecg_result.ecg_frame_count == (30*256/*MEAS._time x ECG_FS*/)){\r
+                ALG_PRINT("collect 30sec \n");\r
+                BP_ReadyFlag = 1;\r
+                }\r
+            }else {\r
+            if(PXIBP_GETEcgStopFlag(_state.pxialg_state_bp) == 1) {//ready sqi > 0, need to stop .\r
+                _state.has_time_out = 1;\r
+\r
+                ALG_PRINT("EcgStop,has_time_out\n");\r
+                //ecg_bp_algorithm_close();\r
+              return 1;\r
+            }     \r
+        } \r
+    }\r
+\r
+    if((ecg_result.ready_flag == 1)&&(BP_ReadyFlag)){\r
+        //time_s=get_sys_tick();\r
+        PXIBP_SetCalValue(_state.pxialg_state_bp, CalValue, CalValue1);\r
+        pwv = PXIBP_AnalysisECG(_state.pxialg_state_bp, HR, Age, cal_mode, omron_sbp, omron_dbp);\r
+        pwv_result = PXIBP_GetPWV_Result(_state.pxialg_state_bp);\r
+        ALG_PRINT("pwv = %f, pwv_result = %d\n", pwv, pwv_result);      // { 0:Poor 1:Normal 2:Good }\r
+        //time_e=get_sys_tick();\r
+        //debug_printf("pwv duration time = %d \n\r",time_e-time_s);\r
+        if(cal_mode == ECG_PPG_BP_CALI){\r
+            NoCal_SBP = PXIBP_ComputeSBP_NOCal(_state.pxialg_state_bp);\r
+            NoCal_DBP = PXIBP_ComputeDBP_NOCal(_state.pxialg_state_bp);\r
+            calibration_bp[0] = PXIBP_GetdiffSBP(_state.pxialg_state_bp);\r
+            calibration_bp[1] = PXIBP_GetdiffDBP(_state.pxialg_state_bp);\r
+            calibration_bp[2] = PXIBP_Getcalvalue(_state.pxialg_state_bp);\r
+            calibration_bp[3] = PXIBP_Getcalvalue1(_state.pxialg_state_bp);\r
+            //extern atomic_t  BPcalibration_mode;\r
+            //atomic_set(&BPcalibration_mode,0);\r
+            //SetBpDataPer();\r
+            bp_cal_ready = true ;\r
+            _state.has_got_BP++;\r
+            ALG_PRINT("Calibration = %d, ", cal_mode);\r
+            ALG_PRINT("NoCal_SBP = %d, NoCal_DBP = %d\n", NoCal_SBP, NoCal_DBP);\r
+            ALG_PRINT("calibration_bp = %d,%d, %d,%d,\n", calibration_bp[0], calibration_bp[1],calibration_bp[2],calibration_bp[3]);\r
+        }else{\r
+        \r
+            Out_SBP = PXIBP_ComputeSBP(_state.pxialg_state_bp);\r
+            Out_DBP = PXIBP_ComputeDBP(_state.pxialg_state_bp);\r
+            _state.has_got_BP++; \r
+            if(_state.has_got_BP == 1)\r
+            {\r
+                alg_value[0] = Out_SBP;\r
+                alg_value[1] = Out_DBP;\r
+                ALG_PRINT("alg_value[0] = %d, alg_value[1] = %d ,touch_flag = :%d\n", alg_value[0],alg_value[1],touch_flag);\r
+            }\r
+            \r
+            ALG_PRINT("Out_SBP = %d, Out_DBP = %d ecg_ready_count %d\n", Out_SBP, Out_DBP,ecg_result.ecg_ready_count);\r
+        }\r
+        \r
+    }else{\r
+        ALG_PRINT("Signal not ready!");\r
+    }\r
+#endif // ENABLE_PXI_ALG_ECG_BP\r
+    return 1;\r
+}\r
+\r
+void ecg_bp_algorithm_init(void)\r
+{\r
+#if defined(ENABLE_PXI_ALG_ECG_BP)\r
+    if (_state.pxialg_has_init)\r
+    {\r
+        _state.pxialg_has_init = false;\r
+\r
+        #if defined(ENABLE_PXI_ALG_ECG_HRD)\r
+        free(_state.pxialg_buffer_hrv);\r
+        #endif        \r
+        free(_state.pxialg_state_bp);\r
+        free(_state.pxialg_buffer_bp);\r
+        memset(&ecg_result,0,sizeof(ecg_result));\r
+        need_log_header = true;\r
+        BP_ReadyFlag = 0;\r
+        _state.has_got_BP = 0;\r
+        _state.has_time_out = 0;\r
+        _state.pxialg_data.frame_count = 0 ;\r
+        LOG_PRINT("ecg_bp_algorithm_init \n");\r
+    }\r
+#endif // ENABLE_PXI_ALG_ECG_BP\r
+}\r
+  \r
+void ecg_bp_algorithm_close(void)\r
+{\r
+#if defined(ENABLE_PXI_ALG_ECG_BP)\r
+    if (_state.pxialg_has_init)\r
+    {\r
+        LOG_PRINT("ecg_bp_algorithm_close \n");\r
+        _state.pxialg_has_init = false;\r
+        PXIBP_Close(_state.pxialg_state_bp, _state.pxialg_buffer_bp); // close\r
+        #if defined(ENABLE_PXI_ALG_ECG_HRD)\r
+        free(_state.pxialg_buffer_hrv);\r
+        #endif        \r
+        free(_state.pxialg_state_bp);\r
+        free(_state.pxialg_buffer_bp);\r
+        memset(&ecg_result,0,sizeof(ecg_result));\r
+        BP_ReadyFlag = 0;\r
+        _state.has_got_BP = 0;\r
+        _state.has_time_out = 0;\r
+        need_log_header = true;\r
+        _state.pxialg_data.frame_count = 0 ;\r
+    }\r
+#endif // ENABLE_PXI_ALG_ECG_BP\r
+}\r
+bool get_bp_cal_data(int* cal_data)\r
+{\r
+    cal_data[0]=calibration_bp[0];\r
+    cal_data[1]=calibration_bp[1];\r
+    cal_data[2]=calibration_bp[2];\r
+    cal_data[3]=calibration_bp[3];\r
+    return bp_cal_ready ;\r
+}    \r
+\r
+void pah8311_get_bp(int *sbp,int *dbp)\r
+{\r
+    if(sbp == NULL || dbp == NULL)\r
+        return;\r
+        \r
+    *sbp = NoCal_SBP;\r
+    *dbp = NoCal_DBP;\r
+\r
+    NoCal_SBP = 0;\r
+    NoCal_DBP = 0;\r
+}
\ No newline at end of file
diff --git a/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/ECG_PPG_BP/v3070/pah_ecg_bp_alg.h b/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/ECG_PPG_BP/v3070/pah_ecg_bp_alg.h
new file mode 100644 (file)
index 0000000..9ecc16b
--- /dev/null
@@ -0,0 +1,59 @@
+/*==============================================================================\r
+* Edit History\r
+* \r
+* This section contains comments describing changes made to the module. Notice\r
+* that changes are listed in reverse chronological order. Please use ISO format\r
+* for dates.\r
+* \r
+* when       who       what, where, why\r
+* ---------- ---       -----------------------------------------------------------\r
+* 2016-04-29 bell      Initial revision.\r
+==============================================================================*/\r
+\r
+#ifndef __pah_ecg_bp_alg_h__\r
+#define __pah_ecg_bp_alg_h__\r
+\r
+\r
+#include <stdbool.h>\r
+#include <stdint.h>\r
+#include <string.h>\r
+\r
+\r
+bool  report_fifo_data_ecg_bp(\r
+uint32_t ppg_timestamp, \r
+uint32_t time_period, \r
+uint32_t *ppg_data,\r
+uint32_t *ecg_data,\r
+uint8_t *dac_data,\r
+uint8_t  *tag_data,\r
+uint16_t ppg_size,\r
+uint8_t ch_num,\r
+int16_t *acc_data,\r
+uint16_t acc_size, \r
+int *alg_value_out,\r
+uint8_t *got_BP,\r
+uint8_t *got_time_out,\r
+uint8_t is_touched,\r
+uint8_t calibration_mode,\r
+uint8_t user_age,\r
+uint16_t    Benchmark_SBP,\r
+uint16_t    Benchmark_DBP,\r
+float   user_height,\r
+bool bp_cal_ready ,\r
+int cal_sbp_in    ,   \r
+int cal_dbp_in    ,\r
+int CalValue_in   ,\r
+int CalValue1_in  \r
+);\r
+\r
+\r
+void ecg_bp_algorithm_init(void);\r
+\r
+\r
+void ecg_bp_algorithm_close(void);\r
+\r
+bool get_bp_cal_data(int* cal_data);\r
+\r
+\r
+#endif  // header guard\r
+\r
diff --git a/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/ECG_PPG_BP/v3070/pxi_bp_api.h b/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/ECG_PPG_BP/v3070/pxi_bp_api.h
new file mode 100644 (file)
index 0000000..929111a
--- /dev/null
@@ -0,0 +1,103 @@
+#ifndef _PXIALG_BP_\r
+#define _PXIALG_BP_\r
+\r
+#include "stdint.h"\r
+\r
+#if defined(WIN32) && !defined(PXIALG_STATIC_LIB)\r
+#   ifdef PXIALG_EXPORTS\r
+#       define PXIALG_API   __declspec(dllexport)\r
+#   else\r
+#       define PXIALG_API   __declspec(dllimport)\r
+#   endif\r
+#else\r
+#   define PXIALG_API\r
+#endif // WIN32\r
+\r
+\r
+#ifdef __cplusplus\r
+extern "C"\r
+{\r
+#endif\r
+\r
+       typedef struct {\r
+               float p1;\r
+               int p2;\r
+               int p3;\r
+               int p4[100];\r
+               int p5;\r
+               int p6[100];\r
+               int p7;\r
+               int p8[100];\r
+               float p9;\r
+               float p10;\r
+               float p11;\r
+               int p12;\r
+               int p13;\r
+               int p14;\r
+               int p15;\r
+               int p16;\r
+               int p17;\r
+               int p18;\r
+               int p19;\r
+               int p20;\r
+       }BPResult;\r
+\r
+       struct ECG_result {\r
+               int state_size;\r
+               int buffer_size;\r
+               int ecg_frame_count;\r
+               int ecg_ready_count;\r
+               float ecg_readysqi;\r
+               int ready_flag;\r
+       };\r
+\r
+       PXIALG_API int PXIBP_GetVersion(void);\r
+       PXIALG_API int PXIBP_GetMemorySize(void *p_state,int enable_lhr, int test_seconds, int sampling_rate);\r
+       PXIALG_API int PXIBP_GetStateSize(void);\r
+       PXIALG_API int PXIBP_Open(void *p_state,void *p_buffer,int ECG_FS,int ECG_time,float height);\r
+       PXIALG_API void PXIBP_SetModel(void *p_state,int omron_sbp,int omron_dbp,int cal_sbp,int cal_dbp,int calmode);\r
+       PXIALG_API int PXIBP_Process(void *p_state,int data_ready, int data,int data1,int* ppg_output);\r
+       PXIALG_API int PXIBP_GetReady(void *p_state,int data,short touch_flag,int frame_sum);\r
+       PXIALG_API float  PXIBP_GetSDNN(void *p_state);\r
+       PXIALG_API float  PXIBP_GetRMSSD(void *p_state);\r
+       PXIALG_API void PXIBP_SetCalValue(void *p_state, int value1, int value2);\r
+       PXIALG_API float PXIBP_AnalysisECG(void *p_state,float hrv_hr,int age,int cal_mode,int omron_sbp,int omron_dbp);\r
+       PXIALG_API int PXIBP_ComputeSBP(void *p_state);\r
+       PXIALG_API int PXIBP_GetPWV_Result(void *p_state);\r
+       PXIALG_API int PXIBP_GetdiffSBP(void *p_state);\r
+       PXIALG_API int PXIBP_GetdiffDBP(void *p_state);\r
+       PXIALG_API int PXIBP_Getcalvalue(void *p_state);\r
+       PXIALG_API int PXIBP_Getcalvalue1(void *p_state);\r
+       PXIALG_API int PXIBP_GetResult(void *p_state,BPResult *bp_result);\r
+       PXIALG_API int PXIBP_ComputeDBP(void *p_state);\r
+       PXIALG_API int PXIBP_ComputeSBP_NOCal(void *p_state);\r
+       PXIALG_API int PXIBP_ComputeDBP_NOCal(void *p_state);\r
+       PXIALG_API int PXIBP_GetICountECG(void *p_state);\r
+       PXIALG_API int PXIBP_GetIReadyCountECG(void *p_state);\r
+       PXIALG_API int PXIBP_Close(void *p_state,void *p_buffer);\r
+       PXIALG_API int PXIBP_rawADC(void *p_state,float dac_raw);\r
+       PXIALG_API int PXIBP_GETEcgStopFlag(void *p_state);\r
+       PXIALG_API float  PXIBP_GetECGReadySQI(void *p_state);\r
+#if 0\r
+       PXIALG_API void PXIAFIBOpen(void *p_buffer,int P_Th0,\r
+                                                          int P_Th1,\r
+                                                          int P_Th2,\r
+                                                          int P_Th3,\r
+                                                          int H_Th1,\r
+                                                          int H_Th2,\r
+                                                          int H_Th3,\r
+                                                          float Offset);\r
+       PXIALG_API int IHBGetMemory(int enable_lhr, int test_seconds, int sampling_rate);\r
+       PXIALG_API int IHBProcess(float data);\r
+       PXIALG_API int IHBResult(float mean_hr);\r
+       PXIALG_API void IHBGetResult(IHBresult *p);\r
+       PXIALG_API void IHBDecode(IHBresult *p);\r
+       PXIALG_API float IHBCheck(void);\r
+       PXIALG_API void IHBClose(void *p);\r
+#endif\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif /* _PXIALG_AFIB_ */\r
+\r
diff --git a/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/HRD/v5653/libhr_v5653_3.a b/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/HRD/v5653/libhr_v5653_3.a
new file mode 100644 (file)
index 0000000..ede59bc
Binary files /dev/null and b/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/HRD/v5653/libhr_v5653_3.a differ
diff --git a/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/HRD/v5653/pah831x_testpattern_HRD.h b/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/HRD/v5653/pah831x_testpattern_HRD.h
new file mode 100644 (file)
index 0000000..ffbd742
--- /dev/null
@@ -0,0 +1,264 @@
+#ifndef _PAH831x_TESTPATTERN_\r
+#define _PAH831x_TESTPATTERN_\r
+\r
+#include <stdint.h>\r
+#define NF_PPG_CHANNEL 1\r
+#define NF_PPG_PER_CHANNEL 30\r
+static const int32_t PAH831x_rawdata_HRD[][NF_PPG_PER_CHANNEL*NF_PPG_CHANNEL] = \r
+{\r
+{1, 20, 126895, 351967, 1126749, 1412507, 1511185, 1622335, 1751269, 1902539, 2082335, 2299557, 2567191, 2904801, 3344931, 3942167, 4801289, 6089909, 7092175, 7506431, 7618145, 7628949},\r
+{1, 20, 7630491, 7645867, 7659817, 7683205, 7698343, 7712887, 7731527, 7748979, 7766075, 7779373, 7789761, 7795993, 7801633, 7739125, 7679763, 7668305, 7677091, 7698165, 7715617, 7722801},\r
+{1, 20, 7737937, 7755687, 7771121, 7785191, 7800505, 7820629, 7829593, 7851557, 7863845, 7874649, 7882009, 7895367, 7877617, 7799555, 7750523, 7744705, 7746783, 7761979, 7766015, 7762989},\r
+{1, 20, 7774267, 7778897, 7793323, 7805491, 7820273, 7831909, 7842059, 7853101, 7860223, 7875183, 7883315, 7889371, 7879041, 7784063, 7732595, 7731883, 7744229, 7764057, 7767915, 7767025},\r
+{1, 20, 7776583, 7779075, 7793679, 7809529, 7828405, 7836597, 7849717, 7855949, 7867347, 7875717, 7891271, 7895485, 7822411, 7766847, 7754737, 7761979, 7782935, 7790711, 7793383, 7797715},\r
+{1, 20, 7805671, 7820927, 7839387, 7854347, 7866695, 7882009, 7892813, 7900591, 7916203, 7926473, 7916321, 7820629, 7773793, 7775929, 7782935, 7799793, 7804423, 7804839, 7807925, 7820035},\r
+{1, 20, 7836775, 7844611, 7856485, 7869663, 7877379, 7887589, 7894179, 7913175, 7913175, 7828525, 7779551, 7779313, 7785487, 7802287, 7808935, 7808461, 7808103, 7824429, 7833155, 7850547},\r
+{1, 20, 7861709, 7876429, 7884087, 7894951, 7907179, 7921783, 7883969, 7792789, 7767025, 7765601, 7773793, 7779431, 7788929, 7798013, 7803355, 7822173, 7840279, 7853695, 7867169, 7877913},\r
+{1, 20, 7885869, 7894297, 7912107, 7928193, 7898751, 7802109, 7762633, 7758595, 7756697, 7776227, 7781035, 7782697, 7783705, 7794391, 7806619, 7822233, 7834343, 7841407, 7848411, 7858027},\r
+{1, 20, 7874411, 7889311, 7873283, 7783587, 7739837, 7737047, 7739303, 7753549, 7760435, 7760139, 7762395, 7774743, 7789999, 7801811, 7814397, 7827455, 7840457, 7854763, 7865567, 7884919},\r
+{1, 20, 7905221, 7836241, 7754085, 7737879, 7741203, 7759071, 7771537, 7770231, 7773733, 7778363, 7794273, 7809113, 7822469, 7834757, 7843009, 7851617, 7861293, 7871147, 7886105, 7878863},\r
+{1, 20, 7776405, 7728677, 7724521, 7730933, 7746841, 7753787, 7755213, 7760257, 7769875, 7787981, 7799497, 7814099, 7820155, 7835113, 7856663, 7867109, 7878389, 7887887, 7791185, 7732239},\r
+{1, 20, 7722919, 7737107, 7746605, 7758181, 7754499, 7756637, 7767323, 7785011, 7800505, 7807333, 7818611, 7823361, 7834521, 7846749, 7856899, 7867703, 7790593, 7712175, 7698937, 7697869},\r
+{1, 20, 7702677, 7718941, 7714845, 7716745, 7729331, 7741499, 7754975, 7779431, 7781865, 7793857, 7805491, 7822113, 7831611, 7853575, 7830425, 7730637, 7688133, 7675251, 7676439, 7691161},\r
+{1, 20, 7696325, 7693357, 7695257, 7710749, 7717043, 7734317, 7750997, 7766015, 7762811, 7782935, 7794095, 7802523, 7819501, 7795341, 7692763, 7657265, 7642957, 7648537, 7662547, 7662311},\r
+{1, 20, 7670561, 7659341, 7675785, 7686173, 7703805, 7708019, 7719417, 7729627, 7743577, 7752125, 7765779, 7776049, 7733485, 7652337, 7623725, 7615769, 7618025, 7628355, 7628651, 7626099},\r
+{1, 20, 7630313, 7637793, 7651327, 7662845, 7669433, 7679821, 7686649, 7692585, 7702321, 7719239, 7728855, 7673173, 7599149, 7578549, 7575167, 7580033, 7588167, 7591907, 7591551, 7599207},\r
+{1, 20, 7611793, 7620163, 7633935, 7646163, 7656493, 7666999, 7676973, 7689973, 7707187, 7711343, 7632569, 7573919, 7565075, 7564777, 7573919, 7583595, 7583417, 7580331, 7590185, 7601285},\r
+{1, 20, 7613811, 7622893, 7635537, 7645391, 7653821, 7667653, 7681187, 7699531, 7693535, 7600871, 7555043, 7548097, 7555101, 7564955, 7573563, 7566499, 7568637, 7579499, 7596655, 7611793},\r
+{1, 20, 7621943, 7633223, 7643551, 7655365, 7666585, 7682433, 7695435, 7670443, 7573563, 7541805, 7541745, 7549403, 7561037, 7564837, 7564421, 7567983, 7583773, 7600217, 7614583, 7627167},\r
+{1, 20, 7639039, 7645629, 7657621, 7669375, 7684333, 7700065, 7650023, 7557773, 7536403, 7535097, 7545723, 7559317, 7558425, 7554093, 7560563, 7572851, 7586089, 7599565, 7610783, 7622775},\r
+{1, 20, 7637913, 7645689, 7662311, 7680653, 7672223, 7578609, 7535037, 7527321, 7532781, 7544179, 7552075, 7547801, 7555101, 7572019, 7588939, 7603185, 7618559, 7632333, 7644441, 7650971},\r
+{1, 20, 7668543, 7677031, 7608527, 7533969, 7526133, 7524945, 7543347, 7550531, 7546553, 7543051, 7556527, 7561573, 7579499, 7588879, 7600633, 7609833, 7622597, 7641117, 7635657, 7550353},\r
+{1, 20, 7500963, 7492177, 7490099, 7500725, 7510521, 7511767, 7508205, 7519603, 7532129, 7543883, 7549877, 7562521, 7571249, 7586919, 7594519, 7591491, 7510995, 7461785, 7444985, 7442611},\r
+{1, 20, 7447003, 7451811, 7448605, 7449199, 7461785, 7469323, 7478999, 7486775, 7496867, 7501081, 7514557, 7529457, 7538481, 7470095, 7407527, 7385919, 7374997, 7378973, 7384553, 7382179},\r
+{1, 20, 7376125, 7382595, 7392627, 7400403, 7411089, 7419577, 7429195, 7437267, 7451455, 7469383, 7467305, 7388057, 7331603, 7315575, 7303999, 7310945, 7315159, 7306729, 7306077, 7312725},\r
+{1, 20, 7326795, 7332909, 7344009, 7352023, 7365677, 7373513, 7390311, 7406161, 7412573, 7338251, 7276929, 7251879, 7246417, 7251523, 7252711, 7246417, 7244339, 7248851, 7259299, 7271527},\r
+{1, 20, 7283401, 7290999, 7306017, 7315219, 7331959, 7347333, 7367933, 7320383, 7237751, 7204983, 7200471, 7201895, 7209435, 7209673, 7204211, 7208307, 7220773, 7234723, 7248435, 7259953},\r
+{1, 20, 7268679, 7277761, 7293849, 7305661, 7327209, 7328041, 7246061, 7187767, 7169959, 7167585, 7180823, 7182603, 7182365, 7185333, 7196257, 7210623, 7221841, 7235733, 7245111, 7262979},\r
+{1, 20, 7277227, 7290227, 7312487, 7328279, 7275921, 7191033, 7165091, 7165091, 7167407, 7177023, 7181593, 7177497, 7183137, 7197443, 7208069, 7223919, 7233417, 7241669, 7255857, 7267789},\r
+{1, 20, 7287853, 7306315, 7272003, 7192577, 7166575, 7163489, 7173759, 7187055, 7193881, 7190973, 7200947, 7211929, 7226235, 7244577, 7254847, 7269629, 7279897, 7295095, 7315753, 7331069},\r
+{1, 20, 7275387, 7198571, 7182009, 7180287, 7193525, 7203795, 7205279, 7206289, 7214719, 7231933, 7246003, 7261259, 7273843, 7282867, 7301091, 7314625, 7285477, 7207713, 7180287, 7178447},\r
+{1, 20, 7191745, 7202431, 7205635, 7203557, 7211037, 7224809, 7240243, 7252591, 7266363, 7276159, 7294205, 7310411, 7247427, 7188539, 7175777, 7177973, 7194773, 7202787, 7203143, 7201777},\r
+{1, 20, 7209909, 7224275, 7241135, 7251167, 7264701, 7280255, 7287437, 7227185, 7174233, 7158739, 7161351, 7173165, 7177973, 7173045, 7174945, 7183791, 7197207, 7211215, 7220713, 7231873},\r
+{1, 20, 7244815, 7257459, 7209673, 7130957, 7095935, 7076701, 7067025, 7066669, 7067321, 7063701, 7064947, 7080441, 7092017, 7104541, 7110893, 7124607, 7132977, 7148707, 7165389, 7185571},\r
+{1, 20, 7142119, 7057943, 7014667, 6997095, 6983859, 6986411, 6987717, 6984155, 6985877, 6996205, 7009325, 7021969, 7037581, 7042983, 7055449, 7071715, 7084061, 7098665, 7119797, 7130957},\r
+{1, 20, 7084003, 6999055, 6967653, 6954533, 6947053, 6956313, 6958689, 6953583, 6958095, 6970561, 6982315, 6996799, 7012709, 7023927, 7036631, 7050581, 7065243, 7084893, 7103177, 7122765},\r
+{1, 20, 7125081, 7032119, 6983621, 6973885, 6977329, 6991991, 6994483, 6993891, 7003923, 7015677, 7033841, 7044407, 7066431, 7076345, 7089405, 7112259, 7123241, 7143187, 7158027, 7184443},\r
+{1, 20, 7181831, 7090413, 7044585, 7046247, 7052243, 7070467, 7082637, 7084061, 7084833, 7099793, 7120333, 7137963, 7155297, 7165447, 7186995, 7195069, 7215371, 7235555, 7248615, 7268975},\r
+{1, 20, 7222375, 7143721, 7136003, 7146511, 7166635, 7179457, 7183019, 7187353, 7196435, 7210801, 7229915, 7251523, 7264463, 7276633, 7292957, 7308807, 7315337, 7338073, 7363717, 7348817},\r
+{1, 20, 7259181, 7229439, 7240303, 7254965, 7273783, 7280491, 7283281, 7287259, 7305009, 7319553, 7337777, 7353329, 7363303, 7378855, 7389481, 7401947, 7420883, 7439345, 7426701, 7345375},\r
+{1, 20, 7314387, 7320027, 7333503, 7354161, 7357781, 7360275, 7369239, 7384553, 7396841, 7412869, 7426167, 7435367, 7445815, 7460003, 7471817, 7488675, 7495739, 7427295, 7379805, 7381705},\r
+{1, 20, 7395417, 7412751, 7424505, 7424207, 7428363, 7438335, 7454127, 7463921, 7482323, 7488379, 7502209, 7511173, 7526371, 7510579, 7438693, 7414413, 7422487, 7434359, 7449853, 7453415},\r
+{1, 20, 7453415, 7456263, 7471875, 7488557, 7500073, 7511707, 7522631, 7532781, 7542041, 7556883, 7544951, 7467245, 7438157, 7442135, 7449081, 7463327, 7467957, 7471579, 7474251, 7484639},\r
+{1, 20, 7495443, 7508681, 7522097, 7529933, 7541033, 7551005, 7561631, 7572851, 7573623, 7497699, 7456145, 7455729, 7458281, 7468849, 7481789, 7479237, 7482799, 7492949, 7507611, 7522215},\r
+{1, 20, 7530763, 7539727, 7548215, 7554449, 7568043, 7581517, 7568517, 7495027, 7461725, 7465703, 7473775, 7493069, 7488259, 7494731, 7497699, 7512063, 7518475, 7532365, 7539431, 7546019},\r
+{1, 20, 7555635, 7564303, 7574989, 7592975, 7593983, 7515211, 7471817, 7475141, 7477693, 7486657, 7496451, 7494731, 7495145, 7508917, 7514795, 7528033, 7537471, 7550233, 7558129, 7570121},\r
+{1, 20, 7576829, 7587217, 7603719, 7562521, 7493661, 7476981, 7473953, 7481729, 7496037, 7497817, 7496095, 7502209, 7519663, 7528567, 7540855, 7553795, 7562641, 7575641, 7582111, 7596595},\r
+{1, 20, 7606807, 7619095, 7561513, 7492119, 7476743, 7478939, 7488497, 7499597, 7498055, 7496095, 7502923, 7518475, 7529873, 7544239, 7551125, 7559673, 7571011, 7583061, 7593331, 7608469},\r
+{1, 20, 7611495, 7525777, 7476803, 7469619, 7477991, 7486479, 7494967, 7490397, 7494375, 7504229, 7515389, 7525895, 7540023, 7549225, 7562165, 7570833, 7580747, 7594221, 7610605, 7614761},\r
+{1, 20, 7532307, 7472291, 7466593, 7467187, 7477753, 7487073, 7486063, 7485589, 7491347, 7505177, 7522511, 7532603, 7547801, 7555517, 7569527, 7580569, 7595883, 7610843, 7609063, 7517229},\r
+{1, 20, 7466651, 7459765, 7461547, 7474073, 7481433, 7477397, 7481195, 7489447, 7506483, 7518059, 7532723, 7541329, 7552549, 7564777, 7573267, 7588701, 7605737, 7574573, 7480601, 7452167},\r
+{1, 20, 7450505, 7458401, 7470569, 7472529, 7466829, 7473657, 7488437, 7499361, 7511115, 7527023, 7535809, 7543645, 7560147, 7577659, 7547325, 7459707, 7429729, 7427473, 7435189, 7448427},\r
+{1, 20, 7449021, 7442313, 7452583, 7463683, 7481433, 7491169, 7508443, 7517823, 7530525, 7541271, 7558011, 7574691, 7575701, 7472647, 7408359, 7390431, 7389065, 7396071, 7392745, 7388591},\r
+{1, 20, 7392093, 7394585, 7412335, 7419697, 7431391, 7443381, 7451811, 7463803, 7477219, 7496273, 7503873, 7423257, 7353033, 7328159, 7318959, 7312903, 7329229, 7325013, 7320323, 7322105},\r
+{1, 20, 7336707, 7352261, 7360869, 7376539, 7388175, 7392271, 7409011, 7428839, 7447121, 7422901, 7319433, 7275861, 7254907, 7248673, 7257399, 7254551, 7249505, 7253837, 7265057, 7273249},\r
+{1, 20, 7289337, 7303643, 7317119, 7330891, 7351549, 7367755, 7387581, 7402481, 7361699, 7256569, 7210325, 7194831, 7199047, 7207475, 7204685, 7192933, 7192813, 7211393, 7225285, 7234249},\r
+{1, 20, 7251047, 7257577, 7275387, 7288565, 7303347, 7330177, 7343891, 7277999, 7189965, 7150489, 7139743, 7141347, 7150963, 7150251, 7141761, 7155891, 7161529, 7185155, 7190201, 7215609},\r
+{1, 20, 7231459, 7244519, 7266719, 7278117, 7301625, 7316941, 7215371, 7131907, 7111903, 7104305, 7125615, 7125971, 7123419, 7124725, 7131611, 7147521, 7173045, 7186699, 7201895, 7218221},\r
+{1, 20, 7234189, 7249267, 7269629, 7288447, 7303999, 7213293, 7122409, 7097715, 7086555, 7058417, 6959283, 6811173, 6641991, 6433807, 3488961, 2852423, 3535317, 3280071, 3219391, 2337569},\r
+{1, 20, 2177665, 5475461, 5538735, 2458821, 1923747, 2203997, 4717461, 3378727, 368189, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},      \r
+};\r
+static const int16_t PAH831x_mems_HRD[][3*NF_PPG_PER_CHANNEL] = \r
+{\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},      \r
+};\r
+static const uint32_t duration_HRD[] = \r
+{\r
+1140,\r
+1070,\r
+955,\r
+994,\r
+1002,\r
+1001,\r
+999,\r
+1000,\r
+1001,\r
+999,\r
+1000,\r
+1001,\r
+999,\r
+1000,\r
+999,\r
+1002,\r
+1000,\r
+1001,\r
+998,\r
+999,\r
+998,\r
+1000,\r
+1000,\r
+1001,\r
+1000,\r
+1001,\r
+1000,\r
+1000,\r
+1001,\r
+1001,\r
+1000,\r
+998,\r
+999,\r
+1000,\r
+1000,\r
+999,\r
+1000,\r
+1000,\r
+1000,\r
+1001,\r
+1000,\r
+1001,\r
+1000,\r
+1001,\r
+999,\r
+1000,\r
+1001,\r
+1001,\r
+1000,\r
+998,\r
+999,\r
+1001,\r
+999,\r
+1000,\r
+999,\r
+1000,\r
+1001,\r
+1001,\r
+1001,\r
+999,\r
+1000,  \r
+};\r
+\r
+static const uint32_t framenumbers_HRD[] = \r
+{\r
+1,\r
+2,\r
+3,\r
+4,\r
+5,\r
+6,\r
+7,\r
+8,\r
+9,\r
+10,\r
+11,\r
+12,\r
+13,\r
+14,\r
+15,\r
+16,\r
+17,\r
+18,\r
+19,\r
+20,\r
+21,\r
+22,\r
+23,\r
+24,\r
+25,\r
+26,\r
+27,\r
+28,\r
+29,\r
+30,\r
+31,\r
+32,\r
+33,\r
+34,\r
+35,\r
+36,\r
+37,\r
+38,\r
+39,\r
+40,\r
+41,\r
+42,\r
+43,\r
+44,\r
+45,\r
+46,\r
+47,\r
+48,\r
+49,\r
+50,\r
+51,\r
+52,\r
+53,\r
+54,\r
+55,\r
+56,\r
+57,\r
+58,\r
+59,\r
+60,\r
+61,    \r
+};\r
+#endif\r
diff --git a/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/HRD/v5653/pah8series_api_c.h b/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/HRD/v5653/pah8series_api_c.h
new file mode 100644 (file)
index 0000000..557a6c7
--- /dev/null
@@ -0,0 +1,56 @@
+#ifndef __PAH8SERIES_API_C_H__\r
+#define __PAH8SERIES_API_C_H__\r
+\r
+\r
+#include "pah8series_data_c.h"\r
+\r
+\r
+#if defined(WIN32) && !defined(PXIALG_STATIC_LIB)\r
+#   ifdef PXIALG_EXPORTS\r
+#       define PXIALG_API   __declspec(dllexport)\r
+#   else\r
+#       define PXIALG_API   __declspec(dllimport)\r
+#   endif\r
+#else\r
+#    define PXIALG_API\r
+#endif // WIN32\r
+\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif // __cplusplus\r
+\r
+\r
+PXIALG_API uint32_t pah8series_version(void);\r
+PXIALG_API uint32_t pah8series_query_open_size(void);\r
+PXIALG_API uint8_t  pah8series_open(void *pBuffer);\r
+PXIALG_API uint8_t  pah8series_close(void);\r
+PXIALG_API uint8_t  pah8series_reset(void);\r
+PXIALG_API uint8_t  pah8series_set_param(pah8series_param_idx_t idx, float p1);\r
+PXIALG_API uint8_t  pah8series_get_param(pah8series_param_idx_t idx, float *p1);\r
+PXIALG_API uint8_t  pah8series_get_hr(float *hr);\r
+PXIALG_API uint8_t  pah8series_get_hr_trust_level(int *hr_trust_level);\r
+PXIALG_API uint8_t  pah8series_entrance(pah8series_data_t *pah8series_data);\r
+PXIALG_API uint8_t  pah8series_set_data(pah8series_data_t *pah8series_data);\r
+PXIALG_API uint8_t  pah8series_process(uint8_t *is_finished);\r
+PXIALG_API uint8_t  pah8series_get_signal_grade(int16_t *grade);\r
+//PXIALG_API uint8_t  pah8series_get_display_buffer(int32_t **buffer1, int32_t **buffer2, int32_t *size);\r
+PXIALG_API uint8_t  pah8series_get_signal_level(int ch, uint8_t *signal_level);\r
+PXIALG_API uint8_t  pah8series_get_rms_gs(int32_t *rms_gs);\r
+PXIALG_API uint8_t  pah8series_get_motion_flag(uint8_t *motion_flag);\r
+PXIALG_API uint8_t  pah8series_get_wear_index(uint32_t expo_time[3], uint8_t led_dac[3], uint8_t checkRaw, int *wear_index);\r
+PXIALG_API uint8_t  pah8series_get_object_flag(uint8_t *object_flag);\r
+PXIALG_API uint8_t  pah8series_get_flag_forced_out(uint8_t *flag_forced_out);\r
+PXIALG_API uint8_t  pah8series_get_smooth_hr(float *smooth_hr);\r
+PXIALG_API uint8_t     pah8series_set_alg_ch_order(int8_t *alg_ch, int8_t ch_nr);\r
+PXIALG_API uint8_t pah8series_get_pi_val(float *val, int array_size);\r
+#if FW == 0\r
+PXIALG_API uint8_t  pah8series_set_debug_file_print_en(uint8_t en, char *path);\r
+#endif\r
+PXIALG_API uint8_t pah8series_set_alg_ch_order(int8_t *alg_ch, int8_t ch_nr);\r
+#ifdef __cplusplus\r
+}\r
+#endif // __cplusplus\r
+\r
+\r
+#endif\r
diff --git a/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/HRD/v5653/pah8series_data_c.h b/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/HRD/v5653/pah8series_data_c.h
new file mode 100644 (file)
index 0000000..a20af70
--- /dev/null
@@ -0,0 +1,215 @@
+#ifndef __PAH8SERIES_DATA_C_H__\r
+#define __PAH8SERIES_DATA_C_H__\r
+\r
+#include <stdint.h>\r
+\r
+typedef struct {\r
+    uint8_t                     frame_count;\r
+    uint32_t                    time;\r
+    uint8_t                     touch_flag;\r
+    uint32_t                    nf_ppg_channel;\r
+    uint32_t                    nf_ppg_per_channel;\r
+    int32_t                     *ppg_data;\r
+    uint32_t                    nf_mems;\r
+    int16_t                     *mems_data;\r
+} pah8series_data_t;\r
+\r
+typedef enum {\r
+    PAH8SERIES_PARAM_IDX_SAMPLE_RATE = 0,\r
+    PAH8SERIES_PARAM_IDX_GSENSOR_MODE,\r
+    PAH8SERIES_PARAM_IDX_PPG_CH_NUM,\r
+    PAH8SERIES_PARAM_IDX_HAS_IR_CH,\r
+    PAH8SERIES_PARAM_IDX_SIGNAL_GRADE,\r
+    PAH8SERIES_PARAM_IDX_IIR_SMOOTH_PRED,\r
+    PAH8SERIES_PARAM_IDX_IIR_LP,\r
+    PAH8SERIES_PARAM_IDX_FIRST_HR_MULTIPLE_OFFSET_MEMS_THR,\r
+    PAH8SERIES_PARAM_IDX_FIRST_HR_IN_MOTION_FLAG,\r
+    PAH8SERIES_PARAM_IDX_FIRST_HR_MEMS_QUALITY_THR,\r
+    PAH8SERIES_PARAM_IDX_FIRST_HR_PPG_QUALITY_THR,\r
+    PAH8SERIES_PARAM_IDX_STATIC_MODE,\r
+    PAH8SERIES_PARAM_IDX_STATIC_HR_UP_IDX,\r
+    PAH8SERIES_PARAM_IDX_STATIC_HR_DN_IDX,\r
+    PAH8SERIES_PARAM_IDX_IS_AUTO,\r
+    PAH8SERIES_PARAM_IDX_IS_TAG,\r
+    PAH8SERIES_PARAM_IDX_IS_8002,\r
+    PAH8SERIES_PARAM_IDX_FIRST_HR_6SEC,\r
+    PAH8SERIES_PARAM_IDX_HR_MODEL_TIME_CONST,\r
+    PAH8SERIES_PARAM_IDX_HR_MODEL_PROGRESS_RATIO,\r
+    PAH8SERIES_PARAM_IDX_INIT_WALK_HR,\r
+    PAH8SERIES_PARAM_IDX_WALK_HR_UP_IDX,\r
+    PAH8SERIES_PARAM_IDX_WALK_HR_DN_IDX,\r
+    PAH8SERIES_PARAM_IDX_HR_TOO_LOW_IDX,\r
+    PAH8SERIES_PARAM_IDX_EN_LWPS,\r
+    PAH8SERIES_PARAM_IDX_EN_JUDGE_WALK,\r
+    PAH8SERIES_PARAM_IDX_EN_CHK_HR_GT_MOTION,\r
+    PAH8SERIES_PARAM_IDX_EN_HI_QUALITY_HR_JMP,\r
+    PAH8SERIES_PARAM_IDX_EN_SPLIT_MOTION_PEAK,\r
+    PAH8SERIES_PARAM_IDX_EN_LOCAL_FIRST_PEAK_TRACK,\r
+    PAH8SERIES_PARAM_IDX_LOCAL_FIRST_PEAK_FRM_ALIVE_THR,\r
+    PAH8SERIES_PARAM_IDX_EN_GLOBAL_FIRST_PEAK_TRACK,\r
+    PAH8SERIES_PARAM_IDX_GLOBAL_FIRST_PEAK_FRM_ALIVE_THR,\r
+    PAH8SERIES_PARAM_IDX_EN_FORCE_HR_OUT_IN10S,\r
+    PAH8SERIES_PARAM_IDX_DEFAULT_HR_OUT_IN10S,\r
+    PAH8SERIES_PARAM_IDX_FIRST_HR_HALF_1X_ENERGY_THT,\r
+    PAH8SERIES_PARAM_IDX_HR_IN_MOTION_SEARCH_ST,\r
+    PAH8SERIES_PARAM_IDX_HR_IN_MOTION_SEARCH_END,\r
+    PAH8SERIES_PARAM_IDX_EN_MA_WALK,\r
+    PAH8SERIES_PARAM_IDX_EN_HAND_CLAP,\r
+    PAH8SERIES_PARAM_IDX_EN_NOR_PRE_DIFF_NOR,\r
+    PAH8SERIES_PARAM_IDX_EN_HALF_HR_CHK,\r
+    PAH8SERIES_PARAM_IDX_EN_NON_MOTION_FIRST_PEAK_TRACK,\r
+    PAH8SERIES_PARAM_IDX_NON_MOTION_FIRST_PEAK_ALIVE_FRM_THR,\r
+    PAH8SERIES_PARAM_IDX_PPG_NORMALIZE_LEN,\r
+    PAH8SERIES_PARAM_IDX_PPG_DIFF_NORMALIZE_LEN,\r
+    PAH8SERIES_PARAM_IDX_EN_CHK_HQ_3X_PPG,\r
+    PAH8SERIES_PARAM_IDX_EN_POST_HR_PROCESS,\r
+    //v519\r
+    PAH8SERIES_PARAM_IDX_SET_EN_JAFMI,\r
+    PAH8SERIES_PARAM_IDX_SET_EN_TIME_DOMAIN_CONFIRM,\r
+    PAH8SERIES_PARAM_IDX_SET_RESERVE_PEAK_RATIO_THR,\r
+    PAH8SERIES_PARAM_IDX_SET_SUPPORT_HR_IDX_OFFSET,\r
+    PAH8SERIES_PARAM_IDX_SET_SUPPORT_CHECK_STEP_FREQ,\r
+    //v520\r
+    PAH8SERIES_PARAM_IDX_SET_SUPPORT_FOUND_HR_IDX,\r
+    PAH8SERIES_PARAM_IDX_SET_SUPPORT_SIGNAL_LEVEL_CHECK,\r
+    //v521\r
+    PAH8SERIES_PARAM_IDX_SET_FORCE_OUT_SAMPLE_COUNT_10S,\r
+    //v526\r
+    PAH8SERIES_PARAM_IDX_SET_FLAG_LIMIT_HR_UB,\r
+    PAH8SERIES_PARAM_IDX_SET_LIMIT_HR_UB,\r
+    //v528\r
+    PAH8SERIES_PARAM_IDX_SET_SUPPORT_FAST_POST_HR_IDX_FLAG,\r
+    //v532\r
+    PAH8SERIES_PARAM_IDX_SET_FLAG_LIMIT_HR_LB,\r
+    PAH8SERIES_PARAM_IDX_SET_LIMIT_HR_LB,\r
+       //V534 pre06    \r
+       PAH8SERIES_PARAM_IDX_SET_FLAG_EN_ONHAND_RECONIZATION,\r
+       //V536 pre00\r
+       PAH8SERIES_PARAM_IDX_SET_LINIT_HROUT_LB,\r
+       PAH8SERIES_PARAM_IDX_SET_LINIT_HROUT_UB,\r
+       //V537 pre06\r
+       PAH8SERIES_PARAM_IDX_SET_DYNAMIC_HR_RATIO,              //V536 pre04\r
+       PAH8SERIES_PARAM_IDX_SET_IIR_LP2_ALPHA,\r
+       //V538 pre04\r
+       PAH8SERIES_PARAM_IDX_SET_SIGNAL_GRADE_ONDASK_THR,               //V536 pre01\r
+       PAH8SERIES_PARAM_IDX_SET_FLAG_EN_ARMSWING_RECOGNIZATION,\r
+       //V5363\r
+       PAH8SERIES_PARAM_IDX_SET_HROUT_TRUST_ENH,\r
+       PAH8SERIES_PARAM_IDX_SET_HROUT_TRUST_UB,\r
+       //V536 pre04\r
+       PAH8SERIES_PARAM_IDX_SET_SIG_LEVEL_GOOD_COUNT_TH,\r
+       PAH8SERIES_PARAM_IDX_SET_SIG_LEVEL_GOOD_MODE,\r
+       //V538 pre24\r
+       PAH8SERIES_PARAM_IDX_SET_TRUSE_LEVEL_EQMOTION,\r
+       //V539 pre25\r
+       PAH8SERIES_PARAM_IDX_SET_FLAG_EN_RE_INIT_HR_30S,\r
+       PAH8SERIES_PARAM_IDX_SET_FLAG_EN_DOUBLE_EA,\r
+       PAH8SERIES_PARAM_IDX_SET_DOUBLE_EA_ALPHA,\r
+       PAH8SERIES_PARAM_IDX_SET_DOUBLE_EA_BETA,\r
+       PAH8SERIES_PARAM_IDX_SET_FLAG_PREDICTION_FEEDBACK,\r
+       PAH8SERIES_PARAM_IDX_SET_FEEDBACK_GLITCH_COUNT_TH,\r
+       PAH8SERIES_PARAM_IDX_SET_FEEDBACK_TRUST_LEVEL_TH,\r
+       PAH8SERIES_PARAM_IDX_SET_FEEDBACK_LEN_PRED_SHORT,\r
+       PAH8SERIES_PARAM_IDX_SET_FEEDBACK_LEN_PRED_LONG,\r
+       PAH8SERIES_PARAM_IDX_SET_FLAG_PREDICTION_SMOOTH,\r
+       PAH8SERIES_PARAM_IDX_SET_SMOOTH_GLITCH_COUNT_TH,\r
+       PAH8SERIES_PARAM_IDX_SET_SMOOTH_TRUST_LEVEL_TH,\r
+       PAH8SERIES_PARAM_IDX_SET_SMOOTH_LEN_PRED_SHORT,\r
+       PAH8SERIES_PARAM_IDX_SET_SMOOTH_LEN_PRED_LONG,\r
+       PAH8SERIES_PARAM_IDX_SET_SKIP_DATA_LEN,\r
+       PAH8SERIES_PARAM_IDX_SET_FLAG_MEMS_3_SEP,\r
+       PAH8SERIES_PARAM_IDX_SET_FLAG_EN_SUPER_LOW_INIT_HR,\r
+       //V541 pre10\r
+       PAH8SERIES_PARAM_IDX_SET_FLAG_BIKE_MODE,\r
+       PAH8SERIES_PARAM_IDX_SET_MOTION_RMS_GS_THR,\r
+       //V542 pre05\r
+       PAH8SERIES_PARAM_IDX_SET_FLAG_EN_LIMIT_HR_UB_BY_MEMS,\r
+       PAH8SERIES_PARAM_IDX_SET_LIMIT_HR_UB_MEMS_TH,\r
+       PAH8SERIES_PARAM_IDX_SET_LIMIT_HR_UB_BY_MEMS,\r
+       //V543 pre06\r
+       PAH8SERIES_PARAM_IDX_SET_HR_STEP_FREQ_MIXED_DIFF_IDX_TH,\r
+       //V543 pre08\r
+       PAH8SERIES_PARAM_IDX_SET_STATIC_MEMS_FFT_ENERGY_TH,\r
+       //V544 pre07\r
+       PAH8SERIES_PARAM_IDX_SET_FLAG_EN_LIMIT_HR_DIFF,\r
+       PAH8SERIES_PARAM_IDX_SET_LIMIT_HR_DIFF,\r
+       PAH8SERIES_PARAM_IDX_SET_FLAG_EN_FORCE_HR_FOLLOW_MEMS,\r
+       PAH8SERIES_PARAM_IDX_SET_COUNT_DASK_TRANS_TO_HAND_TH,\r
+       //V546 pre03\r
+       PAH8SERIES_PARAM_IDX_SET_FLAG_MEMS_3_SWITCH,\r
+       PAH8SERIES_PARAM_IDX_SET_FLAG_EN_DY_HR_CLEAN_SPEC_AND_MOTION_IDX_FIX,\r
+       PAH8SERIES_PARAM_IDX_SET_NO_MOVE_JMP_DIFF_IDX,\r
+       PAH8SERIES_PARAM_IDX_SET_MOTION_JMP_DIFF_IDX_THR,\r
+       //V548 pre02\r
+       PAH8SERIES_PARAM_IDX_SET_FLAG_EN_CHANNEL_QUALITY,\r
+       PAH8SERIES_PARAM_IDX_SET_FLAG_TIME_DOMAIN_INIT_HR_DETECTION,\r
+       PAH8SERIES_PARAM_IDX_SET_FORCE_HR_FOLLOW_MEMS_UP_COUNT_TH,\r
+       PAH8SERIES_PARAM_IDX_SET_FORCE_HR_FOLLOW_MEMS_DN_COUNT_TH,\r
+       PAH8SERIES_PARAM_IDX_SET_FLAG_DYNAMIC_HR_RATIO_SWITCH,\r
+       PAH8SERIES_PARAM_IDX_SET_DYNAMIC_HR_REG_COUNT_TH,\r
+       PAH8SERIES_PARAM_IDX_SET_DYNAMIC_HR_RATIO_REG,\r
+       //V549 pre04\r
+       PAH8SERIES_PARAM_IDX_SET_FLAG_EN_SWIMMING_FINE_TUNING,\r
+       PAH8SERIES_PARAM_IDX_SET_FALG_INIT_HR_LBUB_BY_SIG_QUAL,\r
+       PAH8SERIES_PARAM_IDX_SET_FALG_INIT_HR_LBUB_BY_SIG_QUAL_TH,\r
+       PAH8SERIES_PARAM_IDX_SET_FALG_INIT_HR_BETWEEN_LBUB,\r
+       PAH8SERIES_PARAM_IDX_SET_FALG_IMP,\r
+       PAH8SERIES_PARAM_IDX_SET_INIT_HR_LBUB_RATIO,\r
+       //V550\r
+       PAH8SERIES_PARAM_IDX_SUPPORT_DYNAMIC_HR_STATE_SWITCH,\r
+       //V551\r
+       PAH8SERIES_PARAM_IDX_SET_TRUST_LEVEL_SKIP_ZERO_COUNT_TH,\r
+       PAH8SERIES_PARAM_IDX_SET_MOTION_JMP_DIFF_IDX_THR0,\r
+       PAH8SERIES_PARAM_IDX_SET_MOTION_JMP_DIFF_IDX_THR1,\r
+       //V552\r
+       PAH8SERIES_PARAM_IDX_SET_ADPTIVE_RLS_ORDER,\r
+       PAH8SERIES_PARAM_IDX_SET_FLAG_PREDICTION_FEEDBACK_DATA_COUNT,\r
+       PAH8SERIES_PARAM_IDX_SET_FLAG_PREDICTION_FEEDBACK_HR_LIMIT,\r
+       PAH8SERIES_PARAM_IDX_SET_FLAG_PREDICTION_FEEDBACK_SIGNAL_QUALITY,\r
+       //V552 pre04\r
+       PAH8SERIES_PARAM_IDX_SET_CHECK_SIGNAL_LEVEL_JMP_COUNT_TH,\r
+       PAH8SERIES_PARAM_IDX_SET_FLAG_CHECK_SIGNAL_LEVEL_EXCLUDE_MOTION_FREQ,\r
+       //V553 pre09\r
+       PAH8SERIES_PARAM_IDX_SET_FLAG_SUPPORT_AUTOCORRELATION,\r
+       PAH8SERIES_PARAM_IDX_SET_DYNAMIC_PPG_NORMALIZE_LEN,\r
+       //V553 pre11\r
+       PAH8SERIES_PARAM_IDX_SET_FLAG_SUPPORT_FFT120,\r
+       PAH8SERIES_PARAM_IDX_SET_IIR_FILTER_OUT_PRED_THR,\r
+       PAH8SERIES_PARAM_IDX_SET_IIR_FILTER_OUT_PRED_VALUE,\r
+       PAH8SERIES_PARAM_IDX_SET_IIR_FILTER_OUT_PRED_RATIO,\r
+    //V555\r
+    PAH8SERIES_PARAM_IDX_SET_MEMS_RAWDATA_SCALE,\r
+       //V559 pre01\r
+       PAH8SERIES_PARAM_IDX_SET_FLAG_SUPPORT_INTENSE_EXERCISE,\r
+       PAH8SERIES_PARAM_IDX_SET_FLAG_SUPPORT_DAILY_ACTIVITY,\r
+       PAH8SERIES_PARAM_IDX_SET_FLAG_SUPPORT_WALK_ACTIVITY,\r
+       //V562 pre00\r
+       PAH8SERIES_PARAM_IDX_SET_FFT_WINDOW_LEN,\r
+       //v5653\r
+       PAH8SERIES_PARAM_IDX_SET_IIR_LP_ALPHA_STATIC,\r
+       PAH8SERIES_PARAM_IDX_SET_IIR_LP_MOTION_TO_STATIC_COUNT,\r
+\r
+    PAH8SERIES_NF_PARAM_IDX,\r
+} pah8series_param_idx_t;\r
+\r
+typedef enum {\r
+    MSG_SUCCESS = 0,\r
+    MSG_ALG_NOT_OPEN,\r
+    MSG_ALG_REOPEN,\r
+    MSG_MEMS_LEN_TOO_SHORT,\r
+    MSG_NO_TOUCH,\r
+    MSG_PPG_LEN_TOO_SHORT,\r
+    MSG_FRAME_LOSS,\r
+    MSG_INVALID_ARGUMENT,\r
+       MSG_PROCESS_NOT_FINISHED,\r
+       MSG_ADDR_NOT_4BYTE_ALIGNED,\r
+\r
+    MSG_NO_MEM = 14,\r
+    MSG_ECG_LEN_TOO_SHORT = 15,\r
+\r
+    MSG_HR_READY = 0x30,\r
+    MSG_SIGNAL_POOR = 0x40\r
+} pah8series_msg_code_t;\r
+\r
+\r
+#endif // PAH8002_DATA_H__\r
diff --git a/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/HRD/v5653/pah_hrd_alg.c b/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/HRD/v5653/pah_hrd_alg.c
new file mode 100644 (file)
index 0000000..3eba1cb
--- /dev/null
@@ -0,0 +1,315 @@
+// c\r
+#include <string.h>\r
+#include <stdint.h>\r
+#include <stdbool.h>\r
+#include <stdlib.h>\r
+#include <stdio.h>\r
+#include <string.h>\r
+\r
+#include "pah831x_config.h"\r
+#include "pah831x_main.h"\r
+#include "pah831x_comm.h"\r
+// motion algorithm\r
+//#include "hdppg_api.h"\r
+\r
+#if defined(ENABLE_PXI_ALG_HRD)\r
+#include "pah8series_api_c.h"\r
+#endif\r
+#ifndef ENABLE_PXI_ALG_HRD\r
+typedef struct {\r
+    uint8_t                     frame_count;\r
+    uint32_t                    time;\r
+    uint8_t                     touch_flag;\r
+    uint32_t                    nf_ppg_channel;\r
+    uint32_t                    nf_ppg_per_channel;\r
+    int32_t                     *ppg_data;\r
+    uint32_t                    nf_mems;\r
+    int16_t                     *mems_data;\r
+} pah8series_data_t;\r
+\r
+#endif\r
+\r
+\r
+typedef struct\r
+{\r
+     // pxialg\r
+    void*                pxialg_buffer;\r
+    pah8series_data_t    pxialg_data;\r
+    bool                pxialg_has_init;\r
+    uint64_t            last_report_time;\r
+    uint8_t*             ppg_dac_data;\r
+\r
+\r
+} main_hr_state_s;\r
+\r
+\r
+\r
+static bool need_log_header = true;\r
+static main_hr_state_s _state;\r
+\r
+static float myHR =0.0f;\r
+static int hr_trust_level = 0;\r
+static int16_t grade = 0; \r
+//int8_t alg_ch[3]    = {2, 1, 0};\r
+uint8_t pah8series_set_alg_ch_order(int8_t *alg_ch, int8_t ch_nr);\r
+\r
+static uint8_t log_data_en_hrd=0;\r
+/*============================================================================\r
+STATIC FUNCTION PROTOTYPES\r
+============================================================================*/\r
+\r
+\r
+static void log_pah8series_data_header(uint32_t ch_num, uint32_t ir_ch_num, uint32_t g_sensor_mode);\r
+static void log_pah8series_data(const pah8series_data_t *data);\r
+static bool hr_algorithm_process(pah8series_data_t *pxialg_data, uint32_t ch_num);\r
+static bool hr_algorithm_calculate(pah8series_data_t *pxialg_data, uint32_t ch_num);\r
+#if defined(ENABLE_PXI_ALG_HRD)\r
+static void algorithm_param_set(pah8series_param_idx_t param, float value);\r
+#endif\r
+static void log_pah8series_data_header(uint32_t ch_num, uint32_t ir_ch_num, uint32_t g_sensor_mode)\r
+{\r
+    //log pah8series data header\r
+    // (1)Using total channel numbers;\r
+    // (2)reserved;\r
+    // (3)reserved;\r
+    // (4)IR channel number;\r
+    // (5)MEMS mode 0:2G, 1:4G, 2:8G\r
+    //LOG_PRINT("PPG CH#, %d, %d, %d, %d, %d\n", ch_num, get_ppg_setting_version(), 0, ir_ch_num, g_sensor_mode);\r
+    //LOG_PRINT("PPG CH#, %d, %d, %d, %d\n", ch_num, 0, ir_ch_num, g_sensor_mode);\r
+    LOG_PRINT("PPG CH#, %d, %d, %d, %d, %d\n", ch_num, 0, 0, ir_ch_num, g_sensor_mode);\r
+}\r
+static void log_pah8series_data(const pah8series_data_t *pxialg_data)\r
+{\r
+    int i = 0;\r
+    uint32_t *ppg_data = (uint32_t *)pxialg_data->ppg_data;\r
+    \r
+    uint8_t *dac_data = _state.ppg_dac_data;\r
+    \r
+    int16_t *mems_data = pxialg_data->mems_data;\r
+    int data_num = pxialg_data->nf_ppg_channel * pxialg_data->nf_ppg_per_channel;\r
+    \r
+    LOG_PRINT("Frame Count, %d \n", pxialg_data->frame_count);\r
+    LOG_PRINT("Time, %d \n", pxialg_data->time);\r
+    LOG_PRINT("PPG, %d, %d, ", pxialg_data->touch_flag, data_num);\r
+    for (i = 0; i < data_num; ++i)\r
+    {\r
+        LOG_PRINT("%d, ", *ppg_data);\r
+        ppg_data++;\r
+    }\r
+    LOG_PRINT("\n");\r
+    LOG_PRINT("MEMS, %d, ", pxialg_data->nf_mems);\r
+    for (i = 0; i < (pxialg_data->nf_mems * 3); ++i)\r
+    {\r
+        LOG_PRINT("%d, ", *mems_data);\r
+        mems_data++;\r
+    }\r
+    LOG_PRINT("\n");\r
+    LOG_PRINT("DAC, %d, ", data_num);\r
+    for (i = 0; i < data_num; ++i)\r
+    {\r
+        LOG_PRINT("%d, ", *dac_data);\r
+        dac_data++;\r
+    }\r
+    LOG_PRINT("\n");\r
+\r
+}\r
+\r
+\r
+bool  report_fifo_data_hr(\r
+uint32_t ppg_timestamp,     \r
+uint32_t time_period, \r
+uint32_t *ppg_data,\r
+uint8_t *dac_data,\r
+uint32_t ppg_size,\r
+uint8_t ch_num,\r
+int16_t *acc_data,\r
+uint32_t acc_size, \r
+uint8_t *hr_out,\r
+uint8_t *hr_trust_level_out,\r
+uint8_t is_touched,\r
+uint8_t log_data_en   \r
+)\r
+{\r
+//    ALG_PRINT("time_period = %d  timestamp =%d \n", time_period , ppg_timestamp);\r
+    log_data_en_hrd = log_data_en ;\r
+    _state.pxialg_data.mems_data = acc_data ;\r
+    _state.pxialg_data.nf_mems =   acc_size  ;\r
+    _state.pxialg_data.touch_flag = is_touched<2 ? 1 : 0;\r
+    _state.pxialg_data.time = time_period;\r
+    _state.pxialg_data.ppg_data = (int32_t*)ppg_data;\r
+ \r
+    _state.pxialg_data.nf_ppg_channel = ch_num;\r
+    _state.pxialg_data.nf_ppg_per_channel = ppg_size;\r
+    ++_state.pxialg_data.frame_count;\r
+    \r
+    _state.ppg_dac_data = dac_data ;\r
+\r
+    //if(is_touched)\r
+    {\r
+        hr_algorithm_process(&_state.pxialg_data, _state.pxialg_data.nf_ppg_channel);\r
+        *hr_out = (uint8_t) myHR ;\r
+        *hr_trust_level_out = hr_trust_level ;\r
+    }\r
+    return true ;\r
+\r
+    \r
+}\r
+\r
+static bool hr_algorithm_process(pah8series_data_t *pxialg_data, uint32_t ch_num)\r
+{\r
+    if(log_data_en_hrd)\r
+    {\r
+        // log header\r
+        if (need_log_header)\r
+        {\r
+            need_log_header = false;\r
+            log_pah8series_data_header(ch_num, PPG_IR_CH_NUM, ALG_GSENSOR_MODE);\r
+        }\r
+        // log\r
+        log_pah8series_data(&_state.pxialg_data);  \r
+    }\r
+    // hr\r
+    \r
+    hr_algorithm_calculate(&_state.pxialg_data, ch_num);\r
+\r
+\r
+    return true;\r
+}\r
+static bool hr_algorithm_calculate(pah8series_data_t *pxialg_data, uint32_t ch_num)\r
+{\r
+    bool has_updated = false;\r
+    int8_t alg_ch[3]    = {2, 1, 0};\r
+#if defined(ENABLE_PXI_ALG_HRD)\r
+    uint8_t ret = 0;\r
+     // Initialize algorithm\r
+    if (!_state.pxialg_has_init)\r
+    {\r
+        \r
+        LOG_PRINT("VERSION= %d \n\r", pah8series_version());\r
+        int open_size = pah8series_query_open_size();\r
+        _state.pxialg_buffer = malloc(open_size); \r
+\r
+        LOG_PRINT("open_size= %d \n\r", open_size);\r
+        ret = pah8series_open(_state.pxialg_buffer);\r
+        if (ret != MSG_SUCCESS)\r
+        {\r
+            LOG_PRINT("pah8series_open fail \n\r");\r
+            return false;\r
+        }\r
+\r
+        //version = pah8series_version();\r
+        algorithm_param_set(PAH8SERIES_PARAM_IDX_GSENSOR_MODE, ALG_GSENSOR_MODE);\r
+        algorithm_param_set(PAH8SERIES_PARAM_IDX_PPG_CH_NUM, ch_num);\r
+        algorithm_param_set(PAH8SERIES_PARAM_IDX_HAS_IR_CH, PPG_IR_CH_NUM);\r
+        algorithm_param_set(PAH8SERIES_PARAM_IDX_SET_FLAG_LIMIT_HR_UB, 1); //v\r
+        algorithm_param_set(PAH8SERIES_PARAM_IDX_SET_LIMIT_HR_UB, 220);//v\r
+        algorithm_param_set(PAH8SERIES_PARAM_IDX_SET_FLAG_LIMIT_HR_LB, 1);//v\r
+        algorithm_param_set(PAH8SERIES_PARAM_IDX_SET_LIMIT_HR_LB, 110);//vv\r
+        algorithm_param_set(PAH8SERIES_PARAM_IDX_IS_8002, 0);\r
+        algorithm_param_set(PAH8SERIES_PARAM_IDX_SET_FALG_INIT_HR_LBUB_BY_SIG_QUAL, 1);\r
+        algorithm_param_set(PAH8SERIES_PARAM_IDX_SET_FLAG_PREDICTION_FEEDBACK, 1);\r
+        algorithm_param_set(PAH8SERIES_PARAM_IDX_SET_FLAG_PREDICTION_SMOOTH, 1);\r
+        algorithm_param_set(PAH8SERIES_PARAM_IDX_SET_SMOOTH_TRUST_LEVEL_TH, 1);\r
+        algorithm_param_set(PAH8SERIES_PARAM_IDX_SET_FLAG_SUPPORT_FFT120, 0);\r
+        algorithm_param_set(PAH8SERIES_PARAM_IDX_SET_IIR_LP_ALPHA_STATIC, 0.125f);\r
+        algorithm_param_set(PAH8SERIES_PARAM_IDX_SET_IIR_LP_MOTION_TO_STATIC_COUNT, 6);\r
+        algorithm_param_set(PAH8SERIES_PARAM_IDX_SET_FLAG_EN_CHANNEL_QUALITY, 1);\r
+\r
+        _state.pxialg_has_init = true;\r
+    }\r
+    uint32_t cal_start = pxi_get_tick_count();\r
+    // Calculate Heart Rate\r
+    ret = pah8series_entrance(pxialg_data);\r
+    uint32_t cal_end = pxi_get_tick_count();\r
+   \r
+    ALG_PRINT("hd_hr_cal_time = %d \n", cal_end-cal_start);\r
+    if (ret == MSG_HR_READY)\r
+    {\r
+        pah8series_get_hr(&myHR);\r
+        pah8series_get_hr_trust_level(&hr_trust_level);\r
+        pah8series_get_signal_grade(&grade);\r
+        \r
+        LOG_PRINT("myHR = %d, hr_trust_level = %d, grade = %d \n", (int)myHR, hr_trust_level, grade);\r
+    \r
+        has_updated = true;\r
+    }\r
+    else\r
+    {\r
+        switch (ret)\r
+        {\r
+            case MSG_SUCCESS:\r
+                ALG_PRINT("Algorithm entrance success. \n");\r
+                break;\r
+            case MSG_ALG_NOT_OPEN:\r
+                ALG_PRINT("Algorithm is not initialized. \n");\r
+                break;\r
+            case MSG_MEMS_LEN_TOO_SHORT:\r
+                ALG_PRINT("MEMS data length is shorter than PPG data length. \n");\r
+                break;\r
+            case MSG_NO_TOUCH:\r
+                ALG_PRINT("PPG is no touch. \n");\r
+                break;\r
+            case MSG_PPG_LEN_TOO_SHORT:\r
+                ALG_PRINT("PPG data length is too short. \n");\r
+                break;\r
+            case MSG_FRAME_LOSS:\r
+                ALG_PRINT("Frame count is not continuous. \n");\r
+                break;\r
+            default:\r
+                ALG_PRINT("Algorithm unhandle error = %d \n", ret);\r
+                break;\r
+        }\r
+    } \r
+    \r
+    \r
+\r
+#endif // ENABLE_PXI_ALG_HRD\r
+    return has_updated;\r
+}\r
+\r
+void hr_algorithm_close(void)\r
+{\r
+    \r
+#if defined(ENABLE_PXI_ALG_HRD)\r
+    if (_state.pxialg_has_init)\r
+    {\r
+        _state.pxialg_has_init = false;\r
+        pah8series_close();\r
+        free(_state.pxialg_buffer);\r
+        LOG_PRINT("_state.pxialg_buffer = 0x%x \n",_state.pxialg_buffer);\r
+        need_log_header = true;\r
+        myHR =0.0f;\r
+        hr_trust_level = 0 ;\r
+        _state.pxialg_data.frame_count = 0 ;\r
+        LOG_PRINT("hr_algorithm_close \n");\r
+    }\r
+#endif // ENABLE_PXI_ALG_HRD\r
+}\r
+void hr_algorithm_init(void)\r
+{\r
+#if defined(ENABLE_PXI_ALG_HRD)\r
+    if (_state.pxialg_has_init)\r
+    {\r
+        _state.pxialg_has_init = false;\r
+        pah8series_close();\r
+        free(_state.pxialg_buffer);\r
+        need_log_header = true;\r
+        myHR =0.0f;\r
+        hr_trust_level = 0 ;\r
+        _state.pxialg_data.frame_count = 0 ;\r
+        LOG_PRINT("hr_algorithm_init \n");\r
+    }\r
+#endif // ENABLE_PXI_ALG_HRD\r
+}\r
+#if defined(ENABLE_PXI_ALG_HRD)\r
+static void algorithm_param_set(pah8series_param_idx_t param, float value)\r
+{\r
+    pah8series_set_param(param, value);\r
+     //LOG_PRINT("Param[%02d] = %f \n", param, value);\r
+    LOG_PRINT("Param[%02d] = "LOG_FLOAT_MARKER" \n", param, LOG_FLOAT(value));\r
+}\r
+#endif // ENABLE_PXI_ALG_HRD\r
+\r
+\r
+\r
+\r
diff --git a/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/HRD/v5653/pah_hrd_alg.h b/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/HRD/v5653/pah_hrd_alg.h
new file mode 100644 (file)
index 0000000..7424cc6
--- /dev/null
@@ -0,0 +1,42 @@
+/*==============================================================================\r
+* Edit History\r
+* \r
+* This section contains comments describing changes made to the module. Notice\r
+* that changes are listed in reverse chronological order. Please use ISO format\r
+* for dates.\r
+* \r
+* when       who       what, where, why\r
+* ---------- ---       -----------------------------------------------------------\r
+* 2016-04-29 bell      Initial revision.\r
+==============================================================================*/\r
+\r
+#ifndef __pah_hrd_alg_h__\r
+#define __pah_hrd_alg_h__\r
+\r
+\r
+#include <stdbool.h>\r
+#include <stdint.h>\r
+#include <string.h>\r
+\r
+\r
+\r
+bool  report_fifo_data_hr(\r
+uint32_t ppg_timestamp,        \r
+uint32_t time_period, \r
+uint32_t *ppg_data,\r
+uint8_t *dac_data,\r
+uint32_t ppg_size,\r
+uint8_t ch_num,\r
+int16_t *acc_data,\r
+uint32_t acc_size, \r
+uint8_t *hr_out,\r
+uint8_t *hr_trust_level_out,\r
+uint8_t is_touched  ,\r
+uint8_t log_data_en \r
+);\r
+void hr_algorithm_init(void);\r
+void hr_algorithm_close(void);\r
+\r
+\r
+#endif  // header guard\r
+\r
diff --git a/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/HRD/v5653/test_library_HRD.c b/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/HRD/v5653/test_library_HRD.c
new file mode 100644 (file)
index 0000000..d1ae675
--- /dev/null
@@ -0,0 +1,196 @@
+// algorithm\r
+#include "pah8series_api_c.h"\r
+// testpattern\r
+#include "pah831x_testpattern_HRD.h"\r
+// platform\r
+#include <stdlib.h>\r
+\r
+#include <math.h>  \r
+// #include "nrf_delay.h"\r
+\r
+\r
+#include "pah831x_comm.h"\r
+\r
+\r
+#define array_szie(arr) (sizeof(arr) / sizeof(arr[0]))\r
+\r
+\r
+\r
+//============================================================================\r
+// PUBLIC FUNCTION DEFINITIONS\r
+//============================================================================\r
+// #define LOG_FLOAT_MARKER "%d.%03d"\r
+\r
+#define ALG_GSENSOR_MODE 3\r
+#define  PPG_IR_CH_NUM 0\r
+\r
+#define   log_printf ALG_PRINT\r
+\r
+#define  debug_printf ALG_PRINT\r
+/**\r
+ * @brief Macro for dissecting a float number into two numbers (integer and residuum).\r
+ */\r
+// #define LOG_FLOAT(val) (int32_t)(val),                                     \\r
+//                        (int32_t)(((val > 0) ? (val) - (int32_t)(val)       \\r
+//                        : (int32_t)(val) - (val))*1000)\r
+\r
+\r
+#if defined(ENABLE_PXI_ALG_HRD)\r
+static void algorithm_param_set(pah8series_param_idx_t param, float value)\r
+{\r
+    pah8series_set_param(param, value);\r
+    LOG_PRINT("Param[%02d] = %f \n", param, value);\r
+}\r
+#endif // ENABLE_PXI_ALG_HRD\r
+void test_library_HRD(void)\r
+{\r
+    int i               = 0;\r
+    int j               = 0;\r
+    uint8_t ret         = 0;\r
+    int     buffer_size = 0;\r
+    void *pBuffer       = NULL;\r
+    //int     time_s,time_e,time_c;\r
+    int     ch_num      = 1;\r
+    static float hr     = 0.0f;\r
+    pah8series_data_t   pxialg_data;\r
+\r
+    buffer_size = pah8series_query_open_size();\r
+    log_printf("buffer_size = %d  \n", buffer_size);\r
+\r
+    pBuffer = (void*)malloc(buffer_size);;\r
+\r
+   \r
+    if (!buffer_size)\r
+    {\r
+        log_printf("HRVGetMemorySize(), failed to get memory size \n");\r
+        return ;\r
+    }\r
+\r
+    ret = pah8series_open(pBuffer);\r
+\r
+    if(ret != MSG_SUCCESS)\r
+    {\r
+        log_printf("pah8series_open() failed, ret = %d \n", ret);\r
+        return ;\r
+    }\r
+\r
+    log_printf("pah8series_version = %d \n", pah8series_version());\r
+\r
+    algorithm_param_set(PAH8SERIES_PARAM_IDX_GSENSOR_MODE, ALG_GSENSOR_MODE);\r
+    algorithm_param_set(PAH8SERIES_PARAM_IDX_PPG_CH_NUM, ch_num);\r
+    algorithm_param_set(PAH8SERIES_PARAM_IDX_HAS_IR_CH, PPG_IR_CH_NUM);\r
+    algorithm_param_set(PAH8SERIES_PARAM_IDX_SET_FLAG_LIMIT_HR_UB, 1); //v\r
+    algorithm_param_set(PAH8SERIES_PARAM_IDX_SET_LIMIT_HR_UB, 220);//v\r
+    algorithm_param_set(PAH8SERIES_PARAM_IDX_SET_FLAG_LIMIT_HR_LB, 1);//v\r
+    algorithm_param_set(PAH8SERIES_PARAM_IDX_SET_LIMIT_HR_LB, 110);//vv\r
+    algorithm_param_set(PAH8SERIES_PARAM_IDX_IS_8002, 0);\r
+    algorithm_param_set(PAH8SERIES_PARAM_IDX_SET_FALG_INIT_HR_LBUB_BY_SIG_QUAL, 1);\r
+    algorithm_param_set(PAH8SERIES_PARAM_IDX_SET_FLAG_PREDICTION_FEEDBACK, 1);\r
+    algorithm_param_set(PAH8SERIES_PARAM_IDX_SET_FLAG_PREDICTION_SMOOTH, 1);\r
+    algorithm_param_set(PAH8SERIES_PARAM_IDX_SET_SMOOTH_TRUST_LEVEL_TH, 1);\r
+    algorithm_param_set(PAH8SERIES_PARAM_IDX_SET_FLAG_SUPPORT_FFT120, 0);\r
+    algorithm_param_set(PAH8SERIES_PARAM_IDX_SET_IIR_LP_ALPHA_STATIC, 0.125f);\r
+    algorithm_param_set(PAH8SERIES_PARAM_IDX_SET_IIR_LP_MOTION_TO_STATIC_COUNT, 6);\r
+    algorithm_param_set(PAH8SERIES_PARAM_IDX_SET_FLAG_EN_CHANNEL_QUALITY, 1);\r
+\r
+\r
+    log_printf("ARRAY_SIZE = %d\n",array_szie(PAH831x_rawdata_HRD));\r
+\r
+\r
+    for(i = 0; i < (array_szie(PAH831x_rawdata_HRD)); i ++)\r
+    {\r
+        uint32_t  touch_flag         = PAH831x_rawdata_HRD[i][0];                         \r
+        uint32_t  time               = duration_HRD[i];                          \r
+         int       ppg_count_per_ch   = PAH831x_rawdata_HRD[i][1];     \r
+        int       frame_number       = framenumbers_HRD[i]; \r
+        int       mems_number        = PAH831x_mems_HRD[i][0];          \r
+        int32_t   RAW_DATA_CH1 [20]  = {0};\r
+        int16_t   Mems_data_buf[100] = {0};\r
+\r
+        for (j=0;j<ppg_count_per_ch; j++)\r
+        {\r
+            uint32_t  green1 = PAH831x_rawdata_HRD[i][j+2];\r
+            RAW_DATA_CH1[j] = green1 ;\r
+        }\r
+\r
+         for (j=0;j<PAH831x_mems_HRD[i][0]; j++)\r
+        {\r
+            Mems_data_buf[j*3]  = PAH831x_mems_HRD[i][j*3+1];\r
+            Mems_data_buf[j*3+1]= PAH831x_mems_HRD[i][j*3+2];\r
+            Mems_data_buf[j*3+2]= PAH831x_mems_HRD[i][j*3+3]; \r
+        }\r
+\r
+        pxialg_data.touch_flag         = touch_flag;\r
+        pxialg_data.time               = time;\r
+        pxialg_data.ppg_data           = (int32_t*)RAW_DATA_CH1;\r
+        pxialg_data.nf_ppg_channel     = ch_num;\r
+        pxialg_data.nf_ppg_per_channel = ppg_count_per_ch;\r
+        pxialg_data.frame_count        = frame_number;\r
+        pxialg_data.nf_mems            = mems_number;\r
+        pxialg_data.mems_data          = Mems_data_buf;\r
+\r
+        ret = pah8series_entrance(&pxialg_data); \r
+\r
+        //log_printf("ret = %d\n", ret);\r
+\r
+        if (ret == MSG_HR_READY)\r
+        {\r
+\r
+            int hr_trust_level = 0;\r
+            int16_t grade = 0;    \r
+            pah8series_get_hr(&hr);\r
+            pah8series_get_hr_trust_level(&hr_trust_level);\r
+            pah8series_get_signal_grade(&grade);\r
+            log_printf("hr = %d, hr_trust_level = %d, grade = %d \n", (int)hr, hr_trust_level, grade);\r
+          //  NRF_LOG_FLUSH();\r
+        }\r
+        else\r
+        {\r
+\r
+           switch (ret)\r
+           {\r
+\r
+            case  MSG_SUCCESS:\r
+                debug_printf("Algorithm entrance success. \n");\r
+\r
+            break;\r
+            case  MSG_ALG_NOT_OPEN:\r
+                debug_printf("Algorithm is not initialized. \n");\r
+\r
+            break;\r
+            case MSG_MEMS_LEN_TOO_SHORT:\r
+                debug_printf("MEMS data length is shorter than PPG data length. \n");\r
+\r
+            break;\r
+            case MSG_NO_TOUCH:\r
+                debug_printf("PPG is no touch. \n");\r
+\r
+            break;\r
+            case MSG_PPG_LEN_TOO_SHORT:\r
+                //debug_printf("PPG data length is too short. \n");\r
+            break;\r
+            case MSG_FRAME_LOSS:\r
+                debug_printf("Frame count is not continuous. \n");\r
+\r
+            break;\r
+            default:\r
+                debug_printf("Algorithm unhandle error = %d \n", ret);\r
+            break;\r
+            }\r
+         } \r
+     }\r
+\r
+    nrf_delay_ms(50);\r
+    //NRF_LOG_FLUSH();\r
+    free(pBuffer);     \r
+    //return ;          \r
+}\r
+\r
+\r
+\r
+\r
+\r
+   \r
+\r
+   \r
+\r
diff --git a/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/RAW_ECG/hrv_api.h b/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/RAW_ECG/hrv_api.h
new file mode 100644 (file)
index 0000000..5eb1062
--- /dev/null
@@ -0,0 +1,36 @@
+#ifndef HRV_API_H_\r
+#define HRV_API_H_\r
+\r
+#if defined(WIN32) && !defined(PXIALG_STATIC_LIB)\r
+#   ifdef PXIALG_EXPORTS\r
+#       define PXIALG_API   __declspec(dllexport)\r
+#   else\r
+#       define PXIALG_API   __declspec(dllimport)\r
+#endif\r
+#else\r
+#   define PXIALG_API\r
+#endif // WIN32\r
+\r
+\r
+#ifdef __cplusplus\r
+extern "C"\r
+{\r
+#endif\r
+       //PXIALG_API int ATOReset(void);\r
+       PXIALG_API int PXINLMS_GetMemorySize(void *p_state,int enable_lhr, int test_seconds, int sampling_rate);\r
+       PXIALG_API int PXINLMS_GetStateSize(void);\r
+       PXIALG_API int PXINLMS_Open(void *p_state,void *p_buffer,int ECG_FS,int ECG_time);\r
+       PXIALG_API int PXINLMS_Reset(void *p_state,int ecg_fs);\r
+       PXIALG_API float PXINLMS_Process(void *p_state,int data_ready, int data);\r
+       PXIALG_API int PXINLMS_GetICountECG(void *p_state);\r
+       PXIALG_API int PXINLMS_Close(void *p_state,void *p_buffer);\r
+       PXIALG_API int PXINLMS_GetVersion(void);\r
+       PXIALG_API float PXINLMS_GetSGfilter(void *p_state);\r
+       PXIALG_API void PXINLMS_Update_Buffer_NLMS(void* p_state,float data);\r
+       PXIALG_API float PXINLMS_NLMS_Filter(void* p_state, float data);\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif /* HRV_API_H_ */\r
+\r
diff --git a/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/RAW_ECG/libecgdenoise_v7010_3.a b/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/RAW_ECG/libecgdenoise_v7010_3.a
new file mode 100644 (file)
index 0000000..fb542eb
Binary files /dev/null and b/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/RAW_ECG/libecgdenoise_v7010_3.a differ
diff --git a/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/RAW_ECG/libecgdenoise_v7010_5.a b/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/RAW_ECG/libecgdenoise_v7010_5.a
new file mode 100644 (file)
index 0000000..199725a
Binary files /dev/null and b/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/RAW_ECG/libecgdenoise_v7010_5.a differ
diff --git a/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/RAW_ECG/pah_ecg_raw.c b/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/RAW_ECG/pah_ecg_raw.c
new file mode 100644 (file)
index 0000000..ec9d5fa
--- /dev/null
@@ -0,0 +1,358 @@
+// c\r
+#include <string.h>\r
+#include <stdint.h>\r
+#include <stdbool.h>\r
+#include <stdlib.h>\r
+#include <stdio.h>\r
+#include <string.h>\r
+\r
+#include "pah831x_config.h"\r
+#include "pah831x_main.h"\r
+#include "pah831x_comm.h"\r
+\r
+\r
+\r
+#if defined(ENABLE_PXI_ALG_HRD)\r
+#include "pah8series_api_c.h"\r
+#endif\r
+\r
+#include "hrv_api.h"\r
+typedef struct {\r
+    uint8_t                     frame_count;\r
+    uint32_t                    time;\r
+    uint8_t                     touch_flag;\r
+    uint32_t                    nf_ppg_channel;\r
+    uint32_t                    nf_ecg_channel;\r
+    uint32_t                    nf_ppg_per_channel;\r
+    int32_t                     *ppg_data;\r
+    int32_t                     *ecg_data;    \r
+    uint32_t                    nf_mems;\r
+    int16_t                     *mems_data;\r
+} pah8series_data_ppg_ecg_t;\r
+\r
+typedef struct\r
+{\r
+     // pxialg\r
+    void*                        pxialg_buffer_filter;\r
+    void*                        pxialg_state_filter;\r
+    pah8series_data_ppg_ecg_t    pxialg_data;\r
+    bool                         pxialg_has_init;\r
+    uint64_t                     last_report_time;\r
+    uint8_t*                      ppg_dac_data;\r
+    uint8_t*                      ecg_tag_data;\r
+} main_ecg_state_s;\r
+\r
+static bool need_log_header = true;\r
+static main_ecg_state_s _state;\r
+\r
+float sg_filter = 0.0f;\r
+float ecg_filter_data_out[512]={0};\r
+\r
+/*============================================================================\r
+STATIC FUNCTION PROTOTYPES\r
+============================================================================*/\r
+\r
+static void log_pah8series_data_header(uint32_t ch_num, uint32_t ir_ch_num, uint32_t g_sensor_mode);\r
+static void log_pah8series_data(const pah8series_data_ppg_ecg_t *data);\r
+static bool Log_process(pah8series_data_ppg_ecg_t *pxialg_data, uint32_t ch_num);\r
+static bool Log_process_v2(pah8series_data_ppg_ecg_t *pxialg_data, uint32_t ppg_ch_num,uint32_t ecg_ch_num);\r
+\r
+static uint8_t ecg_filter(const uint32_t* ecg_data, uint16_t ecg_data_num);\r
+\r
+static void log_pah8series_data_header(uint32_t ch_num, uint32_t ir_ch_num, uint32_t g_sensor_mode)\r
+{\r
+    //log pah8series data header\r
+    LOG_PRINT("ECG CH#, %d, %d, %d, %d\n", \r
+                ch_num,   /*(1)Using total channel numbers;*/ \\r
+                     0,   /*(2)reserved;*/ \\r
+             ir_ch_num,   /*(3)IR channel number;*/ \\r
+             g_sensor_mode/*(4)MEMS mode 0:2G, 1:4G, 2:8G*/ \\r
+            );\r
+\r
+}\r
+static void log_pah8series_data(const pah8series_data_ppg_ecg_t *pxialg_data)\r
+{\r
+    int i = 0;\r
+    uint32_t *ecg_data = (uint32_t *)pxialg_data->ppg_data;\r
+    \r
+    uint8_t *ecg_tag_data = _state.ecg_tag_data;\r
+    \r
+    int16_t *mems_data = pxialg_data->mems_data;\r
+    int data_num = pxialg_data->nf_ppg_channel * pxialg_data->nf_ppg_per_channel;\r
+    \r
+    LOG_PRINT("Frame Count, %d \n", pxialg_data->frame_count);\r
+    LOG_PRINT("Time, %d \n", pxialg_data->time);\r
+    LOG_PRINT("ECG, %d, %d, ", pxialg_data->touch_flag, data_num);\r
+    for (i = 0; i < data_num; ++i)\r
+    {\r
+        LOG_PRINT("%d, ", *ecg_data);\r
+        ecg_data++;\r
+    }\r
+    LOG_PRINT("\n");\r
+    LOG_PRINT("MEMS, %d, ", pxialg_data->nf_mems);\r
+    for (i = 0; i < (pxialg_data->nf_mems * 3); ++i)\r
+    {\r
+        LOG_PRINT("%d, ", *mems_data);\r
+        mems_data++;\r
+    }\r
+    LOG_PRINT("\n");\r
+    LOG_PRINT("ECG_TAG,  %d, ",  data_num);\r
+    for (i = 0; i < data_num; ++i)\r
+    {\r
+        LOG_PRINT("%d, ", *ecg_tag_data);\r
+        ecg_tag_data++;\r
+    }\r
+    LOG_PRINT("\n");\r
+\r
+}\r
+\r
+static void log_pah8series_data_v2(const pah8series_data_ppg_ecg_t *pxialg_data)\r
+{\r
+    int i = 0;\r
+    \r
+    uint32_t *ppg_data = (uint32_t *)pxialg_data->ppg_data;\r
+    \r
+    uint8_t *ppg_dac_data = _state.ppg_dac_data;\r
+    \r
+    uint32_t *ecg_data = (uint32_t *)pxialg_data->ecg_data;\r
+    \r
+    uint8_t *ecg_tag_data = _state.ecg_tag_data;\r
+    \r
+    int16_t *mems_data = pxialg_data->mems_data;\r
+    int ppg_data_num = pxialg_data->nf_ppg_channel * pxialg_data->nf_ppg_per_channel;\r
+    int ecg_data_num = pxialg_data->nf_ecg_channel * pxialg_data->nf_ppg_per_channel;\r
+    \r
+    LOG_PRINT("Frame Count, %d \n", pxialg_data->frame_count);\r
+    LOG_PRINT("Time, %d \n", pxialg_data->time);\r
+    \r
+    LOG_PRINT("PPG, %d, %d, ", pxialg_data->touch_flag, ppg_data_num);\r
+    for (i = 0; i < ppg_data_num; ++i)\r
+    {\r
+        LOG_PRINT("%d, ", *ppg_data);\r
+        ppg_data++;\r
+    }\r
+    LOG_PRINT("\n");\r
+    LOG_PRINT("ECG, %d, %d, ", pxialg_data->touch_flag, ecg_data_num);\r
+    for (i = 0; i < ecg_data_num; ++i)\r
+    {\r
+        LOG_PRINT("%d, ", *ecg_data);\r
+        ecg_data++;\r
+    }\r
+    LOG_PRINT("\n");\r
+    LOG_PRINT("MEMS, %d, ", pxialg_data->nf_mems);\r
+    for (i = 0; i < (pxialg_data->nf_mems * 3); ++i)\r
+    {\r
+        LOG_PRINT("%d, ", *mems_data);\r
+        mems_data++;\r
+    }\r
+    LOG_PRINT("\n");\r
+    \r
+    LOG_PRINT("DAC,  %d, ",  ppg_data_num);\r
+    for (i = 0; i < ppg_data_num; ++i)\r
+    {\r
+        LOG_PRINT("%d, ", *ppg_dac_data);\r
+        ppg_dac_data++;\r
+    }\r
+    LOG_PRINT("\n");\r
+    \r
+    \r
+    LOG_PRINT("ECG_TAG,  %d, ",  ecg_data_num);\r
+    for (i = 0; i < ecg_data_num; ++i)\r
+    {\r
+        LOG_PRINT("%d, ", *ecg_tag_data);\r
+        ecg_tag_data++;\r
+    }\r
+    LOG_PRINT("\n");\r
+\r
+}\r
+\r
+\r
+bool  report_ecg_fifo_data(\r
+uint32_t ppg_timestamp,     \r
+uint32_t time_period, \r
+uint32_t *ppg_data,\r
+uint8_t  *tag_data,\r
+uint32_t ppg_size,\r
+uint8_t ch_num,\r
+int16_t *acc_data,\r
+uint8_t acc_size, \r
+uint8_t is_touched  \r
+)\r
+{\r
+//    ALG_PRINT("time_period = %d  timestamp =%d \n", time_period , ppg_timestamp);\r
+    \r
+    _state.pxialg_data.mems_data = acc_data ;\r
+    _state.pxialg_data.nf_mems =   acc_size  ;\r
+    _state.pxialg_data.touch_flag = is_touched<2 ? 1 : 0;\r
+    _state.pxialg_data.time = time_period;\r
+    _state.pxialg_data.ppg_data = (int32_t*)ppg_data;\r
+    \r
+    _state.pxialg_data.nf_ppg_channel = ch_num;\r
+    _state.pxialg_data.nf_ppg_per_channel = ppg_size;\r
+    ++_state.pxialg_data.frame_count;\r
+    _state.ecg_tag_data = tag_data;\r
+\r
+    Log_process(&_state.pxialg_data, _state.pxialg_data.nf_ppg_channel);\r
+    return true ;\r
+}\r
+\r
+\r
+bool  report_ppg_ecg_fifo_data(\r
+uint32_t ppg_timestamp,     \r
+uint32_t time_period, \r
+uint32_t *ppg_data,\r
+uint8_t  *dac_data,\r
+uint32_t *ecg_data,\r
+uint8_t  *tag_data,\r
+uint32_t ppg_size,\r
+uint8_t ppg_ch_num,\r
+uint8_t ecg_ch_num,\r
+int16_t *acc_data,\r
+uint8_t acc_size, \r
+uint8_t is_touched  \r
+)\r
+{\r
+//    ALG_PRINT("time_period = %d  timestamp =%d \n", time_period , ppg_timestamp);\r
+    \r
+    _state.pxialg_data.mems_data = acc_data ;\r
+    _state.pxialg_data.nf_mems =   acc_size  ;\r
+    _state.pxialg_data.touch_flag = is_touched<2 ? 1 : 0;\r
+    _state.pxialg_data.time = time_period;\r
+    _state.pxialg_data.ppg_data = (int32_t*)ppg_data;\r
+    _state.pxialg_data.ecg_data = (int32_t*)ecg_data;\r
+    \r
+    _state.pxialg_data.nf_ppg_channel = ppg_ch_num;\r
+    _state.pxialg_data.nf_ecg_channel = ecg_ch_num;\r
+    _state.pxialg_data.nf_ppg_per_channel = ppg_size;\r
+    ++_state.pxialg_data.frame_count;\r
+    _state.ppg_dac_data = dac_data;\r
+    _state.ecg_tag_data = tag_data;\r
+\r
+    Log_process_v2(&_state.pxialg_data, _state.pxialg_data.nf_ppg_channel,_state.pxialg_data.nf_ecg_channel);\r
+    return true ;\r
+}\r
+\r
+\r
+static bool Log_process(pah8series_data_ppg_ecg_t *pxialg_data, uint32_t ch_num)\r
+{\r
+    // log header\r
+    if (need_log_header)\r
+    {\r
+        need_log_header = false;\r
+        log_pah8series_data_header(ch_num, PPG_IR_CH_NUM, ALG_GSENSOR_MODE);\r
+    }\r
+    // log\r
+    log_pah8series_data(&_state.pxialg_data);  \r
+\r
+    ecg_filter((const uint32_t*)pxialg_data->ppg_data, \\r
+               (pxialg_data->nf_ppg_channel * pxialg_data->nf_ppg_per_channel));\r
+    return true;\r
+}\r
+\r
+static bool Log_process_v2(pah8series_data_ppg_ecg_t *pxialg_data, uint32_t ppg_ch_num,uint32_t ecg_ch_num)\r
+{\r
+    // log header\r
+    if (need_log_header)\r
+    {\r
+        need_log_header = false;\r
+         LOG_PRINT("ECG CH#, %d, %d, %d, %d, %d\n", \r
+                ppg_ch_num,   /*(1)Using total channel numbers;*/ \\r
+                ecg_ch_num,   /*(2)reserved;*/ \\r
+                0,   /*(3)IR channel number;*/ \\r
+                0,   /*(3)IR channel number;*/ \\r
+                ALG_GSENSOR_MODE/*(4)MEMS mode 0:2G, 1:4G, 2:8G*/ \\r
+            );\r
+    }\r
+    // log\r
+    log_pah8series_data_v2(&_state.pxialg_data);  \r
+\r
+    ecg_filter((const uint32_t*)pxialg_data->ppg_data, \\r
+               (pxialg_data->nf_ppg_channel * pxialg_data->nf_ppg_per_channel));\r
+    return true;\r
+}\r
+\r
+\r
+static uint8_t ecg_filter(const uint32_t* ecg_data, uint16_t ecg_data_num)\r
+{\r
+#if defined(ENABLE_PXI_ALG_ECG)\r
+    uint8_t ret = 0;\r
+     // Initialize algorithm\r
+    if (!_state.pxialg_has_init)\r
+    {\r
+        int ecg_fl_state_size = 0;\r
+        int ecg_fl_buffer_size = 0;\r
+        \r
+        ecg_fl_state_size = PXINLMS_GetStateSize();\r
+        ALG_PRINT("ECG_Filter_state_query_open_size() = %d,\n", ecg_fl_state_size);\r
+        _state.pxialg_state_filter = (void *)malloc(ecg_fl_state_size);\r
+        if (!_state.pxialg_state_filter){\r
+            ALG_PRINT("ECG_Filter_state_size_not enough \n");\r
+              return false; }\r
+        ecg_fl_buffer_size = PXINLMS_GetMemorySize(_state.pxialg_state_filter, \\r
+                                                    1, \\r
+                                                    (int)30/*MEAS._time Sec.*/, \\r
+                                                    (int)256/*ECG_FS 256Hz*/);\r
+        ALG_PRINT("ECG_Filter_Buffer_query_open_size() = %d \n", ecg_fl_buffer_size);\r
+        _state.pxialg_buffer_filter = (unsigned char *)malloc(ecg_fl_buffer_size);\r
+                    \r
+        if (!_state.pxialg_buffer_filter){\r
+            ALG_PRINT("ECG_Filter_buffer_size_not enough \n");\r
+              return false; }\r
+        \r
+        LOG_PRINT("VERSION= %d \n\r", PXINLMS_GetVersion());        \r
+        PXINLMS_Open(_state.pxialg_state_filter, \\r
+                     _state.pxialg_buffer_filter, \\r
+                     (int)30/*MEAS._time Sec.*/, \\r
+                     (int)256/*ECG_FS 256Hz*/);        \r
+              \r
+        _state.pxialg_has_init = true;\r
+    }\r
+    //uint32_t cal_start = pxi_get_tick_count();\r
+    for(uint32_t i=0; i < ecg_data_num; i++){    \r
+        PXINLMS_Process(_state.pxialg_state_filter, 1, (int)ecg_data[i]);\r
+        sg_filter = PXINLMS_GetSGfilter(_state.pxialg_state_filter);\r
+        PXINLMS_Update_Buffer_NLMS(_state.pxialg_state_filter, sg_filter);\r
+        ecg_filter_data_out[i] = PXINLMS_NLMS_Filter(_state.pxialg_state_filter, sg_filter);\r
+    }\r
+    LOG_PRINT("ECG_filter,  %d, ", ecg_data_num);\r
+    for (uint32_t j = 0; j < ecg_data_num; ++j)\r
+    {\r
+        LOG_PRINT("%d, ", (int32_t)ecg_filter_data_out[j]);\r
+    }\r
+    LOG_PRINT("\n");\r
+#endif // ENABLE_PXI_ecg_filter\r
+    return 1;\r
+}\r
+\r
+void ecg_filter_close(void)\r
+{\r
+    \r
+#if defined(ENABLE_PXI_ALG_ECG)\r
+    if (_state.pxialg_has_init)\r
+    {\r
+        _state.pxialg_has_init = false;\r
+        free(_state.pxialg_buffer_filter);\r
+        free(_state.pxialg_state_filter);\r
+        //LOG_PRINT("_state.pxialg_buffer = 0x%x \n",_state.pxialg_buffer_filter);\r
+    need_log_header = true;\r
+    _state.pxialg_data.frame_count = 0 ;\r
+        LOG_PRINT("ecg_filter_close \n");\r
+    }\r
+#endif // ENABLE_PXI_ecg_filter\r
+}\r
+void ecg_filter_init(void)\r
+{\r
+#if defined(ENABLE_PXI_ALG_ECG)\r
+    if (_state.pxialg_has_init)\r
+    {\r
+        _state.pxialg_has_init = false;\r
+        free(_state.pxialg_buffer_filter);\r
+        free(_state.pxialg_state_filter);\r
+    need_log_header = true;\r
+    _state.pxialg_data.frame_count = 0 ;\r
+        LOG_PRINT("ecg_filter_init \n");\r
+    }\r
+#endif // ENABLE_PXI_ecg_filter\r
+}\r
+\r
+\r
diff --git a/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/RAW_ECG/pah_ecg_raw.h b/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/RAW_ECG/pah_ecg_raw.h
new file mode 100644 (file)
index 0000000..1736ab4
--- /dev/null
@@ -0,0 +1,51 @@
+/*==============================================================================\r
+* Edit History\r
+* \r
+* This section contains comments describing changes made to the module. Notice\r
+* that changes are listed in reverse chronological order. Please use ISO format\r
+* for dates.\r
+* \r
+* when       who       what, where, why\r
+* ---------- ---       -----------------------------------------------------------\r
+* 2016-04-29 bell      Initial revision.\r
+==============================================================================*/\r
+\r
+#ifndef ___pah_ecg_raw_h__\r
+#define ___pah_ecg_raw_h__\r
+\r
+\r
+#include <stdbool.h>\r
+#include <stdint.h>\r
+#include <string.h>\r
+\r
+bool  report_ecg_fifo_data(\r
+uint32_t ppg_timestamp, \r
+uint32_t time_period, \r
+uint32_t *ppg_data,\r
+uint8_t  *tag_data,\r
+uint16_t ppg_size,\r
+uint8_t ch_num,\r
+int16_t *acc_data,\r
+uint16_t acc_size, \r
+uint8_t is_touched  \r
+);\r
+\r
+bool  report_ppg_ecg_fifo_data(\r
+uint32_t ppg_timestamp,     \r
+uint32_t time_period, \r
+uint32_t *ppg_data,\r
+uint8_t  *dac_data,\r
+uint32_t *ecg_data,\r
+uint8_t  *tag_data,\r
+uint32_t ppg_size,\r
+uint8_t ppg_ch_num,\r
+uint8_t ecg_ch_num,\r
+int16_t *acc_data,\r
+uint8_t acc_size, \r
+uint8_t is_touched  \r
+);\r
+\r
+void ecg_filter_close(void);\r
+void ecg_filter_init(void);\r
+#endif  // header guard\r
+\r
diff --git a/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/RAW_PPG/pah_ppg_raw.c b/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/RAW_PPG/pah_ppg_raw.c
new file mode 100644 (file)
index 0000000..c3908d5
--- /dev/null
@@ -0,0 +1,156 @@
+// c\r
+#include <string.h>\r
+#include <stdint.h>\r
+#include <stdbool.h>\r
+#include <stdlib.h>\r
+#include <stdio.h>\r
+#include <string.h>\r
+\r
+#include "pah831x_config.h"\r
+#include "pah831x_main.h"\r
+#include "pah831x_comm.h"\r
+\r
+#if defined(ENABLE_PXI_ALG_HRD)\r
+#include "pah8series_api_c.h"\r
+#endif\r
+\r
+#ifndef ENABLE_PXI_ALG_HRD\r
+typedef struct {\r
+    uint8_t                     frame_count;\r
+    uint32_t                    time;\r
+    uint8_t                     touch_flag;\r
+    uint32_t                    nf_ppg_channel;\r
+    uint32_t                    nf_ppg_per_channel;\r
+    int32_t                     *ppg_data;\r
+    uint32_t                    nf_mems;\r
+    int16_t                     *mems_data;\r
+} pah8series_data_t;\r
+#endif\r
+\r
+typedef struct\r
+{\r
+     // pxialg\r
+    //void*                pxialg_buffer;\r
+    pah8series_data_t    pxialg_data;\r
+    bool                pxialg_has_init;\r
+    uint64_t            last_report_time;\r
+    uint8_t*             ppg_dac_data;\r
+} main_hr_state_s;\r
+\r
+static bool need_log_header = true;\r
+static main_hr_state_s _state;\r
+\r
+/*============================================================================\r
+STATIC FUNCTION PROTOTYPES\r
+============================================================================*/\r
+\r
+static void log_pah8series_data_header(uint32_t ch_num, uint32_t ir_ch_num, uint32_t g_sensor_mode);\r
+static void log_pah8series_data(const pah8series_data_t *data);\r
+static bool Log_process(pah8series_data_t *pxialg_data, uint32_t ch_num);\r
+\r
+static void log_pah8series_data_header(uint32_t ch_num, uint32_t ir_ch_num, uint32_t g_sensor_mode)\r
+{\r
+ //log pah8series data header\r
+    // (1)Using total channel numbers;\r
+    // (2)reserved;\r
+    // (3)reserved;\r
+    // (4)IR channel number;\r
+    // (5)MEMS mode 0:2G, 1:4G, 2:8G\r
+    //LOG_PRINT("PPG CH#, %d, %d, %d, %d, %d\n", ch_num, get_ppg_setting_version(), 0, ir_ch_num, g_sensor_mode);\r
+    //LOG_PRINT("PPG CH#, %d, %d, %d, %d\n", ch_num, 0, ir_ch_num, g_sensor_mode);\r
+    LOG_PRINT("PPG CH#, %d, %d, %d, %d, %d\n", ch_num, 0, 0, ir_ch_num, g_sensor_mode);\r
+}\r
+static void log_pah8series_data(const pah8series_data_t *pxialg_data)\r
+{\r
+    int i = 0;\r
+    uint32_t *ppg_data = (uint32_t *)pxialg_data->ppg_data;\r
+    \r
+    uint8_t *dac_data = _state.ppg_dac_data;\r
+    \r
+    int16_t *mems_data = pxialg_data->mems_data;\r
+    int data_num = pxialg_data->nf_ppg_channel * pxialg_data->nf_ppg_per_channel;\r
+    \r
+    LOG_PRINT("Frame Count, %d \n", pxialg_data->frame_count);\r
+    LOG_PRINT("Time, %d \n", pxialg_data->time);\r
+    LOG_PRINT("PPG, %d, %d, ", pxialg_data->touch_flag, data_num);\r
+    for (i = 0; i < data_num; ++i)\r
+    {\r
+        LOG_PRINT("%d, ", *ppg_data);\r
+        ppg_data++;\r
+    }\r
+    LOG_PRINT("\n");\r
+    LOG_PRINT("MEMS, %d, ", pxialg_data->nf_mems);\r
+    for (i = 0; i < (pxialg_data->nf_mems * 3); ++i)\r
+    {\r
+        LOG_PRINT("%d, ", *mems_data);\r
+        mems_data++;\r
+    }\r
+    LOG_PRINT("\n");\r
+    LOG_PRINT("DAC, %d, ", data_num);\r
+    for (i = 0; i < data_num; ++i)\r
+    {\r
+        LOG_PRINT("%d, ", *dac_data);\r
+        dac_data++;\r
+    }\r
+    LOG_PRINT("\n");\r
+\r
+}\r
+\r
+\r
+bool  report_ppg_fifo_data(\r
+uint32_t ppg_timestamp,     \r
+uint32_t time_period, \r
+uint32_t *ppg_data,\r
+uint8_t *dac_data,\r
+uint32_t ppg_size,\r
+uint8_t ch_num,\r
+int16_t *acc_data,\r
+uint8_t acc_size, \r
+uint8_t is_touched  \r
+)\r
+{\r
+//    ALG_PRINT("time_period = %d  timestamp =%d \n", time_period , ppg_timestamp);\r
+    \r
+    _state.pxialg_data.mems_data = acc_data ;\r
+    _state.pxialg_data.nf_mems =   acc_size  ;\r
+    _state.pxialg_data.touch_flag = is_touched<2 ? 1 : 0;\r
+    _state.pxialg_data.time = time_period;\r
+    _state.pxialg_data.ppg_data = (int32_t*)ppg_data;\r
+    \r
+    _state.pxialg_data.nf_ppg_channel = ch_num;\r
+    _state.pxialg_data.nf_ppg_per_channel = ppg_size;\r
+    ++_state.pxialg_data.frame_count;\r
+    \r
+    _state.ppg_dac_data = dac_data ;\r
+    \r
+    Log_process(&_state.pxialg_data, _state.pxialg_data.nf_ppg_channel);\r
+    return true ;\r
+}\r
+\r
+static bool Log_process(pah8series_data_t *pxialg_data, uint32_t ch_num)\r
+{\r
+    // log header\r
+    if (need_log_header)\r
+    {\r
+        need_log_header = false;\r
+        log_pah8series_data_header(ch_num, PPG_IR_CH_NUM, ALG_GSENSOR_MODE);\r
+    }\r
+    // log\r
+    log_pah8series_data(&_state.pxialg_data);  \r
+\r
+    return true;\r
+}\r
+\r
+void raw_ppg_close(void)\r
+{\r
+    need_log_header = true;\r
+    _state.pxialg_data.frame_count = 0 ;\r
+    LOG_PRINT("raw_ppg_close \n");\r
+\r
+}\r
+void raw_ppg_init(void)\r
+{\r
+    need_log_header = true;\r
+    _state.pxialg_data.frame_count = 0 ;\r
+    LOG_PRINT("raw_ppg_init \n");\r
+}\r
diff --git a/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/RAW_PPG/pah_ppg_raw.h b/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/RAW_PPG/pah_ppg_raw.h
new file mode 100644 (file)
index 0000000..5bc7a98
--- /dev/null
@@ -0,0 +1,36 @@
+/*==============================================================================\r
+* Edit History\r
+* \r
+* This section contains comments describing changes made to the module. Notice\r
+* that changes are listed in reverse chronological order. Please use ISO format\r
+* for dates.\r
+* \r
+* when       who       what, where, why\r
+* ---------- ---       -----------------------------------------------------------\r
+* 2016-04-29 bell      Initial revision.\r
+==============================================================================*/\r
+\r
+#ifndef ___pah_ppg_raw_h__\r
+#define ___pah_ppg_raw_h__\r
+\r
+\r
+#include <stdbool.h>\r
+#include <stdint.h>\r
+#include <string.h>\r
+\r
+bool  report_ppg_fifo_data(\r
+uint32_t ppg_timestamp,        \r
+uint32_t time_period, \r
+uint32_t *ppg_data,\r
+uint8_t *dac_data,\r
+uint32_t ppg_size,\r
+uint8_t ch_num,\r
+int16_t *acc_data,\r
+uint8_t acc_size, \r
+uint8_t is_touched  \r
+);\r
+void raw_ppg_init(void);\r
+void raw_ppg_close(void);\r
+\r
+#endif  // header guard\r
+\r
diff --git a/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/RR_HRV_STRESS_RRI/V3131/libhrv_v3131_0.a b/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/RR_HRV_STRESS_RRI/V3131/libhrv_v3131_0.a
new file mode 100644 (file)
index 0000000..b8987ab
Binary files /dev/null and b/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/RR_HRV_STRESS_RRI/V3131/libhrv_v3131_0.a differ
diff --git a/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/RR_HRV_STRESS_RRI/V3131/pah831X_testpattern_stress.h b/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/RR_HRV_STRESS_RRI/V3131/pah831X_testpattern_stress.h
new file mode 100644 (file)
index 0000000..78afde5
--- /dev/null
@@ -0,0 +1,231 @@
+#ifndef _PAH8112_TESTPATTERN_\r
+#define _PAH8112_TESTPATTERN_\r
+\r
+#include <stdint.h>\r
+#define NF_PPG_CHANNEL 2\r
+#define NF_PPG_PER_CHANNEL 35\r
+static const int32_t pah831x_rawdata_Stress[][NF_PPG_PER_CHANNEL*NF_PPG_CHANNEL] = \r
+{\r
+{1, 40, 471, 1174507, 0, 14639408, 0, 19509133, 0, 22987405, 280, 27889801, 16, 28351143, 361, 13933947, 221, 15917925, 0, 17468416, 0, 18143527, 0, 18613892, 0, 18970862, 0, 19353321, 0, 19791280, 0, 20162034, 0, 20413378, 0, 20677601, 0, 20934638, 0, 21154387, 0, 21330926},\r
+{1, 40, 0, 21506564, 0, 21676005, 0, 21867912, 14, 22067504, 0, 22262982, 0, 22448878, 0, 22511929, 0, 22541987, 0, 22600381, 0, 22652221, 0, 22763590, 0, 22870660, 0, 22983697, 0, 23134521, 0, 23267491, 30, 23412259, 0, 23563895, 0, 23678199, 52, 23821069, 0, 23950737},\r
+{1, 40, 0, 24119326, 14, 24234849, 0, 24308563, 0, 24324793, 0, 24299661, 0, 24403389, 0, 24490575, 0, 24632902, 0, 24738798, 0, 24848401, 0, 24951587, 0, 25083745, 0, 25192624, 0, 25305480, 0, 25409297, 0, 25499016, 0, 25637817, 0, 25691418, 0, 25703353, 0, 25693228},\r
+{1, 40, 0, 25669049, 0, 25707467, 0, 25783534, 0, 25808798, 0, 25835374, 0, 25890379, 0, 25919307, 0, 25977291, 0, 26053857, 2, 26156861, 0, 26517003, 10, 26567095, 0, 26643684, 0, 26546465, 0, 26400862, 0, 26345126, 0, 26299425, 0, 26305864, 0, 26309398, 0, 26291901},\r
+{1, 40, 0, 26336294, 0, 26337207, 0, 26399037, 0, 26431977, 67, 26499339, 0, 26568464, 0, 26673664, 12, 26564301, 0, 26353335, 0, 26170234, 6, 26082298, 0, 26034999, 0, 25974477, 0, 25978351, 0, 25962969, 0, 25964393, 0, 26001207, 0, 26040358, 0, 26077740, 0, 26127888},\r
+{1, 40, 0, 26200893, 0, 26211834, 30, 26059503, 0, 25796847, 0, 25589353, 24, 25488256, 0, 25418278, 0, 25343738, 0, 25243325, 0, 25238255, 0, 25206394, 0, 25234320, 0, 25202576, 0, 25223206, 0, 25284012, 0, 25291876, 18, 25277345, 40, 25040333, 0, 24684844, 0, 24458774},\r
+{1, 40, 6, 24264843, 0, 24158502, 0, 24068919, 0, 23924112, 0, 23836922, 0, 23821423, 0, 23785972, 0, 23788427, 0, 23797259, 0, 23764830, 0, 23799652, 0, 23728077, 10, 23488840, 0, 23146913, 0, 22962671, 38, 22767432, 0, 22673970, 0, 22579088, 0, 22510475, 0, 22426134},\r
+{1, 40, 0, 22403906, 0, 22396499, 0, 22409661, 0, 22418893, 0, 22439067, 0, 22471323, 0, 22395642, 0, 22177947, 10, 21951081, 0, 21872896, 18, 21832486, 0, 21793508, 0, 21744217, 0, 21719707, 0, 21718800, 0, 21741707, 0, 21804510, 0, 21844630, 0, 21900705, 0, 21977694},\r
+{1, 40, 0, 22067450, 0, 21987778, 20, 21862405, 0, 21755842, 0, 21732758, 0, 21716747, 0, 21758575, 0, 21815279, 0, 21874604, 0, 21919165, 0, 22037587, 0, 22132129, 0, 22250150, 0, 22377010, 0, 22474117, 0, 22584843, 0, 22648954, 0, 22635731, 34, 22610315, 0, 22611344},\r
+{1, 40, 0, 22684343, 0, 22759624, 0, 22837698, 0, 22925684, 0, 22982561, 0, 23095568, 0, 23228633, 0, 23342608, 0, 23483369, 0, 23589025, 0, 23699010, 0, 23812073, 2, 23894594, 0, 23905764, 0, 23979052, 12, 24014892, 8, 24115077, 0, 24191844, 0, 24265700, 0, 24381495},\r
+{1, 40, 0, 24463220, 0, 24589273, 0, 24695218, 0, 24783604, 0, 24864528, 0, 24976562, 0, 25056690, 0, 25158182, 0, 25208848, 0, 25238995, 32, 25278374, 12, 25340032, 0, 25430299, 0, 25502107, 0, 25567872, 0, 25669081, 0, 25750461, 0, 25787731, 0, 25874576, 0, 25941537},\r
+{1, 40, 0, 26028672, 0, 26065602, 0, 26186646, 0, 26259589, 0, 26284210, 22, 26309225, 0, 26350258, 0, 26391913, 14, 26454544, 0, 26500535, 0, 26586757, 0, 26627216, 0, 26670013, 0, 26741593, 0, 26794189, 0, 26848840, 0, 26942642, 0, 26971197, 0, 27039693, 0, 27122443},\r
+{1, 40, 28, 27154409, 0, 27154242, 0, 27136745, 0, 27168144, 10, 27238756, 0, 27275798, 0, 27294831, 0, 27317682, 0, 27372276, 0, 27408862, 0, 27434278, 0, 27532466, 0, 27531269, 0, 27593388, 0, 27625015, 0, 27690440, 32, 27737967, 0, 27724288, 24, 27692833, 6, 27658640},\r
+{1, 40, 0, 27695282, 0, 27712038, 0, 27734377, 0, 27759510, 0, 27806235, 0, 27808573, 0, 27867497, 0, 27855760, 0, 27918336, 0, 27919471, 0, 27988596, 0, 28008832, 0, 28052140, 0, 27988658, 67, 27918619, 0, 27899297, 0, 27857981, 26, 27902664, 0, 27889497, 0, 27875250},\r
+{1, 40, 0, 27882601, 0, 27890181, 0, 27901634, 0, 27934630, 0, 27951554, 0, 28009288, 12, 28026896, 0, 28068608, 0, 28101893, 52, 27976403, 0, 27917133, 0, 27886363, 4, 27879067, 0, 27895707, 0, 27909498, 0, 27882941, 0, 27874454, 0, 27852171, 0, 27915881, 0, 27926939},\r
+{1, 40, 0, 27980109, 20, 27986777, 0, 28036585, 0, 28037437, 0, 28006605, 0, 27925854, 0, 27784242, 42, 27713858, 0, 27761218, 0, 27762643, 0, 27739275, 0, 27746114, 0, 27712434, 0, 27719162, 0, 27753811, 0, 27707080, 0, 27806297, 0, 27811027, 0, 27815924, 0, 27715172},\r
+{1, 40, 32, 27576576, 0, 27432225, 0, 27352503, 20, 27306457, 0, 27281268, 0, 27240859, 38, 27186098, 0, 27119248, 0, 27131614, 4, 27122610, 0, 27145121, 0, 27144097, 0, 27149968, 0, 27121758, 0, 26873288, 0, 26687910, 0, 26570228, 0, 26451639, 73, 26434253, 0, 26368717},\r
+{1, 40, 0, 26289847, 48, 26277309, 0, 26217132, 0, 26262210, 0, 26252237, 0, 26278795, 0, 26294182, 0, 26273836, 0, 26036652, 0, 25807104, 0, 25663666, 0, 25570148, 0, 25484382, 0, 25458170, 32, 25363283, 0, 25335813, 0, 25287373, 0, 25315188, 0, 25313764, 0, 25341629},\r
+{1, 40, 4, 25327382, 0, 25250220, 0, 25050818, 0, 24877178, 0, 24771294, 0, 24740580, 0, 24693960, 0, 24644385, 0, 24605117, 42, 24567674, 0, 24577424, 0, 24612296, 0, 24619080, 0, 24697611, 0, 24688662, 0, 24622725, 0, 24458774, 0, 24393010, 0, 24362746, 0, 24376709},\r
+{1, 40, 0, 24379904, 0, 24385541, 0, 24370615, 0, 24409082, 0, 24478491, 0, 24501570, 0, 24551835, 10, 24596396, 10, 24611500, 0, 24540265, 0, 24507898, 0, 24468118, 0, 24536848, 0, 24540722, 0, 24608478, 0, 24614522, 0, 24649110, 0, 24745705, 0, 24752829, 0, 24848912},\r
+{1, 40, 0, 24878486, 0, 24933598, 0, 24947044, 36, 24958102, 0, 24968130, 0, 24952342, 0, 25032982, 0, 25094472, 0, 25141487, 0, 25183315, 0, 25218137, 0, 25254605, 0, 25328634, 0, 25428418, 0, 25480737, 0, 25483013, 0, 25540518, 22, 25511963, 18, 25533222, 0, 25566903},\r
+{1, 40, 4, 25603884, 4, 25683667, 0, 25735357, 0, 25763511, 0, 25812574, 0, 25837250, 0, 25866829, 0, 25926093, 0, 25968779, 0, 26028672, 0, 26074779, 0, 26099166, 0, 26098025, 16, 26096261, 0, 26105666, 0, 26202657, 79, 26221178, 0, 26215763, 0, 26286998, 2, 26336523},\r
+{1, 40, 0, 26352651, 0, 26407301, 0, 26455513, 0, 26479788, 0, 26542191, 0, 26571481, 0, 26603280, 0, 26596274, 12, 26576495, 0, 26610120, 0, 26641352, 12, 26678733, 0, 26722103, 0, 26706771, 26, 26770482, 0, 26810774, 0, 26820635, 0, 26889477, 0, 26894263, 0, 26924065},\r
+{1, 40, 0, 26976267, 0, 26987325, 0, 26951819, 0, 26948173, 0, 26989946, 0, 27034167, 0, 27044708, 22, 27087794, 0, 27111101, 0, 27120562, 0, 27169341, 0, 27205470, 0, 27232428, 26, 27247983, 0, 27279326, 0, 27329024, 0, 27304292, 0, 27306685, 0, 27287819, 0, 27273627},\r
+{1, 40, 0, 27297051, 0, 27334038, 0, 27348229, 52, 27371364, 0, 27407154, 44, 27415418, 0, 27443110, 0, 27487276, 0, 27534920, 0, 27545232, 0, 27556630, 0, 27563469, 0, 27480153, 0, 27464598, 0, 27487905, 0, 27502892, 0, 27508079, 4, 27486135, 0, 27525632, 0, 27532410},\r
+{1, 40, 0, 27543863, 26, 27569168, 0, 27613618, 0, 27622110, 0, 27665764, 0, 27674028, 0, 27653453, 0, 27516571, 0, 27444079, 0, 27440890, 0, 27443339, 0, 27474281, 0, 27422313, 0, 27422425, 0, 27439922, 0, 27446928, 34, 27441686, 0, 27443912, 0, 27458042, 6, 27458270},\r
+{1, 40, 14, 27501924, 0, 27382761, 0, 27248500, 0, 27164955, 0, 27112470, 0, 27070580, 0, 27022486, 0, 27039126, 0, 26930164, 0, 26952503, 0, 26877790, 0, 26888392, 0, 26913808, 0, 26880701, 0, 26885943, 73, 26814992, 0, 26559059, 0, 26446224, 10, 26351109, 0, 26266084},\r
+{1, 40, 0, 26258565, 0, 26154562, 0, 26050159, 0, 26066287, 0, 26022689, 0, 26009071, 0, 25985992, 0, 25978184, 4, 26015510, 0, 25991117, 0, 25782372, 52, 25474181, 0, 25272559, 0, 25175051, 34, 25103649, 0, 25000158, 0, 24926586, 0, 24830731, 0, 24764800, 0, 24741487},\r
+{1, 40, 0, 24713677, 0, 24725192, 0, 24693392, 0, 24688489, 26, 24503680, 0, 24209563, 0, 23921892, 0, 23752236, 0, 23668240, 0, 23596833, 20, 23493342, 0, 23400281, 0, 23326196, 0, 23342269, 0, 23343638, 0, 23330359, 0, 23330187, 0, 23343293, 0, 23329958, 0, 23153808},\r
+{1, 40, 0, 22797634, 0, 22585984, 0, 22448356, 0, 22384016, 0, 22336205, 16, 22277849, 16, 22216870, 0, 22207354, 0, 22226732, 0, 22258988, 0, 22290955, 0, 22331814, 0, 22399003, 0, 22363503, 0, 22112868, 0, 21878021, 0, 21777552, 0, 21741078, 65, 21730309, 0, 21685687},\r
+{1, 40, 0, 21638561, 24, 21642379, 0, 21694063, 0, 21721761, 24, 21805250, 0, 21823198, 0, 21878422, 0, 21893353, 0, 21712300, 0, 21545216, 0, 21435286, 0, 21449305, 0, 21449472, 0, 21461837, 0, 21463835, 0, 21495919, 69, 21536550, 0, 21622032, 0, 21700847, 8, 21786957},\r
+{1, 40, 0, 21865772, 0, 21970170, 0, 21824166, 0, 21642095, 0, 21520422, 0, 21476886, 0, 21494210, 0, 21503443, 0, 21488684, 0, 21524813, 0, 21620435, 0, 21665285, 30, 21749286, 0, 21856823, 12, 21970454, 0, 22060838, 0, 22021915, 0, 21853857, 0, 21719769, 0, 21651895},\r
+{1, 40, 0, 21673037, 0, 21685003, 0, 21713157, 0, 21742447, 0, 21824740, 0, 21899620, 0, 21967549, 30, 22053259, 0, 22152531, 6, 22275567, 32, 22342817, 0, 22320762, 0, 22219553, 0, 22127232, 0, 22151390, 0, 22197554, 0, 22240523, 0, 22282123, 0, 22321101, 0, 22398263},\r
+{1, 40, 0, 22475024, 0, 22570824, 22, 22670380, 0, 22760820, 0, 22845106, 20, 22902778, 0, 22843681, 0, 22788457, 0, 22777972, 0, 22846586, 0, 22913947, 0, 22947456, 0, 23019091, 0, 23073229, 0, 23154777, 0, 23253821, 0, 23330298, 0, 23409686, 2, 23510611, 0, 23587600},\r
+{1, 40, 18, 23599738, 4, 23525197, 0, 23512375, 6, 23531865, 0, 23558706, 0, 23592275, 0, 23657182, 0, 23713658, 0, 23767112, 0, 23826153, 0, 23924797, 0, 23950157, 0, 24063165, 0, 24120609, 0, 24200503, 0, 24186657, 2, 24148702, 0, 24118099, 2, 24143571, 4, 24166255},\r
+{1, 40, 0, 24237434, 0, 24285245, 0, 24313856, 0, 24356196, 0, 24413751, 0, 24506017, 0, 24561235, 0, 24663073, 0, 24724279, 0, 24788730, 0, 24792553, 24, 24734881, 0, 24715503, 16, 24741036, 6, 24772546, 0, 24782408, 0, 24865892, 28, 24896038, 0, 24936158, 0, 24997648},\r
+{1, 40, 6, 25070480, 0, 25068427, 0, 25187589, 0, 25250220, 0, 25283272, 0, 25246230, 0, 25190494, 0, 25182118, 0, 25216940, 16, 25240075, 0, 25256030, 0, 25301509, 0, 25311938, 0, 25379979, 0, 25394342, 14, 25465633, 0, 25508947, 0, 25542338, 0, 25590383, 0, 25667884},\r
+{1, 40, 0, 25590895, 0, 25509971, 0, 25444891, 0, 25414116, 14, 25417138, 0, 25436226, 0, 25415084, 62, 25432069, 0, 25488428, 0, 25535104, 0, 25583482, 0, 25606166, 0, 25619956, 0, 25666176, 0, 25704013, 0, 25642011, 0, 25489797, 0, 25430244, 0, 25397303, 20, 25379355},\r
+{1, 40, 0, 25402323, 0, 25384770, 50, 25391949, 0, 25398500, 0, 25463012, 48, 25457597, 0, 25503415, 0, 25491561, 0, 25537441, 0, 25582630, 0, 25487916, 0, 25368581, 0, 25318778, 0, 25266404, 8, 25284980, 0, 25277629, 0, 25273527, 81, 25280934, 0, 25323336, 4, 25354223},\r
+{1, 40, 26, 25359354, 0, 25395083, 0, 25434635, 0, 25523077, 0, 25524218, 0, 25404883, 0, 25285949, 0, 25196994, 0, 25186220, 0, 25176080, 0, 25200695, 0, 25156018, 0, 25215744, 0, 25228393, 0, 25245434, 56, 25311365, 0, 25324933, 0, 25407220, 0, 25411667, 0, 25386134},\r
+{1, 40, 0, 25225204, 0, 25156190, 0, 25119031, 0, 25103137, 0, 25120345, 0, 25122170, 0, 25081477, 0, 25100343, 0, 25149523, 18, 25206394, 50, 25234949, 0, 25268569, 0, 25316212, 34, 25355247, 0, 25251756, 0, 25134419, 0, 25051392, 0, 25008651, 0, 25037540, 0, 25034752},\r
+{1, 40, 0, 25021128, 0, 25049449, 0, 25055321, 0, 25098802, 0, 25123990, 18, 25161549, 0, 25233920, 0, 25251244, 0, 25160292, 0, 25027968, 0, 24981236, 0, 24934566, 0, 24977419, 0, 24959983, 0, 24956560, 0, 24941289, 0, 25023410, 0, 25018562, 0, 25066262, 0, 25111685},\r
+{1, 40, 0, 25167304, 0, 25216539, 0, 25123366, 10, 24978671, 0, 24891252, 0, 24835294, 0, 24795742, 0, 24829250, 0, 24856147, 0, 24811926, 0, 24833296, 0, 24878035, 28, 24870338, 0, 24943627, 0, 24944194, 36, 25017538, 0, 25053211, 0, 24930292, 46, 24825149, 0, 24780755},\r
+{1, 40, 0, 24727017, 26, 24717952, 0, 24758188, 0, 24714418, 0, 24741092, 0, 24792097, 0, 24802921, 0, 24832217, 0, 24890685, 0, 24919518, 20, 24982038, 0, 24980780, 0, 24854784, 18, 24809705, 0, 24767304, 0, 24785714, 0, 24815860, 0, 24814831, 0, 24795853, 0, 24848567},\r
+{1, 40, 0, 24907269, 0, 24944706, 0, 25013893, 0, 25048709, 0, 25054297, 0, 25148666, 0, 25087521, 0, 25028251, 36, 24950633, 0, 24945446, 0, 24934733, 20, 24987108, 0, 24986534, 0, 24987620, 0, 25010470, 0, 25060452, 0, 25089630, 0, 25141030, 0, 25192893, 0, 25227085},\r
+{1, 40, 0, 25241104, 0, 25249652, 0, 25172034, 0, 25070196, 87, 25063696, 0, 25055376, 0, 25090086, 0, 25043695, 0, 25062388, 6, 25087009, 0, 25116182, 0, 25137842, 0, 25181039, 0, 25214658, 0, 25273583, 0, 25285209, 0, 25326241, 0, 25259792, 0, 25151688, 32, 25139723},\r
+{1, 40, 0, 25106955, 0, 25152601, 28, 25176537, 12, 25175340, 0, 25169352, 0, 25227764, 0, 25242980, 0, 25268001, 0, 25333420, 0, 25390981, 0, 25406653, 0, 25463924, 0, 25374280, 0, 25275353, 0, 25248000, 0, 25212666, 0, 25197167, 0, 25231872, 69, 25240420, 0, 25262130},\r
+{1, 40, 0, 25252841, 28, 25279910, 0, 25346816, 0, 25368926, 2, 25444151, 0, 25447001, 0, 25510711, 0, 25429220, 0, 25308688, 0, 25270394, 0, 25240247, 0, 25208336, 0, 25212210, 0, 25233352, 0, 25233808, 0, 25229645, 22, 25235177, 0, 25294102, 0, 25327782, 0, 25364368},\r
+{1, 40, 0, 25384253, 0, 25443750, 0, 25316157, 0, 25221782, 0, 25149696, 0, 25133506, 0, 25134480, 0, 25151348, 24, 25115330, 0, 25113277, 0, 25181551, 0, 25231643, 12, 25250448, 0, 25246686, 0, 25304019, 0, 25374052, 0, 25274440, 0, 25171862, 0, 25056289, 0, 24977135},\r
+{1, 40, 0, 25002323, 0, 24993035, 0, 24972176, 0, 24984431, 0, 24985338, 0, 25003920, 16, 25018278, 28, 25046316, 0, 25090765, 0, 25125643, 6, 25178701, 0, 25013832, 0, 24887835, 0, 24751632, 0, 24674470, 0, 24653673, 0, 24623070, 0, 24621473, 0, 24608478, 0, 24637712},\r
+{1, 40, 0, 24636349, 0, 24681483, 12, 24702397, 0, 24716416, 24, 24747531, 32, 24730774, 0, 24603291, 0, 24433753, 2, 24344114, 0, 24301657, 0, 24287465, 0, 24290944, 0, 24264442, 0, 24256751, 28, 24260569, 0, 24307812, 0, 24330952, 14, 24345594, 0, 24399788, 0, 24407028},\r
+{1, 40, 28, 24273107, 0, 24103741, 0, 24014836, 0, 24013412, 0, 24013868, 0, 24006633, 0, 23971472, 0, 23987372, 0, 24008342, 0, 24035584, 0, 24098838, 0, 24139926, 0, 24196630, 65, 24239371, 0, 24172009, 0, 24010790, 54, 23864731, 0, 23786262, 0, 23749047, 30, 23781871},\r
+{1, 40, 0, 23731211, 0, 23740098, 0, 23756571, 0, 23804210, 0, 23856356, 0, 23866329, 0, 23941097, 0, 23990160, 8, 24033413, 0, 23913288, 0, 23751613, 38, 23638550, 0, 23583499, 0, 23633419, 34, 23598085, 0, 23606294, 0, 23610056, 0, 23655418, 0, 23692171, 0, 23741295},\r
+{1, 40, 2, 23803586, 0, 23845698, 0, 23906905, 0, 23938932, 0, 23801817, 0, 23671941, 36, 23616495, 2, 23637292, 0, 23674167, 0, 23669548, 0, 23666982, 0, 23700719, 0, 23753661, 0, 23808712, 0, 23849177, 0, 23888723, 0, 23987995, 0, 23989476, 0, 23807404, 28, 23760556},\r
+{1, 40, 0, 23734344, 0, 23693885, 36, 23759476, 22, 23764318, 0, 23774803, 14, 23824896, 0, 23863819, 0, 23896420, 0, 23951009, 0, 24037632, 0, 24082198, 0, 24100151, 0, 24013184, 0, 23843077, 0, 23752525, 0, 23725968, 0, 23744773, 16, 23804438, 22, 23774464, 0, 23798739},\r
+{1, 40, 8, 23857608, 4, 23903142, 0, 23981673, 0, 23991017, 0, 24045100, 0, 24122490, 0, 24131945, 0, 24031476, 0, 23921318, 0, 23880520, 0, 23905419, 0, 23938187, 0, 23958989, 28, 23949812, 0, 24005264, 0, 24040937, 0, 24114337, 0, 24160211, 0, 24201588, 0, 24278238},\r
+{1, 40, 0, 24327986, 0, 24374544, 0, 24266724, 0, 24205122, 0, 24179645, 0, 24180157, 0, 24223471, 0, 24272595, 44, 24269573, 0, 24297839, 0, 24386454, 0, 24418827, 0, 24501231, 0, 24489833, 0, 24562604, 0, 24620560, 0, 24561920, 0, 24479059, 0, 24429083, 0, 24443558},\r
+{1, 40, 0, 24476783, 0, 24505844, 0, 24528528, 0, 24562721, 4, 24614750, 0, 24617711, 0, 24715675, 0, 24741832, 0, 24806800, 0, 24839908, 0, 24863270, 0, 24749128, 0, 24659083, 0, 24573718, 0, 24608250, 0, 24633666, 0, 24626376, 0, 24642960, 0, 24667575, 4, 24715558},\r
+{1, 40, 0, 24748043, 0, 24804402, 0, 24855067, 12, 24883049, 0, 24951947, 0, 24945107, 2, 24830502, 0, 24743201, 0, 24696353, 0, 24689747, 0, 24701028, 0, 24727240, 0, 24735048, 0, 24750664, 0, 24801497, 42, 24817625, 0, 24854784, 22, 24900997, 24, 24959070, 0, 24992751},\r
+{1, 40, 0, 24974686, 0, 24831360, 0, 24763831, 0, 24727129, 0, 24794829, 0, 24787706, 0, 24821899, 0, 24843954, 0, 24847771, 0, 24876154, 0, 24934450, 0, 24990925, 0, 25010643, 0, 25092992, 44, 25106098, 0, 25016798, 0, 24931316, 0, 24895298, 0, 24921744, 0, 24924532},\r
+{1, 40, 0, 24954512, 0, 24938952, 0, 24993435, 0, 24991894, 0, 25075951, 0, 25116928, 0, 25158182, 0, 25205426, 0, 25252953, 48, 25289828, 16, 25191012, 0, 25085523, 0, 25002724, 0, 25021701, 0, 25025458, 0, 25059194, 0, 25042270, 0, 25074927, 0, 25127129, 0, 25145878},\r
+{1, 40, 0, 25196877, 0, 25255691, 0, 25294786, 0, 25321856, 0, 25377586, 0, 25272676, 0, 25151916, 0, 25107066, 14, 25123194, 0, 25152317, 0, 25190722, 0, 25174372, 0, 25189242, 0, 25246002, 0, 25281563, 0, 25300313, 0, 25334845, 0, 25432180, 0, 25438964, 0, 25405796},\r
+{1, 40, 20, 25292505, 22, 25214714, 0, 25167076, 0, 25180009, 40, 25227425, 0, 25220474, 0, 25244121, 0, 25287546, 0, 25298944, 0, 25357701, 0, 25386251, 0, 25458682, 0, 25494071, 0, 25499653, 0, 25474409, 0, 25341345, 0, 25261562, 34, 25200584, 0, 25208676, 6, 25219673},\r
+{1, 40, 10, 25238878, 0, 25261618, 0, 25253353, 0, 25321967, 0, 25352058, 0, 25413431, 0, 25458793, 0, 25510995, 0, 25578585, 0, 25517835, 0, 25377018, 0, 25281391, 0, 25224976, 12, 25234604, 0, 25264523, 0, 25269081, 16, 25252502, 0, 25275236, 0, 25302533, 0, 25336787},\r
+{1, 40, 0, 25418562, 0, 25474070, 0, 25511340, 0, 25546612, 0, 25427678, 0, 25309200, 0, 25250905, 0, 25280879, 0, 25264640, 44, 25300825, 0, 25306011, 26, 25323392, 0, 25361062, 0, 25386651, 0, 25426765, 4, 25471732, 0, 25527808, 0, 25611408, 0, 25558294, 0, 25364825},\r
+{1, 40, 0, 25243892, 0, 25181718, 0, 25178473, 0, 25184857, 16, 25177789, 0, 25172546, 0, 25222411, 18, 25266632, 0, 25298660, 0, 25360150, 0, 25418162, 0, 25529972, 0, 25554081, 0, 25431496, 0, 25269253, 0, 25145878, 0, 25151744, 0, 25221726, 0, 25265435, 0, 25306295},\r
+{1, 40, 56, 25285270, 0, 25306752, 0, 25378955, 22, 25450134, 0, 25532710, 0, 25541999, 4, 25588385, 0, 25629645, 0, 25381921, 0, 25216656, 0, 25112765, 0, 25089458, 0, 25112364, 0, 25150091, 0, 25132710, 0, 25117440, 12, 25151860, 0, 25189069, 0, 25232495, 34, 25262870},\r
+{1, 40, 0, 25289939, 0, 25354278, 8, 25198475, 0, 24974686, 0, 24840648, 0, 24763770, 0, 24753001, 0, 24746390, 0, 24739038, 0, 24703365, 0, 24729293, 0, 24776364, 4, 24794089, 0, 24787422, 30, 24850966, 0, 24882593, 0, 24897636, 0, 24716360, 0, 24469943, 0, 24333629},\r
+{1, 40, 0, 24277609, 0, 24259372, 0, 24251392, 0, 24251336, 0, 24247346, 0, 24289858, 14, 24335621, 0, 24351866, 0, 24413979, 24, 24460710, 0, 24499350, 0, 24434098, 0, 24220505, 0, 24106418, 0, 24079916, 0, 24087268, 0, 24114053, 0, 24075870, 0, 24072793, 0, 24101459},\r
+{1, 40, 0, 24137360, 4, 24204549, 0, 24244212, 14, 24296815, 32, 24381785, 0, 24228769, 0, 24095816, 0, 24033018, 0, 23950669, 0, 23978423, 0, 23985263, 0, 23987823, 0, 23979503, 0, 24017402, 0, 24044243, 0, 24104364, 0, 24165910, 0, 24212813, 18, 24266440, 0, 24225007},\r
+{1, 40, 0, 24017458, 36, 23884393, 0, 23835158, 0, 23772182, 0, 23818802, 0, 23801761, 0, 23787058, 0, 23812986, 0, 23848264, 0, 23887070, 69, 23923884, 0, 24006060, 6, 24025839, 18, 24010963, 0, 23819258, 0, 23654221, 18, 23544459, 0, 23540468, 0, 23546852, 0, 23558138},       \r
+};\r
+static const int16_t pah831x_mems_Stress[][3*NF_PPG_PER_CHANNEL] = \r
+{\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},      \r
+};\r
+static const uint32_t duration_Stress[] = \r
+{\r
+1269,\r
+1014,\r
+1013,\r
+1014,\r
+1013,\r
+1013,\r
+1014,\r
+1013,\r
+1013,\r
+1013,\r
+1013,\r
+1014,\r
+1013,\r
+1013,\r
+1014,\r
+1013,\r
+1014,\r
+1014,\r
+1013,\r
+1014,\r
+1013,\r
+1013,\r
+1014,\r
+1013,\r
+1014,\r
+1014,\r
+1014,\r
+1013,\r
+1014,\r
+1014,\r
+1013,\r
+1014,\r
+1013,\r
+1013,\r
+1014,\r
+1013,\r
+1014,\r
+1013,\r
+1013,\r
+1013,\r
+1013,\r
+1013,\r
+1014,\r
+1013,\r
+1014,\r
+1013,\r
+1014,\r
+1014,\r
+1013,\r
+1013,\r
+1014,\r
+1014,\r
+1013,\r
+1014,\r
+1013,\r
+1013,\r
+1014,\r
+1014,\r
+1014,\r
+1014,\r
+1013,\r
+1014,\r
+1014,\r
+1014,\r
+1014,\r
+1014,\r
+1014,\r
+1013,\r
+1013,\r
+1013,\r
+1013,  \r
+};\r
+\r
+\r
+#endif\r
diff --git a/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/RR_HRV_STRESS_RRI/V3131/pah831x_testpattern_HRV.h b/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/RR_HRV_STRESS_RRI/V3131/pah831x_testpattern_HRV.h
new file mode 100644 (file)
index 0000000..48aa532
--- /dev/null
@@ -0,0 +1,612 @@
+#ifndef _PAH831X_TESTPATTERN_\r
+#define _PAH831X_TESTPATTERN_\r
+\r
+#include <stdint.h>\r
+#define NF_PPG_CHANNEL 2\r
+#define NF_PPG_PER_CHANNEL 35\r
+static const int32_t pah831x_rawdata_HRV[][NF_PPG_PER_CHANNEL*NF_PPG_CHANNEL] = \r
+{\r
+{1, 40, 0, 9353191, 0, 15016962, 79, 15867246, 0, 16533658, 54, 16859270, 0, 17252557, 18, 17781157, 14, 18210933, 42, 18765749, 0, 19302248, 0, 19868099, 0, 20255174, 0, 20463511, 0, 20978791, 0, 21141341, 0, 21312477, 0, 21433326, 0, 21524684, 0, 21640597, 0, 21733397},\r
+{1, 40, 0, 21750741, 0, 21894788, 0, 21919778, 0, 22031761, 0, 22119445, 0, 22187690, 0, 22232780, 0, 22317802, 0, 22334144, 26, 22391334, 24, 22457045, 0, 22489113, 0, 22577894, 89, 22589862, 0, 22633117, 0, 22634035, 0, 22652953, 6, 22722944, 0, 22761570, 58, 22798485},\r
+{1, 40, 0, 22806306, 0, 22828501, 0, 22816226, 0, 22875776, 0, 22894126, 0, 22976699, 0, 23001821, 0, 23007722, 0, 23043025, 0, 23085666, 0, 23123545, 0, 23139669, 0, 23197209, 0, 23162210, 0, 23233297, 0, 23269077, 0, 23298350, 0, 23313032, 0, 23353271, 0, 23340339},\r
+{1, 40, 24, 23330244, 56, 23296998, 2, 23334702, 0, 23363712, 0, 23376469, 34, 23383940, 0, 23425493, 0, 23442269, 0, 23438818, 0, 23477047, 0, 23500288, 0, 23512874, 0, 23532795, 0, 23486353, 0, 23540923, 0, 23543018, 0, 23581248, 0, 23600691, 0, 23602700, 0, 23615675},\r
+{1, 40, 0, 23619784, 0, 23602875, 0, 23603357, 6, 23596279, 10, 23583347, 0, 23606984, 0, 23613580, 0, 23582647, 0, 23574169, 0, 23590336, 0, 23559795, 0, 23632977, 0, 23623104, 4, 23681386, 0, 23697292, 0, 23700437, 0, 23672170, 0, 23663385, 0, 23681169, 0, 23645559},\r
+{1, 40, 0, 23650060, 0, 23607069, 0, 23578235, 0, 23608554, 0, 23611221, 0, 23656396, 0, 23616725, 0, 23635161, 0, 23600776, 0, 23591692, 6, 23567398, 0, 23590860, 0, 23611571, 6, 23592213, 18, 23636211, 30, 23626862, 0, 23653294, 0, 23618342, 34, 23643204, 10, 23648618},\r
+{1, 40, 0, 23647133, 0, 23588066, 0, 23560409, 0, 23530261, 0, 23554073, 0, 23578628, 0, 23549486, 0, 23482419, 0, 23487010, 0, 23426321, 0, 23477747, 0, 23432657, 0, 23407274, 0, 23438685, 0, 23465335, 0, 23427456, 0, 23426410, 34, 23436544, 0, 23463808, 0, 23501644},\r
+{1, 40, 0, 23451968, 0, 23445546, 2, 23401984, 0, 23449041, 0, 23433834, 0, 23414570, 20, 23429120, 0, 23355716, 0, 23323430, 0, 23379178, 0, 23377386, 0, 23329809, 0, 23390540, 0, 23377433, 0, 23395387, 0, 23361092, 0, 23345015, 0, 23291404, 0, 23322295, 0, 23327406},\r
+{1, 40, 0, 23254660, 0, 23174400, 0, 23189474, 24, 23177024, 40, 23145873, 0, 23104409, 20, 23043374, 40, 23033454, 0, 23009514, 0, 23030528, 0, 22986487, 58, 23028868, 0, 23059319, 0, 23045209, 0, 23031313, 0, 22993783, 0, 22992516, 0, 23020390, 0, 22987319, 0, 23000819},\r
+{1, 40, 0, 22949525, 0, 22925145, 0, 22916450, 0, 22864068, 0, 22829508, 0, 22798574, 0, 22774805, 0, 22717354, 0, 22715912, 0, 22686246, 10, 22686028, 0, 22647227, 0, 22646182, 0, 22654353, 2, 22582613, 26, 22591304, 0, 22565440, 0, 22552200, 0, 22557184, 30, 22572475},\r
+{1, 40, 0, 22494792, 0, 22455253, 0, 22406451, 0, 22370884, 0, 22360533, 0, 22316492, 0, 22312209, 0, 22267251, 0, 22255893, 0, 22233698, 0, 22239466, 0, 22218316, 0, 22176550, 0, 22180744, 0, 22178427, 0, 22174498, 32, 22161740, 0, 22172313, 0, 22171089, 0, 22119010},\r
+{1, 40, 18, 22075579, 67, 22026867, 0, 22004672, 0, 21980552, 20, 21986188, 0, 21953335, 0, 21927688, 0, 21903876, 0, 21915456, 0, 21924454, 0, 21896405, 0, 21895227, 0, 21893043, 0, 21874952, 0, 21900731, 0, 21929740, 0, 21923404, 0, 21939136, 0, 21904486, 0, 21866346},\r
+{1, 40, 0, 21854331, 0, 21791940, 0, 21773764, 32, 21784076, 0, 21768652, 0, 21753753, 0, 21757730, 42, 21744844, 0, 21752490, 0, 21737591, 0, 21732347, 54, 21714086, 6, 21715874, 0, 21744930, 0, 21747639, 0, 21758912, 0, 21785868, 16, 21835673, 0, 21781717, 0, 21761881},\r
+{1, 40, 0, 21726186, 0, 21721907, 0, 21749081, 0, 21723345, 0, 21714871, 0, 21694336, 0, 21696170, 0, 21709277, 0, 21720465, 0, 21727321, 0, 21714432, 0, 21720243, 0, 21738858, 0, 21730248, 4, 21751223, 46, 21777216, 0, 21785083, 0, 21811473, 12, 21755677, 0, 21723869},\r
+{1, 40, 0, 21706218, 0, 21687475, 0, 21698397, 0, 21692586, 2, 21684330, 0, 21701896, 0, 21689484, 0, 21697830, 0, 21701371, 0, 21706308, 0, 21729245, 0, 21711244, 0, 21722602, 0, 21743795, 0, 21752008, 0, 21785736, 22, 21754500, 0, 21802163, 0, 21776823, 0, 21737459},\r
+{1, 40, 0, 21722342, 0, 21700189, 0, 21691584, 0, 21686340, 0, 21692851, 8, 21676992, 40, 21660343, 0, 21658073, 0, 21603153, 40, 21619844, 0, 21626572, 0, 21623645, 0, 21648418, 0, 21644006, 0, 21678869, 0, 21668996, 0, 21678169, 0, 21704298, 0, 21665062, 0, 21643481},\r
+{1, 40, 0, 21630549, 0, 21605034, 0, 21626880, 2, 21585809, 0, 21586508, 0, 21574054, 0, 21546619, 0, 21599965, 34, 21553826, 0, 21555400, 0, 21577681, 0, 21552384, 16, 21575671, 0, 21577245, 0, 21579515, 0, 21568507, 0, 21570999, 46, 21580083, 0, 21555835, 0, 21523157},\r
+{1, 40, 0, 21482393, 0, 21520708, 0, 21501704, 0, 21489689, 0, 21480209, 0, 21483310, 0, 21473915, 0, 21457489, 0, 21446523, 0, 21445299, 0, 21415150, 0, 21411353, 0, 21423671, 0, 21461248, 0, 21508040, 0, 21479424, 0, 21511534, 0, 21496068, 0, 21440145, 34, 21437960},\r
+{1, 40, 0, 21394444, 0, 21401390, 0, 21369408, 0, 21381422, 0, 21357525, 0, 21364386, 0, 21348262, 0, 21333670, 54, 21326242, 0, 21344853, 0, 21310690, 0, 21290632, 0, 21325717, 0, 21324364, 0, 21303129, 0, 21312874, 0, 21302254, 0, 21344550, 0, 21279057, 0, 21249783},\r
+{1, 40, 0, 21207534, 0, 21203908, 0, 21179835, 0, 21171707, 0, 21150954, 38, 21169523, 0, 21141166, 0, 21159040, 0, 21149077, 0, 21154538, 0, 21128366, 26, 21156458, 0, 21144098, 0, 21166860, 56, 21147242, 52, 21194077, 0, 21188181, 0, 21193028, 0, 21161834, 0, 21164061},\r
+{1, 40, 0, 21131076, 0, 21161920, 0, 21121288, 0, 21109580, 0, 21098790, 0, 21094549, 0, 21048938, 0, 21039283, 0, 21044612, 0, 21019008, 0, 21041595, 18, 21033079, 0, 21066325, 0, 21024733, 0, 21055534, 0, 21046886, 0, 21092497, 0, 21068556, 16, 21060428, 36, 21036266},\r
+{1, 40, 0, 20993275, 0, 20997512, 0, 20970163, 0, 20974489, 0, 20962082, 0, 20929314, 0, 20925990, 0, 20916160, 0, 20906679, 0, 20898163, 0, 20908078, 0, 20908168, 0, 20911048, 0, 20926515, 0, 20933290, 0, 20932940, 0, 20894489, 0, 20917691, 0, 20898948, 0, 20860676},\r
+{1, 40, 0, 20894796, 0, 20856132, 24, 20859669, 0, 20824674, 0, 20821879, 0, 20833672, 6, 20831752, 26, 20843942, 0, 20846301, 0, 20860326, 44, 20894929, 0, 20908736, 0, 20944298, 0, 20982092, 0, 20988599, 0, 21000529, 0, 21019182, 0, 21062438, 0, 21093764, 0, 21042909},\r
+{1, 40, 0, 21035174, 0, 20960682, 0, 20964352, 0, 20914632, 0, 20905719, 0, 20848093, 0, 20777574, 0, 20763464, 0, 20717324, 0, 20766476, 0, 20775654, 0, 20807850, 0, 20778316, 0, 20775304, 0, 20706884, 0, 20712955, 24, 20712213, 42, 20696571, 0, 20714222, 0, 20681105},\r
+{1, 40, 0, 20687398, 0, 20653056, 0, 20667080, 0, 20586427, 0, 20614434, 0, 20512110, 0, 20425297, 0, 20422502, 0, 20403541, 0, 20504857, 0, 20540074, 0, 20499003, 0, 20494417, 0, 20477986, 0, 20492142, 0, 20485981, 0, 20414506, 0, 20367799, 0, 20279850, 2, 20276531},\r
+{1, 40, 0, 20272729, 0, 20363127, 0, 20448366, 0, 20455223, 65, 20435959, 0, 20386193, 0, 20325158, 0, 20232797, 40, 20203481, 0, 20152712, 0, 20119854, 0, 20077521, 0, 20044795, 8, 20081800, 38, 20076381, 0, 20043571, 0, 19968512, 0, 19913984, 8, 19925038, 0, 19951121},\r
+{1, 40, 0, 19958681, 0, 19946184, 0, 19891835, 0, 19907822, 0, 19938363, 0, 19919227, 0, 19914205, 0, 19901269, 0, 19903718, 0, 19911756, 0, 19906163, 8, 19900526, 0, 19876147, 0, 19876454, 0, 19819524, 0, 19827520, 30, 19824768, 0, 19825075, 0, 19821666, 10, 19829051},\r
+{1, 40, 16, 19787938, 18, 19813670, 0, 19769280, 0, 19826909, 22, 19808384, 28, 19844693, 0, 19863389, 0, 19845870, 0, 19819438, 0, 19824332, 0, 19804846, 0, 19796151, 0, 19787630, 0, 19790340, 0, 19747741, 0, 19731840, 0, 19714888, 0, 19704358, 0, 19686182, 0, 19701866},\r
+{1, 40, 0, 19704183, 0, 19724061, 0, 19703744, 0, 19676744, 0, 19640567, 0, 19612390, 0, 19600942, 0, 19577958, 10, 19568085, 0, 19553275, 0, 19551965, 0, 19551658, 0, 19552618, 65, 19553975, 8, 19583594, 0, 19547639, 0, 19583552, 2, 19587963, 8, 19582766, 0, 19600768},\r
+{1, 40, 0, 19663680, 0, 19680896, 0, 19648435, 0, 19608716, 0, 19611993, 0, 19577437, 0, 19585779, 0, 19581457, 26, 19590280, 0, 19577480, 0, 19611515, 28, 19593600, 0, 19593339, 0, 19607278, 0, 19609898, 0, 19635195, 12, 19649877, 48, 19640439, 0, 19669708, 24, 19687667},\r
+{1, 40, 0, 19679453, 4, 19639697, 0, 19644808, 0, 19628467, 0, 19664861, 0, 19655509, 0, 19679193, 0, 19672200, 0, 19664294, 0, 19693960, 0, 19689766, 0, 19721920, 0, 19731447, 0, 19739396, 0, 19757836, 0, 19789030, 0, 19785971, 0, 19808123, 0, 19831628, 0, 19778325},\r
+{1, 40, 0, 19755345, 0, 19760891, 0, 19781252, 50, 19781602, 6, 19810308, 0, 19796283, 20, 19792832, 60, 19822280, 0, 19835997, 0, 19843729, 0, 19865139, 0, 19872960, 0, 19844953, 0, 19888512, 0, 19914466, 0, 19918310, 0, 19948851, 0, 19980262, 0, 19949243, 0, 19923729},\r
+{1, 40, 0, 19942340, 0, 19940590, 0, 19934259, 0, 19967202, 0, 19979694, 0, 19992716, 36, 19969514, 0, 19986073, 0, 20001587, 0, 19995251, 2, 20030156, 0, 20067468, 0, 20093073, 0, 20071227, 6, 20098491, 50, 20128375, 0, 20133661, 0, 20161928, 24, 20123699, 52, 20109414},\r
+{1, 40, 0, 20137198, 0, 20135846, 0, 20166737, 0, 20196403, 0, 20175035, 0, 20181286, 0, 20215714, 0, 20177962, 0, 20204049, 0, 20258180, 0, 20222395, 0, 20269060, 0, 20262724, 0, 20282734, 0, 20309209, 0, 20303880, 0, 20346129, 0, 20354214, 0, 20303880, 0, 20316462},\r
+{1, 40, 0, 20341410, 0, 20324590, 12, 20351415, 0, 20357316, 0, 20346568, 0, 20317512, 0, 20356134, 8, 20386457, 0, 20387767, 0, 20402709, 0, 20407820, 0, 20447099, 0, 20431458, 0, 20457890, 0, 20488341, 0, 20494370, 0, 20509184, 0, 20522291, 0, 20468027, 0, 20466935},\r
+{1, 40, 0, 20469597, 0, 20486681, 0, 20527837, 0, 20548330, 0, 20528887, 0, 20542651, 0, 20575987, 0, 20584942, 0, 20589051, 0, 20590361, 12, 20587562, 4, 20607705, 0, 20614566, 0, 20650786, 0, 20667255, 10, 20694169, 0, 20704960, 0, 20646766, 0, 20643357, 0, 20630033},\r
+{1, 40, 0, 20629418, 0, 20643618, 0, 20655155, 0, 20644232, 0, 20649386, 0, 20670357, 0, 20662058, 0, 20661009, 0, 20656989, 0, 20646370, 0, 20638813, 0, 20659042, 0, 20684646, 0, 20719466, 0, 20719684, 0, 20737378, 0, 20745766, 58, 20706841, 38, 20685081, 0, 20697228},\r
+{1, 40, 0, 20683857, 0, 20687876, 0, 20684381, 0, 20671889, 0, 20695479, 0, 20710638, 0, 20710293, 0, 20708369, 0, 20707451, 0, 20734365, 0, 20749568, 0, 20755029, 0, 20774122, 0, 20813312, 0, 20803921, 0, 20831709, 0, 20819648, 0, 20801604, 0, 20803136, 0, 20789678},\r
+{1, 40, 0, 20795357, 0, 20815628, 0, 20811217, 0, 20785702, 0, 20789329, 22, 20812091, 10, 20830485, 0, 20857267, 0, 20847219, 0, 20862464, 0, 20846869, 6, 20860019, 0, 20863603, 0, 20908428, 0, 20906551, 0, 20887633, 0, 20849096, 0, 20859712, 0, 20850713, 0, 20826901},\r
+{1, 40, 0, 20840140, 0, 20846387, 0, 20838041, 0, 20833369, 0, 20829696, 0, 20843153, 0, 20860718, 0, 20862685, 0, 20836949, 0, 20864648, 0, 20875703, 6, 20868189, 0, 20884398, 0, 20883131, 38, 20870634, 75, 20834811, 0, 20838523, 0, 20814233, 0, 20773990, 0, 20766958},\r
+{1, 40, 40, 20754201, 0, 20754112, 0, 20727462, 0, 20744674, 0, 20709111, 0, 20715490, 0, 20714922, 0, 20729429, 0, 20714880, 0, 20727022, 0, 20732138, 0, 20742097, 0, 20747605, 0, 20755643, 0, 20706009, 0, 20659434, 0, 20699281, 0, 20629550, 0, 20579566, 18, 20516087},\r
+{1, 40, 0, 20458457, 0, 20431368, 0, 20421888, 26, 20431808, 0, 20453303, 0, 20461474, 0, 20473314, 0, 20514163, 0, 20486071, 0, 20514427, 0, 20536358, 0, 20550775, 0, 20522333, 0, 20470562, 0, 20441463, 0, 20429708, 0, 20402577, 0, 20351680, 0, 20348403, 0, 20303052},\r
+{1, 40, 0, 20306154, 0, 20268053, 0, 20268842, 0, 20242803, 0, 20228646, 0, 20198020, 20, 20210777, 14, 20193604, 0, 20160401, 0, 20191987, 0, 20158173, 0, 20110592, 0, 20056418, 0, 20019891, 0, 19958549, 0, 19913066, 0, 19909397, 0, 19834905, 0, 19808823, 0, 19777015},\r
+{1, 40, 0, 19769454, 0, 19737429, 0, 19726988, 0, 19726553, 0, 19721966, 0, 19704618, 0, 19711564, 0, 19719825, 0, 19673467, 0, 19600110, 38, 19519850, 0, 19476859, 0, 19404117, 0, 19361211, 32, 19334557, 16, 19266359, 0, 19221009, 0, 19178363, 0, 19115187, 0, 19105881},\r
+{1, 40, 10, 19093341, 0, 19038293, 0, 19001898, 0, 18988441, 0, 18970705, 0, 18968823, 0, 18934178, 0, 18835089, 0, 18717909, 0, 18658666, 0, 18587669, 0, 18560230, 0, 18496004, 0, 18438813, 0, 18409015, 0, 18356411, 0, 18333431, 0, 18293235, 65, 18281309, 0, 18264443},\r
+{1, 40, 0, 18240763, 0, 18214984, 0, 18231982, 10, 18190037, 0, 18118954, 0, 18035242, 0, 17943274, 0, 17857595, 0, 17841561, 0, 17776157, 0, 17728490, 0, 17694587, 0, 17660945, 0, 17642726, 0, 17606724, 0, 17569326, 0, 17585753, 0, 17566660, 0, 17559931, 0, 17537258},\r
+{1, 40, 0, 17490158, 0, 17381849, 0, 17314653, 0, 17261785, 6, 17205602, 0, 17144477, 0, 17108343, 0, 17049843, 0, 17038963, 0, 17004535, 0, 16938389, 0, 16932838, 0, 16891729, 0, 16857561, 0, 16871761, 0, 16891904, 0, 16883950, 0, 16880631, 0, 16822476, 0, 16740078},\r
+{1, 40, 0, 16685290, 0, 16629713, 0, 16559155, 0, 16525469, 0, 16490560, 0, 16410999, 10, 16416938, 0, 16418952, 0, 16408200, 2, 16402611, 12, 16405580, 10, 16407547, 0, 16412791, 0, 16395490, 0, 16411609, 6, 16456832, 46, 16408115, 2, 16371810, 0, 16333623, 0, 16267212},\r
+{1, 40, 0, 16240605, 0, 16168994, 0, 16164364, 0, 16160256, 0, 16188484, 0, 16132556, 0, 16129062, 0, 16139157, 0, 16180138, 0, 16217885, 0, 16233484, 0, 16254980, 0, 16277875, 0, 16304874, 0, 16334848, 12, 16360930, 0, 16357346, 0, 16330649, 67, 16274641, 46, 16261883},\r
+{1, 40, 0, 16213606, 0, 16208622, 0, 16201676, 18, 16208490, 28, 16216576, 0, 16253188, 0, 16251003, 0, 16277875, 0, 16291724, 0, 16303782, 0, 16358088, 0, 16380548, 0, 16387144, 0, 16392780, 0, 16427383, 0, 16454033, 0, 16453030, 0, 16435029, 0, 16408772, 0, 16379409},\r
+{1, 40, 0, 16348390, 0, 16371763, 0, 16363072, 0, 16348872, 0, 16350182, 0, 16355554, 8, 16361757, 30, 16380108, 26, 16406323, 0, 16392341, 0, 16436514, 0, 16451195, 0, 16484356, 0, 16520443, 0, 16524552, 0, 16527304, 20, 16558805, 0, 16538837, 0, 16533683, 0, 16505066},\r
+{1, 40, 0, 16519351, 0, 16483874, 0, 16507293, 0, 16539669, 0, 16507426, 0, 16536652, 0, 16562517, 0, 16587682, 0, 16605947, 0, 16625826, 0, 16676595, 0, 16683848, 0, 16738547, 0, 16745710, 6, 16787788, 0, 16822169, 0, 16865907, 0, 16915276, 16, 16888669, 44, 16882073},\r
+{1, 40, 0, 16859306, 0, 16852492, 0, 16870493, 28, 16879057, 0, 16885917, 0, 16879539, 0, 16866082, 0, 16867874, 0, 16872546, 0, 16906496, 0, 16924450, 0, 16951628, 0, 16964778, 0, 16967965, 0, 17028872, 0, 17031449, 0, 17087155, 0, 17104588, 0, 17102054, 0, 17132330},\r
+{1, 40, 0, 17113851, 0, 17082304, 0, 17076625, 0, 17095543, 0, 17111099, 30, 17112452, 14, 17122022, 0, 17117303, 0, 17152955, 0, 17176810, 20, 17180390, 0, 17193062, 0, 17234261, 0, 17220454, 0, 17252744, 0, 17234568, 0, 17276160, 0, 17280704, 0, 17275289, 0, 17234218},\r
+{1, 40, 0, 17226355, 0, 17201625, 0, 17196731, 0, 17204770, 0, 17225390, 0, 17240204, 0, 17230417, 0, 17230459, 2, 17255799, 0, 17248418, 0, 17291626, 0, 17312686, 46, 17338858, 6, 17352925, 0, 17361578, 8, 17382984, 12, 17420164, 0, 17417369, 0, 17420296, 0, 17381107},\r
+{1, 40, 0, 17372279, 12, 17369966, 0, 17381499, 0, 17370577, 0, 17375731, 0, 17388710, 0, 17402513, 0, 17409288, 0, 17413218, 0, 17422613, 0, 17390587, 0, 17428377, 0, 17456166, 0, 17459050, 0, 17469973, 0, 17480196, 0, 17517683, 0, 17511479, 2, 17474082, 0, 17473860},\r
+{1, 40, 0, 17445286, 0, 17426850, 50, 17381806, 28, 17397141, 0, 17366425, 0, 17406839, 20, 17359611, 0, 17371712, 0, 17339293, 0, 17337373, 0, 17342485, 12, 17343752, 0, 17373678, 0, 17388795, 0, 17412650, 0, 17427332, 0, 17433186, 0, 17453239, 0, 17444544, 0, 17408371},\r
+{1, 40, 0, 17398190, 0, 17328635, 0, 17304081, 0, 17290056, 0, 17280618, 0, 17264712, 0, 17260608, 0, 17250077, 0, 17235221, 0, 17241164, 0, 17248328, 0, 17276206, 0, 17264145, 71, 17275724, 12, 17271223, 0, 17293158, 0, 17347857, 0, 17367650, 0, 17348774, 0, 17309192},\r
+{1, 40, 0, 17279483, 0, 17262353, 0, 17261700, 0, 17269828, 0, 17251302, 0, 17209403, 0, 17208614, 0, 17189610, 0, 17188211, 0, 17212548, 0, 17228450, 0, 17249203, 0, 17235793, 0, 17227182, 0, 17249817, 0, 17256499, 0, 17306218, 0, 17355592, 0, 17329113, 22, 17302941},\r
+{1, 40, 0, 17259648, 0, 17239987, 0, 17212680, 30, 17215692, 0, 17189303, 0, 17205294, 0, 17174276, 0, 17189085, 0, 17193147, 0, 17219976, 0, 17220236, 0, 17247283, 0, 17240115, 0, 17262792, 0, 17273540, 0, 17318933, 0, 17351573, 0, 17381149, 0, 17347899, 0, 17352793},\r
+{1, 40, 0, 17345412, 0, 17336192, 0, 17334272, 0, 17338201, 0, 17317888, 6, 17324834, 0, 17337373, 0, 17335624, 0, 17345715, 36, 17337241, 0, 17374813, 0, 17356377, 0, 17397141, 6, 17417194, 0, 17425715, 0, 17437337, 0, 17471633, 0, 17475959, 0, 17485525, 0, 17450747},\r
+{1, 40, 0, 17446600, 0, 17434585, 0, 17436898, 0, 17451362, 0, 17438297, 0, 17461934, 0, 17502084, 0, 17503833, 0, 17516066, 0, 17518033, 0, 17514099, 0, 17515848, 0, 17553817, 0, 17554077, 0, 17565657, 6, 17595541, 0, 17558186, 0, 17534852, 0, 17555520, 34, 17556612},\r
+{1, 40, 14, 17576533, 0, 17624068, 0, 17655398, 2, 17707562, 34, 17715690, 32, 17716343, 0, 17733516, 0, 17758549, 0, 17733819, 0, 17733209, 0, 17747541, 0, 17771874, 0, 17827276, 0, 17841083, 0, 17860480, 0, 17819980, 0, 17831121, 0, 17798485, 0, 17777992, 0, 17778560},\r
+{1, 40, 0, 17780962, 0, 17764275, 0, 17792627, 0, 17768162, 0, 17782971, 0, 17817924, 0, 17820548, 0, 17847982, 0, 17870835, 4, 17890756, 50, 17868518, 0, 17891805, 0, 17892637, 0, 17875464, 0, 17847462, 12, 17859037, 0, 17823778, 0, 17811852, 0, 17787908, 0, 17785070},\r
+{1, 40, 0, 17812160, 0, 17800797, 0, 17826137, 0, 17837806, 0, 17853269, 0, 17860697, 0, 17848640, 0, 17882065, 0, 17905612, 0, 17884817, 0, 17870528, 0, 17848290, 0, 17839991, 46, 17835272, 0, 17842304, 0, 17822340, 4, 17803946, 36, 17799052, 8, 17822950, 0, 17812070},\r
+{1, 40, 0, 17815697, 16, 17831645, 52, 17845405, 0, 17858688, 0, 17894429, 0, 17881147, 38, 17884467, 0, 17851566, 0, 17789832, 0, 17778692, 0, 17782446, 0, 17769736, 0, 17785288, 0, 17752913, 0, 17735876, 0, 17735701, 0, 17731857, 0, 17735829, 0, 17732817, 0, 17750161},\r
+{1, 40, 0, 17768337, 0, 17758417, 0, 17804689, 0, 17812987, 0, 17807048, 0, 17815086, 0, 17749768, 0, 17736396, 0, 17734609, 48, 17701708, 0, 17678028, 0, 17666666, 24, 17630668, 85, 17649497, 0, 17620181, 0, 17610786, 0, 17624418, 30, 17628394, 0, 17601962, 0, 17562901},\r
+{1, 40, 0, 17550668, 40, 17549969, 12, 17576358, 0, 17557222, 0, 17536341, 0, 17477661, 0, 17467613, 0, 17435413, 0, 17394124, 0, 17407453, 0, 17353493, 0, 17339161, 0, 17335449, 0, 17337501, 0, 17351176, 0, 17336934, 0, 17360264, 0, 17374071, 0, 17362841, 46, 17358647},\r
+{1, 40, 8, 17373593, 0, 17415577, 0, 17441617, 6, 17432921, 0, 17392204, 0, 17364198, 0, 17344755, 50, 17340168, 58, 17305651, 0, 17312947, 0, 17273672, 0, 17263492, 0, 17276642, 0, 17276509, 0, 17281096, 0, 17303291, 0, 17312686, 0, 17322777, 0, 17318323, 0, 17349256},\r
+{1, 40, 0, 17333350, 0, 17385911, 0, 17369309, 0, 17399718, 0, 17370141, 20, 17340125, 0, 17341478, 0, 17303816, 12, 17302681, 0, 17301457, 0, 17304648, 0, 17294336, 4, 17285248, 20, 17335799, 6, 17326711, 0, 17358212, 0, 17370269, 0, 17361749, 0, 17381585, 0, 17377173},\r
+{1, 40, 0, 17420339, 0, 17428599, 0, 17453632, 0, 17456123, 0, 17480110, 0, 17429341, 0, 17414924, 0, 17412868, 0, 17388620, 0, 17386261, 0, 17409681, 0, 17407496, 0, 17434628, 0, 17424883, 20, 17474124, 0, 17439914, 0, 17481420, 0, 17501431, 0, 17507852, 0, 17545557},\r
+{1, 40, 0, 17562555, 0, 17583436, 0, 17641634, 32, 17652074, 12, 17650722, 0, 17643818, 0, 17614284, 4, 17616686, 0, 17642594, 0, 17668108, 0, 17634862, 0, 17658018, 0, 17645870, 0, 17649937, 0, 17669333, 0, 17656443, 0, 17690611, 0, 17739063, 0, 17740505, 0, 17758724},\r
+{1, 40, 0, 17765585, 0, 17753480, 0, 17769689, 0, 17750378, 0, 17771481, 0, 17772616, 0, 17732160, 0, 17731157, 0, 17757632, 12, 17748369, 0, 17760473, 0, 17792759, 0, 17792849, 30, 17797960, 0, 17800098, 0, 17809493, 0, 17799530, 0, 17829329, 0, 17841126, 0, 17865156},\r
+{1, 40, 0, 17872145, 0, 17926233, 0, 17913693, 0, 17932309, 0, 17998323, 0, 17978359, 0, 17919769, 0, 17882414, 0, 17900893, 0, 17910549, 0, 17954457, 0, 17986833, 0, 17976870, 0, 18002167, 18, 17987050, 0, 18028646, 0, 18057045, 4, 18018248, 58, 18055513, 20, 18064908},\r
+{1, 40, 0, 18101085, 0, 18131797, 0, 18147613, 32, 18186542, 16, 18178594, 0, 18185757, 0, 18156919, 14, 18129442, 0, 18139140, 0, 18168631, 0, 18142984, 0, 18129920, 0, 18139315, 0, 18143159, 0, 18158011, 0, 18187460, 0, 18164480, 0, 18222502, 0, 18197290, 0, 18232285},\r
+{1, 40, 0, 18248409, 2, 18267502, 0, 18281612, 0, 18319974, 0, 18323601, 0, 18301013, 0, 18319014, 0, 18310233, 0, 18334173, 12, 18350080, 34, 18370961, 0, 18367991, 0, 18357986, 38, 18372710, 38, 18364846, 0, 18368034, 0, 18382890, 0, 18397132, 0, 18394163, 0, 18413559},\r
+{1, 40, 0, 18437414, 0, 18449211, 0, 18480059, 0, 18471974, 0, 18446545, 0, 18423872, 0, 18381184, 0, 18383325, 0, 18347630, 0, 18318446, 0, 18332032, 0, 18348023, 0, 18359735, 0, 18368384, 0, 18373538, 0, 18384900, 42, 18380356, 0, 18381316, 0, 18412074, 40, 18393420},\r
+{1, 40, 46, 18410065, 0, 18408273, 0, 18420855, 0, 18394513, 20, 18335398, 0, 18307084, 0, 18268160, 0, 18290965, 0, 18268812, 0, 18280520, 0, 18254745, 0, 18273881, 0, 18259332, 0, 18238446, 0, 18227131, 0, 18245657, 0, 18258850, 0, 18263790, 0, 18280392, 0, 18275848},\r
+{1, 40, 0, 18310451, 0, 18322026, 0, 18276066, 0, 18269905, 0, 18221235, 0, 18232375, 0, 18205678, 0, 18223377, 0, 18202709, 0, 18170598, 0, 18191611, 75, 18174702, 0, 18202577, 0, 18187332, 0, 18209655, 58, 18169856, 0, 18192093, 0, 18202052, 0, 18210005, 50, 18241156},\r
+{1, 40, 2, 18243690, 0, 18224337, 0, 18213371, 0, 18192268, 0, 18185975, 0, 18160768, 0, 18116202, 0, 18113536, 0, 18091690, 0, 18075174, 0, 18030088, 0, 18056520, 0, 18077755, 0, 18085051, 0, 18105629, 0, 18121224, 0, 18132194, 30, 18143377, 0, 18173393, 0, 18180864},\r
+{1, 40, 0, 18181563, 0, 18206468, 52, 18169331, 0, 18115938, 0, 18123584, 30, 18110391, 26, 18098726, 6, 18083084, 0, 18050274, 0, 18057920, 16, 18025804, 0, 18014182, 0, 17986397, 0, 17994521, 0, 17984913, 0, 17999155, 0, 18009728, 0, 18034500, 0, 18026069, 0, 18072554},\r
+{1, 40, 0, 18071462, 0, 18024145, 0, 17988932, 0, 17943232, 0, 17931042, 0, 17906965, 0, 17920644, 0, 17923571, 0, 17928900, 0, 17902771, 0, 17931959, 0, 17926016, 32, 17947033, 0, 17957824, 0, 17962935, 0, 17952012, 48, 17987097, 38, 17992512, 0, 18022570, 0, 18039394},\r
+{1, 40, 22, 18056388, 16, 18036902, 0, 18031705, 0, 18034500, 0, 18071330, 0, 18108774, 0, 18163912, 0, 18165789, 0, 18177454, 0, 18219268, 0, 18154039, 0, 18169941, 0, 18155959, 0, 18170641, 0, 18185582, 0, 18140057, 0, 18143027, 0, 18133764, 0, 18106675, 0, 18124283},\r
+{1, 40, 0, 18073864, 0, 18061892, 0, 18033715, 0, 18047475, 0, 18034982, 0, 18007061, 0, 18037777, 36, 18037777, 14, 18083170, 0, 18133981, 0, 18209305, 0, 18275366, 0, 18314252, 0, 18306299, 0, 18340202, 0, 18371660, 0, 18378649, 0, 18414609, 0, 18411724, 0, 18399667},\r
+{1, 40, 0, 18318007, 0, 18318532, 0, 18308919, 0, 18336708, 0, 18309401, 0, 18310493, 0, 18275148, 0, 18263569, 0, 18258675, 0, 18249894, 0, 18232115, 0, 18213149, 0, 18201966, 12, 18198907, 0, 18212322, 0, 18216558, 0, 18235912, 2, 18227396, 28, 18197815, 0, 18155349},\r
+{1, 40, 0, 18129570, 2, 18100736, 12, 18087104, 0, 18060057, 0, 18040878, 0, 18046690, 4, 18080460, 0, 18060147, 0, 18080507, 0, 18042278, 0, 18019908, 0, 17979669, 0, 18021742, 0, 18005883, 0, 18043281, 0, 18038301, 0, 18058180, 0, 18030088, 0, 17978969, 0, 17993736},\r
+{1, 40, 0, 17977659, 0, 18013832, 0, 18029696, 0, 17995835, 0, 18000029, 16, 18000115, 0, 18028078, 0, 17995093, 0, 18029781, 32, 18019865, 16, 18014097, 0, 18027289, 10, 18057262, 69, 18075046, 0, 18080290, 0, 18060454, 0, 18009595, 24, 18017284, 18, 18023402, 0, 18038037},\r
+{1, 40, 0, 18028381, 0, 18023795, 0, 18026811, 0, 18063556, 0, 18058005, 0, 18090905, 0, 18077056, 0, 18094225, 0, 18090641, 0, 18129570, 0, 18125815, 0, 18092872, 0, 18050402, 0, 18009463, 0, 17956949, 0, 17935671, 0, 17914218, 0, 17889710, 0, 17871577, 65, 17852966},\r
+{1, 40, 20, 17812770, 0, 17829636, 0, 17834222, 0, 17830553, 0, 17818056, 20, 17841561, 0, 17865809, 0, 17893947, 0, 17906837, 0, 17832345, 0, 17820373, 0, 17772488, 0, 17745442, 0, 17694630, 0, 17683750, 0, 17665796, 0, 17642201, 0, 17647095, 0, 17668633, 0, 17642376},\r
+{1, 40, 0, 17665399, 0, 17672652, 0, 17686766, 0, 17756932, 0, 17774626, 0, 17791974, 0, 17838417, 73, 17792149, 0, 17734737, 0, 17709312, 0, 17713634, 10, 17698867, 22, 17661030, 0, 17688776, 0, 17682483, 0, 17677939, 8, 17694673, 2, 17678336, 0, 17666321, 0, 17695197},\r
+{1, 40, 0, 17685017, 0, 17691396, 0, 17698039, 0, 17725474, 0, 17717785, 0, 17672260, 0, 17644953, 0, 17609608, 0, 17558357, 0, 17566924, 0, 17542805, 0, 17505885, 0, 17517597, 0, 17468356, 0, 17459357, 0, 17416362, 0, 17395438, 0, 17390545, 20, 17440524, 0, 17451929},\r
+{1, 40, 0, 17475217, 0, 17548091, 30, 17524804, 0, 17531575, 0, 17484829, 0, 17479761, 30, 17463112, 0, 17451840, 0, 17458961, 0, 17470058, 0, 17449437, 0, 17428467, 0, 17402120, 0, 17408499, 0, 17415709, 0, 17425582, 0, 17430301, 0, 17453107, 0, 17458483, 0, 17437422},\r
+{1, 40, 0, 17434538, 0, 17434363, 0, 17443409, 0, 17426457, 0, 17407846, 0, 17399411, 0, 17397533, 0, 17374161, 6, 17380714, 14, 17379840, 0, 17395566, 0, 17378180, 0, 17388403, 2, 17383684, 6, 17414092, 0, 17433011, 0, 17412390, 0, 17465779, 16, 17465472, 0, 17507985},\r
+{1, 40, 0, 17514666, 0, 17504401, 0, 17495752, 0, 17473075, 0, 17468748, 0, 17460403, 0, 17451229, 0, 17470890, 0, 17466606, 0, 17460053, 0, 17473075, 0, 17467046, 0, 17498982, 0, 17483255, 0, 17503133, 0, 17484565, 0, 17474517, 0, 17504051, 0, 17538393, 0, 17536076},\r
+{1, 40, 48, 17559146, 40, 17574306, 0, 17531840, 0, 17554734, 12, 17570547, 0, 17558404, 0, 17566353, 0, 17577233, 0, 17591782, 0, 17590907, 0, 17612450, 0, 17604932, 0, 17629137, 0, 17638489, 0, 17662737, 0, 17662080, 0, 17669725, 0, 17696640, 0, 17693713, 0, 17669550},\r
+{1, 40, 0, 17703458, 0, 17698299, 0, 17725696, 0, 17707255, 0, 17767112, 24, 17745484, 0, 17752388, 0, 17762308, 0, 17771746, 0, 17784371, 0, 17818188, 0, 17826312, 0, 17814212, 0, 17818713, 0, 17847982, 0, 17856285, 0, 17886301, 0, 17884599, 0, 17861964, 0, 17846673},\r
+{1, 40, 0, 17867643, 0, 17848640, 0, 17863146, 0, 17856896, 0, 17859127, 0, 17854668, 0, 17868868, 0, 17885077, 0, 17898709, 0, 17880840, 44, 17918062, 34, 17902903, 0, 17931259, 0, 17959965, 0, 17970363, 52, 17987315, 0, 18005401, 0, 18002606, 0, 17963195, 8, 17989674},\r
+{1, 40, 0, 17997580, 0, 17997230, 0, 17990894, 0, 17974557, 0, 18008721, 0, 17981414, 0, 18002167, 0, 18003349, 0, 18015496, 0, 18059447, 0, 18060104, 0, 18046600, 0, 18075131, 0, 18067835, 0, 18072204, 0, 18045380, 0, 18045337, 0, 18046033, 0, 18036292, 0, 18013004},\r
+{1, 40, 18, 18029256, 0, 18036727, 0, 18005094, 0, 18024755, 0, 18010252, 32, 18011080, 14, 18036642, 0, 18045555, 4, 18080290, 65, 18062592, 0, 18075699, 0, 18092740, 0, 18118822, 0, 18126336, 0, 18167232, 0, 18164962, 0, 18165704, 0, 18128435, 0, 18111044, 0, 18075349},\r
+{1, 40, 0, 18083827, 0, 18083520, 0, 18090248, 0, 18099293, 0, 18130402, 0, 18135381, 0, 18137698, 0, 18168017, 0, 18180206, 0, 18165265, 0, 18166272, 0, 18187242, 0, 18202274, 0, 18209523, 0, 18225864, 14, 18217958, 91, 18168806, 0, 18146961, 0, 18136341, 0, 18141802},\r
+{1, 40, 12, 18132369, 0, 18137783, 0, 18151765, 0, 18146043, 0, 18154299, 0, 18149145, 0, 18175052, 0, 18185147, 0, 18167364, 0, 18190562, 0, 18204283, 0, 18207820, 0, 18214417, 0, 18255005, 0, 18248499, 0, 18267153, 0, 18203669, 20, 18201049, 14, 18190126, 0, 18181824},\r
+{1, 40, 0, 18174442, 0, 18172957, 36, 18183048, 12, 18158536, 0, 18191001, 0, 18175662, 12, 18178986, 14, 18213196, 0, 18180906, 0, 18193928, 0, 18214464, 0, 18205768, 0, 18187067, 0, 18218961, 0, 18190562, 0, 18184055, 0, 18150848, 0, 18113710, 0, 18100693, 0, 18112708},\r
+{1, 40, 0, 18116420, 0, 18084437, 0, 18081335, 0, 18055253, 0, 18067310, 0, 18054860, 0, 18067925, 0, 18057045, 0, 18070284, 0, 18053111, 2, 18074828, 0, 18081685, 0, 18098594, 0, 18097937, 42, 18091212, 10, 18085094, 0, 18048614, 0, 18018248, 0, 17996053, 26, 17963545},\r
+{1, 40, 0, 17969006, 0, 17955114, 0, 17925755, 0, 17955072, 0, 17903688, 0, 17876953, 0, 17876996, 0, 17903688, 0, 17878523, 0, 17890188, 0, 17892987, 0, 17918020, 0, 17903735, 0, 17909064, 0, 17896217, 0, 17907187, 10, 17878348, 12, 17866030, 0, 17835575, 0, 17846848},\r
+{1, 40, 0, 17839816, 32, 17816264, 20, 17811067, 0, 17794158, 0, 17777382, 0, 17755754, 16, 17760081, 0, 17754837, 0, 17749636, 0, 17776290, 0, 17787037, 0, 17786120, 0, 17781486, 0, 17784896, 0, 17795161, 0, 17819148, 0, 17762350, 0, 17755054, 0, 17737578, 0, 17726656},\r
+{1, 40, 0, 17739413, 0, 17713459, 0, 17697032, 34, 17682530, 0, 17656618, 0, 17698692, 0, 17684539, 0, 17723464, 32, 17726131, 26, 17720802, 0, 17706295, 0, 17748108, 0, 17747234, 30, 17746841, 0, 17757896, 0, 17756014, 0, 17710489, 0, 17704985, 0, 17699042, 0, 17680081},\r
+{1, 40, 0, 17679906, 0, 17677504, 0, 17662297, 0, 17643554, 0, 17634513, 0, 17651332, 0, 17647138, 0, 17613410, 0, 17616076, 0, 17619089, 0, 17624243, 0, 17671910, 0, 17672260, 0, 17700966, 0, 17610918, 0, 17626299, 20, 17644736, 0, 17620445, 0, 17628526, 12, 17640934},\r
+{1, 40, 24, 17633681, 24, 17651549, 0, 17641369, 0, 17625335, 0, 17655790, 0, 17642376, 0, 17639014, 0, 17635298, 0, 17647880, 0, 17646963, 0, 17680345, 0, 17692185, 0, 17656576, 0, 17617954, 0, 17598028, 0, 17610308, 0, 17588637, 0, 17584878, 0, 17574916, 0, 17550318},\r
+{1, 40, 0, 17558489, 0, 17569369, 0, 17536908, 18, 17546956, 0, 17561331, 0, 17572864, 0, 17554427, 0, 17589248, 20, 17596019, 0, 17621141, 0, 17632371, 0, 17593484, 0, 17584878, 0, 17578282, 0, 17551236, 0, 17529958, 0, 17508945, 0, 17531400, 0, 17556087, 0, 17528081},\r
+{1, 40, 0, 17535466, 0, 17526464, 2, 17528605, 0, 17526596, 0, 17512264, 0, 17506278, 0, 17526246, 0, 17526246, 0, 17557222, 0, 17580727, 28, 17550886, 30, 17545207, 0, 17543680, 0, 17534199, 0, 17547831, 0, 17538525, 0, 17516808, 0, 17522184, 0, 17522141, 0, 17510562},\r
+{1, 40, 0, 17520174, 0, 17521049, 0, 17501038, 0, 17508812, 0, 17480588, 0, 17478011, 0, 17473117, 0, 17464861, 20, 17498589, 0, 17507110, 0, 17471283, 0, 17504358, 30, 17498329, 0, 17450005, 0, 17450837, 0, 17444241, 0, 17461495, 30, 17450794, 4, 17446293, 0, 17472593},\r
+{1, 40, 0, 17472332, 0, 17497540, 0, 17507153, 0, 17533806, 0, 17522141, 0, 17550365, 0, 17557222, 0, 17574741, 0, 17536994, 0, 17496797, 0, 17490419, 0, 17450837, 0, 17448610, 0, 17458483, 0, 17433710, 0, 17445201, 0, 17427767, 0, 17451929, 0, 17474867, 4, 17462852},\r
+{1, 40, 0, 17460842, 0, 17489373, 0, 17513664, 0, 17536384, 30, 17564215, 0, 17510737, 0, 17481203, 0, 17459268, 0, 17464686, 0, 17439522, 0, 17418986, 0, 17396876, 0, 17378747, 0, 17365201, 0, 17387443, 0, 17368132, 0, 17381892, 0, 17391854, 0, 17409241, 0, 17414135},\r
+{1, 40, 0, 17435852, 0, 17449655, 26, 17393122, 0, 17358822, 0, 17342613, 0, 17280878, 60, 17251737, 0, 17250820, 0, 17227532, 0, 17199441, 0, 17178077, 14, 17194112, 0, 17209403, 0, 17217570, 0, 17230852, 0, 17248810, 0, 17303906, 0, 17289489, 0, 17271005, 0, 17312204},\r
+{1, 40, 0, 17304733, 0, 17249642, 0, 17226965, 0, 17197516, 0, 17165405, 0, 17160947, 0, 17124859, 0, 17115596, 2, 17120755, 20, 17085145, 0, 17075315, 0, 17073873, 2, 17084795, 36, 17087244, 0, 17110310, 0, 17120273, 2, 17127219, 0, 17142993, 0, 17134080, 0, 17079684},\r
+{1, 40, 0, 17082611, 0, 17074965, 0, 17043289, 0, 17032281, 0, 17008426, 0, 17010739, 0, 17008644, 0, 16993088, 0, 16975044, 0, 16996672, 0, 17014148, 0, 17002048, 0, 17008819, 0, 17010564, 0, 17039052, 10, 17028782, 0, 17023628, 0, 16979545, 0, 16935897, 20, 16925367},\r
+{1, 40, 42, 16893649, 0, 16920738, 0, 16922265, 0, 16940224, 46, 16911168, 0, 16916061, 0, 16918464, 0, 16918685, 0, 16931746, 0, 16919078, 0, 16942058, 0, 16964296, 0, 16975918, 0, 16985442, 0, 17003793, 0, 16967790, 0, 16958400, 0, 16946385, 0, 16941751, 0, 16955383},\r
+{1, 40, 0, 16956125, 0, 16978888, 34, 16957610, 24, 16980202, 18, 16985881, 0, 17012138, 16, 17034244, 18, 17061858, 0, 17077414, 0, 17077107, 0, 17121058, 0, 17136789, 0, 17181657, 0, 17176985, 0, 17166715, 0, 17157192, 0, 17127308, 0, 17145702, 0, 17157452, 0, 17148757},\r
+{1, 40, 0, 17176896, 0, 17161561, 0, 17174101, 0, 17162129, 0, 17171741, 0, 17197256, 20, 17207961, 0, 17207961, 0, 17250777, 0, 17280750, 40, 17277952, 0, 17307835, 0, 17302464, 0, 17304691, 4, 17315178, 0, 17306568, 0, 17293725, 0, 17278826, 0, 17291323, 0, 17318408},\r
+{1, 40, 0, 17338069, 0, 17361531, 0, 17374114, 0, 17370662, 0, 17422045, 0, 17418547, 0, 17441006, 0, 17486839, 0, 17495355, 0, 17500164, 0, 17478318, 0, 17462109, 0, 17484258, 0, 17499946, 0, 17502698, 0, 17538393, 0, 17548526, 0, 17546956, 34, 17574348, 0, 17569719},\r
+{1, 40, 0, 17608123, 0, 17631018, 10, 17641984, 20, 17646438, 0, 17675844, 0, 17705595, 0, 17714901, 0, 17745749, 0, 17696115, 0, 17690393, 0, 17698649, 0, 17683707, 0, 17701141, 0, 17710139, 0, 17670557, 0, 17697864, 0, 17714683, 0, 17680213, 0, 17729932, 0, 17725081},\r
+{1, 40, 0, 17770432, 26, 17757107, 24, 17803989, 0, 17786816, 0, 17820198, 32, 17814254, 44, 17801237, 0, 17781836, 0, 17779609, 0, 17782404, 0, 17792802, 0, 17827712, 0, 17854451, 0, 17858163, 0, 17853708, 0, 17854101, 0, 17896174, 0, 17910988, 0, 17897399, 0, 17955025},\r
+{1, 40, 0, 17948296, 0, 17939997, 0, 17993693, 0, 17972676, 0, 17922129, 0, 17959441, 0, 17934754, 67, 17963810, 48, 17988057, 0, 17969881, 0, 17966344, 0, 17944627, 6, 17972458, 0, 17948561, 0, 17977745, 0, 17977702, 0, 18012787, 0, 18006933, 0, 18046775, 0, 18036424},\r
+{1, 40, 0, 18032622, 0, 18010730, 0, 18045290, 0, 18022660, 0, 18048567, 0, 18055820, 0, 18043281, 0, 18057437, 0, 18074432, 0, 18097416, 8, 18103620, 0, 18096277, 0, 18124108, 0, 18115938, 28, 18117337, 20, 18134114, 0, 18155084, 0, 18130926, 0, 18121049, 10, 18111219},\r
+{1, 40, 0, 18096977, 0, 18079368, 0, 18088328, 0, 18112183, 0, 18128520, 0, 18110873, 0, 18085836, 0, 18108292, 0, 18106897, 0, 18099293, 0, 18120482, 0, 18138005, 0, 18138090, 0, 18145301, 0, 18169506, 0, 18122406, 0, 18087014, 62, 18079543, 0, 18062242, 0, 18046254},\r
+{1, 40, 0, 18051059, 54, 18058965, 0, 18085401, 0, 18071462, 0, 18068842, 0, 18074696, 0, 18061632, 0, 18088064, 0, 18111569, 0, 18077755, 0, 18099776, 0, 18119304, 0, 18112051, 0, 18076748, 0, 18062199, 0, 18075874, 0, 18052633, 0, 18021132, 0, 18002739, 8, 18013879},\r
+{1, 40, 0, 17995136, 0, 17987575, 0, 18016891, 36, 18006276, 10, 18002956, 0, 18023402, 0, 18015624, 0, 18025629, 26, 18025501, 0, 18038912, 0, 18011869, 0, 17971191, 0, 17945066, 0, 17939340, 0, 17909806, 0, 17913390, 0, 17885294, 0, 17890931, 0, 17871795, 0, 17870792},\r
+{1, 40, 0, 17857860, 0, 17851131, 0, 17840384, 0, 17855628, 0, 17872452, 0, 17894775, 0, 17904128, 0, 17916142, 0, 17889314, 6, 17856328, 16, 17838152, 0, 17831163, 0, 17803549, 0, 17807658, 8, 17770129, 0, 17766370, 0, 17763878, 0, 17748718, 18, 17753830, 0, 17747059},\r
+{1, 40, 0, 17760123, 0, 17784238, 0, 17804556, 0, 17773230, 0, 17822600, 0, 17813030, 0, 17835272, 0, 17820458, 0, 17786513, 0, 17751910, 0, 17777382, 20, 17741947, 0, 17723161, 0, 17698257, 0, 17694980, 0, 17708569, 32, 17684014, 22, 17711449, 0, 17687377, 0, 17682265},\r
+{1, 40, 16, 17675886, 34, 17715473, 0, 17733691, 0, 17739763, 0, 17764928, 0, 17746449, 0, 17701051, 0, 17702493, 0, 17705685, 0, 17651289, 0, 17637397, 0, 17659720, 0, 17641851, 0, 17630229, 0, 17640674, 0, 17636433, 0, 17638314, 0, 17647052, 2, 17662647, 38, 17651899},\r
+{1, 40, 0, 17678553, 0, 17674094, 0, 17664396, 24, 17680738, 12, 17681041, 0, 17644300, 0, 17650457, 0, 17632021, 12, 17629751, 0, 17623675, 0, 17609651, 0, 17601480, 0, 17587630, 0, 17583044, 0, 17575748, 0, 17576230, 0, 17557529, 0, 17577625, 0, 17563251, 0, 17606549},\r
+{1, 40, 0, 17597026, 0, 17605896, 0, 17622933, 0, 17578065, 0, 17543330, 0, 17552896, 12, 17539046, 8, 17540928, 0, 17529216, 0, 17528998, 0, 17518165, 40, 17537258, 0, 17503091, 0, 17495355, 0, 17504665, 0, 17494263, 0, 17505143, 0, 17496494, 0, 17517772, 0, 17535249},\r
+{1, 40, 0, 17540228, 0, 17517550, 0, 17498764, 0, 17500599, 0, 17459793, 0, 17434013, 0, 17418594, 0, 17431611, 0, 17400810, 0, 17414528, 0, 17424055, 0, 17391547, 0, 17388403, 0, 17401070, 0, 17404962, 0, 17402820, 0, 17399283, 0, 17447820, 0, 17394781, 40, 17329113},\r
+{1, 40, 42, 17309845, 0, 17270698, 0, 17260915, 8, 17222378, 12, 17228889, 20, 17235178, 0, 17235003, 0, 17230024, 0, 17235443, 0, 17237802, 0, 17211191, 0, 17236535, 0, 17211980, 0, 17192277, 0, 17189828, 0, 17203370, 0, 17147579, 0, 17110400, 0, 17103189, 0, 17082700},\r
+{1, 40, 0, 17053559, 0, 17051417, 0, 17056964, 0, 17029747, 0, 16990075, 0, 16953463, 0, 16971724, 28, 16970414, 46, 16959667, 0, 16941184, 0, 16955515, 0, 16947912, 32, 16970500, 12, 16951104, 0, 16912435, 0, 16875212, 0, 16843754, 0, 16825446, 0, 16785646, 0, 16747110},\r
+{1, 40, 0, 16735402, 0, 16722380, 0, 16684633, 0, 16693414, 0, 16681792, 0, 16704686, 0, 16707481, 0, 16701060, 0, 16697258, 0, 16729024, 0, 16680307, 0, 16662745, 0, 16639543, 0, 16654882, 0, 16616213, 40, 16619622, 0, 16637273, 0, 16636881, 0, 16652172, 16, 16656192},\r
+{1, 40, 0, 16650163, 0, 16671219, 0, 16679522, 0, 16670344, 0, 16695074, 0, 16703462, 0, 16733960, 0, 16683758, 0, 16668774, 0, 16624733, 0, 16627618, 0, 16610926, 0, 16633472, 0, 16633557, 0, 16627968, 20, 16666547, 0, 16696605, 0, 16763451, 0, 16832746, 0, 16888320},\r
+{1, 40, 0, 16932360, 12, 16965870, 0, 16959317, 0, 16910425, 0, 16873335, 0, 16855944, 0, 16871496, 0, 16871061, 0, 16916061, 14, 16950404, 0, 16990775, 0, 16972424, 0, 16962726, 0, 16927509, 0, 16894958, 0, 16884211, 0, 16906406, 0, 16930875, 0, 17004185, 0, 17026598},\r
+{1, 40, 0, 17028740, 0, 17009693, 24, 16983129, 0, 16913749, 0, 16894656, 0, 16908680, 0, 16929651, 0, 16956347, 0, 16984482, 0, 17020044, 0, 17053730, 0, 17019259, 0, 17029875, 0, 16972206, 0, 16961544, 10, 16913792, 0, 16895790, 0, 16876130, 0, 16913617, 0, 16982604},\r
+{1, 40, 0, 16948744, 0, 16970065, 0, 16943150, 0, 16920520, 0, 16916761, 0, 16930133, 0, 16937032, 0, 16959010, 42, 16976051, 0, 17045563, 0, 17045998, 32, 17107690, 34, 17085188, 0, 17051153, 0, 17052334, 0, 17047573, 16, 17054997, 0, 17039488, 0, 17045606, 0, 17054080},\r
+{1, 40, 0, 17070114, 0, 17063650, 0, 17079684, 0, 17092006, 0, 17097860, 0, 17098777, 0, 17142860, 0, 17137792, 0, 17177420, 20, 17173009, 0, 17221721, 0, 17165013, 32, 17143517, 8, 17143210, 0, 17150506, 0, 17160819, 2, 17166673, 6, 17178862, 26, 17183406, 0, 17193979},\r
+{1, 40, 0, 17208661, 20, 17232601, 0, 17246276, 0, 17232908, 0, 17256238, 0, 17264277, 0, 17299144, 0, 17311901, 0, 17349299, 0, 17346504, 0, 17361924, 0, 17385386, 0, 17390323, 0, 17431261, 0, 17463287, 0, 17537779, 0, 17544857, 0, 17586453, 0, 17595234, 0, 17597768},\r
+{1, 40, 44, 17618521, 0, 17642116, 0, 17645128, 0, 17603579, 18, 17615726, 0, 17648887, 0, 17646745, 0, 17641809, 0, 17641198, 0, 17599645, 0, 17600260, 0, 17576665, 0, 17592264, 0, 17554820, 0, 17594184, 0, 17581559, 0, 17607424, 0, 17623590, 0, 17639709, 0, 17654698},\r
+{1, 40, 0, 17618914, 0, 17652599, 0, 17667805, 0, 17670690, 0, 17693973, 0, 17690961, 0, 17701226, 0, 17708829, 0, 17748761, 0, 17759163, 10, 17768204, 0, 17776157, 0, 17787430, 0, 17803025, 14, 17829068, 0, 17827451, 0, 17812595, 0, 17833608, 0, 17848947, 0, 17847065},\r
+{1, 40, 0, 17838984, 0, 17812420, 0, 17834747, 0, 17850517, 0, 17788480, 0, 17776418, 0, 17724778, 0, 17721937, 0, 17698342, 0, 17710532, 0, 17672042, 12, 17668155, 0, 17633113, 0, 17601305, 0, 17609083, 2, 17604279, 12, 17579507, 0, 17594624, 0, 17580992, 0, 17580292},\r
+{1, 40, 0, 17631061, 0, 17599995, 0, 17604979, 0, 17560541, 0, 17542630, 0, 17505757, 0, 17468096, 0, 17463726, 0, 17444676, 0, 17463027, 0, 17432576, 0, 17443844, 0, 17432661, 28, 17445461, 0, 17461585, 0, 17459093, 0, 17463769, 30, 17481378, 0, 17521092, 0, 17519825},\r
+{1, 40, 0, 17515933, 6, 17493303, 30, 17452014, 0, 17439082, 0, 17406489, 0, 17385476, 0, 17376823, 0, 17355242, 0, 17345237, 0, 17356160, 0, 17323127, 0, 17314956, 0, 17298530, 0, 17313646, 0, 17293418, 0, 17285687, 0, 17300932, 0, 17329945, 0, 17321774, 24, 17280226},\r
+{1, 40, 0, 17269303, 0, 17249770, 0, 17219584, 0, 17208921, 0, 17195464, 0, 17193497, 20, 17160469, 0, 17151163, 0, 17152256, 0, 17154743, 0, 17143035, 0, 17143517, 0, 17145309, 0, 17158459, 0, 17154615, 0, 17127833, 0, 17086805, 0, 17063910, 0, 17040755, 0, 17004360},\r
+{1, 40, 0, 16972642, 0, 16975483, 0, 16944810, 0, 16943411, 0, 16922833, 26, 16938389, 0, 16918728, 0, 16891072, 28, 16876305, 18, 16884428, 0, 16859306, 0, 16879189, 0, 16897800, 0, 16849698, 0, 16815180, 0, 16748467, 0, 16709056, 0, 16696430, 0, 16667767, 0, 16622634},\r
+{1, 40, 0, 16615560, 0, 16567893, 0, 16565269, 0, 16544341, 0, 16514807, 0, 16512665, 0, 16513233, 0, 16514850, 0, 16517909, 0, 16522760, 52, 16539754, 26, 16473476, 0, 16433062, 0, 16381158, 50, 16344849, 4, 16288925, 0, 16272588, 0, 16245107, 0, 16186692, 14, 16171750},\r
+{1, 40, 0, 16155319, 0, 16125610, 0, 16127052, 0, 16115302, 0, 16127488, 0, 16103287, 0, 16119931, 0, 16138807, 0, 16121809, 0, 16098521, 0, 16054702, 0, 16034035, 0, 16014899, 0, 16001531, 0, 15997465, 0, 15969459, 16, 15969984, 22, 15967756, 0, 15942024, 0, 15954649},\r
+{1, 40, 6, 15945954, 2, 15943726, 0, 15939968, 0, 15957316, 0, 15946478, 0, 15953774, 0, 15926818, 0, 15861981, 0, 15831880, 0, 15789806, 0, 15718502, 0, 15744017, 0, 15691413, 0, 15662011, 0, 15642043, 0, 15611153, 0, 15583978, 0, 15558592, 0, 15556979, 0, 15582446},\r
+{1, 40, 0, 15553305, 28, 15575022, 24, 15571131, 0, 15579434, 0, 15565320, 32, 15503543, 4, 15462472, 0, 15432763, 0, 15398378, 0, 15396590, 0, 15346781, 0, 15328870, 0, 15313578, 0, 15305011, 0, 15280810, 0, 15289766, 0, 15274777, 0, 15274909, 0, 15314146, 0, 15337911},\r
+{1, 40, 0, 15328298, 0, 15358404, 0, 15329437, 16, 15282163, 0, 15259225, 0, 15212343, 0, 15172236, 18, 15160004, 52, 15104256, 0, 15111854, 0, 15087697, 26, 15095735, 16, 15087257, 0, 15090926, 0, 15066811, 0, 15066154, 0, 15044356, 0, 15040512, 0, 15055453, 0, 15061785},\r
+{1, 40, 0, 15074457, 0, 15042214, 0, 14999308, 0, 14971827, 0, 14950988, 0, 14950856, 0, 14929710, 0, 14902536, 0, 14913284, 10, 14890257, 32, 14877499, 0, 14854737, 0, 14847180, 0, 14869026, 30, 14864657, 0, 14876014, 0, 14886587, 0, 14894016, 0, 14866359, 0, 14862690},\r
+{1, 40, 0, 14834901, 0, 14815022, 0, 14765085, 0, 14789461, 0, 14782515, 0, 14787234, 0, 14779195, 0, 14793745, 0, 14777536, 0, 14807769, 0, 14813538, 0, 14821794, 0, 14852859, 0, 14865399, 0, 14879991, 2, 14889689, 14, 14908518, 6, 14885670, 0, 14847658, 0, 14829307},\r
+{1, 40, 0, 14821794, 71, 14790818, 8, 14791735, 0, 14769233, 0, 14759577, 24, 14759360, 0, 14768755, 0, 14766003, 0, 14761809, 0, 14778888, 0, 14799513, 0, 14794269, 0, 14831714, 0, 14851852, 0, 14880951, 0, 14877017, 0, 14843507, 0, 14822929, 0, 14806634, 0, 14794577},\r
+{1, 40, 8, 14776051, 0, 14782340, 0, 14765563, 0, 14747912, 0, 14747827, 0, 14764778, 0, 14763076, 0, 14802265, 0, 14806284, 54, 14814980, 0, 14805934, 0, 14831406, 0, 14854694, 8, 14851942, 0, 14818385, 0, 14827822, 0, 14810043, 0, 14817600, 0, 14811613, 0, 14797589},\r
+{1, 40, 0, 14799598, 0, 14800123, 0, 14808994, 0, 14839095, 0, 14835643, 0, 14872695, 0, 14847790, 0, 14874790, 0, 14899912, 0, 14914504, 0, 14935825, 36, 14935957, 22, 14923157, 20, 14901269, 0, 14880426, 36, 14868629, 30, 14873045, 32, 14864260, 0, 14846173, 0, 14876714},\r
+{1, 40, 0, 14877892, 0, 14894190, 0, 14868326, 0, 14907515, 0, 14902272, 0, 14916078, 0, 14928136, 0, 14932855, 0, 14950374, 0, 14940023, 0, 14900437, 0, 14903931, 0, 14895543, 0, 14898909, 0, 14902664, 0, 14899955, 0, 14908565, 0, 14927219, 12, 14938009, 26, 14934604},\r
+{1, 40, 0, 14944652, 0, 14941508, 0, 14958592, 0, 14976810, 16, 14982446, 0, 15015735, 0, 15014993, 0, 14986116, 4, 14975104, 0, 14969860, 0, 14943778, 0, 14949764, 0, 14937442, 0, 14946094, 0, 14946355, 0, 14943342, 0, 14946969, 0, 14950899, 0, 14954308, 0, 14952473},\r
+{1, 40, 0, 14982225, 0, 14972962, 0, 14996121, 0, 15027665, 0, 14996556, 46, 14972091, 6, 14974361, 0, 14983317, 0, 14964313, 46, 14961911, 0, 14975061, 0, 14974929, 0, 14983581, 0, 14974404, 0, 14966890, 0, 14968725, 0, 14991662, 0, 14991705, 0, 15010406, 0, 15025873},\r
+{1, 40, 0, 15052305, 0, 15052744, 0, 15052305, 0, 15055671, 0, 15028057, 0, 15020979, 0, 14973358, 30, 14992012, 30, 14972352, 0, 14985241, 0, 14971652, 32, 14983142, 10, 14997341, 0, 14988343, 0, 15008661, 0, 14999526, 8, 15005384, 0, 14993937, 0, 15052394, 0, 15070745},\r
+{1, 40, 0, 15045798, 0, 15037977, 0, 15014075, 0, 15024780, 0, 14997781, 0, 15027447, 0, 15020544, 0, 14998698, 0, 15012590, 0, 14995464, 0, 15025873, 0, 15039680, 0, 15012765, 0, 15032076, 75, 15042649, 44, 15060693, 0, 15092458, 0, 15104123, 44, 15070873, 0, 15069171},\r
+{1, 40, 0, 15042649, 0, 15028014, 0, 15045226, 0, 15040379, 0, 15013640, 0, 14966148, 0, 14969642, 0, 14963221, 0, 14970606, 0, 14985241, 0, 15005512, 0, 15016435, 0, 15013158, 0, 15052087, 0, 15067596, 0, 15072448, 10, 15043306, 0, 15023428, 0, 14994939, 0, 14980872},\r
+{1, 40, 0, 14966062, 16, 14944217, 8, 14936614, 0, 14934515, 0, 14934080, 0, 14937792, 0, 14945134, 0, 14949806, 0, 14945570, 0, 14960251, 0, 14977463, 0, 14975146, 0, 15009096, 0, 15008921, 0, 14988650, 0, 14978730, 0, 14956710, 0, 14958852, 0, 14919923, 4, 14909307},\r
+{1, 40, 36, 14908740, 0, 14896900, 0, 14895108, 0, 14904674, 50, 14897510, 0, 14905681, 0, 14899912, 0, 14932945, 30, 14924509, 0, 14948104, 0, 14964096, 0, 14981265, 0, 14928179, 0, 14927526, 0, 14900305, 0, 14887897, 0, 14876582, 0, 14887462, 0, 14875925, 0, 14870510},\r
+{1, 40, 0, 14879816, 0, 14863957, 0, 14863910, 0, 14881608, 0, 14891831, 0, 14894626, 6, 14916910, 10, 14925559, 0, 14956232, 0, 14995682, 8, 14947972, 30, 14937706, 0, 14891438, 0, 14933248, 0, 14911142, 0, 14913326, 0, 14928968, 0, 14926566, 0, 14900569, 0, 14923067},\r
+{1, 40, 0, 14902839, 0, 14932770, 0, 14944435, 0, 14954700, 0, 14985066, 0, 14987426, 0, 15034653, 0, 15010274, 0, 14990267, 0, 14943995, 0, 14944738, 4, 14929928, 28, 14958067, 12, 14947840, 0, 14925209, 0, 14930538, 42, 14937489, 0, 14926041, 0, 14949764, 0, 14968640},\r
+{1, 40, 0, 14974011, 4, 15003374, 0, 15008746, 0, 15030024, 0, 15059340, 0, 15071441, 0, 15050688, 0, 15036620, 0, 15048025, 0, 15044531, 0, 15075157, 0, 15071616, 0, 15086212, 38, 15118062, 48, 15128196, 0, 15120115, 0, 15163716, 22, 15179622, 48, 15206229, 16, 15218986},\r
+{1, 40, 0, 15229166, 0, 15275827, 46, 15280238, 0, 15310037, 0, 15277184, 0, 15275869, 0, 15294353, 0, 15296145, 0, 15298329, 0, 15315106, 0, 15297672, 0, 15308859, 0, 15311872, 0, 15325593, 0, 15337561, 0, 15383351, 0, 15367970, 0, 15405806, 0, 15413495, 24, 15412450},\r
+{1, 40, 2, 15438225, 0, 15458453, 0, 15443511, 8, 15436083, 0, 15436872, 0, 15454348, 0, 15457143, 0, 15482790, 0, 15479556, 0, 15497774, 0, 15493056, 0, 15500266, 0, 15527091, 0, 15536004, 0, 15551210, 0, 15551385, 0, 15572573, 0, 15582186, 0, 15603857, 0, 15617664},\r
+{1, 40, 0, 15585420, 12, 15586905, 0, 15579302, 0, 15588130, 18, 15569779, 24, 15562525, 0, 15543872, 0, 15571921, 0, 15577075, 10, 15575458, 0, 15574016, 0, 15591534, 0, 15622033, 0, 15621333, 0, 15645755, 0, 15678395, 0, 15676428, 0, 15687436, 0, 15671842, 0, 15668168},\r
+{1, 40, 0, 15661529, 0, 15649164, 12, 15675072, 0, 15679530, 0, 15656985, 0, 15676778, 38, 15685994, 22, 15694382, 0, 15698926, 0, 15707272, 36, 15716275, 54, 15719505, 0, 15772283, 0, 15775825, 0, 15802956, 14, 15815146, 0, 15804441, 0, 15780893, 0, 15803784, 0, 15782071},\r
+{1, 40, 0, 15782161, 0, 15808678, 0, 15778577, 0, 15790852, 0, 15807018, 0, 15792819, 0, 15788232, 0, 15821653, 0, 15819601, 0, 15843020, 0, 15858530, 0, 15882777, 2, 15862417, 87, 15909474, 24, 15893175, 0, 15897194, 6, 15883170, 32, 15873472, 10, 15867485, 0, 15856695},\r
+{1, 40, 0, 15872294, 0, 15853811, 0, 15877098, 0, 15860147, 0, 15870412, 0, 15872512, 0, 15871462, 0, 15885969, 0, 15901610, 0, 15910651, 0, 15932194, 0, 15958801, 0, 15973307, 0, 15977194, 0, 15947921, 0, 15934946, 0, 15945561, 0, 15929309, 0, 15946611, 6, 15905757},\r
+{1, 40, 16, 15923234, 0, 15945211, 0, 15953949, 0, 15939925, 6, 15973525, 0, 15962035, 0, 15967496, 0, 15983441, 0, 16005461, 0, 15995673, 0, 16014766, 0, 16015773, 0, 15991611, 0, 15985450, 0, 15975095, 0, 15991961, 0, 15986542, 0, 15978547, 0, 16003366, 0, 15987677},\r
+{1, 40, 0, 16008260, 0, 16011362, 0, 16035652, 0, 16038186, 0, 16048759, 38, 16049501, 0, 16047057, 0, 16091665, 0, 16087381, 22, 16069205, 16, 16046967, 0, 16042816, 0, 16030233, 0, 16039671, 0, 16029358, 0, 16030105, 0, 16046050, 0, 16046050, 0, 16030715, 0, 16036612},\r
+{1, 40, 0, 16052953, 0, 16054788, 2, 16071436, 0, 16081612, 0, 16096294, 0, 16124650, 0, 16116480, 0, 16080217, 0, 16067110, 0, 16062916, 0, 16068505, 58, 16047974, 0, 16048759, 0, 16056755, 0, 16052253, 0, 16023769, 0, 16063701, 0, 16058589, 0, 16047927, 0, 16071829},\r
+{1, 40, 0, 16089173, 0, 16044740, 0, 16107699, 0, 16113245, 0, 16123950, 0, 16111936, 0, 16090525, 0, 16096861, 0, 16087296, 0, 16060992, 0, 16059374, 0, 16058504, 69, 16039321, 0, 16072921, 0, 16055227, 0, 16081395, 44, 16061734, 0, 16085896, 0, 16114120, 0, 16116612},\r
+{1, 40, 0, 16174720, 8, 16103854, 0, 16154666, 0, 16133870, 0, 16133346, 0, 16119321, 0, 16114035, 0, 16087863, 0, 16108919, 0, 16080217, 0, 16105600, 0, 16112418, 0, 16096861, 0, 16108309, 0, 16095159, 0, 16111411, 0, 16112768, 52, 16131989, 56, 16153049, 32, 16164104},\r
+{1, 40, 0, 16161830, 0, 16122990, 10, 16114077, 12, 16110886, 0, 16093934, 0, 16096951, 0, 16096819, 0, 16094067, 0, 16088913, 0, 16110361, 0, 16109444, 0, 16104029, 0, 16125960, 0, 16109969, 0, 16126135, 0, 16156586, 0, 16160955, 0, 16189619, 0, 16189401, 0, 16184857},\r
+{1, 40, 6, 16185949, 0, 16221905, 0, 16206788, 24, 16233002, 6, 16250261, 0, 16254630, 0, 16270314, 0, 16291460, 18, 16306009, 0, 16297096, 0, 16312827, 0, 16385045, 0, 16410824, 0, 16440401, 0, 16484881, 0, 16482649, 0, 16514589, 0, 16480247, 0, 16466048, 0, 16485883},\r
+{1, 40, 0, 16520704, 0, 16538137, 0, 16583662, 0, 16608000, 0, 16630762, 0, 16661435, 0, 16683541, 0, 16747374, 0, 16777868, 12, 16809019, 34, 16877529, 0, 16896533, 0, 16923404, 6, 16909725, 18, 16933977, 0, 16926417, 0, 16938914, 0, 16944678, 0, 16960059, 0, 16995972},\r
+{1, 40, 0, 16976661, 0, 16951581, 0, 16971549, 0, 17013405, 0, 17065834, 0, 17088640, 0, 17171259, 0, 17198391, 0, 17275592, 0, 17298397, 0, 17335974, 0, 17336234, 0, 17357730, 0, 17375428, 0, 17369617, 0, 17404744, 32, 17456166, 0, 17533674, 0, 17598425, 0, 17599121},\r
+{1, 40, 38, 17613320, 18, 17622365, 0, 17633331, 0, 17628834, 0, 17673527, 0, 17708172, 0, 17734737, 0, 17781312, 0, 17813294, 0, 17821508, 0, 17798788, 0, 17845973, 0, 17846762, 0, 17855850, 0, 17854758, 0, 17861397, 0, 17906094, 0, 17914176, 8, 17942749, 0, 17948736},\r
+{1, 40, 0, 17978444, 50, 18010513, 10, 18018990, 0, 18064776, 0, 18095667, 0, 18086754, 0, 18144076, 0, 18157009, 0, 18144904, 0, 18138180, 0, 18176102, 0, 18151065, 0, 18146521, 0, 18207953, 0, 18207428, 0, 18215859, 0, 18221585, 0, 18212279, 0, 18247317, 0, 18263616},\r
+{1, 40, 0, 18288038, 0, 18291840, 0, 18299660, 2, 18329369, 16, 18341341, 18, 18372403, 0, 18344136, 0, 18348987, 38, 18361920, 0, 18371050, 0, 18400277, 0, 18383940, 0, 18402333, 0, 18432960, 0, 18467212, 0, 18483729, 0, 18474026, 0, 18516889, 0, 18539652, 0, 18567176},\r
+{1, 40, 0, 18552059, 0, 18580416, 0, 18601954, 0, 18609467, 0, 18570235, 0, 18553851, 0, 18588279, 0, 18608332, 0, 18604620, 0, 18654250, 40, 18643767, 20, 18658884, 0, 18668846, 0, 18687193, 0, 18710788, 0, 18724288, 0, 18754043, 0, 18786939, 0, 18780736, 0, 18825216},\r
+{1, 40, 0, 18809267, 0, 18826350, 0, 18794892, 0, 18793668, 0, 18818090, 0, 18797162, 0, 18825736, 0, 18816345, 0, 18849591, 0, 18821939, 0, 18825608, 0, 18863223, 0, 18872443, 0, 18893107, 26, 18906346, 0, 18917708, 0, 18927189, 0, 18955281, 34, 18969130, 2, 19011818},\r
+{1, 40, 0, 18993510, 0, 18969262, 8, 18972672, 0, 18968473, 0, 18956505, 0, 18983897, 0, 18993770, 0, 19020599, 0, 19012296, 0, 19026713, 0, 19043054, 0, 19053324, 0, 19076130, 0, 19044714, 0, 19072896, 0, 19091554, 0, 19098585, 0, 19101602, 0, 19127509, 0, 19099110},\r
+{1, 40, 6, 19095923, 77, 19094958, 0, 19108633, 0, 19103914, 0, 19123404, 0, 19140791, 4, 19166438, 0, 19157393, 0, 19177403, 4, 19173077, 0, 19191078, 0, 19184742, 0, 19210611, 0, 19200908, 0, 19225945, 0, 19231884, 0, 19243464, 0, 19241497, 0, 19205235, 0, 19192345},\r
+{1, 40, 0, 19209429, 0, 19187801, 18, 19187234, 0, 19200998, 0, 19207244, 0, 19208861, 14, 19228782, 0, 19229747, 8, 19246434, 0, 19246958, 0, 19248708, 4, 19260458, 0, 19259498, 0, 19287590, 0, 19284313, 0, 19306158, 0, 19279291, 0, 19247266, 0, 19224064, 0, 19237568},\r
+{1, 40, 0, 19255479, 0, 19268236, 0, 19244206, 0, 19234683, 0, 19230617, 0, 19253162, 0, 19247658, 32, 19274658, 18, 19250717, 0, 19282875, 0, 19263517, 0, 19273390, 0, 19280558, 0, 19300219, 0, 19305373, 0, 19266884, 0, 19267712, 0, 19247923, 0, 19245824, 0, 19259763},\r
+{1, 40, 0, 19220701, 0, 19259456, 0, 19254037, 0, 19274440, 0, 19285713, 0, 19255261, 0, 19252945, 0, 19262690, 0, 19246916, 14, 19273873, 0, 19258321, 0, 19285452, 4, 19289864, 20, 19302754, 0, 19276932, 0, 19240187, 0, 19283793, 42, 19269593, 0, 19253555, 0, 19258274},\r
+{1, 40, 0, 19214190, 0, 19241937, 0, 19231142, 0, 19227865, 0, 19221836, 0, 19206937, 0, 19209254, 0, 19235950, 0, 19247658, 0, 19244817, 0, 19219042, 0, 19240669, 0, 19268019, 0, 19244121, 0, 19170675, 0, 19158400, 0, 19130393, 0, 19121565, 0, 19117371, 60, 19109465},\r
+{1, 40, 34, 19085696, 0, 19076347, 0, 19057693, 0, 19091289, 0, 19049826, 0, 19054327, 0, 19038728, 0, 19066517, 0, 19042269, 0, 19060881, 0, 19048516, 0, 19056251, 0, 19050700, 0, 18979571, 0, 18964979, 0, 18935185, 0, 18925529, 0, 18895863, 0, 18887035, 0, 18856102},\r
+{1, 40, 0, 18844569, 12, 18821892, 0, 18813593, 0, 18811016, 0, 18779733, 16, 18775317, 38, 18782660, 0, 18775799, 0, 18763959, 0, 18779861, 16, 18767368, 0, 18727347, 0, 18706112, 0, 18632362, 0, 18581115, 0, 18577049, 0, 18555771, 0, 18523093, 0, 18489100, 0, 18472849},       \r
+};\r
+static const int16_t pah831x_mems_HRV[][3*NF_PPG_PER_CHANNEL] = \r
+{\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},\r
+{20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},      \r
+};\r
+static const uint32_t duration_HRV[] = \r
+{\r
+1125,\r
+1018,\r
+1018,\r
+1018,\r
+1018,\r
+1018,\r
+1018,\r
+1018,\r
+1017,\r
+1018,\r
+1018,\r
+1018,\r
+1018,\r
+1018,\r
+1018,\r
+1017,\r
+1018,\r
+1018,\r
+1018,\r
+1017,\r
+1017,\r
+1018,\r
+1018,\r
+1017,\r
+1019,\r
+1018,\r
+1018,\r
+1018,\r
+1019,\r
+1018,\r
+1017,\r
+1018,\r
+1019,\r
+1018,\r
+1018,\r
+1018,\r
+1018,\r
+1018,\r
+1019,\r
+1019,\r
+1018,\r
+1019,\r
+1018,\r
+1018,\r
+1018,\r
+1018,\r
+1018,\r
+1018,\r
+1018,\r
+1018,\r
+1019,\r
+1018,\r
+1017,\r
+1018,\r
+1018,\r
+1017,\r
+1018,\r
+1018,\r
+1017,\r
+1018,\r
+1018,\r
+1017,\r
+1018,\r
+1017,\r
+1018,\r
+1018,\r
+1018,\r
+1018,\r
+1017,\r
+1018,\r
+1017,\r
+1017,\r
+1018,\r
+1017,\r
+1018,\r
+1018,\r
+1017,\r
+1018,\r
+1018,\r
+1018,\r
+1017,\r
+1018,\r
+1018,\r
+1017,\r
+1018,\r
+1018,\r
+1018,\r
+1018,\r
+1018,\r
+1017,\r
+1018,\r
+1018,\r
+1018,\r
+1017,\r
+1018,\r
+1017,\r
+1018,\r
+1017,\r
+1018,\r
+1018,\r
+1017,\r
+1018,\r
+1018,\r
+1018,\r
+1018,\r
+1018,\r
+1018,\r
+1019,\r
+1018,\r
+1017,\r
+1018,\r
+1018,\r
+1018,\r
+1018,\r
+1018,\r
+1018,\r
+1018,\r
+1018,\r
+1018,\r
+1018,\r
+1019,\r
+1017,\r
+1018,\r
+1018,\r
+1018,\r
+1018,\r
+1018,\r
+1017,\r
+1018,\r
+1018,\r
+1018,\r
+1019,\r
+1018,\r
+1018,\r
+1018,\r
+1018,\r
+1018,\r
+1017,\r
+1018,\r
+1017,\r
+1017,\r
+1018,\r
+1018,\r
+1018,\r
+1017,\r
+1018,\r
+1017,\r
+1017,\r
+1018,\r
+1017,\r
+1018,\r
+1017,\r
+1018,\r
+1018,\r
+1017,\r
+1018,\r
+1019,\r
+1018,\r
+1018,\r
+1018,\r
+1018,\r
+1017,\r
+1018,\r
+1018,\r
+1018,\r
+1018,\r
+1018,\r
+1018,\r
+1017,\r
+1018,\r
+1017,\r
+1017,\r
+1018,\r
+1018,\r
+1017,\r
+1018,\r
+1018,\r
+1017,\r
+1018,\r
+1017,\r
+1018,\r
+1017,\r
+1018,\r
+1017,\r
+1018,\r
+1018,\r
+1017,\r
+1018,\r
+1018,\r
+1018,\r
+1018,\r
+1018,\r
+1017,\r
+1017,\r
+1018,\r
+1017,\r
+1018,\r
+1018,  \r
+};\r
+\r
+\r
+#endif\r
diff --git a/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/RR_HRV_STRESS_RRI/V3131/pah831x_testpattern_RR_2.h b/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/RR_HRV_STRESS_RRI/V3131/pah831x_testpattern_RR_2.h
new file mode 100644 (file)
index 0000000..3faa594
--- /dev/null
@@ -0,0 +1,745 @@
+#ifndef _PAH831X_RR_TESTPATTERN_\r
+#define _PAH831X_RR_TESTPATTERN_\r
+\r
+#include <stdint.h>\r
+#define NF_PPG_CHANNEL 1\r
+#define NF_PPG_PER_CHANNEL 30\r
+static const int32_t PAH831X_rawdata_RR[][NF_PPG_PER_CHANNEL*NF_PPG_CHANNEL] = \r
+{\r
+{1, 25, 18026524, 18055375, 18079648, 18095666, 18123044, 18139288, 18167218, 18182511, 18200299, 18215314, 18180258, 18122800, 18081416, 18071446, 18063662, 18078937, 18114062, 18129909, 18146813, 18163423, 18176339, 18201358, 18217463, 18237507, 18255069, },\r
+{1, 25, 18272199, 18290767, 18299070, 18270535, 18216094, 18167098, 18156592, 18161446, 18188198, 18219682, 18235477, 18250422, 18268279, 18287091, 18305468, 18322460, 18337371, 18349663, 18372201, 18395851, 18407068, 18367398, 18309717, 18267759, 18265299, },\r
+{1, 25, 18266512, 18298412, 18326414, 18330904, 18350165, 18360931, 18384408, 18401381, 18422064, 18440096, 18453688, 18471978, 18489386, 18486924, 18431668, 18380021, 18360464, 18371145, 18389955, 18415563, 18424596, 18430543, 18440842, 18456167, 18468668, },\r
+{1, 25, 18485241, 18499096, 18516727, 18534637, 18558199, 18559985, 18506359, 18452473, 18423625, 18428288, 18448123, 18473730, 18482885, 18497464, 18508371, 18518946, 18538902, 18554264, 18567994, 18580650, 18597607, 18608772, 18614026, 18556310, 18482121, },\r
+{1, 25, 18434876, 18405091, 18396387, 18430699, 18455925, 18461941, 18475515, 18490305, 18509515, 18528812, 18549097, 18571081, 18583304, 18605045, 18618725, 18594937, 18513710, 18417765, 18352073, 18323864, 18331615, 18372652, 18406495, 18429259, 18452924, },\r
+{1, 25, 18471493, 18507052, 18529800, 18557125, 18576664, 18601768, 18627496, 18645926, 18600919, 18506914, 18417850, 18367382, 18358471, 18393890, 18437304, 18460086, 18474406, 18491085, 18521114, 18544849, 18572588, 18593255, 18609326, 18622348, 18645841, },\r
+{1, 25, 18643344, 18599340, 18492714, 18401796, 18380247, 18390284, 18423434, 18462287, 18487704, 18512394, 18530198, 18562950, 18583235, 18614806, 18642391, 18662085, 18676250, 18702967, 18713734, 18666246, 18580703, 18508578, 18478342, 18489352, 18526679, },\r
+{1, 25, 18553413, 18571012, 18592666, 18608652, 18630704, 18658444, 18684468, 18707267, 18737798, 18748184, 18776634, 18787575, 18761463, 18685041, 18629404, 18611927, 18624481, 18648059, 18675297, 18685891, 18692878, 18710422, 18724380, 18748617, 18763875, },\r
+{1, 25, 18776427, 18791909, 18809490, 18820603, 18818730, 18759990, 18687831, 18653728, 18646152, 18677152, 18701303, 18710977, 18711706, 18727361, 18741682, 18758916, 18780934, 18802728, 18816597, 18828371, 18846366, 18851671, 18804774, 18724136, 18671378, },\r
+{1, 25, 18643586, 18643256, 18671553, 18697368, 18716334, 18721710, 18741404, 18764255, 18788061, 18805762, 18824486, 18838582, 18861728, 18879569, 18872651, 18786586, 18687276, 18606449, 18571773, 18571601, 18602219, 18644904, 18666246, 18686167, 18701511, },\r
+{1, 25, 18728037, 18752467, 18779946, 18799520, 18818228, 18833936, 18858624, 18862785, 18770862, 18657613, 18573681, 18544658, 18547208, 18589978, 18630341, 18645562, 18660768, 18693501, 18720652, 18744456, 18768833, 18789465, 18805414, 18822215, 18841685, },\r
+{1, 25, 18828265, 18730569, 18614044, 18549634, 18527876, 18545611, 18580374, 18615881, 18630964, 18645493, 18675504, 18706436, 18733517, 18759401, 18777346, 18791649, 18817326, 18826325, 18815593, 18700385, 18573387, 18526626, 18513519, 18541364, 18590378, },\r
+{1, 25, 18612224, 18628104, 18648041, 18676024, 18699759, 18730603, 18747231, 18771226, 18795428, 18814553, 18826012, 18787955, 18678989, 18567283, 18533233, 18533459, 18577529, 18613678, 18622815, 18639512, 18660733, 18687311, 18718953, 18741873, 18760943, },\r
+{1, 25, 18779408, 18803907, 18820811, 18805780, 18722039, 18638785, 18606189, 18617059, 18658409, 18689601, 18699934, 18713335, 18732198, 18753836, 18775560, 18798965, 18821835, 18844633, 18863079, 18875408, 18837542, 18729234, 18634242, 18605513, 18604005, },\r
+{1, 25, 18635611, 18671083, 18686132, 18696293, 18711757, 18733602, 18762886, 18786899, 18813563, 18835218, 18852435, 18870968, 18833312, 18699985, 18564354, 18508387, 18478394, 18496530, 18546669, 18578155, 18601941, 18628347, 18659051, 18690102, 18719229, },\r
+{1, 25, 18742359, 18765452, 18791025, 18809333, 18819025, 18716785, 18549877, 18457120, 18412389, 18400601, 18428428, 18482415, 18520766, 18542821, 18573318, 18605340, 18651578, 18683394, 18714097, 18736585, 18766925, 18788286, 18773774, 18649896, 18498401, },\r
+{1, 25, 18428582, 18398398, 18414504, 18471373, 18505561, 18521530, 18550068, 18590100, 18625867, 18665813, 18698044, 18727742, 18754253, 18779999, 18794491, 18746745, 18605738, 18484081, 18441413, 18428080, 18472429, 18522101, 18549182, 18570057, 18597520, },\r
+{1, 25, 18633461, 18670547, 18709642, 18735215, 18758708, 18785113, 18806282, 18827416, 18793002, 18664685, 18551592, 18511232, 18510486, 18562204, 18604507, 18617234, 18631102, 18657525, 18691283, 18723772, 18753263, 18777797, 18800629, 18822769, 18840783, },\r
+{1, 25, 18838824, 18754182, 18658202, 18611632, 18607542, 18651146, 18698719, 18720166, 18723130, 18741664, 18770549, 18797787, 18821713, 18851169, 18872425, 18893525, 18912215, 18896455, 18780363, 18659988, 18604836, 18597122, 18622000, 18667824, 18694871, },\r
+{1, 25, 18716560, 18735284, 18768174, 18805069, 18836173, 18860739, 18886798, 18903078, 18927766, 18938030, 18852886, 18705637, 18606709, 18572606, 18566087, 18603658, 18653277, 18689686, 18701685, 18735892, 18777778, 18807860, 18848430, 18880660, 18909580, },\r
+{1, 25, 18930159, 18960483, 18974179, 18903182, 18764064, 18642425, 18599358, 18585124, 18619765, 18680880, 18726060, 18749121, 18782061, 18815158, 18849556, 18889120, 18910273, 18942398, 18969220, 18995175, 19012321, 18980646, 18865698, 18739618, 18668257, },\r
+{1, 25, 18650331, 18677983, 18729858, 18773254, 18802694, 18827591, 18856527, 18898171, 18925253, 18952177, 18970520, 18996163, 19022065, 19042629, 19045749, 18967765, 18855399, 18776167, 18750092, 18766874, 18811483, 18839899, 18854706, 18861572, 18884630, },\r
+{1, 25, 18917382, 18949959, 18977212, 18994846, 19019048, 19034201, 19063814, 19051036, 18964644, 18876881, 18819892, 18814136, 18849540, 18887994, 18913550, 18925754, 18940960, 18969341, 18999838, 19030093, 19046962, 19070870, 19091051, 19115635, 19128569, },\r
+{1, 25, 19105527, 19012236, 18909076, 18845500, 18834005, 18846801, 18896558, 18925876, 18945312, 18965839, 18994169, 19024249, 19050481, 19075516, 19099859, 19117161, 19140463, 19161494, 19168828, 19096011, 18980108, 18881042, 18847494, 18849609, 18882793, },\r
+{1, 25, 18920380, 18959252, 18977074, 19000515, 19028429, 19061508, 19086336, 19114093, 19141556, 19157176, 19181259, 19202029, 19195459, 19102287, 18991534, 18893143, 18859109, 18855468, 18896004, 18939989, 18970209, 18992384, 19016795, 19045662, 19075726, },\r
+{1, 25, 19100397, 19125762, 19148196, 19167579, 19183687, 19201942, 19191956, 19101576, 18991014, 18917762, 18897859, 18902558, 18943890, 18980768, 18996284, 19010121, 19035416, 19065010, 19093601, 19114630, 19137775, 19160212, 19176005, 19200591, 19214841, },\r
+{1, 25, 19190066, 19093670, 19002959, 18945676, 18932482, 18960690, 19003219, 19021805, 19044327, 19066276, 19082174, 19107592, 19133874, 19154074, 19176387, 19186200, 19210057, 19229318, 19222643, 19153865, 19072674, 19035225, 19031566, 19067335, 19098906, },\r
+{1, 25, 19109481, 19126038, 19139874, 19157577, 19179958, 19204561, 19220268, 19245616, 19256573, 19276166, 19284451, 19244472, 19144677, 19062548, 19015651, 19015182, 19039490, 19070281, 19081429, 19093825, 19108545, 19128519, 19153936, 19175224, 19191940, },\r
+{1, 25, 19205774, 19221656, 19234399, 19225799, 19139545, 18997879, 18880349, 18835132, 18825250, 18862474, 18905488, 18932794, 18962163, 18985102, 19017177, 19045038, 19081551, 19105424, 19125363, 19151179, 19164997, 19175728, 19110174, 18998972, 18904015, },\r
+{1, 25, 18863445, 18859231, 18886851, 18926224, 18947669, 18962858, 18986575, 19018355, 19044534, 19073783, 19100379, 19124738, 19141522, 19161459, 19177358, 19115723, 19007345, 18917034, 18875459, 18867224, 18897980, 18937908, 18960534, 18970244, 18994151, },\r
+{1, 25, 19018841, 19044969, 19072205, 19097866, 19117891, 19134551, 19154750, 19166175, 19097882, 18998938, 18923119, 18900945, 18910116, 18944861, 18969100, 18976087, 18986211, 19010935, 19036976, 19066934, 19088607, 19110625, 19133354, 19156796, 19159881, },\r
+{1, 25, 19074545, 18986766, 18917501, 18893507, 18913080, 18947584, 18964798, 18974455, 18985864, 19012496, 19032832, 19060451, 19086925, 19107557, 19130355, 19146861, 19125918, 19010121, 18880193, 18816408, 18784906, 18794128, 18838513, 18860600, 18876793, },\r
+{1, 25, 18891426, 18917501, 18943179, 18971666, 19003062, 19024648, 19058214, 19080007, 19044152, 18906008, 18751236, 18675332, 18642304, 18632161, 18673493, 18709313, 18730221, 18748531, 18776687, 18813980, 18851827, 18886416, 18922912, 18950790, 18982328, },\r
+{1, 25, 18957742, 18817794, 18656694, 18563106, 18518200, 18506187, 18542925, 18583893, 18610263, 18636062, 18664634, 18706539, 18746034, 18784593, 18815731, 18852591, 18880954, 18896367, 18800717, 18631190, 18502649, 18453566, 18438656, 18482972, 18529003, },\r
+{1, 25, 18558892, 18578379, 18606466, 18643171, 18683983, 18720514, 18746884, 18781610, 18813616, 18843160, 18814275, 18672054, 18530787, 18470314, 18448503, 18479886, 18537411, 18556326, 18564163, 18585315, 18622850, 18654075, 18688197, 18715329, 18748513, },\r
+{1, 25, 18778473, 18809108, 18753178, 18623353, 18525118, 18492749, 18502960, 18554628, 18592509, 18610870, 18616608, 18643551, 18670478, 18700645, 18729616, 18763095, 18794215, 18822493, 18833206, 18719091, 18563382, 18472777, 18436421, 18442644, 18487096, },\r
+{1, 25, 18523351, 18549182, 18566660, 18590776, 18633079, 18671101, 18715798, 18745220, 18775143, 18808795, 18834560, 18754738, 18586857, 18451279, 18395105, 18369288, 18401485, 18457433, 18490217, 18509722, 18538849, 18578190, 18617908, 18660837, 18699828, },\r
+{1, 25, 18726859, 18770515, 18799504, 18789898, 18661254, 18500309, 18412458, 18386505, 18399492, 18453203, 18495073, 18516866, 18543652, 18577115, 18626647, 18662605, 18702169, 18732840, 18770427, 18800509, 18823759, 18770117, 18627584, 18508042, 18469534, },\r
+{1, 25, 18468390, 18515427, 18557886, 18574409, 18591867, 18611963, 18644419, 18683723, 18721015, 18751894, 18780225, 18816477, 18831993, 18784455, 18665969, 18574809, 18543601, 18561649, 18610923, 18652342, 18664582, 18683444, 18704406, 18737556, 18769231, },\r
+{1, 25, 18794788, 18823464, 18852469, 18879532, 18894061, 18812974, 18667912, 18567960, 18528083, 18525604, 18557505, 18592111, 18599202, 18605998, 18623735, 18648614, 18685490, 18713837, 18737487, 18767758, 18787921, 18809142, 18742879, 18569849, 18429173, },\r
+{1, 25, 18355332, 18327332, 18339017, 18381651, 18410500, 18430161, 18449424, 18479313, 18522796, 18566625, 18606362, 18640310, 18677550, 18710076, 18706417, 18558892, 18377055, 18270864, 18224416, 18213995, 18254201, 18307013, 18326621, 18341497, 18380420, },\r
+{1, 25, 18416845, 18461628, 18500256, 18539735, 18578050, 18616385, 18650642, 18605513, 18432743, 18284005, 18201981, 18181697, 18207581, 18263287, 18286831, 18311537, 18333624, 18368457, 18412667, 18450464, 18490737, 18527061, 18563332, 18593637, 18614233, },\r
+{1, 25, 18519344, 18363463, 18262072, 18230779, 18242342, 18297268, 18335116, 18345953, 18364747, 18394827, 18435970, 18480300, 18511439, 18549477, 18585262, 18614875, 18638124, 18549217, 18392919, 18292033, 18256197, 18263651, 18321038, 18360411, 18376641, },\r
+{1, 25, 18390458, 18424352, 18468719, 18508960, 18541866, 18575555, 18613264, 18640032, 18672991, 18615899, 18432223, 18285669, 18219751, 18186949, 18212939, 18269234, 18300875, 18312907, 18344547, 18379066, 18420209, 18461958, 18498921, 18532695, 18567891, },\r
+{1, 25, 18603692, 18620806, 18484532, 18300458, 18179441, 18121293, 18108220, 18144022, 18197977, 18227380, 18254878, 18288132, 18323362, 18368768, 18408315, 18446701, 18485382, 18523229, 18567856, 18568618, 18422237, 18243504, 18141698, 18100626, 18105307, },\r
+{1, 25, 18155205, 18207825, 18230639, 18250510, 18288808, 18329707, 18374698, 18416308, 18455734, 18492143, 18520801, 18561787, 18544902, 18395243, 18243677, 18171450, 18152257, 18181558, 18232252, 18272284, 18291149, 18319183, 18358643, 18404502, 18446303, },\r
+{1, 25, 18489402, 18524946, 18556361, 18586112, 18620285, 18577895, 18433854, 18322807, 18286155, 18294737, 18337300, 18380645, 18389609, 18407153, 18428046, 18468477, 18501522, 18541173, 18572917, 18602548, 18635871, 18662119, 18637084, 18504088, 18395485, },\r
+{1, 25, 18345067, 18353408, 18388532, 18432414, 18442071, 18456305, 18477025, 18512948, 18550414, 18591902, 18617632, 18648909, 18680880, 18713248, 18678418, 18519692, 18392035, 18331008, 18308538, 18326828, 18371803, 18398693, 18421197, 18439921, 18476850, },\r
+{1, 25, 18514023, 18552842, 18590862, 18626283, 18666455, 18690293, 18648909, 18468286, 18316426, 18237125, 18202884, 18208345, 18258068, 18293593, 18312161, 18334526, 18369688, 18413689, 18446441, 18486387, 18524997, 18560020, 18589840, 18579334, 18410205, },\r
+{1, 25, 18229930, 18122402, 18069885, 18063089, 18101337, 18146241, 18175142, 18200888, 18229946, 18269442, 18310046, 18353200, 18390544, 18424161, 18462010, 18491257, 18429675, 18233675, 18069124, 17985991, 17948818, 17954677, 17998681, 18026733, 18045874, },\r
+{1, 25, 18065135, 18110230, 18142305, 18188440, 18229877, 18260026, 18297876, 18336331, 18352314, 18229063, 18034291, 17911942, 17850827, 17844498, 17875584, 17909808, 17928758, 17952130, 17981517, 18020282, 18062535, 18094055, 18142443, 18179547, 18216545, },\r
+{1, 25, 18245343, 18184263, 18012135, 17883385, 17831667, 17822740, 17880299, 17916917, 17931064, 17947934, 17973991, 18017578, 18057421, 18099724, 18140797, 18175837, 18216110, 18254896, 18231074, 18062484, 17903601, 17824768, 17797999, 17817122, 17874612, },\r
+{1, 25, 17903410, 17925603, 17946825, 17991346, 18032282, 18078520, 18123442, 18165329, 18202727, 18247233, 18273170, 18183395, 17986371, 17839869, 17776759, 17739971, 17768907, 17819133, 17851918, 17872688, 17899926, 17947690, 17996497, 18040360, 18089979, },\r
+{1, 25, 18127221, 18174917, 18211949, 18216441, 18058079, 17878895, 17783608, 17745326, 17741356, 17790803, 17840440, 17866863, 17895712, 17934254, 17979574, 18026040, 18069869, 18120842, 18160058, 18202605, 18218626, 18091871, 17914802, 17794704, 17747252, },\r
+{1, 25, 17734977, 17780904, 17842990, 17877544, 17897845, 17937548, 17986511, 18031813, 18080774, 18126372, 18163959, 18208449, 18231801, 18107873, 17923488, 17801067, 17754863, 17747356, 17794375, 17847428, 17880960, 17909063, 17944344, 17989319, 18037067, },\r
+{1, 25, 18088281, 18127725, 18166977, 18215054, 18249175, 18220862, 18052201, 17900220, 17833211, 17819272, 17846838, 17913622, 17951800, 17977772, 18000398, 18035663, 18085057, 18134070, 18182182, 18227017, 18267778, 18301620, 18330227, 18253543, 18111097, },\r
+{1, 25, 18011440, 17981309, 17996948, 18052861, 18086044, 18101284, 18117946, 18148634, 18183170, 18229912, 18272493, 18315040, 18343109, 18382864, 18412216, 18329585, 18202918, 18130273, 18113422, 18143069, 18187001, 18226045, 18242413, 18261310, 18289310, },\r
+{1, 25, 18326743, 18370190, 18405957, 18443251, 18475741, 18510364, 18533666, 18422221, 18259490, 18173027, 18143311, 18149345, 18190053, 18227224, 18248064, 18268332, 18297788, 18342658, 18380576, 18422653, 18463553, 18492021, 18524476, 18557003, 18501885, },\r
+{1, 25, 18331700, 18182718, 18105793, 18071151, 18084744, 18137260, 18185545, 18206713, 18237194, 18269216, 18311519, 18353893, 18390371, 18434980, 18472949, 18506967, 18522465, 18415685, 18239256, 18118952, 18065865, 18055184, 18093952, 18146484, 18174327, },\r
+{1, 25, 18192914, 18224172, 18268749, 18314225, 18355714, 18399577, 18436333, 18472413, 18505163, 18494171, 18343300, 18182771, 18099291, 18060298, 18071966, 18120200, 18147610, 18172212, 18194681, 18224416, 18257426, 18308209, 18356390, 18390769, 18429312, },\r
+{1, 25, 18454763, 18496424, 18463292, 18315075, 18180102, 18127811, 18116195, 18152431, 18198253, 18220151, 18226809, 18254392, 18293540, 18337716, 18375600, 18407293, 18440911, 18473660, 18507001, 18507227, 18387009, 18276185, 18230554, 18228975, 18271575, },\r
+{1, 25, 18309733, 18331198, 18346126, 18363688, 18394428, 18432483, 18477752, 18514525, 18551072, 18585541, 18607715, 18535123, 18385464, 18285565, 18252954, 18253039, 18307047, 18346680, 18359944, 18370553, 18399075, 18427820, 18473244, 18510502, 18543028, },\r
+{1, 25, 18574929, 18605998, 18619349, 18492645, 18310444, 18193798, 18142565, 18138577, 18173616, 18214186, 18230501, 18247440, 18270880, 18313705, 18349074, 18381754, 18423537, 18456982, 18490530, 18507331, 18363083, 18161133, 18031796, 17961423, 17922933, },\r
+{1, 25, 17942767, 17987360, 18006743, 18023456, 18041730, 18077947, 18110612, 18148703, 18184019, 18216596, 18254411, 18288965, 18228699, 18021063, 17844100, 17749073, 17689067, 17677295, 17713859, 17748813, 17764260, 17782430, 17822358, 17857952, 17893095, },\r
+{1, 25, 17931255, 17968861, 18009100, 18048961, 18074532, 17987811, 17766391, 17607042, 17518967, 17467042, 17456934, 17493083, 17515796, 17524654, 17541906, 17582232, 17617271, 17665747, 17705085, 17749176, 17793751, 17837303, 17882969, 17883715, 17701012, },\r
+{1, 25, 17512206, 17411145, 17359981, 17351816, 17396963, 17433494, 17455286, 17476421, 17507177, 17558046, 17598600, 17646746, 17690142, 17729099, 17776900, 17819550, 17831426, 17685026, 17520424, 17432385, 17408008, 17433858, 17496395, 17523961, 17541264, },\r
+{1, 25, 17567496, 17600316, 17645151, 17695967, 17732219, 17770900, 17812701, 17852802, 17889940, 17831269, 17649347, 17514910, 17461857, 17452964, 17498595, 17553521, 17578591, 17597854, 17627085, 17671139, 17714259, 17768299, 17811523, 17846284, 17884357, },\r
+{1, 25, 17921026, 17957105, 17909012, 17723690, 17578280, 17511651, 17490968, 17512588, 17569611, 17610162, 17633499, 17659853, 17704687, 17753823, 17805194, 17849561, 17891362, 17936282, 17976055, 18019364, 18041921, 17946756, 17750753, 17609660, 17555220, },\r
+{1, 25, 17546187, 17571328, 17633448, 17673774, 17702469, 17729619, 17773570, 17824144, 17877438, 17929660, 17970681, 18012586, 18053260, 18088976, 18128505, 18092495, 17923315, 17763462, 17687576, 17668122, 17688460, 17747512, 17786573, 17806181, 17833472, },\r
+{1, 25, 17864072, 17915270, 17966988, 18022641, 18056691, 18095806, 18136167, 18168953, 18208101, 18222890, 18107005, 17955388, 17875896, 17854762, 17876000, 17925099, 17956307, 17975068, 17993567, 18021463, 18060541, 18108237, 18152829, 18187522, 18228230, },\r
+{1, 25, 18257651, 18292258, 18272961, 18142687, 18028344, 17983164, 17991816, 18030756, 18079855, 18098927, 18116731, 18137520, 18178021, 18211726, 18251515, 18284058, 18318906, 18348795, 18381893, 18413984, 18385794, 18238181, 18083132, 18004264, 17978794, },\r
+{1, 25, 17992872, 18046029, 18083323, 18107369, 18125003, 18159920, 18198757, 18246054, 18288339, 18323397, 18363688, 18397947, 18419827, 18437650, 18326863, 18175731, 18072903, 18036998, 18041921, 18086790, 18132683, 18151840, 18172334, 18201634, 18241633, },\r
+{1, 25, 18280277, 18328649, 18360966, 18393786, 18427889, 18458489, 18489142, 18440892, 18280953, 18157545, 18109312, 18099846, 18130950, 18167428, 18186689, 18196051, 18218140, 18245394, 18281423, 18326343, 18353806, 18385672, 18425947, 18448209, 18458993, },\r
+{1, 25, 18341097, 18210494, 18144195, 18130724, 18152620, 18186845, 18208759, 18216545, 18225074, 18250648, 18280242, 18316842, 18345155, 18376137, 18410101, 18435917, 18441205, 18316322, 18164601, 18070164, 18030929, 18038593, 18076838, 18109606, 18123599, },\r
+{1, 25, 18142512, 18167600, 18200057, 18238667, 18275441, 18308173, 18347912, 18382396, 18418996, 18350165, 18151426, 18002043, 17926139, 17892957, 17907521, 17953743, 17981949, 17995438, 18020717, 18055428, 18094506, 18133914, 18178610, 18226202, 18259976, },\r
+{1, 25, 18294166, 18276880, 18110126, 17952684, 17876486, 17841759, 17863395, 17913900, 17951036, 17973922, 17990375, 18025693, 18066834, 18107629, 18149101, 18194490, 18236639, 18267154, 18244146, 18075798, 17928411, 17864385, 17840857, 17869222, 17916986, },\r
+{1, 25, 17947812, 17963589, 17987065, 18020179, 18058737, 18106920, 18152222, 18182442, 18224018, 18264015, 18229599, 18062657, 17916153, 17851278, 17835656, 17864037, 17920004, 17946772, 17964785, 17993687, 18028466, 18072122, 18117044, 18160128, 18199224, },\r
+{1, 25, 18242291, 18284820, 18317744, 18237767, 18067025, 17962792, 17931914, 17943547, 17994467, 18028275, 18046724, 18065013, 18097383, 18138871, 18173911, 18214966, 18245983, 18293229, 18325355, 18351969, 18273568, 18143624, 18071117, 18061338, 18095806, },\r
+{1, 25, 18148010, 18174778, 18191181, 18209089, 18239882, 18270829, 18318785, 18356545, 18391913, 18419185, 18435275, 18411574, 18257582, 18130395, 18080654, 18058148, 18091176, 18128193, 18142010, 18153090, 18175264, 18207910, 18249677, 18294426, 18339486, },\r
+{1, 25, 18377211, 18417192, 18453792, 18461334, 18306734, 18130759, 18034657, 17991192, 17987360, 18025449, 18062657, 18094124, 18115380, 18143709, 18187331, 18224381, 18273915, 18315056, 18356805, 18395018, 18437772, 18422844, 18250075, 18081901, 17985174, },\r
+{1, 25, 17949181, 17957833, 18009360, 18054958, 18078348, 18095616, 18139322, 18186983, 18238996, 18285738, 18332239, 18373432, 18417869, 18449318, 18483161, 18417938, 18240731, 18109381, 18042008, 18032176, 18065204, 18116455, 18145219, 18166265, 18193190, },\r
+{1, 25, 18232773, 18280624, 18321733, 18363203, 18408766, 18447099, 18482155, 18528552, 18550639, 18451139, 18291165, 18195878, 18168675, 18179061, 18224469, 18262229, 18288113, 18303632, 18334805, 18382102, 18422757, 18464871, 18504401, 18535261, 18574270, },\r
+{1, 25, 18611043, 18650382, 18626716, 18502960, 18405213, 18379016, 18393717, 18429901, 18466535, 18477198, 18495697, 18516207, 18551298, 18590533, 18626562, 18654994, 18690068, 18724189, 18758621, 18765799, 18656225, 18528430, 18455145, 18437390, 18454381, },\r
+{1, 25, 18494829, 18526037, 18534584, 18555668, 18583686, 18621238, 18657005, 18694767, 18726721, 18765781, 18794892, 18825163, 18806385, 18655445, 18493425, 18401312, 18368855, 18367573, 18404258, 18435882, 18450618, 18467748, 18499078, 18539889, 18576784, },\r
+{1, 25, 18620925, 18650833, 18691004, 18727206, 18764966, 18791753, 18668344, 18466241, 18326239, 18248689, 18216874, 18228975, 18277174, 18306944, 18317572, 18350061, 18380332, 18420764, 18463796, 18508838, 18542976, 18581640, 18619452, 18662710, 18694627, },\r
+{1, 25, 18624221, 18436299, 18284682, 18203194, 18169734, 18178645, 18219838, 18255260, 18278249, 18303093, 18336660, 18373172, 18422810, 18461212, 18498645, 18533180, 18567803, 18608235, 18639668, 18651995, 18515565, 18343889, 18231507, 18180152, 18178627, },\r
+{1, 25, 18212384, 18242238, 18259541, 18270535, 18310792, 18349212, 18392157, 18433316, 18465737, 18501124, 18534083, 18578484, 18613089, 18601404, 18442938, 18295535, 18215210, 18181922, 18194127, 18233951, 18258572, 18275319, 18290074, 18322513, 18361746, },\r
+{1, 25, 18401848, 18448938, 18494449, 18533788, 18569849, 18605409, 18651822, 18681589, 18636564, 18454156, 18307549, 18227537, 18193694, 18199936, 18249815, 18277867, 18298049, 18321887, 18351553, 18394619, 18425461, 18471044, 18512323, 18541312, 18577253, },\r
+{1, 25, 18607941, 18643206, 18681780, 18655150, 18505614, 18390249, 18326552, 18303077, 18331406, 18373414, 18393075, 18404969, 18422897, 18463449, 18501625, 18535765, 18575953, 18610090, 18642373, 18680445, 18713110, 18728263, 18609188, 18463292, 18377662, },\r
+{1, 25, 18351154, 18352627, 18390857, 18424665, 18439974, 18460034, 18494258, 18537203, 18573994, 18615777, 18646152, 18684659, 18716854, 18750906, 18784298, 18800942, 18686982, 18523316, 18425081, 18378806, 18366203, 18397151, 18437512, 18458109, 18480475, },\r
+{1, 25, 18501054, 18537914, 18588521, 18631657, 18668501, 18704355, 18743832, 18777847, 18817897, 18826758, 18706019, 18562740, 18481497, 18446112, 18443891, 18481948, 18515236, 18542386, 18572243, 18600189, 18644955, 18689964, 18731643, 18776114, 18815888, },\r
+{1, 25, 18847581, 18880209, 18907741, 18925096, 18832861, 18712242, 18630513, 18605062, 18619261, 18657109, 18678192, 18690450, 18700072, 18728748, 18756039, 18788234, 18818003, 18853197, 18873967, 18907465, 18934355, 18927490, 18824624, 18730221, 18697662, },\r
+{1, 25, 18700489, 18730430, 18755569, 18762973, 18766545, 18769196, 18774103, 18768400, 18768971, 18774485, 18790662, 18805554, 18831768, 18824313, 18694974, 18566867, 18500794, 18453325, 18447707, 18469136, 18486040, 18494189, 18506237, 18531742, 18563868, },\r
+{1, 25, 18607177, 18647123, 18691941, 18726078, 18757668, 18791111, 18732806, 18569138, 18437079, 18378910, 18353355, 18368024, 18408594, 18420469, 18432849, 18455578, 18485883, 18525830, 18560609, 18599011, 18642720, 18677776, 18708742, 18726893, 18610403, },\r
+{1, 25, 18442591, 18325217, 18259681, 18246383, 18271106, 18292882, 18320101, 18340370, 18371750, 18409114, 18447845, 18483630, 18535035, 18571983, 18610037, 18647417, 18658289, 18528430, 18374334, 18286327, 18247925, 18256680, 18299556, 18322564, 18341166, },\r
+{1, 25, 18359302, 18397064, 18434375, 18478827, 18520594, 18562013, 18598578, 18637570, 18644540, 18525015, 18396960, 18341827, 18333919, 18363826, 18401623, 18418007, 18428566, 18449387, 18484185, 18522311, 18552789, 18594417, 18623441, 18660855, 18688438, },\r
+{1, 25, 18595752, 18414679, 18295066, 18232183, 18215296, 18246089, 18294649, 18309353, 18323118, 18344443, 18382795, 18418683, 18471996, 18509289, 18546497, 18583200, 18614668, 18533459, 18327938, 18173287, 18096136, 18055547, 18060958, 18107873, 18146484, },\r
+{1, 25, 18157667, 18187469, 18227311, 18282758, 18322893, 18371681, 18421873, 18460952, 18508907, 18492263, 18302852, 18116612, 17993514, 17945801, 17925343, 17968288, 18025138, 18056813, 18091611, 18127152, 18170010, 18230710, 18274850, 18324610, 18360031, },\r
+{1, 25, 18402647, 18449960, 18463916, 18307132, 18095563, 17957002, 17890027, 17868962, 17900550, 17956585, 17986960, 18016469, 18048249, 18093777, 18141663, 18187487, 18229219, 18284265, 18321229, 18362961, 18405004, 18395676, 18222648, 18034535, 17917992, },\r
+{1, 25, 17871006, 17865632, 17914819, 17962394, 17990532, 18016347, 18054022, 18104803, 18150298, 18205744, 18247042, 18287317, 18325857, 18371421, 18415528, 18419586, 18268730, 18087675, 17976472, 17936664, 17922238, 17985747, 18035212, 18066090, 18096032, },\r
+{1, 25, 18130273, 18178419, 18228646, 18278562, 18318230, 18361122, 18404136, 18444602, 18476903, 18503881, 18418649, 18246054, 18125886, 18069245, 18057662, 18103885, 18157216, 18180882, 18201652, 18233744, 18273048, 18323638, 18370935, 18410951, 18453548, },\r
+{1, 25, 18489437, 18533579, 18565115, 18521079, 18381563, 18277745, 18242828, 18249000, 18295830, 18341946, 18362786, 18387752, 18413204, 18447949, 18492783, 18530962, 18572537, 18599791, 18643171, 18675592, 18687796, 18578883, 18425272, 18318333, 18272042, },\r
+{1, 25, 18270134, 18310670, 18355695, 18373727, 18397271, 18424421, 18473400, 18509047, 18554853, 18601975, 18636166, 18670441, 18707232, 18735926, 18670077, 18491379, 18349679, 18276861, 18251428, 18264171, 18324108, 18368300, 18402212, 18436349, 18473939, },\r
+{1, 25, 18521356, 18572363, 18611200, 18646812, 18683150, 18715572, 18749415, 18757634, 18617388, 18453514, 18355939, 18314796, 18310688, 18357881, 18406790, 18423728, 18454970, 18481428, 18521565, 18564666, 18611425, 18647539, 18687796, 18726078, 18757477, },\r
+{1, 25, 18775647, 18663680, 18491830, 18379345, 18322131, 18301862, 18330055, 18379517, 18402541, 18422202, 18446147, 18489092, 18532347, 18575589, 18614580, 18645475, 18682388, 18720946, 18751026, 18701996, 18521061, 18358349, 18273481, 18225804, 18221226, },\r
+{1, 25, 18274226, 18319148, 18339624, 18365318, 18399492, 18433369, 18487566, 18537689, 18578519, 18612985, 18653868, 18689115, 18706921, 18581831, 18399542, 18288617, 18225804, 18206957, 18243141, 18287144, 18313201, 18337491, 18373154, 18414904, 18455456, },\r
+{1, 25, 18505597, 18554437, 18595006, 18633010, 18675159, 18705117, 18658444, 18494935, 18354535, 18296454, 18268160, 18286242, 18338706, 18371508, 18394410, 18411956, 18453792, 18500534, 18545733, 18591557, 18623181, 18667495, 18703904, 18734764, 18732928, },\r
+{1, 25, 18595370, 18447099, 18373432, 18341376, 18361037, 18404693, 18435137, 18462894, 18491796, 18528672, 18567336, 18613957, 18653226, 18691872, 18728801, 18760909, 18796919, 18817674, 18723080, 18571566, 18471442, 18431825, 18440216, 18477145, 18510157, },\r
+{1, 25, 18533719, 18552425, 18576906, 18616072, 18656763, 18694316, 18729441, 18771781, 18798896, 18831526, 18850320, 18782825, 18633323, 18522483, 18480457, 18474475, 18512566, 18547882, 18561475, 18578119, 18598769, 18637500, 18679458, 18714912, 18750715, },\r
+{1, 25, 18782494, 18813356, 18844355, 18872651, 18818488, 18656798, 18537827, 18490010, 18474424, 18502477, 18536734, 18558754, 18566296, 18591939, 18632716, 18673944, 18714028, 18752119, 18786795, 18820412, 18851307, 18877730, 18837627, 18680254, 18561007, },\r
+{1, 25, 18507729, 18492993, 18523282, 18552061, 18572728, 18582038, 18609639, 18639979, 18679994, 18712815, 18744161, 18778473, 18807322, 18842430, 18863461, 18793695, 18663820, 18585713, 18564545, 18580859, 18620580, 18643084, 18651042, 18667060, 18685785, },\r
+{1, 25, 18713752, 18745201, 18777207, 18814067, 18842882, 18872287, 18888913, 18783189, 18638055, 18557210, 18529834, 18532920, 18571654, 18599220, 18610472, 18620164, 18645475, 18675695, 18715294, 18753698, 18784505, 18828820, 18854932, 18874731, 18762540, },\r
+{1, 25, 18568793, 18442296, 18373605, 18340439, 18353147, 18390180, 18404813, 18416603, 18444793, 18480891, 18517855, 18562811, 18607715, 18644175, 18676510, 18702482, 18660022, 18467437, 18280417, 18159209, 18085818, 18049064, 18070718, 18107769, 18133410, },\r
+{1, 25, 18144195, 18177934, 18217949, 18259352, 18301793, 18344478, 18395676, 18441118, 18470489, 18387112, 18179512, 18020473, 17930475, 17881323, 17876764, 17921408, 17961994, 17978032, 17999063, 18041244, 18078988, 18125053, 18174415, 18216301, 18259577, },\r
+{1, 25, 18302748, 18333314, 18222474, 18021843, 17882329, 17804032, 17774437, 17796837, 17842781, 17868389, 17899769, 17932728, 17973593, 18020648, 18073301, 18111861, 18161810, 18208743, 18246712, 18264917, 18120513, 17944675, 17828201, 17777800, 17771056, },\r
+{1, 25, 17819306, 17866118, 17883144, 17906566, 17943200, 17983008, 18026821, 18072382, 18122142, 18161133, 18201079, 18237732, 18184990, 18036268, 17925170, 17873001, 17882051, 17940583, 17976419, 17998421, 18020197, 18053520, 18095581, 18139150, 18183499, },\r
+{1, 25, 18229686, 18275943, 18311190, 18348379, 18271469, 18096637, 17983961, 17929053, 17918529, 17966138, 18013730, 18042528, 18069731, 18101024, 18137467, 18187243, 18235997, 18284005, 18324073, 18363272, 18405195, 18408663, 18244666, 18050017, 17932192, },\r
+{1, 25, 17876173, 17861211, 17897829, 17956012, 17988469, 18021705, 18052427, 18107058, 18153748, 18209749, 18256577, 18303735, 18350910, 18393025, 18424267, 18349905, 18161393, 18003171, 17913882, 17875931, 17886610, 17944813, 17990481, 18024064, 18061303, },\r
+{1, 25, 18108964, 18157442, 18208119, 18264206, 18315767, 18359891, 18403634, 18449578, 18480942, 18402594, 18224209, 18081623, 18010540, 17991208, 18022779, 18076562, 18116455, 18145078, 18183517, 18222821, 18276498, 18321351, 18369982, 18418216, 18456860, },\r
+{1, 25, 18496339, 18536458, 18571184, 18522430, 18364174, 18239396, 18179823, 18174622, 18211777, 18263962, 18298760, 18326154, 18357447, 18400357, 18443857, 18491830, 18534568, 18578639, 18613524, 18654925, 18683566, 18719455, 18699032, 18576489, 18463051, },\r
+{1, 25, 18416325, 18409929, 18458160, 18497464, 18525102, 18542317, 18570682, 18610297, 18655097, 18688629, 18727361, 18758881, 18790747, 18822838, 18846610, 18849834, 18755413, 18682422, 18658515, 18668153, 18711549, 18748946, 18763302, 18782374, 18804480, },\r
+{1, 25, 18834647, 18865645, 18897598, 18920779, 18949473, 18972653, 18998400, 19014125, 18940944, 18825301, 18743641, 18710249, 18712815, 18746345, 18778524, 18795637, 18803543, 18824868, 18851291, 18893281, 18928806, 18957639, 18983889, 19015356, 19039697, },\r
+{1, 25, 19047291, 18954518, 18795308, 18662970, 18597902, 18568931, 18587828, 18628608, 18652966, 18671136, 18693778, 18729234, 18775265, 18819234, 18860808, 18898553, 18922010, 18953114, 18987824, 18966914, 18794388, 18618083, 18506880, 18434685, 18418700, },\r
+{1, 25, 18454588, 18500845, 18532018, 18555442, 18585575, 18620787, 18656225, 18694924, 18734730, 18783847, 18818574, 18858018, 18889693, 18857809, 18687138, 18533475, 18447447, 18412458, 18414279, 18460310, 18497985, 18523524, 18549912, 18587465, 18629959, },\r
+{1, 25, 18670441, 18711948, 18749121, 18785720, 18821469, 18853562, 18881336, 18786655, 18627358, 18505301, 18452059, 18442835, 18481428, 18522483, 18543461, 18568722, 18598995, 18633010, 18680549, 18729459, 18762435, 18800473, 18834594, 18864674, 18901239, },\r
+{1, 25, 18899037, 18771712, 18628918, 18553484, 18522345, 18531153, 18578293, 18607766, 18620734, 18644660, 18669523, 18705932, 18751252, 18780952, 18816442, 18844442, 18877019, 18912873, 18925547, 18834387, 18718329, 18660144, 18653017, 18690692, 18727172, },\r
+{1, 25, 18751859, 18767203, 18791891, 18819112, 18859144, 18897062, 18930176, 18961800, 18990910, 19024770, 19043616, 18960449, 18831924, 18742255, 18709400, 18713648, 18755917, 18782720, 18804167, 18825285, 18845933, 18880469, 18924680, 18963031, 18993580, },\r
+{1, 25, 19025653, 19060868, 19091051, 19052822, 18889971, 18729425, 18641680, 18604767, 18599220, 18642529, 18672453, 18697246, 18715209, 18754131, 18793382, 18837888, 18878407, 18909094, 18954380, 18990250, 19003670, 18930679, 18747717, 18582229, 18485034, },\r
+{1, 25, 18439454, 18432085, 18479780, 18513954, 18542057, 18570873, 18608304, 18651422, 18699828, 18747144, 18789205, 18824486, 18870743, 18897477, 18821140, 18614044, 18455491, 18360636, 18320432, 18329187, 18379621, 18417399, 18444966, 18471702, 18512272, },\r
+{1, 25, 18560245, 18607057, 18651406, 18696084, 18740469, 18781645, 18813598, 18786379, 18602081, 18434287, 18333521, 18288304, 18293869, 18350945, 18385533, 18407968, 18438690, 18479573, 18522085, 18570109, 18620718, 18666038, 18705515, 18746520, 18783101, },\r
+{1, 25, 18805501, 18693241, 18509618, 18394861, 18340924, 18327714, 18371456, 18415441, 18431809, 18456653, 18490079, 18538294, 18595959, 18635247, 18678643, 18721970, 18760354, 18799278, 18819770, 18717565, 18580859, 18509637, 18486162, 18516953, 18562759, },\r
+{1, 25, 18582714, 18598735, 18622451, 18659433, 18692183, 18724656, 18764533, 18803508, 18836813, 18872927, 18889589, 18790869, 18648805, 18557072, 18517577, 18519952, 18568567, 18599340, 18621255, 18638713, 18672054, 18708256, 18757928, 18800457, 18841374, },\r
+{1, 25, 18878996, 18914157, 18951883, 18904915, 18734677, 18587412, 18503724, 18472378, 18486613, 18531898, 18570768, 18594521, 18623232, 18658669, 18710788, 18753351, 18797474, 18838408, 18879309, 18917520, 18941913, 18873707, 18688526, 18534948, 18441153, },\r
+{1, 25, 18400635, 18405697, 18458595, 18501140, 18529712, 18559447, 18603605, 18650955, 18699934, 18751878, 18789550, 18831786, 18875702, 18912406, 18854792, 18659571, 18493980, 18397340, 18342918, 18347582, 18392834, 18432952, 18457624, 18487393, 18530978, },\r
+{1, 25, 18580339, 18625970, 18672938, 18714219, 18761447, 18799658, 18830953, 18726495, 18536354, 18402438, 18328441, 18302748, 18335723, 18392088, 18422168, 18452335, 18488189, 18531065, 18576975, 18628571, 18665224, 18719508, 18754755, 18795914, 18761967, },\r
+{1, 25, 18599115, 18456202, 18382049, 18354915, 18383158, 18437530, 18466397, 18496615, 18526697, 18567440, 18612847, 18663594, 18708116, 18741648, 18787366, 18825216, 18786517, 18616974, 18478984, 18411454, 18389158, 18424214, 18471564, 18505041, 18521841, },\r
+{1, 25, 18550865, 18597883, 18637379, 18682977, 18729146, 18768469, 18803283, 18843869, 18807617, 18645302, 18504817, 18441916, 18422792, 18453306, 18501973, 18528603, 18552738, 18575727, 18613054, 18652810, 18688526, 18728592, 18767861, 18807495, 18836953, },\r
+{1, 25, 18842361, 18720184, 18581571, 18514421, 18494657, 18518842, 18563019, 18583460, 18599757, 18621793, 18647452, 18677723, 18716353, 18755707, 18786761, 18818956, 18852156, 18781785, 18644106, 18544867, 18503777, 18516380, 18553744, 18583078, 18596323, },\r
+{1, 25, 18607142, 18635385, 18668137, 18702309, 18740018, 18779617, 18818488, 18853231, 18818887, 18628987, 18481741, 18401536, 18356841, 18371004, 18416343, 18438725, 18460519, 18483421, 18520350, 18560678, 18600675, 18645302, 18677776, 18715729, 18755795, },\r
+{1, 25, 18676943, 18472533, 18302313, 18203507, 18155656, 18151391, 18193989, 18230432, 18252641, 18277591, 18302764, 18345622, 18390337, 18437790, 18483195, 18529523, 18561355, 18521339, 18327990, 18139497, 18035714, 17990826, 17980216, 18022867, 18059467, },\r
+{1, 25, 18088419, 18116177, 18154546, 18198964, 18248758, 18289883, 18338480, 18388256, 18433854, 18456929, 18318681, 18131886, 17998333, 17932797, 17918910, 17959966, 18016243, 18046740, 18071170, 18108653, 18157181, 18206992, 18257237, 18303250, 18350841, },\r
+{1, 25, 18393890, 18436142, 18414695, 18245237, 18079282, 17979593, 17950275, 17969745, 18027253, 18058548, 18081277, 18106538, 18145304, 18185996, 18234593, 18282843, 18322633, 18368353, 18407777, 18438204, 18372114, 18198826, 18073648, 18016920, 18009829, },\r
+{1, 25, 18051110, 18095372, 18118727, 18141819, 18178748, 18213546, 18261327, 18304792, 18351223, 18386176, 18428359, 18467143, 18486873, 18396873, 18253352, 18162001, 18125661, 18145513, 18197317, 18219406, 18232234, 18255571, 18283138, 18320952, 18360827, },\r
+{1, 25, 18400444, 18440789, 18482104, 18522465, 18539093, 18442193, 18321661, 18254531, 18245308, 18274643, 18325233, 18342918, 18367347, 18391064, 18425583, 18461663, 18504332, 18541675, 18579663, 18617181, 18650416, 18618672, 18447880, 18296905, 18219562, },\r
+{1, 25, 18176357, 18196693, 18235461, 18261467, 18268956, 18290923, 18318835, 18355661, 18397151, 18439489, 18477909, 18518912, 18559412, 18553274, 18386228, 18206679, 18082403, 18018931, 17992057, 18025831, 18057299, 18069071, 18080705, 18107300, 18146553, },\r
+{1, 25, 18192670, 18234646, 18275492, 18313220, 18361331, 18399455, 18379448, 18200647, 18010315, 17890911, 17830316, 17820052, 17853236, 17890391, 17906600, 17931826, 17964854, 18003415, 18050364, 18089841, 18126908, 18166318, 18210129, 18254220, 18239309, },\r
+{1, 25, 18067632, 17892453, 17799228, 17751915, 17753059, 17803824, 17837476, 17846525, 17859563, 17894083, 17937773, 17982019, 18033962, 18086288, 18120513, 18164792, 18198635, 18222266, 18083963, 17921251, 17816897, 17770414, 17765768, 17809320, 17845225, },\r
+{1, 25, 17862129, 17883715, 17911352, 17949720, 17993376, 18038418, 18086044, 18124586, 18159435, 18203091, 18232547, 18176928, 18017127, 17900950, 17841690, 17832553, 17877664, 17915461, 17941138, 17961285, 17983372, 18012881, 18050537, 18092251, 18125939, },\r
+{1, 25, 18166144, 18202311, 18238321, 18277469, 18241095, 18100660, 17988366, 17934116, 17928567, 17966866, 17996253, 18016071, 18034761, 18052931, 18087119, 18134538, 18167444, 18203784, 18246261, 18291894, 18332550, 18344773, 18258155, 18154424, 18108688, },\r
+{1, 25, 18102897, 18147419, 18179356, 18195982, 18206193, 18231974, 18262627, 18293176, 18330227, 18362770, 18402005, 18434824, 18471094, 18426762, 18271488, 18156487, 18099620, 18079648, 18103417, 18138282, 18145444, 18164705, 18181782, 18213875, 18248289, },\r
+{1, 25, 18286017, 18324973, 18361226, 18392035, 18420122, 18342052, 18155083, 18000154, 17909115, 17869135, 17863188, 17904018, 17923332, 17940809, 17954643, 17988347, 18025815, 18063559, 18102706, 18135856, 18175819, 18216527, 18179667, 17981100, 17796906, },\r
+{1, 25, 17680310, 17605707, 17575090, 17588163, 17622351, 17633414, 17643936, 17675682, 17707877, 17743888, 17774368, 17814330, 17846666, 17891638, 17901279, 17738185, 17546552, 17421080, 17339454, 17290061, 17297359, 17332502, 17347829, 17357884, 17385191, },\r
+{1, 25, 17414475, 17460939, 17498995, 17539462, 17571102, 17618590, 17655033, 17638631, 17465811, 17277750, 17158432, 17084921, 17060284, 17085303, 17113945, 17127919, 17145153, 17177764, 17213202, 17259129, 17304328, 17345454, 17384116, 17423922, 17469295, },\r
+{1, 25, 17474427, 17326573, 17156492, 17051251, 17000072, 16985474, 17031261, 17064429, 17084125, 17104930, 17138269, 17182583, 17220900, 17263550, 17304068, 17343754, 17383700, 17423508, 17453675, 17346718, 17189276, 17096643, 17065780, 17086691, 17140575, },\r
+{1, 25, 17172356, 17180208, 17201968, 17237544, 17281877, 17328341, 17372395, 17418410, 17461252, 17502687, 17543673, 17535837, 17398420, 17261903, 17196472, 17177557, 17218629, 17267175, 17293561, 17312875, 17340097, 17375741, 17421271, 17465620, 17507594, },\r
+{1, 25, 17544072, 17591698, 17629945, 17649641, 17521881, 17345661, 17240649, 17196454, 17182618, 17225565, 17269046, 17296197, 17317487, 17345245, 17391502, 17442007, 17494452, 17541176, 17591127, 17629547, 17662732, 17664083, 17509414, 17332693, 17218923, },\r
+{1, 25, 17173499, 17157983, 17197442, 17243733, 17269757, 17298972, 17336039, 17386993, 17434656, 17489718, 17534433, 17587537, 17625299, 17675509, 17714848, 17652276, 17471705, 17308560, 17214831, 17179863, 17179776, 17228546, 17271196, 17303271, 17327613, },\r
+{1, 25, 17357226, 17406776, 17455668, 17505773, 17559850, 17600765, 17645011, 17698308, 17728406, 17638649, 17465100, 17333855, 17269065, 17248069, 17278098, 17328845, 17367820, 17389368, 17415775, 17469035, 17511755, 17568276, 17621831, 17664412, 17707723, },\r
+{1, 25, 17752695, 17800425, 17795380, 17652589, 17519140, 17453381, 17424824, 17454923, 17503676, 17540205, 17561878, 17590814, 17636118, 17675544, 17733451, 17776048, 17828061, 17874387, 17918876, 17955718, 17882709, 17769287, 17699260, 17681265, 17701115, },\r
+{1, 25, 17750389, 17782775, 17799040, 17817677, 17856843, 17896667, 17936128, 17982193, 18019762, 18060558, 18093118, 18126805, 18055688, 17900411, 17788653, 17733294, 17730348, 17766513, 17799159, 17820954, 17840390, 17865425, 17891673, 17936266, 17982782, },\r
+{1, 25, 18022814, 18065915, 18106034, 18140676, 18136411, 17983719, 17809615, 17688425, 17631593, 17617080, 17642550, 17669613, 17682826, 17687332, 17709005, 17727729, 17764693, 17799889, 17827941, 17857743, 17898644, 17925083, 17890876, 17704289, 17527499, },\r
+{1, 25, 17420576, 17358023, 17330769, 17352145, 17381030, 17395854, 17417752, 17434985, 17469677, 17502496, 17543363, 17578626, 17616284, 17656281, 17702450, 17708416, 17566750, 17377267, 17252437, 17190542, 17154982, 17180192, 17212422, 17239677, 17254379, },\r
+{1, 25, 17274473, 17307034, 17352943, 17398038, 17447017, 17488938, 17538490, 17579615, 17619023, 17593778, 17420403, 17257967, 17165559, 17130711, 17133051, 17173932, 17197998, 17211087, 17225650, 17261401, 17292834, 17335381, 17377753, 17412065, 17451542, },\r
+{1, 25, 17479300, 17501370, 17403950, 17247201, 17142448, 17089361, 17070185, 17070307, 17074988, 17068139, 17068381, 17088008, 17120446, 17151811, 17183294, 17219860, 17246073, 17280993, 17310778, 17230140, 17077692, 16971343, 16916939, 16890983, 16910246, },\r
+{1, 25, 16943099, 16955288, 16970875, 16999170, 17037364, 17071711, 17111639, 17150596, 17191704, 17231510, 17265718, 17269550, 17124608, 16955601, 16854402, 16803238, 16791952, 16820142, 16865412, 16891087, 16907767, 16939615, 16977948, 17024518, 17067895, },\r
+{1, 25, 17115540, 17155104, 17206389, 17245693, 17226709, 17060874, 16883754, 16787393, 16734738, 16723590, 16752040, 16778203, 16802476, 16827026, 16859950, 16894555, 16947661, 16987087, 17034435, 17079356, 17116858, 17152365, 17092811, 16921031, 16786334, },\r
+{1, 25, 16721995, 16689556, 16708055, 16748659, 16771874, 16787496, 16810798, 16836874, 16879160, 16916278, 16954093, 16998928, 17039185, 17062834, 16997957, 16836717, 16716984, 16658850, 16643907, 16669427, 16710743, 16734374, 16751658, 16772949, 16806863, },\r
+{1, 25, 16851177, 16888504, 16932073, 16967391, 17013542, 17047369, 17015779, 16863955, 16727334, 16664486, 16633849, 16658868, 16709182, 16727265, 16735309, 16761092, 16793616, 16834931, 16874063, 16910992, 16953104, 16987294, 17022159, 17048496, 16966645, },\r
+{1, 25, 16829886, 16741638, 16713984, 16729728, 16774684, 16788900, 16794170, 16790999, 16795609, 16802805, 16822968, 16854765, 16885644, 16908824, 16932803, 16958443, 16880095, 16742505, 16652107, 16616391, 16614363, 16649939, 16678946, 16686592, 16699420, },\r
+{1, 25, 16723208, 16760970, 16793788, 16835122, 16880477, 16908373, 16958289, 17001077, 16979405, 16825431, 16686175, 16624922, 16596695, 16613219, 16657932, 16681356, 16705125, 16728064, 16761472, 16800065, 16835573, 16878102, 16920145, 16961288, 17004787, },\r
+{1, 25, 17042809, 16990017, 16832989, 16707829, 16646905, 16631527, 16660983, 16705714, 16736922, 16758160, 16784375, 16819189, 16861580, 16910453, 16953329, 16990518, 17034053, 17075403, 17092065, 16968551, 16827268, 16753844, 16735292, 16759495, 16810207, },\r
+{1, 25, 16828724, 16842561, 16863331, 16892960, 16925017, 16959900, 16996465, 17032389, 17067115, 17101324, 17092723, 16958358, 16823696, 16757520, 16738899, 16761020, 16800985, 16820230, 16835730, 16847136, 16877704, 16914269, 16951111, 16988074, 17020166, },\r
+{1, 25, 17044110, 17076339, 17093851, 16969020, 16775568, 16645709, 16567621, 16522977, 16518712, 16538302, 16539499, 16543522, 16552086, 16580902, 16618004, 16649697, 16686592, 16719307, 16745955, 16784323, 16813519, 16721666, 16550629, 16424517, 16342371, },\r
+{1, 25, 16302234, 16303449, 16336199, 16358842, 16383079, 16399447, 16432075, 16472628, 16511118, 16553941, 16594338, 16636970, 16674836, 16712529, 16662682, 16495288, 16371724, 16310020, 16276992, 16291208, 16338799, 16374133, 16380027, 16405514, 16440744, },\r
+{1, 25, 16474778, 16510650, 16541996, 16581231, 16613514, 16640022, 16655869, 16546314, 16405601, 16327547, 16287965, 16286561, 16305495, 16315879, 16321393, 16327149, 16351473, 16382264, 16415067, 16441888, 16477622, 16510407, 16543591, 16544042, 16404839, },\r
+{1, 25, 16285364, 16212981, 16181739, 16186091, 16214940, 16234947, 16244709, 16253724, 16277963, 16306395, 16337533, 16367475, 16398752, 16434346, 16465694, 16487330, 16389355, 16221009, 16093490, 16003248, 15943381, 15925662, 15937574, 15940366, 15947335, },\r
+{1, 25, 15953733, 15974347, 16002381, 16040350, 16073378, 16109702, 16148902, 16185656, 16189576, 16042709, 15894714, 15793290, 15739042, 15716433, 15731447, 15761527, 15786252, 15803018, 15826562, 15867981, 15913266, 15950906, 15983345, 16016182, 16052729, },\r
+{1, 25, 16082793, 16006022, 15856278, 15731949, 15646268, 15595018, 15596422, 15614193, 15625203, 15630075, 15644846, 15669430, 15702615, 15738002, 15768220, 15802758, 15835645, 15873511, 15865173, 15733390, 15616499, 15544409, 15513480, 15517606, 15539260, },\r
+{1, 25, 15545120, 15540473, 15546038, 15563810, 15580194, 15599993, 15625931, 15656064, 15680751, 15701575, 15649355, 15518023, 15400490, 15335787, 15296568, 15308791, 15335405, 15348061, 15367186, 15400699, 15461727, 15543334, 15629051, 15693460, 15741192, },\r
+{1, 25, 15779992, 15822799, 15794539, 15653030, 15535567, 15473326, 15443539, 15457410, 15503441, 15533295, 15544045, 15563064, 15596283, 15634757, 15668703, 15708960, 15756032, 15800571, 15836269, 15858584, 15770873, 15623938, 15520934, 15460339, 15427346, },\r
+{1, 25, 15434386, 15461623, 15485167, 15467448, 15441147, 15417463, 15412437, 15410755, 15422388, 15439258, 15469580, 15498691, 15512370, 15442639, 15311878, 15223716, 15205772, 15250364, 15372767, 15521403, 15636352, 15730962, 15806086, 15882162, 15940920, },\r
+};\r
+static const int16_t PAH831X_mems_RR[][3*127] = \r
+{\r
+{123, 361, -5155, 6017, 349, -5115, 6021, 305, -5015, 6037, 277, -4943, 6085, 253, -4915, 6121, 249, -4907, 6109, 237, -4935, 6121, 245, -4967, 6049, 289, -4999, 6025, 305, -5015, 6029, 297, -5063, 6009, 293, -5075, 6061, 273, -5067, 6069, 281, -5055, 6017, 289, -5059, 5993, 269, -5083, 5965, 269, -5035, 6005, 313, -5035, 6029, 313, -5087, 5997, 321, -5091, 5957, 313, -5067, 5961, 293, -5027, 5985, 301, -4971, 6009, 253, -4987, 6041, 245, -4995, 6065, 269, -4991, 6041, 265, -5015, 6037, 281, -5015, 6025, 281, -5047, 5993, 317, -5067, 5989, 289, -5043, 6005, 297, -5063, 5989, 325, -5099, 6017, 345, -5127, 6013, 349, -5123, 5993, 321, -5067, 6029, 305, -5063, 6021, 277, -5019, 6037, 257, -4991, 6045, 233, -4959, 6057, 245, -4963, 6057, 269, -4995, 6017, 277, -5031, 6013, 297, -5075, 5973, 285, -5079, 5949, 293, -5059, 5969, 293, -5099, 5957, 301, -5103, 5945, 305, -5087, 5957, 317, -5115, 5981, 301, -5095, 5981, 297, -5059, 5985, 305, -5015, 6009, 273, -5027, 6009, 285, -5047, 6049, 321, -5059, 6037, 317, -5059, 6021, 309, -5043, 6021, 313, -5043, 6021, 297, -5023, 6009, 281, -5023, 6009, 265, -5027, 6009, 281, -5007, 5993, 253, -5011, 5989, 261, -5007, 6017, 293, -5007, 6017, 285, -5023, 6013, 285, -5035, 6017, 301, -5055, 6021, 333, -5063, 6029, 349, -5071, 6001, 341, -5091, 6009, 333, -5107, 6025, 317, -5075, 5981, 277, -5035, 5985, 273, -5007, 5981, 269, -4995, 6013, 273, -5023, 6033, 257, -5027, 6033, 289, -5007, 6065, 309, -4987, 6045, 309, -4967, 6041, 337, -5019, 6061, 301, -5059, 6061, 313, -5067, 6065, 309, -5027, 6073, 305, -4955, 6105, 261, -4915, 6121, 265, -4899, 6093, 249, -4907, 6081, 277, -4947, 6073, 289, -4995, 6077, 285, -5019, 6053, 309, -5047, 5985, 313, -5087, 6001, 305, -5075, 5973, 301, -5051, 5949, 301, -5071, 5957, 317, -5095, 5973, 305, -5091, 5973, 305, -5059, 5961, 301, -5055, 5957, 289, -5059, 5997, 273, -5027, 6021, 281, -4995, 6005, 253, -4987, 6057, 281, -5027, 6065, 317, -5043, 6049, 313, -5055, 6029, 341, -5051, 6029, 329, -5035, 6001, 325, -5035, 6017, 297, -5035, 6037, 289, -4999, 6033, 285, -5023, 6041, 285, -5015, 6045, 277, -5015, 6037, 293, -5003, 6037, 289, -4991, 6069, 309, -4999, 6081, 285, -4999, 6053, 329, -5019, 6037, 321, -5027, 6001,                                                                                                                                                                                                                                                                },\r
+{124, 325, -5019, 6021, 317, -5035, 6033, 293, -5019, 6009, 285, -5031, 6033, 289, -5031, 6061, 277, -4967, 6053, 289, -4971, 6057, 305, -4971, 6045, 317, -4999, 6073, 297, -4999, 6045, 285, -4999, 6037, 273, -5003, 6057, 277, -4987, 6061, 297, -4991, 6041, 333, -5027, 6033, 309, -5023, 6021, 305, -5015, 6045, 309, -4999, 6021, 321, -5011, 6029, 317, -5027, 6041, 301, -5043, 6021, 289, -5011, 6037, 289, -4967, 6073, 277, -4975, 6065, 289, -4975, 6045, 285, -5007, 6049, 269, -5011, 6061, 313, -5015, 6033, 313, -5019, 6009, 289, -5015, 6005, 261, -4991, 6013, 269, -4987, 6013, 285, -4979, 6025, 305, -4995, 6041, 325, -5039, 6049, 325, -5087, 6061, 337, -5067, 6029, 321, -5047, 5993, 325, -5039, 5997, 289, -5019, 6009, 265, -5011, 6033, 273, -5003, 6037, 281, -4995, 6021, 301, -5015, 6045, 313, -5015, 6053, 289, -4979, 6061, 301, -4963, 6057, 301, -4979, 6061, 305, -4983, 6041, 321, -5015, 6065, 345, -5039, 6057, 345, -5063, 6029, 349, -5055, 6009, 317, -5031, 6045, 301, -5023, 6049, 253, -5027, 6037, 273, -4999, 6053, 273, -4975, 6045, 273, -4983, 6069, 289, -5003, 6041, 297, -4999, 6025, 293, -4999, 6017, 293, -5003, 6025, 285, -4979, 6053, 285, -4971, 6045, 317, -4991, 6025, 321, -5007, 6037, 301, -5031, 6017, 305, -5031, 6041, 289, -5003, 6037, 305, -4991, 6057, 317, -4995, 6029, 317, -5031, 6013, 317, -5043, 6021, 309, -5047, 6045, 341, -5039, 6009, 325, -5043, 6013, 309, -5015, 6001, 305, -5039, 6005, 305, -5079, 6025, 317, -5067, 6013, 305, -5059, 5997, 293, -5031, 6009, 313, -5011, 6033, 325, -5019, 6041, 313, -5019, 6021, 321, -5027, 6029, 305, -5027, 6053, 317, -5023, 6057, 325, -5031, 6033, 345, -5035, 5993, 313, -5051, 5997, 293, -5043, 5993, 297, -5051, 6005, 293, -5011, 6005, 285, -4971, 6017, 313, -4959, 6049, 321, -4983, 6061, 321, -5047, 6021, 309, -5071, 6025, 337, -5027, 6013, 333, -5023, 5985, 305, -5043, 6021, 293, -5059, 6009, 309, -5035, 6021, 317, -5031, 6045, 325, -5003, 6029, 337, -5039, 6033, 349, -5063, 6021, 337, -5059, 6013, 309, -5027, 6033, 293, -5003, 6049, 325, -5015, 6049, 321, -5023, 6013, 353, -5059, 6017, 333, -5063, 5993, 313, -5035, 6009, 309, -4995, 6029, 273, -4991, 6001, 301, -4995, 6013, 269, -5027, 6013, 277, -5031, 6029, 317, -5039, 6013, 321, -5039, 6025,                                                                                                                                                                                                                                },\r
+{125, 345, -5027, 6021, 369, -5047, 6005, 309, -5047, 6021, 313, -5031, 6041, 317, -5015, 6021, 289, -5027, 6029, 285, -5003, 6029, 305, -4995, 6029, 321, -5051, 6021, 313, -5059, 5997, 289, -5023, 6017, 289, -5023, 6029, 301, -5035, 6037, 325, -5055, 6017, 357, -5043, 6005, 345, -5043, 6025, 333, -5031, 6037, 325, -5011, 6033, 317, -4999, 6041, 289, -5003, 6049, 285, -5007, 6053, 289, -5031, 6065, 325, -5015, 6037, 301, -5003, 6013, 309, -4995, 6021, 317, -5011, 6049, 337, -5063, 6013, 321, -5071, 6009, 313, -5067, 6005, 309, -5039, 6017, 297, -5015, 6041, 293, -4983, 6045, 301, -5003, 6037, 297, -5031, 6045, 289, -5039, 6025, 301, -5039, 6045, 289, -5011, 6033, 297, -4967, 6021, 289, -4979, 6045, 265, -4987, 6037, 277, -5015, 6029, 313, -5039, 6029, 337, -5039, 6021, 313, -5019, 6013, 289, -5019, 6017, 273, -5015, 6025, 265, -5003, 6033, 273, -5003, 6017, 285, -4999, 6045, 277, -5027, 6041, 301, -5011, 6077, 301, -5031, 6053, 313, -5011, 6041, 301, -5011, 6009, 301, -4983, 6013, 293, -4991, 6041, 265, -4971, 6065, 277, -4999, 6041, 289, -5031, 6033, 309, -5015, 6053, 305, -4999, 6073, 305, -4991, 6073, 313, -5035, 6025, 289, -5059, 6013, 297, -5071, 6013, 277, -5071, 6025, 297, -5067, 6041, 325, -5035, 6029, 317, -5011, 6025, 313, -5039, 6037, 277, -5035, 6005, 257, -4987, 6009, 245, -4975, 6021, 253, -4975, 6069, 265, -5003, 6057, 297, -5011, 6021, 309, -5035, 6037, 285, -5031, 5989, 293, -5039, 6009, 285, -5019, 6021, 257, -4995, 6025, 293, -4999, 6017, 293, -5027, 6029, 289, -5063, 6009, 289, -5063, 5993, 293, -5035, 6017, 273, -4999, 6033, 257, -4983, 6069, 293, -4991, 6065, 305, -5023, 6077, 289, -5047, 6049, 297, -5015, 6049, 305, -5007, 6041, 285, -5019, 6013, 297, -5063, 5997, 281, -5043, 5997, 285, -5019, 5989, 273, -5019, 6017, 269, -5015, 6065, 289, -5015, 6077, 305, -5027, 6073, 321, -5039, 6061, 309, -5007, 6057, 293, -5003, 6041, 293, -4991, 6033, 281, -4991, 6037, 265, -5003, 6029, 265, -4999, 5997, 273, -5023, 6013, 297, -5031, 6009, 281, -5039, 6001, 265, -5023, 6005, 265, -5019, 6017, 261, -4995, 6029, 265, -5003, 6037, 269, -5011, 6045, 297, -5035, 6045, 289, -5027, 6025, 305, -5023, 6049, 301, -5035, 6033, 293, -5023, 6017, 293, -5011, 6017, 269, -5019, 6009, 261, -5031, 6017, 269, -5051, 6017,                                                                                                                                                                                                },\r
+{124, 261, -5039, 6009, 277, -5007, 6009, 273, -5007, 6041, 309, -5019, 6049, 325, -5043, 6057, 317, -5055, 6049, 293, -5043, 6033, 293, -5047, 6045, 293, -5035, 6009, 269, -5027, 6005, 257, -5011, 6025, 229, -4999, 6025, 249, -5007, 6021, 265, -5003, 6021, 265, -5003, 6001, 293, -5035, 6017, 293, -5039, 6009, 317, -5019, 6013, 293, -5019, 6009, 297, -5027, 6009, 301, -5043, 6049, 281, -5011, 6041, 269, -5035, 6029, 277, -5043, 6021, 253, -5035, 6021, 281, -5035, 6045, 281, -5019, 6029, 301, -5035, 6049, 313, -5035, 6053, 313, -5047, 6005, 337, -5059, 6013, 313, -5055, 5997, 281, -5023, 6021, 253, -5003, 6033, 245, -4983, 6013, 261, -5011, 6025, 277, -5011, 6033, 289, -5035, 6009, 285, -5047, 6021, 289, -5047, 6001, 285, -5039, 6001, 309, -5039, 6005, 285, -5047, 6001, 281, -5059, 6009, 285, -5067, 6001, 285, -5067, 6001, 285, -5039, 6017, 257, -5015, 6029, 269, -5003, 6033, 277, -4999, 6053, 289, -5015, 6037, 293, -5043, 6037, 309, -5067, 6017, 289, -5055, 6001, 281, -5031, 6001, 293, -5043, 5981, 289, -5047, 5985, 261, -5035, 6009, 285, -5043, 6017, 277, -5039, 6013, 289, -5051, 6017, 297, -5071, 6017, 305, -5047, 6017, 281, -5039, 6013, 277, -5003, 6041, 289, -5019, 6021, 277, -5023, 6021, 277, -5031, 6013, 281, -5027, 6001, 261, -5027, 6033, 265, -5035, 6009, 277, -5019, 6009, 269, -5019, 5997, 265, -5047, 6021, 253, -5023, 6017, 285, -5031, 6021, 269, -4999, 6041, 265, -5027, 6053, 297, -5051, 6025, 317, -5051, 6033, 309, -5047, 6029, 297, -5043, 6025, 281, -5043, 5997, 261, -5027, 6017, 277, -5051, 6009, 293, -5035, 6001, 277, -5007, 6025, 269, -5011, 6041, 265, -5007, 6041, 273, -5027, 6029, 297, -5023, 6029, 297, -5047, 6033, 313, -5047, 6025, 297, -5035, 6029, 317, -4999, 6001, 309, -5059, 6005, 297, -5067, 6025, 253, -5035, 6013, 269, -5023, 6013, 261, -5007, 6009, 269, -4999, 6029, 269, -4991, 6029, 289, -5011, 6053, 269, -4999, 6033, 289, -5003, 6037, 289, -4995, 6049, 309, -5031, 6057, 289, -5043, 6017, 289, -5091, 5989, 277, -5083, 5989, 265, -5051, 5985, 285, -5027, 6033, 293, -5019, 6013, 309, -5051, 6013, 313, -5071, 6025, 305, -5047, 6037, 301, -5023, 6037, 289, -5019, 6029, 281, -5003, 6017, 281, -4995, 6025, 305, -4995, 6009, 301, -5023, 6025, 293, -5059, 6001, 277, -5063, 5997,                                                                                                                                                                                                                                },\r
+{125, 289, -5059, 5985, 285, -5055, 5957, 269, -5059, 5957, 273, -5059, 5977, 273, -5051, 6005, 301, -5039, 6021, 305, -5083, 6045, 337, -5087, 6045, 333, -5079, 5997, 329, -5047, 6017, 289, -5015, 6001, 289, -4999, 5993, 281, -5019, 6013, 301, -5055, 5989, 321, -5071, 5989, 301, -5087, 5989, 289, -5071, 6001, 293, -5035, 6005, 293, -5011, 6017, 301, -5007, 6009, 313, -5051, 6001, 309, -5087, 6001, 333, -5091, 6005, 329, -5063, 6025, 317, -5043, 6017, 317, -5047, 6005, 301, -5075, 5985, 285, -5067, 6001, 289, -5039, 5993, 277, -5023, 6021, 289, -5031, 6025, 289, -5039, 6029, 301, -5071, 5997, 313, -5055, 6001, 321, -5067, 5993, 333, -5075, 5973, 321, -5087, 5989, 317, -5087, 5993, 297, -5067, 5985, 289, -5047, 5989, 289, -5031, 6001, 285, -5015, 6017, 285, -5043, 6013, 329, -5059, 5993, 305, -5083, 6005, 293, -5063, 6025, 313, -5059, 6017, 321, -5063, 6021, 329, -5051, 6013, 325, -5071, 5997, 305, -5075, 6001, 285, -5067, 5993, 309, -5059, 5989, 325, -5071, 5981, 297, -5047, 6013, 281, -5047, 5997, 269, -5027, 5977, 297, -5023, 5993, 285, -5035, 5989, 281, -5051, 5985, 309, -5075, 6009, 341, -5119, 6005, 345, -5103, 5993, 345, -5087, 6001, 325, -5099, 5985, 321, -5067, 5981, 321, -5059, 5989, 281, -5051, 5997, 289, -5055, 6009, 281, -5023, 5993, 281, -5039, 6017, 297, -5051, 6009, 301, -5071, 6021, 309, -5091, 5993, 309, -5087, 5981, 317, -5075, 5985, 341, -5075, 5985, 337, -5063, 5945, 333, -5107, 5977, 313, -5107, 5993, 301, -5075, 6009, 293, -5043, 6029, 281, -5023, 6021, 293, -5043, 6033, 309, -5063, 6013, 329, -5059, 5973, 313, -5047, 5969, 333, -5039, 5981, 345, -4975, 6005, 325, -5115, 6021, 301, -5187, 5925, 301, -5091, 5933, 261, -5047, 5973, 273, -5019, 5981, 285, -5055, 5973, 277, -5083, 5977, 285, -5095, 5977, 293, -5083, 5993, 305, -5063, 5981, 309, -5075, 5997, 337, -5083, 6017, 313, -5067, 6001, 333, -5039, 6017, 317, -5051, 6013, 313, -5059, 6005, 301, -5051, 6013, 309, -5067, 6017, 289, -5075, 6021, 289, -5047, 5997, 309, -5047, 6001, 309, -5043, 5985, 325, -5051, 5985, 333, -5087, 5997, 321, -5099, 6001, 333, -5083, 5993, 345, -5051, 6009, 317, -5047, 6025, 317, -5059, 6025, 297, -5035, 6009, 297, -4991, 6009, 281, -5011, 6005, 269, -5055, 6001, 269, -5087, 5989, 277, -5071, 5981, 289, -5047, 5973,                                                                                                                                                                                                },\r
+{125, 285, -5067, 5965, 305, -5083, 5957, 293, -5059, 5973, 309, -5051, 6001, 301, -5059, 5989, 269, -5059, 5977, 281, -5047, 6009, 297, -5059, 6033, 293, -5031, 6013, 305, -5043, 6009, 289, -5031, 6021, 305, -5027, 6021, 309, -5059, 6017, 313, -5075, 6029, 297, -5039, 5981, 273, -5023, 5981, 285, -5031, 5977, 273, -5039, 5997, 297, -5071, 5985, 305, -5075, 5993, 301, -5063, 5997, 341, -5067, 6009, 365, -5075, 5989, 337, -5063, 6001, 301, -5039, 6005, 277, -5027, 6017, 269, -5031, 6001, 265, -5039, 6013, 273, -5059, 5977, 293, -5059, 5981, 285, -5027, 5993, 285, -5031, 5989, 305, -5035, 5997, 281, -5051, 5997, 333, -5079, 6001, 317, -5071, 5985, 341, -5063, 5981, 321, -5075, 6013, 313, -5071, 5981, 297, -5059, 5993, 285, -5059, 5997, 277, -5055, 6005, 293, -5039, 6009, 297, -5051, 6013, 301, -5059, 6001, 301, -5067, 6009, 325, -5067, 6021, 325, -5023, 5997, 301, -5059, 6025, 321, -5071, 5977, 337, -5047, 5969, 309, -5059, 5993, 309, -5071, 5993, 297, -5075, 5965, 297, -5055, 6001, 297, -5011, 6033, 285, -5031, 6005, 325, -5063, 5997, 289, -5087, 6005, 297, -5099, 5993, 293, -5059, 5981, 289, -5067, 5993, 301, -5063, 5969, 309, -5087, 5961, 285, -5091, 5997, 305, -5055, 5985, 305, -5063, 5985, 313, -5055, 6005, 337, -5051, 6017, 325, -5063, 6029, 317, -5063, 6001, 313, -5051, 6013, 289, -5043, 6025, 293, -5047, 5993, 285, -5075, 5981, 301, -5071, 5969, 313, -5051, 5981, 297, -5071, 5993, 293, -5067, 5969, 313, -5035, 5985, 321, -5043, 6005, 317, -5051, 6025, 313, -5067, 5989, 333, -5075, 5985, 313, -5095, 5961, 329, -5059, 6009, 289, -5043, 6017, 289, -5067, 5973, 289, -5095, 5965, 285, -5075, 5973, 301, -5039, 5997, 285, -5035, 6025, 305, -5039, 6001, 289, -5059, 5993, 289, -5087, 6009, 309, -5079, 5985, 301, -5079, 5981, 289, -5075, 5985, 309, -5067, 5973, 301, -5075, 5977, 317, -5063, 5985, 321, -5083, 5989, 305, -5079, 5997, 305, -5059, 5989, 305, -5067, 5985, 301, -5059, 5969, 293, -5071, 6009, 301, -5067, 5965, 293, -5043, 5997, 293, -5043, 5997, 301, -5063, 6001, 317, -5071, 5997, 313, -5063, 6001, 329, -5059, 5997, 313, -5071, 5989, 297, -5095, 5981, 301, -5091, 5953, 317, -5063, 5973, 301, -5059, 5989, 313, -5095, 5977, 305, -5071, 5969, 321, -5047, 5977, 297, -5031, 5989, 285, -5051, 6009, 305, -5083, 6005,                                                                                                                                                                                                },\r
+{125, 325, -5099, 5985, 341, -5103, 5977, 349, -5111, 5973, 313, -5095, 5997, 293, -5055, 5989, 301, -5035, 6021, 297, -5055, 6013, 305, -5075, 6021, 321, -5079, 6017, 333, -5083, 6013, 345, -5095, 6009, 333, -5079, 5985, 329, -5071, 5985, 281, -5059, 5977, 285, -5051, 5977, 325, -5067, 5969, 297, -5091, 5961, 285, -5095, 5969, 293, -5087, 5969, 293, -5059, 5981, 297, -5043, 6005, 309, -5035, 5993, 317, -5051, 5993, 293, -5071, 6009, 329, -5079, 6009, 325, -5071, 6009, 309, -5071, 5973, 309, -5087, 6001, 309, -5079, 5985, 297, -5067, 5977, 297, -5039, 5977, 309, -5079, 5981, 305, -5079, 6001, 317, -5043, 5997, 329, -5071, 6001, 349, -5071, 5989, 321, -5075, 5981, 317, -5055, 6013, 297, -5059, 6013, 289, -5051, 5997, 317, -5079, 6005, 313, -5083, 6001, 309, -5083, 5981, 305, -5059, 5989, 285, -5039, 5981, 289, -5055, 5989, 305, -5059, 5997, 317, -5063, 6001, 301, -5075, 5981, 297, -5063, 5989, 293, -5059, 5969, 297, -5071, 5977, 281, -5047, 5993, 285, -5059, 6001, 305, -5039, 6005, 317, -5071, 6001, 313, -5067, 5993, 317, -5075, 5993, 301, -5059, 5989, 293, -5051, 6005, 301, -5059, 5993, 289, -5075, 6001, 309, -5067, 5981, 309, -5075, 5997, 309, -5079, 5965, 329, -5095, 5985, 317, -5079, 5977, 305, -5039, 5997, 317, -5023, 5997, 301, -5063, 6009, 309, -5087, 6009, 329, -5091, 5993, 321, -5079, 5989, 297, -5035, 6001, 281, -5031, 5985, 273, -5043, 5985, 277, -5083, 5993, 305, -5103, 5981, 325, -5099, 6009, 321, -5107, 5997, 333, -5091, 5973, 309, -5063, 5953, 285, -5039, 5985, 285, -5031, 5993, 297, -5047, 6001, 333, -5067, 6009, 305, -5091, 5981, 317, -5091, 5989, 301, -5035, 5977, 285, -5031, 5985, 297, -5031, 5969, 285, -5079, 5985, 305, -5103, 6013, 337, -5091, 5985, 345, -5095, 5989, 333, -5095, 5989, 325, -5099, 5973, 305, -5083, 5981, 281, -5055, 5997, 285, -5043, 5997, 285, -5055, 6013, 305, -5071, 5985, 301, -5087, 5973, 325, -5087, 5957, 325, -5055, 5965, 325, -5055, 5981, 313, -5059, 5981, 301, -5079, 5993, 309, -5059, 6013, 321, -5071, 6009, 337, -5087, 5981, 317, -5095, 5945, 277, -5099, 5965, 269, -5091, 5973, 277, -5071, 5973, 285, -5059, 5969, 325, -5075, 5985, 345, -5099, 5985, 341, -5099, 5985, 337, -5091, 5977, 329, -5079, 5973, 317, -5063, 6001, 301, -5043, 6005, 301, -5067, 6013, 301, -5059, 6013,                                                                                                                                                                                                },\r
+{124, 305, -5059, 5993, 301, -5075, 5981, 289, -5087, 5977, 293, -5107, 5985, 317, -5091, 5985, 325, -5079, 5985, 321, -5075, 5957, 333, -5067, 5973, 329, -5059, 5997, 329, -5071, 6005, 333, -5059, 5985, 349, -5043, 6025, 325, -5043, 6021, 297, -5067, 5981, 317, -5079, 5985, 321, -5075, 5993, 313, -5083, 5949, 301, -5083, 5945, 305, -5087, 5965, 301, -5091, 5973, 301, -5115, 5977, 305, -5091, 5965, 317, -5087, 5937, 329, -5063, 5973, 321, -5059, 5993, 325, -5071, 6009, 349, -5099, 5993, 341, -5075, 6013, 353, -5087, 5993, 321, -5087, 5997, 321, -5099, 5981, 305, -5087, 5985, 329, -5087, 5973, 321, -5075, 5973, 313, -5083, 5969, 317, -5103, 5985, 329, -5099, 5973, 321, -5083, 5981, 313, -5055, 5977, 313, -5051, 5977, 305, -5067, 6001, 313, -5091, 6009, 333, -5091, 5993, 305, -5087, 5985, 321, -5059, 5977, 297, -5079, 5985, 289, -5087, 5973, 301, -5083, 5973, 285, -5091, 5965, 293, -5075, 5965, 273, -5047, 5997, 289, -5039, 6009, 317, -5067, 5969, 321, -5071, 5985, 329, -5079, 5997, 329, -5095, 5981, 317, -5099, 5965, 337, -5091, 5989, 321, -5099, 5985, 301, -5099, 5993, 317, -5095, 5993, 317, -5067, 5993, 313, -5023, 6009, 321, -5027, 6001, 313, -5023, 6013, 289, -5111, 6037, 289, -5127, 5945, 309, -5071, 5953, 297, -5031, 5985, 301, -5043, 5953, 293, -5083, 5957, 273, -5111, 5961, 277, -5115, 5969, 289, -5075, 5977, 289, -5079, 5977, 289, -5083, 5993, 297, -5079, 5981, 281, -5075, 5989, 313, -5067, 5985, 317, -5051, 6009, 301, -5079, 6001, 309, -5091, 5981, 317, -5075, 5989, 305, -5055, 6001, 293, -5055, 6005, 301, -5063, 6009, 285, -5051, 6005, 277, -5047, 5997, 301, -5087, 5977, 309, -5111, 5965, 305, -5111, 5985, 305, -5083, 5981, 305, -5059, 5993, 293, -5067, 5997, 297, -5063, 5997, 317, -5063, 6005, 309, -5055, 6005, 313, -5055, 5997, 281, -5055, 6005, 281, -5047, 5989, 281, -5055, 6005, 289, -5059, 5985, 277, -5079, 5989, 281, -5079, 5981, 297, -5071, 5981, 305, -5079, 5981, 281, -5075, 5993, 289, -5087, 5969, 269, -5075, 5981, 265, -5059, 6001, 277, -5035, 5985, 289, -5039, 6013, 297, -5035, 6001, 301, -5051, 6005, 313, -5083, 5993, 289, -5063, 5985, 309, -5063, 5985, 301, -5067, 5993, 297, -5099, 5997, 289, -5099, 5977, 297, -5075, 5977, 269, -5039, 6001, 273, -5043, 5997, 289, -5079, 5981,                                                                                                                                                                                                                                },\r
+{125, 289, -5091, 5985, 273, -5059, 6013, 285, -5055, 6013, 301, -5067, 6005, 293, -5059, 5993, 317, -5051, 5997, 281, -5059, 6001, 289, -5071, 5977, 269, -5055, 6009, 273, -5047, 6005, 261, -5031, 5973, 281, -5067, 5985, 297, -5071, 5949, 281, -5067, 5993, 293, -5075, 5989, 281, -5079, 6001, 297, -5087, 6001, 305, -5079, 6025, 297, -5071, 6005, 269, -5071, 5989, 269, -5063, 6013, 269, -5051, 5993, 273, -5047, 5985, 281, -5075, 5993, 301, -5071, 5973, 313, -5091, 5977, 313, -5091, 5969, 289, -5075, 5981, 281, -5055, 6013, 273, -5031, 6005, 285, -5035, 5989, 281, -5067, 5981, 297, -5091, 5997, 305, -5091, 5997, 285, -5107, 5953, 285, -5127, 5949, 257, -5099, 5957, 265, -5067, 5965, 257, -5043, 5969, 273, -5059, 6005, 273, -5075, 6033, 289, -5067, 5981, 329, -5115, 5949, 325, -5171, 5925, 289, -5167, 5921, 269, -5119, 5929, 277, -5075, 5921, 261, -5083, 5933, 277, -5127, 5945, 325, -5131, 5957, 337, -5143, 5941, 321, -5167, 5929, 293, -5155, 5929, 273, -5123, 5921, 257, -5119, 5925, 265, -5131, 5925, 277, -5135, 5945, 277, -5131, 5957, 293, -5119, 5969, 329, -5103, 5985, 329, -5107, 5973, 289, -5103, 5957, 285, -5103, 5945, 293, -5067, 5969, 265, -5079, 5945, 253, -5095, 5933, 249, -5119, 5949, 281, -5107, 5961, 293, -5123, 5945, 301, -5123, 5953, 293, -5103, 5953, 277, -5079, 5969, 301, -5087, 5989, 293, -5111, 5977, 305, -5115, 5953, 325, -5115, 5949, 281, -5135, 5941, 297, -5119, 5949, 289, -5115, 5945, 285, -5079, 5961, 265, -5111, 5969, 289, -5107, 5985, 301, -5107, 5981, 313, -5103, 5969, 309, -5079, 5961, 293, -5083, 5985, 269, -5091, 5985, 285, -5103, 5965, 289, -5107, 5969, 289, -5095, 5949, 293, -5095, 5949, 269, -5103, 5953, 281, -5091, 5953, 305, -5091, 5977, 293, -5103, 5981, 305, -5107, 5953, 305, -5115, 5941, 293, -5083, 5937, 265, -5063, 5973, 269, -5051, 5977, 281, -5055, 5989, 297, -5071, 5989, 301, -5095, 5973, 317, -5091, 5985, 333, -5107, 5977, 309, -5143, 5957, 305, -5151, 5949, 301, -5147, 5973, 305, -5107, 5977, 301, -5095, 5981, 317, -5071, 5989, 309, -5083, 5997, 309, -5095, 5993, 309, -5083, 5997, 297, -5079, 5973, 285, -5079, 5989, 293, -5063, 5977, 293, -5079, 5977, 305, -5099, 5941, 313, -5115, 5937, 317, -5115, 5961, 309, -5095, 5957, 297, -5099, 5945, 281, -5091, 5941, 261, -5083, 5981,                                                                                                                                                                                                },\r
+{125, 277, -5083, 6001, 305, -5071, 5997, 321, -5079, 5973, 289, -5083, 5985, 297, -5067, 5997, 305, -5063, 5997, 313, -5079, 5965, 321, -5107, 5953, 317, -5127, 5941, 309, -5131, 5933, 317, -5111, 5953, 317, -5103, 5957, 333, -5083, 5981, 309, -5079, 5997, 325, -5087, 6001, 337, -5099, 5985, 313, -5107, 5977, 297, -5103, 5965, 309, -5083, 5981, 305, -5071, 5961, 317, -5079, 5965, 317, -5071, 5977, 321, -5051, 6029, 317, -5087, 5981, 301, -5107, 5965, 313, -5111, 5973, 317, -5107, 5957, 317, -5091, 5961, 305, -5087, 5969, 297, -5091, 5993, 297, -5071, 5973, 297, -5083, 5981, 309, -5087, 5973, 313, -5083, 5965, 317, -5087, 5965, 309, -5115, 5981, 309, -5123, 5953, 293, -5099, 5981, 289, -5071, 5981, 313, -5071, 5993, 309, -5099, 5977, 337, -5111, 5981, 341, -5107, 5965, 313, -5119, 5969, 317, -5111, 5969, 309, -5115, 5953, 313, -5115, 5961, 317, -5111, 5973, 317, -5095, 5977, 321, -5067, 5981, 309, -5067, 5989, 305, -5063, 5985, 301, -5091, 6005, 317, -5131, 5953, 337, -5139, 5921, 313, -5095, 5925, 313, -5067, 5961, 293, -5075, 5989, 301, -5099, 5985, 305, -5111, 5945, 309, -5095, 5957, 333, -5095, 5949, 329, -5103, 5953, 293, -5087, 5949, 297, -5051, 5977, 309, -5047, 6013, 309, -5071, 6001, 333, -5107, 5985, 325, -5115, 5973, 321, -5111, 5969, 321, -5111, 5953, 317, -5103, 5973, 317, -5095, 5941, 305, -5107, 5953, 317, -5115, 5949, 321, -5115, 5937, 313, -5091, 5985, 321, -5091, 5989, 337, -5071, 5989, 329, -5083, 5993, 313, -5095, 5989, 313, -5107, 5993, 309, -5103, 5981, 309, -5079, 5981, 309, -5071, 5961, 309, -5083, 5953, 301, -5103, 5933, 297, -5103, 5949, 313, -5079, 5949, 309, -5091, 5973, 313, -5095, 5981, 309, -5099, 5961, 305, -5083, 5977, 301, -5095, 5961, 297, -5099, 5953, 321, -5099, 5965, 305, -5099, 5973, 301, -5087, 5969, 317, -5059, 5965, 305, -5079, 5957, 305, -5083, 5973, 301, -5099, 5977, 329, -5095, 5997, 325, -5107, 5981, 341, -5095, 5977, 337, -5091, 5949, 309, -5099, 5961, 297, -5095, 5969, 309, -5115, 5977, 321, -5099, 5981, 317, -5087, 5985, 293, -5087, 5989, 313, -5079, 5989, 309, -5079, 5989, 317, -5059, 5969, 305, -5087, 5953, 293, -5067, 5961, 293, -5083, 5973, 293, -5071, 5977, 301, -5071, 5977, 321, -5091, 5961, 329, -5119, 5985, 313, -5095, 5965, 309, -5083, 5949, 317, -5087, 5981,                                                                                                                                                                                                },\r
+{125, 293, -5095, 5973, 313, -5099, 5961, 285, -5103, 5973, 305, -5099, 5977, 301, -5091, 5969, 309, -5071, 5981, 329, -5087, 5993, 325, -5087, 5993, 309, -5091, 5997, 321, -5099, 5993, 325, -5103, 5965, 329, -5075, 5957, 301, -5051, 5973, 301, -5059, 5973, 309, -5083, 5973, 325, -5119, 5981, 321, -5119, 5981, 313, -5095, 5965, 297, -5107, 5953, 309, -5103, 5961, 313, -5079, 5977, 301, -5059, 5945, 313, -5067, 5969, 305, -5099, 5985, 321, -5127, 5961, 329, -5123, 5965, 313, -5103, 5965, 309, -5083, 5997, 305, -5067, 5985, 305, -5075, 6013, 321, -5079, 5997, 305, -5095, 5989, 313, -5099, 5953, 297, -5103, 5941, 289, -5103, 5969, 289, -5075, 5965, 297, -5099, 5961, 345, -5095, 5981, 317, -5115, 5969, 333, -5115, 5977, 337, -5119, 5953, 309, -5099, 5961, 301, -5099, 6005, 297, -5087, 5957, 325, -5095, 5973, 313, -5087, 5985, 301, -5083, 5965, 309, -5075, 5949, 313, -5063, 5961, 313, -5095, 5957, 309, -5107, 5937, 321, -5123, 5941, 309, -5111, 5953, 309, -5107, 5949, 325, -5091, 5961, 301, -5067, 5977, 313, -5103, 5993, 301, -5095, 5969, 321, -5091, 5965, 317, -5107, 5977, 321, -5111, 5985, 325, -5115, 5965, 301, -5087, 5961, 317, -5087, 5981, 309, -5087, 5977, 301, -5115, 5961, 313, -5139, 5957, 325, -5115, 5961, 349, -5095, 5981, 321, -5075, 5985, 313, -5091, 5981, 313, -5103, 5965, 313, -5103, 5965, 317, -5083, 5981, 305, -5119, 5969, 329, -5111, 5981, 325, -5123, 5945, 313, -5115, 5961, 309, -5095, 5945, 321, -5099, 5953, 309, -5099, 5957, 281, -5087, 5981, 301, -5103, 5981, 297, -5103, 5961, 321, -5091, 5985, 309, -5111, 5953, 273, -5103, 5925, 289, -5099, 5937, 277, -5103, 5941, 293, -5087, 5957, 317, -5099, 5977, 345, -5115, 5973, 353, -5111, 5945, 333, -5115, 5949, 309, -5111, 5973, 285, -5119, 5965, 309, -5111, 5965, 353, -5131, 5945, 349, -5107, 5953, 317, -5079, 5945, 289, -5063, 5949, 281, -5051, 5977, 301, -5079, 6005, 325, -5083, 5981, 353, -5107, 5989, 349, -5127, 5949, 329, -5135, 5941, 329, -5119, 5941, 317, -5079, 5945, 289, -5079, 5957, 313, -5119, 5945, 329, -5131, 5957, 313, -5135, 5945, 317, -5127, 5953, 273, -5111, 5965, 277, -5083, 5961, 309, -5055, 5953, 317, -5063, 5965, 333, -5067, 5977, 325, -5103, 5997, 321, -5131, 6001, 313, -5131, 5977, 313, -5155, 5933, 333, -5111, 5913, 289, -5095, 5941,                                                                                                                                                                                                },\r
+{125, 305, -5099, 5949, 313, -5103, 5969, 325, -5119, 5961, 337, -5119, 5985, 337, -5115, 5997, 325, -5111, 5965, 341, -5107, 5977, 337, -5107, 5949, 325, -5091, 5957, 293, -5099, 5957, 309, -5107, 5953, 317, -5103, 5949, 305, -5099, 5973, 313, -5119, 5937, 305, -5111, 5957, 293, -5111, 5937, 293, -5095, 5941, 301, -5095, 5945, 293, -5099, 5941, 317, -5103, 5929, 341, -5135, 5969, 325, -5151, 5969, 317, -5123, 5957, 317, -5111, 5973, 321, -5083, 5961, 325, -5111, 5949, 301, -5123, 5949, 317, -5119, 5953, 321, -5127, 5953, 305, -5123, 5961, 321, -5135, 5969, 337, -5115, 5933, 337, -5127, 5933, 353, -5115, 5929, 317, -5095, 5945, 317, -5103, 5961, 313, -5103, 5985, 313, -5111, 5981, 321, -5107, 5957, 345, -5107, 5953, 325, -5103, 5941, 317, -5091, 5941, 293, -5087, 5985, 301, -5087, 5973, 321, -5119, 5949, 349, -5103, 5929, 321, -5127, 5949, 297, -5107, 5937, 285, -5075, 5945, 293, -5067, 5969, 297, -5083, 5949, 305, -5107, 5969, 325, -5119, 5957, 341, -5111, 5949, 309, -5107, 5957, 313, -5111, 5957, 321, -5119, 5953, 313, -5127, 5969, 317, -5111, 5969, 301, -5111, 5957, 297, -5087, 5977, 305, -5091, 5965, 333, -5123, 5985, 333, -5123, 5973, 329, -5087, 5973, 317, -5111, 5969, 313, -5095, 5949, 309, -5103, 5957, 301, -5111, 5945, 297, -5107, 5953, 317, -5103, 5941, 309, -5087, 5949, 301, -5099, 5957, 329, -5099, 5965, 325, -5115, 5957, 321, -5115, 5981, 321, -5099, 5953, 313, -5111, 5953, 313, -5115, 5961, 309, -5107, 5961, 317, -5103, 5949, 305, -5103, 5953, 297, -5083, 5937, 309, -5095, 5965, 325, -5103, 5973, 325, -5119, 5961, 317, -5123, 5953, 317, -5115, 5933, 321, -5115, 5953, 309, -5115, 5961, 333, -5115, 5969, 337, -5135, 5953, 341, -5107, 5949, 305, -5127, 5937, 305, -5111, 5969, 313, -5139, 5957, 337, -5115, 5945, 329, -5107, 5949, 321, -5091, 5973, 329, -5087, 5989, 309, -5115, 5969, 317, -5123, 5957, 325, -5111, 5949, 321, -5087, 5945, 325, -5087, 5941, 301, -5127, 5941, 305, -5147, 5929, 309, -5119, 5941, 313, -5091, 5953, 305, -5095, 5961, 309, -5099, 5965, 353, -5115, 5965, 349, -5111, 5937, 333, -5095, 5949, 305, -5119, 5977, 309, -5099, 5945, 317, -5115, 5969, 325, -5119, 5965, 321, -5123, 5965, 329, -5103, 5973, 333, -5107, 5917, 305, -5127, 5953, 293, -5127, 5945, 313, -5119, 5961, 317, -5095, 5981,                                                                                                                                                                                                },\r
+{124, 329, -5091, 5981, 341, -5115, 5973, 333, -5115, 5965, 325, -5095, 5981, 337, -5095, 5985, 329, -5099, 5953, 337, -5107, 5945, 317, -5107, 5961, 313, -5107, 5957, 317, -5123, 5937, 317, -5123, 5941, 297, -5115, 5949, 297, -5095, 5949, 297, -5083, 5957, 317, -5103, 5957, 305, -5119, 5961, 325, -5131, 5969, 325, -5103, 5957, 341, -5103, 5957, 345, -5099, 5993, 349, -5131, 5977, 341, -5123, 5941, 329, -5123, 5941, 325, -5103, 5937, 313, -5095, 5965, 329, -5107, 5977, 305, -5123, 5961, 325, -5115, 5969, 329, -5103, 5957, 313, -5091, 5949, 325, -5083, 5977, 325, -5107, 5961, 325, -5135, 5969, 341, -5099, 5961, 321, -5099, 5949, 301, -5111, 5973, 313, -5095, 5969, 321, -5111, 5965, 329, -5091, 5965, 325, -5099, 5961, 329, -5107, 5973, 313, -5123, 5945, 313, -5111, 5953, 305, -5099, 5949, 309, -5087, 5957, 313, -5091, 5957, 313, -5107, 5949, 349, -5107, 5961, 341, -5099, 5957, 329, -5107, 5957, 313, -5127, 5957, 309, -5139, 5941, 313, -5119, 5957, 321, -5107, 5945, 305, -5119, 5937, 337, -5111, 5953, 349, -5147, 5961, 325, -5123, 5953, 329, -5107, 5969, 333, -5099, 5961, 345, -5091, 5965, 333, -5103, 5953, 325, -5099, 5949, 321, -5099, 5937, 325, -5095, 5929, 337, -5111, 5937, 333, -5107, 5945, 333, -5123, 5953, 333, -5131, 5941, 317, -5127, 5949, 321, -5119, 5949, 321, -5107, 5961, 317, -5115, 5953, 337, -5127, 5937, 345, -5135, 5961, 329, -5103, 5969, 333, -5095, 5945, 345, -5135, 5949, 329, -5135, 5945, 309, -5131, 5941, 329, -5119, 5949, 357, -5095, 5969, 373, -5111, 5961, 353, -5131, 5945, 341, -5151, 5973, 353, -5127, 5969, 361, -5115, 5997, 361, -5111, 5993, 353, -5115, 5977, 333, -5123, 5949, 337, -5095, 5961, 337, -5075, 5949, 325, -5123, 5941, 321, -5135, 5937, 329, -5107, 5945, 337, -5107, 5953, 329, -5099, 5933, 345, -5131, 5933, 341, -5107, 5953, 345, -5119, 5929, 349, -5111, 5941, 325, -5123, 5949, 333, -5115, 5957, 337, -5091, 5981, 329, -5083, 5981, 317, -5123, 5945, 325, -5131, 5941, 329, -5111, 5949, 333, -5111, 5957, 317, -5135, 5945, 325, -5119, 5945, 325, -5139, 5945, 341, -5127, 5933, 329, -5127, 5945, 317, -5135, 5949, 305, -5119, 5945, 329, -5115, 5961, 313, -5107, 5977, 333, -5127, 5965, 345, -5143, 5965, 333, -5119, 5945, 313, -5115, 5961, 313, -5095, 5973, 325, -5099, 5961,                                                                                                                                                                                                                                },\r
+{124, 329, -5111, 5949, 333, -5115, 5937, 305, -5119, 5957, 317, -5115, 5949, 321, -5099, 5941, 321, -5095, 5949, 317, -5083, 5949, 313, -5111, 5985, 333, -5107, 5961, 345, -5115, 5969, 337, -5123, 5965, 317, -5115, 5969, 293, -5123, 5937, 297, -5135, 5945, 317, -5107, 5945, 305, -5107, 5937, 317, -5119, 5953, 325, -5135, 5965, 341, -5139, 5969, 321, -5111, 5977, 309, -5063, 5965, 297, -5055, 5965, 309, -5071, 5973, 305, -5107, 5973, 325, -5123, 5961, 317, -5127, 5949, 317, -5115, 5953, 317, -5111, 5945, 313, -5111, 5941, 309, -5119, 5949, 305, -5115, 5953, 297, -5087, 5949, 313, -5099, 5973, 317, -5083, 5957, 317, -5079, 5977, 313, -5055, 5981, 325, -5059, 5989, 333, -5119, 5989, 317, -5139, 5941, 345, -5131, 5981, 321, -5123, 5973, 329, -5099, 5961, 329, -5079, 5957, 321, -5095, 5985, 317, -5107, 5949, 317, -5091, 5993, 305, -5135, 5965, 313, -5119, 5957, 293, -5063, 5969, 301, -5087, 5985, 313, -5095, 5969, 321, -5103, 5949, 309, -5107, 5965, 321, -5103, 5965, 321, -5103, 5961, 301, -5119, 5953, 301, -5091, 5949, 301, -5083, 5977, 293, -5083, 5965, 301, -5087, 5957, 289, -5103, 5961, 269, -5099, 5953, 277, -5087, 5969, 309, -5071, 5961, 313, -5079, 5973, 329, -5099, 5969, 317, -5115, 5977, 317, -5095, 5953, 309, -5103, 5961, 305, -5079, 5977, 305, -5107, 5969, 305, -5111, 5973, 289, -5087, 5957, 313, -5095, 5953, 301, -5091, 5965, 305, -5107, 5965, 297, -5107, 5957, 293, -5087, 5973, 305, -5083, 5997, 305, -5095, 5985, 329, -5091, 5981, 329, -5107, 5949, 297, -5119, 5969, 305, -5111, 5957, 281, -5067, 5961, 277, -5063, 5965, 281, -5087, 5965, 293, -5091, 5977, 305, -5091, 5957, 313, -5067, 5973, 313, -5075, 5981, 297, -5059, 6005, 305, -5083, 5993, 321, -5099, 5985, 321, -5131, 5969, 325, -5099, 5965, 321, -5127, 5973, 301, -5131, 5981, 305, -5131, 5961, 321, -5103, 5937, 313, -5099, 5965, 309, -5091, 5969, 321, -5111, 5977, 321, -5099, 5973, 301, -5075, 5977, 309, -5051, 5977, 301, -5071, 5949, 297, -5095, 5953, 305, -5095, 5945, 309, -5111, 5945, 301, -5099, 5929, 305, -5103, 5965, 289, -5123, 5957, 297, -5115, 5957, 309, -5103, 5957, 317, -5095, 5969, 305, -5103, 5957, 313, -5095, 5977, 317, -5123, 5985, 321, -5099, 5965, 329, -5087, 5977, 329, -5103, 5961, 321, -5123, 5965, 301, -5139, 5965,                                                                                                                                                                                                                                },\r
+{124, 297, -5135, 5957, 313, -5111, 5961, 329, -5095, 5965, 337, -5079, 5969, 341, -5087, 5969, 329, -5127, 5973, 321, -5115, 5965, 325, -5107, 5989, 333, -5103, 5981, 341, -5099, 5953, 321, -5119, 5953, 341, -5099, 5969, 337, -5091, 5977, 341, -5091, 5997, 337, -5103, 5977, 337, -5119, 5949, 329, -5107, 5933, 321, -5115, 5925, 313, -5115, 5941, 321, -5111, 5929, 321, -5143, 5941, 325, -5139, 5949, 345, -5115, 5969, 341, -5111, 5965, 345, -5123, 5957, 325, -5103, 5953, 329, -5107, 5965, 313, -5111, 5957, 313, -5115, 5977, 321, -5111, 5957, 325, -5131, 5937, 333, -5135, 5937, 345, -5139, 5937, 345, -5147, 5945, 329, -5131, 5953, 345, -5127, 5969, 337, -5107, 5961, 349, -5111, 5953, 333, -5119, 5965, 321, -5123, 5965, 329, -5087, 5937, 333, -5087, 5961, 357, -5107, 5985, 325, -5103, 5957, 337, -5107, 5961, 333, -5103, 5961, 345, -5135, 5941, 325, -5155, 5925, 317, -5139, 5925, 321, -5115, 5937, 321, -5119, 5949, 337, -5119, 5953, 345, -5107, 5957, 357, -5115, 5957, 341, -5095, 5953, 337, -5115, 5977, 329, -5119, 5965, 337, -5115, 5945, 325, -5111, 5953, 325, -5139, 5965, 357, -5131, 5949, 345, -5131, 5961, 345, -5143, 5941, 353, -5107, 5945, 341, -5111, 5949, 329, -5119, 5941, 337, -5135, 5953, 341, -5123, 5961, 349, -5111, 5941, 341, -5115, 5965, 337, -5095, 5945, 313, -5099, 5941, 321, -5107, 5949, 321, -5115, 5941, 337, -5111, 5945, 333, -5119, 5933, 313, -5107, 5945, 317, -5123, 5933, 325, -5107, 5949, 329, -5087, 5969, 341, -5099, 5981, 333, -5111, 5957, 341, -5131, 5961, 333, -5119, 5961, 333, -5107, 5957, 333, -5095, 5953, 357, -5119, 5961, 341, -5127, 5949, 325, -5131, 5941, 313, -5111, 5965, 321, -5087, 5977, 333, -5095, 5997, 341, -5099, 5981, 337, -5111, 5977, 361, -5119, 5961, 337, -5115, 5953, 329, -5111, 5961, 321, -5111, 5945, 317, -5071, 5989, 341, -5103, 5989, 321, -5103, 5969, 337, -5087, 5969, 313, -5087, 5985, 325, -5079, 5973, 337, -5095, 5969, 305, -5115, 5953, 285, -5103, 5957, 313, -5087, 5953, 325, -5083, 5937, 325, -5111, 5965, 305, -5123, 5961, 341, -5111, 5973, 345, -5107, 5969, 321, -5115, 5977, 333, -5111, 5969, 321, -5091, 5981, 333, -5111, 5973, 341, -5107, 5957, 301, -5111, 5953, 313, -5107, 5969, 325, -5111, 5973, 333, -5095, 5957, 333, -5087, 5957, 337, -5095, 5969,                                                                                                                                                                                                                                },\r
+{124, 329, -5119, 5977, 333, -5111, 5981, 353, -5083, 5993, 337, -5079, 5973, 345, -5087, 5961, 325, -5099, 5969, 345, -5115, 5957, 329, -5099, 5965, 325, -5087, 5969, 325, -5079, 5949, 309, -5103, 5957, 321, -5107, 5949, 329, -5107, 5965, 313, -5099, 5953, 301, -5095, 5961, 317, -5083, 5965, 321, -5075, 5977, 321, -5103, 5953, 329, -5091, 5969, 325, -5111, 5993, 345, -5123, 5981, 353, -5115, 5957, 365, -5119, 5973, 337, -5111, 5953, 325, -5103, 5949, 329, -5107, 5949, 321, -5115, 5961, 333, -5119, 5985, 349, -5103, 5985, 369, -5123, 5965, 353, -5111, 5973, 329, -5095, 5989, 325, -5067, 5985, 333, -5067, 5957, 329, -5091, 5953, 309, -5099, 5937, 313, -5115, 5945, 305, -5111, 5937, 313, -5111, 5957, 337, -5119, 5953, 341, -5103, 5957, 321, -5103, 5969, 325, -5103, 5969, 313, -5099, 5969, 321, -5083, 5977, 317, -5083, 5993, 313, -5083, 5965, 337, -5111, 5973, 345, -5091, 5973, 337, -5095, 5953, 309, -5087, 5941, 317, -5099, 5969, 313, -5115, 5949, 337, -5107, 5981, 337, -5103, 5977, 341, -5095, 5985, 321, -5091, 5993, 309, -5111, 5981, 325, -5075, 5993, 325, -5083, 5985, 325, -5087, 5965, 325, -5099, 5981, 325, -5091, 5977, 321, -5083, 5949, 321, -5075, 5981, 293, -5087, 5969, 317, -5095, 5973, 329, -5087, 5965, 317, -5063, 5953, 325, -5059, 5973, 317, -5111, 5977, 309, -5119, 5945, 305, -5075, 5937, 293, -5063, 5977, 305, -5083, 5969, 305, -5103, 5969, 325, -5091, 5965, 329, -5083, 5985, 313, -5087, 5973, 293, -5075, 5957, 301, -5079, 5985, 317, -5087, 5957, 329, -5107, 5989, 321, -5111, 5989, 337, -5131, 5969, 337, -5107, 5961, 341, -5087, 5965, 325, -5083, 5969, 313, -5083, 5973, 341, -5087, 5965, 329, -5091, 5981, 329, -5091, 5993, 325, -5083, 5977, 313, -5063, 5977, 313, -5059, 5965, 309, -5079, 5957, 305, -5087, 5957, 301, -5099, 5973, 309, -5119, 5953, 329, -5123, 5957, 333, -5103, 5945, 301, -5079, 5933, 309, -5055, 5965, 309, -5051, 5985, 321, -5075, 5965, 345, -5099, 5965, 321, -5119, 5977, 309, -5079, 5973, 321, -5087, 5985, 305, -5087, 5997, 309, -5083, 5989, 329, -5103, 5973, 333, -5107, 5965, 317, -5111, 5973, 345, -5135, 5957, 329, -5111, 5969, 329, -5091, 5981, 333, -5083, 5961, 333, -5083, 5977, 325, -5099, 5977, 317, -5083, 5981, 341, -5043, 5973, 337, -5063, 5973, 317, -5103, 5993,                                                                                                                                                                                                                                },\r
+{123, 317, -5107, 5969, 293, -5079, 5981, 317, -5071, 5977, 301, -5139, 5941, 305, -5111, 5929, 309, -5103, 5949, 305, -5107, 5977, 329, -5115, 5961, 317, -5107, 5965, 313, -5107, 5969, 325, -5063, 5965, 341, -5071, 5965, 337, -5083, 5985, 305, -5087, 5989, 301, -5087, 5953, 329, -5083, 5973, 325, -5099, 5953, 321, -5099, 5953, 325, -5095, 5965, 313, -5079, 5961, 317, -5091, 5977, 325, -5107, 5985, 345, -5095, 5981, 333, -5099, 5985, 321, -5083, 5977, 305, -5083, 5973, 301, -5071, 5973, 317, -5075, 5977, 329, -5103, 5973, 333, -5091, 5969, 333, -5087, 5985, 325, -5095, 5965, 317, -5059, 5969, 305, -5079, 5957, 281, -5083, 5961, 285, -5099, 5965, 321, -5091, 5977, 313, -5083, 5961, 301, -5079, 5989, 309, -5091, 5993, 317, -5095, 5973, 321, -5115, 5973, 321, -5107, 5977, 309, -5099, 5989, 301, -5083, 5985, 313, -5087, 5969, 313, -5083, 5957, 321, -5067, 5969, 321, -5075, 6005, 329, -5103, 5997, 333, -5091, 5981, 313, -5079, 5977, 305, -5083, 5981, 309, -5091, 5977, 321, -5103, 5941, 309, -5103, 5961, 309, -5063, 5965, 321, -5071, 5985, 309, -5063, 5989, 309, -5091, 5973, 309, -5091, 5973, 301, -5083, 5977, 305, -5087, 5977, 297, -5075, 5969, 301, -5063, 5969, 297, -5083, 5981, 309, -5063, 5985, 305, -5051, 5985, 317, -5071, 5973, 309, -5079, 5981, 325, -5103, 5985, 321, -5123, 5973, 325, -5099, 5969, 329, -5063, 5985, 313, -5087, 5957, 305, -5095, 5953, 309, -5099, 5965, 297, -5079, 5989, 321, -5067, 5993, 329, -5091, 5989, 321, -5091, 5969, 297, -5087, 5981, 309, -5083, 5985, 317, -5079, 5945, 329, -5075, 5949, 301, -5087, 5965, 297, -5111, 5945, 285, -5099, 5949, 309, -5055, 5957, 289, -5095, 5973, 309, -5095, 5965, 305, -5095, 5981, 325, -5091, 5969, 321, -5083, 5977, 341, -5083, 5981, 321, -5103, 5957, 325, -5115, 5965, 321, -5107, 5973, 309, -5095, 5969, 309, -5099, 5985, 333, -5095, 5977, 321, -5103, 5961, 325, -5087, 5945, 321, -5091, 5977, 313, -5091, 5977, 317, -5103, 5989, 313, -5091, 5973, 321, -5063, 6009, 329, -5083, 6013, 329, -5111, 5969, 329, -5051, 5965, 325, -5035, 6013, 301, -5107, 5965, 301, -5119, 5961, 305, -5087, 5993, 325, -5071, 5969, 321, -5059, 5969, 317, -5091, 5973, 313, -5083, 5965, 313, -5091, 5977, 329, -5095, 5961, 325, -5091, 5973, 317, -5091, 5985,                                                                                                                                                                                                                                                                },\r
+{124, 285, -5087, 5989, 277, -5059, 5989, 297, -5075, 5969, 325, -5099, 5977, 309, -5087, 5973, 301, -5063, 5973, 317, -5091, 5997, 329, -5107, 5993, 341, -5095, 5969, 325, -5067, 5981, 301, -5067, 5997, 297, -5099, 5973, 305, -5099, 5961, 281, -5063, 5977, 289, -5063, 5985, 281, -5063, 5981, 305, -5075, 5985, 321, -5083, 5997, 321, -5107, 5993, 305, -5071, 5985, 293, -5071, 5965, 277, -5055, 5985, 297, -5039, 5977, 309, -5051, 5989, 281, -5091, 5985, 297, -5095, 5965, 297, -5079, 5969, 281, -5075, 5981, 289, -5075, 5985, 289, -5059, 6005, 273, -5067, 5989, 297, -5055, 5981, 297, -5063, 5981, 285, -5063, 6005, 297, -5067, 6001, 297, -5067, 5997, 301, -5079, 6009, 305, -5091, 5977, 309, -5091, 5997, 285, -5083, 5993, 305, -5071, 5969, 305, -5067, 5977, 289, -5087, 5997, 277, -5079, 5969, 293, -5071, 5993, 305, -5079, 5989, 305, -5071, 5989, 301, -5083, 5973, 281, -5083, 5965, 301, -5063, 5981, 297, -5055, 5977, 313, -5075, 5961, 297, -5099, 5969, 301, -5095, 5961, 281, -5083, 5989, 285, -5091, 5981, 281, -5087, 5985, 285, -5079, 5981, 293, -5071, 5993, 277, -5087, 5981, 301, -5079, 5989, 309, -5063, 5981, 309, -5067, 5969, 309, -5083, 5969, 301, -5079, 5993, 297, -5067, 6001, 305, -5055, 5997, 317, -5063, 5973, 321, -5055, 5981, 309, -5087, 6017, 285, -5159, 5981, 289, -5115, 5965, 293, -5071, 5989, 285, -5071, 5997, 301, -5083, 5977, 309, -5091, 5993, 313, -5087, 5989, 305, -5055, 6009, 301, -5051, 5981, 293, -5079, 5981, 313, -5087, 5973, 289, -5091, 5953, 305, -5071, 5965, 273, -5087, 5953, 289, -5055, 5949, 289, -5067, 5973, 297, -5075, 5981, 289, -5099, 6021, 297, -5083, 6005, 317, -5079, 5981, 313, -5063, 5961, 281, -5075, 5989, 289, -5083, 5977, 293, -5083, 5993, 305, -5079, 5985, 297, -5083, 5977, 297, -5095, 5985, 297, -5091, 5989, 301, -5071, 5985, 293, -5075, 5961, 293, -5079, 5981, 293, -5083, 5981, 305, -5087, 5985, 301, -5099, 5977, 293, -5079, 5969, 305, -5079, 5997, 301, -5095, 5977, 289, -5087, 5977, 289, -5079, 6001, 301, -5075, 5985, 285, -5063, 5969, 285, -5067, 5977, 289, -5055, 5985, 285, -5067, 5989, 305, -5083, 5989, 297, -5075, 6001, 285, -5079, 5989, 281, -5079, 5989, 309, -5055, 6009, 309, -5079, 5985, 305, -5091, 5985, 285, -5095, 5985, 285, -5095, 5977, 285, -5083, 5981,                                                                                                                                                                                                                                },\r
+{124, 305, -5079, 5993, 301, -5051, 5993, 309, -5075, 5993, 289, -5075, 5989, 277, -5083, 5989, 289, -5063, 5997, 293, -5063, 5985, 285, -5059, 6005, 285, -5059, 5997, 277, -5059, 5977, 277, -5059, 5977, 293, -5075, 5981, 281, -5087, 5973, 269, -5103, 5961, 269, -5083, 5961, 281, -5079, 5973, 281, -5071, 5981, 253, -5079, 5985, 281, -5083, 5993, 293, -5075, 6005, 277, -5027, 6025, 297, -5035, 6033, 309, -5059, 6009, 293, -5091, 5997, 281, -5111, 5973, 273, -5115, 5977, 253, -5079, 5993, 289, -5059, 5993, 317, -5039, 5989, 305, -5059, 6005, 281, -5103, 6013, 253, -5115, 5985, 269, -5063, 5993, 257, -5047, 6021, 253, -5051, 6013, 277, -5063, 5993, 289, -5075, 6001, 281, -5071, 5993, 273, -5051, 5993, 281, -5067, 6005, 297, -5083, 5993, 281, -5095, 5973, 289, -5087, 5977, 261, -5055, 5981, 261, -5043, 5997, 237, -5039, 5993, 249, -5071, 5985, 269, -5063, 5997, 285, -5075, 6005, 281, -5079, 5981, 289, -5071, 5981, 261, -5071, 6001, 261, -5071, 5989, 261, -5067, 5977, 273, -5059, 5989, 269, -5055, 5993, 253, -5071, 6005, 269, -5059, 5989, 289, -5083, 6001, 277, -5095, 6001, 281, -5075, 5997, 281, -5075, 5989, 281, -5051, 5985, 257, -5043, 6001, 249, -5071, 6005, 245, -5059, 5969, 257, -5051, 5977, 281, -5047, 5997, 269, -5051, 5989, 253, -5087, 5989, 261, -5079, 5993, 265, -5071, 5989, 273, -5059, 5997, 281, -5075, 5973, 293, -5087, 5969, 273, -5067, 5985, 249, -5031, 5993, 253, -5019, 5969, 249, -5023, 6037, 269, -5051, 6005, 273, -5067, 6009, 269, -5079, 6001, 265, -5107, 5969, 285, -5091, 5997, 285, -5083, 5997, 273, -5079, 5985, 265, -5067, 6001, 273, -5083, 6009, 273, -5091, 6017, 285, -5075, 5989, 269, -5067, 6009, 257, -5047, 5981, 273, -5031, 6001, 261, -5043, 5993, 253, -5059, 5981, 249, -5039, 5973, 261, -5063, 5973, 265, -5079, 5973, 265, -5079, 5985, 269, -5079, 5985, 261, -5059, 5997, 285, -5055, 5997, 257, -5087, 6005, 265, -5067, 5997, 261, -5067, 5985, 269, -5055, 5989, 257, -5067, 5997, 269, -5059, 6001, 293, -5051, 6005, 293, -5067, 6005, 289, -5067, 6001, 265, -5071, 5997, 277, -5055, 6001, 277, -5063, 6001, 277, -5075, 5993, 281, -5079, 6001, 285, -5071, 5969, 269, -5083, 5969, 261, -5051, 6017, 249, -5051, 6017, 273, -5083, 6009, 261, -5083, 5993, 293, -5051, 6001, 305, -5047, 6017,                                                                                                                                                                                                                                },\r
+{123, 289, -5059, 6021, 289, -5055, 5997, 273, -5071, 5985, 261, -5059, 5981, 249, -5059, 5965, 241, -5071, 5949, 273, -5071, 5977, 273, -5067, 6001, 273, -5063, 5993, 273, -5083, 5993, 277, -5083, 5977, 269, -5075, 6005, 265, -5047, 5989, 265, -5059, 5989, 285, -5059, 5993, 253, -5047, 5989, 289, -5067, 5997, 265, -5087, 5985, 281, -5103, 5969, 265, -5079, 5977, 257, -5063, 5993, 257, -5059, 5997, 277, -5063, 5985, 285, -5067, 5993, 261, -5071, 5965, 265, -5083, 5993, 265, -5079, 5965, 285, -5071, 5977, 261, -5079, 5953, 269, -5067, 5977, 261, -5079, 5969, 269, -5075, 5965, 277, -5071, 5965, 301, -5059, 5993, 305, -5083, 5981, 297, -5071, 5997, 273, -5079, 5973, 285, -5091, 5969, 289, -5067, 5985, 277, -5075, 5989, 293, -5067, 5997, 309, -5059, 5993, 325, -5091, 6005, 305, -5107, 5997, 289, -5095, 5973, 309, -5107, 5985, 305, -5107, 5985, 313, -5087, 5989, 313, -5091, 5977, 309, -5087, 5973, 317, -5131, 5965, 317, -5123, 5977, 313, -5095, 5977, 305, -5087, 5993, 321, -5087, 5993, 317, -5095, 5965, 313, -5075, 5945, 285, -5091, 5941, 269, -5051, 5945, 289, -5079, 5957, 297, -5107, 5953, 293, -5107, 5949, 305, -5099, 5949, 309, -5095, 5941, 317, -5099, 5953, 309, -5087, 5977, 309, -5079, 5969, 297, -5087, 5973, 305, -5095, 5969, 309, -5095, 5977, 313, -5103, 5993, 329, -5123, 5961, 325, -5107, 5977, 321, -5103, 5973, 305, -5119, 5961, 325, -5115, 5949, 309, -5107, 5965, 309, -5103, 5969, 325, -5099, 5961, 345, -5099, 5993, 333, -5103, 5957, 297, -5091, 5965, 317, -5091, 5957, 317, -5079, 5997, 313, -5075, 5969, 325, -5083, 5993, 321, -5099, 5989, 321, -5111, 5969, 301, -5091, 5977, 329, -5083, 5989, 329, -5099, 5957, 313, -5095, 5941, 329, -5087, 5953, 321, -5107, 5933, 289, -5115, 5993, 285, -5091, 6021, 317, -5039, 5949, 341, -5079, 5965, 325, -5135, 5965, 309, -5091, 5965, 317, -5087, 5977, 329, -5087, 5965, 333, -5103, 5985, 333, -5123, 5965, 333, -5127, 5957, 349, -5123, 5961, 325, -5095, 5977, 321, -5083, 5989, 301, -5099, 5965, 325, -5115, 5957, 309, -5095, 5965, 321, -5083, 5993, 317, -5099, 5989, 329, -5103, 5973, 333, -5087, 5973, 345, -5095, 5957, 317, -5095, 5949, 333, -5095, 5969, 309, -5071, 5977, 321, -5087, 5965, 321, -5083, 5957, 325, -5119, 5981, 325, -5091, 5969,                                                                                                                                                                                                                                                                },\r
+{126, 337, -5087, 5981, 321, -5083, 5961, 329, -5083, 5965, 305, -5095, 5965, 305, -5119, 5953, 317, -5095, 5957, 337, -5079, 5985, 309, -5059, 5989, 337, -5087, 5993, 357, -5103, 5997, 301, -5079, 6001, 301, -5083, 5965, 317, -5095, 5965, 337, -5135, 5973, 341, -5123, 5965, 329, -5091, 5957, 329, -5087, 5953, 337, -5099, 5977, 333, -5103, 5957, 317, -5099, 5993, 333, -5111, 5973, 341, -5079, 5985, 333, -5055, 6021, 321, -5063, 5997, 317, -5083, 5973, 333, -5071, 5949, 317, -5059, 5989, 293, -5171, 5953, 293, -5139, 5897, 305, -5091, 5953, 301, -5079, 5957, 325, -5087, 5953, 313, -5115, 5961, 301, -5091, 5973, 313, -5095, 5973, 301, -5079, 5977, 309, -5075, 5985, 313, -5083, 5985, 313, -5083, 5977, 349, -5079, 5993, 333, -5083, 5973, 317, -5103, 5961, 297, -5103, 5957, 313, -5079, 5965, 309, -5091, 5981, 321, -5099, 5985, 333, -5103, 5981, 317, -5087, 5969, 321, -5099, 5977, 333, -5091, 5981, 317, -5075, 5985, 333, -5071, 5989, 341, -5083, 5977, 325, -5107, 5969, 289, -5087, 5977, 297, -5063, 5965, 301, -5083, 5981, 321, -5067, 5969, 321, -5063, 5981, 313, -5075, 5997, 313, -5071, 5977, 309, -5083, 5969, 285, -5087, 5953, 289, -5099, 5969, 313, -5091, 5953, 317, -5107, 5957, 305, -5087, 5957, 313, -5091, 5981, 305, -5095, 5985, 297, -5075, 5993, 313, -5083, 5989, 301, -5091, 5997, 301, -5091, 6001, 297, -5071, 5977, 301, -5067, 5961, 285, -5091, 5981, 289, -5099, 5969, 297, -5103, 5969, 293, -5087, 5969, 313, -5095, 5961, 321, -5103, 5969, 329, -5103, 5965, 317, -5079, 5953, 293, -5063, 5977, 289, -5059, 5965, 309, -5063, 5993, 305, -5103, 5973, 317, -5087, 5989, 313, -5099, 5989, 289, -5087, 5997, 293, -5095, 5989, 301, -5091, 5973, 281, -5083, 5957, 293, -5103, 5957, 285, -5087, 5969, 305, -5083, 5961, 329, -5091, 5969, 313, -5079, 5981, 305, -5063, 5985, 329, -5075, 6001, 313, -5091, 6001, 333, -5099, 5977, 293, -5107, 5965, 285, -5095, 5949, 293, -5087, 5981, 305, -5099, 5977, 337, -5095, 5969, 329, -5111, 5965, 313, -5095, 5989, 329, -5091, 5985, 313, -5099, 5981, 325, -5103, 5965, 313, -5075, 5973, 325, -5079, 5973, 305, -5103, 5977, 317, -5083, 5973, 341, -5103, 5957, 317, -5095, 5941, 305, -5115, 5953, 301, -5099, 5949, 285, -5095, 5949, 285, -5091, 5941, 297, -5091, 5965, 317, -5103, 5969, 325, -5103, 5973, 301, -5115, 5973,                                                                                                                                                                },\r
+{125, 317, -5099, 5973, 317, -5095, 5981, 313, -5103, 5961, 325, -5095, 5973, 313, -5091, 5973, 313, -5079, 5953, 325, -5067, 5965, 333, -5095, 5985, 313, -5115, 5957, 329, -5119, 5977, 321, -5135, 5989, 337, -5099, 5989, 341, -5095, 5977, 333, -5091, 5981, 309, -5115, 5977, 289, -5127, 5969, 309, -5067, 5981, 317, -5035, 5969, 321, -5115, 5993, 313, -5167, 5949, 313, -5091, 5953, 329, -5063, 5997, 309, -5051, 6001, 325, -5083, 5977, 309, -5115, 5953, 297, -5115, 5961, 309, -5083, 5945, 285, -5055, 5949, 281, -5079, 5961, 289, -5107, 5969, 297, -5103, 5965, 309, -5091, 5993, 333, -5099, 5981, 313, -5095, 5953, 301, -5091, 5977, 277, -5087, 5973, 277, -5091, 5981, 305, -5095, 5977, 333, -5099, 5957, 313, -5087, 5957, 313, -5075, 5977, 293, -5087, 5981, 309, -5095, 5981, 317, -5099, 5981, 301, -5071, 5965, 301, -5071, 5981, 285, -5091, 5957, 297, -5091, 5965, 305, -5099, 6005, 301, -5087, 5981, 313, -5075, 5989, 325, -5107, 5973, 309, -5095, 5985, 309, -5095, 5985, 293, -5091, 5985, 297, -5095, 5977, 317, -5075, 5981, 285, -5047, 5965, 313, -5039, 5957, 293, -5127, 5977, 265, -5127, 5917, 297, -5059, 5945, 273, -5047, 6001, 281, -5059, 5977, 317, -5103, 5969, 321, -5095, 5985, 301, -5091, 5973, 293, -5079, 5957, 277, -5087, 5973, 289, -5111, 5977, 309, -5127, 5985, 305, -5127, 5973, 321, -5115, 5969, 333, -5091, 5969, 325, -5083, 5985, 321, -5091, 5985, 313, -5095, 5973, 305, -5091, 5969, 289, -5079, 5973, 285, -5063, 5957, 301, -5079, 5973, 297, -5103, 5949, 293, -5099, 5933, 293, -5099, 5949, 293, -5083, 5949, 301, -5091, 5969, 293, -5107, 5977, 297, -5107, 5961, 293, -5087, 5973, 281, -5075, 5997, 321, -5079, 5985, 309, -5103, 5957, 301, -5115, 5949, 289, -5111, 5981, 301, -5111, 5981, 325, -5103, 5965, 301, -5091, 5953, 309, -5111, 5969, 301, -5131, 5961, 301, -5099, 5953, 301, -5079, 5961, 313, -5067, 5985, 317, -5103, 5985, 321, -5119, 5969, 313, -5107, 5977, 297, -5079, 5989, 321, -5083, 5993, 321, -5091, 5989, 305, -5107, 5977, 305, -5095, 5977, 281, -5103, 5961, 293, -5107, 5945, 301, -5111, 5949, 325, -5099, 5945, 305, -5091, 5949, 309, -5107, 5961, 333, -5103, 5933, 321, -5111, 5973, 301, -5091, 5973, 317, -5079, 5965, 297, -5099, 5977, 285, -5091, 5945, 273, -5091, 5981, 281, -5099, 5977, 277, -5139, 5957,                                                                                                                                                                                                },\r
+{124, 313, -5131, 5965, 313, -5123, 5949, 293, -5115, 5945, 297, -5095, 5957, 301, -5091, 5965, 309, -5111, 5969, 325, -5095, 5973, 309, -5115, 5969, 317, -5095, 5977, 325, -5099, 5969, 313, -5111, 5961, 277, -5103, 5941, 289, -5103, 5949, 293, -5083, 5957, 297, -5083, 5965, 297, -5111, 5953, 341, -5119, 5961, 321, -5127, 5965, 305, -5103, 5973, 297, -5103, 5973, 293, -5103, 5969, 305, -5083, 5977, 281, -5095, 5965, 297, -5087, 5953, 313, -5091, 5969, 309, -5087, 5957, 301, -5087, 5957, 317, -5087, 5957, 333, -5087, 5969, 317, -5099, 5969, 317, -5119, 5965, 301, -5135, 5973, 305, -5147, 5953, 309, -5135, 5953, 317, -5143, 5969, 313, -5131, 5969, 309, -5119, 5961, 309, -5099, 5965, 305, -5095, 5981, 305, -5107, 5989, 309, -5091, 5957, 321, -5083, 5973, 321, -5087, 5961, 333, -5111, 5949, 337, -5115, 5957, 309, -5083, 5925, 309, -5079, 5965, 305, -5099, 5957, 301, -5131, 5945, 317, -5127, 5933, 325, -5111, 5945, 309, -5099, 5945, 301, -5099, 5961, 305, -5107, 5973, 305, -5111, 5977, 317, -5091, 5989, 337, -5091, 5993, 341, -5083, 5973, 309, -5095, 5993, 297, -5111, 5957, 301, -5127, 5949, 325, -5107, 5953, 329, -5087, 5937, 333, -5087, 5981, 329, -5111, 5981, 321, -5111, 5953, 297, -5119, 5965, 325, -5095, 5977, 325, -5103, 5965, 305, -5107, 5969, 305, -5119, 5969, 313, -5099, 5961, 313, -5099, 5965, 317, -5079, 5993, 321, -5087, 5981, 313, -5127, 5965, 329, -5111, 5953, 321, -5111, 5949, 305, -5103, 5941, 305, -5095, 5929, 277, -5095, 5945, 305, -5079, 5945, 309, -5071, 5973, 301, -5087, 6001, 329, -5095, 5969, 329, -5099, 5981, 337, -5099, 5989, 321, -5123, 5981, 297, -5103, 5961, 313, -5095, 5949, 309, -5107, 5969, 305, -5103, 5953, 297, -5111, 5961, 301, -5099, 5957, 309, -5111, 5977, 337, -5111, 5957, 313, -5099, 5989, 309, -5115, 5961, 289, -5099, 5969, 293, -5063, 5973, 301, -5087, 5969, 293, -5083, 5961, 321, -5099, 5961, 333, -5091, 5965, 329, -5099, 5957, 309, -5119, 5953, 305, -5115, 5965, 289, -5095, 5989, 313, -5091, 5973, 297, -5095, 5961, 309, -5103, 5957, 285, -5107, 5957, 289, -5087, 5949, 289, -5079, 5973, 317, -5063, 5985, 309, -5067, 6001, 297, -5091, 5957, 297, -5087, 5949, 301, -5075, 5969, 297, -5095, 5957, 305, -5115, 5949, 289, -5135, 5933, 301, -5131, 5941, 313, -5127, 5969,                                                                                                                                                                                                                                },\r
+{125, 313, -5135, 5969, 329, -5115, 5969, 321, -5115, 5969, 321, -5099, 5977, 325, -5107, 5993, 309, -5103, 5973, 301, -5107, 5985, 317, -5075, 5957, 289, -5075, 5957, 305, -5087, 5945, 309, -5091, 5953, 305, -5107, 5953, 305, -5119, 5949, 317, -5127, 5941, 297, -5119, 5953, 301, -5099, 5957, 313, -5091, 5949, 321, -5087, 5965, 313, -5091, 5961, 305, -5103, 5953, 293, -5115, 5957, 301, -5107, 5961, 297, -5103, 5977, 321, -5103, 5961, 329, -5107, 5985, 321, -5107, 5977, 337, -5123, 5973, 317, -5135, 5961, 309, -5123, 5953, 317, -5079, 5973, 321, -5083, 5989, 345, -5099, 5953, 297, -5115, 5945, 289, -5115, 5969, 309, -5095, 5961, 301, -5107, 5969, 297, -5111, 5957, 317, -5107, 5977, 313, -5079, 5965, 317, -5095, 6001, 349, -5095, 5985, 333, -5111, 5961, 325, -5107, 5957, 305, -5115, 5957, 289, -5115, 5937, 305, -5095, 5929, 309, -5087, 5945, 277, -5095, 5945, 289, -5079, 5969, 301, -5099, 5965, 305, -5099, 5969, 317, -5135, 5965, 301, -5099, 5977, 317, -5111, 5969, 325, -5107, 5961, 305, -5119, 5953, 317, -5119, 5953, 313, -5131, 5945, 325, -5119, 5945, 321, -5119, 5953, 313, -5119, 5961, 309, -5079, 5981, 321, -5111, 5973, 333, -5115, 5957, 333, -5119, 5957, 309, -5115, 5973, 297, -5091, 5961, 321, -5119, 5945, 325, -5103, 5941, 325, -5123, 5945, 313, -5155, 5953, 301, -5143, 5949, 325, -5119, 5941, 333, -5095, 5985, 341, -5095, 5989, 337, -5111, 5969, 313, -5123, 5965, 317, -5107, 5961, 301, -5103, 5977, 317, -5119, 5965, 333, -5115, 5925, 305, -5119, 5953, 317, -5107, 5961, 313, -5099, 5953, 341, -5079, 5961, 353, -5079, 5973, 337, -5111, 5973, 321, -5143, 5949, 309, -5135, 5965, 325, -5151, 5945, 325, -5123, 5953, 313, -5099, 5953, 321, -5107, 5965, 321, -5131, 5945, 341, -5147, 5945, 333, -5123, 5941, 341, -5107, 5977, 325, -5131, 5973, 321, -5115, 5953, 333, -5079, 5949, 325, -5095, 5945, 313, -5099, 5937, 309, -5099, 5925, 313, -5127, 5937, 325, -5111, 5933, 337, -5127, 5941, 321, -5131, 5949, 325, -5115, 5945, 313, -5103, 5949, 329, -5107, 5961, 329, -5099, 5953, 337, -5115, 5957, 349, -5127, 5953, 329, -5115, 5941, 329, -5143, 5957, 329, -5135, 5929, 341, -5143, 5929, 329, -5131, 5949, 329, -5127, 5961, 333, -5131, 5973, 341, -5115, 5953, 345, -5131, 5957, 349, -5099, 5953, 345, -5087, 5961, 349, -5099, 5961,                                                                                                                                                                                                },\r
+{124, 341, -5115, 5961, 337, -5143, 5981, 333, -5139, 5949, 353, -5123, 5961, 333, -5119, 5945, 337, -5131, 5945, 337, -5119, 5957, 317, -5119, 5941, 341, -5119, 5953, 317, -5103, 5961, 337, -5103, 5977, 349, -5075, 5953, 337, -5095, 5949, 333, -5119, 5945, 337, -5139, 5929, 345, -5127, 5949, 325, -5119, 5937, 337, -5131, 5933, 349, -5127, 5933, 345, -5111, 5965, 333, -5123, 5941, 337, -5127, 5957, 341, -5147, 5945, 333, -5135, 5945, 337, -5127, 5961, 353, -5111, 5941, 341, -5131, 5937, 337, -5119, 5949, 337, -5115, 5957, 345, -5119, 5961, 357, -5127, 5937, 333, -5119, 5945, 349, -5123, 5945, 337, -5139, 5961, 333, -5115, 5965, 337, -5115, 5945, 349, -5107, 5937, 349, -5127, 5937, 345, -5139, 5941, 345, -5119, 5917, 349, -5135, 5933, 337, -5123, 5921, 337, -5115, 5961, 377, -5115, 5941, 357, -5123, 5945, 345, -5119, 5945, 337, -5115, 5961, 357, -5119, 5945, 361, -5139, 5929, 369, -5143, 5941, 357, -5139, 5945, 345, -5115, 5953, 365, -5123, 5953, 361, -5103, 5949, 357, -5127, 5957, 349, -5143, 5949, 345, -5139, 5937, 357, -5135, 5941, 349, -5127, 5941, 369, -5115, 5965, 353, -5135, 5949, 365, -5159, 5929, 361, -5143, 5925, 369, -5151, 5957, 349, -5135, 5937, 365, -5119, 5945, 365, -5119, 5941, 337, -5123, 5957, 357, -5119, 5957, 385, -5119, 5941, 365, -5127, 5937, 353, -5107, 5925, 337, -5115, 5913, 349, -5115, 5909, 345, -5099, 5921, 345, -5119, 5937, 357, -5147, 5925, 349, -5139, 5925, 369, -5135, 5949, 349, -5127, 5953, 353, -5119, 5953, 389, -5139, 5945, 373, -5135, 5925, 337, -5135, 5929, 349, -5123, 5945, 357, -5135, 5941, 357, -5127, 5933, 365, -5143, 5929, 381, -5123, 5921, 369, -5135, 5941, 373, -5155, 5929, 345, -5147, 5945, 353, -5135, 5945, 357, -5115, 5965, 369, -5111, 5925, 365, -5131, 5933, 365, -5131, 5953, 365, -5127, 5945, 357, -5107, 5945, 361, -5123, 5941, 365, -5139, 5953, 345, -5127, 5941, 365, -5139, 5925, 361, -5115, 5929, 369, -5119, 5937, 357, -5119, 5925, 353, -5123, 5937, 365, -5143, 5925, 361, -5143, 5933, 369, -5115, 5921, 353, -5115, 5921, 349, -5115, 5949, 337, -5131, 5953, 353, -5123, 5949, 381, -5111, 5941, 373, -5131, 5941, 373, -5151, 5937, 377, -5151, 5945, 357, -5135, 5933, 365, -5119, 5941, 373, -5127, 5929, 373, -5131, 5941, 365, -5127, 5945, 353, -5135, 5941,                                                                                                                                                                                                                                },\r
+{125, 349, -5115, 5925, 353, -5107, 5945, 373, -5131, 5937, 361, -5123, 5949, 365, -5123, 5969, 349, -5123, 5941, 369, -5123, 5945, 377, -5119, 5941, 377, -5139, 5933, 357, -5139, 5945, 349, -5123, 5933, 357, -5131, 5933, 361, -5127, 5937, 389, -5115, 5925, 369, -5127, 5937, 361, -5131, 5929, 369, -5107, 5965, 357, -5127, 5941, 353, -5135, 5933, 361, -5163, 5937, 357, -5155, 5921, 365, -5135, 5941, 357, -5095, 5949, 365, -5103, 5949, 361, -5115, 5957, 365, -5127, 5949, 349, -5119, 5917, 357, -5127, 5929, 373, -5167, 5929, 373, -5159, 5949, 357, -5151, 5949, 393, -5123, 5933, 373, -5115, 5921, 353, -5123, 5945, 369, -5135, 5925, 349, -5131, 5933, 361, -5131, 5937, 369, -5131, 5945, 397, -5131, 5949, 385, -5135, 5929, 377, -5139, 5941, 353, -5111, 5933, 369, -5135, 5925, 349, -5131, 5905, 357, -5155, 5913, 365, -5151, 5909, 357, -5123, 5909, 349, -5119, 5929, 385, -5143, 5945, 385, -5175, 5941, 373, -5143, 5941, 365, -5143, 5949, 377, -5147, 5925, 385, -5155, 5941, 381, -5131, 5933, 381, -5123, 5929, 365, -5123, 5925, 381, -5151, 5925, 357, -5147, 5937, 349, -5159, 5905, 373, -5143, 5921, 381, -5115, 5949, 349, -5115, 5953, 369, -5111, 5961, 377, -5167, 5933, 413, -5155, 5933, 405, -5139, 5961, 381, -5159, 5937, 389, -5147, 5925, 381, -5131, 5941, 361, -5111, 5949, 377, -5127, 5945, 361, -5119, 5933, 393, -5135, 5917, 401, -5123, 5917, 385, -5155, 5921, 373, -5135, 5905, 381, -5127, 5921, 377, -5123, 5921, 353, -5155, 5913, 353, -5143, 5929, 361, -5155, 5925, 361, -5135, 5929, 365, -5119, 5917, 365, -5135, 5921, 365, -5155, 5941, 401, -5151, 5937, 389, -5143, 5929, 369, -5135, 5925, 393, -5143, 5929, 385, -5179, 5909, 373, -5155, 5921, 369, -5131, 5937, 385, -5111, 5929, 377, -5119, 5941, 393, -5151, 5925, 377, -5155, 5909, 361, -5135, 5921, 377, -5127, 5929, 393, -5127, 5945, 377, -5143, 5941, 365, -5147, 5909, 377, -5155, 5929, 365, -5159, 5917, 377, -5139, 5917, 389, -5159, 5929, 397, -5151, 5917, 389, -5135, 5913, 385, -5119, 5945, 365, -5119, 5917, 377, -5127, 5925, 393, -5155, 5933, 365, -5179, 5945, 381, -5139, 5925, 393, -5115, 5933, 381, -5123, 5929, 381, -5127, 5941, 377, -5135, 5941, 401, -5139, 5929, 401, -5139, 5929, 385, -5155, 5929, 393, -5179, 5909, 381, -5187, 5913, 381, -5171, 5933, 373, -5127, 5921,                                                                                                                                                                                                },\r
+{123, 381, -5151, 5925, 409, -5131, 5913, 425, -5139, 5925, 409, -5147, 5945, 389, -5143, 5961, 389, -5119, 5953, 377, -5115, 5953, 385, -5127, 5933, 381, -5139, 5897, 377, -5163, 5905, 381, -5139, 5889, 369, -5147, 5877, 353, -5139, 5897, 373, -5131, 5929, 393, -5175, 5925, 409, -5155, 5917, 401, -5135, 5933, 381, -5111, 5941, 393, -5131, 5933, 401, -5163, 5925, 393, -5139, 5933, 405, -5127, 5941, 385, -5147, 5937, 409, -5159, 5949, 389, -5163, 5909, 357, -5159, 5905, 365, -5131, 5885, 365, -5111, 5933, 365, -5115, 5965, 377, -5107, 5925, 393, -5139, 5949, 413, -5155, 5957, 417, -5163, 5941, 405, -5139, 5917, 401, -5139, 5925, 389, -5159, 5945, 377, -5119, 5929, 385, -5131, 5945, 377, -5123, 5929, 373, -5143, 5933, 381, -5123, 5937, 373, -5131, 5937, 353, -5127, 5913, 381, -5135, 5929, 393, -5143, 5933, 405, -5147, 5897, 393, -5135, 5925, 381, -5139, 5921, 401, -5175, 5917, 393, -5147, 5921, 369, -5135, 5937, 389, -5111, 5929, 381, -5151, 5929, 369, -5171, 5917, 365, -5155, 5913, 377, -5119, 5929, 361, -5123, 5917, 369, -5151, 5921, 385, -5179, 5921, 409, -5191, 5917, 441, -5175, 5925, 413, -5171, 5933, 417, -5143, 5941, 369, -5139, 5913, 397, -5159, 5933, 377, -5167, 5929, 385, -5143, 5925, 369, -5127, 5929, 365, -5111, 5941, 377, -5135, 5937, 393, -5147, 5933, 389, -5151, 5933, 409, -5167, 5937, 417, -5167, 5909, 401, -5147, 5913, 381, -5155, 5917, 373, -5127, 5933, 373, -5115, 5933, 401, -5131, 5917, 397, -5135, 5921, 377, -5131, 5925, 377, -5127, 5941, 389, -5123, 5969, 397, -5111, 5961, 401, -5115, 5929, 393, -5139, 5937, 401, -5167, 5917, 385, -5203, 5929, 401, -5199, 5933, 401, -5151, 5913, 393, -5147, 5933, 381, -5135, 5933, 385, -5115, 5933, 385, -5107, 5945, 381, -5107, 5957, 389, -5127, 5941, 373, -5135, 5933, 389, -5127, 5949, 401, -5131, 5925, 405, -5127, 5901, 377, -5119, 5913, 365, -5131, 5921, 385, -5147, 5933, 397, -5159, 5933, 377, -5147, 5921, 357, -5123, 5921, 369, -5123, 5945, 373, -5155, 5949, 381, -5135, 5937, 377, -5099, 5953, 373, -5111, 5957, 385, -5123, 5945, 385, -5163, 5941, 377, -5167, 5921, 369, -5155, 5913, 353, -5123, 5917, 381, -5131, 5957, 389, -5131, 5937, 385, -5143, 5937, 381, -5143, 5937, 385, -5143, 5941, 385, -5139, 5933, 373, -5139, 5945,                                                                                                                                                                                                                                                                },\r
+{125, 373, -5131, 5949, 361, -5099, 5945, 377, -5111, 5945, 389, -5127, 5949, 377, -5123, 5953, 381, -5135, 5917, 385, -5139, 5929, 369, -5123, 5921, 337, -5123, 5909, 357, -5135, 5917, 385, -5147, 5913, 385, -5151, 5925, 361, -5151, 5937, 369, -5123, 5949, 381, -5107, 5961, 369, -5115, 5953, 365, -5103, 5945, 381, -5123, 5945, 369, -5123, 5941, 365, -5147, 5921, 409, -5147, 5929, 381, -5155, 5925, 373, -5159, 5925, 389, -5127, 5945, 365, -5123, 5929, 369, -5135, 5925, 361, -5107, 5933, 373, -5127, 5953, 393, -5115, 5973, 409, -5139, 5957, 385, -5135, 5945, 365, -5111, 5933, 353, -5111, 5937, 369, -5111, 5929, 377, -5135, 5933, 377, -5147, 5921, 385, -5155, 5929, 381, -5127, 5921, 389, -5115, 5921, 377, -5151, 5933, 369, -5127, 5937, 389, -5103, 5929, 385, -5111, 5969, 389, -5107, 5945, 373, -5127, 5921, 381, -5131, 5937, 369, -5115, 5917, 389, -5119, 5929, 401, -5127, 5929, 397, -5163, 5929, 397, -5171, 5917, 397, -5179, 5913, 405, -5179, 5949, 397, -5179, 5941, 389, -5147, 5941, 421, -5155, 5937, 409, -5155, 5929, 397, -5159, 5917, 401, -5131, 5909, 405, -5151, 5961, 397, -5143, 5921, 413, -5131, 5921, 417, -5123, 5957, 409, -5123, 5933, 425, -5139, 5949, 401, -5147, 5909, 409, -5139, 5897, 413, -5135, 5897, 373, -5139, 5909, 369, -5123, 5897, 389, -5119, 5917, 397, -5151, 5925, 405, -5159, 5937, 397, -5147, 5945, 397, -5143, 5917, 405, -5151, 5929, 405, -5131, 5913, 405, -5135, 5933, 397, -5139, 5945, 409, -5143, 5945, 421, -5171, 5925, 421, -5187, 5937, 425, -5155, 5929, 405, -5131, 5921, 393, -5123, 5937, 401, -5147, 5917, 377, -5147, 5917, 377, -5143, 5921, 377, -5139, 5933, 369, -5179, 5941, 397, -5155, 5929, 413, -5123, 5941, 421, -5135, 5937, 421, -5147, 5937, 413, -5147, 5941, 409, -5139, 5901, 413, -5131, 5905, 385, -5135, 5929, 373, -5151, 5921, 373, -5139, 5929, 385, -5135, 5929, 381, -5131, 5901, 393, -5147, 5917, 409, -5167, 5941, 417, -5155, 5969, 389, -5127, 5941, 397, -5151, 5933, 397, -5131, 5957, 381, -5139, 5973, 405, -5139, 5969, 417, -5119, 5945, 405, -5107, 5941, 385, -5131, 5901, 377, -5187, 5877, 385, -5187, 5881, 397, -5223, 5917, 405, -5175, 5889, 429, -5167, 5881, 405, -5215, 5937, 385, -5179, 5933, 389, -5143, 5949, 393, -5091, 5929, 385, -5047, 5993, 361, -5127, 5969, 401, -5135, 5913,                                                                                                                                                                                                },\r
+{125, 413, -5175, 5921, 437, -5203, 5841, 413, -5231, 5845, 405, -5255, 5829, 369, -5239, 5853, 389, -5215, 5817, 421, -5231, 5817, 393, -5291, 5809, 413, -5307, 5733, 417, -5359, 5757, 433, -5335, 5737, 429, -5311, 5745, 429, -5323, 5773, 437, -5323, 5789, 429, -5335, 5801, 425, -5323, 5805, 417, -5283, 5837, 429, -5271, 5901, 425, -5275, 5877, 433, -5271, 5877, 429, -5235, 5837, 409, -5231, 5877, 401, -5279, 5969, 413, -5211, 5861, 413, -5175, 5841, 393, -5219, 5785, 389, -5279, 5805, 369, -5291, 5845, 341, -5335, 5805, 457, -5343, 5817, 465, -5355, 5709, 445, -5315, 5705, 377, -5275, 5677, 381, -5311, 5709, 417, -5295, 5737, 417, -5287, 5877, 441, -5243, 5797, 421, -5243, 5789, 401, -5267, 5805, 405, -5247, 5825, 385, -5219, 5841, 393, -5207, 5861, 369, -5191, 5809, 409, -5239, 5849, 385, -5251, 5877, 433, -5243, 5821, 441, -5287, 5809, 409, -5319, 5813, 389, -5311, 5789, 389, -5311, 5797, 389, -5343, 5801, 429, -5339, 5781, 433, -5323, 5801, 417, -5263, 5825, 389, -5231, 5833, 389, -5219, 5833, 401, -5235, 5845, 405, -5235, 5877, 445, -5231, 5849, 437, -5247, 5881, 429, -5283, 5853, 389, -5287, 5821, 409, -5231, 5797, 389, -5235, 5837, 405, -5227, 5801, 413, -5275, 5781, 409, -5315, 5777, 409, -5311, 5773, 417, -5287, 5757, 385, -5287, 5769, 401, -5271, 5821, 425, -5263, 5841, 409, -5259, 5841, 417, -5247, 5865, 425, -5255, 5877, 445, -5295, 5833, 437, -5287, 5825, 421, -5299, 5805, 417, -5271, 5781, 409, -5267, 5797, 373, -5291, 5817, 397, -5267, 5805, 437, -5271, 5817, 429, -5267, 5837, 421, -5255, 5801, 397, -5267, 5825, 397, -5263, 5853, 417, -5239, 5837, 453, -5271, 5825, 425, -5295, 5829, 401, -5299, 5801, 433, -5291, 5785, 413, -5283, 5765, 385, -5263, 5797, 397, -5247, 5793, 393, -5271, 5805, 397, -5307, 5805, 421, -5295, 5837, 429, -5283, 5825, 413, -5271, 5833, 421, -5235, 5825, 421, -5243, 5841, 421, -5251, 5829, 413, -5255, 5809, 393, -5299, 5813, 397, -5295, 5781, 417, -5287, 5793, 433, -5275, 5825, 465, -5271, 5841, 445, -5291, 5821, 441, -5283, 5813, 421, -5311, 5813, 421, -5275, 5813, 405, -5271, 5817, 409, -5279, 5817, 409, -5279, 5817, 413, -5287, 5805, 421, -5307, 5797, 421, -5287, 5777, 425, -5291, 5781, 393, -5271, 5785, 405, -5255, 5789, 417, -5279, 5809, 413, -5279, 5813, 417, -5267, 5813,                                                                                                                                                                                                },\r
+{122, 421, -5267, 5821, 437, -5243, 5821, 409, -5287, 5809, 409, -5275, 5789, 389, -5275, 5793, 413, -5283, 5789, 389, -5299, 5813, 413, -5283, 5821, 429, -5295, 5813, 421, -5303, 5793, 429, -5279, 5821, 441, -5279, 5817, 425, -5295, 5809, 429, -5271, 5841, 429, -5255, 5833, 425, -5267, 5817, 401, -5279, 5833, 401, -5295, 5821, 409, -5275, 5793, 417, -5279, 5809, 417, -5287, 5833, 437, -5275, 5801, 441, -5275, 5809, 437, -5287, 5817, 425, -5279, 5805, 425, -5267, 5805, 409, -5255, 5801, 429, -5275, 5813, 409, -5279, 5809, 397, -5287, 5801, 409, -5291, 5813, 385, -5279, 5805, 397, -5267, 5817, 413, -5283, 5805, 413, -5267, 5817, 421, -5267, 5809, 429, -5279, 5797, 425, -5287, 5809, 433, -5279, 5805, 417, -5275, 5809, 429, -5283, 5805, 409, -5275, 5821, 417, -5271, 5821, 413, -5295, 5833, 409, -5303, 5801, 409, -5291, 5817, 421, -5299, 5813, 405, -5291, 5809, 405, -5263, 5797, 397, -5239, 5809, 401, -5263, 5809, 425, -5299, 5781, 409, -5291, 5805, 421, -5299, 5801, 429, -5291, 5809, 429, -5275, 5817, 425, -5283, 5825, 381, -5259, 5821, 385, -5251, 5841, 405, -5251, 5829, 413, -5271, 5809, 425, -5291, 5805, 393, -5287, 5793, 389, -5259, 5793, 417, -5247, 5825, 405, -5251, 5805, 405, -5255, 5829, 417, -5271, 5833, 425, -5287, 5829, 429, -5307, 5821, 409, -5307, 5801, 401, -5263, 5793, 401, -5263, 5805, 405, -5291, 5797, 421, -5275, 5837, 405, -5275, 5805, 421, -5283, 5817, 429, -5279, 5857, 433, -5263, 5825, 417, -5243, 5817, 433, -5259, 5809, 425, -5263, 5821, 417, -5283, 5805, 433, -5267, 5793, 409, -5275, 5801, 405, -5283, 5801, 405, -5295, 5825, 421, -5275, 5785, 397, -5267, 5809, 385, -5247, 5809, 417, -5259, 5817, 417, -5283, 5817, 441, -5283, 5849, 441, -5283, 5841, 441, -5271, 5809, 433, -5267, 5801, 417, -5279, 5809, 413, -5275, 5833, 385, -5267, 5813, 385, -5251, 5833, 417, -5239, 5849, 413, -5239, 5853, 433, -5255, 5845, 433, -5283, 5825, 417, -5291, 5837, 421, -5259, 5805, 417, -5255, 5805, 429, -5275, 5821, 409, -5287, 5833, 437, -5287, 5837, 433, -5271, 5809, 405, -5239, 5801, 381, -5243, 5813, 401, -5247, 5813, 397, -5271, 5829, 417, -5271, 5817, 413, -5263, 5837, 433, -5247, 5833, 413, -5267, 5809, 429, -5283, 5837, 409, -5295, 5805, 409, -5259, 5805,                                                                                                                                                                                                                                                                                                },\r
+{126, 405, -5255, 5817, 397, -5275, 5821, 393, -5279, 5821, 397, -5263, 5829, 413, -5271, 5805, 433, -5299, 5805, 417, -5299, 5825, 413, -5263, 5821, 425, -5255, 5821, 437, -5259, 5801, 417, -5255, 5821, 417, -5255, 5821, 393, -5247, 5829, 401, -5255, 5821, 413, -5243, 5837, 437, -5267, 5821, 417, -5295, 5821, 409, -5287, 5793, 397, -5279, 5789, 405, -5255, 5805, 413, -5275, 5825, 421, -5279, 5805, 429, -5283, 5809, 413, -5279, 5837, 397, -5251, 5849, 417, -5263, 5821, 417, -5267, 5825, 389, -5263, 5813, 425, -5263, 5817, 421, -5275, 5785, 417, -5279, 5793, 417, -5263, 5821, 425, -5271, 5809, 421, -5299, 5817, 429, -5315, 5849, 433, -5295, 5825, 441, -5275, 5833, 425, -5255, 5829, 429, -5271, 5833, 421, -5299, 5817, 429, -5291, 5801, 429, -5267, 5821, 429, -5267, 5821, 413, -5283, 5817, 425, -5283, 5797, 437, -5291, 5817, 425, -5275, 5809, 429, -5259, 5813, 405, -5255, 5801, 413, -5251, 5805, 405, -5243, 5785, 401, -5259, 5797, 417, -5295, 5797, 409, -5323, 5793, 421, -5311, 5805, 433, -5271, 5833, 433, -5283, 5837, 425, -5279, 5809, 409, -5267, 5813, 417, -5255, 5845, 417, -5263, 5829, 425, -5291, 5837, 409, -5295, 5809, 401, -5295, 5797, 401, -5279, 5813, 417, -5259, 5817, 437, -5239, 5833, 453, -5251, 5829, 449, -5287, 5813, 429, -5295, 5797, 433, -5303, 5825, 421, -5311, 5825, 405, -5279, 5821, 421, -5243, 5865, 417, -5255, 5853, 429, -5251, 5845, 421, -5251, 5833, 381, -5275, 5821, 413, -5303, 5781, 373, -5275, 5801, 393, -5263, 5781, 409, -5247, 5805, 393, -5263, 5821, 417, -5279, 5813, 421, -5263, 5817, 417, -5243, 5829, 397, -5251, 5829, 389, -5263, 5825, 377, -5255, 5825, 381, -5263, 5829, 405, -5267, 5813, 389, -5271, 5817, 393, -5279, 5821, 393, -5299, 5793, 397, -5279, 5789, 389, -5259, 5809, 409, -5271, 5841, 377, -5275, 5817, 397, -5267, 5833, 417, -5275, 5841, 405, -5271, 5849, 405, -5255, 5841, 385, -5251, 5805, 389, -5259, 5809, 389, -5243, 5837, 393, -5251, 5837, 393, -5279, 5821, 381, -5287, 5817, 385, -5247, 5809, 393, -5239, 5813, 393, -5239, 5797, 393, -5259, 5809, 389, -5239, 5805, 393, -5275, 5825, 377, -5259, 5825, 401, -5255, 5857, 409, -5259, 5861, 421, -5223, 5885, 389, -5263, 5837, 389, -5295, 5821, 393, -5303, 5809, 393, -5283, 5813, 385, -5283, 5793, 401, -5283, 5813, 381, -5275, 5821, 393, -5263, 5841,                                                                                                                                                                },\r
+{124, 397, -5227, 5865, 413, -5247, 5873, 405, -5267, 5841, 409, -5251, 5833, 405, -5255, 5813, 373, -5251, 5825, 373, -5239, 5813, 389, -5255, 5801, 369, -5259, 5801, 361, -5267, 5801, 357, -5283, 5809, 385, -5299, 5813, 393, -5271, 5817, 405, -5243, 5801, 401, -5219, 5837, 389, -5227, 5849, 385, -5235, 5853, 389, -5215, 5841, 409, -5243, 5817, 405, -5255, 5833, 413, -5283, 5821, 385, -5295, 5821, 393, -5287, 5821, 397, -5251, 5841, 401, -5255, 5833, 393, -5275, 5825, 401, -5279, 5813, 381, -5287, 5825, 353, -5259, 5833, 365, -5227, 5825, 369, -5231, 5837, 397, -5235, 5853, 401, -5227, 5861, 413, -5235, 5853, 429, -5275, 5817, 405, -5271, 5829, 389, -5247, 5849, 405, -5263, 5829, 397, -5279, 5793, 365, -5283, 5797, 373, -5251, 5821, 377, -5243, 5829, 377, -5255, 5841, 413, -5287, 5837, 405, -5283, 5829, 413, -5267, 5829, 413, -5263, 5821, 389, -5251, 5817, 357, -5251, 5813, 369, -5243, 5829, 393, -5255, 5825, 389, -5243, 5813, 409, -5255, 5853, 429, -5283, 5837, 425, -5299, 5805, 413, -5291, 5817, 385, -5287, 5817, 385, -5267, 5817, 381, -5251, 5809, 373, -5247, 5817, 389, -5247, 5817, 397, -5259, 5813, 421, -5291, 5837, 405, -5299, 5825, 421, -5279, 5821, 393, -5267, 5829, 385, -5227, 5817, 393, -5243, 5825, 413, -5267, 5817, 401, -5263, 5817, 393, -5259, 5805, 397, -5259, 5829, 401, -5243, 5837, 409, -5251, 5825, 421, -5271, 5849, 413, -5283, 5833, 397, -5267, 5817, 409, -5287, 5813, 397, -5299, 5809, 401, -5311, 5805, 417, -5299, 5829, 401, -5271, 5825, 417, -5263, 5821, 417, -5259, 5817, 417, -5255, 5853, 405, -5267, 5853, 393, -5271, 5825, 405, -5243, 5805, 401, -5259, 5793, 413, -5267, 5797, 405, -5291, 5773, 393, -5287, 5785, 369, -5275, 5777, 377, -5255, 5809, 393, -5263, 5809, 401, -5263, 5841, 413, -5275, 5837, 421, -5275, 5809, 401, -5283, 5805, 385, -5243, 5829, 381, -5235, 5837, 405, -5267, 5825, 437, -5255, 5841, 417, -5295, 5829, 433, -5291, 5825, 433, -5315, 5809, 417, -5327, 5813, 389, -5271, 5805, 381, -5235, 5805, 413, -5219, 5825, 405, -5251, 5821, 401, -5263, 5809, 405, -5279, 5801, 401, -5271, 5817, 421, -5243, 5821, 393, -5247, 5825, 413, -5251, 5853, 425, -5259, 5837, 425, -5247, 5853, 433, -5263, 5829, 397, -5295, 5821, 409, -5283, 5805, 401, -5271, 5801, 385, -5267, 5801,                                                                                                                                                                                                                                },\r
+{124, 389, -5247, 5805, 401, -5275, 5821, 389, -5263, 5801, 417, -5267, 5817, 409, -5287, 5809, 417, -5299, 5801, 401, -5291, 5825, 397, -5271, 5809, 401, -5275, 5829, 397, -5267, 5821, 405, -5299, 5801, 417, -5319, 5785, 397, -5283, 5797, 393, -5259, 5809, 413, -5267, 5805, 409, -5271, 5805, 401, -5283, 5821, 401, -5263, 5817, 413, -5251, 5829, 433, -5247, 5833, 437, -5263, 5829, 425, -5303, 5821, 409, -5295, 5809, 417, -5295, 5785, 413, -5279, 5809, 413, -5263, 5805, 409, -5287, 5801, 409, -5311, 5777, 417, -5271, 5793, 393, -5283, 5801, 393, -5279, 5809, 401, -5267, 5821, 429, -5251, 5833, 433, -5283, 5829, 433, -5299, 5833, 437, -5303, 5813, 429, -5283, 5801, 409, -5271, 5809, 425, -5275, 5833, 429, -5295, 5817, 433, -5303, 5797, 409, -5307, 5793, 429, -5283, 5789, 433, -5303, 5809, 441, -5307, 5813, 437, -5307, 5805, 421, -5307, 5805, 437, -5287, 5801, 437, -5275, 5817, 437, -5259, 5825, 429, -5295, 5825, 441, -5283, 5813, 453, -5271, 5781, 413, -5255, 5797, 397, -5295, 5785, 401, -5283, 5797, 425, -5287, 5797, 437, -5303, 5801, 441, -5283, 5825, 429, -5303, 5805, 457, -5295, 5813, 449, -5311, 5797, 433, -5307, 5821, 441, -5291, 5797, 441, -5295, 5805, 453, -5287, 5797, 457, -5275, 5809, 429, -5291, 5821, 421, -5303, 5809, 405, -5291, 5797, 421, -5287, 5797, 457, -5267, 5801, 453, -5291, 5801, 429, -5295, 5797, 445, -5295, 5797, 429, -5291, 5805, 453, -5315, 5801, 445, -5315, 5809, 465, -5323, 5801, 465, -5311, 5793, 433, -5287, 5809, 425, -5279, 5797, 445, -5267, 5797, 433, -5275, 5789, 433, -5287, 5821, 441, -5291, 5801, 449, -5299, 5781, 449, -5299, 5797, 437, -5291, 5789, 445, -5287, 5793, 457, -5315, 5801, 453, -5299, 5813, 433, -5311, 5793, 421, -5283, 5789, 445, -5291, 5805, 453, -5295, 5801, 457, -5299, 5797, 453, -5311, 5785, 425, -5303, 5793, 437, -5291, 5797, 429, -5307, 5789, 457, -5315, 5793, 449, -5307, 5793, 445, -5291, 5797, 465, -5303, 5769, 441, -5283, 5785, 441, -5307, 5781, 453, -5291, 5813, 441, -5283, 5797, 461, -5291, 5809, 461, -5271, 5821, 445, -5303, 5801, 465, -5331, 5785, 433, -5319, 5777, 417, -5291, 5749, 425, -5291, 5789, 417, -5279, 5801, 429, -5271, 5813, 465, -5267, 5793, 465, -5275, 5817, 449, -5295, 5805, 445, -5307, 5781, 453, -5339, 5781, 461, -5319, 5793,                                                                                                                                                                                                                                },\r
+{125, 449, -5295, 5793, 461, -5295, 5793, 441, -5303, 5789, 449, -5303, 5789, 461, -5319, 5793, 437, -5303, 5809, 449, -5291, 5793, 441, -5287, 5805, 453, -5279, 5821, 453, -5279, 5801, 445, -5279, 5785, 437, -5283, 5789, 449, -5307, 5785, 437, -5331, 5765, 433, -5331, 5757, 445, -5303, 5769, 429, -5299, 5789, 437, -5299, 5785, 441, -5287, 5801, 437, -5271, 5817, 453, -5291, 5817, 461, -5299, 5821, 429, -5299, 5809, 421, -5307, 5769, 441, -5295, 5769, 421, -5287, 5761, 441, -5295, 5793, 437, -5303, 5781, 445, -5303, 5809, 461, -5315, 5785, 457, -5319, 5797, 457, -5311, 5805, 441, -5299, 5797, 469, -5291, 5817, 465, -5291, 5821, 445, -5295, 5797, 441, -5311, 5785, 437, -5311, 5793, 449, -5295, 5797, 449, -5279, 5785, 445, -5307, 5789, 449, -5303, 5793, 445, -5311, 5805, 465, -5307, 5805, 481, -5303, 5797, 465, -5307, 5813, 457, -5287, 5797, 441, -5263, 5781, 437, -5271, 5781, 437, -5295, 5797, 437, -5311, 5809, 433, -5319, 5793, 441, -5319, 5777, 445, -5307, 5769, 429, -5299, 5761, 445, -5311, 5785, 449, -5303, 5765, 453, -5311, 5805, 469, -5311, 5793, 433, -5303, 5813, 441, -5275, 5801, 445, -5303, 5813, 449, -5295, 5805, 453, -5279, 5805, 449, -5299, 5789, 457, -5299, 5793, 465, -5311, 5801, 437, -5339, 5777, 445, -5331, 5773, 445, -5283, 5773, 437, -5287, 5777, 465, -5299, 5777, 457, -5307, 5785, 453, -5323, 5805, 449, -5311, 5773, 433, -5303, 5793, 453, -5315, 5773, 461, -5323, 5757, 445, -5279, 5797, 445, -5271, 5781, 449, -5287, 5801, 469, -5295, 5813, 441, -5311, 5793, 445, -5327, 5789, 441, -5327, 5781, 461, -5335, 5773, 465, -5291, 5769, 457, -5283, 5789, 461, -5299, 5793, 437, -5319, 5769, 441, -5323, 5777, 453, -5327, 5773, 453, -5315, 5797, 453, -5303, 5793, 441, -5291, 5789, 445, -5303, 5789, 417, -5319, 5797, 441, -5295, 5829, 449, -5303, 5801, 453, -5311, 5785, 461, -5323, 5769, 441, -5307, 5769, 425, -5319, 5753, 433, -5295, 5765, 429, -5307, 5777, 433, -5307, 5777, 469, -5295, 5789, 469, -5299, 5793, 441, -5295, 5773, 433, -5307, 5785, 425, -5307, 5773, 429, -5307, 5769, 449, -5307, 5809, 469, -5315, 5793, 445, -5327, 5781, 445, -5307, 5789, 437, -5295, 5793, 449, -5303, 5789, 457, -5323, 5801, 449, -5319, 5777, 453, -5299, 5793, 457, -5311, 5797, 473, -5319, 5821, 473, -5311, 5797, 449, -5307, 5789,                                                                                                                                                                                                },\r
+{124, 449, -5283, 5793, 453, -5275, 5805, 441, -5299, 5797, 457, -5307, 5789, 429, -5291, 5781, 437, -5295, 5793, 453, -5283, 5793, 453, -5279, 5793, 437, -5291, 5793, 449, -5295, 5781, 429, -5303, 5773, 425, -5295, 5777, 449, -5295, 5781, 449, -5307, 5773, 457, -5307, 5781, 457, -5299, 5793, 433, -5291, 5813, 445, -5295, 5813, 465, -5295, 5797, 449, -5331, 5805, 449, -5323, 5781, 421, -5295, 5793, 437, -5283, 5801, 437, -5283, 5793, 429, -5275, 5805, 457, -5291, 5805, 457, -5331, 5789, 437, -5323, 5793, 445, -5311, 5781, 449, -5291, 5797, 421, -5263, 5781, 429, -5287, 5809, 445, -5291, 5789, 445, -5311, 5801, 457, -5291, 5829, 437, -5295, 5809, 429, -5283, 5805, 433, -5279, 5801, 429, -5287, 5805, 429, -5291, 5781, 429, -5287, 5781, 417, -5271, 5777, 425, -5283, 5789, 461, -5275, 5801, 469, -5283, 5801, 445, -5303, 5793, 441, -5315, 5777, 421, -5311, 5801, 409, -5287, 5817, 429, -5299, 5817, 457, -5299, 5805, 449, -5295, 5801, 445, -5291, 5801, 441, -5307, 5809, 445, -5291, 5785, 429, -5303, 5785, 433, -5315, 5805, 449, -5291, 5789, 445, -5315, 5773, 449, -5303, 5781, 437, -5303, 5805, 453, -5295, 5785, 425, -5271, 5777, 433, -5259, 5797, 437, -5279, 5801, 433, -5283, 5793, 453, -5315, 5777, 445, -5287, 5789, 433, -5295, 5809, 437, -5303, 5801, 449, -5315, 5813, 449, -5291, 5797, 461, -5287, 5801, 453, -5283, 5809, 445, -5311, 5793, 425, -5311, 5769, 409, -5287, 5797, 433, -5279, 5801, 441, -5267, 5793, 441, -5279, 5801, 437, -5299, 5785, 421, -5319, 5797, 429, -5295, 5789, 445, -5287, 5797, 445, -5275, 5825, 445, -5271, 5841, 473, -5279, 5821, 449, -5287, 5801, 445, -5283, 5789, 409, -5307, 5793, 441, -5295, 5789, 413, -5291, 5781, 425, -5287, 5773, 413, -5275, 5785, 425, -5291, 5793, 437, -5303, 5793, 453, -5279, 5793, 425, -5283, 5817, 405, -5275, 5813, 441, -5287, 5805, 441, -5283, 5821, 437, -5279, 5821, 429, -5299, 5805, 441, -5311, 5797, 417, -5295, 5789, 433, -5287, 5761, 429, -5303, 5801, 433, -5283, 5793, 461, -5287, 5801, 457, -5283, 5805, 457, -5295, 5801, 441, -5303, 5781, 421, -5315, 5765, 417, -5283, 5789, 409, -5267, 5797, 409, -5267, 5809, 409, -5271, 5789, 437, -5283, 5801, 449, -5307, 5785, 457, -5315, 5781, 441, -5315, 5793, 441, -5291, 5801, 449, -5279, 5797, 433, -5271, 5813,                                                                                                                                                                                                                                },\r
+{125, 433, -5271, 5805, 437, -5283, 5797, 449, -5287, 5793, 437, -5279, 5805, 421, -5287, 5817, 433, -5323, 5797, 437, -5327, 5789, 433, -5319, 5769, 429, -5315, 5781, 445, -5331, 5773, 437, -5307, 5797, 473, -5291, 5813, 445, -5279, 5817, 441, -5283, 5777, 437, -5275, 5833, 417, -5303, 5825, 453, -5287, 5785, 461, -5283, 5777, 457, -5263, 5765, 405, -5315, 5801, 425, -5327, 5777, 441, -5319, 5773, 413, -5311, 5781, 449, -5307, 5781, 441, -5303, 5785, 429, -5315, 5801, 445, -5303, 5797, 441, -5287, 5801, 437, -5275, 5805, 433, -5283, 5825, 469, -5295, 5841, 469, -5307, 5805, 457, -5311, 5777, 453, -5307, 5773, 425, -5311, 5777, 425, -5295, 5801, 449, -5299, 5797, 461, -5287, 5789, 465, -5287, 5765, 453, -5299, 5765, 441, -5299, 5809, 437, -5287, 5825, 437, -5307, 5821, 445, -5303, 5809, 477, -5303, 5793, 469, -5287, 5805, 461, -5279, 5821, 449, -5315, 5821, 433, -5283, 5777, 441, -5299, 5773, 425, -5303, 5793, 441, -5323, 5781, 457, -5307, 5769, 457, -5299, 5785, 461, -5295, 5785, 441, -5291, 5797, 441, -5283, 5797, 441, -5287, 5817, 465, -5291, 5801, 473, -5295, 5785, 445, -5311, 5797, 445, -5319, 5789, 437, -5311, 5793, 453, -5307, 5801, 433, -5295, 5781, 449, -5291, 5785, 465, -5299, 5801, 457, -5311, 5793, 457, -5315, 5793, 449, -5307, 5781, 433, -5299, 5761, 457, -5279, 5781, 449, -5287, 5813, 469, -5295, 5801, 469, -5303, 5809, 465, -5311, 5777, 473, -5307, 5781, 457, -5307, 5793, 445, -5315, 5765, 417, -5299, 5769, 433, -5295, 5769, 465, -5299, 5785, 465, -5299, 5797, 465, -5303, 5809, 449, -5299, 5809, 461, -5291, 5785, 465, -5287, 5797, 453, -5291, 5773, 449, -5319, 5785, 445, -5327, 5781, 453, -5315, 5801, 469, -5323, 5817, 469, -5355, 5781, 549, -5251, 5701, 437, -5315, 5833, 453, -5323, 5765, 445, -5355, 5881, 509, -5311, 5701, 493, -5299, 5833, 465, -5351, 5745, 473, -5315, 5797, 473, -5303, 5761, 481, -5275, 5813, 453, -5271, 5765, 465, -5299, 5785, 457, -5351, 5761, 453, -5351, 5785, 493, -5315, 5737, 485, -5279, 5765, 449, -5299, 5765, 453, -5311, 5773, 469, -5315, 5777, 477, -5311, 5809, 481, -5339, 5789, 521, -5323, 5797, 505, -5307, 5773, 481, -5299, 5785, 457, -5315, 5785, 441, -5327, 5765, 461, -5323, 5769, 473, -5307, 5773, 481, -5303, 5773, 473, -5303, 5789, 469, -5307, 5781, 473, -5319, 5777,                                                                                                                                                                                                },\r
+{124, 489, -5295, 5777, 493, -5311, 5785, 469, -5319, 5781, 485, -5339, 5773, 489, -5327, 5797, 477, -5319, 5801, 477, -5311, 5781, 477, -5287, 5773, 489, -5299, 5777, 493, -5315, 5793, 493, -5343, 5781, 481, -5331, 5765, 469, -5323, 5765, 457, -5287, 5761, 453, -5275, 5777, 461, -5299, 5789, 473, -5331, 5777, 509, -5339, 5761, 509, -5331, 5781, 481, -5323, 5801, 477, -5315, 5785, 469, -5319, 5781, 477, -5303, 5793, 477, -5311, 5769, 473, -5323, 5777, 485, -5343, 5777, 477, -5343, 5777, 489, -5303, 5765, 481, -5299, 5753, 481, -5307, 5777, 477, -5307, 5789, 505, -5315, 5797, 501, -5343, 5777, 505, -5335, 5785, 501, -5323, 5761, 485, -5311, 5773, 469, -5315, 5773, 465, -5291, 5781, 469, -5307, 5769, 481, -5315, 5765, 469, -5339, 5773, 457, -5355, 5773, 461, -5339, 5765, 485, -5315, 5757, 481, -5271, 5777, 489, -5291, 5789, 497, -5307, 5801, 497, -5323, 5789, 497, -5315, 5801, 473, -5331, 5769, 465, -5323, 5781, 489, -5323, 5777, 501, -5315, 5777, 505, -5307, 5777, 481, -5315, 5773, 481, -5331, 5773, 493, -5339, 5769, 489, -5331, 5761, 485, -5311, 5769, 473, -5319, 5785, 489, -5315, 5789, 505, -5331, 5785, 521, -5331, 5765, 493, -5311, 5773, 477, -5299, 5753, 469, -5311, 5741, 461, -5319, 5757, 457, -5331, 5761, 489, -5299, 5741, 505, -5307, 5761, 481, -5339, 5773, 481, -5351, 5773, 513, -5335, 5801, 521, -5307, 5765, 489, -5319, 5805, 497, -5339, 5785, 477, -5355, 5785, 501, -5339, 5757, 509, -5307, 5773, 485, -5275, 5777, 453, -5291, 5789, 465, -5339, 5741, 481, -5339, 5745, 485, -5303, 5757, 493, -5283, 5773, 513, -5311, 5789, 489, -5347, 5761, 497, -5347, 5757, 509, -5327, 5781, 509, -5275, 5793, 493, -5307, 5805, 501, -5323, 5789, 485, -5319, 5805, 505, -5319, 5777, 509, -5311, 5765, 473, -5327, 5761, 473, -5315, 5753, 473, -5315, 5777, 477, -5303, 5789, 497, -5307, 5781, 481, -5303, 5773, 501, -5319, 5761, 493, -5319, 5789, 485, -5323, 5765, 469, -5339, 5773, 489, -5331, 5769, 485, -5319, 5765, 493, -5331, 5773, 497, -5335, 5781, 493, -5355, 5761, 493, -5323, 5769, 489, -5311, 5793, 497, -5323, 5777, 493, -5323, 5773, 497, -5315, 5785, 489, -5311, 5781, 493, -5307, 5769, 477, -5311, 5765, 481, -5331, 5777, 493, -5319, 5781, 477, -5331, 5789, 485, -5311, 5769, 501, -5319, 5773, 493, -5327, 5781,                                                                                                                                                                                                                                },\r
+{124, 497, -5339, 5769, 501, -5315, 5769, 489, -5319, 5765, 473, -5319, 5757, 465, -5319, 5773, 473, -5307, 5769, 477, -5303, 5785, 493, -5295, 5785, 505, -5311, 5793, 505, -5311, 5793, 489, -5307, 5765, 485, -5315, 5789, 489, -5339, 5777, 477, -5327, 5753, 485, -5323, 5781, 489, -5327, 5797, 517, -5307, 5793, 489, -5327, 5765, 501, -5335, 5765, 477, -5335, 5773, 473, -5327, 5773, 481, -5303, 5781, 513, -5319, 5793, 501, -5359, 5777, 513, -5339, 5781, 497, -5315, 5777, 497, -5291, 5777, 505, -5319, 5765, 477, -5323, 5753, 469, -5323, 5749, 461, -5295, 5753, 461, -5311, 5749, 489, -5291, 5761, 489, -5327, 5757, 485, -5311, 5785, 489, -5311, 5777, 481, -5319, 5789, 485, -5339, 5781, 473, -5323, 5773, 493, -5323, 5761, 493, -5327, 5757, 481, -5327, 5777, 493, -5339, 5785, 493, -5343, 5765, 473, -5343, 5765, 481, -5327, 5781, 497, -5319, 5793, 477, -5303, 5785, 493, -5307, 5785, 489, -5331, 5785, 485, -5331, 5769, 501, -5307, 5777, 485, -5319, 5777, 485, -5315, 5785, 517, -5315, 5793, 485, -5303, 5801, 489, -5303, 5797, 489, -5303, 5777, 489, -5307, 5789, 513, -5315, 5785, 493, -5307, 5789, 461, -5315, 5773, 469, -5311, 5777, 481, -5315, 5773, 473, -5315, 5761, 473, -5315, 5773, 481, -5311, 5773, 481, -5319, 5781, 469, -5331, 5777, 473, -5295, 5761, 485, -5311, 5773, 493, -5335, 5761, 493, -5319, 5781, 485, -5303, 5801, 473, -5311, 5789, 477, -5327, 5789, 485, -5315, 5797, 473, -5303, 5777, 485, -5315, 5789, 481, -5303, 5781, 465, -5315, 5777, 469, -5323, 5777, 465, -5319, 5769, 485, -5323, 5761, 489, -5331, 5785, 493, -5319, 5781, 501, -5331, 5765, 473, -5323, 5777, 481, -5307, 5773, 485, -5307, 5765, 465, -5327, 5769, 461, -5335, 5781, 461, -5319, 5773, 469, -5327, 5781, 469, -5299, 5781, 453, -5295, 5785, 473, -5279, 5773, 481, -5303, 5797, 501, -5323, 5813, 485, -5343, 5785, 465, -5319, 5797, 465, -5331, 5773, 457, -5335, 5773, 469, -5327, 5785, 485, -5307, 5789, 505, -5327, 5809, 501, -5311, 5805, 517, -5315, 5801, 501, -5335, 5777, 485, -5327, 5785, 481, -5315, 5777, 449, -5311, 5753, 441, -5271, 5777, 477, -5299, 5761, 469, -5315, 5765, 473, -5303, 5773, 465, -5303, 5769, 461, -5307, 5781, 453, -5319, 5789, 473, -5311, 5769, 493, -5319, 5765, 497, -5315, 5773, 477, -5335, 5761, 489, -5295, 5805,                                                                                                                                                                                                                                },\r
+{125, 485, -5319, 5797, 477, -5331, 5805, 453, -5323, 5777, 453, -5275, 5777, 441, -5287, 5773, 449, -5295, 5777, 473, -5315, 5753, 485, -5315, 5781, 473, -5307, 5765, 469, -5287, 5793, 485, -5299, 5801, 489, -5331, 5825, 493, -5327, 5793, 473, -5311, 5805, 477, -5315, 5805, 473, -5299, 5797, 477, -5291, 5781, 473, -5275, 5785, 465, -5283, 5805, 489, -5295, 5817, 465, -5307, 5793, 473, -5311, 5793, 481, -5303, 5789, 473, -5311, 5769, 449, -5299, 5781, 449, -5303, 5773, 453, -5291, 5761, 481, -5307, 5781, 469, -5295, 5805, 469, -5331, 5813, 453, -5323, 5793, 445, -5287, 5793, 465, -5303, 5785, 465, -5315, 5801, 477, -5303, 5765, 461, -5311, 5777, 501, -5311, 5793, 477, -5327, 5777, 461, -5295, 5785, 453, -5295, 5801, 469, -5299, 5785, 481, -5295, 5809, 481, -5311, 5785, 489, -5311, 5797, 453, -5311, 5797, 461, -5307, 5785, 461, -5311, 5777, 469, -5311, 5797, 449, -5315, 5781, 465, -5323, 5777, 465, -5307, 5785, 461, -5299, 5777, 485, -5291, 5789, 445, -5287, 5801, 465, -5299, 5785, 449, -5307, 5789, 457, -5291, 5809, 473, -5303, 5805, 481, -5303, 5805, 485, -5319, 5781, 457, -5343, 5785, 465, -5363, 5781, 477, -5355, 5781, 481, -5343, 5777, 485, -5295, 5801, 453, -5291, 5817, 469, -5303, 5801, 473, -5311, 5829, 461, -5307, 5813, 489, -5319, 5789, 465, -5319, 5781, 461, -5299, 5757, 449, -5311, 5773, 465, -5299, 5765, 457, -5319, 5757, 477, -5315, 5785, 477, -5335, 5797, 465, -5331, 5789, 461, -5299, 5801, 477, -5299, 5801, 461, -5295, 5793, 457, -5291, 5793, 441, -5295, 5797, 445, -5295, 5793, 469, -5291, 5797, 473, -5307, 5773, 465, -5339, 5761, 445, -5327, 5781, 433, -5335, 5777, 465, -5311, 5777, 469, -5283, 5813, 481, -5275, 5813, 497, -5303, 5797, 465, -5311, 5789, 453, -5327, 5793, 433, -5295, 5789, 425, -5295, 5785, 449, -5287, 5801, 457, -5303, 5805, 473, -5307, 5793, 501, -5295, 5805, 461, -5299, 5797, 465, -5303, 5785, 453, -5315, 5805, 461, -5311, 5805, 449, -5283, 5789, 437, -5279, 5765, 437, -5287, 5793, 445, -5295, 5793, 449, -5287, 5801, 437, -5295, 5789, 449, -5275, 5805, 457, -5275, 5809, 449, -5291, 5801, 465, -5299, 5805, 445, -5307, 5805, 461, -5295, 5797, 465, -5319, 5785, 453, -5311, 5797, 461, -5299, 5793, 453, -5303, 5793, 449, -5307, 5781, 441, -5271, 5797, 449, -5287, 5789, 465, -5319, 5813,                                                                                                                                                                                                },\r
+{124, 453, -5311, 5829, 477, -5311, 5797, 469, -5287, 5785, 465, -5311, 5789, 437, -5315, 5789, 441, -5319, 5781, 457, -5307, 5785, 457, -5311, 5781, 457, -5303, 5777, 461, -5295, 5781, 481, -5319, 5769, 473, -5303, 5793, 441, -5311, 5805, 433, -5291, 5797, 425, -5267, 5809, 445, -5259, 5817, 453, -5275, 5817, 461, -5327, 5809, 461, -5335, 5761, 453, -5339, 5757, 465, -5331, 5781, 469, -5347, 5781, 469, -5339, 5797, 465, -5307, 5801, 489, -5299, 5809, 469, -5327, 5797, 489, -5315, 5797, 465, -5315, 5801, 449, -5299, 5781, 449, -5283, 5777, 429, -5275, 5793, 449, -5283, 5797, 473, -5295, 5777, 485, -5323, 5765, 457, -5343, 5769, 453, -5323, 5741, 453, -5307, 5749, 465, -5323, 5769, 461, -5303, 5781, 461, -5295, 5809, 473, -5287, 5809, 465, -5335, 5797, 465, -5327, 5769, 461, -5303, 5773, 461, -5307, 5805, 469, -5291, 5789, 489, -5323, 5777, 473, -5343, 5773, 461, -5331, 5777, 465, -5315, 5761, 481, -5311, 5769, 473, -5303, 5793, 485, -5311, 5797, 501, -5291, 5809, 473, -5311, 5785, 469, -5311, 5793, 461, -5331, 5793, 473, -5323, 5773, 485, -5307, 5781, 473, -5311, 5777, 481, -5323, 5781, 477, -5307, 5773, 493, -5299, 5793, 501, -5299, 5781, 477, -5335, 5757, 485, -5343, 5745, 493, -5315, 5765, 513, -5295, 5753, 481, -5311, 5765, 453, -5327, 5757, 481, -5335, 5773, 493, -5307, 5769, 509, -5331, 5769, 497, -5355, 5781, 493, -5351, 5765, 493, -5347, 5749, 481, -5331, 5741, 473, -5331, 5733, 493, -5327, 5761, 493, -5347, 5757, 501, -5363, 5761, 517, -5335, 5749, 517, -5319, 5777, 509, -5327, 5757, 525, -5339, 5773, 525, -5343, 5773, 509, -5335, 5769, 501, -5343, 5781, 521, -5359, 5757, 513, -5347, 5745, 513, -5339, 5761, 493, -5331, 5753, 513, -5323, 5749, 509, -5351, 5741, 497, -5339, 5737, 517, -5363, 5741, 521, -5367, 5725, 489, -5327, 5729, 489, -5323, 5741, 517, -5323, 5761, 517, -5315, 5753, 533, -5339, 5761, 537, -5347, 5717, 513, -5391, 5753, 505, -5407, 5733, 517, -5363, 5717, 505, -5347, 5737, 517, -5327, 5757, 529, -5339, 5761, 533, -5343, 5761, 533, -5331, 5785, 521, -5331, 5789, 537, -5331, 5785, 557, -5339, 5773, 549, -5339, 5773, 537, -5347, 5765, 501, -5359, 5749, 537, -5359, 5757, 525, -5355, 5737, 517, -5343, 5725, 533, -5339, 5729, 525, -5347, 5725, 517, -5359, 5721, 497, -5355, 5721,                                                                                                                                                                                                                                },\r
+{125, 497, -5351, 5753, 513, -5315, 5749, 529, -5347, 5749, 541, -5351, 5761, 533, -5371, 5745, 545, -5355, 5745, 513, -5363, 5757, 513, -5351, 5753, 545, -5355, 5749, 553, -5363, 5757, 537, -5351, 5733, 525, -5351, 5741, 509, -5347, 5737, 509, -5359, 5729, 517, -5335, 5741, 553, -5331, 5749, 553, -5343, 5757, 541, -5367, 5741, 545, -5367, 5749, 525, -5355, 5765, 545, -5339, 5757, 537, -5339, 5773, 545, -5347, 5769, 545, -5355, 5769, 537, -5355, 5773, 541, -5351, 5749, 521, -5355, 5741, 505, -5331, 5733, 497, -5339, 5749, 529, -5319, 5769, 541, -5327, 5757, 557, -5355, 5757, 525, -5339, 5757, 517, -5339, 5737, 521, -5359, 5749, 509, -5355, 5741, 545, -5347, 5741, 505, -5347, 5737, 521, -5343, 5753, 521, -5359, 5745, 533, -5343, 5737, 529, -5335, 5757, 525, -5359, 5733, 537, -5351, 5741, 541, -5359, 5737, 533, -5347, 5741, 529, -5355, 5749, 533, -5315, 5769, 541, -5343, 5757, 541, -5355, 5749, 533, -5335, 5749, 529, -5351, 5749, 517, -5351, 5733, 513, -5335, 5733, 513, -5323, 5745, 521, -5315, 5733, 529, -5335, 5749, 529, -5343, 5725, 533, -5347, 5741, 525, -5367, 5725, 505, -5363, 5745, 509, -5343, 5745, 509, -5319, 5737, 541, -5319, 5757, 549, -5339, 5761, 537, -5323, 5777, 537, -5351, 5769, 505, -5351, 5753, 505, -5359, 5745, 517, -5351, 5749, 541, -5347, 5765, 561, -5347, 5749, 553, -5359, 5749, 529, -5347, 5737, 521, -5347, 5733, 501, -5343, 5765, 501, -5351, 5761, 517, -5343, 5765, 529, -5339, 5769, 529, -5335, 5761, 541, -5339, 5761, 537, -5339, 5757, 525, -5347, 5745, 521, -5347, 5737, 517, -5343, 5725, 509, -5351, 5741, 505, -5347, 5753, 505, -5327, 5741, 521, -5335, 5745, 525, -5339, 5753, 533, -5343, 5745, 517, -5335, 5737, 521, -5335, 5749, 525, -5331, 5745, 541, -5347, 5753, 517, -5355, 5765, 537, -5355, 5745, 537, -5347, 5757, 529, -5335, 5757, 517, -5335, 5729, 513, -5343, 5753, 509, -5351, 5753, 533, -5335, 5765, 533, -5339, 5757, 537, -5319, 5769, 521, -5343, 5749, 513, -5331, 5733, 525, -5331, 5773, 529, -5347, 5769, 549, -5355, 5757, 549, -5347, 5729, 529, -5331, 5745, 521, -5319, 5761, 521, -5331, 5773, 533, -5335, 5757, 541, -5339, 5769, 533, -5323, 5765, 529, -5339, 5745, 509, -5339, 5729, 501, -5339, 5725, 505, -5315, 5749, 489, -5315, 5753, 537, -5351, 5745, 545, -5359, 5765, 541, -5371, 5729,                                                                                                                                                                                                },\r
+{124, 517, -5351, 5745, 525, -5343, 5741, 513, -5315, 5753, 517, -5327, 5761, 537, -5351, 5765, 537, -5331, 5761, 521, -5339, 5745, 521, -5363, 5741, 525, -5335, 5765, 541, -5355, 5761, 533, -5367, 5721, 521, -5355, 5729, 509, -5335, 5749, 501, -5347, 5745, 521, -5351, 5749, 533, -5319, 5749, 541, -5343, 5757, 533, -5359, 5749, 525, -5335, 5757, 525, -5335, 5753, 517, -5347, 5729, 513, -5363, 5749, 509, -5371, 5741, 501, -5343, 5745, 529, -5315, 5757, 541, -5343, 5773, 541, -5351, 5745, 549, -5335, 5773, 533, -5319, 5765, 509, -5339, 5757, 505, -5343, 5757, 517, -5347, 5761, 549, -5355, 5753, 541, -5375, 5745, 561, -5363, 5749, 561, -5351, 5737, 549, -5335, 5773, 517, -5339, 5773, 521, -5339, 5757, 533, -5331, 5773, 537, -5339, 5765, 517, -5351, 5761, 529, -5327, 5757, 521, -5339, 5753, 517, -5335, 5745, 513, -5343, 5733, 505, -5339, 5725, 517, -5343, 5741, 529, -5355, 5733, 521, -5351, 5745, 501, -5347, 5761, 497, -5335, 5761, 505, -5319, 5753, 521, -5319, 5789, 517, -5343, 5773, 529, -5339, 5785, 533, -5343, 5749, 533, -5347, 5725, 517, -5339, 5729, 505, -5343, 5745, 533, -5347, 5745, 529, -5335, 5729, 517, -5347, 5757, 529, -5347, 5765, 521, -5331, 5765, 521, -5331, 5785, 529, -5331, 5777, 517, -5319, 5773, 513, -5335, 5773, 513, -5331, 5773, 521, -5327, 5765, 521, -5331, 5773, 517, -5359, 5761, 509, -5355, 5741, 509, -5351, 5761, 509, -5335, 5749, 517, -5319, 5737, 525, -5319, 5753, 509, -5327, 5761, 529, -5335, 5757, 529, -5323, 5773, 529, -5343, 5765, 501, -5335, 5749, 493, -5323, 5753, 489, -5323, 5765, 493, -5319, 5761, 517, -5323, 5749, 521, -5327, 5745, 509, -5359, 5757, 521, -5367, 5733, 513, -5363, 5753, 521, -5331, 5757, 505, -5327, 5765, 509, -5335, 5745, 497, -5343, 5757, 501, -5331, 5773, 537, -5343, 5769, 501, -5339, 5741, 505, -5351, 5745, 521, -5335, 5753, 513, -5339, 5757, 517, -5323, 5765, 525, -5343, 5769, 509, -5339, 5773, 517, -5335, 5749, 513, -5371, 5749, 521, -5367, 5749, 525, -5339, 5749, 497, -5299, 5757, 493, -5311, 5749, 501, -5331, 5769, 529, -5331, 5789, 545, -5319, 5761, 533, -5311, 5761, 509, -5319, 5757, 505, -5331, 5757, 497, -5327, 5769, 517, -5347, 5765, 513, -5363, 5761, 513, -5371, 5765, 525, -5383, 5789, 521, -5363, 5777, 529, -5339, 5757, 513, -5311, 5793,                                                                                                                                                                                                                                },\r
+{123, 497, -5307, 5777, 493, -5335, 5789, 493, -5335, 5765, 517, -5363, 5749, 525, -5343, 5745, 521, -5323, 5757, 505, -5315, 5765, 509, -5311, 5761, 501, -5303, 5725, 509, -5323, 5761, 481, -5363, 5753, 501, -5351, 5749, 509, -5323, 5757, 497, -5311, 5757, 485, -5327, 5769, 473, -5339, 5785, 497, -5335, 5781, 505, -5315, 5769, 501, -5303, 5773, 489, -5323, 5793, 505, -5331, 5749, 489, -5347, 5745, 485, -5339, 5765, 497, -5315, 5789, 521, -5319, 5773, 537, -5343, 5769, 529, -5347, 5769, 497, -5343, 5757, 489, -5315, 5777, 489, -5307, 5793, 485, -5311, 5789, 497, -5315, 5793, 521, -5331, 5769, 493, -5319, 5789, 493, -5311, 5773, 513, -5299, 5793, 525, -5335, 5749, 497, -5319, 5761, 485, -5323, 5761, 485, -5323, 5761, 497, -5319, 5785, 485, -5319, 5761, 481, -5315, 5765, 477, -5311, 5769, 473, -5323, 5793, 493, -5331, 5785, 493, -5307, 5773, 493, -5315, 5777, 493, -5331, 5757, 481, -5335, 5765, 481, -5331, 5749, 485, -5319, 5765, 485, -5315, 5765, 497, -5315, 5773, 489, -5327, 5789, 493, -5315, 5789, 517, -5315, 5773, 501, -5319, 5777, 505, -5315, 5785, 489, -5303, 5765, 469, -5307, 5773, 473, -5307, 5777, 461, -5311, 5777, 497, -5307, 5785, 509, -5331, 5765, 509, -5323, 5769, 505, -5319, 5757, 485, -5303, 5769, 473, -5295, 5785, 481, -5303, 5785, 473, -5295, 5761, 497, -5303, 5785, 501, -5299, 5813, 501, -5327, 5777, 469, -5303, 5761, 465, -5299, 5785, 477, -5307, 5801, 509, -5299, 5773, 481, -5311, 5793, 493, -5359, 5789, 505, -5355, 5793, 513, -5363, 5781, 501, -5319, 5753, 529, -5295, 5749, 505, -5259, 5765, 473, -5279, 5797, 469, -5339, 5829, 485, -5367, 5809, 537, -5371, 5773, 541, -5319, 5757, 513, -5275, 5741, 485, -5263, 5733, 457, -5279, 5757, 461, -5327, 5765, 477, -5347, 5769, 505, -5351, 5769, 509, -5343, 5785, 501, -5339, 5777, 489, -5315, 5769, 489, -5275, 5765, 489, -5275, 5789, 461, -5303, 5809, 497, -5355, 5789, 521, -5363, 5789, 525, -5351, 5745, 525, -5307, 5741, 481, -5303, 5753, 457, -5319, 5781, 465, -5319, 5785, 513, -5327, 5789, 533, -5315, 5781, 521, -5331, 5785, 529, -5347, 5773, 489, -5311, 5737, 485, -5303, 5777, 481, -5311, 5801, 525, -5327, 5797, 529, -5347, 5789, 525, -5351, 5757, 505, -5327, 5765, 493, -5287, 5781, 477, -5295, 5757, 489, -5311, 5769,                                                                                                                                                                                                                                                                },\r
+{125, 493, -5347, 5761, 497, -5351, 5761, 497, -5347, 5753, 513, -5331, 5753, 489, -5307, 5761, 485, -5291, 5769, 473, -5299, 5769, 481, -5307, 5769, 505, -5327, 5777, 505, -5331, 5761, 517, -5355, 5785, 517, -5347, 5781, 505, -5331, 5757, 513, -5299, 5729, 489, -5295, 5757, 481, -5327, 5773, 493, -5339, 5777, 505, -5347, 5777, 521, -5347, 5761, 505, -5299, 5761, 501, -5299, 5781, 469, -5315, 5773, 489, -5295, 5769, 521, -5319, 5773, 509, -5335, 5781, 509, -5351, 5761, 517, -5355, 5757, 517, -5319, 5753, 505, -5299, 5761, 489, -5315, 5781, 505, -5311, 5757, 517, -5327, 5741, 505, -5339, 5745, 513, -5343, 5761, 509, -5307, 5769, 513, -5307, 5777, 489, -5311, 5765, 493, -5303, 5769, 533, -5319, 5749, 517, -5331, 5757, 517, -5351, 5761, 489, -5355, 5761, 493, -5359, 5749, 505, -5339, 5757, 525, -5343, 5761, 517, -5335, 5749, 529, -5335, 5753, 517, -5331, 5773, 521, -5347, 5785, 509, -5347, 5781, 497, -5315, 5761, 517, -5327, 5753, 501, -5335, 5749, 513, -5343, 5773, 529, -5323, 5757, 517, -5339, 5745, 517, -5347, 5725, 509, -5327, 5737, 505, -5359, 5737, 525, -5355, 5733, 517, -5335, 5741, 501, -5335, 5773, 501, -5331, 5785, 509, -5323, 5797, 517, -5311, 5781, 513, -5327, 5757, 529, -5351, 5741, 517, -5367, 5749, 497, -5359, 5745, 513, -5319, 5761, 529, -5319, 5761, 521, -5339, 5757, 509, -5335, 5741, 525, -5347, 5737, 533, -5339, 5745, 525, -5327, 5781, 521, -5335, 5773, 509, -5339, 5769, 489, -5327, 5753, 493, -5319, 5757, 537, -5331, 5761, 525, -5347, 5769, 537, -5343, 5769, 545, -5327, 5765, 529, -5335, 5769, 529, -5351, 5761, 525, -5339, 5757, 521, -5303, 5777, 509, -5303, 5761, 513, -5311, 5757, 513, -5327, 5749, 509, -5339, 5737, 505, -5335, 5753, 525, -5339, 5753, 509, -5327, 5745, 537, -5327, 5753, 509, -5335, 5749, 509, -5339, 5765, 509, -5335, 5753, 513, -5335, 5749, 525, -5351, 5741, 521, -5339, 5745, 513, -5351, 5761, 525, -5343, 5745, 517, -5335, 5769, 517, -5339, 5757, 529, -5335, 5765, 525, -5351, 5769, 521, -5367, 5773, 525, -5335, 5741, 521, -5315, 5737, 493, -5327, 5773, 501, -5351, 5757, 537, -5355, 5733, 537, -5355, 5725, 537, -5363, 5733, 513, -5363, 5745, 509, -5327, 5745, 529, -5355, 5757, 513, -5343, 5741, 521, -5343, 5745, 553, -5343, 5753, 537, -5327, 5753, 513, -5339, 5737, 517, -5327, 5749,                                                                                                                                                                                                },\r
+{124, 521, -5335, 5753, 509, -5335, 5733, 521, -5335, 5753, 533, -5339, 5781, 541, -5367, 5777, 541, -5367, 5753, 549, -5359, 5749, 533, -5347, 5729, 533, -5319, 5741, 521, -5335, 5773, 525, -5351, 5757, 533, -5343, 5745, 541, -5343, 5761, 517, -5363, 5765, 509, -5355, 5761, 541, -5339, 5761, 549, -5339, 5737, 537, -5323, 5737, 521, -5323, 5737, 521, -5327, 5733, 529, -5351, 5725, 529, -5367, 5741, 517, -5347, 5737, 521, -5355, 5721, 533, -5359, 5741, 537, -5327, 5753, 521, -5331, 5753, 521, -5351, 5781, 541, -5359, 5761, 549, -5363, 5737, 533, -5351, 5733, 529, -5363, 5729, 521, -5343, 5725, 517, -5331, 5733, 553, -5327, 5741, 529, -5359, 5741, 541, -5371, 5729, 553, -5367, 5761, 557, -5355, 5745, 553, -5351, 5741, 521, -5331, 5741, 537, -5339, 5765, 537, -5343, 5737, 541, -5355, 5761, 553, -5355, 5745, 553, -5355, 5761, 541, -5367, 5757, 553, -5343, 5753, 553, -5351, 5761, 525, -5327, 5733, 525, -5319, 5765, 529, -5347, 5765, 557, -5371, 5745, 553, -5355, 5749, 545, -5327, 5741, 513, -5339, 5737, 501, -5343, 5737, 509, -5343, 5737, 529, -5347, 5757, 545, -5355, 5757, 553, -5379, 5737, 545, -5371, 5741, 537, -5331, 5745, 537, -5327, 5741, 533, -5339, 5757, 529, -5351, 5745, 537, -5367, 5741, 529, -5359, 5737, 565, -5343, 5741, 533, -5343, 5753, 537, -5347, 5745, 537, -5359, 5737, 537, -5343, 5733, 545, -5355, 5745, 529, -5367, 5753, 537, -5363, 5741, 537, -5343, 5741, 529, -5331, 5737, 549, -5347, 5745, 549, -5347, 5745, 541, -5327, 5729, 561, -5347, 5757, 553, -5355, 5733, 541, -5355, 5705, 529, -5359, 5733, 513, -5359, 5737, 541, -5359, 5753, 529, -5335, 5753, 553, -5315, 5761, 549, -5319, 5765, 529, -5351, 5761, 521, -5375, 5749, 529, -5363, 5725, 549, -5355, 5733, 545, -5351, 5757, 549, -5359, 5757, 533, -5375, 5749, 549, -5359, 5737, 561, -5351, 5741, 541, -5351, 5741, 533, -5355, 5741, 545, -5359, 5729, 529, -5347, 5761, 537, -5331, 5757, 545, -5359, 5781, 537, -5351, 5745, 549, -5351, 5745, 553, -5335, 5717, 517, -5323, 5713, 505, -5335, 5733, 501, -5347, 5741, 509, -5347, 5745, 545, -5351, 5733, 565, -5363, 5733, 537, -5351, 5737, 537, -5347, 5745, 537, -5339, 5761, 533, -5331, 5773, 537, -5347, 5753, 537, -5367, 5741, 557, -5359, 5753, 553, -5355, 5729, 545, -5331, 5721, 517, -5327, 5733,                                                                                                                                                                                                                                },\r
+{124, 509, -5347, 5745, 549, -5359, 5761, 573, -5375, 5761, 565, -5359, 5769, 557, -5339, 5749, 545, -5327, 5733, 517, -5331, 5753, 533, -5335, 5769, 541, -5355, 5761, 553, -5363, 5753, 553, -5371, 5725, 561, -5359, 5737, 537, -5363, 5729, 513, -5347, 5737, 525, -5327, 5749, 545, -5323, 5753, 537, -5319, 5773, 549, -5363, 5753, 545, -5343, 5729, 533, -5351, 5717, 521, -5339, 5737, 509, -5347, 5749, 505, -5347, 5729, 529, -5347, 5737, 537, -5347, 5753, 541, -5359, 5741, 545, -5371, 5745, 545, -5371, 5729, 545, -5355, 5745, 533, -5359, 5737, 529, -5351, 5725, 533, -5367, 5737, 537, -5367, 5761, 525, -5363, 5761, 545, -5335, 5753, 545, -5331, 5761, 541, -5339, 5745, 549, -5355, 5733, 553, -5379, 5753, 541, -5339, 5733, 521, -5351, 5737, 529, -5359, 5725, 541, -5351, 5745, 561, -5339, 5741, 557, -5335, 5733, 549, -5363, 5749, 533, -5359, 5757, 541, -5359, 5737, 533, -5355, 5725, 525, -5343, 5725, 513, -5359, 5753, 537, -5355, 5749, 541, -5335, 5773, 541, -5343, 5773, 569, -5347, 5757, 541, -5343, 5725, 533, -5371, 5737, 525, -5355, 5729, 525, -5363, 5737, 553, -5395, 5737, 553, -5375, 5745, 557, -5371, 5721, 545, -5359, 5761, 545, -5331, 5749, 529, -5339, 5765, 533, -5363, 5737, 541, -5351, 5737, 561, -5375, 5729, 537, -5383, 5733, 553, -5347, 5749, 549, -5335, 5745, 545, -5335, 5745, 545, -5355, 5729, 557, -5359, 5733, 529, -5347, 5725, 541, -5355, 5733, 537, -5351, 5729, 533, -5359, 5749, 537, -5363, 5753, 549, -5343, 5761, 553, -5355, 5753, 541, -5355, 5761, 537, -5371, 5765, 565, -5343, 5745, 561, -5355, 5729, 561, -5367, 5713, 545, -5359, 5741, 537, -5351, 5745, 525, -5367, 5753, 549, -5351, 5785, 553, -5351, 5757, 553, -5339, 5769, 537, -5359, 5781, 537, -5355, 5757, 557, -5339, 5757, 561, -5327, 5745, 537, -5347, 5753, 541, -5363, 5761, 549, -5359, 5741, 533, -5355, 5745, 529, -5347, 5749, 521, -5323, 5729, 525, -5327, 5737, 525, -5335, 5737, 525, -5327, 5753, 537, -5343, 5757, 533, -5347, 5745, 537, -5351, 5749, 537, -5363, 5753, 525, -5351, 5741, 529, -5343, 5749, 529, -5335, 5753, 525, -5379, 5749, 497, -5367, 5753, 505, -5355, 5753, 517, -5343, 5757, 541, -5347, 5749, 533, -5355, 5753, 533, -5335, 5753, 537, -5319, 5765, 541, -5331, 5761, 537, -5343, 5773, 529, -5347, 5741, 529, -5359, 5737,                                                                                                                                                                                                                                },\r
+{125, 537, -5335, 5745, 525, -5347, 5737, 517, -5347, 5749, 529, -5343, 5777, 529, -5331, 5765, 529, -5343, 5753, 517, -5347, 5753, 525, -5343, 5749, 521, -5339, 5753, 529, -5343, 5773, 521, -5327, 5745, 501, -5339, 5745, 521, -5335, 5741, 517, -5331, 5761, 521, -5351, 5757, 517, -5331, 5769, 517, -5303, 5761, 509, -5307, 5777, 525, -5335, 5769, 537, -5351, 5749, 525, -5355, 5749, 501, -5355, 5733, 509, -5379, 5741, 541, -5371, 5769, 533, -5363, 5765, 549, -5363, 5757, 541, -5343, 5773, 529, -5319, 5809, 509, -5311, 5777, 509, -5299, 5781, 501, -5319, 5761, 521, -5343, 5757, 525, -5343, 5745, 529, -5343, 5749, 545, -5319, 5745, 513, -5323, 5741, 509, -5351, 5749, 485, -5351, 5749, 489, -5339, 5753, 493, -5335, 5757, 521, -5331, 5761, 505, -5335, 5749, 513, -5327, 5777, 497, -5335, 5773, 513, -5331, 5781, 517, -5319, 5761, 525, -5303, 5749, 521, -5323, 5781, 493, -5363, 5757, 505, -5367, 5761, 505, -5331, 5737, 513, -5311, 5749, 509, -5311, 5789, 509, -5339, 5773, 529, -5335, 5753, 509, -5339, 5753, 489, -5339, 5781, 485, -5339, 5781, 481, -5347, 5789, 521, -5331, 5777, 521, -5315, 5785, 525, -5311, 5793, 509, -5307, 5765, 505, -5323, 5757, 509, -5327, 5753, 489, -5335, 5761, 509, -5343, 5753, 497, -5327, 5745, 497, -5323, 5769, 493, -5315, 5769, 477, -5311, 5773, 501, -5303, 5777, 501, -5323, 5777, 485, -5355, 5761, 501, -5339, 5761, 501, -5327, 5773, 489, -5311, 5765, 493, -5327, 5777, 497, -5323, 5761, 509, -5343, 5753, 493, -5347, 5757, 505, -5339, 5781, 501, -5331, 5773, 497, -5323, 5773, 485, -5303, 5785, 509, -5303, 5797, 509, -5335, 5785, 509, -5339, 5765, 497, -5343, 5737, 497, -5335, 5765, 485, -5327, 5749, 501, -5339, 5765, 505, -5311, 5761, 501, -5323, 5765, 481, -5327, 5773, 481, -5335, 5753, 493, -5339, 5773, 477, -5315, 5765, 501, -5307, 5761, 497, -5303, 5773, 477, -5303, 5789, 473, -5303, 5789, 493, -5287, 5765, 501, -5327, 5785, 525, -5363, 5777, 501, -5379, 5753, 493, -5367, 5761, 497, -5347, 5757, 481, -5331, 5765, 497, -5323, 5773, 497, -5351, 5765, 497, -5335, 5781, 513, -5319, 5793, 513, -5315, 5757, 477, -5307, 5781, 453, -5295, 5797, 477, -5307, 5773, 493, -5311, 5757, 501, -5335, 5761, 517, -5355, 5753, 509, -5331, 5785, 513, -5343, 5753, 473, -5315, 5769, 477, -5319, 5753, 469, -5319, 5761,                                                                                                                                                                                                },\r
+{124, 465, -5315, 5773, 477, -5315, 5781, 477, -5331, 5769, 497, -5323, 5773, 493, -5323, 5773, 501, -5287, 5781, 517, -5299, 5813, 497, -5339, 5789, 497, -5335, 5773, 477, -5359, 5761, 481, -5339, 5769, 477, -5319, 5773, 489, -5315, 5781, 477, -5307, 5765, 493, -5291, 5769, 485, -5303, 5781, 497, -5343, 5789, 497, -5343, 5789, 513, -5331, 5785, 505, -5315, 5793, 497, -5315, 5777, 513, -5299, 5765, 485, -5327, 5745, 473, -5319, 5761, 473, -5319, 5773, 485, -5319, 5773, 493, -5319, 5765, 489, -5299, 5781, 481, -5323, 5773, 485, -5327, 5785, 469, -5295, 5765, 489, -5291, 5781, 489, -5295, 5777, 497, -5339, 5773, 481, -5367, 5765, 489, -5347, 5761, 465, -5327, 5769, 505, -5331, 5789, 501, -5319, 5769, 497, -5331, 5765, 489, -5339, 5773, 481, -5331, 5777, 497, -5315, 5777, 485, -5287, 5773, 497, -5295, 5777, 481, -5319, 5789, 501, -5323, 5789, 497, -5323, 5781, 501, -5339, 5765, 501, -5335, 5781, 489, -5335, 5761, 501, -5319, 5769, 481, -5311, 5777, 457, -5311, 5789, 445, -5319, 5773, 489, -5343, 5769, 477, -5303, 5765, 485, -5311, 5777, 493, -5315, 5773, 489, -5291, 5781, 485, -5295, 5777, 481, -5295, 5789, 497, -5303, 5793, 521, -5319, 5773, 521, -5335, 5761, 505, -5359, 5769, 481, -5359, 5749, 473, -5339, 5753, 485, -5343, 5769, 493, -5347, 5785, 501, -5331, 5797, 505, -5339, 5789, 489, -5331, 5781, 505, -5307, 5777, 489, -5319, 5797, 477, -5295, 5781, 481, -5307, 5793, 493, -5323, 5789, 517, -5355, 5753, 497, -5315, 5761, 489, -5319, 5765, 493, -5319, 5749, 477, -5339, 5769, 465, -5327, 5765, 473, -5331, 5765, 489, -5311, 5761, 489, -5323, 5773, 489, -5331, 5769, 473, -5319, 5769, 493, -5315, 5793, 477, -5315, 5773, 505, -5327, 5785, 517, -5343, 5773, 517, -5343, 5773, 505, -5327, 5757, 493, -5339, 5761, 509, -5339, 5777, 501, -5335, 5753, 505, -5335, 5765, 513, -5307, 5777, 473, -5307, 5773, 509, -5327, 5757, 485, -5351, 5765, 477, -5323, 5769, 505, -5311, 5777, 521, -5331, 5805, 505, -5327, 5773, 509, -5335, 5781, 501, -5331, 5801, 501, -5311, 5805, 489, -5315, 5777, 501, -5311, 5761, 517, -5335, 5737, 485, -5335, 5761, 481, -5327, 5733, 473, -5299, 5773, 497, -5323, 5765, 509, -5343, 5761, 501, -5323, 5757, 505, -5303, 5761, 489, -5311, 5781, 493, -5327, 5773, 509, -5355, 5781, 521, -5343, 5757,                                                                                                                                                                                                                                },\r
+{125, 485, -5351, 5749, 497, -5347, 5741, 489, -5343, 5761, 505, -5343, 5777, 517, -5335, 5753, 509, -5331, 5777, 497, -5355, 5761, 505, -5331, 5749, 485, -5327, 5753, 489, -5311, 5769, 505, -5315, 5777, 517, -5335, 5769, 525, -5323, 5769, 509, -5339, 5753, 497, -5347, 5769, 497, -5351, 5765, 505, -5339, 5741, 485, -5327, 5753, 505, -5335, 5757, 501, -5327, 5765, 509, -5319, 5765, 493, -5307, 5761, 489, -5291, 5785, 533, -5299, 5801, 537, -5323, 5785, 505, -5327, 5761, 505, -5343, 5749, 493, -5347, 5765, 505, -5359, 5757, 521, -5355, 5753, 505, -5359, 5757, 505, -5343, 5761, 521, -5351, 5773, 509, -5343, 5761, 525, -5335, 5769, 505, -5343, 5773, 521, -5331, 5773, 517, -5311, 5785, 525, -5323, 5781, 525, -5335, 5753, 509, -5335, 5741, 509, -5339, 5737, 493, -5351, 5729, 513, -5351, 5741, 513, -5355, 5741, 513, -5335, 5749, 537, -5343, 5745, 501, -5331, 5761, 509, -5331, 5761, 525, -5323, 5753, 521, -5343, 5769, 533, -5335, 5765, 517, -5343, 5761, 529, -5343, 5757, 533, -5335, 5769, 517, -5347, 5753, 545, -5335, 5749, 529, -5343, 5741, 533, -5335, 5761, 513, -5339, 5773, 525, -5327, 5757, 517, -5323, 5749, 517, -5311, 5753, 513, -5339, 5753, 517, -5343, 5753, 521, -5343, 5737, 525, -5347, 5753, 521, -5359, 5749, 533, -5359, 5757, 533, -5351, 5761, 537, -5335, 5753, 537, -5319, 5781, 533, -5331, 5761, 529, -5331, 5773, 537, -5323, 5761, 529, -5339, 5749, 529, -5343, 5753, 517, -5351, 5729, 521, -5355, 5741, 521, -5343, 5745, 509, -5347, 5749, 521, -5339, 5753, 541, -5367, 5749, 541, -5355, 5745, 537, -5331, 5757, 537, -5363, 5753, 525, -5351, 5741, 541, -5347, 5749, 521, -5351, 5757, 541, -5347, 5749, 537, -5363, 5753, 537, -5351, 5765, 541, -5343, 5773, 549, -5339, 5761, 561, -5367, 5757, 529, -5355, 5737, 533, -5331, 5753, 537, -5335, 5737, 533, -5339, 5725, 533, -5339, 5745, 517, -5343, 5741, 549, -5351, 5753, 553, -5367, 5749, 537, -5371, 5741, 537, -5363, 5721, 533, -5323, 5741, 537, -5319, 5749, 549, -5327, 5753, 533, -5343, 5757, 545, -5351, 5753, 569, -5363, 5749, 545, -5351, 5749, 529, -5355, 5741, 533, -5335, 5717, 537, -5343, 5769, 541, -5371, 5761, 561, -5383, 5753, 573, -5363, 5749, 569, -5351, 5725, 537, -5331, 5745, 517, -5343, 5745, 541, -5383, 5745, 553, -5371, 5725, 549, -5359, 5741, 553, -5343, 5741,                                                                                                                                                                                                },\r
+{124, 529, -5339, 5765, 549, -5335, 5725, 549, -5319, 5705, 537, -5347, 5709, 521, -5367, 5717, 545, -5379, 5733, 533, -5387, 5725, 533, -5375, 5725, 557, -5355, 5737, 545, -5335, 5745, 545, -5339, 5753, 541, -5347, 5749, 541, -5387, 5737, 545, -5375, 5745, 557, -5379, 5729, 533, -5371, 5741, 541, -5363, 5749, 537, -5347, 5737, 549, -5339, 5729, 533, -5351, 5749, 525, -5363, 5741, 549, -5379, 5745, 581, -5371, 5745, 577, -5331, 5749, 545, -5347, 5733, 529, -5351, 5741, 521, -5359, 5745, 553, -5367, 5737, 549, -5351, 5745, 565, -5351, 5753, 553, -5351, 5753, 565, -5355, 5737, 565, -5343, 5749, 553, -5355, 5753, 541, -5347, 5769, 537, -5367, 5725, 553, -5343, 5729, 561, -5359, 5741, 541, -5327, 5733, 525, -5339, 5721, 549, -5347, 5741, 533, -5363, 5721, 537, -5363, 5705, 545, -5363, 5725, 557, -5355, 5749, 557, -5347, 5733, 561, -5335, 5741, 569, -5351, 5725, 573, -5351, 5741, 561, -5359, 5753, 553, -5363, 5733, 541, -5387, 5701, 529, -5367, 5729, 549, -5363, 5737, 537, -5359, 5737, 533, -5351, 5737, 577, -5351, 5729, 573, -5367, 5745, 561, -5371, 5757, 561, -5355, 5741, 565, -5359, 5753, 549, -5359, 5749, 565, -5343, 5713, 549, -5343, 5721, 525, -5375, 5725, 525, -5399, 5725, 529, -5379, 5729, 541, -5375, 5725, 557, -5367, 5725, 557, -5351, 5749, 557, -5347, 5749, 565, -5323, 5741, 577, -5319, 5749, 533, -5363, 5741, 537, -5363, 5717, 549, -5379, 5733, 525, -5383, 5717, 533, -5359, 5717, 565, -5359, 5733, 569, -5379, 5733, 585, -5391, 5729, 581, -5419, 5729, 561, -5379, 5729, 553, -5359, 5741, 549, -5351, 5741, 565, -5367, 5733, 557, -5375, 5729, 557, -5367, 5737, 569, -5343, 5733, 541, -5335, 5725, 557, -5379, 5729, 553, -5363, 5721, 537, -5371, 5729, 533, -5375, 5709, 553, -5367, 5701, 553, -5363, 5713, 561, -5371, 5721, 549, -5387, 5725, 533, -5351, 5745, 553, -5359, 5749, 553, -5359, 5705, 569, -5371, 5729, 593, -5383, 5713, 557, -5371, 5717, 561, -5359, 5713, 569, -5379, 5733, 549, -5375, 5713, 533, -5383, 5721, 569, -5387, 5717, 573, -5387, 5721, 589, -5359, 5733, 565, -5331, 5741, 553, -5375, 5781, 577, -5383, 5749, 569, -5383, 5725, 565, -5387, 5717, 545, -5367, 5717, 565, -5383, 5717, 545, -5367, 5725, 553, -5379, 5729, 565, -5379, 5717, 565, -5363, 5721, 585, -5355, 5753, 585, -5367, 5749,                                                                                                                                                                                                                                },\r
+{124, 561, -5355, 5741, 541, -5351, 5725, 553, -5339, 5737, 553, -5363, 5725, 557, -5367, 5701, 537, -5391, 5705, 533, -5383, 5713, 561, -5359, 5705, 553, -5383, 5701, 565, -5383, 5745, 581, -5379, 5717, 573, -5387, 5737, 557, -5371, 5749, 565, -5359, 5729, 537, -5359, 5725, 533, -5363, 5737, 557, -5359, 5729, 585, -5375, 5733, 585, -5363, 5721, 585, -5375, 5733, 573, -5391, 5717, 545, -5387, 5733, 549, -5343, 5737, 545, -5331, 5713, 553, -5347, 5741, 541, -5355, 5729, 545, -5367, 5737, 553, -5379, 5721, 573, -5387, 5729, 585, -5383, 5705, 565, -5395, 5701, 525, -5387, 5717, 537, -5355, 5741, 553, -5363, 5733, 577, -5339, 5721, 561, -5351, 5749, 553, -5347, 5733, 561, -5355, 5717, 541, -5347, 5709, 537, -5379, 5729, 521, -5395, 5725, 557, -5391, 5733, 569, -5391, 5753, 593, -5363, 5737, 573, -5391, 5709, 557, -5383, 5729, 553, -5379, 5721, 553, -5379, 5725, 533, -5371, 5721, 545, -5367, 5737, 549, -5363, 5745, 553, -5339, 5725, 557, -5343, 5741, 565, -5355, 5717, 557, -5375, 5709, 549, -5379, 5713, 533, -5387, 5717, 545, -5383, 5685, 533, -5371, 5717, 537, -5367, 5713, 537, -5359, 5725, 545, -5351, 5761, 541, -5367, 5741, 545, -5371, 5737, 553, -5375, 5733, 545, -5351, 5733, 521, -5335, 5721, 541, -5335, 5729, 557, -5355, 5725, 561, -5379, 5713, 545, -5371, 5725, 545, -5371, 5749, 557, -5371, 5729, 557, -5351, 5737, 553, -5351, 5757, 549, -5371, 5729, 541, -5375, 5737, 537, -5371, 5741, 549, -5391, 5729, 557, -5363, 5737, 545, -5375, 5729, 565, -5359, 5733, 557, -5371, 5717, 545, -5355, 5737, 549, -5335, 5709, 525, -5347, 5725, 541, -5355, 5749, 537, -5363, 5717, 557, -5371, 5733, 557, -5359, 5741, 541, -5375, 5717, 549, -5363, 5733, 533, -5367, 5725, 533, -5363, 5733, 541, -5363, 5745, 545, -5371, 5737, 545, -5367, 5717, 545, -5371, 5733, 537, -5359, 5737, 509, -5355, 5709, 533, -5367, 5725, 529, -5359, 5721, 537, -5355, 5737, 565, -5343, 5721, 573, -5371, 5729, 569, -5383, 5749, 537, -5347, 5733, 529, -5339, 5745, 537, -5335, 5741, 553, -5359, 5769, 557, -5395, 5761, 561, -5391, 5757, 561, -5379, 5737, 549, -5375, 5713, 529, -5379, 5709, 513, -5387, 5693, 509, -5371, 5697, 521, -5347, 5709, 529, -5343, 5717, 541, -5351, 5725, 561, -5339, 5749, 565, -5371, 5761, 545, -5351, 5749, 541, -5359, 5729,                                                                                                                                                                                                                                },\r
+{125, 541, -5355, 5741, 533, -5387, 5713, 541, -5387, 5713, 533, -5403, 5689, 545, -5411, 5713, 541, -5407, 5717, 533, -5399, 5725, 565, -5379, 5749, 561, -5355, 5753, 533, -5355, 5745, 537, -5343, 5753, 549, -5355, 5757, 553, -5347, 5757, 537, -5339, 5737, 553, -5339, 5725, 549, -5383, 5725, 533, -5387, 5697, 521, -5387, 5697, 513, -5363, 5705, 513, -5367, 5717, 537, -5363, 5737, 561, -5355, 5745, 573, -5363, 5729, 549, -5355, 5749, 545, -5347, 5761, 549, -5343, 5741, 541, -5327, 5741, 545, -5331, 5757, 549, -5347, 5721, 541, -5383, 5733, 537, -5395, 5717, 533, -5379, 5721, 565, -5327, 5721, 537, -5319, 5737, 545, -5367, 5737, 561, -5399, 5737, 545, -5395, 5741, 549, -5355, 5757, 521, -5323, 5753, 557, -5347, 5781, 545, -5355, 5745, 533, -5359, 5733, 545, -5347, 5737, 537, -5375, 5733, 533, -5379, 5737, 525, -5367, 5717, 541, -5335, 5713, 545, -5363, 5725, 545, -5351, 5717, 537, -5363, 5725, 541, -5363, 5737, 549, -5359, 5749, 537, -5343, 5769, 557, -5371, 5753, 537, -5379, 5713, 513, -5367, 5725, 501, -5355, 5737, 505, -5367, 5753, 517, -5339, 5737, 545, -5367, 5725, 557, -5399, 5729, 553, -5399, 5721, 549, -5379, 5749, 545, -5351, 5745, 533, -5343, 5717, 533, -5379, 5745, 541, -5371, 5745, 517, -5371, 5745, 521, -5355, 5745, 533, -5343, 5729, 529, -5339, 5733, 525, -5359, 5709, 545, -5359, 5701, 529, -5355, 5729, 553, -5351, 5725, 553, -5383, 5741, 549, -5383, 5761, 541, -5367, 5733, 561, -5367, 5721, 533, -5371, 5733, 533, -5343, 5737, 517, -5339, 5729, 521, -5323, 5741, 545, -5339, 5737, 569, -5375, 5737, 561, -5379, 5725, 589, -5379, 5713, 541, -5395, 5701, 529, -5387, 5705, 521, -5379, 5717, 517, -5391, 5733, 549, -5379, 5733, 561, -5363, 5737, 561, -5367, 5757, 541, -5387, 5749, 553, -5371, 5757, 541, -5347, 5757, 569, -5351, 5737, 569, -5359, 5737, 537, -5375, 5705, 545, -5359, 5693, 525, -5371, 5693, 513, -5367, 5705, 521, -5363, 5721, 545, -5335, 5725, 545, -5359, 5725, 553, -5379, 5729, 565, -5367, 5757, 545, -5355, 5749, 517, -5343, 5737, 529, -5351, 5765, 533, -5355, 5725, 529, -5355, 5705, 541, -5375, 5729, 545, -5375, 5725, 553, -5391, 5725, 557, -5395, 5741, 553, -5379, 5753, 593, -5367, 5753, 577, -5355, 5729, 601, -5359, 5765, 565, -5367, 5741, 577, -5367, 5717, 525, -5367, 5717, 549, -5387, 5717,                                                                                                                                                                                                },\r
+{124, 553, -5371, 5717, 533, -5363, 5717, 537, -5383, 5729, 545, -5387, 5721, 545, -5367, 5737, 549, -5355, 5733, 565, -5363, 5729, 561, -5367, 5713, 565, -5391, 5717, 537, -5371, 5697, 533, -5347, 5697, 541, -5371, 5717, 525, -5363, 5713, 533, -5367, 5705, 529, -5359, 5725, 537, -5355, 5729, 549, -5355, 5729, 561, -5355, 5733, 565, -5367, 5745, 557, -5387, 5725, 549, -5387, 5733, 545, -5395, 5733, 541, -5379, 5721, 533, -5367, 5701, 549, -5347, 5717, 565, -5391, 5717, 557, -5371, 5713, 553, -5371, 5729, 525, -5375, 5737, 533, -5371, 5753, 553, -5359, 5725, 541, -5347, 5721, 557, -5343, 5721, 553, -5363, 5733, 533, -5383, 5709, 557, -5383, 5725, 545, -5367, 5721, 541, -5355, 5733, 557, -5343, 5725, 545, -5359, 5729, 525, -5379, 5729, 521, -5359, 5721, 533, -5359, 5729, 545, -5359, 5741, 549, -5351, 5741, 537, -5339, 5737, 529, -5347, 5745, 537, -5339, 5733, 549, -5363, 5721, 553, -5411, 5721, 545, -5423, 5717, 553, -5415, 5701, 549, -5395, 5721, 557, -5367, 5729, 541, -5359, 5741, 549, -5363, 5745, 553, -5375, 5745, 557, -5383, 5749, 565, -5371, 5741, 537, -5371, 5741, 533, -5383, 5725, 533, -5355, 5721, 525, -5355, 5713, 541, -5363, 5701, 537, -5367, 5701, 525, -5363, 5697, 533, -5383, 5697, 545, -5387, 5721, 545, -5391, 5725, 565, -5363, 5725, 569, -5355, 5729, 549, -5363, 5749, 537, -5359, 5737, 533, -5387, 5721, 541, -5387, 5717, 537, -5359, 5725, 541, -5375, 5729, 545, -5403, 5733, 561, -5387, 5725, 565, -5363, 5733, 565, -5351, 5741, 541, -5363, 5741, 545, -5375, 5745, 561, -5371, 5737, 549, -5367, 5725, 557, -5363, 5725, 521, -5367, 5733, 533, -5391, 5705, 541, -5387, 5725, 549, -5371, 5733, 529, -5363, 5717, 545, -5359, 5745, 521, -5371, 5737, 553, -5347, 5733, 553, -5335, 5741, 553, -5343, 5713, 533, -5339, 5729, 521, -5351, 5713, 541, -5355, 5709, 533, -5359, 5729, 537, -5343, 5725, 545, -5355, 5757, 557, -5351, 5753, 541, -5375, 5745, 549, -5395, 5745, 537, -5383, 5721, 541, -5375, 5741, 541, -5355, 5717, 517, -5379, 5729, 533, -5383, 5717, 549, -5379, 5725, 557, -5359, 5749, 593, -5391, 5741, 581, -5391, 5741, 561, -5407, 5737, 549, -5359, 5725, 513, -5331, 5721, 493, -5331, 5709, 517, -5355, 5705, 505, -5367, 5697, 537, -5375, 5697, 513, -5363, 5697, 545, -5347, 5729, 533, -5359, 5737,                                                                                                                                                                                                                                },\r
+{124, 561, -5347, 5741, 565, -5387, 5753, 577, -5399, 5769, 557, -5387, 5709, 525, -5375, 5697, 529, -5347, 5709, 517, -5363, 5729, 521, -5375, 5729, 529, -5355, 5721, 545, -5355, 5741, 565, -5371, 5733, 557, -5395, 5733, 537, -5391, 5741, 545, -5379, 5745, 569, -5379, 5725, 569, -5375, 5733, 561, -5375, 5725, 537, -5395, 5721, 537, -5391, 5737, 537, -5371, 5733, 541, -5371, 5729, 561, -5363, 5717, 549, -5335, 5717, 541, -5347, 5737, 537, -5331, 5749, 537, -5327, 5729, 561, -5363, 5737, 581, -5391, 5741, 569, -5395, 5701, 549, -5403, 5701, 541, -5383, 5697, 509, -5363, 5701, 517, -5359, 5725, 517, -5367, 5725, 537, -5407, 5725, 573, -5383, 5741, 569, -5383, 5725, 521, -5363, 5725, 549, -5363, 5753, 541, -5355, 5741, 565, -5367, 5741, 549, -5355, 5725, 565, -5375, 5717, 549, -5367, 5717, 533, -5375, 5697, 533, -5367, 5725, 521, -5375, 5721, 541, -5363, 5717, 545, -5351, 5741, 545, -5351, 5733, 553, -5371, 5721, 545, -5371, 5733, 549, -5355, 5721, 553, -5343, 5721, 553, -5379, 5733, 561, -5435, 5753, 561, -5403, 5737, 541, -5383, 5745, 533, -5343, 5721, 537, -5351, 5721, 529, -5363, 5729, 525, -5355, 5713, 537, -5363, 5733, 553, -5355, 5729, 561, -5359, 5705, 549, -5363, 5721, 573, -5371, 5729, 565, -5359, 5741, 545, -5347, 5733, 533, -5355, 5721, 517, -5379, 5717, 537, -5407, 5721, 533, -5383, 5697, 533, -5375, 5709, 517, -5375, 5721, 533, -5375, 5737, 553, -5371, 5733, 565, -5399, 5737, 573, -5383, 5733, 573, -5387, 5737, 537, -5355, 5737, 541, -5359, 5713, 525, -5375, 5709, 529, -5375, 5709, 549, -5383, 5705, 569, -5391, 5709, 553, -5395, 5713, 577, -5367, 5697, 529, -5367, 5709, 517, -5379, 5721, 521, -5351, 5709, 533, -5347, 5737, 565, -5367, 5749, 565, -5359, 5737, 561, -5339, 5729, 561, -5347, 5709, 553, -5367, 5737, 549, -5391, 5737, 541, -5395, 5701, 541, -5403, 5721, 553, -5391, 5737, 549, -5367, 5729, 553, -5359, 5701, 545, -5355, 5717, 533, -5387, 5697, 545, -5387, 5709, 561, -5379, 5733, 569, -5363, 5733, 569, -5411, 5717, 541, -5387, 5733, 561, -5363, 5721, 573, -5359, 5721, 569, -5351, 5721, 541, -5371, 5705, 529, -5367, 5693, 533, -5403, 5701, 537, -5399, 5721, 557, -5391, 5705, 561, -5371, 5709, 569, -5355, 5737, 561, -5375, 5729, 553, -5367, 5749, 553, -5391, 5725, 577, -5411, 5725,                                                                                                                                                                                                                                },\r
+{125, 569, -5411, 5705, 537, -5415, 5717, 545, -5387, 5701, 561, -5359, 5689, 557, -5371, 5701, 525, -5391, 5697, 541, -5387, 5733, 577, -5363, 5709, 593, -5379, 5721, 577, -5371, 5705, 577, -5387, 5729, 569, -5375, 5737, 565, -5379, 5701, 569, -5363, 5701, 525, -5383, 5705, 557, -5403, 5733, 561, -5391, 5733, 557, -5375, 5713, 561, -5367, 5713, 549, -5367, 5737, 549, -5395, 5737, 573, -5387, 5721, 565, -5359, 5717, 557, -5359, 5725, 545, -5363, 5705, 553, -5379, 5705, 557, -5395, 5693, 541, -5403, 5689, 549, -5379, 5705, 557, -5375, 5717, 577, -5403, 5729, 585, -5419, 5717, 561, -5383, 5705, 561, -5371, 5713, 549, -5383, 5709, 529, -5387, 5741, 549, -5395, 5721, 573, -5391, 5717, 573, -5391, 5717, 585, -5395, 5705, 593, -5399, 5717, 565, -5391, 5725, 557, -5375, 5713, 561, -5363, 5713, 561, -5371, 5721, 549, -5395, 5745, 593, -5391, 5689, 581, -5387, 5693, 565, -5395, 5693, 545, -5395, 5733, 557, -5395, 5721, 561, -5407, 5709, 569, -5395, 5717, 565, -5367, 5729, 565, -5375, 5737, 585, -5375, 5721, 585, -5375, 5729, 569, -5351, 5693, 541, -5391, 5733, 533, -5391, 5701, 561, -5403, 5693, 577, -5391, 5713, 597, -5387, 5721, 585, -5399, 5721, 581, -5427, 5701, 581, -5391, 5717, 569, -5399, 5705, 549, -5379, 5721, 573, -5387, 5713, 557, -5407, 5717, 561, -5411, 5721, 581, -5403, 5701, 577, -5403, 5721, 573, -5407, 5713, 569, -5395, 5701, 565, -5379, 5697, 577, -5375, 5693, 565, -5387, 5693, 557, -5379, 5697, 557, -5379, 5713, 549, -5387, 5713, 577, -5359, 5725, 581, -5387, 5713, 597, -5379, 5705, 605, -5407, 5717, 577, -5415, 5693, 573, -5403, 5705, 565, -5387, 5701, 561, -5383, 5693, 561, -5391, 5677, 553, -5383, 5689, 553, -5367, 5697, 577, -5395, 5709, 581, -5391, 5737, 585, -5387, 5729, 597, -5395, 5737, 581, -5395, 5729, 601, -5395, 5705, 601, -5383, 5717, 573, -5395, 5713, 573, -5387, 5705, 577, -5391, 5697, 577, -5387, 5713, 581, -5399, 5717, 585, -5407, 5713, 593, -5371, 5701, 573, -5359, 5709, 553, -5351, 5717, 561, -5387, 5701, 581, -5383, 5693, 585, -5395, 5673, 573, -5399, 5697, 573, -5395, 5693, 601, -5395, 5693, 597, -5419, 5689, 569, -5407, 5685, 581, -5407, 5721, 573, -5415, 5721, 581, -5411, 5705, 573, -5395, 5709, 573, -5387, 5709, 577, -5403, 5693, 569, -5395, 5705, 565, -5383, 5693, 577, -5407, 5701,                                                                                                                                                                                                },\r
+{123, 573, -5419, 5685, 585, -5395, 5689, 581, -5383, 5701, 593, -5371, 5705, 577, -5391, 5721, 597, -5399, 5709, 585, -5411, 5705, 589, -5407, 5685, 577, -5399, 5709, 573, -5391, 5689, 573, -5375, 5689, 581, -5395, 5697, 553, -5427, 5701, 581, -5415, 5673, 573, -5391, 5701, 593, -5407, 5717, 597, -5383, 5721, 593, -5387, 5713, 601, -5391, 5709, 573, -5379, 5713, 569, -5387, 5701, 561, -5407, 5677, 589, -5427, 5673, 589, -5431, 5701, 597, -5423, 5713, 577, -5383, 5705, 589, -5379, 5709, 597, -5375, 5681, 601, -5411, 5713, 585, -5411, 5705, 601, -5427, 5697, 585, -5419, 5701, 613, -5379, 5705, 581, -5375, 5693, 597, -5367, 5693, 577, -5387, 5693, 593, -5419, 5701, 581, -5423, 5669, 577, -5399, 5673, 561, -5399, 5685, 577, -5395, 5677, 581, -5399, 5697, 581, -5395, 5709, 569, -5403, 5709, 585, -5391, 5697, 597, -5423, 5721, 613, -5411, 5717, 593, -5371, 5709, 593, -5351, 5685, 569, -5407, 5705, 577, -5411, 5685, 573, -5403, 5701, 585, -5415, 5709, 589, -5419, 5713, 581, -5395, 5717, 613, -5363, 5721, 609, -5363, 5717, 585, -5395, 5717, 585, -5411, 5697, 577, -5407, 5693, 581, -5403, 5693, 565, -5407, 5661, 557, -5403, 5689, 573, -5375, 5693, 569, -5391, 5705, 581, -5395, 5705, 593, -5383, 5729, 589, -5399, 5737, 581, -5387, 5689, 577, -5367, 5697, 561, -5359, 5697, 549, -5379, 5721, 569, -5379, 5721, 573, -5379, 5689, 569, -5379, 5717, 565, -5399, 5717, 561, -5379, 5709, 569, -5375, 5689, 577, -5395, 5705, 573, -5399, 5717, 585, -5395, 5725, 569, -5387, 5729, 573, -5379, 5721, 589, -5387, 5705, 577, -5379, 5721, 573, -5383, 5693, 545, -5371, 5721, 569, -5379, 5745, 581, -5379, 5717, 581, -5391, 5733, 565, -5371, 5697, 565, -5363, 5697, 565, -5363, 5725, 541, -5375, 5713, 573, -5367, 5733, 577, -5375, 5713, 585, -5379, 5733, 585, -5383, 5713, 557, -5383, 5709, 537, -5335, 5709, 545, -5335, 5709, 545, -5339, 5721, 557, -5359, 5721, 565, -5379, 5713, 565, -5383, 5725, 561, -5379, 5729, 561, -5363, 5725, 545, -5375, 5737, 545, -5403, 5713, 557, -5399, 5705, 585, -5407, 5741, 597, -5411, 5721, 577, -5411, 5725, 577, -5383, 5697, 565, -5379, 5749, 557, -5363, 5729, 569, -5363, 5729, 573, -5351, 5729, 573, -5363, 5749, 569, -5383, 5713, 565, -5367, 5701, 561, -5367, 5701, 537, -5355, 5685,                                                                                                                                                                                                                                                                },\r
+{125, 533, -5347, 5701, 557, -5363, 5693, 549, -5395, 5709, 541, -5379, 5717, 541, -5375, 5737, 561, -5383, 5729, 581, -5379, 5753, 569, -5363, 5729, 557, -5339, 5737, 541, -5343, 5749, 565, -5375, 5745, 553, -5371, 5737, 537, -5383, 5729, 517, -5363, 5701, 529, -5363, 5701, 549, -5383, 5717, 585, -5379, 5721, 585, -5375, 5721, 561, -5379, 5717, 549, -5379, 5749, 553, -5407, 5757, 545, -5387, 5725, 553, -5355, 5729, 533, -5311, 5729, 545, -5339, 5769, 541, -5363, 5757, 557, -5383, 5721, 545, -5367, 5717, 529, -5363, 5725, 533, -5367, 5737, 557, -5367, 5737, 565, -5363, 5717, 545, -5351, 5717, 545, -5363, 5733, 541, -5379, 5729, 533, -5363, 5757, 553, -5331, 5733, 557, -5351, 5737, 525, -5363, 5737, 537, -5359, 5745, 545, -5351, 5741, 545, -5375, 5749, 565, -5371, 5725, 573, -5367, 5713, 561, -5379, 5729, 553, -5383, 5745, 545, -5375, 5713, 529, -5367, 5725, 525, -5371, 5725, 541, -5379, 5733, 525, -5351, 5741, 565, -5363, 5745, 553, -5347, 5741, 557, -5367, 5721, 549, -5395, 5729, 549, -5371, 5729, 517, -5347, 5745, 529, -5351, 5745, 537, -5351, 5729, 537, -5367, 5721, 533, -5359, 5733, 537, -5339, 5725, 541, -5331, 5725, 549, -5351, 5749, 537, -5343, 5737, 545, -5339, 5757, 553, -5343, 5785, 569, -5355, 5737, 557, -5371, 5721, 517, -5391, 5701, 517, -5399, 5705, 513, -5379, 5721, 545, -5387, 5717, 553, -5371, 5737, 557, -5363, 5753, 545, -5355, 5753, 557, -5343, 5745, 545, -5343, 5741, 521, -5331, 5733, 525, -5331, 5729, 537, -5335, 5721, 517, -5351, 5729, 557, -5343, 5733, 545, -5347, 5701, 553, -5371, 5713, 557, -5375, 5717, 537, -5367, 5721, 549, -5359, 5745, 537, -5375, 5741, 525, -5371, 5725, 537, -5359, 5725, 545, -5371, 5737, 569, -5355, 5725, 565, -5343, 5737, 529, -5371, 5745, 533, -5379, 5733, 549, -5407, 5737, 577, -5387, 5745, 561, -5367, 5737, 565, -5351, 5761, 553, -5351, 5733, 541, -5339, 5733, 525, -5363, 5729, 529, -5375, 5737, 549, -5395, 5713, 573, -5411, 5717, 569, -5379, 5721, 561, -5351, 5757, 557, -5351, 5753, 577, -5379, 5749, 553, -5367, 5745, 549, -5347, 5729, 557, -5347, 5717, 549, -5343, 5741, 557, -5363, 5721, 541, -5391, 5713, 537, -5367, 5713, 541, -5355, 5729, 537, -5343, 5725, 557, -5375, 5753, 553, -5383, 5753, 553, -5351, 5729, 549, -5339, 5721, 533, -5343, 5741, 545, -5363, 5737,                                                                                                                                                                                                },\r
+{124, 565, -5383, 5733, 545, -5395, 5701, 565, -5375, 5733, 569, -5367, 5737, 557, -5363, 5737, 573, -5355, 5745, 573, -5363, 5725, 549, -5395, 5737, 541, -5375, 5737, 553, -5379, 5733, 553, -5367, 5717, 549, -5371, 5741, 561, -5375, 5717, 553, -5379, 5709, 561, -5371, 5721, 573, -5375, 5725, 565, -5371, 5737, 557, -5395, 5721, 577, -5363, 5729, 553, -5359, 5717, 545, -5351, 5713, 553, -5343, 5725, 577, -5367, 5729, 569, -5375, 5717, 557, -5379, 5729, 565, -5391, 5721, 561, -5355, 5725, 565, -5371, 5713, 565, -5379, 5713, 565, -5415, 5733, 573, -5383, 5745, 593, -5399, 5729, 581, -5387, 5721, 569, -5383, 5729, 577, -5363, 5733, 573, -5359, 5721, 553, -5379, 5737, 557, -5379, 5705, 561, -5351, 5689, 553, -5363, 5701, 533, -5367, 5721, 557, -5383, 5721, 585, -5387, 5697, 597, -5391, 5681, 577, -5375, 5705, 561, -5383, 5725, 569, -5391, 5725, 585, -5359, 5701, 577, -5363, 5721, 569, -5407, 5725, 581, -5407, 5721, 569, -5395, 5709, 569, -5383, 5709, 573, -5375, 5709, 585, -5383, 5721, 585, -5415, 5709, 589, -5407, 5705, 573, -5407, 5725, 565, -5375, 5725, 577, -5387, 5717, 601, -5371, 5729, 605, -5363, 5721, 601, -5379, 5725, 589, -5387, 5713, 573, -5395, 5709, 553, -5363, 5725, 573, -5395, 5705, 561, -5379, 5721, 593, -5375, 5721, 617, -5383, 5729, 609, -5399, 5725, 585, -5391, 5709, 577, -5359, 5713, 577, -5387, 5697, 573, -5403, 5681, 557, -5395, 5665, 561, -5371, 5681, 565, -5371, 5709, 565, -5379, 5713, 585, -5375, 5709, 585, -5359, 5737, 601, -5391, 5709, 577, -5411, 5709, 577, -5427, 5693, 569, -5395, 5697, 573, -5383, 5685, 577, -5391, 5705, 581, -5427, 5697, 589, -5427, 5705, 585, -5391, 5701, 561, -5379, 5705, 573, -5387, 5701, 589, -5383, 5713, 593, -5379, 5701, 577, -5399, 5729, 553, -5399, 5713, 553, -5391, 5685, 577, -5383, 5689, 573, -5391, 5705, 589, -5399, 5697, 593, -5395, 5701, 589, -5391, 5693, 601, -5415, 5713, 573, -5407, 5713, 601, -5395, 5673, 585, -5399, 5701, 561, -5391, 5689, 561, -5403, 5701, 577, -5407, 5709, 585, -5391, 5713, 593, -5375, 5697, 585, -5375, 5717, 581, -5375, 5729, 585, -5391, 5717, 597, -5391, 5709, 597, -5411, 5709, 581, -5439, 5685, 621, -5415, 5689, 609, -5399, 5693, 581, -5387, 5693, 573, -5387, 5689, 581, -5419, 5701, 561, -5395, 5713, 597, -5407, 5701,                                                                                                                                                                                                                                },\r
+{124, 613, -5395, 5693, 581, -5375, 5713, 597, -5371, 5709, 577, -5391, 5713, 593, -5391, 5709, 597, -5391, 5685, 577, -5399, 5677, 585, -5423, 5689, 589, -5411, 5681, 597, -5379, 5673, 585, -5375, 5673, 557, -5383, 5697, 581, -5375, 5717, 597, -5387, 5713, 605, -5399, 5705, 621, -5419, 5693, 601, -5411, 5689, 609, -5407, 5685, 593, -5411, 5713, 609, -5407, 5693, 601, -5399, 5713, 573, -5403, 5709, 565, -5399, 5717, 569, -5423, 5721, 569, -5427, 5713, 601, -5395, 5741, 601, -5359, 5689, 573, -5371, 5705, 609, -5379, 5677, 617, -5395, 5705, 613, -5403, 5693, 613, -5439, 5717, 613, -5443, 5705, 581, -5391, 5689, 573, -5371, 5685, 549, -5355, 5685, 541, -5363, 5705, 569, -5399, 5725, 593, -5423, 5721, 601, -5419, 5705, 625, -5387, 5697, 585, -5387, 5689, 581, -5391, 5685, 585, -5391, 5689, 585, -5383, 5709, 565, -5383, 5725, 589, -5407, 5709, 601, -5419, 5693, 593, -5419, 5685, 597, -5407, 5681, 577, -5383, 5697, 569, -5391, 5717, 577, -5399, 5701, 585, -5403, 5697, 605, -5411, 5713, 593, -5423, 5685, 609, -5395, 5685, 577, -5387, 5721, 573, -5395, 5705, 593, -5395, 5705, 597, -5399, 5693, 593, -5427, 5673, 601, -5435, 5689, 609, -5431, 5677, 597, -5403, 5685, 601, -5367, 5705, 617, -5387, 5697, 589, -5387, 5685, 581, -5427, 5705, 581, -5423, 5701, 589, -5395, 5689, 581, -5403, 5681, 585, -5375, 5673, 585, -5379, 5673, 581, -5399, 5693, 609, -5395, 5697, 581, -5383, 5685, 573, -5395, 5705, 597, -5411, 5713, 601, -5419, 5693, 617, -5399, 5693, 613, -5403, 5717, 601, -5407, 5725, 601, -5419, 5673, 601, -5423, 5665, 593, -5439, 5693, 581, -5419, 5681, 597, -5399, 5685, 589, -5383, 5701, 593, -5391, 5697, 605, -5395, 5705, 601, -5399, 5701, 613, -5391, 5689, 613, -5395, 5685, 581, -5411, 5709, 573, -5399, 5677, 565, -5387, 5677, 577, -5403, 5673, 581, -5399, 5681, 577, -5411, 5693, 605, -5415, 5689, 585, -5399, 5685, 593, -5403, 5689, 589, -5419, 5685, 589, -5411, 5673, 593, -5403, 5673, 593, -5383, 5685, 621, -5399, 5697, 597, -5407, 5689, 565, -5395, 5677, 577, -5411, 5685, 581, -5411, 5713, 609, -5395, 5709, 613, -5399, 5697, 601, -5395, 5701, 605, -5407, 5693, 605, -5427, 5717, 597, -5427, 5685, 601, -5403, 5689, 601, -5419, 5689, 601, -5403, 5693, 589, -5391, 5685, 585, -5407, 5693, 593, -5399, 5685,                                                                                                                                                                                                                                },\r
+{125, 613, -5411, 5709, 601, -5391, 5673, 601, -5395, 5709, 597, -5423, 5709, 585, -5423, 5697, 593, -5379, 5681, 577, -5375, 5693, 581, -5407, 5685, 581, -5427, 5673, 593, -5439, 5673, 573, -5415, 5673, 577, -5415, 5669, 573, -5419, 5697, 597, -5411, 5689, 613, -5427, 5673, 609, -5427, 5709, 609, -5411, 5705, 601, -5407, 5697, 593, -5399, 5693, 581, -5415, 5689, 589, -5395, 5689, 581, -5407, 5689, 577, -5415, 5665, 585, -5407, 5685, 597, -5411, 5713, 609, -5419, 5681, 589, -5407, 5685, 589, -5403, 5681, 597, -5407, 5693, 601, -5387, 5673, 593, -5387, 5709, 581, -5411, 5689, 577, -5427, 5693, 573, -5419, 5701, 565, -5407, 5665, 581, -5415, 5673, 589, -5415, 5705, 585, -5395, 5701, 589, -5387, 5709, 593, -5383, 5713, 601, -5391, 5721, 581, -5399, 5705, 581, -5415, 5677, 581, -5415, 5669, 593, -5415, 5681, 601, -5415, 5705, 633, -5407, 5717, 609, -5419, 5693, 597, -5423, 5701, 577, -5431, 5693, 589, -5431, 5697, 585, -5411, 5693, 609, -5399, 5693, 593, -5399, 5689, 609, -5415, 5713, 597, -5427, 5701, 593, -5415, 5717, 589, -5395, 5685, 593, -5383, 5693, 561, -5383, 5669, 573, -5395, 5685, 565, -5403, 5701, 585, -5403, 5689, 605, -5415, 5681, 605, -5403, 5681, 597, -5423, 5697, 601, -5415, 5697, 601, -5427, 5701, 601, -5407, 5689, 589, -5395, 5669, 605, -5399, 5681, 589, -5419, 5701, 593, -5415, 5685, 593, -5419, 5685, 605, -5411, 5709, 609, -5387, 5705, 625, -5383, 5701, 625, -5411, 5701, 593, -5427, 5697, 601, -5399, 5677, 597, -5379, 5705, 593, -5399, 5713, 605, -5427, 5705, 605, -5419, 5697, 613, -5419, 5693, 589, -5395, 5681, 585, -5391, 5681, 589, -5403, 5665, 585, -5387, 5697, 597, -5415, 5681, 589, -5415, 5705, 589, -5411, 5689, 597, -5403, 5681, 573, -5419, 5685, 585, -5419, 5697, 609, -5411, 5693, 605, -5407, 5689, 597, -5399, 5705, 573, -5403, 5701, 601, -5411, 5697, 621, -5431, 5681, 617, -5427, 5701, 589, -5407, 5697, 589, -5399, 5685, 601, -5407, 5705, 617, -5427, 5709, 625, -5427, 5685, 605, -5415, 5689, 573, -5399, 5717, 593, -5391, 5713, 581, -5403, 5717, 593, -5403, 5693, 593, -5383, 5693, 593, -5391, 5697, 577, -5395, 5689, 581, -5419, 5677, 605, -5423, 5665, 593, -5411, 5677, 597, -5395, 5677, 589, -5395, 5709, 593, -5407, 5721, 601, -5411, 5693, 577, -5403, 5681, 557, -5387, 5685, 569, -5395, 5677,                                                                                                                                                                                                },\r
+{124, 569, -5419, 5685, 581, -5399, 5709, 597, -5375, 5717, 625, -5383, 5737, 613, -5399, 5713, 585, -5403, 5721, 577, -5415, 5713, 577, -5427, 5693, 605, -5435, 5681, 613, -5419, 5677, 593, -5403, 5709, 585, -5375, 5709, 577, -5399, 5713, 585, -5387, 5709, 593, -5383, 5701, 589, -5391, 5721, 613, -5391, 5693, 597, -5407, 5685, 573, -5399, 5673, 573, -5375, 5685, 577, -5383, 5673, 577, -5403, 5673, 593, -5415, 5685, 593, -5435, 5685, 593, -5431, 5681, 573, -5415, 5697, 581, -5403, 5693, 585, -5399, 5713, 577, -5411, 5697, 593, -5395, 5721, 573, -5375, 5705, 601, -5395, 5713, 613, -5407, 5717, 605, -5407, 5709, 597, -5407, 5713, 601, -5423, 5673, 581, -5407, 5713, 597, -5419, 5681, 601, -5411, 5701, 585, -5411, 5693, 569, -5419, 5689, 573, -5435, 5685, 581, -5407, 5689, 601, -5379, 5693, 593, -5379, 5729, 625, -5407, 5761, 637, -5431, 5729, 617, -5407, 5733, 605, -5363, 5725, 597, -5363, 5701, 569, -5391, 5681, 565, -5395, 5681, 561, -5407, 5677, 545, -5395, 5669, 561, -5387, 5665, 577, -5387, 5701, 601, -5375, 5721, 597, -5399, 5721, 617, -5407, 5725, 605, -5395, 5705, 597, -5411, 5689, 573, -5399, 5697, 557, -5391, 5685, 577, -5391, 5689, 585, -5407, 5693, 597, -5423, 5689, 593, -5419, 5701, 573, -5419, 5685, 577, -5407, 5701, 613, -5391, 5669, 593, -5427, 5689, 605, -5379, 5729, 609, -5355, 5721, 593, -5407, 5705, 597, -5471, 5705, 593, -5455, 5705, 581, -5399, 5705, 577, -5387, 5701, 581, -5399, 5705, 597, -5439, 5689, 565, -5427, 5681, 561, -5411, 5685, 585, -5399, 5689, 605, -5399, 5689, 605, -5391, 5701, 585, -5375, 5705, 577, -5391, 5705, 585, -5399, 5725, 601, -5371, 5717, 601, -5407, 5713, 585, -5419, 5697, 609, -5435, 5681, 577, -5443, 5677, 561, -5419, 5673, 549, -5403, 5677, 553, -5403, 5701, 569, -5399, 5713, 589, -5399, 5713, 597, -5395, 5717, 601, -5395, 5693, 589, -5387, 5733, 581, -5399, 5709, 605, -5415, 5697, 609, -5379, 5689, 569, -5399, 5689, 569, -5411, 5677, 553, -5415, 5665, 549, -5431, 5649, 553, -5399, 5653, 549, -5403, 5673, 553, -5407, 5705, 557, -5387, 5709, 593, -5399, 5725, 573, -5399, 5717, 565, -5387, 5697, 573, -5395, 5697, 561, -5407, 5697, 561, -5423, 5677, 565, -5407, 5713, 573, -5419, 5685, 569, -5435, 5689, 545, -5415, 5681, 577, -5403, 5673, 569, -5399, 5689,                                                                                                                                                                                                                                },\r
+{124, 565, -5399, 5701, 573, -5415, 5709, 565, -5399, 5693, 569, -5415, 5693, 565, -5403, 5729, 561, -5383, 5725, 553, -5387, 5709, 581, -5399, 5693, 589, -5403, 5685, 553, -5415, 5685, 537, -5431, 5705, 557, -5431, 5685, 545, -5415, 5665, 561, -5391, 5681, 545, -5383, 5701, 553, -5403, 5709, 541, -5371, 5701, 549, -5355, 5709, 557, -5403, 5685, 569, -5391, 5701, 553, -5435, 5697, 581, -5407, 5693, 561, -5399, 5689, 561, -5379, 5689, 541, -5403, 5709, 549, -5427, 5697, 557, -5419, 5709, 557, -5415, 5709, 549, -5423, 5677, 533, -5395, 5701, 537, -5383, 5701, 553, -5387, 5705, 565, -5403, 5709, 565, -5423, 5705, 589, -5423, 5693, 577, -5427, 5681, 537, -5415, 5669, 561, -5399, 5697, 533, -5407, 5693, 545, -5415, 5689, 553, -5419, 5689, 573, -5411, 5685, 581, -5391, 5689, 549, -5407, 5701, 557, -5399, 5705, 541, -5387, 5697, 537, -5379, 5717, 581, -5371, 5713, 581, -5411, 5709, 565, -5439, 5729, 573, -5475, 5705, 581, -5447, 5689, 577, -5423, 5697, 549, -5427, 5665, 553, -5403, 5681, 545, -5407, 5697, 549, -5383, 5697, 557, -5391, 5701, 549, -5391, 5721, 557, -5403, 5705, 585, -5403, 5705, 593, -5391, 5689, 569, -5407, 5693, 565, -5399, 5689, 577, -5427, 5685, 573, -5427, 5657, 553, -5431, 5681, 533, -5435, 5677, 533, -5407, 5701, 533, -5411, 5701, 561, -5399, 5685, 549, -5407, 5697, 561, -5431, 5693, 589, -5427, 5701, 557, -5395, 5705, 589, -5383, 5689, 581, -5419, 5685, 569, -5411, 5689, 557, -5423, 5685, 545, -5427, 5693, 573, -5423, 5697, 581, -5395, 5717, 597, -5379, 5701, 561, -5383, 5697, 553, -5419, 5701, 549, -5407, 5677, 553, -5427, 5689, 549, -5411, 5701, 549, -5403, 5705, 573, -5399, 5697, 581, -5403, 5697, 557, -5395, 5709, 569, -5395, 5689, 565, -5415, 5713, 581, -5427, 5713, 577, -5403, 5697, 569, -5403, 5693, 549, -5415, 5689, 517, -5395, 5697, 549, -5387, 5701, 545, -5379, 5709, 549, -5399, 5705, 565, -5403, 5693, 561, -5411, 5705, 569, -5403, 5685, 561, -5423, 5669, 565, -5419, 5701, 569, -5411, 5709, 577, -5415, 5709, 577, -5407, 5701, 553, -5427, 5689, 553, -5407, 5677, 553, -5399, 5693, 557, -5419, 5685, 553, -5395, 5701, 561, -5399, 5697, 573, -5403, 5697, 569, -5403, 5689, 577, -5411, 5689, 565, -5391, 5689, 585, -5403, 5685, 561, -5435, 5701, 553, -5407, 5713, 569, -5415, 5701,                                                                                                                                                                                                                                },\r
+{125, 561, -5399, 5677, 565, -5391, 5685, 557, -5387, 5717, 541, -5379, 5709, 557, -5383, 5721, 573, -5387, 5697, 553, -5395, 5701, 565, -5415, 5697, 569, -5423, 5681, 565, -5415, 5673, 557, -5451, 5673, 565, -5443, 5701, 577, -5427, 5721, 589, -5451, 5713, 569, -5447, 5713, 577, -5391, 5713, 565, -5383, 5717, 565, -5383, 5725, 529, -5399, 5717, 565, -5387, 5689, 561, -5383, 5677, 577, -5395, 5681, 577, -5411, 5677, 545, -5403, 5673, 553, -5411, 5673, 573, -5411, 5693, 565, -5423, 5689, 565, -5403, 5693, 569, -5395, 5689, 561, -5407, 5681, 581, -5387, 5701, 557, -5399, 5709, 561, -5403, 5709, 549, -5403, 5685, 545, -5407, 5697, 557, -5431, 5657, 549, -5435, 5689, 585, -5411, 5689, 569, -5411, 5681, 569, -5395, 5705, 573, -5399, 5729, 569, -5407, 5713, 577, -5395, 5721, 585, -5383, 5701, 561, -5399, 5701, 541, -5391, 5689, 545, -5391, 5677, 557, -5407, 5693, 573, -5427, 5709, 593, -5423, 5733, 609, -5443, 5709, 597, -5419, 5721, 593, -5399, 5709, 565, -5387, 5697, 541, -5387, 5685, 545, -5407, 5685, 541, -5399, 5685, 553, -5391, 5697, 581, -5395, 5681, 585, -5423, 5697, 577, -5423, 5709, 569, -5391, 5689, 573, -5399, 5733, 565, -5403, 5669, 561, -5403, 5697, 541, -5395, 5721, 561, -5415, 5701, 557, -5415, 5693, 557, -5423, 5669, 561, -5407, 5673, 581, -5415, 5693, 565, -5423, 5721, 565, -5419, 5709, 577, -5387, 5713, 585, -5383, 5733, 573, -5415, 5725, 573, -5419, 5689, 569, -5419, 5693, 565, -5411, 5673, 553, -5383, 5689, 569, -5403, 5693, 569, -5411, 5697, 573, -5407, 5705, 565, -5395, 5701, 565, -5403, 5689, 565, -5411, 5689, 553, -5419, 5701, 549, -5375, 5697, 537, -5367, 5721, 565, -5371, 5709, 581, -5371, 5713, 601, -5383, 5713, 589, -5403, 5709, 573, -5411, 5701, 561, -5439, 5689, 549, -5419, 5697, 573, -5403, 5701, 581, -5395, 5717, 569, -5415, 5717, 577, -5395, 5713, 573, -5399, 5737, 581, -5399, 5717, 553, -5403, 5729, 577, -5399, 5693, 553, -5387, 5685, 569, -5383, 5713, 585, -5387, 5709, 569, -5391, 5713, 569, -5407, 5697, 565, -5399, 5689, 561, -5395, 5685, 549, -5399, 5701, 569, -5367, 5701, 573, -5379, 5685, 549, -5379, 5673, 557, -5395, 5713, 577, -5419, 5737, 593, -5395, 5717, 569, -5387, 5705, 553, -5395, 5705, 541, -5395, 5697, 549, -5403, 5697, 557, -5395, 5717, 573, -5387, 5721, 573, -5355, 5693,                                                                                                                                                                                                },\r
+{124, 585, -5363, 5713, 589, -5407, 5697, 557, -5419, 5709, 569, -5391, 5705, 565, -5363, 5721, 577, -5351, 5725, 561, -5407, 5709, 565, -5407, 5681, 557, -5403, 5685, 549, -5403, 5669, 557, -5379, 5717, 573, -5399, 5713, 589, -5403, 5749, 605, -5395, 5725, 601, -5387, 5737, 581, -5363, 5717, 573, -5371, 5733, 561, -5375, 5717, 581, -5391, 5697, 581, -5379, 5673, 557, -5411, 5701, 553, -5407, 5689, 573, -5415, 5697, 573, -5387, 5705, 577, -5367, 5705, 565, -5375, 5725, 577, -5383, 5733, 589, -5387, 5725, 585, -5379, 5713, 585, -5383, 5725, 577, -5379, 5701, 589, -5399, 5689, 569, -5423, 5677, 577, -5411, 5705, 585, -5407, 5717, 581, -5399, 5701, 605, -5403, 5709, 569, -5411, 5729, 581, -5399, 5713, 569, -5387, 5677, 565, -5379, 5697, 573, -5387, 5701, 577, -5391, 5693, 581, -5407, 5685, 577, -5423, 5697, 605, -5395, 5701, 581, -5371, 5693, 585, -5407, 5717, 577, -5415, 5725, 565, -5375, 5701, 585, -5379, 5705, 585, -5395, 5701, 577, -5387, 5709, 573, -5391, 5709, 593, -5411, 5701, 581, -5399, 5677, 573, -5411, 5689, 573, -5447, 5705, 597, -5443, 5725, 617, -5435, 5697, 601, -5387, 5685, 581, -5367, 5705, 569, -5379, 5709, 581, -5403, 5705, 593, -5427, 5701, 593, -5427, 5693, 605, -5419, 5701, 613, -5407, 5697, 605, -5399, 5689, 597, -5399, 5701, 593, -5383, 5685, 593, -5411, 5689, 593, -5419, 5669, 573, -5399, 5681, 589, -5395, 5693, 581, -5395, 5701, 605, -5391, 5689, 581, -5399, 5701, 605, -5407, 5729, 581, -5419, 5693, 577, -5411, 5705, 597, -5419, 5693, 613, -5439, 5709, 613, -5443, 5677, 601, -5431, 5697, 581, -5407, 5685, 589, -5399, 5673, 589, -5403, 5677, 581, -5411, 5709, 585, -5415, 5713, 597, -5419, 5673, 613, -5395, 5705, 601, -5399, 5697, 605, -5395, 5713, 597, -5415, 5705, 601, -5427, 5701, 601, -5431, 5697, 597, -5411, 5677, 597, -5399, 5693, 605, -5419, 5697, 589, -5419, 5689, 585, -5391, 5705, 597, -5399, 5717, 605, -5399, 5717, 593, -5399, 5721, 609, -5395, 5701, 609, -5403, 5685, 589, -5407, 5693, 593, -5423, 5661, 589, -5415, 5677, 577, -5407, 5689, 597, -5415, 5693, 593, -5427, 5693, 581, -5419, 5689, 597, -5415, 5693, 597, -5411, 5697, 613, -5407, 5669, 593, -5411, 5689, 593, -5403, 5677, 597, -5427, 5677, 597, -5419, 5685, 609, -5419, 5677, 593, -5435, 5681, 605, -5427, 5693,                                                                                                                                                                                                                                },\r
+{125, 593, -5423, 5657, 577, -5399, 5673, 593, -5379, 5705, 597, -5399, 5689, 613, -5427, 5697, 625, -5435, 5693, 617, -5439, 5677, 617, -5427, 5681, 609, -5403, 5673, 593, -5423, 5657, 601, -5411, 5681, 617, -5423, 5689, 597, -5435, 5701, 589, -5431, 5689, 593, -5411, 5665, 597, -5399, 5685, 605, -5399, 5713, 617, -5407, 5677, 593, -5411, 5685, 597, -5407, 5689, 581, -5431, 5677, 573, -5431, 5693, 593, -5439, 5685, 633, -5435, 5705, 629, -5415, 5677, 633, -5399, 5697, 601, -5403, 5701, 605, -5431, 5689, 609, -5455, 5681, 617, -5435, 5673, 593, -5415, 5669, 605, -5415, 5689, 601, -5423, 5689, 593, -5407, 5681, 597, -5411, 5677, 609, -5407, 5669, 605, -5423, 5657, 593, -5431, 5665, 573, -5435, 5685, 613, -5435, 5669, 633, -5439, 5665, 605, -5419, 5681, 585, -5419, 5677, 609, -5423, 5685, 601, -5435, 5705, 597, -5423, 5689, 605, -5431, 5669, 605, -5451, 5669, 593, -5443, 5665, 609, -5419, 5677, 597, -5387, 5693, 609, -5387, 5681, 601, -5415, 5689, 601, -5419, 5701, 605, -5411, 5697, 613, -5415, 5689, 625, -5431, 5685, 601, -5415, 5697, 581, -5403, 5681, 597, -5403, 5685, 613, -5435, 5677, 609, -5447, 5673, 613, -5443, 5681, 609, -5431, 5677, 625, -5427, 5685, 633, -5411, 5697, 589, -5395, 5689, 597, -5379, 5689, 597, -5375, 5697, 593, -5403, 5693, 589, -5435, 5689, 617, -5447, 5681, 621, -5431, 5665, 601, -5415, 5645, 589, -5411, 5661, 613, -5443, 5681, 593, -5435, 5689, 613, -5387, 5717, 613, -5467, 5701, 633, -5463, 5689, 617, -5427, 5673, 609, -5395, 5657, 581, -5391, 5689, 557, -5399, 5693, 601, -5427, 5673, 629, -5455, 5677, 613, -5447, 5673, 633, -5423, 5677, 609, -5419, 5657, 577, -5431, 5697, 553, -5371, 5721, 593, -5387, 5689, 621, -5423, 5685, 637, -5455, 5661, 609, -5459, 5645, 585, -5427, 5669, 585, -5391, 5657, 585, -5407, 5689, 629, -5423, 5669, 637, -5443, 5717, 637, -5439, 5709, 637, -5431, 5669, 609, -5423, 5681, 581, -5439, 5701, 585, -5415, 5677, 617, -5431, 5673, 589, -5431, 5681, 589, -5403, 5681, 601, -5403, 5653, 589, -5411, 5677, 605, -5411, 5665, 617, -5407, 5673, 609, -5423, 5677, 621, -5439, 5685, 625, -5455, 5677, 617, -5443, 5709, 609, -5415, 5689, 637, -5423, 5705, 617, -5427, 5673, 609, -5435, 5677, 605, -5431, 5689, 573, -5419, 5665, 573, -5427, 5693, 605, -5419, 5669, 613, -5391, 5681,                                                                                                                                                                                                },\r
+{124, 617, -5383, 5709, 609, -5395, 5697, 605, -5391, 5701, 585, -5423, 5685, 601, -5411, 5681, 589, -5415, 5669, 589, -5399, 5673, 597, -5419, 5645, 597, -5423, 5665, 605, -5423, 5693, 625, -5459, 5689, 617, -5455, 5713, 617, -5451, 5709, 605, -5415, 5685, 593, -5391, 5681, 605, -5383, 5669, 589, -5407, 5681, 589, -5415, 5681, 597, -5431, 5689, 601, -5431, 5657, 609, -5431, 5693, 609, -5415, 5673, 621, -5383, 5697, 581, -5383, 5713, 605, -5411, 5709, 617, -5415, 5685, 625, -5435, 5689, 621, -5423, 5701, 605, -5411, 5661, 573, -5403, 5669, 581, -5407, 5685, 601, -5419, 5709, 593, -5407, 5689, 601, -5395, 5689, 609, -5415, 5705, 609, -5419, 5701, 585, -5399, 5669, 585, -5403, 5677, 601, -5423, 5673, 593, -5415, 5665, 597, -5415, 5677, 581, -5407, 5685, 601, -5415, 5677, 605, -5411, 5677, 597, -5415, 5697, 593, -5431, 5705, 593, -5427, 5713, 609, -5427, 5705, 601, -5415, 5693, 569, -5403, 5681, 569, -5411, 5681, 593, -5431, 5681, 569, -5419, 5697, 597, -5419, 5685, 605, -5419, 5685, 593, -5399, 5669, 597, -5391, 5689, 589, -5387, 5701, 585, -5387, 5681, 585, -5411, 5705, 589, -5419, 5673, 569, -5427, 5705, 593, -5415, 5705, 589, -5419, 5693, 585, -5399, 5685, 561, -5415, 5681, 573, -5399, 5657, 565, -5403, 5677, 581, -5411, 5681, 581, -5411, 5709, 617, -5395, 5721, 605, -5387, 5709, 577, -5399, 5709, 601, -5391, 5713, 597, -5411, 5701, 585, -5407, 5697, 581, -5435, 5677, 569, -5443, 5673, 569, -5455, 5681, 589, -5439, 5681, 581, -5427, 5705, 613, -5415, 5697, 597, -5415, 5709, 585, -5419, 5725, 585, -5427, 5717, 597, -5395, 5697, 573, -5387, 5693, 553, -5391, 5705, 553, -5399, 5677, 569, -5395, 5677, 565, -5407, 5661, 573, -5415, 5653, 585, -5427, 5677, 577, -5403, 5689, 589, -5403, 5701, 589, -5383, 5733, 605, -5391, 5729, 589, -5403, 5717, 569, -5407, 5705, 573, -5407, 5713, 569, -5407, 5709, 565, -5419, 5689, 565, -5395, 5681, 585, -5375, 5681, 585, -5407, 5697, 609, -5451, 5697, 577, -5443, 5689, 573, -5399, 5673, 561, -5367, 5725, 581, -5363, 5733, 569, -5391, 5705, 589, -5407, 5685, 561, -5431, 5689, 565, -5411, 5705, 577, -5403, 5713, 589, -5419, 5725, 581, -5411, 5697, 585, -5403, 5701, 573, -5387, 5685, 565, -5391, 5705, 569, -5399, 5705, 565, -5407, 5673, 569, -5435, 5689, 557, -5395, 5689,                                                                                                                                                                                                                                },\r
+{124, 569, -5359, 5673, 573, -5371, 5709, 557, -5403, 5705, 581, -5407, 5693, 585, -5407, 5721, 565, -5399, 5729, 561, -5399, 5693, 585, -5399, 5681, 573, -5391, 5693, 561, -5403, 5677, 553, -5427, 5701, 569, -5419, 5701, 589, -5387, 5693, 601, -5415, 5705, 569, -5419, 5709, 565, -5411, 5709, 549, -5407, 5697, 565, -5399, 5693, 565, -5395, 5705, 581, -5415, 5689, 577, -5399, 5709, 569, -5387, 5693, 565, -5387, 5689, 561, -5395, 5701, 569, -5395, 5709, 577, -5403, 5713, 585, -5399, 5693, 593, -5395, 5685, 581, -5407, 5693, 557, -5411, 5681, 545, -5387, 5689, 545, -5383, 5693, 541, -5391, 5705, 577, -5403, 5705, 585, -5407, 5693, 581, -5383, 5689, 577, -5379, 5717, 573, -5403, 5721, 565, -5403, 5721, 581, -5407, 5697, 561, -5419, 5677, 553, -5423, 5677, 557, -5443, 5681, 569, -5423, 5697, 601, -5423, 5709, 585, -5411, 5713, 601, -5415, 5717, 593, -5407, 5705, 581, -5407, 5721, 565, -5403, 5693, 549, -5399, 5705, 565, -5375, 5697, 573, -5375, 5693, 553, -5383, 5689, 565, -5407, 5677, 561, -5439, 5673, 573, -5411, 5689, 585, -5415, 5681, 561, -5403, 5673, 573, -5435, 5701, 573, -5423, 5669, 553, -5415, 5689, 545, -5399, 5701, 573, -5395, 5709, 573, -5423, 5709, 597, -5431, 5713, 585, -5427, 5709, 597, -5399, 5705, 601, -5395, 5685, 589, -5427, 5705, 557, -5435, 5701, 569, -5423, 5669, 569, -5387, 5689, 581, -5383, 5725, 577, -5391, 5705, 581, -5407, 5689, 585, -5415, 5693, 565, -5419, 5697, 593, -5403, 5705, 593, -5411, 5709, 577, -5399, 5709, 597, -5407, 5709, 585, -5399, 5713, 593, -5399, 5705, 569, -5407, 5693, 561, -5403, 5713, 557, -5407, 5669, 569, -5387, 5681, 569, -5403, 5685, 581, -5403, 5689, 565, -5403, 5681, 589, -5399, 5697, 585, -5387, 5697, 577, -5391, 5677, 561, -5399, 5685, 553, -5411, 5701, 585, -5415, 5681, 565, -5415, 5677, 573, -5423, 5689, 585, -5415, 5673, 585, -5399, 5693, 585, -5403, 5725, 593, -5415, 5705, 577, -5415, 5689, 561, -5403, 5685, 581, -5387, 5681, 585, -5387, 5689, 577, -5383, 5669, 565, -5423, 5669, 553, -5399, 5697, 585, -5379, 5717, 597, -5411, 5709, 585, -5427, 5681, 593, -5407, 5701, 617, -5403, 5717, 605, -5415, 5721, 605, -5415, 5709, 585, -5411, 5697, 581, -5415, 5689, 585, -5407, 5701, 597, -5407, 5689, 609, -5451, 5657, 613, -5443, 5649, 605, -5439, 5681,                                                                                                                                                                                                                                },\r
+{124, 585, -5411, 5697, 573, -5411, 5701, 577, -5415, 5681, 585, -5403, 5673, 605, -5403, 5705, 585, -5419, 5693, 565, -5451, 5685, 541, -5463, 5677, 561, -5459, 5669, 561, -5451, 5677, 577, -5443, 5621, 577, -5467, 5649, 569, -5499, 5645, 561, -5407, 5673, 569, -5395, 5709, 561, -5391, 5705, 569, -5407, 5713, 557, -5391, 5701, 573, -5387, 5725, 581, -5391, 5697, 561, -5407, 5669, 565, -5455, 5645, 549, -5427, 5649, 557, -5431, 5665, 569, -5439, 5673, 561, -5451, 5689, 589, -5447, 5693, 565, -5419, 5717, 573, -5411, 5709, 557, -5387, 5697, 553, -5387, 5705, 557, -5403, 5697, 565, -5387, 5713, 585, -5379, 5713, 617, -5387, 5693, 641, -5339, 5713, 645, -5419, 5801, 573, -5507, 5681, 561, -5395, 5649, 561, -5311, 5745, 597, -5363, 5753, 593, -5451, 5653, 565, -5419, 5657, 561, -5375, 5713, 561, -5387, 5745, 549, -5415, 5693, 557, -5375, 5689, 569, -5387, 5717, 585, -5363, 5713, 601, -5355, 5713, 597, -5363, 5725, 581, -5375, 5689, 581, -5351, 5765, 553, -5439, 5701, 557, -5387, 5681, 537, -5379, 5709, 565, -5363, 5693, 573, -5387, 5657, 561, -5411, 5689, 569, -5395, 5705, 569, -5391, 5713, 585, -5395, 5709, 577, -5399, 5701, 573, -5423, 5717, 577, -5439, 5717, 561, -5407, 5713, 561, -5379, 5705, 553, -5379, 5701, 561, -5387, 5705, 577, -5399, 5697, 601, -5403, 5685, 593, -5439, 5717, 593, -5439, 5697, 593, -5415, 5709, 605, -5403, 5725, 585, -5407, 5697, 569, -5387, 5717, 565, -5391, 5705, 553, -5411, 5685, 545, -5403, 5685, 549, -5399, 5685, 557, -5407, 5677, 581, -5415, 5681, 589, -5411, 5689, 597, -5423, 5693, 609, -5403, 5713, 605, -5403, 5709, 593, -5423, 5673, 573, -5419, 5677, 549, -5411, 5673, 553, -5427, 5669, 565, -5411, 5661, 557, -5403, 5649, 569, -5403, 5657, 569, -5411, 5689, 589, -5407, 5725, 593, -5395, 5729, 621, -5415, 5705, 633, -5403, 5705, 609, -5415, 5701, 601, -5435, 5689, 573, -5439, 5697, 585, -5443, 5693, 601, -5423, 5701, 605, -5415, 5697, 613, -5431, 5677, 589, -5435, 5673, 577, -5395, 5693, 585, -5399, 5705, 601, -5423, 5721, 613, -5447, 5701, 625, -5443, 5689, 617, -5419, 5669, 569, -5395, 5665, 577, -5415, 5665, 569, -5423, 5681, 561, -5415, 5677, 577, -5415, 5661, 593, -5423, 5657, 609, -5407, 5669, 597, -5403, 5689, 585, -5423, 5685, 585, -5411, 5697, 601, -5399, 5697,                                                                                                                                                                                                                                },\r
+{124, 609, -5419, 5701, 617, -5451, 5701, 605, -5447, 5665, 585, -5443, 5673, 581, -5439, 5669, 577, -5415, 5681, 577, -5407, 5669, 593, -5431, 5693, 601, -5435, 5689, 597, -5431, 5689, 621, -5403, 5685, 617, -5391, 5717, 609, -5403, 5701, 609, -5415, 5693, 581, -5435, 5673, 593, -5423, 5705, 589, -5399, 5697, 605, -5395, 5673, 601, -5419, 5693, 573, -5435, 5701, 601, -5411, 5705, 585, -5379, 5701, 597, -5383, 5689, 597, -5407, 5697, 577, -5407, 5685, 557, -5403, 5693, 565, -5379, 5681, 573, -5395, 5697, 573, -5403, 5673, 589, -5399, 5661, 601, -5419, 5673, 577, -5419, 5681, 589, -5399, 5681, 601, -5407, 5709, 589, -5399, 5701, 601, -5415, 5713, 601, -5415, 5705, 613, -5431, 5705, 585, -5427, 5697, 577, -5423, 5677, 577, -5415, 5681, 581, -5435, 5673, 573, -5419, 5669, 609, -5407, 5701, 617, -5427, 5681, 601, -5427, 5709, 597, -5427, 5713, 577, -5403, 5697, 573, -5415, 5677, 585, -5415, 5685, 577, -5407, 5669, 565, -5387, 5661, 569, -5411, 5705, 589, -5427, 5677, 601, -5419, 5657, 601, -5411, 5673, 597, -5407, 5689, 589, -5399, 5693, 581, -5399, 5693, 573, -5395, 5701, 589, -5407, 5709, 621, -5407, 5689, 589, -5451, 5677, 569, -5435, 5669, 581, -5427, 5665, 569, -5423, 5697, 593, -5395, 5709, 629, -5375, 5717, 621, -5383, 5701, 629, -5395, 5709, 593, -5411, 5701, 573, -5399, 5697, 589, -5391, 5697, 565, -5419, 5697, 577, -5415, 5689, 593, -5423, 5677, 605, -5431, 5673, 617, -5419, 5685, 629, -5435, 5697, 605, -5439, 5677, 597, -5443, 5697, 597, -5411, 5701, 629, -5419, 5685, 589, -5415, 5677, 601, -5427, 5677, 581, -5431, 5681, 581, -5399, 5689, 585, -5415, 5673, 601, -5443, 5681, 605, -5447, 5657, 609, -5431, 5665, 605, -5415, 5645, 585, -5423, 5665, 581, -5423, 5685, 601, -5443, 5689, 609, -5435, 5661, 593, -5423, 5661, 605, -5407, 5693, 609, -5411, 5681, 613, -5399, 5681, 617, -5419, 5681, 613, -5427, 5681, 601, -5435, 5693, 637, -5435, 5685, 617, -5427, 5677, 593, -5427, 5669, 605, -5423, 5669, 601, -5423, 5677, 605, -5419, 5693, 605, -5415, 5681, 629, -5419, 5693, 645, -5431, 5709, 625, -5467, 5693, 613, -5451, 5669, 577, -5427, 5701, 565, -5419, 5685, 601, -5407, 5665, 629, -5415, 5665, 617, -5423, 5645, 625, -5447, 5661, 613, -5423, 5673, 625, -5411, 5685, 621, -5415, 5685, 625, -5423, 5689,                                                                                                                                                                                                                                },\r
+{124, 645, -5443, 5693, 629, -5443, 5701, 613, -5419, 5677, 601, -5423, 5685, 585, -5411, 5665, 585, -5431, 5649, 589, -5447, 5641, 585, -5443, 5653, 593, -5427, 5693, 609, -5431, 5709, 613, -5435, 5681, 605, -5419, 5685, 625, -5407, 5717, 625, -5419, 5685, 589, -5419, 5665, 589, -5419, 5661, 577, -5411, 5673, 585, -5423, 5665, 577, -5415, 5657, 581, -5403, 5653, 561, -5399, 5673, 557, -5403, 5673, 593, -5387, 5693, 613, -5387, 5697, 613, -5403, 5689, 629, -5399, 5689, 621, -5395, 5705, 629, -5399, 5685, 625, -5411, 5709, 617, -5423, 5689, 613, -5447, 5677, 593, -5459, 5673, 581, -5431, 5689, 581, -5427, 5677, 609, -5419, 5677, 605, -5415, 5681, 613, -5427, 5717, 613, -5455, 5685, 629, -5439, 5681, 629, -5439, 5697, 617, -5447, 5677, 597, -5447, 5649, 577, -5443, 5645, 581, -5451, 5653, 561, -5447, 5641, 577, -5443, 5645, 585, -5439, 5661, 605, -5447, 5669, 585, -5419, 5669, 577, -5411, 5689, 581, -5403, 5701, 609, -5419, 5693, 597, -5427, 5673, 585, -5427, 5641, 613, -5431, 5653, 597, -5427, 5657, 577, -5415, 5649, 561, -5423, 5657, 597, -5419, 5665, 585, -5407, 5677, 585, -5415, 5661, 577, -5419, 5677, 585, -5435, 5697, 613, -5451, 5669, 617, -5443, 5673, 589, -5403, 5689, 601, -5435, 5689, 617, -5463, 5693, 577, -5431, 5673, 593, -5427, 5657, 597, -5423, 5681, 573, -5443, 5681, 573, -5427, 5657, 569, -5419, 5665, 585, -5407, 5677, 593, -5411, 5669, 589, -5411, 5713, 605, -5415, 5705, 653, -5435, 5705, 625, -5447, 5713, 613, -5415, 5689, 605, -5395, 5693, 589, -5395, 5693, 585, -5395, 5709, 605, -5407, 5701, 593, -5427, 5697, 589, -5435, 5665, 581, -5431, 5673, 561, -5403, 5669, 545, -5391, 5673, 589, -5391, 5677, 585, -5419, 5673, 593, -5407, 5685, 593, -5395, 5693, 589, -5387, 5713, 593, -5403, 5693, 569, -5407, 5681, 585, -5415, 5677, 581, -5423, 5677, 589, -5451, 5661, 593, -5435, 5669, 573, -5411, 5681, 577, -5407, 5673, 557, -5391, 5649, 565, -5395, 5697, 577, -5399, 5689, 577, -5403, 5709, 597, -5403, 5713, 577, -5407, 5681, 597, -5407, 5693, 573, -5399, 5665, 569, -5415, 5657, 561, -5399, 5657, 569, -5407, 5649, 577, -5423, 5689, 585, -5431, 5697, 585, -5455, 5661, 581, -5423, 5689, 577, -5403, 5677, 589, -5411, 5677, 581, -5419, 5673, 589, -5423, 5653, 601, -5415, 5657, 613, -5423, 5681,                                                                                                                                                                                                                                },\r
+{125, 613, -5411, 5685, 613, -5411, 5681, 605, -5407, 5677, 597, -5407, 5685, 605, -5403, 5681, 601, -5391, 5701, 613, -5403, 5689, 605, -5431, 5673, 637, -5435, 5665, 617, -5435, 5669, 601, -5435, 5685, 609, -5395, 5689, 613, -5403, 5681, 633, -5435, 5693, 633, -5439, 5681, 645, -5451, 5689, 601, -5443, 5653, 605, -5431, 5661, 613, -5419, 5649, 625, -5423, 5645, 637, -5431, 5657, 617, -5451, 5681, 637, -5463, 5689, 677, -5443, 5673, 657, -5435, 5685, 661, -5419, 5681, 629, -5427, 5669, 613, -5439, 5669, 609, -5447, 5665, 609, -5455, 5661, 609, -5447, 5661, 625, -5443, 5669, 645, -5419, 5661, 653, -5415, 5673, 637, -5431, 5665, 617, -5427, 5657, 629, -5423, 5673, 649, -5415, 5689, 625, -5407, 5677, 617, -5423, 5653, 625, -5411, 5661, 613, -5419, 5657, 617, -5415, 5661, 597, -5431, 5689, 613, -5451, 5685, 669, -5435, 5677, 629, -5431, 5689, 625, -5415, 5705, 653, -5419, 5709, 641, -5407, 5685, 633, -5427, 5669, 625, -5435, 5669, 617, -5439, 5681, 601, -5407, 5665, 621, -5419, 5669, 633, -5411, 5653, 641, -5435, 5673, 637, -5423, 5677, 657, -5419, 5701, 645, -5427, 5689, 633, -5447, 5701, 613, -5443, 5701, 597, -5439, 5681, 617, -5423, 5665, 621, -5427, 5685, 593, -5443, 5661, 613, -5439, 5657, 621, -5439, 5657, 613, -5423, 5673, 617, -5387, 5657, 621, -5387, 5677, 617, -5387, 5685, 625, -5395, 5709, 629, -5407, 5701, 617, -5383, 5709, 625, -5367, 5697, 617, -5403, 5697, 601, -5375, 5689, 601, -5391, 5653, 605, -5395, 5669, 617, -5419, 5661, 589, -5415, 5673, 605, -5411, 5677, 601, -5415, 5689, 617, -5411, 5673, 617, -5415, 5689, 593, -5415, 5709, 601, -5435, 5693, 609, -5423, 5689, 609, -5435, 5669, 629, -5423, 5677, 609, -5387, 5689, 625, -5383, 5701, 633, -5403, 5677, 621, -5443, 5701, 601, -5451, 5689, 613, -5451, 5685, 629, -5451, 5693, 617, -5439, 5693, 641, -5435, 5709, 633, -5419, 5685, 593, -5387, 5669, 605, -5399, 5669, 601, -5419, 5657, 577, -5439, 5673, 585, -5431, 5661, 613, -5415, 5677, 609, -5399, 5669, 605, -5407, 5709, 629, -5435, 5717, 629, -5435, 5705, 645, -5447, 5685, 649, -5423, 5685, 609, -5407, 5697, 601, -5423, 5669, 557, -5415, 5697, 569, -5407, 5693, 577, -5399, 5669, 581, -5399, 5681, 565, -5411, 5657, 573, -5419, 5649, 597, -5407, 5661, 605, -5391, 5685, 581, -5391, 5681, 605, -5387, 5693,                                                                                                                                                                                                },\r
+{124, 617, -5383, 5705, 625, -5383, 5709, 625, -5391, 5717, 597, -5391, 5709, 585, -5403, 5725, 585, -5395, 5705, 589, -5379, 5733, 585, -5391, 5713, 621, -5439, 5693, 637, -5459, 5685, 597, -5435, 5681, 613, -5419, 5685, 573, -5403, 5705, 589, -5403, 5709, 605, -5395, 5717, 601, -5391, 5729, 585, -5407, 5713, 593, -5403, 5697, 585, -5399, 5693, 581, -5371, 5697, 593, -5383, 5705, 577, -5419, 5673, 565, -5427, 5673, 565, -5439, 5657, 569, -5415, 5685, 577, -5383, 5709, 561, -5371, 5697, 589, -5363, 5709, 585, -5379, 5701, 585, -5391, 5701, 569, -5403, 5681, 565, -5391, 5697, 581, -5383, 5717, 565, -5379, 5717, 597, -5407, 5713, 609, -5387, 5693, 597, -5379, 5729, 605, -5395, 5753, 637, -5403, 5729, 613, -5407, 5733, 617, -5387, 5741, 621, -5399, 5729, 597, -5395, 5705, 557, -5387, 5701, 565, -5399, 5681, 537, -5387, 5689, 545, -5383, 5701, 565, -5383, 5701, 589, -5395, 5709, 589, -5399, 5713, 601, -5403, 5713, 557, -5403, 5713, 581, -5431, 5697, 565, -5439, 5677, 569, -5431, 5701, 549, -5427, 5685, 541, -5419, 5665, 533, -5391, 5669, 537, -5379, 5705, 561, -5387, 5729, 561, -5351, 5717, 565, -5359, 5749, 569, -5387, 5761, 557, -5427, 5745, 557, -5407, 5713, 565, -5399, 5741, 561, -5379, 5721, 545, -5363, 5717, 533, -5367, 5689, 537, -5399, 5685, 529, -5403, 5685, 505, -5387, 5697, 517, -5343, 5729, 533, -5323, 5737, 541, -5339, 5737, 521, -5335, 5729, 533, -5339, 5757, 557, -5319, 5733, 553, -5339, 5749, 545, -5359, 5737, 553, -5367, 5733, 577, -5395, 5729, 585, -5403, 5737, 565, -5387, 5761, 537, -5351, 5753, 557, -5347, 5765, 545, -5363, 5749, 521, -5379, 5761, 529, -5387, 5749, 593, -5259, 5729, 493, -5367, 5697, 477, -5367, 5809, 489, -5407, 5737, 557, -5355, 5665, 517, -5383, 5757, 509, -5387, 5741, 537, -5343, 5753, 553, -5327, 5781, 541, -5351, 5761, 533, -5355, 5737, 541, -5367, 5745, 501, -5391, 5733, 473, -5407, 5733, 525, -5331, 5709, 533, -5319, 5745, 521, -5303, 5761, 501, -5307, 5765, 509, -5323, 5761, 533, -5371, 5765, 525, -5383, 5721, 521, -5363, 5717, 509, -5351, 5725, 517, -5359, 5741, 521, -5355, 5733, 529, -5367, 5729, 501, -5363, 5725, 489, -5355, 5705, 489, -5347, 5737, 489, -5367, 5705, 497, -5351, 5757, 517, -5359, 5753, 553, -5359, 5725, 533, -5363, 5733, 525, -5363, 5717,                                                                                                                                                                                                                                },\r
+{124, 553, -5355, 5753, 549, -5355, 5745, 541, -5367, 5745, 561, -5355, 5749, 569, -5335, 5753, 561, -5339, 5773, 577, -5351, 5769, 565, -5371, 5749, 549, -5367, 5753, 541, -5355, 5765, 533, -5339, 5753, 533, -5327, 5769, 545, -5355, 5769, 557, -5403, 5745, 561, -5399, 5713, 569, -5383, 5717, 545, -5391, 5741, 557, -5407, 5737, 573, -5419, 5741, 577, -5407, 5733, 581, -5415, 5729, 565, -5407, 5741, 553, -5391, 5721, 581, -5387, 5725, 581, -5387, 5749, 569, -5347, 5733, 549, -5343, 5713, 529, -5323, 5721, 545, -5351, 5689, 533, -5383, 5745, 517, -5359, 5733, 529, -5391, 5717, 529, -5407, 5693, 537, -5411, 5721, 549, -5379, 5717, 553, -5355, 5741, 565, -5383, 5701, 557, -5383, 5725, 525, -5351, 5717, 513, -5323, 5729, 525, -5323, 5693, 521, -5343, 5701, 521, -5359, 5705, 537, -5371, 5713, 553, -5375, 5721, 585, -5383, 5733, 581, -5403, 5757, 573, -5403, 5741, 581, -5391, 5733, 569, -5367, 5725, 545, -5379, 5729, 529, -5371, 5737, 529, -5387, 5721, 533, -5383, 5733, 513, -5363, 5725, 521, -5359, 5709, 521, -5379, 5721, 537, -5383, 5725, 569, -5403, 5717, 577, -5403, 5717, 561, -5383, 5737, 545, -5379, 5721, 589, -5367, 5717, 577, -5383, 5705, 561, -5399, 5709, 541, -5387, 5717, 557, -5355, 5733, 533, -5355, 5749, 537, -5367, 5741, 557, -5371, 5749, 589, -5379, 5749, 581, -5383, 5749, 577, -5391, 5733, 573, -5427, 5725, 561, -5427, 5717, 553, -5391, 5713, 549, -5395, 5705, 537, -5383, 5705, 545, -5411, 5693, 549, -5379, 5701, 533, -5375, 5725, 541, -5383, 5709, 549, -5375, 5709, 549, -5383, 5709, 549, -5371, 5717, 549, -5371, 5721, 545, -5391, 5705, 565, -5379, 5717, 557, -5375, 5717, 549, -5379, 5709, 545, -5379, 5713, 541, -5403, 5721, 557, -5391, 5721, 557, -5375, 5729, 553, -5387, 5725, 541, -5387, 5713, 553, -5383, 5741, 561, -5383, 5729, 565, -5387, 5725, 561, -5391, 5725, 561, -5363, 5737, 577, -5391, 5725, 561, -5387, 5717, 553, -5411, 5701, 565, -5391, 5713, 549, -5391, 5717, 541, -5387, 5709, 553, -5379, 5697, 545, -5359, 5721, 541, -5359, 5729, 545, -5379, 5737, 581, -5367, 5721, 561, -5351, 5713, 557, -5339, 5725, 553, -5363, 5737, 565, -5371, 5725, 561, -5379, 5721, 569, -5399, 5705, 557, -5431, 5705, 541, -5423, 5713, 541, -5419, 5697, 533, -5399, 5713, 525, -5375, 5717, 549, -5375, 5733,                                                                                                                                                                                                                                },\r
+{125, 573, -5379, 5733, 569, -5363, 5733, 537, -5375, 5745, 549, -5371, 5725, 537, -5375, 5729, 569, -5355, 5733, 557, -5363, 5725, 565, -5371, 5713, 577, -5375, 5689, 549, -5407, 5689, 537, -5395, 5661, 509, -5379, 5689, 529, -5367, 5729, 557, -5391, 5733, 585, -5379, 5709, 533, -5383, 5729, 553, -5383, 5725, 541, -5395, 5709, 565, -5375, 5713, 561, -5379, 5733, 553, -5419, 5721, 561, -5431, 5685, 557, -5419, 5677, 537, -5395, 5677, 541, -5371, 5725, 565, -5375, 5721, 565, -5391, 5705, 565, -5395, 5705, 565, -5391, 5725, 557, -5387, 5737, 557, -5383, 5713, 549, -5387, 5713, 545, -5411, 5705, 577, -5407, 5713, 569, -5379, 5701, 585, -5379, 5737, 577, -5399, 5721, 577, -5427, 5701, 545, -5395, 5701, 541, -5395, 5685, 561, -5391, 5693, 561, -5379, 5689, 541, -5383, 5693, 553, -5383, 5701, 549, -5387, 5713, 565, -5367, 5729, 569, -5391, 5721, 581, -5407, 5725, 565, -5411, 5697, 561, -5399, 5681, 561, -5411, 5697, 549, -5419, 5677, 541, -5407, 5709, 553, -5399, 5689, 557, -5407, 5701, 585, -5411, 5713, 593, -5431, 5717, 589, -5435, 5741, 577, -5375, 5725, 553, -5379, 5721, 553, -5395, 5725, 541, -5407, 5737, 533, -5367, 5717, 529, -5343, 5717, 545, -5339, 5729, 549, -5351, 5721, 569, -5339, 5721, 561, -5355, 5733, 565, -5363, 5713, 561, -5387, 5733, 553, -5383, 5709, 561, -5395, 5713, 525, -5383, 5697, 537, -5351, 5717, 541, -5347, 5717, 537, -5355, 5725, 549, -5375, 5725, 549, -5387, 5741, 537, -5371, 5745, 565, -5367, 5741, 541, -5367, 5745, 593, -5383, 5769, 601, -5395, 5757, 569, -5403, 5705, 565, -5387, 5701, 533, -5379, 5701, 521, -5359, 5721, 525, -5363, 5717, 537, -5371, 5713, 553, -5359, 5709, 549, -5351, 5725, 573, -5367, 5733, 569, -5387, 5725, 557, -5363, 5729, 553, -5367, 5741, 557, -5379, 5701, 561, -5379, 5693, 533, -5391, 5713, 533, -5395, 5717, 541, -5387, 5717, 561, -5383, 5749, 545, -5387, 5725, 557, -5359, 5725, 545, -5359, 5741, 533, -5351, 5749, 581, -5367, 5741, 573, -5375, 5717, 569, -5383, 5737, 557, -5407, 5721, 545, -5427, 5705, 545, -5391, 5725, 549, -5367, 5729, 561, -5347, 5737, 549, -5351, 5729, 549, -5387, 5725, 549, -5383, 5733, 529, -5355, 5733, 533, -5351, 5729, 561, -5359, 5737, 565, -5363, 5725, 589, -5363, 5741, 545, -5371, 5725, 529, -5391, 5733, 557, -5383, 5709, 549, -5395, 5717,                                                                                                                                                                                                },\r
+{124, 517, -5403, 5697, 521, -5387, 5701, 537, -5371, 5701, 529, -5371, 5725, 525, -5387, 5733, 525, -5375, 5725, 541, -5363, 5737, 569, -5375, 5753, 553, -5375, 5737, 549, -5383, 5713, 537, -5387, 5713, 541, -5395, 5717, 553, -5387, 5717, 565, -5379, 5721, 569, -5391, 5701, 541, -5387, 5709, 553, -5399, 5733, 541, -5379, 5753, 541, -5363, 5749, 541, -5363, 5741, 529, -5363, 5725, 549, -5355, 5737, 549, -5371, 5741, 553, -5383, 5737, 573, -5407, 5729, 569, -5359, 5717, 557, -5355, 5749, 545, -5359, 5725, 537, -5387, 5721, 529, -5371, 5729, 529, -5359, 5725, 525, -5363, 5709, 521, -5359, 5709, 545, -5363, 5741, 533, -5351, 5761, 545, -5355, 5749, 577, -5359, 5757, 565, -5359, 5737, 573, -5387, 5757, 553, -5387, 5737, 541, -5375, 5717, 541, -5403, 5725, 537, -5399, 5729, 537, -5383, 5725, 569, -5403, 5725, 573, -5391, 5713, 557, -5375, 5713, 561, -5383, 5733, 557, -5371, 5741, 549, -5375, 5733, 557, -5383, 5769, 549, -5387, 5709, 533, -5391, 5733, 525, -5367, 5709, 517, -5359, 5709, 521, -5395, 5693, 537, -5403, 5677, 541, -5403, 5689, 557, -5383, 5733, 561, -5387, 5729, 569, -5379, 5697, 553, -5363, 5705, 533, -5395, 5729, 553, -5399, 5705, 545, -5387, 5721, 553, -5407, 5693, 557, -5399, 5713, 561, -5407, 5725, 549, -5419, 5737, 565, -5395, 5705, 581, -5367, 5709, 557, -5359, 5733, 533, -5379, 5717, 545, -5391, 5693, 553, -5407, 5709, 561, -5383, 5709, 565, -5411, 5729, 573, -5411, 5709, 565, -5383, 5709, 561, -5387, 5697, 549, -5371, 5721, 533, -5359, 5733, 545, -5347, 5741, 565, -5371, 5737, 557, -5391, 5717, 557, -5391, 5717, 557, -5367, 5717, 557, -5351, 5705, 545, -5367, 5721, 549, -5391, 5733, 549, -5415, 5717, 585, -5411, 5713, 589, -5395, 5713, 557, -5403, 5701, 549, -5395, 5705, 549, -5387, 5709, 545, -5387, 5725, 557, -5407, 5709, 561, -5403, 5729, 549, -5391, 5725, 549, -5391, 5713, 549, -5399, 5717, 561, -5391, 5717, 569, -5391, 5693, 553, -5387, 5693, 553, -5391, 5697, 549, -5395, 5689, 541, -5387, 5709, 541, -5371, 5713, 569, -5387, 5705, 569, -5379, 5709, 557, -5367, 5709, 553, -5363, 5721, 557, -5375, 5725, 573, -5407, 5697, 561, -5435, 5705, 565, -5435, 5701, 549, -5411, 5705, 549, -5395, 5701, 533, -5379, 5725, 565, -5355, 5725, 565, -5375, 5709, 553, -5375, 5721, 569, -5395, 5729,                                                                                                                                                                                                                                },\r
+{125, 561, -5395, 5709, 569, -5383, 5717, 557, -5403, 5717, 549, -5415, 5697, 561, -5403, 5701, 589, -5415, 5725, 597, -5427, 5729, 577, -5415, 5709, 581, -5395, 5701, 545, -5391, 5689, 521, -5399, 5721, 545, -5387, 5717, 561, -5383, 5697, 569, -5395, 5685, 553, -5399, 5701, 565, -5387, 5709, 573, -5395, 5689, 581, -5391, 5685, 557, -5391, 5689, 561, -5395, 5689, 561, -5383, 5685, 553, -5383, 5689, 569, -5387, 5701, 561, -5387, 5721, 561, -5399, 5725, 557, -5387, 5709, 553, -5383, 5721, 557, -5407, 5705, 549, -5407, 5697, 585, -5419, 5701, 585, -5399, 5689, 581, -5415, 5729, 577, -5427, 5709, 549, -5415, 5689, 541, -5399, 5689, 549, -5411, 5693, 581, -5395, 5725, 581, -5379, 5721, 581, -5387, 5729, 573, -5407, 5705, 561, -5411, 5717, 561, -5387, 5709, 585, -5367, 5713, 565, -5379, 5725, 581, -5399, 5709, 577, -5403, 5721, 577, -5383, 5709, 569, -5387, 5701, 569, -5387, 5705, 545, -5403, 5705, 565, -5399, 5717, 549, -5395, 5701, 549, -5387, 5701, 545, -5387, 5713, 553, -5403, 5709, 557, -5391, 5677, 549, -5403, 5697, 577, -5431, 5709, 569, -5431, 5713, 573, -5419, 5693, 561, -5423, 5693, 545, -5431, 5709, 553, -5411, 5701, 545, -5383, 5697, 569, -5395, 5721, 573, -5415, 5717, 565, -5403, 5697, 557, -5403, 5693, 573, -5407, 5697, 569, -5407, 5689, 565, -5391, 5681, 545, -5375, 5701, 561, -5379, 5685, 573, -5403, 5709, 561, -5415, 5721, 565, -5411, 5717, 581, -5391, 5701, 557, -5407, 5681, 557, -5423, 5705, 537, -5415, 5685, 545, -5399, 5693, 565, -5367, 5697, 573, -5359, 5725, 589, -5383, 5741, 585, -5387, 5737, 581, -5403, 5721, 581, -5415, 5697, 541, -5411, 5693, 545, -5427, 5685, 549, -5411, 5693, 553, -5419, 5705, 573, -5403, 5701, 581, -5383, 5705, 569, -5399, 5717, 569, -5411, 5725, 573, -5379, 5729, 565, -5355, 5729, 581, -5379, 5733, 581, -5407, 5713, 573, -5407, 5685, 557, -5403, 5697, 553, -5403, 5681, 557, -5391, 5685, 577, -5391, 5689, 573, -5403, 5689, 573, -5407, 5709, 577, -5399, 5701, 569, -5379, 5705, 573, -5387, 5705, 549, -5371, 5709, 549, -5395, 5701, 553, -5407, 5701, 557, -5435, 5717, 581, -5423, 5669, 581, -5391, 5665, 569, -5403, 5685, 557, -5415, 5725, 581, -5411, 5705, 589, -5403, 5705, 577, -5403, 5721, 573, -5399, 5713, 573, -5411, 5709, 565, -5399, 5693, 573, -5387, 5697, 581, -5399, 5713,                                                                                                                                                                                                },\r
+{123, 573, -5407, 5705, 593, -5423, 5713, 581, -5415, 5717, 593, -5407, 5717, 597, -5395, 5705, 577, -5399, 5689, 561, -5411, 5693, 537, -5419, 5717, 561, -5399, 5701, 561, -5395, 5673, 561, -5399, 5693, 561, -5395, 5713, 601, -5403, 5717, 577, -5399, 5697, 593, -5391, 5697, 589, -5379, 5697, 573, -5423, 5709, 573, -5415, 5693, 573, -5411, 5705, 589, -5415, 5713, 581, -5411, 5669, 589, -5419, 5677, 561, -5431, 5689, 561, -5419, 5677, 597, -5395, 5705, 613, -5399, 5721, 597, -5399, 5721, 589, -5399, 5693, 569, -5423, 5697, 577, -5391, 5693, 581, -5407, 5689, 557, -5399, 5685, 577, -5403, 5665, 569, -5415, 5685, 561, -5411, 5705, 585, -5411, 5693, 601, -5419, 5689, 593, -5419, 5689, 569, -5427, 5701, 557, -5419, 5685, 585, -5399, 5697, 573, -5367, 5709, 589, -5375, 5717, 589, -5391, 5701, 585, -5399, 5689, 577, -5403, 5701, 581, -5423, 5697, 577, -5443, 5685, 581, -5431, 5673, 585, -5403, 5681, 585, -5383, 5685, 581, -5407, 5717, 597, -5419, 5705, 581, -5423, 5701, 585, -5403, 5689, 585, -5403, 5701, 577, -5411, 5701, 581, -5399, 5689, 593, -5407, 5701, 593, -5407, 5681, 589, -5403, 5689, 589, -5415, 5673, 581, -5423, 5665, 561, -5423, 5673, 561, -5419, 5677, 565, -5387, 5673, 581, -5391, 5709, 581, -5411, 5685, 589, -5419, 5697, 601, -5431, 5701, 581, -5427, 5677, 573, -5403, 5681, 573, -5419, 5693, 605, -5419, 5677, 573, -5411, 5673, 569, -5411, 5673, 553, -5407, 5693, 589, -5407, 5685, 597, -5415, 5705, 609, -5419, 5717, 601, -5435, 5677, 581, -5423, 5669, 577, -5411, 5705, 589, -5407, 5689, 561, -5407, 5701, 593, -5411, 5709, 593, -5419, 5701, 585, -5427, 5721, 593, -5419, 5693, 609, -5415, 5693, 593, -5395, 5685, 577, -5407, 5697, 577, -5411, 5693, 593, -5411, 5697, 589, -5403, 5693, 573, -5391, 5673, 585, -5419, 5689, 585, -5439, 5693, 569, -5427, 5697, 581, -5403, 5713, 601, -5407, 5681, 601, -5415, 5705, 593, -5427, 5697, 573, -5423, 5665, 589, -5419, 5685, 605, -5399, 5693, 605, -5399, 5693, 605, -5411, 5701, 597, -5419, 5709, 601, -5407, 5709, 605, -5427, 5705, 593, -5395, 5693, 617, -5427, 5697, 589, -5435, 5673, 565, -5407, 5649, 581, -5407, 5661, 557, -5427, 5657, 561, -5423, 5661, 577, -5431, 5685, 601, -5411, 5693, 597, -5411, 5705, 613, -5431, 5685, 597, -5411, 5709,                                                                                                                                                                                                                                                                },\r
+{125, 597, -5415, 5705, 601, -5411, 5693, 581, -5431, 5701, 573, -5423, 5681, 565, -5407, 5661, 581, -5407, 5677, 581, -5387, 5685, 569, -5395, 5689, 601, -5395, 5693, 577, -5431, 5665, 597, -5427, 5689, 577, -5451, 5669, 589, -5439, 5677, 617, -5427, 5697, 605, -5411, 5705, 597, -5419, 5681, 585, -5447, 5689, 581, -5447, 5697, 577, -5419, 5717, 585, -5407, 5693, 569, -5391, 5685, 569, -5391, 5669, 573, -5399, 5681, 581, -5415, 5677, 577, -5427, 5673, 581, -5415, 5661, 581, -5411, 5681, 577, -5399, 5693, 577, -5399, 5681, 593, -5419, 5689, 577, -5419, 5685, 573, -5415, 5689, 569, -5431, 5681, 581, -5427, 5709, 565, -5387, 5709, 597, -5371, 5709, 597, -5387, 5693, 601, -5419, 5717, 585, -5427, 5701, 581, -5423, 5685, 597, -5427, 5713, 601, -5423, 5709, 585, -5407, 5709, 585, -5391, 5697, 577, -5419, 5689, 589, -5451, 5701, 577, -5435, 5693, 581, -5407, 5689, 585, -5423, 5709, 577, -5403, 5721, 569, -5391, 5709, 585, -5379, 5713, 585, -5403, 5701, 581, -5395, 5689, 577, -5415, 5673, 577, -5431, 5673, 577, -5431, 5677, 541, -5399, 5669, 549, -5395, 5673, 565, -5415, 5681, 553, -5415, 5685, 569, -5407, 5697, 569, -5423, 5689, 573, -5415, 5705, 577, -5403, 5713, 581, -5395, 5713, 581, -5411, 5701, 565, -5407, 5697, 565, -5415, 5685, 557, -5431, 5693, 569, -5423, 5697, 561, -5435, 5661, 561, -5399, 5673, 545, -5383, 5705, 565, -5387, 5705, 557, -5411, 5733, 581, -5411, 5721, 569, -5379, 5721, 577, -5391, 5721, 573, -5407, 5709, 553, -5403, 5717, 549, -5403, 5669, 537, -5395, 5693, 537, -5387, 5705, 537, -5403, 5689, 545, -5407, 5697, 557, -5399, 5709, 581, -5383, 5733, 537, -5367, 5717, 541, -5355, 5725, 549, -5359, 5729, 573, -5379, 5725, 561, -5391, 5725, 553, -5415, 5713, 557, -5427, 5713, 553, -5443, 5681, 553, -5415, 5697, 541, -5411, 5709, 533, -5395, 5725, 537, -5395, 5725, 545, -5415, 5729, 545, -5395, 5725, 545, -5367, 5713, 541, -5375, 5721, 537, -5391, 5709, 541, -5395, 5709, 545, -5367, 5705, 561, -5383, 5709, 553, -5423, 5701, 537, -5407, 5697, 541, -5395, 5681, 525, -5379, 5705, 513, -5379, 5705, 517, -5387, 5697, 521, -5387, 5725, 529, -5407, 5729, 553, -5391, 5725, 553, -5375, 5721, 545, -5375, 5721, 537, -5399, 5721, 533, -5423, 5713, 529, -5419, 5705, 533, -5391, 5713, 529, -5359, 5725, 549, -5383, 5717,                                                                                                                                                                                                },\r
+{125, 561, -5379, 5717, 541, -5379, 5717, 537, -5371, 5709, 529, -5363, 5713, 513, -5387, 5721, 533, -5395, 5713, 549, -5395, 5713, 545, -5379, 5729, 553, -5367, 5733, 541, -5375, 5737, 525, -5367, 5733, 517, -5363, 5725, 525, -5387, 5717, 521, -5395, 5725, 525, -5395, 5701, 525, -5395, 5709, 513, -5391, 5709, 537, -5371, 5733, 541, -5363, 5729, 525, -5371, 5705, 529, -5379, 5713, 525, -5387, 5729, 537, -5391, 5721, 545, -5383, 5733, 533, -5379, 5717, 525, -5383, 5721, 517, -5375, 5717, 509, -5379, 5745, 529, -5395, 5705, 541, -5379, 5709, 525, -5383, 5721, 525, -5371, 5729, 545, -5383, 5689, 561, -5383, 5693, 541, -5391, 5713, 545, -5391, 5713, 545, -5387, 5709, 549, -5391, 5733, 565, -5347, 5725, 545, -5379, 5725, 541, -5395, 5713, 513, -5391, 5729, 513, -5383, 5713, 529, -5379, 5725, 537, -5371, 5709, 533, -5363, 5713, 521, -5375, 5713, 521, -5383, 5725, 541, -5371, 5733, 553, -5367, 5721, 565, -5387, 5733, 549, -5395, 5729, 553, -5411, 5713, 545, -5399, 5713, 549, -5407, 5709, 545, -5431, 5709, 537, -5427, 5701, 541, -5411, 5717, 549, -5383, 5709, 565, -5379, 5733, 545, -5367, 5717, 565, -5383, 5725, 573, -5399, 5709, 537, -5375, 5701, 537, -5367, 5705, 549, -5363, 5701, 533, -5383, 5693, 545, -5395, 5677, 529, -5399, 5689, 521, -5395, 5677, 541, -5415, 5693, 545, -5403, 5693, 541, -5383, 5685, 545, -5399, 5685, 549, -5395, 5689, 549, -5399, 5729, 569, -5387, 5701, 581, -5387, 5697, 581, -5403, 5705, 561, -5415, 5725, 553, -5407, 5697, 553, -5415, 5709, 545, -5403, 5713, 573, -5391, 5717, 585, -5383, 5729, 589, -5395, 5701, 581, -5399, 5717, 593, -5423, 5693, 573, -5427, 5685, 549, -5415, 5685, 553, -5423, 5689, 553, -5419, 5693, 585, -5415, 5689, 557, -5403, 5697, 577, -5395, 5721, 581, -5391, 5697, 589, -5411, 5697, 585, -5431, 5689, 569, -5423, 5681, 573, -5411, 5689, 569, -5411, 5677, 573, -5403, 5685, 573, -5415, 5685, 573, -5411, 5701, 581, -5407, 5713, 581, -5427, 5693, 577, -5431, 5685, 581, -5435, 5697, 581, -5403, 5713, 597, -5379, 5705, 585, -5395, 5701, 577, -5411, 5721, 577, -5427, 5689, 573, -5411, 5697, 581, -5419, 5701, 593, -5407, 5689, 613, -5427, 5689, 577, -5419, 5685, 593, -5399, 5689, 589, -5407, 5705, 589, -5423, 5705, 577, -5427, 5677, 565, -5427, 5669, 553, -5415, 5681, 569, -5403, 5689,                                                                                                                                                                                                },\r
+{124, 569, -5387, 5697, 569, -5399, 5681, 597, -5415, 5697, 621, -5419, 5697, 617, -5403, 5673, 593, -5435, 5685, 589, -5451, 5677, 585, -5395, 5681, 609, -5395, 5701, 593, -5403, 5689, 577, -5415, 5693, 569, -5435, 5685, 569, -5431, 5677, 561, -5419, 5661, 565, -5423, 5677, 573, -5415, 5685, 601, -5439, 5705, 589, -5427, 5685, 589, -5403, 5709, 593, -5419, 5717, 601, -5423, 5677, 593, -5435, 5693, 601, -5427, 5681, 597, -5419, 5681, 581, -5411, 5689, 565, -5399, 5705, 593, -5403, 5689, 597, -5403, 5665, 589, -5423, 5677, 577, -5407, 5673, 577, -5387, 5693, 593, -5403, 5689, 601, -5399, 5681, 581, -5399, 5677, 585, -5419, 5681, 577, -5427, 5681, 577, -5411, 5669, 585, -5427, 5673, 577, -5423, 5681, 573, -5419, 5681, 585, -5427, 5689, 609, -5439, 5697, 589, -5439, 5685, 569, -5415, 5673, 569, -5395, 5685, 565, -5399, 5693, 573, -5431, 5681, 589, -5419, 5685, 609, -5415, 5689, 601, -5443, 5693, 601, -5435, 5681, 593, -5431, 5689, 597, -5423, 5693, 589, -5415, 5673, 581, -5403, 5681, 585, -5403, 5685, 597, -5399, 5713, 593, -5419, 5701, 605, -5431, 5701, 593, -5419, 5709, 605, -5403, 5677, 581, -5411, 5665, 585, -5407, 5661, 565, -5419, 5665, 589, -5443, 5665, 609, -5427, 5657, 601, -5423, 5665, 593, -5411, 5685, 609, -5419, 5681, 605, -5407, 5693, 601, -5407, 5669, 597, -5411, 5681, 597, -5439, 5689, 609, -5439, 5677, 601, -5439, 5669, 593, -5427, 5673, 609, -5419, 5669, 597, -5439, 5669, 621, -5451, 5697, 609, -5447, 5685, 589, -5403, 5681, 577, -5403, 5681, 581, -5407, 5693, 613, -5423, 5681, 613, -5435, 5673, 601, -5435, 5665, 585, -5439, 5645, 601, -5427, 5681, 613, -5431, 5673, 625, -5447, 5669, 613, -5427, 5661, 593, -5415, 5653, 601, -5423, 5689, 605, -5435, 5693, 581, -5443, 5665, 601, -5439, 5641, 613, -5435, 5649, 593, -5431, 5665, 597, -5411, 5685, 625, -5411, 5677, 629, -5415, 5705, 613, -5427, 5685, 597, -5459, 5661, 589, -5471, 5657, 617, -5447, 5677, 617, -5423, 5673, 613, -5427, 5677, 597, -5435, 5657, 613, -5451, 5645, 621, -5451, 5645, 609, -5435, 5649, 593, -5431, 5669, 621, -5443, 5689, 625, -5431, 5677, 633, -5419, 5673, 617, -5419, 5689, 613, -5431, 5693, 597, -5419, 5677, 617, -5435, 5645, 581, -5435, 5641, 561, -5423, 5641, 593, -5427, 5661, 609, -5443, 5669, 633, -5455, 5661,                                                                                                                                                                                                                                },\r
+{125, 625, -5439, 5677, 613, -5431, 5673, 585, -5427, 5681, 597, -5427, 5677, 585, -5419, 5673, 589, -5423, 5669, 589, -5427, 5669, 613, -5439, 5669, 609, -5439, 5673, 613, -5435, 5661, 589, -5431, 5665, 597, -5415, 5673, 585, -5415, 5669, 621, -5411, 5693, 625, -5411, 5689, 625, -5435, 5673, 645, -5467, 5685, 637, -5455, 5681, 605, -5447, 5669, 605, -5419, 5649, 621, -5431, 5669, 605, -5435, 5685, 597, -5427, 5661, 617, -5447, 5665, 621, -5435, 5677, 613, -5419, 5669, 609, -5411, 5677, 601, -5423, 5689, 597, -5423, 5673, 605, -5415, 5669, 621, -5423, 5669, 589, -5431, 5665, 585, -5435, 5653, 589, -5451, 5653, 569, -5439, 5661, 585, -5443, 5665, 605, -5439, 5681, 601, -5423, 5681, 609, -5431, 5673, 601, -5423, 5693, 609, -5439, 5685, 597, -5443, 5677, 589, -5435, 5657, 597, -5423, 5661, 597, -5415, 5665, 589, -5431, 5673, 581, -5427, 5677, 601, -5419, 5661, 597, -5427, 5669, 629, -5419, 5677, 597, -5431, 5689, 601, -5403, 5681, 589, -5403, 5669, 597, -5427, 5685, 581, -5439, 5673, 605, -5423, 5661, 613, -5419, 5669, 597, -5411, 5665, 601, -5427, 5669, 585, -5423, 5681, 597, -5419, 5709, 625, -5447, 5673, 605, -5427, 5653, 585, -5431, 5649, 573, -5419, 5681, 573, -5415, 5665, 581, -5375, 5681, 613, -5391, 5693, 613, -5463, 5685, 605, -5451, 5685, 581, -5439, 5677, 585, -5439, 5685, 589, -5455, 5685, 597, -5443, 5677, 605, -5419, 5665, 609, -5419, 5665, 601, -5431, 5677, 593, -5455, 5689, 593, -5443, 5661, 581, -5443, 5677, 601, -5411, 5673, 593, -5407, 5673, 605, -5419, 5685, 625, -5431, 5693, 613, -5443, 5685, 605, -5435, 5657, 593, -5431, 5657, 585, -5431, 5661, 585, -5439, 5645, 585, -5443, 5649, 581, -5435, 5657, 581, -5419, 5677, 593, -5407, 5689, 601, -5439, 5693, 629, -5443, 5673, 617, -5435, 5681, 621, -5439, 5673, 601, -5451, 5653, 601, -5427, 5669, 585, -5455, 5661, 609, -5435, 5649, 621, -5439, 5669, 601, -5455, 5665, 585, -5447, 5665, 605, -5423, 5673, 601, -5423, 5673, 593, -5423, 5669, 597, -5419, 5661, 629, -5451, 5661, 625, -5451, 5665, 609, -5435, 5669, 617, -5431, 5697, 613, -5427, 5669, 601, -5431, 5685, 593, -5439, 5673, 605, -5423, 5673, 609, -5415, 5681, 621, -5419, 5673, 585, -5423, 5661, 585, -5431, 5669, 589, -5431, 5657, 601, -5423, 5641, 589, -5423, 5665, 593, -5435, 5673, 593, -5427, 5685,                                                                                                                                                                                                },\r
+{125, 605, -5431, 5677, 617, -5427, 5669, 601, -5431, 5669, 597, -5443, 5669, 601, -5455, 5665, 601, -5459, 5649, 593, -5447, 5641, 589, -5443, 5669, 593, -5435, 5677, 613, -5443, 5681, 597, -5431, 5677, 613, -5419, 5677, 609, -5415, 5681, 609, -5419, 5677, 609, -5435, 5681, 605, -5435, 5657, 597, -5435, 5645, 605, -5431, 5673, 593, -5439, 5653, 601, -5427, 5649, 585, -5431, 5669, 593, -5423, 5661, 593, -5431, 5657, 609, -5435, 5661, 601, -5439, 5681, 601, -5431, 5673, 625, -5423, 5665, 609, -5423, 5661, 601, -5439, 5669, 605, -5435, 5661, 581, -5431, 5657, 581, -5447, 5649, 593, -5435, 5653, 601, -5415, 5685, 617, -5411, 5697, 613, -5419, 5697, 617, -5435, 5701, 637, -5431, 5689, 601, -5431, 5681, 609, -5459, 5681, 593, -5471, 5689, 605, -5443, 5665, 609, -5439, 5645, 605, -5419, 5665, 601, -5439, 5657, 585, -5443, 5661, 589, -5435, 5661, 601, -5431, 5689, 605, -5415, 5693, 625, -5431, 5709, 617, -5423, 5705, 601, -5423, 5677, 593, -5423, 5653, 585, -5411, 5665, 593, -5423, 5665, 581, -5451, 5641, 581, -5451, 5645, 565, -5435, 5657, 561, -5427, 5653, 569, -5403, 5661, 589, -5419, 5669, 609, -5419, 5681, 605, -5427, 5697, 613, -5427, 5713, 613, -5431, 5677, 609, -5443, 5681, 581, -5455, 5645, 573, -5447, 5657, 557, -5455, 5649, 577, -5439, 5669, 605, -5423, 5677, 609, -5411, 5681, 621, -5415, 5717, 617, -5423, 5713, 605, -5435, 5697, 597, -5427, 5665, 593, -5411, 5669, 585, -5407, 5693, 585, -5419, 5689, 589, -5427, 5677, 593, -5439, 5685, 597, -5443, 5689, 601, -5423, 5665, 589, -5391, 5681, 597, -5399, 5669, 577, -5423, 5689, 581, -5427, 5677, 605, -5415, 5681, 593, -5415, 5665, 589, -5395, 5669, 561, -5419, 5673, 573, -5443, 5649, 577, -5423, 5665, 605, -5447, 5653, 597, -5423, 5685, 573, -5423, 5693, 577, -5427, 5673, 589, -5419, 5689, 605, -5411, 5689, 597, -5415, 5677, 581, -5423, 5661, 573, -5431, 5677, 565, -5423, 5685, 589, -5419, 5673, 593, -5415, 5677, 577, -5403, 5677, 585, -5411, 5685, 585, -5387, 5685, 589, -5403, 5697, 601, -5427, 5705, 601, -5419, 5697, 601, -5411, 5717, 585, -5415, 5713, 581, -5419, 5681, 577, -5407, 5677, 585, -5427, 5689, 581, -5431, 5665, 605, -5431, 5669, 609, -5427, 5673, 589, -5407, 5677, 577, -5411, 5673, 565, -5395, 5693, 597, -5395, 5697, 601, -5395, 5693, 589, -5403, 5713,                                                                                                                                                                                                },\r
+{125, 545, -5395, 5689, 561, -5391, 5685, 577, -5395, 5697, 565, -5427, 5681, 565, -5443, 5681, 573, -5439, 5665, 565, -5431, 5665, 569, -5431, 5681, 585, -5447, 5693, 593, -5427, 5713, 581, -5423, 5693, 589, -5411, 5693, 573, -5403, 5705, 565, -5399, 5693, 561, -5411, 5685, 561, -5423, 5677, 545, -5399, 5681, 577, -5395, 5681, 593, -5407, 5665, 569, -5435, 5677, 577, -5439, 5673, 561, -5423, 5681, 573, -5391, 5685, 561, -5383, 5717, 573, -5423, 5697, 541, -5431, 5685, 553, -5431, 5673, 553, -5407, 5689, 549, -5387, 5705, 561, -5383, 5697, 577, -5411, 5717, 573, -5427, 5705, 573, -5423, 5689, 585, -5431, 5681, 553, -5447, 5677, 553, -5419, 5685, 545, -5391, 5681, 561, -5375, 5693, 561, -5395, 5717, 557, -5407, 5689, 549, -5415, 5693, 557, -5431, 5713, 573, -5423, 5709, 561, -5399, 5725, 573, -5391, 5725, 565, -5387, 5701, 565, -5395, 5721, 561, -5391, 5709, 557, -5399, 5693, 553, -5427, 5693, 549, -5395, 5681, 553, -5387, 5689, 533, -5403, 5705, 525, -5383, 5697, 561, -5379, 5693, 577, -5379, 5721, 561, -5391, 5725, 549, -5407, 5733, 573, -5411, 5721, 553, -5411, 5713, 553, -5391, 5677, 549, -5407, 5681, 537, -5423, 5697, 537, -5387, 5701, 553, -5399, 5713, 577, -5415, 5709, 577, -5415, 5713, 565, -5419, 5713, 577, -5391, 5709, 557, -5379, 5717, 545, -5379, 5709, 533, -5383, 5709, 557, -5411, 5701, 549, -5411, 5705, 561, -5415, 5693, 573, -5403, 5665, 565, -5423, 5693, 537, -5395, 5701, 565, -5395, 5705, 589, -5427, 5713, 581, -5407, 5705, 557, -5399, 5705, 541, -5383, 5685, 553, -5395, 5685, 565, -5383, 5673, 565, -5379, 5677, 529, -5403, 5701, 537, -5395, 5713, 557, -5391, 5681, 573, -5391, 5693, 569, -5399, 5713, 569, -5411, 5705, 585, -5451, 5693, 565, -5455, 5697, 561, -5431, 5685, 573, -5407, 5693, 561, -5419, 5705, 557, -5439, 5709, 577, -5411, 5689, 577, -5395, 5705, 541, -5387, 5725, 553, -5387, 5713, 565, -5407, 5701, 577, -5387, 5685, 569, -5387, 5685, 581, -5403, 5689, 561, -5415, 5701, 565, -5423, 5661, 561, -5399, 5665, 537, -5403, 5693, 561, -5407, 5697, 569, -5427, 5697, 577, -5419, 5693, 565, -5411, 5697, 569, -5403, 5701, 549, -5423, 5701, 553, -5403, 5701, 577, -5395, 5685, 573, -5407, 5717, 565, -5419, 5685, 573, -5411, 5701, 577, -5431, 5677, 549, -5419, 5689, 585, -5411, 5709, 573, -5419, 5721,                                                                                                                                                                                                },\r
+{125, 593, -5379, 5693, 589, -5387, 5689, 557, -5411, 5697, 533, -5415, 5697, 549, -5411, 5677, 549, -5403, 5677, 561, -5395, 5701, 581, -5403, 5725, 609, -5395, 5713, 585, -5391, 5721, 573, -5391, 5721, 581, -5387, 5713, 557, -5411, 5697, 557, -5419, 5677, 553, -5403, 5689, 557, -5383, 5657, 565, -5403, 5685, 561, -5399, 5689, 549, -5391, 5689, 573, -5391, 5701, 553, -5387, 5713, 569, -5407, 5709, 581, -5419, 5713, 541, -5407, 5685, 537, -5395, 5689, 557, -5403, 5697, 549, -5423, 5693, 573, -5399, 5693, 565, -5411, 5689, 573, -5411, 5705, 569, -5403, 5689, 553, -5395, 5673, 573, -5407, 5713, 565, -5407, 5685, 565, -5387, 5705, 561, -5387, 5701, 561, -5387, 5693, 573, -5395, 5701, 565, -5403, 5701, 569, -5435, 5701, 569, -5431, 5689, 569, -5423, 5685, 545, -5427, 5689, 549, -5395, 5693, 573, -5399, 5705, 561, -5407, 5693, 569, -5399, 5697, 577, -5407, 5701, 569, -5411, 5689, 569, -5399, 5689, 581, -5383, 5705, 573, -5383, 5717, 553, -5383, 5697, 569, -5387, 5685, 589, -5403, 5701, 593, -5403, 5701, 565, -5419, 5693, 569, -5427, 5685, 573, -5431, 5697, 593, -5415, 5709, 593, -5419, 5721, 593, -5431, 5721, 593, -5439, 5705, 589, -5435, 5693, 589, -5423, 5669, 577, -5423, 5705, 565, -5423, 5697, 597, -5391, 5689, 597, -5411, 5665, 589, -5419, 5685, 589, -5419, 5673, 577, -5427, 5661, 589, -5423, 5665, 589, -5387, 5677, 585, -5411, 5677, 597, -5439, 5677, 609, -5427, 5681, 589, -5431, 5681, 593, -5419, 5669, 593, -5427, 5677, 581, -5435, 5685, 589, -5439, 5681, 597, -5451, 5685, 613, -5439, 5665, 609, -5403, 5677, 613, -5423, 5693, 613, -5447, 5689, 621, -5455, 5673, 621, -5439, 5669, 601, -5415, 5693, 601, -5411, 5677, 609, -5415, 5665, 617, -5431, 5661, 597, -5423, 5653, 581, -5419, 5665, 593, -5435, 5685, 617, -5447, 5685, 617, -5451, 5693, 601, -5431, 5701, 589, -5427, 5685, 593, -5411, 5693, 585, -5395, 5681, 613, -5411, 5681, 605, -5431, 5673, 601, -5439, 5669, 613, -5427, 5673, 577, -5423, 5657, 593, -5423, 5653, 597, -5435, 5645, 597, -5431, 5669, 621, -5447, 5681, 613, -5443, 5669, 597, -5443, 5685, 597, -5439, 5689, 597, -5435, 5649, 601, -5435, 5665, 605, -5435, 5669, 597, -5407, 5633, 577, -5419, 5677, 601, -5451, 5697, 609, -5471, 5685, 633, -5443, 5669, 633, -5407, 5681, 633, -5411, 5689, 617, -5431, 5689,                                                                                                                                                                                                },\r
+{124, 597, -5407, 5697, 601, -5415, 5677, 597, -5423, 5681, 605, -5447, 5677, 609, -5447, 5677, 609, -5435, 5657, 621, -5427, 5653, 593, -5431, 5665, 585, -5419, 5649, 601, -5439, 5669, 617, -5431, 5677, 633, -5427, 5689, 633, -5423, 5677, 625, -5439, 5677, 621, -5439, 5665, 589, -5423, 5673, 609, -5431, 5669, 605, -5427, 5665, 609, -5427, 5673, 609, -5447, 5665, 621, -5427, 5657, 605, -5415, 5653, 597, -5431, 5669, 577, -5435, 5669, 593, -5463, 5657, 613, -5451, 5673, 645, -5439, 5669, 637, -5411, 5697, 613, -5435, 5661, 597, -5447, 5669, 589, -5439, 5657, 589, -5439, 5653, 601, -5427, 5649, 589, -5427, 5653, 597, -5423, 5657, 609, -5431, 5653, 617, -5423, 5689, 633, -5415, 5673, 633, -5431, 5677, 625, -5431, 5657, 605, -5447, 5665, 605, -5447, 5665, 605, -5443, 5641, 585, -5411, 5653, 601, -5427, 5665, 609, -5435, 5669, 609, -5443, 5661, 621, -5463, 5661, 609, -5471, 5673, 625, -5451, 5653, 621, -5443, 5653, 617, -5439, 5673, 637, -5423, 5677, 621, -5415, 5661, 621, -5423, 5657, 609, -5427, 5657, 581, -5431, 5649, 597, -5443, 5673, 617, -5431, 5661, 625, -5427, 5677, 637, -5419, 5657, 609, -5447, 5653, 605, -5447, 5669, 621, -5443, 5665, 637, -5439, 5685, 629, -5431, 5681, 633, -5411, 5693, 621, -5431, 5645, 613, -5439, 5661, 581, -5439, 5653, 585, -5423, 5657, 601, -5411, 5685, 621, -5439, 5661, 641, -5419, 5685, 637, -5435, 5665, 625, -5431, 5641, 601, -5431, 5653, 581, -5435, 5645, 617, -5435, 5653, 617, -5455, 5661, 609, -5467, 5649, 609, -5439, 5657, 617, -5435, 5653, 581, -5419, 5661, 605, -5415, 5677, 617, -5435, 5669, 629, -5451, 5653, 617, -5451, 5685, 641, -5439, 5689, 625, -5427, 5673, 617, -5435, 5665, 605, -5431, 5645, 589, -5435, 5673, 577, -5439, 5649, 605, -5463, 5657, 617, -5447, 5677, 641, -5435, 5665, 613, -5431, 5649, 597, -5431, 5677, 597, -5423, 5677, 621, -5435, 5677, 641, -5443, 5665, 625, -5459, 5665, 617, -5447, 5661, 617, -5459, 5637, 609, -5447, 5641, 605, -5423, 5657, 617, -5431, 5657, 621, -5435, 5665, 617, -5435, 5669, 605, -5459, 5665, 597, -5431, 5665, 597, -5455, 5645, 609, -5431, 5669, 613, -5435, 5685, 625, -5435, 5661, 625, -5439, 5669, 621, -5431, 5665, 609, -5431, 5661, 593, -5443, 5665, 581, -5459, 5653, 601, -5443, 5645, 625, -5443, 5657, 641, -5451, 5673,                                                                                                                                                                                                                                },\r
+{125, 629, -5463, 5673, 617, -5447, 5649, 601, -5443, 5637, 593, -5447, 5669, 601, -5435, 5661, 621, -5431, 5653, 637, -5435, 5669, 621, -5443, 5669, 605, -5419, 5665, 617, -5427, 5661, 609, -5423, 5673, 637, -5427, 5677, 617, -5443, 5649, 601, -5463, 5645, 597, -5463, 5677, 597, -5435, 5645, 617, -5403, 5617, 601, -5443, 5649, 605, -5467, 5669, 617, -5455, 5689, 637, -5439, 5669, 625, -5475, 5653, 637, -5463, 5665, 621, -5451, 5657, 625, -5451, 5657, 629, -5435, 5657, 621, -5427, 5649, 593, -5427, 5665, 613, -5423, 5669, 629, -5439, 5677, 613, -5431, 5677, 609, -5423, 5677, 605, -5423, 5681, 637, -5439, 5665, 629, -5447, 5657, 601, -5463, 5653, 597, -5475, 5637, 605, -5431, 5653, 613, -5411, 5657, 613, -5411, 5693, 609, -5415, 5681, 621, -5439, 5657, 609, -5443, 5673, 589, -5415, 5677, 597, -5419, 5669, 609, -5439, 5669, 613, -5431, 5661, 617, -5415, 5665, 605, -5407, 5685, 597, -5407, 5653, 601, -5427, 5685, 617, -5451, 5677, 589, -5475, 5685, 609, -5439, 5661, 597, -5419, 5669, 617, -5407, 5677, 581, -5415, 5649, 569, -5435, 5653, 593, -5447, 5665, 605, -5463, 5653, 609, -5435, 5665, 617, -5439, 5685, 625, -5435, 5661, 601, -5435, 5689, 577, -5407, 5677, 573, -5403, 5677, 597, -5403, 5693, 601, -5447, 5677, 589, -5459, 5661, 597, -5459, 5649, 585, -5423, 5649, 585, -5411, 5665, 581, -5419, 5669, 581, -5423, 5665, 605, -5435, 5673, 601, -5443, 5681, 609, -5443, 5697, 617, -5423, 5689, 589, -5407, 5661, 589, -5423, 5669, 593, -5439, 5681, 593, -5427, 5689, 601, -5419, 5669, 609, -5427, 5677, 613, -5431, 5677, 585, -5415, 5657, 585, -5411, 5673, 577, -5407, 5685, 613, -5407, 5713, 597, -5415, 5677, 617, -5423, 5673, 605, -5431, 5669, 569, -5431, 5665, 553, -5463, 5665, 577, -5463, 5653, 593, -5435, 5665, 617, -5427, 5669, 601, -5431, 5669, 605, -5407, 5673, 621, -5407, 5705, 605, -5419, 5697, 585, -5443, 5693, 605, -5451, 5685, 605, -5431, 5677, 617, -5411, 5697, 605, -5431, 5665, 601, -5427, 5657, 601, -5419, 5657, 601, -5387, 5625, 613, -5395, 5653, 605, -5403, 5653, 589, -5419, 5665, 577, -5443, 5673, 589, -5471, 5661, 565, -5459, 5681, 613, -5459, 5693, 641, -5455, 5685, 661, -5443, 5645, 637, -5439, 5645, 609, -5443, 5657, 589, -5431, 5665, 589, -5415, 5665, 601, -5435, 5705, 617, -5467, 5689, 629, -5467, 5673,                                                                                                                                                                                                },\r
+{124, 665, -5451, 5685, 645, -5431, 5709, 653, -5435, 5717, 645, -5483, 5685, 637, -5495, 5657, 649, -5495, 5637, 637, -5499, 5673, 617, -5483, 5669, 597, -5471, 5673, 605, -5455, 5657, 629, -5443, 5653, 625, -5431, 5673, 633, -5435, 5681, 633, -5439, 5653, 593, -5443, 5633, 585, -5447, 5629, 557, -5419, 5609, 541, -5399, 5629, 569, -5395, 5621, 553, -5423, 5645, 577, -5427, 5649, 593, -5423, 5633, 573, -5411, 5657, 573, -5403, 5657, 569, -5395, 5677, 585, -5415, 5673, 601, -5411, 5681, 629, -5431, 5721, 649, -5431, 5705, 657, -5431, 5697, 641, -5439, 5713, 621, -5427, 5681, 605, -5423, 5693, 625, -5427, 5689, 617, -5439, 5681, 597, -5443, 5653, 589, -5447, 5661, 585, -5443, 5657, 585, -5411, 5653, 573, -5415, 5673, 597, -5419, 5693, 601, -5443, 5689, 613, -5447, 5657, 637, -5451, 5661, 613, -5439, 5657, 613, -5459, 5665, 609, -5463, 5665, 617, -5487, 5681, 641, -5471, 5645, 601, -5467, 5633, 597, -5451, 5633, 565, -5423, 5617, 569, -5423, 5657, 585, -5419, 5641, 601, -5423, 5649, 617, -5431, 5653, 613, -5447, 5657, 625, -5439, 5669, 621, -5407, 5669, 637, -5427, 5665, 629, -5459, 5653, 625, -5475, 5649, 605, -5503, 5641, 613, -5495, 5633, 633, -5487, 5657, 645, -5483, 5673, 633, -5459, 5661, 633, -5447, 5665, 629, -5439, 5661, 621, -5451, 5685, 613, -5463, 5693, 633, -5443, 5673, 657, -5463, 5669, 653, -5443, 5673, 637, -5439, 5653, 629, -5423, 5653, 609, -5415, 5645, 617, -5435, 5665, 601, -5447, 5649, 589, -5447, 5645, 609, -5431, 5621, 625, -5451, 5645, 609, -5439, 5649, 617, -5447, 5649, 609, -5427, 5657, 585, -5439, 5661, 621, -5451, 5673, 625, -5451, 5653, 613, -5455, 5653, 609, -5463, 5617, 597, -5439, 5629, 605, -5443, 5657, 613, -5451, 5673, 613, -5451, 5673, 637, -5443, 5681, 641, -5431, 5693, 645, -5435, 5673, 617, -5435, 5677, 633, -5431, 5673, 617, -5443, 5657, 597, -5439, 5637, 601, -5459, 5649, 613, -5471, 5649, 609, -5467, 5677, 617, -5455, 5653, 621, -5443, 5689, 625, -5447, 5693, 637, -5447, 5701, 645, -5423, 5669, 613, -5399, 5669, 605, -5403, 5645, 597, -5407, 5633, 565, -5431, 5633, 561, -5411, 5633, 597, -5379, 5645, 625, -5387, 5673, 617, -5407, 5669, 657, -5447, 5681, 645, -5463, 5697, 617, -5447, 5669, 621, -5451, 5673, 609, -5463, 5673, 613, -5455, 5649, 605, -5451, 5673,                                                                                                                                                                                                                                },\r
+{125, 617, -5479, 5653, 613, -5467, 5637, 621, -5463, 5641, 621, -5451, 5653, 609, -5451, 5657, 597, -5423, 5653, 613, -5431, 5661, 601, -5423, 5673, 637, -5447, 5665, 633, -5435, 5657, 641, -5427, 5653, 621, -5427, 5653, 621, -5415, 5649, 621, -5435, 5649, 629, -5463, 5673, 617, -5475, 5649, 621, -5463, 5641, 601, -5451, 5657, 613, -5439, 5653, 613, -5415, 5681, 633, -5427, 5673, 633, -5439, 5657, 621, -5467, 5673, 633, -5451, 5657, 637, -5475, 5669, 613, -5491, 5669, 605, -5475, 5649, 601, -5451, 5661, 597, -5455, 5649, 621, -5455, 5633, 625, -5463, 5645, 629, -5435, 5661, 609, -5415, 5661, 621, -5403, 5665, 633, -5427, 5661, 601, -5439, 5661, 621, -5439, 5661, 609, -5455, 5661, 621, -5455, 5669, 613, -5439, 5661, 613, -5455, 5645, 645, -5463, 5653, 621, -5459, 5645, 617, -5447, 5653, 613, -5471, 5657, 633, -5447, 5669, 609, -5431, 5669, 621, -5415, 5681, 613, -5423, 5681, 621, -5435, 5653, 605, -5443, 5657, 621, -5427, 5669, 633, -5431, 5673, 625, -5447, 5665, 633, -5447, 5677, 633, -5423, 5685, 613, -5427, 5709, 605, -5451, 5677, 565, -5427, 5693, 581, -5403, 5685, 609, -5395, 5681, 597, -5447, 5689, 593, -5451, 5641, 605, -5399, 5665, 577, -5419, 5657, 565, -5403, 5617, 565, -5359, 5653, 573, -5383, 5661, 581, -5447, 5633, 557, -5451, 5657, 597, -5423, 5685, 613, -5399, 5709, 649, -5419, 5705, 673, -5447, 5725, 669, -5495, 5713, 669, -5487, 5729, 649, -5467, 5701, 625, -5427, 5713, 605, -5395, 5713, 577, -5415, 5681, 585, -5439, 5681, 585, -5427, 5693, 585, -5399, 5689, 569, -5427, 5681, 605, -5427, 5681, 609, -5427, 5681, 605, -5431, 5681, 597, -5431, 5673, 605, -5427, 5681, 585, -5447, 5685, 577, -5451, 5657, 517, -5435, 5645, 533, -5387, 5621, 529, -5407, 5665, 533, -5375, 5657, 537, -5383, 5669, 525, -5395, 5665, 553, -5419, 5677, 557, -5419, 5677, 557, -5415, 5673, 557, -5407, 5689, 589, -5435, 5689, 565, -5435, 5661, 557, -5439, 5665, 553, -5423, 5673, 529, -5427, 5669, 553, -5427, 5665, 545, -5423, 5665, 569, -5451, 5673, 569, -5423, 5705, 585, -5431, 5705, 589, -5431, 5697, 601, -5455, 5709, 589, -5447, 5709, 577, -5455, 5697, 593, -5435, 5697, 589, -5411, 5681, 573, -5431, 5677, 573, -5451, 5677, 553, -5459, 5665, 573, -5439, 5645, 545, -5415, 5657, 545, -5419, 5649, 541, -5435, 5649, 537, -5435, 5657,                                                                                                                                                                                                },\r
+{124, 533, -5419, 5637, 541, -5399, 5657, 541, -5415, 5665, 553, -5419, 5685, 565, -5427, 5677, 557, -5415, 5701, 565, -5407, 5681, 557, -5399, 5681, 557, -5451, 5665, 561, -5467, 5657, 553, -5471, 5665, 565, -5451, 5657, 569, -5443, 5669, 561, -5443, 5693, 561, -5435, 5681, 581, -5431, 5689, 597, -5427, 5709, 589, -5435, 5689, 593, -5419, 5673, 589, -5423, 5677, 557, -5419, 5689, 565, -5391, 5681, 577, -5391, 5677, 561, -5419, 5665, 569, -5435, 5685, 593, -5447, 5681, 577, -5447, 5673, 577, -5427, 5657, 561, -5411, 5685, 549, -5411, 5661, 549, -5391, 5673, 569, -5395, 5681, 557, -5407, 5677, 549, -5427, 5681, 565, -5435, 5693, 565, -5419, 5705, 593, -5407, 5701, 613, -5435, 5709, 601, -5439, 5693, 585, -5439, 5685, 569, -5443, 5701, 577, -5451, 5693, 581, -5431, 5693, 577, -5415, 5705, 573, -5403, 5685, 577, -5431, 5685, 565, -5423, 5665, 537, -5427, 5685, 557, -5403, 5689, 573, -5411, 5685, 577, -5415, 5669, 589, -5419, 5677, 581, -5431, 5697, 573, -5407, 5693, 561, -5403, 5673, 541, -5383, 5685, 553, -5375, 5697, 549, -5419, 5685, 565, -5407, 5665, 569, -5415, 5673, 557, -5415, 5677, 561, -5395, 5709, 573, -5399, 5697, 561, -5423, 5669, 585, -5439, 5681, 569, -5443, 5685, 553, -5427, 5673, 569, -5419, 5697, 557, -5431, 5701, 565, -5431, 5689, 585, -5403, 5697, 577, -5411, 5705, 565, -5395, 5705, 585, -5415, 5705, 585, -5423, 5677, 581, -5431, 5685, 585, -5399, 5681, 581, -5419, 5697, 593, -5415, 5693, 605, -5419, 5709, 605, -5435, 5705, 585, -5427, 5697, 545, -5443, 5685, 553, -5427, 5681, 569, -5431, 5665, 561, -5419, 5669, 545, -5435, 5669, 549, -5439, 5677, 549, -5427, 5669, 581, -5407, 5665, 557, -5387, 5661, 561, -5403, 5681, 573, -5403, 5693, 589, -5379, 5669, 589, -5379, 5685, 609, -5383, 5709, 625, -5403, 5709, 601, -5419, 5701, 597, -5403, 5733, 593, -5419, 5713, 597, -5407, 5697, 593, -5415, 5693, 577, -5459, 5681, 537, -5455, 5669, 521, -5439, 5661, 569, -5431, 5661, 577, -5415, 5689, 597, -5399, 5677, 597, -5395, 5713, 621, -5399, 5721, 625, -5419, 5721, 629, -5427, 5713, 605, -5435, 5709, 613, -5447, 5709, 605, -5435, 5669, 593, -5423, 5657, 565, -5415, 5669, 557, -5419, 5673, 561, -5427, 5649, 537, -5435, 5641, 541, -5411, 5645, 537, -5399, 5657, 561, -5411, 5681, 565, -5395, 5677,                                                                                                                                                                                                                                },\r
+{124, 601, -5395, 5689, 625, -5423, 5705, 629, -5427, 5701, 605, -5427, 5669, 605, -5439, 5673, 581, -5435, 5677, 589, -5451, 5677, 577, -5443, 5677, 557, -5435, 5673, 561, -5435, 5685, 577, -5411, 5673, 605, -5395, 5677, 605, -5411, 5693, 597, -5447, 5669, 597, -5443, 5661, 597, -5435, 5677, 581, -5435, 5665, 593, -5419, 5693, 601, -5431, 5665, 585, -5439, 5661, 597, -5427, 5681, 593, -5411, 5693, 577, -5415, 5701, 573, -5399, 5693, 597, -5411, 5685, 601, -5435, 5669, 589, -5419, 5673, 585, -5415, 5673, 593, -5411, 5661, 593, -5423, 5677, 605, -5411, 5685, 593, -5419, 5693, 613, -5431, 5705, 593, -5415, 5689, 613, -5415, 5705, 573, -5395, 5689, 569, -5423, 5697, 597, -5463, 5685, 589, -5455, 5673, 593, -5435, 5669, 573, -5415, 5673, 625, -5211, 5661, 661, -5383, 5861, 633, -5695, 5697, 577, -5551, 5593, 497, -5283, 5733, 577, -5299, 5685, 625, -5443, 5673, 589, -5515, 5645, 573, -5483, 5645, 573, -5435, 5677, 597, -5379, 5705, 613, -5379, 5709, 629, -5403, 5709, 617, -5403, 5709, 605, -5391, 5705, 585, -5371, 5693, 565, -5419, 5697, 577, -5463, 5681, 569, -5463, 5657, 553, -5447, 5645, 561, -5443, 5645, 561, -5427, 5661, 561, -5411, 5677, 565, -5419, 5657, 569, -5411, 5685, 597, -5435, 5693, 589, -5387, 5717, 593, -5367, 5705, 609, -5375, 5705, 605, -5399, 5705, 601, -5403, 5669, 589, -5415, 5665, 577, -5439, 5677, 569, -5443, 5661, 581, -5431, 5685, 581, -5423, 5693, 585, -5415, 5697, 585, -5399, 5697, 569, -5403, 5721, 585, -5427, 5741, 605, -5443, 5725, 597, -5423, 5685, 617, -5411, 5677, 609, -5423, 5685, 569, -5411, 5677, 577, -5415, 5669, 597, -5415, 5669, 589, -5431, 5665, 585, -5431, 5685, 597, -5423, 5705, 581, -5411, 5689, 585, -5403, 5681, 577, -5391, 5677, 569, -5415, 5669, 581, -5423, 5657, 581, -5431, 5649, 585, -5463, 5665, 585, -5443, 5661, 585, -5435, 5677, 601, -5419, 5681, 605, -5415, 5701, 597, -5431, 5689, 589, -5423, 5677, 577, -5431, 5661, 569, -5415, 5669, 585, -5411, 5669, 593, -5395, 5689, 601, -5395, 5693, 605, -5427, 5681, 621, -5443, 5673, 609, -5451, 5693, 601, -5439, 5681, 589, -5435, 5669, 605, -5435, 5681, 617, -5423, 5701, 621, -5415, 5697, 617, -5427, 5693, 605, -5435, 5689, 593, -5411, 5681, 577, -5399, 5689, 597, -5399, 5657, 605, -5391, 5661, 601, -5427, 5665,                                                                                                                                                                                                                                },\r
+{125, 593, -5455, 5657, 609, -5459, 5657, 597, -5431, 5653, 609, -5419, 5669, 593, -5403, 5653, 601, -5411, 5681, 597, -5411, 5697, 593, -5427, 5693, 621, -5431, 5677, 609, -5447, 5649, 613, -5439, 5665, 609, -5431, 5649, 617, -5423, 5673, 593, -5455, 5641, 609, -5463, 5677, 617, -5451, 5661, 617, -5447, 5645, 621, -5431, 5673, 609, -5423, 5677, 617, -5407, 5673, 601, -5415, 5673, 613, -5435, 5657, 613, -5435, 5649, 637, -5451, 5653, 629, -5471, 5633, 641, -5443, 5653, 633, -5443, 5649, 625, -5451, 5665, 633, -5451, 5641, 625, -5459, 5609, 621, -5479, 5661, 633, -5435, 5673, 629, -5415, 5681, 637, -5403, 5689, 621, -5431, 5685, 617, -5439, 5653, 613, -5431, 5661, 605, -5463, 5657, 625, -5447, 5641, 657, -5463, 5645, 657, -5475, 5657, 657, -5479, 5645, 637, -5483, 5649, 637, -5483, 5657, 637, -5459, 5657, 645, -5463, 5653, 665, -5463, 5681, 657, -5459, 5657, 649, -5443, 5645, 649, -5439, 5641, 629, -5447, 5649, 641, -5463, 5641, 665, -5475, 5633, 657, -5475, 5641, 649, -5451, 5637, 653, -5459, 5637, 661, -5455, 5637, 645, -5455, 5629, 645, -5459, 5649, 657, -5479, 5645, 641, -5463, 5645, 681, -5471, 5637, 657, -5475, 5633, 629, -5467, 5621, 637, -5463, 5637, 637, -5471, 5633, 653, -5475, 5629, 653, -5487, 5641, 649, -5475, 5633, 669, -5463, 5621, 665, -5491, 5637, 657, -5475, 5641, 677, -5467, 5645, 673, -5467, 5645, 661, -5463, 5621, 637, -5467, 5633, 629, -5471, 5641, 657, -5471, 5649, 673, -5463, 5633, 665, -5479, 5641, 657, -5459, 5625, 637, -5467, 5621, 653, -5463, 5641, 669, -5459, 5641, 681, -5459, 5641, 677, -5479, 5653, 705, -5487, 5665, 689, -5491, 5645, 685, -5463, 5609, 669, -5455, 5625, 657, -5455, 5621, 649, -5447, 5609, 661, -5471, 5621, 673, -5455, 5629, 669, -5459, 5625, 669, -5447, 5657, 685, -5443, 5677, 693, -5463, 5645, 693, -5475, 5645, 665, -5479, 5637, 657, -5471, 5657, 665, -5499, 5641, 693, -5495, 5637, 665, -5487, 5621, 641, -5479, 5609, 645, -5471, 5621, 649, -5483, 5621, 641, -5475, 5633, 669, -5463, 5665, 677, -5467, 5661, 673, -5459, 5649, 669, -5455, 5633, 677, -5463, 5641, 637, -5451, 5637, 637, -5479, 5629, 637, -5483, 5637, 653, -5463, 5617, 641, -5479, 5641, 641, -5471, 5609, 641, -5451, 5613, 637, -5459, 5621, 641, -5467, 5621, 649, -5443, 5625, 673, -5471, 5637, 669, -5471, 5641,                                                                                                                                                                                                },\r
+{123, 689, -5471, 5657, 669, -5479, 5661, 649, -5443, 5645, 625, -5419, 5669, 633, -5435, 5641, 625, -5467, 5641, 629, -5451, 5621, 645, -5447, 5625, 657, -5447, 5649, 661, -5447, 5645, 685, -5471, 5649, 697, -5499, 5653, 685, -5515, 5653, 641, -5519, 5641, 641, -5507, 5657, 645, -5511, 5649, 621, -5507, 5633, 593, -5475, 5633, 565, -5451, 5617, 577, -5443, 5641, 589, -5439, 5641, 621, -5427, 5617, 661, -5275, 5637, 717, -5447, 5805, 725, -5623, 5533, 701, -5411, 5669, 645, -5431, 5657, 665, -5363, 5605, 657, -5387, 5629, 637, -5447, 5621, 637, -5467, 5637, 625, -5439, 5637, 629, -5415, 5673, 637, -5435, 5725, 653, -5443, 5733, 665, -5451, 5713, 653, -5479, 5697, 625, -5455, 5653, 585, -5467, 5657, 593, -5471, 5633, 597, -5483, 5649, 605, -5483, 5641, 609, -5463, 5629, 629, -5463, 5645, 645, -5471, 5653, 649, -5463, 5653, 661, -5463, 5645, 629, -5439, 5645, 621, -5415, 5665, 617, -5411, 5693, 629, -5427, 5697, 625, -5419, 5665, 609, -5423, 5661, 621, -5439, 5649, 629, -5427, 5629, 597, -5443, 5645, 597, -5455, 5645, 617, -5467, 5637, 637, -5455, 5637, 609, -5451, 5661, 625, -5459, 5673, 657, -5451, 5689, 629, -5431, 5689, 617, -5435, 5697, 629, -5451, 5673, 613, -5451, 5665, 613, -5451, 5645, 605, -5451, 5657, 617, -5459, 5685, 633, -5455, 5677, 617, -5451, 5665, 609, -5459, 5649, 649, -5435, 5669, 633, -5427, 5681, 629, -5435, 5669, 629, -5431, 5661, 605, -5427, 5657, 593, -5443, 5653, 581, -5451, 5645, 565, -5435, 5641, 569, -5427, 5653, 585, -5439, 5677, 605, -5443, 5677, 597, -5439, 5669, 605, -5443, 5677, 613, -5447, 5645, 633, -5447, 5653, 605, -5435, 5653, 585, -5435, 5661, 585, -5435, 5661, 573, -5423, 5641, 593, -5399, 5645, 593, -5395, 5681, 585, -5407, 5669, 605, -5431, 5689, 629, -5423, 5717, 633, -5439, 5713, 629, -5431, 5709, 613, -5451, 5689, 605, -5463, 5697, 589, -5459, 5653, 573, -5439, 5649, 577, -5439, 5673, 573, -5447, 5673, 581, -5443, 5661, 589, -5423, 5677, 593, -5411, 5693, 597, -5407, 5693, 605, -5415, 5693, 613, -5423, 5693, 625, -5419, 5677, 637, -5403, 5665, 617, -5419, 5657, 573, -5431, 5677, 569, -5443, 5657, 545, -5447, 5645, 561, -5443, 5649, 565, -5419, 5681, 577, -5395, 5661, 569, -5407, 5693, 585, -5423, 5689, 621, -5415, 5713, 613, -5391, 5685,                                                                                                                                                                                                                                                                },\r
+{125, 625, -5411, 5705, 609, -5411, 5697, 593, -5415, 5661, 581, -5423, 5661, 569, -5427, 5661, 581, -5423, 5681, 593, -5419, 5685, 621, -5419, 5681, 613, -5419, 5701, 617, -5411, 5709, 589, -5403, 5693, 589, -5403, 5677, 593, -5403, 5685, 585, -5415, 5685, 593, -5427, 5677, 601, -5423, 5673, 605, -5427, 5681, 593, -5407, 5689, 613, -5419, 5685, 593, -5411, 5677, 601, -5395, 5669, 589, -5411, 5685, 585, -5395, 5657, 585, -5403, 5681, 585, -5435, 5649, 605, -5427, 5657, 597, -5463, 5677, 613, -5467, 5625, 605, -5351, 5685, 597, -5355, 5713, 621, -5391, 5693, 613, -5439, 5697, 593, -5435, 5681, 597, -5415, 5661, 617, -5371, 5717, 633, -5395, 5673, 629, -5391, 5637, 605, -5415, 5677, 613, -5495, 5645, 621, -5491, 5657, 649, -5375, 5697, 637, -5327, 5741, 665, -5379, 5725, 633, -5383, 5677, 625, -5327, 5725, 621, -5399, 5717, 625, -5419, 5613, 593, -5359, 5709, 601, -5467, 5697, 649, -5415, 5589, 641, -5419, 5701, 653, -5467, 5601, 701, -5363, 5681, 709, -5419, 5793, 713, -5551, 5677, 709, -5379, 5597, 633, -5331, 5797, 637, -5411, 5641, 633, -5399, 5673, 621, -5339, 5689, 621, -5347, 5665, 637, -5387, 5677, 665, -5467, 5669, 697, -5371, 5677, 697, -5427, 5653, 701, -5423, 5673, 733, -5407, 5645, 733, -5419, 5701, 737, -5391, 5653, 721, -5411, 5673, 729, -5379, 5697, 705, -5399, 5729, 697, -5387, 5701, 713, -5355, 5701, 725, -5299, 5725, 745, -5335, 5737, 721, -5403, 5777, 753, -5383, 5689, 741, -5399, 5733, 781, -5371, 5705, 785, -5355, 5681, 765, -5403, 5705, 785, -5415, 5665, 777, -5471, 5617, 817, -5403, 5677, 805, -5471, 5653, 829, -5459, 5717, 813, -5491, 5637, 845, -5435, 5685, 833, -5451, 5613, 825, -5415, 5685, 809, -5455, 5633, 805, -5419, 5697, 809, -5467, 5581, 833, -5379, 5657, 793, -5435, 5569, 829, -5467, 5653, 861, -5407, 5645, 881, -5391, 5645, 877, -5439, 5597, 853, -5495, 5641, 837, -5431, 5669, 861, -5435, 5617, 889, -5443, 5637, 913, -5431, 5661, 917, -5455, 5665, 913, -5491, 5653, 921, -5499, 5665, 929, -5463, 5617, 893, -5451, 5665, 889, -5475, 5613, 877, -5495, 5645, 921, -5495, 5581, 921, -5499, 5605, 889, -5479, 5557, 901, -5415, 5657, 897, -5523, 5629, 953, -5499, 5573, 921, -5471, 5605, 885, -5475, 5597, 869, -5515, 5585, 901, -5419, 5597, 901, -5415, 5645, 933, -5439, 5565, 937, -5415, 5637,                                                                                                                                                                                                },\r
+{124, 921, -5495, 5605, 949, -5479, 5593, 933, -5519, 5649, 957, -5447, 5605, 989, -5407, 5653, 961, -5471, 5629, 965, -5459, 5637, 973, -5491, 5641, 977, -5475, 5617, 941, -5479, 5609, 933, -5471, 5605, 925, -5459, 5617, 929, -5483, 5613, 929, -5475, 5609, 929, -5479, 5613, 957, -5475, 5609, 961, -5475, 5601, 969, -5459, 5613, 965, -5475, 5625, 945, -5471, 5617, 945, -5451, 5605, 965, -5459, 5613, 953, -5443, 5629, 937, -5435, 5597, 949, -5459, 5605, 917, -5471, 5609, 909, -5491, 5593, 933, -5475, 5593, 949, -5455, 5605, 961, -5467, 5581, 981, -5439, 5601, 985, -5467, 5621, 965, -5495, 5637, 969, -5515, 5625, 957, -5499, 5621, 961, -5463, 5625, 937, -5459, 5605, 941, -5475, 5593, 913, -5479, 5589, 913, -5479, 5585, 917, -5483, 5577, 929, -5471, 5593, 937, -5475, 5585, 945, -5451, 5581, 957, -5439, 5621, 969, -5447, 5621, 977, -5463, 5629, 961, -5455, 5653, 969, -5463, 5621, 949, -5467, 5613, 941, -5483, 5601, 921, -5451, 5585, 925, -5435, 5589, 925, -5451, 5585, 925, -5475, 5629, 925, -5463, 5605, 929, -5451, 5633, 941, -5431, 5649, 949, -5423, 5613, 933, -5435, 5609, 937, -5451, 5629, 953, -5451, 5641, 933, -5451, 5621, 953, -5447, 5629, 949, -5443, 5645, 933, -5435, 5649, 949, -5451, 5641, 945, -5447, 5621, 937, -5439, 5645, 937, -5443, 5645, 929, -5467, 5649, 941, -5455, 5641, 937, -5443, 5625, 945, -5431, 5609, 917, -5419, 5617, 917, -5463, 5617, 917, -5467, 5621, 929, -5447, 5609, 913, -5423, 5621, 925, -5419, 5617, 929, -5443, 5629, 917, -5459, 5633, 909, -5443, 5613, 897, -5423, 5613, 913, -5431, 5617, 925, -5459, 5641, 937, -5475, 5633, 953, -5459, 5617, 941, -5443, 5629, 929, -5431, 5633, 917, -5447, 5649, 929, -5439, 5641, 941, -5447, 5629, 933, -5463, 5633, 909, -5443, 5629, 921, -5439, 5637, 921, -5447, 5633, 913, -5459, 5621, 929, -5439, 5625, 937, -5427, 5641, 929, -5451, 5633, 945, -5455, 5645, 933, -5431, 5625, 941, -5435, 5649, 925, -5455, 5629, 905, -5439, 5617, 885, -5439, 5609, 893, -5443, 5617, 925, -5435, 5633, 929, -5411, 5629, 921, -5419, 5629, 941, -5427, 5629, 929, -5415, 5617, 925, -5439, 5645, 909, -5455, 5641, 897, -5471, 5629, 929, -5495, 5605, 945, -5467, 5633, 917, -5415, 5609, 917, -5431, 5649, 921, -5467, 5621, 945, -5463, 5625, 929, -5459, 5637, 937, -5459, 5645,                                                                                                                                                                                                                                },\r
+{125, 925, -5447, 5641, 893, -5435, 5629, 901, -5443, 5633, 889, -5403, 5609, 885, -5471, 5589, 909, -5495, 5601, 913, -5463, 5621, 945, -5411, 5577, 913, -5427, 5605, 913, -5435, 5613, 945, -5455, 5645, 929, -5423, 5629, 917, -5395, 5649, 949, -5423, 5645, 937, -5443, 5645, 941, -5459, 5637, 949, -5475, 5649, 941, -5479, 5613, 909, -5463, 5609, 917, -5455, 5597, 905, -5503, 5613, 889, -5515, 5653, 913, -5455, 5613, 933, -5451, 5621, 921, -5451, 5641, 913, -5451, 5621, 941, -5443, 5645, 941, -5443, 5629, 937, -5451, 5637, 929, -5443, 5641, 917, -5443, 5621, 937, -5435, 5629, 913, -5447, 5625, 889, -5439, 5625, 893, -5427, 5629, 905, -5443, 5621, 901, -5455, 5613, 913, -5439, 5621, 913, -5431, 5621, 909, -5423, 5601, 929, -5451, 5637, 929, -5463, 5645, 905, -5435, 5661, 901, -5435, 5629, 889, -5439, 5633, 881, -5447, 5613, 881, -5447, 5597, 913, -5491, 5625, 937, -5451, 5645, 933, -5415, 5633, 921, -5443, 5625, 949, -5479, 5629, 937, -5495, 5649, 929, -5467, 5653, 937, -5435, 5665, 921, -5439, 5649, 913, -5439, 5633, 905, -5447, 5629, 897, -5447, 5629, 893, -5447, 5593, 901, -5455, 5609, 893, -5443, 5609, 897, -5467, 5613, 909, -5467, 5633, 925, -5439, 5629, 921, -5431, 5641, 937, -5443, 5641, 937, -5459, 5621, 901, -5467, 5629, 877, -5427, 5625, 881, -5443, 5629, 889, -5447, 5617, 889, -5447, 5621, 889, -5451, 5613, 897, -5427, 5613, 889, -5411, 5629, 893, -5411, 5645, 905, -5431, 5653, 909, -5443, 5657, 893, -5471, 5661, 913, -5471, 5661, 885, -5463, 5645, 877, -5439, 5649, 909, -5447, 5645, 893, -5447, 5629, 885, -5459, 5625, 877, -5459, 5617, 861, -5443, 5633, 873, -5403, 5641, 893, -5407, 5641, 889, -5403, 5637, 897, -5427, 5641, 897, -5411, 5653, 901, -5411, 5637, 893, -5399, 5641, 889, -5427, 5661, 873, -5459, 5637, 873, -5451, 5625, 861, -5439, 5621, 865, -5435, 5609, 865, -5415, 5621, 861, -5447, 5661, 881, -5451, 5653, 885, -5423, 5661, 869, -5395, 5629, 853, -5399, 5645, 877, -5419, 5645, 881, -5435, 5645, 917, -5411, 5649, 901, -5423, 5657, 913, -5439, 5661, 897, -5463, 5657, 901, -5463, 5645, 889, -5475, 5637, 857, -5455, 5641, 837, -5439, 5653, 861, -5435, 5645, 881, -5443, 5673, 885, -5439, 5673, 889, -5447, 5665, 873, -5411, 5673, 869, -5407, 5669, 873, -5407, 5653, 853, -5423, 5637, 837, -5431, 5641,                                                                                                                                                                                                },\r
+{124, 849, -5439, 5637, 853, -5391, 5645, 861, -5399, 5661, 853, -5431, 5637, 825, -5475, 5625, 833, -5447, 5625, 849, -5399, 5653, 865, -5407, 5661, 853, -5447, 5653, 857, -5431, 5645, 829, -5439, 5633, 825, -5423, 5633, 841, -5423, 5657, 829, -5427, 5641, 829, -5427, 5669, 837, -5419, 5653, 853, -5403, 5657, 857, -5419, 5697, 833, -5451, 5653, 837, -5443, 5661, 825, -5403, 5649, 825, -5423, 5661, 825, -5439, 5649, 813, -5431, 5657, 849, -5435, 5677, 817, -5411, 5665, 825, -5387, 5657, 829, -5399, 5653, 817, -5411, 5657, 833, -5403, 5685, 817, -5399, 5673, 821, -5399, 5677, 841, -5419, 5665, 837, -5423, 5665, 829, -5423, 5657, 825, -5427, 5657, 833, -5427, 5673, 825, -5439, 5665, 829, -5447, 5641, 821, -5447, 5665, 837, -5431, 5669, 837, -5395, 5681, 837, -5395, 5681, 821, -5391, 5673, 829, -5415, 5649, 829, -5415, 5665, 817, -5415, 5677, 829, -5371, 5681, 873, -5351, 5705, 841, -5411, 5677, 845, -5475, 5661, 821, -5475, 5633, 805, -5391, 5649, 817, -5399, 5641, 809, -5423, 5621, 809, -5447, 5637, 797, -5447, 5641, 789, -5431, 5649, 829, -5403, 5701, 837, -5399, 5673, 853, -5395, 5685, 849, -5383, 5693, 845, -5371, 5689, 845, -5391, 5681, 825, -5431, 5681, 813, -5435, 5661, 805, -5447, 5645, 837, -5431, 5657, 829, -5419, 5661, 813, -5431, 5649, 817, -5423, 5669, 809, -5419, 5661, 809, -5427, 5689, 849, -5427, 5697, 841, -5407, 5697, 841, -5399, 5693, 845, -5399, 5685, 805, -5395, 5677, 785, -5403, 5649, 805, -5419, 5641, 813, -5435, 5637, 821, -5439, 5665, 801, -5423, 5657, 817, -5411, 5653, 813, -5391, 5661, 821, -5411, 5661, 825, -5419, 5669, 817, -5427, 5681, 809, -5391, 5669, 809, -5363, 5681, 805, -5395, 5693, 817, -5423, 5661, 821, -5427, 5657, 813, -5407, 5657, 825, -5427, 5661, 821, -5419, 5657, 825, -5431, 5653, 825, -5447, 5665, 825, -5415, 5677, 829, -5407, 5685, 813, -5415, 5669, 825, -5399, 5677, 813, -5439, 5649, 801, -5387, 5669, 809, -5399, 5689, 797, -5395, 5649, 817, -5407, 5661, 837, -5395, 5677, 849, -5391, 5661, 841, -5419, 5665, 821, -5423, 5653, 825, -5423, 5665, 837, -5399, 5641, 825, -5371, 5653, 805, -5371, 5661, 817, -5387, 5685, 825, -5407, 5681, 825, -5399, 5677, 833, -5411, 5677, 825, -5427, 5677, 809, -5439, 5673, 849, -5451, 5657, 849, -5447, 5677, 849, -5459, 5649,                                                                                                                                                                                                                                },\r
+{124, 833, -5435, 5645, 837, -5423, 5657, 841, -5439, 5661, 833, -5403, 5665, 845, -5411, 5665, 825, -5419, 5657, 817, -5415, 5657, 809, -5399, 5677, 817, -5399, 5649, 837, -5423, 5677, 825, -5451, 5641, 813, -5435, 5621, 813, -5431, 5613, 833, -5423, 5645, 837, -5427, 5653, 821, -5447, 5649, 833, -5423, 5673, 865, -5415, 5701, 873, -5427, 5689, 833, -5447, 5649, 813, -5435, 5657, 837, -5439, 5645, 837, -5427, 5677, 849, -5415, 5669, 849, -5431, 5669, 817, -5427, 5665, 813, -5427, 5657, 821, -5419, 5657, 825, -5403, 5657, 825, -5411, 5669, 845, -5415, 5661, 849, -5403, 5661, 865, -5423, 5697, 849, -5427, 5689, 861, -5427, 5693, 857, -5435, 5673, 853, -5411, 5673, 829, -5395, 5669, 817, -5407, 5665, 837, -5431, 5677, 829, -5415, 5653, 825, -5407, 5641, 829, -5431, 5645, 829, -5439, 5661, 841, -5419, 5677, 857, -5415, 5677, 853, -5435, 5665, 845, -5431, 5681, 849, -5431, 5661, 841, -5435, 5645, 813, -5439, 5641, 801, -5443, 5653, 801, -5443, 5661, 825, -5435, 5649, 817, -5411, 5641, 825, -5415, 5657, 837, -5427, 5665, 849, -5423, 5665, 865, -5431, 5665, 845, -5415, 5665, 837, -5427, 5661, 829, -5415, 5649, 813, -5411, 5645, 825, -5423, 5633, 813, -5423, 5657, 809, -5435, 5637, 825, -5407, 5661, 825, -5411, 5661, 849, -5431, 5657, 857, -5443, 5677, 833, -5431, 5653, 813, -5431, 5653, 817, -5435, 5645, 821, -5427, 5653, 857, -5423, 5665, 821, -5415, 5677, 813, -5387, 5689, 837, -5399, 5685, 833, -5435, 5653, 825, -5415, 5665, 845, -5455, 5677, 817, -5455, 5649, 825, -5443, 5657, 849, -5451, 5657, 837, -5435, 5641, 841, -5431, 5657, 841, -5431, 5649, 837, -5427, 5661, 841, -5427, 5681, 837, -5403, 5669, 841, -5407, 5677, 817, -5411, 5657, 817, -5387, 5665, 837, -5379, 5665, 833, -5399, 5641, 813, -5419, 5649, 813, -5455, 5625, 821, -5451, 5625, 825, -5419, 5617, 821, -5419, 5657, 825, -5423, 5669, 841, -5439, 5657, 845, -5415, 5657, 853, -5419, 5685, 829, -5419, 5681, 829, -5403, 5673, 833, -5419, 5673, 821, -5411, 5657, 837, -5423, 5673, 829, -5411, 5665, 833, -5419, 5669, 845, -5443, 5685, 845, -5439, 5673, 821, -5459, 5657, 825, -5427, 5641, 829, -5403, 5677, 817, -5395, 5649, 805, -5403, 5649, 801, -5415, 5633, 817, -5427, 5673, 837, -5423, 5697, 869, -5411, 5685, 861, -5411, 5681, 865, -5415, 5681,                                                                                                                                                                                                                                },\r
+{124, 849, -5427, 5689, 845, -5415, 5661, 813, -5415, 5677, 809, -5423, 5641, 801, -5407, 5649, 817, -5415, 5661, 817, -5419, 5661, 825, -5435, 5637, 809, -5427, 5641, 817, -5427, 5657, 829, -5431, 5665, 837, -5407, 5645, 857, -5415, 5669, 857, -5399, 5673, 813, -5435, 5649, 813, -5451, 5665, 829, -5435, 5657, 817, -5447, 5637, 845, -5431, 5653, 849, -5407, 5673, 841, -5407, 5669, 829, -5423, 5661, 833, -5423, 5677, 845, -5419, 5665, 825, -5427, 5645, 845, -5411, 5645, 845, -5423, 5637, 821, -5439, 5645, 829, -5435, 5645, 825, -5423, 5637, 849, -5427, 5649, 837, -5431, 5665, 837, -5423, 5661, 821, -5435, 5661, 829, -5415, 5649, 837, -5415, 5669, 849, -5411, 5657, 833, -5407, 5661, 849, -5415, 5657, 857, -5443, 5657, 825, -5439, 5653, 837, -5451, 5657, 809, -5467, 5653, 821, -5447, 5641, 853, -5435, 5661, 861, -5435, 5657, 857, -5439, 5653, 849, -5435, 5657, 825, -5447, 5653, 845, -5443, 5649, 853, -5431, 5669, 857, -5443, 5657, 857, -5443, 5649, 861, -5423, 5657, 857, -5407, 5665, 845, -5427, 5633, 825, -5435, 5625, 829, -5431, 5621, 829, -5439, 5633, 817, -5439, 5625, 829, -5439, 5637, 825, -5435, 5641, 853, -5415, 5637, 857, -5427, 5669, 849, -5431, 5665, 849, -5423, 5645, 845, -5435, 5649, 857, -5451, 5653, 861, -5439, 5649, 869, -5439, 5649, 861, -5415, 5657, 845, -5423, 5637, 845, -5419, 5653, 849, -5435, 5653, 861, -5443, 5641, 857, -5451, 5653, 865, -5455, 5657, 853, -5447, 5653, 845, -5443, 5645, 829, -5443, 5641, 825, -5431, 5641, 813, -5447, 5633, 841, -5435, 5633, 865, -5439, 5633, 857, -5431, 5641, 845, -5423, 5661, 829, -5423, 5653, 861, -5423, 5657, 869, -5435, 5653, 861, -5439, 5657, 857, -5407, 5649, 869, -5419, 5645, 841, -5415, 5649, 837, -5431, 5637, 817, -5439, 5637, 821, -5455, 5637, 837, -5447, 5633, 849, -5431, 5645, 853, -5447, 5657, 853, -5455, 5625, 861, -5463, 5661, 857, -5443, 5657, 857, -5447, 5637, 849, -5447, 5633, 821, -5451, 5649, 833, -5451, 5657, 841, -5439, 5633, 849, -5407, 5637, 841, -5419, 5641, 833, -5419, 5641, 841, -5427, 5633, 849, -5427, 5653, 849, -5431, 5649, 853, -5435, 5665, 825, -5435, 5653, 845, -5435, 5657, 857, -5451, 5641, 853, -5459, 5637, 853, -5463, 5625, 833, -5439, 5637, 849, -5431, 5641, 849, -5423, 5649, 833, -5415, 5645, 821, -5419, 5629,                                                                                                                                                                                                                                },\r
+{124, 825, -5431, 5629, 829, -5431, 5661, 857, -5423, 5661, 869, -5431, 5673, 865, -5431, 5669, 857, -5435, 5657, 853, -5415, 5645, 841, -5423, 5637, 837, -5467, 5641, 809, -5479, 5621, 849, -5479, 5661, 865, -5451, 5645, 857, -5443, 5637, 837, -5427, 5637, 837, -5431, 5653, 853, -5459, 5657, 873, -5439, 5665, 873, -5427, 5637, 849, -5423, 5649, 833, -5439, 5661, 849, -5431, 5621, 837, -5415, 5637, 829, -5427, 5625, 837, -5423, 5629, 837, -5447, 5621, 849, -5455, 5633, 853, -5443, 5601, 837, -5423, 5641, 829, -5427, 5637, 845, -5435, 5661, 845, -5435, 5653, 845, -5439, 5657, 865, -5447, 5661, 877, -5443, 5637, 857, -5471, 5649, 865, -5467, 5645, 845, -5443, 5629, 845, -5435, 5633, 853, -5419, 5649, 853, -5423, 5641, 841, -5423, 5661, 845, -5451, 5649, 841, -5439, 5633, 841, -5447, 5641, 849, -5423, 5633, 841, -5427, 5637, 841, -5455, 5653, 849, -5455, 5621, 849, -5455, 5617, 841, -5447, 5629, 849, -5447, 5641, 853, -5423, 5641, 857, -5427, 5633, 837, -5443, 5649, 845, -5439, 5641, 853, -5423, 5633, 861, -5431, 5661, 869, -5419, 5657, 865, -5431, 5641, 877, -5419, 5665, 861, -5439, 5641, 829, -5443, 5645, 829, -5447, 5613, 845, -5455, 5637, 837, -5431, 5613, 833, -5463, 5637, 821, -5431, 5625, 841, -5439, 5637, 865, -5451, 5637, 865, -5447, 5637, 845, -5455, 5637, 857, -5459, 5633, 833, -5467, 5637, 845, -5463, 5633, 853, -5439, 5637, 849, -5455, 5629, 853, -5447, 5629, 845, -5435, 5629, 873, -5443, 5637, 877, -5463, 5629, 865, -5447, 5637, 877, -5431, 5629, 877, -5443, 5645, 877, -5443, 5641, 865, -5455, 5637, 849, -5439, 5629, 869, -5451, 5645, 861, -5467, 5637, 869, -5451, 5613, 861, -5447, 5621, 849, -5455, 5633, 841, -5471, 5629, 849, -5455, 5629, 853, -5439, 5653, 861, -5443, 5641, 873, -5455, 5645, 861, -5451, 5629, 857, -5415, 5637, 873, -5415, 5633, 881, -5419, 5625, 857, -5463, 5641, 837, -5495, 5629, 849, -5499, 5629, 865, -5471, 5629, 865, -5467, 5629, 873, -5471, 5625, 861, -5463, 5617, 853, -5471, 5621, 877, -5467, 5613, 853, -5471, 5645, 865, -5463, 5649, 873, -5467, 5637, 865, -5447, 5641, 889, -5451, 5637, 869, -5455, 5621, 857, -5467, 5601, 857, -5455, 5601, 861, -5447, 5601, 869, -5467, 5609, 845, -5459, 5605, 857, -5451, 5593, 853, -5431, 5633, 873, -5451, 5625, 865, -5455, 5629,                                                                                                                                                                                                                                },\r
+{124, 877, -5451, 5621, 865, -5455, 5621, 873, -5483, 5621, 865, -5487, 5613, 857, -5475, 5605, 869, -5471, 5617, 877, -5475, 5613, 893, -5471, 5621, 893, -5475, 5633, 869, -5475, 5617, 849, -5467, 5621, 861, -5459, 5621, 865, -5455, 5621, 853, -5455, 5585, 873, -5487, 5613, 865, -5463, 5601, 845, -5459, 5605, 857, -5451, 5625, 877, -5475, 5625, 873, -5491, 5617, 877, -5471, 5621, 865, -5463, 5617, 857, -5455, 5621, 861, -5467, 5621, 857, -5447, 5621, 877, -5459, 5633, 881, -5459, 5617, 861, -5447, 5637, 869, -5439, 5625, 885, -5447, 5617, 877, -5467, 5625, 877, -5479, 5621, 877, -5471, 5629, 865, -5467, 5625, 889, -5491, 5633, 877, -5487, 5621, 861, -5459, 5621, 881, -5471, 5621, 857, -5479, 5617, 853, -5439, 5617, 877, -5451, 5617, 857, -5455, 5617, 869, -5443, 5637, 885, -5467, 5633, 885, -5495, 5621, 893, -5475, 5625, 885, -5459, 5625, 881, -5483, 5601, 869, -5483, 5625, 885, -5455, 5617, 877, -5451, 5617, 877, -5467, 5609, 861, -5475, 5601, 869, -5479, 5605, 865, -5475, 5593, 865, -5479, 5613, 873, -5471, 5609, 877, -5463, 5605, 893, -5471, 5609, 885, -5463, 5621, 897, -5455, 5629, 889, -5459, 5621, 873, -5459, 5617, 865, -5491, 5621, 877, -5495, 5581, 861, -5487, 5605, 857, -5479, 5609, 869, -5487, 5613, 889, -5479, 5605, 897, -5451, 5605, 885, -5467, 5613, 873, -5455, 5605, 861, -5487, 5621, 877, -5495, 5613, 877, -5479, 5597, 881, -5463, 5617, 877, -5471, 5629, 869, -5515, 5593, 889, -5523, 5605, 869, -5467, 5593, 861, -5459, 5593, 873, -5483, 5609, 877, -5479, 5609, 873, -5459, 5633, 893, -5443, 5617, 889, -5467, 5629, 889, -5467, 5621, 853, -5471, 5609, 865, -5463, 5593, 881, -5463, 5617, 865, -5483, 5581, 869, -5471, 5589, 877, -5479, 5597, 873, -5475, 5585, 881, -5471, 5593, 897, -5471, 5609, 901, -5471, 5633, 873, -5483, 5613, 889, -5471, 5625, 873, -5471, 5613, 877, -5463, 5605, 853, -5463, 5605, 853, -5447, 5597, 893, -5435, 5617, 881, -5479, 5605, 881, -5503, 5593, 877, -5475, 5609, 901, -5451, 5617, 889, -5499, 5637, 877, -5511, 5589, 845, -5471, 5589, 857, -5459, 5613, 881, -5455, 5605, 885, -5475, 5597, 893, -5487, 5605, 893, -5483, 5637, 881, -5471, 5625, 881, -5451, 5621, 865, -5467, 5633, 865, -5467, 5617, 877, -5491, 5621, 889, -5483, 5609, 877, -5475, 5609, 869, -5459, 5605,                                                                                                                                                                                                                                },\r
+{123, 869, -5459, 5577, 861, -5475, 5601, 873, -5471, 5613, 865, -5459, 5605, 885, -5467, 5609, 885, -5463, 5637, 877, -5503, 5621, 869, -5487, 5613, 873, -5491, 5605, 865, -5475, 5609, 861, -5467, 5597, 869, -5487, 5581, 861, -5463, 5617, 877, -5479, 5625, 889, -5479, 5617, 901, -5431, 5613, 901, -5467, 5689, 873, -5555, 5609, 837, -5451, 5613, 841, -5423, 5637, 865, -5431, 5625, 869, -5471, 5589, 845, -5495, 5617, 857, -5467, 5641, 873, -5455, 5613, 869, -5459, 5633, 865, -5443, 5625, 869, -5415, 5625, 917, -5363, 5689, 901, -5591, 5645, 861, -5615, 5513, 805, -5431, 5609, 813, -5387, 5625, 869, -5423, 5629, 861, -5487, 5617, 849, -5503, 5585, 881, -5495, 5613, 865, -5459, 5629, 853, -5435, 5645, 853, -5451, 5649, 853, -5439, 5629, 865, -5419, 5621, 861, -5419, 5625, 865, -5447, 5637, 861, -5487, 5637, 841, -5519, 5609, 865, -5499, 5609, 873, -5467, 5637, 877, -5435, 5661, 893, -5463, 5641, 869, -5475, 5637, 877, -5447, 5665, 865, -5439, 5669, 857, -5455, 5669, 833, -5419, 5625, 849, -5355, 5617, 833, -5439, 5649, 861, -5463, 5641, 841, -5523, 5637, 837, -5455, 5589, 845, -5423, 5641, 841, -5439, 5629, 833, -5471, 5597, 821, -5479, 5601, 825, -5463, 5585, 821, -5459, 5625, 825, -5451, 5617, 865, -5435, 5645, 861, -5427, 5657, 841, -5419, 5649, 857, -5435, 5645, 861, -5451, 5649, 853, -5467, 5641, 841, -5455, 5645, 841, -5435, 5637, 817, -5447, 5629, 821, -5467, 5621, 825, -5455, 5621, 829, -5447, 5629, 841, -5439, 5613, 837, -5447, 5617, 845, -5451, 5649, 849, -5447, 5653, 869, -5443, 5673, 845, -5439, 5681, 857, -5439, 5665, 833, -5423, 5645, 821, -5419, 5653, 829, -5423, 5657, 825, -5439, 5633, 833, -5483, 5625, 841, -5463, 5629, 849, -5467, 5621, 849, -5455, 5625, 825, -5451, 5641, 825, -5439, 5625, 817, -5419, 5657, 817, -5419, 5673, 829, -5423, 5673, 845, -5447, 5641, 829, -5455, 5649, 801, -5439, 5641, 821, -5435, 5641, 817, -5439, 5645, 813, -5455, 5645, 825, -5495, 5645, 841, -5467, 5657, 849, -5447, 5641, 821, -5443, 5641, 809, -5431, 5641, 793, -5443, 5661, 801, -5455, 5625, 797, -5435, 5625, 801, -5455, 5613, 789, -5459, 5649, 809, -5451, 5641, 817, -5423, 5633, 825, -5399, 5649, 821, -5427, 5677, 829, -5455, 5665, 829, -5459, 5657, 821, -5447, 5661, 833, -5427, 5633,                                                                                                                                                                                                                                                                },\r
+{126, 805, -5415, 5633, 773, -5435, 5641, 785, -5419, 5637, 801, -5407, 5661, 809, -5427, 5637, 757, -5439, 5641, 797, -5427, 5649, 801, -5427, 5661, 837, -5415, 5661, 841, -5423, 5653, 833, -5423, 5669, 833, -5475, 5653, 821, -5463, 5641, 833, -5455, 5653, 813, -5455, 5665, 829, -5431, 5677, 821, -5435, 5661, 813, -5407, 5661, 793, -5427, 5657, 821, -5439, 5657, 829, -5443, 5649, 817, -5415, 5669, 849, -5447, 5685, 837, -5455, 5633, 833, -5439, 5621, 801, -5407, 5633, 801, -5383, 5629, 801, -5427, 5673, 857, -5351, 5649, 813, -5511, 5757, 753, -5603, 5513, 757, -5395, 5597, 741, -5363, 5649, 809, -5411, 5617, 849, -5507, 5633, 845, -5495, 5629, 837, -5463, 5641, 837, -5423, 5653, 837, -5403, 5665, 845, -5431, 5689, 821, -5459, 5641, 833, -5459, 5645, 805, -5423, 5649, 789, -5407, 5653, 793, -5435, 5645, 809, -5451, 5641, 833, -5451, 5645, 829, -5459, 5653, 825, -5459, 5665, 841, -5447, 5673, 849, -5427, 5669, 825, -5435, 5661, 821, -5435, 5641, 805, -5419, 5645, 809, -5431, 5629, 793, -5443, 5637, 793, -5427, 5613, 813, -5427, 5637, 817, -5451, 5645, 813, -5423, 5625, 821, -5443, 5625, 817, -5415, 5641, 841, -5423, 5673, 833, -5479, 5645, 805, -5467, 5641, 801, -5447, 5641, 797, -5419, 5649, 805, -5415, 5645, 785, -5435, 5629, 797, -5443, 5641, 833, -5455, 5641, 849, -5435, 5629, 833, -5439, 5637, 825, -5431, 5641, 837, -5427, 5669, 829, -5439, 5653, 829, -5423, 5637, 821, -5431, 5653, 801, -5435, 5653, 817, -5427, 5661, 821, -5423, 5649, 833, -5435, 5649, 821, -5443, 5653, 825, -5443, 5645, 821, -5435, 5649, 833, -5443, 5633, 837, -5451, 5637, 825, -5455, 5657, 829, -5439, 5673, 829, -5467, 5645, 837, -5459, 5645, 845, -5443, 5629, 825, -5427, 5629, 809, -5435, 5633, 825, -5435, 5621, 805, -5439, 5637, 809, -5431, 5629, 797, -5431, 5653, 805, -5463, 5645, 817, -5459, 5621, 829, -5463, 5637, 809, -5447, 5645, 829, -5439, 5641, 817, -5455, 5633, 849, -5435, 5613, 841, -5455, 5657, 837, -5415, 5645, 825, -5419, 5677, 853, -5419, 5665, 845, -5427, 5665, 857, -5431, 5657, 849, -5447, 5641, 829, -5443, 5625, 817, -5455, 5641, 829, -5467, 5609, 821, -5443, 5613, 837, -5427, 5629, 837, -5447, 5645, 837, -5451, 5653, 837, -5451, 5665, 825, -5423, 5657, 837, -5431, 5657, 817, -5431, 5641, 809, -5451, 5625, 817, -5459, 5621, 829, -5451, 5633,                                                                                                                                                                },\r
+{124, 833, -5443, 5645, 837, -5439, 5641, 853, -5463, 5629, 841, -5451, 5625, 853, -5435, 5649, 821, -5451, 5649, 821, -5431, 5665, 849, -5439, 5661, 849, -5419, 5649, 833, -5427, 5637, 813, -5459, 5617, 805, -5471, 5621, 829, -5435, 5629, 849, -5447, 5645, 853, -5443, 5669, 853, -5467, 5661, 869, -5443, 5649, 877, -5427, 5645, 873, -5443, 5653, 837, -5423, 5649, 829, -5407, 5669, 845, -5419, 5653, 837, -5431, 5649, 849, -5443, 5633, 837, -5471, 5625, 849, -5435, 5625, 849, -5451, 5637, 837, -5419, 5641, 841, -5427, 5641, 825, -5447, 5637, 853, -5451, 5649, 865, -5459, 5665, 865, -5459, 5657, 861, -5455, 5637, 841, -5435, 5633, 853, -5427, 5645, 845, -5447, 5649, 841, -5451, 5633, 849, -5459, 5621, 849, -5459, 5625, 857, -5459, 5637, 861, -5439, 5629, 833, -5439, 5637, 845, -5439, 5641, 853, -5415, 5633, 857, -5415, 5633, 829, -5435, 5641, 829, -5479, 5661, 853, -5487, 5657, 885, -5455, 5609, 865, -5427, 5609, 845, -5419, 5613, 837, -5435, 5633, 853, -5479, 5617, 873, -5487, 5633, 873, -5491, 5665, 881, -5463, 5641, 853, -5439, 5633, 857, -5403, 5609, 817, -5403, 5669, 825, -5411, 5649, 865, -5451, 5645, 873, -5487, 5645, 877, -5499, 5621, 857, -5467, 5617, 857, -5439, 5617, 849, -5439, 5613, 857, -5459, 5629, 853, -5475, 5669, 897, -5479, 5645, 889, -5475, 5641, 861, -5479, 5613, 845, -5459, 5625, 845, -5431, 5637, 845, -5431, 5613, 845, -5447, 5613, 865, -5447, 5625, 865, -5455, 5629, 861, -5475, 5629, 853, -5455, 5621, 865, -5467, 5629, 853, -5459, 5601, 849, -5463, 5637, 853, -5447, 5641, 873, -5451, 5641, 877, -5463, 5633, 881, -5463, 5625, 841, -5455, 5625, 845, -5459, 5621, 841, -5455, 5633, 837, -5463, 5609, 849, -5471, 5613, 853, -5463, 5621, 853, -5451, 5637, 873, -5435, 5649, 869, -5451, 5649, 849, -5451, 5621, 845, -5447, 5645, 849, -5447, 5617, 845, -5447, 5625, 845, -5451, 5629, 853, -5447, 5641, 853, -5459, 5637, 861, -5447, 5641, 857, -5435, 5653, 849, -5435, 5641, 861, -5435, 5673, 845, -5467, 5669, 853, -5451, 5649, 837, -5443, 5649, 833, -5427, 5649, 845, -5427, 5645, 853, -5435, 5637, 825, -5435, 5625, 833, -5431, 5633, 829, -5451, 5633, 849, -5463, 5637, 833, -5443, 5637, 841, -5443, 5609, 813, -5431, 5625, 833, -5435, 5625, 805, -5443, 5641, 809, -5407, 5641, 813, -5443, 5653,                                                                                                                                                                                                                                },\r
+{124, 833, -5455, 5645, 841, -5447, 5637, 869, -5459, 5633, 813, -5439, 5657, 833, -5415, 5657, 837, -5419, 5645, 853, -5463, 5673, 845, -5479, 5649, 841, -5455, 5653, 841, -5431, 5629, 813, -5427, 5625, 805, -5427, 5637, 809, -5431, 5641, 829, -5447, 5657, 821, -5443, 5657, 833, -5435, 5665, 845, -5443, 5649, 833, -5451, 5629, 857, -5443, 5633, 837, -5435, 5649, 821, -5427, 5645, 829, -5431, 5649, 817, -5439, 5641, 817, -5435, 5649, 809, -5443, 5637, 809, -5423, 5637, 825, -5419, 5625, 813, -5411, 5665, 809, -5415, 5665, 825, -5423, 5653, 861, -5439, 5645, 857, -5459, 5645, 837, -5467, 5641, 789, -5471, 5637, 809, -5455, 5633, 845, -5435, 5657, 833, -5455, 5653, 817, -5487, 5633, 841, -5471, 5637, 825, -5443, 5653, 825, -5395, 5669, 825, -5403, 5649, 821, -5435, 5657, 821, -5455, 5661, 825, -5467, 5637, 829, -5435, 5621, 821, -5407, 5629, 821, -5427, 5621, 813, -5451, 5617, 805, -5467, 5629, 821, -5443, 5641, 821, -5455, 5621, 821, -5447, 5645, 829, -5443, 5649, 833, -5439, 5653, 821, -5443, 5653, 813, -5443, 5637, 809, -5447, 5637, 813, -5459, 5645, 821, -5463, 5649, 805, -5443, 5633, 837, -5427, 5629, 825, -5443, 5653, 829, -5463, 5645, 825, -5447, 5641, 837, -5427, 5661, 829, -5431, 5661, 833, -5423, 5641, 825, -5439, 5637, 817, -5455, 5657, 833, -5463, 5645, 813, -5467, 5645, 813, -5443, 5669, 813, -5447, 5661, 833, -5423, 5681, 817, -5435, 5645, 845, -5419, 5657, 809, -5415, 5653, 805, -5419, 5645, 801, -5439, 5637, 801, -5439, 5641, 797, -5439, 5629, 805, -5439, 5645, 789, -5463, 5641, 833, -5459, 5613, 825, -5463, 5633, 809, -5423, 5661, 805, -5427, 5665, 809, -5435, 5645, 801, -5423, 5629, 817, -5435, 5649, 829, -5435, 5665, 841, -5451, 5645, 829, -5443, 5673, 817, -5431, 5649, 805, -5435, 5649, 809, -5447, 5641, 809, -5427, 5637, 801, -5423, 5649, 793, -5435, 5641, 797, -5427, 5637, 813, -5427, 5665, 821, -5407, 5649, 817, -5407, 5649, 813, -5431, 5669, 821, -5419, 5653, 837, -5439, 5661, 825, -5439, 5645, 805, -5435, 5645, 793, -5439, 5649, 813, -5427, 5665, 817, -5435, 5657, 805, -5407, 5657, 797, -5439, 5645, 801, -5435, 5633, 809, -5427, 5637, 797, -5419, 5653, 801, -5399, 5661, 809, -5403, 5669, 817, -5403, 5673, 825, -5419, 5661, 829, -5439, 5649, 813, -5447, 5637, 797, -5435, 5629,                                                                                                                                                                                                                                },\r
+{124, 793, -5435, 5645, 801, -5455, 5645, 825, -5467, 5677, 825, -5443, 5669, 849, -5435, 5649, 817, -5435, 5649, 817, -5435, 5641, 829, -5435, 5653, 817, -5427, 5657, 813, -5435, 5629, 837, -5439, 5653, 849, -5443, 5653, 837, -5435, 5641, 849, -5419, 5633, 833, -5443, 5625, 797, -5447, 5633, 817, -5427, 5629, 809, -5415, 5621, 817, -5431, 5653, 821, -5431, 5653, 841, -5455, 5649, 849, -5455, 5641, 833, -5463, 5617, 825, -5427, 5637, 829, -5447, 5633, 849, -5447, 5649, 837, -5443, 5669, 841, -5463, 5641, 853, -5451, 5657, 853, -5451, 5649, 841, -5427, 5649, 825, -5443, 5649, 833, -5443, 5625, 849, -5431, 5625, 833, -5463, 5637, 845, -5455, 5633, 861, -5471, 5621, 841, -5451, 5613, 865, -5459, 5621, 853, -5459, 5637, 849, -5475, 5641, 849, -5455, 5645, 869, -5451, 5629, 853, -5443, 5649, 865, -5455, 5637, 845, -5463, 5629, 825, -5463, 5625, 837, -5439, 5633, 833, -5443, 5601, 821, -5463, 5621, 857, -5471, 5605, 833, -5467, 5605, 853, -5439, 5629, 857, -5451, 5621, 857, -5455, 5617, 861, -5459, 5637, 861, -5455, 5645, 853, -5467, 5629, 877, -5463, 5629, 845, -5479, 5617, 857, -5471, 5617, 857, -5447, 5597, 841, -5455, 5601, 849, -5475, 5621, 857, -5471, 5629, 877, -5479, 5629, 869, -5463, 5625, 873, -5443, 5625, 865, -5447, 5661, 853, -5447, 5653, 861, -5443, 5633, 857, -5459, 5629, 857, -5467, 5625, 869, -5483, 5605, 857, -5495, 5597, 861, -5475, 5593, 845, -5447, 5605, 853, -5459, 5613, 853, -5467, 5621, 865, -5459, 5617, 869, -5459, 5637, 857, -5471, 5641, 849, -5459, 5617, 861, -5459, 5613, 853, -5463, 5609, 869, -5463, 5625, 853, -5447, 5629, 857, -5447, 5637, 881, -5463, 5633, 873, -5471, 5645, 849, -5475, 5621, 845, -5479, 5613, 865, -5475, 5613, 861, -5475, 5645, 877, -5471, 5613, 861, -5475, 5617, 849, -5463, 5609, 857, -5483, 5605, 873, -5475, 5593, 861, -5475, 5601, 857, -5463, 5621, 877, -5475, 5613, 873, -5467, 5613, 885, -5463, 5633, 893, -5459, 5621, 861, -5459, 5617, 857, -5455, 5613, 861, -5459, 5621, 861, -5471, 5597, 857, -5463, 5581, 857, -5483, 5601, 845, -5471, 5593, 861, -5471, 5617, 861, -5463, 5597, 861, -5447, 5601, 877, -5471, 5637, 885, -5507, 5633, 877, -5483, 5621, 885, -5455, 5605, 873, -5471, 5605, 869, -5487, 5601, 853, -5483, 5601, 845, -5471, 5581, 845, -5447, 5605,                                                                                                                                                                                                                                },\r
+{125, 849, -5459, 5617, 889, -5495, 5613, 877, -5483, 5613, 885, -5487, 5629, 885, -5471, 5633, 873, -5467, 5613, 861, -5475, 5605, 861, -5471, 5625, 857, -5463, 5625, 873, -5455, 5617, 877, -5475, 5605, 873, -5463, 5629, 861, -5475, 5597, 869, -5471, 5589, 873, -5479, 5601, 877, -5455, 5605, 881, -5475, 5613, 889, -5487, 5605, 881, -5515, 5589, 861, -5499, 5585, 849, -5471, 5617, 845, -5471, 5609, 845, -5455, 5609, 845, -5483, 5601, 857, -5495, 5601, 865, -5475, 5605, 885, -5483, 5605, 889, -5471, 5589, 893, -5479, 5601, 877, -5499, 5601, 881, -5483, 5621, 873, -5475, 5621, 853, -5467, 5601, 877, -5487, 5621, 869, -5483, 5617, 877, -5479, 5593, 877, -5471, 5585, 857, -5463, 5609, 857, -5459, 5621, 881, -5471, 5617, 877, -5475, 5625, 885, -5483, 5605, 873, -5495, 5609, 873, -5495, 5589, 857, -5463, 5597, 857, -5483, 5577, 869, -5487, 5577, 877, -5495, 5605, 877, -5483, 5597, 857, -5499, 5601, 865, -5495, 5613, 857, -5475, 5617, 837, -5463, 5605, 885, -5467, 5597, 873, -5463, 5617, 873, -5467, 5621, 885, -5479, 5609, 889, -5491, 5605, 869, -5467, 5601, 865, -5471, 5617, 881, -5503, 5613, 897, -5499, 5605, 881, -5499, 5605, 881, -5483, 5617, 869, -5471, 5613, 869, -5471, 5585, 869, -5471, 5593, 849, -5487, 5609, 853, -5495, 5601, 885, -5475, 5601, 905, -5483, 5621, 893, -5475, 5609, 889, -5459, 5621, 881, -5475, 5625, 881, -5479, 5581, 865, -5467, 5577, 837, -5463, 5573, 833, -5479, 5577, 857, -5459, 5601, 857, -5487, 5585, 877, -5487, 5593, 873, -5499, 5605, 905, -5483, 5613, 869, -5467, 5621, 885, -5487, 5601, 877, -5499, 5601, 861, -5503, 5593, 865, -5475, 5601, 865, -5479, 5581, 865, -5467, 5597, 857, -5491, 5605, 865, -5479, 5609, 885, -5467, 5609, 881, -5475, 5617, 901, -5467, 5605, 885, -5487, 5621, 889, -5495, 5617, 889, -5511, 5605, 873, -5483, 5605, 857, -5463, 5617, 861, -5467, 5609, 885, -5483, 5609, 869, -5491, 5613, 889, -5483, 5593, 885, -5479, 5613, 881, -5471, 5613, 865, -5479, 5625, 873, -5475, 5609, 889, -5471, 5597, 857, -5471, 5593, 861, -5455, 5593, 869, -5471, 5601, 857, -5499, 5609, 881, -5483, 5601, 877, -5475, 5597, 877, -5483, 5581, 869, -5495, 5601, 869, -5507, 5617, 865, -5495, 5589, 873, -5487, 5585, 845, -5499, 5605, 853, -5483, 5617, 869, -5459, 5609, 877, -5475, 5585, 857, -5471, 5613,                                                                                                                                                                                                },\r
+{124, 885, -5471, 5633, 893, -5483, 5633, 873, -5503, 5609, 881, -5483, 5609, 873, -5467, 5585, 849, -5463, 5597, 825, -5451, 5589, 845, -5475, 5601, 873, -5499, 5593, 885, -5511, 5593, 869, -5483, 5589, 885, -5451, 5589, 869, -5459, 5613, 869, -5475, 5633, 881, -5459, 5621, 877, -5463, 5629, 885, -5487, 5621, 873, -5507, 5605, 845, -5483, 5581, 845, -5459, 5589, 841, -5439, 5605, 865, -5451, 5613, 857, -5455, 5621, 889, -5491, 5617, 889, -5491, 5633, 873, -5499, 5617, 881, -5479, 5589, 861, -5487, 5601, 853, -5467, 5625, 865, -5475, 5625, 869, -5467, 5613, 861, -5483, 5613, 861, -5511, 5597, 869, -5475, 5609, 857, -5455, 5617, 881, -5475, 5593, 893, -5495, 5613, 869, -5475, 5605, 873, -5459, 5585, 849, -5487, 5601, 865, -5467, 5605, 885, -5487, 5577, 845, -5491, 5573, 841, -5467, 5585, 837, -5451, 5613, 841, -5467, 5605, 865, -5463, 5601, 889, -5471, 5617, 877, -5487, 5625, 885, -5487, 5637, 873, -5487, 5601, 865, -5491, 5593, 861, -5475, 5589, 841, -5479, 5609, 841, -5475, 5601, 841, -5499, 5609, 869, -5487, 5597, 885, -5475, 5605, 881, -5451, 5621, 873, -5459, 5645, 877, -5463, 5629, 865, -5467, 5617, 873, -5483, 5621, 885, -5475, 5609, 877, -5475, 5629, 869, -5499, 5589, 869, -5479, 5565, 845, -5475, 5605, 837, -5455, 5637, 861, -5467, 5625, 873, -5475, 5613, 869, -5451, 5641, 869, -5451, 5613, 857, -5459, 5617, 865, -5447, 5633, 861, -5483, 5613, 853, -5475, 5617, 869, -5491, 5593, 877, -5503, 5589, 865, -5499, 5601, 853, -5487, 5601, 865, -5483, 5593, 861, -5467, 5609, 857, -5471, 5621, 861, -5479, 5613, 865, -5487, 5617, 869, -5487, 5621, 869, -5467, 5605, 849, -5479, 5617, 841, -5467, 5641, 873, -5463, 5613, 865, -5467, 5609, 849, -5483, 5605, 849, -5475, 5613, 857, -5487, 5593, 841, -5495, 5601, 857, -5463, 5621, 857, -5463, 5609, 861, -5459, 5605, 861, -5463, 5609, 877, -5471, 5621, 869, -5459, 5625, 885, -5491, 5617, 857, -5487, 5589, 849, -5467, 5601, 853, -5467, 5597, 829, -5455, 5605, 829, -5471, 5601, 849, -5491, 5609, 845, -5475, 5613, 877, -5471, 5633, 881, -5479, 5613, 865, -5455, 5629, 853, -5443, 5601, 845, -5439, 5601, 845, -5463, 5617, 853, -5499, 5609, 861, -5507, 5601, 881, -5495, 5605, 857, -5491, 5593, 861, -5467, 5609, 873, -5455, 5609, 865, -5463, 5617, 861, -5487, 5621,                                                                                                                                                                                                                                },\r
+{124, 869, -5483, 5637, 861, -5479, 5637, 877, -5463, 5629, 877, -5471, 5617, 857, -5467, 5601, 853, -5471, 5605, 849, -5479, 5597, 865, -5459, 5589, 849, -5467, 5593, 877, -5475, 5597, 861, -5471, 5581, 833, -5459, 5601, 861, -5451, 5597, 873, -5455, 5625, 885, -5471, 5601, 857, -5479, 5617, 869, -5487, 5629, 881, -5503, 5605, 857, -5471, 5601, 857, -5475, 5605, 865, -5479, 5601, 853, -5475, 5617, 853, -5487, 5609, 853, -5475, 5609, 873, -5479, 5613, 877, -5455, 5617, 861, -5459, 5625, 881, -5471, 5625, 865, -5475, 5637, 873, -5451, 5585, 853, -5447, 5581, 841, -5459, 5625, 853, -5491, 5629, 881, -5507, 5597, 869, -5463, 5597, 853, -5419, 5605, 853, -5443, 5621, 865, -5463, 5637, 853, -5483, 5609, 877, -5467, 5593, 873, -5459, 5621, 853, -5475, 5621, 853, -5471, 5605, 869, -5479, 5609, 857, -5463, 5601, 861, -5479, 5613, 853, -5487, 5613, 853, -5491, 5601, 881, -5487, 5617, 889, -5479, 5585, 889, -5467, 5609, 857, -5503, 5601, 865, -5499, 5617, 845, -5487, 5609, 861, -5467, 5597, 853, -5463, 5605, 861, -5483, 5637, 861, -5479, 5621, 877, -5475, 5613, 877, -5483, 5621, 861, -5467, 5597, 861, -5455, 5593, 837, -5459, 5605, 849, -5471, 5597, 869, -5483, 5601, 865, -5479, 5589, 853, -5491, 5577, 841, -5475, 5601, 861, -5455, 5593, 865, -5451, 5621, 873, -5467, 5605, 881, -5487, 5617, 869, -5475, 5617, 861, -5455, 5617, 841, -5467, 5605, 837, -5455, 5613, 837, -5467, 5609, 869, -5463, 5605, 857, -5467, 5613, 881, -5475, 5617, 881, -5471, 5625, 873, -5479, 5621, 849, -5479, 5617, 853, -5467, 5609, 865, -5475, 5617, 881, -5491, 5609, 885, -5511, 5597, 873, -5503, 5605, 849, -5491, 5617, 841, -5459, 5621, 841, -5451, 5617, 833, -5451, 5613, 857, -5483, 5617, 893, -5511, 5613, 905, -5483, 5573, 861, -5479, 5601, 865, -5479, 5613, 865, -5471, 5609, 865, -5467, 5633, 873, -5455, 5605, 841, -5463, 5609, 817, -5467, 5593, 841, -5455, 5601, 841, -5455, 5621, 849, -5467, 5593, 857, -5487, 5597, 869, -5487, 5585, 885, -5479, 5593, 885, -5491, 5605, 885, -5479, 5629, 869, -5467, 5621, 857, -5463, 5625, 825, -5471, 5609, 825, -5475, 5593, 845, -5475, 5613, 849, -5439, 5609, 853, -5443, 5613, 841, -5467, 5617, 873, -5483, 5629, 897, -5463, 5629, 873, -5467, 5613, 881, -5467, 5629, 865, -5483, 5613, 861, -5491, 5637,                                                                                                                                                                                                                                },\r
+{124, 861, -5467, 5633, 861, -5471, 5617, 845, -5467, 5593, 833, -5455, 5601, 829, -5475, 5597, 849, -5455, 5605, 853, -5463, 5609, 849, -5471, 5613, 869, -5491, 5609, 873, -5499, 5633, 865, -5483, 5617, 857, -5487, 5609, 841, -5455, 5605, 809, -5443, 5617, 837, -5467, 5617, 845, -5495, 5597, 869, -5495, 5597, 841, -5475, 5593, 857, -5467, 5601, 865, -5487, 5617, 873, -5487, 5621, 869, -5475, 5641, 865, -5467, 5621, 869, -5463, 5637, 845, -5471, 5641, 849, -5459, 5621, 861, -5467, 5605, 833, -5451, 5597, 845, -5447, 5585, 849, -5459, 5605, 837, -5495, 5601, 865, -5499, 5605, 869, -5499, 5613, 873, -5483, 5613, 861, -5479, 5613, 845, -5459, 5605, 845, -5459, 5613, 865, -5455, 5625, 873, -5447, 5629, 845, -5467, 5633, 857, -5475, 5633, 833, -5483, 5601, 853, -5487, 5617, 837, -5487, 5605, 857, -5459, 5613, 865, -5455, 5613, 873, -5451, 5637, 873, -5455, 5625, 853, -5487, 5605, 841, -5491, 5601, 829, -5475, 5617, 853, -5475, 5617, 861, -5479, 5625, 865, -5499, 5637, 881, -5475, 5617, 865, -5479, 5605, 837, -5463, 5617, 841, -5483, 5609, 853, -5471, 5621, 853, -5459, 5621, 857, -5455, 5605, 845, -5455, 5621, 857, -5451, 5605, 853, -5479, 5605, 849, -5475, 5613, 857, -5475, 5601, 861, -5467, 5601, 833, -5443, 5625, 821, -5451, 5617, 825, -5459, 5617, 853, -5495, 5613, 869, -5487, 5597, 869, -5471, 5601, 849, -5483, 5581, 833, -5471, 5597, 837, -5467, 5617, 849, -5467, 5617, 857, -5475, 5617, 857, -5471, 5629, 853, -5475, 5605, 861, -5459, 5633, 865, -5447, 5617, 853, -5459, 5613, 861, -5455, 5617, 841, -5463, 5613, 833, -5459, 5613, 841, -5463, 5617, 841, -5475, 5633, 853, -5475, 5617, 849, -5479, 5593, 853, -5467, 5605, 837, -5455, 5629, 857, -5451, 5625, 853, -5463, 5613, 853, -5463, 5625, 857, -5479, 5621, 857, -5463, 5601, 849, -5447, 5613, 857, -5459, 5637, 837, -5463, 5605, 817, -5451, 5621, 809, -5459, 5621, 833, -5475, 5621, 873, -5479, 5613, 869, -5479, 5605, 861, -5471, 5629, 837, -5471, 5625, 857, -5475, 5613, 869, -5475, 5605, 873, -5479, 5613, 857, -5479, 5621, 853, -5475, 5601, 861, -5483, 5629, 853, -5467, 5621, 837, -5451, 5613, 837, -5455, 5613, 837, -5467, 5617, 833, -5463, 5641, 833, -5463, 5641, 865, -5483, 5617, 881, -5467, 5629, 865, -5467, 5605, 829, -5463, 5605, 825, -5483, 5601,                                                                                                                                                                                                                                },\r
+{125, 845, -5467, 5621, 853, -5459, 5605, 865, -5443, 5617, 865, -5459, 5617, 841, -5451, 5621, 841, -5451, 5613, 837, -5459, 5605, 849, -5471, 5617, 845, -5507, 5601, 853, -5499, 5613, 873, -5483, 5613, 853, -5451, 5621, 853, -5451, 5617, 845, -5455, 5625, 853, -5467, 5625, 849, -5459, 5629, 853, -5479, 5613, 833, -5491, 5617, 837, -5483, 5593, 861, -5459, 5609, 869, -5459, 5637, 849, -5467, 5613, 865, -5475, 5605, 861, -5495, 5601, 845, -5467, 5617, 849, -5475, 5629, 861, -5483, 5609, 861, -5475, 5613, 881, -5463, 5625, 849, -5447, 5629, 845, -5463, 5605, 845, -5475, 5597, 841, -5451, 5597, 845, -5451, 5597, 845, -5475, 5605, 849, -5467, 5597, 861, -5491, 5629, 869, -5483, 5617, 849, -5483, 5601, 881, -5475, 5609, 857, -5483, 5625, 869, -5467, 5613, 861, -5471, 5613, 841, -5463, 5613, 829, -5467, 5589, 813, -5491, 5625, 857, -5455, 5609, 873, -5451, 5649, 885, -5451, 5641, 865, -5459, 5633, 861, -5467, 5645, 881, -5483, 5617, 861, -5491, 5605, 861, -5471, 5609, 849, -5471, 5601, 861, -5483, 5605, 845, -5471, 5593, 861, -5459, 5621, 849, -5447, 5625, 825, -5455, 5633, 845, -5451, 5629, 877, -5451, 5649, 873, -5447, 5625, 857, -5463, 5633, 861, -5471, 5597, 861, -5495, 5609, 849, -5487, 5581, 837, -5471, 5609, 833, -5471, 5605, 861, -5475, 5609, 849, -5483, 5625, 849, -5479, 5621, 857, -5475, 5605, 853, -5447, 5605, 861, -5443, 5617, 853, -5455, 5629, 845, -5455, 5601, 849, -5467, 5617, 837, -5479, 5597, 829, -5491, 5613, 857, -5483, 5605, 865, -5475, 5609, 861, -5455, 5613, 849, -5463, 5625, 865, -5475, 5617, 853, -5483, 5609, 845, -5475, 5641, 833, -5451, 5609, 857, -5471, 5637, 857, -5475, 5621, 857, -5475, 5613, 869, -5463, 5605, 869, -5475, 5621, 857, -5483, 5613, 837, -5459, 5613, 865, -5467, 5613, 841, -5471, 5625, 857, -5467, 5621, 845, -5471, 5597, 849, -5467, 5613, 845, -5459, 5617, 845, -5443, 5625, 849, -5435, 5637, 885, -5431, 5641, 865, -5435, 5633, 861, -5487, 5629, 833, -5503, 5613, 825, -5495, 5585, 821, -5463, 5617, 849, -5467, 5613, 853, -5463, 5633, 873, -5455, 5625, 873, -5475, 5633, 833, -5479, 5633, 829, -5479, 5613, 833, -5455, 5625, 829, -5459, 5617, 821, -5439, 5621, 841, -5439, 5629, 845, -5443, 5625, 849, -5463, 5641, 853, -5447, 5629, 841, -5443, 5621, 845, -5451, 5613, 829, -5439, 5605,                                                                                                                                                                                                },\r
+{123, 821, -5435, 5609, 837, -5451, 5625, 861, -5463, 5613, 853, -5503, 5629, 845, -5483, 5617, 853, -5479, 5613, 845, -5451, 5609, 853, -5463, 5621, 825, -5471, 5641, 825, -5475, 5653, 825, -5443, 5665, 841, -5447, 5637, 841, -5471, 5633, 869, -5459, 5637, 853, -5451, 5625, 825, -5439, 5609, 829, -5439, 5617, 845, -5459, 5613, 837, -5487, 5629, 841, -5475, 5633, 833, -5467, 5641, 845, -5443, 5653, 825, -5439, 5649, 841, -5419, 5629, 837, -5435, 5629, 837, -5455, 5609, 833, -5455, 5617, 821, -5451, 5629, 821, -5447, 5637, 833, -5435, 5637, 849, -5471, 5633, 825, -5459, 5625, 825, -5459, 5633, 829, -5455, 5621, 801, -5455, 5629, 821, -5463, 5613, 833, -5459, 5625, 829, -5455, 5629, 845, -5459, 5621, 845, -5467, 5637, 833, -5467, 5641, 853, -5451, 5657, 833, -5451, 5661, 837, -5447, 5649, 833, -5439, 5637, 845, -5447, 5657, 837, -5475, 5625, 829, -5459, 5637, 825, -5459, 5621, 825, -5435, 5641, 813, -5439, 5645, 829, -5459, 5633, 849, -5451, 5625, 837, -5435, 5629, 809, -5451, 5621, 821, -5467, 5645, 825, -5443, 5653, 829, -5439, 5633, 837, -5427, 5641, 817, -5407, 5641, 817, -5423, 5653, 825, -5447, 5637, 809, -5443, 5621, 793, -5443, 5621, 801, -5451, 5637, 817, -5427, 5645, 825, -5459, 5649, 837, -5459, 5649, 845, -5467, 5641, 829, -5475, 5649, 813, -5471, 5633, 809, -5451, 5637, 805, -5447, 5633, 813, -5447, 5633, 817, -5451, 5629, 805, -5459, 5657, 805, -5463, 5649, 813, -5451, 5649, 813, -5423, 5641, 825, -5423, 5665, 821, -5423, 5661, 801, -5423, 5633, 813, -5443, 5637, 797, -5451, 5621, 785, -5435, 5621, 789, -5439, 5625, 785, -5447, 5641, 801, -5451, 5613, 809, -5459, 5637, 813, -5443, 5629, 809, -5435, 5669, 797, -5411, 5669, 825, -5423, 5665, 821, -5435, 5677, 789, -5443, 5677, 789, -5423, 5645, 789, -5443, 5633, 781, -5451, 5641, 805, -5447, 5633, 805, -5447, 5629, 813, -5447, 5633, 825, -5447, 5645, 821, -5455, 5625, 809, -5427, 5661, 801, -5411, 5669, 797, -5415, 5677, 813, -5415, 5673, 801, -5431, 5665, 797, -5427, 5653, 805, -5447, 5629, 809, -5443, 5661, 777, -5431, 5637, 773, -5443, 5629, 777, -5455, 5625, 777, -5443, 5633, 797, -5415, 5633, 805, -5423, 5665, 797, -5423, 5665, 793, -5403, 5673, 793, -5411, 5673, 813, -5423, 5689, 793, -5443, 5661, 809, -5467, 5641,                                                                                                                                                                                                                                                                },\r
+{124, 793, -5443, 5645, 789, -5447, 5629, 769, -5447, 5629, 777, -5447, 5665, 789, -5431, 5661, 801, -5435, 5661, 813, -5447, 5669, 809, -5423, 5685, 801, -5427, 5653, 801, -5419, 5653, 805, -5423, 5633, 789, -5427, 5641, 781, -5443, 5657, 781, -5431, 5649, 793, -5439, 5653, 797, -5467, 5625, 793, -5463, 5645, 785, -5411, 5649, 793, -5419, 5649, 773, -5423, 5653, 793, -5439, 5649, 809, -5435, 5645, 801, -5415, 5665, 785, -5419, 5641, 765, -5403, 5661, 793, -5411, 5681, 825, -5423, 5669, 825, -5443, 5665, 821, -5455, 5661, 813, -5475, 5653, 805, -5471, 5633, 805, -5471, 5621, 793, -5459, 5645, 781, -5431, 5649, 801, -5427, 5661, 789, -5407, 5673, 793, -5415, 5661, 781, -5427, 5665, 789, -5439, 5653, 785, -5435, 5649, 805, -5423, 5657, 801, -5395, 5657, 793, -5423, 5637, 801, -5435, 5641, 793, -5443, 5637, 777, -5443, 5645, 801, -5427, 5649, 789, -5447, 5649, 797, -5435, 5649, 789, -5419, 5633, 789, -5443, 5653, 777, -5415, 5641, 773, -5451, 5669, 797, -5451, 5665, 789, -5427, 5657, 813, -5419, 5673, 825, -5431, 5653, 817, -5455, 5669, 789, -5447, 5665, 789, -5427, 5649, 789, -5423, 5661, 797, -5411, 5661, 817, -5411, 5681, 797, -5427, 5665, 769, -5419, 5665, 781, -5435, 5665, 789, -5431, 5665, 809, -5423, 5665, 813, -5439, 5677, 837, -5419, 5685, 809, -5415, 5677, 789, -5399, 5661, 793, -5423, 5673, 781, -5439, 5641, 789, -5439, 5633, 769, -5451, 5649, 789, -5423, 5653, 809, -5407, 5665, 797, -5407, 5657, 789, -5435, 5657, 801, -5435, 5645, 797, -5439, 5637, 793, -5431, 5641, 769, -5423, 5661, 789, -5427, 5633, 777, -5439, 5637, 789, -5463, 5653, 805, -5479, 5653, 797, -5463, 5645, 817, -5431, 5653, 813, -5411, 5685, 793, -5403, 5673, 793, -5431, 5657, 797, -5443, 5657, 793, -5431, 5637, 797, -5427, 5657, 789, -5419, 5633, 781, -5415, 5653, 809, -5463, 5645, 781, -5455, 5637, 797, -5439, 5641, 817, -5439, 5641, 821, -5443, 5661, 809, -5443, 5657, 789, -5435, 5645, 805, -5427, 5649, 805, -5423, 5645, 785, -5411, 5661, 789, -5415, 5649, 789, -5435, 5665, 797, -5427, 5657, 809, -5427, 5645, 805, -5463, 5657, 821, -5475, 5645, 821, -5451, 5645, 821, -5463, 5633, 825, -5475, 5633, 801, -5447, 5649, 793, -5447, 5629, 813, -5451, 5645, 817, -5451, 5653, 841, -5451, 5649, 833, -5451, 5661, 841, -5443, 5645,                                                                                                                                                                                                                                },\r
+{126, 825, -5467, 5641, 829, -5451, 5649, 821, -5435, 5653, 825, -5439, 5617, 793, -5443, 5609, 813, -5451, 5641, 801, -5447, 5621, 805, -5451, 5589, 813, -5471, 5629, 805, -5447, 5629, 817, -5455, 5653, 817, -5439, 5649, 853, -5467, 5633, 841, -5479, 5645, 813, -5479, 5645, 813, -5463, 5633, 809, -5451, 5621, 805, -5459, 5649, 797, -5447, 5649, 825, -5439, 5633, 841, -5467, 5645, 821, -5459, 5637, 833, -5439, 5653, 809, -5451, 5657, 825, -5471, 5633, 857, -5443, 5633, 853, -5427, 5629, 825, -5423, 5617, 837, -5435, 5613, 821, -5467, 5621, 829, -5447, 5633, 825, -5455, 5625, 825, -5431, 5637, 821, -5443, 5637, 841, -5459, 5681, 837, -5451, 5653, 821, -5443, 5637, 825, -5451, 5657, 813, -5455, 5649, 821, -5451, 5625, 841, -5459, 5617, 845, -5479, 5613, 841, -5463, 5633, 837, -5447, 5633, 833, -5459, 5629, 825, -5455, 5621, 817, -5467, 5653, 825, -5451, 5637, 829, -5443, 5649, 829, -5447, 5649, 853, -5455, 5661, 833, -5463, 5641, 829, -5455, 5645, 825, -5439, 5613, 837, -5431, 5641, 813, -5459, 5629, 817, -5443, 5633, 845, -5463, 5641, 833, -5459, 5605, 829, -5443, 5621, 833, -5447, 5629, 813, -5463, 5617, 837, -5435, 5629, 813, -5427, 5613, 821, -5443, 5617, 829, -5467, 5641, 853, -5471, 5653, 833, -5475, 5605, 801, -5467, 5621, 813, -5463, 5653, 829, -5455, 5613, 845, -5439, 5621, 829, -5447, 5649, 833, -5439, 5637, 845, -5423, 5633, 837, -5459, 5617, 833, -5479, 5637, 829, -5459, 5621, 813, -5463, 5633, 813, -5475, 5637, 837, -5471, 5625, 853, -5463, 5613, 857, -5475, 5641, 825, -5479, 5637, 833, -5467, 5645, 833, -5451, 5633, 833, -5447, 5633, 837, -5423, 5625, 845, -5443, 5629, 845, -5483, 5637, 845, -5467, 5621, 837, -5459, 5597, 841, -5451, 5577, 817, -5435, 5601, 825, -5463, 5613, 829, -5447, 5617, 829, -5451, 5621, 837, -5439, 5613, 829, -5451, 5645, 821, -5483, 5621, 841, -5491, 5613, 837, -5463, 5609, 837, -5455, 5629, 837, -5467, 5633, 829, -5487, 5625, 833, -5475, 5613, 829, -5495, 5605, 853, -5467, 5633, 865, -5463, 5609, 845, -5471, 5617, 853, -5479, 5613, 849, -5471, 5609, 825, -5471, 5609, 833, -5459, 5617, 853, -5455, 5641, 865, -5455, 5633, 877, -5471, 5629, 853, -5479, 5605, 845, -5467, 5609, 841, -5455, 5589, 841, -5483, 5621, 849, -5459, 5609, 857, -5459, 5613, 857, -5491, 5617, 861, -5479, 5613, 861, -5447, 5621,                                                                                                                                                                },\r
+{124, 837, -5443, 5625, 841, -5475, 5609, 833, -5459, 5593, 833, -5463, 5613, 837, -5459, 5625, 845, -5463, 5605, 857, -5451, 5613, 881, -5475, 5633, 901, -5519, 5609, 889, -5527, 5605, 885, -5487, 5609, 893, -5471, 5609, 861, -5479, 5617, 849, -5475, 5621, 829, -5491, 5609, 829, -5491, 5609, 845, -5495, 5597, 853, -5455, 5605, 853, -5483, 5625, 881, -5471, 5593, 873, -5471, 5593, 853, -5487, 5609, 845, -5479, 5621, 849, -5471, 5633, 853, -5467, 5617, 869, -5499, 5617, 861, -5483, 5589, 857, -5463, 5601, 821, -5479, 5585, 817, -5467, 5593, 841, -5459, 5597, 861, -5455, 5609, 873, -5483, 5609, 885, -5479, 5621, 833, -5467, 5605, 833, -5455, 5641, 853, -5463, 5621, 849, -5459, 5609, 841, -5451, 5597, 833, -5467, 5613, 813, -5479, 5601, 857, -5491, 5601, 857, -5491, 5621, 857, -5467, 5609, 873, -5475, 5597, 893, -5487, 5625, 909, -5503, 5613, 897, -5491, 5625, 849, -5483, 5613, 849, -5475, 5617, 849, -5467, 5597, 833, -5463, 5601, 841, -5459, 5609, 825, -5443, 5609, 821, -5459, 5593, 845, -5479, 5597, 857, -5463, 5609, 877, -5475, 5633, 893, -5463, 5605, 889, -5451, 5629, 857, -5479, 5633, 857, -5483, 5621, 853, -5483, 5609, 833, -5471, 5601, 841, -5487, 5585, 821, -5483, 5601, 813, -5463, 5589, 813, -5475, 5609, 853, -5475, 5605, 865, -5463, 5609, 885, -5463, 5621, 885, -5479, 5613, 881, -5495, 5609, 865, -5475, 5605, 853, -5463, 5609, 849, -5463, 5613, 857, -5479, 5609, 833, -5467, 5605, 829, -5467, 5617, 837, -5459, 5629, 833, -5483, 5625, 845, -5479, 5605, 865, -5483, 5617, 865, -5475, 5645, 869, -5459, 5609, 837, -5471, 5625, 841, -5467, 5629, 825, -5459, 5605, 809, -5471, 5617, 841, -5467, 5625, 845, -5483, 5597, 853, -5455, 5601, 849, -5443, 5613, 837, -5479, 5617, 845, -5475, 5605, 865, -5467, 5601, 869, -5475, 5625, 861, -5471, 5621, 833, -5455, 5621, 837, -5463, 5605, 837, -5447, 5613, 841, -5459, 5613, 845, -5487, 5613, 833, -5483, 5613, 849, -5467, 5613, 829, -5479, 5609, 833, -5467, 5625, 837, -5455, 5617, 845, -5455, 5625, 865, -5467, 5609, 837, -5491, 5601, 837, -5463, 5613, 845, -5459, 5621, 849, -5451, 5613, 829, -5443, 5617, 821, -5471, 5605, 857, -5455, 5589, 861, -5463, 5601, 837, -5475, 5609, 825, -5487, 5613, 853, -5503, 5601, 841, -5487, 5589, 821, -5471, 5613, 837, -5447, 5629,                                                                                                                                                                                                                                },\r
+{125, 841, -5435, 5629, 857, -5439, 5633, 857, -5447, 5625, 861, -5471, 5625, 869, -5467, 5617, 845, -5475, 5617, 849, -5491, 5609, 841, -5491, 5601, 853, -5491, 5605, 853, -5471, 5605, 845, -5455, 5593, 841, -5467, 5605, 857, -5471, 5609, 845, -5483, 5613, 857, -5467, 5601, 865, -5471, 5629, 869, -5483, 5645, 873, -5499, 5637, 877, -5475, 5605, 865, -5471, 5585, 813, -5459, 5573, 833, -5471, 5573, 825, -5487, 5581, 845, -5479, 5585, 853, -5487, 5589, 849, -5471, 5601, 869, -5455, 5625, 849, -5483, 5625, 861, -5491, 5621, 857, -5479, 5609, 861, -5483, 5609, 845, -5479, 5601, 845, -5495, 5589, 861, -5479, 5605, 857, -5483, 5609, 845, -5499, 5589, 849, -5471, 5613, 841, -5471, 5609, 849, -5491, 5593, 857, -5499, 5613, 881, -5475, 5629, 869, -5443, 5621, 865, -5447, 5641, 861, -5479, 5633, 869, -5499, 5621, 873, -5487, 5625, 865, -5495, 5605, 841, -5483, 5593, 837, -5499, 5609, 853, -5487, 5601, 849, -5475, 5593, 841, -5463, 5609, 849, -5459, 5613, 841, -5455, 5601, 865, -5495, 5613, 853, -5491, 5601, 849, -5459, 5581, 833, -5467, 5609, 841, -5487, 5605, 857, -5495, 5617, 865, -5479, 5613, 877, -5487, 5605, 853, -5479, 5605, 845, -5475, 5597, 845, -5487, 5605, 849, -5463, 5617, 845, -5463, 5617, 853, -5471, 5629, 861, -5499, 5605, 845, -5491, 5613, 845, -5479, 5613, 841, -5467, 5617, 841, -5471, 5589, 853, -5475, 5609, 841, -5487, 5617, 869, -5451, 5605, 853, -5467, 5597, 845, -5479, 5609, 841, -5471, 5617, 849, -5471, 5637, 849, -5467, 5605, 857, -5479, 5625, 849, -5487, 5621, 841, -5467, 5609, 833, -5475, 5625, 829, -5455, 5609, 817, -5471, 5605, 853, -5463, 5629, 861, -5455, 5617, 869, -5471, 5609, 857, -5451, 5621, 857, -5463, 5625, 837, -5435, 5649, 865, -5447, 5609, 841, -5471, 5613, 841, -5499, 5617, 853, -5515, 5613, 861, -5507, 5613, 849, -5479, 5629, 857, -5483, 5621, 853, -5471, 5633, 857, -5467, 5629, 849, -5471, 5617, 845, -5471, 5621, 837, -5459, 5625, 845, -5459, 5621, 845, -5459, 5613, 849, -5455, 5601, 845, -5455, 5589, 865, -5475, 5601, 825, -5467, 5589, 829, -5455, 5601, 833, -5459, 5625, 837, -5479, 5613, 849, -5475, 5617, 841, -5479, 5601, 845, -5475, 5609, 821, -5467, 5613, 833, -5463, 5621, 845, -5487, 5621, 841, -5479, 5605, 845, -5459, 5601, 857, -5463, 5609, 841, -5463, 5613, 829, -5475, 5605,                                                                                                                                                                                                },\r
+{126, 837, -5483, 5621, 841, -5467, 5617, 861, -5455, 5625, 885, -5455, 5641, 837, -5459, 5641, 829, -5451, 5629, 845, -5471, 5629, 849, -5467, 5621, 829, -5459, 5625, 829, -5475, 5617, 833, -5487, 5621, 825, -5471, 5633, 821, -5451, 5625, 837, -5427, 5633, 837, -5435, 5621, 821, -5459, 5637, 833, -5459, 5613, 845, -5463, 5625, 829, -5471, 5633, 829, -5451, 5625, 829, -5463, 5621, 821, -5455, 5609, 829, -5475, 5617, 849, -5471, 5613, 833, -5483, 5625, 841, -5479, 5617, 841, -5467, 5625, 845, -5463, 5637, 821, -5459, 5621, 821, -5455, 5629, 813, -5459, 5629, 817, -5459, 5621, 801, -5459, 5621, 817, -5483, 5625, 829, -5471, 5625, 829, -5443, 5617, 829, -5451, 5637, 821, -5455, 5625, 825, -5443, 5609, 813, -5447, 5633, 825, -5475, 5645, 837, -5471, 5633, 837, -5447, 5625, 829, -5439, 5625, 797, -5447, 5637, 809, -5431, 5621, 781, -5451, 5609, 801, -5455, 5637, 833, -5451, 5621, 825, -5443, 5617, 801, -5459, 5645, 793, -5431, 5649, 825, -5435, 5645, 841, -5431, 5661, 829, -5431, 5669, 825, -5451, 5661, 817, -5471, 5645, 821, -5483, 5633, 809, -5463, 5621, 805, -5475, 5641, 801, -5475, 5629, 801, -5471, 5629, 801, -5447, 5637, 781, -5451, 5637, 809, -5443, 5653, 801, -5427, 5657, 813, -5431, 5673, 829, -5435, 5649, 837, -5415, 5649, 833, -5423, 5637, 817, -5439, 5621, 777, -5451, 5605, 789, -5463, 5613, 801, -5459, 5629, 809, -5459, 5633, 801, -5431, 5633, 785, -5439, 5637, 785, -5443, 5657, 801, -5431, 5641, 813, -5447, 5649, 821, -5435, 5657, 809, -5423, 5657, 805, -5431, 5665, 797, -5439, 5645, 793, -5455, 5633, 785, -5431, 5621, 801, -5459, 5649, 789, -5451, 5653, 805, -5447, 5637, 809, -5431, 5637, 817, -5427, 5661, 797, -5439, 5673, 793, -5435, 5669, 825, -5439, 5661, 825, -5447, 5657, 813, -5447, 5657, 805, -5447, 5661, 805, -5455, 5641, 793, -5439, 5633, 805, -5431, 5629, 797, -5419, 5637, 809, -5431, 5641, 797, -5447, 5653, 813, -5443, 5645, 777, -5435, 5645, 809, -5447, 5661, 789, -5435, 5633, 793, -5431, 5641, 785, -5451, 5649, 789, -5463, 5645, 793, -5455, 5621, 809, -5431, 5637, 793, -5427, 5661, 785, -5439, 5653, 809, -5455, 5641, 817, -5435, 5629, 809, -5435, 5637, 797, -5435, 5653, 805, -5451, 5661, 813, -5455, 5653, 813, -5443, 5637, 809, -5431, 5633, 789, -5419, 5653, 797, -5451, 5657, 817, -5463, 5649, 833, -5439, 5633,                                                                                                                                                                },\r
+{125, 809, -5435, 5633, 789, -5455, 5633, 801, -5435, 5637, 821, -5443, 5657, 825, -5419, 5649, 805, -5431, 5641, 773, -5447, 5649, 777, -5459, 5669, 833, -5439, 5653, 833, -5415, 5637, 793, -5419, 5653, 797, -5423, 5649, 797, -5431, 5653, 817, -5431, 5665, 813, -5459, 5653, 805, -5475, 5641, 809, -5491, 5625, 801, -5459, 5645, 801, -5467, 5649, 817, -5463, 5633, 821, -5439, 5637, 813, -5415, 5653, 817, -5447, 5673, 817, -5467, 5653, 813, -5467, 5645, 797, -5427, 5653, 805, -5399, 5649, 813, -5415, 5657, 817, -5427, 5637, 801, -5447, 5617, 809, -5459, 5613, 793, -5451, 5617, 793, -5451, 5629, 789, -5443, 5641, 781, -5427, 5637, 793, -5423, 5641, 793, -5439, 5653, 801, -5439, 5637, 801, -5451, 5637, 805, -5447, 5637, 793, -5435, 5637, 809, -5435, 5629, 833, -5431, 5629, 805, -5427, 5657, 773, -5439, 5661, 813, -5455, 5653, 849, -5443, 5677, 849, -5447, 5665, 861, -5455, 5637, 825, -5439, 5661, 805, -5443, 5641, 817, -5439, 5633, 801, -5451, 5645, 833, -5475, 5673, 825, -5471, 5641, 813, -5459, 5641, 813, -5435, 5641, 829, -5419, 5637, 825, -5431, 5677, 829, -5439, 5641, 841, -5443, 5661, 841, -5455, 5645, 809, -5435, 5649, 821, -5451, 5625, 801, -5455, 5621, 805, -5447, 5613, 809, -5439, 5617, 817, -5439, 5625, 813, -5443, 5633, 849, -5475, 5649, 845, -5471, 5621, 837, -5459, 5617, 829, -5443, 5621, 805, -5439, 5637, 805, -5451, 5633, 809, -5443, 5645, 833, -5459, 5649, 845, -5463, 5645, 821, -5459, 5613, 833, -5459, 5633, 817, -5427, 5629, 833, -5455, 5645, 841, -5459, 5629, 841, -5455, 5629, 845, -5467, 5633, 837, -5463, 5641, 845, -5475, 5625, 841, -5483, 5617, 813, -5447, 5609, 809, -5435, 5645, 829, -5439, 5645, 841, -5451, 5633, 817, -5443, 5649, 833, -5459, 5621, 813, -5463, 5617, 829, -5455, 5617, 837, -5459, 5605, 833, -5459, 5629, 809, -5435, 5649, 825, -5411, 5621, 857, -5443, 5653, 841, -5455, 5645, 825, -5471, 5633, 829, -5459, 5629, 845, -5455, 5617, 861, -5475, 5633, 841, -5491, 5637, 825, -5467, 5613, 841, -5459, 5609, 825, -5467, 5621, 837, -5463, 5633, 833, -5479, 5641, 849, -5471, 5629, 869, -5471, 5625, 833, -5463, 5633, 817, -5459, 5621, 841, -5435, 5629, 845, -5439, 5633, 841, -5435, 5605, 845, -5443, 5613, 825, -5491, 5621, 837, -5475, 5605, 837, -5455, 5593, 833, -5439, 5617, 825, -5431, 5605,                                                                                                                                                                                                },\r
+{124, 845, -5443, 5629, 849, -5479, 5633, 873, -5495, 5633, 849, -5483, 5641, 841, -5463, 5629, 845, -5471, 5617, 821, -5471, 5633, 837, -5463, 5625, 845, -5483, 5609, 845, -5459, 5597, 821, -5451, 5629, 833, -5471, 5633, 849, -5447, 5629, 857, -5451, 5649, 877, -5463, 5629, 857, -5471, 5629, 837, -5475, 5629, 845, -5467, 5613, 837, -5463, 5589, 829, -5455, 5621, 821, -5471, 5625, 861, -5463, 5625, 881, -5467, 5629, 849, -5471, 5625, 837, -5463, 5621, 853, -5459, 5629, 849, -5443, 5625, 853, -5451, 5625, 845, -5451, 5629, 825, -5463, 5605, 825, -5471, 5605, 813, -5471, 5613, 821, -5487, 5597, 853, -5483, 5593, 853, -5463, 5605, 861, -5475, 5605, 849, -5459, 5633, 861, -5483, 5633, 861, -5471, 5613, 849, -5451, 5625, 833, -5471, 5629, 821, -5487, 5629, 849, -5495, 5601, 869, -5471, 5601, 825, -5467, 5601, 845, -5471, 5633, 861, -5471, 5605, 853, -5463, 5601, 873, -5451, 5609, 877, -5455, 5645, 849, -5471, 5621, 853, -5455, 5613, 853, -5463, 5609, 853, -5451, 5621, 841, -5471, 5605, 837, -5479, 5597, 857, -5491, 5613, 861, -5487, 5577, 853, -5483, 5593, 877, -5475, 5585, 841, -5463, 5605, 845, -5475, 5617, 809, -5475, 5597, 849, -5463, 5621, 841, -5471, 5637, 845, -5455, 5653, 853, -5447, 5605, 865, -5439, 5609, 845, -5455, 5613, 829, -5483, 5613, 825, -5507, 5601, 857, -5495, 5585, 857, -5491, 5609, 865, -5475, 5617, 861, -5471, 5641, 837, -5447, 5637, 853, -5451, 5629, 869, -5471, 5609, 857, -5475, 5633, 849, -5499, 5589, 845, -5495, 5585, 837, -5463, 5621, 853, -5439, 5617, 853, -5447, 5617, 877, -5483, 5609, 853, -5479, 5585, 841, -5467, 5609, 849, -5467, 5601, 841, -5459, 5601, 853, -5483, 5593, 853, -5467, 5609, 845, -5447, 5605, 861, -5451, 5597, 845, -5471, 5597, 841, -5499, 5601, 841, -5491, 5621, 849, -5479, 5601, 833, -5479, 5581, 841, -5467, 5605, 849, -5467, 5625, 869, -5475, 5625, 861, -5467, 5601, 845, -5459, 5613, 833, -5455, 5621, 841, -5463, 5621, 853, -5491, 5597, 865, -5471, 5601, 845, -5455, 5617, 845, -5471, 5621, 853, -5475, 5617, 857, -5475, 5625, 849, -5463, 5613, 849, -5467, 5625, 861, -5479, 5617, 861, -5479, 5605, 833, -5459, 5617, 849, -5459, 5609, 853, -5479, 5613, 857, -5463, 5589, 841, -5451, 5597, 825, -5483, 5637, 853, -5487, 5621, 865, -5475, 5597, 841, -5487, 5601,                                                                                                                                                                                                                                },\r
+{125, 853, -5459, 5609, 833, -5451, 5601, 837, -5467, 5593, 837, -5479, 5621, 865, -5475, 5605, 853, -5467, 5589, 853, -5483, 5605, 857, -5483, 5617, 849, -5487, 5621, 833, -5479, 5613, 849, -5467, 5617, 853, -5479, 5633, 849, -5479, 5613, 853, -5483, 5605, 853, -5475, 5593, 829, -5471, 5581, 833, -5467, 5593, 817, -5475, 5617, 841, -5455, 5625, 845, -5463, 5625, 869, -5459, 5597, 853, -5463, 5605, 861, -5475, 5613, 853, -5471, 5609, 853, -5475, 5613, 849, -5483, 5609, 841, -5471, 5621, 857, -5459, 5605, 865, -5447, 5601, 857, -5455, 5625, 833, -5491, 5605, 845, -5499, 5605, 845, -5487, 5613, 857, -5487, 5617, 849, -5483, 5629, 861, -5459, 5641, 869, -5463, 5633, 869, -5447, 5625, 841, -5459, 5617, 829, -5479, 5593, 813, -5507, 5597, 845, -5491, 5609, 845, -5479, 5609, 865, -5467, 5605, 861, -5483, 5609, 873, -5443, 5609, 861, -5455, 5613, 853, -5475, 5621, 849, -5487, 5621, 845, -5483, 5601, 841, -5483, 5605, 825, -5479, 5621, 833, -5475, 5621, 857, -5455, 5601, 885, -5463, 5581, 861, -5467, 5601, 853, -5483, 5621, 845, -5483, 5601, 845, -5483, 5593, 825, -5471, 5609, 841, -5475, 5589, 833, -5455, 5605, 833, -5471, 5605, 853, -5471, 5605, 861, -5475, 5605, 849, -5487, 5621, 845, -5495, 5613, 857, -5479, 5617, 873, -5471, 5613, 857, -5459, 5597, 857, -5455, 5605, 853, -5475, 5605, 837, -5487, 5613, 849, -5471, 5613, 837, -5467, 5621, 849, -5475, 5617, 849, -5467, 5613, 841, -5479, 5617, 857, -5475, 5609, 853, -5459, 5613, 845, -5451, 5629, 869, -5487, 5629, 837, -5487, 5613, 861, -5479, 5629, 861, -5463, 5617, 849, -5467, 5601, 857, -5463, 5589, 857, -5459, 5597, 845, -5463, 5621, 833, -5459, 5617, 853, -5491, 5605, 849, -5475, 5613, 857, -5471, 5605, 833, -5467, 5605, 849, -5471, 5585, 849, -5439, 5609, 849, -5451, 5629, 853, -5483, 5625, 845, -5491, 5593, 857, -5487, 5605, 865, -5499, 5617, 853, -5487, 5609, 845, -5459, 5605, 837, -5491, 5597, 837, -5483, 5617, 849, -5483, 5613, 877, -5471, 5613, 853, -5479, 5609, 869, -5463, 5617, 857, -5471, 5621, 837, -5455, 5613, 845, -5455, 5609, 825, -5467, 5613, 853, -5479, 5617, 865, -5483, 5609, 837, -5491, 5585, 841, -5483, 5585, 833, -5495, 5593, 845, -5475, 5613, 849, -5471, 5625, 861, -5471, 5637, 849, -5483, 5621, 873, -5471, 5625, 861, -5471, 5609, 829, -5463, 5613,                                                                                                                                                                                                },\r
+{125, 833, -5475, 5609, 841, -5483, 5605, 837, -5495, 5601, 861, -5503, 5605, 869, -5499, 5597, 861, -5471, 5605, 857, -5475, 5617, 869, -5451, 5605, 845, -5455, 5629, 837, -5447, 5625, 837, -5487, 5629, 817, -5503, 5609, 853, -5495, 5621, 861, -5487, 5593, 845, -5491, 5589, 849, -5487, 5605, 861, -5475, 5613, 865, -5459, 5609, 873, -5491, 5629, 877, -5503, 5637, 849, -5479, 5629, 853, -5455, 5613, 841, -5467, 5593, 829, -5451, 5597, 821, -5459, 5601, 833, -5463, 5593, 829, -5479, 5597, 853, -5479, 5585, 861, -5479, 5609, 837, -5487, 5601, 849, -5471, 5621, 845, -5447, 5625, 865, -5463, 5641, 853, -5479, 5609, 841, -5479, 5597, 857, -5471, 5589, 857, -5479, 5605, 849, -5491, 5605, 845, -5475, 5609, 841, -5463, 5621, 837, -5479, 5617, 857, -5495, 5597, 857, -5475, 5617, 841, -5459, 5621, 853, -5455, 5625, 861, -5459, 5609, 857, -5455, 5609, 845, -5455, 5625, 861, -5471, 5629, 857, -5487, 5597, 877, -5487, 5625, 869, -5503, 5589, 857, -5475, 5629, 833, -5455, 5629, 841, -5455, 5621, 833, -5459, 5613, 837, -5475, 5597, 821, -5479, 5605, 829, -5467, 5613, 845, -5483, 5601, 841, -5491, 5609, 841, -5479, 5625, 853, -5471, 5605, 849, -5459, 5601, 857, -5463, 5601, 845, -5479, 5601, 845, -5499, 5593, 849, -5507, 5605, 837, -5475, 5597, 857, -5479, 5601, 853, -5471, 5621, 845, -5467, 5609, 857, -5483, 5621, 849, -5499, 5621, 849, -5487, 5609, 837, -5467, 5605, 829, -5471, 5605, 861, -5479, 5601, 861, -5479, 5593, 853, -5459, 5601, 829, -5459, 5613, 845, -5475, 5641, 849, -5479, 5625, 885, -5451, 5601, 873, -5451, 5621, 857, -5471, 5613, 817, -5475, 5609, 849, -5491, 5617, 833, -5459, 5613, 845, -5471, 5625, 837, -5487, 5617, 845, -5471, 5609, 853, -5451, 5601, 845, -5459, 5613, 845, -5467, 5609, 829, -5475, 5617, 829, -5483, 5637, 841, -5483, 5637, 837, -5487, 5617, 833, -5455, 5609, 829, -5435, 5621, 841, -5431, 5637, 845, -5443, 5637, 845, -5451, 5625, 837, -5459, 5621, 829, -5487, 5621, 825, -5487, 5633, 833, -5487, 5637, 817, -5459, 5621, 821, -5471, 5617, 833, -5451, 5629, 841, -5459, 5637, 837, -5459, 5629, 829, -5471, 5645, 849, -5483, 5637, 845, -5455, 5633, 845, -5447, 5629, 809, -5439, 5617, 785, -5431, 5621, 821, -5451, 5621, 849, -5447, 5621, 833, -5439, 5629, 829, -5443, 5613, 825, -5459, 5625, 809, -5455, 5645,                                                                                                                                                                                                },\r
+{124, 813, -5459, 5645, 825, -5467, 5645, 833, -5463, 5641, 817, -5451, 5629, 825, -5431, 5629, 829, -5439, 5637, 829, -5435, 5617, 825, -5447, 5653, 801, -5487, 5625, 801, -5447, 5605, 825, -5415, 5689, 825, -5463, 5657, 853, -5399, 5621, 825, -5427, 5709, 821, -5423, 5657, 797, -5387, 5717, 817, -5451, 5621, 821, -5515, 5601, 789, -5539, 5601, 801, -5459, 5601, 809, -5431, 5613, 809, -5423, 5633, 793, -5431, 5665, 829, -5439, 5645, 829, -5443, 5693, 825, -5447, 5645, 817, -5359, 5657, 749, -5475, 5673, 749, -5459, 5605, 777, -5411, 5633, 793, -5415, 5625, 809, -5447, 5629, 809, -5487, 5625, 809, -5499, 5625, 809, -5467, 5641, 805, -5411, 5649, 797, -5407, 5669, 769, -5419, 5665, 793, -5419, 5665, 781, -5439, 5653, 797, -5431, 5653, 777, -5439, 5657, 769, -5431, 5645, 797, -5419, 5645, 773, -5419, 5657, 777, -5423, 5649, 809, -5423, 5657, 793, -5431, 5693, 797, -5467, 5669, 797, -5467, 5633, 769, -5419, 5649, 753, -5387, 5673, 761, -5419, 5649, 773, -5427, 5673, 793, -5387, 5673, 801, -5411, 5709, 797, -5471, 5641, 773, -5463, 5629, 761, -5419, 5665, 769, -5403, 5641, 777, -5419, 5621, 773, -5439, 5633, 781, -5427, 5653, 781, -5419, 5645, 773, -5411, 5685, 765, -5391, 5689, 777, -5411, 5697, 745, -5427, 5669, 765, -5415, 5709, 785, -5427, 5693, 785, -5447, 5653, 785, -5475, 5633, 765, -5463, 5629, 777, -5455, 5649, 777, -5459, 5657, 789, -5443, 5669, 785, -5439, 5653, 777, -5391, 5681, 789, -5387, 5689, 777, -5399, 5677, 785, -5411, 5661, 781, -5423, 5689, 785, -5419, 5665, 805, -5443, 5637, 785, -5451, 5637, 773, -5427, 5641, 761, -5443, 5613, 761, -5427, 5629, 777, -5451, 5669, 773, -5447, 5673, 801, -5439, 5677, 801, -5411, 5665, 745, -5399, 5677, 757, -5415, 5661, 777, -5435, 5673, 781, -5431, 5661, 769, -5443, 5653, 769, -5459, 5653, 785, -5475, 5653, 793, -5467, 5645, 785, -5431, 5653, 793, -5395, 5669, 793, -5423, 5669, 789, -5423, 5693, 781, -5427, 5677, 785, -5427, 5669, 781, -5427, 5657, 777, -5447, 5685, 753, -5423, 5669, 785, -5423, 5653, 785, -5423, 5641, 797, -5415, 5649, 781, -5427, 5645, 769, -5447, 5645, 769, -5435, 5653, 769, -5423, 5661, 765, -5419, 5661, 773, -5419, 5649, 765, -5391, 5665, 765, -5391, 5677, 797, -5419, 5649, 789, -5419, 5653, 785, -5447, 5653, 793, -5431, 5677,                                                                                                                                                                                                                                },\r
+{124, 785, -5447, 5677, 777, -5443, 5661, 777, -5447, 5661, 789, -5431, 5673, 785, -5427, 5649, 777, -5427, 5661, 769, -5435, 5649, 777, -5415, 5641, 765, -5427, 5665, 773, -5431, 5677, 781, -5423, 5685, 801, -5435, 5673, 789, -5415, 5665, 785, -5431, 5673, 777, -5423, 5661, 781, -5427, 5641, 765, -5415, 5649, 753, -5415, 5653, 761, -5431, 5641, 769, -5423, 5661, 817, -5423, 5657, 813, -5427, 5657, 809, -5447, 5657, 777, -5423, 5657, 765, -5411, 5653, 761, -5423, 5653, 761, -5435, 5641, 765, -5439, 5665, 765, -5411, 5673, 785, -5419, 5677, 805, -5411, 5665, 809, -5423, 5681, 801, -5463, 5669, 801, -5475, 5673, 809, -5479, 5657, 793, -5471, 5661, 793, -5459, 5665, 793, -5447, 5661, 773, -5459, 5661, 793, -5439, 5653, 777, -5435, 5645, 773, -5427, 5641, 793, -5431, 5649, 801, -5435, 5661, 805, -5415, 5673, 797, -5411, 5665, 809, -5419, 5657, 801, -5423, 5641, 785, -5415, 5633, 789, -5439, 5645, 773, -5459, 5637, 769, -5439, 5633, 769, -5443, 5625, 773, -5435, 5665, 781, -5435, 5653, 813, -5435, 5653, 789, -5427, 5665, 785, -5427, 5665, 805, -5439, 5653, 809, -5435, 5641, 789, -5443, 5645, 801, -5443, 5665, 801, -5459, 5641, 777, -5447, 5645, 801, -5419, 5641, 797, -5415, 5657, 781, -5415, 5677, 813, -5435, 5649, 805, -5443, 5653, 789, -5427, 5645, 777, -5443, 5661, 789, -5443, 5677, 793, -5443, 5653, 801, -5439, 5649, 797, -5423, 5657, 789, -5403, 5645, 785, -5411, 5665, 801, -5423, 5665, 813, -5439, 5669, 801, -5427, 5677, 793, -5435, 5669, 797, -5443, 5649, 777, -5423, 5649, 785, -5447, 5641, 781, -5459, 5637, 789, -5447, 5645, 797, -5443, 5661, 813, -5435, 5649, 793, -5443, 5649, 769, -5435, 5657, 797, -5435, 5669, 805, -5431, 5645, 797, -5419, 5661, 825, -5439, 5669, 805, -5443, 5649, 801, -5435, 5649, 809, -5443, 5661, 797, -5435, 5649, 777, -5435, 5629, 777, -5463, 5649, 793, -5447, 5641, 797, -5423, 5653, 785, -5431, 5641, 797, -5427, 5661, 821, -5423, 5665, 821, -5447, 5661, 809, -5439, 5645, 813, -5451, 5637, 805, -5439, 5637, 785, -5439, 5637, 785, -5431, 5645, 805, -5431, 5653, 813, -5455, 5633, 785, -5455, 5633, 781, -5435, 5657, 797, -5447, 5649, 805, -5443, 5641, 809, -5407, 5665, 805, -5407, 5661, 793, -5415, 5665, 789, -5419, 5669, 817, -5451, 5653, 805, -5451, 5641, 789, -5443, 5633,                                                                                                                                                                                                                                },\r
+{125, 797, -5443, 5633, 797, -5475, 5653, 829, -5467, 5641, 805, -5467, 5665, 793, -5451, 5669, 809, -5447, 5641, 825, -5431, 5649, 801, -5455, 5653, 777, -5447, 5665, 793, -5435, 5653, 801, -5447, 5653, 813, -5431, 5633, 833, -5447, 5641, 809, -5435, 5637, 797, -5447, 5633, 801, -5435, 5617, 809, -5443, 5617, 821, -5439, 5633, 793, -5451, 5641, 797, -5451, 5637, 813, -5443, 5633, 817, -5431, 5637, 825, -5423, 5649, 825, -5431, 5661, 841, -5435, 5657, 817, -5459, 5637, 821, -5459, 5645, 809, -5447, 5649, 805, -5451, 5645, 829, -5467, 5629, 833, -5451, 5633, 813, -5435, 5649, 801, -5459, 5633, 817, -5451, 5629, 821, -5443, 5657, 833, -5431, 5657, 813, -5435, 5649, 813, -5435, 5649, 825, -5471, 5625, 821, -5451, 5633, 817, -5443, 5617, 821, -5451, 5633, 809, -5451, 5653, 833, -5451, 5653, 853, -5439, 5629, 829, -5423, 5641, 825, -5455, 5629, 841, -5471, 5621, 817, -5439, 5629, 809, -5447, 5625, 813, -5443, 5621, 801, -5435, 5637, 805, -5459, 5633, 821, -5479, 5633, 833, -5467, 5625, 837, -5455, 5617, 813, -5459, 5629, 829, -5451, 5613, 829, -5447, 5645, 821, -5479, 5637, 825, -5467, 5641, 813, -5443, 5629, 829, -5459, 5621, 841, -5475, 5633, 837, -5455, 5637, 821, -5475, 5617, 809, -5471, 5613, 833, -5467, 5613, 837, -5463, 5621, 841, -5451, 5617, 833, -5443, 5605, 821, -5463, 5613, 805, -5467, 5629, 797, -5467, 5625, 809, -5451, 5641, 841, -5459, 5629, 849, -5475, 5609, 845, -5475, 5629, 845, -5463, 5593, 833, -5463, 5609, 841, -5459, 5601, 829, -5455, 5617, 825, -5475, 5621, 833, -5463, 5617, 809, -5467, 5617, 821, -5475, 5613, 845, -5435, 5629, 857, -5423, 5621, 845, -5439, 5657, 853, -5451, 5645, 865, -5467, 5637, 821, -5475, 5629, 797, -5483, 5601, 805, -5479, 5617, 837, -5479, 5625, 845, -5475, 5633, 845, -5467, 5617, 845, -5467, 5645, 837, -5467, 5613, 825, -5467, 5633, 849, -5463, 5613, 849, -5471, 5609, 841, -5447, 5625, 845, -5459, 5629, 837, -5447, 5609, 841, -5467, 5613, 837, -5471, 5597, 821, -5467, 5613, 841, -5483, 5589, 841, -5467, 5621, 833, -5475, 5625, 817, -5459, 5605, 821, -5475, 5617, 825, -5475, 5589, 829, -5455, 5609, 829, -5471, 5637, 853, -5463, 5621, 849, -5487, 5625, 825, -5479, 5625, 837, -5491, 5605, 853, -5467, 5597, 849, -5471, 5629, 845, -5455, 5633, 845, -5463, 5617, 853, -5447, 5601,                                                                                                                                                                                                },\r
+{123, 829, -5455, 5633, 825, -5467, 5625, 849, -5471, 5641, 837, -5447, 5629, 829, -5463, 5641, 845, -5487, 5621, 829, -5471, 5613, 837, -5447, 5609, 841, -5463, 5613, 817, -5479, 5625, 849, -5475, 5629, 869, -5475, 5613, 873, -5471, 5625, 817, -5455, 5637, 821, -5459, 5605, 829, -5443, 5613, 837, -5435, 5609, 821, -5455, 5641, 837, -5463, 5605, 829, -5459, 5597, 817, -5479, 5629, 821, -5475, 5613, 841, -5471, 5625, 861, -5467, 5601, 837, -5447, 5609, 797, -5471, 5637, 825, -5479, 5633, 837, -5479, 5621, 849, -5459, 5609, 825, -5455, 5617, 801, -5471, 5633, 861, -5479, 5625, 849, -5463, 5637, 833, -5455, 5629, 833, -5475, 5641, 837, -5467, 5645, 833, -5451, 5609, 821, -5443, 5605, 797, -5447, 5613, 797, -5459, 5617, 813, -5463, 5621, 825, -5455, 5641, 849, -5463, 5625, 837, -5463, 5625, 825, -5459, 5617, 801, -5439, 5601, 845, -5443, 5613, 825, -5463, 5633, 817, -5483, 5625, 821, -5471, 5617, 813, -5467, 5617, 809, -5459, 5601, 797, -5459, 5629, 821, -5451, 5633, 841, -5451, 5649, 857, -5443, 5653, 853, -5447, 5653, 837, -5463, 5653, 817, -5459, 5621, 789, -5487, 5617, 797, -5483, 5621, 813, -5467, 5589, 829, -5471, 5605, 837, -5471, 5637, 821, -5467, 5665, 849, -5467, 5621, 849, -5459, 5641, 829, -5467, 5645, 821, -5463, 5621, 829, -5459, 5629, 841, -5463, 5637, 821, -5467, 5625, 805, -5459, 5629, 837, -5463, 5629, 845, -5459, 5609, 829, -5463, 5605, 801, -5447, 5601, 793, -5447, 5625, 825, -5443, 5605, 805, -5447, 5629, 821, -5451, 5637, 781, -5483, 5669, 873, -5475, 5581, 837, -5439, 5585, 797, -5475, 5641, 793, -5491, 5613, 821, -5495, 5625, 865, -5447, 5609, 845, -5447, 5621, 825, -5467, 5637, 817, -5455, 5653, 833, -5475, 5633, 841, -5451, 5613, 833, -5415, 5625, 813, -5447, 5637, 797, -5467, 5657, 841, -5471, 5633, 857, -5471, 5605, 837, -5467, 5613, 805, -5451, 5633, 789, -5475, 5669, 825, -5467, 5629, 849, -5447, 5617, 853, -5439, 5617, 821, -5471, 5657, 829, -5483, 5653, 829, -5471, 5621, 825, -5431, 5613, 813, -5427, 5637, 813, -5443, 5641, 825, -5463, 5613, 841, -5471, 5621, 821, -5471, 5597, 825, -5471, 5621, 837, -5475, 5625, 821, -5495, 5629, 837, -5487, 5613, 821, -5451, 5625, 813, -5451, 5617, 825, -5475, 5629, 837, -5475, 5613, 829, -5463, 5621, 829, -5463, 5637,                                                                                                                                                                                                                                                                },\r
+{124, 833, -5451, 5641, 829, -5487, 5629, 833, -5483, 5629, 845, -5459, 5625, 821, -5459, 5617, 825, -5471, 5629, 821, -5475, 5625, 837, -5447, 5617, 829, -5447, 5625, 825, -5463, 5625, 821, -5475, 5633, 829, -5463, 5633, 829, -5479, 5625, 821, -5463, 5609, 829, -5471, 5625, 849, -5479, 5637, 837, -5467, 5617, 829, -5439, 5605, 837, -5447, 5621, 817, -5483, 5617, 817, -5487, 5605, 821, -5471, 5597, 829, -5467, 5613, 861, -5475, 5613, 853, -5471, 5645, 857, -5455, 5649, 845, -5451, 5641, 837, -5451, 5625, 817, -5447, 5625, 805, -5479, 5629, 817, -5495, 5641, 837, -5499, 5621, 849, -5487, 5613, 849, -5463, 5609, 829, -5455, 5621, 821, -5459, 5625, 825, -5463, 5629, 837, -5471, 5617, 869, -5475, 5629, 849, -5459, 5645, 833, -5467, 5633, 833, -5463, 5625, 809, -5471, 5605, 821, -5443, 5629, 821, -5463, 5617, 809, -5479, 5609, 825, -5475, 5621, 809, -5463, 5601, 833, -5459, 5597, 845, -5459, 5601, 829, -5451, 5613, 825, -5455, 5617, 833, -5471, 5629, 849, -5467, 5625, 841, -5459, 5633, 825, -5467, 5613, 821, -5467, 5609, 825, -5479, 5605, 813, -5467, 5597, 833, -5483, 5609, 829, -5451, 5617, 833, -5455, 5645, 849, -5459, 5649, 837, -5447, 5649, 853, -5459, 5637, 841, -5459, 5637, 817, -5463, 5629, 809, -5459, 5625, 817, -5463, 5617, 825, -5483, 5605, 825, -5491, 5605, 833, -5483, 5625, 849, -5471, 5617, 841, -5451, 5621, 829, -5455, 5637, 837, -5447, 5649, 841, -5435, 5613, 829, -5443, 5633, 817, -5463, 5637, 813, -5475, 5617, 817, -5447, 5609, 805, -5443, 5613, 829, -5487, 5593, 817, -5483, 5609, 849, -5491, 5609, 853, -5499, 5625, 849, -5471, 5633, 845, -5455, 5621, 829, -5455, 5621, 825, -5463, 5629, 837, -5463, 5621, 841, -5475, 5629, 829, -5467, 5617, 829, -5467, 5633, 821, -5475, 5629, 833, -5479, 5597, 825, -5463, 5609, 833, -5455, 5625, 829, -5471, 5629, 841, -5471, 5633, 837, -5463, 5633, 861, -5471, 5625, 841, -5467, 5637, 845, -5467, 5633, 821, -5463, 5605, 813, -5471, 5613, 821, -5467, 5621, 825, -5451, 5625, 837, -5479, 5633, 841, -5463, 5633, 833, -5459, 5613, 825, -5459, 5613, 833, -5463, 5617, 809, -5455, 5609, 797, -5459, 5605, 821, -5459, 5629, 829, -5451, 5657, 833, -5455, 5633, 853, -5447, 5641, 841, -5439, 5645, 833, -5435, 5649, 837, -5459, 5641, 821, -5487, 5633, 813, -5511, 5613,                                                                                                                                                                                                                                },\r
+{125, 825, -5483, 5621, 841, -5463, 5621, 817, -5455, 5609, 821, -5459, 5617, 797, -5455, 5629, 821, -5443, 5641, 821, -5455, 5645, 845, -5471, 5641, 845, -5443, 5641, 829, -5443, 5637, 829, -5451, 5625, 813, -5435, 5621, 805, -5427, 5625, 817, -5435, 5625, 801, -5447, 5625, 805, -5471, 5621, 813, -5483, 5621, 809, -5451, 5625, 793, -5447, 5613, 793, -5439, 5637, 809, -5451, 5669, 817, -5463, 5645, 837, -5459, 5665, 837, -5467, 5641, 849, -5483, 5621, 805, -5447, 5625, 789, -5435, 5629, 797, -5455, 5629, 813, -5463, 5617, 801, -5463, 5641, 817, -5455, 5633, 841, -5467, 5625, 829, -5439, 5629, 825, -5463, 5637, 817, -5451, 5645, 813, -5447, 5629, 817, -5447, 5657, 813, -5459, 5645, 817, -5455, 5645, 817, -5459, 5645, 817, -5455, 5633, 793, -5439, 5637, 813, -5423, 5621, 805, -5427, 5637, 789, -5451, 5641, 817, -5455, 5641, 813, -5455, 5637, 805, -5443, 5645, 817, -5443, 5637, 809, -5423, 5637, 805, -5423, 5661, 813, -5459, 5661, 805, -5471, 5629, 805, -5463, 5621, 789, -5455, 5633, 805, -5459, 5637, 793, -5439, 5641, 797, -5427, 5633, 801, -5439, 5645, 809, -5451, 5653, 793, -5443, 5649, 793, -5451, 5653, 813, -5455, 5649, 793, -5427, 5653, 809, -5431, 5649, 813, -5419, 5653, 797, -5435, 5661, 801, -5435, 5629, 805, -5447, 5657, 785, -5439, 5657, 801, -5431, 5649, 793, -5427, 5645, 785, -5435, 5645, 781, -5423, 5653, 785, -5435, 5653, 781, -5443, 5661, 797, -5443, 5673, 817, -5439, 5665, 793, -5427, 5653, 785, -5411, 5657, 777, -5415, 5649, 773, -5423, 5661, 781, -5411, 5669, 801, -5435, 5669, 817, -5455, 5645, 805, -5443, 5657, 797, -5423, 5677, 801, -5435, 5673, 789, -5455, 5677, 797, -5455, 5689, 789, -5463, 5677, 777, -5439, 5673, 777, -5443, 5673, 757, -5443, 5653, 765, -5423, 5641, 781, -5419, 5649, 761, -5435, 5645, 785, -5439, 5649, 777, -5427, 5669, 801, -5427, 5645, 793, -5403, 5657, 801, -5411, 5661, 793, -5403, 5689, 761, -5411, 5645, 765, -5427, 5665, 765, -5435, 5669, 765, -5443, 5661, 769, -5451, 5653, 761, -5431, 5645, 773, -5451, 5645, 741, -5419, 5645, 785, -5403, 5653, 777, -5427, 5665, 793, -5431, 5677, 781, -5443, 5685, 805, -5419, 5661, 765, -5415, 5677, 769, -5423, 5661, 785, -5411, 5669, 761, -5415, 5681, 793, -5423, 5669, 777, -5399, 5677, 773, -5423, 5669, 765, -5443, 5681, 761, -5447, 5673,                                                                                                                                                                                                },\r
+{124, 769, -5435, 5665, 773, -5427, 5669, 781, -5411, 5681, 761, -5415, 5677, 773, -5431, 5677, 777, -5411, 5657, 753, -5411, 5665, 733, -5407, 5673, 757, -5419, 5661, 769, -5423, 5665, 769, -5415, 5669, 757, -5403, 5681, 773, -5423, 5673, 757, -5415, 5673, 773, -5431, 5681, 757, -5407, 5673, 765, -5431, 5665, 765, -5427, 5681, 761, -5431, 5661, 749, -5423, 5669, 753, -5395, 5677, 777, -5403, 5677, 773, -5439, 5693, 781, -5423, 5697, 793, -5427, 5661, 765, -5403, 5669, 741, -5411, 5673, 753, -5419, 5677, 761, -5407, 5661, 777, -5403, 5669, 789, -5415, 5677, 773, -5419, 5673, 765, -5423, 5665, 757, -5423, 5673, 757, -5435, 5657, 765, -5415, 5661, 769, -5411, 5649, 749, -5431, 5685, 757, -5419, 5673, 777, -5403, 5665, 769, -5419, 5661, 757, -5419, 5673, 749, -5391, 5693, 757, -5387, 5681, 765, -5399, 5673, 777, -5415, 5673, 781, -5423, 5653, 781, -5435, 5669, 769, -5443, 5649, 777, -5459, 5653, 765, -5447, 5665, 773, -5431, 5685, 789, -5439, 5685, 789, -5431, 5669, 785, -5411, 5685, 785, -5403, 5681, 769, -5395, 5685, 765, -5423, 5681, 761, -5431, 5661, 765, -5411, 5649, 773, -5387, 5657, 789, -5395, 5645, 773, -5423, 5669, 789, -5423, 5649, 805, -5431, 5673, 773, -5427, 5653, 761, -5423, 5649, 761, -5415, 5665, 765, -5403, 5665, 789, -5415, 5661, 765, -5411, 5669, 781, -5431, 5685, 777, -5447, 5693, 785, -5439, 5669, 781, -5427, 5681, 785, -5423, 5677, 777, -5427, 5669, 761, -5439, 5661, 773, -5451, 5673, 785, -5427, 5673, 789, -5423, 5665, 793, -5431, 5681, 785, -5407, 5669, 785, -5403, 5633, 769, -5407, 5669, 773, -5419, 5665, 773, -5439, 5673, 797, -5451, 5689, 805, -5419, 5669, 797, -5423, 5665, 785, -5431, 5677, 773, -5415, 5661, 753, -5407, 5657, 769, -5411, 5669, 769, -5423, 5665, 765, -5435, 5653, 777, -5431, 5685, 777, -5419, 5669, 793, -5399, 5637, 769, -5407, 5649, 789, -5415, 5669, 769, -5427, 5677, 781, -5439, 5665, 781, -5443, 5645, 781, -5455, 5653, 765, -5447, 5645, 773, -5423, 5653, 769, -5411, 5657, 785, -5415, 5669, 797, -5447, 5665, 809, -5447, 5685, 797, -5439, 5681, 817, -5415, 5677, 777, -5427, 5669, 753, -5407, 5661, 737, -5415, 5665, 785, -5419, 5657, 765, -5419, 5657, 773, -5427, 5669, 789, -5467, 5661, 793, -5455, 5641, 773, -5427, 5653, 789, -5399, 5649, 785, -5407, 5677,                                                                                                                                                                                                                                },\r
+{124, 785, -5423, 5657, 781, -5439, 5657, 773, -5447, 5661, 777, -5431, 5669, 785, -5395, 5669, 773, -5399, 5665, 761, -5395, 5661, 781, -5431, 5673, 785, -5439, 5673, 801, -5427, 5673, 797, -5447, 5681, 777, -5447, 5649, 781, -5455, 5649, 761, -5435, 5665, 777, -5423, 5661, 785, -5427, 5681, 785, -5435, 5681, 805, -5431, 5677, 789, -5427, 5689, 777, -5431, 5681, 769, -5407, 5665, 765, -5419, 5661, 789, -5411, 5649, 777, -5423, 5653, 785, -5407, 5645, 777, -5411, 5653, 765, -5407, 5649, 769, -5415, 5657, 777, -5407, 5641, 781, -5423, 5649, 765, -5415, 5669, 777, -5419, 5673, 781, -5443, 5657, 793, -5431, 5657, 781, -5423, 5661, 765, -5411, 5649, 769, -5415, 5673, 777, -5419, 5669, 797, -5423, 5685, 797, -5415, 5665, 789, -5431, 5669, 797, -5431, 5701, 797, -5411, 5685, 769, -5407, 5653, 749, -5415, 5661, 769, -5391, 5677, 785, -5399, 5673, 793, -5407, 5645, 793, -5439, 5661, 789, -5427, 5665, 761, -5419, 5669, 749, -5419, 5677, 781, -5411, 5665, 777, -5407, 5665, 765, -5403, 5705, 789, -5423, 5681, 789, -5415, 5673, 777, -5403, 5645, 769, -5411, 5673, 781, -5423, 5665, 777, -5411, 5661, 777, -5415, 5657, 769, -5439, 5653, 781, -5427, 5641, 761, -5419, 5665, 769, -5411, 5645, 777, -5427, 5669, 773, -5455, 5661, 785, -5439, 5661, 777, -5439, 5645, 773, -5427, 5665, 785, -5427, 5677, 769, -5435, 5661, 789, -5431, 5673, 797, -5431, 5665, 797, -5439, 5657, 789, -5439, 5665, 765, -5431, 5665, 793, -5415, 5661, 793, -5415, 5673, 773, -5419, 5657, 785, -5419, 5657, 813, -5423, 5665, 801, -5431, 5649, 809, -5435, 5653, 801, -5411, 5665, 773, -5423, 5661, 809, -5415, 5653, 805, -5439, 5661, 801, -5439, 5633, 789, -5435, 5637, 789, -5447, 5637, 773, -5447, 5665, 801, -5443, 5673, 789, -5403, 5661, 825, -5399, 5677, 821, -5415, 5677, 809, -5415, 5657, 797, -5443, 5665, 785, -5443, 5653, 801, -5459, 5629, 797, -5439, 5649, 797, -5435, 5657, 825, -5447, 5657, 829, -5447, 5673, 845, -5431, 5673, 817, -5427, 5649, 813, -5447, 5657, 805, -5463, 5657, 813, -5447, 5657, 833, -5435, 5645, 817, -5451, 5657, 805, -5443, 5645, 801, -5451, 5641, 797, -5443, 5625, 813, -5427, 5637, 797, -5439, 5637, 801, -5451, 5625, 813, -5427, 5641, 821, -5431, 5637, 809, -5423, 5649, 813, -5427, 5653, 829, -5459, 5669, 829, -5439, 5633,                                                                                                                                                                                                                                },\r
+{125, 817, -5447, 5633, 817, -5459, 5629, 805, -5475, 5637, 825, -5455, 5641, 817, -5455, 5649, 793, -5447, 5649, 813, -5411, 5649, 833, -5427, 5645, 809, -5443, 5641, 829, -5443, 5649, 825, -5455, 5665, 817, -5443, 5657, 805, -5435, 5661, 829, -5435, 5645, 813, -5459, 5637, 809, -5475, 5625, 829, -5455, 5641, 813, -5455, 5629, 837, -5431, 5645, 833, -5423, 5657, 821, -5435, 5645, 829, -5439, 5649, 821, -5431, 5669, 825, -5423, 5665, 825, -5423, 5665, 801, -5443, 5661, 809, -5459, 5625, 837, -5459, 5629, 797, -5447, 5617, 801, -5443, 5633, 825, -5439, 5617, 805, -5447, 5625, 805, -5439, 5645, 853, -5451, 5645, 873, -5447, 5645, 841, -5435, 5665, 837, -5451, 5677, 817, -5451, 5645, 833, -5459, 5649, 829, -5451, 5637, 809, -5455, 5633, 797, -5451, 5645, 801, -5455, 5633, 809, -5455, 5641, 825, -5451, 5633, 829, -5451, 5625, 821, -5451, 5641, 805, -5435, 5657, 825, -5435, 5641, 825, -5455, 5633, 817, -5451, 5645, 817, -5443, 5637, 821, -5451, 5629, 817, -5443, 5645, 813, -5455, 5613, 805, -5467, 5625, 833, -5471, 5649, 825, -5467, 5621, 813, -5447, 5641, 821, -5439, 5657, 825, -5435, 5669, 829, -5415, 5657, 825, -5431, 5649, 837, -5455, 5645, 789, -5467, 5649, 781, -5463, 5637, 821, -5455, 5629, 809, -5463, 5641, 837, -5451, 5673, 841, -5435, 5645, 849, -5435, 5645, 845, -5447, 5629, 821, -5459, 5625, 825, -5443, 5641, 829, -5467, 5641, 825, -5455, 5645, 829, -5455, 5637, 829, -5435, 5645, 817, -5435, 5633, 801, -5443, 5613, 829, -5455, 5605, 825, -5439, 5625, 801, -5447, 5613, 813, -5451, 5625, 821, -5439, 5629, 825, -5411, 5641, 809, -5415, 5649, 813, -5459, 5665, 833, -5471, 5633, 845, -5431, 5629, 825, -5439, 5629, 801, -5463, 5633, 813, -5471, 5617, 821, -5455, 5629, 821, -5443, 5661, 837, -5435, 5645, 801, -5447, 5625, 817, -5479, 5649, 833, -5459, 5645, 821, -5459, 5645, 813, -5447, 5637, 805, -5443, 5649, 817, -5435, 5653, 829, -5435, 5645, 821, -5459, 5641, 837, -5455, 5649, 841, -5455, 5649, 821, -5467, 5661, 825, -5455, 5649, 829, -5427, 5637, 809, -5439, 5621, 825, -5455, 5629, 821, -5439, 5637, 809, -5427, 5629, 813, -5435, 5625, 817, -5427, 5653, 825, -5439, 5641, 825, -5439, 5609, 825, -5431, 5641, 825, -5455, 5653, 809, -5463, 5625, 821, -5471, 5649, 829, -5463, 5633, 809, -5447, 5633, 805, -5439, 5621,                                                                                                                                                                                                },\r
+{124, 793, -5447, 5637, 813, -5443, 5621, 833, -5459, 5657, 825, -5459, 5637, 821, -5455, 5637, 829, -5435, 5649, 821, -5439, 5661, 829, -5443, 5629, 821, -5459, 5649, 833, -5451, 5665, 809, -5443, 5633, 821, -5447, 5621, 801, -5431, 5625, 805, -5443, 5621, 817, -5463, 5625, 813, -5459, 5625, 829, -5451, 5629, 841, -5447, 5633, 829, -5435, 5625, 841, -5443, 5625, 825, -5447, 5637, 829, -5443, 5637, 817, -5447, 5629, 817, -5467, 5637, 809, -5459, 5657, 805, -5447, 5645, 805, -5435, 5645, 829, -5431, 5645, 829, -5427, 5657, 813, -5431, 5633, 813, -5463, 5649, 837, -5463, 5657, 809, -5459, 5625, 809, -5463, 5641, 833, -5463, 5629, 853, -5463, 5653, 805, -5423, 5641, 817, -5435, 5645, 817, -5463, 5645, 817, -5459, 5637, 809, -5435, 5637, 821, -5451, 5625, 837, -5455, 5625, 837, -5447, 5629, 825, -5435, 5617, 821, -5439, 5633, 821, -5451, 5633, 817, -5459, 5633, 817, -5435, 5641, 813, -5411, 5633, 813, -5439, 5641, 813, -5435, 5637, 829, -5443, 5629, 817, -5467, 5621, 821, -5479, 5645, 829, -5471, 5637, 829, -5451, 5629, 825, -5451, 5645, 821, -5451, 5649, 825, -5431, 5633, 829, -5447, 5653, 801, -5431, 5649, 797, -5435, 5637, 801, -5435, 5645, 829, -5447, 5657, 829, -5451, 5645, 829, -5451, 5621, 821, -5459, 5645, 821, -5475, 5625, 809, -5447, 5637, 829, -5431, 5653, 809, -5427, 5645, 797, -5447, 5645, 813, -5435, 5629, 805, -5451, 5645, 817, -5459, 5653, 829, -5443, 5661, 829, -5423, 5649, 829, -5427, 5641, 805, -5439, 5645, 793, -5431, 5645, 805, -5427, 5657, 801, -5451, 5649, 805, -5459, 5625, 825, -5463, 5629, 813, -5447, 5629, 809, -5435, 5629, 789, -5447, 5641, 817, -5463, 5641, 817, -5455, 5645, 817, -5451, 5629, 809, -5463, 5633, 797, -5435, 5653, 809, -5451, 5653, 809, -5447, 5641, 789, -5439, 5649, 813, -5451, 5645, 801, -5451, 5637, 821, -5459, 5645, 837, -5455, 5645, 829, -5431, 5641, 813, -5435, 5661, 813, -5431, 5665, 813, -5419, 5657, 825, -5451, 5653, 813, -5447, 5637, 801, -5443, 5645, 809, -5443, 5641, 817, -5443, 5649, 809, -5447, 5653, 809, -5451, 5645, 833, -5447, 5645, 817, -5459, 5625, 797, -5451, 5649, 797, -5443, 5661, 785, -5431, 5661, 805, -5423, 5665, 793, -5411, 5669, 817, -5423, 5657, 801, -5419, 5649, 793, -5411, 5657, 797, -5427, 5661, 809, -5435, 5653, 797, -5443, 5637,                                                                                                                                                                                                                                },\r
+{124, 805, -5463, 5645, 817, -5455, 5637, 813, -5447, 5653, 821, -5443, 5649, 821, -5451, 5649, 809, -5459, 5653, 797, -5451, 5697, 821, -5435, 5661, 821, -5427, 5677, 801, -5423, 5645, 777, -5427, 5657, 781, -5423, 5677, 797, -5459, 5653, 789, -5431, 5625, 769, -5403, 5645, 773, -5419, 5621, 781, -5435, 5621, 773, -5443, 5649, 789, -5467, 5649, 773, -5435, 5645, 797, -5431, 5665, 821, -5431, 5669, 805, -5447, 5673, 785, -5403, 5645, 805, -5303, 5721, 793, -5427, 5673, 761, -5515, 5633, 761, -5483, 5621, 761, -5415, 5653, 781, -5419, 5633, 781, -5451, 5649, 789, -5443, 5653, 809, -5427, 5665, 789, -5415, 5673, 809, -5407, 5681, 809, -5423, 5713, 809, -5427, 5713, 817, -5415, 5689, 797, -5419, 5685, 765, -5415, 5677, 749, -5415, 5673, 745, -5407, 5673, 761, -5427, 5649, 777, -5423, 5661, 793, -5435, 5657, 793, -5423, 5665, 793, -5407, 5657, 793, -5383, 5685, 765, -5387, 5717, 793, -5403, 5701, 785, -5395, 5681, 777, -5387, 5685, 753, -5399, 5681, 745, -5423, 5673, 737, -5427, 5661, 745, -5415, 5665, 757, -5411, 5677, 757, -5411, 5693, 769, -5415, 5685, 793, -5411, 5681, 773, -5391, 5681, 745, -5383, 5701, 745, -5327, 5741, 797, -5363, 5645, 805, -5475, 5677, 773, -5427, 5701, 753, -5363, 5681, 769, -5371, 5673, 745, -5419, 5693, 753, -5419, 5693, 745, -5395, 5669, 765, -5435, 5649, 781, -5455, 5681, 761, -5399, 5717, 753, -5375, 5673, 769, -5411, 5673, 749, -5451, 5669, 761, -5419, 5653, 745, -5403, 5677, 761, -5379, 5673, 769, -5395, 5713, 757, -5383, 5677, 757, -5391, 5689, 765, -5399, 5697, 769, -5415, 5677, 769, -5411, 5673, 781, -5443, 5661, 749, -5451, 5681, 757, -5447, 5669, 761, -5435, 5653, 769, -5439, 5693, 761, -5427, 5681, 777, -5419, 5673, 773, -5403, 5693, 757, -5399, 5693, 745, -5391, 5669, 749, -5391, 5685, 737, -5407, 5661, 745, -5395, 5681, 777, -5395, 5681, 789, -5415, 5661, 773, -5435, 5665, 745, -5419, 5665, 761, -5411, 5693, 761, -5415, 5665, 741, -5411, 5665, 737, -5419, 5657, 737, -5427, 5657, 741, -5419, 5665, 745, -5427, 5685, 757, -5419, 5685, 757, -5391, 5685, 781, -5419, 5685, 777, -5411, 5693, 753, -5415, 5673, 781, -5419, 5661, 749, -5427, 5669, 753, -5439, 5689, 769, -5419, 5673, 773, -5403, 5669, 785, -5423, 5693, 769, -5455, 5665, 745, -5431, 5665, 737, -5399, 5685,                                                                                                                                                                                                                                },\r
+{125, 737, -5391, 5697, 753, -5407, 5697, 781, -5403, 5697, 773, -5395, 5701, 781, -5383, 5701, 761, -5407, 5669, 761, -5403, 5669, 745, -5399, 5677, 741, -5407, 5649, 741, -5423, 5657, 745, -5431, 5665, 749, -5407, 5661, 757, -5399, 5681, 749, -5411, 5665, 765, -5419, 5681, 769, -5375, 5685, 757, -5371, 5697, 741, -5399, 5701, 757, -5423, 5677, 765, -5423, 5689, 765, -5427, 5661, 765, -5423, 5669, 761, -5407, 5673, 757, -5423, 5677, 749, -5399, 5677, 765, -5419, 5677, 745, -5407, 5685, 761, -5399, 5693, 781, -5415, 5693, 769, -5399, 5669, 761, -5387, 5685, 733, -5407, 5661, 741, -5415, 5669, 761, -5411, 5661, 757, -5415, 5653, 745, -5415, 5661, 769, -5423, 5649, 765, -5415, 5665, 737, -5395, 5685, 757, -5419, 5697, 777, -5399, 5697, 777, -5391, 5709, 765, -5407, 5669, 741, -5395, 5665, 733, -5403, 5665, 745, -5403, 5673, 757, -5419, 5685, 785, -5427, 5685, 777, -5443, 5669, 761, -5439, 5673, 781, -5431, 5681, 777, -5415, 5697, 777, -5411, 5685, 785, -5415, 5685, 777, -5411, 5693, 773, -5391, 5689, 757, -5399, 5709, 745, -5403, 5693, 753, -5411, 5665, 769, -5399, 5681, 793, -5423, 5673, 805, -5403, 5673, 797, -5387, 5669, 781, -5415, 5673, 797, -5427, 5681, 757, -5415, 5657, 753, -5391, 5653, 745, -5391, 5673, 737, -5395, 5685, 773, -5419, 5685, 761, -5423, 5669, 765, -5403, 5669, 761, -5411, 5689, 765, -5419, 5685, 785, -5415, 5669, 793, -5407, 5693, 789, -5399, 5673, 781, -5423, 5697, 765, -5431, 5685, 769, -5415, 5677, 781, -5383, 5689, 785, -5387, 5685, 769, -5403, 5673, 753, -5399, 5665, 733, -5423, 5649, 745, -5431, 5681, 741, -5419, 5657, 773, -5431, 5677, 781, -5411, 5689, 797, -5403, 5697, 801, -5387, 5697, 773, -5391, 5697, 773, -5375, 5705, 781, -5395, 5693, 781, -5415, 5681, 785, -5427, 5673, 777, -5407, 5653, 749, -5407, 5653, 757, -5415, 5673, 749, -5387, 5673, 769, -5387, 5681, 765, -5415, 5685, 773, -5447, 5677, 789, -5435, 5673, 769, -5427, 5697, 761, -5383, 5685, 765, -5415, 5677, 753, -5431, 5681, 781, -5427, 5681, 785, -5431, 5681, 769, -5407, 5673, 761, -5427, 5681, 757, -5411, 5681, 765, -5407, 5665, 769, -5395, 5705, 773, -5403, 5697, 777, -5411, 5673, 761, -5411, 5669, 753, -5423, 5689, 773, -5419, 5681, 765, -5423, 5661, 749, -5431, 5653, 761, -5415, 5669, 777, -5403, 5665, 785, -5391, 5681,                                                                                                                                                                                                },\r
+{124, 789, -5399, 5697, 769, -5419, 5697, 781, -5415, 5673, 773, -5399, 5689, 773, -5411, 5673, 741, -5399, 5665, 745, -5399, 5653, 765, -5391, 5689, 785, -5411, 5689, 801, -5407, 5689, 785, -5431, 5677, 765, -5455, 5645, 761, -5443, 5681, 813, -5427, 5685, 805, -5427, 5693, 765, -5423, 5677, 757, -5407, 5677, 769, -5427, 5693, 781, -5411, 5677, 765, -5431, 5685, 773, -5411, 5669, 785, -5411, 5677, 777, -5411, 5653, 769, -5407, 5669, 773, -5411, 5665, 789, -5395, 5661, 781, -5411, 5673, 789, -5427, 5661, 757, -5427, 5649, 765, -5427, 5677, 761, -5427, 5649, 769, -5395, 5685, 769, -5415, 5657, 765, -5419, 5673, 773, -5431, 5677, 765, -5427, 5689, 765, -5439, 5681, 789, -5427, 5697, 785, -5415, 5689, 789, -5403, 5673, 777, -5427, 5673, 773, -5423, 5677, 753, -5403, 5669, 765, -5407, 5693, 785, -5403, 5661, 761, -5399, 5689, 769, -5399, 5689, 789, -5415, 5653, 769, -5435, 5657, 785, -5443, 5649, 777, -5435, 5681, 757, -5423, 5673, 773, -5411, 5689, 785, -5403, 5693, 793, -5383, 5697, 789, -5399, 5701, 793, -5411, 5677, 781, -5427, 5661, 789, -5407, 5657, 749, -5387, 5669, 769, -5395, 5657, 745, -5399, 5677, 781, -5419, 5673, 769, -5415, 5673, 801, -5415, 5685, 777, -5427, 5681, 773, -5419, 5673, 773, -5407, 5677, 745, -5423, 5669, 749, -5431, 5677, 785, -5419, 5673, 785, -5407, 5677, 789, -5399, 5681, 781, -5415, 5677, 777, -5415, 5665, 781, -5395, 5669, 769, -5399, 5685, 781, -5415, 5697, 801, -5427, 5689, 813, -5415, 5665, 789, -5403, 5641, 773, -5423, 5657, 757, -5407, 5657, 773, -5411, 5661, 801, -5427, 5645, 797, -5411, 5653, 777, -5423, 5665, 765, -5415, 5657, 793, -5407, 5673, 785, -5415, 5685, 789, -5411, 5685, 793, -5427, 5661, 793, -5415, 5657, 797, -5423, 5665, 777, -5443, 5669, 797, -5423, 5669, 805, -5419, 5649, 813, -5431, 5685, 801, -5435, 5681, 769, -5451, 5685, 781, -5439, 5657, 793, -5431, 5669, 813, -5443, 5665, 805, -5439, 5665, 817, -5447, 5673, 809, -5443, 5665, 805, -5427, 5641, 797, -5431, 5657, 773, -5431, 5665, 801, -5435, 5649, 821, -5435, 5653, 829, -5423, 5645, 829, -5431, 5653, 825, -5435, 5649, 789, -5411, 5653, 809, -5411, 5649, 793, -5419, 5637, 789, -5447, 5645, 801, -5439, 5645, 789, -5427, 5653, 793, -5439, 5661, 809, -5435, 5641, 809, -5435, 5641, 805, -5435, 5653,                                                                                                                                                                                                                                },\r
+{124, 805, -5443, 5653, 813, -5451, 5649, 813, -5459, 5653, 821, -5427, 5657, 817, -5431, 5665, 797, -5419, 5669, 809, -5435, 5677, 805, -5427, 5661, 813, -5447, 5653, 801, -5435, 5661, 821, -5431, 5665, 833, -5435, 5685, 809, -5439, 5685, 797, -5427, 5633, 789, -5431, 5629, 809, -5427, 5645, 801, -5419, 5657, 801, -5419, 5665, 817, -5415, 5673, 829, -5427, 5673, 825, -5407, 5677, 817, -5419, 5685, 829, -5419, 5669, 825, -5455, 5657, 805, -5439, 5633, 805, -5451, 5629, 765, -5443, 5629, 785, -5443, 5641, 781, -5443, 5625, 801, -5439, 5637, 801, -5439, 5649, 809, -5447, 5661, 821, -5423, 5677, 813, -5415, 5681, 829, -5435, 5689, 821, -5431, 5681, 825, -5427, 5665, 817, -5435, 5649, 785, -5455, 5633, 789, -5463, 5629, 801, -5439, 5637, 813, -5451, 5641, 805, -5431, 5649, 797, -5447, 5665, 813, -5419, 5657, 821, -5399, 5673, 813, -5415, 5681, 837, -5407, 5653, 797, -5415, 5657, 805, -5427, 5677, 801, -5459, 5657, 805, -5435, 5637, 813, -5435, 5637, 809, -5439, 5645, 793, -5447, 5637, 801, -5443, 5661, 813, -5439, 5633, 805, -5435, 5653, 813, -5439, 5657, 813, -5427, 5661, 801, -5423, 5685, 817, -5411, 5685, 821, -5395, 5657, 801, -5403, 5665, 809, -5439, 5649, 813, -5455, 5641, 817, -5459, 5649, 809, -5443, 5665, 825, -5451, 5649, 809, -5447, 5641, 813, -5439, 5641, 825, -5435, 5641, 813, -5443, 5649, 813, -5451, 5637, 797, -5447, 5633, 821, -5451, 5649, 813, -5447, 5641, 849, -5443, 5645, 821, -5467, 5661, 817, -5439, 5645, 809, -5419, 5657, 809, -5427, 5645, 805, -5427, 5649, 793, -5455, 5613, 813, -5459, 5629, 789, -5463, 5633, 809, -5455, 5629, 821, -5435, 5633, 821, -5439, 5637, 801, -5443, 5637, 801, -5451, 5657, 829, -5459, 5641, 805, -5455, 5633, 793, -5435, 5625, 793, -5415, 5629, 813, -5423, 5617, 821, -5459, 5641, 817, -5467, 5637, 841, -5471, 5637, 837, -5467, 5625, 841, -5451, 5629, 825, -5443, 5653, 809, -5431, 5653, 797, -5427, 5649, 837, -5427, 5661, 805, -5443, 5641, 801, -5459, 5657, 809, -5443, 5645, 809, -5451, 5645, 805, -5435, 5629, 805, -5435, 5649, 841, -5443, 5649, 825, -5455, 5641, 825, -5451, 5649, 821, -5451, 5641, 817, -5419, 5641, 797, -5419, 5641, 805, -5431, 5637, 809, -5463, 5629, 813, -5451, 5637, 825, -5443, 5629, 817, -5455, 5645, 777, -5479, 5629, 801, -5459, 5625,                                                                                                                                                                                                                                },\r
+{125, 797, -5435, 5625, 813, -5439, 5641, 801, -5455, 5657, 821, -5463, 5665, 829, -5463, 5641, 809, -5455, 5633, 805, -5447, 5629, 785, -5443, 5653, 809, -5435, 5629, 841, -5439, 5625, 805, -5443, 5641, 801, -5459, 5665, 801, -5455, 5641, 829, -5455, 5621, 829, -5427, 5617, 837, -5427, 5653, 821, -5455, 5641, 829, -5451, 5657, 837, -5455, 5653, 809, -5459, 5629, 809, -5455, 5637, 805, -5483, 5625, 809, -5463, 5585, 801, -5459, 5621, 813, -5431, 5629, 837, -5407, 5661, 821, -5419, 5677, 817, -5443, 5665, 829, -5455, 5649, 825, -5439, 5645, 809, -5435, 5645, 813, -5455, 5645, 821, -5467, 5649, 829, -5455, 5637, 829, -5475, 5633, 833, -5479, 5633, 809, -5479, 5613, 809, -5475, 5621, 821, -5463, 5633, 825, -5443, 5633, 833, -5431, 5641, 829, -5447, 5641, 829, -5443, 5641, 845, -5463, 5645, 825, -5455, 5637, 809, -5439, 5621, 793, -5435, 5625, 801, -5447, 5617, 821, -5451, 5613, 809, -5447, 5609, 805, -5463, 5613, 817, -5459, 5629, 825, -5455, 5645, 825, -5451, 5633, 805, -5463, 5625, 817, -5443, 5645, 833, -5463, 5645, 861, -5475, 5657, 869, -5459, 5645, 845, -5467, 5657, 833, -5487, 5653, 813, -5475, 5633, 813, -5467, 5625, 817, -5455, 5617, 821, -5459, 5645, 805, -5455, 5637, 833, -5439, 5609, 813, -5463, 5617, 809, -5463, 5621, 801, -5447, 5625, 813, -5451, 5645, 829, -5439, 5641, 829, -5447, 5645, 829, -5479, 5609, 821, -5459, 5653, 797, -5427, 5649, 801, -5443, 5629, 821, -5455, 5645, 797, -5427, 5649, 793, -5431, 5633, 797, -5423, 5625, 821, -5471, 5645, 845, -5495, 5633, 829, -5451, 5629, 829, -5447, 5629, 829, -5439, 5637, 809, -5451, 5609, 761, -5459, 5641, 797, -5459, 5629, 821, -5443, 5629, 829, -5431, 5645, 797, -5443, 5661, 821, -5467, 5661, 829, -5451, 5649, 829, -5427, 5625, 797, -5439, 5653, 797, -5463, 5665, 813, -5459, 5629, 833, -5459, 5633, 841, -5447, 5629, 801, -5451, 5633, 793, -5447, 5633, 793, -5451, 5629, 809, -5459, 5661, 813, -5439, 5617, 825, -5435, 5625, 805, -5471, 5625, 805, -5459, 5625, 813, -5475, 5653, 813, -5451, 5637, 813, -5427, 5633, 813, -5447, 5641, 825, -5455, 5649, 841, -5459, 5657, 829, -5443, 5649, 813, -5439, 5621, 813, -5455, 5637, 797, -5491, 5633, 809, -5475, 5617, 817, -5475, 5637, 817, -5439, 5613, 801, -5447, 5633, 805, -5455, 5641, 817, -5467, 5657, 833, -5447, 5653,                                                                                                                                                                                                },\r
+{124, 845, -5415, 5665, 821, -5459, 5661, 837, -5471, 5629, 821, -5471, 5621, 829, -5459, 5633, 825, -5451, 5637, 813, -5443, 5621, 809, -5455, 5633, 805, -5471, 5613, 805, -5463, 5609, 813, -5443, 5613, 809, -5447, 5617, 817, -5447, 5641, 829, -5435, 5629, 837, -5455, 5629, 829, -5459, 5653, 825, -5451, 5641, 849, -5455, 5641, 849, -5455, 5617, 821, -5463, 5617, 789, -5463, 5625, 801, -5475, 5629, 805, -5447, 5633, 817, -5439, 5629, 845, -5439, 5649, 849, -5435, 5661, 841, -5447, 5633, 825, -5463, 5649, 825, -5443, 5641, 809, -5443, 5645, 833, -5455, 5629, 825, -5463, 5629, 817, -5451, 5641, 829, -5455, 5633, 829, -5451, 5625, 813, -5463, 5649, 821, -5455, 5613, 809, -5443, 5625, 821, -5455, 5653, 805, -5447, 5645, 821, -5435, 5629, 817, -5447, 5637, 821, -5451, 5629, 817, -5459, 5625, 797, -5459, 5629, 805, -5455, 5633, 809, -5451, 5621, 813, -5467, 5633, 825, -5479, 5637, 849, -5487, 5649, 845, -5487, 5633, 829, -5455, 5637, 813, -5447, 5637, 789, -5431, 5645, 793, -5435, 5657, 809, -5459, 5657, 841, -5443, 5657, 845, -5459, 5641, 809, -5467, 5633, 809, -5479, 5629, 809, -5455, 5621, 817, -5443, 5613, 841, -5447, 5637, 817, -5455, 5641, 809, -5467, 5637, 821, -5439, 5617, 805, -5455, 5617, 797, -5459, 5641, 805, -5467, 5629, 809, -5463, 5633, 853, -5439, 5649, 833, -5431, 5661, 825, -5427, 5649, 813, -5459, 5629, 809, -5451, 5613, 781, -5459, 5621, 793, -5471, 5617, 805, -5487, 5629, 837, -5487, 5633, 853, -5459, 5645, 821, -5443, 5637, 829, -5451, 5629, 809, -5459, 5625, 789, -5459, 5641, 817, -5447, 5633, 829, -5443, 5629, 825, -5463, 5637, 805, -5467, 5629, 833, -5467, 5641, 817, -5451, 5613, 813, -5415, 5621, 805, -5431, 5649, 809, -5451, 5629, 809, -5455, 5645, 813, -5459, 5625, 813, -5439, 5621, 801, -5455, 5629, 813, -5459, 5621, 817, -5463, 5621, 821, -5459, 5617, 813, -5443, 5613, 813, -5467, 5653, 825, -5467, 5649, 833, -5463, 5645, 833, -5459, 5649, 817, -5471, 5641, 805, -5451, 5645, 805, -5443, 5645, 809, -5427, 5645, 809, -5455, 5633, 809, -5463, 5625, 829, -5475, 5609, 809, -5443, 5629, 817, -5463, 5645, 833, -5455, 5653, 821, -5455, 5633, 829, -5431, 5637, 833, -5431, 5653, 821, -5435, 5645, 833, -5451, 5633, 821, -5459, 5641, 809, -5459, 5637, 817, -5451, 5625, 801, -5447, 5613,                                                                                                                                                                                                                                },\r
+{123, 785, -5463, 5629, 817, -5463, 5641, 817, -5463, 5633, 817, -5467, 5621, 825, -5459, 5617, 809, -5439, 5645, 821, -5463, 5617, 801, -5463, 5617, 821, -5455, 5633, 833, -5467, 5629, 821, -5463, 5617, 821, -5459, 5609, 821, -5447, 5641, 809, -5451, 5637, 829, -5451, 5645, 829, -5455, 5641, 829, -5451, 5633, 849, -5443, 5645, 805, -5447, 5621, 793, -5455, 5613, 797, -5443, 5613, 817, -5443, 5613, 833, -5459, 5649, 845, -5463, 5633, 813, -5447, 5629, 817, -5463, 5625, 793, -5459, 5633, 805, -5463, 5637, 821, -5471, 5625, 817, -5463, 5633, 797, -5443, 5621, 805, -5447, 5633, 829, -5435, 5629, 829, -5439, 5641, 833, -5443, 5637, 809, -5463, 5617, 805, -5483, 5637, 837, -5483, 5641, 845, -5475, 5641, 825, -5463, 5637, 825, -5455, 5621, 825, -5455, 5633, 817, -5443, 5629, 813, -5475, 5645, 817, -5479, 5641, 837, -5455, 5637, 841, -5455, 5637, 829, -5463, 5645, 829, -5463, 5617, 825, -5459, 5617, 809, -5435, 5633, 821, -5455, 5621, 805, -5447, 5617, 821, -5459, 5625, 825, -5463, 5609, 813, -5459, 5641, 805, -5435, 5633, 817, -5459, 5633, 817, -5475, 5621, 825, -5471, 5637, 829, -5451, 5625, 841, -5435, 5621, 821, -5451, 5629, 813, -5471, 5645, 809, -5483, 5629, 829, -5479, 5633, 853, -5459, 5645, 825, -5451, 5637, 821, -5459, 5645, 817, -5463, 5633, 801, -5471, 5657, 817, -5459, 5629, 805, -5447, 5625, 797, -5459, 5633, 797, -5439, 5641, 809, -5435, 5641, 817, -5463, 5625, 817, -5443, 5625, 821, -5427, 5649, 825, -5451, 5629, 821, -5443, 5629, 801, -5447, 5649, 793, -5431, 5649, 797, -5439, 5641, 817, -5443, 5633, 801, -5455, 5625, 785, -5459, 5653, 785, -5455, 5657, 813, -5443, 5653, 801, -5447, 5641, 809, -5447, 5649, 777, -5447, 5657, 797, -5439, 5649, 797, -5447, 5661, 813, -5447, 5677, 797, -5451, 5649, 781, -5439, 5661, 797, -5447, 5641, 813, -5451, 5657, 805, -5439, 5653, 817, -5447, 5641, 813, -5435, 5645, 801, -5427, 5653, 797, -5451, 5653, 801, -5435, 5665, 797, -5427, 5653, 785, -5431, 5665, 797, -5435, 5633, 789, -5427, 5649, 781, -5431, 5653, 777, -5435, 5653, 773, -5439, 5645, 805, -5431, 5637, 797, -5427, 5653, 797, -5431, 5677, 769, -5427, 5665, 785, -5423, 5665, 781, -5419, 5669, 793, -5427, 5673, 817, -5431, 5665, 805, -5455, 5653, 781, -5463, 5625, 773, -5479, 5641,                                                                                                                                                                                                                                                                },\r
+{124, 773, -5471, 5653, 793, -5443, 5661, 817, -5443, 5653, 825, -5419, 5649, 793, -5415, 5677, 789, -5427, 5705, 785, -5415, 5673, 793, -5435, 5645, 773, -5431, 5633, 785, -5411, 5645, 773, -5431, 5625, 757, -5419, 5633, 789, -5423, 5645, 801, -5427, 5637, 813, -5443, 5649, 761, -5431, 5649, 765, -5415, 5661, 765, -5415, 5649, 773, -5439, 5677, 793, -5411, 5681, 797, -5399, 5685, 765, -5403, 5685, 801, -5431, 5689, 809, -5459, 5649, 797, -5435, 5641, 757, -5447, 5637, 765, -5451, 5645, 769, -5435, 5649, 817, -5415, 5661, 821, -5403, 5677, 809, -5419, 5681, 789, -5443, 5665, 777, -5431, 5669, 797, -5415, 5673, 781, -5407, 5685, 797, -5423, 5645, 785, -5447, 5673, 781, -5431, 5669, 789, -5431, 5677, 785, -5439, 5641, 769, -5431, 5653, 777, -5427, 5653, 777, -5407, 5653, 765, -5395, 5649, 781, -5415, 5669, 789, -5411, 5661, 793, -5435, 5657, 781, -5427, 5641, 781, -5439, 5657, 781, -5443, 5673, 765, -5423, 5665, 773, -5431, 5669, 777, -5443, 5641, 793, -5467, 5653, 777, -5439, 5645, 757, -5431, 5669, 777, -5431, 5669, 793, -5431, 5661, 785, -5427, 5665, 785, -5447, 5677, 805, -5427, 5665, 785, -5439, 5653, 785, -5439, 5657, 769, -5431, 5673, 781, -5427, 5665, 777, -5427, 5653, 773, -5403, 5649, 773, -5423, 5649, 765, -5431, 5661, 753, -5423, 5681, 757, -5415, 5661, 777, -5423, 5665, 793, -5407, 5649, 773, -5419, 5649, 761, -5407, 5657, 761, -5415, 5653, 801, -5435, 5689, 817, -5451, 5673, 785, -5435, 5681, 773, -5447, 5661, 761, -5459, 5661, 769, -5439, 5669, 765, -5439, 5653, 773, -5423, 5657, 785, -5431, 5677, 801, -5439, 5665, 797, -5419, 5673, 785, -5391, 5661, 765, -5427, 5685, 773, -5431, 5677, 773, -5427, 5677, 789, -5415, 5661, 797, -5443, 5653, 797, -5447, 5641, 773, -5447, 5645, 769, -5447, 5645, 769, -5435, 5653, 765, -5435, 5649, 757, -5427, 5653, 733, -5407, 5657, 761, -5403, 5681, 777, -5403, 5693, 785, -5439, 5681, 797, -5435, 5681, 809, -5423, 5665, 801, -5443, 5665, 781, -5439, 5653, 769, -5447, 5657, 749, -5419, 5665, 765, -5383, 5673, 793, -5395, 5681, 801, -5431, 5677, 769, -5423, 5673, 785, -5403, 5673, 777, -5423, 5689, 769, -5431, 5669, 769, -5447, 5665, 773, -5443, 5653, 777, -5415, 5653, 765, -5395, 5661, 785, -5411, 5677, 769, -5415, 5645, 773, -5419, 5677, 789, -5407, 5681,                                                                                                                                                                                                                                },\r
+{125, 777, -5423, 5665, 781, -5399, 5653, 745, -5411, 5653, 749, -5407, 5665, 785, -5407, 5677, 777, -5439, 5653, 753, -5431, 5645, 741, -5423, 5669, 765, -5407, 5685, 777, -5423, 5669, 793, -5415, 5693, 793, -5423, 5677, 777, -5451, 5673, 793, -5439, 5673, 773, -5407, 5665, 785, -5403, 5677, 769, -5427, 5661, 753, -5407, 5665, 753, -5403, 5681, 781, -5411, 5677, 785, -5423, 5673, 785, -5427, 5685, 793, -5423, 5673, 789, -5419, 5665, 785, -5399, 5661, 777, -5407, 5661, 757, -5411, 5645, 753, -5407, 5661, 757, -5419, 5645, 757, -5419, 5661, 757, -5435, 5689, 777, -5415, 5681, 773, -5399, 5677, 773, -5383, 5665, 789, -5387, 5669, 781, -5399, 5673, 797, -5439, 5657, 773, -5463, 5673, 761, -5439, 5649, 797, -5443, 5653, 753, -5439, 5669, 765, -5435, 5673, 781, -5435, 5669, 809, -5431, 5657, 797, -5423, 5681, 793, -5435, 5709, 789, -5427, 5697, 789, -5431, 5649, 793, -5415, 5661, 765, -5419, 5657, 753, -5411, 5669, 785, -5407, 5657, 793, -5415, 5641, 797, -5435, 5625, 769, -5427, 5641, 769, -5427, 5653, 781, -5427, 5645, 801, -5439, 5661, 797, -5415, 5677, 793, -5419, 5681, 781, -5423, 5673, 789, -5423, 5657, 805, -5443, 5677, 785, -5439, 5685, 809, -5427, 5673, 769, -5431, 5661, 793, -5447, 5661, 781, -5455, 5661, 785, -5439, 5661, 797, -5415, 5661, 789, -5419, 5645, 793, -5427, 5657, 797, -5411, 5657, 781, -5427, 5645, 789, -5435, 5653, 801, -5439, 5673, 809, -5423, 5689, 817, -5415, 5669, 797, -5399, 5673, 781, -5423, 5685, 797, -5419, 5681, 805, -5435, 5669, 789, -5439, 5653, 773, -5427, 5641, 781, -5423, 5645, 777, -5431, 5641, 789, -5427, 5633, 781, -5423, 5645, 801, -5423, 5669, 797, -5427, 5649, 789, -5419, 5657, 813, -5431, 5673, 805, -5431, 5669, 797, -5443, 5657, 805, -5447, 5657, 797, -5451, 5653, 805, -5427, 5665, 801, -5451, 5629, 797, -5451, 5641, 793, -5431, 5645, 809, -5419, 5645, 793, -5427, 5653, 789, -5423, 5657, 809, -5443, 5685, 825, -5443, 5677, 809, -5407, 5665, 817, -5435, 5661, 805, -5451, 5653, 801, -5443, 5629, 809, -5451, 5633, 797, -5455, 5633, 797, -5455, 5621, 789, -5455, 5617, 789, -5455, 5653, 825, -5443, 5653, 813, -5427, 5665, 833, -5415, 5685, 821, -5427, 5649, 829, -5439, 5653, 813, -5435, 5641, 817, -5427, 5657, 829, -5455, 5649, 833, -5483, 5649, 837, -5471, 5657, 829, -5455, 5633,                                                                                                                                                                                                },\r
+{124, 841, -5463, 5617, 801, -5459, 5613, 809, -5435, 5641, 813, -5463, 5645, 817, -5467, 5641, 837, -5455, 5657, 813, -5431, 5653, 841, -5439, 5645, 837, -5455, 5641, 825, -5447, 5649, 817, -5431, 5621, 833, -5427, 5629, 809, -5439, 5629, 817, -5451, 5641, 809, -5455, 5605, 825, -5447, 5629, 821, -5447, 5633, 829, -5443, 5637, 845, -5455, 5645, 845, -5455, 5641, 829, -5467, 5653, 837, -5455, 5641, 833, -5463, 5637, 817, -5463, 5625, 821, -5455, 5641, 809, -5451, 5661, 841, -5451, 5653, 845, -5431, 5653, 829, -5451, 5641, 825, -5463, 5625, 837, -5455, 5629, 817, -5451, 5633, 833, -5439, 5625, 825, -5451, 5657, 825, -5475, 5641, 837, -5463, 5641, 837, -5455, 5633, 833, -5439, 5641, 837, -5451, 5641, 825, -5439, 5661, 825, -5439, 5649, 837, -5455, 5633, 821, -5443, 5637, 833, -5451, 5625, 833, -5455, 5625, 797, -5451, 5621, 821, -5447, 5629, 817, -5427, 5609, 821, -5431, 5613, 821, -5463, 5629, 845, -5439, 5625, 833, -5459, 5645, 849, -5463, 5641, 833, -5467, 5617, 837, -5451, 5625, 829, -5447, 5625, 821, -5459, 5633, 845, -5447, 5649, 853, -5467, 5633, 833, -5471, 5637, 837, -5475, 5633, 829, -5455, 5645, 857, -5451, 5625, 841, -5451, 5645, 813, -5427, 5641, 833, -5443, 5625, 829, -5455, 5629, 829, -5471, 5617, 817, -5471, 5617, 813, -5455, 5621, 813, -5439, 5617, 829, -5463, 5629, 841, -5463, 5609, 809, -5463, 5597, 821, -5447, 5613, 821, -5439, 5625, 825, -5415, 5629, 845, -5423, 5629, 861, -5427, 5657, 841, -5451, 5661, 833, -5483, 5649, 821, -5475, 5645, 845, -5483, 5625, 829, -5479, 5601, 837, -5467, 5641, 825, -5459, 5621, 845, -5467, 5621, 833, -5455, 5629, 829, -5471, 5629, 829, -5471, 5625, 833, -5455, 5625, 833, -5431, 5625, 853, -5443, 5641, 845, -5455, 5641, 861, -5467, 5653, 869, -5471, 5641, 849, -5479, 5613, 821, -5459, 5601, 797, -5459, 5617, 813, -5451, 5605, 809, -5459, 5617, 833, -5439, 5629, 853, -5447, 5641, 825, -5443, 5641, 845, -5455, 5641, 837, -5451, 5629, 833, -5459, 5629, 845, -5483, 5621, 837, -5495, 5613, 829, -5491, 5609, 833, -5475, 5625, 837, -5471, 5605, 829, -5455, 5609, 813, -5459, 5629, 825, -5447, 5629, 837, -5451, 5645, 853, -5463, 5657, 853, -5463, 5637, 865, -5451, 5637, 849, -5479, 5621, 841, -5483, 5605, 817, -5459, 5625, 821, -5455, 5633, 853, -5463, 5621,                                                                                                                                                                                                                                },\r
+{124, 849, -5459, 5613, 837, -5471, 5617, 825, -5459, 5645, 833, -5439, 5645, 837, -5427, 5641, 833, -5431, 5637, 829, -5455, 5629, 829, -5443, 5633, 833, -5447, 5605, 829, -5479, 5609, 829, -5471, 5605, 829, -5475, 5637, 833, -5479, 5609, 821, -5475, 5621, 821, -5471, 5613, 829, -5459, 5617, 829, -5447, 5621, 837, -5451, 5633, 841, -5475, 5637, 833, -5471, 5645, 837, -5451, 5641, 825, -5455, 5625, 845, -5459, 5637, 853, -5463, 5629, 825, -5471, 5633, 821, -5451, 5625, 833, -5447, 5605, 833, -5443, 5617, 821, -5451, 5625, 817, -5459, 5641, 825, -5463, 5621, 841, -5447, 5625, 837, -5443, 5621, 813, -5459, 5621, 809, -5483, 5613, 785, -5495, 5605, 817, -5467, 5609, 833, -5467, 5633, 837, -5463, 5637, 849, -5439, 5657, 861, -5415, 5661, 865, -5431, 5641, 845, -5459, 5653, 821, -5471, 5637, 805, -5475, 5629, 817, -5475, 5601, 809, -5479, 5613, 833, -5467, 5625, 849, -5463, 5617, 845, -5467, 5597, 841, -5479, 5609, 829, -5467, 5621, 841, -5467, 5657, 865, -5455, 5649, 861, -5463, 5653, 833, -5451, 5637, 821, -5447, 5629, 821, -5451, 5605, 825, -5439, 5617, 801, -5455, 5601, 817, -5467, 5593, 841, -5491, 5613, 837, -5483, 5617, 845, -5467, 5621, 837, -5451, 5621, 821, -5447, 5633, 849, -5439, 5645, 845, -5455, 5641, 837, -5455, 5633, 817, -5471, 5613, 821, -5471, 5625, 825, -5463, 5609, 845, -5447, 5621, 837, -5495, 5641, 853, -5499, 5625, 841, -5467, 5625, 845, -5471, 5637, 845, -5479, 5629, 861, -5463, 5637, 841, -5463, 5625, 821, -5443, 5629, 837, -5463, 5641, 833, -5463, 5625, 845, -5463, 5637, 853, -5443, 5605, 849, -5451, 5605, 841, -5463, 5641, 849, -5467, 5629, 837, -5467, 5629, 853, -5459, 5621, 841, -5447, 5621, 817, -5439, 5629, 837, -5451, 5617, 821, -5455, 5621, 813, -5451, 5617, 825, -5463, 5621, 845, -5471, 5605, 849, -5471, 5605, 849, -5475, 5609, 845, -5475, 5617, 837, -5475, 5617, 849, -5475, 5629, 845, -5471, 5637, 833, -5471, 5605, 817, -5451, 5633, 821, -5459, 5633, 841, -5467, 5621, 861, -5463, 5617, 849, -5475, 5633, 849, -5475, 5633, 829, -5451, 5621, 841, -5463, 5613, 829, -5455, 5625, 841, -5455, 5609, 841, -5455, 5621, 829, -5459, 5609, 857, -5459, 5629, 837, -5479, 5617, 829, -5467, 5609, 833, -5467, 5597, 833, -5455, 5609, 837, -5455, 5625, 849, -5471, 5613, 817, -5499, 5633,                                                                                                                                                                                                                                },\r
+{124, 813, -5487, 5621, 805, -5455, 5621, 837, -5423, 5641, 841, -5435, 5657, 841, -5439, 5641, 841, -5447, 5625, 821, -5471, 5625, 837, -5479, 5633, 841, -5491, 5601, 865, -5507, 5609, 849, -5503, 5605, 849, -5487, 5609, 825, -5475, 5621, 825, -5439, 5637, 845, -5443, 5637, 845, -5459, 5633, 869, -5483, 5629, 857, -5487, 5629, 837, -5463, 5621, 837, -5467, 5605, 821, -5459, 5625, 829, -5459, 5605, 841, -5467, 5585, 849, -5479, 5585, 841, -5471, 5613, 841, -5459, 5621, 837, -5451, 5613, 841, -5459, 5601, 837, -5455, 5617, 853, -5475, 5629, 841, -5483, 5621, 833, -5475, 5613, 837, -5471, 5621, 857, -5487, 5637, 841, -5483, 5633, 849, -5475, 5617, 853, -5471, 5605, 837, -5483, 5621, 817, -5467, 5617, 833, -5475, 5625, 829, -5471, 5625, 821, -5455, 5641, 845, -5455, 5641, 857, -5475, 5633, 853, -5479, 5597, 817, -5475, 5605, 841, -5471, 5601, 845, -5487, 5609, 849, -5467, 5613, 853, -5451, 5621, 833, -5471, 5641, 849, -5475, 5625, 861, -5451, 5629, 849, -5455, 5629, 829, -5455, 5633, 841, -5487, 5605, 833, -5491, 5585, 833, -5463, 5609, 825, -5443, 5645, 837, -5447, 5633, 837, -5467, 5617, 841, -5499, 5605, 857, -5475, 5613, 837, -5471, 5605, 825, -5463, 5605, 845, -5479, 5625, 825, -5479, 5621, 841, -5479, 5625, 841, -5459, 5629, 841, -5487, 5629, 857, -5491, 5617, 849, -5463, 5629, 853, -5439, 5629, 849, -5451, 5633, 845, -5471, 5625, 841, -5459, 5625, 833, -5463, 5601, 829, -5463, 5589, 833, -5475, 5589, 829, -5479, 5597, 845, -5467, 5609, 829, -5471, 5621, 857, -5443, 5621, 877, -5459, 5645, 865, -5463, 5633, 857, -5471, 5629, 821, -5487, 5617, 833, -5495, 5597, 817, -5483, 5609, 829, -5459, 5613, 853, -5447, 5637, 849, -5443, 5621, 833, -5447, 5637, 865, -5471, 5641, 849, -5483, 5621, 841, -5483, 5617, 825, -5479, 5613, 845, -5491, 5593, 845, -5487, 5613, 857, -5483, 5637, 845, -5479, 5617, 857, -5447, 5613, 845, -5475, 5621, 841, -5471, 5621, 853, -5495, 5613, 837, -5487, 5621, 853, -5463, 5585, 845, -5475, 5613, 857, -5483, 5617, 849, -5475, 5613, 853, -5463, 5601, 853, -5455, 5613, 853, -5459, 5605, 841, -5471, 5625, 841, -5475, 5629, 837, -5471, 5617, 833, -5471, 5617, 845, -5467, 5633, 861, -5475, 5629, 857, -5483, 5621, 849, -5483, 5605, 861, -5483, 5601, 845, -5483, 5605, 833, -5479, 5609,                                                                                                                                                                                                                                },\r
+{125, 817, -5479, 5625, 833, -5483, 5621, 849, -5471, 5617, 849, -5447, 5637, 853, -5439, 5641, 857, -5459, 5637, 853, -5475, 5633, 849, -5467, 5641, 833, -5467, 5621, 849, -5463, 5617, 861, -5467, 5617, 853, -5467, 5613, 833, -5451, 5617, 833, -5459, 5629, 833, -5475, 5621, 833, -5459, 5629, 837, -5439, 5641, 825, -5443, 5645, 833, -5447, 5641, 829, -5443, 5633, 821, -5451, 5601, 829, -5443, 5625, 833, -5463, 5609, 833, -5463, 5609, 825, -5463, 5609, 817, -5459, 5621, 829, -5455, 5645, 813, -5455, 5633, 813, -5455, 5633, 841, -5447, 5661, 833, -5431, 5633, 837, -5459, 5649, 833, -5467, 5649, 813, -5447, 5653, 813, -5455, 5661, 833, -5439, 5645, 821, -5451, 5621, 805, -5475, 5609, 813, -5455, 5621, 821, -5471, 5637, 825, -5451, 5649, 821, -5435, 5641, 829, -5447, 5621, 821, -5427, 5645, 813, -5439, 5661, 813, -5431, 5653, 829, -5443, 5649, 833, -5455, 5645, 785, -5455, 5645, 785, -5463, 5629, 793, -5447, 5633, 797, -5455, 5645, 813, -5427, 5637, 813, -5395, 5645, 825, -5439, 5657, 797, -5447, 5669, 805, -5439, 5677, 829, -5435, 5669, 813, -5447, 5653, 833, -5451, 5661, 789, -5471, 5641, 797, -5483, 5649, 797, -5467, 5665, 805, -5463, 5641, 801, -5455, 5645, 813, -5447, 5657, 793, -5423, 5661, 809, -5427, 5661, 809, -5447, 5657, 817, -5447, 5653, 809, -5427, 5645, 797, -5403, 5661, 789, -5411, 5653, 797, -5419, 5621, 809, -5407, 5645, 805, -5407, 5653, 793, -5435, 5661, 801, -5439, 5657, 817, -5439, 5673, 813, -5431, 5657, 773, -5439, 5649, 797, -5435, 5649, 793, -5431, 5665, 797, -5403, 5673, 789, -5411, 5661, 777, -5443, 5665, 777, -5439, 5669, 785, -5427, 5661, 801, -5419, 5669, 809, -5399, 5657, 813, -5415, 5645, 809, -5451, 5673, 801, -5439, 5677, 797, -5439, 5677, 793, -5443, 5669, 793, -5411, 5661, 805, -5379, 5693, 785, -5411, 5693, 777, -5407, 5689, 789, -5387, 5681, 785, -5387, 5705, 781, -5403, 5673, 789, -5419, 5657, 777, -5427, 5673, 789, -5411, 5669, 765, -5403, 5661, 769, -5411, 5669, 777, -5387, 5677, 809, -5387, 5665, 801, -5399, 5689, 789, -5411, 5685, 781, -5387, 5685, 769, -5383, 5697, 793, -5407, 5693, 797, -5439, 5645, 773, -5411, 5645, 745, -5419, 5641, 753, -5431, 5677, 777, -5431, 5669, 805, -5435, 5661, 785, -5423, 5653, 761, -5387, 5689, 781, -5379, 5701, 765, -5403, 5685, 805, -5411, 5717,                                                                                                                                                                                                },\r
+{124, 793, -5399, 5689, 785, -5403, 5657, 785, -5431, 5661, 741, -5439, 5665, 749, -5423, 5649, 761, -5431, 5653, 769, -5427, 5657, 757, -5419, 5665, 761, -5391, 5669, 769, -5383, 5669, 761, -5387, 5693, 781, -5379, 5709, 773, -5395, 5685, 777, -5407, 5693, 777, -5415, 5665, 753, -5407, 5681, 789, -5415, 5661, 793, -5419, 5669, 773, -5423, 5673, 777, -5447, 5657, 761, -5443, 5677, 773, -5423, 5669, 781, -5415, 5661, 753, -5403, 5681, 777, -5403, 5693, 785, -5379, 5713, 777, -5371, 5705, 773, -5379, 5693, 765, -5403, 5685, 773, -5411, 5677, 777, -5411, 5669, 781, -5399, 5649, 789, -5407, 5677, 809, -5411, 5701, 753, -5415, 5661, 757, -5399, 5665, 765, -5399, 5677, 757, -5387, 5705, 773, -5399, 5689, 781, -5403, 5685, 769, -5399, 5697, 769, -5387, 5693, 773, -5375, 5677, 781, -5407, 5673, 761, -5439, 5681, 765, -5435, 5689, 785, -5435, 5681, 793, -5403, 5701, 789, -5391, 5709, 781, -5387, 5685, 781, -5387, 5677, 773, -5399, 5709, 753, -5391, 5673, 761, -5391, 5693, 781, -5387, 5689, 781, -5395, 5677, 797, -5399, 5681, 801, -5419, 5697, 785, -5411, 5689, 781, -5391, 5697, 789, -5387, 5681, 773, -5395, 5681, 773, -5411, 5697, 741, -5435, 5657, 777, -5435, 5665, 753, -5395, 5669, 757, -5387, 5685, 781, -5407, 5673, 789, -5395, 5693, 785, -5415, 5689, 785, -5403, 5685, 785, -5407, 5669, 773, -5415, 5697, 773, -5411, 5681, 781, -5419, 5689, 785, -5423, 5677, 769, -5411, 5669, 797, -5407, 5669, 757, -5423, 5665, 773, -5415, 5697, 793, -5411, 5677, 781, -5399, 5693, 769, -5403, 5673, 793, -5407, 5697, 821, -5423, 5701, 781, -5415, 5693, 797, -5403, 5681, 769, -5407, 5677, 769, -5423, 5657, 769, -5423, 5641, 769, -5419, 5653, 785, -5419, 5637, 765, -5423, 5633, 765, -5399, 5673, 777, -5399, 5681, 785, -5387, 5697, 797, -5387, 5685, 797, -5383, 5689, 789, -5395, 5689, 789, -5399, 5685, 797, -5431, 5669, 777, -5451, 5657, 801, -5451, 5669, 797, -5451, 5669, 809, -5455, 5669, 817, -5455, 5649, 793, -5423, 5661, 793, -5415, 5677, 785, -5431, 5693, 765, -5419, 5693, 789, -5395, 5701, 801, -5403, 5697, 817, -5391, 5673, 821, -5415, 5665, 805, -5403, 5653, 793, -5411, 5677, 793, -5415, 5653, 789, -5411, 5653, 801, -5427, 5641, 785, -5427, 5645, 785, -5435, 5661, 761, -5423, 5661, 769, -5415, 5653, 761, -5403, 5657,                                                                                                                                                                                                                                },\r
+{125, 781, -5423, 5673, 793, -5423, 5665, 825, -5443, 5669, 809, -5423, 5685, 801, -5411, 5665, 813, -5411, 5681, 789, -5431, 5673, 773, -5423, 5665, 797, -5407, 5669, 805, -5407, 5665, 813, -5419, 5661, 813, -5411, 5645, 805, -5423, 5637, 793, -5427, 5637, 797, -5419, 5641, 789, -5419, 5661, 813, -5427, 5665, 809, -5439, 5677, 805, -5439, 5673, 821, -5423, 5669, 833, -5403, 5697, 837, -5419, 5665, 821, -5435, 5669, 805, -5471, 5633, 805, -5439, 5641, 789, -5431, 5649, 809, -5431, 5629, 805, -5427, 5653, 829, -5407, 5657, 829, -5399, 5673, 833, -5427, 5661, 853, -5459, 5657, 829, -5443, 5653, 817, -5443, 5681, 821, -5447, 5649, 797, -5459, 5641, 805, -5455, 5601, 817, -5447, 5621, 805, -5447, 5621, 825, -5447, 5681, 821, -5431, 5645, 821, -5415, 5645, 829, -5443, 5669, 841, -5431, 5661, 849, -5423, 5661, 849, -5451, 5649, 849, -5447, 5653, 825, -5459, 5633, 813, -5455, 5637, 821, -5459, 5649, 813, -5443, 5625, 809, -5451, 5625, 825, -5451, 5625, 825, -5463, 5629, 817, -5475, 5617, 829, -5483, 5637, 825, -5455, 5637, 849, -5447, 5649, 837, -5439, 5657, 809, -5423, 5661, 841, -5439, 5645, 837, -5443, 5657, 813, -5463, 5641, 805, -5459, 5625, 825, -5459, 5617, 837, -5463, 5633, 845, -5459, 5633, 845, -5467, 5637, 845, -5475, 5637, 841, -5467, 5653, 845, -5471, 5625, 841, -5447, 5653, 845, -5467, 5641, 833, -5451, 5645, 833, -5455, 5649, 837, -5431, 5657, 833, -5455, 5625, 833, -5447, 5641, 849, -5475, 5633, 845, -5455, 5617, 829, -5447, 5597, 841, -5459, 5605, 833, -5455, 5625, 849, -5431, 5641, 837, -5471, 5653, 841, -5455, 5645, 845, -5443, 5641, 841, -5447, 5641, 837, -5447, 5633, 821, -5455, 5617, 809, -5447, 5609, 825, -5439, 5617, 833, -5455, 5621, 837, -5467, 5641, 853, -5467, 5637, 829, -5451, 5637, 857, -5431, 5629, 841, -5431, 5645, 853, -5443, 5665, 877, -5467, 5653, 857, -5439, 5637, 817, -5447, 5641, 825, -5467, 5637, 825, -5475, 5621, 845, -5463, 5621, 857, -5459, 5641, 861, -5451, 5621, 857, -5463, 5629, 849, -5463, 5621, 813, -5431, 5625, 813, -5447, 5645, 849, -5419, 5645, 853, -5431, 5665, 837, -5439, 5649, 817, -5463, 5653, 833, -5463, 5625, 837, -5455, 5621, 829, -5439, 5629, 817, -5471, 5605, 813, -5467, 5605, 829, -5463, 5617, 833, -5455, 5613, 817, -5451, 5629, 829, -5447, 5645, 841, -5443, 5653,                                                                                                                                                                                                },\r
+{124, 837, -5447, 5661, 841, -5439, 5637, 849, -5439, 5645, 821, -5459, 5649, 829, -5467, 5657, 837, -5463, 5605, 853, -5447, 5625, 817, -5435, 5637, 821, -5435, 5637, 813, -5451, 5645, 829, -5443, 5657, 837, -5415, 5637, 841, -5431, 5633, 833, -5439, 5641, 813, -5459, 5633, 841, -5447, 5633, 837, -5451, 5633, 813, -5479, 5625, 821, -5491, 5629, 821, -5471, 5641, 809, -5471, 5633, 845, -5439, 5629, 833, -5411, 5665, 841, -5407, 5645, 841, -5439, 5657, 833, -5447, 5637, 825, -5483, 5637, 805, -5483, 5637, 817, -5471, 5629, 853, -5451, 5625, 849, -5471, 5641, 857, -5455, 5637, 829, -5447, 5641, 805, -5447, 5625, 825, -5431, 5625, 829, -5447, 5625, 837, -5443, 5633, 853, -5455, 5633, 853, -5459, 5633, 861, -5443, 5633, 861, -5439, 5633, 845, -5443, 5645, 837, -5451, 5637, 841, -5447, 5625, 821, -5451, 5625, 813, -5435, 5633, 817, -5439, 5629, 837, -5439, 5613, 833, -5463, 5625, 845, -5471, 5629, 841, -5475, 5633, 853, -5467, 5629, 869, -5467, 5645, 853, -5459, 5617, 833, -5471, 5621, 829, -5459, 5633, 837, -5447, 5637, 825, -5455, 5637, 825, -5455, 5641, 845, -5459, 5633, 833, -5447, 5625, 845, -5455, 5645, 877, -5455, 5649, 869, -5447, 5625, 857, -5463, 5625, 849, -5471, 5641, 833, -5467, 5613, 833, -5455, 5621, 829, -5443, 5633, 841, -5455, 5629, 853, -5463, 5637, 833, -5439, 5625, 845, -5423, 5649, 849, -5435, 5649, 865, -5439, 5641, 845, -5443, 5621, 837, -5439, 5613, 857, -5447, 5633, 829, -5447, 5605, 829, -5463, 5609, 833, -5467, 5613, 837, -5467, 5625, 841, -5447, 5625, 849, -5459, 5645, 833, -5451, 5637, 837, -5463, 5637, 845, -5451, 5637, 837, -5455, 5625, 857, -5459, 5633, 849, -5463, 5613, 857, -5459, 5621, 833, -5455, 5629, 853, -5447, 5629, 817, -5475, 5637, 845, -5475, 5633, 817, -5451, 5633, 817, -5447, 5613, 841, -5423, 5601, 845, -5439, 5617, 825, -5451, 5633, 841, -5455, 5625, 881, -5471, 5637, 881, -5471, 5657, 857, -5463, 5637, 853, -5459, 5625, 817, -5451, 5617, 841, -5467, 5613, 817, -5487, 5613, 821, -5459, 5625, 809, -5475, 5625, 845, -5467, 5637, 865, -5463, 5633, 865, -5451, 5649, 849, -5443, 5649, 845, -5431, 5641, 825, -5447, 5645, 805, -5467, 5641, 829, -5483, 5633, 837, -5463, 5621, 833, -5471, 5613, 869, -5455, 5625, 869, -5463, 5625, 849, -5463, 5625, 845, -5475, 5633,                                                                                                                                                                                                                                },\r
+{124, 845, -5479, 5625, 849, -5467, 5641, 833, -5443, 5641, 829, -5431, 5629, 825, -5435, 5621, 829, -5451, 5633, 821, -5443, 5621, 853, -5447, 5621, 857, -5479, 5629, 849, -5475, 5621, 845, -5459, 5621, 813, -5439, 5633, 829, -5435, 5621, 817, -5431, 5629, 841, -5455, 5641, 825, -5459, 5641, 833, -5459, 5605, 833, -5479, 5617, 821, -5455, 5617, 837, -5443, 5613, 837, -5463, 5617, 849, -5483, 5629, 857, -5447, 5637, 857, -5463, 5645, 849, -5483, 5641, 829, -5463, 5637, 825, -5443, 5633, 821, -5427, 5633, 825, -5435, 5617, 837, -5447, 5629, 853, -5439, 5625, 861, -5463, 5645, 873, -5479, 5645, 853, -5459, 5621, 841, -5443, 5629, 829, -5443, 5637, 829, -5451, 5621, 833, -5447, 5649, 853, -5455, 5637, 841, -5439, 5641, 829, -5451, 5617, 813, -5439, 5629, 825, -5455, 5637, 837, -5455, 5649, 841, -5455, 5629, 849, -5455, 5625, 849, -5483, 5625, 841, -5467, 5621, 841, -5463, 5605, 825, -5475, 5629, 837, -5479, 5625, 853, -5463, 5625, 837, -5463, 5633, 837, -5447, 5633, 845, -5443, 5641, 833, -5463, 5625, 829, -5443, 5629, 817, -5463, 5637, 833, -5467, 5633, 821, -5455, 5629, 821, -5463, 5633, 849, -5455, 5633, 825, -5451, 5621, 829, -5459, 5633, 857, -5475, 5625, 857, -5459, 5621, 825, -5459, 5621, 821, -5451, 5625, 841, -5447, 5617, 841, -5459, 5633, 833, -5451, 5625, 829, -5467, 5625, 833, -5463, 5621, 825, -5483, 5641, 821, -5459, 5621, 833, -5463, 5633, 845, -5463, 5645, 857, -5467, 5665, 853, -5447, 5641, 861, -5451, 5645, 841, -5435, 5637, 845, -5459, 5653, 801, -5451, 5641, 805, -5483, 5609, 817, -5475, 5601, 833, -5487, 5613, 853, -5471, 5625, 849, -5467, 5621, 853, -5459, 5641, 857, -5463, 5633, 869, -5451, 5641, 845, -5455, 5649, 849, -5455, 5673, 861, -5447, 5657, 845, -5447, 5629, 817, -5459, 5621, 841, -5455, 5617, 829, -5455, 5601, 825, -5455, 5609, 829, -5455, 5605, 817, -5463, 5625, 825, -5471, 5613, 845, -5455, 5613, 841, -5459, 5621, 849, -5463, 5649, 861, -5475, 5617, 845, -5471, 5637, 833, -5455, 5645, 865, -5439, 5665, 845, -5467, 5625, 813, -5479, 5637, 825, -5463, 5629, 825, -5451, 5625, 829, -5459, 5617, 837, -5455, 5625, 853, -5451, 5641, 841, -5451, 5633, 845, -5447, 5629, 833, -5447, 5645, 845, -5463, 5645, 849, -5467, 5633, 869, -5475, 5649, 853, -5467, 5657, 825, -5431, 5637,                                                                                                                                                                                                                                },\r
+{124, 829, -5447, 5617, 833, -5467, 5645, 817, -5459, 5621, 833, -5455, 5625, 837, -5463, 5633, 837, -5447, 5617, 845, -5447, 5617, 849, -5463, 5629, 825, -5483, 5637, 825, -5467, 5629, 813, -5435, 5633, 817, -5431, 5637, 845, -5447, 5629, 837, -5455, 5629, 829, -5467, 5625, 825, -5471, 5601, 837, -5483, 5629, 845, -5459, 5617, 841, -5451, 5621, 841, -5471, 5637, 845, -5471, 5629, 845, -5459, 5637, 829, -5435, 5641, 837, -5435, 5649, 849, -5483, 5625, 821, -5475, 5613, 817, -5479, 5613, 833, -5455, 5629, 833, -5435, 5621, 825, -5443, 5629, 821, -5447, 5633, 845, -5463, 5637, 841, -5455, 5641, 837, -5443, 5625, 841, -5439, 5621, 833, -5439, 5645, 833, -5427, 5629, 857, -5459, 5637, 857, -5467, 5633, 849, -5479, 5625, 829, -5463, 5629, 833, -5443, 5633, 825, -5451, 5613, 821, -5459, 5617, 825, -5447, 5649, 849, -5439, 5673, 869, -5419, 5673, 889, -5419, 5653, 865, -5467, 5633, 833, -5475, 5641, 833, -5467, 5621, 813, -5451, 5605, 817, -5467, 5609, 813, -5491, 5617, 841, -5459, 5613, 825, -5439, 5641, 865, -5447, 5637, 833, -5455, 5657, 825, -5447, 5625, 833, -5451, 5633, 833, -5435, 5649, 841, -5439, 5629, 865, -5455, 5629, 833, -5451, 5613, 837, -5451, 5625, 821, -5459, 5625, 805, -5467, 5605, 809, -5459, 5609, 829, -5451, 5621, 833, -5443, 5641, 833, -5459, 5633, 853, -5467, 5637, 853, -5479, 5641, 825, -5447, 5625, 829, -5431, 5629, 829, -5451, 5629, 841, -5455, 5617, 841, -5475, 5617, 845, -5463, 5605, 841, -5467, 5641, 845, -5459, 5637, 837, -5451, 5633, 849, -5443, 5653, 825, -5459, 5641, 829, -5451, 5621, 821, -5447, 5641, 845, -5459, 5645, 825, -5475, 5605, 837, -5463, 5649, 857, -5451, 5645, 841, -5447, 5629, 845, -5447, 5621, 833, -5455, 5629, 837, -5443, 5629, 829, -5447, 5633, 817, -5443, 5621, 837, -5459, 5625, 821, -5471, 5617, 817, -5467, 5617, 813, -5435, 5629, 853, -5423, 5633, 829, -5447, 5629, 833, -5455, 5637, 849, -5463, 5617, 861, -5471, 5637, 853, -5459, 5629, 817, -5459, 5613, 829, -5463, 5617, 833, -5467, 5641, 837, -5447, 5657, 841, -5451, 5641, 849, -5463, 5621, 837, -5439, 5645, 849, -5439, 5653, 837, -5431, 5649, 825, -5455, 5649, 849, -5475, 5641, 841, -5463, 5633, 845, -5447, 5645, 829, -5451, 5641, 809, -5435, 5637, 841, -5455, 5633, 821, -5479, 5629, 817, -5455, 5637,                                                                                                                                                                                                                                },\r
+{125, 805, -5423, 5621, 813, -5427, 5641, 825, -5443, 5653, 857, -5443, 5645, 853, -5443, 5657, 845, -5447, 5649, 829, -5471, 5641, 825, -5467, 5637, 833, -5463, 5629, 813, -5455, 5633, 805, -5455, 5621, 813, -5435, 5633, 833, -5435, 5657, 841, -5423, 5645, 825, -5435, 5653, 817, -5431, 5657, 849, -5443, 5661, 829, -5479, 5645, 829, -5479, 5645, 825, -5463, 5625, 809, -5487, 5617, 817, -5463, 5621, 821, -5451, 5613, 805, -5443, 5645, 805, -5435, 5645, 821, -5431, 5649, 833, -5435, 5661, 833, -5415, 5657, 825, -5415, 5641, 825, -5419, 5657, 817, -5423, 5637, 829, -5435, 5637, 817, -5443, 5613, 825, -5455, 5621, 805, -5439, 5641, 797, -5447, 5633, 801, -5451, 5649, 805, -5443, 5657, 805, -5439, 5657, 801, -5435, 5649, 837, -5411, 5665, 825, -5423, 5653, 813, -5439, 5653, 809, -5455, 5641, 821, -5443, 5653, 785, -5439, 5653, 805, -5447, 5645, 813, -5423, 5633, 809, -5419, 5665, 825, -5439, 5653, 809, -5443, 5649, 801, -5459, 5669, 805, -5447, 5669, 797, -5443, 5653, 817, -5443, 5661, 817, -5423, 5673, 809, -5423, 5677, 809, -5407, 5673, 789, -5411, 5669, 813, -5427, 5653, 797, -5431, 5653, 789, -5431, 5637, 793, -5443, 5621, 785, -5423, 5649, 789, -5439, 5657, 797, -5423, 5661, 817, -5419, 5673, 813, -5423, 5681, 781, -5427, 5649, 797, -5427, 5661, 781, -5423, 5669, 781, -5427, 5649, 805, -5427, 5649, 785, -5407, 5653, 785, -5431, 5653, 777, -5415, 5649, 793, -5435, 5669, 813, -5451, 5661, 793, -5439, 5653, 805, -5423, 5669, 797, -5415, 5685, 825, -5423, 5701, 805, -5419, 5681, 805, -5407, 5673, 785, -5411, 5669, 789, -5439, 5673, 789, -5431, 5657, 769, -5411, 5645, 761, -5443, 5641, 773, -5431, 5665, 777, -5411, 5681, 781, -5419, 5657, 785, -5419, 5669, 797, -5387, 5645, 793, -5371, 5677, 789, -5379, 5677, 793, -5411, 5693, 777, -5427, 5673, 797, -5435, 5665, 793, -5435, 5661, 801, -5423, 5669, 793, -5435, 5673, 781, -5447, 5673, 777, -5447, 5665, 765, -5427, 5681, 785, -5427, 5677, 781, -5415, 5689, 785, -5419, 5697, 781, -5399, 5697, 789, -5383, 5689, 785, -5415, 5677, 781, -5395, 5681, 773, -5387, 5677, 777, -5407, 5669, 793, -5419, 5653, 781, -5431, 5653, 773, -5411, 5641, 765, -5411, 5649, 761, -5427, 5649, 777, -5439, 5657, 785, -5451, 5665, 765, -5411, 5681, 769, -5415, 5689, 781, -5379, 5673, 753, -5355, 5721,                                                                                                                                                                                                },\r
+{124, 733, -5291, 5601, 829, -5551, 5657, 853, -5519, 5685, 789, -5367, 5697, 785, -5403, 5673, 769, -5479, 5617, 761, -5523, 5637, 769, -5447, 5673, 797, -5371, 5677, 777, -5411, 5701, 785, -5431, 5701, 781, -5423, 5693, 809, -5399, 5705, 785, -5415, 5709, 777, -5407, 5709, 789, -5403, 5669, 785, -5415, 5673, 773, -5423, 5681, 757, -5423, 5653, 773, -5435, 5649, 793, -5443, 5661, 785, -5435, 5657, 769, -5391, 5657, 737, -5379, 5677, 741, -5399, 5681, 757, -5403, 5693, 765, -5395, 5681, 773, -5407, 5705, 789, -5435, 5693, 777, -5435, 5657, 757, -5415, 5657, 753, -5415, 5669, 773, -5415, 5677, 769, -5427, 5665, 781, -5431, 5673, 797, -5439, 5677, 773, -5427, 5657, 769, -5391, 5685, 769, -5395, 5681, 765, -5403, 5693, 781, -5435, 5681, 765, -5427, 5677, 765, -5411, 5669, 781, -5411, 5665, 765, -5415, 5653, 757, -5399, 5673, 761, -5419, 5677, 773, -5399, 5673, 781, -5407, 5689, 773, -5411, 5677, 765, -5407, 5669, 769, -5399, 5681, 757, -5391, 5673, 733, -5399, 5673, 741, -5403, 5681, 757, -5403, 5689, 753, -5383, 5689, 773, -5387, 5685, 797, -5423, 5685, 797, -5451, 5689, 765, -5447, 5669, 769, -5443, 5673, 785, -5439, 5681, 781, -5443, 5693, 765, -5431, 5677, 781, -5411, 5657, 769, -5403, 5681, 753, -5391, 5677, 753, -5403, 5689, 749, -5403, 5693, 761, -5407, 5661, 793, -5399, 5661, 785, -5399, 5673, 777, -5415, 5685, 777, -5431, 5653, 777, -5435, 5645, 737, -5411, 5645, 757, -5403, 5677, 761, -5395, 5669, 777, -5415, 5669, 769, -5423, 5693, 761, -5407, 5673, 765, -5391, 5677, 785, -5423, 5673, 769, -5415, 5677, 773, -5395, 5685, 793, -5419, 5709, 801, -5439, 5701, 765, -5427, 5681, 761, -5447, 5661, 777, -5447, 5649, 773, -5391, 5669, 765, -5375, 5693, 773, -5391, 5665, 769, -5415, 5693, 765, -5435, 5685, 777, -5435, 5689, 761, -5415, 5673, 785, -5395, 5697, 781, -5403, 5705, 773, -5407, 5701, 757, -5415, 5685, 761, -5411, 5693, 769, -5423, 5681, 765, -5431, 5665, 765, -5427, 5645, 761, -5399, 5665, 753, -5391, 5681, 773, -5383, 5677, 769, -5411, 5661, 769, -5419, 5685, 785, -5427, 5677, 757, -5411, 5669, 729, -5415, 5669, 749, -5427, 5657, 749, -5395, 5665, 753, -5427, 5673, 777, -5435, 5681, 789, -5423, 5685, 785, -5423, 5677, 781, -5419, 5697, 773, -5403, 5681, 761, -5391, 5681, 769, -5403, 5685,                                                                                                                                                                                                                                },\r
+{124, 761, -5403, 5697, 769, -5427, 5685, 769, -5435, 5673, 761, -5443, 5661, 749, -5411, 5661, 773, -5399, 5669, 773, -5399, 5653, 769, -5395, 5673, 785, -5419, 5681, 769, -5427, 5681, 801, -5403, 5657, 773, -5403, 5661, 773, -5411, 5673, 765, -5399, 5669, 773, -5391, 5685, 773, -5379, 5681, 769, -5387, 5673, 777, -5395, 5677, 785, -5407, 5677, 769, -5419, 5689, 773, -5423, 5677, 777, -5427, 5673, 773, -5443, 5661, 773, -5439, 5673, 789, -5471, 5689, 801, -5455, 5697, 817, -5423, 5673, 801, -5415, 5689, 801, -5415, 5681, 765, -5415, 5669, 765, -5415, 5661, 785, -5415, 5661, 797, -5411, 5649, 777, -5407, 5673, 801, -5411, 5669, 777, -5415, 5661, 793, -5419, 5673, 769, -5407, 5665, 785, -5419, 5653, 777, -5439, 5653, 781, -5423, 5657, 797, -5423, 5653, 797, -5415, 5685, 789, -5427, 5677, 785, -5415, 5681, 773, -5427, 5665, 777, -5427, 5669, 769, -5431, 5665, 769, -5423, 5657, 773, -5419, 5673, 789, -5411, 5653, 785, -5423, 5653, 801, -5443, 5669, 793, -5411, 5661, 801, -5395, 5693, 821, -5411, 5677, 813, -5415, 5665, 821, -5403, 5649, 801, -5435, 5657, 777, -5431, 5649, 777, -5427, 5665, 801, -5451, 5669, 797, -5439, 5673, 809, -5427, 5681, 801, -5407, 5673, 797, -5407, 5681, 817, -5399, 5689, 809, -5431, 5681, 801, -5423, 5669, 809, -5419, 5649, 805, -5439, 5645, 809, -5443, 5653, 809, -5427, 5653, 789, -5423, 5661, 789, -5423, 5653, 785, -5415, 5657, 789, -5415, 5649, 801, -5435, 5677, 813, -5431, 5661, 809, -5447, 5649, 809, -5439, 5669, 813, -5411, 5657, 821, -5427, 5645, 805, -5443, 5653, 809, -5443, 5661, 809, -5447, 5665, 817, -5419, 5673, 833, -5411, 5661, 801, -5415, 5665, 801, -5439, 5673, 789, -5423, 5677, 825, -5423, 5657, 833, -5443, 5649, 813, -5471, 5633, 825, -5459, 5657, 809, -5431, 5641, 793, -5431, 5661, 797, -5443, 5649, 801, -5439, 5669, 805, -5415, 5661, 809, -5427, 5661, 829, -5411, 5673, 829, -5399, 5681, 805, -5403, 5673, 805, -5439, 5661, 829, -5455, 5645, 817, -5451, 5645, 805, -5451, 5645, 793, -5443, 5661, 813, -5427, 5669, 817, -5411, 5657, 825, -5411, 5665, 817, -5431, 5649, 825, -5439, 5649, 817, -5435, 5637, 837, -5443, 5653, 805, -5439, 5641, 813, -5435, 5673, 825, -5423, 5661, 829, -5415, 5657, 837, -5443, 5657, 817, -5451, 5641, 809, -5439, 5633, 797, -5427, 5637,                                                                                                                                                                                                                                },\r
+{124, 793, -5451, 5657, 817, -5431, 5657, 821, -5431, 5633, 837, -5415, 5649, 817, -5427, 5673, 805, -5431, 5649, 817, -5431, 5665, 825, -5443, 5661, 829, -5451, 5657, 825, -5463, 5661, 833, -5455, 5645, 797, -5443, 5649, 821, -5435, 5637, 821, -5427, 5629, 821, -5431, 5661, 833, -5443, 5645, 829, -5451, 5649, 825, -5443, 5649, 833, -5423, 5645, 825, -5415, 5657, 845, -5415, 5681, 825, -5447, 5665, 825, -5443, 5637, 821, -5443, 5649, 809, -5435, 5657, 825, -5451, 5665, 821, -5447, 5645, 825, -5439, 5633, 813, -5439, 5641, 821, -5431, 5649, 841, -5415, 5669, 805, -5423, 5645, 837, -5423, 5653, 845, -5439, 5657, 813, -5431, 5641, 813, -5447, 5661, 821, -5443, 5637, 821, -5423, 5657, 833, -5431, 5637, 813, -5451, 5633, 833, -5451, 5625, 833, -5467, 5649, 821, -5451, 5629, 813, -5451, 5641, 825, -5439, 5641, 829, -5447, 5665, 829, -5447, 5653, 841, -5427, 5661, 845, -5443, 5653, 849, -5463, 5673, 813, -5451, 5665, 833, -5435, 5629, 817, -5419, 5633, 805, -5451, 5653, 809, -5443, 5637, 821, -5439, 5641, 829, -5427, 5625, 837, -5443, 5641, 837, -5463, 5649, 829, -5479, 5641, 833, -5451, 5641, 821, -5447, 5641, 821, -5415, 5641, 841, -5423, 5649, 849, -5431, 5657, 829, -5443, 5653, 813, -5435, 5657, 817, -5431, 5653, 805, -5451, 5629, 801, -5459, 5649, 837, -5471, 5633, 845, -5455, 5641, 853, -5443, 5641, 849, -5423, 5661, 849, -5439, 5657, 829, -5463, 5645, 817, -5467, 5637, 837, -5463, 5621, 845, -5447, 5641, 833, -5443, 5645, 829, -5447, 5633, 845, -5439, 5621, 817, -5451, 5637, 845, -5443, 5617, 825, -5463, 5613, 813, -5455, 5609, 841, -5467, 5629, 825, -5443, 5637, 813, -5419, 5649, 845, -5439, 5653, 849, -5443, 5641, 833, -5447, 5645, 841, -5447, 5633, 813, -5479, 5621, 825, -5471, 5621, 833, -5443, 5621, 829, -5447, 5625, 821, -5439, 5637, 833, -5435, 5637, 849, -5447, 5633, 821, -5443, 5637, 841, -5447, 5649, 833, -5443, 5649, 829, -5463, 5661, 857, -5455, 5657, 833, -5463, 5653, 845, -5435, 5629, 821, -5431, 5641, 809, -5443, 5641, 833, -5443, 5649, 829, -5443, 5637, 837, -5443, 5653, 845, -5467, 5625, 845, -5467, 5649, 837, -5431, 5621, 845, -5427, 5661, 829, -5431, 5629, 845, -5435, 5649, 841, -5443, 5645, 833, -5451, 5641, 833, -5435, 5637, 813, -5431, 5625, 829, -5451, 5645, 841, -5447, 5621,                                                                                                                                                                                                                                },\r
+{125, 825, -5471, 5609, 813, -5447, 5637, 825, -5455, 5625, 833, -5467, 5637, 845, -5451, 5677, 837, -5463, 5649, 857, -5463, 5633, 849, -5443, 5637, 833, -5447, 5621, 829, -5463, 5649, 829, -5447, 5641, 833, -5435, 5637, 837, -5443, 5645, 857, -5467, 5653, 857, -5471, 5625, 853, -5471, 5617, 837, -5463, 5621, 821, -5447, 5617, 809, -5435, 5601, 797, -5423, 5625, 833, -5431, 5641, 845, -5443, 5629, 861, -5443, 5645, 849, -5451, 5649, 817, -5451, 5629, 837, -5459, 5633, 829, -5471, 5637, 817, -5455, 5645, 849, -5435, 5645, 857, -5419, 5637, 845, -5415, 5649, 833, -5435, 5653, 821, -5447, 5637, 829, -5451, 5617, 837, -5479, 5629, 857, -5479, 5657, 853, -5455, 5657, 869, -5419, 5645, 857, -5415, 5657, 841, -5463, 5653, 817, -5507, 5617, 813, -5483, 5605, 833, -5463, 5597, 813, -5427, 5637, 837, -5427, 5637, 821, -5451, 5681, 849, -5459, 5657, 869, -5467, 5649, 849, -5463, 5633, 829, -5419, 5609, 793, -5415, 5609, 789, -5423, 5633, 805, -5447, 5613, 833, -5463, 5637, 865, -5471, 5621, 861, -5475, 5625, 833, -5483, 5641, 849, -5471, 5625, 833, -5451, 5629, 821, -5423, 5633, 829, -5443, 5629, 845, -5451, 5645, 841, -5467, 5633, 821, -5443, 5617, 829, -5459, 5617, 821, -5451, 5613, 825, -5443, 5645, 853, -5447, 5645, 849, -5463, 5665, 861, -5451, 5673, 853, -5459, 5645, 833, -5463, 5633, 817, -5451, 5637, 793, -5415, 5629, 813, -5415, 5637, 825, -5439, 5645, 845, -5459, 5637, 849, -5475, 5629, 845, -5475, 5637, 845, -5443, 5641, 849, -5423, 5617, 849, -5427, 5629, 817, -5415, 5649, 849, -5435, 5645, 845, -5439, 5645, 821, -5459, 5629, 809, -5459, 5621, 821, -5439, 5621, 813, -5447, 5633, 825, -5455, 5625, 853, -5463, 5629, 849, -5475, 5637, 841, -5487, 5625, 841, -5467, 5641, 817, -5459, 5633, 837, -5451, 5633, 845, -5455, 5637, 833, -5447, 5633, 837, -5443, 5661, 837, -5459, 5649, 845, -5459, 5645, 833, -5463, 5625, 821, -5443, 5649, 841, -5443, 5641, 817, -5431, 5625, 825, -5439, 5641, 833, -5447, 5649, 841, -5475, 5633, 837, -5463, 5621, 829, -5455, 5605, 833, -5451, 5625, 825, -5439, 5633, 845, -5455, 5641, 837, -5439, 5625, 841, -5475, 5625, 825, -5463, 5625, 817, -5459, 5641, 829, -5439, 5633, 833, -5407, 5649, 813, -5423, 5685, 817, -5415, 5633, 845, -5427, 5645, 837, -5451, 5661, 829, -5471, 5625, 801, -5479, 5629,                                                                                                                                                                                                },\r
+{124, 817, -5483, 5625, 849, -5475, 5629, 853, -5447, 5625, 849, -5455, 5633, 865, -5471, 5633, 837, -5459, 5637, 817, -5443, 5637, 805, -5455, 5641, 825, -5439, 5633, 829, -5431, 5649, 817, -5439, 5625, 837, -5431, 5657, 853, -5439, 5637, 833, -5455, 5621, 829, -5471, 5629, 829, -5455, 5621, 829, -5447, 5617, 829, -5455, 5645, 829, -5451, 5609, 837, -5443, 5629, 833, -5455, 5633, 833, -5467, 5621, 821, -5471, 5633, 829, -5459, 5629, 829, -5443, 5661, 853, -5435, 5633, 825, -5443, 5629, 833, -5439, 5637, 821, -5467, 5625, 813, -5471, 5641, 829, -5447, 5661, 865, -5463, 5637, 837, -5447, 5629, 821, -5439, 5657, 817, -5443, 5633, 841, -5447, 5661, 817, -5447, 5637, 833, -5447, 5641, 817, -5455, 5657, 829, -5455, 5637, 829, -5455, 5649, 821, -5435, 5617, 817, -5459, 5645, 817, -5443, 5633, 833, -5439, 5645, 833, -5451, 5633, 833, -5443, 5629, 845, -5439, 5653, 817, -5447, 5653, 833, -5467, 5649, 825, -5451, 5641, 813, -5447, 5649, 813, -5451, 5637, 817, -5475, 5633, 821, -5463, 5637, 805, -5439, 5637, 817, -5439, 5633, 821, -5435, 5641, 845, -5471, 5653, 833, -5455, 5653, 821, -5447, 5649, 805, -5439, 5645, 825, -5447, 5665, 825, -5447, 5653, 797, -5447, 5649, 813, -5447, 5657, 801, -5451, 5653, 813, -5459, 5653, 817, -5463, 5637, 821, -5435, 5637, 789, -5427, 5649, 821, -5443, 5633, 809, -5447, 5617, 813, -5439, 5629, 805, -5455, 5645, 817, -5443, 5661, 813, -5439, 5637, 809, -5451, 5637, 813, -5439, 5649, 789, -5427, 5649, 797, -5423, 5669, 801, -5415, 5665, 809, -5431, 5653, 805, -5439, 5665, 809, -5431, 5645, 813, -5427, 5665, 817, -5423, 5681, 805, -5447, 5657, 817, -5463, 5649, 825, -5471, 5657, 805, -5463, 5641, 789, -5467, 5681, 785, -5435, 5681, 801, -5415, 5665, 789, -5403, 5673, 781, -5419, 5669, 797, -5435, 5641, 801, -5423, 5669, 805, -5427, 5665, 825, -5415, 5661, 809, -5431, 5657, 805, -5427, 5633, 793, -5411, 5641, 789, -5415, 5645, 769, -5419, 5661, 781, -5443, 5685, 777, -5435, 5657, 781, -5439, 5657, 781, -5415, 5697, 797, -5423, 5645, 793, -5439, 5673, 773, -5443, 5669, 769, -5411, 5665, 785, -5407, 5701, 809, -5443, 5681, 793, -5443, 5661, 785, -5451, 5665, 773, -5427, 5669, 773, -5403, 5665, 789, -5403, 5669, 769, -5403, 5657, 793, -5431, 5645, 793, -5439, 5673, 797, -5419, 5677,                                                                                                                                                                                                                                },\r
+{124, 769, -5399, 5689, 781, -5399, 5681, 801, -5419, 5673, 793, -5427, 5685, 781, -5411, 5689, 765, -5411, 5677, 757, -5415, 5677, 773, -5411, 5657, 773, -5415, 5657, 761, -5427, 5641, 765, -5423, 5661, 773, -5415, 5657, 797, -5411, 5665, 785, -5415, 5693, 777, -5399, 5685, 785, -5407, 5681, 773, -5419, 5689, 749, -5419, 5689, 761, -5419, 5677, 765, -5423, 5673, 745, -5435, 5641, 761, -5439, 5657, 801, -5443, 5653, 773, -5431, 5661, 753, -5415, 5653, 785, -5411, 5665, 777, -5427, 5685, 781, -5423, 5685, 789, -5431, 5669, 777, -5423, 5665, 781, -5415, 5705, 769, -5415, 5689, 757, -5423, 5665, 761, -5411, 5657, 757, -5419, 5665, 765, -5419, 5669, 773, -5423, 5669, 793, -5443, 5657, 773, -5435, 5657, 789, -5415, 5673, 761, -5423, 5661, 781, -5419, 5677, 757, -5395, 5681, 765, -5403, 5673, 765, -5423, 5673, 753, -5399, 5665, 765, -5403, 5677, 777, -5415, 5689, 769, -5403, 5705, 777, -5415, 5677, 805, -5427, 5681, 785, -5435, 5673, 761, -5459, 5669, 777, -5447, 5673, 777, -5439, 5669, 757, -5439, 5665, 769, -5415, 5681, 749, -5391, 5677, 769, -5383, 5681, 793, -5403, 5693, 769, -5399, 5697, 781, -5407, 5681, 777, -5403, 5681, 793, -5403, 5689, 773, -5423, 5677, 777, -5403, 5657, 785, -5419, 5625, 781, -5431, 5641, 745, -5411, 5649, 725, -5411, 5661, 777, -5423, 5673, 769, -5399, 5677, 773, -5391, 5705, 765, -5407, 5681, 765, -5443, 5685, 781, -5399, 5685, 781, -5379, 5689, 781, -5399, 5673, 789, -5439, 5681, 781, -5451, 5665, 757, -5443, 5657, 769, -5435, 5653, 785, -5403, 5673, 781, -5399, 5705, 785, -5395, 5697, 785, -5399, 5685, 757, -5415, 5689, 757, -5407, 5689, 765, -5423, 5677, 761, -5427, 5653, 773, -5431, 5685, 793, -5415, 5701, 793, -5403, 5697, 789, -5435, 5693, 785, -5423, 5669, 765, -5419, 5677, 761, -5411, 5681, 741, -5431, 5661, 745, -5419, 5641, 753, -5407, 5657, 765, -5419, 5669, 749, -5419, 5657, 769, -5399, 5677, 777, -5423, 5693, 809, -5407, 5669, 793, -5415, 5673, 785, -5431, 5689, 777, -5435, 5673, 765, -5423, 5685, 769, -5415, 5673, 769, -5435, 5665, 769, -5423, 5657, 765, -5431, 5657, 761, -5423, 5661, 773, -5403, 5677, 793, -5399, 5661, 781, -5419, 5673, 777, -5415, 5681, 769, -5427, 5685, 785, -5419, 5665, 773, -5403, 5657, 777, -5423, 5657, 745, -5439, 5653, 753, -5427, 5653,                                                                                                                                                                                                                                },\r
+{124, 801, -5427, 5669, 785, -5423, 5681, 777, -5415, 5693, 793, -5403, 5677, 789, -5419, 5669, 781, -5391, 5657, 781, -5407, 5649, 793, -5411, 5673, 773, -5407, 5661, 769, -5403, 5681, 777, -5407, 5697, 781, -5427, 5661, 781, -5419, 5665, 785, -5403, 5669, 761, -5439, 5657, 769, -5455, 5661, 789, -5451, 5665, 801, -5443, 5693, 809, -5439, 5677, 801, -5419, 5677, 777, -5423, 5709, 789, -5403, 5681, 797, -5411, 5685, 781, -5411, 5681, 777, -5407, 5665, 789, -5435, 5669, 781, -5431, 5653, 777, -5415, 5633, 773, -5419, 5637, 777, -5435, 5645, 781, -5411, 5657, 785, -5427, 5657, 793, -5423, 5673, 757, -5403, 5673, 793, -5391, 5673, 797, -5407, 5657, 781, -5415, 5661, 777, -5431, 5653, 789, -5451, 5669, 809, -5427, 5677, 789, -5427, 5661, 789, -5431, 5681, 813, -5423, 5669, 817, -5423, 5673, 801, -5435, 5685, 797, -5427, 5661, 777, -5391, 5669, 773, -5391, 5669, 785, -5403, 5665, 789, -5423, 5649, 797, -5439, 5641, 777, -5431, 5665, 777, -5443, 5677, 785, -5443, 5669, 781, -5431, 5669, 789, -5407, 5685, 801, -5399, 5677, 801, -5395, 5681, 781, -5411, 5701, 797, -5411, 5677, 797, -5411, 5653, 801, -5427, 5661, 789, -5431, 5665, 789, -5419, 5665, 797, -5419, 5665, 801, -5415, 5669, 801, -5415, 5669, 801, -5427, 5657, 777, -5443, 5645, 769, -5439, 5653, 781, -5431, 5649, 793, -5419, 5653, 805, -5419, 5645, 789, -5431, 5673, 797, -5439, 5673, 793, -5439, 5661, 813, -5427, 5669, 813, -5423, 5661, 797, -5419, 5665, 789, -5431, 5685, 777, -5415, 5665, 793, -5423, 5645, 773, -5431, 5657, 777, -5423, 5649, 793, -5419, 5669, 789, -5427, 5661, 801, -5427, 5645, 793, -5443, 5637, 797, -5443, 5649, 785, -5427, 5657, 833, -5423, 5657, 797, -5431, 5645, 797, -5443, 5637, 785, -5415, 5665, 777, -5419, 5657, 801, -5411, 5673, 805, -5407, 5677, 841, -5415, 5657, 829, -5419, 5669, 813, -5423, 5661, 813, -5427, 5665, 809, -5419, 5665, 793, -5427, 5665, 793, -5427, 5645, 817, -5455, 5669, 825, -5435, 5657, 841, -5439, 5661, 817, -5435, 5677, 833, -5447, 5685, 829, -5443, 5661, 817, -5435, 5645, 837, -5447, 5637, 833, -5439, 5645, 829, -5451, 5637, 833, -5451, 5645, 837, -5431, 5637, 797, -5415, 5653, 805, -5439, 5625, 821, -5439, 5629, 833, -5419, 5637, 829, -5435, 5653, 817, -5439, 5649, 841, -5447, 5629, 829, -5451, 5629,                                                                                                                                                                                                                                },\r
+{125, 829, -5451, 5645, 809, -5459, 5637, 809, -5475, 5629, 849, -5491, 5609, 829, -5467, 5633, 825, -5459, 5669, 845, -5439, 5665, 829, -5443, 5649, 849, -5419, 5649, 853, -5443, 5629, 837, -5451, 5641, 825, -5463, 5629, 817, -5451, 5609, 817, -5451, 5613, 833, -5439, 5633, 845, -5439, 5621, 837, -5451, 5617, 845, -5471, 5625, 849, -5447, 5645, 865, -5451, 5665, 865, -5463, 5657, 857, -5467, 5641, 849, -5435, 5657, 833, -5455, 5645, 813, -5451, 5633, 821, -5435, 5645, 829, -5451, 5637, 833, -5447, 5625, 829, -5475, 5621, 833, -5471, 5621, 833, -5447, 5625, 853, -5439, 5637, 829, -5443, 5621, 821, -5479, 5621, 837, -5451, 5637, 857, -5435, 5637, 817, -5431, 5633, 833, -5451, 5641, 833, -5471, 5637, 849, -5467, 5629, 845, -5455, 5641, 845, -5451, 5625, 841, -5459, 5657, 849, -5467, 5641, 841, -5455, 5633, 821, -5459, 5621, 805, -5447, 5657, 817, -5431, 5657, 829, -5435, 5637, 853, -5431, 5637, 833, -5447, 5629, 841, -5467, 5649, 817, -5455, 5633, 833, -5439, 5629, 841, -5435, 5633, 829, -5435, 5641, 837, -5451, 5633, 849, -5463, 5633, 841, -5443, 5617, 833, -5435, 5637, 841, -5451, 5649, 837, -5459, 5649, 825, -5455, 5629, 833, -5463, 5633, 833, -5431, 5657, 833, -5423, 5637, 837, -5431, 5641, 829, -5423, 5665, 845, -5423, 5657, 833, -5435, 5645, 805, -5455, 5641, 821, -5459, 5633, 817, -5467, 5629, 845, -5451, 5641, 845, -5443, 5645, 849, -5447, 5653, 825, -5447, 5637, 837, -5459, 5637, 813, -5451, 5633, 829, -5443, 5645, 857, -5447, 5677, 845, -5447, 5649, 833, -5451, 5641, 849, -5451, 5625, 825, -5435, 5629, 817, -5443, 5637, 817, -5423, 5637, 829, -5443, 5637, 833, -5455, 5625, 821, -5459, 5653, 829, -5459, 5625, 833, -5447, 5633, 817, -5455, 5633, 833, -5439, 5653, 833, -5435, 5661, 841, -5455, 5641, 845, -5459, 5653, 841, -5459, 5617, 821, -5475, 5625, 821, -5451, 5645, 841, -5427, 5645, 849, -5431, 5641, 853, -5439, 5637, 821, -5451, 5621, 833, -5463, 5641, 817, -5447, 5629, 825, -5447, 5657, 845, -5439, 5645, 825, -5431, 5653, 813, -5439, 5649, 817, -5459, 5641, 833, -5459, 5625, 821, -5443, 5649, 837, -5455, 5629, 833, -5443, 5637, 833, -5447, 5641, 845, -5443, 5661, 853, -5439, 5645, 849, -5443, 5645, 841, -5447, 5653, 833, -5427, 5653, 825, -5447, 5645, 821, -5451, 5637, 821, -5443, 5625, 829, -5435, 5625,                                                                                                                                                                                                },\r
+{124, 837, -5459, 5625, 833, -5467, 5621, 833, -5463, 5629, 849, -5443, 5621, 841, -5427, 5653, 857, -5439, 5645, 841, -5455, 5657, 829, -5451, 5625, 829, -5451, 5641, 821, -5447, 5621, 809, -5447, 5629, 809, -5467, 5649, 829, -5459, 5649, 837, -5459, 5625, 829, -5451, 5625, 809, -5459, 5625, 829, -5435, 5645, 841, -5447, 5677, 853, -5435, 5637, 853, -5443, 5629, 857, -5467, 5613, 845, -5471, 5637, 813, -5463, 5613, 829, -5455, 5645, 813, -5463, 5605, 809, -5443, 5605, 825, -5447, 5617, 837, -5427, 5661, 845, -5443, 5645, 837, -5447, 5645, 829, -5447, 5629, 817, -5447, 5625, 809, -5463, 5657, 825, -5443, 5633, 833, -5427, 5641, 849, -5435, 5633, 857, -5467, 5657, 845, -5459, 5625, 817, -5447, 5637, 841, -5483, 5645, 825, -5471, 5645, 845, -5443, 5653, 845, -5439, 5661, 849, -5447, 5621, 825, -5455, 5625, 833, -5455, 5629, 825, -5463, 5625, 853, -5471, 5605, 841, -5459, 5649, 845, -5451, 5641, 837, -5431, 5645, 849, -5443, 5633, 821, -5459, 5665, 841, -5431, 5645, 829, -5443, 5613, 821, -5447, 5617, 809, -5463, 5621, 809, -5447, 5617, 821, -5463, 5625, 829, -5451, 5629, 821, -5447, 5633, 845, -5467, 5625, 853, -5467, 5625, 837, -5459, 5629, 833, -5455, 5621, 829, -5447, 5625, 845, -5459, 5629, 861, -5443, 5633, 845, -5463, 5637, 821, -5439, 5645, 809, -5439, 5649, 825, -5451, 5633, 837, -5447, 5637, 829, -5455, 5653, 833, -5447, 5625, 837, -5451, 5637, 853, -5487, 5625, 845, -5487, 5629, 845, -5463, 5641, 821, -5451, 5649, 853, -5447, 5649, 853, -5455, 5657, 829, -5463, 5641, 837, -5439, 5657, 829, -5435, 5637, 833, -5435, 5665, 837, -5423, 5641, 825, -5443, 5645, 841, -5455, 5649, 833, -5447, 5645, 817, -5467, 5625, 813, -5463, 5617, 809, -5443, 5613, 801, -5443, 5629, 829, -5451, 5617, 821, -5443, 5633, 853, -5459, 5633, 837, -5463, 5649, 837, -5435, 5661, 829, -5439, 5645, 829, -5431, 5649, 829, -5443, 5645, 837, -5455, 5633, 805, -5455, 5645, 825, -5451, 5629, 825, -5459, 5665, 833, -5443, 5653, 821, -5443, 5653, 825, -5431, 5653, 837, -5431, 5669, 829, -5427, 5661, 801, -5423, 5677, 829, -5415, 5653, 817, -5407, 5649, 817, -5435, 5633, 813, -5459, 5637, 809, -5475, 5637, 805, -5463, 5629, 813, -5443, 5637, 825, -5435, 5645, 789, -5423, 5649, 797, -5411, 5645, 801, -5391, 5665, 829, -5431, 5681,                                                                                                                                                                                                                                },\r
+{124, 833, -5439, 5677, 813, -5419, 5641, 813, -5399, 5653, 797, -5415, 5653, 797, -5431, 5645, 821, -5439, 5657, 809, -5463, 5641, 801, -5459, 5649, 817, -5467, 5665, 797, -5423, 5677, 801, -5431, 5673, 813, -5415, 5677, 813, -5411, 5697, 805, -5407, 5665, 813, -5395, 5673, 825, -5383, 5721, 821, -5427, 5693, 829, -5427, 5685, 797, -5435, 5645, 757, -5403, 5645, 765, -5383, 5633, 753, -5387, 5649, 781, -5411, 5637, 797, -5435, 5653, 777, -5411, 5685, 773, -5455, 5661, 769, -5391, 5657, 765, -5391, 5689, 789, -5419, 5649, 785, -5419, 5657, 761, -5419, 5685, 773, -5411, 5705, 801, -5423, 5697, 793, -5427, 5677, 805, -5299, 5697, 833, -5335, 5769, 757, -5523, 5645, 733, -5523, 5621, 717, -5423, 5681, 773, -5387, 5669, 825, -5435, 5653, 785, -5483, 5629, 757, -5435, 5645, 749, -5391, 5697, 761, -5371, 5733, 793, -5395, 5709, 813, -5419, 5721, 793, -5411, 5713, 773, -5363, 5701, 773, -5331, 5709, 753, -5375, 5681, 745, -5387, 5649, 753, -5379, 5701, 773, -5459, 5661, 757, -5447, 5657, 753, -5415, 5657, 757, -5395, 5669, 753, -5423, 5681, 737, -5407, 5689, 737, -5403, 5713, 737, -5367, 5689, 753, -5371, 5717, 749, -5415, 5697, 765, -5427, 5681, 749, -5415, 5681, 725, -5387, 5681, 753, -5383, 5677, 757, -5415, 5697, 737, -5411, 5677, 761, -5407, 5689, 765, -5411, 5685, 757, -5391, 5693, 765, -5383, 5701, 741, -5367, 5705, 713, -5383, 5689, 713, -5371, 5701, 733, -5387, 5681, 741, -5403, 5677, 737, -5411, 5681, 733, -5395, 5685, 737, -5363, 5701, 753, -5383, 5709, 741, -5387, 5689, 737, -5379, 5709, 741, -5375, 5713, 769, -5367, 5713, 765, -5379, 5697, 705, -5403, 5685, 721, -5387, 5709, 753, -5399, 5725, 733, -5407, 5689, 705, -5387, 5689, 693, -5399, 5697, 721, -5399, 5689, 713, -5435, 5705, 709, -5419, 5677, 697, -5399, 5705, 721, -5363, 5701, 709, -5363, 5733, 721, -5355, 5733, 713, -5363, 5737, 697, -5375, 5725, 701, -5383, 5701, 721, -5379, 5693, 717, -5379, 5677, 733, -5391, 5701, 701, -5391, 5693, 717, -5387, 5677, 741, -5387, 5685, 733, -5395, 5689, 729, -5387, 5689, 725, -5395, 5713, 713, -5379, 5697, 717, -5371, 5701, 737, -5383, 5697, 749, -5387, 5705, 761, -5395, 5741, 769, -5403, 5709, 753, -5415, 5693, 737, -5427, 5661, 729, -5427, 5685, 717, -5407, 5669, 717, -5403, 5709, 737, -5407, 5701,                                                                                                                                                                                                                                },\r
+{124, 769, -5391, 5701, 757, -5391, 5685, 745, -5383, 5705, 737, -5387, 5693, 737, -5399, 5697, 729, -5403, 5705, 741, -5395, 5709, 737, -5403, 5685, 769, -5419, 5689, 761, -5415, 5677, 753, -5387, 5685, 745, -5375, 5689, 733, -5403, 5689, 709, -5415, 5685, 717, -5387, 5693, 749, -5387, 5689, 749, -5395, 5693, 737, -5395, 5685, 737, -5387, 5697, 749, -5387, 5693, 753, -5387, 5693, 749, -5407, 5701, 749, -5423, 5681, 737, -5415, 5697, 729, -5411, 5689, 737, -5399, 5697, 737, -5395, 5709, 721, -5375, 5693, 741, -5395, 5685, 761, -5395, 5713, 733, -5379, 5709, 733, -5387, 5697, 741, -5399, 5697, 757, -5419, 5693, 753, -5419, 5689, 737, -5403, 5697, 725, -5391, 5697, 729, -5395, 5697, 741, -5375, 5693, 741, -5411, 5685, 757, -5387, 5689, 753, -5391, 5677, 737, -5411, 5673, 717, -5387, 5693, 725, -5379, 5685, 741, -5395, 5697, 769, -5387, 5677, 757, -5387, 5705, 741, -5371, 5709, 733, -5359, 5701, 737, -5363, 5681, 721, -5363, 5689, 753, -5395, 5693, 741, -5423, 5697, 725, -5427, 5689, 745, -5431, 5677, 765, -5407, 5697, 745, -5423, 5725, 765, -5415, 5713, 777, -5415, 5701, 749, -5403, 5697, 721, -5387, 5709, 741, -5371, 5709, 733, -5383, 5685, 733, -5391, 5685, 741, -5379, 5701, 753, -5379, 5685, 761, -5387, 5685, 749, -5415, 5677, 761, -5403, 5661, 749, -5403, 5657, 737, -5395, 5673, 733, -5395, 5693, 725, -5391, 5681, 729, -5411, 5689, 733, -5383, 5705, 765, -5431, 5689, 733, -5427, 5669, 741, -5395, 5681, 757, -5395, 5697, 761, -5379, 5697, 745, -5411, 5693, 753, -5415, 5693, 745, -5411, 5725, 749, -5407, 5693, 773, -5415, 5701, 737, -5395, 5681, 741, -5379, 5681, 757, -5399, 5657, 757, -5423, 5673, 757, -5435, 5713, 737, -5423, 5669, 753, -5411, 5681, 761, -5407, 5693, 749, -5395, 5705, 761, -5379, 5729, 769, -5391, 5737, 765, -5387, 5693, 765, -5391, 5673, 729, -5411, 5669, 713, -5383, 5653, 709, -5395, 5669, 733, -5411, 5657, 773, -5407, 5701, 785, -5399, 5717, 773, -5391, 5697, 757, -5399, 5697, 741, -5395, 5697, 729, -5403, 5665, 717, -5411, 5669, 745, -5415, 5661, 749, -5423, 5677, 749, -5447, 5689, 761, -5403, 5701, 733, -5395, 5689, 769, -5391, 5701, 765, -5391, 5701, 753, -5403, 5717, 769, -5395, 5713, 753, -5379, 5697, 745, -5403, 5689, 733, -5411, 5673, 725, -5391, 5681, 713, -5395, 5669,                                                                                                                                                                                                                                },\r
+{125, 741, -5407, 5661, 757, -5399, 5665, 769, -5407, 5673, 749, -5439, 5681, 757, -5407, 5673, 757, -5403, 5693, 769, -5371, 5701, 773, -5379, 5721, 745, -5399, 5685, 713, -5399, 5693, 745, -5395, 5677, 745, -5403, 5665, 745, -5387, 5681, 741, -5391, 5677, 761, -5411, 5693, 777, -5403, 5693, 757, -5411, 5693, 757, -5435, 5693, 769, -5435, 5669, 753, -5427, 5661, 769, -5443, 5681, 749, -5439, 5681, 765, -5419, 5701, 761, -5403, 5681, 761, -5403, 5693, 757, -5415, 5689, 777, -5435, 5689, 781, -5423, 5685, 789, -5403, 5685, 757, -5395, 5649, 757, -5411, 5669, 761, -5427, 5681, 765, -5411, 5661, 753, -5391, 5661, 737, -5411, 5689, 773, -5399, 5685, 781, -5407, 5673, 761, -5411, 5653, 781, -5415, 5677, 733, -5427, 5681, 745, -5431, 5649, 753, -5447, 5665, 749, -5423, 5677, 737, -5415, 5665, 749, -5431, 5681, 781, -5399, 5681, 797, -5407, 5689, 797, -5399, 5681, 793, -5407, 5693, 769, -5423, 5693, 773, -5391, 5673, 769, -5395, 5681, 781, -5391, 5673, 781, -5395, 5673, 769, -5411, 5653, 753, -5423, 5645, 777, -5431, 5669, 781, -5415, 5669, 769, -5423, 5677, 781, -5411, 5705, 761, -5407, 5681, 761, -5391, 5669, 761, -5423, 5665, 773, -5415, 5657, 773, -5403, 5661, 777, -5407, 5665, 773, -5415, 5661, 757, -5407, 5661, 761, -5411, 5661, 753, -5407, 5653, 789, -5435, 5685, 789, -5435, 5673, 797, -5427, 5661, 777, -5427, 5669, 789, -5431, 5665, 809, -5431, 5665, 817, -5423, 5673, 801, -5415, 5661, 809, -5431, 5661, 797, -5435, 5677, 805, -5423, 5685, 801, -5419, 5657, 809, -5411, 5653, 817, -5439, 5657, 821, -5443, 5669, 801, -5419, 5665, 813, -5399, 5645, 801, -5431, 5637, 805, -5435, 5657, 797, -5443, 5645, 825, -5447, 5657, 801, -5423, 5649, 817, -5419, 5677, 829, -5431, 5653, 829, -5459, 5653, 821, -5447, 5637, 829, -5443, 5657, 813, -5431, 5649, 805, -5451, 5633, 809, -5447, 5641, 821, -5455, 5645, 813, -5439, 5657, 821, -5423, 5685, 849, -5423, 5677, 841, -5435, 5657, 813, -5435, 5637, 797, -5447, 5633, 805, -5459, 5641, 809, -5451, 5629, 833, -5439, 5657, 837, -5463, 5673, 877, -5459, 5673, 849, -5455, 5653, 825, -5459, 5641, 817, -5451, 5637, 805, -5459, 5653, 793, -5431, 5637, 845, -5439, 5637, 837, -5455, 5641, 829, -5427, 5625, 833, -5431, 5621, 825, -5435, 5629, 809, -5447, 5637, 821, -5431, 5629, 833, -5447, 5633,                                                                                                                                                                                                },\r
+{124, 817, -5443, 5649, 829, -5427, 5637, 821, -5447, 5641, 853, -5467, 5649, 841, -5447, 5653, 825, -5431, 5645, 821, -5455, 5629, 821, -5463, 5621, 821, -5471, 5641, 833, -5455, 5649, 861, -5463, 5637, 857, -5439, 5673, 853, -5439, 5641, 857, -5423, 5621, 833, -5467, 5621, 817, -5459, 5641, 833, -5455, 5625, 857, -5455, 5621, 837, -5467, 5629, 829, -5467, 5621, 841, -5459, 5633, 849, -5455, 5625, 865, -5455, 5641, 849, -5455, 5661, 853, -5475, 5669, 849, -5475, 5645, 865, -5451, 5629, 825, -5431, 5621, 801, -5439, 5637, 813, -5463, 5633, 833, -5471, 5625, 845, -5451, 5617, 845, -5447, 5617, 805, -5447, 5617, 825, -5459, 5625, 861, -5459, 5617, 861, -5487, 5621, 845, -5495, 5625, 837, -5467, 5629, 829, -5443, 5645, 829, -5443, 5625, 845, -5459, 5609, 849, -5467, 5633, 861, -5471, 5649, 849, -5455, 5641, 853, -5475, 5633, 845, -5483, 5617, 837, -5475, 5633, 845, -5471, 5621, 821, -5451, 5617, 825, -5447, 5625, 833, -5459, 5633, 829, -5459, 5637, 849, -5439, 5645, 849, -5475, 5629, 845, -5475, 5617, 861, -5455, 5597, 837, -5443, 5601, 829, -5435, 5629, 841, -5467, 5621, 845, -5455, 5637, 865, -5451, 5629, 841, -5459, 5629, 833, -5475, 5625, 809, -5471, 5621, 833, -5467, 5633, 837, -5439, 5609, 841, -5447, 5625, 841, -5447, 5653, 869, -5447, 5641, 845, -5451, 5645, 857, -5463, 5645, 837, -5459, 5617, 845, -5463, 5621, 829, -5499, 5629, 845, -5491, 5621, 849, -5463, 5629, 841, -5439, 5633, 833, -5451, 5617, 841, -5483, 5617, 837, -5463, 5637, 833, -5483, 5633, 853, -5459, 5609, 833, -5439, 5625, 837, -5443, 5621, 837, -5459, 5633, 845, -5463, 5641, 837, -5443, 5609, 853, -5447, 5629, 829, -5463, 5625, 833, -5499, 5613, 825, -5483, 5597, 809, -5463, 5609, 801, -5447, 5617, 825, -5451, 5617, 821, -5455, 5621, 857, -5467, 5629, 861, -5463, 5657, 853, -5463, 5637, 857, -5495, 5637, 837, -5499, 5613, 853, -5467, 5621, 829, -5455, 5621, 821, -5455, 5613, 813, -5467, 5625, 821, -5459, 5613, 817, -5447, 5625, 845, -5459, 5625, 845, -5451, 5653, 845, -5439, 5641, 865, -5459, 5617, 853, -5463, 5641, 861, -5491, 5641, 861, -5471, 5637, 853, -5447, 5641, 825, -5459, 5625, 825, -5467, 5629, 805, -5455, 5625, 833, -5467, 5613, 849, -5451, 5621, 829, -5439, 5629, 837, -5451, 5633, 845, -5455, 5633, 849, -5443, 5629,                                                                                                                                                                                                                                },\r
+{124, 853, -5435, 5617, 841, -5459, 5621, 837, -5463, 5633, 833, -5459, 5617, 837, -5475, 5629, 817, -5483, 5613, 825, -5471, 5625, 817, -5467, 5629, 825, -5455, 5633, 817, -5459, 5633, 813, -5467, 5633, 813, -5491, 5625, 825, -5475, 5637, 833, -5451, 5637, 833, -5451, 5641, 829, -5463, 5629, 853, -5431, 5637, 817, -5455, 5629, 821, -5447, 5625, 821, -5463, 5629, 821, -5459, 5637, 841, -5455, 5633, 817, -5447, 5625, 829, -5455, 5633, 817, -5427, 5625, 805, -5431, 5645, 825, -5447, 5617, 809, -5455, 5653, 813, -5459, 5629, 845, -5455, 5645, 833, -5455, 5653, 821, -5451, 5645, 817, -5455, 5629, 809, -5447, 5641, 813, -5443, 5645, 809, -5443, 5653, 805, -5431, 5661, 817, -5431, 5649, 829, -5431, 5633, 801, -5435, 5649, 805, -5451, 5641, 797, -5475, 5641, 801, -5467, 5625, 813, -5463, 5645, 793, -5463, 5649, 797, -5459, 5645, 813, -5443, 5653, 801, -5415, 5637, 801, -5395, 5665, 797, -5423, 5641, 821, -5427, 5657, 813, -5431, 5645, 805, -5411, 5657, 809, -5407, 5649, 813, -5431, 5637, 801, -5423, 5641, 797, -5447, 5633, 825, -5443, 5641, 809, -5451, 5641, 797, -5459, 5637, 785, -5455, 5629, 789, -5471, 5629, 793, -5467, 5641, 789, -5463, 5653, 801, -5419, 5657, 785, -5431, 5657, 797, -5443, 5681, 813, -5443, 5689, 829, -5443, 5641, 813, -5459, 5629, 809, -5443, 5629, 769, -5455, 5637, 773, -5431, 5637, 785, -5427, 5625, 793, -5431, 5645, 801, -5447, 5637, 785, -5455, 5637, 789, -5447, 5637, 801, -5419, 5657, 793, -5419, 5693, 789, -5423, 5693, 789, -5427, 5677, 805, -5419, 5681, 789, -5423, 5645, 781, -5431, 5645, 769, -5403, 5649, 789, -5415, 5645, 777, -5455, 5653, 805, -5443, 5665, 809, -5431, 5649, 785, -5431, 5661, 785, -5423, 5665, 797, -5427, 5665, 793, -5415, 5661, 789, -5443, 5661, 769, -5451, 5645, 769, -5439, 5653, 777, -5443, 5665, 781, -5427, 5653, 765, -5423, 5669, 757, -5435, 5661, 781, -5447, 5669, 769, -5431, 5661, 793, -5415, 5669, 793, -5439, 5657, 785, -5447, 5649, 793, -5443, 5657, 777, -5435, 5645, 765, -5415, 5653, 761, -5395, 5653, 781, -5399, 5669, 781, -5399, 5689, 785, -5431, 5653, 789, -5423, 5653, 781, -5447, 5657, 773, -5435, 5649, 765, -5431, 5669, 761, -5431, 5653, 753, -5423, 5665, 765, -5403, 5657, 777, -5427, 5645, 765, -5435, 5661, 757, -5375, 5657, 753, -5371, 5681,                                                                                                                                                                                                                                },\r
+{124, 745, -5323, 5597, 813, -5495, 5669, 865, -5487, 5697, 813, -5411, 5693, 821, -5435, 5673, 801, -5487, 5641, 765, -5515, 5665, 765, -5479, 5661, 765, -5439, 5665, 789, -5407, 5673, 781, -5431, 5661, 741, -5435, 5653, 773, -5435, 5653, 765, -5411, 5661, 765, -5415, 5657, 793, -5415, 5653, 793, -5419, 5649, 825, -5431, 5673, 825, -5451, 5661, 809, -5463, 5633, 773, -5459, 5629, 773, -5419, 5625, 781, -5419, 5641, 769, -5403, 5661, 781, -5379, 5677, 797, -5367, 5673, 745, -5383, 5665, 757, -5387, 5681, 773, -5423, 5661, 761, -5443, 5621, 793, -5471, 5633, 809, -5479, 5641, 821, -5495, 5617, 849, -5507, 5621, 849, -5515, 5629, 825, -5507, 5629, 861, -5491, 5637, 853, -5479, 5641, 841, -5447, 5625, 805, -5459, 5645, 777, -5439, 5633, 789, -5443, 5661, 789, -5459, 5657, 805, -5459, 5657, 829, -5495, 5645, 817, -5483, 5617, 821, -5471, 5625, 813, -5483, 5629, 797, -5483, 5617, 809, -5491, 5593, 805, -5491, 5613, 805, -5475, 5605, 805, -5447, 5613, 805, -5459, 5629, 793, -5447, 5629, 773, -5451, 5617, 801, -5435, 5629, 809, -5451, 5617, 821, -5471, 5633, 833, -5503, 5621, 825, -5499, 5609, 801, -5479, 5609, 845, -5479, 5613, 817, -5491, 5605, 837, -5479, 5629, 813, -5451, 5629, 833, -5447, 5665, 837, -5451, 5641, 821, -5455, 5637, 793, -5451, 5653, 809, -5443, 5653, 821, -5435, 5649, 837, -5459, 5629, 805, -5471, 5617, 813, -5479, 5601, 817, -5459, 5625, 821, -5479, 5641, 833, -5487, 5629, 809, -5491, 5621, 837, -5475, 5629, 813, -5439, 5609, 801, -5423, 5629, 809, -5423, 5641, 817, -5431, 5641, 813, -5447, 5645, 849, -5439, 5649, 821, -5427, 5625, 833, -5447, 5649, 845, -5495, 5629, 849, -5499, 5621, 825, -5503, 5605, 797, -5495, 5605, 829, -5491, 5625, 829, -5483, 5669, 829, -5483, 5645, 841, -5471, 5617, 817, -5447, 5625, 809, -5427, 5637, 821, -5435, 5681, 825, -5455, 5661, 825, -5439, 5609, 849, -5411, 5613, 845, -5419, 5629, 837, -5463, 5633, 841, -5475, 5593, 849, -5479, 5617, 825, -5475, 5629, 813, -5463, 5621, 813, -5443, 5625, 817, -5451, 5637, 813, -5443, 5629, 817, -5463, 5633, 821, -5463, 5645, 825, -5463, 5637, 829, -5447, 5633, 829, -5447, 5641, 841, -5443, 5641, 857, -5451, 5645, 845, -5459, 5649, 829, -5479, 5637, 825, -5479, 5649, 813, -5455, 5625, 817, -5451, 5629, 813, -5427, 5621,                                                                                                                                                                                                                                },\r
+{124, 809, -5451, 5637, 837, -5463, 5641, 829, -5463, 5617, 841, -5451, 5633, 825, -5447, 5637, 841, -5439, 5669, 837, -5455, 5645, 821, -5415, 5661, 845, -5435, 5657, 833, -5451, 5657, 821, -5463, 5645, 825, -5451, 5625, 789, -5455, 5633, 793, -5447, 5629, 829, -5439, 5629, 817, -5431, 5613, 833, -5439, 5633, 841, -5447, 5633, 829, -5451, 5653, 841, -5443, 5625, 837, -5443, 5637, 837, -5451, 5641, 845, -5471, 5633, 829, -5471, 5621, 829, -5483, 5629, 849, -5483, 5633, 833, -5479, 5633, 825, -5487, 5601, 825, -5475, 5613, 845, -5479, 5629, 861, -5463, 5645, 837, -5459, 5653, 829, -5447, 5637, 833, -5443, 5641, 849, -5443, 5653, 853, -5439, 5641, 841, -5467, 5617, 829, -5471, 5593, 829, -5479, 5621, 821, -5467, 5625, 833, -5455, 5597, 841, -5463, 5601, 849, -5479, 5609, 849, -5463, 5625, 849, -5455, 5629, 849, -5447, 5629, 837, -5443, 5633, 845, -5447, 5673, 861, -5471, 5649, 845, -5455, 5637, 861, -5451, 5625, 837, -5459, 5637, 845, -5475, 5629, 833, -5479, 5633, 849, -5499, 5621, 865, -5471, 5605, 865, -5479, 5657, 833, -5475, 5633, 841, -5455, 5621, 825, -5451, 5629, 849, -5459, 5633, 865, -5463, 5621, 857, -5483, 5621, 853, -5475, 5621, 861, -5467, 5617, 857, -5447, 5621, 853, -5455, 5617, 857, -5459, 5637, 841, -5475, 5621, 857, -5475, 5597, 861, -5491, 5633, 857, -5479, 5601, 837, -5479, 5601, 837, -5475, 5617, 841, -5463, 5617, 857, -5471, 5621, 865, -5455, 5613, 857, -5459, 5581, 857, -5459, 5609, 873, -5487, 5605, 865, -5503, 5593, 849, -5483, 5593, 841, -5467, 5613, 849, -5467, 5609, 853, -5471, 5617, 853, -5459, 5641, 853, -5459, 5633, 865, -5459, 5645, 849, -5455, 5637, 841, -5455, 5605, 845, -5475, 5601, 849, -5463, 5601, 865, -5459, 5617, 841, -5459, 5601, 865, -5455, 5621, 889, -5475, 5621, 889, -5483, 5649, 869, -5491, 5629, 861, -5459, 5621, 841, -5447, 5621, 825, -5431, 5621, 809, -5443, 5601, 833, -5475, 5605, 833, -5475, 5605, 841, -5487, 5613, 873, -5467, 5601, 861, -5463, 5613, 853, -5475, 5597, 865, -5471, 5617, 881, -5479, 5617, 869, -5463, 5617, 865, -5475, 5625, 869, -5475, 5601, 845, -5455, 5613, 817, -5459, 5617, 833, -5475, 5593, 841, -5455, 5613, 877, -5467, 5637, 889, -5487, 5653, 881, -5491, 5625, 873, -5467, 5621, 853, -5459, 5641, 849, -5459, 5625, 829, -5447, 5601,                                                                                                                                                                                                                                },\r
+{124, 845, -5479, 5597, 853, -5495, 5597, 853, -5483, 5593, 853, -5483, 5593, 853, -5467, 5593, 865, -5467, 5645, 865, -5455, 5629, 849, -5463, 5585, 869, -5467, 5597, 857, -5467, 5605, 861, -5463, 5629, 857, -5463, 5629, 861, -5447, 5641, 873, -5443, 5637, 861, -5439, 5625, 841, -5471, 5597, 829, -5487, 5593, 849, -5487, 5597, 849, -5503, 5625, 869, -5491, 5617, 873, -5463, 5613, 873, -5447, 5605, 857, -5451, 5617, 849, -5475, 5637, 849, -5479, 5625, 853, -5499, 5617, 857, -5479, 5637, 857, -5459, 5625, 853, -5451, 5593, 857, -5467, 5625, 849, -5475, 5621, 853, -5491, 5609, 849, -5483, 5597, 853, -5503, 5605, 861, -5511, 5597, 853, -5495, 5589, 833, -5451, 5593, 849, -5431, 5629, 833, -5447, 5625, 857, -5479, 5625, 853, -5491, 5605, 853, -5487, 5581, 853, -5483, 5593, 857, -5483, 5581, 841, -5491, 5585, 873, -5455, 5609, 873, -5479, 5613, 885, -5455, 5609, 889, -5479, 5637, 897, -5491, 5637, 861, -5475, 5613, 833, -5435, 5649, 857, -5423, 5653, 849, -5455, 5629, 841, -5479, 5601, 833, -5507, 5605, 841, -5511, 5597, 849, -5475, 5593, 857, -5487, 5617, 881, -5479, 5597, 865, -5479, 5617, 885, -5463, 5621, 885, -5459, 5629, 885, -5443, 5649, 865, -5447, 5641, 857, -5459, 5637, 833, -5467, 5609, 849, -5463, 5621, 837, -5463, 5605, 845, -5475, 5601, 833, -5487, 5593, 841, -5511, 5573, 845, -5491, 5605, 841, -5475, 5621, 845, -5475, 5621, 853, -5447, 5617, 841, -5451, 5629, 861, -5467, 5617, 873, -5475, 5617, 853, -5455, 5605, 837, -5459, 5621, 841, -5467, 5625, 849, -5467, 5633, 877, -5471, 5613, 885, -5479, 5617, 869, -5495, 5597, 873, -5491, 5633, 833, -5459, 5617, 841, -5459, 5629, 845, -5447, 5617, 853, -5483, 5609, 849, -5463, 5605, 865, -5479, 5609, 865, -5479, 5613, 873, -5479, 5605, 865, -5479, 5621, 857, -5483, 5609, 861, -5463, 5625, 877, -5475, 5629, 877, -5479, 5653, 873, -5463, 5629, 869, -5467, 5625, 865, -5447, 5601, 825, -5467, 5613, 833, -5487, 5605, 817, -5503, 5597, 837, -5499, 5577, 845, -5503, 5601, 853, -5495, 5613, 865, -5471, 5629, 881, -5467, 5617, 877, -5459, 5609, 865, -5479, 5629, 853, -5479, 5625, 853, -5475, 5613, 877, -5471, 5617, 877, -5463, 5601, 865, -5467, 5609, 841, -5459, 5609, 865, -5471, 5585, 849, -5467, 5597, 845, -5463, 5613, 849, -5471, 5605, 841, -5451, 5605,                                                                                                                                                                                                                                },\r
+{124, 869, -5467, 5633, 853, -5463, 5605, 845, -5479, 5621, 865, -5487, 5625, 853, -5483, 5597, 857, -5487, 5585, 869, -5519, 5609, 853, -5507, 5581, 869, -5479, 5613, 869, -5459, 5625, 857, -5483, 5629, 857, -5483, 5641, 861, -5463, 5625, 881, -5451, 5621, 849, -5447, 5613, 849, -5471, 5629, 853, -5479, 5593, 853, -5475, 5605, 861, -5475, 5617, 853, -5479, 5617, 869, -5483, 5589, 841, -5479, 5609, 857, -5475, 5613, 869, -5467, 5613, 853, -5471, 5637, 857, -5459, 5613, 873, -5459, 5641, 849, -5447, 5617, 837, -5467, 5617, 829, -5463, 5593, 813, -5475, 5609, 837, -5467, 5601, 845, -5487, 5585, 841, -5475, 5601, 837, -5483, 5597, 849, -5487, 5609, 841, -5475, 5609, 857, -5471, 5609, 865, -5467, 5625, 861, -5467, 5625, 853, -5487, 5601, 865, -5463, 5617, 829, -5451, 5625, 865, -5439, 5653, 853, -5455, 5617, 865, -5471, 5617, 853, -5467, 5621, 853, -5471, 5617, 857, -5475, 5613, 865, -5479, 5617, 853, -5467, 5625, 841, -5455, 5625, 825, -5447, 5609, 841, -5455, 5593, 825, -5463, 5621, 841, -5471, 5609, 849, -5475, 5613, 853, -5471, 5621, 845, -5467, 5633, 849, -5463, 5637, 861, -5463, 5629, 869, -5439, 5629, 861, -5451, 5645, 849, -5459, 5637, 837, -5491, 5617, 825, -5483, 5605, 813, -5483, 5597, 833, -5479, 5605, 857, -5471, 5613, 849, -5475, 5621, 849, -5459, 5593, 853, -5463, 5625, 849, -5471, 5621, 853, -5487, 5621, 857, -5491, 5625, 853, -5455, 5609, 857, -5447, 5617, 853, -5439, 5609, 857, -5447, 5629, 853, -5459, 5629, 857, -5455, 5621, 849, -5491, 5609, 829, -5491, 5613, 829, -5475, 5609, 829, -5479, 5609, 841, -5471, 5617, 857, -5475, 5609, 845, -5463, 5613, 841, -5475, 5613, 849, -5479, 5609, 853, -5467, 5605, 837, -5447, 5617, 873, -5455, 5629, 865, -5475, 5621, 845, -5499, 5613, 853, -5479, 5637, 841, -5455, 5597, 857, -5463, 5613, 865, -5467, 5613, 845, -5471, 5613, 865, -5483, 5625, 833, -5467, 5601, 845, -5463, 5609, 857, -5451, 5609, 849, -5467, 5621, 869, -5483, 5625, 881, -5479, 5613, 857, -5463, 5589, 841, -5435, 5621, 857, -5487, 5625, 853, -5483, 5605, 869, -5455, 5609, 841, -5479, 5597, 829, -5459, 5621, 845, -5487, 5613, 865, -5479, 5621, 877, -5459, 5625, 857, -5475, 5601, 849, -5479, 5609, 849, -5487, 5605, 857, -5491, 5609, 849, -5491, 5605, 833, -5483, 5593, 841, -5475, 5601,                                                                                                                                                                                                                                },\r
+{124, 845, -5471, 5617, 849, -5459, 5625, 873, -5487, 5637, 881, -5491, 5625, 873, -5503, 5609, 857, -5487, 5597, 853, -5455, 5617, 857, -5479, 5605, 869, -5479, 5609, 865, -5467, 5613, 861, -5467, 5633, 853, -5471, 5601, 885, -5487, 5633, 885, -5483, 5617, 857, -5483, 5593, 877, -5507, 5593, 849, -5495, 5605, 821, -5495, 5593, 833, -5487, 5585, 837, -5495, 5597, 853, -5487, 5609, 857, -5451, 5621, 893, -5443, 5617, 901, -5463, 5641, 865, -5459, 5653, 873, -5487, 5625, 865, -5495, 5633, 869, -5511, 5625, 865, -5487, 5613, 861, -5483, 5597, 873, -5483, 5589, 869, -5475, 5617, 881, -5495, 5629, 853, -5487, 5613, 849, -5495, 5617, 873, -5487, 5609, 869, -5475, 5613, 845, -5471, 5585, 841, -5475, 5605, 849, -5459, 5605, 865, -5459, 5597, 877, -5479, 5605, 865, -5483, 5581, 845, -5487, 5593, 829, -5475, 5573, 829, -5459, 5605, 841, -5467, 5613, 853, -5487, 5597, 853, -5499, 5609, 849, -5475, 5625, 845, -5471, 5617, 837, -5483, 5621, 869, -5475, 5633, 861, -5479, 5609, 837, -5487, 5589, 813, -5483, 5621, 821, -5479, 5605, 845, -5483, 5621, 849, -5463, 5641, 861, -5459, 5617, 865, -5471, 5625, 873, -5459, 5625, 861, -5451, 5633, 861, -5475, 5645, 865, -5483, 5629, 841, -5479, 5649, 857, -5487, 5637, 829, -5463, 5613, 825, -5431, 5641, 821, -5431, 5621, 825, -5451, 5633, 813, -5479, 5633, 853, -5451, 5617, 849, -5447, 5601, 821, -5451, 5601, 837, -5463, 5621, 837, -5451, 5625, 833, -5455, 5621, 821, -5463, 5633, 841, -5463, 5625, 817, -5451, 5629, 821, -5467, 5621, 801, -5475, 5625, 817, -5479, 5609, 817, -5471, 5625, 833, -5447, 5629, 825, -5471, 5617, 825, -5479, 5613, 841, -5467, 5621, 837, -5439, 5629, 829, -5455, 5633, 829, -5463, 5637, 841, -5451, 5625, 849, -5435, 5641, 841, -5435, 5645, 833, -5467, 5653, 821, -5467, 5613, 829, -5459, 5617, 817, -5459, 5605, 813, -5451, 5597, 797, -5475, 5617, 805, -5467, 5617, 829, -5463, 5621, 845, -5463, 5629, 829, -5463, 5621, 833, -5451, 5625, 821, -5443, 5645, 809, -5435, 5653, 833, -5443, 5653, 845, -5435, 5621, 813, -5423, 5637, 817, -5455, 5657, 825, -5463, 5641, 833, -5463, 5629, 829, -5487, 5629, 825, -5495, 5613, 837, -5491, 5617, 833, -5475, 5625, 845, -5451, 5657, 845, -5455, 5653, 845, -5471, 5629, 837, -5455, 5649, 833, -5451, 5665, 817, -5443, 5637,                                                                                                                                                                                                                                },\r
+{125, 821, -5427, 5657, 829, -5423, 5617, 829, -5451, 5609, 833, -5451, 5609, 833, -5459, 5617, 829, -5471, 5613, 825, -5471, 5601, 825, -5459, 5613, 825, -5439, 5645, 833, -5447, 5653, 841, -5451, 5641, 829, -5451, 5637, 821, -5451, 5641, 809, -5431, 5649, 825, -5427, 5621, 833, -5459, 5625, 837, -5499, 5609, 825, -5519, 5597, 825, -5507, 5609, 837, -5495, 5629, 861, -5471, 5649, 861, -5463, 5633, 857, -5423, 5633, 797, -5451, 5701, 825, -5431, 5657, 845, -5411, 5629, 821, -5399, 5609, 773, -5451, 5641, 773, -5491, 5609, 833, -5479, 5621, 865, -5483, 5601, 857, -5471, 5601, 821, -5471, 5597, 837, -5487, 5633, 841, -5479, 5621, 853, -5439, 5621, 845, -5415, 5633, 849, -5439, 5649, 857, -5431, 5669, 849, -5455, 5657, 841, -5451, 5629, 853, -5471, 5633, 841, -5467, 5625, 809, -5443, 5637, 825, -5487, 5657, 845, -5495, 5625, 845, -5479, 5601, 837, -5455, 5617, 825, -5439, 5625, 817, -5471, 5625, 833, -5475, 5621, 849, -5431, 5629, 849, -5399, 5649, 825, -5439, 5645, 833, -5455, 5661, 861, -5459, 5657, 893, -5439, 5641, 889, -5415, 5621, 841, -5407, 5621, 809, -5423, 5653, 833, -5455, 5645, 869, -5471, 5609, 861, -5467, 5617, 821, -5479, 5625, 825, -5475, 5645, 833, -5463, 5617, 857, -5443, 5649, 837, -5399, 5641, 821, -5411, 5653, 837, -5427, 5665, 857, -5459, 5673, 897, -5459, 5641, 889, -5435, 5633, 849, -5447, 5645, 833, -5459, 5649, 845, -5467, 5629, 869, -5471, 5641, 861, -5495, 5677, 873, -5499, 5637, 877, -5479, 5605, 857, -5447, 5597, 837, -5447, 5609, 813, -5447, 5669, 869, -5471, 5633, 865, -5455, 5641, 885, -5467, 5677, 885, -5467, 5641, 877, -5439, 5597, 877, -5415, 5593, 853, -5435, 5613, 857, -5479, 5597, 865, -5511, 5597, 869, -5495, 5581, 881, -5471, 5581, 849, -5455, 5593, 841, -5451, 5605, 853, -5459, 5629, 825, -5471, 5605, 829, -5467, 5625, 845, -5463, 5625, 849, -5459, 5629, 877, -5487, 5613, 881, -5499, 5605, 857, -5503, 5597, 853, -5487, 5585, 861, -5479, 5585, 853, -5475, 5605, 869, -5475, 5589, 877, -5475, 5613, 869, -5467, 5613, 881, -5471, 5601, 905, -5491, 5625, 917, -5491, 5625, 897, -5479, 5629, 901, -5459, 5617, 905, -5487, 5645, 885, -5491, 5637, 901, -5483, 5625, 865, -5479, 5613, 865, -5479, 5601, 861, -5479, 5609, 845, -5491, 5577, 849, -5503, 5569, 845, -5499, 5585, 869, -5499, 5617,                                                                                                                                                                                                },\r
+{125, 881, -5483, 5621, 877, -5467, 5637, 889, -5451, 5621, 877, -5443, 5629, 877, -5451, 5621, 889, -5471, 5633, 877, -5487, 5633, 881, -5479, 5649, 873, -5451, 5629, 877, -5443, 5625, 873, -5435, 5637, 853, -5439, 5641, 857, -5447, 5617, 845, -5483, 5605, 861, -5463, 5613, 857, -5415, 5613, 865, -5435, 5617, 873, -5463, 5617, 865, -5459, 5621, 873, -5463, 5641, 889, -5455, 5621, 881, -5459, 5629, 889, -5467, 5641, 885, -5471, 5653, 885, -5435, 5657, 865, -5431, 5633, 845, -5439, 5629, 849, -5459, 5633, 845, -5463, 5629, 857, -5479, 5629, 865, -5455, 5621, 873, -5455, 5629, 861, -5439, 5633, 869, -5439, 5629, 885, -5451, 5633, 881, -5463, 5649, 885, -5459, 5613, 869, -5455, 5617, 869, -5487, 5617, 845, -5471, 5629, 873, -5483, 5633, 869, -5475, 5613, 877, -5451, 5613, 897, -5427, 5625, 881, -5439, 5629, 893, -5423, 5649, 913, -5447, 5653, 905, -5463, 5649, 905, -5479, 5613, 921, -5499, 5613, 897, -5467, 5609, 865, -5459, 5621, 861, -5459, 5629, 841, -5475, 5637, 837, -5463, 5645, 845, -5431, 5625, 841, -5423, 5637, 873, -5419, 5625, 873, -5399, 5637, 889, -5431, 5613, 905, -5491, 5625, 909, -5539, 5613, 901, -5579, 5625, 933, -5583, 5601, 941, -5583, 5597, 921, -5543, 5613, 897, -5479, 5605, 881, -5447, 5609, 833, -5447, 5589, 809, -5463, 5597, 801, -5455, 5601, 797, -5427, 5605, 809, -5415, 5605, 849, -5419, 5609, 861, -5447, 5613, 841, -5451, 5597, 817, -5451, 5577, 841, -5467, 5577, 841, -5439, 5533, 885, -5479, 5569, 877, -5519, 5609, 881, -5435, 5593, 889, -5427, 5585, 889, -5431, 5565, 881, -5447, 5597, 849, -5471, 5629, 853, -5435, 5565, 921, -5543, 5597, 945, -5479, 5617, 937, -5455, 5585, 925, -5495, 5597, 917, -5531, 5585, 921, -5523, 5565, 937, -5519, 5561, 929, -5499, 5589, 933, -5535, 5605, 909, -5543, 5601, 909, -5543, 5609, 945, -5575, 5581, 941, -5571, 5557, 925, -5583, 5569, 933, -5603, 5541, 925, -5595, 5541, 925, -5571, 5541, 921, -5563, 5533, 917, -5551, 5537, 917, -5579, 5529, 925, -5579, 5501, 949, -5511, 5541, 953, -5495, 5569, 961, -5511, 5593, 961, -5539, 5581, 933, -5555, 5565, 949, -5555, 5553, 953, -5531, 5513, 941, -5527, 5493, 909, -5543, 5481, 917, -5567, 5457, 909, -5559, 5481, 933, -5551, 5493, 957, -5543, 5501, 981, -5531, 5541, 989, -5531, 5569, 961, -5523, 5569, 941, -5563, 5569,                                                                                                                                                                                                },\r
+{124, 913, -5555, 5565, 917, -5543, 5573, 909, -5559, 5553, 897, -5539, 5533, 893, -5567, 5541, 909, -5571, 5517, 913, -5567, 5505, 937, -5571, 5541, 941, -5579, 5533, 957, -5515, 5545, 969, -5523, 5569, 977, -5603, 5537, 937, -5555, 5525, 933, -5475, 5529, 937, -5447, 5577, 937, -5531, 5549, 893, -5551, 5533, 869, -5531, 5525, 889, -5519, 5509, 893, -5523, 5525, 901, -5615, 5517, 913, -5563, 5497, 905, -5523, 5521, 929, -5459, 5537, 989, -5563, 5549, 965, -5611, 5573, 981, -5503, 5589, 957, -5467, 5585, 981, -5487, 5597, 957, -5543, 5589, 921, -5563, 5541, 913, -5563, 5549, 905, -5543, 5545, 921, -5519, 5553, 925, -5547, 5545, 949, -5567, 5557, 957, -5575, 5561, 929, -5543, 5533, 925, -5507, 5537, 917, -5487, 5533, 933, -5499, 5585, 949, -5507, 5573, 941, -5543, 5537, 941, -5539, 5553, 933, -5511, 5533, 945, -5515, 5549, 925, -5535, 5549, 929, -5555, 5541, 929, -5535, 5533, 917, -5535, 5545, 901, -5527, 5557, 909, -5515, 5561, 901, -5523, 5561, 905, -5531, 5573, 913, -5503, 5561, 901, -5515, 5581, 937, -5543, 5557, 933, -5551, 5557, 913, -5547, 5561, 937, -5523, 5569, 933, -5531, 5565, 913, -5547, 5541, 929, -5547, 5545, 925, -5555, 5525, 917, -5543, 5517, 889, -5519, 5549, 901, -5503, 5557, 917, -5507, 5589, 937, -5531, 5593, 925, -5527, 5561, 921, -5519, 5557, 929, -5519, 5569, 909, -5511, 5549, 909, -5519, 5533, 913, -5535, 5545, 905, -5527, 5541, 913, -5523, 5553, 901, -5523, 5541, 889, -5523, 5553, 921, -5523, 5561, 917, -5503, 5581, 905, -5475, 5581, 897, -5479, 5585, 921, -5503, 5577, 929, -5527, 5545, 917, -5527, 5557, 929, -5535, 5565, 909, -5563, 5557, 917, -5575, 5537, 909, -5539, 5553, 917, -5507, 5569, 913, -5519, 5565, 929, -5515, 5569, 937, -5499, 5609, 921, -5487, 5569, 933, -5511, 5561, 901, -5519, 5581, 881, -5495, 5589, 897, -5483, 5585, 893, -5479, 5569, 913, -5499, 5561, 937, -5543, 5545, 925, -5543, 5541, 909, -5555, 5533, 893, -5507, 5529, 897, -5495, 5541, 901, -5507, 5585, 897, -5503, 5573, 937, -5523, 5585, 901, -5511, 5585, 885, -5491, 5573, 901, -5483, 5581, 909, -5503, 5573, 913, -5535, 5565, 905, -5527, 5549, 893, -5535, 5553, 889, -5507, 5561, 905, -5499, 5577, 905, -5495, 5577, 909, -5499, 5561, 905, -5491, 5557, 901, -5515, 5569, 885, -5519, 5577, 905, -5511, 5561,                                                                                                                                                                                                                                },\r
+{125, 897, -5511, 5589, 917, -5511, 5613, 925, -5511, 5601, 925, -5515, 5569, 901, -5499, 5569, 881, -5483, 5557, 889, -5503, 5585, 881, -5499, 5581, 901, -5519, 5573, 917, -5495, 5573, 893, -5475, 5581, 897, -5487, 5601, 925, -5511, 5553, 885, -5503, 5561, 897, -5495, 5577, 909, -5511, 5585, 913, -5519, 5553, 893, -5511, 5557, 913, -5519, 5553, 905, -5515, 5553, 905, -5499, 5585, 889, -5515, 5593, 901, -5515, 5597, 929, -5503, 5589, 901, -5503, 5581, 917, -5487, 5585, 901, -5499, 5585, 901, -5495, 5573, 885, -5515, 5573, 893, -5507, 5549, 893, -5519, 5561, 901, -5511, 5569, 909, -5503, 5565, 921, -5491, 5573, 917, -5479, 5569, 885, -5499, 5585, 885, -5495, 5565, 897, -5495, 5573, 909, -5507, 5541, 877, -5519, 5577, 889, -5503, 5573, 905, -5519, 5573, 917, -5483, 5593, 921, -5487, 5585, 945, -5495, 5565, 925, -5519, 5609, 937, -5527, 5597, 949, -5523, 5577, 929, -5511, 5549, 881, -5515, 5585, 889, -5539, 5601, 925, -5547, 5549, 929, -5519, 5541, 905, -5531, 5553, 893, -5563, 5597, 893, -5563, 5597, 917, -5495, 5573, 925, -5451, 5573, 881, -5455, 5573, 853, -5463, 5581, 885, -5499, 5589, 905, -5527, 5569, 921, -5523, 5545, 897, -5523, 5557, 901, -5527, 5569, 905, -5515, 5549, 905, -5491, 5557, 909, -5483, 5545, 901, -5475, 5557, 885, -5507, 5585, 901, -5543, 5585, 941, -5539, 5589, 965, -5507, 5569, 949, -5523, 5593, 961, -5491, 5561, 937, -5507, 5557, 913, -5547, 5565, 921, -5563, 5585, 949, -5559, 5585, 937, -5523, 5597, 925, -5515, 5581, 917, -5503, 5573, 889, -5519, 5557, 921, -5499, 5569, 925, -5523, 5581, 929, -5551, 5581, 913, -5543, 5569, 925, -5515, 5573, 945, -5511, 5557, 929, -5491, 5561, 901, -5511, 5565, 909, -5491, 5565, 925, -5499, 5549, 917, -5523, 5561, 917, -5539, 5561, 925, -5531, 5557, 917, -5503, 5569, 905, -5467, 5553, 937, -5479, 5581, 925, -5507, 5549, 921, -5531, 5573, 925, -5551, 5565, 945, -5543, 5569, 929, -5531, 5565, 913, -5539, 5549, 897, -5523, 5561, 889, -5535, 5561, 925, -5511, 5573, 909, -5539, 5557, 913, -5523, 5569, 909, -5531, 5561, 909, -5511, 5561, 929, -5507, 5573, 913, -5507, 5581, 917, -5507, 5577, 921, -5515, 5573, 933, -5527, 5557, 901, -5523, 5569, 897, -5507, 5549, 889, -5507, 5561, 897, -5499, 5569, 929, -5491, 5569, 949, -5535, 5561, 917, -5519, 5565, 913, -5499, 5569,                                                                                                                                                                                                },\r
+{124, 925, -5507, 5573, 929, -5523, 5557, 913, -5519, 5589, 921, -5491, 5565, 933, -5475, 5573, 937, -5475, 5597, 925, -5503, 5589, 933, -5527, 5573, 929, -5527, 5561, 921, -5519, 5565, 921, -5535, 5569, 933, -5523, 5573, 937, -5491, 5577, 929, -5519, 5581, 925, -5535, 5561, 921, -5523, 5577, 937, -5511, 5577, 913, -5483, 5569, 937, -5475, 5585, 929, -5495, 5585, 925, -5499, 5577, 909, -5499, 5557, 909, -5523, 5541, 921, -5511, 5569, 933, -5475, 5561, 913, -5459, 5541, 925, -5503, 5553, 909, -5531, 5557, 901, -5491, 5565, 937, -5495, 5593, 953, -5543, 5557, 973, -5463, 5585, 961, -5487, 5649, 989, -5539, 5553, 965, -5535, 5601, 929, -5571, 5581, 925, -5571, 5533, 945, -5423, 5601, 981, -5455, 5665, 997, -5543, 5629, 981, -5531, 5633, 933, -5491, 5637, 933, -5447, 5617, 929, -5427, 5625, 953, -5439, 5617, 961, -5531, 5589, 961, -5571, 5557, 925, -5531, 5553, 893, -5487, 5565, 929, -5487, 5589, 941, -5567, 5589, 961, -5535, 5581, 953, -5559, 5593, 945, -5515, 5553, 901, -5491, 5581, 881, -5439, 5613, 845, -5431, 5605, 885, -5427, 5609, 897, -5419, 5629, 933, -5451, 5629, 945, -5451, 5629, 873, -5455, 5581, 877, -5503, 5577, 909, -5479, 5605, 925, -5447, 5617, 957, -5511, 5609, 921, -5539, 5629, 877, -5491, 5621, 933, -5479, 5573, 857, -5479, 5613, 849, -5471, 5609, 861, -5447, 5605, 813, -5435, 5605, 869, -5411, 5521, 877, -5459, 5633, 869, -5459, 5621, 925, -5447, 5609, 949, -5511, 5585, 941, -5547, 5593, 909, -5523, 5589, 893, -5471, 5613, 893, -5463, 5613, 885, -5483, 5609, 873, -5463, 5573, 861, -5467, 5561, 857, -5459, 5577, 845, -5463, 5565, 861, -5475, 5585, 877, -5475, 5569, 897, -5479, 5593, 917, -5511, 5625, 937, -5563, 5637, 949, -5587, 5605, 889, -5519, 5585, 889, -5483, 5581, 869, -5463, 5577, 853, -5463, 5565, 861, -5467, 5565, 857, -5491, 5569, 857, -5487, 5569, 873, -5503, 5565, 877, -5523, 5597, 889, -5519, 5601, 937, -5511, 5613, 937, -5511, 5621, 945, -5507, 5605, 913, -5487, 5625, 889, -5499, 5589, 881, -5495, 5569, 881, -5511, 5561, 869, -5503, 5569, 869, -5471, 5577, 873, -5467, 5605, 889, -5483, 5589, 905, -5475, 5601, 865, -5483, 5613, 893, -5471, 5641, 901, -5479, 5593, 897, -5499, 5581, 905, -5495, 5573, 881, -5495, 5573, 881, -5495, 5589, 897, -5491, 5573, 877, -5491, 5565,                                                                                                                                                                                                                                },\r
+{126, 881, -5487, 5581, 885, -5479, 5597, 889, -5495, 5589, 877, -5467, 5613, 885, -5471, 5585, 869, -5487, 5597, 869, -5479, 5569, 865, -5487, 5601, 877, -5503, 5601, 873, -5495, 5585, 917, -5515, 5589, 929, -5531, 5605, 925, -5515, 5613, 905, -5483, 5605, 921, -5495, 5597, 893, -5495, 5613, 889, -5483, 5593, 869, -5479, 5581, 885, -5507, 5569, 865, -5519, 5565, 849, -5495, 5581, 861, -5475, 5593, 909, -5483, 5617, 929, -5499, 5593, 921, -5495, 5601, 921, -5487, 5597, 905, -5495, 5577, 901, -5503, 5561, 873, -5511, 5585, 865, -5491, 5597, 841, -5487, 5581, 877, -5487, 5601, 897, -5479, 5581, 917, -5499, 5577, 917, -5523, 5593, 897, -5511, 5597, 905, -5499, 5593, 909, -5499, 5589, 909, -5511, 5577, 901, -5511, 5585, 913, -5527, 5581, 905, -5531, 5577, 885, -5531, 5561, 889, -5515, 5565, 877, -5491, 5577, 877, -5475, 5573, 905, -5487, 5613, 897, -5483, 5605, 897, -5499, 5589, 889, -5491, 5569, 889, -5491, 5589, 909, -5479, 5577, 909, -5483, 5577, 909, -5499, 5585, 897, -5495, 5577, 901, -5483, 5573, 905, -5507, 5585, 913, -5499, 5589, 921, -5519, 5577, 905, -5547, 5569, 905, -5527, 5577, 901, -5479, 5577, 905, -5467, 5593, 905, -5487, 5609, 905, -5499, 5597, 909, -5507, 5601, 881, -5515, 5585, 889, -5507, 5589, 885, -5515, 5605, 917, -5523, 5589, 909, -5515, 5561, 885, -5499, 5577, 893, -5499, 5585, 909, -5507, 5593, 909, -5487, 5593, 921, -5495, 5593, 909, -5511, 5609, 905, -5483, 5593, 893, -5479, 5577, 881, -5471, 5565, 893, -5491, 5561, 869, -5495, 5561, 889, -5503, 5577, 889, -5515, 5569, 881, -5515, 5581, 869, -5491, 5589, 889, -5495, 5597, 893, -5503, 5589, 913, -5515, 5589, 885, -5523, 5585, 889, -5503, 5593, 889, -5491, 5609, 885, -5503, 5601, 873, -5503, 5573, 873, -5483, 5585, 877, -5491, 5589, 897, -5491, 5597, 889, -5495, 5621, 881, -5503, 5585, 901, -5495, 5589, 921, -5487, 5593, 905, -5495, 5601, 901, -5531, 5589, 885, -5503, 5577, 873, -5495, 5573, 849, -5483, 5605, 869, -5479, 5621, 865, -5479, 5601, 865, -5467, 5597, 853, -5459, 5601, 877, -5459, 5613, 873, -5471, 5605, 881, -5487, 5597, 897, -5499, 5589, 881, -5483, 5601, 889, -5491, 5601, 881, -5507, 5585, 877, -5515, 5597, 845, -5487, 5593, 857, -5467, 5601, 861, -5487, 5609, 873, -5479, 5605, 853, -5479, 5593, 853, -5487, 5617, 849, -5467, 5625, 833, -5467, 5613,                                                                                                                                                                },\r
+{125, 857, -5479, 5577, 865, -5499, 5617, 873, -5503, 5589, 877, -5479, 5577, 861, -5483, 5597, 885, -5495, 5609, 861, -5499, 5589, 877, -5475, 5609, 877, -5467, 5625, 853, -5451, 5609, 853, -5467, 5609, 845, -5479, 5629, 837, -5443, 5621, 829, -5455, 5625, 865, -5471, 5617, 853, -5487, 5597, 857, -5467, 5593, 869, -5483, 5625, 857, -5499, 5617, 865, -5479, 5613, 869, -5463, 5621, 853, -5455, 5621, 837, -5431, 5621, 837, -5439, 5621, 853, -5447, 5613, 869, -5463, 5613, 861, -5479, 5609, 853, -5475, 5621, 829, -5479, 5625, 841, -5467, 5613, 861, -5475, 5613, 873, -5483, 5621, 865, -5479, 5621, 861, -5459, 5633, 873, -5475, 5645, 869, -5495, 5617, 861, -5475, 5613, 841, -5475, 5601, 825, -5467, 5609, 829, -5427, 5609, 841, -5447, 5597, 861, -5459, 5593, 857, -5471, 5597, 837, -5475, 5589, 857, -5475, 5601, 857, -5487, 5597, 857, -5487, 5609, 845, -5495, 5609, 853, -5495, 5585, 865, -5491, 5597, 841, -5491, 5605, 841, -5495, 5605, 853, -5451, 5609, 857, -5455, 5629, 869, -5531, 5585, 849, -5543, 5573, 853, -5523, 5585, 873, -5443, 5569, 885, -5423, 5625, 889, -5483, 5645, 913, -5471, 5617, 885, -5471, 5629, 873, -5447, 5605, 861, -5507, 5625, 865, -5499, 5637, 877, -5487, 5633, 877, -5491, 5545, 841, -5531, 5633, 845, -5423, 5629, 885, -5495, 5581, 881, -5551, 5577, 877, -5503, 5601, 897, -5495, 5597, 889, -5491, 5597, 881, -5515, 5601, 869, -5507, 5597, 837, -5467, 5605, 849, -5435, 5609, 861, -5491, 5609, 861, -5491, 5585, 877, -5499, 5601, 881, -5523, 5557, 901, -5491, 5585, 877, -5627, 5597, 877, -5563, 5457, 897, -5347, 5633, 909, -5443, 5661, 945, -5519, 5601, 893, -5507, 5645, 877, -5439, 5633, 881, -5431, 5645, 889, -5435, 5645, 877, -5471, 5597, 885, -5507, 5601, 897, -5535, 5573, 897, -5519, 5569, 901, -5527, 5561, 905, -5523, 5593, 893, -5503, 5597, 885, -5483, 5601, 897, -5471, 5613, 873, -5543, 5605, 853, -5495, 5521, 873, -5379, 5605, 885, -5395, 5609, 925, -5455, 5609, 889, -5499, 5609, 893, -5495, 5593, 901, -5467, 5625, 901, -5543, 5649, 881, -5575, 5481, 893, -5379, 5533, 921, -5399, 5673, 945, -5563, 5581, 909, -5595, 5589, 865, -5547, 5629, 897, -5459, 5633, 909, -5423, 5617, 897, -5463, 5633, 913, -5483, 5585, 901, -5483, 5593, 905, -5495, 5589, 909, -5507, 5581, 889, -5511, 5561, 913, -5527, 5585,                                                                                                                                                                                                },\r
+{125, 913, -5487, 5581, 897, -5475, 5585, 885, -5487, 5593, 889, -5515, 5525, 901, -5451, 5589, 905, -5511, 5593, 941, -5511, 5545, 945, -5487, 5617, 981, -5539, 5601, 949, -5515, 5589, 897, -5503, 5633, 917, -5487, 5613, 917, -5483, 5601, 905, -5467, 5613, 929, -5483, 5601, 925, -5515, 5597, 933, -5511, 5589, 937, -5511, 5573, 937, -5531, 5569, 941, -5515, 5581, 945, -5495, 5601, 945, -5467, 5581, 909, -5491, 5573, 921, -5499, 5565, 909, -5507, 5585, 909, -5499, 5585, 929, -5479, 5605, 925, -5483, 5605, 945, -5495, 5581, 949, -5495, 5561, 937, -5483, 5569, 921, -5487, 5581, 901, -5499, 5581, 929, -5503, 5577, 929, -5495, 5577, 909, -5487, 5593, 905, -5479, 5597, 921, -5487, 5589, 933, -5471, 5593, 921, -5483, 5589, 921, -5479, 5601, 937, -5487, 5597, 937, -5499, 5585, 957, -5511, 5589, 949, -5515, 5601, 933, -5511, 5565, 933, -5507, 5573, 937, -5483, 5557, 933, -5479, 5585, 941, -5471, 5613, 961, -5495, 5597, 937, -5515, 5605, 953, -5507, 5593, 933, -5487, 5585, 945, -5495, 5565, 941, -5507, 5573, 941, -5511, 5585, 921, -5515, 5561, 929, -5519, 5577, 929, -5511, 5565, 929, -5499, 5585, 941, -5499, 5533, 933, -5499, 5565, 937, -5507, 5581, 953, -5515, 5573, 945, -5499, 5589, 949, -5499, 5573, 981, -5503, 5573, 953, -5507, 5549, 945, -5495, 5565, 937, -5487, 5593, 929, -5459, 5581, 941, -5471, 5601, 933, -5499, 5589, 953, -5551, 5593, 941, -5547, 5589, 941, -5527, 5589, 953, -5519, 5577, 977, -5527, 5565, 973, -5535, 5561, 941, -5547, 5545, 973, -5539, 5561, 957, -5511, 5565, 941, -5511, 5577, 949, -5515, 5581, 953, -5511, 5581, 961, -5503, 5565, 937, -5483, 5565, 941, -5467, 5561, 945, -5487, 5569, 945, -5523, 5541, 945, -5555, 5553, 961, -5527, 5553, 973, -5527, 5557, 957, -5519, 5553, 945, -5527, 5557, 957, -5507, 5593, 945, -5515, 5561, 945, -5515, 5537, 949, -5515, 5553, 961, -5531, 5537, 969, -5543, 5549, 937, -5523, 5561, 933, -5523, 5557, 961, -5535, 5545, 977, -5535, 5553, 945, -5535, 5561, 933, -5527, 5561, 949, -5511, 5557, 965, -5499, 5549, 957, -5499, 5569, 961, -5507, 5581, 945, -5511, 5565, 965, -5511, 5541, 973, -5519, 5541, 953, -5527, 5557, 953, -5499, 5565, 965, -5507, 5557, 941, -5503, 5569, 953, -5507, 5557, 965, -5511, 5529, 953, -5507, 5565, 945, -5503, 5565, 961, -5507, 5573, 965, -5527, 5541,                                                                                                                                                                                                },\r
+{125, 969, -5535, 5553, 957, -5527, 5553, 965, -5531, 5557, 981, -5531, 5553, 961, -5539, 5545, 953, -5547, 5573, 925, -5639, 5577, 861, -5703, 5373, 937, -5359, 5429, 1001, -5243, 5697, 1085, -5523, 5617, 1041, -5603, 5573, 937, -5587, 5593, 949, -5471, 5593, 1005, -5423, 5617, 1001, -5443, 5609, 973, -5519, 5561, 973, -5567, 5521, 953, -5555, 5541, 937, -5527, 5521, 941, -5539, 5517, 941, -5539, 5537, 969, -5527, 5573, 973, -5515, 5553, 969, -5523, 5569, 993, -5475, 5593, 981, -5511, 5597, 969, -5503, 5509, 969, -5479, 5585, 985, -5539, 5569, 1001, -5543, 5541, 941, -5595, 5537, 941, -5523, 5445, 957, -5435, 5589, 985, -5479, 5593, 1013, -5519, 5569, 953, -5555, 5561, 957, -5543, 5577, 965, -5523, 5577, 973, -5511, 5589, 961, -5543, 5549, 973, -5507, 5541, 997, -5559, 5517, 997, -5563, 5517, 985, -5583, 5529, 1009, -5555, 5513, 989, -5551, 5537, 997, -5543, 5553, 1001, -5499, 5573, 985, -5491, 5597, 989, -5491, 5573, 997, -5491, 5585, 969, -5523, 5549, 993, -5531, 5533, 965, -5551, 5533, 981, -5535, 5521, 981, -5543, 5521, 945, -5531, 5529, 993, -5547, 5521, 977, -5535, 5517, 1001, -5511, 5553, 1001, -5519, 5553, 1009, -5531, 5565, 1001, -5543, 5569, 993, -5531, 5557, 997, -5535, 5533, 985, -5515, 5537, 997, -5543, 5553, 993, -5551, 5553, 1001, -5551, 5565, 981, -5563, 5553, 977, -5559, 5549, 985, -5523, 5561, 1001, -5511, 5553, 989, -5499, 5533, 977, -5527, 5541, 1009, -5543, 5541, 985, -5523, 5525, 993, -5535, 5533, 997, -5543, 5537, 989, -5519, 5541, 993, -5531, 5549, 997, -5523, 5549, 1009, -5527, 5561, 1017, -5499, 5561, 1009, -5519, 5553, 1001, -5527, 5549, 997, -5531, 5553, 1005, -5511, 5545, 989, -5539, 5545, 985, -5539, 5533, 973, -5543, 5549, 981, -5539, 5553, 993, -5527, 5569, 993, -5551, 5541, 1001, -5531, 5537, 997, -5543, 5517, 1013, -5559, 5533, 1005, -5539, 5537, 981, -5555, 5537, 985, -5555, 5549, 981, -5543, 5557, 1009, -5503, 5553, 981, -5503, 5545, 997, -5523, 5569, 997, -5539, 5557, 985, -5543, 5553, 989, -5527, 5549, 981, -5511, 5549, 985, -5523, 5553, 1001, -5535, 5549, 1013, -5559, 5537, 1005, -5535, 5521, 985, -5519, 5529, 989, -5551, 5557, 993, -5575, 5525, 981, -5543, 5537, 977, -5527, 5525, 985, -5531, 5545, 973, -5507, 5553, 973, -5511, 5553, 989, -5503, 5561, 993, -5499, 5553, 993, -5511, 5553, 981, -5527, 5549,                                                                                                                                 },\r
+{123, 1005, -5547, 5549, 981, -5555, 5549, 1001, -5531, 5557, 1001, -5515, 5565, 1009, -5519, 5561, 1005, -5511, 5561, 1001, -5531, 5541, 989, -5551, 5553, 993, -5543, 5541, 1005, -5531, 5569, 1013, -5495, 5569, 997, -5483, 5569, 985, -5495, 5561, 993, -5519, 5553, 993, -5519, 5545, 985, -5511, 5553, 969, -5511, 5537, 973, -5499, 5533, 949, -5499, 5533, 1005, -5507, 5549, 989, -5527, 5545, 985, -5555, 5533, 993, -5535, 5545, 997, -5519, 5561, 977, -5523, 5569, 989, -5523, 5569, 993, -5551, 5549, 965, -5539, 5537, 977, -5527, 5549, 965, -5519, 5537, 957, -5515, 5537, 953, -5539, 5541, 965, -5531, 5553, 1001, -5547, 5565, 1017, -5535, 5565, 1009, -5515, 5573, 1001, -5519, 5553, 1001, -5535, 5557, 997, -5559, 5549, 977, -5535, 5561, 977, -5503, 5545, 953, -5483, 5561, 933, -5495, 5549, 945, -5495, 5565, 957, -5495, 5549, 977, -5499, 5573, 977, -5507, 5549, 985, -5515, 5545, 993, -5507, 5537, 969, -5487, 5533, 977, -5539, 5517, 989, -5575, 5521, 993, -5563, 5557, 993, -5527, 5565, 965, -5515, 5553, 937, -5531, 5557, 949, -5519, 5549, 933, -5499, 5533, 957, -5503, 5553, 957, -5511, 5553, 973, -5531, 5561, 985, -5531, 5557, 981, -5531, 5545, 969, -5543, 5541, 973, -5527, 5545, 949, -5515, 5549, 961, -5535, 5557, 973, -5547, 5537, 965, -5583, 5533, 949, -5539, 5517, 961, -5503, 5525, 925, -5515, 5549, 985, -5535, 5513, 989, -5507, 5557, 985, -5471, 5565, 977, -5491, 5609, 977, -5527, 5593, 1009, -5515, 5597, 1005, -5511, 5585, 985, -5483, 5573, 957, -5475, 5601, 949, -5487, 5557, 937, -5503, 5553, 945, -5511, 5549, 961, -5535, 5545, 969, -5563, 5545, 981, -5579, 5561, 973, -5543, 5561, 961, -5539, 5565, 965, -5515, 5557, 965, -5515, 5569, 981, -5487, 5589, 989, -5499, 5593, 981, -5515, 5585, 989, -5547, 5569, 957, -5507, 5557, 937, -5491, 5581, 957, -5519, 5537, 961, -5527, 5561, 961, -5515, 5541, 953, -5507, 5545, 937, -5527, 5537, 945, -5523, 5545, 953, -5523, 5545, 933, -5499, 5549, 949, -5515, 5557, 941, -5511, 5585, 953, -5511, 5561, 969, -5495, 5569, 969, -5535, 5569, 961, -5515, 5585, 949, -5499, 5565, 965, -5491, 5565, 965, -5519, 5565, 969, -5535, 5545, 949, -5547, 5545, 957, -5515, 5565, 969, -5503, 5561, 961, -5523, 5541, 957, -5539, 5549, 945, -5539, 5577, 925, -5511, 5585, 937, -5487, 5589,                                                                                                                                                                                                                            },\r
+{125, 949, -5503, 5581, 937, -5475, 5597, 953, -5467, 5581, 961, -5483, 5577, 953, -5511, 5561, 957, -5523, 5541, 949, -5523, 5549, 961, -5547, 5569, 957, -5551, 5537, 957, -5511, 5549, 937, -5499, 5565, 913, -5479, 5549, 929, -5463, 5577, 925, -5467, 5561, 941, -5499, 5581, 953, -5523, 5573, 929, -5499, 5549, 933, -5483, 5553, 945, -5503, 5585, 981, -5523, 5609, 1001, -5515, 5589, 985, -5535, 5573, 973, -5539, 5565, 957, -5531, 5557, 929, -5499, 5581, 929, -5483, 5577, 937, -5467, 5589, 945, -5475, 5585, 941, -5471, 5577, 965, -5475, 5581, 957, -5495, 5565, 953, -5503, 5577, 941, -5495, 5577, 945, -5483, 5577, 981, -5531, 5585, 969, -5515, 5541, 961, -5515, 5557, 933, -5495, 5565, 929, -5487, 5581, 953, -5511, 5581, 933, -5499, 5573, 937, -5475, 5593, 957, -5471, 5589, 945, -5475, 5573, 965, -5495, 5605, 973, -5503, 5565, 953, -5507, 5573, 941, -5523, 5577, 961, -5527, 5569, 977, -5523, 5589, 961, -5519, 5573, 961, -5491, 5593, 973, -5483, 5561, 945, -5487, 5609, 929, -5467, 5597, 945, -5451, 5621, 969, -5479, 5629, 973, -5451, 5621, 977, -5439, 5581, 953, -5463, 5573, 933, -5511, 5557, 953, -5503, 5533, 933, -5487, 5589, 957, -5483, 5581, 973, -5507, 5553, 933, -5535, 5625, 969, -5439, 5641, 973, -5375, 5601, 1033, -5483, 5621, 969, -5515, 5665, 937, -5435, 5601, 957, -5439, 5613, 961, -5459, 5597, 945, -5579, 5637, 909, -5363, 5693, 901, -5403, 5665, 993, -5515, 5693, 973, -5471, 5537, 985, -5567, 5429, 937, -5639, 5541, 913, -5555, 5605, 1033, -5427, 5533, 953, -5411, 5637, 913, -5491, 5609, 1005, -5487, 5617, 1045, -5435, 5633, 945, -5435, 5653, 949, -5515, 5625, 993, -5435, 5577, 993, -5463, 5509, 929, -5587, 5545, 921, -5643, 5493, 933, -5519, 5529, 901, -5435, 5561, 917, -5451, 5593, 925, -5535, 5589, 1001, -5599, 5561, 1061, -5607, 5481, 961, -5583, 5425, 889, -5559, 5517, 869, -5467, 5681, 917, -5319, 5573, 965, -5483, 5533, 941, -5575, 5569, 933, -5523, 5565, 917, -5415, 5653, 941, -5391, 5661, 981, -5447, 5617, 1005, -5495, 5573, 977, -5555, 5581, 949, -5519, 5569, 957, -5495, 5521, 945, -5539, 5521, 905, -5563, 5565, 945, -5543, 5453, 973, -5611, 5473, 949, -5611, 5561, 945, -5507, 5573, 977, -5443, 5577, 969, -5483, 5565, 965, -5547, 5553, 961, -5571, 5545, 957, -5559, 5545, 961, -5539, 5517, 937, -5551, 5505,                                                                                                                                                                              },\r
+{126, 933, -5551, 5521, 941, -5555, 5529, 949, -5543, 5561, 965, -5543, 5565, 993, -5555, 5561, 965, -5535, 5545, 953, -5523, 5509, 901, -5531, 5533, 941, -5543, 5545, 953, -5527, 5545, 957, -5523, 5569, 1021, -5523, 5545, 1029, -5575, 5537, 1021, -5631, 5537, 977, -5587, 5537, 937, -5527, 5553, 953, -5519, 5529, 957, -5523, 5533, 945, -5567, 5553, 957, -5535, 5533, 981, -5519, 5593, 957, -5503, 5557, 937, -5503, 5513, 921, -5511, 5505, 953, -5531, 5525, 949, -5547, 5489, 981, -5575, 5517, 997, -5571, 5545, 989, -5583, 5529, 989, -5571, 5513, 993, -5559, 5533, 957, -5571, 5545, 957, -5543, 5553, 953, -5523, 5545, 973, -5483, 5581, 973, -5491, 5557, 973, -5559, 5549, 949, -5555, 5553, 953, -5503, 5549, 961, -5475, 5525, 961, -5515, 5533, 997, -5555, 5525, 993, -5551, 5509, 977, -5567, 5501, 993, -5579, 5517, 981, -5591, 5529, 973, -5563, 5529, 989, -5535, 5541, 993, -5527, 5553, 977, -5519, 5541, 961, -5519, 5553, 965, -5503, 5565, 961, -5507, 5561, 977, -5535, 5553, 1009, -5555, 5533, 997, -5579, 5529, 977, -5575, 5509, 1001, -5571, 5481, 977, -5579, 5473, 961, -5571, 5505, 961, -5547, 5509, 981, -5543, 5525, 1001, -5531, 5521, 1001, -5563, 5541, 973, -5571, 5545, 969, -5559, 5521, 969, -5535, 5537, 973, -5535, 5537, 973, -5551, 5517, 989, -5607, 5517, 989, -5595, 5525, 993, -5575, 5521, 997, -5559, 5501, 985, -5583, 5517, 977, -5575, 5505, 965, -5539, 5493, 993, -5519, 5521, 985, -5547, 5529, 977, -5547, 5525, 989, -5531, 5533, 1005, -5515, 5525, 1025, -5567, 5525, 1013, -5587, 5513, 989, -5583, 5513, 981, -5587, 5493, 1005, -5563, 5517, 1001, -5591, 5481, 985, -5623, 5469, 997, -5607, 5497, 989, -5571, 5493, 973, -5543, 5497, 989, -5527, 5525, 989, -5527, 5537, 993, -5543, 5521, 997, -5567, 5529, 985, -5583, 5533, 997, -5571, 5513, 997, -5579, 5501, 993, -5583, 5501, 1001, -5579, 5493, 997, -5591, 5481, 1017, -5595, 5509, 1041, -5619, 5493, 993, -5647, 5497, 997, -5547, 5465, 1045, -5523, 5517, 989, -5571, 5493, 989, -5583, 5489, 1005, -5583, 5481, 985, -5583, 5493, 997, -5531, 5493, 997, -5559, 5517, 1001, -5615, 5449, 1017, -5615, 5481, 981, -5595, 5465, 1005, -5555, 5469, 1021, -5555, 5517, 1025, -5611, 5489, 1025, -5575, 5477, 1029, -5555, 5521, 1013, -5595, 5497, 1037, -5603, 5485, 1025, -5607, 5501, 989, -5567, 5489, 985, -5555, 5497, 1001, -5567, 5481,                                                                                                 },\r
+{124, 997, -5555, 5509, 1005, -5559, 5485, 1005, -5599, 5505, 1013, -5607, 5493, 1049, -5563, 5525, 1045, -5479, 5585, 1009, -5387, 5633, 993, -5471, 5601, 957, -5575, 5601, 877, -5595, 5625, 861, -5475, 5825, 957, -4991, 5917, 761, -4583, 6277, 809, -4879, 5761, 845, -5903, 5441, 1085, -6115, 5009, 1033, -5963, 5181, 885, -5795, 5505, 1033, -5531, 5637, 1173, -5487, 5625, 1297, -5687, 5469, 1365, -5859, 5533, 1373, -5835, 5649, 1317, -5611, 5597, 1269, -5507, 5449, 1229, -5627, 5393, 1121, -5771, 5289, 1109, -5859, 5181, 1141, -5843, 5261, 1121, -5779, 5369, 1101, -5767, 5357, 1101, -5799, 5281, 1089, -5815, 5341, 1029, -5747, 5329, 1145, -5715, 5105, 1181, -5703, 5157, 1017, -5699, 5245, 1061, -5811, 5137, 1333, -5935, 4969, 1393, -5975, 5045, 1329, -6047, 5069, 1369, -6007, 5005, 1389, -6011, 5057, 1297, -6019, 5109, 1181, -5951, 5193, 1137, -5947, 5017, 1093, -5915, 5097, 997, -5783, 5281, 981, -5615, 5405, 1025, -5631, 5417, 1173, -5679, 5309, 1201, -5751, 5265, 1069, -5871, 5325, 1089, -5743, 5361, 1093, -5591, 5473, 1145, -5495, 5397, 1117, -5507, 5425, 981, -5679, 5445, 861, -5763, 5545, 925, -5691, 5465, 1049, -5627, 5385, 1061, -5611, 5401, 1001, -5711, 5429, 869, -5719, 5481, 645, -5635, 5613, 481, -5407, 5673, -1399, -4519, 5453, -311, -6007, 4969, 1781, -6267, 5045, 953, -5859, 4893, 465, -5707, 5249, 741, -5643, 5285, 953, -5735, 5329, 1017, -5895, 5353, 1177, -5799, 5349, 1221, -5503, 5345, 1221, -5235, 5429, 1161, -5135, 5573, 977, -5123, 5713, 885, -5179, 5861, 973, -5071, 5917, 1177, -4871, 5909, 1357, -4823, 5913, 1517, -4779, 5837, 1601, -4731, 5805, 1557, -4755, 5937, 1573, -4851, 5989, 1469, -4895, 6333, 1213, -4987, 6661, 1237, -5199, 6721, 1409, -5183, 6837, 1469, -4967, 6873, 1497, -4779, 6817, 1609, -4687, 6677, 1721, -4567, 6549, 1705, -4371, 6553, 1641, -4199, 6341, 1533, -4227, 6329, 1401, -4439, 6277, 1313, -4575, 6245, 1305, -4647, 6277, 1309, -4547, 6329, 1261, -4379, 6497, 1225, -4175, 6645, 1209, -4111, 6681, 1253, -4223, 6517, 1401, -4239, 6305, 1385, -4191, 6229, 1285, -4239, 6237, 1193, -4259, 6193, 1165, -4335, 6145, 1129, -4479, 6221, 1077, -4535, 6233, 1053, -4575, 6281, 1041, -4563, 6333, 1061, -4491, 6289, 1113, -4391, 6253, 1121, -4319, 6241, 1133, -4271, 6229, 1125, -4227, 6189, 1085, -4251, 6189, 1069, -4307, 6169, 1065, -4319, 6189, 1013, -4307, 6241, },\r
+};\r
+static const uint32_t duration_RR[] = \r
+{\r
+ 1001,\r
+ 994  ,\r
+ 1008,\r
+ 1005,\r
+ 1006,\r
+ 1005,\r
+ 1005,\r
+ 1001,\r
+ 1008,\r
+ 1005,\r
+ 1005,\r
+ 1006,\r
+ 1000,\r
+ 1000,\r
+ 1000,\r
+ 1000,\r
+ 1000,\r
+ 1000,\r
+ 1000,\r
+ 1000,\r
+ 1006,\r
+ 1005,\r
+ 1005,\r
+ 1005,\r
+ 1005,\r
+ 1005,\r
+ 1005,\r
+ 1005,\r
+ 1005,\r
+ 1005,\r
+ 1005,\r
+ 1005,\r
+ 1005,\r
+ 1005,\r
+ 1005,\r
+ 1005,\r
+ 1005,\r
+ 1005,\r
+ 1005,\r
+ 1005,\r
+ 1004,\r
+ 999  ,\r
+ 1007,\r
+ 1005,\r
+ 1005,\r
+ 1004,\r
+ 1004,\r
+ 1005,\r
+ 1005,\r
+ 1005,\r
+ 1005,\r
+ 1005,\r
+ 1004,\r
+ 1005,\r
+ 1005,\r
+ 1005,\r
+ 1005,\r
+ 1005,\r
+ 1005,\r
+ 1002,\r
+ 1001,\r
+ 1007,\r
+ 1005,\r
+ 1005,\r
+ 1005,\r
+ 1005,\r
+ 1005,\r
+ 1005,\r
+ 1005,\r
+ 1005,\r
+ 1005,\r
+ 1005,\r
+ 1005,\r
+ 1005,\r
+ 1005,\r
+ 1003,\r
+ 999  ,\r
+ 1008,\r
+ 1005,\r
+ 1005,\r
+ 1005,\r
+ 1005,\r
+ 1005,\r
+ 1005,\r
+ 1005,\r
+ 1004,\r
+ 1005,\r
+ 1004,\r
+ 1002,\r
+ 1002,\r
+ 1002,\r
+ 1004,\r
+ 1005,\r
+ 1005,\r
+ 1003,\r
+ 1002,\r
+ 1001,\r
+ 1001,\r
+ 1003,\r
+ 1004,\r
+ 1002,\r
+ 1003,\r
+ 1003,\r
+ 1004,\r
+ 1003,\r
+ 1002,\r
+ 1002,\r
+ 1002,\r
+ 1004,\r
+ 1004,\r
+ 1004,\r
+ 1003,\r
+ 1010,\r
+ 1010,\r
+ 1010,\r
+ 1010,\r
+ 1010,\r
+ 1005,\r
+ 1007,\r
+ 1004,\r
+ 1003,\r
+ 1005,\r
+ 1005,\r
+ 1005,\r
+ 1005,\r
+ 1005,\r
+ 1005,\r
+ 1003,\r
+ 1004,\r
+ 1004,\r
+ 1005,\r
+ 1005,\r
+ 1005,\r
+ 1004,\r
+ 1005,\r
+ 1005,\r
+ 1005,\r
+ 1005,\r
+ 1004,\r
+ 1003,\r
+ 1004,\r
+ 1005,\r
+ 1005,\r
+ 1005,\r
+ 1005,\r
+ 1002,\r
+ 1000,\r
+ 1002,\r
+ 1000,\r
+ 1000,\r
+ 1000,\r
+ 1000,\r
+ 1002,\r
+ 1000,\r
+ 1002,\r
+ 1002,\r
+ 1002,\r
+ 1000,\r
+ 1000,\r
+ 1000,\r
+ 1001,\r
+ 1002,\r
+ 1002,\r
+ 1000,\r
+ 1003,\r
+ 1003,\r
+ 1000,\r
+ 1002,\r
+ 1002,\r
+ 1004,\r
+ 1002,\r
+ 1010,\r
+ 1009,\r
+ 1010,\r
+ 1010,\r
+ 1010,\r
+ 1010,\r
+ 1010,\r
+ 1010,\r
+ 1010,\r
+ 1010,\r
+};\r
+\r
+static const uint8_t frame_RR[] = \r
+{\r
+ 1     ,\r
+ 2     ,\r
+ 3     ,\r
+ 4     ,\r
+ 5     ,\r
+ 6     ,\r
+ 7     ,\r
+ 8     ,\r
+ 9     ,\r
+ 10  ,\r
+ 11  ,\r
+ 12  ,\r
+ 13  ,\r
+ 14  ,\r
+ 15  ,\r
+ 16  ,\r
+ 17  ,\r
+ 18  ,\r
+ 19  ,\r
+ 20  ,\r
+ 21  ,\r
+ 22  ,\r
+ 23  ,\r
+ 24  ,\r
+ 25  ,\r
+ 26  ,\r
+ 27  ,\r
+ 28  ,\r
+ 29  ,\r
+ 30  ,\r
+ 31  ,\r
+ 32  ,\r
+ 33  ,\r
+ 34  ,\r
+ 35  ,\r
+ 36  ,\r
+ 37  ,\r
+ 38  ,\r
+ 39  ,\r
+ 40  ,\r
+ 41  ,\r
+ 42  ,\r
+ 43  ,\r
+ 44  ,\r
+ 45  ,\r
+ 46  ,\r
+ 47  ,\r
+ 48  ,\r
+ 49  ,\r
+ 50  ,\r
+ 51  ,\r
+ 52  ,\r
+ 53  ,\r
+ 54  ,\r
+ 55  ,\r
+ 56  ,\r
+ 57  ,\r
+ 58  ,\r
+ 59  ,\r
+ 60  ,\r
+ 61  ,\r
+ 62  ,\r
+ 63  ,\r
+ 64  ,\r
+ 65  ,\r
+ 66  ,\r
+ 67  ,\r
+ 68  ,\r
+ 69  ,\r
+ 70  ,\r
+ 71  ,\r
+ 72  ,\r
+ 73  ,\r
+ 74  ,\r
+ 75  ,\r
+ 76  ,\r
+ 77  ,\r
+ 78  ,\r
+ 79  ,\r
+ 80  ,\r
+ 81  ,\r
+ 82  ,\r
+ 83  ,\r
+ 84  ,\r
+ 85  ,\r
+ 86  ,\r
+ 87  ,\r
+ 88  ,\r
+ 89  ,\r
+ 90  ,\r
+ 91  ,\r
+ 92  ,\r
+ 93  ,\r
+ 94  ,\r
+ 95  ,\r
+ 96  ,\r
+ 97  ,\r
+ 98  ,\r
+ 99  ,\r
+ 100,\r
+ 101,\r
+ 102,\r
+ 103,\r
+ 104,\r
+ 105,\r
+ 106,\r
+ 107,\r
+ 108,\r
+ 109,\r
+ 110,\r
+ 111,\r
+ 112,\r
+ 113,\r
+ 114,\r
+ 115,\r
+ 116,\r
+ 117,\r
+ 118,\r
+ 119,\r
+ 120,\r
+ 121,\r
+ 122,\r
+ 123,\r
+ 124,\r
+ 125,\r
+ 126,\r
+ 127,\r
+ 128,\r
+ 129,\r
+ 130,\r
+ 131,\r
+ 132,\r
+ 133,\r
+ 134,\r
+ 135,\r
+ 136,\r
+ 137,\r
+ 138,\r
+ 139,\r
+ 140,\r
+ 141,\r
+ 142,\r
+ 143,\r
+ 144,\r
+ 145,\r
+ 146,\r
+ 147,\r
+ 148,\r
+ 149,\r
+ 150,\r
+ 151,\r
+ 152,\r
+ 153,\r
+ 154,\r
+ 155,\r
+ 156,\r
+ 157,\r
+ 158,\r
+ 159,\r
+ 160,\r
+ 161,\r
+ 162,\r
+ 163,\r
+ 164,\r
+ 165,\r
+ 166,\r
+ 167,\r
+ 168,\r
+ 169,\r
+ 170,\r
+ 171,\r
+ 172,\r
+ 173,\r
+ 174,\r
+ 175,\r
+ 176,\r
+ 177,\r
+ 178,\r
+ 179,\r
+ 180,\r
+ 181,\r
+};\r
+       \r
+#endif\r
diff --git a/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/RR_HRV_STRESS_RRI/V3131/pah_RRI_alg.c b/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/RR_HRV_STRESS_RRI/V3131/pah_RRI_alg.c
new file mode 100644 (file)
index 0000000..1f9789c
--- /dev/null
@@ -0,0 +1,273 @@
+// c\r
+#include <string.h>\r
+#include <stdint.h>\r
+#include <stdbool.h>\r
+#include <stdlib.h>\r
+#include <stdio.h>\r
+#include <string.h>\r
+\r
+//#include "main.h"\r
+#include "pah831x_comm.h"\r
+#include "pah831x_config.h"\r
+#include "pah831x_main.h"\r
+#include "pah_RRI_alg.h"\r
+// Platform support\r
+// HRV algorithm\r
+#include "pxialg_hrv_v3.h"\r
+//HR\r
+#include "pxialg.h"\r
+\r
+typedef struct\r
+{\r
+     // pxialg\r
+    void*                pxialg_buffer;\r
+    pah8series_data_t          pxialg_data;\r
+    bool                pxialg_has_init;\r
+    uint64_t            last_report_time;\r
+       uint8_t*             ppg_dac_data;\r
+\r
+   \r
+} main_rr2_state_s;\r
+\r
+\r
+\r
+static bool need_log_header = true;\r
+static main_rr2_state_s _state;\r
+\r
+\r
+static float    rri           =  0.0f  ;\r
+static float    rri_time_point=  0.0f  ;\r
+static int      rri_confidence=  0     ;\r
+//int      rr            =  0     ;\r
+\r
+static uint32_t  duration_total=0;\r
+\r
+static uint8_t log_data_en_rri  = 0 ;\r
+static uint8_t sampling_rate_rri= 0 ;\r
+\r
+/*============================================================================\r
+STATIC FUNCTION PROTOTYPES\r
+============================================================================*/\r
+static bool rri_algorithm_process(pah8series_data_t *pxialg_data, uint32_t ch_num);\r
+static bool rri_algorithm_calculate(pah8series_data_t *pxialg_data, uint32_t ch_num);\r
+static bool run_rri_pxialg(const pah8series_data_t *pxialg_data);\r
+\r
+static void log_pah8series_data_header(uint32_t ch_num, uint32_t ir_ch_num, uint32_t g_sensor_mode);\r
+static void log_pah8series_data(const pah8series_data_t *data);\r
+\r
+static void log_pah8series_data_header(uint32_t ch_num, uint32_t ir_ch_num, uint32_t g_sensor_mode)\r
+{\r
+    //log pah8series data header\r
+    // (1)Using total channel numbers;\r
+    // (2)reserved;\r
+    // (3)reserved;\r
+    // (4)IR channel number;\r
+    // (5)MEMS mode 0:2G, 1:4G, 2:8G\r
+    //LOG_PRINT("PPG CH#, %d, %d, %d, %d, %d\n", ch_num, SETTING_VERSION, 0, ir_ch_num, g_sensor_mode);\r
+    LOG_PRINT("PPG CH#, %d, %d, %d, %d, %d\n", ch_num, 0, 0, ir_ch_num, g_sensor_mode);\r
+\r
+}\r
+static void log_pah8series_data(const pah8series_data_t *pxialg_data)\r
+{\r
+    int i = 0;\r
+    uint32_t *ppg_data = (uint32_t *)pxialg_data->ppg_data;\r
+       uint8_t *dac_data = _state.ppg_dac_data;\r
+    int16_t *mems_data = pxialg_data->mems_data;\r
+    int data_num = pxialg_data->nf_ppg_channel * pxialg_data->nf_ppg_per_channel;\r
+    \r
+    LOG_PRINT("Frame Count, %d \n", pxialg_data->frame_count);\r
+    LOG_PRINT("Time, %d \n", pxialg_data->time);\r
+    LOG_PRINT("PPG, %d, %d, ", pxialg_data->touch_flag, data_num);\r
+    for (i = 0; i < data_num; ++i)\r
+    {\r
+        LOG_PRINT("%d, ", *ppg_data);\r
+        ppg_data++;\r
+    }\r
+    LOG_PRINT("\n");\r
+    LOG_PRINT("MEMS, %d, ", pxialg_data->nf_mems);\r
+    for (i = 0; i < (pxialg_data->nf_mems * 3); ++i)\r
+    {\r
+        LOG_PRINT("%d, ", *mems_data);\r
+        mems_data++;\r
+    }\r
+    LOG_PRINT("\n");\r
+    LOG_PRINT("DAC, %d, ", data_num);\r
+    for (i = 0; i < data_num; ++i)\r
+    {\r
+        LOG_PRINT("%d, ", *dac_data);\r
+        dac_data++;\r
+    }\r
+    LOG_PRINT("\n");\r
+}\r
+\r
+\r
+bool  report_fifo_data_rri(\r
+uint32_t ppg_timestamp,     \r
+uint32_t time_period, \r
+uint32_t *ppg_data,\r
+uint8_t *dac_data,\r
+uint8_t ppg_size,\r
+uint8_t ch_num,\r
+int16_t *acc_data,\r
+uint8_t acc_size,\r
+uint8_t is_touched  , \r
+uint8_t log_data_en  ,\r
+uint8_t sampling_rate\r
+)\r
+{\r
+//    ALG_PRINT("time_period = %d  timestamp =%d \n", time_period , ppg_timestamp);\r
+    log_data_en_rri   =   log_data_en;\r
+    sampling_rate_rri = sampling_rate ;\r
+    //alg_work_mode_rr =alg_work_mode ;\r
+    _state.pxialg_data.mems_data = acc_data ;\r
+    _state.pxialg_data.nf_mems =   acc_size  ;\r
+    _state.pxialg_data.touch_flag = is_touched<2 ? 1 : 0;\r
+    _state.pxialg_data.time = time_period;\r
+    _state.pxialg_data.ppg_data = (int32_t*)ppg_data;\r
+       \r
+       _state.ppg_dac_data = dac_data ;\r
+ \r
+    _state.pxialg_data.nf_ppg_channel = ch_num;\r
+    _state.pxialg_data.nf_ppg_per_channel = ppg_size;\r
+    ++_state.pxialg_data.frame_count;\r
+    rri_algorithm_process(&_state.pxialg_data, _state.pxialg_data.nf_ppg_channel);\r
+\r
+\r
+    return true ;\r
+\r
+    \r
+}\r
+\r
+static bool rri_algorithm_process(pah8series_data_t *pxialg_data, uint32_t ch_num)\r
+{\r
+    if(log_data_en_rri)\r
+    {\r
+        // log header\r
+        if (need_log_header)\r
+        {\r
+            need_log_header = false;\r
+            log_pah8series_data_header(ch_num, PPG_IR_CH_NUM, ALG_GSENSOR_MODE);\r
+        }\r
+        \r
+        // log\r
+        log_pah8series_data(&_state.pxialg_data);\r
+    }\r
+    // rr\r
+    if(_state.pxialg_data.touch_flag)\r
+    {\r
+          rri_algorithm_calculate(&_state.pxialg_data, ch_num);\r
+      }else\r
+       {\r
+               rri_algorithm_close();\r
+       }\r
+    return true;\r
+    \r
+    \r
+}\r
+static bool rri_algorithm_calculate(pah8series_data_t *pxialg_data, uint32_t ch_num)\r
+{\r
+ bool has_updated = false;\r
+    \r
+#if defined(ENABLE_PXI_ALG_RRI)\r
+    //uint8_t ret = 0;\r
+    // Algorithm support only data length >= 10\r
+    \r
+    // Initialize algorithm\r
+    if (!_state.pxialg_has_init)\r
+    {\r
+         //memset(&_state, 0, sizeof(_state));        \r
+         int version     = RESPGetVersion();\r
+         LOG_PRINT("RR_GetVersion() = %d \n", RESPGetVersion());\r
+        \r
+         int buffer_size = RESPGetMemorySize(0,1, 60, sampling_rate_rri);\r
+         LOG_PRINT("RR_buffer_size = %d  \n", buffer_size);\r
+#ifdef _ALGO_NON_USE_HEAP_SIZE\r
+         //ASSERT(sizeof(pah_alg_buffer)>=buffer_size);\r
+         if (sizeof(pah_alg_buffer)>=buffer_size)\r
+         {\r
+             memset(pah_alg_buffer,0x00,sizeof(pah_alg_buffer));\r
+             _state.pxialg_buffer = pah_alg_buffer;\r
+         }else\r
+         {\r
+             ALG_PRINT("RRI_buffer_size_not enough \n");\r
+             return false;\r
+         }\r
+         \r
+ #else         \r
+         _state.pxialg_buffer = (void*)malloc(buffer_size);            \r
+#endif\r
+        if (!buffer_size)\r
+        {\r
+            LOG_PRINT("RRVGetMemorySize(), failed to get memory size \n");\r
+            return 0 ;\r
+        }       \r
+        if (!HHRVOpen(_state.pxialg_buffer))\r
+        {\r
+            LOG_PRINT("Out of memory \n \n");  \r
+            return 0;\r
+        }\r
+            \r
+        _state.pxialg_has_init = true;\r
+    }\r
+    // Calculate RRI\r
+        run_rri_pxialg(pxialg_data);        \r
+#endif \r
+    \r
+    return has_updated;    \r
+}\r
+\r
+\r
+static bool run_rri_pxialg(const pah8series_data_t *pxialg_data)\r
+{\r
+    uint32_t *ppg_data      =(uint32_t *)pxialg_data->ppg_data;\r
+    //int16_t *mems_data      = pxialg_data->mems_data;\r
+    int ppg_ch_num          = pxialg_data->nf_ppg_channel ;\r
+    int nf_ppg_per_channel  = pxialg_data->nf_ppg_per_channel ;\r
+    //int nf_mems             = pxialg_data->nf_mems ;\r
+    uint32_t duration       = pxialg_data->time;\r
+    uint8_t touch_flag      = pxialg_data->touch_flag;\r
+    uint32_t Green          = 0;\r
+    uint32_t green1_index   = 0;\r
+    for (int i = 0; i < nf_ppg_per_channel; ++i)\r
+    {        \r
+        Green = ppg_data[i * ppg_ch_num + green1_index];\r
+        float raw_data = (float)Green ;        \r
+        HHRVProcess(touch_flag, raw_data, (float)duration/nf_ppg_per_channel);\r
+        if (HHRVGetOnlineRRIReportFlag() == 1) \r
+        {\r
+            rri = HHRVGetOnlineRRI();\r
+            rri_time_point = HHRVGetOnlineRRITimePoint();\r
+            LOG_PRINT("rri = %d,  rri_confidence_level= %d,  rri_time_point = %d, \n", (int)rri,rri_confidence,(int)rri_time_point);                 \r
+        }\r
+    }\r
+    duration_total+=duration;\r
+    return true;      \r
+}\r
+\r
+\r
+\r
+\r
+\r
+void rri_algorithm_close(void)\r
+{\r
+    \r
+#if defined(ENABLE_PXI_ALG_RRI)\r
+    HHRVClose();\r
+#ifndef _ALGO_NON_USE_HEAP_SIZE\r
+    if (_state.pxialg_buffer)\r
+    {\r
+        free(_state.pxialg_buffer);\r
+    }\r
+#endif\r
+    _state.pxialg_has_init = 0;\r
+    rri                   = 0;\r
+    rri_time_point        = 0;\r
+    need_log_header = true;\r
+\r
+#endif \r
+}\r
+\r
+\r
+\r
+\r
+\r
diff --git a/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/RR_HRV_STRESS_RRI/V3131/pah_RRI_alg.h b/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/RR_HRV_STRESS_RRI/V3131/pah_RRI_alg.h
new file mode 100644 (file)
index 0000000..17c578d
--- /dev/null
@@ -0,0 +1,42 @@
+/*==============================================================================\r
+* Edit History\r
+* \r
+* This section contains comments describing changes made to the module. Notice\r
+* that changes are listed in reverse chronological order. Please use ISO format\r
+* for dates.\r
+* \r
+* when       who       what, where, why\r
+* ---------- ---       -----------------------------------------------------------\r
+* 2016-04-29 bell      Initial revision.\r
+==============================================================================*/\r
+\r
+#ifndef __pah_rri_alg_h__\r
+#define __pah_rri_alg_h__\r
+\r
+\r
+#include <stdbool.h>\r
+#include <stdint.h>\r
+#include <string.h>\r
+//#include "pah831x_data_types.h"\r
+\r
+bool  report_fifo_data_rri(\r
+uint32_t ppg_timestamp,     \r
+uint32_t time_period, \r
+uint32_t *ppg_data,\r
+uint8_t *dac_data,\r
+uint8_t ppg_size,\r
+uint8_t ch_num,\r
+int16_t *acc_data,\r
+uint8_t acc_size,\r
+uint8_t is_touched  , \r
+uint8_t log_data_en ,\r
+uint8_t sampling_rate\r
+);\r
+\r
+\r
+\r
+void rri_algorithm_close(void);\r
+\r
+\r
+\r
+#endif  // header guard\r
diff --git a/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/RR_HRV_STRESS_RRI/V3131/pah_RR_alg_V30x.c b/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/RR_HRV_STRESS_RRI/V3131/pah_RR_alg_V30x.c
new file mode 100644 (file)
index 0000000..a241a93
--- /dev/null
@@ -0,0 +1,281 @@
+// c\r
+#include <string.h>\r
+#include <stdint.h>\r
+#include <stdbool.h>\r
+#include <stdlib.h>\r
+#include <stdio.h>\r
+#include <string.h>\r
+\r
+//#include "main.h"\r
+#include "pah831x_comm.h"\r
+#include "pah831x_config.h"\r
+#include "pah831x_main.h"\r
+#include "pah_RR_alg_V30x.h"\r
+// Platform support\r
+//#include "pxi_nrf_debug_print.h"\r
+// HRV algorithm\r
+#include "pxialg_hrv_v3.h"\r
+\r
+//HR\r
+#include "pxialg.h"\r
+\r
+typedef struct\r
+{\r
+     // pxialg\r
+    void*                pxialg_buffer;\r
+    pah8series_data_t          pxialg_data;\r
+    bool                pxialg_has_init;\r
+    uint64_t            last_report_time;\r
+       uint8_t*             ppg_dac_data;\r
+\r
+   \r
+} main_rr2_state_s;\r
+\r
+\r
+\r
+static bool need_log_header = true;\r
+static main_rr2_state_s _state;\r
+\r
+\r
+static float    rri           =  0.0f  ;\r
+static float    rri_time_point=  0.0f  ;\r
+static int      rri_confidence=  0     ;\r
+static int      rr            =  0     ;\r
+\r
+static uint32_t  duration_total=0;\r
+\r
+static uint8_t log_data_en_rr  = 0 ;\r
+static uint8_t alg_work_mode_rr= 0 ;\r
+\r
+/*============================================================================\r
+STATIC FUNCTION PROTOTYPES\r
+============================================================================*/\r
+\r
+static void log_pah8series_data_header(uint32_t ch_num, uint32_t ir_ch_num, uint32_t g_sensor_mode);\r
+static void log_pah8series_data(const pah8series_data_t *data);\r
+\r
+static bool rr_2_algorithm_calculate(pah8series_data_t *pxialg_data, uint32_t ch_num);\r
+static bool rr_2_algorithm_process(pah8series_data_t *pxialg_data, uint32_t ch_num);    \r
+static bool run_rr_2_pxialg(const pah8series_data_t *pxialg_data);\r
+\r
+\r
+static void log_pah8series_data_header(uint32_t ch_num, uint32_t ir_ch_num, uint32_t g_sensor_mode)\r
+{\r
+    //log pah8series data header\r
+    // (1)Using total channel numbers;\r
+    // (2)reserved;\r
+    // (3)reserved;\r
+    // (4)IR channel number;\r
+    // (5)MEMS mode 0:2G, 1:4G, 2:8G\r
+    //LOG_PRINT("PPG CH#, %d, %d, %d, %d, %d\n", ch_num, SETTING_VERSION, 0, ir_ch_num, g_sensor_mode);\r
+    LOG_PRINT("PPG CH#, %d, %d, %d, %d, %d\n", ch_num, 0, 0, ir_ch_num, g_sensor_mode);\r
+\r
+}\r
+static void log_pah8series_data(const pah8series_data_t *pxialg_data)\r
+{\r
+    int i = 0;\r
+    uint32_t *ppg_data = (uint32_t *)pxialg_data->ppg_data;\r
+       uint8_t *dac_data = _state.ppg_dac_data;\r
+    int16_t *mems_data = pxialg_data->mems_data;\r
+    int data_num = pxialg_data->nf_ppg_channel * pxialg_data->nf_ppg_per_channel;\r
+    \r
+    LOG_PRINT("Frame Count, %d \n", pxialg_data->frame_count);\r
+    LOG_PRINT("Time, %d \n", pxialg_data->time);\r
+    LOG_PRINT("PPG, %d, %d, ", pxialg_data->touch_flag, data_num);\r
+    for (i = 0; i < data_num; ++i)\r
+    {\r
+        LOG_PRINT("%d, ", *ppg_data);\r
+        ppg_data++;\r
+    }\r
+    LOG_PRINT("\n");\r
+    LOG_PRINT("MEMS, %d, ", pxialg_data->nf_mems);\r
+    for (i = 0; i < (pxialg_data->nf_mems * 3); ++i)\r
+    {\r
+        LOG_PRINT("%d, ", *mems_data);\r
+        mems_data++;\r
+    }\r
+    LOG_PRINT("\n");\r
+    LOG_PRINT("DAC, %d, ", data_num);\r
+    for (i = 0; i < data_num; ++i)\r
+    {\r
+        LOG_PRINT("%d, ", *dac_data);\r
+        dac_data++;\r
+    }\r
+    LOG_PRINT("\n");\r
+}\r
+\r
+\r
+bool  report_fifo_data_rr_2(\r
+uint32_t ppg_timestamp,     \r
+uint32_t time_period, \r
+uint32_t *ppg_data,\r
+uint8_t *dac_data,\r
+uint8_t ppg_size,\r
+uint8_t ch_num,\r
+int16_t *acc_data,\r
+uint8_t acc_size,\r
+int  *RR_out,\r
+float *RRI,\r
+uint8_t is_touched  , \r
+uint8_t log_data_en  ,\r
+uint8_t alg_work_mode\r
+)\r
+{\r
+//    ALG_PRINT("time_period = %d  timestamp =%d \n", time_period , ppg_timestamp);\r
+    log_data_en_rr   =   log_data_en;\r
+    alg_work_mode_rr =alg_work_mode ;\r
+    _state.pxialg_data.mems_data = acc_data ;\r
+    _state.pxialg_data.nf_mems =   acc_size  ;\r
+    _state.pxialg_data.touch_flag = is_touched<2 ? 1 : 0;\r
+    _state.pxialg_data.time = time_period;\r
+    _state.pxialg_data.ppg_data = (int32_t*)ppg_data;\r
+       \r
+       _state.ppg_dac_data = dac_data ;\r
+ \r
+    _state.pxialg_data.nf_ppg_channel = ch_num;\r
+    _state.pxialg_data.nf_ppg_per_channel = ppg_size;\r
+    ++_state.pxialg_data.frame_count;\r
+//    ALG_PRINT("_state.pxialg_data.time = %d  timestamp =%d \n", _state.pxialg_data.time , ppg_timestamp);\r
+    rr_2_algorithm_process(&_state.pxialg_data, _state.pxialg_data.nf_ppg_channel);\r
+    *RR_out                 = rr ;\r
+     *RRI                   = rri;\r
+\r
+    return true ;\r
+\r
+    \r
+}\r
+\r
+static bool rr_2_algorithm_process(pah8series_data_t *pxialg_data, uint32_t ch_num)\r
+{\r
+    if(log_data_en_rr)\r
+    {\r
+    // log header\r
+    if (need_log_header)\r
+    {\r
+        need_log_header = false;\r
+        log_pah8series_data_header(ch_num, PPG_IR_CH_NUM, ALG_GSENSOR_MODE);\r
+    }\r
+    \r
+    // log\r
+    log_pah8series_data(&_state.pxialg_data);\r
+    }\r
+    // rr\r
+    if(_state.pxialg_data.touch_flag)\r
+    {\r
+          rr_2_algorithm_calculate(&_state.pxialg_data, ch_num);\r
+    }else\r
+       {\r
+               rr_2_algorithm_close();\r
+       }\r
+    return true;\r
+    \r
+    \r
+}\r
+static bool rr_2_algorithm_calculate(pah8series_data_t *pxialg_data, uint32_t ch_num)\r
+{\r
+ bool has_updated = false;\r
+    \r
+#if defined(ENABLE_PXI_ALG_RR_2)\r
+    //uint8_t ret = 0;\r
+    // Algorithm support only data length >= 10\r
+    \r
+    // Initialize algorithm\r
+    if (!_state.pxialg_has_init)\r
+    {\r
+         //memset(&_state, 0, sizeof(_state));        \r
+         int version     = RESPGetVersion();\r
+         LOG_PRINT("RR_GetVersion() = %d \n", RESPGetVersion());\r
+        \r
+         int buffer_size = RESPGetMemorySize(0,1, 60, 25);\r
+         LOG_PRINT("RR_buffer_size = %d  \n", buffer_size);\r
+#ifdef _ALGO_NON_USE_HEAP_SIZE\r
+         //ASSERT(sizeof(pah_alg_buffer)>=buffer_size);\r
+         if (sizeof(pah_alg_buffer)>=buffer_size)\r
+         {\r
+             memset(pah_alg_buffer,0x00,sizeof(pah_alg_buffer));\r
+             _state.pxialg_buffer = pah_alg_buffer;\r
+         }else\r
+         {\r
+             ALG_PRINT("RR_buffer_size_not enough \n");\r
+             return false;\r
+         }\r
+         \r
+#else          \r
+         _state.pxialg_buffer = (void*)malloc(buffer_size);            \r
+#endif\r
+        if (!buffer_size)\r
+        {\r
+            LOG_PRINT("RRVGetMemorySize(), failed to get memory size \n");\r
+            return 0 ;\r
+        }       \r
+        if (!HHRVOpen(_state.pxialg_buffer))\r
+        {\r
+            LOG_PRINT("Out of memory \n \n");  \r
+            return 0;\r
+        }\r
+            \r
+        _state.pxialg_has_init = true;\r
+    }\r
+    // Calculate HRV\r
+        run_rr_2_pxialg(pxialg_data);        \r
+#endif \r
+    \r
+    return has_updated;    \r
+}\r
+\r
+\r
+static bool run_rr_2_pxialg(const pah8series_data_t *pxialg_data)\r
+{\r
+    uint32_t *ppg_data      =(uint32_t *)pxialg_data->ppg_data;\r
+    //int16_t *mems_data      = pxialg_data->mems_data;\r
+    int ppg_ch_num          = pxialg_data->nf_ppg_channel ;\r
+    int nf_ppg_per_channel  = pxialg_data->nf_ppg_per_channel ;\r
+    //int nf_mems             = pxialg_data->nf_mems ;\r
+    uint32_t duration       = pxialg_data->time;\r
+    uint8_t touch_flag      = pxialg_data->touch_flag;\r
+    uint32_t Green          = 0;\r
+    uint32_t green1_index   = 0;\r
+    for (int i = 0; i < nf_ppg_per_channel; ++i)\r
+    {        \r
+        Green = ppg_data[i * ppg_ch_num + green1_index];\r
+        float raw_data = (float)Green ;        \r
+        HHRVProcess(touch_flag, raw_data, (float)duration/nf_ppg_per_channel);\r
+        if (HHRVGetOnlineRRIReportFlag() == 1) \r
+        {\r
+            rri = HHRVGetOnlineRRI();\r
+            rri_time_point = HHRVGetOnlineRRITimePoint();\r
+            rr               =RESPGetRR();\r
+            LOG_PRINT("rri = %d,  rri_confidence_level= %d,  rri_time_point = %d, rr= %d,  \n", (int)rri,rri_confidence,(int)rri_time_point, rr);                 \r
+        }\r
+    }\r
+    duration_total+=duration;\r
+    return true;      \r
+}\r
+\r
+\r
+\r
+\r
+\r
+void rr_2_algorithm_close(void)\r
+{\r
+    \r
+#if defined(ENABLE_PXI_ALG_RR_2)\r
+    HHRVClose();\r
+#ifndef _ALGO_NON_USE_HEAP_SIZE        \r
+    if (_state.pxialg_buffer)\r
+    {\r
+        free(_state.pxialg_buffer);\r
+    }\r
+#endif\r
+    _state.pxialg_has_init = 0;\r
+    rri                   = 0;\r
+    rri_time_point        = 0;\r
+    rr                    = 0;\r
+    need_log_header = true;\r
+#endif \r
+}\r
+\r
+\r
+\r
+\r
+\r
diff --git a/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/RR_HRV_STRESS_RRI/V3131/pah_RR_alg_V30x.h b/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/RR_HRV_STRESS_RRI/V3131/pah_RR_alg_V30x.h
new file mode 100644 (file)
index 0000000..583b0c8
--- /dev/null
@@ -0,0 +1,55 @@
+/*\r
+ * @Author: penglei 1624952103@qq.com\r
+ * @Date: 2025-12-25 09:34:31\r
+ * @LastEditors: penglei 1624952103@qq.com\r
+ * @LastEditTime: 2026-01-15 15:46:45\r
+ * @FilePath: /FD230/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/RR_HRV_STRESS_RRI/V3131/pah_RR_alg_V30x.h\r
+ * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE\r
+ */\r
+/*==============================================================================\r
+* Edit History\r
+* \r
+* This section contains comments describing changes made to the module. Notice\r
+* that changes are listed in reverse chronological order. Please use ISO format\r
+* for dates.\r
+* \r
+* when       who       what, where, why\r
+* ---------- ---       -----------------------------------------------------------\r
+* 2016-04-29 bell      Initial revision.\r
+==============================================================================*/\r
+\r
+#ifndef __pah_rr_alg_V30X_h__\r
+#define __pah_rr_alg_V30X_h__\r
+\r
+\r
+#include <stdbool.h>\r
+#include <stdint.h>\r
+#include <string.h>\r
+//#include "pah831x_data_types.h"\r
+\r
+#define ENABLE_PXI_ALG_RR_2\r
+\r
+bool  report_fifo_data_rr_2(\r
+uint32_t ppg_timestamp,     \r
+uint32_t time_period, \r
+uint32_t *ppg_data,\r
+uint8_t *dac_data,\r
+uint8_t ppg_size,\r
+uint8_t ch_num,\r
+int16_t *acc_data,\r
+uint8_t acc_size,\r
+int  *RR_out,\r
+float *RRI,\r
+uint8_t is_touched  , \r
+uint8_t log_data_en,\r
+uint8_t alg_work_mode\r
+);\r
+\r
+\r
+\r
+\r
+void rr_2_algorithm_close(void);\r
+\r
+\r
+\r
+#endif  // header guard\r
diff --git a/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/RR_HRV_STRESS_RRI/V3131/pah_hrv_alg.c b/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/RR_HRV_STRESS_RRI/V3131/pah_hrv_alg.c
new file mode 100644 (file)
index 0000000..dde283a
--- /dev/null
@@ -0,0 +1,409 @@
+// c\r
+#include <string.h>\r
+#include <stdint.h>\r
+#include <stdbool.h>\r
+#include <stdlib.h>\r
+#include <stdio.h>\r
+#include <string.h>\r
+\r
+//#include "main.h"\r
+#include "pah831x_comm.h"\r
+#include "pah831x_config.h"\r
+#include "pah831x_main.h"\r
+#include "pah_hrv_alg.h"\r
+// Platform support\r
+//#include "pxi_nrf_debug_print.h"\r
+// HRV algorithm\r
+//#include "pxialg_hrv.h"\r
+#include "pxialg_hrv_v3.h"\r
+typedef struct\r
+{\r
+     // pxialg\r
+    void*                pxialg_buffer;\r
+    pah8series_data_t      pxialg_data;\r
+    bool                pxialg_has_init;\r
+    uint64_t            last_report_time;\r
+       uint8_t*             ppg_dac_data;\r
+} main_hrv_state_s;\r
+\r
+typedef struct\r
+{\r
+    void            *pBuffer;\r
+    float           collect_duration;\r
+    uint8_t         has_got_sdnn;\r
+    uint8_t         has_time_out;\r
+} hrv_state_s;\r
+\r
+#define HRV_ENABLE_LHR            1\r
+\r
+#define HRV_SAMPLING_RATE        25//20\r
+\r
+#define HRV_COLLECTION_SECONDS  60    // HRV measure seconds\r
+\r
+static main_hrv_state_s _state;\r
+static hrv_state_s _hrv_state;\r
+static bool need_log_header = true;\r
+\r
+static uint32_t  duration_total=0;\r
+\r
+static float SDNN        = 0.0f;\r
+static float RMSSD       = 0;\r
+static uint8_t HRAvg     = 0;\r
+static float SQ_SDNN     = 0.0f;\r
+static uint8_t AnomalyFlag=0;\r
+static uint8_t  SDNN_ReadyFlag  = 0;\r
+\r
+static uint8_t log_data_en_hrv= 0 ;\r
+static uint8_t sample_rate_hrv= 0 ;\r
+\r
+static float    rri           =  0.0f  ;\r
+static float    rri_time_point=  0.0f  ;\r
+static int      rri_confidence=  0     ;\r
+\r
+static uint8_t hrv_ret = 0;\r
+\r
+/*============================================================================\r
+STATIC FUNCTION PROTOTYPES\r
+============================================================================*/\r
+\r
+\r
+static void log_pah8series_data_header(uint32_t ch_num, uint32_t ir_ch_num, uint32_t g_sensor_mode);\r
+static void log_pah8series_data(const pah8series_data_t *data);\r
+//static void pah8116_ae_info_check(pah8series_data_t *pxialg_data, bool Tuning);        //V2.5\r
+static bool hrv_algorithm_calculate(pah8series_data_t *pxialg_data, uint32_t ch_num);\r
+static bool hrv_algorithm_process(pah8series_data_t *pxialg_data, uint32_t ch_num);    \r
+static uint8_t run_hrv_pxialg(uint32_t duration, const uint32_t* ppg_data, uint32_t ppg_count_per_ch, uint32_t ppg_ch_num, uint8_t touch_flag);\r
+\r
+static void log_pah8series_data_header(uint32_t ch_num, uint32_t ir_ch_num, uint32_t g_sensor_mode)\r
+{\r
+    //log pah8series data header\r
+    // (1)Using total channel numbers;\r
+    // (2)reserved;\r
+    // (3)reserved;\r
+    // (4)IR channel number;\r
+    // (5)MEMS mode 0:2G, 1:4G, 2:8G\r
+    //LOG_PRINT("PPG CH#, %d, %d, %d, %d, %d\n", ch_num, SETTING_VERSION, 0, ir_ch_num, g_sensor_mode);\r
+    LOG_PRINT("PPG CH#, %d, %d, %d, %d, %d\n", ch_num, 0, 0, ir_ch_num, g_sensor_mode);\r
+\r
+}\r
+static void log_pah8series_data(const pah8series_data_t *pxialg_data)\r
+{\r
+    int i = 0;\r
+    uint32_t *ppg_data = (uint32_t *)pxialg_data->ppg_data;\r
+       uint8_t *dac_data = _state.ppg_dac_data;\r
+    int16_t *mems_data = pxialg_data->mems_data;\r
+    int data_num = pxialg_data->nf_ppg_channel * pxialg_data->nf_ppg_per_channel;\r
+    \r
+    LOG_PRINT("Frame Count, %d \n", pxialg_data->frame_count);\r
+    LOG_PRINT("Time, %d \n", pxialg_data->time);\r
+    LOG_PRINT("PPG, %d, %d, ", pxialg_data->touch_flag, data_num);\r
+    for (i = 0; i < data_num; ++i)\r
+    {\r
+        LOG_PRINT("%d, ", *ppg_data);\r
+        ppg_data++;\r
+    }\r
+    LOG_PRINT("\n");\r
+    LOG_PRINT("MEMS, %d, ", pxialg_data->nf_mems);\r
+    for (i = 0; i < (pxialg_data->nf_mems * 3); ++i)\r
+    {\r
+        LOG_PRINT("%d, ", *mems_data);\r
+        mems_data++;\r
+    }\r
+    LOG_PRINT("\n");\r
+    LOG_PRINT("DAC, %d, ", data_num);\r
+    for (i = 0; i < data_num; ++i)\r
+    {\r
+        LOG_PRINT("%d, ", *dac_data);\r
+        dac_data++;\r
+    }\r
+    LOG_PRINT("\n");\r
+}\r
+\r
+\r
+bool  report_fifo_data_hrv(\r
+uint32_t ppg_timestamp,     \r
+uint32_t time_period, \r
+uint32_t *ppg_data,\r
+uint8_t *dac_data,\r
+uint8_t ppg_size,\r
+uint8_t ch_num,\r
+int16_t *acc_data,\r
+uint8_t acc_size,\r
+float *SDNN_out,\r
+uint8_t *HR_out,\r
+float *SDNN_singal_quality_out,\r
+uint8_t  *AnomalyFlag_out,    \r
+uint8_t *got_sdnn,\r
+uint8_t *got_time_out,\r
+uint8_t is_touched  ,\r
+uint8_t log_data_en,\r
+uint8_t sampling_rate\r
+)\r
+{\r
+//    ALG_PRINT("time_period = %d  timestamp =%d \n", time_period , ppg_timestamp);\r
+    log_data_en_hrv   =   log_data_en;\r
+       sample_rate_hrv   =   sampling_rate ;\r
+       LOG_PRINT("is_touched = %d\n",is_touched);\r
+    _state.pxialg_data.mems_data = acc_data ;\r
+    _state.pxialg_data.nf_mems =   acc_size  ;\r
+    _state.pxialg_data.touch_flag = is_touched<2 ? 1 : 0;\r
+    _state.pxialg_data.time = time_period;\r
+    _state.pxialg_data.ppg_data = (int32_t*)ppg_data;\r
+       \r
+       _state.ppg_dac_data = dac_data ;\r
+ \r
+    _state.pxialg_data.nf_ppg_channel = ch_num;\r
+    _state.pxialg_data.nf_ppg_per_channel = ppg_size;\r
+    ++_state.pxialg_data.frame_count;\r
+//    ALG_PRINT("_state.pxialg_data.time = %d  timestamp =%d \n", _state.pxialg_data.time , ppg_timestamp);\r
+    hrv_algorithm_process(&_state.pxialg_data, _state.pxialg_data.nf_ppg_channel);\r
+    *SDNN_out               = SDNN ;\r
+    *HR_out                 = HRAvg ;\r
+    *SDNN_singal_quality_out= SQ_SDNN;\r
+    *got_sdnn               = _hrv_state.has_got_sdnn;\r
+    *got_time_out           = _hrv_state.has_time_out;\r
+    *AnomalyFlag_out        = AnomalyFlag;\r
+    return true ;\r
+\r
+    \r
+}\r
+\r
+static bool hrv_algorithm_process(pah8series_data_t *pxialg_data, uint32_t ch_num)\r
+{\r
+    if(log_data_en_hrv)\r
+    {\r
+        // log header\r
+        if (need_log_header)\r
+        {\r
+            need_log_header = false;\r
+            log_pah8series_data_header(ch_num, PPG_IR_CH_NUM, ALG_GSENSOR_MODE);\r
+        }\r
+        \r
+        // log\r
+        log_pah8series_data(&_state.pxialg_data);\r
+    }\r
+    // hrv\r
+    if(_state.pxialg_data.touch_flag)\r
+    {\r
+        hrv_algorithm_calculate(&_state.pxialg_data, ch_num);\r
+    }else\r
+       {\r
+               hrv_algorithm_close();\r
+       }\r
+    return true;\r
+    \r
+    \r
+}\r
+static bool hrv_algorithm_calculate(pah8series_data_t *pxialg_data, uint32_t ch_num)\r
+{\r
+ bool has_updated = false;\r
+    \r
+#if defined(ENABLE_PXI_ALG_HRV)\r
+    //uint8_t ret = 0;\r
+    // Algorithm support only data length >= 10\r
+    if (pxialg_data->nf_ppg_per_channel < 10)\r
+    {\r
+        LOG_PRINT("hrv_algorithm_calculate(). fifo_data_num_per_ch = %d, is not enough to run algorithm \n", pxialg_data->nf_ppg_per_channel);\r
+        return false;\r
+    }\r
+    // Initialize algorithm\r
+    if (!_state.pxialg_has_init)\r
+    {\r
+        int buffer_size = 0;\r
+\r
+        //memset(&_sdnn_state, 0, sizeof(_sdnn_state));\r
+        memset(&_hrv_state, 0, sizeof(_hrv_state));\r
+        LOG_PRINT("HHRVGetVersion() = %d \n", HHRVGetVersion());\r
+\r
+        //buffer_size = HRVGetMemorySize(HRV_ENABLE_LHR, HRV_COLLECTION_SECONDS, HRV_SAMPLING_RATE);\r
+        buffer_size = RESPGetMemorySize(HRV_ENABLE_LHR,0, HRV_COLLECTION_SECONDS, HRV_SAMPLING_RATE);\r
+        LOG_PRINT("HRVGetMemorySize(), open_size = %d \n", buffer_size);\r
+\r
+        if (!buffer_size)\r
+        {\r
+            LOG_PRINT("HRVGetMemorySize(), failed to get memory size \n");\r
+            return 0;\r
+        }\r
+#ifdef _ALGO_NON_USE_HEAP_SIZE\r
+        //ASSERT(sizeof(pah_alg_buffer)>=buffer_size);\r
+               if (sizeof(pah_alg_buffer)>=buffer_size)\r
+               {\r
+                   memset(pah_alg_buffer,0x00,sizeof(pah_alg_buffer));\r
+            _hrv_state.pBuffer = pah_alg_buffer;\r
+               }else\r
+               {\r
+                       ALG_PRINT("HRV_buffer_size_not enough \n");\r
+                       return false;\r
+               }\r
+        \r
+#else\r
+        _hrv_state.pBuffer = (uint8_t*)malloc(buffer_size);\r
+#endif\r
+        if (!_hrv_state.pBuffer)\r
+        {\r
+            LOG_PRINT("Out of memory \n");\r
+            return 0;\r
+        }\r
+\r
+        if (!HHRVOpen(_hrv_state.pBuffer))\r
+        {\r
+            LOG_PRINT("HRVOpen() failed. \n");\r
+            return 0;\r
+        }\r
+        HHRVSetRRIQualityMode(1);\r
+        HHRVSetMemsScale(3);\r
+        \r
+        duration_total=0;\r
+        SDNN_ReadyFlag = 0 ;\r
+        _state.pxialg_has_init = true;\r
+    }\r
+\r
+    // Calculate HRV\r
+    run_hrv_pxialg(pxialg_data->time, (const uint32_t*)pxialg_data->ppg_data, pxialg_data->nf_ppg_per_channel, pxialg_data->nf_ppg_channel, pxialg_data->touch_flag);\r
+        \r
+#endif // ENABLE_PXI_ALG_HRV\r
+    \r
+    return has_updated;    \r
+}\r
+\r
+\r
+static uint8_t run_hrv_pxialg(uint32_t duration, const uint32_t* ppg_data, uint32_t ppg_count_per_ch_in, uint32_t ppg_ch_num_in, uint8_t touch_flag)\r
+{\r
+    uint32_t i = 0;\r
+    uint32_t green1_index = 0, green2_index = 0;\r
+       \r
+       uint32_t ppg_count_per_ch = 0 ; \r
+       uint32_t ppg_ch_num  = 0 ; \r
+    float  duration_new=0;\r
+       \r
+       if((sample_rate_hrv==50)&&(ppg_ch_num_in==1))\r
+       {\r
+               ppg_ch_num=2;\r
+               ppg_count_per_ch = ppg_count_per_ch_in/2 ;\r
+       }else\r
+       {\r
+               ppg_ch_num=ppg_ch_num_in;\r
+               ppg_count_per_ch = ppg_count_per_ch_in ;\r
+       }\r
+    \r
+    if (_hrv_state.has_got_sdnn)\r
+        return 1;\r
+\r
+    if (ppg_ch_num == 2)\r
+    {\r
+        green1_index = 0;\r
+        green2_index = 1;\r
+    }else if ((ppg_ch_num == 1)||(ppg_ch_num == 3))\r
+    {\r
+        green1_index = 0;\r
+        green2_index = 0;\r
+    }else\r
+    {\r
+        LOG_PRINT("Not support ppg_ch_num = %d \n", ppg_ch_num);\r
+        return 0;\r
+    }\r
+\r
+    duration_new = (float)duration;\r
+       float timeInterval =duration_new / ppg_count_per_ch;\r
+   //LOG_PRINT("timeInterval = "LOG_FLOAT_MARKER"  \n",LOG_FLOAT(timeInterval));\r
+\r
+       for (i = 0; i < ppg_count_per_ch; ++i)\r
+    {\r
+        uint32_t green1 = ppg_data[i * ppg_ch_num + green1_index];\r
+        uint32_t green2 = ppg_data[i * ppg_ch_num + green2_index];\r
+        float raw_data = (float)green1 + (float) green2;\r
+        // If using Interrupt mode call this API\r
+        //HRVSetDiffTime(timeInterval,1);\r
+              \r
+        //HRVProcess(touch_flag, raw_data);\r
+        HHRVProcess(touch_flag, raw_data, timeInterval);\r
+        if (HHRVGetOnlineRRIReportFlag() == 1) \r
+        {\r
+            rri = HHRVGetOnlineRRI();\r
+            rri_time_point = HHRVGetOnlineRRITimePoint();\r
+            int rr               =RESPGetRR();\r
+            LOG_PRINT("rri = %d,  rri_confidence_level= %d,  rri_time_point = %d, rr=:%d\n", (int)rri,rri_confidence,(int)rri_time_point,rr);                 \r
+        }    \r
+        duration_total+=timeInterval;\r
+        if((SDNN_ReadyFlag==0)&&(HHRVGetReadyFlag()==1))\r
+        {\r
+            SDNN_ReadyFlag = 1 ;\r
+        }\r
+        //if((duration_total>25000)&&(!HHRVGetReadyFlag()))\r
+        if((duration_total>25000)&&(SDNN_ReadyFlag==0))      \r
+                {\r
+            LOG_PRINT("PPG Raw data is too Weak\r\n");\r
+            LOG_PRINT("TEST Stop\r\n");\r
+            hrv_algorithm_close();\r
+            _hrv_state.has_time_out = 1;\r
+            return 1;\r
+        }    \r
+              \r
+                         \r
+        if(SDNN_ReadyFlag  == 1 || HHRVGetReadyFlag())\r
+        {\r
+            SDNN_ReadyFlag=1;\r
+            _hrv_state.collect_duration += timeInterval;\r
+            //LOG_PRINT("collect_duration = %d \n", (int)_hrv_state.collect_duration);\r
+\r
+            if(_hrv_state.collect_duration > (HRV_COLLECTION_SECONDS * 1000))\r
+            {\r
+                float SDNN  = 0;\r
+                int   HRAvg = 0;\r
+                HRAvg = HHRVGetHRAvg();\r
+            \r
+                SDNN = HHRVGetSDNN();\r
+                RMSSD = HHRVGetRMSSD();\r
+                float HRV_Quality=HHRVGetRRIQuality();\r
+                LOG_PRINT("HRAvg = %d  ,SDNN = "LOG_FLOAT_MARKER"  ,HRV_Quality = "LOG_FLOAT_MARKER"  \n", HRAvg , LOG_FLOAT(SDNN),LOG_FLOAT(HRV_Quality));\r
+\r
+                hrv_ret = (uint8_t)SDNN;\r
+\r
+                if(HRV_Quality>0.4f)\r
+                {\r
+                     LOG_PRINT("HRV_Quality Good\n");\r
+                }\r
+                else\r
+                {\r
+                    LOG_PRINT("HRV_Quality Weak\n");\r
+                }\r
+\r
+                hrv_algorithm_close();\r
+                _hrv_state.has_got_sdnn = 1;\r
+                return 1;\r
+            }\r
+        }    \r
+    }\r
+    LOG_PRINT("total_duration = %d \n",duration_total);\r
+\r
+    LOG_PRINT("Ready = %d\r\n", SDNN_ReadyFlag);\r
+    LOG_PRINT("collect_duration = %d \n", (int)_hrv_state.collect_duration);\r
+    \r
+    return 1;\r
+}\r
+\r
+\r
+\r
+\r
+\r
+void hrv_algorithm_close(void)\r
+{\r
+    \r
+#if defined(ENABLE_PXI_ALG_HRV)\r
+    HHRVClose();\r
+#ifndef _ALGO_NON_USE_HEAP_SIZE        \r
+    if (_hrv_state.pBuffer)\r
+    {\r
+        free(_hrv_state.pBuffer);\r
+        _hrv_state.pBuffer = NULL;\r
+    }\r
+#endif\r
+    _state.pxialg_has_init = 0 ;\r
+    log_data_en_hrv = 0 ;\r
+#endif // ENABLE_PXI_ALG_HRV\r
+}\r
+\r
+uint8_t pah_831x_alg_get_hrv_result(void)\r
+{\r
+    return hrv_ret;\r
+}\r
diff --git a/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/RR_HRV_STRESS_RRI/V3131/pah_hrv_alg.h b/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/RR_HRV_STRESS_RRI/V3131/pah_hrv_alg.h
new file mode 100644 (file)
index 0000000..fef8b98
--- /dev/null
@@ -0,0 +1,61 @@
+/*\r
+ * @Author: penglei 1624952103@qq.com\r
+ * @Date: 2025-12-25 09:34:31\r
+ * @LastEditors: penglei 1624952103@qq.com\r
+ * @LastEditTime: 2025-12-25 17:24:34\r
+ * @FilePath: /FD230/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/RR_HRV_STRESS_RRI/V3131/pah_hrv_alg.h\r
+ * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE\r
+ */\r
+/*==============================================================================\r
+* Edit History\r
+* \r
+* This section contains comments describing changes made to the module. Notice\r
+* that changes are listed in reverse chronological order. Please use ISO format\r
+* for dates.\r
+* \r
+* when       who       what, where, why\r
+* ---------- ---       -----------------------------------------------------------\r
+* 2016-04-29 bell      Initial revision.\r
+==============================================================================*/\r
+\r
+#ifndef __pah_hrv_alg_h__\r
+#define __pah_hrv_alg_h__\r
+\r
+\r
+\r
+#include <stdbool.h>\r
+#include <stdint.h>\r
+#include <string.h>\r
+//#include "pah831x_data_types.h"\r
+#include "pah831x_comm.h"\r
+#include "pah831x_config.h"\r
+#include "pah831x_main.h"\r
+//HR\r
+#include "pxialg.h"\r
+\r
+bool  report_fifo_data_hrv(\r
+uint32_t ppg_timestamp,        \r
+uint32_t time_period, \r
+uint32_t *ppg_data,\r
+uint8_t *dac_data,\r
+uint8_t ppg_size,\r
+uint8_t ch_num,\r
+int16_t *acc_data,\r
+uint8_t acc_size,\r
+float *SDNN_out,\r
+uint8_t *HR_out,\r
+float *SDNN_singal_quality_out,\r
+uint8_t  *AnomalyFlag_out,     \r
+uint8_t *got_sdnn,     \r
+uint8_t *got_time_out,\r
+uint8_t is_touched  ,\r
+uint8_t log_data_en,\r
+uint8_t sampling_rate\r
+);\r
+\r
+\r
+void hrv_algorithm_close(void);\r
+//void hrv_algorithm_init(void);\r
+uint8_t pah_831x_alg_get_hrv_result(void);\r
+\r
+#endif  // header guard\r
diff --git a/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/RR_HRV_STRESS_RRI/V3131/pah_stress_alg.c b/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/RR_HRV_STRESS_RRI/V3131/pah_stress_alg.c
new file mode 100644 (file)
index 0000000..5dd3a7c
--- /dev/null
@@ -0,0 +1,392 @@
+// c\r
+#include <string.h>\r
+#include <stdint.h>\r
+#include <stdbool.h>\r
+#include <stdlib.h>\r
+#include <stdio.h>\r
+#include <string.h>\r
+\r
+//#include "main.h"\r
+#include "pah831x_comm.h"\r
+#include "pah831x_config.h"\r
+#include "pah831x_main.h"\r
+#include "pah_stress_alg.h"\r
+// Platform support\r
+//#include "pxi_nrf_debug_print.h"\r
+// HRV algorithm\r
+//#include "pxialg_hrv.h"\r
+#include "pxialg_hrv_v3.h"\r
+typedef struct\r
+{\r
+     // pxialg\r
+    void*            pxialg_buffer;\r
+    pah8series_data_t   pxialg_data;\r
+    bool             pxialg_has_init;\r
+    uint64_t         last_report_time;\r
+       uint8_t*             ppg_dac_data;\r
+} main_stress_state_s;\r
+\r
+typedef struct\r
+{\r
+    void            *pBuffer;\r
+    float           collect_duration;\r
+    uint8_t         has_got_sdnn;\r
+    uint8_t         has_time_out;\r
+} stress_state_s;\r
+\r
+#define STRESS_ENABLE_LHR            1\r
+\r
+#define STRESS_SAMPLING_RATE        25//20\r
+\r
+#define STRESS_COLLECTION_SECONDS  60    // HRV measure seconds\r
+\r
+static main_stress_state_s _state;\r
+static stress_state_s _stress_state;\r
+static bool need_log_header = true;\r
+\r
+static uint32_t  duration_total=0;\r
+\r
+static  float Stress         = 0.0f;\r
+static  uint8_t HRAvg        = 0;\r
+static  float SQ_Stress      = 0.0f;\r
+static  uint8_t AnomalyFlag  = 0;\r
+uint8_t Stress_ReadyFlag     = 0;\r
+static uint8_t log_data_en_stress  = 0 ;\r
+\r
+static int grade=100;\r
+\r
+/*============================================================================\r
+STATIC FUNCTION PROTOTYPES\r
+============================================================================*/\r
+\r
+\r
+static void log_pah8series_data_header(uint32_t ch_num, uint32_t ir_ch_num, uint32_t g_sensor_mode);\r
+static void log_pah8series_data(const pah8series_data_t *data);\r
+//static void pah8116_ae_info_check(pah8series_data_t *pxialg_data, bool Tuning);        //V2.5\r
+static bool stress_algorithm_calculate(pah8series_data_t *pxialg_data, uint32_t ch_num);\r
+static bool stress_algorithm_process(pah8series_data_t *pxialg_data, uint32_t ch_num); \r
+\r
+#if defined(ENABLE_PXI_ALG_STRESS)\r
+static uint8_t run_stress_pxialg(uint32_t duration, const uint32_t* ppg_data, uint32_t ppg_count_per_ch, uint32_t ppg_ch_num, uint8_t touch_flag);\r
+#endif // ENABLE_PXI_ALG_HRV\r
+static void log_pah8series_data_header(uint32_t ch_num, uint32_t ir_ch_num, uint32_t g_sensor_mode)\r
+{\r
+    //log pah8series data header\r
+    // (1)Using total channel numbers;\r
+    // (2)reserved;\r
+    // (3)reserved;\r
+    // (4)IR channel number;\r
+    // (5)MEMS mode 0:2G, 1:4G, 2:8G\r
+    //LOG_PRINT("PPG CH#, %d, %d, %d, %d, %d\n", ch_num, SETTING_VERSION, 0, ir_ch_num, g_sensor_mode);\r
+    LOG_PRINT("PPG CH#, %d, %d, %d, %d, %d\n", ch_num, 0, 0, ir_ch_num, g_sensor_mode);\r
+\r
+}\r
+static void log_pah8series_data(const pah8series_data_t *pxialg_data)\r
+{\r
+    int i = 0;\r
+    uint32_t *ppg_data = (uint32_t *)pxialg_data->ppg_data;\r
+       uint8_t *dac_data = _state.ppg_dac_data;\r
+    int16_t *mems_data = pxialg_data->mems_data;\r
+    int data_num = pxialg_data->nf_ppg_channel * pxialg_data->nf_ppg_per_channel;\r
+    \r
+    LOG_PRINT("Frame Count, %d \n", pxialg_data->frame_count);\r
+    LOG_PRINT("Time, %d \n", pxialg_data->time);\r
+    LOG_PRINT("PPG, %d, %d, ", pxialg_data->touch_flag, data_num);\r
+    for (i = 0; i < data_num; ++i)\r
+    {\r
+        LOG_PRINT("%d, ", *ppg_data);\r
+        ppg_data++;\r
+    }\r
+    LOG_PRINT("\n");\r
+    LOG_PRINT("MEMS, %d, ", pxialg_data->nf_mems);\r
+    for (i = 0; i < (pxialg_data->nf_mems * 3); ++i)\r
+    {\r
+        LOG_PRINT("%d, ", *mems_data);\r
+        mems_data++;\r
+    }\r
+    LOG_PRINT("\n");\r
+    LOG_PRINT("DAC, %d, ", data_num);\r
+    for (i = 0; i < data_num; ++i)\r
+    {\r
+        LOG_PRINT("%d, ", *dac_data);\r
+        dac_data++;\r
+    }\r
+    LOG_PRINT("\n");\r
+}\r
+\r
+\r
+bool  report_fifo_data_stress(\r
+uint32_t ppg_timestamp,     \r
+uint32_t time_period, \r
+uint32_t *ppg_data,\r
+uint8_t *dac_data,\r
+uint8_t ppg_size,\r
+uint8_t ch_num,\r
+int16_t *acc_data,\r
+uint8_t acc_size,\r
+float *Stress_out,\r
+uint8_t *HR_out,\r
+float *Stress_singal_quality_out,\r
+uint8_t  *AnomalyFlag_out,    \r
+uint8_t *got_Stress,\r
+uint8_t is_touched,\r
+int32_t score  ,\r
+uint8_t log_data_en  \r
+)\r
+{\r
+//    ALG_PRINT("time_period = %d  timestamp =%d \n", time_period , ppg_timestamp);\r
+    log_data_en_stress   =   log_data_en;\r
+    _state.pxialg_data.mems_data = acc_data ;\r
+    _state.pxialg_data.nf_mems =   acc_size  ;\r
+    _state.pxialg_data.touch_flag = is_touched<2 ? 1 : 0;\r
+    _state.pxialg_data.time = time_period;\r
+    _state.pxialg_data.ppg_data = (int32_t*)ppg_data;\r
+       \r
+       _state.ppg_dac_data = dac_data ;\r
+ \r
+    _state.pxialg_data.nf_ppg_channel = ch_num;\r
+    _state.pxialg_data.nf_ppg_per_channel = ppg_size;\r
+    ++_state.pxialg_data.frame_count;\r
+//    ALG_PRINT("_state.pxialg_data.time = %d  timestamp =%d \n", _state.pxialg_data.time , ppg_timestamp);\r
+    grade = score ;\r
+    stress_algorithm_process(&_state.pxialg_data, _state.pxialg_data.nf_ppg_channel);\r
+    *Stress_out               = Stress ;\r
+    *HR_out                   = HRAvg ;\r
+    *Stress_singal_quality_out= SQ_Stress;\r
+    *got_Stress               = _stress_state.has_got_sdnn;\r
+    *AnomalyFlag_out            = AnomalyFlag;\r
+    return true ;\r
+\r
+    \r
+}\r
+\r
+static bool stress_algorithm_process(pah8series_data_t *pxialg_data, uint32_t ch_num)\r
+{\r
+    if(log_data_en_stress)\r
+    {\r
+        // log header\r
+        if (need_log_header)\r
+        {\r
+            need_log_header = false;\r
+            log_pah8series_data_header(ch_num, PPG_IR_CH_NUM, ALG_GSENSOR_MODE);\r
+        }\r
+        \r
+        // log\r
+        log_pah8series_data(&_state.pxialg_data);\r
+    }\r
+    // hrv\r
+    if(_state.pxialg_data.touch_flag)\r
+    {\r
+        stress_algorithm_calculate(&_state.pxialg_data, ch_num);\r
+    }else\r
+       {\r
+               stress_algorithm_close();\r
+       }\r
+    return true;\r
+    \r
+    \r
+}\r
+static bool stress_algorithm_calculate(pah8series_data_t *pxialg_data, uint32_t ch_num)\r
+{\r
+ bool has_updated = false;\r
+    \r
+#if defined(ENABLE_PXI_ALG_STRESS)\r
+    //uint8_t ret = 0;\r
+    // Algorithm support only data length >= 10\r
+\r
+    // Initialize algorithm\r
+    if (!_state.pxialg_has_init)\r
+    {\r
+        int buffer_size = 0;\r
+\r
+        //memset(&_sdnn_state, 0, sizeof(_sdnn_state));\r
+        memset(&_stress_state, 0, sizeof(_stress_state));\r
+        LOG_PRINT("HHRVGetVersion() = %d \n", HHRVGetVersion());\r
+\r
+        buffer_size = RESPGetMemorySize(STRESS_ENABLE_LHR,0 ,STRESS_COLLECTION_SECONDS, STRESS_SAMPLING_RATE);\r
+        LOG_PRINT("RESPGetMemorySize(), open_size = %d \n", buffer_size);\r
+\r
+        if (!buffer_size)\r
+        {\r
+            LOG_PRINT("RESPGetMemorySize(), failed to get memory size \n");\r
+            return 0;\r
+        }\r
+#ifdef _ALGO_NON_USE_HEAP_SIZE\r
+        //ASSERT(sizeof(pah_alg_buffer)>=buffer_size);\r
+               if (sizeof(pah_alg_buffer)>=buffer_size)\r
+               {\r
+                   memset(pah_alg_buffer,0x00,sizeof(pah_alg_buffer));\r
+            _stress_state.pBuffer = pah_alg_buffer;\r
+               }else\r
+               {\r
+                       ALG_PRINT("HRV_buffer_size_not enough \n");\r
+                       return false;\r
+               }\r
+        \r
+#else\r
+        _stress_state.pBuffer = (uint8_t*)malloc(buffer_size);\r
+#endif\r
+        if (!_stress_state.pBuffer)\r
+        {\r
+            LOG_PRINT("Out of memory \n");\r
+            return 0;\r
+        }\r
+\r
+        if (!HHRVOpen(_stress_state.pBuffer))\r
+        {\r
+            LOG_PRINT("HRVOpen() failed. \n");\r
+            return 0;\r
+        }\r
+        HHRVSetRRIQualityMode(1);\r
+        HHRVSetMemsScale(3);\r
+        duration_total=0;\r
+        Stress_ReadyFlag = 0 ;\r
+\r
+        _state.pxialg_has_init = true;\r
+    }\r
+\r
+    // Calculate HRV\r
+     run_stress_pxialg(pxialg_data->time, (const uint32_t*)pxialg_data->ppg_data, pxialg_data->nf_ppg_per_channel, pxialg_data->nf_ppg_channel, pxialg_data->touch_flag);\r
+        \r
+#endif // ENABLE_PXI_ALG_HRV\r
+    \r
+    return has_updated;    \r
+}\r
+\r
+#if defined(ENABLE_PXI_ALG_STRESS)\r
+static uint8_t run_stress_pxialg(uint32_t duration, const uint32_t* ppg_data, uint32_t ppg_count_per_ch, uint32_t ppg_ch_num, uint8_t touch_flag)\r
+{\r
+    uint32_t i = 0;\r
+    uint32_t green1_index = 0, green2_index = 0;\r
+    float  duration_new=0;\r
+    \r
+    if (_stress_state.has_got_sdnn)\r
+        return 1;\r
+\r
+    if (ppg_ch_num == 2)\r
+    {\r
+        green1_index = 0;\r
+        green2_index = 1;\r
+    }else if ((ppg_ch_num == 1)||(ppg_ch_num == 3))\r
+    {\r
+        green1_index = 0;\r
+        green2_index = 0;\r
+    }else\r
+    {\r
+        LOG_PRINT("Not support ppg_ch_num = %d \n", ppg_ch_num);\r
+        return 0;\r
+    }\r
+\r
+    duration_new = (float)duration;\r
+    float timeInterval =duration_new / ppg_count_per_ch;\r
+    LOG_PRINT("timeInterval = "LOG_FLOAT_MARKER"  \n",LOG_FLOAT(timeInterval));\r
+\r
+    for (i = 0; i < ppg_count_per_ch; ++i)\r
+    {\r
+        uint32_t green1 = ppg_data[i * ppg_ch_num + green1_index];\r
+        uint32_t green2 = ppg_data[i * ppg_ch_num + green2_index];\r
+        float raw_data = (float)green1 + (float) green2;\r
+        // If using Interrupt mode call this API\r
+\r
+        HHRVProcess(touch_flag, raw_data, timeInterval);  \r
+\r
+        \r
+        duration_total+=timeInterval;\r
+        if((Stress_ReadyFlag==0)&&(HHRVGetReadyFlag()==1))\r
+        {\r
+            Stress_ReadyFlag = 1 ;\r
+        }\r
+      \r
+        if((duration_total>25000)&&(Stress_ReadyFlag==0))\r
+        {\r
+            LOG_PRINT("PPG Raw data is too Weak\r\n");\r
+            LOG_PRINT("TEST Stop\r\n");\r
+            stress_algorithm_close();\r
+                return 1;\r
+        }    \r
+\r
+                         \r
+        if(Stress_ReadyFlag  == 1 || HHRVGetReadyFlag())\r
+        {\r
+            Stress_ReadyFlag=1;\r
+            _stress_state.collect_duration += timeInterval;\r
+            //LOG_PRINT("collect_duration = %d \n", (int)_hrv_state.collect_duration);\r
+\r
+            if(_stress_state.collect_duration > (STRESS_COLLECTION_SECONDS * 1000))\r
+            {\r
+                \r
+                HRAvg = HHRVGetHRAvg();\r
+                Stress= HHRVGetStress(grade);\r
+                //SDNN = HRVGetSDNN();\r
+              \r
+                SQ_Stress=HHRVGetRRIQuality();\r
+                LOG_PRINT("HRAvg = %d  ,Stress = "LOG_FLOAT_MARKER"  ,HRV_Quality = "LOG_FLOAT_MARKER"   \n", HRAvg , LOG_FLOAT(Stress),LOG_FLOAT(SQ_Stress));\r
+                if(Stress >=80 &&  Stress<=100)\r
+                {\r
+                    LOG_PRINT("Stress_Level High\n");\r
+                }\r
+                else if(Stress >=60 &&  Stress<80)\r
+                {\r
+                    LOG_PRINT("Stress_Level Medium\n");\r
+                }\r
+                else if(Stress >=30 &&  Stress<60)\r
+                {\r
+                    LOG_PRINT("Stress_Level Normal\n");\r
+                }\r
+                else\r
+                {\r
+                    LOG_PRINT("Stress_Level Relaxed\n");\r
+                }                                    \r
+            \r
+            \r
+                if(SQ_Stress>0.4f)\r
+                {\r
+                        LOG_PRINT("Stress_Quality Good\n");\r
+                }\r
+                else\r
+                {\r
+                        LOG_PRINT("Stress_Quality Weak\n");\r
+                }\r
+\r
+                stress_algorithm_close();\r
+                _stress_state.has_got_sdnn = 1;\r
+            \r
+                return 1;\r
+            }\r
+        }    \r
+    }\r
+    LOG_PRINT("total_duration = %d \n",duration_total);\r
+\r
+    LOG_PRINT("Ready = %d\r\n", Stress_ReadyFlag);\r
+    LOG_PRINT("collect_duration = %d \n", (int)_stress_state.collect_duration);\r
+\r
+    return 1;\r
+}\r
+#endif // ENABLE_PXI_ALG_HRV\r
+\r
+\r
+\r
+\r
+void stress_algorithm_close(void)\r
+{\r
+    \r
+#if defined(ENABLE_PXI_ALG_STRESS)\r
+    if (!_state.pxialg_has_init)\r
+    {\r
+        HHRVClose();\r
+#ifndef _ALGO_NON_USE_HEAP_SIZE        \r
+        if (_stress_state.pBuffer)\r
+        {\r
+            free(_stress_state.pBuffer);\r
+            _stress_state.pBuffer = NULL;\r
+        }\r
+#endif\r
+        _state.pxialg_has_init = 0 ;\r
+    }\r
+#endif // ENABLE_PXI_ALG_HRV\r
+}\r
+\r
+\r
+\r
+\r
+\r
diff --git a/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/RR_HRV_STRESS_RRI/V3131/pah_stress_alg.h b/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/RR_HRV_STRESS_RRI/V3131/pah_stress_alg.h
new file mode 100644 (file)
index 0000000..b3a29f6
--- /dev/null
@@ -0,0 +1,61 @@
+/*\r
+ * @Author: penglei 1624952103@qq.com\r
+ * @Date: 2025-12-25 09:34:31\r
+ * @LastEditors: penglei 1624952103@qq.com\r
+ * @LastEditTime: 2026-01-15 16:21:24\r
+ * @FilePath: /FD230/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/RR_HRV_STRESS_RRI/V3131/pah_stress_alg.h\r
+ * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE\r
+ */\r
+/*==============================================================================\r
+* Edit History\r
+* \r
+* This section contains comments describing changes made to the module. Notice\r
+* that changes are listed in reverse chronological order. Please use ISO format\r
+* for dates.\r
+* \r
+* when       who       what, where, why\r
+* ---------- ---       -----------------------------------------------------------\r
+* 2016-04-29 bell      Initial revision.\r
+==============================================================================*/\r
+\r
+#ifndef __pah_stress_alg_h__\r
+#define __pah_stress_alg_h__\r
+\r
+\r
+#include <stdbool.h>\r
+#include <stdint.h>\r
+#include <string.h>\r
+//#include "pah831x_data_types.h"\r
+#include "pah831x_comm.h"\r
+#include "pah831x_config.h"\r
+#include "pah831x_main.h"\r
+//HR\r
+#include "pxialg.h"\r
+\r
+#define ENABLE_PXI_ALG_STRESS\r
+\r
+bool  report_fifo_data_stress(\r
+uint32_t ppg_timestamp,        \r
+uint32_t time_period, \r
+uint32_t *ppg_data,\r
+uint8_t *dac_data,\r
+uint8_t ppg_size,\r
+uint8_t ch_num,\r
+int16_t *acc_data,\r
+uint8_t acc_size,\r
+float *Stress_out,\r
+uint8_t *HR_out,\r
+float *Stress_singal_quality_out,\r
+uint8_t  *Stress_AnomalyFlag_out,      \r
+uint8_t *got_Stress,   \r
+uint8_t is_touched,\r
+int32_t score  ,\r
+uint8_t log_data_en      \r
+);\r
+\r
+\r
+void stress_algorithm_close(void);\r
+//void hrv_algorithm_init(void);\r
+\r
+\r
+#endif  // header guard\r
diff --git a/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/RR_HRV_STRESS_RRI/V3131/pxialg_hrv_v3.h b/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/RR_HRV_STRESS_RRI/V3131/pxialg_hrv_v3.h
new file mode 100644 (file)
index 0000000..5100bfd
--- /dev/null
@@ -0,0 +1,80 @@
+#ifndef _PXIALG_HRV_v3_\r
+#define _PXIALG_HRV_v3_\r
+\r
+#include "stdint.h"\r
+\r
+#if defined(WIN32) && !defined(PXIALG_STATIC_LIB)\r
+#   ifdef PXIALG_EXPORTS\r
+#       define PXIALG_API   __declspec(dllexport)\r
+#   else\r
+#       define PXIALG_API   __declspec(dllimport)\r
+#   endif\r
+#else\r
+#   define PXIALG_API\r
+#endif // WIN32\r
+\r
+\r
+#ifdef __cplusplus\r
+extern "C"\r
+{\r
+#endif\r
+       PXIALG_API int HHRVReset(void);\r
+       PXIALG_API int HHRVRecompute(void);\r
+       PXIALG_API int HHRVGetMemorySize(int enable_lhr, int test_seconds, int sampling_rate);\r
+       PXIALG_API int HHRVOpen(void *p_buffer);\r
+       PXIALG_API int HHRVProcess(int data_ready, float data, float time);     \r
+       PXIALG_API int HHRVProcessMEMS(int data_ready, float data_mx, float data_my, float data_mz, float time);\r
+       PXIALG_API int HHRVProcessD(int data_ready, uint32_t data, float time); \r
+       PXIALG_API int HHRVProcessM(int data_ready, float *mems_data, float time);\r
+\r
+       PXIALG_API int HHRVClose(void);\r
+\r
+       PXIALG_API int HHRVGetVersion(void);\r
+       PXIALG_API float HHRVGetSDNN(void);\r
+       PXIALG_API int HHRVGetSDNNLevel(int m_iAge, float dSDNN);\r
+       PXIALG_API float HHRVGetLHRatio(float *nlf, float *nhf);\r
+       PXIALG_API float HHRVGetRMSSD(void);\r
+       PXIALG_API int HHRVGetSleepQuality(int age);\r
+       PXIALG_API int HHRVGetOnlineRRIReportFlag(void);\r
+       PXIALG_API float HHRVGetOnlineRRI(void);\r
+       PXIALG_API int HHRVGetOnlineRRIConfidenceLevel(void);\r
+       PXIALG_API float HHRVGetOnlineRRITimePoint(void);\r
+       PXIALG_API int HHRVGetRRINum(void);\r
+       PXIALG_API float * HHRVGetRRIBuf(void);\r
+       PXIALG_API float HHRVGetNoiseRate(void);\r
+       PXIALG_API float HHRVGetRRIStability(void);\r
+       PXIALG_API float HHRVGetRRIQuality(void);\r
+       PXIALG_API int HHRVGetReadyFlag(void);\r
+       PXIALG_API int HHRVGetHRAvg(void);\r
+       PXIALG_API float HHRVGetMEMSStd(void);\r
+    PXIALG_API int HHRVGetHR(void);\r
+       PXIALG_API float HHRVGetMEMSgs(void);\r
+       PXIALG_API float HHRVGetMEMSwgs(int win);\r
+\r
+       PXIALG_API int HHRVAlignment(int ecg_time[], int ecg_rri[], int ecg_len, \r
+                                    int ppg_rri[], int ppg_cf[], int ppg_len,\r
+                                    float align_ppg_time[], float align_ppg_rri[]);\r
+\r
+       //PXIALG_API void HRVSetFreqOffset(float FreqOffset);\r
+       //PXIALG_API void HRVSetDiffTime(float DiffTime, int SampleNum);\r
+       PXIALG_API int HHRVSetMemsScale(int scale);\r
+       PXIALG_API int HHRVSetRRIQualityMode(int mode);\r
+\r
+       PXIALG_API int HHRVGetOutput(float* p1, float* p2, float* p3, float* p4, float* p5, float* p6, float* p7, float* p8);\r
+\r
+       PXIALG_API int RESPReset(void);\r
+       PXIALG_API int RESPGetMemorySize(int enable_lhr, int enable_rr, int test_seconds, int sampling_rate);\r
+       PXIALG_API int RESPOpen(void *p_buffer);\r
+       PXIALG_API int RESPProcess(int data_ready, float data, float time);\r
+       PXIALG_API int RESPGetVersion(void);\r
+       PXIALG_API int RESPGetRR(void);\r
+       PXIALG_API int RESPClose(void);\r
+\r
+       //PXIALG_API int RESPClose(void);\r
+       PXIALG_API float HHRVGetStress(int grade); //v312\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif /* _PXIALG_HRV_v3_ */\r
+\r
diff --git a/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/RR_HRV_STRESS_RRI/V3131/test_library_HRV.c b/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/RR_HRV_STRESS_RRI/V3131/test_library_HRV.c
new file mode 100644 (file)
index 0000000..65dae5d
--- /dev/null
@@ -0,0 +1,169 @@
+// algorithm\r
+//#include "pxialg_hrv.h"\r
+#include "pxialg_hrv_v3.h"\r
+// testpattern\r
+#include "pah831x_testpattern_HRV.h"\r
+\r
+// C language\r
+#include <math.h>\r
+#include <string.h>\r
+#include <stdlib.h>\r
+#include <stdint.h>\r
+#include <stdbool.h>\r
+//#include "main.h"\r
+#include "pah831x_config.h"\r
+#include "pah831x_comm.h"\r
+\r
+\r
+\r
+#define array_szie(arr) (sizeof(arr) / sizeof(arr[0]))\r
+\r
+#define        TOTAL_CHANNEL              2\r
+#define        HRV_ENABLE_LHR             1\r
+#define        HRV_SAMPLING_RATE          20\r
+#define        HRV_COLLECTION_SECONDS     180\r
+static float   duration_total     =       0.0f;\r
+static float   collect_duration   =       0.0f;\r
+\r
+\r
+\r
+\r
+//============================================================================\r
+// PUBLIC FUNCTION DEFINITIONS\r
+//============================================================================\r
+//#define LOG_FLOAT_MARKER "%d.%03d"\r
+\r
+/**\r
+ * @brief Macro for dissecting a float number into two numbers (integer and residuum).\r
+ */\r
+//#define LOG_FLOAT(val) (int32_t)(val),(int32_t)(((val > 0) ? (val) - (int32_t)(val): (int32_t)(val) - (val))*1000)\r
+\r
+void test_library_HRV(void)\r
+{\r
+    int i               = 0;\r
+    int j               = 0;\r
+    int32_t version     = 0;\r
+   \r
+    int     buffer_size = 0;\r
+    void *pBuffer       = NULL;\r
+    //int     time_s,time_e,time_c;\r
+//    int  SDNN_ReadyFlag = 0;\r
+    //NRF_LOG_FLUSH();\r
+   \r
+   \r
+    version     = HHRVGetVersion();\r
+    LOG_PRINT("version =%d \n",version);\r
+   \r
+    //buffer_size = HRVGetMemorySize(HRV_ENABLE_LHR, HRV_COLLECTION_SECONDS, HRV_SAMPLING_RATE);\r
+    buffer_size = RESPGetMemorySize(HRV_ENABLE_LHR,0 ,HRV_COLLECTION_SECONDS, HRV_SAMPLING_RATE);\r
+    LOG_PRINT("buffer_size = %d  \n", buffer_size);\r
+    \r
+    pBuffer = malloc(buffer_size);\r
+\r
+    LOS_Mdelay(50);\r
+    if (!pBuffer)\r
+    {\r
+        LOG_PRINT("HRVGetMemorySize(), failed to get memory size \n");\r
+        return ;\r
+    }\r
+    LOS_Mdelay(50);\r
+    if (!HHRVOpen(pBuffer))\r
+    {\r
+        LOG_PRINT("HRVOpen() failed. \n");  \r
+         return;\r
+    }\r
+    HHRVSetRRIQualityMode(1);\r
+    HHRVSetMemsScale(3);\r
+\r
+    LOG_PRINT("ARRAY_SIZE = %d\n",array_szie(pah831x_rawdata_HRV));\r
+//******************************************************************         \r
+         //NRF_LOG_FLUSH();\r
+    LOS_Mdelay(50);\r
+     \r
+    for(i = 0; i < (array_szie(pah831x_rawdata_HRV)); i ++)\r
+    {\r
+\r
+        float duration_new      = (float)duration_HRV[i];\r
+        int   ppg_count_per_ch  = pah831x_rawdata_HRV[i][1];         \r
+        float timeInterval      = duration_new / (ppg_count_per_ch/NF_PPG_CHANNEL);\r
+//        int   HR_out = 0;\r
+        //LOG_PRINT("timeInterval = "LOG_FLOAT_MARKER"  ",LOG_FLOAT(timeInterval));\r
+        //log_printf("   ppg_num = %d  ",ppg_count_per_ch);\r
+        //LOS_Mdelay(50);\r
+ \r
+        for( j = 0 ; j <(ppg_count_per_ch/NF_PPG_CHANNEL) ; j ++)\r
+        {\r
+        #if NF_PPG_CHANNEL==1\r
+            int green1 = pah831x_rawdata_HRV[i][j+1];\r
+       \r
+            float raw_data=(float)green1;\r
+        #else\r
+            int green1 = pah831x_rawdata_HRV[i][NF_PPG_CHANNEL*j+2];\r
+             \r
+            int green2 = pah831x_rawdata_HRV[i][NF_PPG_CHANNEL*j+3];\r
+             \r
+            float raw_data = (float)green1 +(float) green2;\r
+        \r
+        #endif\r
+            \r
+//            HRVSetDiffTime(timeInterval,1);\r
+//            HRVProcess(1, raw_data);\r
+            \r
+            HHRVProcess(1, raw_data, timeInterval);  \r
+            duration_total+=timeInterval;\r
+            \r
+\r
+            {\r
+\r
+                collect_duration += timeInterval;\r
+              \r
+                if (collect_duration > (HRV_COLLECTION_SECONDS * 1000))\r
+                {\r
+                    LOG_PRINT("collect_duration = "LOG_FLOAT_MARKER" \n", LOG_FLOAT(collect_duration));\r
+                    LOG_PRINT("\n");\r
+                    float RMSSD  = 0;\r
+                    float SDNN  = 0;\r
+                    int   HRAvg = 0;\r
+                    //int   Anomaly_Flag=0;\r
+                    HRAvg = HHRVGetHRAvg();\r
+                    RMSSD = HHRVGetRMSSD() ;\r
+                    SDNN = HHRVGetSDNN();\r
+                    float tt=HHRVGetRRIQuality();\r
+                    //Anomaly_Flag= HRVGetAnomalyFlag();\r
+                    //LOG_PRINT("HRAvg = %d  SDNN = "LOG_FLOAT_MARKER"  HRV_Quality = "LOG_FLOAT_MARKER"  Anomaly_Flag= %d \n", HRAvg , LOG_FLOAT(SDNN),LOG_FLOAT(tt),Anomaly_Flag);\r
+                    LOG_PRINT("HRAvg = %d  ,SDNN = "LOG_FLOAT_MARKER"  ,HRV_Quality = "LOG_FLOAT_MARKER"  \n", HRAvg , LOG_FLOAT(SDNN),LOG_FLOAT(tt));\r
+                    LOG_PRINT("RMSSD = "LOG_FLOAT_MARKER"\n", LOG_FLOAT(RMSSD));\r
+                    //LOS_Mdelay(50);\r
+                    if(tt>0.4f)\r
+                    {\r
+                        LOG_PRINT("HRV_Quality Good\n");\r
+                    }else\r
+                    {\r
+                        LOG_PRINT("HRV_Quality Weak\n");\r
+                        \r
+                    }\r
+                    HHRVClose(); \r
+                    LOS_Mdelay(50);\r
+                    free(pBuffer);\r
+                    return ;\r
+                }\r
+            }\r
+                 \r
+//            HR_out = HRVGetHRAvg();\r
+//            LOG_PRINT("total_duration = "LOG_FLOAT_MARKER" ",LOG_FLOAT(duration_total));\r
+//            LOG_PRINT("  Ready = %d  ", HRVGetReadyFlag());\r
+//            LOG_PRINT("  collect_duration = "LOG_FLOAT_MARKER" \n", LOG_FLOAT(collect_duration));\r
+//            LOG_PRINT("  HR_out = %d \n", HR_out);\r
+\r
+        }\r
+        \r
+    }\r
+   \r
+}    \r
+\r
+\r
+\r
+   \r
+\r
+   \r
+\r
diff --git a/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/RR_HRV_STRESS_RRI/V3131/test_library_RR2.c b/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/RR_HRV_STRESS_RRI/V3131/test_library_RR2.c
new file mode 100644 (file)
index 0000000..c941aa5
--- /dev/null
@@ -0,0 +1,152 @@
+// algorithm\r
+#include "pxialg_hrv_v3.h"\r
+// testpattern\r
+#include "pah831x_testpattern_RR_2.h"\r
+// C language\r
+#include <math.h>\r
+#include <string.h>\r
+#include <stdlib.h>\r
+#include <stdint.h>\r
+#include <stdbool.h>\r
+\r
+#include "pah831x_comm.h"\r
+\r
+\r
+\r
+#define array_szie(arr) (sizeof(arr) / sizeof(arr[0]))\r
+\r
+\r
+//============================================================================\r
+// PUBLIC FUNCTION DEFINITIONS\r
+//============================================================================\r
+//#define LOG_FLOAT_MARKER "%d.%03d"\r
+\r
+/**\r
+ * @brief Macro for dissecting a float number into two numbers (integer and residuum).\r
+ */\r
+//#define LOG_FLOAT(val) (int32_t)(val),(int32_t)(((val > 0) ? (val) - (int32_t)(val): (int32_t)(val) - (val))*1000)\r
+\r
+#define array_szie(arr) (sizeof(arr) / sizeof(arr[0]))\r
+#define TOTAL_CHANNEL 3\r
+\r
+#define        RRI_ENABLE_LHR               0\r
+#define        RR_ENABLE                    1\r
+#define        RR_SAMPLING_RATE             25//100\r
+#define        RR_COLLECTION_SECONDS        60//180\r
+\r
+//============================================================================\r
+// PUBLIC FUNCTION DEFINITIONS\r
+//============================================================================\r
+//#define LOG_FLOAT_MARKER "%d.%03d"\r
+\r
+/**\r
+ * @brief Macro for dissecting a float number into two numbers (integer and residuum).\r
+ */\r
+//#define LOG_FLOAT(val) (int32_t)(val),(int32_t)(((val > 0) ? (val) - (int32_t)(val): (int32_t)(val) - (val))*1000)\r
+\r
+typedef struct\r
+{\r
+   void            *pBuffer;\r
+   float           collect_duration;\r
+   uint8_t         has_got_sdnn;\r
+} rr_state_s;\r
+#if 1\r
+void test_library_RR_2(void)\r
+{\r
+    int i                 = 0     ;\r
+    int j                 = 0     ;\r
+     //int32_t version       = 0     ;\r
+    int   buffer_size     = 0     ;\r
+    //int     time_s,time_e,time_c;\r
+    float    rri           =  0.0f  ;\r
+    float    rri_time_point=  0.0f  ;\r
+    int      rri_confidence=  0     ;\r
+    int      rr            =  0     ;\r
+    float    mems_flag     =0     ;\r
+\r
+    \r
+    int   ppg_sample_num = 0; \r
+    int   mems_number = 0; \r
+    uint32_t ppg_ch_num =  NF_PPG_CHANNEL ;\r
+    int32_t Green = 0 ;\r
+    int32_t touch_flag= 0 ;\r
+    \r
+    uint32_t duration = 0 ;\r
+    float mems_time = 0 ;\r
+   // float ppg_time = 0 ;\r
+\r
+    \r
+    rr_state_s _state;\r
+    buffer_size = RESPGetMemorySize(RRI_ENABLE_LHR,RR_ENABLE, RR_COLLECTION_SECONDS, RR_SAMPLING_RATE);\r
+    LOG_PRINT("RR_buffer_size = %d  \n", buffer_size);\r
+    LOG_PRINT("RR_Version = %d size = %d \n",RESPGetVersion(),buffer_size);\r
+\r
+     _state.pBuffer = (void*)malloc(buffer_size);\r
+    \r
+    RESPOpen(_state.pBuffer);\r
+    HHRVSetRRIQualityMode(1);\r
+    LOS_Mdelay(50);\r
+    if (!buffer_size)\r
+    {\r
+         LOG_PRINT("RRVGetMemorySize(), failed to get memory size \n");\r
+         return ;\r
+    }\r
+    LOS_Mdelay(50);\r
+\r
+    LOG_PRINT("ARRAY_SIZE = %d\n",array_szie(PAH831X_rawdata_RR));\r
+//******************************************************************         \r
+    LOS_Mdelay(50);\r
+\r
+    for(i = 0; i < (array_szie(PAH831X_rawdata_RR)); i ++)\r
+    {\r
+        ppg_sample_num  = PAH831X_rawdata_RR[i][1]/ppg_ch_num; \r
+        touch_flag      = PAH831X_rawdata_RR[i][0];  \r
+        duration        = duration_RR[i] ;\r
+       // ppg_time =   duration/ppg_sample_num;\r
+        mems_number       = PAH831X_mems_RR[i][0];\r
+        mems_time         = (float) duration /  mems_number;\r
+\r
+        //LOG_PRINT("ppg_sample_num = %d,ppg_time =%f\n",ppg_sample_num,ppg_time);\r
+        float Mems_data_buf[3]={0};\r
+        //LOG_PRINT("mems_time = %f\n",mems_time);\r
+        for( j = 0 ; j <mems_number ; j ++)\r
+        {\r
+            Mems_data_buf[0]=PAH831X_mems_RR[i][3*j+1];\r
+            Mems_data_buf[1]=PAH831X_mems_RR[i][3*j+2];\r
+            Mems_data_buf[2]=PAH831X_mems_RR[i][3*j+3]; \r
+            HHRVProcessM(1,Mems_data_buf,mems_time);\r
+        }\r
+        \r
+\r
+\r
+        for ( j = 0; j < ppg_sample_num; ++j)\r
+        {        \r
+            Green =  PAH831X_rawdata_RR[i][2+ppg_ch_num*j];\r
+            //LOG_PRINT("Green =%d\n",Green);\r
+            float raw_data = (float)Green ;\r
+                     \r
+            RESPProcess(touch_flag, raw_data, (float)duration/ppg_sample_num);\r
+            \r
+            if (HHRVGetOnlineRRIReportFlag() == 1) \r
+            {\r
+                rri = HHRVGetOnlineRRI();\r
+\r
+                rri_time_point = HHRVGetOnlineRRITimePoint();\r
+                rri_confidence   = HHRVGetOnlineRRIConfidenceLevel();\r
+                rr               =RESPGetRR();\r
+                mems_flag        = HHRVGetMEMSwgs(5);\r
+                \r
+                LOG_PRINT("rri = %d,  rri_confidence_level= %d,  rri_time_point = %d, rr= %d,  mems = %d  \n", (int)rri,rri_confidence,(int)rri_time_point, rr,(int)mems_flag); \r
+              \r
+            }\r
+        }                 \r
+    }        \r
+\r
+     free(_state.pBuffer);\r
+     return ;\r
+}    \r
+\r
+#endif\r
+\r
+\r
+\r
diff --git a/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/RR_HRV_STRESS_RRI/V3131/test_library_stress.c b/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/RR_HRV_STRESS_RRI/V3131/test_library_stress.c
new file mode 100644 (file)
index 0000000..f457c96
--- /dev/null
@@ -0,0 +1,213 @@
+// algorithm\r
+//#include "pxialg_hrv.h"\r
+#include "pxialg_hrv_v3.h"\r
+// testpattern\r
+#include "pah831X_testpattern_stress.h"\r
+\r
+// C language\r
+#include <math.h>\r
+#include <string.h>\r
+#include <stdlib.h>\r
+#include <stdint.h>\r
+#include <stdbool.h>\r
+//#include "main.h"\r
+#include "pah831x_config.h"\r
+#include "pah831x_comm.h"\r
+\r
+\r
+\r
+#define array_szie(arr) (sizeof(arr) / sizeof(arr[0]))\r
+\r
+#define        TOTAL_CHANNEL              2\r
+#define        HRV_ENABLE_LHR             1\r
+#define        HRV_SAMPLING_RATE          20\r
+#define        HRV_COLLECTION_SECONDS     60\r
+static float   duration_total     =       0.0f;\r
+static float   collect_duration   =       0.0f;\r
+\r
+\r
+\r
+\r
+//============================================================================\r
+// PUBLIC FUNCTION DEFINITIONS\r
+//============================================================================\r
+//#define LOG_FLOAT_MARKER "%d.%03d"\r
+\r
+/**\r
+ * @brief Macro for dissecting a float number into two numbers (integer and residuum).\r
+ */\r
+//#define LOG_FLOAT(val) (int32_t)(val),(int32_t)(((val > 0) ? (val) - (int32_t)(val): (int32_t)(val) - (val))*1000)\r
+\r
+void test_library_STRESS(void)\r
+{\r
+    int i               = 0;\r
+    int j               = 0;\r
+    int32_t version     = 0;\r
+    \r
+    int     buffer_size = 0;\r
+    void *pBuffer       = NULL;\r
+    //int     time_s,time_e,time_c;\r
+//    int  Stress_ReadyFlag = 0;\r
+    //NRF_LOG_FLUSH();\r
+  \r
+  \r
+    version     = HHRVGetVersion();\r
+    LOG_PRINT("version =%d \n",version);\r
+  \r
+    //buffer_size = HRVGetMemorySize(HRV_ENABLE_LHR, HRV_COLLECTION_SECONDS, HRV_SAMPLING_RATE);\r
+    buffer_size = RESPGetMemorySize(HRV_ENABLE_LHR,0, HRV_COLLECTION_SECONDS, HRV_SAMPLING_RATE);\r
+    LOG_PRINT("buffer_size = %d  \n", buffer_size);\r
+     \r
+    pBuffer = malloc(buffer_size);\r
+\r
+    LOS_Mdelay(50);\r
+    if (!buffer_size)\r
+    {\r
+        LOG_PRINT("HRVGetMemorySize(), failed to get memory size \n");\r
+        return ;\r
+    }\r
+    LOS_Mdelay(50);\r
+    if (!HHRVOpen(pBuffer))\r
+    {\r
+        LOG_PRINT("HRVOpen() failed. \n");  \r
+        return;\r
+    }\r
+    HHRVSetRRIQualityMode(1);\r
+    HHRVSetMemsScale(3);\r
+\r
+    LOG_PRINT("ARRAY_SIZE = %d\n",array_szie(pah831x_rawdata_Stress));\r
+//******************************************************************     \r
+    LOS_Mdelay(50);\r
+     \r
+    for(i = 0; i < (array_szie(pah831x_rawdata_Stress)); i ++)\r
+    {\r
+       \r
+        float duration_new      = (float)duration_Stress[i];\r
+        int   ppg_count_per_ch  = pah831x_rawdata_Stress[i][1];     \r
+        float timeInterval      = duration_new / (ppg_count_per_ch/NF_PPG_CHANNEL);\r
+        //LOG_PRINT("timeInterval = "LOG_FLOAT_MARKER"  ",LOG_FLOAT(timeInterval));\r
+        //log_printf("   ppg_num = %d  ",ppg_count_per_ch);\r
+        LOS_Mdelay(50);\r
+        //NRF_LOG_FLUSH();              \r
+\r
+        for( j = 0 ; j <(ppg_count_per_ch/NF_PPG_CHANNEL) ; j ++)\r
+        {\r
+        #if NF_PPG_CHANNEL==1\r
+            int green1 = pah831x_rawdata_Stress[i][j+1];\r
+           \r
+            float raw_data=(float)green1;\r
+        #else\r
+            int green1 = pah831x_rawdata_Stress[i][NF_PPG_CHANNEL*j+2];\r
+                 \r
+            int green2 = pah831x_rawdata_Stress[i][NF_PPG_CHANNEL*j+3];\r
+                 \r
+            float raw_data = (float)green1 +(float) green2;\r
+            \r
+        #endif\r
+           \r
+//            HRVSetDiffTime(timeInterval,1);\r
+//            HRVProcess(1, raw_data);\r
+            HHRVProcess(1, raw_data, timeInterval); \r
+            duration_total+=timeInterval;\r
+           \r
+\r
+            //nrf_delay_ms(50);\r
+//            if((duration_total>25000)&&(!HRVGetReadyFlag()))\r
+//            {\r
+//                LOG_PRINT("PPG Raw data is too Weak\r\n");    \r
+//                LOG_PRINT("TEST Stop\r\n");\r
+//                LOS_Mdelay(50);\r
+//                //NRF_LOG_FLUSH();              \r
+//                return ;\r
+//            }  \r
+//            if (Stress_ReadyFlag  == 1 || HRVGetReadyFlag())\r
+            {\r
+//                Stress_ReadyFlag=1;\r
+                collect_duration += timeInterval;\r
+              \r
+                if (collect_duration > (HRV_COLLECTION_SECONDS * 1000))\r
+                {\r
+                    LOG_PRINT("  collect_duration = "LOG_FLOAT_MARKER" \n", LOG_FLOAT(collect_duration));\r
+                    LOG_PRINT("\n");\r
+                    \r
+                    float RMSSD        =0.0f   ;\r
+                    float SDNN         =0.0f   ;\r
+                    float Stress       =0.0f   ;\r
+                    int   HRAvg        =0      ;\r
+                    //int   Anomaly_Flag =0      ;\r
+                    int   grade        =100    ;\r
+                    HRAvg = HHRVGetHRAvg()      ;\r
+                    RMSSD = HHRVGetRMSSD()      ;\r
+                    SDNN  = HHRVGetSDNN()       ;\r
+                    Stress= HHRVGetStress(grade);\r
+                    \r
+                    float tt=HHRVGetRRIQuality();\r
+                    //Anomaly_Flag= HRVGetAnomalyFlag();\r
+                    //LOG_PRINT("HRAvg = %d  SDNN = "LOG_FLOAT_MARKER" Stress = "LOG_FLOAT_MARKER"   HRV_Quality = "LOG_FLOAT_MARKER"  Anomaly_Flag= %d \n", HRAvg , LOG_FLOAT(SDNN),LOG_FLOAT(Stress),LOG_FLOAT(tt),Anomaly_Flag);\r
+                    LOG_PRINT("HRAvg = %d  ,SDNN = "LOG_FLOAT_MARKER" ,Stress = "LOG_FLOAT_MARKER"   H,RV_Quality = "LOG_FLOAT_MARKER"   \n", HRAvg , LOG_FLOAT(SDNN),LOG_FLOAT(Stress),LOG_FLOAT(tt));\r
+                    \r
+                    LOG_PRINT("RMSSD = "LOG_FLOAT_MARKER"\n", LOG_FLOAT(RMSSD));\r
+                    \r
+                       \r
+                    \r
+                    //NRF_LOG_FLUSH();\r
+                    if(Stress>=80 &&  Stress<=100)\r
+                    {\r
+                        LOG_PRINT("Stress_Level High\n"); \r
+                        LOS_Mdelay(50);\r
+                    }\r
+                    else if(Stress>=60 &&  Stress<80)\r
+                    {\r
+                        LOG_PRINT("Stress_Level Medium\n");\r
+                        LOS_Mdelay(50);\r
+                    }\r
+                    else if(Stress>=30 &&  Stress<60)\r
+                    {\r
+                        LOG_PRINT("Stress_Level Normal\n");\r
+                        LOS_Mdelay(50);\r
+                    }\r
+                    else\r
+                    {\r
+                        LOG_PRINT("Stress_Level Relaxed\n");\r
+                        LOS_Mdelay(50);\r
+                    }          \r
+                    if(tt>0.4f)\r
+                    {\r
+                        LOG_PRINT("HRV_Quality Good\n");\r
+                        LOS_Mdelay(50);\r
+                        //NRF_LOG_FLUSH(); \r
+                    }\r
+                    else\r
+                    {\r
+                        LOG_PRINT("HRV_Quality Weak\n");\r
+                        LOS_Mdelay(50);\r
+                      //NRF_LOG_FLUSH(); \r
+                    }\r
+                    //NRF_LOG_FLUSH(); \r
+                    HHRVClose(); \r
+                    return ;\r
+ \r
+                }\r
+            }\r
+        }\r
+\r
+//        HR_out = HRVGetHRAvg();\r
+//        LOG_PRINT("total_duration = "LOG_FLOAT_MARKER" ",LOG_FLOAT(duration_total));\r
+//        LOG_PRINT("  Ready = %d  ", HRVGetReadyFlag());\r
+//        LOG_PRINT("  collect_duration = "LOG_FLOAT_MARKER" ", LOG_FLOAT(collect_duration));\r
+//        LOG_PRINT("  HR_out = %d \n", HR_out);\r
+//        LOS_Mdelay(50); \r
+\r
+    }\r
+    //NRF_LOG_FLUSH();\r
+    free(pBuffer);\r
+    return ;\r
+\r
+}  \r
+\r
+\r
+\r
+   \r
+\r
+   \r
+\r
diff --git a/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/SHRD/V307009/libv307009_4.a b/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/SHRD/V307009/libv307009_4.a
new file mode 100644 (file)
index 0000000..d0d7a95
Binary files /dev/null and b/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/SHRD/V307009/libv307009_4.a differ
diff --git a/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/SHRD/V307009/pah_shrd_alg.c b/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/SHRD/V307009/pah_shrd_alg.c
new file mode 100644 (file)
index 0000000..029e6ea
--- /dev/null
@@ -0,0 +1,310 @@
+// c\r
+#include <string.h>\r
+#include <stdint.h>\r
+#include <stdbool.h>\r
+#include <stdlib.h>\r
+#include <stdio.h>\r
+#include <string.h>\r
+\r
+#include "pah831x_config.h"\r
+#include "pah831x_main.h"\r
+#include "pah831x_comm.h"\r
+\r
+// SHR algorithm\r
+#include "pxialg.h"\r
+\r
+\r
+//#include "pxialg.h"\r
+#if defined(ENABLE_PXI_ALG_HRD)\r
+#include "pah8series_api_c.h"\r
+#endif\r
+#ifndef ENABLE_PXI_ALG_HRD\r
+typedef struct {\r
+    uint8_t                     frame_count;\r
+    uint32_t                    time;\r
+    uint8_t                     touch_flag;\r
+    uint32_t                    nf_ppg_channel;\r
+    uint32_t                    nf_ppg_per_channel;\r
+    int32_t                     *ppg_data;\r
+    uint32_t                    nf_mems;\r
+    int16_t                     *mems_data;\r
+} pah8series_data_t;\r
+\r
+#endif\r
+\r
+\r
+typedef struct\r
+{\r
+    // pxialg\r
+   void*                 pxialg_buffer_hr;\r
+    pah8series_data_t    pxialg_data;\r
+    bool                 pxialg_has_init;\r
+    uint64_t             last_report_time;\r
+    uint32_t             Expo_time[3];\r
+    uint8_t              LEDDAC[3];\r
+    alg_status_e         alg_status;\r
+    uint8_t              Tuning;\r
+    uint16_t             Touch_data;\r
+    uint8_t*             ppg_dac_data;\r
+} main_shrd_state_s;\r
+\r
+\r
+static bool need_log_header = true;\r
+//static shrd_info_t    _shrd_detect_item;\r
+static main_shrd_state_s _state;\r
+\r
+\r
+static float    myHR                    = 0.0f;\r
+static float    hr_grader               = 0.0f;\r
+\r
+static uint8_t last_hr_info_shrd = 0 ;\r
+static uint8_t log_data_en_shrd  = 0 ;\r
+static uint8_t alg_work_mode_shrd= 0 ;\r
+\r
+\r
+/*============================================================================\r
+STATIC FUNCTION PROTOTYPES\r
+============================================================================*/\r
+\r
+static void log_pah8series_data_header(uint32_t ch_num, uint32_t ir_ch_num, uint32_t g_sensor_mode);\r
+static void log_pah8series_data(const pah8series_data_t *data);\r
+static bool shrd_algorithm_process(pah8series_data_t *pxialg_data, uint32_t ch_num);\r
+static uint8_t shrd_algorithm_calculate(pah8series_data_t *pxialg_data);\r
+\r
+\r
+static void log_pah8series_data_header(uint32_t ch_num, uint32_t ir_ch_num, uint32_t g_sensor_mode)\r
+{\r
+    //log pah8series data header\r
+    // (1)Using total channel numbers;\r
+    // (2)reserved;\r
+    // (3)reserved;\r
+    // (4)IR channel number;\r
+    // (5)MEMS mode 0:2G, 1:4G, 2:8G\r
+    //LOG_PRINT("PPG CH#, %d, %d, %d, %d, %d\n", ch_num, get_ppg_setting_version(), 0, ir_ch_num, g_sensor_mode);\r
+    LOG_PRINT("PPG CH#, %d, %d, %d, %d, %d\n", ch_num, 0, 0, ir_ch_num, g_sensor_mode);\r
+\r
+}\r
+static void log_pah8series_data(const pah8series_data_t *pxialg_data)\r
+{\r
+    int i = 0;\r
+    uint32_t *ppg_data = (uint32_t *)pxialg_data->ppg_data;\r
+    \r
+    uint8_t *dac_data = _state.ppg_dac_data;\r
+    \r
+    int16_t *mems_data = pxialg_data->mems_data;\r
+    int data_num = pxialg_data->nf_ppg_channel * pxialg_data->nf_ppg_per_channel;\r
+    \r
+    LOG_PRINT("Frame Count, %d \n", pxialg_data->frame_count);\r
+    LOG_PRINT("Time, %d \n", pxialg_data->time);\r
+    LOG_PRINT("PPG, %d, %d, ", pxialg_data->touch_flag+alg_work_mode_shrd, data_num);\r
+    for (i = 0; i < data_num; ++i)\r
+    {\r
+        LOG_PRINT("%d, ", *ppg_data);\r
+        ppg_data++;\r
+    }\r
+    LOG_PRINT("\n");\r
+    LOG_PRINT("MEMS, %d, ", pxialg_data->nf_mems);\r
+    for (i = 0; i < (pxialg_data->nf_mems * 3); ++i)\r
+    {\r
+        LOG_PRINT("%d, ", *mems_data);\r
+        mems_data++;\r
+    }\r
+    LOG_PRINT("\n");\r
+    LOG_PRINT("DAC, %d, ", data_num);\r
+    for (i = 0; i < data_num; ++i)\r
+    {\r
+        LOG_PRINT("%d, ", *dac_data);\r
+        dac_data++;\r
+    }\r
+    LOG_PRINT("\n");\r
+\r
+}\r
+\r
+bool  report_fifo_data_shrd(\r
+uint32_t ppg_timestamp,     \r
+uint32_t time_period, \r
+uint32_t *ppg_data,\r
+uint8_t *dac_data,\r
+uint32_t ppg_size,\r
+uint32_t ch_num,\r
+int16_t *acc_data,\r
+uint8_t acc_size, \r
+float *hr_out, \r
+float *hr_grader_out, \r
+uint8_t is_touched,\r
+uint8_t log_data_en \r
+)\r
+{\r
+//    ALG_PRINT("time_period = %d  timestamp =%d \n", time_period , ppg_timestamp);\r
+ \r
+    log_data_en_shrd   =   log_data_en;\r
+\r
+    \r
+    _state.pxialg_data.mems_data = acc_data ;\r
+    _state.pxialg_data.nf_mems =   acc_size  ;\r
+    _state.pxialg_data.touch_flag = is_touched<2 ? 1 : 0;\r
+    //_state.pxialg_data.touch_flag = is_touched;\r
+    _state.pxialg_data.time = time_period;\r
+    _state.pxialg_data.ppg_data = (int32_t*)ppg_data;\r
+ \r
+    _state.pxialg_data.nf_ppg_channel = ch_num;\r
+    _state.pxialg_data.nf_ppg_per_channel = ppg_size;\r
+    ++_state.pxialg_data.frame_count;\r
+\r
+    _state.ppg_dac_data = dac_data ;\r
+    \r
+    shrd_algorithm_process(&_state.pxialg_data, _state.pxialg_data.nf_ppg_channel);\r
+    \r
+    *hr_out        = myHR ;\r
+    *hr_grader_out  = hr_grader ;\r
+    return true ;\r
+\r
+    \r
+}\r
+\r
+static bool shrd_algorithm_process(pah8series_data_t *pxialg_data, uint32_t ch_num)\r
+{\r
+    \r
+    if(log_data_en_shrd)\r
+    {\r
+        // log header\r
+        if (need_log_header)\r
+        {\r
+            need_log_header = false;\r
+            log_pah8series_data_header(ch_num, PPG_IR_CH_NUM, ALG_GSENSOR_MODE);\r
+        }\r
+        \r
+        log_pah8series_data(&_state.pxialg_data);\r
+    }\r
+       if(_state.pxialg_data.touch_flag)\r
+    {\r
+               shrd_algorithm_calculate(&_state.pxialg_data);\r
+       }\r
+    \r
+    return true;        \r
+}\r
+\r
+\r
+static uint8_t shrd_algorithm_calculate(pah8series_data_t *pxialg_data)\r
+{\r
+    \r
+    int     i    ;\r
+\r
+   \r
+    uint8_t ret_value = 0;\r
+    uint8_t ready_flag = 0;\r
+\r
+#if defined(ENABLE_PXI_ALG_SHRD)\r
+    // Initialize algorithm\r
+    if (!_state.pxialg_has_init)\r
+    {\r
+        int32_t version     = 0;\r
+        int     buffer_size = 0;\r
+        \r
+             \r
+        /// static  Hr\r
+        version = PxiAlg_Version();\r
+        LOG_PRINT("HR_Version = %d \r\n", version);            \r
+         \r
+        uint32_t Query_Mem_Size = PxiAlg_Query_Mem_Size();\r
+        LOG_PRINT("HR_Mem_Size = %d \r\n", Query_Mem_Size);\r
+            \r
+        _state.pxialg_buffer_hr = malloc(Query_Mem_Size);\r
+             \r
+                \r
+        if (!PxiAlg_Open_Mem(_state.pxialg_buffer_hr))\r
+        {\r
+            LOG_PRINT("PxiAlg_Open_Mem fail \n\r");\r
+            return false;\r
+        }\r
+                    \r
+        PxiAlg_SetQualityThreshold(0.35f); \r
+        PxiAlg_SetHRSmoothWeight(0.9f); \r
+        PxiAlg_SetProcWindow(5.0f, 5.0f); \r
+        PxiAlg_SetTimeoutLength(30.0f);\r
+        PxiAlg_SetMemsScale(0);                      //MEMS 2/4/8/16G : 0/1/2/3\r
+        PxiAlg_SetSkipSampleNum(10); \r
+        PxiAlg_SetMemsScaleBase(1, 0); //MEMS 2/4/8/16G : 0/1/2/3\r
+        PxiAlg_SetForceOutputLink(15, 90, 60, 1, 0.9f); \r
+        //PxiAlg_SetNormalOutput(200, 40, 1); \r
+        PxiAlg_SetForceRipple(3, 1); \r
+        //PxiAlg_SetForceOutput(30, 120, 45);\r
+        //PxiAlg_SetForceOutputTime(10);\r
+        \r
+        if(_state.pxialg_data.nf_ppg_channel==5)\r
+        {\r
+            PxiAlg_SetPackage(0, 1);\r
+        }else if(_state.pxialg_data.nf_ppg_channel==4)\r
+        {\r
+            PxiAlg_SetPackage(2, 1);\r
+        }\r
+        //_state.pxialg_data.frame_count=0;\r
+        myHR = 0 ;\r
+        hr_grader = 0 ;\r
+        _state.pxialg_has_init = true;\r
+    }\r
+    //log_printf("frame_count =  %d  \n",frame_number);        \r
+\r
+\r
+       // PxiAlg_Process(ppg_raw, MEMS_Data);\r
+    uint32_t time_s = pxi_get_tick_count();\r
+    ret_value = PxiAlg_Entrance(pxialg_data); \r
+    uint32_t time_e = pxi_get_tick_count();         \r
+\r
+    uint32_t time_diff=time_e-time_s;\r
+    LOG_PRINT("hr process-time = %d \n",time_diff);\r
+\r
+    //if( ret_value == FLAG_DATA_READY) \r
+    if(PxiAlg_GetHrUpdateFlag())\r
+    {\r
+        PxiAlg_HrGet(&myHR);\r
+        ready_flag = PxiAlg_GetReadyFlag();\r
+        PxiAlg_GetSigGrade(&hr_grader);      \r
+    }\r
+    LOG_PRINT("myHR = "LOG_FLOAT_MARKER" ",LOG_FLOAT(myHR));\r
+    LOG_PRINT(",grade = "LOG_FLOAT_MARKER" \n",LOG_FLOAT(hr_grader));\r
+ \r
+\r
+#endif\r
+    \r
+    return true;\r
+}\r
+\r
+\r
+\r
+\r
+\r
+void shrd_algorithm_close(void)\r
+{\r
+ #if defined(ENABLE_PXI_ALG_SHRD)\r
+    if (_state.pxialg_has_init)\r
+    {\r
+        _state.pxialg_has_init = false;\r
+        need_log_header = true;\r
+        _state.pxialg_data.frame_count=0;\r
+\r
+        PxiAlg_Close();\r
+\r
+        free(_state.pxialg_buffer_hr);\r
+\r
+        LOG_PRINT("shrd_algorithm_close\n");\r
+\r
+    }\r
+#endif // ENABLE_PXI_ALG_SHRD\r
+}   \r
+\r
+void shrd_algorithm_init(void)\r
+{\r
+    #if defined(ENABLE_PXI_ALG_SHRD)\r
+    \r
+    memset(&_state, 0, sizeof(_state));\r
+    _state.last_report_time = pxi_get_tick_count();\r
+    LOG_PRINT("_state.last_report_time = %d \n", _state.last_report_time);\r
+    PxiAlg_Close();\r
+    free(_state.pxialg_buffer_hr);\r
+\r
+    _state.pxialg_data.frame_count=0;\r
+    need_log_header = true;\r
+#endif // ENABLE_PXI_ALG_SHRD\r
+}\r
+\r
diff --git a/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/SHRD/V307009/pah_shrd_alg.h b/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/SHRD/V307009/pah_shrd_alg.h
new file mode 100644 (file)
index 0000000..be7066d
--- /dev/null
@@ -0,0 +1,47 @@
+/*==============================================================================\r
+* Edit History\r
+* \r
+* This section contains comments describing changes made to the module. Notice\r
+* that changes are listed in reverse chronological order. Please use ISO format\r
+* for dates.\r
+* \r
+* when       who       what, where, why\r
+* ---------- ---       -----------------------------------------------------------\r
+* 2016-04-29 bell      Initial revision.\r
+==============================================================================*/\r
+\r
+#ifndef __pah_shrd_alg_h__\r
+#define __pah_shrd_alg_h__\r
+\r
+\r
+#include <stdbool.h>\r
+#include <stdint.h>\r
+#include <string.h>\r
+\r
+\r
+\r
+\r
+bool  report_fifo_data_shrd(\r
+uint32_t ppg_timestamp,     \r
+uint32_t time_period, \r
+uint32_t *ppg_data,\r
+uint8_t *dac_data,\r
+uint32_t ppg_size,\r
+uint32_t ch_num,\r
+int16_t *acc_data,\r
+uint8_t acc_size, \r
+float *hr_out, \r
+float *hr_grader_out, \r
+uint8_t is_touched,\r
+uint8_t log_data_en \r
+);\r
+\r
+\r
+\r
+\r
+void shrd_algorithm_init(void);\r
+void shrd_algorithm_close(void);\r
+\r
+\r
+#endif  // header guard\r
+\r
diff --git a/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/SHRD/V307009/pxialg.h b/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/SHRD/V307009/pxialg.h
new file mode 100644 (file)
index 0000000..a638ec2
--- /dev/null
@@ -0,0 +1,709 @@
+#ifndef PXIALG_H__\r
+#define PXIALG_H__\r
+#include "stdint.h"\r
+#include "pxivar.h"\r
+\r
+#define FW                             1\r
+\r
+#define FW_DEBUG  0\r
+#if ( FW == 0 )\r
+#undef FW_DEBUG\r
+#define FW_DEBUG  0\r
+#endif\r
+\r
+//#define STRIIV\r
+\r
+#if FW == 1\r
+#define PXIALG_API\r
+#else\r
+#ifdef PXIALG_EXPORTS\r
+#define PXIALG_API             __declspec(dllexport)\r
+#else\r
+#define PXIALG_API             __declspec(dllimport)\r
+#endif\r
+#endif\r
+/*\r
+typedef struct {\r
+       uint8_t                                         frame_count;\r
+       uint32_t                                        time;\r
+       uint8_t                                         touch_flag;\r
+       uint32_t                                        nf_ppg_channel;\r
+       uint32_t                                        nf_ppg_per_channel;\r
+       int32_t                                         *ppg_data;\r
+       uint32_t                                        nf_mems;\r
+       int16_t                                         *mems_data;\r
+} pah8series_data_t;\r
+\r
+typedef enum {\r
+       FLAG_DATA_READY                         = 0,\r
+       FLAG_DATA_NOT_READY,\r
+       FLAG_DATA_LOSS,\r
+       FLAG_NO_TOUCH,\r
+       FLAG_DATA_ERROR,\r
+       FLAG_POOR_SIGNAL,\r
+       FLAG_FIFO_ERROR,\r
+       FLAG_TIMMING_ERROR,\r
+       FLAG_MEMS_ERROR,\r
+       FLAG_HR_UPDATE                          = 16,\r
+       FLAG_SG_UPDATE,\r
+} PXI_STATUS_FLAG;\r
+\r
+typedef enum {\r
+       _quick_report_rms_gs_th         = 0,\r
+       _hr_speed_mode,\r
+       _support_cal_motion_idx_enhancement_enh,\r
+       _rsv1,\r
+       _set_switch_mems_fft_max_energy_th,\r
+       _set_switch_mems_large_energy_num_th,\r
+       _set_switch_mn_fft_energy_lo_thr,\r
+       _set_switch_mn_fft_energy_hi_thr,\r
+\r
+       _ppg_large_energy_num_th,\r
+       _max_hr_idx_th,\r
+       _min_hr_idx_th,\r
+       _ppg_fft_total_peak_num_th,\r
+       _mems_large_energy_num_th,\r
+       _mems_fft_max_energy_th,\r
+       _support_signal_grade_motion_detection_enh,\r
+       _support_signal_grade_check_signal_lelvel_enh,\r
+       _support_signal_grade_large_energy_num_enh,\r
+       _rsv2,\r
+       _rsv3,\r
+       _set_reg_shake_count_th0,\r
+} PXI_PARAM_SET;\r
+\r
+typedef enum {\r
+       _rms_gs                                         = 0,\r
+       _signal_level,\r
+       _cal_motion_idx,\r
+       _is_prediction_hr,\r
+       _get_switch_mems_fft_max_energy_th,\r
+       _get_switch_mems_large_energy_num_th,\r
+       _get_switch_mn_fft_energy_lo_thr,\r
+       _get_switch_mn_fft_energy_hi_thr,\r
+\r
+       _hr_sample_count,\r
+       _ppg_large_energy_num,\r
+       _signal_grade_motion_frm,\r
+       _ppg_fft_max_energy_idx,\r
+       _ppg_fft_total_peak_num,\r
+       _mems_large_energy_num,\r
+       _mems_fft_max_energy,\r
+       _grade,\r
+       _signal_grade_hr_to_low_frm,\r
+       _flag_signal_grade_ready_go,\r
+       _motion_flag,\r
+       _get_reg_shake_count_th0,\r
+} PXI_PARAM_GET;\r
+\r
+typedef enum {\r
+       MemsLargeEnergyNumTh            = 0,\r
+       MemsFftMaxEnergyTh,\r
+       QuickReportRmsGsTh,\r
+       SupportSigGradeMotionDetection,\r
+       PpgLargeEnergyNumTh,\r
+       SupportSigGradeLargeEnergyNumEnh,\r
+       SupportSigGradeLargeEnergyNumTh,\r
+       SigGradeThr,\r
+       SupportSigGradeCheckSigLevel,\r
+       FlagCheckNotStableFirstHR,\r
+       MaxHrDefinition,\r
+       MinHrDefinition,\r
+} PXI_PARAM2;\r
+*/\r
+\r
+#if FW == 1\r
+/**\r
+ * @brief When HRD and MEMS data are ready, call this function to do the algorithm processing\r
+ *\r
+ * @param[in] HRD_Data   Pointer to the buffer where HRD data (13 Bytes) is stored.\r
+ * @param[in] MEMS_Data  Pointer to the buffer where MEMS data (3*sizeof(float) Bytes) is stored.\r
+ *\r
+ * @return Return one of the PXI_STATUS_FLAG types.\r
+ */\r
+PXIALG_API int32_t PxiAlg_ProcessByTime(unsigned char *HRD_Data, float *MEMS_Data, float time);\r
+PXIALG_API int32_t PxiAlg_Process(unsigned char *HRD_Data, float *MEMS_Data);\r
+\r
+/**\r
+ * @brief Call this function to get Heart Rate\r
+ *\r
+ * @param[out] hr   Pointer to a float variable where heart rate is stored\r
+ *\r
+ * @return None\r
+ */\r
+PXIALG_API void PxiAlg_HrGet(float *hr);\r
+\r
+\r
+PXIALG_API void PxiAlg_FlagInitialSignalNoiseGet(uint8_t *flag);\r
+/**\r
+ * @brief Call this function to feed Algorithm raw data(19 Bytes), and get Signal Grade and Heart Rate\r
+ *\r
+ * @param[in] pixart_19_byte_data   Pointer to a arrag where raw data is stored\r
+ *     Format: 13 bytes PPG + G-sensor X_L[13] + X_H[14] + Y_L[15] + Y_H[16] + Z_L[17] + Z_H[18]\r
+ * @param[out] grade   Pointer to a float variable where signal grade is stored.\r
+ * @param[out] heart_rate   Pointer to a float variable where heart rate is stored\r
+ *\r
+ * @return status bit field, combinatoin of the list below\r
+ * 1 << FLAG_DATA_READY,\r
+ * 1 << FLAG_DATA_NOT_READY,\r
+ * 1 << FLAG_DATA_LOSS,\r
+ * 1 << FLAG_NO_TOUCH,\r
+ * 1 << FLAG_DATA_ERROR,\r
+ * 1 << FLAG_POOR_SIGNAL,\r
+ * 1 << FLAG_FIFO_ERROR,\r
+ * 1 << FLAG_TIMMING_ERROR,\r
+ * 1 << FLAG_MEMS_ERROR,\r
+ * 1 << FLAG_HR_UPDATE,\r
+ * 1 << FLAG_SG_UPDATE,\r
+ */\r
+PXIALG_API uint32_t PxiAlg_HRM(uint8_t *pixart_19_byte_data, float *grade, float * heart_rate);\r
+#else\r
+/**\r
+ * @brief When HRD, MEMS, and ECG data are ready, call this function to do the algorithm processing\r
+ *\r
+ * @param[in] HRD_Data   Pointer to the buffer where HRD data (13 Bytes) is stored.\r
+ * @param[in] MEMS_Data  Pointer to the buffer where MEMS data (12 Bytes) is stored.\r
+ * @param[in] ECG_Data   Pointer to the buffer where ECG data (4 Bytes) is stored.\r
+ *\r
+ * @return Return one of the PXI_STATUS_FLAG types.\r
+ */\r
+PXIALG_API int32_t PxiAlg_Process(unsigned char *HRD_Data, float *MEMS_Data, float ECG_Data);\r
+\r
+/**\r
+ * @brief When HRD, MEMS, ECG data, and time interval are ready, call this function to do the algorithm processing\r
+ *\r
+ * @param[in] HRD_Data   Pointer to the buffer where HRD data (13 Bytes) is stored.\r
+ * @param[in] MEMS_Data  Pointer to the buffer where MEMS data (12 Bytes) is stored.\r
+ * @param[in] ECG_Data   Pointer to the buffer where ECG data (4 Bytes) is stored.\r
+ * @param[in] time              Time interval.\r
+ *\r
+ * @return Return one of the PXI_STATUS_FLAG types.\r
+ */\r
+PXIALG_API int32_t PxiAlg_ProcessByTime(unsigned char *HRD_Data, float *MEMS_Data, float ECG_Data, float time);\r
+\r
+/**\r
+ * @brief Call this function to get Heart Rate\r
+ *\r
+ * @param[out] hr   Pointer to a float variable where heart rate is stored\r
+ *\r
+ * @return None\r
+ */\r
+PXIALG_API void PxiAlg_HrGet(float *hr);\r
+\r
+PXIALG_API void PxiAlg_FlagInitialSignalNoiseGet(uint8_t *flag);\r
+\r
+/**\r
+ * @brief Call this            function to get output\r
+ *\r
+ * @param[out] output  Pointer to a SHr_motion_plot variable where output information is stored\r
+ *\r
+ * @return None\r
+ */\r
+PXIALG_API int32_t PxiAlg_OutputGet(void *output);\r
+\r
+/**\r
+ * @brief Call this            function to get a specific parameter\r
+ *\r
+ * @param[out] param   Pointer to the start address of the variable of parameter list\r
+ * @param[in]  offset  Offset of the parameter variable\r
+ * @param[in]  size            Type size of the parameter\r
+ *\r
+ * @return None\r
+ */\r
+PXIALG_API void PxiAlg_ParamGet(uint8_t *param, int32_t offset, int32_t size);\r
+\r
+/**\r
+ * @brief Call this            function to set a specific parameter\r
+ *\r
+ * @param[in] offset   Offset of the parameter variable\r
+ * @param[in] size             Type size of the parameter\r
+ * @param[in] param            Pointer to the start address of the variable of parameter list\r
+ *\r
+ * @return None\r
+ */\r
+PXIALG_API void PxiAlg_ParamSet(int32_t offset, int32_t size, uint8_t *param);\r
+#endif\r
+\r
+/**\r
+* @brief When HRD, MEMS, and Expo data are ready, call this function to do the algorithm processing\r
+*\r
+* @param[in] HRD_Data   Pointer to the buffer where HRD data (13 Bytes) is stored.\r
+* @param[in] MEMS_Data  Pointer to the buffer where MEMS data (12 Bytes) is stored.\r
+* @param[in] expo       Exposure Time.\r
+*\r
+* @return Return one of the PXI_STATUS_FLAG types.\r
+*/\r
+PXIALG_API int32_t PxiAlg_Process_Expo(unsigned char *HRD_Data, float *MEMS_Data, int expo);\r
+\r
+/**\r
+ * @brief Call this function to determine the version of the algorithm\r
+ *\r
+ *\r
+ * @return Version of the algorithm\r
+ */\r
+PXIALG_API int32_t PxiAlg_Version(void);\r
+\r
+/**\r
+ * @brief Call this funtion to get Ready_Flag\r
+ *\r
+ * @return Return Ready_Flag\r
+ */\r
+PXIALG_API unsigned char PxiAlg_GetReadyFlag(void);\r
+\r
+/**\r
+ * @brief Call this funtion to get Motion_Flag\r
+ *\r
+ * @return Return Motion_Flag\r
+ */\r
+PXIALG_API unsigned char PxiAlg_GetMotionFlag(void);\r
+\r
+\r
+/**\r
+* @brief Call this function to get force flag\r
+*\r
+* @return force_flag\r
+*/\r
+PXIALG_API unsigned char PxiAlg_GetForceFlag(void);\r
+\r
+/**\r
+ * @brief Call this funtion to get Timeout_Flag\r
+ *\r
+ * @return Return Timeout_Flag\r
+ */\r
+PXIALG_API unsigned char PxiAlg_GetTimeoutFlag(void);\r
+\r
+/**\r
+ * @brief Call this function to set PPG buffer pointer and size\r
+ *\r
+ * @param[in] ppg_buffer   Pointer to a float buffer where the PPG data would be stored\r
+ * @param[in] size   PPG buffer size\r
+ *\r
+ * @return None\r
+ */\r
+PXIALG_API void PxiAlg_SetPPGBuffer(float *ppg_buffer, int32_t size);\r
+\r
+/**\r
+ * @brief Call this function to set algorithm parameters\r
+ *\r
+ * @param[in] hr_param   Pointer to a "HR_Param" sturcture where the parameters are stored.\r
+ *\r
+ * @return None\r
+ */\r
+PXIALG_API void PxiAlg_SetParam(void *hr_param);\r
+\r
+/**\r
+ * @brief Call this function to set data\r
+ *\r
+ * @param[in] data   Pointer to an algorithm-dependent data\r
+ *\r
+ * @return None\r
+ */\r
+PXIALG_API void PxiAlg_SetData(void *data);\r
+\r
+\r
+/**\r
+ * @brief Call this function to notify algorithm the Output Data Rate of PPG Sensor\r
+ *\r
+ * @param[in] odr                      The Output Data Rate of PPG Sensor. Only 10,20,40,160 and 200 ODR are supported.\r
+ *\r
+ * @return 1 for success. 0 for failure.\r
+ */\r
+PXIALG_API uint8_t PxiAlg_SetODR(int32_t odr);\r
+\r
+/**\r
+ * @brief Call this function to notify algorithm the Timeout Length of PPG Sensor\r
+ *\r
+ * @param[in] t                        The Timeout Length of PPG Sensor. Unit: second.\r
+ *\r
+ * @return 1 for success. 0 for failure.\r
+ */\r
+PXIALG_API uint8_t PxiAlg_SetTimeoutLength(int32_t t);\r
+\r
+/**\r
+ * @brief Call this function to notify algorithm the Quality Threshold of PPG Sensor\r
+ *\r
+ * @param[in] th                       The Quality Threshold of PPG Sensor. Range: 0.0 ~ 1.0\r
+ *\r
+ * @return 1 for success. 0 for failure.\r
+ */\r
+PXIALG_API uint8_t PxiAlg_SetQualityThreshold(float th);\r
+\r
+/**\r
+* @brief Call this function to notify algorithm the HR smooth weight of PPG Sensor\r
+*\r
+* @param[in] w                 The weight. Range: 0.0 ~ 1.0\r
+*\r
+* @return 1 for success. 0 for failure.\r
+*/\r
+PXIALG_API uint8_t PxiAlg_SetHRSmoothWeight(float w);\r
+\r
+/**\r
+* @brief Call this function to notify algorithm the length of process window of PPG Sensor\r
+*\r
+* @param[in] t                 The normal time window.\r
+* @param[in] t_fast            The fast time window.\r
+*\r
+* @return 1 for success. 0 for failure.\r
+*/\r
+PXIALG_API uint8_t PxiAlg_SetProcWindow(float t, float t_fast);\r
+\r
+/**\r
+ * @brief Call this function to notify algorithm the number of PPG sample to skip\r
+ *\r
+ * @param[in] num                      The number\r
+ *\r
+ * @return 1 for success. 0 for failure.\r
+ */\r
+PXIALG_API uint8_t PxiAlg_SetSkipSampleNum(int num);\r
+\r
+\r
+/**\r
+ * @brief Call this function to notify algorithm the MEMS Scale of Motion Sensor\r
+ *\r
+ * @param[in] scale                    The MEMS Scale of Motion Sensor. 0: +-2G, 1: +-4G, 2: +-8G, and 3: +-16G\r
+ *\r
+ * @return 1 for success. 0 for failure.\r
+ */\r
+PXIALG_API uint8_t PxiAlg_SetMemsScale(int scale);\r
+PXIALG_API uint8_t PxiAlg_SetMemsScaleBase(int scale, int th);\r
+\r
+\r
+\r
+\r
+\r
+/**\r
+ * @brief Call this function to notify algorithm the time length to force hr to update\r
+ *\r
+ * @param[in] t                        The time length\r
+ * @param[in] ub               The upper bound\r
+ * @param[in] lb               The lower bound\r
+ *\r
+ * @return 1 for success. 0 for failure.\r
+ */\r
+PXIALG_API uint8_t PxiAlg_SetForceOutput(int t, int ub, int lb);\r
+\r
+\r
+\r
+/**\r
+ * @brief Call this function to notify algorithm force hr to output\r
+ *\r
+ * @param[in] t                        The time length\r
+ * @param[in] ub               The upper bound\r
+ * @param[in] lb               The lower bound\r
+ * @param[in] link_flag        To link with normal output\r
+ * @param[in] w                    Smoothing weight between force and normal\r
+ *\r
+ * @return 1 for success. 0 for failure.\r
+ */\r
+PXIALG_API uint8_t PxiAlg_SetForceOutputLink(int t, int ub, int lb, int link_flag, float w);\r
+\r
+\r
+/**\r
+ * @brief Call this function to notify algorithm normal hr to output\r
+ *\r
+ * @param[in] ub                   The upper bound\r
+ * @param[in] lb                   The lower bound\r
+ * @param[in] static_flag      First normal output at static\r
+ *\r
+ * @return 1 for success. 0 for failure.\r
+ */\r
+PXIALG_API uint8_t PxiAlg_SetNormalOutput(int ub, int lb, int static_flag);\r
+\r
+\r
+/**\r
+ * @brief Call this function to notify algorithm the time to force hr to output\r
+ *\r
+ * @param[in] t                        The duration\r
+ * @param[in] bpm              The amplitude\r
+ *\r
+ * @return 1 for success. 0 for failure.\r
+ */\r
+PXIALG_API uint8_t PxiAlg_SetForceRipple(int t, int bpm);\r
+\r
+\r
+/**\r
+ * @brief Call this function to notify algorithm the time to force hr to output\r
+ *\r
+ * @param[in] ch               The ppg channel selection\r
+ * @param[in] flag             The resample flag\r
+ *\r
+ * @return 1 for success. 0 for failure.\r
+ */\r
+PXIALG_API uint8_t PxiAlg_SetPackage(int ch, int flag);\r
+\r
+\r
+/**\r
+ * @brief Call this function to notify algorithm hr model range\r
+ *\r
+ * @param[in] ub               The motion upper bound\r
+ * @param[in] lb               The motion lower bound\r
+ *\r
+ * @return 1 for success. 0 for failure.\r
+ */\r
+PXIALG_API uint8_t PxiAlg_SetHrModel(int ub, int lb);\r
+\r
+\r
+/**\r
+ * @brief Call this function to notify algorithm the time length to force hr to update\r
+ *\r
+ * @param[in] t                        The time length\r
+ *\r
+ * @return 1 for success. 0 for failure.\r
+ */\r
+PXIALG_API uint8_t PxiAlg_SetForceUpdateTimeLength(int t);\r
+/**\r
+ * @brief Call this function to notify algorithm the time to force hr to output\r
+ *\r
+ * @param[in] t                        The time length\r
+ *\r
+ * @return 1 for success. 0 for failure.\r
+ */\r
+PXIALG_API uint8_t PxiAlg_SetForceOutputTime(int t);\r
+/**\r
+ * @brief Call this function to notify algorithm the bound of hr\r
+ *\r
+ * @param[in] ub                       The upper bound\r
+ * @param[in] lb                       The lower bound\r
+ *\r
+ * @return 1 for success. 0 for failure.\r
+ */\r
+PXIALG_API uint8_t PxiAlg_SetFullHRBound(int ub, int lb);\r
+/**\r
+ * @brief Call this function to notify algorithm the bound of first hr\r
+ *\r
+ * @param[in] ub                       The upper bound\r
+ * @param[in] lb                       The lower bound\r
+ * @param[in] t                        The time length to keep this bound\r
+ *\r
+ * @return 1 for success. 0 for failure.\r
+ */\r
+PXIALG_API uint8_t PxiAlg_SetFirstHRBound(int ub, int lb, int t);\r
+\r
+\r
+\r
+/**\r
+ * @brief Call this function to notify algorithm the MEMS Energy Threshold of Motion Sensor\r
+ *\r
+ * @param[in] lower                    The MEMS energy lower threshold\r
+ * @param[in] upper                    The MEMS energy upper threshold\r
+ *\r
+ * @return 1 for success. 0 for failure.\r
+ */\r
+PXIALG_API uint8_t PxiAlg_SetMemsEnergyThrd(int lower, int upper);\r
+\r
+/**\r
+ * @brief Call this function to set PPG Signal Grade Threshold\r
+ *\r
+ * @param[in] threshold                The PPG Signal Grade Threshold. Its value ranges from 0 to 100.\r
+ *\r
+ * @return 1 for success. 0 for failure.\r
+ */\r
+PXIALG_API uint8_t PxiAlg_SetSigGradeThrd(float thrd);\r
+\r
+/**\r
+ * @brief Call this function to set parameters of PPG Signal Grade\r
+ *\r
+ * @param[in] frm_thrd         The PPG Signal Grade Frame Threshold.\r
+ * @param[in] rep_count                The PPG Signal Grade Repetitive Counter.\r
+ *\r
+ * @return 1 for success. 0 for failure.\r
+ */\r
+PXIALG_API uint8_t PxiAlg_SetSigGradeParam(int16_t frm_thrd, int16_t rep_count);\r
+\r
+/**\r
+ * @brief Call this function to enable or disable fast output mode\r
+ *\r
+ * @param[in] en               The flag of fast output mode.\r
+ */\r
+\r
+PXIALG_API void PxiAlg_EnableFastOutput(uint8_t en);\r
+\r
+/**\r
+ * @brief Call this function to enable or disable motion mode\r
+ *\r
+ * @param[in] en               The flag of motion mode.\r
+ */\r
+PXIALG_API void PxiAlg_EnableMotionMode(uint8_t en);\r
+\r
+/**\r
+ * @brief Call this function to enable or disable auto mode\r
+ *\r
+ * @param[in] en               The flag of auto mode.\r
+ */\r
+PXIALG_API void PxiAlg_EnableAutoMode(uint8_t en);\r
+\r
+/**\r
+ * @brief Call this function to enable or disable tracking mode after fast output\r
+ *\r
+ * @param[in] en               The flag of tracking mode.\r
+ */\r
+PXIALG_API void PxiAlg_EnableTrackingAfterFastOut(uint8_t en);\r
+\r
+/**\r
+ * @brief Call this function to enable or disable mems0 signal grade mode\r
+ *\r
+ * @param[in] en               1 : enable. 0 : disable.\r
+ */\r
+PXIALG_API void PxiAlg_EnableMEMS0SigGrade(uint8_t en);\r
+\r
+//PXIALG_API void PxiAlg_EnableMEMS0SigGrade(uint8_t en, uint8_t idx);\r
+//// idx = 0: PxiAlg_EnableFastOutput(uint8_t en);\r
+//// idx = 1: PxiAlg_EnableMotionMode(uint8_t en);\r
+//// idx = 2: PxiAlg_EnableAutoMode(uint8_t en);\r
+//// idx = 3: PxiAlg_EnableTrackingAfterFastOut(uint8_t en);\r
+\r
+/**\r
+ * @brief Call this function to get PPG Signal Grade\r
+ *\r
+ * @param[out] grade   Pointer to a float variable where signal grade is stored.\r
+ *\r
+ * @return  Return 1 when Signal Grade is ready. Otherwise, return 0.\r
+ */\r
+PXIALG_API uint8_t PxiAlg_GetSigGrade(float *grade);\r
+\r
+/**\r
+ * @brief Call this function to get the alarm flag of fast output\r
+ *\r
+ * @param[out] flag            The alarm flag of fast output\r
+ *\r
+ * @return  Return 1 when the flag is set. Otherwise, return 0.\r
+ */\r
+PXIALG_API uint8_t PxiAlg_GetFastOutAlarmFlag(void);\r
+\r
+/**\r
+ * @brief Call this function to get the alarm flag of signal bad\r
+ *\r
+ * @param[out] flag            The alarm flag of fast output\r
+ *\r
+ * @return  Return 1 when the flag is set. Otherwise, return 0.\r
+ */\r
+PXIALG_API uint8_t PxiAlg_GetSignalBadAlarm(void);\r
+\r
+/**\r
+ * @brief Call this function to open algorithm\r
+ */\r
+#if FW == 1\r
+PXIALG_API uint8_t PxiAlg_Open_Mem(void *mem);\r
+#else\r
+PXIALG_API void PxiAlg_Open(void);\r
+#endif\r
+\r
+/**\r
+ * @brief Call this function to close algorithm\r
+ */\r
+PXIALG_API void PxiAlg_Close(void);\r
+\r
+/**\r
+ * @brief Call this function to initialize 200Hz low-pass filter\r
+ */\r
+PXIALG_API void PxiAlg_LPF200Hz_Init(void);\r
+\r
+/**\r
+ * @brief Call this function to process 200Hz low-pass filter\r
+ */\r
+PXIALG_API float PxiAlg_LPF200Hz_Process(float data);\r
+\r
+/**\r
+ * @brief Call this function to get PPG Signal Level\r
+ *\r
+ * @param[out] grade   Pointer to a float variable where signal level is stored.\r
+ *\r
+ * @return  Return 1 when Signal Level is ready. Otherwise, return 0.\r
+ */\r
+#ifndef REDUCE_MORE_CODE_SIZE\r
+PXIALG_API uint8_t PxiAlg_Get_Signal_Level(float *level);\r
+#endif\r
+/**\r
+ * @brief Call this function to enable/disable Check_Not_Stable_First_HR\r
+ *\r
+ * @param[in] 1 : enable, 0: disable\r
+ */\r
+PXIALG_API void PxiAlg_Check_Not_Stable_First_HR(uint8_t check); \r
+\r
+/**\r
+ * @brief Call this function to set Signal_Grade_Large_Energy_Num_Th_Lo\r
+ *\r
+ * @param[in] Threshold.\r
+ *\r
+ */\r
+PXIALG_API void PxiAlg_Set_Signal_Grade_Large_Energy_Num_Th_Lo(uint8_t th) ;\r
+\r
+/**\r
+ * @brief Call this function to Set SportMode\r
+ *\r
+ * @@param[in] en      0: disable 1: enable\r
+ *\r
+ * @return  Return 1 when Set Signal Grade Large Energy Num Threshold is ready. Otherwise, return 0.\r
+ */\r
+PXIALG_API void PxiAlg_SetSportMode(uint8_t en);\r
+\r
+/**\r
+ * @brief Call this function to Set Signal Grade Large Energy Num Threshold\r
+ *\r
+ * @@param[in] th      => threshold\r
+ *\r
+ * @return  Return 1 when Set Signal Grade Large Energy Num Threshold is ready. Otherwise, return 0.\r
+ */\r
+PXIALG_API uint8_t PxiAlg_Set_Signal_Grade_Large_Energy_Num_Th(uint8_t th);\r
+\r
+\r
+/**\r
+ * @brief Call this function to Set Algorithm Parameters\r
+ *\r
+ * @@param[in] index - index of parameters, param - parameter value\r
+ *\r
+ * @return  Return 1 when Set algorithm parameter suceeessfully. Otherwise, return 0.\r
+ */\r
+PXIALG_API uint8_t PxiAlg_Set_Parameter(uint32_t index, float param);\r
+\r
+/**\r
+ * @brief Call this function to Get Algorithm Parameters\r
+ *\r
+ * @@param[in] index - index of parameters, *param - pointer to parameter value\r
+ *\r
+ * @return  Return 1 when Set algorithm parameter suceeessfully. Otherwise, return 0.\r
+ */\r
+PXIALG_API uint8_t PxiAlg_Get_Parameter(uint32_t index, float *param);\r
+\r
+/**\r
+* @brief Call this function to Set Algorithm Parameters (2nd Version)\r
+*\r
+* @@param[in] index - index of parameters, param - parameter value\r
+*\r
+* @return  Return 1 when Set algorithm parameter suceeessfully. Otherwise, return 0.\r
+*/\r
+PXIALG_API uint8_t PxiAlg_Set_Parameter2(uint32_t index, float param);\r
+\r
+/**\r
+* @brief Call this function to Get Algorithm Parameters (2nd Version)\r
+*\r
+* @@param[in] index - index of parameters, *param - pointer to parameter value\r
+*\r
+* @return  Return 1 when Set algorithm parameter suceeessfully. Otherwise, return 0.\r
+*/\r
+PXIALG_API uint8_t PxiAlg_Get_Parameter2(uint32_t index, float *param);\r
+\r
+\r
+\r
+PXIALG_API uint8_t PxiAlg_Set_Cal_Flag_HR_Trust_Energy_Ratio(float fValue);\r
+PXIALG_API uint8_t PxiAlg_Set_Cal_Flag_HR_Trust_Large_Energy_Num_Th(uint16_t fValue);\r
+PXIALG_API uint8_t PxiAlg_Get_Cal_Flag_HR_Trust_Energy_Ratio(float *fValue);\r
+PXIALG_API uint8_t PxiAlg_Get_Cal_Flag_HR_Trust_Large_Energy_Num_Th(uint16_t *fValue);\r
+\r
+PXIALG_API uint8_t PxiAlg_Get_Flag_HR_Trust(uint8_t *flag);\r
+\r
+#if (ANDROID_JNI==1)\r
+PXIALG_API uint8_t PxiAlg_Get_ParameterName(uint32_t index, const char **param);\r
+#endif\r
+\r
+PXIALG_API uint8_t PxiAlg_DecodeProcess(uint32_t data, int touch_flag, float time_in);\r
+PXIALG_API uint8_t  PxiAlg_Entrance_0(pah8series_data_t *pah8series_data);\r
+PXIALG_API uint8_t  PxiAlg_Entrance(pah8series_data_t *pah8series_data);\r
+PXIALG_API uint8_t  PxiAlg_EntranceD(pah8series_data_t *pah8series_data);\r
+PXIALG_API uint32_t PxiAlg_Query_Mem_Size(void);\r
+PXIALG_API uint8_t PxiAlg_GetHrUpdateFlag(void);\r
+\r
+PXIALG_API void PxiAlg_SetData_Seg(pah8series_data_t *pah8series_data);\r
+PXIALG_API uint8_t PxiAlg_Process_Seg(uint8_t *is_finished);\r
+PXIALG_API uint8_t PxiAlg_ProcessD_Seg(uint8_t *is_finished);\r
+#endif /* PXIALG_H__ */\r
diff --git a/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/SHRD/V307009/pxivar.h b/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/SHRD/V307009/pxivar.h
new file mode 100644 (file)
index 0000000..3571111
--- /dev/null
@@ -0,0 +1,100 @@
+#ifndef PXIVAR_H__\r
+#define PXIVAR_H__\r
+\r
+#include "stdint.h"\r
+\r
+#if defined(ENABLE_PXI_ALG_HRD)\r
+#include "pah8series_api_c.h"\r
+#endif\r
+#ifndef ENABLE_PXI_ALG_HRD\r
+typedef struct {\r
+    uint8_t                     frame_count;\r
+    uint32_t                    time;\r
+    uint8_t                     touch_flag;\r
+    uint32_t                    nf_ppg_channel;\r
+    uint32_t                    nf_ppg_per_channel;\r
+    int32_t                     *ppg_data;\r
+    uint32_t                    nf_mems;\r
+    int16_t                     *mems_data;\r
+} pah8series_data_t;\r
+\r
+#endif\r
+\r
+typedef enum {\r
+       FLAG_DATA_READY                         = 0,\r
+       FLAG_DATA_NOT_READY,\r
+       FLAG_DATA_LOSS,\r
+       FLAG_NO_TOUCH,\r
+       FLAG_DATA_ERROR,\r
+       FLAG_POOR_SIGNAL,\r
+       FLAG_FIFO_ERROR,\r
+       FLAG_TIMMING_ERROR,\r
+       FLAG_MEMS_ERROR,\r
+       FLAG_HR_UPDATE                          = 16,\r
+       FLAG_SG_UPDATE,\r
+} PXI_STATUS_FLAG;\r
+\r
+typedef enum {\r
+       _quick_report_rms_gs_th         = 0,\r
+       _hr_speed_mode,\r
+       _support_cal_motion_idx_enhancement_enh,\r
+       _rsv1,\r
+       _set_switch_mems_fft_max_energy_th,\r
+       _set_switch_mems_large_energy_num_th,\r
+       _set_switch_mn_fft_energy_lo_thr,\r
+       _set_switch_mn_fft_energy_hi_thr,\r
+\r
+       _ppg_large_energy_num_th,\r
+       _max_hr_idx_th,\r
+       _min_hr_idx_th,\r
+       _ppg_fft_total_peak_num_th,\r
+       _mems_large_energy_num_th,\r
+       _mems_fft_max_energy_th,\r
+       _support_signal_grade_motion_detection_enh,\r
+       _support_signal_grade_check_signal_lelvel_enh,\r
+       _support_signal_grade_large_energy_num_enh,\r
+       _rsv2,\r
+       _rsv3,\r
+       _set_reg_shake_count_th0,\r
+} PXI_PARAM_SET;\r
+\r
+typedef enum {\r
+       _rms_gs                                         = 0,\r
+       _signal_level,\r
+       _cal_motion_idx,\r
+       _is_prediction_hr,\r
+       _get_switch_mems_fft_max_energy_th,\r
+       _get_switch_mems_large_energy_num_th,\r
+       _get_switch_mn_fft_energy_lo_thr,\r
+       _get_switch_mn_fft_energy_hi_thr,\r
+\r
+       _hr_sample_count,\r
+       _ppg_large_energy_num,\r
+       _signal_grade_motion_frm,\r
+       _ppg_fft_max_energy_idx,\r
+       _ppg_fft_total_peak_num,\r
+       _mems_large_energy_num,\r
+       _mems_fft_max_energy,\r
+       _grade,\r
+       _signal_grade_hr_to_low_frm,\r
+       _flag_signal_grade_ready_go,\r
+       _motion_flag,\r
+       _get_reg_shake_count_th0,\r
+} PXI_PARAM_GET;\r
+\r
+typedef enum {\r
+       MemsLargeEnergyNumTh            = 0,\r
+       MemsFftMaxEnergyTh,\r
+       QuickReportRmsGsTh,\r
+       SupportSigGradeMotionDetection,\r
+       PpgLargeEnergyNumTh,\r
+       SupportSigGradeLargeEnergyNumEnh,\r
+       SupportSigGradeLargeEnergyNumTh,\r
+       SigGradeThr,\r
+       SupportSigGradeCheckSigLevel,\r
+       FlagCheckNotStableFirstHR,\r
+       MaxHrDefinition,\r
+       MinHrDefinition,\r
+} PXI_PARAM2;\r
+\r
+#endif /* PXIVAR_H__ */\r
diff --git a/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/SPO2/V587/libspo2_v587_20.a b/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/SPO2/V587/libspo2_v587_20.a
new file mode 100644 (file)
index 0000000..5906ca5
Binary files /dev/null and b/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/SPO2/V587/libspo2_v587_20.a differ
diff --git a/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/SPO2/V587/pah831x_testpattern_V587_1.h b/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/SPO2/V587/pah831x_testpattern_V587_1.h
new file mode 100644 (file)
index 0000000..62e45eb
--- /dev/null
@@ -0,0 +1,155 @@
+#ifndef _PAH831x_TESTPATTERN_\r
+#define _PAH831x_TESTPATTERN_\r
+\r
+#include <stdint.h>\r
+#define NF_PPG_CHANNEL 4\r
+#define NF_PPG_PER_CHANNEL 35\r
+static const int32_t PAH831x_rawdata_SPO2[][NF_PPG_PER_CHANNEL*NF_PPG_CHANNEL] = \r
+{\r
+{1,100,1104581,1100870,1032938,1037129,1104566,1100872,1032939,1037140,1104575,1100885,1033004,1037168,1928176,1927474,1905334,1906662,1988985,2440107,3347092,3345994,1988701,2434937,4261584,4383059,1987392,2432531,4163980,4272000,1987012,2432059,4152029,4270677,1986848,2431955,4151654,4270276,1987148,2432034,4152379,4271027,1987364,2432221,4153198,4271641,1987280,2432068,4153395,4271897,1987060,2432034,4153130,4271991,1987016,2431862,4152866,4271718,1986912,2431852,4152644,4271257,1986960,2431832,4152977,4271317,1987036,2431881,4153233,4271667,1987144,2431950,4153676,4272170,1987228,2432044,4154060,4272298,1986780,2431458,4152601,4270651,1985776,2430498,4149367,4267784,1985216,2429971,4147345,4265949,1985252,2429725,4147046,4265702,1985420,2430040,4147669,4266222,1985716,2430222,4148940,4267212},\r
+{1,104,1985576,2430276,4148949,4267605,1985448,2430035,4148821,4267195,1985368,2429952,4148667,4266897,1985236,2429833,4148275,4266769,1985180,2429740,4148309,4266666,1985216,2429760,4148480,4266811,1985264,2429863,4148727,4267212,1985408,2429725,4149230,4267298,1984768,2429277,4147635,4265685,1983776,2428140,4143957,4261981,1983208,2427623,4142114,4260224,1983256,2427480,4141627,4259771,1983400,2427662,4142702,4260701,1983604,2427963,4143658,4261691,1983520,2427913,4143726,4261572,1983232,2427687,4142899,4261256,1983160,2427613,4142489,4260608,1982988,2427283,4142540,4260420,1983072,2427396,4142498,4260497,1983116,2427337,4142745,4260394,1983136,2427357,4142993,4261239,1983088,2427367,4143086,4261239,1982308,2426648,4140552,4258286,1981320,2425649,4137275,4254830,1980928,2425255,4135662,4253329,1981008,2425314,4135569,4253260},\r
+{1,96,1981172,2425388,4136439,4254353,1981272,2425604,4136960,4255018,1981096,2425452,4136780,4254890,1980876,2425393,4136226,4254054,1980704,2424964,4135842,4253909,1980596,2425043,4135543,4253474,1980564,2424969,4135799,4253593,1980724,2425112,4136174,4253977,1980628,2425073,4136456,4254173,1980524,2425112,4136098,4253900,1979456,2423936,4132377,4249924,1978500,2422916,4128913,4246545,1978108,2422503,4127513,4245162,1978168,2422336,4127616,4245401,1978328,2422680,4128392,4246178,1978428,2422690,4128930,4246468,1978108,2422641,4128904,4246545,1978016,2422350,4127786,4245478,1977728,2422144,4127283,4245017,1977644,2421892,4127001,4244736,1977592,2421942,4127300,4244829,1977700,2422080,4127709,4245358,1977612,2422168,4127940,4245563,1977300,2421804,4126890,4244718},\r
+{1,100,1976100,2420420,4122675,4240136,1975228,2419406,4119313,4236902,1974952,2419076,4118365,4235801,1974876,2419259,4118493,4235997,1975068,2419283,4119270,4236774,1975048,2419288,4119500,4237098,1974748,2419106,4118912,4236398,1974488,2418850,4118297,4235741,1974328,2418742,4117862,4235383,1974256,2418604,4117896,4235246,1974212,2418555,4117930,4235571,1974236,2418727,4118331,4235904,1974260,2418697,4118732,4235980,1973676,2418077,4116701,4233881,1972440,2416915,4112025,4229299,1971704,2415926,4109218,4226824,1971500,2415768,4108526,4225868,1971420,2415803,4109038,4226483,1971428,2415896,4109482,4227063,1971400,2415798,4109474,4227072,1971096,2415369,4108637,4226423,1970896,2415355,4108049,4225937,1970804,2415355,4107784,4225553,1970744,2415404,4108023,4225493,1970820,2415547,4108279,4225928},\r
+{1,104,1970824,2415635,4108578,4226355,1970908,2415739,4109021,4226781,1970204,2414990,4106461,4224221,1968952,2413774,4102058,4219750,1968308,2413001,4099490,4217216,1968196,2412814,4098978,4216840,1968224,2413031,4099413,4217429,1968328,2413115,4100147,4218350,1968312,2413213,4100096,4217813,1968072,2412888,4099396,4217275,1967748,2412598,4098500,4216635,1967684,2412686,4098304,4216465,1967672,2412800,4098380,4216439,1967724,2412809,4098670,4216721,1967736,2412992,4099182,4217250,1967896,2413184,4099771,4217770,1967204,2412470,4096981,4214894,1965964,2411185,4092194,4210227,1965364,2410668,4089762,4208017,1965184,2410530,4089309,4207701,1965416,2410752,4089898,4208435,1965504,2410998,4090547,4208768,1965316,2410806,4090112,4208802,1965112,2410924,4089523,4208179,1964928,2410771,4089113,4207906,1964908,2410899,4089053,4207735},\r
+{1,100,1964996,2411096,4089122,4208119,1965132,2411323,4089582,4208597,1965316,2411480,4089821,4209143,1965356,2411933,4090436,4209629,1964756,2411273,4088166,4207223,1963584,2409920,4083114,4202103,1962928,2409181,4080264,4199594,1962680,2409176,4079624,4199031,1962844,2409388,4080179,4199628,1962980,2409708,4080546,4200260,1962840,2409708,4080307,4200268,1962684,2409664,4079598,4199697,1962596,2409595,4079035,4198988,1962560,2409747,4078771,4199125,1962696,2409964,4078924,4199202,1962856,2410176,4079155,4199850,1963076,2410550,4079735,4200285,1963456,2411091,4080725,4201216,1963200,2410894,4079820,4199970,1961984,2409467,4074154,4194483,1960892,2408413,4069879,4190907,1960496,2408024,4068070,4189568,1960344,2408157,4068232,4189627,1960908,2408718,4069179,4190668,1961108,2408955,4069751,4191035},\r
+{1,104,1960944,2408979,4069060,4190557,1960848,2408999,4068437,4189977,1960976,2409053,4068326,4189883,1961116,2409408,4068300,4190156,1961288,2409742,4068684,4190660,1961596,2410082,4069299,4191283,1961968,2410471,4070178,4192179,1962132,2410929,4070647,4192844,1961376,2410185,4067362,4189627,1960064,2408684,4061730,4184072,1959508,2408039,4058948,4181521,1959256,2407857,4058052,4180701,1959492,2408064,4058368,4181205,1959680,2408438,4058811,4181896,1959808,2408787,4058888,4182084,1959760,2408699,4058205,4181512,1959792,2408846,4058069,4181230,1959992,2409265,4058171,4181623,1960208,2409486,4058393,4181973,1960284,2409801,4058572,4182476,1960688,2410244,4059281,4183313,1960968,2410688,4060134,4184234,1961404,2411264,4060876,4185028,1961296,2410963,4060040,4184251,1960060,2409796,4054323,4178423,1959348,2408960,4050935,4175001},\r
+{1,96,1959220,2408694,4049945,4174165,1959464,2409048,4050150,4174361,1959888,2409481,4051063,4175530,1960064,2409821,4051541,4176059,1959984,2409856,4051046,4175633,1960084,2410008,4050824,4175488,1960332,2410358,4050918,4175761,1960468,2410683,4051225,4176204,1960952,2411150,4052224,4177066,1961408,2411500,4052633,4177860,1961736,2412145,4053563,4178756,1962184,2412573,4054621,4179968,1962604,2413149,4055654,4180983,1962252,2412868,4053819,4179276,1961092,2411648,4048520,4174071,1960616,2410993,4045994,4171400,1960664,2410958,4045320,4171110,1960968,2411421,4046301,4172288,1961312,2411928,4047385,4173175,1961632,2412307,4047889,4173755,1961820,2412430,4047744,4173653,1961828,2412750,4047496,4173653,1962160,2413006,4047931,4174011,1962528,2413459,4048674,4174873},\r
+{1,104,1962964,2413952,4049638,4175795,1963256,2414478,4050491,4176776,1963696,2414916,4051396,4177621,1964220,2415384,4052258,4178525,1964660,2415950,4053555,4179686,1964920,2416300,4054400,4180795,1964284,2415675,4050952,4177228,1963396,2414567,4046720,4173004,1963112,2414336,4045201,4171648,1963200,2414247,4044876,4171699,1963604,2414902,4045764,4172561,1963996,2415276,4046737,4173636,1964244,2415586,4046950,4174190,1964384,2415660,4047095,4174080,1964588,2415955,4047513,4174361,1964872,2416364,4048349,4175138,1965364,2416792,4049066,4176213,1965676,2417319,4050107,4177117,1966068,2417846,4051225,4178056,1966536,2418323,4052369,4179507,1967136,2418870,4053632,4180881,1967388,2419249,4054451,4181589,1966636,2418491,4051012,4178141,1965956,2417841,4047880,4174993,1965956,2417703,4047061,4174284,1966236,2417944,4047522,4174984},\r
+{1,100,1966616,2418348,4048597,4175982,1966920,2418934,4049757,4177211,1967240,2419259,4050329,4177655,1967332,2419367,4050304,4177971,1967604,2419643,4050705,4178636,1967964,2420017,4051481,4179456,1968388,2420450,4052821,4180531,1968736,2420908,4053828,4181410,1969140,2421361,4054920,4182775,1969660,2421828,4056251,4183944,1970000,2422326,4057309,4185088,1969552,2421814,4055270,4183236,1968636,2421006,4051558,4179746,1968552,2420706,4050474,4178867,1968940,2421065,4051131,4179251,1969220,2421361,4052121,4180292,1969656,2421769,4053478,4181802,1969844,2422148,4054195,4182109,1969944,2422227,4054348,4182570,1970124,2422449,4054758,4182894,1970472,2422769,4055620,4183748,1970644,2423153,4056584,4185028,1971172,2423616,4057873,4185873,1971436,2424029,4058862,4186820,1971860,2424270,4059673,4188194},\r
+{1,100,1972120,2424772,4060970,4189337,1972284,2424950,4061465,4189832,1971560,2424398,4058222,4186419,1971196,2423670,4055927,4184456,1971080,2423655,4055662,4184234,1971396,2424000,4056644,4185079,1971844,2424502,4058035,4186496,1972124,2424856,4058794,4187477,1972352,2425004,4059161,4187904,1972432,2425014,4059281,4188168,1972564,2425329,4059929,4188475,1972888,2425540,4060817,4189474,1973180,2425993,4062062,4190464,1973496,2426240,4062984,4191368,1973844,2426545,4064034,4192392,1974036,2427037,4065109,4193595,1974536,2427377,4066082,4194534,1974672,2427736,4066918,4195293,1974016,2427047,4064093,4192426,1973484,2426387,4061730,4190318,1973404,2426417,4061294,4189900,1973708,2426732,4062131,4190694,1974120,2427042,4063394,4191880,1974400,2427401,4064486,4192955,1974464,2427520,4064878,4193433},\r
+{1,104,1974528,2427485,4064964,4193638,1974612,2427707,4065228,4193885,1974840,2427958,4066355,4194457,1975128,2428209,4066824,4195524,1975372,2428470,4068172,4196676,1975740,2428819,4068753,4197529,1975956,2429124,4069768,4198365,1976160,2429341,4070749,4199475,1976524,2429661,4071850,4200405,1976292,2429587,4071185,4199910,1975600,2428800,4067916,4196710,1975216,2428430,4066500,4195328,1975480,2428455,4066901,4195379,1975776,2428775,4067925,4196488,1976100,2429203,4069196,4197614,1976212,2429464,4070135,4198417,1976328,2429440,4070135,4198749,1976336,2429430,4070144,4198792,1976372,2429440,4070493,4198937,1976684,2429725,4071304,4199688,1976868,2429971,4072046,4200593,1977100,2430395,4072874,4201472,1977420,2430488,4073881,4202231,1977536,2430675,4074666,4202956,1977808,2431089,4075741,4203938,1977892,2431291,4075972,4204492},\r
+{1,96,1977336,2430532,4073429,4201719,1976812,2430060,4071287,4199773,1976888,2429986,4071005,4199671,1977116,2430311,4072251,4200644,1977480,2430695,4073668,4201881,1977716,2430921,4074197,4202905,1977680,2431153,4074598,4202862,1977676,2430946,4074453,4202862,1977756,2431099,4074641,4203246,1977948,2431320,4075502,4203741,1978116,2431596,4076151,4204612,1978436,2431748,4076953,4205303,1978552,2431852,4077704,4205943,1978820,2432157,4078481,4206762,1979024,2432507,4079223,4207453,1979040,2432610,4079675,4207829,1978324,2431896,4076654,4205081,1977896,2431478,4074632,4203323,1977840,2431399,4074496,4202931,1978116,2431552,4074990,4203477,1978356,2431817,4076134,4204620,1978504,2431990,4076970,4205166,1978564,2431995,4076928,4205772,1978528,2432128,4076817,4205457},\r
+{1,104,1978552,2432162,4077397,4205721,1978688,2432211,4077653,4206054,1978828,2432403,4078310,4206720,1979032,2432644,4078890,4207394,1979256,2432807,4079556,4207897,1979364,2432896,4080204,4208537,1979516,2433063,4081049,4209262,1979600,2433191,4081254,4209365,1978892,2432482,4078105,4206429,1978352,2431901,4075810,4204083,1978248,2431753,4075443,4204049,1978420,2431916,4075878,4204407,1978580,2432226,4077226,4205619,1978728,2432192,4077696,4205960,1978812,2432152,4077636,4206216,1978708,2432236,4077670,4206003,1978668,2432344,4077568,4206020,1978828,2432260,4077994,4206190,1979052,2432448,4078745,4206830,1979000,2432585,4079317,4207334,1979268,2432738,4079795,4207906,1979412,2432792,4080349,4208512,1979532,2432964,4081032,4209169,1979612,2433014,4081237,4209143,1978692,2432226,4078276,4206276,1978188,2431684,4075596,4203776},\r
+{1,100,1978020,2431552,4074965,4203349,1978112,2431532,4075340,4203869,1978472,2431773,4076373,4204603,1978648,2431857,4076996,4205184,1978460,2431881,4076842,4205158,1978448,2431822,4076714,4204876,1978372,2431625,4076561,4204851,1978436,2431670,4076996,4205132,1978556,2431729,4077499,4205320,1978696,2431916,4078148,4205909,1978844,2431857,4078711,4206336,1978912,2432142,4079155,4206882,1979096,2432265,4079846,4207658,1978968,2432388,4079803,4207360,1978172,2431251,4076322,4203989,1977560,2430754,4074009,4202180,1977460,2430724,4073745,4201736,1977712,2430784,4074282,4202589,1977936,2430985,4075289,4203272,1978004,2431025,4075588,4203682,1977916,2430971,4075332,4203443,1977864,2430985,4075409,4203221,1977840,2430833,4075588,4203426,1977940,2430862,4075801,4203477,1977992,2431025,4076339,4204100},\r
+{1,100,1978188,2431177,4076953,4204629,1978296,2431355,4077414,4205269,1978548,2431355,4077900,4205678,1978664,2431414,4078702,4206003,1978456,2431330,4078489,4206020,1977704,2430523,4075392,4202606,1977240,2429961,4073088,4200618,1977100,2429760,4073070,4200448,1977292,2429937,4073420,4201156,1977480,2430203,4074308,4201890,1977584,2430227,4074734,4202419,1977452,2430075,4074598,4202094,1977404,2429971,4074530,4201907,1977360,2429966,4074461,4201651,1977436,2430065,4074931,4202282,1977576,2430109,4075246,4202811,1977676,2430148,4075724,4203033,1977780,2430331,4076544,4203409,1978040,2430434,4076893,4204134,1978196,2430720,4077491,4204825,1977908,2430350,4076740,4203793,1977172,2429666,4073762,4200738,1976832,2429262,4072379,4199534,1976856,2429203,4072533,4199833,1977200,2429390,4073378,4200533},\r
+{1,104,1977380,2429636,4074188,4201437,1977380,2429858,4074598,4201651,1977260,2429671,4074146,4201514,1977172,2429558,4074069,4201335,1977296,2429651,4074513,4201352,1977388,2429794,4075170,4202146,1977584,2429937,4075699,4202649,1977640,2430099,4075955,4203042,1977932,2430340,4076851,4203741,1978092,2430473,4077209,4204356,1978204,2430828,4077917,4204902,1977692,2430272,4075741,4202760,1977080,2429469,4073531,4200328,1976924,2429228,4072763,4199748,1977176,2429454,4073173,4200311,1977300,2429720,4074205,4201224,1977520,2429907,4074760,4201617,1977560,2429976,4074982,4201659,1977456,2429769,4074564,4201676,1977380,2429873,4074700,4201676,1977460,2429858,4074897,4201702,1977672,2429937,4075520,4202350,1977804,2430168,4076006,4202973,1977836,2430375,4076629,4203323,1978008,2430473,4076996,4203912,1978300,2430724,4077747,4204689},\r
+{1,96,1978220,2430641,4077917,4204322,1977520,2429868,4074734,4201344,1977036,2429435,4072917,4199876,1976912,2429257,4072601,4199424,1977224,2429479,4073164,4199859,1977288,2429691,4073992,4200780,1977348,2429804,4074197,4201241,1977456,2429760,4074120,4201216,1977276,2429769,4073984,4200994,1977316,2429651,4073770,4201045,1977380,2429863,4074265,4201164,1977492,2429833,4074845,4201668,1977616,2430006,4075374,4202205,1977808,2430208,4076040,4202905,1977944,2430385,4076586,4203426,1978224,2430577,4077149,4203904,1977936,2430478,4076902,4203588,1977188,2429558,4073574,4200251,1976704,2429203,4071953,4198894,1976652,2429060,4071697,4198604,1976780,2429213,4072055,4198971,1976980,2429371,4072456,4199517,1977048,2429636,4072960,4200106,1976948,2429361,4072721,4199901},\r
+{1,104,1976828,2429312,4072712,4199910,1976988,2429371,4072823,4199978,1977196,2429533,4073198,4200251,1977224,2429676,4073796,4200729,1977436,2429897,4074350,4201207,1977524,2429932,4074888,4201600,1977592,2430114,4075520,4202248,1977888,2430365,4076108,4203059,1977816,2430252,4075844,4202880,1976968,2429316,4072814,4199577,1976468,2428878,4070818,4197964,1976396,2428706,4070715,4197708,1976548,2428854,4070681,4198323,1976724,2429036,4071680,4198749,1976920,2429134,4072089,4199133,1976776,2429193,4071825,4198980,1976764,2429124,4071850,4198826,1976728,2429282,4071918,4199065,1976940,2429248,4072482,4199389,1977052,2429390,4072891,4199808,1977228,2429558,4073386,4200251,1977380,2429715,4073804,4200755,1977376,2429858,4074427,4201258,1977628,2430011,4075067,4201915,1977576,2430006,4075221,4202112,1976900,2429400,4072473,4199432},\r
+{1,100,1976512,2428745,4070459,4197486,1976436,2428657,4070152,4197307,1976640,2428809,4070417,4197444,1976700,2429036,4070988,4198058,1976840,2429090,4071671,4198613,1976860,2429105,4071364,4198587,1976696,2428987,4071330,4198272,1976780,2429031,4071355,4198664,1976880,2429120,4071816,4198724,1977056,2429415,4072268,4199338,1977216,2429474,4072797,4199808,1977272,2429622,4073198,4200362,1977348,2429779,4073702,4200755,1977572,2429828,4074427,4201309,1977684,2430119,4074700,4201634,1977188,2429661,4072994,4200064,1976676,2428878,4070732,4197802,1976576,2428873,4070246,4197435,1976704,2428903,4070681,4197905,1977020,2429193,4071586,4198604,1977100,2429410,4072234,4199278,1977060,2429430,4071901,4199022,1977160,2429376,4071876,4198980,1977152,2429405,4071953,4199296,1977252,2429632,4072738,4199927},\r
+{1,100,1977508,2429892,4073489,4200652,1977768,2430040,4074308,4201233,1977844,2430035,4074897,4201668,1978116,2430336,4075118,4201907,1978152,2430513,4075579,4202692,1978224,2430601,4076032,4202854,1977864,2430370,4074828,4201856,1977412,2429819,4072849,4200260,1977324,2429725,4072558,4199970,1977484,2429917,4072960,4200243,1977688,2430208,4073796,4201045,1977784,2430301,4074163,4201557,1977972,2430542,4074325,4201565,1977880,2430464,4074359,4201437,1978116,2430646,4074880,4202069,1978208,2430621,4075178,4202146,1978216,2430784,4075639,4202547,1978368,2430838,4076270,4203076,1978564,2431079,4076526,4203613,1978756,2431256,4077073,4204040,1978908,2431399,4077525,4204706,1978928,2431601,4077533,4205166,1978328,2430941,4075776,4202683,1977948,2430291,4073907,4200635,1977724,2430272,4073292,4200499},\r
+{1,104,1977944,2430395,4073369,4200558,1978120,2430518,4074086,4200994,1978284,2430641,4074811,4201489,1978144,2430631,4074769,4201565,1978124,2430710,4074700,4201634,1978380,2430705,4074709,4201617,1978380,2430729,4075187,4202077,1978408,2430843,4075656,4202214,1978400,2430902,4075793,4202709,1978604,2431040,4076305,4203229,1978776,2431202,4076979,4203537,1978928,2431409,4077337,4204083,1978792,2431310,4077175,4203886,1978052,2430616,4074606,4201395,1977816,2430158,4073463,4200072,1977852,2430193,4073642,4200166,1978028,2430345,4074308,4200558,1978264,2430665,4074811,4201156,1978304,2430867,4075016,4201420,1978152,2430685,4074786,4201565,1978148,2430665,4074880,4201446,1978384,2430724,4075170,4201898,1978492,2430813,4075724,4202009,1978564,2430897,4075801,4202342,1978652,2430985,4076288,4202769,1978788,2431232,4076885,4203246},\r
+{1,100,1978888,2431345,4077482,4203665,1979116,2431527,4078208,4204125,1979160,2431527,4078062,4204347,1978616,2430828,4076014,4202308,1978212,2430528,4074828,4200823,1978396,2430523,4074692,4200652,1978524,2430793,4075187,4201361,1978700,2430887,4075980,4201898,1978808,2430946,4076561,4202589,1978812,2431099,4076416,4202282,1978628,2431104,4076245,4202410,1978928,2431064,4076526,4202478,1978936,2431207,4076885,4202914,1979036,2431261,4077158,4203315,1979056,2431286,4077764,4203622,1979192,2431522,4078011,4204168,1979348,2431709,4078532,4204492,1979540,2431788,4079138,4204970,1979468,2431803,4079351,4205329,1979068,2431507,4077696,4203332,1978608,2430961,4076032,4201890,1978552,2430951,4075835,4201489,1978776,2430912,4076475,4201992,1979012,2431276,4077124,4202803,1979148,2431448,4077755,4203195},\r
+{1,100,1979084,2431438,4077627,4203400,1979084,2431315,4077329,4203059,1979020,2431291,4077644,4203212,1979196,2431428,4077960,4203238,1979252,2431552,4078216,4203724,1979320,2431665,4078600,4204219,1979516,2431788,4079180,4204578,1979672,2431955,4079846,4205021,1979848,2432004,4080119,4205303,1979804,2432039,4080435,4205619,1979216,2431478,4078310,4203511,1978836,2430961,4076817,4201924,1978784,2430936,4076825,4201762,1978992,2431143,4077201,4202171,1979248,2431310,4078088,4202948,1979256,2431340,4078182,4203187,1979236,2431286,4078284,4203204,1979156,2431153,4077900,4203016,1979312,2431236,4078114,4203118,1979256,2431232,4078387,4203357,1979384,2431300,4078626,4203630,1979568,2431522,4079291,4204125,1979684,2431635,4079812,4204484,1979908,2431699,4080153,4204987,1979900,2431847,4080836,4205320},\r
+{1,100,1979516,2431620,4079880,4204561,1979068,2430887,4077585,4202333,1978968,2430660,4077013,4201284,1978976,2430734,4077115,4201813,1979204,2431000,4078037,4202547,1979376,2431158,4078318,4203042,1979348,2431128,4078446,4203161,1979272,2431128,4078045,4202897,1979204,2431044,4078310,4202709,1979324,2431064,4078540,4202973,1979260,2431099,4078702,4203161,1979444,2431271,4078890,4203571,1979448,2431345,4079342,4203938,1979604,2431473,4079820,4204168,1979684,2431527,4080204,4204808,1979568,2431414,4079735,4204475,1978916,2430788,4077670,4202001,1978612,2430370,4075878,4200567,1978572,2430276,4076032,4200789,1978708,2430488,4076501,4201130,1978844,2430547,4077158,4201275,1978844,2430646,4077346,4201813,1978824,2430631,4076885,4201523,1978680,2430513,4076552,4201284,1978520,2430508,4076723,4201233},\r
+{1,100,1978632,2430601,4076928,4201582,1978776,2430552,4077337,4201531,1978916,2430596,4077704,4202077,1979020,2430897,4078080,4202402,1978968,2430916,4078395,4202828,1979004,2430656,4078267,4202726,1978248,2430001,4076057,4200652,1977864,2429484,4073915,4198357,1977560,2429184,4073335,4197674,1977552,2429174,4073318,4197717,1977668,2429282,4073770,4198391,1977756,2429385,4073984,4198604,1977608,2429174,4073898,4198434,1977448,2429129,4073378,4198075,1977428,2429041,4073198,4197913,1977320,2429006,4073335,4197836,1977324,2429060,4073506,4198016,1977368,2428957,4073693,4198237,1977356,2429105,4073728,4198485,1977328,2428932,4073838,4198408,1977356,2429001,4074342,4198690,1977176,2428878,4073702,4198451,1976368,2427840,4070715,4195438,1975856,2427293,4068923,4193416,1975644,2427091,4068411,4192955},\r
+{1,104,1975604,2427101,4068369,4192981,1975708,2427209,4068650,4193425,1975652,2427121,4068693,4193416,1975460,2426939,4068189,4193015,1975208,2426825,4067677,4192554,1975160,2426688,4067541,4192281,1975112,2426599,4067729,4192443,1974972,2426500,4067848,4192563,1975000,2426530,4067788,4192776,1975008,2426564,4067831,4192682,1975024,2426614,4068096,4193083,1975092,2426555,4068744,4193433,1974776,2426269,4067797,4192682,1973764,2425353,4064768,4189661,1973380,2424792,4062685,4187733,1973180,2424649,4062054,4187264,1973108,2424566,4062446,4187298,1973216,2424546,4062523,4187528,1973156,2424551,4062668,4187485,1972800,2424280,4061909,4186948,1972704,2424187,4061482,4186547,1972680,2424123,4061269,4186453,1972680,2423842,4061440,4186478,1972584,2424088,4061713,4186675,1972616,2424118,4061900,4186982,1972604,2424098,4062173,4187153},\r
+{1,100,1972744,2424162,4062182,4187502,1972740,2424073,4062634,4187776,1972776,2424177,4062771,4188014,1972184,2423773,4061141,4186299,1971504,2422729,4058069,4183159,1971020,2422331,4056490,4182067,1970924,2422242,4056413,4181768,1970928,2422291,4056669,4182101,1971132,2422331,4057028,4182306,1970952,2422227,4056439,4182126,1970564,2421937,4056055,4181572,1970600,2421789,4055722,4181128,1970552,2421804,4056004,4181213,1970588,2421779,4055799,4181341,1970520,2421971,4056072,4181751,1970604,2422001,4056422,4182050,1970644,2422030,4056678,4182272,1970732,2422173,4056908,4182510,1970892,2422301,4057275,4182946,1970908,2422449,4057710,4183398,1970404,2421833,4056021,4181785,1969672,2420937,4053077,4178901,1969252,2420667,4051549,4177757,1969072,2420696,4051669,4177476,1969340,2420834,4051558,4177715},\r
+{1,100,1969364,2420809,4051942,4178176,1969332,2420864,4051993,4178039,1969120,2420731,4051524,4177672,1969100,2420642,4051225,4177612,1969048,2420622,4051328,4177689,1969168,2420859,4051652,4177774,1969232,2420982,4051993,4178227,1969372,2421046,4052232,4178585,1969324,2421203,4052548,4178978,1969480,2421164,4053128,4179276,1969724,2421469,4053435,4179712,1969728,2421479,4053683,4180061,1969272,2420923,4051857,4178013,1968424,2420253,4048836,4175283,1968168,2419899,4047948,4174301,1968088,2419913,4047633,4174361,1968296,2419982,4047957,4174617,1968264,2420076,4048298,4174924,1968280,2420051,4048273,4174993,1968100,2420032,4047607,4174318,1968032,2419879,4047266,4174148,1967996,2419953,4047522,4174327,1967972,2420164,4047829,4174822,1968180,2420258,4048273,4175197,1968212,2420430,4048921,4175607},\r
+{1,100,1968320,2420342,4049245,4176145,1968628,2420711,4049536,4176469,1968632,2420928,4050244,4176964,1968976,2421065,4050432,4177322,1968384,2420475,4048844,4175769,1967660,2419741,4045994,4173098,1967380,2419401,4044825,4172049,1967396,2419456,4044782,4171980,1967468,2419520,4045235,4172433,1967568,2419766,4045482,4172723,1967480,2419820,4045559,4172663,1967396,2419667,4045073,4172330,1967400,2419549,4044859,4172100,1967432,2419648,4044996,4172364,1967592,2419864,4045542,4172962,1967640,2419938,4045909,4173286,1967768,2420056,4046336,4173687,1967896,2420219,4046771,4174148,1968100,2420288,4047342,4174677,1968148,2420642,4047982,4175069,1968356,2420657,4048341,4175709,1967928,2420258,4046984,4173900,1967444,2419726,4044458,4171511,1967068,2419510,4043605,4171042,1967124,2419579,4043673,4171084},\r
+{1,100,1967272,2419756,4043989,4171468,1967296,2419761,4044475,4171776,1967380,2419830,4044151,4172057,1967168,2419633,4043989,4171409,1967056,2419505,4043673,4171008,1967144,2419667,4043844,4171485,1967312,2419731,4044185,4171673,1967368,2419953,4044620,4172228,1967552,2420081,4045021,4172740,1967568,2420253,4045465,4173038,1967716,2420450,4045892,4173243,1967804,2420519,4046532,4173943,1967748,2420425,4045994,4173440,1967036,2419549,4043323,4170658,1966580,2419081,4041642,4169258,1966576,2418993,4041233,4168849,1966540,2419204,4041420,4169028,1966732,2419229,4041915,4169608,1966724,2419091,4041984,4169907,1966568,2419160,4041838,4169352,1966532,2419032,4041531,4168994,1966488,2419022,4041702,4169164,1966548,2419195,4042077,4169275,1966684,2419244,4042547,4169753,1966712,2419323,4042581,4170103},\r
+{1,104,1966844,2419441,4043281,4170700,1967032,2419564,4043724,4171153,1967168,2419800,4044322,4171665,1967304,2419923,4044714,4172125,1966744,2419283,4042982,4170231,1966132,2418806,4040465,4168200,1966044,2418486,4039756,4167210,1966020,2418628,4040064,4167586,1966248,2418830,4040482,4168064,1966344,2418998,4041122,4168465,1966356,2419042,4041113,4168533,1966340,2419072,4040977,4168396,1966348,2418939,4040755,4168081,1966508,2419121,4041070,4168704,1966532,2419239,4041548,4169011,1966736,2419451,4042035,4169523,1966920,2419657,4042752,4170197,1966980,2419667,4042871,4170453,1967316,2420061,4043596,4171042,1967344,2420219,4043997,4171818,1967228,2419977,4043630,4170820,1966580,2419264,4041036,4168243,1966300,2419027,4039748,4167185,1966268,2418904,4039918,4167125,1966540,2419106,4040337,4167586,1966676,2419411,4041164,4168388},\r
+{1,100,1966768,2419490,4041275,4168499,1966652,2419392,4040985,4168345,1966740,2419470,4040755,4168584,1966796,2419524,4041190,4168345,1966904,2419623,4041497,4168721,1967020,2419825,4042086,4169429,1967164,2419894,4042564,4169830,1967408,2420174,4042897,4170248,1967588,2420307,4043938,4171195,1967844,2420593,4044509,4171682,1967752,2420627,4044518,4171409,1967308,2419859,4042385,4169446,1966800,2419451,4040738,4167808,1966820,2419308,4040354,4167364,1966992,2419529,4040661,4167765,1967144,2419869,4041403,4168533,1967300,2419982,4041966,4169096,1967312,2419899,4041864,4168806,1967248,2419741,4041966,4168627,1967244,2419756,4041531,4168661,1967380,2420066,4042188,4169181,1967508,2420184,4042615,4169591,1967716,2420302,4043144,4170094,1967848,2420470,4043707,4170376,1967976,2420593,4044032,4170862},\r
+       \r
+};\r
+static const int16_t PAH831x_mems_SPO2[][3*68] = \r
+{\r
+{67,-412,-284,-3972,-440,-296,-3964,-420,-284,-3972,-392,-284,-3976,-396,-288,-3960,-404,-280,-3964,-416,-280,-3964,-408,-276,-3972,-396,-280,-3976,-396,-276,-3972,-404,-268,-3976,-412,-280,-3968,-392,-296,-3960,-392,-304,-3964,-424,-284,-3964,-428,-288,-3976,-388,-284,-3968,-384,-280,-3972,-396,-284,-3972,-396,-276,-3956,-404,-280,-3972,-408,-284,-3968,-404,-288,-3968,-396,-296,-3964,-420,-288,-3972,-428,-268,-3980,-400,-280,-3984,-380,-288,-3964,-404,-284,-3964,-444,-284,-3964,-444,-284,-3964,-424,-292,-3972,-388,-276,-3972,-400,-280,-3972,-420,-288,-3964,-408,-296,-3968,-428,-288,-3972,-416,-284,-3968,-408,-284,-3972,-396,-284,-3968,-404,-288,-3968,-404,-284,-3964,-400,-280,-3968,-416,-288,-3972,-428,-284,-3968,-408,-284,-3968,-392,-296,-3956,-400,-296,-3968,-420,-288,-3972,-436,-284,-3972,-408,-284,-3972,-376,-292,-3964,-384,-292,-3956,-420,-288,-3964,-444,-276,-3976,-432,-268,-3988,-392,-288,-3968,-380,-288,-3960,-416,-296,-3972,-444,-292,-3960,-424,-284,-3964,-400,-280,-3964,-400,-284,-3968,-428,-288,-3968,-436,-280,-3968,-440,-272,-3968,-416,-288,-3968},\r
+{53,-400,-292,-3968,-404,-300,-3968,-424,-292,-3968,-420,-296,-3964,-428,-280,-3968,-432,-288,-3968,-404,-276,-3960,-408,-296,-3968,-416,-292,-3964,-428,-296,-3964,-428,-292,-3964,-416,-292,-3964,-412,-304,-3964,-424,-288,-3964,-436,-284,-3956,-444,-292,-3980,-416,-284,-3972,-408,-288,-3976,-408,-288,-3976,-420,-296,-3964,-440,-296,-3964,-464,-296,-3968,-436,-300,-3956,-388,-292,-3960,-404,-296,-3960,-436,-300,-3968,-448,-280,-3968,-432,-272,-3976,-416,-292,-3972,-392,-292,-3964,-408,-288,-3964,-432,-292,-3960,-448,-288,-3976,-440,-288,-3972,-432,-284,-3972,-416,-280,-3972,-420,-284,-3964,-416,-288,-3964,-412,-292,-3968,-416,-292,-3964,-432,-284,-3964,-424,-288,-3968,-408,-280,-3964,-412,-288,-3972,-424,-292,-3964,-416,-288,-3964,-416,-272,-3980,-416,-280,-3976,-420,-280,-3976,-412,-284,-3968,-424,-284,-3956,-424,-284,-3968,-420,-296,-3968},\r
+{52,-408,-280,-3972,-416,-284,-3968,-404,-284,-3964,-396,-276,-3968,-416,-284,-3980,-400,-280,-3972,-400,-284,-3968,-392,-284,-3960,-400,-284,-3968,-412,-284,-3980,-412,-284,-3968,-420,-284,-3968,-400,-288,-3964,-388,-288,-3968,-396,-284,-3968,-412,-284,-3968,-428,-276,-3980,-400,-280,-3964,-380,-284,-3968,-376,-296,-3960,-404,-284,-3968,-420,-272,-3976,-404,-280,-3984,-388,-296,-3968,-392,-288,-3968,-420,-292,-3972,-416,-280,-3964,-412,-280,-3968,-404,-276,-3968,-384,-288,-3960,-372,-284,-3968,-400,-284,-3964,-436,-284,-3980,-416,-284,-3972,-384,-288,-3972,-376,-292,-3972,-400,-280,-3972,-420,-280,-3976,-408,-280,-3972,-388,-284,-3964,-380,-284,-3968,-396,-288,-3968,-408,-288,-3976,-416,-280,-3968,-412,-288,-3968,-392,-288,-3972,-384,-284,-3964,-384,-280,-3964,-392,-280,-3972,-404,-280,-3972,-416,-280,-3980,-404,-280,-3980},\r
+{53,-384,-280,-3964,-392,-292,-3964,-408,-292,-3964,-420,-292,-3964,-428,-288,-3968,-396,-284,-3968,-376,-272,-3972,-388,-276,-3968,-400,-280,-3972,-400,-276,-3976,-408,-296,-3972,-400,-292,-3972,-404,-280,-3976,-400,-284,-3968,-384,-284,-3964,-376,-280,-3972,-400,-288,-3976,-404,-280,-3968,-396,-288,-3972,-384,-280,-3960,-388,-280,-3976,-400,-280,-3968,-408,-284,-3968,-396,-288,-3968,-388,-292,-3968,-400,-280,-3964,-404,-296,-3972,-392,-276,-3980,-396,-268,-3984,-396,-272,-3976,-400,-288,-3972,-412,-288,-3960,-408,-288,-3960,-404,-280,-3972,-388,-284,-3980,-388,-284,-3976,-396,-288,-3968,-388,-284,-3964,-400,-280,-3968,-404,-280,-3980,-392,-276,-3976,-384,-284,-3964,-376,-288,-3968,-388,-288,-3972,-408,-288,-3976,-404,-276,-3968,-392,-288,-3968,-376,-284,-3972,-392,-288,-3972,-400,-280,-3972,-420,-280,-3976,-396,-284,-3976,-396,-284,-3964},\r
+{53,-396,-284,-3964,-384,-284,-3968,-396,-292,-3964,-412,-288,-3976,-412,-276,-3984,-408,-284,-3976,-396,-296,-3972,-384,-296,-3960,-412,-288,-3964,-420,-284,-3964,-396,-292,-3964,-392,-288,-3972,-408,-284,-3968,-412,-284,-3968,-396,-292,-3968,-392,-288,-3972,-408,-288,-3968,-412,-288,-3976,-412,-292,-3972,-408,-284,-3968,-404,-288,-3964,-404,-296,-3968,-416,-292,-3964,-416,-292,-3968,-412,-288,-3972,-404,-284,-3968,-392,-292,-3968,-404,-292,-3968,-424,-292,-3968,-404,-292,-3964,-400,-288,-3964,-404,-300,-3960,-416,-296,-3972,-420,-276,-3984,-424,-284,-3980,-396,-296,-3968,-400,-304,-3960,-428,-288,-3956,-432,-284,-3968,-408,-292,-3964,-396,-292,-3968,-400,-296,-3964,-416,-292,-3972,-412,-284,-3964,-400,-292,-3972,-396,-296,-3968,-408,-288,-3972,-416,-292,-3964,-408,-296,-3964,-408,-288,-3972,-408,-292,-3968,-404,-292,-3964,-408,-296,-3968},\r
+{53,-408,-292,-3964,-396,-284,-3964,-404,-292,-3976,-424,-288,-3976,-416,-296,-3968,-396,-300,-3964,-392,-292,-3968,-400,-288,-3972,-416,-300,-3964,-412,-284,-3976,-400,-280,-3976,-396,-288,-3972,-392,-296,-3964,-400,-296,-3972,-416,-288,-3960,-428,-292,-3976,-404,-296,-3964,-388,-284,-3968,-388,-292,-3972,-392,-292,-3968,-412,-284,-3972,-412,-292,-3972,-400,-292,-3968,-380,-288,-3976,-384,-292,-3968,-392,-300,-3968,-404,-300,-3964,-396,-300,-3968,-396,-296,-3968,-388,-288,-3968,-396,-284,-3972,-392,-292,-3968,-392,-304,-3968,-392,-292,-3968,-396,-304,-3968,-384,-300,-3972,-388,-304,-3968,-392,-280,-3964,-404,-292,-3960,-376,-308,-3972,-384,-300,-3988,-412,-296,-3980,-404,-292,-3988,-380,-300,-3964,-380,-288,-3972,-408,-304,-3968,-384,-292,-3964,-356,-288,-3944,-368,-288,-3952,-392,-296,-3964,-384,-268,-3972,-384,-296,-3980,-364,-300,-3980},\r
+{53,-372,-308,-3972,-404,-304,-3972,-424,-308,-3964,-396,-304,-3976,-384,-292,-3972,-388,-284,-3968,-372,-284,-3972,-360,-288,-3980,-392,-284,-3972,-404,-292,-3976,-380,-292,-3956,-372,-304,-3960,-384,-296,-3964,-400,-300,-3972,-396,-296,-3972,-372,-296,-3968,-368,-304,-3960,-396,-292,-3972,-396,-288,-3984,-384,-280,-3972,-392,-296,-3968,-396,-296,-3968,-392,-296,-3964,-396,-292,-3972,-380,-288,-3976,-364,-284,-3972,-368,-284,-3964,-376,-292,-3964,-372,-296,-3968,-384,-292,-3972,-404,-288,-3976,-392,-284,-3980,-364,-300,-3968,-360,-300,-3968,-400,-296,-3968,-420,-288,-3972,-412,-288,-3976,-372,-284,-3972,-364,-300,-3968,-376,-292,-3968,-372,-292,-3968,-388,-288,-3976,-400,-288,-3972,-396,-300,-3972,-384,-296,-3968,-376,-292,-3968,-384,-288,-3964,-388,-284,-3972,-392,-296,-3964,-396,-296,-3976,-404,-296,-3984,-392,-284,-3976,-380,-288,-3968},\r
+{53,-396,-304,-3964,-412,-292,-3972,-400,-296,-3960,-380,-292,-3964,-384,-296,-3968,-384,-288,-3968,-408,-292,-3968,-408,-296,-3972,-396,-300,-3972,-384,-300,-3972,-404,-296,-3976,-420,-284,-3968,-404,-292,-3972,-388,-300,-3964,-396,-284,-3968,-416,-292,-3968,-412,-288,-3972,-392,-292,-3972,-384,-304,-3964,-400,-304,-3964,-404,-288,-3968,-404,-288,-3976,-392,-296,-3968,-392,-300,-3968,-400,-296,-3968,-408,-292,-3964,-408,-292,-3972,-384,-288,-3964,-388,-296,-3956,-404,-296,-3972,-412,-284,-3984,-404,-284,-3976,-396,-296,-3972,-400,-296,-3964,-424,-288,-3960,-408,-300,-3964,-384,-300,-3952,-380,-296,-3968,-404,-284,-3972,-416,-288,-3976,-400,-296,-3968,-384,-300,-3964,-404,-296,-3964,-408,-292,-3964,-408,-304,-3976,-416,-292,-3964,-408,-292,-3968,-400,-296,-3968,-376,-292,-3968,-400,-296,-3968,-416,-288,-3972,-412,-288,-3964,-396,-296,-3968},\r
+{53,-400,-296,-3968,-404,-292,-3972,-408,-300,-3972,-396,-292,-3968,-400,-292,-3972,-404,-292,-3968,-412,-300,-3968,-412,-296,-3968,-404,-284,-3964,-392,-300,-3968,-396,-304,-3964,-404,-300,-3964,-424,-276,-3988,-416,-288,-3976,-388,-300,-3964,-400,-304,-3956,-424,-292,-3960,-428,-288,-3972,-420,-292,-3972,-380,-296,-3960,-372,-292,-3964,-412,-288,-3964,-436,-288,-3972,-420,-304,-3972,-404,-292,-3976,-396,-288,-3968,-380,-292,-3968,-400,-292,-3972,-420,-292,-3968,-428,-296,-3968,-404,-288,-3968,-380,-288,-3968,-388,-288,-3964,-404,-288,-3968,-412,-288,-3976,-396,-296,-3964,-408,-308,-3980,-404,-280,-3956,-392,-308,-3964,-392,-284,-3972,-396,-288,-3960,-416,-292,-3988,-400,-272,-3952,-404,-300,-3976,-404,-296,-3972,-392,-284,-3972,-416,-292,-3984,-396,-284,-3964,-400,-296,-3964,-428,-300,-3972,-412,-272,-3956,-396,-304,-3972,-380,-288,-3968},\r
+{53,-404,-292,-3968,-412,-296,-3972,-388,-288,-3960,-404,-300,-3976,-404,-288,-3972,-400,-284,-3968,-388,-288,-3972,-388,-292,-3960,-396,-300,-3968,-404,-292,-3968,-404,-292,-3964,-404,-292,-3972,-388,-288,-3968,-396,-292,-3972,-400,-292,-3968,-388,-288,-3964,-396,-296,-3976,-404,-292,-3972,-396,-288,-3972,-396,-292,-3972,-388,-292,-3964,-392,-288,-3968,-396,-300,-3960,-404,-292,-3968,-404,-284,-3984,-384,-284,-3972,-388,-296,-3972,-408,-292,-3964,-420,-292,-3964,-412,-300,-3972,-388,-296,-3964,-388,-284,-3972,-388,-276,-3968,-384,-292,-3968,-408,-288,-3964,-424,-296,-3984,-388,-284,-3960,-372,-288,-3972,-396,-292,-3976,-404,-288,-3964,-384,-284,-3960,-404,-304,-3976,-400,-272,-3952,-412,-300,-3988,-376,-280,-3956,-372,-292,-3960,-420,-296,-3984,-420,-280,-3960,-392,-280,-3968,-384,-300,-3980,-368,-284,-3948,-420,-300,-3984,-408,-280,-3968},\r
+{53,-380,-292,-3956,-384,-296,-3980,-396,-288,-3948,-412,-292,-3976,-412,-280,-3996,-380,-276,-3956,-388,-308,-3976,-400,-284,-3956,-408,-296,-3960,-408,-296,-3972,-392,-296,-3968,-384,-280,-3968,-400,-288,-3976,-388,-284,-3960,-396,-304,-3984,-404,-284,-3960,-400,-292,-3972,-376,-292,-3972,-380,-288,-3964,-408,-288,-3980,-404,-288,-3968,-376,-292,-3960,-392,-296,-3976,-400,-284,-3964,-400,-296,-3972,-396,-288,-3972,-380,-292,-3964,-392,-296,-3972,-400,-284,-3964,-396,-304,-3976,-384,-288,-3960,-388,-304,-3980,-404,-280,-3968,-400,-284,-3972,-380,-288,-3976,-388,-300,-3960,-392,-284,-3960,-424,-304,-3996,-396,-260,-3964,-392,-308,-3992,-384,-284,-3960,-408,-292,-3952,-424,-300,-3976,-396,-288,-3960,-364,-296,-3968,-380,-292,-3976,-388,-284,-3960,-408,-296,-3976,-396,-280,-3972,-392,-296,-3964,-388,-292,-3980,-388,-284,-3968,-396,-300,-3968},\r
+{52,-396,-296,-3976,-384,-288,-3956,-396,-292,-3976,-404,-284,-3964,-396,-284,-3976,-396,-296,-3968,-376,-292,-3960,-400,-304,-3976,-404,-284,-3972,-396,-292,-3972,-392,-296,-3972,-380,-292,-3964,-408,-296,-3980,-404,-288,-3968,-388,-288,-3968,-404,-300,-3968,-400,-292,-3960,-392,-300,-3968,-392,-296,-3960,-396,-284,-3976,-420,-292,-3996,-396,-280,-3960,-396,-308,-3980,-408,-300,-3956,-408,-300,-3956,-408,-304,-3976,-400,-296,-3960,-384,-288,-3968,-392,-304,-3972,-388,-276,-3956,-420,-304,-3984,-400,-284,-3972,-392,-300,-3964,-404,-300,-3976,-408,-296,-3960,-412,-296,-3968,-408,-296,-3968,-380,-288,-3956,-404,-304,-3980,-416,-292,-3964,-412,-300,-3968,-400,-292,-3972,-384,-296,-3956,-404,-304,-3976,-416,-300,-3964,-420,-292,-3972,-420,-300,-3976,-376,-296,-3960,-392,-308,-3964,-416,-292,-3964,-416,-292,-3960,-404,-292,-3960},\r
+{53,-420,-320,-3988,-400,-284,-3952,-396,-288,-3976,-404,-304,-3992,-412,-292,-3944,-432,-300,-3976,-416,-300,-3968,-384,-284,-3944,-416,-324,-4000,-384,-272,-3940,-384,-300,-3960,-436,-308,-3988,-412,-276,-3940,-400,-308,-3988,-388,-292,-3976,-396,-284,-3944,-424,-312,-3988,-396,-280,-3940,-412,-300,-3972,-436,-296,-3984,-392,-284,-3948,-396,-308,-3980,-400,-276,-3960,-420,-300,-3980,-408,-292,-3972,-376,-288,-3956,-420,-308,-3988,-412,-276,-3952,-388,-304,-3968,-392,-296,-3984,-400,-272,-3948,-440,-316,-3996,-380,-276,-3948,-364,-300,-3948,-428,-312,-4000,-412,-268,-3956,-380,-296,-3992,-388,-292,-3980,-400,-288,-3944,-444,-316,-3984,-400,-280,-3948,-384,-296,-3972,-408,-296,-3984,-392,-272,-3952,-396,-308,-3980,-384,-292,-3960,-408,-288,-3968,-428,-296,-3988,-372,-276,-3952,-384,-308,-3976,-408,-288,-3968,-404,-284,-3964,-412,-304,-3992},\r
+{53,-380,-276,-3956,-396,-304,-3972,-400,-288,-3968,-388,-296,-3956,-416,-304,-3984,-408,-284,-3964,-396,-288,-3972,-404,-300,-3976,-380,-284,-3944,-400,-300,-3980,-400,-288,-3964,-396,-296,-3968,-400,-296,-3980,-388,-280,-3956,-404,-308,-3972,-412,-284,-3976,-396,-284,-3972,-392,-292,-3980,-396,-292,-3964,-412,-296,-3964,-424,-292,-3968,-396,-288,-3956,-376,-304,-3976,-380,-288,-3956,-408,-296,-3980,-424,-292,-3972,-392,-284,-3940,-396,-300,-3996,-412,-292,-3976,-416,-288,-3960,-412,-300,-3984,-388,-284,-3952,-400,-308,-3980,-420,-292,-3968,-400,-276,-3952,-408,-304,-3988,-392,-288,-3956,-388,-300,-3968,-416,-292,-3980,-396,-284,-3956,-408,-304,-3980,-400,-288,-3968,-408,-292,-3964,-412,-300,-3980,-392,-288,-3952,-388,-308,-3972,-400,-288,-3972,-404,-284,-3956,-412,-304,-3976,-408,-288,-3968,-408,-288,-3980,-404,-292,-3980,-384,-300,-3960},\r
+{53,-408,-304,-3964,-408,-288,-3964,-408,-300,-3968,-392,-296,-3968,-384,-284,-3960,-400,-288,-3976,-408,-288,-3964,-404,-292,-3964,-396,-300,-3972,-384,-288,-3972,-404,-296,-3972,-408,-292,-3972,-400,-296,-3964,-404,-296,-3972,-400,-288,-3960,-408,-288,-3972,-404,-288,-3972,-396,-296,-3968,-392,-292,-3972,-404,-292,-3968,-416,-292,-3976,-412,-292,-3964,-404,-296,-3972,-404,-288,-3972,-392,-284,-3960,-408,-284,-3976,-408,-288,-3976,-384,-292,-3956,-400,-300,-3968,-416,-292,-3972,-408,-292,-3980,-396,-288,-3968,-400,-292,-3968,-424,-296,-3968,-424,-284,-3960,-392,-288,-3964,-384,-292,-3968,-392,-300,-3960,-404,-292,-3964,-404,-296,-3968,-400,-300,-3968,-408,-288,-3972,-392,-276,-3976,-392,-284,-3968,-392,-296,-3960,-408,-300,-3960,-404,-300,-3960,-408,-296,-3984,-416,-288,-3964,-392,-284,-3960,-380,-284,-3968,-396,-296,-3972,-408,-280,-3960},\r
+{53,-412,-296,-3972,-404,-304,-3972,-408,-304,-3968,-396,-288,-3968,-396,-284,-3972,-404,-288,-3972,-412,-280,-3968,-388,-292,-3964,-392,-300,-3956,-420,-304,-3968,-428,-288,-3976,-412,-280,-3984,-396,-292,-3976,-384,-300,-3960,-400,-292,-3960,-424,-296,-3968,-416,-296,-3968,-404,-296,-3968,-404,-292,-3976,-416,-296,-3960,-416,-284,-3968,-412,-296,-3972,-400,-292,-3968,-412,-296,-3976,-424,-296,-3968,-404,-300,-3960,-412,-300,-3964,-416,-288,-3964,-428,-296,-3972,-420,-300,-3964,-404,-292,-3952,-408,-296,-3972,-420,-300,-3976,-424,-300,-3964,-408,-296,-3964,-400,-292,-3964,-424,-300,-3972,-428,-300,-3968,-404,-300,-3960,-400,-300,-3968,-424,-296,-3968,-420,-288,-3960,-412,-304,-3968,-412,-288,-3976,-428,-288,-3984,-408,-288,-3968,-400,-312,-3960,-420,-304,-3956,-440,-304,-3960,-424,-296,-3968,-404,-300,-3968,-396,-284,-3960,-424,-300,-3976},\r
+{53,-420,-292,-3964,-412,-296,-3968,-404,-304,-3972,-408,-300,-3968,-412,-296,-3968,-424,-288,-3972,-416,-288,-3968,-412,-300,-3968,-404,-292,-3964,-408,-296,-3960,-412,-292,-3968,-404,-296,-3968,-404,-296,-3964,-424,-292,-3972,-420,-296,-3968,-404,-288,-3968,-412,-300,-3964,-408,-292,-3968,-416,-292,-3972,-408,-296,-3960,-396,-296,-3976,-408,-300,-3964,-424,-308,-3964,-420,-288,-3976,-392,-292,-3972,-408,-300,-3968,-416,-296,-3960,-420,-292,-3960,-404,-288,-3960,-400,-296,-3968,-400,-296,-3976,-408,-292,-3968,-408,-296,-3968,-404,-296,-3960,-404,-296,-3968,-416,-292,-3976,-408,-292,-3968,-400,-292,-3972,-400,-296,-3964,-400,-292,-3968,-412,-292,-3956,-392,-292,-3968,-404,-288,-3972,-420,-300,-3972,-412,-292,-3972,-404,-296,-3964,-392,-296,-3972,-400,-300,-3972,-412,-296,-3972,-412,-292,-3964,-396,-296,-3968,-392,-288,-3968,-400,-288,-3964},\r
+{53,-404,-284,-3968,-408,-292,-3964,-420,-300,-3972,-408,-288,-3980,-396,-288,-3976,-392,-296,-3972,-404,-296,-3968,-424,-296,-3964,-420,-288,-3964,-400,-292,-3968,-384,-288,-3968,-388,-280,-3968,-412,-292,-3968,-408,-292,-3968,-408,-300,-3968,-400,-292,-3972,-396,-292,-3968,-392,-296,-3964,-392,-296,-3968,-404,-292,-3968,-408,-292,-3972,-400,-288,-3964,-392,-280,-3968,-396,-296,-3960,-404,-296,-3972,-412,-292,-3968,-400,-288,-3964,-400,-292,-3964,-392,-288,-3968,-396,-292,-3968,-400,-288,-3968,-396,-292,-3968,-396,-288,-3968,-404,-296,-3968,-408,-288,-3972,-404,-308,-3964,-412,-292,-3972,-404,-284,-3976,-392,-288,-3976,-396,-292,-3972,-404,-292,-3956,-424,-284,-3968,-412,-292,-3972,-388,-292,-3968,-388,-292,-3964,-396,-284,-3964,-404,-300,-3964,-412,-296,-3968,-412,-292,-3972,-400,-288,-3972,-388,-296,-3972,-396,-296,-3964,-400,-292,-3968},\r
+{53,-404,-288,-3964,-404,-288,-3968,-400,-288,-3968,-404,-292,-3968,-396,-296,-3968,-392,-308,-3968,-404,-292,-3968,-412,-292,-3972,-400,-288,-3972,-400,-296,-3968,-400,-288,-3968,-404,-288,-3972,-396,-296,-3964,-404,-300,-3968,-400,-288,-3968,-392,-288,-3968,-400,-304,-3968,-416,-284,-3976,-408,-280,-3984,-388,-284,-3972,-376,-300,-3948,-404,-296,-3968,-432,-300,-3968,-412,-288,-3972,-380,-292,-3968,-384,-288,-3968,-396,-288,-3972,-400,-300,-3964,-404,-292,-3968,-408,-288,-3972,-388,-284,-3972,-388,-300,-3972,-400,-300,-3968,-396,-300,-3960,-392,-296,-3964,-400,-296,-3964,-404,-292,-3972,-400,-296,-3968,-384,-284,-3968,-392,-296,-3968,-404,-288,-3972,-412,-284,-3972,-400,-284,-3980,-388,-292,-3964,-380,-288,-3964,-404,-288,-3972,-416,-288,-3976,-408,-292,-3968,-368,-292,-3964,-388,-296,-3964,-408,-296,-3968,-412,-284,-3980,-396,-280,-3984},\r
+{53,-384,-300,-3964,-388,-296,-3960,-408,-288,-3964,-424,-284,-3972,-404,-292,-3976,-376,-296,-3972,-372,-288,-3960,-400,-288,-3964,-424,-292,-3968,-416,-296,-3964,-384,-288,-3972,-388,-292,-3972,-400,-284,-3972,-400,-296,-3972,-388,-296,-3960,-396,-296,-3964,-412,-288,-3964,-408,-292,-3968,-392,-292,-3968,-388,-288,-3968,-396,-288,-3968,-404,-292,-3968,-392,-300,-3968,-408,-292,-3972,-408,-280,-3964,-416,-300,-3976,-404,-296,-3964,-396,-292,-3964,-388,-300,-3960,-392,-292,-3968,-404,-288,-3968,-404,-296,-3976,-400,-284,-3976,-388,-284,-3976,-396,-296,-3964,-404,-292,-3960,-412,-284,-3960,-396,-288,-3972,-396,-304,-3964,-380,-288,-3972,-392,-292,-3968,-400,-288,-3968,-408,-280,-3972,-420,-292,-3972,-392,-296,-3964,-372,-296,-3964,-396,-292,-3972,-424,-288,-3968,-412,-296,-3976,-380,-296,-3968,-384,-296,-3968,-400,-296,-3960,-396,-284,-3968},\r
+{53,-396,-300,-3964,-384,-300,-3964,-404,-296,-3964,-400,-296,-3960,-380,-284,-3968,-416,-304,-3972,-412,-284,-3972,-408,-292,-3976,-412,-288,-3964,-408,-296,-3960,-392,-288,-3952,-400,-288,-3976,-416,-288,-3976,-408,-288,-3980,-384,-296,-3980,-388,-296,-3968,-404,-280,-3960,-416,-292,-3972,-412,-304,-3968,-412,-308,-3972,-392,-292,-3964,-376,-292,-3968,-380,-284,-3968,-384,-280,-3968,-388,-288,-3968,-404,-288,-3972,-396,-292,-3968,-400,-296,-3968,-396,-300,-3968,-392,-300,-3964,-388,-292,-3972,-404,-292,-3972,-396,-284,-3976,-388,-284,-3972,-396,-284,-3968,-404,-300,-3972,-396,-300,-3968,-404,-288,-3972,-404,-288,-3972,-376,-292,-3968,-364,-296,-3976,-404,-296,-3964,-420,-292,-3968,-376,-284,-3968,-376,-292,-3968,-396,-288,-3964,-404,-292,-3976,-384,-292,-3980,-368,-300,-3964,-404,-312,-3980,-420,-288,-3964,-400,-300,-3968,-372,-296,-3968},\r
+{53,-376,-292,-3960,-404,-284,-3972,-416,-288,-3964,-392,-304,-3960,-384,-296,-3976,-388,-288,-3968,-388,-292,-3976,-376,-296,-3972,-392,-284,-3968,-412,-288,-3972,-408,-292,-3972,-392,-296,-3964,-392,-300,-3976,-376,-300,-3968,-376,-292,-3968,-388,-284,-3968,-376,-280,-3972,-376,-312,-3972,-384,-288,-3964,-404,-304,-3980,-404,-284,-3968,-376,-296,-3968,-388,-296,-3968,-388,-280,-3972,-392,-296,-3972,-372,-292,-3972,-376,-296,-3968,-392,-280,-3984,-400,-284,-3972,-368,-304,-3960,-364,-284,-3964,-432,-304,-3960,-412,-296,-3968,-368,-308,-3972,-380,-284,-3980,-396,-288,-3960,-380,-292,-3968,-364,-284,-3964,-384,-300,-3984,-412,-292,-3968,-392,-288,-3960,-380,-300,-3968,-388,-288,-3964,-400,-284,-3964,-388,-284,-3976,-392,-284,-3968,-396,-292,-3976,-376,-296,-3972,-392,-300,-3972,-396,-296,-3968,-380,-292,-3960,-380,-296,-3968,-392,-284,-3976},\r
+{53,-396,-276,-3972,-384,-284,-3976,-364,-288,-3964,-384,-304,-3968,-392,-280,-3972,-388,-292,-3968,-388,-288,-3976,-392,-284,-3980,-384,-288,-3976,-384,-292,-3968,-392,-304,-3972,-380,-288,-3960,-384,-292,-3964,-388,-296,-3980,-380,-288,-3968,-388,-296,-3976,-392,-292,-3968,-384,-284,-3968,-384,-296,-3976,-380,-280,-3972,-396,-296,-3972,-400,-296,-3980,-384,-296,-3960,-368,-296,-3968,-380,-288,-3968,-388,-284,-3972,-408,-284,-3980,-376,-284,-3964,-372,-300,-3972,-392,-296,-3968,-404,-288,-3976,-396,-288,-3976,-372,-300,-3968,-372,-300,-3968,-388,-296,-3968,-384,-284,-3968,-380,-288,-3972,-376,-296,-3964,-372,-288,-3968,-388,-304,-3964,-400,-292,-3972,-388,-292,-3984,-368,-288,-3968,-376,-292,-3972,-412,-304,-3972,-404,-284,-3964,-380,-300,-3968,-364,-304,-3980,-376,-288,-3952,-400,-296,-3968,-388,-284,-3960,-392,-300,-3976,-396,-284,-3972},\r
+{53,-368,-276,-3968,-368,-296,-3984,-388,-300,-3968,-392,-292,-3964,-400,-288,-3976,-384,-292,-3964,-372,-292,-3972,-384,-292,-3972,-396,-284,-3968,-392,-292,-3968,-372,-292,-3972,-376,-304,-3968,-384,-296,-3964,-404,-296,-3968,-396,-288,-3980,-384,-288,-3968,-384,-292,-3968,-384,-288,-3976,-380,-284,-3968,-392,-308,-3968,-396,-296,-3956,-400,-292,-3984,-392,-288,-3980,-372,-288,-3968,-384,-304,-3972,-408,-288,-3964,-416,-300,-3964,-392,-296,-3976,-368,-288,-3960,-384,-292,-3972,-400,-292,-3968,-384,-300,-3968,-388,-304,-3972,-392,-296,-3968,-396,-288,-3968,-388,-288,-3972,-396,-292,-3968,-400,-296,-3968,-388,-296,-3960,-384,-300,-3972,-396,-304,-3968,-392,-284,-3964,-392,-296,-3976,-388,-288,-3968,-392,-288,-3964,-416,-288,-3968,-400,-292,-3968,-388,-292,-3976,-396,-300,-3972,-412,-296,-3964,-400,-300,-3972,-388,-288,-3960,-396,-296,-3968},\r
+{52,-408,-292,-3980,-392,-296,-3980,-396,-300,-3968,-396,-304,-3956,-424,-292,-3968,-412,-296,-3964,-380,-304,-3964,-380,-292,-3968,-404,-292,-3968,-408,-292,-3964,-400,-296,-3980,-392,-292,-3960,-384,-292,-3964,-396,-292,-3984,-404,-296,-3968,-388,-292,-3960,-380,-296,-3968,-388,-288,-3968,-424,-296,-3976,-396,-288,-3964,-360,-292,-3960,-388,-308,-3980,-416,-288,-3964,-412,-296,-3976,-376,-292,-3964,-384,-296,-3968,-400,-296,-3972,-400,-292,-3968,-392,-292,-3972,-392,-292,-3972,-380,-292,-3964,-392,-312,-3968,-392,-288,-3960,-392,-284,-3980,-392,-288,-3980,-388,-296,-3972,-400,-296,-3964,-392,-296,-3960,-400,-304,-3968,-392,-296,-3960,-380,-288,-3968,-372,-288,-3976,-392,-292,-3972,-400,-292,-3972,-384,-296,-3972,-372,-296,-3972,-384,-296,-3972,-392,-296,-3972,-400,-296,-3972,-388,-304,-3968,-372,-296,-3964,-388,-296,-3972},\r
+{53,-388,-288,-3972,-396,-284,-3968,-392,-300,-3972,-372,-300,-3968,-380,-296,-3964,-392,-300,-3976,-384,-292,-3960,-376,-296,-3960,-388,-292,-3984,-388,-292,-3968,-380,-300,-3976,-392,-300,-3960,-400,-292,-3976,-396,-288,-3984,-364,-292,-3968,-348,-296,-3960,-392,-292,-3976,-420,-284,-3960,-388,-292,-3976,-368,-300,-3968,-376,-296,-3968,-404,-296,-3972,-392,-292,-3964,-372,-296,-3968,-388,-304,-3976,-380,-288,-3976,-376,-292,-3968,-384,-288,-3964,-392,-296,-3964,-388,-284,-3972,-388,-288,-3968,-392,-300,-3972,-388,-292,-3968,-372,-284,-3972,-372,-300,-3972,-388,-304,-3964,-388,-300,-3972,-380,-288,-3972,-388,-284,-3976,-388,-288,-3968,-380,-284,-3976,-388,-296,-3968,-380,-296,-3968,-364,-292,-3964,-384,-296,-3964,-392,-300,-3976,-388,-284,-3984,-372,-288,-3972,-376,-288,-3976,-392,-300,-3964,-396,-292,-3968,-396,-292,-3964,-376,-300,-3964},\r
+{53,-364,-292,-3968,-376,-292,-3968,-396,-296,-3976,-392,-284,-3976,-380,-296,-3968,-368,-296,-3968,-380,-292,-3976,-392,-300,-3972,-380,-304,-3968,-384,-300,-3972,-380,-284,-3968,-376,-288,-3972,-372,-300,-3968,-368,-304,-3964,-392,-292,-3976,-400,-300,-3976,-380,-296,-3976,-368,-300,-3976,-380,-300,-3964,-388,-296,-3964,-384,-300,-3968,-364,-296,-3964,-388,-296,-3972,-384,-292,-3972,-376,-296,-3972,-380,-312,-3964,-380,-292,-3968,-384,-304,-3988,-380,-300,-3980,-384,-296,-3956,-388,-300,-3968,-384,-288,-3964,-404,-300,-3976,-396,-288,-3968,-356,-292,-3964,-364,-308,-3980,-392,-300,-3960,-384,-300,-3972,-372,-300,-3972,-380,-292,-3972,-400,-296,-3972,-380,-296,-3976,-380,-296,-3964,-400,-300,-3972,-392,-296,-3968,-372,-300,-3972,-376,-304,-3968,-388,-296,-3968,-388,-300,-3976,-388,-300,-3972,-380,-300,-3968,-388,-300,-3976,-380,-300,-3968},\r
+{53,-396,-304,-3972,-392,-296,-3968,-380,-296,-3968,-384,-304,-3972,-392,-300,-3964,-384,-292,-3964,-372,-296,-3968,-392,-304,-3972,-408,-300,-3984,-392,-292,-3972,-380,-308,-3972,-388,-304,-3968,-404,-296,-3960,-408,-296,-3968,-392,-300,-3964,-372,-304,-3972,-372,-296,-3960,-392,-304,-3972,-404,-308,-3976,-392,-296,-3964,-380,-308,-3972,-388,-296,-3972,-388,-300,-3968,-400,-304,-3972,-388,-296,-3960,-380,-296,-3964,-396,-296,-3976,-396,-300,-3968,-396,-312,-3976,-388,-300,-3964,-384,-296,-3968,-396,-300,-3972,-392,-300,-3964,-388,-300,-3972,-404,-296,-3976,-400,-304,-3968,-380,-304,-3984,-376,-304,-3964,-392,-296,-3960,-404,-300,-3980,-388,-300,-3964,-380,-300,-3972,-388,-304,-3964,-400,-296,-3968,-396,-296,-3988,-364,-292,-3976,-380,-308,-3972,-408,-300,-3968,-404,-296,-3960,-380,-304,-3964,-376,-300,-3964,-392,-296,-3964,-392,-296,-3976},\r
+{53,-368,-296,-3964,-384,-308,-3968,-400,-292,-3964,-388,-296,-3968,-376,-304,-3976,-384,-300,-3968,-392,-304,-3968,-376,-304,-3968,-388,-300,-3960,-392,-300,-3972,-388,-300,-3980,-380,-296,-3972,-380,-296,-3972,-376,-304,-3960,-380,-300,-3972,-400,-300,-3980,-392,-288,-3968,-380,-308,-3972,-372,-296,-3968,-372,-300,-3972,-380,-308,-3972,-380,-304,-3964,-400,-300,-3968,-392,-300,-3976,-372,-300,-3964,-364,-316,-3964,-380,-296,-3976,-396,-292,-3976,-388,-296,-3980,-372,-304,-3968,-380,-308,-3960,-400,-308,-3964,-384,-300,-3960,-372,-312,-3972,-384,-288,-3976,-388,-292,-3976,-372,-304,-3968,-364,-308,-3960,-380,-308,-3964,-400,-300,-3988,-392,-296,-3960,-368,-296,-3976,-380,-316,-3980,-400,-308,-3964,-400,-300,-3964,-372,-304,-3968,-356,-292,-3964,-404,-304,-3992,-384,-296,-3960,-364,-304,-3964,-388,-304,-3972,-392,-296,-3964,-396,-304,-3980},\r
+{53,-388,-296,-3968,-372,-300,-3960,-372,-308,-3972,-388,-296,-3972,-392,-292,-3972,-380,-304,-3976,-368,-296,-3968,-380,-304,-3964,-384,-304,-3968,-400,-300,-3972,-392,-296,-3984,-380,-300,-3980,-388,-308,-3972,-384,-300,-3960,-376,-300,-3968,-384,-300,-3968,-392,-296,-3972,-372,-296,-3976,-364,-300,-3964,-392,-312,-3968,-400,-312,-3968,-376,-296,-3968,-372,-308,-3972,-376,-296,-3976,-380,-312,-3968,-380,-304,-3972,-388,-300,-3964,-400,-304,-3968,-388,-296,-3968,-368,-296,-3972,-368,-300,-3976,-376,-308,-3964,-388,-304,-3968,-388,-308,-3968,-380,-304,-3972,-376,-304,-3968,-376,-296,-3976,-392,-308,-3968,-392,-296,-3968,-376,-292,-3964,-380,-316,-3980,-384,-300,-3956,-384,-304,-3976,-384,-300,-3972,-372,-304,-3964,-372,-296,-3988,-392,-296,-3972,-384,-296,-3964,-388,-312,-3976,-384,-300,-3952,-392,-312,-3968,-388,-304,-3972,-360,-300,-3964},\r
+{53,-368,-308,-3976,-388,-288,-3964,-404,-312,-3972,-388,-308,-3980,-368,-300,-3948,-388,-304,-3976,-404,-308,-3988,-376,-280,-3944,-372,-312,-3976,-364,-300,-3976,-396,-300,-3968,-384,-292,-3984,-376,-312,-3960,-364,-300,-3952,-420,-316,-3992,-392,-288,-3960,-368,-308,-3968,-368,-304,-3984,-392,-288,-3956,-384,-304,-3984,-376,-300,-3972,-380,-304,-3956,-400,-324,-3960,-372,-296,-3956,-384,-300,-3964,-384,-296,-3984,-384,-300,-3976,-376,-300,-3984,-368,-300,-3972,-376,-308,-3968,-408,-308,-3976,-400,-300,-3960,-376,-300,-3968,-372,-312,-3964,-372,-292,-3968,-380,-304,-3976,-372,-300,-3964,-368,-308,-3972,-376,-304,-3972,-380,-296,-3968,-388,-292,-3972,-380,-300,-3972,-376,-292,-3968,-384,-308,-3964,-364,-296,-3960,-384,-304,-3964,-392,-300,-3976,-396,-308,-3968,-388,-304,-3984,-392,-300,-3968,-384,-296,-3968,-372,-292,-3968,-376,-304,-3968},\r
+{53,-392,-296,-3980,-396,-296,-3960,-372,-300,-3964,-364,-308,-3960,-384,-304,-3968,-404,-292,-3980,-388,-296,-3972,-384,-300,-3976,-380,-292,-3976,-388,-288,-3972,-376,-296,-3968,-380,-292,-3964,-392,-300,-3964,-396,-308,-3972,-380,-300,-3972,-360,-300,-3968,-376,-296,-3968,-388,-284,-3968,-404,-296,-3972,-384,-300,-3972,-372,-304,-3976,-396,-292,-3976,-396,-296,-3976,-376,-296,-3968,-364,-312,-3968,-380,-296,-3972,-416,-292,-3972,-388,-296,-3976,-364,-300,-3960,-364,-300,-3972,-384,-296,-3972,-384,-296,-3968,-376,-300,-3972,-380,-296,-3972,-388,-304,-3976,-376,-300,-3968,-364,-296,-3968,-380,-296,-3972,-392,-296,-3964,-376,-296,-3964,-376,-304,-3964,-392,-308,-3968,-400,-292,-3976,-380,-296,-3984,-364,-300,-3968,-372,-304,-3964,-404,-300,-3964,-412,-300,-3968,-388,-304,-3972,-372,-304,-3972,-380,-292,-3972,-384,-296,-3972,-388,-296,-3968},\r
+{53,-384,-296,-3968,-384,-300,-3980,-384,-292,-3972,-388,-300,-3968,-396,-304,-3964,-396,-300,-3972,-392,-300,-3972,-380,-296,-3968,-380,-296,-3968,-384,-296,-3968,-368,-288,-3968,-372,-300,-3976,-392,-308,-3964,-420,-308,-3968,-416,-304,-3968,-392,-296,-3968,-364,-292,-3968,-356,-304,-3968,-376,-292,-3972,-412,-300,-3976,-408,-308,-3964,-364,-304,-3968,-372,-304,-3964,-400,-292,-3976,-420,-284,-3988,-396,-292,-3976,-368,-312,-3964,-384,-308,-3956,-416,-292,-3968,-404,-300,-3972,-364,-300,-3968,-364,-300,-3968,-392,-296,-3968,-400,-296,-3968,-396,-296,-3964,-408,-296,-3968,-400,-300,-3968,-404,-304,-3968,-388,-304,-3976,-388,-312,-3968,-392,-304,-3968,-384,-296,-3972,-396,-296,-3968,-404,-292,-3968,-408,-304,-3964,-392,-304,-3968,-388,-308,-3968,-392,-300,-3972,-396,-304,-3972,-384,-300,-3972,-392,-304,-3968,-396,-300,-3968,-392,-304,-3964},\r
+ \r
+};\r
+static const uint32_t duration_SPO2[] = \r
+{\r
+975,\r
+1026,\r
+982,\r
+1006,\r
+1005,\r
+1006,\r
+1026,\r
+983,\r
+1007,\r
+1006,\r
+1005,\r
+1028,\r
+984,\r
+1006,\r
+1006,\r
+1006,\r
+1028,\r
+984,\r
+1008,\r
+1006,\r
+1005,\r
+1030,\r
+983,\r
+1006,\r
+1005,\r
+1007,\r
+1026,\r
+983,\r
+1006,\r
+1007,\r
+1006,\r
+1029,\r
+985,   \r
+};\r
+\r
+static const uint8_t frame_SPO2[] = \r
+{\r
+73,\r
+74,\r
+75,\r
+76,\r
+77,\r
+78,\r
+79,\r
+80,\r
+81,\r
+82,\r
+83,\r
+84,\r
+85,\r
+86,\r
+87,\r
+88,\r
+89,\r
+90,\r
+91,\r
+92,\r
+93,\r
+94,\r
+95,\r
+96,\r
+97,\r
+98,\r
+99,\r
+100,\r
+101,\r
+102,\r
+103,\r
+104,\r
+105,\r
+};\r
+       \r
+#endif\r
diff --git a/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/SPO2/V587/pah_spo2_alg.c b/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/SPO2/V587/pah_spo2_alg.c
new file mode 100644 (file)
index 0000000..d3b0c77
--- /dev/null
@@ -0,0 +1,611 @@
+// c\r
+#include <string.h>\r
+#include <stdint.h>\r
+#include <stdbool.h>\r
+#include <stdlib.h>\r
+#include <stdio.h>\r
+#include <string.h>\r
+\r
+#include "pah831x_config.h"\r
+#include "pah831x_main.h"\r
+#include "pah831x_comm.h"\r
+\r
+// SPO2 algorithm\r
+//#include "pxialg_spo2.h"\r
+#include "pah_spo2_alg.h"\r
+// HR   algorithm\r
+// algorithm\r
+#include "pxialg_spo2.h"\r
+// HR algorithm\r
+#include "pxialg.h"\r
+\r
+\r
+//#include "pxialg.h"\r
+#if defined(ENABLE_PXI_ALG_HRD)\r
+#include "pah8series_api_c.h"\r
+#endif\r
+#ifndef ENABLE_PXI_ALG_HRD\r
+typedef struct {\r
+    uint8_t                     frame_count;\r
+    uint32_t                    time;\r
+    uint8_t                     touch_flag;\r
+    uint32_t                    nf_ppg_channel;\r
+    uint32_t                    nf_ppg_per_channel;\r
+    int32_t                     *ppg_data;\r
+    uint32_t                    nf_mems;\r
+    int16_t                     *mems_data;\r
+} pah8series_data_t;\r
+\r
+#endif\r
+\r
+\r
+typedef struct\r
+{\r
+    // pxialg\r
+    void*                pxialg_buffer_spo2;\r
+   void*                 pxialg_buffer_hr;\r
+    pah8series_data_t    pxialg_data;\r
+    bool                 pxialg_has_init;\r
+    uint64_t             last_report_time;\r
+    uint32_t             Expo_time[3];\r
+    uint8_t              LEDDAC[3];\r
+    alg_status_e         alg_status;\r
+    uint8_t              Tuning;\r
+    uint16_t             Touch_data;\r
+    uint8_t*             ppg_dac_data;\r
+} main_spo2_state_s;\r
+\r
+\r
+static bool need_log_header = true;\r
+//static SpO2_info_t    _spo2_detect_item;\r
+static main_spo2_state_s _state;\r
+//static SpO2_mems_t  mems_data_raw[PPG_BUF_MAX_SPO2]; \r
+\r
+static uint8_t  alg_cal_en              = 0 ;\r
+static uint32_t data_buf_count          = 0 ;\r
+static uint32_t data_buf_count_spo2_alg = 0 ;\r
+static uint32_t data_buf_num            = 0 ;\r
+\r
+static float    myHR                    = 0.0f;\r
+//static float    myHR_opt                = 0.0f;\r
+static float    mySpO2                  = 0.0f;\r
+static float    hr_grader               = 0.0f;\r
+//static float    HR_temp                 = 0.0f;\r
+static uint8_t  mySPO2_ReadyFlag        = 0   ;\r
+//static uint8_t  mySPO2_ReadyFlag_out  = 0   ;\r
+static float    correlation             = 0.0f;\r
+static float    trust_flag              = 0.0f;\r
+static float    MEMS_RMS                = 0.0f;\r
+\r
+static int32_t  alg_count=0;\r
+\r
+static float hr_inupt_info = 0 ;\r
+static uint8_t log_data_en_spo2  = 0 ;\r
+//static uint8_t alg_work_mode_spo2= 0 ;\r
+//static uint8_t afe_gain_spo2= 0 ;\r
+//static uint8_t ppg_setting_spo2= 0 ;\r
+\r
+\r
+\r
+static int32_t ppg_data_buf[120]={0};\r
+static uint8_t ppg_dac_buf[120]={0};\r
+\r
+static uint8_t spo2_ret = 0;\r
+\r
+/*============================================================================\r
+STATIC FUNCTION PROTOTYPES\r
+============================================================================*/\r
+\r
+static void log_pah8series_data_header(uint32_t ch_num, uint32_t ir_ch_num, uint32_t g_sensor_mode);\r
+static void log_pah8series_data(const pah8series_data_t *data);\r
+static bool spo2_algorithm_process(pah8series_data_t *pxialg_data, uint32_t ch_num);\r
+static void spo2_algorithm_calculate_run(void);\r
+static uint8_t spo2_algorithm_calculate(pah8series_data_t *pxialg_data);\r
+\r
+\r
+static void log_pah8series_data_header(uint32_t ch_num, uint32_t ir_ch_num, uint32_t g_sensor_mode)\r
+{\r
+    //log pah8series data header\r
+    // (1)Using total channel numbers;\r
+    // (2)reserved;\r
+    // (3)reserved;\r
+    // (4)IR channel number;\r
+    // (5)MEMS mode 0:2G, 1:4G, 2:8G\r
+    //LOG_PRINT("PPG CH#, %d, %d, %d, %d, %d\n", ch_num, get_ppg_setting_version(), 0, ir_ch_num, g_sensor_mode);\r
+    LOG_PRINT("PPG CH#, %d, %d, %d, %d, %d\n", ch_num, 0, 0, ir_ch_num, g_sensor_mode);\r
+\r
+}\r
+static void log_pah8series_data(const pah8series_data_t *pxialg_data)\r
+{\r
+    int i = 0;\r
+    uint32_t *ppg_data = (uint32_t *)pxialg_data->ppg_data;\r
+    \r
+    uint8_t *dac_data = _state.ppg_dac_data;\r
+    \r
+    int16_t *mems_data = pxialg_data->mems_data;\r
+    int data_num = pxialg_data->nf_ppg_channel * pxialg_data->nf_ppg_per_channel;\r
+    \r
+    LOG_PRINT("Frame Count, %d \n", pxialg_data->frame_count);\r
+    LOG_PRINT("Time, %d \n", pxialg_data->time);\r
+    LOG_PRINT("PPG, %d, %d, ", pxialg_data->touch_flag, data_num);\r
+    for (i = 0; i < data_num; ++i)\r
+    {\r
+        LOG_PRINT("%d, ", *ppg_data);\r
+        ppg_data++;\r
+    }\r
+    LOG_PRINT("\n");\r
+    LOG_PRINT("MEMS, %d, ", pxialg_data->nf_mems);\r
+    for (i = 0; i < (pxialg_data->nf_mems * 3); ++i)\r
+    {\r
+        LOG_PRINT("%d, ", *mems_data);\r
+        mems_data++;\r
+    }\r
+    LOG_PRINT("\n");\r
+    LOG_PRINT("DAC, %d, ", data_num);\r
+    for (i = 0; i < data_num; ++i)\r
+    {\r
+        LOG_PRINT("%d, ", *dac_data);\r
+        dac_data++;\r
+    }\r
+    LOG_PRINT("\n");\r
+//    LOG_PRINT("DAC, %d, ", pxialg_data->nf_ppg_channel);\r
+//    for (i = 0; i < pxialg_data->nf_ppg_channel; ++i)\r
+//    {\r
+//        LOG_PRINT("%d, ", *dac_data);\r
+//        dac_data++;\r
+//    }\r
+//    LOG_PRINT("\n");\r
+\r
+}\r
+\r
+\r
+\r
+bool  report_fifo_data_spo2(\r
+uint32_t ppg_timestamp,     \r
+uint32_t time_period, \r
+uint32_t *ppg_data,\r
+uint8_t *dac_data,\r
+uint32_t ppg_size,\r
+uint32_t ch_num,\r
+int16_t *acc_data,\r
+uint8_t acc_size, \r
+uint8_t *got_time_out, \r
+uint8_t is_touched,\r
+float hr_inupt,\r
+uint8_t log_data_en\r
+)\r
+{\r
+//    ALG_PRINT("time_period = %d  timestamp =%d \n", time_period , ppg_timestamp);\r
+    \r
+    //afe_gain_spo2 = AFE_Gain;\r
+    //ppg_setting_spo2 = ppg_setting ;\r
+    \r
+    hr_inupt_info  =   hr_inupt ; \r
+    log_data_en_spo2   =   log_data_en;\r
+    //alg_work_mode_spo2 =   alg_work_mode ;\r
+    \r
+    _state.pxialg_data.mems_data = acc_data ;\r
+    _state.pxialg_data.nf_mems =   acc_size  ;\r
+    _state.pxialg_data.touch_flag = is_touched<2 ? 1 : 0;\r
+    _state.pxialg_data.time = time_period;\r
+       _state.pxialg_data.ppg_data = (int32_t*)ppg_data;\r
+ \r
+    _state.pxialg_data.nf_ppg_channel = ch_num;\r
+    _state.pxialg_data.nf_ppg_per_channel = ppg_size;\r
+       if(ch_num==5)\r
+       {\r
+               _state.pxialg_data.nf_ppg_channel = 4;\r
+               for(int i = 0 ; i < ppg_size ;i++ )\r
+               {\r
+                       ppg_data_buf[4*i]  =ppg_data[5*i+1] ;\r
+                       ppg_data_buf[4*i+1]=ppg_data[5*i+2] ;\r
+                       ppg_data_buf[4*i+2]=ppg_data[5*i+3] ;\r
+                       ppg_data_buf[4*i+3]=ppg_data[5*i+4] ;   \r
+                       ppg_dac_buf[4*i]   =dac_data[5*i+1] ;\r
+                       ppg_dac_buf[4*i+1] =dac_data[5*i+2] ;\r
+                       ppg_dac_buf[4*i+2] =dac_data[5*i+3] ;\r
+                       ppg_dac_buf[4*i+3] =dac_data[5*i+4] ;\r
+                       \r
+               }               \r
+               \r
+               _state.pxialg_data.ppg_data = (int32_t*)ppg_data_buf;\r
+               _state.ppg_dac_data = ppg_dac_buf ;\r
+       }else\r
+       {\r
+               _state.pxialg_data.nf_ppg_channel = ch_num;\r
+               _state.pxialg_data.ppg_data = (int32_t*)ppg_data;\r
+               _state.ppg_dac_data = dac_data ;\r
+       }\r
+       \r
+    ++_state.pxialg_data.frame_count;\r
+    \r
+    spo2_algorithm_process(&_state.pxialg_data, _state.pxialg_data.nf_ppg_channel);\r
+\r
+    return true ;\r
+\r
+    \r
+}\r
+\r
+static void spo2_algorithm_calculate_run(void)\r
+{\r
+    if(alg_cal_en == 1)\r
+    {\r
+        alg_cal_en = 0 ;\r
+        data_buf_num = data_buf_count ;\r
+        data_buf_count = 0 ;\r
+\r
+        uint32_t qq1 = pxi_get_tick_count();\r
+        spo2_algorithm_calculate(&_state.pxialg_data);\r
+        uint32_t qq2 = pxi_get_tick_count();\r
+        LOG_PRINT("Cal time = %d data_buf_num = %d  \n",qq2-qq1,data_buf_num);\r
+    }\r
+}\r
+\r
+static bool spo2_algorithm_process(pah8series_data_t *pxialg_data, uint32_t ch_num)\r
+{\r
+    if(log_data_en_spo2)\r
+    {\r
+    // log header\r
+    if (need_log_header)\r
+    {\r
+        need_log_header = false;\r
+        log_pah8series_data_header(ch_num, PPG_IR_CH_NUM, ALG_GSENSOR_MODE);\r
+    }\r
+    \r
+    log_pah8series_data(&_state.pxialg_data);\r
+    }\r
+   // data_buf_count_spo2_alg += _state.pxialg_data.nf_ppg_per_channel ;\r
+    alg_cal_en = 1 ;\r
+    //LOG_PRINT("data_buf_count = %d data_buf_count_spo2_alg = %d  \n",data_buf_count, data_buf_count_spo2_alg);\r
+       if(_state.pxialg_data.touch_flag)\r
+    {\r
+               spo2_algorithm_calculate_run();\r
+       }\r
+    return true;        \r
+}\r
+\r
+static uint8_t spo2_algorithm_calculate(pah8series_data_t *pxialg_data)\r
+{\r
+    \r
+    int     i    ;\r
+    //int8_t alg_ch[2]    = {1, 0};\r
+    \r
+    uint8_t ReadyFlag   = 0;\r
+    \r
+    // CH1\r
+    float   ch1_spo2            = 0.0f;\r
+    float   ch1_correlation     = 0.0f;\r
+       float   ch1_trust_flag      = 0.0f;\r
+       uint8_t ch1_no_value_reason = 0   ;\r
+    float   ch1_ratio           = 0.0f;\r
+    float   ch1_periodocity     = 0.0f;\r
+    \r
+    // CH2\r
+    float   ch2_spo2            = 0.0f;\r
+    float   ch2_correlation     = 0.0f;\r
+       float   ch2_trust_flag      = 0.0f;\r
+       uint8_t ch2_no_value_reason = 0   ;\r
+    float   ch2_ratio           = 0.0f;\r
+    float   ch2_periodocity     = 0.0f;\r
+    \r
+    // CH3\r
+    float   ch3_spo2            = 0.0f;\r
+    float   ch3_correlation     = 0.0f;\r
+       float   ch3_trust_flag      = 0.0f;\r
+       uint8_t ch3_no_value_reason = 0   ;\r
+    float   ch3_ratio           = 0.0f;\r
+    float   ch3_periodocity     = 0.0f;\r
+      \r
+    float   Opt_SpO2   = 0   ;\r
+       float   MEMS_RMS   = 0.0f;\r
+       float   MEMS_Mean_X= 0.0f;\r
+       float   MEMS_Mean_Y= 0.0f;\r
+       float   MEMS_Mean_Z= 0.0f;\r
+//     float   myHR       = 0.0f;\r
+       int     ret_value  = 0   ;\r
+//     float   hr_grader  = 0.0f;\r
+       uint8_t ready_flag = 0   ;\r
+    int     Opt_falg   = 0   ;\r
+    \r
+    \r
+#if defined(ENABLE_PXI_ALG_SPO2)\r
+    // Initialize algorithm\r
+    if (!_state.pxialg_has_init)\r
+    {\r
+        int32_t version     = 0;\r
+        int     buffer_size = 0;\r
+        uint8_t ret = 0;\r
+        version     = SpO2_Version();\r
+        LOG_PRINT("SPO2_version =%d \n",version);\r
+        buffer_size = SpO2_OpenSize();\r
+        LOG_PRINT("SPO2_size = %d  \n", buffer_size);\r
+        _state.pxialg_buffer_spo2 = malloc(buffer_size);\r
+\r
+       // nrf_delay_ms(50);\r
+        if (!_state.pxialg_buffer_spo2)\r
+        {\r
+            LOG_PRINT("Out of memory. \n");\r
+            return false;\r
+        }\r
+        //nrf_delay_ms(50);\r
+        if (SpO2_Open(_state.pxialg_buffer_spo2) != SPO2_MSG_SUCCESS)\r
+        {\r
+            LOG_PRINT("SpO2_Open() failed. \n");\r
+            free(_state.pxialg_buffer_spo2);\r
+            return false;\r
+        }\r
+           //log_printf("pBuffer =%x \n",pBuffer);\r
+        \r
+        SpO2_SetInputRatioHighBound(94.0f);\r
+        SpO2_SetInputRatioLowBound(83.0f);\r
+        SpO2_SetInputModelScale(1.10000002384186f);\r
+    \r
+        SpO2_SetInputCoefHigh0(-10648.826171875f);\r
+        SpO2_SetInputCoefHigh1(334.476318359375f);\r
+        SpO2_SetInputCoefHigh2(-3.47309589385986f);\r
+        SpO2_SetInputCoefHigh3(0.0120320003479719f);\r
+    \r
+        SpO2_SetInputCoefMid0(-90.8541793823242f);\r
+        SpO2_SetInputCoefMid1(6.06652688980103f);\r
+        SpO2_SetInputCoefMid2(-0.071273997426033f);\r
+        SpO2_SetInputCoefMid3(0.000297999999020249f);\r
+    \r
+        SpO2_SetInputCoefLow0(37.8047142028809f);\r
+        SpO2_SetInputCoefLow1(0.723900973796844f);\r
+        SpO2_SetInputCoefLow2(-0.00353899993933737f);\r
+        SpO2_SetInputCoefLow3(0.0000319999999192078f);\r
+            \r
+        SpO2_SetIIRFilterRatio(0.5f);\r
+        SpO2_SetInputCorrelationTh(0.850000023841858f);\r
+        SpO2_SetInputRatioLow(0.05f);        \r
+    \r
+        SpO2_SetInputFlagCheckHr(1);\r
+        SpO2_SetMotionDetectionLevel(2.0f);\r
+        SpO2_Set_Update_Sec(1);\r
+            \r
+        SpO2_Set_Init_Low_SpO2_Constrain(0.0);  \r
+        SpO2_SetOutputHighBound(100.0f);\r
+        SpO2_SetOutputLowBound(60.0f);\r
+                    \r
+        SpO2_Set_Keep_Init_SpO2_Bound(92.00f);    \r
+        SpO2_Set_Keep_Init_SpO2_Count_Th(15.0f);  \r
+        SpO2_Set_SpO2_Bias_Value(0.3f);           \r
+        SpO2_Set_SpO2_Outlier_Smooth_Coef(5.5f);  \r
+        SpO2_Set_SpO2_Decrease_Coef(0.5f);        \r
+        SpO2_SetSkipDataLen(0);\r
+    \r
+        SpO2_Set_Flag_Hold_Breathe_Mode(0);\r
+        SpO2_Set_Input_Correlation_Th2(0.85000022411346f);\r
+        SpO2_Set_Correlation_Th2_Count(15);\r
+        SpO2_Set_Init_Low_SpO2_Th(92.0f);\r
+        SpO2_Set_Motion_Rms_Th(3000.0f);\r
+        SpO2_Set_Motion_Rms_Th2(3000.0f);\r
+        SpO2_Set_Motion_MEMS_Th(0.0f);\r
+        SpO2_Set_T1(0.85f);\r
+        SpO2_Set_Spo2_Force_Output_Second(27.0f);    \r
+        //SpO2_SetChMapping(alg_ch, 3); // Swap Channel\r
+        \r
+        Spo2_Set_Force_Output_Value(97.50f);  // Good Signal Force SpO2\r
+        Spo2_Set_Force_Output_Value2(95.00f); // Bad  Signal Force SpO2\r
+        \r
+        SpO2_Set_Init_Low_SpO2_Check_Sec(20);\r
+        Spo2_Set_SpO2_First_Smooth_Th(92.0f);\r
+        Spo2_Set_SpO2_First_Smooth_Sec(15);\r
+        Spo2_Set_SpO2_Correlation_Smooth_Th(0.85f);\r
+        SpO2_Set_Signal_Periodicity_Th(0.30f); \r
+\r
+      \r
+\r
+                \r
+        _state.pxialg_has_init = true;\r
+        return true;\r
+    }\r
+    //log_printf("frame_count =  %d  \n",frame_number);        \r
+//    uint8_t ppg_raw[13];\r
+//    float MEMS_Data[3]={0,0,0};\r
+    uint32_t time_s  = 0 ;\r
+    uint32_t time_e  = 0 ;\r
+    uint32_t time_diff= 0 ;\r
+\r
+//       // PxiAlg_Process(ppg_raw, MEMS_Data);\r
+//    time_s = pxi_get_tick_count();\r
+//    ret_value = PxiAlg_Entrance(pxialg_data); \r
+//    time_e = pxi_get_tick_count();         \r
+//    \r
+//    time_diff=time_e-time_s;\r
+//    LOG_PRINT("hr process-time = %d \n",time_diff);\r
+\r
+//    //if( ret_value == FLAG_DATA_READY) \r
+//    if(PxiAlg_GetHrUpdateFlag())\r
+//    {\r
+//        PxiAlg_HrGet(&myHR);\r
+//        ready_flag = PxiAlg_GetReadyFlag();\r
+//        PxiAlg_GetSigGrade(&hr_grader);      \r
+//    }\r
+\r
+    alg_count  = alg_count + _state.pxialg_data.nf_ppg_per_channel ;\r
+    myHR = hr_inupt_info ;\r
+\r
+    \r
+\r
+    if(pxialg_data->nf_ppg_channel==6)\r
+    {\r
+        for(i = 0 ; i<_state.pxialg_data.nf_ppg_per_channel;i++)\r
+        {\r
+            ppg_data_buf[4*i]  =pxialg_data->ppg_data[6*i+2];\r
+            ppg_data_buf[4*i+1]=pxialg_data->ppg_data[6*i+3];\r
+            ppg_data_buf[4*i+2]=pxialg_data->ppg_data[6*i+4];\r
+            ppg_data_buf[4*i+3]=pxialg_data->ppg_data[6*i+5];\r
+        }\r
+        SpO2_SetHrValue(myHR);\r
+        SpO2_SetMems((SpO2_mems_t*)pxialg_data->mems_data, pxialg_data->nf_mems);\r
+        time_s = pxi_get_tick_count();\r
+        ret_value = SpO2_Process(1, 4, ppg_data_buf, pxialg_data->nf_ppg_per_channel,pxialg_data->time);\r
+        time_e = pxi_get_tick_count();\r
+        time_diff=time_e-time_s;\r
+        LOG_PRINT("spo2 process-time = %d \n",time_diff);\r
+    \r
+\r
+    }else if(pxialg_data->nf_ppg_channel==4)\r
+    {\r
+    SpO2_SetHrValue(myHR);\r
+    SpO2_SetMems((SpO2_mems_t*)pxialg_data->mems_data, pxialg_data->nf_mems);\r
+    time_s = pxi_get_tick_count();\r
+    ret_value = SpO2_Process(1, pxialg_data->nf_ppg_channel, pxialg_data->ppg_data, pxialg_data->nf_ppg_per_channel,pxialg_data->time );\r
+\r
+    time_e = pxi_get_tick_count();\r
+    time_diff=time_e-time_s;\r
+    }\r
+    \r
+\r
+   \r
+    LOG_PRINT("spo2 process-time = %d \n",time_diff);\r
+    SpO2_GetSpO2(&Opt_SpO2);\r
+\r
+    spo2_ret = (uint8_t)Opt_SpO2;\r
+    \r
+    Opt_falg=SpO2_GetFlagOptimalSpO2Info();\r
+\r
+   \r
+    SpO2_info_t    _spo2_detect_item;\r
+\r
+    // CH1  \r
+    SpO2_GetInfo_ByIndex(&_spo2_detect_item,0);\r
+    ch1_spo2       =_spo2_detect_item.SpO2;\r
+    ch1_correlation=_spo2_detect_item.Noise;\r
+    ch1_trust_flag =_spo2_detect_item.Output[3];\r
+    ch1_no_value_reason=_spo2_detect_item.Output[4];\r
+    ch1_ratio=_spo2_detect_item.R_IR_Ratio;\r
+    SpO2_GetPeriodicityByCh(0, &ch1_periodocity);\r
+\r
+\r
+    //  CH2   \r
+    SpO2_GetInfo_ByIndex(&_spo2_detect_item,1);\r
+    ch2_spo2       =_spo2_detect_item.SpO2;\r
+    ch2_correlation=_spo2_detect_item.Noise;\r
+    ch2_trust_flag =_spo2_detect_item.Output[3];\r
+    ch2_no_value_reason=_spo2_detect_item.Output[4];\r
+    ch2_ratio     = _spo2_detect_item.R_IR_Ratio;\r
+    SpO2_GetPeriodicityByCh(1, &ch2_periodocity);\r
+\r
+    // CH3   \r
+    SpO2_GetInfo_ByIndex(&_spo2_detect_item,2);\r
+    ch3_spo2       =_spo2_detect_item.SpO2;\r
+    ch3_correlation=_spo2_detect_item.Noise;\r
+    ch3_trust_flag =_spo2_detect_item.Output[3];\r
+    ch3_no_value_reason=_spo2_detect_item.Output[4];\r
+    ch3_ratio=_spo2_detect_item.R_IR_Ratio;\r
+    SpO2_GetPeriodicityByCh(2, &ch3_periodocity);\r
+    \r
+    MEMS_RMS  =_spo2_detect_item.RMS;\r
+    MEMS_Mean_X=_spo2_detect_item.xyz_mean[0];\r
+    MEMS_Mean_Y=_spo2_detect_item.xyz_mean[1];\r
+    MEMS_Mean_Z=_spo2_detect_item.xyz_mean[2];\r
+    uint8_t update_flag = 0 ;    \r
+    if( ret_value == 0  && (alg_count>=25) )\r
+    {        \r
+        update_flag = 1 ;\r
+        alg_count = alg_count -25;\r
+        \r
+        LOG_PRINT("myHR = "LOG_FLOAT_MARKER" ",LOG_FLOAT(myHR));\r
+        LOG_PRINT(",grade = "LOG_FLOAT_MARKER" ",LOG_FLOAT(hr_grader));\r
+        \r
+        LOG_PRINT(",CH1_spo2 = "LOG_FLOAT_MARKER" ",LOG_FLOAT(ch1_spo2));\r
+        LOG_PRINT(",CH1_trust_flag = "LOG_FLOAT_MARKER" ",LOG_FLOAT(ch1_trust_flag));\r
+        LOG_PRINT(",CH1_correlation = "LOG_FLOAT_MARKER" ",LOG_FLOAT(ch1_correlation));\r
+        LOG_PRINT(",CH1_ratio = "LOG_FLOAT_MARKER" ",LOG_FLOAT(ch1_ratio));\r
+        LOG_PRINT(",CH1_perio = "LOG_FLOAT_MARKER" ",LOG_FLOAT(ch1_periodocity));\r
+         \r
+        LOG_PRINT(",CH2_spo2 = "LOG_FLOAT_MARKER" ",LOG_FLOAT(ch2_spo2));\r
+        LOG_PRINT(",CH2_trust_flag = "LOG_FLOAT_MARKER" ",LOG_FLOAT(ch2_trust_flag));\r
+        LOG_PRINT(",CH2_correlation = "LOG_FLOAT_MARKER" ",LOG_FLOAT(ch2_correlation));\r
+        LOG_PRINT(",CH2_ratio = "LOG_FLOAT_MARKER" ",LOG_FLOAT(ch2_ratio));\r
+        LOG_PRINT(",CH2_perio = "LOG_FLOAT_MARKER" ",LOG_FLOAT(ch2_periodocity));\r
+        \r
+        LOG_PRINT(",CH3_spo2 = "LOG_FLOAT_MARKER" ",LOG_FLOAT(ch3_spo2));\r
+        LOG_PRINT(",CH3_trust_flag = "LOG_FLOAT_MARKER" ",LOG_FLOAT(ch3_trust_flag));\r
+        LOG_PRINT(",CH3_correlation = "LOG_FLOAT_MARKER" ",LOG_FLOAT(ch3_correlation));\r
+        LOG_PRINT(",CH3_ratio = "LOG_FLOAT_MARKER" ",LOG_FLOAT(ch3_ratio));\r
+        LOG_PRINT(",CH3_perio = "LOG_FLOAT_MARKER" ",LOG_FLOAT(ch3_periodocity));\r
+        \r
+       \r
+        LOG_PRINT(",MEMS_RMS = "LOG_FLOAT_MARKER" ",LOG_FLOAT(MEMS_RMS));\r
+        LOG_PRINT(",Optimize_spo2 = "LOG_FLOAT_MARKER" ",LOG_FLOAT(Opt_SpO2));\r
+        LOG_PRINT(",Optimize_flag =  %d \n", Opt_falg);\r
+            \r
+        \r
+                \r
+         \r
+    }\r
+    else\r
+    {\r
+   \r
+        switch (ret_value)\r
+        {\r
+            case SPO2_MSG_ALG_NOT_OPEN:\r
+                 //debug_printf("Algorithm is not initialized. \n");\r
+            break;\r
+                            \r
+            case SPO2_MSG_ALG_REOPEN:\r
+                 //debug_printf("Algorithm is re initialized. \n");\r
+            break;\r
+                            \r
+            case SPO2_MSG_ALG_NOT_SUPPORT:\r
+                 //debug_printf("Algorithm is not support. \n");\r
+            break;\r
+                            \r
+            default:\r
+                 //debug_printf("Algorithm unhandle error = %d \n", ret_value);\r
+            break;\r
+        }\r
+     }    \r
+   \r
+#endif\r
+    return true;\r
+}\r
+\r
+\r
+\r
+\r
+\r
+void spo2_algorithm_close(void)\r
+{\r
+ #if defined(ENABLE_PXI_ALG_SPO2)\r
+    if (_state.pxialg_has_init)\r
+    {\r
+        _state.pxialg_has_init = false;\r
+        need_log_header = true;\r
+        _state.pxialg_data.frame_count=0;\r
+        SpO2_Close();\r
+//        PxiAlg_Close();\r
+        free(_state.pxialg_buffer_spo2);\r
+        free(_state.pxialg_buffer_hr);\r
+        alg_count = 0 ;\r
+        LOG_PRINT("spo2_algorithm_close\n");\r
+\r
+    }\r
+#endif // ENABLE_PXI_ALG_SPO2\r
+}   \r
+\r
+void spo2_algorithm_init(void)\r
+{\r
+    #if defined(ENABLE_PXI_ALG_SPO2)\r
+    \r
+    memset(&_state, 0, sizeof(_state));\r
+    _state.last_report_time = pxi_get_tick_count();\r
+    LOG_PRINT("_state.last_report_time = %d \n", _state.last_report_time);\r
+    SpO2_Close();\r
+    //PxiAlg_Close();\r
+    free(_state.pxialg_buffer_spo2);\r
+    free(_state.pxialg_buffer_hr);\r
+    alg_count = 0 ;\r
+    _state.pxialg_data.frame_count=0;\r
+    need_log_header = true;\r
+#endif // ENABLE_PXI_ALG_SPO2\r
+}\r
+\r
+\r
+uint8_t pah_831x_alg_get_spo2_result(void)\r
+{\r
+    return spo2_ret;\r
+}
\ No newline at end of file
diff --git a/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/SPO2/V587/pah_spo2_alg.h b/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/SPO2/V587/pah_spo2_alg.h
new file mode 100644 (file)
index 0000000..23bc524
--- /dev/null
@@ -0,0 +1,58 @@
+/*\r
+ * @Author: penglei 1624952103@qq.com\r
+ * @Date: 2025-12-25 09:34:32\r
+ * @LastEditors: penglei 1624952103@qq.com\r
+ * @LastEditTime: 2025-12-25 16:56:08\r
+ * @FilePath: /FD230/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/SPO2/V587/pah_spo2_alg.h\r
+ * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE\r
+ */\r
+/*==============================================================================\r
+* Edit History\r
+* \r
+* This section contains comments describing changes made to the module. Notice\r
+* that changes are listed in reverse chronological order. Please use ISO format\r
+* for dates.\r
+* \r
+* when       who       what, where, why\r
+* ---------- ---       -----------------------------------------------------------\r
+* 2016-04-29 bell      Initial revision.\r
+==============================================================================*/\r
+\r
+#ifndef __pah_spo2_alg_h__\r
+#define __pah_spo2_alg_h__\r
+\r
+\r
+#include <stdbool.h>\r
+#include <stdint.h>\r
+#include <string.h>\r
+\r
+\r
+\r
+\r
+bool  report_fifo_data_spo2(\r
+uint32_t ppg_timestamp,     \r
+uint32_t time_period, \r
+uint32_t *ppg_data,\r
+uint8_t *dac_data,\r
+uint32_t ppg_size,\r
+uint32_t ch_num,\r
+int16_t *acc_data,\r
+uint8_t acc_size, \r
+uint8_t *got_time_out, \r
+uint8_t is_touched ,\r
+float hr_inupt,\r
+uint8_t log_data_en \r
+);\r
+\r
+\r
+\r
+\r
+\r
+\r
+// void spo2_algorithm_calculate_run(void);\r
+void spo2_algorithm_init(void);\r
+void spo2_algorithm_close(void);\r
+uint8_t pah_831x_alg_get_spo2_result(void);\r
+\r
+#endif  // header guard\r
+\r
diff --git a/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/SPO2/V587/pxialg_spo2.h b/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/SPO2/V587/pxialg_spo2.h
new file mode 100644 (file)
index 0000000..df508d5
--- /dev/null
@@ -0,0 +1,160 @@
+#ifndef __PXIALG_SPO2_H__\r
+#define __PXIALG_SPO2_H__\r
+\r
+\r
+#include <stdint.h>\r
+\r
+\r
+#if defined(WIN32) && !defined(PXIALG_STATIC_LIB)\r
+#   ifdef PXIALG_EXPORTS\r
+#       define PXIALG_API   __declspec(dllexport)\r
+#   else\r
+#       define PXIALG_API   __declspec(dllimport)\r
+#   endif\r
+#else\r
+#   define PXIALG_API\r
+#endif // WIN32\r
+\r
+#pragma pack(1)\r
+typedef struct SpO2_mems {\r
+       int16_t data[3];\r
+} SpO2_mems_t;\r
+\r
+typedef struct SpO2_info {\r
+       float IR_DC;\r
+       float R_DC;\r
+       float G_DC;\r
+       float IR_AC;\r
+       float R_AC;\r
+       float G_AC;\r
+       float R_IR_Ratio;\r
+       float R_G_Ratio;\r
+       float G_IR_Ratio;\r
+       float Noise;\r
+       float SpO2_ref;\r
+       float PI;\r
+       float PVI;\r
+       float RMS;\r
+       float MEMS;\r
+       float Output[5];\r
+       float xyz_mean[3];\r
+       float SpO2;\r
+} SpO2_info_t;\r
+#pragma pack()\r
+\r
+typedef enum {\r
+       SPO2_MSG_SUCCESS = 0,\r
+       SPO2_MSG_ALG_NOT_OPEN,\r
+       SPO2_MSG_ALG_REOPEN,\r
+       SPO2_MSG_ALG_NOT_SUPPORT,\r
+    SPO2_MSG_INVALID_ARGUMENT,\r
+       SPO2_MSG_MOVING_SPO2_READY = 0x100,\r
+       SPO2_MSG_MOVING_SPO2_NOT_READY,\r
+       SPO2_MSG_MOVING_SPO2_STOP,\r
+}spo2_msg_code_t;\r
+\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif // __cplusplus\r
+\r
+\r
+PXIALG_API uint32_t SpO2_OpenSize(void);\r
+PXIALG_API int SpO2_Open(void *mem);\r
+PXIALG_API int SpO2_Close(void);\r
+PXIALG_API int SpO2_GetSpO2(float *spo2);\r
+PXIALG_API int SpO2_GetReadyFlag(uint8_t *ready_flag);\r
+PXIALG_API int SpO2_GetPeriodicity(float *periodicity);\r
+PXIALG_API int SpO2_GetPeriodicityByCh(int ch, float* periodicity);\r
+PXIALG_API int SpO2_Version(void);\r
+PXIALG_API int SpO2_Process(int touch_flag, int total_channel, int *input, int samples_per_ch, float time_in);\r
+PXIALG_API int SpO2_ProcessD(int touch_flag, int total_channel, int *input, int samples_per_ch, float time_in);\r
+PXIALG_API int SpO2_GetFilteredData(int touch_flag, int total_channel, int expo_R,  int expo_IR, int DAC_R, int DAC_IR, float **filter_R, float **filter_IR, int *FilteredDataLength);\r
+\r
+//parameters\r
+PXIALG_API int SpO2_SetIIRFilterRatio(float IIRFilterRatio);   //0 ~ 0.5. bigger value more smooth.\r
+PXIALG_API int SpO2_SetMotionDetectionLevel(float level);\r
+PXIALG_API int SpO2_SetInputModelScale(float scale);\r
+PXIALG_API int SpO2_SetInputCorrelationTh(float th);\r
+PXIALG_API int SpO2_SetInputRatioLow(float ratio);\r
+PXIALG_API int SpO2_SetInputCoefLow0(float coef);\r
+PXIALG_API int SpO2_SetInputCoefLow1(float coef);\r
+PXIALG_API int SpO2_SetInputCoefLow2(float coef);\r
+PXIALG_API int SpO2_SetInputCoefLow3(float coef);\r
+PXIALG_API int SpO2_SetInputCoefMid0(float coef);\r
+PXIALG_API int SpO2_SetInputCoefMid1(float coef);\r
+PXIALG_API int SpO2_SetInputCoefMid2(float coef);\r
+PXIALG_API int SpO2_SetInputCoefMid3(float coef);\r
+PXIALG_API int SpO2_SetInputCoefHigh0(float coef);\r
+PXIALG_API int SpO2_SetInputCoefHigh1(float coef);\r
+PXIALG_API int SpO2_SetInputCoefHigh2(float coef);\r
+PXIALG_API int SpO2_SetInputCoefHigh3(float coef);\r
+PXIALG_API int SpO2_SetInputRatioHighBound(float bound);\r
+PXIALG_API int SpO2_SetInputRatioLowBound(float bound);\r
+PXIALG_API int SpO2_SetInputFlagCheckHr(int value);\r
+PXIALG_API int SpO2_SetOutputHighBound(float value);\r
+PXIALG_API int SpO2_SetOutputLowBound(float value);\r
+PXIALG_API int SpO2_Set_Init_Low_SpO2_Constrain(int value);\r
+PXIALG_API int SpO2_Set_Init_Low_SpO2_Th(float value);\r
+\r
+PXIALG_API int SpO2_Set_Init_Low_SpO2_Check_Sec(int value);\r
+\r
+PXIALG_API int SpO2_Set_Motion_Rms_Th(float value);\r
+PXIALG_API int SpO2_Set_Motion_Rms_Th2(float value);\r
+\r
+PXIALG_API int SpO2_Set_Correlation_Th2_Count(int value);\r
+PXIALG_API int SpO2_Set_Input_Correlation_Th2(float value);\r
+\r
+PXIALG_API int SpO2_Set_Flag_Hold_Breathe_Mode(char value);\r
+\r
+PXIALG_API int SpO2_Set_Keep_Init_SpO2_Bound(float value);\r
+PXIALG_API int SpO2_Set_Keep_Init_SpO2_Count_Th(int value);\r
+PXIALG_API int SpO2_Set_SpO2_Bias_Value(float value);\r
+PXIALG_API int SpO2_Set_SpO2_Outlier_Smooth_Coef(float value);\r
+PXIALG_API int SpO2_Set_SpO2_Decrease_Coef(float value);\r
+\r
+PXIALG_API int SpO2_Set_Motion_MEMS_Th(float value);\r
+\r
+PXIALG_API int SpO2_Set_T1(float value);\r
+PXIALG_API int SpO2_Set_T2(float value);\r
+PXIALG_API int SpO2_Set_T3(float value);\r
+PXIALG_API int SpO2_Set_T4(float value);\r
+PXIALG_API int SpO2_Set_T5(float value);\r
+PXIALG_API int SpO2_Set_Spo2_Force_Output_Second(int value);\r
+\r
+PXIALG_API int SpO2_Set_Signal_Periodicity_Th(float value);\r
+PXIALG_API int Spo2_Set_SpO2_First_Smooth_Th(float value);\r
+PXIALG_API int Spo2_Set_SpO2_First_Smooth_Sec(int value);\r
+PXIALG_API int Spo2_Set_SpO2_Correlation_Smooth_Th(float value);\r
+//set HR\r
+PXIALG_API int SpO2_SetHrValue(int value);\r
+\r
+//get SPO2_Info\r
+PXIALG_API int SpO2_GetInfo(SpO2_info_t *info);\r
+PXIALG_API int SpO2_GetInfo_ByIndex(SpO2_info_t* p, int index);\r
+\r
+PXIALG_API int SpO2_SetMems(SpO2_mems_t *mems, int samples);\r
+\r
+PXIALG_API int SpO2_Set_Update_Sec(int spo2_update_sec);\r
+\r
+PXIALG_API int SpO2_SetMemsRmsThr(float mems_rms_thr);\r
+PXIALG_API int SpO2_CalAvgSpO2(float mySpO2, float trust_flag, float mems_rms, float *result); //called every one second\r
+PXIALG_API int SpO2_SetSkipDataLen(int len);\r
+PXIALG_API int SpO2_SetChMapping(int8_t *alg_ch, int8_t ch_nr);\r
+\r
+PXIALG_API int SpO2_Set_Init_Low_SpO2_Check_Sec(int value);\r
+\r
+PXIALG_API int Spo2_Set_SpO2_First_Smooth_Th(float value);\r
+PXIALG_API int Spo2_Set_SpO2_First_Smooth_Sec(int value);\r
+PXIALG_API int Spo2_Set_SpO2_Correlation_Smooth_Th(float value);\r
+\r
+PXIALG_API int Spo2_Set_Force_Output_Value(float value);\r
+PXIALG_API int Spo2_Set_Force_Output_Value2(float value);\r
+\r
+PXIALG_API int SpO2_GetFlagOptimalSpO2Info(void);\r
+#ifdef __cplusplus\r
+}\r
+#endif // __cplusplus\r
+\r
+\r
+#endif\r
diff --git a/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/SPO2/V587/test_library_SPO2_V587.c b/code/sdk/zhihui/drivers/ppg/pah831x/PXI_ALG/SPO2/V587/test_library_SPO2_V587.c
new file mode 100644 (file)
index 0000000..28b91f4
--- /dev/null
@@ -0,0 +1,796 @@
+// algorithm\r
+#include "pxialg_spo2.h"\r
+// HR algorithm\r
+#include "pxialg.h"\r
+// testpattern\r
+#include "pah831x_testpattern_V587_1.h"\r
+// platform\r
+#include <stdlib.h>\r
+\r
+\r
+#include "pah831x_comm.h"\r
+#include <math.h>  \r
+#include "nrf_delay.h"\r
+#define array_szie(arr) (sizeof(arr) / sizeof(arr[0]))\r
+\r
+//#define  SAMPLES_PER_CHANNEL 25\r
+#define  TOTAL_CHANNEL 4\r
+\r
+#define   log_printf ALG_PRINT\r
+\r
+\r
+\r
+static SpO2_mems_t  mems_data_raw[210];        //add item\r
+\r
+typedef struct\r
+{\r
+    void *pBuffer;\r
+    void *hr_pBuffer;\r
+} pxialg_spo2_state;\r
+\r
+\r
+\r
+void spo2_log_printf(char s, float f)\r
+{\r
+       log_printf("%s= "LOG_FLOAT_MARKER"   \n",s, LOG_FLOAT(f));\r
+       \r
+}\r
+\r
+\r
+\r
+\r
+\r
+       \r
+void test_library_SPO2(void)\r
+{\r
+       int i               = 0;\r
+       int j               = 0;\r
+       int32_t version     = 0;\r
+       uint8_t ReadyFlag   = 0;\r
+       int     buffer_size = 0;\r
+       void *pBuffer       = NULL;\r
+       int     motion_flag = 0;\r
+       float   motion_thr  = 0.0f;\r
+       \r
+         \r
+    uint32_t         effective        = 0;           //add item for V560\r
+   \r
+   \r
+   \r
+    uint8_t          reset_flag       = 0;          // add item for Flow\r
+    uint8_t          over_mems_flag   = 0;          // add item for Flow\r
+    uint8_t          time_out_flag    = 0;          // add item for Flow\r
+       \r
+       uint8_t          posture_falg     = 0;\r
+\r
+    \r
+    \r
+    // add for new flow\r
+    int              mems_1_flag      =0;\r
+    int              mems_2_flag      =0;\r
+    int              mems_3_flag      =0;\r
+    int              mems_4_flag      =0;\r
+    float            before_spo2      =0.0f; \r
+    int              drop_count       =0;\r
+    int              ascend_count     =0;\r
+    static int32_t   mems_1           =0;\r
+    static int32_t   mems_2           =0;\r
+    static int32_t   mems_3           =0;\r
+    static int32_t   mems_4           =0;\r
+    static uint32_t  count_index      =0;  \r
+    float            FirstSpO2        =0.0f; \r
+    float            Firsttime        =0.0f; \r
+    uint8_t          first_falg       =0;\r
+    #define          window           9\r
+    float            MEMS_data[window]={0};\r
+    \r
+    //int     time_s,time_e,time_c;\r
+       static pxialg_spo2_state    _spo2_state;\r
+       pah8series_data_t   pxialg_data;\r
+       \r
+       version     = SpO2_Version();\r
+       log_printf("SPO2_version =%d \n",version);\r
+       buffer_size = SpO2_OpenSize();\r
+    \r
+       log_printf("SPO2_size = %d  \n", buffer_size);\r
+       pBuffer = malloc(buffer_size);\r
+       \r
+\r
+       nrf_delay_ms(50);\r
+       if (!pBuffer)\r
+    {\r
+               log_printf("Out of memory. \n");\r
+               return;\r
+    }\r
+       nrf_delay_ms(50);\r
+    \r
+       if (SpO2_Open(pBuffer) != SPO2_MSG_SUCCESS)\r
+       {\r
+        log_printf("SpO2_Open() failed. \n");\r
+        free(pBuffer);\r
+        return;\r
+       }\r
+          //log_printf("pBuffer =%x \n",pBuffer);\r
+       \r
+    SpO2_SetInputRatioHighBound(98.0f);\r
+    SpO2_SetInputRatioLowBound(88.0f);\r
+    SpO2_SetInputModelScale(0.850000023841858f);\r
+\r
+    SpO2_SetInputCoefHigh0(-222421.515625f);\r
+    SpO2_SetInputCoefHigh1(6730.0947265625f);\r
+    SpO2_SetInputCoefHigh2(-67.8570251464844f);\r
+    SpO2_SetInputCoefHigh3(0.228081002831459f);\r
+\r
+    SpO2_SetInputCoefMid0(685.031494140625f);\r
+    SpO2_SetInputCoefMid1(-20.9844379425049f);\r
+    SpO2_SetInputCoefMid2(0.233719006180763f);\r
+    SpO2_SetInputCoefMid3(-0.000824999995529652f);\r
+\r
+    SpO2_SetInputCoefLow0(47.5770835876465f);\r
+    SpO2_SetInputCoefLow1(0.467613995075226f);\r
+    SpO2_SetInputCoefLow2(-0.00219999998807907f);\r
+    SpO2_SetInputCoefLow3(0.000020999999833293f);\r
+        \r
+    SpO2_SetIIRFilterRatio(0.5f);\r
+    SpO2_SetInputCorrelationTh(0.850000023841858f);\r
+    SpO2_SetInputRatioLow(0.05f);        \r
+\r
+    SpO2_SetInputFlagCheckHr(1);\r
+    SpO2_SetMotionDetectionLevel(2.0f);\r
+    SpO2_Set_Update_Sec(1);\r
+        \r
+    SpO2_Set_Init_Low_SpO2_Constrain(0.0);  \r
+    SpO2_SetOutputHighBound(100.0f);\r
+    SpO2_SetOutputLowBound(60.0f);\r
+                               \r
+    SpO2_Set_Keep_Init_SpO2_Bound(94.80f);    \r
+    SpO2_Set_Keep_Init_SpO2_Count_Th(15.0f);  \r
+    SpO2_Set_SpO2_Bias_Value(0.2f);           \r
+    SpO2_Set_SpO2_Outlier_Smooth_Coef(5.5f);  \r
+    SpO2_Set_SpO2_Decrease_Coef(0.5f);        \r
+    SpO2_SetSkipDataLen(25);\r
+\r
+    SpO2_Set_Flag_Hold_Breathe_Mode(0);\r
+    SpO2_Set_Input_Correlation_Th2(0.85000022411346f);\r
+    SpO2_Set_Correlation_Th2_Count(15);\r
+    SpO2_Set_Init_Low_SpO2_Th(94.5f);\r
+    SpO2_Set_Motion_Rms_Th(3000.0f);\r
+    SpO2_Set_Motion_Rms_Th2(1500.0f);\r
+    SpO2_Set_Motion_MEMS_Th(0.0f);\r
+    SpO2_Set_T1(0.85f);\r
+    SpO2_Set_Spo2_Force_Output_Second(30.0f);    \r
+   //SpO2_SetChMapping(alg_ch, 3); // Swap Channel\r
+    \r
+    Spo2_Set_Force_Output_Value(97.50f);  // Good Signal Force SpO2\r
+    Spo2_Set_Force_Output_Value2(95.00f); // Bad  Signal Force SpO2\r
+    \r
+    SpO2_Set_Init_Low_SpO2_Check_Sec(20);\r
+    Spo2_Set_SpO2_First_Smooth_Th(95.0f);\r
+    Spo2_Set_SpO2_First_Smooth_Sec(15);\r
+    Spo2_Set_SpO2_Correlation_Smooth_Th(0.85f);\r
+    SpO2_Set_Signal_Periodicity_Th(0.30f);\r
+\r
+    \r
+    \r
+    \r
+    \r
+       /// static  Hr\r
+       version = PxiAlg_Version();\r
+       log_printf("HR_Version = %d \r\n", version);            \r
+     \r
+       uint32_t Query_Mem_Size = PxiAlg_Query_Mem_Size();\r
+       log_printf("HR_Mem_Size = %d \r\n", Query_Mem_Size);\r
+               \r
+       _spo2_state.hr_pBuffer = malloc(Query_Mem_Size);\r
+                \r
+       PxiAlg_Open_Mem(_spo2_state.hr_pBuffer);\r
+\r
+                               \r
+       PxiAlg_SetQualityThreshold(0.35f); \r
+       PxiAlg_SetHRSmoothWeight(0.9f); \r
+       PxiAlg_SetProcWindow(5.0f, 5.0f); \r
+       PxiAlg_SetTimeoutLength(30.0f);\r
+       PxiAlg_SetMemsScale(0);               //MEMS 2/4/8/16G : 0/1/2/3\r
+       PxiAlg_SetSkipSampleNum(10); \r
+       PxiAlg_SetMemsScaleBase(1, 0);  //MEMS 2/4/8/16G : 0/1/2/3\r
+       PxiAlg_SetForceOutputLink(15, 90, 60, 1, 0.9f); \r
+       PxiAlg_SetNormalOutput(200, 40, 1); \r
+       PxiAlg_SetForceRipple(3, 1); \r
+       //PxiAlg_SetForceOutput(30, 120, 45);\r
+       //PxiAlg_SetForceOutputTime(10);\r
+       PxiAlg_SetPackage(2, 1);\r
+                \r
+\r
+//-----------------------------------------------//\r
+       //int32_t  index_count=0;\r
+       int32_t  alg_count=0;\r
+       //int32_t  data_buf_count = 0 ;\r
+       //int32_t  meme_buf_count = 0 ;\r
+       int32_t  mems_index_count = 0 ;\r
+       //int32_t  data_buf_time = 0 ;\r
+       //uint32_t ppg_time  = 0 ;\r
+    \r
+       log_printf("ARRAY_SIZE = %d\n",array_szie(PAH831x_rawdata_SPO2));\r
+//******************************************************************            \r
+       // PD1\r
+    float   pd1_spo2            = 0.0f;\r
+    float   pd1_correlation     = 0.0f;\r
+       float   pd1_trust_flag      = 0.0f;\r
+       uint8_t pd1_no_value_reason = 0   ;\r
+    float   pd1_ratio           = 0.0f;\r
+    float   pd1_periodocity     = 0.0f;\r
+    \r
+    \r
+    // PD2\r
+    float   pd2_spo2            = 0.0f;\r
+    float   pd2_correlation     = 0.0f;\r
+       float   pd2_trust_flag      = 0.0f;\r
+       uint8_t pd2_no_value_reason = 0   ;\r
+    float   pd2_ratio           = 0.0f;\r
+    float   pd2_periodocity     = 0.0f;\r
+    \r
+    // PD0\r
+    float   pd0_spo2            = 0.0f;\r
+    float   pd0_correlation     = 0.0f;\r
+       float   pd0_trust_flag      = 0.0f;\r
+       uint8_t pd0_no_value_reason = 0   ;\r
+    float   pd0_ratio           = 0.0f;\r
+    float   pd0_periodocity     = 0.0f;\r
+    \r
+    // PD3\r
+    float   pd3_spo2            = 0.0f;\r
+    float   pd3_correlation     = 0.0f;\r
+       float   pd3_trust_flag      = 0.0f;\r
+       uint8_t pd3_no_value_reason = 0   ;\r
+    float   pd3_ratio           = 0.0f;\r
+    float   pd3_periodocity     = 0.0f;\r
+      \r
+    float   Opt_SpO2   = 0   ;\r
+    int     Opt_falg   = 0   ;\r
+       float   MEMS_RMS   = 0.0f;\r
+       float   MEMS_Mean_X= 0.0f;\r
+       float   MEMS_Mean_Y= 0.0f;\r
+       float   MEMS_Mean_Z= 0.0f;\r
+       float   myHR       = 0.0f;\r
+       int     ret_value  = 0   ;\r
+       float   hr_grader  = 0.0f;\r
+       uint8_t ready_flag = 0   ;\r
+//*******************************************************************           \r
+                \r
+       nrf_delay_ms(10);\r
+                \r
+\r
+       for( i = 0 ; i <array_szie(PAH831x_rawdata_SPO2) ; i ++)\r
+       {\r
+                         \r
+               uint32_t  touch_flag         = PAH831x_rawdata_SPO2[i][0];                         \r
+               uint32_t  time               = duration_SPO2[i];                          \r
+               int       ppg_count_per_ch   = PAH831x_rawdata_SPO2[i][1];      \r
+               int       frame_number       = frame_SPO2[i]; \r
+               int       mems_number        = PAH831x_mems_SPO2[i][0];          \r
+               int32_t   RAW_DATA [110]       = {0}; \r
+                         \r
+        \r
+        //log_printf("RAW_DATA =\n");\r
+               for (j=0;j<ppg_count_per_ch; j++)\r
+               {\r
+            \r
+                       RAW_DATA[j] = PAH831x_rawdata_SPO2[i][j+2] ;\r
+//                     log_printf("%d , ", RAW_DATA[j]);\r
+\r
+               }\r
+                                \r
+\r
+               for( j = 0 ; j <(PAH831x_mems_SPO2[i][0]) ; j ++)\r
+               {\r
+                       mems_data_raw[j].data[0]=PAH831x_mems_SPO2[i][3*j+1];\r
+                       mems_data_raw[j].data[1]=PAH831x_mems_SPO2[i][3*j+2];\r
+                       mems_data_raw[j].data[2]=PAH831x_mems_SPO2[i][3*j+3]; \r
+                       \r
+               }\r
+                                \r
+                               \r
+\r
+               nrf_delay_ms(10);\r
+               pxialg_data.touch_flag         = touch_flag;\r
+               pxialg_data.time               = time;\r
+               pxialg_data.ppg_data           = (int32_t*)RAW_DATA;\r
+               pxialg_data.nf_ppg_channel     = NF_PPG_CHANNEL;\r
+               pxialg_data.nf_ppg_per_channel = ppg_count_per_ch/NF_PPG_CHANNEL;\r
+               pxialg_data.frame_count        = frame_number;\r
+               pxialg_data.nf_mems            = mems_number;\r
+               pxialg_data.mems_data          = (int16_t*)mems_data_raw;\r
+                                \r
+               //log_printf("frame_count =  %d  \n",frame_number);              \r
+ \r
+               ret_value = PxiAlg_Entrance(&pxialg_data); \r
+                                \r
+                                \r
+               alg_count  = alg_count + PAH831x_rawdata_SPO2[i][1]/NF_PPG_CHANNEL ;\r
+               nrf_delay_ms(10);\r
+                                \r
+               //if( ret_value == FLAG_DATA_READY) \r
+               if(PxiAlg_GetHrUpdateFlag())\r
+               {\r
+                       PxiAlg_HrGet(&myHR);\r
+                       ready_flag = PxiAlg_GetReadyFlag();\r
+                       PxiAlg_GetSigGrade(&hr_grader);\r
+//                     log_printf("myHR = "LOG_FLOAT_MARKER" ",LOG_FLOAT(myHR));\r
+//                     nrf_delay_ms(100);\r
+//          log_printf("myHR_opt = "LOG_FLOAT_MARKER" ",LOG_FLOAT(myHR_opt));\r
+//                     log_printf("grade = "LOG_FLOAT_MARKER"\n ",LOG_FLOAT(hr_grader));\r
+//                     nrf_delay_ms(100);\r
+               }\r
+                       //ready_flag = PxiAlg_GetReadyFlag();\r
+               //PxiAlg_GetSigGrade(&hr_grader);\r
+                \r
+               \r
+               nrf_delay_ms(50);\r
+               SpO2_SetHrValue(myHR);\r
+               SpO2_SetMems(mems_data_raw, pxialg_data.nf_mems);\r
+       uint32_t time_s = pxi_nrf_get_tick_count();\r
+//             ret_value = SpO2_Process(1, NF_PPG_CHANNEL, pxialg_data.ppg_data, pxialg_data.nf_ppg_per_channel);\r
+               ret_value = SpO2_Process(1, NF_PPG_CHANNEL, pxialg_data.ppg_data, pxialg_data.nf_ppg_per_channel,pxialg_data.time );\r
+\r
+         uint32_t time_e = pxi_nrf_get_tick_count();\r
+         uint32_t time_diff=time_e-time_s;\r
+//         log_printf("process-time = %d \n",time_diff);\r
+               SpO2_GetSpO2(&Opt_SpO2);\r
+        Opt_falg=SpO2_GetFlagOptimalSpO2Info();\r
+//             SpO2_GetReadyFlag(&ReadyFlag);\r
+        \r
+       \r
+               SpO2_info_t    _spo2_detect_item;\r
+\r
+        // CH1  \r
+        SpO2_GetInfo_ByIndex(&_spo2_detect_item,0);\r
+        pd1_spo2       =_spo2_detect_item.SpO2;\r
+               pd1_correlation=_spo2_detect_item.Noise;\r
+               pd1_trust_flag =_spo2_detect_item.Output[3];\r
+               pd1_no_value_reason=_spo2_detect_item.Output[4];\r
+        pd1_ratio=_spo2_detect_item.R_IR_Ratio;\r
+        SpO2_GetPeriodicityByCh(0, &pd1_periodocity);\r
+\r
+        //  CH2   \r
+        SpO2_GetInfo_ByIndex(&_spo2_detect_item,1);\r
+        pd2_spo2       =_spo2_detect_item.SpO2;\r
+               pd2_correlation=_spo2_detect_item.Noise;\r
+               pd2_trust_flag =_spo2_detect_item.Output[3];\r
+               pd2_no_value_reason=_spo2_detect_item.Output[4];\r
+        pd2_ratio     = _spo2_detect_item.R_IR_Ratio;\r
+        SpO2_GetPeriodicityByCh(1, &pd2_periodocity);\r
+    \r
+        // CH3   \r
+        SpO2_GetInfo_ByIndex(&_spo2_detect_item,2);\r
+        pd0_spo2       =_spo2_detect_item.SpO2;\r
+               pd0_correlation=_spo2_detect_item.Noise;\r
+               pd0_trust_flag =_spo2_detect_item.Output[3];\r
+               pd0_no_value_reason=_spo2_detect_item.Output[4];\r
+        pd0_ratio=_spo2_detect_item.R_IR_Ratio;\r
+        SpO2_GetPeriodicityByCh(2, &pd0_periodocity);\r
+    \r
+//        // PD3    \r
+//        SpO2_GetInfo_ByIndex(&_spo2_detect_item,3);\r
+//        pd3_spo2       =_spo2_detect_item.SpO2;\r
+//             pd3_correlation=_spo2_detect_item.Noise;\r
+//             pd3_trust_flag =_spo2_detect_item.Output[3];\r
+//             pd3_no_value_reason=_spo2_detect_item.Output[4];\r
+//        pd3_ratio=_spo2_detect_item.R_IR_Ratio;\r
+        \r
+        // Optimize_spo2\r
+        //SpO2_GetSpO2(&Opt_SpO2);\r
+        \r
+               MEMS_RMS  =_spo2_detect_item.RMS;\r
+               MEMS_Mean_X=_spo2_detect_item.xyz_mean[0];\r
+               MEMS_Mean_Y=_spo2_detect_item.xyz_mean[1];\r
+               MEMS_Mean_Z=_spo2_detect_item.xyz_mean[2];\r
+         \r
+\r
+//             if(MEMS_RMS>motion_thr)\r
+//                      motion_flag=1;\r
+               \r
+               \r
+//             if(MEMS_Mean_Z<4000  && count_time>0)\r
+//                      posture_falg=1;\r
+//             else\r
+//                      posture_falg=0;\r
+                                \r
+               nrf_delay_ms(10);\r
+               if( ret_value == 0  && (alg_count>=25) )\r
+               {        \r
+                               alg_count = alg_count -25;\r
+                               if (ReadyFlag > 0)\r
+                               {\r
+                                  log_printf("Ready = %d,", ReadyFlag);\r
+////                                   nrf_delay_ms(10);\r
+                                  log_printf("myHR = "LOG_FLOAT_MARKER" ",LOG_FLOAT(myHR));\r
+////                                   //log_printf("myHR_opt = "LOG_FLOAT_MARKER" ",LOG_FLOAT(myHR_opt));\r
+////                                   nrf_delay_ms(10);\r
+                                  log_printf(",grade = "LOG_FLOAT_MARKER" ",LOG_FLOAT(hr_grader));\r
+                                  nrf_delay_ms(10);\r
+////                    \r
+                    log_printf(",CH1_spo2 = "LOG_FLOAT_MARKER" ",LOG_FLOAT(pd1_spo2));\r
+                                       nrf_delay_ms(10);\r
+                    log_printf(",CH1_trust_flag = "LOG_FLOAT_MARKER" ",LOG_FLOAT(pd1_trust_flag));\r
+                    nrf_delay_ms(10);\r
+                    log_printf(",CH1_correlation = "LOG_FLOAT_MARKER" ",LOG_FLOAT(pd1_correlation));\r
+                    nrf_delay_ms(10);\r
+                    log_printf(",CH1_ratio = "LOG_FLOAT_MARKER" ",LOG_FLOAT(pd1_ratio));\r
+                    nrf_delay_ms(10);\r
+                    log_printf(",CH1_perio = "LOG_FLOAT_MARKER" ",LOG_FLOAT(pd1_periodocity));\r
+                    \r
+                    \r
+                    \r
+                    \r
+                    \r
+                    log_printf(",CH2_spo2 = "LOG_FLOAT_MARKER" ",LOG_FLOAT(pd2_spo2));\r
+                                       nrf_delay_ms(10);\r
+                    log_printf(",CH2_trust_flag = "LOG_FLOAT_MARKER" ",LOG_FLOAT(pd2_trust_flag));\r
+                    nrf_delay_ms(10);\r
+                    log_printf(",CH2_correlation = "LOG_FLOAT_MARKER" ",LOG_FLOAT(pd2_correlation));\r
+                    nrf_delay_ms(10);\r
+                    log_printf(",CH2_ratio = "LOG_FLOAT_MARKER" ",LOG_FLOAT(pd2_ratio));\r
+                    nrf_delay_ms(10);\r
+                    log_printf(",CH2_perio = "LOG_FLOAT_MARKER" ",LOG_FLOAT(pd2_periodocity));\r
+                    \r
+                    \r
+       \r
+                    \r
+                    log_printf(",CH3_spo2 = "LOG_FLOAT_MARKER" ",LOG_FLOAT(pd0_spo2));\r
+                                       nrf_delay_ms(10);\r
+                    log_printf(",CH3_trust_flag = "LOG_FLOAT_MARKER" ",LOG_FLOAT(pd0_trust_flag));\r
+                    nrf_delay_ms(10);\r
+                    log_printf(",CH3_correlation = "LOG_FLOAT_MARKER" ",LOG_FLOAT(pd0_correlation));\r
+                    nrf_delay_ms(10);\r
+                    log_printf(",CH3_ratio = "LOG_FLOAT_MARKER" ",LOG_FLOAT(pd0_ratio));\r
+                    nrf_delay_ms(10);\r
+                    log_printf(",CH3_perio = "LOG_FLOAT_MARKER" ",LOG_FLOAT(pd0_periodocity));\r
+\r
+                    \r
+////                    \r
+////                    \r
+//////                    \r
+////                    log_printf(",pd21_ir2_r2_spo2 = "LOG_FLOAT_MARKER" ",LOG_FLOAT(pd3_spo2));\r
+////                                   nrf_delay_ms(10);\r
+////                    log_printf(",pd21_ir2_r2_trust_flag = "LOG_FLOAT_MARKER" ",LOG_FLOAT(pd3_trust_flag));\r
+////                    nrf_delay_ms(10);\r
+////                    log_printf(",pd21_ir2_r2_correlation = "LOG_FLOAT_MARKER" ",LOG_FLOAT(pd3_correlation));\r
+////                    nrf_delay_ms(10);\r
+////                    log_printf(",pd21_ir2_r2_ratio = "LOG_FLOAT_MARKER" ",LOG_FLOAT(pd3_ratio));\r
+////                    nrf_delay_ms(10);\r
+                    \r
+                    \r
+//                    log_printf(",MEMS_RMS    = "LOG_FLOAT_MARKER"  ",LOG_FLOAT(MEMS_RMS));\r
+//                                     nrf_delay_ms(10);\r
+\r
+                                       log_printf(",Optimize_spo2 = "LOG_FLOAT_MARKER"  ",LOG_FLOAT(Opt_SpO2));\r
+                    nrf_delay_ms(10);\r
+                    log_printf(",Optimize_flag =  %d \n", Opt_falg);\r
+\r
+                                       nrf_delay_ms(10);\r
+                    \r
+       \r
+//                                     log_printf(",Motion_falg  = %d \n" , motion_flag);\r
+//                                     nrf_delay_ms(50);\r
+//                                     log_printf(",Posture_falg  = %d " , posture_falg);\r
+//                                      nrf_delay_ms(50);\r
+\r
+/*                                     \r
+                                       if(no_value_reason==0)\r
+                                       {\r
+                                               log_printf(", Normal_Signal \n");\r
+                                       }\r
+                                       else if(no_value_reason==1)\r
+                                       {\r
+                                               log_printf(", Signal contain noise\n");\r
+                                       }\r
+                                       else if(no_value_reason==2)\r
+                                       {\r
+                                               log_printf(", No Detect PPG waveform\n");\r
+                                       }\r
+                                       else if(no_value_reason==3)\r
+                                       {\r
+                                               log_printf(", Open constrin mode\n");\r
+\r
+                                       }               \r
+                                       else if(no_value_reason==4)\r
+                                       {\r
+                                               log_printf(", Serious Motion\n");\r
+                                       }                                               \r
+                                       //log_printf(",MEMX_X  ="  LOG_FLOAT_MARKER"   " , LOG_FLOAT(MEMS_Mean_X));\r
+                                       //nrf_delay_ms(50);\r
+                                       //log_printf(",MEMX_Y  ="  LOG_FLOAT_MARKER"   " , LOG_FLOAT(MEMS_Mean_Y));\r
+                                       //nrf_delay_ms(50);\r
+                                       //log_printf(",MEMX_Z  ="  LOG_FLOAT_MARKER"   " , LOG_FLOAT(MEMS_Mean_Z));\r
+\r
+*/     \r
+                                       //log_printf("  ,count_time = %d ", count_time);\r
+                               }\r
+                               else\r
+                               {\r
+                                       \r
+                    log_printf("Ready = %d,", ReadyFlag);\r
+////                                   nrf_delay_ms(10);\r
+                               log_printf("myHR = "LOG_FLOAT_MARKER" ",LOG_FLOAT(myHR));\r
+////                                   //log_printf("myHR_opt = "LOG_FLOAT_MARKER" ",LOG_FLOAT(myHR_opt));\r
+////                                   nrf_delay_ms(10);\r
+                                       log_printf(",grade = "LOG_FLOAT_MARKER" ",LOG_FLOAT(hr_grader));\r
+////                                   nrf_delay_ms(10);\r
+////                    \r
+                    log_printf(",CH1_spo2 = "LOG_FLOAT_MARKER" ",LOG_FLOAT(pd1_spo2));\r
+                                       nrf_delay_ms(10);\r
+                    log_printf(",CH1_trust_flag = "LOG_FLOAT_MARKER" ",LOG_FLOAT(pd1_trust_flag));\r
+                    nrf_delay_ms(10);\r
+                    log_printf(",CH1_correlation = "LOG_FLOAT_MARKER" ",LOG_FLOAT(pd1_correlation));\r
+                    nrf_delay_ms(10);\r
+                    log_printf(",CH1_ratio = "LOG_FLOAT_MARKER" ",LOG_FLOAT(pd1_ratio));\r
+                    nrf_delay_ms(10);\r
+                    log_printf(",CH1_perio = "LOG_FLOAT_MARKER" ",LOG_FLOAT(pd1_periodocity));\r
+                    \r
+                    \r
+                    \r
+                    \r
+                    \r
+                    \r
+                    log_printf(",CH2_spo2 = "LOG_FLOAT_MARKER" ",LOG_FLOAT(pd2_spo2));\r
+                                       nrf_delay_ms(10);\r
+                    log_printf(",CH2_trust_flag = "LOG_FLOAT_MARKER" ",LOG_FLOAT(pd2_trust_flag));\r
+                    nrf_delay_ms(10);\r
+                    log_printf(",CH2_correlation = "LOG_FLOAT_MARKER" ",LOG_FLOAT(pd2_correlation));\r
+                    nrf_delay_ms(10);\r
+                    log_printf(",CH2_ratio = "LOG_FLOAT_MARKER" ",LOG_FLOAT(pd2_ratio));\r
+                    nrf_delay_ms(10);\r
+                    log_printf(",CH2_perio = "LOG_FLOAT_MARKER" ",LOG_FLOAT(pd2_periodocity));\r
+                    \r
+                    \r
+                    \r
+       \r
+                    \r
+                    log_printf(",CH3_spo2 = "LOG_FLOAT_MARKER" ",LOG_FLOAT(pd0_spo2));\r
+                                       nrf_delay_ms(10);\r
+                    log_printf(",CH3_trust_flag = "LOG_FLOAT_MARKER" ",LOG_FLOAT(pd0_trust_flag));\r
+                    nrf_delay_ms(10);\r
+                    log_printf(",CH3_correlation = "LOG_FLOAT_MARKER" ",LOG_FLOAT(pd0_correlation));\r
+                    nrf_delay_ms(10);\r
+                    log_printf(",CH3_ratio = "LOG_FLOAT_MARKER" ",LOG_FLOAT(pd0_ratio));\r
+                    nrf_delay_ms(10);\r
+                    log_printf(",CH3_perio = "LOG_FLOAT_MARKER" ",LOG_FLOAT(pd0_periodocity));\r
+                    \r
+////                    \r
+//////                    \r
+////                    log_printf(",pd3_spo2 = "LOG_FLOAT_MARKER" ",LOG_FLOAT(pd3_spo2));\r
+////                                   nrf_delay_ms(10);\r
+////                    log_printf(",pd3_trust_flag = "LOG_FLOAT_MARKER" ",LOG_FLOAT(pd3_trust_flag));\r
+////                    nrf_delay_ms(10);\r
+////                    log_printf(",pd3_correlation = "LOG_FLOAT_MARKER" ",LOG_FLOAT(pd3_correlation));\r
+////                    nrf_delay_ms(10);\r
+////                    log_printf(",pd3_ratio = "LOG_FLOAT_MARKER" ",LOG_FLOAT(pd3_ratio));\r
+////                    nrf_delay_ms(10);\r
+                    \r
+                    \r
+                                       log_printf(",Optimize_spo2 = "LOG_FLOAT_MARKER" ",LOG_FLOAT(Opt_SpO2));\r
+                    log_printf(",Optimize_flag = %d   \n", Opt_falg);\r
+                                       nrf_delay_ms(10);\r
+                                        \r
+                    \r
+/*\r
+                                       nrf_delay_ms(50); \r
+                                       if(no_value_reason==0)\r
+                                       {\r
+                                               log_printf(", Normal_Signal \n");\r
+                                       }\r
+                                       else if(no_value_reason==1)\r
+                                       {\r
+                                               log_printf(", Signal contain noise\n");\r
+                                       }\r
+                                       else if(no_value_reason==2)\r
+                                       {\r
+                                               log_printf(", No Detect PPG waveform\n");\r
+                                       }\r
+                                       else if(no_value_reason==3)\r
+                                       {\r
+                                               log_printf(", Open constrin mode\n");\r
+\r
+                                       }               \r
+                                       else if(no_value_reason==4)\r
+                                       {\r
+                                               log_printf(", Serious Motion\n");\r
+                                       }                                               \r
+\r
+\r
+                                       \r
+                                       //log_printf(",MEMX_X  ="  LOG_FLOAT_MARKER"   " ,LOG_FLOAT( MEMS_Mean_X));\r
+                                       //nrf_delay_ms(50);\r
+                                       //log_printf(",MEMX_Y  ="  LOG_FLOAT_MARKER"   " , LOG_FLOAT(MEMS_Mean_Y));\r
+                                       //nrf_delay_ms(50);\r
+                                       //log_printf(",MEMX_Z  ="  LOG_FLOAT_MARKER"   " , LOG_FLOAT(MEMS_Mean_Z));\r
+*/\r
+                               }\r
+                                        \r
+//                             float  new_spo2=mySpO2;\r
+                       \r
+                               \r
+                       #if defined(Optimize_SPO2_flow_qq) \r
+                               MEMS_data[count_index%window]= MEMS_RMS; \r
+                count_index++;\r
+               \r
+                if(count_index>=window)\r
+                {\r
+\r
+                    for (int k=0; k<window ;k++)\r
+                    {\r
+                        if(MEMS_data[k] <=1500.00)\r
+                        {\r
+                            mems_1++;\r
+                            //log_printf("mems_1    = %d   \n",mems_1);\r
+\r
+                        }\r
+                        else if(MEMS_data[k]>1500.00 && MEMS_data[k]<=3000.00)\r
+                        {\r
+                            mems_2++;\r
+                            //log_printf("mems_2    = %d  \n",mems_2);\r
+\r
+                        }\r
+                        else if(MEMS_data[k]>3000.00 && MEMS_data[k]<6500.00)\r
+                        {\r
+                            mems_3++ ;\r
+                            //log_printf("mems_3    = %d  \n",mems_3);\r
+\r
+                        }\r
+                        else if(MEMS_data[k] >=6500.00)\r
+                        {\r
+                            mems_4++ ;\r
+                            //log_printf("mems_4    = %d  \n",mems_4);\r
+\r
+                        }\r
+                                \r
+                    }\r
+                                       \r
+                    \r
+                    if( (mems_1+mems_2)< (mems_3+mems_4))\r
+                    {\r
+                         if(mems_4>=1)\r
+                         {\r
+                            log_printf("mems_4_flag  => **Serious motion force stop. **\n");\r
+                            mems_4_flag=1;\r
+                         }\r
+                         else if(mems_3>mems_4)\r
+                         {\r
+                             log_printf("mems_3_flag  => **Moderate motion suggest abandon data.** \n");\r
+                             mems_3_flag=1;\r
+                         }\r
+                             \r
+                    }\r
+                    else\r
+                    {\r
+                         if(mems_1>mems_2)\r
+                         {\r
+                            log_printf("mems_1_flag  =>Relatively Static condition \n");\r
+                            mems_1_flag=1;\r
+                         }\r
+                         else if(mems_1<=mems_2)\r
+                         {\r
+                             log_printf("mems_2_flag =>Slight motion suggest static. \n");\r
+                             mems_2_flag=1;\r
+                         }\r
+                        \r
+                    }\r
+                    mems_1=0;\r
+                    mems_2=0;\r
+                    mems_3=0;\r
+                    mems_4=0;\r
+                    \r
+                }\r
+                               if(new_spo2>0 && mems_4_flag==0)\r
+                //if(new_spo2>0)    \r
+                               {\r
+                     \r
+                     if(first_falg==0)\r
+                                    {\r
+                                               FirstSpO2   =new_spo2;\r
+                        before_spo2= new_spo2; \r
+                                               first_falg=1;\r
+                        Firsttime=count_index;\r
+                                    }\r
+                     \r
+                     if(FirstSpO2>=93)\r
+                     {\r
+                        //log_printf("  ,Opt_SPO2    = "LOG_FLOAT_MARKER"  ",LOG_FLOAT(new_spo2));\r
+                        if( (new_spo2-before_spo2)<=-1.5)\r
+                        {\r
+                            drop_count++;\r
+                        }\r
+                        if(drop_count>=2 && new_spo2<=93)\r
+                        {\r
+                           log_printf("  ,Meet unexpect drop\n"); \r
+                           log_printf("  ,Opt_SPO2    = "LOG_FLOAT_MARKER"  \n",LOG_FLOAT(FirstSpO2)); \r
+                        }\r
+                        else\r
+                        {\r
+                           log_printf("  ,Opt_SPO2    = "LOG_FLOAT_MARKER"  \n",LOG_FLOAT(new_spo2)); \r
+                           before_spo2=new_spo2;\r
+                        }\r
+                         \r
+                     }\r
+                     else\r
+                     {\r
+                        // before_spo2=new_spo2;\r
+                         \r
+                        if( (new_spo2-before_spo2)>1.5)\r
+                        {\r
+                            ascend_count++;\r
+                        }\r
+                        \r
+                        \r
+                        if(ascend_count>=2)\r
+                        {\r
+                           // wait extra 10sec to read spo2\r
+                           log_printf("  ,Meet unexpect ascending wait extra 10sec to read spo2\n"); \r
+                           if((count_index-Firsttime) >=30)\r
+                           {                               \r
+                                log_printf("  ,Opt_SPO2    = "LOG_FLOAT_MARKER" \n ",LOG_FLOAT(new_spo2)); \r
+                           }\r
+                        }\r
+                        else\r
+                        {\r
+                         \r
+                            if(trust_flag==1)\r
+                            {\r
+                                if(new_spo2>before_spo2)\r
+                                {                                    \r
+                                    before_spo2=new_spo2;\r
+                                }                                    \r
+                            }\r
+                         \r
+                            if((count_index-Firsttime) >=15)\r
+                            {\r
+                                if(new_spo2<93)\r
+                                {\r
+                                  log_printf("  ,Opt_SPO2    = "LOG_FLOAT_MARKER" \n ",LOG_FLOAT(before_spo2));\r
+                                }\r
+                            }                                \r
+                        }\r
+                         \r
+                         \r
+                     }\r
+                     \r
+       \r
+                               }\r
+                       #endif  \r
+               }\r
+               else\r
+               {\r
+       \r
+               switch (ret_value)\r
+               {\r
+                               case SPO2_MSG_ALG_NOT_OPEN:\r
+                     //debug_printf("Algorithm is not initialized. \n");\r
+                break;\r
+                                                               \r
+                               case SPO2_MSG_ALG_REOPEN:\r
+                     //debug_printf("Algorithm is re initialized. \n");\r
+                break;\r
+                                                               \r
+                               case SPO2_MSG_ALG_NOT_SUPPORT:\r
+                     //debug_printf("Algorithm is not support. \n");\r
+                break;\r
+                                                               \r
+                               default:\r
+                     //debug_printf("Algorithm unhandle error = %d \n", ret_value);\r
+                break;\r
+            }\r
+         }\r
+\r
+                               \r
+                                \r
+                                nrf_delay_ms(40); \r
+                }\r
+       \r
+               log_printf("Out of memory. \n");\r
+               nrf_delay_ms(10);\r
+               SpO2_Close();\r
+\r
+    free(pBuffer);\r
+\r
+    return;\r
+}\r
diff --git a/code/sdk/zhihui/drivers/ppg/pah831x/pah/pah_plat.h b/code/sdk/zhihui/drivers/ppg/pah831x/pah/pah_plat.h
new file mode 100644 (file)
index 0000000..16ca581
--- /dev/null
@@ -0,0 +1,87 @@
+#pragma once\r
+/**\r
+ * @file pah_plat.h\r
+ *\r
+ * Copyright (c) 2016-2020 PixArt Imaging Inc.\r
+ * All Rights Reserved.\r
+ * Confidential and Proprietary - PixArt Imaging Inc.\r
+ **/\r
+\r
+#include "pah_plat_inc.h"\r
+#include "pah_ret.h"\r
+\r
+\r
+//============================================================================\r
+// Definition\r
+//============================================================================\r
+typedef enum\r
+{\r
+    PAH_PLAT_COMM_I2C,\r
+    PAH_PLAT_COMM_SPI,\r
+    PAH_PLAT_COMM_I3C,\r
+} pah_plat_comm_type;\r
+\r
+\r
+typedef struct pah_plat_comm\r
+{\r
+    void                *user_data;\r
+    pah_plat_comm_type  type;\r
+    size_t              max_length;\r
+\r
+    pah_ret     (*write)(/*struct pah_plat_comm *plat_comm,*/ uint8_t addr, const uint8_t *data, size_t write_size);\r
+    pah_ret     (*read)(/*struct pah_plat_comm *plat_comm,*/ uint8_t addr, uint8_t *data, size_t read_size);\r
+\r
+//    pah_ret     (*write_timed)(struct pah_plat_comm *plat_comm, uint8_t addr, const uint8_t *data, size_t write_size, uint64_t *write_time);\r
+//    pah_ret     (*write_array)(struct pah_plat_comm *plat_comm, const uint8_t reg_array[][2], size_t reg_array_count);\r
+\r
+} pah_plat_comm;\r
+\r
+\r
+typedef struct pah_plat_time\r
+{\r
+    void    *user_data;\r
+\r
+    void        (*delay_ms)(/*struct pah_plat_time *plat_time,*/ uint32_t ms);\r
+    //uint64_t    (*get_timestamp_ms)(struct pah_plat_time *plat_time);\r
+\r
+} pah_plat_time;\r
+\r
+\r
+typedef struct pah_plat_printer\r
+{\r
+    void    *user_data;\r
+\r
+    void    (*print)(\r
+        const struct pah_plat_printer   *plat_printer,\r
+        int32_t                         fileline,\r
+        const char                      *funcname,\r
+        const char                      *filename,\r
+        const char                      *format, ...);\r
+\r
+} pah_plat_printer;\r
+\r
+\r
+typedef struct\r
+{\r
+    pah_plat_comm       comm;\r
+    pah_plat_time       time;\r
+    pah_plat_printer    printer;\r
+\r
+} pah_plat;\r
+\r
+\r
+//============================================================================\r
+// Macro\r
+//============================================================================\r
+#ifndef __FILENAME__\r
+#   define __FILENAME__ (strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 : __FILE__)\r
+#endif\r
+\r
+#define PAH_PLAT_PRINT(printer, format, ...) \\r
+    do { \\r
+        const struct pah_plat_printer *pah_plat_printer = printer; \\r
+        if (pah_plat_printer->print) \\r
+            pah_plat_printer->print(pah_plat_printer, __LINE__, __func__, __FILENAME__, format, ##__VA_ARGS__); \\r
+    } while (0) \\r
+\r
+\r
diff --git a/code/sdk/zhihui/drivers/ppg/pah831x/pah/pah_plat_inc.h b/code/sdk/zhihui/drivers/ppg/pah831x/pah/pah_plat_inc.h
new file mode 100644 (file)
index 0000000..e29ef57
--- /dev/null
@@ -0,0 +1,13 @@
+#pragma once\r
+/**\r
+ * @file pah_plat_inc.h\r
+ *\r
+ * Copyright (c) 2016-2018 PixArt Imaging Inc.\r
+ * All Rights Reserved.\r
+ * Confidential and Proprietary - PixArt Imaging Inc.\r
+ **/\r
+\r
+#include <stdbool.h>\r
+#include <stdint.h>\r
+#include <string.h>\r
+\r
diff --git a/code/sdk/zhihui/drivers/ppg/pah831x/pah/pah_reg.h b/code/sdk/zhihui/drivers/ppg/pah831x/pah/pah_reg.h
new file mode 100644 (file)
index 0000000..185559d
--- /dev/null
@@ -0,0 +1,33 @@
+#pragma once\r
+/**\r
+ * @file pah_reg.h\r
+ *\r
+ * Copyright (c) 2016-2018 PixArt Imaging Inc.\r
+ * All Rights Reserved.\r
+ * Confidential and Proprietary - PixArt Imaging Inc.\r
+ **/\r
+\r
+#include "pah_plat_inc.h"\r
+#include "pah_util.h"\r
+\r
+\r
+//============================================================================\r
+// Definition\r
+//============================================================================\r
+typedef const uint8_t (pah_reg)[2];\r
+\r
+\r
+typedef struct {\r
+\r
+    pah_reg     *reg_arr;\r
+    uint32_t     reg_arr_len;\r
+\r
+} pah_reg_arr;\r
+\r
+\r
+#define PAH_REG_ARR_SETUP(pah_reg_arr, reg_array) \\r
+    do { \\r
+        pah_reg_arr.reg_arr     = (pah_reg*)reg_array; \\r
+        pah_reg_arr.reg_arr_len = PAH_ARRAY_SIZE(reg_array); \\r
+    } while(0)\r
+\r
diff --git a/code/sdk/zhihui/drivers/ppg/pah831x/pah/pah_ret.h b/code/sdk/zhihui/drivers/ppg/pah831x/pah/pah_ret.h
new file mode 100644 (file)
index 0000000..1ba8ecc
--- /dev/null
@@ -0,0 +1,47 @@
+#pragma once\r
+/**\r
+ * @file pah_ret.h\r
+ *\r
+ * Copyright (c) 2016-2018 PixArt Imaging Inc.\r
+ * All Rights Reserved.\r
+ * Confidential and Proprietary - PixArt Imaging Inc.\r
+ **/\r
+\r
+typedef enum {\r
+\r
+    PAH_RET_SUCCESS = 0,            // Success\r
+\r
+    PAH_RET_PENDING,\r
+\r
+    PAH_RET_FAILED,                 // Unknown error, generally there exists bug in this driver\r
+\r
+    PAH_RET_PLAT_FAILED,            // Platform API failed\r
+    PAH_RET_VERIFY_FAILED,          // Verify device failed\r
+\r
+    PAH_RET_NOT_IMPLEMENTED,        // This API is not supported or is not implemented\r
+\r
+    PAH_RET_INVALID_ARGUMENT,       // Invalid argument to API\r
+    PAH_RET_INVALID_OPERATION,      // This operation is not available at this time\r
+\r
+    PAH_RET_FIFO_CKS_FAILED,        // Failed to compare check sum with fifo data\r
+    PAH_RET_FIFO_OVERFLOW,          // Fifo in device is overflow\r
+\r
+    PAH_RET_ASYNC_PENDING,\r
+\r
+} pah_ret;\r
+\r
+\r
+#define PAH_SUCCEEDED(ret)              (ret == PAH_RET_SUCCESS)\r
+#define PAH_FAILED(ret)                 (!PAH_SUCCEEDED(ret))\r
+\r
+\r
+#define PAH_CHECK_RET(ret) \\r
+    if (PAH_FAILED(ret)) { \\r
+        return ret; \\r
+    }\r
+\r
+#define PAH_CHECK_NULL(p) \\r
+    if (!p) { \\r
+        return PAH_RET_INVALID_ARGUMENT; \\r
+    }\r
+\r
diff --git a/code/sdk/zhihui/drivers/ppg/pah831x/pah/pah_util.h b/code/sdk/zhihui/drivers/ppg/pah831x/pah/pah_util.h
new file mode 100644 (file)
index 0000000..dd055ff
--- /dev/null
@@ -0,0 +1,74 @@
+#pragma once\r
+/**\r
+ * @file pah_util.h\r
+ *\r
+ * Copyright (c) 2016-2018 PixArt Imaging Inc.\r
+ * All Rights Reserved.\r
+ * Confidential and Proprietary - PixArt Imaging Inc.\r
+ **/\r
+\r
+#include "pah_plat_inc.h"\r
+\r
+\r
+#define PAH_ARRAY_SIZE(arr)         (sizeof(arr) / sizeof(arr[0]))\r
+\r
+#define PAH_SET_BIT(var,pos)        do { ((var) |= (1 << (pos))); } while(0)\r
+#define PAH_CLEAR_BIT(var,pos)      do { ((var) &= ~(1 << (pos))); } while(0)\r
+#define PAH_CHECK_BIT(var,pos)      (((var) >> (pos)) & 1)\r
+\r
+//\r
+// PAH_SET_BITSLICE\r
+//\r
+// ex1:\r
+//      // var    = 0x00 : 00000000\r
+//      // pos    = 2    :      ^\r
+//      // mask   = 0x3C : 00111100\r
+//      // value  = 0x0D :   1101\r
+//      // ret    = 0x34 : 00110100\r
+//      uint8_t data = 0x00;\r
+//      uint8_t ret = PAH_SET_BITSLICE(data, 2, 0x3C, 0x0D);\r
+//\r
+// ex2:\r
+//      // var    = 0x6D : 01101101\r
+//      // pos    = 6    :  ^\r
+//      // mask   = 0xC0 : 11000000\r
+//      // value  = 0x02 : 10\r
+//      // ret    = 0xAD : 10101101\r
+//      uint8_t data = 0x6D;\r
+//      uint8_t ret = PAH_SET_BITSLICE(data, 6, 0xC0, 0x02);\r
+//\r
+#define PAH_SET_BITSLICE(var, pos, mask, value) \\r
+    ((var & ~mask) | ((value << pos) & mask))\r
+\r
+//\r
+// PAH_GET_BITSLICE\r
+//\r
+// ex1:\r
+//      // var    = 0x5D : 01011101\r
+//      // pos    = 2    :      ^\r
+//      // mask   = 0x3C : 00111100\r
+//      // ret    = 0x07 :   0111\r
+//      uint8_t ret = PAH_GET_BITSLICE(0x5D, 2, 0x3C);\r
+//\r
+// ex2:\r
+//      // var    = 0xA6 : 10100110\r
+//      // pos    = 5    :   ^\r
+//      // mask   = 0xE0 : 11100000\r
+//      // ret    = 0x05 : 101\r
+//      uint8_t ret = PAH_GET_BITSLICE(0xA6, 5, 0xE0);\r
+//\r
+#define PAH_GET_BITSLICE(var, pos, mask) \\r
+    ((var & mask) >> pos)\r
+\r
+#define PAH_UINT64_HIGH(var)        ((uint32_t)(var >> 32))\r
+#define PAH_UINT64_LOW(var)         ((uint32_t)(var & UINT32_MAX))\r
+\r
+#define PAH_UINT16_HIGH(var)        ((uint8_t)(var >> 8))\r
+#define PAH_UINT16_LOW(var)         ((uint8_t)(var & UINT8_MAX))\r
+\r
+#define PAH_UNUSED_VAR(var)         (void)(var)\r
+\r
+#ifndef __FILENAME__\r
+#   define __FILENAME__ (strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 : __FILE__)\r
+#endif\r
+\r
diff --git a/code/sdk/zhihui/drivers/ppg/pah831x/pah831x_factory_20251217/demo_factory_v3.c b/code/sdk/zhihui/drivers/ppg/pah831x/pah831x_factory_20251217/demo_factory_v3.c
new file mode 100644 (file)
index 0000000..824f07f
--- /dev/null
@@ -0,0 +1,108 @@
+\r
+#include <stdarg.h>\r
+#include <stdio.h>\r
+#include <stdbool.h>\r
+#include <stdlib.h>\r
+\r
+\r
+#include "pah831x_comm.h"\r
+//***************Factory Test ********************//\r
+#include "pah831x_factory_test_v3.h"  \r
+//=================================================//\r
+\r
+//#define FACTORY_1_LED\r
+#define FACTORY_2_LED\r
+\r
+\r
+\r
+void demo_factory_test_V3(void)\r
+{\r
+    uint16_t sensor_pid = 0 ;\r
+    pah831x_read_id(&sensor_pid);\r
+\r
+    if(sensor_pid==0x8311)\r
+    {\r
+        LOG_PRINT("ID Check Success. Sensor_pid = 0x%x \n",sensor_pid);\r
+    }\r
+    else\r
+    {\r
+        LOG_PRINT("ID Check Fail.    Sensor_pid = 0x%x \n",sensor_pid);\r
+        return;\r
+    }\r
+    LOG_PRINT("PAH831X_VERIFY_REG_VERSION = 0x%x \n",get_pah813x_verify_reg_version());\r
+#ifdef FACTORY_1_LED\r
+    //Check Light_Leak_Test\r
+    demo_factory_mode(Light_Leak_Test_1_LED);\r
+\r
+    //Check_Brightness_PCB_Only\r
+\r
+    demo_factory_mode(Check_Brightness_PCB_Only_test_1_Side_A_1_LED);    \r
+    \r
+    demo_factory_mode(Check_Brightness_PCB_Only_test_2_Side_B_1_LED); \r
+//    //INT_TEST\r
+    demo_factory_mode(INT_TEST);\r
+\r
+//    //Check_Brightness_with_mechanical_cover\r
+//  \r
+    demo_factory_mode(Check_Brightness_with_mechanical_cover_test_1_Side_A_1_LED);    \r
+    \r
+    demo_factory_mode(Check_Brightness_with_mechanical_cover_test_2_Side_B_1_LED); \r
+#endif\r
+\r
+#ifdef FACTORY_2_LED\r
+    //Check Light_Leak_Test\r
+    demo_factory_mode(Light_Leak_Test_2_LED);\r
+\r
+    //Check_Brightness_PCB_Only\r
+\r
+    demo_factory_mode(Check_Brightness_PCB_Only_test_1_Side_A_2_LED);    \r
+    \r
+    demo_factory_mode(Check_Brightness_PCB_Only_test_2_Side_B_2_LED); \r
+//    //INT_TEST\r
+    demo_factory_mode(INT_TEST);\r
+\r
+//    //Check_Brightness_with_mechanical_cover\r
+//  \r
+    demo_factory_mode(Check_Brightness_with_mechanical_cover_test_1_Side_A_2_LED);    \r
+    \r
+    demo_factory_mode(Check_Brightness_with_mechanical_cover_test_2_Side_B_2_LED); \r
+#endif\r
+\r
+\r
+//    //ECG Waveform Test\r
+    demo_factory_mode(Check_ECG_WAVEFORM_TEST);\r
+    demo_factory_mode(Check_ECG_DC_TEST);\r
+    \r
+    //AFE_TEST\r
+    demo_factory_mode(Check_PPG_AFE_BUILT_IN_TEST);\r
+    \r
+    \r
+    //S1 OPEN , S2 OPEN\r
+    demo_factory_mode(Check_ECG_LL_TO_LA_STEP1);\r
+\r
+\r
+    //S1 SHORT , S2 OPEN\r
+    demo_factory_mode(Check_ECG_LL_TO_LA_STEP2);\r
+\r
+\r
+    //S1 SHORT , S2 OPEN\r
+    demo_factory_mode(Check_ECG_LL_TO_LA_STEP3);\r
+\r
+\r
+    //S1 OPEN , S2 OPEN\r
+    demo_factory_mode(Check_ECG_LL_TO_RA_STEP1);\r
+\r
+\r
+    //S1 OPEN , S2 SHORT\r
+    demo_factory_mode(Check_ECG_LL_TO_RA_STEP2);\r
+\r
+\r
+    //S1 OPEN , S2 SHORT\r
+    demo_factory_mode(Check_ECG_LL_TO_RA_STEP3);\r
+\r
+ \r
+ \r
+ \r
+\r
+\r
+}\r
diff --git a/code/sdk/zhihui/drivers/ppg/pah831x/pah831x_factory_20251217/pah831x_factory_test_v3.c b/code/sdk/zhihui/drivers/ppg/pah831x/pah831x_factory_20251217/pah831x_factory_test_v3.c
new file mode 100644 (file)
index 0000000..1918ce9
--- /dev/null
@@ -0,0 +1,1191 @@
+\r
+#include <stdlib.h>\r
+#include <stdarg.h>\r
+#include <string.h>\r
+#include <stdio.h>\r
+\r
+\r
+\r
+// include Factroy test.h\r
+#include "pah831x_factory_test_v3.h"\r
+#include "pah831x_verify_reg_v3.h"\r
+\r
+\r
+#include "pah831x_verify_cal_v3.h"\r
+#include "pah831x_comm.h"\r
+\r
+// void LOG_PRINT(const char* format, ...);\r
+\r
+/*============================================================================\r
+TYPE DEFINITIONS\r
+============================================================================*/\r
+typedef const uint8_t(*register_array_t)[2];\r
+typedef const uint16_t(*test_spec_array_t)[3];\r
+//V3.5\r
+typedef struct {\r
+    register_array_t        test_register_array;\r
+    uint32_t                test_register_array_length;\r
+    test_spec_array_t       test_spec_array;\r
+} pah831x_reg_spec_array_s;\r
+\r
+\r
+typedef struct {\r
+    register_array_t        test_register_cal_array;\r
+    uint32_t                test_register_cal_array_length;\r
+\r
+} pah831x_reg_cal_array_s;\r
+\r
+/*============================================================================\r
+PRIVATE GLOBAL VARIABLES\r
+============================================================================*/\r
+static pah831x_reg_spec_array_s    g_state;\r
+\r
+static pah831x_reg_cal_array_s    g_state_cal;\r
+\r
+#define LEAKLIGHT_FAIL_STR_MAX 512\r
+static char g_leaklight_fail_str[LEAKLIGHT_FAIL_STR_MAX];\r
+\r
+#define PAH831X_IS_LEAK_LIGHT_TEST(mode) \\r
+    ((mode) == Light_Leak_Test_2_LED || (mode) == Light_Leak_Test_1_LED)\r
+\r
+static void pah831x_leaklight_fail_str_reset(void)\r
+{\r
+    g_leaklight_fail_str[0] = '\0';\r
+}\r
+\r
+static void pah831x_leaklight_fail_str_append(const char *fmt, ...)\r
+{\r
+    size_t len = strlen(g_leaklight_fail_str);\r
+    if (len >= LEAKLIGHT_FAIL_STR_MAX - 1) {\r
+        return;\r
+    }\r
+\r
+    va_list arg;\r
+    va_start(arg, fmt);\r
+    vsnprintf(g_leaklight_fail_str + len, LEAKLIGHT_FAIL_STR_MAX - len, fmt, arg);\r
+    va_end(arg);\r
+}\r
+\r
+uint16_t pah831x_get_leaklight_fail_str(char *buf, uint16_t buf_size)\r
+{\r
+    if (buf == NULL || buf_size == 0) {\r
+        return 0;\r
+    }\r
+\r
+    strncpy(buf, g_leaklight_fail_str, buf_size - 1);\r
+    buf[buf_size - 1] = '\0';\r
+    return (uint16_t)strlen(buf);\r
+}\r
+\r
+#define GPIO_INPUT_PIN_INT1 13  /**< Pin number for INT1. */\r
+#define GPIO_INPUT_PIN_INT2 14  /**< Pin number for INT2. */\r
+\r
+#define UINT32_FROM_UINT8(data0, data1, data2, data3)   ((uint32_t)((data0 << 0) | (data1 << 8) | (data2 << 16) | (data3 << 24)))\r
+\r
+#define PAH_SET_BIT(var,pos)        do { ((var) |= (1 << (pos))); } while(0)\r
+#define PAH_CLEAR_BIT(var,pos)      do { ((var) &= ~(1 << (pos))); } while(0)\r
+#define PAH_CHECK_BIT(var,pos)      (((var) >> (pos)) & 1)\r
+static bool pah831x_comm_write(uint8_t addr, uint8_t data);\r
+static bool pah831x_comm_read(uint8_t addr, uint8_t *data);\r
+\r
+static uint8_t check_table[14]=\r
+{\r
+    0x00,\r
+    0x03,\r
+    0x06,\r
+    0x09,\r
+    0x0C,\r
+    0x0F,\r
+    0x12,\r
+    0x16,\r
+    0x19,\r
+    0x1C,\r
+    0x1F,\r
+    0x22,\r
+    0x25,\r
+    0x28,\r
+};\r
+static uint8_t  reg_bank = 0xFF;\r
+static bool pah831x_comm_write(uint8_t addr, uint8_t data)\r
+{\r
+    \r
+    //pxi_nrf_i2c_831x_write(addr, &data,1);\r
+    //LOG_PRINT("I2C_W= 0x%2x ,0x%2x\n",addr,data);\r
+    uint8_t i = 0 ;\r
+    uint8_t data_read = 0 ;\r
+    uint8_t data_out = 0 ;\r
+    if(addr==0x7F)\r
+    {\r
+        reg_bank = data ;\r
+    }else if(reg_bank == 0x04)\r
+    {\r
+        for (i=0; i<14; i++)\r
+        {\r
+            if(addr==check_table[i])\r
+            {\r
+                pah831x_comm_read(addr,&data_read);\r
+                data_out = (data_read&0x0F)+ (data&0xF0);\r
+                // pxi_nrf_i2c_write(0x40, addr, &data_out, 1);\r
+                pah_comm_i2c_write( addr, &data_out, 1);\r
+//                LOG_PRINT("I2C_W= 0x%2x ,0x%2x\n",addr,data_out);\r
+                return true;\r
+            }\r
+        }\r
+    }\r
+    \r
+    // pxi_nrf_i2c_write(0x40, addr, &data, 1);\r
+    pah_comm_i2c_write( addr, &data, 1);\r
+return true;\r
+}\r
+\r
+static bool pah831x_comm_read(uint8_t addr, uint8_t *data)\r
+{\r
+    //pxi_nrf_i2c_831x_read(addr, data,1);\r
+    // pxi_nrf_i2c_read(0x40, addr, data, 1);\r
+    pah_comm_i2c_read(addr, data, 1);\r
+    return true;\r
+}\r
+\r
+static bool pah831x_comm_burstread(uint8_t addr, uint8_t *data, uint16_t num)\r
+{\r
+    //pxi_nrf_i2c_831x_read(addr, data,num);\r
+    uint16_t read_num=num ;\r
+    uint16_t read_index = 0 ;\r
+    while(read_num>250)\r
+    {\r
+        // pxi_nrf_i2c_read(0x40, addr, data+read_index, 250);\r
+        pah_comm_i2c_read(addr, data+read_index, 250);\r
+        read_index+=250;\r
+        read_num = read_num- 250;\r
+    }\r
+    // pxi_nrf_i2c_read(0x40, addr, data+read_index, read_num);\r
+    pah_comm_i2c_read(addr, data+read_index, read_num);\r
+    return true;\r
+}\r
+\r
+void pah831x_delay_ms(uint16_t delay_ms)\r
+{\r
+    LOS_Mdelay(delay_ms);\r
+}\r
+\r
+// void LOG_PRINT(const char* format, ...)\r
+// {\r
+//     // static char dest[256];\r
+//     // va_list argptr;\r
+//     // int char_num = 0;\r
+    \r
+//     // va_start(argptr, format);\r
+//     // char_num = vsprintf(dest, format, argptr);\r
+//     // va_end(argptr);\r
+//     printf(format);\r
+//     // pxi_nrf_uart_transmit((uint8_t*)dest, (uint16_t)(char_num + 1));\r
+// }\r
+\r
+static void pah831x_startup(void)\r
+{\r
+    pah831x_comm_write(0x7f, 0x03);  //bank3\r
+    pah831x_comm_write(0x01, 0x01);  //0x01:PD_Mode_EnH\r
+    //pah831x_delay_ms(10);\r
+    pah831x_delay_ms(2);\r
+    pah831x_comm_write(0x7f, 0x03);  //bank3\r
+    pah831x_comm_write(0x01, 0x00);  //0x01:PD_Mode_EnH\r
+    pah831x_delay_ms(10);\r
+    //pah831x_delay_ms(2);\r
+}\r
+\r
+void pah831x_read_id(uint16_t *id)\r
+{\r
+    uint16_t data=0 ;\r
+    pah831x_startup();\r
+    pah831x_comm_write(0x7f, 0x00);   //bank0\r
+    pah831x_comm_burstread(0x00, (uint8_t*)&data, 2);//Product_ID: deault:0x8311\r
+    *id= data ;\r
+    uint8_t version = 0 ;\r
+    pah831x_comm_read(0x02,&version);\r
+    LOG_PRINT("Product_ID = 0x%x ,version  0x%x\n",data,version);\r
+}\r
+\r
+uint32_t get_pah813x_verify_reg_version(void)\r
+{\r
+    return PAH831X_VERIFY_REG_VERSION ;\r
+}\r
+\r
+static void pah831x_powerdown(void)\r
+{\r
+    pah831x_comm_write(0x7f, 0x03);  //bank3\r
+    pah831x_comm_write(0x01, 0x01);  //0x01:PD_Mode_EnH\r
+    pah831x_delay_ms(10);\r
+}\r
+\r
+static void pah831x_update_flag(void)\r
+{\r
+    pah831x_comm_write(0x7f, 0x00);  //bank0\r
+    pah831x_comm_write(0x7e, 0x80);  //\r
+    pah831x_delay_ms(10);\r
+}\r
+\r
+static void pah831x_start_tg(void)\r
+{\r
+    pah831x_comm_write(0x7f, 0x00);  //bank0\r
+    pah831x_comm_write(0x07, 0x01);  //TG enable\r
+    pah831x_delay_ms(10);\r
+}\r
+\r
+static void pah831x_write_reg_array(const uint8_t reg_array[][2], uint16_t length)\r
+{\r
+    uint16_t i;    \r
+    for (i=0; i<length; i++)\r
+    {\r
+        pah831x_comm_write(reg_array[i][0], reg_array[i][1]);\r
+    }\r
+}\r
+\r
+static void pah831x_get_channel_num(const uint8_t reg_array[][2], uint16_t length , uint8_t *channel_en_num , uint16_t *channel_en_bit_out)\r
+{\r
+    uint16_t i;\r
+    int8_t bank_num = -1 ;\r
+    uint16_t channel_en_ch_real=0;\r
+    uint16_t channel_en_bit = 0 ;\r
+    for (i=0; i<length; i++)\r
+    {\r
+        if((reg_array[i][0]==0x7F) && (bank_num!=reg_array[i][1]))\r
+        {\r
+            bank_num = reg_array[i][1] ;\r
+        }\r
+        if( bank_num == 0)\r
+        {\r
+            if(reg_array[i][0]==0x50)//CH_A\r
+            {\r
+                if((reg_array[i][1]&0x01)!=0)\r
+                {                \r
+                    channel_en_bit+=1;\r
+                }\r
+                if((reg_array[i][1]&0x02)!=0)\r
+                {                \r
+                    channel_en_bit+=2;\r
+                }\r
+            }else if(reg_array[i][0]==0x51)//CH_B\r
+            {\r
+                if((reg_array[i][1]&0x01)!=0)\r
+                {                \r
+                    channel_en_bit+=4;\r
+                }\r
+                if((reg_array[i][1]&0x02)!=0)\r
+                {                \r
+                    channel_en_bit+=8;\r
+                }\r
+            }else if(reg_array[i][0]==0x52)//CH_C\r
+            {\r
+                if((reg_array[i][1]&0x01)!=0)\r
+                {                \r
+                    channel_en_bit+=16;\r
+                }\r
+                if((reg_array[i][1]&0x02)!=0)\r
+                {                \r
+                    channel_en_bit+=32;\r
+                }\r
+            }else if(reg_array[i][0]==0x53)//CH_D\r
+            {\r
+                if((reg_array[i][1]&0x01)!=0)\r
+                {                \r
+                    channel_en_bit+=64;\r
+                }\r
+                if((reg_array[i][1]&0x02)!=0)\r
+                {                \r
+                    channel_en_bit+=128;\r
+                }\r
+            }else if(reg_array[i][0]==0x70)//CH_E\r
+            {\r
+                if((reg_array[i][1]&0x01)!=0)\r
+                {                \r
+                    channel_en_bit+=256;\r
+                }\r
+                if((reg_array[i][1]&0x02)!=0)\r
+                {                \r
+                    channel_en_bit+=512;\r
+                }\r
+            }else if(reg_array[i][0]==0x71)//CH_F\r
+            {\r
+                if((reg_array[i][1]&0x01)!=0)\r
+                {                \r
+                    channel_en_bit+=1024;\r
+                }\r
+                if((reg_array[i][1]&0x02)!=0)\r
+                {                \r
+                    channel_en_bit+=2048;\r
+                    \r
+                }\r
+            }else if(reg_array[i][0]==0x1B)\r
+            {                \r
+                channel_en_ch_real += (reg_array[i][1]& 0xF );\r
+            }else if(reg_array[i][0]==0x68)\r
+            {                \r
+                channel_en_ch_real += ((reg_array[i][1]& 0x3 )<<4);\r
+            }              \r
+        }            \r
+    }\r
+    \r
+    for (i=0; i<6; i++)\r
+    {\r
+        if(PAH_CHECK_BIT(channel_en_ch_real,i))\r
+        {\r
+            if(PAH_CHECK_BIT(channel_en_bit,2*i))\r
+            {\r
+                PAH_SET_BIT(*channel_en_bit_out,2*i);\r
+                *channel_en_num+=1;\r
+            }\r
+            if(PAH_CHECK_BIT(channel_en_bit,2*i+1))\r
+            {\r
+                PAH_SET_BIT(*channel_en_bit_out,2*i+1);\r
+                *channel_en_num+=1;\r
+            }\r
+        } \r
+    }        \r
+    //LOG_PRINT("channel_en_ch_real = %d ,channel_en_bit  0x%x\n",channel_en_ch_real,channel_en_bit);\r
+    //LOG_PRINT("channel_en_num = %d ,channel_en_bit_out  0x%x\n",*channel_en_num,*channel_en_bit_out);\r
+}\r
+\r
+static bool pah831x_factory_test_INT(uint16_t *int1_l, uint16_t *int1_h,uint16_t *int2_l, uint16_t *int2_h)\r
+{\r
+    bool verify_result= true ;\r
+    pah831x_startup();\r
+    pah831x_write_reg_array(pah831x_verify_int_test_1_array,sizeof(pah831x_verify_int_test_1_array)/2);\r
+    //pah831x_update_flag();\r
+    pah831x_delay_ms(200);\r
+    //*int_l = Get_Voltage(PAH8SERIES_INT_AD,100);\r
+    // *int1_l=nrf_gpio_pin_read(GPIO_INPUT_PIN_INT1);\r
+    //*int2_h=nrf_gpio_pin_read(GPIO_INPUT_PIN_INT2);\r
+    \r
+    pah831x_write_reg_array(pah831x_verify_int_test_2_array,sizeof(pah831x_verify_int_test_2_array)/2);\r
+    //pah831x_update_flag();\r
+    pah831x_delay_ms(200);\r
+    //*int_h = Get_Voltage(PAH8SERIES_INT_AD,100);\r
+    // *int1_h=nrf_gpio_pin_read(GPIO_INPUT_PIN_INT1);\r
+   // *int2_l=nrf_gpio_pin_read(GPIO_INPUT_PIN_INT2);\r
+////          \r
+    LOG_PRINT("INT1-Low  %d\n",*int1_l);\r
+    LOG_PRINT("INT1-High %d\n",*int1_h);\r
+   // LOG_PRINT("INT2-Low  %d\n",*int2_l);\r
+   // LOG_PRINT("INT2-High %d\n",*int2_h); \r
+    \r
+    //if((*int1_l==0)&&(*int1_h==1)&&(*int2_l==0)&&(*int2_h==1))\r
+    if((*int1_l==0)&&(*int1_h==1))\r
+    {\r
+        verify_result= true  ;\r
+    }else\r
+    {\r
+        verify_result= false;    \r
+    }\r
+    pah831x_powerdown();\r
+    return verify_result ;\r
+}\r
+\r
+static bool pah831x_factory_test_Check_ADC(uint8_t test_mode,uint32_t *touch, uint16_t *adc_data)\r
+{\r
+    uint16_t channel_en_bit = 0 ;\r
+    uint8_t channel_en_num = 0 ;\r
+    uint8_t i = 0 ;\r
+    uint16_t adc_value = 0 ;\r
+    uint16_t adc_value_on = 0 ;\r
+    uint16_t adc_value_off = 0 ;\r
+    uint32_t touch_value = 0 ;    \r
+    uint8_t read_index_1 = 0 ;\r
+    uint8_t read_index_2 = 0 ;\r
+    uint8_t ppg_1_2  = 0 ;\r
+    bool verify_result= true ;   \r
+    \r
+    switch(test_mode)\r
+    {\r
+        case Check_Brightness_PCB_Only_test_1_Side_A_2_LED:\r
+            g_state.test_register_array=pah831x_verify_led_brightness_array_test_1_Side_A_2_LED;\r
+            g_state.test_register_array_length=sizeof(pah831x_verify_led_brightness_array_test_1_Side_A_2_LED)/2;\r
+            g_state.test_spec_array = Brightness_PCB_Only_Spec_test_1_Side_A_2_LED;\r
+            \r
+            g_state_cal.test_register_cal_array=pah831x_verify_led_brightness_cal_array_Side_A_2_LED;\r
+            g_state_cal.test_register_cal_array_length=sizeof(pah831x_verify_led_brightness_cal_array_Side_A_2_LED)/2; \r
+        \r
+        break;    \r
+        case Check_Brightness_PCB_Only_test_2_Side_B_2_LED:\r
+            g_state.test_register_array=pah831x_verify_led_brightness_array_test_2_Side_B_2_LED;\r
+            g_state.test_register_array_length=sizeof(pah831x_verify_led_brightness_array_test_2_Side_B_2_LED)/2;\r
+            g_state.test_spec_array = Brightness_PCB_Only_Spec_test_2_Side_B_2_LED;\r
+        \r
+        \r
+            g_state_cal.test_register_cal_array=pah831x_verify_led_brightness_cal_array_Side_B_2_LED;\r
+            g_state_cal.test_register_cal_array_length=sizeof(pah831x_verify_led_brightness_cal_array_Side_B_2_LED)/2; \r
+        \r
+        break;\r
+        case Check_Brightness_with_mechanical_cover_test_1_Side_A_2_LED:\r
+            g_state.test_register_array=pah831x_verify_led_brightness_array_test_1_Side_A_2_LED;\r
+            g_state.test_register_array_length=sizeof(pah831x_verify_led_brightness_array_test_1_Side_A_2_LED)/2;\r
+            g_state.test_spec_array = Brightness_with_cover_Spec_test_1_Side_A_2_LED;\r
+        \r
+        \r
+            g_state_cal.test_register_cal_array=pah831x_verify_led_brightness_cal_array_Side_A_2_LED;\r
+            g_state_cal.test_register_cal_array_length=sizeof(pah831x_verify_led_brightness_cal_array_Side_A_2_LED)/2; \r
+        \r
+        break;    \r
+        case Check_Brightness_with_mechanical_cover_test_2_Side_B_2_LED:\r
+            g_state.test_register_array=pah831x_verify_led_brightness_array_test_2_Side_B_2_LED;\r
+            g_state.test_register_array_length=sizeof(pah831x_verify_led_brightness_array_test_2_Side_B_2_LED)/2;\r
+            g_state.test_spec_array = Brightness_with_cover_Spec_test_2_Side_B_2_LED;        \r
+        \r
+            g_state_cal.test_register_cal_array=pah831x_verify_led_brightness_cal_array_Side_B_2_LED;\r
+            g_state_cal.test_register_cal_array_length=sizeof(pah831x_verify_led_brightness_cal_array_Side_B_2_LED)/2; \r
+        \r
+        break;\r
+        case Check_Brightness_PCB_Only_test_1_Side_A_1_LED:\r
+            g_state.test_register_array=pah831x_verify_led_brightness_array_test_1_Side_A_1_LED;\r
+            g_state.test_register_array_length=sizeof(pah831x_verify_led_brightness_array_test_1_Side_A_1_LED)/2;\r
+            g_state.test_spec_array = Brightness_PCB_Only_Spec_test_1_Side_A_1_LED;\r
+                    \r
+            g_state_cal.test_register_cal_array=pah831x_verify_led_brightness_cal_array_Side_A_1_LED;\r
+            g_state_cal.test_register_cal_array_length=sizeof(pah831x_verify_led_brightness_cal_array_Side_A_1_LED)/2; \r
+        \r
+        break;    \r
+        case Check_Brightness_PCB_Only_test_2_Side_B_1_LED:\r
+            g_state.test_register_array=pah831x_verify_led_brightness_array_test_2_Side_B_1_LED;\r
+            g_state.test_register_array_length=sizeof(pah831x_verify_led_brightness_array_test_2_Side_B_1_LED)/2;\r
+            g_state.test_spec_array = Brightness_PCB_Only_Spec_test_2_Side_B_1_LED;\r
+            \r
+            g_state_cal.test_register_cal_array=pah831x_verify_led_brightness_cal_array_Side_B_1_LED;\r
+            g_state_cal.test_register_cal_array_length=sizeof(pah831x_verify_led_brightness_cal_array_Side_B_1_LED)/2; \r
+        \r
+        break;\r
+        case Check_Brightness_with_mechanical_cover_test_1_Side_A_1_LED:\r
+            g_state.test_register_array=pah831x_verify_led_brightness_array_test_1_Side_A_1_LED;\r
+            g_state.test_register_array_length=sizeof(pah831x_verify_led_brightness_array_test_1_Side_A_1_LED)/2;\r
+            g_state.test_spec_array = Brightness_with_cover_Spec_test_1_Side_A_1_LED;\r
+        \r
+            g_state_cal.test_register_cal_array=pah831x_verify_led_brightness_cal_array_Side_A_1_LED;\r
+            g_state_cal.test_register_cal_array_length=sizeof(pah831x_verify_led_brightness_cal_array_Side_A_1_LED)/2; \r
+        \r
+        break;    \r
+        case Check_Brightness_with_mechanical_cover_test_2_Side_B_1_LED:\r
+            g_state.test_register_array=pah831x_verify_led_brightness_array_test_2_Side_B_1_LED;\r
+            g_state.test_register_array_length=sizeof(pah831x_verify_led_brightness_array_test_2_Side_B_1_LED)/2;\r
+            g_state.test_spec_array = Brightness_with_cover_Spec_test_2_Side_B_1_LED;\r
+        \r
+            g_state_cal.test_register_cal_array=pah831x_verify_led_brightness_cal_array_Side_B_1_LED;\r
+            g_state_cal.test_register_cal_array_length=sizeof(pah831x_verify_led_brightness_cal_array_Side_B_1_LED)/2; \r
+        \r
+        break;\r
+        case Light_Leak_Test_2_LED:\r
+            g_state.test_register_array=pah831x_verify_light_leakage_array_2_LED;\r
+            g_state.test_register_array_length=sizeof(pah831x_verify_light_leakage_array_2_LED)/2;\r
+            g_state.test_spec_array = Light_Leak_Spec_2_LED;\r
+        \r
+            g_state_cal.test_register_cal_array=pah831x_verify_light_leakage_cal_array_2_LED;\r
+            g_state_cal.test_register_cal_array_length=sizeof(pah831x_verify_light_leakage_cal_array_2_LED)/2; \r
+        \r
+        break;  \r
+        case Light_Leak_Test_1_LED:\r
+            g_state.test_register_array=pah831x_verify_light_leakage_array_1_LED;\r
+            g_state.test_register_array_length=sizeof(pah831x_verify_light_leakage_array_1_LED)/2;\r
+            g_state.test_spec_array = Light_Leak_Spec_1_LED;\r
+        \r
+            g_state_cal.test_register_cal_array=pah831x_verify_light_leakage_cal_array_1_LED;\r
+            g_state_cal.test_register_cal_array_length=sizeof(pah831x_verify_light_leakage_cal_array_1_LED)/2; \r
+        \r
+        break;                \r
+    }\r
+\r
+    bool is_leak_light_test = PAH831X_IS_LEAK_LIGHT_TEST(test_mode);\r
+    if (is_leak_light_test) {\r
+        pah831x_leaklight_fail_str_reset();\r
+    }\r
+\r
+    //=================================pah831x_verify_init=============================//\r
+    pah831x_startup();\r
+    pah831x_get_channel_num(g_state.test_register_array,g_state.test_register_array_length,&channel_en_num,&channel_en_bit);\r
+    pah831x_write_reg_array(g_state.test_register_array,g_state.test_register_array_length);\r
+    \r
+    //=================================pah831x_verify_init_cal=============================//\r
+\r
+   // pah831x_write_reg_array(g_state_cal.test_register_cal_array,g_state_cal.test_register_cal_array_length);   \r
+    \r
+    pah831x_update_flag();\r
+    pah831x_start_tg();\r
+\r
+    pah831x_delay_ms(150);\r
+     //============================================================================//\r
+    pah831x_comm_write(0x7f, 0x00);  //bank0\r
+    pah831x_comm_burstread(0x38, (uint8_t*)&touch_value, 2);\r
+    \r
+    pah831x_comm_write(0x7f, 0x02);  //bank2\r
+    pah831x_comm_burstread(0x50, (uint8_t*)&adc_data[0], 8);//CH_A\r
+    pah831x_comm_burstread(0x58, (uint8_t*)&adc_data[4], 8);//CH_B\r
+    pah831x_comm_burstread(0x60, (uint8_t*)&adc_data[8], 8);//CH_C\r
+    pah831x_comm_burstread(0x68, (uint8_t*)&adc_data[12], 8);//CH_D\r
+    pah831x_comm_burstread(0x32, (uint8_t*)&adc_data[16], 8);//CH_E\r
+    pah831x_comm_burstread(0x3A, (uint8_t*)&adc_data[20], 8);//CH_F        \r
+\r
+    for(i = 0 ;i < 12 ; i++)\r
+    {\r
+        if(PAH_CHECK_BIT(channel_en_bit,i)==1) \r
+        {\r
+            \r
+            adc_value_on = adc_data[2*i];\r
+            adc_value_off= adc_data[2*i+1];\r
+           \r
+            read_index_1 = 2*i+1;\r
+            read_index_2 = 2*i+2;\r
+            ppg_1_2 = (((read_index_1-1)>>1)&0x01)+1;\r
+            \r
+            if(g_state.test_spec_array[read_index_1][0])\r
+            {\r
+                if((test_mode==Light_Leak_Test_2_LED)||(test_mode==Light_Leak_Test_1_LED)||(test_mode==Check_Brightness_with_mechanical_cover_test_1_Side_A_1_LED)||(test_mode==Check_Brightness_with_mechanical_cover_test_2_Side_B_1_LED))\r
+                {\r
+                    if(adc_value_on>adc_value_off)\r
+                    {\r
+                        adc_value = adc_value_on-adc_value_off;\r
+                    }else\r
+                    {\r
+                        adc_value = 0 ; \r
+                    }\r
+                    LOG_PRINT("CH_%c_ppg%d     ,(min ,value,max)= ( %d ,%d , %d) \n",((read_index_1-1)/4)+65,ppg_1_2,g_state.test_spec_array[read_index_1][1],adc_value,g_state.test_spec_array[read_index_1][2]);\r
+                    if(( adc_value > g_state.test_spec_array[read_index_1][2])||(adc_value < g_state.test_spec_array[read_index_1][1]))\r
+                    {\r
+                        verify_result = false ;\r
+                        if (is_leak_light_test) {\r
+                            pah831x_leaklight_fail_str_append(\r
+                                "%c_%d ( %d ,%d , %d)\n",\r
+                                ((read_index_1 - 1) / 4) + 65, ppg_1_2,\r
+                                g_state.test_spec_array[read_index_1][1], adc_value,\r
+                                g_state.test_spec_array[read_index_1][2]);\r
+                        }\r
+                    }\r
+                }else\r
+                {                \r
+                    LOG_PRINT("CH_%c_ppg%d_on  ,(min ,value,max)= ( %d ,%d , %d) \n",((read_index_1-1)/4)+65,ppg_1_2,g_state.test_spec_array[read_index_1][1],adc_value_on,g_state.test_spec_array[read_index_1][2]);\r
+                    if(( adc_value_on > g_state.test_spec_array[read_index_1][2])||(adc_value_on < g_state.test_spec_array[read_index_1][1]))\r
+                    {\r
+                        verify_result = false ;\r
+                    }\r
+                }\r
+            }           \r
+            if(g_state.test_spec_array[read_index_2][0])\r
+            {\r
+                LOG_PRINT("CH_%c_ppg%d_off ,(min ,value,max)= ( %d ,%d , %d) \n",((read_index_1-1)/4)+65,ppg_1_2,g_state.test_spec_array[read_index_2][1],adc_value_off,g_state.test_spec_array[read_index_2][2]);\r
+                if(( adc_value_off > g_state.test_spec_array[read_index_2][2])||(adc_value_off < g_state.test_spec_array[read_index_2][1]))\r
+                {\r
+                    verify_result = false ;\r
+                    if (is_leak_light_test) {\r
+                        pah831x_leaklight_fail_str_append(\r
+                            "%c_%d_OFF ( %d ,%d , %d)\n",\r
+                            ((read_index_1 - 1) / 4) + 65, ppg_1_2,\r
+                            g_state.test_spec_array[read_index_2][1], adc_value_off,\r
+                            g_state.test_spec_array[read_index_2][2]);\r
+                    }\r
+                }\r
+            }\r
+        }\r
+    }\r
+    *touch  = touch_value ;\r
+    if(g_state.test_spec_array[0][0])\r
+    {\r
+        LOG_PRINT("CH T ,(min ,value,max)= ( %d ,%d , %d) \n",g_state.test_spec_array[0][1],*touch,g_state.test_spec_array[0][2]);\r
+        if(( *touch > g_state.test_spec_array[0][2])||(*touch < g_state.test_spec_array[0][1]))\r
+        {\r
+            verify_result = false ;\r
+            if (is_leak_light_test) {\r
+                pah831x_leaklight_fail_str_append(\r
+                    "T ( %d ,%d , %d)\n",\r
+                    g_state.test_spec_array[0][1], *touch, g_state.test_spec_array[0][2]);\r
+            }\r
+        }\r
+    }\r
+    pah831x_powerdown(); \r
+    return verify_result;\r
+}\r
+\r
+static bool pah831x_factory_test_Check_PPG_AFE_BUILT_IN(uint16_t *adc_data)\r
+{\r
+    uint16_t channel_en_bit = 0 ;\r
+    uint8_t channel_en_num = 0 ;\r
+    uint8_t i = 0 ;\r
+    uint16_t adc_value = 0 ;\r
+    uint16_t adc_value_offdac1 = 0 ;\r
+    uint16_t adc_value_offdac2 = 0 ;\r
+ \r
+    uint16_t adc_data_buf[8] ={0};\r
+\r
+    \r
+    \r
+    bool verify_result= true ;   \r
+    //=============================ppg_afe_built_in_test_offdac1===============================================//\r
+    \r
+    g_state.test_register_array=pah831x_verify_ppg_afe_built_in_test_offdac1;\r
+    g_state.test_register_array_length=sizeof(pah831x_verify_ppg_afe_built_in_test_offdac1)/2;\r
+    g_state.test_spec_array = PPG_AFE_BUILT_IN_TEST_Spec;\r
+    \r
+    g_state_cal.test_register_cal_array=pah831x_verify_ppg_afe_built_in_test;\r
+    g_state_cal.test_register_cal_array_length=sizeof(pah831x_verify_ppg_afe_built_in_test)/2;       \r
+\r
+    //=================================pah831x_verify_init=============================//\r
+    pah831x_startup();\r
+    pah831x_get_channel_num(g_state.test_register_array,g_state.test_register_array_length,&channel_en_num,&channel_en_bit);\r
+    pah831x_write_reg_array(g_state.test_register_array,g_state.test_register_array_length);\r
+    \r
+    //=================================pah831x_verify_init_cal=============================//\r
+\r
+    pah831x_write_reg_array(g_state_cal.test_register_cal_array,g_state_cal.test_register_cal_array_length);   \r
+    \r
+    pah831x_update_flag();\r
+    pah831x_start_tg();\r
+    pah831x_delay_ms(120);\r
+     //============================================================================//\r
+    \r
+    pah831x_comm_write(0x7f, 0x02);  //bank2\r
+    pah831x_comm_burstread(0x50, (uint8_t*)&adc_data[0], 2);//CH_A\r
+    pah831x_comm_burstread(0x58, (uint8_t*)&adc_data[2], 2);//CH_B\r
+    pah831x_comm_burstread(0x60, (uint8_t*)&adc_data[4], 2);//CH_C\r
+    pah831x_comm_burstread(0x68, (uint8_t*)&adc_data[6], 2);//CH_D\r
+    \r
+    pah831x_powerdown();    \r
+    \r
+    //=============================ppg_afe_built_in_test_offdac2===============================================//\r
+    pah831x_startup();\r
+    \r
+    g_state.test_register_array=pah831x_verify_ppg_afe_built_in_test_offdac2;\r
+    g_state.test_register_array_length=sizeof(pah831x_verify_ppg_afe_built_in_test_offdac2)/2;\r
+    g_state.test_spec_array = PPG_AFE_BUILT_IN_TEST_Spec;\r
+    \r
+    g_state_cal.test_register_cal_array=pah831x_verify_ppg_afe_built_in_test;\r
+    g_state_cal.test_register_cal_array_length=sizeof(pah831x_verify_ppg_afe_built_in_test)/2;       \r
+\r
+    //=================================pah831x_verify_init=============================//\r
+    pah831x_startup();\r
+    pah831x_get_channel_num(g_state.test_register_array,g_state.test_register_array_length,&channel_en_num,&channel_en_bit);\r
+    pah831x_write_reg_array(g_state.test_register_array,g_state.test_register_array_length);\r
+    \r
+    //=================================pah831x_verify_init_cal=============================//\r
+\r
+    // pah831x_write_reg_array(g_state_cal.test_register_cal_array,g_state_cal.test_register_cal_array_length);   \r
+    \r
+    pah831x_update_flag();\r
+    pah831x_start_tg();\r
+    pah831x_delay_ms(120);\r
+     //============================================================================//\r
+    \r
+    pah831x_comm_write(0x7f, 0x02);  //bank2\r
+    pah831x_comm_burstread(0x50, (uint8_t*)&adc_data[1], 2);//CH_A\r
+    pah831x_comm_burstread(0x58, (uint8_t*)&adc_data[3], 2);//CH_B\r
+    pah831x_comm_burstread(0x60, (uint8_t*)&adc_data[5], 2);//CH_C\r
+    pah831x_comm_burstread(0x68, (uint8_t*)&adc_data[7], 2);//CH_D\r
+\r
+    for(i = 0 ;i < 4 ; i++)\r
+    {\r
+        if(PAH_CHECK_BIT(channel_en_bit,i)==1) \r
+        {\r
+            \r
+            adc_value_offdac1 = adc_data[2*i];\r
+            adc_value_offdac2=  adc_data[2*i+1];\r
+            adc_value = adc_value_offdac2 -adc_value_offdac1 ;\r
+            adc_data[i]= adc_value ;\r
+            if(g_state.test_spec_array[i][0])\r
+            {\r
+                                \r
+                LOG_PRINT("CH_%c_ppg_on  ,(min ,value,max)= ( %d ,%d , %d) \n",i+65,g_state.test_spec_array[i][1],adc_value,g_state.test_spec_array[i][2]);\r
+                if(( adc_value > g_state.test_spec_array[i][2])||(adc_value < g_state.test_spec_array[i][1]))\r
+                {\r
+                    verify_result = false ;\r
+                }\r
+\r
+            }           \r
+\r
+        }\r
+    }\r
+\r
+    pah831x_powerdown(); \r
+    return verify_result;\r
+}\r
+\r
+\r
+int32_t cvt24bit(uint32_t val)\r
+{\r
+    val &= 0xffffff;  // limit to 24 bits -- may not be necessary\r
+    if (val >= ((uint32_t)1 << 23))\r
+        return (int32_t)val - ((uint32_t)1 << 24);\r
+    else\r
+        return val;\r
+}\r
+#define ECG_GAIN 20.6\r
+static float ADC_to_mV(int32_t ECG_mV)\r
+{\r
+    float ECG_mV_out = 0 ;\r
+    ECG_mV_out = (float)((ECG_mV - (63488*32))*2.4f*1000/(126976*32));\r
+    return ECG_mV_out ;\r
+}\r
+\r
+float ADC_to_mV_diff(int32_t ECG_mV)\r
+{\r
+    float ECG_mV_out = 0 ;\r
+    ECG_mV_out = (float)((ECG_mV )*2.4f*1000/(126976*32))/ECG_GAIN;\r
+    //return ECG_mV;\r
+    return ECG_mV_out ;\r
+}\r
+\r
+static bool pah831x_factory_test_Check_ECG_Waveform(uint32_t stop_time_ms)\r
+{\r
+    uint8_t data_buff[512] = {0}; \r
+    uint16_t i=0, j=0;\r
+    bool verify_result= true;\r
+    uint16_t fifo_read_num_per_sample = 0 ;\r
+    uint16_t fifo_read_num_per_sample_temp = 0 ;\r
+    uint16_t data_count = 0 ;\r
+    int32_t ECG_ADC_data[128]={0};\r
+    int32_t DATA_MAX=0;\r
+    int32_t DATA_MIN=0x7fffffff;\r
+    int32_t DATA_VPP=0;\r
+\r
+    float ECG_mV_MAX=0;\r
+    float ECG_mV_MIN=0;\r
+    float ECG_mV_VPP=0;\r
+    g_state.test_register_array=pah831x_verify_ECG_array_test;\r
+    g_state.test_register_array_length=sizeof(pah831x_verify_ECG_array_test)/2;\r
+    //=================================pah831x_verify_init=============================//\r
+    pah831x_startup();\r
+    pah831x_write_reg_array(g_state.test_register_array,g_state.test_register_array_length);\r
+    //=================================pah831x_verify_init=============================//\r
+    pah831x_update_flag();\r
+    pah831x_start_tg();\r
+    pah831x_delay_ms(200);\r
+\r
+    pah831x_comm_write(0x7f, 0x00);  //bank0\r
+    pah831x_comm_burstread(0x33, (uint8_t*)&fifo_read_num_per_sample,2);\r
+    fifo_read_num_per_sample_temp = fifo_read_num_per_sample;\r
+    pah831x_comm_write(0x7A, 0x01);\r
+    pah831x_comm_burstread(0x7b, data_buff, fifo_read_num_per_sample*5);\r
+    pah831x_comm_write(0x7A, 0x00);\r
+    LOG_PRINT("fifo_read_num_per_sample =%d \n",fifo_read_num_per_sample);\r
+    for(i = 0; i < fifo_read_num_per_sample; i++)\r
+    {\r
+        ECG_ADC_data[i]=cvt24bit((uint32_t)(data_buff[i * 5 + 4]<<16)+(data_buff[i * 5 + 3]<<8)+(data_buff[i * 5 + 2]));\r
+    }\r
+    \r
+    for(j = 15; j < fifo_read_num_per_sample; j++)\r
+    {\r
+        LOG_PRINT("ECG_ADC_data[%d] =%d \n",j,ECG_ADC_data[j]);\r
+        DATA_MAX = (ECG_ADC_data[j] >= DATA_MAX) ? ECG_ADC_data[j] : DATA_MAX;\r
+        DATA_MIN = (ECG_ADC_data[j] <= DATA_MIN) ? ECG_ADC_data[j] : DATA_MIN;\r
+    }\r
+    DATA_VPP= DATA_MAX - DATA_MIN;\r
+\r
+    ECG_mV_MAX=ADC_to_mV(DATA_MAX)/ECG_GAIN;\r
+    ECG_mV_MIN=ADC_to_mV(DATA_MIN)/ECG_GAIN;\r
+\r
+    ECG_mV_VPP = (ECG_mV_MAX- ECG_mV_MIN);\r
+\r
+    LOG_PRINT("ECG_mV_MAX =%f ,ECG_mV_MIN =%f ,ECG_mV_VPP = %f,\n",ECG_mV_MAX,ECG_mV_MIN,ECG_mV_VPP);\r
+    \r
+    pah831x_delay_ms(stop_time_ms);\r
+    pah831x_powerdown();\r
+    if(( ECG_mV_VPP > 55.0f)||(ECG_mV_VPP < 45.0f))\r
+    {\r
+        verify_result = false ;\r
+    }\r
+\r
+    return verify_result;\r
+\r
+}\r
+\r
+static bool pah831x_factory_test_Check_ECG_DC(uint32_t stop_time_ms)\r
+{\r
+    uint8_t data_buff[512] = {0}; \r
+    uint16_t i=0, j=0;\r
+    bool verify_result= true;\r
+    uint16_t fifo_read_num_per_sample = 0 ;\r
+    uint16_t fifo_read_num_per_sample_temp = 0 ;\r
+    uint16_t data_count = 0 ;\r
+    int32_t ECG_ADC_data[128]={0};\r
+    int32_t DATA_MAX=0;\r
+    int32_t DATA_MIN=0x7fffffff;\r
+    int32_t DATA_VPP=0;\r
+    float ECG_mV_MAX=0;\r
+    float ECG_mV_MIN=0;\r
+    float ECG_mV_VPP=0;\r
+    g_state.test_register_array=pah831x_verify_ECG_array_test_DC;\r
+    g_state.test_register_array_length=sizeof(pah831x_verify_ECG_array_test_DC)/2;\r
+\r
+    //=================================pah831x_verify_init=============================//\r
+    pah831x_startup();\r
+    pah831x_write_reg_array(g_state.test_register_array,g_state.test_register_array_length);\r
+    //=================================pah831x_verify_init=============================//\r
+    pah831x_update_flag();\r
+    pah831x_start_tg();\r
+    pah831x_delay_ms(200);\r
+\r
+    pah831x_comm_write(0x7f, 0x00);  //bank0\r
+\r
+    pah831x_comm_burstread(0x33, (uint8_t*)&fifo_read_num_per_sample,2);\r
+    fifo_read_num_per_sample_temp = fifo_read_num_per_sample;\r
+    pah831x_comm_write(0x7A, 0x01);\r
+    pah831x_comm_burstread(0x7b, data_buff, fifo_read_num_per_sample*5);\r
+    pah831x_comm_write(0x7A, 0x00);\r
+    LOG_PRINT("fifo_read_num_per_sample =%d \n",fifo_read_num_per_sample);\r
+    for(i = 0; i < fifo_read_num_per_sample; i++)\r
+    {\r
+        ECG_ADC_data[i]=cvt24bit((uint32_t)(data_buff[i * 5 + 4]<<16)+(data_buff[i * 5 + 3]<<8)+(data_buff[i * 5 + 2]));\r
+    }\r
+    \r
+    for(j = 15; j < fifo_read_num_per_sample; j++)\r
+    {\r
+        LOG_PRINT("ECG_ADC_data[%d] =%d \n",j,ECG_ADC_data[j]);\r
+        DATA_MAX = (ECG_ADC_data[j] >= DATA_MAX) ? ECG_ADC_data[j] : DATA_MAX;\r
+        DATA_MIN = (ECG_ADC_data[j] <= DATA_MIN) ? ECG_ADC_data[j] : DATA_MIN;\r
+    }\r
+    DATA_VPP= DATA_MAX - DATA_MIN;\r
+\r
+    ECG_mV_MAX=ADC_to_mV(DATA_MAX);\r
+    ECG_mV_MIN=ADC_to_mV(DATA_MIN);\r
+\r
+    LOG_PRINT("ECG_mV_MAX =%f ,ECG_mV_MIN =%f \n",ECG_mV_MAX,ECG_mV_MIN);\r
+\r
+    pah831x_delay_ms(stop_time_ms);\r
+    pah831x_powerdown();\r
+    if(( ECG_mV_MAX > 660.0f)||(ECG_mV_MIN <540.0f))\r
+    {\r
+        verify_result = false ;\r
+    }\r
+\r
+    return verify_result;\r
+\r
+}\r
+static bool pah831x_factory_test_ECG_LL_TO_LA(uint8_t test_mode ,uint8_t* data_out)\r
+{\r
+    bool verify_result= true ;\r
+    uint8_t data_temp = 0 ;\r
+    uint8_t data_0x2F = 0 ;\r
+    pah831x_startup();\r
+    if((test_mode==Check_ECG_LL_TO_LA_STEP1)||(test_mode==Check_ECG_LL_TO_LA_STEP2))\r
+    {\r
+        pah831x_write_reg_array(pah831x_verify_ecg_ft1,sizeof(pah831x_verify_ecg_ft1)/2);\r
+    }else  if(test_mode==Check_ECG_LL_TO_LA_STEP3)\r
+    {\r
+        pah831x_write_reg_array(pah831x_verify_ecg_ft2,sizeof(pah831x_verify_ecg_ft2)/2);\r
+    }\r
+    pah831x_update_flag();\r
+    pah831x_start_tg();\r
+    pah831x_delay_ms(500);\r
+    \r
+    pah831x_comm_write(0x7f, 0x00);   //bank0\r
+    \r
+    pah831x_comm_read(0x2F,&data_temp);\r
+    \r
+    data_0x2F = data_temp&0x01 ;\r
+     \r
+    LOG_PRINT("data_0x2F  %d\n",data_0x2F);\r
+    \r
+\r
+\r
+    if((test_mode==Check_ECG_LL_TO_LA_STEP1)||(test_mode==Check_ECG_LL_TO_LA_STEP3))\r
+    {     \r
+        verify_result=  data_0x2F==1 ? true : false;\r
+\r
+    }else  if(test_mode==Check_ECG_LL_TO_LA_STEP2)\r
+    {\r
+        verify_result=  data_0x2F==0 ? true : false;\r
+    }\r
+    *data_out = data_0x2F;\r
+    \r
+    pah831x_powerdown();\r
+    return verify_result ;\r
+}\r
+static bool pah831x_factory_test_ECG_LL_TO_RA(uint8_t test_mode ,uint8_t* data_out)\r
+{\r
+    bool verify_result= true ;\r
+    pah831x_startup();\r
+    if((test_mode==Check_ECG_LL_TO_RA_STEP1)||(test_mode==Check_ECG_LL_TO_RA_STEP2))\r
+    {\r
+        pah831x_write_reg_array(pah831x_verify_ecg_ft1,sizeof(pah831x_verify_ecg_ft1)/2);\r
+    }else  if(test_mode==Check_ECG_LL_TO_RA_STEP3)\r
+    {\r
+        pah831x_write_reg_array(pah831x_verify_ecg_ft2,sizeof(pah831x_verify_ecg_ft2)/2);\r
+    }\r
+    pah831x_update_flag();\r
+    pah831x_start_tg();\r
+    pah831x_delay_ms(500);\r
+    \r
+    pah831x_comm_write(0x7f, 0x00);   //bank0\r
+    uint8_t data_temp = 0 ;\r
+    uint8_t data_0x2F = 0 ;\r
+    pah831x_comm_read(0x2F,&data_temp);\r
+    \r
+    data_0x2F = (data_temp>>3)&0x01 ;\r
+     \r
+    LOG_PRINT("data_0x2F  %d\n",data_0x2F);\r
+\r
+    if((test_mode==Check_ECG_LL_TO_RA_STEP1)||(test_mode==Check_ECG_LL_TO_RA_STEP3))\r
+    {     \r
+        verify_result=  data_0x2F==1 ? true : false;\r
+\r
+    }else  if(test_mode==Check_ECG_LL_TO_RA_STEP2)\r
+    {\r
+        verify_result=  data_0x2F==0 ? true : false;\r
+    }\r
+    *data_out = data_0x2F;\r
+    \r
+    pah831x_powerdown();\r
+    return verify_result ;\r
+}\r
+\r
+\r
+void demo_factory_mode(pah831x_factory_test_e test_mode)\r
+{\r
+    uint32_t  touch;\r
+    uint16_t int1_low ,int1_high , int2_low ,int2_high;\r
+    uint16_t adc_data[25]={0} ;\r
+    uint8_t data_out = 0;\r
+    uint8_t data_out_b0 = 0;\r
+    uint8_t data_out_b3 = 0;\r
+\r
+    uint16_t sensor_pid = 0 ;\r
+    pah831x_read_id(&sensor_pid);\r
+\r
+    if(sensor_pid==0x8311)\r
+    {\r
+        LOG_PRINT("ID Check Success. Sensor_pid = 0x%x \n",sensor_pid);\r
+    }\r
+    else\r
+    {\r
+        LOG_PRINT("ID Check Fail.    Sensor_pid = 0x%x \n",sensor_pid);\r
+        return;\r
+    }\r
+    LOG_PRINT("PAH831X_VERIFY_REG_VERSION = 0x%x \n",get_pah813x_verify_reg_version());\r
+\r
+    bool verify_result = true ;\r
+    memset(&g_state, 0, sizeof(g_state));\r
+    switch(test_mode)\r
+    {\r
+        case  Check_Brightness_PCB_Only_test_1_Side_A_2_LED:\r
+            LOG_PRINT("//----Check_Brightness_PCB_Only_test_1_Side_A_2_LED--// \n");\r
+            verify_result = pah831x_factory_test_Check_ADC(test_mode ,&touch, adc_data);\r
+            if(verify_result) \r
+            {\r
+                LOG_PRINT("TEST Pass \n");\r
+            }else\r
+            {\r
+                LOG_PRINT("TEST Fail \n");\r
+            }\r
+        break;\r
+           case  Check_Brightness_PCB_Only_test_2_Side_B_2_LED:\r
+            LOG_PRINT("//----Check_Brightness_PCB_Only_test_2_Side_B_2_LED--// \n");\r
+            verify_result = pah831x_factory_test_Check_ADC(test_mode ,&touch, adc_data);\r
+            if(verify_result) \r
+            {\r
+                LOG_PRINT("TEST Pass \n");\r
+            }else\r
+            {\r
+                LOG_PRINT("TEST Fail \n");\r
+            }\r
+        break;\r
+            case  Check_Brightness_PCB_Only_test_1_Side_A_1_LED:\r
+            LOG_PRINT("//----Check_Brightness_PCB_Only_test_1_Side_A_1_LED--// \n");\r
+            verify_result = pah831x_factory_test_Check_ADC(test_mode ,&touch, adc_data);\r
+            if(verify_result) \r
+            {\r
+                LOG_PRINT("TEST Pass \n");\r
+            }else\r
+            {\r
+                LOG_PRINT("TEST Fail \n");\r
+            }\r
+        break;\r
+           case  Check_Brightness_PCB_Only_test_2_Side_B_1_LED:\r
+            LOG_PRINT("//----Check_Brightness_PCB_Only_test_2_Side_B_1_LED--// \n");\r
+            verify_result = pah831x_factory_test_Check_ADC(test_mode ,&touch, adc_data);\r
+            if(verify_result) \r
+            {\r
+                LOG_PRINT("TEST Pass \n");\r
+            }else\r
+            {\r
+                LOG_PRINT("TEST Fail \n");\r
+            }\r
+        break;\r
+        case INT_TEST:\r
+            LOG_PRINT("//----INT_TEST----// \n");\r
+            verify_result = pah831x_factory_test_INT(&int1_low,&int1_high,&int2_low,&int2_high);\r
+            if(verify_result) \r
+            {\r
+                LOG_PRINT("TEST Pass \n");\r
+            }else\r
+            {\r
+                LOG_PRINT("TEST Fail \n");\r
+            }\r
+        break;\r
+        case Check_Brightness_with_mechanical_cover_test_1_Side_A_2_LED:\r
+            LOG_PRINT("//----Check_Brightness_with_mechanical_cover_test_1_Side_A_2_LED----// \n");\r
+            verify_result = pah831x_factory_test_Check_ADC(test_mode ,&touch, adc_data);\r
+            if(verify_result) \r
+            {\r
+                LOG_PRINT("TEST Pass \n");\r
+            }else\r
+            {\r
+                LOG_PRINT("TEST Fail \n");\r
+            }\r
+        break;\r
+        case Check_Brightness_with_mechanical_cover_test_2_Side_B_2_LED:\r
+            LOG_PRINT("//----Check_Brightness_with_mechanical_cover_test_2_Side_B_2_LED----// \n");\r
+            verify_result = pah831x_factory_test_Check_ADC(test_mode ,&touch, adc_data);\r
+            if(verify_result) \r
+            {\r
+                LOG_PRINT("TEST Pass \n");\r
+            }else\r
+            {\r
+                LOG_PRINT("TEST Fail \n");\r
+            }\r
+        break;\r
+        case Check_Brightness_with_mechanical_cover_test_1_Side_A_1_LED:\r
+            LOG_PRINT("//----Check_Brightness_with_mechanical_cover_test_1_Side_A_1_LED----// \n");\r
+            verify_result = pah831x_factory_test_Check_ADC(test_mode ,&touch, adc_data);\r
+            if(verify_result) \r
+            {\r
+                LOG_PRINT("TEST Pass \n");\r
+            }else\r
+            {\r
+                LOG_PRINT("TEST Fail \n");\r
+            }\r
+        break;\r
+        case Check_Brightness_with_mechanical_cover_test_2_Side_B_1_LED:\r
+            LOG_PRINT("//----Check_Brightness_with_mechanical_cover_test_2_Side_B_1_LED----// \n");\r
+            verify_result = pah831x_factory_test_Check_ADC(test_mode ,&touch, adc_data);\r
+            if(verify_result) \r
+            {\r
+                LOG_PRINT("TEST Pass \n");\r
+            }else\r
+            {\r
+                LOG_PRINT("TEST Fail \n");\r
+            }\r
+        break;\r
+        case Light_Leak_Test_2_LED:\r
+            LOG_PRINT("//----Light_Leak_Test_2_LED----// \n");\r
+            verify_result = pah831x_factory_test_Check_ADC(test_mode ,&touch, adc_data);\r
+            if(verify_result) \r
+            {\r
+                LOG_PRINT("TEST Pass \n");\r
+            }else\r
+            {\r
+                LOG_PRINT("TEST Fail \n\n");\r
+            }       \r
+        break;\r
+        case Light_Leak_Test_1_LED:\r
+            LOG_PRINT("//----Light_Leak_Test_1_LED----// \n");\r
+            verify_result = pah831x_factory_test_Check_ADC(test_mode ,&touch, adc_data);\r
+            if(verify_result) \r
+            {\r
+                LOG_PRINT("TEST Pass \n");\r
+            }else\r
+            {\r
+                LOG_PRINT("TEST Fail \n\n");\r
+            }       \r
+        break;\r
+        case Check_PPG_AFE_BUILT_IN_TEST:\r
+            LOG_PRINT("//----Check_PPG_AFE_BUILT_IN_TEST----// \n");\r
+            verify_result = pah831x_factory_test_Check_PPG_AFE_BUILT_IN(adc_data);\r
+            if(verify_result) \r
+            {\r
+                LOG_PRINT("TEST Pass \n");\r
+            }else\r
+            {\r
+                LOG_PRINT("TEST Fail \n\n");\r
+            }       \r
+        break;\r
+        case Check_ECG_WAVEFORM_TEST:\r
+            LOG_PRINT("//----ECG_Waveform_Test----// \n");\r
+            verify_result = pah831x_factory_test_Check_ECG_Waveform(1000);//set delay time ms for LL PIN Test\r
+            if(verify_result) \r
+            {\r
+                LOG_PRINT("TEST Pass \n");\r
+            }else\r
+            {\r
+                LOG_PRINT("TEST Fail \n\n");\r
+            }       \r
+        break;\r
+        case Check_ECG_DC_TEST:\r
+            LOG_PRINT("//----ECG_DC_Test----// \n");\r
+            verify_result = pah831x_factory_test_Check_ECG_DC(1000);//set delay time ms for LL PIN Test\r
+            if(verify_result) \r
+            {\r
+                LOG_PRINT("TEST Pass \n");\r
+            }else\r
+            {\r
+                LOG_PRINT("TEST Fail \n\n");\r
+            }       \r
+        break;\r
+        case Check_ECG_LL_TO_LA_STEP1:\r
+            LOG_PRINT("//----Check_ECG_LL_TO_LA_STEP1----// \n");\r
+            verify_result = pah831x_factory_test_ECG_LL_TO_LA(Check_ECG_LL_TO_LA_STEP1 ,&data_out);\r
+            if(verify_result) \r
+            {\r
+                LOG_PRINT("TEST Pass \n\n");\r
+            }else\r
+            {\r
+                LOG_PRINT("TEST Fail \n\n");\r
+            }       \r
+        break;  \r
+        case Check_ECG_LL_TO_LA_STEP2:\r
+            LOG_PRINT("//----Check_ECG_LL_TO_LA_STEP2----// \n");\r
+            verify_result = pah831x_factory_test_ECG_LL_TO_LA(Check_ECG_LL_TO_LA_STEP2 ,&data_out);\r
+            if(verify_result) \r
+            {\r
+                LOG_PRINT("TEST Pass \n\n");\r
+            }else\r
+            {\r
+                LOG_PRINT("TEST Fail \n\n");\r
+            }       \r
+        break; \r
+        case Check_ECG_LL_TO_LA_STEP3:\r
+            LOG_PRINT("//----Check_ECG_LL_TO_LA_STEP3----// \n");\r
+            verify_result = pah831x_factory_test_ECG_LL_TO_LA(Check_ECG_LL_TO_LA_STEP3 ,&data_out);\r
+            if(verify_result) \r
+            {\r
+                LOG_PRINT("TEST Pass \n\n");\r
+            }else\r
+            {\r
+                LOG_PRINT("TEST Fail \n\n");\r
+            }       \r
+        break;  \r
+        case Check_ECG_LL_TO_RA_STEP1:\r
+            LOG_PRINT("//----Check_ECG_LL_TO_RA_STEP1----// \n");\r
+            verify_result = pah831x_factory_test_ECG_LL_TO_RA(Check_ECG_LL_TO_RA_STEP1 ,&data_out);\r
+            if(verify_result) \r
+            {\r
+                LOG_PRINT("TEST Pass \n\n");\r
+            }else\r
+            {\r
+                LOG_PRINT("TEST Fail \n\n");\r
+            }       \r
+        break;    \r
+        case Check_ECG_LL_TO_RA_STEP2:\r
+            LOG_PRINT("//----Check_ECG_LL_TO_RA_STEP2----// \n");\r
+            verify_result = pah831x_factory_test_ECG_LL_TO_RA(Check_ECG_LL_TO_RA_STEP2 ,&data_out);\r
+            if(verify_result) \r
+            {\r
+                LOG_PRINT("TEST Pass \n\n");\r
+            }else\r
+            {\r
+                LOG_PRINT("TEST Fail \n\n");\r
+            }       \r
+        break;    \r
+        case Check_ECG_LL_TO_RA_STEP3:\r
+            LOG_PRINT("//----Check_ECG_LL_TO_RA_STEP3----// \n");\r
+            verify_result = pah831x_factory_test_ECG_LL_TO_RA(Check_ECG_LL_TO_RA_STEP3 ,&data_out);\r
+            if(verify_result) \r
+            {\r
+                LOG_PRINT("TEST Pass \n\n");\r
+            }else\r
+            {\r
+                LOG_PRINT("TEST Fail \n\n");\r
+            }       \r
+        break;  \r
+        case Factory_Test_Stop:\r
+            LOG_PRINT("//----Factory_Test_Stop----// \n");\r
+            pah831x_powerdown();\r
+      \r
+        break;            \r
+        default:\r
+            LOG_PRINT("Not implemented yet \n");\r
+    }\r
+\r
+    pah831x_delay_ms(150);\r
+}\r
diff --git a/code/sdk/zhihui/drivers/ppg/pah831x/pah831x_factory_20251217/pah831x_factory_test_v3.h b/code/sdk/zhihui/drivers/ppg/pah831x/pah831x_factory_20251217/pah831x_factory_test_v3.h
new file mode 100644 (file)
index 0000000..59f09f3
--- /dev/null
@@ -0,0 +1,406 @@
+#ifndef __pah831x_factory_test_V3_H\r
+#define __pah831x_factory_test_V3_H\r
+\r
+// c\r
+#include <string.h>\r
+#include <stdlib.h>\r
+#include <stdint.h>\r
+#include <stdbool.h>\r
+#include <stdlib.h>\r
+\r
+// #define ENABLE_LOG_PRINT\r
+// #ifdef ENABLE_LOG_PRINT\r
+// #define LOG_PRINT(fmt, ...)                    \\r
+//     do {                                      \\r
+//         printf(fmt"PAH831X:", ##__VA_ARGS__);     \\r
+//     } while (0)\r
+// #else\r
+// #define LOG_PRINT(...) do {} while (0)\r
+// #endif\r
+\r
+\r
+typedef enum {\r
+\r
+    pah_verify_ch_t,\r
+    pah_verify_ch_a,\r
+    pah_verify_ch_b,\r
+    pah_verify_ch_c,\r
+       pah_verify_ch_d,\r
+    pah_verify_ch_num,\r
+\r
+} pah_verify_ch_e;\r
+\r
+\r
+typedef struct {\r
+\r
+    uint16_t    value;\r
+\r
+    uint16_t    min;\r
+    bool        min_enabled_verify;\r
+    bool        min_verified_success;\r
+\r
+    uint16_t    max;\r
+    bool        max_enabled_verify;\r
+    bool        max_verified_success;\r
+\r
+} pah_verify_ch_adc_data_s;\r
+\r
+\r
+typedef struct {\r
+\r
+    pah_verify_ch_adc_data_s ch_adc_data[pah_verify_ch_num];\r
+\r
+} pah_verify_adc_data_s;\r
+\r
+\r
+static const uint16_t Brightness_PCB_Only_Spec_test_1_Side_A_2_LED[][3]=\r
+{\r
+{0,  2500,  7500}, //check_ch_t_ppg_en      ,Brightness_PCB_Only_touch_min    , Brightness_PCB_Only_touch_min\r
+{1, 32000, 63488}, //check_ch_a_ppg1_on_en ,Brightness_PCB_Only_ch_a_ppg1_on_min , Brightness_PCB_Only_ch_a_ppg1_on_max\r
+{1, 31000, 32000}, //check_ch_a_ppg1_off_en,Brightness_PCB_Only_ch_a_ppg1_off_min, Brightness_PCB_Only_ch_a_ppg1_off_max\r
+{1, 32000, 63488}, //check_ch_a_ppg2_on_en ,Brightness_PCB_Only_ch_a_ppg2_on_min , Brightness_PCB_Only_ch_a_ppg2_on_max\r
+{1, 31000, 32000}, //check_ch_a_ppg2_off_en,Brightness_PCB_Only_ch_a_ppg2_off_min, Brightness_PCB_Only_ch_a_ppg2_off_max\r
+{1, 32000, 63488}, //check_ch_b_ppg1_on_en ,Brightness_PCB_Only_ch_b_ppg1_on_min , Brightness_PCB_Only_ch_b_ppg1_on_max\r
+{1, 31000, 32000}, //check_ch_b_ppg1_off_en,Brightness_PCB_Only_ch_b_ppg1_off_min, Brightness_PCB_Only_ch_b_ppg1_off_max\r
+{1, 32000, 63488}, //check_ch_b_ppg2_on_en ,Brightness_PCB_Only_ch_b_ppg2_on_min , Brightness_PCB_Only_ch_b_ppg2_on_max\r
+{1, 31000, 32000}, //check_ch_b_ppg2_off_en,Brightness_PCB_Only_ch_b_ppg2_off_min, Brightness_PCB_Only_ch_b_ppg2_off_max\r
+{1, 32000, 63488}, //check_ch_c_ppg1_on_en ,Brightness_PCB_Only_ch_c_ppg1_on_min , Brightness_PCB_Only_ch_c_ppg1_on_max\r
+{1, 31000, 32000}, //check_ch_c_ppg1_off_en,Brightness_PCB_Only_ch_c_ppg1_off_min, Brightness_PCB_Only_ch_c_ppg1_off_max\r
+{1, 32000, 63488}, //check_ch_c_ppg2_on_en ,Brightness_PCB_Only_ch_c_ppg2_on_min , Brightness_PCB_Only_ch_c_ppg2_on_max\r
+{1, 31000, 32000}, //check_ch_c_ppg2_off_en,Brightness_PCB_Only_ch_c_ppg2_off_min, Brightness_PCB_Only_ch_c_ppg2_off_max\r
+{0, 32000, 63488}, //check_ch_d_ppg1_on_en ,Brightness_PCB_Only_ch_d_ppg1_on_min , Brightness_PCB_Only_ch_d_ppg1_on_max\r
+{0, 31000, 32000}, //check_ch_d_ppg1_off_en,Brightness_PCB_Only_ch_d_ppg1_off_min, Brightness_PCB_Only_ch_d_ppg1_off_max\r
+{0, 32000, 63488}, //check_ch_d_ppg2_on_en ,Brightness_PCB_Only_ch_d_ppg2_on_min , Brightness_PCB_Only_ch_d_ppg2_on_max\r
+{0, 31000, 32000}, //check_ch_d_ppg2_off_en,Brightness_PCB_Only_ch_d_ppg2_off_min, Brightness_PCB_Only_ch_d_ppg2_off_max\r
+{0, 32000, 63488}, //check_ch_e_ppg1_on_en ,Brightness_PCB_Only_ch_e_ppg1_on_min , Brightness_PCB_Only_ch_e_ppg1_on_max\r
+{0, 31000, 32000}, //check_ch_e_ppg1_off_en,Brightness_PCB_Only_ch_e_ppg1_off_min, Brightness_PCB_Only_ch_e_ppg1_off_max\r
+{0, 32000, 63488}, //check_ch_e_ppg2_on_en ,Brightness_PCB_Only_ch_e_ppg2_on_min , Brightness_PCB_Only_ch_e_ppg2_on_max\r
+{0, 31000, 32000}, //check_ch_e_ppg2_off_en,Brightness_PCB_Only_ch_e_ppg2_off_min, Brightness_PCB_Only_ch_e_ppg2_off_max\r
+{0, 32000, 63488}, //check_ch_f_ppg1_on_en ,Brightness_PCB_Only_ch_f_ppg1_on_min , Brightness_PCB_Only_ch_f_ppg1_on_max\r
+{0, 31000, 32000}, //check_ch_f_ppg1_off_en,Brightness_PCB_Only_ch_f_ppg1_off_min, Brightness_PCB_Only_ch_f_ppg1_off_max\r
+{0, 32000, 63488}, //check_ch_f_ppg2_on_en ,Brightness_PCB_Only_ch_f_ppg2_on_min , Brightness_PCB_Only_ch_f_ppg2_on_max\r
+{0, 31000, 32000}, //check_ch_f_ppg2_off_en,Brightness_PCB_Only_ch_f_ppg2_off_min, Brightness_PCB_Only_ch_f_ppg2_off_max\r
+\r
+};\r
+\r
+static const uint16_t Brightness_PCB_Only_Spec_test_2_Side_B_2_LED[][3]=\r
+{\r
+{0,  2500,  7500}, //check_ch_t_ppg_en      ,Brightness_PCB_Only_touch_min    , Brightness_PCB_Only_touch_min\r
+{0, 32000, 63488}, //check_ch_a_ppg1_on_en ,Brightness_PCB_Only_ch_a_ppg1_on_min , Brightness_PCB_Only_ch_a_ppg1_on_max\r
+{0, 31000, 32000}, //check_ch_a_ppg1_off_en,Brightness_PCB_Only_ch_a_ppg1_off_min, Brightness_PCB_Only_ch_a_ppg1_off_max\r
+{0, 32000, 63488}, //check_ch_a_ppg2_on_en ,Brightness_PCB_Only_ch_a_ppg2_on_min , Brightness_PCB_Only_ch_a_ppg2_on_max\r
+{0, 31000, 32000}, //check_ch_a_ppg2_off_en,Brightness_PCB_Only_ch_a_ppg2_off_min, Brightness_PCB_Only_ch_a_ppg2_off_max\r
+{0, 32000, 63488}, //check_ch_b_ppg1_on_en ,Brightness_PCB_Only_ch_b_ppg1_on_min , Brightness_PCB_Only_ch_b_ppg1_on_max\r
+{0, 31000, 32000}, //check_ch_b_ppg1_off_en,Brightness_PCB_Only_ch_b_ppg1_off_min, Brightness_PCB_Only_ch_b_ppg1_off_max\r
+{0, 32000, 63488}, //check_ch_b_ppg2_on_en ,Brightness_PCB_Only_ch_b_ppg2_on_min , Brightness_PCB_Only_ch_b_ppg2_on_max\r
+{0, 31000, 32000}, //check_ch_b_ppg2_off_en,Brightness_PCB_Only_ch_b_ppg2_off_min, Brightness_PCB_Only_ch_b_ppg2_off_max\r
+{0, 32000, 63488}, //check_ch_c_ppg1_on_en ,Brightness_PCB_Only_ch_c_ppg1_on_min , Brightness_PCB_Only_ch_c_ppg1_on_max\r
+{0, 31000, 32000}, //check_ch_c_ppg1_off_en,Brightness_PCB_Only_ch_c_ppg1_off_min, Brightness_PCB_Only_ch_c_ppg1_off_max\r
+{0, 32000, 63488}, //check_ch_c_ppg2_on_en ,Brightness_PCB_Only_ch_c_ppg2_on_min , Brightness_PCB_Only_ch_c_ppg2_on_max\r
+{0, 31000, 32000}, //check_ch_c_ppg2_off_en,Brightness_PCB_Only_ch_c_ppg2_off_min, Brightness_PCB_Only_ch_c_ppg2_off_max\r
+{1, 32000, 63488}, //check_ch_d_ppg1_on_en ,Brightness_PCB_Only_ch_d_ppg1_on_min , Brightness_PCB_Only_ch_d_ppg1_on_max\r
+{1, 31000, 32000}, //check_ch_d_ppg1_off_en,Brightness_PCB_Only_ch_d_ppg1_off_min, Brightness_PCB_Only_ch_d_ppg1_off_max\r
+{1, 32000, 63488}, //check_ch_d_ppg2_on_en ,Brightness_PCB_Only_ch_d_ppg2_on_min , Brightness_PCB_Only_ch_d_ppg2_on_max\r
+{1, 31000, 32000}, //check_ch_d_ppg2_off_en,Brightness_PCB_Only_ch_d_ppg2_off_min, Brightness_PCB_Only_ch_d_ppg2_off_max\r
+{1, 32000, 63488}, //check_ch_e_ppg1_on_en ,Brightness_PCB_Only_ch_e_ppg1_on_min , Brightness_PCB_Only_ch_e_ppg1_on_max\r
+{1, 31000, 32000}, //check_ch_e_ppg1_off_en,Brightness_PCB_Only_ch_e_ppg1_off_min, Brightness_PCB_Only_ch_e_ppg1_off_max\r
+{1, 32000, 63488}, //check_ch_e_ppg2_on_en ,Brightness_PCB_Only_ch_e_ppg2_on_min , Brightness_PCB_Only_ch_e_ppg2_on_max\r
+{1, 31000, 32000}, //check_ch_e_ppg2_off_en,Brightness_PCB_Only_ch_e_ppg2_off_min, Brightness_PCB_Only_ch_e_ppg2_off_max\r
+{1, 32000, 63488}, //check_ch_f_ppg1_on_en ,Brightness_PCB_Only_ch_f_ppg1_on_min , Brightness_PCB_Only_ch_f_ppg1_on_max\r
+{1, 31000, 32000}, //check_ch_f_ppg1_off_en,Brightness_PCB_Only_ch_f_ppg1_off_min, Brightness_PCB_Only_ch_f_ppg1_off_max\r
+{1, 32000, 63488}, //check_ch_f_ppg2_on_en ,Brightness_PCB_Only_ch_f_ppg2_on_min , Brightness_PCB_Only_ch_f_ppg2_on_max\r
+{1, 31000, 32000}, //check_ch_f_ppg2_off_en,Brightness_PCB_Only_ch_f_ppg2_off_min, Brightness_PCB_Only_ch_f_ppg2_off_max\r
+\r
+};\r
+\r
+\r
+static const uint16_t Brightness_with_cover_Spec_test_1_Side_A_2_LED[][3]=\r
+{\r
+{1,  1700,  7800}, //check_ch_t_ppg_en     ,Brightness_with_cover_touch_min         , Brightness_with_cover_touch_min      \r
+{1,  7500, 30000}, //check_ch_a_ppg1_en    ,Brightness_with_cover_ch_a_ppg1_min     , Brightness_with_cover_ch_a_ppg1_max\r
+{1, 31000, 32000}, //check_ch_a_ppg1_off_en,Brightness_with_cover_ch_a_ppg1_off_min , Brightness_with_cover_ch_a_ppg1_off_max\r
+{1,  7500, 30000}, //check_ch_a_ppg2_en    ,Brightness_with_cover_ch_a_ppg2_min     , Brightness_with_cover_ch_a_ppg2_max\r
+{1, 31000, 32000}, //check_ch_a_ppg2_off_en,Brightness_with_cover_ch_a_ppg2_off_min , Brightness_with_cover_ch_a_ppg2_off_max\r
+{1,  7500, 30000}, //check_ch_b_ppg1_en    ,Brightness_with_cover_ch_b_ppg1_min     , Brightness_with_cover_ch_b_ppg1_max\r
+{1, 31000, 32000}, //check_ch_b_ppg1_off_en,Brightness_with_cover_ch_b_ppg1_off_min , Brightness_with_cover_ch_b_ppg1_off_max\r
+{1,  7500, 30000}, //check_ch_b_ppg2_en    ,Brightness_with_cover_ch_b_ppg2_min     , Brightness_with_cover_ch_b_ppg2_max\r
+{1, 31000, 32000}, //check_ch_b_ppg2_off_en,Brightness_with_cover_ch_b_ppg2_off_min , Brightness_with_cover_ch_b_ppg2_off_max\r
+{1,  7500, 30000}, //check_ch_c_ppg1_en    ,Brightness_with_cover_ch_c_ppg1_min     , Brightness_with_cover_ch_c_ppg1_max\r
+{1, 31000, 32000}, //check_ch_c_ppg1_off_en,Brightness_with_cover_ch_c_ppg1_off_min , Brightness_with_cover_ch_c_ppg1_off_max\r
+{1,  7500, 30000}, //check_ch_c_ppg2_en    ,Brightness_with_cover_ch_c_ppg2_min     , Brightness_with_cover_ch_c_ppg2_max\r
+{1, 31000, 32000}, //check_ch_c_ppg2_off_en,Brightness_with_cover_ch_c_ppg2_off_min , Brightness_with_cover_ch_c_ppg2_off_max\r
+{0,  7500, 30000}, //check_ch_d_ppg1_en    ,Brightness_with_cover_ch_d_ppg1_min     , Brightness_with_cover_ch_d_ppg1_max\r
+{0, 31000, 32000}, //check_ch_d_ppg1_off_en,Brightness_with_cover_ch_d_ppg1_off_min , Brightness_with_cover_ch_d_ppg1_off_max\r
+{0,  7500, 30000}, //check_ch_d_ppg2_en    ,Brightness_with_cover_ch_d_ppg2_min     , Brightness_with_cover_ch_d_ppg2_max\r
+{0, 31000, 32000}, //check_ch_d_ppg2_off_en,Brightness_with_cover_ch_d_ppg2_off_min , Brightness_with_cover_ch_d_ppg2_off_max\r
+{0,  7500, 30000}, //check_ch_e_ppg1_en    ,Brightness_with_cover_ch_e_ppg1_min     , Brightness_with_cover_ch_e_ppg1_max\r
+{0, 31000, 32000}, //check_ch_e_ppg1_off_en,Brightness_with_cover_ch_e_ppg1_off_min , Brightness_with_cover_ch_e_ppg1_off_max\r
+{0,  7500, 30000}, //check_ch_e_ppg2_en    ,Brightness_with_cover_ch_e_ppg2_min     , Brightness_with_cover_ch_e_ppg2_max\r
+{0, 31000, 32000}, //check_ch_e_ppg2_off_en,Brightness_with_cover_ch_e_ppg2_off_min , Brightness_with_cover_ch_e_ppg2_off_max\r
+{0,  7500, 30000}, //check_ch_f_ppg1_en    ,Brightness_with_cover_ch_f_ppg1_min     , Brightness_with_cover_ch_f_ppg1_max\r
+{0, 31000, 32000}, //check_ch_f_ppg1_off_en,Brightness_with_cover_ch_f_ppg1_off_min , Brightness_with_cover_ch_f_ppg1_off_max\r
+{0,  7500, 30000}, //check_ch_f_ppg2_en    ,Brightness_with_cover_ch_f_ppg2_min     , Brightness_with_cover_ch_f_ppg2_max\r
+{0, 31000, 32000}, //check_ch_f_ppg2_off_en,Brightness_with_cover_ch_f_ppg2_off_min , Brightness_with_cover_ch_f_ppg2_off_max\r
+\r
+\r
+\r
+};\r
+\r
+static const uint16_t Brightness_with_cover_Spec_test_2_Side_B_2_LED[][3]=\r
+{\r
+{0,  1700,  7800}, //check_ch_t_ppg_en     ,Brightness_with_cover_touch_min         , Brightness_with_cover_touch_min      \r
+{0,  7500, 30000}, //check_ch_a_ppg1_en    ,Brightness_with_cover_ch_a_ppg1_min     , Brightness_with_cover_ch_a_ppg1_max\r
+{0, 31000, 32000}, //check_ch_a_ppg1_off_en,Brightness_with_cover_ch_a_ppg1_off_min , Brightness_with_cover_ch_a_ppg1_off_max\r
+{0,  7500, 30000}, //check_ch_a_ppg2_en    ,Brightness_with_cover_ch_a_ppg2_min     , Brightness_with_cover_ch_a_ppg2_max\r
+{0, 31000, 32000}, //check_ch_a_ppg2_off_en,Brightness_with_cover_ch_a_ppg2_off_min , Brightness_with_cover_ch_a_ppg2_off_max\r
+{0,  7500, 30000}, //check_ch_b_ppg1_en    ,Brightness_with_cover_ch_b_ppg1_min     , Brightness_with_cover_ch_b_ppg1_max\r
+{0, 31000, 32000}, //check_ch_b_ppg1_off_en,Brightness_with_cover_ch_b_ppg1_off_min , Brightness_with_cover_ch_b_ppg1_off_max\r
+{0,  7500, 30000}, //check_ch_b_ppg2_en    ,Brightness_with_cover_ch_b_ppg2_min     , Brightness_with_cover_ch_b_ppg2_max\r
+{0, 31000, 32000}, //check_ch_b_ppg2_off_en,Brightness_with_cover_ch_b_ppg2_off_min , Brightness_with_cover_ch_b_ppg2_off_max\r
+{0,  7500, 30000}, //check_ch_c_ppg1_en    ,Brightness_with_cover_ch_c_ppg1_min     , Brightness_with_cover_ch_c_ppg1_max\r
+{0, 31000, 32000}, //check_ch_c_ppg1_off_en,Brightness_with_cover_ch_c_ppg1_off_min , Brightness_with_cover_ch_c_ppg1_off_max\r
+{0,  7500, 30000}, //check_ch_c_ppg2_en    ,Brightness_with_cover_ch_c_ppg2_min     , Brightness_with_cover_ch_c_ppg2_max\r
+{0, 31000, 32000}, //check_ch_c_ppg2_off_en,Brightness_with_cover_ch_c_ppg2_off_min , Brightness_with_cover_ch_c_ppg2_off_max\r
+{1,  7500, 30000}, //check_ch_d_ppg1_en    ,Brightness_with_cover_ch_d_ppg1_min     , Brightness_with_cover_ch_d_ppg1_max\r
+{1, 31000, 32000}, //check_ch_d_ppg1_off_en,Brightness_with_cover_ch_d_ppg1_off_min , Brightness_with_cover_ch_d_ppg1_off_max\r
+{1,  7500, 30000}, //check_ch_d_ppg2_en    ,Brightness_with_cover_ch_d_ppg2_min     , Brightness_with_cover_ch_d_ppg2_max\r
+{1, 31000, 32000}, //check_ch_d_ppg2_off_en,Brightness_with_cover_ch_d_ppg2_off_min , Brightness_with_cover_ch_d_ppg2_off_max\r
+{1,  7500, 30000}, //check_ch_e_ppg1_en    ,Brightness_with_cover_ch_e_ppg1_min     , Brightness_with_cover_ch_e_ppg1_max\r
+{1, 31000, 32000}, //check_ch_e_ppg1_off_en,Brightness_with_cover_ch_e_ppg1_off_min , Brightness_with_cover_ch_e_ppg1_off_max\r
+{1,  7500, 30000}, //check_ch_e_ppg2_en    ,Brightness_with_cover_ch_e_ppg2_min     , Brightness_with_cover_ch_e_ppg2_max\r
+{1, 31000, 32000}, //check_ch_e_ppg2_off_en,Brightness_with_cover_ch_e_ppg2_off_min , Brightness_with_cover_ch_e_ppg2_off_max\r
+{1,  7500, 30000}, //check_ch_f_ppg1_en    ,Brightness_with_cover_ch_f_ppg1_min     , Brightness_with_cover_ch_f_ppg1_max\r
+{1, 31000, 32000}, //check_ch_f_ppg1_off_en,Brightness_with_cover_ch_f_ppg1_off_min , Brightness_with_cover_ch_f_ppg1_off_max\r
+{1,  7500, 30000}, //check_ch_f_ppg2_en    ,Brightness_with_cover_ch_f_ppg2_min     , Brightness_with_cover_ch_f_ppg2_max\r
+{1, 31000, 32000}, //check_ch_f_ppg2_off_en,Brightness_with_cover_ch_f_ppg2_off_min , Brightness_with_cover_ch_f_ppg2_off_max\r
+\r
+\r
+};\r
+\r
+static const uint16_t Brightness_PCB_Only_Spec_test_1_Side_A_1_LED[][3]=\r
+{\r
+{0,  2500,  7500}, //check_ch_t_ppg_en      ,Brightness_PCB_Only_touch_min    , Brightness_PCB_Only_touch_min\r
+{1, 32000, 63488}, //check_ch_a_ppg1_on_en ,Brightness_PCB_Only_ch_a_ppg1_on_min , Brightness_PCB_Only_ch_a_ppg1_on_max\r
+{1, 31000, 32000}, //check_ch_a_ppg1_off_en,Brightness_PCB_Only_ch_a_ppg1_off_min, Brightness_PCB_Only_ch_a_ppg1_off_max\r
+{1, 32000, 63488}, //check_ch_a_ppg2_on_en ,Brightness_PCB_Only_ch_a_ppg2_on_min , Brightness_PCB_Only_ch_a_ppg2_on_max\r
+{1, 31000, 32000}, //check_ch_a_ppg2_off_en,Brightness_PCB_Only_ch_a_ppg2_off_min, Brightness_PCB_Only_ch_a_ppg2_off_max\r
+{1, 32000, 63488}, //check_ch_b_ppg1_on_en ,Brightness_PCB_Only_ch_b_ppg1_on_min , Brightness_PCB_Only_ch_b_ppg1_on_max\r
+{1, 31000, 32000}, //check_ch_b_ppg1_off_en,Brightness_PCB_Only_ch_b_ppg1_off_min, Brightness_PCB_Only_ch_b_ppg1_off_max\r
+{1, 32000, 63488}, //check_ch_b_ppg2_on_en ,Brightness_PCB_Only_ch_b_ppg2_on_min , Brightness_PCB_Only_ch_b_ppg2_on_max\r
+{1, 31000, 32000}, //check_ch_b_ppg2_off_en,Brightness_PCB_Only_ch_b_ppg2_off_min, Brightness_PCB_Only_ch_b_ppg2_off_max\r
+{1, 32000, 63488}, //check_ch_c_ppg1_on_en ,Brightness_PCB_Only_ch_c_ppg1_on_min , Brightness_PCB_Only_ch_c_ppg1_on_max\r
+{1, 31000, 32000}, //check_ch_c_ppg1_off_en,Brightness_PCB_Only_ch_c_ppg1_off_min, Brightness_PCB_Only_ch_c_ppg1_off_max\r
+{1, 32000, 63488}, //check_ch_c_ppg2_on_en ,Brightness_PCB_Only_ch_c_ppg2_on_min , Brightness_PCB_Only_ch_c_ppg2_on_max\r
+{1, 31000, 32000}, //check_ch_c_ppg2_off_en,Brightness_PCB_Only_ch_c_ppg2_off_min, Brightness_PCB_Only_ch_c_ppg2_off_max\r
+{0, 32000, 63488}, //check_ch_d_ppg1_on_en ,Brightness_PCB_Only_ch_d_ppg1_on_min , Brightness_PCB_Only_ch_d_ppg1_on_max\r
+{0, 31000, 32000}, //check_ch_d_ppg1_off_en,Brightness_PCB_Only_ch_d_ppg1_off_min, Brightness_PCB_Only_ch_d_ppg1_off_max\r
+{0, 32000, 63488}, //check_ch_d_ppg2_on_en ,Brightness_PCB_Only_ch_d_ppg2_on_min , Brightness_PCB_Only_ch_d_ppg2_on_max\r
+{0, 31000, 32000}, //check_ch_d_ppg2_off_en,Brightness_PCB_Only_ch_d_ppg2_off_min, Brightness_PCB_Only_ch_d_ppg2_off_max\r
+{0, 32000, 63488}, //check_ch_e_ppg1_on_en ,Brightness_PCB_Only_ch_e_ppg1_on_min , Brightness_PCB_Only_ch_e_ppg1_on_max\r
+{0, 31000, 32000}, //check_ch_e_ppg1_off_en,Brightness_PCB_Only_ch_e_ppg1_off_min, Brightness_PCB_Only_ch_e_ppg1_off_max\r
+{0, 32000, 63488}, //check_ch_e_ppg2_on_en ,Brightness_PCB_Only_ch_e_ppg2_on_min , Brightness_PCB_Only_ch_e_ppg2_on_max\r
+{0, 31000, 32000}, //check_ch_e_ppg2_off_en,Brightness_PCB_Only_ch_e_ppg2_off_min, Brightness_PCB_Only_ch_e_ppg2_off_max\r
+{0, 32000, 63488}, //check_ch_f_ppg1_on_en ,Brightness_PCB_Only_ch_f_ppg1_on_min , Brightness_PCB_Only_ch_f_ppg1_on_max\r
+{0, 31000, 32000}, //check_ch_f_ppg1_off_en,Brightness_PCB_Only_ch_f_ppg1_off_min, Brightness_PCB_Only_ch_f_ppg1_off_max\r
+{0, 32000, 63488}, //check_ch_f_ppg2_on_en ,Brightness_PCB_Only_ch_f_ppg2_on_min , Brightness_PCB_Only_ch_f_ppg2_on_max\r
+{0, 31000, 32000}, //check_ch_f_ppg2_off_en,Brightness_PCB_Only_ch_f_ppg2_off_min, Brightness_PCB_Only_ch_f_ppg2_off_max\r
+\r
+};\r
+\r
+static const uint16_t Brightness_PCB_Only_Spec_test_2_Side_B_1_LED[][3]=\r
+{\r
+{0,  2500,  7500}, //check_ch_t_ppg_en      ,Brightness_PCB_Only_touch_min    , Brightness_PCB_Only_touch_min\r
+{0, 32000, 63488}, //check_ch_a_ppg1_on_en ,Brightness_PCB_Only_ch_a_ppg1_on_min , Brightness_PCB_Only_ch_a_ppg1_on_max\r
+{0, 31000, 32000}, //check_ch_a_ppg1_off_en,Brightness_PCB_Only_ch_a_ppg1_off_min, Brightness_PCB_Only_ch_a_ppg1_off_max\r
+{0, 32000, 63488}, //check_ch_a_ppg2_on_en ,Brightness_PCB_Only_ch_a_ppg2_on_min , Brightness_PCB_Only_ch_a_ppg2_on_max\r
+{0, 31000, 32000}, //check_ch_a_ppg2_off_en,Brightness_PCB_Only_ch_a_ppg2_off_min, Brightness_PCB_Only_ch_a_ppg2_off_max\r
+{0, 32000, 63488}, //check_ch_b_ppg1_on_en ,Brightness_PCB_Only_ch_b_ppg1_on_min , Brightness_PCB_Only_ch_b_ppg1_on_max\r
+{0, 31000, 32000}, //check_ch_b_ppg1_off_en,Brightness_PCB_Only_ch_b_ppg1_off_min, Brightness_PCB_Only_ch_b_ppg1_off_max\r
+{0, 32000, 63488}, //check_ch_b_ppg2_on_en ,Brightness_PCB_Only_ch_b_ppg2_on_min , Brightness_PCB_Only_ch_b_ppg2_on_max\r
+{0, 31000, 32000}, //check_ch_b_ppg2_off_en,Brightness_PCB_Only_ch_b_ppg2_off_min, Brightness_PCB_Only_ch_b_ppg2_off_max\r
+{0, 32000, 63488}, //check_ch_c_ppg1_on_en ,Brightness_PCB_Only_ch_c_ppg1_on_min , Brightness_PCB_Only_ch_c_ppg1_on_max\r
+{0, 31000, 32000}, //check_ch_c_ppg1_off_en,Brightness_PCB_Only_ch_c_ppg1_off_min, Brightness_PCB_Only_ch_c_ppg1_off_max\r
+{0, 32000, 63488}, //check_ch_c_ppg2_on_en ,Brightness_PCB_Only_ch_c_ppg2_on_min , Brightness_PCB_Only_ch_c_ppg2_on_max\r
+{0, 31000, 32000}, //check_ch_c_ppg2_off_en,Brightness_PCB_Only_ch_c_ppg2_off_min, Brightness_PCB_Only_ch_c_ppg2_off_max\r
+{1, 32000, 63488}, //check_ch_d_ppg1_on_en ,Brightness_PCB_Only_ch_d_ppg1_on_min , Brightness_PCB_Only_ch_d_ppg1_on_max\r
+{1, 31000, 32000}, //check_ch_d_ppg1_off_en,Brightness_PCB_Only_ch_d_ppg1_off_min, Brightness_PCB_Only_ch_d_ppg1_off_max\r
+{1, 32000, 63488}, //check_ch_d_ppg2_on_en ,Brightness_PCB_Only_ch_d_ppg2_on_min , Brightness_PCB_Only_ch_d_ppg2_on_max\r
+{1, 31000, 32000}, //check_ch_d_ppg2_off_en,Brightness_PCB_Only_ch_d_ppg2_off_min, Brightness_PCB_Only_ch_d_ppg2_off_max\r
+{1, 32000, 63488}, //check_ch_e_ppg1_on_en ,Brightness_PCB_Only_ch_e_ppg1_on_min , Brightness_PCB_Only_ch_e_ppg1_on_max\r
+{1, 31000, 32000}, //check_ch_e_ppg1_off_en,Brightness_PCB_Only_ch_e_ppg1_off_min, Brightness_PCB_Only_ch_e_ppg1_off_max\r
+{1, 32000, 63488}, //check_ch_e_ppg2_on_en ,Brightness_PCB_Only_ch_e_ppg2_on_min , Brightness_PCB_Only_ch_e_ppg2_on_max\r
+{1, 31000, 32000}, //check_ch_e_ppg2_off_en,Brightness_PCB_Only_ch_e_ppg2_off_min, Brightness_PCB_Only_ch_e_ppg2_off_max\r
+{1, 32000, 63488}, //check_ch_f_ppg1_on_en ,Brightness_PCB_Only_ch_f_ppg1_on_min , Brightness_PCB_Only_ch_f_ppg1_on_max\r
+{1, 31000, 32000}, //check_ch_f_ppg1_off_en,Brightness_PCB_Only_ch_f_ppg1_off_min, Brightness_PCB_Only_ch_f_ppg1_off_max\r
+{1, 32000, 63488}, //check_ch_f_ppg2_on_en ,Brightness_PCB_Only_ch_f_ppg2_on_min , Brightness_PCB_Only_ch_f_ppg2_on_max\r
+{1, 31000, 32000}, //check_ch_f_ppg2_off_en,Brightness_PCB_Only_ch_f_ppg2_off_min, Brightness_PCB_Only_ch_f_ppg2_off_max\r
+\r
+};\r
+\r
+\r
+static const uint16_t Brightness_with_cover_Spec_test_1_Side_A_1_LED[][3]=\r
+{\r
+{1,  1700,  7800}, //check_ch_t_ppg_en     ,Brightness_with_cover_touch_min         , Brightness_with_cover_touch_min      \r
+{1,  7500, 30000}, //check_ch_a_ppg1_en    ,Brightness_with_cover_ch_a_ppg1_min     , Brightness_with_cover_ch_a_ppg1_max\r
+{1, 31000, 32000}, //check_ch_a_ppg1_off_en,Brightness_with_cover_ch_a_ppg1_off_min , Brightness_with_cover_ch_a_ppg1_off_max\r
+{1,  7500, 30000}, //check_ch_a_ppg2_en    ,Brightness_with_cover_ch_a_ppg2_min     , Brightness_with_cover_ch_a_ppg2_max\r
+{1, 31000, 32000}, //check_ch_a_ppg2_off_en,Brightness_with_cover_ch_a_ppg2_off_min , Brightness_with_cover_ch_a_ppg2_off_max\r
+{1,  7500, 30000}, //check_ch_b_ppg1_en    ,Brightness_with_cover_ch_b_ppg1_min     , Brightness_with_cover_ch_b_ppg1_max\r
+{1, 31000, 32000}, //check_ch_b_ppg1_off_en,Brightness_with_cover_ch_b_ppg1_off_min , Brightness_with_cover_ch_b_ppg1_off_max\r
+{1,  7500, 30000}, //check_ch_b_ppg2_en    ,Brightness_with_cover_ch_b_ppg2_min     , Brightness_with_cover_ch_b_ppg2_max\r
+{1, 31000, 32000}, //check_ch_b_ppg2_off_en,Brightness_with_cover_ch_b_ppg2_off_min , Brightness_with_cover_ch_b_ppg2_off_max\r
+{1,  7500, 30000}, //check_ch_c_ppg1_en    ,Brightness_with_cover_ch_c_ppg1_min     , Brightness_with_cover_ch_c_ppg1_max\r
+{1, 31000, 32000}, //check_ch_c_ppg1_off_en,Brightness_with_cover_ch_c_ppg1_off_min , Brightness_with_cover_ch_c_ppg1_off_max\r
+{1,  7500, 30000}, //check_ch_c_ppg2_en    ,Brightness_with_cover_ch_c_ppg2_min     , Brightness_with_cover_ch_c_ppg2_max\r
+{1, 31000, 32000}, //check_ch_c_ppg2_off_en,Brightness_with_cover_ch_c_ppg2_off_min , Brightness_with_cover_ch_c_ppg2_off_max\r
+{0,  7500, 30000}, //check_ch_d_ppg1_en    ,Brightness_with_cover_ch_d_ppg1_min     , Brightness_with_cover_ch_d_ppg1_max\r
+{0, 31000, 32000}, //check_ch_d_ppg1_off_en,Brightness_with_cover_ch_d_ppg1_off_min , Brightness_with_cover_ch_d_ppg1_off_max\r
+{0,  7500, 30000}, //check_ch_d_ppg2_en    ,Brightness_with_cover_ch_d_ppg2_min     , Brightness_with_cover_ch_d_ppg2_max\r
+{0, 31000, 32000}, //check_ch_d_ppg2_off_en,Brightness_with_cover_ch_d_ppg2_off_min , Brightness_with_cover_ch_d_ppg2_off_max\r
+{0,  7500, 30000}, //check_ch_e_ppg1_en    ,Brightness_with_cover_ch_e_ppg1_min     , Brightness_with_cover_ch_e_ppg1_max\r
+{0, 31000, 32000}, //check_ch_e_ppg1_off_en,Brightness_with_cover_ch_e_ppg1_off_min , Brightness_with_cover_ch_e_ppg1_off_max\r
+{0,  7500, 30000}, //check_ch_e_ppg2_en    ,Brightness_with_cover_ch_e_ppg2_min     , Brightness_with_cover_ch_e_ppg2_max\r
+{0, 31000, 32000}, //check_ch_e_ppg2_off_en,Brightness_with_cover_ch_e_ppg2_off_min , Brightness_with_cover_ch_e_ppg2_off_max\r
+{0,  7500, 30000}, //check_ch_f_ppg1_en    ,Brightness_with_cover_ch_f_ppg1_min     , Brightness_with_cover_ch_f_ppg1_max\r
+{0, 31000, 32000}, //check_ch_f_ppg1_off_en,Brightness_with_cover_ch_f_ppg1_off_min , Brightness_with_cover_ch_f_ppg1_off_max\r
+{0,  7500, 30000}, //check_ch_f_ppg2_en    ,Brightness_with_cover_ch_f_ppg2_min     , Brightness_with_cover_ch_f_ppg2_max\r
+{0, 31000, 32000}, //check_ch_f_ppg2_off_en,Brightness_with_cover_ch_f_ppg2_off_min , Brightness_with_cover_ch_f_ppg2_off_max\r
+\r
+\r
+};\r
+\r
+static const uint16_t Brightness_with_cover_Spec_test_2_Side_B_1_LED[][3]=\r
+{\r
+{0,  1700,  7800}, //check_ch_t_ppg_en     ,Brightness_with_cover_touch_min         , Brightness_with_cover_touch_min      \r
+{0,  7500, 30000}, //check_ch_a_ppg1_en    ,Brightness_with_cover_ch_a_ppg1_min     , Brightness_with_cover_ch_a_ppg1_max\r
+{0, 31000, 32000}, //check_ch_a_ppg1_off_en,Brightness_with_cover_ch_a_ppg1_off_min , Brightness_with_cover_ch_a_ppg1_off_max\r
+{0,  7500, 30000}, //check_ch_a_ppg2_en    ,Brightness_with_cover_ch_a_ppg2_min     , Brightness_with_cover_ch_a_ppg2_max\r
+{0, 31000, 32000}, //check_ch_a_ppg2_off_en,Brightness_with_cover_ch_a_ppg2_off_min , Brightness_with_cover_ch_a_ppg2_off_max\r
+{0,  7500, 30000}, //check_ch_b_ppg1_en    ,Brightness_with_cover_ch_b_ppg1_min     , Brightness_with_cover_ch_b_ppg1_max\r
+{0, 31000, 32000}, //check_ch_b_ppg1_off_en,Brightness_with_cover_ch_b_ppg1_off_min , Brightness_with_cover_ch_b_ppg1_off_max\r
+{0,  7500, 30000}, //check_ch_b_ppg2_en    ,Brightness_with_cover_ch_b_ppg2_min     , Brightness_with_cover_ch_b_ppg2_max\r
+{0, 31000, 32000}, //check_ch_b_ppg2_off_en,Brightness_with_cover_ch_b_ppg2_off_min , Brightness_with_cover_ch_b_ppg2_off_max\r
+{0,  7500, 30000}, //check_ch_c_ppg1_en    ,Brightness_with_cover_ch_c_ppg1_min     , Brightness_with_cover_ch_c_ppg1_max\r
+{0, 31000, 32000}, //check_ch_c_ppg1_off_en,Brightness_with_cover_ch_c_ppg1_off_min , Brightness_with_cover_ch_c_ppg1_off_max\r
+{0,  7500, 30000}, //check_ch_c_ppg2_en    ,Brightness_with_cover_ch_c_ppg2_min     , Brightness_with_cover_ch_c_ppg2_max\r
+{0, 31000, 32000}, //check_ch_c_ppg2_off_en,Brightness_with_cover_ch_c_ppg2_off_min , Brightness_with_cover_ch_c_ppg2_off_max\r
+{1,  7500, 30000}, //check_ch_d_ppg1_en    ,Brightness_with_cover_ch_d_ppg1_min     , Brightness_with_cover_ch_d_ppg1_max\r
+{1, 31000, 32000}, //check_ch_d_ppg1_off_en,Brightness_with_cover_ch_d_ppg1_off_min , Brightness_with_cover_ch_d_ppg1_off_max\r
+{1,  7500, 30000}, //check_ch_d_ppg2_en    ,Brightness_with_cover_ch_d_ppg2_min     , Brightness_with_cover_ch_d_ppg2_max\r
+{1, 31000, 32000}, //check_ch_d_ppg2_off_en,Brightness_with_cover_ch_d_ppg2_off_min , Brightness_with_cover_ch_d_ppg2_off_max\r
+{1,  7500, 30000}, //check_ch_e_ppg1_en    ,Brightness_with_cover_ch_e_ppg1_min     , Brightness_with_cover_ch_e_ppg1_max\r
+{1, 31000, 32000}, //check_ch_e_ppg1_off_en,Brightness_with_cover_ch_e_ppg1_off_min , Brightness_with_cover_ch_e_ppg1_off_max\r
+{1,  7500, 30000}, //check_ch_e_ppg2_en    ,Brightness_with_cover_ch_e_ppg2_min     , Brightness_with_cover_ch_e_ppg2_max\r
+{1, 31000, 32000}, //check_ch_e_ppg2_off_en,Brightness_with_cover_ch_e_ppg2_off_min , Brightness_with_cover_ch_e_ppg2_off_max\r
+{1,  7500, 30000}, //check_ch_f_ppg1_en    ,Brightness_with_cover_ch_f_ppg1_min     , Brightness_with_cover_ch_f_ppg1_max\r
+{1, 31000, 32000}, //check_ch_f_ppg1_off_en,Brightness_with_cover_ch_f_ppg1_off_min , Brightness_with_cover_ch_f_ppg1_off_max\r
+{1,  7500, 30000}, //check_ch_f_ppg2_en    ,Brightness_with_cover_ch_f_ppg2_min     , Brightness_with_cover_ch_f_ppg2_max\r
+{1, 31000, 32000}, //check_ch_f_ppg2_off_en,Brightness_with_cover_ch_f_ppg2_off_min , Brightness_with_cover_ch_f_ppg2_off_max\r
+\r
+\r
+};\r
+\r
+static const uint16_t Light_Leak_Spec_2_LED[][3]=\r
+{\r
+{1,     0,    250},  //check_ch_t_en, Light_Leak_touch_min, Light_Leak_touch_max,\r
+{1,     0,    400},  //check_ch_a_ppg1_en,    Light_Leak_ch_a_ppg1_min ,    Light_Leak_ch_a_ppg1_max \r
+{1, 31000,  32000},  //check_ch_a_ppg1_off_en,Light_Leak_ch_a_ppg1_off_min, Light_Leak_ch_a_ppg1_off_max\r
+{1,     0,    400},  //check_ch_a_ppg2_en,    Light_Leak_ch_a_ppg2_min ,    Light_Leak_ch_a_ppg2_max \r
+{1, 31000,  32000},  //check_ch_a_ppg2_off_en,Light_Leak_ch_a_ppg2_off_min, Light_Leak_ch_a_ppg2_off_max\r
+{1,     0,    400},  //check_ch_b_ppg1_en,    Light_Leak_ch_b_ppg1_min ,    Light_Leak_ch_b_ppg1_max \r
+{1, 31000,  32000},  //check_ch_b_ppg1_off_en,Light_Leak_ch_b_ppg1_off_min, Light_Leak_ch_b_ppg1_off_max\r
+{1,     0,    400},  //check_ch_b_ppg2_en,    Light_Leak_ch_b_ppg2_min ,    Light_Leak_ch_b_ppg2_max     \r
+{1, 31000,  32000},  //check_ch_b_ppg2_off_en,Light_Leak_ch_b_ppg2_off_min, Light_Leak_ch_b_ppg2_off_max\r
+{1,     0,    400},  //check_ch_c_ppg1_en,    Light_Leak_ch_c_ppg1_min ,    Light_Leak_ch_c_ppg1_max \r
+{1, 31000,  32000},  //check_ch_c_ppg1_off_en,Light_Leak_ch_c_ppg1_off_min, Light_Leak_ch_c_ppg1_off_max\r
+{1,     0,    400},  //check_ch_c_ppg2_en,    Light_Leak_ch_c_ppg2_min ,    Light_Leak_ch_c_ppg2_max \r
+{1, 31000,  32000},  //check_ch_c_ppg2_off_en,Light_Leak_ch_c_ppg2_off_min, Light_Leak_ch_c_ppg2_off_max\r
+{1,     0,    400},  //check_ch_d_ppg1_en,    Light_Leak_ch_d_ppg1_min ,    Light_Leak_ch_d_ppg1_max \r
+{1, 31000,  32000},  //check_ch_d_ppg1_off_en,Light_Leak_ch_d_ppg1_off_min, Light_Leak_ch_d_ppg1_off_max\r
+{1,     0,    400},  //check_ch_d_ppg2_en,    Light_Leak_ch_d_ppg2_min ,    Light_Leak_ch_d_ppg2_max     \r
+{1, 31000,  32000},  //check_ch_d_ppg2_off_en,Light_Leak_ch_d_ppg2_off_min, Light_Leak_ch_d_ppg2_off_max\r
+{1,     0,    400},  //check_ch_e_ppg1_en,    Light_Leak_ch_e_ppg1_min ,    Light_Leak_ch_e_ppg1_max \r
+{1, 31000,  32000},  //check_ch_e_ppg1_off_en,Light_Leak_ch_e_ppg1_off_min, Light_Leak_ch_e_ppg1_off_max\r
+{1,     0,    400},  //check_ch_e_ppg2_en,    Light_Leak_ch_e_ppg2_min ,    Light_Leak_ch_e_ppg2_max \r
+{1, 31000,  32000},  //check_ch_e_ppg2_off_en,Light_Leak_ch_e_ppg2_off_min, Light_Leak_ch_e_ppg2_off_max\r
+{1,     0,    400},  //check_ch_f_ppg1_en,    Light_Leak_ch_f_ppg1_min ,    Light_Leak_ch_f_ppg1_max \r
+{1, 31000,  32000},  //check_ch_f_ppg1_off_en,Light_Leak_ch_f_ppg1_off_min, Light_Leak_ch_f_ppg1_off_max\r
+{1,     0,    400},  //check_ch_f_ppg2_en,    Light_Leak_ch_f_ppg2_min ,    Light_Leak_ch_f_ppg2_max     \r
+{1, 31000,  32000},  //check_ch_f_ppg2_off_en,Light_Leak_ch_f_ppg2_off_min, Light_Leak_ch_f_ppg2_off_max\r
+};\r
+static const uint16_t Light_Leak_Spec_1_LED[][3]=\r
+{\r
+{1,     0,    250},  //check_ch_t_en, Light_Leak_touch_min, Light_Leak_touch_max,\r
+{1,     0,    400},  //check_ch_a_ppg1_en,    Light_Leak_ch_a_ppg1_min ,    Light_Leak_ch_a_ppg1_max \r
+{1, 31000,  32000},  //check_ch_a_ppg1_off_en,Light_Leak_ch_a_ppg1_off_min, Light_Leak_ch_a_ppg1_off_max\r
+{1,     0,    400},  //check_ch_a_ppg2_en,    Light_Leak_ch_a_ppg2_min ,    Light_Leak_ch_a_ppg2_max \r
+{1, 31000,  32000},  //check_ch_a_ppg2_off_en,Light_Leak_ch_a_ppg2_off_min, Light_Leak_ch_a_ppg2_off_max\r
+{1,     0,    400},  //check_ch_b_ppg1_en,    Light_Leak_ch_b_ppg1_min ,    Light_Leak_ch_b_ppg1_max \r
+{1, 31000,  32000},  //check_ch_b_ppg1_off_en,Light_Leak_ch_b_ppg1_off_min, Light_Leak_ch_b_ppg1_off_max\r
+{1,     0,    400},  //check_ch_b_ppg2_en,    Light_Leak_ch_b_ppg2_min ,    Light_Leak_ch_b_ppg2_max     \r
+{1, 31000,  32000},  //check_ch_b_ppg2_off_en,Light_Leak_ch_b_ppg2_off_min, Light_Leak_ch_b_ppg2_off_max\r
+{1,     0,    400},  //check_ch_c_ppg1_en,    Light_Leak_ch_c_ppg1_min ,    Light_Leak_ch_c_ppg1_max \r
+{1, 31000,  32000},  //check_ch_c_ppg1_off_en,Light_Leak_ch_c_ppg1_off_min, Light_Leak_ch_c_ppg1_off_max\r
+{1,     0,    400},  //check_ch_c_ppg2_en,    Light_Leak_ch_c_ppg2_min ,    Light_Leak_ch_c_ppg2_max \r
+{1, 31000,  32000},  //check_ch_c_ppg2_off_en,Light_Leak_ch_c_ppg2_off_min, Light_Leak_ch_c_ppg2_off_max\r
+{1,     0,    400},  //check_ch_d_ppg1_en,    Light_Leak_ch_d_ppg1_min ,    Light_Leak_ch_d_ppg1_max \r
+{1, 31000,  32000},  //check_ch_d_ppg1_off_en,Light_Leak_ch_d_ppg1_off_min, Light_Leak_ch_d_ppg1_off_max\r
+{1,     0,    400},  //check_ch_d_ppg2_en,    Light_Leak_ch_d_ppg2_min ,    Light_Leak_ch_d_ppg2_max     \r
+{1, 31000,  32000},  //check_ch_d_ppg2_off_en,Light_Leak_ch_d_ppg2_off_min, Light_Leak_ch_d_ppg2_off_max\r
+{0,     0,    400},  //check_ch_e_ppg1_en,    Light_Leak_ch_e_ppg1_min ,    Light_Leak_ch_e_ppg1_max \r
+{0, 31000,  32000},  //check_ch_e_ppg1_off_en,Light_Leak_ch_e_ppg1_off_min, Light_Leak_ch_e_ppg1_off_max\r
+{0,     0,    400},  //check_ch_e_ppg2_en,    Light_Leak_ch_e_ppg2_min ,    Light_Leak_ch_e_ppg2_max \r
+{0, 31000,  32000},  //check_ch_e_ppg2_off_en,Light_Leak_ch_e_ppg2_off_min, Light_Leak_ch_e_ppg2_off_max\r
+{0,     0,    400},  //check_ch_f_ppg1_en,    Light_Leak_ch_f_ppg1_min ,    Light_Leak_ch_f_ppg1_max \r
+{0, 31000,  32000},  //check_ch_f_ppg1_off_en,Light_Leak_ch_f_ppg1_off_min, Light_Leak_ch_f_ppg1_off_max\r
+{0,     0,    400},  //check_ch_f_ppg2_en,    Light_Leak_ch_f_ppg2_min ,    Light_Leak_ch_f_ppg2_max     \r
+{0, 31000,  32000},  //check_ch_f_ppg2_off_en,Light_Leak_ch_f_ppg2_off_min, Light_Leak_ch_f_ppg2_off_max\r
+};\r
+\r
+static const uint16_t PPG_AFE_BUILT_IN_TEST_Spec[][3]=\r
+{\r
+{1,     1537,   2380},  //check_ch_a_ppg1_en, ch_a_ppg1_diff_min, ch_a_ppg1_diff_max\r
+{1,     1537,   2380},  //check_ch_a_ppg2_en, ch_a_ppg2_diff_min, ch_a_ppg2_diff_max \r
+{1,     1537,   2380},  //check_ch_a_ppg3_en, ch_a_ppg3_diff_min, ch_a_ppg3_diff_max\r
+{1,     1537,   2380},  //check_ch_a_ppg4_en, ch_a_ppg4_diff_min, ch_a_ppg4_diff_max       \r
+};\r
+\r
+typedef enum\r
+{\r
+    Check_Brightness_PCB_Only_test_1_Side_A_2_LED,\r
+    Check_Brightness_PCB_Only_test_2_Side_B_2_LED,\r
+    Check_Brightness_PCB_Only_test_1_Side_A_1_LED,\r
+    Check_Brightness_PCB_Only_test_2_Side_B_1_LED,\r
+    INT_TEST,\r
+    Check_Brightness_with_mechanical_cover_test_1_Side_A_2_LED,\r
+    Check_Brightness_with_mechanical_cover_test_2_Side_B_2_LED,\r
+    Check_Brightness_with_mechanical_cover_test_1_Side_A_1_LED,\r
+    Check_Brightness_with_mechanical_cover_test_2_Side_B_1_LED,\r
+    Light_Leak_Test_2_LED,\r
+    Light_Leak_Test_1_LED,\r
+    Check_ECG_LOD_TEST,\r
+    Check_ECG_WAVEFORM_TEST,\r
+    Check_ECG_DC_TEST,\r
+    Check_PPG_AFE_BUILT_IN_TEST,\r
+    Check_ECG_WAVEFORM_TEST_AC_COUPLE,\r
+    Check_ECG_LL_TO_LA_STEP1,\r
+    Check_ECG_LL_TO_LA_STEP2,\r
+    Check_ECG_LL_TO_LA_STEP3,\r
+    Check_ECG_LL_TO_RA_STEP1,\r
+    Check_ECG_LL_TO_RA_STEP2,\r
+    Check_ECG_LL_TO_RA_STEP3,\r
+    //Touchs_value,\r
+    //Power_Noise_Test,\r
+    Factory_Test_Stop,\r
+} pah831x_factory_test_e;\r
+\r
+\r
+void pah831x_read_id(uint16_t *id);\r
+\r
+uint32_t get_pah813x_verify_reg_version(void);\r
+void demo_factory_mode(pah831x_factory_test_e test_mode);\r
+uint16_t pah831x_get_leaklight_fail_str(char *buf, uint16_t buf_size);\r
+\r
+\r
+\r
+#endif\r
diff --git a/code/sdk/zhihui/drivers/ppg/pah831x/pah831x_factory_20251217/pah831x_verify_cal_v3.h b/code/sdk/zhihui/drivers/ppg/pah831x/pah831x_factory_20251217/pah831x_verify_cal_v3.h
new file mode 100644 (file)
index 0000000..af67285
--- /dev/null
@@ -0,0 +1,325 @@
+#ifndef __PAH831X_VERIFY_CAL_REG_V3_H\r
+#define __PAH831X_VERIFY_CAL_REG_V3_H\r
+#endif\r
+\r
+// c\r
+#include <string.h>\r
+#include <stdlib.h>\r
+#include <stdint.h>\r
+#include <stdbool.h>\r
+#include <stdlib.h>\r
+\r
+\r
+//PD_Assign\r
+#define PD_LEFT_UP     (0x8)\r
+#define PD_RIGHT_UP    (0x1)\r
+#define PD_LEFT_DOWN   (0x4)\r
+#define PD_RIGHT_DOWN  (0x2)\r
+\r
+//LED_Aassign-2_LED\r
+#define LED_G1_2_LED     (0x04)\r
+#define LED_R1_2_LED     (0x02)\r
+#define LED_IR1_2_LED    (0x01)\r
+#define LED_G2_2_LED     (0x20)\r
+#define LED_R2_2_LED     (0x10)\r
+#define LED_IR2_2_LED    (0x08)\r
+\r
+\r
+//LED_Aassign-1_LED\r
+#define LED_G1_1_LED     (0x04)\r
+#define LED_R1_1_LED     (0x02)\r
+#define LED_IR1_1_LED    (0x01)\r
+#define LED_G2_1_LED     (0x08)\r
+\r
+//dac_data\r
+#define CH_A_LED_DAC_1_LED_Side_A    (0x63)\r
+#define CH_B_LED_DAC_1_LED_Side_A    (0x54)\r
+#define CH_C_LED_DAC_1_LED_Side_A    (0x7F)\r
+#define CH_D_LED_DAC_1_LED_Side_A    (0x73)\r
+#define CH_E_LED_DAC_1_LED_Side_A    (0x45)\r
+#define CH_F_LED_DAC_1_LED_Side_A    (0x68)\r
+\r
+#define CH_A_LED_DAC_1_LED_Side_B    (0x8D)\r
+#define CH_B_LED_DAC_1_LED_Side_B    (0x8D)\r
+#define CH_C_LED_DAC_1_LED_Side_B    (0x6C)\r
+#define CH_D_LED_DAC_1_LED_Side_B    (0xA0)\r
+#define CH_E_LED_DAC_1_LED_Side_B    (0x78)\r
+#define CH_F_LED_DAC_1_LED_Side_B    (0xAE)\r
+\r
+\r
+\r
+#define CH_A_LED_DAC_2_LED_Side_A    (0x3F)\r
+#define CH_B_LED_DAC_2_LED_Side_A    (0x45)\r
+#define CH_C_LED_DAC_2_LED_Side_A    (0x68)\r
+#define CH_D_LED_DAC_2_LED_Side_A    (0x3F)\r
+#define CH_E_LED_DAC_2_LED_Side_A    (0x45)\r
+#define CH_F_LED_DAC_2_LED_Side_A    (0x68)\r
+\r
+#define CH_A_LED_DAC_2_LED_Side_B    (0x3F)\r
+#define CH_B_LED_DAC_2_LED_Side_B    (0x45)\r
+#define CH_C_LED_DAC_2_LED_Side_B    (0x68)\r
+#define CH_D_LED_DAC_2_LED_Side_B    (0x3F)\r
+#define CH_E_LED_DAC_2_LED_Side_B    (0x45)\r
+#define CH_F_LED_DAC_2_LED_Side_B    (0x68)\r
+\r
+\r
+const uint8_t pah831x_verify_light_leakage_cal_array_2_LED[][2] = {\r
+    //dac_data\r
+    { 0x7F, 0x04 },//bank4            \r
+    { 0x2E, 0xFF },\r
+    { 0x30, 0xFF },\r
+    { 0x32, 0xFF },\r
+    { 0x34, 0xFF },\r
+    { 0x36, 0xFF },\r
+    { 0x38, 0xFF },\r
+    //PD_Assign\r
+    { 0x7f, 0x01},//bank1            \r
+    { 0x35, PD_RIGHT_UP+PD_LEFT_DOWN   },\r
+    { 0x39, PD_LEFT_UP  +PD_RIGHT_DOWN },\r
+    { 0x3D, PD_RIGHT_UP+PD_LEFT_DOWN   },\r
+    { 0x41, PD_LEFT_UP  +PD_RIGHT_DOWN },\r
+    { 0x45, PD_RIGHT_UP+PD_LEFT_DOWN   },\r
+    { 0x49, PD_LEFT_UP  +PD_RIGHT_DOWN },\r
+    { 0x4D, PD_RIGHT_UP+PD_LEFT_DOWN   },\r
+    { 0x51, PD_LEFT_UP  +PD_RIGHT_DOWN  },\r
+    { 0x55, PD_RIGHT_UP+PD_LEFT_DOWN   },\r
+    { 0x59, PD_LEFT_UP  +PD_RIGHT_DOWN },\r
+    { 0x5D, PD_RIGHT_UP+PD_LEFT_DOWN   },\r
+    { 0x61, PD_LEFT_UP  +PD_RIGHT_DOWN  },\r
+    { 0x65, PD_RIGHT_UP+PD_LEFT_DOWN },    \r
+    //LED_Aassign    \r
+    { 0x7F, 0x04 },//Bank4\r
+    { 0x01, LED_G1_2_LED  }, \r
+    { 0x04, LED_R1_2_LED  }, \r
+    { 0x07, LED_IR1_2_LED }, \r
+    { 0x0A, LED_G2_2_LED  }, \r
+    { 0x0D, LED_R2_2_LED  }, \r
+    { 0x10, LED_IR2_2_LED }, \r
+    { 0x13, LED_IR1_2_LED+LED_IR2_2_LED },\r
+    { 0x17, LED_G1_2_LED  },\r
+    { 0x1A, LED_R1_2_LED  },\r
+    { 0x1D, LED_IR1_2_LED },\r
+    { 0x20, LED_G2_2_LED  },\r
+    { 0x23, LED_R2_2_LED  },\r
+    { 0x26, LED_IR2_2_LED },\r
+    { 0x29, LED_IR1_2_LED+LED_IR2_2_LED },     \r
+};\r
+\r
+const uint8_t pah831x_verify_led_brightness_cal_array_Side_A_2_LED[][2] = {\r
+    //dac_data\r
+    { 0x7F, 0x04 },//bank4            \r
+    { 0x2E, CH_A_LED_DAC_2_LED_Side_A },\r
+    { 0x30, CH_B_LED_DAC_2_LED_Side_A },\r
+    { 0x32, CH_C_LED_DAC_2_LED_Side_A },\r
+    { 0x34, CH_D_LED_DAC_2_LED_Side_A },\r
+    { 0x36, CH_E_LED_DAC_2_LED_Side_A },\r
+    { 0x38, CH_F_LED_DAC_2_LED_Side_A },\r
+    //PD_Assign\r
+    { 0x7f, 0x01},//bank1            \r
+    { 0x35, PD_RIGHT_UP  },\r
+    { 0x39, PD_LEFT_UP   },\r
+    { 0x3D, PD_RIGHT_UP  },\r
+    { 0x41, PD_LEFT_UP   },\r
+    { 0x45, PD_RIGHT_UP  },\r
+    { 0x49, PD_LEFT_UP   },\r
+    { 0x4D, PD_RIGHT_DOWN},\r
+    { 0x51, PD_LEFT_DOWN },\r
+    { 0x55, PD_RIGHT_DOWN},\r
+    { 0x59, PD_LEFT_DOWN },\r
+    { 0x5D, PD_RIGHT_DOWN},\r
+    { 0x61,  PD_LEFT_DOWN        },\r
+    { 0x65,  PD_RIGHT_UP+PD_LEFT_DOWN  },    \r
+    //LED_Aassign    \r
+    { 0x7F, 0x04 },//Bank4\r
+    { 0x01, LED_G1_2_LED  }, \r
+    { 0x04, LED_R1_2_LED  }, \r
+    { 0x07, LED_IR1_2_LED }, \r
+    { 0x0A, LED_G2_2_LED  }, \r
+    { 0x0D, LED_R2_2_LED  }, \r
+    { 0x10, LED_IR2_2_LED }, \r
+    { 0x13, LED_IR1_2_LED+LED_IR2_2_LED },\r
+    { 0x17, LED_G1_2_LED  },\r
+    { 0x1A, LED_R1_2_LED  },\r
+    { 0x1D, LED_IR1_2_LED },\r
+    { 0x20, LED_G2_2_LED  },\r
+    { 0x23, LED_R2_2_LED  },\r
+    { 0x26, LED_IR2_2_LED },\r
+    { 0x29, LED_IR1_2_LED+LED_IR2_2_LED },     \r
+};\r
+const uint8_t pah831x_verify_led_brightness_cal_array_Side_B_2_LED[][2] = {\r
+    //dac_data\r
+    { 0x7F, 0x04 },//bank4            \r
+    { 0x2E, CH_A_LED_DAC_2_LED_Side_B },\r
+    { 0x30, CH_B_LED_DAC_2_LED_Side_B },\r
+    { 0x32, CH_C_LED_DAC_2_LED_Side_B },\r
+    { 0x34, CH_D_LED_DAC_2_LED_Side_B },\r
+    { 0x36, CH_E_LED_DAC_2_LED_Side_B },\r
+    { 0x38, CH_F_LED_DAC_2_LED_Side_B },\r
+    //PD_Assign\r
+    { 0x7f, 0x01},//bank1            \r
+    { 0x35, PD_RIGHT_UP  },\r
+    { 0x39, PD_LEFT_UP   },\r
+    { 0x3D, PD_RIGHT_UP  },\r
+    { 0x41, PD_LEFT_UP   },\r
+    { 0x45, PD_RIGHT_UP  },\r
+    { 0x49, PD_LEFT_UP   },\r
+    { 0x4D, PD_RIGHT_DOWN},\r
+    { 0x51, PD_LEFT_DOWN },\r
+    { 0x55, PD_RIGHT_DOWN},\r
+    { 0x59, PD_LEFT_DOWN },\r
+    { 0x5D, PD_RIGHT_DOWN},\r
+    { 0x61,  PD_LEFT_DOWN        },\r
+    { 0x65,  PD_RIGHT_UP+PD_LEFT_DOWN  },    \r
+    //LED_Aassign    \r
+    { 0x7F, 0x04 },//Bank4\r
+    { 0x01, LED_G1_2_LED  }, \r
+    { 0x04, LED_R1_2_LED  }, \r
+    { 0x07, LED_IR1_2_LED }, \r
+    { 0x0A, LED_G2_2_LED  }, \r
+    { 0x0D, LED_R2_2_LED  }, \r
+    { 0x10, LED_IR2_2_LED }, \r
+    { 0x13, LED_IR1_2_LED+LED_IR2_2_LED },\r
+    { 0x17, LED_G1_2_LED  },\r
+    { 0x1A, LED_R1_2_LED  },\r
+    { 0x1D, LED_IR1_2_LED },\r
+    { 0x20, LED_G2_2_LED  },\r
+    { 0x23, LED_R2_2_LED  },\r
+    { 0x26, LED_IR2_2_LED },\r
+    { 0x29, LED_IR1_2_LED+LED_IR2_2_LED },     \r
+};\r
+const uint8_t pah831x_verify_light_leakage_cal_array_1_LED[][2] = {\r
+    //dac_data\r
+    { 0x7F, 0x04 },//bank4            \r
+    { 0x2E, 0xFF },\r
+    { 0x30, 0xFF },\r
+    { 0x32, 0xFF },\r
+    { 0x34, 0xFF },\r
+    { 0x36, 0xFF },\r
+    { 0x38, 0xFF },\r
+    //PD_Assign\r
+    { 0x7f, 0x01},//bank1            \r
+    { 0x35, PD_RIGHT_UP+PD_LEFT_DOWN   },\r
+    { 0x39, PD_LEFT_UP  +PD_RIGHT_DOWN },\r
+    { 0x3D, PD_RIGHT_UP+PD_LEFT_DOWN   },\r
+    { 0x41, PD_LEFT_UP  +PD_RIGHT_DOWN },\r
+    { 0x45, PD_RIGHT_UP+PD_LEFT_DOWN   },\r
+    { 0x49, PD_LEFT_UP  +PD_RIGHT_DOWN },\r
+    { 0x4D, PD_RIGHT_UP+PD_LEFT_DOWN   },\r
+    { 0x51, PD_LEFT_UP  +PD_RIGHT_DOWN  },\r
+    { 0x55, PD_RIGHT_UP+PD_LEFT_DOWN   },\r
+    { 0x59, PD_LEFT_UP  +PD_RIGHT_DOWN },\r
+    { 0x5D, PD_RIGHT_UP+PD_LEFT_DOWN   },\r
+    { 0x61, PD_LEFT_UP  +PD_RIGHT_DOWN  },\r
+    { 0x65, PD_RIGHT_UP+PD_LEFT_DOWN },    \r
+    //LED_Aassign    \r
+    { 0x7F, 0x04 },//Bank4\r
+    { 0x01, LED_G1_1_LED  }, \r
+    { 0x04, LED_R1_1_LED  }, \r
+    { 0x07, LED_IR1_1_LED }, \r
+    { 0x0A, LED_G2_1_LED  }, \r
+    { 0x0D, LED_R1_1_LED  }, \r
+    { 0x10, LED_IR1_1_LED }, \r
+    { 0x13, LED_IR1_1_LED },//\r
+    { 0x17, LED_G1_1_LED  },\r
+    { 0x1A, LED_R1_1_LED  },\r
+    { 0x1D, LED_IR1_1_LED },\r
+    { 0x20, LED_G2_1_LED  },\r
+    { 0x23, LED_R1_1_LED  },\r
+    { 0x26, LED_IR1_1_LED },\r
+    { 0x29, LED_IR1_1_LED },     \r
+};\r
+\r
+const uint8_t pah831x_verify_led_brightness_cal_array_Side_A_1_LED[][2] = {\r
+    //dac_data\r
+    { 0x7F, 0x04 },//bank4            \r
+    { 0x2E, CH_A_LED_DAC_1_LED_Side_A },\r
+    { 0x30, CH_B_LED_DAC_1_LED_Side_A },\r
+    { 0x32, CH_C_LED_DAC_1_LED_Side_A },\r
+    { 0x34, CH_D_LED_DAC_1_LED_Side_A },\r
+    { 0x36, CH_E_LED_DAC_1_LED_Side_A },\r
+    { 0x38, CH_F_LED_DAC_1_LED_Side_A },\r
+    //PD_Assign\r
+    { 0x7f, 0x01},//bank1            \r
+    { 0x35, PD_RIGHT_UP  },\r
+    { 0x39, PD_LEFT_UP   },\r
+    { 0x3D, PD_RIGHT_UP  },\r
+    { 0x41, PD_LEFT_UP   },\r
+    { 0x45, PD_RIGHT_UP  },\r
+    { 0x49, PD_LEFT_UP   },\r
+    { 0x4D, PD_RIGHT_DOWN},\r
+    { 0x51, PD_LEFT_DOWN },\r
+    { 0x55, PD_RIGHT_DOWN},\r
+    { 0x59, PD_LEFT_DOWN },\r
+    { 0x5D, PD_RIGHT_DOWN},\r
+    { 0x61,  PD_LEFT_DOWN        },\r
+    { 0x65,  PD_RIGHT_UP+PD_LEFT_DOWN  },    \r
+    //LED_Aassign    \r
+    { 0x7F, 0x04 },//Bank4\r
+    { 0x01, LED_G1_1_LED  }, \r
+    { 0x04, LED_R1_1_LED  }, \r
+    { 0x07, LED_IR1_1_LED }, \r
+    { 0x0A, LED_G2_1_LED  }, \r
+    { 0x0D, LED_R1_1_LED  }, \r
+    { 0x10, LED_IR1_1_LED }, \r
+    { 0x13, LED_IR1_1_LED },//\r
+    { 0x17, LED_G1_1_LED  },\r
+    { 0x1A, LED_R1_1_LED  },\r
+    { 0x1D, LED_IR1_1_LED },\r
+    { 0x20, LED_G2_1_LED  },\r
+    { 0x23, LED_R1_1_LED  },\r
+    { 0x26, LED_IR1_1_LED },\r
+    { 0x29, LED_IR1_1_LED },     \r
+};\r
+\r
+const uint8_t pah831x_verify_led_brightness_cal_array_Side_B_1_LED[][2] = {\r
+    //dac_data\r
+    { 0x7F, 0x04 },//bank4            \r
+    { 0x2E, CH_A_LED_DAC_1_LED_Side_B },\r
+    { 0x30, CH_B_LED_DAC_1_LED_Side_B },\r
+    { 0x32, CH_C_LED_DAC_1_LED_Side_B },\r
+    { 0x34, CH_D_LED_DAC_1_LED_Side_B },\r
+    { 0x36, CH_E_LED_DAC_1_LED_Side_B },\r
+    { 0x38, CH_F_LED_DAC_1_LED_Side_B },\r
+    //PD_Assign\r
+    { 0x7f, 0x01},//bank1            \r
+    { 0x35, PD_RIGHT_UP  },\r
+    { 0x39, PD_LEFT_UP   },\r
+    { 0x3D, PD_RIGHT_UP  },\r
+    { 0x41, PD_LEFT_UP   },\r
+    { 0x45, PD_RIGHT_UP  },\r
+    { 0x49, PD_LEFT_UP   },\r
+    { 0x4D, PD_RIGHT_DOWN},\r
+    { 0x51, PD_LEFT_DOWN },\r
+    { 0x55, PD_RIGHT_DOWN},\r
+    { 0x59, PD_LEFT_DOWN },\r
+    { 0x5D, PD_RIGHT_DOWN},\r
+    { 0x61,  PD_LEFT_DOWN        },\r
+    { 0x65,  PD_RIGHT_UP+PD_LEFT_DOWN  },    \r
+    //LED_Aassign    \r
+    { 0x7F, 0x04 },//Bank4\r
+    { 0x01, LED_G1_1_LED  }, \r
+    { 0x04, LED_R1_1_LED  }, \r
+    { 0x07, LED_IR1_1_LED }, \r
+    { 0x0A, LED_G2_1_LED  }, \r
+    { 0x0D, LED_R1_1_LED  }, \r
+    { 0x10, LED_IR1_1_LED }, \r
+    { 0x13, LED_IR1_1_LED },//\r
+    { 0x17, LED_G1_1_LED  },\r
+    { 0x1A, LED_R1_1_LED  },\r
+    { 0x1D, LED_IR1_1_LED },\r
+    { 0x20, LED_G2_1_LED  },\r
+    { 0x23, LED_R1_1_LED  },\r
+    { 0x26, LED_IR1_1_LED },\r
+    { 0x29, LED_IR1_1_LED },     \r
+};\r
+\r
+const uint8_t pah831x_verify_ppg_afe_built_in_test[][2] = {\r
+    //dac_data\r
+    //PD_Assign\r
+    { 0x7f, 0x01},//bank1            \r
+    { 0x35, PD_RIGHT_UP  },\r
+    { 0x3D, PD_RIGHT_DOWN  },\r
+    { 0x45, PD_LEFT_DOWN  },\r
+    { 0x4D, PD_LEFT_UP},\r
+    { 0x65, PD_RIGHT_UP+PD_LEFT_DOWN  },         \r
+};\r
diff --git a/code/sdk/zhihui/drivers/ppg/pah831x/pah831x_factory_20251217/pah831x_verify_reg_v3.h b/code/sdk/zhihui/drivers/ppg/pah831x/pah831x_factory_20251217/pah831x_verify_reg_v3.h
new file mode 100644 (file)
index 0000000..cb1ee6d
--- /dev/null
@@ -0,0 +1,1306 @@
+#ifndef __PAH831X_VERIFY_REG_V3_H\r
+#define __PAH831X_VERIFY_REG_V3_H\r
+#endif\r
+\r
+// c\r
+#include <string.h>\r
+#include <stdlib.h>\r
+#include <stdint.h>\r
+#include <stdbool.h>\r
+#include <stdlib.h>\r
+\r
+#define PAH831X_VERIFY_REG_VERSION 0x0305\r
+\r
+//#define Ext_LPO_CLK_FROM_GPIO2_TEST\r
+\r
+static const uint8_t pah831x_verify_light_leakage_array_1_LED[][2] = {\r
+    { 0x7F, 0x05 },//Bank5\r
+    { 0x00, 0x00 },\r
+    { 0x7F, 0x04 },//Bank4\r
+    { 0x00, 0x81 },\r
+    { 0x03, 0x81 },\r
+    { 0x06, 0x81 },\r
+    { 0x09, 0x81 },\r
+    { 0x0C, 0x81 },\r
+    { 0x0F, 0x81 },\r
+    { 0x12, 0x81 },\r
+    { 0x16, 0x81 },\r
+    { 0x19, 0x81 },\r
+    { 0x1C, 0x81 },\r
+    { 0x1F, 0x81 },\r
+    { 0x22, 0x81 },\r
+    { 0x25, 0x81 },\r
+    { 0x28, 0x81 },\r
+    { 0x2E, 0xFF },\r
+    { 0x30, 0xFF },\r
+    { 0x32, 0xFF },\r
+    { 0x34, 0xFF },\r
+    { 0x36, 0xFF },\r
+    { 0x38, 0xFF },\r
+    { 0x7F, 0x03 },//Bank3\r
+    { 0x0B, 0x06 },\r
+    { 0x50, 0xFF },\r
+    { 0x0B, 0x37 },\r
+    { 0x50, 0x00 },\r
+    { 0x52, 0x01 },\r
+    { 0x58, 0x0C },\r
+    { 0x59, 0x0C },\r
+    { 0x5A, 0x0C },\r
+    { 0x5B, 0x0C },\r
+    { 0x5C, 0x0C },\r
+    { 0x5D, 0x0C },\r
+    { 0x7F, 0x01 },//Bank1\r
+    { 0x04, 0x48 },\r
+    { 0x00, 0x98 },\r
+    { 0x06, 0x10 },\r
+    { 0x0C, 0xBB },\r
+    { 0x0D, 0xFF },\r
+    { 0x0F, 0x0F },\r
+    { 0x1A, 0xFF },\r
+    { 0x34, 0x04 },\r
+    { 0x36, 0x0C },\r
+    { 0x3A, 0x0C },\r
+    { 0x3E, 0x0C },\r
+    { 0x42, 0x0C },\r
+    { 0x46, 0x0C },\r
+    { 0x4A, 0x0C },\r
+    { 0x4E, 0x0C },\r
+    { 0x52, 0x0C },\r
+    { 0x56, 0x0C },\r
+    { 0x5A, 0x0C },\r
+    { 0x5E, 0x0C },\r
+    { 0x62, 0x0C },\r
+    { 0x66, 0x0C },\r
+    { 0x7F, 0x00 },//Bank0\r
+    { 0x12, 0x10 },\r
+    { 0x13, 0x10 },\r
+    { 0x14, 0x10 },\r
+    { 0x15, 0x10 },\r
+    { 0x16, 0x08 },\r
+    { 0x6D, 0x10 },\r
+    { 0x6E, 0x10 },\r
+    { 0x17, 0x00 },\r
+    { 0x18, 0x7F },\r
+    { 0x19, 0x7F },\r
+    { 0x49, 0x01 },\r
+    { 0x32, 0x00/*0xFF*/ },\r
+    { 0x5C, 0x00/*0xFF*/ },\r
+    { 0x54,  0x00/*0xFF*/ },\r
+    { 0x55,  0x00/*0xFF*/ },\r
+    { 0x7F, 0x04 },//Bank4\r
+    { 0x14, 0x20 },\r
+    { 0x2A, 0x20 },\r
+    { 0x01, 0x01 },\r
+    { 0x04, 0x02 },\r
+    { 0x07, 0x04 },\r
+    { 0x0A, 0x08 },\r
+    { 0x0D, 0x10 },\r
+    { 0x10, 0x20 },\r
+    { 0x13, 0x01 },\r
+    { 0x17, 0x01 },\r
+    { 0x1A, 0x02 },\r
+    { 0x1D, 0x04 },\r
+    { 0x20, 0x08 },\r
+    { 0x23, 0x10 },\r
+    { 0x26, 0x20 },\r
+    { 0x29, 0x01 },\r
+    { 0x7F, 0x01 },//Bank1\r
+    { 0x35, 0x0C },\r
+    { 0x39, 0x03 },\r
+    { 0x3D, 0x0C },\r
+    { 0x41, 0x03 },\r
+    { 0x45, 0x0C },\r
+    { 0x49, 0x03 },\r
+    { 0x4D, 0x0C },\r
+    { 0x51, 0x03 },\r
+    { 0x55, 0x0C },\r
+    { 0x59, 0x03 },\r
+    { 0x5D, 0x0C },\r
+    { 0x61, 0x03 },\r
+    { 0x65, 0x0C },\r
+    { 0x7F, 0x00 },//Bank0\r
+    { 0x03, 0x40 },\r
+    { 0x04, 0x06 },\r
+    { 0x4F, 0x09 },\r
+    { 0x1B, 0x1F },\r
+    { 0x50, 0x2B },\r
+    { 0x51, 0x2B },\r
+    { 0x52, 0x2B },\r
+    { 0x53, 0x2B },\r
+    { 0x70, 0x2B },\r
+    { 0x71, 0x2B },\r
+    { 0x56, 0x01 },\r
+    { 0x68, 0x00 },\r
+    { 0x7E, 0x80 },//update flag\r
+};\r
+static const uint8_t pah831x_verify_light_leakage_array_2_LED[][2] = {\r
+    { 0x7F, 0x05 },//Bank5\r
+    { 0x00, 0x00 },\r
+    { 0x7F, 0x04 },//Bank4\r
+    { 0x00, 0x81 },\r
+    { 0x03, 0x81 },\r
+    { 0x06, 0x81 },\r
+    { 0x09, 0x81 },\r
+    { 0x0C, 0x81 },\r
+    { 0x0F, 0x81 },\r
+    { 0x12, 0x81 },\r
+    { 0x16, 0x81 },\r
+    { 0x19, 0x81 },\r
+    { 0x1C, 0x81 },\r
+    { 0x1F, 0x81 },\r
+    { 0x22, 0x81 },\r
+    { 0x25, 0x81 },\r
+    { 0x28, 0x81 },\r
+    { 0x2E, 0xFF },\r
+    { 0x30, 0xFF },\r
+    { 0x32, 0xFF },\r
+    { 0x34, 0xFF },\r
+    { 0x36, 0xFF },\r
+    { 0x38, 0xFF },\r
+    { 0x7F, 0x03 },//Bank3\r
+    { 0x0B, 0x06 },\r
+    { 0x50, 0xFF },\r
+    { 0x0B, 0x37 },\r
+    { 0x50, 0x00 },\r
+    { 0x52, 0x01 },\r
+    { 0x58, 0x0C },\r
+    { 0x59, 0x0C },\r
+    { 0x5A, 0x0C },\r
+    { 0x5B, 0x0C },\r
+    { 0x5C, 0x0C },\r
+    { 0x5D, 0x0C },\r
+    { 0x7F, 0x01 },//Bank1\r
+    { 0x04, 0x48 },\r
+    { 0x00, 0x98 },\r
+    { 0x06, 0x10 },\r
+    { 0x0C, 0xBB },\r
+    { 0x0D, 0xFF },\r
+    { 0x0F, 0x0F },\r
+    { 0x1A, 0xFF },\r
+    { 0x34, 0x04 },\r
+    { 0x36, 0x0C },\r
+    { 0x3A, 0x0C },\r
+    { 0x3E, 0x0C },\r
+    { 0x42, 0x0C },\r
+    { 0x46, 0x0C },\r
+    { 0x4A, 0x0C },\r
+    { 0x4E, 0x0C },\r
+    { 0x52, 0x0C },\r
+    { 0x56, 0x0C },\r
+    { 0x5A, 0x0C },\r
+    { 0x5E, 0x0C },\r
+    { 0x62, 0x0C },\r
+    { 0x66, 0x0C },\r
+    { 0x7F, 0x00 },//Bank0\r
+    { 0x12, 0x10 },\r
+    { 0x13, 0x10 },\r
+    { 0x14, 0x10 },\r
+    { 0x15, 0x10 },\r
+    { 0x16, 0x08 },\r
+    { 0x6D, 0x10 },\r
+    { 0x6E, 0x10 },\r
+    { 0x17, 0x00 },\r
+    { 0x18, 0x7F },\r
+    { 0x19, 0x7F },\r
+    { 0x49, 0x01 },\r
+    { 0x32, 0xE0/*0xFF*/ },\r
+    { 0x5C, 0xE0/*0xFF*/ },\r
+    { 0x54, 0x00/*0xFF*/ },\r
+    { 0x55, 0x00/*0xFF*/ },\r
+    { 0x7F, 0x04 },//Bank4\r
+    { 0x14, 0x20 },\r
+    { 0x2A, 0x20 },\r
+    { 0x01, 0x01 },\r
+    { 0x04, 0x02 },\r
+    { 0x07, 0x04 },\r
+    { 0x0A, 0x08 },\r
+    { 0x0D, 0x10 },\r
+    { 0x10, 0x20 },\r
+    { 0x13, 0x09 },\r
+    { 0x17, 0x01 },\r
+    { 0x1A, 0x02 },\r
+    { 0x1D, 0x04 },\r
+    { 0x20, 0x08 },\r
+    { 0x23, 0x10 },\r
+    { 0x26, 0x20 },\r
+    { 0x29, 0x09 },\r
+    { 0x7F, 0x01 },//Bank1\r
+    { 0x35, 0x05 },\r
+    { 0x39, 0x0A },\r
+    { 0x3D, 0x05 },\r
+    { 0x41, 0x0A },\r
+    { 0x45, 0x05 },\r
+    { 0x49, 0x0A },\r
+    { 0x4D, 0x05 },\r
+    { 0x51, 0x0A },\r
+    { 0x55, 0x05 },\r
+    { 0x59, 0x0A },\r
+    { 0x5D, 0x05 },\r
+    { 0x61, 0x0A },\r
+    { 0x65, 0x05 },\r
+    { 0x7F, 0x00 },//Bank0\r
+    { 0x03, 0x40 },\r
+    { 0x04, 0x06 },\r
+    { 0x4F, 0x09 },\r
+    { 0x1B, 0x1F },\r
+    { 0x50, 0x2B },\r
+    { 0x51, 0x2B },\r
+    { 0x52, 0x2B },\r
+    { 0x53, 0x2B },\r
+    { 0x70, 0x2B },\r
+    { 0x71, 0x2B },\r
+    { 0x56, 0x01 },\r
+    { 0x68, 0x03 },\r
+    { 0x7E, 0x80 },//update flag\r
+};\r
+static const uint8_t pah831x_verify_led_brightness_array_test_1_Side_A_2_LED[][2] = {\r
+    { 0x7F, 0x05 }, //Bank5\r
+    { 0x00, 0x00 }, \r
+    { 0x7F, 0x04 }, //Bank4\r
+    { 0x00, 0x81 }, \r
+    { 0x03, 0x81 }, \r
+    { 0x06, 0x81 }, \r
+    { 0x09, 0x81 }, \r
+    { 0x0C, 0x81 }, \r
+    { 0x0F, 0x81 }, \r
+    { 0x12, 0x81 }, \r
+    { 0x16, 0x81 }, \r
+    { 0x19, 0x81 }, \r
+    { 0x1C, 0x81 }, \r
+    { 0x1F, 0x81 }, \r
+    { 0x22, 0x81 }, \r
+    { 0x25, 0x81 }, \r
+    { 0x28, 0x81 }, \r
+    { 0x2E, 0x3F }, \r
+    { 0x30, 0x45 }, \r
+    { 0x32, 0x68 }, \r
+    { 0x34, 0x3F }, \r
+    { 0x36, 0x45 }, \r
+    { 0x38, 0x68 }, \r
+    { 0x7F, 0x03 }, //Bank3\r
+    { 0x0B, 0x06 }, \r
+    { 0x50, 0xFF }, \r
+    { 0x0B, 0x37 }, \r
+    { 0x50, 0x00 }, \r
+    { 0x52, 0x01 }, \r
+    { 0x58, 0x0C }, \r
+    { 0x59, 0x0C }, \r
+    { 0x5A, 0x0C }, \r
+    { 0x5B, 0x0C }, \r
+    { 0x5C, 0x0C }, \r
+    { 0x5D, 0x0C }, \r
+    { 0x7F, 0x01 }, //Bank1\r
+    { 0x04, 0x48 }, \r
+    { 0x00, 0x98 }, \r
+    { 0x06, 0x10 }, \r
+    { 0x0C, 0xBB }, \r
+    { 0x0D, 0xFF }, \r
+    { 0x0F, 0x0F }, \r
+    { 0x1A, 0xFF }, \r
+    { 0x34, 0x04 }, \r
+    { 0x36, 0x0C }, \r
+    { 0x3A, 0x0C }, \r
+    { 0x3E, 0x0C }, \r
+    { 0x42, 0x0C }, \r
+    { 0x46, 0x0C }, \r
+    { 0x4A, 0x0C }, \r
+    { 0x4E, 0x0C }, \r
+    { 0x52, 0x0C }, \r
+    { 0x56, 0x0C }, \r
+    { 0x5A, 0x0C }, \r
+    { 0x5E, 0x0C }, \r
+    { 0x62, 0x0C }, \r
+    { 0x66, 0x0C }, \r
+    { 0x7F, 0x00 }, //Bank0\r
+    { 0x12, 0x10 }, \r
+    { 0x13, 0x10 }, \r
+    { 0x14, 0x10 }, \r
+    { 0x15, 0x10 }, \r
+    { 0x16, 0x08 }, \r
+    { 0x6D, 0x10 }, \r
+    { 0x6E, 0x10 }, \r
+    { 0x17, 0x00 }, \r
+    { 0x18, 0x7F }, \r
+    { 0x19, 0x7F }, \r
+    { 0x49, 0x01 }, \r
+    { 0x32, 0xE0/*0xFF*/ },\r
+    { 0x5C, 0xE0/*0xFF*/ },\r
+    { 0x54,0x00/*0xFF*/ }, \r
+    { 0x55,0x00/*0xFF*/ }, \r
+    { 0x7F, 0x04 }, //Bank4\r
+    { 0x14, 0x20 }, \r
+    { 0x2A, 0x20 }, \r
+    { 0x01, 0x04 }, \r
+    { 0x04, 0x02 }, \r
+    { 0x07, 0x01 }, \r
+    { 0x13, 0x09 }, \r
+    { 0x17, 0x04 }, \r
+    { 0x1A, 0x02 }, \r
+    { 0x1D, 0x01 }, \r
+    { 0x29, 0x09 }, \r
+    { 0x7F, 0x01 }, //Bank1\r
+    { 0x35, 0x01 }, \r
+    { 0x39, 0x08 }, \r
+    { 0x3D, 0x01 }, \r
+    { 0x41, 0x08 }, \r
+    { 0x45, 0x01 }, \r
+    { 0x49, 0x08 }, \r
+    { 0x65, 0x05 }, \r
+    { 0x7F, 0x00 }, //Bank0\r
+    { 0x03, 0x40 }, \r
+    { 0x04, 0x06 }, \r
+    { 0x4F, 0x09 }, \r
+    { 0x1B, 0x17 }, \r
+    { 0x50, 0x2B }, \r
+    { 0x51, 0x2B }, \r
+    { 0x52, 0x2B }, \r
+    { 0x56, 0x01 }, \r
+    { 0x68, 0x00 }, \r
+    { 0x7E, 0x80 }, //update flag\r
+};\r
+\r
+static const uint8_t pah831x_verify_led_brightness_array_test_2_Side_B_2_LED[][2] = {\r
+    { 0x7F, 0x05 }, //Bank5\r
+    { 0x00, 0x00 }, \r
+    { 0x7F, 0x04 }, //Bank4\r
+    { 0x00, 0x81 }, \r
+    { 0x03, 0x81 }, \r
+    { 0x06, 0x81 }, \r
+    { 0x09, 0x81 }, \r
+    { 0x0C, 0x81 }, \r
+    { 0x0F, 0x81 }, \r
+    { 0x12, 0x81 }, \r
+    { 0x16, 0x81 }, \r
+    { 0x19, 0x81 }, \r
+    { 0x1C, 0x81 }, \r
+    { 0x1F, 0x81 }, \r
+    { 0x22, 0x81 }, \r
+    { 0x25, 0x81 }, \r
+    { 0x28, 0x81 }, \r
+    { 0x2E, 0x3F }, \r
+    { 0x30, 0x45 }, \r
+    { 0x32, 0x68 }, \r
+    { 0x34, 0x3F }, \r
+    { 0x36, 0x45 }, \r
+    { 0x38, 0x68 }, \r
+    { 0x7F, 0x03 }, //Bank3\r
+    { 0x0B, 0x06 }, \r
+    { 0x50, 0xFF }, \r
+    { 0x0B, 0x37 }, \r
+    { 0x50, 0x00 }, \r
+    { 0x52, 0x01 }, \r
+    { 0x58, 0x0C }, \r
+    { 0x59, 0x0C }, \r
+    { 0x5A, 0x0C }, \r
+    { 0x5B, 0x0C }, \r
+    { 0x5C, 0x0C }, \r
+    { 0x5D, 0x0C }, \r
+    { 0x7F, 0x01 }, //Bank1\r
+    { 0x04, 0x48 }, \r
+    { 0x00, 0x98 }, \r
+    { 0x06, 0x10 }, \r
+    { 0x0C, 0xBB }, \r
+    { 0x0D, 0xFF }, \r
+    { 0x0F, 0x0F }, \r
+    { 0x1A, 0xFF }, \r
+    { 0x34, 0x04 }, \r
+    { 0x36, 0x0C }, \r
+    { 0x3A, 0x0C }, \r
+    { 0x3E, 0x0C }, \r
+    { 0x42, 0x0C }, \r
+    { 0x46, 0x0C }, \r
+    { 0x4A, 0x0C }, \r
+    { 0x4E, 0x0C }, \r
+    { 0x52, 0x0C }, \r
+    { 0x56, 0x0C }, \r
+    { 0x5A, 0x0C }, \r
+    { 0x5E, 0x0C }, \r
+    { 0x62, 0x0C }, \r
+    { 0x66, 0x0C }, \r
+    { 0x7F, 0x00 }, //Bank0\r
+    { 0x12, 0x10 }, \r
+    { 0x13, 0x10 }, \r
+    { 0x14, 0x10 }, \r
+    { 0x15, 0x10 }, \r
+    { 0x16, 0x08 }, \r
+    { 0x6D, 0x10 }, \r
+    { 0x6E, 0x10 }, \r
+    { 0x17, 0x00 }, \r
+    { 0x18, 0x7F }, \r
+    { 0x19, 0x7F }, \r
+    { 0x49, 0x01 }, \r
+    { 0x32, 0xE0/*0xFF*/ },\r
+    { 0x5C, 0xE0/*0xFF*/ },\r
+    { 0x54, 0xFF }, \r
+    { 0x55, 0xFF }, \r
+    { 0x7F, 0x04 }, //Bank4\r
+    { 0x14, 0x20 }, \r
+    { 0x2A, 0x20 }, \r
+    { 0x0A, 0x20 }, \r
+    { 0x0D, 0x10 }, \r
+    { 0x10, 0x08 }, \r
+    { 0x13, 0x09 }, \r
+    { 0x20, 0x20 }, \r
+    { 0x23, 0x10 }, \r
+    { 0x26, 0x08 }, \r
+    { 0x29, 0x09 }, \r
+    { 0x7F, 0x01 }, //Bank1\r
+    { 0x4D, 0x02 }, \r
+    { 0x51, 0x04 }, \r
+    { 0x55, 0x02 }, \r
+    { 0x59, 0x04 }, \r
+    { 0x5D, 0x02 }, \r
+    { 0x61, 0x04 }, \r
+    { 0x65, 0x05 }, \r
+    { 0x7F, 0x00 }, //Bank0\r
+    { 0x03, 0x40 }, \r
+    { 0x04, 0x06 }, \r
+    { 0x4F, 0x09 }, \r
+    { 0x1B, 0x18 }, \r
+    { 0x53, 0x2B }, \r
+    { 0x70, 0x2B }, \r
+    { 0x71, 0x2B }, \r
+    { 0x56, 0x01 }, \r
+    { 0x68, 0x03 }, \r
+    { 0x7E, 0x80 }, //update flag\r
+};\r
+static const uint8_t pah831x_verify_led_brightness_array_test_1_Side_A_1_LED[][2] = {\r
+    { 0x7F, 0x05 }, //Bank5\r
+    { 0x00, 0x00 }, \r
+    { 0x7F, 0x04 }, //Bank4\r
+    { 0x00, 0x81 }, \r
+    { 0x03, 0x81 }, \r
+    { 0x06, 0x81 }, \r
+    { 0x09, 0x81 }, \r
+    { 0x0C, 0x81 }, \r
+    { 0x0F, 0x81 }, \r
+    { 0x12, 0x81 }, \r
+    { 0x16, 0x81 }, \r
+    { 0x19, 0x81 }, \r
+    { 0x1C, 0x81 }, \r
+    { 0x1F, 0x81 }, \r
+    { 0x22, 0x81 }, \r
+    { 0x25, 0x81 }, \r
+    { 0x28, 0x81 }, \r
+    { 0x2E, 0x63 }, \r
+    { 0x30, 0x54 }, \r
+    { 0x32, 0x7F }, \r
+    { 0x34, 0x73 }, \r
+    { 0x36, 0x45 }, \r
+    { 0x38, 0x68 }, \r
+    { 0x7F, 0x03 }, //Bank3\r
+    { 0x0B, 0x06 }, \r
+    { 0x50, 0xFF }, \r
+    { 0x0B, 0x37 }, \r
+    { 0x50, 0x00 }, \r
+    { 0x52, 0x01 }, \r
+    { 0x58, 0x0C }, \r
+    { 0x59, 0x0C }, \r
+    { 0x5A, 0x0C }, \r
+    { 0x5B, 0x0C }, \r
+    { 0x5C, 0x0C }, \r
+    { 0x5D, 0x0C }, \r
+    { 0x7F, 0x01 }, //Bank1\r
+    { 0x04, 0x48 }, \r
+    { 0x00, 0x98 }, \r
+    { 0x06, 0x10 }, \r
+    { 0x0C, 0xBB }, \r
+    { 0x0D, 0xFF }, \r
+    { 0x0F, 0x0F }, \r
+    { 0x1A, 0xFF }, \r
+    { 0x34, 0x04 }, \r
+    { 0x36, 0x0C }, \r
+    { 0x3A, 0x0C }, \r
+    { 0x3E, 0x0C }, \r
+    { 0x42, 0x0C }, \r
+    { 0x46, 0x0C }, \r
+    { 0x4A, 0x0C }, \r
+    { 0x4E, 0x0C }, \r
+    { 0x52, 0x0C }, \r
+    { 0x56, 0x0C }, \r
+    { 0x5A, 0x0C }, \r
+    { 0x5E, 0x0C }, \r
+    { 0x62, 0x0C }, \r
+    { 0x66, 0x0C }, \r
+    { 0x7F, 0x00 }, //Bank0\r
+    { 0x12, 0x10 }, \r
+    { 0x13, 0x10 }, \r
+    { 0x14, 0x10 }, \r
+    { 0x15, 0x10 }, \r
+    { 0x16, 0x08 }, \r
+    { 0x6D, 0x10 }, \r
+    { 0x6E, 0x10 }, \r
+    { 0x17, 0x00 }, \r
+    { 0x18, 0x7F }, \r
+    { 0x19, 0x7F }, \r
+    { 0x49, 0x01 }, \r
+    { 0x32, 0xE0/*0xFF*/ },\r
+    { 0x5C, 0xE0/*0xFF*/ },\r
+    { 0x54, 0xFF }, \r
+    { 0x55, 0xFF }, \r
+    { 0x7F, 0x04 }, //Bank4\r
+    { 0x14, 0x20 }, \r
+    { 0x2A, 0x20 }, \r
+    { 0x01, 0x04 }, \r
+    { 0x04, 0x02 }, \r
+    { 0x07, 0x01 }, \r
+    { 0x13, 0x01 }, \r
+    { 0x17, 0x04 }, \r
+    { 0x1A, 0x02 }, \r
+    { 0x1D, 0x01 }, \r
+    { 0x29, 0x01 }, \r
+    { 0x7F, 0x01 }, //Bank1\r
+    { 0x35, 0x01 }, \r
+    { 0x39, 0x08 }, \r
+    { 0x3D, 0x01 }, \r
+    { 0x41, 0x08 }, \r
+    { 0x45, 0x01 }, \r
+    { 0x49, 0x08 }, \r
+    { 0x65, 0x0C }, \r
+    { 0x7F, 0x00 }, //Bank0\r
+    { 0x03, 0x40 }, \r
+    { 0x04, 0x06 }, \r
+    { 0x4F, 0x09 }, \r
+    { 0x1B, 0x17 }, \r
+    { 0x50, 0x2B }, \r
+    { 0x51, 0x2B }, \r
+    { 0x52, 0x2B }, \r
+    { 0x56, 0x01 }, \r
+    { 0x68, 0x00 }, \r
+    { 0x7E, 0x80 }, //update flag\r
+      \r
+};\r
+\r
+static const uint8_t pah831x_verify_led_brightness_array_test_2_Side_B_1_LED[][2] = {\r
+    { 0x7F, 0x05 },//Bank5\r
+    { 0x00, 0x00 },\r
+    { 0x7F, 0x04 },//Bank4\r
+    { 0x00, 0x81 },\r
+    { 0x03, 0x81 },\r
+    { 0x06, 0x81 },\r
+    { 0x09, 0x81 },\r
+    { 0x0C, 0x81 },\r
+    { 0x0F, 0x81 },\r
+    { 0x12, 0x81 },\r
+    { 0x16, 0x81 },\r
+    { 0x19, 0x81 },\r
+    { 0x1C, 0x81 },\r
+    { 0x1F, 0x81 },\r
+    { 0x22, 0x81 },\r
+    { 0x25, 0x81 },\r
+    { 0x28, 0x81 },\r
+    { 0x2E, 0x8D },\r
+    { 0x30, 0x8D },\r
+    { 0x32, 0x6C },\r
+    { 0x34, 0xA0 },\r
+    { 0x36, 0x78 },\r
+    { 0x38, 0xAE },\r
+    { 0x7F, 0x03 },//Bank3\r
+    { 0x0B, 0x06 },\r
+    { 0x50, 0xFF },\r
+    { 0x0B, 0x37 },\r
+    { 0x50, 0x00 },\r
+    { 0x52, 0x01 },\r
+    { 0x58, 0x0C },\r
+    { 0x59, 0x0C },\r
+    { 0x5A, 0x0C },\r
+    { 0x5B, 0x0C },\r
+    { 0x5C, 0x0C },\r
+    { 0x5D, 0x0C },\r
+    { 0x7F, 0x01 },//Bank1\r
+    { 0x04, 0x48 },\r
+    { 0x00, 0x98 },\r
+    { 0x06, 0x10 },\r
+    { 0x0C, 0xBB },\r
+    { 0x0D, 0xFF },\r
+    { 0x0F, 0x0F },\r
+    { 0x1A, 0xFF },\r
+    { 0x34, 0x04 },\r
+    { 0x36, 0x0C },\r
+    { 0x3A, 0x0C },\r
+    { 0x3E, 0x0C },\r
+    { 0x42, 0x0C },\r
+    { 0x46, 0x0C },\r
+    { 0x4A, 0x0C },\r
+    { 0x4E, 0x0C },\r
+    { 0x52, 0x0C },\r
+    { 0x56, 0x0C },\r
+    { 0x5A, 0x0C },\r
+    { 0x5E, 0x0C },\r
+    { 0x62, 0x0C },\r
+    { 0x66, 0x0C },\r
+    { 0x7F, 0x00 },//Bank0\r
+    { 0x12, 0x10 },\r
+    { 0x13, 0x10 },\r
+    { 0x14, 0x10 },\r
+    { 0x15, 0x10 },\r
+    { 0x16, 0x08 },\r
+    { 0x6D, 0x10 },\r
+    { 0x6E, 0x10 },\r
+    { 0x17, 0x00 },\r
+    { 0x18, 0x7F },\r
+    { 0x19, 0x7F },\r
+    { 0x49, 0x01 },\r
+    { 0x32, 0xE0/*0xFF*/ },\r
+    { 0x5C, 0xE0/*0xFF*/ },\r
+    { 0x54, 0xE0/*0xFF*/ },\r
+    { 0x55, 0xE0/*0xFF*/ },\r
+    { 0x7F, 0x04 },//Bank4\r
+    { 0x14, 0x20 },\r
+    { 0x2A, 0x20 },\r
+    { 0x0A, 0x08 },\r
+    { 0x0D, 0x02 },\r
+    { 0x10, 0x01 },\r
+    { 0x13, 0x01 },\r
+    { 0x20, 0x08 },\r
+    { 0x23, 0x02 },\r
+    { 0x26, 0x01 },\r
+    { 0x29, 0x01 },\r
+    { 0x7F, 0x01 },//Bank1\r
+    { 0x4D, 0x02 },\r
+    { 0x51, 0x04 },\r
+    { 0x55, 0x02 },\r
+    { 0x59, 0x04 },\r
+    { 0x5D, 0x02 },\r
+    { 0x61, 0x04 },\r
+    { 0x65, 0x05 },\r
+    { 0x7F, 0x00 },//Bank0\r
+    { 0x03, 0x40 },\r
+    { 0x04, 0x06 },\r
+    { 0x4F, 0x09 },\r
+    { 0x1B, 0x18 },\r
+    { 0x53, 0x2B },\r
+    { 0x70, 0x2B },\r
+    { 0x71, 0x2B },\r
+    { 0x56, 0x01 },\r
+    { 0x68, 0x03 },\r
+    { 0x7E, 0x80 },//update flag\r
+\r
+\r
+};\r
+static const uint8_t pah831x_verify_int_test_1_array[][2] = {\r
+    { 0x7F, 0x03 }, //change to bank3                          \r
+    { 0x5B, 0x0E }, \r
+    { 0x5A, 0x0D }, \r
+};\r
+\r
+static const uint8_t pah831x_verify_int_test_2_array[][2] = {\r
+    { 0x7F, 0x03 }, //change to bank3                          \r
+    { 0x5B, 0x0D }, \r
+    { 0x5A, 0x0E }, \r
+}; \r
+static const uint8_t pah831x_verify_ECG_array_test_DC[][2] = {\r
+    { 0x7F, 0x05 }, //Bank5\r
+    { 0x00, 0x00 }, \r
+    { 0x7F, 0x04 }, //Bank4\r
+    { 0x00, 0x81 }, \r
+    { 0x03, 0x81 }, \r
+    { 0x06, 0x81 }, \r
+    { 0x09, 0x81 }, \r
+    { 0x0C, 0x81 }, \r
+    { 0x0F, 0x81 }, \r
+    { 0x12, 0x81 }, \r
+    { 0x16, 0x81 }, \r
+    { 0x19, 0x81 }, \r
+    { 0x1C, 0x81 }, \r
+    { 0x1F, 0x81 }, \r
+    { 0x22, 0x81 }, \r
+    { 0x25, 0x81 }, \r
+    { 0x28, 0x81 }, \r
+    { 0x7F, 0x03 }, //Bank3\r
+    { 0x0B, 0x36 }, \r
+    { 0x50, 0x22 }, \r
+#ifndef Ext_LPO_CLK_FROM_GPIO2_TEST   \r
+    { 0x59 , 0x0C }, //{Dummy[2:0], R_GPIO_1, R_GPIO_1_IEB, R_GPIO_1_OEB, R_GPIO_1_PULLL_EnH, R_GPIO_1_PULLH_EnH}\r
+    { 0x5B , 0x08 }, //{Dummy[2:0], R_GPIO_3, R_GPIO_3_IEB, R_GPIO_3_OEB, R_GPIO_3_PULLL_EnH, R_GPIO_3_PULLH_EnH}\r
+   // { 0x59, 0x08 }, //{Dummy[2:0], R_GPIO_1, R_GPIO_1_IEB, R_GPIO_1_OEB, R_GPIO_1_PULLL_EnH, R_GPIO_1_PULLH_EnH}\r
+    { 0x52 , 0x01 }, //{Dummy[2:0], R_GPIO_2_Open_Drain_EnH, R_GPIO_1_Open_Drain_EnH, R_GPIO_DRV[1:0], R_GPIO_18V_EnL}  \r
+#else\r
+    { 0x59 , 0x0C }, //{Dummy[2:0], R_GPIO_1, R_GPIO_1_IEB, R_GPIO_1_OEB, R_GPIO_1_PULLL_EnH, R_GPIO_1_PULLH_EnH}\r
+    { 0x5B , 0x08 }, //{Dummy[2:0], R_GPIO_3, R_GPIO_3_IEB, R_GPIO_3_OEB, R_GPIO_3_PULLL_EnH, R_GPIO_3_PULLH_EnH}\r
+    { 0x52 , 0x00 }, //{Dummy[2:0], R_GPIO_2_Open_Drain_EnH, R_GPIO_1_Open_Drain_EnH, R_GPIO_DRV[1:0], R_GPIO_18V_EnL}\r
+    { 0x5A , 0x04 }, //{Dummy[2:0], R_GPIO_2, R_GPIO_2_IEB, R_GPIO_2_OEB, R_GPIO_2_PULLL_EnH, R_GPIO_2_PULLH_EnH}\r
+    { 0x54 , 0x14 }, //{Dummy[3:0], R_Ext_CLK_Sel, R_Ext_32K_CLK_Sel, R_Ext_32K_CLK, R_Ext_CLK}\r
+    { 0x54 , 0x16 }, //{Dummy[3:0], R_Ext_CLK_Sel, R_Ext_32K_CLK_Sel, R_Ext_32K_CLK, R_Ext_CLK}\r
+#endif \r
+    { 0x0B, 0x37 }, \r
+    { 0x50, 0x00 }, \r
+    { 0x70, 0x10 }, \r
+    { 0x7F, 0x01 }, //Bank1\r
+    { 0x00, 0x98 }, \r
+    { 0x04, 0x48 },\r
+    { 0x06, 0x03 }, //\r
+    { 0x0B, 0x03 }, \r
+    { 0x0D, 0xF2 }, \r
+    { 0x0F, 0x0E },\r
+    { 0x20, 0x07 }, \r
+    { 0x23, 0x95 }, \r
+    { 0x26, 0x04/*0x07*/ }, \r
+    { 0x08, 0x00 }, \r
+    { 0x09, 0x33 }, \r
+    { 0x21, 0x21 }, \r
+    { 0x76, 0x58 }, \r
+    { 0x77, 0xA0 }, \r
+    { 0x78, 0x0F }, \r
+    { 0x79, 0xA0 }, \r
+    { 0x7A, 0x0F }, \r
+    { 0x7B, 0x80 }, \r
+    { 0x7C, 0x3E }, \r
+    { 0x7E, 0x02 }, \r
+    { 0x7F, 0x00 }, //Bank0\r
+    { 0x03, 0x6A }, //Golden report period[7:0] (1T=31.25us)\r
+    { 0x04, 0x00 }, //Golden report period[15:8]\r
+    { 0x05, 0x00 }, //Golden report period[19:16]\r
+    { 0x29, 0x01 }, \r
+    { 0x2A, 0x00 }, \r
+    { 0x2B, 0x01 }, \r
+    { 0x2C, 0x00 }, \r
+    { 0x27, 0x20 }, \r
+    { 0x28, 0x00 }, \r
+    { 0x1B, 0x60 }, \r
+    { 0x68, 0x00 }, \r
+    { 0x2E, 0x03 }, \r
+    { 0x32, 0xFF }, \r
+    { 0x5C, 0xFF }, \r
+    { 0x54, 0xFF },  \r
+    { 0x55, 0xFF },  \r
+    { 0x35, 0x32 }, \r
+    { 0x36, 0x00 }, \r
+    { 0x49, 0x10 }, \r
+    { 0x5A, 0x02 }, \r
+    { 0x5B, 0x02 }, \r
+    { 0x56, 0x01 }, \r
+    { 0x7E, 0x80 }, //update flag\r
+}; \r
+static const uint8_t pah831x_verify_ECG_array_test[][2] = {\r
+    { 0x7F, 0x05 }, //Bank5\r
+    { 0x00, 0x00 }, \r
+    { 0x7F, 0x04 }, //Bank4\r
+    { 0x00, 0x81 }, \r
+    { 0x03, 0x81 }, \r
+    { 0x06, 0x81 }, \r
+    { 0x09, 0x81 }, \r
+    { 0x0C, 0x81 }, \r
+    { 0x0F, 0x81 }, \r
+    { 0x12, 0x81 }, \r
+    { 0x16, 0x81 }, \r
+    { 0x19, 0x81 }, \r
+    { 0x1C, 0x81 }, \r
+    { 0x1F, 0x81 }, \r
+    { 0x22, 0x81 }, \r
+    { 0x25, 0x81 }, \r
+    { 0x28, 0x81 }, \r
+    { 0x7F, 0x03 }, //Bank3\r
+    { 0x0B, 0x36 }, \r
+    { 0x50, 0x22 }, \r
+#ifndef Ext_LPO_CLK_FROM_GPIO2_TEST   \r
+    { 0x59 , 0x0C }, //{Dummy[2:0], R_GPIO_1, R_GPIO_1_IEB, R_GPIO_1_OEB, R_GPIO_1_PULLL_EnH, R_GPIO_1_PULLH_EnH}\r
+    { 0x5B , 0x08 }, //{Dummy[2:0], R_GPIO_3, R_GPIO_3_IEB, R_GPIO_3_OEB, R_GPIO_3_PULLL_EnH, R_GPIO_3_PULLH_EnH}\r
+   // { 0x59, 0x08 }, //{Dummy[2:0], R_GPIO_1, R_GPIO_1_IEB, R_GPIO_1_OEB, R_GPIO_1_PULLL_EnH, R_GPIO_1_PULLH_EnH}\r
+    { 0x52 , 0x01 }, //{Dummy[2:0], R_GPIO_2_Open_Drain_EnH, R_GPIO_1_Open_Drain_EnH, R_GPIO_DRV[1:0], R_GPIO_18V_EnL}  \r
+#else\r
+    { 0x59 , 0x0C }, //{Dummy[2:0], R_GPIO_1, R_GPIO_1_IEB, R_GPIO_1_OEB, R_GPIO_1_PULLL_EnH, R_GPIO_1_PULLH_EnH}\r
+    { 0x5B , 0x08 }, //{Dummy[2:0], R_GPIO_3, R_GPIO_3_IEB, R_GPIO_3_OEB, R_GPIO_3_PULLL_EnH, R_GPIO_3_PULLH_EnH}\r
+    { 0x52 , 0x00 }, //{Dummy[2:0], R_GPIO_2_Open_Drain_EnH, R_GPIO_1_Open_Drain_EnH, R_GPIO_DRV[1:0], R_GPIO_18V_EnL}\r
+    { 0x5A , 0x04 }, //{Dummy[2:0], R_GPIO_2, R_GPIO_2_IEB, R_GPIO_2_OEB, R_GPIO_2_PULLL_EnH, R_GPIO_2_PULLH_EnH}\r
+    { 0x54 , 0x14 }, //{Dummy[3:0], R_Ext_CLK_Sel, R_Ext_32K_CLK_Sel, R_Ext_32K_CLK, R_Ext_CLK}\r
+    { 0x54 , 0x16 }, //{Dummy[3:0], R_Ext_CLK_Sel, R_Ext_32K_CLK_Sel, R_Ext_32K_CLK, R_Ext_CLK}\r
+#endif\r
+    { 0x0B, 0x37 }, \r
+    { 0x50, 0x00 }, \r
+    { 0x70, 0x10 }, \r
+    { 0x7F, 0x01 }, //Bank1\r
+    { 0x00, 0x98 }, \r
+    { 0x04, 0x48 },\r
+    { 0x06, 0x03 }, //\r
+    { 0x0B, 0x03 }, \r
+    { 0x0D, 0xF2 }, \r
+    { 0x0F, 0x0E },\r
+    { 0x20, 0x07 }, \r
+    { 0x23, 0x95 }, \r
+    { 0x26, 0x07 }, \r
+    { 0x08, 0x00 }, \r
+    { 0x09, 0x33 }, \r
+    { 0x21, 0x21 }, \r
+    { 0x76, 0x58 }, \r
+    { 0x77, 0xA0 }, \r
+    { 0x78, 0x0F }, \r
+    { 0x79, 0xA0 }, \r
+    { 0x7A, 0x0F }, \r
+    { 0x7B, 0x80 }, \r
+    { 0x7C, 0x3E }, \r
+    { 0x7E, 0x02 }, \r
+    { 0x7F, 0x00 }, //Bank0\r
+    { 0x03, 0x6A }, //Golden report period[7:0] (1T=31.25us)\r
+    { 0x04, 0x00 }, //Golden report period[15:8]\r
+    { 0x05, 0x00 }, //Golden report period[19:16]\r
+    { 0x29, 0x01 }, \r
+    { 0x2A, 0x00 }, \r
+    { 0x2B, 0x01 }, \r
+    { 0x2C, 0x00 }, \r
+    { 0x27, 0x20 }, \r
+    { 0x28, 0x00 }, \r
+    { 0x1B, 0x60 }, \r
+    { 0x68, 0x00 }, \r
+    { 0x2E, 0x03 }, \r
+    { 0x32, 0xFF }, \r
+    { 0x5C, 0xFF }, \r
+    { 0x54, 0xFF },  \r
+    { 0x55, 0xFF },  \r
+    { 0x35, 0x32 }, \r
+    { 0x36, 0x00 }, \r
+    { 0x49, 0x10 }, \r
+    { 0x5A, 0x02 }, \r
+    { 0x5B, 0x02 }, \r
+    { 0x56, 0x01 }, \r
+    { 0x7E, 0x80 }, //update flag\r
+}; \r
+\r
+static const uint8_t pah831x_verify_ECG_array_test_AC_COUPLE[][2] = {\r
+    { 0x7F, 0x03 },// -------- Bank3 -------- \r
+    { 0x0B, 0x36 },\r
+    { 0x50, 0x22 },\r
+#ifndef Ext_LPO_CLK_FROM_GPIO2_TEST   \r
+    { 0x59 , 0x0C }, //{Dummy[2:0], R_GPIO_1, R_GPIO_1_IEB, R_GPIO_1_OEB, R_GPIO_1_PULLL_EnH, R_GPIO_1_PULLH_EnH}\r
+    { 0x5B , 0x08 }, //{Dummy[2:0], R_GPIO_3, R_GPIO_3_IEB, R_GPIO_3_OEB, R_GPIO_3_PULLL_EnH, R_GPIO_3_PULLH_EnH}\r
+   // { 0x59, 0x08 }, //{Dummy[2:0], R_GPIO_1, R_GPIO_1_IEB, R_GPIO_1_OEB, R_GPIO_1_PULLL_EnH, R_GPIO_1_PULLH_EnH}\r
+    { 0x52 , 0x01 }, //{Dummy[2:0], R_GPIO_2_Open_Drain_EnH, R_GPIO_1_Open_Drain_EnH, R_GPIO_DRV[1:0], R_GPIO_18V_EnL}  \r
+#else\r
+    { 0x59 , 0x0C }, //{Dummy[2:0], R_GPIO_1, R_GPIO_1_IEB, R_GPIO_1_OEB, R_GPIO_1_PULLL_EnH, R_GPIO_1_PULLH_EnH}\r
+    { 0x5B , 0x08 }, //{Dummy[2:0], R_GPIO_3, R_GPIO_3_IEB, R_GPIO_3_OEB, R_GPIO_3_PULLL_EnH, R_GPIO_3_PULLH_EnH}\r
+    { 0x52 , 0x00 }, //{Dummy[2:0], R_GPIO_2_Open_Drain_EnH, R_GPIO_1_Open_Drain_EnH, R_GPIO_DRV[1:0], R_GPIO_18V_EnL}\r
+    { 0x5A , 0x04 }, //{Dummy[2:0], R_GPIO_2, R_GPIO_2_IEB, R_GPIO_2_OEB, R_GPIO_2_PULLL_EnH, R_GPIO_2_PULLH_EnH}\r
+    { 0x54 , 0x14 }, //{Dummy[3:0], R_Ext_CLK_Sel, R_Ext_32K_CLK_Sel, R_Ext_32K_CLK, R_Ext_CLK}\r
+    { 0x54 , 0x16 }, //{Dummy[3:0], R_Ext_CLK_Sel, R_Ext_32K_CLK_Sel, R_Ext_32K_CLK, R_Ext_CLK}\r
+#endif\r
+    { 0x5A, 0x0C },\r
+    { 0x0B, 0x37 },\r
+    { 0x50, 0x00 },\r
+    { 0x70, 0x10 },\r
+    { 0x7F, 0x01 },// -------- Bank1 --------\r
+    { 0x00, 0x98 },\r
+    { 0x04, 0x48 },\r
+    { 0x05, 0x83 },\r
+    { 0x06, 0x23 },\r
+    { 0x0D, 0xFF },\r
+    { 0x0F, 0x0E },\r
+    { 0x26, 0x07 },\r
+    { 0x08, 0x01 },\r
+    { 0x09, 0x11 },\r
+    { 0x21, 0x21 },\r
+    { 0x76, 0x58 },\r
+    { 0x7E, 0x03 },\r
+    { 0x7F, 0x00 },// -------- Bank0 -------- \r
+    { 0x03, 0x6A },\r
+    { 0x04, 0x00 },\r
+    { 0x29, 0x01 },\r
+    { 0x27, 0x20 },\r
+    { 0x28, 0x00 },\r
+    { 0x2E, 0x03 },\r
+    { 0x35, 0x60 }, \r
+    { 0x36, 0x00 }, \r
+    { 0x5A, 0x02 },\r
+    { 0x5B, 0x02 },\r
+    { 0x1B, 0x20 },\r
+//    { 0x7E, 0x80 },\r
+\r
+};\r
+\r
+static const uint8_t pah831x_verify_ppg_afe_built_in_test_offdac1[][2] = {\r
+    { 0x7F, 0x05 }, //Bank5\r
+    { 0x00, 0x00 }, \r
+    { 0x7F, 0x04 }, //Bank4\r
+    { 0x00, 0x81 }, \r
+    { 0x03, 0x81 }, \r
+    { 0x06, 0x81 }, \r
+    { 0x09, 0x81 }, \r
+    { 0x0C, 0x81 }, \r
+    { 0x0F, 0x81 }, \r
+    { 0x12, 0x81 }, \r
+    { 0x16, 0x81 }, \r
+    { 0x19, 0x81 }, \r
+    { 0x1C, 0x81 }, \r
+    { 0x1F, 0x81 }, \r
+    { 0x22, 0x81 }, \r
+    { 0x25, 0x81 }, \r
+    { 0x28, 0x81 }, \r
+    { 0x2E, 0x01 }, \r
+    { 0x30, 0x01 }, \r
+    { 0x32, 0x01 }, \r
+    { 0x34, 0x01 }, \r
+    { 0x7F, 0x03 }, //Bank3\r
+    { 0x0B, 0x06 }, \r
+    { 0x50, 0xFF }, \r
+    { 0x0B, 0x37 }, \r
+    { 0x50, 0x00 }, \r
+    { 0x70, 0x10 }, \r
+//   { 0x54, 0x00 }, \r
+    { 0x52, 0x01 }, \r
+    { 0x58, 0x0C }, \r
+    { 0x59, 0x0C }, \r
+    { 0x5A, 0x0C }, \r
+    { 0x5B, 0x0C }, \r
+    { 0x5C, 0x0C }, \r
+    { 0x5D, 0x0C }, \r
+    { 0x7F, 0x01 }, //Bank1\r
+    { 0x0B, 0x0C }, \r
+    { 0x04, 0x40 }, \r
+    { 0x05, 0x00 }, \r
+    { 0x00, 0x98 }, \r
+    { 0x06, 0x10 }, \r
+    { 0x0C, 0xBB }, \r
+    { 0x0D, 0xFF }, \r
+    { 0x0F, 0x0F }, \r
+    { 0x1A, 0x20 }, \r
+    { 0x34, 0x04 }, \r
+    { 0x36, 0x0C }, \r
+    { 0x3A, 0x0C }, \r
+    { 0x3E, 0x0C }, \r
+    { 0x42, 0x0C }, \r
+    { 0x46, 0x0C }, \r
+    { 0x4A, 0x0C }, \r
+    { 0x4E, 0x0C }, \r
+    { 0x52, 0x0C }, \r
+    { 0x56, 0x0C }, \r
+    { 0x5A, 0x0C }, \r
+    { 0x5E, 0x0C }, \r
+    { 0x62, 0x0C }, \r
+    { 0x66, 0x0C }, \r
+    { 0x38, 0x0F }, \r
+    { 0x40, 0x0F }, \r
+    { 0x48, 0x0F }, \r
+    { 0x50, 0x0F }, \r
+    { 0x69, 0x0F }, \r
+    { 0x6A, 0x0F }, \r
+    { 0x6B, 0x0F }, \r
+    { 0x6C, 0x0F }, \r
+    { 0x7F, 0x00 }, //Bank0\r
+    { 0x12, 0x10 }, \r
+    { 0x13, 0x10 }, \r
+    { 0x14, 0x10 }, \r
+    { 0x15, 0x10 }, \r
+    { 0x16, 0x08 }, \r
+    { 0x6D, 0x10 }, \r
+    { 0x6E, 0x10 }, \r
+    { 0x17, 0x00 }, \r
+    { 0x18, 0x7F }, \r
+    { 0x19, 0x7F }, \r
+    { 0x49, 0x01 }, \r
+    { 0x32, 0xE0/*0xFF*/ },\r
+    { 0x5C, 0xE0/*0xFF*/ },\r
+    { 0x54, 0xFF }, \r
+    { 0x55, 0xFF }, \r
+    { 0x7F, 0x04 }, //Bank4\r
+    { 0x01, 0x00 }, \r
+    { 0x04, 0x00 }, \r
+    { 0x07, 0x00 }, \r
+    { 0x0A, 0x00 }, \r
+    { 0x17, 0x00 }, \r
+    { 0x1A, 0x00 }, \r
+    { 0x1D, 0x00 }, \r
+    { 0x20, 0x00 }, \r
+    { 0x7F, 0x01 }, //Bank1\r
+    { 0x35, 0x01 }, \r
+    { 0x39, 0x10 }, \r
+    { 0x3D, 0x02 }, \r
+    { 0x41, 0x10 }, \r
+    { 0x45, 0x04 }, \r
+    { 0x49, 0x10 }, \r
+    { 0x4D, 0x08 }, \r
+    { 0x51, 0x10 }, \r
+    { 0x65, 0x05 }, \r
+    { 0x7F, 0x00 }, //Bank0\r
+    { 0x03, 0x40 }, \r
+    { 0x04, 0x06 }, \r
+    { 0x4F, 0x09 }, \r
+    { 0x1B, 0x0F }, \r
+    { 0x50, 0x07 }, \r
+    { 0x51, 0x07 }, \r
+    { 0x52, 0x07 }, \r
+    { 0x53, 0x07 }, \r
+    { 0x56, 0x01 }, \r
+    { 0x68, 0x00 }, \r
+    { 0x7E, 0x80 }, //update flag\r
+\r
+};\r
+static const uint8_t pah831x_verify_ppg_afe_built_in_test_offdac2[][2] = {\r
+    { 0x7F, 0x05 }, //Bank5\r
+    { 0x00, 0x00 }, \r
+    { 0x7F, 0x04 }, //Bank4\r
+    { 0x00, 0x81 }, \r
+    { 0x03, 0x81 }, \r
+    { 0x06, 0x81 }, \r
+    { 0x09, 0x81 }, \r
+    { 0x0C, 0x81 }, \r
+    { 0x0F, 0x81 }, \r
+    { 0x12, 0x81 }, \r
+    { 0x16, 0x81 }, \r
+    { 0x19, 0x81 }, \r
+    { 0x1C, 0x81 }, \r
+    { 0x1F, 0x81 }, \r
+    { 0x22, 0x81 }, \r
+    { 0x25, 0x81 }, \r
+    { 0x28, 0x81 }, \r
+    { 0x2E, 0x01 }, \r
+    { 0x30, 0x01 }, \r
+    { 0x32, 0x01 }, \r
+    { 0x34, 0x01 }, \r
+    { 0x7F, 0x03 }, //Bank3\r
+    { 0x0B, 0x06 }, \r
+    { 0x50, 0xFF }, \r
+    { 0x0B, 0x37 }, \r
+    { 0x50, 0x00 }, \r
+    { 0x70, 0x10 }, \r
+//    { 0x54, 0x00 }, \r
+    { 0x52, 0x01 }, \r
+    { 0x58, 0x0C }, \r
+    { 0x59, 0x0C }, \r
+    { 0x5A, 0x0C }, \r
+    { 0x5B, 0x0C }, \r
+    { 0x5C, 0x0C }, \r
+    { 0x5D, 0x0C },  \r
+    { 0x7F, 0x01 }, //Bank1\r
+    { 0x0B, 0x0C }, \r
+    { 0x04, 0x40 }, \r
+    { 0x05, 0x00 }, \r
+    { 0x00, 0x98 }, \r
+    { 0x06, 0x10 }, \r
+    { 0x0C, 0xBB },  \r
+    { 0x0D, 0xFF }, \r
+    { 0x0F, 0x0F }, \r
+    { 0x1A, 0x20 }, \r
+    { 0x34, 0x04 }, \r
+    { 0x36, 0x0C }, \r
+    { 0x3A, 0x0C }, \r
+    { 0x3E, 0x0C }, \r
+    { 0x42, 0x0C }, \r
+    { 0x46, 0x0C }, \r
+    { 0x4A, 0x0C }, \r
+    { 0x4E, 0x0C }, \r
+    { 0x52, 0x0C }, \r
+    { 0x56, 0x0C }, \r
+    { 0x5A, 0x0C }, \r
+    { 0x5E, 0x0C }, \r
+    { 0x62, 0x0C }, \r
+    { 0x66, 0x0C }, \r
+    { 0x38, 0x0E }, \r
+    { 0x40, 0x0E }, \r
+    { 0x48, 0x0E }, \r
+    { 0x50, 0x0E }, \r
+    { 0x69, 0x0E }, \r
+    { 0x6A, 0x0E }, \r
+    { 0x6B, 0x0E }, \r
+    { 0x6C, 0x0E }, \r
+    { 0x7F, 0x00 }, //Bank0\r
+    { 0x12, 0x10 }, \r
+    { 0x13, 0x10 }, \r
+    { 0x14, 0x10 }, \r
+    { 0x15, 0x10 }, \r
+    { 0x16, 0x08 }, \r
+    { 0x6D, 0x10 },  \r
+    { 0x6E, 0x10 }, \r
+    { 0x17, 0x00 }, \r
+    { 0x18, 0x7F }, \r
+    { 0x19, 0x7F }, \r
+    { 0x49, 0x01 }, \r
+    { 0x32, 0xE0/*0xFF*/ },\r
+    { 0x5C, 0xE0/*0xFF*/ },\r
+    { 0x54, 0xFF }, \r
+    { 0x55, 0xFF }, \r
+    { 0x7F, 0x04 }, //Bank4\r
+    { 0x01, 0x00 }, \r
+    { 0x04, 0x00 }, \r
+    { 0x07, 0x00 }, \r
+    { 0x0A, 0x00 }, \r
+    { 0x17, 0x00 }, \r
+    { 0x1A, 0x00 }, \r
+    { 0x1D, 0x00 },  \r
+    { 0x20, 0x00 }, \r
+    { 0x7F, 0x01 }, //Bank1\r
+    { 0x35, 0x01 }, \r
+    { 0x39, 0x10 }, \r
+    { 0x3D, 0x02 },  \r
+    { 0x41, 0x10 }, \r
+    { 0x45, 0x04 }, \r
+    { 0x49, 0x10 }, \r
+    { 0x4D, 0x08 },  \r
+    { 0x51, 0x10 }, \r
+    { 0x65, 0x05 }, \r
+    { 0x7F, 0x00 }, //Bank0\r
+    { 0x03, 0x40 }, \r
+    { 0x04, 0x06 }, \r
+    { 0x4F, 0x09 }, \r
+    { 0x1B, 0x0F }, \r
+    { 0x50, 0x07 }, \r
+    { 0x51, 0x07 }, \r
+    { 0x52, 0x07 }, \r
+    { 0x53, 0x07 }, \r
+    { 0x56, 0x01 }, \r
+    { 0x68, 0x00 }, \r
+    { 0x7E, 0x80 }, //update flag\r
+};\r
+\r
+static const uint8_t pah831x_verify_ecg_ft1[][2] = \r
+{\r
+    { 0x7F, 0x03 }, //Bank3\r
+    { 0x0B, 0x36 }, \r
+    { 0x50, 0x22 }, \r
+    { 0x52, 0x01 }, \r
+    { 0x58, 0x0C }, \r
+    { 0x59, 0x08 }, \r
+    { 0x5A, 0x0C }, \r
+    { 0x5B, 0x08 }, \r
+    { 0x5C, 0x0C }, \r
+    { 0x5D, 0x0C }, \r
+    { 0x61, 0x01 }, \r
+    { 0x0C, 0x00 }, \r
+    { 0x0D, 0x04 }, \r
+    { 0x0B, 0x37 }, \r
+    { 0x50, 0x00 }, \r
+    { 0x70, 0x10 }, \r
+    { 0x7F, 0x02 }, //Bank2\r
+    { 0x4B, 0x00 }, \r
+    { 0x4C, 0x00 }, \r
+    { 0x4D, 0x00 }, \r
+    { 0x4E, 0x00 }, \r
+    { 0x4F, 0x00 }, \r
+    { 0x7F, 0x01 }, //Bank1\r
+    { 0x00, 0x98 }, \r
+    { 0x04, 0x48 }, \r
+    { 0x05, 0x80 }, \r
+    { 0x06, 0x02 }, \r
+    { 0x0B, 0x03 }, \r
+    { 0x0C, 0xBB }, \r
+    { 0x0D, 0xF2 }, \r
+    { 0x0F, 0x0E }, \r
+    { 0x20, 0x07 }, \r
+    { 0x23, 0x95 }, \r
+    { 0x26, 0x05 }, \r
+    { 0x08, 0x04 }, \r
+    { 0x09, 0x33/*0xDD*/ }, \r
+    { 0x21, 0x21 }, \r
+    { 0x76, 0x58 }, \r
+    { 0x77, 0xA0 }, \r
+    { 0x78, 0x0F }, \r
+    { 0x79, 0xA0 }, \r
+    { 0x7A, 0x0F }, \r
+    { 0x7B, 0x80 }, \r
+    { 0x7C, 0x3E }, \r
+    { 0x7D, 0x77 }, \r
+    { 0x7E, 0x02 }, \r
+    { 0x7F, 0x00 }, //Bank0\r
+    { 0x03, 0x40 }, \r
+    { 0x04, 0x00 }, \r
+    { 0x05, 0x00 }, \r
+    { 0x24, 0x01 }, \r
+    { 0x25, 0x00 }, \r
+    { 0x29, 0x01 }, \r
+    { 0x2A, 0x00 }, \r
+    { 0x2B, 0x01 }, \r
+    { 0x2C, 0x00 }, \r
+    { 0x27, 0x01 }, \r
+    { 0x28, 0x00 }, \r
+    { 0x17, 0x00 }, \r
+    { 0x18, 0x7F }, \r
+    { 0x19, 0x00 }, \r
+    { 0x1B, 0x60 }, \r
+    { 0x68, 0x00 }, \r
+    { 0x2E, 0x07 }, \r
+    { 0x46, 0x00 }, \r
+    { 0x47, 0x00 }, \r
+    { 0x48, 0x00 }, \r
+    { 0x31, 0x00 }, \r
+    { 0x32, 0x00 }, \r
+    { 0x5C, 0xFF }, \r
+    { 0x54, 0x00 }, \r
+    { 0x55, 0x00 }, \r
+    { 0x35, 0x14 }, \r
+    { 0x36, 0x00 }, \r
+    { 0x37, 0x00 }, \r
+    { 0x7e, 0x80 },  \r
+};\r
+\r
+\r
+\r
+\r
+\r
+static const uint8_t pah831x_verify_ecg_ft2[][2] = \r
+{ \r
+    { 0x7F, 0x03 }, //Bank3\r
+    { 0x0B, 0x36 }, \r
+    { 0x50, 0x22 }, \r
+    { 0x52, 0x01 }, \r
+    { 0x58, 0x0C }, \r
+    { 0x59, 0x08 }, \r
+    { 0x5A, 0x0C }, \r
+    { 0x5B, 0x08 }, \r
+    { 0x5C, 0x0C }, \r
+    { 0x5D, 0x0C }, \r
+    { 0x61, 0x01 }, \r
+    { 0x0C, 0x00 }, \r
+    { 0x0D, 0x04 }, \r
+    { 0x0B, 0x37 }, \r
+    { 0x50, 0x00 }, \r
+    { 0x70, 0x10 }, \r
+    { 0x7F, 0x02 }, //Bank2\r
+    { 0x4B, 0x00 }, \r
+    { 0x4C, 0x00 }, \r
+    { 0x4D, 0x00 }, \r
+    { 0x4E, 0x00 }, \r
+    { 0x4F, 0x00 }, \r
+    { 0x7F, 0x01 }, //Bank1\r
+    { 0x00, 0x98 }, \r
+    { 0x04, 0x48 }, \r
+    { 0x05, 0x80 }, \r
+    { 0x06, 0x02 }, \r
+    { 0x0B, 0x03 }, \r
+    { 0x0C, 0xBB }, \r
+    { 0x0D, 0xF2 }, \r
+    { 0x0F, 0x0E }, \r
+    { 0x20, 0x07 }, \r
+    { 0x23, 0x95 }, \r
+    { 0x26, 0x05 }, \r
+    { 0x08, 0x04 }, \r
+    { 0x09, 0xDD/*0x33*/ }, \r
+    { 0x21, 0x21 }, \r
+    { 0x76, 0x58 }, \r
+    { 0x77, 0xA0 }, \r
+    { 0x78, 0x0F }, \r
+    { 0x79, 0xA0 }, \r
+    { 0x7A, 0x0F }, \r
+    { 0x7B, 0x80 }, \r
+    { 0x7C, 0x3E }, \r
+    { 0x7D, 0x77 }, \r
+    { 0x7E, 0x02 }, \r
+    { 0x7F, 0x00 }, //Bank0\r
+    { 0x03, 0x40 }, \r
+    { 0x04, 0x00 }, \r
+    { 0x05, 0x00 }, \r
+    { 0x24, 0x01 }, \r
+    { 0x25, 0x00 }, \r
+    { 0x29, 0x01 }, \r
+    { 0x2A, 0x00 }, \r
+    { 0x2B, 0x01 }, \r
+    { 0x2C, 0x00 }, \r
+    { 0x27, 0x01 }, \r
+    { 0x28, 0x00 }, \r
+    { 0x17, 0x00 }, \r
+    { 0x18, 0x7F }, \r
+    { 0x19, 0x00 }, \r
+    { 0x1B, 0x60 }, \r
+    { 0x68, 0x00 }, \r
+    { 0x2E, 0x07 }, \r
+    { 0x46, 0x00 }, \r
+    { 0x47, 0x00 }, \r
+    { 0x48, 0x00 }, \r
+    { 0x31, 0x00 }, \r
+    { 0x32, 0x00 }, \r
+    { 0x5C, 0xFF }, \r
+    { 0x54, 0x00 }, \r
+    { 0x55, 0x00 }, \r
+    { 0x35, 0x14 }, \r
+    { 0x36, 0x00 }, \r
+    { 0x37, 0x00 }, \r
+    { 0x7e, 0x80 },  \r
+};\r
+\r
diff --git a/code/sdk/zhihui/drivers/ppg/pah831x/pah_sensor/pah831x.c b/code/sdk/zhihui/drivers/ppg/pah831x/pah_sensor/pah831x.c
new file mode 100644 (file)
index 0000000..a59373b
--- /dev/null
@@ -0,0 +1,2344 @@
+/**\r
+ * Copyright (c) 2022 PixArt Imaging Inc.\r
+ * All Rights Reserved.\r
+ * Confidential and Proprietary - PixArt Imaging Inc.\r
+ **/\r
+#include "pah831x.h"\r
+\r
+#include "pah_util.h"\r
+\r
+#include "pah831x_comm.h"\r
+\r
+//============================================================================\r
+// Macro\r
+//============================================================================\r
+\r
+#define DELAY_MS(ms)    LOS_Mdelay( ms)\r
+    \r
+#define UINT32_FROM_UINT8(data0, data1, data2, data3)   ((uint32_t)((data0 << 0) | (data1 << 8) | (data2 << 16) | (data3 << 24)))\r
+#define UINT16_FROM_UINT8(data0, data1)                 ((uint16_t)((data0 << 0) | (data1 << 8)))\r
+\r
+//============================================================================\r
+// Definition\r
+//============================================================================\r
+#define RESET_DELAY_MS (1) // 0.5+\r
+#define POWER_DOWN_DELAY_MS (3) // 2+\r
+#define POWER_UP_DELAY_MS (15) // 11+\r
+#define UPDATE_FLAG_DELAY_MS (1)\r
+\r
+typedef enum\r
+{\r
+    PAH831X_PPG_CH__A,\r
+    PAH831X_PPG_CH__B,\r
+    PAH831X_PPG_CH__C,\r
+    PAH831X_PPG_CH__D,\r
+    PAH831X_PPG_CH__E,\r
+    PAH831X_PPG_CH__F,\r
+    PAH831X_PPG_CH__T,\r
+\r
+    PAH831X_PPG_CH__NUM,\r
+} pah831x_ppg_ch;\r
+\r
+typedef enum\r
+{\r
+    PAH831X_REG__B0_0X03,\r
+    PAH831X_REG__B0_0X04,\r
+    PAH831X_REG__B0_0X12,\r
+    PAH831X_REG__B0_0X13,\r
+    PAH831X_REG__B0_0X14,\r
+    PAH831X_REG__B0_0X15,\r
+    PAH831X_REG__B0_0X16,\r
+    PAH831X_REG__B0_0X1B,\r
+    PAH831X_REG__B0_0X24,\r
+    PAH831X_REG__B0_0X25,\r
+    PAH831X_REG__B0_0X27,\r
+    PAH831X_REG__B0_0X28,\r
+    PAH831X_REG__B0_0X50,\r
+    PAH831X_REG__B0_0X51,\r
+    PAH831X_REG__B0_0X52,\r
+    PAH831X_REG__B0_0X53,\r
+    PAH831X_REG__B0_0X56,\r
+    PAH831X_REG__B0_0X68,\r
+    PAH831X_REG__B0_0X6D,\r
+    PAH831X_REG__B0_0X6E,\r
+    PAH831X_REG__B0_0X70,\r
+    PAH831X_REG__B0_0X71,\r
+    PAH831X_REG__B1_0X06,\r
+    PAH831X_REG__B1_0X1A,\r
+    PAH831X_REG__B1_0X26,\r
+    PAH831X_REG__B4_0X00,\r
+    PAH831X_REG__B4_0X01,\r
+    PAH831X_REG__B4_0X03,\r
+    PAH831X_REG__B4_0X04,\r
+    PAH831X_REG__B4_0X06,\r
+    PAH831X_REG__B4_0X07,\r
+    PAH831X_REG__B4_0X09,\r
+    PAH831X_REG__B4_0X0A,\r
+    PAH831X_REG__B4_0X0C,\r
+    PAH831X_REG__B4_0X0D,\r
+    PAH831X_REG__B4_0X0F,\r
+    PAH831X_REG__B4_0X10,\r
+    PAH831X_REG__B4_0X12,\r
+    PAH831X_REG__B4_0X16,\r
+    PAH831X_REG__B4_0X17,\r
+    PAH831X_REG__B4_0X19,\r
+    PAH831X_REG__B4_0X1A,\r
+    PAH831X_REG__B4_0X1C,\r
+    PAH831X_REG__B4_0X1D,\r
+    PAH831X_REG__B4_0X1F,\r
+    PAH831X_REG__B4_0X20,\r
+    PAH831X_REG__B4_0X22,\r
+    PAH831X_REG__B4_0X23,\r
+    PAH831X_REG__B4_0X25,\r
+    PAH831X_REG__B4_0X26,\r
+    PAH831X_REG__B4_0X28,\r
+\r
+    PAH831X_REG__NUM,\r
+} pah831x_reg;\r
+\r
+typedef struct\r
+{\r
+    uint8_t values[PAH831X_REG__NUM];\r
+    bool has_values[PAH831X_REG__NUM];\r
+    bool values_has_changed[PAH831X_REG__NUM];\r
+} pah831x_regs;\r
+\r
+typedef struct\r
+{\r
+    uint8_t bank;\r
+    uint8_t addr;\r
+} pah831x_reg_info;\r
+\r
+static const pah831x_reg_info REG_LOOKUP_TABLE[PAH831X_REG__NUM] =\r
+{\r
+    [PAH831X_REG__B0_0X03] = { .bank = 0, .addr = PAH831X_B0__REPORT_PERIOD_1__ADDR },\r
+    [PAH831X_REG__B0_0X04] = { .bank = 0, .addr = PAH831X_B0__REPORT_PERIOD_2__ADDR },\r
+    [PAH831X_REG__B0_0X12] = { .bank = 0, .addr = PAH831X_B0__FRAME_NUM_A__ADDR },\r
+    [PAH831X_REG__B0_0X13] = { .bank = 0, .addr = PAH831X_B0__FRAME_NUM_B__ADDR },\r
+    [PAH831X_REG__B0_0X14] = { .bank = 0, .addr = PAH831X_B0__FRAME_NUM_C__ADDR },\r
+    [PAH831X_REG__B0_0X15] = { .bank = 0, .addr = PAH831X_B0__FRAME_NUM_D__ADDR },\r
+    [PAH831X_REG__B0_0X16] = { .bank = 0, .addr = PAH831X_B0__FRAME_NUM_T__ADDR },\r
+    [PAH831X_REG__B0_0X1B] = { .bank = 0, .addr = PAH831X_B0__CH_ENH_1__ADDR },\r
+    [PAH831X_REG__B0_0X24] = { .bank = 0, .addr = PAH831X_B0__REPORT_DIVIDER_T_1__ADDR },\r
+    [PAH831X_REG__B0_0X25] = { .bank = 0, .addr = PAH831X_B0__REPORT_DIVIDER_T_2__ADDR },\r
+    [PAH831X_REG__B0_0X27] = { .bank = 0, .addr = PAH831X_B0__FRAME_NUM_ECG_1__ADDR },\r
+    [PAH831X_REG__B0_0X28] = { .bank = 0, .addr = PAH831X_B0__FRAME_NUM_ECG_2__ADDR },\r
+    [PAH831X_REG__B0_0X50] = { .bank = 0, .addr = PAH831X_B0__PPG_A__ADDR },\r
+    [PAH831X_REG__B0_0X51] = { .bank = 0, .addr = PAH831X_B0__PPG_B__ADDR },\r
+    [PAH831X_REG__B0_0X52] = { .bank = 0, .addr = PAH831X_B0__PPG_C__ADDR },\r
+    [PAH831X_REG__B0_0X53] = { .bank = 0, .addr = PAH831X_B0__PPG_D__ADDR },\r
+    [PAH831X_REG__B0_0X56] = { .bank = 0, .addr = PAH831X_B0__DECIMATION_NUM__ADDR },\r
+    [PAH831X_REG__B0_0X68] = { .bank = 0, .addr = PAH831X_B0__CH_ENH_2__ADDR },\r
+    [PAH831X_REG__B0_0X6D] = { .bank = 0, .addr = PAH831X_B0__FRAME_NUM_E__ADDR },\r
+    [PAH831X_REG__B0_0X6E] = { .bank = 0, .addr = PAH831X_B0__FRAME_NUM_F__ADDR },\r
+    [PAH831X_REG__B0_0X70] = { .bank = 0, .addr = PAH831X_B0__PPG_E__ADDR },\r
+    [PAH831X_REG__B0_0X71] = { .bank = 0, .addr = PAH831X_B0__PPG_F__ADDR },\r
+    [PAH831X_REG__B1_0X06] = { .bank = 1, .addr = PAH831X_B1__ECG_POLAR_FLIP_ENH__ADDR },\r
+    [PAH831X_REG__B1_0X1A] = { .bank = 1, .addr = PAH831X_B1__PPG_IP_STL__ADDR },\r
+    [PAH831X_REG__B1_0X26] = { .bank = 1, .addr = PAH831X_B1__ECG_FE_INA_GAIN__ADDR },\r
+    [PAH831X_REG__B4_0X00] = { .bank = 4, .addr = PAH831X_B4__PPG_CH_A_LEDDAC_1__ADDR },\r
+    [PAH831X_REG__B4_0X01] = { .bank = 4, .addr = PAH831X_B4__PPG_CH_A_LEDDAC_1_CH_SEL__ADDR },\r
+    [PAH831X_REG__B4_0X03] = { .bank = 4, .addr = PAH831X_B4__PPG_CH_B_LEDDAC_1__ADDR },\r
+    [PAH831X_REG__B4_0X04] = { .bank = 4, .addr = PAH831X_B4__PPG_CH_B_LEDDAC_1_CH_SEL__ADDR },\r
+    [PAH831X_REG__B4_0X06] = { .bank = 4, .addr = PAH831X_B4__PPG_CH_C_LEDDAC_1__ADDR },\r
+    [PAH831X_REG__B4_0X07] = { .bank = 4, .addr = PAH831X_B4__PPG_CH_C_LEDDAC_1_CH_SEL__ADDR },\r
+    [PAH831X_REG__B4_0X09] = { .bank = 4, .addr = PAH831X_B4__PPG_CH_D_LEDDAC_1__ADDR },\r
+    [PAH831X_REG__B4_0X0A] = { .bank = 4, .addr = PAH831X_B4__PPG_CH_D_LEDDAC_1_CH_SEL__ADDR },\r
+    [PAH831X_REG__B4_0X0C] = { .bank = 4, .addr = PAH831X_B4__PPG_CH_E_LEDDAC_1__ADDR },\r
+    [PAH831X_REG__B4_0X0D] = { .bank = 4, .addr = PAH831X_B4__PPG_CH_E_LEDDAC_1_CH_SEL__ADDR },\r
+    [PAH831X_REG__B4_0X0F] = { .bank = 4, .addr = PAH831X_B4__PPG_CH_F_LEDDAC_1__ADDR },\r
+    [PAH831X_REG__B4_0X10] = { .bank = 4, .addr = PAH831X_B4__PPG_CH_F_LEDDAC_1_CH_SEL__ADDR },\r
+    [PAH831X_REG__B4_0X12] = { .bank = 4, .addr = PAH831X_B4__PPG_CH_T_LEDDAC_1__ADDR },\r
+    [PAH831X_REG__B4_0X16] = { .bank = 4, .addr = PAH831X_B4__PPG_CH_A_LEDDAC_2__ADDR },\r
+    [PAH831X_REG__B4_0X17] = { .bank = 4, .addr = PAH831X_B4__PPG_CH_A_LEDDAC_2_CH_SEL__ADDR },\r
+    [PAH831X_REG__B4_0X19] = { .bank = 4, .addr = PAH831X_B4__PPG_CH_B_LEDDAC_2__ADDR },\r
+    [PAH831X_REG__B4_0X1A] = { .bank = 4, .addr = PAH831X_B4__PPG_CH_B_LEDDAC_2_CH_SEL__ADDR },\r
+    [PAH831X_REG__B4_0X1C] = { .bank = 4, .addr = PAH831X_B4__PPG_CH_C_LEDDAC_2__ADDR },\r
+    [PAH831X_REG__B4_0X1D] = { .bank = 4, .addr = PAH831X_B4__PPG_CH_C_LEDDAC_2_CH_SEL__ADDR },\r
+    [PAH831X_REG__B4_0X1F] = { .bank = 4, .addr = PAH831X_B4__PPG_CH_D_LEDDAC_2__ADDR },\r
+    [PAH831X_REG__B4_0X20] = { .bank = 4, .addr = PAH831X_B4__PPG_CH_D_LEDDAC_2_CH_SEL__ADDR },\r
+    [PAH831X_REG__B4_0X22] = { .bank = 4, .addr = PAH831X_B4__PPG_CH_E_LEDDAC_2__ADDR },\r
+    [PAH831X_REG__B4_0X23] = { .bank = 4, .addr = PAH831X_B4__PPG_CH_E_LEDDAC_2_CH_SEL__ADDR },\r
+    [PAH831X_REG__B4_0X25] = { .bank = 4, .addr = PAH831X_B4__PPG_CH_F_LEDDAC_2__ADDR },\r
+    [PAH831X_REG__B4_0X26] = { .bank = 4, .addr = PAH831X_B4__PPG_CH_F_LEDDAC_2_CH_SEL__ADDR },\r
+    [PAH831X_REG__B4_0X28] = { .bank = 4, .addr = PAH831X_B4__PPG_CH_T_LEDDAC_2__ADDR },\r
+};\r
+\r
+static const pah831x_reg PPG_LED_REG_LOOKUP_TABLE[PAH831X_CH__PPG_NUM] = {\r
+    PAH831X_REG__B4_0X01, // PAH831X_CH__PPG_A1\r
+    PAH831X_REG__B4_0X17, // PAH831X_CH__PPG_A2\r
+    PAH831X_REG__B4_0X04, // PAH831X_CH__PPG_B1\r
+    PAH831X_REG__B4_0X1A, // PAH831X_CH__PPG_B2\r
+    PAH831X_REG__B4_0X07, // PAH831X_CH__PPG_C1\r
+    PAH831X_REG__B4_0X1D, // PAH831X_CH__PPG_C2\r
+    PAH831X_REG__B4_0X0A, // PAH831X_CH__PPG_D1\r
+    PAH831X_REG__B4_0X20, // PAH831X_CH__PPG_D2\r
+    PAH831X_REG__B4_0X0D, // PAH831X_CH__PPG_E1\r
+    PAH831X_REG__B4_0X23, // PAH831X_CH__PPG_E2\r
+    PAH831X_REG__B4_0X10, // PAH831X_CH__PPG_F1\r
+    PAH831X_REG__B4_0X26, // PAH831X_CH__PPG_F2\r
+};\r
+\r
+#define PPG_LEDDAC_REG__NUM (14)\r
+static const pah831x_reg PPG_LEDDAC_REG_LOOKUP_TABLE[PPG_LEDDAC_REG__NUM] = {\r
+    PAH831X_REG__B4_0X00,\r
+    PAH831X_REG__B4_0X03,\r
+    PAH831X_REG__B4_0X06,\r
+    PAH831X_REG__B4_0X09,\r
+    PAH831X_REG__B4_0X0C,\r
+    PAH831X_REG__B4_0X0F,\r
+    PAH831X_REG__B4_0X12,\r
+    PAH831X_REG__B4_0X16,\r
+    PAH831X_REG__B4_0X19,\r
+    PAH831X_REG__B4_0X1C,\r
+    PAH831X_REG__B4_0X1F,\r
+    PAH831X_REG__B4_0X22,\r
+    PAH831X_REG__B4_0X25,\r
+    PAH831X_REG__B4_0X28,\r
+};\r
+\r
+//============================================================================\r
+// Private function\r
+//============================================================================\r
+static void reset_state(pah831x *state);\r
+\r
+static pah_ret read_product_id(pah_plat *plat, uint16_t *product_id);\r
+static pah_ret read_ppg_leddac_regs(pah_plat *plat, uint8_t ppg_leddac_regs[PPG_LEDDAC_REG__NUM]);\r
+static pah_ret read_int_flag(pah_plat *plat, pah831x_int_flag *int_flag);\r
+static pah_ret read_touch_flag(pah_plat *plat, bool *touch_flag);\r
+static pah_ret read_touch_value(pah_plat *plat, uint16_t *touch_value);\r
+static pah_ret read_fifo_data_count(pah_plat *plat, uint16_t *fifo_data_count);\r
+static pah_ret read_fifo(pah_plat *plat, uint8_t *buffer, size_t read_size);\r
+static pah_ret read_fifo_ex(pah_plat *plat, uint8_t *buffer, size_t buffer_size, uint16_t data_count, size_t sample_size, pah831x_read_fifo_cb read_fifo_cb, void *user_data);\r
+\r
+static pah_ret write_reg_arr(pah_plat *plat, const pah_reg_arr *reg_arr);\r
+static pah_ret write_reg_array(pah_plat *plat, const uint8_t reg_array[][2], size_t length);\r
+static pah_ret write_fifo_watermark(pah_plat *plat, uint16_t fifo_watermark);\r
+static pah_ret write_ppg_led(pah_plat *plat, uint8_t ppg_led[PAH831X_CH__PPG_NUM]);\r
+\r
+static pah_ret set_soft_reset(pah_plat *plat);\r
+static pah_ret set_power_off(pah_plat *plat);\r
+static pah_ret set_power_down(pah_plat *plat);\r
+static pah_ret set_update_flag(pah_plat *plat);\r
+static pah_ret enable_report_start_timer(pah_plat *plat);\r
+static pah_ret enable_fifo_clk(pah_plat *plat);\r
+static pah_ret disable_fifo_clk(pah_plat *plat);\r
+static pah_ret enable_read_fifo(pah_plat *plat);\r
+static pah_ret disable_read_fifo(pah_plat *plat);\r
+static pah_ret clear_int_flag(pah_plat *plat);\r
+\r
+static pah_ret comm_write(/*pah_plat *plat,*/ uint8_t addr, uint8_t data);\r
+static pah_ret comm_read(/*pah_plat *plat,*/ uint8_t addr, uint8_t *data, size_t read_size);\r
+\r
+static bool regs_contains_report_period(const pah831x_regs *regs);\r
+static bool regs_contains_ch_enh(const pah831x_regs *regs);\r
+static pah831x_verify_reg_arr_ret verify_regs_ppg_frame_period(const pah831x_regs *regs, float ppg_sample_rate, float ecg_sample_rate, uint16_t *frame_period, uint16_t *max_frame_period);\r
+\r
+static uint16_t determine_sample_data_count(const pah831x_ppg *ppg, const pah831x_ecg *ecg, uint16_t *ppg_sample_data_count, uint16_t *ecg_sample_data_count);\r
+static bool ppg_is_enabled(const pah831x_ppg *ppg);\r
+static bool ecg_is_enabled(const pah831x_ecg *ecg);\r
+\r
+static void extract_regs(const pah_reg_arr *reg_arr, pah831x_regs *regs);\r
+static void set_regs_merge_ch_enh(pah831x_regs *regs, const pah_reg_arr *reg_arr);\r
+static void set_ppg_leddac_reg_cal(pah831x_regs *regs, uint8_t ppg_leddac_regs[PPG_LEDDAC_REG__NUM]);\r
+static void set_regs_turn_off_ppg_led(pah831x_regs *regs);\r
+static void set_regs_enable_ecg_write_fifo(pah831x_regs *regs);\r
+static void set_regs_enable_ecg_polar_switch(pah831x_regs *regs);\r
+static void set_regs_ppg_decimation_num(pah831x_regs *regs, uint8_t decimation_num);\r
+static void set_regs_ch_t_report_divider(pah831x_regs *regs, uint16_t value);\r
+static pah_ret write_changed_regs(pah_plat *plat, const pah831x_regs *regs);\r
+static uint16_t extract_ecg_frame_num(const pah831x_regs *regs);\r
+static uint8_t extract_ecg_gain(const pah831x_regs *regs);\r
+static void extract_ppg_ch_enh(const pah831x_regs *regs, bool ppg_ch_enh[PAH831X_PPG_CH__NUM]);\r
+static uint8_t extract_ppg_ch_num(const pah831x_regs *regs);\r
+static void extract_ppg_ch_write_fifo(const pah831x_regs *regs, bool ppg_ch_write_fifo[PAH831X_CH__PPG_NUM]);\r
+static void extract_ppg_led(const pah831x_regs *regs, uint8_t ppg_led[PAH831X_CH__PPG_NUM]);\r
+static bool extract_ecg_ch_enabled(const pah831x_regs *regs);\r
+float extract_ppg_sample_rate(const pah831x_regs *regs);\r
+float extract_ecg_sample_rate(const pah831x_regs *regs);\r
+static uint32_t extract_report_period(const pah831x_regs *regs);\r
+static uint8_t extract_decimation_num(const  pah831x_regs *regs);\r
+static pah831x_ch extract_ch(const uint8_t *fifo, uint16_t data_index);\r
+static uint8_t extract_ch_tag(const uint8_t *fifo, uint16_t data_index);\r
+\r
+static void select_watermarks(float ppg_sample_rate, uint8_t ppg_ch_num, float ecg_sample_rate, uint32_t batch_period, uint16_t *ppg_watermark, uint16_t *ecg_watermark, uint16_t *fifo_watermark);\r
+\r
+static float calculate_sample_rate(uint32_t report_period, uint8_t decimation_num);\r
+static uint16_t calculate_ecg_watermark_factor(float ppg_sample_rate, float ecg_sample_rate);\r
+static uint8_t calculate_decimation_num(float sample_rate, uint32_t report_period);\r
+static bool calculate_ppg_frame_period(const pah831x_regs *regs, uint16_t *ppg_frame_period);\r
+static uint16_t calculate_ppg_ch_frame_period(uint8_t frame_num, uint8_t ppg_ip_stl);\r
+static float sample_rate_to_sample_period(float sample_rate);\r
+static bool ecg_is_divisible_by_ppg(float ppg_sample_rate, float ecg_sample_rate);\r
+\r
+static int32_t cvt24bit(uint32_t val);\r
+\r
+//============================================================================\r
+// Public function\r
+//============================================================================\r
+uint16_t pah831x_default_i2c_slave_addr(void)\r
+{\r
+    return PAH831X_DEFAULT_I2C_SLAVE_ADDR;\r
+}\r
+\r
+void pah831x_init(pah831x *state, const pah_plat *plat, const pah831x_init_reg_setting *init_reg_setting)\r
+{\r
+    memset(state, 0, sizeof(*state));\r
+\r
+    state->plat = *plat;\r
+\r
+    state->setting.init_reg_setting = *init_reg_setting;\r
+    state->setting.batch_period_ms = PAH831X_DEFAULT_BATCH_PERIOD_MS;\r
+}\r
+\r
+void pah831x_deinit(pah831x *state)\r
+{\r
+    pah_plat *plat = &state->plat;\r
+\r
+    write_reg_arr(plat, &state->setting.init_reg_setting.deinit);\r
+\r
+    pah831x_power_off(state);\r
+}\r
+\r
+\r
+\r
+void pah831x_set_ppg_led_on(pah831x *state, pah831x_ppg_led_on ppg_led_on)\r
+{\r
+    state->setting.ppg_led_on = ppg_led_on;\r
+}\r
+\r
+void pah831x_set_batch_period(pah831x *state, uint32_t batch_period_ms)\r
+{\r
+    state->setting.batch_period_ms = batch_period_ms;\r
+}\r
+\r
+void pah831x_set_ecg_polar_switch(pah831x *state, bool enable_ecg_polar_switch)\r
+{\r
+    state->setting.enable_ecg_polar_switch = enable_ecg_polar_switch;\r
+}\r
+\r
+pah_ret pah831x_soft_reset(pah831x *state)\r
+{\r
+    pah_ret ret;\r
+    pah_plat *plat = &state->plat;\r
+\r
+    ret = set_soft_reset(plat);\r
+    PAH_CHECK_RET(ret);\r
+    reset_state(state);\r
+\r
+    return PAH_RET_SUCCESS;\r
+}\r
+\r
+pah_ret pah831x_power_off(pah831x *state)\r
+{\r
+    pah_ret ret;\r
+    pah_plat *plat = &state->plat;\r
+\r
+    ret = set_power_off(plat);\r
+    PAH_CHECK_RET(ret);\r
+    reset_state(state);\r
+\r
+    return PAH_RET_SUCCESS;\r
+}\r
+\r
+pah_ret pah831x_start(pah831x *state, const pah_reg_arr *reg_arr)\r
+{\r
+    pah_ret ret;\r
+    pah_plat *plat = &state->plat;\r
+    pah831x_regs regs;\r
+    pah831x_ppg ppg;\r
+    pah831x_ecg ecg;\r
+    uint16_t fifo_watermark = 0;\r
+    uint8_t ppg_leddac_regs[PPG_LEDDAC_REG__NUM];\r
+\r
+    memset(&regs, 0, sizeof(regs));\r
+    memset(&ppg, 0, sizeof(ppg));\r
+    memset(&ecg, 0, sizeof(ecg));\r
+\r
+    extract_regs(&state->setting.init_reg_setting.init, &regs);\r
+    extract_regs(&state->setting.init_reg_setting.init_cal_1, &regs);\r
+    if (reg_arr)\r
+        extract_regs(reg_arr, &regs);\r
+\r
+    ppg.sample_rate = extract_ppg_sample_rate(&regs);\r
+    ppg.ch_num = extract_ppg_ch_num(&regs);\r
+\r
+    ecg.sample_rate = extract_ecg_sample_rate(&regs);\r
+    ecg.enabled = extract_ecg_ch_enabled(&regs);\r
+    ecg.frame_num = extract_ecg_frame_num(&regs);\r
+    ecg.gain = extract_ecg_gain(&regs);\r
+\r
+    if (state->setting.ppg_led_on == PAH831X_PPG_LED_ON_DEFERRED && ppg_is_enabled(&ppg))\r
+    {\r
+        extract_ppg_led(&regs, state->ppg_led);\r
+        set_regs_turn_off_ppg_led(&regs);\r
+        state->is_ppg_led_on = false;\r
+    }\r
+\r
+    if (state->setting.enable_ecg_polar_switch && ecg_is_enabled(&ecg))\r
+        set_regs_enable_ecg_polar_switch(&regs);\r
+\r
+    ret = set_soft_reset(plat);\r
+    PAH_CHECK_RET(ret);\r
+    reset_state(state);\r
+\r
+    ret = read_ppg_leddac_regs(plat, ppg_leddac_regs);\r
+    PAH_CHECK_RET(ret);\r
+    set_ppg_leddac_reg_cal(&regs, ppg_leddac_regs);\r
+\r
+    ret = write_reg_arr(plat, &state->setting.init_reg_setting.init);\r
+    PAH_CHECK_RET(ret);\r
+    ret = write_reg_arr(plat, &state->setting.init_reg_setting.init_cal_1);\r
+    PAH_CHECK_RET(ret);\r
+    if (reg_arr)\r
+    {\r
+        ret = write_reg_arr(plat, reg_arr);\r
+        PAH_CHECK_RET(ret);\r
+    }\r
+\r
+        if (ppg_is_enabled(&ppg) || ecg_is_enabled(&ecg))\r
+        {\r
+            select_watermarks(ppg.sample_rate, ppg.ch_num, ecg.sample_rate, state->setting.batch_period_ms, &ppg.watermark, &ecg.watermark, &fifo_watermark);\r
+            ret = write_fifo_watermark(plat, fifo_watermark);\r
+            PAH_CHECK_RET(ret);\r
+        }\r
+\r
+    ret = write_changed_regs(plat, &regs);\r
+    PAH_CHECK_RET(ret);\r
+\r
+    ret = set_update_flag(plat);\r
+    PAH_CHECK_RET(ret);\r
+    DELAY_MS(UPDATE_FLAG_DELAY_MS);\r
+    ret = enable_report_start_timer(plat);\r
+    PAH_CHECK_RET(ret);\r
+\r
+    state->sample_data_count = determine_sample_data_count(&ppg, &ecg, &ppg.sample_data_count, &ecg.sample_data_count);\r
+    state->ppg = ppg;\r
+    state->ecg = ecg;\r
+    state->fifo_watermark = fifo_watermark;\r
+    state->is_started = true;\r
+\r
+    return PAH_RET_SUCCESS;\r
+}\r
+\r
+pah_ret pah831x_start_2(pah831x *state, const pah_reg_arr *ppg_reg_arr, const pah_reg_arr *ecg_reg_arr)\r
+{\r
+    pah_ret ret;\r
+    pah_plat *plat = &state->plat;\r
+    pah831x_regs regs;\r
+    pah831x_ppg ppg;\r
+    pah831x_ecg ecg;\r
+    uint16_t fifo_watermark = 0;\r
+    uint8_t ppg_leddac_regs[PPG_LEDDAC_REG__NUM];\r
+\r
+    memset(&regs, 0, sizeof(regs));\r
+    memset(&ppg, 0, sizeof(ppg));\r
+    memset(&ecg, 0, sizeof(ecg));\r
+\r
+    extract_regs(&state->setting.init_reg_setting.init, &regs);\r
+    extract_regs(&state->setting.init_reg_setting.init_cal_1, &regs);\r
+    if (ppg_reg_arr->reg_arr_len)\r
+    {\r
+        extract_regs(ppg_reg_arr, &regs);\r
+        ppg.sample_rate = extract_ppg_sample_rate(&regs);\r
+        ppg.ch_num = extract_ppg_ch_num(&regs);\r
+    }\r
+    if (ecg_reg_arr->reg_arr_len)\r
+    {\r
+        extract_regs(ecg_reg_arr, &regs);\r
+        ecg.sample_rate = extract_ecg_sample_rate(&regs);\r
+        ecg.enabled = extract_ecg_ch_enabled(&regs);\r
+        ecg.frame_num = extract_ecg_frame_num(&regs);\r
+        ecg.gain = extract_ecg_gain(&regs);\r
+        ppg.ch_num = extract_ppg_ch_num(&regs);\r
+        ppg.sample_rate = extract_ppg_sample_rate(&regs);\r
+    }\r
+\r
+    if (ppg_reg_arr->reg_arr_len)\r
+    {\r
+        set_regs_merge_ch_enh(&regs, ppg_reg_arr);\r
+\r
+        state->is_ppg_led_on = true;\r
+        if (state->setting.ppg_led_on == PAH831X_PPG_LED_ON_DEFERRED)\r
+        {\r
+            extract_ppg_led(&regs, state->ppg_led);\r
+            set_regs_turn_off_ppg_led(&regs);\r
+            state->is_ppg_led_on = false;\r
+        }\r
+    }\r
+    if (ecg_reg_arr->reg_arr_len)\r
+    {\r
+        set_regs_merge_ch_enh(&regs, ecg_reg_arr);\r
+\r
+        set_regs_enable_ecg_write_fifo(&regs);\r
+        if (state->setting.enable_ecg_polar_switch)\r
+            set_regs_enable_ecg_polar_switch(&regs);\r
+\r
+        if (ppg_reg_arr->reg_arr_len)\r
+        //if (ppg_reg_arr)\r
+        {\r
+            uint32_t report_period = extract_report_period(&regs);\r
+            uint8_t ppg_decimation_num = calculate_decimation_num(ppg.sample_rate, report_period);\r
+            set_regs_ppg_decimation_num(&regs, ppg_decimation_num);\r
+            \r
+            set_regs_ch_t_report_divider(&regs, 1);\r
+        }\r
+    }\r
+\r
+    ret = set_soft_reset(plat);\r
+    PAH_CHECK_RET(ret);\r
+    reset_state(state);\r
+\r
+    ret = read_ppg_leddac_regs(plat, ppg_leddac_regs);\r
+    PAH_CHECK_RET(ret);\r
+    set_ppg_leddac_reg_cal(&regs, ppg_leddac_regs);\r
+\r
+    ret = write_reg_arr(plat, &state->setting.init_reg_setting.init);\r
+    PAH_CHECK_RET(ret);\r
+    ret = write_reg_arr(plat, &state->setting.init_reg_setting.init_cal_1);\r
+    PAH_CHECK_RET(ret);\r
+    if (ppg_reg_arr->reg_arr_len)\r
+    {\r
+        ret = write_reg_arr(plat, ppg_reg_arr);\r
+        PAH_CHECK_RET(ret);\r
+    }\r
+    if (ecg_reg_arr->reg_arr_len)\r
+    {\r
+        ret = write_reg_arr(plat, ecg_reg_arr);\r
+        PAH_CHECK_RET(ret);\r
+    }\r
+    \r
+    if (ppg_reg_arr->reg_arr_len || ecg_reg_arr->reg_arr_len)\r
+    {\r
+        select_watermarks(ppg.sample_rate, ppg.ch_num, ecg.sample_rate, state->setting.batch_period_ms, &ppg.watermark, &ecg.watermark, &fifo_watermark);\r
+        ret = write_fifo_watermark(plat, fifo_watermark);\r
+        PAH_CHECK_RET(ret);\r
+    }\r
+\r
+    ret = write_changed_regs(plat, &regs);\r
+    PAH_CHECK_RET(ret);\r
+\r
+     if(state->ir_r_led_switch_enable)\r
+     {\r
+            DEBUG_PRINT("this->ir_r_led_switch_status = %d\n",state->ir_r_led_switch_status);\r
+            if(state->ir_r_led_switch_status)\r
+            {\r
+                pah831x_ir_r_led_control(state->ir_r_led_switch_enable);\r
+            }\r
+    }\r
+//    DEBUG_PRINT("state->afe_gain_flag =%d \n",state->afe_gain_flag);\r
+//    switch (state->afe_gain_flag)\r
+//    {\r
+//        case pah_AFE_GAIN_CHA_75K :\r
+//            pah831x_update_ch_a_75k();\r
+//            break;\r
+//        case pah_AFE_GAIN_CHA_150K :\r
+//            pah831x_update_ch_a_150k();\r
+//            break;\r
+//        case pah_AFE_GAIN_CHA_1000K :\r
+//            pah831x_update_ch_a_1000k();\r
+//            break;\r
+//        case pah_AFE_GAIN_CHA_350K_LOW :\r
+//            pah831x_update_ch_a_350k_low();\r
+//            break;\r
+\r
+//        default:\r
+//            DEBUG_PRINT("No Support Setting \n");\r
+//            break;            \r
+//    }\r
+    \r
+    \r
+    \r
+    ret = set_update_flag(plat);\r
+    PAH_CHECK_RET(ret);\r
+    DELAY_MS(UPDATE_FLAG_DELAY_MS);\r
+    ret = enable_report_start_timer(plat);\r
+    PAH_CHECK_RET(ret);\r
+\r
+    state->sample_data_count = determine_sample_data_count(&ppg, &ecg, &ppg.sample_data_count, &ecg.sample_data_count);\r
+    state->ppg = ppg;\r
+    state->ecg = ecg;\r
+    state->fifo_watermark = fifo_watermark;\r
+    state->is_started = true;\r
+\r
+    return PAH_RET_SUCCESS;\r
+}\r
+\r
+pah_ret pah831x_verify_product_id(pah831x *state, uint16_t *product_id)\r
+{\r
+    return pah831x_hal_verify_product_id(&state->plat, product_id);\r
+}\r
+\r
+pah_ret pah831x_hal_verify_product_id(pah_plat *plat, uint16_t *product_id)\r
+{\r
+    pah_ret ret;\r
+    uint16_t data = 0;\r
+\r
+    ret = read_product_id(plat, &data);\r
+    PAH_CHECK_RET(ret);\r
+\r
+    if (product_id)\r
+        *product_id = data;\r
+    if (data != 0x8311)\r
+        return PAH_RET_VERIFY_FAILED;\r
+\r
+    return PAH_RET_SUCCESS;\r
+}\r
+\r
+pah_ret pah831x_hal_soft_reset(pah_plat *plat)\r
+{\r
+    return set_soft_reset(plat);\r
+}\r
+\r
+pah_ret pah831x_hal_power_down(pah_plat *plat)\r
+{\r
+    return set_power_down(plat);\r
+}\r
+\r
+pah_ret pah831x_reset_batch_period(pah831x *state, uint32_t batch_period_ms)\r
+{\r
+    pah_ret ret;\r
+    pah_plat *plat = &state->plat;\r
+    pah831x_ppg ppg = state->ppg;\r
+    pah831x_ecg ecg = state->ecg;\r
+    uint16_t fifo_watermark = 0;\r
+\r
+    if (!state->is_started)\r
+        return PAH_RET_INVALID_OPERATION;\r
+\r
+    select_watermarks(ppg.sample_rate, ppg.ch_num, ecg.sample_rate, batch_period_ms, &ppg.watermark, &ecg.watermark, &fifo_watermark);\r
+    if (state->fifo_watermark != fifo_watermark)\r
+    {\r
+        ret = write_fifo_watermark(plat, fifo_watermark);\r
+        PAH_CHECK_RET(ret);\r
+        ret = set_update_flag(plat);\r
+        PAH_CHECK_RET(ret);\r
+    }\r
+\r
+    state->sample_data_count = determine_sample_data_count(&ppg, &ecg, &ppg.sample_data_count, &ecg.sample_data_count);\r
+    state->ppg = ppg;\r
+    state->ecg = ecg;\r
+    state->fifo_watermark = fifo_watermark;\r
+    state->setting.batch_period_ms = batch_period_ms;\r
+\r
+    return PAH_RET_SUCCESS;\r
+}\r
+\r
+uint32_t pah831x_get_batch_period(pah831x *state)\r
+{\r
+    const pah831x_ppg *ppg = &state->ppg;\r
+    const pah831x_ecg *ecg = &state->ecg;\r
+\r
+    if (!state->is_started)\r
+        return 0;\r
+\r
+    if (ecg->sample_rate > 0.0f)\r
+        return (uint32_t)(ecg->watermark * sample_rate_to_sample_period(ecg->sample_rate));\r
+    else if (ppg->sample_rate > 0.0f)\r
+        return (uint32_t)(ppg->watermark * sample_rate_to_sample_period(ppg->sample_rate));\r
+\r
+    return 0;\r
+}\r
+\r
+uint32_t pah831x_get_max_batch_period(pah831x *state)\r
+{\r
+    const pah831x_ppg *ppg = &state->ppg;\r
+    const pah831x_ecg *ecg = &state->ecg;\r
+    uint16_t sample_data_count = 0;\r
+    uint16_t max_watermark = 0;\r
+    float sample_period = 0.0f;\r
+\r
+    if (!state->is_started)\r
+        return 0;\r
+\r
+    if (ppg_is_enabled(ppg))\r
+    {\r
+        sample_data_count += PAH831X_MAX_PPG_CH_NUM;\r
+    }\r
+\r
+    if (ecg_is_enabled(ecg))\r
+    {\r
+        if (ppg_is_enabled(ppg))\r
+            sample_data_count += calculate_ecg_watermark_factor(ppg->sample_rate, ecg->sample_rate);\r
+        else\r
+            sample_data_count += 1;\r
+    }\r
+\r
+    if (sample_data_count == 0)\r
+        return 0;\r
+\r
+    max_watermark = PAH831X_MAX_DATA_COUNT / sample_data_count;\r
+\r
+    if (ppg_is_enabled(ppg))\r
+        sample_period = sample_rate_to_sample_period(ppg->sample_rate);\r
+    else if (ecg_is_enabled(ecg))\r
+        sample_period = sample_rate_to_sample_period(ecg->sample_rate);\r
+\r
+    return (uint32_t)(max_watermark * sample_period);\r
+}\r
+\r
+uint16_t pah831x_get_fifo_watermark(pah831x *state)\r
+{\r
+    return state->fifo_watermark;\r
+}\r
+\r
+size_t pah831x_get_sample_size(pah831x *state)\r
+{\r
+    return state->sample_data_count * PAH831X_DATA_SIZE;\r
+}\r
+\r
+bool pah831x_get_ppg_is_enabled(pah831x *state)\r
+{\r
+    return ppg_is_enabled(&state->ppg);\r
+}\r
+\r
+float pah831x_get_ppg_sample_rate(pah831x *state)\r
+{\r
+    return state->ppg.sample_rate;\r
+}\r
+\r
+uint16_t pah831x_get_ppg_watermark(pah831x *state)\r
+{\r
+    return state->ppg.watermark;\r
+}\r
+\r
+uint16_t pah831x_get_max_ppg_watermark(void)\r
+{\r
+    return PAH831X_PPG_MAX_WATERMARK;\r
+}\r
+\r
+uint8_t pah831x_get_ppg_ch_num(pah831x *state)\r
+{\r
+    return state->ppg.ch_num;\r
+}\r
+\r
+bool pah831x_get_ecg_is_enabled(pah831x *state)\r
+{\r
+    return ecg_is_enabled(&state->ecg);\r
+}\r
+\r
+float pah831x_get_ecg_sample_rate(pah831x *state)\r
+{\r
+    return state->ecg.sample_rate;\r
+}\r
+\r
+uint16_t pah831x_get_ecg_watermark(pah831x *state)\r
+{\r
+    return state->ecg.watermark;\r
+}\r
+\r
+uint16_t pah831x_get_ecg_frame_num(pah831x *state)\r
+{\r
+    return state->ecg.frame_num;\r
+}\r
+\r
+uint8_t pah831x_get_ecg_gain(pah831x *state)\r
+{\r
+    return state->ecg.gain;\r
+}\r
+\r
+uint16_t pah831x_get_max_ecg_watermark(void)\r
+{\r
+    return PAH831X_ECG_MAX_WATERMARK;\r
+}\r
+\r
+pah_ret pah831x_read_int_flag(pah831x *state, pah831x_int_flag *int_flag)\r
+{\r
+    pah_ret ret;\r
+    \r
+    ret = read_int_flag(&state->plat, &state->int_flag);\r
+    PAH_CHECK_RET(ret);\r
+\r
+    state->has_int_flag = true;\r
+\r
+    *int_flag = state->int_flag;\r
+\r
+    return PAH_RET_SUCCESS;\r
+}\r
+\r
+uint16_t pah831x_read_fifo_data_count(pah831x *state)\r
+{\r
+    pah_ret ret;\r
+    uint16_t fifo_data_count = 0;\r
+\r
+    ret = read_fifo_data_count(&state->plat, &fifo_data_count);\r
+    if (PAH_FAILED(ret))\r
+        return 0;\r
+\r
+    if(state->sample_data_count!= 0)\r
+        return (fifo_data_count / state->sample_data_count) * state->sample_data_count;\r
+    else\r
+        return 0;\r
+}\r
+\r
+void pah831x_deduce_sample_num(pah831x *state, uint16_t data_count, uint16_t *sample_num, uint16_t *ppg_sample_num, uint16_t *ecg_sample_num)\r
+{\r
+    const pah831x_ppg *ppg = &state->ppg;\r
+    const pah831x_ecg *ecg = &state->ecg;\r
+    uint16_t sample_count = data_count / state->sample_data_count;\r
+\r
+    if (sample_num)\r
+        *sample_num = sample_count;\r
+    if (ppg_sample_num && ppg_is_enabled(ppg))\r
+        *ppg_sample_num = sample_count * (ppg->sample_data_count / ppg->ch_num);\r
+    if (ecg_sample_num && ecg_is_enabled(ecg))\r
+        *ecg_sample_num = sample_count * (ecg->sample_data_count / 1);\r
+}\r
+\r
+pah_ret pah831x_read_fifo(pah831x *state, uint8_t *buffer, size_t buffer_size, uint16_t data_count, pah831x_read_fifo_cb read_fifo_cb, void *user_data)\r
+{\r
+    size_t sample_size = pah831x_get_sample_size(state);\r
+    return read_fifo_ex(&state->plat, buffer, buffer_size, data_count, sample_size, read_fifo_cb, user_data);\r
+}\r
+\r
+pah_ret pah831x_read_touch_flag(pah831x *state, bool *touch_flag)\r
+{\r
+    return read_touch_flag(&state->plat, touch_flag);\r
+}\r
+\r
+pah_ret pah831x_read_touch_value(pah831x *state, uint16_t *touch_value)\r
+{\r
+    return read_touch_value(&state->plat, touch_value);\r
+}\r
+\r
+pah_ret pah831x_polling_fifo_begin(pah831x *state)\r
+{\r
+    pah_ret ret;\r
+    pah_plat *plat = &state->plat;\r
+\r
+    ret = enable_fifo_clk(plat);\r
+    PAH_CHECK_RET(ret);\r
+\r
+    state->fifo_clock_enabled = true;\r
+\r
+    return PAH_RET_SUCCESS;\r
+}\r
+\r
+pah_ret pah831x_manual_read_fifo_begin(pah831x *state)\r
+{\r
+    return enable_read_fifo(&state->plat);\r
+}\r
+\r
+pah_ret pah831x_manual_read_fifo(pah831x *state, uint8_t *buffer, size_t read_size)\r
+{\r
+    return read_fifo(&state->plat, buffer, read_size);\r
+}\r
+\r
+pah_ret pah831x_manual_read_fifo_end(pah831x *state)\r
+{\r
+    return disable_read_fifo(&state->plat);\r
+}\r
+\r
+pah_ret pah831x_task(pah831x *state)\r
+{\r
+    pah_ret ret;\r
+    pah_plat *plat = &state->plat;\r
+    bool need_update_flag = false;\r
+\r
+    if (!state->is_ppg_led_on)\r
+    {\r
+        if (!state->has_int_flag)\r
+        {\r
+            ret = read_int_flag(plat, &state->int_flag);\r
+            PAH_CHECK_RET(ret);\r
+        }\r
+\r
+        if (state->int_flag.touch_flag > 0)\r
+        {\r
+            ret = write_ppg_led(plat, state->ppg_led);\r
+            PAH_CHECK_RET(ret);\r
+            need_update_flag = true;\r
+            state->is_ppg_led_on = true;\r
+        }\r
+    }\r
+\r
+    if (state->fifo_clock_enabled)\r
+    {\r
+        ret = disable_fifo_clk(plat);\r
+        PAH_CHECK_RET(ret);\r
+\r
+        state->fifo_clock_enabled = false;\r
+    }\r
+\r
+    if (need_update_flag)\r
+    {\r
+        ret = set_update_flag(plat);\r
+        PAH_CHECK_RET(ret);\r
+    }\r
+\r
+    ret = clear_int_flag(plat);\r
+    PAH_CHECK_RET(ret);\r
+    state->has_int_flag = false;\r
+\r
+    return PAH_RET_SUCCESS;\r
+}\r
+\r
+void pah831x_extract_sample_num(const uint8_t *fifo, uint16_t data_count, uint16_t *ppg_sample_num, uint16_t *ecg_sample_num)\r
+{\r
+    uint16_t ppg_sample_count = 0;\r
+    uint16_t ecg_sample_count = 0;\r
+    int last_ch = (int)PAH831X_CH__NUM;\r
+    uint16_t data_index = 0;\r
+\r
+    for (data_index = 0; data_index < data_count; ++data_index)\r
+    {\r
+        int ch = (int)extract_ch(fifo, data_index);\r
+\r
+        if (ch == PAH831X_CH__ECG)\r
+        {\r
+            ++ecg_sample_count;\r
+            last_ch = ch;\r
+        }\r
+        else if (ch <= last_ch)\r
+        {\r
+            ++ppg_sample_count;\r
+            last_ch = ch;\r
+        }\r
+    }\r
+\r
+    if (ppg_sample_num)\r
+        *ppg_sample_num = ppg_sample_count;\r
+    if (ecg_sample_num)\r
+        *ecg_sample_num = ecg_sample_count;\r
+}\r
+\r
+void pah831x_extract_ppg_sample(const uint8_t *fifo, uint16_t data_count, uint16_t sample_index, pah831x_ppg_sample *ppg_sample)\r
+{\r
+    int last_ch = (int)PAH831X_CH__NUM;\r
+    int16_t ppg_sample_index = -1;\r
+    uint16_t data_index = 0;\r
+\r
+    memset(ppg_sample, 0, sizeof(*ppg_sample));\r
+\r
+    for (data_index = 0; data_index < data_count; ++data_index)\r
+    {\r
+        pah831x_ch ch = extract_ch(fifo, data_index);\r
+\r
+        if ((int)ch <= last_ch && ch != PAH831X_CH__ECG)\r
+        {\r
+            ++ppg_sample_index;\r
+            last_ch = (int)ch;\r
+        }\r
+\r
+        if (ppg_sample_index == sample_index)\r
+        {\r
+            uint16_t fifo_index = PAH831X_DATA_SIZE * data_index;\r
+            uint8_t dac = fifo[fifo_index + 0];\r
+            uint32_t data = 0;\r
+\r
+            memcpy((uint8_t*)&data, &fifo[fifo_index + 2], 3);\r
+\r
+            if (ch < PAH831X_CH__PPG_NUM)\r
+            {\r
+                ppg_sample->has_data[ch] = true;\r
+                ppg_sample->data[ch] = data;\r
+                ppg_sample->dac[ch] = dac;\r
+            }\r
+        }\r
+        else if (ppg_sample_index > sample_index)\r
+        {\r
+            break;\r
+        }\r
+    }\r
+}\r
+\r
+void pah831x_extract_ecg_sample(const uint8_t *fifo, uint16_t data_count, uint16_t sample_index, pah831x_ecg_sample *ecg_sample)\r
+{\r
+    int16_t ecg_sample_index = -1;\r
+    uint16_t data_index = 0;\r
+\r
+    memset(ecg_sample, 0, sizeof(*ecg_sample));\r
+\r
+    for (data_index = 0; data_index < data_count; ++data_index)\r
+    {\r
+        pah831x_ch ch = extract_ch(fifo, data_index);\r
+\r
+        if (ch == PAH831X_CH__ECG)\r
+            ++ecg_sample_index;\r
+        \r
+        if (ecg_sample_index == sample_index)\r
+        {\r
+            uint16_t fifo_index = PAH831X_DATA_SIZE * data_index;\r
+            uint8_t ecg_tag = fifo[fifo_index + 0];\r
+            uint32_t rawdata = 0;\r
+\r
+            memcpy((uint8_t*)&rawdata, &fifo[fifo_index + 2], 3);\r
+\r
+            ecg_sample->tag = ecg_tag;\r
+            ecg_sample->data = cvt24bit(rawdata);\r
+\r
+            break;\r
+        }\r
+    }\r
+}\r
+\r
+float pah831x_extract_ppg_sample_rate(const pah_reg_arr *reg_arr)\r
+{\r
+    pah831x_regs regs;\r
+\r
+    extract_regs(reg_arr, &regs);\r
+\r
+    return extract_ppg_sample_rate(&regs);\r
+}\r
+\r
+float pah831x_extract_ecg_sample_rate(const pah_reg_arr *reg_arr)\r
+{\r
+    pah831x_regs regs;\r
+\r
+    extract_regs(reg_arr, &regs);\r
+\r
+    return extract_ecg_sample_rate(&regs);\r
+}\r
+\r
+float pah831x_ecg_to_adc(pah831x *state, int32_t data)\r
+{\r
+    float frame_num = (float)state->ecg.frame_num;\r
+\r
+    float adc = (float)(data - (63488.0f * frame_num)) * 2.4f / (126976.0f * frame_num);\r
+    return adc * 1000.0f;\r
+}\r
+\r
+pah831x_verify_reg_arr_ret pah831x_verify_reg_arr_start(pah831x *state, const pah_reg_arr *reg_arr)\r
+{\r
+    pah831x_verify_reg_arr_ret ret;\r
+    pah831x_regs regs;\r
+    float ppg_sample_rate = 0.0f;\r
+    uint8_t ppg_ch_num = 0;\r
+    float ecg_sample_rate = 0.0f;\r
+    bool ecg_enabled = false;\r
+\r
+    memset(&regs, 0, sizeof(regs));\r
+\r
+    extract_regs(&state->setting.init_reg_setting.init, &regs);\r
+    extract_regs(&state->setting.init_reg_setting.init_cal_1, &regs);\r
+    extract_regs(reg_arr, &regs);\r
+\r
+    ppg_ch_num = extract_ppg_ch_num(&regs);\r
+    ppg_sample_rate = ppg_ch_num > 0 ? extract_ppg_sample_rate(&regs) : 0.0f;\r
+\r
+    ecg_enabled = extract_ecg_ch_enabled(&regs);\r
+    ecg_sample_rate = ecg_enabled ? extract_ecg_sample_rate(&regs) : 0.0f;\r
+\r
+    ret = verify_regs_ppg_frame_period(&regs, ppg_sample_rate, ecg_sample_rate, NULL, NULL);\r
+    if (ret != PAH831X_VERIFY_REG_ARR_RET__SUCCESS)\r
+        return ret;\r
+\r
+    if (ppg_sample_rate > 0.0f && ecg_sample_rate > 0.0f && !ecg_is_divisible_by_ppg(ppg_sample_rate, ecg_sample_rate))\r
+        return PAH831X_VERIFY_REG_ARR_RET__ECG_PPG_NOT_DIVISIBLE;\r
+\r
+    return PAH831X_VERIFY_REG_ARR_RET__SUCCESS;\r
+}\r
+\r
+pah831x_verify_reg_arr_ret pah831x_verify_reg_arr_start_2(pah831x *state, const pah_reg_arr *ppg_reg_arr, const pah_reg_arr *ecg_reg_arr)\r
+{\r
+    pah831x_verify_reg_arr_ret ret;\r
+    pah831x_regs regs;\r
+    float ppg_sample_rate = 0.0f;\r
+    float ecg_sample_rate = 0.0f;\r
+\r
+    memset(&regs, 0, sizeof(regs));\r
+\r
+    extract_regs(&state->setting.init_reg_setting.init, &regs);\r
+    extract_regs(&state->setting.init_reg_setting.init_cal_1, &regs);\r
+    if (ppg_reg_arr)\r
+        extract_regs(ppg_reg_arr, &regs);\r
+    if (ecg_reg_arr)\r
+        extract_regs(ecg_reg_arr, &regs);\r
+    if (ppg_reg_arr)\r
+        set_regs_merge_ch_enh(&regs, ppg_reg_arr);\r
+    if (ecg_reg_arr)\r
+        set_regs_merge_ch_enh(&regs, ecg_reg_arr);\r
+\r
+    if (!regs.has_values[PAH831X_REG__B0_0X71])\r
+        return PAH831X_VERIFY_REG_ARR_RET__MISS_PPG1_F_ENH;\r
+\r
+    if (ppg_reg_arr)\r
+    {\r
+        pah831x_regs ppg_regs;\r
+\r
+        memset(&ppg_regs, 0, sizeof(ppg_regs));\r
+        extract_regs(ppg_reg_arr, &ppg_regs);\r
+\r
+        if (!regs_contains_report_period(&ppg_regs))\r
+            return PAH831X_VERIFY_REG_ARR_RET__PPG_MISS_REPORT_PERIOD;\r
+        if (!regs_contains_ch_enh(&ppg_regs))\r
+            return PAH831X_VERIFY_REG_ARR_RET__PPG_MISS_CH_ENH;\r
+\r
+        ppg_sample_rate = extract_ppg_sample_rate(&ppg_regs);\r
+        if (ppg_sample_rate <= 0.0f)\r
+            return PAH831X_VERIFY_REG_ARR_RET__PPG_INVALID_SAMPLE_RATE;\r
+\r
+        if (0 == extract_ppg_ch_num(&regs))\r
+            return PAH831X_VERIFY_REG_ARR_RET__PPG_INVALID_CH_NUM;\r
+    }\r
+\r
+    if (ecg_reg_arr)\r
+    {\r
+        pah831x_regs ecg_regs;\r
+\r
+        memset(&ecg_regs, 0, sizeof(ecg_regs));\r
+        extract_regs(ecg_reg_arr, &ecg_regs);\r
+\r
+        if (!regs_contains_report_period(&ecg_regs))\r
+            return PAH831X_VERIFY_REG_ARR_RET__ECG_MISS_REPORT_PERIOD;\r
+        if (!regs_contains_ch_enh(&ecg_regs))\r
+            return PAH831X_VERIFY_REG_ARR_RET__ECG_MISS_CH_ENH;\r
+        if (ecg_regs.has_values[PAH831X_REG__B0_0X71])\r
+            return PAH831X_VERIFY_REG_ARR_RET__ECG_REDUNDANT_REG;\r
+\r
+        ecg_sample_rate = extract_ecg_sample_rate(&ecg_regs);\r
+        if (ecg_sample_rate <= 0.0f)\r
+            return PAH831X_VERIFY_REG_ARR_RET__ECG_INVALID_SAMPLE_RATE;\r
+        if (!extract_ecg_ch_enabled(&regs))\r
+            return PAH831X_VERIFY_REG_ARR_RET__ECG_INVALID_CH_NUM;\r
+    }\r
+\r
+    ret = verify_regs_ppg_frame_period(&regs, ppg_sample_rate, ecg_sample_rate, NULL, NULL);\r
+    if (ret != PAH831X_VERIFY_REG_ARR_RET__SUCCESS)\r
+        return ret;\r
+\r
+    if (ppg_sample_rate > 0.0f && ecg_sample_rate > 0.0f && !ecg_is_divisible_by_ppg(ppg_sample_rate, ecg_sample_rate))\r
+        return PAH831X_VERIFY_REG_ARR_RET__ECG_PPG_NOT_DIVISIBLE;\r
+\r
+    return PAH831X_VERIFY_REG_ARR_RET__SUCCESS;\r
+}\r
+\r
+pah831x_verify_reg_arr_ret pah831x_verify_ppg_reg_arr(pah831x *state, const pah_reg_arr *ppg_reg_arr)\r
+{\r
+    pah831x_regs regs;\r
+    float sample_rate = 0.0f;\r
+\r
+    extract_regs(&state->setting.init_reg_setting.init, &regs);\r
+    extract_regs(&state->setting.init_reg_setting.init_cal_1, &regs);\r
+    extract_regs(ppg_reg_arr, &regs);\r
+\r
+    if (!regs_contains_report_period(&regs))\r
+        return PAH831X_VERIFY_REG_ARR_RET__PPG_MISS_REPORT_PERIOD;\r
+    if (!regs_contains_ch_enh(&regs))\r
+        return PAH831X_VERIFY_REG_ARR_RET__PPG_MISS_CH_ENH;\r
+\r
+    sample_rate = extract_ppg_sample_rate(&regs);\r
+    if (sample_rate <= 0.0f)\r
+        return PAH831X_VERIFY_REG_ARR_RET__PPG_INVALID_SAMPLE_RATE;\r
+\r
+    if (0 == extract_ppg_ch_num(&regs))\r
+        return PAH831X_VERIFY_REG_ARR_RET__PPG_INVALID_CH_NUM;\r
+\r
+    return PAH831X_VERIFY_REG_ARR_RET__SUCCESS;\r
+}\r
+\r
+pah831x_verify_reg_arr_ret pah831x_verify_ecg_reg_arr(pah831x *state, const pah_reg_arr *ecg_reg_arr)\r
+{\r
+    pah831x_regs regs;\r
+    float sample_rate = 0.0f;\r
+\r
+    extract_regs(&state->setting.init_reg_setting.init, &regs);\r
+    extract_regs(&state->setting.init_reg_setting.init_cal_1, &regs);\r
+    extract_regs(ecg_reg_arr, &regs);\r
+\r
+    if (!regs_contains_report_period(&regs))\r
+        return PAH831X_VERIFY_REG_ARR_RET__ECG_MISS_REPORT_PERIOD;\r
+    if (!regs_contains_ch_enh(&regs))\r
+        return PAH831X_VERIFY_REG_ARR_RET__ECG_MISS_CH_ENH;\r
+\r
+    sample_rate = extract_ecg_sample_rate(&regs);\r
+    if (sample_rate <= 0.0f)\r
+        return PAH831X_VERIFY_REG_ARR_RET__ECG_INVALID_SAMPLE_RATE;\r
+\r
+    if (!extract_ecg_ch_enabled(&regs))\r
+        return PAH831X_VERIFY_REG_ARR_RET__ECG_INVALID_CH_NUM;\r
+\r
+    return PAH831X_VERIFY_REG_ARR_RET__SUCCESS;\r
+}\r
+\r
+\r
+pah_ret pah831x_extract_PPG_ADC(uint16_t* adc_buf)\r
+{\r
+\r
+    uint8_t buffer_index = 0 ;\r
+    comm_write( PAH831X_SWITCH_BANK__ADDR, PAH831X_SWITCH_BANK__2);\r
+        \r
+    comm_read( PAH831X_B2__PPG1_A_ADCDATA_ON__ADDR, (uint8_t*)&adc_buf[buffer_index], 8); \r
+    buffer_index = buffer_index+4;\r
+   \r
+    comm_read( PAH831X_B2__PPG1_B_ADCDATA_ON__ADDR, (uint8_t*)&adc_buf[buffer_index], 8); \r
+    buffer_index = buffer_index+4;\r
+   \r
+    comm_read( PAH831X_B2__PPG1_C_ADCDATA_ON__ADDR, (uint8_t*)&adc_buf[buffer_index], 8); \r
+    buffer_index = buffer_index+4;\r
+   \r
+    comm_read( PAH831X_B2__PPG1_D_ADCDATA_ON__ADDR, (uint8_t*)&adc_buf[buffer_index], 8); \r
+    buffer_index = buffer_index+4;\r
+  \r
+    comm_read( PAH831X_B2__PPG1_E_ADCDATA_ON__ADDR, (uint8_t*)&adc_buf[buffer_index], 8); \r
+    buffer_index = buffer_index+4;\r
+   \r
+    comm_read( PAH831X_B2__PPG1_F_ADCDATA_ON__ADDR, (uint8_t*)&adc_buf[buffer_index], 8); \r
+    buffer_index = buffer_index+4;\r
+    comm_write( PAH831X_SWITCH_BANK__ADDR, PAH831X_SWITCH_BANK__0);\r
+    \r
+    return PAH_RET_SUCCESS;\r
+    \r
+}\r
+\r
+pah_ret pah831x_update_ch_a_1000k(void)\r
+{    \r
+    comm_write( 0x7F , 0x01 ); //Bank1\r
+    comm_write( 0x36 , 0x01 ); //B_PPG1_ChA_TIA_CF_ADJ[6:0]\r
+    comm_write( 0x3A , 0x01 ); //B_PPG2_ChA_TIA_CF_ADJ[6:0]\r
+    comm_write( 0x37 , 0x0C ); //B_PPG1_ChA_TIA_RF_ADJ[3:0], 1000k\r
+    comm_write( 0x3B , 0x0C ); //B_PPG2_ChA_TIA_RF_ADJ[3:0]. 1000k\r
+    comm_write( 0x38 , 0x02 ); //B_PPG1_ChA_ON_AMBC_ADJ[7:0]\r
+    comm_write( 0x3C , 0x02 ); //B_PPG2_ChA_ON_AMBC_ADJ[7:0]\r
+    comm_write( 0x69 , 0x02 ); //B_PPG1_ChA_OFF_AMBC_ADJ[7:0]\r
+    comm_write( 0x70 , 0x02 ); //B_PPG2_ChA_OFF_AMBC_ADJ[7:0]\r
+    comm_write( 0x7F , 0x00 ); //Bank1   \r
+    comm_write( 0x7e , 0x80 );  //    \r
+    return PAH_RET_SUCCESS;\r
+}\r
+\r
+pah_ret pah831x_update_ch_a_150k(void)\r
+{    \r
+    comm_write( 0x7F , 0x01 ); //Bank1\r
+    comm_write( 0x36 , 0x0C ); //B_PPG1_ChA_TIA_CF_ADJ[6:0]\r
+    comm_write( 0x3A , 0x0C ); //B_PPG2_ChA_TIA_CF_ADJ[6:0]\r
+    comm_write( 0x37 , 0x07 ); //B_PPG1_ChA_TIA_RF_ADJ[3:0], 150k\r
+    comm_write( 0x3B , 0x07 ); //B_PPG2_ChA_TIA_RF_ADJ[3:0]. 150k\r
+    comm_write( 0x38 , 0x0F ); //B_PPG1_ChA_ON_AMBC_ADJ[7:0]\r
+    comm_write( 0x3C , 0x0F ); //B_PPG2_ChA_ON_AMBC_ADJ[7:0]\r
+    comm_write( 0x69 , 0x0F ); //B_PPG1_ChA_OFF_AMBC_ADJ[7:0]\r
+    comm_write( 0x70 , 0x0F ); //B_PPG2_ChA_OFF_AMBC_ADJ[7:0]\r
+    comm_write( 0x7F , 0x00 ); //Bank1   \r
+    comm_write( 0x7e , 0x80 );  //    \r
+    return PAH_RET_SUCCESS;\r
+}\r
+pah_ret pah831x_update_ch_a_75k(void)\r
+{    \r
+    comm_write( 0x7F , 0x01 ); //Bank1\r
+    comm_write( 0x36 , 0x1A ); //B_PPG1_ChA_TIA_CF_ADJ[6:0]\r
+    comm_write( 0x3A , 0x1A ); //B_PPG2_ChA_TIA_CF_ADJ[6:0]\r
+    comm_write( 0x37 , 0x05 ); //B_PPG1_ChA_TIA_RF_ADJ[3:0], 150k\r
+    comm_write( 0x3B , 0x05 ); //B_PPG2_ChA_TIA_RF_ADJ[3:0]. 150k\r
+    comm_write( 0x38 , 0x1D ); //B_PPG1_ChA_ON_AMBC_ADJ[7:0]\r
+    comm_write( 0x3C , 0x1D ); //B_PPG2_ChA_ON_AMBC_ADJ[7:0]\r
+    comm_write( 0x69 , 0x1D ); //B_PPG1_ChA_OFF_AMBC_ADJ[7:0]\r
+    comm_write( 0x70 , 0x1D ); //B_PPG2_ChA_OFF_AMBC_ADJ[7:0]\r
+    comm_write( 0x7F , 0x00 ); //Bank1   \r
+    comm_write( 0x7e , 0x80 );  //    \r
+    return PAH_RET_SUCCESS;\r
+}\r
+pah_ret pah831x_update_ch_a_350k_low(void)\r
+{    \r
+    uint8_t data = 0 ;\r
+    uint8_t data_temp = 0 ;\r
+    comm_write( 0x7F , 0x04 ); //Bank4\r
+    comm_read( 0x00, &data ,1  );\r
+    data_temp = data&0x0F+0x80;\r
+    comm_write( 0x00 , data_temp ); \r
+    comm_read( 0x16, &data ,1  );\r
+    data_temp = data&0x0F+0x80 ;\r
+    comm_write( 0x16 , data_temp ); \r
+    comm_write( 0x7F , 0x00 ); //Bank1   \r
+    comm_write( 0x7e , 0x80 );  //    \r
+    return PAH_RET_SUCCESS;\r
+}\r
+\r
+\r
+pah_ret pah831x_update_hrd_ch_gain(uint16_t adc_data)\r
+{    \r
+    \r
+    if(adc_data>28000)\r
+    {\r
+        //gain 350k\r
+        comm_write( 0x7F , 0x01 ); //Bank1\r
+        comm_write( 0x36 , 0x05 ); //B_PPG1_ChA_TIA_CF_ADJ[6:0]\r
+        comm_write( 0x3A , 0x05 ); //B_PPG2_ChA_TIA_CF_ADJ[6:0]\r
+        comm_write( 0x37 , 0x09 ); //B_PPG1_ChA_TIA_RF_ADJ[3:0], 350k\r
+        comm_write( 0x3B , 0x09 ); //B_PPG2_ChA_TIA_RF_ADJ[3:0]. 350k\r
+        comm_write( 0x38 , 0x05 ); //B_PPG1_ChA_ON_AMBC_ADJ[7:0]\r
+        comm_write( 0x3C , 0x05 ); //B_PPG2_ChA_ON_AMBC_ADJ[7:0]\r
+        comm_write( 0x69 , 0x05 ); //B_PPG1_ChA_OFF_AMBC_ADJ[7:0]\r
+        comm_write( 0x70 , 0x05 ); //B_PPG2_ChA_OFF_AMBC_ADJ[7:0]\r
+        comm_write( 0x7F , 0x00 ); //Bank1   \r
+        comm_write( 0x7e , 0x80 );  // \r
+    }else\r
+    {\r
+        //gain 1000k\r
+        comm_write( 0x7F , 0x01 ); //Bank1\r
+        comm_write( 0x36 , 0x01 ); //B_PPG1_ChA_TIA_CF_ADJ[6:0]\r
+        comm_write( 0x3A , 0x01 ); //B_PPG2_ChA_TIA_CF_ADJ[6:0]\r
+        comm_write( 0x37 , 0x0C ); //B_PPG1_ChA_TIA_RF_ADJ[3:0], 1000k\r
+        comm_write( 0x3B , 0x0C ); //B_PPG2_ChA_TIA_RF_ADJ[3:0]. 1000k\r
+        comm_write( 0x38 , 0x02 ); //B_PPG1_ChA_ON_AMBC_ADJ[7:0]\r
+        comm_write( 0x3C , 0x02 ); //B_PPG2_ChA_ON_AMBC_ADJ[7:0]\r
+        comm_write( 0x69 , 0x02 ); //B_PPG1_ChA_OFF_AMBC_ADJ[7:0]\r
+        comm_write( 0x70 , 0x02 ); //B_PPG2_ChA_OFF_AMBC_ADJ[7:0]\r
+        comm_write( 0x7F , 0x00 ); //Bank1   \r
+        comm_write( 0x7e , 0x80 );  // \r
+    }\r
+    return PAH_RET_SUCCESS;\r
+}\r
+\r
+\r
+pah_ret pah831x_ir_r_led_control(uint8_t enable)\r
+{    \r
+    \r
+    if(enable)\r
+    {\r
+        comm_write( 0x7F , 0x04 ); //Bank4\r
+//        comm_write( 0x04 , 0x10 ); //B_PPG_ChB_LEDDAC1_CH_SEL[5:0], R2(LED4)\r
+//        comm_write( 0x07 , 0x02 ); //B_PPG_ChC_LEDDAC1_CH_SEL[5:0], R1(LED1)\r
+//        comm_write( 0x0A , 0x08 ); //B_PPG_ChD_LEDDAC1_CH_SEL[5:0], IR2(LED3)\r
+//        comm_write( 0x0D , 0x01 ); //B_PPG_ChE_LEDDAC1_CH_SEL[5:0], IR1(LED0)\r
+//        comm_write( 0x1A , 0x10 ); //B_PPG_ChB_LEDDAC2_CH_SEL[5:0], R2(LED4)\r
+//        comm_write( 0x1D , 0x02 ); //B_PPG_ChC_LEDDAC2_CH_SEL[5:0], R1(LED1)\r
+//        comm_write( 0x20 , 0x08 ); //B_PPG_ChD_LEDDAC2_CH_SEL[5:0], IR2(LED3)\r
+//        comm_write( 0x23 , 0x01 ); //B_PPG_ChE_LEDDAC2_CH_SEL[5:0], IR1(LED0)\r
+        \r
+        comm_write( 0x04 , 0x02 ); //B_PPG_ChB_LEDDAC1_CH_SEL[5:0], R2(LED4)\r
+        comm_write( 0x07 , 0x10 ); //B_PPG_ChC_LEDDAC1_CH_SEL[5:0], R1(LED1)\r
+        comm_write( 0x0A , 0x01 ); //B_PPG_ChD_LEDDAC1_CH_SEL[5:0], IR2(LED3)\r
+        comm_write( 0x0D , 0x08 ); //B_PPG_ChE_LEDDAC1_CH_SEL[5:0], IR1(LED0)\r
+        comm_write( 0x1A , 0x02 ); //B_PPG_ChB_LEDDAC2_CH_SEL[5:0], R2(LED4)\r
+        comm_write( 0x1D , 0x10 ); //B_PPG_ChC_LEDDAC2_CH_SEL[5:0], R1(LED1)\r
+        comm_write( 0x20 , 0x01 ); //B_PPG_ChD_LEDDAC2_CH_SEL[5:0], IR2(LED3)\r
+        comm_write( 0x23 , 0x08 ); //B_PPG_ChE_LEDDAC2_CH_SEL[5:0], IR1(LED0)\r
+      \r
+        \r
+        \r
+    }else\r
+    {\r
+        comm_write( 0x7F , 0x04 ); //Bank4\r
+        comm_write( 0x04 , 0x00 ); //B_PPG_ChB_LEDDAC1_CH_SEL[5:0], R2(LED4)\r
+        comm_write( 0x07 , 0x00 ); //B_PPG_ChC_LEDDAC1_CH_SEL[5:0], R1(LED1)\r
+        comm_write( 0x0A , 0x00 ); //B_PPG_ChD_LEDDAC1_CH_SEL[5:0], IR2(LED3)\r
+        comm_write( 0x0D , 0x00 ); //B_PPG_ChE_LEDDAC1_CH_SEL[5:0], IR1(LED0)\r
+        comm_write( 0x1A , 0x00 ); //B_PPG_ChB_LEDDAC2_CH_SEL[5:0], R2(LED4)\r
+        comm_write( 0x1D , 0x00 ); //B_PPG_ChC_LEDDAC2_CH_SEL[5:0], R1(LED1)\r
+        comm_write( 0x20 , 0x00 ); //B_PPG_ChD_LEDDAC2_CH_SEL[5:0], IR2(LED3)\r
+        comm_write( 0x23 , 0x00 ); //B_PPG_ChE_LEDDAC2_CH_SEL[5:0], IR1(LED0)\r
+    }\r
+    comm_write( 0x7F , 0x00 ); //Bank1   \r
+    comm_write( 0x7e , 0x80 );  //    \r
+    return PAH_RET_SUCCESS;\r
+}\r
+\r
+//============================================================================\r
+// Private function\r
+//============================================================================\r
+static void reset_state(pah831x *state)\r
+{\r
+    memset(&state->ppg, 0, sizeof(state->ppg));\r
+    memset(&state->ecg, 0, sizeof(state->ecg));\r
+\r
+    state->fifo_watermark = 0;\r
+    state->sample_data_count = 0;\r
+    state->is_started = false;\r
+    state->fifo_clock_enabled = false;\r
+}\r
+\r
+static pah_ret read_product_id(pah_plat *plat, uint16_t *product_id)\r
+{\r
+    pah_ret ret;\r
+    uint16_t data = 0;\r
+\r
+    ret = comm_write( PAH831X_SWITCH_BANK__ADDR, PAH831X_SWITCH_BANK__0);\r
+    PAH_CHECK_RET(ret);\r
+    ret = comm_read( PAH831X_B0__PART_ID__ADDR, (uint8_t*)&data, PAH831X_B0__PART_ID__SIZE);\r
+    PAH_CHECK_RET(ret);\r
+\r
+    if (product_id)\r
+        *product_id = data;\r
+\r
+    return PAH_RET_SUCCESS;\r
+}\r
+\r
+static pah_ret read_ppg_leddac_regs(pah_plat *plat, uint8_t ppg_leddac_regs[PPG_LEDDAC_REG__NUM])\r
+{\r
+    pah_ret ret;\r
+    int i = 0;\r
+    memset(ppg_leddac_regs, 0, sizeof(ppg_leddac_regs[0]) * PPG_LEDDAC_REG__NUM);\r
+\r
+    ret = comm_write( PAH831X_SWITCH_BANK__ADDR, PAH831X_SWITCH_BANK__4);\r
+    PAH_CHECK_RET(ret);\r
+\r
+    for (i = 0; i < PPG_LEDDAC_REG__NUM; ++i)\r
+    {\r
+        pah831x_reg reg_index = PPG_LEDDAC_REG_LOOKUP_TABLE[i];\r
+        uint8_t addr = REG_LOOKUP_TABLE[reg_index].addr;\r
+        uint8_t data = 0;\r
+\r
+        ret = comm_read( addr, &data, 1);\r
+        PAH_CHECK_RET(ret);\r
+\r
+        ppg_leddac_regs[i] = data;\r
+    }\r
+\r
+    return PAH_RET_SUCCESS;\r
+}\r
+\r
+static pah_ret read_int_flag(pah_plat *plat, pah831x_int_flag *int_flag)\r
+{\r
+    pah_ret ret;\r
+\r
+    ret = comm_write( PAH831X_SWITCH_BANK__ADDR, PAH831X_SWITCH_BANK__0);\r
+    PAH_CHECK_RET(ret);\r
+    ret = comm_read( PAH831X_B0__INT_FLAG_LOD__ADDR, (uint8_t*)&int_flag->value, PAH831X_B0__INT_FLAGS_SIZE);\r
+    PAH_CHECK_RET(ret);\r
+\r
+    return PAH_RET_SUCCESS;\r
+}\r
+\r
+static pah_ret read_touch_flag(pah_plat *plat, bool *touch_flag)\r
+{\r
+    pah_ret ret;\r
+    pah831x_int_flag int_flag;\r
+\r
+    ret = comm_write( PAH831X_SWITCH_BANK__ADDR, PAH831X_SWITCH_BANK__0);\r
+    PAH_CHECK_RET(ret);\r
+    ret = comm_read( PAH831X_B0__INT_FLAG__ADDR, &int_flag.data[1], PAH831X_B0__INT_FLAG__SIZE);\r
+    PAH_CHECK_RET(ret);\r
+\r
+    if (touch_flag)\r
+        *touch_flag = (bool)int_flag.touch_flag;\r
+\r
+    return PAH_RET_SUCCESS;\r
+}\r
+\r
+static pah_ret read_touch_value(pah_plat *plat, uint16_t *touch_value)\r
+{\r
+    pah_ret ret;\r
+\r
+    ret = comm_write( PAH831X_SWITCH_BANK__ADDR, PAH831X_SWITCH_BANK__0);\r
+    PAH_CHECK_RET(ret);\r
+    ret = comm_read( PAH831X_B0__TOUCH_VALUE__ADDR, (uint8_t*)touch_value, PAH831X_B0__TOUCH_VALUE__SIZE);\r
+    PAH_CHECK_RET(ret);\r
+\r
+    return PAH_RET_SUCCESS;\r
+}\r
+\r
+static pah_ret read_fifo_data_count(pah_plat *plat, uint16_t *fifo_data_count)\r
+{\r
+    pah_ret ret;\r
+\r
+    ret = comm_write( PAH831X_SWITCH_BANK__ADDR, PAH831X_SWITCH_BANK__0);\r
+    PAH_CHECK_RET(ret);\r
+    ret = comm_read( PAH831X_B0__FIFO_DATA_COUNT_UNLOCK__ADDR, (uint8_t*)fifo_data_count, PAH831X_B0__FIFO_DATA_COUNT_UNLOCK__SIZE);\r
+    PAH_CHECK_RET(ret);\r
+\r
+    return PAH_RET_SUCCESS;\r
+}\r
+\r
+static pah_ret read_fifo(pah_plat *plat, uint8_t *buffer, size_t read_size)\r
+{\r
+    pah_ret ret;\r
+    \r
+    ret = comm_write( PAH831X_SWITCH_BANK__ADDR, PAH831X_SWITCH_BANK__0);\r
+    PAH_CHECK_RET(ret);\r
+    ret = comm_read( PAH831X_B0__READ_FIFO__ADDR, buffer, read_size);\r
+    PAH_CHECK_RET(ret);\r
+    \r
+    return PAH_RET_SUCCESS;\r
+}\r
+\r
+static pah_ret read_fifo_ex(pah_plat *plat, uint8_t *buffer, size_t buffer_size, uint16_t data_count, size_t sample_size, pah831x_read_fifo_cb read_fifo_cb, void *user_data)\r
+{\r
+    pah_ret ret;\r
+    size_t curr_read_size = 0;\r
+    size_t total_read_size = PAH831X_DATA_SIZE * data_count;\r
+\r
+    ret = comm_write( PAH831X_SWITCH_BANK__ADDR, PAH831X_SWITCH_BANK__0);\r
+    PAH_CHECK_RET(ret);\r
+    ret = comm_write( PAH831X_B0__READ_FIFO_ENH__ADDR, PAH831X_B0__READ_FIFO_ENH__ENABLE);\r
+    PAH_CHECK_RET(ret);\r
+\r
+    while (curr_read_size < total_read_size)\r
+    {\r
+        size_t remain_size = total_read_size - curr_read_size;\r
+        size_t read_size = remain_size;\r
+        if (read_size > buffer_size)\r
+            read_size = buffer_size;\r
+        read_size = (read_size / sample_size) * sample_size;\r
+\r
+        if (read_size == 0)\r
+            break;\r
+\r
+        ret = comm_read( PAH831X_B0__READ_FIFO__ADDR, buffer, read_size);\r
+        PAH_CHECK_RET(ret);\r
+\r
+        curr_read_size += read_size;\r
+\r
+        if (read_fifo_cb)\r
+        {\r
+            uint16_t data_count = (uint16_t)(read_size / PAH831X_DATA_SIZE);\r
+\r
+            float read_size_ratio = 1.0f;\r
+            if (read_size < total_read_size)\r
+                read_size_ratio = (float)read_size / total_read_size;\r
+\r
+            read_fifo_cb(user_data, buffer, data_count, read_size_ratio);\r
+        }\r
+    }\r
+\r
+    ret = comm_write( PAH831X_B0__READ_FIFO_ENH__ADDR, PAH831X_B0__READ_FIFO_ENH__DISABLE);\r
+    PAH_CHECK_RET(ret);\r
+\r
+    return PAH_RET_SUCCESS;\r
+}\r
+\r
+static pah_ret write_reg_arr(pah_plat *plat, const pah_reg_arr *reg_arr)\r
+{\r
+    return write_reg_array(plat, reg_arr->reg_arr, reg_arr->reg_arr_len);\r
+}\r
+\r
+static pah_ret write_reg_array(pah_plat *plat, const uint8_t reg_array[][2], size_t length)\r
+{\r
+    pah_ret ret;\r
+    size_t i = 0;\r
+\r
+    if (length == 0)\r
+        return PAH_RET_SUCCESS;\r
+    for (i = 0; i < length; ++i)\r
+    {\r
+        ret = comm_write( reg_array[i][0], reg_array[i][1]);\r
+        if (PAH_FAILED(ret))\r
+            return ret;\r
+    }\r
+\r
+    return PAH_RET_SUCCESS;\r
+}\r
+\r
+static pah_ret write_fifo_watermark(pah_plat *plat, uint16_t fifo_watermark)\r
+{\r
+    const uint8_t reg_array[][2] = {\r
+        { PAH831X_SWITCH_BANK__ADDR, PAH831X_SWITCH_BANK__0 },\r
+        { PAH831X_B0__FIFO_SIZE_L__ADDR, PAH_UINT16_LOW(fifo_watermark) },\r
+        { PAH831X_B0__FIFO_SIZE_H__ADDR, (PAH_UINT16_HIGH(fifo_watermark) & PAH831X_B0__FIFO_SIZE_H__MSK) },\r
+    };\r
+\r
+    return write_reg_array(plat, reg_array, PAH_ARRAY_SIZE(reg_array));\r
+}\r
+\r
+static pah_ret write_ppg_led(pah_plat *plat, uint8_t ppg_led[PAH831X_CH__PPG_NUM])\r
+{\r
+    int i = 0;\r
+    pah_ret ret;\r
+\r
+    ret = comm_write( PAH831X_SWITCH_BANK__ADDR, PAH831X_SWITCH_BANK__4);\r
+    PAH_CHECK_RET(ret);\r
+\r
+    for (i = 0; i < PAH831X_CH__PPG_NUM; ++i)\r
+    {\r
+        pah831x_reg reg_index = PPG_LED_REG_LOOKUP_TABLE[i];\r
+        pah831x_reg_info reg_info = REG_LOOKUP_TABLE[reg_index];\r
+\r
+        ret = comm_write( reg_info.addr, ppg_led[i]);\r
+        PAH_CHECK_RET(ret);\r
+    }\r
+\r
+    return PAH_RET_SUCCESS;\r
+}\r
+\r
+static pah_ret set_soft_reset(pah_plat *plat)\r
+{\r
+    pah_ret ret;\r
+\r
+    ret = set_power_off(plat);\r
+    PAH_CHECK_RET(ret);\r
+\r
+    ret = comm_write( PAH831X_B3__POWERDN__ADDR, PAH831X_B3__POWERDN__POWER_UP);\r
+    PAH_CHECK_RET(ret);\r
+    DELAY_MS(POWER_UP_DELAY_MS);\r
+\r
+    if (plat->comm.type == PAH_PLAT_COMM_I3C)\r
+    {\r
+        uint8_t data = 0;\r
+        data = PAH_SET_BITSLICE(data, PAH831X_B3__I2C__18V_ENL__POS, PAH831X_B3__I2C__18V_ENL__MSK, 1);\r
+        data = PAH_SET_BITSLICE(data, PAH831X_B3__I2C__DRV__POS, PAH831X_B3__I2C__DRV__MSK, 1);\r
+        ret = comm_write( PAH831X_B3__I2C__ADDR, data);\r
+        PAH_CHECK_RET(ret);\r
+    }\r
+\r
+    return PAH_RET_SUCCESS;\r
+}\r
+\r
+static pah_ret set_power_off(pah_plat *plat)\r
+{\r
+    pah_ret ret;\r
+\r
+    ret = comm_write( PAH831X_SWITCH_BANK__ADDR, PAH831X_SWITCH_BANK__3);\r
+    PAH_CHECK_RET(ret);\r
+\r
+    ret = comm_write( PAH831X_B3__PWRSV_SEL__ADDR, PAH831X_B3__PWRSV_SEL__ENABLE_OSC_4M);\r
+    PAH_CHECK_RET(ret);\r
+    ret = comm_write( PAH831X_B3__EXT_CLK__ADDR, PAH831X_B3__EXT_CLK__ENABLE_32K_CLK_SEL);\r
+    PAH_CHECK_RET(ret);\r
+    ret = comm_write( PAH831X_B3__EXT_CLK__ADDR, PAH831X_B3__EXT_CLK__DISABLE_32K_CLK_SEL);\r
+    PAH_CHECK_RET(ret);\r
+    ret = comm_write( PAH831X_B3__PWRSV_SEL__ADDR, PAH831X_B3__PWRSV_SEL__DISABLE_OSC_4M);\r
+    PAH_CHECK_RET(ret);\r
+    ret = comm_write( PAH831X_B3__RESET__ADDR, PAH831X_B3__RESET__LP);\r
+    PAH_CHECK_RET(ret);\r
+    DELAY_MS(RESET_DELAY_MS);\r
+\r
+    ret = comm_write( PAH831X_B3__RESET__ADDR, PAH831X_B3__RESET__WD);\r
+    PAH_CHECK_RET(ret);\r
+    DELAY_MS(RESET_DELAY_MS);\r
+\r
+    ret = comm_write( PAH831X_B3__POWERDN__ADDR, PAH831X_B3__POWERDN__POWER_DOWN);\r
+    PAH_CHECK_RET(ret);\r
+    DELAY_MS(POWER_DOWN_DELAY_MS);\r
+\r
+    return PAH_RET_SUCCESS;\r
+}\r
+\r
+static pah_ret set_power_down(pah_plat *plat)\r
+{\r
+    pah_ret ret;\r
+\r
+    ret = comm_write( PAH831X_SWITCH_BANK__ADDR, PAH831X_SWITCH_BANK__3);\r
+    PAH_CHECK_RET(ret);\r
+    ret = comm_write( PAH831X_B3__POWERDN__ADDR, PAH831X_B3__POWERDN__POWER_DOWN);\r
+    PAH_CHECK_RET(ret);\r
+    DELAY_MS(POWER_DOWN_DELAY_MS);\r
+\r
+    return PAH_RET_SUCCESS;\r
+}\r
+\r
+static pah_ret set_update_flag(pah_plat *plat)\r
+{\r
+    pah_ret ret;\r
+\r
+    ret = comm_write( PAH831X_SWITCH_BANK__ADDR, PAH831X_SWITCH_BANK__0);\r
+    PAH_CHECK_RET(ret);\r
+    ret = comm_write( PAH831X_B0__UPDATE_FLAG__ADDR, PAH831X_B0__UPDATE_FLAG__VALUE);\r
+    PAH_CHECK_RET(ret);\r
+\r
+    return PAH_RET_SUCCESS;\r
+}\r
+\r
+static pah_ret enable_report_start_timer(pah_plat *plat)\r
+{\r
+    const uint8_t reg_array[][2] = {\r
+        { PAH831X_SWITCH_BANK__ADDR, PAH831X_SWITCH_BANK__0 },\r
+        { PAH831X_B0__REPORT_ENH__ADDR, PAH831X_B0__REPORT_ENH__VALUE },\r
+    };\r
+\r
+    return write_reg_array(plat, reg_array, PAH_ARRAY_SIZE(reg_array));\r
+}\r
+\r
+static pah_ret enable_fifo_clk(pah_plat *plat)\r
+{\r
+    const uint8_t reg_array[][2] = {\r
+        { PAH831X_SWITCH_BANK__ADDR, PAH831X_SWITCH_BANK__3 },\r
+        { PAH831X_B3__PWRSV_SEL__ADDR, PAH831X_B3__PWRSV_SEL__ENABLE_OSC_4M },\r
+        { PAH831X_B3__CLK__ADDR, PAH831X_B3__CLK__ENABLE_CLK },\r
+    };\r
+\r
+    return write_reg_array(plat, reg_array, PAH_ARRAY_SIZE(reg_array));\r
+}\r
+\r
+static pah_ret disable_fifo_clk(pah_plat *plat)\r
+{\r
+    const uint8_t reg_array[][2] = {\r
+        { PAH831X_SWITCH_BANK__ADDR, PAH831X_SWITCH_BANK__3 },\r
+        { PAH831X_B3__PWRSV_SEL__ADDR, PAH831X_B3__PWRSV_SEL__DISABLE_OSC_4M },\r
+        { PAH831X_B3__CLK__ADDR, PAH831X_B3__CLK__DISABLE_CLK },\r
+    };\r
+\r
+    return write_reg_array(plat, reg_array, PAH_ARRAY_SIZE(reg_array));\r
+}\r
+\r
+static pah_ret enable_read_fifo(pah_plat *plat)\r
+{\r
+    const uint8_t reg_array[][2] = {\r
+        { PAH831X_SWITCH_BANK__ADDR, PAH831X_SWITCH_BANK__0 },\r
+        { PAH831X_B0__READ_FIFO_ENH__ADDR, PAH831X_B0__READ_FIFO_ENH__ENABLE },\r
+    };\r
+\r
+    return write_reg_array(plat, reg_array, PAH_ARRAY_SIZE(reg_array));\r
+}\r
+\r
+static pah_ret disable_read_fifo(pah_plat *plat)\r
+{\r
+    const uint8_t reg_array[][2] = {\r
+        { PAH831X_SWITCH_BANK__ADDR, PAH831X_SWITCH_BANK__0 },\r
+        { PAH831X_B0__READ_FIFO_ENH__ADDR, PAH831X_B0__READ_FIFO_ENH__DISABLE },\r
+    };\r
+\r
+    return write_reg_array(plat, reg_array, PAH_ARRAY_SIZE(reg_array));\r
+}\r
+\r
+static pah_ret clear_int_flag(pah_plat *plat)\r
+{\r
+    pah_ret ret;\r
+    pah831x_int_flag int_flag;\r
+    int_flag.value = 0;\r
+\r
+    ret = comm_write( PAH831X_SWITCH_BANK__ADDR, PAH831X_SWITCH_BANK__0);\r
+    PAH_CHECK_RET(ret);\r
+    ret = comm_read( PAH831X_B0__INT_FLAG_LOD__ADDR, (uint8_t*)&int_flag.value, PAH831X_B0__INT_FLAGS_SIZE);\r
+    PAH_CHECK_RET(ret);\r
+\r
+    ret = comm_write( PAH831X_B0__INT_FLAG_LOD__ADDR, PAH831X_B0__INT_FLAG_LOD__CLEAR);\r
+    PAH_CHECK_RET(ret);\r
+    ret = comm_write( PAH831X_B0__INT_FLAG__ADDR, int_flag.data[1]);\r
+    PAH_CHECK_RET(ret);\r
+\r
+    return PAH_RET_SUCCESS;\r
+}\r
+\r
+static pah_ret comm_write(/*pah_plat *plat,*/ uint8_t addr, uint8_t data)\r
+{\r
+    //return plat->comm.write(/*&plat->comm,*/ addr, &data, 1);\r
+    return pah_comm_i2c_write( addr, &data, 1);\r
+}\r
+\r
+static pah_ret comm_read(/*pah_plat *plat, */uint8_t addr, uint8_t *data, size_t read_size)\r
+{\r
+    //return plat->comm.read(/*&plat->comm,*/ addr, data, read_size);\r
+    return pah_comm_i2c_read( addr, data, read_size);\r
+}\r
+\r
+static bool regs_contains_report_period(const pah831x_regs *regs)\r
+{\r
+    return regs->has_values[PAH831X_REG__B0_0X03]\r
+        && regs->has_values[PAH831X_REG__B0_0X04];\r
+}\r
+\r
+static bool regs_contains_ch_enh(const pah831x_regs *regs)\r
+{\r
+    return regs->has_values[PAH831X_REG__B0_0X1B]\r
+        && regs->has_values[PAH831X_REG__B0_0X68];\r
+}\r
+\r
+static pah831x_verify_reg_arr_ret verify_regs_ppg_frame_period(const pah831x_regs *regs, float ppg_sample_rate, float ecg_sample_rate, uint16_t *frame_period, uint16_t *max_frame_period)\r
+{\r
+    if (ppg_sample_rate <= 0.0f)\r
+        return PAH831X_VERIFY_REG_ARR_RET__SUCCESS;\r
+\r
+    uint16_t ppg_frame_period = 0;\r
+    uint16_t max_ppg_frame_period = 0;\r
+    float sample_rate = 0.0f;\r
+\r
+    if (!calculate_ppg_frame_period(regs, &ppg_frame_period))\r
+        return PAH831X_VERIFY_REG_ARR_RET__PPG_FRAME_PERIOD_CAL_FAIL;\r
+\r
+    sample_rate = ppg_sample_rate;\r
+    if (sample_rate < ecg_sample_rate)\r
+        sample_rate = ecg_sample_rate;\r
+    max_ppg_frame_period = (uint16_t)((0.9f / sample_rate) * 1000000.0f);\r
+\r
+    if (frame_period)\r
+        *frame_period = ppg_frame_period;\r
+    if (max_frame_period)\r
+        *max_frame_period = max_ppg_frame_period;\r
+\r
+    if (ppg_frame_period >= max_ppg_frame_period)\r
+        return PAH831X_VERIFY_REG_ARR_RET__PPG_FRAME_PERIOD_EXCEED;\r
+\r
+    return PAH831X_VERIFY_REG_ARR_RET__SUCCESS;\r
+}\r
+\r
+static uint16_t determine_sample_data_count(const pah831x_ppg *ppg, const pah831x_ecg *ecg, uint16_t *ppg_sample_data_count, uint16_t *ecg_sample_data_count)\r
+{\r
+    uint16_t ppg_data_count = 0;\r
+    uint16_t ecg_data_count = 0;\r
+\r
+    if (ppg_is_enabled(ppg))\r
+    {\r
+        ppg_data_count = ppg->ch_num;\r
+    }\r
+\r
+    if (ecg_is_enabled(ecg))\r
+    {\r
+        if (ppg_is_enabled(ppg))\r
+            ecg_data_count = calculate_ecg_watermark_factor(ppg->sample_rate, ecg->sample_rate);\r
+        else\r
+            ecg_data_count = 1;\r
+    }\r
+\r
+    if (ppg_sample_data_count)\r
+        *ppg_sample_data_count = ppg_data_count;\r
+    if (ecg_sample_data_count)\r
+        *ecg_sample_data_count = ecg_data_count;\r
+    return ppg_data_count + ecg_data_count;\r
+}\r
+\r
+static bool ppg_is_enabled(const pah831x_ppg *ppg)\r
+{\r
+    return ppg->sample_rate > 0.0f && ppg->ch_num > 0;\r
+}\r
+\r
+static bool ecg_is_enabled(const pah831x_ecg *ecg)\r
+{\r
+    return ecg->sample_rate > 0.0f && ecg->enabled;\r
+}\r
+\r
+static void extract_regs(const pah_reg_arr *reg_arr, pah831x_regs *regs)\r
+{\r
+    uint32_t i = 0;\r
+    uint8_t bank = 0;\r
+\r
+    for (i = 0; i < reg_arr->reg_arr_len; ++i)\r
+    {\r
+        uint8_t addr = reg_arr->reg_arr[i][0];\r
+        uint8_t value = reg_arr->reg_arr[i][1];\r
+\r
+        if (addr == PAH831X_SWITCH_BANK__ADDR)\r
+        {\r
+            bank = value;\r
+        }\r
+        else\r
+        {\r
+            int j = 0;\r
+\r
+            for (j = 0; j <= PAH831X_REG__NUM; ++j)\r
+            {\r
+                const pah831x_reg_info *reg_info = &REG_LOOKUP_TABLE[j];\r
+                if (reg_info->bank == bank && reg_info->addr == addr)\r
+                {\r
+                    regs->has_values[j] = true;\r
+                    regs->values[j] = value;\r
+                    break;\r
+                }\r
+            }\r
+        }\r
+    }\r
+}\r
+\r
+static void set_regs_merge_ch_enh(pah831x_regs *regs, const pah_reg_arr *reg_arr)\r
+{\r
+    size_t i = 0;\r
+    pah831x_reg reg_indices[] = {\r
+        PAH831X_REG__B0_0X1B,\r
+        PAH831X_REG__B0_0X68,\r
+    };\r
+    pah831x_regs another_regs;\r
+\r
+    memset(&another_regs, 0, sizeof(another_regs));\r
+\r
+    extract_regs(reg_arr, &another_regs);\r
+\r
+    for (i = 0; i < PAH_ARRAY_SIZE(reg_indices); ++i)\r
+    {\r
+        pah831x_reg reg_index = reg_indices[i];\r
+\r
+        if (another_regs.has_values[reg_index])\r
+        {\r
+            regs->has_values[reg_index] = true;\r
+            regs->values[reg_index] |= another_regs.values[reg_index];\r
+            regs->values_has_changed[reg_index] = true;\r
+        }\r
+    }\r
+}\r
+\r
+static void set_ppg_leddac_reg_cal(pah831x_regs *regs, uint8_t ppg_leddac_regs[PPG_LEDDAC_REG__NUM])\r
+{\r
+    int i = 0;\r
+\r
+    for (i = 0; i < PPG_LEDDAC_REG__NUM; ++i)\r
+    {\r
+        pah831x_reg reg_index = PPG_LEDDAC_REG_LOOKUP_TABLE[i];\r
+        uint8_t cal_value = PAH_GET_BITSLICE(ppg_leddac_regs[i], PAH831X_B4__PPG_CH_X_LEDDAC_Y__REG_CAL__POS, PAH831X_B4__PPG_CH_X_LEDDAC_Y__REG_CAL__MSK);\r
+\r
+        regs->has_values[reg_index] = true;\r
+        regs->values[reg_index] = PAH_SET_BITSLICE(regs->values[reg_index], PAH831X_B4__PPG_CH_X_LEDDAC_Y__REG_CAL__POS, PAH831X_B4__PPG_CH_X_LEDDAC_Y__REG_CAL__MSK, cal_value);\r
+        regs->values_has_changed[reg_index] = true;\r
+    }\r
+}\r
+\r
+static void set_regs_turn_off_ppg_led(pah831x_regs *regs)\r
+{\r
+    int i = 0;\r
+\r
+    for (i = 0; i < PAH831X_CH__PPG_NUM; ++i)\r
+    {\r
+        pah831x_reg reg_index = PPG_LED_REG_LOOKUP_TABLE[i];\r
+\r
+        regs->has_values[reg_index] = true;\r
+        regs->values[reg_index] = 0;\r
+        regs->values_has_changed[reg_index] = true;\r
+    }\r
+}\r
+\r
+static void set_regs_enable_ecg_write_fifo(pah831x_regs *regs)\r
+{\r
+    pah831x_reg index = PAH831X_REG__B0_0X71;\r
+    uint8_t value = regs->values[index];\r
+\r
+    regs->has_values[index] = true;\r
+    regs->values[index] = PAH_SET_BITSLICE(value, PAH831X_B0__ECG_FIFO_WRITE_MASK__POS, PAH831X_B0__ECG_FIFO_WRITE_MASK__MSK, 0);\r
+    regs->values_has_changed[index] = true;\r
+}\r
+\r
+static void set_regs_enable_ecg_polar_switch(pah831x_regs *regs)\r
+{\r
+    pah831x_reg index = PAH831X_REG__B1_0X06;\r
+    uint8_t value = regs->values[index];\r
+\r
+    regs->has_values[index] = true;\r
+    regs->values[index] = PAH_SET_BITSLICE(value, PAH831X_B1__ECG_POLAR_FLIP_ENH__POS, PAH831X_B1__ECG_POLAR_FLIP_ENH__MSK, PAH831X_B1__ECG_POLAR_FLIP_ENH__ENABLE);\r
+    regs->values_has_changed[index] = true;\r
+}\r
+\r
+static void set_regs_ppg_decimation_num(pah831x_regs *regs, uint8_t ppg_decimation_num)\r
+{\r
+    pah831x_reg index = PAH831X_REG__B0_0X56;\r
+\r
+    regs->has_values[index] = true;\r
+    regs->values[index] = ppg_decimation_num;\r
+    regs->values_has_changed[index] = true;\r
+}\r
+\r
+static void set_regs_ch_t_report_divider(pah831x_regs *regs, uint16_t value)\r
+{\r
+    uint8_t low = PAH_UINT16_LOW(value);\r
+    uint8_t high = PAH_UINT16_HIGH(value);\r
+    pah831x_reg low_index = PAH831X_REG__B0_0X24;\r
+    pah831x_reg high_index = PAH831X_REG__B0_0X25;\r
+\r
+    regs->has_values[low_index] = true;\r
+    regs->values[low_index] = low;\r
+    regs->values_has_changed[low_index] = true;\r
+    regs->has_values[high_index] = true;\r
+    regs->values[high_index] = high;\r
+    regs->values_has_changed[high_index] = true;\r
+}\r
+\r
+static pah_ret write_changed_regs(pah_plat *plat, const pah831x_regs *regs)\r
+{\r
+    pah_ret ret;\r
+    int i = 0;\r
+    int last_bank = -1;\r
+\r
+    for (i = 0; i <= PAH831X_REG__NUM; ++i)\r
+    {\r
+        if (regs->has_values[i] && regs->values_has_changed[i])\r
+        {\r
+            uint8_t bank = REG_LOOKUP_TABLE[i].bank;\r
+            uint8_t addr = REG_LOOKUP_TABLE[i].addr;\r
+            uint8_t value = regs->values[i];\r
+\r
+            if (last_bank != bank)\r
+            {\r
+                last_bank = bank;\r
+\r
+                ret = comm_write( PAH831X_SWITCH_BANK__ADDR, bank);\r
+                PAH_CHECK_RET(ret);\r
+            }\r
+            \r
+            ret = comm_write( addr, value);\r
+            PAH_CHECK_RET(ret);\r
+        }\r
+    }\r
+\r
+    return PAH_RET_SUCCESS;\r
+}\r
+\r
+static uint16_t extract_ecg_frame_num(const pah831x_regs *regs)\r
+{\r
+    uint8_t data0 = PAH831X_B0__FRAME_NUM_ECG_1__DEFAULT;\r
+    uint8_t data1 = PAH831X_B0__FRAME_NUM_ECG_2__DEFAULT;\r
+\r
+    if (regs->has_values[PAH831X_REG__B0_0X27])\r
+        data0 = regs->values[PAH831X_REG__B0_0X27];\r
+    if (regs->has_values[PAH831X_REG__B0_0X28])\r
+        data1 = regs->values[PAH831X_REG__B0_0X28];\r
+\r
+    return UINT16_FROM_UINT8(data0, data1);\r
+}\r
+\r
+static uint8_t extract_ecg_gain(const pah831x_regs *regs)\r
+{\r
+    uint8_t gain = PAH831X_B1__ECG_FE_INA_GAIN__SELECT_3;\r
+\r
+    if (regs->has_values[PAH831X_REG__B1_0X26])\r
+    {\r
+        static uint8_t ECG_GAIN_TABLE[] = {\r
+            PAH831X_B1__ECG_FE_INA_GAIN__SELECT_0,\r
+            PAH831X_B1__ECG_FE_INA_GAIN__SELECT_1,\r
+            PAH831X_B1__ECG_FE_INA_GAIN__SELECT_2,\r
+            PAH831X_B1__ECG_FE_INA_GAIN__SELECT_3,\r
+        };\r
+\r
+        uint8_t value = PAH_GET_BITSLICE(regs->values[PAH831X_REG__B1_0X26], PAH831X_B1__ECG_FE_INA_GAIN__POS, PAH831X_B1__ECG_FE_INA_GAIN__MSK);\r
+        gain = ECG_GAIN_TABLE[value];\r
+    }\r
+\r
+    return gain;\r
+}\r
+\r
+static void extract_ppg_ch_enh(const pah831x_regs *regs, bool ppg_ch_enh[PAH831X_PPG_CH__NUM])\r
+{\r
+    if (regs->has_values[PAH831X_REG__B0_0X1B])\r
+    {\r
+        ppg_ch_enh[PAH831X_PPG_CH__A] = PAH_CHECK_BIT(regs->values[PAH831X_REG__B0_0X1B], PAH831X_B0__CH_ENH_1__CH_A__POS);\r
+        ppg_ch_enh[PAH831X_PPG_CH__B] = PAH_CHECK_BIT(regs->values[PAH831X_REG__B0_0X1B], PAH831X_B0__CH_ENH_1__CH_B__POS);\r
+        ppg_ch_enh[PAH831X_PPG_CH__C] = PAH_CHECK_BIT(regs->values[PAH831X_REG__B0_0X1B], PAH831X_B0__CH_ENH_1__CH_C__POS);\r
+        ppg_ch_enh[PAH831X_PPG_CH__D] = PAH_CHECK_BIT(regs->values[PAH831X_REG__B0_0X1B], PAH831X_B0__CH_ENH_1__CH_D__POS);\r
+        ppg_ch_enh[PAH831X_PPG_CH__B] = PAH_CHECK_BIT(regs->values[PAH831X_REG__B0_0X1B], PAH831X_B0__CH_ENH_1__CH_T__POS);\r
+        }\r
+\r
+    if (regs->has_values[PAH831X_REG__B0_0X68])\r
+    {\r
+        ppg_ch_enh[PAH831X_PPG_CH__E] = PAH_CHECK_BIT(regs->values[PAH831X_REG__B0_0X68], PAH831X_B0__CH_ENH_2__CH_E__POS);\r
+        ppg_ch_enh[PAH831X_PPG_CH__F] = PAH_CHECK_BIT(regs->values[PAH831X_REG__B0_0X68], PAH831X_B0__CH_ENH_2__CH_F__POS);\r
+    }\r
+}\r
+\r
+static uint8_t extract_ppg_ch_num(const pah831x_regs *regs)\r
+{\r
+    uint8_t ch_num = 0;\r
+    int i = 0;\r
+    bool ppg_ch_write_fifo[PAH831X_CH__PPG_NUM];\r
+\r
+    extract_ppg_ch_write_fifo(regs, ppg_ch_write_fifo);\r
+\r
+    for (i = 0; i < PAH831X_CH__PPG_NUM; ++i)\r
+    {\r
+        if (ppg_ch_write_fifo[i])\r
+            ++ch_num;\r
+    }\r
+\r
+    return ch_num;\r
+}\r
+\r
+static void extract_ppg_ch_write_fifo(const pah831x_regs *regs, bool ppg_ch_write_fifo[PAH831X_CH__PPG_NUM])\r
+{\r
+    ppg_ch_write_fifo[PAH831X_CH__PPG_A1] =\r
+        regs->has_values[PAH831X_REG__B0_0X1B] &&\r
+        regs->has_values[PAH831X_REG__B0_0X50] &&\r
+        PAH_CHECK_BIT(regs->values[PAH831X_REG__B0_0X1B], PAH831X_B0__CH_ENH_1__CH_A__POS) &&\r
+        PAH_CHECK_BIT(regs->values[PAH831X_REG__B0_0X50], PAH831X_B0__PPG_A__PPG1_ENH__POS) &&\r
+        !PAH_CHECK_BIT(regs->values[PAH831X_REG__B0_0X50], PAH831X_B0__PPG_A__FIFO_WRITE_MASK__POS);\r
+    ppg_ch_write_fifo[PAH831X_CH__PPG_A2] =\r
+        regs->has_values[PAH831X_REG__B0_0X1B] &&\r
+        regs->has_values[PAH831X_REG__B0_0X50] &&\r
+        PAH_CHECK_BIT(regs->values[PAH831X_REG__B0_0X1B], PAH831X_B0__CH_ENH_1__CH_A__POS) &&\r
+        PAH_CHECK_BIT(regs->values[PAH831X_REG__B0_0X50], PAH831X_B0__PPG_A__PPG2_ENH__POS) &&\r
+        !PAH_CHECK_BIT(regs->values[PAH831X_REG__B0_0X50], PAH831X_B0__PPG_A__FIFO_WRITE_MASK__POS);\r
+\r
+    ppg_ch_write_fifo[PAH831X_CH__PPG_B1] =\r
+        regs->has_values[PAH831X_REG__B0_0X1B] &&\r
+        regs->has_values[PAH831X_REG__B0_0X51] &&\r
+        PAH_CHECK_BIT(regs->values[PAH831X_REG__B0_0X1B], PAH831X_B0__CH_ENH_1__CH_B__POS) &&\r
+        PAH_CHECK_BIT(regs->values[PAH831X_REG__B0_0X51], PAH831X_B0__PPG_B__PPG1_ENH__POS) &&\r
+        !PAH_CHECK_BIT(regs->values[PAH831X_REG__B0_0X51], PAH831X_B0__PPG_B__FIFO_WRITE_MASK__POS);\r
+    ppg_ch_write_fifo[PAH831X_CH__PPG_B2] =\r
+        regs->has_values[PAH831X_REG__B0_0X1B] &&\r
+        regs->has_values[PAH831X_REG__B0_0X51] &&\r
+        PAH_CHECK_BIT(regs->values[PAH831X_REG__B0_0X1B], PAH831X_B0__CH_ENH_1__CH_B__POS) &&\r
+        PAH_CHECK_BIT(regs->values[PAH831X_REG__B0_0X51], PAH831X_B0__PPG_B__PPG2_ENH__POS) &&\r
+        !PAH_CHECK_BIT(regs->values[PAH831X_REG__B0_0X51], PAH831X_B0__PPG_B__FIFO_WRITE_MASK__POS);\r
+\r
+    ppg_ch_write_fifo[PAH831X_CH__PPG_C1] =\r
+        regs->has_values[PAH831X_REG__B0_0X1B] &&\r
+        regs->has_values[PAH831X_REG__B0_0X52] &&\r
+        PAH_CHECK_BIT(regs->values[PAH831X_REG__B0_0X1B], PAH831X_B0__CH_ENH_1__CH_C__POS) &&\r
+        PAH_CHECK_BIT(regs->values[PAH831X_REG__B0_0X52], PAH831X_B0__PPG_C__PPG1_ENH__POS) &&\r
+        !PAH_CHECK_BIT(regs->values[PAH831X_REG__B0_0X52], PAH831X_B0__PPG_C__FIFO_WRITE_MASK__POS);\r
+    ppg_ch_write_fifo[PAH831X_CH__PPG_C2] =\r
+        regs->has_values[PAH831X_REG__B0_0X1B] &&\r
+        regs->has_values[PAH831X_REG__B0_0X52] &&\r
+        PAH_CHECK_BIT(regs->values[PAH831X_REG__B0_0X1B], PAH831X_B0__CH_ENH_1__CH_C__POS) &&\r
+        PAH_CHECK_BIT(regs->values[PAH831X_REG__B0_0X52], PAH831X_B0__PPG_C__PPG2_ENH__POS) &&\r
+        !PAH_CHECK_BIT(regs->values[PAH831X_REG__B0_0X52], PAH831X_B0__PPG_C__FIFO_WRITE_MASK__POS);\r
+\r
+    ppg_ch_write_fifo[PAH831X_CH__PPG_D1] =\r
+        regs->has_values[PAH831X_REG__B0_0X1B] &&\r
+        regs->has_values[PAH831X_REG__B0_0X53] &&\r
+        PAH_CHECK_BIT(regs->values[PAH831X_REG__B0_0X1B], PAH831X_B0__CH_ENH_1__CH_D__POS) &&\r
+        PAH_CHECK_BIT(regs->values[PAH831X_REG__B0_0X53], PAH831X_B0__PPG_D__PPG1_ENH__POS) &&\r
+        !PAH_CHECK_BIT(regs->values[PAH831X_REG__B0_0X53], PAH831X_B0__PPG_D__FIFO_WRITE_MASK__POS);\r
+    ppg_ch_write_fifo[PAH831X_CH__PPG_D2] =\r
+        regs->has_values[PAH831X_REG__B0_0X1B] &&\r
+        regs->has_values[PAH831X_REG__B0_0X53] &&\r
+        PAH_CHECK_BIT(regs->values[PAH831X_REG__B0_0X1B], PAH831X_B0__CH_ENH_1__CH_D__POS) &&\r
+        PAH_CHECK_BIT(regs->values[PAH831X_REG__B0_0X53], PAH831X_B0__PPG_D__PPG2_ENH__POS) &&\r
+        !PAH_CHECK_BIT(regs->values[PAH831X_REG__B0_0X53], PAH831X_B0__PPG_D__FIFO_WRITE_MASK__POS);\r
+\r
+    ppg_ch_write_fifo[PAH831X_CH__PPG_E1] =\r
+        regs->has_values[PAH831X_REG__B0_0X68] &&\r
+        regs->has_values[PAH831X_REG__B0_0X70] &&\r
+        PAH_CHECK_BIT(regs->values[PAH831X_REG__B0_0X68], PAH831X_B0__CH_ENH_2__CH_E__POS) &&\r
+        PAH_CHECK_BIT(regs->values[PAH831X_REG__B0_0X70], PAH831X_B0__PPG_E__PPG1_ENH__POS) &&\r
+        !PAH_CHECK_BIT(regs->values[PAH831X_REG__B0_0X70], PAH831X_B0__PPG_E__FIFO_WRITE_MASK__POS);\r
+    ppg_ch_write_fifo[PAH831X_CH__PPG_E2] =\r
+        regs->has_values[PAH831X_REG__B0_0X68] &&\r
+        regs->has_values[PAH831X_REG__B0_0X70] &&\r
+        PAH_CHECK_BIT(regs->values[PAH831X_REG__B0_0X68], PAH831X_B0__CH_ENH_2__CH_E__POS) &&\r
+        PAH_CHECK_BIT(regs->values[PAH831X_REG__B0_0X70], PAH831X_B0__PPG_E__PPG2_ENH__POS) &&\r
+        !PAH_CHECK_BIT(regs->values[PAH831X_REG__B0_0X70], PAH831X_B0__PPG_E__FIFO_WRITE_MASK__POS);\r
+\r
+    ppg_ch_write_fifo[PAH831X_CH__PPG_F1] =\r
+        regs->has_values[PAH831X_REG__B0_0X68] &&\r
+        regs->has_values[PAH831X_REG__B0_0X71] &&\r
+        PAH_CHECK_BIT(regs->values[PAH831X_REG__B0_0X68], PAH831X_B0__CH_ENH_2__CH_F__POS) &&\r
+        PAH_CHECK_BIT(regs->values[PAH831X_REG__B0_0X71], PAH831X_B0__PPG_F__PPG1_ENH__POS) &&\r
+        !PAH_CHECK_BIT(regs->values[PAH831X_REG__B0_0X71], PAH831X_B0__PPG_F__FIFO_WRITE_MASK__POS);\r
+    ppg_ch_write_fifo[PAH831X_CH__PPG_F2] =\r
+        regs->has_values[PAH831X_REG__B0_0X68] &&\r
+        regs->has_values[PAH831X_REG__B0_0X71] &&\r
+        PAH_CHECK_BIT(regs->values[PAH831X_REG__B0_0X68], PAH831X_B0__CH_ENH_2__CH_F__POS) &&\r
+        PAH_CHECK_BIT(regs->values[PAH831X_REG__B0_0X71], PAH831X_B0__PPG_F__PPG2_ENH__POS) &&\r
+        !PAH_CHECK_BIT(regs->values[PAH831X_REG__B0_0X71], PAH831X_B0__PPG_F__FIFO_WRITE_MASK__POS);\r
+}\r
+\r
+static void extract_ppg_led(const pah831x_regs *regs, uint8_t ppg_led[PAH831X_CH__PPG_NUM])\r
+{\r
+    int i = 0;\r
+\r
+    for (i = 0; i < PAH831X_CH__PPG_NUM; ++i)\r
+    {\r
+        pah831x_reg reg_index = PPG_LED_REG_LOOKUP_TABLE[i];\r
+\r
+        if (regs->has_values[reg_index])\r
+            ppg_led[i] = regs->values[reg_index];\r
+        else\r
+            ppg_led[i] = 0;\r
+    }\r
+}\r
+\r
+static bool extract_ecg_ch_enabled(const pah831x_regs *regs)\r
+{\r
+    return regs->has_values[PAH831X_REG__B0_0X1B] &&\r
+        PAH_CHECK_BIT(regs->values[PAH831X_REG__B0_0X1B], PAH831X_B0__CH_ENH_1__ECG__POS);\r
+}\r
+\r
+float extract_ppg_sample_rate(const pah831x_regs *regs)\r
+{\r
+    uint32_t report_period = extract_report_period(regs);\r
+    uint8_t decimation_num = extract_decimation_num(regs);\r
+\r
+    return calculate_sample_rate(report_period, decimation_num);\r
+}\r
+\r
+float extract_ecg_sample_rate(const pah831x_regs *regs)\r
+{\r
+    uint32_t report_period = extract_report_period(regs);\r
+    uint8_t decimation_num = 1;\r
+\r
+    return calculate_sample_rate(report_period, decimation_num);\r
+}\r
+\r
+static uint32_t extract_report_period(const pah831x_regs *regs)\r
+{\r
+    return UINT32_FROM_UINT8(regs->values[PAH831X_REG__B0_0X03], regs->values[PAH831X_REG__B0_0X04], 0, 0);\r
+}\r
+\r
+static uint8_t extract_decimation_num(const pah831x_regs *regs)\r
+{\r
+    uint8_t decimation_num = PAH_GET_BITSLICE(regs->values[PAH831X_REG__B0_0X56], PAH831X_B0__DECIMATION_NUM__POS, PAH831X_B0__DECIMATION_NUM__MSK);\r
+    return (decimation_num > 0) ? decimation_num : 1;\r
+}\r
+\r
+static pah831x_ch extract_ch(const uint8_t *fifo, uint16_t data_index)\r
+{\r
+    pah831x_ch ch;\r
+    uint16_t fifo_index = PAH831X_DATA_SIZE * data_index;\r
+    uint8_t rx_tag = PAH_CHECK_BIT(fifo[fifo_index + 1], 4);\r
+    uint8_t ch_tag = extract_ch_tag(fifo, data_index);\r
+\r
+    switch (ch_tag)\r
+    {\r
+        case 0:\r
+            ch = (rx_tag == 0) ? PAH831X_CH__PPG_A1 : PAH831X_CH__PPG_A2;\r
+            break;\r
+        case 1:\r
+            ch = (rx_tag == 0) ? PAH831X_CH__PPG_B1 : PAH831X_CH__PPG_B2;\r
+            break;\r
+        case 2:\r
+            ch = (rx_tag == 0) ? PAH831X_CH__PPG_C1 : PAH831X_CH__PPG_C2;\r
+            break;\r
+        case 3:\r
+            ch = (rx_tag == 0) ? PAH831X_CH__PPG_D1 : PAH831X_CH__PPG_D2;\r
+            break;\r
+        case 4:\r
+            ch = (rx_tag == 0) ? PAH831X_CH__PPG_E1 : PAH831X_CH__PPG_E2;\r
+            break;\r
+        case 5:\r
+            ch = (rx_tag == 0) ? PAH831X_CH__PPG_F1 : PAH831X_CH__PPG_F2;\r
+            break;\r
+        case 6:\r
+        default:\r
+            ch = PAH831X_CH__ECG;\r
+            break;\r
+    }\r
+\r
+    return ch;\r
+}\r
+\r
+static uint8_t extract_ch_tag(const uint8_t *fifo, uint16_t data_index)\r
+{\r
+    uint16_t fifo_index = PAH831X_DATA_SIZE * data_index;\r
+    return PAH_GET_BITSLICE(fifo[fifo_index + 1], 0, 0x07);\r
+}\r
+\r
+static void select_watermarks(float ppg_sample_rate, uint8_t ppg_ch_num, float ecg_sample_rate, uint32_t batch_period, uint16_t *ppg_watermark, uint16_t *ecg_watermark, uint16_t *fifo_watermark)\r
+{\r
+    uint16_t select_ppg_watermark = 0;\r
+    uint16_t select_ecg_watermark = 0;\r
+    uint16_t select_fifo_watermark = 0;\r
+    float select_batch_period = (float)UINT32_MAX;\r
+    float ppg_batch_period = 0;\r
+    float ecg_batch_period = 0;\r
+    bool divisible = ecg_is_divisible_by_ppg(ppg_sample_rate, ecg_sample_rate);\r
+    float ppg_sample_period = sample_rate_to_sample_period(ppg_sample_rate);\r
+    float ecg_sample_period = sample_rate_to_sample_period(ecg_sample_rate);\r
+\r
+    if (ppg_sample_rate > 0.0f && divisible)\r
+    {\r
+        select_ppg_watermark = (uint16_t)(batch_period / ppg_sample_period);\r
+//        if (select_ppg_watermark > PAH831X_PPG_MAX_WATERMARK)\r
+//            select_ppg_watermark = PAH831X_PPG_MAX_WATERMARK;\r
+\r
+        ppg_batch_period = ppg_sample_period * select_ppg_watermark;\r
+        if (select_batch_period > ppg_batch_period)\r
+            select_batch_period = ppg_batch_period;\r
+    }\r
+    if (ecg_sample_rate > 0.0f)\r
+    {\r
+        select_ecg_watermark = (uint16_t)(batch_period / ecg_sample_period);\r
+        if (select_ecg_watermark > PAH831X_ECG_MAX_WATERMARK)\r
+            select_ecg_watermark = PAH831X_ECG_MAX_WATERMARK;\r
+\r
+        ecg_batch_period = ecg_sample_period * select_ecg_watermark;\r
+        if (select_batch_period > ecg_batch_period)\r
+            select_batch_period = ecg_batch_period;\r
+    }\r
+    if (ppg_sample_rate > 0.0f && divisible && ecg_sample_rate > 0.0f)\r
+    {\r
+        uint16_t sample_data_count = 0;\r
+        uint16_t max_watermark = 0;\r
+        float sample_period = 0.0f;\r
+        uint32_t max_batch_period = 0;\r
+\r
+        sample_data_count += ppg_ch_num;\r
+        sample_data_count += calculate_ecg_watermark_factor(ppg_sample_rate, ecg_sample_rate);\r
+\r
+        max_watermark = PAH831X_MAX_DATA_COUNT / sample_data_count;\r
+\r
+        sample_period = sample_rate_to_sample_period(ppg_sample_rate);\r
+        max_batch_period = (uint32_t)(max_watermark * sample_period);\r
+        if (select_batch_period > max_batch_period)\r
+            select_batch_period = (float)max_batch_period;\r
+    }\r
+\r
+    if (ppg_sample_rate > 0.0f && divisible)\r
+    {\r
+        select_ppg_watermark = (uint16_t)(select_batch_period / ppg_sample_period);\r
+        if (select_ppg_watermark < 1)\r
+            select_ppg_watermark = 1;\r
+    }\r
+    if (ecg_sample_rate > 0.0f)\r
+    {\r
+        select_ecg_watermark = (uint16_t)(select_batch_period / ecg_sample_period);\r
+        if (select_ecg_watermark < 1)\r
+            select_ecg_watermark = 1;\r
+        if (ppg_sample_rate > 0.0f && divisible)\r
+        {\r
+            uint16_t ecg_watermark_factor = calculate_ecg_watermark_factor(ppg_sample_rate, ecg_sample_rate);\r
+            select_ecg_watermark = (select_ecg_watermark / ecg_watermark_factor) * ecg_watermark_factor;\r
+            if (select_ecg_watermark < 1 * ecg_watermark_factor)\r
+                select_ecg_watermark = 1 * ecg_watermark_factor;\r
+        }\r
+    }\r
+    LOG_PRINT("select_ppg_watermark = %d,select_ecg_watermark =%d \n", select_ppg_watermark,select_ecg_watermark);\r
+    select_fifo_watermark = select_ppg_watermark * ppg_ch_num + select_ecg_watermark;\r
+\r
+    *ppg_watermark = select_ppg_watermark;\r
+    *ecg_watermark = select_ecg_watermark;\r
+    *fifo_watermark = select_fifo_watermark;\r
+    \r
+    if(select_fifo_watermark>PAH831X_MAX_DATA_COUNT)\r
+        *fifo_watermark = 0 ;\r
+}\r
+\r
+static float calculate_sample_rate(uint32_t report_period, uint8_t decimation_num)\r
+{\r
+    //return 32000.0f / (report_period * decimation_num);\r
+    return LPO_CLK_FREQ / (report_period * decimation_num);\r
+}\r
+\r
+static uint16_t calculate_ecg_watermark_factor(float ppg_sample_rate, float ecg_sample_rate)\r
+{\r
+    return (uint16_t)(ecg_sample_rate / ppg_sample_rate);\r
+}\r
+\r
+static uint8_t calculate_decimation_num(float sample_rate, uint32_t report_period)\r
+{\r
+   // return (uint8_t)(32000.0f / (sample_rate * report_period));\r
+    return (uint8_t)(LPO_CLK_FREQ / (sample_rate * report_period));\r
+}\r
+\r
+static bool calculate_ppg_frame_period(const pah831x_regs *regs, uint16_t *ppg_frame_period)\r
+{\r
+    uint16_t frame_period = 0;\r
+    uint8_t ppg_ip_stl = regs->values[PAH831X_REG__B1_0X1A];\r
+    bool ppg_ch_enh[PAH831X_PPG_CH__NUM];\r
+\r
+    if (!regs->has_values[PAH831X_REG__B1_0X1A])\r
+        return false;\r
+\r
+    memset(ppg_ch_enh, 0, sizeof(ppg_ch_enh));\r
+    extract_ppg_ch_enh(regs, ppg_ch_enh);\r
+\r
+    if (ppg_ch_enh[PAH831X_PPG_CH__A] && regs->has_values[PAH831X_REG__B0_0X12])\r
+        frame_period += calculate_ppg_ch_frame_period(regs->values[PAH831X_REG__B0_0X12], ppg_ip_stl);\r
+    if (ppg_ch_enh[PAH831X_PPG_CH__B] && regs->has_values[PAH831X_REG__B0_0X13])\r
+        frame_period += calculate_ppg_ch_frame_period(regs->values[PAH831X_REG__B0_0X13], ppg_ip_stl);\r
+    if (ppg_ch_enh[PAH831X_PPG_CH__C] && regs->has_values[PAH831X_REG__B0_0X14])\r
+        frame_period += calculate_ppg_ch_frame_period(regs->values[PAH831X_REG__B0_0X14], ppg_ip_stl);\r
+    if (ppg_ch_enh[PAH831X_PPG_CH__D] && regs->has_values[PAH831X_REG__B0_0X15])\r
+        frame_period += calculate_ppg_ch_frame_period(regs->values[PAH831X_REG__B0_0X15], ppg_ip_stl);\r
+    if (ppg_ch_enh[PAH831X_PPG_CH__E] && regs->has_values[PAH831X_REG__B0_0X6D])\r
+        frame_period += calculate_ppg_ch_frame_period(regs->values[PAH831X_REG__B0_0X6D], ppg_ip_stl);\r
+    if (ppg_ch_enh[PAH831X_PPG_CH__F] && regs->has_values[PAH831X_REG__B0_0X6E])\r
+        frame_period += calculate_ppg_ch_frame_period(regs->values[PAH831X_REG__B0_0X6E], ppg_ip_stl);\r
+    if (ppg_ch_enh[PAH831X_PPG_CH__T] && regs->has_values[PAH831X_REG__B0_0X16])\r
+        frame_period += calculate_ppg_ch_frame_period(regs->values[PAH831X_REG__B0_0X16], ppg_ip_stl);\r
+\r
+    *ppg_frame_period = (uint16_t)(frame_period * 0.25f);\r
+    return true;\r
+}\r
+\r
+static uint16_t calculate_ppg_ch_frame_period(uint8_t frame_num, uint8_t ppg_ip_stl)\r
+{\r
+    return ((frame_num + 1) * 64 + ppg_ip_stl) * 3;\r
+}\r
+\r
+static float sample_rate_to_sample_period(float sample_rate)\r
+{\r
+    if(sample_rate!=0)\r
+        return 1000.0f / sample_rate; \r
+    else\r
+        return 0 ;\r
+}\r
+\r
+static bool ecg_is_divisible_by_ppg(float ppg_sample_rate, float ecg_sample_rate)\r
+{\r
+    uint32_t ppg_rate = (uint32_t)ppg_sample_rate;\r
+    uint32_t ecg_rate = (uint32_t)ecg_sample_rate;\r
+\r
+    if (ppg_rate == 0)\r
+        return true;\r
+\r
+    return (ecg_rate % ppg_rate) == 0;\r
+}\r
+\r
+static int32_t cvt24bit(uint32_t val)\r
+{\r
+    val &= 0xffffff;  // limit to 24 bits -- may not be necessary\r
+    if (val >= ((uint32_t)1 << 23))\r
+        return (int32_t)val - ((uint32_t)1 << 24);\r
+    else\r
+        return val;\r
+}\r
+\r
+pah_ret pah_831x_get_product_id(uint16_t *product_id)\r
+{\r
+    int ret = read_product_id(NULL,product_id);\r
+    printf("ret:%d,product_id:0x%x\n",ret,*product_id);\r
+    return 0;\r
+}
\ No newline at end of file
diff --git a/code/sdk/zhihui/drivers/ppg/pah831x/pah_sensor/pah831x.h b/code/sdk/zhihui/drivers/ppg/pah831x/pah_sensor/pah831x.h
new file mode 100644 (file)
index 0000000..8e1616c
--- /dev/null
@@ -0,0 +1,335 @@
+#pragma once\r
+/**\r
+ * Copyright (c) 2022 PixArt Imaging Inc.\r
+ * All Rights Reserved.\r
+ * Confidential and Proprietary - PixArt Imaging Inc.\r
+ **/\r
+#include "pah831x_define.h"\r
+#include "pah831x_config.h"\r
+\r
+#include "pah_plat.h"\r
+#include "pah_reg.h"\r
+#include "pah_ret.h"\r
+\r
+//============================================================================\r
+// Terminology\r
+//============================================================================\r
+/**\r
+ *\r
+ * [data]: channel data.\r
+ * [data_size]: the size in bytes of [data].\r
+ * [data_num]: the number of [data]\r
+ * Ex: ch_num=2, data_size=5\r
+ * |----------------------------------|----------------------------------|-------\r
+ * |             data(ch0)            |          data(ch1)               |   ...\r
+ * |----------------------------------|----------------------------------|-------\r
+ * | byte | byte | byte | byte | byte | byte | byte | byte | byte | byte |   ...\r
+ * |----------------------------------|----------------------------------|-------\r
+ *\r
+ *\r
+ * [sample]: combination of one or more [data] at a point in time.\r
+ * [ch_num]: the number of channel per [sample].\r
+ * Ex: ch_num=2,\r
+ * |-----------------------|-----------------------|-----------------------|-\r
+ * |       sample(0)       |       sample(1)       |       sample(2)       |\r
+ * |-----------------------|-----------------------|-----------------------|-\r
+ * | data(ch0) | data(ch1) | data(ch0) | data(ch1) | data(ch0) | data(ch1) |\r
+ * |-----------------------|-----------------------|-----------------------|-\r
+ *\r
+ *\r
+ * [sample_num]: the number of [sample]\r
+ * [sample_rate]: [sample_num] per second\r
+ * Ex: sample_rate=20Hz\r
+ * |-------------|-------------|-------------|-------------|-------------|-\r
+ * |  time=50ms  |  time=100ms |  time=150ms |  time=200ms |  time=250ms |\r
+ * |-------------|-------------|-------------|-------------|-------------|-\r
+ * |  sample(0)  |  sample(1)  |  sample(2)  |  sample(3)  |  sample(4)  |\r
+ * |-----------------------------------------|---------------------------|-\r
+ *                                           v                           v\r
+ *                                     sample_num=3                sample_num=5\r
+ *\r
+ *\r
+ * [watermark]: Sensors trigger an interrupt signal when [sample_num] in FIFO\r
+ *              reaches the number of watermark.\r
+ * Ex: watermark=3\r
+ * |-----------------------------------|-----------------------------------|-\r
+ * | sample(0) | sample(1) | sample(2) | sample(0) | sample(1) | sample(2) |\r
+ * |-----------------------------------|-----------------------------------|-\r
+ *                                     v                                   v\r
+ *                                 interrupt                           interrupt\r
+ *\r
+ **/\r
+\r
+//============================================================================\r
+// Preprocessor\r
+//============================================================================\r
+#if defined (__CC_ARM)\r
+#pragma anon_unions\r
+#endif\r
+\r
+//============================================================================\r
+// Public definition\r
+//============================================================================\r
+typedef void (*pah831x_read_fifo_cb)(void *user_data, uint8_t *fifo, uint16_t data_count, float read_bytes_ratio);\r
+\r
+typedef enum\r
+{\r
+    // When enabling PPG, the driver turns on LED instantly\r
+    PAH831X_PPG_LED_ON_INSTANTLY = 0,\r
+\r
+    // When enabling PPG, the driver does not turn on LED.\r
+    // and turn on LED once the first touch has been detected.\r
+    PAH831X_PPG_LED_ON_DEFERRED,\r
+} pah831x_ppg_led_on;\r
+\r
+typedef enum\r
+{\r
+    PAH831X_CH__PPG_A1,\r
+    PAH831X_CH__PPG_A2,\r
+    PAH831X_CH__PPG_B1,\r
+    PAH831X_CH__PPG_B2,\r
+    PAH831X_CH__PPG_C1,\r
+    PAH831X_CH__PPG_C2,\r
+    PAH831X_CH__PPG_D1,\r
+    PAH831X_CH__PPG_D2,\r
+    PAH831X_CH__PPG_E1,\r
+    PAH831X_CH__PPG_E2,\r
+    PAH831X_CH__PPG_F1,\r
+    PAH831X_CH__PPG_F2,\r
+    PAH831X_CH__PPG_NUM,\r
+    PAH831X_CH__ECG = PAH831X_CH__PPG_NUM,\r
+\r
+    PAH831X_CH__NUM,\r
+} pah831x_ch;\r
+\r
+typedef enum\r
+{\r
+    PAH831X_VERIFY_REG_ARR_RET__SUCCESS,\r
+\r
+    PAH831X_VERIFY_REG_ARR_RET__MISS_PPG1_F_ENH,\r
+\r
+    PAH831X_VERIFY_REG_ARR_RET__PPG_MISS_REPORT_PERIOD,\r
+    PAH831X_VERIFY_REG_ARR_RET__PPG_MISS_CH_ENH,\r
+    PAH831X_VERIFY_REG_ARR_RET__PPG_INVALID_SAMPLE_RATE,\r
+    PAH831X_VERIFY_REG_ARR_RET__PPG_INVALID_CH_NUM,\r
+    PAH831X_VERIFY_REG_ARR_RET__PPG_FRAME_PERIOD_CAL_FAIL,\r
+    PAH831X_VERIFY_REG_ARR_RET__PPG_FRAME_PERIOD_EXCEED,\r
+\r
+    PAH831X_VERIFY_REG_ARR_RET__ECG_MISS_REPORT_PERIOD,\r
+    PAH831X_VERIFY_REG_ARR_RET__ECG_MISS_CH_ENH,\r
+    PAH831X_VERIFY_REG_ARR_RET__ECG_REDUNDANT_REG,\r
+    PAH831X_VERIFY_REG_ARR_RET__ECG_INVALID_SAMPLE_RATE,\r
+    PAH831X_VERIFY_REG_ARR_RET__ECG_INVALID_CH_NUM,\r
+\r
+    PAH831X_VERIFY_REG_ARR_RET__ECG_PPG_NOT_DIVISIBLE,\r
+} pah831x_verify_reg_arr_ret;\r
+\r
+typedef struct\r
+{\r
+    pah_reg_arr init;\r
+    pah_reg_arr init_cal_1;\r
+    pah_reg_arr deinit; // optional\r
+} pah831x_init_reg_setting;\r
+\r
+typedef union\r
+{\r
+    struct\r
+    {\r
+        uint32_t lod_inp_h_state : 1;\r
+        uint32_t lod_inp_l_state : 1;\r
+        uint32_t lod_inm_h_state : 1;\r
+        uint32_t lod_inm_l_state : 1;\r
+        uint32_t lod_rld_h_state : 1;\r
+        uint32_t lod_rld_l_state : 1;\r
+        uint32_t reserve_06 : 1;\r
+        uint32_t reserve_07 : 1;\r
+\r
+        uint32_t notouch_detect : 1;\r
+        uint32_t overflow : 1;\r
+        uint32_t touch_detect : 1;\r
+        uint32_t fifo_ready : 1;\r
+        uint32_t touch_flag : 1;\r
+        uint32_t reserve_15 : 1;\r
+        uint32_t reserve_16 : 1;\r
+        uint32_t reserve_17 : 1;\r
+    };\r
+    uint8_t data[2];\r
+    uint16_t value;\r
+} pah831x_int_flag;\r
+#define PAH831X_HAS_FIFO_INT(int_flag)      (int_flag.fifo_ready)\r
+#define PAH831X_HAS_TOUCH_INT(int_flag)     (int_flag.notouch_detect || int_flag.touch_detect)\r
+\r
+typedef struct\r
+{\r
+    bool has_data[PAH831X_CH__PPG_NUM];\r
+    uint32_t data[PAH831X_CH__PPG_NUM];\r
+    uint8_t dac[PAH831X_CH__PPG_NUM];\r
+} pah831x_ppg_sample;\r
+\r
+typedef struct\r
+{\r
+    int32_t data;\r
+    uint8_t tag;\r
+} pah831x_ecg_sample;\r
+\r
+//============================================================================\r
+// Private definition\r
+//============================================================================\r
+typedef struct\r
+{\r
+    pah831x_init_reg_setting init_reg_setting;\r
+    pah831x_ppg_led_on ppg_led_on;\r
+    uint32_t batch_period_ms;\r
+    bool enable_ecg_polar_switch;\r
+} pah831x_setting;\r
+\r
+typedef struct\r
+{\r
+    float sample_rate;\r
+    uint16_t watermark;\r
+    uint16_t sample_data_count;\r
+    uint8_t ch_num;\r
+} pah831x_ppg;\r
+\r
+typedef struct\r
+{\r
+    float sample_rate;\r
+    uint16_t watermark;\r
+    uint16_t frame_num;\r
+    uint16_t sample_data_count;\r
+    uint8_t gain;\r
+    bool enabled;\r
+} pah831x_ecg;\r
+\r
+typedef struct\r
+{\r
+    pah831x_setting setting;\r
+    pah831x_ppg ppg;\r
+    pah831x_ecg ecg;\r
+    pah831x_int_flag int_flag;\r
+    pah_plat plat;\r
+\r
+    uint16_t fifo_watermark;\r
+    uint16_t sample_data_count;\r
+\r
+    uint8_t ppg_led[PAH831X_CH__PPG_NUM];\r
+\r
+    bool is_started;\r
+    bool is_ppg_led_on;\r
+    bool fifo_clock_enabled;\r
+    bool has_int_flag;\r
+    uint16_t touch_value ;\r
+    bool touch_flag ; \r
+    \r
+    bool ir_r_led_switch_enable  ;\r
+    bool ir_r_led_switch_status ;\r
+    bool ir_r_led_switch_new_status ;\r
+    \r
+    uint8_t afe_gain_flag;\r
+//    bool channel_f_touch_en_bit ;\r
+} pah831x;\r
+\r
+//============================================================================\r
+// Public function\r
+//============================================================================\r
+#ifdef __cplusplus\r
+extern  "C" {\r
+#endif\r
+\r
+// Default\r
+uint16_t    pah831x_default_i2c_slave_addr(void);\r
+\r
+// Init\r
+void        pah831x_init(pah831x *state, const pah_plat *plat, const pah831x_init_reg_setting *init_reg_setting);\r
+void        pah831x_deinit(pah831x *state);\r
+\r
+// Optional config (Set for next start)\r
+void        pah831x_set_ppg_led_on(pah831x *state, pah831x_ppg_led_on ppg_led_on);\r
+void        pah831x_set_batch_period(pah831x *state, uint32_t batch_period_ms);\r
+void        pah831x_set_ecg_polar_switch(pah831x *state, bool enable_ecg_polar_switch);\r
+\r
+// Power\r
+pah_ret     pah831x_soft_reset(pah831x *state);\r
+pah_ret     pah831x_power_off(pah831x *state);\r
+\r
+// Start_1\r
+// reg_arr can be NULL\r
+pah_ret     pah831x_start(pah831x *state, const pah_reg_arr *reg_arr);\r
+\r
+// Start_2\r
+// ppg_reg_arr or ecg_reg_arr can be NULL\r
+pah_ret     pah831x_start_2(pah831x *state, const pah_reg_arr *ppg_reg_arr, const pah_reg_arr *ecg_reg_arr);\r
+\r
+// Basic verification\r
+pah_ret     pah831x_verify_product_id(pah831x *state, uint16_t *product_id);\r
+pah_ret     pah831x_hal_verify_product_id(pah_plat *plat, uint16_t *product_id);\r
+pah_ret     pah831x_hal_soft_reset(pah_plat *plat);\r
+pah_ret     pah831x_hal_power_down(pah_plat *plat);\r
+\r
+// PPG/ECG\r
+pah_ret     pah831x_reset_batch_period(pah831x *state, uint32_t batch_period_ms);\r
+uint32_t    pah831x_get_batch_period(pah831x *state);\r
+uint32_t    pah831x_get_max_batch_period(pah831x *state);\r
+uint16_t    pah831x_get_fifo_watermark(pah831x *state);\r
+size_t      pah831x_get_sample_size(pah831x *state);\r
+bool        pah831x_get_ppg_is_enabled(pah831x *state);\r
+float       pah831x_get_ppg_sample_rate(pah831x *state);\r
+uint16_t    pah831x_get_ppg_watermark(pah831x *state);\r
+uint16_t    pah831x_get_max_ppg_watermark(void);\r
+uint8_t     pah831x_get_ppg_ch_num(pah831x *state);\r
+bool        pah831x_get_ecg_is_enabled(pah831x *state);\r
+float       pah831x_get_ecg_sample_rate(pah831x *state);\r
+uint16_t    pah831x_get_ecg_watermark(pah831x *state);\r
+uint16_t    pah831x_get_ecg_frame_num(pah831x *state);\r
+uint8_t     pah831x_get_ecg_gain(pah831x *state);\r
+uint16_t    pah831x_get_max_ecg_watermark(void);\r
+\r
+// Task\r
+pah_ret     pah831x_read_int_flag(pah831x *state, pah831x_int_flag *int_flag);\r
+uint16_t    pah831x_read_fifo_data_count(pah831x *state);\r
+void        pah831x_deduce_sample_num(pah831x *state, uint16_t data_count, uint16_t *sample_num, uint16_t *ppg_sample_num, uint16_t *ecg_sample_num);\r
+pah_ret     pah831x_read_fifo(pah831x *state, uint8_t *buffer, size_t buffer_size, uint16_t data_count, pah831x_read_fifo_cb read_fifo_cb, void *user_data);\r
+pah_ret     pah831x_read_touch_flag(pah831x *state, bool *touch_flag);\r
+pah_ret     pah831x_read_touch_value(pah831x *state, uint16_t *touch_value);\r
+pah_ret     pah831x_polling_fifo_begin(pah831x *state);\r
+pah_ret     pah831x_manual_read_fifo_begin(pah831x *state);\r
+pah_ret     pah831x_manual_read_fifo(pah831x *state, uint8_t *buffer, size_t read_size);\r
+pah_ret     pah831x_manual_read_fifo_end(pah831x *state);\r
+pah_ret     pah831x_task(pah831x *state);\r
+\r
+// Helper\r
+void        pah831x_extract_sample_num(const uint8_t *fifo, uint16_t data_count, uint16_t *ppg_sample_num, uint16_t *ecg_sample_num);\r
+void        pah831x_extract_ppg_sample(const uint8_t *fifo, uint16_t data_count, uint16_t sample_index, pah831x_ppg_sample *ppg_sample);\r
+void        pah831x_extract_ecg_sample(const uint8_t *fifo, uint16_t data_count, uint16_t sample_index, pah831x_ecg_sample *ecg_sample);\r
+\r
+float       pah831x_extract_ppg_sample_rate(const pah_reg_arr *reg_arr);\r
+float       pah831x_extract_ecg_sample_rate(const pah_reg_arr *reg_arr);\r
+\r
+float       pah831x_ecg_to_adc(pah831x *state, int32_t data);\r
+\r
+// Verify\r
+pah831x_verify_reg_arr_ret pah831x_verify_reg_arr_start(pah831x *state, const pah_reg_arr *reg_arr);\r
+pah831x_verify_reg_arr_ret pah831x_verify_reg_arr_start_2(pah831x *state, const pah_reg_arr *ppg_reg_arr, const pah_reg_arr *ecg_reg_arr);\r
+pah831x_verify_reg_arr_ret pah831x_verify_ppg_reg_arr(pah831x *state, const pah_reg_arr *ppg_reg_arr);\r
+pah831x_verify_reg_arr_ret pah831x_verify_ecg_reg_arr(pah831x *state, const pah_reg_arr *ecg_reg_arr);\r
+\r
+//ADC Data\r
+pah_ret pah831x_extract_PPG_ADC(uint16_t* adc_buf);\r
+\r
+pah_ret pah831x_update_ch_a_1000k(void);\r
+pah_ret pah831x_update_ch_a_150k(void);\r
+\r
+pah_ret pah831x_update_ch_a_75k(void);\r
+pah_ret pah831x_update_ch_a_350k_low(void);\r
+\r
+pah_ret pah831x_update_hrd_ch_gain(uint16_t adc_data);\r
+\r
+\r
+pah_ret pah831x_ir_r_led_control(uint8_t enable);\r
+\r
+pah_ret pah_831x_get_product_id(uint16_t *product_id);\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
diff --git a/code/sdk/zhihui/drivers/ppg/pah831x/pah_sensor/pah831x_comm.c b/code/sdk/zhihui/drivers/ppg/pah831x/pah_sensor/pah831x_comm.c
new file mode 100644 (file)
index 0000000..b1c3f1a
--- /dev/null
@@ -0,0 +1,73 @@
+/*\r
+ * @Author: penglei 1624952103@qq.com\r
+ * @Date: 2025-12-25 09:34:31\r
+ * @LastEditors: penglei 1624952103@qq.com\r
+ * @LastEditTime: 2026-01-15 15:12:15\r
+ * @FilePath: /FD230/code/sdk/zhihui/drivers/ppg/pah831x/pah_sensor/pah831x_comm.c\r
+ * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE\r
+ */\r
+//#pragma once\r
+/**\r
+ * Copyright (c) 2018-2021 PixArt Imaging Inc.\r
+ * All Rights Reserved.\r
+ * Confidential and Proprietary - PixArt Imaging Inc.\r
+ **/\r
+#include <string.h>\r
+#include <stdlib.h>\r
+#include <stdint.h>\r
+#include <stdbool.h>\r
+#include <stdlib.h>\r
+#include <stdarg.h>\r
+#include <stdio.h>\r
+\r
+//#include "pah_815x_main.h"\r
+#include "pah831x_comm.h"\r
+#include "pah831x.h"\r
+#include "custom_utils.h"\r
+#include "systick.h"\r
+\r
+static uint8_t _curr_bank = 0xFF;\r
+\r
+#define PAH831X_I2C_BUS I2C_BUS_2\r
+\r
+pah_ret pah_comm_i2c_write( uint8_t addr, const uint8_t *data, size_t write_size)\r
+{\r
+    // DEBUG_PRINT("Write { 0x%02X, 0x%02X }\n",addr, data[0]);\r
+    custom_i2c_write_reg(PAH831X_DEFAULT_I2C_SLAVE_ADDR, addr, 1, data, write_size, PAH831X_I2C_BUS);\r
+    return PAH_RET_SUCCESS;\r
+}\r
+\r
+pah_ret pah_comm_i2c_read( uint8_t addr, uint8_t *data, size_t read_size)\r
+{\r
+    // DEBUG_PRINT("Read { 0x%02X }, Length =%d\n",addr,read_size);\r
+    custom_i2c_read_regs(PAH831X_DEFAULT_I2C_SLAVE_ADDR, addr, 1, data, read_size,PAH831X_I2C_BUS);\r
+    // if(read_size==2)\r
+    // {\r
+    //     DEBUG_PRINT("Read { 0x%02X }, Data { 0x%02X, 0x%02x }\n",addr, data[0],data[1]);\r
+    // }\r
+    // else if(read_size==1)\r
+    // {\r
+    //     DEBUG_PRINT("Read {0x%02X  }, Data { 0x%02x }\n", addr, data[0]);\r
+    // }\r
+    return PAH_RET_SUCCESS;\r
+}\r
+\r
+void pah_delay_ms( uint32_t ms)\r
+{\r
+    LOS_Mdelay(ms);\r
+}\r
+\r
+uint64_t pxi_get_tick_count(void)\r
+{\r
+    return uapi_systick_get_ms();\r
+}\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
diff --git a/code/sdk/zhihui/drivers/ppg/pah831x/pah_sensor/pah831x_comm.h b/code/sdk/zhihui/drivers/ppg/pah831x/pah_sensor/pah831x_comm.h
new file mode 100644 (file)
index 0000000..895d0e0
--- /dev/null
@@ -0,0 +1,72 @@
+/*\r
+ * @Author: penglei 1624952103@qq.com\r
+ * @Date: 2025-12-25 09:34:31\r
+ * @LastEditors: penglei 1624952103@qq.com\r
+ * @LastEditTime: 2025-12-29 11:19:48\r
+ * @FilePath: /FD230/code/sdk/zhihui/drivers/ppg/pah831x/pah_sensor/pah831x_comm.h\r
+ * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE\r
+ */\r
+#pragma once\r
+/**\r
+ * Copyright (c) 2018-2019 PixArt Imaging Inc.\r
+ * All Rights Reserved.\r
+ * Confidential and Proprietary - PixArt Imaging Inc.\r
+ **/\r
+#include <string.h>\r
+#include <stdarg.h>\r
+#include <stdio.h>\r
+#include <stdbool.h>\r
+#include <stdlib.h>\r
+\r
+\r
+// PXI bsp\r
+\r
+#include "pah831x.h"\r
+#include "pah831x_main.h"\r
+\r
+\r
+#define PXI_NRF_I2C_MAX_COMM_SIZE 255\r
+\r
+#define UNUSED_VAR(var)             (void)(var)    \r
+\r
+//=========== log  Define =====================// \r
+// #define DEBUG_LOG\r
+#define ENABLE_DATA_LOG\r
+#define ENABLE_ALG_LOG\r
+\r
+#ifdef  DEBUG_LOG\r
+#define DEBUG_PRINT(format, ...)    printf(format, ##__VA_ARGS__)\r
+#else\r
+#define DEBUG_PRINT(...) do {} while (0)\r
+#endif  \r
+        \r
+#ifdef  ENABLE_DATA_LOG\r
+#define LOG_PRINT(format, ...)    printf(format, ##__VA_ARGS__)\r
+#else\r
+#define LOG_PRINT(...) do {} while (0)\r
+#endif    \r
+       \r
+#ifdef  ENABLE_ALG_LOG\r
+#define ALG_PRINT(format, ...)    printf(format, ##__VA_ARGS__)\r
+#else\r
+#define ALG_PRINT(...) do {} while (0)\r
+#endif     \r
+//=====================================================//    \r
+#define ENABLE_CORE_PRINT (1)\r
+#define ENABLE_PLAT_PRINT (0)\r
+\r
+void pah_print(const char* format, ...);\r
+pah_ret pah_comm_i2c_write( uint8_t addr, const uint8_t *data, size_t write_size);\r
+pah_ret pah_comm_i2c_read( uint8_t addr, uint8_t *data, size_t read_size);\r
+void pah_delay_ms( uint32_t ms);\r
+uint64_t pxi_get_tick_count(void);\r
+//============================================================================\r
+// PUBLIC FUNCTION DEFINITIONS\r
+//============================================================================\r
+#define LOG_FLOAT_MARKER "%c%d.%05d"\r
+\r
+/**\r
+ * @brief Macro for dissecting a float number into two numbers (integer and residuum).\r
+ */\r
+#define LOG_FLOAT(val) ((val >= 0.0f)?32:45),(int32_t)((val >= 0.0f)?val:val*-1) , (int32_t)(((val > 0) ? (val) - (int32_t)(val): (int32_t)(val) - (val))*100000)              \r
+\r
diff --git a/code/sdk/zhihui/drivers/ppg/pah831x/pah_sensor/pah831x_config.h b/code/sdk/zhihui/drivers/ppg/pah831x/pah_sensor/pah831x_config.h
new file mode 100644 (file)
index 0000000..4ec5acc
--- /dev/null
@@ -0,0 +1,171 @@
+#pragma once\r
+/**\r
+ * Copyright (c) 2022 PixArt Imaging Inc.\r
+ * All Rights Reserved.\r
+ * Confidential and Proprietary - PixArt Imaging Inc.\r
+ **/\r
+\r
+//============================================================================\r
+// Option\r
+//============================================================================\r
+#define PAH831X_ENABLE_PRINT (1)\r
+\r
+#define PAH831X_DEFAULT_BATCH_PERIOD_MS (200)\r
+\r
+#define REQ_BATCH_PERIOD (1000)\r
+\r
+#define PAH831X_DEFAULT_BATCH_PERIOD_MS (200)\r
+\r
+#define PPG_WATERMARK_HRV 25\r
+\r
+#define PPG_WATERMARK_RR 25\r
+\r
+#define PPG_WATERMARK_STRESS 25\r
+\r
+#define PPG_WATERMARK_SS 25\r
+\r
+#define PPG_WATERMARK_OSA 25\r
+\r
+#define PPG_WATERMARK_RRI 100\r
+\r
+//#define Ext_LPO_CLK_FROM_GPIO2\r
+#ifdef Ext_LPO_CLK_FROM_GPIO2\r
+    #define LPO_CLK_FREQ 32768.0f\r
+#else\r
+    #define LPO_CLK_FREQ 32000.0f\r
+#endif\r
+#define LED_DAC_CHECK_TIME 2000\r
+\r
+//#define PPG_MODE_ONLY\r
+\r
+#define PPG_IR_CH_NUM 0\r
+#define ALG_GSENSOR_MODE 3\r
+\r
+#define PPG_DATA_NORMALIZE\r
+\r
+#define ENABLE_PAH831X_ECG_FUNCTION\r
+\r
+//============================================================================\r
+// DEMO\r
+//============================================================================\r
+        \r
+// (0) IR TOUCH POLLING===========//\r
+#define demo_ppg_Touch_polling_en_831x        \r
+        \r
+/* (1) HRD mode*/\r
+//#define demo_ppg_HRD_dri_en_831x\r
+//#define demo_ppg_HRD_polling_en_831x\r
+//#define demo_ppg_HRD_testpattern_en_831x\r
+#define ENABLE_PXI_ALG_HRD\r
+        \r
+/* (2) SPO2 mode*/\r
+//#define demo_ppg_SPO2_dri_en_831x\r
+//#define demo_ppg_SPO2_polling_en_831x\r
+//#define demo_ppg_SPO2_testpattern_en_831x\r
+#define ENABLE_PXI_ALG_SPO2\r
+#define ENABLE_PXI_ALG_SHRD\r
+\r
+//#define Optimize_SPO2_flow\r
+#define PPG_BUF_MAX_SPO2 30\r
+\r
+/* (3) HRV mode*/\r
+//#define demo_ppg_HRV_dri_en_831x\r
+//#define demo_ppg_HRV_polling_en_831x\r
+//#define demo_HRV_testpattern_en      \r
+#define ENABLE_PXI_ALG_HRV\r
+\r
+/* (4) RAW mode*/\r
+//#define demo_ppg_RAW_dri_en_831x\r
+//#define demo_ppg_RAW_polling_en_831x\r
+\r
+/* (5)  ECG AFIB *****/\r
+//#define demo_ecg_AFIB_dri_en_831x\r
+//#define demo_ecg_AFIB_polling_en_831x\r
+#define ENABLE_PXI_ALG_ECG_AFIB\r
+#define ENABLE_PXI_ALG_ECG_HRD\r
+\r
+/* (6)  ECG BP *****/\r
+//#define demo_ecg_BP_dri_en_831x\r
+//#define demo_ecg_BP_polling_en_831x\r
+//#define ENABLE_PXI_ALG_ECG_HRD\r
+#define ENABLE_PXI_ALG_ECG_BP\r
+\r
+/* (7)  ECG RAW *****/\r
+//#define demo_ecg_RAW_dri_en_831x\r
+//#define demo_ecg_RAW_polling_en_831x\r
+#define ENABLE_PXI_ALG_ECG\r
+\r
+/* (7)  Factory_Test *****/\r
+#define demo_factory_test_en_831x\r
+\r
+//#define PAH8311_1LED_TYPE \r
+#define PAH8311_2LED_TYPE \r
+\r
+\r
+#define LED_CH_0 0x01\r
+#define LED_CH_1 0x02\r
+#define LED_CH_2 0x04\r
+#define LED_CH_3 0x08\r
+#define LED_CH_4 0x10\r
+#define LED_CH_5 0x20\r
+\r
+\r
+#define PD_CH_0 0x01\r
+#define PD_CH_1 0x02\r
+#define PD_CH_2 0x04\r
+#define PD_CH_3 0x08\r
+\r
+#ifdef PAH8311_1LED_TYPE\r
+\r
+///////////////////////////\r
+//------------1LED---------\r
+//          PD_1\r
+//          PD_2\r
+//  LED_GREEN_1 LED_IR\r
+//  LED_R       LED_GREEN_2\r
+//          PD_3\r
+//          PD_4\r
+///////////////////////////////\r
+\r
+\r
+//------------1LED---------\r
+#define LED_GREEN_1 LED_CH_2\r
+#define LED_GREEN_2 LED_CH_3\r
+#define LED_IR      LED_CH_0\r
+#define LED_R       LED_CH_1\r
+\r
+#define PD_1  PD_CH_2\r
+#define PD_2  PD_CH_3\r
+#define PD_3  PD_CH_0\r
+#define PD_4  PD_CH_1\r
+\r
+#endif\r
+\r
+\r
+#ifdef PAH8311_2LED_TYPE\r
+//------------2LED---------\r
+//    PD_1            PD_2\r
+//  LED_GREEN_1    LED_IR1\r
+//  LED_R1          LED_GREEN_1\r
+//  LED_GREEN_2    LED_IR2\r
+//  LED_R2          LED_GREEN_2\r
+//    PD_3           PD_4\r
+///////////////////////////////\r
+\r
+\r
+//------------2LED---------\r
+#define LED_GREEN_1 LED_CH_2\r
+#define LED_GREEN_2 LED_CH_5\r
+#define LED_IR1     LED_CH_0\r
+#define LED_R1      LED_CH_1\r
+#define LED_IR2     LED_CH_3\r
+#define LED_R2      LED_CH_4\r
+\r
+#define PD_1  PD_CH_3\r
+#define PD_2  PD_CH_0\r
+#define PD_3  PD_CH_2\r
+#define PD_4  PD_CH_1\r
+\r
+\r
+#endif\r
+\r
diff --git a/code/sdk/zhihui/drivers/ppg/pah831x/pah_sensor/pah831x_define.h b/code/sdk/zhihui/drivers/ppg/pah831x/pah_sensor/pah831x_define.h
new file mode 100644 (file)
index 0000000..5a27361
--- /dev/null
@@ -0,0 +1,1480 @@
+#pragma once\r
+/**\r
+ * Copyright (c) 2022 PixArt Imaging Inc.\r
+ * All Rights Reserved.\r
+ * Confidential and Proprietary - PixArt Imaging Inc.\r
+ **/\r
+\r
+//============================================================================\r
+// Definition\r
+//============================================================================\r
+#define PAH831X_DEFAULT_I2C_SLAVE_ADDR (0x40)\r
+\r
+#define PAH831X_MAX_PPG_CH_NUM      (12)\r
+#define PAH831X_MAX_ECG_CH_NUM      (1)\r
+#define PAH831X_MAX_PPG_ECG_CH_NUM  (PAH831X_MAX_PPG_CH_NUM + PAH831X_MAX_ECG_CH_NUM)\r
+\r
+#define PAH831X_FIFO_SIZE       (3120) // Acutally 3600. 3120 can be divided with no remainder\r
+#define PAH831X_DATA_SIZE       (5)\r
+#define PAH831X_MAX_DATA_COUNT  (PAH831X_FIFO_SIZE / PAH831X_DATA_SIZE)\r
+\r
+#define PAH831X_PPG_MAX_WATERMARK       (PAH831X_MAX_DATA_COUNT / PAH831X_MAX_PPG_CH_NUM)\r
+#define PAH831X_ECG_MAX_WATERMARK       (PAH831X_MAX_DATA_COUNT / PAH831X_MAX_ECG_CH_NUM)\r
+#define PAH831X_PPG_ECG_MAX_WATERMARK   (PAH831X_MAX_DATA_COUNT / PAH831X_MAX_PPG_ECG_CH_NUM)\r
+\r
+//============================================================================\r
+// Register address\r
+//============================================================================\r
+// Bank switch\r
+#define PAH831X_SWITCH_BANK__ADDR                       (0x7F)\r
+\r
+// Bank 0\r
+#define PAH831X_B0__PART_ID__ADDR                       (0x00)\r
+#define PAH831X_B0__VERSION_ID__ADDR                    (0x02)\r
+#define PAH831X_B0__REPORT_PERIOD__ADDR                 (0x03)\r
+#define PAH831X_B0__REPORT_PERIOD_1__ADDR               PAH831X_B0__REPORT_PERIOD__ADDR\r
+#define PAH831X_B0__REPORT_PERIOD_2__ADDR               (0x04)\r
+#define PAH831X_B0__REPORT_PERIOD_3__ADDR               (0x05)\r
+#define PAH831X_B0__REPORT_HIGH_SPEED_ENH__ADDR         (0x06)\r
+#define PAH831X_B0__REPORT_ENH__ADDR                    (0x07)\r
+#define PAH831X_B0__FRAME_PERIOD_A__ADDR                (0x08)\r
+#define PAH831X_B0__FRAME_PERIOD_A_1__ADDR              PAH831X_B0__FRAME_PERIOD_A__ADDR\r
+#define PAH831X_B0__FRAME_PERIOD_A_2__ADDR              (0x09)\r
+#define PAH831X_B0__FRAME_PERIOD_B__ADDR                (0x0A)\r
+#define PAH831X_B0__FRAME_PERIOD_B_1__ADDR              PAH831X_B0__FRAME_PERIOD_B__ADDR\r
+#define PAH831X_B0__FRAME_PERIOD_B_2__ADDR              (0x0B)\r
+#define PAH831X_B0__FRAME_PERIOD_C__ADDR                (0x0C)\r
+#define PAH831X_B0__FRAME_PERIOD_C_1__ADDR              PAH831X_B0__FRAME_PERIOD_C__ADDR\r
+#define PAH831X_B0__FRAME_PERIOD_C_2__ADDR              (0x0D)\r
+#define PAH831X_B0__FRAME_PERIOD_D__ADDR                (0x0E)\r
+#define PAH831X_B0__FRAME_PERIOD_D_1__ADDR              PAH831X_B0__FRAME_PERIOD_D__ADDR\r
+#define PAH831X_B0__FRAME_PERIOD_D_2__ADDR              (0x0F)\r
+#define PAH831X_B0__FRAME_PERIOD_T__ADDR                (0x10)\r
+#define PAH831X_B0__FRAME_PERIOD_T_1__ADDR              PAH831X_B0__FRAME_PERIOD_T__ADDR\r
+#define PAH831X_B0__FRAME_PERIOD_T_2__ADDR              (0x11)\r
+#define PAH831X_B0__FRAME_NUM_A__ADDR                   (0x12)\r
+#define PAH831X_B0__FRAME_NUM_B__ADDR                   (0x13)\r
+#define PAH831X_B0__FRAME_NUM_C__ADDR                   (0x14)\r
+#define PAH831X_B0__FRAME_NUM_D__ADDR                   (0x15)\r
+#define PAH831X_B0__FRAME_NUM_T__ADDR                   (0x16)\r
+#define PAH831X_B0__ON_OFF_MODE_ENH__ADDR               (0x17)\r
+#define PAH831X_B0__OFF_ON_OFF_MODE_ENH__ADDR           (0x18)\r
+#define PAH831X_B0__AVG_MODE__ADDR                      (0x19)\r
+#define PAH831X_B0__CH_ENH_1__ADDR                      (0x1B)\r
+#define PAH831X_B0__REPORT_DIVIDER_A__ADDR              (0x1C)\r
+#define PAH831X_B0__REPORT_DIVIDER_A_1__ADDR            PAH831X_B0__REPORT_DIVIDER_A__ADDR\r
+#define PAH831X_B0__REPORT_DIVIDER_A_2__ADDR            (0x1D)\r
+#define PAH831X_B0__REPORT_DIVIDER_B__ADDR              (0x1E)\r
+#define PAH831X_B0__REPORT_DIVIDER_B_1__ADDR            PAH831X_B0__REPORT_DIVIDER_B__ADDR\r
+#define PAH831X_B0__REPORT_DIVIDER_B_2__ADDR            (0x1F)\r
+#define PAH831X_B0__REPORT_DIVIDER_C__ADDR              (0x20)\r
+#define PAH831X_B0__REPORT_DIVIDER_C_1__ADDR            PAH831X_B0__REPORT_DIVIDER_C__ADDR\r
+#define PAH831X_B0__REPORT_DIVIDER_C_2__ADDR            (0x21)\r
+#define PAH831X_B0__REPORT_DIVIDER_D__ADDR              (0x22)\r
+#define PAH831X_B0__REPORT_DIVIDER_D_1__ADDR            PAH831X_B0__REPORT_DIVIDER_D__ADDR\r
+#define PAH831X_B0__REPORT_DIVIDER_D_2__ADDR            (0x23)\r
+#define PAH831X_B0__REPORT_DIVIDER_T__ADDR              (0x24)\r
+#define PAH831X_B0__REPORT_DIVIDER_T_1__ADDR            PAH831X_B0__REPORT_DIVIDER_T__ADDR\r
+#define PAH831X_B0__REPORT_DIVIDER_T_2__ADDR            (0x25)\r
+#define PAH831X_B0__FRAME_NUM_ECG__ADDR                 (0x27)\r
+#define PAH831X_B0__FRAME_NUM_ECG_1__ADDR               PAH831X_B0__FRAME_NUM_ECG__ADDR\r
+#define PAH831X_B0__FRAME_NUM_ECG_2__ADDR               (0x28)\r
+#define PAH831X_B0__REPORT_DIVIDER_ECG__ADDR            (0x29)\r
+#define PAH831X_B0__REPORT_DIVIDER_ECG_1__ADDR          PAH831X_B0__REPORT_DIVIDER_ECG__ADDR\r
+#define PAH831X_B0__REPORT_DIVIDER_ECG_2__ADDR          (0x2A)\r
+#define PAH831X_B0__REPORT_DIVIDER_LOD__ADDR            (0x2B)\r
+#define PAH831X_B0__REPORT_DIVIDER_LOD_1__ADDR          PAH831X_B0__REPORT_DIVIDER_LOD__ADDR\r
+#define PAH831X_B0__REPORT_DIVIDER_LOD_2__ADDR          (0x2C)\r
+#define PAH831X_B0__SYNC_ENH__ADDR                      (0x2D)\r
+#define PAH831X_B0__LPF__ADDR                           (0x2E)\r
+#define PAH831X_B0__INT_FLAG_LOD__ADDR                  (0x2F)\r
+#define PAH831X_B0__INT_FLAG__ADDR                      (0x30)\r
+#define PAH831X_B0__INT_FLAG_INV__ADDR                  (0x31)\r
+#define PAH831X_B0__INT_1_EN__ADDR                      (0x32)\r
+#define PAH831X_B0__FIFO_DATA_COUNT__ADDR               (0x33)\r
+#define PAH831X_B0__FIFO_DATA_COUNT_L__ADDR             PAH831X_B0__FIFO_DATA_COUNT__ADDR\r
+#define PAH831X_B0__FIFO_DATA_COUNT_H__ADDR             (0x34)\r
+#define PAH831X_B0__FIFO_SIZE__ADDR                     (0x35)\r
+#define PAH831X_B0__FIFO_SIZE_L__ADDR                   PAH831X_B0__FIFO_SIZE__ADDR\r
+#define PAH831X_B0__FIFO_SIZE_H__ADDR                   (0x36)\r
+#define PAH831X_B0__FIFO_ON_OFF_ENH__ADDR               (0x37)\r
+#define PAH831X_B0__TOUCH_VALUE__ADDR                   (0x38)\r
+#define PAH831X_B0__CHECKSUM__ADDR                      (0x3A)\r
+#define PAH831X_B0__WR_PTR__ADDR                        (0x3B)\r
+#define PAH831X_B0__WR_PTR_1__ADDR                      PAH831X_B0__WR_PTR__ADDR\r
+#define PAH831X_B0__WR_PTR_2__ADDR                      (0x3C)\r
+#define PAH831X_B0__RD_PTR__ADDR                        (0x3D)\r
+#define PAH831X_B0__RD_PTR_1__ADDR                      PAH831X_B0__RD_PTR__ADDR\r
+#define PAH831X_B0__RD_PTR_2__ADDR                      (0x3E)\r
+#define PAH831X_B0__FIFO_CLEAR__ADDR                    (0x41)\r
+#define PAH831X_B0__BACK_TRACKING_COUNT__ADDR           (0x42)\r
+#define PAH831X_B0__BACK_TRACKING_COUNT_1__ADDR         PAH831X_B0__BACK_TRACKING_COUNT__ADDR\r
+#define PAH831X_B0__BACK_TRACKING_COUNT_2__ADDR         (0x43)\r
+#define PAH831X_B0__FIFO_DATA_COUNT_UNLOCK__ADDR        (0x44)\r
+#define PAH831X_B0__FIFO_DATA_COUNT_UNLOCK_1__ADDR      PAH831X_B0__FIFO_DATA_COUNT_UNLOCK__ADDR\r
+#define PAH831X_B0__FIFO_DATA_COUNT_UNLOCK_2__ADDR      (0x45)\r
+#define PAH831X_B0__LPF_DC_OFFSET__ADDR                 (0x46)\r
+#define PAH831X_B0__LPF_DC_OFFSET_1__ADDR               PAH831X_B0__LPF_DC_OFFSET__ADDR\r
+#define PAH831X_B0__LPF_DC_OFFSET_2__ADDR               (0x47)\r
+#define PAH831X_B0__LPF_DC_OFFSET_3__ADDR               (0x48)\r
+#define PAH831X_B0__TOUCH_ENH__ADDR                     (0x49)\r
+#define PAH831X_B0__TOUCH_DETECTION_TH_HI__ADDR         (0x4A)\r
+#define PAH831X_B0__TOUCH_DETECTION_TH_HI_1__ADDR       PAH831X_B0__TOUCH_DETECTION_TH_HI__ADDR\r
+#define PAH831X_B0__TOUCH_DETECTION_TH_HI_2__ADDR       (0x4B)\r
+#define PAH831X_B0__TOUCH_DETECTION_TH_LO__ADDR         (0x4C)\r
+#define PAH831X_B0__TOUCH_DETECTION_TH_LO_1__ADDR       PAH831X_B0__TOUCH_DETECTION_TH_LO__ADDR\r
+#define PAH831X_B0__TOUCH_DETECTION_TH_LO_2__ADDR       (0x4D)\r
+#define PAH831X_B0__TOUCH_DETECTION_COUTH_TH__ADDR      (0x4E)\r
+#define PAH831X_B0__NO_TOUCH_DETECTION_COUTH_TH__ADDR   (0x4F)\r
+#define PAH831X_B0__PPG_A__ADDR                         (0x50)\r
+#define PAH831X_B0__PPG_B__ADDR                         (0x51)\r
+#define PAH831X_B0__PPG_C__ADDR                         (0x52)\r
+#define PAH831X_B0__PPG_D__ADDR                         (0x53)\r
+#define PAH831X_B0__INT_1_MASK_ENL__ADDR                (0x54)\r
+#define PAH831X_B0__INT_2_MASK_ENL__ADDR                (0x55)\r
+#define PAH831X_B0__DECIMATION_NUM__ADDR                (0x56)\r
+#define PAH831X_B0__ECG_RAWDATA__ADDR                   (0x57)\r
+#define PAH831X_B0__ECG_RAWDATA_1__ADDR                 PAH831X_B0__ECG_RAWDATA__ADDR\r
+#define PAH831X_B0__ECG_RAWDATA_2__ADDR                 (0x58)\r
+#define PAH831X_B0__ECG_RAWDATA_3__ADDR                 (0x59)\r
+#define PAH831X_B0__LOD_DETECTION_COUNT_TH__ADDR        (0x5A)\r
+#define PAH831X_B0__NO_LOD_DETECTION_COUNT_TH__ADDR     (0x5B)\r
+#define PAH831X_B0__LOD_INT_2_EN__ADDR                  (0x5C)\r
+#define PAH831X_B0__PPG_ADC_OFFSET__ADDR                (0x5D)\r
+#define PAH831X_B0__PPG_ADC_OFFSET_1__ADDR              PAH831X_B0__PPG_ADC_OFFSET__ADDR\r
+#define PAH831X_B0__PPG_ADC_OFFSET_2__ADDR              (0x5E)\r
+#define PAH831X_B0__ECG_ADC_OFFSET__ADDR                (0x5F)\r
+#define PAH831X_B0__ECG_ADC_OFFSET_1__ADDR              PAH831X_B0__ECG_ADC_OFFSET__ADDR\r
+#define PAH831X_B0__ECG_ADC_OFFSET_2__ADDR              (0x60)\r
+#define PAH831X_B0__FRAME_PERIOD_E__ADDR                (0x64)\r
+#define PAH831X_B0__FRAME_PERIOD_E_1__ADDR              PAH831X_B0__FRAME_PERIOD_E__ADDR\r
+#define PAH831X_B0__FRAME_PERIOD_E_2__ADDR              (0x65)\r
+#define PAH831X_B0__FRAME_PERIOD_F__ADDR                (0x66)\r
+#define PAH831X_B0__FRAME_PERIOD_F_1__ADDR              PAH831X_B0__FRAME_PERIOD_F__ADDR\r
+#define PAH831X_B0__FRAME_PERIOD_F_2__ADDR              (0x67)\r
+#define PAH831X_B0__CH_ENH_2__ADDR                      (0x68)\r
+#define PAH831X_B0__REPORT_DIVIDER_E__ADDR              (0x69)\r
+#define PAH831X_B0__REPORT_DIVIDER_E_1__ADDR            PAH831X_B0__REPORT_DIVIDER_E__ADDR\r
+#define PAH831X_B0__REPORT_DIVIDER_E_2__ADDR            (0x6A)\r
+#define PAH831X_B0__REPORT_DIVIDER_F__ADDR              (0x6B)\r
+#define PAH831X_B0__REPORT_DIVIDER_F_1__ADDR            PAH831X_B0__REPORT_DIVIDER_F__ADDR\r
+#define PAH831X_B0__REPORT_DIVIDER_F_2__ADDR            (0x6C)\r
+#define PAH831X_B0__FRAME_NUM_E__ADDR                   (0x6D)\r
+#define PAH831X_B0__FRAME_NUM_F__ADDR                   (0x6E)\r
+#define PAH831X_B0__PPG_E__ADDR                         (0x70)\r
+#define PAH831X_B0__PPG_F__ADDR                         (0x71)\r
+#define PAH831X_B0__ECG_FIFO_WRITE_MASK__ADDR           PAH831X_B0__PPG_F__ADDR\r
+#define PAH831X_B0__FRAME_REPEAT_A__ADDR                (0x72)\r
+#define PAH831X_B0__FRAME_REPEAT_B__ADDR                (0x73)\r
+#define PAH831X_B0__FRAME_REPEAT_C__ADDR                (0x74)\r
+#define PAH831X_B0__FRAME_REPEAT_D__ADDR                (0x75)\r
+#define PAH831X_B0__FRAME_REPEAT_E__ADDR                (0x76)\r
+#define PAH831X_B0__FRAME_REPEAT_F__ADDR                (0x77)\r
+#define PAH831X_B0__FRAME_REPEAT_T__ADDR                (0x78)\r
+#define PAH831X_B0__READ_FIFO_ENH__ADDR                 (0x7A)\r
+#define PAH831X_B0__READ_FIFO__ADDR                     (0x7B)\r
+#define PAH831X_B0__UPDATE_FLAG__ADDR                   (0x7E)\r
+\r
+// Bank 1\r
+#define PAH831X_B1__ECG_LOD_GATE_INACHOP_ENH__ADDR      (0x06)\r
+#define PAH831X_B1__ECG_POLAR_FLIP_ENH__ADDR            PAH831X_B1__ECG_LOD_GATE_INACHOP_ENH__ADDR\r
+#define PAH831X_B1__PPG_IP_STL__ADDR                    (0x1A)\r
+#define PAH831X_B1__ECG_FE_INA_GAIN__ADDR               (0x26)\r
+\r
+// Bank 2\r
+#define PAH831X_B2__PPG1_ADC_DEBUG_MODE__ADDR           (0x0E)\r
+#define PAH831X_B2__PPG1_ADC_DEBUG_PATTERN_ON__ADDR     (0x0F)\r
+#define PAH831X_B2__PPG1_ADC_DEBUG_PATTERN_ON_1__ADDR   PAH831X_B2__PPG1_ADC_DEBUG_PATTERN_ON__ADDR\r
+#define PAH831X_B2__PPG1_ADC_DEBUG_PATTERN_ON_2__ADDR   (0x10)\r
+#define PAH831X_B2__PPG1_ADC_DEBUG_PATTERN_OFF__ADDR    (0x11)\r
+#define PAH831X_B2__PPG1_ADC_DEBUG_PATTERN_OFF_1__ADDR  PAH831X_B2__PPG1_ADC_DEBUG_PATTERN_OFF__ADDR\r
+#define PAH831X_B2__PPG1_ADC_DEBUG_PATTERN_OFF_2__ADDR  (0x12)\r
+#define PAH831X_B2__PPG2_ADC_DEBUG_MODE__ADDR           (0x13)\r
+#define PAH831X_B2__PPG2_ADC_DEBUG_PATTERN_ON__ADDR     (0x14)\r
+#define PAH831X_B2__PPG2_ADC_DEBUG_PATTERN_ON_1__ADDR   PAH831X_B2__PPG2_ADC_DEBUG_PATTERN_ON__ADDR\r
+#define PAH831X_B2__PPG2_ADC_DEBUG_PATTERN_ON_2__ADDR   (0x15)\r
+#define PAH831X_B2__PPG2_ADC_DEBUG_PATTERN_OFF__ADDR    (0x16)\r
+#define PAH831X_B2__PPG2_ADC_DEBUG_PATTERN_OFF_1__ADDR  PAH831X_B2__PPG2_ADC_DEBUG_PATTERN_OFF__ADDR\r
+#define PAH831X_B2__PPG2_ADC_DEBUG_PATTERN_OFF_2__ADDR  (0x17)\r
+#define PAH831X_B2__ECG_ADC_DEBUG_MODE__ADDR            (0x18)\r
+#define PAH831X_B2__ECG_ADC_DEBUG_PATTERN_ON__ADDR      (0x19)\r
+#define PAH831X_B2__ECG_ADC_DEBUG_PATTERN_ON_1__ADDR    PAH831X_B2__ECG_ADC_DEBUG_PATTERN_ON__ADDR\r
+#define PAH831X_B2__ECG_ADC_DEBUG_PATTERN_ON_2__ADDR    (0x1A)\r
+#define PAH831X_B2__ECG_ADC_DEBUG_PATTERN_OFF__ADDR     (0x1B)\r
+#define PAH831X_B2__ECG_ADC_DEBUG_PATTERN_OFF_1__ADDR   PAH831X_B2__ECG_ADC_DEBUG_PATTERN_OFF__ADDR\r
+#define PAH831X_B2__ECG_ADC_DEBUG_PATTERN_OFF_2__ADDR   (0x1C)\r
+#define PAH831X_B2__PPG1_E_ADCDATA_ON__ADDR             (0x32)\r
+#define PAH831X_B2__PPG1_E_ADCDATA_OFF__ADDR            (0x34)\r
+#define PAH831X_B2__PPG2_E_ADCDATA_ON__ADDR             (0x36)\r
+#define PAH831X_B2__PPG2_E_ADCDATA_OFF__ADDR            (0x38)\r
+#define PAH831X_B2__PPG1_F_ADCDATA_ON__ADDR             (0x3A)\r
+#define PAH831X_B2__PPG1_F_ADCDATA_OFF__ADDR            (0x3C)\r
+#define PAH831X_B2__PPG2_F_ADCDATA_ON__ADDR             (0x3E)\r
+#define PAH831X_B2__PPG2_F_ADCDATA_OFF__ADDR            (0x40)\r
+#define PAH831X_B2__GPIO_0_SEL__ADDR                    (0x4A)\r
+#define PAH831X_B2__GPIO_1_SEL__ADDR                    (0x4B)\r
+#define PAH831X_B2__GPIO_2_SEL__ADDR                    (0x4C)\r
+#define PAH831X_B2__GPIO_3_SEL__ADDR                    (0x4D)\r
+#define PAH831X_B2__GPIO_4_SEL__ADDR                    (0x4E)\r
+#define PAH831X_B2__GPIO_5_SEL__ADDR                    (0x4F)\r
+#define PAH831X_B2__PPG1_A_ADCDATA_ON__ADDR             (0x50)\r
+#define PAH831X_B2__PPG1_A_ADCDATA_OFF__ADDR            (0x52)\r
+#define PAH831X_B2__PPG2_A_ADCDATA_ON__ADDR             (0x54)\r
+#define PAH831X_B2__PPG2_A_ADCDATA_OFF__ADDR            (0x56)\r
+#define PAH831X_B2__PPG1_B_ADCDATA_ON__ADDR             (0x58)\r
+#define PAH831X_B2__PPG1_B_ADCDATA_OFF__ADDR            (0x5A)\r
+#define PAH831X_B2__PPG2_B_ADCDATA_ON__ADDR             (0x5C)\r
+#define PAH831X_B2__PPG2_B_ADCDATA_OFF__ADDR            (0x5E)\r
+#define PAH831X_B2__PPG1_C_ADCDATA_ON__ADDR             (0x60)\r
+#define PAH831X_B2__PPG1_C_ADCDATA_OFF__ADDR            (0x62)\r
+#define PAH831X_B2__PPG2_C_ADCDATA_ON__ADDR             (0x64)\r
+#define PAH831X_B2__PPG2_C_ADCDATA_OFF__ADDR            (0x66)\r
+#define PAH831X_B2__PPG1_D_ADCDATA_ON__ADDR             (0x68)\r
+#define PAH831X_B2__PPG1_D_ADCDATA_OFF__ADDR            (0x6A)\r
+#define PAH831X_B2__PPG2_D_ADCDATA_ON__ADDR             (0x6C)\r
+#define PAH831X_B2__PPG2_D_ADCDATA_OFF__ADDR            (0x6E)\r
+\r
+// Bank 3\r
+#define PAH831X_B3__POWERDN__ADDR                       (0x01)\r
+#define PAH831X_B3__PWRSV_SEL__ADDR                     (0x0B)\r
+#define PAH831X_B3__CLK__ADDR                           (0x50)\r
+#define PAH831X_B3__GPIO__ADDR                          (0x52)\r
+#define PAH831X_B3__EXT_CLK__ADDR                       (0x54)\r
+#define PAH831X_B3__I2C__ADDR                           (0x56)\r
+#define PAH831X_B3__GPIO_0__ADDR                        (0x58)\r
+#define PAH831X_B3__GPIO_1__ADDR                        (0x59)\r
+#define PAH831X_B3__GPIO_2__ADDR                        (0x5A)\r
+#define PAH831X_B3__GPIO_3__ADDR                        (0x5B)\r
+#define PAH831X_B3__GPIO_4__ADDR                        (0x5C)\r
+#define PAH831X_B3__GPIO_5__ADDR                        (0x5D)\r
+#define PAH831X_B3__RESET__ADDR                         (0x70)\r
+\r
+// Bank 4\r
+#define PAH831X_B4__PPG_CH_A_LEDDAC_1__ADDR             (0x00)\r
+#define PAH831X_B4__PPG_CH_A_LEDDAC_1_CH_SEL__ADDR      (0x01)\r
+#define PAH831X_B4__PPG_CH_A_LEDDAC_1_CODE__ADDR        (0x02)\r
+#define PAH831X_B4__PPG_CH_B_LEDDAC_1__ADDR             (0x03)\r
+#define PAH831X_B4__PPG_CH_B_LEDDAC_1_CH_SEL__ADDR      (0x04)\r
+#define PAH831X_B4__PPG_CH_B_LEDDAC_1_CODE__ADDR        (0x05)\r
+#define PAH831X_B4__PPG_CH_C_LEDDAC_1__ADDR             (0x06)\r
+#define PAH831X_B4__PPG_CH_C_LEDDAC_1_CH_SEL__ADDR      (0x07)\r
+#define PAH831X_B4__PPG_CH_C_LEDDAC_1_CODE__ADDR        (0x08)\r
+#define PAH831X_B4__PPG_CH_D_LEDDAC_1__ADDR             (0x09)\r
+#define PAH831X_B4__PPG_CH_D_LEDDAC_1_CH_SEL__ADDR      (0x0A)\r
+#define PAH831X_B4__PPG_CH_D_LEDDAC_1_CODE__ADDR        (0x0B)\r
+#define PAH831X_B4__PPG_CH_E_LEDDAC_1__ADDR             (0x0C)\r
+#define PAH831X_B4__PPG_CH_E_LEDDAC_1_CH_SEL__ADDR      (0x0D)\r
+#define PAH831X_B4__PPG_CH_E_LEDDAC_1_CODE__ADDR        (0x0E)\r
+#define PAH831X_B4__PPG_CH_F_LEDDAC_1__ADDR             (0x0F)\r
+#define PAH831X_B4__PPG_CH_F_LEDDAC_1_CH_SEL__ADDR      (0x10)\r
+#define PAH831X_B4__PPG_CH_F_LEDDAC_1_CODE__ADDR        (0x11)\r
+#define PAH831X_B4__PPG_CH_T_LEDDAC_1__ADDR             (0x12)\r
+#define PAH831X_B4__PPG_CH_T_LEDDAC_1_CH_SEL__ADDR      (0x13)\r
+#define PAH831X_B4__PPG_CH_T_LEDDAC_1_CODE__ADDR        (0x14)\r
+#define PAH831X_B4__PPG_LEDDAC_STEP__ADDR               (0x15)\r
+#define PAH831X_B4__PPG_CH_A_LEDDAC_2__ADDR             (0x16)\r
+#define PAH831X_B4__PPG_CH_A_LEDDAC_2_CH_SEL__ADDR      (0x17)\r
+#define PAH831X_B4__PPG_CH_A_LEDDAC_2_CODE__ADDR        (0x18)\r
+#define PAH831X_B4__PPG_CH_B_LEDDAC_2__ADDR             (0x19)\r
+#define PAH831X_B4__PPG_CH_B_LEDDAC_2_CH_SEL__ADDR      (0x1A)\r
+#define PAH831X_B4__PPG_CH_B_LEDDAC_2_CODE__ADDR        (0x1B)\r
+#define PAH831X_B4__PPG_CH_C_LEDDAC_2__ADDR             (0x1C)\r
+#define PAH831X_B4__PPG_CH_C_LEDDAC_2_CH_SEL__ADDR      (0x1D)\r
+#define PAH831X_B4__PPG_CH_C_LEDDAC_2_CODE__ADDR        (0x1E)\r
+#define PAH831X_B4__PPG_CH_D_LEDDAC_2__ADDR             (0x1F)\r
+#define PAH831X_B4__PPG_CH_D_LEDDAC_2_CH_SEL__ADDR      (0x20)\r
+#define PAH831X_B4__PPG_CH_D_LEDDAC_2_CODE__ADDR        (0x21)\r
+#define PAH831X_B4__PPG_CH_E_LEDDAC_2__ADDR             (0x22)\r
+#define PAH831X_B4__PPG_CH_E_LEDDAC_2_CH_SEL__ADDR      (0x23)\r
+#define PAH831X_B4__PPG_CH_E_LEDDAC_2_CODE__ADDR        (0x24)\r
+#define PAH831X_B4__PPG_CH_F_LEDDAC_2__ADDR             (0x25)\r
+#define PAH831X_B4__PPG_CH_F_LEDDAC_2_CH_SEL__ADDR      (0x26)\r
+#define PAH831X_B4__PPG_CH_F_LEDDAC_2_CODE__ADDR        (0x27)\r
+#define PAH831X_B4__PPG_CH_T_LEDDAC_2__ADDR             (0x28)\r
+#define PAH831X_B4__PPG_CH_T_LEDDAC_2_CH_SEL__ADDR      (0x29)\r
+#define PAH831X_B4__PPG_CH_T_LEDDAC_2_CODE__ADDR        (0x2A)\r
+#define PAH831X_B4__PPG_LEDDAC_OFF__ADDR                (0x2B)\r
+#define PAH831X_B4__PPG_LEDDAC_MANUAL__ADDR             (0x2C)\r
+#define PAH831X_B4__CH_A_LED_DAC_1_MIN__ADDR            (0x2D)\r
+#define PAH831X_B4__CH_A_LED_DAC_1_MAX__ADDR            (0x2E)\r
+#define PAH831X_B4__CH_B_LED_DAC_1_MIN__ADDR            (0x2F)\r
+#define PAH831X_B4__CH_B_LED_DAC_1_MAX__ADDR            (0x30)\r
+#define PAH831X_B4__CH_C_LED_DAC_1_MIN__ADDR            (0x31)\r
+#define PAH831X_B4__CH_C_LED_DAC_1_MAX__ADDR            (0x32)\r
+#define PAH831X_B4__CH_D_LED_DAC_1_MIN__ADDR            (0x33)\r
+#define PAH831X_B4__CH_D_LED_DAC_1_MAX__ADDR            (0x34)\r
+#define PAH831X_B4__CH_E_LED_DAC_1_MIN__ADDR            (0x35)\r
+#define PAH831X_B4__CH_E_LED_DAC_1_MAX__ADDR            (0x36)\r
+#define PAH831X_B4__CH_F_LED_DAC_1_MIN__ADDR            (0x37)\r
+#define PAH831X_B4__CH_F_LED_DAC_1_MAX__ADDR            (0x38)\r
+#define PAH831X_B4__CH_A_LED_DAC_2_MIN__ADDR            (0x39)\r
+#define PAH831X_B4__CH_A_LED_DAC_2_MAX__ADDR            (0x3A)\r
+#define PAH831X_B4__CH_B_LED_DAC_2_MIN__ADDR            (0x3B)\r
+#define PAH831X_B4__CH_B_LED_DAC_2_MAX__ADDR            (0x3C)\r
+#define PAH831X_B4__CH_C_LED_DAC_2_MIN__ADDR            (0x3D)\r
+#define PAH831X_B4__CH_C_LED_DAC_2_MAX__ADDR            (0x3E)\r
+#define PAH831X_B4__CH_D_LED_DAC_2_MIN__ADDR            (0x3F)\r
+#define PAH831X_B4__CH_D_LED_DAC_2_MAX__ADDR            (0x40)\r
+#define PAH831X_B4__CH_E_LED_DAC_2_MIN__ADDR            (0x41)\r
+#define PAH831X_B4__CH_E_LED_DAC_2_MAX__ADDR            (0x42)\r
+#define PAH831X_B4__CH_F_LED_DAC_2_MIN__ADDR            (0x43)\r
+#define PAH831X_B4__CH_F_LED_DAC_2_MAX__ADDR            (0x44)\r
+\r
+//============================================================================\r
+// Register value\r
+//============================================================================\r
+#define PAH831X_B0__INT_FLAGS_SIZE    (PAH831X_B0__INT_FLAG_LOD__SIZE + PAH831X_B0__INT_FLAG__SIZE)\r
+\r
+// PAH831X_SWITCH_BANK__ADDR (0x7F)\r
+#define PAH831X_SWITCH_BANK__0  (0x00)\r
+#define PAH831X_SWITCH_BANK__1  (0x01)\r
+#define PAH831X_SWITCH_BANK__2  (0x02)\r
+#define PAH831X_SWITCH_BANK__3  (0x03)\r
+#define PAH831X_SWITCH_BANK__4  (0x04)\r
+\r
+// PAH831X_B0__PART_ID__ADDR (0x00), R\r
+#define PAH831X_B0__PART_ID__SIZE   (2)\r
+\r
+// PAH831X_B0__VERSION_ID__ADDR (0x02), R\r
+#define PAH831X_B0__VERSION_ID__POS         (0)\r
+#define PAH831X_B0__VERSION_ID__LEN         (4)\r
+#define PAH831X_B0__VERSION_ID__MSK         (0x0F)\r
+#define PAH831X_B0__VERSION_ID__ECO__POS    (4)\r
+#define PAH831X_B0__VERSION_ID__ECO__LEN    (4)\r
+#define PAH831X_B0__VERSION_ID__ECO__MSK    (0xF0)\r
+\r
+// PAH831X_B0__REPORT_PERIOD__ADDR (0x03), R/W\r
+#define PAH831X_B0__REPORT_PERIOD__SIZE         (3)\r
+#define PAH831X_B0__REPORT_PERIOD__DEFAULT      (1600)\r
+// PAH831X_B0__REPORT_PERIOD_1__ADDR (0x03), R/W\r
+#define PAH831X_B0__REPORT_PERIOD_1__POS        (0)\r
+#define PAH831X_B0__REPORT_PERIOD_1__LEN        (8)\r
+#define PAH831X_B0__REPORT_PERIOD_1__MSK        (0xFF)\r
+#define PAH831X_B0__REPORT_PERIOD_1__DEFAULT    (0x40)\r
+// PAH831X_B0__REPORT_PERIOD_2__ADDR (0x04), R/W\r
+#define PAH831X_B0__REPORT_PERIOD_2__POS        (0)\r
+#define PAH831X_B0__REPORT_PERIOD_2__LEN        (8)\r
+#define PAH831X_B0__REPORT_PERIOD_2__MSK        (0xFF)\r
+#define PAH831X_B0__REPORT_PERIOD_2__DEFAULT    (0x06)\r
+// PAH831X_B0__REPORT_PERIOD_3__ADDR (0x05), R/W\r
+#define PAH831X_B0__REPORT_PERIOD_3__POS        (0)\r
+#define PAH831X_B0__REPORT_PERIOD_3__LEN        (4)\r
+#define PAH831X_B0__REPORT_PERIOD_3__MSK        (0x0F)\r
+#define PAH831X_B0__REPORT_PERIOD_3__DEFAULT    (0x00)\r
+\r
+// PAH831X_B0__REPORT_HIGH_SPEED_ENH__ADDR (0x06), R/W\r
+#define PAH831X_B0__REPORT_HIGH_SPEED_ENH__POS  (0)\r
+#define PAH831X_B0__REPORT_HIGH_SPEED_ENH__LEN  (1)\r
+#define PAH831X_B0__REPORT_HIGH_SPEED_ENH__MSK  (0x01)\r
+\r
+// PAH831X_B0__REPORT_ENH__ADDR (0x07), R/W\r
+#define PAH831X_B0__REPORT_ENH__VALUE   (0x01)\r
+\r
+// PAH831X_B0__FRAME_PERIOD_A__ADDR (0x08), R/W\r
+#define PAH831X_B0__FRAME_PERIOD_A__SIZE    (2)\r
+// PAH831X_B0__FRAME_PERIOD_A_1__ADDR (0x08), R/W\r
+#define PAH831X_B0__FRAME_PERIOD_A_1__POS   (0)\r
+#define PAH831X_B0__FRAME_PERIOD_A_1__LEN   (8)\r
+#define PAH831X_B0__FRAME_PERIOD_A_1__MSK   (0xFF)\r
+// PAH831X_B0__FRAME_PERIOD_A_2__ADDR (0x09), R/W\r
+#define PAH831X_B0__FRAME_PERIOD_A_2__POS   (0)\r
+#define PAH831X_B0__FRAME_PERIOD_A_2__LEN   (6)\r
+#define PAH831X_B0__FRAME_PERIOD_A_2__MSK   (0x3F)\r
+\r
+// PAH831X_B0__FRAME_PERIOD_B__ADDR (0x0A), R/W\r
+#define PAH831X_B0__FRAME_PERIOD_B__SIZE    (2)\r
+// PAH831X_B0__FRAME_PERIOD_B_1__ADDR (0x0A), R/W\r
+#define PAH831X_B0__FRAME_PERIOD_B_1__POS   (0)\r
+#define PAH831X_B0__FRAME_PERIOD_B_1__LEN   (8)\r
+#define PAH831X_B0__FRAME_PERIOD_B_1__MSK   (0xFF)\r
+// PAH831X_B0__FRAME_PERIOD_B_2__ADDR (0x0B), R/W\r
+#define PAH831X_B0__FRAME_PERIOD_B_2__POS   (0)\r
+#define PAH831X_B0__FRAME_PERIOD_B_2__LEN   (6)\r
+#define PAH831X_B0__FRAME_PERIOD_B_2__MSK   (0x3F)\r
+\r
+// PAH831X_B0__FRAME_PERIOD_C__ADDR (0x0C), R/W\r
+#define PAH831X_B0__FRAME_PERIOD_C__SIZE    (2)\r
+// PAH831X_B0__FRAME_PERIOD_C_1__ADDR (0x0C), R/W\r
+#define PAH831X_B0__FRAME_PERIOD_C_1__POS   (0)\r
+#define PAH831X_B0__FRAME_PERIOD_C_1__LEN   (8)\r
+#define PAH831X_B0__FRAME_PERIOD_C_1__MSK   (0xFF)\r
+// PAH831X_B0__FRAME_PERIOD_C_2__ADDR (0x0D), R/W\r
+#define PAH831X_B0__FRAME_PERIOD_C_2__POS   (0)\r
+#define PAH831X_B0__FRAME_PERIOD_C_2__LEN   (6)\r
+#define PAH831X_B0__FRAME_PERIOD_C_2__MSK   (0x3F)\r
+\r
+// PAH831X_B0__FRAME_PERIOD_D__ADDR (0x0E), R/W\r
+#define PAH831X_B0__FRAME_PERIOD_D__SIZE    (2)\r
+// PAH831X_B0__FRAME_PERIOD_D_1__ADDR (0x0E), R/W\r
+#define PAH831X_B0__FRAME_PERIOD_D_1__POS   (0)\r
+#define PAH831X_B0__FRAME_PERIOD_D_1__LEN   (8)\r
+#define PAH831X_B0__FRAME_PERIOD_D_1__MSK   (0xFF)\r
+// PAH831X_B0__FRAME_PERIOD_D_2__ADDR (0x0F), R/W\r
+#define PAH831X_B0__FRAME_PERIOD_D_2__POS   (0)\r
+#define PAH831X_B0__FRAME_PERIOD_D_2__LEN   (6)\r
+#define PAH831X_B0__FRAME_PERIOD_D_2__MSK   (0x3F)\r
+\r
+// PAH831X_B0__FRAME_PERIOD_T__ADDR (0x10), R/W\r
+#define PAH831X_B0__FRAME_PERIOD_T__SIZE    (2)\r
+// PAH831X_B0__FRAME_PERIOD_T_1__ADDR (0x10), R/W\r
+#define PAH831X_B0__FRAME_PERIOD_T_1__POS   (0)\r
+#define PAH831X_B0__FRAME_PERIOD_T_1__LEN   (8)\r
+#define PAH831X_B0__FRAME_PERIOD_T_1__MSK   (0xFF)\r
+// PAH831X_B0__FRAME_PERIOD_T_2__ADDR (0x11), R/W\r
+#define PAH831X_B0__FRAME_PERIOD_T_2__POS   (0)\r
+#define PAH831X_B0__FRAME_PERIOD_T_2__LEN   (6)\r
+#define PAH831X_B0__FRAME_PERIOD_T_2__MSK   (0x3F)\r
+\r
+// PAH831X_B0__FRAME_NUM_A__ADDR (0x12), R/W\r
+#define PAH831X_B0__FRAME_NUM_A__POS    (0)\r
+#define PAH831X_B0__FRAME_NUM_A__LEN    (7)\r
+#define PAH831X_B0__FRAME_NUM_A__MSK    (0x7F)\r
+\r
+// PAH831X_B0__FRAME_NUM_B__ADDR (0x13), R/W\r
+#define PAH831X_B0__FRAME_NUM_B__POS    (0)\r
+#define PAH831X_B0__FRAME_NUM_B__LEN    (7)\r
+#define PAH831X_B0__FRAME_NUM_B__MSK    (0x7F)\r
+\r
+// PAH831X_B0__FRAME_NUM_C__ADDR (0x14), R/W\r
+#define PAH831X_B0__FRAME_NUM_C__POS    (0)\r
+#define PAH831X_B0__FRAME_NUM_C__LEN    (7)\r
+#define PAH831X_B0__FRAME_NUM_C__MSK    (0x7F)\r
+\r
+// PAH831X_B0__FRAME_NUM_D__ADDR (0x15), R/W\r
+#define PAH831X_B0__FRAME_NUM_D__POS    (0)\r
+#define PAH831X_B0__FRAME_NUM_D__LEN    (7)\r
+#define PAH831X_B0__FRAME_NUM_D__MSK    (0x7F)\r
+\r
+// PAH831X_B0__FRAME_NUM_T__ADDR (0x16), R/W\r
+#define PAH831X_B0__FRAME_NUM_T__POS    (0)\r
+#define PAH831X_B0__FRAME_NUM_T__LEN    (7)\r
+#define PAH831X_B0__FRAME_NUM_T__MSK    (0x7F)\r
+\r
+// PAH831X_B0__ON_OFF_MODE_ENH__ADDR (0x17), R/W\r
+#define PAH831X_B0__ON_OFF_MODE_A_ENH__POS      (0)\r
+#define PAH831X_B0__ON_OFF_MODE_B_ENH__POS      (1)\r
+#define PAH831X_B0__ON_OFF_MODE_C_ENH__POS      (2)\r
+#define PAH831X_B0__ON_OFF_MODE_D_ENH__POS      (3)\r
+#define PAH831X_B0__ON_OFF_MODE_T_ENH__POS      (4)\r
+#define PAH831X_B0__ON_OFF_MODE_E_ENH__POS      (5)\r
+#define PAH831X_B0__ON_OFF_MODE_F_ENH__POS      (6)\r
+\r
+// PAH831X_B0__OFF_ON_OFF_MODE_ENH__ADDR (0x18), R/W\r
+#define PAH831X_B0__OFF_ON_OFF_MODE_A_ENH__POS  (0)\r
+#define PAH831X_B0__OFF_ON_OFF_MODE_B_ENH__POS  (1)\r
+#define PAH831X_B0__OFF_ON_OFF_MODE_C_ENH__POS  (2)\r
+#define PAH831X_B0__OFF_ON_OFF_MODE_D_ENH__POS  (3)\r
+#define PAH831X_B0__OFF_ON_OFF_MODE_T_ENH__POS  (4)\r
+#define PAH831X_B0__OFF_ON_OFF_MODE_E_ENH__POS  (5)\r
+#define PAH831X_B0__OFF_ON_OFF_MODE_F_ENH__POS  (6)\r
+\r
+// PAH831X_B0__AVG_MODE__ADDR (0x19), R/W\r
+#define PAH831X_B0__AVG_MODE__A__POS    (0)\r
+#define PAH831X_B0__AVG_MODE__B__POS    (1)\r
+#define PAH831X_B0__AVG_MODE__C__POS    (2)\r
+#define PAH831X_B0__AVG_MODE__D__POS    (3)\r
+#define PAH831X_B0__AVG_MODE__T__POS    (4)\r
+#define PAH831X_B0__AVG_MODE__E__POS    (5)\r
+#define PAH831X_B0__AVG_MODE__F__POS    (6)\r
+\r
+// PAH831X_B0__CH_ENH_1__ADDR (0x1B), R/W\r
+#define PAH831X_B0__CH_ENH_1__CH_A__POS             (0)\r
+#define PAH831X_B0__CH_ENH_1__CH_B__POS             (1)\r
+#define PAH831X_B0__CH_ENH_1__CH_C__POS             (2)\r
+#define PAH831X_B0__CH_ENH_1__CH_D__POS             (3)\r
+#define PAH831X_B0__CH_ENH_1__CH_T__POS             (4)\r
+#define PAH831X_B0__CH_ENH_1__ECG__POS              (5)\r
+#define PAH831X_B0__CH_ENH_1__LOD__POS              (6)\r
+#define PAH831X_B0__CH_ENH_1__SIN_ADD_FIRST__POS    (7)\r
+\r
+// PAH831X_B0__REPORT_DIVIDER_A__ADDR (0x1C), R/W\r
+#define PAH831X_B0__REPORT_DIVIDER_A__SIZE      (2)\r
+// PAH831X_B0__REPORT_DIVIDER_A_1__ADDR (0x1C), R/W\r
+#define PAH831X_B0__REPORT_DIVIDER_A_1__POS     (0)\r
+#define PAH831X_B0__REPORT_DIVIDER_A_1__LEN     (8)\r
+#define PAH831X_B0__REPORT_DIVIDER_A_1__MSK     (0xFF)\r
+// PAH831X_B0__REPORT_DIVIDER_A_2__ADDR (0x1D), R/W\r
+#define PAH831X_B0__REPORT_DIVIDER_A_2__POS     (0)\r
+#define PAH831X_B0__REPORT_DIVIDER_A_2__LEN     (8)\r
+#define PAH831X_B0__REPORT_DIVIDER_A_2__MSK     (0xFF)\r
+\r
+// PAH831X_B0__REPORT_DIVIDER_B__ADDR (0x1E), R/W\r
+#define PAH831X_B0__REPORT_DIVIDER_B__SIZE      (2)\r
+// PAH831X_B0__REPORT_DIVIDER_B_1__ADDR (0x1E), R/W\r
+#define PAH831X_B0__REPORT_DIVIDER_B_1__POS     (0)\r
+#define PAH831X_B0__REPORT_DIVIDER_B_1__LEN     (8)\r
+#define PAH831X_B0__REPORT_DIVIDER_B_1__MSK     (0xFF)\r
+// PAH831X_B0__REPORT_DIVIDER_B_2__ADDR (0x1F), R/W\r
+#define PAH831X_B0__REPORT_DIVIDER_B_2__POS     (0)\r
+#define PAH831X_B0__REPORT_DIVIDER_B_2__LEN     (8)\r
+#define PAH831X_B0__REPORT_DIVIDER_B_2__MSK     (0xFF)\r
+\r
+// PAH831X_B0__REPORT_DIVIDER_C__ADDR (0x20), R/W\r
+#define PAH831X_B0__REPORT_DIVIDER_C__SIZE      (2)\r
+// PAH831X_B0__REPORT_DIVIDER_C_1__ADDR (0x20), R/W\r
+#define PAH831X_B0__REPORT_DIVIDER_C_1__POS     (0)\r
+#define PAH831X_B0__REPORT_DIVIDER_C_1__LEN     (8)\r
+#define PAH831X_B0__REPORT_DIVIDER_C_1__MSK     (0xFF)\r
+// PAH831X_B0__REPORT_DIVIDER_C_2__ADDR (0x21), R/W\r
+#define PAH831X_B0__REPORT_DIVIDER_C_2__POS     (0)\r
+#define PAH831X_B0__REPORT_DIVIDER_C_2__LEN     (8)\r
+#define PAH831X_B0__REPORT_DIVIDER_C_2__MSK     (0xFF)\r
+\r
+// PAH831X_B0__REPORT_DIVIDER_D__ADDR (0x22), R/W\r
+#define PAH831X_B0__REPORT_DIVIDER_D__SIZE      (2)\r
+// PAH831X_B0__REPORT_DIVIDER_D_1__ADDR (0x22), R/W\r
+#define PAH831X_B0__REPORT_DIVIDER_D_1__POS     (0)\r
+#define PAH831X_B0__REPORT_DIVIDER_D_1__LEN     (8)\r
+#define PAH831X_B0__REPORT_DIVIDER_D_1__MSK     (0xFF)\r
+// PAH831X_B0__REPORT_DIVIDER_D_2__ADDR (0x23), R/W\r
+#define PAH831X_B0__REPORT_DIVIDER_D_2__POS     (0)\r
+#define PAH831X_B0__REPORT_DIVIDER_D_2__LEN     (8)\r
+#define PAH831X_B0__REPORT_DIVIDER_D_2__MSK     (0xFF)\r
+\r
+// PAH831X_B0__REPORT_DIVIDER_T__ADDR (0x24), R/W\r
+#define PAH831X_B0__REPORT_DIVIDER_T__SIZE      (2)\r
+// PAH831X_B0__REPORT_DIVIDER_T_1__ADDR (0x24), R/W\r
+#define PAH831X_B0__REPORT_DIVIDER_T_1__POS     (0)\r
+#define PAH831X_B0__REPORT_DIVIDER_T_1__LEN     (8)\r
+#define PAH831X_B0__REPORT_DIVIDER_T_1__MSK     (0xFF)\r
+// PAH831X_B0__REPORT_DIVIDER_T_2__ADDR (0x25), R/W\r
+#define PAH831X_B0__REPORT_DIVIDER_T_2__POS     (0)\r
+#define PAH831X_B0__REPORT_DIVIDER_T_2__LEN     (8)\r
+#define PAH831X_B0__REPORT_DIVIDER_T_2__MSK     (0xFF)\r
+\r
+// PAH831X_B0__FRAME_NUM_ECG__ADDR (0x27), R/W\r
+#define PAH831X_B0__FRAME_NUM_ECG__SIZE     (2)\r
+// PAH831X_B0__FRAME_NUM_ECG_1__ADDR (0x27), R/W\r
+#define PAH831X_B0__FRAME_NUM_ECG_1__POS    (0)\r
+#define PAH831X_B0__FRAME_NUM_ECG_1__LEN    (8)\r
+#define PAH831X_B0__FRAME_NUM_ECG_1__MSK    (0xFF)\r
+#define PAH831X_B0__FRAME_NUM_ECG_1__DEFAULT    (1)\r
+// PAH831X_B0__FRAME_NUM_ECG_2__ADDR (0x28), R/W\r
+#define PAH831X_B0__FRAME_NUM_ECG_2__POS    (0)\r
+#define PAH831X_B0__FRAME_NUM_ECG_2__LEN    (1)\r
+#define PAH831X_B0__FRAME_NUM_ECG_2__MSK    (0x01)\r
+#define PAH831X_B0__FRAME_NUM_ECG_2__DEFAULT    (0)\r
+\r
+// PAH831X_B0__REPORT_DIVIDER_ECG__ADDR (0x29), R/W\r
+#define PAH831X_B0__REPORT_DIVIDER_ECG__SIZE    (2)\r
+// PAH831X_B0__REPORT_DIVIDER_ECG_1__ADDR (0x29), R/W\r
+#define PAH831X_B0__REPORT_DIVIDER_ECG_1__POS   (0)\r
+#define PAH831X_B0__REPORT_DIVIDER_ECG_1__LEN   (8)\r
+#define PAH831X_B0__REPORT_DIVIDER_ECG_1__MSK   (0xFF)\r
+// PAH831X_B0__REPORT_DIVIDER_ECG_2__ADDR (0x2A), R/W\r
+#define PAH831X_B0__REPORT_DIVIDER_ECG_2__POS   (0)\r
+#define PAH831X_B0__REPORT_DIVIDER_ECG_2__LEN   (8)\r
+#define PAH831X_B0__REPORT_DIVIDER_ECG_2__MSK   (0xFF)\r
+\r
+// PAH831X_B0__REPORT_DIVIDER_LOD__ADDR (0x2B), R/W\r
+#define PAH831X_B0__REPORT_DIVIDER_LOD__SIZE    (2)\r
+// PAH831X_B0__REPORT_DIVIDER_LOD_1__ADDR (0x2B), R/W\r
+#define PAH831X_B0__REPORT_DIVIDER_LOD_1__POS   (0)\r
+#define PAH831X_B0__REPORT_DIVIDER_LOD_1__LEN   (8)\r
+#define PAH831X_B0__REPORT_DIVIDER_LOD_1__MSK   (0xFF)\r
+// PAH831X_B0__REPORT_DIVIDER_LOD_2__ADDR (0x2C), R/W\r
+#define PAH831X_B0__REPORT_DIVIDER_LOD_2__POS   (0)\r
+#define PAH831X_B0__REPORT_DIVIDER_LOD_2__LEN   (8)\r
+#define PAH831X_B0__REPORT_DIVIDER_LOD_2__MSK   (0xFF)\r
+\r
+// PAH831X_B0__SYNC_ENH__ADDR (0x2D), R/W\r
+#define PAH831X_B0__SYNC_ENH__SLAVE_REPORT__POS     (0)\r
+#define PAH831X_B0__SYNC_ENH__MASTER_REPORT__POS    (1)\r
+#define PAH831X_B0__SYNC_ENH__SLAVE_CHANNEL__POS    (4)\r
+#define PAH831X_B0__SYNC_ENH__MASTER_CHANNEL__POS   (5)\r
+\r
+// PAH831X_B0__LPF__ADDR (0x2E), R/W\r
+#define PAH831X_B0__LPF__ENH__POS       (0)\r
+#define PAH831X_B0__LPF__ENH__LEN       (1)\r
+#define PAH831X_B0__LPF__ENH__MSK       (0x01)\r
+#define PAH831X_B0__LPF__SEL__POS       (1)\r
+#define PAH831X_B0__LPF__SEL__LEN       (2)\r
+#define PAH831X_B0__LPF__SEL__MSK       (0x06)\r
+#define PAH831X_B0__LPF__MASK_CNT__POS  (4)\r
+#define PAH831X_B0__LPF__MASK_CNT__LEN  (4)\r
+#define PAH831X_B0__LPF__MASK_CNT__MSK  (0xF0)\r
+\r
+// PAH831X_B0__INT_FLAG_LOD__ADDR (0x2F), R/W\r
+#define PAH831X_B0__INT_FLAG_LOD__SIZE      (1)\r
+#define PAH831X_B0__INT_FLAG_LOD__POS       (0)\r
+#define PAH831X_B0__INT_FLAG_LOD__LEN       (8)\r
+#define PAH831X_B0__INT_FLAG_LOD__MSK       (0xFF)\r
+#define PAH831X_B0__INT_FLAG_LOD__CLEAR     (0x00)\r
+\r
+// PAH831X_B0__INT_FLAG__ADDR (0x30), R/W\r
+#define PAH831X_B0__INT_FLAG__SIZE  (1)\r
+#define PAH831X_B0__INT_FLAG__POS   (0)\r
+#define PAH831X_B0__INT_FLAG__LEN   (8)\r
+#define PAH831X_B0__INT_FLAG__MSK   (0xFF)\r
+\r
+// PAH831X_B0__INT_FLAG_INV__ADDR (0x31), R/W\r
+#define PAH831X_B0__INT_FLAG_INV__POS   (0)\r
+#define PAH831X_B0__INT_FLAG_INV__LEN   (1)\r
+#define PAH831X_B0__INT_FLAG_INV__MSK   (0x01)\r
+\r
+// PAH831X_B0__INT_1_EN__ADDR (0x32), R/W\r
+#define PAH831X_B0__INT_1_EN__ENABLE    (0xFF)\r
+\r
+// PAH831X_B0__FIFO_DATA_COUNT__ADDR (0x33), R\r
+#define PAH831X_B0__FIFO_DATA_COUNT__SIZE   (2)\r
+\r
+// PAH831X_B0__FIFO_DATA_COUNT_L__ADDR (0x33), R\r
+#define PAH831X_B0__FIFO_DATA_COUNT_L__POS  (0)\r
+#define PAH831X_B0__FIFO_DATA_COUNT_L__LEN  (8)\r
+#define PAH831X_B0__FIFO_DATA_COUNT_L__MSK  (0xFF)\r
+\r
+// PAH831X_B0__FIFO_DATA_COUNT_H__ADDR (0x34), R\r
+#define PAH831X_B0__FIFO_DATA_COUNT_H__POS  (0)\r
+#define PAH831X_B0__FIFO_DATA_COUNT_H__LEN  (2)\r
+#define PAH831X_B0__FIFO_DATA_COUNT_H__MSK  (0x03)\r
+\r
+// PAH831X_B0__FIFO_SIZE__ADDR (0x35), R/W\r
+#define PAH831X_B0__FIFO_SIZE__SIZE     (2)\r
+\r
+// PAH831X_B0__FIFO_SIZE_L__ADDR (0x35), R/W\r
+#define PAH831X_B0__FIFO_SIZE_L__POS    (0)\r
+#define PAH831X_B0__FIFO_SIZE_L__LEN    (8)\r
+#define PAH831X_B0__FIFO_SIZE_L__MSK    (0xFF)\r
+\r
+// PAH831X_B0__FIFO_SIZE_H__ADDR (0x36), R/W\r
+#define PAH831X_B0__FIFO_SIZE_H__POS    (0)\r
+#define PAH831X_B0__FIFO_SIZE_H__LEN    (2)\r
+#define PAH831X_B0__FIFO_SIZE_H__MSK    (0x03)\r
+\r
+// PAH831X_B0__FIFO_ON_OFF_ENH__ADDR (0x37), R/W\r
+#define PAH831X_B0__FIFO_ON_OFF_ENH__POS    (0)\r
+#define PAH831X_B0__FIFO_ON_OFF_ENH__LEN    (1)\r
+#define PAH831X_B0__FIFO_ON_OFF_ENH__MSK    (0x01)\r
+\r
+// PAH831X_B0__TOUCH_VALUE__ADDR (0x38), R\r
+#define PAH831X_B0__TOUCH_VALUE__SIZE   (2)\r
+\r
+// PAH831X_B0__CHECKSUM__ADDR (0x3A), R\r
+#define PAH831X_B0__CHECKSUM__POS   (0)\r
+#define PAH831X_B0__CHECKSUM__LEN   (8)\r
+#define PAH831X_B0__CHECKSUM__MSK   (0xFF)\r
+\r
+// PAH831X_B0__WR_PTR__ADDR (0x3B), R\r
+#define PAH831X_B0__WR_PTR__SIZE    (2)\r
+// PAH831X_B0__WR_PTR_1__ADDR (0x3B), R\r
+#define PAH831X_B0__WR_PTR_1__POS   (0)\r
+#define PAH831X_B0__WR_PTR_1__LEN   (8)\r
+#define PAH831X_B0__WR_PTR_1__MSK   (0xFF)\r
+// PAH831X_B0__WR_PTR_2__ADDR (0x3C), R\r
+#define PAH831X_B0__WR_PTR_2__POS   (0)\r
+#define PAH831X_B0__WR_PTR_2__LEN   (2)\r
+#define PAH831X_B0__WR_PTR_2__MSK   (0x03)\r
+\r
+// PAH831X_B0__RD_PTR__ADDR (0x3D), R\r
+#define PAH831X_B0__RD_PTR__SIZE    (2)\r
+// PAH831X_B0__RD_PTR_1__ADDR (0x3D), R\r
+#define PAH831X_B0__RD_PTR_1__POS   (0)\r
+#define PAH831X_B0__RD_PTR_1__LEN   (8)\r
+#define PAH831X_B0__RD_PTR_1__MSK   (0xFF)\r
+// PAH831X_B0__RD_PTR_2__ADDR (0x3E), R\r
+#define PAH831X_B0__RD_PTR_2__POS   (0)\r
+#define PAH831X_B0__RD_PTR_2__LEN   (2)\r
+#define PAH831X_B0__RD_PTR_2__MSK   (0x03)\r
+\r
+// PAH831X_B0__FIFO_CLEAR__ADDR (0x41), W\r
+#define PAH831X_B0__FIFO_CLEAR__SET     (0x01)\r
+#define PAH831X_B0__FIFO_CLEAR__RESET   (0x00)\r
+\r
+// PAH831X_B0__BACK_TRACKING_COUNT__ADDR (0x42), R/W\r
+#define PAH831X_B0__BACK_TRACKING_COUNT__SIZE   (2)\r
+// PAH831X_B0__BACK_TRACKING_COUNT_1__ADDR (0x42), R/W\r
+#define PAH831X_B0__BACK_TRACKING_COUNT_1__POS  (0)\r
+#define PAH831X_B0__BACK_TRACKING_COUNT_1__LEN  (8)\r
+#define PAH831X_B0__BACK_TRACKING_COUNT_1__MSK  (0xFF)\r
+// PAH831X_B0__BACK_TRACKING_COUNT_2__ADDR (0x43), R/W\r
+#define PAH831X_B0__BACK_TRACKING_COUNT_2__POS  (0)\r
+#define PAH831X_B0__BACK_TRACKING_COUNT_2__LEN  (2)\r
+#define PAH831X_B0__BACK_TRACKING_COUNT_2__MSK  (0x03)\r
+\r
+// PAH831X_B0__FIFO_DATA_COUNT_UNLOCK__ADDR (0x44), R\r
+#define PAH831X_B0__FIFO_DATA_COUNT_UNLOCK__SIZE    (2)\r
+// PAH831X_B0__FIFO_DATA_COUNT_UNLOCK_1__ADDR (0x44), R\r
+#define PAH831X_B0__FIFO_DATA_COUNT_UNLOCK_1__POS   (0)\r
+#define PAH831X_B0__FIFO_DATA_COUNT_UNLOCK_1__LEN   (8)\r
+#define PAH831X_B0__FIFO_DATA_COUNT_UNLOCK_1__MSK   (0xFF)\r
+// PAH831X_B0__FIFO_DATA_COUNT_UNLOCK_2__ADDR (0x45), R\r
+#define PAH831X_B0__FIFO_DATA_COUNT_UNLOCK_2__POS   (0)\r
+#define PAH831X_B0__FIFO_DATA_COUNT_UNLOCK_2__LEN   (2)\r
+#define PAH831X_B0__FIFO_DATA_COUNT_UNLOCK_2__MSK   (0x03)\r
+\r
+// PAH831X_B0__LPF_DC_OFFSET__ADDR (0x46), R/W\r
+#define PAH831X_B0__LPF_DC_OFFSET__SIZE     (3)\r
+// PAH831X_B0__LPF_DC_OFFSET_1__ADDR (0x46), R/W\r
+#define PAH831X_B0__LPF_DC_OFFSET_1__POS    (0)\r
+#define PAH831X_B0__LPF_DC_OFFSET_1__LEN    (8)\r
+#define PAH831X_B0__LPF_DC_OFFSET_1__MSK    (0xFF)\r
+// PAH831X_B0__LPF_DC_OFFSET_2__ADDR (0x47), R/W\r
+#define PAH831X_B0__LPF_DC_OFFSET_2__POS    (0)\r
+#define PAH831X_B0__LPF_DC_OFFSET_2__LEN    (8)\r
+#define PAH831X_B0__LPF_DC_OFFSET_2__MSK    (0xFF)\r
+// PAH831X_B0__LPF_DC_OFFSET_3__ADDR (0x48), R/W\r
+#define PAH831X_B0__LPF_DC_OFFSET_3__POS    (0)\r
+#define PAH831X_B0__LPF_DC_OFFSET_3__LEN    (6)\r
+#define PAH831X_B0__LPF_DC_OFFSET_3__MSK    (0x3F)\r
+\r
+// PAH831X_B0__TOUCH_ENH__ADDR (0x49), R/W\r
+#define PAH831X_B0__TOUCH_ENH__TOUCH_ENH__POS       (0)\r
+#define PAH831X_B0__TOUCH_ENH__TOUCH_ENH__LEN       (1)\r
+#define PAH831X_B0__TOUCH_ENH__TOUCH_ENH__MSK       (0x01)\r
+#define PAH831X_B0__TOUCH_ENH__FAST_TOUCH_ENH__POS  (4)\r
+#define PAH831X_B0__TOUCH_ENH__FAST_TOUCH_ENH__LEN  (1)\r
+#define PAH831X_B0__TOUCH_ENH__FAST_TOUCH_ENH__MSK  (0x10)\r
+#define PAH831X_B0__TOUCH_ENH__ENABLE               (0x11)\r
+#define PAH831X_B0__TOUCH_ENH__DISABLE              (0x00)\r
+\r
+// PAH831X_B0__TOUCH_DETECTION_TH_HI__ADDR (0x4A)\r
+#define PAH831X_B0__TOUCH_DETECTION_TH_HI__SIZE     (2)\r
+// PAH831X_B0__TOUCH_DETECTION_TH_HI_1__ADDR (0x4A)\r
+#define PAH831X_B0__TOUCH_DETECTION_TH_HI_1__POS    (0)\r
+#define PAH831X_B0__TOUCH_DETECTION_TH_HI_1__LEN    (8)\r
+#define PAH831X_B0__TOUCH_DETECTION_TH_HI_1__MSK    (0xFF)\r
+// PAH831X_B0__TOUCH_DETECTION_TH_HI_2__ADDR (0x4B)\r
+#define PAH831X_B0__TOUCH_DETECTION_TH_HI_2__POS    (0)\r
+#define PAH831X_B0__TOUCH_DETECTION_TH_HI_2__LEN    (8)\r
+#define PAH831X_B0__TOUCH_DETECTION_TH_HI_2__MSK    (0xFF)\r
+\r
+// PAH831X_B0__TOUCH_DETECTION_TH_LO__ADDR (0x4C)\r
+#define PAH831X_B0__TOUCH_DETECTION_TH_LO__SIZE     (2)\r
+// PAH831X_B0__TOUCH_DETECTION_TH_LO_1__ADDR (0x4C)\r
+#define PAH831X_B0__TOUCH_DETECTION_TH_LO_1__POS    (0)\r
+#define PAH831X_B0__TOUCH_DETECTION_TH_LO_1__LEN    (8)\r
+#define PAH831X_B0__TOUCH_DETECTION_TH_LO_1__MSK    (0xFF)\r
+// PAH831X_B0__TOUCH_DETECTION_TH_LO_2__ADDR (0x4D)\r
+#define PAH831X_B0__TOUCH_DETECTION_TH_LO_2__POS    (0)\r
+#define PAH831X_B0__TOUCH_DETECTION_TH_LO_2__LEN    (8)\r
+#define PAH831X_B0__TOUCH_DETECTION_TH_LO_2__MSK    (0xFF)\r
+\r
+// PAH831X_B0__TOUCH_DETECTION_COUTH_TH__ADDR (0x4E)\r
+#define PAH831X_B0__TOUCH_DETECTION_COUTH_TH__POS       (0)\r
+#define PAH831X_B0__TOUCH_DETECTION_COUTH_TH__LEN       (5)\r
+#define PAH831X_B0__TOUCH_DETECTION_COUTH_TH__MSK       (0x1F)\r
+\r
+// PAH831X_B0__NO_TOUCH_DETECTION_COUTH_TH__ADDR (0x4F)\r
+#define PAH831X_B0__NO_TOUCH_DETECTION_COUTH_TH__POS    (0)\r
+#define PAH831X_B0__NO_TOUCH_DETECTION_COUTH_TH__LEN    (5)\r
+#define PAH831X_B0__NO_TOUCH_DETECTION_COUTH_TH__MSK    (0x1F)\r
+\r
+// PAH831X_B0__PPG_A__ADDR (0x50), R/W\r
+#define PAH831X_B0__PPG_A__PPG1_ENH__POS            (0)\r
+#define PAH831X_B0__PPG_A__PPG1_ENH__LEN            (1)\r
+#define PAH831X_B0__PPG_A__PPG1_ENH__MSK            (0x01)\r
+#define PAH831X_B0__PPG_A__PPG2_ENH__POS            (1)\r
+#define PAH831X_B0__PPG_A__PPG2_ENH__LEN            (1)\r
+#define PAH831X_B0__PPG_A__PPG2_ENH__MSK            (0x02)\r
+#define PAH831X_B0__PPG_A__AGC_PPG1_SEL__POS        (2)\r
+#define PAH831X_B0__PPG_A__AGC_PPG1_SEL__LEN        (2)\r
+#define PAH831X_B0__PPG_A__AGC_PPG1_SEL__MSK        (0x0C)\r
+#define PAH831X_B0__PPG_A__AGC_PPG2_SEL__POS        (4)\r
+#define PAH831X_B0__PPG_A__AGC_PPG2_SEL__LEN        (2)\r
+#define PAH831X_B0__PPG_A__AGC_PPG2_SEL__MSK        (0x30)\r
+#define PAH831X_B0__PPG_A__FIFO_WRITE_MASK__POS     (6)\r
+#define PAH831X_B0__PPG_A__FIFO_WRITE_MASK__LEN     (1)\r
+#define PAH831X_B0__PPG_A__FIFO_WRITE_MASK__MSK     (0x40)\r
+\r
+// PAH831X_B0__PPG_B__ADDR (0x51), R/W\r
+#define PAH831X_B0__PPG_B__PPG1_ENH__POS            (0)\r
+#define PAH831X_B0__PPG_B__PPG1_ENH__LEN            (1)\r
+#define PAH831X_B0__PPG_B__PPG1_ENH__MSK            (0x01)\r
+#define PAH831X_B0__PPG_B__PPG2_ENH__POS            (1)\r
+#define PAH831X_B0__PPG_B__PPG2_ENH__LEN            (1)\r
+#define PAH831X_B0__PPG_B__PPG2_ENH__MSK            (0x02)\r
+#define PAH831X_B0__PPG_B__AGC_PPG1_SEL__POS        (2)\r
+#define PAH831X_B0__PPG_B__AGC_PPG1_SEL__LEN        (2)\r
+#define PAH831X_B0__PPG_B__AGC_PPG1_SEL__MSK        (0x0C)\r
+#define PAH831X_B0__PPG_B__AGC_PPG2_SEL__POS        (4)\r
+#define PAH831X_B0__PPG_B__AGC_PPG2_SEL__LEN        (2)\r
+#define PAH831X_B0__PPG_B__AGC_PPG2_SEL__MSK        (0x30)\r
+#define PAH831X_B0__PPG_B__FIFO_WRITE_MASK__POS     (6)\r
+#define PAH831X_B0__PPG_B__FIFO_WRITE_MASK__LEN     (1)\r
+#define PAH831X_B0__PPG_B__FIFO_WRITE_MASK__MSK     (0x40)\r
+\r
+// PAH831X_B0__PPG_C__ADDR (0x52), R/W\r
+#define PAH831X_B0__PPG_C__PPG1_ENH__POS            (0)\r
+#define PAH831X_B0__PPG_C__PPG1_ENH__LEN            (1)\r
+#define PAH831X_B0__PPG_C__PPG1_ENH__MSK            (0x01)\r
+#define PAH831X_B0__PPG_C__PPG2_ENH__POS            (1)\r
+#define PAH831X_B0__PPG_C__PPG2_ENH__LEN            (1)\r
+#define PAH831X_B0__PPG_C__PPG2_ENH__MSK            (0x02)\r
+#define PAH831X_B0__PPG_C__AGC_PPG1_SEL__POS        (2)\r
+#define PAH831X_B0__PPG_C__AGC_PPG1_SEL__LEN        (2)\r
+#define PAH831X_B0__PPG_C__AGC_PPG1_SEL__MSK        (0x0C)\r
+#define PAH831X_B0__PPG_C__AGC_PPG2_SEL__POS        (4)\r
+#define PAH831X_B0__PPG_C__AGC_PPG2_SEL__LEN        (2)\r
+#define PAH831X_B0__PPG_C__AGC_PPG2_SEL__MSK        (0x30)\r
+#define PAH831X_B0__PPG_C__FIFO_WRITE_MASK__POS     (6)\r
+#define PAH831X_B0__PPG_C__FIFO_WRITE_MASK__LEN     (1)\r
+#define PAH831X_B0__PPG_C__FIFO_WRITE_MASK__MSK     (0x40)\r
+\r
+// PAH831X_B0__PPG_D__ADDR (0x53), R/W\r
+#define PAH831X_B0__PPG_D__PPG1_ENH__POS            (0)\r
+#define PAH831X_B0__PPG_D__PPG1_ENH__LEN            (1)\r
+#define PAH831X_B0__PPG_D__PPG1_ENH__MSK            (0x01)\r
+#define PAH831X_B0__PPG_D__PPG2_ENH__POS            (1)\r
+#define PAH831X_B0__PPG_D__PPG2_ENH__LEN            (1)\r
+#define PAH831X_B0__PPG_D__PPG2_ENH__MSK            (0x02)\r
+#define PAH831X_B0__PPG_D__AGC_PPG1_SEL__POS        (2)\r
+#define PAH831X_B0__PPG_D__AGC_PPG1_SEL__LEN        (2)\r
+#define PAH831X_B0__PPG_D__AGC_PPG1_SEL__MSK        (0x0C)\r
+#define PAH831X_B0__PPG_D__AGC_PPG2_SEL__POS        (4)\r
+#define PAH831X_B0__PPG_D__AGC_PPG2_SEL__LEN        (2)\r
+#define PAH831X_B0__PPG_D__AGC_PPG2_SEL__MSK        (0x30)\r
+#define PAH831X_B0__PPG_D__FIFO_WRITE_MASK__POS     (6)\r
+#define PAH831X_B0__PPG_D__FIFO_WRITE_MASK__LEN     (1)\r
+#define PAH831X_B0__PPG_D__FIFO_WRITE_MASK__MSK     (0x40)\r
+\r
+// PAH831X_B0__INT_1_MASK_ENL__ADDR (0x54), R/W\r
+#define PAH831X_B0__INT_1_MASK_ENL__POS     (0)\r
+#define PAH831X_B0__INT_1_MASK_ENL__LEN     (8)\r
+#define PAH831X_B0__INT_1_MASK_ENL__MSK     (0xFF)\r
+\r
+// PAH831X_B0__INT_2_MASK_ENL__ADDR (0x55), R/W\r
+#define PAH831X_B0__INT_2_MASK_ENL__POS     (0)\r
+#define PAH831X_B0__INT_2_MASK_ENL__LEN     (8)\r
+#define PAH831X_B0__INT_2_MASK_ENL__MSK     (0xFF)\r
+\r
+// PAH831X_B0__DECIMATION_NUM__ADDR (0x56), R/W\r
+#define PAH831X_B0__DECIMATION_NUM__POS     (0)\r
+#define PAH831X_B0__DECIMATION_NUM__LEN     (5)\r
+#define PAH831X_B0__DECIMATION_NUM__MSK     (0x1F)\r
+\r
+// PAH831X_B0__ECG_RAWDATA__ADDR (0x57), R\r
+#define PAH831X_B0__ECG_RAWDATA__SIZE       (3)\r
+// PAH831X_B0__ECG_RAWDATA_1__ADDR (0x57), R\r
+#define PAH831X_B0__ECG_RAWDATA_1____POS    (0)\r
+#define PAH831X_B0__ECG_RAWDATA_1____LEN    (8)\r
+#define PAH831X_B0__ECG_RAWDATA_1____MSK    (0xFF)\r
+// PAH831X_B0__ECG_RAWDATA_2__ADDR (0x58), R\r
+#define PAH831X_B0__ECG_RAWDATA_2____POS    (0)\r
+#define PAH831X_B0__ECG_RAWDATA_2____LEN    (8)\r
+#define PAH831X_B0__ECG_RAWDATA_2____MSK    (0xFF)\r
+// PAH831X_B0__ECG_RAWDATA_3__ADDR (0x59), R\r
+#define PAH831X_B0__ECG_RAWDATA_3____POS    (0)\r
+#define PAH831X_B0__ECG_RAWDATA_3____LEN    (8)\r
+#define PAH831X_B0__ECG_RAWDATA_3____MSK    (0xFF)\r
+\r
+// PAH831X_B0__LOD_DETECTION_COUNT_TH__ADDR (0x5A), R/W\r
+#define PAH831X_B0__LOD_DETECTION_COUNT_TH__POS     (0)\r
+#define PAH831X_B0__LOD_DETECTION_COUNT_TH__LEN     (8)\r
+#define PAH831X_B0__LOD_DETECTION_COUNT_TH__MSK     (0xFF)\r
+\r
+// PAH831X_B0__NO_LOD_DETECTION_COUNT_TH__ADDR (0x5B), R/W\r
+#define PAH831X_B0__NO_LOD_DETECTION_COUNT_TH__POS  (0)\r
+#define PAH831X_B0__NO_LOD_DETECTION_COUNT_TH__LEN  (8)\r
+#define PAH831X_B0__NO_LOD_DETECTION_COUNT_TH__MSK  (0xFF)\r
+\r
+// PAH831X_B0__LOD_INT_2_EN__ADDR (0x5C), R/W\r
+#define PAH831X_B0__LOD_INT_2_EN__ENABLE    (0xFF)\r
+\r
+// PAH831X_B0__PPG_ADC_OFFSET__ADDR (0x5D), R/W\r
+#define PAH831X_B0__PPG_ADC_OFFSET__SIZE    (2)\r
+// PAH831X_B0__PPG_ADC_OFFSET_1__ADDR (0x5D), R/W\r
+#define PAH831X_B0__PPG_ADC_OFFSET_1__POS   (0)\r
+#define PAH831X_B0__PPG_ADC_OFFSET_1__LEN   (8)\r
+#define PAH831X_B0__PPG_ADC_OFFSET_1__MSK   (0xFF)\r
+// PAH831X_B0__PPG_ADC_OFFSET_2__ADDR (0x5E), R/W\r
+#define PAH831X_B0__PPG_ADC_OFFSET_2__POS   (0)\r
+#define PAH831X_B0__PPG_ADC_OFFSET_2__LEN   (8)\r
+#define PAH831X_B0__PPG_ADC_OFFSET_2__MSK   (0xFF)\r
+\r
+// PAH831X_B0__ECG_ADC_OFFSET__ADDR (0x5F), R/W\r
+#define PAH831X_B0__ECG_ADC_OFFSET__SIZE    (2)\r
+// PAH831X_B0__ECG_ADC_OFFSET_1__ADDR (0x5D), R/W\r
+#define PAH831X_B0__ECG_ADC_OFFSET_1__POS   (0)\r
+#define PAH831X_B0__ECG_ADC_OFFSET_1__LEN   (8)\r
+#define PAH831X_B0__ECG_ADC_OFFSET_1__MSK   (0xFF)\r
+// PAH831X_B0__ECG_ADC_OFFSET_2__ADDR (0x60), R/W\r
+#define PAH831X_B0__ECG_ADC_OFFSET_2__POS   (0)\r
+#define PAH831X_B0__ECG_ADC_OFFSET_2__LEN   (8)\r
+#define PAH831X_B0__ECG_ADC_OFFSET_2__MSK   (0xFF)\r
+\r
+// PAH831X_B0__FRAME_PERIOD_E__ADDR (0x64), R/W\r
+#define PAH831X_B0__FRAME_PERIOD_E__SIZE    (2)\r
+// PAH831X_B0__FRAME_PERIOD_E_1__ADDR (0x64), R/W\r
+#define PAH831X_B0__FRAME_PERIOD_E_1__POS   (0)\r
+#define PAH831X_B0__FRAME_PERIOD_E_1__LEN   (8)\r
+#define PAH831X_B0__FRAME_PERIOD_E_1__MSK   (0xFF)\r
+// PAH831X_B0__FRAME_PERIOD_E_2__ADDR (0x65), R/W\r
+#define PAH831X_B0__FRAME_PERIOD_E_2__POS   (0)\r
+#define PAH831X_B0__FRAME_PERIOD_E_2__LEN   (6)\r
+#define PAH831X_B0__FRAME_PERIOD_E_2__MSK   (0x3F)\r
+\r
+// PAH831X_B0__FRAME_PERIOD_F__ADDR (0x66), R/W\r
+#define PAH831X_B0__FRAME_PERIOD_F__SIZE    (2)\r
+// PAH831X_B0__FRAME_PERIOD_F_1__ADDR (0x66), R/W\r
+#define PAH831X_B0__FRAME_PERIOD_F_1__POS   (0)\r
+#define PAH831X_B0__FRAME_PERIOD_F_1__LEN   (8)\r
+#define PAH831X_B0__FRAME_PERIOD_F_1__MSK   (0xFF)\r
+// PAH831X_B0__FRAME_PERIOD_F_2__ADDR (0x67), R/W\r
+#define PAH831X_B0__FRAME_PERIOD_F_2__POS   (0)\r
+#define PAH831X_B0__FRAME_PERIOD_F_2__LEN   (6)\r
+#define PAH831X_B0__FRAME_PERIOD_F_2__MSK   (0x3F)\r
+\r
+// PAH831X_B0__CH_ENH_2__ADDR (0x68), R/W\r
+#define PAH831X_B0__CH_ENH_2__CH_E__POS     (0)\r
+#define PAH831X_B0__CH_ENH_2__CH_F__POS     (1)\r
+\r
+// PAH831X_B0__REPORT_DIVIDER_E__ADDR (0x69), R/W\r
+#define PAH831X_B0__REPORT_DIVIDER_E__SIZE      (2)\r
+// PAH831X_B0__REPORT_DIVIDER_E_1__ADDR (0x69), R/W\r
+#define PAH831X_B0__REPORT_DIVIDER_E_1__POS     (0)\r
+#define PAH831X_B0__REPORT_DIVIDER_E_1__LEN     (8)\r
+#define PAH831X_B0__REPORT_DIVIDER_E_1__MSK     (0xFF)\r
+// PAH831X_B0__REPORT_DIVIDER_E_2__ADDR (0x6A), R/W\r
+#define PAH831X_B0__REPORT_DIVIDER_E_2__POS     (0)\r
+#define PAH831X_B0__REPORT_DIVIDER_E_2__LEN     (8)\r
+#define PAH831X_B0__REPORT_DIVIDER_E_2__MSK     (0xFF)\r
+\r
+// PAH831X_B0__REPORT_DIVIDER_F__ADDR (0x6B), R/W\r
+#define PAH831X_B0__REPORT_DIVIDER_F__SIZE      (2)\r
+// PAH831X_B0__REPORT_DIVIDER_F_1__ADDR (0x6B), R/W\r
+#define PAH831X_B0__REPORT_DIVIDER_F_1__POS     (0)\r
+#define PAH831X_B0__REPORT_DIVIDER_F_1__LEN     (8)\r
+#define PAH831X_B0__REPORT_DIVIDER_F_1__MSK     (0xFF)\r
+// PAH831X_B0__REPORT_DIVIDER_F_2__ADDR (0x6C), R/W\r
+#define PAH831X_B0__REPORT_DIVIDER_F_2__POS     (0)\r
+#define PAH831X_B0__REPORT_DIVIDER_F_2__LEN     (8)\r
+#define PAH831X_B0__REPORT_DIVIDER_F_2__MSK     (0xFF)\r
+\r
+// PAH831X_B0__FRAME_NUM_E__ADDR (0x6D), R/W\r
+#define PAH831X_B0__FRAME_NUM_E__POS    (0)\r
+#define PAH831X_B0__FRAME_NUM_E__LEN    (7)\r
+#define PAH831X_B0__FRAME_NUM_E__MSK    (0x7F)\r
+\r
+// PAH831X_B0__FRAME_NUM_F__ADDR (0x6D), R/W\r
+#define PAH831X_B0__FRAME_NUM_F__POS    (0)\r
+#define PAH831X_B0__FRAME_NUM_F__LEN    (7)\r
+#define PAH831X_B0__FRAME_NUM_F__MSK    (0x7F)\r
+\r
+// PAH831X_B0__PPG_E__ADDR (0x70), R/W\r
+#define PAH831X_B0__PPG_E__PPG1_ENH__POS            (0)\r
+#define PAH831X_B0__PPG_E__PPG1_ENH__LEN            (1)\r
+#define PAH831X_B0__PPG_E__PPG1_ENH__MSK            (0x01)\r
+#define PAH831X_B0__PPG_E__PPG2_ENH__POS            (1)\r
+#define PAH831X_B0__PPG_E__PPG2_ENH__LEN            (1)\r
+#define PAH831X_B0__PPG_E__PPG2_ENH__MSK            (0x02)\r
+#define PAH831X_B0__PPG_E__AGC_PPG1_SEL__POS        (2)\r
+#define PAH831X_B0__PPG_E__AGC_PPG1_SEL__LEN        (2)\r
+#define PAH831X_B0__PPG_E__AGC_PPG1_SEL__MSK        (0x0C)\r
+#define PAH831X_B0__PPG_E__AGC_PPG2_SEL__POS        (4)\r
+#define PAH831X_B0__PPG_E__AGC_PPG2_SEL__LEN        (2)\r
+#define PAH831X_B0__PPG_E__AGC_PPG2_SEL__MSK        (0x30)\r
+#define PAH831X_B0__PPG_E__FIFO_WRITE_MASK__POS     (6)\r
+#define PAH831X_B0__PPG_E__FIFO_WRITE_MASK__LEN     (1)\r
+#define PAH831X_B0__PPG_E__FIFO_WRITE_MASK__MSK     (0x40)\r
+\r
+// PAH831X_B0__PPG_F__ADDR (0x71), R/W\r
+#define PAH831X_B0__PPG_F__PPG1_ENH__POS            (0)\r
+#define PAH831X_B0__PPG_F__PPG1_ENH__LEN            (1)\r
+#define PAH831X_B0__PPG_F__PPG1_ENH__MSK            (0x01)\r
+#define PAH831X_B0__PPG_F__PPG2_ENH__POS            (1)\r
+#define PAH831X_B0__PPG_F__PPG2_ENH__LEN            (1)\r
+#define PAH831X_B0__PPG_F__PPG2_ENH__MSK            (0x02)\r
+#define PAH831X_B0__PPG_F__AGC_PPG1_SEL__POS        (2)\r
+#define PAH831X_B0__PPG_F__AGC_PPG1_SEL__LEN        (2)\r
+#define PAH831X_B0__PPG_F__AGC_PPG1_SEL__MSK        (0x0C)\r
+#define PAH831X_B0__PPG_F__AGC_PPG2_SEL__POS        (4)\r
+#define PAH831X_B0__PPG_F__AGC_PPG2_SEL__LEN        (2)\r
+#define PAH831X_B0__PPG_F__AGC_PPG2_SEL__MSK        (0x30)\r
+#define PAH831X_B0__PPG_F__FIFO_WRITE_MASK__POS     (6)\r
+#define PAH831X_B0__PPG_F__FIFO_WRITE_MASK__LEN     (1)\r
+#define PAH831X_B0__PPG_F__FIFO_WRITE_MASK__MSK     (0x40)\r
+\r
+// PAH831X_B0__ECG_FIFO_WRITE_MASK__ADDR (0x71), R/W\r
+#define PAH831X_B0__ECG_FIFO_WRITE_MASK__POS        (7)\r
+#define PAH831X_B0__ECG_FIFO_WRITE_MASK__LEN        (1)\r
+#define PAH831X_B0__ECG_FIFO_WRITE_MASK__MSK        (0x80)\r
+\r
+// PAH831X_B0__FRAME_REPEAT_A__ADDR (0x72), R/W\r
+#define PAH831X_B0__FRAME_REPEAT_A__POS     (0)\r
+#define PAH831X_B0__FRAME_REPEAT_A__LEN     (5)\r
+#define PAH831X_B0__FRAME_REPEAT_A__MSK     (0x1F)\r
+\r
+// PAH831X_B0__FRAME_REPEAT_B__ADDR (0x73), R/W\r
+#define PAH831X_B0__FRAME_REPEAT_B__POS     (0)\r
+#define PAH831X_B0__FRAME_REPEAT_B__LEN     (5)\r
+#define PAH831X_B0__FRAME_REPEAT_B__MSK     (0x1F)\r
+\r
+// PAH831X_B0__FRAME_REPEAT_C__ADDR (0x74), R/W\r
+#define PAH831X_B0__FRAME_REPEAT_C__POS     (0)\r
+#define PAH831X_B0__FRAME_REPEAT_C__LEN     (5)\r
+#define PAH831X_B0__FRAME_REPEAT_C__MSK     (0x1F)\r
+\r
+// PAH831X_B0__FRAME_REPEAT_D__ADDR (0x75), R/W\r
+#define PAH831X_B0__FRAME_REPEAT_D__POS     (0)\r
+#define PAH831X_B0__FRAME_REPEAT_D__LEN     (5)\r
+#define PAH831X_B0__FRAME_REPEAT_D__MSK     (0x1F)\r
+\r
+// PAH831X_B0__FRAME_REPEAT_E__ADDR (0x76), R/W\r
+#define PAH831X_B0__FRAME_REPEAT_E__POS     (0)\r
+#define PAH831X_B0__FRAME_REPEAT_E__LEN     (5)\r
+#define PAH831X_B0__FRAME_REPEAT_E__MSK     (0x1F)\r
+\r
+// PAH831X_B0__FRAME_REPEAT_F__ADDR (0x77), R/W\r
+#define PAH831X_B0__FRAME_REPEAT_F__POS     (0)\r
+#define PAH831X_B0__FRAME_REPEAT_F__LEN     (5)\r
+#define PAH831X_B0__FRAME_REPEAT_F__MSK     (0x1F)\r
+\r
+// PAH831X_B0__FRAME_REPEAT_T__ADDR (0x78), R/W\r
+#define PAH831X_B0__FRAME_REPEAT_T__POS     (0)\r
+#define PAH831X_B0__FRAME_REPEAT_T__LEN     (5)\r
+#define PAH831X_B0__FRAME_REPEAT_T__MSK     (0x1F)\r
+\r
+// PAH831X_B0__READ_FIFO_ENH__ADDR (0x7A), R/W\r
+#define PAH831X_B0__READ_FIFO_ENH__DISABLE      (0x00)\r
+#define PAH831X_B0__READ_FIFO_ENH__ENABLE       (0x01)\r
+#define PAH831X_B0__READ_FIFO_ENH__ENABLE_BACK  (0x02)\r
+\r
+// PAH831X_B0__READ_FIFO__ADDR (0x7B), R\r
+\r
+// PAH831X_B0__UPDATE_FLAG__ADDR (0x7E), W\r
+#define PAH831X_B0__UPDATE_FLAG__VALUE      (0x80)\r
+\r
+// PAH831X_B1__ECG_POLAR_FLIP_ENH__ADDR (0x1A), R/W\r
+#define PAH831X_B1__ECG_POLAR_FLIP_ENH__POS     (6)\r
+#define PAH831X_B1__ECG_POLAR_FLIP_ENH__LEN     (1)\r
+#define PAH831X_B1__ECG_POLAR_FLIP_ENH__MSK     (0x40)\r
+#define PAH831X_B1__ECG_POLAR_FLIP_ENH__ENABLE  (1)\r
+\r
+// PAH831X_B1__ECG_FE_INA_GAIN__ADDR (0x26), R/W\r
+#define PAH831X_B1__ECG_FE_INA_GAIN__POS        (0)\r
+#define PAH831X_B1__ECG_FE_INA_GAIN__LEN        (2)\r
+#define PAH831X_B1__ECG_FE_INA_GAIN__MSK        (0x03)\r
+#define PAH831X_B1__ECG_FE_INA_GAIN__SELECT_0   (1) // 1x\r
+#define PAH831X_B1__ECG_FE_INA_GAIN__SELECT_1   (1) // 1x\r
+#define PAH831X_B1__ECG_FE_INA_GAIN__SELECT_2   (11) // 11x\r
+#define PAH831X_B1__ECG_FE_INA_GAIN__SELECT_3   (21) // 21x\r
+\r
+// PAH831X_B2__PPG1_ADC_DEBUG_MODE__ADDR (0x0E), R/W\r
+#define PAH831X_B2__PPG1_ADC_DEBUG_MODE__POS    (0)\r
+#define PAH831X_B2__PPG1_ADC_DEBUG_MODE__LEN    (4)\r
+#define PAH831X_B2__PPG1_ADC_DEBUG_MODE__MSK    (0x0F)\r
+\r
+// PAH831X_B2__PPG1_ADC_DEBUG_PATTERN_ON__ADDR (0x0F), R/W\r
+#define PAH831X_B2__PPG1_ADC_DEBUG_PATTERN_ON__SIZE     (2)\r
+// PAH831X_B2__PPG1_ADC_DEBUG_PATTERN_ON_1__ADDR (0x0F), R/W\r
+#define PAH831X_B2__PPG1_ADC_DEBUG_PATTERN_ON_1__POS    (0)\r
+#define PAH831X_B2__PPG1_ADC_DEBUG_PATTERN_ON_1__LEN    (8)\r
+#define PAH831X_B2__PPG1_ADC_DEBUG_PATTERN_ON_1__MSK    (0xFF)\r
+// PAH831X_B2__PPG1_ADC_DEBUG_PATTERN_ON_2__ADDR (0x10), R/W\r
+#define PAH831X_B2__PPG1_ADC_DEBUG_PATTERN_ON_2__POS    (0)\r
+#define PAH831X_B2__PPG1_ADC_DEBUG_PATTERN_ON_2__LEN    (8)\r
+#define PAH831X_B2__PPG1_ADC_DEBUG_PATTERN_ON_2__MSK    (0xFF)\r
+\r
+// PAH831X_B2__PPG1_ADC_DEBUG_PATTERN_OFF__ADDR (0x11), R/W\r
+#define PAH831X_B2__PPG1_ADC_DEBUG_PATTERN_OFF__SIZE    (2)\r
+// PAH831X_B2__PPG1_ADC_DEBUG_PATTERN_OFF_1__ADDR (0x11), R/W\r
+#define PAH831X_B2__PPG1_ADC_DEBUG_PATTERN_OFF_1__POS   (0)\r
+#define PAH831X_B2__PPG1_ADC_DEBUG_PATTERN_OFF_1__LEN   (8)\r
+#define PAH831X_B2__PPG1_ADC_DEBUG_PATTERN_OFF_1__MSK   (0xFF)\r
+// PAH831X_B2__PPG1_ADC_DEBUG_PATTERN_OFF_2__ADDR (0x12), R/W\r
+#define PAH831X_B2__PPG1_ADC_DEBUG_PATTERN_OFF_2__POS   (0)\r
+#define PAH831X_B2__PPG1_ADC_DEBUG_PATTERN_OFF_2__LEN   (8)\r
+#define PAH831X_B2__PPG1_ADC_DEBUG_PATTERN_OFF_2__MSK   (0xFF)\r
+\r
+// PAH831X_B2__PPG2_ADC_DEBUG_MODE__ADDR (0x13), R/W\r
+#define PAH831X_B2__PPG2_ADC_DEBUG_MODE__POS    (0)\r
+#define PAH831X_B2__PPG2_ADC_DEBUG_MODE__LEN    (4)\r
+#define PAH831X_B2__PPG2_ADC_DEBUG_MODE__MSK    (0x0F)\r
+\r
+// PAH831X_B2__PPG2_ADC_DEBUG_PATTERN_ON__ADDR (0x14), R/W\r
+#define PAH831X_B2__PPG2_ADC_DEBUG_PATTERN_ON__SIZE     (2)\r
+// PAH831X_B2__PPG2_ADC_DEBUG_PATTERN_ON_1__ADDR (0x14), R/W\r
+#define PAH831X_B2__PPG2_ADC_DEBUG_PATTERN_ON_1__POS    (0)\r
+#define PAH831X_B2__PPG2_ADC_DEBUG_PATTERN_ON_1__LEN    (8)\r
+#define PAH831X_B2__PPG2_ADC_DEBUG_PATTERN_ON_1__MSK    (0xFF)\r
+// PAH831X_B2__PPG2_ADC_DEBUG_PATTERN_ON_2__ADDR (0x15), R/W\r
+#define PAH831X_B2__PPG2_ADC_DEBUG_PATTERN_ON_2__POS    (0)\r
+#define PAH831X_B2__PPG2_ADC_DEBUG_PATTERN_ON_2__LEN    (8)\r
+#define PAH831X_B2__PPG2_ADC_DEBUG_PATTERN_ON_2__MSK    (0xFF)\r
+\r
+// PAH831X_B2__PPG2_ADC_DEBUG_PATTERN_OFF__ADDR (0x16), R/W\r
+#define PAH831X_B2__PPG2_ADC_DEBUG_PATTERN_OFF__SIZE    (2)\r
+// PAH831X_B2__PPG2_ADC_DEBUG_PATTERN_OFF_1__ADDR (0x16), R/W\r
+#define PAH831X_B2__PPG2_ADC_DEBUG_PATTERN_OFF_1__POS   (0)\r
+#define PAH831X_B2__PPG2_ADC_DEBUG_PATTERN_OFF_1__LEN   (8)\r
+#define PAH831X_B2__PPG2_ADC_DEBUG_PATTERN_OFF_1__MSK   (0xFF)\r
+// PAH831X_B2__PPG2_ADC_DEBUG_PATTERN_OFF_2__ADDR (0x17), R/W\r
+#define PAH831X_B2__PPG2_ADC_DEBUG_PATTERN_OFF_2__POS   (0)\r
+#define PAH831X_B2__PPG2_ADC_DEBUG_PATTERN_OFF_2__LEN   (8)\r
+#define PAH831X_B2__PPG2_ADC_DEBUG_PATTERN_OFF_2__MSK   (0xFF)\r
+\r
+// PAH831X_B2__ECG_ADC_DEBUG_MODE__ADDR (0x18), R/W\r
+#define PAH831X_B2__ECG_ADC_DEBUG_MODE__POS     (0)\r
+#define PAH831X_B2__ECG_ADC_DEBUG_MODE__LEN     (4)\r
+#define PAH831X_B2__ECG_ADC_DEBUG_MODE__MSK     (0x0F)\r
+\r
+// PAH831X_B2__ECG_ADC_DEBUG_PATTERN_ON__ADDR (0x19), R/W\r
+#define PAH831X_B2__ECG_ADC_DEBUG_PATTERN_ON__SIZE      (2)\r
+// PAH831X_B2__ECG_ADC_DEBUG_PATTERN_ON_1__ADDR (0x19), R/W\r
+#define PAH831X_B2__ECG_ADC_DEBUG_PATTERN_ON_1__POS     (0)\r
+#define PAH831X_B2__ECG_ADC_DEBUG_PATTERN_ON_1__LEN     (8)\r
+#define PAH831X_B2__ECG_ADC_DEBUG_PATTERN_ON_1__MSK     (0xFF)\r
+// PAH831X_B2__ECG_ADC_DEBUG_PATTERN_ON_2__ADDR (0x1A), R/W\r
+#define PAH831X_B2__ECG_ADC_DEBUG_PATTERN_ON_2__POS     (0)\r
+#define PAH831X_B2__ECG_ADC_DEBUG_PATTERN_ON_2__LEN     (8)\r
+#define PAH831X_B2__ECG_ADC_DEBUG_PATTERN_ON_2__MSK     (0xFF)\r
+\r
+// PAH831X_B2__ECG_ADC_DEBUG_PATTERN_OFF__ADDR (0x1B), R/W\r
+#define PAH831X_B2__ECG_ADC_DEBUG_PATTERN_OFF__SIZE     (2)\r
+// PAH831X_B2__ECG_ADC_DEBUG_PATTERN_OFF_1__ADDR (0x1B), R/W\r
+#define PAH831X_B2__ECG_ADC_DEBUG_PATTERN_OFF_1__POS    (0)\r
+#define PAH831X_B2__ECG_ADC_DEBUG_PATTERN_OFF_1__LEN    (8)\r
+#define PAH831X_B2__ECG_ADC_DEBUG_PATTERN_OFF_1__MSK    (0xFF)\r
+// PAH831X_B2__ECG_ADC_DEBUG_PATTERN_OFF_2__ADDR (0x1C), R/W\r
+#define PAH831X_B2__ECG_ADC_DEBUG_PATTERN_OFF_2__POS    (0)\r
+#define PAH831X_B2__ECG_ADC_DEBUG_PATTERN_OFF_2__LEN    (8)\r
+#define PAH831X_B2__ECG_ADC_DEBUG_PATTERN_OFF_2__MSK    (0xFF)\r
+\r
+// PAH831X_B2__PPG1_E_ADCDATA_ON__ADDR (0x32), R\r
+#define PAH831X_B2__PPG1_E_ADCDATA_ON__SIZE     (2)\r
+\r
+// PAH831X_B2__PPG1_E_ADCDATA_OFF__ADDR (0x34), R\r
+#define PAH831X_B2__PPG1_E_ADCDATA_OFF__SIZE    (2)\r
+\r
+// PAH831X_B2__PPG2_E_ADCDATA_ON__ADDR (0x36), R\r
+#define PAH831X_B2__PPG2_E_ADCDATA_ON__SIZE     (2)\r
+\r
+// PAH831X_B2__PPG2_E_ADCDATA_OFF__ADDR (0x38), R\r
+#define PAH831X_B2__PPG2_E_ADCDATA_OFF__SIZE    (2)\r
+\r
+// PAH831X_B2__PPG1_F_ADCDATA_ON__ADDR (0x3A), R\r
+#define PAH831X_B2__PPG1_F_ADCDATA_ON__SIZE     (2)\r
+\r
+// PAH831X_B2__PPG1_F_ADCDATA_OFF__ADDR (0x3C), R\r
+#define PAH831X_B2__PPG1_F_ADCDATA_OFF__SIZE    (2)\r
+\r
+// PAH831X_B2__PPG2_F_ADCDATA_ON__ADDR (0x3E), R\r
+#define PAH831X_B2__PPG2_F_ADCDATA_ON__SIZE     (2)\r
+\r
+// PAH831X_B2__PPG2_F_ADCDATA_OFF__ADDR (0x40), R\r
+#define PAH831X_B2__PPG2_F_ADCDATA_OFF__SIZE    (2)\r
+\r
+// PAH831X_B2__GPIO_0_SEL__ADDR (0x4A), R/W\r
+#define PAH831X_B2__GPIO_0_SEL__POS     (0)\r
+#define PAH831X_B2__GPIO_0_SEL__LEN     (6)\r
+#define PAH831X_B2__GPIO_0_SEL__MSK     (0x3F)\r
+\r
+// PAH831X_B2__GPIO_1_SEL__ADDR (0x4B), R/W\r
+#define PAH831X_B2__GPIO_1_SEL__POS     (0)\r
+#define PAH831X_B2__GPIO_1_SEL__LEN     (6)\r
+#define PAH831X_B2__GPIO_1_SEL__MSK     (0x3F)\r
+\r
+// PAH831X_B2__GPIO_2_SEL__ADDR (0x4C), R/W\r
+#define PAH831X_B2__GPIO_2_SEL__POS     (0)\r
+#define PAH831X_B2__GPIO_2_SEL__LEN     (6)\r
+#define PAH831X_B2__GPIO_2_SEL__MSK     (0x3F)\r
+\r
+// PAH831X_B2__GPIO_3_SEL__ADDR (0x4D), R/W\r
+#define PAH831X_B2__GPIO_3_SEL__POS     (0)\r
+#define PAH831X_B2__GPIO_3_SEL__LEN     (6)\r
+#define PAH831X_B2__GPIO_3_SEL__MSK     (0x3F)\r
+\r
+// PAH831X_B2__GPIO_4_SEL__ADDR (0x4E), R/W\r
+#define PAH831X_B2__GPIO_4_SEL__POS     (0)\r
+#define PAH831X_B2__GPIO_4_SEL__LEN     (6)\r
+#define PAH831X_B2__GPIO_4_SEL__MSK     (0x3F)\r
+\r
+// PAH831X_B2__GPIO_5_SEL__ADDR (0x4F), R/W\r
+#define PAH831X_B2__GPIO_5_SEL__POS     (0)\r
+#define PAH831X_B2__GPIO_5_SEL__LEN     (6)\r
+#define PAH831X_B2__GPIO_5_SEL__MSK     (0x3F)\r
+\r
+// PAH831X_B2__PPG1_A_ADCDATA_ON__ADDR (0x50), R\r
+#define PAH831X_B2__PPG1_A_ADCDATA_ON__SIZE     (2)\r
+\r
+// PAH831X_B2__PPG1_A_ADCDATA_OFF__ADDR (0x52), R\r
+#define PAH831X_B2__PPG1_A_ADCDATA_OFF__SIZE    (2)\r
+\r
+// PAH831X_B2__PPG2_A_ADCDATA_ON__ADDR (0x54), R\r
+#define PAH831X_B2__PPG2_A_ADCDATA_ON__SIZE     (2)\r
+\r
+// PAH831X_B2__PPG2_A_ADCDATA_OFF__ADDR (0x56), R\r
+#define PAH831X_B2__PPG2_A_ADCDATA_OFF__SIZE    (2)\r
+\r
+// PAH831X_B2__PPG1_B_ADCDATA_ON__ADDR (0x58), R\r
+#define PAH831X_B2__PPG1_B_ADCDATA_ON__SIZE     (2)\r
+\r
+// PAH831X_B2__PPG1_B_ADCDATA_OFF__ADDR (0x5A), R\r
+#define PAH831X_B2__PPG1_B_ADCDATA_OFF__SIZE    (2)\r
+\r
+// PAH831X_B2__PPG2_B_ADCDATA_ON__ADDR (0x5C), R\r
+#define PAH831X_B2__PPG2_B_ADCDATA_ON__SIZE     (2)\r
+\r
+// PAH831X_B2__PPG2_B_ADCDATA_OFF__ADDR (0x5E), R\r
+#define PAH831X_B2__PPG2_B_ADCDATA_OFF__SIZE    (2)\r
+\r
+// PAH831X_B2__PPG1_C_ADCDATA_ON__ADDR (0x60), R\r
+#define PAH831X_B2__PPG1_C_ADCDATA_ON__SIZE     (2)\r
+\r
+// PAH831X_B2__PPG1_C_ADCDATA_OFF__ADDR (0x62), R\r
+#define PAH831X_B2__PPG1_C_ADCDATA_OFF__SIZE    (2)\r
+\r
+// PAH831X_B2__PPG2_C_ADCDATA_ON__ADDR (0x64), R\r
+#define PAH831X_B2__PPG2_C_ADCDATA_ON__SIZE     (2)\r
+\r
+// PAH831X_B2__PPG2_C_ADCDATA_OFF__ADDR (0x66), R\r
+#define PAH831X_B2__PPG2_C_ADCDATA_OFF__SIZE    (2)\r
+\r
+// PAH831X_B2__PPG1_D_ADCDATA_ON__ADDR (0x68), R\r
+#define PAH831X_B2__PPG1_D_ADCDATA_ON__SIZE     (2)\r
+\r
+// PAH831X_B2__PPG1_D_ADCDATA_OFF__ADDR (0x6A), R\r
+#define PAH831X_B2__PPG1_D_ADCDATA_OFF__SIZE    (2)\r
+\r
+// PAH831X_B2__PPG2_D_ADCDATA_ON__ADDR (0x6C), R\r
+#define PAH831X_B2__PPG2_D_ADCDATA_ON__SIZE     (2)\r
+\r
+// PAH831X_B2__PPG2_D_ADCDATA_OFF__ADDR (0x6E), R\r
+#define PAH831X_B2__PPG2_D_ADCDATA_OFF__SIZE    (2)\r
+\r
+// PAH831X_B3__POWERDN__ADDR (0x01), R/W\r
+#define PAH831X_B3__POWERDN__POWER_UP       (0x00)\r
+#define PAH831X_B3__POWERDN__POWER_DOWN     (0x01)\r
+\r
+// PAH831X_B3__PWRSV_SEL__ADDR (0x0B), R/W\r
+#define PAH831X_B3__PWRSV_SEL__OSC_4M_ENH__POS      (0)\r
+#define PAH831X_B3__PWRSV_SEL__PMU_V2I_ENH__POS     (1)\r
+#define PAH831X_B3__PWRSV_SEL__BG_ENH__POS          (2)\r
+#define PAH831X_B3__PWRSV_SEL__PPG2_AMBC_ENH__POS   (4)\r
+#define PAH831X_B3__PWRSV_SEL__PPG1_AMBC_ENH__POS   (5)\r
+#define PAH831X_B3__PWRSV_SEL__ENABLE_OSC_4M        (0x36)\r
+#define PAH831X_B3__PWRSV_SEL__DISABLE_OSC_4M       (0x37)\r
+\r
+// PAH831X_B3__CLK__ADDR (0x50), R/W\r
+#define PAH831X_B3__CLK__ENH_EFUSE_CLK__POS         (0)\r
+#define PAH831X_B3__CLK__ENH_TEST_CLK__POS          (1)\r
+#define PAH831X_B3__CLK__ENH_TG_CLK__POS            (2)\r
+#define PAH831X_B3__CLK__ENH_LPO_CLK__POS           (3)\r
+#define PAH831X_B3__CLK__MANUAL_EFUSE_CLK__POS      (4)\r
+#define PAH831X_B3__CLK__MANUAL_TEST_CLK__POS       (5)\r
+#define PAH831X_B3__CLK__MANUAL_TG_CLK__POS         (6)\r
+#define PAH831X_B3__CLK__MANUAL_LPO_CLK__POS        (7)\r
+#define PAH831X_B3__CLK__ENABLE_CLK                 (0xFF)\r
+#define PAH831X_B3__CLK__DISABLE_CLK                (0x00)\r
+\r
+// PAH831X_B3__GPIO__ADDR (0x52), R/W\r
+#define PAH831X_B3__GPIO__18V_ENL__POS              (0)\r
+#define PAH831X_B3__GPIO__18V_ENL__LEN              (1)\r
+#define PAH831X_B3__GPIO__18V_ENL__MSK              (0x01)\r
+#define PAH831X_B3__GPIO__DRV__POS                  (1)\r
+#define PAH831X_B3__GPIO__DRV__LEN                  (2)\r
+#define PAH831X_B3__GPIO__DRV__MSK                  (0x06)\r
+#define PAH831X_B3__GPIO__1_OPEN_DRAIN_ENH__POS     (3)\r
+#define PAH831X_B3__GPIO__1_OPEN_DRAIN_ENH__LEN     (1)\r
+#define PAH831X_B3__GPIO__1_OPEN_DRAIN_ENH__MSK     (0x08)\r
+#define PAH831X_B3__GPIO__2_OPEN_DRAIN_ENH__POS     (4)\r
+#define PAH831X_B3__GPIO__2_OPEN_DRAIN_ENH__LEN     (1)\r
+#define PAH831X_B3__GPIO__2_OPEN_DRAIN_ENH__MSK     (0x10)\r
+\r
+// PAH831X_B3__EXT_CLK__ADDR (0x54), R/W\r
+#define PAH831X_B3__EXT_CLK__ENABLE_32K_CLK_SEL     (0x14)\r
+#define PAH831X_B3__EXT_CLK__DISABLE_32K_CLK_SEL    (0x10)\r
+\r
+// PAH831X_B3__I2C__ADDR (0x56), R/W\r
+#define PAH831X_B3__I2C__18V_ENL__POS       (0)\r
+#define PAH831X_B3__I2C__18V_ENL__LEN       (1)\r
+#define PAH831X_B3__I2C__18V_ENL__MSK       (0x01)\r
+#define PAH831X_B3__I2C__DRV__POS           (1)\r
+#define PAH831X_B3__I2C__DRV__LEN           (2)\r
+#define PAH831X_B3__I2C__DRV__MSK           (0x06)\r
+\r
+// PAH831X_B3__GPIO_0__ADDR (0x58), R/W\r
+#define PAH831X_B3__GPIO_0__PULLH_ENH__POS  (0)\r
+#define PAH831X_B3__GPIO_0__PULLH_ENH__LEN  (1)\r
+#define PAH831X_B3__GPIO_0__PULLH_ENH__MSK  (0x01)\r
+#define PAH831X_B3__GPIO_0__PULLL_ENH__POS  (1)\r
+#define PAH831X_B3__GPIO_0__PULLL_ENH__LEN  (1)\r
+#define PAH831X_B3__GPIO_0__PULLL_ENH__MSK  (0x02)\r
+#define PAH831X_B3__GPIO_0__OEB__POS        (2)\r
+#define PAH831X_B3__GPIO_0__OEB__LEN        (1)\r
+#define PAH831X_B3__GPIO_0__OEB__MSK        (0x04)\r
+#define PAH831X_B3__GPIO_0__IEB__POS        (3)\r
+#define PAH831X_B3__GPIO_0__IEB__LEN        (1)\r
+#define PAH831X_B3__GPIO_0__IEB__MSK        (0x08)\r
+#define PAH831X_B3__GPIO_0__ENH__POS        (4)\r
+#define PAH831X_B3__GPIO_0__ENH__LEN        (1)\r
+#define PAH831X_B3__GPIO_0__ENH__MSK        (0x10)\r
+#define PAH831X_B3__GPIO_0__18V_ENL__POS    (5)\r
+#define PAH831X_B3__GPIO_0__18V_ENL__LEN    (1)\r
+#define PAH831X_B3__GPIO_0__18V_ENL__MSK    (0x20)\r
+#define PAH831X_B3__GPIO_0__DEG__POS        (6)\r
+#define PAH831X_B3__GPIO_0__DEG__LEN        (2)\r
+#define PAH831X_B3__GPIO_0__DEG__MSK        (0xC0)\r
+\r
+// PAH831X_B3__GPIO_1__ADDR (0x59), R/W\r
+#define PAH831X_B3__GPIO_1__PULLH_ENH__POS  (0)\r
+#define PAH831X_B3__GPIO_1__PULLH_ENH__LEN  (1)\r
+#define PAH831X_B3__GPIO_1__PULLH_ENH__MSK  (0x01)\r
+#define PAH831X_B3__GPIO_1__PULLL_ENH__POS  (1)\r
+#define PAH831X_B3__GPIO_1__PULLL_ENH__LEN  (1)\r
+#define PAH831X_B3__GPIO_1__PULLL_ENH__MSK  (0x02)\r
+#define PAH831X_B3__GPIO_1__OEB__POS        (2)\r
+#define PAH831X_B3__GPIO_1__OEB__LEN        (1)\r
+#define PAH831X_B3__GPIO_1__OEB__MSK        (0x04)\r
+#define PAH831X_B3__GPIO_1__IEB__POS        (3)\r
+#define PAH831X_B3__GPIO_1__IEB__LEN        (1)\r
+#define PAH831X_B3__GPIO_1__IEB__MSK        (0x08)\r
+#define PAH831X_B3__GPIO_1__ENH__POS        (4)\r
+#define PAH831X_B3__GPIO_1__ENH__LEN        (1)\r
+#define PAH831X_B3__GPIO_1__ENH__MSK        (0x10)\r
+\r
+// PAH831X_B3__GPIO_2__ADDR (0x5A), R/W\r
+#define PAH831X_B3__GPIO_2__PULLH_ENH__POS  (0)\r
+#define PAH831X_B3__GPIO_2__PULLH_ENH__LEN  (1)\r
+#define PAH831X_B3__GPIO_2__PULLH_ENH__MSK  (0x01)\r
+#define PAH831X_B3__GPIO_2__PULLL_ENH__POS  (1)\r
+#define PAH831X_B3__GPIO_2__PULLL_ENH__LEN  (1)\r
+#define PAH831X_B3__GPIO_2__PULLL_ENH__MSK  (0x02)\r
+#define PAH831X_B3__GPIO_2__OEB__POS        (2)\r
+#define PAH831X_B3__GPIO_2__OEB__LEN        (1)\r
+#define PAH831X_B3__GPIO_2__OEB__MSK        (0x04)\r
+#define PAH831X_B3__GPIO_2__IEB__POS        (3)\r
+#define PAH831X_B3__GPIO_2__IEB__LEN        (1)\r
+#define PAH831X_B3__GPIO_2__IEB__MSK        (0x08)\r
+#define PAH831X_B3__GPIO_2__ENH__POS        (4)\r
+#define PAH831X_B3__GPIO_2__ENH__LEN        (1)\r
+#define PAH831X_B3__GPIO_2__ENH__MSK        (0x10)\r
+\r
+// PAH831X_B3__GPIO_3__ADDR (0x5B), R/W\r
+#define PAH831X_B3__GPIO_3__PULLH_ENH__POS  (0)\r
+#define PAH831X_B3__GPIO_3__PULLH_ENH__LEN  (1)\r
+#define PAH831X_B3__GPIO_3__PULLH_ENH__MSK  (0x01)\r
+#define PAH831X_B3__GPIO_3__PULLL_ENH__POS  (1)\r
+#define PAH831X_B3__GPIO_3__PULLL_ENH__LEN  (1)\r
+#define PAH831X_B3__GPIO_3__PULLL_ENH__MSK  (0x02)\r
+#define PAH831X_B3__GPIO_3__OEB__POS        (2)\r
+#define PAH831X_B3__GPIO_3__OEB__LEN        (1)\r
+#define PAH831X_B3__GPIO_3__OEB__MSK        (0x04)\r
+#define PAH831X_B3__GPIO_3__IEB__POS        (3)\r
+#define PAH831X_B3__GPIO_3__IEB__LEN        (1)\r
+#define PAH831X_B3__GPIO_3__IEB__MSK        (0x08)\r
+#define PAH831X_B3__GPIO_3__ENH__POS        (4)\r
+#define PAH831X_B3__GPIO_3__ENH__LEN        (1)\r
+#define PAH831X_B3__GPIO_3__ENH__MSK        (0x10)\r
+\r
+// PAH831X_B3__GPIO_4__ADDR (0x5C), R/W\r
+#define PAH831X_B3__GPIO_4__PULLH_ENH__POS  (0)\r
+#define PAH831X_B3__GPIO_4__PULLH_ENH__LEN  (1)\r
+#define PAH831X_B3__GPIO_4__PULLH_ENH__MSK  (0x01)\r
+#define PAH831X_B3__GPIO_4__PULLL_ENH__POS  (1)\r
+#define PAH831X_B3__GPIO_4__PULLL_ENH__LEN  (1)\r
+#define PAH831X_B3__GPIO_4__PULLL_ENH__MSK  (0x02)\r
+#define PAH831X_B3__GPIO_4__OEB__POS        (2)\r
+#define PAH831X_B3__GPIO_4__OEB__LEN        (1)\r
+#define PAH831X_B3__GPIO_4__OEB__MSK        (0x04)\r
+#define PAH831X_B3__GPIO_4__IEB__POS        (3)\r
+#define PAH831X_B3__GPIO_4__IEB__LEN        (1)\r
+#define PAH831X_B3__GPIO_4__IEB__MSK        (0x08)\r
+#define PAH831X_B3__GPIO_4__ENH__POS        (4)\r
+#define PAH831X_B3__GPIO_4__ENH__LEN        (1)\r
+#define PAH831X_B3__GPIO_4__ENH__MSK        (0x10)\r
+\r
+// PAH831X_B3__GPIO_5__ADDR (0x5D), R/W\r
+#define PAH831X_B3__GPIO_5__PULLH_ENH__POS  (0)\r
+#define PAH831X_B3__GPIO_5__PULLH_ENH__LEN  (1)\r
+#define PAH831X_B3__GPIO_5__PULLH_ENH__MSK  (0x01)\r
+#define PAH831X_B3__GPIO_5__PULLL_ENH__POS  (1)\r
+#define PAH831X_B3__GPIO_5__PULLL_ENH__LEN  (1)\r
+#define PAH831X_B3__GPIO_5__PULLL_ENH__MSK  (0x02)\r
+#define PAH831X_B3__GPIO_5__OEB__POS        (2)\r
+#define PAH831X_B3__GPIO_5__OEB__LEN        (1)\r
+#define PAH831X_B3__GPIO_5__OEB__MSK        (0x04)\r
+#define PAH831X_B3__GPIO_5__IEB__POS        (3)\r
+#define PAH831X_B3__GPIO_5__IEB__LEN        (1)\r
+#define PAH831X_B3__GPIO_5__IEB__MSK        (0x08)\r
+#define PAH831X_B3__GPIO_5__ENH__POS        (4)\r
+#define PAH831X_B3__GPIO_5__ENH__LEN        (1)\r
+#define PAH831X_B3__GPIO_5__ENH__MSK        (0x10)\r
+\r
+// PAH831X_B3__RESET__ADDR (0x70), W\r
+#define PAH831X_B3__RESET__GLOBAL           (0x01)\r
+#define PAH831X_B3__RESET__WD               (0x02)\r
+#define PAH831X_B3__RESET__TG               (0x04)\r
+#define PAH831X_B3__RESET__TEST             (0x08)\r
+#define PAH831X_B3__RESET__LP               (0x10)\r
+#define PAH831X_B3__RESET__REG_BANK         (0x20)\r
+\r
+// PAH831X_B4__PPG_CH_A_LEDDAC_1__ADDR (0x00), R/W\r
+#define PAH831X_B4__PPG_CH_A_LEDDAC_1__REG_CAL__POS (0)\r
+#define PAH831X_B4__PPG_CH_A_LEDDAC_1__REG_CAL__LEN (4)\r
+#define PAH831X_B4__PPG_CH_A_LEDDAC_1__REG_CAL__MSK (0x0F)\r
+\r
+// PAH831X_B4__PPG_CH_B_LEDDAC_1__ADDR (0x03), R/W\r
+#define PAH831X_B4__PPG_CH_B_LEDDAC_1__REG_CAL__POS (0)\r
+#define PAH831X_B4__PPG_CH_B_LEDDAC_1__REG_CAL__LEN (4)\r
+#define PAH831X_B4__PPG_CH_B_LEDDAC_1__REG_CAL__MSK (0x0F)\r
+\r
+// PAH831X_B4__PPG_CH_C_LEDDAC_1__ADDR (0x03), R/W\r
+#define PAH831X_B4__PPG_CH_C_LEDDAC_1__REG_CAL__POS (0)\r
+#define PAH831X_B4__PPG_CH_C_LEDDAC_1__REG_CAL__LEN (4)\r
+#define PAH831X_B4__PPG_CH_C_LEDDAC_1__REG_CAL__MSK (0x0F)\r
+\r
+// PAH831X_B4__PPG_CH_D_LEDDAC_1__ADDR (0x03), R/W\r
+#define PAH831X_B4__PPG_CH_D_LEDDAC_1__REG_CAL__POS (0)\r
+#define PAH831X_B4__PPG_CH_D_LEDDAC_1__REG_CAL__LEN (4)\r
+#define PAH831X_B4__PPG_CH_D_LEDDAC_1__REG_CAL__MSK (0x0F)\r
+\r
+// PAH831X_B4__PPG_CH_E_LEDDAC_1__ADDR (0x03), R/W\r
+#define PAH831X_B4__PPG_CH_E_LEDDAC_1__REG_CAL__POS (0)\r
+#define PAH831X_B4__PPG_CH_E_LEDDAC_1__REG_CAL__LEN (4)\r
+#define PAH831X_B4__PPG_CH_E_LEDDAC_1__REG_CAL__MSK (0x0F)\r
+\r
+// PAH831X_B4__PPG_CH_F_LEDDAC_1__ADDR (0x03), R/W\r
+#define PAH831X_B4__PPG_CH_F_LEDDAC_1__REG_CAL__POS (0)\r
+#define PAH831X_B4__PPG_CH_F_LEDDAC_1__REG_CAL__LEN (4)\r
+#define PAH831X_B4__PPG_CH_F_LEDDAC_1__REG_CAL__MSK (0x0F)\r
+\r
+// PAH831X_B4__PPG_CH_T_LEDDAC_1__ADDR (0x03), R/W\r
+#define PAH831X_B4__PPG_CH_T_LEDDAC_1__REG_CAL__POS (0)\r
+#define PAH831X_B4__PPG_CH_T_LEDDAC_1__REG_CAL__LEN (4)\r
+#define PAH831X_B4__PPG_CH_T_LEDDAC_1__REG_CAL__MSK (0x0F)\r
+\r
+// PAH831X_B4__PPG_CH_A_LEDDAC_2__ADDR (0x00), R/W\r
+#define PAH831X_B4__PPG_CH_A_LEDDAC_2__REG_CAL__POS (0)\r
+#define PAH831X_B4__PPG_CH_A_LEDDAC_2__REG_CAL__LEN (4)\r
+#define PAH831X_B4__PPG_CH_A_LEDDAC_2__REG_CAL__MSK (0x0F)\r
+\r
+// PAH831X_B4__PPG_CH_B_LEDDAC_2__ADDR (0x00), R/W\r
+#define PAH831X_B4__PPG_CH_B_LEDDAC_2__REG_CAL__POS (0)\r
+#define PAH831X_B4__PPG_CH_B_LEDDAC_2__REG_CAL__LEN (4)\r
+#define PAH831X_B4__PPG_CH_B_LEDDAC_2__REG_CAL__MSK (0x0F)\r
+\r
+// PAH831X_B4__PPG_CH_C_LEDDAC_2__ADDR (0x00), R/W\r
+#define PAH831X_B4__PPG_CH_C_LEDDAC_2__REG_CAL__POS (0)\r
+#define PAH831X_B4__PPG_CH_C_LEDDAC_2__REG_CAL__LEN (4)\r
+#define PAH831X_B4__PPG_CH_C_LEDDAC_2__REG_CAL__MSK (0x0F)\r
+\r
+// PAH831X_B4__PPG_CH_D_LEDDAC_2__ADDR (0x00), R/W\r
+#define PAH831X_B4__PPG_CH_D_LEDDAC_2__REG_CAL__POS (0)\r
+#define PAH831X_B4__PPG_CH_D_LEDDAC_2__REG_CAL__LEN (4)\r
+#define PAH831X_B4__PPG_CH_D_LEDDAC_2__REG_CAL__MSK (0x0F)\r
+\r
+// PAH831X_B4__PPG_CH_E_LEDDAC_2__ADDR (0x00), R/W\r
+#define PAH831X_B4__PPG_CH_E_LEDDAC_2__REG_CAL__POS (0)\r
+#define PAH831X_B4__PPG_CH_E_LEDDAC_2__REG_CAL__LEN (4)\r
+#define PAH831X_B4__PPG_CH_E_LEDDAC_2__REG_CAL__MSK (0x0F)\r
+\r
+// PAH831X_B4__PPG_CH_F_LEDDAC_2__ADDR (0x00), R/W\r
+#define PAH831X_B4__PPG_CH_F_LEDDAC_2__REG_CAL__POS (0)\r
+#define PAH831X_B4__PPG_CH_F_LEDDAC_2__REG_CAL__LEN (4)\r
+#define PAH831X_B4__PPG_CH_F_LEDDAC_2__REG_CAL__MSK (0x0F)\r
+\r
+// PAH831X_B4__PPG_CH_T_LEDDAC_2__ADDR (0x00), R/W\r
+#define PAH831X_B4__PPG_CH_T_LEDDAC_2__REG_CAL__POS (0)\r
+#define PAH831X_B4__PPG_CH_T_LEDDAC_2__REG_CAL__LEN (4)\r
+#define PAH831X_B4__PPG_CH_T_LEDDAC_2__REG_CAL__MSK (0x0F)\r
+\r
+// PAH831X_B4__PPG_LEDDAC_MANUAL__ADDR (0x2C), R/W\r
+#define PAH831X_B4__PPG_LEDDAC_MANUAL__POS  (0)\r
+#define PAH831X_B4__PPG_LEDDAC_MANUAL__LEN  (1)\r
+#define PAH831X_B4__PPG_LEDDAC_MANUAL__MSK  (0x01)\r
+\r
+//---------------- Common ----------------\r
+#define PAH831X_B4__PPG_CH_X_LEDDAC_Y__REG_CAL__POS (0)\r
+#define PAH831X_B4__PPG_CH_X_LEDDAC_Y__REG_CAL__LEN (4)\r
+#define PAH831X_B4__PPG_CH_X_LEDDAC_Y__REG_CAL__MSK (0x0F)\r
diff --git a/code/sdk/zhihui/drivers/ppg/pah831x/pah_sensor/pah831x_main.c b/code/sdk/zhihui/drivers/ppg/pah831x/pah_sensor/pah831x_main.c
new file mode 100644 (file)
index 0000000..957d5e7
--- /dev/null
@@ -0,0 +1,1993 @@
+#include "pah831x.h"\r
+//#include "pah831x_reg_default.h"\r
+\r
+#ifdef PAH8311_2LED_TYPE\r
+//#include "pah831x_reg_default_note_0109_2LED_20250313.h"\r
+#include "pah831x_reg_default_note_0109_2LED_20251226.h"\r
+#endif\r
+#ifdef PAH8311_1LED_TYPE\r
+#include "pah831x_reg_default_note_0109_1LED.h"\r
+#endif\r
+\r
+#include "pah831x_main.h"\r
+#include "pah831x_comm.h"\r
+#include "cmsis_os2.h"\r
+// c\r
+#include <stdarg.h>\r
+#include <stdio.h>\r
+#include <stdbool.h>\r
+#include <stdlib.h>\r
+\r
+#ifdef SUPPORT_CYWEE_SERVICE\r
+#include "cywee_hal.h"\r
+#include "cywee_service.h"\r
+#endif\r
+\r
+#ifdef SUPPORT_PPG_SERVICE\r
+#include "ppg_service.h"\r
+#endif\r
+#include "pah831x_factory_test_v3.h"\r
+#include "pah_ecg_afib_alg.h"\r
+#include "pah_ecg_raw.h"\r
+//============================================================================\r
+// Macro\r
+//============================================================================\r
+#define UNUSED_VAR(var)             (void)(var)\r
+\r
+// #define DEBUG_PRINT(format, ...)    pah_print(format, ##__VA_ARGS__)\r
+//============================================================================\r
+// Option\r
+//============================================================================\r
+#define ENABLE_PPG_SENSOR (0)\r
+#define ENABLE_ECG_SENSOR (1)\r
+\r
+//============================================================================\r
+// Develop Option\r
+//============================================================================\r
+#define ENABLE_PRINT_PPG_EVENT_DATA (1)\r
+#define ENABLE_PRINT_ECG_EVENT_DATA (1)\r
+#define ENABLE_PRINT_TOUCH_EVENT_DATA (1)\r
+\r
+#define FILEPATH "user/userdata/bp_cali_data.bin"\r
+\r
+\r
+//============================================================================\r
+// Definitions\r
+//============================================================================\r
+typedef enum\r
+{\r
+    TOUCH_STATUS__UNKNOWN,\r
+    TOUCH_STATUS__ON,\r
+    TOUCH_STATUS__OFF,\r
+} touch_status;\r
+\r
+\r
+typedef struct\r
+{\r
+    bool touch_is_enabled ;\r
+    bool ppg_is_enabled ;\r
+    bool ecg_is_enabled ;\r
+} sensor_config;\r
+\r
+\r
+typedef struct\r
+{\r
+    volatile bool has_interrupt;\r
+    volatile uint64_t interrupt_timestamp;\r
+\r
+    pah831x core;\r
+    uint64_t prev_task_timestamp;\r
+    uint64_t task_timestamp;\r
+    \r
+    // ppg\r
+    uint64_t ppg_prev_timestamp;\r
+    \r
+    // ecg\r
+    uint64_t ecg_prev_timestamp;\r
+    \r
+    // touch\r
+    touch_status touch_status;\r
+    //Dri or Polling\r
+    uint8_t work_mode;\r
+    \r
+    //operate_mode\r
+    uint8_t operate_mode;\r
+\r
+    sensor_config config;\r
+\r
+    uint8_t ppg_reg_setting ;\r
+    uint8_t ecg_reg_setting;\r
+    \r
+    uint8_t led_dac_check_count ;\r
+    bool led_dac_check_flag  ;\r
+    bool led_dac_check_status  ;\r
+    bool led_dac_check_powersave  ;\r
+    uint32_t led_dac_check_period ;\r
+    uint8_t afe_gain_flag;\r
+//    bool ir_r_led_switch_enable  ;\r
+//    bool ir_r_led_switch_status ;\r
+//    bool ir_r_led_switch_new_status ;\r
+    float sample_period;\r
+    uint16_t interrupt_report_num;\r
+    \r
+} main_state;\r
+\r
+//============================================================================\r
+// Global variables\r
+//============================================================================\r
+static main_state _state;\r
+\r
+\r
+ppg_data_out _ppg_data_out ;\r
+ecg_data_out _ecg_data_out ;\r
+\r
+//uint8_t fifo_buffer[2000];\r
+uint8_t fifo_buffer[1500];\r
+\r
+uint32_t ppg_buffer[300];\r
+uint8_t ppg_dac_buffer[300];\r
+uint16_t adc_buf[24];\r
+\r
+#ifdef ENABLE_PAH831X_ECG_FUNCTION\r
+uint32_t ecg_buffer[350];\r
+uint8_t ecg_tag_buffer[350];\r
+#endif\r
+\r
+static int16_t acc_data[3*55];\r
+static uint16_t acc_num = 50;\r
+\r
+static int32_t factory_data = 0;\r
+static uint8_t work_mode = 0;\r
+static uint8_t wear_status = 0;\r
+\r
+static osTimerId_t g_pah831x_timer = NULL;\r
+\r
+static FILE *logFp = NULL;\r
+static uint8_t *log_swtich = 0;\r
+static int time_out = 200;\r
+static uint8_t time_cnt = 0;\r
+static uint8_t wear_cnt = 0;\r
+\r
+static int history_wear_status = -1;\r
+static uint8_t ppg_work_status = 0 ;\r
+static uint8_t ret_hrs = 0;\r
+static uint8_t ret_spo2 = 0;\r
+static uint8_t ret_hrv = 0;\r
+static uint8_t ret_wear = 0;\r
+static ecg_data_out _ecg_data_out_alg;\r
+\r
+static uint8_t bp_cali_cnt = 0;\r
+//void demo_pah831x(void);\r
+\r
+static bool sensor_basic_verification(main_state *this, pah_plat *plat);\r
+static bool verify_product_id(uint16_t product_id);\r
+\r
+static void start_ppg_ecg(main_state *this);\r
+static void start_touch(main_state *this);\r
+\r
+static void read_fifo_callback(void *user_data, uint8_t *fifo, uint16_t data_count, float read_size_ratio);\r
+static void send_fifo_data(main_state *this, uint8_t *fifo, uint16_t data_count, float read_size_ratio);\r
+static float update_sample_interval(main_state *this, uint64_t start_timestamp, uint64_t end_timestamp, uint32_t sample_num, float read_size_ratio);\r
+\r
+static void send_ppg_event(main_state *this, uint64_t timestamp, const pah831x_ppg_sample *ppg_sample);\r
+static void send_ecg_event(main_state *this, uint64_t timestamp, const pah831x_ecg_sample *ecg_sample);\r
+static void send_touch_event(main_state *this, uint64_t timestamp, const touch_status touch_status);\r
+\r
+\r
+static int32_t cvt24bit(uint32_t val)\r
+{\r
+    val &= 0xffffff;  // limit to 24 bits -- may not be necessary\r
+    if (val >= ((uint32_t)1 << 23))\r
+        return (int32_t)val - ((uint32_t)1 << 24);\r
+    else\r
+        return val;\r
+}\r
+\r
+\r
+void pah831x_sensor_init(void)\r
+{\r
+    memset(&_state, 0, sizeof(_state));\r
+    pah_plat plat = {\r
+        .comm.user_data         = &_state,\r
+        .comm.type              = PAH_PLAT_COMM_I2C,\r
+        .comm.max_length        = PXI_NRF_I2C_MAX_COMM_SIZE,\r
+    };\r
+    \r
+    if (!sensor_basic_verification(&_state, &plat))\r
+    {\r
+        DEBUG_PRINT("Failed to verify product_id");\r
+        return;\r
+    }\r
+    \r
+    pah831x_init_reg_setting init_reg_setting;\r
+    memset(&init_reg_setting, 0, sizeof(init_reg_setting));\r
+    PAH_REG_ARR_SETUP(init_reg_setting.init, PAH831X_REG_INIT);\r
+    PAH_REG_ARR_SETUP(init_reg_setting.deinit, PAH831X_REG_DEINIT);\r
+    pah831x_init(&_state.core, &plat, &init_reg_setting);\r
+    \r
+    pah831x_set_batch_period(&_state.core, REQ_BATCH_PERIOD);\r
+}\r
+\r
+\r
+\r
+\r
+void pah831x_sensor_start(uint8_t work_mode ,uint8_t operate_mode ,uint8_t ppg_reg_setting ,uint8_t ecg_reg_setting,uint16_t interrupt_report_num,float sample_period )\r
+{\r
+    \r
+    _state.work_mode=work_mode;\r
+    _state.operate_mode = operate_mode;\r
+    _state.ppg_reg_setting = ppg_reg_setting;\r
+    _state.ecg_reg_setting = ecg_reg_setting;\r
+    _state.sample_period   = sample_period ;\r
+    _state.interrupt_report_num = interrupt_report_num ;\r
+    uint32_t batch_period_ms = (uint32_t) (_state.sample_period*_state.interrupt_report_num);\r
+    pah831x_set_batch_period(&_state.core, batch_period_ms);\r
+    DEBUG_PRINT("batch_period_ms =%d ,sample_period =%f , interrupt_report_num =%d\n",batch_period_ms,_state.sample_period,_state.interrupt_report_num);\r
+\r
+    if(_state.operate_mode==PAH831X_INIT_AUTO_MODE)\r
+    {        \r
+        start_touch(&_state);\r
+        DEBUG_PRINT(" PAH831X_INIT_AUTO_MODE \n");\r
+\r
+    }else if(_state.operate_mode==PAH831X_INIT_ALWAYS_RUN)\r
+    {\r
+        start_ppg_ecg(&_state);\r
+        DEBUG_PRINT(" PAH831X_INIT_ALWAYS_RUN \n");\r
+    }else if(_state.operate_mode==PAH831X_INIT_TOUCH_ONLY)\r
+    {\r
+        start_touch(&_state);\r
+        DEBUG_PRINT(" PAH831X_INIT_TOUCH_ONLY \n");\r
+    }\r
+    _state.has_interrupt = false;\r
+    uint64_t now_timestamp = pxi_get_tick_count();\r
+    _state.prev_task_timestamp = now_timestamp;\r
+    _state.ppg_prev_timestamp = now_timestamp;\r
+    _state.ecg_prev_timestamp = now_timestamp;\r
+    _state.interrupt_timestamp = pxi_get_tick_count();\r
+    \r
+}\r
+\r
+ void disable_ppg_sensor(main_state *this)\r
+{\r
+    this->config.ppg_is_enabled=0;\r
+    start_ppg_ecg(this);\r
+}\r
+void disable_touch_sensor(main_state *this)\r
+{\r
+    this->config.touch_is_enabled=0;\r
+    start_touch(this);\r
+}\r
+\r
+\r
+void pah_sensor_stop(void)\r
+{\r
+//    disable_touch_sensor(&_state);\r
+//    disable_ppg_sensor(&_state);\r
+    pah831x_deinit(&_state.core);\r
+    _state.work_mode = PAH831X_WORK_IDLE ;\r
+}\r
+\r
+\r
+void pah831x_data_ready_interrupt(main_state *this)\r
+{\r
+    bool touch_status_changed = false;\r
+    if (_state.has_interrupt)\r
+    {\r
+        _state.has_interrupt = false;\r
+        \r
+        pah831x_int_flag int_flag;\r
+        pah831x_read_int_flag(&_state.core, &int_flag);\r
+        DEBUG_PRINT("int_flag(data[1],fifo,touch): 0x%02X, %d, %d,\n", int_flag.data[1], (int)PAH831X_HAS_FIFO_INT(int_flag), (int)PAH831X_HAS_TOUCH_INT(int_flag));\r
+        //uint16_t touch_value = 0 ;\r
+        //bool touch_flag = false;\r
+        pah831x_read_touch_flag(&_state.core,&_state.core.touch_flag);\r
+        pah831x_read_touch_value(&_state.core, &_state.core.touch_value);\r
+        DEBUG_PRINT("touch_flag= %d, touch_value =%d,\n",_state.core.touch_flag,_state.core.touch_value);\r
+        touch_status touch_status = TOUCH_STATUS__UNKNOWN;\r
+        if (PAH831X_HAS_TOUCH_INT(int_flag))\r
+        {\r
+            //touch_status touch_status = (int_flag.touch_flag > 0 ? TOUCH_STATUS__ON : TOUCH_STATUS__OFF);\r
+            touch_status = (int_flag.touch_flag > 0 ? TOUCH_STATUS__ON : TOUCH_STATUS__OFF);\r
+            if (_state.touch_status != touch_status)\r
+            {\r
+                _state.touch_status = touch_status;\r
+                touch_status_changed = true;\r
+                send_touch_event(&_state, _state.interrupt_timestamp, touch_status);\r
+            }\r
+        }\r
+        \r
+        if (PAH831X_HAS_FIFO_INT(int_flag))\r
+        {\r
+            uint16_t data_count = pah831x_read_fifo_data_count(&_state.core);\r
+\r
+            if (data_count > 0)\r
+            {\r
+                _state.task_timestamp = _state.interrupt_timestamp;\r
+                \r
+//                uint8_t buffer[254];\r
+                pah831x_read_fifo(&_state.core, fifo_buffer, sizeof(fifo_buffer), data_count, read_fifo_callback, &_state);\r
+                \r
+               \r
+//                uint16_t adc_buf[24];\r
+                uint16_t i = 0 ;\r
+                if(_state.ppg_reg_setting!=PAH831X_PPG_REG_SETTING_IDLE)                \r
+                {\r
+                    pah831x_extract_PPG_ADC(adc_buf);\r
+                    DEBUG_PRINT("ADC: ");\r
+                    for(i=0;i<24;i++)\r
+                    {\r
+                        DEBUG_PRINT(" %d ,",adc_buf[i]);\r
+                    }\r
+                    DEBUG_PRINT("\n");\r
+                }\r
+                if(_state.led_dac_check_flag==true)\r
+                {\r
+                    \r
+                    if((_state.led_dac_check_status==true)&& (this->touch_status == TOUCH_STATUS__ON))\r
+                    {    \r
+                        _state.led_dac_check_period+=_state.task_timestamp-_state.prev_task_timestamp;\r
+                        LOG_PRINT("_state.led_dac_check_period =%d\n", _state.led_dac_check_period);\r
+                        if(_state.led_dac_check_period > LED_DAC_CHECK_TIME)\r
+                        {\r
+                            uint8_t *ppg_dac_data= _ppg_data_out.ppg_dac_data ;\r
+                            uint16_t  ch_a_point = (_ppg_data_out.sample_num_per_ch-1)* _ppg_data_out.ch_num;   \r
+                            LOG_PRINT("CH_A DAC = %d ,ch_a_point =%d\n", ppg_dac_data[ch_a_point],ch_a_point);\r
+                            if(ppg_dac_data[ch_a_point]>=230)\r
+                            {\r
+                                LOG_PRINT("pah831x_update_ch_a_1000k\n");\r
+                                _state.afe_gain_flag = pah_AFE_GAIN_CHA_1000K ;\r
+                                pah831x_update_ch_a_1000k();\r
+                            }\r
+\r
+                            \r
+                            _state.led_dac_check_status=false ;\r
+                        }\r
+                    }else if(this->touch_status == TOUCH_STATUS__OFF) \r
+                    {\r
+                        \r
+                        _state.led_dac_check_status=true ;\r
+                        _state.led_dac_check_period = 0 ;\r
+                    }\r
+                }\r
+                \r
+    \r
+                \r
+                \r
+                _state.prev_task_timestamp = _state.task_timestamp;\r
+            }\r
+        }\r
+    \r
+        pah_ret ret = pah831x_task(&_state.core);\r
+        if (PAH_FAILED(ret))\r
+            DEBUG_PRINT("task() failed, ret: %d\n", ret);\r
+    }\r
+    if ((touch_status_changed)&&(_state.operate_mode==PAH831X_INIT_AUTO_MODE))\r
+    {\r
+        if (this->touch_status == TOUCH_STATUS__ON)\r
+        {\r
+            start_ppg_ecg(this);\r
+                       _state.has_interrupt = false;\r
+            uint64_t now_timestamp = pxi_get_tick_count();\r
+            this->prev_task_timestamp = now_timestamp;\r
+            this->ppg_prev_timestamp = now_timestamp;\r
+        }\r
+        else if (this->touch_status == TOUCH_STATUS__OFF)\r
+        {\r
+            start_touch(this);\r
+            DEBUG_PRINT("this->touch_status == TOUCH_STATUS__OFF\n" );\r
+        }\r
+    }\r
+}\r
+void pah831x_polling(main_state *this)\r
+{\r
+    bool touch_status_changed = false;\r
+    //if (_state.has_interrupt)\r
+    {\r
+        //_state.has_interrupt = false;\r
+        uint64_t now_timestamp;\r
+        \r
+        now_timestamp = pxi_get_tick_count();\r
+        pah831x_int_flag int_flag;\r
+        pah831x_read_int_flag(&_state.core, &int_flag);\r
+        DEBUG_PRINT("int_flag(data[1],fifo,touch): 0x%02X, %d, %d\n", int_flag.data[1], (int)PAH831X_HAS_FIFO_INT(int_flag), (int)PAH831X_HAS_TOUCH_INT(int_flag));\r
+        pah831x_read_touch_flag(&_state.core,&_state.core.touch_flag);\r
+        pah831x_read_touch_value(&_state.core, &_state.core.touch_value);\r
+        DEBUG_PRINT("touch_flag= %d, touch_value =%d ,\n",_state.core.touch_flag,_state.core.touch_value);\r
+        touch_status touch_status = TOUCH_STATUS__UNKNOWN;\r
+        //if (PAH831X_HAS_TOUCH_INT(int_flag))\r
+        {\r
+            //touch_status touch_status = (int_flag.touch_flag > 0 ? TOUCH_STATUS__ON : TOUCH_STATUS__OFF);\r
+            touch_status = (int_flag.touch_flag > 0 ? TOUCH_STATUS__ON : TOUCH_STATUS__OFF);\r
+            if (_state.touch_status != touch_status)\r
+            {\r
+                _state.touch_status = touch_status;\r
+                touch_status_changed = true;\r
+                send_touch_event(&_state, now_timestamp, touch_status);\r
+            }\r
+        }\r
+        \r
+        //if (PAH831X_HAS_FIFO_INT(int_flag))\r
+        {\r
+            uint16_t data_count = pah831x_read_fifo_data_count(&_state.core);\r
+            if (data_count > 0)\r
+            {\r
+                _state.task_timestamp = now_timestamp;\r
+                pah831x_polling_fifo_begin(&_state.core);\r
+                //uint8_t buffer[254];\r
+                pah831x_read_fifo(&_state.core, fifo_buffer, sizeof(fifo_buffer), data_count, read_fifo_callback, &_state);\r
+                \r
+                \r
+                uint16_t i = 0 ;                \r
+                if(_state.ppg_reg_setting!=PAH831X_PPG_REG_SETTING_IDLE)                \r
+                {\r
+                    pah831x_extract_PPG_ADC(adc_buf);\r
+                    DEBUG_PRINT("ADC: ");\r
+                    for(i=0;i<24;i++)\r
+                    {\r
+                        DEBUG_PRINT(" %d ,",adc_buf[i]);\r
+                    }\r
+                    DEBUG_PRINT("\n");\r
+                }\r
+                \r
+                if(_state.led_dac_check_flag==true) \r
+                {\r
+                    \r
+                    if((_state.led_dac_check_status==true)&& (this->touch_status == TOUCH_STATUS__ON))\r
+                    {    \r
+                        _state.led_dac_check_period+=_state.task_timestamp-_state.prev_task_timestamp;\r
+                        LOG_PRINT("_state.led_dac_check_period =%d\n", _state.led_dac_check_period);\r
+                        if(_state.led_dac_check_period > LED_DAC_CHECK_TIME)\r
+                        {\r
+                            uint8_t *ppg_dac_data= _ppg_data_out.ppg_dac_data ;\r
+                            uint16_t  ch_a_point = (_ppg_data_out.sample_num_per_ch-1)* _ppg_data_out.ch_num;   \r
+                            LOG_PRINT("CH_A DAC = %d ,ch_a_point =%d\n", ppg_dac_data[ch_a_point],ch_a_point);\r
+                            if(ppg_dac_data[ch_a_point]>=230)\r
+                            {\r
+                                LOG_PRINT("pah831x_update_ch_a_1000k\n");\r
+                                _state.afe_gain_flag = pah_AFE_GAIN_CHA_1000K ;\r
+                                pah831x_update_ch_a_1000k();\r
+                            }\r
+                            _state.led_dac_check_status=false ;\r
+                        }\r
+                    }else if(this->touch_status == TOUCH_STATUS__OFF) \r
+                    {\r
+                        _state.led_dac_check_status=true ;\r
+                        _state.led_dac_check_period = 0 ;\r
+                    }\r
+                }\r
+                \r
+\r
+                _state.prev_task_timestamp = _state.task_timestamp;\r
+            }\r
+        }\r
+    \r
+        pah_ret ret = pah831x_task(&_state.core);\r
+        if (PAH_FAILED(ret))\r
+            DEBUG_PRINT("task() failed, ret: %d", ret);\r
+    }\r
+    if ((touch_status_changed)&&(_state.operate_mode==PAH831X_INIT_AUTO_MODE))\r
+    {\r
+        if (this->touch_status == TOUCH_STATUS__ON)\r
+        {\r
+            start_ppg_ecg(this);\r
+            uint64_t now_timestamp = pxi_get_tick_count();\r
+            this->prev_task_timestamp = now_timestamp;\r
+            this->ppg_prev_timestamp = now_timestamp;\r
+        }\r
+        else if (this->touch_status == TOUCH_STATUS__OFF)\r
+        {\r
+            start_touch(this);\r
+            \r
+        }\r
+    }\r
+}\r
+\r
+void pah831x_sensor_task(void)\r
+{\r
+    if(_state.work_mode == PAH831X_WORK_DRI)\r
+    {\r
+        pah831x_data_ready_interrupt(&_state);\r
+    }\r
+    else if (_state.work_mode == PAH831X_WORK_POLLING)\r
+    {\r
+        pah831x_polling(&_state);\r
+    }\r
+}\r
+\r
+static bool sensor_basic_verification(main_state *this, pah_plat *plat)\r
+{\r
+    uint16_t product_id = 0;\r
+    int retry = 3;\r
+\r
+    do\r
+    {\r
+        pah831x_hal_soft_reset(plat);\r
+        pah831x_hal_verify_product_id(plat, &product_id);\r
+        if (verify_product_id(product_id))\r
+            break;\r
+        --retry;\r
+    } while (retry > 0);\r
+\r
+    DEBUG_PRINT("product_id = 0x%04X\n", product_id);\r
+    return verify_product_id(product_id);\r
+}\r
+\r
+static bool verify_product_id(uint16_t product_id)\r
+{\r
+    return product_id == 0x8311;\r
+}\r
+\r
+static void start_ppg_ecg(main_state *this)\r
+{\r
+    //pah831x_set_batch_period(&this->core, REQ_BATCH_PERIOD);\r
+    uint32_t batch_period_ms = (uint32_t) (this->sample_period*this->interrupt_report_num);\r
+    pah831x_set_batch_period(&_state.core, batch_period_ms);\r
+    //pah_reg_arr *ppg_reg_arr_ptr;\r
+    pah_reg_arr ppg_reg_arr;\r
+    \r
+    DEBUG_PRINT("ppg_reg_setting = %d , ecg_reg_setting = %d\n", this->ppg_reg_setting,this->ecg_reg_setting);\r
+    if(this->ppg_reg_setting!=0)\r
+    {\r
+       // pah_reg_arr ppg_reg_arr;\r
+        PAH_REG_ARR_SETUP(ppg_reg_arr, PAH831X_REG_PPG_1);\r
+        _state.afe_gain_flag = pah_AFE_GAIN_CHA_75K ;\r
+        this->led_dac_check_powersave=true;\r
+        switch (this->ppg_reg_setting)\r
+        {\r
+            case PAH831X_PPG_REG_SETTING_1 :\r
+                PAH_REG_ARR_SETUP(ppg_reg_arr, PAH831X_REG_PPG_1);\r
+//                this->led_dac_check_flag=true;\r
+//                this->led_dac_check_status=true;\r
+                break;\r
+            case PAH831X_PPG_REG_SETTING_2 :\r
+                PAH_REG_ARR_SETUP(ppg_reg_arr, PAH831X_REG_PPG_2);\r
+//                this->led_dac_check_flag=true;\r
+//                this->led_dac_check_status=true;\r
+                break;\r
+            case PAH831X_PPG_REG_SETTING_3 :\r
+                PAH_REG_ARR_SETUP(ppg_reg_arr, PAH831X_REG_PPG_3);\r
+                break;\r
+            case PAH831X_PPG_REG_SETTING_4 :\r
+                PAH_REG_ARR_SETUP(ppg_reg_arr, PAH831X_REG_PPG_4);\r
+                break;\r
+            case PAH831X_PPG_REG_SETTING_5 :\r
+                PAH_REG_ARR_SETUP(ppg_reg_arr, PAH831X_REG_PPG_5);\r
+                break;\r
+            case PAH831X_PPG_REG_SETTING_6 :\r
+                PAH_REG_ARR_SETUP(ppg_reg_arr, PAH831X_REG_PPG_6);\r
+                break;\r
+            case PAH831X_PPG_REG_SETTING_7 :\r
+                PAH_REG_ARR_SETUP(ppg_reg_arr, PAH831X_REG_PPG_7);\r
+                break;\r
+            case PAH831X_PPG_REG_SETTING_8 :\r
+                PAH_REG_ARR_SETUP(ppg_reg_arr, PAH831X_REG_PPG_8);\r
+            \r
+                break;\r
+            case PAH831X_PPG_REG_SETTING_9 :\r
+                PAH_REG_ARR_SETUP(ppg_reg_arr, PAH831X_REG_PPG_9);\r
+\r
+                break;\r
+            case PAH831X_PPG_REG_SETTING_10 :\r
+                PAH_REG_ARR_SETUP(ppg_reg_arr, PAH831X_REG_PPG_10);\r
+\r
+                break;\r
+            default:\r
+                DEBUG_PRINT("No Support Setting \n");\r
+                break;            \r
+        }\r
+        //ppg_reg_arr_ptr = &ppg_reg_arr;\r
+    }else\r
+    {\r
+       // ppg_reg_arr_ptr = NULL;\r
+        //ppg_reg_arr = NULL;\r
+        memset(&ppg_reg_arr, 0, sizeof(ppg_reg_arr));\r
+    }\r
+\r
+    //pah_reg_arr *ecg_reg_arr_ptr ;\r
+    pah_reg_arr ecg_reg_arr;\r
+    if(this->ecg_reg_setting)\r
+    {\r
+        //pah_reg_arr ecg_reg_arr;\r
+        switch (this->ecg_reg_setting)\r
+        {\r
+            case PAH831X_ECG_REG_SETTING_1 :\r
+                PAH_REG_ARR_SETUP(ecg_reg_arr, PAH831X_REG_ECG_1);\r
+                break;\r
+            case PAH831X_ECG_REG_SETTING_2 :\r
+                PAH_REG_ARR_SETUP(ecg_reg_arr, PAH831X_REG_ECG_2);\r
+                break;\r
+            case PAH831X_ECG_REG_SETTING_3 :\r
+                PAH_REG_ARR_SETUP(ecg_reg_arr, PAH831X_REG_ECG_3);\r
+                break;\r
+            case PAH831X_ECG_REG_SETTING_4 :\r
+                PAH_REG_ARR_SETUP(ecg_reg_arr, PAH831X_REG_ECG_4);\r
+                break;\r
+            case PAH831X_ECG_REG_SETTING_5 :\r
+                PAH_REG_ARR_SETUP(ecg_reg_arr, PAH831X_REG_ECG_5);\r
+                break;\r
+            default:\r
+                DEBUG_PRINT("No ECG Support Setting \n");\r
+                break;            \r
+        }\r
+       // ecg_reg_arr_ptr = &ecg_reg_arr;\r
+    }else\r
+    {\r
+       // ecg_reg_arr_ptr = NULL;\r
+        //ecg_reg_arr = NULL;\r
+        memset(&ecg_reg_arr, 0, sizeof(ecg_reg_arr));\r
+    }\r
+     //this->led_dac_check_flag=true;\r
+     this->led_dac_check_period = 0 ;\r
+    \r
+    this->config.ppg_is_enabled = true;\r
+\r
+    \r
+    //pah831x_start_2(&this->core, ppg_reg_arr_ptr, ecg_reg_arr_ptr);\r
+    pah831x_start_2(&this->core, &ppg_reg_arr, &ecg_reg_arr);\r
+}\r
+\r
+static void start_touch(main_state *this)\r
+{\r
+    pah_reg_arr touch_reg_arr;\r
+    this->config.ppg_is_enabled = 0;\r
+    PAH_REG_ARR_SETUP(touch_reg_arr, PAH831X_REG_TOUCH);\r
+    pah831x_start(&this->core, &touch_reg_arr);\r
+}\r
+\r
+\r
+static void read_fifo_callback(void *user_data, uint8_t *fifo, uint16_t data_count, float read_size_ratio)\r
+{\r
+    main_state *this = (main_state*)user_data;\r
+    \r
+    send_fifo_data(this, fifo, data_count, read_size_ratio);\r
+}\r
+\r
+static void send_fifo_data(main_state *this, uint8_t *fifo, uint16_t data_count, float read_size_ratio)\r
+{\r
+    uint16_t ppg_sample_num = 0;\r
+    uint16_t ecg_sample_num = 0;\r
+    uint16_t i = 0 ;\r
+    uint32_t duration = 0 ;\r
+    pah831x_extract_sample_num(fifo, data_count, &ppg_sample_num, &ecg_sample_num);\r
+    DEBUG_PRINT("sample_num(ppg,ecg): %d, %d\n", (int)ppg_sample_num, (int)ecg_sample_num);\r
+    \r
+    if (ppg_sample_num > 0 && ecg_sample_num == 0)\r
+    {\r
+        float ppg_sample_interval = update_sample_interval(this, this->prev_task_timestamp, this->task_timestamp, ppg_sample_num, read_size_ratio);        \r
+        \r
+        \r
+        if((this->task_timestamp)<(this->prev_task_timestamp))\r
+        {\r
+            duration = ppg_sample_num *  this->sample_period;\r
+        }else\r
+        {\r
+            duration =(uint32_t)(this->task_timestamp - this->prev_task_timestamp );\r
+        }\r
+        \r
+        _ppg_data_out.ppg_data_ready++;\r
+        _ppg_data_out.duration = duration;\r
+        _ppg_data_out.is_touched = _state.touch_status ;\r
+        _ppg_data_out.ch_num = this->core.ppg.ch_num  ;\r
+        _ppg_data_out.sample_num_per_ch = ppg_sample_num ;\r
+        _ppg_data_out.touch_value = _state.core.touch_value;\r
+        \r
+        _ppg_data_out.afe_gain_flag =_state.afe_gain_flag ;\r
+\r
+        for (i = 0; i < (_ppg_data_out.ch_num*_ppg_data_out.sample_num_per_ch); i++)\r
+        {\r
+            uint16_t fifo_index = PAH831X_DATA_SIZE * i;\r
+            uint8_t dac = fifo[fifo_index + 0];\r
+            uint32_t data = 0;\r
+            uint32_t data_normalize = 0;\r
+            memcpy((uint8_t*)&data, &fifo[fifo_index + 2], 3);            \r
+            data_normalize = dac>0? ((data*256)/ dac) :data;\r
+        #ifdef PPG_DATA_NORMALIZE\r
+            \r
+            ppg_buffer[i] = data_normalize ;\r
+        #else\r
+            ppg_buffer[i] = data ;\r
+        #endif\r
+            ppg_dac_buffer[i] = dac ;\r
+          //  DEBUG_PRINT("send_fifo_data:data= %d,dac= %d , data_normalize = %d\n", data,dac, data_normalize);\r
+        }\r
+        _ppg_data_out.ppg_raw_data = (uint8_t*)ppg_buffer ;\r
+        _ppg_data_out.ppg_dac_data = ppg_dac_buffer ;\r
+        _ppg_data_out.ppg_adc_data = adc_buf;\r
+    }\r
+#ifdef ENABLE_PAH831X_ECG_FUNCTION\r
+    if (ecg_sample_num > 0 && ppg_sample_num == 0)\r
+    {\r
+        duration =(uint32_t)(this->task_timestamp - this->prev_task_timestamp );\r
+        _ecg_data_out.ecg_data_ready++;\r
+        _ecg_data_out.duration = duration;\r
+        _ecg_data_out.is_touched = 1 ;\r
+        _ecg_data_out.ch_num = 1  ;\r
+        _ecg_data_out.sample_num_per_ch = ecg_sample_num ;\r
+        \r
+        for (i = 0; i < (ecg_sample_num); i++)\r
+        {\r
+            uint16_t fifo_index = PAH831X_DATA_SIZE * i;\r
+            uint8_t ecg_tag = fifo[fifo_index + 0];\r
+            uint32_t rawdata = 0;\r
+\r
+            memcpy((uint8_t*)&rawdata, &fifo[fifo_index + 2], 3);\r
+\r
+            ecg_tag_buffer[i] = ecg_tag;\r
+            ecg_buffer[i] = cvt24bit(rawdata);\r
+           \r
+        }\r
+        _ecg_data_out.ecg_raw_data = (uint8_t*)ecg_buffer ;\r
+        _ecg_data_out.ecg_tag_data = ecg_tag_buffer ;\r
+        \r
+        \r
+    }\r
+    \r
+    if (ecg_sample_num > 0 && ppg_sample_num > 0)\r
+    {\r
+        duration =(uint32_t)(this->task_timestamp - this->prev_task_timestamp );\r
+        _ecg_data_out.ecg_data_ready++;\r
+        _ecg_data_out.duration = duration;\r
+        //_ecg_data_out.is_touched = 1 ;\r
+        _ecg_data_out.ch_num = 1  ;\r
+        _ecg_data_out.sample_num_per_ch = ecg_sample_num ;\r
+        _ppg_data_out.ppg_data_ready++;\r
+        _ppg_data_out.duration = duration;\r
+        _ppg_data_out.is_touched = _state.touch_status ;\r
+        _ppg_data_out.ch_num = this->core.ppg.ch_num  ;\r
+        //_ppg_data_out.ch_num = 1  ;\r
+        _ppg_data_out.sample_num_per_ch = ppg_sample_num ;\r
+        _ppg_data_out.touch_value = _state.core.touch_value;\r
+        uint16_t  ecg_buffer_cnt = 0;\r
+        uint16_t  ppg_buffer_cnt = 0;\r
+        uint8_t   ECG_CH_TAG = 0x06;\r
+     //   DEBUG_PRINT("_ecg_data_out.ch_num=  %d, _ppg_data_out.ch_num = %d\n",_ecg_data_out.ch_num,_ppg_data_out.ch_num);\r
+        for (i = 0; i < ((_ppg_data_out.ch_num+_ecg_data_out.ch_num)*_ppg_data_out.sample_num_per_ch); i++)\r
+        {\r
+            uint16_t fifo_index = PAH831X_DATA_SIZE * i;\r
+            uint8_t tag = fifo[fifo_index + 0];\r
+            uint8_t ECG_tag = (fifo[fifo_index + 1]&ECG_CH_TAG);\r
+            uint32_t data = 0;\r
+            uint32_t data_normalize = 0;\r
+            memcpy((uint8_t*)&data, &fifo[fifo_index + 2], 3);\r
+           // DEBUG_PRINT("ECG_tag: %d, tag = %d\n", ECG_tag,tag);\r
+            if(ECG_tag!=ECG_CH_TAG)\r
+            {\r
+               // DEBUG_PRINT("ppg raw: %d, \n", data);\r
+                if(tag!=0)\r
+                    data_normalize = (data*256) / tag;\r
+                #ifdef PPG_DATA_NORMALIZE\r
+                    ppg_buffer[ppg_buffer_cnt] = data_normalize ;\r
+                #else\r
+                    ppg_buffer[ppg_buffer_cnt] = tag ;\r
+                #endif\r
+                ppg_dac_buffer[ppg_buffer_cnt] = tag ;\r
+                \r
+               // DEBUG_PRINT("ppg raw: %d,%d,%d \n", data,data_normalize,ppg_buffer[ppg_buffer_cnt]);\r
+                ppg_buffer_cnt++;\r
+            }\r
+            else\r
+            {\r
+                ecg_tag_buffer[ecg_buffer_cnt] = tag;\r
+                ecg_buffer[ecg_buffer_cnt] = cvt24bit(data);\r
+                ecg_buffer_cnt++;\r
+            }\r
+            \r
+        }\r
+      //  DEBUG_PRINT("ppg_buffer_cnt: %d, ecg_buffer_cnt = %d\n", ppg_buffer_cnt,ecg_buffer_cnt);\r
+        _ppg_data_out.ppg_raw_data = (uint8_t*)ppg_buffer ;\r
+        _ppg_data_out.ppg_dac_data = ppg_dac_buffer ;\r
+        _ecg_data_out.ecg_raw_data = (uint8_t*)ecg_buffer ;\r
+        _ecg_data_out.ecg_tag_data = ecg_tag_buffer ;\r
+    }\r
+#endif\r
+}\r
+\r
+uint8_t get_ppg_data_ready(void)\r
+{\r
+    return _ppg_data_out.ppg_data_ready ;\r
+}\r
+\r
+void clear_ppg_data_ready(void)\r
+{\r
+    _ppg_data_out.ppg_data_ready--;\r
+}\r
+\r
+ppg_data_out get_ppg_data_out(void)\r
+{\r
+    return _ppg_data_out ;\r
+}\r
+uint8_t get_ppg_enable(void)\r
+{\r
+    return _state.config.ppg_is_enabled ;\r
+}\r
+\r
+uint8_t get_ecg_data_ready(void)\r
+{\r
+    return _ecg_data_out.ecg_data_ready ;\r
+}\r
+\r
+void clear_ecg_data_ready(void)\r
+{\r
+    _ecg_data_out.ecg_data_ready--;\r
+}\r
+ecg_data_out get_ecg_data_out(void)\r
+{\r
+    return _ecg_data_out ;\r
+}\r
+\r
+uint8_t get_ecg_enable(void)\r
+{\r
+    return _state.config.ecg_is_enabled ;\r
+}\r
+\r
+static float update_sample_interval(main_state *this, uint64_t start_timestamp, uint64_t end_timestamp, uint32_t sample_num, float read_size_ratio)\r
+{\r
+    float sample_interval = (float)(end_timestamp - start_timestamp) / sample_num;\r
+    return sample_interval * read_size_ratio;\r
+}\r
+\r
+static void send_ppg_event(main_state *this, uint64_t timestamp, const pah831x_ppg_sample *ppg_sample)\r
+{\r
+    UNUSED_VAR(this);\r
+    \r
+#if ENABLE_PRINT_PPG_EVENT_DATA\r
+    DEBUG_PRINT("PPG(time,a1,b1,c1,d1,e1,f1,a2,b2,c2,d2,e2,f2): %llu, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d", timestamp, \r
+        (int)ppg_sample->data[PAH831X_CH__PPG_A1],\r
+        (int)ppg_sample->data[PAH831X_CH__PPG_B1],\r
+        (int)ppg_sample->data[PAH831X_CH__PPG_C1],\r
+        (int)ppg_sample->data[PAH831X_CH__PPG_D1],\r
+        (int)ppg_sample->data[PAH831X_CH__PPG_E1],\r
+        (int)ppg_sample->data[PAH831X_CH__PPG_F1],\r
+        (int)ppg_sample->data[PAH831X_CH__PPG_A2],\r
+        (int)ppg_sample->data[PAH831X_CH__PPG_B2],\r
+        (int)ppg_sample->data[PAH831X_CH__PPG_C2],\r
+        (int)ppg_sample->data[PAH831X_CH__PPG_D2],\r
+        (int)ppg_sample->data[PAH831X_CH__PPG_E2],\r
+        (int)ppg_sample->data[PAH831X_CH__PPG_F2]);\r
+#endif\r
+}\r
+#define ECG_GAIN 20.6\r
+static float ADC_to_mV(int32_t ECG_mV)\r
+{\r
+    float ECG_mV_out = 0 ;\r
+    ECG_mV_out = (float)((ECG_mV - (63488*32))*2.4f*1000/(126976*32));\r
+    return ECG_mV_out ;\r
+}\r
+\r
+static void send_ecg_event(main_state *this, uint64_t timestamp, const pah831x_ecg_sample *ecg_sample)\r
+{\r
+    UNUSED_VAR(this);\r
+    float temp = 0 ;\r
+    temp = ADC_to_mV((int)ecg_sample->data);\r
+#if ENABLE_PRINT_ECG_EVENT_DATA\r
+    //DEBUG_PRINT("ECG(time,data,tag): %llu, %d, %d", timestamp, (int)ecg_sample->data, (int)ecg_sample->tag);\r
+    DEBUG_PRINT("ECG(time,data,tag): %llu, %f, %d\n", timestamp, temp, (int)ecg_sample->tag);\r
+#endif\r
+}\r
+\r
+static void send_touch_event(main_state *this, uint64_t timestamp, const touch_status touch_status)\r
+{\r
+    UNUSED_VAR(this);\r
+    \r
+#if ENABLE_PRINT_TOUCH_EVENT_DATA\r
+    if (touch_status == TOUCH_STATUS__ON)\r
+        DEBUG_PRINT("TOUCH(time,status): %llu, ON\n", timestamp);\r
+    else if (touch_status == TOUCH_STATUS__OFF)\r
+        DEBUG_PRINT("TOUCH(time,status): %llu, OFF\n", timestamp);\r
+#endif\r
+}\r
+\r
+void pah_interrupt_handle(void)\r
+{\r
+    _state.has_interrupt = true;\r
+    _state.interrupt_timestamp = pxi_get_tick_count();\r
+}\r
+\r
+void set_ir_r_led_switch_status(bool status)\r
+{\r
+    _state.core.ir_r_led_switch_new_status = status;\r
+}\r
+\r
+uint16_t get_pah831x_touch_value()\r
+{\r
+    uint16_t pah831x_touch_value = 0 ;\r
+\r
+    pah831x_read_touch_value(&_state.core, &pah831x_touch_value);\r
+    \r
+    return pah831x_touch_value ;\r
+}\r
+\r
+\r
+static void pah831x_hr_timer_handler(void)\r
+{\r
+    pah831x_sensor_task();\r
+    \r
+    if(get_ppg_data_ready())\r
+    {\r
+\r
+    #ifdef SUPPORT_CYWEE_SERVICE\r
+        gsenson_t data[5] = {0};\r
+        cywee_get_gsensor_data(5, data);\r
+\r
+        memset(acc_data, 0, sizeof(acc_data));\r
+\r
+        for(int i = 0, j = 0; j < 4; j++)\r
+        {\r
+            // 直接取前 4 笔原始数据(最简单,无插值)\r
+            float x = data[j].x;\r
+            float y = data[j].y;\r
+            float z = data[j].z;\r
+\r
+            acc_data[i]   = (int16_t)(x * 2048 / 10);\r
+            acc_data[i+1] = (int16_t)(y * 2048 / 10);\r
+            acc_data[i+2] = (int16_t)(z * 2048 / 10);\r
+            \r
+            i += 3;\r
+        }\r
+    #endif\r
+\r
+        ppg_data_out _ppg_data_out_alg = get_ppg_data_out() ;\r
+        LOG_PRINT("Touch_value = %d \n", _ppg_data_out_alg.touch_value);\r
+        uint8_t hr_out             = 0 ;\r
+        uint8_t hr_trust_level_out = 0 ;\r
+        report_fifo_data_hr(\r
+            (uint32_t)_ppg_data_out_alg.end_timestamp,     \r
+            _ppg_data_out_alg.duration, \r
+            (uint32_t*)_ppg_data_out_alg.ppg_raw_data,\r
+            _ppg_data_out_alg.ppg_dac_data,\r
+            _ppg_data_out_alg.sample_num_per_ch,\r
+            _ppg_data_out_alg.ch_num,\r
+            acc_data,\r
+            4/*25*/, \r
+            &hr_out,\r
+            &hr_trust_level_out,\r
+            _ppg_data_out_alg.is_touched ,\r
+            1                \r
+        );\r
+        LOG_PRINT("_ppg_data_out_alg.is_touched  %d\n",  _ppg_data_out_alg.is_touched );\r
+        LOG_PRINT("hr_out:%d,hr_trust_level_out:%d,acc_num:%d\n",  hr_out,hr_trust_level_out,acc_num);\r
+\r
+//    \r
+        ret_hrs = hr_out;\r
+        ret_wear = _ppg_data_out_alg.is_touched;\r
+\r
+        clear_ppg_data_ready();\r
+    }\r
+    if((get_ppg_enable())!=(ppg_work_status)){\r
+        hr_algorithm_close();\r
+        ppg_work_status = get_ppg_enable() ;\r
+    }\r
+}\r
+\r
+static void pah831x_wear_timer_handler(void)\r
+{\r
+\r
+    pah831x_sensor_task();\r
+    // if(get_ppg_data_ready())\r
+    {\r
+        pah831x_read_touch_flag(&_state.core,&_state.core.touch_flag);\r
+        ret_wear = _state.core.touch_flag;\r
+        // if(_ppg_data_out_alg.ch_num==1)\r
+        // {\r
+        //     LOG_PRINT("Touch_value , %d ",_ppg_data_out_alg.sample_num_per_ch);\r
+        //     uint32_t *ppg_data = (uint32_t*)_ppg_data_out_alg.ppg_raw_data;\r
+            \r
+        //     for(i= 0 ; i <_ppg_data_out_alg.sample_num_per_ch;i++)\r
+        //     {\r
+        //         ir_touch_value[i]=(ppg_data[i])>>6;\r
+        //         LOG_PRINT(" %d, ", ir_touch_value[i]);\r
+        //     }\r
+        //         LOG_PRINT("\n");\r
+\r
+        // }\r
+        // printf("history_wear_status:%d,ret_wear:%d\n",history_wear_status,ret_wear);\r
+        if(history_wear_status != ret_wear)\r
+        {\r
+            history_wear_status = ret_wear;\r
+        #ifdef SUPPORT_CYWEE_SERVICE\r
+                // do_cywee_service_check_msg(CYWEE_SERVICE_CMD_WEAR_STATUS_CHANGE,&wear_status);\r
+                cywee_wear_status_update(&ret_wear);\r
+        #endif\r
+        }\r
+\r
+        clear_ppg_data_ready();\r
+    }\r
+}\r
+\r
+static void pah831x_hrv_timer_handler(void)\r
+{\r
+    float   HRV_out                = 0.0f ;\r
+    uint8_t HRV_withHR             = 0.0f ;\r
+    float   HRV_singal_quality     = 0.0f ;\r
+    uint8_t got_HRV                = 0    ;\r
+    uint8_t HRV_Anomaly            = 0    ;\r
+    uint8_t got_hrv                = 0    ;\r
+    uint8_t got_time_out              = 0    ; \r
+\r
+    pah831x_sensor_task();\r
+\r
+    if(get_ppg_data_ready())\r
+    {\r
+\r
+        ppg_data_out _ppg_data_out_alg = get_ppg_data_out() ;\r
+        \r
+            report_fifo_data_hrv(\r
+            (uint32_t)_ppg_data_out_alg.end_timestamp,     \r
+            _ppg_data_out_alg.duration, \r
+            (uint32_t*)_ppg_data_out_alg.ppg_raw_data,\r
+            _ppg_data_out_alg.ppg_dac_data,\r
+            _ppg_data_out_alg.sample_num_per_ch,\r
+            _ppg_data_out_alg.ch_num,\r
+            acc_data,\r
+            acc_num/*acc_num*/, \r
+            &HRV_out,               \r
+            &HRV_withHR,                 \r
+            &HRV_singal_quality,\r
+            &HRV_Anomaly,    \r
+            &got_hrv,\r
+            &got_time_out,\r
+            _ppg_data_out_alg.is_touched  ,\r
+            LOG_DATA_ENABLE,\r
+            25\r
+        );\r
+        ret_hrv = pah_831x_alg_get_hrv_result();\r
+        printf("ret_hrv:%d\n",ret_hrv);\r
+        clear_ppg_data_ready();\r
+    }\r
+\r
+}\r
+\r
+\r
+static void pah831x_spo2_timer_handler(void)\r
+{\r
+    uint8_t got_time_out = 0;\r
+    float hr_out = 0 ;\r
+    float hr_grader_out = 0 ;  \r
+    pah831x_sensor_task();\r
+  \r
+    if(get_ppg_data_ready())\r
+    {\r
+        ppg_data_out _ppg_data_out_alg = get_ppg_data_out() ;\r
+        LOG_PRINT("Touch_value = %d \n", _ppg_data_out_alg.touch_value);\r
+\r
+        // report_fifo_data_shrd(\r
+        //     (uint32_t)_ppg_data_out_alg.end_timestamp,     \r
+        //     _ppg_data_out_alg.duration, \r
+        //     (uint32_t*)_ppg_data_out_alg.ppg_raw_data,\r
+        //     _ppg_data_out_alg.ppg_dac_data,\r
+        //     _ppg_data_out_alg.sample_num_per_ch,\r
+        //     _ppg_data_out_alg.ch_num,\r
+        //     acc_data,\r
+        //     acc_num/*25*/, \r
+        //     &hr_out,\r
+        //     &hr_grader_out,\r
+        //     _ppg_data_out_alg.is_touched,\r
+        //     0\r
+            \r
+        // );\r
+\r
+        report_fifo_data_spo2(\r
+            (uint32_t)_ppg_data_out_alg.end_timestamp,     \r
+            _ppg_data_out_alg.duration, \r
+            (uint32_t*)_ppg_data_out_alg.ppg_raw_data,\r
+            _ppg_data_out_alg.ppg_dac_data,\r
+            _ppg_data_out_alg.sample_num_per_ch,\r
+            _ppg_data_out_alg.ch_num,\r
+            acc_data,\r
+            acc_num/*25*/, \r
+            &got_time_out,\r
+            _ppg_data_out_alg.is_touched,  \r
+            hr_out,\r
+            1\r
+        );\r
+\r
+        // LOG_PRINT("_ppg_data_out_alg.is_touched  %d\n",  _ppg_data_out_alg.is_touched );\r
+        ret_spo2 = pah_831x_alg_get_spo2_result();\r
+        ret_wear = _ppg_data_out_alg.is_touched;\r
+\r
+        LOG_PRINT("spo2:%d  ret_wear:%d\n", ret_spo2,ret_wear);\r
+//    \r
+        clear_ppg_data_ready();\r
+    }\r
+}\r
+\r
+static uint8_t ecg_param_init = 0;\r
+static int cali_value[4] = {-1, -22, 28, 64};\r
+static bool bp_cal_ready = false;\r
+static int cal_sbp_in = 0;\r
+static int cal_dbp_in = 0;\r
+static int CalValue_in = 0;\r
+static int CalValue1_in = 0;\r
+// static uint8_t calibration_mode = ECG_PPG_BP_CALI;\r
+static uint8_t calibration_mode = ECG_PPG_BP_ESTIMATE;\r
+\r
+// 2. 固定基准参数:静态常量,全程不变\r
+static uint8_t user_age = 24;\r
+static uint16_t user_height = 173;\r
+static uint16_t Benchmark_SBP = 135;\r
+static uint16_t Benchmark_DBP = 85;\r
+\r
+// calibration_bp = 11,-16, 71,86,\r
+\r
+// 28,9, 34,85,\r
+\r
+// 26,9, 29,86,\r
+\r
+static void pah831x_ecg_bp_timer_handler(void)\r
+{\r
+    int         alg_out[2] = {0} ;\r
+    uint8_t     got_BP = 0;\r
+    uint8_t     got_time_out = 0;\r
+\r
+    if(ecg_param_init == 0)\r
+    {\r
+        ecg_param_init = 1;\r
+\r
+        if(calibration_mode==ECG_PPG_BP_CALI)\r
+        {\r
+            bp_cal_ready = false ;  \r
+            cal_sbp_in    = 0 ; \r
+            cal_dbp_in    = 0 ;\r
+            CalValue_in   = 0 ;\r
+            CalValue1_in  = 0 ; \r
+            LOG_PRINT("ECG_PPG_BP_CALI_cali_value = %d, %d, %d, %d,\n", cal_sbp_in,cal_dbp_in,CalValue_in,CalValue1_in);\r
+            \r
+        }else if(calibration_mode==ECG_PPG_BP_ESTIMATE)\r
+        {\r
+\r
+            pah831x_read_calidata();\r
+\r
+            //bp_cal_ready = get_bp_cal_data(cali_value);\r
+            bp_cal_ready = true  ;//read from flash\r
+            // cali_value[0] = 26   ;//read from flash\r
+            // cali_value[1] = 9  ;//read from flash\r
+            // cali_value[2] = 29   ;//read from flash\r
+            // cali_value[3] = 86   ;//read from flash\r
+            // cal_sbp_in   = cali_value[0];\r
+            // cal_dbp_in   = cali_value[1];\r
+            // CalValue_in  = cali_value[2];\r
+            // CalValue1_in = cali_value[3];\r
+            got_BP = 0 ;\r
+            Benchmark_SBP = 0 ;\r
+            Benchmark_DBP = 0 ;\r
+            LOG_PRINT("ECG_PPG_BP_ESTIMATE_cali_value = %d, %d, %d, %d,\n", cal_sbp_in,cal_dbp_in,CalValue_in,CalValue1_in);\r
+            \r
+            //calibration_mode = ECG_PPG_BP_ESTIMATE;\r
+        }\r
+\r
+    }\r
+\r
+   \r
+    pah831x_sensor_task();\r
+\r
+    if(get_ecg_data_ready())\r
+    //if(get_ecg_data_ready()&&get_ppg_data_ready())\r
+    {\r
+        ecg_data_out _ecg_data_out_alg = get_ecg_data_out() ;\r
+        ppg_data_out _ppg_data_out_alg = get_ppg_data_out() ;\r
+\r
+        report_fifo_data_ecg_bp(\r
+        (uint32_t)_ecg_data_out_alg.end_timestamp,     \r
+        _ecg_data_out_alg.duration, \r
+        (uint32_t*)_ppg_data_out_alg.ppg_raw_data,\r
+        (uint32_t*)_ecg_data_out_alg.ecg_raw_data,\r
+        _ppg_data_out_alg.ppg_dac_data,\r
+        _ecg_data_out_alg.ecg_tag_data,\r
+        _ecg_data_out_alg.sample_num_per_ch,\r
+        _ecg_data_out_alg.ch_num,\r
+        acc_data,\r
+        acc_num/*25*/, \r
+        alg_out,\r
+        &got_BP,\r
+        &got_time_out,\r
+        _ecg_data_out_alg.is_touched,\r
+        calibration_mode,\r
+        user_age,\r
+        Benchmark_SBP,\r
+        Benchmark_DBP,\r
+        user_height,\r
+        bp_cal_ready  ,\r
+        cal_sbp_in    ,   \r
+        cal_dbp_in    ,\r
+        CalValue_in   ,\r
+        CalValue1_in  \r
+        );\r
+        // LOG_PRINT("got_time_out =%d\n",got_time_out);\r
+        // LOG_PRINT("got_BP =%d\n",got_BP);\r
+        // LOG_PRINT("_ecg_data_out_alg.is_touched =%d\n",_ecg_data_out_alg.is_touched);\r
+        // LOG_PRINT("ECG_PPG_BP_CALI_cali_value = %d, %d, %d, %d,\n", cal_sbp_in,cal_dbp_in,CalValue_in,CalValue1_in);\r
+        \r
+        clear_ecg_data_ready();\r
+        clear_ppg_data_ready();\r
+    }\r
+//     if((get_ecg_enable())!=(ppg_work_status)){\r
+//         ecg_bp_algorithm_close();\r
+//         ppg_work_status = get_ecg_enable() ;\r
+//     }\r
+//     if(got_time_out==1)\r
+//     {\r
+//         pah_sensor_stop();\r
+//         ecg_bp_algorithm_close();\r
+//         LOG_PRINT("got_time_out\n");\r
+//         got_time_out=0;\r
+//     }\r
+//     if((got_BP==1) && (calibration_mode==ECG_PPG_BP_CALI))\r
+//     {\r
+//         pah_sensor_stop();\r
+//         ecg_bp_algorithm_close();\r
+//         bp_cal_ready = get_bp_cal_data(cali_value);//save to flash\r
+// //            cal_sbp_in   = cali_value[0];\r
+// //            cal_dbp_in   = cali_value[1];\r
+// //            CalValue_in  = cali_value[2];\r
+// //            CalValue1_in = cali_value[3];\r
+// //            got_BP = 0 ;\r
+// //            Benchmark_SBP = 0 ;\r
+// //            Benchmark_DBP = 0 ;\r
+// //            LOG_PRINT("cali_value = %d, %d, %d, %d,\n", cali_value[0],cali_value[1],cali_value[2],cali_value[3]);\r
+// //            LOG_PRINT("ECG_PPG_BP_CALI,alg_out = %d, %d, \n", alg_out[0],alg_out[1]);\r
+// //             \r
+// //            pah831x_sensor_init();\r
+// //            pah831x_sensor_start(PAH831X_WORK_DRI, PAH831X_INIT_ALWAYS_RUN, PAH831X_PPG_REG_SETTING_IDLE, PAH831X_ECG_REG_SETTING_2, 128, 3.90625f);\r
+// //            ecg_bp_algorithm_init();\r
+// //            calibration_mode = ECG_PPG_BP_ESTIMATE;\r
+            \r
+//     }\r
+//     if((got_BP==1) && (calibration_mode==ECG_PPG_BP_ESTIMATE))\r
+//     {\r
+//         pah_sensor_stop();\r
+//         ecg_bp_algorithm_close();\r
+//         LOG_PRINT("ECG_PPG_BP_ESTIMATE,alg_out = %d, %d, \n", alg_out[0],alg_out[1]);\r
+//         got_BP = 0 ;\r
+//     }\r
+}\r
+\r
+static void pah831x_ecg_afib_timer_handler(void)\r
+{\r
+\r
+    uint8_t alg_out  = 0 ;    \r
+    uint8_t got_afib = 0;\r
+    uint8_t got_time_out = 0;\r
+\r
+    pah831x_sensor_task();\r
+    if(get_ecg_data_ready())\r
+    {\r
+        _ecg_data_out_alg = get_ecg_data_out() ;\r
+\r
+\r
+        report_fifo_data_ecg_afib(\r
+            (uint32_t)_ecg_data_out_alg.end_timestamp,     \r
+            _ecg_data_out_alg.duration, \r
+            (uint32_t*)_ecg_data_out_alg.ecg_raw_data,\r
+            _ecg_data_out_alg.ecg_tag_data,\r
+            _ecg_data_out_alg.sample_num_per_ch,\r
+            _ecg_data_out_alg.ch_num,\r
+            acc_data,\r
+            acc_num/*25*/, \r
+            &alg_out,\r
+            &got_afib,\r
+            &got_time_out,\r
+            _ecg_data_out_alg.is_touched  \r
+        );\r
+        clear_ecg_data_ready();\r
+    }\r
+    if((get_ecg_enable())!=(ppg_work_status)){\r
+        ecg_afib_algorithm_close();\r
+        ppg_work_status = get_ecg_enable() ;\r
+    }\r
+\r
+    if(got_afib==1 || got_time_out==1)\r
+    {\r
+        pah_sensor_stop();\r
+    }\r
+}\r
+\r
+static void pah831x_stress_timer_handler(void)\r
+{\r
+    float       Stress_out                = 0.0f ;\r
+    uint8_t     Stress_withHR             = 0.0f ;\r
+    float       Stress_singal_quality     = 0.0f ;\r
+    uint8_t     got_stress                = 0    ;\r
+    uint8_t     Stress_Anomaly            = 0    ;\r
+    uint8_t     Stress_Enable             = 0    ;\r
+    int32_t     score                     = 50   ;           \r
+    \r
+\r
+    pah831x_sensor_task();\r
+    if(get_ppg_data_ready())\r
+    {\r
+        ppg_data_out _ppg_data_out_alg = get_ppg_data_out() ;\r
+        \r
+        report_fifo_data_stress(\r
+            (uint32_t)_ppg_data_out_alg.end_timestamp,     \r
+            _ppg_data_out_alg.duration, \r
+            (uint32_t*)_ppg_data_out_alg.ppg_raw_data,\r
+            _ppg_data_out_alg.ppg_dac_data,\r
+            _ppg_data_out_alg.sample_num_per_ch,\r
+            _ppg_data_out_alg.ch_num,\r
+            acc_data,\r
+            _ppg_data_out_alg.sample_num_per_ch/*acc_num*/, \r
+            &Stress_out,               \r
+            &Stress_withHR,                 \r
+            &Stress_singal_quality,\r
+            &Stress_Anomaly,  \r
+            &got_stress,\r
+            _ppg_data_out_alg.is_touched ,\r
+            score  ,         \r
+            1\r
+        );\r
+\r
+        clear_ppg_data_ready();\r
+    }\r
+    if((get_ppg_enable())!=(ppg_work_status))\r
+    {\r
+        stress_algorithm_close();\r
+        ppg_work_status = get_ppg_enable() ;\r
+    }\r
+\r
+    if(got_stress==1 )\r
+    {\r
+        pah_sensor_stop();\r
+        stress_algorithm_close();\r
+        got_stress = 0 ;\r
+    }\r
+    // If user want to stop ppg flow ,Please call pah_sensor_stop() & hrv_algorithm_close()\r
+    //pah_sensor_stop();\r
+    //hrv_algorithm_close();\r
+}\r
+\r
+static void pah831x_rr_timer_handler(void)\r
+{ \r
+\r
+    int     RR_out_2         = 0 ;\r
+    float   RRI_out_2        = 0.0f ;\r
+\r
+    pah831x_sensor_task();\r
+\r
+    if(get_ppg_data_ready())\r
+    {\r
+\r
+        ppg_data_out _ppg_data_out_alg = get_ppg_data_out() ;\r
+        \r
+        report_fifo_data_rr_2(\r
+            (uint32_t)_ppg_data_out_alg.end_timestamp,     \r
+            _ppg_data_out_alg.duration, \r
+            (uint32_t*)_ppg_data_out_alg.ppg_raw_data,\r
+            _ppg_data_out_alg.ppg_dac_data,\r
+            _ppg_data_out_alg.sample_num_per_ch,\r
+            _ppg_data_out_alg.ch_num,\r
+            acc_data,\r
+            acc_num/*acc_num*/, \r
+            &RR_out_2,                            \r
+            &RRI_out_2,\r
+            _ppg_data_out_alg.is_touched  ,\r
+            LOG_DATA_ENABLE,\r
+            0\r
+        );\r
+        //LOG_PRINT("_ppg_data_out_alg.is_touched  %d\n",  _ppg_data_out_alg.is_touched );\r
+//    \r
+        clear_ppg_data_ready();\r
+    }\r
+    if((get_ppg_enable())!=(ppg_work_status))\r
+    {\r
+        rr_2_algorithm_close();\r
+        ppg_work_status = get_ppg_enable() ;\r
+    }\r
+\r
+        // If user want to stop ppg flow ,Please call pah_sensor_stop() & rr_2_algorithm_close()\r
+        //pah_sensor_stop();\r
+        //rr_2_algorithm_close();\r
+}\r
+\r
+static void pah831x_ecg_raw_timer_handler(void)\r
+{\r
+    pah831x_sensor_task();\r
+        if(get_ecg_data_ready())\r
+    {\r
+        _ecg_data_out_alg = get_ecg_data_out() ;\r
+\r
+        report_ecg_fifo_data(\r
+            (uint32_t)_ecg_data_out_alg.end_timestamp,     \r
+            _ecg_data_out_alg.duration, \r
+            (uint32_t*)_ecg_data_out_alg.ecg_raw_data,\r
+            _ecg_data_out_alg.ecg_tag_data,\r
+            _ecg_data_out_alg.sample_num_per_ch,\r
+            _ecg_data_out_alg.ch_num,\r
+            acc_data,\r
+            acc_num/*25*/, \r
+            _ecg_data_out_alg.is_touched  \r
+        );\r
+\r
+        \r
+\r
+        clear_ecg_data_ready();\r
+    \r
+        \r
+    }\r
+    if((get_ecg_enable())!=(ppg_work_status)){\r
+        ppg_work_status = get_ecg_enable() ;\r
+    }\r
+    // If user want to stop ppg flow ,Please call pah_sensor_stop() & raw_algorithm_close()\r
+    //pah_sensor_stop();\r
+    //ecg_filter_close();\r
+}\r
+\r
+\r
+static uint32_t time = 0;\r
+void pah831x_hrv_start(void)\r
+{\r
+    pah831x_sensor_init();\r
+\r
+// #if defined(PPG_MODE_ONLY)    \r
+    pah831x_sensor_start(PAH831X_WORK_POLLING ,PAH831X_INIT_ALWAYS_RUN  ,PAH831X_PPG_REG_SETTING_3 ,PAH831X_ECG_REG_SETTING_IDLE,PPG_WATERMARK_HRV/*interrupt_report_num*/,40/*sample_period*/ );\r
+// #else\r
+//     pah831x_sensor_start(PAH831X_WORK_POLLING ,PAH831X_INIT_AUTO_MODE  ,PAH831X_PPG_REG_SETTING_3 ,PAH831X_ECG_REG_SETTING_IDLE,PPG_WATERMARK_HRV/*interrupt_report_num*/,40/*sample_period*/ );\r
+\r
+// #endif\r
+\r
+    hrv_algorithm_close();\r
+    ppg_work_status = get_ppg_enable();\r
+}\r
+\r
+void pah831x_rr_start(void)\r
+{\r
+    pah831x_sensor_init();\r
+    \r
+// #if defined(PPG_MODE_ONLY)    \r
+    pah831x_sensor_start(PAH831X_WORK_POLLING ,PAH831X_INIT_ALWAYS_RUN  ,PAH831X_PPG_REG_SETTING_3 ,PAH831X_ECG_REG_SETTING_IDLE,PPG_WATERMARK_RR/*interrupt_report_num*/,40/*sample_period*/ );\r
+// #else\r
+//     pah831x_sensor_start(PAH831X_WORK_POLLING ,PAH831X_INIT_AUTO_MODE  ,PAH831X_PPG_REG_SETTING_3 ,PAH831X_ECG_REG_SETTING_IDLE,PPG_WATERMARK_RR/*interrupt_report_num*/,40/*sample_period*/ );\r
+// #endif\r
+\r
+    rr_2_algorithm_close(); \r
+    ppg_work_status = get_ppg_enable() ;\r
+}\r
+\r
+void pah831x_stress_start(void)\r
+{\r
+    pah831x_sensor_init();\r
+\r
+// #if defined(PPG_MODE_ONLY)\r
+    pah831x_sensor_start(PAH831X_WORK_POLLING ,PAH831X_INIT_ALWAYS_RUN  ,PAH831X_PPG_REG_SETTING_3 ,PAH831X_ECG_REG_SETTING_IDLE,PPG_WATERMARK_STRESS/*interrupt_report_num*/,40/*sample_period*/ );\r
+// #else\r
+//     pah831x_sensor_start(PAH831X_WORK_DRI ,PAH831X_INIT_AUTO_MODE  ,PAH831X_PPG_REG_SETTING_3 ,PAH831X_ECG_REG_SETTING_IDLE,PPG_WATERMARK_STRESS/*interrupt_report_num*/,40/*sample_period*/ );\r
+// #endif    \r
+    \r
+    stress_algorithm_close(); \r
+    ppg_work_status = get_ppg_enable() ;\r
+}\r
+\r
+void pah831x_hr_start(void)\r
+{\r
+    pah831x_sensor_init();\r
+// #if defined(PPG_MODE_ONLY)    \r
+    pah831x_sensor_start(PAH831X_WORK_POLLING ,PAH831X_INIT_ALWAYS_RUN,PAH831X_PPG_REG_SETTING_1 ,PAH831X_ECG_REG_SETTING_IDLE,20,50 );\r
+// #else\r
+//     pah831x_sensor_start(PAH831X_WORK_POLLING ,PAH831X_INIT_AUTO_MODE,PAH831X_PPG_REG_SETTING_1 ,PAH831X_ECG_REG_SETTING_IDLE,20,50 );\r
+// #endif\r
+    hr_algorithm_init();  \r
+    ppg_work_status = get_ppg_enable() ;\r
+}\r
+\r
+void pah831x_ecg_bp_start(uint8_t cmd)\r
+{\r
+    if(cmd == 0)\r
+    {\r
+        calibration_mode = ECG_PPG_BP_CALI;\r
+    }\r
+    else if(cmd == 1)\r
+    {\r
+        calibration_mode = ECG_PPG_BP_ESTIMATE;\r
+    }\r
+\r
+    if(calibration_mode==ECG_PPG_BP_CALI)\r
+    {\r
+        pah831x_sensor_init();\r
+        pah831x_sensor_start(PAH831X_WORK_POLLING, PAH831X_INIT_ALWAYS_RUN, PAH831X_PPG_REG_SETTING_IDLE, PAH831X_ECG_REG_SETTING_2, 128, 3.90625f);\r
+        ecg_bp_algorithm_init();\r
+        \r
+    }else if(calibration_mode==ECG_PPG_BP_ESTIMATE)\r
+    {\r
+        pah831x_sensor_init();\r
+        pah831x_sensor_start(PAH831X_WORK_POLLING, PAH831X_INIT_ALWAYS_RUN, PAH831X_PPG_REG_SETTING_IDLE, PAH831X_ECG_REG_SETTING_2, 128, 3.90625f);\r
+        ecg_bp_algorithm_init();\r
+        //calibration_mode = ECG_PPG_BP_ESTIMATE;\r
+    }\r
+}\r
+\r
+void pah831x_spo2_start(void)\r
+{\r
+    uint8_t got_time_out = 0; \r
+    float hr_out = 0 ;\r
+    float hr_grader_out = 0 ;    \r
+    pah831x_sensor_init();\r
+// #if defined(PPG_MODE_ONLY)    \r
+    pah831x_sensor_start(PAH831X_WORK_POLLING ,PAH831X_INIT_ALWAYS_RUN,PAH831X_PPG_REG_SETTING_2 ,PAH831X_ECG_REG_SETTING_IDLE,25,40 );\r
+// #else\r
+    // pah831x_sensor_start(PAH831X_WORK_POLLING ,PAH831X_INIT_AUTO_MODE,PAH831X_PPG_REG_SETTING_2 ,PAH831X_ECG_REG_SETTING_IDLE,25,40 );\r
+// #endif\r
+    shrd_algorithm_close();\r
+    spo2_algorithm_close();\r
+    ppg_work_status = get_ppg_enable() ;\r
+}\r
+\r
+void pah831x_wear_start(void)\r
+{\r
+\r
+    printf("pah831x_wear_start \n");\r
+    //SENSOR_ENABLE\r
+    \r
+    pah831x_sensor_init();\r
+\r
+    pah831x_sensor_start(PAH831X_WORK_POLLING ,PAH831X_INIT_TOUCH_ONLY,PAH831X_PPG_REG_SETTING_1 ,PAH831X_ECG_REG_SETTING_IDLE,20,50 );\r
+    ppg_work_status = get_ppg_enable() ;\r
+}\r
+\r
+\r
+void pah831x_ecg_afib_start(void)\r
+{\r
+    pah831x_sensor_init();\r
+    pah831x_sensor_start(PAH831X_WORK_POLLING ,PAH831X_INIT_ALWAYS_RUN,PAH831X_PPG_REG_SETTING_IDLE ,PAH831X_ECG_REG_SETTING_1,256,3.91f  );\r
+    ecg_afib_algorithm_init();\r
+\r
+}\r
+\r
+\r
+void pah831x_ecg_raw_start(void)\r
+{\r
+    pah831x_sensor_init();\r
+    pah831x_sensor_start(PAH831X_WORK_POLLING, PAH831X_INIT_ALWAYS_RUN, PAH831X_PPG_REG_SETTING_IDLE, PAH831X_ECG_REG_SETTING_1, 250, 2);\r
+    ecg_filter_init(); \r
+}\r
+\r
+void pah831x_spo2_stop(void)\r
+{\r
+    pah_sensor_stop();\r
+    shrd_algorithm_close();\r
+    spo2_algorithm_close();\r
+}\r
+\r
+void pah831x_hr_stop(void)\r
+{\r
+    pah_sensor_stop();\r
+    hr_algorithm_close();\r
+}\r
+\r
+void pah831x_hrv_stop(void)\r
+{\r
+    pah_sensor_stop();\r
+    hrv_algorithm_close();\r
+}\r
+\r
+void pah831x_ecgbp_stop(void)\r
+{\r
+    pah_sensor_stop();\r
+    ecg_bp_algorithm_close();\r
+\r
+    if(calibration_mode == ECG_PPG_BP_CALI)\r
+    {\r
+        pah831x_save_calidata();\r
+    }\r
+}\r
+\r
+void pah831x_ecg_afib_stop(void)\r
+{\r
+    pah_sensor_stop();\r
+    ecg_afib_algorithm_close();\r
+}\r
+\r
+void pah831x_stress_stop(void)\r
+{\r
+    pah_sensor_stop();\r
+    stress_algorithm_close();\r
+}\r
+\r
+void pah831x_rr_stop(void)\r
+{\r
+    pah_sensor_stop();\r
+    rr_2_algorithm_close();\r
+}\r
+\r
+void pah831x_ecg_raw_stop(void)\r
+{\r
+    pah_sensor_stop();\r
+    ecg_filter_close();\r
+}\r
+\r
+\r
+\r
+\r
+void pah831x_timer_handler(void)\r
+{\r
+    if(work_mode == 1)\r
+    {\r
+        printf("hr_alg_task \n");\r
+        pah831x_hr_timer_handler();\r
+    }    \r
+    else if(work_mode == 2)\r
+    {\r
+        // PRINT("spo2_alg_task \n");\r
+        // spo2_alg_task();\r
+        pah831x_spo2_timer_handler();\r
+    }\r
+    else if(work_mode == 3)\r
+    {\r
+        // PRINT("spo2_alg_task \n");\r
+        // spo2_alg_task();\r
+        pah831x_hrv_timer_handler();\r
+        // pah831x_ecg_bp_timer_handler();\r
+    }\r
+    else if(work_mode == 4)\r
+    {\r
+        // PRINT("spo2_alg_task \n");\r
+        // spo2_alg_task();\r
+        // pah831x_hrv_timer_handler();\r
+        pah831x_ecg_bp_timer_handler();\r
+    }\r
+    else if(work_mode == 5)\r
+    {\r
+        // spo2_alg_task();\r
+        // pah831x_hrv_timer_handler();\r
+        pah831x_wear_timer_handler();\r
+    }\r
+    else if(work_mode == 6)\r
+    {\r
+        // spo2_alg_task();\r
+        // pah831x_hrv_timer_handler();\r
+        pah831x_ecg_afib_timer_handler();\r
+    }\r
+    else if(work_mode == 7)\r
+    {\r
+        // spo2_alg_task();\r
+        // pah831x_hrv_timer_handler();\r
+        pah831x_stress_timer_handler();\r
+    }\r
+    else if(work_mode == 8)\r
+    {\r
+        // spo2_alg_task();\r
+        // pah831x_hrv_timer_handler();\r
+        pah831x_rr_timer_handler();\r
+    }\r
+    else if(work_mode == 9)\r
+    {\r
+        // spo2_alg_task();\r
+        pah831x_ecg_raw_timer_handler();\r
+    }\r
+    \r
+    \r
+}\r
+\r
+void pah831x_sensor_stop(void)\r
+{\r
+    if(work_mode == 1)\r
+        pah831x_hr_stop();\r
+    else if(work_mode == 2)\r
+        pah831x_spo2_stop();\r
+    else if(work_mode == 3)\r
+        pah831x_hrv_stop();\r
+    else if(work_mode == 4)\r
+        pah831x_ecgbp_stop();\r
+    else if(work_mode == 6)\r
+        pah831x_ecg_afib_stop();\r
+    else if(work_mode == 7)\r
+        pah831x_stress_stop();\r
+    else if(work_mode == 8)\r
+        pah831x_rr_stop();\r
+    else if(work_mode == 9)\r
+        pah831x_ecg_raw_stop();\r
+\r
+    ret_hrs = 0;\r
+    ret_spo2 = 0;\r
+    ret_hrv = 0;\r
+    ret_wear = 0;\r
+\r
+    memset(acc_data, 0, sizeof(acc_data));\r
+}\r
+\r
+static void pah831x_timer_callback(void)\r
+{\r
+    // printf("pah831x_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
+    // pah831x_check_int();\r
+}\r
+\r
+static void pah831x_timer_init(void)\r
+{\r
+    if(g_pah831x_timer == NULL)\r
+        g_pah831x_timer = osTimerNew((osTimerFunc_t)pah831x_timer_callback, osTimerPeriodic, NULL, NULL);\r
+}\r
+\r
+void pah831x_control(char *mode,uint8_t enable)\r
+{\r
+    printf("mode : %s ,enable : %d\n",mode,enable);\r
+    if(!enable)\r
+    {\r
+\r
+        if(g_pah831x_timer != NULL && work_mode < 4 && work_mode > 0)\r
+            osTimerStop(g_pah831x_timer);\r
+\r
+\r
+        if(strcmp(mode, "leaklight") == 0)\r
+        {\r
+            demo_factory_mode(Factory_Test_Stop);\r
+        }\r
+\r
+        pah831x_sensor_stop();\r
+\r
+        work_mode = 0;\r
+\r
+        if(logFp)\r
+        {\r
+            fclose(logFp);\r
+            logFp = NULL;\r
+        }\r
+        // if(uapi_dev_runtime_get_sleep_monitoring_status() && uapi_dev_runtime_get_hrs_passivity_flag())\r
+        // {\r
+        //     pah831x_wearstatus_update(history_wear_status);   \r
+        //     uapi_dev_runtime_set_hrs_passivity(0); \r
+        // }\r
+    }\r
+    else\r
+    {\r
+        if (strcmp(mode, "hrs") == 0) {\r
+            printf("hrs \n");\r
+            // pah_sensor_init(diw_4mm_g_ir_hrd);\r
+            // auto_mode_sensor_start();\r
+            work_mode = 1;\r
+            // demo_factory_mode(Check_ECG_LL_TO_LA_STEP2);\r
+            // touch_only_sensor_start();\r
+            // ppg_only_sensor_start();\r
+            pah831x_hr_start();\r
+            time_out = 200;\r
+        } else if (strcmp(mode, "hrv") == 0) {\r
+            // md = HRV_MODE;\r
+            pah831x_hrv_start();\r
+            // pah831x_stress_start();\r
+            // pah831x_ecg_bp_start();\r
+            work_mode = 3;\r
+            time_out = 800;\r
+        } else if (strcmp(mode, "spo2") == 0) {\r
+            // md = SPO2_MODE;\r
+            // pah_sensor_init(diw_4mm_ir_r_ir_spo2);\r
+            // ppg_only_sensor_start();\r
+            pah831x_spo2_start();\r
+            work_mode = 2;\r
+            time_out = 200;\r
+            // demo_factory_mode(Check_ECG_LL_TO_LA_STEP3);\r
+            if(log_swtich && logFp == NULL)\r
+                logFp = fopen("/user/userdata/spo2log.txt", "w");\r
+\r
+        } else if (strcmp(mode, "ecgbp") == 0) {\r
+            // md = HRV_MODE;\r
+            // pah831x_hrv_start();\r
+            pah831x_ecg_bp_start(1);\r
+            // demo_factory_mode(Check_ECG_WAVEFORM_TEST);\r
+            work_mode = 4;\r
+            time_out = 200;\r
+        } else if (strcmp(mode, "ecgbp_cali") == 0) {\r
+            // md = HRV_MODE;\r
+            // pah831x_hrv_start();\r
+            pah831x_ecg_bp_start(0);\r
+            // demo_factory_mode(Check_ECG_WAVEFORM_TEST);\r
+            work_mode = 4;\r
+            time_out = 200;\r
+        } \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
+            // extern void test_library_HRD(void);\r
+            // test_library_HRD();\r
+            // work_mode = 6;\r
+            // pah831x_ecg_bp_start(1);\r
+            // demo_factory_mode(Check_Brightness_with_mechanical_cover_test_1_Side_A_1_LED);\r
+            // demo_factory_mode(Check_ECG_LL_TO_LA_STEP1);\r
+            demo_factory_mode(Light_Leak_Test_2_LED);\r
+            \r
+            // work_mode = 4;\r
+            // time_out = 200;\r
+            // factory_test_mode(factory_test_leak_light_target_sample, 0, 0, 0, 0);\r
+        } else if (strcmp(mode, "wear") == 0) {\r
+            // pah_sensor_init(diw_4mm_g_ir_hrd);\r
+            // touch_only_sensor_start();\r
+            pah831x_wear_start();\r
+            work_mode = 5;\r
+            time_out = 5000;\r
+        } else if (strcmp(mode, "ecgafib") == 0) {\r
+            // pah_sensor_init(diw_4mm_g_ir_hrd);\r
+            // touch_only_sensor_start();\r
+            printf("ecg_afib \n");\r
+            pah831x_ecg_afib_start();\r
+            work_mode = 6;\r
+            time_out = 200;\r
+        } else if (strcmp(mode, "stress") == 0) {\r
+            // pah_sensor_init(diw_4mm_g_ir_hrd);\r
+            // touch_only_sensor_start();\r
+            printf("stress \n");\r
+            pah831x_stress_start();\r
+            work_mode = 7;\r
+            time_out = 800;\r
+        } else if (strcmp(mode, "rr") == 0) {\r
+            // pah_sensor_init(diw_4mm_g_ir_hrd);\r
+            // touch_only_sensor_start();\r
+            printf("rr \n");\r
+            pah831x_rr_start();\r
+\r
+            work_mode = 8;\r
+            time_out = 800;\r
+        } else if (strcmp(mode, "ecgraw") == 0) {\r
+            // pah_sensor_init(diw_4mm_g_ir_hrd);\r
+            // touch_only_sensor_start();\r
+            printf("ecgraw \n");\r
+            pah831x_ecg_raw_start();\r
+            work_mode = 9;\r
+            time_out = 200;\r
+        } \r
+\r
+        \r
+        if(work_mode)\r
+            pah831x_timer_init();\r
+\r
+        time_cnt = 0;\r
+\r
+        // printf("work_mode : %d\n",work_mode);\r
+\r
+        if(g_pah831x_timer != NULL && work_mode)\r
+        {\r
+            // printf("time_out : %d\n",time_out);\r
+            osTimerStart(g_pah831x_timer,time_out);\r
+        }\r
+            \r
+\r
+    }\r
+}\r
+\r
+uint16_t pah831x_get_chip_id(void)\r
+{\r
+    uint16_t id = 0;\r
+    pah_831x_get_product_id(&id);\r
+    return id;\r
+}\r
+\r
+uint8_t pah831x_get_hrs(void)\r
+{\r
+    return ret_hrs;\r
+}\r
+\r
+uint8_t pah831x_get_spo2(void)\r
+{\r
+    return ret_spo2;\r
+}\r
+\r
+uint8_t pah831x_get_hrv(void)\r
+{\r
+    return ret_hrv;\r
+}\r
+\r
+uint8_t pah831x_get_wear_status(void)\r
+{\r
+    return ret_wear;\r
+}\r
+\r
+void pah831x_set_bp_cali_data(int *sbp,int *dbp)\r
+{\r
+    if(sbp == NULL || dbp == NULL)\r
+        return;\r
+\r
+    Benchmark_SBP = *sbp;\r
+    Benchmark_DBP = *dbp;\r
+\r
+    int user_info[5] = {0};\r
+    get_user_info_from_config_model(user_info);\r
+    user_age = user_info[0];\r
+    user_height = user_info[3];\r
+\r
+    // int user_info[5] = {0};\r
+    // get_user_info_from_config_model(user_info);\r
+    // memset(&scl, 0, sizeof(scl));\r
+    // scl.iData[0] = 1;\r
+    // scl.iData[1] = user_info[0];\r
+    // scl.iData[2] = !user_info[1]; //APP 1女 0男\r
+    // scl.iData[3] = user_info[2];\r
+    // scl.iData[4] = user_info[3];\r
+    // scl.iData[5] = user_info[4];\r
+    // CWM_OS_dbgPrintf("set user info : age[%d] , sex[%d] , weight[%d] , height[%d] , method[%d] \r\n",\r
+    // user_info[0],user_info[1],user_info[2],user_info[3],user_info[4]);\r
+}\r
+\r
+void pah831x_read_calidata(void)\r
+{\r
+    // C89 规范:所有变量定义在函数开头\r
+    int cali_data[5] = {0};\r
+    FILE *fp = NULL;\r
+    size_t ret = 0;\r
+\r
+    fp = fopen(FILEPATH, "rb");  // 二进制读取,嵌入式/跨平台更安全\r
+    if (fp == NULL)\r
+    {\r
+        printf("%s fopen failed\n", FILEPATH);\r
+\r
+        cal_sbp_in = 26   ;//read from flash\r
+        cal_dbp_in = 9  ;//read from flash\r
+        CalValue_in = 29   ;//read from flash\r
+        CalValue1_in = 86   ;//read from flash\r
+\r
+        return;\r
+    }\r
+\r
+    // 读取数据,并检查是否读取成功(必须判断返回值)\r
+    ret = fread(cali_data, sizeof(cali_data), 1, fp);\r
+    fclose(fp);  // 先关闭文件,再判断结果\r
+\r
+    // 读取失败:直接返回,不覆盖有效数据\r
+    if (ret != 1)\r
+    {\r
+        printf("read cali data failed!\n");\r
+\r
+        cal_sbp_in = 26   ;//read from flash\r
+        cal_dbp_in = 9  ;//read from flash\r
+        CalValue_in = 29   ;//read from flash\r
+        CalValue1_in = 86   ;//read from flash\r
+\r
+        return;\r
+    }\r
+\r
+    // 数据赋值\r
+    cal_sbp_in  = cali_data[0];\r
+    cal_dbp_in  = cali_data[1];\r
+    CalValue_in = cali_data[2];\r
+    CalValue1_in = cali_data[3];\r
+    bp_cali_cnt = cali_data[4];\r
+\r
+    printf("read cali data success\n");\r
+}\r
+\r
+/**\r
+ * @brief 保存血压校准数据\r
+ */\r
+void pah831x_save_calidata(void)\r
+{\r
+\r
+    if(!cal_sbp_in && !cal_dbp_in && !CalValue_in && !CalValue1_in)\r
+    {\r
+        printf("error cali param!\n");\r
+        return;\r
+    }\r
+\r
+    // C89 规范:所有变量定义在函数开头\r
+    int cali_data[5] = {0};\r
+    FILE *fp = NULL;\r
+    size_t ret = 0;\r
+\r
+    // 填充校准数据\r
+    cali_data[0] = cal_sbp_in;\r
+    cali_data[1] = cal_dbp_in;\r
+    cali_data[2] = CalValue_in;\r
+    cali_data[3] = CalValue1_in;\r
+    cali_data[4] = ++bp_cali_cnt;  // 先保存当前计数值\r
+\r
+    fp = fopen(FILEPATH, "wb");  // 二进制写入,避免文本模式转义\r
+    if (fp == NULL)\r
+    {\r
+        printf("%s fopen failed\n", FILEPATH);\r
+        return;\r
+    }\r
+\r
+    // 写入数据,并检查是否成功\r
+    ret = fwrite(cali_data, sizeof(cali_data), 1, fp);\r
+    fclose(fp);\r
+\r
+    if (ret != 1)\r
+    {\r
+        printf("save cali data failed!\n");\r
+        return;\r
+    }\r
+\r
+}\r
+\r
+bool is_pah831x_need_cali(void)\r
+{\r
+    pah831x_read_calidata();\r
+\r
+    return bp_cali_cnt >= 10 ? 0 : 1;\r
+}
\ No newline at end of file
diff --git a/code/sdk/zhihui/drivers/ppg/pah831x/pah_sensor/pah831x_main.h b/code/sdk/zhihui/drivers/ppg/pah831x/pah_sensor/pah831x_main.h
new file mode 100644 (file)
index 0000000..3a62944
--- /dev/null
@@ -0,0 +1,381 @@
+\r
+#pragma once\r
+// c\r
+#include <stdarg.h>\r
+#include <stdio.h>\r
+#include <stdbool.h>\r
+#include <stdlib.h>\r
+\r
+#include <string.h>\r
+#include <stdint.h>\r
+\r
+// AE Info Read\r
+typedef struct\r
+{\r
+    \r
+    uint32_t                Expo_time_A;\r
+    uint32_t                Expo_time_B;\r
+    uint32_t                Expo_time_C;\r
+    uint32_t                Expo_time_D;\r
+    uint32_t                touch_data;\r
+    uint8_t                 LEDDAC_A;\r
+    uint8_t                 LEDDAC_B;\r
+    uint8_t                 LEDDAC_C;\r
+    uint8_t                 LEDDAC_D;\r
+    int32_t                 cap_touch_data;\r
+} pah_ae_info;\r
+\r
+\r
+typedef struct {\r
+    uint64_t            end_timestamp;\r
+    uint64_t            start_timestamp;\r
+    uint8_t             ppg_data_ready;\r
+    uint32_t            duration;\r
+    uint8_t             is_touched ;\r
+    uint8_t             ch_num;\r
+    uint32_t            sample_num_per_ch;\r
+    uint8_t             *ppg_raw_data;\r
+    uint8_t             *ppg_dac_data;\r
+    uint16_t             *ppg_adc_data;\r
+    uint32_t            touch_value ;\r
+    uint8_t             afe_gain_flag;\r
+  //  pah_ae_info         pah_ae_info_data;\r
+  //  pah_815x_touch_data touch_data;\r
+    //uint8_t             ppg_status;\r
+} ppg_data_out;   \r
+\r
+typedef struct {\r
+    uint64_t            end_timestamp;\r
+//    uint64_t            start_timestamp;\r
+    uint32_t            duration;\r
+//   uint8_t             ppg_data_ready;\r
+    uint8_t             is_touched ;\r
+    uint8_t             ch_num;\r
+    uint8_t             acc_data_num;\r
+    uint32_t            sample_num_per_ch;\r
+    uint32_t             ppg_raw_data[55];\r
+    uint8_t             ppg_dac_data[6];\r
+    int16_t             acc_data[170];\r
+ //   uint32_t            touch_value ;\r
+    uint32_t            frame_count ;\r
+    uint8_t             afe_gain_flag;\r
+  //  pah_ae_info         pah_ae_info_data;\r
+  //  pah_815x_touch_data touch_data;\r
+    //uint8_t             ppg_status;\r
+} ppg_data_out_buffer;   \r
+\r
+\r
+\r
+typedef struct {\r
+    uint64_t            end_timestamp;\r
+    uint64_t            start_timestamp;\r
+    uint8_t             ecg_data_ready;\r
+    uint32_t            duration;\r
+    uint8_t             is_touched ;\r
+    uint8_t             ch_num;\r
+    uint32_t            sample_num_per_ch;\r
+    uint8_t             *ecg_raw_data;\r
+    float               *ecg_raw_data_mv;\r
+    uint8_t             *ecg_tag_data;\r
+  //  pah_ae_info         pah_ae_info_data;\r
+  //  pah_815x_touch_data touch_data;\r
+    //uint8_t             ppg_status;\r
+} ecg_data_out;\r
+\r
+\r
+typedef enum\r
+{\r
+    PAH831X_WORK_IDLE = 0,\r
+    PAH831X_WORK_DRI,\r
+    PAH831X_WORK_POLLING,\r
+} pah831x_work_mode;\r
+typedef enum\r
+{\r
+    PAH831X_INIT_IDLE = 0,\r
+    PAH831X_INIT_AUTO_MODE,\r
+    PAH831X_INIT_ALWAYS_RUN,\r
+    PAH831X_INIT_TOUCH_ONLY,\r
+} pah831x_operate_mode;\r
+typedef enum\r
+{\r
+    PAH831X_PPG_REG_SETTING_IDLE = 0,\r
+    PAH831X_PPG_REG_SETTING_1,\r
+    PAH831X_PPG_REG_SETTING_2,\r
+    PAH831X_PPG_REG_SETTING_3,\r
+    PAH831X_PPG_REG_SETTING_4,\r
+    PAH831X_PPG_REG_SETTING_5,\r
+    PAH831X_PPG_REG_SETTING_6, // add\r
+    PAH831X_PPG_REG_SETTING_7, // add\r
+    PAH831X_PPG_REG_SETTING_8, // add\r
+    PAH831X_PPG_REG_SETTING_9, // add\r
+    PAH831X_PPG_REG_SETTING_10, // add\r
+\r
+} pah831x_ppg_reg_setting_table;\r
+typedef enum\r
+{\r
+    PAH831X_ECG_REG_SETTING_IDLE = 0,\r
+    PAH831X_ECG_REG_SETTING_1,\r
+    PAH831X_ECG_REG_SETTING_2,\r
+    PAH831X_ECG_REG_SETTING_3,\r
+    PAH831X_ECG_REG_SETTING_4,\r
+    PAH831X_ECG_REG_SETTING_5,\r
+    PAH831X_ECG_REG_SETTING_6, // add\r
+    PAH831X_ECG_REG_SETTING_7, // add\r
+    PAH831X_ECG_REG_SETTING_8, // add\r
+    PAH831X_ECG_REG_SETTING_9, // add\r
+    PAH831X_ECG_REG_SETTING_10, // add   \r
+\r
+} pah831x_ecg_reg_setting_table;\r
+\r
+\r
+typedef enum {\r
+    pah_AFE_GAIN_CHA_IDLE      =0 ,\r
+    pah_AFE_GAIN_CHA_75K       =1 ,\r
+    pah_AFE_GAIN_CHA_150K      =2 ,\r
+       pah_AFE_GAIN_CHA_350K      =3 ,\r
+       pah_AFE_GAIN_CHA_1000K     =4 ,\r
+    pah_AFE_GAIN_CHA_350K_LOW  =5 ,\r
+\r
+} pah_afe_gain_e;\r
+\r
+typedef enum\r
+{\r
+    alg_status_idle,\r
+    alg_status_process,\r
+    alg_status_close,\r
+    alg_status_finish,\r
+    alg_status_data_weak,\r
+} alg_status_e;\r
+\r
+typedef enum {\r
+    pah_alg_mode_IDLE     =0x00 , \r
+    pah_alg_mode_HR_25HZ  =0x02 ,// HR Detect\r
+    pah_alg_mode_HR       =0x04, // HR Detect\r
+       pah_alg_mode_SPO2     =0x08 ,// SPO2\r
+       pah_alg_mode_HRV      =0x10 ,// HRV\r
+    pah_alg_mode_STRESS   =0x20 ,// STRESS\r
+       pah_alg_mode_RR       =0x40 ,// RR\r
+    pah_alg_mode_SS       =0x80 ,// SS\r
+} pah_alg_mode_e;\r
+\r
+typedef enum {\r
+    pah_alg_mode_bit_HR_25HZ  =1 ,// HR Detect\r
+    pah_alg_mode_bit_HR       =2 ,// HR Detect\r
+       pah_alg_mode_bit_SPO2     =3 ,// SPO2\r
+       pah_alg_mode_bit_HRV      =4 ,// HRV\r
+    pah_alg_mode_bit_STRESS   =5 ,// STRESS\r
+       pah_alg_mode_bit_RR       =6 ,// RR\r
+    pah_alg_mode_bit_SS       =7 ,// SS\r
+} pah_alg_mode_bit_e;\r
+\r
+\r
+\r
+\r
+\r
+typedef enum\r
+{\r
+    LOG_DATA_DISABLE=0,\r
+    LOG_DATA_ENABLE=1,\r
+} lod_data_en_e;\r
+\r
+\r
+typedef enum\r
+{\r
+    ECG_PPG_BP_ESTIMATE=0,\r
+    ECG_PPG_BP_CALI=1,\r
+} ecg_bp_mode_e;\r
+\r
+typedef enum\r
+{\r
+    HRD_ACTION_MODE_IDLE               =0 ,\r
+    HRD_ACTION_MODE_NORMAL             =1 ,\r
+    HRD_ACTION_MODE_OUTDOOR_RUN        =2 ,    \r
+    HRD_ACTION_MODE_INDOOR_RUN         =3 ,\r
+    HRD_ACTION_MODE_OUTDOOR_WALK       =4 ,\r
+    HRD_ACTION_MODE_INDOOR_WALK        =5 ,\r
+    HRD_ACTION_MODE_OUTDOOR_BIKE       =6 ,\r
+    HRD_ACTION_MODE_INDOOR_BIKE        =7 ,\r
+    HRD_ACTION_MODE_Elliptical_trainer =8 ,\r
+    HRD_ACTION_MODE_Rowing_machine     =9 ,\r
+    HRD_ACTION_MODE_HITT               =10,\r
+    HRD_ACTION_MODE_BALL               =11,\r
+    HRD_ACTION_MODE_Swimming           =12,\r
+    HRD_ACTION_MODE_reserved1          =13,    \r
+    HRD_ACTION_MODE_reserved2          =14,    \r
+} hrd_action_mode_e;\r
+///*{ Parameter, , NORMAL ,  INDOOR_RUN , INDOOR_WALK , OUTDOOR_BIKE , Rowing_machine , HITT  , OUTDOOR_RUN , OUTDOOR_WALK , INDOOR_BIKE , Elliptical_trainer , BALL  , reserved */\r
+#if 0\r
+typedef enum\r
+{\r
+ORUN  = 0,//�ǥ~�]�B\r
+IRUN = 1,//�Ǥ��]�B\r
+OWALK = 2,//��~����\r
+IWALK = 3,//�Ǥ�����\r
+HIKING = 4,//�{�B\r
+OCYCLE = 5,//��~�M��\r
+ICYCLE = 6,//�Ǥ��樮\r
+CRICKET = 7,//�O�y\r
+FOOTBALL = 8,//���y\r
+PSWIM = 9,//�a����a\r
+OSWIM = 10,//�}��ϴ�a\r
+YOGA = 11,//���\r
+PILATES = 12,//���Դ�\r
+DANCE = 13,//���R\r
+ZUMBA = 14,//�L�ڻR\r
+ROWER = 15,//�E���\r
+ELLIPTICAL = 16,//����\r
+CTRAINING = 17,//�֤߰V�m\r
+TSTRAINING = 18,//�DzΤO�q�V�m\r
+FSTRAINING = 19,//�\��ʤO�q�V�m\r
+HIIT = 20,//HIIT\r
+COOLDOWN = 21,//��z���P\r
+WORKOUT = 22,//�ۥѰV�m\r
+FITNESS = 23,//����\r
+TRAIL_RUNNING = 24,//\r
+// ����,//\r
+TREADMILL = 25,//��B��\r
+AEROBICS = 26,//���񰷨���\r
+SIT_UP = 27,//���װ_��\r
+PLANK = 28,//���O�伵\r
+JUMPING_JACK = 29,//�}�X��\r
+CHIN_UP = 30,//����V�W\r
+PUSH_UP = 31,//���׼�\r
+DEEP_SQUAT = 32,//�`��\r
+HIGH_KNEE_LIFT = 33,//����L\r
+DUMBBELL = 34,//�׹a\r
+BARBELL = 35,//���a\r
+BOXING = 36,//����\r
+KICKBOXING = 37,//�ۥѷi��\r
+HORIZONTAL_BAR = 38,//���\r
+PARALLEL_BARS = 39,//����\r
+WALKING_MACHINE = 40,//���B��\r
+SUMMIT_TRAINERS = 41,//�n�s��\r
+/*�y��*///\r
+BOWLING = 42,//�O�ֲy\r
+TENNIS = 43,//���y\r
+TABLE_TENNIS = 44,//���y\r
+GOLF = 45,//�����Ҳy\r
+BASKETBALL = 46,//�x�y\r
+BADMINTON = 47,//�Ф�y\r
+HOCKEY = 48,//���Ҳy\r
+RUGBY = 49,//���V�y\r
+HANDBALL = 50,//��y\r
+SQUASH = 51,//���y\r
+BASEBALL = 52,//�βy\r
+SOFTBALL = 53,//�S�y\r
+SHUTTLECOCK = 54,//���y\r
+SEPAKTAKRAW = 55,//�òy\r
+/*�𶢹B��*///\r
+STREET_DANCE = 56,//��R\r
+MOUNTAIN_CLINBING = 57,//�n�s\r
+ROPE_SKIPPING = 58,//��÷\r
+CLIMB_STAIRS = 59,//����\r
+BALLET = 60,//����\r
+SOCIAL_DANCE = 61,//����R\r
+DARTS = 62,//����\r
+HORSEBACK_RIDING = 63,//�M��\r
+ROLLER_SKATING = 64,//����\r
+TAI_CHI = 65,//�ӷ�\r
+FRISBEE = 66,//���L\r
+HULA_HOOP = 67,//�I�հ�\r
+/*�B���B��*///\r
+SLEIGH = 68,//����\r
+SKATING = 69,//�ƦB\r
+BOBSLEIGH_AND_TOBOGGANING = 70,//����\r
+CURLING = 71,//�B��\r
+ICE_HOCKEY = 72,//�B�y\r
+/*���W�B��*///\r
+SURFING = 73,//�Į�\r
+SAILBOAT = 74,//�|��\r
+SAILBOARD = 75,//�|�O\r
+FOLDBOATING = 76,//�ָ�\r
+CANOEING = 77,//�E��\r
+BOAT_RACE = 78,//�ɸ�\r
+MOTORBOAT = 79,//������\r
+WATER_POLO = 80,//���y\r
+\r
+/*�����B��*///\r
+SLIDING_PLATE = 81,//�ƪO\r
+ROCK_CLIMBING = 82,//�k��\r
+BUNGEE_JUMPING = 83,//�۷�\r
+PARKOUR = 84,//�]��\r
+OTHER = 85,//��L\r
+\r
+/*�s�W�B��*///\r
+SPINNING = 86,//�ʷP�樮\r
+MARTIAL_ARTS = 87,//�Z�N\r
+TAEKWONDO = 88,//�`���D\r
+KARATE = 89,//�Ť�D\r
+GYMNASTICS = 90,//���\r
+PADEL = 91,//Ţ�����y\r
+PICKLEBALL = 92,//�ǧJ�y\r
+SNOWBOARDING = 93,//��O�Ƴ�\r
+SKIING = 94,//���O�Ƴ�\r
+PADDLING = 95,//����\r
+BMX = 96,//�p����\r
+\r
+HRD_SPORT_MODE_IDLE               =200 ,\r
+HRD_SPORT_MODE_NORMAL             =201 ,\r
+HRD_SPORT_MODE_OUTDOOR_RUN        =202 ,    \r
+HRD_SPORT_MODE_INDOOR_RUN         =203 ,\r
+HRD_SPORT_MODE_OUTDOOR_WALK       =204 ,\r
+HRD_SPORT_MODE_INDOOR_WALK        =205 ,\r
+HRD_SPORT_MODE_OUTDOOR_BIKE       =206 ,\r
+HRD_SPORT_MODE_INDOOR_BIKE        =207 ,\r
+HRD_SPORT_MODE_Elliptical_trainer =208 ,\r
+HRD_SPORT_MODE_Rowing_machine     =209 ,\r
+HRD_SPORT_MODE_HITT               =210,\r
+HRD_SPORT_MODE_BALL               =211,\r
+HRD_SPORT_MODE_Swimming           =212,\r
+HRD_SPORT_MODE_reserved1          =213,    \r
+HRD_SPORT_MODE_reserved2          =214, \r
+} hrd_sport_mode_e;\r
+#endif\r
+\r
+\r
+\r
+\r
+\r
+//void uart_print(const char* format, ...);\r
+void pah_interrupt_handle(void);\r
+//void demo_pah831x(void);\r
+void pah831x_sensor_init(void);\r
+void pah831x_sensor_start(uint8_t work_mode ,uint8_t operate_mode ,uint8_t ppg_reg_setting ,uint8_t ecg_reg_setting,uint16_t interrupt_report_num,float sample_period );\r
+void pah831x_sensor_task(void);\r
+\r
+uint8_t get_ppg_enable(void);\r
+uint8_t get_ppg_data_ready(void);\r
+void clear_ppg_data_ready(void);\r
+ppg_data_out get_ppg_data_out(void);\r
+\r
+uint8_t get_ecg_enable(void);\r
+uint8_t get_ecg_data_ready(void);\r
+void clear_ecg_data_ready(void);\r
+ecg_data_out get_ecg_data_out(void);\r
+\r
+void pah_sensor_stop(void);\r
+\r
+void set_ir_r_led_switch_status(bool status);\r
+\r
+uint16_t get_pah831x_touch_value(void);\r
+\r
+void pah831x_control(char *mode,uint8_t enable);\r
+\r
+void pah831x_timer_handler(void);\r
+\r
+uint8_t pah831x_get_hrs(void);\r
+\r
+uint8_t pah831x_get_spo2(void);\r
+\r
+uint8_t pah831x_get_hrv(void);\r
+\r
+\r
+void pah8311_get_bp(int *sbp,int *dbp);\r
+\r
+void pah831x_read_calidata(void);\r
+\r
+void pah831x_save_calidata(void);\r
+\r
+void pah831x_set_bp_cali_data(int *sbp,int *dbp);\r
+\r
+bool is_pah831x_need_cali(void);
\ No newline at end of file
diff --git a/code/sdk/zhihui/drivers/ppg/pah831x/pah_sensor/pah831x_reg_default_note_0109_1LED.h b/code/sdk/zhihui/drivers/ppg/pah831x/pah_sensor/pah831x_reg_default_note_0109_1LED.h
new file mode 100644 (file)
index 0000000..2a8b745
--- /dev/null
@@ -0,0 +1,777 @@
+#pragma once \r
+/**\r
+ * Copyright (c) 2022 PixArt Imaging Inc.\r
+ * All Rights Reserved.\r
+ * Confidential and Proprietary - PixArt Imaging Inc.\r
+ **/\r
+#include <stdint.h>\r
+#include "pah831x_config.h"\r
+\r
+static const uint8_t PAH831X_REG_INIT[][2] = {\r
+    { 0x7F, 0x05 },//Bank5\r
+    { 0x00, 0x3F },\r
+    { 0x01, 0x00 },\r
+    { 0x02, 0x80 },\r
+    { 0x05, 0x00 },\r
+    { 0x06, 0x04 },\r
+    { 0x07, 0x00 },\r
+    { 0x08, 0xD0 },\r
+    { 0x09, 0x00 },\r
+    { 0x0A, 0x60 },\r
+    { 0x0B, 0x17 },\r
+    { 0x0D, 0x00 },\r
+    { 0x0E, 0x80 },\r
+    { 0x11, 0x00 },\r
+    { 0x12, 0x04 },\r
+    { 0x13, 0x00 },\r
+    { 0x14, 0xD0 },\r
+    { 0x15, 0x00 },\r
+    { 0x16, 0x60 },\r
+    { 0x17, 0x17 },\r
+    { 0x19, 0x00 },\r
+    { 0x1A, 0x80 },\r
+    { 0x1D, 0x00 },\r
+    { 0x1E, 0x04 },\r
+    { 0x1F, 0x00 },\r
+    { 0x20, 0xD0 },\r
+    { 0x21, 0x00 },\r
+    { 0x22, 0x60 },\r
+    { 0x23, 0x17 },\r
+    { 0x25, 0x00 },\r
+    { 0x26, 0x80 },\r
+    { 0x29, 0x00 },\r
+    { 0x2A, 0x04 },\r
+    { 0x2B, 0x00 },\r
+    { 0x2C, 0xD0 },\r
+    { 0x2D, 0x00 },\r
+    { 0x2E, 0x60 },\r
+    { 0x2F, 0x17 },\r
+    { 0x31, 0x00 },\r
+    { 0x32, 0x80 },\r
+    { 0x35, 0x00 },\r
+    { 0x36, 0x04 },\r
+    { 0x37, 0x00 },\r
+    { 0x38, 0xD0 },\r
+    { 0x39, 0x00 },\r
+    { 0x3A, 0x60 },\r
+    { 0x3B, 0x17 },\r
+    { 0x3D, 0x00 },\r
+    { 0x3E, 0x80 },\r
+    { 0x41, 0x00 },\r
+    { 0x42, 0x04 },\r
+    { 0x43, 0x00 },\r
+    { 0x44, 0xD0 },\r
+    { 0x45, 0x00 },\r
+    { 0x46, 0x60 },\r
+    { 0x47, 0x17 },\r
+    { 0x7F, 0x04 },//Bank4\r
+    { 0x13, 0x09 },\r
+    { 0x29, 0x09 },\r
+    { 0x14, 0x20 },\r
+    { 0x2A, 0x20 },\r
+    { 0x00, 0xC6 },\r
+    { 0x03, 0x96 },\r
+    { 0x06, 0x96 },\r
+    { 0x09, 0xB6 },\r
+    { 0x0C, 0xB6 },\r
+    { 0x0F, 0xB6 },\r
+    { 0x12, 0x86 },\r
+    { 0x16, 0xC6 },\r
+    { 0x19, 0x96 },\r
+    { 0x1C, 0x96 },\r
+    { 0x1F, 0xB6 },\r
+    { 0x22, 0xB6 },\r
+    { 0x25, 0xB6 },\r
+    { 0x28, 0x86 },\r
+    { 0x2D, 0x01 },\r
+    { 0x2F, 0x01 },\r
+    { 0x31, 0x01 },\r
+    { 0x33, 0x01 },\r
+    { 0x35, 0x01 },\r
+    { 0x37, 0x01 },\r
+    { 0x01, 0x00 },\r
+    { 0x04, 0x00 },\r
+    { 0x07, 0x00 },\r
+    { 0x0A, 0x00 },\r
+    { 0x0D, 0x00 },\r
+    { 0x10, 0x00 },\r
+    { 0x17, 0x00 },\r
+    { 0x1A, 0x00 },\r
+    { 0x1D, 0x00 },\r
+    { 0x20, 0x00 },\r
+    { 0x23, 0x00 },\r
+    { 0x26, 0x00 },\r
+    { 0x7F, 0x03 },//Bank3\r
+    { 0x0B, 0x36 },\r
+    { 0x50, 0x22 },\r
+    { 0x52, 0x01 },\r
+    { 0x58, 0x0C },\r
+    { 0x59, 0x08 },\r
+    { 0x5A, 0x08 },\r
+    { 0x0B, 0x37 },\r
+    { 0x50, 0x00 },\r
+    { 0x70, 0x10 },\r
+    { 0x7F, 0x02 },//Bank2\r
+    { 0x4B, 0x00 },\r
+    { 0x4C, 0x00 },\r
+    { 0x7F, 0x01 },//Bank1\r
+    { 0x00, 0x98 },\r
+    { 0x04, 0x40 },\r
+    { 0x05, 0x00 },\r
+    { 0x06, 0x03 },\r
+    { 0x08, 0x00 },\r
+    { 0x09, 0x33 },\r
+    { 0x0B, 0x00 },\r
+    { 0x0C, 0xBB },\r
+    { 0x0D, 0xF2 },\r
+    { 0x0F, 0x0E },\r
+    { 0x1A, 0x20 },\r
+    { 0x20, 0x07 },\r
+    { 0x21, 0x21 },\r
+    { 0x23, 0x95 },\r
+    { 0x26, 0x07 },\r
+    { 0x76, 0x58 },\r
+    { 0x77, 0xA0 },\r
+    { 0x78, 0x0F },\r
+    { 0x79, 0xA0 },\r
+    { 0x7A, 0x0F },\r
+    { 0x7B, 0x80 },\r
+    { 0x7C, 0x3E },\r
+    { 0x7D, 0x77 },\r
+    { 0x7E, 0x02 },\r
+    { 0x34, 0x04 },\r
+    { 0x36, 0x0C },\r
+    { 0x3A, 0x0C },\r
+    { 0x3E, 0x0C },\r
+    { 0x42, 0x0C },\r
+    { 0x46, 0x0C },\r
+    { 0x4A, 0x0C },\r
+    { 0x4E, 0x0C },\r
+    { 0x52, 0x0C },\r
+    { 0x56, 0x0C },\r
+    { 0x5A, 0x0C },\r
+    { 0x5E, 0x0C },\r
+    { 0x62, 0x0C },\r
+    { 0x66, 0x0C },\r
+    { 0x37, 0x07 },\r
+    { 0x3B, 0x07 },\r
+    { 0x3F, 0x07 },\r
+    { 0x43, 0x07 },\r
+    { 0x47, 0x07 },\r
+    { 0x4B, 0x07 },\r
+    { 0x4F, 0x07 },\r
+    { 0x53, 0x07 },\r
+    { 0x57, 0x07 },\r
+    { 0x5B, 0x07 },\r
+    { 0x5F, 0x07 },\r
+    { 0x63, 0x07 },\r
+    { 0x67, 0x07 },\r
+    { 0x68, 0x0F },\r
+    { 0x6F, 0x0F },\r
+    { 0x65, 0x06 },\r
+    { 0x7F, 0x00 },//Bank0\r
+    { 0x29, 0x01 },\r
+    { 0x2A, 0x00 },\r
+    { 0x2B, 0x01 },\r
+    { 0x2C, 0x00 },\r
+    { 0x27, 0x20 },\r
+    { 0x28, 0x00 },\r
+    { 0x2D, 0x00 },\r
+    { 0x2E, 0x03 },\r
+    { 0x5F, 0x00 },\r
+    { 0x60, 0x00 },\r
+    { 0x46, 0x00 },\r
+    { 0x47, 0x00 },\r
+    { 0x48, 0x00 },\r
+    { 0x35, 0x14 },\r
+    { 0x36, 0x00 },\r
+    { 0x37, 0x00 },\r
+    { 0x5A, 0x02 },\r
+    { 0x5B, 0x02 },\r
+    { 0x12, 0x08 },\r
+    { 0x13, 0x08 },\r
+    { 0x14, 0x08 },\r
+    { 0x15, 0x08 },\r
+    { 0x16, 0x08 },\r
+    { 0x6D, 0x08 },\r
+    { 0x6E, 0x08 },\r
+    { 0x17, 0x00 },\r
+    { 0x18, 0x7F },\r
+    { 0x19, 0x7F },\r
+    { 0x49, 0x01 },\r
+    { 0x4A, 0x60 },\r
+    { 0x4B, 0x6D },\r
+    { 0x4C, 0x20 },\r
+    { 0x4D, 0x4E },\r
+    { 0x4E, 0x01 },\r
+    { 0x4F, 0x0C },\r
+    { 0x32, 0xFF },\r
+    { 0x5C, 0xFF },\r
+    { 0x54, 0xFF },\r
+    { 0x55, 0xFF },\r
+    { 0x50, 0x17 },\r
+    { 0x51, 0x17 },\r
+    { 0x52, 0x17 },\r
+    { 0x53, 0x17 },\r
+    { 0x70, 0x17 },\r
+    { 0x71, 0x17 },\r
+    { 0x56, 0x01 },\r
+};               \r
+                 \r
+static const uint8_t PAH831X_REG_DEINIT[][2] = {\r
+    { 0x7F, 0x01 }, //Bank1\r
+    { 0x00, 0x98 }, //{T_BG_CHOPCLK_EnH, T_BG_PADOUT_EnH, T_OSC_4M_CHOP_EnH, B_OSC_32K_EnH, T_POR_EnL, T_V2I_CURRENT_DIV2_EnH, T_TST_TRIM_EnH, T_VPP_SW_EnH}\r
+};\r
+\r
+static const uint8_t PAH831X_REG_TOUCH[][2] = {\r
+    { 0x7F, 0x03 },//Bank3\r
+    { 0x0B, 0x36 },//{Dummy[1:0], B_PPG1_AMBC_PWRSV_SEL_EnH, B_PPG2_AMBC_PWRSV_SEL_EnH, Dummy, B_BG_PWRSV_SEL_EnH, B_PMU_V2I_PWRSV_SEL_EnH, B_OSC_4M_PWRSV_SEL_EnH}\r
+#ifdef Ext_LPO_CLK_FROM_GPIO2   \r
+    { 0x59 , 0x0C }, //{Dummy[2:0], R_GPIO_1, R_GPIO_1_IEB, R_GPIO_1_OEB, R_GPIO_1_PULLL_EnH, R_GPIO_1_PULLH_EnH}\r
+    { 0x5B , 0x08 }, //{Dummy[2:0], R_GPIO_3, R_GPIO_3_IEB, R_GPIO_3_OEB, R_GPIO_3_PULLL_EnH, R_GPIO_3_PULLH_EnH}\r
+   // { 0x59, 0x08 }, //{Dummy[2:0], R_GPIO_1, R_GPIO_1_IEB, R_GPIO_1_OEB, R_GPIO_1_PULLL_EnH, R_GPIO_1_PULLH_EnH}\r
+    { 0x52 , 0x01 }, //{Dummy[2:0], R_GPIO_2_Open_Drain_EnH, R_GPIO_1_Open_Drain_EnH, R_GPIO_DRV[1:0], R_GPIO_18V_EnL}  \r
+#else\r
+    { 0x59 , 0x0C }, //{Dummy[2:0], R_GPIO_1, R_GPIO_1_IEB, R_GPIO_1_OEB, R_GPIO_1_PULLL_EnH, R_GPIO_1_PULLH_EnH}\r
+    { 0x5B , 0x08 }, //{Dummy[2:0], R_GPIO_3, R_GPIO_3_IEB, R_GPIO_3_OEB, R_GPIO_3_PULLL_EnH, R_GPIO_3_PULLH_EnH}\r
+    { 0x52 , 0x00 }, //{Dummy[2:0], R_GPIO_2_Open_Drain_EnH, R_GPIO_1_Open_Drain_EnH, R_GPIO_DRV[1:0], R_GPIO_18V_EnL}\r
+    { 0x5A , 0x04 }, //{Dummy[2:0], R_GPIO_2, R_GPIO_2_IEB, R_GPIO_2_OEB, R_GPIO_2_PULLL_EnH, R_GPIO_2_PULLH_EnH}\r
+    { 0x54 , 0x14 }, //{Dummy[3:0], R_Ext_CLK_Sel, R_Ext_32K_CLK_Sel, R_Ext_32K_CLK, R_Ext_CLK}\r
+    { 0x54 , 0x16 }, //{Dummy[3:0], R_Ext_CLK_Sel, R_Ext_32K_CLK_Sel, R_Ext_32K_CLK, R_Ext_CLK}\r
+#endif\r
+    { 0x0B, 0x37 },//{Dummy[1:0], B_PPG1_AMBC_PWRSV_SEL_EnH, B_PPG2_AMBC_PWRSV_SEL_EnH, Dummy, B_BG_PWRSV_SEL_EnH, B_PMU_V2I_PWRSV_SEL_EnH, B_OSC_4M_PWRSV_SEL_EnH}                                                                                                                        \r
+    { 0x7F, 0x04 },//Bank4   \r
+    { 0x12, 0x81 },//{B_PPG_ChT_LEDDAC1_IOUT_CAL_EnH, B_PPG_ChT_LEDDAC1_RGE[2:0], B_PPG_ChT_LEDDAC1_RGE_CAL[3:0]}                             \r
+    { 0x28, 0x81 },//{B_PPG_ChT_LEDDAC2_IOUT_CAL_EnH, B_PPG_ChT_LEDDAC2_RGE[2:0], B_PPG_ChT_LEDDAC2_RGE_CAL[3:0]}   \r
+    { 0x13, 0x01 },//B_PPG_ChT_LEDDAC1_CH_SEL[5:0], IR\r
+    { 0x29, 0x01 },//B_PPG_ChT_LEDDAC2_CH_SEL[5:0], IR\r
+    { 0x14, 0x20 },//B_PPG_ChT_LEDDAC1_CODE[7:0]\r
+    { 0x2A, 0x20 },//B_PPG_ChT_LEDDAC2_CODE[7:0]\r
+    { 0x7F, 0x00 },//Bank0    \r
+    { 0x4B, 0x0C },//R_TouchDetection_Th_Hi[15:8]   3168\r
+    { 0x4D, 0x06 },//R_TouchDetection_Th_Low[15:8]  1568\r
+    { 0x7F, 0x01 },//Bank1   \r
+    { 0x65, 0x01 },//{B_PPG1_ChT_AMBC_INV_EnH, B_PPG1_ChT_AMBC_LSB_ADJ, B_PPG1_ChT_PD_CH_SEL[4:0]}  \r
+    { 0x7F, 0x00 },//Bank0\r
+    { 0x03, 0x80 },//Golden report period[7:0] (1T=31.25us)\r
+    { 0x04, 0x0C },//Golden report period[15:8], 10Hz\r
+    { 0x4F, 0x04 },//R_NoTouchDetection_Count_Th[4:0]\r
+    { 0x1B, 0x10 },//{R_sinc_add_first, RDB_LOD_EnH, RDB_ECG_EnH, RDB_ChT_EnH, RDB_ChD_EnH, RDB_ChC_EnH, RDB_ChB_EnH, RDB_ChA_EnH} \r
+    { 0x68, 0x00 },//{Dummy[5:0], RDB_ChF_EnH, RDB_ChE_EnH};\r
+};\r
+\r
+#define PAH831X_REG_PPG_1_ODR (20)\r
+static const uint8_t PAH831X_REG_PPG_1[][2] = {\r
+    { 0x7F, 0x03 },//Bank3\r
+    { 0x0B, 0x36 },\r
+#ifdef Ext_LPO_CLK_FROM_GPIO2   \r
+    { 0x59 , 0x0C }, //{Dummy[2:0], R_GPIO_1, R_GPIO_1_IEB, R_GPIO_1_OEB, R_GPIO_1_PULLL_EnH, R_GPIO_1_PULLH_EnH}\r
+    { 0x5B , 0x08 }, //{Dummy[2:0], R_GPIO_3, R_GPIO_3_IEB, R_GPIO_3_OEB, R_GPIO_3_PULLL_EnH, R_GPIO_3_PULLH_EnH}\r
+   // { 0x59, 0x08 }, //{Dummy[2:0], R_GPIO_1, R_GPIO_1_IEB, R_GPIO_1_OEB, R_GPIO_1_PULLL_EnH, R_GPIO_1_PULLH_EnH}\r
+    { 0x52 , 0x01 }, //{Dummy[2:0], R_GPIO_2_Open_Drain_EnH, R_GPIO_1_Open_Drain_EnH, R_GPIO_DRV[1:0], R_GPIO_18V_EnL}  \r
+#else\r
+    { 0x59 , 0x0C }, //{Dummy[2:0], R_GPIO_1, R_GPIO_1_IEB, R_GPIO_1_OEB, R_GPIO_1_PULLL_EnH, R_GPIO_1_PULLH_EnH}\r
+    { 0x5B , 0x08 }, //{Dummy[2:0], R_GPIO_3, R_GPIO_3_IEB, R_GPIO_3_OEB, R_GPIO_3_PULLL_EnH, R_GPIO_3_PULLH_EnH}\r
+    { 0x52 , 0x00 }, //{Dummy[2:0], R_GPIO_2_Open_Drain_EnH, R_GPIO_1_Open_Drain_EnH, R_GPIO_DRV[1:0], R_GPIO_18V_EnL}\r
+    { 0x5A , 0x04 }, //{Dummy[2:0], R_GPIO_2, R_GPIO_2_IEB, R_GPIO_2_OEB, R_GPIO_2_PULLL_EnH, R_GPIO_2_PULLH_EnH}\r
+    { 0x54 , 0x14 }, //{Dummy[3:0], R_Ext_CLK_Sel, R_Ext_32K_CLK_Sel, R_Ext_32K_CLK, R_Ext_CLK}\r
+    { 0x54 , 0x16 }, //{Dummy[3:0], R_Ext_CLK_Sel, R_Ext_32K_CLK_Sel, R_Ext_32K_CLK, R_Ext_CLK}\r
+#endif\r
+    { 0x0B, 0x37 },                                                                                                                   \r
+    { 0x7F, 0x04 },//Bank4   \r
+    { 0x12, 0x86 },          \r
+    { 0x28, 0x86 },\r
+    { 0x13, 0x01 },\r
+    { 0x29, 0x01 },\r
+    { 0x14, 0x20 },\r
+    { 0x2A, 0x20 },\r
+    { 0x7F, 0x00 },//Bank0    \r
+    { 0x4B, 0x0C },\r
+    { 0x4D, 0x06 },\r
+    { 0x7F, 0x04 },//Bank4   \r
+    { 0x01, 0x04 },\r
+    { 0x04, 0x02 },\r
+    { 0x07, 0x01 },\r
+    { 0x17, 0x04 },\r
+    { 0x1A, 0x02 },\r
+    { 0x1D, 0x01 },\r
+    { 0x7F, 0x01 },//Bank1   \r
+    { 0x65, 0x01 },\r
+    { 0x0B, 0x0C },\r
+    { 0x36, 0x05 },\r
+    { 0x3A, 0x05 },\r
+    { 0x3E, 0x0C },\r
+    { 0x42, 0x0C },\r
+    { 0x46, 0x0C },\r
+    { 0x4A, 0x0C },\r
+    { 0x37, 0x09 },\r
+    { 0x3B, 0x09 },\r
+    { 0x3F, 0x07 },\r
+    { 0x43, 0x07 },\r
+    { 0x47, 0x07 },\r
+    { 0x4B, 0x07 },\r
+    { 0x35, 0x01 },\r
+    { 0x39, 0x02 },\r
+    { 0x3D, 0x01 },\r
+    { 0x41, 0x02 },\r
+    { 0x45, 0x01 },\r
+    { 0x49, 0x02 },\r
+    { 0x38, 0x05 },\r
+    { 0x3C, 0x05 },\r
+    { 0x40, 0x0F },\r
+    { 0x44, 0x0F },\r
+    { 0x48, 0x0F },\r
+    { 0x4C, 0x0F },\r
+    { 0x69, 0x05 },\r
+    { 0x70, 0x05 },\r
+    { 0x6A, 0x0F },\r
+    { 0x71, 0x0F },\r
+    { 0x6B, 0x0F },\r
+    { 0x72, 0x0F },\r
+    { 0x7F, 0x00 },//Bank0                                                                                                                                                                                                                                                                                     \r
+    { 0x18, 0x7F },                                                                                                                                 \r
+    { 0x03, 0x40 },\r
+    { 0x04, 0x06 },\r
+    { 0x4F, 0x09 },\r
+    { 0x1B, 0x11 },\r
+    { 0x50, 0x05 },\r
+    { 0x51, 0x12 },\r
+    { 0x52, 0x12 },\r
+    { 0x68, 0x00 },\r
+};\r
+#define PAH831X_REG_PPG_2_ODR (25)\r
+static const uint8_t PAH831X_REG_PPG_2[][2] = {\r
+    { 0x7F, 0x03 },//Bank3\r
+    { 0x0B, 0x36 },\r
+#ifdef Ext_LPO_CLK_FROM_GPIO2   \r
+    { 0x59 , 0x0C }, //{Dummy[2:0], R_GPIO_1, R_GPIO_1_IEB, R_GPIO_1_OEB, R_GPIO_1_PULLL_EnH, R_GPIO_1_PULLH_EnH}\r
+    { 0x5B , 0x08 }, //{Dummy[2:0], R_GPIO_3, R_GPIO_3_IEB, R_GPIO_3_OEB, R_GPIO_3_PULLL_EnH, R_GPIO_3_PULLH_EnH}\r
+   // { 0x59, 0x08 }, //{Dummy[2:0], R_GPIO_1, R_GPIO_1_IEB, R_GPIO_1_OEB, R_GPIO_1_PULLL_EnH, R_GPIO_1_PULLH_EnH}\r
+    { 0x52 , 0x01 }, //{Dummy[2:0], R_GPIO_2_Open_Drain_EnH, R_GPIO_1_Open_Drain_EnH, R_GPIO_DRV[1:0], R_GPIO_18V_EnL}  \r
+#else\r
+    { 0x59 , 0x0C }, //{Dummy[2:0], R_GPIO_1, R_GPIO_1_IEB, R_GPIO_1_OEB, R_GPIO_1_PULLL_EnH, R_GPIO_1_PULLH_EnH}\r
+    { 0x5B , 0x08 }, //{Dummy[2:0], R_GPIO_3, R_GPIO_3_IEB, R_GPIO_3_OEB, R_GPIO_3_PULLL_EnH, R_GPIO_3_PULLH_EnH}\r
+    { 0x52 , 0x00 }, //{Dummy[2:0], R_GPIO_2_Open_Drain_EnH, R_GPIO_1_Open_Drain_EnH, R_GPIO_DRV[1:0], R_GPIO_18V_EnL}\r
+    { 0x5A , 0x04 }, //{Dummy[2:0], R_GPIO_2, R_GPIO_2_IEB, R_GPIO_2_OEB, R_GPIO_2_PULLL_EnH, R_GPIO_2_PULLH_EnH}\r
+    { 0x54 , 0x14 }, //{Dummy[3:0], R_Ext_CLK_Sel, R_Ext_32K_CLK_Sel, R_Ext_32K_CLK, R_Ext_CLK}\r
+    { 0x54 , 0x16 }, //{Dummy[3:0], R_Ext_CLK_Sel, R_Ext_32K_CLK_Sel, R_Ext_32K_CLK, R_Ext_CLK}\r
+#endif\r
+    { 0x0B, 0x37 },\r
+    { 0x7F, 0x04 },//Bank4   \r
+    { 0x12, 0x86 },\r
+    { 0x28, 0x86 },\r
+    { 0x13, 0x01 },\r
+    { 0x29, 0x01 },\r
+    { 0x14, 0x20 },\r
+    { 0x2A, 0x20 },\r
+    { 0x7F, 0x00 },//Bank0    \r
+    { 0x4B, 0x0C },\r
+    { 0x4D, 0x06 },\r
+    { 0x7F, 0x04 },//Bank4                                                                                                                                                           \r
+    { 0x01, 0x04 },\r
+    { 0x04, 0x02 },\r
+    { 0x07, 0x01 },\r
+    { 0x17, 0x04 },\r
+    { 0x1A, 0x02 },\r
+    { 0x1D, 0x01 },\r
+    { 0x7F, 0x01 },//Bank1   \r
+    { 0x65, 0x01 },\r
+    { 0x0B, 0x0C },\r
+    { 0x36, 0x05 },\r
+    { 0x3A, 0x05 },\r
+    { 0x3E, 0x0C },\r
+    { 0x42, 0x0C },\r
+    { 0x46, 0x0C },\r
+    { 0x4A, 0x0C },\r
+    { 0x37, 0x09 },\r
+    { 0x3B, 0x09 },\r
+    { 0x3F, 0x07 },\r
+    { 0x43, 0x07 },\r
+    { 0x47, 0x07 },\r
+    { 0x4B, 0x07 },\r
+    { 0x35, 0x01 },\r
+    { 0x39, 0x02 },\r
+    { 0x3D, 0x01 },\r
+    { 0x41, 0x02 },\r
+    { 0x45, 0x01 },\r
+    { 0x49, 0x02 },\r
+    { 0x38, 0x05 },\r
+    { 0x3C, 0x05 },\r
+    { 0x40, 0x0F },\r
+    { 0x44, 0x0F },\r
+    { 0x48, 0x0F },\r
+    { 0x4C, 0x0F },\r
+    { 0x69, 0x05 },\r
+    { 0x70, 0x05 },\r
+    { 0x6A, 0x0F },\r
+    { 0x71, 0x0F },\r
+    { 0x6B, 0x0F },\r
+    { 0x72, 0x0F },\r
+    { 0x7F, 0x00 },//Bank0                                                                                                                                                                                                                                                                                     \r
+    { 0x18, 0x7F },\r
+    { 0x03, 0x00 },\r
+    { 0x04, 0x05 },\r
+    { 0x4F, 0x09 },\r
+    { 0x1B, 0x16 },\r
+    { 0x50, 0x05 },\r
+    { 0x51, 0x12 },\r
+    { 0x52, 0x12 },\r
+    { 0x68, 0x00 },\r
+};    \r
+#define PAH831X_REG_PPG_3_ODR (25)\r
+static const uint8_t PAH831X_REG_PPG_3[][2] = {\r
+     { 0x7F, 0x03 },//Bank3\r
+    { 0x0B, 0x36 },\r
+#ifdef Ext_LPO_CLK_FROM_GPIO2   \r
+    { 0x59 , 0x0C }, //{Dummy[2:0], R_GPIO_1, R_GPIO_1_IEB, R_GPIO_1_OEB, R_GPIO_1_PULLL_EnH, R_GPIO_1_PULLH_EnH}\r
+    { 0x5B , 0x08 }, //{Dummy[2:0], R_GPIO_3, R_GPIO_3_IEB, R_GPIO_3_OEB, R_GPIO_3_PULLL_EnH, R_GPIO_3_PULLH_EnH}\r
+   // { 0x59, 0x08 }, //{Dummy[2:0], R_GPIO_1, R_GPIO_1_IEB, R_GPIO_1_OEB, R_GPIO_1_PULLL_EnH, R_GPIO_1_PULLH_EnH}\r
+    { 0x52 , 0x01 }, //{Dummy[2:0], R_GPIO_2_Open_Drain_EnH, R_GPIO_1_Open_Drain_EnH, R_GPIO_DRV[1:0], R_GPIO_18V_EnL}  \r
+#else\r
+    { 0x59 , 0x0C }, //{Dummy[2:0], R_GPIO_1, R_GPIO_1_IEB, R_GPIO_1_OEB, R_GPIO_1_PULLL_EnH, R_GPIO_1_PULLH_EnH}\r
+    { 0x5B , 0x08 }, //{Dummy[2:0], R_GPIO_3, R_GPIO_3_IEB, R_GPIO_3_OEB, R_GPIO_3_PULLL_EnH, R_GPIO_3_PULLH_EnH}\r
+    { 0x52 , 0x00 }, //{Dummy[2:0], R_GPIO_2_Open_Drain_EnH, R_GPIO_1_Open_Drain_EnH, R_GPIO_DRV[1:0], R_GPIO_18V_EnL}\r
+    { 0x5A , 0x04 }, //{Dummy[2:0], R_GPIO_2, R_GPIO_2_IEB, R_GPIO_2_OEB, R_GPIO_2_PULLL_EnH, R_GPIO_2_PULLH_EnH}\r
+    { 0x54 , 0x14 }, //{Dummy[3:0], R_Ext_CLK_Sel, R_Ext_32K_CLK_Sel, R_Ext_32K_CLK, R_Ext_CLK}\r
+    { 0x54 , 0x16 }, //{Dummy[3:0], R_Ext_CLK_Sel, R_Ext_32K_CLK_Sel, R_Ext_32K_CLK, R_Ext_CLK}\r
+#endif\r
+    { 0x0B, 0x37 },                                                                                                                   \r
+    { 0x7F, 0x04 },//Bank4   \r
+    { 0x12, 0x86 },          \r
+    { 0x28, 0x86 },\r
+    { 0x13, 0x01 },\r
+    { 0x29, 0x01 },\r
+    { 0x14, 0x20 },\r
+    { 0x2A, 0x20 },\r
+    { 0x7F, 0x00 },//Bank0    \r
+    { 0x4B, 0x0C },\r
+    { 0x4D, 0x06 },\r
+    { 0x7F, 0x04 },//Bank4   \r
+    { 0x01, 0x04 },\r
+    { 0x04, 0x02 },\r
+    { 0x07, 0x01 },\r
+    { 0x17, 0x04 },\r
+    { 0x1A, 0x02 },\r
+    { 0x1D, 0x01 },\r
+    { 0x7F, 0x01 },//Bank1   \r
+    { 0x65, 0x01 },\r
+    { 0x0B, 0x0C },\r
+    { 0x36, 0x05 },\r
+    { 0x3A, 0x05 },\r
+    { 0x3E, 0x0C },\r
+    { 0x42, 0x0C },\r
+    { 0x46, 0x0C },\r
+    { 0x4A, 0x0C },\r
+    { 0x37, 0x09 },\r
+    { 0x3B, 0x09 },\r
+    { 0x3F, 0x07 },\r
+    { 0x43, 0x07 },\r
+    { 0x47, 0x07 },\r
+    { 0x4B, 0x07 },\r
+    { 0x35, 0x01 },\r
+    { 0x39, 0x02 },\r
+    { 0x3D, 0x01 },\r
+    { 0x41, 0x02 },\r
+    { 0x45, 0x01 },\r
+    { 0x49, 0x02 },\r
+    { 0x38, 0x05 },\r
+    { 0x3C, 0x05 },\r
+    { 0x40, 0x0F },\r
+    { 0x44, 0x0F },\r
+    { 0x48, 0x0F },\r
+    { 0x4C, 0x0F },\r
+    { 0x69, 0x05 },\r
+    { 0x70, 0x05 },\r
+    { 0x6A, 0x0F },\r
+    { 0x71, 0x0F },\r
+    { 0x6B, 0x0F },\r
+    { 0x72, 0x0F },\r
+    { 0x7F, 0x00 },//Bank0                                                                                                                                                                                                                                                                                     \r
+    { 0x18, 0x7F },                                                                                                                                 \r
+    { 0x03, 0x40 },\r
+    { 0x04, 0x01 },\r
+    { 0x4F, 0x09 },\r
+    { 0x1B, 0x11 },\r
+    { 0x50, 0x05 },\r
+    { 0x51, 0x12 },\r
+    { 0x52, 0x12 },\r
+    { 0x68, 0x00 },\r
+\r
+};\r
+#define PAH831X_REG_PPG_4_ODR (20)\r
+static const uint8_t PAH831X_REG_PPG_4[][2] = {\r
+    { 0x7F, 0x04 },//Bank4\r
+};\r
+#define PAH831X_REG_PPG_5_ODR (20)\r
+static const uint8_t PAH831X_REG_PPG_5[][2] = {\r
+    { 0x7F, 0x01 },//Bank1\r
+};\r
+#define PAH831X_REG_PPG_6_ODR (20)\r
+static const uint8_t PAH831X_REG_PPG_6[][2] = {\r
+    { 0x7F, 0x01 },//Bank1\r
+};\r
+#define PAH831X_REG_PPG_7_ODR (20)\r
+static const uint8_t PAH831X_REG_PPG_7[][2] = {\r
+    { 0x7F, 0x01 },//Bank1\r
+};\r
+#define PAH831X_REG_PPG_8_ODR (20)\r
+static const uint8_t PAH831X_REG_PPG_8[][2] = {\r
+    { 0x7F, 0x01 },//Bank1\r
+};\r
+#define PAH831X_REG_PPG_9_ODR (20)\r
+static const uint8_t PAH831X_REG_PPG_9[][2] = {\r
+    { 0x7F, 0x01 },//Bank1\r
+};\r
+#define PAH831X_REG_PPG_10_ODR (20)\r
+static const uint8_t PAH831X_REG_PPG_10[][2] = {\r
+    { 0x7F, 0x01 },//Bank1\r
+};\r
+\r
+\r
+\r
+\r
+#define PAH831X_REG_ECG_1_ODR (256)\r
+static const uint8_t PAH831X_REG_ECG_1[][2] = {\r
+    { 0x7F ,0x03 }, //Bank3\r
+    { 0x0B ,0x36 }, //{Dummy[1:0], B_PPG1_AMBC_PWRSV_SEL_EnH, B_PPG2_AMBC_PWRSV_SEL_EnH, Dummy, B_BG_PWRSV_SEL_EnH, B_PMU_V2I_PWRSV_SEL_EnH, B_OSC_4M_PWRSV_SEL_EnH}\r
+#ifndef Ext_LPO_CLK_FROM_GPIO2   \r
+    { 0x59 , 0x0C }, //{Dummy[2:0], R_GPIO_1, R_GPIO_1_IEB, R_GPIO_1_OEB, R_GPIO_1_PULLL_EnH, R_GPIO_1_PULLH_EnH}\r
+    { 0x5B , 0x08 }, //{Dummy[2:0], R_GPIO_3, R_GPIO_3_IEB, R_GPIO_3_OEB, R_GPIO_3_PULLL_EnH, R_GPIO_3_PULLH_EnH}\r
+   // { 0x59, 0x08 }, //{Dummy[2:0], R_GPIO_1, R_GPIO_1_IEB, R_GPIO_1_OEB, R_GPIO_1_PULLL_EnH, R_GPIO_1_PULLH_EnH}\r
+    { 0x52 , 0x01 }, //{Dummy[2:0], R_GPIO_2_Open_Drain_EnH, R_GPIO_1_Open_Drain_EnH, R_GPIO_DRV[1:0], R_GPIO_18V_EnL}  \r
+#else\r
+    { 0x59 , 0x0C }, //{Dummy[2:0], R_GPIO_1, R_GPIO_1_IEB, R_GPIO_1_OEB, R_GPIO_1_PULLL_EnH, R_GPIO_1_PULLH_EnH}\r
+    { 0x5B , 0x08 }, //{Dummy[2:0], R_GPIO_3, R_GPIO_3_IEB, R_GPIO_3_OEB, R_GPIO_3_PULLL_EnH, R_GPIO_3_PULLH_EnH}\r
+    { 0x52 , 0x00 }, //{Dummy[2:0], R_GPIO_2_Open_Drain_EnH, R_GPIO_1_Open_Drain_EnH, R_GPIO_DRV[1:0], R_GPIO_18V_EnL}\r
+    { 0x5A , 0x04 }, //{Dummy[2:0], R_GPIO_2, R_GPIO_2_IEB, R_GPIO_2_OEB, R_GPIO_2_PULLL_EnH, R_GPIO_2_PULLH_EnH}\r
+    { 0x54 , 0x14 }, //{Dummy[3:0], R_Ext_CLK_Sel, R_Ext_32K_CLK_Sel, R_Ext_32K_CLK, R_Ext_CLK}\r
+    { 0x54 , 0x16 }, //{Dummy[3:0], R_Ext_CLK_Sel, R_Ext_32K_CLK_Sel, R_Ext_32K_CLK, R_Ext_CLK}\r
+#endif\r
+    { 0x0B , 0x37 }, //{Dummy[1:0], B_PPG1_AMBC_PWRSV_SEL_EnH, B_PPG2_AMBC_PWRSV_SEL_EnH, Dummy, B_BG_PWRSV_SEL_EnH, B_PMU_V2I_PWRSV_SEL_EnH, B_OSC_4M_PWRSV_SEL_EnH}\r
+    { 0x7F , 0x05 }, //Bank5                                                                                                                                                   \r
+    { 0x02 , 0x69 }, //R_ChA_ADC_target[15:8],32768                                                                                                                            \r
+    { 0x08 , 0x73 }, //R_ChA_ACC_lock_out_UB[15:8],53248                                                                                                                       \r
+    { 0x0A , 0x50 }, //R_ChA_ACC_lock_out_LB[15:8],24576                                                                                                                       \r
+    { 0x0E , 0x80 }, //R_ChB_ADC_target[15:8]                                                                                                                                  \r
+    { 0x14 , 0xD0 }, //R_ChB_ACC_lock_out_UB[15:8]                                                                                                                             \r
+    { 0x16 , 0x60 }, //R_ChB_ACC_lock_out_LB[15:8]                                                                                                                             \r
+    { 0x1A , 0x80 }, //R_ChC_ADC_target[15:8]                                                                                                                                  \r
+    { 0x20 , 0xD0 }, //R_ChC_ACC_lock_out_UB[15:8]                                                                                                                             \r
+    { 0x22 , 0x60 }, //R_ChC_ACC_lock_out_LB[15:8]                                                                                                                             \r
+    { 0x26 , 0x80 }, //R_ChD_ADC_target[15:8]                                                                                                                                  \r
+    { 0x2C , 0xD0 }, //R_ChD_ACC_lock_out_UB[15:8]                                                                                                                             \r
+    { 0x2E , 0x60 }, //R_ChD_ACC_lock_out_LB[15:8]                                                                                                                             \r
+    { 0x7F , 0x04 }, //Bank4                                                                                                                                                   \r
+    { 0x13 , 0x01/*0x09*/ }, //B_PPG_ChT_LEDDAC1_CH_SEL[5:0], IR                                                                                                                                                          \r
+    { 0x29 , 0x01/*0x09*/ }, //B_PPG_ChT_LEDDAC2_CH_SEL[5:0], IR                                                                                                                                                          \r
+    { 0x14 , 0x45 }, //B_PPG_ChT_LEDDAC1_CODE[7:0]                                                                                                                                                          \r
+    { 0x2A , 0x45 }, //B_PPG_ChT_LEDDAC2_CODE[7:0]                                                                                                                                                          \r
+    { 0x01 , 0x04/*0x0C*/ }, //B_PPG_ChA_LEDDAC1_CH_SEL[5:0]  2G                                                                                                                       \r
+    { 0x04 , 0x02/*0x12*/ }, //B_PPG_ChB_LEDDAC1_CH_SEL[5:0]  R                                                                                                                        \r
+    { 0x07 , 0x01/*0x09*/ }, //B_PPG_ChC_LEDDAC1_CH_SEL[5:0], IR                                                                                                                       \r
+    { 0x0A , 0x00 }, //B_PPG_ChD_LEDDAC1_CH_SEL[5:0], none                                                                                                                     \r
+    { 0x17 , 0x04/*0x0C*/ }, //B_PPG_ChA_LEDDAC2_CH_SEL[5:0]  2G                                                                                                                       \r
+    { 0x1A , 0x02/*0x12*/ }, //B_PPG_ChB_LEDDAC2_CH_SEL[5:0]  R                                                                                                                        \r
+    { 0x1D , 0x01/*0x09*/ }, //B_PPG_ChC_LEDDAC2_CH_SEL[5:0], IR                                                                                                                       \r
+    { 0x20 , 0x00 }, //B_PPG_ChD_LEDDAC2_CH_SEL[5:0], none                                                                                                                     \r
+    { 0x34 , 0x01 }, //R_ChD_LED_dac1_max[7:0]                                                                                                                                 \r
+    { 0x7F , 0x01 }, //Bank1   \r
+    { 0x65 , 0x01/*0x05*/ }, //{B_PPG1_ChT_AMBC_INV_EnH, B_PPG1_ChT_AMBC_LSB_ADJ, B_PPG1_ChT_PD_CH_SEL[4:0]}                                                                                                                                                          \r
+    { 0x04 , 0x40 }, //{T_OSC_32K_RANGE[1:0], T_OSC_4M_EnL, T_PPG1_TIA_EnL, T_PPG1_AMBC_EnL, Dummy, T_PPG1_ADC_EnL, T_PPG2_TIA_EnL}                                            \r
+    { 0x05 , 0x00 }, //{T_PPG2_AMBC_EnL, T_PPG2_ADC_EnL, T_PPG_LEDDAC2_EnL, T_PPG_LEDDAC1_EnL, T_ECG_FE_INA_EnL, T_ECG_ADC_EnL, T_ECG_FE_LOD_CMP_EnL, T_ECG_FE_LOD_I_EnL}                                                                                                                                   \r
+    { 0x36 , 0x00 }, //B_PPG1_ChA_TIA_CF_ADJ[6:0]                                                                                                                              \r
+    { 0x3A , 0x00 }, //B_PPG2_ChA_TIA_CF_ADJ[6:0]                                                                                                                              \r
+    { 0x3E , 0x05 }, //B_PPG1_ChB_TIA_CF_ADJ[6:0]                                                                                                                              \r
+    { 0x42 , 0x05 }, //B_PPG2_ChB_TIA_CF_ADJ[6:0]                                                                                                                              \r
+    { 0x46 , 0x05 }, //B_PPG1_ChC_TIA_CF_ADJ[6:0]                                                                                                                              \r
+    { 0x4A , 0x05 }, //B_PPG2_ChC_TIA_CF_ADJ[6:0]                                                                                                                              \r
+    { 0x4E , 0x0C }, //B_PPG1_ChD_TIA_CF_ADJ[6:0]                                                                                                                              \r
+    { 0x52 , 0x0C }, //B_PPG2_ChD_TIA_CF_ADJ[6:0]                                                                                                                              \r
+    { 0x37 , 0x0F }, //B_PPG1_ChA_TIA_RF_ADJ[3:0],2000k                                                                                                                         \r
+    { 0x3B , 0x0F }, //B_PPG2_ChA_TIA_RF_ADJ[3:0],2000k                                                                                                                         \r
+    { 0x3F , 0x09 }, //B_PPG1_ChB_TIA_RF_ADJ[3:0],350k                                                                                                                               \r
+    { 0x43 , 0x09 }, //B_PPG2_ChB_TIA_RF_ADJ[3:0],350k                                                                                                                                \r
+    { 0x47 , 0x09 }, //B_PPG1_ChC_TIA_RF_ADJ[3:0],350k                                                                                                                                \r
+    { 0x4B , 0x09 }, //B_PPG2_ChC_TIA_RF_ADJ[3:0],350k                                                                                                                                \r
+    { 0x4F , 0x07 }, //B_PPG1_ChD_TIA_RF_ADJ[3:0]                                                                                                                              \r
+    { 0x53 , 0x07 }, //B_PPG2_ChD_TIA_RF_ADJ[3:0]                                                                                                                              \r
+    { 0x35 , 0x01/*0x05*/ }, //{B_PPG1_ChA_AMBC_INV_EnH, B_PPG1_ChA_AMBC_LSB_ADJ, B_PPG1_ChA_PD_CH_SEL[4:0]}                                                                           \r
+    { 0x39 , 0x02/*0x0A*/ }, //{B_PPG2_ChA_AMBC_INV_EnH, B_PPG2_ChA_AMBC_LSB_ADJ, B_PPG2_ChA_PD_CH_SEL[4:0]}                                                                           \r
+    { 0x3D , 0x01/*0x05*/ }, //{B_PPG1_ChB_AMBC_INV_EnH, B_PPG1_ChB_AMBC_LSB_ADJ, B_PPG1_ChB_PD_CH_SEL[4:0]}                                                                           \r
+    { 0x41 , 0x01/*0x0A*/ }, //{B_PPG2_ChB_AMBC_INV_EnH, B_PPG2_ChB_AMBC_LSB_ADJ, B_PPG2_ChB_PD_CH_SEL[4:0]}                                                                           \r
+    { 0x45 , 0x01/*0x05*/ }, //{B_PPG1_ChC_AMBC_INV_EnH, B_PPG1_ChC_AMBC_LSB_ADJ, B_PPG1_ChC_PD_CH_SEL[4:0]}                                                                           \r
+    { 0x49 , 0x02/*0x0A*/ }, //{B_PPG2_ChC_AMBC_INV_EnH, B_PPG2_ChC_AMBC_LSB_ADJ, B_PPG2_ChC_PD_CH_SEL[4:0]}                                                                           \r
+    { 0x38 , 0x01 }, //B_PPG1_ChA_ON_AMBC_ADJ[7:0]                                                                                                                             \r
+    { 0x3C , 0x01 }, //B_PPG2_ChA_ON_AMBC_ADJ[7:0]                                                                                                                             \r
+    { 0x40 , 0x05 }, //B_PPG1_ChB_ON_AMBC_ADJ[7:0]                                                                                                                             \r
+    { 0x44 , 0x05 }, //B_PPG2_ChB_ON_AMBC_ADJ[7:0]                                                                                                                             \r
+    { 0x48 , 0x05 }, //B_PPG1_ChC_ON_AMBC_ADJ[7:0]                                                                                                                             \r
+    { 0x4C , 0x05 }, //B_PPG2_ChC_ON_AMBC_ADJ[7:0]                                                                                                                             \r
+    { 0x50 , 0x0F }, //B_PPG1_ChD_ON_AMBC_ADJ[7:0]                                                                                                                             \r
+    { 0x54 , 0x0F }, //B_PPG2_ChD_ON_AMBC_ADJ[7:0]                                                                                                                             \r
+    { 0x69 , 0x01 }, //B_PPG1_ChA_OFF_AMBC_ADJ[7:0]                                                                                                                            \r
+    { 0x70 , 0x01 }, //B_PPG2_ChA_OFF_AMBC_ADJ[7:0]                                                                                                                            \r
+    { 0x6A , 0x05 }, //B_PPG1_ChB_OFF_AMBC_ADJ[7:0]                                                                                                                            \r
+    { 0x71 , 0x05 }, //B_PPG2_ChB_OFF_AMBC_ADJ[7:0]                                                                                                                            \r
+    { 0x6B , 0x05 }, //B_PPG1_ChC_OFF_AMBC_ADJ[7:0]                                                                                                                            \r
+    { 0x72 , 0x05 }, //B_PPG2_ChC_OFF_AMBC_ADJ[7:0]                                                                                                                            \r
+    { 0x6C , 0x0F }, //B_PPG1_ChD_OFF_AMBC_ADJ[7:0]                                                                                                                            \r
+    { 0x73 , 0x0F }, //B_PPG2_ChD_OFF_AMBC_ADJ[7:0]                                                                                                                            \r
+    { 0x7F , 0x00 }, //Bank0                                                                                                                                                   \r
+    { 0x15 , 0x01 }, //RDB_FrameNum_D[6:0]                                                                                                                                     \r
+    { 0x18 , 0x77 }, //{RDB_OffOnOff_F_EnH, RDB_OffOnOff_E_EnH, RDB_OffOnOff_T_EnH, RDB_OffOnOff_F_EnH, RDB_OffOnOff_E_EnH, RDB_OffOnOff_D_EnH, RDB_OffOnOff_C_EnH, RDB_OffOnOff_B_EnH, RDB_OffOnOff_A_EnH}                                                                                                                                    \r
+    { 0x4B , 0x0C }, //R_TouchDetection_Th_Hi[15:8]   3168\r
+    { 0x4D , 0x06 }, //R_TouchDetection_Th_Low[15:8]\r
+    { 0x4F , 0x0C }, //R_NoTouchDetection_Count_Th[4:0] 1568\r
+    { 0x7F , 0x00 }, //Bank0\r
+#ifndef Ext_LPO_CLK_FROM_GPIO2 \r
+    { 0x03 , 0x7D }, //Golden report period[7:0] (1T=31.25us)(256Hz)\r
+    { 0x04 , 0x00 }, //{Bit[7:0](Golden report period[15:8])}\r
+#else\r
+    { 0x03 , 0x80 }, //Golden report period[7:0] (1T=31.25us)(256Hz)\r
+    { 0x04 , 0x00 }, //{Bit[7:0](Golden report period[15:8])}\r
+#endif\r
+    { 0x27 , 0x20 }, //RDB_FrameNum_ECG[7:0]\r
+    { 0x4F , 0x04 }, //R_NoTouchDetection_Count_Th[4:0]\r
+    { 0x24 , 0x08 }, //RDB_ChT_report_divider[7:0]\r
+    { 0x2E , 0x03 }, //{fp_lpf_mask_cnt[7:4], Reserved[3], fp_lpf_sel[2:1](0:128/1:256/2:512/3:1024Hz), fp_lpf_enh[0]}\r
+    { 0x1B , 0x30 }, //{Reserved[7], RDB_LOD_EnH[6], RDB_ECG_EnH[5], RDB_ChT_EnH[4], RDB_ChD_EnH[3], RDB_ChC_EnH[2], RDB_ChB_EnH[1], RDB_ChA_EnH[0]}\r
+    { 0x68 , 0x00 }, //{Dummy[5:0], RDB_ChF_EnH, RDB_ChE_EnH}; \r
+    { 0x7F , 0x01 }, //Bank1\r
+    { 0x05 , 0x80 }, //{T_PPG2_AMBC_EnL, T_PPG2_ADC_EnL, T_PPG_LEDDAC2_EnL, T_PPG_LEDDAC1_EnL, T_ECG_FE_INA_EnL, T_ECG_ADC_EnL, T_ECG_FE_LOD_CMP_EnL, T_ECG_FE_LOD_I_EnL}\r
+    { 0x06 , 0x02 }, //{T_ECG_FE_LOD_GATE_INACHOP_EnH, T_ECG_FE_I_GATED_INA_EnH, T_ECG_PGA_TEST_EnH, T_ECG_FE_LOD_RLDCMP_EnL, T_ECG_FE_VCMBUF_EnL, T_ECG_FE_INA_HPF_SHORT, T_ECG_POLAR_FLIP_EnH, Dummy}\r
+    { 0x0B , 0x00 }, //(enable PPG and ECG) \r
+    { 0x0D , 0xF2 }, //{B_PPG_LEDDAC2_PWRSV_SEL_EnH, B_PPG_LEDDAC1_PWRSV_SEL_EnH, B_ECG_FE_INA_PWRSV_SEL_EnH, B_ECG_ADC_PWRSV_SEL_EnH, B_ECG_FE_LOD_CMP_PWRSV_SEL_EnH, B_ECG_FE_LOD_I_PWRSV_SEL_EnH, B_ECG_FE_RLD_PWRSV_SEL_EnH, B_ECG_FE_LOD_RLDCMP_PWRSV_SEL_EnH} \r
+    { 0x0F , 0x0E }, //{B_ECG_VCMBUF_OFF[3:0], B_ECG_FE_VCMBUF_PWRSV_SEL_EnH, B_ECG_FE_PGA_PWRSV_SEL_EnH, B_ECG_FE_BUF_PWRSV_SEL_EnH, B_ECG_FE_INA_LPF_FAST_SEL_EnH}\r
+    { 0x26 , 0x07 }, //{T_ECG_RF_PGA_ADJ[2:0], Dummy, T_ECG_PGA_LPF_1M_EN, T_ECG_FE_RLD2VCMBUF_EnH, T_ECG_FE_INA_GAIN[1:0]} \r
+    { 0x7E , 0x02 }, //{Dummy[4:0], B_ECG_FAST_RECOVERY_MODE, B_FAST_RECOVERY_EN, TS_ECG_FAST_RECOVERY_EnH} \r
+};       \r
+ #define PAH831X_REG_ECG_2_ODR (256)\r
+static const uint8_t PAH831X_REG_ECG_2[][2] = {\r
+    { 0x7F ,0x03 }, //Bank3\r
+    { 0x0B ,0x36 }, //{Dummy[1:0], B_PPG1_AMBC_PWRSV_SEL_EnH, B_PPG2_AMBC_PWRSV_SEL_EnH, Dummy, B_BG_PWRSV_SEL_EnH, B_PMU_V2I_PWRSV_SEL_EnH, B_OSC_4M_PWRSV_SEL_EnH}\r
+#ifdef Ext_LPO_CLK_FROM_GPIO2   \r
+    { 0x59 , 0x0C }, //{Dummy[2:0], R_GPIO_1, R_GPIO_1_IEB, R_GPIO_1_OEB, R_GPIO_1_PULLL_EnH, R_GPIO_1_PULLH_EnH}\r
+    { 0x5B , 0x08 }, //{Dummy[2:0], R_GPIO_3, R_GPIO_3_IEB, R_GPIO_3_OEB, R_GPIO_3_PULLL_EnH, R_GPIO_3_PULLH_EnH}\r
+   // { 0x59, 0x08 }, //{Dummy[2:0], R_GPIO_1, R_GPIO_1_IEB, R_GPIO_1_OEB, R_GPIO_1_PULLL_EnH, R_GPIO_1_PULLH_EnH}\r
+    { 0x52 , 0x01 }, //{Dummy[2:0], R_GPIO_2_Open_Drain_EnH, R_GPIO_1_Open_Drain_EnH, R_GPIO_DRV[1:0], R_GPIO_18V_EnL}  \r
+#else\r
+    { 0x59 , 0x0C }, //{Dummy[2:0], R_GPIO_1, R_GPIO_1_IEB, R_GPIO_1_OEB, R_GPIO_1_PULLL_EnH, R_GPIO_1_PULLH_EnH}\r
+    { 0x5B , 0x08 }, //{Dummy[2:0], R_GPIO_3, R_GPIO_3_IEB, R_GPIO_3_OEB, R_GPIO_3_PULLL_EnH, R_GPIO_3_PULLH_EnH}\r
+    { 0x52 , 0x00 }, //{Dummy[2:0], R_GPIO_2_Open_Drain_EnH, R_GPIO_1_Open_Drain_EnH, R_GPIO_DRV[1:0], R_GPIO_18V_EnL}\r
+    { 0x5A , 0x04 }, //{Dummy[2:0], R_GPIO_2, R_GPIO_2_IEB, R_GPIO_2_OEB, R_GPIO_2_PULLL_EnH, R_GPIO_2_PULLH_EnH}\r
+    { 0x54 , 0x14 }, //{Dummy[3:0], R_Ext_CLK_Sel, R_Ext_32K_CLK_Sel, R_Ext_32K_CLK, R_Ext_CLK}\r
+    { 0x54 , 0x16 }, //{Dummy[3:0], R_Ext_CLK_Sel, R_Ext_32K_CLK_Sel, R_Ext_32K_CLK, R_Ext_CLK}\r
+#endif\r
+    { 0x0B , 0x37 }, //{Dummy[1:0], B_PPG1_AMBC_PWRSV_SEL_EnH, B_PPG2_AMBC_PWRSV_SEL_EnH, Dummy, B_BG_PWRSV_SEL_EnH, B_PMU_V2I_PWRSV_SEL_EnH, B_OSC_4M_PWRSV_SEL_EnH}\r
+    { 0x7F , 0x05 }, //Bank5                                                                                                                                                   \r
+    { 0x02 , 0x69 }, //R_ChA_ADC_target[15:8],32768                                                                                                                            \r
+    { 0x08 , 0x73 }, //R_ChA_ACC_lock_out_UB[15:8],53248                                                                                                                       \r
+    { 0x0A , 0x50 }, //R_ChA_ACC_lock_out_LB[15:8],24576                                                                                                                       \r
+    { 0x0E , 0x80 }, //R_ChB_ADC_target[15:8]                                                                                                                                  \r
+    { 0x14 , 0xD0 }, //R_ChB_ACC_lock_out_UB[15:8]                                                                                                                             \r
+    { 0x16 , 0x60 }, //R_ChB_ACC_lock_out_LB[15:8]                                                                                                                             \r
+    { 0x1A , 0x80 }, //R_ChC_ADC_target[15:8]                                                                                                                                  \r
+    { 0x20 , 0xD0 }, //R_ChC_ACC_lock_out_UB[15:8]                                                                                                                             \r
+    { 0x22 , 0x60 }, //R_ChC_ACC_lock_out_LB[15:8]                                                                                                                             \r
+    { 0x26 , 0x80 }, //R_ChD_ADC_target[15:8]                                                                                                                                  \r
+    { 0x2C , 0xD0 }, //R_ChD_ACC_lock_out_UB[15:8]                                                                                                                             \r
+    { 0x2E , 0x60 }, //R_ChD_ACC_lock_out_LB[15:8]                                                                                                                             \r
+    { 0x7F , 0x04 }, //Bank4                                                                                                                                                   \r
+    { 0x13 , 0x01/*0x09*/ }, //B_PPG_ChT_LEDDAC1_CH_SEL[5:0], IR                                                                                                                                                          \r
+    { 0x29 , 0x01/*0x09*/ }, //B_PPG_ChT_LEDDAC2_CH_SEL[5:0], IR                                                                                                                                                          \r
+    { 0x14 , 0x45 }, //B_PPG_ChT_LEDDAC1_CODE[7:0]                                                                                                                                                          \r
+    { 0x2A , 0x45 }, //B_PPG_ChT_LEDDAC2_CODE[7:0]                                                                                                                                                          \r
+    { 0x01 , 0x04/*0x0C*/ }, //B_PPG_ChA_LEDDAC1_CH_SEL[5:0]  2G                                                                                                                       \r
+    { 0x04 , 0x02/*0x12*/ }, //B_PPG_ChB_LEDDAC1_CH_SEL[5:0]  R                                                                                                                        \r
+    { 0x07 , 0x01/*0x09*/ }, //B_PPG_ChC_LEDDAC1_CH_SEL[5:0], IR                                                                                                                       \r
+    { 0x0A , 0x00 }, //B_PPG_ChD_LEDDAC1_CH_SEL[5:0], none                                                                                                                     \r
+    { 0x17 , 0x04/*0x0C*/ }, //B_PPG_ChA_LEDDAC2_CH_SEL[5:0]  2G                                                                                                                       \r
+    { 0x1A , 0x02/*0x12*/ }, //B_PPG_ChB_LEDDAC2_CH_SEL[5:0]  R                                                                                                                        \r
+    { 0x1D , 0x01/*0x09*/ }, //B_PPG_ChC_LEDDAC2_CH_SEL[5:0], IR                                                                                                                       \r
+    { 0x20 , 0x00 }, //B_PPG_ChD_LEDDAC2_CH_SEL[5:0], none                                                                                                                     \r
+    { 0x34 , 0x01 }, //R_ChD_LED_dac1_max[7:0]                                                                                                                                 \r
+    { 0x7F , 0x01 }, //Bank1   \r
+    { 0x65 , 0x01/*0x05*/ }, //{B_PPG1_ChT_AMBC_INV_EnH, B_PPG1_ChT_AMBC_LSB_ADJ, B_PPG1_ChT_PD_CH_SEL[4:0]}                                                                                                                                                          \r
+    { 0x04 , 0x40 }, //{T_OSC_32K_RANGE[1:0], T_OSC_4M_EnL, T_PPG1_TIA_EnL, T_PPG1_AMBC_EnL, Dummy, T_PPG1_ADC_EnL, T_PPG2_TIA_EnL}                                            \r
+    { 0x05 , 0x00 }, //{T_PPG2_AMBC_EnL, T_PPG2_ADC_EnL, T_PPG_LEDDAC2_EnL, T_PPG_LEDDAC1_EnL, T_ECG_FE_INA_EnL, T_ECG_ADC_EnL, T_ECG_FE_LOD_CMP_EnL, T_ECG_FE_LOD_I_EnL}                                                                                                                                   \r
+    { 0x36 , 0x00 }, //B_PPG1_ChA_TIA_CF_ADJ[6:0]                                                                                                                              \r
+    { 0x3A , 0x00 }, //B_PPG2_ChA_TIA_CF_ADJ[6:0]                                                                                                                              \r
+    { 0x3E , 0x05 }, //B_PPG1_ChB_TIA_CF_ADJ[6:0]                                                                                                                              \r
+    { 0x42 , 0x05 }, //B_PPG2_ChB_TIA_CF_ADJ[6:0]                                                                                                                              \r
+    { 0x46 , 0x05 }, //B_PPG1_ChC_TIA_CF_ADJ[6:0]                                                                                                                              \r
+    { 0x4A , 0x05 }, //B_PPG2_ChC_TIA_CF_ADJ[6:0]                                                                                                                              \r
+    { 0x4E , 0x0C }, //B_PPG1_ChD_TIA_CF_ADJ[6:0]                                                                                                                              \r
+    { 0x52 , 0x0C }, //B_PPG2_ChD_TIA_CF_ADJ[6:0]                                                                                                                              \r
+    { 0x37 , 0x0F }, //B_PPG1_ChA_TIA_RF_ADJ[3:0],2000k                                                                                                                         \r
+    { 0x3B , 0x0F }, //B_PPG2_ChA_TIA_RF_ADJ[3:0],2000k                                                                                                                         \r
+    { 0x3F , 0x09 }, //B_PPG1_ChB_TIA_RF_ADJ[3:0],350k                                                                                                                               \r
+    { 0x43 , 0x09 }, //B_PPG2_ChB_TIA_RF_ADJ[3:0],350k                                                                                                                                \r
+    { 0x47 , 0x09 }, //B_PPG1_ChC_TIA_RF_ADJ[3:0],350k                                                                                                                                \r
+    { 0x4B , 0x09 }, //B_PPG2_ChC_TIA_RF_ADJ[3:0],350k                                                                                                                                \r
+    { 0x4F , 0x07 }, //B_PPG1_ChD_TIA_RF_ADJ[3:0]                                                                                                                              \r
+    { 0x53 , 0x07 }, //B_PPG2_ChD_TIA_RF_ADJ[3:0]                                                                                                                              \r
+    { 0x35 , 0x01/*0x05*/ }, //{B_PPG1_ChA_AMBC_INV_EnH, B_PPG1_ChA_AMBC_LSB_ADJ, B_PPG1_ChA_PD_CH_SEL[4:0]}                                                                           \r
+    { 0x39 , 0x02/*0x0A*/ }, //{B_PPG2_ChA_AMBC_INV_EnH, B_PPG2_ChA_AMBC_LSB_ADJ, B_PPG2_ChA_PD_CH_SEL[4:0]}                                                                           \r
+    { 0x3D , 0x01/*0x05*/ }, //{B_PPG1_ChB_AMBC_INV_EnH, B_PPG1_ChB_AMBC_LSB_ADJ, B_PPG1_ChB_PD_CH_SEL[4:0]}                                                                           \r
+    { 0x41 , 0x01/*0x0A*/ }, //{B_PPG2_ChB_AMBC_INV_EnH, B_PPG2_ChB_AMBC_LSB_ADJ, B_PPG2_ChB_PD_CH_SEL[4:0]}                                                                           \r
+    { 0x45 , 0x01/*0x05*/ }, //{B_PPG1_ChC_AMBC_INV_EnH, B_PPG1_ChC_AMBC_LSB_ADJ, B_PPG1_ChC_PD_CH_SEL[4:0]}                                                                           \r
+    { 0x49 , 0x02/*0x0A*/ }, //{B_PPG2_ChC_AMBC_INV_EnH, B_PPG2_ChC_AMBC_LSB_ADJ, B_PPG2_ChC_PD_CH_SEL[4:0]}                                                                           \r
+    { 0x38 , 0x01 }, //B_PPG1_ChA_ON_AMBC_ADJ[7:0]                                                                                                                             \r
+    { 0x3C , 0x01 }, //B_PPG2_ChA_ON_AMBC_ADJ[7:0]                                                                                                                             \r
+    { 0x40 , 0x05 }, //B_PPG1_ChB_ON_AMBC_ADJ[7:0]                                                                                                                             \r
+    { 0x44 , 0x05 }, //B_PPG2_ChB_ON_AMBC_ADJ[7:0]                                                                                                                             \r
+    { 0x48 , 0x05 }, //B_PPG1_ChC_ON_AMBC_ADJ[7:0]                                                                                                                             \r
+    { 0x4C , 0x05 }, //B_PPG2_ChC_ON_AMBC_ADJ[7:0]                                                                                                                             \r
+    { 0x50 , 0x0F }, //B_PPG1_ChD_ON_AMBC_ADJ[7:0]                                                                                                                             \r
+    { 0x54 , 0x0F }, //B_PPG2_ChD_ON_AMBC_ADJ[7:0]                                                                                                                             \r
+    { 0x69 , 0x01 }, //B_PPG1_ChA_OFF_AMBC_ADJ[7:0]                                                                                                                            \r
+    { 0x70 , 0x01 }, //B_PPG2_ChA_OFF_AMBC_ADJ[7:0]                                                                                                                            \r
+    { 0x6A , 0x05 }, //B_PPG1_ChB_OFF_AMBC_ADJ[7:0]                                                                                                                            \r
+    { 0x71 , 0x05 }, //B_PPG2_ChB_OFF_AMBC_ADJ[7:0]                                                                                                                            \r
+    { 0x6B , 0x05 }, //B_PPG1_ChC_OFF_AMBC_ADJ[7:0]                                                                                                                            \r
+    { 0x72 , 0x05 }, //B_PPG2_ChC_OFF_AMBC_ADJ[7:0]                                                                                                                            \r
+    { 0x6C , 0x0F }, //B_PPG1_ChD_OFF_AMBC_ADJ[7:0]                                                                                                                            \r
+    { 0x73 , 0x0F }, //B_PPG2_ChD_OFF_AMBC_ADJ[7:0]                                                                                                                            \r
+    { 0x7F , 0x00 }, //Bank0                                                                                                                                                   \r
+    { 0x15 , 0x01 }, //RDB_FrameNum_D[6:0]                                                                                                                                     \r
+    { 0x18 , 0x77 }, //{RDB_OffOnOff_F_EnH, RDB_OffOnOff_E_EnH, RDB_OffOnOff_T_EnH, RDB_OffOnOff_F_EnH, RDB_OffOnOff_E_EnH, RDB_OffOnOff_D_EnH, RDB_OffOnOff_C_EnH, RDB_OffOnOff_B_EnH, RDB_OffOnOff_A_EnH}                                                                                                                                    \r
+    { 0x4B , 0x0C }, //R_TouchDetection_Th_Hi[15:8]   3168\r
+    { 0x4D , 0x06 }, //R_TouchDetection_Th_Low[15:8]\r
+    { 0x4F , 0x0C }, //R_NoTouchDetection_Count_Th[4:0] 1568\r
+    { 0x7F , 0x00 }, //Bank0\r
+#ifndef Ext_LPO_CLK_FROM_GPIO2 \r
+    { 0x03 , 0x7D }, //Golden report period[7:0] (1T=31.25us)(256Hz)\r
+    { 0x04 , 0x00 }, //{Bit[7:0](Golden report period[15:8])}\r
+#else\r
+    { 0x03 , 0x80 }, //Golden report period[7:0] (1T=31.25us)(256Hz)\r
+    { 0x04 , 0x00 }, //{Bit[7:0](Golden report period[15:8])}\r
+#endif\r
+    { 0x27 , 0x20 }, //RDB_FrameNum_ECG[7:0]\r
+    { 0x4F , 0x04 }, //R_NoTouchDetection_Count_Th[4:0]\r
+    { 0x24 , 0x08 }, //RDB_ChT_report_divider[7:0]\r
+    { 0x2E , 0x03 }, //{fp_lpf_mask_cnt[7:4], Reserved[3], fp_lpf_sel[2:1](0:128/1:256/2:512/3:1024Hz), fp_lpf_enh[0]}\r
+    { 0x1B , 0x60 }, //{Reserved[7], RDB_LOD_EnH[6], RDB_ECG_EnH[5], RDB_ChT_EnH[4], RDB_ChD_EnH[3], RDB_ChC_EnH[2], RDB_ChB_EnH[1], RDB_ChA_EnH[0]}\r
+    { 0x68 , 0x00 }, //{Dummy[5:0], RDB_ChF_EnH, RDB_ChE_EnH}; \r
+    { 0x7F , 0x01 }, //Bank1\r
+    { 0x05 , 0x80 }, //{T_PPG2_AMBC_EnL, T_PPG2_ADC_EnL, T_PPG_LEDDAC2_EnL, T_PPG_LEDDAC1_EnL, T_ECG_FE_INA_EnL, T_ECG_ADC_EnL, T_ECG_FE_LOD_CMP_EnL, T_ECG_FE_LOD_I_EnL}\r
+    { 0x06 , 0x02 }, //{T_ECG_FE_LOD_GATE_INACHOP_EnH, T_ECG_FE_I_GATED_INA_EnH, T_ECG_PGA_TEST_EnH, T_ECG_FE_LOD_RLDCMP_EnL, T_ECG_FE_VCMBUF_EnL, T_ECG_FE_INA_HPF_SHORT, T_ECG_POLAR_FLIP_EnH, Dummy}\r
+    { 0x0B , 0x00 }, //(enable PPG and ECG) \r
+    { 0x0D , 0xF2 }, //{B_PPG_LEDDAC2_PWRSV_SEL_EnH, B_PPG_LEDDAC1_PWRSV_SEL_EnH, B_ECG_FE_INA_PWRSV_SEL_EnH, B_ECG_ADC_PWRSV_SEL_EnH, B_ECG_FE_LOD_CMP_PWRSV_SEL_EnH, B_ECG_FE_LOD_I_PWRSV_SEL_EnH, B_ECG_FE_RLD_PWRSV_SEL_EnH, B_ECG_FE_LOD_RLDCMP_PWRSV_SEL_EnH} \r
+    { 0x0F , 0x0E }, //{B_ECG_VCMBUF_OFF[3:0], B_ECG_FE_VCMBUF_PWRSV_SEL_EnH, B_ECG_FE_PGA_PWRSV_SEL_EnH, B_ECG_FE_BUF_PWRSV_SEL_EnH, B_ECG_FE_INA_LPF_FAST_SEL_EnH}\r
+    { 0x26 , 0x07 }, //{T_ECG_RF_PGA_ADJ[2:0], Dummy, T_ECG_PGA_LPF_1M_EN, T_ECG_FE_RLD2VCMBUF_EnH, T_ECG_FE_INA_GAIN[1:0]} \r
+    { 0x7E , 0x02 }, //{Dummy[4:0], B_ECG_FAST_RECOVERY_MODE, B_FAST_RECOVERY_EN, TS_ECG_FAST_RECOVERY_EnH} \r
+};\r
+#define PAH831X_REG_ECG_3_ODR (300)\r
+static const uint8_t PAH831X_REG_ECG_3[][2] = {\r
+    { 0x7F, 0x05},  \r
+};\r
+#define PAH831X_REG_ECG_4_ODR (300)\r
+static const uint8_t PAH831X_REG_ECG_4[][2] = {\r
+    { 0x7F, 0x01 },//Bank1 \r
+};\r
+#define PAH831X_REG_ECG_5_ODR (300)\r
+static const uint8_t PAH831X_REG_ECG_5[][2] = {\r
+    { 0x7F, 0x01 },//Bank1 \r
+};\r
+         \r
diff --git a/code/sdk/zhihui/drivers/ppg/pah831x/pah_sensor/pah831x_reg_default_note_0109_2LED_20251223.h b/code/sdk/zhihui/drivers/ppg/pah831x/pah_sensor/pah831x_reg_default_note_0109_2LED_20251223.h
new file mode 100644 (file)
index 0000000..c3131ab
--- /dev/null
@@ -0,0 +1,1485 @@
+#pragma once \r
+/**\r
+ * Copyright (c) 2022 PixArt Imaging Inc.\r
+ * All Rights Reserved.\r
+ * Confidential and Proprietary - PixArt Imaging Inc.\r
+ **/\r
+#include <stdint.h>\r
+#include "pah831x_config.h"\r
+\r
+static const uint8_t PAH831X_REG_INIT[][2] = {\r
+    { 0x7F, 0x05 },\r
+    { 0x00, 0x3F },\r
+    { 0x01, 0x00 },\r
+    { 0x02, 0x80 },\r
+    { 0x05, 0x00 },\r
+    { 0x06, 0x04 },\r
+    { 0x07, 0x00 },\r
+    { 0x08, 0xD0 },\r
+    { 0x09, 0x00 },\r
+    { 0x0A, 0x60 },\r
+    { 0x0B, 0x17 },\r
+    { 0x0D, 0x00 },\r
+    { 0x0E, 0x80 },\r
+    { 0x11, 0x00 },\r
+    { 0x12, 0x04 },\r
+    { 0x13, 0x00 },\r
+    { 0x14, 0xD0 },\r
+    { 0x15, 0x00 },\r
+    { 0x16, 0x60 },\r
+    { 0x17, 0x17 },\r
+    { 0x19, 0x00 },\r
+    { 0x1A, 0x80 },\r
+    { 0x1D, 0x00 },\r
+    { 0x1E, 0x04 },\r
+    { 0x1F, 0x00 },\r
+    { 0x20, 0xD0 },\r
+    { 0x21, 0x00 },\r
+    { 0x22, 0x60 },\r
+    { 0x23, 0x17 },\r
+    { 0x25, 0x00 },\r
+    { 0x26, 0x80 },\r
+    { 0x29, 0x00 },\r
+    { 0x2A, 0x04 },\r
+    { 0x2B, 0x00 },\r
+    { 0x2C, 0xD0 },\r
+    { 0x2D, 0x00 },\r
+    { 0x2E, 0x60 },\r
+    { 0x2F, 0x17 },\r
+    { 0x31, 0x00 },\r
+    { 0x32, 0x80 },\r
+    { 0x35, 0x00 },\r
+    { 0x36, 0x04 },\r
+    { 0x37, 0x00 },\r
+    { 0x38, 0xD0 },\r
+    { 0x39, 0x00 },\r
+    { 0x3A, 0x60 },\r
+    { 0x3B, 0x17 },\r
+    { 0x3D, 0x00 },\r
+    { 0x3E, 0x80 },\r
+    { 0x41, 0x00 },\r
+    { 0x42, 0x04 },\r
+    { 0x43, 0x00 },\r
+    { 0x44, 0xD0 },\r
+    { 0x45, 0x00 },\r
+    { 0x46, 0x60 },\r
+    { 0x47, 0x17 },\r
+    { 0x7F, 0x04 },\r
+    { 0x13, 0x09 },\r
+    { 0x29, 0x09 },\r
+    { 0x14, 0x20 },\r
+    { 0x2A, 0x20 },\r
+    { 0x00, 0xB1 },\r
+    { 0x03, 0x91 },\r
+    { 0x06, 0x91 },\r
+    { 0x09, 0xB1 },\r
+    { 0x0C, 0xB1 },\r
+    { 0x0F, 0xB1 },\r
+    { 0x12, 0x81 },\r
+    { 0x16, 0xB1 },\r
+    { 0x19, 0x91 },\r
+    { 0x1C, 0x91 },\r
+    { 0x1F, 0xB1 },\r
+    { 0x22, 0xB1 },\r
+    { 0x25, 0xB1 },\r
+    { 0x28, 0x81 },\r
+    { 0x2D, 0x01 },\r
+    { 0x2F, 0x01 },\r
+    { 0x31, 0x01 },\r
+    { 0x33, 0x01 },\r
+    { 0x35, 0x01 },\r
+    { 0x37, 0x01 },\r
+    { 0x01, 0x00 },\r
+    { 0x04, 0x00 },\r
+    { 0x07, 0x00 },\r
+    { 0x0A, 0x00 },\r
+    { 0x0D, 0x00 },\r
+    { 0x10, 0x00 },\r
+    { 0x17, 0x00 },\r
+    { 0x1A, 0x00 },\r
+    { 0x1D, 0x00 },\r
+    { 0x20, 0x00 },\r
+    { 0x23, 0x00 },\r
+    { 0x26, 0x00 },\r
+    { 0x7F, 0x03 },\r
+    { 0x0B, 0x36 },\r
+    { 0x50, 0x22 },\r
+    { 0x52, 0x01 },\r
+    { 0x58, 0x0C },\r
+    { 0x59, 0x08 },\r
+    { 0x5A, 0x08 },\r
+    { 0x0B, 0x37 },\r
+    { 0x50, 0x00 },\r
+    { 0x70, 0x10 },\r
+    { 0x7F, 0x02 },\r
+    { 0x4B, 0x00 },\r
+    { 0x4C, 0x00 },\r
+    { 0x7F, 0x01 },\r
+    { 0x00, 0x98 },\r
+    { 0x04, 0x40 },\r
+    { 0x05, 0x00 },\r
+    { 0x06, 0x03 },\r
+    { 0x08, 0x00 },\r
+    { 0x09, 0x33 },\r
+    { 0x0B, 0x00 },\r
+    { 0x0C, 0xBB },\r
+    { 0x0D, 0xF2 },\r
+    { 0x0F, 0x0E },\r
+    { 0x1A, 0x20 },\r
+    { 0x20, 0x07 },\r
+    { 0x21, 0x21 },\r
+    { 0x23, 0x95 },\r
+    { 0x26, 0x07 },\r
+    { 0x76, 0x58 },\r
+    { 0x77, 0xA0 },\r
+    { 0x78, 0x0F },\r
+    { 0x79, 0xA0 },\r
+    { 0x7A, 0x0F },\r
+    { 0x7B, 0x80 },\r
+    { 0x7C, 0x3E },\r
+    { 0x7D, 0x77 },\r
+    { 0x7E, 0x02 },\r
+    { 0x34, 0x04 },\r
+    { 0x36, 0x0C },\r
+    { 0x3A, 0x0C },\r
+    { 0x3E, 0x0C },\r
+    { 0x42, 0x0C },\r
+    { 0x46, 0x0C },\r
+    { 0x4A, 0x0C },\r
+    { 0x4E, 0x0C },\r
+    { 0x52, 0x0C },\r
+    { 0x56, 0x0C },\r
+    { 0x5A, 0x0C },\r
+    { 0x5E, 0x0C },\r
+    { 0x62, 0x0C },\r
+    { 0x66, 0x0C },\r
+    { 0x37, 0x07 },\r
+    { 0x3B, 0x07 },\r
+    { 0x3F, 0x07 },\r
+    { 0x43, 0x07 },\r
+    { 0x47, 0x07 },\r
+    { 0x4B, 0x07 },\r
+    { 0x4F, 0x07 },\r
+    { 0x53, 0x07 },\r
+    { 0x57, 0x07 },\r
+    { 0x5B, 0x07 },\r
+    { 0x5F, 0x07 },\r
+    { 0x63, 0x07 },\r
+    { 0x67, 0x07 },\r
+    { 0x68, 0x0F },\r
+    { 0x6F, 0x0F },\r
+    { 0x65, 0x06 },\r
+    { 0x7F, 0x00 },\r
+    { 0x29, 0x01 },\r
+    { 0x2A, 0x00 },\r
+    { 0x2B, 0x01 },\r
+    { 0x2C, 0x00 },\r
+    { 0x27, 0x20 },\r
+    { 0x28, 0x00 },\r
+    { 0x2D, 0x00 },\r
+    { 0x2E, 0x03 },\r
+    { 0x5F, 0x00 },\r
+    { 0x60, 0x00 },\r
+    { 0x46, 0x00 },\r
+    { 0x47, 0x00 },\r
+    { 0x48, 0x00 },\r
+    { 0x35, 0x14 },\r
+    { 0x36, 0x00 },\r
+    { 0x37, 0x00 },\r
+    { 0x5A, 0x02 },\r
+    { 0x5B, 0x02 },\r
+    { 0x12, 0x08 },\r
+    { 0x13, 0x08 },\r
+    { 0x14, 0x08 },\r
+    { 0x15, 0x08 },\r
+    { 0x16, 0x02 },\r
+    { 0x6D, 0x08 },\r
+    { 0x6E, 0x08 },\r
+    { 0x17, 0x00 },\r
+    { 0x18, 0x7F },\r
+    { 0x19, 0x7F },\r
+    { 0x49, 0x01 },\r
+    { 0x4A, 0x60 },\r
+    { 0x4B, 0x6D },\r
+    { 0x4C, 0x20 },\r
+    { 0x4D, 0x4E },\r
+    { 0x4E, 0x00/*0x01*/ },\r
+    { 0x4F, 0x0C },\r
+    { 0x32, 0xFF },\r
+    { 0x5C, 0xFF },\r
+    { 0x54, 0xFF },\r
+    { 0x55, 0xFF },\r
+    { 0x50, 0x17 },\r
+    { 0x51, 0x17 },\r
+    { 0x52, 0x17 },\r
+    { 0x53, 0x17 },\r
+    { 0x70, 0x17 },\r
+    { 0x71, 0x17 },\r
+    { 0x56, 0x01 },\r
+};               \r
+                 \r
+\r
+static const uint8_t PAH831X_REG_DEINIT[][2] = {\r
+    { 0x7F, 0x01 }, \r
+    { 0x00, 0x98 }, \r
+};\r
+\r
+static const uint8_t PAH831X_REG_TOUCH[][2] = {\r
+    { 0x7F, 0x03 },\r
+    { 0x0B, 0x36 },\r
+#ifndef Ext_LPO_CLK_FROM_GPIO2   \r
+    { 0x59 , 0x0C }, \r
+    { 0x5B , 0x08 }, \r
+   // { 0x59, 0x08 }, \r
+    { 0x52 , 0x01 }, \r
+#else\r
+    { 0x59 , 0x0C }, \r
+    { 0x5B , 0x08 }, \r
+    { 0x52 , 0x00 }, \r
+    { 0x5A , 0x04 }, \r
+    { 0x54 , 0x14 }, \r
+    { 0x54 , 0x16 }, \r
+#endif\r
+    { 0x0B, 0x37 },\r
+    { 0x7F, 0x04 },\r
+    { 0x12, 0x81 },\r
+    { 0x28, 0x81 },\r
+    { 0x13, LED_IR1+LED_IR2/*0x09*/ },\r
+    { 0x29, LED_IR1+LED_IR2/*0x09*/ },\r
+    { 0x14, 0x20 },\r
+    { 0x2A, 0x20 },\r
+    { 0x7F, 0x00 },\r
+    { 0x4B, 0x0C },//R_TouchDetection_Th_Hi[15:8]   3168\r
+    { 0x4D, 0x06 },//R_TouchDetection_Th_Low[15:8]  1568\r
+    { 0x7F, 0x01 },\r
+    { 0x65, PD_2+PD_3/*0x05*/ },\r
+    { 0x7F, 0x00 },\r
+    { 0x03, 0x80 },//Golden report period[7:0] (1T=31.25us)\r
+    { 0x04, 0x0C },//Golden report period[15:8], 10Hz\r
+    { 0x4F, 0x04 },//R_NoTouchDetection_Count_Th[4:0]\r
+    { 0x1B, 0x10 },\r
+    { 0x68, 0x00 },\r
+};\r
+//PAH831X_REG_PPG_1 : 20HZ 1CH_2PPG G/G 150K\r
+#define PAH831X_REG_PPG_1_ODR (20)\r
+static const uint8_t PAH831X_REG_PPG_1[][2] = {\r
+    { 0x7F, 0x03 },\r
+    { 0x0B, 0x36 },\r
+#ifndef Ext_LPO_CLK_FROM_GPIO2   \r
+    { 0x59 , 0x0C }, \r
+    { 0x5B , 0x08 }, \r
+   // { 0x59, 0x08 }, \r
+    { 0x52 , 0x01 }, \r
+#else\r
+    { 0x59 , 0x0C }, \r
+    { 0x5B , 0x08 }, \r
+    { 0x52 , 0x00 }, \r
+    { 0x5A , 0x04 }, \r
+    { 0x54 , 0x14 }, \r
+    { 0x54 , 0x16 }, \r
+#endif\r
+    { 0x0B, 0x37 },\r
+    { 0x7F, 0x04 },\r
+    { 0x00, 0xB6 },\r
+    { 0x03, 0x96 },\r
+    { 0x06, 0x96 },\r
+    { 0x09, 0xB6 },\r
+    { 0x0C, 0xB6 },\r
+    { 0x0F, 0xB6 },\r
+    { 0x16, 0xB6 },\r
+    { 0x19, 0x96 },\r
+    { 0x1C, 0x96 },\r
+    { 0x1F, 0xB6 },\r
+    { 0x22, 0xB6 },\r
+    { 0x25, 0xB6 },\r
+    { 0x12, 0x86 },\r
+    { 0x28, 0x86 },\r
+    { 0x13, LED_IR1+LED_IR2/*0x09*/ },\r
+    { 0x29, LED_IR1+LED_IR2/*0x09*/ },\r
+    { 0x14, 0x20 },\r
+    { 0x2A, 0x20 },\r
+    { 0x7F, 0x00 },\r
+    { 0x4B, 0x0C },//R_TouchDetection_Th_Hi[15:8]   3168\r
+    { 0x4D, 0x06 },//R_TouchDetection_Th_Low[15:8]  1568\r
+    { 0x7F, 0x04 },\r
+    { 0x01, LED_GREEN_1+LED_GREEN_2/*0x24*/ },\r
+    { 0x04, LED_R1+LED_R2/*0x12*/ },\r
+    { 0x07, LED_IR1+LED_IR2/*0x09*/ },\r
+    { 0x17, LED_GREEN_1+LED_GREEN_2/*0x24*/ },\r
+    { 0x1A, LED_R1+LED_R2/*0x12*/ },\r
+    { 0x1D, LED_IR1+LED_IR2/*0x09*/ },\r
+    { 0x7F, 0x01 },\r
+    { 0x65, PD_2+PD_3/*0x05*/ },\r
+    { 0x04, 0x40 },\r
+    { 0x05, 0x00 },\r
+    { 0x0B, 0x0C },\r
+    { 0x36, 0x05 },\r
+    { 0x3A, 0x05 },\r
+    { 0x3E, 0x0C },\r
+    { 0x42, 0x0C },\r
+    { 0x46, 0x0C },\r
+    { 0x4A, 0x0C },\r
+    { 0x37, 0x09 },\r
+    { 0x3B, 0x09 },\r
+    { 0x3F, 0x07 },\r
+    { 0x43, 0x07 },\r
+    { 0x47, 0x07 },\r
+    { 0x4B, 0x07 },\r
+    { 0x35, PD_2+PD_3/*0x05*/ },\r
+    { 0x39, PD_1+PD_4/*0x0A*/ },\r
+    { 0x3D, PD_2+PD_3/*0x05*/ },\r
+    { 0x41, PD_1+PD_4/*0x0A*/ },\r
+    { 0x45, PD_2+PD_3/*0x05*/ },\r
+    { 0x49, PD_1+PD_4/*0x0A*/ },\r
+    { 0x38, 0x06 },\r
+    { 0x3C, 0x06 },\r
+    { 0x40, 0x0F },\r
+    { 0x44, 0x0F },\r
+    { 0x48, 0x0F },\r
+    { 0x4C, 0x0F },                                               \r
+    { 0x69, 0x06 },\r
+    { 0x70, 0x06 },\r
+    { 0x6A, 0x0F },\r
+    { 0x71, 0x0F },\r
+    { 0x6B, 0x0F },\r
+    { 0x72, 0x0F },\r
+    { 0x7F, 0x00 },\r
+    { 0x18, 0x7F },\r
+#ifndef Ext_LPO_CLK_FROM_GPIO2 \r
+    { 0x03, 0x40 },//Golden report period[7:0] (1T=31.25us)\r
+    { 0x04, 0x06 },//Golden report period[15:8], 20Hz\r
+#else    \r
+    \r
+    { 0x03, 0x66 },//Golden report period[7:0] (1T=31.25us)\r
+    { 0x04, 0x06 },//Golden report period[15:8], 20Hz\r
+#endif\r
+    { 0x4F, 0x09 },//R_NoTouchDetection_Count_Th[4:0]\r
+    { 0x1B, 0x11 },\r
+    { 0x50, 0x17 },\r
+    { 0x51, 0x17 },\r
+    { 0x52, 0x17 },\r
+    { 0x68, 0x00 },\r
+};\r
+\r
+\r
+//PAH831X_REG_PPG_2 : 25HZ 4CH_1PPG  R1/R2/IR1/IR2 150K\r
+#define PAH831X_REG_PPG_2_ODR (25)\r
+static const uint8_t PAH831X_REG_PPG_2[][2] = {\r
+    { 0x7F, 0x03 },\r
+    { 0x0B, 0x36 },\r
+#ifndef Ext_LPO_CLK_FROM_GPIO2   \r
+    { 0x59 , 0x0C }, \r
+    { 0x5B , 0x08 }, \r
+   // { 0x59, 0x08 }, \r
+    { 0x52 , 0x01 }, \r
+#else\r
+    { 0x59 , 0x0C }, \r
+    { 0x5B , 0x08 }, \r
+    { 0x52 , 0x00 }, \r
+    { 0x5A , 0x04 }, \r
+    { 0x54 , 0x14 }, \r
+    { 0x54 , 0x16 }, \r
+#endif\r
+    { 0x0B, 0x37 },\r
+    { 0x7F, 0x04 },\r
+    { 0x00, 0xB6 },\r
+    { 0x03, 0x96 },\r
+    { 0x06, 0xA6 },\r
+    { 0x09, 0xA6 },\r
+    { 0x0C, 0xA6 },\r
+    { 0x0F, 0xA6 },\r
+    { 0x16, 0xB6 },\r
+    { 0x19, 0x96 },\r
+    { 0x1C, 0xA6 },\r
+    { 0x1F, 0xA6 },\r
+    { 0x22, 0xA6 },\r
+    { 0x25, 0xA6 },\r
+    { 0x12, 0x86 },\r
+    { 0x28, 0x86 },\r
+    { 0x13, LED_IR1+LED_IR2/*0x09*/ },\r
+    { 0x29, LED_IR1+LED_IR2/*0x09*/ },\r
+    { 0x14, 0x20 },\r
+    { 0x2A, 0x20 },\r
+    { 0x7F, 0x00 },\r
+    { 0x4B, 0x0C },//R_TouchDetection_Th_Hi[15:8]   3168\r
+    { 0x4D, 0x06 },//R_TouchDetection_Th_Low[15:8]  1568\r
+    { 0x7F, 0x04 },\r
+    { 0x07, LED_R1/*0x02*/ },\r
+    { 0x0A, LED_R2/*0x10*/ },\r
+    { 0x0D, LED_IR1/*0x01*/ },\r
+    { 0x10, LED_IR2/*0x08*/ },\r
+    { 0x1D, LED_R1/*0x02*/ },\r
+    { 0x20, LED_R2/*0x10*/ },\r
+    { 0x23, LED_IR1/*0x01*/ },\r
+    { 0x26, LED_IR2/*0x08*/ },\r
+    { 0x7F, 0x01 },\r
+    { 0x65, PD_2+PD_3/*0x05*//*0x09*/ },\r
+    { 0x0B, 0x0C },//(enable PPG/ECG BG/PMU block) \r
+    { 0x46, 0x0C },\r
+    { 0x4A, 0x0C },\r
+    { 0x4E, 0x0C },\r
+    { 0x52, 0x0C },\r
+    { 0x56, 0x0C },\r
+    { 0x5A, 0x0C },\r
+    { 0x5E, 0x0C },\r
+    { 0x62, 0x0C },\r
+    { 0x47, 0x07 },\r
+    { 0x4B, 0x07 },\r
+    { 0x4F, 0x07 },\r
+    { 0x53, 0x07 },\r
+    { 0x57, 0x07 },\r
+    { 0x5B, 0x07 },\r
+    { 0x5F, 0x07 },\r
+    { 0x63, 0x07 },\r
+    { 0x45, PD_1+PD_2/*0x09*/ },\r
+    { 0x49, PD_3+PD_4/*0x06*/ },\r
+    { 0x4D, PD_1+PD_2/*0x09*/ },\r
+    { 0x51, PD_3+PD_4/*0x06*/ },\r
+    { 0x55, PD_1+PD_2/*0x09*/ },\r
+    { 0x59, PD_3+PD_4/*0x06*/ },\r
+    { 0x5D, PD_1+PD_2/*0x09*/ },\r
+    { 0x61, PD_3+PD_4/*0x06*/ },\r
+    { 0x48, 0x0F },\r
+    { 0x4C, 0x0F },\r
+    { 0x50, 0x0F },\r
+    { 0x54, 0x0F },\r
+    { 0x58, 0x0F },\r
+    { 0x5C, 0x0F },\r
+    { 0x60, 0x0F },\r
+    { 0x64, 0x0F },\r
+    { 0x6B, 0x0F },\r
+    { 0x72, 0x0F },\r
+    { 0x6C, 0x0F },\r
+    { 0x73, 0x0F },\r
+    { 0x6D, 0x0F },\r
+    { 0x74, 0x0F },\r
+    { 0x6E, 0x0F },\r
+    { 0x75, 0x0F },\r
+    { 0x7F, 0x00 },\r
+    { 0x18, 0x7F },\r
+#ifndef Ext_LPO_CLK_FROM_GPIO2 \r
+    { 0x03, 0x00 },//Golden report period[7:0] (1T=31.25us)\r
+    { 0x04, 0x05 },//Golden report period[15:8], 25Hz\r
+#else    \r
+    { 0x03, 0x1E },//Golden report period[7:0] (1T=31.25us)\r
+    { 0x04, 0x05 },//Golden report period[15:8], 25Hz\r
+#endif\r
+    { 0x1B, 0x1C },\r
+    { 0x4F, 0x0C },//R_NoTouchDetection_Count_Th[4:0]\r
+    { 0x52, 0x12 },\r
+    { 0x53, 0x05 },\r
+    { 0x70, 0x12 },\r
+    { 0x71, 0x05 },\r
+    { 0x68, 0x03 },\r
+};   \r
+\r
+//PAH831X_REG_PPG_3 : 25HZ 1CH_1PPG G\r
+#define PAH831X_REG_PPG_3_ODR (25)\r
+static const uint8_t PAH831X_REG_PPG_3[][2] = {\r
+   { 0x7F, 0x03 },\r
+    { 0x0B, 0x36 },\r
+#ifndef Ext_LPO_CLK_FROM_GPIO2   \r
+    { 0x59 , 0x0C }, \r
+    { 0x5B , 0x08 }, \r
+   // { 0x59, 0x08 }, \r
+    { 0x52 , 0x01 }, \r
+#else\r
+    { 0x59 , 0x0C }, \r
+    { 0x5B , 0x08 }, \r
+    { 0x52 , 0x00 }, \r
+    { 0x5A , 0x04 }, \r
+    { 0x54 , 0x14 }, \r
+    { 0x54 , 0x16 }, \r
+#endif\r
+    { 0x0B, 0x37 },\r
+    { 0x7F, 0x04 },\r
+    { 0x00, 0xB6 },\r
+    { 0x03, 0x96 },\r
+    { 0x06, 0x96 },\r
+    { 0x09, 0xB6 },\r
+    { 0x0C, 0xB6 },\r
+    { 0x0F, 0xB6 },\r
+    { 0x16, 0xB6 },\r
+    { 0x19, 0x96 },\r
+    { 0x1C, 0x96 },\r
+    { 0x1F, 0xB6 },\r
+    { 0x22, 0xB6 },\r
+    { 0x25, 0xB6 },\r
+    { 0x12, 0x86 },\r
+    { 0x28, 0x86 },\r
+    { 0x13, LED_IR1+LED_IR2/*0x09*/ },\r
+    { 0x29, LED_IR1+LED_IR2/*0x09*/ },\r
+    { 0x14, 0x20 },\r
+    { 0x2A, 0x20 },\r
+    { 0x7F, 0x00 },\r
+    { 0x4B, 0x0C },//R_TouchDetection_Th_Hi[15:8]   3168\r
+    { 0x4D, 0x06 },//R_TouchDetection_Th_Low[15:8]  1568\r
+    { 0x7F, 0x04 },\r
+    { 0x01, LED_GREEN_1+LED_GREEN_2/*0x24*/ },\r
+    { 0x04, LED_R1+LED_R2/*0x12*/ },\r
+    { 0x07, LED_IR1+LED_IR2/*0x09*/ },\r
+    { 0x17, LED_GREEN_1+LED_GREEN_2/*0x24*/ },\r
+    { 0x1A, LED_R1+LED_R2/*0x12*/ },\r
+    { 0x1D, LED_IR1+LED_IR2/*0x09*/ },\r
+    { 0x7F, 0x01 },\r
+    { 0x65, PD_2+PD_3/*0x05*/ },\r
+    { 0x04, 0x40 },\r
+    { 0x05, 0x00 },\r
+    { 0x0B, 0x0C },//(disable ECG BG/PMU block)\r
+    { 0x36, 0x05 },\r
+    { 0x3A, 0x05 },\r
+    { 0x3E, 0x0C },\r
+    { 0x42, 0x0C },\r
+    { 0x46, 0x0C },\r
+    { 0x4A, 0x0C },\r
+    { 0x37, 0x09 },\r
+    { 0x3B, 0x09 },\r
+    { 0x3F, 0x07 },\r
+    { 0x43, 0x07 },\r
+    { 0x47, 0x07 },\r
+    { 0x4B, 0x07 },\r
+    { 0x35, PD_1+PD_2+PD_3+PD_4/*0x0F*/ },\r
+    { 0x39, 0x10 },\r
+    { 0x3D, PD_2+PD_3/*0x05*/ },\r
+    { 0x41, PD_1+PD_4/*0x0A*/ },\r
+    { 0x45, PD_2+PD_3/*0x05*/ },\r
+    { 0x49, PD_1+PD_4/*0x0A*/ },\r
+    { 0x38, 0x06 },\r
+    { 0x3C, 0x06 },\r
+    { 0x40, 0x0F },\r
+    { 0x44, 0x0F },\r
+    { 0x48, 0x0F },\r
+    { 0x4C, 0x0F },\r
+    { 0x69, 0x06 },\r
+    { 0x70, 0x06 },\r
+    { 0x6A, 0x0F },\r
+    { 0x71, 0x0F },\r
+    { 0x6B, 0x0F },\r
+    { 0x72, 0x0F },\r
+    { 0x7F, 0x00 },\r
+    { 0x18, 0x7F },\r
+#ifndef Ext_LPO_CLK_FROM_GPIO2 \r
+    { 0x03, 0x00 },//Golden report period[7:0] (1T=31.25us)\r
+    { 0x04, 0x05 },//Golden report period[15:8], 25Hz\r
+#else    \r
+    { 0x03, 0x1E },//Golden report period[7:0] (1T=31.25us)\r
+    { 0x04, 0x05 },//Golden report period[15:8], 25Hz\r
+#endif\r
+    { 0x4F, 0x09 },//R_NoTouchDetection_Count_Th[4:0]\r
+    { 0x1B, 0x11 },\r
+    { 0x50, 0x05 },\r
+//    { 0x51, 0x17 },\r
+//    { 0x52, 0x17 },\r
+    { 0x68, 0x00 },\r
+};\r
+\r
+//PAH831X_REG_PPG_4 : 50HZ 3CH_2PPG G1/G2/R1/R2/IR1/IR2\r
+#define PAH831X_REG_PPG_4_ODR (20)\r
+static const uint8_t PAH831X_REG_PPG_4[][2] = {\r
+     { 0x7F, 0x03 },\r
+    { 0x0B, 0x36 },\r
+#ifndef Ext_LPO_CLK_FROM_GPIO2   \r
+    { 0x59 , 0x0C }, \r
+    { 0x5B , 0x08 }, \r
+   // { 0x59, 0x08 }, \r
+    { 0x52 , 0x01 }, \r
+#else\r
+    { 0x59 , 0x0C }, \r
+    { 0x5B , 0x08 }, \r
+    { 0x52 , 0x00 }, \r
+    { 0x5A , 0x04 }, \r
+    { 0x54 , 0x14 }, \r
+    { 0x54 , 0x16 }, \r
+#endif\r
+    { 0x0B, 0x37 },\r
+    { 0x7F, 0x04 },\r
+    { 0x00, 0xB6 },\r
+    { 0x03, 0x96 },\r
+    { 0x06, 0x96 },\r
+    { 0x09, 0xB6 },\r
+    { 0x0C, 0xB6 },\r
+    { 0x0F, 0xB6 },\r
+    { 0x16, 0xB6 },\r
+    { 0x19, 0x96 },\r
+    { 0x1C, 0x96 },\r
+    { 0x1F, 0xB6 },\r
+    { 0x22, 0xB6 },\r
+    { 0x25, 0xB6 },\r
+    { 0x12, 0x86 },\r
+    { 0x28, 0x86 },\r
+    { 0x13, LED_IR1+LED_IR2/*0x09*/ },\r
+    { 0x29, LED_IR1+LED_IR2/*0x09*/ },\r
+    { 0x14, 0x20 },\r
+    { 0x2A, 0x20 },\r
+    { 0x7F, 0x00 },\r
+    { 0x4B, 0x0C },//R_TouchDetection_Th_Hi[15:8]   3168\r
+    { 0x4D, 0x06 },//R_TouchDetection_Th_Low[15:8]  1568\r
+    { 0x7F, 0x04 },\r
+    { 0x01, LED_GREEN_1+LED_GREEN_2/*0x24*/ },\r
+    { 0x04, LED_R1+LED_R2/*0x12*/ },\r
+    { 0x07, LED_IR1+LED_IR2/*0x09*/ },\r
+    { 0x17, LED_GREEN_1+LED_GREEN_2/*0x24*/ },\r
+    { 0x1A, LED_R1+LED_R2/*0x12*/ },\r
+    { 0x1D, LED_IR1+LED_IR2/*0x09*/ },\r
+    { 0x7F, 0x01 },\r
+    { 0x65, PD_2+PD_3/*0x05*/ },\r
+    { 0x04, 0x40 },\r
+    { 0x05, 0x00 },\r
+    { 0x0B, 0x0C },//(disable ECG BG/PMU block)\r
+    { 0x36, 0x05 },\r
+    { 0x3A, 0x05 },\r
+    { 0x3E, 0x0C },\r
+    { 0x42, 0x0C },\r
+    { 0x46, 0x0C },\r
+    { 0x4A, 0x0C },\r
+    { 0x37, 0x09 },\r
+    { 0x3B, 0x09 },\r
+    { 0x3F, 0x07 },\r
+    { 0x43, 0x07 },\r
+    { 0x47, 0x07 },\r
+    { 0x4B, 0x07 },\r
+    { 0x35, PD_2+PD_3/*0x05*/ },\r
+    { 0x39, PD_1+PD_4/*0x0A*/ },\r
+    { 0x3D, PD_2+PD_3/*0x05*/ },\r
+    { 0x41, PD_1+PD_4/*0x0A*/ },\r
+    { 0x45, PD_2+PD_3/*0x05*/ },\r
+    { 0x49, PD_1+PD_4/*0x0A*/ },\r
+    { 0x38, 0x06 },\r
+    { 0x3C, 0x06 },\r
+    { 0x40, 0x0F },\r
+    { 0x44, 0x0F },\r
+    { 0x48, 0x0F },\r
+    { 0x4C, 0x0F },\r
+    { 0x69, 0x06 },\r
+    { 0x70, 0x06 },\r
+    { 0x6A, 0x0F },\r
+    { 0x71, 0x0F },\r
+    { 0x6B, 0x0F },\r
+    { 0x72, 0x0F },\r
+    { 0x7F, 0x00 },\r
+    { 0x18, 0x7F },\r
+#ifndef Ext_LPO_CLK_FROM_GPIO2\r
+    { 0x03, 0x80 },//Golden report period[7:0] (1T=31.25us)\r
+    { 0x04, 0x02 },//Golden report period[15:8], 50Hz\r
+#else    \r
+    \r
+    { 0x03, 0x8F },//Golden report period[7:0] (1T=31.25us)\r
+    { 0x04, 0x02 },//Golden report period[15:8], 50Hz\r
+#endif\r
+    { 0x4F, 0x16 },//R_NoTouchDetection_Count_Th[4:0]\r
+    { 0x1B, 0x17 },\r
+    { 0x50, 0x17 },\r
+    { 0x51, 0x17 },\r
+    { 0x52, 0x17 },\r
+    { 0x68, 0x00 },\r
+};\r
+\r
+//PAH831X_REG_PPG_5 : 25HZ 3CH_1PPG G/R_FAR/IR_FAR\r
+#define PAH831X_REG_PPG_5_ODR (25)\r
+static const uint8_t PAH831X_REG_PPG_5[][2] = {\r
+   { 0x7F, 0x03 },\r
+    { 0x0B, 0x36 },\r
+#ifndef Ext_LPO_CLK_FROM_GPIO2   \r
+    { 0x59 , 0x0C }, \r
+    { 0x5B , 0x08 }, \r
+   // { 0x59, 0x08 }, \r
+    { 0x52 , 0x01 }, \r
+#else\r
+    { 0x59 , 0x0C }, \r
+    { 0x5B , 0x08 }, \r
+    { 0x52 , 0x00 }, \r
+    { 0x5A , 0x04 }, \r
+    { 0x54 , 0x14 }, \r
+    { 0x54 , 0x16 }, \r
+#endif\r
+    { 0x0B, 0x37 },\r
+    { 0x7F, 0x04 },\r
+    { 0x00, 0xB6 },\r
+    { 0x03, 0x96 },\r
+    { 0x06, 0xA6 },\r
+    { 0x09, 0xA6 },\r
+    { 0x0C, 0xA6 },\r
+    { 0x0F, 0xA6 },\r
+    { 0x16, 0xB6 },\r
+    { 0x19, 0x96 },\r
+    { 0x1C, 0xA6 },\r
+    { 0x1F, 0xA6 },\r
+    { 0x22, 0xA6 },\r
+    { 0x25, 0xA6 },\r
+    { 0x12, 0x86 },\r
+    { 0x28, 0x86 },\r
+    { 0x13, LED_IR1+LED_IR2/*0x09*/ },\r
+    { 0x29, LED_IR1+LED_IR2/*0x09*/ },\r
+    { 0x14, 0x20 },\r
+    { 0x2A, 0x20 },\r
+    { 0x7F, 0x00 },\r
+    { 0x4B, 0x0C },//R_TouchDetection_Th_Hi[15:8]   3168\r
+    { 0x4D, 0x06 },//R_TouchDetection_Th_Low[15:8]  1568\r
+    { 0x7F, 0x04 },\r
+    { 0x01, LED_GREEN_1+LED_GREEN_2/*0x24*/ },\r
+    { 0x07, LED_R1/*0x02*/ },\r
+    { 0x0A, LED_R2/*0x10*/ },\r
+    { 0x0D, LED_IR1/*0x01*/ },\r
+    { 0x10, LED_IR2/*0x08*/ },\r
+    { 0x1D, LED_R1/*0x02*/ },\r
+    { 0x17, LED_GREEN_1+LED_GREEN_2/*0x24*/ },\r
+    { 0x20, LED_R2/*0x10*/ },\r
+    { 0x23, LED_IR1/*0x01*/ },\r
+    { 0x26, LED_IR2/*0x08*/ },\r
+    { 0x7F, 0x01 },\r
+    { 0x65, PD_2+PD_3/*0x05*//*0x09*/ },\r
+    { 0x0B, 0x0C },//(enable PPG/ECG BG/PMU block) \r
+    { 0x36, 0x05 },\r
+    { 0x3A, 0x05 },\r
+    { 0x46, 0x0C },\r
+    { 0x4A, 0x0C },\r
+    { 0x4E, 0x0C },\r
+    { 0x52, 0x0C },\r
+    { 0x56, 0x0C },\r
+    { 0x5A, 0x0C },\r
+    { 0x5E, 0x0C },\r
+    { 0x62, 0x0C },\r
+    { 0x37, 0x09 },\r
+    { 0x3B, 0x09 },        \r
+    { 0x47, 0x07 },\r
+    { 0x4B, 0x07 },\r
+    { 0x4F, 0x07 },\r
+    { 0x53, 0x07 },\r
+    { 0x57, 0x07 },\r
+    { 0x5B, 0x07 },\r
+    { 0x5F, 0x07 },\r
+    { 0x63, 0x07 },\r
+    { 0x35, PD_1+PD_2/*0x09*/ },\r
+    { 0x39, PD_3+PD_4/*0x06*/ },\r
+    { 0x45, PD_1+PD_2/*0x09*/ },\r
+    { 0x49, PD_3+PD_4/*0x06*/ },\r
+    { 0x4D, PD_1+PD_2/*0x09*/ },\r
+    { 0x51, PD_3+PD_4/*0x06*/ },\r
+    { 0x55, PD_1+PD_2/*0x09*/ },\r
+    { 0x59, PD_3+PD_4/*0x06*/ },\r
+    { 0x5D, PD_1+PD_2/*0x09*/ },\r
+    { 0x61, PD_3+PD_4/*0x06*/ },\r
+    { 0x38, 0x06 },\r
+    { 0x3C, 0x06 },\r
+    { 0x48, 0x0F },\r
+    { 0x4C, 0x0F },\r
+    { 0x50, 0x0F },\r
+    { 0x54, 0x0F },\r
+    { 0x58, 0x0F },\r
+    { 0x5C, 0x0F },\r
+    { 0x60, 0x0F },\r
+    { 0x64, 0x0F },\r
+    { 0x69, 0x06 },\r
+    { 0x70, 0x06 },   \r
+    { 0x6B, 0x0F },\r
+    { 0x72, 0x0F },\r
+    { 0x6C, 0x0F },\r
+    { 0x73, 0x0F },\r
+    { 0x6D, 0x0F },\r
+    { 0x74, 0x0F },\r
+    { 0x6E, 0x0F },\r
+    { 0x75, 0x0F },\r
+    { 0x7F, 0x00 },\r
+    { 0x18, 0x7F },\r
+#ifndef Ext_LPO_CLK_FROM_GPIO2 \r
+    { 0x03, 0x00 },//Golden report period[7:0] (1T=31.25us)\r
+    { 0x04, 0x05 },//Golden report period[15:8], 25Hz\r
+#else    \r
+    { 0x03, 0x1E },//Golden report period[7:0] (1T=31.25us)\r
+    { 0x04, 0x05 },//Golden report period[15:8], 25Hz\r
+#endif\r
+    { 0x1B, 0x15 },\r
+    { 0x4F, 0x0C },//R_NoTouchDetection_Count_Th[4:0]\r
+    { 0x50, 0x12 },\r
+    { 0x52, 0x12 },\r
+    { 0x53, 0x05 },\r
+    { 0x70, 0x12 },\r
+    { 0x71, 0x05 },\r
+    { 0x68, 0x01 },\r
+};\r
+\r
+//PAH831X_REG_PPG_6 : 25HZ 5CH_1PPG G/R1_FAR/R2_FAR/IR1_FAR/IR2_FAR\r
+#define PAH831X_REG_PPG_6_ODR (100)\r
+static const uint8_t PAH831X_REG_PPG_6[][2] = {\r
+   { 0x7F, 0x03 },\r
+    { 0x0B, 0x36 },\r
+#ifndef Ext_LPO_CLK_FROM_GPIO2   \r
+    { 0x59 , 0x0C }, \r
+    { 0x5B , 0x08 }, \r
+   // { 0x59, 0x08 }, \r
+    { 0x52 , 0x01 }, \r
+#else\r
+    { 0x59 , 0x0C }, \r
+    { 0x5B , 0x08 }, \r
+    { 0x52 , 0x00 }, \r
+    { 0x5A , 0x04 }, \r
+    { 0x54 , 0x14 }, \r
+    { 0x54 , 0x16 }, \r
+#endif\r
+    { 0x0B, 0x37 },\r
+    { 0x7F, 0x04 },\r
+    { 0x00, 0xB6 },\r
+    { 0x03, 0x96 },\r
+    { 0x06, 0xA6 },\r
+    { 0x09, 0xA6 },\r
+    { 0x0C, 0xA6 },\r
+    { 0x0F, 0xA6 },\r
+    { 0x16, 0xB6 },\r
+    { 0x19, 0x96 },\r
+    { 0x1C, 0xA6 },\r
+    { 0x1F, 0xA6 },\r
+    { 0x22, 0xA6 },\r
+    { 0x25, 0xA6 },\r
+    { 0x12, 0x86 },\r
+    { 0x28, 0x86 },\r
+    { 0x13, LED_IR1+LED_IR2/*0x09*/ },\r
+    { 0x29, LED_IR1+LED_IR2/*0x09*/ },\r
+    { 0x14, 0x20 },\r
+    { 0x2A, 0x20 },\r
+    { 0x7F, 0x00 },\r
+    { 0x4B, 0x0C },//R_TouchDetection_Th_Hi[15:8]   3168\r
+    { 0x4D, 0x06 },//R_TouchDetection_Th_Low[15:8]  1568\r
+    { 0x7F, 0x04 },\r
+    { 0x01, LED_GREEN_1+LED_GREEN_2/*0x24*/ },\r
+    { 0x07, LED_R1/*0x02*/ },\r
+    { 0x0A, LED_R2/*0x10*/ },\r
+    { 0x0D, LED_IR1/*0x01*/ },\r
+    { 0x10, LED_IR2/*0x08*/ },\r
+    { 0x1D, LED_R1/*0x02*/ },\r
+    { 0x17, LED_GREEN_1+LED_GREEN_2/*0x24*/ },\r
+    { 0x20, LED_R2/*0x10*/ },\r
+    { 0x23, LED_IR1/*0x01*/ },\r
+    { 0x26, LED_IR2/*0x08*/ },\r
+    { 0x7F, 0x01 },\r
+    { 0x65, PD_2+PD_3/*0x05*//*0x09*/ },\r
+    { 0x0B, 0x0C },//(enable PPG/ECG BG/PMU block) \r
+    { 0x36, 0x05 },\r
+    { 0x3A, 0x05 },\r
+    { 0x46, 0x0C },\r
+    { 0x4A, 0x0C },\r
+    { 0x4E, 0x0C },\r
+    { 0x52, 0x0C },\r
+    { 0x56, 0x0C },\r
+    { 0x5A, 0x0C },\r
+    { 0x5E, 0x0C },\r
+    { 0x62, 0x0C },\r
+    { 0x37, 0x09 },\r
+    { 0x3B, 0x09 },        \r
+    { 0x47, 0x07 },\r
+    { 0x4B, 0x07 },\r
+    { 0x4F, 0x07 },\r
+    { 0x53, 0x07 },\r
+    { 0x57, 0x07 },\r
+    { 0x5B, 0x07 },\r
+    { 0x5F, 0x07 },\r
+    { 0x63, 0x07 },\r
+    { 0x35, PD_1+PD_2/*0x09*/ },\r
+    { 0x39, PD_3+PD_4/*0x06*/ },\r
+    { 0x45, PD_1+PD_2/*0x09*/ },\r
+    { 0x49, PD_3+PD_4/*0x06*/ },\r
+    { 0x4D, PD_1+PD_2/*0x09*/ },\r
+    { 0x51, PD_3+PD_4/*0x06*/ },\r
+    { 0x55, PD_1+PD_2/*0x09*/ },\r
+    { 0x59, PD_3+PD_4/*0x06*/ },\r
+    { 0x5D, PD_1+PD_2/*0x09*/ },\r
+    { 0x61, PD_3+PD_4/*0x06*/ },\r
+    { 0x38, 0x06 },\r
+    { 0x3C, 0x06 },\r
+    { 0x48, 0x0F },\r
+    { 0x4C, 0x0F },\r
+    { 0x50, 0x0F },\r
+    { 0x54, 0x0F },\r
+    { 0x58, 0x0F },\r
+    { 0x5C, 0x0F },\r
+    { 0x60, 0x0F },\r
+    { 0x64, 0x0F },\r
+    { 0x69, 0x06 },\r
+    { 0x70, 0x06 },   \r
+    { 0x6B, 0x0F },\r
+    { 0x72, 0x0F },\r
+    { 0x6C, 0x0F },\r
+    { 0x73, 0x0F },\r
+    { 0x6D, 0x0F },\r
+    { 0x74, 0x0F },\r
+    { 0x6E, 0x0F },\r
+    { 0x75, 0x0F },\r
+    { 0x7F, 0x00 },\r
+    { 0x18, 0x7F },\r
+#ifndef Ext_LPO_CLK_FROM_GPIO2 \r
+    { 0x03, 0x00 },//Golden report period[7:0] (1T=31.25us)\r
+    { 0x04, 0x05 },//Golden report period[15:8], 25Hz\r
+#else    \r
+    { 0x03, 0x1E },//Golden report period[7:0] (1T=31.25us)\r
+    { 0x04, 0x05 },//Golden report period[15:8], 25Hz\r
+#endif\r
+    { 0x1B, 0x1D },\r
+    { 0x4F, 0x0C },//R_NoTouchDetection_Count_Th[4:0]\r
+    { 0x50, 0x12 },\r
+    { 0x52, 0x12 },\r
+    { 0x53, 0x05 },\r
+    { 0x70, 0x12 },\r
+    { 0x71, 0x05 },\r
+    { 0x68, 0x03 },\r
+\r
+};\r
+\r
+//PAH831X_REG_PPG_7 : 100HZ 1CH_1PPG G 150K\r
+#define PAH831X_REG_PPG_7_ODR (100)\r
+static const uint8_t PAH831X_REG_PPG_7[][2] = {\r
+    { 0x7F, 0x03 },\r
+    { 0x0B, 0x36 },\r
+#ifndef Ext_LPO_CLK_FROM_GPIO2   \r
+    { 0x59 , 0x0C }, \r
+    { 0x5B , 0x08 }, \r
+   // { 0x59, 0x08 }, \r
+    { 0x52 , 0x01 }, \r
+#else\r
+    { 0x59 , 0x0C }, \r
+    { 0x5B , 0x08 }, \r
+    { 0x52 , 0x00 }, \r
+    { 0x5A , 0x04 }, \r
+    { 0x54 , 0x14 }, \r
+    { 0x54 , 0x16 }, \r
+#endif\r
+    { 0x0B, 0x37 },\r
+    { 0x7F, 0x04 },\r
+    { 0x12, 0x81 },\r
+    { 0x28, 0x81 },\r
+    { 0x13, LED_IR1+LED_IR2/*0x09*/ },\r
+    { 0x29, LED_IR1+LED_IR2/*0x09*/ },\r
+    { 0x14, 0x20 },\r
+    { 0x2A, 0x20 },\r
+    { 0x7F, 0x00 },\r
+    { 0x4B, 0x0C },//R_TouchDetection_Th_Hi[15:8]   3168\r
+    { 0x4D, 0x06 },//R_TouchDetection_Th_Low[15:8]  1568\r
+    { 0x7F, 0x04 },\r
+    { 0x01, LED_GREEN_1+LED_GREEN_2/*0x24*/ },\r
+    { 0x04, LED_R1+LED_R2/*0x12*/ },\r
+    { 0x07, LED_IR1+LED_IR2/*0x09*/ },\r
+    { 0x17, LED_GREEN_1+LED_GREEN_2/*0x24*/ },\r
+    { 0x1A, LED_R1+LED_R2/*0x12*/ },\r
+    { 0x1D, LED_IR1+LED_IR2/*0x09*/ },\r
+    { 0x7F, 0x01 },\r
+    { 0x65, PD_2+PD_3/*0x05*/ },\r
+    { 0x04, 0x40 },\r
+    { 0x05, 0x00 },\r
+    { 0x0B, 0x0C },//(disable ECG BG/PMU block)\r
+    { 0x36, 0x05 },\r
+    { 0x3A, 0x05 },\r
+    { 0x3E, 0x0C },\r
+    { 0x42, 0x0C },\r
+    { 0x46, 0x0C },\r
+    { 0x4A, 0x0C },\r
+    { 0x37, 0x09 },\r
+    { 0x3B, 0x09 },\r
+    { 0x3F, 0x07 },\r
+    { 0x43, 0x07 },\r
+    { 0x47, 0x07 },\r
+    { 0x4B, 0x07 },\r
+    { 0x35, PD_1+PD_2+PD_3+PD_4/*0x0F*/ },\r
+    { 0x39, 0x10 },\r
+    { 0x3D, PD_2+PD_3/*0x05*/ },\r
+    { 0x41, PD_1+PD_4/*0x0A*/ },\r
+    { 0x45, PD_2+PD_3/*0x05*/ },\r
+    { 0x49, PD_1+PD_4/*0x0A*/ },\r
+    { 0x38, 0x06 },\r
+    { 0x3C, 0x06 },\r
+    { 0x40, 0x0F },\r
+    { 0x44, 0x0F },\r
+    { 0x48, 0x0F },\r
+    { 0x4C, 0x0F },\r
+    { 0x69, 0x06 },\r
+    { 0x70, 0x06 },\r
+    { 0x6A, 0x0F },\r
+    { 0x71, 0x0F },\r
+    { 0x6B, 0x0F },\r
+    { 0x72, 0x0F },\r
+    { 0x7F, 0x00 },\r
+    { 0x18, 0x7F },\r
+#ifndef Ext_LPO_CLK_FROM_GPIO2 \r
+    { 0x03, 0x40 },//Golden report period[7:0] (1T=31.25us)\r
+    { 0x04, 0x01 },//Golden report period[15:8], 25Hz\r
+#else    \r
+    { 0x03, 0x47 },//Golden report period[7:0] (1T=31.25us)\r
+    { 0x04, 0x01 },//Golden report period[15:8], 25Hz\r
+#endif\r
+    { 0x4F, 0x09 },//R_NoTouchDetection_Count_Th[4:0]\r
+    { 0x1B, 0x11 },\r
+    { 0x50, 0x05 },\r
+//    { 0x51, 0x17 },\r
+//    { 0x52, 0x17 },\r
+    { 0x68, 0x00 },\r
+ \r
+};\r
+\r
+//PAH831X_REG_PPG_8 : 50HZ 1CH_1PPG G 150K\r
+#define PAH831X_REG_PPG_8_ODR (50)\r
+static const uint8_t PAH831X_REG_PPG_8[][2] = {\r
+    { 0x7F, 0x03 },\r
+    { 0x0B, 0x36 },\r
+#ifndef Ext_LPO_CLK_FROM_GPIO2   \r
+    { 0x59 , 0x0C }, \r
+    { 0x5B , 0x08 }, \r
+   // { 0x59, 0x08 }, \r
+    { 0x52 , 0x01 }, \r
+#else\r
+    { 0x59 , 0x0C }, \r
+    { 0x5B , 0x08 }, \r
+    { 0x52 , 0x00 }, \r
+    { 0x5A , 0x04 }, \r
+    { 0x54 , 0x14 }, \r
+    { 0x54 , 0x16 }, \r
+#endif\r
+    { 0x0B, 0x37 },\r
+    { 0x7F, 0x04 },\r
+    { 0x12, 0x81 },\r
+    { 0x28, 0x81 },\r
+    { 0x13, LED_IR1+LED_IR2/*0x09*/ },\r
+    { 0x29, LED_IR1+LED_IR2/*0x09*/ },\r
+    { 0x14, 0x20 },\r
+    { 0x2A, 0x20 },\r
+    { 0x7F, 0x00 },\r
+    { 0x4B, 0x0C },//R_TouchDetection_Th_Hi[15:8]   3168\r
+    { 0x4D, 0x06 },//R_TouchDetection_Th_Low[15:8]  1568\r
+    { 0x7F, 0x04 },\r
+    { 0x01, LED_GREEN_1+LED_GREEN_2/*0x24*/ },\r
+    { 0x04, LED_R1+LED_R2/*0x12*/ },\r
+    { 0x07, LED_IR1+LED_IR2/*0x09*/ },\r
+    { 0x17, LED_GREEN_1+LED_GREEN_2/*0x24*/ },\r
+    { 0x1A, LED_R1+LED_R2/*0x12*/ },\r
+    { 0x1D, LED_IR1+LED_IR2/*0x09*/ },\r
+    { 0x7F, 0x01 },\r
+    { 0x65, PD_2+PD_3/*0x05*/ },\r
+    { 0x04, 0x40 },\r
+    { 0x05, 0x00 },\r
+    { 0x0B, 0x0C },//(disable ECG BG/PMU block)\r
+    { 0x36, 0x05 },\r
+    { 0x3A, 0x05 },\r
+    { 0x3E, 0x0C },\r
+    { 0x42, 0x0C },\r
+    { 0x46, 0x0C },\r
+    { 0x4A, 0x0C },\r
+    { 0x37, 0x09 },\r
+    { 0x3B, 0x09 },\r
+    { 0x3F, 0x07 },\r
+    { 0x43, 0x07 },\r
+    { 0x47, 0x07 },\r
+    { 0x4B, 0x07 },\r
+    { 0x35, PD_1+PD_2+PD_3+PD_4/*0x0F*/ },\r
+    { 0x39, 0x10 },\r
+    { 0x3D, PD_2+PD_3/*0x05*/ },\r
+    { 0x41, PD_1+PD_4/*0x0A*/ },\r
+    { 0x45, PD_2+PD_3/*0x05*/ },\r
+    { 0x49, PD_1+PD_4/*0x0A*/ },\r
+    { 0x38, 0x06 },\r
+    { 0x3C, 0x06 },\r
+    { 0x40, 0x0F },\r
+    { 0x44, 0x0F },\r
+    { 0x48, 0x0F },\r
+    { 0x4C, 0x0F },\r
+    { 0x69, 0x06 },\r
+    { 0x70, 0x06 },\r
+    { 0x6A, 0x0F },\r
+    { 0x71, 0x0F },\r
+    { 0x6B, 0x0F },\r
+    { 0x72, 0x0F },\r
+    { 0x7F, 0x00 },\r
+    { 0x18, 0x7F },\r
+#ifndef Ext_LPO_CLK_FROM_GPIO2 \r
+    { 0x03, 0x80 },//Golden report period[7:0] (1T=31.25us)\r
+    { 0x04, 0x02 },//Golden report period[15:8], 25Hz\r
+#else    \r
+    { 0x03, 0x8F },//Golden report period[7:0] (1T=31.25us)\r
+    { 0x04, 0x02 },//Golden report period[15:8], 25Hz\r
+#endif\r
+    { 0x4F, 0x09 },//R_NoTouchDetection_Count_Th[4:0]\r
+    { 0x1B, 0x11 },\r
+    { 0x50, 0x05 },\r
+//    { 0x51, 0x17 },\r
+//    { 0x52, 0x17 },\r
+    { 0x68, 0x00 },\r
+\r
+};\r
+\r
+\r
+\r
+#define PAH831X_REG_PPG_9_ODR (25)\r
+static const uint8_t PAH831X_REG_PPG_9[][2] = {\r
+    { 0x7F, 0x05 },\r
+ \r
+};\r
+\r
+\r
+#define PAH831X_REG_PPG_10_ODR (25)\r
+static const uint8_t PAH831X_REG_PPG_10[][2] = {\r
+   { 0x7F, 0x03 },\r
+ \r
+};\r
+\r
+\r
+#define PAH831X_REG_ECG_1_ODR (300)\r
+static const uint8_t PAH831X_REG_ECG_1[][2] = {\r
+    { 0x7F ,0x03 }, \r
+    { 0x0B ,0x36 }, \r
+#ifndef Ext_LPO_CLK_FROM_GPIO2   \r
+    { 0x59 , 0x0C }, \r
+    { 0x5B , 0x08 }, \r
+   // { 0x59, 0x08 }, \r
+    { 0x52 , 0x01 }, \r
+#else\r
+    { 0x59 , 0x0C }, \r
+    { 0x5B , 0x08 }, \r
+    { 0x52 , 0x00 }, \r
+    { 0x5A , 0x04 }, \r
+    { 0x54 , 0x14 }, \r
+    { 0x54 , 0x16 }, \r
+#endif\r
+    { 0x0B , 0x37 }, \r
+    { 0x7F , 0x05 }, \r
+    { 0x02 , 0x69 },                                                                                                           \r
+    { 0x08 , 0x73 },                                                                                                           \r
+    { 0x0A , 0x50 },                                                                                                           \r
+    { 0x0E , 0x80 },                                                                                                           \r
+    { 0x14 , 0xD0 },                                                                                                           \r
+    { 0x16 , 0x60 },                                                                                                           \r
+    { 0x1A , 0x80 },                                                                                                           \r
+    { 0x20 , 0xD0 },                                                                                                           \r
+    { 0x22 , 0x60 },                                                                                                           \r
+    { 0x26 , 0x80 },                                                                                                           \r
+    { 0x2C , 0xD0 },                                                                                                           \r
+    { 0x2E , 0x60 },                                                                                                           \r
+    { 0x7F , 0x04 }, \r
+    { 0x13 , LED_IR1+LED_IR2/*0x09*/ }, \r
+    { 0x29 , LED_IR1+LED_IR2/*0x09*/ }, \r
+    { 0x14 , 0x45 }, \r
+    { 0x2A , 0x45 }, \r
+    { 0x01 , LED_GREEN_1+LED_GREEN_2/*0x0C*/ }, \r
+    { 0x04 , LED_R1+LED_R2/*0x12*/ }, \r
+    { 0x07 , LED_IR1+LED_IR2/*0x09*/ }, \r
+    { 0x0A , 0x00 }, \r
+    { 0x17 , LED_GREEN_1+LED_GREEN_2/*0x0C*/ }, \r
+    { 0x1A , LED_R1+LED_R2/*0x12*/ }, \r
+    { 0x1D , LED_IR1+LED_IR2/*0x09*/ }, \r
+    { 0x20 , 0x00 }, \r
+    { 0x34 , 0x01 }, //R_ChD_LED_dac1_max[7:0]                                                                                                                                 \r
+    { 0x7F , 0x01 }, \r
+    { 0x65 , PD_2+PD_3/*0x05*/ }, \r
+    { 0x04 , 0x40 }, \r
+    { 0x05 , 0x00 }, \r
+    { 0x36 , 0x00 }, \r
+    { 0x3A , 0x00 }, \r
+    { 0x3E , 0x05 }, \r
+    { 0x42 , 0x05 }, \r
+    { 0x46 , 0x05 }, \r
+    { 0x4A , 0x05 }, \r
+    { 0x4E , 0x0C }, \r
+    { 0x52 , 0x0C }, \r
+    { 0x37 , 0x0F }, \r
+    { 0x3B , 0x0F }, \r
+    { 0x3F , 0x09 }, \r
+    { 0x43 , 0x09 }, \r
+    { 0x47 , 0x09 }, \r
+    { 0x4B , 0x09 }, \r
+    { 0x4F , 0x07 }, \r
+    { 0x53 , 0x07 }, \r
+    { 0x35 , PD_1+PD_3/*0x05*/ }, \r
+    { 0x39 , PD_2+PD_4/*0x0A*/ }, \r
+    { 0x3D , PD_1+PD_3/*0x05*/ }, \r
+    { 0x41 , PD_2+PD_4/*0x0A*/ }, \r
+    { 0x45 , PD_1+PD_3/*0x05*/ }, \r
+    { 0x49 , PD_2+PD_4/*0x0A*/ }, \r
+    { 0x4D , PD_1+PD_3/*0x05*/ }, \r
+    { 0x51 , PD_2+PD_4/*0x0A*/ }, \r
+    { 0x38 , 0x01 }, \r
+    { 0x3C , 0x01 }, \r
+    { 0x40 , 0x05 }, \r
+    { 0x44 , 0x05 }, \r
+    { 0x48 , 0x05 }, \r
+    { 0x4C , 0x05 }, \r
+    { 0x50 , 0x0F }, \r
+    { 0x54 , 0x0F }, \r
+    { 0x69 , 0x01 }, \r
+    { 0x70 , 0x01 }, \r
+    { 0x6A , 0x05 }, \r
+    { 0x71 , 0x05 }, \r
+    { 0x6B , 0x05 }, \r
+    { 0x72 , 0x05 }, \r
+    { 0x6C , 0x0F }, \r
+    { 0x73 , 0x0F }, \r
+    { 0x7F , 0x00 }, \r
+    { 0x15 , 0x01 }, //RDB_FrameNum_D[6:0]                                                                                                                                     \r
+    { 0x18 , 0x77 }, \r
+    { 0x4B , 0x0C }, //R_TouchDetection_Th_Hi[15:8]   3168\r
+    { 0x4D , 0x06 }, //R_TouchDetection_Th_Low[15:8]\r
+    { 0x4F , 0x0C }, //R_NoTouchDetection_Count_Th[4:0] 1568\r
+    { 0x7F , 0x00 }, \r
+#ifndef Ext_LPO_CLK_FROM_GPIO2 \r
+    { 0x03 , 0x7D }, //Golden report period[7:0] (1T=31.25us)(250Hz)\r
+    { 0x04 , 0x00 }, //{Bit[7:0](Golden report period[15:8])}\r
+#else    \r
+    { 0x03, 0x80 },//Golden report period[7:0] (1T=31.25us)\r
+    { 0x04, 0x00 },//Golden report period[15:8], 25Hz\r
+#endif\r
+    { 0x27 , 0x20 }, //RDB_FrameNum_ECG[7:0]\r
+    { 0x4F , 0x04 }, //R_NoTouchDetection_Count_Th[4:0]\r
+    { 0x24 , 0x08 }, //RDB_ChT_report_divider[7:0]\r
+    { 0x2E , 0x03 }, \r
+    { 0x1B , 0x30 }, \r
+    { 0x68 , 0x00 }, \r
+    { 0x7F , 0x01 }, \r
+    { 0x05 , 0x80 }, \r
+    { 0x06 , 0x02 }, \r
+    { 0x0B , 0x00 }, //(enable PPG and ECG) \r
+    { 0x0D , 0xF2 }, \r
+    { 0x0F , 0x0E }, \r
+    { 0x26 , 0x07 }, \r
+    { 0x7E , 0x02 }, \r
+\r
+};       \r
+ #define PAH831X_REG_ECG_2_ODR (300)\r
+static const uint8_t PAH831X_REG_ECG_2[][2] = {\r
+   { 0x7F ,0x03 }, //Bank3\r
+    { 0x0B ,0x36 }, //{Dummy[1:0], B_PPG1_AMBC_PWRSV_SEL_EnH, B_PPG2_AMBC_PWRSV_SEL_EnH, Dummy, B_BG_PWRSV_SEL_EnH, B_PMU_V2I_PWRSV_SEL_EnH, B_OSC_4M_PWRSV_SEL_EnH}\r
+#ifndef Ext_LPO_CLK_FROM_GPIO2   \r
+    { 0x59 , 0x0C }, //{Dummy[2:0], R_GPIO_1, R_GPIO_1_IEB, R_GPIO_1_OEB, R_GPIO_1_PULLL_EnH, R_GPIO_1_PULLH_EnH}\r
+    { 0x5B , 0x08 }, //{Dummy[2:0], R_GPIO_3, R_GPIO_3_IEB, R_GPIO_3_OEB, R_GPIO_3_PULLL_EnH, R_GPIO_3_PULLH_EnH}\r
+   // { 0x59, 0x08 }, //{Dummy[2:0], R_GPIO_1, R_GPIO_1_IEB, R_GPIO_1_OEB, R_GPIO_1_PULLL_EnH, R_GPIO_1_PULLH_EnH}\r
+    { 0x52 , 0x01 }, //{Dummy[2:0], R_GPIO_2_Open_Drain_EnH, R_GPIO_1_Open_Drain_EnH, R_GPIO_DRV[1:0], R_GPIO_18V_EnL}  \r
+#else\r
+    { 0x59 , 0x0C }, //{Dummy[2:0], R_GPIO_1, R_GPIO_1_IEB, R_GPIO_1_OEB, R_GPIO_1_PULLL_EnH, R_GPIO_1_PULLH_EnH}\r
+    { 0x5B , 0x08 }, //{Dummy[2:0], R_GPIO_3, R_GPIO_3_IEB, R_GPIO_3_OEB, R_GPIO_3_PULLL_EnH, R_GPIO_3_PULLH_EnH}\r
+    { 0x52 , 0x00 }, //{Dummy[2:0], R_GPIO_2_Open_Drain_EnH, R_GPIO_1_Open_Drain_EnH, R_GPIO_DRV[1:0], R_GPIO_18V_EnL}\r
+    { 0x5A , 0x04 }, //{Dummy[2:0], R_GPIO_2, R_GPIO_2_IEB, R_GPIO_2_OEB, R_GPIO_2_PULLL_EnH, R_GPIO_2_PULLH_EnH}\r
+    { 0x54 , 0x14 }, //{Dummy[3:0], R_Ext_CLK_Sel, R_Ext_32K_CLK_Sel, R_Ext_32K_CLK, R_Ext_CLK}\r
+    { 0x54 , 0x16 }, //{Dummy[3:0], R_Ext_CLK_Sel, R_Ext_32K_CLK_Sel, R_Ext_32K_CLK, R_Ext_CLK}\r
+#endif\r
+    { 0x0B , 0x37 }, //{Dummy[1:0], B_PPG1_AMBC_PWRSV_SEL_EnH, B_PPG2_AMBC_PWRSV_SEL_EnH, Dummy, B_BG_PWRSV_SEL_EnH, B_PMU_V2I_PWRSV_SEL_EnH, B_OSC_4M_PWRSV_SEL_EnH}\r
+    { 0x7F , 0x05 }, //Bank5                                                                                                                                                   \r
+    { 0x02 , 0x69 }, //R_ChA_ADC_target[15:8],32768                                                                                                                            \r
+    { 0x08 , 0x73 }, //R_ChA_ACC_lock_out_UB[15:8],53248                                                                                                                       \r
+    { 0x0A , 0x50 }, //R_ChA_ACC_lock_out_LB[15:8],24576                                                                                                                       \r
+    { 0x0E , 0x80 }, //R_ChB_ADC_target[15:8]                                                                                                                                  \r
+    { 0x14 , 0xD0 }, //R_ChB_ACC_lock_out_UB[15:8]                                                                                                                             \r
+    { 0x16 , 0x60 }, //R_ChB_ACC_lock_out_LB[15:8]                                                                                                                             \r
+    { 0x1A , 0x80 }, //R_ChC_ADC_target[15:8]                                                                                                                                  \r
+    { 0x20 , 0xD0 }, //R_ChC_ACC_lock_out_UB[15:8]                                                                                                                             \r
+    { 0x22 , 0x60 }, //R_ChC_ACC_lock_out_LB[15:8]                                                                                                                             \r
+    { 0x26 , 0x80 }, //R_ChD_ADC_target[15:8]                                                                                                                                  \r
+    { 0x2C , 0xD0 }, //R_ChD_ACC_lock_out_UB[15:8]                                                                                                                             \r
+    { 0x2E , 0x60 }, //R_ChD_ACC_lock_out_LB[15:8]                                                                                                                             \r
+    { 0x7F , 0x04 }, //Bank4                                                                                                                                                   \r
+    { 0x13 , LED_IR1+LED_IR2/*0x09*/ }, //B_PPG_ChT_LEDDAC1_CH_SEL[5:0], IR                                                                                                                                                          \r
+    { 0x29 , LED_IR1+LED_IR2/*0x09*/ }, //B_PPG_ChT_LEDDAC2_CH_SEL[5:0], IR                                                                                                                                                          \r
+    { 0x14 , 0x20 }, //B_PPG_ChT_LEDDAC1_CODE[7:0]                                                                                                                                                          \r
+    { 0x2A , 0x20 }, //B_PPG_ChT_LEDDAC2_CODE[7:0]                                                                                                                                                          \r
+    { 0x01 , LED_GREEN_1+LED_GREEN_2/*0x24*/ }, //B_PPG_ChA_LEDDAC1_CH_SEL[5:0]  2G                                                                                                                       \r
+    { 0x04 , 0x00/*0x02*/ }, //B_PPG_ChB_LEDDAC1_CH_SEL[5:0]  R                                                                                                                        \r
+    { 0x07 , 0x00/*0x01*/ }, //B_PPG_ChC_LEDDAC1_CH_SEL[5:0], IR                                                                                                                       \r
+    { 0x0A , 0x00 }, //B_PPG_ChD_LEDDAC1_CH_SEL[5:0], none                                                                                                                     \r
+    { 0x17 , LED_GREEN_1+LED_GREEN_2/*0x24*/ }, //B_PPG_ChA_LEDDAC2_CH_SEL[5:0]  2G                                                                                                                       \r
+    { 0x1A , 0x00/*0x02*/ }, //B_PPG_ChB_LEDDAC2_CH_SEL[5:0]  R                                                                                                                        \r
+    { 0x1D , 0x00/*0x01*/ }, //B_PPG_ChC_LEDDAC2_CH_SEL[5:0], IR                                                                                                                       \r
+    { 0x7F , 0x01 }, //Bank1   \r
+    { 0x65 , PD_2+PD_3/*0x05*/ }, //{B_PPG1_ChT_AMBC_INV_EnH, B_PPG1_ChT_AMBC_LSB_ADJ, B_PPG1_ChT_PD_CH_SEL[4:0]}                                                                                                                                                          \r
+    { 0x04 , 0x40 }, //{T_OSC_32K_RANGE[1:0], T_OSC_4M_EnL, T_PPG1_TIA_EnL, T_PPG1_AMBC_EnL, Dummy, T_PPG1_ADC_EnL, T_PPG2_TIA_EnL}                                            \r
+    { 0x05 , 0x00 }, //{T_PPG2_AMBC_EnL, T_PPG2_ADC_EnL, T_PPG_LEDDAC2_EnL, T_PPG_LEDDAC1_EnL, T_ECG_FE_INA_EnL, T_ECG_ADC_EnL, T_ECG_FE_LOD_CMP_EnL, T_ECG_FE_LOD_I_EnL}                                                                                                                                   \r
+    { 0x36 , 0x05 }, //B_PPG1_ChA_TIA_CF_ADJ[6:0]                                                                                                                              \r
+    { 0x3A , 0x05 }, //B_PPG2_ChA_TIA_CF_ADJ[6:0]                                                                                                                              \r
+    { 0x3E , 0x0C }, //B_PPG1_ChB_TIA_CF_ADJ[6:0]                                                                                                                              \r
+    { 0x42 , 0x0C }, //B_PPG2_ChB_TIA_CF_ADJ[6:0]                                                                                                                              \r
+    { 0x46 , 0x0C }, //B_PPG1_ChC_TIA_CF_ADJ[6:0]                                                                                                                              \r
+    { 0x4A , 0x0C }, //B_PPG2_ChC_TIA_CF_ADJ[6:0]                                                                                                                              \r
+    { 0x4E , 0x0C }, //B_PPG1_ChD_TIA_CF_ADJ[6:0]                                                                                                                              \r
+    { 0x52 , 0x0C }, //B_PPG2_ChD_TIA_CF_ADJ[6:0]                                                                                                                              \r
+    { 0x37 , 0x09 }, //B_PPG1_ChA_TIA_RF_ADJ[3:0],350k                                                                                                                         \r
+    { 0x3B , 0x09 }, //B_PPG2_ChA_TIA_RF_ADJ[3:0],350k                                                                                                                         \r
+    { 0x3F , 0x07 }, //B_PPG1_ChB_TIA_RF_ADJ[3:0],150k                                                                                                                               \r
+    { 0x43 , 0x07 }, //B_PPG2_ChB_TIA_RF_ADJ[3:0],150k                                                                                                                                \r
+    { 0x47 , 0x07 }, //B_PPG1_ChC_TIA_RF_ADJ[3:0],150k                                                                                                                                \r
+    { 0x4B , 0x07 }, //B_PPG2_ChC_TIA_RF_ADJ[3:0],150k                                                                                                                                \r
+    { 0x4F , 0x07 }, //B_PPG1_ChD_TIA_RF_ADJ[3:0]                                                                                                                              \r
+    { 0x53 , 0x07 }, //B_PPG2_ChD_TIA_RF_ADJ[3:0]                                                                                                                              \r
+    { 0x35 , PD_2+PD_3/*0x05*/ }, //{B_PPG1_ChA_AMBC_INV_EnH, B_PPG1_ChA_AMBC_LSB_ADJ, B_PPG1_ChA_PD_CH_SEL[4:0]}                                                                           \r
+    { 0x39 , PD_1+PD_4/*0x0A*/ }, //{B_PPG2_ChA_AMBC_INV_EnH, B_PPG2_ChA_AMBC_LSB_ADJ, B_PPG2_ChA_PD_CH_SEL[4:0]}                                                                           \r
+    { 0x3D , PD_2+PD_3/*0x05*/ }, //{B_PPG1_ChB_AMBC_INV_EnH, B_PPG1_ChB_AMBC_LSB_ADJ, B_PPG1_ChB_PD_CH_SEL[4:0]}                                                                           \r
+    { 0x41 , PD_1+PD_4/*0x0A*/ }, //{B_PPG2_ChB_AMBC_INV_EnH, B_PPG2_ChB_AMBC_LSB_ADJ, B_PPG2_ChB_PD_CH_SEL[4:0]}                                                                           \r
+    { 0x45 , PD_2+PD_3/*0x05*/ }, //{B_PPG1_ChC_AMBC_INV_EnH, B_PPG1_ChC_AMBC_LSB_ADJ, B_PPG1_ChC_PD_CH_SEL[4:0]}                                                                           \r
+    { 0x49 , PD_1+PD_4/*0x0A*/ }, //{B_PPG2_ChC_AMBC_INV_EnH, B_PPG2_ChC_AMBC_LSB_ADJ, B_PPG2_ChC_PD_CH_SEL[4:0]}                                                                           \r
+    { 0x4D , PD_2+PD_3/*0x05*/ }, //{B_PPG1_ChD_AMBC_INV_EnH, B_PPG1_ChD_AMBC_LSB_ADJ, B_PPG1_ChD_PD_CH_SEL[4:0]}                                                                           \r
+    { 0x51 , PD_1+PD_4/*0x0A*/ }, //{B_PPG2_ChD_AMBC_INV_EnH, B_PPG2_ChD_AMBC_LSB_ADJ, B_PPG2_ChD_PD_CH_SEL[4:0]}                                                                           \r
+    { 0x38 , 0x06 }, //B_PPG1_ChA_ON_AMBC_ADJ[7:0]                                                                                                                             \r
+    { 0x3C , 0x06 }, //B_PPG2_ChA_ON_AMBC_ADJ[7:0]                                                                                                                             \r
+    { 0x40 , 0x05 }, //B_PPG1_ChB_ON_AMBC_ADJ[7:0]                                                                                                                             \r
+    { 0x44 , 0x05 }, //B_PPG2_ChB_ON_AMBC_ADJ[7:0]                                                                                                                             \r
+    { 0x48 , 0x05 }, //B_PPG1_ChC_ON_AMBC_ADJ[7:0]                                                                                                                             \r
+    { 0x4C , 0x05 }, //B_PPG2_ChC_ON_AMBC_ADJ[7:0]                                                                                                                             \r
+    { 0x50 , 0x0F }, //B_PPG1_ChD_ON_AMBC_ADJ[7:0]                                                                                                                             \r
+    { 0x54 , 0x0F }, //B_PPG2_ChD_ON_AMBC_ADJ[7:0]                                                                                                                             \r
+    { 0x69 , 0x06 }, //B_PPG1_ChA_OFF_AMBC_ADJ[7:0]                                                                                                                            \r
+    { 0x70 , 0x06 }, //B_PPG2_ChA_OFF_AMBC_ADJ[7:0]                                                                                                                            \r
+    { 0x6A , 0x05 }, //B_PPG1_ChB_OFF_AMBC_ADJ[7:0]                                                                                                                            \r
+    { 0x71 , 0x05 }, //B_PPG2_ChB_OFF_AMBC_ADJ[7:0]                                                                                                                            \r
+    { 0x6B , 0x05 }, //B_PPG1_ChC_OFF_AMBC_ADJ[7:0]                                                                                                                            \r
+    { 0x72 , 0x05 }, //B_PPG2_ChC_OFF_AMBC_ADJ[7:0]                                                                                                                            \r
+    { 0x6C , 0x0F }, //B_PPG1_ChD_OFF_AMBC_ADJ[7:0]                                                                                                                            \r
+    { 0x73 , 0x0F }, //B_PPG2_ChD_OFF_AMBC_ADJ[7:0]                                                                                                                            \r
+    { 0x7F , 0x00 }, //Bank0                                                                                                                                                                                                                                                                                  \r
+    { 0x18 , 0x7F }, //{RDB_OffOnOff_F_EnH, RDB_OffOnOff_E_EnH, RDB_OffOnOff_T_EnH, RDB_OffOnOff_F_EnH, RDB_OffOnOff_E_EnH, RDB_OffOnOff_D_EnH, RDB_OffOnOff_C_EnH, RDB_OffOnOff_B_EnH, RDB_OffOnOff_A_EnH}                                                                                                                                    \r
+    { 0x4B , 0x0C }, //R_TouchDetection_Th_Hi[15:8]   3168\r
+    { 0x4D , 0x06 }, //R_TouchDetection_Th_Low[15:8]\r
+    { 0x4F , 0x0C }, //R_NoTouchDetection_Count_Th[4:0] 1568\r
+    { 0x7F , 0x00 }, //Bank0\r
+#ifndef Ext_LPO_CLK_FROM_GPIO2 \r
+    { 0x03 , 0x7D }, //Golden report period[7:0] (1T=31.25us)(250Hz)\r
+    { 0x04 , 0x00 }, //{Bit[7:0](Golden report period[15:8])}\r
+#else    \r
+    { 0x03, 0x80 },//Golden report period[7:0] (1T=31.25us)\r
+    { 0x04, 0x00 },//Golden report period[15:8], 25Hz\r
+#endif\r
+    { 0x12 , 0x20 }, //RDB_FrameNum_A[6:0]          \r
+    { 0x27 , 0x20 }, //RDB_FrameNum_ECG[7:0]\r
+    { 0x4F , 0x04 }, //R_NoTouchDetection_Count_Th[4:0]\r
+    { 0x24 , 0x08 }, //RDB_ChT_report_divider[7:0]\r
+    { 0x2E , 0x03 }, //{fp_lpf_mask_cnt[7:4], Reserved[3], fp_lpf_sel[2:1](0:128/1:256/2:512/3:1024Hz), fp_lpf_enh[0]}\r
+    { 0x1B , 0x21 }, //{Reserved[7], RDB_LOD_EnH[6], RDB_ECG_EnH[5], RDB_ChT_EnH[4], RDB_ChD_EnH[3], RDB_ChC_EnH[2], RDB_ChB_EnH[1], RDB_ChA_EnH[0]}\r
+    { 0x50 , 0x05 },//{1'b0, R_PPG_FIFO_Write_skip_A_EnH, R_AGC_DAC_TIA_A_EnH[1:0], R_AGC_PPG2_A_Sel, R_AGC_PPG1_A_Sel, R_PPG2_A_EnH, R_PPG1_A_EnH};\r
+    { 0x68 , 0x00 }, //{Dummy[5:0], RDB_ChF_EnH, RDB_ChE_EnH}; \r
+    { 0x7F , 0x01 }, //Bank1\r
+    { 0x05 , 0x00 }, //{T_PPG2_AMBC_EnL, T_PPG2_ADC_EnL, T_PPG_LEDDAC2_EnL, T_PPG_LEDDAC1_EnL, T_ECG_FE_INA_EnL, T_ECG_ADC_EnL, T_ECG_FE_LOD_CMP_EnL, T_ECG_FE_LOD_I_EnL}\r
+    { 0x06 , 0x01 }, //{T_ECG_FE_LOD_GATE_INACHOP_EnH, T_ECG_FE_I_GATED_INA_EnH, T_ECG_PGA_TEST_EnH, T_ECG_FE_LOD_RLDCMP_EnL, T_ECG_FE_VCMBUF_EnL, T_ECG_FE_INA_HPF_SHORT, T_ECG_POLAR_FLIP_EnH, Dummy}\r
+    { 0x0B , 0x00 }, //(enable PPG and ECG) \r
+    { 0x0D , 0xF2 }, //{B_PPG_LEDDAC2_PWRSV_SEL_EnH, B_PPG_LEDDAC1_PWRSV_SEL_EnH, B_ECG_FE_INA_PWRSV_SEL_EnH, B_ECG_ADC_PWRSV_SEL_EnH, B_ECG_FE_LOD_CMP_PWRSV_SEL_EnH, B_ECG_FE_LOD_I_PWRSV_SEL_EnH, B_ECG_FE_RLD_PWRSV_SEL_EnH, B_ECG_FE_LOD_RLDCMP_PWRSV_SEL_EnH} \r
+    { 0x0F , 0x0E }, //{B_ECG_VCMBUF_OFF[3:0], B_ECG_FE_VCMBUF_PWRSV_SEL_EnH, B_ECG_FE_PGA_PWRSV_SEL_EnH, B_ECG_FE_BUF_PWRSV_SEL_EnH, B_ECG_FE_INA_LPF_FAST_SEL_EnH}\r
+    { 0x26 , 0x07 }, //{T_ECG_RF_PGA_ADJ[2:0], Dummy, T_ECG_PGA_LPF_1M_EN, T_ECG_FE_RLD2VCMBUF_EnH, T_ECG_FE_INA_GAIN[1:0]} \r
+    { 0x7E , 0x02 }, //{Dummy[4:0], B_ECG_FAST_RECOVERY_MODE, B_FAST_RECOVERY_EN, TS_ECG_FAST_RECOVERY_EnH}  \r
+ \r
+};\r
+\r
+//for LOD \r
+#define PAH831X_REG_ECG_3_ODR (300)\r
+static const uint8_t PAH831X_REG_ECG_3[][2] = {\r
+    { 0x7F ,0x03 }, \r
+    { 0x0B ,0x36 }, \r
+#ifndef Ext_LPO_CLK_FROM_GPIO2   \r
+    { 0x59 , 0x0C }, \r
+    { 0x5B , 0x08 }, \r
+   // { 0x59, 0x08 }, \r
+    { 0x52 , 0x01 }, \r
+#else\r
+    { 0x59 , 0x0C }, \r
+    { 0x5B , 0x08 }, \r
+    { 0x52 , 0x00 }, \r
+    { 0x5A , 0x04 }, \r
+    { 0x54 , 0x14 }, \r
+    { 0x54 , 0x16 }, \r
+#endif\r
+    { 0x0B , 0x37 }, \r
+    { 0x7F , 0x05 }, \r
+    { 0x02 , 0x69 },                                                                                                           \r
+    { 0x08 , 0x73 },                                                                                                           \r
+    { 0x0A , 0x50 },                                                                                                           \r
+    { 0x0E , 0x80 },                                                                                                           \r
+    { 0x14 , 0xD0 },                                                                                                           \r
+    { 0x16 , 0x60 },                                                                                                           \r
+    { 0x1A , 0x80 },                                                                                                           \r
+    { 0x20 , 0xD0 },                                                                                                           \r
+    { 0x22 , 0x60 },                                                                                                           \r
+    { 0x26 , 0x80 },                                                                                                           \r
+    { 0x2C , 0xD0 },                                                                                                           \r
+    { 0x2E , 0x60 },                                                                                                           \r
+    { 0x7F , 0x04 }, \r
+    { 0x13 , LED_IR1+LED_IR2/*0x09*/ }, \r
+    { 0x29 , LED_IR1+LED_IR2/*0x09*/ }, \r
+    { 0x14 , 0x45 }, \r
+    { 0x2A , 0x45 }, \r
+    { 0x01 , LED_GREEN_1+LED_GREEN_2/*0x0C*/ }, \r
+    { 0x04 , LED_R1+LED_R2/*0x12*/ }, \r
+    { 0x07 , LED_IR1+LED_IR2/*0x09*/ }, \r
+    { 0x0A , 0x00 }, \r
+    { 0x17 , LED_GREEN_1+LED_GREEN_2/*0x0C*/ }, \r
+    { 0x1A , LED_R1+LED_R2/*0x12*/ }, \r
+    { 0x1D , LED_IR1+LED_IR2/*0x09*/ }, \r
+    { 0x20 , 0x00 }, \r
+    { 0x34 , 0x01 }, //R_ChD_LED_dac1_max[7:0]                                                                                                                                 \r
+    { 0x7F , 0x01 }, \r
+    { 0x65 , PD_2+PD_3/*0x05*/ }, \r
+    { 0x04 , 0x40 }, \r
+    { 0x05 , 0x00 }, \r
+    { 0x36 , 0x00 }, \r
+    { 0x3A , 0x00 }, \r
+    { 0x3E , 0x05 }, \r
+    { 0x42 , 0x05 }, \r
+    { 0x46 , 0x05 }, \r
+    { 0x4A , 0x05 }, \r
+    { 0x4E , 0x0C }, \r
+    { 0x52 , 0x0C }, \r
+    { 0x37 , 0x0F }, \r
+    { 0x3B , 0x0F }, \r
+    { 0x3F , 0x09 }, \r
+    { 0x43 , 0x09 }, \r
+    { 0x47 , 0x09 }, \r
+    { 0x4B , 0x09 }, \r
+    { 0x4F , 0x07 }, \r
+    { 0x53 , 0x07 }, \r
+    { 0x35 , PD_1+PD_3/*0x05*/ }, \r
+    { 0x39 , PD_2+PD_4/*0x0A*/ }, \r
+    { 0x3D , PD_1+PD_3/*0x05*/ }, \r
+    { 0x41 , PD_2+PD_4/*0x0A*/ }, \r
+    { 0x45 , PD_1+PD_3/*0x05*/ }, \r
+    { 0x49 , PD_2+PD_4/*0x0A*/ }, \r
+    { 0x4D , PD_1+PD_3/*0x05*/ }, \r
+    { 0x51 , PD_2+PD_4/*0x0A*/ }, \r
+    { 0x38 , 0x01 }, \r
+    { 0x3C , 0x01 }, \r
+    { 0x40 , 0x05 }, \r
+    { 0x44 , 0x05 }, \r
+    { 0x48 , 0x05 }, \r
+    { 0x4C , 0x05 }, \r
+    { 0x50 , 0x0F }, \r
+    { 0x54 , 0x0F }, \r
+    { 0x69 , 0x01 }, \r
+    { 0x70 , 0x01 }, \r
+    { 0x6A , 0x05 }, \r
+    { 0x71 , 0x05 }, \r
+    { 0x6B , 0x05 }, \r
+    { 0x72 , 0x05 }, \r
+    { 0x6C , 0x0F }, \r
+    { 0x73 , 0x0F }, \r
+    { 0x7F , 0x00 }, \r
+    { 0x15 , 0x01 }, //RDB_FrameNum_D[6:0]                                                                                                                                     \r
+    { 0x18 , 0x77 }, \r
+    { 0x4B , 0x0C }, //R_TouchDetection_Th_Hi[15:8]   3168\r
+    { 0x4D , 0x06 }, //R_TouchDetection_Th_Low[15:8]\r
+    { 0x4F , 0x0C }, //R_NoTouchDetection_Count_Th[4:0] 1568\r
+    { 0x7F , 0x00 }, \r
+#ifndef Ext_LPO_CLK_FROM_GPIO2 \r
+    { 0x03 , 0x7D }, //Golden report period[7:0] (1T=31.25us)(250Hz)\r
+    { 0x04 , 0x00 }, //{Bit[7:0](Golden report period[15:8])}\r
+#else    \r
+    { 0x03, 0x80 },//Golden report period[7:0] (1T=31.25us)\r
+    { 0x04, 0x00 },//Golden report period[15:8], 25Hz\r
+#endif\r
+    { 0x27 , 0x20 }, //RDB_FrameNum_ECG[7:0]\r
+    { 0x4F , 0x04 }, //R_NoTouchDetection_Count_Th[4:0]\r
+    { 0x24 , 0x08 }, //RDB_ChT_report_divider[7:0]\r
+    { 0x2E , 0x03 }, \r
+    { 0x1B , 0x60 },\r
+    { 0x68 , 0x00 }, \r
+    { 0x7F , 0x01 }, \r
+    { 0x05 , 0x80 }, \r
+    { 0x06 , 0x02 }, \r
+    { 0x0B , 0x00 }, //(enable PPG and ECG) \r
+    { 0x0D , 0xF2 }, \r
+    { 0x0F , 0x0E }, \r
+    { 0x26 , 0x07 }, \r
+    { 0x7E , 0x02 }, \r
+};\r
+#define PAH831X_REG_ECG_4_ODR (300)\r
+static const uint8_t PAH831X_REG_ECG_4[][2] = {\r
+    { 0x7F, 0x01 },\r
+};\r
+#define PAH831X_REG_ECG_5_ODR (300)\r
+static const uint8_t PAH831X_REG_ECG_5[][2] = {\r
+    { 0x7F, 0x01 },\r
+};  \r
+       
\ No newline at end of file
diff --git a/code/sdk/zhihui/drivers/ppg/pah831x/pah_sensor/pah831x_reg_default_note_0109_2LED_20251226.h b/code/sdk/zhihui/drivers/ppg/pah831x/pah_sensor/pah831x_reg_default_note_0109_2LED_20251226.h
new file mode 100644 (file)
index 0000000..40020ca
--- /dev/null
@@ -0,0 +1,1485 @@
+#pragma once \r
+/**\r
+ * Copyright (c) 2022 PixArt Imaging Inc.\r
+ * All Rights Reserved.\r
+ * Confidential and Proprietary - PixArt Imaging Inc.\r
+ **/\r
+#include <stdint.h>\r
+#include "pah831x_config.h"\r
+\r
+static const uint8_t PAH831X_REG_INIT[][2] = {\r
+    { 0x7F, 0x05 },\r
+    { 0x00, 0x3F },\r
+    { 0x01, 0x00 },\r
+    { 0x02, 0x80 },\r
+    { 0x05, 0x00 },\r
+    { 0x06, 0x04 },\r
+    { 0x07, 0x00 },\r
+    { 0x08, 0xD0 },\r
+    { 0x09, 0x00 },\r
+    { 0x0A, 0x60 },\r
+    { 0x0B, 0x17 },\r
+    { 0x0D, 0x00 },\r
+    { 0x0E, 0x80 },\r
+    { 0x11, 0x00 },\r
+    { 0x12, 0x04 },\r
+    { 0x13, 0x00 },\r
+    { 0x14, 0xD0 },\r
+    { 0x15, 0x00 },\r
+    { 0x16, 0x60 },\r
+    { 0x17, 0x17 },\r
+    { 0x19, 0x00 },\r
+    { 0x1A, 0x80 },\r
+    { 0x1D, 0x00 },\r
+    { 0x1E, 0x04 },\r
+    { 0x1F, 0x00 },\r
+    { 0x20, 0xD0 },\r
+    { 0x21, 0x00 },\r
+    { 0x22, 0x60 },\r
+    { 0x23, 0x17 },\r
+    { 0x25, 0x00 },\r
+    { 0x26, 0x80 },\r
+    { 0x29, 0x00 },\r
+    { 0x2A, 0x04 },\r
+    { 0x2B, 0x00 },\r
+    { 0x2C, 0xD0 },\r
+    { 0x2D, 0x00 },\r
+    { 0x2E, 0x60 },\r
+    { 0x2F, 0x17 },\r
+    { 0x31, 0x00 },\r
+    { 0x32, 0x80 },\r
+    { 0x35, 0x00 },\r
+    { 0x36, 0x04 },\r
+    { 0x37, 0x00 },\r
+    { 0x38, 0xD0 },\r
+    { 0x39, 0x00 },\r
+    { 0x3A, 0x60 },\r
+    { 0x3B, 0x17 },\r
+    { 0x3D, 0x00 },\r
+    { 0x3E, 0x80 },\r
+    { 0x41, 0x00 },\r
+    { 0x42, 0x04 },\r
+    { 0x43, 0x00 },\r
+    { 0x44, 0xD0 },\r
+    { 0x45, 0x00 },\r
+    { 0x46, 0x60 },\r
+    { 0x47, 0x17 },\r
+    { 0x7F, 0x04 },\r
+    { 0x13, 0x09 },\r
+    { 0x29, 0x09 },\r
+    { 0x14, 0x20 },\r
+    { 0x2A, 0x20 },\r
+    { 0x00, 0xB1 },\r
+    { 0x03, 0x91 },\r
+    { 0x06, 0x91 },\r
+    { 0x09, 0xB1 },\r
+    { 0x0C, 0xB1 },\r
+    { 0x0F, 0xB1 },\r
+    { 0x12, 0x81 },\r
+    { 0x16, 0xB1 },\r
+    { 0x19, 0x91 },\r
+    { 0x1C, 0x91 },\r
+    { 0x1F, 0xB1 },\r
+    { 0x22, 0xB1 },\r
+    { 0x25, 0xB1 },\r
+    { 0x28, 0x81 },\r
+    { 0x2D, 0x01 },\r
+    { 0x2F, 0x01 },\r
+    { 0x31, 0x01 },\r
+    { 0x33, 0x01 },\r
+    { 0x35, 0x01 },\r
+    { 0x37, 0x01 },\r
+    { 0x01, 0x00 },\r
+    { 0x04, 0x00 },\r
+    { 0x07, 0x00 },\r
+    { 0x0A, 0x00 },\r
+    { 0x0D, 0x00 },\r
+    { 0x10, 0x00 },\r
+    { 0x17, 0x00 },\r
+    { 0x1A, 0x00 },\r
+    { 0x1D, 0x00 },\r
+    { 0x20, 0x00 },\r
+    { 0x23, 0x00 },\r
+    { 0x26, 0x00 },\r
+    { 0x7F, 0x03 },\r
+    { 0x0B, 0x36 },\r
+    { 0x50, 0x22 },\r
+    { 0x52, 0x01 },\r
+    { 0x58, 0x0C },\r
+    { 0x59, 0x08 },\r
+    { 0x5A, 0x0C/*0x08*/ },\r
+    { 0x0B, 0x37 },\r
+    { 0x50, 0x00 },\r
+    { 0x70, 0x10 },\r
+    { 0x7F, 0x02 },\r
+    { 0x4B, 0x00 },\r
+    { 0x4C, 0x00 },\r
+    { 0x7F, 0x01 },\r
+    { 0x00, 0x98 },\r
+    { 0x04, 0x40 },\r
+    { 0x05, 0x00 },\r
+    { 0x06, 0x03 },\r
+    { 0x08, 0x00 },\r
+    { 0x09, 0x33 },\r
+    { 0x0B, 0x00 },\r
+    { 0x0C, 0xBB },\r
+    { 0x0D, 0xFF },\r
+    { 0x0F, 0x0E },\r
+    { 0x1A, 0x20 },\r
+    { 0x20, 0x07 },\r
+    { 0x21, 0x21 },\r
+    { 0x23, 0x95 },\r
+    { 0x26, 0x07 },\r
+    { 0x76, 0x58 },\r
+    { 0x77, 0xA0 },\r
+    { 0x78, 0x0F },\r
+    { 0x79, 0xA0 },\r
+    { 0x7A, 0x0F },\r
+    { 0x7B, 0x80 },\r
+    { 0x7C, 0x3E },\r
+    { 0x7D, 0x77 },\r
+    { 0x7E, 0x02 },\r
+    { 0x34, 0x04 },\r
+    { 0x36, 0x0C },\r
+    { 0x3A, 0x0C },\r
+    { 0x3E, 0x0C },\r
+    { 0x42, 0x0C },\r
+    { 0x46, 0x0C },\r
+    { 0x4A, 0x0C },\r
+    { 0x4E, 0x0C },\r
+    { 0x52, 0x0C },\r
+    { 0x56, 0x0C },\r
+    { 0x5A, 0x0C },\r
+    { 0x5E, 0x0C },\r
+    { 0x62, 0x0C },\r
+    { 0x66, 0x0C },\r
+    { 0x37, 0x07 },\r
+    { 0x3B, 0x07 },\r
+    { 0x3F, 0x07 },\r
+    { 0x43, 0x07 },\r
+    { 0x47, 0x07 },\r
+    { 0x4B, 0x07 },\r
+    { 0x4F, 0x07 },\r
+    { 0x53, 0x07 },\r
+    { 0x57, 0x07 },\r
+    { 0x5B, 0x07 },\r
+    { 0x5F, 0x07 },\r
+    { 0x63, 0x07 },\r
+    { 0x67, 0x07 },\r
+    { 0x68, 0x0F },\r
+    { 0x6F, 0x0F },\r
+    { 0x65, 0x06 },\r
+    { 0x7F, 0x00 },\r
+    { 0x29, 0x01 },\r
+    { 0x2A, 0x00 },\r
+    { 0x2B, 0x01 },\r
+    { 0x2C, 0x00 },\r
+    { 0x27, 0x20 },\r
+    { 0x28, 0x00 },\r
+    { 0x2D, 0x00 },\r
+    { 0x2E, 0x03 },\r
+    { 0x5F, 0x00 },\r
+    { 0x60, 0x00 },\r
+    { 0x46, 0x00 },\r
+    { 0x47, 0x00 },\r
+    { 0x48, 0x00 },\r
+    { 0x35, 0x14 },\r
+    { 0x36, 0x00 },\r
+    { 0x37, 0x00 },\r
+    { 0x5A, 0x02 },\r
+    { 0x5B, 0x02 },\r
+    { 0x12, 0x08 },\r
+    { 0x13, 0x08 },\r
+    { 0x14, 0x08 },\r
+    { 0x15, 0x08 },\r
+    { 0x16, 0x02 },\r
+    { 0x6D, 0x08 },\r
+    { 0x6E, 0x08 },\r
+    { 0x17, 0x00 },\r
+    { 0x18, 0x7F },\r
+    { 0x19, 0x7F },\r
+    { 0x49, 0x01 },\r
+    { 0x4A, 0x60 },\r
+    { 0x4B, 0x6D },\r
+    { 0x4C, 0x20 },\r
+    { 0x4D, 0x4E },\r
+    { 0x4E, 0x00/*0x01*/ },\r
+    { 0x4F, 0x0C },\r
+    { 0x32, 0xFF },\r
+    { 0x5C, 0xFF },\r
+    { 0x54, 0xFF },\r
+    { 0x55, 0xFF },\r
+    { 0x50, 0x17 },\r
+    { 0x51, 0x17 },\r
+    { 0x52, 0x17 },\r
+    { 0x53, 0x17 },\r
+    { 0x70, 0x17 },\r
+    { 0x71, 0x17 },\r
+    { 0x56, 0x01 },\r
+};               \r
+                 \r
+\r
+static const uint8_t PAH831X_REG_DEINIT[][2] = {\r
+    { 0x7F, 0x01 }, \r
+    { 0x00, 0x98 }, \r
+};\r
+\r
+static const uint8_t PAH831X_REG_TOUCH[][2] = {\r
+    { 0x7F, 0x03 },\r
+    { 0x0B, 0x36 },\r
+#ifndef Ext_LPO_CLK_FROM_GPIO2   \r
+    { 0x59 , 0x0C }, \r
+    { 0x5B , 0x08 }, \r
+   // { 0x59, 0x08 }, \r
+    { 0x52 , 0x01 }, \r
+#else\r
+    { 0x59 , 0x0C }, \r
+    { 0x5B , 0x08 }, \r
+    { 0x52 , 0x00 }, \r
+    { 0x5A , 0x04 }, \r
+    { 0x54 , 0x14 }, \r
+    { 0x54 , 0x16 }, \r
+#endif\r
+    { 0x0B, 0x37 },\r
+    { 0x7F, 0x04 },\r
+    { 0x12, 0x81 },\r
+    { 0x28, 0x81 },\r
+    { 0x13, LED_IR1+LED_IR2/*0x09*/ },\r
+    { 0x29, LED_IR1+LED_IR2/*0x09*/ },\r
+    { 0x14, 0x20 },\r
+    { 0x2A, 0x20 },\r
+    { 0x7F, 0x00 },\r
+    { 0x4B, 0x0C },//R_TouchDetection_Th_Hi[15:8]   3168\r
+    { 0x4D, 0x06 },//R_TouchDetection_Th_Low[15:8]  1568\r
+    { 0x7F, 0x01 },\r
+    { 0x65, PD_2+PD_3/*0x05*/ },\r
+    { 0x7F, 0x00 },\r
+    { 0x03, 0x80 },//Golden report period[7:0] (1T=31.25us)\r
+    { 0x04, 0x0C },//Golden report period[15:8], 10Hz\r
+    { 0x4F, 0x04 },//R_NoTouchDetection_Count_Th[4:0]\r
+    { 0x1B, 0x10 },\r
+    { 0x68, 0x00 },\r
+};\r
+//PAH831X_REG_PPG_1 : 20HZ 1CH_2PPG G/G 150K\r
+#define PAH831X_REG_PPG_1_ODR (20)\r
+static const uint8_t PAH831X_REG_PPG_1[][2] = {\r
+    { 0x7F, 0x03 },\r
+    { 0x0B, 0x36 },\r
+#ifndef Ext_LPO_CLK_FROM_GPIO2   \r
+    { 0x59 , 0x0C }, \r
+    { 0x5B , 0x08 }, \r
+   // { 0x59, 0x08 }, \r
+    { 0x52 , 0x01 }, \r
+#else\r
+    { 0x59 , 0x0C }, \r
+    { 0x5B , 0x08 }, \r
+    { 0x52 , 0x00 }, \r
+    { 0x5A , 0x04 }, \r
+    { 0x54 , 0x14 }, \r
+    { 0x54 , 0x16 }, \r
+#endif\r
+    { 0x0B, 0x37 },\r
+    { 0x7F, 0x04 },\r
+    { 0x00, 0xB6 },\r
+    { 0x03, 0x96 },\r
+    { 0x06, 0x96 },\r
+    { 0x09, 0xB6 },\r
+    { 0x0C, 0xB6 },\r
+    { 0x0F, 0xB6 },\r
+    { 0x16, 0xB6 },\r
+    { 0x19, 0x96 },\r
+    { 0x1C, 0x96 },\r
+    { 0x1F, 0xB6 },\r
+    { 0x22, 0xB6 },\r
+    { 0x25, 0xB6 },\r
+    { 0x12, 0x86 },\r
+    { 0x28, 0x86 },\r
+    { 0x13, LED_IR1+LED_IR2/*0x09*/ },\r
+    { 0x29, LED_IR1+LED_IR2/*0x09*/ },\r
+    { 0x14, 0x20 },\r
+    { 0x2A, 0x20 },\r
+    { 0x7F, 0x00 },\r
+    { 0x4B, 0x0C },//R_TouchDetection_Th_Hi[15:8]   3168\r
+    { 0x4D, 0x06 },//R_TouchDetection_Th_Low[15:8]  1568\r
+    { 0x7F, 0x04 },\r
+    { 0x01, LED_GREEN_1+LED_GREEN_2/*0x24*/ },\r
+    { 0x04, LED_R1+LED_R2/*0x12*/ },\r
+    { 0x07, LED_IR1+LED_IR2/*0x09*/ },\r
+    { 0x17, LED_GREEN_1+LED_GREEN_2/*0x24*/ },\r
+    { 0x1A, LED_R1+LED_R2/*0x12*/ },\r
+    { 0x1D, LED_IR1+LED_IR2/*0x09*/ },\r
+    { 0x7F, 0x01 },\r
+    { 0x65, PD_2+PD_3/*0x05*/ },\r
+    { 0x04, 0x40 },\r
+    { 0x05, 0x00 },\r
+    { 0x0B, 0x0C },\r
+    { 0x36, 0x05 },\r
+    { 0x3A, 0x05 },\r
+    { 0x3E, 0x0C },\r
+    { 0x42, 0x0C },\r
+    { 0x46, 0x0C },\r
+    { 0x4A, 0x0C },\r
+    { 0x37, 0x09 },\r
+    { 0x3B, 0x09 },\r
+    { 0x3F, 0x07 },\r
+    { 0x43, 0x07 },\r
+    { 0x47, 0x07 },\r
+    { 0x4B, 0x07 },\r
+    { 0x35, PD_2+PD_3/*0x05*/ },\r
+    { 0x39, PD_1+PD_4/*0x0A*/ },\r
+    { 0x3D, PD_2+PD_3/*0x05*/ },\r
+    { 0x41, PD_1+PD_4/*0x0A*/ },\r
+    { 0x45, PD_2+PD_3/*0x05*/ },\r
+    { 0x49, PD_1+PD_4/*0x0A*/ },\r
+    { 0x38, 0x06 },\r
+    { 0x3C, 0x06 },\r
+    { 0x40, 0x0F },\r
+    { 0x44, 0x0F },\r
+    { 0x48, 0x0F },\r
+    { 0x4C, 0x0F },                                               \r
+    { 0x69, 0x06 },\r
+    { 0x70, 0x06 },\r
+    { 0x6A, 0x0F },\r
+    { 0x71, 0x0F },\r
+    { 0x6B, 0x0F },\r
+    { 0x72, 0x0F },\r
+    { 0x7F, 0x00 },\r
+    { 0x18, 0x7F },\r
+#ifndef Ext_LPO_CLK_FROM_GPIO2 \r
+    { 0x03, 0x40 },//Golden report period[7:0] (1T=31.25us)\r
+    { 0x04, 0x06 },//Golden report period[15:8], 20Hz\r
+#else    \r
+    \r
+    { 0x03, 0x66 },//Golden report period[7:0] (1T=31.25us)\r
+    { 0x04, 0x06 },//Golden report period[15:8], 20Hz\r
+#endif\r
+    { 0x4F, 0x09 },//R_NoTouchDetection_Count_Th[4:0]\r
+    { 0x1B, 0x11 },\r
+    { 0x50, 0x17 },\r
+    { 0x51, 0x17 },\r
+    { 0x52, 0x17 },\r
+    { 0x68, 0x00 },\r
+};\r
+\r
+\r
+//PAH831X_REG_PPG_2 : 25HZ 4CH_1PPG  R1/R2/IR1/IR2 150K\r
+#define PAH831X_REG_PPG_2_ODR (25)\r
+static const uint8_t PAH831X_REG_PPG_2[][2] = {\r
+    { 0x7F, 0x03 },\r
+    { 0x0B, 0x36 },\r
+#ifndef Ext_LPO_CLK_FROM_GPIO2   \r
+    { 0x59 , 0x0C }, \r
+    { 0x5B , 0x08 }, \r
+   // { 0x59, 0x08 }, \r
+    { 0x52 , 0x01 }, \r
+#else\r
+    { 0x59 , 0x0C }, \r
+    { 0x5B , 0x08 }, \r
+    { 0x52 , 0x00 }, \r
+    { 0x5A , 0x04 }, \r
+    { 0x54 , 0x14 }, \r
+    { 0x54 , 0x16 }, \r
+#endif\r
+    { 0x0B, 0x37 },\r
+    { 0x7F, 0x04 },\r
+    { 0x00, 0xB6 },\r
+    { 0x03, 0x96 },\r
+    { 0x06, 0xA6 },\r
+    { 0x09, 0xA6 },\r
+    { 0x0C, 0xA6 },\r
+    { 0x0F, 0xA6 },\r
+    { 0x16, 0xB6 },\r
+    { 0x19, 0x96 },\r
+    { 0x1C, 0xA6 },\r
+    { 0x1F, 0xA6 },\r
+    { 0x22, 0xA6 },\r
+    { 0x25, 0xA6 },\r
+    { 0x12, 0x86 },\r
+    { 0x28, 0x86 },\r
+    { 0x13, LED_IR1+LED_IR2/*0x09*/ },\r
+    { 0x29, LED_IR1+LED_IR2/*0x09*/ },\r
+    { 0x14, 0x20 },\r
+    { 0x2A, 0x20 },\r
+    { 0x7F, 0x00 },\r
+    { 0x4B, 0x0C },//R_TouchDetection_Th_Hi[15:8]   3168\r
+    { 0x4D, 0x06 },//R_TouchDetection_Th_Low[15:8]  1568\r
+    { 0x7F, 0x04 },\r
+    { 0x07, LED_R1/*0x02*/ },\r
+    { 0x0A, LED_R2/*0x10*/ },\r
+    { 0x0D, LED_IR1/*0x01*/ },\r
+    { 0x10, LED_IR2/*0x08*/ },\r
+    { 0x1D, LED_R1/*0x02*/ },\r
+    { 0x20, LED_R2/*0x10*/ },\r
+    { 0x23, LED_IR1/*0x01*/ },\r
+    { 0x26, LED_IR2/*0x08*/ },\r
+    { 0x7F, 0x01 },\r
+    { 0x65, PD_2+PD_3/*0x05*//*0x09*/ },\r
+    { 0x0B, 0x0C },//(enable PPG/ECG BG/PMU block) \r
+    { 0x46, 0x0C },\r
+    { 0x4A, 0x0C },\r
+    { 0x4E, 0x0C },\r
+    { 0x52, 0x0C },\r
+    { 0x56, 0x0C },\r
+    { 0x5A, 0x0C },\r
+    { 0x5E, 0x0C },\r
+    { 0x62, 0x0C },\r
+    { 0x47, 0x07 },\r
+    { 0x4B, 0x07 },\r
+    { 0x4F, 0x07 },\r
+    { 0x53, 0x07 },\r
+    { 0x57, 0x07 },\r
+    { 0x5B, 0x07 },\r
+    { 0x5F, 0x07 },\r
+    { 0x63, 0x07 },\r
+    { 0x45, PD_1+PD_2/*0x09*/ },\r
+    { 0x49, PD_3+PD_4/*0x06*/ },\r
+    { 0x4D, PD_1+PD_2/*0x09*/ },\r
+    { 0x51, PD_3+PD_4/*0x06*/ },\r
+    { 0x55, PD_1+PD_2/*0x09*/ },\r
+    { 0x59, PD_3+PD_4/*0x06*/ },\r
+    { 0x5D, PD_1+PD_2/*0x09*/ },\r
+    { 0x61, PD_3+PD_4/*0x06*/ },\r
+    { 0x48, 0x0F },\r
+    { 0x4C, 0x0F },\r
+    { 0x50, 0x0F },\r
+    { 0x54, 0x0F },\r
+    { 0x58, 0x0F },\r
+    { 0x5C, 0x0F },\r
+    { 0x60, 0x0F },\r
+    { 0x64, 0x0F },\r
+    { 0x6B, 0x0F },\r
+    { 0x72, 0x0F },\r
+    { 0x6C, 0x0F },\r
+    { 0x73, 0x0F },\r
+    { 0x6D, 0x0F },\r
+    { 0x74, 0x0F },\r
+    { 0x6E, 0x0F },\r
+    { 0x75, 0x0F },\r
+    { 0x7F, 0x00 },\r
+    { 0x18, 0x7F },\r
+#ifndef Ext_LPO_CLK_FROM_GPIO2 \r
+    { 0x03, 0x00 },//Golden report period[7:0] (1T=31.25us)\r
+    { 0x04, 0x05 },//Golden report period[15:8], 25Hz\r
+#else    \r
+    { 0x03, 0x1E },//Golden report period[7:0] (1T=31.25us)\r
+    { 0x04, 0x05 },//Golden report period[15:8], 25Hz\r
+#endif\r
+    { 0x1B, 0x1C },\r
+    { 0x4F, 0x0C },//R_NoTouchDetection_Count_Th[4:0]\r
+    { 0x52, 0x12 },\r
+    { 0x53, 0x05 },\r
+    { 0x70, 0x12 },\r
+    { 0x71, 0x05 },\r
+    { 0x68, 0x03 },\r
+};   \r
+\r
+//PAH831X_REG_PPG_3 : 25HZ 1CH_1PPG G\r
+#define PAH831X_REG_PPG_3_ODR (25)\r
+static const uint8_t PAH831X_REG_PPG_3[][2] = {\r
+   { 0x7F, 0x03 },\r
+    { 0x0B, 0x36 },\r
+#ifndef Ext_LPO_CLK_FROM_GPIO2   \r
+    { 0x59 , 0x0C }, \r
+    { 0x5B , 0x08 }, \r
+   // { 0x59, 0x08 }, \r
+    { 0x52 , 0x01 }, \r
+#else\r
+    { 0x59 , 0x0C }, \r
+    { 0x5B , 0x08 }, \r
+    { 0x52 , 0x00 }, \r
+    { 0x5A , 0x04 }, \r
+    { 0x54 , 0x14 }, \r
+    { 0x54 , 0x16 }, \r
+#endif\r
+    { 0x0B, 0x37 },\r
+    { 0x7F, 0x04 },\r
+    { 0x00, 0xB6 },\r
+    { 0x03, 0x96 },\r
+    { 0x06, 0x96 },\r
+    { 0x09, 0xB6 },\r
+    { 0x0C, 0xB6 },\r
+    { 0x0F, 0xB6 },\r
+    { 0x16, 0xB6 },\r
+    { 0x19, 0x96 },\r
+    { 0x1C, 0x96 },\r
+    { 0x1F, 0xB6 },\r
+    { 0x22, 0xB6 },\r
+    { 0x25, 0xB6 },\r
+    { 0x12, 0x86 },\r
+    { 0x28, 0x86 },\r
+    { 0x13, LED_IR1+LED_IR2/*0x09*/ },\r
+    { 0x29, LED_IR1+LED_IR2/*0x09*/ },\r
+    { 0x14, 0x20 },\r
+    { 0x2A, 0x20 },\r
+    { 0x7F, 0x00 },\r
+    { 0x4B, 0x0C },//R_TouchDetection_Th_Hi[15:8]   3168\r
+    { 0x4D, 0x06 },//R_TouchDetection_Th_Low[15:8]  1568\r
+    { 0x7F, 0x04 },\r
+    { 0x01, LED_GREEN_1+LED_GREEN_2/*0x24*/ },\r
+    { 0x04, LED_R1+LED_R2/*0x12*/ },\r
+    { 0x07, LED_IR1+LED_IR2/*0x09*/ },\r
+    { 0x17, LED_GREEN_1+LED_GREEN_2/*0x24*/ },\r
+    { 0x1A, LED_R1+LED_R2/*0x12*/ },\r
+    { 0x1D, LED_IR1+LED_IR2/*0x09*/ },\r
+    { 0x7F, 0x01 },\r
+    { 0x65, PD_2+PD_3/*0x05*/ },\r
+    { 0x04, 0x40 },\r
+    { 0x05, 0x00 },\r
+    { 0x0B, 0x0C },//(disable ECG BG/PMU block)\r
+    { 0x36, 0x05 },\r
+    { 0x3A, 0x05 },\r
+    { 0x3E, 0x0C },\r
+    { 0x42, 0x0C },\r
+    { 0x46, 0x0C },\r
+    { 0x4A, 0x0C },\r
+    { 0x37, 0x09 },\r
+    { 0x3B, 0x09 },\r
+    { 0x3F, 0x07 },\r
+    { 0x43, 0x07 },\r
+    { 0x47, 0x07 },\r
+    { 0x4B, 0x07 },\r
+    { 0x35, PD_1+PD_2+PD_3+PD_4/*0x0F*/ },\r
+    { 0x39, 0x10 },\r
+    { 0x3D, PD_2+PD_3/*0x05*/ },\r
+    { 0x41, PD_1+PD_4/*0x0A*/ },\r
+    { 0x45, PD_2+PD_3/*0x05*/ },\r
+    { 0x49, PD_1+PD_4/*0x0A*/ },\r
+    { 0x38, 0x06 },\r
+    { 0x3C, 0x06 },\r
+    { 0x40, 0x0F },\r
+    { 0x44, 0x0F },\r
+    { 0x48, 0x0F },\r
+    { 0x4C, 0x0F },\r
+    { 0x69, 0x06 },\r
+    { 0x70, 0x06 },\r
+    { 0x6A, 0x0F },\r
+    { 0x71, 0x0F },\r
+    { 0x6B, 0x0F },\r
+    { 0x72, 0x0F },\r
+    { 0x7F, 0x00 },\r
+    { 0x18, 0x7F },\r
+#ifndef Ext_LPO_CLK_FROM_GPIO2 \r
+    { 0x03, 0x00 },//Golden report period[7:0] (1T=31.25us)\r
+    { 0x04, 0x05 },//Golden report period[15:8], 25Hz\r
+#else    \r
+    { 0x03, 0x1E },//Golden report period[7:0] (1T=31.25us)\r
+    { 0x04, 0x05 },//Golden report period[15:8], 25Hz\r
+#endif\r
+    { 0x4F, 0x09 },//R_NoTouchDetection_Count_Th[4:0]\r
+    { 0x1B, 0x11 },\r
+    { 0x50, 0x05 },\r
+//    { 0x51, 0x17 },\r
+//    { 0x52, 0x17 },\r
+    { 0x68, 0x00 },\r
+};\r
+\r
+//PAH831X_REG_PPG_4 : 50HZ 3CH_2PPG G1/G2/R1/R2/IR1/IR2\r
+#define PAH831X_REG_PPG_4_ODR (20)\r
+static const uint8_t PAH831X_REG_PPG_4[][2] = {\r
+     { 0x7F, 0x03 },\r
+    { 0x0B, 0x36 },\r
+#ifndef Ext_LPO_CLK_FROM_GPIO2   \r
+    { 0x59 , 0x0C }, \r
+    { 0x5B , 0x08 }, \r
+   // { 0x59, 0x08 }, \r
+    { 0x52 , 0x01 }, \r
+#else\r
+    { 0x59 , 0x0C }, \r
+    { 0x5B , 0x08 }, \r
+    { 0x52 , 0x00 }, \r
+    { 0x5A , 0x04 }, \r
+    { 0x54 , 0x14 }, \r
+    { 0x54 , 0x16 }, \r
+#endif\r
+    { 0x0B, 0x37 },\r
+    { 0x7F, 0x04 },\r
+    { 0x00, 0xB6 },\r
+    { 0x03, 0x96 },\r
+    { 0x06, 0x96 },\r
+    { 0x09, 0xB6 },\r
+    { 0x0C, 0xB6 },\r
+    { 0x0F, 0xB6 },\r
+    { 0x16, 0xB6 },\r
+    { 0x19, 0x96 },\r
+    { 0x1C, 0x96 },\r
+    { 0x1F, 0xB6 },\r
+    { 0x22, 0xB6 },\r
+    { 0x25, 0xB6 },\r
+    { 0x12, 0x86 },\r
+    { 0x28, 0x86 },\r
+    { 0x13, LED_IR1+LED_IR2/*0x09*/ },\r
+    { 0x29, LED_IR1+LED_IR2/*0x09*/ },\r
+    { 0x14, 0x20 },\r
+    { 0x2A, 0x20 },\r
+    { 0x7F, 0x00 },\r
+    { 0x4B, 0x0C },//R_TouchDetection_Th_Hi[15:8]   3168\r
+    { 0x4D, 0x06 },//R_TouchDetection_Th_Low[15:8]  1568\r
+    { 0x7F, 0x04 },\r
+    { 0x01, LED_GREEN_1+LED_GREEN_2/*0x24*/ },\r
+    { 0x04, LED_R1+LED_R2/*0x12*/ },\r
+    { 0x07, LED_IR1+LED_IR2/*0x09*/ },\r
+    { 0x17, LED_GREEN_1+LED_GREEN_2/*0x24*/ },\r
+    { 0x1A, LED_R1+LED_R2/*0x12*/ },\r
+    { 0x1D, LED_IR1+LED_IR2/*0x09*/ },\r
+    { 0x7F, 0x01 },\r
+    { 0x65, PD_2+PD_3/*0x05*/ },\r
+    { 0x04, 0x40 },\r
+    { 0x05, 0x00 },\r
+    { 0x0B, 0x0C },//(disable ECG BG/PMU block)\r
+    { 0x36, 0x05 },\r
+    { 0x3A, 0x05 },\r
+    { 0x3E, 0x0C },\r
+    { 0x42, 0x0C },\r
+    { 0x46, 0x0C },\r
+    { 0x4A, 0x0C },\r
+    { 0x37, 0x09 },\r
+    { 0x3B, 0x09 },\r
+    { 0x3F, 0x07 },\r
+    { 0x43, 0x07 },\r
+    { 0x47, 0x07 },\r
+    { 0x4B, 0x07 },\r
+    { 0x35, PD_2+PD_3/*0x05*/ },\r
+    { 0x39, PD_1+PD_4/*0x0A*/ },\r
+    { 0x3D, PD_2+PD_3/*0x05*/ },\r
+    { 0x41, PD_1+PD_4/*0x0A*/ },\r
+    { 0x45, PD_2+PD_3/*0x05*/ },\r
+    { 0x49, PD_1+PD_4/*0x0A*/ },\r
+    { 0x38, 0x06 },\r
+    { 0x3C, 0x06 },\r
+    { 0x40, 0x0F },\r
+    { 0x44, 0x0F },\r
+    { 0x48, 0x0F },\r
+    { 0x4C, 0x0F },\r
+    { 0x69, 0x06 },\r
+    { 0x70, 0x06 },\r
+    { 0x6A, 0x0F },\r
+    { 0x71, 0x0F },\r
+    { 0x6B, 0x0F },\r
+    { 0x72, 0x0F },\r
+    { 0x7F, 0x00 },\r
+    { 0x18, 0x7F },\r
+#ifndef Ext_LPO_CLK_FROM_GPIO2\r
+    { 0x03, 0x80 },//Golden report period[7:0] (1T=31.25us)\r
+    { 0x04, 0x02 },//Golden report period[15:8], 50Hz\r
+#else    \r
+    \r
+    { 0x03, 0x8F },//Golden report period[7:0] (1T=31.25us)\r
+    { 0x04, 0x02 },//Golden report period[15:8], 50Hz\r
+#endif\r
+    { 0x4F, 0x16 },//R_NoTouchDetection_Count_Th[4:0]\r
+    { 0x1B, 0x17 },\r
+    { 0x50, 0x17 },\r
+    { 0x51, 0x17 },\r
+    { 0x52, 0x17 },\r
+    { 0x68, 0x00 },\r
+};\r
+\r
+//PAH831X_REG_PPG_5 : 25HZ 3CH_1PPG G/R_FAR/IR_FAR\r
+#define PAH831X_REG_PPG_5_ODR (25)\r
+static const uint8_t PAH831X_REG_PPG_5[][2] = {\r
+   { 0x7F, 0x03 },\r
+    { 0x0B, 0x36 },\r
+#ifndef Ext_LPO_CLK_FROM_GPIO2   \r
+    { 0x59 , 0x0C }, \r
+    { 0x5B , 0x08 }, \r
+   // { 0x59, 0x08 }, \r
+    { 0x52 , 0x01 }, \r
+#else\r
+    { 0x59 , 0x0C }, \r
+    { 0x5B , 0x08 }, \r
+    { 0x52 , 0x00 }, \r
+    { 0x5A , 0x04 }, \r
+    { 0x54 , 0x14 }, \r
+    { 0x54 , 0x16 }, \r
+#endif\r
+    { 0x0B, 0x37 },\r
+    { 0x7F, 0x04 },\r
+    { 0x00, 0xB6 },\r
+    { 0x03, 0x96 },\r
+    { 0x06, 0xA6 },\r
+    { 0x09, 0xA6 },\r
+    { 0x0C, 0xA6 },\r
+    { 0x0F, 0xA6 },\r
+    { 0x16, 0xB6 },\r
+    { 0x19, 0x96 },\r
+    { 0x1C, 0xA6 },\r
+    { 0x1F, 0xA6 },\r
+    { 0x22, 0xA6 },\r
+    { 0x25, 0xA6 },\r
+    { 0x12, 0x86 },\r
+    { 0x28, 0x86 },\r
+    { 0x13, LED_IR1+LED_IR2/*0x09*/ },\r
+    { 0x29, LED_IR1+LED_IR2/*0x09*/ },\r
+    { 0x14, 0x20 },\r
+    { 0x2A, 0x20 },\r
+    { 0x7F, 0x00 },\r
+    { 0x4B, 0x0C },//R_TouchDetection_Th_Hi[15:8]   3168\r
+    { 0x4D, 0x06 },//R_TouchDetection_Th_Low[15:8]  1568\r
+    { 0x7F, 0x04 },\r
+    { 0x01, LED_GREEN_1+LED_GREEN_2/*0x24*/ },\r
+    { 0x07, LED_R1/*0x02*/ },\r
+    { 0x0A, LED_R2/*0x10*/ },\r
+    { 0x0D, LED_IR1/*0x01*/ },\r
+    { 0x10, LED_IR2/*0x08*/ },\r
+    { 0x1D, LED_R1/*0x02*/ },\r
+    { 0x17, LED_GREEN_1+LED_GREEN_2/*0x24*/ },\r
+    { 0x20, LED_R2/*0x10*/ },\r
+    { 0x23, LED_IR1/*0x01*/ },\r
+    { 0x26, LED_IR2/*0x08*/ },\r
+    { 0x7F, 0x01 },\r
+    { 0x65, PD_2+PD_3/*0x05*//*0x09*/ },\r
+    { 0x0B, 0x0C },//(enable PPG/ECG BG/PMU block) \r
+    { 0x36, 0x05 },\r
+    { 0x3A, 0x05 },\r
+    { 0x46, 0x0C },\r
+    { 0x4A, 0x0C },\r
+    { 0x4E, 0x0C },\r
+    { 0x52, 0x0C },\r
+    { 0x56, 0x0C },\r
+    { 0x5A, 0x0C },\r
+    { 0x5E, 0x0C },\r
+    { 0x62, 0x0C },\r
+    { 0x37, 0x09 },\r
+    { 0x3B, 0x09 },        \r
+    { 0x47, 0x07 },\r
+    { 0x4B, 0x07 },\r
+    { 0x4F, 0x07 },\r
+    { 0x53, 0x07 },\r
+    { 0x57, 0x07 },\r
+    { 0x5B, 0x07 },\r
+    { 0x5F, 0x07 },\r
+    { 0x63, 0x07 },\r
+    { 0x35, PD_1+PD_2/*0x09*/ },\r
+    { 0x39, PD_3+PD_4/*0x06*/ },\r
+    { 0x45, PD_1+PD_2/*0x09*/ },\r
+    { 0x49, PD_3+PD_4/*0x06*/ },\r
+    { 0x4D, PD_1+PD_2/*0x09*/ },\r
+    { 0x51, PD_3+PD_4/*0x06*/ },\r
+    { 0x55, PD_1+PD_2/*0x09*/ },\r
+    { 0x59, PD_3+PD_4/*0x06*/ },\r
+    { 0x5D, PD_1+PD_2/*0x09*/ },\r
+    { 0x61, PD_3+PD_4/*0x06*/ },\r
+    { 0x38, 0x06 },\r
+    { 0x3C, 0x06 },\r
+    { 0x48, 0x0F },\r
+    { 0x4C, 0x0F },\r
+    { 0x50, 0x0F },\r
+    { 0x54, 0x0F },\r
+    { 0x58, 0x0F },\r
+    { 0x5C, 0x0F },\r
+    { 0x60, 0x0F },\r
+    { 0x64, 0x0F },\r
+    { 0x69, 0x06 },\r
+    { 0x70, 0x06 },   \r
+    { 0x6B, 0x0F },\r
+    { 0x72, 0x0F },\r
+    { 0x6C, 0x0F },\r
+    { 0x73, 0x0F },\r
+    { 0x6D, 0x0F },\r
+    { 0x74, 0x0F },\r
+    { 0x6E, 0x0F },\r
+    { 0x75, 0x0F },\r
+    { 0x7F, 0x00 },\r
+    { 0x18, 0x7F },\r
+#ifndef Ext_LPO_CLK_FROM_GPIO2 \r
+    { 0x03, 0x00 },//Golden report period[7:0] (1T=31.25us)\r
+    { 0x04, 0x05 },//Golden report period[15:8], 25Hz\r
+#else    \r
+    { 0x03, 0x1E },//Golden report period[7:0] (1T=31.25us)\r
+    { 0x04, 0x05 },//Golden report period[15:8], 25Hz\r
+#endif\r
+    { 0x1B, 0x15 },\r
+    { 0x4F, 0x0C },//R_NoTouchDetection_Count_Th[4:0]\r
+    { 0x50, 0x12 },\r
+    { 0x52, 0x12 },\r
+    { 0x53, 0x05 },\r
+    { 0x70, 0x12 },\r
+    { 0x71, 0x05 },\r
+    { 0x68, 0x01 },\r
+};\r
+\r
+//PAH831X_REG_PPG_6 : 25HZ 5CH_1PPG G/R1_FAR/R2_FAR/IR1_FAR/IR2_FAR\r
+#define PAH831X_REG_PPG_6_ODR (100)\r
+static const uint8_t PAH831X_REG_PPG_6[][2] = {\r
+   { 0x7F, 0x03 },\r
+    { 0x0B, 0x36 },\r
+#ifndef Ext_LPO_CLK_FROM_GPIO2   \r
+    { 0x59 , 0x0C }, \r
+    { 0x5B , 0x08 }, \r
+   // { 0x59, 0x08 }, \r
+    { 0x52 , 0x01 }, \r
+#else\r
+    { 0x59 , 0x0C }, \r
+    { 0x5B , 0x08 }, \r
+    { 0x52 , 0x00 }, \r
+    { 0x5A , 0x04 }, \r
+    { 0x54 , 0x14 }, \r
+    { 0x54 , 0x16 }, \r
+#endif\r
+    { 0x0B, 0x37 },\r
+    { 0x7F, 0x04 },\r
+    { 0x00, 0xB6 },\r
+    { 0x03, 0x96 },\r
+    { 0x06, 0xA6 },\r
+    { 0x09, 0xA6 },\r
+    { 0x0C, 0xA6 },\r
+    { 0x0F, 0xA6 },\r
+    { 0x16, 0xB6 },\r
+    { 0x19, 0x96 },\r
+    { 0x1C, 0xA6 },\r
+    { 0x1F, 0xA6 },\r
+    { 0x22, 0xA6 },\r
+    { 0x25, 0xA6 },\r
+    { 0x12, 0x86 },\r
+    { 0x28, 0x86 },\r
+    { 0x13, LED_IR1+LED_IR2/*0x09*/ },\r
+    { 0x29, LED_IR1+LED_IR2/*0x09*/ },\r
+    { 0x14, 0x20 },\r
+    { 0x2A, 0x20 },\r
+    { 0x7F, 0x00 },\r
+    { 0x4B, 0x0C },//R_TouchDetection_Th_Hi[15:8]   3168\r
+    { 0x4D, 0x06 },//R_TouchDetection_Th_Low[15:8]  1568\r
+    { 0x7F, 0x04 },\r
+    { 0x01, LED_GREEN_1+LED_GREEN_2/*0x24*/ },\r
+    { 0x07, LED_R1/*0x02*/ },\r
+    { 0x0A, LED_R2/*0x10*/ },\r
+    { 0x0D, LED_IR1/*0x01*/ },\r
+    { 0x10, LED_IR2/*0x08*/ },\r
+    { 0x1D, LED_R1/*0x02*/ },\r
+    { 0x17, LED_GREEN_1+LED_GREEN_2/*0x24*/ },\r
+    { 0x20, LED_R2/*0x10*/ },\r
+    { 0x23, LED_IR1/*0x01*/ },\r
+    { 0x26, LED_IR2/*0x08*/ },\r
+    { 0x7F, 0x01 },\r
+    { 0x65, PD_2+PD_3/*0x05*//*0x09*/ },\r
+    { 0x0B, 0x0C },//(enable PPG/ECG BG/PMU block) \r
+    { 0x36, 0x05 },\r
+    { 0x3A, 0x05 },\r
+    { 0x46, 0x0C },\r
+    { 0x4A, 0x0C },\r
+    { 0x4E, 0x0C },\r
+    { 0x52, 0x0C },\r
+    { 0x56, 0x0C },\r
+    { 0x5A, 0x0C },\r
+    { 0x5E, 0x0C },\r
+    { 0x62, 0x0C },\r
+    { 0x37, 0x09 },\r
+    { 0x3B, 0x09 },        \r
+    { 0x47, 0x07 },\r
+    { 0x4B, 0x07 },\r
+    { 0x4F, 0x07 },\r
+    { 0x53, 0x07 },\r
+    { 0x57, 0x07 },\r
+    { 0x5B, 0x07 },\r
+    { 0x5F, 0x07 },\r
+    { 0x63, 0x07 },\r
+    { 0x35, PD_1+PD_2/*0x09*/ },\r
+    { 0x39, PD_3+PD_4/*0x06*/ },\r
+    { 0x45, PD_1+PD_2/*0x09*/ },\r
+    { 0x49, PD_3+PD_4/*0x06*/ },\r
+    { 0x4D, PD_1+PD_2/*0x09*/ },\r
+    { 0x51, PD_3+PD_4/*0x06*/ },\r
+    { 0x55, PD_1+PD_2/*0x09*/ },\r
+    { 0x59, PD_3+PD_4/*0x06*/ },\r
+    { 0x5D, PD_1+PD_2/*0x09*/ },\r
+    { 0x61, PD_3+PD_4/*0x06*/ },\r
+    { 0x38, 0x06 },\r
+    { 0x3C, 0x06 },\r
+    { 0x48, 0x0F },\r
+    { 0x4C, 0x0F },\r
+    { 0x50, 0x0F },\r
+    { 0x54, 0x0F },\r
+    { 0x58, 0x0F },\r
+    { 0x5C, 0x0F },\r
+    { 0x60, 0x0F },\r
+    { 0x64, 0x0F },\r
+    { 0x69, 0x06 },\r
+    { 0x70, 0x06 },   \r
+    { 0x6B, 0x0F },\r
+    { 0x72, 0x0F },\r
+    { 0x6C, 0x0F },\r
+    { 0x73, 0x0F },\r
+    { 0x6D, 0x0F },\r
+    { 0x74, 0x0F },\r
+    { 0x6E, 0x0F },\r
+    { 0x75, 0x0F },\r
+    { 0x7F, 0x00 },\r
+    { 0x18, 0x7F },\r
+#ifndef Ext_LPO_CLK_FROM_GPIO2 \r
+    { 0x03, 0x00 },//Golden report period[7:0] (1T=31.25us)\r
+    { 0x04, 0x05 },//Golden report period[15:8], 25Hz\r
+#else    \r
+    { 0x03, 0x1E },//Golden report period[7:0] (1T=31.25us)\r
+    { 0x04, 0x05 },//Golden report period[15:8], 25Hz\r
+#endif\r
+    { 0x1B, 0x1D },\r
+    { 0x4F, 0x0C },//R_NoTouchDetection_Count_Th[4:0]\r
+    { 0x50, 0x12 },\r
+    { 0x52, 0x12 },\r
+    { 0x53, 0x05 },\r
+    { 0x70, 0x12 },\r
+    { 0x71, 0x05 },\r
+    { 0x68, 0x03 },\r
+\r
+};\r
+\r
+//PAH831X_REG_PPG_7 : 100HZ 1CH_1PPG G 150K\r
+#define PAH831X_REG_PPG_7_ODR (100)\r
+static const uint8_t PAH831X_REG_PPG_7[][2] = {\r
+    { 0x7F, 0x03 },\r
+    { 0x0B, 0x36 },\r
+#ifndef Ext_LPO_CLK_FROM_GPIO2   \r
+    { 0x59 , 0x0C }, \r
+    { 0x5B , 0x08 }, \r
+   // { 0x59, 0x08 }, \r
+    { 0x52 , 0x01 }, \r
+#else\r
+    { 0x59 , 0x0C }, \r
+    { 0x5B , 0x08 }, \r
+    { 0x52 , 0x00 }, \r
+    { 0x5A , 0x04 }, \r
+    { 0x54 , 0x14 }, \r
+    { 0x54 , 0x16 }, \r
+#endif\r
+    { 0x0B, 0x37 },\r
+    { 0x7F, 0x04 },\r
+    { 0x12, 0x81 },\r
+    { 0x28, 0x81 },\r
+    { 0x13, LED_IR1+LED_IR2/*0x09*/ },\r
+    { 0x29, LED_IR1+LED_IR2/*0x09*/ },\r
+    { 0x14, 0x20 },\r
+    { 0x2A, 0x20 },\r
+    { 0x7F, 0x00 },\r
+    { 0x4B, 0x0C },//R_TouchDetection_Th_Hi[15:8]   3168\r
+    { 0x4D, 0x06 },//R_TouchDetection_Th_Low[15:8]  1568\r
+    { 0x7F, 0x04 },\r
+    { 0x01, LED_GREEN_1+LED_GREEN_2/*0x24*/ },\r
+    { 0x04, LED_R1+LED_R2/*0x12*/ },\r
+    { 0x07, LED_IR1+LED_IR2/*0x09*/ },\r
+    { 0x17, LED_GREEN_1+LED_GREEN_2/*0x24*/ },\r
+    { 0x1A, LED_R1+LED_R2/*0x12*/ },\r
+    { 0x1D, LED_IR1+LED_IR2/*0x09*/ },\r
+    { 0x7F, 0x01 },\r
+    { 0x65, PD_2+PD_3/*0x05*/ },\r
+    { 0x04, 0x40 },\r
+    { 0x05, 0x00 },\r
+    { 0x0B, 0x0C },//(disable ECG BG/PMU block)\r
+    { 0x36, 0x05 },\r
+    { 0x3A, 0x05 },\r
+    { 0x3E, 0x0C },\r
+    { 0x42, 0x0C },\r
+    { 0x46, 0x0C },\r
+    { 0x4A, 0x0C },\r
+    { 0x37, 0x09 },\r
+    { 0x3B, 0x09 },\r
+    { 0x3F, 0x07 },\r
+    { 0x43, 0x07 },\r
+    { 0x47, 0x07 },\r
+    { 0x4B, 0x07 },\r
+    { 0x35, PD_1+PD_2+PD_3+PD_4/*0x0F*/ },\r
+    { 0x39, 0x10 },\r
+    { 0x3D, PD_2+PD_3/*0x05*/ },\r
+    { 0x41, PD_1+PD_4/*0x0A*/ },\r
+    { 0x45, PD_2+PD_3/*0x05*/ },\r
+    { 0x49, PD_1+PD_4/*0x0A*/ },\r
+    { 0x38, 0x06 },\r
+    { 0x3C, 0x06 },\r
+    { 0x40, 0x0F },\r
+    { 0x44, 0x0F },\r
+    { 0x48, 0x0F },\r
+    { 0x4C, 0x0F },\r
+    { 0x69, 0x06 },\r
+    { 0x70, 0x06 },\r
+    { 0x6A, 0x0F },\r
+    { 0x71, 0x0F },\r
+    { 0x6B, 0x0F },\r
+    { 0x72, 0x0F },\r
+    { 0x7F, 0x00 },\r
+    { 0x18, 0x7F },\r
+#ifndef Ext_LPO_CLK_FROM_GPIO2 \r
+    { 0x03, 0x40 },//Golden report period[7:0] (1T=31.25us)\r
+    { 0x04, 0x01 },//Golden report period[15:8], 25Hz\r
+#else    \r
+    { 0x03, 0x47 },//Golden report period[7:0] (1T=31.25us)\r
+    { 0x04, 0x01 },//Golden report period[15:8], 25Hz\r
+#endif\r
+    { 0x4F, 0x09 },//R_NoTouchDetection_Count_Th[4:0]\r
+    { 0x1B, 0x11 },\r
+    { 0x50, 0x05 },\r
+//    { 0x51, 0x17 },\r
+//    { 0x52, 0x17 },\r
+    { 0x68, 0x00 },\r
+ \r
+};\r
+\r
+//PAH831X_REG_PPG_8 : 50HZ 1CH_1PPG G 150K\r
+#define PAH831X_REG_PPG_8_ODR (50)\r
+static const uint8_t PAH831X_REG_PPG_8[][2] = {\r
+    { 0x7F, 0x03 },\r
+    { 0x0B, 0x36 },\r
+#ifndef Ext_LPO_CLK_FROM_GPIO2   \r
+    { 0x59 , 0x0C }, \r
+    { 0x5B , 0x08 }, \r
+   // { 0x59, 0x08 }, \r
+    { 0x52 , 0x01 }, \r
+#else\r
+    { 0x59 , 0x0C }, \r
+    { 0x5B , 0x08 }, \r
+    { 0x52 , 0x00 }, \r
+    { 0x5A , 0x04 }, \r
+    { 0x54 , 0x14 }, \r
+    { 0x54 , 0x16 }, \r
+#endif\r
+    { 0x0B, 0x37 },\r
+    { 0x7F, 0x04 },\r
+    { 0x12, 0x81 },\r
+    { 0x28, 0x81 },\r
+    { 0x13, LED_IR1+LED_IR2/*0x09*/ },\r
+    { 0x29, LED_IR1+LED_IR2/*0x09*/ },\r
+    { 0x14, 0x20 },\r
+    { 0x2A, 0x20 },\r
+    { 0x7F, 0x00 },\r
+    { 0x4B, 0x0C },//R_TouchDetection_Th_Hi[15:8]   3168\r
+    { 0x4D, 0x06 },//R_TouchDetection_Th_Low[15:8]  1568\r
+    { 0x7F, 0x04 },\r
+    { 0x01, LED_GREEN_1+LED_GREEN_2/*0x24*/ },\r
+    { 0x04, LED_R1+LED_R2/*0x12*/ },\r
+    { 0x07, LED_IR1+LED_IR2/*0x09*/ },\r
+    { 0x17, LED_GREEN_1+LED_GREEN_2/*0x24*/ },\r
+    { 0x1A, LED_R1+LED_R2/*0x12*/ },\r
+    { 0x1D, LED_IR1+LED_IR2/*0x09*/ },\r
+    { 0x7F, 0x01 },\r
+    { 0x65, PD_2+PD_3/*0x05*/ },\r
+    { 0x04, 0x40 },\r
+    { 0x05, 0x00 },\r
+    { 0x0B, 0x0C },//(disable ECG BG/PMU block)\r
+    { 0x36, 0x05 },\r
+    { 0x3A, 0x05 },\r
+    { 0x3E, 0x0C },\r
+    { 0x42, 0x0C },\r
+    { 0x46, 0x0C },\r
+    { 0x4A, 0x0C },\r
+    { 0x37, 0x09 },\r
+    { 0x3B, 0x09 },\r
+    { 0x3F, 0x07 },\r
+    { 0x43, 0x07 },\r
+    { 0x47, 0x07 },\r
+    { 0x4B, 0x07 },\r
+    { 0x35, PD_1+PD_2+PD_3+PD_4/*0x0F*/ },\r
+    { 0x39, 0x10 },\r
+    { 0x3D, PD_2+PD_3/*0x05*/ },\r
+    { 0x41, PD_1+PD_4/*0x0A*/ },\r
+    { 0x45, PD_2+PD_3/*0x05*/ },\r
+    { 0x49, PD_1+PD_4/*0x0A*/ },\r
+    { 0x38, 0x06 },\r
+    { 0x3C, 0x06 },\r
+    { 0x40, 0x0F },\r
+    { 0x44, 0x0F },\r
+    { 0x48, 0x0F },\r
+    { 0x4C, 0x0F },\r
+    { 0x69, 0x06 },\r
+    { 0x70, 0x06 },\r
+    { 0x6A, 0x0F },\r
+    { 0x71, 0x0F },\r
+    { 0x6B, 0x0F },\r
+    { 0x72, 0x0F },\r
+    { 0x7F, 0x00 },\r
+    { 0x18, 0x7F },\r
+#ifndef Ext_LPO_CLK_FROM_GPIO2 \r
+    { 0x03, 0x80 },//Golden report period[7:0] (1T=31.25us)\r
+    { 0x04, 0x02 },//Golden report period[15:8], 25Hz\r
+#else    \r
+    { 0x03, 0x8F },//Golden report period[7:0] (1T=31.25us)\r
+    { 0x04, 0x02 },//Golden report period[15:8], 25Hz\r
+#endif\r
+    { 0x4F, 0x09 },//R_NoTouchDetection_Count_Th[4:0]\r
+    { 0x1B, 0x11 },\r
+    { 0x50, 0x05 },\r
+//    { 0x51, 0x17 },\r
+//    { 0x52, 0x17 },\r
+    { 0x68, 0x00 },\r
+\r
+};\r
+\r
+\r
+\r
+#define PAH831X_REG_PPG_9_ODR (25)\r
+static const uint8_t PAH831X_REG_PPG_9[][2] = {\r
+    { 0x7F, 0x05 },\r
+ \r
+};\r
+\r
+\r
+#define PAH831X_REG_PPG_10_ODR (25)\r
+static const uint8_t PAH831X_REG_PPG_10[][2] = {\r
+   { 0x7F, 0x03 },\r
+ \r
+};\r
+\r
+\r
+#define PAH831X_REG_ECG_1_ODR (300)\r
+static const uint8_t PAH831X_REG_ECG_1[][2] = {\r
+    { 0x7F ,0x03 }, \r
+    { 0x0B ,0x36 }, \r
+#ifndef Ext_LPO_CLK_FROM_GPIO2   \r
+    { 0x59 , 0x0C }, \r
+    { 0x5B , 0x08 }, \r
+   // { 0x59, 0x08 }, \r
+    { 0x52 , 0x01 }, \r
+#else\r
+    { 0x59 , 0x0C }, \r
+    { 0x5B , 0x08 }, \r
+    { 0x52 , 0x00 }, \r
+    { 0x5A , 0x04 }, \r
+    { 0x54 , 0x14 }, \r
+    { 0x54 , 0x16 }, \r
+#endif\r
+    { 0x0B , 0x37 }, \r
+    { 0x7F , 0x05 }, \r
+    { 0x02 , 0x69 },                                                                                                           \r
+    { 0x08 , 0x73 },                                                                                                           \r
+    { 0x0A , 0x50 },                                                                                                           \r
+    { 0x0E , 0x80 },                                                                                                           \r
+    { 0x14 , 0xD0 },                                                                                                           \r
+    { 0x16 , 0x60 },                                                                                                           \r
+    { 0x1A , 0x80 },                                                                                                           \r
+    { 0x20 , 0xD0 },                                                                                                           \r
+    { 0x22 , 0x60 },                                                                                                           \r
+    { 0x26 , 0x80 },                                                                                                           \r
+    { 0x2C , 0xD0 },                                                                                                           \r
+    { 0x2E , 0x60 },                                                                                                           \r
+    { 0x7F , 0x04 }, \r
+    { 0x13 , LED_IR1+LED_IR2/*0x09*/ }, \r
+    { 0x29 , LED_IR1+LED_IR2/*0x09*/ }, \r
+    { 0x14 , 0x45 }, \r
+    { 0x2A , 0x45 }, \r
+    { 0x01 , LED_GREEN_1+LED_GREEN_2/*0x0C*/ }, \r
+    { 0x04 , LED_R1+LED_R2/*0x12*/ }, \r
+    { 0x07 , LED_IR1+LED_IR2/*0x09*/ }, \r
+    { 0x0A , 0x00 }, \r
+    { 0x17 , LED_GREEN_1+LED_GREEN_2/*0x0C*/ }, \r
+    { 0x1A , LED_R1+LED_R2/*0x12*/ }, \r
+    { 0x1D , LED_IR1+LED_IR2/*0x09*/ }, \r
+    { 0x20 , 0x00 }, \r
+    { 0x34 , 0x01 }, //R_ChD_LED_dac1_max[7:0]                                                                                                                                 \r
+    { 0x7F , 0x01 }, \r
+    { 0x65 , PD_2+PD_3/*0x05*/ }, \r
+    { 0x04 , 0x40 }, \r
+    { 0x05 , 0x00 }, \r
+    { 0x36 , 0x00 }, \r
+    { 0x3A , 0x00 }, \r
+    { 0x3E , 0x05 }, \r
+    { 0x42 , 0x05 }, \r
+    { 0x46 , 0x05 }, \r
+    { 0x4A , 0x05 }, \r
+    { 0x4E , 0x0C }, \r
+    { 0x52 , 0x0C }, \r
+    { 0x37 , 0x0F }, \r
+    { 0x3B , 0x0F }, \r
+    { 0x3F , 0x09 }, \r
+    { 0x43 , 0x09 }, \r
+    { 0x47 , 0x09 }, \r
+    { 0x4B , 0x09 }, \r
+    { 0x4F , 0x07 }, \r
+    { 0x53 , 0x07 }, \r
+    { 0x35 , PD_1+PD_3/*0x05*/ }, \r
+    { 0x39 , PD_2+PD_4/*0x0A*/ }, \r
+    { 0x3D , PD_1+PD_3/*0x05*/ }, \r
+    { 0x41 , PD_2+PD_4/*0x0A*/ }, \r
+    { 0x45 , PD_1+PD_3/*0x05*/ }, \r
+    { 0x49 , PD_2+PD_4/*0x0A*/ }, \r
+    { 0x4D , PD_1+PD_3/*0x05*/ }, \r
+    { 0x51 , PD_2+PD_4/*0x0A*/ }, \r
+    { 0x38 , 0x01 }, \r
+    { 0x3C , 0x01 }, \r
+    { 0x40 , 0x05 }, \r
+    { 0x44 , 0x05 }, \r
+    { 0x48 , 0x05 }, \r
+    { 0x4C , 0x05 }, \r
+    { 0x50 , 0x0F }, \r
+    { 0x54 , 0x0F }, \r
+    { 0x69 , 0x01 }, \r
+    { 0x70 , 0x01 }, \r
+    { 0x6A , 0x05 }, \r
+    { 0x71 , 0x05 }, \r
+    { 0x6B , 0x05 }, \r
+    { 0x72 , 0x05 }, \r
+    { 0x6C , 0x0F }, \r
+    { 0x73 , 0x0F }, \r
+    { 0x7F , 0x00 }, \r
+    { 0x15 , 0x01 }, //RDB_FrameNum_D[6:0]                                                                                                                                     \r
+    { 0x18 , 0x77 }, \r
+    { 0x4B , 0x0C }, //R_TouchDetection_Th_Hi[15:8]   3168\r
+    { 0x4D , 0x06 }, //R_TouchDetection_Th_Low[15:8]\r
+    { 0x4F , 0x0C }, //R_NoTouchDetection_Count_Th[4:0] 1568\r
+    { 0x7F , 0x00 }, \r
+#ifndef Ext_LPO_CLK_FROM_GPIO2 \r
+    { 0x03 , 0x7D }, //Golden report period[7:0] (1T=31.25us)(250Hz)\r
+    { 0x04 , 0x00 }, //{Bit[7:0](Golden report period[15:8])}\r
+#else    \r
+    { 0x03, 0x80 },//Golden report period[7:0] (1T=31.25us)\r
+    { 0x04, 0x00 },//Golden report period[15:8], 25Hz\r
+#endif\r
+    { 0x27 , 0x20 }, //RDB_FrameNum_ECG[7:0]\r
+    { 0x4F , 0x04 }, //R_NoTouchDetection_Count_Th[4:0]\r
+    { 0x24 , 0x08 }, //RDB_ChT_report_divider[7:0]\r
+    { 0x2E , 0x03 }, \r
+    { 0x1B , 0x30 }, \r
+    { 0x68 , 0x00 }, \r
+    { 0x7F , 0x01 }, \r
+    { 0x05 , 0x80 }, \r
+    { 0x06 , 0x02 }, \r
+    { 0x0B , 0x00 }, //(enable PPG and ECG) \r
+    { 0x0D , 0xF2 }, \r
+    { 0x0F , 0x0E }, \r
+    { 0x26 , 0x07 }, \r
+    { 0x7E , 0x02 }, \r
+\r
+};       \r
+ #define PAH831X_REG_ECG_2_ODR (300)\r
+static const uint8_t PAH831X_REG_ECG_2[][2] = {\r
+   { 0x7F ,0x03 }, //Bank3\r
+    { 0x0B ,0x36 }, //{Dummy[1:0], B_PPG1_AMBC_PWRSV_SEL_EnH, B_PPG2_AMBC_PWRSV_SEL_EnH, Dummy, B_BG_PWRSV_SEL_EnH, B_PMU_V2I_PWRSV_SEL_EnH, B_OSC_4M_PWRSV_SEL_EnH}\r
+#ifndef Ext_LPO_CLK_FROM_GPIO2   \r
+    { 0x59 , 0x0C }, //{Dummy[2:0], R_GPIO_1, R_GPIO_1_IEB, R_GPIO_1_OEB, R_GPIO_1_PULLL_EnH, R_GPIO_1_PULLH_EnH}\r
+    { 0x5B , 0x08 }, //{Dummy[2:0], R_GPIO_3, R_GPIO_3_IEB, R_GPIO_3_OEB, R_GPIO_3_PULLL_EnH, R_GPIO_3_PULLH_EnH}\r
+   // { 0x59, 0x08 }, //{Dummy[2:0], R_GPIO_1, R_GPIO_1_IEB, R_GPIO_1_OEB, R_GPIO_1_PULLL_EnH, R_GPIO_1_PULLH_EnH}\r
+    { 0x52 , 0x01 }, //{Dummy[2:0], R_GPIO_2_Open_Drain_EnH, R_GPIO_1_Open_Drain_EnH, R_GPIO_DRV[1:0], R_GPIO_18V_EnL}  \r
+#else\r
+    { 0x59 , 0x0C }, //{Dummy[2:0], R_GPIO_1, R_GPIO_1_IEB, R_GPIO_1_OEB, R_GPIO_1_PULLL_EnH, R_GPIO_1_PULLH_EnH}\r
+    { 0x5B , 0x08 }, //{Dummy[2:0], R_GPIO_3, R_GPIO_3_IEB, R_GPIO_3_OEB, R_GPIO_3_PULLL_EnH, R_GPIO_3_PULLH_EnH}\r
+    { 0x52 , 0x00 }, //{Dummy[2:0], R_GPIO_2_Open_Drain_EnH, R_GPIO_1_Open_Drain_EnH, R_GPIO_DRV[1:0], R_GPIO_18V_EnL}\r
+    { 0x5A , 0x04 }, //{Dummy[2:0], R_GPIO_2, R_GPIO_2_IEB, R_GPIO_2_OEB, R_GPIO_2_PULLL_EnH, R_GPIO_2_PULLH_EnH}\r
+    { 0x54 , 0x14 }, //{Dummy[3:0], R_Ext_CLK_Sel, R_Ext_32K_CLK_Sel, R_Ext_32K_CLK, R_Ext_CLK}\r
+    { 0x54 , 0x16 }, //{Dummy[3:0], R_Ext_CLK_Sel, R_Ext_32K_CLK_Sel, R_Ext_32K_CLK, R_Ext_CLK}\r
+#endif\r
+    { 0x0B , 0x37 }, //{Dummy[1:0], B_PPG1_AMBC_PWRSV_SEL_EnH, B_PPG2_AMBC_PWRSV_SEL_EnH, Dummy, B_BG_PWRSV_SEL_EnH, B_PMU_V2I_PWRSV_SEL_EnH, B_OSC_4M_PWRSV_SEL_EnH}\r
+    { 0x7F , 0x05 }, //Bank5                                                                                                                                                   \r
+    { 0x02 , 0x69 }, //R_ChA_ADC_target[15:8],32768                                                                                                                            \r
+    { 0x08 , 0x73 }, //R_ChA_ACC_lock_out_UB[15:8],53248                                                                                                                       \r
+    { 0x0A , 0x50 }, //R_ChA_ACC_lock_out_LB[15:8],24576                                                                                                                       \r
+    { 0x0E , 0x80 }, //R_ChB_ADC_target[15:8]                                                                                                                                  \r
+    { 0x14 , 0xD0 }, //R_ChB_ACC_lock_out_UB[15:8]                                                                                                                             \r
+    { 0x16 , 0x60 }, //R_ChB_ACC_lock_out_LB[15:8]                                                                                                                             \r
+    { 0x1A , 0x80 }, //R_ChC_ADC_target[15:8]                                                                                                                                  \r
+    { 0x20 , 0xD0 }, //R_ChC_ACC_lock_out_UB[15:8]                                                                                                                             \r
+    { 0x22 , 0x60 }, //R_ChC_ACC_lock_out_LB[15:8]                                                                                                                             \r
+    { 0x26 , 0x80 }, //R_ChD_ADC_target[15:8]                                                                                                                                  \r
+    { 0x2C , 0xD0 }, //R_ChD_ACC_lock_out_UB[15:8]                                                                                                                             \r
+    { 0x2E , 0x60 }, //R_ChD_ACC_lock_out_LB[15:8]                                                                                                                             \r
+    { 0x7F , 0x04 }, //Bank4                                                                                                                                                   \r
+    { 0x13 , LED_IR1+LED_IR2/*0x09*/ }, //B_PPG_ChT_LEDDAC1_CH_SEL[5:0], IR                                                                                                                                                          \r
+    { 0x29 , LED_IR1+LED_IR2/*0x09*/ }, //B_PPG_ChT_LEDDAC2_CH_SEL[5:0], IR                                                                                                                                                          \r
+    { 0x14 , 0x20 }, //B_PPG_ChT_LEDDAC1_CODE[7:0]                                                                                                                                                          \r
+    { 0x2A , 0x20 }, //B_PPG_ChT_LEDDAC2_CODE[7:0]                                                                                                                                                          \r
+    { 0x01 , LED_GREEN_1+LED_GREEN_2/*0x24*/ }, //B_PPG_ChA_LEDDAC1_CH_SEL[5:0]  2G                                                                                                                       \r
+    { 0x04 , 0x00/*0x02*/ }, //B_PPG_ChB_LEDDAC1_CH_SEL[5:0]  R                                                                                                                        \r
+    { 0x07 , 0x00/*0x01*/ }, //B_PPG_ChC_LEDDAC1_CH_SEL[5:0], IR                                                                                                                       \r
+    { 0x0A , 0x00 }, //B_PPG_ChD_LEDDAC1_CH_SEL[5:0], none                                                                                                                     \r
+    { 0x17 , LED_GREEN_1+LED_GREEN_2/*0x24*/ }, //B_PPG_ChA_LEDDAC2_CH_SEL[5:0]  2G                                                                                                                       \r
+    { 0x1A , 0x00/*0x02*/ }, //B_PPG_ChB_LEDDAC2_CH_SEL[5:0]  R                                                                                                                        \r
+    { 0x1D , 0x00/*0x01*/ }, //B_PPG_ChC_LEDDAC2_CH_SEL[5:0], IR                                                                                                                       \r
+    { 0x7F , 0x01 }, //Bank1   \r
+    { 0x65 , PD_2+PD_3/*0x05*/ }, //{B_PPG1_ChT_AMBC_INV_EnH, B_PPG1_ChT_AMBC_LSB_ADJ, B_PPG1_ChT_PD_CH_SEL[4:0]}                                                                                                                                                          \r
+    { 0x04 , 0x40 }, //{T_OSC_32K_RANGE[1:0], T_OSC_4M_EnL, T_PPG1_TIA_EnL, T_PPG1_AMBC_EnL, Dummy, T_PPG1_ADC_EnL, T_PPG2_TIA_EnL}                                            \r
+    { 0x05 , 0x00 }, //{T_PPG2_AMBC_EnL, T_PPG2_ADC_EnL, T_PPG_LEDDAC2_EnL, T_PPG_LEDDAC1_EnL, T_ECG_FE_INA_EnL, T_ECG_ADC_EnL, T_ECG_FE_LOD_CMP_EnL, T_ECG_FE_LOD_I_EnL}                                                                                                                                   \r
+    { 0x36 , 0x05 }, //B_PPG1_ChA_TIA_CF_ADJ[6:0]                                                                                                                              \r
+    { 0x3A , 0x05 }, //B_PPG2_ChA_TIA_CF_ADJ[6:0]                                                                                                                              \r
+    { 0x3E , 0x0C }, //B_PPG1_ChB_TIA_CF_ADJ[6:0]                                                                                                                              \r
+    { 0x42 , 0x0C }, //B_PPG2_ChB_TIA_CF_ADJ[6:0]                                                                                                                              \r
+    { 0x46 , 0x0C }, //B_PPG1_ChC_TIA_CF_ADJ[6:0]                                                                                                                              \r
+    { 0x4A , 0x0C }, //B_PPG2_ChC_TIA_CF_ADJ[6:0]                                                                                                                              \r
+    { 0x4E , 0x0C }, //B_PPG1_ChD_TIA_CF_ADJ[6:0]                                                                                                                              \r
+    { 0x52 , 0x0C }, //B_PPG2_ChD_TIA_CF_ADJ[6:0]                                                                                                                              \r
+    { 0x37 , 0x09 }, //B_PPG1_ChA_TIA_RF_ADJ[3:0],350k                                                                                                                         \r
+    { 0x3B , 0x09 }, //B_PPG2_ChA_TIA_RF_ADJ[3:0],350k                                                                                                                         \r
+    { 0x3F , 0x07 }, //B_PPG1_ChB_TIA_RF_ADJ[3:0],150k                                                                                                                               \r
+    { 0x43 , 0x07 }, //B_PPG2_ChB_TIA_RF_ADJ[3:0],150k                                                                                                                                \r
+    { 0x47 , 0x07 }, //B_PPG1_ChC_TIA_RF_ADJ[3:0],150k                                                                                                                                \r
+    { 0x4B , 0x07 }, //B_PPG2_ChC_TIA_RF_ADJ[3:0],150k                                                                                                                                \r
+    { 0x4F , 0x07 }, //B_PPG1_ChD_TIA_RF_ADJ[3:0]                                                                                                                              \r
+    { 0x53 , 0x07 }, //B_PPG2_ChD_TIA_RF_ADJ[3:0]                                                                                                                              \r
+    { 0x35 , PD_2+PD_3/*0x05*/ }, //{B_PPG1_ChA_AMBC_INV_EnH, B_PPG1_ChA_AMBC_LSB_ADJ, B_PPG1_ChA_PD_CH_SEL[4:0]}                                                                           \r
+    { 0x39 , PD_1+PD_4/*0x0A*/ }, //{B_PPG2_ChA_AMBC_INV_EnH, B_PPG2_ChA_AMBC_LSB_ADJ, B_PPG2_ChA_PD_CH_SEL[4:0]}                                                                           \r
+    { 0x3D , PD_2+PD_3/*0x05*/ }, //{B_PPG1_ChB_AMBC_INV_EnH, B_PPG1_ChB_AMBC_LSB_ADJ, B_PPG1_ChB_PD_CH_SEL[4:0]}                                                                           \r
+    { 0x41 , PD_1+PD_4/*0x0A*/ }, //{B_PPG2_ChB_AMBC_INV_EnH, B_PPG2_ChB_AMBC_LSB_ADJ, B_PPG2_ChB_PD_CH_SEL[4:0]}                                                                           \r
+    { 0x45 , PD_2+PD_3/*0x05*/ }, //{B_PPG1_ChC_AMBC_INV_EnH, B_PPG1_ChC_AMBC_LSB_ADJ, B_PPG1_ChC_PD_CH_SEL[4:0]}                                                                           \r
+    { 0x49 , PD_1+PD_4/*0x0A*/ }, //{B_PPG2_ChC_AMBC_INV_EnH, B_PPG2_ChC_AMBC_LSB_ADJ, B_PPG2_ChC_PD_CH_SEL[4:0]}                                                                           \r
+    { 0x4D , PD_2+PD_3/*0x05*/ }, //{B_PPG1_ChD_AMBC_INV_EnH, B_PPG1_ChD_AMBC_LSB_ADJ, B_PPG1_ChD_PD_CH_SEL[4:0]}                                                                           \r
+    { 0x51 , PD_1+PD_4/*0x0A*/ }, //{B_PPG2_ChD_AMBC_INV_EnH, B_PPG2_ChD_AMBC_LSB_ADJ, B_PPG2_ChD_PD_CH_SEL[4:0]}                                                                           \r
+    { 0x38 , 0x06 }, //B_PPG1_ChA_ON_AMBC_ADJ[7:0]                                                                                                                             \r
+    { 0x3C , 0x06 }, //B_PPG2_ChA_ON_AMBC_ADJ[7:0]                                                                                                                             \r
+    { 0x40 , 0x05 }, //B_PPG1_ChB_ON_AMBC_ADJ[7:0]                                                                                                                             \r
+    { 0x44 , 0x05 }, //B_PPG2_ChB_ON_AMBC_ADJ[7:0]                                                                                                                             \r
+    { 0x48 , 0x05 }, //B_PPG1_ChC_ON_AMBC_ADJ[7:0]                                                                                                                             \r
+    { 0x4C , 0x05 }, //B_PPG2_ChC_ON_AMBC_ADJ[7:0]                                                                                                                             \r
+    { 0x50 , 0x0F }, //B_PPG1_ChD_ON_AMBC_ADJ[7:0]                                                                                                                             \r
+    { 0x54 , 0x0F }, //B_PPG2_ChD_ON_AMBC_ADJ[7:0]                                                                                                                             \r
+    { 0x69 , 0x06 }, //B_PPG1_ChA_OFF_AMBC_ADJ[7:0]                                                                                                                            \r
+    { 0x70 , 0x06 }, //B_PPG2_ChA_OFF_AMBC_ADJ[7:0]                                                                                                                            \r
+    { 0x6A , 0x05 }, //B_PPG1_ChB_OFF_AMBC_ADJ[7:0]                                                                                                                            \r
+    { 0x71 , 0x05 }, //B_PPG2_ChB_OFF_AMBC_ADJ[7:0]                                                                                                                            \r
+    { 0x6B , 0x05 }, //B_PPG1_ChC_OFF_AMBC_ADJ[7:0]                                                                                                                            \r
+    { 0x72 , 0x05 }, //B_PPG2_ChC_OFF_AMBC_ADJ[7:0]                                                                                                                            \r
+    { 0x6C , 0x0F }, //B_PPG1_ChD_OFF_AMBC_ADJ[7:0]                                                                                                                            \r
+    { 0x73 , 0x0F }, //B_PPG2_ChD_OFF_AMBC_ADJ[7:0]                                                                                                                            \r
+    { 0x7F , 0x00 }, //Bank0                                                                                                                                                                                                                                                                                  \r
+    { 0x18 , 0x7F }, //{RDB_OffOnOff_F_EnH, RDB_OffOnOff_E_EnH, RDB_OffOnOff_T_EnH, RDB_OffOnOff_F_EnH, RDB_OffOnOff_E_EnH, RDB_OffOnOff_D_EnH, RDB_OffOnOff_C_EnH, RDB_OffOnOff_B_EnH, RDB_OffOnOff_A_EnH}                                                                                                                                    \r
+    { 0x4B , 0x0C }, //R_TouchDetection_Th_Hi[15:8]   3168\r
+    { 0x4D , 0x06 }, //R_TouchDetection_Th_Low[15:8]\r
+    { 0x4F , 0x0C }, //R_NoTouchDetection_Count_Th[4:0] 1568\r
+    { 0x7F , 0x00 }, //Bank0\r
+#ifndef Ext_LPO_CLK_FROM_GPIO2 \r
+    { 0x03 , 0x7D }, //Golden report period[7:0] (1T=31.25us)(250Hz)\r
+    { 0x04 , 0x00 }, //{Bit[7:0](Golden report period[15:8])}\r
+#else    \r
+    { 0x03, 0x80 },//Golden report period[7:0] (1T=31.25us)\r
+    { 0x04, 0x00 },//Golden report period[15:8], 25Hz\r
+#endif\r
+    { 0x12 , 0x20 }, //RDB_FrameNum_A[6:0]          \r
+    { 0x27 , 0x20 }, //RDB_FrameNum_ECG[7:0]\r
+    { 0x4F , 0x04 }, //R_NoTouchDetection_Count_Th[4:0]\r
+    { 0x24 , 0x08 }, //RDB_ChT_report_divider[7:0]\r
+    { 0x2E , 0x03 }, //{fp_lpf_mask_cnt[7:4], Reserved[3], fp_lpf_sel[2:1](0:128/1:256/2:512/3:1024Hz), fp_lpf_enh[0]}\r
+    { 0x1B , 0x21 }, //{Reserved[7], RDB_LOD_EnH[6], RDB_ECG_EnH[5], RDB_ChT_EnH[4], RDB_ChD_EnH[3], RDB_ChC_EnH[2], RDB_ChB_EnH[1], RDB_ChA_EnH[0]}\r
+    { 0x50 , 0x05 },//{1'b0, R_PPG_FIFO_Write_skip_A_EnH, R_AGC_DAC_TIA_A_EnH[1:0], R_AGC_PPG2_A_Sel, R_AGC_PPG1_A_Sel, R_PPG2_A_EnH, R_PPG1_A_EnH};\r
+    { 0x68 , 0x00 }, //{Dummy[5:0], RDB_ChF_EnH, RDB_ChE_EnH}; \r
+    { 0x7F , 0x01 }, //Bank1\r
+    { 0x05 , 0x00 }, //{T_PPG2_AMBC_EnL, T_PPG2_ADC_EnL, T_PPG_LEDDAC2_EnL, T_PPG_LEDDAC1_EnL, T_ECG_FE_INA_EnL, T_ECG_ADC_EnL, T_ECG_FE_LOD_CMP_EnL, T_ECG_FE_LOD_I_EnL}\r
+    { 0x06 , 0x01 }, //{T_ECG_FE_LOD_GATE_INACHOP_EnH, T_ECG_FE_I_GATED_INA_EnH, T_ECG_PGA_TEST_EnH, T_ECG_FE_LOD_RLDCMP_EnL, T_ECG_FE_VCMBUF_EnL, T_ECG_FE_INA_HPF_SHORT, T_ECG_POLAR_FLIP_EnH, Dummy}\r
+    { 0x0B , 0x00 }, //(enable PPG and ECG) \r
+    { 0x0D , 0xF2 }, //{B_PPG_LEDDAC2_PWRSV_SEL_EnH, B_PPG_LEDDAC1_PWRSV_SEL_EnH, B_ECG_FE_INA_PWRSV_SEL_EnH, B_ECG_ADC_PWRSV_SEL_EnH, B_ECG_FE_LOD_CMP_PWRSV_SEL_EnH, B_ECG_FE_LOD_I_PWRSV_SEL_EnH, B_ECG_FE_RLD_PWRSV_SEL_EnH, B_ECG_FE_LOD_RLDCMP_PWRSV_SEL_EnH} \r
+    { 0x0F , 0x0E }, //{B_ECG_VCMBUF_OFF[3:0], B_ECG_FE_VCMBUF_PWRSV_SEL_EnH, B_ECG_FE_PGA_PWRSV_SEL_EnH, B_ECG_FE_BUF_PWRSV_SEL_EnH, B_ECG_FE_INA_LPF_FAST_SEL_EnH}\r
+    { 0x26 , 0x07 }, //{T_ECG_RF_PGA_ADJ[2:0], Dummy, T_ECG_PGA_LPF_1M_EN, T_ECG_FE_RLD2VCMBUF_EnH, T_ECG_FE_INA_GAIN[1:0]} \r
+    { 0x7E , 0x02 }, //{Dummy[4:0], B_ECG_FAST_RECOVERY_MODE, B_FAST_RECOVERY_EN, TS_ECG_FAST_RECOVERY_EnH}  \r
+ \r
+};\r
+\r
+//for LOD \r
+#define PAH831X_REG_ECG_3_ODR (300)\r
+static const uint8_t PAH831X_REG_ECG_3[][2] = {\r
+    { 0x7F ,0x03 }, \r
+    { 0x0B ,0x36 }, \r
+#ifndef Ext_LPO_CLK_FROM_GPIO2   \r
+    { 0x59 , 0x0C }, \r
+    { 0x5B , 0x08 }, \r
+   // { 0x59, 0x08 }, \r
+    { 0x52 , 0x01 }, \r
+#else\r
+    { 0x59 , 0x0C }, \r
+    { 0x5B , 0x08 }, \r
+    { 0x52 , 0x00 }, \r
+    { 0x5A , 0x04 }, \r
+    { 0x54 , 0x14 }, \r
+    { 0x54 , 0x16 }, \r
+#endif\r
+    { 0x0B , 0x37 }, \r
+    { 0x7F , 0x05 }, \r
+    { 0x02 , 0x69 },                                                                                                           \r
+    { 0x08 , 0x73 },                                                                                                           \r
+    { 0x0A , 0x50 },                                                                                                           \r
+    { 0x0E , 0x80 },                                                                                                           \r
+    { 0x14 , 0xD0 },                                                                                                           \r
+    { 0x16 , 0x60 },                                                                                                           \r
+    { 0x1A , 0x80 },                                                                                                           \r
+    { 0x20 , 0xD0 },                                                                                                           \r
+    { 0x22 , 0x60 },                                                                                                           \r
+    { 0x26 , 0x80 },                                                                                                           \r
+    { 0x2C , 0xD0 },                                                                                                           \r
+    { 0x2E , 0x60 },                                                                                                           \r
+    { 0x7F , 0x04 }, \r
+    { 0x13 , LED_IR1+LED_IR2/*0x09*/ }, \r
+    { 0x29 , LED_IR1+LED_IR2/*0x09*/ }, \r
+    { 0x14 , 0x45 }, \r
+    { 0x2A , 0x45 }, \r
+    { 0x01 , LED_GREEN_1+LED_GREEN_2/*0x0C*/ }, \r
+    { 0x04 , LED_R1+LED_R2/*0x12*/ }, \r
+    { 0x07 , LED_IR1+LED_IR2/*0x09*/ }, \r
+    { 0x0A , 0x00 }, \r
+    { 0x17 , LED_GREEN_1+LED_GREEN_2/*0x0C*/ }, \r
+    { 0x1A , LED_R1+LED_R2/*0x12*/ }, \r
+    { 0x1D , LED_IR1+LED_IR2/*0x09*/ }, \r
+    { 0x20 , 0x00 }, \r
+    { 0x34 , 0x01 }, //R_ChD_LED_dac1_max[7:0]                                                                                                                                 \r
+    { 0x7F , 0x01 }, \r
+    { 0x65 , PD_2+PD_3/*0x05*/ }, \r
+    { 0x04 , 0x40 }, \r
+    { 0x05 , 0x00 }, \r
+    { 0x36 , 0x00 }, \r
+    { 0x3A , 0x00 }, \r
+    { 0x3E , 0x05 }, \r
+    { 0x42 , 0x05 }, \r
+    { 0x46 , 0x05 }, \r
+    { 0x4A , 0x05 }, \r
+    { 0x4E , 0x0C }, \r
+    { 0x52 , 0x0C }, \r
+    { 0x37 , 0x0F }, \r
+    { 0x3B , 0x0F }, \r
+    { 0x3F , 0x09 }, \r
+    { 0x43 , 0x09 }, \r
+    { 0x47 , 0x09 }, \r
+    { 0x4B , 0x09 }, \r
+    { 0x4F , 0x07 }, \r
+    { 0x53 , 0x07 }, \r
+    { 0x35 , PD_1+PD_3/*0x05*/ }, \r
+    { 0x39 , PD_2+PD_4/*0x0A*/ }, \r
+    { 0x3D , PD_1+PD_3/*0x05*/ }, \r
+    { 0x41 , PD_2+PD_4/*0x0A*/ }, \r
+    { 0x45 , PD_1+PD_3/*0x05*/ }, \r
+    { 0x49 , PD_2+PD_4/*0x0A*/ }, \r
+    { 0x4D , PD_1+PD_3/*0x05*/ }, \r
+    { 0x51 , PD_2+PD_4/*0x0A*/ }, \r
+    { 0x38 , 0x01 }, \r
+    { 0x3C , 0x01 }, \r
+    { 0x40 , 0x05 }, \r
+    { 0x44 , 0x05 }, \r
+    { 0x48 , 0x05 }, \r
+    { 0x4C , 0x05 }, \r
+    { 0x50 , 0x0F }, \r
+    { 0x54 , 0x0F }, \r
+    { 0x69 , 0x01 }, \r
+    { 0x70 , 0x01 }, \r
+    { 0x6A , 0x05 }, \r
+    { 0x71 , 0x05 }, \r
+    { 0x6B , 0x05 }, \r
+    { 0x72 , 0x05 }, \r
+    { 0x6C , 0x0F }, \r
+    { 0x73 , 0x0F }, \r
+    { 0x7F , 0x00 }, \r
+    { 0x15 , 0x01 }, //RDB_FrameNum_D[6:0]                                                                                                                                     \r
+    { 0x18 , 0x77 }, \r
+    { 0x4B , 0x0C }, //R_TouchDetection_Th_Hi[15:8]   3168\r
+    { 0x4D , 0x06 }, //R_TouchDetection_Th_Low[15:8]\r
+    { 0x4F , 0x0C }, //R_NoTouchDetection_Count_Th[4:0] 1568\r
+    { 0x7F , 0x00 }, \r
+#ifndef Ext_LPO_CLK_FROM_GPIO2 \r
+    { 0x03 , 0x7D }, //Golden report period[7:0] (1T=31.25us)(250Hz)\r
+    { 0x04 , 0x00 }, //{Bit[7:0](Golden report period[15:8])}\r
+#else    \r
+    { 0x03, 0x80 },//Golden report period[7:0] (1T=31.25us)\r
+    { 0x04, 0x00 },//Golden report period[15:8], 25Hz\r
+#endif\r
+    { 0x27 , 0x20 }, //RDB_FrameNum_ECG[7:0]\r
+    { 0x4F , 0x04 }, //R_NoTouchDetection_Count_Th[4:0]\r
+    { 0x24 , 0x08 }, //RDB_ChT_report_divider[7:0]\r
+    { 0x2E , 0x03 }, \r
+    { 0x1B , 0x60 },\r
+    { 0x68 , 0x00 }, \r
+    { 0x7F , 0x01 }, \r
+    { 0x05 , 0x80 }, \r
+    { 0x06 , 0x02 }, \r
+    { 0x0B , 0x00 }, //(enable PPG and ECG) \r
+    { 0x0D , 0xF2 }, \r
+    { 0x0F , 0x0E }, \r
+    { 0x26 , 0x07 }, \r
+    { 0x7E , 0x02 }, \r
+};\r
+#define PAH831X_REG_ECG_4_ODR (300)\r
+static const uint8_t PAH831X_REG_ECG_4[][2] = {\r
+    { 0x7F, 0x01 },\r
+};\r
+#define PAH831X_REG_ECG_5_ODR (300)\r
+static const uint8_t PAH831X_REG_ECG_5[][2] = {\r
+    { 0x7F, 0x01 },\r
+};  \r
+       
\ No newline at end of file
index 9539965..3b4311f 100644 (file)
@@ -82,7 +82,17 @@ static uint32_t ppg_do_test(uint8_t *para, uint32_t paraLen, char *strCommonCmd)
     } else if (strcmp(mode, "spo2") == 0) {
         md = PPG_SERVICE_CMD_TYPE_DO_SPO2_TEST;
         ppg_set_factory_log_switch(1);
-    } else if (strcmp(mode, "leaklight") == 0) {
+    } else if (strcmp(mode, "ecgbp") == 0) {
+        md = PPG_SERVICE_CMD_TYPE_DO_ECGBP_TEST;
+    }else if (strcmp(mode, "ecgafib") == 0) {
+        md = PPG_SERVICE_CMD_TYPE_DO_ECGAFIB_TEST;
+    }else if (strcmp(mode, "stress") == 0) {
+        md = PPG_SERVICE_CMD_TYPE_DO_STRESS_TEST;
+    }else if (strcmp(mode, "rr") == 0) {
+        md = PPG_SERVICE_CMD_TYPE_DO_RR_TEST;
+    }else if (strcmp(mode, "ecgraw") == 0) {
+        md = PPG_SERVICE_CMD_TYPE_DO_ECGRAW_TEST;
+    }else if (strcmp(mode, "leaklight") == 0) {
         md = PPG_SERVICE_CMD_TYPE_DO_LEAKLIGHT_TEST;
     } else if (strcmp(mode, "graycard") == 0) {
         md = PPG_SERVICE_CMD_TYPE_DO_GRAYCARD_TEST;
@@ -90,7 +100,7 @@ static uint32_t ppg_do_test(uint8_t *para, uint32_t paraLen, char *strCommonCmd)
         md = PPG_SERVICE_CMD_TYPE_FPC_TEST;
     } else if (strcmp(mode, "factory") == 0) {
         md = PPG_SERVICE_CMD_TYPE_FACTORY_TEST;
-    }
+    } 
 
     if(enabled == 0 )
     {   
index 83aa5ac..7b2d33b 100644 (file)
@@ -47,7 +47,7 @@ static uint8_t keep_in_wear_det_mod = 1; //持续坚持 佩戴检测模式
 
 void set_keep_in_wear_det_mode(uint8_t mod)
 {
-    keep_in_wear_det_mod = mod;
+    // keep_in_wear_det_mod = mod;
 }
 
 void uapi_ppg_service_deinit(void)
@@ -155,6 +155,66 @@ static void ppg_service_check_task(void  *arg)
             cmd = "hrv";
             enable = 0;
         }
+        else if(mail == PPG_SERVICE_CMD_TYPE_DO_ECGBP_TEST)
+        {
+            cmd = "ecgbp";
+            enable = 1;
+        }
+        else if(mail == PPG_SERVICE_CMD_TYPE_STOP_ECGBP_TEST)
+        {
+            cmd = "ecgbp";
+            enable = 0;
+        }
+        else if(mail == PPG_SERVICE_CMD_TYPE_DO_ECGAFIB_TEST)
+        {
+            cmd = "ecgafib";
+            enable = 1;
+        }
+        else if(mail == PPG_SERVICE_CMD_TYPE_STOP_ECGAFIB_TEST)
+        {
+            cmd = "ecgafib";
+            enable = 0;
+        }
+        else if(mail == PPG_SERVICE_CMD_TYPE_DO_STRESS_TEST)
+        {
+            cmd = "stress";
+            enable = 1;
+        }
+        else if(mail == PPG_SERVICE_CMD_TYPE_STOP_STRESS_TEST)
+        {
+            cmd = "stress";
+            enable = 0;
+        }
+        else if(mail == PPG_SERVICE_CMD_TYPE_DO_RR_TEST)
+        {
+            cmd = "rr";
+            enable = 1;
+        }
+        else if(mail == PPG_SERVICE_CMD_TYPE_STOP_RR_TEST)
+        {
+            cmd = "rr";
+            enable = 0;
+        }
+        else if(mail == PPG_SERVICE_CMD_TYPE_DO_ECGRAW_TEST)
+        {
+            cmd = "ecgraw";
+            enable = 1;
+        }
+        else if(mail == PPG_SERVICE_CMD_TYPE_STOP_ECGRAW_TEST)
+        {
+            cmd = "ecgraw";
+            enable = 0;
+        }
+        else if(mail == PPG_SERVICE_CMD_TYPE_DO_ECGBPCALI_TEST)
+        {
+            cmd = "ecgbp_cali";
+            enable = 1;
+        }
+        else if(mail == PPG_SERVICE_CMD_TYPE_STOP_ECGBPCALI_TEST)
+        {
+            cmd = "ecgbp_cali";
+            enable = 0;
+        }
         else if (mail == PPG_SERVICE_CMD_TYPE_INT_HANDLER){
             ppg_int_handler();
             continue;
@@ -229,7 +289,7 @@ errcode_t uapi_ppg_service_init(void)
     taskcfg.create_queue_handle = create_ppg_queue;
     taskcfg.attr.name="ppg_service";
 
-    taskcfg.attr.priority = osPriorityBelowNormal4;
+    taskcfg.attr.priority = osPriorityAboveNormal3;
 
     taskcfg.attr.stack_size = PPG_SERVICE_TASK_SIZE;
     taskcfg.func = ppg_service_check_task;
@@ -286,6 +346,58 @@ void ppg_hrv_stop(void)
     send_ppg_cmd_msg(PPG_SERVICE_CMD_TYPE_STOP_HRV_TEST);
 }
 
+void ppg_bp_start(uint8_t mode)
+{
+    if(mode == 0)
+        send_ppg_cmd_msg(PPG_SERVICE_CMD_TYPE_DO_ECGBPCALI_TEST);
+    else if(mode == 1)
+        send_ppg_cmd_msg(PPG_SERVICE_CMD_TYPE_DO_ECGBP_TEST);
+}
+
+void ppg_bp_stop(void)
+{
+    send_ppg_cmd_msg(PPG_SERVICE_CMD_TYPE_STOP_ECGBP_TEST);
+}
+
+void ppg_afib_start(void)
+{
+    send_ppg_cmd_msg(PPG_SERVICE_CMD_TYPE_DO_ECGAFIB_TEST);
+}
+
+void ppg_afib_stop(void)
+{
+    send_ppg_cmd_msg(PPG_SERVICE_CMD_TYPE_STOP_ECGAFIB_TEST);
+}
+
+void ppg_stress_start(void)
+{
+    send_ppg_cmd_msg(PPG_SERVICE_CMD_TYPE_DO_STRESS_TEST);
+}
+
+void ppg_stress_stop(void)
+{
+    send_ppg_cmd_msg(PPG_SERVICE_CMD_TYPE_STOP_STRESS_TEST);
+}
+
+void ppg_rr_start(void)
+{
+    send_ppg_cmd_msg(PPG_SERVICE_CMD_TYPE_DO_RR_TEST);
+}
+
+void ppg_rr_stop(void)
+{
+    send_ppg_cmd_msg(PPG_SERVICE_CMD_TYPE_STOP_RR_TEST);
+}
+
+void ppg_ecg_raw_start(void)
+{
+    send_ppg_cmd_msg(PPG_SERVICE_CMD_TYPE_DO_ECGRAW_TEST);
+}
+
+void ppg_ecg_raw_stop(void)
+{
+    send_ppg_cmd_msg(PPG_SERVICE_CMD_TYPE_STOP_ECGRAW_TEST);
+}
 
 // void ppg_service_service_resume(void)
 // {
index 50ef058..1bdd4a0 100644 (file)
@@ -2,7 +2,7 @@
  * @Author: penglei 1624952103@qq.com
  * @Date: 2024-03-27 09:07:00
  * @LastEditors: penglei 1624952103@qq.com
- * @LastEditTime: 2025-11-02 16:53:00
+ * @LastEditTime: 2025-12-26 13:57:44
  * @FilePath: /FD230/code/sdk/drivers/peripheral/ppg/service/ppg_service.h
  * @Description: 
  * 
@@ -50,6 +50,19 @@ extern "C" {
 #define PPG_SERVICE_CMD_TYPE_FPC_TEST 0x27
 #define PPG_SERVICE_CMD_TYPE_FACTORY_TEST 0x28
 #define PPG_SERVICE_CMD_TYPE_STOP_HRV_TEST 0x29
+#define PPG_SERVICE_CMD_TYPE_DO_ECGBP_TEST 0x2A
+#define PPG_SERVICE_CMD_TYPE_STOP_ECGBP_TEST 0x2B
+#define PPG_SERVICE_CMD_TYPE_DO_ECGAFIB_TEST 0x2C
+#define PPG_SERVICE_CMD_TYPE_STOP_ECGAFIB_TEST 0x2D
+#define PPG_SERVICE_CMD_TYPE_DO_STRESS_TEST 0x2E
+#define PPG_SERVICE_CMD_TYPE_STOP_STRESS_TEST 0x2F
+#define PPG_SERVICE_CMD_TYPE_DO_RR_TEST 0x30
+#define PPG_SERVICE_CMD_TYPE_STOP_RR_TEST 0x31
+#define PPG_SERVICE_CMD_TYPE_DO_ECGRAW_TEST 0x32
+#define PPG_SERVICE_CMD_TYPE_STOP_ECGRAW_TEST 0x33
+#define PPG_SERVICE_CMD_TYPE_DO_ECGBPCALI_TEST 0x34
+#define PPG_SERVICE_CMD_TYPE_STOP_ECGBPCALI_TEST 0x35
+
 
 errcode_t uapi_ppg_service_init(void);
 void uapi_ppg_service_deinit(void);
@@ -95,6 +108,27 @@ void ppg_spo2_stop(void);
 void ppg_hrv_start(void);
 void ppg_hrv_stop(void);
 
+//mode:0 校准模式  1:正常测量
+void ppg_bp_start(uint8_t mode);
+void ppg_bp_stop(void);
+
+//房颤测量
+void ppg_afib_start(void);
+void ppg_afib_stop(void);
+
+//压力测量
+void ppg_stress_start(void);
+void ppg_stress_stop(void);
+
+//呼吸率测量
+void ppg_rr_start(void);
+void ppg_rr_stop(void);
+
+//ECG心电原始数据
+void ppg_ecg_raw_start(void);
+void ppg_ecg_raw_stop(void);
+
+
 #ifdef __cplusplus
 #if __cplusplus
 }
index 0fdaf0b..2992e68 100644 (file)
@@ -127,6 +127,7 @@ static int create_folder_structure(const char *folder_path)
     // }
     
     free(full_path);
+    full_path = NULL;
     return 0;
 }
 
@@ -250,6 +251,7 @@ static void agnss_download_result_handler(const char *filename, HTTPC_RESULT res
             
             // 释放内存
             free(filepath);
+            filepath = NULL;
         }
     } else {
         // AGNSS文件列表下载的结果处理
@@ -406,8 +408,8 @@ static HTTPC_RESULT download_file_with_httpclient(const char *filename, const ch
     char *path = malloc(512);
     if (host == NULL || path == NULL) {
         printf("Error: Failed to allocate memory for URL parsing\n");
-        if (host) free(host);
-        if (path) free(path);
+        if (host) free(host); host = NULL;
+        if (path) free(path); path = NULL;
         g_download_status = -1;
         return HTTP_EARG;
     }
@@ -425,6 +427,8 @@ static HTTPC_RESULT download_file_with_httpclient(const char *filename, const ch
                 printf("Host name too long: %d bytes\n", host_len);
                 free(host);
                 free(path);
+                host = NULL;
+                path = NULL;
                 g_download_status = -1;
                 return HTTP_EARG;
             }
@@ -435,6 +439,8 @@ static HTTPC_RESULT download_file_with_httpclient(const char *filename, const ch
                 printf("Path too long: %zu bytes\n", strlen(path_start));
                 free(host);
                 free(path);
+                host = NULL;
+                path = NULL;
                 g_download_status = -1;
                 return HTTP_EARG;
             }
@@ -443,6 +449,8 @@ static HTTPC_RESULT download_file_with_httpclient(const char *filename, const ch
             printf("Invalid URL format - no path found\n");
             free(host);
             free(path);
+            host = NULL;
+            path = NULL;
             g_download_status = -1;
             return HTTP_EARG;
         }
@@ -450,6 +458,8 @@ static HTTPC_RESULT download_file_with_httpclient(const char *filename, const ch
         printf("Unsupported URL scheme: %s\n", url);
         free(host);
         free(path);
+        host = NULL;
+        path = NULL;
         g_download_status = -1;
         return HTTP_EARG;
     }
@@ -461,8 +471,10 @@ static HTTPC_RESULT download_file_with_httpclient(const char *filename, const ch
         printf("Error: Failed to allocate memory for filepath/timestamp_folder\n");
         free(host);
         free(path);
-        if (filepath) free(filepath);
-        if (timestamp_folder) free(timestamp_folder);
+        host = NULL;
+        path = NULL;
+        if (filepath) free(filepath); filepath = NULL;
+        if (timestamp_folder) free(timestamp_folder); timestamp_folder = NULL;
         g_download_status = -1;
         return HTTP_EARG;
     }
@@ -506,6 +518,7 @@ static HTTPC_RESULT download_file_with_httpclient(const char *filename, const ch
                             printf("File will be saved to: %s\n", filepath);
 
                             free(full_folder_path); // 用完释放内存
+                            full_folder_path = NULL;
                         } else {
                             printf("Error: Failed to allocate memory for full_folder_path\n");
                         }
@@ -530,6 +543,7 @@ static HTTPC_RESULT download_file_with_httpclient(const char *filename, const ch
                         create_folder_structure(full_folder_path);
                         snprintf(filepath, 512, "%s/%s", full_folder_path, filename);
                         free(full_folder_path);
+                        full_folder_path = NULL;
                     }
                 }
             }
@@ -552,10 +566,10 @@ static HTTPC_RESULT download_file_with_httpclient(const char *filename, const ch
     HTTPC_RESULT prep_result = gnss_http_prepare_auto(&clientData, 2048, 256 * 1024);
     if (prep_result != HTTP_SUCCESS) {
         printf("HTTP客户端准备失败: %d\n", prep_result);
-        free(host);
-        free(path);
-        free(filepath);
-        free(timestamp_folder);
+        free(host); host = NULL;
+        free(path); path = NULL;
+        free(filepath); filepath = NULL;
+        free(timestamp_folder); timestamp_folder = NULL;
         g_download_status = -1;
         return prep_result;
     }
@@ -564,10 +578,10 @@ static HTTPC_RESULT download_file_with_httpclient(const char *filename, const ch
     char *full_url = malloc(512);
     if (full_url == NULL) {
         printf("Error: Failed to allocate memory for full_url\n");
-        free(host);
-        free(path);
-        free(filepath);
-        free(timestamp_folder);
+        free(host); host = NULL;
+        free(path); path = NULL;
+        free(filepath); filepath = NULL;
+        free(timestamp_folder); timestamp_folder = NULL;
         g_download_status = -1;
         return HTTP_EARG;
     }
@@ -797,11 +811,11 @@ static HTTPC_RESULT download_file_with_httpclient(const char *filename, const ch
     HttpClientClse(&client);
     
     // 释放动态分配的内存
-    free(host);
-    free(path);
-    free(filepath);
-    free(timestamp_folder);
-    free(full_url);
+    free(host); host = NULL;
+    free(path); path = NULL;
+    free(filepath); filepath = NULL;
+    free(timestamp_folder); timestamp_folder = NULL;
+    free(full_url); full_url = NULL;
     
     return result;
 }
@@ -991,6 +1005,7 @@ static void verify_files_recursive(const char *base_path, int *total_count)
             closedir(sub_dir);
             verify_files_recursive(full_path, total_count);
             free(full_path);
+            full_path = NULL;
         } else {
             // 这是一个文件,检查是否是AGNSS相关文件
             if (strstr(entry->d_name, ".eph") != NULL || 
@@ -1019,6 +1034,7 @@ static void verify_files_recursive(const char *base_path, int *total_count)
                 }
             }
             free(full_path);
+            full_path = NULL;
         }
     }
     
@@ -1421,6 +1437,7 @@ static void agnss_process_complete_response(void)
                             if (folder_timestamp_str == NULL) {
                                 printf("Error: Failed to allocate memory for folder_timestamp_str\n");
                                 free(download_url);
+                                download_url = NULL;
                                 continue;
                             }
                             memset(folder_timestamp_str, 0, 32);
@@ -1450,10 +1467,12 @@ static void agnss_process_complete_response(void)
                                 add_valid_timestamp(folder_timestamp);
                             }
                             free(folder_timestamp_str);
+                            folder_timestamp_str = NULL;
                         }
                     }
                 }
                 free(download_url);
+                download_url = NULL;
             }
             
             search_pos = url_end + 1;
@@ -1481,6 +1500,7 @@ static void agnss_process_complete_response(void)
                 closedir(dir);
             }
             free(selected_folder_path);
+            selected_folder_path = NULL;
         } else {
             printf("没有找到符合条件的时间戳文件夹\n");
         }
@@ -1554,6 +1574,7 @@ static void agnss_process_complete_response(void)
                                                 }
                                             }
                                             free(temp_url);
+                                            temp_url = NULL;
                                         }
                                     }
                                 }
@@ -1628,6 +1649,7 @@ static void agnss_process_complete_response(void)
                                 char *url_start = strstr(item_start, "\"downloadUrl\":\"");
                                 if (!url_start) {
                                     free(filename);  // 释放内存
+                                    filename = NULL;
                                     item_start++;
                                     continue;
                                 }
@@ -1636,6 +1658,7 @@ static void agnss_process_complete_response(void)
                                 char *url_end = strchr(url_start, '"');
                                 if (!url_end) {
                                     free(filename);  // 释放内存
+                                    filename = NULL;
                                     item_start++;
                                     continue;
                                 }
@@ -1643,6 +1666,7 @@ static void agnss_process_complete_response(void)
                                 int url_len = url_end - url_start;
                                 if (url_len <= 0 || url_len >= 512) {
                                     free(filename);  // 释放内存
+                                    filename = NULL;
                                     item_start++;
                                     continue;
                                 }
@@ -1652,6 +1676,7 @@ static void agnss_process_complete_response(void)
                                 if (download_url == NULL) {
                                     printf("Error: Failed to allocate memory for download_url (item: %d)\n", total_item_count);
                                     free(filename);  // 释放内存
+                                    filename = NULL;
                                     item_start++;
                                     continue;
                                 }
@@ -1664,8 +1689,8 @@ static void agnss_process_complete_response(void)
                                 if (folder_timestamp == 0) {
                                     printf("Warning: Failed to extract folder timestamp from URL (item: %d, url: %s)\n",
                                         total_item_count, download_url);
-                                    free(filename);
-                                    free(download_url);
+                                    free(filename); filename = NULL;
+                                    free(download_url); download_url = NULL;
                                     item_start++;
                                     continue;
                                 }
@@ -1703,8 +1728,8 @@ static void agnss_process_complete_response(void)
 
                                 
                                 // 释放内存
-                                free(filename);
-                                free(download_url);
+                                free(filename); filename = NULL;
+                                free(download_url); download_url = NULL;
                                 
                                 // 移动到下一个文件项
                                 char *next_item = strstr(item_start, "},");
@@ -1725,6 +1750,8 @@ static void agnss_process_complete_response(void)
                                 printf("没有找到符合条件的时间戳文件夹,跳过下载\n");
                             }
                             free(selected_timestamp_str);
+                            selected_timestamp_str = NULL;
+
                     }
                     } else {
                         printf("没有找到符合条件的时间戳文件夹\n");
@@ -1783,7 +1810,7 @@ int download_agnss_file(const char *filename)
     
     // 释放内存
     free(full_url);
-    
+    full_url = NULL;
     if (result == HTTP_SUCCESS) {
         printf("File %s downloaded successfully\n", filename);
         return 0;
@@ -1816,6 +1843,7 @@ static BK_URL parse_url(const char *url) {
     if (!colon) {
         result.error = "Invalid URL: No protocol specified";
         free(temp_url);
+        temp_url = NULL;
         return result;
     }
     *colon = '\0';
@@ -1827,6 +1855,7 @@ static BK_URL parse_url(const char *url) {
     if (!slash) {
         result.error = "Invalid URL: No path specified";
         free(temp_url);
+        temp_url = NULL;
         return result;
     }
     *slash = '\0';
@@ -1839,6 +1868,7 @@ static BK_URL parse_url(const char *url) {
         if (!result.port) {
             result.error = "Invalid port number";
             free(temp_url);
+            temp_url = NULL;
             return result;
         }
     } else {
@@ -1864,6 +1894,7 @@ static BK_URL parse_url(const char *url) {
     }
     
     free(temp_url);
+    temp_url = NULL;
     return result;
 }
 
@@ -2000,7 +2031,8 @@ int download_agnss_files(void)
     
     // 释放URL内存
     free(full_url);
-    
+    full_url = NULL;
+
     if (result != HTTP_SUCCESS) {
         agnss_download_result_handler(NULL, result, 0, NULL, 0);
         // 下载失败,设置失败状态并清除标志位
@@ -2189,7 +2221,7 @@ static void gnss_http_server_send_task(void const *arg)
     gnss_http_data_mail_t mail = {0};
     uint32_t msgsize = sizeof(gnss_http_data_mail_t);
 
-    while (1) {
+    while (g_gnss_http_server_initialized) {
         ret = osal_msg_queue_read_copy(g_app_send_queue, (void *)&mail, &msgsize,
                                        OSAL_MSGQ_WAIT_FOREVER);
         if (ret != OSAL_SUCCESS) {
@@ -2204,6 +2236,7 @@ static void gnss_http_server_send_task(void const *arg)
             {
                 printf("free(mail.data)\n");
                 free(mail.data);
+                mail.data = NULL;
             }
         }
         else if(mail.cmd == GNSS_HTTP_SERVICE_CMD_SERVER_INIT)
@@ -2260,7 +2293,7 @@ static void gnss_http_server_recv_task(void const *arg)
     uint32_t msgsize = sizeof(gnss_http_data_mail_t);
 
 
-    while (1) {
+    while (g_gnss_http_server_initialized) {
         
         ret = osal_msg_queue_read_copy(g_app_recv_queue, (void *)&mail, &msgsize,
                                        OSAL_MSGQ_WAIT_FOREVER);
@@ -2283,7 +2316,7 @@ static void gnss_http_server_recv_task(void const *arg)
                 
                 // 释放消息队列中的数据内存
                 free(mail.data);
-                
+                mail.data = NULL;
                 // printf("数据片段处理完成,继续等待更多数据或完成信号\n");
             }
         }
@@ -2502,7 +2535,7 @@ int gnss_check_agnss_status(void)
     // 打印未来文件夹数量(调试用)
     // printf("future_folder_count : %d\n", future_folder_count);
 
-    // 返回剩余有效分钟数,并同步星历过期状态到 runtime(供 BLE 等查询)
+    // 返回剩余有效分钟数
     if (found_valid_folder) {
         uint32_t remaining_seconds = VALID_TIME_WINDOW - min_time_diff;
         int remaining_minutes = (int)(remaining_seconds / 60) + (future_folder_count * 24 * 60);
@@ -2782,6 +2815,9 @@ errcode_t uapi_gnss_http_server_deinit(void)
         PRINT("GNSS HTTP server not initialized\r\n");
         return ERRCODE_SUCC;
     }
+
+    g_gnss_http_server_initialized = 0;
+    
     int ret = 0;
     // 清理全局状态
     g_download_status = 0;
@@ -2843,7 +2879,6 @@ errcode_t uapi_gnss_http_server_deinit(void)
     memset(&recv_taskcfg, 0, sizeof(recv_taskcfg));
 
     // 标记为未初始化
-    g_gnss_http_server_initialized = 0;
     
     PRINT("GNSS HTTP server deinitialized successfully\r\n");
     return ERRCODE_SUCC;