Library for MAX30101, read/write functions for registers implemented.

Dependents:   test_MAX30101 testSensor

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers MAX30101.cpp Source File

MAX30101.cpp

00001 /**
00002  * MAX30101
00003  * High-Sensitivity Pulse Oximeter and
00004  * Heart-Rate Sensor for Wearable Health
00005  */
00006 #include "mbed.h"
00007 #include "MAX30101.h"
00008 
00009 /* Status */
00010 #define REG_INT_MSB        0x00 /* Interrupt Status 1 */
00011 #define REG_INT_LSB        0x01 /* Interrupt Status 2 */
00012 #define REG_INT_ENB_MSB    0x02 /* Interrupt Enable 1 */
00013 #define REG_INT_ENB_LSB    0x03 /* Interrupt Enable 2 */
00014 /* FIFO */
00015 #define REG_FIFO_WR_PTR    0x04 /* FIFO Write Pointer */
00016 #define REG_OVF_COUNTER    0x05 /* Overflow Counter */
00017 #define REG_FIFO_RD_PTR    0x06 /* FIFO Read Pointer */
00018 #define REG_FIFO_DATA      0x07 /* FIFO Data Register */
00019 /* Configuration */
00020 #define REG_FIFO_CONFIG    0x08 /* FIFO Configuration */
00021 #define REG_MODE_CONFIG    0x09 /* Mode Configuration */
00022 #define REG_SPO2_CONFIG    0x0A /* SpO2 Configuration */
00023 /* reserved                0x0B */
00024 #define REG_LED1_PA        0x0C /* LED Pulse Amplitude 1 */
00025 #define REG_LED2_PA        0x0D /* LED Pulse Amplitude 2 */
00026 #define REG_LED3_PA        0x0E /* LED Pulse Amplitude 3 */
00027 /* reserved                0x0F */
00028 #define REG_PILOT_PA       0x10 /* Proximity LED Pulse Amplitude */
00029 #define REG_SLOT_MSB       0x11 /* Multi-LED Mode Control Registers 2, 1 */
00030 #define REG_SLOT_LSB       0x12 /* Multi-LED Mode Control Registers 4, 3 */
00031 /* DIE Temperature */
00032 #define REG_TEMP_INT       0x1F /* Die Temperature Integer */
00033 #define REG_TEMP_FRAC      0x20 /* Die Temperature Fraction */
00034 #define REG_TEMP_EN        0x21 /* Die Temperature Config */
00035 /* Proximity Function */
00036 #define REG_PROX_INT_THR   0x30 /* Proximity Interrupt Threshold */
00037 /* Part ID */
00038 #define REG_REV_ID         0xFE /* Revision ID */
00039 #define REG_PART_ID        0xFF /* Part ID: 0x15 */
00040 /* Depth of FIFO */
00041 #define FIFO_DEPTH         32
00042 
00043 MAX30101::MAX30101(PinName sda, PinName scl, int addr) : m_i2c(sda, scl), m_addr(addr<<1) {
00044     // activate the peripheral
00045 }
00046 
00047 MAX30101::~MAX30101() { }
00048 
00049 void MAX30101::readRegs(int addr, uint8_t * data, int len) {
00050     char t[1] = {addr} ;
00051     m_i2c.write(m_addr, t, 1, true) ;
00052     m_i2c.read(m_addr, (char*)data, len) ;
00053 }
00054 
00055 void MAX30101::writeRegs(uint8_t * data, int len) {
00056    m_i2c.write(m_addr, (char *)data, len) ;
00057 }
00058 
00059 uint8_t MAX30101::getID(void)
00060 {
00061     uint8_t id ;
00062     readRegs(REG_PART_ID, &id, 1) ;
00063     return( id ) ;
00064 }
00065 
00066 uint8_t MAX30101::getRev(void)
00067 {
00068     uint8_t rev ;
00069     readRegs(REG_REV_ID, &rev, 1) ;
00070     return( rev ) ;
00071 }
00072 
00073 uint16_t MAX30101::getIntStatus(void) 
00074 {
00075     uint8_t res[2] ;
00076     uint16_t value ;
00077     readRegs(REG_INT_MSB, res, 2) ;
00078     value = (res[0] << 8) | res[1] ;
00079     return( value ) ;
00080 }
00081 
00082 uint16_t MAX30101::getIntEnable(void) 
00083 {
00084     uint8_t res[2] ;
00085     uint16_t value ;
00086     readRegs(REG_INT_ENB_MSB, res, 2) ;
00087     value = (res[0] << 8) | res[1] ;
00088     return( value ) ;
00089 }
00090 
00091 void MAX30101::setIntEnable(uint16_t mask) 
00092 {
00093     uint8_t res[3] ;
00094     res[0] = REG_INT_ENB_MSB ;
00095     res[1] = (mask >> 8) & 0xFF ;
00096     res[2] = (mask & 0xFF) ;
00097     writeRegs(res, 3) ;
00098 }
00099 
00100 uint8_t MAX30101::getFIFO_WR_PTR(void) 
00101 {
00102     uint8_t data ;
00103     readRegs(REG_FIFO_WR_PTR, &data, 1) ;
00104     return( data ) ;
00105 }
00106 
00107 void    MAX30101::setFIFO_WR_PTR(uint8_t data) 
00108 {
00109     uint8_t res[2] ;
00110     res[0] = REG_FIFO_WR_PTR ;
00111     res[1] = data ;
00112     writeRegs(res, 2) ;
00113 }
00114 
00115 uint8_t MAX30101::getOVF_COUNTER(void) 
00116 {
00117     uint8_t data ;
00118     readRegs(REG_OVF_COUNTER, &data, 1) ;
00119     return( data ) ;
00120 }
00121 
00122 void    MAX30101::setOVF_COUNTER(uint8_t data) 
00123 {
00124     uint8_t res[2] ;
00125     res[0] = REG_OVF_COUNTER ;
00126     res[1] = data ;
00127     writeRegs(res, 2) ;
00128 }
00129 
00130 uint8_t MAX30101::getFIFO_RD_PTR(void)
00131 {
00132     uint8_t data ;
00133     readRegs(REG_FIFO_RD_PTR, &data, 1) ;
00134     return( data ) ;
00135 }
00136 
00137 void    MAX30101::setFIFO_RD_PTR(uint8_t data) 
00138 {
00139     uint8_t res[2] ;
00140     res[0] = REG_FIFO_RD_PTR ;
00141     res[1] = data ;
00142     writeRegs(res, 2) ;
00143 }
00144 
00145 uint8_t MAX30101::getFIFO_DATA(void) 
00146 {
00147     uint8_t data ;
00148     readRegs(REG_FIFO_DATA, &data, 1) ;
00149     return( data ) ;
00150 }
00151 
00152 void    MAX30101::setFIFO_DATA(uint8_t data) 
00153 {
00154     uint8_t res[2] ;
00155     res[0] = REG_FIFO_DATA ;
00156     res[1] = data ;
00157     writeRegs(res, 2) ;
00158 }
00159 
00160 uint8_t MAX30101::getFIFO_CONFIG(void) 
00161 {
00162     uint8_t data ;
00163     readRegs(REG_FIFO_CONFIG, &data, 1) ;
00164     return( data ) ;
00165 }
00166 
00167 void    MAX30101::setFIFO_CONFIG(uint8_t data) 
00168 {
00169     uint8_t res[2] ;
00170     res[0] = REG_FIFO_CONFIG ;
00171     res[1] = data ;
00172     writeRegs(res, 2) ;
00173 }
00174 
00175 uint8_t MAX30101::getMODE_CONFIG(void)
00176 {
00177     uint8_t data ;
00178     readRegs(REG_MODE_CONFIG, &data, 1) ;
00179     return( data ) ;
00180 }
00181 
00182 void    MAX30101::setMODE_CONFIG(uint8_t data) 
00183 {
00184     uint8_t res[2] ;
00185     res[0] = REG_MODE_CONFIG ;
00186     res[1] = data ;
00187     writeRegs(res, 2) ;
00188 }
00189 
00190 uint8_t MAX30101::getSPO2_CONFIG(void)
00191 {
00192     uint8_t data ;
00193     readRegs(REG_SPO2_CONFIG, &data, 1) ;
00194     return( data ) ;
00195 }
00196 
00197 void    MAX30101::setSPO2_CONFIG(uint8_t data)
00198 {
00199     uint8_t res[2] ;
00200     res[0] = REG_SPO2_CONFIG ;
00201     res[1] = data ;
00202     writeRegs(res, 2) ;
00203 }
00204 
00205 uint8_t MAX30101::getLED1_PA(void)
00206 {
00207     uint8_t data ;
00208     readRegs(REG_LED1_PA, &data, 1) ;
00209     return( data ) ;
00210 }
00211 
00212 void    MAX30101::setLED1_PA(uint8_t data)
00213 {
00214     uint8_t res[2] ;
00215     res[0] = REG_LED1_PA ;
00216     res[1] = data ;
00217     writeRegs(res, 2) ;
00218 }
00219 
00220 uint8_t MAX30101::getLED2_PA(void)
00221 {
00222     uint8_t data ;
00223     readRegs(REG_LED2_PA, &data, 1) ;
00224     return( data ) ;
00225 }
00226 
00227 void    MAX30101::setLED2_PA(uint8_t data)
00228 {
00229     uint8_t res[2] ;
00230     res[0] = REG_LED2_PA ;
00231     res[1] = data ;
00232     writeRegs(res, 2) ;
00233 }
00234 
00235 uint8_t MAX30101::getLED3_PA(void)
00236 {
00237     uint8_t data ;
00238     readRegs(REG_LED3_PA, &data, 1) ;
00239     return( data ) ;
00240 }
00241 
00242 void    MAX30101::setLED3_PA(uint8_t data)
00243 {
00244     uint8_t res[2] ;
00245     res[0] = REG_LED3_PA ;
00246     res[1] = data ;
00247     writeRegs(res, 2) ;
00248 }
00249 
00250 uint8_t MAX30101::getPILOT_PA(void) 
00251 {
00252     uint8_t data ;
00253     readRegs(REG_PILOT_PA, &data, 1) ;
00254     return( data ) ;
00255 }
00256 
00257 void    MAX30101::setPILOT_PA(uint8_t data)
00258 {
00259     uint8_t res[2] ;
00260     res[0] = REG_PILOT_PA ;
00261     res[1] = data ;
00262     writeRegs(res, 2) ;
00263 }
00264 
00265 uint16_t MAX30101::getSLOT(void) 
00266 {
00267     uint8_t res[2] ;
00268     uint16_t data ;
00269     readRegs(REG_SLOT_MSB, res, 2) ;
00270     data = (res[0] << 8) | res[1] ;
00271     return( data ) ;
00272 }
00273 
00274 void     MAX30101::setSLOT(uint16_t data) 
00275 {
00276     uint8_t res[3] ;
00277     res[0] = REG_SLOT_MSB ;
00278     res[1] = (data >> 8) & 0xFF ;
00279     res[2] = data & 0xFF ;
00280     writeRegs(res, 3) ;
00281 }
00282 
00283 uint8_t  MAX30101::getTEMP_INT(void)  
00284 {
00285     uint8_t data ;
00286     readRegs(REG_TEMP_INT, &data, 1) ;
00287     return( data ) ;
00288 }
00289 
00290 uint8_t  MAX30101::getTEMP_FRAC(void) 
00291 {
00292     uint8_t data ;
00293     readRegs(REG_TEMP_FRAC, &data, 1) ;
00294     return( data ) ;
00295 }
00296 
00297 uint8_t  MAX30101::getTEMP_EN(void) 
00298 {
00299     uint8_t data ;
00300     readRegs(REG_TEMP_EN, &data, 1) ;
00301     return( data ) ;
00302 }
00303 
00304 void  MAX30101::setTEMP_EN(void) 
00305 {
00306     uint8_t res[2] ;
00307     res[0] = REG_TEMP_EN ;
00308     res[1] = 1 ;
00309     writeRegs(res, 2) ;
00310 }
00311 
00312 float MAX30101::getTEMP(void)
00313 {
00314     float temp ;
00315     int temp_int, temp_frac ;
00316     while(getTEMP_EN() == 0x01) { } 
00317     temp_int = getTEMP_INT() ;
00318     temp_frac = getTEMP_FRAC() ;
00319     temp = ((float)temp_int)+(((float)temp_frac)/16.0) ;
00320     return( temp ) ;
00321 }
00322 
00323 uint8_t  MAX30101::getPROX_INT_THR(void)  
00324 {
00325     uint8_t data ;
00326     readRegs(REG_PROX_INT_THR, &data, 1) ;
00327     return( data ) ;
00328 }
00329 
00330 void     MAX30101::setPROX_INT_THR(uint8_t data)  
00331 {
00332     uint8_t res[2] ;
00333     res[0] = REG_PROX_INT_THR ;
00334     res[1] = data ;
00335     writeRegs(res, 2) ;
00336 }
00337 
00338 void MAX30101::clearFIFO(void)
00339 {
00340     uint8_t res[5] ;
00341     res[0] = REG_FIFO_WR_PTR ;
00342     res[1] = 0x00 ; /* FIFO_WR_PTR */
00343     res[2] = 0x00 ; /* OVF_COUNTER */
00344     res[3] = 0x00 ; /* FIFO_RD_PTR */
00345     res[4] = 0x00 ; /* FIFO_DATA (do we need to clear this?) */
00346     writeRegs(res, 5) ;
00347 }
00348 
00349 /*
00350  * readFIFO(void)
00351  * FIFO data is always a 3-bytes data
00352  * byte1[1:0] : FIFO_DATA[17]-FIFO_DATA[16]
00353  * byte2[7:0] : FIFO_DATA[15]-FIFO_DATA[8]
00354  * byte3[7:0] : FIFO_DATA[7]-FIFO_DATA[0]
00355  * The data is left aligned, so FIFO_DATA[17]
00356  * is always MSB, although the data length 
00357  * can be 18-bit ~ 15-bit
00358  */
00359 uint32_t MAX30101::readFIFO(void)
00360 {
00361     uint32_t data = 0 ;
00362     uint8_t res[3] ;
00363     readRegs(REG_FIFO_DATA, res, 3) ;
00364     data = 
00365         ((res[0] & 0x03)<<16)
00366         | (res[1] << 8) 
00367         | res[2] ;
00368     return( data ) ;
00369 }
00370 
00371 void MAX30101::reset(void)
00372 {
00373     uint8_t res[2] ;
00374     res[0] = REG_MODE_CONFIG ;
00375     res[1] = 0x40 ; /* reset */
00376     writeRegs(res, 2) ;
00377 }