max30102.c 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. #include "max30102.h"
  2. #include "iot_errno.h"
  3. #include "iot_gpio.h"
  4. #include "iot_gpio_ex.h"
  5. #include "iot_i2c.h"
  6. #include "iot_i2c_ex.h"
  7. #include <stdio.h>
  8. #define WIFI_IOT_IO_FUNC_GPIO_0_I2C1_SDA 6
  9. #define WIFI_IOT_IO_FUNC_GPIO_1_I2C1_SCL 6
  10. #define WIFI_IOT_I2C_IDX_1 1
  11. #define WIFI_IOT_IO_NAME_GPIO_7 7
  12. #define WIFI_IOT_IO_NAME_GPIO_8 8
  13. #define WIFI_IOT_IO_NAME_GPIO_0 0
  14. #define WIFI_IOT_IO_NAME_GPIO_1 1
  15. #define MAX30102_INIT_GPIO 7
  16. /***************************************************************
  17. * 函数名称: GpioInit
  18. * 说 明: GPIO初始化
  19. * 参 数: 无
  20. * 返 回 值: 无
  21. ***************************************************************/
  22. void BoardInit(void)
  23. {
  24. // IoTGpioInit(WIFI_IOT_IO_NAME_GPIO_8);
  25. // IoTGpioSetFunc(WIFI_IOT_IO_NAME_GPIO_8, WIFI_IOT_IO_FUNC_GPIO_8_GPIO);
  26. // IoTGpioSetDir(WIFI_IOT_IO_NAME_GPIO_8, IOT_GPIO_DIR_OUT); // 设置GPIO_8为输出模式
  27. IoTGpioInit(MAX30102_INIT_GPIO);
  28. IoTGpioSetFunc(MAX30102_INIT_GPIO, IOT_GPIO_FUNC_GPIO_7_GPIO);
  29. IoTGpioSetDir(MAX30102_INIT_GPIO, IOT_GPIO_DIR_IN); // 设置GPIO_7为输出模式
  30. IoTGpioInit(WIFI_IOT_IO_NAME_GPIO_0);
  31. IoTGpioSetFunc(WIFI_IOT_IO_NAME_GPIO_0, WIFI_IOT_IO_FUNC_GPIO_0_I2C1_SDA); // GPIO_0复用为I2C1_SDA
  32. IoTGpioInit(WIFI_IOT_IO_NAME_GPIO_1);
  33. IoTGpioSetFunc(WIFI_IOT_IO_NAME_GPIO_1, WIFI_IOT_IO_FUNC_GPIO_1_I2C1_SCL); // GPIO_1复用为I2C1_SCL
  34. IoTI2cInit(WIFI_IOT_I2C_IDX_1, 400000); /* baudrate: 400kbps */
  35. }
  36. uint8_t GetInit(void)
  37. {
  38. IotGpioValue temp = {0};
  39. IoTGpioGetInputVal(MAX30102_INIT_GPIO,&temp);
  40. return temp;
  41. }
  42. /**
  43. * \brief Write a value to a MAX30102 register
  44. * \par Details
  45. * This function writes a value to a MAX30102 register
  46. *
  47. * \param[in] uch_addr - register address
  48. * \param[in] uch_data - register data
  49. *
  50. * \retval true on success
  51. */
  52. static int maxim_max30102_write_reg(uint8_t uch_addr, uint8_t uch_data)
  53. {
  54. uint32_t ret;
  55. uint8_t send_data[2] = {uch_addr, uch_data};
  56. ret = IoTI2cWrite(WIFI_IOT_I2C_IDX_1, (MAX30102_SLAVE_ADDRESS << 1) | 0x00, send_data, 2);
  57. if (ret != 0) {
  58. printf("===== Error: I2C write ret = 0x%x! =====\r\n", ret);
  59. return -1;
  60. }
  61. return 0;
  62. }
  63. /**
  64. * \brief Read a MAX30102 register
  65. * \par Details
  66. * This function reads a MAX30102 register
  67. *
  68. * \param[in] uch_addr - register address
  69. * \param[out] puch_data - pointer that stores the register data
  70. *
  71. * \retval true on success
  72. */
  73. uint8_t maxim_max30102_read_reg(uint8_t uch_addr, uint8_t *puch_data)
  74. {
  75. uint32_t ret = 0;
  76. IotI2cData max30102_i2c_data = {0};
  77. uint8_t buffer[1] = {uch_addr};
  78. max30102_i2c_data.sendBuf = buffer;
  79. max30102_i2c_data.sendLen = 1;
  80. max30102_i2c_data.receiveBuf = puch_data;
  81. max30102_i2c_data.receiveLen = 1;
  82. ret = IoTI2cWriteread(WIFI_IOT_I2C_IDX_1, (MAX30102_SLAVE_ADDRESS << 1) | 0x00, &max30102_i2c_data);
  83. if (ret != 0) {
  84. printf("===== Error: I2C writeread ret = 0x%x! =====\r\n", ret);
  85. return -1;
  86. }
  87. return 0;
  88. }
  89. uint8_t maxim_max30102_init()
  90. {
  91. if(maxim_max30102_write_reg(REG_INTR_ENABLE_1,0xc0)!=IOT_SUCCESS) // INTR setting
  92. return 0;
  93. if(maxim_max30102_write_reg(REG_INTR_ENABLE_2,0x00)!=IOT_SUCCESS)
  94. return 0;
  95. if(maxim_max30102_write_reg(REG_FIFO_WR_PTR,0x00)!=IOT_SUCCESS) //FIFO_WR_PTR[4:0]
  96. return 0;
  97. if(maxim_max30102_write_reg(REG_OVF_COUNTER,0x00)!=IOT_SUCCESS) //OVF_COUNTER[4:0]
  98. return 0;
  99. if(maxim_max30102_write_reg(REG_FIFO_RD_PTR,0x00)!=IOT_SUCCESS) //FIFO_RD_PTR[4:0]
  100. return 0;
  101. if(maxim_max30102_write_reg(REG_FIFO_CONFIG,0x0f)!=IOT_SUCCESS) //sample avg = 1, fifo rollover=false, fifo almost full = 17
  102. return 0;
  103. if(maxim_max30102_write_reg(REG_MODE_CONFIG,0x03)!=IOT_SUCCESS) //0x02 for Red only, 0x03 for SpO2 mode 0x07 multimode LED
  104. return 0;
  105. if(maxim_max30102_write_reg(REG_SPO2_CONFIG,0x27)!=IOT_SUCCESS) // SPO2_ADC range = 4096nA, SPO2 sample rate (100 Hz), LED pulseWidth (400uS)
  106. return 0;
  107. if(maxim_max30102_write_reg(REG_LED1_PA,0x32)!=IOT_SUCCESS) //Choose value for ~ 7mA for LED1
  108. return 0;
  109. if(maxim_max30102_write_reg(REG_LED2_PA,0x32)!=IOT_SUCCESS) // Choose value for ~ 7mA for LED2
  110. return 0;
  111. if(maxim_max30102_write_reg(REG_PILOT_PA,0x7f)!=IOT_SUCCESS) // Choose value for ~ 25mA for Pilot LED
  112. return 0;
  113. return 1;
  114. }
  115. /**
  116. * \brief Reset the MAX30102
  117. * \par Details
  118. * This function resets the MAX30102
  119. *
  120. * \param None
  121. *
  122. * \retval true on success
  123. */
  124. uint8_t maxim_max30102_reset()
  125. {
  126. if(maxim_max30102_write_reg(REG_MODE_CONFIG,0x40)!=IOT_SUCCESS)
  127. return 0;
  128. else
  129. return 1;
  130. }
  131. /**
  132. * \brief Read a set of samples from the MAX30102 FIFO register
  133. * \par Details
  134. * This function reads a set of samples from the MAX30102 FIFO register
  135. *
  136. * \param[out] *pun_red_led - pointer that stores the red LED reading data
  137. * \param[out] *pun_ir_led - pointer that stores the IR LED reading data
  138. *
  139. * \retval true on success
  140. */
  141. uint8_t max30102_FIFO_ReadBytes(uint8_t Register_Address,uint8_t* Data)
  142. {
  143. uint32_t un_temp;
  144. unsigned char uch_temp;
  145. //read and clear status register
  146. maxim_max30102_read_reg(REG_INTR_STATUS_1, &uch_temp);
  147. maxim_max30102_read_reg(REG_INTR_STATUS_2, &uch_temp);
  148. // ach_i2c_data[0]=REG_FIFO_DATA;
  149. uint32_t ret = 0;
  150. IotI2cData max30102_i2c_data = {0};
  151. uint8_t buffer[1] = {REG_FIFO_DATA};
  152. max30102_i2c_data.sendBuf = buffer;
  153. max30102_i2c_data.sendLen = 1;
  154. max30102_i2c_data.receiveBuf = Data;
  155. max30102_i2c_data.receiveLen = 6;
  156. ret = IoTI2cWriteread(WIFI_IOT_I2C_IDX_1, (MAX30102_SLAVE_ADDRESS << 1) | 0x00, &max30102_i2c_data);
  157. if (ret != 0) {
  158. printf("===== Error: I2C writeread ret = 0x%x! =====\r\n", ret);
  159. return -1;
  160. }
  161. return 0;
  162. }
  163. /**
  164. * \brief Read a set of samples from the MAX30102 FIFO register
  165. * \par Details
  166. * This function reads a set of samples from the MAX30102 FIFO register
  167. *
  168. * \param[out] *pun_red_led - pointer that stores the red LED reading data
  169. * \param[out] *pun_ir_led - pointer that stores the IR LED reading data
  170. *
  171. * \retval true on success
  172. */
  173. uint8_t maxim_max30102_read_fifo(uint32_t *pun_red_led, uint32_t *pun_ir_led)
  174. {
  175. uint32_t un_temp;
  176. unsigned char uch_temp;
  177. *pun_red_led=0;
  178. *pun_ir_led=0;
  179. uint8_t ach_i2c_data[6];
  180. //read and clear status register
  181. maxim_max30102_read_reg(REG_INTR_STATUS_1, &uch_temp);
  182. maxim_max30102_read_reg(REG_INTR_STATUS_2, &uch_temp);
  183. // ach_i2c_data[0]=REG_FIFO_DATA;
  184. uint32_t ret = 0;
  185. IotI2cData max30102_i2c_data = {0};
  186. uint8_t buffer[1] = {REG_FIFO_DATA};
  187. max30102_i2c_data.sendBuf = buffer;
  188. max30102_i2c_data.sendLen = 1;
  189. max30102_i2c_data.receiveBuf = ach_i2c_data;
  190. max30102_i2c_data.receiveLen = 6;
  191. ret = IoTI2cWriteread(WIFI_IOT_I2C_IDX_1, (MAX30102_SLAVE_ADDRESS << 1) | 0x00, &max30102_i2c_data);
  192. if (ret != 0) {
  193. printf("===== Error: I2C writeread ret = 0x%x! =====\r\n", ret);
  194. return -1;
  195. }
  196. un_temp=(unsigned char) ach_i2c_data[0];
  197. un_temp<<=16;
  198. *pun_red_led+=un_temp;
  199. un_temp=(unsigned char) ach_i2c_data[1];
  200. un_temp<<=8;
  201. *pun_red_led+=un_temp;
  202. un_temp=(unsigned char) ach_i2c_data[2];
  203. *pun_red_led+=un_temp;
  204. un_temp=(unsigned char) ach_i2c_data[3];
  205. un_temp<<=16;
  206. *pun_ir_led+=un_temp;
  207. un_temp=(unsigned char) ach_i2c_data[4];
  208. un_temp<<=8;
  209. *pun_ir_led+=un_temp;
  210. un_temp=(unsigned char) ach_i2c_data[5];
  211. *pun_ir_led+=un_temp;
  212. *pun_red_led&=0x03FFFF; //Mask MSB [23:18]
  213. *pun_ir_led&=0x03FFFF; //Mask MSB [23:18]
  214. return 1;
  215. }