John Greene / Mbed OS MAX30101_HR_SPO2

Dependencies:   MAX30101 max32630fthr

Fork of MAX30101_Demo_Plot_Algorithm by John Greene

main.cpp

Committer:
coreyharris
Date:
2017-08-29
Revision:
6:238d2eec53de
Parent:
5:2f708191f1bd
Child:
7:6075af57668e

File content as of revision 6:238d2eec53de:

/*******************************************************************************
 * Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 *
 * Except as contained in this notice, the name of Maxim Integrated
 * Products, Inc. shall not be used except as stated in the Maxim Integrated
 * Products, Inc. Branding Policy.
 *
 * The mere transfer of this software does not imply any licenses
 * of trade secrets, proprietary technology, copyrights, patents,
 * trademarks, maskwork rights, or any other form of intellectual
 * property whatsoever. Maxim Integrated Products, Inc. retains all
 * ownership rights.
 *******************************************************************************
 */
 

#include "mbed.h"
#include "max32630fthr.h"
#include "MAX30101.h"

MAX32630FTHR pegasus(MAX32630FTHR::VIO_3V3);

bool op_sensor_config(MAX30101 &op_sensor);

/* Op Sensor FIFO nearly full callback */
volatile bool op_sensorIntFlag = 0;                  
void op_sensor_callback()
{
    op_sensorIntFlag = 1;
}

int main()
{
    Serial pc(USBTX, USBRX);            // Use USB debug probe for serial link
    pc.baud(115200);                    // Baud rate = 115200
    
    DigitalOut rLed(LED1, LED_OFF);     // Debug LEDs
    DigitalOut gLed(LED2, LED_OFF);
    DigitalOut bLed(LED3, LED_OFF);
    
    InterruptIn op_sensor_int(P3_2);            // Config P3_2 as int. in for
    op_sensor_int.fall(&op_sensor_callback);    // FIFO ready interrupt
    
    I2C i2cBus(I2C1_SDA, I2C1_SCL);         // I2C bus, P3_4 = SDA, P3_5 = SCL 

    MAX30101 op_sensor(i2cBus);             // Create new MAX30101 on i2cBus
    int rc = op_sensor_config(op_sensor);   // Config sensor, return 0 on success
    
    MAX30101::InterruptBitField_u ints;         // Read interrupt status to clear
    rc = op_sensor.getInterruptStatus(ints);    // power on interrupt 
    
    uint8_t fifoData[MAX30101::MAX_FIFO_BYTES];
    uint16_t idx, readBytes;
    int16_t opSample;
    uint32_t sample;
    while(1) {

        if( rc == 0 ) {
            
            // Check if op_sensor interrupt asserted
            if(op_sensorIntFlag) {
                
                op_sensorIntFlag = 0;                       // Lower interrupt flag
                rc = op_sensor.getInterruptStatus(ints);    // Read interrupt status 
                
                // Check if FIFO almost full interrupt asserted
                if((rc == 0) && (ints.bits.a_full)) {
                    
                    // Read FIFO 
                    rc = op_sensor.readFIFO(MAX30101::OneLedChannel, fifoData, readBytes);     
                    
                    if(rc == 0) {
                        
                        // Convert read bytes into samples
                        for(idx = 0; idx < readBytes; idx+=3) {
                            sample = (fifoData[idx]<<16) | (fifoData[idx+1]<<8) | (fifoData[idx+2]);
                            opSample = sample >> 8;            // Sign extends sample to 16-bit opSample
                            pc.printf("%i\r\n", opSample);     // Print results
                        }
                        
                    }
                }
            }
        
        // If rc != 0, a communication error has occurred 
        } else {        
            
            pc.printf("Something went wrong, "
                      "check the I2C bus or power connections... \r\n");
            bLed = LED_OFF;
            gLed = LED_OFF;
            
            while(1)
            {
                rLed = !rLed;
                wait(0.5);   
            } 
        }  
        
    } 
}


bool op_sensor_config(MAX30101 &op_sensor) {
    
    //Reset Device
    MAX30101::ModeConfiguration_u modeConfig;
    modeConfig.all = 0;
    modeConfig.bits.reset = 1;
    int32_t rc = op_sensor.setModeConfiguration(modeConfig);
    
        
    //enable MAX30101 interrupts
    MAX30101::InterruptBitField_u ints;
    if(rc == 0)
    {
        ints.all = 0;
        ints.bits.die_temp = 1;     // Enable FIFO almost full interrupt
        ints.bits.a_full = 1;       // Enable internal die temp. interrupt
        rc = op_sensor.enableInterrupts(ints);
    }
    
    //configure FIFO
    MAX30101::FIFO_Configuration_u fifoConfig;
    if(rc == 0)
    {
        fifoConfig.all = 0;
        fifoConfig.bits.fifo_a_full = 15;                               // Max level of 15 samples 
        fifoConfig.bits.sample_average = MAX30101::AveragedSamples_8;   // Average 8 samples
        rc = op_sensor.setFIFOConfiguration(fifoConfig);
    }
    
    MAX30101::SpO2Configuration_u spo2Config;
    if(rc == 0)
    {
        spo2Config.all = 0;
        spo2Config.bits.spo2_sr = MAX30101::SR_400_Hz;      // SpO2 SR = 400Hz
        spo2Config.bits.led_pw = 1;                         // 16-bit ADC resolution
        rc = op_sensor.setSpO2Configuration(spo2Config);
    }
    
    //Set LED1 drive current
    if(rc == 0)
    {
        // Heart Rate only, 1 LED channel, Pulse amp. = 0x1F
        rc = op_sensor.setLEDPulseAmplitude(MAX30101::LED1_PA, 0x1F);
    }
       
    //Set operating mode
    modeConfig.all = 0;
    if(rc == 0)
    {
        modeConfig.bits.mode = MAX30101::HeartRateMode;     // Heart-rate only
        rc = op_sensor.setModeConfiguration(modeConfig);
    }    
    
    
    return rc;
}