Firmware enhancements for HSP_RPC_GUI 3.0.1

Dependencies:   USBDevice

Fork of HSP_RPC_GUI by Maxim Integrated

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers MAX30101.h Source File

MAX30101.h

00001 /*******************************************************************************
00002 / * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved.
00003  *
00004  * Permission is hereby granted, free of charge, to any person obtaining a
00005  * copy of this software and associated documentation files (the "Software"),
00006  * to deal in the Software without restriction, including without limitation
00007  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
00008  * and/or sell copies of the Software, and to permit persons to whom the
00009  * Software is furnished to do so, subject to the following conditions:
00010  *
00011  * The above copyright notice and this permission notice shall be included
00012  * in all copies or substantial portions of the Software.
00013  *
00014  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00015  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00016  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
00017  * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
00018  * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
00019  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
00020  * OTHER DEALINGS IN THE SOFTWARE.
00021  *
00022  * Except as contained in this notice, the name of Maxim Integrated
00023  * Products, Inc. shall not be used except as stated in the Maxim Integrated
00024  * Products, Inc. Branding Policy.
00025  *
00026  * The mere transfer of this software does not imply any licenses
00027  * of trade secrets, proprietary technology, copyrights, patents,
00028  * trademarks, maskwork rights, or any other form of intellectual
00029  * property whatsoever. Maxim Integrated Products, Inc. retains all
00030  * ownership rights.
00031  *******************************************************************************/
00032 /** 
00033  * Maxim Integrated MAX30101 Oximeter chip
00034  *  
00035  * IMPORTANT: The code below will also need MAX14720.cpp and MAX14720.h
00036  * 
00037  * @code
00038  * #include "mbed.h"
00039  * #include "MAX14720.h"
00040  * #include "MAX30101.h"
00041  * 
00042  * 
00043  * /// define the HVOUT Boost Voltage default for the MAX14720 PMIC
00044  * #define HVOUT_VOLTAGE 4500 // set to 4500 mV
00045  * 
00046  * /// define all I2C addresses
00047  * #define MAX14720_I2C_SLAVE_ADDR (0x54)
00048  * #define MAX30101_I2C_SLAVE_ADDR (0xAE)
00049  * 
00050  * /// Settings for the HR initialization
00051  * #define FIFO_WATERLEVEL_MARK 15
00052  * #define SAMPLE_AVG           2
00053  * #define SAMPLE_RATE          1
00054  * #define PULSE_WIDTH          2
00055  * #define RED_LED_CURRENT      0x1F
00056  *  
00057  *  /// Buffer size for streaming data out.
00058  * #define BUFFER_LENGTH 50 
00059  * 
00060  * 
00061  * /// I2C Master 2
00062  * I2C i2c2(I2C2_SDA, I2C2_SCL); // used by MAX14720, MAX30101, LIS2DH
00063  * /// SPI Master 0 with SPI0_SS for use with MAX30001
00064  *  SPI spi(SPI0_MOSI, SPI0_MISO, SPI0_SCK, SPI0_SS); // used by MAX30001
00065  * 
00066  * /// PMIC
00067  * MAX14720 max14720(&i2c2, MAX14720_I2C_SLAVE_ADDR);
00068  * /// Optical Oximeter
00069  * MAX30101 max30101(&i2c2, MAX30101_I2C_SLAVE_ADDR);
00070  * InterruptIn max30101_Interrupt(P4_0);
00071  * 
00072  * //@brief Creating a buffer to hold the data
00073  * uint32_t oxiBuffer[BUFFER_LENGTH];
00074  * int oxiIndex = 0;
00075  * char data_trigger = 0;
00076  *  
00077  *
00078  * //@brief Creates a packet that will be streamed via USB Serial
00079  * //@brief the packet created will be inserted into a fifo to be streamed at a later time
00080  * //@param id Streaming ID
00081  * //@param buffer Pointer to a uint32 array that contains the data to include in the packet
00082  * //@param number Number of elements in the buffer
00083  * //
00084  * void StreamPacketUint32_ex(uint32_t id, uint32_t *buffer, uint32_t number) {
00085  *   int i;
00086  *   if (id == MAX30101_OXIMETER_DATA + 1) {
00087  * 
00088  *     for (i = 0; i < number; i++) {
00089  *       oxiBuffer[oxiIndex] = buffer[i];
00090  *       oxiIndex++;
00091  *           
00092  *       if (oxiIndex > BUFFER_LENGTH)
00093  *         {
00094  *         data_trigger = 1;
00095  *         oxiIndex = 0;
00096  *         }
00097  *     }
00098  *   }
00099  * }
00100  * 
00101  * int main() {
00102  *   // hold results for returning functions
00103  *   int result;
00104  * 
00105  *   // initialize HVOUT on the MAX14720 PMIC
00106  *   result = max14720.init();
00107  *   if (result == MAX14720_ERROR){
00108  *     printf("Error initializing MAX14720");
00109  *     }
00110  *   max14720.boostEn = MAX14720::BOOST_ENABLED;
00111  *   max14720.boostSetVoltage(HVOUT_VOLTAGE);
00112  * 
00113  *   // MAX30101 initialize interrupt
00114  *   max30101.onDataAvailable(&StreamPacketUint32_ex);
00115  *   max30101_Interrupt.fall(&MAX30101::MAX30101MidIntHandler);
00116  *   
00117  *   // This is the HR mode only (IR LED only)  
00118  *   max30101.HRmode_init(FIFO_WATERLEVEL_MARK, SAMPLE_AVG, SAMPLE_RATE,PULSE_WIDTH, RED_LED_CURRENT); 
00119  * 
00120  *   printf("Please wait for data to start streaming\n");
00121  *   fflush(stdout);
00122  *   
00123  *   while (1) {
00124  *     if(data_trigger == 1)
00125  *      {
00126  *       printf("%ld ", oxiBuffer[oxiIndex]);  // Print the ECG data on a serial port terminal software
00127  *       fflush(stdout);
00128  *      }
00129  *   } 
00130  * }
00131  * @endcode
00132  *
00133  */
00134 
00135 #ifndef _MAX30101_H_
00136 #define _MAX30101_H_
00137 
00138 #include "mbed.h"
00139 
00140 #define MAX30101_RAW_DATA_SIZE 3 * 4 * 32
00141 #define MAX30101_PROC_DATA_SIZE 4 * 32
00142 
00143 #define MAX30101_OXIMETER_DATA 0x10
00144 
00145 #define CHUNK_SIZE 252
00146 
00147 ///< MAX30101 Register addresses
00148 
00149 #define MAX30101_INT_PORT 4
00150 #define MAX30101_INT_PIN 0
00151 #define MAX30101_MASTER_NUM 2
00152 
00153 /**
00154 * Maxim Integrated MAX30101 Oximeter chip
00155 */
00156 class MAX30101 {
00157 public:
00158   float max30101_final_temp;                         ///< Global declaration
00159   uint32_t max30101_buffer[MAX30101_PROC_DATA_SIZE]; ///< final Processed data
00160   char max30101_rawData[MAX30101_RAW_DATA_SIZE];     ///<  raw data from the chip
00161 
00162   typedef enum { ///< MAX30101 Register addresses
00163 
00164     ///< Status
00165     REG_INT_STAT_1 = 0x00,
00166     REG_INT_STAT_2 = 0x01,
00167     REG_INT_EN_1   = 0x02,
00168     REG_INT_EN_2   = 0x03,
00169 
00170     REG_FIFO_W_PTR   = 0x04,
00171     REG_FIFO_OVF_CNT = 0x05,
00172     REG_FIFO_R_PTR   = 0x06,
00173     REG_FIFO_DATA    = 0x07,
00174     ///< Configuration
00175     REG_FIFO_CFG  = 0x08,
00176     REG_MODE_CFG  = 0x09,
00177     REG_SPO2_CFG  = 0x0A,
00178     REG_LED1_PA   = 0x0C,
00179     REG_LED2_PA   = 0x0D,
00180     REG_LED3_PA   = 0x0E,
00181     REG_PILOT_PA  = 0x10,
00182     REG_SLT2_SLT1 = 0x11,
00183     REG_SLT4_SLT3 = 0x12,
00184     ///< Die Temp
00185     REG_TINT    = 0x1F,
00186     REG_TFRAC   = 0x20,
00187     REG_TEMP_EN = 0x21,
00188     ///< Proximity Func
00189     REG_PROX_INT_THR = 0x30,
00190     /* Part ID        */
00191     REG_REV_ID = 0xFE,
00192     REG_ID     = 0xFF,
00193   } MAX30101_REG_map_t ;
00194 
00195   /**********/
00196   /* STATUS */
00197   /**********/
00198   /// @brief STATUS1 (0x00)
00199   typedef union max30101_Interrupt_Status_1_reg {
00200     char all;
00201     struct {
00202       char pwr_rdy  : 1;
00203       char reserved : 3;
00204       char prox_int : 1;
00205       char alc_ovf  : 1;
00206       char ppg_rdy  : 1;
00207       char a_full   : 1;
00208     } bit;
00209   } max30101_Interrupt_Status_1_t;
00210 
00211   /// @brief STATUS2 (0x01)
00212   typedef union max30101_Interrupt_Status_2_reg {
00213     char all;
00214     struct {
00215       char reserved1    : 1;
00216       char die_temp_rdy : 1;
00217       char reserved2    : 6;
00218     } bit;
00219   } max30101_Interrupt_Status_2_t;
00220 
00221   /// @brief INTERRUPT_ENABLE1 (0x02)
00222   typedef union max30101_Interrupt_Enable_1_reg {
00223     char all;
00224     struct {
00225       char reserved1   : 4;
00226       char prox_int_en : 1;
00227       char alc_ovf_en  : 1;
00228       char ppg_rdy_en  : 1;
00229       char a_full_en   : 1;
00230     } bit;
00231   } max30101_Interrupt_Enable_1_t;
00232 
00233   /// @brief INTERRUPT_ENABLE2 (0x03)
00234   typedef union max30101_Interrupt_Enable_2_reg {
00235     char all;
00236     struct {
00237       char reserved1       : 1;
00238       char die_temp_rdy_en : 1;
00239       char reserved2       : 6;
00240     } bit;
00241   } max30101_Interrupt_Enable_2_t;
00242 
00243   /*********/
00244   /* FIFO  */
00245   /*********/
00246   // 0x04
00247   /// @brief FIFO_WR_PTR (0x04)
00248   typedef union max30101_fifo_wr_ptr_reg {
00249     char all;
00250     struct {
00251       char fifo_wr_ptr : 5;
00252       char reserved1   : 3;
00253     } bit;
00254   } max30101_fifo_wr_ptr_t;
00255 
00256   /// @brief OVF_COUNTER (0x05)
00257   typedef union max30101_ovf_counter_reg {
00258     char all;
00259     struct {
00260       char fifo_ovf_counter : 5;
00261       char reserved1        : 3;
00262     } bit;
00263   } max30101_ovf_counter_reg_t;
00264 
00265   /// @brief FIFO_READ_PTR (0x06)
00266   typedef union max30101_fifo_rd_ptr_reg {
00267     char all;
00268     struct {
00269       char fifo_rd_ptr : 5;
00270       char reserved1   : 3;
00271     } bit;
00272   } max30101_fifo_rd_ptr_t;
00273 
00274   /********************/
00275   /* Configuration    */
00276   /********************/
00277   // 0x08
00278   /// @brief FIFO_CONFIGURATION (0x08)
00279   typedef union max30101_fifo_configuration_reg {
00280     char all;
00281     struct {
00282       char fifo_a_full       : 4;
00283       char fifo_roll_over_en : 1;
00284       char smp_ave           : 3;
00285     } bit;
00286   } max30101_fifo_configuration_t;
00287 
00288   /// @brief MODE_CONFIGURATION (0x09)
00289   typedef union max30101_mode_configuration_reg {
00290     char all;
00291     struct {
00292       char mode      : 3;
00293       char reserved1 : 3;
00294       char reset     : 1;
00295       char shdn      : 1;
00296     } bit;
00297   } max30101_mode_configuration_t;
00298 
00299   /// @brief SPO2_CONGIGURATION (0x0A)
00300   typedef union max30101_spo2_configuration_reg {
00301     char all;
00302     struct {
00303       char led_pw       : 2;
00304       char spo2_sr      : 3;
00305       char spo2_adc_rge : 2;
00306       char reserved1    : 1;
00307     } bit;
00308   } max30101_spo2_configuration_t;
00309 
00310   typedef union max30101_multiLED_mode_ctrl_1_reg {
00311     char all;
00312     struct {
00313       char slot1     : 3;
00314       char reserved  : 1;
00315       char slot2     : 3;
00316       char reserved1 : 1;
00317     } bit;
00318   } max30101_multiLED_mode_ctrl_1_t;
00319 
00320   typedef union max30101_multiLED_mode_ctrl_2_reg {
00321     char all;
00322     struct {
00323       char slot3     : 3;
00324       char reserved  : 1;
00325       char slot4     : 3;
00326       char reserved1 : 1;
00327     } bit;
00328   } max30101_multiLED_mode_ctrl_2_t;
00329 
00330   /********************/
00331   /* Die Temperature  */
00332   /********************/
00333 
00334   char max30101_tinit;
00335 
00336   char max30101_tfrac;
00337 
00338   typedef union max30101_die_temp_config {
00339     char all;
00340     struct {
00341       char temp_en  : 1;
00342       char reserved : 7;
00343     } bit;
00344   } max30101_die_temp_config_t;
00345 
00346   /***** Function Prototypes *****/
00347 
00348   char max30101_prox_int_thresh;
00349 
00350   /**
00351   * @brief MAX30101 constructor.
00352   * @param sda mbed pin to use for SDA line of I2C interface.
00353   * @param scl mbed pin to use for SCL line of I2C interface.
00354   */
00355   MAX30101(PinName sda, PinName scl, int slaveAddress);
00356 
00357   /**
00358   * @brief MAX30101 constructor.
00359   * @param i2c I2C object to use.
00360   */
00361   MAX30101(I2C *i2c, int slaveAddress);
00362 
00363   /**
00364   * @brief MAX30101 destructor.
00365   */
00366   ~MAX30101(void);
00367 
00368   /**
00369    * @brief Allows reading from MAX30101 register
00370    * @param reg: is the register address, to read from (look at max30101.h and the
00371    *             data sheet for details)
00372    * @param value: is the pointer to the value read from the register
00373    * @returns  0-if no error.  A non-zero value indicates an error.
00374    */
00375   int i2c_reg_read(MAX30101_REG_map_t  reg, char *value);
00376 
00377   /**
00378    * @brief Allows writing to MAX30101 register
00379    * @param reg: is the register address, to read from (look at max30101.h and
00380    * the data sheet for details)
00381    * @param value: is the value to write to the register
00382    * @returns  0-if if no error.  A non-zero value indicates an error.
00383    */
00384   int i2c_reg_write(MAX30101_REG_map_t  reg, char value);
00385 
00386   /**
00387    * @brief This function sets up for the SpO2 mode.  The data is returned in
00388    * the callback function
00389    * @brief max30101_int_handler in global array: buffer[].  SP mode handles two LED (Red,IR) data.  Hence it
00390    * @brief can fill up the FIFO up to a maximum of 3bytes/sample x 32 x 2 = 192bytes.
00391    * @param fifo_waterlevel_mark: corresponds to FIFO_A_FULL, In FIFO Configuration Register (0x08)
00392    * @param sample_avg: corresponds to SMP_AVE, in FIFO Configuration Register (0x08)
00393    * @param sample_rate: corresponds to SPO2_SR, IN SpO2 Configuration Register (0x0A)
00394    * @param pulse_width: corresponds to LED_PW in SpO2 Configuration register(0x0A)
00395    * @param red_led_current: corresponds to LED1_PA register (0x0C).  Please see data sheet for values
00396    * @param ir_led_current: corresponds to LED2_PA register (0x0D).  Please see data sheet for values
00397    * @returns 0-if everything is good.  A non-zero value indicates an error.
00398    */
00399   int SpO2mode_init(uint8_t fifo_waterlevel_mark, uint8_t sample_avg,
00400                     uint8_t sample_rate, uint8_t pulse_width,
00401                     uint8_t red_led_current, uint8_t ir_led_current);
00402 
00403   /**
00404    * @brief This function will stop the SpO2 mode and turn off all operating LED�s.
00405    * @return  0-if if no error.  A non-zero value indicates an error.
00406    */
00407   int SpO2mode_stop(void);
00408 
00409   /**
00410    * @brief This function sets up for the HR mode.  The data is returned in thecallback function
00411    * @brief max30101_int_handler in global array: buffer[].HR mode handles one LED (Red) data.  Hence it can fill
00412    * @brief up the FIFO up to a maximum of 3bytes/sample x 32 = 96bytes.
00413    * @brief fifo_waterlevel_mark: corresponds to FIFO_A_FULL, In FIFO Configuration Register (0x08)
00414    * @param sample_avg: corresponds to SMP_AVE, in FIFO Configuration Register (0x08)
00415    * @param sample_rate:corresponds to SPO2_SR, IN SpO2 Configuration Register (0x0A)
00416    * @param pulse_width: corresponds to LED_PW in SpO2 Configuration Register(0x0A)
00417    * @param red_led_current: corresponds to LED1_PA register (0x0C).  Please see data sheet for values
00418    * @returns  0-if if no error.  A non-zero value indicates an error.
00419    */
00420   int HRmode_init(uint8_t fifo_waterlevel_mark, uint8_t sample_avg,
00421                   uint8_t sample_rate, uint8_t pulse_width,
00422                   uint8_t red_led_current);
00423 
00424   /**
00425    * @brief This function will stop the HR mode and turn off all operating
00426    * LED’s.
00427    * @return  0-if if no error.  A non-zero value indicates an error.
00428    */
00429   int HRmode_stop(void);
00430 
00431   /**
00432    *@brief This function sets up for the Multi-mode.  The data is returned in the callback function max30101_int_handler in global array:
00433    *@brief buffer[].  Multi-LED mode can handle 1 to 4 LED combinations.  Hence it can fill up the FIFO up to a maximum of
00434    *@brief 3bytes/sample x 32 x 4 = 384bytes.
00435    *@param fifo_waterlevel_mark: corresponds to FIFO_A_FULL, In FIFO Configuration Register (0x08)
00436    *@param sample_avg: corresponds to SMP_AVE, in FIFO Configuration Register (0x08)
00437    *@param sample_rate:corresponds to SPO2_SR, IN SpO2 Configuration Register (0x0A)
00438    *@param pulse_width: corresponds to LED_PW in SpO2 Configuration register(0x0A)
00439    *@param red_led_current: corresponds to LED1_PA register (0x0C).  Please see data sheet for values
00440    *@param ir_led_current: corresponds to LED2_PA register (0x0D).  Please see data sheet for values
00441    *@param green_led_current: corresponds to LED3_PA register (0x0E).  Please see data sheet for values
00442    *@param slot_1,…,slot_4: corresponds to Multi-LED Mode control Registers (0x11-0x12).
00443    *@returns  0-if if no error.  A non-zero value indicates an error.
00444    */
00445   int Multimode_init(uint8_t fifo_waterlevel_mark, uint8_t sample_avg,
00446                      uint8_t sample_rate, uint8_t pulse_width,
00447                      uint8_t red_led_current, uint8_t ir_led_current,
00448                      uint8_t green_led_current, uint8_t slot_1, uint8_t slot_2,
00449                      uint8_t slot_3, uint8_t slot_4);
00450 
00451   /**
00452    * @brief This function will stop the Multi-mode and turn off all operating LED’s.
00453    * @returns  0-if if no error.  A non-zero value indicates an error.
00454    */
00455   int Multimode_stop(void);
00456 
00457   /**
00458    * @brief This is a function that sets up for temperature read and should be called after one of the mode
00459    * @brief has been setup.  The data is returned in the callback function max30101_int_handler.  This
00460    * @brief function needs to be called every time temperature reading is required.
00461    * @brief Call the temp function after one of the MODES have been started
00462    * @brief Note that the temp is disabled after one read... also, it is not necessary
00463    * @brief to read the temp frequently...
00464    * @returns  0-if if no error.  A non-zero value indicates an error.
00465    */
00466   int tempread(void);
00467 
00468   /**
00469    *@brief This is a callback function which collects the data from the FIFO of the MAX30101 in a 32-bit
00470    *@brief unsigned global array called max30101_buffer[].  Upon every interrupt from the MAX30101, this
00471    *@brief function is called to service the FIFO of the MAX30101.  This callback function also services the
00472    *@brief interrupt for the temp data.  The temp data is collected in a floating point global variable
00473    *@brief final_temp.
00474    *@param max30101_buffer[], global uint32_t
00475    *@returns  0-if everything is good.  A non-zero value indicates an error.
00476    */
00477   int int_handler(void);
00478   
00479    /**
00480   * @brief encapsulates the int_handler above
00481   */
00482   static void MidIntHandler(void);
00483   
00484   /**
00485   * @brief type definition for data interrupt
00486   */
00487   typedef void (*DataCallbackFunction)(uint32_t id, uint32_t *buffer,
00488                                        uint32_t length);
00489   /**
00490   * @brief type definition for general interrupt
00491   */
00492   typedef void (*InterruptFunction)();
00493 
00494   /**
00495   * @brief Used to connect a callback for when interrupt data is available
00496   */
00497   void onInterrupt(InterruptFunction _onInterrupt);
00498 
00499   /**
00500   * @brief Used to connect a callback for when interrupt data is available
00501   */
00502   void onDataAvailable(DataCallbackFunction _onDataAvailable);
00503 
00504   static MAX30101 *instance;
00505 
00506 private:
00507   /**
00508    * @brief Used to notify an external function that interrupt data is available
00509    * @param id type of data available
00510    * @param buffer 32-bit buffer that points to the data
00511    * @param length length of 32-bit elements available
00512    */
00513   void dataAvailable(uint32_t id, uint32_t *buffer, uint32_t length);
00514 
00515 
00516   /**
00517    * @brief Executed on interrupt (callback function at the end of the interrupt)
00518    * @param id type of data available
00519    * @param buffer 32-bit buffer that points to the data
00520    * @param length length of 32-bit elements available
00521    */
00522   void interruptPostCallback(void);
00523 
00524   /// callback function when interrupt data is available
00525   DataCallbackFunction onDataAvailableCallback;
00526 
00527   /// callback function when interrupt data is available
00528   InterruptFunction onInterruptCallback;
00529 
00530   /**
00531    * @brief Read from an I2C device (Read I2c wrapper method)
00532    * @param slaveAddress slave address to use with transaction
00533    * @param writeData pointer of data to write
00534    * @param writeCount number of data to write
00535    * @param readData pointer to buffer to read to
00536    * @param readCount number of bytes to read
00537    */
00538 
00539   int I2CM_Read(int slaveAddress, char *writeData, char writeCount, char *readData, char readCount);
00540   
00541   /**
00542    * @brief Write to an I2C device (I2C wrapper method)
00543    * @param slaveAddress slave address to use with transaction
00544    * @param writeData1 pointer of data to write
00545    * @param writeCount1 number of data to write
00546    * @param writeData2 pointer to buffer to read to
00547    * @param writeCount2 number of bytes to read
00548    */
00549   int I2CM_Write(int slaveAddress, char *writeData1, char writeCount1, char *writeData2, char writeCount2);
00550 
00551   /// @brief pointer to I2C object
00552   I2C *i2c;
00553 
00554   /// @brief flag to track if this object is the owner (created) the I2C object
00555   bool i2c_owner;
00556 
00557   /// @brief Device slave address
00558   int slaveAddress;
00559 };
00560 
00561   /**
00562    *  @brief Resets the I2C block, when needed
00563    */
00564 extern void I2CM_Init_Reset(uint8_t index, int speed);
00565 
00566 
00567 
00568 #endif /* _MAX30101_H_ */