From 42c01e1d08815ee72f04080e2c93e84b80365e91 Mon Sep 17 00:00:00 2001 From: anschrammh Date: Thu, 11 May 2023 07:18:11 +0200 Subject: [PATCH] Continued to work on the MAX3010X driver, setup function is complete, still a lot to port/implement --- .../app/app_drivers/i2c/max3010X.c | 149 ++++++++++++++++++ .../app/app_drivers/i2c/max3010X.h | 27 ++++ 2 files changed, 176 insertions(+) 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 0caf86b..955870c 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 @@ -59,6 +59,30 @@ bool MAX3010X_soft_reset(void) return i2c_write_reg(MAX3010X_I2C_ADDR, MAX3010X_MODE_CFG_REG, data); } +bool MAX3010X_shutdown(void) +{ + uint8_t data; + + if(!i2c_read_reg(MAX3010X_I2C_ADDR, MAX3010X_MODE_CFG_REG, &data)) return false; + + // We set the shutdown bit and write the data back to the register + data |= 1 << MAX3010X_MODE_CFG_SHDN_BIT_POS; + + return i2c_write_reg(MAX3010X_I2C_ADDR, MAX3010X_MODE_CFG_REG, data); +} + +bool MAX3010X_wakeup(void) +{ + uint8_t data; + + if(!i2c_read_reg(MAX3010X_I2C_ADDR, MAX3010X_MODE_CFG_REG, &data)) return false; + + // We clear the shutdown bit and write the data back to the register + data &= ~(1 << MAX3010X_MODE_CFG_SHDN_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; @@ -84,6 +108,112 @@ bool MAX3010X_enable_FIFO_rollover(bool enabled) return i2c_write_reg(MAX3010X_I2C_ADDR, MAX3010X_FIFO_CFG_REG, data); } +bool MAX3010X_set_LED_mode(MAX3010X_LED_Mode_e LEDMode) +{ + uint8_t data; + + if(!i2c_read_reg(MAX3010X_I2C_ADDR, MAX3010X_MODE_CFG_REG, &data)) return false; + + data &= 0xF8; + data |= LEDMode; + + return i2c_write_reg(MAX3010X_I2C_ADDR, MAX3010X_MODE_CFG_REG, data); +} + +bool MAX3010X_set_ADC_range(MAX3010X_ADC_Range_e ADCRange) +{ + uint8_t data; + + if(!i2c_read_reg(MAX3010X_I2C_ADDR, MAX3010X_SPO2_CFG_REG, &data)) return false; + + data &= 0x9F; + data |= ADCRange << 5; + + return i2c_write_reg(MAX3010X_I2C_ADDR, MAX3010X_SPO2_CFG_REG, data); +} + +bool MAX3010X_set_sample_rate(MAX3010X_Sample_Rate_e sampleRate) +{ + uint8_t data; + + if(!i2c_read_reg(MAX3010X_I2C_ADDR, MAX3010X_SPO2_CFG_REG, &data)) return false; + + data &= 0xE3; + data |= sampleRate << 2; + + return i2c_write_reg(MAX3010X_I2C_ADDR, MAX3010X_SPO2_CFG_REG, data); +} + +bool MAX3010X_set_pulse_width(MAX3010X_LED_Pulse_Width_e LEDPulseWidth) +{ + uint8_t data; + + if(!i2c_read_reg(MAX3010X_I2C_ADDR, MAX3010X_SPO2_CFG_REG, &data)) return false; + + data &= 0xFC; + data |= LEDPulseWidth; + + return i2c_write_reg(MAX3010X_I2C_ADDR, MAX3010X_SPO2_CFG_REG, data); +} + +bool MAX3010X_set_pulse_amplitude_red(uint8_t powerLevel) +{ + return i2c_write_reg(MAX3010X_I2C_ADDR, MAX3010X_LED1_PULSE_AMP_REG, powerLevel); +} + +bool MAX3010X_set_pulse_amplitude_IR(uint8_t powerLevel) +{ + return i2c_write_reg(MAX3010X_I2C_ADDR, MAX3010X_LED2_PULSE_AMP_REG, powerLevel); +} + +bool MAX3010X_set_multi_LED_mode_slot(uint8_t slot, MAX3010X_SLOT_LED_e slotLED) +{ + uint8_t data; + + switch(slot) + { + case 1: + if(!i2c_read_reg(MAX3010X_I2C_ADDR, MAX3010X_MULTI_LED_MODE_CTRL_SLOT1_2_REG, &data)) return false; + + data &= 0xF8; + data |= slotLED; + + return i2c_write_reg(MAX3010X_I2C_ADDR, MAX3010X_MULTI_LED_MODE_CTRL_SLOT1_2_REG, data); + case 2: + if(!i2c_read_reg(MAX3010X_I2C_ADDR, MAX3010X_MULTI_LED_MODE_CTRL_SLOT1_2_REG, &data)) return false; + + data &= 0x8F; + data |= slotLED << 4; + + return i2c_write_reg(MAX3010X_I2C_ADDR, MAX3010X_MULTI_LED_MODE_CTRL_SLOT1_2_REG, data); + case 3: + if(!i2c_read_reg(MAX3010X_I2C_ADDR, MAX3010X_MULTI_LED_MODE_CTRL_SLOT3_4_REG, &data)) return false; + + data &= 0xF8; + data |= slotLED; + + return i2c_write_reg(MAX3010X_I2C_ADDR, MAX3010X_MULTI_LED_MODE_CTRL_SLOT3_4_REG, data); + case 4: + if(!i2c_read_reg(MAX3010X_I2C_ADDR, MAX3010X_MULTI_LED_MODE_CTRL_SLOT3_4_REG, &data)) return false; + + data &= 0x8F; + data |= slotLED << 4; + + return i2c_write_reg(MAX3010X_I2C_ADDR, MAX3010X_MULTI_LED_MODE_CTRL_SLOT3_4_REG, data); + default: + return false; + } +} + +bool MAX3010X_clear_FIFO(void) +{ + if(!i2c_write_reg(MAX3010X_I2C_ADDR, MAX3010X_FIFO_WR_PTR_REG, 0x00)) return false; + if(!i2c_write_reg(MAX3010X_I2C_ADDR, MAX3010X_FIFO_OVERFLOW_CNT_REG, 0x00)) return false; + if(!i2c_write_reg(MAX3010X_I2C_ADDR, MAX3010X_FIFO_RD_PTR_REG, 0x00)) return false; + + return true; +} + 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; @@ -92,5 +222,24 @@ bool MAX3010X_configure(uint8_t powerLevel, MAX3010X_Sample_Average_e sampleAver if(!MAX3010X_enable_FIFO_rollover(true)) return false; + if(!MAX3010X_set_LED_mode(LEDMode)) return false; + + if(!MAX3010X_set_ADC_range(ADCRange)) return false; + + if(!MAX3010X_set_sample_rate(sampleRate)) return false; + + if(!MAX3010X_set_pulse_width(LEDPulseWidth)) return false; + + if(!MAX3010X_set_pulse_amplitude_red(powerLevel)) return false; + + if(!MAX3010X_set_pulse_amplitude_IR(powerLevel)) return false; + + if(!MAX3010X_set_multi_LED_mode_slot(1, MAX3010X_SLOT_LED_RED)) return false; + + if(LEDMode > MAX3010X_LED_MODE_RED_ONLY) + if(!MAX3010X_set_multi_LED_mode_slot(2, MAX3010X_SLOT_LED_IR)) return false; + + if(!MAX3010X_clear_FIFO()) 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 99634f8..387e5e7 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 @@ -46,6 +46,13 @@ typedef enum MAX3010X_ADC_Range MAX3010X_ADC_RANGE_16384 = 0x03, } MAX3010X_ADC_Range_e; +typedef enum MAX3010X_SLOT_LED +{ + MAX3010X_SLOT_LED_NONE = 0x00, + MAX3010X_SLOT_LED_RED = 0x01, + MAX3010X_SLOT_LED_IR = 0x02, +} MAX3010X_SLOT_LED_e; + /** * @brief Initializes the MAX3010X sensor. This must be called before any other API functions. @@ -58,10 +65,30 @@ bool MAX3010X_init(void); bool MAX3010X_soft_reset(void); +bool MAX3010X_shutdown(void); + +bool MAX3010X_wakeup(void); + bool MAX3010X_set_FIFO_average(MAX3010X_Sample_Average_e sampleAverage); bool MAX3010X_enable_FIFO_rollover(bool enabled); +bool MAX3010X_set_LED_mode(MAX3010X_LED_Mode_e LEDMode); + +bool MAX3010X_set_ADC_range(MAX3010X_ADC_Range_e ADCRange); + +bool MAX3010X_set_sample_rate(MAX3010X_Sample_Rate_e sampleRate); + +bool MAX3010X_set_pulse_width(MAX3010X_LED_Pulse_Width_e LEDPulseWidth); + +bool MAX3010X_set_pulse_amplitude_red(uint8_t powerLevel); + +bool MAX3010X_set_pulse_amplitude_IR(uint8_t powerLevel); + +bool MAX3010X_set_multi_LED_mode_slot(uint8_t slot, MAX3010X_SLOT_LED_e slotLED); + +bool MAX3010X_clear_FIFO(void); + 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