From e4797834d2bb2d8a91914b4a50b674f7fc0c4e71 Mon Sep 17 00:00:00 2001 From: zhaohe Date: Sat, 4 May 2024 10:14:06 +0800 Subject: [PATCH] update --- app/src/board/ads129x/ads129x.c | 45 +-- .../ble_cmd_processer/ble_cmd_process_service.c | 36 +- .../heart_wave_sample_service.h | 11 +- bak/FIR.c | 38 --- bak/FIR.h | 14 - bak/HC_Chen_detect.c | 128 ------- bak/HC_Chen_detect.h | 53 --- bak/Pan_Tompkins_detect.c | 373 --------------------- bak/Pan_Tompkins_detect.h | 21 -- bak/QRS.h | 30 -- bak/So_Chen_detect.c | 93 ----- bak/So_Chen_detect.h | 42 --- bak/adaptive_algorithm.c | 100 ------ bak/adaptive_algorithm.h | 41 --- bak/qrs_time_domain_zh.c | 231 ------------- bak/qrs_time_domain_zh.h | 19 -- bak/zapp_timer.c | 29 -- bak/zapp_timer.h | 17 - ify_hrs_protocol | 2 +- 19 files changed, 27 insertions(+), 1296 deletions(-) delete mode 100644 bak/FIR.c delete mode 100644 bak/FIR.h delete mode 100644 bak/HC_Chen_detect.c delete mode 100644 bak/HC_Chen_detect.h delete mode 100644 bak/Pan_Tompkins_detect.c delete mode 100644 bak/Pan_Tompkins_detect.h delete mode 100644 bak/QRS.h delete mode 100644 bak/So_Chen_detect.c delete mode 100644 bak/So_Chen_detect.h delete mode 100644 bak/adaptive_algorithm.c delete mode 100644 bak/adaptive_algorithm.h delete mode 100644 bak/qrs_time_domain_zh.c delete mode 100644 bak/qrs_time_domain_zh.h delete mode 100644 bak/zapp_timer.c delete mode 100644 bak/zapp_timer.h diff --git a/app/src/board/ads129x/ads129x.c b/app/src/board/ads129x/ads129x.c index 5f89505..a0d613a 100644 --- a/app/src/board/ads129x/ads129x.c +++ b/app/src/board/ads129x/ads129x.c @@ -221,51 +221,10 @@ uint8_t ads129x_init(ads129x_cfg_t* cfg) { nrf_gpio_pin_set(ads129x_cfg->pwdnpin); return 0; } -#if 0 -uint8_t ads129x_start_capture(bool test) { - ads129x_send_cmd(ADS129X_COMMAND_SDATAC); /* ½øÈëÍ£Ö¹Á¬Ðø¶Áģʽ */ - port_delay_ms(10); - - static ads129x_regs_t regcache; - ads129x_readback_regs(®cache); - ads129x_dump_regs(®cache); - - regcache.cfg1 = 0x02; - regcache.cfg2 = 0xE0; - regcache.loff = 0xF0; - regcache.ch1set = 0x00; - regcache.ch2set = 0x00; - regcache.rld_sens = 0x20; - regcache.loff_sens = 0x03; - - /* µ¼ÁªÍÑÂä±È½ÏÆ÷¿ª£¬ÄÚ²¿2.42v²Î¿¼µçѹ */ - regcache.cfg2 = ADS129X_SET_BITS(regcache.cfg2, ADS129X_PDB_LOFF_COMP, ADS129X_PDB_LOFF_COMP_ON); - regcache.cfg2 = ADS129X_SET_BITS(regcache.cfg2, ADS129X_PDB_REFBUF, ADS129X_PDB_REFBUF_ON); - regcache.cfg2 = ADS129X_SET_BITS(regcache.cfg2, ADS129X_VREF_4V, ADS129X_VREF_2420MV); - - /* ͨµÀ¶þµ¼ÁªÍÑÂä¼ì²â¹¦ÄÜ¿ª */ - regcache.loff_sens = ADS129X_SET_BITS(regcache.loff_sens, ADS129X_LOFF2N, ADS129X_LOFF2N_ON); - regcache.loff_sens = ADS129X_SET_BITS(regcache.loff_sens, ADS129X_LOFF2P, ADS129X_LOFF2P_ON); - - if (test) { - regcache.cfg2 = ADS129X_SET_BITS(regcache.cfg2, ADS129X_INT_TEST, ADS129X_INT_TEST_ON); - regcache.cfg2 = ADS129X_SET_BITS(regcache.cfg2, ADS129X_INT_FREQ, ADS129X_INT_FREQ_AC); - regcache.ch1set = ADS129X_SET_BITS(regcache.ch1set, ADS129X_MUXx, ADS129X_CHx_INPUT_TEST); - regcache.ch2set = ADS129X_SET_BITS(regcache.ch2set, ADS129X_MUXx, ADS129X_CHx_INPUT_TEST); - } - - ads129x_write_regs(®cache); - - port_delay_ms(10); - ads129x_send_cmd(ADS129X_COMMAND_START); /* ·¢ËÍ¿ªÊ¼Êý¾Ýת»»£¨µÈЧÓÚÀ­¸ßSTARTÒý½Å£© */ - port_delay_ms(10); - - return 0; -} -#endif uint8_t ads129x_read_reg(uint8_t add) { return ads129x_rw_reg(ADS129X_COMMAND_RREG | add, 0); } -void ads129x_write_reg(uint8_t add, uint8_t data) { + +void ads129x_write_reg(uint8_t add, uint8_t data) { ZLOGI("ads129x_write_reg %x %x", add, data); static ads129x_regs_t regcache; ads129x_readback_regs(®cache); 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 46c4cc3..903749c 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 @@ -478,24 +478,24 @@ void ble_cmder_process_rx(uint8_t* rx, int len) { // void hwss_subic_write_reg(uint8_t addr, uint8_t val); // uint8_t hwss_subic_read_reg(uint8_t addr); - else if (cmd == ify_hrs_test_cmd_start_capture) { - hwss_start_prepare_capture(); - hwss_start_capture(); - send_success_receipt(rxheader, 0); - } else if (cmd == ify_hrs_test_cmd_stop_capture) { - hwss_stop_capture(); - send_success_receipt(rxheader, 0); - } else if (cmd == ify_hrs_test_cmd_read_reg) { - uint8_t regadd = rxheader->data[0]; - uint8_t regval = hwss_subic_read_reg(regadd); - txheader->data[0] = regval; - send_success_receipt(rxheader, 1); - } else if (cmd == ify_hrs_test_cmd_write_reg) { - uint8_t regadd = rxheader->data[0]; - uint8_t regval = rxheader->data[1]; - hwss_subic_write_reg(regadd, regval); - send_success_receipt(rxheader, 0); - } + // else if (cmd == ify_hrs_test_cmd_start_capture) { + // hwss_start_prepare_capture(); + // hwss_start_capture(); + // send_success_receipt(rxheader, 0); + // } else if (cmd == ify_hrs_test_cmd_stop_capture) { + // hwss_stop_capture(); + // send_success_receipt(rxheader, 0); + // } else if (cmd == ify_hrs_test_cmd_read_reg) { + // uint8_t regadd = rxheader->data[0]; + // uint8_t regval = hwss_subic_read_reg(regadd); + // txheader->data[0] = regval; + // send_success_receipt(rxheader, 1); + // } else if (cmd == ify_hrs_test_cmd_write_reg) { + // uint8_t regadd = rxheader->data[0]; + // uint8_t regval = rxheader->data[1]; + // hwss_subic_write_reg(regadd, regval); + // send_success_receipt(rxheader, 0); + // } // else { send_error_receipt(rxheader, kifyhrs_ecode_cmd_not_support); 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 c71815f..1e631fb 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 @@ -7,15 +7,16 @@ typedef void (*heart_wave_sample_service_callback_t)(uint16_t *p_data, uint16_t void hwss_init(void); -void hwss_start_capture(void); -void hwss_start_prepare_capture(void); -void hwss_stop_capture(void); - +void hwss_start_capture(void); +void hwss_start_prepare_capture(void); +void hwss_stop_capture(void); void hwss_subic_write_reg(uint8_t addr, uint8_t val); uint8_t hwss_subic_read_reg(uint8_t addr); + + + float hwss_read_val(void); float hwss_read_heart_rate(void); int hwss_has_captured_time_ms(); - bool hwss_lead_get_state_connected_state(); \ No newline at end of file diff --git a/bak/FIR.c b/bak/FIR.c deleted file mode 100644 index dfcad40..0000000 --- a/bak/FIR.c +++ /dev/null @@ -1,38 +0,0 @@ -#include "FIR.h" -/*360hz 0.51Hz~8.9Hz 20190925*/ -#define taps 32 -static const float coefficients[taps] = {0.012177,0.01599,0.019905,0.02387,0.027827,0.031719,0.035487,0.039075,0.042426,0.045488,0.048212,0.050553,0.052475,0.053944,0.054937,0.055438,0.055438,0.054937,0.053944,0.052475,0.050553,0.048212,0.045488,0.042426,0.039075,0.035487,0.031719,0.027827,0.02387,0.019905,0.01599,0.012177}; - -static float buffer[taps]; -unsigned offset; - -float FIR_filter(float input) { - const float *coeff = coefficients; - const float *coeff_end = coefficients + taps; - - float *buf_val = buffer + offset; - - *buf_val = input; - float output_ = 0; - - while (buf_val >= buffer) { - output_ += *buf_val-- * *coeff++; - } - - buf_val = buffer + taps - 1; - - while (coeff < coeff_end) { - output_ += *buf_val-- * *coeff++; - } - - if (++offset >= taps) { - offset = 0; - } - - return output_; -} - -void FIR_reset_buffer() { - memset(buffer, 0, sizeof(float) * taps); - offset = 0; -} diff --git a/bak/FIR.h b/bak/FIR.h deleted file mode 100644 index f9545c5..0000000 --- a/bak/FIR.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef __FIR_H__ -#define __FIR_H__ - -#include -#include -#include -#include -#include - - -extern float FIR_filter(float); -extern void FIR_reset_buffer(); - -#endif diff --git a/bak/HC_Chen_detect.c b/bak/HC_Chen_detect.c deleted file mode 100644 index 5bfcd67..0000000 --- a/bak/HC_Chen_detect.c +++ /dev/null @@ -1,128 +0,0 @@ -#include "HC_Chen_detect.h" - -bool HC_Chen_detect(float signal) -{ - ecg_buff[ecg_buff_WR_idx++] = signal; - sample = ecg_buff_WR_idx; - ecg_buff_WR_idx %= (M+1); - - /* High pass filtering */ - if(number_iter < M){ - // first fill buffer with enough points for HP filter - hp_sum += ecg_buff[ecg_buff_RD_idx]; - hp_buff[hp_buff_WR_idx] = 0; - } - else{ - hp_sum += ecg_buff[ecg_buff_RD_idx]; - - int tmp = ecg_buff_RD_idx - M; - if(tmp < 0){ - tmp += M + 1; - } - - hp_sum -= ecg_buff[tmp]; - - float y1 = 0; - float y2 = 0; - - tmp = (ecg_buff_RD_idx - ((M+1)/2)); - if(tmp < 0){ - tmp += M + 1; - } - - y2 = ecg_buff[tmp]; - - y1 = HP_CONSTANT * hp_sum; - - hp_buff[hp_buff_WR_idx] = y2 - y1; - - } - - // done reading ECG buffer, increment position - ecg_buff_RD_idx++; - ecg_buff_RD_idx %= (M+1); - - // done writing to HP buffer, increment position - hp_buff_WR_idx++; - hp_buff_WR_idx %= (N+1); - - /* Low pass filtering */ - - // shift in new sample from high pass filter - lp_sum += hp_buff[hp_buff_RD_idx] * hp_buff[hp_buff_RD_idx]; - - if(number_iter < N){ - // first fill buffer with enough points for LP filter - next_eval_pt = 0; - } - else{ - // shift out oldest data point - int tmp = hp_buff_RD_idx - N; - if(tmp < 0){ - tmp += N+1; - } - - lp_sum -= hp_buff[tmp] * hp_buff[tmp]; - - next_eval_pt = lp_sum; - } - - // done reading HP buffer, increment position - hp_buff_RD_idx++; - hp_buff_RD_idx %= (N+1); - - /* Adapative thresholding beat detection */ - // set initial threshold - if(number_iter < window_size) { - if(next_eval_pt > treshold) { - treshold = next_eval_pt; - } - ++number_iter; - } - - // check if detection hold off period has passed - if(triggered){ - trig_time++; - - if(trig_time >= DELAY_TIME){ - triggered = false; - trig_time = 0; - } - } - - // find if we have a new max - if(next_eval_pt > win_max) win_max = next_eval_pt; - - // find if we are above adaptive threshold - if(next_eval_pt > treshold && !triggered) { - //result.push_back(true); - - last_qrs_point = sample; - - triggered = true; - return true; - } - else { - //result.push_back(false); - } - - // adjust adaptive threshold using max of signal found - // in previous window - if(win_idx++ >= window_size){ - // weighting factor for determining the contribution of - // the current peak value to the threshold adjustment - float gamma = (0.2f+0.15f)/2.0f; // 0.15~0.2 - - // forgetting factor - - // rate at which we forget old observations - float alpha = 0.01f + ( ((float) rand() / (float) RAND_MAX) * ((0.1f - 0.01f))); // 0~1 - //float alpha = 1.0f*exp(-0.00005f*(sample - last_qrs_point)); - - treshold = alpha * gamma * win_max + (1.0f - alpha) * treshold; - - // reset current window ind - win_idx = 0; - win_max = -10000000; - } - return false; -} diff --git a/bak/HC_Chen_detect.h b/bak/HC_Chen_detect.h deleted file mode 100644 index cb9fa51..0000000 --- a/bak/HC_Chen_detect.h +++ /dev/null @@ -1,53 +0,0 @@ -#ifndef __HC_CHEN__ -#define __HC_CHEN__ - -#include -#include -#include -#include -#include - - -#include "QRS.h" - - -#define M 9 -#define N 54//SAMPLING_RATE * 0.15f -static const uint32_t window_size = SAMPLING_RATE; -static const float HP_CONSTANT = ((float) 1.0f / (float) M); -// circular buffer for input ecg signal -// we need to keep a history of M + 1 samples for HP filter -static float ecg_buff[M + 1] = {0}; -static int ecg_buff_WR_idx = 0; -static int ecg_buff_RD_idx = 0; - -// circular buffer for input ecg signal -// we need to keep a history of N+1 samples for LP filter -static float hp_buff[N + 1] = {0}; -static int hp_buff_WR_idx = 0; -static int hp_buff_RD_idx = 0; - -// LP filter outputs a single point for every input point -// This goes straight to adaptive filtering for eval -static float next_eval_pt = 0; - -// running sums for HP and LP filters, values shifted in FILO -static float hp_sum = 0; -static float lp_sum = 0; - -// parameters for adaptive thresholding -static float treshold = 0; -static bool triggered = false; -static int trig_time = 0; -static float win_max = 0; -static int win_idx = 0; -static int number_iter = 0; - -static int sample = 0; -static int last_qrs_point = 0; - -static const int DELAY_TIME = 180;//window_size * 0.5f; - -extern bool HC_Chen_detect(float); - -#endif diff --git a/bak/Pan_Tompkins_detect.c b/bak/Pan_Tompkins_detect.c deleted file mode 100644 index 6caea37..0000000 --- a/bak/Pan_Tompkins_detect.c +++ /dev/null @@ -1,373 +0,0 @@ -#include "Pan_Tompkins_detect.h" - -/* y(nT) = 1.875y(nT – T) – 0.9219y(nT – 2T) + x (nT) – x(nT – 2T) */ -int TwoPoleRecursive(int data) -{ - static int xnt, xm1, xm2, ynt, ym1, ym2 = 0; - - xnt = data; - ynt = (ym1 + (ym1 >> 1) + (ym1 >> 2) + (ym1 >> 3)) + // 1.875 = 1 + 1/2 + 1/4 + 1/8 - (((ym2 >> 1) + (ym2 >> 2) + (ym2 >> 3) + (ym2 >> 5) + (ym2 >> 6)) + xnt - xm2); // 0.916 = 1 + 1/2 + 1/4 + 1/8 + 1/32 + 1/64 - xm2 = xm1; - xm1 = xnt; - xm2 = ym1; - ym2 = ym1; - ym1 = ynt; - return ynt; -} - -/* y(nT) = 2y(nT – T) – y(nT – 2T) + x(nT) – 2x(nT – 6T) + x(nT – 12T) */ -int LowPassFilter(int data) -{ - static int y1 = 0, y2 = 0, x[26], n = 12; - int y0; - - x[n] = x[n + 13] = data; - y0 = (y1 << 1) - y2 + x[n] - (x[n + 6] << 1) + x[n + 12]; - y2 = y1; - y1 = y0; - y0 >>= 5; - if(--n < 0){ - n = 12; - } - return y0; -} - -/* p(nT) = x(nT – 16T) – 32 [y(nT – T) + x(nT) – x(nT – 32T)] */ -int HighPassFilter(int data) -{ - static int y1 = 0, x[66], n = 32; - int y0; - - x[n] = x[n + 33] = data; - y0 = y1 + x[n] - x[n + 32]; - y1 = y0; - if(--n < 0){ - n = 32; - } - return (x[n + 16] - (y0 >> 5)); -} - -/* y = 1/8 (2x( nT) + x( nT - T) - x( nT - 3T) - 2x( nT - 4T)) */ -int Derivative(int data) -{ - int y; - static int x_derv[4]; - - y = (data << 1) + x_derv[3] - x_derv[1] - ( x_derv[0] << 1); - y >>= 3; - for(int i = 0; i < 3; ++i){ - x_derv[i] = x_derv[i + 1]; - } - x_derv[3] = data; - return y; -} - -int Squar(int data) -{ - return (data * data); -} - -/* y(nT) = 1/N [x(nT – (N – 1)T) + x(nT – (N – 2)T) +...+ x(nT)] */ -int MovingWindowIntegral(int data) -{ - //static const int WINDOW_SIZE = SAMPLING_RATE * 0.2; - #define WINDOW_SIZE 72 - - static int x[WINDOW_SIZE], ptr = 0; - static long sum = 0; - long ly; - int y; - - if(++ptr == WINDOW_SIZE){ - ptr = 0; - } - sum -= x[ptr]; - sum += data; - x[ptr] = data; - ly = sum >> 5; - uint32_t MAX_INTEGRAL = 4096;//32400; - if(ly > MAX_INTEGRAL){ - y = MAX_INTEGRAL; - } - else{ - y = (int)ly; - } - return (y); -} - -SignalPoint ThresholdCalculate(int sample,float value,int bandpass,int square,int integral) -{ - //static const int QRS_TIME = SAMPLING_RATE * 0.1; - //static const int SEARCH_BACK_TIME = SAMPLING_RATE * 1.66f; - #define QRS_TIME 36 - #define SEARCH_BACK_TIME 598 - - static int bandpass_buffer[SEARCH_BACK_TIME],integral_buffer[SEARCH_BACK_TIME]; - static SignalPoint peak_buffer[SEARCH_BACK_TIME]; - static int square_buffer[QRS_TIME]; - static long unsigned last_qrs = 0, last_slope = 0, current_slope = 0; - static int peak_i = 0, peak_f = 0, threshold_i1 = 0, threshold_i2 = 0, threshold_f1 = 0, threshold_f2 = 0, spk_i = 0, spk_f = 0, npk_i = 0, npk_f = 0; - static bool qrs, regular = true, prev_regular; - static int rr1[8]={0}, rr2[8]={0}, rravg1, rravg2, rrlow = 0, rrhigh = 0, rrmiss = 0; - - SignalPoint result; - result.index = -1; - - peak_buffer[sample%SEARCH_BACK_TIME].index = sample; - peak_buffer[sample%SEARCH_BACK_TIME].value = value; - bandpass_buffer[sample%SEARCH_BACK_TIME] = bandpass; - integral_buffer[sample%SEARCH_BACK_TIME] = integral; - square_buffer[sample%QRS_TIME] = square; - - // If the current signal is above one of the thresholds (integral or filtered signal), it's a peak candidate. - if(integral >= threshold_i1 || bandpass >= threshold_f1){ - peak_i = integral; - peak_f = bandpass; - } - - // If both the integral and the signal are above their thresholds, they're probably signal peaks. - if((integral >= threshold_i1) && (bandpass >= threshold_f1)){ - // There's a 200ms latency. If the new peak respects this condition, we can keep testing. - if(sample > last_qrs + SAMPLING_RATE*0.2f){ - //if(sample > last_qrs + (SAMPLING_RATE*0.2f)){ - // If it respects the 200ms latency, but it doesn't respect the 360ms latency, we check the slope. - if(sample <= last_qrs + (long unsigned int)(0.36*SAMPLING_RATE)){ - // The squared slope is "M" shaped. So we have to check nearby samples to make sure we're really looking - // at its peak value, rather than a low one. - int current = sample; - current_slope = 0; - for(int j = current - QRS_TIME; j <= current; ++j){ - if(square_buffer[j%QRS_TIME] > current_slope){ - current_slope = square_buffer[j%QRS_TIME]; - } - } - //current_slope = square; - - if(current_slope <= (int)(last_slope/2)){ - qrs = false; - //return qrs; - } - - else{ - spk_i = 0.125*peak_i + 0.875*spk_i; - threshold_i1 = npk_i + 0.25*(spk_i - npk_i); - threshold_i2 = 0.5*threshold_i1; - - spk_f = 0.125*peak_f + 0.875*spk_f; - threshold_f1 = npk_f + 0.25*(spk_f - npk_f); - threshold_f2 = 0.5*threshold_f1; - - last_slope = current_slope; - qrs = true; - - result.value = value; - result.index = sample; - } - } - // If it was above both thresholds and respects both latency periods, it certainly is a R peak. - else{ - int current = sample; - current_slope = 0; - for(int j = current - QRS_TIME; j <= current; ++j){ - if(square_buffer[j%QRS_TIME] > current_slope){ - current_slope = square_buffer[j%QRS_TIME]; - } - } - //current_slope = square; - - spk_i = 0.125*peak_i + 0.875*spk_i; - threshold_i1 = npk_i + 0.25*(spk_i - npk_i); - threshold_i2 = 0.5*threshold_i1; - - spk_f = 0.125*peak_f + 0.875*spk_f; - threshold_f1 = npk_f + 0.25*(spk_f - npk_f); - threshold_f2 = 0.5*threshold_f1; - - last_slope = current_slope; - qrs = true; - - result.value = value; - result.index = sample; - } - } - // If the new peak doesn't respect the 200ms latency, it's noise. Update thresholds and move on to the next sample. - else{ - peak_i = integral; - npk_i = 0.125*peak_i + 0.875*npk_i; - threshold_i1 = npk_i + 0.25*(spk_i - npk_i); - threshold_i2 = 0.5*threshold_i1; - peak_f = bandpass; - npk_f = 0.125*peak_f + 0.875*npk_f; - threshold_f1 = npk_f + 0.25*(spk_f - npk_f); - threshold_f2 = 0.5*threshold_f1; - qrs = false; - /*outputSignal[current] = qrs; - if (sample > DELAY + BUFFSIZE) - output(outputSignal[0]); - continue;*/ - - //return qrs; - return result; - } - } - - // If a QRS complex was detected, the RR-averages must be updated. - if(qrs){ - // Add the newest RR-interval to the buffer and get the new average. - rravg1 = 0; - for (int i = 0; i < 7; ++i){ - rr1[i] = rr1[i+1]; - rravg1 += rr1[i]; - } - rr1[7] = sample - last_qrs; - last_qrs = sample; - rravg1 += rr1[7]; - rravg1 *= 0.125; - - // If the newly-discovered RR-average is normal, add it to the "normal" buffer and get the new "normal" average. - // Update the "normal" beat parameters. - if ( (rr1[7] >= rrlow) && (rr1[7] <= rrhigh) ){ - rravg2 = 0; - for (int i = 0; i < 7; ++i){ - rr2[i] = rr2[i+1]; - rravg2 += rr2[i]; - } - rr2[7] = rr1[7]; - rravg2 += rr2[7]; - rravg2 *= 0.125; - rrlow = 0.92*rravg2; - rrhigh = 1.16*rravg2; - rrmiss = 1.66*rravg2; - } - - prev_regular = regular; - if(rravg1 == rravg2){ - regular = true; - } - // If the beat had been normal but turned odd, change the thresholds. - else{ - regular = false; - if (prev_regular){ - threshold_i1 /= 2; - threshold_f1 /= 2; - } - } - } - // If no R-peak was detected, it's important to check how long it's been since the last detection. - else{ - int current = sample; - // If no R-peak was detected for too long, use the lighter thresholds and do a back search. - // However, the back search must respect the 200ms limit and the 360ms one (check the slope). - if((sample - last_qrs > (long unsigned int)rrmiss) && (sample > last_qrs + SAMPLING_RATE*0.2f)){ - //if((sample - last_qrs > (long unsigned int)rrmiss) && (sample > last_qrs + (SAMPLING_RATE*0.2f))){ - - // If over SEARCH_BACK_TIME of QRS complex - if((sample - last_qrs) > SEARCH_BACK_TIME){ - last_qrs = sample; - //return result; - } - - int qrs_last_index = 0; // Last point of QRS complex - - for(int i = current - (sample - last_qrs) + SAMPLING_RATE*0.2f; i < (long unsigned int)current; ++i){ - //for(int i = current - (sample - last_qrs) + (SAMPLING_RATE*0.2f); i < (long unsigned int)current; ++i){ - if((integral_buffer[i%SEARCH_BACK_TIME] > threshold_i2) && (bandpass_buffer[i%SEARCH_BACK_TIME] > threshold_f2)){ - current_slope = 0; - for(int j = current - QRS_TIME; j <= current; ++j){ - if(square_buffer[j%QRS_TIME] > current_slope){ - current_slope = square_buffer[j%QRS_TIME]; - } - } - //current_slope = square; - - if((current_slope < (int)(last_slope/2)) && (i + sample) < last_qrs + 0.36*last_qrs){ - qrs = false; - } - else if(i - last_qrs > 550){ - peak_i = integral_buffer[i%SEARCH_BACK_TIME]; - peak_f = bandpass_buffer[i%SEARCH_BACK_TIME]; - spk_i = 0.25*peak_i+ 0.75*spk_i; - spk_f = 0.25*peak_f + 0.75*spk_f; - threshold_i1 = npk_i + 0.25*(spk_i - npk_i); - threshold_i2 = 0.5*threshold_i1; - last_slope = current_slope; - threshold_f1 = npk_f + 0.25*(spk_f - npk_f); - threshold_f2 = 0.5*threshold_f1; - // If a signal peak was detected on the back search, the RR attributes must be updated. - // This is the same thing done when a peak is detected on the first try. - //RR Average 1 - rravg1 = 0; - for(int j = 0; j < 7; ++j){ - rr1[j] = rr1[j+1]; - rravg1 += rr1[j]; - } - rr1[7] = sample - (current - i) - last_qrs; - qrs = true; - qrs_last_index = i; - last_qrs = sample - (current - i); - rravg1 += rr1[7]; - rravg1 *= 0.125; - - //RR Average 2 - if((rr1[7] >= rrlow) && (rr1[7] <= rrhigh)){ - rravg2 = 0; - for (int i = 0; i < 7; ++i){ - rr2[i] = rr2[i+1]; - rravg2 += rr2[i]; - } - rr2[7] = rr1[7]; - rravg2 += rr2[7]; - rravg2 *= 0.125; - rrlow = 0.92*rravg2; - rrhigh = 1.16*rravg2; - rrmiss = 1.66*rravg2; - } - - prev_regular = regular; - if(rravg1 == rravg2){ - regular = true; - } - else{ - regular = false; - if(prev_regular){ - threshold_i1 /= 2; - threshold_f1 /= 2; - } - } - - break; - } - } - } - - if(qrs){ - //outputSignal[current] = false; - //outputSignal[i] = true; - //if (sample > DELAY + BUFFSIZE) - //output(outputSignal[0]); - //continue; - - //return qrs; - return peak_buffer[qrs_last_index%SEARCH_BACK_TIME]; - } - } - - // Definitely no signal peak was detected. - if(!qrs){ - // If some kind of peak had been detected, then it's certainly a noise peak. Thresholds must be updated accordinly. - if((integral >= threshold_i1) || (bandpass >= threshold_f1)){ - peak_i = integral; - npk_i = 0.125*peak_i + 0.875*npk_i; - threshold_i1 = npk_i + 0.25*(spk_i - npk_i); - threshold_i2 = 0.5*threshold_i1; - peak_f = bandpass; - npk_f = 0.125*peak_f + 0.875*npk_f; - threshold_f1 = npk_f + 0.25*(spk_f - npk_f); - threshold_f2 = 0.5*threshold_f1; - } - } - } - - return result; - } diff --git a/bak/Pan_Tompkins_detect.h b/bak/Pan_Tompkins_detect.h deleted file mode 100644 index cbd65d0..0000000 --- a/bak/Pan_Tompkins_detect.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef __PAN_TOMPKINS__ -#define __PAN_TOMPKINS__ - -#include -#include -#include -#include -#include - -#include "QRS.h" -extern int TwoPoleRecursive(int); - -extern int LowPassFilter(int); -extern int HighPassFilter(int); - -extern int Derivative(int); -extern int Squar(int); -extern int MovingWindowIntegral(int); - -extern SignalPoint ThresholdCalculate(int,float,int,int,int); -#endif diff --git a/bak/QRS.h b/bak/QRS.h deleted file mode 100644 index 33aba1b..0000000 --- a/bak/QRS.h +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once -#include -//const uint32_t SAMPLING_RATE = 1000; -#define SAMPLING_RATE 360 - -typedef struct -{ - float value; - int32_t index; -}SignalPoint; - -enum -{ - NOTQRS, /* not-QRS (not a getann/putann code) */ - NORMAL, /* normal beat */ - LBBB, /* left bundle branch block beat */ - RBBB, /* right bundle branch block beat */ - ABERR, /* aberrated atrial premature beat */ - PVC, /* premature ventricular contraction */ - FUSION, /* fusion of ventricular and normal beat */ - NPC, /* nodal (junctional) premature beat */ - APC, /* atrial premature contraction */ - SVPB, /* premature or ectopic supraventricular beat */ - VESC, /* ventricular escape beat */ - NESC, /* nodal (junctional) escape beat */ - PACE, /* paced beat */ - UNKNOWN, /* unclassifiable beat */ - NOISE, /* signal quality change */ - ARFCT /* isolated QRS-like artifact */ -}; diff --git a/bak/So_Chen_detect.c b/bak/So_Chen_detect.c deleted file mode 100644 index e329825..0000000 --- a/bak/So_Chen_detect.c +++ /dev/null @@ -1,93 +0,0 @@ -#include "So_Chen_detect.h" - -SignalPoint So_Chen_detect(SignalPoint signal,int initial_point,float threshold_parameter,float filter_parameter) -{ - /* init slop window pool, size = 5 */ - if(signal_window_count < signal_window_size){ - signal_window[signal_window_count%signal_window_size] = signal; - ++signal_window_count; - SignalPoint value; - value.index = -1; - return value; - } - else{ - signal_window[signal_window_count%signal_window_size] = signal; - ++signal_window_count; - SignalPoint value; - } - - /* calculate slop */ - uint32_t idx_for_slop = signal_window_count-2; - slop.value = ( (-2.0f * signal_window[(idx_for_slop-2)%signal_window_size].value) - signal_window[(idx_for_slop-1)%signal_window_size].value + signal_window[(idx_for_slop+1)%signal_window_size].value + (2.0f * signal_window[(idx_for_slop+2)%signal_window_size].value) ); - slop.index = signal_window[idx_for_slop%signal_window_size].index; - - /* init maxi */ - if(!so_chen_init_flag){ - if(!maxi_init){ - max.value = 0; - max.index = -1; - maxi = slop.value; - maxi_init = true; - } - ++init_count; - if(init_count > initial_point){ - so_chen_init_flag = true; - /* calculate slop threshold */ - slop_threshold = threshold_parameter / 16.0f * maxi; - } - if(slop.value > maxi){ - maxi = slop.value; - } - SignalPoint value; - value.index = -1; - return value; - } - - /* detect QRS complex on set */ - if(qrs_on_set_flag && (signal_window_count - last_point > enhanced_point)){ - if(!max_init){ - max = signal_window[(idx_for_slop)%signal_window_size]; - max_init = true; - } - if(signal_window[(idx_for_slop)%signal_window_size].value > max.value){ - max = signal_window[(idx_for_slop)%signal_window_size]; - max_slop = slop; - } - else if(signal_window[(idx_for_slop)%signal_window_size].value < max.value){ - last_point = signal_window_count; - qrs_on_set_flag = false; - max_init = false; - maxi = ((abs(max.value - qrs_onset_point.value) - maxi) / filter_parameter) + maxi; - slop_threshold = threshold_parameter / 16.0f * maxi; - last_maxi = maxi; - return max; - } - } - else{ - if(slop.value > slop_threshold){ - ++qrs_on_set_count; - } - else if(qrs_on_set_count){ - qrs_on_set_count = 0; - } - - if(qrs_on_set_count >= 2){ // is QRS complex on set - qrs_on_set_flag = true; - qrs_on_set_count = 0; - qrs_onset_idx = idx_for_slop; - qrs_onset_point = signal; - } - else if((signal_window_count - last_point > enhanced_point * 2) && (slop_threshold > 0)){ //decay threshold - - slop_threshold -= slop.value; - - if((signal_window_count - last_point > SAMPLING_RATE * 3)){ //threshold oscillating - slop_threshold -= ((signal_window_count - last_point) >> (int)threshold_parameter); - } - } - } - - SignalPoint value; - value.index = -1; - return value; -} diff --git a/bak/So_Chen_detect.h b/bak/So_Chen_detect.h deleted file mode 100644 index a505775..0000000 --- a/bak/So_Chen_detect.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef __SO_AND_CHEN__ -#define __SO_AND_CHEN__ - -#include -#include -#include -#include -#include - -#include "QRS.h" -static const uint32_t enhanced_point = SAMPLING_RATE * 0.35f; - -#define signal_window_size 5 -static SignalPoint signal_window[signal_window_size]; -static uint32_t signal_window_count = 0; - -static SignalPoint slop; - -static bool so_chen_init_flag = false; -static uint32_t init_count = 0; - -static bool maxi_init = false; -static float maxi; - -static float slop_threshold = 0; - -static SignalPoint qrs_onset_point; - -static int qrs_on_set_count = 0; -static int qrs_onset_idx = 0; -static bool qrs_on_set_flag = false; - -static SignalPoint max; -static SignalPoint max_slop; -static bool max_init = false; - -static float last_maxi = 0; -static uint32_t last_point = 0; - -SignalPoint So_Chen_detect(SignalPoint,int,float,float); - -#endif diff --git a/bak/adaptive_algorithm.c b/bak/adaptive_algorithm.c deleted file mode 100644 index 11a4e60..0000000 --- a/bak/adaptive_algorithm.c +++ /dev/null @@ -1,100 +0,0 @@ -#include "adaptive_algorithm.h" - -float CalculateMean(float value) -{ - value /= 1000.0f; - if(mean_count < MEAN_SIZE){ - mean_sum += value; - ++mean_count; - } - else{ - mean = mean_sum/MEAN_SIZE; - mean_count = 0; - mean_sum = 0; - - } - return (mean * 1000.0f); -} - -float CalculateRootMeanSquare(float value) -{ - value /= 1000.0f; - if(rms_count < RMS_SIZE){ - rms_sum += value * value; - ++rms_count; - } - else{ - rms = sqrt(rms_sum/RMS_SIZE); - rms_count = 0; - rms_sum = 0; - - } - return (rms * 1000.0f); -} - -float CalculateCoefficientOfVariation(float value) -{ - value /= 1000.0f; - if(cv_count < CV_SIZE){ - sd += (value - mean) * (value - mean); - ++cv_count; - } - else{ - sd = sqrt(sd / (CV_SIZE-1)); - cv = (sd / mean) * 100; - cv_count = 0; - sd = 0; - - } - return cv; -} - -void InitPeakDetect(float value,bool emi_first) -{ - if(!init_flag){ - current_max = value; - current_min = value; - is_detecting_emi = emi_first; - init_flag = true; - } -} - -SignalPoint PeakDetect(float value,int index,float gradient,bool *is_peak) -{ - if(value > current_max){ - max_point = index; - current_max = value; - } - if(value < current_min){ - min_point = index; - current_min = value; - } - - if(is_detecting_emi && value < (current_max - gradient) ){ - - is_detecting_emi = false; - - current_min = current_max; - min_point = max_point; - *is_peak = true; - peak.value = current_max; - peak.index = max_point; - return peak; - } - else if((!is_detecting_emi) && value > (current_min + gradient)) - { - - is_detecting_emi = true; - - current_max = current_min; - max_point = min_point; - *is_peak = false; - peak.value = current_min; - peak.index = min_point; - return peak; - } - - peak.index = -1; - return peak; -} - diff --git a/bak/adaptive_algorithm.h b/bak/adaptive_algorithm.h deleted file mode 100644 index d1bbbc6..0000000 --- a/bak/adaptive_algorithm.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef __ALGORITHM__ -#define __ALGORITHM__ - -#include -#include -#include -#include -#include -#include - -#include "QRS.h" -static const uint32_t MEAN_SIZE = SAMPLING_RATE; -static uint32_t mean_count; -static float mean_sum; -static float mean; - -static const uint32_t RMS_SIZE = SAMPLING_RATE; -static uint32_t rms_count; -static float rms_sum; -static float rms; - -static const uint32_t CV_SIZE = SAMPLING_RATE; -static uint32_t cv_count; -static float sd; -static float cv; - -static float current_max; -static float current_min; -static int max_point; -static int min_point; -static SignalPoint peak; -static bool is_detecting_emi; -static bool init_flag = false; - -extern float CalculateMean(float); -extern float CalculateRootMeanSquare(float); -extern float CalculateCoefficientOfVariation(float); -extern void InitPeakDetect(float,bool); -extern SignalPoint PeakDetect(float,int,float,bool*); - -#endif diff --git a/bak/qrs_time_domain_zh.c b/bak/qrs_time_domain_zh.c deleted file mode 100644 index b42291e..0000000 --- a/bak/qrs_time_domain_zh.c +++ /dev/null @@ -1,231 +0,0 @@ -#include "qrs_time_domain_zh.h" - -#include -#include -#include - -#define HEART_RATE_FILTER_SIZE 10 - -typedef struct { - uint16_t data[HEART_RATE_FILTER_SIZE]; - uint16_t data_process_buf[HEART_RATE_FILTER_SIZE]; - uint32_t cnt; - uint32_t index; -} HeartRateMedianFilter_t; // ÖÐÖµÂ˲¨Æ÷ - -typedef struct { - uint16_t data[HEART_RATE_FILTER_SIZE]; - uint32_t cnt; - uint32_t index; - uint32_t sum; -} HeartRateMeanFilter_t; // ¾ùÖµÂ˲¨Æ÷ - -HeartRateMedianFilter_t m_heart_rate_median_filter; -HeartRateMeanFilter_t m_heart_rate_mean_filter; - -static void HeartRateMedianFilter_reset() { - memset(m_heart_rate_median_filter.data, 0, sizeof(m_heart_rate_median_filter.data)); - m_heart_rate_median_filter.cnt = 0; - m_heart_rate_median_filter.index = 0; -} -static uint16_t HeartRateMedianFilter_process(uint16_t data) { - HeartRateMedianFilter_t* pfilter = &m_heart_rate_median_filter; - - pfilter->data[pfilter->index] = data; - pfilter->index++; - pfilter->cnt++; - if (pfilter->index >=HEART_RATE_FILTER_SIZE) { - pfilter->index = 0; - } - - if (pfilter->cnt data_process_buf, pfilter->data, HEART_RATE_FILTER_SIZE * sizeof(uint16_t)); - for (uint8_t i = 0; i < HEART_RATE_FILTER_SIZE; i++) { - for (uint8_t j = i + 1; j < HEART_RATE_FILTER_SIZE; j++) { - if (pfilter->data_process_buf[i] > pfilter->data_process_buf[j]) { - uint16_t temp = pfilter->data_process_buf[i]; - pfilter->data_process_buf[i] = pfilter->data_process_buf[j]; - pfilter->data_process_buf[j] = temp; - } - } - } - return pfilter->data_process_buf[2]; -} -static void HeartRateMeanFilter_reset() { - memset(m_heart_rate_mean_filter.data, 0, sizeof(m_heart_rate_mean_filter.data)); - m_heart_rate_mean_filter.cnt = 0; - m_heart_rate_mean_filter.index = 0; - m_heart_rate_mean_filter.sum = 0; -} -static uint16_t HeartRateMeanFilter_process(uint16_t data) { - HeartRateMeanFilter_t* pfilter = &m_heart_rate_mean_filter; - - pfilter->sum -= pfilter->data[pfilter->index]; - pfilter->data[pfilter->index] = data; - pfilter->sum += data; - - pfilter->index++; - pfilter->cnt++; - - if (pfilter->index >= HEART_RATE_FILTER_SIZE) { - pfilter->index = 0; - } - - if (pfilter->cnt < HEART_RATE_FILTER_SIZE) { - return data; - } - - return pfilter->sum / HEART_RATE_FILTER_SIZE; -} - -static uint16_t m_data[TABLE_SIZE]; -static uint32_t m_ndata = 0; -static uint32_t m_dataindex = 0; -static uint32_t m_data_cnt = 0; -static uint16_t m_heartrate = 0; - -static uint32_t m_datasum = 0; -static float m_avg = 0; -static uint32_t m_max_val_in_m_data; - -static bool m_findpeak = false; - -static uint16_t pQRS_median_filter_cache[HEART_RATE_FILTER_SIZE]; -static uint16_t pQRS_median_filter_cache_index = 0; -static uint16_t pQRS_median_filter_cache_cnt = 0; - -static uint32_t m_last_peak_pos = 0; -static uint32_t m_peakcnt = 0; - -static uint16_t pQRS_median_filter(uint16_t indata) { - // memcpy(pQRS_median_filter_cache + 1, pQRS_median_filter_cache, 4 * sizeof(uint16_t)); - pQRS_median_filter_cache[pQRS_median_filter_cache_index] = indata; - pQRS_median_filter_cache_index++; - pQRS_median_filter_cache_cnt++; - if (pQRS_median_filter_cache_index >= HEART_RATE_FILTER_SIZE) { - pQRS_median_filter_cache_index = 0; - } - - if (pQRS_median_filter_cache_cnt < HEART_RATE_FILTER_SIZE) { - return indata; - } - - static uint16_t process_cache[HEART_RATE_FILTER_SIZE]; - memcpy(process_cache, pQRS_median_filter_cache, HEART_RATE_FILTER_SIZE * sizeof(uint16_t)); - for (uint8_t i = 0; i < HEART_RATE_FILTER_SIZE; i++) { - for (uint8_t j = i + 1; j < HEART_RATE_FILTER_SIZE; j++) { - if (process_cache[i] > process_cache[j]) { - uint16_t temp = process_cache[i]; - process_cache[i] = process_cache[j]; - process_cache[j] = temp; - } - } - } - return process_cache[2]; -} - -static uint32_t pQRS_findMaxValue() { - uint32_t max_val = 0; - for (uint32_t i = 0; i < TABLE_SIZE; i++) { - if (m_data[i] > max_val) { - max_val = m_data[i]; - } - } - return max_val; -} - -void QRS_resetBuf() { // - m_ndata = 0; - m_dataindex = 0; - m_heartrate = 0; - m_data_cnt = 0; - memset(m_data, 0, sizeof(m_data)); - m_datasum = 0; - m_findpeak = false; - pQRS_median_filter_cache_index = 0; - pQRS_median_filter_cache_cnt = 0; - m_peakcnt = 0; - - HeartRateMedianFilter_reset(); - HeartRateMeanFilter_reset(); -} - -void QRS_processData(uint16_t _data) { - uint16_t data = pQRS_median_filter(_data); - /******************************************************************************* - * Ìî³äBUF * - *******************************************************************************/ - m_datasum -= m_data[m_dataindex]; - m_data[m_dataindex] = data; - m_datasum += data; - - m_data_cnt++; - - if (m_dataindex < TABLE_SIZE) { - m_dataindex++; - } else { - m_dataindex = 0; - } - - m_ndata++; - if (m_ndata > TABLE_SIZE) { - m_ndata = TABLE_SIZE; - } - - /******************************************************************************* - * ÇóBUFµÄƽ¾ùÖµºÍ×î´óÖµ * - *******************************************************************************/ - if (m_ndata == TABLE_SIZE) { - m_avg = (float)m_datasum / m_ndata; - m_max_val_in_m_data = pQRS_findMaxValue(); - } - - /******************************************************************************* - * ѰÕÒQRS²¨·åºÍ²¨¹È * - *******************************************************************************/ - - if (!m_findpeak) { - uint16_t thresholdValue = (m_max_val_in_m_data - m_avg) * 0.666 + m_avg; - if (data > thresholdValue) { - m_findpeak = true; - m_peakcnt++; - - if (m_last_peak_pos != 0) { - uint16_t diff_peak_pos = m_data_cnt - m_last_peak_pos; - if (diff_peak_pos > 0) { - // - // m_heartrate = 60 * 500 / diff_peak_pos; - - uint16_t diff_peak_ms = diff_peak_pos * 2; // 500Hz - uint16_t heart_rate = 60 * 1000 / diff_peak_ms; - - m_heartrate = HeartRateMeanFilter_process(HeartRateMedianFilter_process(heart_rate)); - } - } - - m_last_peak_pos = m_data_cnt; - } - } else { - if (data < m_avg) { - m_findpeak = false; - } - } -} -uint16_t QRS_getHeartRate() { - __disable_fiq(); - uint16_t heartrate = m_heartrate; - __enable_fiq(); - - if (heartrate > 200) return 0; - if (heartrate < 55) return 0; - return heartrate; -} - -uint16_t QRS_getMaxValueLastVal() { return m_max_val_in_m_data; } - -uint16_t QRS_getAvgValueVal() { // - return m_avg; -} diff --git a/bak/qrs_time_domain_zh.h b/bak/qrs_time_domain_zh.h deleted file mode 100644 index 56f1a65..0000000 --- a/bak/qrs_time_domain_zh.h +++ /dev/null @@ -1,19 +0,0 @@ -/** - * @file qrs_time_domain_zh.h - * @author zhaohe (zhaohe@domain.com) - * @brief - * @version 0.1 - * @date 2024-02-10 - * - * @copyright Copyright (c) 2024 - * - */ -#pragma once -#include -#define TABLE_SIZE 1000 - -void QRS_resetBuf(); -void QRS_processData(uint16_t data); -uint16_t QRS_getHeartRate(); -uint16_t QRS_getMaxValueLastVal(); -uint16_t QRS_getAvgValueVal(); diff --git a/bak/zapp_timer.c b/bak/zapp_timer.c deleted file mode 100644 index efaa974..0000000 --- a/bak/zapp_timer.c +++ /dev/null @@ -1,29 +0,0 @@ -#include "zapp_timer.h" - -static void app_timer_timeout_handler(void* p_context) { // - zapp_timer_context* zcontext = (zapp_timer_context*)p_context; - ZASSERT(zcontext != NULL); - ZASSERT(zcontext->mark = 0xAABBCCDD); - - if (zcontext->timeout_handler) zcontext->timeout_handler(zcontext->usrcontext); -} - -ret_code_t zapp_timer_create(zapp_timer_context* context, // - app_timer_id_t* p_timer_id, app_timer_mode_t mode, app_timer_timeout_handler_t timeout_handler) { - context->timeout_handler = timeout_handler; - context->mark = 0xAABBCCDD; - ret_code_t ret = app_timer_create(p_timer_id, mode, app_timer_timeout_handler); - if (ret != NRF_SUCCESS) { - return ret; - } - (*p_timer_id)->p_context = context; - return ret; -} - -ret_code_t zapp_timer_start(app_timer_id_t timer_id, uint32_t timeout_ticks, void* p_context) { // - zapp_timer_context* zcontext = (zapp_timer_context*)timer_id->p_context; - ZASSERT(zcontext != NULL); - ZASSERT(zcontext->mark = 0xAABBCCDD); - zcontext->usrcontext = p_context; - return app_timer_start(timer_id, timeout_ticks, zcontext); -} diff --git a/bak/zapp_timer.h b/bak/zapp_timer.h deleted file mode 100644 index f73f008..0000000 --- a/bak/zapp_timer.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once -#include -#include - -#include "znordic.h" - -typedef void (*app_event_listener_t)(void* p_event_data, uint16_t event_size); - -typedef struct { - uint32_t mark; - app_timer_timeout_handler_t timeout_handler; - void* usrcontext; -} zapp_timer_context; - -ret_code_t zapp_timer_create(zapp_timer_context* context, // - app_timer_id_t const* p_timer_id, app_timer_mode_t mode, app_timer_timeout_handler_t timeout_handler); -ret_code_t zapp_timer_start(app_timer_id_t timer_id, uint32_t timeout_ticks, void* p_context); \ No newline at end of file diff --git a/ify_hrs_protocol b/ify_hrs_protocol index 81bdc53..6bceb37 160000 --- a/ify_hrs_protocol +++ b/ify_hrs_protocol @@ -1 +1 @@ -Subproject commit 81bdc5323d5618123e1cbe6ee590d3514ca216b0 +Subproject commit 6bceb372ed9409f8a4ac2a365b7af800f0a2353b