Arm Mbed OS support forum

nRF52 & MAX30003 ECG AFE

Hi all,

I am working with the nRF52 dev kit and the ecg sensor MAX30003

I am using this library and the example code from maxim (https://os.mbed.com/teams/MaximIntegrated/code/MAX30003/)

My problem is:
No interrupt calls are triggered from the ecg sensor despite the ecg FIFO being full. No ECG readings are coming in. But I am able to accuratelly read and write registers from the MAX30003.

I found someone with the same problem here (https://os.mbed.com/questions/87012/nRF52-DK-MAX30003-WING-ecg-sensor/) but the topic is not answered :frowning:

Thanks for any help!

my code is blow:

#include "mbed.h"
#include "MAX30003.h"
 
//LED pins
#define LED1 p17
//#define LED2 p20 //-->check pins after
 
//SPI PINS (MAX 30003)
#define SPI_MOSI p26 //SPI MOSI Pin
#define SPI_MISO p23 //SPI MISO Pin
#define SPI_SCK p24 //SPI SCK Pin
#define ECG_SPI_CS p22 //ECG SPI Chip Select Pin
#define ECG_INT_PIN p19 //ECG Interrupt Pin (FIFO almost full)

void ecg_config(MAX30003 &ecgAFE);
 
/* ECG FIFO nearly full callback */
volatile bool ecgFIFOIntFlag = 0; 
void ecgFIFO_callback()  {

ecgFIFOIntFlag = 1;
 
}  
 
int main()
{   
 
// Constants
const int EINT_STATUS_MASK =  1 << 23;
const int FIFO_OVF_MASK =  0x7;
const int FIFO_VALID_SAMPLE_MASK =  0x0;
const int FIFO_FAST_SAMPLE_MASK =  0x1;
const int ETAG_BITS_MASK = 0x7;

// Ports and serial connections
Serial pc(USBTX, USBRX);            // Use USB debug probe for serial link
pc.baud(115200);                    // Baud rate = 115200

DigitalOut rLed(LED1, 0);      // Debug LED
//DigitalOut gLed(LED2, 0);      // Debug LED

InterruptIn ecgFIFO_int(ECG_INT_PIN);
ecgFIFO_int.fall(&ecgFIFO_callback);    // ecg FIFO almost full interrupt

SPI spiBus(SPI_MOSI, SPI_MISO, SPI_SCK);     // SPI bus

MAX30003 ecgAFE(spiBus, ECG_SPI_CS);          // New MAX30003 on spiBus, CS
ecg_config(ecgAFE);                    // Config ECG 
 

ecgAFE.writeRegister( MAX30003::SYNCH , 0);

//ecgAFE.writeRegister( MAX30003::FIFO_RST , 0);

uint32_t ecgFIFO, readECGSamples, idx, ETAG[32], status;
int16_t ecgSample[32];

pc.printf("MAX30003 configured \n\n\n");
pc.printf("INFO %X \n\n", ecgAFE.readRegister( MAX30003::INFO ));
pc.printf("STATUS %X \n\n", ecgAFE.readRegister( MAX30003::STATUS ));

while(1) {
       
    // Read back ECG samples from the FIFO 
    if( ecgFIFOIntFlag ) {
        
        ecgFIFOIntFlag = 0; 
        status = ecgAFE.readRegister( MAX30003::STATUS );      // Read the STATUS register
         
        // Check if EINT interrupt asserted
        if ( ( status & EINT_STATUS_MASK ) == EINT_STATUS_MASK ) {     
        
            readECGSamples = 0;                        // Reset sample counter
            
            do {
                ecgFIFO = ecgAFE.readRegister( MAX30003::ECG_FIFO );       // Read FIFO
                ecgSample[readECGSamples] = ecgFIFO >> 8;                  // Isolate voltage data
                ETAG[readECGSamples] = ( ecgFIFO >> 3 ) & ETAG_BITS_MASK;  // Isolate ETAG
                readECGSamples++;                                          // Increment sample counter
            
            // Check that sample is not last sample in FIFO                                              
            } while ( ETAG[readECGSamples-1] == FIFO_VALID_SAMPLE_MASK || 
                      ETAG[readECGSamples-1] == FIFO_FAST_SAMPLE_MASK ); 
            
            // Check if FIFO has overflowed
            if( ETAG[readECGSamples - 1] == FIFO_OVF_MASK ){                  
                ecgAFE.writeRegister( MAX30003::FIFO_RST , 0); // Reset FIFO
                rLed = 1;//notifies the user that an over flow occured
            }
            
            // Print results 
            for( idx = 0; idx < readECGSamples; idx++ ) {
                pc.printf("%6d\r\n", ecgSample[idx]);           
            } 
                           
        }
    }
}
}
 
 
 
 
void ecg_config(MAX30003& ecgAFE) { 
 
 // Reset ECG to clear registers
ecgAFE.writeRegister( MAX30003::SW_RST , 0);

// General config register setting
MAX30003::GeneralConfiguration_u CNFG_GEN_r;
CNFG_GEN_r.bits.en_ecg = 1;     // Enable ECG channel
CNFG_GEN_r.bits.rbiasn = 1;     // Enable resistive bias on negative input
CNFG_GEN_r.bits.rbiasp = 1;     // Enable resistive bias on positive input
CNFG_GEN_r.bits.en_rbias = 1;   // Enable resistive bias
CNFG_GEN_r.bits.imag = 2;       // Current magnitude = 10nA
CNFG_GEN_r.bits.en_dcloff = 1;  // Enable DC lead-off detection   
ecgAFE.writeRegister( MAX30003::CNFG_GEN , CNFG_GEN_r.all);
    

// ECG Config register setting
MAX30003::ECGConfiguration_u CNFG_ECG_r;
CNFG_ECG_r.bits.dlpf = 1;       // Digital LPF cutoff = 40Hz
CNFG_ECG_r.bits.dhpf = 1;       // Digital HPF cutoff = 0.5Hz
CNFG_ECG_r.bits.gain = 3;       // ECG gain = 160V/V
CNFG_ECG_r.bits.rate = 2;       // Sample rate = 128 sps
ecgAFE.writeRegister( MAX30003::CNFG_ECG , CNFG_ECG_r.all);
  

//R-to-R configuration
MAX30003::RtoR1Configuration_u CNFG_RTOR_r;
CNFG_RTOR_r.bits.wndw = 0b0011;         // WNDW = 96ms
CNFG_RTOR_r.bits.rgain = 0b1111;        // Auto-scale gain
CNFG_RTOR_r.bits.pavg = 0b11;           // 16-average
CNFG_RTOR_r.bits.ptsf = 0b0011;         // PTSF = 4/16
CNFG_RTOR_r.bits.en_rtor = 1;           // Enable R-to-R detection
ecgAFE.writeRegister( MAX30003::CNFG_RTOR1 , CNFG_RTOR_r.all);
   
    
//Manage interrupts register setting
MAX30003::ManageInterrupts_u MNG_INT_r;
MNG_INT_r.bits.efit = 0b00011;          // Assert EINT w/ 4 unread samples
MNG_INT_r.bits.clr_rrint = 0b01;        // Clear R-to-R on RTOR reg. read back
ecgAFE.writeRegister( MAX30003::MNGR_INT , MNG_INT_r.all);


//Enable interrupts register setting
MAX30003::EnableInterrupts_u EN_INT_r;
EN_INT_r.bits.en_eint = 1;              // Enable EINT interrupt
EN_INT_r.bits.en_rrint = 1;             // Enable R-to-R interrupt
EN_INT_r.bits.intb_type = 3;            // Open-drain NMOS with internal pullup
ecgAFE.writeRegister( MAX30003::EN_INT , EN_INT_r.all);
   
   
//Dyanmic modes config
MAX30003::ManageDynamicModes_u MNG_DYN_r;
MNG_DYN_r.bits.fast = 0;                // Fast recovery mode disabled
ecgAFE.writeRegister( MAX30003::MNGR_DYN , MNG_DYN_r.all);

// MUX Config
MAX30003::MuxConfiguration_u CNFG_MUX_r;
CNFG_MUX_r.bits.openn = 0;          // Connect ECGN to AFE channel
CNFG_MUX_r.bits.openp = 0;          // Connect ECGP to AFE channel
ecgAFE.writeRegister( MAX30003::CNFG_EMUX , CNFG_MUX_r.all);

return;
}