13 changed files with 412 additions and 619 deletions
-
3.vscode/settings.json
-
186app/app.uvoptx
-
20app/app.uvprojx
-
6app/src/board/board.h
-
12app/src/board/board_ecg_sensor.c
-
6app/src/device_state.h
-
108app/src/heart_ware_sample_data_mgr.c
-
9app/src/heart_ware_sample_data_mgr.h
-
107app/src/heart_wave_sample_data_pre_process.c
-
9app/src/heart_wave_sample_data_pre_process.h
-
221app/src/heart_wave_sample_service.c
-
313app/src/heart_wave_sample_service.c.bak
-
23app/src/one_conduction_main.c
@ -0,0 +1,108 @@ |
|||||
|
#include "app_event.h" |
||||
|
#include "app_event_distribute.h" |
||||
|
#include "basic/qrs_time_domain_zh.h" |
||||
|
#include "board/board_ecg_sensor.h" |
||||
|
#include "heart_wave_sample_service.h" |
||||
|
#include "nrfx_timer.h" |
||||
|
|
||||
|
static uint32_t m_frame_index = 0; // 帧绝对序号 |
||||
|
/*********************************************************************************************************************** |
||||
|
* ab buffer * |
||||
|
***********************************************************************************************************************/ |
||||
|
#define FRAME_BUFFER_SIZE (256 / sizeof(one_frame_t)) |
||||
|
|
||||
|
static one_frame_t m_capture_buffer_a[FRAME_BUFFER_SIZE]; |
||||
|
static one_frame_t m_capture_buffer_b[FRAME_BUFFER_SIZE]; |
||||
|
static one_frame_t* m_capture_buffer; |
||||
|
static one_frame_t m_capture_buffer_index = 0; |
||||
|
|
||||
|
static void eeprom_cache_buffer_swap() { |
||||
|
if (m_capture_buffer == NULL) { |
||||
|
m_capture_buffer = m_capture_buffer_a; |
||||
|
m_capture_buffer_index = 0; |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
if (m_capture_buffer == m_capture_buffer_a) { |
||||
|
m_capture_buffer = m_capture_buffer_b; |
||||
|
} else { |
||||
|
m_capture_buffer = m_capture_buffer_a; |
||||
|
} |
||||
|
m_capture_buffer_index = 0; |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
/*********************************************************************************************************************** |
||||
|
* littlebuffer * |
||||
|
***********************************************************************************************************************/ |
||||
|
static one_frame_t m_prepare_data_cache[LITTLE_DATA_BLOCK_FRAME_NUM]; |
||||
|
static uint32_t m_prepare_data_cache_index; |
||||
|
|
||||
|
static inline void preview_data_cache_push_data(one_frame_t data) { |
||||
|
if (m_prepare_data_cache_index >= LITTLE_DATA_BLOCK_FRAME_NUM) { |
||||
|
return; |
||||
|
} |
||||
|
m_prepare_data_cache[m_prepare_data_cache_index] = data; |
||||
|
m_prepare_data_cache_index++; |
||||
|
} |
||||
|
|
||||
|
static inline bool preview_data_cache_is_full(void) { |
||||
|
if (m_prepare_data_cache_index >= LITTLE_DATA_BLOCK_FRAME_NUM) { |
||||
|
return true; |
||||
|
} |
||||
|
return false; |
||||
|
} |
||||
|
static inline void preview_data_cache_clear(void) { m_prepare_data_cache_index = 0; } |
||||
|
static inline void preview_data_trigger_event() { |
||||
|
static app_event_t event; |
||||
|
event.eventType = kevent_capture_little_data_block_event; |
||||
|
for (uint32_t i = 0; i < LITTLE_DATA_BLOCK_FRAME_NUM; i++) { |
||||
|
event.val.little_data_block.data[i] = m_prepare_data_cache[i]; |
||||
|
} |
||||
|
event.val.little_data_block.frameIndex = m_frame_index - LITTLE_DATA_BLOCK_FRAME_NUM; |
||||
|
AppEvent_pushEvent(&event); |
||||
|
} |
||||
|
|
||||
|
/*********************************************************************************************************************** |
||||
|
* EXT * |
||||
|
***********************************************************************************************************************/ |
||||
|
|
||||
|
void hwsd_mgr_push_one_frame(one_frame_t data) { |
||||
|
m_frame_index++; |
||||
|
|
||||
|
/*********************************************************************************************************************** |
||||
|
* EEPROM数据采样存储 * |
||||
|
***********************************************************************************************************************/ |
||||
|
if (m_capture_buffer == NULL) eeprom_cache_buffer_swap(); |
||||
|
|
||||
|
if (m_capture_buffer_index < FRAME_BUFFER_SIZE) { |
||||
|
m_capture_buffer[m_capture_buffer_index++] = data; |
||||
|
} |
||||
|
|
||||
|
if (m_capture_buffer_index == FRAME_BUFFER_SIZE) { |
||||
|
app_event_t evt; |
||||
|
evt.eventType = kevent_capture_256data_event; |
||||
|
evt.val.capture_data_cache = (uint8_t*)m_capture_buffer; |
||||
|
eeprom_cache_buffer_swap(); |
||||
|
AppEvent_pushEvent(&evt); |
||||
|
} |
||||
|
|
||||
|
/******************************************************************************* |
||||
|
* 实时采样数据事件上报 * |
||||
|
*******************************************************************************/ |
||||
|
/** |
||||
|
* @brief 缓存数据,并触发小数据块事件 |
||||
|
*/ |
||||
|
preview_data_cache_push_data(data); |
||||
|
if (preview_data_cache_is_full()) { |
||||
|
preview_data_trigger_event(); |
||||
|
preview_data_cache_clear(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
void hwsd_mgr_reset_buffer(){ |
||||
|
m_frame_index = 0; |
||||
|
m_capture_buffer = NULL; |
||||
|
m_capture_buffer_index = 0; |
||||
|
preview_data_cache_clear(); |
||||
|
} |
@ -0,0 +1,9 @@ |
|||||
|
#pragma once |
||||
|
#include <stdint.h> |
||||
|
|
||||
|
#include "app_event.h" |
||||
|
#include "app_event_distribute.h" |
||||
|
#include "nrfx_timer.h" |
||||
|
|
||||
|
void hwsd_mgr_push_one_frame(one_frame_t data); |
||||
|
void hwsd_mgr_reset_buffer(); |
@ -0,0 +1,107 @@ |
|||||
|
#include "heart_wave_sample_data_pre_process.h" |
||||
|
|
||||
|
/*********************************************************************************************************************** |
||||
|
* ALGO * |
||||
|
***********************************************************************************************************************/ |
||||
|
|
||||
|
typedef struct { |
||||
|
float value; |
||||
|
float efectiveFactor; |
||||
|
} filter_t; |
||||
|
|
||||
|
typedef struct { |
||||
|
float coef[2]; |
||||
|
float v_out[2]; |
||||
|
} LPFilter; |
||||
|
#define PI 3.14159265358979323846f |
||||
|
|
||||
|
static float Filter(filter_t* filter, float newInput) { |
||||
|
float newv = ((float)filter->value * (1.0f - filter->efectiveFactor)) + ((float)newInput * filter->efectiveFactor); |
||||
|
filter->value = newv; |
||||
|
return newv; |
||||
|
} |
||||
|
|
||||
|
void LPFilter_Init(LPFilter* filter, float cutoffFreqHz, float sampleTimeS) { |
||||
|
float RC = 0.0; |
||||
|
RC = 1.0 / (2 * PI * cutoffFreqHz); |
||||
|
filter->coef[0] = sampleTimeS / (sampleTimeS + RC); |
||||
|
filter->coef[1] = RC / (sampleTimeS + RC); |
||||
|
|
||||
|
filter->v_out[0] = 0.0; |
||||
|
filter->v_out[1] = 0.0; |
||||
|
} |
||||
|
|
||||
|
float LPFilter_Update(LPFilter* filter, float v_in) { |
||||
|
filter->v_out[1] = filter->v_out[0]; |
||||
|
filter->v_out[0] = (filter->coef[0] * v_in) + (filter->coef[1] * filter->v_out[1]); |
||||
|
|
||||
|
return (filter->v_out[0]); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* @brief 放大显示数据 |
||||
|
* |
||||
|
* @param val |
||||
|
* @param valcener |
||||
|
* @param amp |
||||
|
* @return float |
||||
|
*/ |
||||
|
static float amp_display_val(uint16_t val, uint16_t valcener, float amp) { |
||||
|
float valf = (float)val - valcener; |
||||
|
valf = valf * amp; |
||||
|
valf += valcener; |
||||
|
|
||||
|
if (valf >= 100) { |
||||
|
valf = 100; |
||||
|
} |
||||
|
|
||||
|
if (valf <= 0) { |
||||
|
valf = 0; |
||||
|
} |
||||
|
return valf; |
||||
|
} |
||||
|
|
||||
|
uint16_t getRecommendedMagnification() { |
||||
|
// return 0; |
||||
|
uint16_t max = QRS_getMaxValueLastVal(); |
||||
|
if (max == 0) { |
||||
|
return 15; |
||||
|
} |
||||
|
// 3750.0f |
||||
|
if (max <= (3750 / 2)) { |
||||
|
return 15; |
||||
|
} |
||||
|
float af = (3750 / 2) / (max - 3750 / 2); |
||||
|
if (af > 15) { |
||||
|
return 15; |
||||
|
} |
||||
|
return af; |
||||
|
} |
||||
|
|
||||
|
/*********************************************************************************************************************** |
||||
|
* VAR * |
||||
|
***********************************************************************************************************************/ |
||||
|
static one_frame_t m_datacache; |
||||
|
static one_frame_t m_displaydata; |
||||
|
filter_t m_filter = {0, 0.8}; |
||||
|
LPFilter m_lpfilter_01; |
||||
|
LPFilter m_lpfilter_02; |
||||
|
|
||||
|
void hwsd_pre_processer_init() { QRS_resetBuf(); } |
||||
|
void hwsd_pre_processer_process(one_frame_t framdata) { // |
||||
|
m_datacache = framdata; |
||||
|
m_displaydata = framdata; |
||||
|
/******************************************************************************* |
||||
|
* 显示数据计算并赋值 * |
||||
|
*******************************************************************************/ |
||||
|
// QRS_getMaxValueLastVal(); |
||||
|
// float lowpassf_val = LPFilter_Update(&m_lpfilter_01, framdata); |
||||
|
// QRS_processData(lowpassf_val); |
||||
|
// float val_af100 = (float)lowpassf_val / 3750.0f * 100; // 参考电压为3.6v,但信号范围为3.3v |
||||
|
// val_af100 = amp_val(val_af100, 50, getRecommendedMagnification()); |
||||
|
// val_af100 = LPFilter_Update(&m_lpfilter_02, val_af100); |
||||
|
// m_displaydata = m_datacache; |
||||
|
} |
||||
|
|
||||
|
uint16_t hwsd_pre_processer_get_display_data() { return m_displaydata; } |
||||
|
one_frame_t hwsd_pre_processer_get_storage_data() { return m_datacache; } |
@ -0,0 +1,9 @@ |
|||||
|
#pragma once |
||||
|
#include <stdint.h> |
||||
|
|
||||
|
#include "app_event.h" |
||||
|
|
||||
|
void hwsd_pre_processer_init(); |
||||
|
void hwsd_pre_processer_process(one_frame_t framdata); |
||||
|
one_frame_t hwsd_pre_processer_get_display_data(); |
||||
|
one_frame_t hwsd_pre_processer_get_storage_data(); |
@ -1,313 +0,0 @@ |
|||||
#include "heart_wave_sample_service.h" |
|
||||
|
|
||||
#include "app_event.h" |
|
||||
#include "app_event_distribute.h" |
|
||||
#include "basic/FIR.h" |
|
||||
#include "basic/HC_Chen_detect.h" |
|
||||
#include "basic/So_Chen_detect.h" |
|
||||
#include "basic/adaptive_algorithm.h" |
|
||||
#include "basic/Pan_Tompkins_detect.h" |
|
||||
#include "board/board_ecg_sensor.h" |
|
||||
#include "nrfx_timer.h" |
|
||||
|
|
||||
|
|
||||
static uint16_t m_capture_buffer_a[128]; |
|
||||
static uint16_t m_capture_buffer_b[128]; |
|
||||
|
|
||||
static uint16_t* m_capture_buffer; |
|
||||
static uint16_t m_capture_buffer_index = 0; |
|
||||
|
|
||||
volatile static float m_sensor_display_data = 0; // 0->100 |
|
||||
static uint32_t m_start_capture_tp; |
|
||||
static uint32_t m_frame_index = 0; |
|
||||
|
|
||||
static one_frame_data_t m_sensor_little_frame_cache[LITTLE_DATA_BLOCK_FRAME_NUM]; |
|
||||
static uint32_t m_little_frame_index; |
|
||||
static bool m_prestart_flag; |
|
||||
|
|
||||
static nrfx_timer_t m_timer = NRFX_TIMER_INSTANCE(HEART_WAVE_SAMPLE_TMR_INSTANCE); |
|
||||
|
|
||||
typedef struct { |
|
||||
int heartSignalCnt; |
|
||||
int heart_rate; |
|
||||
uint32_t last_qrs_point; |
|
||||
uint32_t time_cnt; |
|
||||
uint32_t origin_time_cnt; |
|
||||
|
|
||||
uint32_t index; |
|
||||
float index_f; |
|
||||
} QRS_t; |
|
||||
|
|
||||
QRS_t m_qrs; |
|
||||
|
|
||||
void QRS_reset() { |
|
||||
m_qrs.heartSignalCnt = 0; |
|
||||
m_qrs.heart_rate = 0; |
|
||||
m_qrs.time_cnt = 0; |
|
||||
m_qrs.index = 0; |
|
||||
m_qrs.index_f = 0; |
|
||||
FIR_reset_buffer(); |
|
||||
} |
|
||||
|
|
||||
void QRS_process(float value) { |
|
||||
bool isPeak = false; |
|
||||
#if 1 |
|
||||
float result = value; |
|
||||
SignalPoint sp; |
|
||||
sp.value = result; |
|
||||
sp.index = m_qrs.time_cnt; |
|
||||
SignalPoint peak = So_Chen_detect(sp, SAMPLING_RATE * 0.25f, 4, 16); |
|
||||
if (peak.index != -1) { |
|
||||
isPeak = true; |
|
||||
} |
|
||||
#endif |
|
||||
|
|
||||
#if 0 |
|
||||
isPeak = HC_Chen_detect(value); |
|
||||
#endif |
|
||||
|
|
||||
#if 0 |
|
||||
static const float CV_LIMIT = 50.0f; |
|
||||
static const float THRESHOLD_FACTOR = 3.0f; |
|
||||
double mean = CalculateMean(value); |
|
||||
double rms = CalculateRootMeanSquare(value); |
|
||||
double cv = CalculateCoefficientOfVariation(value); |
|
||||
double threshold; |
|
||||
if (cv > CV_LIMIT) { |
|
||||
threshold = rms; |
|
||||
} else { |
|
||||
threshold = rms * (cv / 100.0f) * THRESHOLD_FACTOR; |
|
||||
} |
|
||||
bool is_peak; |
|
||||
SignalPoint result; |
|
||||
result = PeakDetect(value, m_qrs.time_cnt, threshold, &is_peak); |
|
||||
if (result.index != -1) { |
|
||||
if (is_peak) { |
|
||||
isPeak = true; |
|
||||
} |
|
||||
} |
|
||||
#endif |
|
||||
|
|
||||
#if 0 |
|
||||
|
|
||||
|
|
||||
double result = value; |
|
||||
double bandpass; |
|
||||
double integral; |
|
||||
double square; |
|
||||
|
|
||||
bandpass = result; |
|
||||
result = Derivative(result); |
|
||||
result = Squar(result); |
|
||||
square = result; |
|
||||
result = MovingWindowIntegral(result); |
|
||||
integral = result; |
|
||||
|
|
||||
SignalPoint peak = ThresholdCalculate(m_qrs.time_cnt,value,bandpass,square,integral); |
|
||||
|
|
||||
if(peak.index != -1){ |
|
||||
isPeak = true; |
|
||||
} |
|
||||
|
|
||||
#endif |
|
||||
|
|
||||
// if (isPeak) { |
|
||||
// uint32_t time_diff = m_qrs.time_cnt - m_qrs.last_qrs_point; |
|
||||
// m_qrs.last_qrs_point = m_qrs.time_cnt; |
|
||||
// m_qrs.heartSignalCnt++; |
|
||||
// // m_qrs.heart_rate = m_qrs.heartSignalCnt; |
|
||||
// if (m_qrs.last_qrs_point != 0) { |
|
||||
// m_qrs.heart_rate = 60 * (1 / (time_diff * 1.0 / SAMPLING_RATE)); |
|
||||
// } |
|
||||
// } |
|
||||
|
|
||||
m_qrs.time_cnt++; |
|
||||
} |
|
||||
|
|
||||
static const void compute_heart_rate(float sample_data) { |
|
||||
ZASSERT(SAMPLE_RATE == 500); |
|
||||
m_qrs.index_f = m_frame_index / 500.0 * 360; |
|
||||
if ((m_qrs.index_f - m_qrs.index) > 1) { |
|
||||
m_qrs.index = m_qrs.index_f; |
|
||||
float val = sample_data; |
|
||||
QRS_process(FIR_filter(val)); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
static void swap_buffer() { |
|
||||
if (m_capture_buffer == NULL) { |
|
||||
m_capture_buffer = m_capture_buffer_a; |
|
||||
m_capture_buffer_index = 0; |
|
||||
return; |
|
||||
} |
|
||||
|
|
||||
if (m_capture_buffer == m_capture_buffer_a) { |
|
||||
m_capture_buffer = m_capture_buffer_b; |
|
||||
} else { |
|
||||
m_capture_buffer = m_capture_buffer_a; |
|
||||
} |
|
||||
m_capture_buffer_index = 0; |
|
||||
return; |
|
||||
} |
|
||||
static float amp_val(uint16_t val, uint16_t valcener, float amp) { |
|
||||
float valf = (float)val - valcener; |
|
||||
valf = valf * amp; |
|
||||
valf += valcener; |
|
||||
|
|
||||
if (valf >= 100) { |
|
||||
valf = 100; |
|
||||
} |
|
||||
|
|
||||
if (valf <= 0) { |
|
||||
valf = 0; |
|
||||
} |
|
||||
return valf; |
|
||||
} |
|
||||
|
|
||||
typedef struct { |
|
||||
float value; |
|
||||
float efectiveFactor; |
|
||||
} filter_t; |
|
||||
|
|
||||
filter_t m_filter = {0, 0.8}; |
|
||||
|
|
||||
static float Filter(filter_t* filter, float newInput) { |
|
||||
float newv = ((float)filter->value * (1.0f - filter->efectiveFactor)) + ((float)newInput * filter->efectiveFactor); |
|
||||
filter->value = newv; |
|
||||
return newv; |
|
||||
} |
|
||||
|
|
||||
/******************************************************************************* |
|
||||
* 小包数据上报 * |
|
||||
*******************************************************************************/ |
|
||||
static inline void prvf_little_block_cache_push_one_frame(uint16_t data) { |
|
||||
if (m_little_frame_index >= LITTLE_DATA_BLOCK_FRAME_NUM) { |
|
||||
return; |
|
||||
} |
|
||||
m_sensor_little_frame_cache[m_little_frame_index].data = data; |
|
||||
m_little_frame_index++; |
|
||||
} |
|
||||
|
|
||||
static inline bool prvf_light_block_cache_is_full(void) { |
|
||||
if (m_little_frame_index >= LITTLE_DATA_BLOCK_FRAME_NUM) { |
|
||||
return true; |
|
||||
} |
|
||||
return false; |
|
||||
} |
|
||||
static inline void prvf_light_block_cache_clear(void) { m_little_frame_index = 0; } |
|
||||
static inline void prvf_light_block_trigger_event() { |
|
||||
static app_event_t event; |
|
||||
event.eventType = kevent_capture_little_data_block_event; |
|
||||
for (uint32_t i = 0; i < LITTLE_DATA_BLOCK_FRAME_NUM; i++) { |
|
||||
event.val.little_data_block.data[i].data = m_sensor_little_frame_cache[i].data; |
|
||||
} |
|
||||
event.val.little_data_block.frameIndex = m_frame_index - LITTLE_DATA_BLOCK_FRAME_NUM; |
|
||||
// ZLOGI("%d", event.val.little_data_block.frameIndex); |
|
||||
AppEvent_pushEvent(&event); |
|
||||
} |
|
||||
|
|
||||
void nrfx_timer_event_handler(nrf_timer_event_t event_type, void* p_context) { // |
|
||||
uint16_t val = BoardEcgSensor_plod_get_ecg_val(); // 12bit |
|
||||
float val_af100 = (float)val / 4096.0f * 100; |
|
||||
if (m_prestart_flag) { |
|
||||
compute_heart_rate(val_af100); |
|
||||
return; |
|
||||
} else { |
|
||||
compute_heart_rate(val_af100); |
|
||||
} |
|
||||
|
|
||||
/******************************************************************************* |
|
||||
* 显示数据计算并赋值 * |
|
||||
*******************************************************************************/ |
|
||||
|
|
||||
m_frame_index++; |
|
||||
val_af100 = amp_val(val_af100, 45, 3.5f); |
|
||||
val_af100 = Filter(&m_filter, val_af100); |
|
||||
m_sensor_display_data = val_af100; |
|
||||
|
|
||||
/******************************************************************************* |
|
||||
* 采样数据缓存 * |
|
||||
*******************************************************************************/ |
|
||||
if (m_capture_buffer == NULL) { |
|
||||
swap_buffer(); |
|
||||
} |
|
||||
|
|
||||
if (m_capture_buffer_index < 128) { |
|
||||
m_capture_buffer[m_capture_buffer_index++] = val; |
|
||||
} |
|
||||
|
|
||||
if (m_capture_buffer_index == 128) { |
|
||||
app_event_t evt; |
|
||||
evt.eventType = kevent_capture_256data_event; |
|
||||
evt.val.capture_data_cache = (uint8_t*)m_capture_buffer; |
|
||||
swap_buffer(); |
|
||||
AppEvent_pushEvent(&evt); |
|
||||
} |
|
||||
|
|
||||
/******************************************************************************* |
|
||||
* 实时采样数据事件上报 * |
|
||||
*******************************************************************************/ |
|
||||
/** |
|
||||
* @brief 缓存数据,并触发小数据块事件 |
|
||||
*/ |
|
||||
prvf_little_block_cache_push_one_frame(val); |
|
||||
if (prvf_light_block_cache_is_full()) { |
|
||||
prvf_light_block_trigger_event(); |
|
||||
prvf_light_block_cache_clear(); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
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_pre_start_capture(void) { |
|
||||
m_start_capture_tp = znordic_getpower_on_s(); |
|
||||
swap_buffer(); |
|
||||
m_frame_index = 0; |
|
||||
|
|
||||
QRS_reset(); |
|
||||
|
|
||||
prvf_light_block_cache_clear(); |
|
||||
nrfx_timer_enable(&m_timer); |
|
||||
m_prestart_flag = true; |
|
||||
} |
|
||||
|
|
||||
void hwss_start_capture(void) { m_prestart_flag = false; } |
|
||||
void hwss_stop_capture(void) { |
|
||||
nrfx_timer_disable(&m_timer); |
|
||||
m_frame_index = 0; |
|
||||
prvf_light_block_cache_clear(); |
|
||||
} |
|
||||
|
|
||||
float hwss_read_val(void) { |
|
||||
__disable_irq(); |
|
||||
float val = m_sensor_display_data; |
|
||||
__enable_irq(); |
|
||||
return val; |
|
||||
} |
|
||||
float hwss_read_heart_rate(void) { // |
|
||||
return m_qrs.heart_rate; |
|
||||
} |
|
||||
|
|
||||
int hwss_has_captured_time_ms() { return (znordic_getpower_on_s() - m_start_capture_tp) * 1000; } |
|
Write
Preview
Loading…
Cancel
Save
Reference in new issue