Max30101 pulse oximeter library

max30101.cpp

Committer:
jurica238814
Date:
2017-11-22
Revision:
6:30640433472a
Parent:
5:2927db6219fc

File content as of revision 6:30640433472a:

/*
 * Made by Jurica Resetar @ Meridda
 * 2017.
 *  
 * All rights reserved
 *
 */
 
#include "mbed.h"
#include "max30101.h"
#include "max30101_regs.h"

MAX30101::MAX30101(I2C *i2c, PinName enablePin): i2c(i2c), _enable(enablePin){
    _enable = 0;
    i2cAddress = MAX_I2C_ADDRESS;
}

char MAX30101::readID(){
    char data = 0;
    
    readFromReg(PART_ID_REG, &data, 1);
    return data;
}

uint8_t MAX30101::writeToReg(char regAddress, char *data, int len){
    uint8_t success; /* '0' - NAK was received '1' - ACK was received, '2' - timeout */
    char dataToSend[2];
    
    dataToSend[0] = regAddress;
    dataToSend[1] = *data;
    success = i2c->write(i2cAddress & 0xFE, dataToSend, len + 1); // R/W bit is set low for a write command
    return success;
}

uint8_t MAX30101::readFromReg(char regAddress, char *dataBuffer, int len){
    uint8_t success;    /* 0 on success (ack), non-0 on failure (nack) */
    char regAddr = regAddress;
    
    i2c->write(i2cAddress & 0xFE, &regAddr, 1);               // R/W bit is set low for a write command
    success = i2c->read(i2cAddress | 0x01, dataBuffer, len);     // R/W bit is set high for a read command
    return success;
}

float MAX30101::getTemperature(){
    int8_t integer;
    uint8_t fraction;
    char data;
    
    data = 0x02;
    writeToReg(INT_ENABLE_2_REG, &data, 1);         // Enable TEMP_RDY interrupt
    
    data = 0x01;
    writeToReg(DIE_TEMP_CONFIG, &data, 1);          // Start temperature read
    do{ 
        // Loop while temperature data is not ready
        readFromReg(INT_STATUS_2_REG, &data, 1);
    }while(!(data & 0x02));
    
    readFromReg(DIE_TEMP_INT_REG, (char*)(&integer), 1);
    readFromReg(DIE_TEMP_FRAC_REG, (char*)(&fraction), 1);
    (integer & 0x80) ? (~integer + 1)*(-1) : integer;   // Convert integer part from 2's complement
        
    return integer + (0.0625 * (fraction & 0x0F));      // Only lower fraction nibble is valid
}

uint8_t MAX30101::configFifo(char *data){
    uint8_t success;
    success = writeToReg((char)FIFO_CONFIG_REG, data, 1);
    return success;
}

uint32_t MAX30101::readFifoSample(char readAddres){
    uint32_t tempDataI;
    char tempDataC[3] = {0};
    
    readFromReg(readAddres, tempDataC, 3);    
    tempDataI = ((*(tempDataC+0) << 16) & 0x000F0000);
    tempDataI = tempDataI | ((*(tempDataC+1) << 8) & 0x0000FF00);
    tempDataI = tempDataI | (*(tempDataC+2) & 0x000000FF);
    return tempDataI;
}

uint8_t MAX30101::getNumOfSamples(){
    char writePtr;
    char readPtr;
    int8_t numOfSamples;
    
    readFromReg(FIFO_WRITE_PTR_REG, &writePtr, 1);
    readFromReg(FIFO_READ_PTR_REG, &readPtr, 1);
    numOfSamples = writePtr - readPtr;
    if(numOfSamples & 0x80) return (readPtr - writePtr);    // Pointers are wrap around
    return (uint8_t) numOfSamples;
}

uint8_t MAX30101::readFifo(int *data, int numOfSamples){
    uint8_t i;
        
    for(i=0; i<numOfSamples; i++){
        *(data+i) = readFifoSample(FIFO_DATA_REG_REG);
    }   
    return 0;
}

uint8_t MAX30101::setSamplesPerSecond(SamplesPerSecond samplesPerSecond){
    char data;
    uint8_t success;
    
    readFromReg((char)SP02_CONFIG_REG, &data, 1);
    data = data | (samplesPerSecond << 2);
    success = writeToReg((char)SP02_CONFIG_REG, &data, 1);
    return success;
}

void MAX30101::setupRedLED(uint8_t pulseInterval){
    char data = 0x00;
    data = 0x02;
    writeToReg((char)MODE_CONFIG_REG, &data, 1);

    data = (char)pulseInterval;
    writeToReg((char)LED1_PA, &data, 1);
        
    data = 0b00011111;
    configFifo(&data);
    
    data = 0b00000011;
    writeToReg((char)SP02_CONFIG_REG, &data, 1);
}

void MAX30101::turnGreenLED(){
    /*
    TODO
    */
}