diff --git a/.vscode/settings.json b/.vscode/settings.json index 190f974..4b2f85b 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -203,7 +203,8 @@ "zsdk_ble_slave_config.h": "c", "ads129x.h": "c", "ads129x_if_impl.h": "c", - "ads129x_type.h": "c" + "ads129x_type.h": "c", + "app_board.h": "c" }, "files.encoding": "gbk" } \ No newline at end of file diff --git a/README.md b/README.md index ddd0234..6e55f32 100644 --- a/README.md +++ b/README.md @@ -44,7 +44,43 @@ V10: ``` -单导:休眠527ua +代码修改思路: + +临时版本: + 1. 开机初始化ads129x + 2. 永不进入深度休眠 + 3. ECG连接状态一直标注为1 + 4. 不存储数据 + + +ECG连接状态一直标注为1 + + + +board_init + 1. 没有深度睡眠 + + poweroff + app_power_state_change_to poweroff + + poweron + app_power_state_change_to poweron + + + 服务本身没有低功耗的概念,所有低功耗的操作,均直接对硬件进行操作。 + 服务内部调用方法,都假设初始化已经均完成。 + + 指示灯初始化 + + + onStateChange + onState + + + + + + ``` \ No newline at end of file diff --git a/app/src/aproject_config/config.h b/app/src/aproject_config/config.h index 9e59a04..6974224 100644 --- a/app/src/aproject_config/config.h +++ b/app/src/aproject_config/config.h @@ -4,7 +4,7 @@ * 设备信息配置 * ***********************************************************************************************************************/ -#define CATEGORY "M1001" // 单导联 +#define CATEGORY "M1003" // 单导联 #define MANUFACTURER_NAME "iflytop" #define FIRMWARE_VERSION (10) @@ -20,21 +20,12 @@ #define BEEP_PIN 1 #define BEEP_PWM_INSTANCE 0 -/******************************************************************************* - * ADC * - *******************************************************************************/ - -#define ECG_NLOD_PIN 3 -#define ECG_PLOD_PIN 28 -#define ECG_ADC_PIN NRF_SAADC_INPUT_AIN0 -#define ECG_ADC_CHANNEL 0 // 不重复即可 #define BATTERY_ADC_PIN NRF_SAADC_INPUT_AIN3 #define BATTERY_ADC_CHANNEL 1 // 不重复即可 #define BATTERY_CHARGE_DETECT_PIN 6 - /** * @brief */ diff --git a/app/src/basic_service/device_state.c b/app/src/basic_service/device_state.c index 243c1b5..84f2892 100644 --- a/app/src/basic_service/device_state.c +++ b/app/src/basic_service/device_state.c @@ -2,18 +2,44 @@ #include "device_state.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 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); // 状态机驱动定时器 -void ds_change_to_state(device_state_t state) { - ZLOGI("change state from %s to %s", device_state_to_str(m_device_state), device_state_to_str(state)); - m_device_state = state; +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; } +device_state_t 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() { // diff --git a/app/src/basic_service/device_state.h b/app/src/basic_service/device_state.h index 6c6d7c9..c139f74 100644 --- a/app/src/basic_service/device_state.h +++ b/app/src/basic_service/device_state.h @@ -4,6 +4,10 @@ #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); + +device_state_t 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(); diff --git a/app/src/board/ads129x/ads129x.c b/app/src/board/ads129x/ads129x.c index 6fdd24c..d968786 100644 --- a/app/src/board/ads129x/ads129x.c +++ b/app/src/board/ads129x/ads129x.c @@ -1,7 +1,8 @@ #include "ads129x.h" #include "ads129x_type.h" -#include "board/app_board.h" +#include "nrf_drv_gpiote.h" +#include "znordic.h" /** * @brief ads129x 使用注意事项 @@ -31,13 +32,15 @@ * */ -#define ADS129X_CS_SET() nrf_gpio_pin_set(ADS1291_SPI_CS0_PIN); -#define ADS129X_CS_RESET() nrf_gpio_pin_clear(ADS1291_SPI_CS0_PIN); -#define ADS129X_START_SET() nrf_gpio_pin_set(ADS1291_START_PIN); -#define ADS129X_START_RESET() nrf_gpio_pin_clear(ADS1291_START_PIN); -#define ADS129X_REST_SET() nrf_gpio_pin_set(ADS1291_PWDN_PIN); -#define ADS129X_REST_RESET() nrf_gpio_pin_clear(ADS1291_PWDN_PIN); -#define ADS129X_DRDY_GET() nrf_gpio_pin_read(ADS1291_READY_PIN) +static ads129x_cfg_t* ads129x_cfg; + +#define ADS129X_CS_SET() nrf_gpio_pin_set(ads129x_cfg->cspin); +#define ADS129X_CS_RESET() nrf_gpio_pin_clear(ads129x_cfg->cspin); +#define ADS129X_START_SET() nrf_gpio_pin_set(ads129x_cfg->startpin); +#define ADS129X_START_RESET() nrf_gpio_pin_clear(ads129x_cfg->startpin); +#define ADS129X_REST_SET() nrf_gpio_pin_set(ads129x_cfg->pwdnpin); +#define ADS129X_REST_RESET() nrf_gpio_pin_clear(ads129x_cfg->pwdnpin); +#define ADS129X_DRDY_GET() nrf_gpio_pin_read(ads129x_cfg->drdypin) static void port_ads129x_delay_us(uint32_t us) { nrf_delay_us(us); } static void port_ads129x_delay_ms(uint32_t ms) { nrf_delay_ms(ms); } @@ -50,7 +53,7 @@ static void port_ads129x_delay_ms(uint32_t ms) { nrf_delay_ms(ms); } uint8_t port_spi_transmit_receive(uint8_t tx) { uint8_t data; - nrf_drv_spi_transfer(&ads129x_spi, &tx, 1, &data, 1); + nrf_drv_spi_transfer(ads129x_cfg->spi, &tx, 1, &data, 1); return data; } @@ -184,10 +187,12 @@ void ads129x_read_data_loop() { } } -uint8_t ads129x_init() { +uint8_t ads129x_init(ads129x_cfg_t* cfg) { /** * @brief */ + ads129x_cfg = cfg; + ZASSERT(nrfx_gpiote_is_init()); ADS129X_CS_SET(); @@ -204,11 +209,7 @@ uint8_t ads129x_init() { ads129X_send_cmd(ADS129X_COMMAND_SDATAC); port_ads129x_delay_ms(100); - nrf_gpio_pin_set(ADS1291_PWDN_PIN); - nrf_delay_ms(2000); - - ads129x_start_capture(false); - ads129x_read_data_loop(); + nrf_gpio_pin_set(ads129x_cfg->pwdnpin); } uint8_t ads129x_start_capture(bool test) { diff --git a/app/src/board/ads129x/ads129x.h b/app/src/board/ads129x/ads129x.h index 9588d67..e25c894 100644 --- a/app/src/board/ads129x/ads129x.h +++ b/app/src/board/ads129x/ads129x.h @@ -6,6 +6,7 @@ extern "C" { #include #include +#include "znordic.h" typedef struct { /** * @brief @@ -24,11 +25,18 @@ typedef struct { uint32_t ch2data; } ads129x_capture_data_t; +typedef struct { + nrf_drv_spi_t* spi; + uint32_t cspin; + uint32_t startpin; + uint32_t drdypin; + uint32_t pwdnpin; +} ads129x_cfg_t; + /** * @brief 初始化SPI */ - -uint8_t ads129x_init(); +uint8_t ads129x_init(ads129x_cfg_t *cfg); uint8_t ads129x_start_capture(bool test); uint8_t ads129x_enter_low_power_mode(); diff --git a/app/src/board/app_board.c b/app/src/board/app_board.c index 8791ca1..a693e52 100644 --- a/app/src/board/app_board.c +++ b/app/src/board/app_board.c @@ -1,5 +1,25 @@ #include "app_board.h" +#include "ads129x/ads129x.h" +#include "board_battery_state.h" +#include "board_power_mgr.h" +/*********************************************************************************************************************** + * CFG * + ***********************************************************************************************************************/ + +#define ADS1291_SPI_INSTANCE 2 + +/*********************************************************************************************************************** + * ADS1291_IF * + ***********************************************************************************************************************/ +#define ADS1291_SPI_CS0_PIN 3 +#define ADS1291_SPI_SCK_PIN (32 + 3) +#define ADS1291_SPI_MOSI_PIN 19 +#define ADS1291_SPI_MISO_PIN (32 + 5) +#define ADS1291_PWDN_PIN 28 +#define ADS1291_START_PIN 2 +#define ADS1291_READY_PIN 23 + /*********************************************************************************************************************** * MARCO * ***********************************************************************************************************************/ @@ -15,6 +35,9 @@ * HARDWARE_INSTANCE * ***********************************************************************************************************************/ +/*********************************************************************************************************************** + * ADS_HANDLER * + ***********************************************************************************************************************/ nrf_drv_spi_t ads129x_spi = NRF_DRV_SPI_INSTANCE(ADS1291_SPI_INSTANCE); // global static nrf_drv_spi_config_t ads129x_spi_config = { .sck_pin = ADS1291_SPI_SCK_PIN, @@ -29,23 +52,23 @@ static nrf_drv_spi_config_t ads129x_spi_config = { }; on_irq_t ads129x_ready_pin_listener; +/*********************************************************************************************************************** + * 中断回调 * + ***********************************************************************************************************************/ static void ads1291_ready_pin_irq(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action) { // - if (ads129x_ready_pin_listener) ads129x_ready_pin_listener(kon_irq_ads1291_ready_pin); + if (ads129x_ready_pin_listener) { + ads129x_ready_pin_listener(kon_irq_ads1291_ready_pin); + } } -void app_board_init() { - nrfx_gpiote_init(); - - /*********************************************************************************************************************** - * ads129x * - ***********************************************************************************************************************/ +/*********************************************************************************************************************** + * ads129x * + ***********************************************************************************************************************/ +static void __ads1291_init() { APP_BOARD_INIT_CHECK(nrf_drv_spi_init(&ads129x_spi, &ads129x_spi_config, NULL, NULL)); znrf_gpio_cfg_output(ADS1291_PWDN_PIN, NRF_GPIO_PIN_NOPULL); znrf_gpio_cfg_output(ADS1291_START_PIN, NRF_GPIO_PIN_NOPULL); znrf_gpio_cfg_output(ADS1291_SPI_CS0_PIN, NRF_GPIO_PIN_NOPULL); - nrf_gpio_pin_clear(ADS1291_PWDN_PIN); - nrf_gpio_pin_clear(ADS1291_START_PIN); - nrf_gpio_pin_set(ADS1291_SPI_CS0_PIN); // --------------------------------------------------------------------------- nrf_gpio_cfg_input(ADS1291_READY_PIN, NRF_GPIO_PIN_NOPULL); @@ -56,6 +79,25 @@ void app_board_init() { inConfig.sense = NRF_GPIOTE_POLARITY_HITOLO; // 下降沿触发 nrfx_gpiote_in_init(ADS1291_READY_PIN, &inConfig, ads1291_ready_pin_irq); } + static ads129x_cfg_t ads129x_cfg = { + .cspin = ADS1291_SPI_CS0_PIN, + .drdypin = ADS1291_READY_PIN, + .pwdnpin = ADS1291_PWDN_PIN, + .startpin = ADS1291_START_PIN, + .spi = &ads129x_spi, + }; + ads129x_init(&ads129x_cfg); +} +/*********************************************************************************************************************** + * EXTERN * + ***********************************************************************************************************************/ +void app_board_init() { + nrfx_gpiote_init(); + __ads1291_init(); + BoardBattery_init(); + BoardBattery_load(); + board_power_mgr_init(); + board_power_mgr_main_power_supply_set(true); } void app_board_reg_irq_listener(app_board_irq_event_t event, on_irq_t listener) { diff --git a/app/src/board/app_board.h b/app/src/board/app_board.h index 33846ae..db66bd7 100644 --- a/app/src/board/app_board.h +++ b/app/src/board/app_board.h @@ -2,18 +2,6 @@ #include "nrf_drv_gpiote.h" #include "znordic.h" -#define ADS1291_SPI_INSTANCE 2 - -/*********************************************************************************************************************** - * ADS1291_IF * - ***********************************************************************************************************************/ -#define ADS1291_SPI_CS0_PIN 3 -#define ADS1291_SPI_SCK_PIN (32 + 3) -#define ADS1291_SPI_MOSI_PIN 19 -#define ADS1291_SPI_MISO_PIN (32 + 5) -#define ADS1291_PWDN_PIN 28 -#define ADS1291_START_PIN 2 -#define ADS1291_READY_PIN 23 typedef enum { kapp_power_state_uint, diff --git a/app/src/board/board_adc_module_ctrl.c b/app/src/board/board_adc_module_ctrl.c index f70fd81..59277c1 100644 --- a/app/src/board/board_adc_module_ctrl.c +++ b/app/src/board/board_adc_module_ctrl.c @@ -36,11 +36,7 @@ void BoardAdc_unload() { void BoardAdc_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 == ECG_ADC_CHANNEL) { - nrf_saadc_channel_config_t channel_config = NRF_DRV_SAADC_DEFAULT_CHANNEL_CONFIG_SE(ECG_ADC_PIN); - channel_config.acq_time = NRF_SAADC_ACQTIME_40US; - ZERROR_CHECK(nrfx_saadc_channel_init(ECG_ADC_CHANNEL, &channel_config)); - } else if (ch == BATTERY_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)); diff --git a/app/src/board/board_ecg_sensor.c b/app/src/board/board_ecg_sensor.c index 77c8676..206581a 100644 --- a/app/src/board/board_ecg_sensor.c +++ b/app/src/board/board_ecg_sensor.c @@ -3,235 +3,3 @@ #include "basic_service/app_event_distribute.h" #include "board_adc_module_ctrl.h" -#if 0 -APP_TIMER_DEF(module_tmr); // - -// 导联连接状态事件生成器 -static bool m_plod_state_connected_state = false; -static uint32_t m_connecte_state_last_trigger_timepoint = 0; - -static uint32_t plod_state_has_disconnected_ms() { return znordic_haspassed_ms(m_connecte_state_last_trigger_timepoint); } -static bool plod_state_is_connected() { return m_plod_state_connected_state; } - -static void module_tmr_cb(void *context) { // - static uint32_t connecte_state_trigger_cnt = 0; - static app_event_t appevent; - memset(&appevent, 0, sizeof(appevent)); - // ZLOGI("ecg sensor %d",m_plod_state_connected_state); - - if (true) { - connecte_state_trigger_cnt++; - m_connecte_state_last_trigger_timepoint = znordic_getpower_on_ms(); - } else { - connecte_state_trigger_cnt = 0; - } - - if (!m_plod_state_connected_state && connecte_state_trigger_cnt >= 10) { - // 连接事件 - appevent.eventType = kplod_connected_event; - m_plod_state_connected_state = true; - AppEvent_pushEvent(&appevent); - } else if (m_plod_state_connected_state && connecte_state_trigger_cnt == 0) { - // 断开事件 - appevent.eventType = kplod_disconnected_event; - m_plod_state_connected_state = false; - AppEvent_pushEvent(&appevent); - } -} - -void BoardEcgSensor_init() { - // nrf_gpio_cfg_sense_input(ECG_NLOD_PIN, NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_NOSENSE); - // nrf_gpio_cfg_sense_input(ECG_PLOD_PIN, NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_NOSENSE); // 低有效 - - app_timer_create(&module_tmr, APP_TIMER_MODE_REPEATED, module_tmr_cb); - app_timer_start(module_tmr, APP_TIMER_TICKS(100), NULL); -} -void BoardEcgSensor_load() { BoardAdc_load(); } -void BoardEcgSensor_unload() { BoardAdc_unload(); } - -int16_t BoardEcgSensor_nlod_get_connected_state() { return true; } -int16_t BoardEcgSensor_plod_get_connected_state() { return true; } -int16_t BoardEcgSensor_plod_get_ecg_val() { return 0; } - -int16_t BoardEcgSensor_plod_get_connected_state_after_filter() { return plod_state_is_connected(); } -int16_t BoardEcgSensor_plod_state_has_disconnected_ms() { return plod_state_has_disconnected_ms(); } - -int16_t BoardEcgSensor_set_sence_state() { - nrf_gpio_cfg_default(ECG_NLOD_PIN); - nrf_gpio_cfg_sense_input(ECG_PLOD_PIN, NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_SENSE_LOW); - return 0; -} - -#endif -#if 0 -void BoardEcgSensor_load() {} -void BoardEcgSensor_unload() {} - -int16_t BoardEcgSensor_nlod_get_connected_state() { return 0; } -int16_t BoardEcgSensor_plod_get_connected_state() { return 0; } -int16_t BoardEcgSensor_plod_get_connected_state_after_filter() { return 0; } -int16_t BoardEcgSensor_plod_state_has_disconnected_ms() { return 0; } - -int16_t BoardEcgSensor_plod_get_ecg_val() { return 0; } -int16_t BoardEcgSensor_set_sence_state() { return 0; } - -/******************************************************************************* - * ADS驱动程序 * - *******************************************************************************/ -#define ADS1291_SPI_INSTANCE 2 - -#define ADS1291_PWDN_PIN 28 -#define ADS1291_START_PIN 2 -#define ADS1291_SPI_CS0_PIN 3 -#define ADS1291_READY_PIN 23 - -#define ADS1291_SPI_SCK_PIN (32 + 3) -// #define ADS1291_SPI_MOSI_PIN (32 + 5) -// #define ADS1291_SPI_MISO_PIN 19 - -#define ADS1291_SPI_MOSI_PIN 19 -#define ADS1291_SPI_MISO_PIN (32 + 5) - -static const nrf_drv_spi_t spi = NRF_DRV_SPI_INSTANCE(ADS1291_SPI_INSTANCE); /**< SPI instance. */ - -static void ads1291_init() { -/******************************************************************************* - * SPI初始化 * - *******************************************************************************/ -#if 1 - static nrf_drv_spi_config_t spi_config = NRF_DRV_SPI_DEFAULT_CONFIG; - spi_config.ss_pin = NRF_DRV_SPI_PIN_NOT_USED; // NRF_DRV_SPI_PIN_NOT_USED - spi_config.miso_pin = ADS1291_SPI_MISO_PIN; - spi_config.mosi_pin = ADS1291_SPI_MOSI_PIN; - spi_config.sck_pin = ADS1291_SPI_SCK_PIN; - spi_config.frequency = NRF_DRV_SPI_FREQ_1M; - spi_config.mode = NRF_DRV_SPI_MODE_1; - // spi_config.mode = - - uint32_t ecode = nrf_drv_spi_init(&spi, &spi_config, NULL, NULL); - if (ecode != NRF_SUCCESS) { - ZLOGI("%s:%d ZERROR_CHECK(nrf_drv_spi_init) fail:%d", __FILE__, __LINE__, ecode); - return; - } -#endif - - // ADS1291_PWDN_PIN output - // ADS1291_START_PIN output - // ADS1291_SPI_CS0_PIN output - // ADS1291_READY_PIN input - - znrf_gpio_cfg_output(ADS1291_PWDN_PIN, NRF_GPIO_PIN_NOPULL); - znrf_gpio_cfg_output(ADS1291_START_PIN, NRF_GPIO_PIN_NOPULL); - znrf_gpio_cfg_output(ADS1291_SPI_CS0_PIN, NRF_GPIO_PIN_NOPULL); - nrf_gpio_cfg_input(ADS1291_READY_PIN, NRF_GPIO_PIN_NOPULL); - - nrf_gpio_pin_clear(ADS1291_PWDN_PIN); // 低复位,高使能 - nrf_gpio_pin_clear(ADS1291_START_PIN); // 低开始转换,高停止转换 - nrf_gpio_pin_set(ADS1291_SPI_CS0_PIN); -} - -static void ads1291_spi_tx_rx_0(uint8_t *tx, uint8_t *rx, uint8_t len) { - nrf_gpio_pin_clear(ADS1291_SPI_CS0_PIN); - nrf_drv_spi_transfer(&spi, tx, len, rx, len); - nrf_gpio_pin_set(ADS1291_SPI_CS0_PIN); -} -uint8_t port_spi_transmit_receive(uint8_t tx) { - uint8_t data; - nrf_drv_spi_transfer(&spi, &tx, 1, &data, 1); - return data; -} - -#define ADS1292_CS_SET() nrf_gpio_pin_set(ADS1291_SPI_CS0_PIN) -#define ADS1292_CS_RESET() nrf_gpio_pin_clear(ADS1291_SPI_CS0_PIN) - -/* ads1292r读写寄存器,自动根据指令类型区分读和写操作 */ -uint8_t ads1292r_rw_reg(uint8_t cmd, uint8_t data) { - uint8_t rx = 0; - - ADS1292_CS_RESET(); /* 选中设备 */ -#if 1 - nrf_delay_us(1); - - port_spi_transmit_receive(cmd); /* 发送读写指令 */ - port_spi_transmit_receive(0X00); /* 只写一个数据 */ - - if ((cmd & ADS1292R_COMMAND_RREG) == ADS1292R_COMMAND_RREG) /* 判断指令类型 */ - rx = port_spi_transmit_receive(0X00); /* 返回寄存器值 */ - else - rx = port_spi_transmit_receive(data); /* 写入数值 */ - - nrf_delay_us(1); -#endif - ADS1292_CS_SET(); /* 释放设备 */ - - return rx; -} -#define port_delay_ms nrf_delay_ms -#define port_delay_us nrf_delay_us -#define ADS1292_START_RESET() nrf_gpio_pin_clear(ADS1291_START_PIN) -#define ADS1292_START_SET() nrf_gpio_pin_set(ADS1291_START_PIN) -#define ADS1292_REST_RESET() nrf_gpio_pin_clear(ADS1291_PWDN_PIN) -#define ADS1292_REST_SET() nrf_gpio_pin_set(ADS1291_PWDN_PIN) -uint8_t ads1292r_send_cmd(uint8_t cmd) { - uint8_t rx = 0; - - ADS1292_CS_RESET(); /* 选中设备 */ - port_delay_us(100); - - rx = port_spi_transmit_receive(cmd); - - port_delay_us(100); - ADS1292_CS_SET(); /* 释放设备 */ - - return rx; -} - -void nrf_log_backend_uart_tx_raw(char const * p_buffer, size_t len); - -void BoardEcgSensor_init() { - /** - * @brief - */ - - ads1291_init(); - - ADS1292_CS_SET(); - - ADS1292_REST_RESET(); - ADS1292_START_RESET(); - port_delay_ms(1000); - ADS1292_REST_SET(); - port_delay_ms(100); /* 硬件复位 */ - - ads1292r_send_cmd(ADS1292R_COMMAND_SDATAC); /* 软件复位,并停止连续读状态 */ - port_delay_ms(100); - ads1292r_send_cmd(ADS1292R_COMMAND_RESET); - port_delay_ms(1000); - ads1292r_send_cmd(ADS1292R_COMMAND_SDATAC); - port_delay_ms(100); - - nrf_gpio_pin_set(ADS1291_PWDN_PIN); - nrf_delay_ms(2000); - char txdata[]= {1,2,3,4}; - while (true) /* 识别芯片型号,1291:0x52 */ - { - uint8_t id = ads1292r_rw_reg(ADS1292R_COMMAND_RREG | ADS1292R_REG_ID, 0); - nrf_log_backend_uart_tx_raw(txdata,4); - znordic_force_flush_log(); - nrf_delay_ms(1000); - } -} - -#endif - -void BoardEcgSensor_init() {} -void BoardEcgSensor_load() {} -void BoardEcgSensor_unload() {} - -int16_t BoardEcgSensor_nlod_get_connected_state() { return 0; } -int16_t BoardEcgSensor_plod_get_connected_state() { return 0; } -int16_t BoardEcgSensor_plod_get_connected_state_after_filter() { return 0; } -int16_t BoardEcgSensor_plod_state_has_disconnected_ms() { return 0; } - -int16_t BoardEcgSensor_plod_get_ecg_val() { return 0; } -int16_t BoardEcgSensor_set_sence_state() { return 0; } diff --git a/app/src/board/board_ecg_sensor.h b/app/src/board/board_ecg_sensor.h index 74ab33c..52c7fbe 100644 --- a/app/src/board/board_ecg_sensor.h +++ b/app/src/board/board_ecg_sensor.h @@ -6,14 +6,3 @@ #include "aproject_config/config.h" #include "znordic.h" -void BoardEcgSensor_init(); -void BoardEcgSensor_load(); -void BoardEcgSensor_unload(); - -int16_t BoardEcgSensor_nlod_get_connected_state(); -int16_t BoardEcgSensor_plod_get_connected_state(); -int16_t BoardEcgSensor_plod_get_connected_state_after_filter(); -int16_t BoardEcgSensor_plod_state_has_disconnected_ms(); - -int16_t BoardEcgSensor_plod_get_ecg_val(); -int16_t BoardEcgSensor_set_sence_state(); diff --git a/app/src/board/soc_public_res_mgr.c b/app/src/board/soc_public_res_mgr.c new file mode 100644 index 0000000..e69de29 diff --git a/app/src/board/soc_public_res_mgr.h b/app/src/board/soc_public_res_mgr.h new file mode 100644 index 0000000..6f70f09 --- /dev/null +++ b/app/src/board/soc_public_res_mgr.h @@ -0,0 +1 @@ +#pragma once diff --git a/app/src/one_conduction_main.c b/app/src/one_conduction_main.c index 9ad11e4..e39ee98 100644 --- a/app/src/one_conduction_main.c +++ b/app/src/one_conduction_main.c @@ -25,87 +25,16 @@ * GLOBAL * *******************************************************************************/ -APP_TIMER_DEF(m_state_machine_driver_tmr); // 状态机驱动定时器 -// APP_TIMER_DEF(m_plod_state_event_detect_tmr); // 导联连接状态检测定时器 -// APP_TIMER_DEF(m_charge_event_detect_tmr); // 充电事件检测 - static int m_cur_fd; static sample_data_filename_t sampledata_file_name; #define SCHED_MAX_EVENT_DATA_SIZE MAX(sizeof(app_event_t), APP_TIMER_SCHED_EVENT_DATA_SIZE) /******************************************************************************* - * 函数声明 * - *******************************************************************************/ - -// 业务事件处理函数 - -/******************************************************************************* - * 事件生成器 * - *******************************************************************************/ -// static void m_charge_event_detect_tmr_cb(void* p_context) { // -// static app_event_t appevent; -// memset(&appevent, 0, sizeof(appevent)); -// static bool ischarging = false; -// } - -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); -} -/******************************************************************************* * 事件处理 * *******************************************************************************/ -static bool m_poweronflag; -static void power_on() { - if (m_poweronflag) { - return; - } - - BoardBeepCtrl_load(); - BoardEcgSensor_load(); - BoardBattery_load(); - BoardLight_load(); - hwss_init(); - - sample_data_mgr_init(); - dsp_mgr_init(); - ble_cmder_init(); - ble_cmder_start_adv(); - m_poweronflag = true; -} -static void power_off() { - if (!m_poweronflag) return; - dsp_mgr_uninit(); - sample_data_mgr_uninit(); - hwss_uninit(); - - BoardEcgSensor_unload(); - BoardBattery_unload(); - 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); - m_poweronflag = false; -} void ENTER_DEEP_SLEEP() { // 进入深度睡眠前,使能唤醒引脚 - BoardEcgSensor_set_sence_state(); BoardBattery_sence_gpio_init_before_sleep(); // nrf_sdh_disable_request(); app_timer_pause(); @@ -117,52 +46,66 @@ void ENTER_DEEP_SLEEP() { /******************************************************************************* * 状态切换方法 * *******************************************************************************/ -/** - * @brief 切换到充电中状态 - */ -static void state_machine__change_to_charging_state() { // - power_on(); - // 切换到充电显示页面 - dsp_mgr_change_to_chargingPage(); - ds_change_to_state(kdevice_state_charging); -} -/** - * @brief 切换到待机状态 - */ +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(); -static void state_machine__change_to_standby_state() { - ZLOGI_BLOCK("change to standby"); - power_off(); - ds_change_to_state(kdevice_state_standby); -} + sample_data_mgr_init(); + dsp_mgr_init(); + ble_cmder_init(); + ble_cmder_start_adv(); -/** - * @brief 切换到开机中画面 - */ -static void state_machine__change_to_poweroning_state() { - power_on(); - dsp_mgr_change_to_welcome(); - ds_change_to_state(kdevice_state_poweron); -} + app_board_change_state(kapp_power_state_working); + + } else if (to == kdevice_state_standby) { + /** + * @brief 切换到待机模式 + * + */ + dsp_mgr_uninit(); + sample_data_mgr_uninit(); + + BoardLight_unload(); -/** - * @brief 切换到首页 - */ -static void state_machine__change_to_home_state() { - ds_change_to_state(kdevice_state_home); - dsp_mgr_change_to_main(); + BoardBeepCtrl_unload(); + ble_stop_upload_record(); + zble_module_disconnect(); + for (size_t i = 0; i < 100; i++) { + nrf_delay_ms(10); + if (!zble_module_is_connected()) { + break; + } + } + ble_cmder_stop_adv(); + ble_cmder_uninit(); + board_power_mgr_main_power_supply_set(false); + app_board_change_state(kapp_power_state_standby); + } + + /*********************************************************************************************************************** + * 切换状态 附带操作 * + ***********************************************************************************************************************/ + if (to == kdevice_state_home) { + dsp_mgr_change_to_main(); + } else if (to == kdevice_state_poweron) { + dsp_mgr_change_to_welcome(); + } else if (to == kdevice_state_charging) { + dsp_mgr_change_to_chargingPage(); + } } static void app_event_listener(void* p_event_data, uint16_t event_size) { if (!p_event_data) return; app_event_t* p_event = (app_event_t*)p_event_data; - // BoardLight_blockFlash(3,100); - // ZLOGI("......"); - - // return; - if (ds_now_state() != kdevice_state_standby && // ds_now_state() != kdevice_state_charging && // ds_now_state() != kdevice_state_poweron // @@ -182,16 +125,17 @@ static void app_event_listener(void* p_event_data, uint16_t event_size) { if (ds_now_state() == kdevice_state_standby) { // 充电事件触发 --> 切换到充电页面 if (BoardBattery_get_charging_state()) { - state_machine__change_to_charging_state(); + ds_change_to_state(kdevice_state_charging); } // 导联连接事件触发 --> 切换到开机中页面 - else if (BoardEcgSensor_plod_get_connected_state_after_filter() && znordic_haspassed_ms(lasttrypoweron_time) >= LOW_BATTERY_REMINDER_DELAY_MS) { + 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) { - state_machine__change_to_poweroning_state(); + ds_change_to_state(kdevice_state_poweron); } else { BoardLight_load(); BoardLight_blockFlash(3, 100); @@ -199,14 +143,16 @@ static void app_event_listener(void* p_event_data, uint16_t event_size) { } } - // 10秒后,如果RTC未被设置过,则进入超低功耗 + /** + * @brief + * TODO: + * 1. 永远不进入超低功耗状态,直到电池电量低于一定程度 + * 2. 如果RTC未被设置,则重置设备状态 + * 3. 在每次从待机状态切换到开机状态,如果RTC未被设置,则清空已经存储的波形数据 + */ else if (ds_cur_state_haspassed_ms() >= 10000) { if (!znordic_rtc_has_setted()) { - ENTER_DEEP_SLEEP(); } - // if (APP_BATTERY_PROTECT_LEVEL > BoardBattery_get_battery_level()) { - // ENTER_DEEP_SLEEP(); - // } } } @@ -215,7 +161,7 @@ static void app_event_listener(void* p_event_data, uint16_t event_size) { *******************************************************************************/ else if (ds_now_state() == kdevice_state_charging) { if (!BoardBattery_get_charging_state()) { - state_machine__change_to_standby_state(); + ds_change_to_state(kdevice_state_standby); } } @@ -225,7 +171,7 @@ static void app_event_listener(void* p_event_data, uint16_t event_size) { else if (ds_now_state() == kdevice_state_poweron) { if (ds_cur_state_haspassed_ms() >= 1500) { - state_machine__change_to_home_state(); + ds_change_to_state(kdevice_state_home); } } @@ -235,14 +181,13 @@ static void app_event_listener(void* p_event_data, uint16_t event_size) { else if (ds_now_state() == kdevice_state_home) { // 如果用户长时间不操作,自动切换到待机状态 - if (!zdatachannel_is_connected() && // - !BoardEcgSensor_plod_get_connected_state_after_filter() && // - BoardEcgSensor_plod_state_has_disconnected_ms() >= 3000 && // + if (!zdatachannel_is_connected() && // + !hwss_lead_get_state_connected_state() && // ds_cur_state_haspassed_ms() >= AUTOMATIC_SLEEP_TIME) { - state_machine__change_to_standby_state(); + ds_change_to_state(kdevice_state_standby); } // 如果用户继续保持静止,切换到采集页面 - else if (BoardEcgSensor_plod_get_connected_state_after_filter() && ds_cur_state_haspassed_ms() > 1500) { + 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); @@ -254,32 +199,31 @@ static void app_event_listener(void* p_event_data, uint16_t event_size) { } } #if 0 + //TODO:使能 // 低电量,设备进入待机模式 else if (BoardBattery_get_battery_level() < APP_AUTO_STANDY_BATTERY_LEVEL && ds_cur_state_haspassed_ms() > 3000) { - state_machine__change_to_standby_state(); + 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"); - state_machine__change_to_standby_state(); + ds_change_to_state(kdevice_state_standby); } else if (BoardBattery_get_charging_state()) { // BoardLight_setGreenLightEffect(kLightEffect_close); - state_machine__change_to_standby_state(); + ds_change_to_state(kdevice_state_standby); } - // ZLOGI("bt:%d plod:%d has_disc:%d state:%d", zdatachannel_is_connected(), BoardEcgSensor_plod_get_connected_state_after_filter(), - // plod_state_has_disconnected_ms(), ds_cur_state_haspassed_ms()); } /******************************************************************************* * 保持静止页面 * *******************************************************************************/ else if (ds_now_state() == kdevice_state_keep_still) { - if (!BoardEcgSensor_plod_get_connected_state_after_filter()) { + if (!hwss_lead_get_state_connected_state()) { // 如果用户未保持静止,切换到首页 - state_machine__change_to_home_state(); + ds_change_to_state(kdevice_state_home); hwss_stop_capture(); } else { /******************************************************************************* @@ -410,7 +354,7 @@ static void app_event_listener(void* p_event_data, uint16_t event_size) { 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()); - state_machine__change_to_home_state(); + ds_change_to_state(kdevice_state_home); ble_cmder_report_sample_finish_event(); } } @@ -419,9 +363,9 @@ static void app_event_listener(void* p_event_data, uint16_t event_size) { *******************************************************************************/ else if (ds_now_state() == kdevice_state_sampling_error) { if ((ds_cur_state_haspassed_ms() >= 3000) || // - (ds_cur_state_haspassed_ms() >= 1000 && BoardEcgSensor_plod_get_connected_state_after_filter())) { + (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()); - state_machine__change_to_home_state(); + ds_change_to_state(kdevice_state_home); ble_cmder_report_sample_finish_event(); } } @@ -432,45 +376,17 @@ static void app_event_listener(void* p_event_data, uint16_t event_size) { void one_conduction_main() { ZLOGI("one_conduction_main"); + AppEvent_regListener(app_event_listener); app_board_init(); - ads129x_init(); - BoardBeepCtrl_init(); - AppEvent_regListener(app_event_listener); - - board_power_mgr_init(); - board_power_mgr_main_power_supply_set(true); - - BoardEcgSensor_init(); - - // BoardBattery_selfTest(); - // BoardLight_selftest(); - - BoardBattery_init(); - BoardEcgSensor_init(); BoardLight_Init(); - BoardBattery_load(); - - // power_on(); -#if 0 - if (BoardBattery_get_battery_level() < APP_WORK_BATTERY_LEVEL) { - BoardLight_load(); - BoardLight_blockFlash(3, 100); - BoardLight_unload(); - // 系统进入深度睡眠,进入深度睡眠前,使能唤醒引脚 - app_timer_pause(); - nrf_delay_ms(LOW_BATTERY_REMINDER_DELAY_MS); - ENTER_DEEP_SLEEP(); - } -#endif - - // wd_init(); - - 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)); + /** + * @brief 服务初始化 + */ + hwss_init(); + ds_init(on_state_change); - state_machine__change_to_standby_state(); - // state_machine__change_to_poweroning_state(); + ds_change_to_state(kdevice_state_poweron); znordic_loop(); } diff --git a/app/src/service/ble_cmd_processer/ble_cmd_process_service.c b/app/src/service/ble_cmd_processer/ble_cmd_process_service.c index f6a97ff..5dd5433 100644 --- a/app/src/service/ble_cmd_processer/ble_cmd_process_service.c +++ b/app/src/service/ble_cmd_processer/ble_cmd_process_service.c @@ -310,7 +310,7 @@ void ble_cmder_process_rx(uint8_t* rx, int len) { 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 = (!BoardEcgSensor_plod_get_connected_state()); + receipt->drop_state0 = (0); receipt->drop_state1 = 0x00; receipt->device_state0.sampling_state = (ds_now_state() == kdevice_state_sampling); receipt->device_state0.report_state = m_realtime_report_state; diff --git a/app/src/service/heart_wave_sample_service/heart_wave_sample_service.c b/app/src/service/heart_wave_sample_service/heart_wave_sample_service.c index 766c887..b74ddd9 100644 --- a/app/src/service/heart_wave_sample_service/heart_wave_sample_service.c +++ b/app/src/service/heart_wave_sample_service/heart_wave_sample_service.c @@ -17,50 +17,12 @@ typedef enum { static capture_state_t m_prepare_capture_state = kidle; static uint32_t m_start_capture_tp; -static nrfx_timer_t m_timer = NRFX_TIMER_INSTANCE(HEART_WAVE_SAMPLE_TMR_INSTANCE); - -void nrfx_timer_event_handler(nrf_timer_event_t event_type, void* p_context) { // - static uint16_t val = 25; - val++; - if (val > 75) val = 25; - - if (m_prepare_capture_state == kprepare) { - hwsd_pre_processer_process(val); - } else if (m_prepare_capture_state == kcapture) { - hwsd_pre_processer_process(val); - hwsd_mgr_push_one_frame(hwsd_pre_processer_get_storage_data()); - } -} - -void hwss_init(void) { - static bool m_timer_inited = false; - if (!m_timer_inited) { - /** - * @brief 初始化定时器 - */ - static nrfx_timer_config_t timer_cfg = { - .frequency = NRF_TIMER_FREQ_500kHz, - .mode = NRF_TIMER_MODE_TIMER, - .bit_width = NRF_TIMER_BIT_WIDTH_24, - .p_context = NULL, - .interrupt_priority = NRFX_TIMER_DEFAULT_CONFIG_IRQ_PRIORITY, - }; - - // nrfx_timer_init(&m_timer, &timer_cfg, nrfx_timer_event_handler); - ZERROR_CHECK(nrfx_timer_init(&m_timer, &timer_cfg, nrfx_timer_event_handler)); - uint32_t timer_ticks = nrfx_timer_ms_to_ticks(&m_timer, 2); // - ZASSERT(SAMPLE_RATE == 500); - nrfx_timer_extended_compare(&m_timer, NRF_TIMER_CC_CHANNEL0, timer_ticks, NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK, true); - m_timer_inited = true; - } -} -void hwss_uninit(void) { nrfx_timer_disable(&m_timer); } +void hwss_init(void) {} void hwss_start_prepare_capture(void) { m_start_capture_tp = znordic_getpower_on_s(); m_prepare_capture_state = kprepare; hwsd_pre_processer_init(); hwsd_mgr_reset_buffer(); - nrfx_timer_enable(&m_timer); } void hwss_start_capture(void) { m_start_capture_tp = znordic_getpower_on_s(); @@ -68,7 +30,6 @@ void hwss_start_capture(void) { } void hwss_stop_capture(void) { m_prepare_capture_state = kidle; - nrfx_timer_disable(&m_timer); hwsd_mgr_reset_buffer(); } @@ -82,3 +43,5 @@ float hwss_read_heart_rate(void) { // return 0; } int hwss_has_captured_time_ms() { return (znordic_getpower_on_s() - m_start_capture_tp) * 1000; } + +bool hwss_lead_get_state_connected_state() { return true; } diff --git a/app/src/service/heart_wave_sample_service/heart_wave_sample_service.h b/app/src/service/heart_wave_sample_service/heart_wave_sample_service.h index d1df979..561ea7d 100644 --- a/app/src/service/heart_wave_sample_service/heart_wave_sample_service.h +++ b/app/src/service/heart_wave_sample_service/heart_wave_sample_service.h @@ -1,12 +1,12 @@ #pragma once #include +#include // 每256个字节触发一次回调 typedef void (*heart_wave_sample_service_callback_t)(uint16_t *p_data, uint16_t length); void hwss_init(void); -void hwss_uninit(void); void hwss_start_capture(void); void hwss_stop_capture(void); @@ -14,4 +14,8 @@ void hwss_stop_capture(void); float hwss_read_val(void); float hwss_read_heart_rate(void); int hwss_has_captured_time_ms(); -void hwss_start_prepare_capture(void); \ No newline at end of file +void hwss_start_prepare_capture(void); + + + +bool hwss_lead_get_state_connected_state(); \ No newline at end of file