MAX30100 pulse rate sensor

Dependencies:   PulseRate

Dependents:   PulseRate

Revision:
3:fa37b0c705b3
Parent:
2:d329886938f1
Child:
4:008e40a7d035
--- a/MAX30100.h	Wed Aug 23 19:04:51 2017 +0000
+++ b/MAX30100.h	Sun Nov 26 21:56:10 2017 +0000
@@ -4,7 +4,7 @@
 #include "mbed.h"
 
 //definitions
-#define MAX30100_ADDRESS 0x57
+#define MAX30100_ADDRESS 0xAE
 
 // Registers
 #define MAX30100_INT_STATUS     0x00  // Which interrupts are tripped
@@ -60,7 +60,8 @@
 }ledCurrent;
 
 //Set up I2C, (SDA,SCL)
-I2C i2c(I2C_SDA, I2C_SCL);
+static I2C i2c(I2C_SDA, I2C_SCL);
+static Serial pc(USBTX, USBRX); // tx, rx
 
 uint16_t IR = 0;      // Last IR reflectance datapoint
 uint16_t RED = 0;     // Last Red reflectance datapoint
@@ -72,93 +73,146 @@
     public:
     
     //Wire read and write protocols
-    void writeByte(uint8_t address, uint8_t subAddress, uint8_t data)
+static int i2c_write (uint8_t i2c_addr, uint8_t register_addr, char* buffer, uint8_t Nbyte )
 {
-   char data_write[2];
-   data_write[0] = subAddress;
-   data_write[1] = data;
-   i2c.write(address, data_write, 2, 0);
-}
+    int ret;
+    char *tmp_buffer;
+
+    tmp_buffer = (char*)malloc(sizeof(char)*(Nbyte+1));
 
-    char readByte(uint8_t address, uint8_t subAddress)
-{
-    char data[1]; // `data` will store the register data     
-    char data_write[1];
-    data_write[0] = subAddress;
-    i2c.write(address, data_write, 1, 1); // no stop
-    i2c.read(address, data, 1, 0); 
-    return data[0]; 
+    /* First, send device address. Then, send data and STOP condition */
+    tmp_buffer[0] = register_addr;
+    memcpy(tmp_buffer+1, buffer, Nbyte);
+
+    ret = i2c.write(i2c_addr, tmp_buffer, Nbyte+1, false);
+
+    return ret;
 }
 
-    void readBytes(uint8_t address, uint8_t subAddress, uint8_t count, uint8_t * dest)
-{     
-    char data[14];
-    char data_write[1];
-    data_write[0] = subAddress;
-    i2c.write(address, data_write, 1, 1); // no stop
-    i2c.read(address, data, count, 0); 
-    for(int ii = 0; ii < count; ii++) {
-        dest[ii] = data[ii];
+static int i2c_read (uint8_t i2c_addr, uint8_t register_addr, char* buffer, uint8_t Nbyte )
+{
+    int ret;
+
+    /* Send device address, with no STOP condition */
+    ret = i2c.write(i2c_addr, (const char*)&register_addr, 1, true);
+    if(!ret) {
+        /* Read data, with STOP condition  */
+        ret = i2c.read((i2c_addr|0x01), buffer, Nbyte, false);
     }
+
+    return ret;
 }
     //
-    
+   
 void setLEDs(pulseWidth pw, ledCurrent red, ledCurrent ir){
-  uint8_t reg = readByte(MAX30100_ADDRESS, MAX30100_SPO2_CONFIG);
-  reg = reg & 0xFC; // Set LED_PW to 00
-  writeByte(MAX30100_ADDRESS, MAX30100_SPO2_CONFIG, reg | pw);     // Mask LED_PW
-  writeByte(MAX30100_ADDRESS, MAX30100_LED_CONFIG, (red<<4) | ir); // write LED configs
+  char reg[1];
+  i2c_read(MAX30100_ADDRESS, MAX30100_SPO2_CONFIG, &reg[0], 1);
+  reg[0] = reg[0] & 0xFC; // Set LED_PW to 00
+  reg[0] = reg[0] | pw;
+  i2c_write(MAX30100_ADDRESS, MAX30100_SPO2_CONFIG, &reg[0], 1);     // Mask LED_PW
+  reg[0] = (red<<4) | ir;
+  i2c_write(MAX30100_ADDRESS, MAX30100_LED_CONFIG, &reg[0], 1); // write LED configs
 }
 
 void setSPO2(sampleRate sr){
-  uint8_t reg = readByte(MAX30100_ADDRESS, MAX30100_SPO2_CONFIG);
-  reg = reg & 0xE3; // Set SPO2_SR to 000
-  writeByte(MAX30100_ADDRESS, MAX30100_SPO2_CONFIG, reg | (sr<<2)); // Mask SPO2_SR
-  reg = readByte(MAX30100_ADDRESS, MAX30100_MODE_CONFIG);
-  reg = reg & 0xf8; // Set Mode to 000
-  writeByte(MAX30100_ADDRESS, MAX30100_SPO2_CONFIG, reg | 0x03); // Mask MODE
+  char reg[1];
+  i2c_read(MAX30100_ADDRESS, MAX30100_SPO2_CONFIG, &reg[0], 1);
+  reg[0] = reg[0] & 0xE3; // Set SPO2_SR to 000
+  reg[0] = reg[0] | (sr<<2);
+  i2c_write(MAX30100_ADDRESS, MAX30100_SPO2_CONFIG, &reg[0], 1); // Mask SPO2_SR
+  i2c_read(MAX30100_ADDRESS, MAX30100_MODE_CONFIG, &reg[0], 1);
+  reg[0] = reg[0] & 0xf8; // Set Mode to 000
+  reg[0] = reg[0] | 0x03;
+  i2c_write(MAX30100_ADDRESS, MAX30100_SPO2_CONFIG, &reg[0], 1); // Mask MODE
 }
 
 int getNumSamp(void){
-    uint8_t wrPtr = readByte(MAX30100_ADDRESS, MAX30100_FIFO_WR_PTR);
-    uint8_t rdPtr = readByte(MAX30100_ADDRESS, MAX30100_FIFO_RD_PTR);
-    return (abs( 16 + wrPtr - rdPtr ) % 16);
+    char wrPtr[1];
+    char rdPtr[1];
+    i2c_read(MAX30100_ADDRESS, MAX30100_FIFO_WR_PTR, &wrPtr[0], 1);
+    i2c_read(MAX30100_ADDRESS, MAX30100_FIFO_RD_PTR, &rdPtr[0], 1);
+    return (abs( 16 + wrPtr[0] - rdPtr[0] ) % 16);
 }
 
 void readSensor(void){
-  uint8_t temp[4] = {0};  // Temporary buffer for read values
-  readBytes(MAX30100_ADDRESS, MAX30100_FIFO_DATA, 4, &temp[0]);  // Read four times from the FIFO
+  char temp[4] = {0};  // Temporary buffer for read values
+  i2c_read(MAX30100_ADDRESS, MAX30100_FIFO_DATA, &temp[0], 4);  // Read four times from the FIFO
   IR = (temp[0]<<8) | temp[1];    // Combine values to get the actual number
   RED = (temp[2]<<8) | temp[3];   // Combine values to get the actual number
 }
 
 void shutdown(void){
-  uint8_t reg = readByte(MAX30100_ADDRESS, MAX30100_MODE_CONFIG);  // Get the current register
-  writeByte(MAX30100_ADDRESS, MAX30100_MODE_CONFIG, reg | 0x80);   // mask the SHDN bit
+  char reg[1];
+  i2c_read(MAX30100_ADDRESS, MAX30100_MODE_CONFIG, &reg[0], 1);  // Get the current register
+  reg[0] = reg[0] | 0x80;
+  i2c_write(MAX30100_ADDRESS, MAX30100_MODE_CONFIG, &reg[0], 1);   // mask the SHDN bit
 }
 
 void reset(void){
-  uint8_t reg = readByte(MAX30100_ADDRESS, MAX30100_MODE_CONFIG);  // Get the current register
-  writeByte(MAX30100_ADDRESS, MAX30100_MODE_CONFIG, reg | 0x40);   // mask the RESET bit
+  char reg[1];
+  i2c_read(MAX30100_ADDRESS, MAX30100_MODE_CONFIG, &reg[0], 1);  // Get the current register
+  reg[0] = reg[0] | 0x40;
+  i2c_write(MAX30100_ADDRESS, MAX30100_MODE_CONFIG, &reg[0], 1);   // mask the RESET bit
 }
 
 void startup(void){
-  uint8_t reg = readByte(MAX30100_ADDRESS, MAX30100_MODE_CONFIG);  // Get the current register
-  writeByte(MAX30100_ADDRESS, MAX30100_MODE_CONFIG, reg & 0x7F);   // mask the SHDN bit
+  char reg[1];
+  i2c_read(MAX30100_ADDRESS, MAX30100_MODE_CONFIG, &reg[0], 1);  // Get the current register
+  reg[0] = reg[0] & 0x7F;
+  i2c_write(MAX30100_ADDRESS, MAX30100_MODE_CONFIG, &reg[0], 1);   // mask the SHDN bit
 }
 
-int getRevID(void){
-  return readByte(MAX30100_ADDRESS, MAX30100_REV_ID);
+uint8_t getRevID(void){
+  char buffer[1];
+  i2c_read(MAX30100_ADDRESS, MAX30100_REV_ID, &buffer[0], 1);
+  return buffer[0];
 }
 
-int getPartID(void){
-  return readByte(MAX30100_ADDRESS, MAX30100_PART_ID);
+uint8_t getPartID(void){
+  char buffer[1];
+  i2c_read(MAX30100_ADDRESS, MAX30100_PART_ID, &buffer[0], 1);
+  return buffer[0];
 }
 
 void begin(pulseWidth pw, ledCurrent ir, sampleRate sr){
-  writeByte(MAX30100_ADDRESS, MAX30100_MODE_CONFIG, 0x02); // Heart rate only
-  writeByte(MAX30100_ADDRESS, MAX30100_LED_CONFIG, ir);
-  writeByte(MAX30100_ADDRESS, MAX30100_SPO2_CONFIG, (sr<<2)|pw);
+  char buffer[1];
+  buffer[0] = 0x02;
+  i2c_write(MAX30100_ADDRESS, MAX30100_MODE_CONFIG, &buffer[0], 1); // Heart rate only
+  buffer[0] = ir;
+  i2c_write(MAX30100_ADDRESS, MAX30100_LED_CONFIG, &buffer[0], 1);
+  buffer[0] = (sr<<2)|pw;
+  i2c_write(MAX30100_ADDRESS, MAX30100_SPO2_CONFIG, &buffer[0], 1);
 }
+
+void printRegisters(){
+    char reg[1];
+    i2c_read(MAX30100_ADDRESS, MAX30100_INT_STATUS, &reg[0], 1);
+    pc.printf("MAX30100_INT_STATUS: %d\r\n",reg[0]);
+    i2c_read(MAX30100_ADDRESS, MAX30100_INT_ENABLE, &reg[0], 1);
+    pc.printf("MAX30100_INT_ENABLE: %d\r\n",reg[0]);
+    i2c_read(MAX30100_ADDRESS, MAX30100_FIFO_WR_PTR, &reg[0], 1);
+    pc.printf("MAX30100_FIFO_WR_PTR: %d\r\n",reg[0]);
+    i2c_read(MAX30100_ADDRESS, MAX30100_OVRFLOW_CTR, &reg[0], 1);
+    pc.printf("MAX30100_OVRFLOW_CTR: %d\r\n",reg[0]);
+    i2c_read(MAX30100_ADDRESS, MAX30100_FIFO_RD_PTR, &reg[0], 1);
+    pc.printf("MAX30100_FIFO_RD_PTR: %d\r\n",reg[0]);
+    i2c_read(MAX30100_ADDRESS, MAX30100_FIFO_DATA, &reg[0], 1);
+    pc.printf("MAX30100_FIFO_DATA: %d\r\n",reg[0]);
+    i2c_read(MAX30100_ADDRESS, MAX30100_MODE_CONFIG, &reg[0], 1);
+    pc.printf("MAX30100_MODE_CONFIG: %d\r\n",reg[0]);
+    i2c_read(MAX30100_ADDRESS, MAX30100_SPO2_CONFIG, &reg[0], 1);
+    pc.printf("MAX30100_SPO2_CONFIG: %d\r\n",reg[0]);
+    i2c_read(MAX30100_ADDRESS, MAX30100_LED_CONFIG, &reg[0], 1);
+    pc.printf("MAX30100_LED_CONFIG: %d\r\n",reg[0]);
+    i2c_read(MAX30100_ADDRESS, MAX30100_TEMP_INTG, &reg[0], 1);
+    pc.printf("MAX30100_TEMP_INTG: %d\r\n",reg[0]);
+    i2c_read(MAX30100_ADDRESS, MAX30100_TEMP_FRAC, &reg[0], 1);
+    pc.printf("MAX30100_TEMP_FRAC: %d\r\n",reg[0]);
+    i2c_read(MAX30100_ADDRESS, MAX30100_REV_ID, &reg[0], 1);
+    pc.printf("MAX30100_REV_ID: %d\r\n",reg[0]);
+    i2c_read(MAX30100_ADDRESS, MAX30100_PART_ID, &reg[0], 1);
+    pc.printf("MAX30100_PART_ID: %d\r\n",reg[0]);
+}
+
 };
 #endif
\ No newline at end of file