Hexiwear Heart rate sensor driver
Dependents: Hexi_MAX30101 Hexiwear HexiwearFinal HexiwearFinal1
Fork of FXOS8700 by
MAX30101.cpp@4:3be008e67345, 2016-09-04 (annotated)
- Committer:
- DimiterK
- Date:
- Sun Sep 04 22:37:38 2016 +0000
- Revision:
- 4:3be008e67345
- Parent:
- 3:4bfb42d6c70c
First revision , not yet operational
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
DimiterK | 3:4bfb42d6c70c | 1 | #include "MAX30101.h" |
AswinSivakumar | 0:a4ffc3c3e770 | 2 | #include "mbed.h" |
AswinSivakumar | 0:a4ffc3c3e770 | 3 | |
DimiterK | 3:4bfb42d6c70c | 4 | |
DimiterK | 4:3be008e67345 | 5 | MAX30101::MAX30101(PinName sda, PinName scl) : m_i2c(sda, scl){ |
DimiterK | 3:4bfb42d6c70c | 6 | // mode (HR, SpO2, or multi-led) |
DimiterK | 3:4bfb42d6c70c | 7 | mode = modeMultiLED; |
DimiterK | 3:4bfb42d6c70c | 8 | |
DimiterK | 4:3be008e67345 | 9 | m_addr = MAX30101_I2C_ADDRESS; |
DimiterK | 3:4bfb42d6c70c | 10 | // LED currents |
DimiterK | 3:4bfb42d6c70c | 11 | LEDCurrentRed = 0; |
DimiterK | 3:4bfb42d6c70c | 12 | LEDCurrentIR = 0; |
DimiterK | 3:4bfb42d6c70c | 13 | LEDCurrentGreen = 0; |
DimiterK | 3:4bfb42d6c70c | 14 | |
DimiterK | 3:4bfb42d6c70c | 15 | // timings |
DimiterK | 3:4bfb42d6c70c | 16 | sampleRate = sampleRate_50; |
DimiterK | 3:4bfb42d6c70c | 17 | pulseWidth = ledPower_411; |
DimiterK | 3:4bfb42d6c70c | 18 | // ADC range |
DimiterK | 3:4bfb42d6c70c | 19 | range = adcRange8192; |
DimiterK | 3:4bfb42d6c70c | 20 | // averaging |
DimiterK | 3:4bfb42d6c70c | 21 | oversample = ovsNone; |
DimiterK | 3:4bfb42d6c70c | 22 | |
DimiterK | 3:4bfb42d6c70c | 23 | // writeRegister(MAX30101_LED1RedPulseAmplitude, 0xFF ); |
DimiterK | 3:4bfb42d6c70c | 24 | // writeRegister(MAX30101_LED2IrPulseAmplitude, 0x33 ); |
DimiterK | 3:4bfb42d6c70c | 25 | // writeRegister(MAX30101_LED3GreenPulseAmplitude, 0xFF ); |
DimiterK | 3:4bfb42d6c70c | 26 | // writeRegister(MAX30101_ProximityModePulseAmplitude, 0x19 ); |
DimiterK | 3:4bfb42d6c70c | 27 | // |
DimiterK | 3:4bfb42d6c70c | 28 | // writeRegister( MAX30101_MultiLEDModeControlTime2Time1, 0x03 ); |
DimiterK | 3:4bfb42d6c70c | 29 | // writeRegister( MAX30101_MultiLEDModeControlTime4Time3, 0x00 ); |
DimiterK | 3:4bfb42d6c70c | 30 | // |
DimiterK | 3:4bfb42d6c70c | 31 | // writeRegister( MAX30101_FIFOConfiguration , 0x06 ); |
DimiterK | 3:4bfb42d6c70c | 32 | // writeRegister( MAX30101_SPO2Configuration , 0x43 ); |
DimiterK | 4:3be008e67345 | 33 | |
DimiterK | 4:3be008e67345 | 34 | writeRegister(MAX30101_ProximityInterruptThreshold , 0x14 ); |
DimiterK | 4:3be008e67345 | 35 | |
DimiterK | 4:3be008e67345 | 36 | /** clear FIFO pointers */ |
DimiterK | 4:3be008e67345 | 37 | writeRegister(MAX30101_FIFO_WR_PTR , 0 ); |
DimiterK | 4:3be008e67345 | 38 | writeRegister(MAX30101_FIFO_RD_PTR , 0 ); |
DimiterK | 4:3be008e67345 | 39 | writeRegister(MAX30101_FIFO_OV_PTR , 0 ); |
DimiterK | 3:4bfb42d6c70c | 40 | |
DimiterK | 3:4bfb42d6c70c | 41 | } |
DimiterK | 3:4bfb42d6c70c | 42 | |
DimiterK | 3:4bfb42d6c70c | 43 | MAX30101::~MAX30101() { } |
DimiterK | 3:4bfb42d6c70c | 44 | |
DimiterK | 3:4bfb42d6c70c | 45 | |
DimiterK | 3:4bfb42d6c70c | 46 | void MAX30101::enable(void) |
AswinSivakumar | 0:a4ffc3c3e770 | 47 | { |
DimiterK | 3:4bfb42d6c70c | 48 | |
DimiterK | 3:4bfb42d6c70c | 49 | writeRegister( MAX30101_InterruptEnable1 , 0x10 ); |
DimiterK | 3:4bfb42d6c70c | 50 | writeRegister( MAX30101_ModeConfiguration , 0x07 ); |
DimiterK | 3:4bfb42d6c70c | 51 | |
AswinSivakumar | 0:a4ffc3c3e770 | 52 | } |
AswinSivakumar | 0:a4ffc3c3e770 | 53 | |
DimiterK | 3:4bfb42d6c70c | 54 | void MAX30101::shutdown(void) |
AswinSivakumar | 0:a4ffc3c3e770 | 55 | { |
DimiterK | 3:4bfb42d6c70c | 56 | writeRegister(MAX30101_ModeConfiguration,SHDN); |
AswinSivakumar | 0:a4ffc3c3e770 | 57 | |
AswinSivakumar | 0:a4ffc3c3e770 | 58 | } |
AswinSivakumar | 0:a4ffc3c3e770 | 59 | |
DimiterK | 3:4bfb42d6c70c | 60 | max30101_status_t MAX30101::reset(void) |
AswinSivakumar | 0:a4ffc3c3e770 | 61 | { |
DimiterK | 3:4bfb42d6c70c | 62 | writeRegister(MAX30101_ModeConfiguration,RESET); |
DimiterK | 3:4bfb42d6c70c | 63 | |
DimiterK | 3:4bfb42d6c70c | 64 | while (1) |
DimiterK | 3:4bfb42d6c70c | 65 | { |
DimiterK | 3:4bfb42d6c70c | 66 | uint8_t status = readRegister( MAX30101_ModeConfiguration ); |
AswinSivakumar | 0:a4ffc3c3e770 | 67 | |
DimiterK | 3:4bfb42d6c70c | 68 | if ( 0 == ( status & RESET ) ) |
DimiterK | 3:4bfb42d6c70c | 69 | { |
DimiterK | 3:4bfb42d6c70c | 70 | return STATUS_MAXIM_SUCCESS; |
DimiterK | 3:4bfb42d6c70c | 71 | } |
DimiterK | 3:4bfb42d6c70c | 72 | } |
AswinSivakumar | 0:a4ffc3c3e770 | 73 | |
AswinSivakumar | 0:a4ffc3c3e770 | 74 | } |
AswinSivakumar | 0:a4ffc3c3e770 | 75 | |
DimiterK | 3:4bfb42d6c70c | 76 | void MAX30101::setMode(max30101_mode_t sensorMode) |
AswinSivakumar | 0:a4ffc3c3e770 | 77 | { |
DimiterK | 3:4bfb42d6c70c | 78 | |
DimiterK | 3:4bfb42d6c70c | 79 | } |
DimiterK | 3:4bfb42d6c70c | 80 | |
DimiterK | 3:4bfb42d6c70c | 81 | void MAX30101::setSPO2_ADC_range(void) |
DimiterK | 3:4bfb42d6c70c | 82 | { |
DimiterK | 3:4bfb42d6c70c | 83 | |
AswinSivakumar | 0:a4ffc3c3e770 | 84 | |
AswinSivakumar | 0:a4ffc3c3e770 | 85 | } |
AswinSivakumar | 0:a4ffc3c3e770 | 86 | |
DimiterK | 3:4bfb42d6c70c | 87 | |
DimiterK | 3:4bfb42d6c70c | 88 | void MAX30101::set_SPO2_sampleRange(void) |
DimiterK | 3:4bfb42d6c70c | 89 | { |
DimiterK | 3:4bfb42d6c70c | 90 | |
DimiterK | 3:4bfb42d6c70c | 91 | } |
DimiterK | 3:4bfb42d6c70c | 92 | |
DimiterK | 3:4bfb42d6c70c | 93 | void MAX30101::set_LED_PulseWidth(uint8_t pw) |
DimiterK | 3:4bfb42d6c70c | 94 | { |
DimiterK | 3:4bfb42d6c70c | 95 | |
DimiterK | 3:4bfb42d6c70c | 96 | } |
DimiterK | 3:4bfb42d6c70c | 97 | |
DimiterK | 3:4bfb42d6c70c | 98 | max30101_status_t MAX30101::readRawData(uint8_t* dataBuff, uint8_t* sampleNum ) |
AswinSivakumar | 0:a4ffc3c3e770 | 99 | { |
DimiterK | 3:4bfb42d6c70c | 100 | // temporary buffer to read samples from the FIFO buffer |
DimiterK | 3:4bfb42d6c70c | 101 | uint8_t tmpBuf[ MAXIM_FIFO_DEPTH * MAXIM_BYTES_PER_ADC_VALUE ]; |
DimiterK | 3:4bfb42d6c70c | 102 | |
DimiterK | 3:4bfb42d6c70c | 103 | uint8_t numAvailSam; |
DimiterK | 3:4bfb42d6c70c | 104 | |
DimiterK | 3:4bfb42d6c70c | 105 | // read FIFO pointers |
DimiterK | 3:4bfb42d6c70c | 106 | uint8_t fifoWrPtr = readRegister( MAX30101_FIFO_WR_PTR ); |
DimiterK | 3:4bfb42d6c70c | 107 | uint8_t fifoRdPtr = readRegister( MAX30101_FIFO_RD_PTR ); |
DimiterK | 3:4bfb42d6c70c | 108 | uint8_t fifoOvPtr = readRegister( MAX30101_FIFO_OV_PTR ); |
DimiterK | 3:4bfb42d6c70c | 109 | |
DimiterK | 3:4bfb42d6c70c | 110 | // overflow happened |
DimiterK | 3:4bfb42d6c70c | 111 | if ( fifoOvPtr > 0 ) |
DimiterK | 3:4bfb42d6c70c | 112 | { |
DimiterK | 3:4bfb42d6c70c | 113 | uint8_t cmd = MAX30101_FIFO_DATA ; |
DimiterK | 3:4bfb42d6c70c | 114 | readRegs(cmd,tmpBuf,100); |
DimiterK | 3:4bfb42d6c70c | 115 | numAvailSam = 0xFF; |
DimiterK | 3:4bfb42d6c70c | 116 | } |
DimiterK | 3:4bfb42d6c70c | 117 | |
DimiterK | 3:4bfb42d6c70c | 118 | else |
DimiterK | 3:4bfb42d6c70c | 119 | { |
DimiterK | 3:4bfb42d6c70c | 120 | if ( fifoWrPtr > fifoRdPtr ) |
DimiterK | 3:4bfb42d6c70c | 121 | { |
DimiterK | 3:4bfb42d6c70c | 122 | /** |
DimiterK | 3:4bfb42d6c70c | 123 | * NUM_AVAILABLE_SAMPLES = FIFO_WR_PTR – FIFO_RD_PTR |
DimiterK | 3:4bfb42d6c70c | 124 | * NUM_SAMPLES_TO_READ = < less than or equal to NUM_AVAILABLE_SAMPLES > |
DimiterK | 3:4bfb42d6c70c | 125 | */ |
DimiterK | 3:4bfb42d6c70c | 126 | numAvailSam = fifoWrPtr - fifoRdPtr; |
DimiterK | 3:4bfb42d6c70c | 127 | } |
DimiterK | 3:4bfb42d6c70c | 128 | |
DimiterK | 3:4bfb42d6c70c | 129 | // note: pointer wrap around should be taken into account |
DimiterK | 3:4bfb42d6c70c | 130 | else if ( fifoWrPtr < fifoRdPtr ) |
DimiterK | 3:4bfb42d6c70c | 131 | { |
DimiterK | 3:4bfb42d6c70c | 132 | numAvailSam = fifoWrPtr + MAXIM_FIFO_DEPTH - fifoRdPtr; |
DimiterK | 3:4bfb42d6c70c | 133 | } |
DimiterK | 3:4bfb42d6c70c | 134 | |
DimiterK | 3:4bfb42d6c70c | 135 | // no new samples available |
DimiterK | 3:4bfb42d6c70c | 136 | else |
DimiterK | 3:4bfb42d6c70c | 137 | { |
DimiterK | 3:4bfb42d6c70c | 138 | numAvailSam = 0; |
DimiterK | 3:4bfb42d6c70c | 139 | } |
DimiterK | 3:4bfb42d6c70c | 140 | |
DimiterK | 3:4bfb42d6c70c | 141 | if ( numAvailSam > 0 ) |
DimiterK | 3:4bfb42d6c70c | 142 | { |
DimiterK | 3:4bfb42d6c70c | 143 | uint8_t cmd = MAX30101_FIFO_DATA ; |
DimiterK | 3:4bfb42d6c70c | 144 | |
DimiterK | 3:4bfb42d6c70c | 145 | /** |
DimiterK | 3:4bfb42d6c70c | 146 | * read all the available samples, |
DimiterK | 3:4bfb42d6c70c | 147 | * FIFO RD pointer is implicitly incremented after each successful sample read |
DimiterK | 3:4bfb42d6c70c | 148 | */ |
DimiterK | 3:4bfb42d6c70c | 149 | readRegs(cmd,tmpBuf,100); |
DimiterK | 3:4bfb42d6c70c | 150 | |
DimiterK | 3:4bfb42d6c70c | 151 | if ( NULL != dataBuff ) |
DimiterK | 3:4bfb42d6c70c | 152 | { |
DimiterK | 3:4bfb42d6c70c | 153 | memcpy ( |
DimiterK | 3:4bfb42d6c70c | 154 | (void*)dataBuff, |
DimiterK | 3:4bfb42d6c70c | 155 | (const void*)tmpBuf, |
DimiterK | 3:4bfb42d6c70c | 156 | numAvailSam * MAXIM_BYTES_PER_ADC_VALUE |
DimiterK | 3:4bfb42d6c70c | 157 | ); |
DimiterK | 3:4bfb42d6c70c | 158 | } |
DimiterK | 3:4bfb42d6c70c | 159 | } |
DimiterK | 3:4bfb42d6c70c | 160 | } |
DimiterK | 3:4bfb42d6c70c | 161 | |
DimiterK | 3:4bfb42d6c70c | 162 | /** save data */ |
DimiterK | 3:4bfb42d6c70c | 163 | |
DimiterK | 3:4bfb42d6c70c | 164 | if ( NULL != sampleNum ) |
DimiterK | 3:4bfb42d6c70c | 165 | { |
DimiterK | 3:4bfb42d6c70c | 166 | *sampleNum = numAvailSam; |
DimiterK | 3:4bfb42d6c70c | 167 | } |
DimiterK | 3:4bfb42d6c70c | 168 | |
DimiterK | 3:4bfb42d6c70c | 169 | |
DimiterK | 3:4bfb42d6c70c | 170 | return STATUS_MAXIM_SUCCESS; |
DimiterK | 3:4bfb42d6c70c | 171 | } |
DimiterK | 3:4bfb42d6c70c | 172 | |
DimiterK | 3:4bfb42d6c70c | 173 | float MAX30101::getTemp(void) |
DimiterK | 3:4bfb42d6c70c | 174 | { |
DimiterK | 3:4bfb42d6c70c | 175 | float temp = 0; |
DimiterK | 3:4bfb42d6c70c | 176 | |
DimiterK | 3:4bfb42d6c70c | 177 | return temp; |
DimiterK | 3:4bfb42d6c70c | 178 | } |
DimiterK | 3:4bfb42d6c70c | 179 | |
DimiterK | 3:4bfb42d6c70c | 180 | float MAX30101::getDieTemp(void) |
DimiterK | 3:4bfb42d6c70c | 181 | { |
DimiterK | 3:4bfb42d6c70c | 182 | float dieTemp = 0; |
DimiterK | 3:4bfb42d6c70c | 183 | |
DimiterK | 3:4bfb42d6c70c | 184 | |
DimiterK | 3:4bfb42d6c70c | 185 | return dieTemp; |
DimiterK | 3:4bfb42d6c70c | 186 | |
DimiterK | 3:4bfb42d6c70c | 187 | } |
DimiterK | 3:4bfb42d6c70c | 188 | |
DimiterK | 3:4bfb42d6c70c | 189 | uint8_t MAX30101::getRevisionID(void) |
DimiterK | 3:4bfb42d6c70c | 190 | { |
DimiterK | 3:4bfb42d6c70c | 191 | uint8_t chipid = 0; |
DimiterK | 3:4bfb42d6c70c | 192 | |
DimiterK | 3:4bfb42d6c70c | 193 | readRegs(MAX30101_DeviceID, &chipid, 1); |
DimiterK | 3:4bfb42d6c70c | 194 | return chipid; |
DimiterK | 3:4bfb42d6c70c | 195 | } |
AswinSivakumar | 0:a4ffc3c3e770 | 196 | |
DimiterK | 3:4bfb42d6c70c | 197 | uint8_t MAX30101::getChipID(void) |
DimiterK | 3:4bfb42d6c70c | 198 | { |
DimiterK | 3:4bfb42d6c70c | 199 | uint8_t chipid = 0; |
DimiterK | 3:4bfb42d6c70c | 200 | |
DimiterK | 3:4bfb42d6c70c | 201 | readRegs(MAX30101_DeviceID, &chipid, 1); |
DimiterK | 3:4bfb42d6c70c | 202 | return chipid; |
AswinSivakumar | 0:a4ffc3c3e770 | 203 | } |
AswinSivakumar | 0:a4ffc3c3e770 | 204 | |
DimiterK | 3:4bfb42d6c70c | 205 | void MAX30101::readRegs(int addr, uint8_t * data, int len) |
DimiterK | 3:4bfb42d6c70c | 206 | { |
DimiterK | 3:4bfb42d6c70c | 207 | char t[1] = {addr}; |
DimiterK | 3:4bfb42d6c70c | 208 | m_i2c.write(m_addr, t, 1, true); |
DimiterK | 3:4bfb42d6c70c | 209 | m_i2c.read(m_addr, (char *)data, len); |
DimiterK | 3:4bfb42d6c70c | 210 | } |
DimiterK | 3:4bfb42d6c70c | 211 | |
DimiterK | 3:4bfb42d6c70c | 212 | void MAX30101::writeRegs(uint8_t * data, int len) |
DimiterK | 3:4bfb42d6c70c | 213 | { |
DimiterK | 3:4bfb42d6c70c | 214 | m_i2c.write(m_addr, (char *)data, len); |
DimiterK | 3:4bfb42d6c70c | 215 | } |
DimiterK | 3:4bfb42d6c70c | 216 | |
DimiterK | 3:4bfb42d6c70c | 217 | |
DimiterK | 3:4bfb42d6c70c | 218 | uint8_t MAX30101::readRegister( uint8_t regaddr) |
DimiterK | 3:4bfb42d6c70c | 219 | { |
DimiterK | 3:4bfb42d6c70c | 220 | uint8_t data = 0; |
DimiterK | 3:4bfb42d6c70c | 221 | readRegs(regaddr, &data,1); |
DimiterK | 3:4bfb42d6c70c | 222 | return data; |
DimiterK | 3:4bfb42d6c70c | 223 | } |
DimiterK | 3:4bfb42d6c70c | 224 | |
DimiterK | 3:4bfb42d6c70c | 225 | void MAX30101::writeRegister(uint8_t regaddr, uint8_t data) |
DimiterK | 3:4bfb42d6c70c | 226 | { |
DimiterK | 3:4bfb42d6c70c | 227 | uint8_t i2data[2]= {regaddr, data}; |
DimiterK | 3:4bfb42d6c70c | 228 | |
DimiterK | 3:4bfb42d6c70c | 229 | writeRegs(i2data, 2); |
DimiterK | 3:4bfb42d6c70c | 230 | } |
AswinSivakumar | 0:a4ffc3c3e770 | 231 |