Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed MAX14720 USBDevice
Dependents: HSP_ECG_LeadOFF_Detection
MAX30101.cpp
00001 00002 /******************************************************************************* 00003 * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. 00004 * 00005 * Permission is hereby granted, free of charge, to any person obtaining a 00006 * copy of this software and associated documentation files (the "Software"), 00007 * to deal in the Software without restriction, including without limitation 00008 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 00009 * and/or sell copies of the Software, and to permit persons to whom the 00010 * Software is furnished to do so, subject to the following conditions: 00011 * 00012 * The above copyright notice and this permission notice shall be included 00013 * in all copies or substantial portions of the Software. 00014 * 00015 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 00016 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 00017 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 00018 * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES 00019 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 00020 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 00021 * OTHER DEALINGS IN THE SOFTWARE. 00022 * 00023 * Except as contained in this notice, the name of Maxim Integrated 00024 * Products, Inc. shall not be used except as stated in the Maxim Integrated 00025 * Products, Inc. Branding Policy. 00026 * 00027 * The mere transfer of this software does not imply any licenses 00028 * of trade secrets, proprietary technology, copyrights, patents, 00029 * trademarks, maskwork rights, or any other form of intellectual 00030 * property whatsoever. Maxim Integrated Products, Inc. retains all 00031 * ownership rights. 00032 ******************************************************************************* 00033 */ 00034 00035 #include "mbed.h" 00036 #include "MAX30101.h" 00037 00038 MAX30101 *MAX30101::instance = NULL; 00039 00040 //****************************************************************************** 00041 MAX30101::MAX30101(PinName sda, PinName scl, int slaveAddress): 00042 slaveAddress(slaveAddress) { 00043 i2c = new I2C(sda, scl); 00044 i2c_owner = true; 00045 i2c->frequency(400000); 00046 onInterruptCallback = NULL; 00047 onDataAvailableCallback = NULL; 00048 instance = this; 00049 } 00050 00051 //****************************************************************************** 00052 MAX30101::MAX30101(I2C *_i2c, int slaveAddress) : 00053 slaveAddress(slaveAddress) { 00054 i2c = _i2c; 00055 i2c_owner = false; 00056 i2c->frequency(400000); 00057 onInterruptCallback = NULL; 00058 onDataAvailableCallback = NULL; 00059 instance = this; 00060 } 00061 00062 //****************************************************************************** 00063 MAX30101::~MAX30101(void) { 00064 if (i2c_owner) { 00065 delete i2c; 00066 } 00067 } 00068 00069 //****************************************************************************** 00070 int MAX30101::int_handler(void) { 00071 uint16_t index, i; 00072 uint16_t rx_bytes, second_rx_bytes; 00073 char temp_int; 00074 char temp_frac; 00075 uint16_t num_active_led; 00076 uint32_t sample; 00077 int loop = 1; 00078 static uint8_t cntr_int = 0; 00079 00080 00081 cntr_int++; 00082 00083 while (loop) { 00084 if (i2c_reg_read(REG_INT_STAT_1, &max30101_Interrupt_Status_1.all) != 0) // Read Interrupt flag bits 00085 { 00086 return -1; 00087 } 00088 00089 if (i2c_reg_read(REG_INT_STAT_2, &max30101_Interrupt_Status_2.all) != 0) // Read Interrupt flag bits 00090 { 00091 return -1; 00092 } 00093 00094 if (max30101_Interrupt_Status_1.bit.a_full) { 00095 /* Read the sample(s) */ 00096 char reg = REG_FIFO_DATA; 00097 00098 num_active_led = 0; 00099 00100 if (max30101_mode_configuration.bit.mode == 0x02) // Heart Rate mode, i.e. 1 led 00101 { 00102 num_active_led = 1; 00103 } else if (max30101_mode_configuration.bit.mode == 0x03) // SpO2 mode, i.e. 2 led 00104 { 00105 num_active_led = 2; 00106 } else if (max30101_mode_configuration.bit.mode == 0x07) // Multi-LED mode, i.e. 1-4 led 00107 { 00108 if (max30101_multiLED_mode_ctrl_1.bit.slot1 != 0) { 00109 num_active_led++; 00110 } 00111 00112 if (max30101_multiLED_mode_ctrl_1.bit.slot2 != 0) { 00113 num_active_led++; 00114 } 00115 00116 if (max30101_multiLED_mode_ctrl_2.bit.slot3 != 0) { 00117 num_active_led++; 00118 } 00119 00120 if (max30101_multiLED_mode_ctrl_2.bit.slot4 != 0) { 00121 num_active_led++; 00122 } 00123 } 00124 // 3bytes/LED x Number of Active LED x FIFO level selected 00125 rx_bytes = 3 * num_active_led * (32-max30101_fifo_configuration.bit.fifo_a_full); 00126 00127 second_rx_bytes = rx_bytes; 00128 00129 /* The FIFO Size is determined by the Sample size. The number of bytes 00130 * in a Sample is dictated by number of LED's 00131 * 00132 * #LED Selected Bytes in "1" sample 00133 * 1 3 00134 * 2 6 00135 * 3 9 00136 * 4 12 00137 * 00138 * The I2C API function limits the number of bytes to read to 256 (i.e. 00139 * char). Therefore, when set for 00140 * Multiple LED's and the FIFO size is set to 32. It would mean there is 00141 * more than 256 bytes. 00142 * In that case two I2C reads have to be made. However It is important 00143 * to not that each "Sample" 00144 * must be read completely and reading only partial number of bytes from 00145 * a sample will result in erroneous data. 00146 * 00147 * For example: 00148 * Num of LED selected = 3 and FIFO size is set to 32 (i.e. 0 value in 00149 * register), then the number of bytes 00150 * will be 3bytes/Led * 3led's * 32 = 288 bytes in all. Since there are 00151 * 3 LED's each sample will contain (3 * 3) 00152 * 9bytes. Therefore Sample 1 = 9bytes, Sample 2 = 18,... Sample 28 = 00153 * 252. Therefore the first 00154 * I2C read should be 252 bytes and the second read should be 288-252 = 00155 * 36. 00156 * 00157 * It turns out that this size issue comes up only when number of LED 00158 * selected is 3 or 4 and choosing 252bytes 00159 * for the first I2C read would work for both Number of LED selection. 00160 */ 00161 00162 if (rx_bytes <= CHUNK_SIZE) { 00163 I2CM_Read(slaveAddress, ®, 1, &max30101_rawData[0], 00164 (char)rx_bytes /*total_databytes_1*/); 00165 } else { 00166 I2CM_Read(slaveAddress, ®, 1, &max30101_rawData[0], CHUNK_SIZE); 00167 00168 second_rx_bytes = second_rx_bytes - CHUNK_SIZE; 00169 I2CM_Read(slaveAddress, ®, 1, &max30101_rawData[CHUNK_SIZE], 00170 (char)second_rx_bytes); 00171 } 00172 00173 index = 0; 00174 00175 for (i = 0; i < rx_bytes; i += 3) { 00176 sample = ((uint32_t)(max30101_rawData[i] & 0x03) << 16) | (max30101_rawData[i + 1] << 8) | max30101_rawData[i + 2]; 00177 00178 // Right shift the data based on the LED_PW setting 00179 sample = sample >> 00180 (3 - 00181 max30101_spo2_configuration.bit.led_pw); // 0=shift 3, 1=shift 2, 2=shift 1, 3=no shift 00182 00183 max30101_buffer[index++] = sample; 00184 } 00185 00186 onDataAvailableCallback(MAX30101_OXIMETER_DATA + num_active_led, max30101_buffer, index); 00187 } 00188 00189 // This interrupt handles the proximity interrupt, for future enhancements 00190 #if 0 00191 if(max30101_Interrupt_Status_1.bit.prox_int) 00192 { 00193 max30101_mode_configuration.full=0; 00194 max30101_mode_configuration.bit.mode=0x03; // SpO2 mode 00195 i2c_reg_write(REG_MODE_CFG, max30101_mode_configuration.full); 00196 00197 } 00198 #endif 00199 00200 // This interrupt handles the temperature interrupt 00201 if (max30101_Interrupt_Status_2.bit.die_temp_rdy) { 00202 char reg; 00203 00204 reg = REG_TINT; 00205 if (I2CM_Read(slaveAddress, ®, 1, &temp_int, 1) != 0) { 00206 return -1; 00207 } 00208 00209 reg = REG_TFRAC; 00210 if (I2CM_Read(slaveAddress, ®, 1, &temp_frac, 1) != 0) { 00211 return -1; 00212 } 00213 00214 max30101_final_temp = (int8_t)temp_int + 0.0625 * temp_frac; 00215 00216 if (i2c_reg_write(REG_TEMP_EN, 0x00) != 0) // Die Temperature Config, Temp disable... after one read... 00217 { 00218 return -1; 00219 } 00220 } 00221 00222 if (i2c_reg_read(REG_INT_STAT_1, &max30101_Interrupt_Status_1.all) != 0) // Read Interrupt flag bits 00223 { 00224 return -1; 00225 } 00226 if (max30101_Interrupt_Status_1.bit.a_full != 1) { 00227 loop = 0; 00228 } 00229 } 00230 00231 interruptPostCallback(); 00232 00233 00234 return 0; 00235 } 00236 00237 //****************************************************************************** 00238 int MAX30101::SpO2mode_init(uint8_t fifo_waterlevel_mark, uint8_t sample_avg, 00239 uint8_t sample_rate, uint8_t pulse_width, 00240 uint8_t red_led_current, uint8_t ir_led_current) { 00241 00242 char status; 00243 00244 max30101_mode_configuration.all = 0; 00245 max30101_mode_configuration.bit.reset = 1; 00246 if (i2c_reg_write(REG_MODE_CFG, max30101_mode_configuration.all) != 0) // Reset the device, Mode = don't use... 00247 { 00248 return -1; 00249 } 00250 00251 /* Give it some settle time (100ms) */ 00252 wait(1.0 / 10.0); // Let things settle down a bit 00253 00254 max30101_fifo_configuration.all = 0; 00255 max30101_fifo_configuration.bit.smp_ave = sample_avg; // Sample averaging; 00256 max30101_fifo_configuration.bit.fifo_roll_over_en = 1; // FIFO Roll over enabled 00257 max30101_fifo_configuration.bit.fifo_a_full = fifo_waterlevel_mark; // Interrupt when certain level is filled 00258 if (i2c_reg_write(REG_FIFO_CFG, max30101_fifo_configuration.all) != 0) { 00259 return -1; 00260 } 00261 00262 max30101_spo2_configuration.bit.spo2_adc_rge = 0x2; // ADC Range 8192 fullscale 00263 max30101_spo2_configuration.bit.spo2_sr = sample_rate; // 100 Samp/sec. 00264 max30101_spo2_configuration.bit.led_pw = pulse_width; // Pulse Width=411us and ADC Resolution=18 00265 if (i2c_reg_write(REG_SPO2_CFG, max30101_spo2_configuration.all) != 0) { 00266 return -1; 00267 } 00268 00269 max30101_led1_pa = red_led_current; // RED LED current 00270 if (i2c_reg_write(REG_LED1_PA, max30101_led1_pa) != 0) { 00271 return -1; 00272 } 00273 00274 max30101_led2_pa = ir_led_current; // IR LED current 00275 if (i2c_reg_write(REG_LED2_PA, max30101_led2_pa) != 0) { 00276 return -1; 00277 } 00278 00279 /************/ 00280 00281 if (i2c_reg_read(REG_INT_STAT_1, &status) != 0) // Clear INT1 by reading the status 00282 { 00283 return -1; 00284 } 00285 00286 if (i2c_reg_read(REG_INT_STAT_2, &status) != 0) // Clear INT2 by reading the status 00287 { 00288 return -1; 00289 } 00290 00291 if (i2c_reg_write(REG_FIFO_W_PTR, 0x00) != 0) // Clear FIFO ptr 00292 { 00293 return -1; 00294 } 00295 00296 if (i2c_reg_write(REG_FIFO_OVF_CNT, 0x00) != 0) // Clear FIFO ptr 00297 { 00298 return -1; 00299 } 00300 00301 if (i2c_reg_write(REG_FIFO_R_PTR, 0x00) != 0) // Clear FIFO ptr 00302 { 00303 return -1; 00304 } 00305 00306 max30101_Interrupt_Enable_1.all = 0; 00307 max30101_Interrupt_Enable_1.bit.a_full_en = 1; // Enable FIFO almost full interrupt 00308 if (i2c_reg_write(REG_INT_EN_1, max30101_Interrupt_Enable_1.all) != 0) { 00309 return -1; 00310 } 00311 00312 max30101_mode_configuration.all = 0; 00313 max30101_mode_configuration.bit.mode = 0x03; // SpO2 mode 00314 if (i2c_reg_write(REG_MODE_CFG, max30101_mode_configuration.all) != 0) { 00315 return -1; 00316 } 00317 00318 return 0; 00319 } 00320 00321 //****************************************************************************** 00322 int MAX30101::SpO2mode_stop(void) { 00323 00324 max30101_Interrupt_Enable_1.all = 0; 00325 max30101_Interrupt_Enable_1.bit.a_full_en = 0; // Disable FIFO almost full interrupt 00326 if (i2c_reg_write(REG_INT_EN_1, max30101_Interrupt_Enable_1.all) != 0) { 00327 return -1; 00328 } 00329 00330 max30101_mode_configuration.all = 0; 00331 max30101_mode_configuration.bit.mode = 0x00; // SpO2 mode off 00332 if (i2c_reg_write(REG_MODE_CFG, max30101_mode_configuration.all) != 0) { 00333 return -1; 00334 } 00335 00336 max30101_led1_pa = 0; // RED LED current, 0.0 00337 if (i2c_reg_write(REG_LED1_PA, max30101_led1_pa) != 0) { 00338 return -1; 00339 } 00340 00341 max30101_led2_pa = 0; // IR LED current, 0.0 00342 if (i2c_reg_write(REG_LED2_PA, max30101_led2_pa) != 0) { 00343 return -1; 00344 } 00345 00346 return 0; 00347 } 00348 00349 //****************************************************************************** 00350 int MAX30101::HRmode_init(uint8_t fifo_waterlevel_mark, uint8_t sample_avg, 00351 uint8_t sample_rate, uint8_t pulse_width, 00352 uint8_t red_led_current) { 00353 00354 /*uint8_t*/ char status; 00355 00356 max30101_mode_configuration.all = 0; 00357 max30101_mode_configuration.bit.reset = 1; 00358 if (i2c_reg_write(REG_MODE_CFG, max30101_mode_configuration.all) != 0) // Reset the device, Mode = don't use... 00359 { 00360 return -1; 00361 } 00362 00363 /* Give it some settle time (100ms) */ 00364 wait(1.0 / 10.0); // Let things settle down a bit 00365 00366 max30101_fifo_configuration.all = 0; 00367 max30101_fifo_configuration.bit.smp_ave = sample_avg; // Sample averaging; 00368 max30101_fifo_configuration.bit.fifo_roll_over_en = 1; // FIFO Roll over enabled 00369 max30101_fifo_configuration.bit.fifo_a_full = fifo_waterlevel_mark; // Interrupt when certain level is filled 00370 if (i2c_reg_write(REG_FIFO_CFG, max30101_fifo_configuration.all) != 0) { 00371 return -1; 00372 } 00373 00374 max30101_spo2_configuration.bit.spo2_adc_rge = 0x2; // ADC Range 8192 fullscale 00375 max30101_spo2_configuration.bit.spo2_sr = sample_rate; // 100 Samp/sec. 00376 max30101_spo2_configuration.bit.led_pw = pulse_width; // Pulse Width=411us and ADC Resolution=18 00377 if (i2c_reg_write(REG_SPO2_CFG, max30101_spo2_configuration.all) != 0) { 00378 return -1; 00379 } 00380 00381 max30101_led1_pa = red_led_current; // RED LED current, 0.0 00382 if (i2c_reg_write(REG_LED1_PA, max30101_led1_pa) != 0) { 00383 return -1; 00384 } 00385 00386 /************/ 00387 00388 if (i2c_reg_read(REG_INT_STAT_1, &status) != 0) // Clear INT1 by reading the status 00389 { 00390 return -1; 00391 } 00392 00393 if (i2c_reg_read(REG_INT_STAT_2, &status) != 0) // Clear INT2 by reading the status 00394 { 00395 return -1; 00396 } 00397 00398 if (i2c_reg_write(REG_FIFO_W_PTR, 0x00) != 0) // Clear FIFO ptr 00399 { 00400 return -1; 00401 } 00402 00403 if (i2c_reg_write(REG_FIFO_OVF_CNT, 0x00) != 0) // Clear FIFO ptr 00404 { 00405 return -1; 00406 } 00407 00408 if (i2c_reg_write(REG_FIFO_R_PTR, 0x00) != 0) // Clear FIFO ptr 00409 { 00410 return -1; 00411 } 00412 00413 max30101_Interrupt_Enable_1.all = 0; 00414 max30101_Interrupt_Enable_1.bit.a_full_en = 1; 00415 // max30101_Interrupt_Enable_1.bit.prox_int_en=0; // Enable Proximity 00416 // Interrupt 00417 if (i2c_reg_write(REG_INT_EN_1, max30101_Interrupt_Enable_1.all) != 0) { 00418 return -1; 00419 } 00420 00421 max30101_mode_configuration.all = 0; 00422 max30101_mode_configuration.bit.mode = 0x02; // HR mode 00423 if (i2c_reg_write(REG_MODE_CFG, max30101_mode_configuration.all) != 0) { 00424 return -1; 00425 } 00426 00427 return 0; 00428 } 00429 00430 //****************************************************************************** 00431 int MAX30101::HRmode_stop(void) { 00432 00433 max30101_Interrupt_Enable_1.all = 0; 00434 max30101_Interrupt_Enable_1.bit.a_full_en = 0; // Disable FIFO almost full interrupt 00435 if (i2c_reg_write(REG_INT_EN_1, max30101_Interrupt_Enable_1.all) != 0) { 00436 return -1; 00437 } 00438 00439 max30101_mode_configuration.all = 0; 00440 max30101_mode_configuration.bit.mode = 0x00; // HR mode off 00441 if (i2c_reg_write(REG_MODE_CFG, max30101_mode_configuration.all) != 0) { 00442 return -1; 00443 } 00444 00445 max30101_led1_pa = 0; // RED LED current, 0.0 00446 if (i2c_reg_write(REG_LED1_PA, max30101_led1_pa) != 0) { 00447 return -1; 00448 } 00449 00450 return 0; 00451 } 00452 00453 //****************************************************************************** 00454 int MAX30101::Multimode_init(uint8_t fifo_waterlevel_mark, uint8_t sample_avg, 00455 uint8_t sample_rate, uint8_t pulse_width, 00456 uint8_t red_led_current, uint8_t ir_led_current, 00457 uint8_t green_led_current, uint8_t slot_1, 00458 uint8_t slot_2, uint8_t slot_3, uint8_t slot_4) { 00459 char status; 00460 max30101_mode_configuration.all = 0; 00461 max30101_mode_configuration.bit.reset = 1; 00462 if (i2c_reg_write(REG_MODE_CFG, max30101_mode_configuration.all) != 0) // Reset the device, Mode = don't use... 00463 { 00464 return -1; 00465 } 00466 00467 /* Give it some settle time (100ms) */ // Let things settle down a bit 00468 wait(1.0 / 10.0); 00469 00470 max30101_fifo_configuration.all = 0; 00471 max30101_fifo_configuration.bit.smp_ave = sample_avg; // Sample averaging; 00472 max30101_fifo_configuration.bit.fifo_roll_over_en = 1; // FIFO Roll over enabled 00473 max30101_fifo_configuration.bit.fifo_a_full = 00474 fifo_waterlevel_mark; // Interrupt when certain level is filled 00475 if (i2c_reg_write(REG_FIFO_CFG, max30101_fifo_configuration.all) != 0) { 00476 return -1; 00477 } 00478 00479 max30101_spo2_configuration.bit.spo2_adc_rge = 0x2; // ADC Range 8192 fullscale 00480 max30101_spo2_configuration.bit.spo2_sr = sample_rate; // 100 Samp/sec. 00481 max30101_spo2_configuration.bit.led_pw = pulse_width; // Pulse Width=411us and ADC Resolution=18 00482 if (i2c_reg_write(REG_SPO2_CFG, max30101_spo2_configuration.all) != 0) { 00483 return -1; 00484 } 00485 00486 max30101_led1_pa = red_led_current; // RED LED current 00487 if (i2c_reg_write(REG_LED1_PA, max30101_led1_pa) != 0) { 00488 return -1; 00489 } 00490 00491 max30101_led2_pa = ir_led_current; // IR LED current 00492 if (i2c_reg_write(REG_LED2_PA, max30101_led2_pa) != 0) { 00493 return -1; 00494 } 00495 00496 max30101_led3_pa = green_led_current; // Green LED current 00497 if (i2c_reg_write(REG_LED3_PA, max30101_led3_pa) != 0) { 00498 return -1; 00499 } 00500 00501 // 0x01=Red(LED1), 0x02=IR(LED2), 0x03=Green(LED3) : Use LEDn_PA to adjust the intensity 00502 // 0x05=Red , 0x06=IR , 0x07=Green : Use PILOT_PA to adjust the intensity DO NOT USE THIS ROW... 00503 00504 max30101_multiLED_mode_ctrl_1.bit.slot1 = slot_1; 00505 max30101_multiLED_mode_ctrl_1.bit.slot2 = slot_2; 00506 if (i2c_reg_write(REG_SLT2_SLT1, max30101_multiLED_mode_ctrl_1.all)) { 00507 return -1; 00508 } 00509 00510 max30101_multiLED_mode_ctrl_2.all = 0; 00511 max30101_multiLED_mode_ctrl_2.bit.slot3 = slot_3; 00512 max30101_multiLED_mode_ctrl_2.bit.slot4 = slot_4; 00513 if (i2c_reg_write(REG_SLT4_SLT3, max30101_multiLED_mode_ctrl_2.all)) { 00514 return -1; 00515 } 00516 00517 /************/ 00518 00519 if (i2c_reg_read(REG_INT_STAT_1, &status) != 0) // Clear INT1 by reading the status 00520 { 00521 return -1; 00522 } 00523 00524 if (i2c_reg_read(REG_INT_STAT_2, &status) != 0) // Clear INT2 by reading the status 00525 { 00526 return -1; 00527 } 00528 00529 if (i2c_reg_write(REG_FIFO_W_PTR, 0x00) != 0) // Clear FIFO ptr 00530 { 00531 return -1; 00532 } 00533 00534 if (i2c_reg_write(REG_FIFO_OVF_CNT, 0x00) != 0) // Clear FIFO ptr 00535 { 00536 return -1; 00537 } 00538 00539 if (i2c_reg_write(REG_FIFO_R_PTR, 0x00) != 0) // Clear FIFO ptr 00540 { 00541 return -1; 00542 } 00543 00544 max30101_Interrupt_Enable_1.all = 0; 00545 max30101_Interrupt_Enable_1.bit.a_full_en = 1; // Enable FIFO almost full interrupt 00546 if (i2c_reg_write(REG_INT_EN_1, max30101_Interrupt_Enable_1.all) != 0) { 00547 return -1; 00548 } 00549 00550 max30101_mode_configuration.all = 0; 00551 max30101_mode_configuration.bit.mode = 0x07; // Multi-LED mode 00552 if (i2c_reg_write(REG_MODE_CFG, max30101_mode_configuration.all) != 0) { 00553 return -1; 00554 } 00555 00556 return 0; 00557 } 00558 00559 //****************************************************************************** 00560 int MAX30101::Multimode_stop(void) { 00561 00562 max30101_Interrupt_Enable_1.all = 0; 00563 max30101_Interrupt_Enable_1.bit.a_full_en = 0; // Disable FIFO almost full interrupt 00564 if (i2c_reg_write(REG_INT_EN_1, max30101_Interrupt_Enable_1.all) != 0) { 00565 return -1; 00566 } 00567 00568 max30101_mode_configuration.all = 0; 00569 max30101_mode_configuration.bit.mode = 0x00; // Multi-LED mode off 00570 if (i2c_reg_write(REG_MODE_CFG, max30101_mode_configuration.all) != 0) { 00571 return -1; 00572 } 00573 00574 max30101_led1_pa = 0; // RED LED current, 0.0 00575 if (i2c_reg_write(REG_LED1_PA, max30101_led1_pa) != 0) { 00576 return -1; 00577 } 00578 00579 max30101_led2_pa = 0; // IR LED current, 0.0 00580 if (i2c_reg_write(REG_LED2_PA, max30101_led2_pa) != 0) { 00581 return -1; 00582 } 00583 00584 max30101_led3_pa = 0; // Green LED current, 0.0 00585 if (i2c_reg_write(REG_LED3_PA, max30101_led3_pa) != 0) { 00586 return -1; 00587 } 00588 return 0; 00589 } 00590 00591 //****************************************************************************** 00592 int MAX30101::tempread(void) { 00593 max30101_Interrupt_Enable_2.all = 0; 00594 max30101_Interrupt_Enable_2.bit.die_temp_rdy_en = 1; // Enable the Temp Rdy; 00595 if (i2c_reg_write(REG_INT_EN_2, 0x02) != 0) // Interrupt Enable 2, Temperature Interrupt 00596 { 00597 return -1; 00598 } 00599 00600 if (i2c_reg_write(REG_TEMP_EN, 0x01) != 0) // Die Temperature Config, Temp enable... 00601 { 00602 return -1; 00603 } 00604 return 0; 00605 } 00606 00607 //****************************************************************************** 00608 int MAX30101::i2c_reg_write(MAX30101_REG_map_t reg, char value) { 00609 char cmdData[2] = {reg, value}; 00610 00611 if (I2CM_Write(slaveAddress, NULL, 0, cmdData, 2) != 0 /*2*/) { 00612 return -1; 00613 } 00614 00615 return 0; 00616 } 00617 00618 //****************************************************************************** 00619 int MAX30101::i2c_reg_read(MAX30101_REG_map_t reg, char *value) { 00620 if (I2CM_Read(slaveAddress, (char *)®, 1, value, 1) != 0 /*1*/) { 00621 return -1; 00622 } 00623 00624 return 0; 00625 } 00626 00627 /** 00628 * @brief Read from an I2C device 00629 * @param slaveAddress slave address to use with transaction 00630 * @param writeData pointer of data to write 00631 * @param writeCount number of data to write 00632 * @param readData pointer to buffer to read to 00633 * @param readCount number of bytes to read 00634 */ 00635 int MAX30101::I2CM_Read(int slaveAddress, char *writeData, char writeCount, 00636 char *readData, char readCount) { 00637 if (writeData != NULL && writeCount != 0) { 00638 i2c->write(slaveAddress, writeData, writeCount, true); 00639 } 00640 if (readData != NULL && readCount != 0) { 00641 i2c->read(slaveAddress, readData, readCount); 00642 } 00643 return 0; 00644 } 00645 00646 /** 00647 * @brief Write to an I2C device 00648 * @param slaveAddress slave address to use with transaction 00649 * @param writeData pointer of data to write 00650 * @param writeCount1 number of data to write 00651 * @param writeData2 pointer to buffer to read to 00652 * @param writeCount2 number of bytes to read 00653 */ 00654 int MAX30101::I2CM_Write(int slaveAddress, char *writeData1, char writeCount1, 00655 char *writeData2, char writeCount2) { 00656 if (writeData1 != NULL && writeCount1 != 0) { 00657 i2c->write(slaveAddress, writeData1, writeCount1); 00658 } 00659 if (writeData2 != NULL && writeCount2 != 0) { 00660 i2c->write(slaveAddress, writeData2, writeCount2); 00661 } 00662 return 0; 00663 } 00664 00665 //****************************************************************************** 00666 void MAX30101::onDataAvailable(DataCallbackFunction _onDataAvailable) { 00667 onDataAvailableCallback = _onDataAvailable; 00668 } 00669 00670 /** 00671 * @brief Used to notify an external function that interrupt data is available 00672 * @param id type of data available 00673 * @param buffer 32-bit buffer that points to the data 00674 * @param length length of 32-bit elements available 00675 */ 00676 void MAX30101::dataAvailable(uint32_t id, uint32_t *buffer, uint32_t length) { 00677 if (onDataAvailableCallback != NULL) { 00678 (*onDataAvailableCallback)(id, buffer, length); 00679 } 00680 } 00681 00682 //****************************************************************************** 00683 void MAX30101::onInterrupt(InterruptFunction _onInterrupt) { 00684 onInterruptCallback = _onInterrupt; 00685 } 00686 00687 /** 00688 * @brief Executed on interrupt 00689 * @param id type of data available 00690 * @param buffer 32-bit buffer that points to the data 00691 * @param length length of 32-bit elements available 00692 */ 00693 void MAX30101::interruptPostCallback(void) { 00694 if (onInterruptCallback != NULL) { 00695 (*onInterruptCallback)(); 00696 } 00697 } 00698 00699 int max30101_enableInterrupts = 0; 00700 /**************************************************************************************************************/ 00701 void MAX30101MidIntHandler(void) { 00702 MAX30101::instance->int_handler(); 00703 }
Generated on Fri Jul 29 2022 01:40:37 by
1.7.2