Commit e48892c6 authored by Arist's avatar Arist
Browse files

fix(max86150): Get samples from FIFO by small junks

There is a recommendation from Maxim not to read the entire FIFO, but rather a fixed number of samples.
See https://os.mbed.com/users/laserdad/code/MAX86150_ECG_PPG//file/3c728f3d1f10/main.cpp/
+ Additional tuning for particular configuration of max86150 in card10 done by @jackie

.
Authored-by: Jakob's avatarJakob (XDjackieXD) Riepler <jakob.riepler@chaosfield.at>
parent 0fd6d958
......@@ -29,7 +29,7 @@ static const uint8_t MAX86150_FIFOREADPTR = 0x06;
static const uint8_t MAX86150_FIFODATA = 0x07;
static const uint8_t MAX86150_FIFOCONFIG = 0x08;
static const uint8_t MAX86150_FIFOCONTROL1= 0x09;
static const uint8_t MAX86150_FIFOCONTROL1 = 0x09;
static const uint8_t MAX86150_FIFOCONTROL2 = 0x0A;
static const uint8_t MAX86150_SYSCONTROL = 0x0D;
......@@ -65,78 +65,61 @@ static const uint8_t MAX86150_INT_PROX_INT_MASK = (byte)~0b00010000;
static const uint8_t MAX86150_INT_PROX_INT_ENABLE = 0x10;
static const uint8_t MAX86150_INT_PROX_INT_DISABLE = 0x00;
static const uint8_t MAX86150_SAMPLEAVG_MASK = (byte)~0b11100000;
static const uint8_t MAX86150_SAMPLEAVG_1 = 0x00;
static const uint8_t MAX86150_SAMPLEAVG_2 = 0x20;
static const uint8_t MAX86150_SAMPLEAVG_4 = 0x40;
static const uint8_t MAX86150_SAMPLEAVG_8 = 0x60;
static const uint8_t MAX86150_SAMPLEAVG_16 = 0x80;
static const uint8_t MAX86150_SAMPLEAVG_32 = 0xA0;
static const uint8_t MAX86150_ROLLOVER_MASK = 0xEF;
static const uint8_t MAX86150_ROLLOVER_ENABLE = 0x10;
static const uint8_t MAX86150_ROLLOVER_DISABLE = 0x00;
static const uint8_t MAX86150_A_FULL_MASK = 0xF0;
static const uint8_t MAX86150_SHUTDOWN_MASK = 0x7F;
static const uint8_t MAX86150_SHUTDOWN = 0x80;
static const uint8_t MAX86150_WAKEUP = 0x00;
static const uint8_t MAX86150_RESET_MASK = 0xFE;
static const uint8_t MAX86150_RESET = 0x01;
static const uint8_t MAX86150_MODE_MASK = 0xF8;
static const uint8_t MAX86150_MODE_REDONLY = 0x02;
static const uint8_t MAX86150_MODE_REDIRONLY = 0x03;
static const uint8_t MAX86150_MODE_MULTILED = 0x07;
static const uint8_t MAX86150_ADCRANGE_MASK = 0x9F;
static const uint8_t MAX86150_ADCRANGE_2048 = 0x00;
static const uint8_t MAX86150_ADCRANGE_4096 = 0x20;
static const uint8_t MAX86150_ADCRANGE_8192 = 0x40;
static const uint8_t MAX86150_ADCRANGE_16384 = 0x60;
static const uint8_t MAX86150_SAMPLERATE_MASK = 0xE3;
static const uint8_t MAX86150_SAMPLERATE_50 = 0x00;
static const uint8_t MAX86150_SAMPLERATE_100 = 0x04;
static const uint8_t MAX86150_SAMPLERATE_200 = 0x08;
static const uint8_t MAX86150_SAMPLERATE_400 = 0x0C;
static const uint8_t MAX86150_SAMPLERATE_800 = 0x10;
static const uint8_t MAX86150_SAMPLERATE_1000 = 0x14;
static const uint8_t MAX86150_SAMPLERATE_1600 = 0x18;
static const uint8_t MAX86150_SAMPLERATE_3200 = 0x1C;
static const uint8_t MAX86150_PULSEWIDTH_MASK = 0xFC;
static const uint8_t MAX86150_PULSEWIDTH_69 = 0x00;
static const uint8_t MAX86150_PULSEWIDTH_118 = 0x01;
static const uint8_t MAX86150_PULSEWIDTH_215 = 0x02;
static const uint8_t MAX86150_PULSEWIDTH_411 = 0x03;
static const uint8_t MAX86150_SAMPLEAVG_MASK = (byte)~0b00000111;
static const uint8_t MAX86150_ROLLOVER_MASK = (byte)~0b00010000;
static const uint8_t MAX86150_ROLLOVER_ENABLE = 0b00010000;
static const uint8_t MAX86150_ROLLOVER_DISABLE = 0b00000000;
static const uint8_t MAX86150_ALMOST_FULL_CLEAR_MASK = (byte)~0b01000000;
static const uint8_t MAX86150_ALMOST_FULL_CLEAR_ENABLE = 0b01000000;
static const uint8_t MAX86150_ALMOST_FULL_CLEAR_DISABLE = 0b00000000;
static const uint8_t MAX86150_ALMOST_FULL_REPEAT_MASK = (byte)~0b00100000;
static const uint8_t MAX86150_ALMOST_FULL_REPEAT_ENABLE = 0b00100000;
static const uint8_t MAX86150_ALMOST_FULL_REPEAT_DISABLE = 0b00000000;
static const uint8_t MAX86150_A_FULL_MASK = (byte)~0b00001111;
static const uint8_t MAX86150_SHUTDOWN_MASK = (byte)~0b00000010;
static const uint8_t MAX86150_SHUTDOWN = 0b10;
static const uint8_t MAX86150_WAKEUP = 0b00;
static const uint8_t MAX86150_FIFO_ENABLE_MASK = (byte)~0b00000100;
static const uint8_t MAX86150_FIFO_ENABLE = 0b100;
static const uint8_t MAX86150_FIFO_DISABLE = 0b000;
static const uint8_t MAX86150_RESET_MASK = (byte)~0b00000001;
static const uint8_t MAX86150_RESET = 0b1;
static const uint8_t MAX86150_ADCRANGE_MASK = (byte)~0b11000000;
static const uint8_t MAX86150_PPG_SAMPLERATE_MASK = (byte)~0b00111100;
static const uint8_t MAX86150_PPG_PULSEWIDTH_MASK = (byte)~0b00000011;
static const uint8_t MAX86150_SLOT1_MASK = 0xF0;
static const uint8_t MAX86150_SLOT2_MASK = 0x0F;
static const uint8_t MAX86150_SLOT3_MASK = 0xF0;
static const uint8_t MAX86150_SLOT4_MASK = 0x0F;
static const uint8_t SLOT_NONE = 0x00;
static const uint8_t SLOT_RED_LED = 0x01;
static const uint8_t SLOT_IR_LED = 0x02;
static const uint8_t SLOT_RED_PILOT = 0x09;
static const uint8_t SLOT_IR_PILOT = 0x0A;
static const uint8_t SLOT_ECG = 0x0D;
static const uint8_t MAX86150_LED1_RANGE_MASK = (byte)~0b00000011;
static const uint8_t MAX86150_LED2_RANGE_MASK = (byte)~0b00001100;
static const uint8_t MAX_30105_EXPECTEDPARTID = 0x1E;
static const uint8_t MAX86150_ECG_SAMPLERATE_MASK = (byte)~0b00000111;
static uint8_t _i2caddr;
static const uint8_t MAX86150_ECG_PGA_GAIN_MASK = (byte)~0b00001100;
//activeLEDs is the number of channels turned on, and can be 1 to 3. 2 is common for Red+IR.
static byte activeDevices; //Gets set during max86150_setup. Allows max86150_check() to calculate how many bytes to read from FIFO
static const uint8_t MAX86150_ECG_IA_GAIN_MASK = (byte)~0b00000011;
static void max86150_bitMask(uint8_t reg, uint8_t mask, uint8_t thing);
static const uint8_t MAX86150_EXPECTEDPARTID = 0x1E;
#define STORAGE_SIZE 128 //Each long is 4 bytes so limit this to fit on your micro
typedef struct Record
{
static byte activeDevices =
3; //Gets set during max86150_setup. Allows max86150_check() to calculate how many bytes to read from FIFO
#define STORAGE_SIZE \
128 //Each long is 4 bytes so limit this to fit on your micro
typedef struct Record {
uint32_t red[STORAGE_SIZE];
uint32_t IR[STORAGE_SIZE];
int32_t ecg[STORAGE_SIZE];
......@@ -153,11 +136,9 @@ static void delay(int ms)
bool max86150_begin(void)
{
_i2caddr = MAX86150_ADDRESS;
// Step 1: Initial Communication and Verification
// Check that a MAX86150 is connected
if (max86150_readPartID() != MAX_30105_EXPECTEDPARTID) {
if (max86150_read_part_id() != MAX86150_EXPECTEDPARTID) {
// Error -- Part ID read from MAX86150 does not match expected part ID.
// This may mean there is a physical connectivity problem (broken wire, unpowered, etc).
return false;
......@@ -170,133 +151,234 @@ bool max86150_begin(void)
//
//Begin Interrupt configuration
uint8_t max86150_getINT1(void)
uint8_t max86150_get_int1(void)
{
return (max86150_readRegister8(_i2caddr, MAX86150_INTSTAT1));
return (max86150_read_register(MAX86150_ADDRESS, MAX86150_INTSTAT1));
}
uint8_t max86150_getINT2(void) {
return (max86150_readRegister8(_i2caddr, MAX86150_INTSTAT2));
uint8_t max86150_get_int2(void)
{
return (max86150_read_register(MAX86150_ADDRESS, MAX86150_INTSTAT2));
}
void max86150_enableAFULL(void) {
max86150_bitMask(MAX86150_INTENABLE1, MAX86150_INT_A_FULL_MASK, MAX86150_INT_A_FULL_ENABLE);
}
void max86150_disableAFULL(void) {
max86150_bitMask(MAX86150_INTENABLE1, MAX86150_INT_A_FULL_MASK, MAX86150_INT_A_FULL_DISABLE);
void max86150_set_int_full(bool enabled)
{
if (enabled) {
max86150_bit_mask(
MAX86150_INTENABLE1,
MAX86150_INT_A_FULL_MASK,
MAX86150_INT_A_FULL_ENABLE
);
} else {
max86150_bit_mask(
MAX86150_INTENABLE1,
MAX86150_INT_A_FULL_MASK,
MAX86150_INT_A_FULL_DISABLE
);
}
}
void max86150_enableDATARDY(void) {
max86150_bitMask(MAX86150_INTENABLE1, MAX86150_INT_DATA_RDY_MASK, MAX86150_INT_DATA_RDY_ENABLE);
}
void max86150_disableDATARDY(void) {
max86150_bitMask(MAX86150_INTENABLE1, MAX86150_INT_DATA_RDY_MASK, MAX86150_INT_DATA_RDY_DISABLE);
void max86150_set_int_datardy(bool enabled)
{
if (enabled) {
max86150_bit_mask(
MAX86150_INTENABLE1,
MAX86150_INT_DATA_RDY_MASK,
MAX86150_INT_DATA_RDY_ENABLE
);
} else {
max86150_bit_mask(
MAX86150_INTENABLE1,
MAX86150_INT_DATA_RDY_MASK,
MAX86150_INT_DATA_RDY_DISABLE
);
}
}
void max86150_enableALCOVF(void) {
max86150_bitMask(MAX86150_INTENABLE1, MAX86150_INT_ALC_OVF_MASK, MAX86150_INT_ALC_OVF_ENABLE);
}
void max86150_disableALCOVF(void) {
max86150_bitMask(MAX86150_INTENABLE1, MAX86150_INT_ALC_OVF_MASK, MAX86150_INT_ALC_OVF_DISABLE);
void max86150_set_int_ambient_light_overflow(bool enabled)
{
if (enabled) {
max86150_bit_mask(
MAX86150_INTENABLE1,
MAX86150_INT_ALC_OVF_MASK,
MAX86150_INT_ALC_OVF_ENABLE
);
} else {
max86150_bit_mask(
MAX86150_INTENABLE1,
MAX86150_INT_ALC_OVF_MASK,
MAX86150_INT_ALC_OVF_DISABLE
);
}
}
void max86150_enablePROXINT(void) {
max86150_bitMask(MAX86150_INTENABLE1, MAX86150_INT_PROX_INT_MASK, MAX86150_INT_PROX_INT_ENABLE);
}
void max86150_disablePROXINT(void) {
max86150_bitMask(MAX86150_INTENABLE1, MAX86150_INT_PROX_INT_MASK, MAX86150_INT_PROX_INT_DISABLE);
void max86150_set_int_proximity(bool enabled)
{
if (enabled) {
max86150_bit_mask(
MAX86150_INTENABLE1,
MAX86150_INT_PROX_INT_MASK,
MAX86150_INT_PROX_INT_ENABLE
);
} else {
max86150_bit_mask(
MAX86150_INTENABLE1,
MAX86150_INT_PROX_INT_MASK,
MAX86150_INT_PROX_INT_DISABLE
);
}
}
//End Interrupt configuration
void max86150_softReset(void) {
max86150_bitMask(MAX86150_SYSCONTROL, MAX86150_RESET_MASK, MAX86150_RESET);
void max86150_soft_reset(void)
{
max86150_bit_mask(
MAX86150_SYSCONTROL, MAX86150_RESET_MASK, MAX86150_RESET
);
// Poll for bit to clear, reset is then complete
// Timeout after 100ms
//TODO
//unsigned long startTime = millis();
//while (millis() - startTime < 100)
{
//uint8_t response = max86150_readRegister8(_i2caddr, MAX86150_SYSCONTROL);
//if ((response & MAX86150_RESET) == 0) break; //We're done!
// Timeout after 100 tries
uint8_t tries = 0;
while (tries < 100) {
uint8_t response = max86150_read_register(
MAX86150_ADDRESS, MAX86150_SYSCONTROL
);
if ((response & MAX86150_RESET) == 0)
break; //We're done!
tries++;
delay(1); //Let's not over burden the I2C bus
}
}
void max86150_shutDown(void) {
void max86150_shut_down(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)
max86150_bitMask(MAX86150_SYSCONTROL, MAX86150_SHUTDOWN_MASK, MAX86150_SHUTDOWN);
max86150_bit_mask(
MAX86150_SYSCONTROL, MAX86150_SHUTDOWN_MASK, MAX86150_SHUTDOWN
);
}
void max86150_wakeUp(void) {
void max86150_wake_up(void)
{
// Pull IC out of low power mode (datasheet pg. 19)
max86150_bitMask(MAX86150_SYSCONTROL, MAX86150_SHUTDOWN_MASK, MAX86150_WAKEUP);
max86150_bit_mask(
MAX86150_SYSCONTROL, MAX86150_SHUTDOWN_MASK, MAX86150_WAKEUP
);
}
void max86150_setLEDMode(uint8_t mode) {
// Set which LEDs are used for sampling -- Red only, RED+IR only, or custom.
// See datasheet, page 19
//max86150_bitMask(MAX86150_PPGCONFIG1, MAX86150_MODE_MASK, mode);
void max86150_set_fifo_enable(bool enabled)
{
if (enabled) {
max86150_bit_mask(
MAX86150_SYSCONTROL,
MAX86150_FIFO_ENABLE_MASK,
MAX86150_FIFO_ENABLE
);
} else {
max86150_bit_mask(
MAX86150_SYSCONTROL,
MAX86150_FIFO_ENABLE_MASK,
MAX86150_FIFO_DISABLE
);
}
}
void max86150_setADCRange(uint8_t adcRange) {
// adcRange: one of MAX86150_ADCRANGE_2048, _4096, _8192, _16384
//max86150_bitMask(MAX86150_PARTICLECONFIG, MAX86150_ADCRANGE_MASK, adcRange);
void max86150_set_ppg_adc_range(uint8_t adcRange)
{
// adcRange: one of MAX86150_ADCRANGE_*
max86150_bit_mask(
MAX86150_PPGCONFIG1, MAX86150_ADCRANGE_MASK, adcRange
);
}
void max86150_setSampleRate(uint8_t sampleRate) {
// sampleRate: one of MAX86150_SAMPLERATE_50, _100, _200, _400, _800, _1000, _1600, _3200
//max86150_bitMask(MAX86150_PARTICLECONFIG, MAX86150_SAMPLERATE_MASK, sampleRate);
void max86150_set_ppg_sample_rate(uint8_t sampleRate)
{
// sampleRate: one of MAX86150_PPG_SAMPLERATE_*
max86150_bit_mask(
MAX86150_PPGCONFIG1, MAX86150_PPG_SAMPLERATE_MASK, sampleRate
);
}
void max86150_setPulseWidth(uint8_t pulseWidth) {
// pulseWidth: one of MAX86150_PULSEWIDTH_69, _188, _215, _411
//max86150_bitMask(MAX86150_PPGCONFIG1, MAX86150_PULSEWIDTH_MASK, pulseWidth);
void max86150_set_ppg_pulse_width(uint8_t pulseWidth)
{
// pulseWidth: one of MAX86150_PPG_PULSEWIDTH_*
max86150_bit_mask(
MAX86150_PPGCONFIG1, MAX86150_PPG_PULSEWIDTH_MASK, pulseWidth
);
}
// NOTE: Amplitude values: 0x00 = 0mA, 0x7F = 25.4mA, 0xFF = 50mA (typical)
// See datasheet, page 21
void max86150_setPulseAmplitudeRed(uint8_t amplitude)
void max86150_set_led_red_amplitude(uint8_t amplitude)
{
max86150_writeRegister8(_i2caddr, MAX86150_LED2_PULSEAMP, amplitude);
max86150_write_register(
MAX86150_ADDRESS, MAX86150_LED2_PULSEAMP, amplitude
);
max86150_bit_mask(
MAX86150_LED_RANGE,
MAX86150_LED2_RANGE_MASK,
MAX86150_LED2_RANGE_50
);
}
void max86150_setPulseAmplitudeIR(uint8_t amplitude)
void max86150_set_led_ir_amplitude(uint8_t amplitude)
{
max86150_writeRegister8(_i2caddr, MAX86150_LED1_PULSEAMP, amplitude);
max86150_write_register(
MAX86150_ADDRESS, MAX86150_LED1_PULSEAMP, amplitude
);
max86150_bit_mask(
MAX86150_LED_RANGE,
MAX86150_LED1_RANGE_MASK,
MAX86150_LED1_RANGE_50
);
}
void max86150_setPulseAmplitudeProximity(uint8_t amplitude) {
max86150_writeRegister8(_i2caddr, MAX86150_LED_PROX_AMP, amplitude);
void max86150_set_led_proximity_amplitude(uint8_t amplitude)
{
max86150_write_register(
MAX86150_ADDRESS, MAX86150_LED_PROX_AMP, amplitude
);
}
void max86150_setProximityThreshold(uint8_t threshMSB)
void max86150_set_proximity_threshold(uint8_t threshMSB)
{
// The threshMSB signifies only the 8 most significant-bits of the ADC count.
max86150_writeRegister8(_i2caddr, MAX86150_PROXINTTHRESH, threshMSB);
max86150_write_register(
MAX86150_ADDRESS, MAX86150_PROXINTTHRESH, threshMSB
);
}
//Given a slot number assign a thing to it
//Devices are SLOT_RED_LED or SLOT_RED_PILOT (proximity)
//Assigning a SLOT_RED_LED will pulse LED
//Assigning a SLOT_RED_PILOT will ??
void max86150_enableSlot(uint8_t slotNumber, uint8_t device)
void max86150_fifo_enable_slot(uint8_t slotNumber, uint8_t device)
{
//uint8_t originalContents;
switch (slotNumber) {
case (1):
max86150_bitMask(MAX86150_FIFOCONTROL1, MAX86150_SLOT1_MASK, device);
max86150_bit_mask(
MAX86150_FIFOCONTROL1, MAX86150_SLOT1_MASK, device
);
break;
case (2):
max86150_bitMask(MAX86150_FIFOCONTROL1, MAX86150_SLOT2_MASK, device << 4);
max86150_bit_mask(
MAX86150_FIFOCONTROL1,
MAX86150_SLOT2_MASK,
device << 4
);
break;
case (3):
max86150_bitMask(MAX86150_FIFOCONTROL2, MAX86150_SLOT3_MASK, device);
max86150_bit_mask(
MAX86150_FIFOCONTROL2, MAX86150_SLOT3_MASK, device
);
break;
case (4):
max86150_bitMask(MAX86150_FIFOCONTROL2, MAX86150_SLOT4_MASK, device << 4);
max86150_bit_mask(
MAX86150_FIFOCONTROL2,
MAX86150_SLOT4_MASK,
device << 4
);
break;
default:
//Shouldn't be here!
......@@ -307,202 +389,292 @@ void max86150_enableSlot(uint8_t slotNumber, uint8_t device)
//Clears all slot assignments
void max86150_disableSlots(void)
{
max86150_writeRegister8(_i2caddr, MAX86150_FIFOCONTROL1, 0);
max86150_writeRegister8(_i2caddr, MAX86150_FIFOCONTROL2, 0);
max86150_write_register(MAX86150_ADDRESS, MAX86150_FIFOCONTROL1, 0);
max86150_write_register(MAX86150_ADDRESS, MAX86150_FIFOCONTROL2, 0);
}
//
// FIFO Configuration
//
void max86150_setFIFOAverage(uint8_t numberOfSamples)
void max86150_set_ppg_averaging(uint8_t numberOfSamples)
{
max86150_bitMask(MAX86150_FIFOCONFIG, MAX86150_SAMPLEAVG_MASK, numberOfSamples);
max86150_bit_mask(
MAX86150_FIFOCONFIG, MAX86150_SAMPLEAVG_MASK, numberOfSamples
);
}
//Resets all points to start in a known state
void max86150_clearFIFO(void) {
max86150_writeRegister8(_i2caddr, MAX86150_FIFOWRITEPTR, 0);
max86150_writeRegister8(_i2caddr, MAX86150_FIFOOVERFLOW, 0);
max86150_writeRegister8(_i2caddr, MAX86150_FIFOREADPTR, 0);
void max86150_clear_fifo(void)
{
max86150_write_register(MAX86150_ADDRESS, MAX86150_FIFOWRITEPTR, 0);
max86150_write_register(MAX86150_ADDRESS, MAX86150_FIFOOVERFLOW, 0);
max86150_write_register(MAX86150_ADDRESS, MAX86150_FIFOREADPTR, 0);
}
//Enable roll over if FIFO over flows
void max86150_enableFIFORollover(void) {
max86150_bitMask(MAX86150_FIFOCONFIG, MAX86150_ROLLOVER_MASK, MAX86150_ROLLOVER_ENABLE);
void max86150_set_fifo_rollover(bool enabled)
{
if (enabled) {
max86150_bit_mask(
MAX86150_FIFOCONFIG,
MAX86150_ROLLOVER_MASK,
MAX86150_ROLLOVER_ENABLE
);
} else {
max86150_bit_mask(
MAX86150_FIFOCONFIG,
MAX86150_ROLLOVER_MASK,
MAX86150_ROLLOVER_DISABLE
);
}
}
//Enable fifo almost full flag clear on data read
void max86150_set_fifo_almost_full_clear(bool enabled)
{
if (enabled) {
max86150_bit_mask(
MAX86150_FIFOCONFIG,
MAX86150_ALMOST_FULL_CLEAR_MASK,
MAX86150_ALMOST_FULL_CLEAR_ENABLE
);
} else {
max86150_bit_mask(
MAX86150_FIFOCONFIG,
MAX86150_ALMOST_FULL_CLEAR_MASK,
MAX86150_ALMOST_FULL_CLEAR_DISABLE
);
}
}
//Disable roll over if FIFO over flows
void max86150_disableFIFORollover(void) {
max86150_bitMask(MAX86150_FIFOCONFIG, MAX86150_ROLLOVER_MASK, MAX86150_ROLLOVER_DISABLE);
//Enable fifo almost full flag repeated assertion
void max86150_set_fifo_almost_full_repeat(bool enabled)
{
if (enabled) {
max86150_bit_mask(
MAX86150_FIFOCONFIG,
MAX86150_ALMOST_FULL_REPEAT_MASK,
MAX86150_ALMOST_FULL_REPEAT_ENABLE
);
} else {
max86150_bit_mask(
MAX86150_FIFOCONFIG,
MAX86150_ALMOST_FULL_REPEAT_MASK,
MAX86150_ALMOST_FULL_REPEAT_DISABLE
);
}
}
//Power on default is 32 samples
//Note it is reverse: 0x00 is 32 samples, 0x0F is 17 samples
void max86150_setFIFOAlmostFull(uint8_t numberOfSamples) {
max86150_bitMask(MAX86150_FIFOCONFIG, MAX86150_A_FULL_MASK, numberOfSamples);
void max86150_set_fifo_almost_full(uint8_t numberOfSamples)
{
max86150_bit_mask(
MAX86150_FIFOCONFIG, MAX86150_A_FULL_MASK, numberOfSamples
);
}
//Read the FIFO Write Pointer
uint8_t max86150_getWritePointer(void) {
return (max86150_readRegister8(_i2caddr, MAX86150_FIFOWRITEPTR));
uint8_t max86150_get_fifo_write_pointer(void)
{
return (max86150_read_register(MAX86150_ADDRESS, MAX86150_FIFOWRITEPTR));
}
//Read the FIFO Read Pointer
uint8_t max86150_getReadPointer(void) {
return (max86150_readRegister8(_i2caddr, MAX86150_FIFOREADPTR));
}
// Set the PROX_INT_THRESHold
void max86150_setPROXINTTHRESH(uint8_t val) {
max86150_writeRegister8(_i2caddr, MAX86150_PROXINTTHRESH, val);
uint8_t max86150_get_fifo_read_pointer(void)
{
return (max86150_read_register(MAX86150_ADDRESS, MAX86150_FIFOREADPTR));
}
//
// Device ID and Revision
//
uint8_t max86150_readPartID() {
return max86150_readRegister8(_i2caddr, MAX86150_PARTID);
uint8_t max86150_read_part_id()
{
return max86150_read_register(MAX86150_ADDRESS, MAX86150_PARTID);
}
//Setup the sensor
//The MAX86150 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 max86150_setup if you are just getting started with the MAX86150 sensor
void max86150_setup(byte powerLevel, byte sampleAverage, byte ledMode, int sampleRate, int pulseWidth, int adcRange)
//Set ecg sample rate
void max86150_set_ecg_sample_rate(uint8_t sampleRate)
{
activeDevices=3;
max86150_writeRegister8(_i2caddr,MAX86150_SYSCONTROL,0x01);
delay(100);
max86150_writeRegister8(_i2caddr,MAX86150_FIFOCONFIG,0x7F);
//FIFO Configuration
//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
//The chip will average multiple samples of same type together if you wish
if (sampleAverage == 1) max86150_setFIFOAverage(MAX86150_SAMPLEAVG_1); //No averaging per FIFO record
else if (sampleAverage == 2) max86150_setFIFOAverage(MAX86150_SAMPLEAVG_2);
else if (sampleAverage == 4) max86150_setFIFOAverage(MAX86150_SAMPLEAVG_4);
else if (sampleAverage == 8) max86150_setFIFOAverage(MAX86150_SAMPLEAVG_8);
else if (sampleAverage == 16) max86150_setFIFOAverage(MAX86150_SAMPLEAVG_16);
else if (sampleAverage == 32) max86150_setFIFOAverage(MAX86150_SAMPLEAVG_32);
else max86150_setFIFOAverage(MAX86150_SAMPLEAVG_4);
uint16_t FIFOCode = 0x00;
FIFOCode = FIFOCode<<4 | 0x0009;// : FIFOCode; //insert ECG front of ETI in FIFO
FIFOCode = FIFOCode<<8 | 0x0021;//) : FIFOCode; //insert Red(2) and IR (1) in front of ECG in FIFO
// sampleRate: one of MAX86150_ECG_SAMPLERATE_*
max86150_bit_mask(