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