Post Go back to editing

Implementation note for MAX86174A/MAX86174B: “Best-in-Class Optical Pulse Oximeter and Heart-Rate Sensor AFE for Wearable Health”

This blog provides an experience about the implementation of MCU firmware for ADI’s “Best-in-Class Optical Pulse Oximeter and Heart-Rate Sensor AFE for Wearable Health”: MAX86174A

https://www.analog.com/en/products/max86174a.html#product-overview

  • Some important points are emphasized.
  • Communication protocol: I2C

Step 1: Create driver files:

  • max86174A.h
  • max86174A.c

Step 2: Define the register’s address using a readable name in max86174A.h

  • Referring to “Register Map” in the datasheet (page 43)

E.g.

#define MAX86174A_Status_1  0x00

#define MAX86174A_Status_2  0x01

Step 3: implement the necessary functions in max86174A.c

  • The most important communication function (communication): 

    uint32_t max86174A_ readReg (uint8_t reg, uint8_t len);

    // Input is the register address, and the number of bytes that will be read from the register
    // Output is the value in the target register

    void max86174A_writeReg (uint8_t reg, uint8_t *val);

    // Input is the register address, and the pointer that is saving the value to be written, such as an array

  • The configuration functions: 

    void max86174A_reset();

    // Register MAX86174A_System_Configuration_1 (0x11), set RESET bit to 1

    void max86174A_setFs(uint32_t Fs);

    // Register MAX86174A_FR_Clock_Divider_MSB (0x1B), set the value to the corresponding frame rate (fps)

    void max86174A_enable_MEAS(uint8_t Num_MEAS)

    // Set the register MAX86174A_System_Configuration_2, to enable the corresponding MEAS.
    // Also should set the PPG1_PWRDN and PPG2_PWRDN to enable/disable the ADC channels, in register MAX86174A_System_Configuration_1 (0x11), here 0 is enable, 1 is disable

    void max86174A_setLED(uint8_t MEAS_x, uint8_t DRVA, uint8_t DRVA_POW, uint8_t DRVB, uint8_t DRVB_POW)

    // The MEAS_x is the number of the measurement
    // There are two LED drivers for each measurement, select which LEDs are driven in register MAX86174A_MEASx_Selects(0x20+8*MEAS_x),
    // Then set the driving current in MAX86174A_MEASx_LEDA_Current (0x25+8*MEAS_x) and MEAS1_LEDB_Current(0x26+8*MEAS_x), respectively
    // Important: if the LED4 is used, in the register MAX86174A_Output_Pin_Configuration, the TRIGLED4_SEL bit must be set to 1

    void max86174A_setPD(uint8_t MEAS_x, uint8_t ADC_TINT, uint8_t ADC_RGE)

    // Set the ADC integrate time in MAX86174A_MEASx_Configuration_1 (0x21+8*MEAS_x)
    // set ADC range in MAX86174A_MEASx_Configuration_2 (0x22+8*MEAS_x)

    void max86174A_start();

    // In register MAX86174A_System_Configuration_1 (0x11), set SHDN bit to 0 to start running

    void max86174A _stop();

    // In register MAX86174A_System_Configuration_1 (0x11), set SHDN bit to 1 so stop running

    void max86174A_read_FIFO_Data(double* data, uint32_t data_len)

    // The data can only be readout from FIFO, each data is 3 bytes, so for reading one data, should read 3 byte from I2C, the register address is MAX86174A_FIFO_Data_Register (0x07)

    void max86174A_set_interrupt_FIFO(uint8_t val_full)

    // Set the FIFO size in MAX86174A_FIFO_Configuration_1 (0x08), the value in register is the number of empty FIFO, so the number of saved data should be subtracted from 256 (256-val_full)
    // Configure the INTB pin, together with the host MCU, to let the MCU know FIFO is full, in register MAX86174A_Output_Pin_Configuration (0x17)
    // Enable the interrupt signal at INTB pin, to let the host MCU know the FIFO is full, in register MAX86174A_Interrupt_Enable_1 (0x58)

    void max86174A_flushFifo()

    // Empty the FIFO by set the FLUSH_FIFO bit to 1, in register MAX86174A_FIFO_Configuration_2 (0x09)

  • The initialization functions: 

    void max86174A _init_user();

    // This function call the above-defined functions to make the PPG sensor work. Following is my flow for a reference:
    max86174A_reset();
    max86174A _stop();
    // MEAS1 and MEAS2 are enabled
    max86174A _enable_MEAS(2); 
    // Set the LED for MEAS1
    max86174A _setLED(0, 0, 10, 0, 10); 
    // Set the PD for MEAS1
    max86174A _setPD(0, 0, 0); 
    // Set the LED for MEAS2
    max86174A _setLED(1, 0, 0, 0, 0); 
    // Set the PD for MEAS2
    max86174A _setPD(1, 0, 0); 
     // Set sampling frequency as 100 fps
    max86174A _setFs(100);
    // Enable an interrupt signal in INTB when there are 250 samples in FIFO
    max86174A _set_interrupt_FIFO(250); 
    // Empty FIFO for initiation
    max86174A _flushFifo(); 
    // Start the MAX86174A
    max86174A _start(); 

Step 4: declare the functions above to the file “max86174A.h”: 

Step 5: Include the file “max86174A.h” in the main.c: 

  • Call max86174A _init_user() in the initiation process
  • Configure the interrupt callback, read the data from FIFO of max86174 after the INTB signals received.

 

Have fun!

Reference:

[1] MAX86174A datasheet: https://www.analog.com/media/en/technical-documentation/data-sheets/max86174a-b.pdf



Changed format
[edited by: Jiabin at 6:59 AM (GMT -5) on 17 Feb 2023]
Parents
  • Hi Jiabin, Thank you for sharing information about the MAX6174A product. Only Maxim ATE products are supported on EngineerZone at this time. Over the next several months, you will see more Maxim products being supported in EngineerZone.

Reply
  • Hi Jiabin, Thank you for sharing information about the MAX6174A product. Only Maxim ATE products are supported on EngineerZone at this time. Over the next several months, you will see more Maxim products being supported in EngineerZone.

Children