John Greene / Mbed OS MAX30101_HR_SPO2

Dependencies:   MAX30101 max32630fthr

Fork of MAX30101_Demo_Plot_Algorithm by John Greene

Committer:
johnGreeneMaxim
Date:
Tue Sep 26 16:45:15 2017 +0000
Revision:
8:a1538e8a3fd9
Parent:
7:6075af57668e
Child:
9:affd4e6372a0
final demo plot for pulse ox

Who changed what in which revision?

UserRevisionLine numberNew contents of line
coreyharris 5:2f708191f1bd 1 /*******************************************************************************
coreyharris 5:2f708191f1bd 2 * Copyright (C) 2017 Maxim Integrated Products, Inc., All Rights Reserved.
coreyharris 5:2f708191f1bd 3 *
coreyharris 5:2f708191f1bd 4 * Permission is hereby granted, free of charge, to any person obtaining a
coreyharris 5:2f708191f1bd 5 * copy of this software and associated documentation files (the "Software"),
coreyharris 5:2f708191f1bd 6 * to deal in the Software without restriction, including without limitation
coreyharris 5:2f708191f1bd 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
coreyharris 5:2f708191f1bd 8 * and/or sell copies of the Software, and to permit persons to whom the
coreyharris 5:2f708191f1bd 9 * Software is furnished to do so, subject to the following conditions:
coreyharris 5:2f708191f1bd 10 *
coreyharris 5:2f708191f1bd 11 * The above copyright notice and this permission notice shall be included
coreyharris 5:2f708191f1bd 12 * in all copies or substantial portions of the Software.
coreyharris 5:2f708191f1bd 13 *
coreyharris 5:2f708191f1bd 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
coreyharris 5:2f708191f1bd 15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
coreyharris 5:2f708191f1bd 16 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
coreyharris 5:2f708191f1bd 17 * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
coreyharris 5:2f708191f1bd 18 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
coreyharris 5:2f708191f1bd 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
coreyharris 5:2f708191f1bd 20 * OTHER DEALINGS IN THE SOFTWARE.
coreyharris 5:2f708191f1bd 21 *
coreyharris 5:2f708191f1bd 22 * Except as contained in this notice, the name of Maxim Integrated
coreyharris 5:2f708191f1bd 23 * Products, Inc. shall not be used except as stated in the Maxim Integrated
coreyharris 5:2f708191f1bd 24 * Products, Inc. Branding Policy.
coreyharris 5:2f708191f1bd 25 *
coreyharris 5:2f708191f1bd 26 * The mere transfer of this software does not imply any licenses
coreyharris 5:2f708191f1bd 27 * of trade secrets, proprietary technology, copyrights, patents,
coreyharris 5:2f708191f1bd 28 * trademarks, maskwork rights, or any other form of intellectual
coreyharris 5:2f708191f1bd 29 * property whatsoever. Maxim Integrated Products, Inc. retains all
coreyharris 5:2f708191f1bd 30 * ownership rights.
coreyharris 5:2f708191f1bd 31 *******************************************************************************
coreyharris 5:2f708191f1bd 32 */
coreyharris 5:2f708191f1bd 33
coreyharris 5:2f708191f1bd 34
coreyharris 0:0bd4103885bf 35 #include "mbed.h"
coreyharris 0:0bd4103885bf 36 #include "max32630fthr.h"
coreyharris 0:0bd4103885bf 37 #include "MAX30101.h"
coreyharris 0:0bd4103885bf 38
coreyharris 0:0bd4103885bf 39 MAX32630FTHR pegasus(MAX32630FTHR::VIO_3V3);
coreyharris 0:0bd4103885bf 40
coreyharris 0:0bd4103885bf 41 bool op_sensor_config(MAX30101 &op_sensor);
johnGreeneMaxim 8:a1538e8a3fd9 42 void pmic_config(I2C & i2c_bus, DigitalOut & pmic_en);
coreyharris 0:0bd4103885bf 43
coreyharris 0:0bd4103885bf 44 /* Op Sensor FIFO nearly full callback */
coreyharris 1:471e2b722d24 45 volatile bool op_sensorIntFlag = 0;
coreyharris 0:0bd4103885bf 46 void op_sensor_callback()
coreyharris 0:0bd4103885bf 47 {
coreyharris 1:471e2b722d24 48 op_sensorIntFlag = 1;
coreyharris 0:0bd4103885bf 49 }
coreyharris 0:0bd4103885bf 50
coreyharris 0:0bd4103885bf 51 int main()
coreyharris 0:0bd4103885bf 52 {
coreyharris 1:471e2b722d24 53 Serial pc(USBTX, USBRX); // Use USB debug probe for serial link
coreyharris 1:471e2b722d24 54 pc.baud(115200); // Baud rate = 115200
coreyharris 0:0bd4103885bf 55
coreyharris 1:471e2b722d24 56 DigitalOut rLed(LED1, LED_OFF); // Debug LEDs
coreyharris 0:0bd4103885bf 57 DigitalOut gLed(LED2, LED_OFF);
coreyharris 0:0bd4103885bf 58 DigitalOut bLed(LED3, LED_OFF);
coreyharris 0:0bd4103885bf 59
coreyharris 1:471e2b722d24 60 InterruptIn op_sensor_int(P3_2); // Config P3_2 as int. in for
coreyharris 1:471e2b722d24 61 op_sensor_int.fall(&op_sensor_callback); // FIFO ready interrupt
coreyharris 0:0bd4103885bf 62
coreyharris 4:14d1b87cd3c4 63 I2C i2cBus(I2C1_SDA, I2C1_SCL); // I2C bus, P3_4 = SDA, P3_5 = SCL
coreyharris 0:0bd4103885bf 64
johnGreeneMaxim 8:a1538e8a3fd9 65 DigitalOut VLED_EN(P3_3,0); //Enable for VLEDs
johnGreeneMaxim 8:a1538e8a3fd9 66 pmic_config(i2cBus, VLED_EN);
johnGreeneMaxim 8:a1538e8a3fd9 67
coreyharris 4:14d1b87cd3c4 68 MAX30101 op_sensor(i2cBus); // Create new MAX30101 on i2cBus
coreyharris 4:14d1b87cd3c4 69 int rc = op_sensor_config(op_sensor); // Config sensor, return 0 on success
coreyharris 0:0bd4103885bf 70
coreyharris 5:2f708191f1bd 71 MAX30101::InterruptBitField_u ints; // Read interrupt status to clear
coreyharris 5:2f708191f1bd 72 rc = op_sensor.getInterruptStatus(ints); // power on interrupt
coreyharris 5:2f708191f1bd 73
coreyharris 0:0bd4103885bf 74 uint8_t fifoData[MAX30101::MAX_FIFO_BYTES];
coreyharris 0:0bd4103885bf 75 uint16_t idx, readBytes;
coreyharris 7:6075af57668e 76 int32_t opSample;
coreyharris 2:54182d6a168f 77 uint32_t sample;
coreyharris 0:0bd4103885bf 78 while(1) {
coreyharris 2:54182d6a168f 79
coreyharris 1:471e2b722d24 80 if( rc == 0 ) {
coreyharris 4:14d1b87cd3c4 81
coreyharris 4:14d1b87cd3c4 82 // Check if op_sensor interrupt asserted
coreyharris 1:471e2b722d24 83 if(op_sensorIntFlag) {
coreyharris 4:14d1b87cd3c4 84
coreyharris 1:471e2b722d24 85 op_sensorIntFlag = 0; // Lower interrupt flag
coreyharris 4:14d1b87cd3c4 86 rc = op_sensor.getInterruptStatus(ints); // Read interrupt status
coreyharris 0:0bd4103885bf 87
coreyharris 4:14d1b87cd3c4 88 // Check if FIFO almost full interrupt asserted
coreyharris 1:471e2b722d24 89 if((rc == 0) && (ints.bits.a_full)) {
coreyharris 4:14d1b87cd3c4 90
coreyharris 4:14d1b87cd3c4 91 // Read FIFO
coreyharris 4:14d1b87cd3c4 92 rc = op_sensor.readFIFO(MAX30101::OneLedChannel, fifoData, readBytes);
coreyharris 0:0bd4103885bf 93
coreyharris 1:471e2b722d24 94 if(rc == 0) {
coreyharris 4:14d1b87cd3c4 95
coreyharris 4:14d1b87cd3c4 96 // Convert read bytes into samples
coreyharris 2:54182d6a168f 97 for(idx = 0; idx < readBytes; idx+=3) {
coreyharris 2:54182d6a168f 98 sample = (fifoData[idx]<<16) | (fifoData[idx+1]<<8) | (fifoData[idx+2]);
coreyharris 7:6075af57668e 99 opSample = sample << 14; // Sign extends sample
coreyharris 7:6075af57668e 100 opSample = opSample >> 14;
coreyharris 5:2f708191f1bd 101 pc.printf("%i\r\n", opSample); // Print results
coreyharris 0:0bd4103885bf 102 }
coreyharris 4:14d1b87cd3c4 103
coreyharris 0:0bd4103885bf 104 }
coreyharris 0:0bd4103885bf 105 }
coreyharris 0:0bd4103885bf 106 }
coreyharris 3:a580414c44ce 107
coreyharris 5:2f708191f1bd 108 // If rc != 0, a communication error has occurred
coreyharris 3:a580414c44ce 109 } else {
coreyharris 0:0bd4103885bf 110
coreyharris 4:14d1b87cd3c4 111 pc.printf("Something went wrong, "
coreyharris 4:14d1b87cd3c4 112 "check the I2C bus or power connections... \r\n");
coreyharris 0:0bd4103885bf 113 bLed = LED_OFF;
coreyharris 0:0bd4103885bf 114 gLed = LED_OFF;
coreyharris 0:0bd4103885bf 115
coreyharris 0:0bd4103885bf 116 while(1)
coreyharris 0:0bd4103885bf 117 {
coreyharris 0:0bd4103885bf 118 rLed = !rLed;
coreyharris 0:0bd4103885bf 119 wait(0.5);
coreyharris 3:a580414c44ce 120 }
coreyharris 3:a580414c44ce 121 }
coreyharris 0:0bd4103885bf 122
coreyharris 3:a580414c44ce 123 }
coreyharris 0:0bd4103885bf 124 }
coreyharris 0:0bd4103885bf 125
coreyharris 0:0bd4103885bf 126
coreyharris 0:0bd4103885bf 127 bool op_sensor_config(MAX30101 &op_sensor) {
coreyharris 0:0bd4103885bf 128
coreyharris 0:0bd4103885bf 129 //Reset Device
coreyharris 0:0bd4103885bf 130 MAX30101::ModeConfiguration_u modeConfig;
coreyharris 0:0bd4103885bf 131 modeConfig.all = 0;
coreyharris 0:0bd4103885bf 132 modeConfig.bits.reset = 1;
coreyharris 0:0bd4103885bf 133 int32_t rc = op_sensor.setModeConfiguration(modeConfig);
coreyharris 0:0bd4103885bf 134
coreyharris 0:0bd4103885bf 135
coreyharris 0:0bd4103885bf 136 //enable MAX30101 interrupts
coreyharris 0:0bd4103885bf 137 MAX30101::InterruptBitField_u ints;
coreyharris 0:0bd4103885bf 138 if(rc == 0)
coreyharris 0:0bd4103885bf 139 {
coreyharris 0:0bd4103885bf 140 ints.all = 0;
coreyharris 1:471e2b722d24 141 ints.bits.die_temp = 1; // Enable FIFO almost full interrupt
coreyharris 1:471e2b722d24 142 ints.bits.a_full = 1; // Enable internal die temp. interrupt
coreyharris 0:0bd4103885bf 143 rc = op_sensor.enableInterrupts(ints);
coreyharris 0:0bd4103885bf 144 }
coreyharris 0:0bd4103885bf 145
coreyharris 0:0bd4103885bf 146 //configure FIFO
coreyharris 0:0bd4103885bf 147 MAX30101::FIFO_Configuration_u fifoConfig;
coreyharris 0:0bd4103885bf 148 if(rc == 0)
coreyharris 0:0bd4103885bf 149 {
coreyharris 0:0bd4103885bf 150 fifoConfig.all = 0;
coreyharris 5:2f708191f1bd 151 fifoConfig.bits.fifo_a_full = 15; // Max level of 15 samples
coreyharris 5:2f708191f1bd 152 fifoConfig.bits.sample_average = MAX30101::AveragedSamples_8; // Average 8 samples
coreyharris 0:0bd4103885bf 153 rc = op_sensor.setFIFOConfiguration(fifoConfig);
coreyharris 0:0bd4103885bf 154 }
coreyharris 0:0bd4103885bf 155
coreyharris 0:0bd4103885bf 156 MAX30101::SpO2Configuration_u spo2Config;
coreyharris 0:0bd4103885bf 157 if(rc == 0)
coreyharris 0:0bd4103885bf 158 {
coreyharris 1:471e2b722d24 159 spo2Config.all = 0;
coreyharris 7:6075af57668e 160 spo2Config.bits.spo2_sr = MAX30101::SR_3200_Hz; // SpO2 SR = 1600Hz
coreyharris 7:6075af57668e 161 spo2Config.bits.led_pw = MAX30101::PW_3; // 18-bit ADC resolution
coreyharris 0:0bd4103885bf 162 rc = op_sensor.setSpO2Configuration(spo2Config);
coreyharris 0:0bd4103885bf 163 }
coreyharris 0:0bd4103885bf 164
coreyharris 0:0bd4103885bf 165 //Set LED1 drive current
coreyharris 0:0bd4103885bf 166 if(rc == 0)
coreyharris 0:0bd4103885bf 167 {
coreyharris 5:2f708191f1bd 168 // Heart Rate only, 1 LED channel, Pulse amp. = 0x1F
coreyharris 2:54182d6a168f 169 rc = op_sensor.setLEDPulseAmplitude(MAX30101::LED1_PA, 0x1F);
coreyharris 0:0bd4103885bf 170 }
coreyharris 0:0bd4103885bf 171
coreyharris 0:0bd4103885bf 172 //Set operating mode
coreyharris 0:0bd4103885bf 173 modeConfig.all = 0;
coreyharris 0:0bd4103885bf 174 if(rc == 0)
coreyharris 0:0bd4103885bf 175 {
coreyharris 1:471e2b722d24 176 modeConfig.bits.mode = MAX30101::HeartRateMode; // Heart-rate only
coreyharris 0:0bd4103885bf 177 rc = op_sensor.setModeConfiguration(modeConfig);
coreyharris 0:0bd4103885bf 178 }
coreyharris 0:0bd4103885bf 179
coreyharris 0:0bd4103885bf 180
coreyharris 0:0bd4103885bf 181 return rc;
coreyharris 0:0bd4103885bf 182 }
johnGreeneMaxim 8:a1538e8a3fd9 183
johnGreeneMaxim 8:a1538e8a3fd9 184 void pmic_config(I2C & i2c_bus, DigitalOut & pmic_en)
johnGreeneMaxim 8:a1538e8a3fd9 185 {
johnGreeneMaxim 8:a1538e8a3fd9 186
johnGreeneMaxim 8:a1538e8a3fd9 187 const uint8_t PMIC_ADRS = 0x54;
johnGreeneMaxim 8:a1538e8a3fd9 188 const uint8_t BBB_EXTRA_ADRS = 0x1C;
johnGreeneMaxim 8:a1538e8a3fd9 189 const uint8_t BOOST_VOLTAGE = 0x05;
johnGreeneMaxim 8:a1538e8a3fd9 190
johnGreeneMaxim 8:a1538e8a3fd9 191 char data_buff[] = {BBB_EXTRA_ADRS, 0x40}; //BBBExtra register address
johnGreeneMaxim 8:a1538e8a3fd9 192 //and data to enable passive
johnGreeneMaxim 8:a1538e8a3fd9 193 //pull down.
johnGreeneMaxim 8:a1538e8a3fd9 194 i2c_bus.write(PMIC_ADRS, data_buff,2); //write to BBBExtra register
johnGreeneMaxim 8:a1538e8a3fd9 195
johnGreeneMaxim 8:a1538e8a3fd9 196 data_buff[0] = BOOST_VOLTAGE;
johnGreeneMaxim 8:a1538e8a3fd9 197 data_buff[1] = 0x14; //Boost voltage configuration
johnGreeneMaxim 8:a1538e8a3fd9 198 //register followed by data
johnGreeneMaxim 8:a1538e8a3fd9 199 //to set voltage to 4.5V
johnGreeneMaxim 8:a1538e8a3fd9 200 pmic_en = 0; //disables VLED
johnGreeneMaxim 8:a1538e8a3fd9 201 i2c_bus.write(PMIC_ADRS, data_buff,2); //write to BBBExtra register
johnGreeneMaxim 8:a1538e8a3fd9 202 pmic_en = 1; //enables VLED
johnGreeneMaxim 8:a1538e8a3fd9 203 }