Chanel's edits

Dependencies:   max32630fthr USBDevice

Committer:
saleiferis
Date:
Wed Feb 12 07:35:43 2020 +0000
Revision:
1:6e6f7e3cc1e1
Parent:
0:89ec48e52250
Child:
4:4233f5538abf
WORKS

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 0:89ec48e52250 261 writeRegister8(_i2caddr, MAX86150_LED_PROX_AMP, 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 1:6e6f7e3cc1e1 369 wait_ms(2000);
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 0:89ec48e52250 373 writeRegister8(_i2caddr,MAX86150_FIFOCONFIG,0x7F);
saleiferis 0:89ec48e52250 374
saleiferis 0:89ec48e52250 375 //FIFO Configuration
saleiferis 0:89ec48e52250 376 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
saleiferis 0:89ec48e52250 377 //The chip will average multiple samples of same type together if you wish
saleiferis 0:89ec48e52250 378 if (sampleAverage == 1) setFIFOAverage(MAX86150_SAMPLEAVG_1); //No averaging per FIFO record
saleiferis 0:89ec48e52250 379 else if (sampleAverage == 2) setFIFOAverage(MAX86150_SAMPLEAVG_2);
saleiferis 0:89ec48e52250 380 else if (sampleAverage == 4) setFIFOAverage(MAX86150_SAMPLEAVG_4);
saleiferis 0:89ec48e52250 381 else if (sampleAverage == 8) setFIFOAverage(MAX86150_SAMPLEAVG_8);
saleiferis 0:89ec48e52250 382 else if (sampleAverage == 16) setFIFOAverage(MAX86150_SAMPLEAVG_16);
saleiferis 0:89ec48e52250 383 else if (sampleAverage == 32) setFIFOAverage(MAX86150_SAMPLEAVG_32);
saleiferis 0:89ec48e52250 384 else setFIFOAverage(MAX86150_SAMPLEAVG_4);
saleiferis 0:89ec48e52250 385
saleiferis 0:89ec48e52250 386 uint16_t FIFOCode = 0x00;
saleiferis 0:89ec48e52250 387
saleiferis 0:89ec48e52250 388 FIFOCode = FIFOCode<<4 | 0x0009;// : FIFOCode; //insert ECG front of ETI in FIFO
saleiferis 0:89ec48e52250 389 FIFOCode = FIFOCode<<8 | 0x0021;//) : FIFOCode; //insert Red(2) and IR (1) in front of ECG in FIFO
saleiferis 0:89ec48e52250 390
saleiferis 0:89ec48e52250 391
saleiferis 0:89ec48e52250 392 //FIFO Control 1 = FD2|FD1, FIFO Control 2 = FD4|FD3
saleiferis 0:89ec48e52250 393
saleiferis 0:89ec48e52250 394 writeRegister8(_i2caddr,MAX86150_FIFOCONTROL1,(0b00100001));
saleiferis 0:89ec48e52250 395 //writeRegister8(_i2caddr,MAX86150_FIFOCONTROL1,(0b00001001));
saleiferis 0:89ec48e52250 396 writeRegister8(_i2caddr,MAX86150_FIFOCONTROL2,(0b00001001));
saleiferis 0:89ec48e52250 397 //writeRegister8(_i2caddr,MAX86150_FIFOCONTROL2,(0b00000000));
saleiferis 0:89ec48e52250 398 //writeRegister8(_i2caddr,MAX86150_FIFOCONTROL1, (char)(FIFOCode & 0x00FF) );
saleiferis 0:89ec48e52250 399 //writeRegister8(_i2caddr,MAX86150_FIFOCONTROL2, (char)(FIFOCode >>8) );
saleiferis 0:89ec48e52250 400 //pc.printf("Set FIFO_CTRL1: %x\n", readRegister8(_i2caddr, MAX86150_FIFOCONTROL1));
saleiferis 0:89ec48e52250 401 //pc.printf("Set FIFO_CTRL2: %x\n", readRegister8(_i2caddr, MAX86150_FIFOCONTROL2));
saleiferis 0:89ec48e52250 402
saleiferis 0:89ec48e52250 403 writeRegister8(_i2caddr,MAX86150_PPGCONFIG1,0b11010111);
saleiferis 0:89ec48e52250 404 writeRegister8(_i2caddr,MAX86150_PPGCONFIG1,0b11100111);
saleiferis 0:89ec48e52250 405
saleiferis 0:89ec48e52250 406 writeRegister8(_i2caddr,MAX86150_PPGCONFIG2, 0x01);
saleiferis 0:89ec48e52250 407 writeRegister8(_i2caddr,MAX86150_LED_RANGE, 0x00 ); // PPG_ADC_RGE: 32768nA
saleiferis 0:89ec48e52250 408
saleiferis 0:89ec48e52250 409 //pc.printf("Before setting, SYS CTRL REG: %x\n",readRegister8(_i2caddr,MAX86150_SYSCONTROL));
saleiferis 0:89ec48e52250 410 //wait_ms(2000);
saleiferis 1:6e6f7e3cc1e1 411 writeRegister8(_i2caddr,MAX86150_SYSCONTROL,0x04);//start FIFO
saleiferis 0:89ec48e52250 412 //wait_ms(1000);
saleiferis 0:89ec48e52250 413 //pc.printf("Just set FIFO, SYS CTRL REG: %x\n",readRegister8(_i2caddr,MAX86150_SYSCONTROL));
saleiferis 0:89ec48e52250 414
saleiferis 0:89ec48e52250 415 writeRegister8(_i2caddr,MAX86150_ECG_CONFIG1,0b00000111);
saleiferis 0:89ec48e52250 416 writeRegister8(_i2caddr,MAX86150_ECG_CONFIG3,0b00001101);
saleiferis 0:89ec48e52250 417
saleiferis 0:89ec48e52250 418 setPulseAmplitudeRed(0xFF);
saleiferis 0:89ec48e52250 419 setPulseAmplitudeIR(0xFF);
saleiferis 0:89ec48e52250 420
saleiferis 0:89ec48e52250 421 //Multi-LED Mode Configuration, Enable the reading of the three LEDs
saleiferis 0:89ec48e52250 422 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
saleiferis 0:89ec48e52250 423 //enableSlot(1, SLOT_RED_LED);
saleiferis 0:89ec48e52250 424 //if (ledMode > 1)
saleiferis 0:89ec48e52250 425 //enableSlot(2, SLOT_IR_LED);
saleiferis 0:89ec48e52250 426 //if (ledMode > 2)
saleiferis 0:89ec48e52250 427 //enableSlot(3, SLOT_ECG);
saleiferis 0:89ec48e52250 428 //enableSlot(1, SLOT_RED_PILOT);
saleiferis 0:89ec48e52250 429 //enableSlot(2, SLOT_IR_PILOT);
saleiferis 0:89ec48e52250 430 //enableSlot(3, SLOT_GREEN_PILOT);
saleiferis 0:89ec48e52250 431 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
saleiferis 0:89ec48e52250 432 //enableFIFORollover();
saleiferis 0:89ec48e52250 433 clearFIFO(); //Reset the FIFO before we begin checking the sensor
saleiferis 0:89ec48e52250 434 writeRegister8(_i2caddr,MAX86150_SYSCONTROL,0x04);
saleiferis 1:6e6f7e3cc1e1 435 //wait_ms(1);
saleiferis 0:89ec48e52250 436 pc.printf("Cleared FIFO, SYS CTRL REG: %x\n",readRegister8(_i2caddr,MAX86150_SYSCONTROL));
saleiferis 0:89ec48e52250 437 }
saleiferis 0:89ec48e52250 438
saleiferis 0:89ec48e52250 439 //Tell caller how many samples are available
saleiferis 0:89ec48e52250 440 uint8_t MAX86150::available(void)
saleiferis 0:89ec48e52250 441 {
saleiferis 0:89ec48e52250 442 int8_t numberOfSamples = sense.head - sense.tail;
saleiferis 0:89ec48e52250 443 if (numberOfSamples < 0) numberOfSamples += STORAGE_SIZE;
saleiferis 0:89ec48e52250 444
saleiferis 0:89ec48e52250 445 return (numberOfSamples);
saleiferis 0:89ec48e52250 446 }
saleiferis 0:89ec48e52250 447
saleiferis 0:89ec48e52250 448 //Report the most recent red value
saleiferis 0:89ec48e52250 449 uint32_t MAX86150::getRed(void)
saleiferis 0:89ec48e52250 450 {
saleiferis 0:89ec48e52250 451 //Check the sensor for new data for 250ms
saleiferis 0:89ec48e52250 452 if(safeCheck(250))
saleiferis 0:89ec48e52250 453 return (sense.red[sense.head]);
saleiferis 0:89ec48e52250 454 else
saleiferis 0:89ec48e52250 455 return(0); //Sensor failed to find new data
saleiferis 0:89ec48e52250 456 }
saleiferis 0:89ec48e52250 457
saleiferis 0:89ec48e52250 458 //Report the most recent IR value
saleiferis 0:89ec48e52250 459 uint32_t MAX86150::getIR(void)
saleiferis 0:89ec48e52250 460 {
saleiferis 0:89ec48e52250 461 //Check the sensor for new data for 250ms
saleiferis 0:89ec48e52250 462 if(safeCheck(250))
saleiferis 0:89ec48e52250 463 return (sense.IR[sense.head]);
saleiferis 0:89ec48e52250 464 else
saleiferis 0:89ec48e52250 465 return(0); //Sensor failed to find new data
saleiferis 0:89ec48e52250 466 }
saleiferis 0:89ec48e52250 467
saleiferis 0:89ec48e52250 468 //Report the most recent Green value
saleiferis 0:89ec48e52250 469 int32_t MAX86150::getECG(void)
saleiferis 0:89ec48e52250 470 {
saleiferis 0:89ec48e52250 471 //Check the sensor for new data for 250ms
saleiferis 0:89ec48e52250 472 if(safeCheck(250))
saleiferis 0:89ec48e52250 473 return (sense.ecg[sense.head]);
saleiferis 0:89ec48e52250 474 else
saleiferis 0:89ec48e52250 475 return(0); //Sensor failed to find new data
saleiferis 0:89ec48e52250 476 }
saleiferis 0:89ec48e52250 477
saleiferis 0:89ec48e52250 478 //Report the next Red value in the FIFO
saleiferis 0:89ec48e52250 479 uint32_t MAX86150::getFIFORed(void)
saleiferis 0:89ec48e52250 480 {
saleiferis 0:89ec48e52250 481 return (sense.red[sense.tail]);
saleiferis 0:89ec48e52250 482 }
saleiferis 0:89ec48e52250 483
saleiferis 0:89ec48e52250 484 //Report the next IR value in the FIFO
saleiferis 0:89ec48e52250 485 uint32_t MAX86150::getFIFOIR(void)
saleiferis 0:89ec48e52250 486 {
saleiferis 0:89ec48e52250 487 return (sense.IR[sense.tail]);
saleiferis 0:89ec48e52250 488 }
saleiferis 0:89ec48e52250 489
saleiferis 0:89ec48e52250 490 //Report the next Green value in the FIFO
saleiferis 0:89ec48e52250 491 int32_t MAX86150::getFIFOECG(void)
saleiferis 0:89ec48e52250 492 {
saleiferis 0:89ec48e52250 493 return (sense.ecg[sense.tail]);
saleiferis 0:89ec48e52250 494 }
saleiferis 0:89ec48e52250 495
saleiferis 0:89ec48e52250 496 //Advance the tail
saleiferis 0:89ec48e52250 497 void MAX86150::nextSample(void)
saleiferis 0:89ec48e52250 498 {
saleiferis 0:89ec48e52250 499 if(available()) //Only advance the tail if new data is available
saleiferis 0:89ec48e52250 500 {
saleiferis 0:89ec48e52250 501 sense.tail++;
saleiferis 0:89ec48e52250 502 sense.tail %= STORAGE_SIZE; //Wrap condition
saleiferis 0:89ec48e52250 503 }
saleiferis 0:89ec48e52250 504 }
saleiferis 0:89ec48e52250 505
saleiferis 0:89ec48e52250 506 //Polls the sensor for new data
saleiferis 0:89ec48e52250 507 //Call regularly
saleiferis 0:89ec48e52250 508 //If new data is available, it updates the head and tail in the main struct
saleiferis 0:89ec48e52250 509 //Returns number of new samples obtained
saleiferis 0:89ec48e52250 510 uint16_t MAX86150::check(void)
saleiferis 0:89ec48e52250 511 {
saleiferis 0:89ec48e52250 512 //pc.printf("In check() ...\n");
saleiferis 0:89ec48e52250 513 //Read register FIDO_DATA in (3-byte * number of active LED) chunks
saleiferis 0:89ec48e52250 514 //Until FIFO_RD_PTR = FIFO_WR_PTR
saleiferis 0:89ec48e52250 515 // pc.printf("SYSCONTROL REG: %x\n",readRegister8(_i2caddr, 0x0D));
saleiferis 0:89ec48e52250 516
saleiferis 0:89ec48e52250 517 uint8_t readPointer = getReadPointer();
saleiferis 0:89ec48e52250 518 uint8_t writePointer = getWritePointer();
saleiferis 0:89ec48e52250 519
saleiferis 0:89ec48e52250 520 int numberOfSamples = 0;
saleiferis 0:89ec48e52250 521
saleiferis 0:89ec48e52250 522 //Do we have new data?
saleiferis 0:89ec48e52250 523 if (readPointer != writePointer)
saleiferis 0:89ec48e52250 524 {
saleiferis 0:89ec48e52250 525 //pc.printf("Checking for new data...\n");
saleiferis 0:89ec48e52250 526 //Calculate the number of readings we need to get from sensor
saleiferis 0:89ec48e52250 527 numberOfSamples = writePointer - readPointer;
saleiferis 0:89ec48e52250 528 if (numberOfSamples < 0) numberOfSamples += 32; //Wrap condition
saleiferis 0:89ec48e52250 529 //pc.printf("Need to get %d samples\n", numberOfSamples);
saleiferis 0:89ec48e52250 530
saleiferis 0:89ec48e52250 531 //We now have the number of readings, now calc bytes to read
saleiferis 0:89ec48e52250 532 //For this example we are just doing Red and IR (3 bytes each)
saleiferis 0:89ec48e52250 533 int bytesLeftToRead = numberOfSamples * activeDevices * 3;
saleiferis 0:89ec48e52250 534
saleiferis 0:89ec48e52250 535 //pc.printf("There are %d bytes to read\n", bytesLeftToRead);
saleiferis 0:89ec48e52250 536
saleiferis 0:89ec48e52250 537 //Get ready to read a burst of data from the FIFO register
saleiferis 0:89ec48e52250 538 /*_i2cPort->beginTransmission(_i2caddr);
saleiferis 0:89ec48e52250 539 _i2cPort->write(MAX86150_FIFODATA);
saleiferis 0:89ec48e52250 540 _i2cPort->endTransmission();*/
saleiferis 0:89ec48e52250 541 char command[] = {MAX86150_FIFODATA};
saleiferis 0:89ec48e52250 542 _i2cPort->write(_i2caddr,command, 1);
saleiferis 0:89ec48e52250 543 //pc.printf("Sent write cmd to read new data\n");
saleiferis 0:89ec48e52250 544
saleiferis 0:89ec48e52250 545
saleiferis 0:89ec48e52250 546 //We may need to read as many as 288 bytes so we read in blocks no larger than I2C_BUFFER_LENGTH
saleiferis 0:89ec48e52250 547 //I2C_BUFFER_LENGTH changes based on the platform. 64 bytes for SAMD21, 32 bytes for Uno.
saleiferis 0:89ec48e52250 548 //Wire.requestFrom() is limited to BUFFER_LENGTH which is 32 on the Uno
saleiferis 0:89ec48e52250 549 while (bytesLeftToRead > 0)
saleiferis 0:89ec48e52250 550 {
saleiferis 0:89ec48e52250 551 int toGet = bytesLeftToRead;
saleiferis 0:89ec48e52250 552 if (toGet > I2C_BUFFER_LENGTH)
saleiferis 0:89ec48e52250 553 {
saleiferis 0:89ec48e52250 554 //If toGet is 32 this is bad because we read 6 bytes (Red+IR * 3 = 6) at a time
saleiferis 0:89ec48e52250 555 //32 % 6 = 2 left over. We don't want to request 32 bytes, we want to request 30.
saleiferis 0:89ec48e52250 556 //32 % 9 (Red+IR+GREEN) = 5 left over. We want to request 27.
saleiferis 0:89ec48e52250 557
saleiferis 0:89ec48e52250 558 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 559 }
saleiferis 0:89ec48e52250 560
saleiferis 0:89ec48e52250 561 bytesLeftToRead -= toGet;
saleiferis 0:89ec48e52250 562
saleiferis 0:89ec48e52250 563 //Request toGet number of bytes from sensor
saleiferis 0:89ec48e52250 564 //_i2cPort->requestFrom(_i2caddr, toGet);
saleiferis 0:89ec48e52250 565 char data[toGet];
saleiferis 0:89ec48e52250 566 char *p = data;
saleiferis 0:89ec48e52250 567 //pc.printf("Before reading FIFO data, toGet = %d\n",toGet);
saleiferis 0:89ec48e52250 568 _i2cPort->read(_i2caddr, data, toGet, false);
saleiferis 0:89ec48e52250 569 //_i2cPort->stop();
saleiferis 0:89ec48e52250 570 //pc.printf("Read FIFO data\n");
saleiferis 0:89ec48e52250 571
saleiferis 0:89ec48e52250 572
saleiferis 0:89ec48e52250 573
saleiferis 0:89ec48e52250 574 while (toGet > 0)
saleiferis 0:89ec48e52250 575 {
saleiferis 0:89ec48e52250 576 //pc.printf("In while loop\n\n");
saleiferis 0:89ec48e52250 577 sense.head++; //Advance the head of the storage struct
saleiferis 0:89ec48e52250 578 sense.head %= STORAGE_SIZE; //Wrap condition
saleiferis 0:89ec48e52250 579
saleiferis 0:89ec48e52250 580 uint8_t temp[sizeof(uint32_t)]; //Array of 4 bytes that we will convert into long
saleiferis 0:89ec48e52250 581 uint32_t tempLong;
saleiferis 0:89ec48e52250 582
saleiferis 0:89ec48e52250 583 //Burst read three bytes - RED
saleiferis 0:89ec48e52250 584 /*temp[3] = 0;
saleiferis 0:89ec48e52250 585 temp[2] = _i2cPort->read();
saleiferis 0:89ec48e52250 586 temp[1] = _i2cPort->read();
saleiferis 0:89ec48e52250 587 temp[0] = _i2cPort->read();*/
saleiferis 0:89ec48e52250 588 temp[3] = 0;
saleiferis 0:89ec48e52250 589 temp[2] = *p++;
saleiferis 0:89ec48e52250 590 temp[1] = *p++;
saleiferis 0:89ec48e52250 591 temp[0] = *p++;
saleiferis 0:89ec48e52250 592
saleiferis 0:89ec48e52250 593
saleiferis 0:89ec48e52250 594 //Convert array to long
saleiferis 0:89ec48e52250 595 memcpy(&tempLong, temp, sizeof(tempLong));
saleiferis 0:89ec48e52250 596
saleiferis 0:89ec48e52250 597 tempLong &= 0x7FFFF; //Zero out all but 18 bits
saleiferis 0:89ec48e52250 598
saleiferis 0:89ec48e52250 599 sense.red[sense.head] = tempLong; //Store this reading into the sense array
saleiferis 0:89ec48e52250 600
saleiferis 0:89ec48e52250 601 //pc.printf("Stored FIFO data into sense array\n");
saleiferis 0:89ec48e52250 602
saleiferis 0:89ec48e52250 603 if (activeDevices > 1)
saleiferis 0:89ec48e52250 604 {
saleiferis 0:89ec48e52250 605 //Burst read three more bytes - IR
saleiferis 0:89ec48e52250 606 /*temp[3] = 0;
saleiferis 0:89ec48e52250 607 temp[2] = _i2cPort->read();
saleiferis 0:89ec48e52250 608 temp[1] = _i2cPort->read();
saleiferis 0:89ec48e52250 609 temp[0] = _i2cPort->read();*/
saleiferis 0:89ec48e52250 610 temp[3] = 0;
saleiferis 0:89ec48e52250 611 temp[2] = *p++;
saleiferis 0:89ec48e52250 612 temp[1] = *p++;
saleiferis 0:89ec48e52250 613 temp[0] = *p++;
saleiferis 0:89ec48e52250 614
saleiferis 0:89ec48e52250 615
saleiferis 0:89ec48e52250 616 //Convert array to long
saleiferis 0:89ec48e52250 617 memcpy(&tempLong, temp, sizeof(tempLong));
saleiferis 0:89ec48e52250 618 //Serial.println(tempLong);
saleiferis 0:89ec48e52250 619 tempLong &= 0x7FFFF; //Zero out all but 18 bits
saleiferis 0:89ec48e52250 620
saleiferis 0:89ec48e52250 621 sense.IR[sense.head] = tempLong;
saleiferis 0:89ec48e52250 622 }
saleiferis 0:89ec48e52250 623
saleiferis 0:89ec48e52250 624 if (activeDevices > 2)
saleiferis 0:89ec48e52250 625 {
saleiferis 0:89ec48e52250 626 //Burst read three more bytes - ECG
saleiferis 0:89ec48e52250 627 int32_t tempLongSigned;
saleiferis 0:89ec48e52250 628
saleiferis 0:89ec48e52250 629 /*temp[3] = 0;
saleiferis 0:89ec48e52250 630 temp[2] = _i2cPort->read();
saleiferis 0:89ec48e52250 631 temp[1] = _i2cPort->read();
saleiferis 0:89ec48e52250 632 temp[0] = _i2cPort->read();
saleiferis 0:89ec48e52250 633 //Serial.println(tempLong);*/
saleiferis 0:89ec48e52250 634 temp[3] = 0;
saleiferis 0:89ec48e52250 635 temp[2] = *p++;
saleiferis 0:89ec48e52250 636 temp[1] = *p++;
saleiferis 0:89ec48e52250 637 temp[0] = *p++;
saleiferis 0:89ec48e52250 638
saleiferis 0:89ec48e52250 639 //Convert array to long
saleiferis 0:89ec48e52250 640 memcpy(&tempLongSigned, temp, sizeof(tempLongSigned));
saleiferis 0:89ec48e52250 641
saleiferis 0:89ec48e52250 642 //tempLong &= 0x3FFFF; //Zero out all but 18 bits
saleiferis 0:89ec48e52250 643
saleiferis 0:89ec48e52250 644 sense.ecg[sense.head] = tempLongSigned;
saleiferis 0:89ec48e52250 645 }
saleiferis 0:89ec48e52250 646
saleiferis 0:89ec48e52250 647 toGet -= activeDevices * 3;
saleiferis 0:89ec48e52250 648 }
saleiferis 0:89ec48e52250 649 } //End while (bytesLeftToRead > 0)
saleiferis 0:89ec48e52250 650 } //End readPtr != writePtr
saleiferis 0:89ec48e52250 651 return (numberOfSamples); //Let the world know how much new data we found
saleiferis 0:89ec48e52250 652 }
saleiferis 0:89ec48e52250 653
saleiferis 0:89ec48e52250 654 //Check for new data but give up after a certain amount of time
saleiferis 0:89ec48e52250 655 //Returns true if new data was found
saleiferis 0:89ec48e52250 656 //Returns false if new data was not found
saleiferis 0:89ec48e52250 657
saleiferis 0:89ec48e52250 658 bool MAX86150::safeCheck(uint8_t maxTimeToCheck)
saleiferis 0:89ec48e52250 659 {
saleiferis 0:89ec48e52250 660 //
saleiferis 0:89ec48e52250 661 //pc.printf("In safe checkk\n");
saleiferis 0:89ec48e52250 662 Timer t;
saleiferis 0:89ec48e52250 663 t.start();
saleiferis 0:89ec48e52250 664 uint32_t markTime = t.read();
saleiferis 0:89ec48e52250 665
saleiferis 0:89ec48e52250 666 while(1)
saleiferis 0:89ec48e52250 667 {
saleiferis 0:89ec48e52250 668 if(t.read() - markTime > maxTimeToCheck) return(false);
saleiferis 0:89ec48e52250 669
saleiferis 0:89ec48e52250 670 if(check() == true) //We found new data!
saleiferis 0:89ec48e52250 671 return(true);
saleiferis 0:89ec48e52250 672
saleiferis 0:89ec48e52250 673 wait_ms(1); //TODO: make it 1 again
saleiferis 0:89ec48e52250 674 }
saleiferis 0:89ec48e52250 675 }
saleiferis 0:89ec48e52250 676
saleiferis 0:89ec48e52250 677 //Given a register, read it, mask it, and then set the thing
saleiferis 0:89ec48e52250 678 void MAX86150::bitMask(uint8_t reg, uint8_t mask, uint8_t thing)
saleiferis 0:89ec48e52250 679 {
saleiferis 0:89ec48e52250 680 // Grab current register context
saleiferis 0:89ec48e52250 681 uint8_t originalContents = readRegister8(_i2caddr, reg);
saleiferis 0:89ec48e52250 682
saleiferis 0:89ec48e52250 683 // Zero-out the portions of the register we're interested in
saleiferis 0:89ec48e52250 684 originalContents = originalContents & mask;
saleiferis 0:89ec48e52250 685
saleiferis 0:89ec48e52250 686 // Change contents
saleiferis 0:89ec48e52250 687 writeRegister8(_i2caddr, reg, originalContents | thing);
saleiferis 0:89ec48e52250 688 }
saleiferis 0:89ec48e52250 689
saleiferis 0:89ec48e52250 690 uint8_t MAX86150::readRegister8(uint8_t address, uint8_t reg) {
saleiferis 0:89ec48e52250 691
saleiferis 0:89ec48e52250 692 /*
saleiferis 0:89ec48e52250 693 uint8_t tempData = 0;
saleiferis 0:89ec48e52250 694 _i2cPort->beginTransmission(address);
saleiferis 0:89ec48e52250 695 _i2cPort->write(reg);
saleiferis 0:89ec48e52250 696 _i2cPort->endTransmission(false);
saleiferis 0:89ec48e52250 697
saleiferis 0:89ec48e52250 698 _i2cPort->requestFrom((uint8_t)address, (uint8_t)1); // Request 1 byte
saleiferis 0:89ec48e52250 699 if (_i2cPort->available())
saleiferis 0:89ec48e52250 700 {
saleiferis 0:89ec48e52250 701
saleiferis 0:89ec48e52250 702 return(_i2cPort->read());
saleiferis 0:89ec48e52250 703 }
saleiferis 0:89ec48e52250 704 return (0); //Fail
saleiferis 0:89ec48e52250 705 */
saleiferis 0:89ec48e52250 706 int suc = 0;
saleiferis 0:89ec48e52250 707 char regData;
saleiferis 0:89ec48e52250 708 char writeData = reg;
saleiferis 0:89ec48e52250 709 _i2cPort->write(address,&writeData,1); //true is for repeated start
saleiferis 0:89ec48e52250 710 suc = _i2cPort->read(address,&regData,1);
saleiferis 0:89ec48e52250 711 //pc.printf("REad in lib was %d",suc);
saleiferis 0:89ec48e52250 712 return regData;
saleiferis 0:89ec48e52250 713
saleiferis 0:89ec48e52250 714 }
saleiferis 0:89ec48e52250 715
saleiferis 0:89ec48e52250 716 void MAX86150::writeRegister8(uint8_t address, uint8_t reg, uint8_t value) {
saleiferis 0:89ec48e52250 717
saleiferis 0:89ec48e52250 718 /*
saleiferis 0:89ec48e52250 719 _i2cPort->beginTransmission(address);
saleiferis 0:89ec48e52250 720 _i2cPort->write(reg);
saleiferis 0:89ec48e52250 721 _i2cPort->write(value);
saleiferis 0:89ec48e52250 722 _i2cPort->endTransmission();
saleiferis 0:89ec48e52250 723 */
saleiferis 0:89ec48e52250 724
saleiferis 0:89ec48e52250 725 //i2c.write(address, reg, 1);
saleiferis 0:89ec48e52250 726 /*writes 1 byte to a single register*/
saleiferis 0:89ec48e52250 727 char writeData[2];
saleiferis 0:89ec48e52250 728 writeData[0] = reg ;
saleiferis 0:89ec48e52250 729 writeData[1] = value;
saleiferis 0:89ec48e52250 730 _i2cPort->write(address,writeData, 2);
saleiferis 0:89ec48e52250 731
saleiferis 0:89ec48e52250 732 }