MAX32620HSP (MAXREFDES100) RPC Example for Graphical User Interface

Dependencies:   USBDevice

Fork of HSP_Release by Jerry Bradshaw

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 }