Qiao li
/
MAX86150_evkit_board_OK
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