MAX30001-MAX32630FTHR SYS EvKit

Dependencies:   USBDevice max32630fthr

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