Library for MAX3010x optical sensors

Dependents:   Temp_Prox_Demo

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers MAX30105.h Source File

MAX30105.h

00001 /** \file max30105.h ******************************************************
00002 *
00003 * Project: MAXREFDES117#
00004 * Filename: max30105.h
00005 * Description: This module is an embedded controller driver header file for MAX30105
00006 *
00007 * ------------------------------------------------------------------------- */
00008 /*******************************************************************************
00009 * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved.
00010 *
00011 * Permission is hereby granted, free of charge, to any person obtaining a
00012 * copy of this software and associated documentation files (the "Software"),
00013 * to deal in the Software without restriction, including without limitation
00014 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
00015 * and/or sell copies of the Software, and to permit persons to whom the
00016 * Software is furnished to do so, subject to the following conditions:
00017 *
00018 * The above copyright notice and this permission notice shall be included
00019 * in all copies or substantial portions of the Software.
00020 *
00021 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00022 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00023 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
00024 * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
00025 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
00026 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
00027 * OTHER DEALINGS IN THE SOFTWARE.
00028 *
00029 * Except as contained in this notice, the name of Maxim Integrated
00030 * Products, Inc. shall not be used except as stated in the Maxim Integrated
00031 * Products, Inc. Branding Policy.
00032 *
00033 * The mere transfer of this software does not imply any licenses
00034 * of trade secrets, proprietary technology, copyrights, patents,
00035 * trademarks, maskwork rights, or any other form of intellectual
00036 * property whatsoever. Maxim Integrated Products, Inc. retains all
00037 * ownership rights.
00038 *******************************************************************************
00039 */
00040 #ifndef _MAX30105_H_
00041 #define _MAX30105_H_
00042 
00043 #include "mbed.h"
00044 
00045 #define MAX30105_NO_ERROR   0
00046 #define MAX30105_ERROR      -1
00047 #define MAX30105_TEMP_ERROR  -999.0
00048 
00049 #define MAX30105_I2C_ADDR  0xAE
00050 #define MAX30105_PART_ID  0x15
00051 
00052 #define MAX30105_DEFAULT_LED_PA 0x20
00053 #define MAX30105_DEFAULT_PILOT_PA 0x40
00054 
00055 /**
00056  * MAX30105 Optical Sensor
00057  *
00058  * @code
00059  * #include "mbed.h"
00060  * #include "MAX30105.h"
00061  *
00062  * I2C i2c(I2C_SDA, I2C_SCL);
00063  * MAX30105 max30105(&i2c);
00064  *
00065  * int main(void) {
00066  *     int lastPrx = 0;    
00067  *
00068  *     max30105.softReset(); // reset the MAX30105
00069  *     max30105.shutDown();  // shut down while configuring
00070  *     max30105.enableIntr(MAX30105::INTR_PROX);  // enable proximity interrupt
00071  *     max30105.setProx(0x40, 0x10);   // set proximity pulse amplitude and threshold
00072  *     max30105.setSingleLED();  // configure single LED mode to initiate proximity detection
00073  *     max30105.wakeUp();        // exit shutdown to start sensing
00074  *
00075  *     while(1) {
00076  *         if (max30105.getIntr1() & MAX30105::INTR_PROX) { // if the proximity interrupt occurs
00077  *             if (!lastPrx) {
00078  *                 printf("Temperature = %02f\n", max30105.readTemperature());
00079  *             }
00080  *             max30105.writeReg(MAX30105::REG_MODE_CONFIG, MAX30105::MODE_1LED); // go back into proximity detection
00081  *             lastPrx = 1;
00082  *         } else {
00083  *             lastPrx = 0;
00084  *         }
00085  *         wait_ms(100);
00086  *     }
00087  * }
00088  * @endcode
00089  */
00090 class MAX30105
00091 {
00092 public:
00093 
00094     /**
00095      * @brief   Register Addresses
00096      * @details Enumerated MAX30105 register addresses
00097      */
00098     enum registers_t {
00099         REG_INTR_STATUS_1 = 0x00,     ///< Interrupt Status 1
00100         REG_INTR_STATUS_2 = 0x01,     ///< Interrupt Status 2
00101         REG_INTR_ENABLE_1 = 0x02,     ///< Interrupt Enable 1
00102         REG_INTR_ENABLE_2 = 0x03,     ///< Interrupt Enable 2
00103         REG_FIFO_WR_PTR = 0x04,     ///< FIFO Write Pointer
00104         REG_OVF_COUNTER = 0x05,     ///< Overflow Counter
00105         REG_FIFO_RD_PTR = 0x06,     ///< FIFO Read Pointer
00106         REG_FIFO_DATA = 0x07,     ///< FIFO Data Register
00107         REG_FIFO_CONFIG = 0x08,     ///< FIFO Configuration
00108         REG_MODE_CONFIG = 0x09,     ///< Mode Configuration
00109         REG_SPO2_CONFIG = 0x0A,     ///< Sensing Configuration
00110         REG_RSVD_0B = 0x0B,     ///< Reserved 0x0B
00111         REG_LED1_PA = 0x0C,     ///< LED1 Pulse Amplitude
00112         REG_LED2_PA = 0x0D,     ///< LED2 Pulse Amplitude
00113         REG_LED3_PA = 0x0E,     ///< LED3 Pulse Amplitude
00114         REG_RSVD_0F = 0x0F,     ///< Reserved 0x0F
00115         REG_PILOT_PA = 0x10,     ///< Proximity Mode LED Pulse Amplitude
00116         REG_MULTI_LED_CTRL1 = 0x11,     ///< LED Slots 1 and 2
00117         REG_MULTI_LED_CTRL2 = 0x12,     ///< LED Slots 3 and 4
00118         REG_TEMP_INT = 0x1F,     ///< Die Temperature Ingteger
00119         REG_TEMP_FRAC = 0x20,     ///< Die Temperature Fraction
00120         REG_TEMP_CONFIG = 0x21,     ///< Die Temperature Configuration
00121         REG_PROX_INTR_THRESH = 0x30,     ///< Proximity Interrupt Threshold
00122         REG_REV_ID = 0xFE,     ///< Part Revision
00123         REG_PART_ID = 0xFF,     ///< Part ID Code
00124     };
00125 
00126     /**
00127      * @brief   Sample Averaging
00128      * @details Number of samples to be averaged and decimated
00129      */
00130     enum smp_ave_t {
00131         SMP_AVE_1 = (0 << 5), ///< 1 (no averaging)
00132         SMP_AVE_2 = (1 << 5), ///< 2
00133         SMP_AVE_4 = (2 << 5), ///< 4
00134         SMP_AVE_8 = (3 << 5), ///< 8
00135         SMP_AVE_16 = (4 << 5), ///< 16
00136         SMP_AVE_32 = (5 << 5), ///< 32
00137     };
00138 
00139     /**
00140      * @brief   FIFO Almost Full Value
00141      * @details Number of empty spaces that triggers FIFO_A_FULL interrupt
00142      */
00143     enum fifo_a_full_t {
00144         FIFO_A_FULL_0 = 0x0, ///< 0 samples remaining, 32 used
00145         FIFO_A_FULL_1 = 0x1, ///< 1 samples remaining, 31 used
00146         FIFO_A_FULL_2 = 0x2, ///< 2 samples remaining, 30 used
00147         FIFO_A_FULL_3 = 0x3, ///< 3 samples remaining, 29 used
00148         FIFO_A_FULL_4 = 0x4, ///< 4 samples remaining, 28 used
00149         FIFO_A_FULL_5 = 0x5, ///< 5 samples remaining, 27 used
00150         FIFO_A_FULL_6 = 0x6, ///< 6 samples remaining, 26 used
00151         FIFO_A_FULL_7 = 0x7, ///< 7 samples remaining, 25 used
00152         FIFO_A_FULL_8 = 0x8, ///< 8 samples remaining, 24 used
00153         FIFO_A_FULL_9 = 0x9, ///< 9 samples remaining, 23 used
00154         FIFO_A_FULL_A = 0xA, ///< 10 samples remaining, 22 used
00155         FIFO_A_FULL_B = 0xB, ///< 11 samples remaining, 21 used
00156         FIFO_A_FULL_C = 0xC, ///< 12 samples remaining, 20 used
00157         FIFO_A_FULL_D = 0xD, ///< 13 samples remaining, 19 used
00158         FIFO_A_FULL_E = 0xE, ///< 14 samples remaining, 18 used
00159         FIFO_A_FULL_F = 0xF, ///< 15 samples remaining, 17 used
00160     };
00161 
00162     /**
00163      * @brief   Mode Control
00164      * @details Operating mode
00165      */
00166     enum mode_t {
00167         MODE_1LED = 0x2, ///< Single Red LED mode
00168         MODE_2LED = 0x3, ///< Red and IR LED mode
00169         MODE_MULTI = 0x7, ///< Multi LED mode Red, IR, and/or Green
00170     };
00171 
00172     /**
00173      * @brief   ADC Range
00174      * @details Sets the full scale range of the ADC
00175      */
00176     enum adc_rge_t {
00177         ADC_RGE_00 = (0 << 5), ///< 2048nA full scale, 7.81pA LSB
00178         ADC_RGE_01 = (1 << 5), ///< 4096nA full scale, 15.63pA LSB
00179         ADC_RGE_10 = (2 << 5), ///< 8192nA full scale, 31.25pA LSB
00180         ADC_RGE_11 = (3 << 5), ///< 16384nA full scale, 62.5pA LSB
00181     };
00182 
00183     /**
00184      * @brief   Sample Rate
00185      * @details Sets the sample rate of the pulses for each enabled LED
00186      */
00187     enum smp_rt_t {
00188         SMP_RT_50 = (0 << 2), ///< 50 Samples per second
00189         SMP_RT_100 = (1 << 2), ///< 100 Samples per second
00190         SMP_RT_200 = (2 << 2), ///< 200 Samples per second
00191         SMP_RT_400 = (3 << 2), ///< 400 Samples per second
00192         SMP_RT_800 = (4 << 2), ///< 800 Samples per second
00193         SMP_RT_1000 = (5 << 2), ///< 1000 Samples per second
00194         SMP_RT_1600 = (6 << 2), ///< 1600 Samples per second
00195         SMP_RT_3200 = (7 << 2), ///< 3200 Samples per second
00196     };
00197 
00198     /**
00199      * @brief   Pulse Width
00200      * @details Sets the pulse width for the channel
00201      */
00202     enum led_pw_t {
00203         LED_PW_15BIT = 0, ///< 69us, 15 bit resolution
00204         LED_PW_16BIT = 1, ///< 118us, 16 bit resolution
00205         LED_PW_17BIT = 2, ///< 215us, 17 bit resolution
00206         LED_PW_18BIT = 3, ///< 411us, 18 bit resolution
00207     };
00208 
00209     /**
00210      * @brief   Slot Control
00211      * @details Sets the active LED and pulse amplitude for the slot
00212      */
00213     enum slot_t {
00214         SLOT_DISABLED = 0, ///< No LED active
00215         SLOT_RED_LED1 = 1, ///< Red, LED1_PA
00216         SLOT_IR_LED2 = 2, ///< IR, LED3_PA
00217         SLOT_GREEN_LED3 = 3, ///< Green, LED3_PA
00218         SLOT_NONE = 4, ///< No LED active
00219         SLOT_RED_PILOT = 5, ///< Red, PILOT_PA
00220         SLOT_IR_PILOT = 6, ///< IR, PILOT_PA
00221         SLOT_GREEN_PILOT = 7, ///< Green, PILOT_PA
00222     };
00223 
00224     static const char INTR_A_FULL = (1 <<7);
00225     static const char INTR_DATA_RDY = (1 <<6);
00226     static const char INTR_ALC_OVF = (1 <<5);
00227     static const char INTR_PROX = (1 <<4);
00228     static const char INTR_PWR_RDY = (1 <<0);
00229     static const char INTR_TEMP_RDY = (1 <<1);
00230 
00231     static const char MASK_SMP_AVE = (7 <<5);
00232     static const char MASK_FIFO_ROLLOVER_EN = (1 <<4);
00233     static const char MASK_FIFO_A_FULL = (0xF <<0);
00234 
00235     static const char MASK_SHDN = (1 <<7);
00236     static const char MASK_RESET = (1 <<6);
00237     static const char MASK_MODE = (7 <<0);
00238 
00239     static const char MASK_ADC_RGE = (3 <<5);
00240     static const char MASK_SMP_RT = (7 <<2);
00241     static const char MASK_LED_PW = (3 <<0);
00242 
00243     static const char MASK_SLOT2 = (7 <<4);
00244     static const char MASK_SLOT1 = (7 <<0);
00245     static const char MASK_SLOT4 = (7 <<4);
00246     static const char MASK_SLOT3 = (7 <<0);
00247 
00248     /**
00249         * MAX30105 constructor.
00250         *
00251         * @param i2c I2C object to use.
00252         */
00253     MAX30105(I2C &i2c);
00254 
00255     /**
00256         * MAX30105 destructor.
00257         */
00258     ~MAX30105();
00259 
00260     /**
00261      * @brief   Get Interrupt 1
00262      * @details Reads Interrupt 1
00263      * @returns contents of REG_INTR_STATUS_1, or -1 if error.
00264     */
00265     int getIntr1();
00266 
00267     /**
00268      * @brief   Get Interrupt 2
00269      * @details Reads Temp Interrupt
00270      * @returns contents of REG_INTR_STATUS_2, or -1 if error.
00271     */
00272     int getIntr2();
00273 
00274     /**
00275      * @brief   Enable Interrupt
00276      * @details Enables any interrupt whos bit is set
00277      * @param   intrBits bit mask of interrupts to enable
00278      * @returns 0 if no errors, -1 if error.
00279     */
00280     int enableIntr(char intrBits);
00281 
00282     /**
00283      * @brief   Disable Interrupt
00284      * @details Disables any interrupt whos bit is set
00285      * @param   intrBits bit mask of interrupts to disable
00286      * @returns 0 if no errors, -1 if error.
00287     */
00288     int disableIntr(char intrBits);
00289 
00290     /**
00291      * @brief   Configure Proximity Function
00292      * @details Sets amplitude and threshold for proximity detector
00293      *          Set threshold to 0x00 to disable proximity detecotr
00294      * @param   proxAmp The amplitude of the proximity pulse 50mA/255 steps
00295      * @param   proxThresh The detect threshold to start sensing
00296      * @returns 0 if no errors, -1 if error.
00297     */
00298     int setProx(char proxAmp, char proxThresh);
00299 
00300     /**
00301      * @brief   Configure Single LED Mode
00302      * @details Configures part for single LED mode.
00303      * @param   smpAve number of samples to average
00304      * @param   fifoRollOver enables FIFO to roll over when full
00305      * @param   fifoAFull sets FIFO almost full level
00306      * @param   adcRange sets ADC range
00307      * @param   smpRate sets sample rate
00308      * @param   ledPW sets LED pulse width
00309      * @param   led1PA sets pulse amplitude for LED1
00310      * @returns 0 if no errors, -1 if error.
00311     */
00312     int setSingleLED(smp_ave_t smpAve = SMP_AVE_1,
00313                      bool fifoRollOver = false,
00314                      fifo_a_full_t fifoAFull = FIFO_A_FULL_F,
00315                      adc_rge_t adcRange = ADC_RGE_01,
00316                      smp_rt_t smpRate = SMP_RT_100,
00317                      led_pw_t ledPW = LED_PW_18BIT,
00318                      char led1PA = MAX30105_DEFAULT_LED_PA);
00319 
00320     /**
00321      * @brief   Configure Dual LED Mode
00322      * @details Configures part for dual LED mode.
00323      * @param   smpAve number of samples to average
00324      * @param   fifoRollOver enables FIFO to roll over when full
00325      * @param   fifoAFull sets FIFO almost full level
00326      * @param   adcRange sets ADC range
00327      * @param   smpRate sets sample rate
00328      * @param   ledPW sets LED pulse width
00329      * @param   led1PA sets pulse amplitude for LED1
00330      * @param   led2PA sets pulse amplitude for LED2
00331      * @returns 0 if no errors, -1 if error.
00332     */
00333     int setDualLED(smp_ave_t smpAve = SMP_AVE_1,
00334                    bool fifoRollOver = false,
00335                    fifo_a_full_t fifoAFull = FIFO_A_FULL_F,
00336                    adc_rge_t adcRange = ADC_RGE_01,
00337                    smp_rt_t smpRate = SMP_RT_100,
00338                    led_pw_t ledPW = LED_PW_18BIT,
00339                    char led1PA = MAX30105_DEFAULT_LED_PA,
00340                    char led2PA = MAX30105_DEFAULT_LED_PA);
00341 
00342     /**
00343      * @brief   Configure Multi LED Mode
00344      * @details Configures part for multi LED mode.
00345      * @param   smpAve number of samples to average
00346      * @param   fifoRollOver enables FIFO to roll over when full
00347      * @param   fifoAFull sets FIFO almost full level
00348      * @param   adcRange sets ADC range
00349      * @param   smpRate sets sample rate
00350      * @param   ledPW sets LED pulse width
00351      * @param   led1PA sets pulse amplitude for LED1
00352      * @param   led2PA sets pulse amplitude for LED2
00353      * @param   led3PA sets pulse amplitude for LED3
00354      * @param   pilotPA sets pulse amplitude for pilot
00355      * @param   slot1 assigns LED and amplitude to slot 1
00356      * @param   slot2 assigns LED and amplitude to slot 2
00357      * @param   slot3 assigns LED and amplitude to slot 3
00358      * @param   slot4 assigns LED and amplitude to slot 4
00359      * @returns 0 if no errors, -1 if error.
00360     */
00361     int setMultiLED(smp_ave_t smpAve = SMP_AVE_1,
00362                     bool fifoRollOver = false,
00363                     fifo_a_full_t fifoAFull = FIFO_A_FULL_F,
00364                     adc_rge_t adcRange = ADC_RGE_01,
00365                     smp_rt_t smpRate = SMP_RT_100,
00366                     led_pw_t ledPW = LED_PW_18BIT,
00367                     char led1PA = MAX30105_DEFAULT_LED_PA,
00368                     char led2PA = MAX30105_DEFAULT_LED_PA,
00369                     char led3PA = MAX30105_DEFAULT_LED_PA,
00370                     char pilotPA = MAX30105_DEFAULT_PILOT_PA,
00371                     slot_t slot1 = SLOT_RED_LED1,
00372                     slot_t slot2 = SLOT_IR_LED2,
00373                     slot_t slot3 = SLOT_GREEN_LED3,
00374                     slot_t slot4 = SLOT_DISABLED);
00375 
00376 
00377     /**
00378      * @brief   Initialize MAX30105
00379      * @details Intializes settings for the MAX30105
00380      * @returns 0 if no errors, -1 if error.
00381     */
00382     int init();
00383 
00384     /**
00385      * @brief   Read FIFOs
00386      * @details Reads from the red and IR FIFOs
00387      * @param   redLED Pointer for where to store red LED data
00388      * @param   irLED Pointer for where to store IR LED data
00389      * @returns 0 if no errors, -1 if error.
00390     */
00391     int readFIFO(uint32_t *redLED, uint32_t *irLED);
00392 
00393     /**
00394      * @brief   Read Temperature
00395      * @details Read the die temperature of the MAX30105
00396      * @returns Temperature in degrees C, or -999.0 if error
00397     */
00398     float readTemperature();
00399 
00400     /**
00401      * @brief   Reset MAX30105
00402      * @details Resets regsisters to their power on defaults
00403      * @returns 0 if no errors, -1 if error.
00404     */
00405     int softReset();
00406 
00407     /**
00408      * @brief   Shutdown MAX30105
00409      * @details Puts MAX30105 in power-save mode, retaining regsiter settings
00410      * @returns 0 if no errors, -1 if error.
00411     */
00412     int shutDown();
00413 
00414     /**
00415      * @brief   Wake Up MAX30105
00416      * @details Wakes MAX30105 from power-save mode
00417      * @returns 0 if no errors, -1 if error.
00418     */
00419     int wakeUp();
00420 
00421     /**
00422      * @brief   Write Register
00423      * @details Writes the given value to the specified register.
00424      * @param   reg The register to be written
00425      * @param   value The data to be written
00426      * @returns 0 if no errors, -1 if error.
00427     */
00428     int writeReg(registers_t reg, char value);
00429 
00430     /**
00431      * @brief   Read Register
00432      * @details Reads from the specified register
00433      * @param   reg The register to be read
00434      * @param   value Pointer for where to store the data
00435      * @returns 0 if no errors, -1 if error.
00436     */
00437     int readReg(registers_t reg, char *value);
00438 
00439 private:
00440     // Internal Resources
00441     I2C _i2c;
00442 
00443     // Configuration Register Cache
00444     char _interruptEnable1;
00445     char _interruptEnable2;
00446     char _fifoConfiguration;
00447     char _modeConfiguration;
00448     char _spo2Configuration;
00449     char _led1PulseAmplitude;
00450     char _led2PulseAmplitude;
00451     char _led3PulseAmplitude;
00452     char _pilotPulseAmplitude;
00453     char _multiLedControl1;
00454     char _multiLedControl2;
00455     char _proxIntThreshold;
00456 };
00457 
00458 #endif /* _MAX30105_H_ */