56 changed files with 2807 additions and 3573 deletions
-
5.vscode/settings.json
-
468app/app.uvoptx
-
262app/app.uvprojx
-
33app/src/app_basic_service/basic/event.h
-
10app/src/app_basic_service/basic/gstate.h
-
29app/src/app_basic_service/basic/state.h
-
0app/src/app_basic_service/device_version_info_mgr.c
-
0app/src/app_basic_service/device_version_info_mgr.h
-
82app/src/app_basic_service/zapp.c
-
37app/src/app_basic_service/zapp.h
-
37app/src/app_service/adc_mgr.c
-
14app/src/app_service/adc_mgr.h
-
46app/src/app_service/battery_mgr_service.c
-
17app/src/app_service/battery_mgr_service.h
-
242app/src/bakservice/ble_cmd_processer/ble_cmd_process_service.c
-
0app/src/bakservice/ble_cmd_processer/ble_cmd_process_service.h
-
0app/src/bakservice/display_mgr/display_manager.c
-
0app/src/bakservice/display_mgr/display_manager.h
-
0app/src/bakservice/display_mgr/font.h
-
0app/src/bakservice/heart_wave_sample_service/heart_ware_sample_data_mgr.c
-
0app/src/bakservice/heart_wave_sample_service/heart_ware_sample_data_mgr.h
-
0app/src/bakservice/heart_wave_sample_service/heart_wave_sample_data_pre_process.c
-
0app/src/bakservice/heart_wave_sample_service/heart_wave_sample_data_pre_process.h
-
0app/src/bakservice/heart_wave_sample_service/heart_wave_sample_service.c
-
0app/src/bakservice/heart_wave_sample_service/heart_wave_sample_service.h
-
0app/src/bakservice/storage/sample_data_manager.c
-
0app/src/bakservice/storage/sample_data_manager.h
-
0app/src/bakservice/storage/storage_service.h
-
0app/src/bakservice/storage/zeeprom_fs.c
-
0app/src/bakservice/storage/zeeprom_fs.h
-
23app/src/basic_service/app_event_distribute.c
-
15app/src/basic_service/app_event_distribute.h
-
64app/src/basic_service/device_state.c
-
29app/src/basic_service/device_state.h
-
15app/src/main.c
-
495app/src/one_conduction_main.c
-
3app/src/one_conduction_main.h
@ -0,0 +1,33 @@ |
|||
#pragma once |
|||
#include <stdbool.h> |
|||
#include <stdint.h> |
|||
|
|||
#include "aproject_config/config.h" |
|||
typedef enum { |
|||
kplod_connected_event = 0, // 导联连接事件 |
|||
kplod_disconnected_event, // 导联断开事件 |
|||
kplod_connecting_event, // 导联连接中事件 |
|||
|
|||
kbattery_start_charge_event, // 充电事件 |
|||
kbattery_end_charge_event, // 充电结束事件 |
|||
|
|||
kevent_tmr_scheduler_event, // 定时器调度事件 |
|||
|
|||
kevent_capture_256data_event, // 采样数据回调 |
|||
kevent_capture_little_data_block_event, // 单次采样数据回调 |
|||
} app_event_type_t; |
|||
|
|||
typedef int32_t one_frame_t; |
|||
|
|||
typedef struct { |
|||
app_event_type_t eventType; |
|||
union { |
|||
uint32_t plod_connected_accumulation_time; // 导联连接累计时间 |
|||
uint8_t* capture_data_cache; // 实时采样数据,数据长度为256字节 |
|||
struct { |
|||
uint32_t frameIndex; |
|||
uint32_t timestamp; |
|||
one_frame_t data[LITTLE_DATA_BLOCK_FRAME_NUM]; |
|||
} little_data_block; |
|||
} val; |
|||
} app_event_t; |
@ -0,0 +1,10 @@ |
|||
#pragma once |
|||
#include <stdbool.h> |
|||
#include <stdint.h> |
|||
|
|||
#include "aproject_config/config.h" |
|||
|
|||
typedef struct { |
|||
bool sample_capture_state_is_over30s; // 采样是否超过30s |
|||
bool is_preview; // 当前是否正在预览 |
|||
} gstate_t; |
@ -0,0 +1,82 @@ |
|||
#include "zapp.h" |
|||
|
|||
#include "znordic.h" |
|||
|
|||
typedef struct { |
|||
app_event_listener_t cbfunc; |
|||
} AppEventListener; |
|||
|
|||
static device_state_t m_device_state = kdevice_state_standby; // 设备状态 |
|||
static uint32_t m_change_to_cur_state_tp = 0; // 切换到当前状态的时间戳 |
|||
static on_state_change_t m_onstate_change; |
|||
static AppEventListener m_listener[10]; |
|||
static int m_listener_num = 0; |
|||
|
|||
APP_TIMER_DEF(m_state_machine_driver_tmr); // 状态机驱动定时器 |
|||
#define SCHED_MAX_EVENT_DATA_SIZE MAX(sizeof(app_event_t), APP_TIMER_SCHED_EVENT_DATA_SIZE) |
|||
|
|||
/*********************************************************************************************************************** |
|||
* CALL BAK * |
|||
***********************************************************************************************************************/ |
|||
static void state_machine_driver_tmr_cb(void* p_context) { // |
|||
static app_event_t appevent; |
|||
appevent.eventType = kevent_tmr_scheduler_event; |
|||
wd_feed(); |
|||
zapp_ebus_push_event(&appevent); |
|||
} |
|||
|
|||
static void app_event_process_cb(void* p_event_data, uint16_t event_size) { |
|||
for (int i = 0; i < m_listener_num; i++) { |
|||
if (m_listener[i].cbfunc) { |
|||
m_listener[i].cbfunc(p_event_data, event_size); |
|||
} |
|||
} |
|||
} |
|||
|
|||
/*********************************************************************************************************************** |
|||
* EXTERN * |
|||
***********************************************************************************************************************/ |
|||
void zapp_early_init() { APP_SCHED_INIT(SCHED_MAX_EVENT_DATA_SIZE, 20); } |
|||
void zapp_init() { ZERROR_CHECK(app_timer_create(&m_state_machine_driver_tmr, APP_TIMER_MODE_REPEATED, state_machine_driver_tmr_cb)); } |
|||
void zapp_start_schedule() { ZERROR_CHECK(app_timer_start(m_state_machine_driver_tmr, APP_TIMER_TICKS(300), NULL)); } |
|||
|
|||
/*********************************************************************************************************************** |
|||
* state_machine * |
|||
***********************************************************************************************************************/ |
|||
void zapp_state_machine_reg_state_change_listener(on_state_change_t listener) { m_onstate_change = listener; } |
|||
void zapp_state_machine_change_state(device_state_t tostate) { |
|||
ZLOGI("change state from %s to %s", device_state_to_str(m_device_state), device_state_to_str(tostate)); |
|||
device_state_t nowstate = m_device_state; |
|||
|
|||
m_device_state = tostate; |
|||
if (m_onstate_change) { |
|||
m_onstate_change(nowstate, m_device_state); |
|||
} |
|||
m_change_to_cur_state_tp = znordic_getpower_on_ms(); |
|||
} |
|||
device_state_t zapp_state_machine_now_state() { return m_device_state; } |
|||
uint32_t zapp_state_machine_haspassed_ms() { return znordic_haspassed_ms(m_change_to_cur_state_tp); } |
|||
|
|||
/*********************************************************************************************************************** |
|||
* EBUS * |
|||
***********************************************************************************************************************/ |
|||
void zapp_ebus_push_event(app_event_t* event) { app_event_process_cb(event, sizeof(app_event_t)); } |
|||
void zapp_ebus_reg_event_listener(app_event_listener_t listener) { |
|||
ZASSERT(m_listener_num < 10); |
|||
m_listener[m_listener_num++].cbfunc = listener; |
|||
} |
|||
|
|||
/*********************************************************************************************************************** |
|||
* GSTATE * |
|||
***********************************************************************************************************************/ |
|||
static gstate_t gstate; |
|||
gstate_t* zapp_get_gstate() { return &gstate; } |
|||
|
|||
void zapp_gstate_set_is_over30s(bool over30s) { |
|||
gstate_t* p_gstate = zapp_get_gstate(); |
|||
p_gstate->sample_capture_state_is_over30s = over30s; |
|||
} |
|||
void zapp_gstate_set_preview_state(bool is_preview) { |
|||
gstate_t* p_gstate = zapp_get_gstate(); |
|||
p_gstate->is_preview = is_preview; |
|||
} |
@ -0,0 +1,37 @@ |
|||
#pragma once |
|||
#include <stdbool.h> |
|||
#include <stdint.h> |
|||
|
|||
#include "aproject_config/config.h" |
|||
#include "basic/event.h" |
|||
#include "basic/gstate.h" |
|||
#include "basic/state.h" |
|||
|
|||
typedef void (*on_state_change_t)(device_state_t from, device_state_t to); |
|||
typedef void (*app_event_listener_t)(void* p_event_data, uint16_t event_size); |
|||
|
|||
void zapp_early_init(); |
|||
void zapp_init(); |
|||
void zapp_start_schedule(); |
|||
|
|||
/*********************************************************************************************************************** |
|||
* StateMachine * |
|||
***********************************************************************************************************************/ |
|||
void zapp_state_machine_reg_state_change_listener(on_state_change_t listener); |
|||
void zapp_state_machine_change_state(device_state_t tostate); |
|||
device_state_t zapp_state_machine_now_state(); |
|||
device_state_t zapp_state_machine_now_state(); |
|||
uint32_t zapp_state_machine_haspassed_ms(); |
|||
|
|||
/*********************************************************************************************************************** |
|||
* event bus * |
|||
***********************************************************************************************************************/ |
|||
void zapp_ebus_push_event(app_event_t* event); |
|||
void zapp_ebus_reg_event_listener(app_event_listener_t listener); |
|||
|
|||
/*********************************************************************************************************************** |
|||
* GSTATE * |
|||
***********************************************************************************************************************/ |
|||
gstate_t* zapp_get_gstate(); |
|||
void zapp_gstate_set_is_over30s(bool over30s); |
|||
void zapp_gstate_set_preview_state(bool is_preview); |
@ -0,0 +1,37 @@ |
|||
|
|||
#include "adc_mgr.h" |
|||
|
|||
/******************************************************************************* |
|||
* ADC * |
|||
*******************************************************************************/ |
|||
|
|||
static uint8_t m_now_adc_channel = 0xff; |
|||
|
|||
void adc_mgr_set_ch(uint8_t ch) { |
|||
if (m_now_adc_channel != ch) { |
|||
if (m_now_adc_channel != 0xff) nrfx_saadc_channel_uninit(m_now_adc_channel); |
|||
if (ch == BATTERY_ADC_CHANNEL) { |
|||
nrf_saadc_channel_config_t channel_config = NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(BATTERY_ADC_PIN); |
|||
channel_config.acq_time = NRF_SAADC_ACQTIME_40US; |
|||
ZERROR_CHECK(nrfx_saadc_channel_init(BATTERY_ADC_CHANNEL, &channel_config)); |
|||
} |
|||
} |
|||
m_now_adc_channel = ch; |
|||
} |
|||
|
|||
void adc_mgr_init() {} |
|||
|
|||
void adc_mgr_load() { |
|||
nrf_drv_saadc_config_t adccfg = NRFX_SAADC_DEFAULT_CONFIG; |
|||
adccfg.resolution = NRF_SAADC_RESOLUTION_12BIT; // 4096 µÈÓÚÂú²ÉÑùÂÊ |
|||
ZERROR_CHECK(nrf_drv_saadc_init(&adccfg, NULL)); |
|||
} |
|||
void adc_mgr_unload() { |
|||
adc_mgr_set_ch(0xff); |
|||
nrf_drv_saadc_uninit(); |
|||
} |
|||
|
|||
int16_t adc_mgr_get_val(uint8_t ch) { |
|||
adc_mgr_set_ch(ch); |
|||
return znrf_adc_channel_read_val(ch); |
|||
} |
@ -0,0 +1,14 @@ |
|||
#pragma once |
|||
|
|||
#include <stdbool.h> |
|||
#include <stdint.h> |
|||
|
|||
#include "aproject_config/config.h" |
|||
#include "znordic.h" |
|||
|
|||
void adc_mgr_init(); |
|||
|
|||
void adc_mgr_load(); |
|||
void adc_mgr_unload(); |
|||
|
|||
int16_t adc_mgr_get_val(uint8_t ch); |
@ -0,0 +1,46 @@ |
|||
#include "battery_mgr_service.h" |
|||
|
|||
#include "adc_mgr.h" |
|||
#include "app_basic_service/zapp.h" |
|||
|
|||
APP_TIMER_DEF(battery_state_detect_tmr); // |
|||
static bool m_battery_is_chargeing = false; // |
|||
|
|||
static bool battery_get_chargeing_state() { return !nrf_gpio_pin_read(BATTERY_CHARGE_DETECT_PIN); } |
|||
static void module_tmr_cb(void *context) { // |
|||
bool chargeing_state = battery_get_chargeing_state(); |
|||
if (chargeing_state != m_battery_is_chargeing) { |
|||
app_event_t event; |
|||
memset(&event, 0, sizeof(event)); |
|||
if (chargeing_state) { |
|||
ZLOGI("battery is charging"); |
|||
event.eventType = kbattery_start_charge_event; |
|||
} else { |
|||
ZLOGI("battery end charging"); |
|||
event.eventType = kbattery_end_charge_event; |
|||
} |
|||
zapp_ebus_push_event(&event); |
|||
} |
|||
m_battery_is_chargeing = chargeing_state; |
|||
} |
|||
|
|||
/*********************************************************************************************************************** |
|||
* extern * |
|||
***********************************************************************************************************************/ |
|||
void BatteryMgrService_init() { |
|||
adc_mgr_init(); |
|||
/** |
|||
* @brief 500ms启动定时器500ms检查一次当前是否正在充电 |
|||
*/ |
|||
nrf_gpio_cfg_sense_input(BATTERY_CHARGE_DETECT_PIN, NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_NOSENSE); |
|||
app_timer_create(&battery_state_detect_tmr, APP_TIMER_MODE_REPEATED, module_tmr_cb); |
|||
app_timer_start(battery_state_detect_tmr, APP_TIMER_TICKS(500), NULL); |
|||
} |
|||
|
|||
void BatteryMgrService_load() { adc_mgr_load(); } |
|||
void BatteryMgrService_unload() { |
|||
// adc是公共资源,在最上层进行unload |
|||
} |
|||
|
|||
int16_t BatteryMgrService_get_battery_level() { return 30; } |
|||
int16_t BatteryMgrService_get_charging_state() { return !nrf_gpio_pin_read(BATTERY_CHARGE_DETECT_PIN); } |
@ -0,0 +1,17 @@ |
|||
#pragma once |
|||
|
|||
#include <stdbool.h> |
|||
#include <stdint.h> |
|||
|
|||
#include "aproject_config/config.h" |
|||
#include "adc_mgr.h" |
|||
#include "znordic.h" |
|||
|
|||
void BatteryMgrService_init(); |
|||
|
|||
void BatteryMgrService_load(); |
|||
void BatteryMgrService_unload(); |
|||
|
|||
|
|||
int16_t BatteryMgrService_get_battery_level(); |
|||
int16_t BatteryMgrService_get_charging_state(); |
@ -1,23 +0,0 @@ |
|||
#include "basic_service/app_event_distribute.h" |
|||
|
|||
#include "basic_service/app_event.h" |
|||
#include "app_scheduler.h" |
|||
|
|||
static AppEventListener m_listener[10]; |
|||
static int m_listener_num = 0; |
|||
|
|||
static void app_event_process_cb(void* p_event_data, uint16_t event_size) { |
|||
for (int i = 0; i < m_listener_num; i++) { |
|||
if (m_listener[i].cbfunc) { |
|||
m_listener[i].cbfunc(p_event_data, event_size); |
|||
} |
|||
} |
|||
} |
|||
|
|||
void AppEvent_regListener(app_event_listener_t listener) { // |
|||
m_listener[m_listener_num++].cbfunc = listener; |
|||
} |
|||
|
|||
void AppEvent_pushEvent(app_event_t* event) { // |
|||
app_sched_event_put(event, sizeof(app_event_t), app_event_process_cb); |
|||
} |
@ -1,15 +0,0 @@ |
|||
#pragma once |
|||
#include <stdbool.h> |
|||
#include <stdint.h> |
|||
|
|||
#include "basic_service/app_event.h" |
|||
|
|||
|
|||
typedef void (*app_event_listener_t)(void* p_event_data, uint16_t event_size); |
|||
|
|||
typedef struct { |
|||
app_event_listener_t cbfunc; |
|||
} AppEventListener; |
|||
|
|||
void AppEvent_regListener(app_event_listener_t listener); |
|||
void AppEvent_pushEvent(app_event_t* event); |
@ -1,64 +0,0 @@ |
|||
|
|||
#include "device_state.h" |
|||
|
|||
#include "basic_service/app_event_distribute.h" |
|||
#include "znordic.h" |
|||
/*********************************************************************************************************************** |
|||
* 状态机 * |
|||
***********************************************************************************************************************/ |
|||
static device_state_t m_device_state = kdevice_state_standby; // 设备状态 |
|||
static uint32_t m_change_to_cur_state_tp = 0; // 切换到当前状态的时间戳 |
|||
static on_state_change_t m_onstate_change; |
|||
APP_TIMER_DEF(m_state_machine_driver_tmr); // 状态机驱动定时器 |
|||
// static zapp_timer_context m_state_machine_driver_tmr_context; |
|||
|
|||
static void state_machine_driver_tmr_cb(void* p_context) { // |
|||
static app_event_t appevent; |
|||
appevent.eventType = kevent_tmr_scheduler_event; |
|||
wd_feed(); |
|||
AppEvent_pushEvent(&appevent); |
|||
} |
|||
|
|||
void ds_change_to_state(device_state_t tostate) { |
|||
ZLOGI("change state from %s to %s", device_state_to_str(m_device_state), device_state_to_str(tostate)); |
|||
device_state_t nowstate = m_device_state; |
|||
|
|||
m_device_state = tostate; |
|||
if (m_onstate_change) { |
|||
m_onstate_change(nowstate, m_device_state); |
|||
} |
|||
m_change_to_cur_state_tp = znordic_getpower_on_ms(); |
|||
} |
|||
|
|||
uint32_t ds_cur_state_haspassed_ms() { return znordic_haspassed_ms(m_change_to_cur_state_tp); } |
|||
device_state_t ds_now_state() { return m_device_state; } |
|||
|
|||
void ds_init(on_state_change_t onstate_change) { |
|||
m_onstate_change = onstate_change; |
|||
ZERROR_CHECK(app_timer_create(&m_state_machine_driver_tmr, APP_TIMER_MODE_REPEATED, state_machine_driver_tmr_cb)); |
|||
ZERROR_CHECK(app_timer_start(m_state_machine_driver_tmr, APP_TIMER_TICKS(300), NULL)); |
|||
} |
|||
|
|||
/*********************************************************************************************************************** |
|||
* sample_capture_state * |
|||
***********************************************************************************************************************/ |
|||
static sample_capture_state_t m_sample_capture_state; |
|||
|
|||
sample_capture_state_t* sample_capture_state_get() { // |
|||
return &m_sample_capture_state; |
|||
} |
|||
void sample_capture_state_reset() { // |
|||
m_sample_capture_state.is_over30s = false; |
|||
}; |
|||
void sample_capture_state_set_is_over30s(bool over30s) { // |
|||
m_sample_capture_state.is_over30s = over30s; |
|||
} |
|||
|
|||
/*********************************************************************************************************************** |
|||
* global_state * |
|||
***********************************************************************************************************************/ |
|||
|
|||
global_state_t m_global_state; |
|||
global_state_t* global_state_get() { return &m_global_state; } |
|||
void global_state_set_preview_state(bool is_preview) { m_global_state.preivew_state = is_preview; } |
|||
|
@ -1,29 +0,0 @@ |
|||
#pragma once |
|||
#include <stdbool.h> |
|||
#include <stdint.h> |
|||
|
|||
#include "aproject_config/config.h" |
|||
#include "basic_service/app_event.h" |
|||
|
|||
typedef void (*on_state_change_t)(device_state_t from, device_state_t to); |
|||
|
|||
void ds_init(on_state_change_t onstate_change); |
|||
void ds_change_to_state(device_state_t state); |
|||
uint32_t ds_cur_state_haspassed_ms(); |
|||
device_state_t ds_now_state(); |
|||
|
|||
typedef struct { |
|||
bool is_over30s; |
|||
} sample_capture_state_t; |
|||
|
|||
sample_capture_state_t* sample_capture_state_get(); |
|||
|
|||
void sample_capture_state_reset(); |
|||
void sample_capture_state_set_is_over30s(bool over30s); |
|||
|
|||
typedef struct { |
|||
bool preivew_state; |
|||
} global_state_t; |
|||
|
|||
global_state_t* global_state_get(); |
|||
void global_state_set_preview_state(bool is_preview); |
@ -1,400 +1,179 @@ |
|||
#include <math.h> |
|||
#include <stdint.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 "app_basic_service/device_version_info_mgr.h" |
|||
#include "app_basic_service/zapp.h" |
|||
#include "app_service/battery_mgr_service.h" |
|||
#include "aproject_config/config.h" |
|||
#include "ify_hrs_protocol/heart_rate_sensor_protocol.h" |
|||
#include "zdatachannel_service.h" |
|||
#include "znordic.h" |
|||
/*********************************************************************************************************************** |
|||
* GLOBAL * |
|||
***********************************************************************************************************************/ |
|||
|
|||
static uint8_t bletxbuf[255]; |
|||
static uint8_t blereportbuf[255]; |
|||
|
|||
/******************************************************************************* |
|||
* GLOBAL * |
|||
* UTILS * |
|||
*******************************************************************************/ |
|||
static void send_error_receipt(ify_hrs_packet_t* rxpacket, int32_t errorcode) { |
|||
ify_hrs_packet_t* txheader = (ify_hrs_packet_t*)bletxbuf; |
|||
error_receipt_t* receipt = (error_receipt_t*)txheader->data; |
|||
uint16_t sendlen = sizeof(ify_hrs_packet_t) + sizeof(error_receipt_t); |
|||
|
|||
txheader->cmd = rxpacket->cmd; |
|||
txheader->frame_index = rxpacket->frame_index; |
|||
txheader->frame_type = kifyhrs_pt_error_receipt; |
|||
receipt->errorcode = errorcode; |
|||
zdatachannel_data_send2(bletxbuf, sendlen); |
|||
} |
|||
|
|||
static int m_cur_fd; |
|||
static sample_data_filename_t sampledata_file_name; |
|||
static void send_success_receipt(ify_hrs_packet_t* rxpacket, int32_t emptydatasize) { |
|||
ify_hrs_packet_t* txheader = (ify_hrs_packet_t*)bletxbuf; |
|||
uint16_t sendlen = sizeof(ify_hrs_packet_t) + emptydatasize; |
|||
|
|||
#define SCHED_MAX_EVENT_DATA_SIZE MAX(sizeof(app_event_t), APP_TIMER_SCHED_EVENT_DATA_SIZE) |
|||
txheader->cmd = rxpacket->cmd; |
|||
txheader->frame_index = rxpacket->frame_index; |
|||
txheader->frame_type = kifyhrs_pt_cmd_receipt; |
|||
|
|||
/******************************************************************************* |
|||
* 事件处理 * |
|||
*******************************************************************************/ |
|||
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(); |
|||
zdatachannel_data_send2(bletxbuf, sendlen); |
|||
} |
|||
|
|||
/******************************************************************************* |
|||
* 状态切换方法 * |
|||
* 下发消息处理 * |
|||
*******************************************************************************/ |
|||
|
|||
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); |
|||
void one_conduction_process_rx_packet(uint8_t* rx, int len) { |
|||
if (len < sizeof(ify_hrs_packet_t)) { |
|||
ZLOGI("rx len error:%d", len); |
|||
return; |
|||
} |
|||
|
|||
/*********************************************************************************************************************** |
|||
* 切换状态 附带操作 * |
|||
***********************************************************************************************************************/ |
|||
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(); |
|||
} |
|||
} |
|||
ify_hrs_packet_t* rxheader = (ify_hrs_packet_t*)rx; |
|||
ify_hrs_packet_t* txheader = (ify_hrs_packet_t*)bletxbuf; |
|||
ify_hrs_cmd_t cmd = (ify_hrs_cmd_t)rxheader->cmd; |
|||
memset(bletxbuf, 0, sizeof(bletxbuf)); |
|||
|
|||
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; |
|||
txheader->cmd = rxheader->cmd; |
|||
txheader->frame_index = rxheader->frame_index; |
|||
txheader->frame_type = kifyhrs_pt_cmd_receipt; |
|||
|
|||
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); |
|||
} |
|||
} |
|||
ZLOGI("rx cmd:%d index:%d datalen:%d", cmd, rxheader->frame_index, len - sizeof(ify_hrs_packet_t)); |
|||
NRF_LOG_HEXDUMP_INFO(rx, len); |
|||
|
|||
/******************************************************************************* |
|||
* 待机状态 * |
|||
*******************************************************************************/ |
|||
static uint32_t lasttrypoweron_time = 0; |
|||
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); |
|||
|
|||
if (ds_now_state() == kdevice_state_standby) { |
|||
// 充电事件触发 --> 切换到充电页面 |
|||
if (BoardBattery_get_charging_state()) { |
|||
ds_change_to_state(kdevice_state_charging); |
|||
} |
|||
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(bletxbuf, 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); |
|||
|
|||
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(); |
|||
} |
|||
} |
|||
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; |
|||
|
|||
/** |
|||
* @brief |
|||
* TODO: |
|||
* 1. 永远不进入超低功耗状态,直到电池电量低于一定程度 |
|||
* 2. 如果RTC未被设置,则重置设备状态 |
|||
* 3. 在每次从待机状态切换到开机状态,如果RTC未被设置,则清空已经存储的波形数据 |
|||
*/ |
|||
else if (ds_cur_state_haspassed_ms() >= 10000) { |
|||
if (!znordic_rtc_has_setted()) { |
|||
} |
|||
} |
|||
zdatachannel_data_send2(bletxbuf, sendlen); |
|||
} |
|||
|
|||
/******************************************************************************* |
|||
* 充电状态 * |
|||
*******************************************************************************/ |
|||
else if (ds_now_state() == kdevice_state_charging) { |
|||
if (!BoardBattery_get_charging_state()) { |
|||
ds_change_to_state(kdevice_state_standby); |
|||
} |
|||
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(bletxbuf, sendlen); |
|||
} |
|||
|
|||
/******************************************************************************* |
|||
* 开机中 * |
|||
*******************************************************************************/ |
|||
|
|||
else if (ds_now_state() == kdevice_state_poweron) { |
|||
if (ds_cur_state_haspassed_ms() >= 1500) { |
|||
ds_change_to_state(kdevice_state_home); |
|||
} |
|||
else if (cmd == ify_hrs_cmd_reset) { |
|||
NVIC_SystemReset(); |
|||
} |
|||
|
|||
/******************************************************************************* |
|||
* 首页 * |
|||
*******************************************************************************/ |
|||
|
|||
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 (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(bletxbuf, sendlen); |
|||
} |
|||
|
|||
/******************************************************************************* |
|||
* 保持静止页面 * |
|||
*******************************************************************************/ |
|||
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 (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); |
|||
|
|||
} 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); |
|||
} |
|||
} |
|||
} |
|||
znordic_rtc_settime(cmd->year + 2000, cmd->month, cmd->day, cmd->hour, cmd->minute, cmd->second); |
|||
zdatachannel_data_send2(bletxbuf, sendlen); |
|||
} |
|||
|
|||
/******************************************************************************* |
|||
* 采样页面逻辑 * |
|||
*******************************************************************************/ |
|||
|
|||
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) { |
|||
// 单帧实时上报 |
|||
if (global_state_get()->preivew_state) ble_cmder_try_report_one_sample_data(p_event); |
|||
} |
|||
|
|||
/******************************************************************************* |
|||
* 采样足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 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); |
|||
|
|||
} else { |
|||
// 采样不足三十秒 |
|||
receipt->drop_state0 = (0); |
|||
receipt->drop_state1 = 0x00; |
|||
receipt->device_state0.sampling_state = (zapp_state_machine_now_state() == kdevice_state_sampling); |
|||
receipt->device_state0.preview_state = zapp_get_gstate()->is_preview; |
|||
receipt->device_state0.low_battery = (BatteryMgrService_get_battery_level() < APP_LOW_BATTERY_WARNING_LIMIT); |
|||
receipt->device_state0.full_storge = false; |
|||
|
|||
// 停止采样 |
|||
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); |
|||
} |
|||
} |
|||
receipt->device_state1 = 0; |
|||
receipt->powerlevel = BatteryMgrService_get_battery_level(); |
|||
receipt->storage_item_num = 0; |
|||
|
|||
zdatachannel_data_send2(bletxbuf, sendlen); |
|||
} |
|||
|
|||
/******************************************************************************* |
|||
* 采样完成页面 * |
|||
*******************************************************************************/ |
|||
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(); |
|||
} |
|||
} |
|||
|
|||
/****************************************************************************************************************** |
|||
* 测试模式 * |
|||
******************************************************************************************************************/ |
|||
|
|||
else if (ds_now_state() == kdevice_state_test_mode) { |
|||
/** |
|||
* @brief 测试模式下永远不退出,当前模式 |
|||
*/ |
|||
|
|||
if (p_event->eventType == kevent_capture_little_data_block_event) { |
|||
ble_cmder_try_report_one_sample_data(p_event); |
|||
} |
|||
/*********************************************************************************************************************** |
|||
* 测试指令 * |
|||
***********************************************************************************************************************/ |
|||
// void hwss_start_capture(void); |
|||
// void hwss_start_prepare_capture(void); |
|||
// void hwss_stop_capture(void); |
|||
|
|||
// void hwss_subic_write_reg(uint8_t addr, uint8_t val); |
|||
// uint8_t hwss_subic_read_reg(uint8_t addr); |
|||
|
|||
// else if (cmd == ify_hrs_test_cmd_start_capture) { |
|||
// hwss_start_prepare_capture(); |
|||
// hwss_start_capture(); |
|||
// send_success_receipt(rxheader, 0); |
|||
// } else if (cmd == ify_hrs_test_cmd_stop_capture) { |
|||
// hwss_stop_capture(); |
|||
// send_success_receipt(rxheader, 0); |
|||
// } else if (cmd == ify_hrs_test_cmd_read_reg) { |
|||
// uint8_t regadd = rxheader->data[0]; |
|||
// uint8_t regval = hwss_subic_read_reg(regadd); |
|||
// txheader->data[0] = regval; |
|||
// send_success_receipt(rxheader, 1); |
|||
// } else if (cmd == ify_hrs_test_cmd_write_reg) { |
|||
// uint8_t regadd = rxheader->data[0]; |
|||
// uint8_t regval = rxheader->data[1]; |
|||
// hwss_subic_write_reg(regadd, regval); |
|||
// send_success_receipt(rxheader, 0); |
|||
// } |
|||
// |
|||
else { |
|||
send_error_receipt(rxheader, kifyhrs_ecode_cmd_not_support); |
|||
} |
|||
} |
|||
/******************************************************************************* |
|||
* 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_test_mode); |
|||
znordic_loop(); |
|||
} |
|||
void one_conduction_main() { ZLOGI("one_conduction_main"); } |
@ -1,4 +1,5 @@ |
|||
#pragma once |
|||
|
|||
#include <stdint.h> |
|||
|
|||
void one_conduction_main(); |
|||
void one_conduction_process_rx_packet(uint8_t* rx, int len); |
Write
Preview
Loading…
Cancel
Save
Reference in new issue