|
|
@ -12,36 +12,19 @@ |
|
|
|
|
|
|
|
static nrf_drv_spi_t ads129x_spi = NRF_DRV_SPI_INSTANCE(ADS1291_SPI_INSTANCE); // global |
|
|
|
static nrf_drv_spi_config_t ads129x_spi_config; |
|
|
|
|
|
|
|
// uint8_t port_spi_transmit_receive(uint8_t tx); |
|
|
|
// int32_t i24toi32(uint8_t* p_i32); |
|
|
|
// uint8_t ads129x_send_cmd(uint8_t cmd); |
|
|
|
// uint8_t ads129x_rw_reg(uint8_t cmd, uint8_t data); |
|
|
|
// void ads129x_write_multiregs(uint8_t reg, uint8_t* ch, uint8_t size); |
|
|
|
// void ads129x_read_multiregs(uint8_t reg, uint8_t* ch, uint8_t size); |
|
|
|
// void ads129x_readback_regs(ads129x_regs_t* regcache); |
|
|
|
// void ads129x_dump_regs(ads129x_regs_t* regcache); |
|
|
|
// bool ads129x_write_regs(ads129x_regs_t* writeval); |
|
|
|
// void ads129x_read_data(ads129x_capture_data_t* capture_data); |
|
|
|
static bool m_testmode_flag; |
|
|
|
|
|
|
|
/*********************************************************************************************************************** |
|
|
|
* PRIVATE_FUNC * |
|
|
|
***********************************************************************************************************************/ |
|
|
|
|
|
|
|
#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) |
|
|
|
uint8_t port_spi_transmit_receive(uint8_t tx) { |
|
|
|
static uint8_t port_spi_transmit_receive(uint8_t tx) { |
|
|
|
uint8_t data; |
|
|
|
nrf_drv_spi_transfer(&ads129x_spi, &tx, 1, &data, 1); |
|
|
|
return data; |
|
|
|
} |
|
|
|
|
|
|
|
int32_t i24toi32(uint8_t* p_i32) { |
|
|
|
static int32_t i24toi32(uint8_t* p_i32) { |
|
|
|
int32_t rev = 0; |
|
|
|
rev = (((int32_t)p_i32[0]) << 16) | (((int32_t)p_i32[1]) << 8) | ((int32_t)p_i32[2]); |
|
|
|
if ((p_i32[0] & 0x80) == 0x80) { |
|
|
@ -51,25 +34,25 @@ int32_t i24toi32(uint8_t* p_i32) { |
|
|
|
} |
|
|
|
|
|
|
|
/* ads129X发送指令 */ |
|
|
|
uint8_t ads129x_send_cmd(uint8_t cmd) { |
|
|
|
static uint8_t ads129x_send_cmd(uint8_t cmd) { |
|
|
|
uint8_t rx = 0; |
|
|
|
|
|
|
|
ADS129X_CS_RESET(); /* 选中设备 */ |
|
|
|
nrf_gpio_pin_clear(ADS1291_SPI_CS0_PIN); /* 选中设备 */ |
|
|
|
nrf_delay_us(100); |
|
|
|
|
|
|
|
rx = port_spi_transmit_receive(cmd); |
|
|
|
|
|
|
|
nrf_delay_us(100); |
|
|
|
ADS129X_CS_SET(); /* 释放设备 */ |
|
|
|
nrf_gpio_pin_set(ADS1291_SPI_CS0_PIN); /* 释放设备 */ |
|
|
|
|
|
|
|
return rx; |
|
|
|
} |
|
|
|
|
|
|
|
/* ads129X读写寄存器,自动根据指令类型区分读和写操作 */ |
|
|
|
uint8_t ads129x_rw_reg(uint8_t cmd, uint8_t data) { |
|
|
|
static uint8_t ads129x_rw_reg(uint8_t cmd, uint8_t data) { |
|
|
|
uint8_t rx = 0; |
|
|
|
|
|
|
|
ADS129X_CS_RESET(); /* 选中设备 */ |
|
|
|
nrf_gpio_pin_clear(ADS1291_SPI_CS0_PIN); /* 选中设备 */ |
|
|
|
nrf_delay_us(1); |
|
|
|
|
|
|
|
port_spi_transmit_receive(cmd); /* 发送读写指令 */ |
|
|
@ -81,16 +64,16 @@ uint8_t ads129x_rw_reg(uint8_t cmd, uint8_t data) { |
|
|
|
rx = port_spi_transmit_receive(data); /* 写入数值 */ |
|
|
|
|
|
|
|
nrf_delay_us(1); |
|
|
|
ADS129X_CS_SET(); /* 释放设备 */ |
|
|
|
nrf_gpio_pin_set(ADS1291_SPI_CS0_PIN); /* 释放设备 */ |
|
|
|
|
|
|
|
return rx; |
|
|
|
} |
|
|
|
|
|
|
|
/* 从指定寄存器开始读写一定数量的寄存器 */ |
|
|
|
void ads129x_write_multiregs(uint8_t reg, uint8_t* ch, uint8_t size) { |
|
|
|
static void ads129x_write_multiregs(uint8_t reg, uint8_t* ch, uint8_t size) { |
|
|
|
uint8_t i; |
|
|
|
|
|
|
|
ADS129X_CS_RESET(); /* 选中设备 */ |
|
|
|
nrf_gpio_pin_clear(ADS1291_SPI_CS0_PIN); /* 选中设备 */ |
|
|
|
nrf_delay_us(100); |
|
|
|
|
|
|
|
port_spi_transmit_receive(ADS129X_COMMAND_WREG | reg); |
|
|
@ -104,14 +87,14 @@ void ads129x_write_multiregs(uint8_t reg, uint8_t* ch, uint8_t size) { |
|
|
|
} |
|
|
|
|
|
|
|
nrf_delay_us(100); |
|
|
|
ADS129X_CS_SET(); |
|
|
|
nrf_gpio_pin_set(ADS1291_SPI_CS0_PIN); |
|
|
|
} |
|
|
|
|
|
|
|
/* 从指定寄存器开始读写一定数量的寄存器 */ |
|
|
|
void ads129x_read_multiregs(uint8_t reg, uint8_t* ch, uint8_t size) { |
|
|
|
static void ads129x_read_multiregs(uint8_t reg, uint8_t* ch, uint8_t size) { |
|
|
|
uint8_t i; |
|
|
|
|
|
|
|
ADS129X_CS_RESET(); /* 选中设备 */ |
|
|
|
nrf_gpio_pin_clear(ADS1291_SPI_CS0_PIN); /* 选中设备 */ |
|
|
|
nrf_delay_us(100); |
|
|
|
|
|
|
|
port_spi_transmit_receive(ADS129X_COMMAND_RREG | reg); |
|
|
@ -125,11 +108,11 @@ void ads129x_read_multiregs(uint8_t reg, uint8_t* ch, uint8_t size) { |
|
|
|
} |
|
|
|
|
|
|
|
nrf_delay_us(100); |
|
|
|
ADS129X_CS_SET(); |
|
|
|
nrf_gpio_pin_set(ADS1291_SPI_CS0_PIN); |
|
|
|
} |
|
|
|
|
|
|
|
void ads129x_readback_regs(ads129x_regs_t* regcache) { ads129x_read_multiregs(ADS129X_REG_ID, (uint8_t*)regcache, sizeof(ads129x_regs_t)); } |
|
|
|
void ads129x_dump_regs(ads129x_regs_t* regcache) { |
|
|
|
static void ads129x_readback_regs(ads129x_regs_t* regcache) { ads129x_read_multiregs(ADS129X_REG_ID, (uint8_t*)regcache, sizeof(ads129x_regs_t)); } |
|
|
|
static void ads129x_dump_regs(ads129x_regs_t* regcache) { |
|
|
|
ZLOGI("id : %x", regcache->id); |
|
|
|
ZLOGI("cfg1 : %x", regcache->cfg1); |
|
|
|
ZLOGI("cfg2 : %x", regcache->cfg2); |
|
|
@ -144,7 +127,7 @@ void ads129x_dump_regs(ads129x_regs_t* regcache) { |
|
|
|
ZLOGI("gpio : %x", regcache->gpio); |
|
|
|
} |
|
|
|
|
|
|
|
bool ads129x_write_regs(ads129x_regs_t* writeval) { |
|
|
|
static bool ads129x_write_regs(ads129x_regs_t* writeval) { |
|
|
|
static ads129x_regs_t rdbak; |
|
|
|
ads129x_write_multiregs(ADS129X_REG_ID, (uint8_t*)writeval, sizeof(ads129x_regs_t)); |
|
|
|
ads129x_read_multiregs(ADS129X_REG_ID, (uint8_t*)&rdbak, sizeof(ads129x_regs_t)); |
|
|
@ -163,10 +146,10 @@ bool ads129x_write_regs(ads129x_regs_t* writeval) { |
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
void ads129x_read_data(ads129x_capture_data_t* capture_data) { |
|
|
|
static void ads129x_read_data(ads129x_capture_data_t* capture_data) { |
|
|
|
uint8_t rddata[9]; |
|
|
|
|
|
|
|
ADS129X_CS_RESET(); /* 选中设备 */ |
|
|
|
nrf_gpio_pin_clear(ADS1291_SPI_CS0_PIN); /* 选中设备 */ |
|
|
|
nrf_delay_us(10); |
|
|
|
|
|
|
|
port_spi_transmit_receive(ADS129X_COMMAND_RDATA); |
|
|
@ -174,7 +157,7 @@ void ads129x_read_data(ads129x_capture_data_t* capture_data) { |
|
|
|
for (int i = 0; i < 9; i++) { |
|
|
|
rddata[i] = port_spi_transmit_receive(0); |
|
|
|
} |
|
|
|
ADS129X_CS_SET(); |
|
|
|
nrf_gpio_pin_set(ADS1291_SPI_CS0_PIN); |
|
|
|
|
|
|
|
/** |
|
|
|
* @brief |
|
|
@ -195,39 +178,61 @@ void ads129x_read_data(ads129x_capture_data_t* capture_data) { |
|
|
|
capture_data->ch2data = i24toi32(&rddata[6]); |
|
|
|
} |
|
|
|
|
|
|
|
static bool ads129x_ping() { |
|
|
|
uint8_t data; |
|
|
|
ads129x_read_multiregs(ADS129X_REG_ID, (uint8_t*)&data, sizeof(uint8_t)); |
|
|
|
if (data == 0x052) { |
|
|
|
return true; |
|
|
|
} |
|
|
|
return false; |
|
|
|
} |
|
|
|
/*********************************************************************************************************************** |
|
|
|
* PUBLIC_FUNC * |
|
|
|
***********************************************************************************************************************/ |
|
|
|
|
|
|
|
void ads1291_ready_pin_irq(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action) { |
|
|
|
if (ADS129X_DRDY_GET()) { |
|
|
|
static void ads1291_ready_pin_irq(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action) { |
|
|
|
static ads129x_capture_data_t capture_data; |
|
|
|
// 读 |
|
|
|
ads129x_read_data(&capture_data); |
|
|
|
ecg_algo_process_data(capture_data.ch1data); |
|
|
|
|
|
|
|
// 算法处理 |
|
|
|
// ecg_algo_process_data(capture_data.ch1data); |
|
|
|
|
|
|
|
// 上报 |
|
|
|
one_frame_t frame; |
|
|
|
frame.data = ecg_algo_get_report_data(); |
|
|
|
// frame.data = ecg_algo_get_report_data(); |
|
|
|
frame.data = capture_data.ch1data; |
|
|
|
frame.leadoff = capture_data.loffstate; |
|
|
|
ecg_data_mgr_push_one_frame(frame); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
void ecg_service_init() { // |
|
|
|
/** |
|
|
|
* @brief |
|
|
|
* 在这里初始化一些硬件无关的内存组件 |
|
|
|
*/ |
|
|
|
|
|
|
|
ecg_data_mgr_init(); |
|
|
|
ecg_algo_init(); |
|
|
|
|
|
|
|
// 初始化部分硬件 |
|
|
|
znrf_gpio_cfg_output(ADS1291_PWDN_PIN, NRF_GPIO_PIN_NOPULL); |
|
|
|
nrf_gpio_pin_clear(ADS1291_PWDN_PIN); |
|
|
|
} |
|
|
|
|
|
|
|
void ecg_service_load() { |
|
|
|
/** |
|
|
|
* @brief 硬件接口初始化 |
|
|
|
*/ |
|
|
|
nrfx_gpiote_init(); |
|
|
|
|
|
|
|
// GPIO初始化 |
|
|
|
znrf_gpio_cfg_output(ADS1291_SPI_CS0_PIN, NRF_GPIO_PIN_NOPULL); |
|
|
|
znrf_gpio_cfg_output(ADS1291_PWDN_PIN, NRF_GPIO_PIN_NOPULL); |
|
|
|
znrf_gpio_cfg_output(ADS1291_START_PIN, NRF_GPIO_PIN_NOPULL); |
|
|
|
nrf_gpio_pin_set(ADS1291_SPI_CS0_PIN); |
|
|
|
nrf_gpio_pin_clear(ADS1291_PWDN_PIN); |
|
|
|
nrf_gpio_pin_clear(ADS1291_START_PIN); |
|
|
|
|
|
|
|
// SPI初始化 |
|
|
|
ads129x_spi_config.sck_pin = ADS1291_SPI_SCK_PIN; |
|
|
|
ads129x_spi_config.mosi_pin = ADS1291_SPI_MOSI_PIN; |
|
|
|
ads129x_spi_config.miso_pin = ADS1291_SPI_MISO_PIN; |
|
|
@ -238,11 +243,9 @@ void ecg_service_load() { |
|
|
|
ads129x_spi_config.mode = NRF_DRV_SPI_MODE_1; |
|
|
|
ads129x_spi_config.bit_order = NRF_DRV_SPI_BIT_ORDER_MSB_FIRST; |
|
|
|
nrf_drv_spi_init(&ads129x_spi, &ads129x_spi_config, NULL, NULL); |
|
|
|
znrf_gpio_cfg_output(ADS1291_SPI_CS0_PIN, NRF_GPIO_PIN_NOPULL); |
|
|
|
znrf_gpio_cfg_output(ADS1291_PWDN_PIN, NRF_GPIO_PIN_NOPULL); |
|
|
|
znrf_gpio_cfg_output(ADS1291_START_PIN, NRF_GPIO_PIN_NOPULL); |
|
|
|
|
|
|
|
ZASSERT(nrfx_gpiote_is_init()); |
|
|
|
// 中断初始化 |
|
|
|
nrfx_gpiote_init(); |
|
|
|
nrf_gpio_cfg_input(ADS1291_READY_PIN, NRF_GPIO_PIN_PULLUP); |
|
|
|
nrf_drv_gpiote_in_config_t inConfig = GPIOTE_CONFIG_IN_SENSE_TOGGLE(false); // |
|
|
|
inConfig.pull = NRF_GPIO_PIN_PULLUP; // 默认上拉 |
|
|
@ -250,40 +253,39 @@ void ecg_service_load() { |
|
|
|
nrfx_gpiote_in_init(ADS1291_READY_PIN, &inConfig, ads1291_ready_pin_irq); |
|
|
|
nrfx_gpiote_in_event_enable(ADS1291_READY_PIN, true); |
|
|
|
|
|
|
|
/** |
|
|
|
* @brief ads129x 芯片初始化 |
|
|
|
*/ |
|
|
|
|
|
|
|
ADS129X_CS_SET(); |
|
|
|
|
|
|
|
ADS129X_REST_RESET(); |
|
|
|
ADS129X_START_RESET(); |
|
|
|
nrf_delay_ms(1000); |
|
|
|
ADS129X_REST_SET(); |
|
|
|
nrf_gpio_pin_set(ADS1291_PWDN_PIN); |
|
|
|
nrf_delay_ms(30); /* 硬件复位 */ |
|
|
|
|
|
|
|
ads129x_send_cmd(ADS129X_COMMAND_WAKEUP); |
|
|
|
ads129x_send_cmd(ADS129X_COMMAND_SDATAC); /* 软件复位,并停止连续读状态 */ |
|
|
|
nrf_delay_ms(30); |
|
|
|
|
|
|
|
for (size_t i = 0; i < 100; i++) { |
|
|
|
if (ads129x_ping()) { |
|
|
|
break; |
|
|
|
} |
|
|
|
nrf_delay_ms(1); |
|
|
|
} |
|
|
|
|
|
|
|
ZASSERT(ads129x_ping()); |
|
|
|
|
|
|
|
static ads129x_regs_t regcache; |
|
|
|
ads129x_readback_regs(®cache); |
|
|
|
ads129x_dump_regs(®cache); |
|
|
|
regcache.cfg1 = 0x02; |
|
|
|
regcache.cfg2 = 0xE0; |
|
|
|
regcache.loff = 0xF0; |
|
|
|
regcache.loff = 0xF1; |
|
|
|
regcache.ch1set = 0x00; |
|
|
|
regcache.ch2set = 0x00; |
|
|
|
regcache.ch2set = 0x81; |
|
|
|
regcache.rld_sens = 0x20; |
|
|
|
regcache.loff_sens = 0x03; |
|
|
|
|
|
|
|
ads129x_write_regs(®cache); |
|
|
|
ads129x_send_cmd(ADS129X_COMMAND_WAKEUP); /* 软件复位,并停止连续读状态 */ |
|
|
|
} |
|
|
|
void ecg_service_unload() { |
|
|
|
/** |
|
|
|
* @brief |
|
|
|
*/ |
|
|
|
ads129x_send_cmd(ADS129X_COMMAND_STANDBY); /* 软件复位,并停止连续读状态 */ |
|
|
|
ADS129X_REST_RESET(); |
|
|
|
nrf_gpio_pin_clear(ADS1291_PWDN_PIN); |
|
|
|
|
|
|
|
nrfx_gpiote_in_event_disable(ADS1291_READY_PIN); |
|
|
|
|
|
|
@ -308,6 +310,19 @@ static uint32_t ecg_service_captured_time = 0; |
|
|
|
|
|
|
|
void ecg_service_start_capture() { // |
|
|
|
ecg_data_mgr_clear_buffer(); |
|
|
|
|
|
|
|
if (m_testmode_flag) { |
|
|
|
static ads129x_regs_t regcache; |
|
|
|
ads129x_readback_regs(®cache); |
|
|
|
ads129x_dump_regs(®cache); |
|
|
|
|
|
|
|
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); |
|
|
|
|
|
|
|
ads129x_write_regs(®cache); |
|
|
|
} |
|
|
|
|
|
|
|
ads129x_send_cmd(ADS129X_COMMAND_START); /* 发送开始数据转换(等效于拉高START引脚) */ |
|
|
|
ecg_service_captured_time = znordic_getpower_on_ms(); |
|
|
|
} |
|
|
@ -315,10 +330,21 @@ void ecg_service_stop_capture() { // |
|
|
|
ads129x_send_cmd(ADS129X_COMMAND_STOP); /* 发送停止数据转换(等效于拉低START引脚) */ |
|
|
|
} |
|
|
|
uint32_t ecg_service_has_captured_time() { return znordic_haspassed_ms(ecg_service_captured_time); } |
|
|
|
|
|
|
|
void ecg_service_subic_write_reg(uint8_t addr, uint8_t val) { ads129x_rw_reg(ADS129X_COMMAND_WREG | addr, val); } |
|
|
|
void ecg_service_subic_write_reg(uint8_t addr, uint8_t val) { |
|
|
|
if (addr > sizeof(ads129x_regs_t)) { |
|
|
|
return; |
|
|
|
} |
|
|
|
static ads129x_regs_t regcache; |
|
|
|
ads129x_readback_regs(®cache); |
|
|
|
uint8_t* p = (uint8_t*)®cache; |
|
|
|
p[addr] = val; |
|
|
|
ads129x_write_regs(®cache); |
|
|
|
} |
|
|
|
uint8_t ecg_service_subic_read_reg(uint8_t addr) { return ads129x_rw_reg(ADS129X_COMMAND_RREG | addr, 0); } |
|
|
|
|
|
|
|
int32_t ecg_service_get_display_val() { return ecg_algo_get_display_data(); } |
|
|
|
|
|
|
|
int32_t ecg_service_get_heart_rate() { return ecg_algo_get_heart_rate(); } |
|
|
|
|
|
|
|
void ecg_service_set_in_test_mode(bool testmode) { |
|
|
|
ZLOGI("ecg_service_set_in_test_mode %d", testmode); |
|
|
|
m_testmode_flag = testmode; |
|
|
|
} |