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.
464 lines
17 KiB
464 lines
17 KiB
#include <math.h>
|
|
#include <stdint.h>
|
|
|
|
#include "aproject_config/config.h"
|
|
#include "ify_hrs_protocol/heart_rate_sensor_protocol.h"
|
|
#include "zdatachannel_service.h"
|
|
//
|
|
#include "app_basic_service/device_version_info_mgr.h"
|
|
#include "app_basic_service/zapp.h"
|
|
#include "app_service/base_hardware/adc_mgr.h"
|
|
#include "app_service/base_hardware/hardware_power_mgr.h"
|
|
#include "app_service/battery_mgr_service.h"
|
|
#include "app_service/beep_ctrl.h"
|
|
#include "app_service/display_ctrl_service/display_mgr.h"
|
|
#include "app_service/ecg_service/ecg_service.h"
|
|
#include "app_service/light_ctrl.h"
|
|
#include "zble_module.h"
|
|
//
|
|
#include "ble_data_processer_utils.h"
|
|
#include "nrf_fstorage.h"
|
|
#include "nrf_fstorage_sd.h"
|
|
|
|
/***********************************************************************************************************************
|
|
* GLOBAL *
|
|
***********************************************************************************************************************/
|
|
|
|
static bool m_poweron_flag;
|
|
static uint16_t m_capture_prepare_progress = 0;
|
|
|
|
/*******************************************************************************
|
|
* UTILS *
|
|
*******************************************************************************/
|
|
|
|
/***********************************************************************************************************************
|
|
* 蓝牙连接事件处理 *
|
|
***********************************************************************************************************************/
|
|
|
|
static void process_on_connect(void* arg) {
|
|
if (zapp_state_machine_now_state() == kstate_standby) {
|
|
zapp_state_machine_change_state(kstate_welcomPage);
|
|
}
|
|
|
|
if (m_poweron_flag) {
|
|
light_ctrl_set_green_light_effect(kLightEffect_slowFlash);
|
|
}
|
|
}
|
|
static void process_on_disconnect(void* arg) {
|
|
if (m_poweron_flag) {
|
|
light_ctrl_set_green_light_effect(kLightEffect_quickFlash);
|
|
}
|
|
}
|
|
|
|
void on_zble_event(zble_event_t* event) {
|
|
if (event->eventType == kzble_event_connected) {
|
|
zapp_exec_in_main_context(NULL, process_on_connect, NULL);
|
|
} else if (event->eventType == kzble_event_disconnected) {
|
|
zapp_exec_in_main_context(NULL, process_on_disconnect, NULL);
|
|
}
|
|
}
|
|
/***********************************************************************************************************************
|
|
* 蓝牙消息处理 *
|
|
***********************************************************************************************************************/
|
|
void one_conduction_process_rx_packet(uint8_t* rx, int len) {
|
|
ify_hrs_packet_t* rxheader = (ify_hrs_packet_t*)rx;
|
|
ify_hrs_packet_t* txheader = bletxbuf_get();
|
|
ify_hrs_cmd_t cmd = (ify_hrs_cmd_t)rxheader->cmd;
|
|
|
|
if (len < sizeof(ify_hrs_packet_t)) {
|
|
ZLOGI("rx len error:%d", len);
|
|
return;
|
|
}
|
|
|
|
bletxbuf_clear();
|
|
|
|
txheader->cmd = rxheader->cmd;
|
|
txheader->frame_index = rxheader->frame_index;
|
|
txheader->frame_type = kifyhrs_pt_cmd_receipt;
|
|
|
|
ZLOGI("rx cmd:%d index:%d datalen:%d", cmd, rxheader->frame_index, len - sizeof(ify_hrs_packet_t));
|
|
NRF_LOG_HEXDUMP_INFO(rx, len);
|
|
|
|
if (cmd == ify_hrs_cmd_read_device_version) {
|
|
device_version_info_receipt_t* receipt = (device_version_info_receipt_t*)txheader->data;
|
|
uint16_t sendlen = sizeof(ify_hrs_packet_t) + sizeof(device_version_info_receipt_t);
|
|
|
|
receipt->blestack_version = device_info_read_blestack_version();
|
|
receipt->bootloader_version = device_info_read_bootloader_version();
|
|
receipt->firmware_version = device_info_read_firmware_version();
|
|
receipt->hardware_version = device_info_read_hardware_version();
|
|
zdatachannel_data_send2((uint8_t*)txheader, sendlen);
|
|
}
|
|
|
|
else if (cmd == ify_hrs_cmd_read_sensor_info) {
|
|
sensor_info_receipt_t* receipt = (sensor_info_receipt_t*)txheader->data;
|
|
uint16_t sendlen = sizeof(ify_hrs_packet_t) + sizeof(sensor_info_receipt_t);
|
|
|
|
receipt->sensor_num = 1;
|
|
receipt->sensor_precision = SAMPLE_PRECISION;
|
|
receipt->sensor_sample_rate = SAMPLE_RATE / 10;
|
|
receipt->sensor0_pos = kifyhrs_sensor_pos_none;
|
|
receipt->sensor1_pos = kifyhrs_sensor_pos_none;
|
|
receipt->sensor2_pos = kifyhrs_sensor_pos_none;
|
|
|
|
zdatachannel_data_send2((uint8_t*)txheader, sendlen);
|
|
}
|
|
|
|
else if (cmd == ify_hrs_cmd_read_sn) {
|
|
read_sn_receipt_t* receipt = (read_sn_receipt_t*)txheader->data;
|
|
uint16_t sendlen = sizeof(ify_hrs_packet_t) + sizeof(read_sn_receipt_t);
|
|
device_info_read_sn((sn_t*)&receipt->sn);
|
|
zdatachannel_data_send2((uint8_t*)txheader, sendlen);
|
|
}
|
|
|
|
else if (cmd == ify_hrs_cmd_reset) {
|
|
NVIC_SystemReset();
|
|
}
|
|
|
|
else if (cmd == ify_hrs_cmd_read_time) {
|
|
read_time_receipt_t* receipt = (read_time_receipt_t*)txheader->data;
|
|
uint16_t sendlen = sizeof(ify_hrs_packet_t) + sizeof(read_time_receipt_t);
|
|
static ztm_t ztm;
|
|
znordic_rtc_gettime(&ztm);
|
|
|
|
receipt->year = (ztm.tm_year + 1900 - 2000);
|
|
receipt->month = ztm.tm_mon + 1;
|
|
receipt->day = ztm.tm_mday;
|
|
receipt->hour = ztm.tm_hour;
|
|
receipt->minute = ztm.tm_min;
|
|
receipt->second = ztm.tm_sec;
|
|
zdatachannel_data_send2((uint8_t*)txheader, sendlen);
|
|
}
|
|
|
|
else if (cmd == ify_hrs_cmd_sync_time) {
|
|
sync_time_cmd_t* cmd = (sync_time_cmd_t*)rxheader->data;
|
|
uint16_t sendlen = sizeof(ify_hrs_packet_t);
|
|
device_info_write_active_flag(true);
|
|
znordic_rtc_settime(cmd->year + 2000, cmd->month, cmd->day, cmd->hour, cmd->minute, cmd->second);
|
|
zdatachannel_data_send2((uint8_t*)txheader, sendlen);
|
|
}
|
|
|
|
/***********************************************************************************************************************
|
|
* 基础指令 *
|
|
***********************************************************************************************************************/
|
|
|
|
else if (cmd == ify_hrs_cmd_read_device_state) {
|
|
device_state_receipt_t* receipt = (device_state_receipt_t*)txheader->data;
|
|
uint16_t sendlen = sizeof(ify_hrs_packet_t) + sizeof(device_state_receipt_t);
|
|
|
|
receipt->drop_state0 = (0);
|
|
receipt->drop_state1 = 0x00;
|
|
receipt->device_state0.sampling_state = (zapp_state_machine_now_state() == kstate_capture);
|
|
receipt->device_state0.report_state = 0;
|
|
receipt->device_state0.low_battery = (0 < APP_LOW_BATTERY_WARNING_LIMIT);
|
|
receipt->device_state0.full_storge = false;
|
|
|
|
receipt->device_state1 = 0;
|
|
receipt->powerlevel = battery_mgr_service_get_battery_level();
|
|
receipt->storage_item_num = 0;
|
|
|
|
zdatachannel_data_send2((uint8_t*)txheader, sendlen);
|
|
}
|
|
|
|
else if (cmd == ify_hrs_cmd_start_realtime_preview) {
|
|
if (zapp_state_machine_now_state() != kstate_mainPage && zapp_state_machine_now_state() != kstate_welcomPage) {
|
|
send_error_receipt(rxheader, kifyhrs_ecode_invalid_state);
|
|
return;
|
|
}
|
|
static app_event_t event;
|
|
event.eventType = kappevent_start_capture;
|
|
|
|
zapp_ebus_push_event(&event);
|
|
send_success_receipt(rxheader, 0);
|
|
}
|
|
|
|
else if (cmd == ify_hrs_cmd_stop_realtime_preview) {
|
|
if (zapp_state_machine_now_state() != kstate_capture) {
|
|
send_error_receipt(rxheader, kifyhrs_ecode_invalid_state);
|
|
return;
|
|
}
|
|
|
|
static app_event_t event;
|
|
event.eventType = kappevent_stop_capture;
|
|
|
|
zapp_ebus_push_event(&event);
|
|
send_success_receipt(rxheader, 0);
|
|
}
|
|
|
|
/***********************************************************************************************************************
|
|
* 测试 *
|
|
***********************************************************************************************************************/
|
|
else if (cmd == ify_hrs_cmd_set_ecg_in_test_mode) {
|
|
int32_t testmode = *(int32_t*)rxheader->data;
|
|
ecg_service_set_in_test_mode(testmode);
|
|
send_success_receipt(rxheader, 0);
|
|
}
|
|
|
|
else if (cmd == ify_hrs_cmd_set_ecg_report_data_in_raw_mode) {
|
|
int32_t testmode = *(int32_t*)rxheader->data;
|
|
ecg_service_set_report_data_in_raw_mode(testmode);
|
|
send_success_receipt(rxheader, 0);
|
|
}
|
|
|
|
else if (cmd == ify_hrs_cmd_ecg_subic_read_reg) {
|
|
uint8_t addr = *(uint8_t*)rxheader->data;
|
|
uint8_t val = ecg_service_subic_read_reg(addr);
|
|
txheader->data[0] = val;
|
|
zdatachannel_data_send2((uint8_t*)txheader, sizeof(ify_hrs_packet_t) + 1);
|
|
}
|
|
|
|
else if (cmd == ify_hrs_cmd_ecg_subic_write_reg) {
|
|
uint8_t addr = *(uint8_t*)rxheader->data;
|
|
uint8_t val = *(uint8_t*)(rxheader->data + 1);
|
|
ecg_service_subic_write_reg(addr, val);
|
|
send_success_receipt(rxheader, 0);
|
|
}
|
|
|
|
else {
|
|
send_error_receipt(rxheader, kifyhrs_ecode_cmd_not_support);
|
|
}
|
|
}
|
|
|
|
/***********************************************************************************************************************
|
|
* 事件处理 *
|
|
***********************************************************************************************************************/
|
|
|
|
// extern int32_t maxval;
|
|
// extern int32_t minval;
|
|
// extern int32_t nowval100;
|
|
void on_zapp_ebus_event(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 (p_event->eventType == kappevent_tmr_1s_scheduler_event) {
|
|
// ZLOGI("tmr event. %d %d %d", nowval100, minval, maxval);
|
|
// ZLOGI("tmr event.");
|
|
}
|
|
|
|
app_event_type_t event = p_event->eventType;
|
|
|
|
if (zapp_state_machine_now_state() == kstate_standby) {
|
|
/**
|
|
* @brief
|
|
* 1. 充电切换到充电状态
|
|
*/
|
|
|
|
if (event == kappevent_state_machine_state_enter) {
|
|
/**
|
|
* @brief 关机
|
|
*/
|
|
ZLOGI("power off");
|
|
dsp_mgr_change_page(kpage_poweroff);
|
|
|
|
battery_mgr_service_change_state_to_standy();
|
|
|
|
beep_unload();
|
|
light_ctrl_unload();
|
|
dsp_mgr_unload();
|
|
ecg_service_unload();
|
|
|
|
// battery_mgr_service_change_state_to_standy();
|
|
hardware_power_mgr_main_power_supply_set(false);
|
|
m_poweron_flag = false;
|
|
|
|
} else if (event == kappevent_state_machine_state_exit) {
|
|
/**
|
|
* @brief 开机
|
|
*/
|
|
ZLOGI("power on");
|
|
hardware_power_mgr_main_power_supply_set(true);
|
|
battery_mgr_service_change_state_to_poweron();
|
|
beep_load();
|
|
light_ctrl_load();
|
|
dsp_mgr_load();
|
|
ecg_service_load();
|
|
m_poweron_flag = true;
|
|
|
|
if (zble_module_is_connected()) {
|
|
light_ctrl_set_green_light_effect(kLightEffect_slowFlash);
|
|
}
|
|
|
|
} else {
|
|
if (p_event->eventType == kappevent_battery_start_charge) {
|
|
zapp_state_machine_change_state(kstate_charging);
|
|
} else if (!device_info_get_active_flag() && zapp_state_machine_haspassed_ms() >= 60000) {
|
|
ZLOGI_BLOCK("rtc not setted, power system off");
|
|
ZERROR_CHECK(sd_power_system_off());
|
|
}
|
|
}
|
|
|
|
} else if (zapp_state_machine_now_state() == kstate_welcomPage) {
|
|
/**
|
|
* @brief
|
|
* 延迟1.5s切换到主页面
|
|
*/
|
|
|
|
if (event == kappevent_state_machine_state_enter) {
|
|
dsp_mgr_change_page(kpage_welcome);
|
|
} else if (event == kappevent_state_machine_state_exit) {
|
|
} else {
|
|
if (p_event->eventType == kappevent_start_capture) {
|
|
zapp_state_machine_change_state(kstate_prepare_capture);
|
|
} else if (zapp_state_machine_haspassed_ms() >= 2000) {
|
|
zapp_state_machine_change_state(kstate_mainPage);
|
|
beep_set_effect(POWER_ON_EFFECT);
|
|
}
|
|
}
|
|
|
|
} else if (zapp_state_machine_now_state() == kstate_mainPage) {
|
|
/**
|
|
* @brief
|
|
* 1. 断开连接->切换到关机状态
|
|
* 2. 开始采集指令->切换到采集状态
|
|
* 3. 充电中事件->切换到充电状态
|
|
*
|
|
*/
|
|
if (event == kappevent_state_machine_state_enter) {
|
|
dsp_mgr_change_page(kpage_main);
|
|
} else if (event == kappevent_state_machine_state_exit) {
|
|
} else {
|
|
if (zble_module_has_disconnected_ms() >= 3000) {
|
|
zapp_state_machine_change_state(kstate_standby);
|
|
} else if (event == kappevent_start_capture) {
|
|
zapp_state_machine_change_state(kstate_prepare_capture);
|
|
} else if (event == kappevent_battery_start_charge) {
|
|
zapp_state_machine_change_state(kstate_charging);
|
|
}
|
|
}
|
|
|
|
} else if (zapp_state_machine_now_state() == kstate_prepare_capture) {
|
|
/**
|
|
* @brief
|
|
* 1. 停止采集指令->切换到MainPage
|
|
* 2. 断开连接 ->切换到关机状态
|
|
* 3. 检查leadoff状态
|
|
*/
|
|
if (event == kappevent_state_machine_state_enter) {
|
|
m_capture_prepare_progress = 0;
|
|
dsp_mgr_change_page(kpage_sample_prepare);
|
|
ecg_service_start_capture();
|
|
beep_set_effect(START_SAMPLE_EFFECT);
|
|
} else if (event == kappevent_state_machine_state_exit) {
|
|
} else {
|
|
if (zble_module_has_disconnected_ms() >= 5000) {
|
|
ecg_service_stop_capture();
|
|
zapp_state_machine_change_state(kstate_standby);
|
|
} else if (event == kappevent_stop_capture) {
|
|
ecg_service_stop_capture();
|
|
zapp_state_machine_change_state(kstate_mainPage);
|
|
} else {
|
|
if (event == kappevent_tmr_1s_scheduler_event) {
|
|
if (!ecg_leadoff_detect() && zapp_state_machine_haspassed_ms() > 1500) {
|
|
m_capture_prepare_progress++;
|
|
if (m_capture_prepare_progress < 4) {
|
|
dsp_mgr_page_sample_prepare_set_progress(m_capture_prepare_progress);
|
|
} else {
|
|
/**
|
|
* @brief 开始采集
|
|
*/
|
|
zapp_state_machine_change_state(kstate_capture);
|
|
beep_set_effect(POWER_ON_EFFECT);
|
|
}
|
|
} else {
|
|
m_capture_prepare_progress = 0;
|
|
dsp_mgr_page_sample_prepare_set_progress(m_capture_prepare_progress);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
} else if (zapp_state_machine_now_state() == kstate_capture) {
|
|
/**
|
|
* @brief
|
|
* 1. 停止采集指令->切换到MainPage
|
|
* 2. 断开连接 ->切换到关机状态
|
|
*/
|
|
if (event == kappevent_state_machine_state_enter) {
|
|
ecg_service_start_capture();
|
|
dsp_mgr_change_page(kpage_sampling);
|
|
} else if (event == kappevent_state_machine_state_exit) {
|
|
ecg_service_stop_capture();
|
|
beep_set_effect(STOP_SAMPLE_EFFECT);
|
|
} else {
|
|
if (zble_module_has_disconnected_ms() >= 1000) {
|
|
zapp_state_machine_change_state(kstate_standby);
|
|
} else if (event == kappevent_stop_capture) {
|
|
zapp_state_machine_change_state(kstate_mainPage);
|
|
} else if (event == kecg_data_report_event) {
|
|
report_ecg_data(p_event);
|
|
}
|
|
}
|
|
|
|
} else if (zapp_state_machine_now_state() == kstate_charging) {
|
|
/**
|
|
* @brief
|
|
* 1. 充电结束事件->切换到待机
|
|
*/
|
|
if (event == kappevent_state_machine_state_enter) {
|
|
dsp_mgr_change_page(kpage_charging_page);
|
|
} else if (event == kappevent_state_machine_state_exit) {
|
|
} else {
|
|
if (event == kappevent_battery_end_charge) {
|
|
if (!zble_module_is_connected()) {
|
|
zapp_state_machine_change_state(kstate_standby);
|
|
} else {
|
|
zapp_state_machine_change_state(kstate_mainPage);
|
|
}
|
|
}
|
|
}
|
|
|
|
} else if (zapp_state_machine_now_state() == kstate_test) {
|
|
// extern int32_t maxval;
|
|
// extern int32_t minval;
|
|
extern uint8_t m_leadoff_raw_state;
|
|
|
|
ZLOGI("tmr event. %d %x", ecg_leadoff_detect(), m_leadoff_raw_state);
|
|
}
|
|
}
|
|
|
|
/***********************************************************************************************************************
|
|
* 状态切换 *
|
|
***********************************************************************************************************************/
|
|
void on_state_change(state_machine_event_t event, device_state_t state) {
|
|
/**
|
|
* @brief 状态退出
|
|
*/
|
|
|
|
static app_event_t appevent;
|
|
if (event == kstate_event_enter) {
|
|
appevent.eventType = kappevent_state_machine_state_enter;
|
|
on_zapp_ebus_event(&appevent, sizeof(app_event_t));
|
|
} else {
|
|
appevent.eventType = kappevent_state_machine_state_exit;
|
|
on_zapp_ebus_event(&appevent, sizeof(app_event_t));
|
|
}
|
|
}
|
|
|
|
void one_conduction_main() {
|
|
device_info_init();
|
|
|
|
sn_t sn;
|
|
device_info_read_sn(&sn);
|
|
ZLOGI("one_conduction_main %s active:%d", sn.sn, device_info_get_active_flag());
|
|
ZLOG_FLUSH();
|
|
|
|
zapp_ebus_reg_event_listener(on_zapp_ebus_event);
|
|
zapp_state_machine_reg_state_change_listener(on_state_change);
|
|
zble_module_reglistener(on_zble_event);
|
|
|
|
adc_mgr_init();
|
|
hardware_power_mgr_init();
|
|
|
|
battery_mgr_service_init();
|
|
battery_mgr_service_load();
|
|
|
|
light_ctrl_init();
|
|
beep_init();
|
|
dsp_mgr_init();
|
|
ecg_service_init();
|
|
|
|
// zapp_state_machine_change_state(kstate_prepare_capture);
|
|
|
|
zble_module_start_adv();
|
|
zapp_start_schedule();
|
|
}
|