StepOne / MAX30100

Dependents:   StepOne (store accelerometer value)

Files at this revision

API Documentation at this revision

Comitter:
ajeje41
Date:
Sun Apr 03 13:43:19 2016 +0000
Commit message:
StepOne (store accelerometer value)

Changed in this revision

max30100.cpp Show annotated file Show diff for this revision Revisions of this file
max30100.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/max30100.cpp	Sun Apr 03 13:43:19 2016 +0000
@@ -0,0 +1,167 @@
+/*
+ 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]);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/max30100.h	Sun Apr 03 13:43:19 2016 +0000
@@ -0,0 +1,149 @@
+/*
+ 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