Driver, C++ source code, and library for the MAX30101 heart rate sensor chip. The MAX30101 IC includes integrated LEDs and photodetectors for the collection of raw data for Heart Rate/Pulse Rate monitoring and for SpO2 (blood oxygen saturation) levels.

Dependents:   MAX30101_Heart_Rate_Sp02_Sensor_Chip MAX30101_Heart_Rate_Sp02_SENSOR_Hello_World

Committer:
phonemacro
Date:
Sat Jul 21 07:30:15 2018 +0000
Revision:
0:b0addee6d8d1
convert to library from folder

Who changed what in which revision?

UserRevisionLine numberNew contents of line
phonemacro 0:b0addee6d8d1 1 /*******************************************************************************
phonemacro 0:b0addee6d8d1 2 * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved.
phonemacro 0:b0addee6d8d1 3 *
phonemacro 0:b0addee6d8d1 4 * Permission is hereby granted, free of charge, to any person obtaining a
phonemacro 0:b0addee6d8d1 5 * copy of this software and associated documentation files (the "Software"),
phonemacro 0:b0addee6d8d1 6 * to deal in the Software without restriction, including without limitation
phonemacro 0:b0addee6d8d1 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
phonemacro 0:b0addee6d8d1 8 * and/or sell copies of the Software, and to permit persons to whom the
phonemacro 0:b0addee6d8d1 9 * Software is furnished to do so, subject to the following conditions:
phonemacro 0:b0addee6d8d1 10 *
phonemacro 0:b0addee6d8d1 11 * The above copyright notice and this permission notice shall be included
phonemacro 0:b0addee6d8d1 12 * in all copies or substantial portions of the Software.
phonemacro 0:b0addee6d8d1 13 *
phonemacro 0:b0addee6d8d1 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
phonemacro 0:b0addee6d8d1 15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
phonemacro 0:b0addee6d8d1 16 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
phonemacro 0:b0addee6d8d1 17 * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
phonemacro 0:b0addee6d8d1 18 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
phonemacro 0:b0addee6d8d1 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
phonemacro 0:b0addee6d8d1 20 * OTHER DEALINGS IN THE SOFTWARE.
phonemacro 0:b0addee6d8d1 21 *
phonemacro 0:b0addee6d8d1 22 * Except as contained in this notice, the name of Maxim Integrated
phonemacro 0:b0addee6d8d1 23 * Products, Inc. shall not be used except as stated in the Maxim Integrated
phonemacro 0:b0addee6d8d1 24 * Products, Inc. Branding Policy.
phonemacro 0:b0addee6d8d1 25 *
phonemacro 0:b0addee6d8d1 26 * The mere transfer of this software does not imply any licenses
phonemacro 0:b0addee6d8d1 27 * of trade secrets, proprietary technology, copyrights, patents,
phonemacro 0:b0addee6d8d1 28 * trademarks, maskwork rights, or any other form of intellectual
phonemacro 0:b0addee6d8d1 29 * property whatsoever. Maxim Integrated Products, Inc. retains all
phonemacro 0:b0addee6d8d1 30 * ownership rights.
phonemacro 0:b0addee6d8d1 31 *******************************************************************************
phonemacro 0:b0addee6d8d1 32 */
phonemacro 0:b0addee6d8d1 33
phonemacro 0:b0addee6d8d1 34 #include "mbed.h"
phonemacro 0:b0addee6d8d1 35 #include "MAX30101.h"
phonemacro 0:b0addee6d8d1 36
phonemacro 0:b0addee6d8d1 37 MAX30101 *MAX30101::instance = NULL;
phonemacro 0:b0addee6d8d1 38
phonemacro 0:b0addee6d8d1 39 //******************************************************************************
phonemacro 0:b0addee6d8d1 40 MAX30101::MAX30101(PinName sda, PinName scl, int slaveAddress):
phonemacro 0:b0addee6d8d1 41 slaveAddress(slaveAddress) {
phonemacro 0:b0addee6d8d1 42 i2c = new I2C(sda, scl);
phonemacro 0:b0addee6d8d1 43 i2c_owner = true;
phonemacro 0:b0addee6d8d1 44 i2c->frequency(400000);
phonemacro 0:b0addee6d8d1 45 onInterruptCallback = NULL;
phonemacro 0:b0addee6d8d1 46 onDataAvailableCallback = NULL;
phonemacro 0:b0addee6d8d1 47 instance = this;
phonemacro 0:b0addee6d8d1 48 }
phonemacro 0:b0addee6d8d1 49
phonemacro 0:b0addee6d8d1 50 //******************************************************************************
phonemacro 0:b0addee6d8d1 51 MAX30101::MAX30101(I2C *_i2c, int slaveAddress) :
phonemacro 0:b0addee6d8d1 52 slaveAddress(slaveAddress) {
phonemacro 0:b0addee6d8d1 53 i2c = _i2c;
phonemacro 0:b0addee6d8d1 54 i2c_owner = false;
phonemacro 0:b0addee6d8d1 55 i2c->frequency(400000);
phonemacro 0:b0addee6d8d1 56 onInterruptCallback = NULL;
phonemacro 0:b0addee6d8d1 57 onDataAvailableCallback = NULL;
phonemacro 0:b0addee6d8d1 58 instance = this;
phonemacro 0:b0addee6d8d1 59 }
phonemacro 0:b0addee6d8d1 60
phonemacro 0:b0addee6d8d1 61 //******************************************************************************
phonemacro 0:b0addee6d8d1 62 MAX30101::~MAX30101(void) {
phonemacro 0:b0addee6d8d1 63 if (i2c_owner) {
phonemacro 0:b0addee6d8d1 64 delete i2c;
phonemacro 0:b0addee6d8d1 65 }
phonemacro 0:b0addee6d8d1 66 }
phonemacro 0:b0addee6d8d1 67
phonemacro 0:b0addee6d8d1 68 //******************************************************************************
phonemacro 0:b0addee6d8d1 69 int MAX30101::int_handler(void) {
phonemacro 0:b0addee6d8d1 70 uint16_t index, i;
phonemacro 0:b0addee6d8d1 71 uint16_t rx_bytes, second_rx_bytes;
phonemacro 0:b0addee6d8d1 72 char temp_int;
phonemacro 0:b0addee6d8d1 73 char temp_frac;
phonemacro 0:b0addee6d8d1 74 uint16_t num_active_led;
phonemacro 0:b0addee6d8d1 75 uint32_t sample;
phonemacro 0:b0addee6d8d1 76 int loop = 1;
phonemacro 0:b0addee6d8d1 77 static uint8_t cntr_int = 0;
phonemacro 0:b0addee6d8d1 78
phonemacro 0:b0addee6d8d1 79 max30101_Interrupt_Status_1_t Interrupt_Status_1;
phonemacro 0:b0addee6d8d1 80 max30101_Interrupt_Status_2_t Interrupt_Status_2;
phonemacro 0:b0addee6d8d1 81 max30101_mode_configuration_t mode_configuration;
phonemacro 0:b0addee6d8d1 82 max30101_multiLED_mode_ctrl_1_t multiLED_mode_ctrl_1;
phonemacro 0:b0addee6d8d1 83 max30101_multiLED_mode_ctrl_2_t multiLED_mode_ctrl_2;
phonemacro 0:b0addee6d8d1 84 max30101_spo2_configuration_t spo2_configuration;
phonemacro 0:b0addee6d8d1 85 max30101_fifo_configuration_t fifo_configuration;
phonemacro 0:b0addee6d8d1 86
phonemacro 0:b0addee6d8d1 87 cntr_int++;
phonemacro 0:b0addee6d8d1 88
phonemacro 0:b0addee6d8d1 89 while (loop) {
phonemacro 0:b0addee6d8d1 90 if (i2c_reg_read(REG_INT_STAT_1, &Interrupt_Status_1.all) != 0) { ///< Read Interrupt flag bits
phonemacro 0:b0addee6d8d1 91 return -1;
phonemacro 0:b0addee6d8d1 92 }
phonemacro 0:b0addee6d8d1 93
phonemacro 0:b0addee6d8d1 94 if (i2c_reg_read(REG_INT_STAT_2, &Interrupt_Status_2.all) != 0) { ///< Read Interrupt flag bits
phonemacro 0:b0addee6d8d1 95 return -1;
phonemacro 0:b0addee6d8d1 96 }
phonemacro 0:b0addee6d8d1 97
phonemacro 0:b0addee6d8d1 98 /* Read all the relevant register bits */
phonemacro 0:b0addee6d8d1 99 if (i2c_reg_read(REG_MODE_CFG, &mode_configuration.all) != 0) {
phonemacro 0:b0addee6d8d1 100 return -1;
phonemacro 0:b0addee6d8d1 101 }
phonemacro 0:b0addee6d8d1 102
phonemacro 0:b0addee6d8d1 103
phonemacro 0:b0addee6d8d1 104 if (i2c_reg_read(REG_SLT2_SLT1, &multiLED_mode_ctrl_1.all) != 0) {
phonemacro 0:b0addee6d8d1 105 return -1;
phonemacro 0:b0addee6d8d1 106 }
phonemacro 0:b0addee6d8d1 107
phonemacro 0:b0addee6d8d1 108
phonemacro 0:b0addee6d8d1 109 if (i2c_reg_read(REG_SLT4_SLT3, &multiLED_mode_ctrl_2.all) != 0) {
phonemacro 0:b0addee6d8d1 110 return -1;
phonemacro 0:b0addee6d8d1 111 }
phonemacro 0:b0addee6d8d1 112
phonemacro 0:b0addee6d8d1 113
phonemacro 0:b0addee6d8d1 114 if (i2c_reg_read(REG_SPO2_CFG, &spo2_configuration.all) != 0) {
phonemacro 0:b0addee6d8d1 115 return -1;
phonemacro 0:b0addee6d8d1 116 }
phonemacro 0:b0addee6d8d1 117
phonemacro 0:b0addee6d8d1 118
phonemacro 0:b0addee6d8d1 119 if (i2c_reg_read(REG_FIFO_CFG, &fifo_configuration.all) != 0) {
phonemacro 0:b0addee6d8d1 120 return -1;
phonemacro 0:b0addee6d8d1 121 }
phonemacro 0:b0addee6d8d1 122
phonemacro 0:b0addee6d8d1 123
phonemacro 0:b0addee6d8d1 124
phonemacro 0:b0addee6d8d1 125 if (Interrupt_Status_1.bit.a_full) {
phonemacro 0:b0addee6d8d1 126 ///< Read the sample(s)
phonemacro 0:b0addee6d8d1 127 char reg = REG_FIFO_DATA;
phonemacro 0:b0addee6d8d1 128
phonemacro 0:b0addee6d8d1 129 num_active_led = 0;
phonemacro 0:b0addee6d8d1 130
phonemacro 0:b0addee6d8d1 131 if (mode_configuration.bit.mode == 0x02) {///< Heart Rate mode, i.e. 1 led
phonemacro 0:b0addee6d8d1 132 num_active_led = 1;
phonemacro 0:b0addee6d8d1 133 } else if (mode_configuration.bit.mode == 0x03) { ///< SpO2 mode, i.e. 2 led
phonemacro 0:b0addee6d8d1 134 num_active_led = 2;
phonemacro 0:b0addee6d8d1 135 } else if (mode_configuration.bit.mode == 0x07) { ///< Multi-LED mode, i.e. 1-4 led
phonemacro 0:b0addee6d8d1 136 if (multiLED_mode_ctrl_1.bit.slot1 != 0) {
phonemacro 0:b0addee6d8d1 137 num_active_led++;
phonemacro 0:b0addee6d8d1 138 }
phonemacro 0:b0addee6d8d1 139
phonemacro 0:b0addee6d8d1 140 if (multiLED_mode_ctrl_1.bit.slot2 != 0) {
phonemacro 0:b0addee6d8d1 141 num_active_led++;
phonemacro 0:b0addee6d8d1 142 }
phonemacro 0:b0addee6d8d1 143
phonemacro 0:b0addee6d8d1 144 if (multiLED_mode_ctrl_2.bit.slot3 != 0) {
phonemacro 0:b0addee6d8d1 145 num_active_led++;
phonemacro 0:b0addee6d8d1 146 }
phonemacro 0:b0addee6d8d1 147
phonemacro 0:b0addee6d8d1 148 if (multiLED_mode_ctrl_2.bit.slot4 != 0) {
phonemacro 0:b0addee6d8d1 149 num_active_led++;
phonemacro 0:b0addee6d8d1 150 }
phonemacro 0:b0addee6d8d1 151 }
phonemacro 0:b0addee6d8d1 152 ///< 3bytes/LED x Number of Active LED x FIFO level selected
phonemacro 0:b0addee6d8d1 153 rx_bytes = 3 * num_active_led * (32-fifo_configuration.bit.fifo_a_full);
phonemacro 0:b0addee6d8d1 154
phonemacro 0:b0addee6d8d1 155 second_rx_bytes = rx_bytes;
phonemacro 0:b0addee6d8d1 156
phonemacro 0:b0addee6d8d1 157 /**
phonemacro 0:b0addee6d8d1 158 * @brief:
phonemacro 0:b0addee6d8d1 159 * The FIFO Size is determined by the Sample size. The number of bytes
phonemacro 0:b0addee6d8d1 160 * in a Sample is dictated by number of LED's
phonemacro 0:b0addee6d8d1 161 *
phonemacro 0:b0addee6d8d1 162 * #LED Selected Bytes in "1" sample
phonemacro 0:b0addee6d8d1 163 * 1 3
phonemacro 0:b0addee6d8d1 164 * 2 6
phonemacro 0:b0addee6d8d1 165 * 3 9
phonemacro 0:b0addee6d8d1 166 * 4 12
phonemacro 0:b0addee6d8d1 167 *
phonemacro 0:b0addee6d8d1 168 * The I2C API function limits the number of bytes to read, to 256 (i.e.
phonemacro 0:b0addee6d8d1 169 * char). Therefore, when set for Multiple LED's and the FIFO
phonemacro 0:b0addee6d8d1 170 * size is set to 32. It would mean there is more than 256 bytes.
phonemacro 0:b0addee6d8d1 171 * In that case two I2C reads have to be made. However It is important
phonemacro 0:b0addee6d8d1 172 * to note that each "Sample" must be read completely and reading only
phonemacro 0:b0addee6d8d1 173 * partial number of bytes from a sample will result in erroneous data.
phonemacro 0:b0addee6d8d1 174 *
phonemacro 0:b0addee6d8d1 175 *
phonemacro 0:b0addee6d8d1 176 * For example:
phonemacro 0:b0addee6d8d1 177 * Num of LED selected = 3 and FIFO size is set to 32 (i.e. 0 value in
phonemacro 0:b0addee6d8d1 178 * register), then the number of bytes will be
phonemacro 0:b0addee6d8d1 179 * 3bytes/Led * 3led's * 32 = 288 bytes in all. Since there are
phonemacro 0:b0addee6d8d1 180 * 3 LED's each sample will contain (3 * 3) 9bytes.
phonemacro 0:b0addee6d8d1 181 * Therefore Sample 1 = 9bytes, Sample 2 = 18,... Sample 28 = 252.
phonemacro 0:b0addee6d8d1 182 * Therefore the first I2C read should be 252 bytes and the second
phonemacro 0:b0addee6d8d1 183 * read should be 288-252 = 36.
phonemacro 0:b0addee6d8d1 184 *
phonemacro 0:b0addee6d8d1 185 * It turns out that this size issue comes up only when number of LED
phonemacro 0:b0addee6d8d1 186 * selected is 3 or 4 and choosing 252bytes
phonemacro 0:b0addee6d8d1 187 * for the first I2C read would work for both Number of LED selection.
phonemacro 0:b0addee6d8d1 188 */
phonemacro 0:b0addee6d8d1 189
phonemacro 0:b0addee6d8d1 190 if (rx_bytes <= CHUNK_SIZE) {
phonemacro 0:b0addee6d8d1 191 I2CM_Read(slaveAddress, &reg, 1, &max30101_rawData[0],
phonemacro 0:b0addee6d8d1 192 (char)rx_bytes /*total_databytes_1*/);
phonemacro 0:b0addee6d8d1 193 } else {
phonemacro 0:b0addee6d8d1 194 I2CM_Read(slaveAddress, &reg, 1, &max30101_rawData[0], CHUNK_SIZE);
phonemacro 0:b0addee6d8d1 195
phonemacro 0:b0addee6d8d1 196 second_rx_bytes = second_rx_bytes - CHUNK_SIZE;
phonemacro 0:b0addee6d8d1 197 I2CM_Read(slaveAddress, &reg, 1, &max30101_rawData[CHUNK_SIZE],
phonemacro 0:b0addee6d8d1 198 (char)second_rx_bytes);
phonemacro 0:b0addee6d8d1 199 }
phonemacro 0:b0addee6d8d1 200
phonemacro 0:b0addee6d8d1 201 index = 0;
phonemacro 0:b0addee6d8d1 202
phonemacro 0:b0addee6d8d1 203 for (i = 0; i < rx_bytes; i += 3) {
phonemacro 0:b0addee6d8d1 204 sample = ((uint32_t)(max30101_rawData[i] & 0x03) << 16) | (max30101_rawData[i + 1] << 8) | max30101_rawData[i + 2];
phonemacro 0:b0addee6d8d1 205
phonemacro 0:b0addee6d8d1 206 ///< Right shift the data based on the LED_PW setting
phonemacro 0:b0addee6d8d1 207 sample = sample >> (3 - spo2_configuration.bit.led_pw); // 0=shift 3, 1=shift 2, 2=shift 1, 3=no shift
phonemacro 0:b0addee6d8d1 208
phonemacro 0:b0addee6d8d1 209 max30101_buffer[index++] = sample;
phonemacro 0:b0addee6d8d1 210 }
phonemacro 0:b0addee6d8d1 211
phonemacro 0:b0addee6d8d1 212 onDataAvailableCallback(MAX30101_OXIMETER_DATA + num_active_led, max30101_buffer, index);
phonemacro 0:b0addee6d8d1 213 }
phonemacro 0:b0addee6d8d1 214
phonemacro 0:b0addee6d8d1 215
phonemacro 0:b0addee6d8d1 216 ///< This interrupt handles the temperature interrupt
phonemacro 0:b0addee6d8d1 217 if (Interrupt_Status_2.bit.die_temp_rdy) {
phonemacro 0:b0addee6d8d1 218 char reg;
phonemacro 0:b0addee6d8d1 219
phonemacro 0:b0addee6d8d1 220 reg = REG_TINT;
phonemacro 0:b0addee6d8d1 221 if (I2CM_Read(slaveAddress, &reg, 1, &temp_int, 1) != 0) {
phonemacro 0:b0addee6d8d1 222 return -1;
phonemacro 0:b0addee6d8d1 223 }
phonemacro 0:b0addee6d8d1 224
phonemacro 0:b0addee6d8d1 225 reg = REG_TFRAC;
phonemacro 0:b0addee6d8d1 226 if (I2CM_Read(slaveAddress, &reg, 1, &temp_frac, 1) != 0) {
phonemacro 0:b0addee6d8d1 227 return -1;
phonemacro 0:b0addee6d8d1 228 }
phonemacro 0:b0addee6d8d1 229
phonemacro 0:b0addee6d8d1 230 max30101_final_temp = (int8_t)temp_int + 0.0625f * temp_frac;
phonemacro 0:b0addee6d8d1 231
phonemacro 0:b0addee6d8d1 232 if (i2c_reg_write(REG_TEMP_EN, 0x00) != 0) { ///< Die Temperature Config, Temp disable... after one read...
phonemacro 0:b0addee6d8d1 233 return -1;
phonemacro 0:b0addee6d8d1 234 }
phonemacro 0:b0addee6d8d1 235 }
phonemacro 0:b0addee6d8d1 236
phonemacro 0:b0addee6d8d1 237 if (i2c_reg_read(REG_INT_STAT_1, &Interrupt_Status_1.all) != 0) { ///< Read Interrupt flag bits
phonemacro 0:b0addee6d8d1 238
phonemacro 0:b0addee6d8d1 239 return -1;
phonemacro 0:b0addee6d8d1 240 }
phonemacro 0:b0addee6d8d1 241 if (Interrupt_Status_1.bit.a_full != 1) {
phonemacro 0:b0addee6d8d1 242 loop = 0;
phonemacro 0:b0addee6d8d1 243 }
phonemacro 0:b0addee6d8d1 244 }
phonemacro 0:b0addee6d8d1 245
phonemacro 0:b0addee6d8d1 246 interruptPostCallback();
phonemacro 0:b0addee6d8d1 247
phonemacro 0:b0addee6d8d1 248
phonemacro 0:b0addee6d8d1 249 return 0;
phonemacro 0:b0addee6d8d1 250 }
phonemacro 0:b0addee6d8d1 251
phonemacro 0:b0addee6d8d1 252 //******************************************************************************
phonemacro 0:b0addee6d8d1 253 int MAX30101::SpO2mode_init(uint8_t fifo_waterlevel_mark, uint8_t sample_avg,
phonemacro 0:b0addee6d8d1 254 uint8_t sample_rate, uint8_t pulse_width,
phonemacro 0:b0addee6d8d1 255 uint8_t red_led_current, uint8_t ir_led_current) {
phonemacro 0:b0addee6d8d1 256
phonemacro 0:b0addee6d8d1 257 char status;
phonemacro 0:b0addee6d8d1 258
phonemacro 0:b0addee6d8d1 259 max30101_mode_configuration_t mode_configuration;
phonemacro 0:b0addee6d8d1 260 max30101_fifo_configuration_t fifo_configuration;
phonemacro 0:b0addee6d8d1 261 max30101_spo2_configuration_t spo2_configuration;
phonemacro 0:b0addee6d8d1 262 max30101_Interrupt_Enable_1_t Interrupt_Enable_1;
phonemacro 0:b0addee6d8d1 263
phonemacro 0:b0addee6d8d1 264 mode_configuration.all = 0;
phonemacro 0:b0addee6d8d1 265 mode_configuration.bit.reset = 1;
phonemacro 0:b0addee6d8d1 266 if (i2c_reg_write(REG_MODE_CFG, mode_configuration.all) != 0) // Reset the device
phonemacro 0:b0addee6d8d1 267 {
phonemacro 0:b0addee6d8d1 268 return -1;
phonemacro 0:b0addee6d8d1 269 }
phonemacro 0:b0addee6d8d1 270
phonemacro 0:b0addee6d8d1 271 ///< Give it some settle time (100ms)
phonemacro 0:b0addee6d8d1 272 wait(1.0 / 10.0); ///< Let things settle down a bit
phonemacro 0:b0addee6d8d1 273
phonemacro 0:b0addee6d8d1 274 fifo_configuration.all = 0;
phonemacro 0:b0addee6d8d1 275 fifo_configuration.bit.smp_ave = sample_avg; ///< Sample averaging;
phonemacro 0:b0addee6d8d1 276 fifo_configuration.bit.fifo_roll_over_en = 1; ///< FIFO Roll over enabled
phonemacro 0:b0addee6d8d1 277 fifo_configuration.bit.fifo_a_full = fifo_waterlevel_mark; ///< Interrupt when certain level is filled
phonemacro 0:b0addee6d8d1 278
phonemacro 0:b0addee6d8d1 279 if (i2c_reg_write(REG_FIFO_CFG, fifo_configuration.all) != 0) {
phonemacro 0:b0addee6d8d1 280 return -1;
phonemacro 0:b0addee6d8d1 281 }
phonemacro 0:b0addee6d8d1 282
phonemacro 0:b0addee6d8d1 283 spo2_configuration.bit.spo2_adc_rge = 0x2; ///< ADC Range 8192 fullscale
phonemacro 0:b0addee6d8d1 284 spo2_configuration.bit.spo2_sr = sample_rate; ///< 100 Samp/sec.
phonemacro 0:b0addee6d8d1 285 spo2_configuration.bit.led_pw = pulse_width; ///< Pulse Width=411us and ADC Resolution=18
phonemacro 0:b0addee6d8d1 286 if (i2c_reg_write(REG_SPO2_CFG, spo2_configuration.all) != 0) {
phonemacro 0:b0addee6d8d1 287 return -1;
phonemacro 0:b0addee6d8d1 288 }
phonemacro 0:b0addee6d8d1 289
phonemacro 0:b0addee6d8d1 290 if (i2c_reg_write(REG_LED1_PA, red_led_current) != 0) {
phonemacro 0:b0addee6d8d1 291 return -1;
phonemacro 0:b0addee6d8d1 292 }
phonemacro 0:b0addee6d8d1 293
phonemacro 0:b0addee6d8d1 294 if (i2c_reg_write(REG_LED2_PA, ir_led_current) != 0) {
phonemacro 0:b0addee6d8d1 295 return -1;
phonemacro 0:b0addee6d8d1 296 }
phonemacro 0:b0addee6d8d1 297
phonemacro 0:b0addee6d8d1 298 /************/
phonemacro 0:b0addee6d8d1 299
phonemacro 0:b0addee6d8d1 300 if (i2c_reg_read(REG_INT_STAT_1, &status) != 0) ///< Clear INT1 by reading the status
phonemacro 0:b0addee6d8d1 301 {
phonemacro 0:b0addee6d8d1 302 return -1;
phonemacro 0:b0addee6d8d1 303 }
phonemacro 0:b0addee6d8d1 304
phonemacro 0:b0addee6d8d1 305 if (i2c_reg_read(REG_INT_STAT_2, &status) != 0) ///< Clear INT2 by reading the status
phonemacro 0:b0addee6d8d1 306 {
phonemacro 0:b0addee6d8d1 307 return -1;
phonemacro 0:b0addee6d8d1 308 }
phonemacro 0:b0addee6d8d1 309
phonemacro 0:b0addee6d8d1 310 if (i2c_reg_write(REG_FIFO_W_PTR, 0x00) != 0) ///< Clear FIFO ptr
phonemacro 0:b0addee6d8d1 311 {
phonemacro 0:b0addee6d8d1 312 return -1;
phonemacro 0:b0addee6d8d1 313 }
phonemacro 0:b0addee6d8d1 314
phonemacro 0:b0addee6d8d1 315 if (i2c_reg_write(REG_FIFO_OVF_CNT, 0x00) != 0) ///< Clear FIFO ptr
phonemacro 0:b0addee6d8d1 316 {
phonemacro 0:b0addee6d8d1 317 return -1;
phonemacro 0:b0addee6d8d1 318 }
phonemacro 0:b0addee6d8d1 319
phonemacro 0:b0addee6d8d1 320 if (i2c_reg_write(REG_FIFO_R_PTR, 0x00) != 0) ///< Clear FIFO ptr
phonemacro 0:b0addee6d8d1 321 {
phonemacro 0:b0addee6d8d1 322 return -1;
phonemacro 0:b0addee6d8d1 323 }
phonemacro 0:b0addee6d8d1 324
phonemacro 0:b0addee6d8d1 325 Interrupt_Enable_1.all = 0;
phonemacro 0:b0addee6d8d1 326 Interrupt_Enable_1.bit.a_full_en = 1; ///< Enable FIFO almost full interrupt
phonemacro 0:b0addee6d8d1 327 if (i2c_reg_write(REG_INT_EN_1, Interrupt_Enable_1.all) != 0) {
phonemacro 0:b0addee6d8d1 328 return -1;
phonemacro 0:b0addee6d8d1 329 }
phonemacro 0:b0addee6d8d1 330
phonemacro 0:b0addee6d8d1 331 mode_configuration.all = 0;
phonemacro 0:b0addee6d8d1 332 mode_configuration.bit.mode = 0x03; ///< SpO2 mode
phonemacro 0:b0addee6d8d1 333 if (i2c_reg_write(REG_MODE_CFG, mode_configuration.all) != 0) {
phonemacro 0:b0addee6d8d1 334 return -1;
phonemacro 0:b0addee6d8d1 335 }
phonemacro 0:b0addee6d8d1 336
phonemacro 0:b0addee6d8d1 337 return 0;
phonemacro 0:b0addee6d8d1 338 }
phonemacro 0:b0addee6d8d1 339
phonemacro 0:b0addee6d8d1 340 //******************************************************************************
phonemacro 0:b0addee6d8d1 341 int MAX30101::SpO2mode_stop(void) {
phonemacro 0:b0addee6d8d1 342
phonemacro 0:b0addee6d8d1 343 max30101_Interrupt_Enable_1_t Interrupt_Enable_1;
phonemacro 0:b0addee6d8d1 344 max30101_mode_configuration_t mode_configuration;
phonemacro 0:b0addee6d8d1 345 uint8_t led1_pa;
phonemacro 0:b0addee6d8d1 346 uint8_t led2_pa;
phonemacro 0:b0addee6d8d1 347
phonemacro 0:b0addee6d8d1 348 Interrupt_Enable_1.all = 0;
phonemacro 0:b0addee6d8d1 349 Interrupt_Enable_1.bit.a_full_en = 0; ///< Disable FIFO almost full interrupt
phonemacro 0:b0addee6d8d1 350 if (i2c_reg_write(REG_INT_EN_1, Interrupt_Enable_1.all) != 0) {
phonemacro 0:b0addee6d8d1 351 return -1;
phonemacro 0:b0addee6d8d1 352 }
phonemacro 0:b0addee6d8d1 353
phonemacro 0:b0addee6d8d1 354 mode_configuration.all = 0;
phonemacro 0:b0addee6d8d1 355 mode_configuration.bit.mode = 0x00; ///< SpO2 mode off
phonemacro 0:b0addee6d8d1 356 if (i2c_reg_write(REG_MODE_CFG, mode_configuration.all) != 0) {
phonemacro 0:b0addee6d8d1 357 return -1;
phonemacro 0:b0addee6d8d1 358 }
phonemacro 0:b0addee6d8d1 359
phonemacro 0:b0addee6d8d1 360 led1_pa = 0; ///< RED LED current, 0.0
phonemacro 0:b0addee6d8d1 361 if (i2c_reg_write(REG_LED1_PA, led1_pa) != 0) {
phonemacro 0:b0addee6d8d1 362 return -1;
phonemacro 0:b0addee6d8d1 363 }
phonemacro 0:b0addee6d8d1 364
phonemacro 0:b0addee6d8d1 365 led2_pa = 0; ///< IR LED current, 0.0
phonemacro 0:b0addee6d8d1 366 if (i2c_reg_write(REG_LED2_PA, led2_pa) != 0) {
phonemacro 0:b0addee6d8d1 367 return -1;
phonemacro 0:b0addee6d8d1 368 }
phonemacro 0:b0addee6d8d1 369
phonemacro 0:b0addee6d8d1 370 return 0;
phonemacro 0:b0addee6d8d1 371 }
phonemacro 0:b0addee6d8d1 372
phonemacro 0:b0addee6d8d1 373 //******************************************************************************
phonemacro 0:b0addee6d8d1 374 int MAX30101::HRmode_init(uint8_t fifo_waterlevel_mark, uint8_t sample_avg,
phonemacro 0:b0addee6d8d1 375 uint8_t sample_rate, uint8_t pulse_width,
phonemacro 0:b0addee6d8d1 376 uint8_t red_led_current) {
phonemacro 0:b0addee6d8d1 377
phonemacro 0:b0addee6d8d1 378 /*uint8_t*/ char status;
phonemacro 0:b0addee6d8d1 379
phonemacro 0:b0addee6d8d1 380 max30101_mode_configuration_t mode_configuration;
phonemacro 0:b0addee6d8d1 381 max30101_fifo_configuration_t fifo_configuration;
phonemacro 0:b0addee6d8d1 382 max30101_spo2_configuration_t spo2_configuration;
phonemacro 0:b0addee6d8d1 383 max30101_Interrupt_Enable_1_t Interrupt_Enable_1;
phonemacro 0:b0addee6d8d1 384
phonemacro 0:b0addee6d8d1 385 mode_configuration.all = 0;
phonemacro 0:b0addee6d8d1 386 mode_configuration.bit.reset = 1;
phonemacro 0:b0addee6d8d1 387 if (i2c_reg_write(REG_MODE_CFG, mode_configuration.all) != 0) ///< Reset the device, Mode = don't use...
phonemacro 0:b0addee6d8d1 388 {
phonemacro 0:b0addee6d8d1 389 return -1;
phonemacro 0:b0addee6d8d1 390 }
phonemacro 0:b0addee6d8d1 391
phonemacro 0:b0addee6d8d1 392 ///< Give it some settle time (100ms)
phonemacro 0:b0addee6d8d1 393 wait(1.0 / 10.0); ///< Let things settle down a bit
phonemacro 0:b0addee6d8d1 394
phonemacro 0:b0addee6d8d1 395 fifo_configuration.all = 0;
phonemacro 0:b0addee6d8d1 396 fifo_configuration.bit.smp_ave = sample_avg; ///< Sample averaging;
phonemacro 0:b0addee6d8d1 397 fifo_configuration.bit.fifo_roll_over_en = 1; ///< FIFO Roll over enabled
phonemacro 0:b0addee6d8d1 398 fifo_configuration.bit.fifo_a_full = fifo_waterlevel_mark; ///< Interrupt when certain level is filled
phonemacro 0:b0addee6d8d1 399 if (i2c_reg_write(REG_FIFO_CFG, fifo_configuration.all) != 0) {
phonemacro 0:b0addee6d8d1 400 return -1;
phonemacro 0:b0addee6d8d1 401 }
phonemacro 0:b0addee6d8d1 402
phonemacro 0:b0addee6d8d1 403 spo2_configuration.bit.spo2_adc_rge = 0x2; ///< ADC Range 8192 fullscale
phonemacro 0:b0addee6d8d1 404 spo2_configuration.bit.spo2_sr = sample_rate; ///< 100 Samp/sec.
phonemacro 0:b0addee6d8d1 405 spo2_configuration.bit.led_pw = pulse_width; ///< Pulse Width=411us and ADC Resolution=18
phonemacro 0:b0addee6d8d1 406 if (i2c_reg_write(REG_SPO2_CFG, spo2_configuration.all) != 0) {
phonemacro 0:b0addee6d8d1 407 return -1;
phonemacro 0:b0addee6d8d1 408 }
phonemacro 0:b0addee6d8d1 409
phonemacro 0:b0addee6d8d1 410 if (i2c_reg_write(REG_LED1_PA, red_led_current) != 0) {
phonemacro 0:b0addee6d8d1 411 return -1;
phonemacro 0:b0addee6d8d1 412 }
phonemacro 0:b0addee6d8d1 413
phonemacro 0:b0addee6d8d1 414 /************/
phonemacro 0:b0addee6d8d1 415
phonemacro 0:b0addee6d8d1 416 if (i2c_reg_read(REG_INT_STAT_1, &status) != 0) ///< Clear INT1 by reading the status
phonemacro 0:b0addee6d8d1 417 {
phonemacro 0:b0addee6d8d1 418 return -1;
phonemacro 0:b0addee6d8d1 419 }
phonemacro 0:b0addee6d8d1 420
phonemacro 0:b0addee6d8d1 421 if (i2c_reg_read(REG_INT_STAT_2, &status) != 0) ///< Clear INT2 by reading the status
phonemacro 0:b0addee6d8d1 422 {
phonemacro 0:b0addee6d8d1 423 return -1;
phonemacro 0:b0addee6d8d1 424 }
phonemacro 0:b0addee6d8d1 425
phonemacro 0:b0addee6d8d1 426 if (i2c_reg_write(REG_FIFO_W_PTR, 0x00) != 0) ///< Clear FIFO ptr
phonemacro 0:b0addee6d8d1 427 {
phonemacro 0:b0addee6d8d1 428 return -1;
phonemacro 0:b0addee6d8d1 429 }
phonemacro 0:b0addee6d8d1 430
phonemacro 0:b0addee6d8d1 431 if (i2c_reg_write(REG_FIFO_OVF_CNT, 0x00) != 0) ///< Clear FIFO ptr
phonemacro 0:b0addee6d8d1 432 {
phonemacro 0:b0addee6d8d1 433 return -1;
phonemacro 0:b0addee6d8d1 434 }
phonemacro 0:b0addee6d8d1 435
phonemacro 0:b0addee6d8d1 436 if (i2c_reg_write(REG_FIFO_R_PTR, 0x00) != 0) ///< Clear FIFO ptr
phonemacro 0:b0addee6d8d1 437 {
phonemacro 0:b0addee6d8d1 438 return -1;
phonemacro 0:b0addee6d8d1 439 }
phonemacro 0:b0addee6d8d1 440
phonemacro 0:b0addee6d8d1 441 Interrupt_Enable_1.all = 0;
phonemacro 0:b0addee6d8d1 442 Interrupt_Enable_1.bit.a_full_en = 1;
phonemacro 0:b0addee6d8d1 443
phonemacro 0:b0addee6d8d1 444 // Interrupt
phonemacro 0:b0addee6d8d1 445 if (i2c_reg_write(REG_INT_EN_1, Interrupt_Enable_1.all) != 0) {
phonemacro 0:b0addee6d8d1 446 return -1;
phonemacro 0:b0addee6d8d1 447 }
phonemacro 0:b0addee6d8d1 448
phonemacro 0:b0addee6d8d1 449 mode_configuration.all = 0;
phonemacro 0:b0addee6d8d1 450 mode_configuration.bit.mode = 0x02; ///< HR mode
phonemacro 0:b0addee6d8d1 451 if (i2c_reg_write(REG_MODE_CFG, mode_configuration.all) != 0) {
phonemacro 0:b0addee6d8d1 452 return -1;
phonemacro 0:b0addee6d8d1 453 }
phonemacro 0:b0addee6d8d1 454
phonemacro 0:b0addee6d8d1 455 return 0;
phonemacro 0:b0addee6d8d1 456 }
phonemacro 0:b0addee6d8d1 457
phonemacro 0:b0addee6d8d1 458 //******************************************************************************
phonemacro 0:b0addee6d8d1 459 int MAX30101::HRmode_stop(void) {
phonemacro 0:b0addee6d8d1 460
phonemacro 0:b0addee6d8d1 461 max30101_Interrupt_Enable_1_t Interrupt_Enable_1;
phonemacro 0:b0addee6d8d1 462 max30101_mode_configuration_t mode_configuration;
phonemacro 0:b0addee6d8d1 463
phonemacro 0:b0addee6d8d1 464 Interrupt_Enable_1.all = 0;
phonemacro 0:b0addee6d8d1 465 Interrupt_Enable_1.bit.a_full_en = 0; ///< Disable FIFO almost full interrupt
phonemacro 0:b0addee6d8d1 466 if (i2c_reg_write(REG_INT_EN_1, Interrupt_Enable_1.all) != 0) {
phonemacro 0:b0addee6d8d1 467 return -1;
phonemacro 0:b0addee6d8d1 468 }
phonemacro 0:b0addee6d8d1 469
phonemacro 0:b0addee6d8d1 470 mode_configuration.all = 0;
phonemacro 0:b0addee6d8d1 471 mode_configuration.bit.mode = 0x00; ///< HR mode off
phonemacro 0:b0addee6d8d1 472 if (i2c_reg_write(REG_MODE_CFG, mode_configuration.all) != 0) {
phonemacro 0:b0addee6d8d1 473 return -1;
phonemacro 0:b0addee6d8d1 474 }
phonemacro 0:b0addee6d8d1 475
phonemacro 0:b0addee6d8d1 476 if (i2c_reg_write(REG_LED1_PA, 0) != 0) {
phonemacro 0:b0addee6d8d1 477 return -1;
phonemacro 0:b0addee6d8d1 478 }
phonemacro 0:b0addee6d8d1 479
phonemacro 0:b0addee6d8d1 480 return 0;
phonemacro 0:b0addee6d8d1 481 }
phonemacro 0:b0addee6d8d1 482
phonemacro 0:b0addee6d8d1 483 //******************************************************************************
phonemacro 0:b0addee6d8d1 484 int MAX30101::Multimode_init(uint8_t fifo_waterlevel_mark, uint8_t sample_avg,
phonemacro 0:b0addee6d8d1 485 uint8_t sample_rate, uint8_t pulse_width,
phonemacro 0:b0addee6d8d1 486 uint8_t red_led_current, uint8_t ir_led_current,
phonemacro 0:b0addee6d8d1 487 uint8_t green_led_current, uint8_t slot_1,
phonemacro 0:b0addee6d8d1 488 uint8_t slot_2, uint8_t slot_3, uint8_t slot_4) {
phonemacro 0:b0addee6d8d1 489
phonemacro 0:b0addee6d8d1 490 char status;
phonemacro 0:b0addee6d8d1 491 max30101_mode_configuration_t mode_configuration;
phonemacro 0:b0addee6d8d1 492 max30101_fifo_configuration_t fifo_configuration;
phonemacro 0:b0addee6d8d1 493 max30101_spo2_configuration_t spo2_configuration;
phonemacro 0:b0addee6d8d1 494 max30101_multiLED_mode_ctrl_1_t multiLED_mode_ctrl_1;
phonemacro 0:b0addee6d8d1 495 max30101_multiLED_mode_ctrl_2_t multiLED_mode_ctrl_2;
phonemacro 0:b0addee6d8d1 496 max30101_Interrupt_Enable_1_t Interrupt_Enable_1;
phonemacro 0:b0addee6d8d1 497
phonemacro 0:b0addee6d8d1 498 mode_configuration.all = 0;
phonemacro 0:b0addee6d8d1 499 mode_configuration.bit.reset = 1;
phonemacro 0:b0addee6d8d1 500 if (i2c_reg_write(REG_MODE_CFG, mode_configuration.all) != 0) ///< Reset the device, Mode = don't use...
phonemacro 0:b0addee6d8d1 501 {
phonemacro 0:b0addee6d8d1 502 return -1;
phonemacro 0:b0addee6d8d1 503 }
phonemacro 0:b0addee6d8d1 504
phonemacro 0:b0addee6d8d1 505 /* Give it some settle time (100ms) */ ///< Let things settle down a bit
phonemacro 0:b0addee6d8d1 506 wait(1.0 / 10.0);
phonemacro 0:b0addee6d8d1 507
phonemacro 0:b0addee6d8d1 508 fifo_configuration.all = 0;
phonemacro 0:b0addee6d8d1 509 fifo_configuration.bit.smp_ave = sample_avg; ///< Sample averaging;
phonemacro 0:b0addee6d8d1 510 fifo_configuration.bit.fifo_roll_over_en = 1; ///< FIFO Roll over enabled
phonemacro 0:b0addee6d8d1 511 fifo_configuration.bit.fifo_a_full =
phonemacro 0:b0addee6d8d1 512 fifo_waterlevel_mark; ///< Interrupt when certain level is filled
phonemacro 0:b0addee6d8d1 513 if (i2c_reg_write(REG_FIFO_CFG, fifo_configuration.all) != 0) {
phonemacro 0:b0addee6d8d1 514 return -1;
phonemacro 0:b0addee6d8d1 515 }
phonemacro 0:b0addee6d8d1 516
phonemacro 0:b0addee6d8d1 517 spo2_configuration.bit.spo2_adc_rge = 0x2; ///< ADC Range 8192 fullscale
phonemacro 0:b0addee6d8d1 518 spo2_configuration.bit.spo2_sr = sample_rate; ///< 100 Samp/sec.
phonemacro 0:b0addee6d8d1 519 spo2_configuration.bit.led_pw = pulse_width; ///< Pulse Width=411us and ADC Resolution=18
phonemacro 0:b0addee6d8d1 520 if (i2c_reg_write(REG_SPO2_CFG, spo2_configuration.all) != 0) {
phonemacro 0:b0addee6d8d1 521 return -1;
phonemacro 0:b0addee6d8d1 522 }
phonemacro 0:b0addee6d8d1 523
phonemacro 0:b0addee6d8d1 524 if (i2c_reg_write(REG_LED1_PA, red_led_current) != 0) {
phonemacro 0:b0addee6d8d1 525 return -1;
phonemacro 0:b0addee6d8d1 526 }
phonemacro 0:b0addee6d8d1 527
phonemacro 0:b0addee6d8d1 528 if (i2c_reg_write(REG_LED2_PA, ir_led_current) != 0) {
phonemacro 0:b0addee6d8d1 529 return -1;
phonemacro 0:b0addee6d8d1 530 }
phonemacro 0:b0addee6d8d1 531
phonemacro 0:b0addee6d8d1 532 if (i2c_reg_write(REG_LED3_PA, green_led_current) != 0) {
phonemacro 0:b0addee6d8d1 533 return -1;
phonemacro 0:b0addee6d8d1 534 }
phonemacro 0:b0addee6d8d1 535
phonemacro 0:b0addee6d8d1 536 ///< 0x01=Red(LED1), 0x02=IR(LED2), 0x03=Green(LED3) : Use LEDn_PA to adjust the intensity
phonemacro 0:b0addee6d8d1 537 ///< 0x05=Red , 0x06=IR , 0x07=Green : Use PILOT_PA to adjust the intensity DO NOT USE THIS ROW...
phonemacro 0:b0addee6d8d1 538
phonemacro 0:b0addee6d8d1 539 multiLED_mode_ctrl_1.bit.slot1 = slot_1;
phonemacro 0:b0addee6d8d1 540 multiLED_mode_ctrl_1.bit.slot2 = slot_2;
phonemacro 0:b0addee6d8d1 541 if (i2c_reg_write(REG_SLT2_SLT1, multiLED_mode_ctrl_1.all)) {
phonemacro 0:b0addee6d8d1 542 return -1;
phonemacro 0:b0addee6d8d1 543 }
phonemacro 0:b0addee6d8d1 544
phonemacro 0:b0addee6d8d1 545 multiLED_mode_ctrl_2.all = 0;
phonemacro 0:b0addee6d8d1 546 multiLED_mode_ctrl_2.bit.slot3 = slot_3;
phonemacro 0:b0addee6d8d1 547 multiLED_mode_ctrl_2.bit.slot4 = slot_4;
phonemacro 0:b0addee6d8d1 548 if (i2c_reg_write(REG_SLT4_SLT3, multiLED_mode_ctrl_2.all)) {
phonemacro 0:b0addee6d8d1 549 return -1;
phonemacro 0:b0addee6d8d1 550 }
phonemacro 0:b0addee6d8d1 551
phonemacro 0:b0addee6d8d1 552 /************/
phonemacro 0:b0addee6d8d1 553
phonemacro 0:b0addee6d8d1 554 if (i2c_reg_read(REG_INT_STAT_1, &status) != 0) ///< Clear INT1 by reading the status
phonemacro 0:b0addee6d8d1 555 {
phonemacro 0:b0addee6d8d1 556 return -1;
phonemacro 0:b0addee6d8d1 557 }
phonemacro 0:b0addee6d8d1 558
phonemacro 0:b0addee6d8d1 559 if (i2c_reg_read(REG_INT_STAT_2, &status) != 0) ///< Clear INT2 by reading the status
phonemacro 0:b0addee6d8d1 560 {
phonemacro 0:b0addee6d8d1 561 return -1;
phonemacro 0:b0addee6d8d1 562 }
phonemacro 0:b0addee6d8d1 563
phonemacro 0:b0addee6d8d1 564 if (i2c_reg_write(REG_FIFO_W_PTR, 0x00) != 0) ///< Clear FIFO ptr
phonemacro 0:b0addee6d8d1 565 {
phonemacro 0:b0addee6d8d1 566 return -1;
phonemacro 0:b0addee6d8d1 567 }
phonemacro 0:b0addee6d8d1 568
phonemacro 0:b0addee6d8d1 569 if (i2c_reg_write(REG_FIFO_OVF_CNT, 0x00) != 0) ///< Clear FIFO ptr
phonemacro 0:b0addee6d8d1 570 {
phonemacro 0:b0addee6d8d1 571 return -1;
phonemacro 0:b0addee6d8d1 572 }
phonemacro 0:b0addee6d8d1 573
phonemacro 0:b0addee6d8d1 574 if (i2c_reg_write(REG_FIFO_R_PTR, 0x00) != 0) ///< Clear FIFO ptr
phonemacro 0:b0addee6d8d1 575 {
phonemacro 0:b0addee6d8d1 576 return -1;
phonemacro 0:b0addee6d8d1 577 }
phonemacro 0:b0addee6d8d1 578
phonemacro 0:b0addee6d8d1 579 Interrupt_Enable_1.all = 0;
phonemacro 0:b0addee6d8d1 580 Interrupt_Enable_1.bit.a_full_en = 1; ///< Enable FIFO almost full interrupt
phonemacro 0:b0addee6d8d1 581 if (i2c_reg_write(REG_INT_EN_1, Interrupt_Enable_1.all) != 0) {
phonemacro 0:b0addee6d8d1 582 return -1;
phonemacro 0:b0addee6d8d1 583 }
phonemacro 0:b0addee6d8d1 584
phonemacro 0:b0addee6d8d1 585 mode_configuration.all = 0;
phonemacro 0:b0addee6d8d1 586 mode_configuration.bit.mode = 0x07; ///< Multi-LED mode
phonemacro 0:b0addee6d8d1 587 if (i2c_reg_write(REG_MODE_CFG, mode_configuration.all) != 0) {
phonemacro 0:b0addee6d8d1 588 return -1;
phonemacro 0:b0addee6d8d1 589 }
phonemacro 0:b0addee6d8d1 590
phonemacro 0:b0addee6d8d1 591 return 0;
phonemacro 0:b0addee6d8d1 592 }
phonemacro 0:b0addee6d8d1 593
phonemacro 0:b0addee6d8d1 594 //******************************************************************************
phonemacro 0:b0addee6d8d1 595 int MAX30101::Multimode_stop(void) {
phonemacro 0:b0addee6d8d1 596
phonemacro 0:b0addee6d8d1 597 max30101_Interrupt_Enable_1_t Interrupt_Enable_1;
phonemacro 0:b0addee6d8d1 598 max30101_mode_configuration_t mode_configuration;
phonemacro 0:b0addee6d8d1 599
phonemacro 0:b0addee6d8d1 600
phonemacro 0:b0addee6d8d1 601 Interrupt_Enable_1.all = 0;
phonemacro 0:b0addee6d8d1 602 Interrupt_Enable_1.bit.a_full_en = 0; ///< Disable FIFO almost full interrupt
phonemacro 0:b0addee6d8d1 603 if (i2c_reg_write(REG_INT_EN_1, Interrupt_Enable_1.all) != 0) {
phonemacro 0:b0addee6d8d1 604 return -1;
phonemacro 0:b0addee6d8d1 605 }
phonemacro 0:b0addee6d8d1 606
phonemacro 0:b0addee6d8d1 607 mode_configuration.all = 0;
phonemacro 0:b0addee6d8d1 608 mode_configuration.bit.mode = 0x00; ///< Multi-LED mode off
phonemacro 0:b0addee6d8d1 609 if (i2c_reg_write(REG_MODE_CFG, mode_configuration.all) != 0) {
phonemacro 0:b0addee6d8d1 610 return -1;
phonemacro 0:b0addee6d8d1 611 }
phonemacro 0:b0addee6d8d1 612
phonemacro 0:b0addee6d8d1 613 if (i2c_reg_write(REG_LED1_PA, 0) != 0) {
phonemacro 0:b0addee6d8d1 614 return -1;
phonemacro 0:b0addee6d8d1 615 }
phonemacro 0:b0addee6d8d1 616
phonemacro 0:b0addee6d8d1 617 if (i2c_reg_write(REG_LED2_PA, 0) != 0) {
phonemacro 0:b0addee6d8d1 618 return -1;
phonemacro 0:b0addee6d8d1 619 }
phonemacro 0:b0addee6d8d1 620
phonemacro 0:b0addee6d8d1 621 if (i2c_reg_write(REG_LED3_PA, 0) != 0) {
phonemacro 0:b0addee6d8d1 622 return -1;
phonemacro 0:b0addee6d8d1 623 }
phonemacro 0:b0addee6d8d1 624 return 0;
phonemacro 0:b0addee6d8d1 625 }
phonemacro 0:b0addee6d8d1 626
phonemacro 0:b0addee6d8d1 627 //******************************************************************************
phonemacro 0:b0addee6d8d1 628 int MAX30101::tempread(void) {
phonemacro 0:b0addee6d8d1 629
phonemacro 0:b0addee6d8d1 630 if (i2c_reg_write(REG_INT_EN_2, 0x02) != 0) {///< Interrupt Enable 2, Temperature Interrupt
phonemacro 0:b0addee6d8d1 631 return -1;
phonemacro 0:b0addee6d8d1 632 }
phonemacro 0:b0addee6d8d1 633
phonemacro 0:b0addee6d8d1 634 if (i2c_reg_write(REG_TEMP_EN, 0x01) != 0) {///< Die Temperature Config, Temp enable...
phonemacro 0:b0addee6d8d1 635
phonemacro 0:b0addee6d8d1 636 return -1;
phonemacro 0:b0addee6d8d1 637 }
phonemacro 0:b0addee6d8d1 638 return 0;
phonemacro 0:b0addee6d8d1 639 }
phonemacro 0:b0addee6d8d1 640
phonemacro 0:b0addee6d8d1 641 //******************************************************************************
phonemacro 0:b0addee6d8d1 642 int MAX30101::i2c_reg_write(MAX30101_REG_map_t reg, char value) {
phonemacro 0:b0addee6d8d1 643
phonemacro 0:b0addee6d8d1 644 char cmdData[2] = {reg, value};
phonemacro 0:b0addee6d8d1 645
phonemacro 0:b0addee6d8d1 646 if (I2CM_Write(slaveAddress, NULL, 0, cmdData, 2) != 0) {
phonemacro 0:b0addee6d8d1 647 return -1;
phonemacro 0:b0addee6d8d1 648 }
phonemacro 0:b0addee6d8d1 649
phonemacro 0:b0addee6d8d1 650 return 0;
phonemacro 0:b0addee6d8d1 651 }
phonemacro 0:b0addee6d8d1 652
phonemacro 0:b0addee6d8d1 653 //******************************************************************************
phonemacro 0:b0addee6d8d1 654 int MAX30101::i2c_reg_read(MAX30101_REG_map_t reg, char *value) {
phonemacro 0:b0addee6d8d1 655 if (I2CM_Read(slaveAddress, (char *)&reg, 1, value, 1) != 0 /*1*/) {
phonemacro 0:b0addee6d8d1 656 return -1;
phonemacro 0:b0addee6d8d1 657 }
phonemacro 0:b0addee6d8d1 658
phonemacro 0:b0addee6d8d1 659 return 0;
phonemacro 0:b0addee6d8d1 660 }
phonemacro 0:b0addee6d8d1 661
phonemacro 0:b0addee6d8d1 662 //******************************************************************************
phonemacro 0:b0addee6d8d1 663 int MAX30101::I2CM_Read(int slaveAddress, char *writeData, char writeCount,
phonemacro 0:b0addee6d8d1 664 char *readData, char readCount) {
phonemacro 0:b0addee6d8d1 665
phonemacro 0:b0addee6d8d1 666 if (writeData != NULL && writeCount != 0) {
phonemacro 0:b0addee6d8d1 667 i2c->write(slaveAddress, writeData, writeCount, true);
phonemacro 0:b0addee6d8d1 668 }
phonemacro 0:b0addee6d8d1 669 if (readData != NULL && readCount != 0) {
phonemacro 0:b0addee6d8d1 670 i2c->read(slaveAddress, readData, readCount);
phonemacro 0:b0addee6d8d1 671 }
phonemacro 0:b0addee6d8d1 672 return 0;
phonemacro 0:b0addee6d8d1 673 }
phonemacro 0:b0addee6d8d1 674
phonemacro 0:b0addee6d8d1 675 //******************************************************************************
phonemacro 0:b0addee6d8d1 676 int MAX30101::I2CM_Write(int slaveAddress, char *writeData1, char writeCount1,
phonemacro 0:b0addee6d8d1 677 char *writeData2, char writeCount2) {
phonemacro 0:b0addee6d8d1 678
phonemacro 0:b0addee6d8d1 679 if (writeData1 != NULL && writeCount1 != 0) {
phonemacro 0:b0addee6d8d1 680 i2c->write(slaveAddress, writeData1, writeCount1);
phonemacro 0:b0addee6d8d1 681 }
phonemacro 0:b0addee6d8d1 682 if (writeData2 != NULL && writeCount2 != 0) {
phonemacro 0:b0addee6d8d1 683 i2c->write(slaveAddress, writeData2, writeCount2);
phonemacro 0:b0addee6d8d1 684 }
phonemacro 0:b0addee6d8d1 685 return 0;
phonemacro 0:b0addee6d8d1 686 }
phonemacro 0:b0addee6d8d1 687
phonemacro 0:b0addee6d8d1 688 //******************************************************************************
phonemacro 0:b0addee6d8d1 689 void MAX30101::onDataAvailable(DataCallbackFunction _onDataAvailable) {
phonemacro 0:b0addee6d8d1 690
phonemacro 0:b0addee6d8d1 691 onDataAvailableCallback = _onDataAvailable;
phonemacro 0:b0addee6d8d1 692 }
phonemacro 0:b0addee6d8d1 693
phonemacro 0:b0addee6d8d1 694 //******************************************************************************
phonemacro 0:b0addee6d8d1 695 void MAX30101::dataAvailable(uint32_t id, uint32_t *buffer, uint32_t length) {
phonemacro 0:b0addee6d8d1 696
phonemacro 0:b0addee6d8d1 697 if (onDataAvailableCallback != NULL) {
phonemacro 0:b0addee6d8d1 698 (*onDataAvailableCallback)(id, buffer, length);
phonemacro 0:b0addee6d8d1 699 }
phonemacro 0:b0addee6d8d1 700 }
phonemacro 0:b0addee6d8d1 701
phonemacro 0:b0addee6d8d1 702 //******************************************************************************
phonemacro 0:b0addee6d8d1 703 void MAX30101::onInterrupt(InterruptFunction _onInterrupt) {
phonemacro 0:b0addee6d8d1 704
phonemacro 0:b0addee6d8d1 705 onInterruptCallback = _onInterrupt;
phonemacro 0:b0addee6d8d1 706 }
phonemacro 0:b0addee6d8d1 707
phonemacro 0:b0addee6d8d1 708 //******************************************************************************
phonemacro 0:b0addee6d8d1 709 void MAX30101::interruptPostCallback(void) {
phonemacro 0:b0addee6d8d1 710
phonemacro 0:b0addee6d8d1 711 if (onInterruptCallback != NULL) {
phonemacro 0:b0addee6d8d1 712
phonemacro 0:b0addee6d8d1 713 (*onInterruptCallback)();
phonemacro 0:b0addee6d8d1 714 }
phonemacro 0:b0addee6d8d1 715 }
phonemacro 0:b0addee6d8d1 716
phonemacro 0:b0addee6d8d1 717 //******************************************************************************
phonemacro 0:b0addee6d8d1 718 void MAX30101::MidIntHandler(void) {
phonemacro 0:b0addee6d8d1 719
phonemacro 0:b0addee6d8d1 720 MAX30101::instance->int_handler();
phonemacro 0:b0addee6d8d1 721 }