Library for MAX30101 SpO2 and heart rate sensor
Dependents: HeartRate HeartRate proj final_project_ee119 ... more
MAX30101.cpp
00001 /******************************************************************************* 00002 * Copyright (C) 2017 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 00034 00035 #include "MAX30101.h" 00036 00037 00038 //***************************************************************************** 00039 MAX30101::MAX30101(I2C &i2c): 00040 m_i2cBus(i2c) 00041 { 00042 //empty block 00043 } 00044 00045 00046 //***************************************************************************** 00047 MAX30101::~MAX30101() 00048 { 00049 //empty block 00050 } 00051 00052 00053 //***************************************************************************** 00054 int32_t MAX30101::enableInterrupts(const InterruptBitField_u data) 00055 { 00056 char cmdData[3]; 00057 cmdData[0] = InterruptEnable1; 00058 cmdData[1] = (data.all & 0xF0); 00059 cmdData[2] = (data.all & 0x02); 00060 00061 return m_i2cBus.write(I2C_W_ADRS, cmdData, 3); 00062 } 00063 00064 00065 //***************************************************************************** 00066 int32_t MAX30101::getInterruptStatus(InterruptBitField_u &data) 00067 { 00068 char local_data[3]; 00069 local_data[0] = InterruptStatus1; 00070 00071 int32_t result = m_i2cBus.write(I2C_W_ADRS, local_data, 1); 00072 if(result == 0) 00073 { 00074 result = m_i2cBus.read(I2C_R_ADRS, (local_data + 1), 2); 00075 if(result == 0) 00076 { 00077 data.all = local_data[1] + local_data[2]; 00078 } 00079 } 00080 00081 return result; 00082 } 00083 00084 00085 //***************************************************************************** 00086 int32_t MAX30101::setFIFOConfiguration(const FIFO_Configuration_u config) 00087 { 00088 return writeRegister(FIFO_Configuration, config.all); 00089 } 00090 00091 00092 //***************************************************************************** 00093 int32_t MAX30101::getFIFOConfiguration(FIFO_Configuration_u &config) 00094 { 00095 return readRegister(FIFO_Configuration, config.all); 00096 } 00097 00098 00099 //***************************************************************************** 00100 int32_t MAX30101::setModeConfiguration(const ModeConfiguration_u config) 00101 { 00102 return writeRegister(ModeConfiguration, (config.all & 0xC7)); 00103 } 00104 00105 00106 //***************************************************************************** 00107 int32_t MAX30101::getModeConfiguration(ModeConfiguration_u &config) 00108 { 00109 return readRegister(ModeConfiguration, config.all); 00110 } 00111 00112 00113 //***************************************************************************** 00114 int32_t MAX30101::setSpO2Configuration(const SpO2Configuration_u config) 00115 { 00116 return writeRegister(SpO2Configuration, (config.all & 0x7F)); 00117 } 00118 00119 00120 //***************************************************************************** 00121 int32_t MAX30101::getSpO2Configuration(SpO2Configuration_u &config) 00122 { 00123 return readRegister(SpO2Configuration, config.all); 00124 } 00125 00126 00127 //***************************************************************************** 00128 int32_t MAX30101::setLEDPulseAmplitude(Registers_e reg, const uint8_t amp) 00129 { 00130 return writeRegister(reg, amp); 00131 } 00132 00133 00134 //***************************************************************************** 00135 int32_t MAX30101::getLEDPulseAmplitude(Registers_e reg, uint8_t &) 00136 { 00137 return readRegister(reg, amp); 00138 } 00139 00140 00141 //***************************************************************************** 00142 int32_t MAX30101::setMultiLEDModeControl(Registers_e reg, const ModeControlReg_u data) 00143 { 00144 return writeRegister(reg, data.all); 00145 } 00146 00147 00148 //***************************************************************************** 00149 int32_t MAX30101::getMultiLEDModeControl(Registers_e reg, ModeControlReg_u &data) 00150 { 00151 return readRegister(reg, data.all); 00152 } 00153 00154 00155 //***************************************************************************** 00156 int32_t MAX30101::getDieTemperature(uint16_t &data) 00157 { 00158 int32_t result = -1; 00159 00160 //Die temp conversion time is 30ms 00161 //ATTEMPTS > than 30ms at 100KHz SCL for getInterruptStatus call 00162 const uint32_t ATTEMPTS = 100; 00163 uint32_t num_reads = 0; 00164 00165 //local i2c transaction buffer 00166 char local_data[2]; 00167 local_data[0] = DieTempConfig; 00168 local_data[1] = 1; 00169 00170 //initiate die temp conversion 00171 result = m_i2cBus.write(I2C_W_ADRS, local_data, 2, true); 00172 if(result == 0) 00173 { 00174 //object for holding status registers data 00175 InterruptBitField_u status; 00176 status.all = 0; 00177 00178 //poll status registers until temp ready, or read fails 00179 do 00180 { 00181 result = getInterruptStatus(status); 00182 num_reads++; 00183 } 00184 while(!status.bits.die_temp && (result == 0) && (num_reads < ATTEMPTS)); 00185 00186 if(status.bits.die_temp) 00187 { 00188 //set pointer to temperature integer register 00189 local_data[0] = DieTempInt; 00190 result = m_i2cBus.write(I2C_W_ADRS, local_data, 1, true); 00191 if(result == 0) 00192 { 00193 //read two bytes 00194 result = m_i2cBus.read(I2C_R_ADRS, local_data, 2); 00195 if(result == 0) 00196 { 00197 //stuff data 00198 data = ( (local_data[0] << 8) | (local_data[1] << 4) ); 00199 data = (data >> 4); 00200 } 00201 } 00202 } 00203 else 00204 { 00205 //if result equals 0 because num_reads exceeded ATTEMPTS, 00206 //change result to -1. Otherwise keep result's error code. 00207 result = (result == 0) ? -1 : result; 00208 } 00209 } 00210 return result; 00211 } 00212 00213 00214 //***************************************************************************** 00215 int32_t MAX30101::getDieTemperatureC(float &data) 00216 { 00217 uint16_t raw_temp; 00218 00219 int32_t result = getDieTemperature(raw_temp); 00220 if(result == 0) 00221 { 00222 if(raw_temp & 0x0800) 00223 { 00224 data = ((0xFFFFF000 | raw_temp)/16.0F); 00225 } 00226 else 00227 { 00228 data = (raw_temp/16.0F); 00229 } 00230 } 00231 00232 return result; 00233 } 00234 00235 00236 //***************************************************************************** 00237 float MAX30101::celsius2fahrenheit(float c) 00238 { 00239 return ((1.8F * c) + 32.0F); 00240 } 00241 00242 00243 //***************************************************************************** 00244 int32_t MAX30101::setProxIntThreshold(const uint8_t data) 00245 { 00246 return writeRegister(ProxIntThreshold, data); 00247 } 00248 00249 00250 //***************************************************************************** 00251 int32_t MAX30101::getProxIntThreshold(uint8_t &data) 00252 { 00253 return readRegister(ProxIntThreshold, data); 00254 } 00255 00256 00257 //***************************************************************************** 00258 int32_t MAX30101::readFIFO(LedChannels_e numLeds, uint8_t *data, uint16_t &readBytes) 00259 { 00260 int32_t result = -1; 00261 00262 readBytes = 0; 00263 00264 //Get write pointer 00265 result = readRegister(FIFO_WritePointer, m_fifoWritePtr); 00266 if(result == 0) 00267 { 00268 //Get read pointer 00269 result = readRegister(FIFO_ReadPointer, m_fifoReadPtr); 00270 if(result == 0) 00271 { 00272 //Calculate num bytes to read 00273 if(m_fifoWritePtr > m_fifoReadPtr) 00274 { 00275 m_fifoNumBytes = ((m_fifoWritePtr - m_fifoReadPtr) * 00276 (BYTES_PER_CH * numLeds)); 00277 } 00278 else 00279 { 00280 m_fifoNumBytes = (((32 - m_fifoReadPtr) + m_fifoWritePtr) * 00281 (BYTES_PER_CH * numLeds)); 00282 } 00283 00284 //temporary buffer for data 00285 char local_data[MAX30101::MAX_FIFO_BYTES]; 00286 local_data[0] = FIFO_DataRegister; 00287 00288 //Set fifo data ptr 00289 result = m_i2cBus.write(I2C_W_ADRS, local_data, 1, true); 00290 if(result == 0) 00291 { 00292 //read fifo 00293 result = m_i2cBus.read(I2C_R_ADRS, local_data, m_fifoNumBytes); 00294 if(result == 0) 00295 { 00296 //move data to user buffer 00297 memcpy(data, local_data, m_fifoNumBytes); 00298 readBytes = m_fifoNumBytes; 00299 } 00300 } 00301 } 00302 } 00303 00304 return result; 00305 } 00306 00307 00308 //***************************************************************************** 00309 int32_t MAX30101::writeRegister(Registers_e reg, uint8_t value) 00310 { 00311 char local_data[2] = {reg, value}; 00312 00313 return m_i2cBus.write(I2C_W_ADRS, local_data, 2); 00314 } 00315 00316 00317 //***************************************************************************** 00318 int32_t MAX30101::readRegister(Registers_e reg, uint8_t &value) 00319 { 00320 int32_t result; 00321 00322 char local_data[2]; 00323 local_data[0] = reg; 00324 00325 result = m_i2cBus.write(I2C_W_ADRS, local_data, 1); 00326 if(result == 0) 00327 { 00328 result = m_i2cBus.read(I2C_R_ADRS, (local_data + 1), 1); 00329 if (result == 0) 00330 { 00331 value = local_data[1]; 00332 } 00333 } 00334 00335 return result; 00336 } 00337
Generated on Wed Jul 13 2022 02:50:32 by 1.7.2