|
|
@ -9,59 +9,41 @@ |
|
|
|
#include "nrf_drv_gpiote.h" |
|
|
|
#include "nrfx_timer.h" |
|
|
|
|
|
|
|
#define SENSOR0_ID 0 |
|
|
|
#define SENSOR1_ID 3 |
|
|
|
#define SENSOR2_ID 4 |
|
|
|
static const nrfx_timer_t m_timer = NRFX_TIMER_INSTANCE(1); /**< Timer used for channel sweeps and tx with duty cycle. */ |
|
|
|
#define SENSOR0_ID 0 |
|
|
|
#define SENSOR1_ID 3 |
|
|
|
#define SENSOR2_ID 4 |
|
|
|
#define FRAME_FILTER_INDEX_NUM 10 // 过滤帧数,每次启动采集后,过滤掉的帧数 |
|
|
|
|
|
|
|
#define GPIO_IRQ_TRIGGER_MODE 1 |
|
|
|
|
|
|
|
/******************************************************************************* |
|
|
|
* STRUCT * |
|
|
|
*******************************************************************************/ |
|
|
|
typedef struct { |
|
|
|
uint8_t add; |
|
|
|
uint8_t data; |
|
|
|
} adscfg_t; |
|
|
|
|
|
|
|
/******************************************************************************* |
|
|
|
* CONFIG * |
|
|
|
* 全局变量 * |
|
|
|
*******************************************************************************/ |
|
|
|
#if GPIO_IRQ_TRIGGER_MODE |
|
|
|
#else |
|
|
|
static const nrfx_timer_t m_timer = NRFX_TIMER_INSTANCE(1); /**< Timer used for channel sweeps and tx with duty cycle. */ |
|
|
|
#endif |
|
|
|
static const nrf_drv_spi_t spi = NRF_DRV_SPI_INSTANCE(ADS1293_SPI_INSTANCE); /**< SPI instance. */ |
|
|
|
|
|
|
|
static adscfg_t m_prvads0cfg[] = // |
|
|
|
{ |
|
|
|
{0x00, 0x00}, {0x01, 0x19}, {0x02, 0x11}, {0x03, 0x00}, {0x04, 0x00}, {0x05, 0x00}, {0x06, 0x00}, {0x07, 0x0f}, {0x08, 0xff}, {0x09, 0x00}, {0x0a, 0x07}, {0x0b, 0x07}, {0x0c, 0x74}, {0x0d, 0x01}, {0x0e, 0x02}, {0x0f, 0x03}, {0x10, 0x04}, |
|
|
|
{0x11, 0x00}, {0x12, 0x05}, {0x13, 0x39}, {0x14, 0x36}, {0x15, 0x06}, {0x16, 0x00}, {0x17, 0x05}, {0x18, 0x00}, {0x19, 0x00}, {0x1a, 0x00}, {0x1b, 0x00}, {0x1c, 0x00}, {0x1d, 0x00}, {0x21, 0x01}, {0x22, 0x20}, {0x23, 0x20}, {0x24, 0x02}, |
|
|
|
{0x25, 0x00}, {0x26, 0x00}, {0x27, 0x08}, {0x28, 0x08}, {0x29, 0x00}, {0x2a, 0x00}, {0x2b, 0x00}, {0x2c, 0x00}, {0x2d, 0x00}, {0x2e, 0x33}, {0x2f, 0x30}, {0x30, 0x00}, {0x31, 0x00}, {0x32, 0x00}, {0x33, 0x00}, {0x34, 0x00}, {0x35, 0x00}, |
|
|
|
{0x36, 0x00}, {0x37, 0x00}, {0x38, 0x00}, {0x39, 0x00}, {0x3a, 0x00}, {0x3b, 0x00}, {0x3c, 0x00}, {0x3d, 0x00}, {0x3e, 0x00}, {0x3f, 0x00}, {0x40, 0xff}, {0x50, 0x00}, {0x60, 0x00}, {0x62, 0x00}, |
|
|
|
}; |
|
|
|
|
|
|
|
static adscfg_t m_prvads1cfg[] = // |
|
|
|
{ |
|
|
|
{0x00, 0x00}, {0x01, 0x0c}, {0x02, 0x14}, {0x03, 0x00}, {0x04, 0x00}, {0x05, 0x00}, {0x06, 0x00}, {0x07, 0x0f}, {0x08, 0xff}, {0x09, 0x00}, {0x0a, 0x00}, {0x0b, 0x07}, {0x0c, 0x78}, {0x0d, 0x00}, {0x0e, 0x00}, {0x0f, 0x00}, {0x10, 0x04}, |
|
|
|
{0x11, 0x00}, {0x12, 0x07}, {0x13, 0x3b}, {0x14, 0x24}, {0x15, 0x04}, {0x16, 0x00}, {0x17, 0x05}, {0x18, 0x00}, {0x19, 0x00}, {0x1a, 0x00}, {0x1b, 0x00}, {0x1c, 0x00}, {0x1d, 0x00}, {0x21, 0x01}, {0x22, 0x20}, {0x23, 0x20}, {0x24, 0x02}, |
|
|
|
{0x25, 0x00}, {0x26, 0x00}, {0x27, 0x08}, {0x28, 0x40}, {0x29, 0x00}, {0x2a, 0x00}, {0x2b, 0x00}, {0x2c, 0x00}, {0x2d, 0x00}, {0x2e, 0x33}, {0x2f, 0x30}, {0x30, 0x00}, {0x31, 0x00}, {0x32, 0x00}, {0x33, 0x00}, {0x34, 0x00}, {0x35, 0x00}, |
|
|
|
{0x36, 0x00}, {0x37, 0x00}, {0x38, 0x00}, {0x39, 0x00}, {0x3a, 0x00}, {0x3b, 0x00}, {0x3c, 0x00}, {0x3d, 0x00}, {0x3e, 0x00}, {0x3f, 0x00}, {0x40, 0xff}, {0x50, 0x00}, {0x60, 0x00}, {0x62, 0x00}, |
|
|
|
}; |
|
|
|
|
|
|
|
static adscfg_t m_prvads0cfg_cache[65]; |
|
|
|
static adscfg_t m_prvads1cfg_cache[65]; |
|
|
|
/******************************************************************************* |
|
|
|
* VARIABLE * |
|
|
|
*******************************************************************************/ |
|
|
|
static ads1293_t m_ads1293_0; // U2 |
|
|
|
static ads1293_t m_ads1293_1; // U3 |
|
|
|
static const nrf_drv_spi_t spi = NRF_DRV_SPI_INSTANCE(ADS1293_SPI_INSTANCE); /**< SPI instance. */ |
|
|
|
static bool m_ads1293_driver_is_inited = false; |
|
|
|
static uint32_t m_frame_index; |
|
|
|
static uint32_t m_frame_filter_index; |
|
|
|
static bool m_work_flag; |
|
|
|
static ads1293_t m_ads1293_0; // U2 |
|
|
|
static ads1293_t m_ads1293_1; // U3 |
|
|
|
|
|
|
|
#define FRAME_FILTER_INDEX_NUM 10 |
|
|
|
static bool m_ads1293_driver_is_inited = false; // 驱动是否初始化 |
|
|
|
static uint32_t m_frame_index; // 当前采集的帧号 |
|
|
|
static uint32_t m_frame_filter_index; // 过滤帧数,每次启动采集后,过滤掉的帧数 |
|
|
|
static bool m_work_flag; // 当前是否在采集 |
|
|
|
|
|
|
|
// 采样数据缓存,用于触发大数据写入服务 |
|
|
|
static uint8_t m_frame_buffer_a[HEART_WAVE_SAMPLE_SERVICE_CACHE_SIZE]; |
|
|
|
static uint8_t m_frame_buffer_b[HEART_WAVE_SAMPLE_SERVICE_CACHE_SIZE]; |
|
|
|
static uint8_t* m_frame_buffer; |
|
|
|
static uint8_t *m_frame_buffer; |
|
|
|
static int32_t m_frame_buffer_index; |
|
|
|
|
|
|
|
// 小包采样数据缓存,用于触发实时上报逻辑使用 |
|
|
|
static one_frame_data_t m_sensor_little_frame_cache[LITTLE_DATA_BLOCK_FRAME_NUM]; |
|
|
|
static uint32_t m_little_frame_index; |
|
|
|
|
|
|
@ -71,18 +53,22 @@ static uint8_t m_lodstate1; |
|
|
|
volatile static bool m_drop_state_triggered = false; |
|
|
|
|
|
|
|
/******************************************************************************* |
|
|
|
* CONFIG * |
|
|
|
*******************************************************************************/ |
|
|
|
#include "heart_wave_sample_service_cfg.h" |
|
|
|
|
|
|
|
/******************************************************************************* |
|
|
|
* 函数声明 * |
|
|
|
*******************************************************************************/ |
|
|
|
|
|
|
|
// READY_PIN 中断回调函数 |
|
|
|
// static void ads1293_ready_pin_irq(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action); |
|
|
|
// 缓冲区切换BUFFER |
|
|
|
static void prvf_buffer_switch(void); |
|
|
|
static void ads1293_ready_pin_irq(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action); |
|
|
|
static void pFrameBufferAB_switch(void); |
|
|
|
void ads1293_sample_one_frame(); |
|
|
|
|
|
|
|
/******************************************************************************* |
|
|
|
* FUNCTION * |
|
|
|
* frame_buffer操作 * |
|
|
|
*******************************************************************************/ |
|
|
|
static void prvf_buffer_switch(void) { |
|
|
|
static void pFrameBufferAB_switch(void) { |
|
|
|
if (m_frame_buffer == m_frame_buffer_a) { |
|
|
|
m_frame_buffer = m_frame_buffer_b; |
|
|
|
m_frame_buffer_index = 0; |
|
|
@ -92,14 +78,14 @@ static void prvf_buffer_switch(void) { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
static inline bool prvf_buffer_is_full(void) { |
|
|
|
static inline bool pFrameBufferAB_is_full(void) { |
|
|
|
if (m_frame_buffer_index >= HEART_WAVE_SAMPLE_SERVICE_CACHE_SIZE) { |
|
|
|
return true; |
|
|
|
} |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
static inline void prvf_buffer_push_one_byte(uint8_t byte) { |
|
|
|
static inline void pFrameBufferAB_push_one_byte(uint8_t byte) { |
|
|
|
if (m_frame_buffer_index >= HEART_WAVE_SAMPLE_SERVICE_CACHE_SIZE) { |
|
|
|
return; |
|
|
|
} |
|
|
@ -107,15 +93,11 @@ static inline void prvf_buffer_push_one_byte(uint8_t byte) { |
|
|
|
m_frame_buffer_index++; |
|
|
|
} |
|
|
|
|
|
|
|
static inline void prvf_trigger_capture_data_block_event(uint8_t* data, int datalen) { |
|
|
|
static app_event_t event; |
|
|
|
event.eventType = kevent_capture_data_block_event; |
|
|
|
event.val.block_sensor_data.data = data; |
|
|
|
event.val.block_sensor_data.len = datalen; |
|
|
|
AppEvent_pushEvent(&event); |
|
|
|
} |
|
|
|
/******************************************************************************* |
|
|
|
* LittleDataBuffer操作 * |
|
|
|
*******************************************************************************/ |
|
|
|
|
|
|
|
static inline void prvf_little_block_cache_push_one_frame(uint32_t data0, uint32_t data1, uint32_t data2) { |
|
|
|
static inline void pLittleBlockCache_push_one_frame(uint32_t data0, uint32_t data1, uint32_t data2) { |
|
|
|
if (m_little_frame_index >= LITTLE_DATA_BLOCK_FRAME_NUM) { |
|
|
|
return; |
|
|
|
} |
|
|
@ -125,14 +107,27 @@ static inline void prvf_little_block_cache_push_one_frame(uint32_t data0, uint32 |
|
|
|
m_little_frame_index++; |
|
|
|
} |
|
|
|
|
|
|
|
static inline bool prvf_light_block_cache_is_full(void) { |
|
|
|
static inline bool pLittleBlockCache_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 inline void pLittleBlockCache_reset(void) { m_little_frame_index = 0; } |
|
|
|
|
|
|
|
/******************************************************************************* |
|
|
|
* 事件操作辅助方法 * |
|
|
|
*******************************************************************************/ |
|
|
|
|
|
|
|
static inline void pEventHelper_trigger_capture_data_block_event(uint8_t *data, int datalen) { |
|
|
|
static app_event_t event; |
|
|
|
event.eventType = kevent_capture_data_block_event; |
|
|
|
event.val.block_sensor_data.data = data; |
|
|
|
event.val.block_sensor_data.len = datalen; |
|
|
|
AppEvent_pushEvent(&event); |
|
|
|
} |
|
|
|
|
|
|
|
static inline void pEventHelper_trigger_little_block_data_event() { |
|
|
|
static app_event_t event; |
|
|
|
event.eventType = kevent_capture_little_data_block_event; |
|
|
|
// memcpy(event.val.little_data_block.data, m_sensor_little_frame_cache, LITTLE_DATA_BLOCK_FRAME_NUM * sizeof(one_frame_data_t)); |
|
|
@ -150,7 +145,7 @@ static inline void prvf_light_block_trigger_event() { |
|
|
|
AppEvent_pushEvent(&event); |
|
|
|
} |
|
|
|
|
|
|
|
static inline void prvf_trigger_sensor_drop_event(uint8_t drop0, uint8_t drop1) { |
|
|
|
static inline void pEventHelper_trigger_sensor_drop_event(uint8_t drop0, uint8_t drop1) { |
|
|
|
static app_event_t event; |
|
|
|
event.eventType = kevent_sensor_drop; |
|
|
|
event.val.sensor_drop.drop0 = drop0; |
|
|
@ -158,26 +153,27 @@ static inline void prvf_trigger_sensor_drop_event(uint8_t drop0, uint8_t drop1) |
|
|
|
AppEvent_pushEvent(&event); |
|
|
|
} |
|
|
|
|
|
|
|
static void ads1293_spi_tx_rx_0(uint8_t* tx, uint8_t* rx, uint8_t len) { |
|
|
|
/******************************************************************************* |
|
|
|
* ADS驱动程序 * |
|
|
|
*******************************************************************************/ |
|
|
|
static void ads1293_spi_tx_rx_0(uint8_t *tx, uint8_t *rx, uint8_t len) { |
|
|
|
if (!m_ads1293_driver_is_inited) { |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
nrf_gpio_pin_clear(ADS1293_SPI_CS0_PIN); |
|
|
|
nrf_drv_spi_transfer(&spi, tx, len, rx, len); |
|
|
|
nrf_gpio_pin_set(ADS1293_SPI_CS0_PIN); |
|
|
|
} |
|
|
|
static void ads1293_spi_tx_rx_1(uint8_t* tx, uint8_t* rx, uint8_t len) { |
|
|
|
static void ads1293_spi_tx_rx_1(uint8_t *tx, uint8_t *rx, uint8_t len) { |
|
|
|
if (!m_ads1293_driver_is_inited) { |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
nrf_gpio_pin_clear(ADS1293_SPI_CS1_PIN); |
|
|
|
nrf_drv_spi_transfer(&spi, tx, len, rx, len); |
|
|
|
nrf_gpio_pin_set(ADS1293_SPI_CS1_PIN); |
|
|
|
} |
|
|
|
|
|
|
|
static void ads1293_spi_writereg_and_check(ads1293_t* ads, uint8_t addr, uint8_t data) { |
|
|
|
static void ads1293_spi_writereg_and_check(ads1293_t *ads, uint8_t addr, uint8_t data) { |
|
|
|
uint8_t readbak = 0; |
|
|
|
// readonly add |
|
|
|
readbak = data; |
|
|
@ -199,12 +195,15 @@ static void ads1293_spi_writereg_and_check(ads1293_t* ads, uint8_t addr, uint8_t |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
static void tryloadcfg_from_fatfs(const char* file, adscfg_t* cfg, uint16_t cfgsize, uint16_t* cfg_ret_size) { |
|
|
|
/******************************************************************************* |
|
|
|
* 配置读取方法 * |
|
|
|
*******************************************************************************/ |
|
|
|
static void tryloadcfg_from_fatfs(const char *file, adscfg_t *cfg, uint16_t cfgsize, uint16_t *cfg_ret_size) { |
|
|
|
// |
|
|
|
*cfg_ret_size = 0; |
|
|
|
|
|
|
|
static FIL fd; |
|
|
|
FRESULT ff_result = f_open(&fd, (const TCHAR*)file, FA_READ); |
|
|
|
FRESULT ff_result = f_open(&fd, (const TCHAR *)file, FA_READ); |
|
|
|
if (ff_result != FR_OK) { |
|
|
|
ZLOGE("open %s failed\n", file); |
|
|
|
return; |
|
|
@ -231,6 +230,56 @@ static void tryloadcfg_from_fatfs(const char* file, adscfg_t* cfg, uint16_t cfgs |
|
|
|
f_close(&fd); |
|
|
|
} |
|
|
|
|
|
|
|
static void ads1293_load_cfg(ads1293_t *ads) { |
|
|
|
char *cfgfile = NULL; |
|
|
|
adscfg_t *defaultCfg = NULL; |
|
|
|
uint16_t defaultCfgSize = 0; |
|
|
|
static adscfg_t cfg_cache[65]; |
|
|
|
|
|
|
|
if (ads == &m_ads1293_0) { |
|
|
|
cfgfile = "0.cfg"; |
|
|
|
} else { |
|
|
|
cfgfile = "1.cfg"; |
|
|
|
} |
|
|
|
|
|
|
|
if (ads == &m_ads1293_0) { |
|
|
|
defaultCfg = m_prvads0cfg; |
|
|
|
defaultCfgSize = ZARRAY_SIZE(m_prvads0cfg); |
|
|
|
} else { |
|
|
|
defaultCfg = m_prvads1cfg; |
|
|
|
defaultCfgSize = ZARRAY_SIZE(m_prvads1cfg); |
|
|
|
} |
|
|
|
|
|
|
|
uint16_t cfgsize = 0; |
|
|
|
tryloadcfg_from_fatfs(cfgfile, cfg_cache, ZARRAY_SIZE(cfg_cache), &cfgsize); |
|
|
|
if (cfgsize != defaultCfgSize) { |
|
|
|
ZLOGI("ads_%d load %s from fatfs\n", ads->id, cfgfile); |
|
|
|
if (memcmp(cfg_cache, defaultCfg, defaultCfgSize) != 0) { |
|
|
|
ZLOGI("ads_%d %s is different from default", ads->id, cfgfile); |
|
|
|
} else { |
|
|
|
ZLOGI("ads_%d %s is same as default", ads->id, cfgfile); |
|
|
|
} |
|
|
|
for (uint16_t i = 0; i < cfgsize; i++) { |
|
|
|
ads1293_spi_writereg_and_check(&m_ads1293_0, cfg_cache[i].add, cfg_cache[i].data); |
|
|
|
} |
|
|
|
} else { |
|
|
|
ZLOGI("ads_%d load cfg from default\n", ads->id); |
|
|
|
for (uint16_t i = 0; i < ZARRAY_SIZE(m_prvads0cfg); i++) { |
|
|
|
ads1293_spi_writereg_and_check(&m_ads1293_0, m_prvads0cfg[i].add, m_prvads0cfg[i].data); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
#if GPIO_IRQ_TRIGGER_MODE |
|
|
|
static void ads1293_ready_pin_irq(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action) { // |
|
|
|
ads1293_sample_one_frame(); |
|
|
|
} |
|
|
|
#else |
|
|
|
void nrfx_timer_event_handler(nrf_timer_event_t event_type, void *p_context) { // |
|
|
|
ads1293_sample_one_frame(); |
|
|
|
} |
|
|
|
#endif |
|
|
|
|
|
|
|
static void ads1293_init() { |
|
|
|
/******************************************************************************* |
|
|
|
* SPI初始化 * |
|
|
@ -258,6 +307,9 @@ static void ads1293_init() { |
|
|
|
ads1293_spi_init(&m_ads1293_0, ads1293_spi_tx_rx_0); |
|
|
|
ads1293_spi_init(&m_ads1293_1, ads1293_spi_tx_rx_1); |
|
|
|
|
|
|
|
ads1293_spi_writereg(&m_ads1293_0, TI_ADS1293_CONFIG_REG, 0); |
|
|
|
ads1293_spi_writereg(&m_ads1293_1, TI_ADS1293_CONFIG_REG, 0); |
|
|
|
|
|
|
|
m_ads1293_driver_is_inited = true; |
|
|
|
|
|
|
|
uint8_t revid = ads1293_spi_readreg(&m_ads1293_0, TI_ADS1293_REVID_REG); |
|
|
@ -267,66 +319,13 @@ static void ads1293_init() { |
|
|
|
|
|
|
|
ads1293_spi_writereg(&m_ads1293_0, TI_ADS1293_CONFIG_REG, 0); |
|
|
|
|
|
|
|
uint16_t cfgsize = 0; |
|
|
|
tryloadcfg_from_fatfs("0.cfg", m_prvads0cfg_cache, ZARRAY_SIZE(m_prvads0cfg_cache), &cfgsize); |
|
|
|
if (cfgsize > 0) { |
|
|
|
ZLOGI("load 0.cfg from fatfs\n"); |
|
|
|
|
|
|
|
if (memcmp(m_prvads0cfg_cache, m_prvads0cfg, sizeof(m_prvads0cfg)) != 0) { |
|
|
|
ZLOGI("0.cfg is different from default\n"); |
|
|
|
} else { |
|
|
|
ZLOGI("0.cfg is same as default\n"); |
|
|
|
} |
|
|
|
|
|
|
|
for (uint16_t i = 0; i < cfgsize; i++) { |
|
|
|
ads1293_spi_writereg_and_check(&m_ads1293_0, m_prvads0cfg_cache[i].add, m_prvads0cfg_cache[i].data); |
|
|
|
} |
|
|
|
} else { |
|
|
|
for (uint16_t i = 0; i < ZARRAY_SIZE(m_prvads0cfg); i++) { |
|
|
|
ads1293_spi_writereg_and_check(&m_ads1293_0, m_prvads0cfg[i].add, m_prvads0cfg[i].data); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
tryloadcfg_from_fatfs("1.cfg", m_prvads1cfg_cache, ZARRAY_SIZE(m_prvads1cfg_cache), &cfgsize); |
|
|
|
if (cfgsize > 0) { |
|
|
|
ZLOGI("load 1.cfg from fatfs\n"); |
|
|
|
|
|
|
|
if (memcmp(m_prvads1cfg_cache, m_prvads1cfg, sizeof(m_prvads1cfg)) != 0) { |
|
|
|
ZLOGI("1.cfg is different from default\n"); |
|
|
|
} else { |
|
|
|
ZLOGI("1.cfg is same as default\n"); |
|
|
|
} |
|
|
|
|
|
|
|
for (uint16_t i = 0; i < cfgsize; i++) { |
|
|
|
ads1293_spi_writereg_and_check(&m_ads1293_1, m_prvads1cfg_cache[i].add, m_prvads1cfg_cache[i].data); |
|
|
|
} |
|
|
|
} else { |
|
|
|
for (uint16_t i = 0; i < ZARRAY_SIZE(m_prvads1cfg); i++) { |
|
|
|
ads1293_spi_writereg_and_check(&m_ads1293_1, m_prvads1cfg[i].add, m_prvads1cfg[i].data); |
|
|
|
} |
|
|
|
} |
|
|
|
ads1293_load_cfg(&m_ads1293_0); |
|
|
|
ads1293_load_cfg(&m_ads1293_1); |
|
|
|
|
|
|
|
/** |
|
|
|
* @brief READY引脚中断初始化 |
|
|
|
*/ |
|
|
|
{ |
|
|
|
// nrf_gpio_cfg_input(ADS1293_READY_PIN, NRF_GPIO_PIN_PULLUP); |
|
|
|
// ZERROR_CHECK(nrfx_gpiote_init()); |
|
|
|
// nrf_drv_gpiote_in_config_t inConfig = GPIOTE_CONFIG_IN_SENSE_TOGGLE(false); // 双边沿中断触发 |
|
|
|
// inConfig.pull = NRF_GPIO_PIN_PULLUP; // 默认上拉 |
|
|
|
// inConfig.sense = NRF_GPIOTE_POLARITY_LOTOHI; // 上升沿触发 |
|
|
|
// ZERROR_CHECK(nrfx_gpiote_in_init(ADS1293_READY_PIN, &inConfig, ads1293_ready_pin_irq)); |
|
|
|
// nrfx_gpiote_in_event_enable(ADS1293_READY_PIN, true); |
|
|
|
} |
|
|
|
|
|
|
|
{} |
|
|
|
} |
|
|
|
|
|
|
|
void ads1293_sample_one_frame(); |
|
|
|
void nrfx_timer_event_handler(nrf_timer_event_t event_type, void* p_context) { // |
|
|
|
ads1293_sample_one_frame(); |
|
|
|
} |
|
|
|
// static void ads1293_ready_pin_irq(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action) { ads1293_sample_one_frame(); } |
|
|
|
static void ads1293_sample_one_frame() { |
|
|
|
if (!m_work_flag) { |
|
|
|
return; |
|
|
@ -337,7 +336,7 @@ static void ads1293_sample_one_frame() { |
|
|
|
} |
|
|
|
m_frame_index++; |
|
|
|
// 检查缓冲区是否为空 |
|
|
|
if (!m_frame_buffer) prvf_buffer_switch(); |
|
|
|
if (!m_frame_buffer) pFrameBufferAB_switch(); |
|
|
|
|
|
|
|
static uint32_t sample[6]; |
|
|
|
ads1293_read_ecgs(&m_ads1293_0, &sample[0]); |
|
|
@ -349,7 +348,7 @@ static void ads1293_sample_one_frame() { |
|
|
|
if (!m_drop_state_triggered) { |
|
|
|
if (m_lodstate0 || m_lodstate1) { |
|
|
|
m_drop_state_triggered = true; |
|
|
|
prvf_trigger_sensor_drop_event(m_lodstate0, m_lodstate1); |
|
|
|
pEventHelper_trigger_sensor_drop_event(m_lodstate0, m_lodstate1); |
|
|
|
} |
|
|
|
} else { |
|
|
|
if (!(m_lodstate0 || m_lodstate1)) { |
|
|
@ -375,29 +374,39 @@ static void ads1293_sample_one_frame() { |
|
|
|
*/ |
|
|
|
for (int i = 0; i < 9; i++) { |
|
|
|
if (prvf_buffer_is_full()) { |
|
|
|
prvf_trigger_capture_data_block_event(m_frame_buffer, HEART_WAVE_SAMPLE_SERVICE_CACHE_SIZE); |
|
|
|
prvf_buffer_switch(); |
|
|
|
pEventHelper_trigger_capture_data_block_event(m_frame_buffer, HEART_WAVE_SAMPLE_SERVICE_CACHE_SIZE); |
|
|
|
pFrameBufferAB_switch(); |
|
|
|
} |
|
|
|
prvf_buffer_push_one_byte(cache[i]); |
|
|
|
pFrameBufferAB_push_one_byte(cache[i]); |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* @brief 缓存数据,并触发小数据块事件 |
|
|
|
*/ |
|
|
|
prvf_little_block_cache_push_one_frame(sample[SENSOR0_ID], sample[SENSOR1_ID], sample[SENSOR2_ID]); |
|
|
|
if (prvf_light_block_cache_is_full()) { |
|
|
|
prvf_light_block_trigger_event(); |
|
|
|
prvf_light_block_cache_clear(); |
|
|
|
pLittleBlockCache_push_one_frame(sample[SENSOR0_ID], sample[SENSOR1_ID], sample[SENSOR2_ID]); |
|
|
|
if (pLittleBlockCache_is_full()) { |
|
|
|
pEventHelper_trigger_little_block_data_event(); |
|
|
|
pLittleBlockCache_reset(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
static void ads1293_uninit() { |
|
|
|
hwss_stop_capture(); |
|
|
|
m_ads1293_driver_is_inited = false; |
|
|
|
hwss_stop_capture(); |
|
|
|
nrf_drv_spi_uninit(&spi); |
|
|
|
} |
|
|
|
|
|
|
|
void hwss_init(void) { |
|
|
|
#if GPIO_IRQ_TRIGGER_MODE |
|
|
|
{ |
|
|
|
nrf_gpio_cfg_input(ADS1293_READY_PIN, NRF_GPIO_PIN_PULLUP); |
|
|
|
ZERROR_CHECK(nrfx_gpiote_init()); |
|
|
|
nrf_drv_gpiote_in_config_t inConfig = GPIOTE_CONFIG_IN_SENSE_TOGGLE(false); // 双边沿中断触发 |
|
|
|
inConfig.pull = NRF_GPIO_PIN_PULLUP; // 默认上拉 |
|
|
|
inConfig.sense = NRF_GPIOTE_POLARITY_HITOLO; // 下降沿触发 |
|
|
|
ZERROR_CHECK(nrfx_gpiote_in_init(ADS1293_READY_PIN, &inConfig, ads1293_ready_pin_irq)); |
|
|
|
} |
|
|
|
#else |
|
|
|
/** |
|
|
|
* @brief 初始化定时器 |
|
|
|
*/ |
|
|
@ -421,32 +430,68 @@ void hwss_init(void) { |
|
|
|
ZASSERT(timer_ticks % 2 == 0); // |
|
|
|
timer_ticks = timer_ticks / 2; // 400HZ |
|
|
|
nrfx_timer_extended_compare(&m_timer, NRF_TIMER_CC_CHANNEL0, timer_ticks, NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK, true); |
|
|
|
#endif |
|
|
|
} |
|
|
|
|
|
|
|
void hwss_load(void) { ads1293_init(); } |
|
|
|
void hwss_unload(void) { |
|
|
|
nrfx_timer_disable(&m_timer); |
|
|
|
ads1293_uninit(); |
|
|
|
} |
|
|
|
void hwss_unload(void) { ads1293_uninit(); } |
|
|
|
|
|
|
|
void hwss_start_capture(void) { |
|
|
|
m_drop_state_triggered = false; |
|
|
|
m_work_flag = true; |
|
|
|
m_frame_index = 0; |
|
|
|
m_frame_filter_index = 0; |
|
|
|
prvf_light_block_cache_clear(); |
|
|
|
ads1293_start_conversion(&m_ads1293_0); |
|
|
|
ads1293_start_conversion(&m_ads1293_1); |
|
|
|
pLittleBlockCache_reset(); |
|
|
|
// ads1293_start_conversion(&m_ads1293_0); |
|
|
|
// ads1293_start_conversion(&m_ads1293_1); |
|
|
|
|
|
|
|
{ |
|
|
|
// 两通道同时开始采集 |
|
|
|
nrf_gpio_pin_clear(ADS1293_SPI_CS0_PIN); |
|
|
|
nrf_gpio_pin_clear(ADS1293_SPI_CS1_PIN); |
|
|
|
|
|
|
|
uint8_t txcache[2]; |
|
|
|
txcache[0] = ADS1293_WRITE_BIT & TI_ADS1293_CONFIG_REG; |
|
|
|
txcache[1] = 0x01; |
|
|
|
nrf_drv_spi_transfer(&spi, txcache, 2, NULL, 0); |
|
|
|
|
|
|
|
nrf_gpio_pin_set(ADS1293_SPI_CS0_PIN); |
|
|
|
nrf_gpio_pin_set(ADS1293_SPI_CS1_PIN); |
|
|
|
} |
|
|
|
|
|
|
|
#if GPIO_IRQ_TRIGGER_MODE |
|
|
|
nrfx_gpiote_in_event_enable(ADS1293_READY_PIN, true); |
|
|
|
#else |
|
|
|
nrfx_timer_enable(&m_timer); |
|
|
|
#endif |
|
|
|
} |
|
|
|
void hwss_stop_capture(void) { |
|
|
|
#if GPIO_IRQ_TRIGGER_MODE |
|
|
|
nrfx_gpiote_in_event_enable(ADS1293_READY_PIN, false); |
|
|
|
#else |
|
|
|
nrfx_timer_disable(&m_timer); |
|
|
|
#endif |
|
|
|
|
|
|
|
m_work_flag = false; |
|
|
|
m_frame_index = 0; |
|
|
|
m_frame_filter_index = 0; |
|
|
|
prvf_light_block_cache_clear(); |
|
|
|
ads1293_stop_conversion(&m_ads1293_0); |
|
|
|
ads1293_stop_conversion(&m_ads1293_1); |
|
|
|
pLittleBlockCache_reset(); |
|
|
|
// ads1293_stop_conversion(&m_ads1293_0); |
|
|
|
// ads1293_stop_conversion(&m_ads1293_1); |
|
|
|
|
|
|
|
{ |
|
|
|
// 两通道同时进入低功耗 |
|
|
|
nrf_gpio_pin_clear(ADS1293_SPI_CS0_PIN); |
|
|
|
nrf_gpio_pin_clear(ADS1293_SPI_CS1_PIN); |
|
|
|
|
|
|
|
uint8_t txcache[2]; |
|
|
|
txcache[0] = ADS1293_WRITE_BIT & TI_ADS1293_CONFIG_REG; |
|
|
|
txcache[1] = 0x04; |
|
|
|
nrf_drv_spi_transfer(&spi, txcache, 2, NULL, 0); |
|
|
|
|
|
|
|
nrf_gpio_pin_set(ADS1293_SPI_CS0_PIN); |
|
|
|
nrf_gpio_pin_set(ADS1293_SPI_CS1_PIN); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
bool hwss_is_capturing(void) { return m_work_flag; } |
|
|
|