none
Revision 2:7d005ac4146f, committed 2019-04-12
- Comitter:
- qiaolimaxim
- Date:
- Fri Apr 12 06:56:27 2019 +0000
- Parent:
- 1:02f411fefe6f
- Commit message:
- max86150
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/i2c_functions.h Fri Apr 12 06:56:27 2019 +0000
@@ -0,0 +1,58 @@
+#ifndef __I2C_FUNCTIONS_H__
+#define __I2C_FUNCTIONS_H__
+
+#include "mbed.h"
+
+/*
+ ***************************************************************************************
+ *
+ * Functions for I2C Communication
+ *
+ ***************************************************************************************
+ */
+
+static I2C i2c(P2_6,P2_7);
+
+static int i2c_freq (int freqHz )
+{
+ i2c.frequency(freqHz);
+}
+
+static int i2c_write (uint8_t i2c_addr, uint8_t register_addr, char* buffer, uint8_t Nbyte )
+{
+ int ret;
+ char *tmp_buffer;
+
+ tmp_buffer = (char*)malloc(sizeof(char)*(Nbyte+1));
+
+ /* 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;
+}
+
+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*)®ister_addr, 1, true);
+ if(!ret) {
+ /* Read data, with STOP condition */
+ ret = i2c.read((i2c_addr|0x01), buffer, Nbyte, false);
+ }
+
+ return ret;
+}
+
+/*
+ ***************************************************************************************
+ *
+ * Functions for ....
+ *
+ ***************************************************************************************
+ */
+ #endif
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/int_example.txt Fri Apr 12 06:56:27 2019 +0000
@@ -0,0 +1,18 @@
+// Flash an LED while waiting for events
+
+#include "mbed.h"
+
+InterruptIn event(p16);
+DigitalOut led(LED1);
+
+void trigger() {
+ printf("triggered!\n");
+}
+
+int main() {
+ event.rise(&trigger);
+ while(1) {
+ led = !led;
+ wait(0.25);
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp Fri Apr 12 06:56:27 2019 +0000
@@ -0,0 +1,130 @@
+#include "mbed.h"
+#include "max86150.h"
+#include "i2c_functions.h"
+
+DigitalOut myled(P7_1);
+Serial myPC(USBTX, USBRX); // Initiating Serial Console communication
+void device_data_read(void);
+
+
+int main()
+{
+ int i=0, j=0;
+
+ i2c_freq(100000);
+ myPC.baud(57600);
+
+ while (i++<1) {
+ myled = !myled;
+ wait(1);
+
+ char data_read[9];
+ char data_write[2];
+
+ // enable()
+ data_write[0] = 0x01;
+ i2c_write(0xBC, 0x0D, data_write,1); // reset
+ data_write[0] = 0x0C;
+ i2c_write(0xBC, 0x08, data_write,1); // FIFO roll ON
+ data_write[0] = 0x21;
+ i2c_write(0xBC, 0x09, data_write,1); // FDx
+ data_write[0] = 0x09;
+ i2c_write(0xBC, 0x0A, data_write,1); // FD3=ECG
+ data_write[0] = 0xDB;
+ i2c_write(0xBC, 0x0E, data_write,1); // PPG_ADC_RANGE PPG_SR:100SpS, PPG_LED_PW:400uS
+ data_write[0] = 0x10;
+ i2c_write(0xBC, 0x11, data_write,1); //LED current - IR
+ data_write[0] = 0x55;
+ i2c_write(0xBC, 0x12, data_write,1); //LED current - Red
+ data_write[0] = 0x10;
+ i2c_write(0xBC, 0x15, data_write,1); //Pilot_PA
+ data_write[0] = 0x04;
+ i2c_write(0xBC, 0x10, data_write,1); //PROX_INT_THRESH
+
+ data_write[0] = 0x03;
+ i2c_write(0xBC, 0x3C, data_write,1); //ECG SAMPLE RATE
+ data_write[0] = 0x0D;
+ i2c_write(0xBC, 0x3E, data_write,1); //PGA_ECG_GAIN, IA_GAIN
+
+ //data_write[0] = 0x40;
+ //i2c_write(0xBC, 0x02, data_write,1); //PPG_RDY_EN
+
+ data_write[0] = 0x10;
+ i2c_write(0xBC, 0x02, data_write,1); //[4] PROX_INT_EN
+ data_write[0] = 0x04;
+ i2c_write(0xBC, 0x03, data_write,1); //ECG_RDY_INT_EN
+ data_write[0] = 0x04;
+ i2c_write(0xBC, 0x0D, data_write,1); //FIFO start
+
+ myPC.printf("\r\nStart reading...");
+ while (j++<15) {
+ myPC.printf("\r\n#%d, ", j);
+
+ i2c_read(0xBC, 0x00, data_read, 2);
+ while(data_read[0]==0x00 & data_read[1]==0x00) {
+ myPC.printf("\r\nReg 0x00 = 0x%x, Reg 0x01 = 0x%x, wait for INT", data_read[0], data_read[1]);
+ i2c_read(0xBC, 0x00, data_read, 2);
+ }
+ if (data_read[0] == 0x80) { // FIFO almost full
+ myPC.printf("\r\nReg 0x00 = 0x%x, read data", data_read[0]);
+ device_data_read();
+ }else if(data_read[1]&0x04 == 0x04) { // Power Ready
+ myPC.printf("\r\nReg 0x00 = 0x%x, read data", data_read[1]);
+ device_data_read();
+ }else if(data_read[0] == 0x10) { // Prox_INT
+ myPC.printf("\r\nReg 0x00 = 0x%x, Proximity Interrupt", data_read[0]);
+ data_write[0] = 0x00;
+ i2c_write(0xBC, 0x0D, data_write,1);
+ data_write[0] = 0x04;
+ i2c_write(0xBC, 0x0D, data_write,1);
+ data_write[0] = 0x80;
+ i2c_write(0xBC, 0x02, data_write,1);
+ }else if(data_read[0] == 0x01) { // Power Ready
+ myPC.printf("\r\nReg 0x00 = 0x%x, Power Ready", data_read[0]);
+ }else
+ myPC.printf("\r\nReg 0x00 = 0x%x, Reg 0x01 = 0x%x, other INT event...", data_read[0], data_read[1]);
+ }
+ }
+}
+
+void device_data_read(void)
+{
+ char wr_ptr;
+ char rd_ptr;
+ char prox_int_threshold;
+ char flag = 0;
+ char dataBuff[32*3*3];
+ int sampleCnt = 0;
+ int red[32], ir[32], ecg[32], threshold_lower;
+ int i;
+
+ i2c_read(0xBC, 0x04, &wr_ptr, 1);
+ i2c_read(0xBC, 0x06, &rd_ptr, 1);
+
+ if(wr_ptr > rd_ptr)
+ sampleCnt = wr_ptr - rd_ptr;
+ else
+ sampleCnt = 32 + wr_ptr - rd_ptr;
+ i2c_read(0xBC, 0x07, dataBuff, sampleCnt*2*3);
+
+ i2c_read(0xBC, 0x10, &prox_int_threshold, 1);
+ threshold_lower = prox_int_threshold*2048*0.8;
+
+ for(i=0;i<sampleCnt;i++){
+ ir[i] = ((dataBuff[i*6+0] << 16) + (dataBuff[i*6+1] << 8) + dataBuff[i*6+2]) & 0x7ffff;
+ red[i] = ((dataBuff[i*6+3] << 16) + (dataBuff[i*6+4] << 8) + dataBuff[i*6+5]) & 0x7ffff;
+ ecg[i] = ((dataBuff[i*6+6] << 16) + (dataBuff[i*6+7] << 8) + dataBuff[i*6+8]) & 0x7ffff;
+ // check sign bit
+ if(ecg[i]>0x1FFFF)
+ ecg[i] = -((~ecg[i] + 1) & 0x1FFFF);
+ else
+ ecg[i] = ecg[i];
+ myPC.printf("\r\nIR = %d, RED = %d, ECG = %d", ir[i], red[i], ecg[i]);
+ if(ir[i]<threshold_lower){
+ flag = 0x10; // PROX_ON
+ myPC.printf("\r\nIR = %d Enter PROX mode", ir[i]);
+ }
+ }
+ if(flag!=0)
+ i2c_write(0xBC, 0x02, &flag,1); // PROX_INT_EN
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/main_backup_reading_OK.txt Fri Apr 12 06:56:27 2019 +0000
@@ -0,0 +1,111 @@
+#include "mbed.h"
+#include "max86150.h"
+#include "i2c_functions.h"
+
+DigitalOut myled(P7_1);
+Serial myPC(USBTX, USBRX); // Initiating Serial Console communication
+
+void device_data_read(void);
+
+
+int main()
+{
+ int i=0, j=0;
+
+ i2c_freq(100000);
+ myPC.baud(57600);
+
+ while (i++<1) {
+ myled = !myled;
+ wait(1);
+
+ char data_read[9];
+ char data_write[2];
+
+ // enable()
+ data_write[0] = 0x01;
+ i2c_write(0xBC, 0x0D, data_write,1); // reset
+ data_write[0] = 0x0C;
+ i2c_write(0xBC, 0x08, data_write,1); // FIFO roll ON
+ data_write[0] = 0x21;
+ i2c_write(0xBC, 0x09, data_write,1); // FDx
+ data_write[0] = 0x00;
+ i2c_write(0xBC, 0x0A, data_write,1); // FDx
+ data_write[0] = 0xDB;
+ i2c_write(0xBC, 0x0E, data_write,1); // PPG_ADC_RANGE PPG_SR:100SpS, PPG_LED_PW:400uS
+ data_write[0] = 0x10;
+ i2c_write(0xBC, 0x11, data_write,1); //LED current - IR
+ data_write[0] = 0x55;
+ i2c_write(0xBC, 0x12, data_write,1); //LED current - Red
+ data_write[0] = 0x10;
+ i2c_write(0xBC, 0x15, data_write,1); //Pilot_PA
+ data_write[0] = 0x04;
+ i2c_write(0xBC, 0x10, data_write,1); //PROX_INT_THRESH
+
+ //data_write[0] = 0x40;
+ //i2c_write(0xBC, 0x02, data_write,1); //PPG_RDY_EN
+
+ data_write[0] = 0x10;
+ i2c_write(0xBC, 0x02, data_write,1); //[4] PROX_INT_EN
+ data_write[0] = 0x04;
+ i2c_write(0xBC, 0x0D, data_write,1); //FIFO start
+
+ myPC.printf("\r\nStart reading...");
+ while (j++<15) {
+ myPC.printf("\r\n#%d, ", j);
+
+ i2c_read(0xBC, 0x00, data_read, 2);
+ while(data_read[0]==0x00) {
+ myPC.printf("\r\nReg 0x00 = 0x%x, wait for INT", data_read[0]);
+ i2c_read(0xBC, 0x00, data_read, 2);
+ }
+ if (data_read[0] == 0x80) { // FIFO almost full
+ myPC.printf("\r\nReg 0x00 = 0x%x, read data", data_read[0]);
+ device_data_read();
+ }else if(data_read[0] == 0x10) { // Prox_INT
+ myPC.printf("\r\nReg 0x00 = 0x%x, Proximity Interrupt", data_read[0]);
+ data_write[0] = 0x00;
+ i2c_write(0xBC, 0x0D, data_write,1);
+ data_write[0] = 0x04;
+ i2c_write(0xBC, 0x0D, data_write,1);
+ data_write[0] = 0x80;
+ i2c_write(0xBC, 0x02, data_write,1);
+ }else if(data_read[0] == 0x01) { // Power Ready
+ myPC.printf("\r\nReg 0x00 = 0x%x, Power Ready", data_read[0]);
+ }else
+ myPC.printf("\r\nReg 0x00 = 0x%x, other INT event...", data_read[0]);
+ }
+ }
+}
+
+void device_data_read(void)
+{
+ char wr_ptr;
+ char rd_ptr;
+ char flag = 0;
+ char dataBuff[32*2*3];
+ int sampleCnt = 0;
+ int red[32], ir[32], ecg[32];
+ int i;
+
+ i2c_read(0xBC, 0x04, &wr_ptr, 1);
+ i2c_read(0xBC, 0x06, &rd_ptr, 1);
+
+ if(wr_ptr > rd_ptr)
+ sampleCnt = wr_ptr - rd_ptr;
+ else
+ sampleCnt = 32 + wr_ptr - rd_ptr;
+ i2c_read(0xBC, 0x07, dataBuff, sampleCnt*2*3);
+
+ for(i=0;i<sampleCnt;i++){
+ ir[i] = ((dataBuff[i*6+0] << 16) + (dataBuff[i*6+1] << 8) + dataBuff[i*6+2]) & 0x7ffff;
+ red[i] = ((dataBuff[i*6+3] << 16) + (dataBuff[i*6+4] << 8) + dataBuff[i*6+5]) & 0x7ffff;
+ myPC.printf("\r\nIR = %d, RED = %d", ir[i], red[i]);
+ if(ir[i]<0x04*2048*0.8){
+ flag = 0x10; // PROX_ON
+ myPC.printf("\r\nIR = %d Enter PROX mode", ir[i]);
+ }
+ }
+ if(flag!=0)
+ i2c_write(0xBC, 0x02, &flag,1); // PROX_INT_EN
+}
\ No newline at end of file
--- a/max30102.cpp Tue Jun 21 09:43:15 2016 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,183 +0,0 @@
-/*
- * 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]);
-}
--- a/max30102.h Tue Jun 21 09:43:15 2016 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,150 +0,0 @@
-/*
- * 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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Fri Apr 12 06:56:27 2019 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/abea610beb85 \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/temp.txt Fri Apr 12 06:56:27 2019 +0000
@@ -0,0 +1,125 @@
+#include "mbed.h"
+#include "max86150.h"
+#include "i2c_functions.h"
+
+DigitalOut myled(P7_1);
+Serial myPC(USBTX, USBRX); // Initiating Serial Console communication
+void device_data_read(void);
+
+
+int main()
+{
+ int i=0, j=0;
+
+ i2c_freq(100000);
+ myPC.baud(57600);
+
+ while (i++<1) {
+ myled = !myled;
+ wait(1);
+
+ char data_read[9];
+ char data_write[2];
+
+ // enable()
+ data_write[0] = 0x01;
+ i2c_write(0xBC, 0x0D, data_write,1); // reset
+ data_write[0] = 0x0C;
+ i2c_write(0xBC, 0x08, data_write,1); // FIFO roll ON
+ data_write[0] = 0x21;
+ i2c_write(0xBC, 0x09, data_write,1); // FDx
+ data_write[0] = 0x09;
+ i2c_write(0xBC, 0x0A, data_write,1); // FD3=ECG
+ data_write[0] = 0xDB;
+ i2c_write(0xBC, 0x0E, data_write,1); // PPG_ADC_RANGE PPG_SR:100SpS, PPG_LED_PW:400uS
+ data_write[0] = 0x10;
+ i2c_write(0xBC, 0x11, data_write,1); //LED current - IR
+ data_write[0] = 0x55;
+ i2c_write(0xBC, 0x12, data_write,1); //LED current - Red
+ data_write[0] = 0x10;
+ i2c_write(0xBC, 0x15, data_write,1); //Pilot_PA
+ data_write[0] = 0x04;
+ i2c_write(0xBC, 0x10, data_write,1); //PROX_INT_THRESH
+
+ data_write[0] = 0x03;
+ i2c_write(0xBC, 0x3C, data_write,1); //ECG SAMPLE RATE
+ data_write[0] = 0x0D;
+ i2c_write(0xBC, 0x3E, data_write,1); //PGA_ECG_GAIN, IA_GAIN
+
+ //data_write[0] = 0x40;
+ //i2c_write(0xBC, 0x02, data_write,1); //PPG_RDY_EN
+
+ data_write[0] = 0x10;
+ i2c_write(0xBC, 0x02, data_write,1); //[4] PROX_INT_EN
+ data_write[0] = 0x04;
+ i2c_write(0xBC, 0x0D, data_write,1); //FIFO start
+
+ myPC.printf("\r\nStart reading...");
+ while (j++<15) {
+ myPC.printf("\r\n#%d, ", j);
+
+ i2c_read(0xBC, 0x00, data_read, 2);
+ while(data_read[0]==0x00) {
+ myPC.printf("\r\nReg 0x00 = 0x%x, wait for INT", data_read[0]);
+ i2c_read(0xBC, 0x00, data_read, 2);
+ }
+ if (data_read[0] == 0x80) { // FIFO almost full
+ myPC.printf("\r\nReg 0x00 = 0x%x, read data", data_read[0]);
+ device_data_read();
+ }else if(data_read[0] == 0x10) { // Prox_INT
+ myPC.printf("\r\nReg 0x00 = 0x%x, Proximity Interrupt", data_read[0]);
+ data_write[0] = 0x00;
+ i2c_write(0xBC, 0x0D, data_write,1);
+ data_write[0] = 0x04;
+ i2c_write(0xBC, 0x0D, data_write,1);
+ data_write[0] = 0x80;
+ i2c_write(0xBC, 0x02, data_write,1);
+ }else if(data_read[0] == 0x01) { // Power Ready
+ myPC.printf("\r\nReg 0x00 = 0x%x, Power Ready", data_read[0]);
+ }else
+ myPC.printf("\r\nReg 0x00 = 0x%x, other INT event...", data_read[0]);
+ }
+ }
+}
+
+void device_data_read(void)
+{
+ char wr_ptr;
+ char rd_ptr;
+ char prox_int_threshold;
+ char flag = 0;
+ char dataBuff[32*3*3];
+ int sampleCnt = 0;
+ int red[32], ir[32], ecg[32], threshold_lower;
+ int i;
+
+ i2c_read(0xBC, 0x04, &wr_ptr, 1);
+ i2c_read(0xBC, 0x06, &rd_ptr, 1);
+
+ if(wr_ptr > rd_ptr)
+ sampleCnt = wr_ptr - rd_ptr;
+ else
+ sampleCnt = 32 + wr_ptr - rd_ptr;
+ i2c_read(0xBC, 0x07, dataBuff, sampleCnt*2*3);
+
+ i2c_read(0xBC, 0x10, &prox_int_threshold, 1);
+ threshold_lower = prox_int_threshold*2048*0.8;
+
+ for(i=0;i<sampleCnt;i++){
+ ir[i] = ((dataBuff[i*6+0] << 16) + (dataBuff[i*6+1] << 8) + dataBuff[i*6+2]) & 0x7ffff;
+ red[i] = ((dataBuff[i*6+3] << 16) + (dataBuff[i*6+4] << 8) + dataBuff[i*6+5]) & 0x7ffff;
+ ecg[i] = ((dataBuff[i*6+6] << 16) + (dataBuff[i*6+7] << 8) + dataBuff[i*6+8]) & 0x7ffff;
+ // check sign bit
+ if(ecg[i]>0x1FFFF)
+ ecg[i] = -((~ecg[i] + 1) & 0x1FFFF);
+ else
+ ecg[i] = ecg[i];
+ myPC.printf("\r\nIR = %d, RED = %d, ECG = %d", ir[i], red[i], ecg[i]);
+ if(ir[i]<threshold_lower){
+ flag = 0x10; // PROX_ON
+ myPC.printf("\r\nIR = %d Enter PROX mode", ir[i]);
+ }
+ }
+ if(flag!=0)
+ i2c_write(0xBC, 0x02, &flag,1); // PROX_INT_EN
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/temp_data.txt Fri Apr 12 06:56:27 2019 +0000 @@ -0,0 +1,31 @@ +LED +0x11 = 0x55; +0x12 = 0x55; +43, 51534, 52190 +44, 51886, 52523 +45, 52191, 52810 +46, 52419, 53020 +47, 52603, 53167 + +0x11 = 0x10; +0x12 = 0x10; +72, 14154, 14188 +73, 14153, 14188 +74, 14151, 14186 +75, 14150, 14184 +76, 14138, 14183 +77, 14135, 14181 + + +0x11 = 0x10; +0x12 = 0x55; +finger_ON +77, 15436, 84795 +78, 15436, 84789 +79, 15437, 84792 +80, 15438, 84796 +81, 15433, 84789 +finger_OFF +87, 105, 592 +88, 111, 590 +=> 15433 > 2048 x 7 threshold = 0x07; \ No newline at end of file