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