zinnet yazıcı
/
max30105Example
maxrefdes117
Diff: MAX30105/MAX30105.cpp
- Revision:
- 0:78a2573ad768
diff -r 000000000000 -r 78a2573ad768 MAX30105/MAX30105.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MAX30105/MAX30105.cpp Tue Aug 06 12:19:46 2019 +0000 @@ -0,0 +1,781 @@ + +#include "mbed.h" +#include "MAX30105.h" +#include "millis.h" + + +//****************************************************************************** + +MAX30105::MAX30105(I2C &i2c): _i2c(i2c) +{ +} + +//****************************************************************************** + +int MAX30105::writeRegValue(uint8_t reg, char value) +{ + char cmdData[2] = { (char)reg, value }; + + if (_i2c.write(MAX30105_ADDRESS, cmdData, sizeof(cmdData)) != 0) { + return MAX30105_ERROR; + } + + return MAX30105_NO_ERROR; +} + +//****************************************************************************** + +int MAX30105::writeReg(uint8_t reg ) +{ + char cmdData[1] = { (char)reg }; + + if (_i2c.write(MAX30105_ADDRESS, cmdData, sizeof(cmdData)) != 0) { + return MAX30105_ERROR; + } + + return MAX30105_NO_ERROR; +} + + +//****************************************************************************** + +int MAX30105::readReg(uint8_t reg, char *value) +{ + char cmdData[1] = { (char)reg }; + + if (_i2c.write(MAX30105_ADDRESS, cmdData, sizeof(cmdData)) != 0) { + return MAX30105_ERROR; + } + + if (_i2c.read(MAX30105_ADDRESS, value, 1) != 0) { + return MAX30105_ERROR; + } + + return MAX30105_NO_ERROR; +} + + +//****************************************************************************** + +uint8_t MAX30105::readRegister8(uint8_t address, uint8_t reg){ + _i2c.write(reg); + char *data = new char[5]; + _i2c.read(address,data,5); + return (uint8_t)data; + +} + + +//****************************************************************************** +void MAX30105::writeRegister8(uint8_t address, uint8_t reg, uint8_t value){ + + writeRegValue(reg, value); + +} + + +//****************************************************************************** + +bool MAX30105::safeCheck(uint8_t maxTimeToCheck) +{ + uint32_t markTime = millis(); + + while(1) + { + if(millis() - markTime > maxTimeToCheck) return(false); + + if(check() == true) //We found new data! + return(true); + + wait(1); + } +} + + +//****************************************************************************** + +// NOTE: Amplitude values: 0x00 = 0mA, 0x7F = 25.4mA, 0xFF = 50mA (typical) +// See datasheet, page 21 +void MAX30105::setPulseAmplitudeRed(uint8_t amplitude) { + writeRegister8(_i2caddr, MAX30105_LED1_PULSEAMP, amplitude); +} + + +//****************************************************************************** + +void MAX30105::setPulseAmplitudeIR(uint8_t amplitude) { + writeRegister8(_i2caddr, MAX30105_LED2_PULSEAMP, amplitude); +} + + +//****************************************************************************** + +void MAX30105::setPulseAmplitudeGreen(uint8_t amplitude) { + writeRegister8(_i2caddr, MAX30105_LED3_PULSEAMP, amplitude); + + +} +//****************************************************************************** + +void MAX30105::setPulseAmplitudeProximity(uint8_t amplitude) { + writeRegister8(_i2caddr, MAX30105_LED_PROX_AMP, amplitude); +} +//Begin Interrupt configuration + + +//****************************************************************************** + +uint8_t MAX30105::getINT1(void) { + return (readRegister8(_i2caddr, MAX30105_INTSTAT1)); +} + +//****************************************************************************** + +uint8_t MAX30105::getINT2(void) { + return (readRegister8(_i2caddr, MAX30105_INTSTAT2)); +} + + +//****************************************************************************** + +void MAX30105::enableAFULL(void) { + bitMask(MAX30105_INTENABLE1, MAX30105_INT_A_FULL_MASK, MAX30105_INT_A_FULL_ENABLE); +} + + +//****************************************************************************** + +void MAX30105::disableAFULL(void) { + bitMask(MAX30105_INTENABLE1, MAX30105_INT_A_FULL_MASK, MAX30105_INT_A_FULL_DISABLE); +} + + +//****************************************************************************** + +void MAX30105::enableDATARDY(void) { + bitMask(MAX30105_INTENABLE1, MAX30105_INT_DATA_RDY_MASK, MAX30105_INT_DATA_RDY_ENABLE); +} + +//****************************************************************************** + +void MAX30105::disableDATARDY(void) { + bitMask(MAX30105_INTENABLE1, MAX30105_INT_DATA_RDY_MASK, MAX30105_INT_DATA_RDY_DISABLE); +} + + +//****************************************************************************** + +void MAX30105::enableALCOVF(void) { + bitMask(MAX30105_INTENABLE1, MAX30105_INT_ALC_OVF_MASK, MAX30105_INT_ALC_OVF_ENABLE); +} + +//****************************************************************************** + +void MAX30105::disableALCOVF(void) { + bitMask(MAX30105_INTENABLE1, MAX30105_INT_ALC_OVF_MASK, MAX30105_INT_ALC_OVF_DISABLE); +} + + +//****************************************************************************** + +void MAX30105::enablePROXINT(void) { + bitMask(MAX30105_INTENABLE1, MAX30105_INT_PROX_INT_MASK, MAX30105_INT_PROX_INT_ENABLE); +} + +//****************************************************************************** + +void MAX30105::disablePROXINT(void) { + bitMask(MAX30105_INTENABLE1, MAX30105_INT_PROX_INT_MASK, MAX30105_INT_PROX_INT_DISABLE); +} + + +//****************************************************************************** + +void MAX30105::enableDIETEMPRDY(void) { + bitMask(MAX30105_INTENABLE2, MAX30105_INT_DIE_TEMP_RDY_MASK, MAX30105_INT_DIE_TEMP_RDY_ENABLE); +} + +//****************************************************************************** + +void MAX30105::disableDIETEMPRDY(void) { + bitMask(MAX30105_INTENABLE2, MAX30105_INT_DIE_TEMP_RDY_MASK, MAX30105_INT_DIE_TEMP_RDY_DISABLE); +} + +//End Interrupt configuration +//****************************************************************************** + +void MAX30105::softReset(void) { + bitMask(MAX30105_MODECONFIG, MAX30105_RESET_MASK, MAX30105_RESET); + + // Poll for bit to clear, reset is then complete + // Timeout after 100ms + unsigned long startTime = millis(); + while (millis() - startTime < 100) + { + uint8_t response = readRegister8(_i2caddr, MAX30105_MODECONFIG); + if ((response & MAX30105_RESET) == 0) break; //We're done! + wait(1); //Let's not over burden the I2C bus + } +} + +//****************************************************************************** + +void MAX30105::shutDown(void) { + // Put IC into low power mode (datasheet pg. 19) + // During shutdown the IC will continue to respond to I2C commands but will + // not update with or take new readings (such as temperature) + bitMask(MAX30105_MODECONFIG, MAX30105_SHUTDOWN_MASK, MAX30105_SHUTDOWN); +} + + +//****************************************************************************** + +void MAX30105::wakeUp(void) { + // Pull IC out of low power mode (datasheet pg. 19) + bitMask(MAX30105_MODECONFIG, MAX30105_SHUTDOWN_MASK, MAX30105_WAKEUP); +} + + +//****************************************************************************** + +void MAX30105::setLEDMode(uint8_t mode) { + // Set which LEDs are used for sampling -- Red only, RED+IR only, or custom. + // See datasheet, page 19 + bitMask(MAX30105_MODECONFIG, MAX30105_MODE_MASK, mode); +} + + +//****************************************************************************** + +void MAX30105::setADCRange(uint8_t adcRange) { + // adcRange: one of MAX30105_ADCRANGE_2048, _4096, _8192, _16384 + bitMask(MAX30105_PARTICLECONFIG, MAX30105_ADCRANGE_MASK, adcRange); +} + + +//****************************************************************************** + +void MAX30105::setSampleRate(uint8_t sampleRate) { + // sampleRate: one of MAX30105_SAMPLERATE_50, _100, _200, _400, _800, _1000, _1600, _3200 + bitMask(MAX30105_PARTICLECONFIG, MAX30105_SAMPLERATE_MASK, sampleRate); +} + + +//****************************************************************************** + +void MAX30105::setPulseWidth(uint8_t pulseWidth) { + // pulseWidth: one of MAX30105_PULSEWIDTH_69, _188, _215, _411 + bitMask(MAX30105_PARTICLECONFIG, MAX30105_PULSEWIDTH_MASK, pulseWidth); +} + + +//****************************************************************************** + +void MAX30105::enableSlot(uint8_t slotNumber, uint8_t device) { + + uint8_t originalContents; + + switch (slotNumber) { + case (1): + bitMask(MAX30105_MULTILEDCONFIG1, MAX30105_SLOT1_MASK, device); + break; + case (2): + bitMask(MAX30105_MULTILEDCONFIG1, MAX30105_SLOT2_MASK, device << 4); + break; + case (3): + bitMask(MAX30105_MULTILEDCONFIG2, MAX30105_SLOT3_MASK, device); + break; + case (4): + bitMask(MAX30105_MULTILEDCONFIG2, MAX30105_SLOT4_MASK, device << 4); + break; + default: + //Shouldn't be here! + break; + } +} + + +//****************************************************************************** + +void MAX30105::disableSlots(void) { + writeRegister8(_i2caddr, MAX30105_MULTILEDCONFIG1, 0); + writeRegister8(_i2caddr, MAX30105_MULTILEDCONFIG2, 0); +} + +// +// FIFO Configuration +// + + +//****************************************************************************** + +//Set sample average (Table 3, Page 18) +void MAX30105::setFIFOAverage(uint8_t numberOfSamples) { + bitMask(MAX30105_FIFOCONFIG, MAX30105_SAMPLEAVG_MASK, numberOfSamples); +} + +//Resets all points to start in a known state +//Page 15 recommends clearing FIFO before beginning a read +void MAX30105::clearFIFO(void) { + writeRegister8(_i2caddr, MAX30105_FIFOWRITEPTR, 0); + writeRegister8(_i2caddr, MAX30105_FIFOOVERFLOW, 0); + writeRegister8(_i2caddr, MAX30105_FIFOREADPTR, 0); +} + + +//****************************************************************************** + +//Enable roll over if FIFO over flows +void MAX30105::enableFIFORollover(void) { + bitMask(MAX30105_FIFOCONFIG, MAX30105_ROLLOVER_MASK, MAX30105_ROLLOVER_ENABLE); +} + + +//****************************************************************************** + +//Disable roll over if FIFO over flows +void MAX30105::disableFIFORollover(void) { + bitMask(MAX30105_FIFOCONFIG, MAX30105_ROLLOVER_MASK, MAX30105_ROLLOVER_DISABLE); +} + +//****************************************************************************** + +//Set number of samples to trigger the almost full interrupt (Page 18) +//Power on default is 32 samples +//Note it is reverse: 0x00 is 32 samples, 0x0F is 17 samples +void MAX30105::setFIFOAlmostFull(uint8_t numberOfSamples) { + bitMask(MAX30105_FIFOCONFIG, MAX30105_A_FULL_MASK, numberOfSamples); +} + +//****************************************************************************** + +//Read the FIFO Write Pointer +uint8_t MAX30105::getWritePointer(void) { + return (readRegister8(_i2caddr, MAX30105_FIFOWRITEPTR)); +} + + +//****************************************************************************** + +//Read the FIFO Read Pointer +uint8_t MAX30105::getReadPointer(void) { + return (readRegister8(_i2caddr, MAX30105_FIFOREADPTR)); +} + +//****************************************************************************** + +float MAX30105::readTemperature() { + + //DIE_TEMP_RDY interrupt must be enabled + //See issue 19: https://github.com/sparkfun/SparkFun_MAX3010x_Sensor_Library/issues/19 + + // Step 1: Config die temperature register to take 1 temperature sample + writeRegister8(_i2caddr, MAX30105_DIETEMPCONFIG, 0x01); + + // Poll for bit to clear, reading is then complete + // Timeout after 100ms + unsigned long startTime = millis(); + while (millis() - startTime < 100) + { + //uint8_t response = readRegister8(_i2caddr, MAX30105_DIETEMPCONFIG); //Original way + //if ((response & 0x01) == 0) break; //We're done! + + //Check to see if DIE_TEMP_RDY interrupt is set + uint8_t response = readRegister8(_i2caddr, MAX30105_INTSTAT2); + if ((response & MAX30105_INT_DIE_TEMP_RDY_ENABLE) > 0) break; //We're done! + wait(1); //Let's not over burden the I2C bus + } + //TODO How do we want to fail? With what type of error? + //? if(millis() - startTime >= 100) return(-999.0); + + // Step 2: Read die temperature register (integer) + int8_t tempInt = readRegister8(_i2caddr, MAX30105_DIETEMPINT); + uint8_t tempFrac = readRegister8(_i2caddr, MAX30105_DIETEMPFRAC); //Causes the clearing of the DIE_TEMP_RDY interrupt + + // Step 3: Calculate temperature (datasheet pg. 23) + return (float)tempInt + ((float)tempFrac * 0.0625); +} + + +//****************************************************************************** + + +// Returns die temp in F +float MAX30105::readTemperatureF() { + float temp = readTemperature(); + + if (temp != -999.0) temp = temp * 1.8 + 32.0; + + return (temp); +} + + +//****************************************************************************** + + +// Set the PROX_INT_THRESHold +void MAX30105::setPROXINTTHRESH(uint8_t val) { + writeRegister8(_i2caddr, MAX30105_PROXINTTHRESH, val); +} + + +//****************************************************************************** + + +// +// Device ID and Revision +// +uint8_t MAX30105::readPartID() { + return readRegister8(_i2caddr, MAX30105_PARTID); +} + + +//****************************************************************************** + + +void MAX30105::readRevisionID() { + revisionID = readRegister8(_i2caddr, MAX30105_REVISIONID); +} + +//****************************************************************************** + + +uint8_t MAX30105::getRevisionID() { + return revisionID; +} + +//****************************************************************************** + + + +//Setup the sensor +//The MAX30105 has many settings. By default we select: +// Sample Average = 4 +// Mode = MultiLED +// ADC Range = 16384 (62.5pA per LSB) +// Sample rate = 50 +//Use the default setup if you are just getting started with the MAX30105 sensor +void MAX30105::setup(uint8_t powerLevel, uint8_t sampleAverage, uint8_t ledMode, int sampleRate, int pulseWidth, int adcRange) { + softReset(); //Reset all configuration, threshold, and data registers to POR values + + //FIFO Configuration + //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + //The chip will average multiple samples of same type together if you wish + if (sampleAverage == 1) setFIFOAverage(MAX30105_SAMPLEAVG_1); //No averaging per FIFO record + else if (sampleAverage == 2) setFIFOAverage(MAX30105_SAMPLEAVG_2); + else if (sampleAverage == 4) setFIFOAverage(MAX30105_SAMPLEAVG_4); + else if (sampleAverage == 8) setFIFOAverage(MAX30105_SAMPLEAVG_8); + else if (sampleAverage == 16) setFIFOAverage(MAX30105_SAMPLEAVG_16); + else if (sampleAverage == 32) setFIFOAverage(MAX30105_SAMPLEAVG_32); + else setFIFOAverage(MAX30105_SAMPLEAVG_4); + + //setFIFOAlmostFull(2); //Set to 30 samples to trigger an 'Almost Full' interrupt + enableFIFORollover(); //Allow FIFO to wrap/roll over + //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + + //Mode Configuration + //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + if (ledMode == 3) setLEDMode(MAX30105_MODE_MULTILED); //Watch all three LED channels + else if (ledMode == 2) setLEDMode(MAX30105_MODE_REDIRONLY); //Red and IR + else setLEDMode(MAX30105_MODE_REDONLY); //Red only + activeLEDs = ledMode; //Used to control how many uint8_ts to read from FIFO buffer + //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + + //Particle Sensing Configuration + //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + if(adcRange < 4096) setADCRange(MAX30105_ADCRANGE_2048); //7.81pA per LSB + else if(adcRange < 8192) setADCRange(MAX30105_ADCRANGE_4096); //15.63pA per LSB + else if(adcRange < 16384) setADCRange(MAX30105_ADCRANGE_8192); //31.25pA per LSB + else if(adcRange == 16384) setADCRange(MAX30105_ADCRANGE_16384); //62.5pA per LSB + else setADCRange(MAX30105_ADCRANGE_2048); + + if (sampleRate < 100) setSampleRate(MAX30105_SAMPLERATE_50); //Take 50 samples per second + else if (sampleRate < 200) setSampleRate(MAX30105_SAMPLERATE_100); + else if (sampleRate < 400) setSampleRate(MAX30105_SAMPLERATE_200); + else if (sampleRate < 800) setSampleRate(MAX30105_SAMPLERATE_400); + else if (sampleRate < 1000) setSampleRate(MAX30105_SAMPLERATE_800); + else if (sampleRate < 1600) setSampleRate(MAX30105_SAMPLERATE_1000); + else if (sampleRate < 3200) setSampleRate(MAX30105_SAMPLERATE_1600); + else if (sampleRate == 3200) setSampleRate(MAX30105_SAMPLERATE_3200); + else setSampleRate(MAX30105_SAMPLERATE_50); + + //The longer the pulse width the longer range of detection you'll have + //At 69us and 0.4mA it's about 2 inches + //At 411us and 0.4mA it's about 6 inches + if (pulseWidth < 118) setPulseWidth(MAX30105_PULSEWIDTH_69); //Page 26, Gets us 15 bit resolution + else if (pulseWidth < 215) setPulseWidth(MAX30105_PULSEWIDTH_118); //16 bit resolution + else if (pulseWidth < 411) setPulseWidth(MAX30105_PULSEWIDTH_215); //17 bit resolution + else if (pulseWidth == 411) setPulseWidth(MAX30105_PULSEWIDTH_411); //18 bit resolution + else setPulseWidth(MAX30105_PULSEWIDTH_69); + //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + + //LED Pulse Amplitude Configuration + //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + //Default is 0x1F which gets us 6.4mA + //powerLevel = 0x02, 0.4mA - Presence detection of ~4 inch + //powerLevel = 0x1F, 6.4mA - Presence detection of ~8 inch + //powerLevel = 0x7F, 25.4mA - Presence detection of ~8 inch + //powerLevel = 0xFF, 50.0mA - Presence detection of ~12 inch + + setPulseAmplitudeRed(powerLevel); + setPulseAmplitudeIR(powerLevel); + setPulseAmplitudeGreen(powerLevel); + setPulseAmplitudeProximity(powerLevel); + //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + + //Multi-LED Mode Configuration, Enable the reading of the three LEDs + //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + enableSlot(1, SLOT_RED_LED); + if (ledMode > 1) enableSlot(2, SLOT_IR_LED); + if (ledMode > 2) enableSlot(3, SLOT_GREEN_LED); + //enableSlot(1, SLOT_RED_PILOT); + //enableSlot(2, SLOT_IR_PILOT); + //enableSlot(3, SLOT_GREEN_PILOT); + //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + + clearFIFO(); //Reset the FIFO before we begin checking the sensor +} + +// +// Data Collection +// + +//Tell caller how many samples are available +uint8_t MAX30105::available(void) +{ + int8_t numberOfSamples = sense.head - sense.tail; + if (numberOfSamples < 0) numberOfSamples += STORAGE_SIZE; + + return (numberOfSamples); +} + +//****************************************************************************** + + +//Report the most recent red value +uint32_t MAX30105::getRed(void) +{ + //Check the sensor for new data for 250ms + if(safeCheck(250)) + return (sense.red[sense.head]); + else + return(0); //Sensor failed to find new data +} + + +//****************************************************************************** + + +//Report the most recent IR value +uint32_t MAX30105::getIR(void) +{ + //Check the sensor for new data for 250ms + if(safeCheck(250)) + return (sense.IR[sense.head]); + else + return(0); //Sensor failed to find new data +} + +//****************************************************************************** + + +//Report the most recent Green value +uint32_t MAX30105::getGreen(void) +{ + //Check the sensor for new data for 250ms + if(safeCheck(250)) + return (sense.green[sense.head]); + else + return(0); //Sensor failed to find new data +} + +//****************************************************************************** + + +//Report the next Red value in the FIFO +uint32_t MAX30105::getFIFORed(void) +{ + return (sense.red[sense.tail]); +} + + +//****************************************************************************** + +//Report the next IR value in the FIFO +uint32_t MAX30105::getFIFOIR(void) +{ + return (sense.IR[sense.tail]); +} + +//****************************************************************************** + + +//Report the next Green value in the FIFO +uint32_t MAX30105::getFIFOGreen(void) +{ + return (sense.green[sense.tail]); +} + +//****************************************************************************** + + +//Advance the tail +void MAX30105::nextSample(void) +{ + if(available()) //Only advance the tail if new data is available + { + sense.tail++; + sense.tail %= STORAGE_SIZE; //Wrap condition + } +} + +//****************************************************************************** + + +//Polls the sensor for new data +//Call regularly +//If new data is available, it updates the head and tail in the main struct +//Returns number of new samples obtained + +uint16_t MAX30105::check(void) +{ + /* + //Read register FIDO_DATA in (3-uint8_t * number of active LED) chunks + //Until FIFO_RD_PTR = FIFO_WR_PTR + + uint8_t readPointer = getReadPointer(); + uint8_t writePointer = getWritePointer(); + + int numberOfSamples = 0; + + //Do we have new data? + if (readPointer != writePointer) + { + //Calculate the number of readings we need to get from sensor + numberOfSamples = writePointer - readPointer; + if (numberOfSamples < 0) numberOfSamples += 32; //Wrap condition + + //We now have the number of readings, now calc uint8_ts to read + //For this example we are just doing Red and IR (3 uint8_ts each) + int uint8_tsLeftToRead = numberOfSamples * activeLEDs * 3; + + //Get ready to read a burst of data from the FIFO register + //buraya bak + _i2c.writeReg(MAX30105_FIFODATA); + + + //We may need to read as many as 288 uint8_ts so we read in blocks no larger than I2C_BUFFER_LENGTH + //I2C_BUFFER_LENGTH changes based on the platform. 64 uint8_ts for SAMD21, 32 uint8_ts for Uno. + //Wire.requestFrom() is limited to BUFFER_LENGTH which is 32 on the Uno + while (uint8_tsLeftToRead > 0) + { + int toGet = uint8_tsLeftToRead; + if (toGet > I2C_BUFFER_LENGTH) + { + //If toGet is 32 this is bad because we read 6 uint8_ts (Red+IR * 3 = 6) at a time + //32 % 6 = 2 left over. We don't want to request 32 uint8_ts, we want to request 30. + //32 % 9 (Red+IR+GREEN) = 5 left over. We want to request 27. + + toGet = I2C_BUFFER_LENGTH - (I2C_BUFFER_LENGTH % (activeLEDs * 3)); //Trim toGet to be a multiple of the samples we need to read + } + + uint8_tsLeftToRead -= toGet; + + //Request toGet number of uint8_ts from sensor + + //buraya bak + _i2c.requestFrom(MAX30105_ADDRESS, toGet); + + while (toGet > 0) + { + sense.head++; //Advance the head of the storage struct + sense.head %= STORAGE_SIZE; //Wrap condition + + uint8_t temp[sizeof(uint32_t)]; //Array of 4 uint8_ts that we will convert into long + uint32_t tempLong; + + //Burst read three uint8_ts - RED + + //buraya bak + + temp[3] = 0; + temp[2] = _i2cPort->read(); + temp[1] = _i2cPort->read(); + temp[0] = _i2cPort->read(); + + //Convert array to long + memcpy(&tempLong, temp, sizeof(tempLong)); + + tempLong &= 0x3FFFF; //Zero out all but 18 bits + + sense.red[sense.head] = tempLong; //Store this reading into the sense array + + if (activeLEDs > 1) + { + + //Burst read three more uint8_ts - IR + temp[3] = 0; + temp[2] = _i2cPort->read(); + temp[1] = _i2cPort->read(); + temp[0] = _i2cPort->read(); + + //Convert array to long + memcpy(&tempLong, temp, sizeof(tempLong)); + + tempLong &= 0x3FFFF; //Zero out all but 18 bits + + sense.IR[sense.head] = tempLong; + } + + if (activeLEDs > 2) + { + //Burst read three more uint8_ts - Green + + + temp[3] = 0; + temp[2] = _i2cPort->read(); + temp[1] = _i2cPort->read(); + temp[0] = _i2cPort->read(); + + //Convert array to long + memcpy(&tempLong, temp, sizeof(tempLong)); + + tempLong &= 0x3FFFF; //Zero out all but 18 bits + + sense.green[sense.head] = tempLong; + } + + toGet -= activeLEDs * 3; + } + + } //End while (uint8_tsLeftToRead > 0) + + } //End readPtr != writePtr + + return (numberOfSamples); //Let the world know how much new data we found + + */ +} + + +//****************************************************************************** + + +//Check for new data but give up after a certain amount of time +//Returns true if new data was found +//Returns false if new data was not found + + +//Given a register, read it, mask it, and then set the thing +void MAX30105::bitMask(uint8_t reg, uint8_t mask, uint8_t thing) +{ + // Grab current register context + uint8_t originalContents = readRegister8(_i2caddr, reg); + + // Zero-out the portions of the register we're interested in + originalContents = originalContents & mask; + + // Change contents + writeRegister8(_i2caddr, reg, originalContents | thing); +} +