This program for MAX32620HSP board's ECG to recieve raw data on serial. You can delete everything in main() everything happens on StreamPacketUint32_ex
Dependencies: mbed MAX14720 USBDevice
Dependents: HSP_ECG_LeadOFF_Detection
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 Fri Jul 29 2022 01:40:37 by
1.7.2