Channel_ID

Dependencies:   MAX30003 max32630fthr DS1307

main.cpp

Committer:
kidecha_rahul
Date:
2021-05-18
Revision:
16:8fc65c8fa0e8
Parent:
15:0356e9454a60

File content as of revision 16:8fc65c8fa0e8:


#include "MAX30003.h"
#include "mbed.h"
#include "max32630fthr.h"
#include "ds1307.h"
//#include <BufferedSerial.h>
#include <string>
//#include <Serial.h>

#define TARGET_TX_PIN P3_1
#define TARGET_RX_PIN P3_0

Timer timer_fast;
Timer t;
MAX32630FTHR pegasus(MAX32630FTHR::VIO_3V3);

void task_fast(void);
DigitalOut ledA(LED2);

void ecg_config(MAX30003 &ecgAFE);
//BufferedSerial pc(P3_1,P3_0);            // Use USB debug probe for serial link static Unbuffered
BufferedSerial pc(P0_1,P0_0);

//atic BufferedSerial pc(TARGET_TX_PIN, TARGET_RX_PIN, 230400); // 230400 works well

//Serial uart_1(USBTX, USBRX);            // Use USB debug probe for serial link static Unbuffered
//
//rial pc(P0_1,P0_0);
volatile bool ecgFIFOIntFlag = 0; 
volatile bool timerflag = 0;

FileHandle *mbed::mbed_override_console(int fd)
{
    return &pc;
}

void ecgFIFO_callback_1()  { // Triggered when the ECG FIFO is about to be full
    
    ecgFIFOIntFlag = 1;
}  

time_t asUnixTime(int year, int mon, int mday, int hour, int min, int sec) {
    struct tm   t;
    t.tm_year = year - 1900;
    t.tm_mon =  mon - 1;        // convert to 0 based month
    t.tm_mday = mday;
    t.tm_hour = hour;
    t.tm_min = min;
    t.tm_sec = sec;
    t.tm_isdst = -1;            // Is Daylight saving time on? 1 = yes, 0 = no, -1 = unknown
 
    return mktime(&t);          // returns seconds elapsed since January 1, 1970 (begin of the Epoch)
}
int main(void)
{   
   // 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;
    
    timer_fast.start();
    DigitalOut rLed(LED2, LED_ON);
    
//    pc.baud(9600);
    
    //pc.set_baud(115200);                    // Baud rate = 115200
    //pc.set_format(
    //    /* bits */ 8,   
    //    /* parity */ BufferedSerial::None,
    //    /* stop bit */ 1 //1
    //);
    //uart_1.baud(115200);  
    InterruptIn ecgFIFO_int(P5_4);          // Config P5_4 as int. in for the
    ecgFIFO_int.fall(&ecgFIFO_callback_1);    // ecg FIFO interrupt at falling edge
    
    SPI spiBus(SPI2_MOSI, SPI2_MISO, SPI2_SCK);     // SPI bus, P5_1 = MOSI, 
                                                    // P5_2 = MISO, P5_0 = SCK
      
    MAX30003 ecgAFE(spiBus, P5_3);          // New MAX30003 on spiBus, CS = P5_3 
    
    ecg_config(ecgAFE);                    // Config ECG 
    
    
    ecgAFE.writeRegister( MAX30003::SYNCH , 0);
    
    uint32_t ecgFIFO, readECGSamples, idx, ETAG[32], status;
    int16_t ecgSample[32];
//-----------------------------------------------------------------------------------------------// 
    
    //bool timerflag = false;
    int16_t ecgSample_1sec[200];
    //uint8_t ecg_1 = 0;
  //  uint8_t ecg_2 = 0;
   uint16_t onesec_counter = 0;
   uint16_t onesec_counter_temp = 0;
   
   uint8_t channel_ID[3]= {1,2,3};
   uint8_t ecg_1 = 0;
   uint8_t ecg_2 = 0;
   uint8_t ecg_3 = 0;
   
    int16_t sample = 300;
    uint8_t final[10];
    
    uint16_t checksum_ = 0;
    uint16_t mod_checksum = 0;
    
    uint8_t p_1 = 0;
    uint8_t p_2 = 0;
    uint8_t p_3 = 0;
    uint8_t p_4 = 0;
    
    uint8_t data_len_1 = 0;
    uint8_t data_len_2 = 0;
    uint32_t packet_1 = 0;
    uint8_t cksm_1 = 0;
    uint8_t cksm_2 = 0;
    uint8_t header_device_id[3] = {0,0,210};
    uint8_t header_packet_type[2] = {0,2};
    
    uint8_t ending[5] = {'@','#','%','!','7'};
    
    bool flip = true;
     int sampleps = 0;
     
    char buf[20];
    
    
    
   // pc.write("Welcome",8*sizeof(char));
   // printf("In the main loop"); //printf("In the main loop");
     bool flag_first = false;
     bool timestamp_reader = false;
      do
      {
        if (pc.readable())  // For nordic - Readiing time
        {     
        scanf("%s",buf);
     //printf("The entered string is %s : \n ",buf);
     
     packet_1 = atoi(buf);  // converting ascii to integer
     set_time(packet_1);   // check unit in packet_1 ??
     
     if ((packet_1 % 60) == 0)  // tim stamp at the beginning of time
         { 
           /*  for (int u = 0;u<3;u++)
             {
                 if (pc.readable()) 
                {     
                    scanf("%s",buf);
                    printf("Entered the minute string  %s : \n ",buf);
                 
                    packet_1 = atoi(buf);
                    set_time(packet_1);
                }
             }*/
         timestamp_reader = true;
         }
         else
         {
             //printf("The timestamp is not divisible by 60 \n");
             }
     //flag_first = true;
    
        }
        
        }while (timestamp_reader==false); // take the third timestamp
         
         
        
    while(1)        
    {
       
    if ((onesec_counter>=125)) //125 sample rate
    {
     //t.start();
     //ledA = !ledA;   
     
      //pc.write((uint8_t *)header_device_id, sizeof(header_device_id));                                                      // sensor ID
      
     // pc.write((uint8_t *)header_packet_type, sizeof(header_packet_type));                                                  // packet type
      
      time_t seconds = time(NULL); // setting zero
      packet_1 = seconds;
      //packet_1 ++;
     // printf("Time as seconds since January 1, 1970 = %d\n", packet_1);
      p_1 = packet_1 & 0xff; 
      p_2 = (packet_1 >> 8) & 0xff;
      p_3 = (packet_1 >> 16) & 0xff;
      p_4 = (packet_1 >> 24) & 0xff;
     // checksum_  = checksum_ + (packet_1 & 0xffff) + ((packet_1 >> 16) & 0xffff) ;
     checksum_  = checksum_ + p_1 + p_2 + p_3 + p_4 ;
     uint8_t header_packet_id[4] = {p_4,p_3,p_2,p_1};
      //pc.write((uint8_t *)header_packet_id, sizeof(header_packet_id));                                                      //packet ID
      
          
      uint8_t Channel_Num = 0;
      if(ecg_1 == 1)
        Channel_Num = channel_ID[0];
      else if (ecg_2 == 1)
            Channel_Num = channel_ID[1];
      else if (ecg_3 == 1)
            Channel_Num = channel_ID[2];
      else
            Channel_Num = 0;      
      //pc.write((uint8_t *)Channel_Num, sizeof(Channel_Num));     
      printf("%6d\r\n", Channel_Num);                                                    //Channel no
      
      onesec_counter_temp = onesec_counter * 2;
      data_len_1 = onesec_counter_temp & 0xff;
      data_len_2 = (onesec_counter_temp >> 8) & 0xff;
      checksum_  = checksum_ + data_len_1 + data_len_2;  
      //pc.write((uint32_t *)packet_1, sizeof(packet_1));
      uint8_t header_ecg_datalen[2] = {data_len_2,data_len_1};
     // pc.write((uint8_t *)header_ecg_datalen, sizeof(header_ecg_datalen));                                                  // Data length
      
      
      mod_checksum = checksum_ % 65536 ;
      cksm_1 = mod_checksum & 0xff;
      cksm_2 = (mod_checksum >> 8) & 0xff;
      uint8_t header_ecg_checksum[2] = {cksm_2,cksm_1};
      //pc.write((uint8_t *)header_ecg_checksum, sizeof(header_ecg_checksum));                                                // checksum
      
    //  pc.write((int16_t *)ecgSample_1sec,onesec_counter * sizeof(int16_t));                                                 // ECG Data
      printf("Samples per second  %d \n", (onesec_counter));
     
      
      onesec_counter = 0;
       // memset(ecgSample_1sec, 0, sizeof(ecgSample_1sec));
              
       // pc.write((uint8_t *)ending, sizeof(ending));                                                                        // Ending of data
        
        checksum_ = 0;
        //t.stop();
       // auto us = t.elapsed_time().count();
       // float time_taken = us/1000000;
       // printf("Timer time: %lu ms \n", (time_taken*100));
      // t.reset();
    //  timer_fast.reset();
       } 
       

       // Read back ECG samples from the FIFO        
       else if((ecgFIFOIntFlag==1))// && (timerflag == 0)) 
        {
            ecg_1 = 1;
            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
                    ecgSample[readECGSamples] = ((ecgSample[readECGSamples]<<8)&0xFF00)|((ecgSample[readECGSamples]>>8)&0x00FF);
                    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
                }
                //uint8_t header_ecg_checksum[2] = {'%','%'};
                //pc.write((uint8_t *)header_ecg_checksum, sizeof(header_ecg_checksum));
                
                //pc.write((int16_t *)ecgSample,readECGSamples * sizeof(int16_t ));
                //memcpy(ecgSample_1sec , ecgSample, sizeof(ecgSample));
                
                //memcpy(ecgSample_1sec + (onesec_counter * sizeof(int16_t)), ecgSample, sizeof(ecgSample));
                
                if (flip)
                {
                 sampleps = 12;
                 //printf("Flipped 12\r\n");     
                 }
                 else
                 {
                     sampleps = 13;
                    // printf("Flipped 13\r\n");     
                  }
                
                 for( idx = 0; idx < sampleps; idx++ ) 
                {
                    //pc.printf("%6d\r\n", ecgSample[idx]);     
                    ecgSample_1sec[onesec_counter] = ecgSample[idx];
                    
                    cksm_1 = ecgSample[idx] & 0xff;
                    cksm_2 = (ecgSample[idx] >> 8) & 0xff;
                    checksum_ += cksm_1 + cksm_2;
                    onesec_counter++;      
                } 
                  flip =!flip; 
                  rLed = ! rLed;           
            }
           
        }
    }
}




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   
    //CNFG_GEN_r.bits.fmstr = 1; //125 sps FMSTR 1
    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.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.all = 0;
    EN_INT_r.bits.en_eint = 1;              // Enable EINT interrupt
    EN_INT_r.bits.en_rrint = 0;             // Disable 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;
}