Interface between the mbed lpc1768 and the ads1298

Dependencies:   USBDevice mbed

Revision:
0:bd3a560e245e
Child:
1:26b8b0e4d836
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Thu Apr 10 06:44:02 2014 +0000
@@ -0,0 +1,571 @@
+/**********************************************************************************************************************************
+*changed the ISR function 
+*incuded 0x02 to make sure that 24 buts are sent
+****************************************************************************************************************************************/
+// include files
+#include "mbed.h"
+#include "ADS1x9x.h"
+#include "stdef.h"
+#pragma diag_suppress 177  //suppress unused declared entities
+
+/*******************************************************************************************************************************************
+                                        Definitions
+ ********************************************************************************************************************************************/
+#define ADS1298_DATA_LENGTH 27
+#define STAND_BY_MODE 0x04
+#define REGISTER_DEFAULT_SETTINGS 0x00
+#define WAIT_CCSSC 0.000000007 //wait 7ns
+#define WAIT_CSH 0.000001 //wait 2 clock cycles
+#define WAIT_DSHD 0.00008 //wait 16 clock cycles
+#define WAIT_RST  0.000009//wait 18 clock cycles
+#define wait_time 0.000004  //8th sclk falling edge
+#define wait_time2 0.000012 //wait 24clock cycles
+#define buffer_size 100      // size of data buffers 
+
+/***********************************************************************************************************************************************
+                                           Pin Allocations
+ ***********************************************************************************************************************************************/
+DigitalOut myled(LED1);
+Timer timer1;
+SPI spi(p5,p6,p7);  // Initialisng variables mosi, miso,sclk,chip select
+DigitalOut cs(p8);           //Chip select
+DigitalOut out(p18);           // To  Oscillioscope
+InterruptIn DRDY(p22);           //Interrupt signal
+DigitalOut Start(p23);
+DigitalOut PWDN (p24);
+DigitalOut CLKSEL(p25);
+DigitalOut Reset(p26);
+DigitalOut CS_START(p27);
+
+
+Serial pc(USBTX, USBRX); //tx,rx
+PwmOut pw(p21);
+
+/***********************************************************************************************************************************************
+                                                STRUCTURES
+*************************************************************************************************************************************************/
+// info from pc
+typedef struct {
+        int resolution;             //resolution of adc
+        volatile char data_out1[9]; //msb
+        volatile char data_out2[9];//middle byte
+        volatile char data_out3[9];//lsb
+        int ttl_freq;
+        int gain;             //duty cycle of pulse generation.
+        int RLD;                    //right leg drive
+        int test_duration;
+        int num_channels;
+        int count;
+        int lpf_cutoff;
+        int mfs;// value either 1 or 0 representing if a ganzfeld or multifocal system(mfs) is used
+        int mfs_frequency; //frequency of mfs simulator 
+        int ganzfeld_frequency; //frequency of ganzfeld simulator
+        int freq_s;
+
+}data;
+
+data test;
+
+/**************************************************************************************************************************************************
+*                                 Global Variables                                                                                                *
+**************************************************************************************************************************************************/
+unsigned char ADS1x9x_SPI_data;
+signed char ADS1x9x_Data [ADS1298_DATA_LENGTH];
+float buffer_1[buffer_size] = {0};
+float buffer_2[buffer_size] = {0};
+unsigned char device_slot;
+
+/************************************************************************************************************************************************
+                                Function prototypes
+ **********************************************************************************************************************************************/
+void pulse_generation(int mfs, int ganzfeld_frequency, int mfs_frequency );
+void Initialize_ADS1x9x_Mode(void);
+void spi_initialise(void);
+void file_system(void);
+void read_data(void);
+void test_info(void);
+ int Initialize_ADS1x9x_Channel (void);
+void lpf_coef(void);
+float lpf( float coeff[5], float);
+void ISR1();
+void read(void);
+
+
+/**************************************************************************************************************************************************
+                                                MAIN PROGRAM 
+***************************************************************************************************************************************************/
+int main() {
+    
+    pc.baud(14400);
+    int system_pause = 1;
+    int device_slot = 1;
+    
+    DRDY.fall(&ISR1);
+    
+    test_info(); 
+    // calculate the low pass filter coeficeints
+    lpf_coef(); 
+    wait(0.1);
+    
+    cs = LOW;
+    
+    CS_START =LOW;
+    wait(WAIT_CCSSC);
+    
+    pc.printf("Initialising");
+      spi_initialise();
+      cs = LOW;
+      wait(0.1);
+      
+      Reset = 1;            //introduced this
+      wait(wait_time);
+      Reset = 0;
+      
+       pc.printf("Waking up adc from sleep ");
+     spi.write(WAKE_CONVERTER_FROM_SLEEP); //power up adc
+     wait(1);
+    
+      
+      spi.write(RESET_CONVERTER); //reset
+      wait(WAIT_RST);
+   
+      CLKSEL = 1; //use internal clock
+       wait(wait_time);
+       
+       PWDN = 1; 
+       Reset = 1;
+       wait(1.5);
+      // Reset = 0; //not sure about this bit.
+      // wait(WAIT_RST);
+       
+       spi.write(RESET_CONVERTER); //reset
+       wait(WAIT_RST);
+    pc.printf("Converter has been reset\n");
+          
+       read(); //read config registers
+        wait(wait_time);
+       
+    spi.write(WRITE_CONFIG_3_REGISTER);
+    wait(wait_time);
+    spi.write(SINGLE_BYTE_READ_WRITE);
+    wait(wait_time);
+    spi.write(INTERNAL_REF);
+    
+              
+       //setup config registers
+       Initialize_ADS1x9x_Mode(); //config 1,2,3,4
+       
+       test.num_channels = Initialize_ADS1x9x_Channel();
+       
+       //initialise gpio
+    init_ADS1x9x_IO (device_slot);
+      wait(wait_time);
+      
+      pc.printf("Reading the config settings");
+            
+       read();
+        wait(0.0001);
+              
+              
+        Start = LOW;
+        wait(WAIT_CSH);
+          
+        spi.write(START_RESTART_CONVERSION);
+        wait(WAIT_DSHD);
+        
+      spi.write(SET_READ_DATA_CONTINUOUSLY );
+      wait(wait_time);
+      
+     
+             
+    system_pause = pc.scanf("%d\n",&system_pause); //wait for start command
+    timer1.start(); 
+    
+    while(timer1.read() < 200){    //Ensure that the test runs for 2 minute only 
+     
+              //check for pause before continuing
+        system_pause = 1;
+        if (system_pause == 0)
+        {
+            while(system_pause == 0)
+            {
+            system_pause = pc.scanf("%d\n",&system_pause);
+            
+             }
+        }
+        
+        else
+        {
+          pulse_generation(test.mfs, test.ganzfeld_frequency,test.mfs_frequency);  //5 is just an arbitrary value selected so that the code runs, to use adc speed  
+         
+         int a = test.count - 1;
+     
+        __disable_irq();
+         if (test.count > a) //prevents the same data being repeatedly sent since the adc is slower than the mcu
+         {
+          //include lpf
+         // test.data_out = lpf(test.data_out) 
+       //  read2();
+         for (int i = 0; i <= (test.num_channels +1);i++){
+          
+               //pc.printf("\n");             
+          pc.printf("%02x%02x%02x\n",test.data_out1[i], test.data_out2[i],test.data_out3[i]); 
+          }  
+                  
+           }
+          
+           
+           else 
+               {
+               wait(0.000000000001); //momentary pause 
+               
+            }
+           __enable_irq ();
+                                         
+        }
+          }
+         Start = LOW; //stop conversion
+         wait(WAIT_DSHD);
+        // spi.write(0x0A);
+    spi.write( STOP_READ_DATA_CONTINUOUSLY );
+    wait(wait_time );
+    spi.write(STAND_BY_MODE);        //Enter standby mode
+  timer1.stop();
+ wait(WAIT_CSH);
+  cs = HIGH;
+     return 1;
+ }
+/**********************************************************************************************************************************************
+                                            TEST INFORMATION
+**********************************************************************************************************************************************/
+void test_info(void){
+  // LocalFileSystem local("local");               // Create the local filesystem under the name "local"
+    //open text file 
+      // FILE *fp = fopen("/local/out.txt", "r");  // Open "out.txt" on the local file system for reading
+         
+         // if (fp == NULL){
+         //    myled = 1;
+          //  }
+            //else {
+          //while (!feof(fp)){
+              
+        // fscanf(fp,"%d\n",&test.num_channels);
+         //fscanf(fp,"%d\n",&test.gain); 
+     //}
+       // }   
+       
+    test.num_channels = 3;
+    test.gain = 6;
+    test.lpf_cutoff = 1000;
+    test.mfs = 1;
+    test.ttl_freq = 500;
+    test.freq_s = 5;
+    
+}
+
+/***********************************************************************************************************************************************
+                                        PUSLE GENERATION
+ ***********************************************************************************************************************************************/
+void pulse_generation(int mfs, int ganzfeld_frequency, int mfs_frequency ){
+
+PwmOut pw(p21);
+float duty_cycle;
+
+static double period;
+ //Enable ganzfeld synchronising pulse
+// pc.printf("Using a Ganzfeld(0) or Mfs(1)?"); //mfs=>multifocal system 
+        switch(test.mfs)
+        {
+            case 0:
+                    { //ganzfeld
+                        period = 1/test.ttl_freq;
+                        pw.period(period); 
+                        pw = 0.5;
+                    }   
+            case 1: //mf case sends pulse at the operating frequency of the adc
+                    {
+                       pw.period(0.0010);
+                        pw = 0.5; //duty cycle of 50% , a perfect square wave                  
+                        
+                    }
+        }
+
+}
+/************************************************************************************************************************************************
+                                            SPI INTERFACE
+*************************************************************************************************************************************************/
+
+void spi_initialise(void){
+           
+    spi.format(8,1);       //configuring the transmission of data and mode 1
+    spi.frequency(2000000);  //spi  clock frequency to 2Mhz
+             return; 
+}
+
+
+ /**********************************************************************************************************************************
+                                         INITIALISE ADS I/O
+  **********************************************************************************************************************************/
+  void init_ADS1x9x_IO (unsigned char){
+ //right now, not using any input or output pins
+ //setting all GPIO to output mode and connecting them to ground
+ 
+ spi.write(WRITE_GENERAL_PORT_IO);  //write the command to the GPIO register
+ wait(wait_time);
+ spi.write(SINGLE_BYTE_READ_WRITE);
+ wait(wait_time);
+ spi.write(REGISTER_DEFAULT_SETTINGS);  //Turn all general purpose inputs and outputs off
+ wait(wait_time);
+ //pc.printf("GPIO initialisation complete\n");
+ return;
+  }
+    
+ /*************************************************************************************************************************************
+                                        INITIALISE ADS MODE
+  **************************************************************************************************************************************/
+  //Data rate configured
+  void Initialize_ADS1x9x_Mode() {
+       
+    wait(WAIT_DSHD);
+    spi.write(WRITE_CONFIG_1_REGISTER);      //Write to config1
+    wait(WAIT_DSHD);
+    spi.write(SINGLE_BYTE_READ_WRITE);       //Second byte of WReg
+    wait(WAIT_DSHD);
+    switch(test.freq_s)
+    {
+        case 0:
+                spi.write(THIRTY_TWO_KSPS_SAMPLING_FREQ);        //use command 0xC0 to use external clock
+                test.freq_s = 32000;
+        case 1:
+                spi.write(SIXTEEN_KSPS_SAMPLING_FREQ);
+                test.freq_s = 16000;
+        case 2:
+                spi.write(EIGHT_KSPS_SAMPLING_FREQ);
+                test.freq_s = 8000;
+        case 3:
+                spi.write(FOUR_KSPS_SAMPLING_FREQ);
+                test.freq_s  = 4000;
+        case 4: 
+                spi.write(TWO_KSPS_SAMPLING_FREQ);
+                test.freq_s = 2000;
+        case 5:
+                spi.write(ONE_KSPS_SAMPLING_FREQ);
+                pc.printf("\n1k sampling rate\n");
+                test.freq_s = 1000;
+         case 6:
+                spi.write(FIVE_SPS_SAMPLING_FREQ);
+                test.freq_s = 500;
+    }
+    wait(0.00002);
+           
+        pc.printf("Config 1 value\n");
+        volatile char d = spi.write(FETCH_DATA);
+        wait(wait_time2);
+        pc.printf("%X",d);
+    
+     
+    spi.write(WRITE_CONFIG_2_REGISTER );           //Write to CONFIG 2
+    wait(wait_time);
+    spi.write(SINGLE_BYTE_READ_WRITE);
+    wait(wait_time);
+    spi.write(REGISTER_DEFAULT_SETTINGS);            //configures the test signal generation
+    
+    wait(wait_time);
+    spi.write(WRITE_CONFIG_3_REGISTER);      //Write to CONFIG 3
+    wait(wait_time);
+    spi.write(SINGLE_BYTE_READ_WRITE);
+    wait(wait_time);
+    spi.write(INTERNAL_REF);                //Configures multireference and enables internal reference buffer
+    wait(0.01);
+    
+    //CONFIG4
+    
+    spi.write(WRITE_CONFIG_4_REGISTER );
+    wait(wait_time);
+    spi.write(SINGLE_BYTE_READ_WRITE);
+    wait(wait_time);
+    spi.write(REGISTER_DEFAULT_SETTINGS); //set adc in continous mode and respiration modulatiion frequency at 64khz
+    wait(0.00001);
+    
+    //pc.printf("Configuration complete"); 
+  return ;
+ 
+ }
+/*****************************************************************************************************************************
+                                               INITIALISE ADS CHANNEL
+ ******************************************************************************************************************************/
+ int Initialize_ADS1x9x_Channel (void){
+     
+    int i,j;
+ 
+ spi.write( WRITE_CHANNEL_1_SET_REGISTER);   //Start at channel register 1
+ wait(WAIT_DSHD);
+spi.write(EIGHT_BYTE_READ_WRITE); //write 8 channels
+wait(WAIT_DSHD);
+ switch(test.gain)
+ {
+     case 1:
+             for ( i = 0; i <= test.num_channels; i++)
+                {
+                     spi.write(GAIN_ONE); //turn on channels
+                     wait(WAIT_DSHD);
+                }
+    case 2:
+            for ( i = 0;i <= test.num_channels ;i++)
+                {
+                     spi.write(GAIN_TWO); //turn on channels
+                     wait(WAIT_DSHD);
+                }        
+    case 3:
+            for ( i = 1; i <= test.num_channels ;i++)
+                {
+                     spi.write(GAIN_THREE); //turn on channels
+                     wait(WAIT_DSHD);
+                }
+    case 4:
+            for (i = 1; i <= test.num_channels; i++)
+                {
+                     spi.write(GAIN_FOUR); //turn on channels
+                     
+                     wait(WAIT_DSHD);
+                }
+        case 6:
+                for (i = 1; i <= test.num_channels; i++)
+            {
+                 spi.write(GAIN_SIX); //turn on channels
+                 wait(WAIT_DSHD);
+                 pc.printf("gain of 6");
+            }
+    case 8:
+                for ( i = 0; i <= test.num_channels ; i++)
+            {
+                 spi.write(GAIN_EIGHT); //turn on channels
+                 wait(WAIT_DSHD);
+            }
+    case 12:
+            for (i = 0; i <= test.num_channels ;i++)
+                {
+                     spi.write(GAIN_TWELVE); //turn on channels
+                     wait(WAIT_DSHD);
+                }
+        
+     }//switch case bracket
+     
+     wait(WAIT_DSHD);
+  for (j = 1; j <= (8 - test.num_channels); j++)
+  {
+       spi.write(INPUT_SHORT); // turn off channels
+       wait(WAIT_DSHD);  
+       pc.printf("turning off channels\n") ;    
+ }
+  wait(wait_time);
+
+ //pc.printf("ADC channels initiaslise\n");
+ return test.num_channels;
+ //Configure right leg drive
+ }
+ 
+ /*******************************************************************************************************************************************
+                                      Low pass filter_coefficents
+The low pass filter uses a 3rd Order butterworth filter to have a 40db attenuation 
+This function calculates the coeffients to be used for the low pass filter 
+inputs:sampling frequency, cut off frequency
+outputs:a pointer to an  array with all the coeffiecents.
+ ********************************************************************************************************************************************/
+ void lpf_coef(void){
+ //calculate prewarped coeficients 
+ static float wp;   //the prewarped frequencies
+ static float coeff[5] = {0};
+ float pi = 3.14159265359;
+ static float a;
+static float b;
+static float* coeff_pointer;
+  
+  a = 0.5*wp*wp;
+  b = 0.5*wp*wp*wp;
+  
+ //user inputs the desired cut off frequency 
+  //pc.printf("enter the desired cut off frequency:");
+ 
+ wp = tan((2*pi *test.lpf_cutoff)/2*test.freq_s);  //prewarped frequency
+
+ coeff[0] = (-1 + wp - a + b)/wp;
+ coeff[1] = (3 -wp -a+3*b)/wp;
+ coeff[2] = (-3 -wp +3*a +3*b)/wp;
+ coeff[3] = (1 + wp + a + b);
+ coeff[4] = wp;
+ }
+ 
+ /*******************************************************************************************************************************************
+                                            Low pass filter
+   ******************************************************************************************************************************************/
+   float lpf( float coeff[5], float lpf_in){
+      
+   static float lpf_out;
+    float y[4];
+    float x[4];
+    
+     
+    x[0] = lpf_in;
+    //moving x and y values by one sample
+     x[3] = x[2]; x[2] = x[1]; x[1] = x[0];
+
+     y[3] = y[2]; y[2] = y[1]; y[1] = y[0]; 
+    
+    //the output is given by:
+    y[0] = (coeff[3]*x[0])+(coeff[2]*x[1])+ (coeff[1]*x[2])+(coeff[0]*x[3]) + (3*y[1])+(3*y[2])+(y[3]);
+    
+    lpf_out = y[0];
+    
+    return lpf_out;
+    
+    }
+          
+     /***************************
+     read the ads channels*/
+     void read(void){
+         int a;
+         int b;
+         volatile int c;
+         
+        
+       spi.write(STOP_READ_DATA_CONTINUOUSLY); //disable conversions to read registers
+          wait(WAIT_DSHD); 
+        
+         spi.write(READ_DEVICE_ID ); //start reading at register 0
+         wait(wait_time2);
+         spi.write(EIGHT_BYTE_READ_WRITE); //read 8 registers
+         //spi.write(0x06);
+           wait(WAIT_DSHD );
+         for (c=1; c<=8; c++){
+             a = spi.write(FETCH_DATA); //send dummy variable to get data
+             wait(WAIT_DSHD);
+             pc.printf("%x\n",a);
+             
+            }
+         wait(wait_time);
+                 
+         }
+         /*********************************************************
+         Interrupt from the DRDY to rad the data from the adc
+         ************************************************************/
+         void ISR1(){
+             //call function read data
+                myled = !myled;
+             
+            
+             for(int i = 0; i <= (test.num_channels+1); i++)
+             {
+              //try changing to wait_time
+              wait(wait_time);
+              test.data_out1[i] = spi.write(FETCH_DATA); //send the dummy variable to recieve the data.
+              wait(wait_time);
+              test.data_out2[i] = spi.write(FETCH_DATA); 
+               wait(wait_time);
+              test.data_out3[i] = spi.write(FETCH_DATA);
+               wait(wait_time);
+              }
+                         
+             test.count = test.count +1;            
+             }
+          
\ No newline at end of file