Driver, C++ source code, and library for the MAX30101 heart rate sensor chip. The MAX30101 IC includes integrated LEDs and photodetectors for the collection of raw data for Heart Rate/Pulse Rate monitoring and for SpO2 (blood oxygen saturation) levels.

Dependents:   MAX30101_Heart_Rate_Sp02_Sensor_Chip MAX30101_Heart_Rate_Sp02_SENSOR_Hello_World

Committer:
phonemacro
Date:
Sat Jul 21 07:30:15 2018 +0000
Revision:
0:b0addee6d8d1
convert to library from folder

Who changed what in which revision?

UserRevisionLine numberNew contents of line
phonemacro 0:b0addee6d8d1 1 /*******************************************************************************
phonemacro 0:b0addee6d8d1 2 / * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved.
phonemacro 0:b0addee6d8d1 3 *
phonemacro 0:b0addee6d8d1 4 * Permission is hereby granted, free of charge, to any person obtaining a
phonemacro 0:b0addee6d8d1 5 * copy of this software and associated documentation files (the "Software"),
phonemacro 0:b0addee6d8d1 6 * to deal in the Software without restriction, including without limitation
phonemacro 0:b0addee6d8d1 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
phonemacro 0:b0addee6d8d1 8 * and/or sell copies of the Software, and to permit persons to whom the
phonemacro 0:b0addee6d8d1 9 * Software is furnished to do so, subject to the following conditions:
phonemacro 0:b0addee6d8d1 10 *
phonemacro 0:b0addee6d8d1 11 * The above copyright notice and this permission notice shall be included
phonemacro 0:b0addee6d8d1 12 * in all copies or substantial portions of the Software.
phonemacro 0:b0addee6d8d1 13 *
phonemacro 0:b0addee6d8d1 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
phonemacro 0:b0addee6d8d1 15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
phonemacro 0:b0addee6d8d1 16 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
phonemacro 0:b0addee6d8d1 17 * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
phonemacro 0:b0addee6d8d1 18 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
phonemacro 0:b0addee6d8d1 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
phonemacro 0:b0addee6d8d1 20 * OTHER DEALINGS IN THE SOFTWARE.
phonemacro 0:b0addee6d8d1 21 *
phonemacro 0:b0addee6d8d1 22 * Except as contained in this notice, the name of Maxim Integrated
phonemacro 0:b0addee6d8d1 23 * Products, Inc. shall not be used except as stated in the Maxim Integrated
phonemacro 0:b0addee6d8d1 24 * Products, Inc. Branding Policy.
phonemacro 0:b0addee6d8d1 25 *
phonemacro 0:b0addee6d8d1 26 * The mere transfer of this software does not imply any licenses
phonemacro 0:b0addee6d8d1 27 * of trade secrets, proprietary technology, copyrights, patents,
phonemacro 0:b0addee6d8d1 28 * trademarks, maskwork rights, or any other form of intellectual
phonemacro 0:b0addee6d8d1 29 * property whatsoever. Maxim Integrated Products, Inc. retains all
phonemacro 0:b0addee6d8d1 30 * ownership rights.
phonemacro 0:b0addee6d8d1 31 *******************************************************************************/
phonemacro 0:b0addee6d8d1 32 /**
phonemacro 0:b0addee6d8d1 33 * Maxim Integrated MAX30101 Oximeter chip
phonemacro 0:b0addee6d8d1 34 *
phonemacro 0:b0addee6d8d1 35 * IMPORTANT: The code below will also need MAX14720.cpp and MAX14720.h
phonemacro 0:b0addee6d8d1 36 *
phonemacro 0:b0addee6d8d1 37 * @code
phonemacro 0:b0addee6d8d1 38 * #include "mbed.h"
phonemacro 0:b0addee6d8d1 39 * #include "MAX14720.h"
phonemacro 0:b0addee6d8d1 40 * #include "MAX30101.h"
phonemacro 0:b0addee6d8d1 41 *
phonemacro 0:b0addee6d8d1 42 *
phonemacro 0:b0addee6d8d1 43 * /// define the HVOUT Boost Voltage default for the MAX14720 PMIC
phonemacro 0:b0addee6d8d1 44 * #define HVOUT_VOLTAGE 4500 // set to 4500 mV
phonemacro 0:b0addee6d8d1 45 *
phonemacro 0:b0addee6d8d1 46 * /// define all I2C addresses
phonemacro 0:b0addee6d8d1 47 * #define MAX14720_I2C_SLAVE_ADDR (0x54)
phonemacro 0:b0addee6d8d1 48 * #define MAX30101_I2C_SLAVE_ADDR (0xAE)
phonemacro 0:b0addee6d8d1 49 *
phonemacro 0:b0addee6d8d1 50 * /// Settings for the HR initialization
phonemacro 0:b0addee6d8d1 51 * #define FIFO_WATERLEVEL_MARK 15
phonemacro 0:b0addee6d8d1 52 * #define SAMPLE_AVG 2
phonemacro 0:b0addee6d8d1 53 * #define SAMPLE_RATE 1
phonemacro 0:b0addee6d8d1 54 * #define PULSE_WIDTH 2
phonemacro 0:b0addee6d8d1 55 * #define RED_LED_CURRENT 0x1F
phonemacro 0:b0addee6d8d1 56 *
phonemacro 0:b0addee6d8d1 57 * /// Buffer size for streaming data out.
phonemacro 0:b0addee6d8d1 58 * #define BUFFER_LENGTH 50
phonemacro 0:b0addee6d8d1 59 *
phonemacro 0:b0addee6d8d1 60 *
phonemacro 0:b0addee6d8d1 61 * /// I2C Master 2
phonemacro 0:b0addee6d8d1 62 * I2C i2c2(I2C2_SDA, I2C2_SCL); // used by MAX14720, MAX30101, LIS2DH
phonemacro 0:b0addee6d8d1 63 * /// SPI Master 0 with SPI0_SS for use with MAX30001
phonemacro 0:b0addee6d8d1 64 * SPI spi(SPI0_MOSI, SPI0_MISO, SPI0_SCK, SPI0_SS); // used by MAX30001
phonemacro 0:b0addee6d8d1 65 *
phonemacro 0:b0addee6d8d1 66 * /// PMIC
phonemacro 0:b0addee6d8d1 67 * MAX14720 max14720(&i2c2, MAX14720_I2C_SLAVE_ADDR);
phonemacro 0:b0addee6d8d1 68 * /// Optical Oximeter
phonemacro 0:b0addee6d8d1 69 * MAX30101 max30101(&i2c2, MAX30101_I2C_SLAVE_ADDR);
phonemacro 0:b0addee6d8d1 70 * InterruptIn max30101_Interrupt(P4_0);
phonemacro 0:b0addee6d8d1 71 *
phonemacro 0:b0addee6d8d1 72 * //@brief Creating a buffer to hold the data
phonemacro 0:b0addee6d8d1 73 * uint32_t oxiBuffer[BUFFER_LENGTH];
phonemacro 0:b0addee6d8d1 74 * int oxiIndex = 0;
phonemacro 0:b0addee6d8d1 75 * char data_trigger = 0;
phonemacro 0:b0addee6d8d1 76 *
phonemacro 0:b0addee6d8d1 77 *
phonemacro 0:b0addee6d8d1 78 * //@brief Creates a packet that will be streamed via USB Serial
phonemacro 0:b0addee6d8d1 79 * //@brief the packet created will be inserted into a fifo to be streamed at a later time
phonemacro 0:b0addee6d8d1 80 * //@param id Streaming ID
phonemacro 0:b0addee6d8d1 81 * //@param buffer Pointer to a uint32 array that contains the data to include in the packet
phonemacro 0:b0addee6d8d1 82 * //@param number Number of elements in the buffer
phonemacro 0:b0addee6d8d1 83 * //
phonemacro 0:b0addee6d8d1 84 * void StreamPacketUint32_ex(uint32_t id, uint32_t *buffer, uint32_t number) {
phonemacro 0:b0addee6d8d1 85 * int i;
phonemacro 0:b0addee6d8d1 86 * if (id == MAX30101_OXIMETER_DATA + 1) {
phonemacro 0:b0addee6d8d1 87 *
phonemacro 0:b0addee6d8d1 88 * for (i = 0; i < number; i++) {
phonemacro 0:b0addee6d8d1 89 * oxiBuffer[oxiIndex] = buffer[i];
phonemacro 0:b0addee6d8d1 90 * oxiIndex++;
phonemacro 0:b0addee6d8d1 91 *
phonemacro 0:b0addee6d8d1 92 * if (oxiIndex > BUFFER_LENGTH)
phonemacro 0:b0addee6d8d1 93 * {
phonemacro 0:b0addee6d8d1 94 * data_trigger = 1;
phonemacro 0:b0addee6d8d1 95 * oxiIndex = 0;
phonemacro 0:b0addee6d8d1 96 * }
phonemacro 0:b0addee6d8d1 97 * }
phonemacro 0:b0addee6d8d1 98 * }
phonemacro 0:b0addee6d8d1 99 * }
phonemacro 0:b0addee6d8d1 100 *
phonemacro 0:b0addee6d8d1 101 * int main() {
phonemacro 0:b0addee6d8d1 102 * // hold results for returning functions
phonemacro 0:b0addee6d8d1 103 * int result;
phonemacro 0:b0addee6d8d1 104 *
phonemacro 0:b0addee6d8d1 105 * // initialize HVOUT on the MAX14720 PMIC
phonemacro 0:b0addee6d8d1 106 * result = max14720.init();
phonemacro 0:b0addee6d8d1 107 * if (result == MAX14720_ERROR){
phonemacro 0:b0addee6d8d1 108 * printf("Error initializing MAX14720");
phonemacro 0:b0addee6d8d1 109 * }
phonemacro 0:b0addee6d8d1 110 * max14720.boostEn = MAX14720::BOOST_ENABLED;
phonemacro 0:b0addee6d8d1 111 * max14720.boostSetVoltage(HVOUT_VOLTAGE);
phonemacro 0:b0addee6d8d1 112 *
phonemacro 0:b0addee6d8d1 113 * // MAX30101 initialize interrupt
phonemacro 0:b0addee6d8d1 114 * max30101.onDataAvailable(&StreamPacketUint32_ex);
phonemacro 0:b0addee6d8d1 115 * max30101_Interrupt.fall(&MAX30101::MAX30101MidIntHandler);
phonemacro 0:b0addee6d8d1 116 *
phonemacro 0:b0addee6d8d1 117 * // This is the HR mode only (IR LED only)
phonemacro 0:b0addee6d8d1 118 * max30101.HRmode_init(FIFO_WATERLEVEL_MARK, SAMPLE_AVG, SAMPLE_RATE,PULSE_WIDTH, RED_LED_CURRENT);
phonemacro 0:b0addee6d8d1 119 *
phonemacro 0:b0addee6d8d1 120 * printf("Please wait for data to start streaming\n");
phonemacro 0:b0addee6d8d1 121 * fflush(stdout);
phonemacro 0:b0addee6d8d1 122 *
phonemacro 0:b0addee6d8d1 123 * while (1) {
phonemacro 0:b0addee6d8d1 124 * if(data_trigger == 1)
phonemacro 0:b0addee6d8d1 125 * {
phonemacro 0:b0addee6d8d1 126 * printf("%ld ", oxiBuffer[oxiIndex]); // Print the ECG data on a serial port terminal software
phonemacro 0:b0addee6d8d1 127 * fflush(stdout);
phonemacro 0:b0addee6d8d1 128 * }
phonemacro 0:b0addee6d8d1 129 * }
phonemacro 0:b0addee6d8d1 130 * }
phonemacro 0:b0addee6d8d1 131 * @endcode
phonemacro 0:b0addee6d8d1 132 *
phonemacro 0:b0addee6d8d1 133 */
phonemacro 0:b0addee6d8d1 134
phonemacro 0:b0addee6d8d1 135 #ifndef _MAX30101_H_
phonemacro 0:b0addee6d8d1 136 #define _MAX30101_H_
phonemacro 0:b0addee6d8d1 137
phonemacro 0:b0addee6d8d1 138 #include "mbed.h"
phonemacro 0:b0addee6d8d1 139
phonemacro 0:b0addee6d8d1 140 #define MAX30101_RAW_DATA_SIZE 3 * 4 * 32
phonemacro 0:b0addee6d8d1 141 #define MAX30101_PROC_DATA_SIZE 4 * 32
phonemacro 0:b0addee6d8d1 142
phonemacro 0:b0addee6d8d1 143 #define MAX30101_OXIMETER_DATA 0x10
phonemacro 0:b0addee6d8d1 144
phonemacro 0:b0addee6d8d1 145 #define CHUNK_SIZE 252
phonemacro 0:b0addee6d8d1 146
phonemacro 0:b0addee6d8d1 147 ///< MAX30101 Register addresses
phonemacro 0:b0addee6d8d1 148
phonemacro 0:b0addee6d8d1 149 #define MAX30101_INT_PORT 4
phonemacro 0:b0addee6d8d1 150 #define MAX30101_INT_PIN 0
phonemacro 0:b0addee6d8d1 151 #define MAX30101_MASTER_NUM 2
phonemacro 0:b0addee6d8d1 152
phonemacro 0:b0addee6d8d1 153 /**
phonemacro 0:b0addee6d8d1 154 * Maxim Integrated MAX30101 Oximeter chip
phonemacro 0:b0addee6d8d1 155 */
phonemacro 0:b0addee6d8d1 156 class MAX30101 {
phonemacro 0:b0addee6d8d1 157 public:
phonemacro 0:b0addee6d8d1 158 float max30101_final_temp; ///< Global declaration
phonemacro 0:b0addee6d8d1 159 uint32_t max30101_buffer[MAX30101_PROC_DATA_SIZE]; ///< final Processed data
phonemacro 0:b0addee6d8d1 160 char max30101_rawData[MAX30101_RAW_DATA_SIZE]; ///< raw data from the chip
phonemacro 0:b0addee6d8d1 161
phonemacro 0:b0addee6d8d1 162 typedef enum { ///< MAX30101 Register addresses
phonemacro 0:b0addee6d8d1 163
phonemacro 0:b0addee6d8d1 164 ///< Status
phonemacro 0:b0addee6d8d1 165 REG_INT_STAT_1 = 0x00,
phonemacro 0:b0addee6d8d1 166 REG_INT_STAT_2 = 0x01,
phonemacro 0:b0addee6d8d1 167 REG_INT_EN_1 = 0x02,
phonemacro 0:b0addee6d8d1 168 REG_INT_EN_2 = 0x03,
phonemacro 0:b0addee6d8d1 169
phonemacro 0:b0addee6d8d1 170 REG_FIFO_W_PTR = 0x04,
phonemacro 0:b0addee6d8d1 171 REG_FIFO_OVF_CNT = 0x05,
phonemacro 0:b0addee6d8d1 172 REG_FIFO_R_PTR = 0x06,
phonemacro 0:b0addee6d8d1 173 REG_FIFO_DATA = 0x07,
phonemacro 0:b0addee6d8d1 174 ///< Configuration
phonemacro 0:b0addee6d8d1 175 REG_FIFO_CFG = 0x08,
phonemacro 0:b0addee6d8d1 176 REG_MODE_CFG = 0x09,
phonemacro 0:b0addee6d8d1 177 REG_SPO2_CFG = 0x0A,
phonemacro 0:b0addee6d8d1 178 REG_LED1_PA = 0x0C,
phonemacro 0:b0addee6d8d1 179 REG_LED2_PA = 0x0D,
phonemacro 0:b0addee6d8d1 180 REG_LED3_PA = 0x0E,
phonemacro 0:b0addee6d8d1 181 REG_PILOT_PA = 0x10,
phonemacro 0:b0addee6d8d1 182 REG_SLT2_SLT1 = 0x11,
phonemacro 0:b0addee6d8d1 183 REG_SLT4_SLT3 = 0x12,
phonemacro 0:b0addee6d8d1 184 ///< Die Temp
phonemacro 0:b0addee6d8d1 185 REG_TINT = 0x1F,
phonemacro 0:b0addee6d8d1 186 REG_TFRAC = 0x20,
phonemacro 0:b0addee6d8d1 187 REG_TEMP_EN = 0x21,
phonemacro 0:b0addee6d8d1 188 ///< Proximity Func
phonemacro 0:b0addee6d8d1 189 REG_PROX_INT_THR = 0x30,
phonemacro 0:b0addee6d8d1 190 /* Part ID */
phonemacro 0:b0addee6d8d1 191 REG_REV_ID = 0xFE,
phonemacro 0:b0addee6d8d1 192 REG_ID = 0xFF,
phonemacro 0:b0addee6d8d1 193 } MAX30101_REG_map_t;
phonemacro 0:b0addee6d8d1 194
phonemacro 0:b0addee6d8d1 195 /**********/
phonemacro 0:b0addee6d8d1 196 /* STATUS */
phonemacro 0:b0addee6d8d1 197 /**********/
phonemacro 0:b0addee6d8d1 198 /// @brief STATUS1 (0x00)
phonemacro 0:b0addee6d8d1 199 typedef union max30101_Interrupt_Status_1_reg {
phonemacro 0:b0addee6d8d1 200 char all;
phonemacro 0:b0addee6d8d1 201 struct {
phonemacro 0:b0addee6d8d1 202 char pwr_rdy : 1;
phonemacro 0:b0addee6d8d1 203 char reserved : 3;
phonemacro 0:b0addee6d8d1 204 char prox_int : 1;
phonemacro 0:b0addee6d8d1 205 char alc_ovf : 1;
phonemacro 0:b0addee6d8d1 206 char ppg_rdy : 1;
phonemacro 0:b0addee6d8d1 207 char a_full : 1;
phonemacro 0:b0addee6d8d1 208 } bit;
phonemacro 0:b0addee6d8d1 209 } max30101_Interrupt_Status_1_t;
phonemacro 0:b0addee6d8d1 210
phonemacro 0:b0addee6d8d1 211 /// @brief STATUS2 (0x01)
phonemacro 0:b0addee6d8d1 212 typedef union max30101_Interrupt_Status_2_reg {
phonemacro 0:b0addee6d8d1 213 char all;
phonemacro 0:b0addee6d8d1 214 struct {
phonemacro 0:b0addee6d8d1 215 char reserved1 : 1;
phonemacro 0:b0addee6d8d1 216 char die_temp_rdy : 1;
phonemacro 0:b0addee6d8d1 217 char reserved2 : 6;
phonemacro 0:b0addee6d8d1 218 } bit;
phonemacro 0:b0addee6d8d1 219 } max30101_Interrupt_Status_2_t;
phonemacro 0:b0addee6d8d1 220
phonemacro 0:b0addee6d8d1 221 /// @brief INTERRUPT_ENABLE1 (0x02)
phonemacro 0:b0addee6d8d1 222 typedef union max30101_Interrupt_Enable_1_reg {
phonemacro 0:b0addee6d8d1 223 char all;
phonemacro 0:b0addee6d8d1 224 struct {
phonemacro 0:b0addee6d8d1 225 char reserved1 : 4;
phonemacro 0:b0addee6d8d1 226 char prox_int_en : 1;
phonemacro 0:b0addee6d8d1 227 char alc_ovf_en : 1;
phonemacro 0:b0addee6d8d1 228 char ppg_rdy_en : 1;
phonemacro 0:b0addee6d8d1 229 char a_full_en : 1;
phonemacro 0:b0addee6d8d1 230 } bit;
phonemacro 0:b0addee6d8d1 231 } max30101_Interrupt_Enable_1_t;
phonemacro 0:b0addee6d8d1 232
phonemacro 0:b0addee6d8d1 233 /// @brief INTERRUPT_ENABLE2 (0x03)
phonemacro 0:b0addee6d8d1 234 typedef union max30101_Interrupt_Enable_2_reg {
phonemacro 0:b0addee6d8d1 235 char all;
phonemacro 0:b0addee6d8d1 236 struct {
phonemacro 0:b0addee6d8d1 237 char reserved1 : 1;
phonemacro 0:b0addee6d8d1 238 char die_temp_rdy_en : 1;
phonemacro 0:b0addee6d8d1 239 char reserved2 : 6;
phonemacro 0:b0addee6d8d1 240 } bit;
phonemacro 0:b0addee6d8d1 241 } max30101_Interrupt_Enable_2_t;
phonemacro 0:b0addee6d8d1 242
phonemacro 0:b0addee6d8d1 243 /*********/
phonemacro 0:b0addee6d8d1 244 /* FIFO */
phonemacro 0:b0addee6d8d1 245 /*********/
phonemacro 0:b0addee6d8d1 246 // 0x04
phonemacro 0:b0addee6d8d1 247 /// @brief FIFO_WR_PTR (0x04)
phonemacro 0:b0addee6d8d1 248 typedef union max30101_fifo_wr_ptr_reg {
phonemacro 0:b0addee6d8d1 249 char all;
phonemacro 0:b0addee6d8d1 250 struct {
phonemacro 0:b0addee6d8d1 251 char fifo_wr_ptr : 5;
phonemacro 0:b0addee6d8d1 252 char reserved1 : 3;
phonemacro 0:b0addee6d8d1 253 } bit;
phonemacro 0:b0addee6d8d1 254 } max30101_fifo_wr_ptr_t;
phonemacro 0:b0addee6d8d1 255
phonemacro 0:b0addee6d8d1 256 /// @brief OVF_COUNTER (0x05)
phonemacro 0:b0addee6d8d1 257 typedef union max30101_ovf_counter_reg {
phonemacro 0:b0addee6d8d1 258 char all;
phonemacro 0:b0addee6d8d1 259 struct {
phonemacro 0:b0addee6d8d1 260 char fifo_ovf_counter : 5;
phonemacro 0:b0addee6d8d1 261 char reserved1 : 3;
phonemacro 0:b0addee6d8d1 262 } bit;
phonemacro 0:b0addee6d8d1 263 } max30101_ovf_counter_reg_t;
phonemacro 0:b0addee6d8d1 264
phonemacro 0:b0addee6d8d1 265 /// @brief FIFO_READ_PTR (0x06)
phonemacro 0:b0addee6d8d1 266 typedef union max30101_fifo_rd_ptr_reg {
phonemacro 0:b0addee6d8d1 267 char all;
phonemacro 0:b0addee6d8d1 268 struct {
phonemacro 0:b0addee6d8d1 269 char fifo_rd_ptr : 5;
phonemacro 0:b0addee6d8d1 270 char reserved1 : 3;
phonemacro 0:b0addee6d8d1 271 } bit;
phonemacro 0:b0addee6d8d1 272 } max30101_fifo_rd_ptr_t;
phonemacro 0:b0addee6d8d1 273
phonemacro 0:b0addee6d8d1 274 /********************/
phonemacro 0:b0addee6d8d1 275 /* Configuration */
phonemacro 0:b0addee6d8d1 276 /********************/
phonemacro 0:b0addee6d8d1 277 // 0x08
phonemacro 0:b0addee6d8d1 278 /// @brief FIFO_CONFIGURATION (0x08)
phonemacro 0:b0addee6d8d1 279 typedef union max30101_fifo_configuration_reg {
phonemacro 0:b0addee6d8d1 280 char all;
phonemacro 0:b0addee6d8d1 281 struct {
phonemacro 0:b0addee6d8d1 282 char fifo_a_full : 4;
phonemacro 0:b0addee6d8d1 283 char fifo_roll_over_en : 1;
phonemacro 0:b0addee6d8d1 284 char smp_ave : 3;
phonemacro 0:b0addee6d8d1 285 } bit;
phonemacro 0:b0addee6d8d1 286 } max30101_fifo_configuration_t;
phonemacro 0:b0addee6d8d1 287
phonemacro 0:b0addee6d8d1 288 /// @brief MODE_CONFIGURATION (0x09)
phonemacro 0:b0addee6d8d1 289 typedef union max30101_mode_configuration_reg {
phonemacro 0:b0addee6d8d1 290 char all;
phonemacro 0:b0addee6d8d1 291 struct {
phonemacro 0:b0addee6d8d1 292 char mode : 3;
phonemacro 0:b0addee6d8d1 293 char reserved1 : 3;
phonemacro 0:b0addee6d8d1 294 char reset : 1;
phonemacro 0:b0addee6d8d1 295 char shdn : 1;
phonemacro 0:b0addee6d8d1 296 } bit;
phonemacro 0:b0addee6d8d1 297 } max30101_mode_configuration_t;
phonemacro 0:b0addee6d8d1 298
phonemacro 0:b0addee6d8d1 299 /// @brief SPO2_CONGIGURATION (0x0A)
phonemacro 0:b0addee6d8d1 300 typedef union max30101_spo2_configuration_reg {
phonemacro 0:b0addee6d8d1 301 char all;
phonemacro 0:b0addee6d8d1 302 struct {
phonemacro 0:b0addee6d8d1 303 char led_pw : 2;
phonemacro 0:b0addee6d8d1 304 char spo2_sr : 3;
phonemacro 0:b0addee6d8d1 305 char spo2_adc_rge : 2;
phonemacro 0:b0addee6d8d1 306 char reserved1 : 1;
phonemacro 0:b0addee6d8d1 307 } bit;
phonemacro 0:b0addee6d8d1 308 } max30101_spo2_configuration_t;
phonemacro 0:b0addee6d8d1 309
phonemacro 0:b0addee6d8d1 310 typedef union max30101_multiLED_mode_ctrl_1_reg {
phonemacro 0:b0addee6d8d1 311 char all;
phonemacro 0:b0addee6d8d1 312 struct {
phonemacro 0:b0addee6d8d1 313 char slot1 : 3;
phonemacro 0:b0addee6d8d1 314 char reserved : 1;
phonemacro 0:b0addee6d8d1 315 char slot2 : 3;
phonemacro 0:b0addee6d8d1 316 char reserved1 : 1;
phonemacro 0:b0addee6d8d1 317 } bit;
phonemacro 0:b0addee6d8d1 318 } max30101_multiLED_mode_ctrl_1_t;
phonemacro 0:b0addee6d8d1 319
phonemacro 0:b0addee6d8d1 320 typedef union max30101_multiLED_mode_ctrl_2_reg {
phonemacro 0:b0addee6d8d1 321 char all;
phonemacro 0:b0addee6d8d1 322 struct {
phonemacro 0:b0addee6d8d1 323 char slot3 : 3;
phonemacro 0:b0addee6d8d1 324 char reserved : 1;
phonemacro 0:b0addee6d8d1 325 char slot4 : 3;
phonemacro 0:b0addee6d8d1 326 char reserved1 : 1;
phonemacro 0:b0addee6d8d1 327 } bit;
phonemacro 0:b0addee6d8d1 328 } max30101_multiLED_mode_ctrl_2_t;
phonemacro 0:b0addee6d8d1 329
phonemacro 0:b0addee6d8d1 330 /********************/
phonemacro 0:b0addee6d8d1 331 /* Die Temperature */
phonemacro 0:b0addee6d8d1 332 /********************/
phonemacro 0:b0addee6d8d1 333
phonemacro 0:b0addee6d8d1 334 char max30101_tinit;
phonemacro 0:b0addee6d8d1 335
phonemacro 0:b0addee6d8d1 336 char max30101_tfrac;
phonemacro 0:b0addee6d8d1 337
phonemacro 0:b0addee6d8d1 338 typedef union max30101_die_temp_config {
phonemacro 0:b0addee6d8d1 339 char all;
phonemacro 0:b0addee6d8d1 340 struct {
phonemacro 0:b0addee6d8d1 341 char temp_en : 1;
phonemacro 0:b0addee6d8d1 342 char reserved : 7;
phonemacro 0:b0addee6d8d1 343 } bit;
phonemacro 0:b0addee6d8d1 344 } max30101_die_temp_config_t;
phonemacro 0:b0addee6d8d1 345
phonemacro 0:b0addee6d8d1 346 /***** Function Prototypes *****/
phonemacro 0:b0addee6d8d1 347
phonemacro 0:b0addee6d8d1 348 char max30101_prox_int_thresh;
phonemacro 0:b0addee6d8d1 349
phonemacro 0:b0addee6d8d1 350 /**
phonemacro 0:b0addee6d8d1 351 * @brief MAX30101 constructor.
phonemacro 0:b0addee6d8d1 352 * @param sda mbed pin to use for SDA line of I2C interface.
phonemacro 0:b0addee6d8d1 353 * @param scl mbed pin to use for SCL line of I2C interface.
phonemacro 0:b0addee6d8d1 354 */
phonemacro 0:b0addee6d8d1 355 MAX30101(PinName sda, PinName scl, int slaveAddress);
phonemacro 0:b0addee6d8d1 356
phonemacro 0:b0addee6d8d1 357 /**
phonemacro 0:b0addee6d8d1 358 * @brief MAX30101 constructor.
phonemacro 0:b0addee6d8d1 359 * @param i2c I2C object to use.
phonemacro 0:b0addee6d8d1 360 */
phonemacro 0:b0addee6d8d1 361 MAX30101(I2C *i2c, int slaveAddress);
phonemacro 0:b0addee6d8d1 362
phonemacro 0:b0addee6d8d1 363 /**
phonemacro 0:b0addee6d8d1 364 * @brief MAX30101 destructor.
phonemacro 0:b0addee6d8d1 365 */
phonemacro 0:b0addee6d8d1 366 ~MAX30101(void);
phonemacro 0:b0addee6d8d1 367
phonemacro 0:b0addee6d8d1 368 /**
phonemacro 0:b0addee6d8d1 369 * @brief Allows reading from MAX30101 register
phonemacro 0:b0addee6d8d1 370 * @param reg: is the register address, to read from (look at max30101.h and the
phonemacro 0:b0addee6d8d1 371 * data sheet for details)
phonemacro 0:b0addee6d8d1 372 * @param value: is the pointer to the value read from the register
phonemacro 0:b0addee6d8d1 373 * @returns 0-if no error. A non-zero value indicates an error.
phonemacro 0:b0addee6d8d1 374 */
phonemacro 0:b0addee6d8d1 375 int i2c_reg_read(MAX30101_REG_map_t reg, char *value);
phonemacro 0:b0addee6d8d1 376
phonemacro 0:b0addee6d8d1 377 /**
phonemacro 0:b0addee6d8d1 378 * @brief Allows writing to MAX30101 register
phonemacro 0:b0addee6d8d1 379 * @param reg: is the register address, to read from (look at max30101.h and
phonemacro 0:b0addee6d8d1 380 * the data sheet for details)
phonemacro 0:b0addee6d8d1 381 * @param value: is the value to write to the register
phonemacro 0:b0addee6d8d1 382 * @returns 0-if if no error. A non-zero value indicates an error.
phonemacro 0:b0addee6d8d1 383 */
phonemacro 0:b0addee6d8d1 384 int i2c_reg_write(MAX30101_REG_map_t reg, char value);
phonemacro 0:b0addee6d8d1 385
phonemacro 0:b0addee6d8d1 386 /**
phonemacro 0:b0addee6d8d1 387 * @brief This function sets up for the SpO2 mode. The data is returned in
phonemacro 0:b0addee6d8d1 388 * the callback function
phonemacro 0:b0addee6d8d1 389 * @brief max30101_int_handler in global array: buffer[]. SP mode handles two LED (Red,IR) data. Hence it
phonemacro 0:b0addee6d8d1 390 * @brief can fill up the FIFO up to a maximum of 3bytes/sample x 32 x 2 = 192bytes.
phonemacro 0:b0addee6d8d1 391 * @param fifo_waterlevel_mark: corresponds to FIFO_A_FULL, In FIFO Configuration Register (0x08)
phonemacro 0:b0addee6d8d1 392 * @param sample_avg: corresponds to SMP_AVE, in FIFO Configuration Register (0x08)
phonemacro 0:b0addee6d8d1 393 * @param sample_rate: corresponds to SPO2_SR, IN SpO2 Configuration Register (0x0A)
phonemacro 0:b0addee6d8d1 394 * @param pulse_width: corresponds to LED_PW in SpO2 Configuration register(0x0A)
phonemacro 0:b0addee6d8d1 395 * @param red_led_current: corresponds to LED1_PA register (0x0C). Please see data sheet for values
phonemacro 0:b0addee6d8d1 396 * @param ir_led_current: corresponds to LED2_PA register (0x0D). Please see data sheet for values
phonemacro 0:b0addee6d8d1 397 * @returns 0-if everything is good. A non-zero value indicates an error.
phonemacro 0:b0addee6d8d1 398 */
phonemacro 0:b0addee6d8d1 399 int SpO2mode_init(uint8_t fifo_waterlevel_mark, uint8_t sample_avg,
phonemacro 0:b0addee6d8d1 400 uint8_t sample_rate, uint8_t pulse_width,
phonemacro 0:b0addee6d8d1 401 uint8_t red_led_current, uint8_t ir_led_current);
phonemacro 0:b0addee6d8d1 402
phonemacro 0:b0addee6d8d1 403 /**
phonemacro 0:b0addee6d8d1 404 * @brief This function will stop the SpO2 mode and turn off all operating LED�s.
phonemacro 0:b0addee6d8d1 405 * @return 0-if if no error. A non-zero value indicates an error.
phonemacro 0:b0addee6d8d1 406 */
phonemacro 0:b0addee6d8d1 407 int SpO2mode_stop(void);
phonemacro 0:b0addee6d8d1 408
phonemacro 0:b0addee6d8d1 409 /**
phonemacro 0:b0addee6d8d1 410 * @brief This function sets up for the HR mode. The data is returned in thecallback function
phonemacro 0:b0addee6d8d1 411 * @brief max30101_int_handler in global array: buffer[].HR mode handles one LED (Red) data. Hence it can fill
phonemacro 0:b0addee6d8d1 412 * @brief up the FIFO up to a maximum of 3bytes/sample x 32 = 96bytes.
phonemacro 0:b0addee6d8d1 413 * @brief fifo_waterlevel_mark: corresponds to FIFO_A_FULL, In FIFO Configuration Register (0x08)
phonemacro 0:b0addee6d8d1 414 * @param sample_avg: corresponds to SMP_AVE, in FIFO Configuration Register (0x08)
phonemacro 0:b0addee6d8d1 415 * @param sample_rate:corresponds to SPO2_SR, IN SpO2 Configuration Register (0x0A)
phonemacro 0:b0addee6d8d1 416 * @param pulse_width: corresponds to LED_PW in SpO2 Configuration Register(0x0A)
phonemacro 0:b0addee6d8d1 417 * @param red_led_current: corresponds to LED1_PA register (0x0C). Please see data sheet for values
phonemacro 0:b0addee6d8d1 418 * @returns 0-if if no error. A non-zero value indicates an error.
phonemacro 0:b0addee6d8d1 419 */
phonemacro 0:b0addee6d8d1 420 int HRmode_init(uint8_t fifo_waterlevel_mark, uint8_t sample_avg,
phonemacro 0:b0addee6d8d1 421 uint8_t sample_rate, uint8_t pulse_width,
phonemacro 0:b0addee6d8d1 422 uint8_t red_led_current);
phonemacro 0:b0addee6d8d1 423
phonemacro 0:b0addee6d8d1 424 /**
phonemacro 0:b0addee6d8d1 425 * @brief This function will stop the HR mode and turn off all operating
phonemacro 0:b0addee6d8d1 426 * LED’s.
phonemacro 0:b0addee6d8d1 427 * @return 0-if if no error. A non-zero value indicates an error.
phonemacro 0:b0addee6d8d1 428 */
phonemacro 0:b0addee6d8d1 429 int HRmode_stop(void);
phonemacro 0:b0addee6d8d1 430
phonemacro 0:b0addee6d8d1 431 /**
phonemacro 0:b0addee6d8d1 432 *@brief This function sets up for the Multi-mode. The data is returned in the callback function max30101_int_handler in global array:
phonemacro 0:b0addee6d8d1 433 *@brief buffer[]. Multi-LED mode can handle 1 to 4 LED combinations. Hence it can fill up the FIFO up to a maximum of
phonemacro 0:b0addee6d8d1 434 *@brief 3bytes/sample x 32 x 4 = 384bytes.
phonemacro 0:b0addee6d8d1 435 *@param fifo_waterlevel_mark: corresponds to FIFO_A_FULL, In FIFO Configuration Register (0x08)
phonemacro 0:b0addee6d8d1 436 *@param sample_avg: corresponds to SMP_AVE, in FIFO Configuration Register (0x08)
phonemacro 0:b0addee6d8d1 437 *@param sample_rate:corresponds to SPO2_SR, IN SpO2 Configuration Register (0x0A)
phonemacro 0:b0addee6d8d1 438 *@param pulse_width: corresponds to LED_PW in SpO2 Configuration register(0x0A)
phonemacro 0:b0addee6d8d1 439 *@param red_led_current: corresponds to LED1_PA register (0x0C). Please see data sheet for values
phonemacro 0:b0addee6d8d1 440 *@param ir_led_current: corresponds to LED2_PA register (0x0D). Please see data sheet for values
phonemacro 0:b0addee6d8d1 441 *@param green_led_current: corresponds to LED3_PA register (0x0E). Please see data sheet for values
phonemacro 0:b0addee6d8d1 442 *@param slot_1,…,slot_4: corresponds to Multi-LED Mode control Registers (0x11-0x12).
phonemacro 0:b0addee6d8d1 443 *@returns 0-if if no error. A non-zero value indicates an error.
phonemacro 0:b0addee6d8d1 444 */
phonemacro 0:b0addee6d8d1 445 int Multimode_init(uint8_t fifo_waterlevel_mark, uint8_t sample_avg,
phonemacro 0:b0addee6d8d1 446 uint8_t sample_rate, uint8_t pulse_width,
phonemacro 0:b0addee6d8d1 447 uint8_t red_led_current, uint8_t ir_led_current,
phonemacro 0:b0addee6d8d1 448 uint8_t green_led_current, uint8_t slot_1, uint8_t slot_2,
phonemacro 0:b0addee6d8d1 449 uint8_t slot_3, uint8_t slot_4);
phonemacro 0:b0addee6d8d1 450
phonemacro 0:b0addee6d8d1 451 /**
phonemacro 0:b0addee6d8d1 452 * @brief This function will stop the Multi-mode and turn off all operating LED’s.
phonemacro 0:b0addee6d8d1 453 * @returns 0-if if no error. A non-zero value indicates an error.
phonemacro 0:b0addee6d8d1 454 */
phonemacro 0:b0addee6d8d1 455 int Multimode_stop(void);
phonemacro 0:b0addee6d8d1 456
phonemacro 0:b0addee6d8d1 457 /**
phonemacro 0:b0addee6d8d1 458 * @brief This is a function that sets up for temperature read and should be called after one of the mode
phonemacro 0:b0addee6d8d1 459 * @brief has been setup. The data is returned in the callback function max30101_int_handler. This
phonemacro 0:b0addee6d8d1 460 * @brief function needs to be called every time temperature reading is required.
phonemacro 0:b0addee6d8d1 461 * @brief Call the temp function after one of the MODES have been started
phonemacro 0:b0addee6d8d1 462 * @brief Note that the temp is disabled after one read... also, it is not necessary
phonemacro 0:b0addee6d8d1 463 * @brief to read the temp frequently...
phonemacro 0:b0addee6d8d1 464 * @returns 0-if if no error. A non-zero value indicates an error.
phonemacro 0:b0addee6d8d1 465 */
phonemacro 0:b0addee6d8d1 466 int tempread(void);
phonemacro 0:b0addee6d8d1 467
phonemacro 0:b0addee6d8d1 468 /**
phonemacro 0:b0addee6d8d1 469 *@brief This is a callback function which collects the data from the FIFO of the MAX30101 in a 32-bit
phonemacro 0:b0addee6d8d1 470 *@brief unsigned global array called max30101_buffer[]. Upon every interrupt from the MAX30101, this
phonemacro 0:b0addee6d8d1 471 *@brief function is called to service the FIFO of the MAX30101. This callback function also services the
phonemacro 0:b0addee6d8d1 472 *@brief interrupt for the temp data. The temp data is collected in a floating point global variable
phonemacro 0:b0addee6d8d1 473 *@brief final_temp.
phonemacro 0:b0addee6d8d1 474 *@param max30101_buffer[], global uint32_t
phonemacro 0:b0addee6d8d1 475 *@returns 0-if everything is good. A non-zero value indicates an error.
phonemacro 0:b0addee6d8d1 476 */
phonemacro 0:b0addee6d8d1 477 int int_handler(void);
phonemacro 0:b0addee6d8d1 478
phonemacro 0:b0addee6d8d1 479 /**
phonemacro 0:b0addee6d8d1 480 * @brief encapsulates the int_handler above
phonemacro 0:b0addee6d8d1 481 */
phonemacro 0:b0addee6d8d1 482 static void MidIntHandler(void);
phonemacro 0:b0addee6d8d1 483
phonemacro 0:b0addee6d8d1 484 /**
phonemacro 0:b0addee6d8d1 485 * @brief type definition for data interrupt
phonemacro 0:b0addee6d8d1 486 */
phonemacro 0:b0addee6d8d1 487 typedef void (*DataCallbackFunction)(uint32_t id, uint32_t *buffer,
phonemacro 0:b0addee6d8d1 488 uint32_t length);
phonemacro 0:b0addee6d8d1 489 /**
phonemacro 0:b0addee6d8d1 490 * @brief type definition for general interrupt
phonemacro 0:b0addee6d8d1 491 */
phonemacro 0:b0addee6d8d1 492 typedef void (*InterruptFunction)();
phonemacro 0:b0addee6d8d1 493
phonemacro 0:b0addee6d8d1 494 /**
phonemacro 0:b0addee6d8d1 495 * @brief Used to connect a callback for when interrupt data is available
phonemacro 0:b0addee6d8d1 496 */
phonemacro 0:b0addee6d8d1 497 void onInterrupt(InterruptFunction _onInterrupt);
phonemacro 0:b0addee6d8d1 498
phonemacro 0:b0addee6d8d1 499 /**
phonemacro 0:b0addee6d8d1 500 * @brief Used to connect a callback for when interrupt data is available
phonemacro 0:b0addee6d8d1 501 */
phonemacro 0:b0addee6d8d1 502 void onDataAvailable(DataCallbackFunction _onDataAvailable);
phonemacro 0:b0addee6d8d1 503
phonemacro 0:b0addee6d8d1 504 static MAX30101 *instance;
phonemacro 0:b0addee6d8d1 505
phonemacro 0:b0addee6d8d1 506 private:
phonemacro 0:b0addee6d8d1 507 /**
phonemacro 0:b0addee6d8d1 508 * @brief Used to notify an external function that interrupt data is available
phonemacro 0:b0addee6d8d1 509 * @param id type of data available
phonemacro 0:b0addee6d8d1 510 * @param buffer 32-bit buffer that points to the data
phonemacro 0:b0addee6d8d1 511 * @param length length of 32-bit elements available
phonemacro 0:b0addee6d8d1 512 */
phonemacro 0:b0addee6d8d1 513 void dataAvailable(uint32_t id, uint32_t *buffer, uint32_t length);
phonemacro 0:b0addee6d8d1 514
phonemacro 0:b0addee6d8d1 515
phonemacro 0:b0addee6d8d1 516 /**
phonemacro 0:b0addee6d8d1 517 * @brief Executed on interrupt (callback function at the end of the interrupt)
phonemacro 0:b0addee6d8d1 518 * @param id type of data available
phonemacro 0:b0addee6d8d1 519 * @param buffer 32-bit buffer that points to the data
phonemacro 0:b0addee6d8d1 520 * @param length length of 32-bit elements available
phonemacro 0:b0addee6d8d1 521 */
phonemacro 0:b0addee6d8d1 522 void interruptPostCallback(void);
phonemacro 0:b0addee6d8d1 523
phonemacro 0:b0addee6d8d1 524 /// callback function when interrupt data is available
phonemacro 0:b0addee6d8d1 525 DataCallbackFunction onDataAvailableCallback;
phonemacro 0:b0addee6d8d1 526
phonemacro 0:b0addee6d8d1 527 /// callback function when interrupt data is available
phonemacro 0:b0addee6d8d1 528 InterruptFunction onInterruptCallback;
phonemacro 0:b0addee6d8d1 529
phonemacro 0:b0addee6d8d1 530 /**
phonemacro 0:b0addee6d8d1 531 * @brief Read from an I2C device (Read I2c wrapper method)
phonemacro 0:b0addee6d8d1 532 * @param slaveAddress slave address to use with transaction
phonemacro 0:b0addee6d8d1 533 * @param writeData pointer of data to write
phonemacro 0:b0addee6d8d1 534 * @param writeCount number of data to write
phonemacro 0:b0addee6d8d1 535 * @param readData pointer to buffer to read to
phonemacro 0:b0addee6d8d1 536 * @param readCount number of bytes to read
phonemacro 0:b0addee6d8d1 537 */
phonemacro 0:b0addee6d8d1 538
phonemacro 0:b0addee6d8d1 539 int I2CM_Read(int slaveAddress, char *writeData, char writeCount, char *readData, char readCount);
phonemacro 0:b0addee6d8d1 540
phonemacro 0:b0addee6d8d1 541 /**
phonemacro 0:b0addee6d8d1 542 * @brief Write to an I2C device (I2C wrapper method)
phonemacro 0:b0addee6d8d1 543 * @param slaveAddress slave address to use with transaction
phonemacro 0:b0addee6d8d1 544 * @param writeData1 pointer of data to write
phonemacro 0:b0addee6d8d1 545 * @param writeCount1 number of data to write
phonemacro 0:b0addee6d8d1 546 * @param writeData2 pointer to buffer to read to
phonemacro 0:b0addee6d8d1 547 * @param writeCount2 number of bytes to read
phonemacro 0:b0addee6d8d1 548 */
phonemacro 0:b0addee6d8d1 549 int I2CM_Write(int slaveAddress, char *writeData1, char writeCount1, char *writeData2, char writeCount2);
phonemacro 0:b0addee6d8d1 550
phonemacro 0:b0addee6d8d1 551 /// @brief pointer to I2C object
phonemacro 0:b0addee6d8d1 552 I2C *i2c;
phonemacro 0:b0addee6d8d1 553
phonemacro 0:b0addee6d8d1 554 /// @brief flag to track if this object is the owner (created) the I2C object
phonemacro 0:b0addee6d8d1 555 bool i2c_owner;
phonemacro 0:b0addee6d8d1 556
phonemacro 0:b0addee6d8d1 557 /// @brief Device slave address
phonemacro 0:b0addee6d8d1 558 int slaveAddress;
phonemacro 0:b0addee6d8d1 559 };
phonemacro 0:b0addee6d8d1 560
phonemacro 0:b0addee6d8d1 561 /**
phonemacro 0:b0addee6d8d1 562 * @brief Resets the I2C block, when needed
phonemacro 0:b0addee6d8d1 563 */
phonemacro 0:b0addee6d8d1 564 extern void I2CM_Init_Reset(uint8_t index, int speed);
phonemacro 0:b0addee6d8d1 565
phonemacro 0:b0addee6d8d1 566
phonemacro 0:b0addee6d8d1 567
phonemacro 0:b0addee6d8d1 568 #endif /* _MAX30101_H_ */