From 348c9065194fba0827fb895bb8b3732a69f69025 Mon Sep 17 00:00:00 2001 From: zhaohe Date: Sun, 18 Feb 2024 15:13:01 +0800 Subject: [PATCH] V25 --- .vscode/settings.json | 3 +- README.md | 3 + app/config/sdk_config.h | 2 +- app/src/app_ble_service.c | 103 ++++++++----------------- app/src/basic/version.h | 2 +- app/src/board/board.h | 1 + app/src/device_ctrl_service.c | 138 ++++++++++++++++++++++++++++------ app/src/device_ctrl_service.h | 11 ++- dynamic_electrocardiograph_ble_server | 2 +- ify_hrs_protocol | 2 +- scripter/build_app.bat | 3 +- 11 files changed, 166 insertions(+), 104 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 6454d51..08583fc 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -167,7 +167,8 @@ "streambuf": "cpp", "thread": "cpp", "cinttypes": "cpp", - "device_exception_manager.h": "c" + "device_exception_manager.h": "c", + "xiosbase": "c" }, "files.encoding": "gbk" } \ No newline at end of file diff --git a/README.md b/README.md index 6b59f7c..f90f392 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,9 @@ # three_lead_ecg_v2 ``` +V25: + 1.针对协议V1.8进行修改 + V24: 1.修复V23版本的BUG diff --git a/app/config/sdk_config.h b/app/config/sdk_config.h index 20afb59..d86e41c 100644 --- a/app/config/sdk_config.h +++ b/app/config/sdk_config.h @@ -7812,7 +7812,7 @@ // NRF_LOG_ENABLED - nrf_log - Logger //========================================================== #ifndef NRF_LOG_ENABLED -#define NRF_LOG_ENABLED 0 +#define NRF_LOG_ENABLED 1 #endif // Log message pool - Configuration of log message pool diff --git a/app/src/app_ble_service.c b/app/src/app_ble_service.c index 0498a5a..f464692 100644 --- a/app/src/app_ble_service.c +++ b/app/src/app_ble_service.c @@ -16,8 +16,7 @@ #include "znordic.h" static uint8_t rxbufcache[256]; -static bool is_rxbufcache_used = false; // 接收到的消息是否正在被处理中 -static bool m_realtime_report_state = false; // 实时上报状态 +static bool is_rxbufcache_used = false; // 接收到的消息是否正在被处理中 static uint8_t m_txbuf[256]; static uint8_t m_reportbuf[256]; @@ -54,14 +53,6 @@ static void zdatachannel_data_handler(zdatachannel_evt_t* p_evt) { /******************************************************************************* * UTILS * *******************************************************************************/ -int ble_start_realtime_report() { - m_realtime_report_state = true; - return 0; -} -int ble_stop_realtime_report() { - m_realtime_report_state = false; - return 0; -} static void send_error_receipt(ify_hrs_packet_t* rxpacket, int32_t errorcode) { ify_hrs_packet_t* txheader = (ify_hrs_packet_t*)m_txbuf; @@ -111,7 +102,7 @@ static void prvf_try_report_sample_end_event() { } void prvf_report_sample_data(uint32_t frameIndex, one_frame_data_t* data, int32_t ndata) { - if (!m_realtime_report_state) { + if (!DeviceCtrl_IsRealtimeReport()) { return; } @@ -335,13 +326,16 @@ static void prvf_process_ble_rx_data(void* p_event_data, uint16_t len) { receipt->drop_state1 = 0x00; receipt->device_state0.sampling_state = (DeviceCtrl_now_state() == kdevice_state_sampling); - receipt->device_state0.report_state = m_realtime_report_state; + receipt->device_state0.report_state = DeviceCtrl_IsRealtimeReport(); receipt->device_state0.low_battery = (BoardBattery_get_battery_level() < APP_LOW_BATTERY_WARNING_LIMIT); receipt->device_state0.full_storge = (SampleDataMgr_storageIsFull()); + // receipt->device_state0.is_storaging = DeviceCtrl_isStoraging(); receipt->device_state1 = 0; receipt->powerlevel = BoardBattery_get_battery_level(); receipt->storage_item_num = SampleDataMgr_getFileNum(); + // receipt->storage_setting_time_s = DeviceCtrl_getSettingStorageTime(); + // receipt->storage_has_storaged_time_s = DeviceCtrl_getHasStoragedTime(); zdatachannel_data_send2(m_txbuf, sendlen); } @@ -368,82 +362,50 @@ static void prvf_process_ble_rx_data(void* p_event_data, uint16_t len) { znordic_rtc_settime(cmd->year + 2000, cmd->month, cmd->day, cmd->hour, cmd->minute, cmd->second); zdatachannel_data_send2(m_txbuf, sendlen); } +#if 1 - else if (cmd == ify_hrs_cmd_start_capture) { - // hwss_start_capture(); - - if (DeviceExceptionMgr_has_error()) { - send_error_receipt(rxheader, kifyhrs_ecode_device_exception); - return; - } - - if (RecordUpload_is_uploading()) { - ZLOGI("uploading,can not start capture"); - send_error_receipt(rxheader, kifyhrs_ecode_device_busy); - return; + else if (cmd == ify_hrs_cmd_start_realtime_preview) { + uint8_t ecode = DeviceCtrl_StartPreview(); + if (ecode == 0) { + send_success_receipt(rxheader, 0); + } else { + send_error_receipt(rxheader, ecode); } + } - if (!hwss_line_detect_get_state()) { - send_error_receipt(rxheader, kifyhrs_ecode_electrode_is_not_inserted); - return; + else if (cmd == ify_hrs_cmd_stop_realtime_preview) { + uint8_t ecode = DeviceCtrl_StopPreview(); + if (ecode == 0) { + send_success_receipt(rxheader, 0); + } else { + send_error_receipt(rxheader, ecode); } - - DeviceCtrl_startSample(0); - send_success_receipt(rxheader, 0); } - - else if (cmd == ify_hrs_cmd_start_capture_time_v2) { - // kifyhrs_ecode_parameter_error - // hwss_start_capture(); - + // + else if (cmd == ify_hrs_cmd_start_storage) { if (paramLen < 4) { send_error_receipt(rxheader, kifyhrs_ecode_parameter_error); return; } + uint32_t time = *(uint32_t*)rxheader->data; - int32_t capture_time_s = *(int32_t*)(&rxheader->data[0]); - - if (RecordUpload_is_uploading()) { - ZLOGI("uploading,can not start capture"); - send_error_receipt(rxheader, kifyhrs_ecode_device_busy); - return; - } - - if (!hwss_line_detect_get_state()) { - send_error_receipt(rxheader, kifyhrs_ecode_electrode_is_not_inserted); - return; - } - - DeviceCtrl_startSample(capture_time_s); - send_success_receipt(rxheader, 0); - } - - // - // ify_hrs_cmd_start_upload_record_v2 - - else if (cmd == ify_hrs_cmd_stop_capture) { - // hwss_stop_capture(); - DeviceCtrl_stopSample(); - send_success_receipt(rxheader, 0); - } - - else if (cmd == ify_hrs_cmd_start_realtime_report) { - int ecode = ble_start_realtime_report(); + uint8_t ecode = DeviceCtrl_startStorage(time); if (ecode == 0) { - send_success_receipt(rxheader, 8); // 凑8个字节,使这个回执的字节长度同上报包长度一致,方便调试 + send_success_receipt(rxheader, 0); } else { send_error_receipt(rxheader, ecode); } } - - else if (cmd == ify_hrs_cmd_stop_realtime_report) { - int ecode = ble_stop_realtime_report(); + // + else if (cmd == ify_hrs_cmd_stop_storage) { + uint8_t ecode = DeviceCtrl_stopStorage(); if (ecode == 0) { send_success_receipt(rxheader, 0); } else { send_error_receipt(rxheader, ecode); } } +#endif else if (cmd == ify_hrs_cmd_read_records_info) { // 指令 10-读取采样记录头部信息 @@ -605,11 +567,8 @@ static void app_event_listener(void* p_event_data, uint16_t event_size) { // prvf_try_report_sample_end_event(); } else if (event->eventType == kevent_capture_little_data_block_event) { // 上报采样数据 - if (m_realtime_report_state) { - // 上报采样数据 - prvf_report_sample_data(event->val.little_data_block.frameIndex, // - event->val.little_data_block.data, LITTLE_DATA_BLOCK_FRAME_NUM); - } + prvf_report_sample_data(event->val.little_data_block.frameIndex, // + event->val.little_data_block.data, LITTLE_DATA_BLOCK_FRAME_NUM); } } diff --git a/app/src/basic/version.h b/app/src/basic/version.h index bb39dd1..8236e4c 100644 --- a/app/src/basic/version.h +++ b/app/src/basic/version.h @@ -2,7 +2,7 @@ #define CATEGORY "M1002" // 三导联 #define MANUFACTURER_NAME "iflytop" -#define FIRMWARE_VERSION (24) +#define FIRMWARE_VERSION (25) #define BLESTACK_VERSION 1 #define BOOTLOADER_VERSION 1 #define HARDWARE_VERSION (1) diff --git a/app/src/board/board.h b/app/src/board/board.h index 067b3bf..d62f991 100644 --- a/app/src/board/board.h +++ b/app/src/board/board.h @@ -60,6 +60,7 @@ #define HEART_WAVE_SAMPLE_SERVICE_CACHE_SIZE (180) #define FILE_MAX_COUNT 1 #define SDCARD_MAX_FILE_SIZE (uint32_t)(3.5 * 1024 * 1024 * 1024) +#define APP_MAX_STORAGE_TIME_S (uint32_t)(72 * 60 * 60) // #define SAMPLE_RATE 400 #define LITTLE_DATA_BLOCK_FRAME_NUM 4 // 每两帧回调一次,对应100HZ diff --git a/app/src/device_ctrl_service.c b/app/src/device_ctrl_service.c index 9b8050e..45f3b2f 100644 --- a/app/src/device_ctrl_service.c +++ b/app/src/device_ctrl_service.c @@ -1,22 +1,31 @@ #include "device_ctrl_service.h" +#include "../../ify_hrs_protocol/heart_rate_sensor_protocol.h" #include "app_event_distribute.h" #include "board/board_battery_state.h" #include "board/board_beep_ctrl.h" #include "board/board_button.h" #include "board/board_light_ctrl.h" #include "board/board_sdcard_driver.h" +#include "board/device_exception_manager.h" #include "heart_wave_sample_service.h" #include "sample_data_manager_service.h" #include "zble_module.h" #include "zdatachannel_service.h" #include "znordic.h" // -APP_TIMER_DEF(m_state_machine_driver_tmr); // 状态机驱动定时器 -static device_state_t m_device_state = kdevice_state_standby; // 设备状态 -static uint32_t m_change_to_cur_state_tp = 0; // 切换到当前状态的时间戳 -static int m_sample_data_fd = -1; // 采集数据文件描述符 -static int m_sample_duration_ms; +APP_TIMER_DEF(m_state_machine_driver_tmr); // 状态机驱动定时器 +static device_state_t m_device_state = kdevice_state_standby; // 设备状态 +static uint32_t m_change_to_cur_state_tp = 0; // 切换到当前状态的时间戳 +static int m_sample_data_fd = -1; // 采集数据文件描述符 +static bool m_has_triggered_connected = false; // 被连接过 + +static uint32_t m_settingStorageTimeS; +static uint32_t m_startStorageTimeTicket; +static uint32_t m_hasStoragedTimeS; +static bool m_isStoraging; + +static bool m_IsRealtimeReport; /******************************************************************************* * 函数列表 * @@ -170,6 +179,7 @@ static void app_event_listener(void* p_event_data, uint16_t event_size) { // * 状态无关事件处理 * *******************************************************************************/ if (event->eventType == kevent_ble_connect_event) { + m_has_triggered_connected = true; BoardLight_setGreenLightEffect(kLightEffect_slowFlash); } else if (event->eventType == kevent_ble_disconnect_event) { BoardLight_setGreenLightEffect(kLightEffect_quickFlash); @@ -197,12 +207,11 @@ static void app_event_listener(void* p_event_data, uint16_t event_size) { // } else if (BoardBattery_get_battery_level() < APP_LOW_BATTERY_LIMIT) { ZLOGI("auto sleep because low battery"); prvf_change_to_standby_state(); + } else if (m_has_triggered_connected && !zble_module_is_connected()) { + prvf_change_to_standby_state(); } } // 如果设备没有采集时,蓝牙断开,设备直接进入休眠状态 - if (event->eventType == kevent_ble_disconnect_event) { - prvf_change_to_standby_state(); - } if (event->eventType == kevent_start_sample_cmd_event) { ZLOGI("start sample"); @@ -229,7 +238,11 @@ static void app_event_listener(void* p_event_data, uint16_t event_size) { // else if (m_device_state == kdevice_state_sampling) { // 采集的字节长度超过最大字节长度,停止采集 - if (event->eventType == kevent_capture_data_block_event) { + if (m_isStoraging) { + m_hasStoragedTimeS = znordic_getpower_on_s() - m_startStorageTimeTicket; + } + + if (m_isStoraging && event->eventType == kevent_capture_data_block_event) { ZLOGI("capture data block %d", event->val.block_sensor_data.len); SampleDataMgr_write(m_sample_data_fd, (uint8_t*)event->val.block_sensor_data.data, event->val.block_sensor_data.len); } @@ -252,8 +265,14 @@ static void app_event_listener(void* p_event_data, uint16_t event_size) { // } else if (event->eventType == kevent_stop_sample_cmd_event) { ZLOGI("stop sample because stop sample event"); stopcapture = true; - } else if (m_sample_duration_ms != 0 && DeviceCtrl_cur_state_haspassed_ms() > m_sample_duration_ms) { - ZLOGI("stop sample because sample timeout"); + } else if (m_isStoraging && m_hasStoragedTimeS >= m_settingStorageTimeS) { + ZLOGI("stop sample because storage time is enough"); + stopcapture = true; + } else if (!m_isStoraging && !zble_module_is_connected()) { + ZLOGI("stop sample because ble disconnected"); + stopcapture = true; + } else if (!m_isStoraging && zble_module_is_connected() && zdatachannel_last_rx_data_haspassed_s() >= BLE_UNCONNECTED_OVERTIME_S) { + ZLOGI("stop sample because ble unconnected"); stopcapture = true; } else if (BoardBattery_get_battery_level() < APP_LOW_BATTERY_LIMIT) { ZLOGI("stop sample because low battery"); @@ -282,22 +301,93 @@ static void app_event_listener(void* p_event_data, uint16_t event_size) { // } } -void DeviceCtrl_startSample(int duration_s) { - ZLOGI("start sample %d", duration_s); - m_sample_duration_ms = duration_s * 1000; - if (duration_s == 0) { - m_sample_duration_ms = 2 * 60 * 1000; // 两分钟 +uint8_t DeviceCtrl_startStorage(uint32_t storageTimeS) { + if (DeviceExceptionMgr_has_error()) { + return kifyhrs_ecode_device_exception; } - static app_event_t event; - event.eventType = kevent_start_sample_cmd_event; - AppEvent_pushEvent(&event); + + if (DeviceCtrl_now_state() != kdevice_state_sampling) { + return kifyhrs_ecode_invalid_state; + } + + if (storageTimeS == 0) { + return kifyhrs_ecode_illegal_parameter; + } + + if (storageTimeS >= APP_MAX_STORAGE_TIME_S) { + return kifyhrs_ecode_illegal_parameter; + } + + m_settingStorageTimeS = storageTimeS; + m_hasStoragedTimeS = 0; + m_startStorageTimeTicket = znordic_getpower_on_s(); + m_isStoraging = true; + + ZLOGI("start storage %d", storageTimeS); + + return 0; } -void DeviceCtrl_stopSample() { - ZLOGI("stop sample"); - static app_event_t event; - event.eventType = kevent_stop_sample_cmd_event; - AppEvent_pushEvent(&event); +uint8_t DeviceCtrl_stopStorage() { + m_isStoraging = false; + m_hasStoragedTimeS = 0; + m_settingStorageTimeS = 0; + m_startStorageTimeTicket = 0; + + if (DeviceCtrl_now_state() == kdevice_state_sampling) { + static app_event_t event; + event.eventType = kevent_stop_sample_cmd_event; + AppEvent_pushEvent(&event); + } + + return 0; +} +bool DeviceCtrl_isStoraging() { return m_isStoraging; } +uint32_t DeviceCtrl_getSettingStorageTime() { return m_settingStorageTimeS; } +uint32_t DeviceCtrl_getHasStoragedTime() { return m_hasStoragedTimeS; } + +uint8_t DeviceCtrl_StartPreview() { + if (DeviceExceptionMgr_has_error()) { + return kifyhrs_ecode_device_exception; + } + + /** + * @brief + * 1.如果当前没有在采集中,则开始采集 + * 2.如果当前正在采集中, 则只设置上报标志位 + */ + + if (m_device_state != kdevice_state_ready && m_device_state != kdevice_state_sampling) { + return kifyhrs_ecode_invalid_state; + } + + if (m_device_state == kdevice_state_ready) { + static app_event_t event; + event.eventType = kevent_start_sample_cmd_event; + AppEvent_pushEvent(&event); + m_IsRealtimeReport = true; + + m_isStoraging = false; + m_hasStoragedTimeS = 0; + m_settingStorageTimeS = 0; + m_startStorageTimeTicket = 0; + + } else if (m_device_state == kdevice_state_sampling) { + m_IsRealtimeReport = true; + } + + return 0; +} +uint8_t DeviceCtrl_StopPreview() { + m_IsRealtimeReport = false; + if (m_device_state == kdevice_state_sampling && !m_isStoraging) { + static app_event_t event; + event.eventType = kevent_stop_sample_cmd_event; + AppEvent_pushEvent(&event); + } + + return 0; } +bool DeviceCtrl_IsRealtimeReport() { return m_IsRealtimeReport; } /******************************************************************************* * EXTERN * diff --git a/app/src/device_ctrl_service.h b/app/src/device_ctrl_service.h index 6c6b609..df50e90 100644 --- a/app/src/device_ctrl_service.h +++ b/app/src/device_ctrl_service.h @@ -37,9 +37,16 @@ void DeviceCtrl_change_to_state(device_state_t state); uint32_t DeviceCtrl_cur_state_haspassed_ms(); device_state_t DeviceCtrl_now_state(); -void DeviceCtrl_startSample(int duration_ms); +uint8_t DeviceCtrl_startStorage(uint32_t storageTimeS); +uint8_t DeviceCtrl_stopStorage(); +bool DeviceCtrl_isStoraging(); +uint32_t DeviceCtrl_getSettingStorageTime(); +uint32_t DeviceCtrl_getHasStoragedTime(); + +uint8_t DeviceCtrl_StartPreview(); +uint8_t DeviceCtrl_StopPreview(); +bool DeviceCtrl_IsRealtimeReport(); -void DeviceCtrl_stopSample(); void DeviceCtrl_schdeule(); void DeviceCtrl_init(); diff --git a/dynamic_electrocardiograph_ble_server b/dynamic_electrocardiograph_ble_server index a1cff30..34a1c92 160000 --- a/dynamic_electrocardiograph_ble_server +++ b/dynamic_electrocardiograph_ble_server @@ -1 +1 @@ -Subproject commit a1cff30cf7bc44f0f12fd0a9623603a6a0060ae5 +Subproject commit 34a1c922a7336ef7602e1aa54fb04334a3d7274a diff --git a/ify_hrs_protocol b/ify_hrs_protocol index 192db52..82fc06a 160000 --- a/ify_hrs_protocol +++ b/ify_hrs_protocol @@ -1 +1 @@ -Subproject commit 192db524c562d22760899ba950f8c2bd493b3660 +Subproject commit 82fc06a24d3eb73b6bb76f2ff5baaae6db0c8b20 diff --git a/scripter/build_app.bat b/scripter/build_app.bat index a5bf10e..5a6fba5 100644 --- a/scripter/build_app.bat +++ b/scripter/build_app.bat @@ -3,7 +3,6 @@ @REM 编译app call scripter\keil_build.bat app\app.uvprojx app\_build\app.hex -del output\* @REM 检查是否编译成功 if not exist app\_build\app.hex ( @@ -11,7 +10,9 @@ if not exist app\_build\app.hex ( exit /b 1 ) + @REM 拷贝app.hex 到 output\ +del /q output\* copy /y app\_build\app.hex output\app.hex