You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

448 lines
17 KiB

#include "display_manager.h"
#include "../../../screen_res/logo_mono.c"
//
#include <stdarg.h>
#include "basic/ssd1306/driver_ssd1306.h"
#include "basic/ssd1306/driver_ssd1306_basic.h"
#include "basic/ssd1306/wave_drawer.h"
#include "board/board_battery_state.h"
#include "config.h"
#include "font.h"
#include "heart_wave_sample_service.h"
#include "one_conduction_board.h"
PageState_t g_pageState;
void dsp_mgr_change_to_page(page_t page) { //
g_pageState.page = page;
g_pageState.last_page = page;
g_pageState.page_change_to_page_time = znordic_getpower_on_s();
g_pageState.in_prompt = false;
memset(g_pageState.prompt, 0, sizeof(g_pageState.prompt));
}
uint32_t dsp_mgr_get_page_elapsed_time_s(void) { //
return znordic_getpower_on_s() - g_pageState.page_change_to_page_time;
}
void dsp_mgr_schedule(void) {}
PageState_t* dsp_mgr_get_state(void) { return NULL; }
int compute_x_pos_by_center(int16_t x, int16_t width) { return x - width / 2; }
int compute_y_pos_by_center(int16_t y, int16_t height) { return y - height / 2; }
#define SCREEN_CENTER_X 64
#define SCREEN_CENTER_Y 32
#define CHARGE_BATTERY_WIDTH (12 * 1.2)
#define CHARGE_BATTERY_HEIGHT (22 * 1.2)
#define MAIN_PAGE_BATTERY_WIDTH (12) // 首页电池宽度
#define MAIN_PAGE_BATTERY_HEIGHT (22) // 首页电池高度
/*******************************************************************************
* 充电页面 *
*******************************************************************************/
/**
* 显示元素:
* 1.电池电量
* ---------------
* | _ |
* | | | |
* | |
* ---------------
*
* 动画效果:
* 1. 电池电量变化
*
*/
static uint32_t m_nowshowbatterylevel; // 当前显示的电池电量
void dsp_mgr_change_to_chargingPage() {
ssd1306_basic_clear();
uint8_t x = compute_x_pos_by_center(SCREEN_CENTER_X, CHARGE_BATTERY_WIDTH);
uint8_t y = compute_y_pos_by_center(SCREEN_CENTER_Y, CHARGE_BATTERY_HEIGHT);
uint8_t xchange, ychange;
ssd1306_basic_draw_battery_level(x, y, &xchange, &ychange, BoardBattery_get_battery_level(), CHARGE_BATTERY_WIDTH, CHARGE_BATTERY_HEIGHT);
m_nowshowbatterylevel = BoardBattery_get_battery_level();
ssd1306_basic_gram_update();
dsp_mgr_change_to_page(kPage_chargingPage);
}
void chargingPage_set_batteryLevel(int batteryLevel) {
uint8_t x = compute_x_pos_by_center(SCREEN_CENTER_X, CHARGE_BATTERY_WIDTH);
uint8_t y = compute_y_pos_by_center(SCREEN_CENTER_Y, CHARGE_BATTERY_HEIGHT);
uint8_t xchange, ychange;
ssd1306_basic_draw_battery_level(x, y, &xchange, &ychange, batteryLevel, CHARGE_BATTERY_WIDTH, CHARGE_BATTERY_HEIGHT);
ssd1306_basic_gram_update();
}
void chargingPage_schedule() { //
static uint32_t last_update_time = 0;
if (znordic_haspassed_ms(last_update_time) < 300) {
return;
}
last_update_time = znordic_getpower_on_ms();
m_nowshowbatterylevel += 5;
if (m_nowshowbatterylevel > 100) {
m_nowshowbatterylevel = BoardBattery_get_battery_level();
}
chargingPage_set_batteryLevel(m_nowshowbatterylevel);
}
/*******************************************************************************
* 欢迎页面 *
*******************************************************************************/
void dsp_mgr_change_to_welcome() {
/**
* @brief 切换到欢迎界面
* 1. 加载屏幕外设
* 2. 打开屏幕电源
* 3. 初始化开机页面
*/
// ssd1306_basic_string(0, 0, "123456789123456789123", 21, 0, SSD1306_FONT_12);
ssd1306_basic_draw_screen((const char*)gImage_logo_mono);
ssd1306_basic_gram_update();
dsp_mgr_change_to_page(kPage_welcome);
}
void welcomePage_schedule() {}
/*******************************************************************************
* 首页 *
*******************************************************************************/
static bool m_main_page_colon_state = false;
void mainPage_show(bool colon_state) {
static ztm_t now;
int16_t batterylevel;
uint8_t xchange, ychange;
uint8_t x, y;
x = compute_x_pos_by_center(SCREEN_CENTER_X, fontclocklib.widthPixel * 5 + MAIN_PAGE_BATTERY_WIDTH);
y = compute_y_pos_by_center(SCREEN_CENTER_Y, fontclocklib.heightPixel + 1);
znordic_rtc_gettime(&now);
batterylevel = BoardBattery_get_battery_level();
ssd1306_basic_clear_gram();
// ZLOGI("mainPage_show %d %d", colon_state, x, y);
ssd1306_basic_draw_str(x, y, &xchange, &ychange, fmt("%02d:%02d", now.tm_hour, now.tm_min), &fontclocklib);
x = x + 6 + xchange;
ssd1306_basic_draw_battery_level(x, y, &xchange, &ychange, batterylevel, MAIN_PAGE_BATTERY_WIDTH, MAIN_PAGE_BATTERY_HEIGHT);
ssd1306_basic_gram_update();
m_main_page_colon_state = colon_state;
dsp_mgr_change_to_page(kPage_main);
}
void dsp_mgr_change_to_main() { mainPage_show(true); }
void mainPage_updateState() { mainPage_show(!m_main_page_colon_state); }
void mainPage_schedule() {
static uint32_t last_update_time = 0;
if (znordic_haspassed_ms(last_update_time) < 300) {
return;
}
last_update_time = znordic_getpower_on_ms();
mainPage_updateState();
}
/*******************************************************************************
* 保持静止页面 *
*******************************************************************************/
static int m_prepare_page_progress = 0;
void PreparePage_show(int progress) {
m_prepare_page_progress = progress;
ssd1306_basic_clear_gram();
uint8_t x = 0;
uint8_t y = 0;
uint8_t xchange, ychange;
x = compute_x_pos_by_center(SCREEN_CENTER_X, font24x24_zh_lib.widthPixel * 4);
y = compute_y_pos_by_center(SCREEN_CENTER_Y, font24x24_zh_lib.heightPixel);
ssd1306_basic_draw_str(x, y, &xchange, &ychange, "保持静止", &font24x24_zh_lib);
if (progress == 0) {
ssd1306_basic_draw_str(x - font8x8_xo_lib.widthPixel, y - font8x8_xo_lib.heightPixel, &xchange, &ychange, "xxxx", &font8x8_xo_lib);
} else if (progress == 1) {
ssd1306_basic_draw_str(x - font8x8_xo_lib.widthPixel, y - font8x8_xo_lib.heightPixel, &xchange, &ychange, "oxxx", &font8x8_xo_lib);
} else if (progress == 2) {
ssd1306_basic_draw_str(x - font8x8_xo_lib.widthPixel, y - font8x8_xo_lib.heightPixel, &xchange, &ychange, "ooxx", &font8x8_xo_lib);
} else if (progress == 3) {
ssd1306_basic_draw_str(x - font8x8_xo_lib.widthPixel, y - font8x8_xo_lib.heightPixel, &xchange, &ychange, "ooox", &font8x8_xo_lib);
} else if (progress == 4) {
ssd1306_basic_draw_str(x - font8x8_xo_lib.widthPixel, y - font8x8_xo_lib.heightPixel, &xchange, &ychange, "oooo", &font8x8_xo_lib);
}
ssd1306_basic_gram_update();
}
void dsp_mgr_change_to_preparePage() {
PreparePage_show(0);
dsp_mgr_change_to_page(kPage_preparePage);
}
void dsp_mgr_preparePage_set_progress(int progress) { PreparePage_show(progress); }
int dsp_mgr_preparePage_get_progress() { return m_prepare_page_progress; }
void PreparePage_schedule() {}
/*******************************************************************************
* 采样页面 *
*******************************************************************************/
#define SMAPLE_PAGE_START_X 1
#define SMAPLE_PAGE_START_Y 1
typedef struct {
wave_drawer_t wave_drawer;
int wave_drawser_x;
int wave_drawser_y;
int wave_drawser_hight;
int wave_drawser_width;
int progress_x;
int progress_y;
int progress_width;
int progress_hight;
int heartrate_x;
int heartrate_y;
} sample_page_state_t;
sample_page_state_t m_sample_page_state;
#if 0
void dsp_mgr_change_to_sampling(int progress_s, int heartrate) { //
sample_page_state_t* sps = &m_sample_page_state;
sps->wave_drawser_x = SMAPLE_PAGE_START_X;
sps->wave_drawser_y = SMAPLE_PAGE_START_Y;
sps->wave_drawser_hight = 40;
sps->wave_drawser_width = 120;
sps->progress_x = SMAPLE_PAGE_START_X + 1;
sps->progress_y = SMAPLE_PAGE_START_Y + sps->wave_drawser_hight + 3 + 4;
sps->progress_width = 80;
sps->progress_hight = 8;
sps->heartrate_x = sps->progress_x + sps->progress_width + 2;
sps->heartrate_y = sps->progress_y - 4;
int progress = progress_s / SAMPLE_MIN_TIME_S * 25;
ssd1306_basic_clear_gram();
wave_drawer_init(&sps->wave_drawer, sps->wave_drawser_x, sps->wave_drawser_y, sps->wave_drawser_width, sps->wave_drawser_hight);
wave_drawer_draw_border(&sps->wave_drawer);
uint8_t xchange, ychange;
ssd1306_basic_draw_progress(sps->progress_x, sps->progress_y, sps->progress_width, sps->progress_hight, 25, progress);
if (heartrate <= 0) {
ssd1306_basic_draw_str(sps->heartrate_x, sps->heartrate_y, &xchange, &ychange, "<>-- ", &font_asicc16x8_lib);
} else {
ssd1306_basic_draw_str(sps->heartrate_x, sps->heartrate_y, &xchange, &ychange, fmt("<>%3d", heartrate), &font_asicc16x8_lib);
}
ssd1306_basic_gram_update();
dsp_mgr_change_to_page(kPage_sampling);
}
void samplePage_update_state(int progress_s, int wave_y, int heartrate, bool update_screen) { //
sample_page_state_t* sps = &m_sample_page_state;
uint8_t xchange, ychange;
int progress = progress_s / SAMPLE_MIN_TIME_S * 25;
if (progress_s / 10 == 0) {
ssd1306_basic_draw_str(sps->progress_x, sps->progress_y - 8, &xchange, &ychange, "xxx", &font8x8_xo_lib);
} else if (progress_s / 10 == 1) {
ssd1306_basic_draw_str(sps->progress_x, sps->progress_y - 8, &xchange, &ychange, "oxx", &font8x8_xo_lib);
} else if (progress_s / 10 == 2) {
ssd1306_basic_draw_str(sps->progress_x, sps->progress_y - 8, &xchange, &ychange, "oox", &font8x8_xo_lib);
} else if (progress_s / 10 == 3) {
ssd1306_basic_draw_str(sps->progress_x, sps->progress_y - 8, &xchange, &ychange, "ooo", &font8x8_xo_lib);
}
wave_drawer_draw_next_point(&sps->wave_drawer, wave_y);
ssd1306_basic_draw_progress(sps->progress_x, sps->progress_y, sps->progress_width, sps->progress_hight, 25, progress);
if (heartrate <= 0) {
ssd1306_basic_draw_str(sps->heartrate_x, sps->heartrate_y, &xchange, &ychange, "<>-- ", &font_asicc16x8_lib);
} else {
ssd1306_basic_draw_str(sps->heartrate_x, sps->heartrate_y, &xchange, &ychange, fmt("<>%3d", heartrate), &font_asicc16x8_lib);
}
if (update_screen) ssd1306_basic_gram_update();
}
#endif
void dsp_mgr_change_to_sampling(int progress_s, int heartrate) { //
sample_page_state_t* sps = &m_sample_page_state;
sps->progress_x = SMAPLE_PAGE_START_X + 10;
sps->progress_y = SMAPLE_PAGE_START_Y + 3;
sps->progress_width = 100;
sps->progress_hight = 8;
sps->wave_drawser_x = SMAPLE_PAGE_START_X + 5;
sps->wave_drawser_y = SMAPLE_PAGE_START_Y + sps->progress_hight + 5;
sps->wave_drawser_hight = 45;
sps->wave_drawser_width = 85;
sps->heartrate_x = sps->wave_drawser_x + sps->wave_drawser_width + 1;
sps->heartrate_y = sps->wave_drawser_y + 5;
int progress = progress_s / SAMPLE_MIN_TIME_S * 25;
uint8_t xchange, ychange;
ssd1306_basic_clear_gram();
/**
* @brief
* =================
* | | 心
* | wave |
* | | 心率
*/
ssd1306_basic_draw_progress(sps->progress_x, sps->progress_y, sps->progress_width, sps->progress_hight, 25, progress);
// ssd1306_basic_draw_str(sps->progress_x + sps->progress_width + 2, sps->progress_y, &xchange, &ychange, "x", &font8x8_xo_lib);
wave_drawer_init(&sps->wave_drawer, sps->wave_drawser_x, sps->wave_drawser_y, sps->wave_drawser_width, sps->wave_drawser_hight);
// wave_drawer_draw_border(&sps->wave_drawer);
ssd1306_basic_draw_str(sps->heartrate_x + 2, sps->heartrate_y, &xchange, &ychange, "<>", &font_asicc16x8_lib);
if (heartrate <= 0) {
ssd1306_basic_draw_str(sps->heartrate_x, sps->heartrate_y + 20, &xchange, &ychange, "-- ", &font_asicc16x8_lib);
} else {
ssd1306_basic_draw_str(sps->heartrate_x, sps->heartrate_y + 20, &xchange, &ychange, fmt("%3d", heartrate), &font_asicc16x8_lib);
}
ssd1306_basic_gram_update();
dsp_mgr_change_to_page(kPage_sampling);
}
void samplePage_update_state(int progress_s, int wave_y, int heartrate, bool updateHeart, bool update_screen) { //
sample_page_state_t* sps = &m_sample_page_state;
uint8_t xchange, ychange;
static bool heart_logo_state = false;
int progress = progress_s / SAMPLE_MIN_TIME_S * 25;
ssd1306_basic_draw_progress(sps->progress_x, sps->progress_y, sps->progress_width, sps->progress_hight, 25, progress);
// if (progress_s / 10 >= 3) {
// ssd1306_basic_draw_str(sps->progress_x + sps->progress_width + 2, sps->progress_y, &xchange, &ychange, "o", &font8x8_xo_lib);
// } else {
// ssd1306_basic_draw_str(sps->progress_x + sps->progress_width + 2, sps->progress_y, &xchange, &ychange, "x", &font8x8_xo_lib);
// }
if (update_screen && updateHeart) {
if (heart_logo_state) {
ssd1306_basic_draw_str(sps->heartrate_x + 2, sps->heartrate_y, &xchange, &ychange, "<>", &font_asicc16x8_lib);
} else {
ssd1306_basic_draw_str(sps->heartrate_x + 2, sps->heartrate_y, &xchange, &ychange, " ", &font_asicc16x8_lib);
}
heart_logo_state = !heart_logo_state;
}
if (heartrate <= 0) {
ssd1306_basic_draw_str(sps->heartrate_x, sps->heartrate_y + 20, &xchange, &ychange, "-- ", &font_asicc16x8_lib);
} else {
if (heartrate >= 100) {
ssd1306_basic_draw_str(sps->heartrate_x, sps->heartrate_y + 20, &xchange, &ychange, fmt("%d", heartrate), &font_asicc16x8_lib);
} else {
ssd1306_basic_draw_str(sps->heartrate_x + 4, sps->heartrate_y + 20, &xchange, &ychange, fmt("%d", heartrate), &font_asicc16x8_lib);
}
}
wave_drawer_draw_next_point(&sps->wave_drawer, wave_y);
if (update_screen) ssd1306_basic_gram_update();
}
void samplePage_schedule() {
static int count = 0;
count++;
int capturetime = hwss_has_captured_time_ms();
int wave_y = (int)hwss_read_val();
int heartrate = (int)hwss_read_heart_rate();
// ZLOGI("samplePage_schedule %d %d %d", capturetime, wave_y, heartrate);
samplePage_update_state(capturetime / 1000, wave_y, hwss_read_heart_rate(), count % 30 == 0, count % 10 == 0);
}
/*******************************************************************************
* samplingError *
*******************************************************************************/
void dsp_mgr_change_to_samplingError() {
/**
* @brief
* 不足30秒[X]
*/
ssd1306_basic_clear_gram();
uint8_t x;
uint8_t y;
x = compute_x_pos_by_center(SCREEN_CENTER_X, font24x24_zh_lib.widthPixel * 3 + font12x24_asiic_lib.widthPixel * 2);
y = compute_y_pos_by_center(SCREEN_CENTER_Y, font24x24_zh_lib.heightPixel);
uint8_t xchange, ychange;
ssd1306_basic_draw_str(x, y, &xchange, &ychange, "不足", &font24x24_zh_lib);
x = x + xchange;
ssd1306_basic_draw_str(x, y, &xchange, &ychange, "30", &font12x24_asiic_lib);
x = x + xchange;
ssd1306_basic_draw_str(x, y, &xchange, &ychange, "", &font24x24_zh_lib);
x = x + xchange;
ssd1306_basic_gram_update();
dsp_mgr_change_to_page(kPage_samplingError);
}
void dsp_mgr_change_to_sampleSuc() {
/**
* @brief
* 1.进度条
* 2.提示信息
*/
ssd1306_basic_clear();
uint8_t x = 0;
uint8_t y = 0;
uint8_t xchange, ychange;
x = compute_x_pos_by_center(SCREEN_CENTER_X, font24x24_zh_lib.widthPixel * 4);
y = compute_y_pos_by_center(SCREEN_CENTER_Y, font24x24_zh_lib.heightPixel);
ssd1306_basic_draw_str(x, y, &xchange, &ychange, "采集完成", &font24x24_zh_lib);
ssd1306_basic_gram_update();
dsp_mgr_change_to_page(kPage_storagingSuc);
}
/*******************************************************************************
* SCHEDULE *
*******************************************************************************/
APP_TIMER_DEF(m_dsp_mgr_schedule_tmr);
static void dsp_mgr_schedule_tmr_cb(void* p_context) { //
if (g_pageState.page == kPage_chargingPage) {
chargingPage_schedule();
} else if (g_pageState.page == kPage_welcome) {
welcomePage_schedule();
} else if (g_pageState.page == kPage_main) {
mainPage_schedule();
} else if (g_pageState.page == kPage_preparePage) {
PreparePage_schedule();
} else if (g_pageState.page == kPage_sampling) {
samplePage_schedule();
}
}
void dsp_mgr_init(void) {
static bool timer_inited = false;
SingleLeadECG_screen_init();
if (!timer_inited) {
ZERROR_CHECK(app_timer_create(&m_dsp_mgr_schedule_tmr, APP_TIMER_MODE_REPEATED, dsp_mgr_schedule_tmr_cb));
}
// 此处周期决定采样一个页面显示的宽度
ZERROR_CHECK(app_timer_start(m_dsp_mgr_schedule_tmr, APP_TIMER_TICKS(12), NULL));
timer_inited = true;
}
void dsp_mgr_uninit(void) {
app_timer_stop(m_dsp_mgr_schedule_tmr);
SingleLeadECG_screen_deinit();
}