Browse Source

init proj

hardware_test_b
zhaohe 1 year ago
parent
commit
9e8f197db3
  1. 121
      README.md
  2. 19
      app/app.uvoptx
  3. 7
      app/config/sdk_config.h
  4. 27
      app/src/app_basic_service/basic/state.h
  5. 2
      app/src/main.c
  6. 381
      app/src/one_conduction_main.c
  7. 10
      scripter/build_app.bat
  8. 32
      scripter/build_dynamic_electrocardiograph_ble_server.bat

121
README.md

@ -1,106 +1,43 @@
# one_lead_ecg
```
开发板功耗测试:
1. 连接无通信:
(20-75)*1.25 170ua
(50-75)*1.25 100ua
2. 慢广播:
8HZ-RTC/2s一次广播 平局功耗18ua,广播时800ua
3. 不广播:
8HZ-RTC 平局功耗11ua 每8s一次500us的高功耗
320HZ-RTC 平局功耗71ua 每8s一次500us的高功耗
4. 深度睡眠 : 3ua
最精简程序(不初始化任何外设)
单导联 3.2v 162ua
开发板 3ua
什么都不开:320
打开zapp定时器,和慢广播后: 320->330
系统初始化: 260->270
屏幕:10ma
20240509功耗测量:
采集时候:9ma
停止采集:3ma
待机:190ua
```
build_app.bat 编译应用程序
build_bootloader.bat 编译bootloader
flash_with_id.bat 烧录程序携带ID
...
```
程序烧录
.\scripter\build_app.bat ; .\scripter\flash.bat
```
```
onCommand
startCapture(inMainPage)
pushStartCaptureEvent
stopCapture(inCapturePage)
pushStopCaptureEvent
onConnect
loadDevice
onDisconnect
unloadDevice
onCharging(inIdlePage)
changePageToChanging
onChargEnd(inChangePage)
changePageToPowerOff
unloadDevice
State
standby
onConnected
loadDevice
onChanger
loadDevice and changeTo chargPage
welcomPage
mainPage
onChange
onStartCapture
capture
onData
onStopCapture
onError
changeToErrorPage(time)
pushDelayEvent()
onErrorPageOvertime
charging
onChargeEnd
功耗管理:
待机状态:
电池管理-待机状态
电池管理-开机状态
其他:失能
0. 调试指示灯
1. 指示灯控制
2. 读取按键
3. 串口日志
手持-蓝牙
main:
1.启动广播
2.初始化串口
3.测试硬件
按键
指示灯
电池电量
开机状态:
全部使能
状态切换:
prepare:
台面-蓝牙
main:
2. 串口
3. IO状态输出
5. 蓝牙收发消息
...
```
1. 调试串口修改位置
1. 在sdk_config.h
```
nrfjprog --readcode flash.hex
```

19
app/app.uvoptx

@ -148,7 +148,24 @@
<Name>UL2CM3(-S0 -C0 -P0 -FD20000000 -FC4000 -FN2 -FF0nrf52xxx -FS00 -FL0200000 -FF1nrf52xxx_uicr -FS110001000 -FL11000 -FP0($$Device:nRF52833_xxAA$Flash\nrf52xxx.flm) -FP1($$Device:nRF52833_xxAA$Flash\nrf52xxx_uicr.flm))</Name>
</SetRegEntry>
</TargetDriverDllRegistry>
<Breakpoint/>
<Breakpoint>
<Bp>
<Number>0</Number>
<Type>0</Type>
<LineNumber>80</LineNumber>
<EnabledFlag>1</EnabledFlag>
<Address>174592</Address>
<ByteObject>0</ByteObject>
<HtxType>0</HtxType>
<ManyObjects>0</ManyObjects>
<SizeOfObject>0</SizeOfObject>
<BreakByAccess>0</BreakByAccess>
<BreakIfRCount>1</BreakIfRCount>
<Filename>.\src\main.c</Filename>
<ExecCommand></ExecCommand>
<Expression>\\app\src/main.c\80</Expression>
</Bp>
</Breakpoint>
<Tracepoint>
<THDelay>0</THDelay>
</Tracepoint>

7
app/config/sdk_config.h

@ -1,13 +1,12 @@
#pragma once
#define NRF_LOG_ENABLED 0
#define NRF_LOG_ENABLED 1
#define NRF_LOG_BACKEND_UART_ENABLED 1
#define NRF_LOG_BACKEND_UART_TX_PIN 41
// #define NRF_LOG_BACKEND_UART_TX_PIN 6
#define APP_TIMER_CONFIG_USE_SCHEDULER 0
// #define NRF_LOG_BACKEND_UART_BAUDRATE 121634816 // 400800 baud
#define NRF_LOG_BACKEND_UART_BAUDRATE 268435456 // 1000000 baud
#define NRF_LOG_BACKEND_UART_BAUDRATE 121634816 // 400800 baud
// #define NRF_LOG_BACKEND_UART_BAUDRATE 268435456 // 1000000 baud
#define NRF_DFU_APP_DATA_AREA_SIZE 8192

27
app/src/app_basic_service/basic/state.h

@ -5,33 +5,18 @@
#include "aproject_config/config.h"
typedef enum {
kstate_standby,
kstate_welcomPage,
kstate_mainPage,
kstate_capture,
kstate_capture_end,
kstate_prepare_capture,
kstate_charging,
kstate_test,
kstate_working_ble_connected,
kstate_working_ble_disconnected,
} device_state_t;
static const char* device_state_to_str(device_state_t ds) {
switch (ds) {
case kstate_standby:
return "kstate_standby";
case kstate_welcomPage:
return "kstate_welcomPage";
case kstate_mainPage:
return "kstate_mainPage";
case kstate_capture:
return "kstate_capture";
case kstate_capture_end:
return "kstate_capture_end";
case kstate_prepare_capture:
return "kstate_prepare_capture";
case kstate_charging:
return "kstate_charging";
case kstate_test:
return "kstate_test";
case kstate_working_ble_connected:
return "kstate_working_ble_connected";
case kstate_working_ble_disconnected:
return "kstate_working_ble_disconnected";
default:
return "unknown";
}

2
app/src/main.c

@ -64,7 +64,7 @@ void app_error_fault_handler(uint32_t id, uint32_t pc, uint32_t info) {
int main() {
zapp_early_init();
znordic_init();
znordic_init_without_wd();
zapp_init();
/*******************************************************************************

381
app/src/one_conduction_main.c

@ -34,21 +34,8 @@ static uint16_t m_capture_prepare_progress = 0;
/***********************************************************************************************************************
* *
***********************************************************************************************************************/
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);
}
}
static void process_on_connect(void* arg);
static void process_on_disconnect(void* arg);
void on_zble_event(zble_event_t* event) {
if (event->eventType == kzble_event_connected) {
@ -78,357 +65,19 @@ void one_conduction_process_rx_packet(uint8_t* rx, int len) {
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;
static void process_on_connect(void* arg) { ZLOGI("ble connected"); }
static void process_on_disconnect(void* arg) { ZLOGI("ble disconnected"); }
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 {
zapp_state_machine_change_state(kstate_capture);
#if 0
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);
}
}
}
#endif
}
} 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() >= 2000) {
zapp_state_machine_change_state(kstate_capture_end);
} else if (event == kappevent_stop_capture) {
zapp_state_machine_change_state(kstate_capture_end);
} else if (event == kecg_data_report_event) {
report_ecg_data(p_event);
}
}
} else if (zapp_state_machine_now_state() == kstate_capture_end) {
if (event == kappevent_state_machine_state_enter) {
dsp_mgr_change_page(kpage_sampling_end);
} else if (event == kappevent_state_machine_state_exit) {
} else {
if (zapp_state_machine_haspassed_ms() > 2000) {
zapp_state_machine_change_state(kstate_mainPage);
}
}
}
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);
}
ZLOGI("event:%d", p_event->eventType)
}
/***********************************************************************************************************************
@ -461,18 +110,18 @@ void one_conduction_main() {
zapp_state_machine_reg_state_change_listener(on_state_change);
zble_module_reglistener(on_zble_event);
adc_mgr_init();
hardware_power_mgr_init();
// adc_mgr_init();
// hardware_power_mgr_init();
battery_mgr_service_init();
battery_mgr_service_load();
// battery_mgr_service_init();
// battery_mgr_service_load();
light_ctrl_init();
beep_init();
dsp_mgr_init();
ecg_service_init();
// light_ctrl_init();
// beep_init();
// dsp_mgr_init();
// ecg_service_init();
// zapp_state_machine_change_state(kstate_capture);
zapp_state_machine_change_state(kstate_standby);
zble_module_start_adv();
zapp_start_schedule();

10
scripter/build_app.bat

@ -1,13 +1,15 @@
@echo off
md output
@REM ±àÒëapp
call scripter\keil_build.bat app\app.uvprojx app\_build\app.hex
del output\app_whole.hex
del output\app.zip
del output\one_lead_ecg_ads1291.zip
del output\one_lead_ecg_ads1291.hex
del output\hand_acid_remoter.zip
del output\hand_acid_remoter.hex
@REM ¼ì²éÊÇ·ñ±àÒë³É¹¦
if not exist app\_build\app.hex (
@ -59,5 +61,5 @@ del output\settings.hex
del output\app.hex
copy /y output\app.zip output\one_lead_ecg_ads1291.zip
copy /y output\app_whole.hex output\one_lead_ecg_ads1291.hex
copy /y output\app.zip output\hand_acid_remoter.zip
copy /y output\app_whole.hex output\hand_acid_remoter.hex

32
scripter/build_dynamic_electrocardiograph_ble_server.bat

@ -1,32 +0,0 @@
set UV_PRO_PATH=dynamic_electrocardiograph_ble_server\ble_app_uart_c_pca10100_s122.uvprojx
set BUILD_RESULT=dynamic_electrocardiograph_ble_server\_build\dynamic_electrocardiograph_ble_server.hex
call scripter\keil_build.bat ^
%UV_PRO_PATH% ^
%BUILD_RESULT%
if not exist %BUILD_RESULT% (
echo EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
echo E 긍陋 %UV_PRO_PATH% 呵겨
echo EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
exit /b 1
)
@REM 댔관
mergehex --merge ^
res/s140_nrf52_7.2.0_softdevice.hex ^
%BUILD_RESULT% ^
--output output/dynamic_electrocardiograph_ble_server.hex
if %errorlevel% neq 0 (
echo EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
echo E 댔관呵겨
echo EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE
exit /b 1
)
@REM �쩌
nrfjprog --eraseall -f NRF52 %홍꼰뇜%
nrfjprog --program output/dynamic_electrocardiograph_ble_server.hex --verify -f NRF52 %�쩌%
Loading…
Cancel
Save