MAX32620HSP (MAXREFDES100) RPC Example for Graphical User Interface

Dependencies:   USBDevice

Fork of HSP_Release by Jerry Bradshaw

This is an example program for the MAX32620HSP (MAXREFDES100 Health Sensor Platform). It demonstrates all the features of the platform and works with a companion graphical user interface (GUI) to help evaluate/configure/monitor the board. Go to the MAXREFDES100 product page and click on "design resources" to download the companion software. The GUI connects to the board through an RPC interface on a virtual serial port over the USB interface.

The RPC interface provides access to all the features of the board and is available to interface with other development environments such Matlab. This firmware provides realtime data streaming through the RPC interface over USB, and also provides the ability to log the data to flash for untethered battery operation. The data logging settings are configured through the GUI, and the GUI also provides the interface to download logged data.

Details on the RPC interface can be found here: HSP RPC Interface Documentation

Windows

With this program loaded, the MAX32620HSP will appear on your computer as a serial port. On Mac and Linux, this will happen by default. For Windows, you need to install a driver: HSP serial port windows driver

For more details about this platform and how to use it, see the MAXREFDES100 product page.

Committer:
jbradshaw
Date:
Tue Oct 25 15:22:11 2016 +0000
Revision:
0:e4a10ed6eb92
Child:
1:9490836294ea
tewt

Who changed what in which revision?

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