|
|
#include "ads129x.h"
#include "ads129x_type.h"
#include "nrf_drv_gpiote.h"
#include "znordic.h"
/**
* @brief ads129x ʹ��ע������ * * ads129x SPI ͨ�Ÿ�ʽ * * [cmd 8bit] [data nbit] * * * ads129x ֧�ֵ�ָ������ * ���� (0x02) * ���� (0x04) * ��λ (0x06) * ��ʼת�� (0x08) * ֹͣ (0x0A) * ͨ��ƫ��У (0x1A) * ʹ������������ģʽ (0x10) * ֹͣ����������ģʽ (0x11) * ������ (0x12) * ���Ĵ��� (0x2x) * д�Ĵ��� (0x4x) * * * ע������: * 1. ��ads129x����������ģʽ�£��Ĵ�����дָ��ʧЧ * 2. ����������ģʽ�£�����ͨ��[������]ָ���ȡ���ݣ���ʱ�Ĵ�������ָ������Ч�� * */
static ads129x_cfg_t* ads129x_cfg;
#define ADS129X_CS_SET() nrf_gpio_pin_set(ads129x_cfg->cspin);
#define ADS129X_CS_RESET() nrf_gpio_pin_clear(ads129x_cfg->cspin);
#define ADS129X_START_SET() nrf_gpio_pin_set(ads129x_cfg->startpin);
#define ADS129X_START_RESET() nrf_gpio_pin_clear(ads129x_cfg->startpin);
#define ADS129X_REST_SET() nrf_gpio_pin_set(ads129x_cfg->pwdnpin);
#define ADS129X_REST_RESET() nrf_gpio_pin_clear(ads129x_cfg->pwdnpin);
#define ADS129X_DRDY_GET() nrf_gpio_pin_read(ads129x_cfg->drdypin)
static void port_ads129x_delay_us(uint32_t us) { nrf_delay_us(us); } static void port_ads129x_delay_ms(uint32_t ms) { nrf_delay_ms(ms); }
#define port_delay_ms port_ads129x_delay_ms
/***********************************************************************************************************************
* BASE_FUNCTION_IMPL * ***********************************************************************************************************************/
uint8_t port_spi_transmit_receive(uint8_t tx) { uint8_t data; nrf_drv_spi_transfer(ads129x_cfg->spi, &tx, 1, &data, 1); return data; }
/* ads129X����ָ�� */ uint8_t ads129x_send_cmd(uint8_t cmd) { uint8_t rx = 0;
ADS129X_CS_RESET(); /* ѡ���豸 */ port_ads129x_delay_us(100);
rx = port_spi_transmit_receive(cmd);
port_ads129x_delay_us(100); ADS129X_CS_SET(); /* �ͷ��豸 */
return rx; }
/* ads129X��д�Ĵ������Զ�����ָ���������ֶ���д���� */ uint8_t ads129x_rw_reg(uint8_t cmd, uint8_t data) { uint8_t rx = 0;
ADS129X_CS_RESET(); /* ѡ���豸 */ port_ads129x_delay_us(1);
port_spi_transmit_receive(cmd); /* ���Ͷ�дָ�� */ port_spi_transmit_receive(0X00); /* ֻдһ������ */
if ((cmd & ADS129X_COMMAND_RREG) == ADS129X_COMMAND_RREG) /* �ж�ָ������ */ rx = port_spi_transmit_receive(0X00); /* ���ؼĴ���ֵ */ else rx = port_spi_transmit_receive(data); /* д����ֵ */
port_ads129x_delay_us(1); ADS129X_CS_SET(); /* �ͷ��豸 */
return rx; }
/* ��ָ���Ĵ�����ʼ��дһ�������ļĴ��� */ void ads129X_write_multiregs(uint8_t reg, uint8_t* ch, uint8_t size) { uint8_t i;
ADS129X_CS_RESET(); /* ѡ���豸 */ port_ads129x_delay_us(100);
port_spi_transmit_receive(ADS129X_COMMAND_WREG | reg); port_ads129x_delay_us(100); port_spi_transmit_receive(size - 1);
for (i = 0; i < size; i++) { port_ads129x_delay_us(100); port_spi_transmit_receive(*ch); ch++; }
port_ads129x_delay_us(100); ADS129X_CS_SET(); }
/* ��ָ���Ĵ�����ʼ��дһ�������ļĴ��� */ void ads129X_read_multiregs(uint8_t reg, uint8_t* ch, uint8_t size) { uint8_t i;
ADS129X_CS_RESET(); /* ѡ���豸 */ port_ads129x_delay_us(100);
port_spi_transmit_receive(ADS129X_COMMAND_RREG | reg); port_ads129x_delay_us(100); port_spi_transmit_receive(size - 1);
for (i = 0; i < size; i++) { port_ads129x_delay_us(100); *ch = port_spi_transmit_receive(0); ch++; }
port_ads129x_delay_us(100); ADS129X_CS_SET(); }
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); ZLOGI("loff : %x", regcache->loff); ZLOGI("ch1set : %x", regcache->ch1set); ZLOGI("ch2set : %x", regcache->ch2set); ZLOGI("rld_sens : %x", regcache->rld_sens); ZLOGI("loff_sens : %x", regcache->loff_sens); ZLOGI("loff_stat : %x", regcache->loff_stat); ZLOGI("resp1 : %x", regcache->resp1); ZLOGI("resp2 : %x", regcache->resp2); ZLOGI("gpio : %x", regcache->gpio); }
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));
writeval->id = 0; writeval->loff_stat = writeval->loff_stat & (0x01 << 6);
rdbak.id = 0; rdbak.loff_stat = rdbak.loff_stat & (0x01 << 6);
if (memcmp(writeval, &rdbak, sizeof(ads129x_regs_t)) != 0) { ZLOGE("ads129x_write_reg reg fail"); return false; } ZLOGI("ads129x_write_reg reg success"); return true; }
/***********************************************************************************************************************
* EXTERN * ***********************************************************************************************************************/ void ads129x_read_data_loop() { // app_timer_pause();
// ads129x_capture_data_t capture_data;
// while (true) {
// ads129x_read_data(&capture_data);
// ZLOGI("%d {%d} %x", ADS129X_DRDY_GET(), capture_data.ch1data, capture_data.loffstate);
// znordic_force_flush_log();
// }
}
uint8_t ads129x_init(ads129x_cfg_t* cfg) { /**
* @brief */ ads129x_cfg = cfg; ZASSERT(nrfx_gpiote_is_init());
ADS129X_CS_SET();
ADS129X_REST_RESET(); ADS129X_START_RESET(); port_ads129x_delay_ms(1000); ADS129X_REST_SET(); port_ads129x_delay_ms(100); /* Ӳ����λ */
ads129x_send_cmd(ADS129X_COMMAND_SDATAC); /* ������λ����ֹͣ������״̬ */ port_ads129x_delay_ms(100); ads129x_send_cmd(ADS129X_COMMAND_RESET); port_ads129x_delay_ms(1000); ads129x_send_cmd(ADS129X_COMMAND_SDATAC); port_ads129x_delay_ms(100);
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; ads129x_write_regs(®cache);
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) { ZLOGI("ads129x_write_reg %x %x", add, data); static ads129x_regs_t regcache; ads129x_readback_regs(®cache); uint8_t* reg = (uint8_t*)®cache; reg[add] = data; ads129x_write_regs(®cache); }
uint8_t ads129x_start_capture() { ads129x_send_cmd(ADS129X_COMMAND_START); /* ���Ϳ�ʼ����ת������Ч������START���ţ� */ return 0; }
uint8_t ads129x_stop_capture() { ads129x_send_cmd(ADS129X_COMMAND_STOP); /* ����ֹͣ����ת������Ч������START���ţ� */ return 0; }
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) { rev |= 0xFF000000; } return rev; }
void ads129x_read_data(ads129x_capture_data_t* capture_data) { uint8_t rddata[9];
ADS129X_CS_RESET(); /* ѡ���豸 */ port_ads129x_delay_us(10);
port_spi_transmit_receive(ADS129X_COMMAND_RDATA); port_ads129x_delay_us(1); for (int i = 0; i < 9; i++) { rddata[i] = port_spi_transmit_receive(0); } ADS129X_CS_SET();
/**
* @brief * * �ض����ݸ�ʽ(datasheet page 42) * 24bit status (1100 + LOFF_STAT[4:0] + GPIO[1:0] + 13`b0) * 24bit ch0 MSB * 24bit ch1 MSB * */ uint32_t status = (((uint32_t)rddata[0]) << 16) | (((uint32_t)rddata[1]) << 8) | ((uint32_t)rddata[2]);
capture_data->loffstate = (status >> (13 + 2)) & 0x1f; capture_data->gpio0 = status >> (14); capture_data->gpio1 = status >> (13);
capture_data->ch1data = i24toi32(&rddata[3]); capture_data->ch2data = i24toi32(&rddata[6]); }
uint8_t ads129x_get_lead_off_state() { // FLIP2,FLIP1,LOFF2N,LOFF2P,LOFF1N,LOFF1P
uint8_t leadoffstate = ads129x_read_reg(ADS129X_REG_LOFFSTAT); return leadoffstate; }
uint8_t ads129x_enter_low_power_mode() { return 0; } uint8_t ads129x_enter_lead_off_detect_mode() { return 0; }
|