m

Fork of MAX30100 by Eduardo Avelar

MAX30100.cpp

Committer:
arturogasca
Date:
2016-12-03
Revision:
1:e3b9aff8f221
Parent:
0:010b908e2187

File content as of revision 1:e3b9aff8f221:

/*
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"
#define I2C_SDA p7
#define I2C_SCL p6


I2C Wire(I2C_SDA , I2C_SCL );
//I2C Wire(P0_1, P0_2); //sda 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;
}