Vincent Neo / Mbed 2 deprecated CS3237_Project

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers MAX30001.cpp Source File

MAX30001.cpp

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