Chanel's edits

Dependencies:   max32630fthr USBDevice

Committer:
saleiferis
Date:
Tue Apr 07 04:57:22 2020 +0000
Revision:
19:f230229cb6f3
Parent:
14:ee2175578993
HeartRateService

Who changed what in which revision?

UserRevisionLine numberNew contents of line
saleiferis 0:89ec48e52250 1 /***************************************************
saleiferis 0:89ec48e52250 2 Arduino library written for the Maxim MAX86150 ECG and PPG integrated sensor
saleiferis 0:89ec48e52250 3
saleiferis 0:89ec48e52250 4 Written by Ashwin Whitchurch, ProtoCentral Electronics (www.protocentral.com)
saleiferis 0:89ec48e52250 5
saleiferis 0:89ec48e52250 6 Based on code written by Peter Jansen and Nathan Seidle (SparkFun) for the MAX30105 sensor
saleiferis 0:89ec48e52250 7 BSD license, all text above must be included in any redistribution.
saleiferis 0:89ec48e52250 8 *****************************************************/
saleiferis 0:89ec48e52250 9
saleiferis 0:89ec48e52250 10 #include "max86150.h"
saleiferis 0:89ec48e52250 11
saleiferis 0:89ec48e52250 12
saleiferis 0:89ec48e52250 13 static const uint8_t MAX86150_INTSTAT1 = 0x00;
saleiferis 0:89ec48e52250 14 static const uint8_t MAX86150_INTSTAT2 = 0x01;
saleiferis 0:89ec48e52250 15 static const uint8_t MAX86150_INTENABLE1 = 0x02;
saleiferis 0:89ec48e52250 16 static const uint8_t MAX86150_INTENABLE2 = 0x03;
saleiferis 0:89ec48e52250 17
saleiferis 0:89ec48e52250 18 static const uint8_t MAX86150_FIFOWRITEPTR = 0x04;
saleiferis 0:89ec48e52250 19 static const uint8_t MAX86150_FIFOOVERFLOW = 0x05;
saleiferis 0:89ec48e52250 20 static const uint8_t MAX86150_FIFOREADPTR = 0x06;
saleiferis 0:89ec48e52250 21 static const uint8_t MAX86150_FIFODATA = 0x07;
saleiferis 0:89ec48e52250 22
saleiferis 0:89ec48e52250 23 static const uint8_t MAX86150_FIFOCONFIG = 0x08;
saleiferis 0:89ec48e52250 24 static const uint8_t MAX86150_FIFOCONTROL1= 0x09;
saleiferis 0:89ec48e52250 25 static const uint8_t MAX86150_FIFOCONTROL2 = 0x0A;
saleiferis 0:89ec48e52250 26
saleiferis 0:89ec48e52250 27 static const uint8_t MAX86150_SYSCONTROL = 0x0D;
saleiferis 0:89ec48e52250 28 static const uint8_t MAX86150_PPGCONFIG1 = 0x0E;
saleiferis 0:89ec48e52250 29 static const uint8_t MAX86150_PPGCONFIG2 = 0x0F;
saleiferis 0:89ec48e52250 30 static const uint8_t MAX86150_LED_PROX_AMP = 0x10;
saleiferis 0:89ec48e52250 31
saleiferis 0:89ec48e52250 32 static const uint8_t MAX86150_LED1_PULSEAMP = 0x11;
saleiferis 0:89ec48e52250 33 static const uint8_t MAX86150_LED2_PULSEAMP = 0x12;
saleiferis 0:89ec48e52250 34 static const uint8_t MAX86150_LED_RANGE = 0x14;
saleiferis 0:89ec48e52250 35 static const uint8_t MAX86150_LED_PILOT_PA = 0x15;
saleiferis 0:89ec48e52250 36
saleiferis 0:89ec48e52250 37 static const uint8_t MAX86150_ECG_CONFIG1 = 0x3C;
saleiferis 0:89ec48e52250 38 static const uint8_t MAX86150_ECG_CONFIG3 = 0x3E;
saleiferis 0:89ec48e52250 39 static const uint8_t MAX86150_PROXINTTHRESH = 0x10;
saleiferis 0:89ec48e52250 40
saleiferis 0:89ec48e52250 41 static const uint8_t MAX86150_PARTID = 0xFF;
saleiferis 0:89ec48e52250 42
saleiferis 0:89ec48e52250 43 // MAX86150 Commands
saleiferis 0:89ec48e52250 44 static const uint8_t MAX86150_INT_A_FULL_MASK = (uint8_t)~0b10000000;
saleiferis 0:89ec48e52250 45 static const uint8_t MAX86150_INT_A_FULL_ENABLE = 0x80;
saleiferis 0:89ec48e52250 46 static const uint8_t MAX86150_INT_A_FULL_DISABLE = 0x00;
saleiferis 0:89ec48e52250 47
saleiferis 0:89ec48e52250 48 static const uint8_t MAX86150_INT_DATA_RDY_MASK = (uint8_t)~0b01000000;
saleiferis 0:89ec48e52250 49 static const uint8_t MAX86150_INT_DATA_RDY_ENABLE = 0x40;
saleiferis 0:89ec48e52250 50 static const uint8_t MAX86150_INT_DATA_RDY_DISABLE = 0x00;
saleiferis 0:89ec48e52250 51
saleiferis 0:89ec48e52250 52 static const uint8_t MAX86150_INT_ALC_OVF_MASK = (uint8_t)~0b00100000;
saleiferis 0:89ec48e52250 53 static const uint8_t MAX86150_INT_ALC_OVF_ENABLE = 0x20;
saleiferis 0:89ec48e52250 54 static const uint8_t MAX86150_INT_ALC_OVF_DISABLE = 0x00;
saleiferis 0:89ec48e52250 55
saleiferis 0:89ec48e52250 56 static const uint8_t MAX86150_INT_PROX_INT_MASK = (uint8_t)~0b00010000;
saleiferis 0:89ec48e52250 57 static const uint8_t MAX86150_INT_PROX_INT_ENABLE = 0x10;
saleiferis 0:89ec48e52250 58 static const uint8_t MAX86150_INT_PROX_INT_DISABLE = 0x00;
saleiferis 0:89ec48e52250 59
saleiferis 0:89ec48e52250 60 static const uint8_t MAX86150_SAMPLEAVG_MASK = (uint8_t)~0b11100000;
saleiferis 0:89ec48e52250 61 static const uint8_t MAX86150_SAMPLEAVG_1 = 0x00;
saleiferis 0:89ec48e52250 62 static const uint8_t MAX86150_SAMPLEAVG_2 = 0x20;
saleiferis 0:89ec48e52250 63 static const uint8_t MAX86150_SAMPLEAVG_4 = 0x40;
saleiferis 0:89ec48e52250 64 static const uint8_t MAX86150_SAMPLEAVG_8 = 0x60;
saleiferis 0:89ec48e52250 65 static const uint8_t MAX86150_SAMPLEAVG_16 = 0x80;
saleiferis 0:89ec48e52250 66 static const uint8_t MAX86150_SAMPLEAVG_32 = 0xA0;
saleiferis 0:89ec48e52250 67
saleiferis 0:89ec48e52250 68 static const uint8_t MAX86150_ROLLOVER_MASK = 0xEF;
saleiferis 0:89ec48e52250 69 static const uint8_t MAX86150_ROLLOVER_ENABLE = 0x10;
saleiferis 0:89ec48e52250 70 static const uint8_t MAX86150_ROLLOVER_DISABLE = 0x00;
saleiferis 0:89ec48e52250 71
saleiferis 0:89ec48e52250 72 static const uint8_t MAX86150_A_FULL_MASK = 0xF0;
saleiferis 0:89ec48e52250 73
saleiferis 0:89ec48e52250 74 static const uint8_t MAX86150_SHUTDOWN_MASK = 0x7F;
saleiferis 0:89ec48e52250 75 static const uint8_t MAX86150_SHUTDOWN = 0x80;
saleiferis 0:89ec48e52250 76 static const uint8_t MAX86150_WAKEUP = 0x00;
saleiferis 0:89ec48e52250 77
saleiferis 0:89ec48e52250 78 static const uint8_t MAX86150_RESET_MASK = 0xFE;
saleiferis 0:89ec48e52250 79 static const uint8_t MAX86150_RESET = 0x01;
saleiferis 0:89ec48e52250 80
saleiferis 0:89ec48e52250 81 static const uint8_t MAX86150_MODE_MASK = 0xF8;
saleiferis 0:89ec48e52250 82 static const uint8_t MAX86150_MODE_REDONLY = 0x02;
saleiferis 0:89ec48e52250 83 static const uint8_t MAX86150_MODE_REDIRONLY = 0x03;
saleiferis 0:89ec48e52250 84 static const uint8_t MAX86150_MODE_MULTILED = 0x07;
saleiferis 0:89ec48e52250 85
saleiferis 0:89ec48e52250 86 static const uint8_t MAX86150_ADCRANGE_MASK = 0x9F;
saleiferis 0:89ec48e52250 87 static const uint8_t MAX86150_ADCRANGE_2048 = 0x00;
saleiferis 0:89ec48e52250 88 static const uint8_t MAX86150_ADCRANGE_4096 = 0x20;
saleiferis 0:89ec48e52250 89 static const uint8_t MAX86150_ADCRANGE_8192 = 0x40;
saleiferis 0:89ec48e52250 90 static const uint8_t MAX86150_ADCRANGE_16384 = 0x60;
saleiferis 0:89ec48e52250 91
saleiferis 0:89ec48e52250 92 static const uint8_t MAX86150_SAMPLERATE_MASK = 0xE3;
saleiferis 0:89ec48e52250 93 static const uint8_t MAX86150_SAMPLERATE_50 = 0x00;
saleiferis 0:89ec48e52250 94 static const uint8_t MAX86150_SAMPLERATE_100 = 0x04;
saleiferis 0:89ec48e52250 95 static const uint8_t MAX86150_SAMPLERATE_200 = 0x08;
saleiferis 0:89ec48e52250 96 static const uint8_t MAX86150_SAMPLERATE_400 = 0x0C;
saleiferis 0:89ec48e52250 97 static const uint8_t MAX86150_SAMPLERATE_800 = 0x10;
saleiferis 0:89ec48e52250 98 static const uint8_t MAX86150_SAMPLERATE_1000 = 0x14;
saleiferis 0:89ec48e52250 99 static const uint8_t MAX86150_SAMPLERATE_1600 = 0x18;
saleiferis 0:89ec48e52250 100 static const uint8_t MAX86150_SAMPLERATE_3200 = 0x1C;
saleiferis 0:89ec48e52250 101
saleiferis 0:89ec48e52250 102 static const uint8_t MAX86150_PULSEWIDTH_MASK = 0xFC;
saleiferis 0:89ec48e52250 103 static const uint8_t MAX86150_PULSEWIDTH_69 = 0x00;
saleiferis 0:89ec48e52250 104 static const uint8_t MAX86150_PULSEWIDTH_118 = 0x01;
saleiferis 0:89ec48e52250 105 static const uint8_t MAX86150_PULSEWIDTH_215 = 0x02;
saleiferis 0:89ec48e52250 106 static const uint8_t MAX86150_PULSEWIDTH_411 = 0x03;
saleiferis 0:89ec48e52250 107
saleiferis 0:89ec48e52250 108 static const uint8_t MAX86150_SLOT1_MASK = 0xF0;
saleiferis 0:89ec48e52250 109 static const uint8_t MAX86150_SLOT2_MASK = 0x0F;
saleiferis 0:89ec48e52250 110 static const uint8_t MAX86150_SLOT3_MASK = 0xF0;
saleiferis 0:89ec48e52250 111 static const uint8_t MAX86150_SLOT4_MASK = 0x0F;
saleiferis 0:89ec48e52250 112
saleiferis 0:89ec48e52250 113 static const uint8_t SLOT_NONE = 0x00;
saleiferis 0:89ec48e52250 114 static const uint8_t SLOT_RED_LED = 0x01;
saleiferis 0:89ec48e52250 115 static const uint8_t SLOT_IR_LED = 0x02;
saleiferis 0:89ec48e52250 116 static const uint8_t SLOT_RED_PILOT = 0x09;
saleiferis 0:89ec48e52250 117 static const uint8_t SLOT_IR_PILOT = 0x0A;
saleiferis 0:89ec48e52250 118 static const uint8_t SLOT_ECG = 0x0D;
saleiferis 0:89ec48e52250 119
saleiferis 0:89ec48e52250 120 static const uint8_t MAX_30105_EXPECTEDPARTID = 0x1E;
saleiferis 0:89ec48e52250 121 //static const uint8_t MAX_30105_EXPECTEDPARTID = 0x00;
saleiferis 0:89ec48e52250 122
saleiferis 0:89ec48e52250 123 extern Serial pc;
saleiferis 0:89ec48e52250 124
saleiferis 0:89ec48e52250 125 MAX86150::MAX86150() {
saleiferis 0:89ec48e52250 126 // Constructor
saleiferis 0:89ec48e52250 127 }
saleiferis 0:89ec48e52250 128
saleiferis 0:89ec48e52250 129 //boolean MAX86150::begin(TwoWire &wirePort, uint32_t i2cSpeed, uint8_t i2caddr)
saleiferis 0:89ec48e52250 130 bool MAX86150::begin(I2C &wirePort, uint32_t i2cSpeed, uint8_t i2caddr)
saleiferis 0:89ec48e52250 131 {
saleiferis 0:89ec48e52250 132
saleiferis 0:89ec48e52250 133 _i2cPort = &wirePort;
saleiferis 0:89ec48e52250 134 _i2cPort->frequency(i2cSpeed);
saleiferis 0:89ec48e52250 135 _i2caddr = i2caddr;
saleiferis 0:89ec48e52250 136 /*
saleiferis 0:89ec48e52250 137 // Step 1: Initial Communication and Verification
saleiferis 0:89ec48e52250 138 // Check that a MAX86150 is connected
saleiferis 0:89ec48e52250 139 //Serial.println(readPartID());
saleiferis 0:89ec48e52250 140 //Serial.println(MAX_30105_EXPECTEDPARTID);
saleiferis 0:89ec48e52250 141 if (readPartID() != MAX_30105_EXPECTEDPARTID) {
saleiferis 0:89ec48e52250 142 // Error -- Part ID read from MAX86150 does not match expected part ID.
saleiferis 0:89ec48e52250 143 // This may mean there is a physical connectivity problem (broken wire, unpowered, etc).
saleiferis 0:89ec48e52250 144 return false;
saleiferis 0:89ec48e52250 145 }
saleiferis 0:89ec48e52250 146 return true;*/
saleiferis 0:89ec48e52250 147
saleiferis 0:89ec48e52250 148
saleiferis 0:89ec48e52250 149
saleiferis 0:89ec48e52250 150 return true;
saleiferis 0:89ec48e52250 151
saleiferis 0:89ec48e52250 152
saleiferis 0:89ec48e52250 153 }
saleiferis 0:89ec48e52250 154
saleiferis 0:89ec48e52250 155 //
saleiferis 0:89ec48e52250 156 // Configuration
saleiferis 0:89ec48e52250 157 //
saleiferis 0:89ec48e52250 158
saleiferis 0:89ec48e52250 159 //Begin Interrupt configuration
saleiferis 0:89ec48e52250 160 uint8_t MAX86150::getINT1(void)
saleiferis 0:89ec48e52250 161 {
saleiferis 0:89ec48e52250 162 return (readRegister8(_i2caddr, MAX86150_INTSTAT1));
saleiferis 0:89ec48e52250 163 }
saleiferis 0:89ec48e52250 164 uint8_t MAX86150::getINT2(void) {
saleiferis 0:89ec48e52250 165 return (readRegister8(_i2caddr, MAX86150_INTSTAT2));
saleiferis 0:89ec48e52250 166 }
saleiferis 0:89ec48e52250 167
saleiferis 0:89ec48e52250 168 void MAX86150::enableAFULL(void) {
saleiferis 0:89ec48e52250 169 bitMask(MAX86150_INTENABLE1, MAX86150_INT_A_FULL_MASK, MAX86150_INT_A_FULL_ENABLE);
saleiferis 0:89ec48e52250 170 }
saleiferis 0:89ec48e52250 171 void MAX86150::disableAFULL(void) {
saleiferis 0:89ec48e52250 172 bitMask(MAX86150_INTENABLE1, MAX86150_INT_A_FULL_MASK, MAX86150_INT_A_FULL_DISABLE);
saleiferis 0:89ec48e52250 173 }
saleiferis 0:89ec48e52250 174
saleiferis 0:89ec48e52250 175 void MAX86150::enableDATARDY(void) {
saleiferis 0:89ec48e52250 176 bitMask(MAX86150_INTENABLE1, MAX86150_INT_DATA_RDY_MASK, MAX86150_INT_DATA_RDY_ENABLE);
saleiferis 0:89ec48e52250 177 }
saleiferis 0:89ec48e52250 178 void MAX86150::disableDATARDY(void) {
saleiferis 0:89ec48e52250 179 bitMask(MAX86150_INTENABLE1, MAX86150_INT_DATA_RDY_MASK, MAX86150_INT_DATA_RDY_DISABLE);
saleiferis 0:89ec48e52250 180 }
saleiferis 0:89ec48e52250 181
saleiferis 0:89ec48e52250 182 void MAX86150::enableALCOVF(void) {
saleiferis 0:89ec48e52250 183 bitMask(MAX86150_INTENABLE1, MAX86150_INT_ALC_OVF_MASK, MAX86150_INT_ALC_OVF_ENABLE);
saleiferis 0:89ec48e52250 184 }
saleiferis 0:89ec48e52250 185 void MAX86150::disableALCOVF(void) {
saleiferis 0:89ec48e52250 186 bitMask(MAX86150_INTENABLE1, MAX86150_INT_ALC_OVF_MASK, MAX86150_INT_ALC_OVF_DISABLE);
saleiferis 0:89ec48e52250 187 }
saleiferis 0:89ec48e52250 188
saleiferis 0:89ec48e52250 189 void MAX86150::enablePROXINT(void) {
saleiferis 0:89ec48e52250 190 bitMask(MAX86150_INTENABLE1, MAX86150_INT_PROX_INT_MASK, MAX86150_INT_PROX_INT_ENABLE);
saleiferis 0:89ec48e52250 191 }
saleiferis 0:89ec48e52250 192 void MAX86150::disablePROXINT(void) {
saleiferis 0:89ec48e52250 193 bitMask(MAX86150_INTENABLE1, MAX86150_INT_PROX_INT_MASK, MAX86150_INT_PROX_INT_DISABLE);
saleiferis 0:89ec48e52250 194 }
saleiferis 0:89ec48e52250 195 //End Interrupt configuration
saleiferis 0:89ec48e52250 196
saleiferis 0:89ec48e52250 197 void MAX86150::softReset(void) {
saleiferis 0:89ec48e52250 198
saleiferis 0:89ec48e52250 199 Timer t;
saleiferis 0:89ec48e52250 200 t.start();
saleiferis 0:89ec48e52250 201 bitMask(MAX86150_SYSCONTROL, MAX86150_RESET_MASK, MAX86150_RESET);
saleiferis 0:89ec48e52250 202
saleiferis 0:89ec48e52250 203 // Poll for bit to clear, reset is then complete
saleiferis 0:89ec48e52250 204 // Timeout after 100ms
saleiferis 0:89ec48e52250 205
saleiferis 0:89ec48e52250 206 unsigned long startTime = t.read(); //TODO: double check t.read() returns milliseconds
saleiferis 0:89ec48e52250 207 while (t.read() - startTime < 100)
saleiferis 0:89ec48e52250 208 {
saleiferis 0:89ec48e52250 209 uint8_t response = readRegister8(_i2caddr, MAX86150_SYSCONTROL);
saleiferis 0:89ec48e52250 210 if ((response & MAX86150_RESET) == 0) break; //We're done!
saleiferis 0:89ec48e52250 211 wait_ms(1); //Let's not over burden the I2C bus
saleiferis 0:89ec48e52250 212 }
saleiferis 0:89ec48e52250 213 }
saleiferis 0:89ec48e52250 214
saleiferis 0:89ec48e52250 215 void MAX86150::shutDown(void) {
saleiferis 0:89ec48e52250 216 // Put IC into low power mode (datasheet pg. 19)
saleiferis 0:89ec48e52250 217 // During shutdown the IC will continue to respond to I2C commands but will
saleiferis 0:89ec48e52250 218 // not update with or take new readings (such as temperature)
saleiferis 0:89ec48e52250 219 bitMask(MAX86150_SYSCONTROL, MAX86150_SHUTDOWN_MASK, MAX86150_SHUTDOWN);
saleiferis 0:89ec48e52250 220 }
saleiferis 0:89ec48e52250 221
saleiferis 0:89ec48e52250 222 void MAX86150::wakeUp(void) {
saleiferis 0:89ec48e52250 223 // Pull IC out of low power mode (datasheet pg. 19)
saleiferis 0:89ec48e52250 224 bitMask(MAX86150_SYSCONTROL, MAX86150_SHUTDOWN_MASK, MAX86150_WAKEUP);
saleiferis 0:89ec48e52250 225 }
saleiferis 0:89ec48e52250 226
saleiferis 0:89ec48e52250 227 void MAX86150::setLEDMode(uint8_t mode) {
saleiferis 0:89ec48e52250 228 // Set which LEDs are used for sampling -- Red only, RED+IR only, or custom.
saleiferis 0:89ec48e52250 229 // See datasheet, page 19
saleiferis 0:89ec48e52250 230 //bitMask(MAX86150_PPGCONFIG1, MAX86150_MODE_MASK, mode);
saleiferis 0:89ec48e52250 231 }
saleiferis 0:89ec48e52250 232
saleiferis 0:89ec48e52250 233 void MAX86150::setADCRange(uint8_t adcRange) {
saleiferis 0:89ec48e52250 234 // adcRange: one of MAX86150_ADCRANGE_2048, _4096, _8192, _16384
saleiferis 0:89ec48e52250 235 //bitMask(MAX86150_PARTICLECONFIG, MAX86150_ADCRANGE_MASK, adcRange);
saleiferis 0:89ec48e52250 236 }
saleiferis 0:89ec48e52250 237
saleiferis 0:89ec48e52250 238 void MAX86150::setSampleRate(uint8_t sampleRate) {
saleiferis 0:89ec48e52250 239 // sampleRate: one of MAX86150_SAMPLERATE_50, _100, _200, _400, _800, _1000, _1600, _3200
saleiferis 0:89ec48e52250 240 //bitMask(MAX86150_PARTICLECONFIG, MAX86150_SAMPLERATE_MASK, sampleRate);
saleiferis 0:89ec48e52250 241 }
saleiferis 0:89ec48e52250 242
saleiferis 0:89ec48e52250 243 void MAX86150::setPulseWidth(uint8_t pulseWidth) {
saleiferis 0:89ec48e52250 244 // pulseWidth: one of MAX86150_PULSEWIDTH_69, _188, _215, _411
saleiferis 0:89ec48e52250 245 bitMask(MAX86150_PPGCONFIG1, MAX86150_PULSEWIDTH_MASK, pulseWidth);
saleiferis 0:89ec48e52250 246 }
saleiferis 0:89ec48e52250 247
saleiferis 0:89ec48e52250 248 // NOTE: Amplitude values: 0x00 = 0mA, 0x7F = 25.4mA, 0xFF = 50mA (typical)
saleiferis 0:89ec48e52250 249 // See datasheet, page 21
saleiferis 0:89ec48e52250 250 void MAX86150::setPulseAmplitudeRed(uint8_t amplitude)
saleiferis 0:89ec48e52250 251 {
saleiferis 0:89ec48e52250 252 writeRegister8(_i2caddr, MAX86150_LED2_PULSEAMP, amplitude);
saleiferis 0:89ec48e52250 253 }
saleiferis 0:89ec48e52250 254
saleiferis 0:89ec48e52250 255 void MAX86150::setPulseAmplitudeIR(uint8_t amplitude)
saleiferis 0:89ec48e52250 256 {
saleiferis 0:89ec48e52250 257 writeRegister8(_i2caddr, MAX86150_LED1_PULSEAMP, amplitude);
saleiferis 0:89ec48e52250 258 }
saleiferis 0:89ec48e52250 259
saleiferis 0:89ec48e52250 260 void MAX86150::setPulseAmplitudeProximity(uint8_t amplitude) {
saleiferis 10:28b8729cf5dc 261 writeRegister8(_i2caddr, MAX86150_LED_PILOT_PA, amplitude);
saleiferis 0:89ec48e52250 262 }
saleiferis 0:89ec48e52250 263
saleiferis 0:89ec48e52250 264 void MAX86150::setProximityThreshold(uint8_t threshMSB)
saleiferis 0:89ec48e52250 265 {
saleiferis 0:89ec48e52250 266 // The threshMSB signifies only the 8 most significant-bits of the ADC count.
saleiferis 0:89ec48e52250 267 writeRegister8(_i2caddr, MAX86150_PROXINTTHRESH, threshMSB);
saleiferis 0:89ec48e52250 268 }
saleiferis 0:89ec48e52250 269
saleiferis 0:89ec48e52250 270 //Given a slot number assign a thing to it
saleiferis 0:89ec48e52250 271 //Devices are SLOT_RED_LED or SLOT_RED_PILOT (proximity)
saleiferis 0:89ec48e52250 272 //Assigning a SLOT_RED_LED will pulse LED
saleiferis 0:89ec48e52250 273 //Assigning a SLOT_RED_PILOT will ??
saleiferis 0:89ec48e52250 274 void MAX86150::enableSlot(uint8_t slotNumber, uint8_t device)
saleiferis 0:89ec48e52250 275 {
saleiferis 0:89ec48e52250 276 uint8_t originalContents;
saleiferis 0:89ec48e52250 277
saleiferis 0:89ec48e52250 278 switch (slotNumber) {
saleiferis 0:89ec48e52250 279 case (1):
saleiferis 0:89ec48e52250 280 bitMask(MAX86150_FIFOCONTROL1, MAX86150_SLOT1_MASK, device);
saleiferis 0:89ec48e52250 281 break;
saleiferis 0:89ec48e52250 282 case (2):
saleiferis 0:89ec48e52250 283 bitMask(MAX86150_FIFOCONTROL1, MAX86150_SLOT2_MASK, device << 4);
saleiferis 0:89ec48e52250 284 break;
saleiferis 0:89ec48e52250 285 case (3):
saleiferis 0:89ec48e52250 286 bitMask(MAX86150_FIFOCONTROL2, MAX86150_SLOT3_MASK, device);
saleiferis 0:89ec48e52250 287 break;
saleiferis 0:89ec48e52250 288 case (4):
saleiferis 0:89ec48e52250 289 bitMask(MAX86150_FIFOCONTROL2, MAX86150_SLOT4_MASK, device << 4);
saleiferis 0:89ec48e52250 290 break;
saleiferis 0:89ec48e52250 291 default:
saleiferis 0:89ec48e52250 292 //Shouldn't be here!
saleiferis 0:89ec48e52250 293 break;
saleiferis 0:89ec48e52250 294 }
saleiferis 0:89ec48e52250 295 }
saleiferis 0:89ec48e52250 296
saleiferis 0:89ec48e52250 297 //Clears all slot assignments
saleiferis 0:89ec48e52250 298 void MAX86150::disableSlots(void)
saleiferis 0:89ec48e52250 299 {
saleiferis 0:89ec48e52250 300 writeRegister8(_i2caddr, MAX86150_FIFOCONTROL1, 0);
saleiferis 0:89ec48e52250 301 writeRegister8(_i2caddr, MAX86150_FIFOCONTROL2, 0);
saleiferis 0:89ec48e52250 302 }
saleiferis 0:89ec48e52250 303
saleiferis 0:89ec48e52250 304 //
saleiferis 0:89ec48e52250 305 // FIFO Configuration
saleiferis 0:89ec48e52250 306 //
saleiferis 0:89ec48e52250 307
saleiferis 0:89ec48e52250 308 void MAX86150::setFIFOAverage(uint8_t numberOfSamples)
saleiferis 0:89ec48e52250 309 {
saleiferis 0:89ec48e52250 310 bitMask(MAX86150_FIFOCONFIG, MAX86150_SAMPLEAVG_MASK, numberOfSamples);
saleiferis 0:89ec48e52250 311 }
saleiferis 0:89ec48e52250 312
saleiferis 0:89ec48e52250 313 //Resets all points to start in a known state
saleiferis 0:89ec48e52250 314 void MAX86150::clearFIFO(void) {
saleiferis 0:89ec48e52250 315 writeRegister8(_i2caddr, MAX86150_FIFOWRITEPTR, 0);
saleiferis 0:89ec48e52250 316 writeRegister8(_i2caddr, MAX86150_FIFOOVERFLOW, 0);
saleiferis 0:89ec48e52250 317 writeRegister8(_i2caddr, MAX86150_FIFOREADPTR, 0);
saleiferis 0:89ec48e52250 318 }
saleiferis 0:89ec48e52250 319
saleiferis 0:89ec48e52250 320 //Enable roll over if FIFO over flows
saleiferis 0:89ec48e52250 321 void MAX86150::enableFIFORollover(void) {
saleiferis 0:89ec48e52250 322 bitMask(MAX86150_FIFOCONFIG, MAX86150_ROLLOVER_MASK, MAX86150_ROLLOVER_ENABLE);
saleiferis 0:89ec48e52250 323 }
saleiferis 0:89ec48e52250 324
saleiferis 0:89ec48e52250 325 //Disable roll over if FIFO over flows
saleiferis 0:89ec48e52250 326 void MAX86150::disableFIFORollover(void) {
saleiferis 0:89ec48e52250 327 bitMask(MAX86150_FIFOCONFIG, MAX86150_ROLLOVER_MASK, MAX86150_ROLLOVER_DISABLE);
saleiferis 0:89ec48e52250 328 }
saleiferis 0:89ec48e52250 329
saleiferis 0:89ec48e52250 330 //Power on default is 32 samples
saleiferis 0:89ec48e52250 331 //Note it is reverse: 0x00 is 32 samples, 0x0F is 17 samples
saleiferis 0:89ec48e52250 332 void MAX86150::setFIFOAlmostFull(uint8_t numberOfSamples) {
saleiferis 0:89ec48e52250 333 bitMask(MAX86150_FIFOCONFIG, MAX86150_A_FULL_MASK, numberOfSamples);
saleiferis 0:89ec48e52250 334 }
saleiferis 0:89ec48e52250 335
saleiferis 0:89ec48e52250 336 //Read the FIFO Write Pointer
saleiferis 0:89ec48e52250 337 uint8_t MAX86150::getWritePointer(void) {
saleiferis 0:89ec48e52250 338 return (readRegister8(_i2caddr, MAX86150_FIFOWRITEPTR));
saleiferis 0:89ec48e52250 339 }
saleiferis 0:89ec48e52250 340
saleiferis 0:89ec48e52250 341 //Read the FIFO Read Pointer
saleiferis 0:89ec48e52250 342 uint8_t MAX86150::getReadPointer(void) {
saleiferis 0:89ec48e52250 343 return (readRegister8(_i2caddr, MAX86150_FIFOREADPTR));
saleiferis 0:89ec48e52250 344 }
saleiferis 0:89ec48e52250 345
saleiferis 0:89ec48e52250 346 // Set the PROX_INT_THRESHold
saleiferis 0:89ec48e52250 347 void MAX86150::setPROXINTTHRESH(uint8_t val) {
saleiferis 0:89ec48e52250 348 writeRegister8(_i2caddr, MAX86150_PROXINTTHRESH, val);
saleiferis 0:89ec48e52250 349 }
saleiferis 0:89ec48e52250 350
saleiferis 0:89ec48e52250 351 //
saleiferis 0:89ec48e52250 352 // Device ID and Revision
saleiferis 0:89ec48e52250 353 //
saleiferis 0:89ec48e52250 354 uint8_t MAX86150::readPartID() {
saleiferis 0:89ec48e52250 355 return readRegister8(_i2caddr, MAX86150_PARTID);
saleiferis 0:89ec48e52250 356 }
saleiferis 0:89ec48e52250 357
saleiferis 0:89ec48e52250 358 //Setup the sensor
saleiferis 0:89ec48e52250 359 //The MAX86150 has many settings. By default we select:
saleiferis 0:89ec48e52250 360 // Sample Average = 4
saleiferis 0:89ec48e52250 361 // Mode = MultiLED
saleiferis 0:89ec48e52250 362 // ADC Range = 16384 (62.5pA per LSB)
saleiferis 0:89ec48e52250 363 // Sample rate = 50
saleiferis 0:89ec48e52250 364 //Use the default setup if you are just getting started with the MAX86150 sensor
saleiferis 0:89ec48e52250 365 void MAX86150::setup(uint8_t powerLevel, uint8_t sampleAverage, uint8_t ledMode, int sampleRate, int pulseWidth, int adcRange)
saleiferis 0:89ec48e52250 366 {
saleiferis 0:89ec48e52250 367 activeDevices=3;
saleiferis 0:89ec48e52250 368 writeRegister8(_i2caddr,MAX86150_SYSCONTROL,0x01); //it as 0x01
saleiferis 10:28b8729cf5dc 369 wait_ms(2);
saleiferis 0:89ec48e52250 370 //pc.printf("Just set SYSCONTOL REG: %x\n", readRegister8(_i2caddr,MAX86150_SYSCONTROL));
saleiferis 0:89ec48e52250 371 //delay(100);
saleiferis 0:89ec48e52250 372 //wait_ms(100);
saleiferis 8:2005014df05c 373
saleiferis 9:171171516ebd 374
saleiferis 9:171171516ebd 375 // FIFO Config
saleiferis 10:28b8729cf5dc 376 writeRegister8(_i2caddr,MAX86150_FIFOCONFIG,0b01111111); //first bit is don't care
saleiferis 9:171171516ebd 377 //FIFO CONTROL
saleiferis 9:171171516ebd 378 writeRegister8(_i2caddr,MAX86150_FIFOCONTROL1,(0b00100001));
saleiferis 9:171171516ebd 379 writeRegister8(_i2caddr,MAX86150_FIFOCONTROL2,(0b00001001));
saleiferis 8:2005014df05c 380
saleiferis 8:2005014df05c 381
saleiferis 9:171171516ebd 382
saleiferis 0:89ec48e52250 383 //pc.printf("Set FIFO_CTRL1: %x\n", readRegister8(_i2caddr, MAX86150_FIFOCONTROL1));
saleiferis 0:89ec48e52250 384 //pc.printf("Set FIFO_CTRL2: %x\n", readRegister8(_i2caddr, MAX86150_FIFOCONTROL2));
saleiferis 9:171171516ebd 385 // PPG CONFIG
saleiferis 10:28b8729cf5dc 386 writeRegister8(_i2caddr,MAX86150_PPGCONFIG1,0b11010110);
saleiferis 9:171171516ebd 387 //writeRegister8(_i2caddr,MAX86150_PPGCONFIG1,0b11100111);
saleiferis 10:28b8729cf5dc 388 writeRegister8(_i2caddr,MAX86150_PPGCONFIG2, 0x00);
saleiferis 10:28b8729cf5dc 389 writeRegister8(_i2caddr,MAX86150_LED_RANGE, 0b00000101 ); // PPG_ADC_RGE: 32768nA
saleiferis 10:28b8729cf5dc 390 writeRegister8(_i2caddr,0x12, 0xFF );
saleiferis 10:28b8729cf5dc 391 writeRegister8(_i2caddr,0x11, 0xFF );
saleiferis 10:28b8729cf5dc 392 //enablePROXINT();
saleiferis 10:28b8729cf5dc 393 //setProximityThreshold(0x05);
saleiferis 10:28b8729cf5dc 394 //setPulseAmplitudeProximity(0xFF);
saleiferis 14:ee2175578993 395 setPulseAmplitudeRed(0x1F);
saleiferis 14:ee2175578993 396 setPulseAmplitudeIR(0x1F);
saleiferis 0:89ec48e52250 397
saleiferis 0:89ec48e52250 398 //pc.printf("Before setting, SYS CTRL REG: %x\n",readRegister8(_i2caddr,MAX86150_SYSCONTROL));
saleiferis 0:89ec48e52250 399 //wait_ms(2000);
saleiferis 9:171171516ebd 400 // SYSCONTROL
saleiferis 9:171171516ebd 401 //writeRegister8(_i2caddr,MAX86150_SYSCONTROL,0x04);//start FIFO
saleiferis 0:89ec48e52250 402 //wait_ms(1000);
saleiferis 0:89ec48e52250 403 //pc.printf("Just set FIFO, SYS CTRL REG: %x\n",readRegister8(_i2caddr,MAX86150_SYSCONTROL));
saleiferis 10:28b8729cf5dc 404
saleiferis 10:28b8729cf5dc 405
saleiferis 10:28b8729cf5dc 406
saleiferis 9:171171516ebd 407 // ECG CONFIG
saleiferis 4:4233f5538abf 408 writeRegister8(_i2caddr,MAX86150_ECG_CONFIG1,0b00000011);
saleiferis 4:4233f5538abf 409 writeRegister8(_i2caddr,MAX86150_ECG_CONFIG3,0b00001111);
saleiferis 0:89ec48e52250 410
saleiferis 10:28b8729cf5dc 411 //setPulseAmplitudeRed(0x00);
saleiferis 10:28b8729cf5dc 412 //setPulseAmplitudeIR(0x00);
saleiferis 9:171171516ebd 413
saleiferis 9:171171516ebd 414 //Enable Interrupt
saleiferis 10:28b8729cf5dc 415 writeRegister8(_i2caddr,MAX86150_INTENABLE1,0b00000000);
saleiferis 9:171171516ebd 416 writeRegister8(_i2caddr,MAX86150_INTENABLE2,0b00000100);
saleiferis 10:28b8729cf5dc 417 //clearFIFO(); //Reset the FIFO before we begin checking the sensor
saleiferis 10:28b8729cf5dc 418 //writeRegister8(_i2caddr,MAX86150_SYSCONTROL,0x04);
saleiferis 9:171171516ebd 419 //wait_ms(1);
saleiferis 9:171171516ebd 420 pc.printf("Cleared FIFO, SYS CTRL REG: %x\n",readRegister8(_i2caddr,MAX86150_SYSCONTROL));
saleiferis 0:89ec48e52250 421 }
saleiferis 0:89ec48e52250 422
saleiferis 0:89ec48e52250 423 //Tell caller how many samples are available
saleiferis 0:89ec48e52250 424 uint8_t MAX86150::available(void)
saleiferis 0:89ec48e52250 425 {
saleiferis 0:89ec48e52250 426 int8_t numberOfSamples = sense.head - sense.tail;
saleiferis 0:89ec48e52250 427 if (numberOfSamples < 0) numberOfSamples += STORAGE_SIZE;
saleiferis 0:89ec48e52250 428
saleiferis 0:89ec48e52250 429 return (numberOfSamples);
saleiferis 0:89ec48e52250 430 }
saleiferis 0:89ec48e52250 431
saleiferis 0:89ec48e52250 432 //Report the most recent red value
saleiferis 0:89ec48e52250 433 uint32_t MAX86150::getRed(void)
saleiferis 0:89ec48e52250 434 {
saleiferis 0:89ec48e52250 435 //Check the sensor for new data for 250ms
saleiferis 0:89ec48e52250 436 if(safeCheck(250))
saleiferis 0:89ec48e52250 437 return (sense.red[sense.head]);
saleiferis 0:89ec48e52250 438 else
saleiferis 0:89ec48e52250 439 return(0); //Sensor failed to find new data
saleiferis 0:89ec48e52250 440 }
saleiferis 0:89ec48e52250 441
saleiferis 0:89ec48e52250 442 //Report the most recent IR value
saleiferis 0:89ec48e52250 443 uint32_t MAX86150::getIR(void)
saleiferis 0:89ec48e52250 444 {
saleiferis 0:89ec48e52250 445 //Check the sensor for new data for 250ms
saleiferis 0:89ec48e52250 446 if(safeCheck(250))
saleiferis 0:89ec48e52250 447 return (sense.IR[sense.head]);
saleiferis 0:89ec48e52250 448 else
saleiferis 0:89ec48e52250 449 return(0); //Sensor failed to find new data
saleiferis 0:89ec48e52250 450 }
saleiferis 0:89ec48e52250 451
saleiferis 0:89ec48e52250 452 //Report the most recent Green value
saleiferis 0:89ec48e52250 453 int32_t MAX86150::getECG(void)
saleiferis 0:89ec48e52250 454 {
saleiferis 0:89ec48e52250 455 //Check the sensor for new data for 250ms
saleiferis 0:89ec48e52250 456 if(safeCheck(250))
saleiferis 0:89ec48e52250 457 return (sense.ecg[sense.head]);
saleiferis 0:89ec48e52250 458 else
saleiferis 0:89ec48e52250 459 return(0); //Sensor failed to find new data
saleiferis 0:89ec48e52250 460 }
saleiferis 0:89ec48e52250 461
saleiferis 0:89ec48e52250 462 //Report the next Red value in the FIFO
saleiferis 0:89ec48e52250 463 uint32_t MAX86150::getFIFORed(void)
saleiferis 0:89ec48e52250 464 {
saleiferis 0:89ec48e52250 465 return (sense.red[sense.tail]);
saleiferis 0:89ec48e52250 466 }
saleiferis 0:89ec48e52250 467
saleiferis 0:89ec48e52250 468 //Report the next IR value in the FIFO
saleiferis 0:89ec48e52250 469 uint32_t MAX86150::getFIFOIR(void)
saleiferis 0:89ec48e52250 470 {
saleiferis 0:89ec48e52250 471 return (sense.IR[sense.tail]);
saleiferis 0:89ec48e52250 472 }
saleiferis 0:89ec48e52250 473
saleiferis 0:89ec48e52250 474 //Report the next Green value in the FIFO
saleiferis 0:89ec48e52250 475 int32_t MAX86150::getFIFOECG(void)
saleiferis 0:89ec48e52250 476 {
saleiferis 0:89ec48e52250 477 return (sense.ecg[sense.tail]);
saleiferis 0:89ec48e52250 478 }
saleiferis 0:89ec48e52250 479
saleiferis 0:89ec48e52250 480 //Advance the tail
saleiferis 0:89ec48e52250 481 void MAX86150::nextSample(void)
saleiferis 0:89ec48e52250 482 {
saleiferis 0:89ec48e52250 483 if(available()) //Only advance the tail if new data is available
saleiferis 0:89ec48e52250 484 {
saleiferis 0:89ec48e52250 485 sense.tail++;
saleiferis 0:89ec48e52250 486 sense.tail %= STORAGE_SIZE; //Wrap condition
saleiferis 0:89ec48e52250 487 }
saleiferis 0:89ec48e52250 488 }
saleiferis 0:89ec48e52250 489
saleiferis 0:89ec48e52250 490 //Polls the sensor for new data
saleiferis 0:89ec48e52250 491 //Call regularly
saleiferis 0:89ec48e52250 492 //If new data is available, it updates the head and tail in the main struct
saleiferis 0:89ec48e52250 493 //Returns number of new samples obtained
saleiferis 0:89ec48e52250 494 uint16_t MAX86150::check(void)
saleiferis 0:89ec48e52250 495 {
saleiferis 0:89ec48e52250 496 //pc.printf("In check() ...\n");
saleiferis 0:89ec48e52250 497 //Read register FIDO_DATA in (3-byte * number of active LED) chunks
saleiferis 0:89ec48e52250 498 //Until FIFO_RD_PTR = FIFO_WR_PTR
saleiferis 0:89ec48e52250 499 // pc.printf("SYSCONTROL REG: %x\n",readRegister8(_i2caddr, 0x0D));
saleiferis 0:89ec48e52250 500
saleiferis 0:89ec48e52250 501 uint8_t readPointer = getReadPointer();
saleiferis 0:89ec48e52250 502 uint8_t writePointer = getWritePointer();
saleiferis 0:89ec48e52250 503
saleiferis 0:89ec48e52250 504 int numberOfSamples = 0;
saleiferis 0:89ec48e52250 505
saleiferis 0:89ec48e52250 506 //Do we have new data?
saleiferis 0:89ec48e52250 507 if (readPointer != writePointer)
saleiferis 0:89ec48e52250 508 {
saleiferis 0:89ec48e52250 509 //pc.printf("Checking for new data...\n");
saleiferis 0:89ec48e52250 510 //Calculate the number of readings we need to get from sensor
saleiferis 0:89ec48e52250 511 numberOfSamples = writePointer - readPointer;
saleiferis 0:89ec48e52250 512 if (numberOfSamples < 0) numberOfSamples += 32; //Wrap condition
saleiferis 0:89ec48e52250 513 //pc.printf("Need to get %d samples\n", numberOfSamples);
saleiferis 0:89ec48e52250 514
saleiferis 0:89ec48e52250 515 //We now have the number of readings, now calc bytes to read
saleiferis 0:89ec48e52250 516 //For this example we are just doing Red and IR (3 bytes each)
saleiferis 0:89ec48e52250 517 int bytesLeftToRead = numberOfSamples * activeDevices * 3;
saleiferis 0:89ec48e52250 518
saleiferis 0:89ec48e52250 519 //pc.printf("There are %d bytes to read\n", bytesLeftToRead);
saleiferis 0:89ec48e52250 520
saleiferis 0:89ec48e52250 521 //Get ready to read a burst of data from the FIFO register
saleiferis 0:89ec48e52250 522 /*_i2cPort->beginTransmission(_i2caddr);
saleiferis 0:89ec48e52250 523 _i2cPort->write(MAX86150_FIFODATA);
saleiferis 0:89ec48e52250 524 _i2cPort->endTransmission();*/
saleiferis 0:89ec48e52250 525 char command[] = {MAX86150_FIFODATA};
saleiferis 0:89ec48e52250 526 _i2cPort->write(_i2caddr,command, 1);
saleiferis 0:89ec48e52250 527 //pc.printf("Sent write cmd to read new data\n");
saleiferis 0:89ec48e52250 528
saleiferis 0:89ec48e52250 529
saleiferis 0:89ec48e52250 530 //We may need to read as many as 288 bytes so we read in blocks no larger than I2C_BUFFER_LENGTH
saleiferis 0:89ec48e52250 531 //I2C_BUFFER_LENGTH changes based on the platform. 64 bytes for SAMD21, 32 bytes for Uno.
saleiferis 0:89ec48e52250 532 //Wire.requestFrom() is limited to BUFFER_LENGTH which is 32 on the Uno
saleiferis 0:89ec48e52250 533 while (bytesLeftToRead > 0)
saleiferis 0:89ec48e52250 534 {
saleiferis 0:89ec48e52250 535 int toGet = bytesLeftToRead;
saleiferis 0:89ec48e52250 536 if (toGet > I2C_BUFFER_LENGTH)
saleiferis 0:89ec48e52250 537 {
saleiferis 0:89ec48e52250 538 //If toGet is 32 this is bad because we read 6 bytes (Red+IR * 3 = 6) at a time
saleiferis 0:89ec48e52250 539 //32 % 6 = 2 left over. We don't want to request 32 bytes, we want to request 30.
saleiferis 0:89ec48e52250 540 //32 % 9 (Red+IR+GREEN) = 5 left over. We want to request 27.
saleiferis 0:89ec48e52250 541
saleiferis 0:89ec48e52250 542 toGet = I2C_BUFFER_LENGTH - (I2C_BUFFER_LENGTH % (activeDevices * 3)); //Trim toGet to be a multiple of the samples we need to read
saleiferis 0:89ec48e52250 543 }
saleiferis 0:89ec48e52250 544
saleiferis 0:89ec48e52250 545 bytesLeftToRead -= toGet;
saleiferis 0:89ec48e52250 546
saleiferis 0:89ec48e52250 547 //Request toGet number of bytes from sensor
saleiferis 0:89ec48e52250 548 //_i2cPort->requestFrom(_i2caddr, toGet);
saleiferis 0:89ec48e52250 549 char data[toGet];
saleiferis 0:89ec48e52250 550 char *p = data;
saleiferis 0:89ec48e52250 551 //pc.printf("Before reading FIFO data, toGet = %d\n",toGet);
saleiferis 0:89ec48e52250 552 _i2cPort->read(_i2caddr, data, toGet, false);
saleiferis 0:89ec48e52250 553 //_i2cPort->stop();
saleiferis 0:89ec48e52250 554 //pc.printf("Read FIFO data\n");
saleiferis 0:89ec48e52250 555
saleiferis 0:89ec48e52250 556
saleiferis 0:89ec48e52250 557
saleiferis 0:89ec48e52250 558 while (toGet > 0)
saleiferis 0:89ec48e52250 559 {
saleiferis 0:89ec48e52250 560 //pc.printf("In while loop\n\n");
saleiferis 0:89ec48e52250 561 sense.head++; //Advance the head of the storage struct
saleiferis 0:89ec48e52250 562 sense.head %= STORAGE_SIZE; //Wrap condition
saleiferis 0:89ec48e52250 563
saleiferis 0:89ec48e52250 564 uint8_t temp[sizeof(uint32_t)]; //Array of 4 bytes that we will convert into long
saleiferis 0:89ec48e52250 565 uint32_t tempLong;
saleiferis 0:89ec48e52250 566
saleiferis 0:89ec48e52250 567 //Burst read three bytes - RED
saleiferis 0:89ec48e52250 568 /*temp[3] = 0;
saleiferis 0:89ec48e52250 569 temp[2] = _i2cPort->read();
saleiferis 0:89ec48e52250 570 temp[1] = _i2cPort->read();
saleiferis 0:89ec48e52250 571 temp[0] = _i2cPort->read();*/
saleiferis 0:89ec48e52250 572 temp[3] = 0;
saleiferis 0:89ec48e52250 573 temp[2] = *p++;
saleiferis 0:89ec48e52250 574 temp[1] = *p++;
saleiferis 0:89ec48e52250 575 temp[0] = *p++;
saleiferis 0:89ec48e52250 576
saleiferis 0:89ec48e52250 577
saleiferis 0:89ec48e52250 578 //Convert array to long
saleiferis 0:89ec48e52250 579 memcpy(&tempLong, temp, sizeof(tempLong));
saleiferis 0:89ec48e52250 580
saleiferis 0:89ec48e52250 581 tempLong &= 0x7FFFF; //Zero out all but 18 bits
saleiferis 0:89ec48e52250 582
saleiferis 0:89ec48e52250 583 sense.red[sense.head] = tempLong; //Store this reading into the sense array
saleiferis 0:89ec48e52250 584
saleiferis 0:89ec48e52250 585 //pc.printf("Stored FIFO data into sense array\n");
saleiferis 0:89ec48e52250 586
saleiferis 0:89ec48e52250 587 if (activeDevices > 1)
saleiferis 0:89ec48e52250 588 {
saleiferis 0:89ec48e52250 589 //Burst read three more bytes - IR
saleiferis 0:89ec48e52250 590 /*temp[3] = 0;
saleiferis 0:89ec48e52250 591 temp[2] = _i2cPort->read();
saleiferis 0:89ec48e52250 592 temp[1] = _i2cPort->read();
saleiferis 0:89ec48e52250 593 temp[0] = _i2cPort->read();*/
saleiferis 0:89ec48e52250 594 temp[3] = 0;
saleiferis 0:89ec48e52250 595 temp[2] = *p++;
saleiferis 0:89ec48e52250 596 temp[1] = *p++;
saleiferis 0:89ec48e52250 597 temp[0] = *p++;
saleiferis 0:89ec48e52250 598
saleiferis 0:89ec48e52250 599
saleiferis 0:89ec48e52250 600 //Convert array to long
saleiferis 0:89ec48e52250 601 memcpy(&tempLong, temp, sizeof(tempLong));
saleiferis 0:89ec48e52250 602 //Serial.println(tempLong);
saleiferis 0:89ec48e52250 603 tempLong &= 0x7FFFF; //Zero out all but 18 bits
saleiferis 0:89ec48e52250 604
saleiferis 0:89ec48e52250 605 sense.IR[sense.head] = tempLong;
saleiferis 0:89ec48e52250 606 }
saleiferis 0:89ec48e52250 607
saleiferis 0:89ec48e52250 608 if (activeDevices > 2)
saleiferis 0:89ec48e52250 609 {
saleiferis 0:89ec48e52250 610 //Burst read three more bytes - ECG
saleiferis 0:89ec48e52250 611 int32_t tempLongSigned;
saleiferis 0:89ec48e52250 612
saleiferis 0:89ec48e52250 613 /*temp[3] = 0;
saleiferis 0:89ec48e52250 614 temp[2] = _i2cPort->read();
saleiferis 0:89ec48e52250 615 temp[1] = _i2cPort->read();
saleiferis 0:89ec48e52250 616 temp[0] = _i2cPort->read();
saleiferis 0:89ec48e52250 617 //Serial.println(tempLong);*/
saleiferis 0:89ec48e52250 618 temp[3] = 0;
saleiferis 0:89ec48e52250 619 temp[2] = *p++;
saleiferis 0:89ec48e52250 620 temp[1] = *p++;
saleiferis 0:89ec48e52250 621 temp[0] = *p++;
saleiferis 0:89ec48e52250 622
saleiferis 0:89ec48e52250 623 //Convert array to long
saleiferis 0:89ec48e52250 624 memcpy(&tempLongSigned, temp, sizeof(tempLongSigned));
saleiferis 0:89ec48e52250 625
saleiferis 0:89ec48e52250 626 //tempLong &= 0x3FFFF; //Zero out all but 18 bits
saleiferis 0:89ec48e52250 627
saleiferis 0:89ec48e52250 628 sense.ecg[sense.head] = tempLongSigned;
saleiferis 0:89ec48e52250 629 }
saleiferis 0:89ec48e52250 630
saleiferis 0:89ec48e52250 631 toGet -= activeDevices * 3;
saleiferis 0:89ec48e52250 632 }
saleiferis 0:89ec48e52250 633 } //End while (bytesLeftToRead > 0)
saleiferis 0:89ec48e52250 634 } //End readPtr != writePtr
saleiferis 0:89ec48e52250 635 return (numberOfSamples); //Let the world know how much new data we found
saleiferis 0:89ec48e52250 636 }
saleiferis 0:89ec48e52250 637
saleiferis 0:89ec48e52250 638 //Check for new data but give up after a certain amount of time
saleiferis 0:89ec48e52250 639 //Returns true if new data was found
saleiferis 0:89ec48e52250 640 //Returns false if new data was not found
saleiferis 0:89ec48e52250 641
saleiferis 0:89ec48e52250 642 bool MAX86150::safeCheck(uint8_t maxTimeToCheck)
saleiferis 0:89ec48e52250 643 {
saleiferis 0:89ec48e52250 644 //
saleiferis 0:89ec48e52250 645 //pc.printf("In safe checkk\n");
saleiferis 0:89ec48e52250 646 Timer t;
saleiferis 0:89ec48e52250 647 t.start();
saleiferis 0:89ec48e52250 648 uint32_t markTime = t.read();
saleiferis 0:89ec48e52250 649
saleiferis 0:89ec48e52250 650 while(1)
saleiferis 0:89ec48e52250 651 {
saleiferis 0:89ec48e52250 652 if(t.read() - markTime > maxTimeToCheck) return(false);
saleiferis 0:89ec48e52250 653
saleiferis 0:89ec48e52250 654 if(check() == true) //We found new data!
saleiferis 0:89ec48e52250 655 return(true);
saleiferis 0:89ec48e52250 656
saleiferis 0:89ec48e52250 657 wait_ms(1); //TODO: make it 1 again
saleiferis 0:89ec48e52250 658 }
saleiferis 0:89ec48e52250 659 }
saleiferis 0:89ec48e52250 660
saleiferis 0:89ec48e52250 661 //Given a register, read it, mask it, and then set the thing
saleiferis 0:89ec48e52250 662 void MAX86150::bitMask(uint8_t reg, uint8_t mask, uint8_t thing)
saleiferis 0:89ec48e52250 663 {
saleiferis 0:89ec48e52250 664 // Grab current register context
saleiferis 0:89ec48e52250 665 uint8_t originalContents = readRegister8(_i2caddr, reg);
saleiferis 0:89ec48e52250 666
saleiferis 0:89ec48e52250 667 // Zero-out the portions of the register we're interested in
saleiferis 0:89ec48e52250 668 originalContents = originalContents & mask;
saleiferis 0:89ec48e52250 669
saleiferis 0:89ec48e52250 670 // Change contents
saleiferis 0:89ec48e52250 671 writeRegister8(_i2caddr, reg, originalContents | thing);
saleiferis 0:89ec48e52250 672 }
saleiferis 0:89ec48e52250 673
saleiferis 0:89ec48e52250 674 uint8_t MAX86150::readRegister8(uint8_t address, uint8_t reg) {
saleiferis 0:89ec48e52250 675
saleiferis 0:89ec48e52250 676 /*
saleiferis 0:89ec48e52250 677 uint8_t tempData = 0;
saleiferis 0:89ec48e52250 678 _i2cPort->beginTransmission(address);
saleiferis 0:89ec48e52250 679 _i2cPort->write(reg);
saleiferis 0:89ec48e52250 680 _i2cPort->endTransmission(false);
saleiferis 0:89ec48e52250 681
saleiferis 0:89ec48e52250 682 _i2cPort->requestFrom((uint8_t)address, (uint8_t)1); // Request 1 byte
saleiferis 0:89ec48e52250 683 if (_i2cPort->available())
saleiferis 0:89ec48e52250 684 {
saleiferis 0:89ec48e52250 685
saleiferis 0:89ec48e52250 686 return(_i2cPort->read());
saleiferis 0:89ec48e52250 687 }
saleiferis 0:89ec48e52250 688 return (0); //Fail
saleiferis 0:89ec48e52250 689 */
saleiferis 0:89ec48e52250 690 int suc = 0;
saleiferis 0:89ec48e52250 691 char regData;
saleiferis 0:89ec48e52250 692 char writeData = reg;
saleiferis 0:89ec48e52250 693 _i2cPort->write(address,&writeData,1); //true is for repeated start
saleiferis 0:89ec48e52250 694 suc = _i2cPort->read(address,&regData,1);
saleiferis 0:89ec48e52250 695 //pc.printf("REad in lib was %d",suc);
saleiferis 0:89ec48e52250 696 return regData;
saleiferis 0:89ec48e52250 697
saleiferis 0:89ec48e52250 698 }
saleiferis 0:89ec48e52250 699
saleiferis 0:89ec48e52250 700 void MAX86150::writeRegister8(uint8_t address, uint8_t reg, uint8_t value) {
saleiferis 0:89ec48e52250 701
saleiferis 0:89ec48e52250 702 /*
saleiferis 0:89ec48e52250 703 _i2cPort->beginTransmission(address);
saleiferis 0:89ec48e52250 704 _i2cPort->write(reg);
saleiferis 0:89ec48e52250 705 _i2cPort->write(value);
saleiferis 0:89ec48e52250 706 _i2cPort->endTransmission();
saleiferis 0:89ec48e52250 707 */
saleiferis 0:89ec48e52250 708
saleiferis 0:89ec48e52250 709 //i2c.write(address, reg, 1);
saleiferis 0:89ec48e52250 710 /*writes 1 byte to a single register*/
saleiferis 0:89ec48e52250 711 char writeData[2];
saleiferis 0:89ec48e52250 712 writeData[0] = reg ;
saleiferis 0:89ec48e52250 713 writeData[1] = value;
saleiferis 0:89ec48e52250 714 _i2cPort->write(address,writeData, 2);
saleiferis 0:89ec48e52250 715
saleiferis 0:89ec48e52250 716 }