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.
392 lines
15 KiB
392 lines
15 KiB
#include <math.h>
|
|
|
|
#include "basic_service/app_event.h"
|
|
#include "basic_service/app_event_distribute.h"
|
|
#include "basic_service/device_version_info_mgr.h"
|
|
//
|
|
#include "board/board_adc_module_ctrl.h"
|
|
#include "board/board_battery_state.h"
|
|
#include "board/board_beep_ctrl.h"
|
|
#include "board/board_ecg_sensor.h"
|
|
#include "board/board_light_ctrl.h"
|
|
#include "board/board_power_mgr.h"
|
|
//
|
|
#include "board/ads129x/ads129x.h"
|
|
#include "board/app_board.h"
|
|
#include "service/ble_cmd_processer/ble_cmd_process_service.h"
|
|
#include "service/display_mgr/display_manager.h"
|
|
#include "service/heart_wave_sample_service/heart_wave_sample_service.h"
|
|
#include "service/storage/storage_service.h"
|
|
#include "zble_module.h"
|
|
#include "zdatachannel_service.h"
|
|
#include "znordic.h"
|
|
|
|
/*******************************************************************************
|
|
* GLOBAL *
|
|
*******************************************************************************/
|
|
|
|
static int m_cur_fd;
|
|
static sample_data_filename_t sampledata_file_name;
|
|
|
|
#define SCHED_MAX_EVENT_DATA_SIZE MAX(sizeof(app_event_t), APP_TIMER_SCHED_EVENT_DATA_SIZE)
|
|
|
|
/*******************************************************************************
|
|
* 事件处理 *
|
|
*******************************************************************************/
|
|
void ENTER_DEEP_SLEEP() {
|
|
// 进入深度睡眠前,使能唤醒引脚
|
|
BoardBattery_sence_gpio_init_before_sleep();
|
|
// nrf_sdh_disable_request();
|
|
app_timer_pause();
|
|
nrf_sdh_suspend();
|
|
sd_power_system_off();
|
|
NVIC_SystemReset();
|
|
}
|
|
|
|
/*******************************************************************************
|
|
* 状态切换方法 *
|
|
*******************************************************************************/
|
|
|
|
static void on_state_change(device_state_t from, device_state_t to) {
|
|
/**
|
|
* @brief 开关机控制
|
|
*/
|
|
if (from == kdevice_state_standby && to != kdevice_state_standby) {
|
|
/**
|
|
* @brief 切换到工作状态
|
|
*/
|
|
BoardBeepCtrl_load();
|
|
BoardLight_load();
|
|
|
|
sample_data_mgr_init();
|
|
dsp_mgr_init();
|
|
ble_cmder_init();
|
|
ble_cmder_start_adv();
|
|
|
|
app_board_change_state(kapp_power_state_working);
|
|
|
|
} else if (to == kdevice_state_standby) {
|
|
/**
|
|
* @brief 切换到待机模式
|
|
*
|
|
*/
|
|
dsp_mgr_uninit();
|
|
sample_data_mgr_uninit();
|
|
|
|
BoardLight_unload();
|
|
|
|
BoardBeepCtrl_unload();
|
|
ble_stop_upload_record();
|
|
zble_module_disconnect();
|
|
for (size_t i = 0; i < 100; i++) {
|
|
nrf_delay_ms(10);
|
|
if (!zble_module_is_connected()) {
|
|
break;
|
|
}
|
|
}
|
|
ble_cmder_stop_adv();
|
|
ble_cmder_uninit();
|
|
board_power_mgr_main_power_supply_set(false);
|
|
app_board_change_state(kapp_power_state_standby);
|
|
}
|
|
|
|
/***********************************************************************************************************************
|
|
* 切换状态 附带操作 *
|
|
***********************************************************************************************************************/
|
|
if (to == kdevice_state_home) {
|
|
dsp_mgr_change_to_main();
|
|
} else if (to == kdevice_state_poweron) {
|
|
dsp_mgr_change_to_welcome();
|
|
} else if (to == kdevice_state_charging) {
|
|
dsp_mgr_change_to_chargingPage();
|
|
}
|
|
}
|
|
|
|
static void app_event_listener(void* p_event_data, uint16_t event_size) {
|
|
if (!p_event_data) return;
|
|
app_event_t* p_event = (app_event_t*)p_event_data;
|
|
|
|
if (ds_now_state() != kdevice_state_standby && //
|
|
ds_now_state() != kdevice_state_charging && //
|
|
ds_now_state() != kdevice_state_poweron //
|
|
) {
|
|
if (zdatachannel_is_connected()) {
|
|
BoardLight_setGreenLightEffect(kLightEffect_slowFlash);
|
|
} else {
|
|
BoardLight_setGreenLightEffect(kLightEffect_quickFlash);
|
|
}
|
|
}
|
|
|
|
/*******************************************************************************
|
|
* 待机状态 *
|
|
*******************************************************************************/
|
|
static uint32_t lasttrypoweron_time = 0;
|
|
|
|
if (ds_now_state() == kdevice_state_standby) {
|
|
// 充电事件触发 --> 切换到充电页面
|
|
if (BoardBattery_get_charging_state()) {
|
|
ds_change_to_state(kdevice_state_charging);
|
|
}
|
|
|
|
// 导联连接事件触发 --> 切换到开机中页面
|
|
|
|
else if (hwss_lead_get_state_connected_state() && znordic_haspassed_ms(lasttrypoweron_time) >= LOW_BATTERY_REMINDER_DELAY_MS) {
|
|
lasttrypoweron_time = znordic_getpower_on_ms();
|
|
// if (BoardBattery_get_battery_level() > APP_WORK_BATTERY_LEVEL) {
|
|
// TODO: 检查电池地量
|
|
if (true) {
|
|
ds_change_to_state(kdevice_state_poweron);
|
|
} else {
|
|
BoardLight_load();
|
|
BoardLight_blockFlash(3, 100);
|
|
BoardLight_unload();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief
|
|
* TODO:
|
|
* 1. 永远不进入超低功耗状态,直到电池电量低于一定程度
|
|
* 2. 如果RTC未被设置,则重置设备状态
|
|
* 3. 在每次从待机状态切换到开机状态,如果RTC未被设置,则清空已经存储的波形数据
|
|
*/
|
|
else if (ds_cur_state_haspassed_ms() >= 10000) {
|
|
if (!znordic_rtc_has_setted()) {
|
|
}
|
|
}
|
|
}
|
|
|
|
/*******************************************************************************
|
|
* 充电状态 *
|
|
*******************************************************************************/
|
|
else if (ds_now_state() == kdevice_state_charging) {
|
|
if (!BoardBattery_get_charging_state()) {
|
|
ds_change_to_state(kdevice_state_standby);
|
|
}
|
|
}
|
|
|
|
/*******************************************************************************
|
|
* 开机中 *
|
|
*******************************************************************************/
|
|
|
|
else if (ds_now_state() == kdevice_state_poweron) {
|
|
if (ds_cur_state_haspassed_ms() >= 1500) {
|
|
ds_change_to_state(kdevice_state_home);
|
|
}
|
|
}
|
|
|
|
/*******************************************************************************
|
|
* 首页 *
|
|
*******************************************************************************/
|
|
|
|
else if (ds_now_state() == kdevice_state_home) {
|
|
// 如果用户长时间不操作,自动切换到待机状态
|
|
if (!zdatachannel_is_connected() && //
|
|
!hwss_lead_get_state_connected_state() && //
|
|
ds_cur_state_haspassed_ms() >= AUTOMATIC_SLEEP_TIME) {
|
|
ds_change_to_state(kdevice_state_standby);
|
|
}
|
|
// 如果用户继续保持静止,切换到采集页面
|
|
else if (hwss_lead_get_state_connected_state() && ds_cur_state_haspassed_ms() > 1500) {
|
|
// dsp_mgr_change_to_preparePage
|
|
if (!BoardBattery_get_charging_state()) {
|
|
ds_change_to_state(kdevice_state_keep_still);
|
|
dsp_mgr_change_to_preparePage();
|
|
hwss_start_prepare_capture();
|
|
if (ble_is_upload_record()) {
|
|
ble_stop_upload_record();
|
|
}
|
|
}
|
|
}
|
|
#if 0
|
|
//TODO:使能
|
|
// 低电量,设备进入待机模式
|
|
else if (BoardBattery_get_battery_level() < APP_AUTO_STANDY_BATTERY_LEVEL && ds_cur_state_haspassed_ms() > 3000) {
|
|
ds_change_to_state(kdevice_state_standby);
|
|
} //
|
|
#endif
|
|
|
|
else if (!ble_is_upload_record() && zble_module_is_connected() && zdatachannel_last_rx_data_haspassed_s() >= BLE_UNCONNECTED_OVERTIME_S) {
|
|
ZLOGI("auto sleep because ble unconnected");
|
|
ds_change_to_state(kdevice_state_standby);
|
|
}
|
|
|
|
else if (BoardBattery_get_charging_state()) {
|
|
// BoardLight_setGreenLightEffect(kLightEffect_close);
|
|
ds_change_to_state(kdevice_state_standby);
|
|
}
|
|
}
|
|
|
|
/*******************************************************************************
|
|
* 保持静止页面 *
|
|
*******************************************************************************/
|
|
else if (ds_now_state() == kdevice_state_keep_still) {
|
|
if (!hwss_lead_get_state_connected_state()) {
|
|
// 如果用户未保持静止,切换到首页
|
|
ds_change_to_state(kdevice_state_home);
|
|
hwss_stop_capture();
|
|
} else {
|
|
/*******************************************************************************
|
|
* 页面加载中 *
|
|
*******************************************************************************/
|
|
if (ds_cur_state_haspassed_ms() >= (KEEP_STILL_OVERTIME_MS_1P5 * 5)) {
|
|
/**
|
|
* @brief
|
|
*
|
|
* 1. 启动采样定时器
|
|
* 2. 切换状态
|
|
* 3. 切换页面
|
|
*/
|
|
ds_change_to_state(kdevice_state_sampling);
|
|
dsp_mgr_change_to_sampling(0, 0);
|
|
hwss_start_capture();
|
|
static ztm_t tm;
|
|
memset(&sampledata_file_name, 0, sizeof(sampledata_file_name));
|
|
znordic_rtc_gettime(&tm);
|
|
sample_capture_state_reset();
|
|
|
|
sampledata_file_name.year = tm.tm_year + 1900 - 2000;
|
|
sampledata_file_name.month = tm.tm_mon + 1;
|
|
sampledata_file_name.day = tm.tm_mday;
|
|
sampledata_file_name.hour = tm.tm_hour;
|
|
sampledata_file_name.min = tm.tm_min;
|
|
sampledata_file_name.sec = tm.tm_sec;
|
|
m_cur_fd = sample_data_mgr_open(&sampledata_file_name, kwrflag_write_only);
|
|
BoardBeepCtrl_setEffect(kBoardBeepEffect_oneShortBeep);
|
|
|
|
} else if (ds_cur_state_haspassed_ms() >= (KEEP_STILL_OVERTIME_MS_1P5 * 4)) {
|
|
if (dsp_mgr_preparePage_get_progress() != 4) {
|
|
dsp_mgr_preparePage_set_progress(4);
|
|
}
|
|
} else if (ds_cur_state_haspassed_ms() >= (KEEP_STILL_OVERTIME_MS_1P5 * 3)) {
|
|
if (dsp_mgr_preparePage_get_progress() != 3) {
|
|
dsp_mgr_preparePage_set_progress(3);
|
|
}
|
|
} else if (ds_cur_state_haspassed_ms() >= (KEEP_STILL_OVERTIME_MS_1P5 * 2)) {
|
|
if (dsp_mgr_preparePage_get_progress() != 2) {
|
|
dsp_mgr_preparePage_set_progress(2);
|
|
}
|
|
} else if (ds_cur_state_haspassed_ms() >= (KEEP_STILL_OVERTIME_MS_1P5 * 1)) {
|
|
if (dsp_mgr_preparePage_get_progress() != 1) {
|
|
dsp_mgr_preparePage_set_progress(1);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/*******************************************************************************
|
|
* 采样页面逻辑 *
|
|
*******************************************************************************/
|
|
|
|
else if (ds_now_state() == kdevice_state_sampling) {
|
|
/*******************************************************************************
|
|
* 采样数据存储 *
|
|
*******************************************************************************/
|
|
if (p_event->eventType == kevent_capture_256data_event) {
|
|
if (hwss_has_captured_time_ms() <= (MAX_STORAGE_TIMEOUT_S * 1000)) {
|
|
sample_data_mgr_write(m_cur_fd, p_event->val.capture_data_cache, 256);
|
|
}
|
|
}
|
|
/*******************************************************************************
|
|
* 实时采样数据上报 *
|
|
*******************************************************************************/
|
|
if (p_event->eventType == kevent_capture_little_data_block_event) {
|
|
// 单帧实时上报
|
|
ZASSERT(LITTLE_DATA_BLOCK_FRAME_NUM == 5);
|
|
ble_cmder_try_report_one_sample_data(p_event->val.little_data_block.frameIndex, //
|
|
p_event->val.little_data_block.data[0], //
|
|
p_event->val.little_data_block.data[1], //
|
|
p_event->val.little_data_block.data[2], //
|
|
p_event->val.little_data_block.data[3], //
|
|
p_event->val.little_data_block.data[4]);
|
|
}
|
|
|
|
/*******************************************************************************
|
|
* 采样足30秒事件捕获 *
|
|
*******************************************************************************/
|
|
if (hwss_has_captured_time_ms() >= (SAMPLE_MIN_TIME_S * 1000)) {
|
|
if (!sample_capture_state_get()->is_over30s) {
|
|
BoardBeepCtrl_setEffect(kBoardBeepEffect_oneShortBeep);
|
|
sample_capture_state_set_is_over30s(true);
|
|
}
|
|
}
|
|
|
|
/*******************************************************************************
|
|
* 采样结束判定 *
|
|
*******************************************************************************/
|
|
bool capture_end = false;
|
|
if (hwss_has_captured_time_ms() >= (MAX_STORAGE_TIMEOUT_S * 1000)) {
|
|
capture_end = true;
|
|
} else if (p_event->eventType == kplod_disconnected_event) {
|
|
ble_cmder_try_report_sensor_drop_event(0x01, 0);
|
|
capture_end = true;
|
|
}
|
|
|
|
if (capture_end) {
|
|
if (sample_capture_state_get()->is_over30s) {
|
|
sample_data_mgr_close(m_cur_fd);
|
|
dsp_mgr_change_to_sampleSuc();
|
|
BoardBeepCtrl_setEffect(kBoardBeepEffect_oneShortBeep);
|
|
ds_change_to_state(kdevice_state_sampling_complete);
|
|
hwss_stop_capture();
|
|
|
|
} else {
|
|
// 采样不足三十秒
|
|
|
|
// 停止采样
|
|
hwss_stop_capture();
|
|
// 关闭文件
|
|
sample_data_mgr_close(m_cur_fd);
|
|
// 删除文件
|
|
sample_data_mgr_delete_file(&sampledata_file_name);
|
|
// 切换到采集出错页面
|
|
dsp_mgr_change_to_samplingError();
|
|
BoardBeepCtrl_setEffect(kBoardBeepEffect_threeShortBeep);
|
|
ds_change_to_state(kdevice_state_sampling_error);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
/*******************************************************************************
|
|
* 采样完成页面 *
|
|
*******************************************************************************/
|
|
else if (ds_now_state() == kdevice_state_sampling_complete) {
|
|
if (ds_cur_state_haspassed_ms() >= 3000) {
|
|
ZLOGI("ds_cur_state_haspassed_ms() %d> 3000", ds_cur_state_haspassed_ms());
|
|
ds_change_to_state(kdevice_state_home);
|
|
ble_cmder_report_sample_finish_event();
|
|
}
|
|
}
|
|
/*******************************************************************************
|
|
* 采样错误页面 *
|
|
*******************************************************************************/
|
|
else if (ds_now_state() == kdevice_state_sampling_error) {
|
|
if ((ds_cur_state_haspassed_ms() >= 3000) || //
|
|
(ds_cur_state_haspassed_ms() >= 1000 && hwss_lead_get_state_connected_state())) {
|
|
ZLOGI("ds_cur_state_haspassed_ms() %d> 3000", ds_cur_state_haspassed_ms());
|
|
ds_change_to_state(kdevice_state_home);
|
|
ble_cmder_report_sample_finish_event();
|
|
}
|
|
}
|
|
}
|
|
/*******************************************************************************
|
|
* MAIN_CODE *
|
|
*******************************************************************************/
|
|
|
|
void one_conduction_main() {
|
|
ZLOGI("one_conduction_main");
|
|
AppEvent_regListener(app_event_listener);
|
|
|
|
app_board_init();
|
|
BoardBeepCtrl_init();
|
|
BoardLight_Init();
|
|
/**
|
|
* @brief 服务初始化
|
|
*/
|
|
hwss_init();
|
|
ds_init(on_state_change);
|
|
|
|
ds_change_to_state(kdevice_state_poweron);
|
|
znordic_loop();
|
|
}
|