gengxin
authorCCC <2393524978@qq.com>
Mon, 18 Dec 2023 01:47:19 +0000 (09:47 +0800)
committerCCC <2393524978@qq.com>
Mon, 18 Dec 2023 01:47:19 +0000 (09:47 +0800)
2.sdk/sdk/gui/lv_watch/lv_apps/custom_function/custom_function.c
2.sdk/sdk/gui/lv_watch/lv_apps/custom_function/custom_function.h
2.sdk/sdk/gui/lv_watch/lv_apps/custom_function/heng_ai_blood_pressure.c [new file with mode: 0644]
2.sdk/sdk/gui/lv_watch/lv_apps/custom_function/heng_ai_blood_pressure.h [new file with mode: 0644]
2.sdk/sdk/gui/lv_watch/lv_apps/custom_function/heng_ai_http_protocol.c [new file with mode: 0644]
2.sdk/sdk/gui/lv_watch/lv_apps/custom_function/heng_ai_http_protocol.h [new file with mode: 0644]

index 74082a6..09915ff 100644 (file)
@@ -9,6 +9,10 @@
 #include "heng_ai.c"
 #include "heng_ai_sleep_activation.c"
 #endif
+#ifdef __MMI_CUSTOM_HENG_AI_BLOOD_PRESSURE__
+#include "heng_ai_blood_pressure.c"
+#include "heng_ai_http_protocol.c"
+#endif
 
 #ifdef __MMI_CUSTOM_BEI_KE_RUI_SHENG__
 #include "bei_ke_rui_sheng.c"
index 0b70bb3..a27ef2c 100644 (file)
@@ -23,6 +23,10 @@ extern "C" {
 #include "heng_ai.h"
 #include "heng_ai_sleep_activation.h"
 #endif
+#ifdef __MMI_CUSTOM_HENG_AI_BLOOD_PRESSURE__
+#include "heng_ai_blood_pressure.h"
+#include "heng_ai_http_protocol.h"
+#endif
 
 #ifdef __MMI_CUSTOM_BEI_KE_RUI_SHENG__
 #include "bei_ke_rui_sheng.h"
diff --git a/2.sdk/sdk/gui/lv_watch/lv_apps/custom_function/heng_ai_blood_pressure.c b/2.sdk/sdk/gui/lv_watch/lv_apps/custom_function/heng_ai_blood_pressure.c
new file mode 100644 (file)
index 0000000..a146aa8
--- /dev/null
@@ -0,0 +1,1773 @@
+
+
+
+#include "lv_watch.h"
+
+#ifdef __MMI_CUSTOM_HENG_AI_BLOOD_PRESSURE__
+
+static uint8_t s_hengai_bp_calibrated = 0; // 0-not calibrated; 1-calibrated
+static const lv_point_t s_hengai_bp_valid_pos[] = {{0, 0}, {1, 0}, {2, 0}};
+static uint8_t s_hengai_bp_measure_count = 0;
+static uint8_t s_hengai_bp_calibrate_times = 0;
+static uint16_t s_bp_value_high = 0, s_bp_value_low = 0;
+
+
+void mmi_heng_ai_bp_raw_data_save(void){}
+
+void mmi_heng_ai_bp_raw_data_send(void){}
+
+void mmi_heng_ai_bp_calibrate_input_value_send(void){}
+
+
+
+// 0-ring; 1-vibrator
+void mmi_heng_ai_wake_ring_type_set(uint8_t ring_type)
+{
+       nv_watch_switch_t ring_type_data = {0};
+       uint32_t nv_data_length = sizeof(nv_watch_switch_t);
+       
+       ring_type_data.switch_flag = ring_type;
+       if(nv_data_length != UI_NV_Write_Req(NV_SECTION_UI_HENG_AI_WAKE_RING_TYPE, 0, nv_data_length, (uint8_t *)&ring_type_data))
+       {
+               printf("[@CHENG_DEBUG][%s][%d]: nv write fail\n", __FUNCTION__, __LINE__);
+       }
+}
+
+uint8_t mmi_heng_ai_wake_ring_type_get(void)
+{
+       nv_watch_switch_t ring_type_data = {0};
+       uint32_t nv_data_length = sizeof(nv_watch_switch_t);
+
+       if(nv_data_length != UI_NV_Read_Req(NV_SECTION_UI_HENG_AI_WAKE_RING_TYPE, 0, nv_data_length, (uint8_t *)&ring_type_data))
+       {
+               printf("[@CHENG_DEBUG][%s][%d]: nv read fail\n", __FUNCTION__, __LINE__);
+       }
+
+       return (ring_type_data.switch_flag);
+}
+
+
+bool mmi_heng_ai_warning_screen_is_active(void)
+{
+       lv_obj_t * activity_obj = lv_watch_get_activity_obj(ACT_ID_HENG_AI_WARNING);
+       if(NULL != activity_obj) 
+               return true;
+
+       return false;
+}
+
+static lv_remind_obj_ext_t * mmi_heng_ai_warning_screen_ext_get(void)
+{
+       lv_obj_t * activity_obj = lv_watch_get_activity_obj(ACT_ID_HENG_AI_WARNING);
+       if(NULL == activity_obj) 
+               return NULL;
+       
+       lv_obj_t * watch_obj = NULL;
+       lv_watch_get_child_obj(activity_obj, lv_watch_obj_signal, &watch_obj);
+       if(NULL != watch_obj) 
+       {
+               void * ext = lv_obj_get_ext_attr(watch_obj);
+               return ext;
+       }
+
+       return NULL;
+}
+
+static void mmi_heng_ai_warning_screen_prepare_destory(lv_obj_t * activity_obj)
+{
+    lv_watch_png_cache_all_free();
+
+       Hal_Vibrator_Play_End();
+
+    Hal_Tone_Play_End();
+    Hal_Audio_Manage_End_Ind(AUDIO_CTRL_PRIORITY_REMIND);
+
+       printf("[@CHENG_DEBUG][%s][%d]: 0x%x\n", __FUNCTION__, __LINE__, s_heng_ai_warning_info.prompt_str);
+       if(NULL != s_heng_ai_warning_info.prompt_str)
+       {
+               lv_mem_free(s_heng_ai_warning_info.prompt_str);
+               s_heng_ai_warning_info.prompt_str = NULL;
+       }
+
+       lv_heng_ai_warning_obj_ext_t * ext = mmi_heng_ai_warning_screen_ext_get();
+    if(ext)
+       {
+        if(NULL != ext->timer_id)
+               {
+            Hal_Timer_Stop(ext->timer_id);
+                       ext->timer_id = NULL;
+        }
+    }
+
+    watch_set_suspend_enable(true, ACT_ID_HENG_AI_WARNING, 0);
+}
+
+void mmi_heng_ai_warning_screen_clean(void)
+{
+       mmi_heng_ai_warning_screen_prepare_destory(NULL);
+       
+    lv_obj_t * activity_obj = lv_watch_get_activity_obj(ACT_ID_HENG_AI_WARNING);
+    if(NULL != activity_obj)
+       {
+               printf("[@CHENG_DEBUG][%s][%d]: \n", __FUNCTION__, __LINE__);
+        lv_obj_del(activity_obj);
+    }
+}
+
+void mmi_heng_ai_warning_btn_event_cb(lv_obj_t * obj, lv_event_t e)
+{
+       if(LV_EVENT_CLICKED == e)
+       {
+               mmi_heng_ai_warning_screen_clean();
+       }
+}
+
+static void mmi_heng_ai_warning_screen_timeout(void * para)
+{
+       mmi_heng_ai_warning_screen_clean();
+}
+
+static lv_obj_t * mmi_heng_ai_warning_screen_create(lv_obj_t * activity_obj)
+{
+       printf("[@CHENG_DEBUG][%s][%d]: \n", __FUNCTION__, __LINE__);
+       if(NULL == activity_obj)
+       {
+               lv_watch_activity_ext_t activity_ext = {0};
+
+               activity_ext.actId = ACT_ID_HENG_AI_WARNING;
+               activity_ext.create = mmi_heng_ai_warning_screen_create;
+               activity_ext.prepare_destory = mmi_heng_ai_warning_screen_prepare_destory;
+               activity_obj = lv_watch_creat_activity_obj(&activity_ext);
+               if(NULL == activity_obj)
+                       return NULL;
+       }
+
+       /* watch obj */
+       lv_obj_t * obj = lv_watch_obj_create(activity_obj);
+       lv_watch_obj_set_anim_mode(obj, LV_WATCH_ANIM_HOR_RIGHT_HIDE);
+       lv_heng_ai_warning_obj_ext_t * ext = (lv_heng_ai_warning_obj_ext_t *)lv_obj_allocate_ext_attr(obj, sizeof(lv_heng_ai_warning_obj_ext_t));
+
+       lv_obj_t * cont = lv_cont_create(obj, NULL);
+       lv_obj_set_size(cont, LV_HOR_RES, LV_VER_RES);
+       lv_obj_set_style_local_bg_color(cont, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_BLACK);
+       //lv_obj_set_style_local_bg_color(cont, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_BLACK);
+       lv_obj_set_click(cont, false);
+
+       hal_rtc_t cur_time;
+       char time_str[8] = {0};
+       
+       Hal_Rtc_Gettime(&cur_time);
+       sprintf(time_str, "%02d:%02d", cur_time.tm_hour, cur_time.tm_min);
+       
+       lv_obj_t * label_time = lv_label_create(cont, NULL);
+       lv_obj_add_style(label_time, LV_LABEL_PART_MAIN, &lv_watch_font26);
+       lv_label_set_text(label_time, time_str);
+       lv_label_set_align(label_time, LV_LABEL_ALIGN_CENTER);
+       lv_obj_align(label_time, NULL, LV_ALIGN_IN_TOP_MID, 0, 50);
+
+       lv_obj_t * label_prompt = lv_label_create(cont, NULL);
+       lv_obj_add_style(label_prompt, LV_LABEL_PART_MAIN, &lv_watch_font26);
+       lv_label_set_align(label_prompt, LV_LABEL_ALIGN_CENTER);
+       lv_label_set_long_mode(label_prompt, LV_LABEL_LONG_BREAK);
+       lv_obj_set_width(label_prompt, lv_obj_get_width(obj) - 20);
+       lv_label_set_text(label_prompt, s_heng_ai_warning_info.prompt_str);
+       lv_obj_align(label_prompt, label_time, LV_ALIGN_OUT_BOTTOM_MID, 0, 10);
+       
+
+       lv_obj_t * btn = lv_btn_create(cont, NULL);
+       lv_obj_set_size(btn, 100, 56);
+       lv_obj_set_style_local_bg_color(btn, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, lv_color_make(0x47, 0xA6, 0xFF));
+       lv_obj_set_style_local_radius(btn, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 30);
+       lv_obj_set_style_local_bg_color(btn, LV_BTN_PART_MAIN, LV_STATE_PRESSED, lv_color_make(0x47, 0xA6, 0xFF));
+       lv_obj_set_style_local_radius(btn, LV_BTN_PART_MAIN, LV_STATE_PRESSED, 30);
+       lv_obj_align(btn, NULL, LV_ALIGN_IN_BOTTOM_MID, 0, -20);
+       lv_obj_set_event_cb(btn, mmi_heng_ai_warning_btn_event_cb);
+
+       lv_obj_t * label = lv_label_create(btn, NULL);
+       lv_obj_add_style(label, LV_LABEL_PART_MAIN, &lv_watch_font26);
+       lv_label_set_text_id(label, WATCH_TEXT_ID_OK);
+       
+       /* start timer (1 min) */
+       ext->timer_id = Hal_Timer_Start(1000 * 60, mmi_heng_ai_warning_screen_timeout, NULL, false);
+
+       watch_set_suspend_enable(false, ACT_ID_HENG_AI_WARNING, 0);
+
+       return obj;
+}
+
+
+
+
+lv_heart_rate_obj_ext_t * health_heart_rate_get_ext(void)
+{
+    lv_obj_t * activity_obj = lv_watch_get_activity_obj(ACT_ID_HEALTH_MEASURE_HEART);
+    if(NULL == activity_obj)
+       {
+               return NULL;
+       }
+
+    lv_obj_t * watch_obj;
+    lv_watch_get_child_obj(activity_obj, lv_watch_obj_signal, &watch_obj);
+    if(NULL != watch_obj) 
+       {
+        lv_heart_rate_obj_ext_t * ext = lv_obj_get_ext_attr(watch_obj);
+        return ext;
+    }
+    return NULL;
+}
+
+void health_heart_rate_display_update(void)
+{
+       lv_heart_rate_obj_ext_t * ext = health_heart_rate_get_ext();
+       if(NULL == ext)
+       {
+               return;
+       }
+
+       switch(ext->measure_state)
+       {
+               case STATE_HEART_RATE_MEASURING:
+                       lv_obj_set_hidden(ext->img, TRUE);
+
+                       lv_label_set_text_id(ext->label_info, WATCH_TEXT_ID_MEASURING);
+                       lv_obj_align(ext->label_info, ext->cont, LV_ALIGN_IN_TOP_MID, 0, HEART_LABEL_INFO_Y);
+
+                       lv_label_set_text(ext->label_value, ext->heart_rate);
+                       lv_obj_align(ext->label_value, ext->cont, LV_ALIGN_IN_TOP_MID, 0, HEART_LABEL_VALUE_Y);
+                       lv_obj_set_hidden(ext->label_value, ((strlen(ext->heart_rate)) ? FALSE : TRUE));
+                       break;
+
+               case STATE_HEART_RATE_MEASURE_FAIL:
+                       lv_img_set_src(ext->img, ICON_HEART_RATE_MEASURE_FAIL);
+                       lv_obj_set_hidden(ext->img, FALSE);
+
+                       lv_label_set_text_id(ext->label_info, WATCH_TEXT_ID_MEASURE_FAIL);
+                       lv_obj_align(ext->label_info, ext->cont, LV_ALIGN_IN_TOP_MID, 0, HEART_LABEL_INFO_Y);
+
+                       lv_obj_remove_style(ext->label_value, LV_LABEL_PART_MAIN, &lv_watch_font40);
+                       lv_obj_add_style(ext->label_value, LV_LABEL_PART_MAIN, &lv_watch_font30);
+                       lv_label_set_text_id(ext->label_value, WATCH_TEXT_ID_NOT_WEAR);
+                       lv_obj_align(ext->label_value, ext->cont, LV_ALIGN_IN_TOP_MID, 0, HEART_LABEL_VALUE_Y);
+                       lv_obj_set_hidden(ext->label_value, FALSE);
+                       break;
+
+               case STATE_HEART_RATE_MEASURE_DONE:
+                       lv_img_set_src(ext->img, ICON_HEART_RATE_MEASURE_DONE);
+                       lv_obj_set_hidden(ext->img, FALSE);
+
+                       lv_label_set_text_id(ext->label_info, WATCH_TEXT_ID_MEASURE_DONE);
+                       lv_obj_align(ext->label_info, ext->cont, LV_ALIGN_IN_TOP_MID, 0, HEART_LABEL_INFO_Y);
+
+                       lv_label_set_text(ext->label_value, ext->heart_rate);
+                       lv_obj_align(ext->label_value, ext->cont, LV_ALIGN_IN_TOP_MID, 0, HEART_LABEL_VALUE_Y);
+                       lv_obj_set_hidden(ext->label_value, FALSE);
+                       break;
+
+               default:
+                       break;
+       }
+}
+
+
+lv_heng_ai_bp_obj_ext_t * mmi_heng_ai_bp_ext_get(void)
+{
+    lv_obj_t * activity_obj = lv_watch_get_activity_obj(ACT_ID_HENG_AI_BP);
+    if(activity_obj == NULL)
+               return NULL;
+
+       lv_obj_t * watch_obj = NULL;
+       lv_watch_get_child_obj(activity_obj, lv_watch_obj_signal, &watch_obj);
+       if(NULL == watch_obj) 
+               return NULL;
+       
+       lv_heng_ai_bp_obj_ext_t * ext = NULL;
+       ext = lv_obj_get_ext_attr(watch_obj);
+       
+       return ext;
+}
+
+static void mmi_heng_ai_blood_pressure_screen_prepare_destory(lv_obj_t * activity_obj)
+{
+       HEALTH_MEASURE_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: \n", __FUNCTION__, __LINE__);
+       
+    watch_set_suspend_enable(true, ACT_ID_HENG_AI_BP, 0);
+    lv_watch_png_cache_all_free();
+       
+    //lv_obj_t * watch_obj = NULL;
+    //lv_watch_get_child_obj(act, lv_watch_obj_signal, &watch_obj);
+    //lv_obj_t * cont = lv_obj_get_child(watch_obj, NULL);
+
+       lv_heart_rate_obj_ext_t * ext = health_heart_rate_get_ext();
+    if(NULL != ext) 
+       {
+               if(NULL != ext->cycle_timer_id)
+               {
+                       Hal_Timer_Stop(ext->cycle_timer_id);
+                       ext->cycle_timer_id = NULL;
+               }
+               if(NULL != ext->gif_info)
+               {
+                       gif_close(ext->gif_info);
+                       ext->gif_info = NULL;
+               }
+               if(STATE_HEART_RATE_MEASURING == ext->measure_state)
+               {
+                       mmi_health_measure_interrupt();
+               }
+
+               HEALTH_MEASURE_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: \n", __FUNCTION__, __LINE__);
+       }
+}
+
+void mmi_heng_ai_blood_pressure_screen_clean(void)
+{
+       lv_obj_t * activity_obj = lv_watch_get_activity_obj(ACT_ID_HENG_AI_BP);
+       if(NULL != activity_obj)
+       {
+               printf("[@CHENG_DEBUG][%s][%d]: \n", __FUNCTION__, __LINE__);
+               mmi_heng_ai_blood_pressure_screen_prepare_destory(NULL);
+               lv_obj_del(activity_obj);
+       }
+}
+
+
+lv_obj_t * mmi_heng_ai_bp_tileview_add_tile(lv_obj_t * tileview, uint16_t id)
+{
+    lv_tileview_ext_t * ext = lv_obj_get_ext_attr(tileview);
+    lv_obj_t * cont = lv_cont_create(tileview, NULL);
+    lv_obj_add_style(cont, LV_CONT_PART_MAIN, &lv_style_transp_tight);
+    lv_obj_set_size(cont, LV_HOR_RES, LV_VER_RES);
+    lv_obj_set_x(cont, LV_HOR_RES * ext->valid_pos[id].x);
+    lv_tileview_add_element(tileview, cont);
+    lv_obj_set_click(cont, false);
+    return cont;
+}
+
+
+
+// measure mode
+void * mmi_heng_ai_bp_measure_screen_ext_get(void)
+{
+       lv_obj_t * activity_obj = lv_watch_get_activity_obj(ACT_ID_HENG_AI_BP_MEASURE);
+       if(activity_obj == NULL)
+               return NULL;
+
+       lv_obj_t * watch_obj = NULL;
+       lv_watch_get_child_obj(activity_obj, lv_watch_obj_signal, &watch_obj);
+       if(NULL == watch_obj) 
+               return NULL;
+       
+       void * ext = lv_obj_get_ext_attr(watch_obj);
+       
+       return ext;
+}
+
+void mmi_heng_ai_bp_measure_screen_prepare_destory(lv_obj_t * activity_obj)
+{
+    watch_set_suspend_enable(true, ACT_ID_HENG_AI_BP_MEASURE, 0);
+    lv_watch_png_cache_all_free();
+
+       lv_heng_ai_bp_measure_ext_t * watch_ext = (lv_heng_ai_bp_measure_ext_t *)mmi_heng_ai_bp_measure_screen_ext_get();
+       if(NULL != watch_ext)
+       {
+               if(NULL != watch_ext->measure_timer_id)
+               {
+                       Hal_Timer_Stop(watch_ext->measure_timer_id);
+                       watch_ext->measure_timer_id = NULL;
+               }
+               if(NULL != watch_ext->result_timer_id)
+               {
+                       Hal_Timer_Stop(watch_ext->result_timer_id);
+                       watch_ext->result_timer_id = NULL;
+               }
+               if(NULL != watch_ext->gif_info)
+               {
+                       gif_close(watch_ext->gif_info);
+                       watch_ext->gif_info = NULL;
+               }
+       }
+}
+
+void mmi_heng_ai_bp_measure_screen_clean(void)
+{
+       lv_obj_t * activity_obj = lv_watch_get_activity_obj(ACT_ID_HENG_AI_BP_MEASURE);
+       if(NULL != activity_obj)
+       {
+               printf("[@CHENG_DEBUG][%s][%d]: \n", __FUNCTION__, __LINE__);
+               mmi_heng_ai_bp_measure_screen_prepare_destory(NULL);
+               lv_obj_del(activity_obj);
+       }
+}
+
+void mmi_heng_ai_bp_measure_result_screen_event_cb(lv_obj_t * obj, lv_event_t e)
+{
+       if(LV_EVENT_CLICKED != e)
+               return;
+
+    printf("[@CHENG_DEBUG][%s][%d]: \n", __FUNCTION__, __LINE__);
+       mmi_heng_ai_bp_measure_screen_clean();
+}
+
+
+// 0-ok; 1-high; 2-low; 3-fail
+void mmi_heng_ai_bp_measure_result_screen(uint8_t result)
+{
+       lv_heng_ai_bp_measure_ext_t * watch_ext = (lv_heng_ai_bp_measure_ext_t *)mmi_heng_ai_bp_measure_screen_ext_get();
+       if(NULL == watch_ext)
+               return;
+
+       if(NULL != watch_ext->measure_timer_id)
+       {
+               Hal_Timer_Stop(watch_ext->measure_timer_id);
+               watch_ext->measure_timer_id = NULL;
+       }
+       if(NULL != watch_ext->result_timer_id)
+       {
+               Hal_Timer_Stop(watch_ext->result_timer_id);
+               watch_ext->result_timer_id = NULL;
+       }
+       if(NULL != watch_ext->gif_info)
+       {
+               gif_close(watch_ext->gif_info);
+               watch_ext->gif_info = NULL;
+       }
+       lv_obj_clean(watch_ext->cont);
+
+       uint32_t label_title_text_id[] = {WATCH_TEXT_ID_CALIBRATE_SUCCESS,
+                                                                               WATCH_TEXT_ID_BLOOD_PRESSURE_HIGH,
+                                                                               WATCH_TEXT_ID_BLOOD_PRESSURE_LOW,
+                                                                               WATCH_TEXT_ID_CALIBRATE_FAILED};
+       
+       lv_obj_t * label_title = lv_label_create(watch_ext->cont, NULL);
+       lv_obj_add_style(label_title, LV_LABEL_PART_MAIN, &lv_watch_font32);
+       lv_label_set_align(label_title, LV_LABEL_ALIGN_CENTER);
+       lv_label_set_text_id(label_title, label_title_text_id[result]);
+       lv_obj_align(label_title, NULL, LV_ALIGN_IN_TOP_MID, 0, 48);
+       lv_obj_set_click(label_title, false);
+       
+       if(3 == result)
+       {
+               lv_obj_t * img = lv_img_create(watch_ext->cont, NULL);
+               lv_img_set_src(img, ICON_HENGAI_BP_ALERT);
+               lv_obj_align(img, NULL, LV_ALIGN_IN_TOP_MID, 0, 104);
+                                       
+               lv_obj_t * label_prompt = lv_label_create(watch_ext->cont, NULL);
+               lv_obj_add_style(label_prompt, LV_LABEL_PART_MAIN, &lv_watch_font28);
+               lv_label_set_align(label_prompt, LV_LABEL_ALIGN_CENTER);
+               lv_label_set_long_mode(label_prompt, LV_LABEL_LONG_BREAK);
+               lv_obj_set_width(label_prompt, 400);
+               lv_label_set_text_id(label_prompt, label_prompt_text_id);
+               lv_obj_align(label_prompt, NULL, LV_ALIGN_IN_TOP_MID, 0, 292);
+       }
+       else
+       {
+               lv_obj_t * label_title_high = lv_label_create(watch_ext->cont, NULL);
+               lv_obj_add_style(label_title_high, LV_LABEL_PART_MAIN, &lv_watch_font24);
+               lv_label_set_align(label_title_high, LV_LABEL_ALIGN_CENTER);
+               lv_label_set_text_id(label_title_high, WATCH_TEXT_ID_SYSTOLIC_BP);
+               lv_obj_align(label_title_high, NULL, LV_ALIGN_IN_TOP_LEFT, 103, 104);
+               lv_obj_set_click(label_title_high, false);
+
+               lv_obj_t * label_value_high = lv_label_create(watch_ext->cont, NULL);
+               lv_obj_add_style(label_value_high, LV_LABEL_PART_MAIN, &lv_watch_font60);
+               lv_label_set_align(label_value_high, LV_LABEL_ALIGN_CENTER);
+               char value_str[4] = {0};
+               sprintf(value_str, "%d", s_bp_value_high);
+               lv_label_set_text(label_value_high, value_str);
+               lv_obj_align(label_value_high, label_title_high, LV_ALIGN_OUT_BOTTOM_MID, 0, 10);
+               lv_obj_set_click(label_value_high, false);
+
+               lv_obj_t * label_uint_high = lv_label_create(watch_ext->cont, NULL);
+               lv_obj_add_style(label_uint_high, LV_LABEL_PART_MAIN, &lv_watch_font24);
+               lv_label_set_align(label_uint_high, LV_LABEL_ALIGN_CENTER);
+               lv_label_set_text(label_uint_high, "mmHg");
+               lv_obj_align(label_uint_high, label_value_high, LV_ALIGN_OUT_BOTTOM_MID, 0, 15);
+               lv_obj_set_click(label_uint_high, false);
+
+               lv_obj_t * label_title_low = lv_label_create(watch_ext->cont, label_title_high);
+               lv_label_set_text_id(label_title_low, WATCH_TEXT_ID_DIASTOLIC_BP);
+               lv_obj_align(label_title_low, NULL, LV_ALIGN_IN_TOP_LEFT, 280, 104);
+
+               lv_obj_t * label_value_low = lv_label_create(watch_ext->cont, label_value_high);
+               sprintf(value_str, "%d", s_bp_value_low);
+               lv_label_set_text(label_value_low, value_str);
+               lv_obj_align(label_value_low, label_title_low, LV_ALIGN_OUT_BOTTOM_MID, 0, 10);
+               
+               lv_obj_t * label_uint_low = lv_label_create(watch_ext->cont, label_uint_high);
+               lv_label_set_text(label_uint_low, "mmHg");
+               lv_obj_align(label_uint_low, label_value_low, LV_ALIGN_OUT_BOTTOM_MID, 0, 15);
+
+               hal_rtc_t cur_time = {0};
+               char time_str[24] = {0};
+               
+               Hal_Rtc_Gettime(&cur_time);
+               sprintf(time_str, "%02d/%02d/%04d %02d:%02d", cur_time.tm_mon, cur_time.tm_mday, cur_time.tm_year, cur_time.tm_hour, cur_time.tm_min);
+
+               lv_obj_t * label_time = lv_label_create(watch_ext->cont, NULL);
+               lv_obj_add_style(label_time, LV_LABEL_PART_MAIN, &lv_watch_font28);
+               lv_label_set_align(label_time, LV_LABEL_ALIGN_CENTER);
+               lv_label_set_text(label_time, time_str);
+               lv_obj_align(label_time, NULL, LV_ALIGN_IN_TOP_MID, 0, 304);
+               lv_obj_set_click(label_time, false);
+       }
+       
+       lv_obj_t * imgbtn = lv_imgbtn_create(watch_ext->cont, NULL);
+       lv_imgbtn_set_src(imgbtn, LV_BTN_STATE_RELEASED, ICON_HENGAI_BP_BOTTOM_BTN_BG);
+       lv_imgbtn_set_src(imgbtn, LV_BTN_STATE_PRESSED, ICON_HENGAI_BP_BOTTOM_BTN_BG);
+       lv_obj_align(imgbtn, NULL, LV_ALIGN_IN_BOTTOM_MID, 0, 0);
+       lv_obj_set_event_cb(imgbtn, mmi_heng_ai_bp_measure_result_screen_event_cb);
+
+       lv_obj_t * btn_label = lv_label_create(imgbtn, NULL);
+       lv_obj_add_style(btn_label, LV_LABEL_PART_MAIN, &lv_watch_font32);
+       lv_label_set_align(btn_label, LV_LABEL_ALIGN_CENTER);
+       lv_label_set_text_id(btn_label, WATCH_TEXT_ID_OK);
+       lv_obj_align(btn_label, NULL, LV_ALIGN_CENTER, 0, 0);
+}
+
+void mmi_heng_ai_bp_measure_result_timeout(void * para)
+{
+       lv_heng_ai_bp_measure_ext_t * watch_ext = (lv_heng_ai_bp_measure_ext_t *)mmi_heng_ai_bp_measure_screen_ext_get();
+       if(NULL == watch_ext)
+               return;
+       
+       if(NULL != watch_ext->result_timer_id)
+       {
+               Hal_Timer_Stop(watch_ext->result_timer_id);
+               watch_ext->result_timer_id = NULL;
+       }
+       if(NULL != watch_ext->gif_info)
+       {
+               gif_close(watch_ext->gif_info);
+               watch_ext->gif_info = NULL;
+       }
+
+       mmi_heng_ai_bp_measure_result_screen(3);
+}
+
+void mmi_heng_ai_bp_measure_cycle_timeout(void * para)
+{
+       s_hengai_bp_measure_count++;
+
+       mmi_heng_ai_bp_raw_data_save();
+       
+       if(0 == (s_hengai_bp_measure_count % MMI_BP_MEASURE_SEND_DATA_COUNT)) // send raw data per 10s
+       {
+               mmi_heng_ai_bp_raw_data_send();
+       }
+       
+       if(MMI_BP_MEASURE_TOTAL_COUNT == s_hengai_bp_measure_count) // stop action when 60s
+       {
+               // close sensor
+               mmi_close_sensor();
+               
+               lv_heng_ai_bp_measure_ext_t * watch_ext = (lv_heng_ai_bp_measure_ext_t *)mmi_heng_ai_bp_measure_screen_ext_get();
+               if(NULL == watch_ext)
+                       return;
+               
+               if(NULL != watch_ext->measure_timer_id)
+               {
+                       Hal_Timer_Stop(watch_ext->measure_timer_id);
+                       watch_ext->measure_timer_id = NULL;
+               }
+               watch_ext->result_timer_id = Hal_Timer_Start(MMI_BP_WAIT_RESULT_TIMEOUT, mmi_heng_ai_bp_measure_result_timeout, NULL, false);
+       }
+}
+
+void mmi_heng_ai_bp_measure_start_btn_event_cb(lv_obj_t * obj, lv_event_t e)
+{
+       if(LV_EVENT_CLICKED != e)
+               return;
+
+       lv_heng_ai_bp_measure_ext_t * watch_ext = (lv_heng_ai_bp_measure_ext_t *)mmi_heng_ai_bp_measure_screen_ext_get();
+       if(NULL == watch_ext)
+               return;
+
+       if(NULL == watch_ext->tileview)
+               return;
+
+       lv_obj_t * watch_obj = lv_obj_get_parent(watch_ext->tileview);
+       lv_obj_del(watch_ext->tileview);
+       lv_watch_obj_set_anim_mode(watch_obj, LV_WATCH_ANIM_HOR_RIGHT_HIDE);
+
+       lv_obj_t * cont = lv_cont_create(watch_obj, NULL);
+       lv_obj_set_size(cont, LV_HOR_RES, LV_VER_RES);
+       lv_obj_set_style_local_bg_color(cont, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_BLACK);
+       lv_obj_set_click(cont, false);
+       watch_ext->cont = cont;
+       
+       if(false == mmi_health_measure_wear_state_get())
+       {
+               lv_obj_t * img = lv_img_create(cont, NULL);
+               lv_img_set_src(img, ICON_HENGAI_BP_ALERT);
+               lv_obj_align(img, NULL, LV_ALIGN_IN_TOP_MID, 0, 90);
+               
+               lv_obj_t * label_1 = lv_label_create(cont, NULL);
+               lv_obj_add_style(label_1, LV_LABEL_PART_MAIN, &lv_watch_font36);
+               lv_label_set_text_id(label_1, WATCH_TEXT_ID_DEVICE_NOT_WEAR);
+               lv_label_set_align(label_1, LV_LABEL_ALIGN_CENTER);
+               lv_obj_align(label_1, NULL, LV_ALIGN_IN_TOP_MID, 0, 278);
+               lv_obj_set_click(label_1, false);
+       }
+       else
+       {
+               mmi_open_sensor();
+
+               gif_info_t * gif_info = gif_open(cont, ANIM_HENGAI_BP_MEASURE, 0);
+               if(NULL == gif_info)
+                       return;
+               lv_obj_align(gif_info->container, NULL, LV_ALIGN_IN_TOP_MID, 0, 104);
+               watch_ext->gif_info = gif_info;
+
+               lv_obj_t * label = lv_label_create(cont, NULL);
+               lv_obj_add_style(label, LV_LABEL_PART_MAIN, &lv_watch_font28);
+               lv_label_set_align(label, LV_LABEL_ALIGN_CENTER);
+               lv_label_set_text_id(label, WATCH_TEXT_ID_IN_MEASURE_PROMPT);
+               lv_obj_align(label, NULL, LV_ALIGN_IN_TOP_MID, 0, 292);
+               lv_obj_set_click(label, false);
+
+               /* start timer (1 min) */
+               s_hengai_bp_measure_count = 0;
+               watch_ext->measure_timer_id = Hal_Timer_Start(1000, mmi_heng_ai_bp_measure_cycle_timeout, NULL, true);
+       }
+}
+
+lv_obj_t * mmi_heng_ai_bp_measure_tab_0(lv_obj_t * tileview, uint16_t id)
+{
+       lv_obj_t * tab = mmi_heng_ai_bp_tileview_add_tile(tileview, id);
+       if(NULL == tab)
+               return NULL;
+       
+       lv_obj_t * label_title = lv_label_create(tab, NULL);
+       lv_obj_add_style(label_title, LV_LABEL_PART_MAIN, &lv_watch_font32);
+       lv_label_set_align(label_title, LV_LABEL_ALIGN_CENTER);
+       lv_label_set_text_id(label_title, WATCH_TEXT_ID_MEASURE_PROMPT);
+       lv_obj_align(label_title, NULL, LV_ALIGN_IN_TOP_MID, 0, 48);
+       lv_obj_set_click(label_title, false);
+
+       lv_obj_t * img = lv_img_create(tab, NULL);
+       lv_img_set_src(img, ICON_HENGAI_BP_PROMPT_0);
+       lv_obj_align(img, NULL, LV_ALIGN_IN_TOP_MID, 0, 104);
+
+       lv_obj_t * label_prompt = lv_label_create(tab, NULL);
+       lv_obj_add_style(label_prompt, LV_LABEL_PART_MAIN, &lv_watch_font28);
+       lv_label_set_align(label_prompt, LV_LABEL_ALIGN_CENTER);
+       lv_label_set_long_mode(label_prompt, LV_LABEL_LONG_BREAK);
+       lv_obj_set_width(label_prompt, 400);
+       lv_label_set_text_id(label_prompt, WATCH_TEXT_ID_CALIBRATE_PROMPT_0);
+       lv_obj_align(label_prompt, NULL, LV_ALIGN_IN_TOP_MID, 0, 292);
+
+       return tab;
+}
+
+lv_obj_t * mmi_heng_ai_bp_measure_tab_1(lv_obj_t * tileview, uint16_t id)
+{
+       lv_obj_t * tab = mmi_heng_ai_bp_tileview_add_tile(tileview, id);
+       if(NULL == tab)
+               return NULL;
+       
+       lv_obj_t * label_title = lv_label_create(tab, NULL);
+       lv_obj_add_style(label_title, LV_LABEL_PART_MAIN, &lv_watch_font32);
+       lv_label_set_align(label_title, LV_LABEL_ALIGN_CENTER);
+       lv_label_set_text_id(label_title, WATCH_TEXT_ID_MEASURE_PROMPT);
+       lv_obj_align(label_title, NULL, LV_ALIGN_IN_TOP_MID, 0, 48);
+       lv_obj_set_click(label_title, false);
+
+       lv_obj_t * img = lv_img_create(tab, NULL);
+       lv_img_set_src(img, ICON_HENGAI_BP_PROMPT_1);
+       lv_obj_align(img, NULL, LV_ALIGN_IN_TOP_MID, 0, 104);
+
+       lv_obj_t * label_prompt = lv_label_create(tab, NULL);
+       lv_obj_add_style(label_prompt, LV_LABEL_PART_MAIN, &lv_watch_font28);
+       lv_label_set_align(label_prompt, LV_LABEL_ALIGN_CENTER);
+       lv_label_set_long_mode(label_prompt, LV_LABEL_LONG_BREAK);
+       lv_obj_set_width(label_prompt, 400);
+       lv_label_set_text_id(label_prompt, WATCH_TEXT_ID_CALIBRATE_PROMPT_1);
+       lv_obj_align(label_prompt, NULL, LV_ALIGN_IN_TOP_MID, 0, 292);
+
+       lv_obj_t * imgbtn = lv_imgbtn_create(tab, NULL);
+       lv_imgbtn_set_src(imgbtn, LV_BTN_STATE_RELEASED, ICON_HENGAI_BP_BOTTOM_BTN_BG);
+       lv_imgbtn_set_src(imgbtn, LV_BTN_STATE_PRESSED, ICON_HENGAI_BP_BOTTOM_BTN_BG);
+       lv_obj_align(imgbtn, NULL, LV_ALIGN_IN_BOTTOM_MID, 0, 0);
+       lv_obj_set_event_cb(imgbtn, mmi_heng_ai_bp_measure_start_btn_event_cb);
+
+       lv_obj_t * btn_label = lv_label_create(imgbtn, NULL);
+       lv_obj_add_style(btn_label, LV_LABEL_PART_MAIN, &lv_watch_font32);
+       lv_label_set_align(btn_label, LV_LABEL_ALIGN_CENTER);
+       lv_label_set_text_id(btn_label, WATCH_TEXT_ID_START_MEASURE);
+       lv_obj_align(btn_label, NULL, LV_ALIGN_CENTER, 0, 0);
+
+       return tab;
+}
+
+void mmi_heng_ai_bp_measure_screen_tileview_led(lv_obj_t * tileview)
+{
+       lv_heng_ai_bp_tileview_ext_t * ext = lv_obj_get_ext_attr(tileview);
+       if(NULL == ext)
+           return NULL;
+
+    if(NULL == ext->led_cont)
+       {
+        ext->led_cont = lv_cont_create(tileview, NULL);
+        lv_obj_set_base_dir(ext->led_cont, LV_BIDI_DIR_LTR);
+        lv_cont_set_fit(ext->led_cont, LV_FIT_TIGHT);
+        lv_cont_set_layout(ext->led_cont, LV_LAYOUT_ROW_MID);
+        lv_obj_add_style(ext->led_cont, LV_CONT_PART_MAIN, &lv_watch_style_transp);
+        lv_obj_set_click(ext->led_cont, false);
+    }
+
+       uint8_t i = 0;
+    for(i = 0; i < 2; i++)
+       {
+        if(NULL == ext->led[i])
+               {
+            ext->led[i] = lv_led_create(ext->led_cont, NULL);
+        }
+               
+        lv_led_off(ext->led[i]);
+        lv_obj_set_size(ext->led[i], 6, 6);
+    }
+       
+       lv_coord_t x = -1, y = -1;
+       lv_tileview_get_tile_act(tileview, &x, &y);
+       lv_led_on(ext->led[x]);
+       lv_obj_set_size(ext->led[x], 10, 10);
+    lv_obj_set_pos(ext->led_cont, LV_HOR_RES * x + (LV_HOR_RES - lv_obj_get_width(ext->led_cont)) / 2, 100);
+}
+
+void mmi_heng_ai_bp_measure_screen_tileview_event_cb(lv_obj_t * tileview, lv_event_t e)
+{
+       if(LV_EVENT_VALUE_CHANGED != e)
+               return;
+
+       mmi_heng_ai_bp_measure_screen_tileview_led(tileview);
+}
+
+lv_obj_t * mmi_heng_ai_bp_measure_screen_create(lv_obj_t * activity_obj)
+{
+    if(NULL == activity_obj) 
+       {
+        lv_watch_activity_ext_t activity_ext = {0};
+
+               activity_ext.actId = ACT_ID_HENG_AI_BP_MEASURE;
+               activity_ext.create = mmi_heng_ai_bp_measure_screen_create;
+               activity_ext.prepare_destory = mmi_heng_ai_bp_measure_screen_prepare_destory;
+        activity_obj = lv_watch_creat_activity_obj(&activity_ext);
+               if(NULL == activity_obj)
+                       return NULL;
+    }
+
+    lv_obj_t * watch_obj = lv_watch_obj_create(activity_obj);
+    LV_ASSERT_MEM(watch_obj);
+       if(NULL == watch_obj)
+               return NULL;
+       lv_watch_obj_set_anim_mode(watch_obj, LV_WATCH_ANIM_NO);
+       lv_heng_ai_bp_measure_ext_t * watch_ext = lv_obj_allocate_ext_attr(watch_obj, sizeof(lv_heng_ai_bp_measure_ext_t));
+       if(NULL == ext)
+               return NULL;
+       watch_ext->tileview = NULL;
+       watch_ext->cont = NULL;
+       watch_ext->gif_info = NULL;
+       watch_ext->measure_timer_id = NULL;
+       watch_ext->result_timer_id = NULL;
+       
+       lv_obj_t * tileview = lv_tileview_create(watch_obj, NULL);
+       if(NULL == tileview)
+               return NULL;
+       lv_heng_ai_bp_tileview_ext_t * ext = lv_obj_allocate_ext_attr(tileview, sizeof(lv_heng_ai_bp_tileview_ext_t));
+       if(NULL == ext)
+               return NULL;
+       
+       watch_ext->tileview = tileview;
+       ext->tab_0 = NULL;
+       ext->tab_1 = NULL;
+       ext->tab_2 = NULL;
+       ext->led_cont= NULL;
+       ext->led[0] = NULL;
+       ext->led[1] = NULL;
+       ext->led[2] = NULL;
+       
+       lv_tileview_set_valid_positions(tileview, s_hengai_bp_valid_pos, 2);
+       lv_tileview_set_edge_flash(tileview, true);
+       lv_tileview_set_anim_time(tileview, 60);
+       lv_page_set_scrollbar_mode(tileview, LV_SCROLLBAR_MODE_OFF);
+       lv_obj_add_style(tileview, LV_TILEVIEW_PART_EDGE_FLASH, &lv_watch_cont_opa1);
+       ext->tileview = tileview;
+
+       ext->tab_0 = mmi_heng_ai_bp_measure_tab_0(tileview, 0);
+       LV_ASSERT_MEM(ext->tab_0);
+       if(NULL == ext->tab_0)
+               return NULL;
+
+       ext->tab_1 = mmi_heng_ai_bp_measure_tab_1(tileview, 1);
+       LV_ASSERT_MEM(ext->tab_1);
+       if(NULL == ext->tab_1)
+               return NULL;
+
+       lv_tileview_set_tile_act(tileview, 0, 0, LV_ANIM_OFF);
+       lv_watch_obj_add_element(tileview);
+       lv_watch_obj_add_element(lv_page_get_scrl(tileview));
+       lv_obj_set_event_cb(tileview, mmi_heng_ai_bp_measure_screen_tileview_event_cb);
+
+       mmi_heng_ai_bp_measure_screen_tileview_led(tileview);
+
+       //
+       watch_set_suspend_enable(false, ACT_ID_HENG_AI_BP_MEASURE, 0);
+}
+
+void mmi_heng_ai_bp_measure_mode_btn_event_cb(lv_obj_t * obj, lv_event_t e)
+{
+       if(LV_EVENT_CLICKED != e)
+               return;
+
+       mmi_heng_ai_bp_measure_screen_create(NULL);
+}
+
+lv_obj_t * mmi_heng_ai_bp_measure_mode_create(lv_obj_t * tileview, uint16_t id)
+{
+       lv_obj_t * tab = mmi_heng_ai_bp_tileview_add_tile(tileview, id);
+       if(NULL == tab)
+               return NULL;
+       
+       lv_obj_t * label_title = lv_label_create(tab, NULL);
+       //lv_obj_set_size(label_title, LV_HOR_RES, 40);
+       lv_obj_add_style(label_title, LV_LABEL_PART_MAIN, &lv_watch_font32);
+       lv_label_set_align(label_title, LV_LABEL_ALIGN_CENTER);
+       lv_label_set_text_id(label_title, WATCH_TEXT_ID_BP_MEASURE_MODE);
+       lv_obj_align(label_title, NULL, LV_ALIGN_IN_TOP_MID, 0, 48);
+       lv_obj_set_click(label_title, false);
+
+       lv_obj_t * img = lv_img_create(tab, NULL);
+       lv_img_set_src(img, ICON_HENGAI_BP_MEASURE_MODE);
+       lv_obj_align(img, NULL, LV_ALIGN_IN_TOP_MID, 0, 104);
+
+       lv_obj_t * imgbtn = lv_imgbtn_create(tab, NULL);
+       lv_imgbtn_set_src(imgbtn, LV_BTN_STATE_RELEASED, ICON_HENGAI_BP_BTN_BG);
+       lv_imgbtn_set_src(imgbtn, LV_BTN_STATE_PRESSED, ICON_HENGAI_BP_BTN_BG);
+       lv_obj_align(imgbtn, NULL, LV_ALIGN_IN_TOP_MID, 0, 300);
+       lv_obj_set_event_cb(imgbtn, mmi_heng_ai_bp_measure_mode_btn_event_cb);
+
+       lv_obj_t * btn_label = lv_label_create(imgbtn, NULL);
+       lv_obj_add_style(btn_label, LV_LABEL_PART_MAIN, &lv_watch_font32);
+       lv_label_set_align(btn_label, LV_LABEL_ALIGN_CENTER);
+       lv_label_set_text_id(btn_label, WATCH_TEXT_ID_START_MEASURE);
+       lv_obj_align(btn_label, NULL, LV_ALIGN_CENTER, 0, 0);
+
+       return tab;
+}
+
+
+// calibrate mode
+void * mmi_heng_ai_bp_calibrate_screen_ext_get(void)
+{
+       lv_obj_t * activity_obj = lv_watch_get_activity_obj(ACT_ID_HENG_AI_BP_CALIBRATE);
+       if(activity_obj == NULL)
+               return NULL;
+
+       lv_obj_t * watch_obj = NULL;
+       lv_watch_get_child_obj(activity_obj, lv_watch_obj_signal, &watch_obj);
+       if(NULL == watch_obj) 
+               return NULL;
+       
+       void * ext = lv_obj_get_ext_attr(watch_obj);
+       
+       return ext;
+}
+
+void mmi_heng_ai_bp_calibrate_screen_prepare_destory(lv_obj_t * activity_obj)
+{
+    watch_set_suspend_enable(true, ACT_ID_HENG_AI_BP_CALIBRATE, 0);
+    lv_watch_png_cache_all_free();
+
+       lv_heng_ai_bp_calibrate_ext_t * watch_ext = (lv_heng_ai_bp_calibrate_ext_t *)mmi_heng_ai_bp_calibrate_screen_ext_get();
+       if(NULL == watch_ext)
+               return;
+       
+       if(NULL != watch_ext->gif_info)
+       {
+               gif_close(watch_ext->gif_info);
+               watch_ext->gif_info = NULL;
+       }
+       if(NULL != watch_ext->measure_timer_id)
+       {
+               Hal_Timer_Stop(watch_ext->measure_timer_id);
+               watch_ext->measure_timer_id = NULL;
+       }
+       if(NULL != watch_ext->result_timer_id)
+       {
+               Hal_Timer_Stop(watch_ext->result_timer_id);
+               watch_ext->result_timer_id = NULL;
+       }
+}
+
+void mmi_heng_ai_bp_calibrate_screen_clean(void)
+{
+       lv_obj_t * activity_obj = lv_watch_get_activity_obj(ACT_ID_HENG_AI_BP_CALIBRATE);
+       if(NULL != activity_obj)
+       {
+               printf("[@CHENG_DEBUG][%s][%d]: \n", __FUNCTION__, __LINE__);
+               mmi_heng_ai_bp_calibrate_screen_prepare_destory(NULL);
+               lv_obj_del(activity_obj);
+       }
+}
+
+void mmi_bp_roller_get_optstr_from_num(uint16_t sel_value, char * stropt, uint32_t user_num)
+{
+/*
+    uint8_t opt_display[5];
+    uint8_t i, pos = 0;
+    uint8_t min = 0;
+    uint8_t max = 0;
+    uint8_t count = 0;
+       
+    if(0 == user_num) // high
+       {
+               min = 80
+        max = 200;
+        count = 121;
+    }
+       else // low
+       {
+        min = 60;
+        max = 120;
+        count = 61;
+    }
+
+    opt_display[0] = ((sel_value - min + count) - 2) % count + min;
+    opt_display[1] = ((sel_value - min + count) - 1) % count + min;
+    opt_display[2] = sel_value;
+    opt_display[3] = (sel_value + 1 - min) % count + min;
+    opt_display[4] = (sel_value + 2 - min) % count + min;
+
+    for(i = 0; i < 5; i++) {
+        stropt[pos++] = (opt_display[i] % 100) / 10 + 0x30;
+        stropt[pos++] = opt_display[i] % 10 + 0x30;
+        stropt[pos++] = 0x0A;
+    }
+    stropt [pos - 1] = 0;
+*/
+}
+
+void mmi_bp_roller_action(lv_obj_t * roller, lv_event_t event)
+{
+    if(LV_EVENT_VALUE_CHANGED != event)
+               return;
+
+       uint32_t user_num = lv_watch_get_free_num(roller);
+       uint16_t sel_value = 0;
+       char sel_str[4] = {0};
+       char stropt[40] = {0};
+       
+       lv_roller_get_selected_str(roller, sel_str, 4);
+       sel_value = atoi(sel_str);
+       mmi_bp_roller_get_optstr_from_num(sel_value, stropt, user_num);
+       lv_roller_set_options(roller, stropt, LV_ROLLER_MODE_NORMAL);
+       lv_roller_set_selected(roller, 2, LV_ANIM_OFF);
+       lv_roller_set_auto_fit(roller, true);
+}
+
+lv_obj_t * mmi_bp_roller_create(lv_obj_t * par, uint32_t user_num)
+{
+       lv_obj_t * roller_cont = lv_cont_create(par, NULL);
+       lv_obj_set_size(roller_cont, 100, 180);
+       lv_cont_set_layout(roller_cont, LV_LAYOUT_OFF);
+       lv_obj_add_style(roller_cont, LV_CONT_PART_MAIN, &lv_watch_style_transp);
+       //lv_obj_align(roller_cont, NULL, LV_ALIGN_IN_TOP_LEFT, 90, 140);
+
+       lv_obj_t * roller = lv_roller_create(roller_cont, NULL);
+       lv_obj_add_style(roller, LV_ROLLER_PART_BG, &lv_watch_font36_gray);
+       lv_obj_set_style_local_text_line_space(roller, LV_ROLLER_PART_BG, LV_STATE_DEFAULT, 20);
+       lv_obj_set_style_local_bg_opa(roller, LV_ROLLER_PART_BG, LV_STATE_DEFAULT, LV_OPA_TRANSP);
+       lv_obj_add_style(roller, LV_ROLLER_PART_SELECTED, &lv_watch_font60);
+       lv_obj_set_style_local_text_line_space(roller, LV_ROLLER_PART_SELECTED, LV_STATE_DEFAULT, 20);
+       lv_obj_set_style_local_bg_opa(roller, LV_ROLLER_PART_SELECTED, LV_STATE_DEFAULT, LV_OPA_TRANSP);
+
+
+       uint16_t sel_value = 0;
+       char stropt[40] = {0};
+       
+       mmi_bp_roller_get_optstr_from_num(sel_value, stropt, user_num);
+
+       lv_roller_set_auto_fit(roller, true);
+    lv_roller_set_options(roller, stropt, LV_ROLLER_MODE_NORMAL);
+    lv_roller_set_visible_row_count(roller, 3);
+    lv_roller_set_selected(roller, 2, LV_ANIM_OFF);
+    lv_obj_set_event_cb(roller, mmi_bp_roller_action);
+    lv_watch_set_free_num(roller, user_num);
+
+    //lv_watch_roller_set_sel_style(roller, ext->sel_str);
+
+       return roller_cont;
+}
+
+// 0-ok; 1-high; 2-low; 3-fail
+void mmi_heng_ai_bp_calibrate_result_screen(uint8_t result)
+{
+       lv_heng_ai_bp_calibrate_ext_t * watch_ext = (lv_heng_ai_bp_calibrate_ext_t *)mmi_heng_ai_bp_calibrate_screen_ext_get();
+       if(NULL == watch_ext)
+               return;
+
+       // clean
+       if(NULL != watch_ext->measure_timer_id)
+       {
+               Hal_Timer_Stop(watch_ext->measure_timer_id);
+               watch_ext->measure_timer_id = NULL;
+       }
+       if(NULL != watch_ext->result_timer_id)
+       {
+               Hal_Timer_Stop(watch_ext->result_timer_id);
+               watch_ext->result_timer_id = NULL;
+       }
+       if(NULL != watch_ext->gif_info)
+       {
+               gif_close(watch_ext->gif_info);
+               watch_ext->gif_info = NULL;
+       }
+       lv_obj_clean(watch_ext->cont);
+
+       // display
+       uint32_t label_title_text_id[] = {WATCH_TEXT_ID_CALIBRATE_SUCCESS,
+                                                                               WATCH_TEXT_ID_BLOOD_PRESSURE_HIGH,
+                                                                               WATCH_TEXT_ID_BLOOD_PRESSURE_LOW,
+                                                                               WATCH_TEXT_ID_CALIBRATE_FAILED};
+       void * img_src_path[] = {ICON_HENGAI_BP_SUCCESS, ICON_HENGAI_BP_ALERT, ICON_HENGAI_BP_ALERT, ICON_HENGAI_BP_ALERT};
+       uint32_t label_prompt_text_id[] = {WATCH_TEXT_ID_BLOOD_PRESSURE_NORMAL_PROMPT,
+                                                                               WATCH_TEXT_ID_BLOOD_PRESSURE_HIGH_PROMPT,
+                                                                               WATCH_TEXT_ID_BLOOD_PRESSURE_LOW_PROMPT,
+                                                                               WATCH_TEXT_ID_BLOOD_PRESSURE_FAILED_PROMPT};
+       
+       lv_obj_t * label_title = lv_label_create(watch_ext->cont, NULL);
+       lv_obj_add_style(label_title, LV_LABEL_PART_MAIN, &lv_watch_font32);
+       lv_label_set_align(label_title, LV_LABEL_ALIGN_CENTER);
+       lv_label_set_text_id(label_title, label_title_text_id[result]);
+       lv_obj_align(label_title, NULL, LV_ALIGN_IN_TOP_MID, 0, 48);
+       lv_obj_set_click(label_title, false);
+       
+       lv_obj_t * img = lv_img_create(watch_ext->cont, NULL);
+       lv_img_set_src(img, img_src_path[result]);
+       lv_obj_align(img, NULL, LV_ALIGN_IN_TOP_MID, 0, 104);
+                               
+       lv_obj_t * label_prompt = lv_label_create(watch_ext->cont, NULL);
+       lv_obj_add_style(label_prompt, LV_LABEL_PART_MAIN, &lv_watch_font28);
+       lv_label_set_align(label_prompt, LV_LABEL_ALIGN_CENTER);
+       lv_label_set_long_mode(label_prompt, LV_LABEL_LONG_BREAK);
+       lv_obj_set_width(label_prompt, 400);
+       lv_label_set_text_id(label_prompt, label_prompt_text_id[result]);
+       lv_obj_align(label_prompt, NULL, LV_ALIGN_IN_TOP_MID, 0, 292);
+}
+
+void mmi_heng_ai_bp_calibrate_result_timeout(void * para)
+{
+       lv_heng_ai_bp_calibrate_ext_t * watch_ext = (lv_heng_ai_bp_calibrate_ext_t *)mmi_heng_ai_bp_calibrate_screen_ext_get();
+       if(NULL == watch_ext)
+               return;
+       
+       if(NULL != watch_ext->result_timer_id)
+       {
+               Hal_Timer_Stop(watch_ext->result_timer_id);
+               watch_ext->result_timer_id = NULL;
+       }
+
+       mmi_heng_ai_bp_calibrate_result_screen(3);
+}
+
+void mmi_heng_ai_bp_calibrate_end_btn_event_cb(lv_obj_t * obj, lv_event_t e)
+{
+       if(LV_EVENT_CLICKED != e)
+               return;
+
+       // send vaule
+       mmi_heng_ai_bp_calibrate_input_value_send();
+       
+       if(1 == s_hengai_bp_calibrate_times)
+       {
+               // once again
+               mmi_heng_ai_bp_calibrate_start_screen();
+       }
+       else
+       {
+               // finish
+               lv_heng_ai_bp_calibrate_ext_t * watch_ext = (lv_heng_ai_bp_calibrate_ext_t *)mmi_heng_ai_bp_calibrate_screen_ext_get();
+               if(NULL == watch_ext)
+                       return;
+               
+               watch_ext->result_timer_id = Hal_Timer_Start(MMI_BP_WAIT_RESULT_TIMEOUT, mmi_heng_ai_bp_calibrate_result_timeout, NULL, false);
+       }
+}
+
+void mmi_heng_ai_bp_calibrate_end_screen(void)
+{
+       mmi_close_sensor();
+       
+       lv_heng_ai_bp_calibrate_ext_t * watch_ext = (lv_heng_ai_bp_calibrate_ext_t *)mmi_heng_ai_bp_calibrate_screen_ext_get();
+       if(NULL == watch_ext)
+               return;
+       
+       Hal_Timer_Stop(watch_ext->measure_timer_id);
+       watch_ext->measure_timer_id = NULL;
+       gif_close(watch_ext->gif_info);
+       watch_ext->gif_info = NULL;
+       lv_obj_clean(watch_ext->cont);
+
+       lv_obj_t * label_title = lv_label_create(watch_ext->cont, NULL);
+       lv_obj_add_style(label_title, LV_LABEL_PART_MAIN, &lv_watch_font32);
+       lv_label_set_align(label_title, LV_LABEL_ALIGN_CENTER);
+       lv_label_set_text_id(label_title, WATCH_TEXT_ID_INPUT_CALIBRATE_VALUE);
+       lv_obj_align(label_title, NULL, LV_ALIGN_IN_TOP_MID, 0, 48);
+       lv_obj_set_click(label_title, false);
+
+       lv_obj_t * label_0 = lv_label_create(watch_ext->cont, NULL);
+       lv_obj_add_style(label_0, LV_LABEL_PART_MAIN, &lv_watch_font24);
+       lv_label_set_align(label_0, LV_LABEL_ALIGN_CENTER);
+       lv_label_set_text_id(label_0, WATCH_TEXT_ID_SYSTOLIC_BP);
+       lv_obj_align(label_0, NULL, LV_ALIGN_IN_TOP_LEFT, 103, 104);
+       lv_obj_set_click(label_0, false);
+
+       lv_obj_t * roller_cont_0 = mmi_bp_roller_create(watch_ext->cont, 0);
+       lv_obj_align(roller_cont_0, NULL, LV_ALIGN_IN_TOP_LEFT, 90, 140);
+
+       lv_obj_t * label_1 = lv_label_create(watch_ext->cont, NULL);
+       lv_obj_add_style(label_1, LV_LABEL_PART_MAIN, &lv_watch_font24);
+       lv_label_set_align(label_1, LV_LABEL_ALIGN_CENTER);
+       lv_label_set_text_id(label_1, WATCH_TEXT_ID_DIASTOLIC_BP);
+       lv_obj_align(label_1, NULL, LV_ALIGN_IN_TOP_LEFT, 280, 104);
+       lv_obj_set_click(label_1, false);
+
+       lv_obj_t * roller_cont_1 = mmi_bp_roller_create(watch_ext->cont, 1);
+       lv_obj_align(roller_cont_1, NULL, LV_ALIGN_IN_TOP_LEFT, 270, 140);
+
+       lv_obj_t * imgbtn = lv_imgbtn_create(watch_ext->cont, NULL);
+       lv_imgbtn_set_src(imgbtn, LV_BTN_STATE_RELEASED, ICON_HENGAI_BP_BOTTOM_BTN_BG);
+       lv_imgbtn_set_src(imgbtn, LV_BTN_STATE_PRESSED, ICON_HENGAI_BP_BOTTOM_BTN_BG);
+       lv_obj_align(imgbtn, NULL, LV_ALIGN_IN_BOTTOM_MID, 0, 0);
+       lv_obj_set_event_cb(imgbtn, mmi_heng_ai_bp_calibrate_end_btn_event_cb);
+
+       lv_obj_t * btn_label = lv_label_create(imgbtn, NULL);
+       lv_obj_add_style(btn_label, LV_LABEL_PART_MAIN, &lv_watch_font32);
+       lv_label_set_align(btn_label, LV_LABEL_ALIGN_CENTER);
+       lv_label_set_text_id(btn_label, WATCH_TEXT_ID_OK);
+       lv_obj_align(btn_label, NULL, LV_ALIGN_CENTER, 0, 0);
+}
+
+void mmi_heng_ai_bp_calibrate_cycle_timeout(void * para)
+{
+       mmi_heng_ai_bp_raw_data_save();
+       
+       s_hengai_bp_measure_count++;
+       
+       if(0 == (s_hengai_bp_measure_count % MMI_BP_MEASURE_SEND_DATA_COUNT)) // send raw data per 10s
+       {
+               mmi_heng_ai_bp_raw_data_send();
+       }
+       
+       if(MMI_BP_MEASURE_TOTAL_COUNT <= s_hengai_bp_measure_count) // stop action when 60s
+       {
+               s_hengai_bp_calibrate_times++;
+               mmi_heng_ai_bp_calibrate_end_screen();          
+       }
+}
+
+void mmi_heng_ai_bp_calibrate_start_screen(void)
+{
+       lv_heng_ai_bp_calibrate_ext_t * watch_ext = (lv_heng_ai_bp_calibrate_ext_t *)mmi_heng_ai_bp_calibrate_screen_ext_get();
+       if(NULL == watch_ext)
+               return;
+
+       lv_obj_clean(watch_ext->cont);
+       if(false == mmi_health_measure_wear_state_get())
+       {
+               lv_obj_t * img = lv_img_create(watch_ext->cont, NULL);
+               lv_img_set_src(img, ICON_HENGAI_BP_ALERT);
+               lv_obj_align(img, NULL, LV_ALIGN_IN_TOP_MID, 0, 90);
+               
+               lv_obj_t * label_1 = lv_label_create(watch_ext->cont, NULL);
+               lv_obj_add_style(label_1, LV_LABEL_PART_MAIN, &lv_watch_font36);
+               lv_label_set_text_id(label_1, WATCH_TEXT_ID_DEVICE_NOT_WEAR);
+               lv_label_set_align(label_1, LV_LABEL_ALIGN_CENTER);
+               lv_obj_align(label_1, NULL, LV_ALIGN_IN_TOP_MID, 0, 278);
+               lv_obj_set_click(label_1, false);
+       }
+       else
+       {
+               mmi_open_sensor();
+               
+               gif_info_t * gif_info = gif_open(watch_ext->cont, ANIM_HENGAI_BP_CALIBRATE, 0);
+               if(NULL == gif_info)
+                       return;
+               lv_obj_align(gif_info->container, NULL, LV_ALIGN_IN_TOP_MID, 0, 104);
+               watch_ext->gif_info = gif_info;
+
+               lv_obj_t * label = lv_label_create(watch_ext->cont, NULL);
+               lv_obj_add_style(label, LV_LABEL_PART_MAIN, &lv_watch_font28);
+               lv_label_set_align(label, LV_LABEL_ALIGN_CENTER);
+               lv_label_set_text_id(label, (0 == s_hengai_bp_calibrate_times) ? WATCH_TEXT_ID_IN_CALIBRATE_PROMPT_FIRST : WATCH_TEXT_ID_IN_CALIBRATE_PROMPT_SECOND);
+               lv_obj_align(label, NULL, LV_ALIGN_IN_TOP_MID, 0, 292);
+               lv_obj_set_click(label, false);
+
+               /* start timer (1 min) */
+               s_hengai_bp_measure_count = 0;
+               watch_ext->measure_timer_id = Hal_Timer_Start(1000, mmi_heng_ai_bp_calibrate_cycle_timeout, NULL, true);
+       }
+}
+
+void mmi_heng_ai_bp_calibrate_start_btn_event_cb(lv_obj_t * obj, lv_event_t e)
+{
+       if(LV_EVENT_CLICKED != e)
+               return;
+
+       s_hengai_bp_calibrate_times = 0;
+
+       lv_heng_ai_bp_calibrate_ext_t * watch_ext = (lv_heng_ai_bp_calibrate_ext_t *)mmi_heng_ai_bp_calibrate_screen_ext_get();
+       if(NULL == watch_ext)
+               return;
+
+       if(NULL == watch_ext->tileview)
+               return;
+
+       lv_obj_t * watch_obj = lv_obj_get_parent(watch_ext->tileview);
+       lv_obj_del(watch_ext->tileview);
+       lv_watch_obj_set_anim_mode(watch_obj, LV_WATCH_ANIM_HOR_RIGHT_HIDE);
+
+       lv_obj_t * cont = lv_cont_create(watch_obj, NULL);
+       lv_obj_set_size(cont, LV_HOR_RES, LV_VER_RES);
+       lv_obj_set_style_local_bg_color(cont, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_BLACK);
+       lv_obj_set_click(cont, false);
+       watch_ext->cont = cont;
+       
+       mmi_heng_ai_bp_calibrate_start_screen();
+}
+
+lv_obj_t * mmi_heng_ai_bp_calibrate_tab_0(lv_obj_t * tileview, uint16_t id)
+{
+       lv_obj_t * tab = mmi_heng_ai_bp_tileview_add_tile(tileview, id);
+       if(NULL == tab)
+               return NULL;
+       
+       lv_obj_t * label_title = lv_label_create(tab, NULL);
+       lv_obj_add_style(label_title, LV_LABEL_PART_MAIN, &lv_watch_font32);
+       lv_label_set_align(label_title, LV_LABEL_ALIGN_CENTER);
+       lv_label_set_text_id(label_title, WATCH_TEXT_ID_CALIBRATE_PROMPT);
+       lv_obj_align(label_title, NULL, LV_ALIGN_IN_TOP_MID, 0, 48);
+       lv_obj_set_click(label_title, false);
+
+       lv_obj_t * img = lv_img_create(tab, NULL);
+       lv_img_set_src(img, ICON_HENGAI_BP_PROMPT_0);
+       lv_obj_align(img, NULL, LV_ALIGN_IN_TOP_MID, 0, 104);
+
+       lv_obj_t * label_prompt = lv_label_create(tab, NULL);
+       lv_obj_add_style(label_prompt, LV_LABEL_PART_MAIN, &lv_watch_font28);
+       lv_label_set_align(label_prompt, LV_LABEL_ALIGN_CENTER);
+       lv_label_set_long_mode(label_prompt, LV_LABEL_LONG_BREAK);
+       lv_obj_set_width(label_prompt, 400);
+       lv_label_set_text_id(label_prompt, WATCH_TEXT_ID_CALIBRATE_PROMPT_0);
+       lv_obj_align(label_prompt, NULL, LV_ALIGN_IN_TOP_MID, 0, 292);
+
+       return tab;
+}
+
+lv_obj_t * mmi_heng_ai_bp_calibrate_tab_1(lv_obj_t * tileview, uint16_t id)
+{
+       lv_obj_t * tab = mmi_heng_ai_bp_tileview_add_tile(tileview, id);
+       if(NULL == tab)
+               return NULL;
+       
+       lv_obj_t * label_title = lv_label_create(tab, NULL);
+       lv_obj_add_style(label_title, LV_LABEL_PART_MAIN, &lv_watch_font32);
+       lv_label_set_align(label_title, LV_LABEL_ALIGN_CENTER);
+       lv_label_set_text_id(label_title, WATCH_TEXT_ID_CALIBRATE_PROMPT);
+       lv_obj_align(label_title, NULL, LV_ALIGN_IN_TOP_MID, 0, 48);
+       lv_obj_set_click(label_title, false);
+
+       lv_obj_t * img = lv_img_create(tab, NULL);
+       lv_img_set_src(img, ICON_HENGAI_BP_PROMPT_1);
+       lv_obj_align(img, NULL, LV_ALIGN_IN_TOP_MID, 0, 104);
+
+       lv_obj_t * label_prompt = lv_label_create(tab, NULL);
+       lv_obj_add_style(label_prompt, LV_LABEL_PART_MAIN, &lv_watch_font28);
+       lv_label_set_align(label_prompt, LV_LABEL_ALIGN_CENTER);
+       lv_label_set_long_mode(label_prompt, LV_LABEL_LONG_BREAK);
+       lv_obj_set_width(label_prompt, 400);
+       lv_label_set_text_id(label_prompt, WATCH_TEXT_ID_CALIBRATE_PROMPT_1);
+       lv_obj_align(label_prompt, NULL, LV_ALIGN_IN_TOP_MID, 0, 292);
+
+       return tab;
+}
+
+lv_obj_t * mmi_heng_ai_bp_calibrate_tab_2(lv_obj_t * tileview, uint16_t id)
+{
+       lv_obj_t * tab = mmi_heng_ai_bp_tileview_add_tile(tileview, id);
+       if(NULL == tab)
+               return NULL;
+       
+       lv_obj_t * label_title = lv_label_create(tab, NULL);
+       lv_obj_add_style(label_title, LV_LABEL_PART_MAIN, &lv_watch_font32);
+       lv_label_set_align(label_title, LV_LABEL_ALIGN_CENTER);
+       lv_label_set_text_id(label_title, WATCH_TEXT_ID_CALIBRATE_PROMPT);
+       lv_obj_align(label_title, NULL, LV_ALIGN_IN_TOP_MID, 0, 48);
+       lv_obj_set_click(label_title, false);
+
+       lv_obj_t * label_prompt = lv_label_create(tab, NULL);
+       lv_obj_add_style(label_prompt, LV_LABEL_PART_MAIN, &lv_watch_font28);
+       lv_label_set_align(label_prompt, LV_LABEL_ALIGN_CENTER);
+       lv_label_set_long_mode(label_prompt, LV_LABEL_LONG_BREAK);
+       lv_obj_set_width(label_prompt, 400);
+       lv_label_set_text_id(label_prompt, WATCH_TEXT_ID_CALIBRATE_PROMPT_2);
+       lv_obj_align(label_prompt, NULL, LV_ALIGN_IN_TOP_MID, 0, 104);
+
+       lv_obj_t * imgbtn = lv_imgbtn_create(tab, NULL);
+       lv_imgbtn_set_src(imgbtn, LV_BTN_STATE_RELEASED, ICON_HENGAI_BP_BOTTOM_BTN_BG);
+       lv_imgbtn_set_src(imgbtn, LV_BTN_STATE_PRESSED, ICON_HENGAI_BP_BOTTOM_BTN_BG);
+       lv_obj_align(imgbtn, NULL, LV_ALIGN_IN_BOTTOM_MID, 0, 0);
+       lv_obj_set_event_cb(imgbtn, mmi_heng_ai_bp_calibrate_start_btn_event_cb);
+
+       lv_obj_t * btn_label = lv_label_create(imgbtn, NULL);
+       lv_obj_add_style(btn_label, LV_LABEL_PART_MAIN, &lv_watch_font32);
+       lv_label_set_align(btn_label, LV_LABEL_ALIGN_CENTER);
+       lv_label_set_text_id(btn_label, WATCH_TEXT_ID_START_CALIBRATE);
+       lv_obj_align(btn_label, NULL, LV_ALIGN_CENTER, 0, 0);
+
+       return tab;
+}
+
+void mmi_heng_ai_bp_calibrate_screen_tileview_led(lv_obj_t * tileview)
+{
+       lv_heng_ai_bp_tileview_ext_t * ext = lv_obj_get_ext_attr(tileview);
+       if(NULL == ext)
+               return NULL;
+
+       if(NULL == ext->led_cont)
+       {
+               ext->led_cont = lv_cont_create(tileview, NULL);
+               lv_obj_set_base_dir(ext->led_cont, LV_BIDI_DIR_LTR);
+               lv_cont_set_fit(ext->led_cont, LV_FIT_TIGHT);
+               lv_cont_set_layout(ext->led_cont, LV_LAYOUT_ROW_MID);
+               lv_obj_add_style(ext->led_cont, LV_CONT_PART_MAIN, &lv_watch_style_transp);
+               lv_obj_set_click(ext->led_cont, false);
+       }
+
+       uint8_t i = 0;
+       for(i = 0; i < MMI_HENGAI_BP_TAB_COUNT; i++)
+       {
+               if(NULL == ext->led[i])
+               {
+                       ext->led[i] = lv_led_create(ext->led_cont, NULL);
+               }
+
+               lv_led_off(ext->led[i]);
+               lv_obj_set_size(ext->led[i], 6, 6);
+       }
+
+       lv_coord_t x = -1, y = -1;
+       lv_tileview_get_tile_act(tileview, &x, &y);
+       lv_led_on(ext->led[x]);
+       lv_obj_set_size(ext->led[x], 10, 10);
+       lv_obj_set_pos(ext->led_cont, LV_HOR_RES * x + (LV_HOR_RES - lv_obj_get_width(ext->led_cont)) / 2, 100);
+}
+ 
+void mmi_heng_ai_bp_calibrate_screen_tileview_event_cb(lv_obj_t * tileview, lv_event_t e)
+{
+       if(LV_EVENT_VALUE_CHANGED != e)
+               return;
+
+       mmi_heng_ai_bp_calibrate_screen_tileview_led(tileview);
+}
+
+lv_obj_t * mmi_heng_ai_bp_calibrate_screen_create(lv_obj_t * activity_obj)
+{
+    if(NULL == activity_obj) 
+       {
+        lv_watch_activity_ext_t activity_ext = {0};
+
+               activity_ext.actId = ACT_ID_HENG_AI_BP_CALIBRATE;
+               activity_ext.create = mmi_heng_ai_bp_calibrate_screen_create;
+               activity_ext.prepare_destory = mmi_heng_ai_bp_calibrate_screen_prepare_destory;
+        activity_obj = lv_watch_creat_activity_obj(&activity_ext);
+               if(NULL == activity_obj)
+                       return NULL;
+    }
+
+    lv_obj_t * watch_obj = lv_watch_obj_create(activity_obj);
+    LV_ASSERT_MEM(watch_obj);
+       if(NULL == watch_obj)
+               return NULL;
+       lv_watch_obj_set_anim_mode(watch_obj, LV_WATCH_ANIM_NO);
+       lv_heng_ai_bp_calibrate_ext_t * watch_ext = lv_obj_allocate_ext_attr(watch_obj, sizeof(lv_heng_ai_bp_calibrate_ext_t));
+       if(NULL == ext)
+               return NULL;
+       watch_ext->tileview = NULL;
+       watch_ext->cont = NULL;
+       watch_ext->gif_info = NULL;
+       watch_ext->measure_timer_id = NULL;
+       watch_ext->result_timer_id = NULL;
+       
+       lv_obj_t * tileview = lv_tileview_create(watch_obj, NULL);
+       if(NULL == tileview)
+               return NULL;
+       lv_heng_ai_bp_tileview_ext_t * ext = lv_obj_allocate_ext_attr(tileview, sizeof(lv_heng_ai_bp_tileview_ext_t));
+       if(NULL == ext)
+               return NULL;
+       
+       watch_ext->tileview = tileview;
+       ext->tab_0 = NULL;
+       ext->tab_1 = NULL;
+       ext->tab_2 = NULL;
+       ext->led_cont= NULL;
+       ext->led[0] = NULL;
+       ext->led[1] = NULL;
+       ext->led[2] = NULL;
+       
+       lv_tileview_set_valid_positions(tileview, s_hengai_bp_valid_pos, MMI_HENGAI_BP_TAB_COUNT);
+       lv_tileview_set_edge_flash(tileview, true);
+       lv_tileview_set_anim_time(tileview, 60);
+       lv_page_set_scrollbar_mode(tileview, LV_SCROLLBAR_MODE_OFF);
+       lv_obj_add_style(tileview, LV_TILEVIEW_PART_EDGE_FLASH, &lv_watch_cont_opa1);
+       ext->tileview = tileview;
+
+       ext->tab_0 = mmi_heng_ai_bp_calibrate_tab_0(tileview, 0);
+       LV_ASSERT_MEM(ext->tab_0);
+       if(NULL == ext->tab_0)
+               return NULL;
+
+       ext->tab_1 = mmi_heng_ai_bp_calibrate_tab_1(tileview, 1);
+       LV_ASSERT_MEM(ext->tab_1);
+       if(NULL == ext->tab_1)
+               return NULL;
+
+       ext->tab_2 = mmi_heng_ai_bp_calibrate_tab_2(tileview, 2);
+       LV_ASSERT_MEM(ext->tab_2);
+       if(NULL == ext->tab_2)
+               return NULL;
+
+       lv_tileview_set_tile_act(tileview, 0, 0, LV_ANIM_OFF);
+       lv_watch_obj_add_element(tileview);
+       lv_watch_obj_add_element(lv_page_get_scrl(tileview));
+       lv_obj_set_event_cb(tileview, mmi_heng_ai_bp_calibrate_screen_tileview_event_cb);
+
+       mmi_heng_ai_bp_calibrate_screen_tileview_led(tileview);
+
+       //
+       watch_set_suspend_enable(false, ACT_ID_HENG_AI_BP_CALIBRATE, 0);
+}
+
+void mmi_heng_ai_bp_calibration_mode_btn_event_cb(lv_obj_t * obj, lv_event_t e)
+{
+       if(LV_EVENT_CLICKED != e)
+               return;
+
+       mmi_heng_ai_bp_calibrate_screen_create(NULL);
+}
+
+lv_obj_t * mmi_heng_ai_bp_calibration_mode_create(lv_obj_t * tileview, uint16_t id)
+{
+       lv_obj_t * tab = mmi_heng_ai_bp_tileview_add_tile(tileview, id);
+       if(NULL == tab)
+               return NULL;
+       
+       lv_obj_t * label_title = lv_label_create(tab, NULL);
+       lv_obj_add_style(label_title, LV_LABEL_PART_MAIN, &lv_watch_font32);
+       lv_label_set_align(label_title, LV_LABEL_ALIGN_CENTER);
+       lv_label_set_text_id(label_title, WATCH_TEXT_ID_BP_CALIBRATION_MODE);
+       lv_obj_align(label_title, NULL, LV_ALIGN_IN_TOP_MID, 0, 48);
+       lv_obj_set_click(label_title, false);
+
+       lv_obj_t * img = lv_img_create(tab, NULL);
+       lv_img_set_src(img, ICON_HENGAI_BP_CALIBRATION_MODE);
+       lv_obj_align(img, NULL, LV_ALIGN_IN_TOP_MID, 0, 104);
+
+       lv_obj_t * imgbtn = lv_imgbtn_create(tab, NULL);
+       lv_imgbtn_set_src(imgbtn, LV_BTN_STATE_RELEASED, ICON_HENGAI_BP_BTN_BG);
+       lv_imgbtn_set_src(imgbtn, LV_BTN_STATE_PRESSED, ICON_HENGAI_BP_BTN_BG);
+       lv_obj_align(imgbtn, NULL, LV_ALIGN_IN_TOP_MID, 0, 300);
+       lv_obj_set_event_cb(imgbtn, mmi_heng_ai_bp_calibration_mode_btn_event_cb);
+
+       lv_obj_t * btn_label = lv_label_create(imgbtn, NULL);
+       lv_obj_add_style(btn_label, LV_LABEL_PART_MAIN, &lv_watch_font32);
+       lv_label_set_align(btn_label, LV_LABEL_ALIGN_CENTER);
+       lv_label_set_text_id(btn_label, WATCH_TEXT_ID_CALIBRATE_PROMPT);
+       lv_obj_align(btn_label, NULL, LV_ALIGN_CENTER, 0, 0);
+
+       return tab;
+}
+
+
+void mmi_heng_ai_bp_attempt_mode_btn_event_cb(lv_obj_t * obj, lv_event_t e)
+{
+       if(LV_EVENT_CLICKED != e)
+               return;
+
+
+}
+
+lv_obj_t * mmi_heng_ai_bp_attempt_mode_create(lv_obj_t * tileview, uint16_t id)
+{
+       lv_obj_t * tab = mmi_heng_ai_bp_tileview_add_tile(tileview, id);
+       if(NULL == tab)
+               return NULL;
+       
+       lv_obj_t * label_title = lv_label_create(tab, NULL);
+       lv_obj_add_style(label_title, LV_LABEL_PART_MAIN, &lv_watch_font32);
+       lv_label_set_align(label_title, LV_LABEL_ALIGN_CENTER);
+       lv_label_set_text_id(label_title, WATCH_TEXT_ID_BP_ATTEMPT_MODE);
+       lv_obj_align(label_title, NULL, LV_ALIGN_IN_TOP_MID, 0, 48);
+       lv_obj_set_click(label_title, false);
+
+       lv_obj_t * img = lv_img_create(tab, NULL);
+       lv_img_set_src(img, ICON_HENGAI_BP_ATTEMPT_MODE);
+       lv_obj_align(img, NULL, LV_ALIGN_IN_TOP_MID, 0, 104);
+
+       lv_obj_t * imgbtn = lv_imgbtn_create(tab, NULL);
+       lv_imgbtn_set_src(imgbtn, LV_BTN_STATE_RELEASED, ICON_HENGAI_BP_BTN_BG);
+       lv_imgbtn_set_src(imgbtn, LV_BTN_STATE_PRESSED, ICON_HENGAI_BP_BTN_BG);
+       lv_obj_align(imgbtn, NULL, LV_ALIGN_IN_TOP_MID, 0, 300);
+       lv_obj_set_event_cb(imgbtn, mmi_heng_ai_bp_attempt_mode_btn_event_cb);
+
+       lv_obj_t * btn_label = lv_label_create(imgbtn, NULL);
+       lv_obj_add_style(btn_label, LV_LABEL_PART_MAIN, &lv_watch_font32);
+       lv_label_set_align(btn_label, LV_LABEL_ALIGN_CENTER);
+       lv_label_set_text_id(btn_label, WATCH_TEXT_ID_START_MEASURE);
+       lv_obj_align(btn_label, NULL, LV_ALIGN_CENTER, 0, 0);
+
+       return tab;
+}
+
+
+void mmi_heng_ai_bp_tileview_led(lv_obj_t * tileview)
+{
+       lv_heng_ai_bp_obj_ext_t * ext = mmi_heng_ai_bp_ext_get();
+       if(NULL == ext)
+           return NULL;
+
+    if(NULL == ext->led_cont)
+       {
+        ext->led_cont = lv_cont_create(tileview, NULL);
+        lv_obj_set_base_dir(ext->led_cont, LV_BIDI_DIR_LTR);
+        lv_cont_set_fit(ext->led_cont, LV_FIT_TIGHT);
+        lv_cont_set_layout(ext->led_cont, LV_LAYOUT_ROW_MID);
+        lv_obj_add_style(ext->led_cont, LV_CONT_PART_MAIN, &lv_watch_style_transp);
+        lv_obj_set_click(ext->led_cont, false);
+    }
+
+       uint8_t i = 0;
+    for(i = 0; i < MMI_HENGAI_BP_TAB_COUNT; i++)
+       {
+        if(NULL == ext->led[i])
+               {
+            ext->led[i] = lv_led_create(ext->led_cont, NULL);
+        }
+               
+        lv_led_off(ext->led[i]);
+        lv_obj_set_size(ext->led[i], 6, 6);
+    }
+       
+       lv_coord_t x = -1, y = -1;
+       lv_tileview_get_tile_act(tileview, &x, &y);
+       lv_led_on(ext->led[x]);
+       lv_obj_set_size(ext->led[x], 10, 10);
+
+    PHONEBOOK_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: x=%d\n", __FUNCTION__, __LINE__, x);
+       
+    lv_obj_set_pos(ext->led_cont, LV_HOR_RES * x + (LV_HOR_RES - lv_obj_get_width(ext->led_cont)) / 2,
+                                       LV_VER_RES - lv_obj_get_width(ext->led_cont) - 10);
+}
+
+void mmi_heng_ai_bp_tileview_event_cb(lv_obj_t * tileview, lv_event_t e)
+{
+       if(LV_EVENT_VALUE_CHANGED != e)
+               return;
+
+       mmi_heng_ai_bp_tileview_led(tileview);
+}
+
+lv_obj_t * mmi_heng_ai_blood_pressure_screen_create(lv_obj_t * activity_obj)
+{
+    if(NULL == activity_obj) 
+       {
+        lv_watch_activity_ext_t activity_ext = {0};
+               
+        activity_ext.actId = ACT_ID_HENG_AI_BP;
+        activity_ext.create = mmi_heng_ai_blood_pressure_screen_create;
+        activity_ext.prepare_destory = mmi_heng_ai_blood_pressure_screen_prepare_destory;
+               
+        activity_obj = lv_watch_creat_activity_obj(&activity_ext);
+        LV_ASSERT_MEM(activity_obj);
+        if(NULL == activity_obj) 
+                       return NULL;
+    }
+
+    lv_obj_t * watch_obj = lv_watch_obj_create(activity_obj);
+    if(NULL == watch_obj)
+        return NULL;
+
+    if(false == watch_modem_sim_present_check_req())
+    {
+               lv_watch_obj_set_anim_mode(watch_obj, LV_WATCH_ANIM_HOR_RIGHT_HIDE);
+               
+               lv_obj_t * img = lv_img_create(watch_obj, NULL);
+               lv_img_set_src(img, ICON_HENGAI_BP_ALERT);
+               lv_obj_align(img, NULL, LV_ALIGN_IN_TOP_MID, 0, 90);
+               
+               lv_obj_t * label_1 = lv_label_create(watch_obj, NULL);
+               //lv_obj_set_size(label_1, LV_HOR_RES, 30);
+               lv_obj_add_style(label_1, LV_LABEL_PART_MAIN, &lv_watch_font36);
+               lv_label_set_text_id(label_1, WATCH_TEXT_ID_DEVICE_NO_NETWORK);
+               lv_label_set_align(label_1, LV_LABEL_ALIGN_CENTER);
+               lv_obj_align(label_1, NULL, LV_ALIGN_IN_TOP_MID, 0, 278);
+               lv_obj_set_click(label_1, false);
+    }
+       else if(true != mmi_watch_tcp_connect_state_get()
+               || true != mmi_protocol_watch_bind_state_get()
+               )
+       {
+               lv_watch_obj_set_anim_mode(watch_obj, LV_WATCH_ANIM_HOR_RIGHT_HIDE);
+               
+               lv_obj_t * img = lv_img_create(watch_obj, NULL);
+               lv_img_set_src(img, ICON_HENGAI_BP_ALERT);
+               lv_obj_align(img, NULL, LV_ALIGN_IN_TOP_MID, 0, 90);
+               
+               lv_obj_t * label_1 = lv_label_create(watch_obj, NULL);
+               //lv_obj_set_size(label_1, LV_HOR_RES, 30);
+               lv_obj_add_style(label_1, LV_LABEL_PART_MAIN, &lv_watch_font36);
+               lv_label_set_text_id(label_1, WATCH_TEXT_ID_DEVICE_NOT_BIND);
+               lv_label_set_align(label_1, LV_LABEL_ALIGN_CENTER);
+               lv_obj_align(label_1, NULL, LV_ALIGN_IN_TOP_MID, 0, 278);
+               lv_obj_set_click(label_1, false);
+    }
+       else if(false == mmi_health_measure_wear_state_get())
+       {
+               lv_watch_obj_set_anim_mode(watch_obj, LV_WATCH_ANIM_HOR_RIGHT_HIDE);
+               
+               lv_obj_t * img = lv_img_create(watch_obj, NULL);
+               lv_img_set_src(img, ICON_HENGAI_BP_ALERT);
+               lv_obj_align(img, NULL, LV_ALIGN_IN_TOP_MID, 0, 90);
+               
+               lv_obj_t * label_1 = lv_label_create(watch_obj, NULL);
+               //lv_obj_set_size(label_1, LV_HOR_RES, 30);
+               lv_obj_add_style(label_1, LV_LABEL_PART_MAIN, &lv_watch_font36);
+               lv_label_set_text_id(label_1, WATCH_TEXT_ID_DEVICE_NOT_WEAR);
+               lv_label_set_align(label_1, LV_LABEL_ALIGN_CENTER);
+               lv_obj_align(label_1, NULL, LV_ALIGN_IN_TOP_MID, 0, 278);
+               lv_obj_set_click(label_1, false);
+       }
+       else
+       {
+               lv_watch_obj_set_anim_mode(watch_obj, LV_WATCH_ANIM_NO);
+               
+               lv_heng_ai_bp_obj_ext_t * ext = lv_obj_allocate_ext_attr(watch_obj, sizeof(lv_heng_ai_bp_obj_ext_t));
+           if(NULL == ext)
+               return NULL;
+
+               ext->tab_measure_mdoe = NULL;
+               ext->tab_calibration_mode = NULL;
+               ext->tab_attempt_mode = NULL;
+               ext->led_cont= NULL;
+               ext->led[0] = NULL;
+               ext->led[1] = NULL;
+               ext->led[2] = NULL;
+               
+               lv_obj_t * tileview = lv_tileview_create(watch_obj, NULL);
+               if(NULL == tileview)
+               return NULL;
+           lv_tileview_set_valid_positions(tileview, s_hengai_bp_valid_pos, MMI_HENGAI_BP_TAB_COUNT);
+           lv_tileview_set_edge_flash(tileview, true);
+           lv_tileview_set_anim_time(tileview, 60);
+           lv_page_set_scrollbar_mode(tileview, LV_SCROLLBAR_MODE_OFF);
+           lv_obj_add_style(tileview, LV_TILEVIEW_PART_EDGE_FLASH, &lv_watch_cont_opa1);
+               ext->tileview = tileview;
+
+               ext->tab_measure_mdoe = mmi_heng_ai_bp_measure_mode_create(tileview, 0);
+           LV_ASSERT_MEM(ext->tab_measure_mdoe);
+               if(NULL == ext->tab_measure_mdoe)
+                       return NULL;
+
+               ext->tab_calibration_mode = mmi_heng_ai_bp_calibration_mode_create(tileview, 1);
+           LV_ASSERT_MEM(ext->tab_calibration_mode);
+               if(NULL == ext->tab_calibration_mode)
+                       return NULL;
+
+               ext->tab_attempt_mode = mmi_heng_ai_bp_attempt_mode_create(tileview, 2);
+           LV_ASSERT_MEM(ext->tab_attempt_mode);
+               if(NULL == ext->tab_attempt_mode)
+                       return NULL;
+
+               if(1 == s_hengai_bp_calibrated)
+                   lv_tileview_set_tile_act(tileview, 1, 0, LV_ANIM_OFF);
+               else
+                   lv_tileview_set_tile_act(tileview, 0, 0, LV_ANIM_OFF);
+               
+           lv_watch_obj_add_element(tileview);
+           lv_watch_obj_add_element(lv_page_get_scrl(tileview));
+               lv_obj_set_event_cb(tileview, mmi_heng_ai_bp_tileview_event_cb);
+
+               mmi_heng_ai_bp_tileview_led(tileview);
+       }
+
+       return watch_obj;
+}
+/*
+{      
+       lv_obj_t * img = lv_img_create(cont, NULL);
+       lv_img_set_src(img, ICON_HEART_RATE_MEASURE_FAIL);
+    lv_obj_align(img, NULL, LV_ALIGN_IN_TOP_MID, 0, HEART_MEASURE_IMAGE_Y);
+       lv_obj_set_hidden(img, true);
+       ext->img = img;
+
+       lv_obj_t * label_info = lv_label_create(cont, NULL);
+    //lv_obj_set_size(label_info, LV_HOR_RES, 30);
+       lv_obj_add_style(label_info, LV_LABEL_PART_MAIN, &lv_watch_font20);
+       lv_label_set_text_id(label_info, WATCH_TEXT_ID_MEASURING);
+    //lv_label_set_align(label_info, LV_LABEL_ALIGN_CENTER);
+    lv_obj_align(label_info, cont, LV_ALIGN_IN_TOP_MID, 0, HEART_LABEL_INFO_Y);
+    lv_obj_set_click(label_info, false);
+       ext->label_info = label_info;
+
+       lv_obj_t * label_value = lv_label_create(cont, NULL);
+    //lv_obj_set_size(label_value, LV_HOR_RES, 40);
+       lv_obj_add_style(label_value, LV_LABEL_PART_MAIN, &lv_watch_font40);
+       lv_label_set_text(label_value, ext->heart_rate);
+    //lv_label_set_align(label_value, LV_LABEL_ALIGN_CENTER);
+    lv_obj_align(label_value, cont, LV_ALIGN_IN_TOP_MID, 0, HEART_LABEL_VALUE_Y);
+       lv_obj_set_click(label_value, false);
+       ext->label_value = label_value;
+
+       if(false == mmi_health_measure_wear_state_get())
+       {
+               ext->measure_state = STATE_HEART_RATE_MEASURE_FAIL;
+       }
+       else
+       {
+               mmi_health_measure_ui_measure_start(MMI_HEALTH_MEASURE_HEART);
+
+               lv_obj_t * gif_cont = lv_cont_create(cont, NULL);
+               lv_obj_set_size(gif_cont, LV_HOR_RES, 100);
+               lv_obj_set_style_local_bg_color(gif_cont, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_BLACK);
+               lv_obj_align(gif_cont, cont, LV_ALIGN_IN_TOP_MID, 0, HEART_MEASURE_IMAGE_Y);
+               ext->gif_cont = gif_cont;
+
+               ext->gif_info = gif_open(gif_cont, ANIM_HEART_RATE_MEASURING, 0);
+               if(!ext->gif_info) 
+               {
+                       HEALTH_MEASURE_DEBUG_PRINTF("[@CHENG_DEBUG][%s][%d]: gif open fail\n", __FUNCTION__, __LINE__);
+               }
+               
+               ext->cycle_timer_id = Hal_Timer_Start(HEALTH_HEART_MEASURE_CYCLE, health_heart_rate_measure_cycle_timeout, NULL, TRUE);
+       
+               ext->measure_state = STATE_HEART_RATE_MEASURING;
+               watch_set_suspend_enable(false, ACT_ID_HENG_AI_BP, 0);
+       }
+       
+       health_heart_rate_display_update();
+
+    return watch_obj;
+}
+*/
+
+void mmi_heng_ai_blood_pressure_create_event_cb(lv_obj_t * btn, lv_event_t e)
+{
+    (void)btn;
+    if(LV_EVENT_CLICKED == e) 
+       {
+        lv_obj_t * obj = mmi_heng_ai_blood_pressure_screen_create(NULL);
+        LV_ASSERT_MEM(obj);
+    }
+}
+
+#endif
diff --git a/2.sdk/sdk/gui/lv_watch/lv_apps/custom_function/heng_ai_blood_pressure.h b/2.sdk/sdk/gui/lv_watch/lv_apps/custom_function/heng_ai_blood_pressure.h
new file mode 100644 (file)
index 0000000..9489dbd
--- /dev/null
@@ -0,0 +1,110 @@
+
+
+
+#ifndef __HENG_AI_BLOOD_PRESSURE_H__
+#define __HENG_AI_BLOOD_PRESSURE_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef LV_CONF_INCLUDE_SIMPLE
+#include "lvgl.h"
+#include "lv_ex_conf.h"
+#else
+#include "../../../lvgl/lvgl.h"
+#include "../../../lv_ex_conf.h"
+#endif
+
+#ifdef __MMI_CUSTOM_HENG_AI_BLOOD_PRESSURE__
+
+#define MMI_HENGAI_BP_TAB_COUNT (3)
+
+#define MMI_BP_MEASURE_TOTAL_COUNT     (60) // times
+#define MMI_BP_MEASURE_SEND_DATA_COUNT (10) // times
+#define MMI_BP_WAIT_RESULT_TIMEOUT     (1000 * 5) // ms
+
+
+
+typedef struct
+{
+    lv_watch_obj_ext_t lv_watch_obj;
+    /*New data for this type */
+       lv_obj_t * tileview;
+    lv_obj_t * tab_measure_mdoe;
+    lv_obj_t * tab_calibration_mode;
+       lv_obj_t * tab_attempt_mode;
+       lv_obj_t * led_cont;
+       lv_obj_t * led[MMI_HENGAI_BP_TAB_COUNT];
+} lv_heng_ai_bp_ext_t;
+
+
+typedef struct
+{
+    lv_watch_obj_ext_t lv_watch_obj;
+    /*New data for this type */
+       lv_obj_t * tileview;
+       lv_obj_t * cont;
+       gif_info_t * gif_info;
+    TIMER_ID measure_timer_id;
+       TIMER_ID result_timer_id;
+} lv_heng_ai_bp_measure_ext_t;
+
+
+
+typedef struct
+{
+    lv_watch_obj_ext_t lv_watch_obj;
+    /*New data for this type */
+       lv_obj_t * tileview;
+       lv_obj_t * cont;
+       gif_info_t * gif_info;
+    TIMER_ID measure_timer_id;
+       TIMER_ID result_timer_id;
+} lv_heng_ai_bp_calibrate_ext_t;
+
+typedef struct
+{
+    lv_watch_obj_ext_t lv_watch_obj;
+    /*New data for this type */
+    lv_obj_t * tab_0;
+    lv_obj_t * tab_1;
+       lv_obj_t * tab_2;
+       lv_obj_t * led_cont;
+       lv_obj_t * led[MMI_HENGAI_BP_TAB_COUNT];
+} lv_heng_ai_bp_tileview_ext_t;
+
+
+
+
+
+
+
+
+
+typedef struct
+{
+       MMI_HENG_AI_WARNING_TYPE_E type;
+       MMI_HENG_AI_WARNING_STATE_E state;
+       void * prompt_str;
+} mmi_heng_ai_warning_info_s;
+
+typedef struct 
+{
+    lv_watch_obj_ext_t lv_watch_obj;
+    /*New data for this type */
+    TIMER_ID timer_id;
+} lv_heng_ai_warning_obj_ext_t;
+
+
+void mmi_heng_ai_warning_info_set(uint8_t type_value, uint8_t state_value, char * unicode_description);
+
+
+#endif
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif
+
diff --git a/2.sdk/sdk/gui/lv_watch/lv_apps/custom_function/heng_ai_http_protocol.c b/2.sdk/sdk/gui/lv_watch/lv_apps/custom_function/heng_ai_http_protocol.c
new file mode 100644 (file)
index 0000000..8ee4425
--- /dev/null
@@ -0,0 +1,448 @@
+
+
+
+#include "lv_watch.h"
+
+#ifdef __MMI_CUSTOM_HENG_AI__
+
+#define MMI_HENGAI_HTTP_R_TASK_PRIORITY 221
+#define MMI_HENGAI_HTTP_S_TASK_PRIORITY 221
+
+#define MMI_HENGAI_HTTP_R_TASK_STACK_SIZE (8 * 1024)
+#define MMI_HENGAI_HTTP_S_TASK_STACK_SIZE (8 * 1024)
+
+static TASK_HANDLE * s_hengai_http_r_task_id = NULL;
+static TASK_HANDLE * s_hengai_http_s_task_id = NULL;
+
+static mmi_hengai_http_tcp_info_t s_hengai_http_tcp_info = {0};
+
+
+void mmi_hengai_http_r_task_msg_send(MMI_HENGAI_HTTP_TCP_MSG_ID_E msg_id, void * param)
+{
+       printf("[@CHENG_DEBUG][%s][%d]: msg_id=%d\n",__FUNCTION__,__LINE__, msg_id);
+       
+       if(NULL != s_hengai_http_r_task_id)
+       {
+               if((64 - 1) < Hal_Get_Message_Count(s_hengai_http_r_task_id))
+               {
+                       printf("[@CHENG_DEBUG][%s][%d]: msg queue full\n",__FUNCTION__,__LINE__);
+                       return;
+               }
+               
+               printf("[@CHENG_DEBUG][%s][%d]: \n",__FUNCTION__,__LINE__);
+               
+        mmi_hengai_http_task_msg_t * msg = Hal_Mem_Alloc(sizeof(mmi_hengai_http_task_msg_t));
+               msg->cmd_type = msg_id;
+               msg->cmd_param = param;
+       
+        Hal_Send_Message((TASK_ID)s_hengai_http_r_task_id, (void *)msg);
+    }
+}
+
+void mmi_hengai_http_tcp_connect_msg(void * param)
+{
+       mmi_hengai_http_r_task_msg_send(MMI_HENGAI_HTTP_TCP_MSG_CONNECT, param);
+}
+
+void mmi_hengai_http_tcp_reconnect_msg(void * param)
+{
+       mmi_hengai_http_r_task_msg_send(MMI_HENGAI_HTTP_TCP_MSG_RECONNECT, param);
+}
+
+void mmi_hengai_http_tcp_disconnect_msg(void * param)
+{
+       mmi_hengai_http_r_task_msg_send(MMI_HENGAI_HTTP_TCP_MSG_DISCONNECT, param);
+}
+
+void mmi_hengai_http_tcp_read_msg(void * param)
+{
+       mmi_hengai_http_r_task_msg_send(MMI_HENGAI_HTTP_TCP_MSG_READ, param);
+}
+
+static void mmi_hengai_http_socket_callback(int sfd, int event, unsigned int len)
+{
+       printf("[@CHENG_DEBUG][%s][%d]: sfd=%d, event=0x%x, len=%d\n",__FUNCTION__, __LINE__, sfd, event, len);
+
+       switch (event)
+       {
+               case NETCONN_EVT_CONNECTED:
+                       printf("[@CHENG_DEBUG][%s][%d]: socket connected\n",__FUNCTION__,__LINE__);
+                       break;
+
+               case NETCONN_EVT_CLOSE_NORMAL:
+                       printf("[@CHENG_DEBUG][%s][%d]: socket close normal\n",__FUNCTION__,__LINE__);
+                       break;
+
+               case NETCONN_EVT_RCVPLUS:
+                       printf("[@CHENG_DEBUG][%s][%d]: socket rcv plus\n",__FUNCTION__,__LINE__);
+                       ValSetDataTransFlag(1);
+                       if(len > 0)
+                       {
+                mmi_hengai_http_socket_fd_t * data_info = (mmi_hengai_http_socket_fd_t *)Hal_Mem_Alloc(sizeof(mmi_hengai_http_socket_fd_t));
+                data_info->socket_fd = sfd;
+                               data_info->len = len;
+                               mmi_hengai_http_tcp_read_msg(data_info);
+                       }
+                       break;
+
+               case NETCONN_EVT_RCVMINUS:
+                       printf("dt rcv minus event\n");
+                       break;
+
+               case NETCONN_EVT_SENDPLUS:
+                       ValSetDataTransFlag(1);
+                       printf("[@CHENG_DEBUG][%s][%d]: socket send plus\n",__FUNCTION__,__LINE__);
+                       break;
+
+               case NETCONN_EVT_SENDACKED:
+                       printf("[@CHENG_DEBUG][%s][%d]: socket send ack\n",__FUNCTION__,__LINE__);
+                       break;
+
+               case NETCONN_EVT_ERROR_RST:
+               case NETCONN_EVT_ERROR_ABRT:
+               case NETCONN_EVT_CLOSE_WAIT:
+                       ValSetDataTransFlag(1);
+                       printf("dt socket error or close event = %02x\n",event);
+                       printf("LH reconnect\n");
+            //if(Hal_Get_Message_Count((TASK_ID)modem_tcp_task_id) < UOS_TCP_TASK_MSG_QSIZE)
+               //{
+               //      send_task_msg_tcp_reconnect(NULL);
+                       //}
+                       break;
+
+               default:
+                       printf("dt other event\n");
+                       break;
+       }
+}
+
+void mmi_hengai_http_tcp_connect(void * param)
+{      
+       int res = -1;
+    if(FALSE == watch_modem_sim_present_check_req())
+    {
+               printf("[@CHENG_DEBUG][%s][%d]: \n",__FUNCTION__,__LINE__);
+        goto go_reconnect;
+    }
+               
+       if(s_hengai_http_tcp_info.first_connect_flag == false)
+       {
+               s_hengai_http_tcp_info.first_connect_flag = true;
+               printf("[@CHENG_DEBUG][%s][%d]: \n",__FUNCTION__,__LINE__);
+       }
+       
+       if(s_hengai_http_tcp_info.connect_flag == true)
+       {
+               printf("[@CHENG_DEBUG][%s][%d]: \n",__FUNCTION__,__LINE__);
+               return;
+       }
+
+       if(s_hengai_http_tcp_info.connecting_flag)
+       {
+               printf("[@CHENG_DEBUG][%s][%d]: \n",__FUNCTION__,__LINE__);
+               return;
+       }
+       else
+       {
+               s_hengai_http_tcp_info.connecting_flag = true;
+       }
+
+       res = ValNetworkSocketInit_with_callback(NULL, MMI_HENGAI_HTTP_IP_ADDRESS, MMI_HENGAI_HTTP_IP_PORT, (socket_callback)mmi_hengai_http_socket_callback);
+       printf("[@CHENG_DEBUG][%s][%d]: socket init connect res = %d\n",__FUNCTION__,__LINE__, res);
+
+go_reconnect : 
+       if(res < 0)
+       {
+               int relink_time = 0;
+               int randnum = 0;
+               unsigned int time = 0;
+               
+               Hal_Rtc_Gettime_Count(&time);
+               srand(time);
+               randnum = rand() % 50 + 10;
+               relink_time = randnum * 1000 / 5;
+               
+               uos_timer_stop(s_hengai_http_tcp_info.relink_timer);
+               uos_timer_start(s_hengai_http_tcp_info.relink_timer, relink_time,
+                                               0, (void (*)(uint32_t))mmi_hengai_http_tcp_reconnect_msg, NULL);
+               printf("reconnect time = %d\n",(relink_time / 1000 * 5));
+       }
+       else
+       {
+               s_hengai_http_tcp_info.sock_fd = res;
+               mmi_hengai_http_tcp_connected(param);
+       }
+}
+
+void mmi_hengai_http_tcp_connected(void *param)
+{
+       printf("[@CHENG_DEBUG][%s][%d]: \n",__FUNCTION__,__LINE__);
+       
+       s_hengai_http_tcp_info.connect_flag = true;
+       s_hengai_http_tcp_info.connecting_flag = false;
+}
+
+void mmi_hengai_http_tcp_disconnect(void *param)
+{
+       if(s_hengai_http_tcp_info.relink_timer != NULL)
+       {
+               uos_timer_stop(s_hengai_http_tcp_info.relink_timer);
+               //s_hengai_http_tcp_info.relink_timer = NULL;
+       }
+       
+       s_hengai_http_tcp_info.reconnect_count = 5;
+       s_hengai_http_tcp_info.connect_flag = false;
+       s_hengai_http_tcp_info.first_connect_flag = false;
+       s_hengai_http_tcp_info.connecting_flag = false;
+
+       printf("[@CHENG_DEBUG][%s][%d]: sock_fd=%d\n",__FUNCTION__,__LINE__, s_hengai_http_tcp_info.sock_fd);
+       if(s_hengai_http_tcp_info.sock_fd > 0)
+       {
+               int ret = ValSocketClose(s_hengai_http_tcp_info.sock_fd);
+               s_hengai_http_tcp_info.sock_fd = -1;
+       }
+}
+
+void mmi_hengai_http_tcp_reconnect(void *param)
+{
+    if(false == watch_modem_sim_present_check_req())
+    {
+       return;
+    }
+
+       mmi_hengai_http_tcp_disconnect(NULL);
+
+       long reconnect_time = (5 * 1000) / 5;
+       s_hengai_http_tcp_info.reconnect_count--;
+       if(s_hengai_http_tcp_info.reconnect_count < 0)
+       {
+               s_hengai_http_tcp_info.reconnect_count = 5;
+       }
+       else
+       {
+               reconnect_time = 10 * 1000 / 5;
+       }
+       
+       uos_timer_stop(s_hengai_http_tcp_info.relink_timer);
+       uos_timer_start(s_hengai_http_tcp_info.relink_timer, reconnect_time , 0, (void (*)(uint32_t))mmi_hengai_http_tcp_connect_msg, NULL);
+}
+
+void mmi_hengai_http_tcp_read_data(void *param)
+{      
+       mmi_hengai_http_socket_fd_t * data_info = (mmi_hengai_http_socket_fd_t *)param;
+       if((NULL == data_info) || (data_info->socket_fd < 0))
+       {
+               printf("[@CHENG_DEBUG][%s][%d]: \n",__FUNCTION__,__LINE__);
+               return;
+       }
+
+       int recv_ret = -1;
+       int recv_len = 0;
+       char * recv_buf = (char *)Hal_Mem_Alloc(HENGAI_HTTP_RECEIVE_BUFF_LEN);
+       if(NULL == recv_buf)
+       {
+               printf("[@CHENG_DEBUG][%s][%d]: recv_buf alloc fail\n",__FUNCTION__,__LINE__);
+               return;
+       }
+       Hal_Mem_Set(recv_buf , 0x00, HENGAI_HTTP_RECEIVE_BUFF_LEN);
+       recv_ret = ValRecvEx(data_info->socket_fd, HENGAI_HTTP_SOCKET_REV_TIMEOUT, recv_buf, HENGAI_HTTP_RECEIVE_BUFF_LEN, &recv_len);
+       printf("[@CHENG_DEBUG][%s][%d]: recv_ret=%d,recv_len=%d,recv_buf=0x%x\n", __FUNCTION__, __LINE__, recv_ret, recv_len, recv_buf);
+       printf("[@CHENG_DEBUG][%d]: str=%s\n", __LINE__, recv_buf);
+       if(0 <= recv_ret)
+       {
+               mmi_hengai_http_data_receive(recv_buf, recv_len);
+//             mmi_protocol_receive_data_process(recv_str, recv_len);
+       }
+
+       if(NULL != recv_buf)
+       {
+               printf("[@CHENG_DEBUG][%s][%d]: recv_buf free\n",__FUNCTION__,__LINE__);
+               Hal_Mem_Free(recv_buf);
+               recv_buf = NULL;
+       }
+}
+
+static void mm_hengai_http_r_task_entry(void * para)
+{
+    while(s_hengai_http_r_task_id == NULL)
+       {
+        uos_sleep(10);
+    }
+
+    while(1)
+       {
+        // receive message
+        mmi_hengai_http_task_msg_t * msg = (mmi_hengai_http_task_msg_t *)Hal_Receive_Message((TASK_ID)s_hengai_http_r_task_id, TRUE);
+               MMI_HENGAI_HTTP_TCP_MSG_ID_E msg_id = msg->cmd_type;
+               void * msg_param = msg->cmd_param;
+
+               printf("[@CHENG_DEBUG][%s][%d]: msg_id=%d\n",__FUNCTION__,__LINE__, msg_id);
+               switch(msg_id)
+               {
+                       case MMI_HENGAI_HTTP_TCP_MSG_CONNECT:
+                               mmi_hengai_http_tcp_connect(msg_param);
+                               break;
+       
+                       case MMI_HENGAI_HTTP_TCP_MSG_CONNECTED:
+                               mmi_hengai_http_tcp_connected(msg_param);
+                               break;
+       
+                       case MMI_HENGAI_HTTP_TCP_MSG_DISCONNECT:
+                               mmi_hengai_http_tcp_disconnect(msg_param);
+                               break;
+       
+                       case MMI_HENGAI_HTTP_TCP_MSG_RECONNECT:
+                               mmi_hengai_http_tcp_reconnect(msg_param);
+                               break;
+       
+                       case MMI_HENGAI_HTTP_TCP_MSG_READ:
+                               mmi_hengai_http_tcp_read_data(msg_param);
+                               break;
+                       
+                       default:
+                               break;
+               }
+               
+        Hal_Mem_Free(msg->cmd_param);
+        Hal_Mem_Free(msg);
+    }
+}
+
+static void mm_hengai_http_r_task_init(void)
+{
+       s_hengai_http_r_task_id = uos_create_task(mm_hengai_http_r_task_entry,
+                                                                                               NULL,
+                                                                                               64,
+                                                                                               MMI_HENGAI_HTTP_R_TASK_STACK_SIZE,
+                                                                                               MMI_HENGAI_HTTP_R_TASK_PRIORITY,
+                                                                                               "mm_hengai_http_r_task");
+
+       printf("[@CHENG_DEBUG][%s][%d]: task_id=0x%x\n",__FUNCTION__,__LINE__, s_hengai_http_r_task_id);
+}
+
+
+// send task
+void mm_hengai_http_s_task_msg_send(MMI_AI_TALK_ACTION_CMD_E action_cmd)
+{
+       if(NULL != s_hengai_http_s_task_id)
+       {
+        mmi_hengai_http_task_msg_t * msg = Hal_Mem_Alloc(sizeof(mmi_hengai_http_task_msg_t));
+               msg->cmd_type = action_cmd;
+               msg->cmd_param = NULL;
+               
+        Hal_Send_Message((TASK_ID)s_hengai_http_s_task_id, (void *)msg);
+    }
+       else
+       {
+               printf("[@CHENG_DEBUG][%s][%d]: \n",__FUNCTION__, __LINE__);
+               mm_hengai_http_send_space_free(action_cmd);
+       }
+}
+
+static void mm_hengai_http_s_task_handle(void *param)
+{
+       MMI_AI_TALK_ACTION_CMD_E action_cmd = ((mmi_hengai_http_task_msg_t *)param)->cmd_type;
+       
+       if((false == watch_modem_sim_present_check_req())
+               || (MMI_MODEM_SIGNAL_BAR_0 == watch_modem_get_signal_bar_req())
+               )
+       {
+               printf("[@CHENG_DEBUG][%s][%d]: \n",__FUNCTION__,__LINE__);
+               mm_hengai_http_send_space_free(action_cmd);
+               return;
+       }
+
+       unsigned char * send_buff = (unsigned char *)mm_hengai_http_send_space_ptr_get(action_cmd);
+       int send_size = mm_hengai_http_send_space_size_get(action_cmd);
+       printf("[@CHENG_DEBUG][%s][%d]: len=%d\n", __FUNCTION__, __LINE__, send_size);
+       printf("[@CHENG_DEBUG][%d]: str=%s\n", __LINE__, send_buff);
+       
+       if((NULL != send_buff) && (0 < send_size))
+       {
+               int sockfd = s_hengai_http_tcp_info.sock_fd;
+               
+               if(sockfd > 0)
+               {
+                       int ret = -1;
+                       ret = ValSend(sockfd, HENGAI_HTTP_SOCKET_REV_TIMEOUT, send_buff, send_size);
+                       printf("[@CHENG_DEBUG][%s][%d]: sock_fd=%d,ret=%d\n", __FUNCTION__, __LINE__, sockfd, ret);
+                       if(ret < 0)
+                       {
+                               printf("[@CHENG_DEBUG][%s][%d]: ValSend fail\n", __FUNCTION__, __LINE__);
+                       }
+               }
+               else
+               {
+                       printf("[@CHENG_DEBUG][%s][%d]: sock_fd=%d\n", __FUNCTION__, __LINE__, sockfd);
+                       mmi_hengai_http_tcp_reconnect_msg(NULL);
+               }
+       }
+       
+       mm_hengai_http_send_space_free(action_cmd);
+}
+
+static void mm_hengai_http_s_task_entry(void *param)
+{
+    while(NULL == s_hengai_http_s_task_id)
+    {
+        uos_sleep(10);
+    }
+       
+    while(1)
+    {
+        mmi_hengai_http_task_msg_t * msg = (mmi_hengai_http_task_msg_t *)Hal_Receive_Message((TASK_ID)s_hengai_http_s_task_id, TRUE);
+        if(!msg)
+            continue;
+
+               mm_hengai_http_s_task_handle((void *)msg);
+        Hal_Mem_Free(msg);
+    }
+}
+
+static void mm_hengai_http_s_task_init(void)
+{
+       s_hengai_http_s_task_id = uos_create_task(mm_hengai_http_s_task_entry, 
+                                                                                               NULL, 
+                                                                                               64, 
+                                                                                               MMI_HENGAI_HTTP_S_TASK_STACK_SIZE, 
+                                                                                               MMI_HENGAI_HTTP_S_TASK_PRIORITY, 
+                                                                                               "mm_hengai_http_s_task");
+
+       printf("[@CHENG_DEBUG][%s][%d]: task_id=0x%x\n",__FUNCTION__,__LINE__, s_hengai_http_s_task_id);
+}
+
+void mmi_hengai_http_tcp_info_init(void)
+{
+       s_hengai_http_tcp_info.sock_fd = -1;
+       s_hengai_http_tcp_info.connect_flag = false;
+       s_hengai_http_tcp_info.connecting_flag = false;
+       s_hengai_http_tcp_info.first_connect_flag = false;
+       s_hengai_http_tcp_info.reconnect_count = 5;
+       
+       if(NULL != s_hengai_http_tcp_info.relink_timer)
+       {
+               uos_timer_stop(s_hengai_http_tcp_info.relink_timer);
+               uos_timer_delete(s_hengai_http_tcp_info.relink_timer);
+               s_hengai_http_tcp_info.relink_timer = NULL;
+       }
+       uos_timer_create(&s_hengai_http_tcp_info.relink_timer);
+}
+
+void mm_hengai_http_task_init(void)
+{
+    if(false == watch_modem_sim_present_check_req()
+               //|| (MMI_MODEM_SIGNAL_BAR_0 == watch_modem_get_signal_bar_req())
+               )
+       {
+               return;
+       }
+       
+       mmi_hengai_http_tcp_info_init();
+       mm_hengai_http_r_task_init();
+       mm_hengai_http_s_task_init();
+}
+
+#endif
+
+
+
diff --git a/2.sdk/sdk/gui/lv_watch/lv_apps/custom_function/heng_ai_http_protocol.h b/2.sdk/sdk/gui/lv_watch/lv_apps/custom_function/heng_ai_http_protocol.h
new file mode 100644 (file)
index 0000000..785df5a
--- /dev/null
@@ -0,0 +1,86 @@
+
+
+
+#ifndef __HENG_AI_HTTP_PROTOCOL_H__
+#define __HENG_AI_HTTP_PROTOCOL_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef LV_CONF_INCLUDE_SIMPLE
+#include "lvgl.h"
+#include "lv_ex_conf.h"
+#else
+#include "../../../lvgl/lvgl.h"
+#include "../../../lv_ex_conf.h"
+#endif
+
+#ifdef __MMI_CUSTOM_HENG_AI__
+
+// http://test.aicaring.com/
+
+
+#include "../../../../product/craneg_modem/cust/fit/inc/sdknet.h"
+
+
+#define MMI_HENGAI_HTTP_IP_ADDRESS             ("ability.raisound.com") // http://test.aicaring.com/
+#define MMI_HENGAI_HTTP_IP_PORT                (8899)
+
+#define HENGAI_HTTP_SOCKET_SEND_TIMEOUT  3
+#define HENGAI_HTTP_SOCKET_REV_TIMEOUT  3
+
+#define HENGAI_HTTP_RECEIVE_BUFF_LEN  (1024 * 2)
+
+
+typedef enum
+{
+       MMI_HENGAI_HTTP_TCP_MSG_ID_START,
+   
+    MMI_HENGAI_HTTP_TCP_MSG_CONNECT,
+    MMI_HENGAI_HTTP_TCP_MSG_CONNECTED,
+    MMI_HENGAI_HTTP_TCP_MSG_DISCONNECT,
+    MMI_HENGAI_HTTP_TCP_MSG_RECONNECT,
+    MMI_HENGAI_HTTP_TCP_MSG_SEND,
+    MMI_HENGAI_HTTP_TCP_MSG_READ,
+    
+    MMI_HENGAI_HTTP_TCP_MSG_ID_END
+}MMI_HENGAI_HTTP_TCP_MSG_ID_E;
+
+
+typedef struct {
+       signed long sock_fd;
+       unsigned char connect_flag;
+       unsigned char connecting_flag;
+       unsigned char first_connect_flag;
+       char reconnect_count;
+       
+       void *relink_timer;
+}mmi_hengai_http_tcp_info_t;
+
+
+typedef struct
+{
+       uint16_t cmd_type;
+       void * cmd_param;
+}mmi_hengai_http_task_msg_t;
+
+typedef struct
+{
+       int socket_fd;
+       int len;
+} mmi_hengai_http_socket_fd_t;
+
+
+void mm_hengai_http_task_init(void);
+
+
+
+#endif
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif
+