Test program for MAX30101 Barely working.

Dependencies:   MAX30101 mbed vt100

main.cpp

Committer:
Rhyme
Date:
2017-05-12
Revision:
4:4b1763d399a0
Parent:
3:f3d19ad49aee

File content as of revision 4:4b1763d399a0:

#include "mbed.h"
#include "vt100.h"
#include "MSS.h"
#include "MAX30101.h"
/**
 * MAX30101 I2C addresss
 * Write 0xAE   0b1010_1110
 * Read  0xAF   0b1010_1111
 * 7bit address = 0b101_0111 = 0x57
 */
#define MAX30101_I2C_ADDRESS (0x57)

#ifndef FIFO_DEPTH
#define FIFO_DEPTH 32
#endif

vt100 *tty = 0 ;
MAX30101 *max30101 = 0 ;
InterruptIn *int0 ;

/* data read test following the pseudo code
 * written in the datasheet
 */
void doPseudo(void)
{
    uint32_t data[3] ;
    uint8_t fifo_wr_ptr, fifo_rd_ptr ;
    int num_available_samples = 0 ;
//    int num_samples_to_read = 0 ;
    int i ;

    fifo_wr_ptr = max30101->getFIFO_WR_PTR() ;
    fifo_rd_ptr = max30101->getFIFO_RD_PTR() ;
    num_available_samples = (fifo_wr_ptr + FIFO_DEPTH - fifo_rd_ptr) % FIFO_DEPTH ;
    printf("=== %d data ===\n", num_available_samples) ;
    for (i = 0 ; i < num_available_samples ; i++ ) {
        data[0] = max30101->readFIFO() ; /* LED1 */
        data[1] = max30101->readFIFO() ; /* LED2 */
        data[2] = max30101->readFIFO() ; /* LED3 */
        printf("LED1: 0x%05X, LED2: 0x%05X, LED3: 0x%05X\n",
            data[0], data[1], data[2]) ;
    }
}

void initSPO2(void)
{
    uint8_t config_byte = 0 ;
    uint16_t slot_config = 0 ;
    
    /* config for SPO2 (0x0A) */
    config_byte =
          (0x01 << 5)  /* SPO2_ADC_RGE */
 //       | (0x05 << 3)  /* SPO2_SR 101 = 1000 samples/sec */
        | (0x00 << 3) /* SPO2_SR 000 = 50 samples/sec */
        | (0x00)       /* LED_PW 00 = 69us */
        ;
    max30101->setSPO2_CONFIG(config_byte) ;
    
    /* slot configuration */
    slot_config = 
          (0x02 << 12) /* SLOT2 LED2(IR) */
        | (0x01 << 8)  /* SLOT1 LED1(RED) */
        | (0x00 << 4)  /* SLOT4 none */
        | (0x00)       /* SLOT3 none */
        ;
    max30101->setSLOT(slot_config) ;
    
    /* Inititalize FIFO */
        /* config for FIFO Configuration (0x08) */
    config_byte =
          (0x02  << 5) /* SMP_AVE = 2 -> avarage of 4 data */
        | (0x01  << 4)  /* FIFO_ROLLOVER_EN = 1 */
//        | (0x0C)        /* FIFO ALMOST FULL at 12 (0x0C) */
        | (0x09)          /* FIFO ALMOST FULL at 9 */
        ;
    max30101->setFIFO_CONFIG(config_byte) ;
    

}

void readSPO2_FIFO(void)
{
    uint32_t data[2] ;
    uint8_t fifo_wr_ptr, fifo_rd_ptr ;
    int num_available_samples = 0 ;
    int num_samples_to_read = 6 ;
    int i ;

    fifo_wr_ptr = max30101->getFIFO_WR_PTR() ;
    fifo_rd_ptr = max30101->getFIFO_RD_PTR() ;
    num_available_samples = (fifo_wr_ptr + FIFO_DEPTH - fifo_rd_ptr) % FIFO_DEPTH ;

    if (num_available_samples < num_samples_to_read) {
        num_samples_to_read = num_available_samples / 2 ;
    } else {
        num_samples_to_read = num_available_samples ;
    }
    printf("=== %d data %d to read===\n", 
    num_available_samples, num_samples_to_read) ;
    for (i = 0 ; i < num_samples_to_read ; i++ ) {
        data[0] = max30101->readFIFO() ; /* LED1 */
        data[1] = max30101->readFIFO() ; /* IR */
//        printf("LED1: 0x%05X, IR: 0x%05X\n", data[0], data[1]) ;
    }
//    max30101->setFIFO_WR_PTR(0) ;
//    max30101->setFIFO_RD_PTR(0) ;
}

void SPO2_isr(void)
{
    uint16_t flag, config ;
    float temp ;
    int temp_int, temp_frac ;

    flag = max30101->getIntStatus() ;
    config = max30101->getIntEnable() ;
//    printf("Int: 0x%04X Enable: 0x%04X\n", flag, config) ;
    if (flag & INT_ST_A_FULL) { /* A_FULL_EN */
//        printf("FIFO almost full!\n") ;
        readSPO2_FIFO() ;
    }
    if (flag & INT_ST_PPG_RGY) { /* New FIFO Data Ready */
        printf("New FIFO Data Ready\n") ;
        doPseudo() ;
    }
    if (flag & INT_ST_ALC_OVF) { /* Ambient Light Cancellaration Overflow */
        printf("Ambient Light Cancellaration Overflow\n") ;
    }
    if (flag & INT_ST_PROX_INT) {/* Proximity Threshold Triggered */
        printf("Proximity Threshold Triggered\n") ;
    }
    if (flag & INT_ST_PWR_RDY) {/* Power Ready Flag */
        printf("Power Ready!\n") ;
    }
    if (flag & INT_ST_DIE_TEMP_RDY) {/* Internal Temperature Ready Flag */
        printf("DIE Temperature Ready!\n") ;
        temp_int = max30101->getTEMP_INT() ;
        temp_frac = max30101->getTEMP_FRAC() ;
        temp = ((float)temp_int)+(((float)temp_frac)/16.0) ;
        printf("Temp: %.2f\n", temp) ;
    }
}

void doSPO2(void)
{
    uint8_t config_byte = 0 ;
    uint16_t slot_config = 0 ;
    uint16_t init_config = 0 ;
    
    int0->fall(&SPO2_isr) ;
    /* Enter into SpO2 Mode. Initiate a Temperature measurement */
        /* I2C Write Command sets MODE[2:0] = 0x03 */
        config_byte = 0x03 ; /* SpO2 mode */
        max30101->setMODE_CONFIG(config_byte) ;

        /* Mask the SPO2_RDY Interrupt */
    /* Temperature Measurement Complete, Interrupt Generated */
        /* TEMP_RDY interrupt triggers */
        /* alerting the central to read the data */
    /* Temp Data is Read, Interrupt Cleared */
    /* FIFO is Almost Full, Interrupt Generated */
    /* FIFO Data is read, Interrupt Cleared */
    /* Next Sample is Stored. */
    
}

void initHR(void)
{

}

void init(void)
{
    uint32_t slot_config = 0 ;
    uint8_t mode ;
    int0 = new InterruptIn(PIN_INT1) ;
    tty = new vt100() ;
    tty->cls() ;
    max30101 = new MAX30101(PIN_SDA, PIN_SCL, MAX30101_I2C_ADDRESS) ;
    max30101->reset() ;
    
    /* config for Mode Configuration (0x09) */

    mode = 0x07 ; /* Green, Red, and/or IR */
    // mode = 0x03 ; /* SpO2 mode */
    max30101->setMODE_CONFIG(mode) ;

    /* config for FIFO Configuration (0x08) */
    mode =
 //         (0x02  << 5) /* SMP_AVE = 2 -> avarage of 4 data */
          (0x05 << 5) /* SMP_AVE = 5 -> avarage of 32 data */
        | (0x01  << 4)  /* FIFO_ROLLOVER_EN = 1 */
//        | (0x00 << 4)  /* FIFO_ROLLOVER_EN = 0 */
        | (0x0C)        /* FIFO ALMOST FULL at 12 (0x0C) */
        ;
    max30101->setFIFO_CONFIG(mode) ;
    
    max30101->setLED1_PA(0x80) ;
    max30101->setLED2_PA(0x80) ;
    max30101->setLED3_PA(0x80) ;
    max30101->setPILOT_PA(0x80) ;
#if 1
    slot_config = 
          (0x02 << 24) /* SLOT2 LED2(IR) */
        | (0x01 << 16) /* SLOT1 LED1(RED) */
        | (0x00 << 8)  /* SLOT4 none */
        | (0x03)       /* SLOT3 LED3(GREEN) */
        ;
    max30101->setSLOT(slot_config) ;
#endif
    mode = 0x01 ;
    max30101->setPROX_INT_THR(mode) ;

//    max30101->setIntEnable(0xF002) ;
}

void reportID(void)
{
    uint8_t id, rev ;
    id = max30101->getID() ;
    rev = max30101->getRev() ;
    printf("MAX30101 ID: 0x%02X, Rev: 0x%02X\n", id, rev) ;
}

void doInt(void)
{
    uint16_t flag ;
    flag = max30101->getIntStatus() ;
    printf("Int: 0x%04X\n", flag) ;
    if (flag & INT_ST_A_FULL) { /* A_FULL_EN */
        printf("FIFO almost full!\n") ;
    }
    if (flag & INT_ST_PPG_RGY) { /* New FIFO Data Ready */
        doPseudo() ;
    }
    if (flag & INT_ST_ALC_OVF) { /* Ambient Light Cancellaration Overflow */
        printf("Ambient Light Cancellaration Overflow\n") ;
    }
    if (flag & INT_ST_PROX_INT) {/* Proximity Threshold Triggered */
        doPseudo() ;
    }
    if (flag & INT_ST_PWR_RDY) {/* Power Ready Flag */
        printf("Power Ready!\n") ;
    }
    if (flag & INT_ST_DIE_TEMP_RDY) {/* Internal Temperature Ready Flag */
        printf("DIE Temperature Ready!\n") ;
    }
    max30101->setIntEnable(0xE002) ;
}

void doHR(void)
{
}

int main() {
    uint16_t int_config = 0 ;
    uint8_t flag = 0 ;
    float temp = 0.0 ;
    
    init() ;
    
    printf("test MAX30101 for %s (%s)\n", BOARD_NAME, __DATE__) ;
    reportID() ;

    initSPO2() ;
    int0->fall(&SPO2_isr) ;
    max30101->setMODE_CONFIG(MODE_SPO2) ; 
    max30101->setIntEnable( INT_EN_A_FULL | INT_EN_DIE_TEMP_RDY | INT_ST_PPG_RGY ) ;
    int_config = max30101->getIntEnable() ;
    printf("Int enable: 0x%04X\n", int_config) ;
    printf("Temperature, Interrupt flags\n") ;

    while(1) {
      max30101->setTEMP_EN() ; /* trigger temperature read */
        temp = max30101->getTEMP() ;
        flag = max30101->getIntStatus() ;
        printf("%.2f, 0x%02X\n", temp, flag) ;
      wait(1) ;
    }
}