From 3ae5bb9bdfb0c99f57d3bbaab273b6a00c46d024 Mon Sep 17 00:00:00 2001 From: Th3maz1ng Date: Mon, 8 May 2023 21:30:58 +0200 Subject: [PATCH] Continued to implement/port the MAX30102 using the sparkfun library. Still work to be done ! --- .../app/app_drivers/i2c/max3010X.c | 105 ++++++++++++++---- .../app/app_drivers/i2c/max3010X.h | 63 +++++++++++ src/W800_SDK_v1.00.10/app/gfx/gfx_task.c | 4 + 3 files changed, 152 insertions(+), 20 deletions(-) diff --git a/src/W800_SDK_v1.00.10/app/app_drivers/i2c/max3010X.c b/src/W800_SDK_v1.00.10/app/app_drivers/i2c/max3010X.c index f35e302..0caf86b 100644 --- a/src/W800_SDK_v1.00.10/app/app_drivers/i2c/max3010X.c +++ b/src/W800_SDK_v1.00.10/app/app_drivers/i2c/max3010X.c @@ -1,31 +1,96 @@ #include "i2c.h" -#include "max3010X.h" +#include "MAX3010X.h" /* Device i2c address */ #define MAX3010X_I2C_ADDR 0x57 /* Device registers list */ /* Status Regs */ -#define MAX3010X_INT_STATUS1 0x00 -#define MAX3010X_INT_STATUS2 0x01 -#define MAX3010X_INT_EN1 0x02 -#define MAX3010X_INT_EN2 0x03 -#define MAX3010X_FIFO_WR_PTR 0x04 -#define MAX3010X_FIFO_OVERFLOW_CNT 0x05 -#define MAX3010X_FIFO_RD_PTR 0x06 +#define MAX3010X_INT_STATUS1_REG 0x00 +#define MAX3010X_INT_STATUS2_REG 0x01 +#define MAX3010X_INT_EN1_REG 0x02 +#define MAX3010X_INT_EN2_REG 0x03 +#define MAX3010X_FIFO_WR_PTR_REG 0x04 +#define MAX3010X_FIFO_OVERFLOW_CNT_REG 0x05 +#define MAX3010X_FIFO_RD_PTR_REG 0x06 #define MAX3010X_FIFO_DATA_REG 0x07 /* Configuration Regs */ -#define MAX3010X_FIFO_CFG 0x08 -#define MAX3010X_MODE_CFG 0x09 -#define MAX3010X_SPO2_CFG 0x0A -#define MAX3010X_LED1_PULSE_AMP 0x0C -#define MAX3010X_LED2_PULSE_AMP 0x0D -#define MAX3010X_MULTI_LED_MODE_CTRL_SLOT1_2 0x11 -#define MAX3010X_MULTI_LED_MODE_CTRL_SLOT3_4 0x12 +#define MAX3010X_FIFO_CFG_REG 0x08 +#define MAX3010X_FIFO_CFG_FIFO_ROLLOVER_EN (4) +#define MAX3010X_FIFO_CFG_SMP_AVE_POS (5) + +#define MAX3010X_MODE_CFG_REG 0x09 +#define MAX3010X_MODE_CFG_RST_BIT_POS (6) +#define MAX3010X_MODE_CFG_SHDN_BIT_POS (7) + +#define MAX3010X_SPO2_CFG_REG 0x0A +#define MAX3010X_LED1_PULSE_AMP_REG 0x0C +#define MAX3010X_LED2_PULSE_AMP_REG 0x0D +#define MAX3010X_MULTI_LED_MODE_CTRL_SLOT1_2_REG 0x11 +#define MAX3010X_MULTI_LED_MODE_CTRL_SLOT3_4_REG 0x12 /* Die Temperature Regs */ -#define MAX3010X_DIE_TEMP_INT 0x1F -#define MAX3010X_DIE_TEMP_FRACT 0x20 -#define MAX3010X_DIE_TEMP_CFG 0x21 +#define MAX3010X_DIE_TEMP_INT_REG 0x1F +#define MAX3010X_DIE_TEMP_FRACT_REG 0x20 +#define MAX3010X_DIE_TEMP_CFG_REG 0x21 /* Part ID Regs */ -#define MAX3010X_REV_ID 0xFE -#define MAX3010X_PART_ID 0xFF \ No newline at end of file +#define MAX3010X_REV_ID_REG 0xFE +#define MAX3010X_PART_ID_REG 0xFF + +/* Other */ +#define MAX3010X_PART_ID 0x15 + +bool MAX3010X_init(void) +{ + uint8_t readPartId = 0; + if(!i2c_read_reg(MAX3010X_I2C_ADDR, MAX3010X_PART_ID_REG, &readPartId)) return false; + + return readPartId == MAX3010X_PART_ID; +} + +bool MAX3010X_soft_reset(void) +{ + uint8_t data; + + if(!i2c_read_reg(MAX3010X_I2C_ADDR, MAX3010X_MODE_CFG_REG, &data)) return false; + + // We set the reset bit and write the data back to the register + data |= 1 << MAX3010X_MODE_CFG_RST_BIT_POS; + + return i2c_write_reg(MAX3010X_I2C_ADDR, MAX3010X_MODE_CFG_REG, data); +} + +bool MAX3010X_set_FIFO_average(MAX3010X_Sample_Average_e sampleAverage) +{ + uint8_t data; + + if(!i2c_read_reg(MAX3010X_I2C_ADDR, MAX3010X_FIFO_CFG_REG, &data)) return false; + + data &= 0x1F; + data |= sampleAverage << MAX3010X_FIFO_CFG_SMP_AVE_POS; + + return i2c_write_reg(MAX3010X_I2C_ADDR, MAX3010X_FIFO_CFG_REG, data); +} + +bool MAX3010X_enable_FIFO_rollover(bool enabled) +{ + uint8_t data; + + if(!i2c_read_reg(MAX3010X_I2C_ADDR, MAX3010X_FIFO_CFG_REG, &data)) return false; + + if(enabled) data |= 1 << MAX3010X_FIFO_CFG_FIFO_ROLLOVER_EN; + else + data &= ~(1 << MAX3010X_FIFO_CFG_FIFO_ROLLOVER_EN); + + return i2c_write_reg(MAX3010X_I2C_ADDR, MAX3010X_FIFO_CFG_REG, data); +} + +bool MAX3010X_configure(uint8_t powerLevel, MAX3010X_Sample_Average_e sampleAverage, MAX3010X_LED_Mode_e LEDMode, MAX3010X_Sample_Rate_e sampleRate, MAX3010X_LED_Pulse_Width_e LEDPulseWidth, MAX3010X_ADC_Range_e ADCRange) +{ + if(!MAX3010X_soft_reset()) return false; + + if(!MAX3010X_set_FIFO_average(sampleAverage)) return false; + + if(!MAX3010X_enable_FIFO_rollover(true)) return false; + + return true; +} diff --git a/src/W800_SDK_v1.00.10/app/app_drivers/i2c/max3010X.h b/src/W800_SDK_v1.00.10/app/app_drivers/i2c/max3010X.h index 7e6056e..99634f8 100644 --- a/src/W800_SDK_v1.00.10/app/app_drivers/i2c/max3010X.h +++ b/src/W800_SDK_v1.00.10/app/app_drivers/i2c/max3010X.h @@ -1,4 +1,67 @@ #ifndef MAX3010X_H #define MAX3010X_H +typedef enum MAX3010X_LED_Mode +{ + MAX3010X_LED_MODE_RED_ONLY = 0x02, + MAX3010X_LED_MODE_RED_AND_IR = 0x03, + MAX3010X_LED_MODE_MULTI_LED = 0x07 +} MAX3010X_LED_Mode_e; + +typedef enum MAX3010X_Sample_Average +{ + MAX3010X_SAMPLE_AVERAGE_1 = 0x00, + MAX3010X_SAMPLE_AVERAGE_2 = 0x01, + MAX3010X_SAMPLE_AVERAGE_4 = 0x02, + MAX3010X_SAMPLE_AVERAGE_8 = 0x03, + MAX3010X_SAMPLE_AVERAGE_16 = 0x04, + MAX3010X_SAMPLE_AVERAGE_32 = 0x05, +} MAX3010X_Sample_Average_e; + +typedef enum MAX3010X_Sample_Rate +{ + MAX3010X_SAMPLES_PER_SECONDS_50 = 0x00, + MAX3010X_SAMPLES_PER_SECONDS_100 = 0x01, + MAX3010X_SAMPLES_PER_SECONDS_200 = 0x02, + MAX3010X_SAMPLES_PER_SECONDS_400 = 0x03, + MAX3010X_SAMPLES_PER_SECONDS_800 = 0x04, + MAX3010X_SAMPLES_PER_SECONDS_1000 = 0x05, + MAX3010X_SAMPLES_PER_SECONDS_1600 = 0x06, + MAX3010X_SAMPLES_PER_SECONDS_3200 = 0x07, +} MAX3010X_Sample_Rate_e; + +typedef enum MAX3010X_LED_Pulse_Width +{ + MAX3010X_LED_PULSE_WIDTH_69 = 0x00, + MAX3010X_LED_PULSE_WIDTH_118 = 0x01, + MAX3010X_LED_PULSE_WIDTH_215 = 0x02, + MAX3010X_LED_PULSE_WIDTH_411 = 0x03, +} MAX3010X_LED_Pulse_Width_e; + +typedef enum MAX3010X_ADC_Range +{ + MAX3010X_ADC_RANGE_2048 = 0x00, + MAX3010X_ADC_RANGE_4096 = 0x01, + MAX3010X_ADC_RANGE_8192 = 0x02, + MAX3010X_ADC_RANGE_16384 = 0x03, +} MAX3010X_ADC_Range_e; + + +/** + * @brief Initializes the MAX3010X sensor. This must be called before any other API functions. + * Don't forget to initialize the I2C peripheral using the i2c_init function first ! + * + * @return true on success + * @return false on failure + */ +bool MAX3010X_init(void); + +bool MAX3010X_soft_reset(void); + +bool MAX3010X_set_FIFO_average(MAX3010X_Sample_Average_e sampleAverage); + +bool MAX3010X_enable_FIFO_rollover(bool enabled); + +bool MAX3010X_configure(uint8_t powerLevel, MAX3010X_Sample_Average_e sampleAverage, MAX3010X_LED_Mode_e LEDMode, MAX3010X_Sample_Rate_e sampleRate, MAX3010X_LED_Pulse_Width_e LEDPulseWidth, MAX3010X_ADC_Range_e ADCRange); + #endif //MAX3010X_H \ No newline at end of file diff --git a/src/W800_SDK_v1.00.10/app/gfx/gfx_task.c b/src/W800_SDK_v1.00.10/app/gfx/gfx_task.c index 4d5394c..b5e14d5 100644 --- a/src/W800_SDK_v1.00.10/app/gfx/gfx_task.c +++ b/src/W800_SDK_v1.00.10/app/gfx/gfx_task.c @@ -15,6 +15,7 @@ #include "watch_peripherals.h" #include "watch_settings.h" #include "firmware_version.h" +#include "MAX3010X.h" #include "ble_modem.h" #include "ble_service.h" @@ -678,6 +679,9 @@ void gfx_task(void *param) battery_controller_status_2_str(watch_peripherals_get_battery_controller_status()), _battery_stats.battery_voltage, _battery_stats.battery_percentage); + + APP_LOG_DEBUG("MAX30102 init : %d", MAX3010X_init()); + APP_LOG_DEBUG("MAX30102 configure : %d", MAX3010X_configure(0x1F, MAX3010X_SAMPLE_AVERAGE_4, MAX3010X_LED_MODE_MULTI_LED, MAX3010X_SAMPLES_PER_SECONDS_400, MAX3010X_LED_PULSE_WIDTH_411, MAX3010X_ADC_RANGE_4096)); }