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 //****************************************************************************** 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 Wed Jul 13 2022 08:45:46 by
1.7.2