HAND

Dependents:   HAND

Revision:
0:010b908e2187
Child:
1:a9cc51956082
diff -r 000000000000 -r 010b908e2187 MAX30100.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/MAX30100.cpp	Fri Nov 25 00:52:54 2016 +0000
@@ -0,0 +1,199 @@
+/*
+Arduino-MAX30100 oximetry / heart rate integrated sensor library
+Copyright (C) 2016  OXullo Intersecans <x@brainrapers.org>
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "MAX30100.h"
+
+I2C Wire(I2C_SDA , I2C_SCL );
+
+MAX30100::MAX30100()
+{
+
+}
+
+bool MAX30100::begin()
+{
+//    Wire.begin();
+//    Wire.setClock(I2C_BUS_SPEED);
+
+    Wire.frequency(I2C_BUS_SPEED);
+
+    if(!setMode(DEFAULT_MODE))
+        return false;
+    if(!setLedsPulseWidth(DEFAULT_PULSE_WIDTH))
+        return false;
+    if(!setSamplingRate(DEFAULT_SAMPLING_RATE))
+        return false;
+    if(!setLedsCurrent(DEFAULT_IR_LED_CURRENT, DEFAULT_RED_LED_CURRENT))
+        return false;
+    if(!setHighresModeEnabled(true))
+        return false;
+    
+    return true;
+}
+
+bool MAX30100::setMode(Mode mode)
+{
+    if(!writeRegister(MAX30100_REG_MODE_CONFIGURATION, mode))
+        return false;
+    else
+        return true;
+}
+
+bool MAX30100::setLedsPulseWidth(LEDPulseWidth ledPulseWidth)
+{
+    uint8_t previous;
+    if(readRegister(MAX30100_REG_SPO2_CONFIGURATION, &previous))
+        if(!writeRegister(MAX30100_REG_SPO2_CONFIGURATION, (previous & 0xfc) | ledPulseWidth))
+            return false;
+        else
+            return true; 
+    else
+        return false;       
+}
+
+bool MAX30100::setSamplingRate(SamplingRate samplingRate)
+{
+    uint8_t previous;
+    if(readRegister(MAX30100_REG_SPO2_CONFIGURATION, &previous))
+        if(!writeRegister(MAX30100_REG_SPO2_CONFIGURATION, (previous & 0xe3) | (samplingRate << 2)))
+            return false;
+        else
+            return true; 
+    else
+        return false;  
+}
+
+bool MAX30100::setLedsCurrent(LEDCurrent irLedCurrent, LEDCurrent redLedCurrent)
+{
+    if(!writeRegister(MAX30100_REG_LED_CONFIGURATION, redLedCurrent << 4 | irLedCurrent))
+        return false;
+    else
+        return true;     
+}
+
+bool MAX30100::setHighresModeEnabled(bool enabled)
+{
+    uint8_t previous;
+    if(readRegister(MAX30100_REG_SPO2_CONFIGURATION, &previous))
+        if (enabled) {
+            if(!writeRegister(MAX30100_REG_SPO2_CONFIGURATION, previous | MAX30100_SPC_SPO2_HI_RES_EN))
+                return false;
+            else
+                return true; 
+        } else {
+            if(!writeRegister(MAX30100_REG_SPO2_CONFIGURATION, previous & ~MAX30100_SPC_SPO2_HI_RES_EN))
+                return false;
+            else
+                return true;         
+        }
+    else
+        return false;
+}
+
+
+bool MAX30100::update()
+{
+    if(!readFifoData())
+        return false;
+    else
+        return true;
+}
+
+
+/*
+uint8_t MAX30100::readRegister(uint8_t address)
+{
+    Wire.beginTransmission(MAX30100_I2C_ADDRESS);
+    Wire.write(address);
+    Wire.endTransmission(false);
+    Wire.requestFrom(MAX30100_I2C_ADDRESS, 1);
+
+    return Wire.read();
+}
+*/
+
+bool MAX30100::readRegister(uint8_t uch_addr, uint8_t *puch_data)
+/**
+* \brief        Read a MAX30102 register
+* \par          Details
+*               This function reads a MAX30102 register
+*
+* \param[in]    uch_addr    - register address
+* \param[out]   puch_data    - pointer that stores the register data
+*
+* \retval       true on success
+*/
+{
+  char ch_i2c_data;
+  ch_i2c_data=uch_addr;
+  if(Wire.write(I2C_WRITE_ADDR, &ch_i2c_data, 1, true)!=0)
+    return false;
+  if(Wire.read(I2C_READ_ADDR, &ch_i2c_data, 1, false)==0)
+  {
+    *puch_data=(uint8_t) ch_i2c_data;
+    return true;
+  }
+  else
+    return false;   
+}
+
+/*
+void MAX30100::writeRegister(uint8_t address, uint8_t data)
+{
+    Wire.beginTransmission(MAX30100_I2C_ADDRESS);
+    Wire.write(address);
+    Wire.write(data);
+    Wire.endTransmission();
+}
+*/
+
+bool MAX30100::writeRegister(uint8_t uch_addr, uint8_t uch_data)
+/**
+* \brief        Write a value to a MAX30102 register
+* \par          Details
+*               This function writes a value to a MAX30102 register
+*
+* \param[in]    uch_addr    - register address
+* \param[in]    uch_data    - register data
+*
+* \retval       true on success
+*/
+{
+  char ach_i2c_data[2];
+  ach_i2c_data[0]=uch_addr;
+  ach_i2c_data[1]=uch_data;
+  
+  if(Wire.write(I2C_WRITE_ADDR, ach_i2c_data, 2, false)==0)
+    return true;
+  else
+    return false;    
+}
+
+bool MAX30100::readFifoData()
+{
+    char ach_i2c_data[4];
+
+    ach_i2c_data[0]=MAX30100_REG_FIFO_DATA;
+    if(Wire.write(I2C_WRITE_ADDR, ach_i2c_data, 1, true)!=0)
+        return false;
+    if(Wire.read(I2C_READ_ADDR, ach_i2c_data, 4, false)!=0)
+        return false;
+
+    // Warning: the values are always left-aligned
+    rawIRValue = (ach_i2c_data[0] << 8) | ach_i2c_data[1];
+    rawRedValue = (ach_i2c_data[2] << 8) | ach_i2c_data[3];
+    
+    return true;
+}