OB1203 basic mbed driver

Dependents:   OB1203_IDT

Revision:
0:2da1f69b38fd
Child:
1:99ca9c464503
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/OB1203.cpp	Wed Apr 25 05:26:34 2018 +0000
@@ -0,0 +1,366 @@
+#include "OB1203.h"
+#include "mbed.h"
+
+extern Serial pc;
+
+OB1203::OB1203(I2C *i2c_obj)
+{
+    i2c = i2c_obj;
+}
+
+
+void OB1203::reset()
+{
+    /*POR reset*/
+    writeRegister(OB1203_ADDR,REG_MAIN_CTRL_0,SW_RESET);
+    wait_ms(POR_TIME_MS);
+}
+
+
+void OB1203::writeRegister(int addr, char reg, char val) {
+ /*writes 1 byte to a single register*/
+    char writeData[2];
+    writeData[0] = reg;
+    writeData[1] = val;
+    i2c->write(addr,writeData, 2);
+}
+
+
+void OB1203::writeBlock(int addr, char startReg, char *data, char numBytes) {
+/*writes data from an array beginning at the startReg*/
+    pc.printf("entering writeBlock with data %02x %02x\r\n",data[0],data[1]);
+    char writeData[numBytes+1];
+    writeData[0]=startReg;
+    for(int n=1;n<numBytes+1;n++) {
+        writeData[n]=data[n-1];
+    }
+    i2c->write(addr,writeData,numBytes+1);
+}
+
+
+void OB1203::readBlock(int addr, char startReg, char *data, int numBytes) 
+{
+    char writeData[1];
+    writeData[0] = startReg;
+    i2c->write(addr,writeData,1,true);
+    i2c->read(addr,data,numBytes);
+}
+
+
+int OB1203::get_status()
+{
+    char writeData[1]; //declare array of size 1
+    writeData[0] = REG_STATUS_0; 
+    char data[1]; //declare array of size 1
+    i2c->write(OB1203_ADDR,writeData,1,true);
+    i2c->read(OB1203_ADDR,data,2);
+    return (data[0]<<8 | data[1]);
+}
+
+
+void OB1203::setMainConfig()
+{
+    char writeData[2];
+    writeData[0] = ls_sai | ls_mode | ls_en; //MAIN_CTRL_0
+    writeData[1] = ps_sai_en | ppg_ps_mode | ppg_ps_en; //MAIN_CTRL_1
+    writeBlock(OB1203_ADDR,REG_MAIN_CTRL_0,writeData,2); 
+}
+
+
+void OB1203::setIntConfig()
+{
+    char writeData[3];
+    writeData[0] =  ls_int_sel | ls_var_mode | ls_int_en;
+    writeData[1] = afull_int_en | ppg_int_en | ps_logic_mode | ps_int_en;
+    writeData[2] = ls_persist | ps_persist;
+    writeBlock(OB1203_ADDR,REG_INT_CFG_0,writeData,3); //default  
+}
+
+
+void OB1203::setLSthresh()
+{
+    char writeData[6];
+    writeData[0] = (char) (ls_thres_hi & 0x000000FF);
+    writeData[1] = (char) ((ls_thres_hi & 0x0000FF00)>>8);
+    writeData[2] = (char) (ls_thres_hi & 0x00FF0000)>>16;
+    writeData[3] = (char) (ls_thres_lo & 0x000000FF);
+    writeData[4] = (char) ((ls_thres_lo & 0x0000FF00)>>8);
+    writeData[5] = (char) (ls_thres_lo & 0x00FF0000)>>16;
+    writeBlock(OB1203_ADDR,REG_LS_THRES_HI,writeData,6); //default  
+}
+
+
+void OB1203::setPSthresh()
+{
+    char writeData[4];
+    writeData[0] = (char) (ps_thres_hi & 0x000FF);
+    writeData[1] = (char) ((ps_thres_hi & 0xFF00)>>8);
+        writeData[0] = (char) (ps_thres_lo & 0x000FF);
+    writeData[1] = (char) ((ps_thres_lo & 0xFF00)>>8);
+    writeBlock(OB1203_ADDR,REG_PS_THRES_HI,writeData,4); //default  
+}
+
+
+void OB1203::setPScurrent()
+{
+    char writeData[2];
+    writeData[0] = (char) (ps_current & 0x00FF);
+    writeData[1] = (char) ((ps_current & 0xFF00)>>8);
+    writeBlock(OB1203_ADDR,REG_PS_LED_CURR,writeData,2);
+}
+
+
+void OB1203::setPPGcurrent()
+{
+    char writeData[4];
+    writeData[0] = (char) (ir_current & 0x00FF);
+    writeData[1] = (char) ((ir_current & 0xFF00)>>8);
+    writeData[2] = (char) (r_current & 0x00FF);
+    writeData[3] = (char) ((r_current & 0xFF00)>>8);
+    writeBlock(OB1203_ADDR,REG_PPG_IRLED_CURR,writeData,4);
+}
+
+
+void OB1203::setPPG_PSgain_cfg()
+{
+    char writeData[2];
+    writeData[0] = ppg_ps_gain;
+    writeData[1] = ppg_pow_save | led_flip;
+    writeBlock(OB1203_ADDR,REG_PPG_PS_GAIN,writeData,2);
+}
+
+void OB1203::setPPGana_can()
+{
+    char writeData[1];
+    writeData[0] = ch1_can_ana | ch2_can_ana;
+    writeBlock(OB1203_ADDR,REG_PPG_CAN_ANA,writeData,1);
+}
+
+void OB1203::setPPGavg_and_rate()
+{
+    char writeData[2];
+    writeData[0] = ppg_avg;
+    writeData[1] = ppg_pwidth | ppg_freq | ppg_rate;
+    writeBlock(OB1203_ADDR,REG_PPG_AVG,writeData,2);
+}
+
+
+void OB1203::setDigitalCan()
+{
+    char writeData[2];
+    writeData[0] = (char)(ps_digital_can & 0x00FF);
+    writeData[1] = (char)((ps_digital_can & 0xFF00)>>8);
+    writeBlock(OB1203_ADDR,REG_PS_CAN_DIG,writeData,2);
+}
+
+
+void OB1203::setFifoConfig()
+{
+    char writeData[1];
+    writeData[0] = fifo_rollover_en | fifo_afull_samples_left;
+    writeBlock(OB1203_ADDR,REG_FIFO_CFG,writeData,1);    
+}
+
+
+void OB1203::init_rgb()
+{
+    /*Configures ALS/RGB mode. PS and BIO off.
+    Use: set class variables using header declarations. Then call this function.*/
+    char writeData[2];
+    writeBlock(OB1203_ADDR,REG_LS_RES_RATE,writeData,2);
+    writeData[0] = ls_res | ls_rate; //LS_RES_RATE
+    writeData[1] = ls_gain; //LS_GAIN
+    writeBlock(OB1203_ADDR,REG_LS_RES_RATE,writeData,2);  
+    setLSthresh(); 
+    setIntConfig();
+    ppg_ps_en = PPG_PS_OFF;
+    ls_en = LS_ON;
+    setMainConfig();
+}
+
+
+void OB1203::init_ps()
+{
+    /*Configures PS mode but not thresholds or interrupts. RGB/ALS and BIO off.
+    Use: set class variables using header declarations. Then call this function.*/
+    char writeData[2];  
+    //PS settings
+    setPScurrent();
+    writeData[0] = ps_can_ana | ps_pulses; //PS_CAN_PULSES
+    writeData[1] = ps_pwidth | ps_rate; //PS_PWIDTH_RATE
+    writeBlock(OB1203_ADDR,REG_PS_CAN_PULSES,writeData,2);
+    //Digital crosstalk cancellation
+    setDigitalCan(); //PS_CAN_DIG
+    //set PS moving average and hysteresis
+    writeData[0] = ps_avg_en | ps_hys_level; //PS_MOV_AVG_HYS
+    writeBlock(OB1203_ADDR,REG_PS_MOV_AVG_HYS,writeData,1);
+    //set PS interrupt thresholds
+    setPSthresh();
+    //interrupt configuration
+    ls_int_en = LS_INT_OFF;
+    setIntConfig();
+    setPPG_PSgain_cfg();
+    setPScurrent(); 
+    //config PS
+    ls_en = LS_OFF;
+    ppg_ps_en = 1;
+    ppg_ps_mode = PS_MODE;
+    setMainConfig();
+}
+
+
+void OB1203::init_ps_rgb()
+{
+    char writeData[2];
+    writeBlock(OB1203_ADDR,REG_LS_RES_RATE,writeData,2);
+    writeData[0] = ls_res | ls_rate; //LS_RES_RATE
+    writeData[1] = ls_gain; //LS_GAIN
+    writeBlock(OB1203_ADDR,REG_LS_RES_RATE,writeData,2);
+    writeData[0] = ps_can_ana | ps_pulses; //PS_CAN_PULSES
+    writeData[1] = ps_pwidth | ps_rate; //PS_PWIDTH_RATE
+    writeBlock(OB1203_ADDR,REG_PS_CAN_PULSES,writeData,2);
+    setDigitalCan(); //PS_CAN_DIG
+    //set PS moving average and hysteresis
+    writeData[0] = ps_avg_en | ps_hys_level; //PS_MOV_AVG_HYS
+    writeBlock(OB1203_ADDR,REG_PS_MOV_AVG_HYS,writeData,1);
+    setIntConfig();
+    setPSthresh();
+    setPScurrent();
+    setLSthresh();
+    ls_en = LS_ON;
+    ppg_ps_en = PPG_PS_ON;
+    ppg_ps_mode = PS_MODE;
+    setMainConfig();    
+}
+
+
+void OB1203::init_hr()
+{
+    setIntConfig(); 
+    setPPG_PSgain_cfg();
+    setPPGcurrent();
+    setPPGana_can();
+    setPPGavg_and_rate();
+    setFifoConfig(); 
+    ppg_ps_mode = HR_MODE; 
+    setMainConfig(); 
+}
+
+void OB1203::init_spo2()
+{
+    setIntConfig(); 
+    setPPG_PSgain_cfg();
+    setPPGcurrent();
+    setPPGana_can();
+    setPPGavg_and_rate();
+    setFifoConfig(); 
+    ppg_ps_mode = SPO2_MODE;
+    setMainConfig();    
+}
+
+uint32_t OB1203::bytes2uint32(char *data, int start_byte) 
+{
+    //coverts a string of 3 bytes with LSB first into unsigned long
+    return uint32_t(data[start_byte+2])<<16 | int32_t(data[start_byte+1])<<8 | int32_t(data[start_byte]) ;
+}
+
+
+char OB1203::get_ls_data(uint32_t *data)
+{  
+    char byte_data[19];
+    readBlock(OB1203_ADDR,REG_STATUS_0,byte_data,19);  
+    #ifdef DEBUG
+        pc.printf("%02x %02x  %02x %02x  %02x %02x %02x  %02x %02x %02x  %02x %02x %02x  %02x %02x  %02x %02x %02x %02x\r\n",
+        byte_data[0],byte_data[1],byte_data[2],byte_data[3],
+        byte_data[4],byte_data[5],byte_data[6],byte_data[7],
+        byte_data[8],byte_data[9],byte_data[10],byte_data[11],
+        byte_data[12],byte_data[13],byte_data[14],byte_data[15],
+        byte_data[16],byte_data[17],byte_data[18]);
+    #endif
+     
+    //byte_data[0] is status
+    data[1] = bytes2uint32(byte_data,4); //w
+    data[2] = bytes2uint32(byte_data,7); //g
+    data[3] = bytes2uint32(byte_data,10); //b
+    data[4] = bytes2uint32(byte_data,13); //r
+    data[5] = bytes2uint32(byte_data,16); //c
+
+    return ( (byte_data[0] & LS_NEW_DATA) == 0x01 ? 1 : 0); //return 1 if new data or 0 if old data
+}
+
+char OB1203::get_ps_data(uint32_t *data)
+{  
+    char byte_data[4];
+    readBlock(OB1203_ADDR,REG_STATUS_0,byte_data,19);  
+    #ifdef DEBUG
+        pc.printf( "%02x %02x %02x %02x\r\n", byte_data[0], byte_data[1], byte_data[2], byte_data[3] );
+    #endif
+     
+    //byte_data[0] is status
+    data[0] = ((uint32_t)byte_data[3])<<8 | ((uint32_t)byte_data[2]);
+    return ( (byte_data[1] & PS_NEW_DATA) == 0x01 ? 1 : 0); //return 1 if new data or 0 if old data
+}
+
+char OB1203::get_ps_ls_data(uint32_t *data)
+{  
+    char byte_data[19];
+    readBlock(OB1203_ADDR,REG_STATUS_0,byte_data,19);  
+    #ifdef DEBUG
+        pc.printf("%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\r\n",
+        byte_data[0],byte_data[1],byte_data[2],byte_data[3],byte_data[4],
+        byte_data[5],byte_data[6],byte_data[7],byte_data[8],byte_data[9],
+        byte_data[10],byte_data[11],byte_data[12],byte_data[13],byte_data[14],
+        byte_data[15],byte_data[16],byte_data[17],byte_data[18] );
+    #endif
+     
+    //byte_data[0] is status
+    data[0] = ((uint32_t)byte_data[3])<<8 | ((uint32_t)byte_data[2]);
+    data[1] = bytes2uint32(byte_data,4); //w
+    data[2] = bytes2uint32(byte_data,7); //g
+    data[3] = bytes2uint32(byte_data,10); //b
+    data[4] = bytes2uint32(byte_data,13); //r
+    data[5] = bytes2uint32(byte_data,16); //c
+    return ( (byte_data[0] & LS_NEW_DATA) == 0x01 ? 1 : 0); //return 1 if new data or 0 if old data
+}
+
+
+void OB1203::getFifoInfo(char *fifo_info)
+{
+    readBlock(OB1203_ADDR,REG_FIFO_WR_PTR,fifo_info,3);
+    writePointer = fifo_info[0];
+    readPointer = fifo_info[1];
+    fifoOverflow = fifo_info[2];
+}
+
+
+uint8_t OB1203::getNumFifoSamplesAvailable()
+{
+    uint8_t numSamples = writePointer;
+    if (writePointer<readPointer)
+    {
+        numSamples += 31-readPointer;
+    }
+    return numSamples;
+}
+
+
+void OB1203::getFifoSamples(uint8_t numSamples, char *fifoData)
+{
+    readBlock(OB1203_ADDR,REG_FIFO_DATA,fifoData,numSamples);
+}
+
+
+void OB1203::parseFifoSamples(char numSamples, char *fifoData, uint32_t *assembledData)
+{
+    for (int n=0; n<numSamples; n++)
+    {
+        assembledData[n] = bytes2uint32(fifoData,3*n);
+    }
+}
+
+
+char OB1203::get_part_ID(char *data)
+{
+    readBlock(OB1203_ADDR,REG_PART_ID,data,1);
+    return data[0];
+}
\ No newline at end of file