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 // * Copyright (C) 2016 Maxim Integrated Products, Inc., All Rights Reserved. 00003 // * 00004 // * Permission is hereby granted, free of charge, to any person obtaining a 00005 // * copy of this software and associated documentation files (the "Software"), 00006 // * to deal in the Software without restriction, including without limitation 00007 // * the rights to use, copy, modify, merge, publish, distribute, sublicense, 00008 // * and/or sell copies of the Software, and to permit persons to whom the 00009 // * Software is furnished to do so, subject to the following conditions: 00010 // * 00011 // * The above copyright notice and this permission notice shall be included 00012 // * in all copies or substantial portions of the Software. 00013 // * 00014 // * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 00015 // * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 00016 // * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 00017 // * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES 00018 // * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 00019 // * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 00020 // * OTHER DEALINGS IN THE SOFTWARE. 00021 // * 00022 // * Except as contained in this notice, the name of Maxim Integrated 00023 // * Products, Inc. shall not be used except as stated in the Maxim Integrated 00024 // * Products, Inc. Branding Policy. 00025 // * 00026 // * The mere transfer of this software does not imply any licenses 00027 // * of trade secrets, proprietary technology, copyrights, patents, 00028 // * trademarks, maskwork rights, or any other form of intellectual 00029 // * property whatsoever. Maxim Integrated Products, Inc. retains all 00030 // * ownership rights. 00031 // ******************************************************************************* 00032 // */ 00033 // 00034 //#include "mbed.h" 00035 //#include "MAX30001.h" 00036 //#include "pwrseq_regs.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 // xferFlag = 0; 00048 // instance = this; 00049 //} 00050 // 00051 ////****************************************************************************** 00052 //MAX30001::MAX30001(SPI *_spi) { 00053 // spi = _spi; 00054 // spi->frequency(3000000); 00055 // spi_owner = false; 00056 // functionpointer.attach(&spiHandler); 00057 // onDataAvailableCallback = NULL; 00058 // xferFlag = 0; 00059 // instance = this; 00060 //} 00061 // 00062 ////****************************************************************************** 00063 //MAX30001::~MAX30001(void) { 00064 // if (spi_owner) { 00065 // delete spi; 00066 // } 00067 //} 00068 // 00069 ////****************************************************************************** 00070 //void MAX30001::FCLK_MaximOnly(void){ 00071 // 00072 // // Use RTC crystal clock for MAX30001 FCLK 00073 ///* 00074 // mxc_pwrseq_reg0_t pwr_reg0; 00075 // mxc_pwrseq_reg4_t pwr_reg4; 00076 // 00077 // // Set the port pin connected to the MAX30001 FCLK pin as an output 00078 // GPIO_SetOutMode(MAX30001_INT_PORT_FCLK, MAX30001_INT_PIN_FCLK, MXC_E_GPIO_OUT_MODE_NORMAL); 00079 // 00080 // // Enable Real Time Clock in Run and Sleep modes 00081 // pwr_reg0 = MXC_PWRSEQ->reg0_f; 00082 // pwr_reg0.pwr_rtcen_run = 1; 00083 // pwr_reg0.pwr_rtcen_slp = 1; 00084 // MXC_PWRSEQ->reg0_f = pwr_reg0; 00085 // 00086 // // Enable the RTC clock output path on P1.7 00087 // pwr_reg4 = MXC_PWRSEQ->reg4_f; 00088 // pwr_reg4.pwr_pseq_32k_en = 1; 00089 // MXC_PWRSEQ->reg4_f = pwr_reg4; 00090 //*/ 00091 // 00092 // #define PORT_FCLK 1 00093 // #define PIN_FCLK 7 00094 // 00095 // // Set the Port pin connected to the MAX30001 FCLK pin as an output 00096 // uint32_t temp = MXC_GPIO->out_mode[PORT_FCLK]; // Port 1 00097 // 00098 // // temp = (temp & ~(0xF << (pin * 4))) | (val << (pin * 4)); 00099 // /* pin 7 */ /* NORMAL MODE */ 00100 // temp = (temp & ~(0xF << (PIN_FCLK * 4))) | (MXC_V_GPIO_OUT_MODE_NORMAL << (PIN_FCLK * 4)); 00101 // 00102 // 00103 //// temp = (temp & ~(0xF << (7 * 4))) | (5 << (7 * 4)); 00104 // 00105 // MXC_GPIO->out_mode[PORT_FCLK] = temp; 00106 // 00107 // 00108 // // Enable Real Time Clock in Run and Sleep Modes 00109 // MXC_PWRSEQ->reg0 = MXC_PWRSEQ->reg0 | MXC_F_PWRSEQ_REG0_PWR_RTCEN_RUN | MXC_F_PWRSEQ_REG0_PWR_RTCEN_SLP; 00110 // 00111 // // Enable the RTC clock output path on P1.7 00112 // MXC_PWRSEQ->reg4 = MXC_PWRSEQ->reg4 | MXC_F_PWRSEQ_REG4_PWR_PSEQ_32K_EN; 00113 // 00114 //} 00115 // 00116 // 00117 ////****************************************************************************** 00118 //int MAX30001::Rbias_FMSTR_Init(uint8_t En_rbias, uint8_t Rbiasv, 00119 // uint8_t Rbiasp, uint8_t Rbiasn, 00120 // uint8_t Fmstr) { 00121 // 00122 // max30001_cnfg_gen_t cnfg_gen; 00123 // 00124 // if (reg_read(CNFG_GEN, &cnfg_gen.all) == -1) { 00125 // return -1; 00126 // } 00127 // 00128 // cnfg_gen.bit.en_rbias = En_rbias; 00129 // cnfg_gen.bit.rbiasv = Rbiasv; 00130 // cnfg_gen.bit.rbiasp = Rbiasp; 00131 // cnfg_gen.bit.rbiasn = Rbiasn; 00132 // cnfg_gen.bit.fmstr = Fmstr; 00133 // 00134 // if (reg_write(CNFG_GEN, cnfg_gen.all) == -1) { 00135 // return -1; 00136 // } 00137 // return 0; 00138 //} 00139 // 00140 ////****************************************************************************** 00141 //int MAX30001::CAL_InitStart(uint8_t En_Vcal, uint8_t Vmode, 00142 // uint8_t Vmag, uint8_t Fcal, uint16_t Thigh, 00143 // uint8_t Fifty) { 00144 // 00145 // max30001_cnfg_cal_t cnfg_cal; 00146 // 00147 // ///< CNFG_CAL 00148 // if (reg_read(CNFG_CAL, &cnfg_cal.all) == -1) { 00149 // return -1; 00150 // } 00151 // 00152 // cnfg_cal.bit.vmode = Vmode; 00153 // cnfg_cal.bit.vmag = Vmag; 00154 // cnfg_cal.bit.fcal = Fcal; 00155 // cnfg_cal.bit.thigh = Thigh; 00156 // cnfg_cal.bit.fifty = Fifty; 00157 // 00158 // if (reg_write(CNFG_CAL, cnfg_cal.all) == -1) { 00159 // return -1; 00160 // } 00161 // 00162 // /// @brief RTOS uses a 32768HZ clock. 32768ticks represents 1secs. 1sec/10 = 00163 // /// 100msecs. 00164 // wait(1.0 / 10.0); 00165 // 00166 // if (reg_read(CNFG_CAL, &cnfg_cal.all) == -1) { 00167 // return -1; 00168 // } 00169 // 00170 // cnfg_cal.bit.en_vcal = En_Vcal; 00171 // 00172 // if (reg_write(CNFG_CAL, cnfg_cal.all) == -1) { 00173 // return -1; 00174 // } 00175 // 00176 // /// @brief RTOS uses a 32768HZ clock. 32768ticks represents 1secs. 1sec/10 = 00177 // /// 100msecs. 00178 // wait(1.0 / 10.0); 00179 // 00180 // return 0; 00181 //} 00182 // 00183 ////****************************************************************************** 00184 //int MAX30001::CAL_Stop(void) { 00185 // 00186 // max30001_cnfg_cal_t cnfg_cal; 00187 // 00188 // if (reg_read(CNFG_CAL, &cnfg_cal.all) == -1) { 00189 // return -1; 00190 // } 00191 // 00192 // cnfg_cal.bit.en_vcal = 0; // Disable VCAL, all other settings are left unaffected 00193 // 00194 // if (reg_write(CNFG_CAL, cnfg_cal.all) == -1) { 00195 // return -1; 00196 // } 00197 // 00198 // return 0; 00199 //} 00200 ////****************************************************************************** 00201 //int MAX30001::INT_assignment(max30001_intrpt_Location_t en_enint_loc, max30001_intrpt_Location_t en_eovf_loc, max30001_intrpt_Location_t en_fstint_loc, 00202 // max30001_intrpt_Location_t en_dcloffint_loc, max30001_intrpt_Location_t en_bint_loc, max30001_intrpt_Location_t en_bovf_loc, 00203 // max30001_intrpt_Location_t en_bover_loc, max30001_intrpt_Location_t en_bundr_loc, max30001_intrpt_Location_t en_bcgmon_loc, 00204 // max30001_intrpt_Location_t en_pint_loc, max30001_intrpt_Location_t en_povf_loc, max30001_intrpt_Location_t en_pedge_loc, 00205 // max30001_intrpt_Location_t en_lonint_loc, max30001_intrpt_Location_t en_rrint_loc, max30001_intrpt_Location_t en_samp_loc, 00206 // max30001_intrpt_type_t intb_Type, max30001_intrpt_type_t int2b_Type) 00207 // 00208 // 00209 //{ 00210 // 00211 // max30001_en_int_t en_int; 00212 // max30001_en_int2_t en_int2; 00213 // 00214 // ///< INT1 00215 // 00216 // if (reg_read(EN_INT, &en_int.all) == -1) { 00217 // return -1; 00218 // } 00219 // 00220 // // max30001_en_int2.bit.en_pint = 0b1; // Keep this off... 00221 // 00222 // en_int.bit.en_eint = 0b1 & en_enint_loc; 00223 // en_int.bit.en_eovf = 0b1 & en_eovf_loc; 00224 // en_int.bit.en_fstint = 0b1 & en_fstint_loc; 00225 // 00226 // en_int.bit.en_dcloffint = 0b1 & en_dcloffint_loc; 00227 // en_int.bit.en_bint = 0b1 & en_bint_loc; 00228 // en_int.bit.en_bovf = 0b1 & en_bovf_loc; 00229 // 00230 // en_int.bit.en_bover = 0b1 & en_bover_loc; 00231 // en_int.bit.en_bundr = 0b1 & en_bundr_loc; 00232 // en_int.bit.en_bcgmon = 0b1 & en_bcgmon_loc; 00233 // 00234 // en_int.bit.en_pint = 0b1 & en_pint_loc; 00235 // en_int.bit.en_povf = 0b1 & en_povf_loc; 00236 // en_int.bit.en_pedge = 0b1 & en_pedge_loc; 00237 // 00238 // en_int.bit.en_lonint = 0b1 & en_lonint_loc; 00239 // en_int.bit.en_rrint = 0b1 & en_rrint_loc; 00240 // en_int.bit.en_samp = 0b1 & en_samp_loc; 00241 // 00242 // en_int.bit.intb_type = int2b_Type; 00243 // 00244 // if (reg_write(EN_INT, en_int.all) == -1) { 00245 // return -1; 00246 // } 00247 // 00248 // ///< INT2 00249 // 00250 // if (reg_read(EN_INT2, &en_int2.all) == -1) { 00251 // return -1; 00252 // } 00253 // 00254 // en_int2.bit.en_eint = 0b1 & (en_enint_loc >> 1); 00255 // en_int2.bit.en_eovf = 0b1 & (en_eovf_loc >> 1); 00256 // en_int2.bit.en_fstint = 0b1 & (en_fstint_loc >> 1); 00257 // 00258 // en_int2.bit.en_dcloffint = 0b1 & (en_dcloffint_loc >> 1); 00259 // en_int2.bit.en_bint = 0b1 & (en_bint_loc >> 1); 00260 // en_int2.bit.en_bovf = 0b1 & (en_bovf_loc >> 1); 00261 // 00262 // en_int2.bit.en_bover = 0b1 & (en_bover_loc >> 1); 00263 // en_int2.bit.en_bundr = 0b1 & (en_bundr_loc >> 1); 00264 // en_int2.bit.en_bcgmon = 0b1 & (en_bcgmon_loc >> 1); 00265 // 00266 // en_int2.bit.en_pint = 0b1 & (en_pint_loc >> 1); 00267 // en_int2.bit.en_povf = 0b1 & (en_povf_loc >> 1); 00268 // en_int2.bit.en_pedge = 0b1 & (en_pedge_loc >> 1); 00269 // 00270 // en_int2.bit.en_lonint = 0b1 & (en_lonint_loc >> 1); 00271 // en_int2.bit.en_rrint = 0b1 & (en_rrint_loc >> 1); 00272 // en_int2.bit.en_samp = 0b1 & (en_samp_loc >> 1); 00273 // 00274 // en_int2.bit.intb_type = intb_Type; 00275 // 00276 // if (reg_write(EN_INT2, en_int2.all) == -1) { 00277 // return -1; 00278 // } 00279 // 00280 // return 0; 00281 //} 00282 // 00283 ////****************************************************************************** 00284 //int MAX30001::ECG_InitStart(uint8_t En_ecg, uint8_t Openp, 00285 // uint8_t Openn, uint8_t Pol, 00286 // uint8_t Calp_sel, uint8_t Caln_sel, 00287 // uint8_t E_fit, uint8_t Rate, uint8_t Gain, 00288 // uint8_t Dhpf, uint8_t Dlpf) { 00289 // 00290 // max30001_cnfg_emux_t cnfg_emux; 00291 // max30001_cnfg_gen_t cnfg_gen; 00292 // max30001_status_t status; 00293 // max30001_mngr_int_t mngr_int; 00294 // max30001_cnfg_ecg_t cnfg_ecg; 00295 // 00296 // ///< CNFG_EMUX 00297 // 00298 // if (reg_read(CNFG_EMUX, &cnfg_emux.all) == -1) { 00299 // return -1; 00300 // } 00301 // 00302 // cnfg_emux.bit.openp = Openp; 00303 // cnfg_emux.bit.openn = Openn; 00304 // cnfg_emux.bit.pol = Pol; 00305 // cnfg_emux.bit.calp_sel = Calp_sel; 00306 // cnfg_emux.bit.caln_sel = Caln_sel; 00307 // 00308 // if (reg_write(CNFG_EMUX, cnfg_emux.all) == -1) { 00309 // return -1; 00310 // } 00311 // 00312 // /**** ENABLE CHANNELS ****/ 00313 // ///< CNFG_GEN 00314 // 00315 // if (reg_read(CNFG_GEN, &cnfg_gen.all) == -1) { 00316 // return -1; 00317 // } 00318 // 00319 // cnfg_gen.bit.en_ecg = En_ecg; // 0b1 00320 // 00321 // ///< fmstr is default 00322 // 00323 // if (reg_write(CNFG_GEN, cnfg_gen.all) == -1) { 00324 // return -1; 00325 // } 00326 // 00327 // ///< Wait for PLL Lock & References to settle down 00328 // 00329 // max30001_timeout = 0; 00330 // 00331 // do { 00332 // if (reg_read(STATUS, &status.all) == -1) {// Wait and spin for PLL to lock... 00333 // 00334 // return -1; 00335 // } 00336 // } while (status.bit.pllint == 1 && max30001_timeout++ <= 1000); 00337 // 00338 // ///< MNGR_INT 00339 // 00340 // if (reg_read(MNGR_INT, &mngr_int.all) == -1) { 00341 // return -1; 00342 // } 00343 // 00344 // mngr_int.bit.e_fit = E_fit; // 31 00345 // 00346 // if (reg_write(MNGR_INT, mngr_int.all) == -1) { 00347 // return -1; 00348 // } 00349 // 00350 // ///< CNFG_ECG 00351 // 00352 // if (reg_read(CNFG_ECG, &cnfg_ecg.all) == -1) { 00353 // return -1; 00354 // } 00355 // 00356 // cnfg_ecg.bit.rate = Rate; 00357 // cnfg_ecg.bit.gain = Gain; 00358 // cnfg_ecg.bit.dhpf = Dhpf; 00359 // cnfg_ecg.bit.dlpf = Dlpf; 00360 // 00361 // if (reg_write(CNFG_ECG, cnfg_ecg.all) == -1) { 00362 // return -1; 00363 // } 00364 // 00365 // return 0; 00366 //} 00367 // 00368 ////****************************************************************************** 00369 //int MAX30001::ECGFast_Init(uint8_t Clr_Fast, uint8_t Fast, uint8_t Fast_Th) { 00370 // 00371 // max30001_mngr_int_t mngr_int; 00372 // max30001_mngr_dyn_t mngr_dyn; 00373 // 00374 // if (reg_read(MNGR_INT, &mngr_int.all) == -1) { 00375 // return -1; 00376 // } 00377 // 00378 // mngr_int.bit.clr_fast = Clr_Fast; 00379 // 00380 // if (reg_write(MNGR_INT, mngr_int.all) == -1) { 00381 // return -1; 00382 // } 00383 // 00384 // if (reg_read(MNGR_DYN, &mngr_dyn.all) == -1) { 00385 // return -1; 00386 // } 00387 // 00388 // mngr_dyn.bit.fast = Fast; 00389 // mngr_dyn.bit.fast_th = Fast_Th; 00390 // 00391 // if (reg_write(MNGR_INT, mngr_dyn.all) == -1) { 00392 // return -1; 00393 // } 00394 // 00395 // return 0; 00396 //} 00397 // 00398 ////****************************************************************************** 00399 //int MAX30001::Stop_ECG(void) { 00400 // 00401 // max30001_cnfg_gen_t cnfg_gen; 00402 // 00403 // if (reg_read(CNFG_GEN, &cnfg_gen.all) == -1) { 00404 // return -1; 00405 // } 00406 // 00407 // cnfg_gen.bit.en_ecg = 0; ///< Stop ECG 00408 // 00409 // ///< fmstr is default 00410 // 00411 // if (reg_write(CNFG_GEN, cnfg_gen.all) == -1) { 00412 // return -1; 00413 // } 00414 // 00415 // return 0; 00416 //} 00417 // 00418 ////****************************************************************************** 00419 //int MAX30001::PACE_InitStart(uint8_t En_pace, uint8_t Clr_pedge, 00420 // uint8_t Pol, uint8_t Gn_diff_off, 00421 // uint8_t Gain, uint8_t Aout_lbw, 00422 // uint8_t Aout, uint8_t Dacp, 00423 // uint8_t Dacn) { 00424 // 00425 // /**** SET MASTER FREQUENCY, ENABLE CHANNELS ****/ 00426 // 00427 // max30001_cnfg_gen_t cnfg_gen; 00428 // max30001_status_t status; 00429 // max30001_mngr_int_t mngr_int; 00430 // max30001_cnfg_pace_t cnfg_pace; 00431 // 00432 // ///< CNFG_GEN 00433 // 00434 // if (reg_read(CNFG_GEN, &cnfg_gen.all) == -1) { 00435 // return -1; 00436 // } 00437 // 00438 // cnfg_gen.bit.en_pace = En_pace; // 0b1; 00439 // 00440 // if (reg_write(CNFG_GEN, cnfg_gen.all) == -1) { 00441 // return -1; 00442 // } 00443 // 00444 // /**** Wait for PLL Lock & References to settle down ****/ 00445 // max30001_timeout = 0; 00446 // 00447 // do { 00448 // if (reg_read(STATUS, &status.all) == 00449 // -1) // Wait and spin for PLL to lock... 00450 // { 00451 // return -1; 00452 // } 00453 // 00454 // } while (status.bit.pllint == 1 && max30001_timeout++ <= 1000); 00455 // 00456 // ///< MNGR_INT 00457 // 00458 // if (reg_read(MNGR_INT, &mngr_int.all) == -1) { 00459 // return -1; 00460 // } 00461 // 00462 // mngr_int.bit.clr_pedge = Clr_pedge; // 0b0; 00463 // 00464 // if (reg_write(MNGR_INT, mngr_int.all) == -1) { 00465 // return -1; 00466 // } 00467 // 00468 // ///< CNFG_PACE 00469 // 00470 // reg_read(CNFG_PACE, &cnfg_pace.all); 00471 // 00472 // cnfg_pace.bit.pol = Pol; 00473 // cnfg_pace.bit.gn_diff_off = Gn_diff_off; 00474 // cnfg_pace.bit.gain = Gain; 00475 // cnfg_pace.bit.aout_lbw = Aout_lbw; 00476 // cnfg_pace.bit.aout = Aout; 00477 // cnfg_pace.bit.dacp = Dacp; 00478 // cnfg_pace.bit.dacn = Dacn; 00479 // 00480 // reg_write(CNFG_PACE, cnfg_pace.all); 00481 // 00482 // return 0; 00483 //} 00484 // 00485 ////****************************************************************************** 00486 //int MAX30001::Stop_PACE(void) { 00487 // 00488 // max30001_cnfg_gen_t cnfg_gen; 00489 // 00490 // if (reg_read(CNFG_GEN, &cnfg_gen.all) == -1) { 00491 // return -1; 00492 // } 00493 // 00494 // cnfg_gen.bit.en_pace = 0; ///< Stop PACE 00495 // 00496 // if (reg_write(CNFG_GEN, cnfg_gen.all) == -1) { 00497 // return -1; 00498 // } 00499 // 00500 // return 0; 00501 //} 00502 // 00503 ////****************************************************************************** 00504 //int MAX30001::BIOZ_InitStart( 00505 // uint8_t En_bioz, uint8_t Openp, uint8_t Openn, uint8_t Calp_sel, 00506 // uint8_t Caln_sel, uint8_t CG_mode, uint8_t B_fit, uint8_t Rate, 00507 // uint8_t Ahpf, uint8_t Ext_rbias, uint8_t Gain, uint8_t Dhpf, uint8_t Dlpf, 00508 // uint8_t Fcgen, uint8_t Cgmon, uint8_t Cgmag, uint8_t Phoff) { 00509 // 00510 // max30001_cnfg_bmux_t cnfg_bmux; 00511 // max30001_cnfg_gen_t cnfg_gen; 00512 // max30001_status_t status; 00513 // max30001_mngr_int_t mngr_int; 00514 // max30001_cnfg_bioz_t cnfg_bioz; 00515 // 00516 // 00517 // // CNFG_BMUX 00518 // 00519 // if (reg_read(CNFG_BMUX, &cnfg_bmux.all) == -1) { 00520 // return -1; 00521 // } 00522 // 00523 // cnfg_bmux.bit.openp = Openp; 00524 // cnfg_bmux.bit.openn = Openn; 00525 // cnfg_bmux.bit.calp_sel = Calp_sel; 00526 // cnfg_bmux.bit.caln_sel = Caln_sel; 00527 // cnfg_bmux.bit.cg_mode = CG_mode; 00528 // 00529 // if (reg_write(CNFG_BMUX, cnfg_bmux.all) == -1) { 00530 // return -1; 00531 // } 00532 // 00533 // /**** SET MASTER FREQUENCY, ENABLE CHANNELS ****/ 00534 // 00535 // ///< CNFG_GEN 00536 // 00537 // if (reg_read(CNFG_GEN, &cnfg_gen.all) == -1) { 00538 // return -1; 00539 // } 00540 // 00541 // cnfg_gen.bit.en_bioz = En_bioz; 00542 // 00543 // ///< fmstr is default 00544 // 00545 // if (reg_write(CNFG_GEN, cnfg_gen.all) == -1) { 00546 // return -1; 00547 // } 00548 // 00549 // /**** Wait for PLL Lock & References to settle down ****/ 00550 // 00551 // max30001_timeout = 0; 00552 // 00553 // do { 00554 // if (reg_read(STATUS, &status.all) == -1) { // Wait and spin for PLL to lock... 00555 // return -1; 00556 // } 00557 // 00558 // } while (status.bit.pllint == 1 && max30001_timeout++ <= 1000); 00559 // 00560 // /**** Start of CNFG_BIOZ ****/ 00561 // 00562 // ///< MNGR_INT 00563 // 00564 // if (reg_read(MNGR_INT, &mngr_int.all) == -1) { 00565 // return -1; 00566 // } 00567 // 00568 // mngr_int.bit.b_fit = B_fit; //; 00569 // 00570 // if (reg_write(MNGR_INT, mngr_int.all) == -1) { 00571 // return -1; 00572 // } 00573 // 00574 // ///< CNFG_BIOZ 00575 // 00576 // if (reg_read(CNFG_BIOZ, &cnfg_bioz.all) == -1) { 00577 // return -1; 00578 // } 00579 // 00580 // cnfg_bioz.bit.rate = Rate; 00581 // cnfg_bioz.bit.ahpf = Ahpf; 00582 // cnfg_bioz.bit.ext_rbias = Ext_rbias; 00583 // cnfg_bioz.bit.gain = Gain; 00584 // cnfg_bioz.bit.dhpf = Dhpf; 00585 // cnfg_bioz.bit.dlpf = Dlpf; 00586 // cnfg_bioz.bit.fcgen = Fcgen; 00587 // cnfg_bioz.bit.cgmon = Cgmon; 00588 // cnfg_bioz.bit.cgmag = Cgmag; 00589 // cnfg_bioz.bit.phoff = Phoff; 00590 // 00591 // if (reg_write(CNFG_BIOZ, cnfg_bioz.all) == -1) { 00592 // return -1; 00593 // } 00594 // 00595 // return 0; 00596 //} 00597 // 00598 ////****************************************************************************** 00599 //int MAX30001::Stop_BIOZ(void) { 00600 // 00601 // max30001_cnfg_gen_t cnfg_gen; 00602 // 00603 // ///< CNFG_GEN 00604 // 00605 // if (reg_read(CNFG_GEN, &cnfg_gen.all) == -1) { 00606 // return -1; 00607 // } 00608 // 00609 // cnfg_gen.bit.en_bioz = 0; // Stop BIOZ 00610 // 00611 // if (reg_write(CNFG_GEN, cnfg_gen.all) == -1) { 00612 // return -1; 00613 // } 00614 // 00615 // return 0; 00616 //} 00617 // 00618 ////****************************************************************************** 00619 //int MAX30001::BIOZ_InitBist(uint8_t En_bist, uint8_t Rnom, 00620 // uint8_t Rmod, uint8_t Fbist) { 00621 // 00622 // max30001_cnfg_bmux_t cnfg_bmux; 00623 // 00624 // ///< CNFG_BMUX 00625 // 00626 // if (reg_read(CNFG_BMUX, &cnfg_bmux.all) == -1) { 00627 // return -1; 00628 // } 00629 // 00630 // cnfg_bmux.bit.en_bist = En_bist; 00631 // cnfg_bmux.bit.rnom = Rnom; 00632 // cnfg_bmux.bit.rmod = Rmod; 00633 // cnfg_bmux.bit.fbist = Fbist; 00634 // 00635 // if (reg_write(CNFG_BMUX, cnfg_bmux.all) == -1) { 00636 // return -1; 00637 // } 00638 // 00639 // return 0; 00640 //} 00641 ////****************************************************************************** 00642 //int MAX30001::RtoR_InitStart(uint8_t En_rtor, uint8_t Wndw, 00643 // uint8_t Gain, uint8_t Pavg, uint8_t Ptsf, 00644 // uint8_t Hoff, uint8_t Ravg, uint8_t Rhsf, 00645 // uint8_t Clr_rrint) { 00646 // 00647 // max30001_mngr_int_t mngr_int; 00648 // max30001_cnfg_rtor1_t cnfg_rtor1; 00649 // max30001_cnfg_rtor2_t cnfg_rtor2; 00650 // 00651 // ///< MNGR_INT 00652 // if (reg_read(MNGR_INT, &mngr_int.all) == -1) { 00653 // return -1; 00654 // } 00655 // 00656 // mngr_int.bit.clr_rrint = Clr_rrint; 00657 // ///< 0b01 & 0b00 are for interrupt mode... 00658 // ///< 0b10 is for monitoring mode... it just overwrites the data... 00659 // 00660 // if (reg_write(MNGR_INT, mngr_int.all) == -1) { 00661 // return -1; 00662 // } 00663 // 00664 // ///< RTOR1 00665 // if (reg_read(CNFG_RTOR1, &cnfg_rtor1.all) == -1) { 00666 // return -1; 00667 // } 00668 // 00669 // cnfg_rtor1.bit.wndw = Wndw; 00670 // cnfg_rtor1.bit.gain = Gain; 00671 // cnfg_rtor1.bit.en_rtor = En_rtor; 00672 // cnfg_rtor1.bit.pavg = Pavg; 00673 // cnfg_rtor1.bit.ptsf = Ptsf; 00674 // 00675 // if (reg_write(CNFG_RTOR1, cnfg_rtor1.all) == -1) { 00676 // return -1; 00677 // } 00678 // 00679 // ///< RTOR2 00680 // if (reg_read(CNFG_RTOR2, &cnfg_rtor2.all) == -1) { 00681 // return -1; 00682 // } 00683 // cnfg_rtor2.bit.hoff = Hoff; 00684 // cnfg_rtor2.bit.ravg = Ravg; 00685 // cnfg_rtor2.bit.rhsf = Rhsf; 00686 // 00687 // if (reg_write(CNFG_RTOR2, cnfg_rtor2.all) == -1) { 00688 // return -1; 00689 // } 00690 // 00691 // return 0; 00692 //} 00693 // 00694 ////****************************************************************************** 00695 //int MAX30001::Stop_RtoR(void) { 00696 // 00697 // max30001_cnfg_rtor1_t cnfg_rtor1; 00698 // 00699 // if (reg_read(CNFG_RTOR1, &cnfg_rtor1.all) == -1) { 00700 // return -1; 00701 // } 00702 // 00703 // cnfg_rtor1.bit.en_rtor = 0; ///< Stop RtoR 00704 // 00705 // if (reg_write(CNFG_RTOR1, cnfg_rtor1.all) == -1) { 00706 // return -1; 00707 // } 00708 // 00709 // return 0; 00710 //} 00711 // 00712 ////****************************************************************************** 00713 //int MAX30001::PLL_lock(void) { 00714 // ///< Spin to see PLLint become zero to indicate a lock. 00715 // 00716 // max30001_status_t status; 00717 // 00718 // max30001_timeout = 0; 00719 // 00720 // do { 00721 // if (reg_read(STATUS, &status.all) == -1) { ///< Wait and spin for PLL to lock... 00722 // 00723 // return -1; 00724 // } 00725 // 00726 // } while (status.bit.pllint == 1 && max30001_timeout++ <= 1000); 00727 // 00728 // return 0; 00729 //} 00730 // 00731 ////****************************************************************************** 00732 //int MAX30001::sw_rst(void) { 00733 // ///< SW reset for the MAX30001 chip 00734 // 00735 // if (reg_write(SW_RST, 0x000000) == -1) { 00736 // return -1; 00737 // } 00738 // 00739 // return 0; 00740 //} 00741 // 00742 ////****************************************************************************** 00743 //int MAX30001::synch(void) { ///< For synchronization 00744 // if (reg_write(SYNCH, 0x000000) == -1) { 00745 // return -1; 00746 // } 00747 // return 0; 00748 //} 00749 // 00750 ////****************************************************************************** 00751 //int MAX30001::fifo_rst(void) { ///< Resets the FIFO 00752 // if (reg_write(FIFO_RST, 0x000000) == -1) { 00753 // return -1; 00754 // } 00755 // return 0; 00756 //} 00757 // 00758 ////****************************************************************************** 00759 //int MAX30001::reg_write(MAX30001_REG_map_t addr, uint32_t data) { 00760 // 00761 // uint8_t result[4]; 00762 // uint8_t data_array[4]; 00763 // int32_t success = 0; 00764 // 00765 // data_array[0] = (addr << 1) & 0xff; 00766 // 00767 // data_array[3] = data & 0xff; 00768 // data_array[2] = (data >> 8) & 0xff; 00769 // data_array[1] = (data >> 16) & 0xff; 00770 // 00771 // success = SPI_Transmit(&data_array[0], 4, &result[0], 4); 00772 // 00773 // if (success != 0) { 00774 // return -1; 00775 // } else { 00776 // return 0; 00777 // } 00778 //} 00779 // 00780 ////****************************************************************************** 00781 //int MAX30001::reg_read(MAX30001_REG_map_t addr, 00782 // uint32_t *return_data) { 00783 // uint8_t result[4]; 00784 // uint8_t data_array[1]; 00785 // int32_t success = 0; 00786 // 00787 // data_array[0] = ((addr << 1) & 0xff) | 1; // For Read, Or with 1 00788 // success = SPI_Transmit(&data_array[0], 1, &result[0], 4); 00789 // *return_data = /*result[0] + */ (uint32_t)(result[1] << 16) + 00790 // (result[2] << 8) + result[3]; 00791 // if (success != 0) { 00792 // return -1; 00793 // } else { 00794 // return 0; 00795 // } 00796 //} 00797 // 00798 ////****************************************************************************** 00799 //int MAX30001::Enable_DcLeadOFF_Init(int8_t En_dcloff, int8_t Ipol, 00800 // int8_t Imag, int8_t Vth) { 00801 // ///< the leads are not touching the body 00802 // 00803 // max30001_cnfg_gen_t cnfg_gen; 00804 // 00805 // ///< CNFG_EMUX, Set ECGP and ECGN for external hook up... 00806 // 00807 // if (reg_read(CNFG_GEN, &cnfg_gen.all) == -1) { 00808 // return -1; 00809 // } 00810 // 00811 // cnfg_gen.bit.en_dcloff = En_dcloff; 00812 // cnfg_gen.bit.ipol = Ipol; 00813 // cnfg_gen.bit.imag = Imag; 00814 // cnfg_gen.bit.vth = Vth; 00815 // 00816 // if (reg_write(CNFG_GEN, cnfg_gen.all) == -1) { 00817 // return -1; 00818 // } 00819 // 00820 // return 0; 00821 //} 00822 // 00823 ////****************************************************************************** 00824 //int MAX30001::Disable_DcLeadOFF(void) { 00825 // 00826 // max30001_cnfg_gen_t cnfg_gen; 00827 // 00828 // ///< CNFG_GEN 00829 // if (reg_read(CNFG_GEN, &cnfg_gen.all) == -1) { 00830 // return -1; 00831 // } 00832 // 00833 // cnfg_gen.bit.en_dcloff = 0; // Turned off the dc lead off. 00834 // 00835 // if (reg_write(CNFG_GEN, cnfg_gen.all) == -1) { 00836 // return -1; 00837 // } 00838 // 00839 // return 0; 00840 //} 00841 // 00842 ////****************************************************************************** 00843 //int MAX30001::BIOZ_Enable_ACLeadOFF_Init(uint8_t En_bloff, uint8_t Bloff_hi_it, 00844 // uint8_t Bloff_lo_it) { 00845 // 00846 // max30001_cnfg_gen_t cnfg_gen; 00847 // max30001_mngr_dyn_t mngr_dyn; 00848 // 00849 // ///< CNFG_GEN 00850 // if (reg_read(CNFG_GEN, &cnfg_gen.all) == -1) { 00851 // return -1; 00852 // } 00853 // 00854 // cnfg_gen.bit.en_bloff = En_bloff; 00855 // 00856 // if (reg_write(CNFG_GEN, cnfg_gen.all) == -1) { 00857 // return -1; 00858 // } 00859 // 00860 // ///< MNGR_DYN 00861 // if (reg_read(MNGR_DYN, &mngr_dyn.all) == -1) { 00862 // return -1; 00863 // } 00864 // 00865 // mngr_dyn.bit.bloff_hi_it = Bloff_hi_it; 00866 // mngr_dyn.bit.bloff_lo_it = Bloff_lo_it; 00867 // 00868 // if (reg_write(MNGR_DYN, mngr_dyn.all) == -1) { 00869 // return -1; 00870 // } 00871 // 00872 // return 0; 00873 //} 00874 // 00875 ////****************************************************************************** 00876 //int MAX30001::BIOZ_Disable_ACleadOFF(void) { 00877 // 00878 // max30001_cnfg_gen_t cnfg_gen; 00879 // 00880 // ///< CNFG_GEN 00881 // if (reg_read(CNFG_GEN, &cnfg_gen.all) == -1) { 00882 // return -1; 00883 // } 00884 // 00885 // cnfg_gen.bit.en_bloff = 0b0; // Turns of the BIOZ AC Lead OFF feature 00886 // 00887 // if (reg_write(CNFG_GEN, cnfg_gen.all) == -1) { 00888 // return -1; 00889 // } 00890 // 00891 // return 0; 00892 //} 00893 // 00894 ////****************************************************************************** 00895 //int MAX30001::BIOZ_Enable_BCGMON(void) { 00896 // 00897 // max30001_cnfg_bioz_t cnfg_bioz; 00898 // 00899 // ///< CNFG_BIOZ 00900 // if (reg_read(CNFG_BIOZ, &cnfg_bioz.all) == -1) { 00901 // return -1; 00902 // } 00903 // 00904 // cnfg_bioz.bit.cgmon = 1; 00905 // 00906 // if (reg_write(CNFG_BIOZ, cnfg_bioz.all) == -1) { 00907 // return -1; 00908 // } 00909 // 00910 // return 0; 00911 //} 00912 // 00913 // 00914 ////****************************************************************************** 00915 //int MAX30001::Enable_LeadON(int8_t Channel) // Channel: ECG = 0b01, BIOZ = 0b10, Disable = 0b00 00916 //{ 00917 // 00918 // max30001_cnfg_gen_t cnfg_gen; 00919 // 00920 // ///< CNFG_GEN 00921 // if (reg_read(CNFG_GEN, &cnfg_gen.all) == -1) { 00922 // return -1; 00923 // } 00924 // 00925 // cnfg_gen.bit.en_ecg = 0b0; 00926 // cnfg_gen.bit.en_bioz = 0b0; 00927 // cnfg_gen.bit.en_pace = 0b0; 00928 // 00929 // cnfg_gen.bit.en_ulp_lon = Channel; ///< BIOZ ULP lead on detection... 00930 // 00931 // if (reg_write(CNFG_GEN, cnfg_gen.all) == -1) { 00932 // return -1; 00933 // } 00934 // 00935 // return 0; 00936 //} 00937 // 00938 ////****************************************************************************** 00939 //int MAX30001::Disable_LeadON(void) { 00940 // 00941 // max30001_cnfg_gen_t cnfg_gen; 00942 // ///< CNFG_GEN 00943 // if (reg_read(CNFG_GEN, &cnfg_gen.all) == -1) { 00944 // return -1; 00945 // } 00946 // 00947 // cnfg_gen.bit.en_ulp_lon = 0b0; 00948 // 00949 // if (reg_write(CNFG_GEN, cnfg_gen.all) == -1) { 00950 // return -1; 00951 // } 00952 // 00953 // return 0; 00954 //} 00955 // 00956 ////****************************************************************************** 00957 //#define LEADOFF_SERVICE_TIME 0x2000 ///< 0x1000 = 1 second 00958 //#define LEADOFF_NUMSTATES 2 00959 //uint32_t leadoffState = 0; 00960 //uint32_t max30001_LeadOffoldTime = 0; 00961 //void MAX30001::ServiceLeadoff(uint32_t currentTime) { 00962 // 00963 // uint32_t delta_Time; 00964 // 00965 // delta_Time = currentTime - max30001_LeadOffoldTime; 00966 // 00967 // if (delta_Time > LEADOFF_SERVICE_TIME) { 00968 // switch (leadoffState) { 00969 // case 0: ///< switch to ECG DC Lead OFF 00970 // Enable_DcLeadOFF_Init(0b01, 0b0, 0b001, 0b00); 00971 // break; 00972 // 00973 // case 1: ///< switch to BIOZ DC Lead OFF 00974 // Enable_DcLeadOFF_Init(0b10, 0b0, 0b001, 0b00); 00975 // break; 00976 // } 00977 // 00978 // leadoffState++; 00979 // leadoffState %= LEADOFF_NUMSTATES; 00980 // 00981 // max30001_LeadOffoldTime = currentTime; 00982 // } 00983 //} 00984 ////****************************************************************************** 00985 //#define LEADON_SERVICE_TIME 0x2000 // 0x1000 = 1 second 00986 //#define LEADON_NUMSTATES 2 00987 //uint32_t leadOnState = 0; 00988 //uint32_t max30001_LeadOnoldTime = 0; 00989 //void MAX30001::ServiceLeadON(uint32_t currentTime) { 00990 // 00991 // uint32_t delta_Time; 00992 // 00993 // delta_Time = currentTime - max30001_LeadOnoldTime; 00994 // 00995 // if (delta_Time > LEADON_SERVICE_TIME) { 00996 // switch (leadOnState) { 00997 // case 0: ///< switch to ECG DC Lead ON 00998 // Enable_LeadON(0b01); 00999 // break; 01000 // 01001 // case 1: ///< switch to BIOZ DC Lead ON 01002 // Enable_LeadON(0b10); 01003 // break; 01004 // } 01005 // 01006 // leadOnState++; 01007 // leadOnState %= LEADON_NUMSTATES; 01008 // 01009 // max30001_LeadOnoldTime = currentTime; 01010 // } 01011 //} 01012 // 01013 ////****************************************************************************** 01014 //int MAX30001::FIFO_LeadONOff_Read(void) { 01015 // 01016 // uint8_t result[32 * 3]; ///< 32words - 3bytes each 01017 // uint8_t data_array[4]; 01018 // int32_t success = 0; 01019 // int i, j; 01020 // 01021 // uint32_t total_databytes; 01022 // uint8_t i_index; 01023 // uint8_t data_chunk; 01024 // uint8_t loop_logic; 01025 // 01026 // uint8_t etag, ptag, btag; 01027 // 01028 // uint8_t adr; 01029 // 01030 // int8_t ReadAllPaceOnce; 01031 // 01032 // static uint8_t dcloffint_OneShot = 0; 01033 // static uint8_t acloffint_OneShot = 0; 01034 // static uint8_t bcgmon_OneShot = 0; 01035 // static uint8_t acleadon_OneShot = 0; 01036 // 01037 // max30001_mngr_int_t mngr_int; 01038 // max30001_cnfg_gen_t cnfg_gen; 01039 // 01040 // int8_t ret_val; 01041 // 01042 // etag = 0; 01043 // if (global_status.bit.eint == 1 || global_status.bit.pint == 1) { 01044 // adr = ECG_FIFO_BURST; 01045 // data_array[0] = ((adr << 1) & 0xff) | 1; 01046 // 01047 // ///< The SPI routine only sends out data of 32 bytes in size. Therefore the 01048 // ///< data is being read in 01049 // ///< smaller chunks in this routine... 01050 // 01051 // ///< READ mngr_int AND cnfg_gen; 01052 // 01053 // if (reg_read(MNGR_INT, &mngr_int.all) == -1) { 01054 // return -1; 01055 // } 01056 // 01057 // if (reg_read(CNFG_GEN, &cnfg_gen.all) == -1) { 01058 // return -1; 01059 // } 01060 // 01061 // total_databytes = (mngr_int.bit.e_fit + 1) * 3; 01062 // 01063 // i_index = 0; 01064 // loop_logic = 1; 01065 // 01066 // while (loop_logic) { 01067 // if (total_databytes > 30) { 01068 // data_chunk = 30; 01069 // total_databytes = total_databytes - 30; 01070 // } else { 01071 // data_chunk = total_databytes; 01072 // loop_logic = 0; 01073 // } 01074 // 01075 // ///< The extra 1 byte is for the extra byte that comes out of the SPI 01076 // success = SPI_Transmit(&data_array[0], 1, &result[i_index], (data_chunk + 1)); // Make a copy of the FIFO over here... 01077 // 01078 // if (success != 0) { 01079 // return -1; 01080 // } 01081 // 01082 // ///< This is important, because every transaction above creates an empty 01083 // ///< redundant data at result[0] 01084 // for (j = i_index; j < (data_chunk + i_index); j++) /* get rid of the 1 extra byte by moving the whole array up one */ 01085 // { 01086 // result[j] = result[j + 1]; 01087 // } 01088 // 01089 // i_index = i_index + 30; /* point to the next array location to put the data in */ 01090 // } 01091 // 01092 // ReadAllPaceOnce = 0; 01093 // 01094 // ///< Put the content of the FIFO based on the EFIT value, We ignore the 01095 // ///< result[0] and start concatenating indexes: 1,2,3 - 4,5,6 - 7,8,9 - 01096 // for (i = 0, j = 0; i < mngr_int.bit.e_fit + 1; i++, j = j + 3) ///< index1=23-16 bit, index2=15-8 bit, index3=7-0 bit 01097 // { 01098 // max30001_ECG_FIFO_buffer[i] = ((uint32_t)result[j] << 16) + (result[j + 1] << 8) + result[j + 2]; 01099 // 01100 // etag = (0b00111000 & result[j + 2]) >> 3; 01101 // ptag = 0b00000111 & result[j + 2]; 01102 // 01103 // if (ptag != 0b111 && ReadAllPaceOnce == 0) { 01104 // 01105 // ReadAllPaceOnce = 1; ///< This will prevent extra read of PACE, once group 01106 // ///< 0-5 is read ONCE. 01107 // 01108 // adr = PACE0_FIFO_BURST; 01109 // 01110 // data_array[0] = ((adr << 1) & 0xff) | 1; ///< For Read Or with 1 01111 // 01112 // success = SPI_Transmit(&data_array[0], 1, &result[0], 10); 01113 // 01114 // max30001_PACE[0] = (uint32_t)(result[1] << 16) + (result[2] << 8) + result[3]; 01115 // max30001_PACE[1] = (uint32_t)(result[4] << 16) + (result[5] << 8) + result[6]; 01116 // max30001_PACE[2] = (uint32_t)(result[7] << 16) + (result[8] << 8) + result[9]; 01117 // 01118 // adr = PACE1_FIFO_BURST; 01119 // 01120 // data_array[0] = ((adr << 1) & 0xff) | 1; ///< For Read Or with 1 01121 // 01122 // success = SPI_Transmit(&data_array[0], 1, &result[0], 10); 01123 // 01124 // max30001_PACE[3] = (uint32_t)(result[1] << 16) + (result[2] << 8) + result[3]; 01125 // max30001_PACE[4] = (uint32_t)(result[4] << 16) + (result[5] << 8) + result[6]; 01126 // max30001_PACE[5] = (uint32_t)(result[7] << 16) + (result[8] << 8) + result[9]; 01127 // 01128 // adr = PACE2_FIFO_BURST; 01129 // 01130 // data_array[0] = ((adr << 1) & 0xff) | 1; ///< For Read Or with 1 01131 // 01132 // success = SPI_Transmit(&data_array[0], 1, &result[0], 10); 01133 // 01134 // max30001_PACE[6] = (uint32_t)(result[1] << 16) + (result[2] << 8) + result[3]; 01135 // max30001_PACE[7] = (uint32_t)(result[4] << 16) + (result[5] << 8) + result[6]; 01136 // max30001_PACE[8] = (uint32_t)(result[7] << 16) + (result[8] << 8) + result[9]; 01137 // 01138 // adr = PACE3_FIFO_BURST; 01139 // 01140 // data_array[0] = ((adr << 1) & 0xff) | 1; ///< For Read Or with 1 01141 // 01142 // success = SPI_Transmit(&data_array[0], 1, &result[0], 10); 01143 // 01144 // max30001_PACE[9] = (uint32_t)(result[1] << 16) + (result[2] << 8) + result[3]; 01145 // max30001_PACE[10] = (uint32_t)(result[4] << 16) + (result[5] << 8) + result[6]; 01146 // max30001_PACE[11] = (uint32_t)(result[7] << 16) + (result[8] << 8) + result[9]; 01147 // 01148 // adr = PACE4_FIFO_BURST; 01149 // 01150 // data_array[0] = ((adr << 1) & 0xff) | 1; ///< For Read Or with 1 01151 // 01152 // success = SPI_Transmit(&data_array[0], 1, &result[0], 10); 01153 // 01154 // max30001_PACE[12] = (uint32_t)(result[1] << 16) + (result[2] << 8) + result[3]; 01155 // max30001_PACE[13] = (uint32_t)(result[4] << 16) + (result[5] << 8) + result[6]; 01156 // max30001_PACE[14] = (uint32_t)(result[7] << 16) + (result[8] << 8) + result[9]; 01157 // 01158 // adr = PACE5_FIFO_BURST; 01159 // 01160 // data_array[0] = ((adr << 1) & 0xff) | 1; ///< For Read Or with 1 01161 // 01162 // success = SPI_Transmit(&data_array[0], 1, &result[0], 10); 01163 // 01164 // max30001_PACE[15] = (uint32_t)(result[1] << 16) + (result[2] << 8) + result[3]; 01165 // max30001_PACE[16] = (uint32_t)(result[4] << 16) + (result[5] << 8) + result[6]; 01166 // max30001_PACE[17] = (uint32_t)(result[7] << 16) + (result[8] << 8) + result[9]; 01167 // 01168 // dataAvailable(MAX30001_DATA_PACE, max30001_PACE, 18); ///< Send out the Pace data once only 01169 // } 01170 // } 01171 // 01172 // if (etag != 0b110) { 01173 // 01174 // dataAvailable(MAX30001_DATA_ECG, max30001_ECG_FIFO_buffer, (mngr_int.bit.e_fit + 1)); 01175 // } 01176 // 01177 // } /* End of ECG init */ 01178 // 01179 // /* RtoR */ 01180 // 01181 // if (global_status.bit.rrint == 1) { 01182 // if (reg_read(RTOR, &max30001_RtoR_data) == -1) { 01183 // return -1; 01184 // } 01185 // 01186 // max30001_RtoR_data = (0x00FFFFFF & max30001_RtoR_data) >> 10; 01187 // 01188 // hspValMax30001.R2R = (uint16_t)max30001_RtoR_data; 01189 // hspValMax30001.fmstr = (uint16_t)cnfg_gen.bit.fmstr; 01190 // 01191 // dataAvailable(MAX30001_DATA_RTOR, &max30001_RtoR_data, 1); 01192 // } 01193 // 01194 // ///< Handling BIOZ data... 01195 // 01196 // if (global_status.bit.bint == 1) { 01197 // adr = 0x22; 01198 // data_array[0] = ((adr << 1) & 0xff) | 1; 01199 // 01200 // ///< [(BFIT+1)*3byte]+1extra byte due to the addr 01201 // 01202 // if (SPI_Transmit(&data_array[0], 1, &result[0],((mngr_int.bit.b_fit + 1) * 3) + 1) == -1) { ///< Make a copy of the FIFO over here... 01203 // return -1; 01204 // } 01205 // 01206 // btag = 0b00000111 & result[3]; 01207 // 01208 // ///< Put the content of the FIFO based on the BFIT value, We ignore the 01209 // ///< result[0] and start concatenating indexes: 1,2,3 - 4,5,6 - 7,8,9 - 01210 // for (i = 0, j = 0; i < mngr_int.bit.b_fit + 1; i++, j = j + 3) ///< index1=23-16 bit, index2=15-8 bit, index3=7-0 bit 01211 // { 01212 // max30001_BIOZ_FIFO_buffer[i] = ((uint32_t)result[j + 1] << 16) + (result[j + 2] << 8) + result[j + 3]; 01213 // } 01214 // 01215 // if (btag != 0b110) { 01216 // dataAvailable(MAX30001_DATA_BIOZ, max30001_BIOZ_FIFO_buffer, 8); 01217 // } 01218 // } 01219 // 01220 // ret_val = 0; 01221 // 01222 // if (global_status.bit.dcloffint == 1) { ///< ECG/BIOZ Lead Off 01223 // dcloffint_OneShot = 1; 01224 // max30001_DCLeadOff = 0; 01225 // max30001_DCLeadOff = max30001_DCLeadOff | (cnfg_gen.bit.en_dcloff << 8) | (global_status.all & 0x00000F); 01226 // dataAvailable(MAX30001_DATA_LEADOFF_DC, &max30001_DCLeadOff, 1); 01227 // ///< Do a FIFO Reset 01228 // reg_write(FIFO_RST, 0x000000); 01229 // 01230 // ret_val = 0b100; 01231 // 01232 // } else if (dcloffint_OneShot == 1 && global_status.bit.dcloffint == 0) { ///< Just send once when it comes out of dc lead off 01233 // max30001_DCLeadOff = 0; 01234 // max30001_DCLeadOff = max30001_DCLeadOff | (cnfg_gen.bit.en_dcloff << 8) | (global_status.all & 0x00000F); 01235 // dataAvailable(MAX30001_DATA_LEADOFF_DC, &max30001_DCLeadOff, 1); 01236 // dcloffint_OneShot = 0; 01237 // } 01238 // 01239 // if (global_status.bit.bover == 1 || global_status.bit.bundr == 1) { ///< BIOZ AC Lead Off 01240 // acloffint_OneShot = 1; 01241 // max30001_ACLeadOff = 0; 01242 // max30001_ACLeadOff = 01243 // max30001_ACLeadOff | ((global_status.all & 0x030000) >> 16); 01244 // dataAvailable(MAX30001_DATA_LEADOFF_AC, &max30001_ACLeadOff, 1); 01245 // ///< Do a FIFO Reset 01246 // reg_write(FIFO_RST, 0x000000); 01247 // 01248 // ret_val = 0b1000; 01249 // } else if (acloffint_OneShot == 1 && global_status.bit.bover == 0 && global_status.bit.bundr == 0) { ///< Just send once when it comes out of ac lead off 01250 // max30001_ACLeadOff = 0; 01251 // max30001_ACLeadOff = max30001_ACLeadOff | ((global_status.all & 0x030000) >> 16); 01252 // dataAvailable(MAX30001_DATA_LEADOFF_AC, &max30001_ACLeadOff, 1); 01253 // acloffint_OneShot = 0; 01254 // } 01255 // 01256 // if (global_status.bit.bcgmon == 1) {///< BIOZ BCGMON check 01257 // bcgmon_OneShot = 1; 01258 // max30001_bcgmon = 0; 01259 // max30001_bcgmon = max30001_bcgmon | ((global_status.all & 0x000030) >> 4); 01260 // dataAvailable(MAX30001_DATA_BCGMON, &max30001_bcgmon, 1); 01261 // // Do a FIFO Reset 01262 // reg_write(FIFO_RST, 0x000000); 01263 // 01264 // ret_val = 0b10000; 01265 // } else if (bcgmon_OneShot == 1 && global_status.bit.bcgmon == 0) { 01266 // max30001_bcgmon = 0; 01267 // max30001_bcgmon = max30001_bcgmon | ((global_status.all & 0x000030) >> 4); 01268 // bcgmon_OneShot = 0; 01269 // dataAvailable(MAX30001_DATA_BCGMON, &max30001_bcgmon, 1); 01270 // } 01271 // 01272 // if (global_status.bit.lonint == 1 && acleadon_OneShot == 0) {///< AC LeadON Check, when lead is on 01273 // max30001_LeadOn = 0; 01274 // reg_read(STATUS, &global_status.all); 01275 // max30001_LeadOn = 01276 // max30001_LeadOn | (cnfg_gen.bit.en_ulp_lon << 8) | 01277 // ((global_status.all & 0x000800) >> 01278 // 11); ///< 0b01 will mean ECG Lead On, 0b10 will mean BIOZ Lead On 01279 // 01280 // // LEAD ON has been detected... Now take actions 01281 // acleadon_OneShot = 1; 01282 // dataAvailable(MAX30001_DATA_ACLEADON, &max30001_LeadOn, 1); ///< One shot data will be sent... 01283 // } else if (global_status.bit.lonint == 0 && acleadon_OneShot == 1) { 01284 // max30001_LeadOn = 0; 01285 // reg_read(STATUS, &global_status.all); 01286 // max30001_LeadOn = 01287 // max30001_LeadOn | (cnfg_gen.bit.en_ulp_lon << 8) | ((global_status.all & 0x000800) >> 11); ///< 0b01 will mean ECG Lead On, 0b10 will mean BIOZ Lead On 01288 // dataAvailable(MAX30001_DATA_ACLEADON, &max30001_LeadOn, 1); ///< One shot data will be sent... 01289 // acleadon_OneShot = 0; 01290 // } 01291 // 01292 // return ret_val; 01293 //} 01294 // 01295 ////****************************************************************************** 01296 //int MAX30001::int_handler(void) { 01297 // 01298 // static uint32_t InitReset = 0; 01299 // 01300 // int8_t return_value; 01301 // 01302 // reg_read(STATUS, &global_status.all); 01303 // 01304 // ///< Inital Reset and any FIFO over flow invokes a FIFO reset 01305 // if (InitReset == 0 || global_status.bit.eovf == 1 || global_status.bit.bovf == 1 || global_status.bit.povf == 1) { 01306 // ///< Do a FIFO Reset 01307 // reg_write(FIFO_RST, 0x000000); 01308 // 01309 // InitReset++; 01310 // return 2; 01311 // } 01312 // 01313 // return_value = 0; 01314 // 01315 // ///< The four data handling goes on over here 01316 // if (global_status.bit.eint == 1 || global_status.bit.pint == 1 || global_status.bit.bint == 1 || global_status.bit.rrint == 1) { 01317 // return_value = return_value | FIFO_LeadONOff_Read(); 01318 // } 01319 // 01320 // ///< ECG/BIOZ DC Lead Off test 01321 // if (global_status.bit.dcloffint == 1) { 01322 // return_value = return_value | FIFO_LeadONOff_Read(); 01323 // } 01324 // 01325 // ///< BIOZ AC Lead Off test 01326 // if (global_status.bit.bover == 1 || global_status.bit.bundr == 1) { 01327 // return_value = return_value | FIFO_LeadONOff_Read(); 01328 // } 01329 // 01330 // ///< BIOZ DRVP/N test using BCGMON. 01331 // if (global_status.bit.bcgmon == 1) { 01332 // return_value = return_value | FIFO_LeadONOff_Read(); 01333 // } 01334 // 01335 // if (global_status.bit.lonint == 1) ///< ECG Lead ON test: i.e. the leads are touching the body... 01336 // { 01337 // 01338 // FIFO_LeadONOff_Read(); 01339 // } 01340 // 01341 // return return_value; 01342 //} 01343 // 01344 // 01345 //event_callback_t MAX30001::functionpointer; 01346 // 01347 // 01348 //volatile int MAX30001::xferFlag = 0; 01349 // 01350 // 01351 ////****************************************************************************** 01352 //int MAX30001::SPI_Transmit(const uint8_t *tx_buf, uint32_t tx_size, uint8_t *rx_buf, uint32_t rx_size) { 01353 // xferFlag = 0; 01354 // unsigned int i; 01355 // for (i = 0; i < sizeof(buffer); i++) { 01356 // if (i < tx_size) { 01357 // buffer[i] = tx_buf[i]; 01358 // } 01359 // else { 01360 // buffer[i] = 0xFF; 01361 // } 01362 // } 01363 // spi->transfer<uint8_t>(buffer, (int)rx_size, rx_buf, (int)rx_size, spiHandler); 01364 // while (xferFlag == 0); 01365 // return 0; 01366 //} 01367 // 01368 ////****************************************************************************** 01369 //void MAX30001::ReadHeartrateData(max30001_bledata_t *_hspValMax30001) { 01370 // _hspValMax30001->R2R = hspValMax30001.R2R; 01371 // _hspValMax30001->fmstr = hspValMax30001.fmstr; 01372 //} 01373 // 01374 ////****************************************************************************** 01375 //void MAX30001::onDataAvailable(PtrFunction _onDataAvailable) { 01376 // onDataAvailableCallback = _onDataAvailable; 01377 //} 01378 // 01379 ////****************************************************************************** 01380 //void MAX30001::dataAvailable(uint32_t id, uint32_t *buffer, uint32_t length) { 01381 // if (onDataAvailableCallback != NULL) { 01382 // (*onDataAvailableCallback)(id, buffer, length); 01383 // } 01384 //} 01385 // 01386 ////****************************************************************************** 01387 //void MAX30001::spiHandler(int events) { 01388 // xferFlag = 1; 01389 //} 01390 // 01391 ////****************************************************************************** 01392 //static int allowInterrupts = 0; 01393 // 01394 //void MAX30001::Mid_IntB_Handler(void) { 01395 // if (allowInterrupts == 0) { 01396 // return; 01397 // } 01398 // MAX30001::instance->int_handler(); 01399 //} 01400 // 01401 //void MAX30001::Mid_Int2B_Handler(void) { 01402 // if (allowInterrupts == 0) { 01403 // return; 01404 // } 01405 // MAX30001::instance->int_handler(); 01406 //} 01407 // 01408 //void MAX30001::AllowInterrupts(int state) { 01409 //allowInterrupts = state; 01410 //} 01411 // 01412 01413 #include "mbed.h" 01414 #include "MAX30001.h" 01415 01416 MAX30001 *MAX30001::instance = NULL; 01417 01418 //****************************************************************************** 01419 MAX30001::MAX30001(PinName mosi, PinName miso, PinName sclk, PinName cs) { 01420 spi = new SPI(mosi, miso, sclk, cs); 01421 spi->frequency(3000000); 01422 spi_owner = true; 01423 functionpointer.attach(&spiHandler); 01424 onDataAvailableCallback = NULL; 01425 instance = this; 01426 } 01427 01428 //****************************************************************************** 01429 MAX30001::MAX30001(SPI *_spi) { 01430 spi = _spi; 01431 spi->frequency(3000000); 01432 spi_owner = false; 01433 functionpointer.attach(&spiHandler); 01434 onDataAvailableCallback = NULL; 01435 instance = this; 01436 } 01437 01438 //****************************************************************************** 01439 MAX30001::~MAX30001(void) { 01440 if (spi_owner) { 01441 delete spi; 01442 } 01443 } 01444 01445 //****************************************************************************** 01446 int MAX30001::max30001_Rbias_FMSTR_Init(uint8_t En_rbias, uint8_t Rbiasv, 01447 uint8_t Rbiasp, uint8_t Rbiasn, 01448 uint8_t Fmstr) { 01449 if (max30001_reg_read(CNFG_GEN, &max30001_cnfg_gen.all) == -1) { 01450 return -1; 01451 } 01452 01453 max30001_cnfg_gen.bit.en_rbias = En_rbias; 01454 max30001_cnfg_gen.bit.rbiasv = Rbiasv; 01455 max30001_cnfg_gen.bit.rbiasp = Rbiasp; 01456 max30001_cnfg_gen.bit.rbiasn = Rbiasn; 01457 max30001_cnfg_gen.bit.fmstr = Fmstr; 01458 01459 if (max30001_reg_write(CNFG_GEN, max30001_cnfg_gen.all) == -1) { 01460 return -1; 01461 } 01462 return 0; 01463 } 01464 01465 //****************************************************************************** 01466 int MAX30001::max30001_CAL_InitStart(uint8_t En_Vcal, uint8_t Vmode, 01467 uint8_t Vmag, uint8_t Fcal, uint16_t Thigh, 01468 uint8_t Fifty) { 01469 // CNFG_CAL 01470 if (max30001_reg_read(CNFG_CAL, &max30001_cnfg_cal.all) == -1) { 01471 return -1; 01472 } 01473 01474 max30001_cnfg_cal.bit.vmode = Vmode; 01475 max30001_cnfg_cal.bit.vmag = Vmag; 01476 max30001_cnfg_cal.bit.fcal = Fcal; 01477 max30001_cnfg_cal.bit.thigh = Thigh; 01478 max30001_cnfg_cal.bit.fifty = Fifty; 01479 01480 if (max30001_reg_write(CNFG_CAL, max30001_cnfg_cal.all) == -1) { 01481 return -1; 01482 } 01483 01484 // RTOS uses a 32768HZ clock. 32768ticks represents 1secs. 1sec/10 = 01485 // 100msecs. 01486 wait(1.0 / 10.0); 01487 01488 if (max30001_reg_read(CNFG_CAL, &max30001_cnfg_cal.all) == -1) { 01489 return -1; 01490 } 01491 01492 max30001_cnfg_cal.bit.en_vcal = En_Vcal; 01493 01494 if (max30001_reg_write(CNFG_CAL, max30001_cnfg_cal.all) == -1) { 01495 return -1; 01496 } 01497 01498 // RTOS uses a 32768HZ clock. 32768ticks represents 1secs. 1sec/10 = 01499 // 100msecs. 01500 wait(1.0 / 10.0); 01501 01502 return 0; 01503 } 01504 01505 //****************************************************************************** 01506 int MAX30001::max30001_CAL_Stop(void) { 01507 01508 if (max30001_reg_read(CNFG_CAL, &max30001_cnfg_cal.all) == -1) { 01509 return -1; 01510 } 01511 01512 max30001_cnfg_cal.bit.en_vcal = 0; // Disable VCAL, all other settings are left unaffected 01513 01514 if (max30001_reg_write(CNFG_CAL, max30001_cnfg_cal.all) == -1) { 01515 return -1; 01516 } 01517 01518 return 0; 01519 } 01520 //****************************************************************************** 01521 //****************************************************************************** 01522 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, 01523 max30001_intrpt_Location_t en_dcloffint_loc, max30001_intrpt_Location_t en_bint_loc, max30001_intrpt_Location_t en_bovf_loc, 01524 max30001_intrpt_Location_t en_bover_loc, max30001_intrpt_Location_t en_bundr_loc, max30001_intrpt_Location_t en_bcgmon_loc, 01525 max30001_intrpt_Location_t en_pint_loc, max30001_intrpt_Location_t en_povf_loc, max30001_intrpt_Location_t en_pedge_loc, 01526 max30001_intrpt_Location_t en_lonint_loc, max30001_intrpt_Location_t en_rrint_loc, max30001_intrpt_Location_t en_samp_loc, 01527 max30001_intrpt_type_t intb_Type, max30001_intrpt_type_t int2b_Type) 01528 01529 01530 { 01531 // INT1 01532 01533 if (max30001_reg_read(EN_INT, &max30001_en_int.all) == -1) { 01534 return -1; 01535 } 01536 01537 // max30001_en_int2.bit.en_pint = 0b1; // Keep this off... 01538 01539 max30001_en_int.bit.en_eint = 0b1 & en_enint_loc; 01540 max30001_en_int.bit.en_eovf = 0b1 & en_eovf_loc; 01541 max30001_en_int.bit.en_fstint = 0b1 & en_fstint_loc; 01542 01543 max30001_en_int.bit.en_dcloffint = 0b1 & en_dcloffint_loc; 01544 max30001_en_int.bit.en_bint = 0b1 & en_bint_loc; 01545 max30001_en_int.bit.en_bovf = 0b1 & en_bovf_loc; 01546 01547 max30001_en_int.bit.en_bover = 0b1 & en_bover_loc; 01548 max30001_en_int.bit.en_bundr = 0b1 & en_bundr_loc; 01549 max30001_en_int.bit.en_bcgmon = 0b1 & en_bcgmon_loc; 01550 01551 max30001_en_int.bit.en_pint = 0b1 & en_pint_loc; 01552 max30001_en_int.bit.en_povf = 0b1 & en_povf_loc; 01553 max30001_en_int.bit.en_pedge = 0b1 & en_pedge_loc; 01554 01555 max30001_en_int.bit.en_lonint = 0b1 & en_lonint_loc; 01556 max30001_en_int.bit.en_rrint = 0b1 & en_rrint_loc; 01557 max30001_en_int.bit.en_samp = 0b1 & en_samp_loc; 01558 01559 max30001_en_int.bit.intb_type = int2b_Type; 01560 01561 if (max30001_reg_write(EN_INT, max30001_en_int.all) == -1) { 01562 return -1; 01563 } 01564 01565 // INT2 01566 01567 if (max30001_reg_read(EN_INT2, &max30001_en_int2.all) == -1) { 01568 return -1; 01569 } 01570 01571 max30001_en_int2.bit.en_eint = 0b1 & (en_enint_loc >> 1); 01572 max30001_en_int2.bit.en_eovf = 0b1 & (en_eovf_loc >> 1); 01573 max30001_en_int2.bit.en_fstint = 0b1 & (en_fstint_loc >> 1); 01574 01575 max30001_en_int2.bit.en_dcloffint = 0b1 & (en_dcloffint_loc >> 1); 01576 max30001_en_int2.bit.en_bint = 0b1 & (en_bint_loc >> 1); 01577 max30001_en_int2.bit.en_bovf = 0b1 & (en_bovf_loc >> 1); 01578 01579 max30001_en_int2.bit.en_bover = 0b1 & (en_bover_loc >> 1); 01580 max30001_en_int2.bit.en_bundr = 0b1 & (en_bundr_loc >> 1); 01581 max30001_en_int2.bit.en_bcgmon = 0b1 & (en_bcgmon_loc >> 1); 01582 01583 max30001_en_int2.bit.en_pint = 0b1 & (en_pint_loc >> 1); 01584 max30001_en_int2.bit.en_povf = 0b1 & (en_povf_loc >> 1); 01585 max30001_en_int2.bit.en_pedge = 0b1 & (en_pedge_loc >> 1); 01586 01587 max30001_en_int2.bit.en_lonint = 0b1 & (en_lonint_loc >> 1); 01588 max30001_en_int2.bit.en_rrint = 0b1 & (en_rrint_loc >> 1); 01589 max30001_en_int2.bit.en_samp = 0b1 & (en_samp_loc >> 1); 01590 01591 max30001_en_int2.bit.intb_type = intb_Type; 01592 01593 if (max30001_reg_write(EN_INT2, max30001_en_int2.all) == -1) { 01594 return -1; 01595 } 01596 01597 return 0; 01598 } 01599 01600 //****************************************************************************** 01601 int MAX30001::max30001_ECG_InitStart(uint8_t En_ecg, uint8_t Openp, 01602 uint8_t Openn, uint8_t Pol, 01603 uint8_t Calp_sel, uint8_t Caln_sel, 01604 uint8_t E_fit, uint8_t Rate, uint8_t Gain, 01605 uint8_t Dhpf, uint8_t Dlpf) { 01606 01607 // CNFG_EMUX 01608 01609 if (max30001_reg_read(CNFG_EMUX, &max30001_cnfg_emux.all) == -1) { 01610 return -1; 01611 } 01612 01613 max30001_cnfg_emux.bit.openp = Openp; 01614 max30001_cnfg_emux.bit.openn = Openn; 01615 max30001_cnfg_emux.bit.pol = Pol; 01616 max30001_cnfg_emux.bit.calp_sel = Calp_sel; 01617 max30001_cnfg_emux.bit.caln_sel = Caln_sel; 01618 01619 if (max30001_reg_write(CNFG_EMUX, max30001_cnfg_emux.all) == -1) { 01620 return -1; 01621 } 01622 01623 /**** ENABLE CHANNELS ****/ 01624 // CNFG_GEN 01625 01626 if (max30001_reg_read(CNFG_GEN, &max30001_cnfg_gen.all) == -1) { 01627 return -1; 01628 } 01629 01630 max30001_cnfg_gen.bit.en_ecg = En_ecg; // 0b1 01631 01632 // fmstr is default 01633 01634 if (max30001_reg_write(CNFG_GEN, max30001_cnfg_gen.all) == -1) { 01635 return -1; 01636 } 01637 01638 /**** Wait for PLL Lock & References to settle down ****/ 01639 01640 max30001_timeout = 0; 01641 01642 do { 01643 if (max30001_reg_read(STATUS, &max30001_status.all) == -1) // Wait and spin for PLL to lock... 01644 { 01645 return -1; 01646 } 01647 } while (max30001_status.bit.pllint == 1 && max30001_timeout++ <= 1000); 01648 01649 // MNGR_INT 01650 01651 if (max30001_reg_read(MNGR_INT, &max30001_mngr_int.all) == -1) { 01652 return -1; 01653 } 01654 01655 max30001_mngr_int.bit.e_fit = E_fit; // 31 01656 01657 if (max30001_reg_write(MNGR_INT, max30001_mngr_int.all) == -1) { 01658 return -1; 01659 } 01660 01661 // CNFG_ECG 01662 01663 if (max30001_reg_read(CNFG_ECG, &max30001_cnfg_ecg.all) == -1) { 01664 return -1; 01665 } 01666 01667 max30001_cnfg_ecg.bit.rate = Rate; 01668 max30001_cnfg_ecg.bit.gain = Gain; 01669 max30001_cnfg_ecg.bit.dhpf = Dhpf; 01670 max30001_cnfg_ecg.bit.dlpf = Dlpf; 01671 01672 if (max30001_reg_write(CNFG_ECG, max30001_cnfg_ecg.all) == -1) { 01673 return -1; 01674 } 01675 01676 return 0; 01677 } 01678 01679 //****************************************************************************** 01680 int MAX30001::max30001_ECGFast_Init(uint8_t Clr_Fast, uint8_t Fast, uint8_t Fast_Th) { 01681 if (max30001_reg_read(MNGR_INT, &max30001_mngr_int.all) == -1) { 01682 return -1; 01683 } 01684 01685 max30001_mngr_int.bit.clr_fast = Clr_Fast; 01686 01687 if (max30001_reg_write(MNGR_INT, max30001_mngr_int.all) == -1) { 01688 return -1; 01689 } 01690 01691 if (max30001_reg_read(MNGR_DYN, &max30001_mngr_dyn.all) == -1) { 01692 return -1; 01693 } 01694 01695 max30001_mngr_dyn.bit.fast = Fast; 01696 max30001_mngr_dyn.bit.fast_th = Fast_Th; 01697 01698 if (max30001_reg_write(MNGR_INT, max30001_mngr_int.all) == -1) { 01699 return -1; 01700 } 01701 01702 return 0; 01703 } 01704 01705 //****************************************************************************** 01706 int MAX30001::max30001_Stop_ECG(void) { 01707 01708 if (max30001_reg_read(CNFG_GEN, &max30001_cnfg_gen.all) == -1) { 01709 return -1; 01710 } 01711 01712 max30001_cnfg_gen.bit.en_ecg = 0; // Stop ECG 01713 01714 // fmstr is default 01715 01716 if (max30001_reg_write(CNFG_GEN, max30001_cnfg_gen.all) == -1) { 01717 return -1; 01718 } 01719 01720 return 0; 01721 } 01722 01723 //****************************************************************************** 01724 int MAX30001::max30001_PACE_InitStart(uint8_t En_pace, uint8_t Clr_pedge, 01725 uint8_t Pol, uint8_t Gn_diff_off, 01726 uint8_t Gain, uint8_t Aout_lbw, 01727 uint8_t Aout, uint8_t Dacp, 01728 uint8_t Dacn) { 01729 01730 /**** SET MASTER FREQUENCY, ENABLE CHANNELS ****/ 01731 01732 // CNFG_GEN 01733 01734 if (max30001_reg_read(CNFG_GEN, &max30001_cnfg_gen.all) == -1) { 01735 return -1; 01736 } 01737 01738 max30001_cnfg_gen.bit.en_pace = En_pace; // 0b1; 01739 01740 if (max30001_reg_write(CNFG_GEN, max30001_cnfg_gen.all) == -1) { 01741 return -1; 01742 } 01743 01744 /**** Wait for PLL Lock & References to settle down ****/ 01745 max30001_timeout = 0; 01746 01747 do { 01748 if (max30001_reg_read(STATUS, &max30001_status.all) == 01749 -1) // Wait and spin for PLL to lock... 01750 { 01751 return -1; 01752 } 01753 01754 } while (max30001_status.bit.pllint == 1 && max30001_timeout++ <= 1000); 01755 01756 // MNGR_INT 01757 01758 if (max30001_reg_read(MNGR_INT, &max30001_mngr_int.all) == -1) { 01759 return -1; 01760 } 01761 01762 max30001_mngr_int.bit.clr_pedge = Clr_pedge; // 0b0; 01763 01764 if (max30001_reg_write(MNGR_INT, max30001_mngr_int.all) == -1) { 01765 return -1; 01766 } 01767 01768 /* Put: CNFG_PACE */ 01769 01770 max30001_reg_read(CNFG_PACE, &max30001_cnfg_pace.all); 01771 01772 max30001_cnfg_pace.bit.pol = Pol; 01773 max30001_cnfg_pace.bit.gn_diff_off = Gn_diff_off; 01774 max30001_cnfg_pace.bit.gain = Gain; 01775 max30001_cnfg_pace.bit.aout_lbw = Aout_lbw; 01776 max30001_cnfg_pace.bit.aout = Aout; 01777 max30001_cnfg_pace.bit.dacp = Dacp; 01778 max30001_cnfg_pace.bit.dacn = Dacn; 01779 01780 max30001_reg_write(CNFG_PACE, max30001_cnfg_pace.all); 01781 01782 return 0; 01783 } 01784 //****************************************************************************** 01785 int MAX30001::max30001_Stop_PACE(void) { 01786 01787 if (max30001_reg_read(CNFG_GEN, &max30001_cnfg_gen.all) == -1) { 01788 return -1; 01789 } 01790 01791 max30001_cnfg_gen.bit.en_pace = 0; // Stop PACE 01792 01793 if (max30001_reg_write(CNFG_GEN, max30001_cnfg_gen.all) == -1) { 01794 return -1; 01795 } 01796 01797 return 0; 01798 } 01799 01800 //****************************************************************************** 01801 int MAX30001::max30001_BIOZ_InitStart( 01802 uint8_t En_bioz, uint8_t Openp, uint8_t Openn, uint8_t Calp_sel, 01803 uint8_t Caln_sel, uint8_t CG_mode, uint8_t B_fit, uint8_t Rate, 01804 uint8_t Ahpf, uint8_t Ext_rbias, uint8_t Gain, uint8_t Dhpf, uint8_t Dlpf, 01805 uint8_t Fcgen, uint8_t Cgmon, uint8_t Cgmag, uint8_t Phoff) { 01806 01807 // CNFG_BMUX 01808 01809 if (max30001_reg_read(CNFG_BMUX, &max30001_cnfg_bmux.all) == -1) { 01810 return -1; 01811 } 01812 01813 max30001_cnfg_bmux.bit.openp = Openp; // 0b1; 01814 max30001_cnfg_bmux.bit.openn = Openn; // 0b1; 01815 max30001_cnfg_bmux.bit.calp_sel = Calp_sel; // 0b10; 01816 max30001_cnfg_bmux.bit.caln_sel = Caln_sel; // 0b11; 01817 max30001_cnfg_bmux.bit.cg_mode = CG_mode; // 0b00; 01818 01819 if (max30001_reg_write(CNFG_BMUX, max30001_cnfg_bmux.all) == -1) { 01820 return -1; 01821 } 01822 01823 /**** SET MASTER FREQUENCY, ENABLE CHANNELS ****/ 01824 01825 // CNFG_GEN 01826 01827 if (max30001_reg_read(CNFG_GEN, &max30001_cnfg_gen.all) == -1) { 01828 return -1; 01829 } 01830 01831 max30001_cnfg_gen.bit.en_bioz = En_bioz; 01832 01833 // fmstr is default 01834 01835 if (max30001_reg_write(CNFG_GEN, max30001_cnfg_gen.all) == -1) { 01836 return -1; 01837 } 01838 01839 /**** Wait for PLL Lock & References to settle down ****/ 01840 01841 max30001_timeout = 0; 01842 01843 do { 01844 if (max30001_reg_read(STATUS, &max30001_status.all) == 01845 -1) // Wait and spin for PLL to lock... 01846 { 01847 return -1; 01848 } 01849 01850 } while (max30001_status.bit.pllint == 1 && max30001_timeout++ <= 1000); 01851 01852 /**** Start of CNFG_BIOZ ****/ 01853 01854 // MNGR_INT 01855 01856 if (max30001_reg_read(MNGR_INT, &max30001_mngr_int.all) == -1) { 01857 return -1; 01858 } 01859 01860 max30001_mngr_int.bit.b_fit = B_fit; //; 01861 01862 if (max30001_reg_write(MNGR_INT, max30001_mngr_int.all) == -1) { 01863 return -1; 01864 } 01865 01866 // CNFG_BIOZ 01867 01868 if (max30001_reg_read(CNFG_BIOZ, &max30001_cnfg_bioz.all) == -1) { 01869 return -1; 01870 } 01871 01872 max30001_cnfg_bioz.bit.rate = Rate; 01873 max30001_cnfg_bioz.bit.ahpf = Ahpf; 01874 max30001_cnfg_bioz.bit.ext_rbias = Ext_rbias; 01875 max30001_cnfg_bioz.bit.gain = Gain; 01876 max30001_cnfg_bioz.bit.dhpf = Dhpf; 01877 max30001_cnfg_bioz.bit.dlpf = Dlpf; 01878 max30001_cnfg_bioz.bit.fcgen = Fcgen; 01879 max30001_cnfg_bioz.bit.cgmon = Cgmon; 01880 max30001_cnfg_bioz.bit.cgmag = Cgmag; 01881 max30001_cnfg_bioz.bit.phoff = Phoff; 01882 01883 if (max30001_reg_write(CNFG_BIOZ, max30001_cnfg_bioz.all) == -1) { 01884 return -1; 01885 } 01886 01887 return 0; 01888 } 01889 01890 //****************************************************************************** 01891 int MAX30001::max30001_Stop_BIOZ(void) { 01892 01893 if (max30001_reg_read(CNFG_GEN, &max30001_cnfg_gen.all) == -1) { 01894 return -1; 01895 } 01896 01897 max30001_cnfg_gen.bit.en_bioz = 0; // Stop BIOZ 01898 01899 if (max30001_reg_write(CNFG_GEN, max30001_cnfg_gen.all) == -1) { 01900 return -1; 01901 } 01902 01903 return 0; 01904 } 01905 01906 //****************************************************************************** 01907 int MAX30001::max30001_BIOZ_InitBist(uint8_t En_bist, uint8_t Rnom, 01908 uint8_t Rmod, uint8_t Fbist) { 01909 01910 // CNFG_BMUX 01911 01912 if (max30001_reg_read(CNFG_BMUX, &max30001_cnfg_bmux.all) == -1) { 01913 return -1; 01914 } 01915 01916 max30001_cnfg_bmux.bit.en_bist = En_bist; 01917 max30001_cnfg_bmux.bit.rnom = Rnom; 01918 max30001_cnfg_bmux.bit.rmod = Rmod; 01919 max30001_cnfg_bmux.bit.fbist = Fbist; 01920 01921 if (max30001_reg_write(CNFG_BMUX, max30001_cnfg_bmux.all) == -1) { 01922 return -1; 01923 } 01924 01925 return 0; 01926 } 01927 //****************************************************************************** 01928 int MAX30001::max30001_RtoR_InitStart(uint8_t En_rtor, uint8_t Wndw, 01929 uint8_t Gain, uint8_t Pavg, uint8_t Ptsf, 01930 uint8_t Hoff, uint8_t Ravg, uint8_t Rhsf, 01931 uint8_t Clr_rrint) { 01932 01933 // MNGR_INT 01934 01935 if (max30001_reg_read(MNGR_INT, &max30001_mngr_int.all) == -1) { 01936 return -1; 01937 } 01938 01939 max30001_mngr_int.bit.clr_rrint = 01940 Clr_rrint; // 0b01 & 0b00 are for interrupt mode... 01941 // 0b10 is for monitoring mode... it just overwrites the data... 01942 01943 if (max30001_reg_write(MNGR_INT, max30001_mngr_int.all) == -1) { 01944 return -1; 01945 } 01946 01947 // RTOR1 01948 if (max30001_reg_read(CNFG_RTOR1, &max30001_cnfg_rtor1.all) == -1) { 01949 return -1; 01950 } 01951 01952 max30001_cnfg_rtor1.bit.wndw = Wndw; 01953 max30001_cnfg_rtor1.bit.gain = Gain; 01954 max30001_cnfg_rtor1.bit.en_rtor = En_rtor; 01955 max30001_cnfg_rtor1.bit.pavg = Pavg; 01956 max30001_cnfg_rtor1.bit.ptsf = Ptsf; 01957 01958 if (max30001_reg_write(CNFG_RTOR1, max30001_cnfg_rtor1.all) == -1) { 01959 return -1; 01960 } 01961 // RTOR2 01962 01963 if (max30001_reg_read(CNFG_RTOR2, &max30001_cnfg_rtor2.all) == -1) { 01964 return -1; 01965 } 01966 max30001_cnfg_rtor2.bit.hoff = Hoff; 01967 max30001_cnfg_rtor2.bit.ravg = Ravg; 01968 max30001_cnfg_rtor2.bit.rhsf = Rhsf; 01969 01970 if (max30001_reg_write(CNFG_RTOR2, max30001_cnfg_rtor2.all) == -1) { 01971 return -1; 01972 } 01973 01974 return 0; 01975 } 01976 01977 //****************************************************************************** 01978 int MAX30001::max30001_Stop_RtoR(void) { 01979 01980 if (max30001_reg_read(CNFG_RTOR1, &max30001_cnfg_rtor1.all) == -1) { 01981 return -1; 01982 } 01983 01984 max30001_cnfg_rtor1.bit.en_rtor = 0; // Stop RtoR 01985 01986 if (max30001_reg_write(CNFG_RTOR1, max30001_cnfg_rtor1.all) == -1) { 01987 return -1; 01988 } 01989 01990 return 0; 01991 } 01992 01993 //****************************************************************************** 01994 int MAX30001::max30001_PLL_lock(void) { 01995 // Spin to see PLLint become zero to indicate a lock. 01996 01997 max30001_timeout = 0; 01998 01999 do { 02000 if (max30001_reg_read(STATUS, &max30001_status.all) == 02001 -1) // Wait and spin for PLL to lock... 02002 { 02003 return -1; 02004 } 02005 02006 } while (max30001_status.bit.pllint == 1 && max30001_timeout++ <= 1000); 02007 02008 return 0; 02009 } 02010 02011 //****************************************************************************** 02012 int MAX30001::max30001_sw_rst(void) { 02013 // SW reset for the MAX30001 chip 02014 02015 if (max30001_reg_write(SW_RST, 0x000000) == -1) { 02016 return -1; 02017 } 02018 02019 return 0; 02020 } 02021 02022 //****************************************************************************** 02023 int MAX30001::max30001_synch(void) { // For synchronization 02024 if (max30001_reg_write(SYNCH, 0x000000) == -1) { 02025 return -1; 02026 } 02027 return 0; 02028 } 02029 02030 //****************************************************************************** 02031 int MAX30001::max300001_fifo_rst(void) { // Resets the FIFO 02032 if (max30001_reg_write(FIFO_RST, 0x000000) == -1) { 02033 return -1; 02034 } 02035 return 0; 02036 } 02037 02038 //****************************************************************************** 02039 // int MAX30001::max30001_reg_write(uint8_t addr, uint32_t data) 02040 int MAX30001::max30001_reg_write(MAX30001_REG_map_t addr, uint32_t data) { 02041 02042 uint8_t result[4]; 02043 uint8_t data_array[4]; 02044 int32_t success = 0; 02045 02046 data_array[0] = (addr << 1) & 0xff; 02047 02048 data_array[3] = data & 0xff; 02049 data_array[2] = (data >> 8) & 0xff; 02050 data_array[1] = (data >> 16) & 0xff; 02051 02052 success = SPI_Transmit(&data_array[0], 4, &result[0], 4); 02053 02054 if (success != 0) { 02055 return -1; 02056 } else { 02057 return 0; 02058 } 02059 } 02060 02061 //****************************************************************************** 02062 // int MAX30001::max30001_reg_read(uint8_t addr, uint32_t *return_data) 02063 int MAX30001::max30001_reg_read(MAX30001_REG_map_t addr, 02064 uint32_t *return_data) { 02065 uint8_t result[4]; 02066 uint8_t data_array[1]; 02067 int32_t success = 0; 02068 02069 data_array[0] = ((addr << 1) & 0xff) | 1; // For Read, Or with 1 02070 success = SPI_Transmit(&data_array[0], 1, &result[0], 4); 02071 *return_data = /*result[0] + */ (uint32_t)(result[1] << 16) + 02072 (result[2] << 8) + result[3]; 02073 if (success != 0) { 02074 return -1; 02075 } else { 02076 return 0; 02077 } 02078 } 02079 02080 //****************************************************************************** 02081 int MAX30001::max30001_Enable_DcLeadOFF_Init(int8_t En_dcloff, int8_t Ipol, 02082 int8_t Imag, int8_t Vth) { 02083 // the leads are not touching the body 02084 02085 // CNFG_EMUX, Set ECGP and ECGN for external hook up... 02086 02087 if (max30001_reg_read(CNFG_GEN, &max30001_cnfg_gen.all) == -1) { 02088 return -1; 02089 } 02090 02091 max30001_cnfg_gen.bit.en_dcloff = En_dcloff; 02092 max30001_cnfg_gen.bit.ipol = Ipol; 02093 max30001_cnfg_gen.bit.imag = Imag; 02094 max30001_cnfg_gen.bit.vth = Vth; 02095 02096 if (max30001_reg_write(CNFG_GEN, max30001_cnfg_gen.all) == -1) { 02097 return -1; 02098 } 02099 02100 return 0; 02101 } 02102 02103 //****************************************************************************** 02104 int MAX30001::max30001_Disable_DcLeadOFF(void) { 02105 if (max30001_reg_read(CNFG_GEN, &max30001_cnfg_gen.all) == -1) { 02106 return -1; 02107 } 02108 02109 max30001_cnfg_gen.bit.en_dcloff = 0; // Turned off the dc lead off. 02110 02111 if (max30001_reg_write(CNFG_GEN, max30001_cnfg_gen.all) == -1) { 02112 return -1; 02113 } 02114 02115 return 0; 02116 } 02117 02118 //****************************************************************************** 02119 int MAX30001::max30001_BIOZ_Enable_ACLeadOFF_Init(uint8_t En_bloff, 02120 uint8_t Bloff_hi_it, 02121 uint8_t Bloff_lo_it) { 02122 02123 // CNFG_GEN 02124 if (max30001_reg_read(CNFG_GEN, &max30001_cnfg_gen.all) == -1) { 02125 return -1; 02126 } 02127 02128 max30001_cnfg_gen.bit.en_bloff = En_bloff; 02129 02130 if (max30001_reg_write(CNFG_GEN, max30001_cnfg_gen.all) == -1) { 02131 return -1; 02132 } 02133 02134 // MNGR_DYN 02135 if (max30001_reg_read(MNGR_DYN, &max30001_mngr_dyn.all) == -1) { 02136 return -1; 02137 } 02138 02139 max30001_mngr_dyn.bit.bloff_hi_it = Bloff_hi_it; 02140 max30001_mngr_dyn.bit.bloff_lo_it = Bloff_lo_it; 02141 02142 if (max30001_reg_write(MNGR_DYN, max30001_mngr_dyn.all) == -1) { 02143 return -1; 02144 } 02145 02146 return 0; 02147 } 02148 02149 //****************************************************************************** 02150 int MAX30001::max30001_BIOZ_Disable_ACleadOFF(void) { 02151 // CNFG_GEN 02152 if (max30001_reg_read(CNFG_GEN, &max30001_cnfg_gen.all) == -1) { 02153 return -1; 02154 } 02155 02156 max30001_cnfg_gen.bit.en_bloff = 0b0; // Turns of the BIOZ AC Lead OFF feature 02157 02158 if (max30001_reg_write(CNFG_GEN, max30001_cnfg_gen.all) == -1) { 02159 return -1; 02160 } 02161 02162 return 0; 02163 } 02164 02165 //****************************************************************************** 02166 int MAX30001::max30001_BIOZ_Enable_BCGMON(void) { 02167 // CNFG_BIOZ 02168 if (max30001_reg_read(CNFG_BIOZ, &max30001_cnfg_bioz.all) == -1) { 02169 return -1; 02170 } 02171 02172 max30001_cnfg_bioz.bit.cgmon = 1; 02173 02174 if (max30001_reg_write(CNFG_BIOZ, max30001_cnfg_bioz.all) == -1) { 02175 return -1; 02176 } 02177 02178 max30001_reg_read(CNFG_BIOZ, &max30001_cnfg_bioz.all); 02179 02180 return 0; 02181 } 02182 02183 #if 1 02184 //****************************************************************************** 02185 int MAX30001::max30001_Enable_LeadON(int8_t Channel) // Channel: ECG = 0b01, BIOZ = 0b10, Disable = 0b00 02186 { 02187 02188 if (max30001_reg_read(CNFG_GEN, &max30001_cnfg_gen.all) == -1) { 02189 return -1; 02190 } 02191 02192 max30001_cnfg_gen.bit.en_ecg = 0b0; 02193 max30001_cnfg_gen.bit.en_bioz = 0b0; 02194 max30001_cnfg_gen.bit.en_pace = 0b0; 02195 02196 max30001_cnfg_gen.bit.en_ulp_lon = Channel; // BIOZ ULP lead on detection... 02197 02198 if (max30001_reg_write(CNFG_GEN, max30001_cnfg_gen.all) == -1) { 02199 return -1; 02200 } 02201 02202 max30001_reg_read(CNFG_GEN, &max30001_cnfg_gen.all); 02203 02204 max30001_reg_read(STATUS, &max30001_status.all); 02205 02206 return 0; 02207 } 02208 //****************************************************************************** 02209 int MAX30001::max30001_Disable_LeadON(void) { 02210 02211 if (max30001_reg_read(CNFG_GEN, &max30001_cnfg_gen.all) == -1) { 02212 return -1; 02213 } 02214 02215 max30001_cnfg_gen.bit.en_ulp_lon = 0b0; 02216 02217 if (max30001_reg_write(CNFG_GEN, max30001_cnfg_gen.all) == -1) { 02218 return -1; 02219 } 02220 02221 return 0; 02222 } 02223 #endif 02224 //****************************************************************************** 02225 #define LEADOFF_SERVICE_TIME 0x2000 // 0x1000 = 1 second 02226 #define LEADOFF_NUMSTATES 2 02227 uint32_t leadoffState = 0; 02228 uint32_t max30001_LeadOffoldTime = 0; 02229 void MAX30001::max30001_ServiceLeadoff(uint32_t currentTime) { 02230 02231 uint32_t delta_Time; 02232 02233 delta_Time = currentTime - max30001_LeadOffoldTime; 02234 02235 if (delta_Time > LEADOFF_SERVICE_TIME) { 02236 switch (leadoffState) { 02237 case 0: /* switch to ECG DC Lead OFF */ 02238 max30001_Enable_DcLeadOFF_Init(0b01, 0b0, 0b001, 0b00); 02239 break; 02240 02241 case 1: /* switch to BIOZ DC Lead OFF */ 02242 max30001_Enable_DcLeadOFF_Init(0b10, 0b0, 0b001, 0b00); 02243 break; 02244 } 02245 02246 leadoffState++; 02247 leadoffState %= LEADOFF_NUMSTATES; 02248 02249 max30001_LeadOffoldTime = currentTime; 02250 } 02251 } 02252 //****************************************************************************** 02253 #define LEADON_SERVICE_TIME 0x2000 // 0x1000 = 1 second 02254 #define LEADON_NUMSTATES 2 02255 uint32_t leadOnState = 0; 02256 uint32_t max30001_LeadOnoldTime = 0; 02257 void MAX30001::max30001_ServiceLeadON(uint32_t currentTime) { 02258 02259 uint32_t delta_Time; 02260 02261 delta_Time = currentTime - max30001_LeadOnoldTime; 02262 02263 if (delta_Time > LEADON_SERVICE_TIME) { 02264 switch (leadOnState) { 02265 case 0: /* switch to ECG DC Lead ON */ 02266 max30001_Enable_LeadON(0b01); 02267 break; 02268 02269 case 1: /* switch to BIOZ DC Lead ON */ 02270 max30001_Enable_LeadON(0b10); 02271 break; 02272 } 02273 02274 leadOnState++; 02275 leadOnState %= LEADON_NUMSTATES; 02276 02277 max30001_LeadOnoldTime = currentTime; 02278 } 02279 } 02280 02281 //****************************************************************************** 02282 int MAX30001::max30001_FIFO_LeadONOff_Read(void) { 02283 02284 uint8_t result[32 * 3]; // 32words - 3bytes each 02285 02286 uint8_t data_array[4]; 02287 int32_t success = 0; 02288 int i, j; 02289 02290 uint32_t total_databytes; 02291 uint8_t i_index; 02292 uint8_t data_chunk; 02293 uint8_t loop_logic; 02294 02295 uint8_t etag, ptag, btag; 02296 02297 uint8_t adr; 02298 02299 int8_t ReadAllPaceOnce; 02300 02301 static uint8_t dcloffint_OneShot = 0; 02302 static uint8_t acloffint_OneShot = 0; 02303 static uint8_t bcgmon_OneShot = 0; 02304 static uint8_t acleadon_OneShot = 0; 02305 02306 int8_t ret_val; 02307 02308 if (max30001_status.bit.eint == 1 || max30001_status.bit.pint == 1) { 02309 adr = ECG_FIFO_BURST; 02310 data_array[0] = ((adr << 1) & 0xff) | 1; 02311 02312 // The SPI routine only sends out data of 32 bytes in size. Therefore the 02313 // data is being read in 02314 // smaller chunks in this routine... 02315 02316 total_databytes = (max30001_mngr_int.bit.e_fit + 1) * 3; 02317 02318 i_index = 0; 02319 loop_logic = 1; 02320 02321 while (loop_logic) { 02322 if (total_databytes > 30) { 02323 data_chunk = 30; 02324 total_databytes = total_databytes - 30; 02325 } else { 02326 data_chunk = total_databytes; 02327 loop_logic = 0; 02328 } 02329 02330 /* The extra 1 byte is for the extra byte that comes out of the SPI */ 02331 success = SPI_Transmit(&data_array[0], 1, &result[i_index], (data_chunk + 1)); // Make a copy of the FIFO over here... 02332 02333 if (success != 0) { 02334 return -1; 02335 } 02336 02337 /* This is important, because every transaction above creates an empty 02338 * redundant data at result[0] */ 02339 for (j = i_index; j < (data_chunk + i_index); j++) /* get rid of the 1 extra byte by moving the whole array up one */ 02340 { 02341 result[j] = result[j + 1]; 02342 } 02343 02344 i_index = i_index + 30; /* point to the next array location to put the data in */ 02345 } 02346 02347 ReadAllPaceOnce = 0; 02348 02349 /* Put the content of the FIFO based on the EFIT value, We ignore the 02350 * result[0] and start concatenating indexes: 1,2,3 - 4,5,6 - 7,8,9 - */ 02351 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 02352 { 02353 max30001_ECG_FIFO_buffer[i] = ((uint32_t)result[j] << 16) + (result[j + 1] << 8) + result[j + 2]; 02354 02355 etag = (0b00111000 & result[j + 2]) >> 3; 02356 ptag = 0b00000111 & result[j + 2]; 02357 02358 if (ptag != 0b111 && ReadAllPaceOnce == 0) { 02359 02360 ReadAllPaceOnce = 1; // This will prevent extra read of PACE, once group 02361 // 0-5 is read ONCE. 02362 02363 adr = PACE0_FIFO_BURST; 02364 02365 data_array[0] = ((adr << 1) & 0xff) | 1; // For Read Or with 1 02366 02367 success = SPI_Transmit(&data_array[0], 1, &result[0], 10); 02368 02369 max30001_PACE[0] = (uint32_t)(result[1] << 16) + (result[2] << 8) + result[3]; 02370 max30001_PACE[1] = (uint32_t)(result[4] << 16) + (result[5] << 8) + result[6]; 02371 max30001_PACE[2] = (uint32_t)(result[7] << 16) + (result[8] << 8) + result[9]; 02372 02373 adr = PACE1_FIFO_BURST; 02374 02375 data_array[0] = ((adr << 1) & 0xff) | 1; // For Read Or with 1 02376 02377 success = SPI_Transmit(&data_array[0], 1, &result[0], 10); 02378 02379 max30001_PACE[3] = (uint32_t)(result[1] << 16) + (result[2] << 8) + result[3]; 02380 max30001_PACE[4] = (uint32_t)(result[4] << 16) + (result[5] << 8) + result[6]; 02381 max30001_PACE[5] = (uint32_t)(result[7] << 16) + (result[8] << 8) + result[9]; 02382 02383 adr = PACE2_FIFO_BURST; 02384 02385 data_array[0] = ((adr << 1) & 0xff) | 1; // For Read Or with 1 02386 02387 success = SPI_Transmit(&data_array[0], 1, &result[0], 10); 02388 02389 max30001_PACE[6] = (uint32_t)(result[1] << 16) + (result[2] << 8) + result[3]; 02390 max30001_PACE[7] = (uint32_t)(result[4] << 16) + (result[5] << 8) + result[6]; 02391 max30001_PACE[8] = (uint32_t)(result[7] << 16) + (result[8] << 8) + result[9]; 02392 02393 adr = PACE3_FIFO_BURST; 02394 02395 data_array[0] = ((adr << 1) & 0xff) | 1; // For Read Or with 1 02396 02397 success = SPI_Transmit(&data_array[0], 1, &result[0], 10); 02398 02399 max30001_PACE[9] = (uint32_t)(result[1] << 16) + (result[2] << 8) + result[3]; 02400 max30001_PACE[10] = (uint32_t)(result[4] << 16) + (result[5] << 8) + result[6]; 02401 max30001_PACE[11] = (uint32_t)(result[7] << 16) + (result[8] << 8) + result[9]; 02402 02403 adr = PACE4_FIFO_BURST; 02404 02405 data_array[0] = ((adr << 1) & 0xff) | 1; // For Read Or with 1 02406 02407 success = SPI_Transmit(&data_array[0], 1, &result[0], 10); 02408 02409 max30001_PACE[12] = (uint32_t)(result[1] << 16) + (result[2] << 8) + result[3]; 02410 max30001_PACE[13] = (uint32_t)(result[4] << 16) + (result[5] << 8) + result[6]; 02411 max30001_PACE[14] = (uint32_t)(result[7] << 16) + (result[8] << 8) + result[9]; 02412 02413 adr = PACE5_FIFO_BURST; 02414 02415 data_array[0] = ((adr << 1) & 0xff) | 1; // For Read Or with 1 02416 02417 success = SPI_Transmit(&data_array[0], 1, &result[0], 10); 02418 02419 max30001_PACE[15] = (uint32_t)(result[1] << 16) + (result[2] << 8) + result[3]; 02420 max30001_PACE[16] = (uint32_t)(result[4] << 16) + (result[5] << 8) + result[6]; 02421 max30001_PACE[17] = (uint32_t)(result[7] << 16) + (result[8] << 8) + result[9]; 02422 02423 dataAvailable(MAX30001_DATA_PACE, max30001_PACE, 18); // Send out the Pace data once only 02424 } 02425 } 02426 02427 if (etag != 0b110) { 02428 02429 dataAvailable(MAX30001_DATA_ECG, max30001_ECG_FIFO_buffer, (max30001_mngr_int.bit.e_fit + 1)); 02430 } 02431 02432 } /* End of ECG init */ 02433 02434 /* RtoR */ 02435 02436 if (max30001_status.bit.rrint == 1) { 02437 if (max30001_reg_read(RTOR, &max30001_RtoR_data) == -1) { 02438 return -1; 02439 } 02440 02441 max30001_RtoR_data = (0x00FFFFFF & max30001_RtoR_data) >> 10; 02442 02443 hspValMax30001.R2R = (uint16_t)max30001_RtoR_data; 02444 hspValMax30001.fmstr = (uint16_t)max30001_cnfg_gen.bit.fmstr; 02445 02446 dataAvailable(MAX30001_DATA_RTOR, &max30001_RtoR_data, 1); 02447 } 02448 02449 // Handling BIOZ data... 02450 02451 if (max30001_status.bit.bint == 1) { 02452 adr = 0x22; 02453 data_array[0] = ((adr << 1) & 0xff) | 1; 02454 02455 /* [(BFIT+1)*3byte]+1extra byte due to the addr */ 02456 02457 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... 02458 02459 { 02460 return -1; 02461 } 02462 02463 btag = 0b00000111 & result[3]; 02464 02465 /* Put the content of the FIFO based on the BFIT value, We ignore the 02466 * result[0] and start concatenating indexes: 1,2,3 - 4,5,6 - 7,8,9 - */ 02467 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 02468 { 02469 max30001_BIOZ_FIFO_buffer[i] = ((uint32_t)result[j + 1] << 16) + (result[j + 2] << 8) + result[j + 3]; 02470 } 02471 02472 if (btag != 0b110) { 02473 dataAvailable(MAX30001_DATA_BIOZ, max30001_BIOZ_FIFO_buffer, 8); 02474 } 02475 } 02476 02477 ret_val = 0; 02478 02479 if (max30001_status.bit.dcloffint == 1) // ECG/BIOZ Lead Off 02480 { 02481 dcloffint_OneShot = 1; 02482 max30001_DCLeadOff = 0; 02483 max30001_DCLeadOff = max30001_DCLeadOff | (max30001_cnfg_gen.bit.en_dcloff << 8) | (max30001_status.all & 0x00000F); 02484 dataAvailable(MAX30001_DATA_LEADOFF_DC, &max30001_DCLeadOff, 1); 02485 // Do a FIFO Reset 02486 max30001_reg_write(FIFO_RST, 0x000000); 02487 02488 ret_val = 0b100; 02489 02490 } else if (dcloffint_OneShot == 1 && max30001_status.bit.dcloffint == 0) // Just send once when it comes out of dc lead off 02491 { 02492 max30001_DCLeadOff = 0; 02493 max30001_DCLeadOff = max30001_DCLeadOff | (max30001_cnfg_gen.bit.en_dcloff << 8) | (max30001_status.all & 0x00000F); 02494 dataAvailable(MAX30001_DATA_LEADOFF_DC, &max30001_DCLeadOff, 1); 02495 dcloffint_OneShot = 0; 02496 } 02497 02498 if (max30001_status.bit.bover == 1 || max30001_status.bit.bundr == 1) // BIOZ AC Lead Off 02499 { 02500 acloffint_OneShot = 1; 02501 max30001_ACLeadOff = 0; 02502 max30001_ACLeadOff = 02503 max30001_ACLeadOff | ((max30001_status.all & 0x030000) >> 16); 02504 dataAvailable(MAX30001_DATA_LEADOFF_AC, &max30001_ACLeadOff, 1); 02505 // Do a FIFO Reset 02506 max30001_reg_write(FIFO_RST, 0x000000); 02507 02508 ret_val = 0b1000; 02509 } 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 02510 { 02511 max30001_ACLeadOff = 0; 02512 max30001_ACLeadOff = max30001_ACLeadOff | ((max30001_status.all & 0x030000) >> 16); 02513 dataAvailable(MAX30001_DATA_LEADOFF_AC, &max30001_ACLeadOff, 1); 02514 acloffint_OneShot = 0; 02515 } 02516 02517 if (max30001_status.bit.bcgmon == 1) // BIOZ BCGMON check 02518 { 02519 bcgmon_OneShot = 1; 02520 max30001_bcgmon = 0; 02521 max30001_bcgmon = max30001_bcgmon | ((max30001_status.all & 0x000030) >> 4); 02522 dataAvailable(MAX30001_DATA_BCGMON, &max30001_bcgmon, 1); 02523 // Do a FIFO Reset 02524 max30001_reg_write(FIFO_RST, 0x000000); 02525 02526 ret_val = 0b10000; 02527 } else if (bcgmon_OneShot == 1 && max30001_status.bit.bcgmon == 0) { 02528 max30001_bcgmon = 0; 02529 max30001_bcgmon = max30001_bcgmon | ((max30001_status.all & 0x000030) >> 4); 02530 bcgmon_OneShot = 0; 02531 dataAvailable(MAX30001_DATA_BCGMON, &max30001_bcgmon, 1); 02532 } 02533 02534 #if 0 02535 if(max30001_status.bit.lonint == 1) // AC LeadON Check 02536 { 02537 max30001_LeadOn = 0; 02538 max30001_reg_read(STATUS,&max30001_status.all); // Reading is important 02539 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 02540 // LEAD ON has been detected... Now take actions 02541 } 02542 #endif 02543 02544 if (max30001_status.bit.lonint == 1 && 02545 acleadon_OneShot == 0) // AC LeadON Check, when lead is on 02546 { 02547 max30001_LeadOn = 0; 02548 max30001_reg_read(STATUS, &max30001_status.all); // Reading is important 02549 max30001_LeadOn = 02550 max30001_LeadOn | (max30001_cnfg_gen.bit.en_ulp_lon << 8) | 02551 ((max30001_status.all & 0x000800) >> 02552 11); // 0b01 will mean ECG Lead On, 0b10 will mean BIOZ Lead On 02553 02554 // LEAD ON has been detected... Now take actions 02555 acleadon_OneShot = 1; 02556 dataAvailable(MAX30001_DATA_ACLEADON, &max30001_LeadOn, 1); // One shot data will be sent... 02557 } else if (max30001_status.bit.lonint == 0 && acleadon_OneShot == 1) { 02558 max30001_LeadOn = 0; 02559 max30001_reg_read(STATUS, &max30001_status.all); 02560 max30001_LeadOn = 02561 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 02562 dataAvailable(MAX30001_DATA_ACLEADON, &max30001_LeadOn, 1); // One shot data will be sent... 02563 acleadon_OneShot = 0; 02564 } 02565 02566 return ret_val; 02567 } 02568 02569 //****************************************************************************** 02570 02571 int MAX30001::max30001_int_handler(void) { 02572 02573 static uint32_t InitReset = 0; 02574 02575 int8_t return_value; 02576 02577 max30001_reg_read(STATUS, &max30001_status.all); 02578 02579 // Inital Reset and any FIFO over flow invokes a FIFO reset 02580 if (InitReset == 0 || max30001_status.bit.eovf == 1 || max30001_status.bit.bovf == 1 || max30001_status.bit.povf == 1) { 02581 // Do a FIFO Reset 02582 max30001_reg_write(FIFO_RST, 0x000000); 02583 02584 InitReset++; 02585 return 2; 02586 } 02587 02588 return_value = 0; 02589 02590 // The four data handling goes on over here 02591 if (max30001_status.bit.eint == 1 || max30001_status.bit.pint == 1 || max30001_status.bit.bint == 1 || max30001_status.bit.rrint == 1) { 02592 return_value = return_value | max30001_FIFO_LeadONOff_Read(); 02593 } 02594 02595 // ECG/BIOZ DC Lead Off test 02596 if (max30001_status.bit.dcloffint == 1) { 02597 return_value = return_value | max30001_FIFO_LeadONOff_Read(); 02598 } 02599 02600 // BIOZ AC Lead Off test 02601 if (max30001_status.bit.bover == 1 || max30001_status.bit.bundr == 1) { 02602 return_value = return_value | max30001_FIFO_LeadONOff_Read(); 02603 } 02604 02605 // BIOZ DRVP/N test using BCGMON. 02606 if (max30001_status.bit.bcgmon == 1) { 02607 return_value = return_value | max30001_FIFO_LeadONOff_Read(); 02608 } 02609 02610 if (max30001_status.bit.lonint == 1) // ECG Lead ON test: i.e. the leads are touching the body... 02611 { 02612 02613 max30001_FIFO_LeadONOff_Read(); 02614 } 02615 02616 return return_value; 02617 } 02618 02619 /// function pointer to the async callback 02620 static event_callback_t functionpointer; 02621 /// flag used to indicate an async xfer has taken place 02622 static volatile int xferFlag = 0; 02623 02624 /** 02625 * @brief Callback handler for SPI async events 02626 * @param events description of event that occurred 02627 */ 02628 static void spiHandler(int events) { xferFlag = 1; } 02629 02630 /** 02631 * @brief Transmit and recieve QUAD SPI data 02632 * @param tx_buf pointer to transmit byte buffer 02633 * @param tx_size number of bytes to transmit 02634 * @param rx_buf pointer to the recieve buffer 02635 * @param rx_size number of bytes to recieve 02636 */ 02637 int MAX30001::SPI_Transmit(const uint8_t *tx_buf, uint32_t tx_size, uint8_t *rx_buf, uint32_t rx_size) { 02638 xferFlag = 0; 02639 int i; 02640 for (i = 0; i < sizeof(buffer); i++) { 02641 if (i < tx_size) 02642 buffer[i] = tx_buf[i]; 02643 else 02644 buffer[i] = 0xFF; 02645 } 02646 spi->transfer<uint8_t>(buffer, (int)rx_size, rx_buf, (int)rx_size, spiHandler /* functionpointer */); 02647 while (xferFlag == 0); 02648 return 0; 02649 } 02650 02651 //****************************************************************************** 02652 void MAX30001::max30001_ReadHeartrateData(max30001_t *_hspValMax30001) { 02653 _hspValMax30001->R2R = hspValMax30001.R2R; 02654 _hspValMax30001->fmstr = hspValMax30001.fmstr; 02655 } 02656 02657 //****************************************************************************** 02658 void MAX30001::onDataAvailable(PtrFunction _onDataAvailable) { 02659 onDataAvailableCallback = _onDataAvailable; 02660 } 02661 02662 /** 02663 * @brief Used to notify an external function that interrupt data is available 02664 * @param id type of data available 02665 * @param buffer 32-bit buffer that points to the data 02666 * @param length length of 32-bit elements available 02667 */ 02668 void MAX30001::dataAvailable(uint32_t id, uint32_t *buffer, uint32_t length) { 02669 if (onDataAvailableCallback != NULL) { 02670 (*onDataAvailableCallback)(id, buffer, length); 02671 } 02672 } 02673 02674 /** 02675 * @brief Callback handler for SPI async events 02676 * @param events description of event that occurred 02677 */ 02678 void MAX30001::spiHandler(int events) { xferFlag = 1; } 02679 02680 //****************************************************************************** 02681 static int allowInterrupts = 0; 02682 02683 void MAX30001Mid_IntB_Handler(void) { 02684 if (allowInterrupts == 0) return; 02685 MAX30001::instance->max30001_int_handler(); 02686 } 02687 02688 void MAX30001Mid_Int2B_Handler(void) { 02689 if (allowInterrupts == 0) return; 02690 MAX30001::instance->max30001_int_handler(); 02691 } 02692 02693 void MAX30001_AllowInterrupts(int state) { 02694 allowInterrupts = state; 02695 }
Generated on Wed Jul 13 2022 02:29:55 by
1.7.2