#include "max30102.h" static const char *TAG = "max30102"; #define MAX30102_I2C_SCL 2 // GPIO number used for I2C master clock #define MAX30102_I2C_SDA 3 // GPIO number used for I2C master data #define MAX30102_I2C_NUM 0 // I2C master i2c port number, the number of i2c peripheral interfaces available will depend on the chip #define MAX30102_I2C_FREQ_HZ 50000 // I2C master clock frequency #define MAX30102_I2C_TX_BUF_DISABLE 0 // I2C master doesn't need buffer #define MAX30102_I2C_RX_BUF_DISABLE 0 #define MAX30102_I2C_TIMEOUT_MS 1000 #define MAX30102_GPIO_INT 7 // GPIO number used for MAX30102 int // | B7 | B6 | B5 | B4 | B3 | B2 | B1 | B0 | WRITE ADDRESS | READ ADDRESS | // | 1 | 0 | 1 | 0 | 1 | 1 | 1 | R/W| 0xAE | 0xAF | #define MAX30102_ADDR 0x57 // I2C device MAX30102's 7-bit address #define MAX30102_PART_ID_REG_ADDR 0xff static xQueueHandle gpio_evt_queue = NULL; /** * @brief init the i2c port for MAX30102 */ static esp_err_t max30102_i2c_init() { int i2c_master_port = MAX30102_I2C_NUM; i2c_config_t conf = { .mode = I2C_MODE_MASTER, .sda_io_num = MAX30102_I2C_SDA, .scl_io_num = MAX30102_I2C_SCL, .sda_pullup_en = GPIO_PULLUP_ENABLE, .scl_pullup_en = GPIO_PULLUP_ENABLE, .master.clk_speed = MAX30102_I2C_FREQ_HZ, }; i2c_param_config(i2c_master_port, &conf); return i2c_driver_install(i2c_master_port, conf.mode, MAX30102_I2C_RX_BUF_DISABLE, MAX30102_I2C_TX_BUF_DISABLE, 0); } /** * @brief Read a sequence of bytes from a MAX30102 registers */ static esp_err_t max30102_register_read(uint8_t reg_addr, uint8_t *data, size_t len) { return i2c_master_write_read_device(MAX30102_I2C_NUM, MAX30102_ADDR, ®_addr, 1, data, len, MAX30102_I2C_TIMEOUT_MS / portTICK_RATE_MS); } /** * @brief Write a byte to a MAX30102 register */ static esp_err_t max30102_register_write_byte(uint8_t reg_addr, uint8_t data) { int ret; uint8_t write_buf[2] = {reg_addr, data}; ret = i2c_master_write_to_device(MAX30102_I2C_NUM, MAX30102_ADDR, write_buf, sizeof(write_buf), MAX30102_I2C_TIMEOUT_MS / portTICK_RATE_MS); return ret; } void gpio_intr_task() { uint8_t byte[6]; int data[2]; uint8_t io_num; for(;;) { if(xQueueReceive(gpio_evt_queue, &io_num, portMAX_DELAY)) { ESP_ERROR_CHECK(max30102_register_read(0x07, &byte, 6)); data[0] = ((byte[0]<<16 | byte[1]<<8 | byte[2]) & 0x03ffff); data[1] = ((byte[3]<<16 | byte[4]<<8 | byte[5]) & 0x03ffff); printf("Red: %d, IR: %d\n", data[1], data[0]); } } } static void IRAM_ATTR gpio_isr_handler(void* arg) { uint32_t gpio_num = (uint32_t) arg; xQueueSendFromISR(gpio_evt_queue, &gpio_num, NULL); } /** * @brief init the gpio intr for MAX30102 */ static esp_err_t max30102_gpio_intr_init() { gpio_config_t io_conf = {}; io_conf.intr_type = GPIO_INTR_NEGEDGE; io_conf.mode = GPIO_MODE_INPUT; io_conf.pin_bit_mask = (1ULL<