Debug demo for ECG

Dependencies:   MAX30003 max32630fthr

Fork of MAX30003_Demo_Debug by Central Applications - Mbed Code repo

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 /*******************************************************************************
00002  * Copyright (C) 2017 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 
00035 #include "mbed.h"
00036 #include "max32630fthr.h"
00037 #include "MAX30003.h"
00038 
00039 MAX32630FTHR pegasus(MAX32630FTHR::VIO_3V3);
00040 
00041 void ecg_config(MAX30003 &ecgAFE);
00042 
00043 /* ECG FIFO nearly full callback */
00044 volatile bool ecgIntFlag = 0; 
00045 void ecgFIFO_callback()  {
00046     
00047     ecgIntFlag = 1;
00048 
00049 }  
00050 
00051 int main()
00052 {   
00053     
00054     // Constants
00055     const int EINT_STATUS =  1 << 23;
00056     const int RTOR_STATUS =  1 << 10;
00057     const int RTOR_REG_OFFSET = 10;
00058     const float RTOR_LSB_RES = 0.008f;
00059     const int FIFO_OVF =  0x7;
00060     const int FIFO_VALID_SAMPLE =  0x0;
00061     const int FIFO_FAST_SAMPLE =  0x1;
00062     const int ETAG_BITS = 0x7;
00063     
00064     // Ports and serial connections
00065     Serial pc(USBTX, USBRX);            // Use USB debug probe for serial link
00066     pc.baud(115200);                    // Baud rate = 115200
00067     
00068     DigitalOut rLed(LED1, LED_OFF);     // Debug LEDs
00069     DigitalOut gLed(LED2, LED_OFF);
00070     DigitalOut bLed(LED3, LED_OFF);
00071     
00072     InterruptIn ecgFIFO_int(P5_4);          // Config P5_4 as int. in for the
00073     ecgFIFO_int.fall(&ecgFIFO_callback);    // ecg FIFO almost full interrupt
00074     
00075     SPI spiBus(SPI2_MOSI, SPI2_MISO, SPI2_SCK);     // SPI bus, P5_1 = MOSI, 
00076                                                     // P5_2 = MISO, P5_0 = SCK
00077     
00078     MAX30003 ecgAFE(spiBus, P5_3);          // New MAX30003 on spiBus, CS = P5_3 
00079     ecg_config( ecgAFE );                   // Config ECG 
00080      
00081     
00082     ecgAFE.writeRegister( MAX30003::SYNCH , 0);
00083     
00084     uint32_t ecgFIFO, RtoR, readECGSamples, idx, ETAG[32], status;
00085     int16_t ecgSample[32];
00086     float BPM;
00087     
00088     while(1) {
00089         
00090         /* Read back ECG samples from the FIFO */
00091         if( ecgIntFlag ) {
00092             
00093             ecgIntFlag = 0;
00094             pc.printf("Interrupt received....\r\n");
00095             status = ecgAFE.readRegister( MAX30003::STATUS );      // Read the STATUS register
00096             pc.printf("Status : 0x%x\r\n"
00097                       "Current BPM is %3.2f\r\n\r\n", status, BPM);
00098              
00099              
00100             // Check if R-to-R interrupt asserted
00101             if( ( status & RTOR_STATUS ) == RTOR_STATUS ){           
00102             
00103                 pc.printf("R-to-R Interrupt \r\n");
00104                 
00105                 // Read RtoR register
00106                 RtoR = ecgAFE.readRegister( MAX30003::RTOR ) >>  RTOR_REG_OFFSET;   
00107                 
00108                 // Convert to BPM
00109                 BPM = 1.0f / ( RtoR * RTOR_LSB_RES / 60.0f );   
00110                 
00111                 // Print RtoR              
00112                 pc.printf("RtoR : %d\r\n\r\n", RtoR);                   
00113                 
00114             }  
00115              
00116             // Check if EINT interrupt asserted
00117             if ( ( status & EINT_STATUS ) == EINT_STATUS ) {     
00118             
00119                 pc.printf("FIFO Interrupt \r\n");
00120                 readECGSamples = 0;                        // Reset sample counter
00121                 
00122                 do {
00123                     ecgFIFO = ecgAFE.readRegister( MAX30003::ECG_FIFO );       // Read FIFO
00124                     ecgSample[readECGSamples] = ecgFIFO >> 8;                  // Isolate voltage data
00125                     ETAG[readECGSamples] = ( ecgFIFO >> 3 ) & ETAG_BITS;  // Isolate ETAG
00126                     readECGSamples++;                                          // Increment sample counter
00127                 
00128                 // Check that sample is not last sample in FIFO                                              
00129                 } while ( ETAG[readECGSamples-1] == FIFO_VALID_SAMPLE || 
00130                           ETAG[readECGSamples-1] == FIFO_FAST_SAMPLE ); 
00131             
00132                 pc.printf("%d samples read from FIFO \r\n", readECGSamples);
00133                 
00134                 // Check if FIFO has overflowed
00135                 if( ETAG[readECGSamples - 1] == FIFO_OVF ){                  
00136                     ecgAFE.writeRegister( MAX30003::FIFO_RST , 0); // Reset FIFO
00137                 }
00138                 
00139                 // Print results 
00140                 for( idx = 0; idx < readECGSamples; idx++ ) {
00141                     pc.printf("Sample : %6d, \tETAG : 0x%x\r\n", ecgSample[idx], ETAG[idx]);           
00142                 }
00143                 pc.printf("\r\n\r\n\r\n"); 
00144                                          
00145             }
00146         }
00147     }
00148 }
00149 
00150 
00151 
00152 
00153 void ecg_config(MAX30003& ecgAFE) { 
00154 
00155     // Reset ECG to clear registers
00156     ecgAFE.writeRegister( MAX30003::SW_RST , 0);
00157     
00158     // General config register setting
00159     MAX30003::GeneralConfiguration_u CNFG_GEN_r;
00160     CNFG_GEN_r.bits.en_ecg = 1;     // Enable ECG channel
00161     CNFG_GEN_r.bits.rbiasn = 1;     // Enable resistive bias on negative input
00162     CNFG_GEN_r.bits.rbiasp = 1;     // Enable resistive bias on positive input
00163     CNFG_GEN_r.bits.en_rbias = 1;   // Enable resistive bias
00164     CNFG_GEN_r.bits.imag = 2;       // Current magnitude = 10nA
00165     CNFG_GEN_r.bits.en_dcloff = 1;  // Enable DC lead-off detection   
00166     ecgAFE.writeRegister( MAX30003::CNFG_GEN , CNFG_GEN_r.all);
00167         
00168     
00169     // ECG Config register setting
00170     MAX30003::ECGConfiguration_u CNFG_ECG_r;
00171     CNFG_ECG_r.bits.dlpf = 1;       // Digital LPF cutoff = 40Hz
00172     CNFG_ECG_r.bits.dhpf = 1;       // Digital HPF cutoff = 0.5Hz
00173     CNFG_ECG_r.bits.gain = 3;       // ECG gain = 160V/V
00174     CNFG_ECG_r.bits.rate = 2;       // Sample rate = 128 sps
00175     ecgAFE.writeRegister( MAX30003::CNFG_ECG , CNFG_ECG_r.all);
00176       
00177     
00178     //R-to-R configuration
00179     MAX30003::RtoR1Configuration_u CNFG_RTOR_r;
00180     CNFG_RTOR_r.bits.wndw = 0b0011;         // WNDW = 96ms
00181     CNFG_RTOR_r.bits.rgain = 0b1111;        // Auto-scale gain
00182     CNFG_RTOR_r.bits.pavg = 0b11;           // 16-average
00183     CNFG_RTOR_r.bits.ptsf = 0b0011;         // PTSF = 4/16
00184     CNFG_RTOR_r.bits.en_rtor = 1;           // Enable R-to-R detection
00185     ecgAFE.writeRegister( MAX30003::CNFG_RTOR1 , CNFG_RTOR_r.all);
00186        
00187         
00188     //Manage interrupts register setting
00189     MAX30003::ManageInterrupts_u MNG_INT_r;
00190     MNG_INT_r.bits.efit = 0b00011;          // Assert EINT w/ 4 unread samples
00191     MNG_INT_r.bits.clr_rrint = 0b01;        // Clear R-to-R on RTOR reg. read back
00192     ecgAFE.writeRegister( MAX30003::MNGR_INT , MNG_INT_r.all);
00193     
00194     
00195     //Enable interrupts register setting
00196     MAX30003::EnableInterrupts_u EN_INT_r;
00197     EN_INT_r.bits.en_eint = 1;              // Enable EINT interrupt
00198     EN_INT_r.bits.en_rrint = 1;             // Enable R-to-R interrupt
00199     EN_INT_r.bits.intb_type = 3;            // Open-drain NMOS with internal pullup
00200     ecgAFE.writeRegister( MAX30003::EN_INT , EN_INT_r.all);
00201        
00202        
00203     //Dyanmic modes config
00204     MAX30003::ManageDynamicModes_u MNG_DYN_r;
00205     MNG_DYN_r.bits.fast = 0;                // Fast recovery mode disabled
00206     ecgAFE.writeRegister( MAX30003::MNGR_DYN , MNG_DYN_r.all);
00207     
00208     // MUX Config
00209     MAX30003::MuxConfiguration_u CNFG_MUX_r;
00210     CNFG_MUX_r.bits.openn = 0;          // Connect ECGN to AFE channel
00211     CNFG_MUX_r.bits.openp = 0;          // Connect ECGP to AFE channel
00212     ecgAFE.writeRegister( MAX30003::CNFG_EMUX , CNFG_MUX_r.all);
00213     
00214     return;
00215 }  
00216