You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

335 lines
10 KiB

1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
  1. #include "ads129x.h"
  2. #include "ads129x_type.h"
  3. #include "nrf_drv_gpiote.h"
  4. #include "znordic.h"
  5. /**
  6. * @brief ads129x ʹע
  7. *
  8. * ads129x SPI ͨŸʽ
  9. *
  10. * [cmd 8bit] [data nbit]
  11. *
  12. *
  13. * ads129x ֵָ֧
  14. * (0x02)
  15. * (0x04)
  16. * λ (0x06)
  17. * ʼת (0x08)
  18. * ֹͣ (0x0A)
  19. * ͨƫУ׼ (0x1A)
  20. * ʹģʽ (0x10)
  21. * ֹͣģʽ (0x11)
  22. * (0x12)
  23. * Ĵ (0x2x)
  24. * дĴ (0x4x)
  25. *
  26. *
  27. * ע:
  28. * 1. ads129xģʽ£ĴдָʧЧ
  29. * 2. ģʽ£ͨ[]ָȡݣʱĴָЧ
  30. *
  31. */
  32. static ads129x_cfg_t* ads129x_cfg;
  33. #define ADS129X_CS_SET() nrf_gpio_pin_set(ads129x_cfg->cspin);
  34. #define ADS129X_CS_RESET() nrf_gpio_pin_clear(ads129x_cfg->cspin);
  35. #define ADS129X_START_SET() nrf_gpio_pin_set(ads129x_cfg->startpin);
  36. #define ADS129X_START_RESET() nrf_gpio_pin_clear(ads129x_cfg->startpin);
  37. #define ADS129X_REST_SET() nrf_gpio_pin_set(ads129x_cfg->pwdnpin);
  38. #define ADS129X_REST_RESET() nrf_gpio_pin_clear(ads129x_cfg->pwdnpin);
  39. #define ADS129X_DRDY_GET() nrf_gpio_pin_read(ads129x_cfg->drdypin)
  40. static void port_ads129x_delay_us(uint32_t us) { nrf_delay_us(us); }
  41. static void port_ads129x_delay_ms(uint32_t ms) { nrf_delay_ms(ms); }
  42. #define port_delay_ms port_ads129x_delay_ms
  43. /***********************************************************************************************************************
  44. * BASE_FUNCTION_IMPL *
  45. ***********************************************************************************************************************/
  46. uint8_t port_spi_transmit_receive(uint8_t tx) {
  47. uint8_t data;
  48. nrf_drv_spi_transfer(ads129x_cfg->spi, &tx, 1, &data, 1);
  49. return data;
  50. }
  51. /* ads129X����ָ�� */
  52. uint8_t ads129x_send_cmd(uint8_t cmd) {
  53. uint8_t rx = 0;
  54. ADS129X_CS_RESET(); /* ѡ���豸 */
  55. port_ads129x_delay_us(100);
  56. rx = port_spi_transmit_receive(cmd);
  57. port_ads129x_delay_us(100);
  58. ADS129X_CS_SET(); /* �ͷ��豸 */
  59. return rx;
  60. }
  61. /* ads129X��д�Ĵ������Զ�����ָ���������ֶ���д���� */
  62. uint8_t ads129x_rw_reg(uint8_t cmd, uint8_t data) {
  63. uint8_t rx = 0;
  64. ADS129X_CS_RESET(); /* ѡ���豸 */
  65. port_ads129x_delay_us(1);
  66. port_spi_transmit_receive(cmd); /* ���Ͷ�дָ�� */
  67. port_spi_transmit_receive(0X00); /* ֻдһ������ */
  68. if ((cmd & ADS129X_COMMAND_RREG) == ADS129X_COMMAND_RREG) /* �ж�ָ������ */
  69. rx = port_spi_transmit_receive(0X00); /* ���ؼĴ���ֵ */
  70. else
  71. rx = port_spi_transmit_receive(data); /* д����ֵ */
  72. port_ads129x_delay_us(1);
  73. ADS129X_CS_SET(); /* �ͷ��豸 */
  74. return rx;
  75. }
  76. /* ��ָ���Ĵ�����ʼ��дһ�������ļĴ��� */
  77. void ads129X_write_multiregs(uint8_t reg, uint8_t* ch, uint8_t size) {
  78. uint8_t i;
  79. ADS129X_CS_RESET(); /* ѡ���豸 */
  80. port_ads129x_delay_us(100);
  81. port_spi_transmit_receive(ADS129X_COMMAND_WREG | reg);
  82. port_ads129x_delay_us(100);
  83. port_spi_transmit_receive(size - 1);
  84. for (i = 0; i < size; i++) {
  85. port_ads129x_delay_us(100);
  86. port_spi_transmit_receive(*ch);
  87. ch++;
  88. }
  89. port_ads129x_delay_us(100);
  90. ADS129X_CS_SET();
  91. }
  92. /* ��ָ���Ĵ�����ʼ��дһ�������ļĴ��� */
  93. void ads129X_read_multiregs(uint8_t reg, uint8_t* ch, uint8_t size) {
  94. uint8_t i;
  95. ADS129X_CS_RESET(); /* ѡ���豸 */
  96. port_ads129x_delay_us(100);
  97. port_spi_transmit_receive(ADS129X_COMMAND_RREG | reg);
  98. port_ads129x_delay_us(100);
  99. port_spi_transmit_receive(size - 1);
  100. for (i = 0; i < size; i++) {
  101. port_ads129x_delay_us(100);
  102. *ch = port_spi_transmit_receive(0);
  103. ch++;
  104. }
  105. port_ads129x_delay_us(100);
  106. ADS129X_CS_SET();
  107. }
  108. static void ads129x_readback_regs(ads129x_regs_t* regcache) { ads129X_read_multiregs(ADS129X_REG_ID, (uint8_t*)regcache, sizeof(ads129x_regs_t)); }
  109. static void ads129x_dump_regs(ads129x_regs_t* regcache) {
  110. ZLOGI("id : %x", regcache->id);
  111. ZLOGI("cfg1 : %x", regcache->cfg1);
  112. ZLOGI("cfg2 : %x", regcache->cfg2);
  113. ZLOGI("loff : %x", regcache->loff);
  114. ZLOGI("ch1set : %x", regcache->ch1set);
  115. ZLOGI("ch2set : %x", regcache->ch2set);
  116. ZLOGI("rld_sens : %x", regcache->rld_sens);
  117. ZLOGI("loff_sens : %x", regcache->loff_sens);
  118. ZLOGI("loff_stat : %x", regcache->loff_stat);
  119. ZLOGI("resp1 : %x", regcache->resp1);
  120. ZLOGI("resp2 : %x", regcache->resp2);
  121. ZLOGI("gpio : %x", regcache->gpio);
  122. }
  123. static bool ads129x_write_regs(ads129x_regs_t* writeval) {
  124. static ads129x_regs_t rdbak;
  125. ads129X_write_multiregs(ADS129X_REG_ID, (uint8_t*)writeval, sizeof(ads129x_regs_t));
  126. ads129X_read_multiregs(ADS129X_REG_ID, (uint8_t*)&rdbak, sizeof(ads129x_regs_t));
  127. writeval->id = 0;
  128. writeval->loff_stat = writeval->loff_stat & (0x01 << 6);
  129. rdbak.id = 0;
  130. rdbak.loff_stat = rdbak.loff_stat & (0x01 << 6);
  131. if (memcmp(writeval, &rdbak, sizeof(ads129x_regs_t)) != 0) {
  132. ZLOGE("ads129x_write_reg reg fail");
  133. return false;
  134. }
  135. ZLOGI("ads129x_write_reg reg success");
  136. return true;
  137. }
  138. /***********************************************************************************************************************
  139. * EXTERN *
  140. ***********************************************************************************************************************/
  141. void ads129x_read_data_loop() {
  142. // app_timer_pause();
  143. // ads129x_capture_data_t capture_data;
  144. // while (true) {
  145. // ads129x_read_data(&capture_data);
  146. // ZLOGI("%d {%d} %x", ADS129X_DRDY_GET(), capture_data.ch1data, capture_data.loffstate);
  147. // znordic_force_flush_log();
  148. // }
  149. }
  150. uint8_t ads129x_init(ads129x_cfg_t* cfg) {
  151. /**
  152. * @brief
  153. */
  154. ads129x_cfg = cfg;
  155. ZASSERT(nrfx_gpiote_is_init());
  156. ADS129X_CS_SET();
  157. ADS129X_REST_RESET();
  158. ADS129X_START_RESET();
  159. port_ads129x_delay_ms(1000);
  160. ADS129X_REST_SET();
  161. port_ads129x_delay_ms(100); /* Ӳ����λ */
  162. ads129x_send_cmd(ADS129X_COMMAND_SDATAC); /* ������λ����ֹͣ������״̬ */
  163. port_ads129x_delay_ms(100);
  164. ads129x_send_cmd(ADS129X_COMMAND_RESET);
  165. port_ads129x_delay_ms(1000);
  166. ads129x_send_cmd(ADS129X_COMMAND_SDATAC);
  167. port_ads129x_delay_ms(100);
  168. static ads129x_regs_t regcache;
  169. ads129x_readback_regs(&regcache);
  170. ads129x_dump_regs(&regcache);
  171. regcache.cfg1 = 0x02;
  172. regcache.cfg2 = 0xE0;
  173. regcache.loff = 0xF0;
  174. regcache.ch1set = 0x00;
  175. regcache.ch2set = 0x00;
  176. regcache.rld_sens = 0x20;
  177. regcache.loff_sens = 0x03;
  178. ads129x_write_regs(&regcache);
  179. nrf_gpio_pin_set(ads129x_cfg->pwdnpin);
  180. return 0;
  181. }
  182. #if 0
  183. uint8_t ads129x_start_capture(bool test) {
  184. ads129x_send_cmd(ADS129X_COMMAND_SDATAC); /* ����ֹͣ������ģʽ */
  185. port_delay_ms(10);
  186. static ads129x_regs_t regcache;
  187. ads129x_readback_regs(&regcache);
  188. ads129x_dump_regs(&regcache);
  189. regcache.cfg1 = 0x02;
  190. regcache.cfg2 = 0xE0;
  191. regcache.loff = 0xF0;
  192. regcache.ch1set = 0x00;
  193. regcache.ch2set = 0x00;
  194. regcache.rld_sens = 0x20;
  195. regcache.loff_sens = 0x03;
  196. /* ���������Ƚ��������ڲ�2.42v�ο���ѹ */
  197. regcache.cfg2 = ADS129X_SET_BITS(regcache.cfg2, ADS129X_PDB_LOFF_COMP, ADS129X_PDB_LOFF_COMP_ON);
  198. regcache.cfg2 = ADS129X_SET_BITS(regcache.cfg2, ADS129X_PDB_REFBUF, ADS129X_PDB_REFBUF_ON);
  199. regcache.cfg2 = ADS129X_SET_BITS(regcache.cfg2, ADS129X_VREF_4V, ADS129X_VREF_2420MV);
  200. /* ͨ���������������⹦�ܿ� */
  201. regcache.loff_sens = ADS129X_SET_BITS(regcache.loff_sens, ADS129X_LOFF2N, ADS129X_LOFF2N_ON);
  202. regcache.loff_sens = ADS129X_SET_BITS(regcache.loff_sens, ADS129X_LOFF2P, ADS129X_LOFF2P_ON);
  203. if (test) {
  204. regcache.cfg2 = ADS129X_SET_BITS(regcache.cfg2, ADS129X_INT_TEST, ADS129X_INT_TEST_ON);
  205. regcache.cfg2 = ADS129X_SET_BITS(regcache.cfg2, ADS129X_INT_FREQ, ADS129X_INT_FREQ_AC);
  206. regcache.ch1set = ADS129X_SET_BITS(regcache.ch1set, ADS129X_MUXx, ADS129X_CHx_INPUT_TEST);
  207. regcache.ch2set = ADS129X_SET_BITS(regcache.ch2set, ADS129X_MUXx, ADS129X_CHx_INPUT_TEST);
  208. }
  209. ads129x_write_regs(&regcache);
  210. port_delay_ms(10);
  211. ads129x_send_cmd(ADS129X_COMMAND_START); /* ���Ϳ�ʼ����ת������Ч������START���ţ� */
  212. port_delay_ms(10);
  213. return 0;
  214. }
  215. #endif
  216. uint8_t ads129x_read_reg(uint8_t add) { return ads129x_rw_reg(ADS129X_COMMAND_RREG | add, 0); }
  217. void ads129x_write_reg(uint8_t add, uint8_t data) {
  218. ZLOGI("ads129x_write_reg %x %x", add, data);
  219. static ads129x_regs_t regcache;
  220. ads129x_readback_regs(&regcache);
  221. uint8_t* reg = (uint8_t*)&regcache;
  222. reg[add] = data;
  223. ads129x_write_regs(&regcache);
  224. }
  225. uint8_t ads129x_start_capture() {
  226. ads129x_send_cmd(ADS129X_COMMAND_START); /* ���Ϳ�ʼ����ת������Ч������START���ţ� */
  227. return 0;
  228. }
  229. uint8_t ads129x_stop_capture() {
  230. ads129x_send_cmd(ADS129X_COMMAND_STOP); /* ����ֹͣ����ת������Ч������START���ţ� */
  231. return 0;
  232. }
  233. static int32_t i24toi32(uint8_t* p_i32) {
  234. int32_t rev = 0;
  235. rev = (((int32_t)p_i32[0]) << 16) | (((int32_t)p_i32[1]) << 8) | ((int32_t)p_i32[2]);
  236. if ((p_i32[0] & 0x80) == 0x80) {
  237. rev |= 0xFF000000;
  238. }
  239. return rev;
  240. }
  241. void ads129x_read_data(ads129x_capture_data_t* capture_data) {
  242. uint8_t rddata[9];
  243. ADS129X_CS_RESET(); /* ѡ���豸 */
  244. port_ads129x_delay_us(10);
  245. port_spi_transmit_receive(ADS129X_COMMAND_RDATA);
  246. port_ads129x_delay_us(1);
  247. for (int i = 0; i < 9; i++) {
  248. rddata[i] = port_spi_transmit_receive(0);
  249. }
  250. ADS129X_CS_SET();
  251. /**
  252. * @brief
  253. *
  254. * ضݸʽ(datasheet page 42)
  255. * 24bit status (1100 + LOFF_STAT[4:0] + GPIO[1:0] + 13`b0)
  256. * 24bit ch0 MSB
  257. * 24bit ch1 MSB
  258. *
  259. */
  260. uint32_t status = (((uint32_t)rddata[0]) << 16) | (((uint32_t)rddata[1]) << 8) | ((uint32_t)rddata[2]);
  261. capture_data->loffstate = (status >> (13 + 2)) & 0x1f;
  262. capture_data->gpio0 = status >> (14);
  263. capture_data->gpio1 = status >> (13);
  264. capture_data->ch1data = i24toi32(&rddata[3]);
  265. capture_data->ch2data = i24toi32(&rddata[6]);
  266. }
  267. uint8_t ads129x_get_lead_off_state() {
  268. // FLIP2,FLIP1,LOFF2N,LOFF2P,LOFF1N,LOFF1P
  269. uint8_t leadoffstate = ads129x_read_reg(ADS129X_REG_LOFFSTAT);
  270. return leadoffstate;
  271. }
  272. uint8_t ads129x_enter_low_power_mode() { return 0; }
  273. uint8_t ads129x_enter_lead_off_detect_mode() { return 0; }