Library for MAX30101, read/write functions for registers implemented.

Dependents:   test_MAX30101 testSensor

MAX30101.cpp

Committer:
Rhyme
Date:
2017-03-27
Revision:
5:7e7ad1807454
Parent:
4:c6761ad52524
Child:
6:8fbe6e6eeff1

File content as of revision 5:7e7ad1807454:

/**
 * MAX30101
 * High-Sensitivity Pulse Oximeter and
 * Heart-Rate Sensor for Wearable Health
 */
#include "mbed.h"
#include "MAX30101.h"

/* Status */
#define REG_INT_MSB        0x00 /* Interrupt Status 1 */
#define REG_INT_LSB        0x01 /* Interrupt Status 2 */
#define REG_INT_ENB_MSB    0x02 /* Interrupt Enable 1 */
#define REG_INT_ENB_LSB    0x03 /* Interrupt Enable 2 */
/* FIFO */
#define REG_FIFO_WR_PTR    0x04 /* FIFO Write Pointer */
#define REG_OVF_COUNTER    0x05 /* Overflow Counter */
#define REG_FIFO_RD_PTR    0x06 /* FIFO Read Pointer */
#define REG_FIFO_DATA      0x07 /* FIFO Data Register */
/* Configuration */
#define REG_FIFO_CONFIG    0x08 /* FIFO Configuration */
#define REG_MODE_CONFIG    0x09 /* Mode Configuration */
#define REG_SPO2_CONFIG    0x0A /* SpO2 Configuration */
/* reserved                0x0B */
#define REG_LED1_PA        0x0C /* LED Pulse Amplitude 1 */
#define REG_LED2_PA        0x0D /* LED Pulse Amplitude 2 */
#define REG_LED3_PA        0x0E /* LED Pulse Amplitude 3 */
/* reserved                0x0F */
#define REG_PILOT_PA       0x10 /* Proximity LED Pulse Amplitude */
#define REG_SLOT_MSB       0x11 /* Multi-LED Mode Control Registers 2, 1 */
#define REG_SLOT_LSB       0x12 /* Multi-LED Mode Control Registers 4, 3 */
/* DIE Temperature */
#define REG_TEMP_INT       0x1F /* Die Temperature Integer */
#define REG_TEMP_FRAC      0x20 /* Die Temperature Fraction */
#define REG_TEMP_EN        0x21 /* Die Temperature Config */
/* Proximity Function */
#define REG_PROX_INT_THR   0x30 /* Proximity Interrupt Threshold */
/* Part ID */
#define REG_REV_ID         0xFE /* Revision ID */
#define REG_PART_ID        0xFF /* Part ID: 0x15 */
/* Depth of FIFO */
#define FIFO_DEPTH         32

MAX30101::MAX30101(PinName sda, PinName scl, int addr) : m_i2c(sda, scl), m_addr(addr<<1) {
    // activate the peripheral
}

MAX30101::~MAX30101() { }

void MAX30101::readRegs(int addr, uint8_t * data, int len) {
    char t[1] = {addr} ;
    m_i2c.write(m_addr, t, 1, true) ;
    m_i2c.read(m_addr, (char*)data, len) ;
}

void MAX30101::writeRegs(uint8_t * data, int len) {
   m_i2c.write(m_addr, (char *)data, len) ;
}

uint8_t MAX30101::getID(void)
{
    uint8_t id ;
    readRegs(REG_PART_ID, &id, 1) ;
    return( id ) ;
}

uint8_t MAX30101::getRev(void)
{
    uint8_t rev ;
    readRegs(REG_REV_ID, &rev, 1) ;
    return( rev ) ;
}

uint16_t MAX30101::getIntStatus(void) 
{
    uint8_t res[2] ;
    uint16_t value ;
    readRegs(REG_INT_MSB, res, 2) ;
    value = (res[0] << 8) | res[1] ;
    return( value ) ;
}

uint16_t MAX30101::getIntEnable(void) 
{
    uint8_t res[2] ;
    uint16_t value ;
    readRegs(REG_INT_ENB_MSB, res, 2) ;
    value = (res[0] << 8) | res[1] ;
    return( value ) ;
}

void MAX30101::setIntEnable(uint16_t mask) 
{
    uint8_t res[3] ;
    res[0] = REG_INT_ENB_MSB ;
    res[1] = (mask >> 8) & 0xFF ;
    res[2] = (mask & 0xFF) ;
    writeRegs(res, 3) ;
}

uint8_t MAX30101::getFIFO_WR_PTR(void) 
{
    uint8_t data ;
    readRegs(REG_FIFO_WR_PTR, &data, 1) ;
    return( data ) ;
}

void    MAX30101::setFIFO_WR_PTR(uint8_t data) 
{
    uint8_t res[2] ;
    res[0] = REG_FIFO_WR_PTR ;
    res[1] = data ;
    writeRegs(res, 2) ;
}

uint8_t MAX30101::getOVF_COUNTER(void) 
{
    uint8_t data ;
    readRegs(REG_OVF_COUNTER, &data, 1) ;
    return( data ) ;
}

void    MAX30101::setOVF_COUNTER(uint8_t data) 
{
    uint8_t res[2] ;
    res[0] = REG_OVF_COUNTER ;
    res[1] = data ;
    writeRegs(res, 2) ;
}

uint8_t MAX30101::getFIFO_RD_PTR(void)
{
    uint8_t data ;
    readRegs(REG_FIFO_RD_PTR, &data, 1) ;
    return( data ) ;
}

void    MAX30101::setFIFO_RD_PTR(uint8_t data) 
{
    uint8_t res[2] ;
    res[0] = REG_FIFO_RD_PTR ;
    res[1] = data ;
    writeRegs(res, 2) ;
}

uint8_t MAX30101::getFIFO_DATA(void) 
{
    uint8_t data ;
    readRegs(REG_FIFO_DATA, &data, 1) ;
    return( data ) ;
}

void    MAX30101::setFIFO_DATA(uint8_t data) 
{
    uint8_t res[2] ;
    res[0] = REG_FIFO_DATA ;
    res[1] = data ;
    writeRegs(res, 2) ;
}

uint8_t MAX30101::getFIFO_CONFIG(void) 
{
    uint8_t data ;
    readRegs(REG_FIFO_CONFIG, &data, 1) ;
    return( data ) ;
}

void    MAX30101::setFIFO_CONFIG(uint8_t data) 
{
    uint8_t res[2] ;
    res[0] = REG_FIFO_CONFIG ;
    res[1] = data ;
    writeRegs(res, 2) ;
}

uint8_t MAX30101::getMODE_CONFIG(void)
{
    uint8_t data ;
    readRegs(REG_MODE_CONFIG, &data, 1) ;
    return( data ) ;
}

void    MAX30101::setMODE_CONFIG(uint8_t data) 
{
    uint8_t res[2] ;
    res[0] = REG_MODE_CONFIG ;
    res[1] = data ;
    writeRegs(res, 2) ;
}

uint8_t MAX30101::getSPO2_CONFIG(void)
{
    uint8_t data ;
    readRegs(REG_SPO2_CONFIG, &data, 1) ;
    return( data ) ;
}

void    MAX30101::setSPO2_CONFIG(uint8_t data)
{
    uint8_t res[2] ;
    res[0] = REG_SPO2_CONFIG ;
    res[1] = data ;
    writeRegs(res, 2) ;
}

uint8_t MAX30101::getLED1_PA(void)
{
    uint8_t data ;
    readRegs(REG_LED1_PA, &data, 1) ;
    return( data ) ;
}

void    MAX30101::setLED1_PA(uint8_t data)
{
    uint8_t res[2] ;
    res[0] = REG_LED1_PA ;
    res[1] = data ;
    writeRegs(res, 2) ;
}

uint8_t MAX30101::getLED2_PA(void)
{
    uint8_t data ;
    readRegs(REG_LED2_PA, &data, 1) ;
    return( data ) ;
}

void    MAX30101::setLED2_PA(uint8_t data)
{
    uint8_t res[2] ;
    res[0] = REG_LED2_PA ;
    res[1] = data ;
    writeRegs(res, 2) ;
}

uint8_t MAX30101::getLED3_PA(void)
{
    uint8_t data ;
    readRegs(REG_LED3_PA, &data, 1) ;
    return( data ) ;
}

void    MAX30101::setLED3_PA(uint8_t data)
{
    uint8_t res[2] ;
    res[0] = REG_LED3_PA ;
    res[1] = data ;
    writeRegs(res, 2) ;
}

uint8_t MAX30101::getPILOT_PA(void) 
{
    uint8_t data ;
    readRegs(REG_PILOT_PA, &data, 1) ;
    return( data ) ;
}

void    MAX30101::setPILOT_PA(uint8_t data)
{
    uint8_t res[2] ;
    res[0] = REG_PILOT_PA ;
    res[1] = data ;
    writeRegs(res, 2) ;
}

uint16_t MAX30101::getSLOT(void) 
{
    uint8_t res[2] ;
    uint16_t data ;
    readRegs(REG_SLOT_MSB, res, 2) ;
    data = (res[0] << 8) | res[1] ;
    return( data ) ;
}

void     MAX30101::setSLOT(uint16_t data) 
{
    uint8_t res[3] ;
    res[0] = REG_SLOT_MSB ;
    res[1] = (data >> 8) & 0xFF ;
    res[2] = data & 0xFF ;
    writeRegs(res, 3) ;
}

uint8_t  MAX30101::getTEMP_INT(void)  
{
    uint8_t data ;
    readRegs(REG_TEMP_INT, &data, 1) ;
    return( data ) ;
}

uint8_t  MAX30101::getTEMP_FRAC(void) 
{
    uint8_t data ;
    readRegs(REG_TEMP_FRAC, &data, 1) ;
    return( data ) ;
}

uint8_t  MAX30101::getTEMP_EN(void) 
{
    uint8_t data ;
    readRegs(REG_TEMP_EN, &data, 1) ;
    return( data ) ;
}

float MAX30101::getTEMP(void)
{
    float temp ;
    int temp_int, temp_frac ;
    while(getTEMP_EN() == 0x01) { } 
    temp_int = getTEMP_INT() ;
    temp_frac = getTEMP_FRAC() ;
    temp = ((float)temp_int)+(((float)temp_frac)/16.0) ;
    return( temp ) ;
}

uint8_t  MAX30101::getPROX_INT_THR(void)  
{
    uint8_t data ;
    readRegs(REG_PROX_INT_THR, &data, 1) ;
    return( data ) ;
}

void     MAX30101::setPROX_INT_THR(uint8_t data)  
{
    uint8_t res[2] ;
    res[0] = REG_PROX_INT_THR ;
    res[1] = data ;
    writeRegs(res, 2) ;
}

void MAX30101::clearFIFO(void)
{
    uint8_t res[5] ;
    res[0] = REG_FIFO_WR_PTR ;
    res[1] = 0x00 ; /* FIFO_WR_PTR */
    res[2] = 0x00 ; /* OVF_COUNTER */
    res[3] = 0x00 ; /* FIFO_RD_PTR */
    res[4] = 0x00 ; /* FIFO_DATA (do we need to clear this?) */
    writeRegs(res, 5) ;
}

/**
 * readFIFO(void)
 * FIFO data is always a 3-bytes data
 * byte1[1:0] : FIFO_DATA[17]-FIFO_DATA[16]
 * byte2[7:0] : FIFO_DATA[15]-FIFO_DATA[8]
 * byte3[7:0] : FIFO_DATA[7]-FIFO_DATA[0]
 * The data is left aligned, so FIFO_DATA[17]
 * is always MSB, although the data length 
 * can be 18-bit ~ 15-bit
 */
uint32_t MAX30101::readFIFO(void)
{
    uint32_t data = 0 ;
    uint8_t res[3] ;
    readRegs(REG_FIFO_DATA, res, 3) ;
    data = 
        ((res[0] & 0x03)<<16)
        | (res[1] << 8) 
        | res[2] ;
    return( data ) ;
}

void MAX30101::reset(void)
{
    uint8_t res[2] ;
    res[0] = REG_MODE_CONFIG ;
    res[1] = 0x40 ; /* reset */
    writeRegs(res, 2) ;
}