Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of MAX30100 by
Revision 1:02f411fefe6f, committed 2016-06-21
- Comitter:
- Filea
- Date:
- Tue Jun 21 09:43:15 2016 +0000
- Parent:
- 0:e1e1947a9882
- Commit message:
- Modified the code from the library MAX30100 to work with MAX30102 pulse oximeter.
Changed in this revision
--- a/max30100.cpp Sun Apr 03 13:43:19 2016 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,167 +0,0 @@ -/* - Library for the Maxim MAX30100 pulse oximetry system - */ - -#include "max30100.h" -#include "functions.h" - -static Serial pc(SERIAL_TX, SERIAL_RX); - -void MAX30100::setLEDs(pulseWidth pw, ledCurrent red, ledCurrent ir){ - char data_read[1]; - char data_write[1]; - i2c_read(MAX30100_ADDRESS, MAX30100_SPO2_CONFIG, data_read, 1); - data_read[0] = data_read[0] & 0xFC; // Set LED_PW to 00 - data_write[0] = data_read[0] | pw; - i2c_write(MAX30100_ADDRESS, MAX30100_SPO2_CONFIG, data_write, 1); // Mask LED_PW - data_write[0] = ((red<<4) | ir); - i2c_write(MAX30100_ADDRESS, MAX30100_LED_CONFIG, data_write, 1); // write LED configs -} - -void MAX30100::setSPO2(sampleRate sr, high_resolution hi_res){ - char data_read[1]; - char data_write[1]; - i2c_read(MAX30100_ADDRESS, MAX30100_SPO2_CONFIG, data_read, 1); - data_read[0] = data_read[0] & 0xA3; // Set SPO2_SR to 000 and SPO2_HI_RES_EN to 0 - data_write[0] = data_read[0] | (sr<<2) | (hi_res<<6); - i2c_write(MAX30100_ADDRESS, MAX30100_SPO2_CONFIG, data_write, 1); // Mask SPO2_SR - i2c_read(MAX30100_ADDRESS, MAX30100_CONFIG, data_read, 1); - data_write[0] = data_read[0] & 0xF8; // Set Mode to 000 - i2c_write(MAX30100_ADDRESS, MAX30100_CONFIG, data_write, 1); // Mask MODE -} - -void MAX30100::setInterruptSPO2(void){ - char data_read[1]; - char data_write[1]; - i2c_read(MAX30100_ADDRESS, MAX30100_INT_ENABLE, data_read, 1); - data_write[0] = data_read[0] | 0x10; // Set Interrupt enable for SPO2 - i2c_write(MAX30100_ADDRESS, MAX30100_INT_ENABLE, data_write, 1); // Mask ENB_SPO2_RDY -} - -int MAX30100::getNumSamp(void){ - char data_read[1]; - i2c_read(MAX30100_ADDRESS, MAX30100_FIFO_W_POINTER, data_read, 1); - char wrPtr = data_read[0]; - i2c_read(MAX30100_ADDRESS, MAX30100_FIFO_R_POINTER, data_read, 1); - char rdPtr = data_read[0]; - return (abs( 16 + (int)wrPtr - (int)rdPtr ) % 16); -} - -void MAX30100::setTemp(void){ - char data_read[1]; - char data_write[1]; - i2c_read(MAX30100_ADDRESS, MAX30100_CONFIG, data_read, 1); - data_write[0] = data_read[0] | 0x0B; // Set SPO2 Mode and enable temperature - i2c_write(MAX30100_ADDRESS, MAX30100_CONFIG, data_write, 1); // Mask MODE - i2c_read(MAX30100_ADDRESS, MAX30100_CONFIG, data_read, 1); -} - -void MAX30100::setSPO2mode(void){ - char data_read[1]; - char data_write[1]; - i2c_read(MAX30100_ADDRESS, MAX30100_CONFIG, data_read, 1); - data_write[0] = data_read[0] | 0x03; // Set SPO2 Mode - i2c_write(MAX30100_ADDRESS, MAX30100_CONFIG, data_write, 1); -} - -int MAX30100::readTemp(void){ - char data_read[1]; - char temp_int, temp_fract; - int temp_measured; - i2c_read(MAX30100_ADDRESS, MAX30100_TEMP_INTEGER, data_read, 1); - temp_int = data_read[0]; - i2c_read(MAX30100_ADDRESS, MAX30100_TEMP_FRACTION, data_read, 1); - temp_fract = data_read[0] & 0x0F; - temp_measured = ((int)temp_int)+(((int)temp_fract) >> 4); - return temp_measured; -} - -void MAX30100::readSensor(void){ - char data_read[4]; - i2c_read(MAX30100_ADDRESS, MAX30100_FIFO_DATA_REG, data_read, 4); // Read four times from the FIFO - HR = (data_read[0]<<8) | data_read[1]; // Combine values to get the actual number - SPO2 = (data_read[2]<<8) | data_read[3]; // Combine values to get the actual number -} - -void MAX30100::shutdown(void){ - char data_read[1]; - char data_write[1]; - i2c_read(MAX30100_ADDRESS, MAX30100_CONFIG, data_read, 1); // Get the current register - data_write[0] = data_read[0] | 0x80; - i2c_write(MAX30100_ADDRESS, MAX30100_CONFIG, data_write, 1); // mask the SHDN bit -} - -void MAX30100::reset(void){ - char data_read[1]; - char data_write[1]; - i2c_read(MAX30100_ADDRESS, MAX30100_CONFIG, data_read, 1); // Get the current register - data_write[0] = data_read[0] | 0x40; - i2c_write(MAX30100_ADDRESS, MAX30100_CONFIG, data_write, 1); // mask the RESET bit -} - -void MAX30100::startup(void){ - char data_read[1]; - char data_write[1]; - i2c_read(MAX30100_ADDRESS, MAX30100_CONFIG, data_read, 1); // Get the current register - data_write[0] = data_read[0] & 0x7F; - i2c_write(MAX30100_ADDRESS, MAX30100_CONFIG, data_write, 1); // mask the SHDN bit -} - -char MAX30100::getRevID(void){ - char data_read[1]; - i2c_read(MAX30100_ADDRESS, MAX30100_REVISION_ID, data_read, 1); - return data_read[0]; -} - -char MAX30100::getPartID(void){ - char data_read[1]; - i2c_read(MAX30100_ADDRESS, MAX30100_PART_ID, data_read, 1); - return data_read[0]; -} - -void MAX30100::begin(pulseWidth pw, ledCurrent ir, sampleRate sr){ - char data_write[1]; - data_write[0] = 0x03; - i2c_write(MAX30100_ADDRESS, MAX30100_CONFIG, data_write, 1); // Heart rate only - data_write[0] = ir; - i2c_write(MAX30100_ADDRESS, MAX30100_LED_CONFIG, data_write, 1); - data_write[0] = ((sr<<2)|pw); - i2c_write(MAX30100_ADDRESS, MAX30100_SPO2_CONFIG, data_write, 1); -} - -void MAX30100::init(pulseWidth pw, sampleRate sr, high_resolution hi_res, ledCurrent red, ledCurrent ir){ - - setLEDs(pw, red, ir); - setSPO2(sr, hi_res); - -} - -void MAX30100::printRegisters(void){ - char data_read[1]; - i2c_read(MAX30100_ADDRESS, MAX30100_INT_STATUS, data_read, 1); - pc.printf("INT_STATUS: %#4X\r\n", data_read[0]); - i2c_read(MAX30100_ADDRESS, MAX30100_INT_ENABLE, data_read, 1); - pc.printf("INT_ENABLE: %#4X\r\n", data_read[0]); - i2c_read(MAX30100_ADDRESS, MAX30100_FIFO_W_POINTER, data_read, 1); - pc.printf("FIFO_W_POINTER: %#4X\r\n", data_read[0]); - i2c_read(MAX30100_ADDRESS, MAX30100_OVR_COUNTER, data_read, 1); - pc.printf("OVR_COUNTER: %#4X\r\n", data_read[0]); - i2c_read(MAX30100_ADDRESS, MAX30100_FIFO_R_POINTER, data_read, 1); - pc.printf("FIFO_R_POINTER: %#4X\r\n", data_read[0]); - i2c_read(MAX30100_ADDRESS, MAX30100_FIFO_DATA_REG, data_read, 1); - pc.printf("FIFO_DATA_REG: %#4X\r\n", data_read[0]); - i2c_read(MAX30100_ADDRESS, MAX30100_CONFIG, data_read, 1); - pc.printf("CONFIG: %#4X\r\n", data_read[0]); - i2c_read(MAX30100_ADDRESS, MAX30100_SPO2_CONFIG, data_read, 1); - pc.printf("SPO2_CONFIG: %#4X\r\n", data_read[0]); - i2c_read(MAX30100_ADDRESS, MAX30100_LED_CONFIG, data_read, 1); - pc.printf("LED_CONFIG: %#4X\r\n", data_read[0]); - i2c_read(MAX30100_ADDRESS, MAX30100_TEMP_INTEGER, data_read, 1); - pc.printf("TEMP_INTEGER: %#4X\r\n", data_read[0]); - i2c_read(MAX30100_ADDRESS, MAX30100_TEMP_FRACTION, data_read, 1); - pc.printf("TEMP_FRACTION: %#4X\r\n", data_read[0]); - i2c_read(MAX30100_ADDRESS, MAX30100_REVISION_ID, data_read, 1); - pc.printf("REVISION_ID: %#4X\r\n", data_read[0]); - i2c_read(MAX30100_ADDRESS, MAX30100_PART_ID, data_read, 1); - pc.printf("PART_ID: %#4X\r\n", data_read[0]); -}
--- a/max30100.h Sun Apr 03 13:43:19 2016 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,149 +0,0 @@ -/* - Library for the Maxim MAX30100 pulse oximetry system - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __MAX30100_H -#define __MAX30100_H - -#include "mbed.h" - - -/******************************************************************************/ -/*********** PULSE OXIMETER AND HEART RATE REGISTER MAPPING **************/ -/******************************************************************************/ - -// status registers -#define MAX30100_INT_STATUS 0x00 -#define MAX30100_INT_ENABLE 0x01 - -// FIFO registers -#define MAX30100_FIFO_W_POINTER 0x02 -#define MAX30100_OVR_COUNTER 0x03 -#define MAX30100_FIFO_R_POINTER 0x04 -#define MAX30100_FIFO_DATA_REG 0x05 - -// configuration registers -#define MAX30100_CONFIG 0x06 -#define MAX30100_SPO2_CONFIG 0x07 -#define MAX30100_LED_CONFIG 0x09 - -// temperature registers -#define MAX30100_TEMP_INTEGER 0x16 -#define MAX30100_TEMP_FRACTION 0x17 - -// PART ID registers -#define MAX30100_REVISION_ID 0xFE -#define MAX30100_PART_ID 0xFF - -#define I_AM_MAX30100 0x11 - -/************************************** REGISTERS VALUE *******************************************/ - -// I2C address -#define MAX30100_ADDRESS 0xAE - -//Enable interrupts -#define MAX30100_INT_ENB_A_FULL ((uint8_t)0x80) -#define MAX30100_INT_ENB_TEMP_RDY ((uint8_t)0x40) -#define MAX30100_INT_ENB_HR_RDY ((uint8_t)0x20) -#define MAX30100_INT_ENB_SO2_RDY ((uint8_t)0x10) - -//Mode configuration -#define MAX30100_MODE_SHDN ((uint8_t)0x80) -#define MAX30100_MODE_RESET ((uint8_t)0x40) -#define MAX30100_MODE_TEMP_EN ((uint8_t)0x08) -#define MAX30100_MODE_HR ((uint8_t)0x02) -#define MAX30100_MODE_SPO2 ((uint8_t)0x03) - -//SPO2 configuration -#define MAX30100_SPO2_HI_RES_EN ((uint8_t)0x40) - -typedef enum{ // This is the same for both LEDs - pw200, // 200us pulse - pw400, // 400us pulse - pw800, // 800us pulse - pw1600 // 1600us pulse -}pulseWidth; - -typedef enum{ - sr50, // 50 samples per second - sr100, // 100 samples per second - sr167, // 167 samples per second - sr200, // 200 samples per second - sr400, // 400 samples per second - sr600, // 600 samples per second - sr800, // 800 samples per second - sr1000 // 1000 samples per second -}sampleRate; - -typedef enum{ - i0, // No current - i4, // 4.4mA - i8, // 7.6mA - i11, // 11.0mA - i14, // 14.2mA - i17, // 17.4mA - i21, // 20.8mA - i27, // 27.1mA - i31, // 30.6mA - i34, // 33.8mA - i37, // 37.0mA - i40, // 40.2mA - i44, // 43.6mA - i47, // 46.8mA - i50 // 50.0mA -}ledCurrent; - -typedef enum{ - low, // low resolution SPO2 - high // high resolution SPO2 (16 bit with 1.6ms LED pulse width) -}high_resolution; - -typedef enum -{ - OXIMETER_OK = 0, - OXIMETER_ERROR = 1, - OXIMETER_TIMEOUT = 2, - OXIMETER_NOT_IMPLEMENTED = 3 -} OXIMETER_StatusTypeDef; - -/** - * @brief MAX30100 driver extended internal structure definition - */ -typedef struct -{ - OXIMETER_StatusTypeDef (*Enable_Free_Fall_Detection) (void); - OXIMETER_StatusTypeDef (*Disable_Free_Fall_Detection) (void); - OXIMETER_StatusTypeDef (*Get_Status_Free_Fall_Detection) (uint8_t *); -} MAX30100_DrvExtTypeDef; - -class MAX30100 { -public: - - /* Public Methods */ - - uint16_t HR; // Last heart rate datapoint - uint16_t SPO2; // Last oximetry datapoint - - void setLEDs(pulseWidth pw, ledCurrent red, ledCurrent ir); // Sets the LED state - void setSPO2(sampleRate sr, high_resolution hi_res); // Setup the SPO2 sensor, disabled by default - int getNumSamp(void); // Get number of samples - void readSensor(void); // Updates the values - void shutdown(void); // Instructs device to power-save - void reset(void); // Resets the device - void startup(void); // Leaves power-save - char getRevID(void); // Gets revision ID - char getPartID(void); // Gets part ID - void begin(pulseWidth pw = pw1600, // Longest pulseWidth - ledCurrent ir = i50, // Highest current - sampleRate sr = sr100); // 2nd lowest sampleRate - void init(pulseWidth pw, sampleRate sr, high_resolution hi_res, ledCurrent red, ledCurrent ir); - void setTemp(void); - int readTemp(void); - void setSPO2mode(void); - void setInterruptSPO2(void); - void printRegisters(void); // Dumps contents of registers for debug -}; - -#endif /* __MAX30100_H */ \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/max30102.cpp Tue Jun 21 09:43:15 2016 +0000 @@ -0,0 +1,183 @@ +/* + * Library for the Maxim MAX30102 pulse oximetry system, I modified a copy of the MAX30100 library in May 2016 + */ + +#include "max30102.h" +#include "functions.h" + +Serial pc(USBTX, USBRX); + +void MAX30102::setLEDs(pulseWidth pw, ledCurrent red, ledCurrent ir){ + char data_read[1]; + char data_write[1]; + i2c_read(MAX30102_ADDRESS, MAX30102_SPO2_CONFIG, data_read, 1); + data_read[0] = data_read[0] & 0xFD; // Set LED_PW to 01 + data_write[0] = data_read[0] | pw; + i2c_write(MAX30102_ADDRESS, MAX30102_SPO2_CONFIG, data_write, 1); // Mask LED_PW + data_write[0] = (red); + i2c_write(MAX30102_ADDRESS, MAX30102_LED_CONFIG_1, data_write, 1); // write LED1 configs + data_write[0] = (ir); + i2c_write(MAX30102_ADDRESS, MAX30102_LED_CONFIG_2, data_write, 1); // write LED2 configs +} + +void MAX30102::setSPO2(sampleRate sr, high_resolution hi_res){ + char data_read[1]; + char data_write[1]; + i2c_read(MAX30102_ADDRESS, MAX30102_SPO2_CONFIG, data_read, 1); + data_read[0] = data_read[0] & 0x85; // Set ADC_rge to 00, SPO2_SR to 001 = sr100 and LEDpw to 01 = 118 + data_write[0] = data_read[0] | (sr<<2) | (hi_res<<6); + i2c_write(MAX30102_ADDRESS, MAX30102_SPO2_CONFIG, data_write, 1); // Mask SPO2_SR + i2c_read(MAX30102_ADDRESS, MAX30102_CONFIG, data_read, 1); + data_write[0] = data_read[0] & 0xF8; // Set Mode to 000 + i2c_write(MAX30102_ADDRESS, MAX30102_CONFIG, data_write, 1); // Mask MODE +} + +void MAX30102::setInterruptSPO2(void){ + char data_read[1]; + char data_write[1]; + i2c_read(MAX30102_ADDRESS, MAX30102_INT_ENABLE, data_read, 1); + data_write[0] = data_read[0] & 0x00; // Set Interrupt enable for SPO2 | 0x10 // New: disable prox! & ~0x10 + i2c_write(MAX30102_ADDRESS, MAX30102_INT_ENABLE, data_write, 1); // Mask ENB_SPO2_RDY +} + +int MAX30102::getNumSamp(void){ + char data_read[1] = {0}; +// i2c_write(MAX30102_ADDRESS, MAX30102_FIFO_W_POINTER, data_read, 1); +// i2c_write(MAX30102_ADDRESS, MAX30102_FIFO_R_POINTER, data_read, 1); +// wait(0.148); + i2c_read(MAX30102_ADDRESS, MAX30102_FIFO_W_POINTER, data_read, 1); + char wrPtr = data_read[0]; + i2c_read(MAX30102_ADDRESS, MAX30102_FIFO_R_POINTER, data_read, 1); + char rdPtr = data_read[0]; + return ((int)wrPtr - (int)rdPtr); // New counting + // return (abs( 16 + (int)wrPtr - (int)rdPtr ) % 16); +} + +void MAX30102::setTemp(void){ + char data_read[1]; + char data_write[1]; + i2c_read(MAX30102_ADDRESS, MAX30102_TEMP_CONFIG, data_read, 1); + data_write[0] = data_read[0] | 0x01; // Enable temperature + i2c_write(MAX30102_ADDRESS, MAX30102_TEMP_CONFIG, data_write, 1); // Mask MODE + i2c_read(MAX30102_ADDRESS, MAX30102_TEMP_CONFIG, data_read, 1); +} + +void MAX30102::setSPO2mode(void){ + char data_read[1]; + char data_write[1]; + i2c_read(MAX30102_ADDRESS, MAX30102_CONFIG, data_read, 1); + data_write[0] = data_read[0] | 0x03; // Set SPO2 Mode + i2c_write(MAX30102_ADDRESS, MAX30102_CONFIG, data_write, 1); +} + +int MAX30102::readTemp(void){ + char data_read[1]; + char temp_int, temp_fract; + int temp_measured; + i2c_read(MAX30102_ADDRESS, MAX30102_TEMP_INTEGER, data_read, 1); + temp_int = data_read[0]; + i2c_read(MAX30102_ADDRESS, MAX30102_TEMP_FRACTION, data_read, 1); + temp_fract = data_read[0] & 0x0F; + temp_measured = ((int)temp_int)+(((int)temp_fract) >> 4); + return temp_measured; +} + +void MAX30102::readSensor(void){ + char data_read[6] = {0}; + HR = 0; + SPO2 = 0; + i2c_read(MAX30102_ADDRESS, MAX30102_FIFO_DATA_REG, data_read, 6); // Read six times from the FIFO + HR = (data_read[0]<<16) | (data_read[1]<<8) | data_read[2]; // Combine values to get the actual number + HR = HR>>2; + SPO2 = (data_read[3]<<16) | (data_read[4]<<8) | data_read[5]; // Combine values to get the actual number + SPO2 = SPO2>>2; +} + +void MAX30102::shutdown(void){ + char data_read[1]; + char data_write[1]; + i2c_read(MAX30102_ADDRESS, MAX30102_CONFIG, data_read, 1); // Get the current register + data_write[0] = data_read[0] | 0x80; + i2c_write(MAX30102_ADDRESS, MAX30102_CONFIG, data_write, 1); // mask the SHDN bit +} + +void MAX30102::reset(void){ + char data_read[1]; + char data_write[1]; + i2c_read(MAX30102_ADDRESS, MAX30102_CONFIG, data_read, 1); // Get the current register + data_write[0] = data_read[0] | 0x40; + i2c_write(MAX30102_ADDRESS, MAX30102_CONFIG, data_write, 1); // mask the RESET bit +} + +void MAX30102::startup(void){ + char data_read[1]; + char data_write[1]; + i2c_read(MAX30102_ADDRESS, MAX30102_CONFIG, data_read, 1); // Get the current register + data_write[0] = data_read[0] & 0x7F; + i2c_write(MAX30102_ADDRESS, MAX30102_CONFIG, data_write, 1); // mask the SHDN bit +} + +char MAX30102::getRevID(void){ + char data_read[1]; + i2c_read(MAX30102_ADDRESS, MAX30102_REVISION_ID, data_read, 1); + return data_read[0]; +} + +char MAX30102::getPartID(void){ + char data_read[1]; + i2c_read(MAX30102_ADDRESS, MAX30102_PART_ID, data_read, 1); + return data_read[0]; +} + +void MAX30102::begin(pulseWidth pw, ledCurrent ir, sampleRate sr){ + char data_write[1]; + data_write[0] = 0x02; + i2c_write(MAX30102_ADDRESS, MAX30102_CONFIG, data_write, 1); // Heart rate only + data_write[0] = ir; + i2c_write(MAX30102_ADDRESS, MAX30102_LED_CONFIG_1, data_write, 1); + data_write[0] = ((sr<<2)|pw); + i2c_write(MAX30102_ADDRESS, MAX30102_SPO2_CONFIG, data_write, 1); +} + +void MAX30102::init(pulseWidth pw, sampleRate sr, high_resolution hi_res, ledCurrent red, ledCurrent ir){ + char data_write[1]; + + setLEDs(pw, red, ir); + setSPO2(sr, hi_res); + + data_write[0] = 0x10; + i2c_write(MAX30102_ADDRESS, MAX30102_FIFO_CONFIG, data_write, 1); + +} + +void MAX30102::printRegisters(void){ + char data_read[1]; + i2c_read(MAX30102_ADDRESS, MAX30102_INT_STATUS, data_read, 1); + pc.printf("INT_STATUS: %#4X\r\n", data_read[0]); + i2c_read(MAX30102_ADDRESS, MAX30102_INT_ENABLE, data_read, 1); + pc.printf("INT_ENABLE: %#4X\r\n", data_read[0]); + i2c_read(MAX30102_ADDRESS, MAX30102_FIFO_W_POINTER, data_read, 1); + pc.printf("FIFO_W_POINTER: %#4X\r\n", data_read[0]); + i2c_read(MAX30102_ADDRESS, MAX30102_OVR_COUNTER, data_read, 1); + pc.printf("OVR_COUNTER: %#4X\r\n", data_read[0]); + i2c_read(MAX30102_ADDRESS, MAX30102_FIFO_R_POINTER, data_read, 1); + pc.printf("FIFO_R_POINTER: %#4X\r\n", data_read[0]); + i2c_read(MAX30102_ADDRESS, MAX30102_FIFO_DATA_REG, data_read, 1); + pc.printf("FIFO_DATA_REG: %#4X\r\n", data_read[0]); + i2c_read(MAX30102_ADDRESS, MAX30102_CONFIG, data_read, 1); + pc.printf("CONFIG: %#4X\r\n", data_read[0]); + i2c_read(MAX30102_ADDRESS, MAX30102_SPO2_CONFIG, data_read, 1); + pc.printf("SPO2_CONFIG: %#4X\r\n", data_read[0]); + i2c_read(MAX30102_ADDRESS, MAX30102_LED_CONFIG_2, data_read, 1); + pc.printf("LED_CONFIG: %#4X\r\n", data_read[0]); + i2c_read(MAX30102_ADDRESS, MAX30102_TEMP_INTEGER, data_read, 1); + pc.printf("TEMP_INTEGER: %#4X\r\n", data_read[0]); + i2c_read(MAX30102_ADDRESS, MAX30102_TEMP_FRACTION, data_read, 1); + pc.printf("TEMP_FRACTION: %#4X\r\n", data_read[0]); + i2c_read(MAX30102_ADDRESS, MAX30102_TEMP_CONFIG, data_read, 1); + pc.printf("TEMP_CONFIG: %#4X\r\n", data_read[0]); + i2c_read(MAX30102_ADDRESS, MAX30102_REVISION_ID, data_read, 1); + pc.printf("REVISION_ID: %#4X\r\n", data_read[0]); + i2c_read(MAX30102_ADDRESS, MAX30102_PART_ID, data_read, 1); + pc.printf("PART_ID: %#4X\r\n", data_read[0]); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/max30102.h Tue Jun 21 09:43:15 2016 +0000 @@ -0,0 +1,150 @@ +/* + * Library for the Maxim MAX30102 pulse oximetry system, I modified a copy of the MAX30100 library in May 2016 + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __MAX30102_H +#define __MAX30102_H + +#include "mbed.h" + + +/******************************************************************************/ +/*********** PULSE OXIMETER AND HEART RATE REGISTER MAPPING **************/ +/******************************************************************************/ + +// status registers +#define MAX30102_INT_STATUS 0x00 +#define MAX30102_INT_ENABLE 0x02 + +// FIFO registers +#define MAX30102_FIFO_W_POINTER 0x04 +#define MAX30102_OVR_COUNTER 0x05 +#define MAX30102_FIFO_R_POINTER 0x06 +#define MAX30102_FIFO_DATA_REG 0x07 + +// configuration registers +#define MAX30102_FIFO_CONFIG 0x08 +#define MAX30102_CONFIG 0x09 +#define MAX30102_SPO2_CONFIG 0x0A +#define MAX30102_LED_CONFIG_1 0x0C +#define MAX30102_LED_CONFIG_2 0x0D + +// temperature registers +#define MAX30102_TEMP_INTEGER 0x1F +#define MAX30102_TEMP_FRACTION 0x20 +#define MAX30102_TEMP_CONFIG 0x21 + +// PART ID registers +#define MAX30102_REVISION_ID 0xFE +#define MAX30102_PART_ID 0xFF + +#define I_AM_MAX30102 0x15 + +/************************************** REGISTERS VALUE *******************************************/ + +// I2C address +#define MAX30102_ADDRESS 0xAE + +//Enable interrupts +#define MAX30102_INT_ENB_A_FULL ((uint8_t)0x80) +#define MAX30102_INT_ENB_TEMP_RDY ((uint8_t)0x40) +#define MAX30102_INT_ENB_HR_RDY ((uint8_t)0x20) +#define MAX30102_INT_ENB_SO2_RDY ((uint8_t)0x10) + +//Mode configuration +#define MAX30102_MODE_SHDN ((uint8_t)0x80) // Bit 7 high +#define MAX30102_MODE_RESET ((uint8_t)0x40) // Bit 6 high +#define MAX30102_MODE_TEMP_EN ((uint8_t)0x01) +#define MAX30102_MODE_HR ((uint8_t)0x02) +#define MAX30102_MODE_SPO2 ((uint8_t)0x03) + +//SPO2 configuration +#define MAX30102_SPO2_HI_RES_EN ((uint8_t)0x40) + +typedef enum{ // This is the same for both LEDs + pw68, // 68us pulse, ADC 15 + pw118, // 118us pulse, ADC 16 + pw215, // 215us pulse, ADC 17 + pw411 // 411us pulse, ADC 18 +}pulseWidth; + +typedef enum{ + sr50, // 50 samples per second + sr100, // 100 samples per second + sr200, // 200 samples per second + sr400, // 400 samples per second + sr800, // 800 samples per second + sr1000 // 1000 samples per second +}sampleRate; + +typedef enum{ + i0, // No current + i4, // 4.4mA + i8, // 7.6mA + i11, // 11.0mA + i14, // 14.2mA + i17, // 17.4mA + i21, // 20.8mA + i27, // 27.1mA + i31, // 30.6mA + i34, // 33.8mA + i37, // 37.0mA + i40, // 40.2mA + i44, // 43.6mA + i47, // 46.8mA + i50 // 50.0mA +}ledCurrent; + +typedef enum{ + low, // low resolution SPO2 + high // high resolution SPO2 (18 bit with 411us LED pulse width) +}high_resolution; + +typedef enum +{ + OXIMETER_OK = 0, + OXIMETER_ERROR = 1, + OXIMETER_TIMEOUT = 2, + OXIMETER_NOT_IMPLEMENTED = 3 +} OXIMETER_StatusTypeDef; + +/** + * @brief MAX30102 driver extended internal structure definition + */ +typedef struct +{ + OXIMETER_StatusTypeDef (*Enable_Free_Fall_Detection) (void); + OXIMETER_StatusTypeDef (*Disable_Free_Fall_Detection) (void); + OXIMETER_StatusTypeDef (*Get_Status_Free_Fall_Detection) (uint8_t *); +} MAX30102_DrvExtTypeDef; + +class MAX30102 { +public: + + /* Public Methods */ + + uint32_t HR; // Last heart rate datapoint + uint32_t SPO2; // Last oximetry datapoint + + void setLEDs(pulseWidth pw, ledCurrent red, ledCurrent ir); // Sets the LED state + void setSPO2(sampleRate sr, high_resolution hi_res); // Setup the SPO2 sensor, disabled by default + int getNumSamp(void); // Get number of samples + void readSensor(void); // Updates the values + void shutdown(void); // Instructs device to power-save + void reset(void); // Resets the device + void startup(void); // Leaves power-save + char getRevID(void); // Gets revision ID + char getPartID(void); // Gets part ID + void begin(pulseWidth pw = pw411, // Longest pulseWidth + ledCurrent ir = i50, // Highest current + sampleRate sr = sr100); // 2nd lowest sampleRate + void init(pulseWidth pw, sampleRate sr, high_resolution hi_res, ledCurrent red, ledCurrent ir); + void setTemp(void); + int readTemp(void); + void setSPO2mode(void); + void setInterruptSPO2(void); + void printRegisters(void); // Dumps contents of registers for debug +}; + +#endif /* __MAX30102_H */ \ No newline at end of file