Lucas Lim / Mbed 2 deprecated HSP_Temperature_Barometer_CS3237

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers MAX30001.cpp Source File

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 }