MAX30001-MAX32630FTHR SYS EvKit
Dependencies: USBDevice max32630fthr
MAX30001.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 "MAX30001.h" 00037 00038 MAX30001 *MAX30001::instance = NULL; 00039 00040 00041 //****************************************************************************** 00042 MAX30001::MAX30001(PinName mosi, PinName miso, PinName sclk, PinName cs) 00043 { 00044 m_spi = new SPI(mosi, miso, sclk); 00045 m_cs = new DigitalOut(cs, 1); 00046 00047 m_spi->frequency(3000000); 00048 spi_owner = true; 00049 functionpointer.attach(&spiHandler); 00050 onDataAvailableCallback = NULL; 00051 instance = this; 00052 } 00053 00054 00055 //****************************************************************************** 00056 MAX30001::MAX30001(SPI *spi, DigitalOut *cs) 00057 { 00058 m_spi = spi; 00059 m_cs = cs; 00060 spi->frequency(3000000); 00061 spi_owner = false; 00062 functionpointer.attach(&spiHandler); 00063 onDataAvailableCallback = NULL; 00064 instance = this; 00065 } 00066 00067 00068 //****************************************************************************** 00069 MAX30001::~MAX30001(void) { 00070 00071 if (spi_owner) { 00072 delete m_spi; 00073 delete m_cs; 00074 } 00075 } 00076 00077 //****************************************************************************** 00078 int MAX30001::max30001_Rbias_FMSTR_Init(uint8_t En_rbias, uint8_t Rbiasv, 00079 uint8_t Rbiasp, uint8_t Rbiasn, 00080 uint8_t Fmstr) { 00081 if (max30001_reg_read(CNFG_GEN, &max30001_cnfg_gen.all) == -1) { 00082 return -1; 00083 } 00084 00085 max30001_cnfg_gen.bit.en_rbias = En_rbias; 00086 max30001_cnfg_gen.bit.rbiasv = Rbiasv; 00087 max30001_cnfg_gen.bit.rbiasp = Rbiasp; 00088 max30001_cnfg_gen.bit.rbiasn = Rbiasn; 00089 max30001_cnfg_gen.bit.fmstr = Fmstr; 00090 00091 if (max30001_reg_write(CNFG_GEN, max30001_cnfg_gen.all) == -1) { 00092 return -1; 00093 } 00094 return 0; 00095 } 00096 00097 //****************************************************************************** 00098 int MAX30001::max30001_CAL_InitStart(uint8_t En_Vcal, uint8_t Vmode, 00099 uint8_t Vmag, uint8_t Fcal, uint16_t Thigh, 00100 uint8_t Fifty) { 00101 // CNFG_CAL 00102 if (max30001_reg_read(CNFG_CAL, &max30001_cnfg_cal.all) == -1) { 00103 return -1; 00104 } 00105 00106 max30001_cnfg_cal.bit.vmode = Vmode; 00107 max30001_cnfg_cal.bit.vmag = Vmag; 00108 max30001_cnfg_cal.bit.fcal = Fcal; 00109 max30001_cnfg_cal.bit.thigh = Thigh; 00110 max30001_cnfg_cal.bit.fifty = Fifty; 00111 00112 if (max30001_reg_write(CNFG_CAL, max30001_cnfg_cal.all) == -1) { 00113 return -1; 00114 } 00115 00116 // RTOS uses a 32768HZ clock. 32768ticks represents 1secs. 1sec/10 = 00117 // 100msecs. 00118 wait(1.0 / 10.0); 00119 00120 if (max30001_reg_read(CNFG_CAL, &max30001_cnfg_cal.all) == -1) { 00121 return -1; 00122 } 00123 00124 max30001_cnfg_cal.bit.en_vcal = En_Vcal; 00125 00126 if (max30001_reg_write(CNFG_CAL, max30001_cnfg_cal.all) == -1) { 00127 return -1; 00128 } 00129 00130 // RTOS uses a 32768HZ clock. 32768ticks represents 1secs. 1sec/10 = 00131 // 100msecs. 00132 wait(1.0 / 10.0); 00133 00134 return 0; 00135 } 00136 00137 //****************************************************************************** 00138 int MAX30001::max30001_CAL_Stop(void) { 00139 00140 if (max30001_reg_read(CNFG_CAL, &max30001_cnfg_cal.all) == -1) { 00141 return -1; 00142 } 00143 00144 max30001_cnfg_cal.bit.en_vcal = 0; // Disable VCAL, all other settings are left unaffected 00145 00146 if (max30001_reg_write(CNFG_CAL, max30001_cnfg_cal.all) == -1) { 00147 return -1; 00148 } 00149 00150 return 0; 00151 } 00152 //****************************************************************************** 00153 //****************************************************************************** 00154 int MAX30001::max30001_INT_assignment(max30001_intrpt_Location_t en_enint_loc, max30001_intrpt_Location_t en_eovf_loc, max30001_intrpt_Location_t en_fstint_loc, 00155 max30001_intrpt_Location_t en_dcloffint_loc, max30001_intrpt_Location_t en_bint_loc, max30001_intrpt_Location_t en_bovf_loc, 00156 max30001_intrpt_Location_t en_bover_loc, max30001_intrpt_Location_t en_bundr_loc, max30001_intrpt_Location_t en_bcgmon_loc, 00157 max30001_intrpt_Location_t en_pint_loc, max30001_intrpt_Location_t en_povf_loc, max30001_intrpt_Location_t en_pedge_loc, 00158 max30001_intrpt_Location_t en_lonint_loc, max30001_intrpt_Location_t en_rrint_loc, max30001_intrpt_Location_t en_samp_loc, 00159 max30001_intrpt_type_t intb_Type, max30001_intrpt_type_t int2b_Type) 00160 00161 00162 { 00163 // INT1 00164 00165 if (max30001_reg_read(EN_INT, &max30001_en_int.all) == -1) { 00166 return -1; 00167 } 00168 00169 // max30001_en_int2.bit.en_pint = 0b1; // Keep this off... 00170 00171 max30001_en_int.bit.en_eint = 0b1 & en_enint_loc; 00172 max30001_en_int.bit.en_eovf = 0b1 & en_eovf_loc; 00173 max30001_en_int.bit.en_fstint = 0b1 & en_fstint_loc; 00174 00175 max30001_en_int.bit.en_dcloffint = 0b1 & en_dcloffint_loc; 00176 max30001_en_int.bit.en_bint = 0b1 & en_bint_loc; 00177 max30001_en_int.bit.en_bovf = 0b1 & en_bovf_loc; 00178 00179 max30001_en_int.bit.en_bover = 0b1 & en_bover_loc; 00180 max30001_en_int.bit.en_bundr = 0b1 & en_bundr_loc; 00181 max30001_en_int.bit.en_bcgmon = 0b1 & en_bcgmon_loc; 00182 00183 max30001_en_int.bit.en_pint = 0b1 & en_pint_loc; 00184 max30001_en_int.bit.en_povf = 0b1 & en_povf_loc; 00185 max30001_en_int.bit.en_pedge = 0b1 & en_pedge_loc; 00186 00187 max30001_en_int.bit.en_lonint = 0b1 & en_lonint_loc; 00188 max30001_en_int.bit.en_rrint = 0b1 & en_rrint_loc; 00189 max30001_en_int.bit.en_samp = 0b1 & en_samp_loc; 00190 00191 max30001_en_int.bit.intb_type = intb_Type; 00192 00193 if (max30001_reg_write(EN_INT, max30001_en_int.all) == -1) { 00194 return -1; 00195 } 00196 00197 // INT2 00198 00199 if (max30001_reg_read(EN_INT2, &max30001_en_int2.all) == -1) { 00200 return -1; 00201 } 00202 00203 max30001_en_int2.bit.en_eint = 0b1 & (en_enint_loc >> 1); 00204 max30001_en_int2.bit.en_eovf = 0b1 & (en_eovf_loc >> 1); 00205 max30001_en_int2.bit.en_fstint = 0b1 & (en_fstint_loc >> 1); 00206 00207 max30001_en_int2.bit.en_dcloffint = 0b1 & (en_dcloffint_loc >> 1); 00208 max30001_en_int2.bit.en_bint = 0b1 & (en_bint_loc >> 1); 00209 max30001_en_int2.bit.en_bovf = 0b1 & (en_bovf_loc >> 1); 00210 00211 max30001_en_int2.bit.en_bover = 0b1 & (en_bover_loc >> 1); 00212 max30001_en_int2.bit.en_bundr = 0b1 & (en_bundr_loc >> 1); 00213 max30001_en_int2.bit.en_bcgmon = 0b1 & (en_bcgmon_loc >> 1); 00214 00215 max30001_en_int2.bit.en_pint = 0b1 & (en_pint_loc >> 1); 00216 max30001_en_int2.bit.en_povf = 0b1 & (en_povf_loc >> 1); 00217 max30001_en_int2.bit.en_pedge = 0b1 & (en_pedge_loc >> 1); 00218 00219 max30001_en_int2.bit.en_lonint = 0b1 & (en_lonint_loc >> 1); 00220 max30001_en_int2.bit.en_rrint = 0b1 & (en_rrint_loc >> 1); 00221 max30001_en_int2.bit.en_samp = 0b1 & (en_samp_loc >> 1); 00222 00223 max30001_en_int2.bit.intb_type = int2b_Type; 00224 00225 if (max30001_reg_write(EN_INT2, max30001_en_int2.all) == -1) { 00226 return -1; 00227 } 00228 00229 return 0; 00230 } 00231 00232 //****************************************************************************** 00233 int MAX30001::max30001_ECG_InitStart(uint8_t En_ecg, uint8_t Openp, 00234 uint8_t Openn, uint8_t Pol, 00235 uint8_t Calp_sel, uint8_t Caln_sel, 00236 uint8_t E_fit, uint8_t Rate, uint8_t Gain, 00237 uint8_t Dhpf, uint8_t Dlpf) { 00238 00239 // CNFG_EMUX 00240 00241 if (max30001_reg_read(CNFG_EMUX, &max30001_cnfg_emux.all) == -1) { 00242 return -1; 00243 } 00244 00245 max30001_cnfg_emux.bit.openp = Openp; 00246 max30001_cnfg_emux.bit.openn = Openn; 00247 max30001_cnfg_emux.bit.pol = Pol; 00248 max30001_cnfg_emux.bit.calp_sel = Calp_sel; 00249 max30001_cnfg_emux.bit.caln_sel = Caln_sel; 00250 00251 if (max30001_reg_write(CNFG_EMUX, max30001_cnfg_emux.all) == -1) { 00252 return -1; 00253 } 00254 00255 /**** ENABLE CHANNELS ****/ 00256 // CNFG_GEN 00257 00258 if (max30001_reg_read(CNFG_GEN, &max30001_cnfg_gen.all) == -1) { 00259 return -1; 00260 } 00261 00262 max30001_cnfg_gen.bit.en_ecg = En_ecg; // 0b1 00263 00264 // fmstr is default 00265 00266 if (max30001_reg_write(CNFG_GEN, max30001_cnfg_gen.all) == -1) { 00267 return -1; 00268 } 00269 00270 /**** Wait for PLL Lock & References to settle down ****/ 00271 00272 max30001_timeout = 0; 00273 00274 do { 00275 if (max30001_reg_read(STATUS, &max30001_status.all) == -1) // Wait and spin for PLL to lock... 00276 { 00277 return -1; 00278 } 00279 } while (max30001_status.bit.pllint == 1 && max30001_timeout++ <= 1000); 00280 00281 // MNGR_INT 00282 00283 if (max30001_reg_read(MNGR_INT, &max30001_mngr_int.all) == -1) { 00284 return -1; 00285 } 00286 00287 max30001_mngr_int.bit.e_fit = E_fit; // 31 00288 00289 if (max30001_reg_write(MNGR_INT, max30001_mngr_int.all) == -1) { 00290 return -1; 00291 } 00292 00293 // CNFG_ECG 00294 00295 if (max30001_reg_read(CNFG_ECG, &max30001_cnfg_ecg.all) == -1) { 00296 return -1; 00297 } 00298 00299 max30001_cnfg_ecg.bit.rate = Rate; 00300 max30001_cnfg_ecg.bit.gain = Gain; 00301 max30001_cnfg_ecg.bit.dhpf = Dhpf; 00302 max30001_cnfg_ecg.bit.dlpf = Dlpf; 00303 00304 if (max30001_reg_write(CNFG_ECG, max30001_cnfg_ecg.all) == -1) { 00305 return -1; 00306 } 00307 00308 return 0; 00309 } 00310 00311 //****************************************************************************** 00312 int MAX30001::max30001_ECGFast_Init(uint8_t Clr_Fast, uint8_t Fast, uint8_t Fast_Th) { 00313 if (max30001_reg_read(MNGR_INT, &max30001_mngr_int.all) == -1) { 00314 return -1; 00315 } 00316 00317 max30001_mngr_int.bit.clr_fast = Clr_Fast; 00318 00319 if (max30001_reg_write(MNGR_INT, max30001_mngr_int.all) == -1) { 00320 return -1; 00321 } 00322 00323 if (max30001_reg_read(MNGR_DYN, &max30001_mngr_dyn.all) == -1) { 00324 return -1; 00325 } 00326 00327 max30001_mngr_dyn.bit.fast = Fast; 00328 max30001_mngr_dyn.bit.fast_th = Fast_Th; 00329 00330 if (max30001_reg_write(MNGR_INT, max30001_mngr_int.all) == -1) { 00331 return -1; 00332 } 00333 00334 return 0; 00335 } 00336 00337 //****************************************************************************** 00338 int MAX30001::max30001_Stop_ECG(void) { 00339 00340 if (max30001_reg_read(CNFG_GEN, &max30001_cnfg_gen.all) == -1) { 00341 return -1; 00342 } 00343 00344 max30001_cnfg_gen.bit.en_ecg = 0; // Stop ECG 00345 00346 // fmstr is default 00347 00348 if (max30001_reg_write(CNFG_GEN, max30001_cnfg_gen.all) == -1) { 00349 return -1; 00350 } 00351 00352 return 0; 00353 } 00354 00355 //****************************************************************************** 00356 int MAX30001::max30001_PACE_InitStart(uint8_t En_pace, uint8_t Clr_pedge, 00357 uint8_t Pol, uint8_t Gn_diff_off, 00358 uint8_t Gain, uint8_t Aout_lbw, 00359 uint8_t Aout, uint8_t Dacp, 00360 uint8_t Dacn) { 00361 00362 /**** SET MASTER FREQUENCY, ENABLE CHANNELS ****/ 00363 00364 // CNFG_GEN 00365 00366 if (max30001_reg_read(CNFG_GEN, &max30001_cnfg_gen.all) == -1) { 00367 return -1; 00368 } 00369 00370 max30001_cnfg_gen.bit.en_pace = En_pace; // 0b1; 00371 00372 if (max30001_reg_write(CNFG_GEN, max30001_cnfg_gen.all) == -1) { 00373 return -1; 00374 } 00375 00376 /**** Wait for PLL Lock & References to settle down ****/ 00377 max30001_timeout = 0; 00378 00379 do { 00380 if (max30001_reg_read(STATUS, &max30001_status.all) == 00381 -1) // Wait and spin for PLL to lock... 00382 { 00383 return -1; 00384 } 00385 00386 } while (max30001_status.bit.pllint == 1 && max30001_timeout++ <= 1000); 00387 00388 // MNGR_INT 00389 00390 if (max30001_reg_read(MNGR_INT, &max30001_mngr_int.all) == -1) { 00391 return -1; 00392 } 00393 00394 max30001_mngr_int.bit.clr_pedge = Clr_pedge; // 0b0; 00395 00396 if (max30001_reg_write(MNGR_INT, max30001_mngr_int.all) == -1) { 00397 return -1; 00398 } 00399 00400 /* Put: CNFG_PACE */ 00401 00402 max30001_reg_read(CNFG_PACE, &max30001_cnfg_pace.all); 00403 00404 max30001_cnfg_pace.bit.pol = Pol; 00405 max30001_cnfg_pace.bit.gn_diff_off = Gn_diff_off; 00406 max30001_cnfg_pace.bit.gain = Gain; 00407 max30001_cnfg_pace.bit.aout_lbw = Aout_lbw; 00408 max30001_cnfg_pace.bit.aout = Aout; 00409 max30001_cnfg_pace.bit.dacp = Dacp; 00410 max30001_cnfg_pace.bit.dacn = Dacn; 00411 00412 max30001_reg_write(CNFG_PACE, max30001_cnfg_pace.all); 00413 00414 return 0; 00415 } 00416 //****************************************************************************** 00417 int MAX30001::max30001_Stop_PACE(void) { 00418 00419 if (max30001_reg_read(CNFG_GEN, &max30001_cnfg_gen.all) == -1) { 00420 return -1; 00421 } 00422 00423 max30001_cnfg_gen.bit.en_pace = 0; // Stop PACE 00424 00425 if (max30001_reg_write(CNFG_GEN, max30001_cnfg_gen.all) == -1) { 00426 return -1; 00427 } 00428 00429 return 0; 00430 } 00431 00432 //****************************************************************************** 00433 int MAX30001::max30001_BIOZ_InitStart( 00434 uint8_t En_bioz, uint8_t Openp, uint8_t Openn, uint8_t Calp_sel, 00435 uint8_t Caln_sel, uint8_t CG_mode, uint8_t B_fit, uint8_t Rate, 00436 uint8_t Ahpf, uint8_t Ext_rbias, uint8_t Gain, uint8_t Dhpf, uint8_t Dlpf, 00437 uint8_t Fcgen, uint8_t Cgmon, uint8_t Cgmag, uint8_t Phoff, uint8_t Inapow_mode) { 00438 00439 // CNFG_BMUX 00440 00441 if (max30001_reg_read(CNFG_BMUX, &max30001_cnfg_bmux.all) == -1) { 00442 return -1; 00443 } 00444 00445 max30001_cnfg_bmux.bit.openp = Openp; // 0b1; 00446 max30001_cnfg_bmux.bit.openn = Openn; // 0b1; 00447 max30001_cnfg_bmux.bit.calp_sel = Calp_sel; // 0b10; 00448 max30001_cnfg_bmux.bit.caln_sel = Caln_sel; // 0b11; 00449 max30001_cnfg_bmux.bit.cg_mode = CG_mode; // 0b00; 00450 00451 if (max30001_reg_write(CNFG_BMUX, max30001_cnfg_bmux.all) == -1) { 00452 return -1; 00453 } 00454 00455 /**** SET MASTER FREQUENCY, ENABLE CHANNELS ****/ 00456 00457 // CNFG_GEN 00458 00459 if (max30001_reg_read(CNFG_GEN, &max30001_cnfg_gen.all) == -1) { 00460 return -1; 00461 } 00462 00463 max30001_cnfg_gen.bit.en_bioz = En_bioz; 00464 00465 // fmstr is default 00466 00467 if (max30001_reg_write(CNFG_GEN, max30001_cnfg_gen.all) == -1) { 00468 return -1; 00469 } 00470 00471 /**** Wait for PLL Lock & References to settle down ****/ 00472 00473 max30001_timeout = 0; 00474 00475 do { 00476 if (max30001_reg_read(STATUS, &max30001_status.all) == 00477 -1) // Wait and spin for PLL to lock... 00478 { 00479 return -1; 00480 } 00481 00482 } while (max30001_status.bit.pllint == 1 && max30001_timeout++ <= 1000); 00483 00484 /**** Start of CNFG_BIOZ ****/ 00485 00486 // MNGR_INT 00487 00488 if (max30001_reg_read(MNGR_INT, &max30001_mngr_int.all) == -1) { 00489 return -1; 00490 } 00491 00492 max30001_mngr_int.bit.b_fit = B_fit; //; 00493 00494 if (max30001_reg_write(MNGR_INT, max30001_mngr_int.all) == -1) { 00495 return -1; 00496 } 00497 00498 // CNFG_BIOZ 00499 00500 if (max30001_reg_read(CNFG_BIOZ, &max30001_cnfg_bioz.all) == -1) { 00501 return -1; 00502 } 00503 00504 max30001_cnfg_bioz.bit.rate = Rate; 00505 max30001_cnfg_bioz.bit.ahpf = Ahpf; 00506 max30001_cnfg_bioz.bit.ext_rbias = Ext_rbias; 00507 max30001_cnfg_bioz.bit.gain = Gain; 00508 max30001_cnfg_bioz.bit.dhpf = Dhpf; 00509 max30001_cnfg_bioz.bit.dlpf = Dlpf; 00510 max30001_cnfg_bioz.bit.fcgen = Fcgen; 00511 max30001_cnfg_bioz.bit.cgmon = Cgmon; 00512 max30001_cnfg_bioz.bit.cgmag = Cgmag; 00513 max30001_cnfg_bioz.bit.phoff = Phoff; 00514 max30001_cnfg_bioz.bit.inapow_mode = Inapow_mode; 00515 00516 if (max30001_reg_write(CNFG_BIOZ, max30001_cnfg_bioz.all) == -1) { 00517 return -1; 00518 } 00519 00520 return 0; 00521 } 00522 00523 //****************************************************************************** 00524 int MAX30001::max30001_Stop_BIOZ(void) { 00525 00526 if (max30001_reg_read(CNFG_GEN, &max30001_cnfg_gen.all) == -1) { 00527 return -1; 00528 } 00529 00530 max30001_cnfg_gen.bit.en_bioz = 0; // Stop BIOZ 00531 00532 if (max30001_reg_write(CNFG_GEN, max30001_cnfg_gen.all) == -1) { 00533 return -1; 00534 } 00535 00536 return 0; 00537 } 00538 00539 //****************************************************************************** 00540 int MAX30001::max30001_BIOZ_InitBist(uint8_t En_bist, uint8_t Rnom, 00541 uint8_t Rmod, uint8_t Fbist) { 00542 00543 // CNFG_BMUX 00544 00545 if (max30001_reg_read(CNFG_BMUX, &max30001_cnfg_bmux.all) == -1) { 00546 return -1; 00547 } 00548 00549 max30001_cnfg_bmux.bit.en_bist = En_bist; 00550 max30001_cnfg_bmux.bit.rnom = Rnom; 00551 max30001_cnfg_bmux.bit.rmod = Rmod; 00552 max30001_cnfg_bmux.bit.fbist = Fbist; 00553 00554 if (max30001_reg_write(CNFG_BMUX, max30001_cnfg_bmux.all) == -1) { 00555 return -1; 00556 } 00557 00558 return 0; 00559 } 00560 //****************************************************************************** 00561 int MAX30001::max30001_RtoR_InitStart(uint8_t En_rtor, uint8_t Wndw, 00562 uint8_t Gain, uint8_t Pavg, uint8_t Ptsf, 00563 uint8_t Hoff, uint8_t Ravg, uint8_t Rhsf, 00564 uint8_t Clr_rrint) { 00565 00566 // MNGR_INT 00567 00568 if (max30001_reg_read(MNGR_INT, &max30001_mngr_int.all) == -1) { 00569 return -1; 00570 } 00571 00572 max30001_mngr_int.bit.clr_rrint = 00573 Clr_rrint; // 0b01 & 0b00 are for interrupt mode... 00574 // 0b10 is for monitoring mode... it just overwrites the data... 00575 00576 if (max30001_reg_write(MNGR_INT, max30001_mngr_int.all) == -1) { 00577 return -1; 00578 } 00579 00580 // RTOR1 00581 if (max30001_reg_read(CNFG_RTOR1, &max30001_cnfg_rtor1.all) == -1) { 00582 return -1; 00583 } 00584 00585 max30001_cnfg_rtor1.bit.wndw = Wndw; 00586 max30001_cnfg_rtor1.bit.gain = Gain; 00587 max30001_cnfg_rtor1.bit.en_rtor = En_rtor; 00588 max30001_cnfg_rtor1.bit.pavg = Pavg; 00589 max30001_cnfg_rtor1.bit.ptsf = Ptsf; 00590 00591 if (max30001_reg_write(CNFG_RTOR1, max30001_cnfg_rtor1.all) == -1) { 00592 return -1; 00593 } 00594 // RTOR2 00595 00596 if (max30001_reg_read(CNFG_RTOR2, &max30001_cnfg_rtor2.all) == -1) { 00597 return -1; 00598 } 00599 max30001_cnfg_rtor2.bit.hoff = Hoff; 00600 max30001_cnfg_rtor2.bit.ravg = Ravg; 00601 max30001_cnfg_rtor2.bit.rhsf = Rhsf; 00602 00603 if (max30001_reg_write(CNFG_RTOR2, max30001_cnfg_rtor2.all) == -1) { 00604 return -1; 00605 } 00606 00607 return 0; 00608 } 00609 00610 //****************************************************************************** 00611 int MAX30001::max30001_Stop_RtoR(void) { 00612 00613 if (max30001_reg_read(CNFG_RTOR1, &max30001_cnfg_rtor1.all) == -1) { 00614 return -1; 00615 } 00616 00617 max30001_cnfg_rtor1.bit.en_rtor = 0; // Stop RtoR 00618 00619 if (max30001_reg_write(CNFG_RTOR1, max30001_cnfg_rtor1.all) == -1) { 00620 return -1; 00621 } 00622 00623 return 0; 00624 } 00625 00626 //****************************************************************************** 00627 int MAX30001::max30001_PLL_lock(void) { 00628 // Spin to see PLLint become zero to indicate a lock. 00629 00630 max30001_timeout = 0; 00631 00632 do { 00633 if (max30001_reg_read(STATUS, &max30001_status.all) == 00634 -1) // Wait and spin for PLL to lock... 00635 { 00636 return -1; 00637 } 00638 00639 } while (max30001_status.bit.pllint == 1 && max30001_timeout++ <= 1000); 00640 00641 return 0; 00642 } 00643 00644 //****************************************************************************** 00645 int MAX30001::max30001_sw_rst(void) { 00646 // SW reset for the MAX30001 chip 00647 00648 if (max30001_reg_write(SW_RST, 0x000000) == -1) { 00649 return -1; 00650 } 00651 00652 return 0; 00653 } 00654 00655 //****************************************************************************** 00656 int MAX30001::max30001_synch(void) { // For synchronization 00657 if (max30001_reg_write(SYNCH, 0x000000) == -1) { 00658 return -1; 00659 } 00660 return 0; 00661 } 00662 00663 //****************************************************************************** 00664 int MAX30001::max300001_fifo_rst(void) { // Resets the FIFO 00665 if (max30001_reg_write(FIFO_RST, 0x000000) == -1) { 00666 return -1; 00667 } 00668 return 0; 00669 } 00670 00671 //****************************************************************************** 00672 // int MAX30001::max30001_reg_write(uint8_t addr, uint32_t data) 00673 int MAX30001::max30001_reg_write(MAX30001_REG_map_t addr, uint32_t data) { 00674 00675 uint8_t result[4]; 00676 uint8_t data_array[4]; 00677 int32_t success = 0; 00678 00679 data_array[0] = (addr << 1) & 0xff; 00680 00681 data_array[3] = data & 0xff; 00682 data_array[2] = (data >> 8) & 0xff; 00683 data_array[1] = (data >> 16) & 0xff; 00684 00685 success = SPI_Transmit(&data_array[0], 4, &result[0], 4); 00686 00687 if (success != 0) { 00688 return -1; 00689 } else { 00690 return 0; 00691 } 00692 } 00693 00694 //****************************************************************************** 00695 // int MAX30001::max30001_reg_read(uint8_t addr, uint32_t *return_data) 00696 int MAX30001::max30001_reg_read(MAX30001_REG_map_t addr, 00697 uint32_t *return_data) { 00698 uint8_t result[4]; 00699 uint8_t data_array[1]; 00700 int32_t success = 0; 00701 00702 data_array[0] = ((addr << 1) & 0xff) | 1; // For Read, Or with 1 00703 success = SPI_Transmit(&data_array[0], 1, &result[0], 4); 00704 *return_data = /*result[0] + */ (uint32_t)(result[1] << 16) + 00705 (result[2] << 8) + result[3]; 00706 if (success != 0) { 00707 return -1; 00708 } else { 00709 return 0; 00710 } 00711 } 00712 00713 //****************************************************************************** 00714 int MAX30001::max30001_Enable_DcLeadOFF_Init(int8_t En_dcloff, int8_t Ipol, 00715 int8_t Imag, int8_t Vth) { 00716 // the leads are not touching the body 00717 00718 // CNFG_EMUX, Set ECGP and ECGN for external hook up... 00719 00720 if (max30001_reg_read(CNFG_GEN, &max30001_cnfg_gen.all) == -1) { 00721 return -1; 00722 } 00723 00724 max30001_cnfg_gen.bit.en_dcloff = En_dcloff; 00725 max30001_cnfg_gen.bit.ipol = Ipol; 00726 max30001_cnfg_gen.bit.imag = Imag; 00727 max30001_cnfg_gen.bit.vth = Vth; 00728 00729 if (max30001_reg_write(CNFG_GEN, max30001_cnfg_gen.all) == -1) { 00730 return -1; 00731 } 00732 00733 return 0; 00734 } 00735 00736 //****************************************************************************** 00737 int MAX30001::max30001_Disable_DcLeadOFF(void) { 00738 if (max30001_reg_read(CNFG_GEN, &max30001_cnfg_gen.all) == -1) { 00739 return -1; 00740 } 00741 00742 max30001_cnfg_gen.bit.en_dcloff = 0; // Turned off the dc lead off. 00743 00744 if (max30001_reg_write(CNFG_GEN, max30001_cnfg_gen.all) == -1) { 00745 return -1; 00746 } 00747 00748 return 0; 00749 } 00750 00751 //****************************************************************************** 00752 int MAX30001::max30001_BIOZ_Enable_ACLeadOFF_Init(uint8_t En_bloff, 00753 uint8_t Bloff_hi_it, 00754 uint8_t Bloff_lo_it) { 00755 00756 // CNFG_GEN 00757 if (max30001_reg_read(CNFG_GEN, &max30001_cnfg_gen.all) == -1) { 00758 return -1; 00759 } 00760 00761 max30001_cnfg_gen.bit.en_bloff = En_bloff; 00762 00763 if (max30001_reg_write(CNFG_GEN, max30001_cnfg_gen.all) == -1) { 00764 return -1; 00765 } 00766 00767 // MNGR_DYN 00768 if (max30001_reg_read(MNGR_DYN, &max30001_mngr_dyn.all) == -1) { 00769 return -1; 00770 } 00771 00772 max30001_mngr_dyn.bit.bloff_hi_it = Bloff_hi_it; 00773 max30001_mngr_dyn.bit.bloff_lo_it = Bloff_lo_it; 00774 00775 if (max30001_reg_write(MNGR_DYN, max30001_mngr_dyn.all) == -1) { 00776 return -1; 00777 } 00778 00779 return 0; 00780 } 00781 00782 //****************************************************************************** 00783 int MAX30001::max30001_BIOZ_Disable_ACleadOFF(void) { 00784 // CNFG_GEN 00785 if (max30001_reg_read(CNFG_GEN, &max30001_cnfg_gen.all) == -1) { 00786 return -1; 00787 } 00788 00789 max30001_cnfg_gen.bit.en_bloff = 0b0; // Turns of the BIOZ AC Lead OFF feature 00790 00791 if (max30001_reg_write(CNFG_GEN, max30001_cnfg_gen.all) == -1) { 00792 return -1; 00793 } 00794 00795 return 0; 00796 } 00797 00798 //****************************************************************************** 00799 int MAX30001::max30001_BIOZ_Enable_BCGMON(void) { 00800 // CNFG_BIOZ 00801 if (max30001_reg_read(CNFG_BIOZ, &max30001_cnfg_bioz.all) == -1) { 00802 return -1; 00803 } 00804 00805 max30001_cnfg_bioz.bit.cgmon = 1; 00806 00807 if (max30001_reg_write(CNFG_BIOZ, max30001_cnfg_bioz.all) == -1) { 00808 return -1; 00809 } 00810 00811 max30001_reg_read(CNFG_BIOZ, &max30001_cnfg_bioz.all); 00812 00813 return 0; 00814 } 00815 00816 #if 1 00817 //****************************************************************************** 00818 int MAX30001::max30001_Enable_LeadON(int8_t Channel) // Channel: ECG = 0b01, BIOZ = 0b10, Disable = 0b00 00819 { 00820 00821 if (max30001_reg_read(CNFG_GEN, &max30001_cnfg_gen.all) == -1) { 00822 return -1; 00823 } 00824 00825 max30001_cnfg_gen.bit.en_ecg = 0b0; 00826 max30001_cnfg_gen.bit.en_bioz = 0b0; 00827 max30001_cnfg_gen.bit.en_pace = 0b0; 00828 00829 max30001_cnfg_gen.bit.en_ulp_lon = Channel; // BIOZ ULP lead on detection... 00830 00831 if (max30001_reg_write(CNFG_GEN, max30001_cnfg_gen.all) == -1) { 00832 return -1; 00833 } 00834 00835 max30001_reg_read(CNFG_GEN, &max30001_cnfg_gen.all); 00836 00837 max30001_reg_read(STATUS, &max30001_status.all); 00838 00839 return 0; 00840 } 00841 //****************************************************************************** 00842 int MAX30001::max30001_Disable_LeadON(void) { 00843 00844 if (max30001_reg_read(CNFG_GEN, &max30001_cnfg_gen.all) == -1) { 00845 return -1; 00846 } 00847 00848 max30001_cnfg_gen.bit.en_ulp_lon = 0b0; 00849 00850 if (max30001_reg_write(CNFG_GEN, max30001_cnfg_gen.all) == -1) { 00851 return -1; 00852 } 00853 00854 return 0; 00855 } 00856 #endif 00857 //****************************************************************************** 00858 #define LEADOFF_SERVICE_TIME 0x2000 // 0x1000 = 1 second 00859 #define LEADOFF_NUMSTATES 2 00860 uint32_t leadoffState = 0; 00861 uint32_t max30001_LeadOffoldTime = 0; 00862 void MAX30001::max30001_ServiceLeadoff(uint32_t currentTime) { 00863 00864 uint32_t delta_Time; 00865 00866 delta_Time = currentTime - max30001_LeadOffoldTime; 00867 00868 if (delta_Time > LEADOFF_SERVICE_TIME) { 00869 switch (leadoffState) { 00870 case 0: /* switch to ECG DC Lead OFF */ 00871 max30001_Enable_DcLeadOFF_Init(0b01, 0b0, 0b001, 0b00); 00872 break; 00873 00874 case 1: /* switch to BIOZ DC Lead OFF */ 00875 max30001_Enable_DcLeadOFF_Init(0b10, 0b0, 0b001, 0b00); 00876 break; 00877 } 00878 00879 leadoffState++; 00880 leadoffState %= LEADOFF_NUMSTATES; 00881 00882 max30001_LeadOffoldTime = currentTime; 00883 } 00884 } 00885 //****************************************************************************** 00886 #define LEADON_SERVICE_TIME 0x2000 // 0x1000 = 1 second 00887 #define LEADON_NUMSTATES 2 00888 uint32_t leadOnState = 0; 00889 uint32_t max30001_LeadOnoldTime = 0; 00890 void MAX30001::max30001_ServiceLeadON(uint32_t currentTime) { 00891 00892 uint32_t delta_Time; 00893 00894 delta_Time = currentTime - max30001_LeadOnoldTime; 00895 00896 if (delta_Time > LEADON_SERVICE_TIME) { 00897 switch (leadOnState) { 00898 case 0: /* switch to ECG DC Lead ON */ 00899 max30001_Enable_LeadON(0b01); 00900 break; 00901 00902 case 1: /* switch to BIOZ DC Lead ON */ 00903 max30001_Enable_LeadON(0b10); 00904 break; 00905 } 00906 00907 leadOnState++; 00908 leadOnState %= LEADON_NUMSTATES; 00909 00910 max30001_LeadOnoldTime = currentTime; 00911 } 00912 } 00913 00914 //****************************************************************************** 00915 int MAX30001::max30001_FIFO_LeadONOff_Read(void) { 00916 00917 uint8_t result[32 * 3]; // 32words - 3bytes each 00918 uint8_t paceResult[6 * 3]; 00919 uint8_t data_array[4]; 00920 int32_t success = 0; 00921 int i, j; 00922 00923 uint32_t total_databytes; 00924 uint8_t i_index; 00925 uint8_t data_chunk; 00926 uint8_t loop_logic; 00927 00928 uint8_t etag, ptag, btag; 00929 00930 uint8_t adr; 00931 00932 //int8_t ReadAllPaceOnce; 00933 bool anyPaceDetected = false; 00934 static uint8_t dcloffint_OneShot = 0; 00935 static uint8_t acloffint_OneShot = 0; 00936 static uint8_t bcgmon_OneShot = 0; 00937 static uint8_t acleadon_OneShot = 0; 00938 00939 int8_t ret_val; 00940 00941 if (max30001_status.bit.eint == 1) { 00942 adr = ECG_FIFO_BURST; 00943 data_array[0] = ((adr << 1) & 0xff) | 1; 00944 00945 // The SPI routine only sends out data of 32 bytes in size. Therefore the 00946 // data is being read in 00947 // smaller chunks in this routine... 00948 00949 total_databytes = (max30001_mngr_int.bit.e_fit + 1) * 3; 00950 00951 i_index = 0; 00952 loop_logic = 1; 00953 00954 while (loop_logic) { 00955 if (total_databytes > 30) { 00956 data_chunk = 30; 00957 total_databytes = total_databytes - 30; 00958 } else { 00959 data_chunk = total_databytes; 00960 loop_logic = 0; 00961 } 00962 00963 /* The extra 1 byte is for the extra byte that comes out of the SPI */ 00964 success = SPI_Transmit(&data_array[0], 1, &result[i_index], (data_chunk + 1)); // Make a copy of the FIFO over here... 00965 00966 if (success != 0) { 00967 return -1; 00968 } 00969 00970 /* This is important, because every transaction above creates an empty 00971 * redundant data at result[0] */ 00972 for (j = i_index; j < (data_chunk + i_index); j++) /* get rid of the 1 extra byte by moving the whole array up one */ 00973 { 00974 result[j] = result[j + 1]; 00975 } 00976 00977 i_index = i_index + 30; /* point to the next array location to put the data in */ 00978 } 00979 00980 //ReadAllPaceOnce = 0; 00981 00982 /* Put the content of the FIFO based on the EFIT value, We ignore the 00983 * result[0] and start concatenating indexes: 1,2,3 - 4,5,6 - 7,8,9 - */ 00984 for (i = 0, j = 0; i < max30001_mngr_int.bit.e_fit + 1; i++, j = j + 3) // index1=23-16 bit, index2=15-8 bit, index3=7-0 bit 00985 { 00986 max30001_ECG_FIFO_buffer[i] = ((uint32_t)result[j] << 16) + (result[j + 1] << 8) + result[j + 2]; 00987 00988 etag = (0b00111000 & result[j + 2]) >> 3; 00989 ptag = 0b00000111 & result[j + 2]; 00990 00991 if (ptag != 0b111 ){//&& ReadAllPaceOnce == 0) { 00992 00993 //ReadAllPaceOnce = 1; // This will prevent extra read of PACE, once group 00994 // 0-5 is read ONCE. 00995 readPace(ptag, paceResult); // BUG: result data from ECG is being overwritten by the PACE data 00996 anyPaceDetected = true; 00997 } 00998 } 00999 01000 if (anyPaceDetected) 01001 dataAvailable(MAX30001_DATA_PACE, max30001_PACE, 18); // Send out the Pace data once only 01002 01003 if (etag != 0b110) { 01004 01005 dataAvailable(MAX30001_DATA_ECG, max30001_ECG_FIFO_buffer, (max30001_mngr_int.bit.e_fit + 1)); 01006 } 01007 01008 } /* End of ECG init */ 01009 01010 /* RtoR */ 01011 01012 if (max30001_status.bit.rrint == 1) { 01013 if (max30001_reg_read(RTOR, &max30001_RtoR_data) == -1) { 01014 return -1; 01015 } 01016 01017 max30001_RtoR_data = (0x00FFFFFF & max30001_RtoR_data) >> 10; 01018 01019 hspValMax30001.R2R = (uint16_t)max30001_RtoR_data; 01020 hspValMax30001.fmstr = (uint16_t)max30001_cnfg_gen.bit.fmstr; 01021 01022 dataAvailable(MAX30001_DATA_RTOR, &max30001_RtoR_data, 1); 01023 } 01024 01025 // Handling BIOZ data... 01026 01027 if (max30001_status.bit.bint == 1) { 01028 adr = 0x22; 01029 data_array[0] = ((adr << 1) & 0xff) | 1; 01030 01031 /* [(BFIT+1)*3byte]+1extra byte due to the addr */ 01032 01033 if (SPI_Transmit(&data_array[0], 1, &result[0],((max30001_mngr_int.bit.b_fit + 1) * 3) + 1) == -1) // Make a copy of the FIFO over here... 01034 01035 { 01036 return -1; 01037 } 01038 01039 btag = 0b00000111 & result[3]; 01040 01041 /* Put the content of the FIFO based on the BFIT value, We ignore the 01042 * result[0] and start concatenating indexes: 1,2,3 - 4,5,6 - 7,8,9 - */ 01043 for (i = 0, j = 0; i < max30001_mngr_int.bit.b_fit + 1; i++, j = j + 3) // index1=23-16 bit, index2=15-8 bit, index3=7-0 bit 01044 { 01045 max30001_BIOZ_FIFO_buffer[i] = ((uint32_t)result[j + 1] << 16) + (result[j + 2] << 8) + result[j + 3]; 01046 } 01047 01048 if (btag != 0b110) { 01049 dataAvailable(MAX30001_DATA_BIOZ, max30001_BIOZ_FIFO_buffer, 8); 01050 } 01051 } 01052 01053 ret_val = 0; 01054 01055 if (max30001_status.bit.dcloffint == 1) // ECG/BIOZ Lead Off 01056 { 01057 dcloffint_OneShot = 1; 01058 max30001_DCLeadOff = 0; 01059 max30001_DCLeadOff = max30001_DCLeadOff | (max30001_cnfg_gen.bit.en_dcloff << 8) | (max30001_status.all & 0x00000F); 01060 dataAvailable(MAX30001_DATA_LEADOFF_DC, &max30001_DCLeadOff, 1); 01061 01062 ret_val = 0b100; 01063 01064 } else if (dcloffint_OneShot == 1 && max30001_status.bit.dcloffint == 0) // Just send once when it comes out of dc lead off 01065 { 01066 max30001_DCLeadOff = 0; 01067 max30001_DCLeadOff = max30001_DCLeadOff | (max30001_cnfg_gen.bit.en_dcloff << 8) | (max30001_status.all & 0x00000F); 01068 dataAvailable(MAX30001_DATA_LEADOFF_DC, &max30001_DCLeadOff, 1); 01069 dcloffint_OneShot = 0; 01070 } 01071 01072 if (max30001_status.bit.bover == 1 || max30001_status.bit.bundr == 1) // BIOZ AC Lead Off 01073 { 01074 acloffint_OneShot = 1; 01075 max30001_ACLeadOff = 0; 01076 max30001_ACLeadOff = 01077 max30001_ACLeadOff | ((max30001_status.all & 0x030000) >> 16); 01078 dataAvailable(MAX30001_DATA_LEADOFF_AC, &max30001_ACLeadOff, 1); 01079 01080 ret_val = 0b1000; 01081 } else if (acloffint_OneShot == 1 && max30001_status.bit.bover == 0 && max30001_status.bit.bundr == 0) // Just send once when it comes out of ac lead off 01082 { 01083 max30001_ACLeadOff = 0; 01084 max30001_ACLeadOff = max30001_ACLeadOff | ((max30001_status.all & 0x030000) >> 16); 01085 dataAvailable(MAX30001_DATA_LEADOFF_AC, &max30001_ACLeadOff, 1); 01086 acloffint_OneShot = 0; 01087 } 01088 01089 if (max30001_status.bit.bcgmon == 1) // BIOZ BCGMON check 01090 { 01091 bcgmon_OneShot = 1; 01092 max30001_bcgmon = 0; 01093 max30001_bcgmon = max30001_bcgmon | ((max30001_status.all & 0x000030) >> 4); 01094 dataAvailable(MAX30001_DATA_BCGMON, &max30001_bcgmon, 1); 01095 01096 ret_val = 0b10000; 01097 } else if (bcgmon_OneShot == 1 && max30001_status.bit.bcgmon == 0) { 01098 max30001_bcgmon = 0; 01099 max30001_bcgmon = max30001_bcgmon | ((max30001_status.all & 0x000030) >> 4); 01100 bcgmon_OneShot = 0; 01101 dataAvailable(MAX30001_DATA_BCGMON, &max30001_bcgmon, 1); 01102 } 01103 01104 #if 0 01105 if(max30001_status.bit.lonint == 1) // AC LeadON Check 01106 { 01107 max30001_LeadOn = 0; 01108 max30001_reg_read(STATUS,&max30001_status.all); // Reading is important 01109 max30001_LeadOn = max30001_LeadOn | (max30001_cnfg_gen.bit.en_ulp_lon << 8) | ((max30001_status.all & 0x000800) >> 11); // 0b01 will mean ECG Lead On, 0b10 will mean BIOZ Lead On 01110 // LEAD ON has been detected... Now take actions 01111 } 01112 #endif 01113 01114 if (max30001_status.bit.lonint == 1 && 01115 acleadon_OneShot == 0) // AC LeadON Check, when lead is on 01116 { 01117 max30001_LeadOn = 0; 01118 max30001_reg_read(STATUS, &max30001_status.all); // Reading is important 01119 max30001_LeadOn = 01120 max30001_LeadOn | (max30001_cnfg_gen.bit.en_ulp_lon << 8) | 01121 ((max30001_status.all & 0x000800) >> 01122 11); // 0b01 will mean ECG Lead On, 0b10 will mean BIOZ Lead On 01123 01124 // LEAD ON has been detected... Now take actions 01125 acleadon_OneShot = 1; 01126 dataAvailable(MAX30001_DATA_ACLEADON, &max30001_LeadOn, 1); // One shot data will be sent... 01127 } else if (max30001_status.bit.lonint == 0 && acleadon_OneShot == 1) { 01128 max30001_LeadOn = 0; 01129 max30001_reg_read(STATUS, &max30001_status.all); 01130 max30001_LeadOn = 01131 max30001_LeadOn | (max30001_cnfg_gen.bit.en_ulp_lon << 8) | ((max30001_status.all & 0x000800) >> 11); // 0b01 will mean ECG Lead On, 0b10 will mean BIOZ Lead On 01132 dataAvailable(MAX30001_DATA_ACLEADON, &max30001_LeadOn, 1); // One shot data will be sent... 01133 acleadon_OneShot = 0; 01134 } 01135 01136 return ret_val; 01137 } 01138 01139 //****************************************************************************** 01140 uint32_t MAX30001::readPace(int group, uint8_t* result) { 01141 uint8_t data_array[4]; 01142 uint32_t success; 01143 int adr = PACE0_FIFO_BURST + group*4; 01144 01145 if (group >= 6) 01146 return (uint32_t)-1; 01147 01148 data_array[0] = ((adr << 1) & 0xff) | 1; // For Read Or with 1 01149 success = SPI_Transmit(&data_array[0], 1, &result[0], 10); 01150 01151 max30001_PACE[group * 3 + 0] = (uint32_t)(result[1] << 16) + (result[2] << 8) + result[3]; 01152 max30001_PACE[group * 3 + 1] = (uint32_t)(result[4] << 16) + (result[5] << 8) + result[6]; 01153 max30001_PACE[group * 3 + 2] = (uint32_t)(result[7] << 16) + (result[8] << 8) + result[9]; 01154 01155 return success; 01156 } 01157 01158 //****************************************************************************** 01159 01160 //****************************************************************************** 01161 01162 int MAX30001::max30001_int_handler(void) { 01163 01164 static uint32_t InitReset = 0; 01165 01166 int8_t return_value; 01167 bool check_one_more = true; 01168 01169 status_check: 01170 max30001_reg_read(STATUS, &max30001_status.all); 01171 01172 // Inital Reset and any FIFO over flow invokes a FIFO reset 01173 if (InitReset == 0 || max30001_status.bit.eovf == 1 || max30001_status.bit.bovf == 1) { 01174 // Do a FIFO Reset 01175 max30001_reg_write(FIFO_RST, 0x000000); 01176 01177 InitReset++; 01178 return 2; 01179 } 01180 01181 return_value = 0; 01182 01183 // The four data handling goes on over here 01184 if (max30001_status.bit.eint == 1 || max30001_status.bit.pint == 1 || max30001_status.bit.bint == 1 || max30001_status.bit.rrint == 1 01185 || max30001_status.bit.dcloffint == 1 || max30001_status.bit.bover == 1 || max30001_status.bit.bundr == 1 01186 || max30001_status.bit.bcgmon == 1 || max30001_status.bit.lonint == 1) { 01187 return_value = return_value | max30001_FIFO_LeadONOff_Read(); 01188 } 01189 /* 01190 // ECG/BIOZ DC Lead Off test 01191 if (max30001_status.bit.dcloffint == 1) { 01192 return_value = return_value | max30001_FIFO_LeadONOff_Read(); 01193 } 01194 01195 // BIOZ AC Lead Off test 01196 if (max30001_status.bit.bover == 1 || max30001_status.bit.bundr == 1) { 01197 return_value = return_value | max30001_FIFO_LeadONOff_Read(); 01198 } 01199 01200 // BIOZ DRVP/N test using BCGMON. 01201 if (max30001_status.bit.bcgmon == 1) { 01202 return_value = return_value | max30001_FIFO_LeadONOff_Read(); 01203 } 01204 01205 if (max30001_status.bit.lonint == 1) // ECG Lead ON test: i.e. the leads are touching the body... 01206 { 01207 01208 max30001_FIFO_LeadONOff_Read(); 01209 } 01210 */ 01211 if (check_one_more) { 01212 check_one_more = false; 01213 goto status_check; 01214 } 01215 return return_value; 01216 } 01217 01218 /// function pointer to the async callback 01219 static event_callback_t functionpointer; 01220 /// flag used to indicate an async xfer has taken place 01221 static volatile int xferFlag = 0; 01222 01223 /** 01224 * @brief Callback handler for SPI async events 01225 * @param events description of event that occurred 01226 */ 01227 01228 01229 static void spiHandler(int events) { xferFlag = 1; } 01230 01231 /** 01232 * @brief Transmit and recieve QUAD SPI data 01233 * @param tx_buf pointer to transmit byte buffer 01234 * @param tx_size number of bytes to transmit 01235 * @param rx_buf pointer to the recieve buffer 01236 * @param rx_size number of bytes to recieve 01237 */ 01238 int MAX30001::SPI_Transmit(const uint8_t *tx_buf, uint32_t tx_size, uint8_t *rx_buf, uint32_t rx_size) 01239 { 01240 m_cs->write(0); 01241 for(int i = 0; i < tx_size; i++) 01242 { 01243 m_spi->write(tx_buf[i]); 01244 } 01245 for(int i = 0; i < (rx_size - tx_size); i++) 01246 { 01247 rx_buf[i + 1] = m_spi->write(0xFF); 01248 } 01249 m_cs->write(1); 01250 01251 return 0; 01252 } 01253 01254 //****************************************************************************** 01255 void MAX30001::max30001_ReadHeartrateData(max30001_t *_hspValMax30001) { 01256 _hspValMax30001->R2R = hspValMax30001.R2R; 01257 _hspValMax30001->fmstr = hspValMax30001.fmstr; 01258 } 01259 01260 //****************************************************************************** 01261 void MAX30001::onDataAvailable(PtrFunction _onDataAvailable) { 01262 onDataAvailableCallback = _onDataAvailable; 01263 } 01264 01265 /** 01266 * @brief Used to notify an external function that interrupt data is available 01267 * @param id type of data available 01268 * @param buffer 32-bit buffer that points to the data 01269 * @param length length of 32-bit elements available 01270 */ 01271 void MAX30001::dataAvailable(uint32_t id, uint32_t *buffer, uint32_t length) { 01272 if (onDataAvailableCallback != NULL) { 01273 (*onDataAvailableCallback)(id, buffer, length); 01274 } 01275 } 01276 01277 /** 01278 * @brief Callback handler for SPI async events 01279 * @param events description of event that occurred 01280 */ 01281 void MAX30001::spiHandler(int events) { xferFlag = 1; } 01282 01283 //****************************************************************************** 01284 static int allowInterrupts = 0; 01285 01286 void MAX30001Mid_IntB_Handler(void) { 01287 if (allowInterrupts == 0) return; 01288 MAX30001::instance->max30001_int_handler(); 01289 } 01290 01291 void MAX30001Mid_Int2B_Handler(void) { 01292 if (allowInterrupts == 0) return; 01293 MAX30001::instance->max30001_int_handler(); 01294 } 01295 01296 void MAX30001_AllowInterrupts(int state) { 01297 allowInterrupts = state; 01298 } 01299
Generated on Tue Jul 12 2022 16:59:43 by 1.7.2