From 132ab9c0e89f805687856396384a63720fd81c0e Mon Sep 17 00:00:00 2001
From: "Jakob (XDjackieXD) Riepler" <jakob.riepler@chaosfield.at>
Date: Fri, 31 Jan 2020 21:54:18 +0100
Subject: [PATCH] fix(max86150): replace Arduino library with a better version

Get samples from FIFO by small junks due to 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.

Co-Authored-by: Arist <aristkojevnikov@gmail.com>
---
 lib/vendor/Maxim/MAX86150/max86150.c | 1107 +++++++++++++++-----------
 lib/vendor/Maxim/MAX86150/max86150.h |  183 +++--
 2 files changed, 753 insertions(+), 537 deletions(-)

diff --git a/lib/vendor/Maxim/MAX86150/max86150.c b/lib/vendor/Maxim/MAX86150/max86150.c
index ab14bb108..203df693a 100644
--- a/lib/vendor/Maxim/MAX86150/max86150.c
+++ b/lib/vendor/Maxim/MAX86150/max86150.c
@@ -18,151 +18,132 @@
 
 typedef uint8_t byte;
 
-static const uint8_t MAX86150_INTSTAT1 =		0x00;
-static const uint8_t MAX86150_INTSTAT2 =		0x01;
-static const uint8_t MAX86150_INTENABLE1 =		0x02;
-static const uint8_t MAX86150_INTENABLE2 =		0x03;
+static const uint8_t MAX86150_INTSTAT1   = 0x00;
+static const uint8_t MAX86150_INTSTAT2   = 0x01;
+static const uint8_t MAX86150_INTENABLE1 = 0x02;
+static const uint8_t MAX86150_INTENABLE2 = 0x03;
 
-static const uint8_t MAX86150_FIFOWRITEPTR = 	0x04;
-static const uint8_t MAX86150_FIFOOVERFLOW = 	0x05;
-static const uint8_t MAX86150_FIFOREADPTR = 	0x06;
-static const uint8_t MAX86150_FIFODATA 		=		0x07;
+static const uint8_t MAX86150_FIFOWRITEPTR = 0x04;
+static const uint8_t MAX86150_FIFOOVERFLOW = 0x05;
+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_FIFOCONTROL2 = 	0x0A;
+static const uint8_t MAX86150_FIFOCONFIG   = 0x08;
+static const uint8_t MAX86150_FIFOCONTROL1 = 0x09;
+static const uint8_t MAX86150_FIFOCONTROL2 = 0x0A;
 
-static const uint8_t MAX86150_SYSCONTROL = 	0x0D;
-static const uint8_t MAX86150_PPGCONFIG1 = 		0x0E;
-static const uint8_t MAX86150_PPGCONFIG2 = 		0x0F;
-static const uint8_t MAX86150_LED_PROX_AMP = 	0x10;
+static const uint8_t MAX86150_SYSCONTROL   = 0x0D;
+static const uint8_t MAX86150_PPGCONFIG1   = 0x0E;
+static const uint8_t MAX86150_PPGCONFIG2   = 0x0F;
+static const uint8_t MAX86150_LED_PROX_AMP = 0x10;
 
-static const uint8_t MAX86150_LED1_PULSEAMP = 	0x11;
-static const uint8_t MAX86150_LED2_PULSEAMP = 	0x12;
-static const uint8_t MAX86150_LED_RANGE 		= 	0x14;
-static const uint8_t MAX86150_LED_PILOT_PA 	= 	0x15;
+static const uint8_t MAX86150_LED1_PULSEAMP = 0x11;
+static const uint8_t MAX86150_LED2_PULSEAMP = 0x12;
+static const uint8_t MAX86150_LED_RANGE     = 0x14;
+static const uint8_t MAX86150_LED_PILOT_PA  = 0x15;
 
-static const uint8_t MAX86150_ECG_CONFIG1 	= 	0x3C;
-static const uint8_t MAX86150_ECG_CONFIG3 	= 	0x3E;
-static const uint8_t MAX86150_PROXINTTHRESH = 	0x10;
+static const uint8_t MAX86150_ECG_CONFIG1   = 0x3C;
+static const uint8_t MAX86150_ECG_CONFIG3   = 0x3E;
+static const uint8_t MAX86150_PROXINTTHRESH = 0x10;
 
-static const uint8_t MAX86150_PARTID = 			0xFF;
+static const uint8_t MAX86150_PARTID = 0xFF;
 
 // MAX86150 Commands
-static const uint8_t MAX86150_INT_A_FULL_MASK =		(byte)~0b10000000;
-static const uint8_t MAX86150_INT_A_FULL_ENABLE = 	0x80;
-static const uint8_t MAX86150_INT_A_FULL_DISABLE = 	0x00;
+static const uint8_t MAX86150_INT_A_FULL_MASK    = (byte)~0b10000000;
+static const uint8_t MAX86150_INT_A_FULL_ENABLE  = 0x80;
+static const uint8_t MAX86150_INT_A_FULL_DISABLE = 0x00;
 
-static const uint8_t MAX86150_INT_DATA_RDY_MASK = (byte)~0b01000000;
-static const uint8_t MAX86150_INT_DATA_RDY_ENABLE =	0x40;
+static const uint8_t MAX86150_INT_DATA_RDY_MASK    = (byte)~0b01000000;
+static const uint8_t MAX86150_INT_DATA_RDY_ENABLE  = 0x40;
 static const uint8_t MAX86150_INT_DATA_RDY_DISABLE = 0x00;
 
-static const uint8_t MAX86150_INT_ALC_OVF_MASK = (byte)~0b00100000;
-static const uint8_t MAX86150_INT_ALC_OVF_ENABLE = 	0x20;
+static const uint8_t MAX86150_INT_ALC_OVF_MASK    = (byte)~0b00100000;
+static const uint8_t MAX86150_INT_ALC_OVF_ENABLE  = 0x20;
 static const uint8_t MAX86150_INT_ALC_OVF_DISABLE = 0x00;
 
-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_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_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 MAX_30105_EXPECTEDPARTID = 0x1E;
-
-static uint8_t _i2caddr;
-
-//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 void max86150_bitMask(uint8_t reg, uint8_t mask, uint8_t thing);
-
-#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];
-    byte head;
-    byte tail;
+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 MAX86150_LED1_RANGE_MASK = (byte)~0b00000011;
+static const uint8_t MAX86150_LED2_RANGE_MASK = (byte)~0b00001100;
+
+static const uint8_t MAX86150_ECG_SAMPLERATE_MASK = (byte)~0b00000111;
+
+static const uint8_t MAX86150_ECG_PGA_GAIN_MASK = (byte)~0b00001100;
+
+static const uint8_t MAX86150_ECG_IA_GAIN_MASK = (byte)~0b00000011;
+
+static const uint8_t MAX86150_EXPECTEDPARTID = 0x1E;
+
+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];
+	byte head;
+	byte tail;
 } sense_struct; //This is our circular buffer of readings from the sensor
 
 static sense_struct sense;
 
 static void delay(int ms)
 {
-    TMR_Delay(MXC_TMR0, MSEC(ms), 0);
+	TMR_Delay(MXC_TMR0, MSEC(ms), 0);
 }
 
 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) {
-    // 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;
-  }
-  return true;
+	// Step 1: Initial Communication and Verification
+	// Check that a MAX86150 is connected
+	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;
+	}
+	return true;
 }
 
 //
@@ -170,498 +151,704 @@ bool max86150_begin(void)
 //
 
 //Begin Interrupt configuration
-uint8_t max86150_getINT1(void)
+uint8_t max86150_get_int1(void)
 {
-  return (max86150_readRegister8(_i2caddr, MAX86150_INTSTAT1));
-}
-uint8_t max86150_getINT2(void) {
-  return (max86150_readRegister8(_i2caddr, MAX86150_INTSTAT2));
-}
-
-void max86150_enableAFULL(void) {
-  max86150_bitMask(MAX86150_INTENABLE1, MAX86150_INT_A_FULL_MASK, MAX86150_INT_A_FULL_ENABLE);
+	return (max86150_read_register(MAX86150_ADDRESS, MAX86150_INTSTAT1));
 }
-void max86150_disableAFULL(void) {
-  max86150_bitMask(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_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);
+uint8_t max86150_get_int2(void)
+{
+	return (max86150_read_register(MAX86150_ADDRESS, MAX86150_INTSTAT2));
 }
 
-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_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_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_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_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);
-
-  // 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!
-    delay(1); //Let's not over burden the I2C bus
-  }
-}
-
-void max86150_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)
-  max86150_bitMask(MAX86150_SYSCONTROL, MAX86150_SHUTDOWN_MASK, MAX86150_SHUTDOWN);
-}
-
-void max86150_wakeUp(void) {
-  // Pull IC out of low power mode (datasheet pg. 19)
-  max86150_bitMask(MAX86150_SYSCONTROL, MAX86150_SHUTDOWN_MASK, MAX86150_WAKEUP);
+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 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_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_bit_mask(
+		MAX86150_SYSCONTROL, MAX86150_SHUTDOWN_MASK, MAX86150_SHUTDOWN
+	);
 }
 
-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_wake_up(void)
+{
+	// Pull IC out of low power mode (datasheet pg. 19)
+	max86150_bit_mask(
+		MAX86150_SYSCONTROL, MAX86150_SHUTDOWN_MASK, MAX86150_WAKEUP
+	);
 }
 
-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_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_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);
+	// The threshMSB signifies only the 8 most significant-bits of the ADC count.
+	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)
-{
-	  //uint8_t originalContents;
-
-	  switch (slotNumber) {
-	    case (1):
-	      max86150_bitMask(MAX86150_FIFOCONTROL1, MAX86150_SLOT1_MASK, device);
-	      break;
-	    case (2):
-	      max86150_bitMask(MAX86150_FIFOCONTROL1, MAX86150_SLOT2_MASK, device << 4);
-	      break;
-	    case (3):
-	      max86150_bitMask(MAX86150_FIFOCONTROL2, MAX86150_SLOT3_MASK, device);
-	      break;
-	    case (4):
-	      max86150_bitMask(MAX86150_FIFOCONTROL2, MAX86150_SLOT4_MASK, device << 4);
-	      break;
-	    default:
-	      //Shouldn't be here!
-	      break;
-	  }
+void max86150_fifo_enable_slot(uint8_t slotNumber, uint8_t device)
+{
+	switch (slotNumber) {
+	case (1):
+		max86150_bit_mask(
+			MAX86150_FIFOCONTROL1, MAX86150_SLOT1_MASK, device
+		);
+		break;
+	case (2):
+		max86150_bit_mask(
+			MAX86150_FIFOCONTROL1,
+			MAX86150_SLOT2_MASK,
+			device << 4
+		);
+		break;
+	case (3):
+		max86150_bit_mask(
+			MAX86150_FIFOCONTROL2, MAX86150_SLOT3_MASK, device
+		);
+		break;
+	case (4):
+		max86150_bit_mask(
+			MAX86150_FIFOCONTROL2,
+			MAX86150_SLOT4_MASK,
+			device << 4
+		);
+		break;
+	default:
+		//Shouldn't be here!
+		break;
+	}
 }
 
 //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);
-}
-
-//Disable roll over if FIFO over flows
-void max86150_disableFIFORollover(void) {
-  max86150_bitMask(MAX86150_FIFOCONFIG, MAX86150_ROLLOVER_MASK, MAX86150_ROLLOVER_DISABLE);
+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
+		);
+	}
+}
+
+//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(
+		MAX86150_ECG_CONFIG1, MAX86150_ECG_SAMPLERATE_MASK, sampleRate
+	);
+}
 
+//Set ecg pga gain
+void max86150_set_ecg_pga_gain(uint8_t gain)
+{
+	// sampleRate: one of MAX86150_ECG_PGA_GAIN_*
+	max86150_bit_mask(
+		MAX86150_ECG_CONFIG3, MAX86150_ECG_PGA_GAIN_MASK, gain
+	);
+}
 
-		//FIFO Control 1 = FD2|FD1, FIFO Control 2 = FD4|FD3
+//Set ecg pga gain
+void max86150_set_ecg_instrumentation_amplifier_gain(uint8_t gain)
+{
+	// sampleRate: one of MAX86150_ECG_IA_GAIN_*
+	max86150_bit_mask(
+		MAX86150_ECG_CONFIG3, MAX86150_ECG_IA_GAIN_MASK, gain
+	);
+}
 
-		max86150_writeRegister8(_i2caddr,MAX86150_FIFOCONTROL1,(0b00100001));
-		//max86150_writeRegister8(_i2caddr,MAX86150_FIFOCONTROL1,(0b00001001));
-		//max86150_writeRegister8(_i2caddr,MAX86150_FIFOCONTROL1,(0b00000010));
-		max86150_writeRegister8(_i2caddr,MAX86150_FIFOCONTROL2,(0b00001001));
-		//max86150_writeRegister8(_i2caddr,MAX86150_FIFOCONTROL2,(0b00000000));
-		//max86150_writeRegister8(_i2caddr,MAX86150_FIFOCONTROL1, (char)(FIFOCode & 0x00FF) );
-		//max86150_writeRegister8(_i2caddr,MAX86150_FIFOCONTROL2, (char)(FIFOCode >>8) );
+//Setup the sensor
+//The MAX86150 has many settings.
+//Use the default max86150_setup if you are just getting started with the MAX86150 sensor
+void max86150_setup(const uint8_t ppg_sample_rate)
+{
+	max86150_soft_reset();
+	max86150_set_ppg_averaging(MAX86150_SAMPLEAVG_4);
+	max86150_set_fifo_rollover(true);
+	max86150_set_fifo_almost_full(8);
+	max86150_set_fifo_almost_full_clear(true);
+	max86150_set_fifo_almost_full_repeat(true);
 
-		max86150_writeRegister8(_i2caddr,MAX86150_PPGCONFIG1,0b11010001);
-		//max86150_writeRegister8(_i2caddr,MAX86150_PPGCONFIG1,0b11100111);
+	max86150_fifo_enable_slot(1, MAX86150_SLOT_RED_LED);
+	max86150_fifo_enable_slot(2, MAX86150_SLOT_IR_LED);
+	max86150_fifo_enable_slot(3, MAX86150_SLOT_ECG);
+	//max86150_fifo_enable_slot(4, MAX86150_SLOT_NONE);
 
-		max86150_writeRegister8(_i2caddr,MAX86150_PPGCONFIG2, 0x06);
-		max86150_writeRegister8(_i2caddr,MAX86150_LED_RANGE, 0x00 ); // PPG_ADC_RGE: 32768nA
+	max86150_set_ppg_adc_range(MAX86150_ADCRANGE_16384);
+	max86150_set_ppg_sample_rate(ppg_sample_rate);
+	max86150_set_ppg_pulse_width(MAX86150_PPG_PULSEWIDTH_100);
 
-		max86150_writeRegister8(_i2caddr,MAX86150_SYSCONTROL,0x04);//start FIFO
+	max86150_set_led_ir_amplitude(0x66);
+	max86150_set_led_red_amplitude(0x66);
 
-		max86150_writeRegister8(_i2caddr,MAX86150_ECG_CONFIG1,0b00000011);
-		//max86150_writeRegister8(_i2caddr,MAX86150_ECG_CONFIG1,0b00000001);
-		max86150_writeRegister8(_i2caddr,MAX86150_ECG_CONFIG3,0b00001101);
+	max86150_set_ecg_sample_rate(MAX86150_ECG_SAMPLERATE_200);
+	max86150_set_ecg_pga_gain(MAX86150_ECG_PGA_GAIN_8);
+	max86150_set_ecg_instrumentation_amplifier_gain(
+		MAX86150_ECG_IA_GAIN_9_5
+	);
 
-		max86150_setPulseAmplitudeRed(0xFF);
-		max86150_setPulseAmplitudeIR(0xFF);
+	max86150_set_int_datardy(false);
+	max86150_set_int_full(true);
 
-  //Multi-LED Mode Configuration, Enable the reading of the three LEDs
-  //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
-  //max86150_enableSlot(1, SLOT_RED_LED);
-  //if (ledMode > 1)
-	//max86150_enableSlot(2, SLOT_IR_LED);
-  //if (ledMode > 2)
-	//max86150_enableSlot(3, SLOT_ECG);
-  //max86150_enableSlot(1, SLOT_RED_PILOT);
-  //max86150_enableSlot(2, SLOT_IR_PILOT);
-  //max86150_enableSlot(3, SLOT_GREEN_PILOT);
-  //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+	max86150_clear_fifo(); //Reset the FIFO before we begin checking the sensor
 
-  	max86150_clearFIFO(); //Reset the FIFO before we begin checking the sensor
+	max86150_set_fifo_enable(true);
 }
 
 //Tell caller how many samples are max86150_available
 uint8_t max86150_available(void)
 {
-  int8_t numberOfSamples = sense.head - sense.tail;
-  if (numberOfSamples < 0) numberOfSamples += STORAGE_SIZE;
+	int8_t numberOfSamples = sense.head - sense.tail;
+	if (numberOfSamples < 0)
+		numberOfSamples += STORAGE_SIZE;
 
-  return (numberOfSamples);
+	return (numberOfSamples);
 }
 
 //Report the most recent red value
-uint32_t max86150_getRed(void)
+uint32_t max86150_get_red(void)
 {
-  //Check the sensor for new data for 250ms
-  if(max86150_safeCheck(250))
-    return (sense.red[sense.head]);
-  else
-    return(0); //Sensor failed to find new data
+	//Check the sensor for new data for 250ms
+	if (max86150_safeCheck(250))
+		return (sense.red[sense.head]);
+	else
+		return (0); //Sensor failed to find new data
 }
 
 //Report the most recent IR value
-uint32_t max86150_getIR(void)
+uint32_t max86150_get_ir(void)
 {
-  //Check the sensor for new data for 250ms
-  if(max86150_safeCheck(250))
-    return (sense.IR[sense.head]);
-  else
-    return(0); //Sensor failed to find new data
+	//Check the sensor for new data for 250ms
+	if (max86150_safeCheck(250))
+		return (sense.IR[sense.head]);
+	else
+		return (0); //Sensor failed to find new data
 }
 
 //Report the most recent Green value
-int32_t max86150_getECG(void)
+int32_t max86150_get_ecg(void)
 {
-  //Check the sensor for new data for 250ms
-  if(max86150_safeCheck(250))
-    return (sense.ecg[sense.head]);
-  else
-    return(0); //Sensor failed to find new data
+	//Check the sensor for new data for 250ms
+	if (max86150_safeCheck(250))
+		return (sense.ecg[sense.head]);
+	else
+		return (0); //Sensor failed to find new data
 }
 
 //Report the next Red value in the FIFO
-uint32_t max86150_getFIFORed(void)
+uint32_t max86150_get_fifo_red(void)
 {
-  return (sense.red[sense.tail]);
+	return (sense.red[sense.tail]);
 }
 
 //Report the next IR value in the FIFO
-uint32_t max86150_getFIFOIR(void)
+uint32_t max86150_get_fifo_ir(void)
 {
-  return (sense.IR[sense.tail]);
+	return (sense.IR[sense.tail]);
 }
 
 //Report the next Green value in the FIFO
-int32_t max86150_getFIFOECG(void)
+int32_t max86150_get_fifo_ecg(void)
 {
-  return (sense.ecg[sense.tail]);
+	return (sense.ecg[sense.tail]);
 }
 
 //Advance the tail
-void max86150_nextSample(void)
+void max86150_next_sample(void)
 {
-  if(max86150_available()) //Only advance the tail if new data is max86150_available
-  {
-    sense.tail++;
-    sense.tail %= STORAGE_SIZE; //Wrap condition
-  }
+	if (max86150_available()) { //Only advance the tail if new data is max86150_available
+		sense.tail++;
+		sense.tail %= STORAGE_SIZE; //Wrap condition
+	}
 }
 
+//Polls the sensor for new data
+//Call regularly
+//If new data is max86150_available, it updates the head and tail in the main struct
+//Returns number of new samples obtained
+uint8_t max86150_get_sample(uint32_t *red, uint32_t *ir, int32_t *ecg)
+{
+	//Read register FIDO_DATA in (3-byte * number of active LED) chunks
+	//Until FIFO_RD_PTR = FIFO_WR_PTR
+
+	byte readPointer  = max86150_get_fifo_read_pointer();
+	byte writePointer = max86150_get_fifo_write_pointer();
+
+	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
+
+		//Get ready to read a burst of data from the FIFO register
+		uint8_t command[] = { MAX86150_FIFODATA };
+
+		// Important! true is for repeated start (since we are not reading complete fifo)
+		// See https://os.mbed.com/users/laserdad/code/MAX86150_ECG_PPG//file/3c728f3d1f10/main.cpp/
+		I2C_MasterWrite(
+			MXC_I2C1_BUS0, MAX86150_ADDRESS << 1, command, 1, true
+		);
+
+		if (numberOfSamples > 0) {
+			uint8_t data[3 * 3];
+			I2C_MasterRead(
+				MXC_I2C1_BUS0,
+				MAX86150_ADDRESS << 1,
+				data,
+				3 * 3,
+				0
+			);
+
+			*red = (data[0] << 16) | (data[1] << 8) | (data[2]);
+			*ir  = (data[3] << 16) | (data[4] << 8) | (data[5]);
+			*ecg = (data[6] << 16) | (data[7] << 8) | (data[8]);
+		}
+
+	}                         //End readPtr != writePtr
+	return (numberOfSamples); //Let the world know how much new data we found
+}
 //Polls the sensor for new data
 //Call regularly
 //If new data is max86150_available, it updates the head and tail in the main struct
 //Returns number of new samples obtained
 uint16_t max86150_check(void)
 {
-  //Read register FIDO_DATA in (3-byte * number of active LED) chunks
-  //Until FIFO_RD_PTR = FIFO_WR_PTR
-
-  byte readPointer = max86150_getReadPointer();
-  byte writePointer = max86150_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 bytes to read
-    //For this example we are just doing Red and IR (3 bytes each)
-    int bytesLeftToRead = numberOfSamples * activeDevices * 3;
-
-    //Get ready to read a burst of data from the FIFO register
-    uint8_t command[] = {MAX86150_FIFODATA};
-    I2C_MasterWrite(MXC_I2C1_BUS0, _i2caddr << 1, command, 1, 0);
-
-    //We may need to read as many as 288 bytes so we read in blocks no larger than I2C_BUFFER_LENGTH
-    //I2C_BUFFER_LENGTH changes based on the platform. 64 bytes for SAMD21, 32 bytes for Uno.
-    //Wire.requestFrom() is limited to BUFFER_LENGTH which is 32 on the Uno
-    while (bytesLeftToRead > 0)
-    {
-      int toGet = bytesLeftToRead;
-      if (toGet > I2C_BUFFER_LENGTH)
-      {
-        //If toGet is 32 this is bad because we read 6 bytes (Red+IR * 3 = 6) at a time
-        //32 % 6 = 2 left over. We don't want to request 32 bytes, 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 % (activeDevices * 3)); //Trim toGet to be a multiple of the samples we need to read
-      }
-
-      bytesLeftToRead -= toGet;
-
-      //Request toGet number of bytes from sensor
-      //_i2cPort->requestFrom(_i2caddr, toGet);
-      uint8_t data[toGet];
-      uint8_t *p = data;
-      I2C_MasterRead(MXC_I2C1_BUS0, _i2caddr << 1, data, toGet, 0);
-
-      while (toGet > 0)
-      {
-        sense.head++; //Advance the head of the storage struct
-        sense.head %= STORAGE_SIZE; //Wrap condition
-
-        byte temp[sizeof(uint32_t)]; //Array of 4 bytes that we will convert into long
-        uint32_t tempLong;
-
-        //Burst read three bytes - RED
-        temp[3] = 0;
-        temp[2] = *p++;
-        temp[1] = *p++;
-        temp[0] = *p++;
-
-        //Convert array to long
-        memcpy(&tempLong, temp, sizeof(tempLong));
+	//Read register FIDO_DATA in (3-byte * number of active LED) chunks
+	//Until FIFO_RD_PTR = FIFO_WR_PTR
+
+	byte readPointer  = max86150_get_fifo_read_pointer();
+	byte writePointer = max86150_get_fifo_write_pointer();
+
+	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 bytes to read
+		//For this example we are just doing Red and IR (3 bytes each)
+		int bytesLeftToRead = numberOfSamples * activeDevices * 3;
+
+		//Get ready to read a burst of data from the FIFO register
+		uint8_t command[] = { MAX86150_FIFODATA };
+		I2C_MasterWrite(
+			MXC_I2C1_BUS0, MAX86150_ADDRESS << 1, command, 1, 0
+		);
+
+		//We may need to read as many as 288 bytes so we read in blocks no larger than I2C_BUFFER_LENGTH
+		//I2C_BUFFER_LENGTH changes based on the platform. 64 bytes for SAMD21, 32 bytes for Uno.
+		//Wire.requestFrom() is limited to BUFFER_LENGTH which is 32 on the Uno
+		while (bytesLeftToRead > 0) {
+			int toGet = bytesLeftToRead;
+			if (toGet > I2C_BUFFER_LENGTH) {
+				//If toGet is 32 this is bad because we read 9 bytes (Red+IR+ECG * 3 = 9) at a time
+				//32 % 9 = 5 left over. We don't want to request 32 bytes, we want to request 27.
+				//32 % 9 (Red+IR+GREEN) = 5 left over. We want to request 27.
+
+				toGet = I2C_BUFFER_LENGTH -
+					(I2C_BUFFER_LENGTH %
+					 (activeDevices *
+					  3)); //Trim toGet to be a multiple of the samples we need to read
+			}
+
+			bytesLeftToRead -= toGet;
+
+			//Request toGet number of bytes from sensor
+			//_i2cPort->requestFrom(MAX86150_ADDRESS, toGet);
+			uint8_t data[bytesLeftToRead];
+			uint8_t *p = data;
+			I2C_MasterRead(
+				MXC_I2C1_BUS0,
+				MAX86150_ADDRESS << 1,
+				data,
+				bytesLeftToRead,
+				0
+			);
+
+			while (bytesLeftToRead > 0) {
+				sense.head++; //Advance the head of the storage struct
+				sense.head %= STORAGE_SIZE; //Wrap condition
+
+				byte temp[sizeof(
+					uint32_t)]; //Array of 4 bytes that we will convert into long
+				uint32_t tempLong;
+
+				//Burst read three bytes - RED
+				temp[3] = 0;
+				temp[2] = *p++;
+				temp[1] = *p++;
+				temp[0] = *p++;
+
+				//Convert array to long
+				memcpy(&tempLong, temp, sizeof(tempLong));
 
 				tempLong &= 0x7FFFF; //Zero out all but 18 bits
 
-        sense.red[sense.head] = tempLong; //Store this reading into the sense array
+				sense.red[sense.head] =
+					tempLong; //Store this reading into the sense array
 
-        if (activeDevices > 1)
-        {
-          //Burst read three more bytes - IR
-          temp[3] = 0;
-          temp[2] = *p++;
-          temp[1] = *p++;
-          temp[0] = *p++;
+				if (activeDevices > 1) {
+					//Burst read three more bytes - IR
+					temp[3] = 0;
+					temp[2] = *p++;
+					temp[1] = *p++;
+					temp[0] = *p++;
 
-          //Convert array to long
-          memcpy(&tempLong, temp, sizeof(tempLong));
+					//Convert array to long
+					memcpy(&tempLong,
+					       temp,
+					       sizeof(tempLong));
 					//Serial.println(tempLong);
-				  tempLong &= 0x7FFFF; //Zero out all but 18 bits
+					tempLong &=
+						0x7FFFF; //Zero out all but 18 bits
 
-				  sense.IR[sense.head] = tempLong;
-        }
+					sense.IR[sense.head] = tempLong;
+				}
 
-        if (activeDevices > 2)
-        {
-          //Burst read three more bytes - ECG
+				if (activeDevices > 2) {
+					//Burst read three more bytes - ECG
 					int32_t tempLongSigned;
-
-          temp[3] = 0;
-          temp[2] = *p++;
-          temp[1] = *p++;
-          temp[0] = *p++;
+					temp[3] = 0;
+					temp[2] = *p++;
+					temp[1] = *p++;
+					temp[0] = *p++;
 
 					//Serial.println(tempLong);
-          //Convert array to long
-          memcpy(&tempLongSigned, temp, sizeof(tempLongSigned));
-
-		  		//tempLong &= 0x3FFFF; //Zero out all but 18 bits
+					//Convert array to long
+					memcpy(&tempLongSigned,
+					       temp,
+					       sizeof(tempLongSigned));
+					//tempLong &= 0x3FFFF; //Zero out all but 18 bits
+					sense.ecg[sense.head] = tempLongSigned;
+				}
 
-          sense.ecg[sense.head] = tempLongSigned;
-        }
-
-        toGet -= activeDevices * 3;
-      }
-    } //End while (bytesLeftToRead > 0)
-  } //End readPtr != writePtr
-  return (numberOfSamples); //Let the world know how much new data we found
+				bytesLeftToRead -= activeDevices * 3;
+			}
+		}                 //End while (bytesLeftToRead > 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
-bool max86150_safeCheck(uint8_t maxTimeToCheck)
+bool max86150_safe_check(uint8_t max_tries)
 {
-  // TODO
-  //uint32_t markTime = millis();
-
-  while(1)
-  {
-	//if(millis() - markTime > maxTimeToCheck) return(false);
+	uint8_t tries = 0;
 
-	if(max86150_check() == true) //We found new data!
-	  return(true);
+	while (tries < max_tries) {
+		if (max86150_check() == true) { //We found new data!
+			return (true);
+		}
 
-	delay(1);
-  }
+		tries++;
+		delay(1);
+	}
+	return false;
 }
 
 //Given a register, read it, mask it, and then set the thing
-void max86150_bitMask(uint8_t reg, uint8_t mask, uint8_t thing)
+void max86150_bit_mask(uint8_t reg, uint8_t mask, uint8_t thing)
 {
-  // Grab current register context
-  uint8_t originalContents = max86150_readRegister8(_i2caddr, reg);
+	// Grab current register context
+	uint8_t originalContents =
+		max86150_read_register(MAX86150_ADDRESS, reg);
 
-  // Zero-out the portions of the register we're interested in
-  originalContents = originalContents & mask;
+	// Zero-out the portions of the register we're interested in
+	originalContents = originalContents & mask;
 
-  // Change contents
-  max86150_writeRegister8(_i2caddr, reg, originalContents | thing);
+	// Change contents
+	max86150_write_register(
+		MAX86150_ADDRESS, reg, originalContents | thing
+	);
 }
 
-uint8_t max86150_readRegister8(uint8_t address, uint8_t reg) {
-
-  uint8_t tempData = 0;
-  uint8_t command[] = {reg};
-  I2C_MasterWrite(MXC_I2C1_BUS0, address << 1, command, 1, 0);
+uint8_t max86150_read_register(uint8_t address, uint8_t reg)
+{
+	uint8_t tempData  = 0;
+	uint8_t command[] = { reg };
+	// Important! true is for repeated start (since we are not reading complete fifo)
+	// See https://os.mbed.com/users/laserdad/code/MAX86150_ECG_PPG//file/3c728f3d1f10/main.cpp/
+	I2C_MasterWrite(MXC_I2C1_BUS0, address << 1, command, 1, true);
 
-  I2C_MasterRead(MXC_I2C1_BUS0, address << 1, &tempData, 1, 0);
+	I2C_MasterRead(MXC_I2C1_BUS0, address << 1, &tempData, 1, 0);
 
-  return tempData;
+	return tempData;
 }
 
-void max86150_writeRegister8(uint8_t address, uint8_t reg, uint8_t value) {
-  uint8_t command[] = {reg, value};
-  I2C_MasterWrite(MXC_I2C1_BUS0, address << 1, command, 2, 0);
+void max86150_write_register(uint8_t address, uint8_t reg, uint8_t value)
+{
+	uint8_t command[] = { reg, value };
+	I2C_MasterWrite(MXC_I2C1_BUS0, address << 1, command, 2, 0);
 }
diff --git a/lib/vendor/Maxim/MAX86150/max86150.h b/lib/vendor/Maxim/MAX86150/max86150.h
index c9454ea51..66b102183 100644
--- a/lib/vendor/Maxim/MAX86150/max86150.h
+++ b/lib/vendor/Maxim/MAX86150/max86150.h
@@ -18,86 +18,115 @@
 #include <stdint.h>
 #include <stdbool.h>
 
-typedef uint8_t byte;
 
-bool max86150_begin(void);
-
-uint32_t max86150_getRed(void); //Returns immediate red value
-uint32_t max86150_getIR(void); //Returns immediate IR value
-int32_t max86150_getECG(void); //Returns immediate ECG value
-bool max86150_safeCheck(uint8_t maxTimeToCheck); //Given a max amount of time, check for new data
-
-// Configuration
-void max86150_softReset();
-void max86150_shutDown();
-void max86150_wakeUp();
+static const uint8_t MAX86150_SAMPLEAVG_1 = 	0b000;
+static const uint8_t MAX86150_SAMPLEAVG_2 = 	0b001;
+static const uint8_t MAX86150_SAMPLEAVG_4 = 	0b010;
+static const uint8_t MAX86150_SAMPLEAVG_8 = 	0b011;
+static const uint8_t MAX86150_SAMPLEAVG_16 = 	0b100;
+static const uint8_t MAX86150_SAMPLEAVG_32 = 	0b101;
+
+static const uint8_t MAX86150_ADCRANGE_4096 = 	0b00000000;
+static const uint8_t MAX86150_ADCRANGE_8192 = 	0b01000000;
+static const uint8_t MAX86150_ADCRANGE_16384 = 	0b10000000;
+static const uint8_t MAX86150_ADCRANGE_32768 = 	0b11000000;
+
+static const uint8_t MAX86150_PPG_SAMPLERATE_10 =	0b00000000;
+static const uint8_t MAX86150_PPG_SAMPLERATE_20 =	0b00000100;
+static const uint8_t MAX86150_PPG_SAMPLERATE_50 =	0b00001000;
+static const uint8_t MAX86150_PPG_SAMPLERATE_84 =	0b00001100;
+static const uint8_t MAX86150_PPG_SAMPLERATE_100 =	0b00010000;
+static const uint8_t MAX86150_PPG_SAMPLERATE_200 =	0b00010100;
+static const uint8_t MAX86150_PPG_SAMPLERATE_400 =	0b00011000;
+static const uint8_t MAX86150_PPG_SAMPLERATE_800 =	0b00011100;
+static const uint8_t MAX86150_PPG_SAMPLERATE_1000 =	0b00100000;
+static const uint8_t MAX86150_PPG_SAMPLERATE_1600 =	0b00100100;
+static const uint8_t MAX86150_PPG_SAMPLERATE_3200 =	0b00101000;
+
+static const uint8_t MAX86150_PPG_PULSEWIDTH_50 =	0b00;
+static const uint8_t MAX86150_PPG_PULSEWIDTH_100 =	0b01;
+static const uint8_t MAX86150_PPG_PULSEWIDTH_200 =	0b10;
+static const uint8_t MAX86150_PPG_PULSEWIDTH_400 =	0b11;
+
+static const uint8_t MAX86150_SLOT_NONE =	0b0000;
+static const uint8_t MAX86150_SLOT_RED_LED =	0b0010;
+static const uint8_t MAX86150_SLOT_IR_LED =	0b0001;
+static const uint8_t MAX86150_SLOT_RED_PILOT =	0b0110;
+static const uint8_t MAX86150_SLOT_IR_PILOT =	0b0101;
+static const uint8_t MAX86150_SLOT_ECG =	0b1001;
+
+static const uint8_t MAX86150_LED1_RANGE_50 =	0b00;
+static const uint8_t MAX86150_LED1_RANGE_100 =	0b01;
+static const uint8_t MAX86150_LED2_RANGE_50 =	0b0000;
+static const uint8_t MAX86150_LED2_RANGE_100 =	0b0100;
+
+static const uint8_t MAX86150_ECG_SAMPLERATE_200 =	0b011;
+static const uint8_t MAX86150_ECG_SAMPLERATE_400 =	0b010;
+static const uint8_t MAX86150_ECG_SAMPLERATE_800 =	0b001;
+static const uint8_t MAX86150_ECG_SAMPLERATE_1600 =	0b000;
+static const uint8_t MAX86150_ECG_SAMPLERATE_3200 =	0b100;
+
+static const uint8_t MAX86150_ECG_PGA_GAIN_1 =		0b0000;
+static const uint8_t MAX86150_ECG_PGA_GAIN_2 =		0b0100;
+static const uint8_t MAX86150_ECG_PGA_GAIN_4 =		0b1000;
+static const uint8_t MAX86150_ECG_PGA_GAIN_8 =		0b1100;
+
+static const uint8_t MAX86150_ECG_IA_GAIN_5 =		0b00;
+static const uint8_t MAX86150_ECG_IA_GAIN_9_5 =		0b01;
+static const uint8_t MAX86150_ECG_IA_GAIN_20 =		0b10;
+static const uint8_t MAX86150_ECG_IA_GAIN_50 =		0b11;
 
-void max86150_setLEDMode(uint8_t mode);
 
-void max86150_setADCRange(uint8_t adcRange);
-void max86150_setSampleRate(uint8_t sampleRate);
-void max86150_setPulseWidth(uint8_t pulseWidth);
 
-void max86150_setPulseAmplitudeRed(uint8_t value);
-void max86150_setPulseAmplitudeIR(uint8_t value);
-void max86150_setPulseAmplitudeProximity(uint8_t value);
-
-void max86150_setProximityThreshold(uint8_t threshMSB);
+bool max86150_begin(void);
 
-//Multi-led configuration mode (page 22)
-void max86150_enableSlot(uint8_t slotNumber, uint8_t device); //Given slot number, assign a device to slot
+uint8_t max86150_get_int1(void);
+uint8_t max86150_get_int2(void);
+
+void max86150_set_int_full(bool enabled);
+void max86150_set_int_datardy(bool enabled);
+void max86150_set_int_ambient_light_overflow(bool enabled);
+void max86150_set_int_proximity(bool enabled);
+
+void max86150_soft_reset(void);
+void max86150_shut_down(void);
+void max86150_wake_up(void);
+void max86150_set_ppg_adc_range(uint8_t adcRange);
+void max86150_set_ppg_sample_rate(uint8_t sampleRate);
+void max86150_set_ppg_pulse_width(uint8_t pulseWidth);
+void max86150_set_led_red_amplitude(uint8_t amplitude);
+void max86150_set_led_ir_amplitude(uint8_t amplitude);
+void max86150_set_led_proximity_amplitude(uint8_t amplitude);
+void max86150_set_proximity_threshold(uint8_t threshMSB);
+void max86150_fifo_enable_slot(uint8_t slotNumber, uint8_t device);
 void max86150_disableSlots(void);
-
-// Data Collection
-
-//Interrupts (page 13, 14)
-uint8_t max86150_getINT1(void); //Returns the main interrupt group
-uint8_t max86150_getINT2(void); //Returns the temp ready interrupt
-void max86150_enableAFULL(void); //Enable/disable individual interrupts
-void max86150_disableAFULL(void);
-void max86150_enableDATARDY(void);
-void max86150_disableDATARDY(void);
-void max86150_enableALCOVF(void);
-void max86150_disableALCOVF(void);
-void max86150_enablePROXINT(void);
-void max86150_disablePROXINT(void);
-void max86150_enableDIETEMPRDY(void);
-void max86150_disableDIETEMPRDY(void);
-
-//FIFO Configuration (page 18)
-void max86150_setFIFOAverage(uint8_t samples);
-void max86150_enableFIFORollover();
-void max86150_disableFIFORollover();
-void max86150_setFIFOAlmostFull(uint8_t samples);
-
-//FIFO Reading
-uint16_t max86150_check(void); //Checks for new data and fills FIFO
-uint8_t max86150_available(void); //Tells caller how many new samples are available (head - tail)
-void max86150_nextSample(void); //Advances the tail of the sense array
-uint32_t max86150_getFIFORed(void); //Returns the FIFO sample pointed to by tail
-uint32_t max86150_getFIFOIR(void); //Returns the FIFO sample pointed to by tail
-int32_t max86150_getFIFOECG(void); //Returns the FIFO sample pointed to by tail
-
-uint8_t max86150_getWritePointer(void);
-uint8_t max86150_getReadPointer(void);
-void max86150_clearFIFO(void); //Sets the read/write pointers to zero
-
-//Proximity Mode Interrupt Threshold
-void max86150_setPROXINTTHRESH(uint8_t val);
-
-// Die Temperature
-float max86150_readTemperature();
-float max86150_readTemperatureF();
-
-// Detecting ID/Revision
-uint8_t max86150_getRevisionID();
-uint8_t max86150_readPartID();
-uint8_t max86150_readRegLED();
-
-// Setup the IC with user selectable settings
-//void max86150_setup(byte powerLevel = 0x1F, byte sampleAverage = 4, byte ledMode = 3, int sampleRate = 400, int pulseWidth = 411, int adcRange = 4096);
-void max86150_setup(byte powerLevel, byte sampleAverage, byte ledMode, int sampleRate, int pulseWidth, int adcRange);
-
-// Low-level I2C communication
-uint8_t max86150_readRegister8(uint8_t address, uint8_t reg);
-void max86150_writeRegister8(uint8_t address, uint8_t reg, uint8_t value);
+void max86150_set_ppg_averaging(uint8_t numberOfSamples);
+void max86150_clear_fifo(void);
+void max86150_set_fifo_rollover(bool enabled);
+void max86150_set_fifo_almost_full_clear(bool enabled);
+void max86150_set_fifo_almost_full_repeat(bool enabled);
+void max86150_set_fifo_almost_full(uint8_t numberOfSamples);
+uint8_t max86150_get_fifo_write_pointer(void);
+uint8_t max86150_get_fifo_read_pointer(void);
+uint8_t max86150_read_part_id();
+void max86150_set_ecg_sample_rate(uint8_t sampleRate);
+void max86150_set_ecg_pga_gain(uint8_t gain);
+void max86150_set_ecg_instrumentation_amplifier_gain(uint8_t gain);
+
+void max86150_setup(const uint8_t ppg_sample_rate);
+
+uint8_t max86150_available(void);
+uint32_t max86150_get_red(void);
+uint32_t max86150_get_ir(void);
+int32_t max86150_get_ecg(void);
+uint32_t max86150_get_fifo_red(void);
+uint32_t max86150_get_fifo_ir(void);
+int32_t max86150_get_fifo_ecg(void);
+void max86150_next_sample(void);
+uint8_t max86150_get_sample(uint32_t *red, uint32_t *ir, int32_t *ecg);
+uint16_t max86150_check(void);
+bool max86150_safe_check(uint8_t max_tries);
+
+void max86150_bit_mask(uint8_t reg, uint8_t mask, uint8_t thing);
+uint8_t max86150_read_register(uint8_t address, uint8_t reg);
+void max86150_write_register(uint8_t address, uint8_t reg, uint8_t value);
-- 
GitLab