With the DDS RAM registers a desired function "frequency (time)" can be implemented for one of the output channels and triggered either by the serial terminal or by an external signal on one of the mbed pins.

Dependencies:   mbed

Revision:
7:c186636817d0
Parent:
0:2160f1821475
--- a/main.cpp	Tue Jul 03 08:42:52 2012 +0000
+++ b/main.cpp	Fri Nov 09 16:02:56 2012 +0000
@@ -1,8 +1,5 @@
-// compile --> copy to mbed
-// ALT + B in serial terminal --> break command for mbed
-
 //      ****************************************
-//      *** frequency ramps with the the RAM ***
+//      *** frequency ramps with the RAM ***
 //      ****************************************
 
 #include "mbed.h"
@@ -30,6 +27,8 @@
 double  ref_clock = 400.0e6;
 
 // ##################### definition of functions ############################
+
+// reset the DDS: 
 int reset() {
     rst = 0;
     rst = 1;
@@ -50,22 +49,29 @@
     return 0;
 }
 
+// This function always rounds values up (in mode ?? of the DDS a problem occurs
+// if the final value is not reached
 int round(double a) {
     return int(a + 0.5);
 }
 
+// Calculate the "Frequency Tuning Word (FTWO)" for the DDS registers:
 uint32_t FTWO_func(double frequency) {
     return 0xFFFFFFFF & round(frequency/ref_clock*pow(2.0,32.0));
     }
-    
+
+// RSCW0, RSCW1, RSCW2 and RSCW3 are the RAM profiles of the DDS which can be filled with different
+// parts of the ramp: 
+// ************* RSCW0 ******************    
 void writeRSCW0(int r0, int r1, uint32_t RSCW, double f[]) {
     int         R_used        = r1-r0;
     uint32_t    FTWO[R_used];
     ps0 = 0;
     ps1 = 0; 
     update = 0;
+    // For the structure of the RSCW0 byte see the register map of the DDS.
     // Instruction byte: page 25, we want to write (0), so 0100
-    // + internal adress of the register to be written in
+    // and internal adress of the register to be written in
     DDS._spi.write(0x00 | (0x07 & 0x1F));
     // byte 5: Ramp rate first part
     DDS._spi.write(0xFF & RSCW);
@@ -80,151 +86,118 @@
         update = 1;
         wait_us(10);//5*1/(12.0e6));
         update =0;
-      
+    
+    // The frequency ramp is given as an array of frequencies. Here the frequency tuning 
+    // words (FTWOs) are calculated:  
     i = 0;
     while (i<=(R_used)) {
-        //FTWO[i] = FTWO_func(frequency[i]);
         FTWO[R_used-i] = FTWO_func(f[i]);
-        //pc.printf("written %i %lf \r \n", i, f[i]);
         i += 1;
         }
-
+    // Print start and final value of the RAM part:
     pc.printf("RSCW0 written: %lf %lf \r\n", f[0], f[R_used]);
-        
+    // Select the combination of ps0 and ps1 belonging to RSCW0 and start the RAM writing process:    
     ps0 = 0;
     ps1 = 0; 
-   
+    // Send instruction byte to start the RAM writing process:   
     DDS._spi.write(0x0B);
-    
+    // Write the frequency tuning words into the RAM:
     i = 0;
     while (i<=(R_used)) {
         DDS.RAM_write_FTWO(FTWO[i]);
-       // pc.printf("calculated %d : %x, %f \n", i, FTWO[i], frequency[i]);
         i += 1;
         }
     }
     
+// ************* RSCW1 ******************  
 void writeRSCW1(int r0, int r1, uint32_t RSCW, double f[]) {
     int         R_used        = r1-r0;
     uint32_t    FTWO[R_used];
     ps0 = 1;
     ps1 = 0; 
     update = 0;
-    // Instruction byte: page 25, we want to write (0), so 0100
-    // + internal adress of the register to be written in
     DDS._spi.write(0x00 | (0x08 & 0x1F));
-    // byte 5: Ramp rate first part
     DDS._spi.write(0xFF & RSCW);
-    // byte 4: Ramp rate second part
     DDS._spi.write(0xFF & (RSCW >> 8));
-    // byte 3: final address <7:0>
     DDS._spi.write(0xFF & r1);
-    // byte 2
     DDS._spi.write(((r0 << 2) & 0xFC) | ((r1 >> 8) & 0x03));
-    // byte 1: beginning address <9:6>
     DDS._spi.write(0x20 | (((r0 >> 6) & 0x0F)));
         update = 1;
-        wait_us(10);//5*1/(12.0e6));
+        wait_us(10);
         update =0;
        
     i = 0;
     while (i<=(R_used)) {
-        //FTWO[i] = FTWO_func(frequency[i]);
         FTWO[R_used-i] = FTWO_func(f[i]);
-        //pc.printf("written %i %lf \r \n", i, f[i]);
         i += 1;
-        }
-        
+        } 
     pc.printf("RSCW1 written: %lf %lf \r\n", f[0], f[R_used]);
         
     ps0 = 1;
     ps1 = 0; 
-   
     DDS._spi.write(0x0B);
-    
     i = 0;
     while (i<=(R_used)) {
         DDS.RAM_write_FTWO(FTWO[i]);
-       // pc.printf("calculated %d : %x, %f \n", i, FTWO[i], frequency[i]);
         i += 1;
         }
     }
-    
+
+// ************* RSCW2 ******************     
 void writeRSCW2(int r0, int r1, uint32_t RSCW, double f[]) {
     int         R_used        = r1-r0;
     uint32_t    FTWO[R_used];
     ps0 = 0;
     ps1 = 1; 
     update = 0;
-    // Instruction byte: page 25, we want to write (0), so 0100
-    // + internal adress of the register to be written in
     DDS._spi.write(0x00 | (0x09 & 0x1F));
-    // byte 5: Ramp rate first part
     DDS._spi.write(0xFF & RSCW);
-    // byte 4: Ramp rate second part
     DDS._spi.write(0xFF & (RSCW >> 8));
-    // byte 3: final address <7:0>
     DDS._spi.write(0xFF & r1);
-    // byte 2
     DDS._spi.write(((r0 << 2) & 0xFC) | ((r1 >> 8) & 0x03));
-    // byte 1: beginning address <9:6>
     DDS._spi.write(0x20 | (((r0 >> 6) & 0x0F)));
         update = 1;
-        wait_us(10);//5*1/(12.0e6));
+        wait_us(10);
         update =0;
       
     i = 0;
     while (i<=(R_used)) {
-        //FTWO[i] = FTWO_func(frequency[i]);
         FTWO[R_used-i] = FTWO_func(f[i]);
-        //pc.printf("written %i %lf \r \n", i, f[i]);
         i += 1;
         }
 
-    pc.printf("RSCW0 written: %lf %lf \r\n", f[0], f[R_used]);
-        
+    pc.printf("RSCW0 written: %lf %lf \r\n", f[0], f[R_used]);        
     ps0 = 0;
     ps1 = 1; 
    
     DDS._spi.write(0x0B);
-    
     i = 0;
     while (i<=(R_used)) {
         DDS.RAM_write_FTWO(FTWO[i]);
-       // pc.printf("calculated %d : %x, %f \n", i, FTWO[i], frequency[i]);
         i += 1;
         }
     }
     
-    
+// ************* RSCW3 ****************** 
 void writeRSCW3(int r0, int r1, uint32_t RSCW, double f[]) {
     int         R_used        = r1-r0;
     uint32_t    FTWO[R_used];
     ps0 = 1;
     ps1 = 1; 
     update = 0;
-    // Instruction byte: page 25, we want to write (0), so 0100
-    // + internal adress of the register to be written in
-    DDS._spi.write(0x00 | (0x10 & 0x1F));
-    // byte 5: Ramp rate first part
+    DDS._spi.write(0x00 | (0x0A & 0x1F));
     DDS._spi.write(0xFF & RSCW);
-    // byte 4: Ramp rate second part
     DDS._spi.write(0xFF & (RSCW >> 8));
-    // byte 3: final address <7:0>
     DDS._spi.write(0xFF & r1);
-    // byte 2
     DDS._spi.write(((r0 << 2) & 0xFC) | ((r1 >> 8) & 0x03));
-    // byte 1: beginning address <9:6>
     DDS._spi.write(0x20 | (((r0 >> 6) & 0x0F)));
         update = 1;
-        wait_us(10);//5*1/(12.0e6));
+        wait_us(10);
         update =0;
       
     i = 0;
     while (i<=(R_used)) {
-        //FTWO[i] = FTWO_func(frequency[i]);
         FTWO[R_used-i] = FTWO_func(f[i]);
-        //pc.printf("written %i %lf \r \n", i, f[i]);
         i += 1;
         }
 
@@ -232,17 +205,15 @@
         
     ps0 = 1;
     ps1 = 1; 
-   
     DDS._spi.write(0x0B);
-    
     i = 0;
     while (i<=(R_used)) {
         DDS.RAM_write_FTWO(FTWO[i]);
-       // pc.printf("calculated %d : %x, %f \n", i, FTWO[i], frequency[i]);
         i += 1;
         }
     }
 
+// Function to calculate the RSCW-word used in RSCW1, RSCW2, RSCW3 and RSCW4
 uint64_t RSCW_func(int ram0, int ram1, double trise) {
     int RAM_used = ram1-ram0+1;
     double tmin = 1.0*4.0/ref_clock*RAM_used;       // minimum 1 dwell of time 4/clock at each address
@@ -254,9 +225,12 @@
     return 0xFFFF & dwells;
     }
    
-int counter(double t) {// for t in us
+// The wait-function doesn't offer time resolution of mikroseconds. By using a process like
+// counting up an integer number and measuring the time the mbed needs for this process a time
+// resolution of some tens of nano-seconds can be reached. "counter()" is used in "start_ramp()" 
+// below:
+int counter(double t) {
     int bins = int((t-91.8160e-9)/(41.6664e-9) + 0.5);
-    //pc.printf("bins = %i", bins);
     return bins;
      };
    
@@ -266,7 +240,7 @@
             ps0 = 1;
             ps1 = 0;
             //-----------------------------
-            // NEVER EVER change this loop!
+            // NEVER EVER change this loop! (Allows for time measurement, see above)
             trigger = 0;
             trigger = 1;
             while(i<count){
@@ -277,11 +251,14 @@
             ps0 = 0;
             ps1 = 0;
             i = 0;
+            while(i<count){
+                i += 1;
+            }
     return 0;
     };
    
+// Functions used to select output channel 1 or 2 upon receive of an external trigger signal:
 void check_up(){
-    // try to avoid initialization ramp
     ps0 = 0;
     ps1 = 1;
     ch_1(); DDS.CFR1_write(0x00000200);
@@ -289,7 +266,6 @@
     };
    
 void check_down() {
-    // try to avoid initialization ramp
     ps0 = 0;
     ps1 = 1;
     ch_2(); DDS.CFR1_write(0x00000200);
@@ -297,25 +273,27 @@
     };
 
 // ############################################################
-    
-    
 // ##################### main part ############################
 
 int main() {
 
     pc.printf(" \r \r \n \n ***** frequency sweep with DDS in RAM mode***** \r \r \n \n");
+    pc.printf("Enter: \r \n");
+    pc.printf("'1' or '2' --> select which of the two output channel should be ramped. \r \n");
+    pc.printf("'a' --> frequency ramp with parameters 'trise' and 'tstay' and the frequency values in the mbed code is started and repeated with about 50 Hz. A trigger signal lies on output pin 13 of the mbed. \r \n");
+    pc.printf("'t' --> read in a new value for 'tstay' \r \n");
 
     reset();
     
-    double      tstay           = 500.0e-6;
+    double      tstay           = 50.0e-6;
     
     // intermediate frequencies
-    double      frequency0      = 78.98e6;//100.0e6; // both channels are initiated on this frequency
-    double      frequency1      = 79.02e6;//110.0e6; 
+    double      frequency0      = 79.5e6;// both channels are initiated on this frequency
+    double      frequency1      = 80.5e6;
     // tuning word RSCW0 variables
-    double      trise_00        = 0.1e-6;//20.0e-6;
-    int         ram0_00         = 50;
-    int         ram1_00         = 55;//100; 
+    double      trise_00        = 100e-6;
+    int         ram0_00         = 1;
+    int         ram1_00         = 156; 
     const int   RAM_used_00     = ram1_00 - ram0_00;
     double      f00 [RAM_used_00+1];
     double      frequency_init [1];
@@ -328,33 +306,20 @@
     }
     
     // tuning word RSCW1 variables 
-    double      trise_10        = 0.1e-6;
+    double      trise_10        = 10.0e-6;//0.1e-6;
     int         ram0_10         = 250;
-    int         ram1_10         = 255;//500;
+    int         ram1_10         = 500;
     int         RAM_used_10     = ram1_10-ram0_10; 
     double      f10 [RAM_used_10+1];   
     double      P [RAM_used_10+1];
     
     j = 0;
     while (j<=(RAM_used_10)) {
-        f10[j] = frequency1 + (frequency1-frequency0)/trise_10*j*trise_10/(RAM_used_10);
+        f10[j] = frequency0 + (frequency1-frequency0)/trise_10*j*trise_10/(RAM_used_10);
         j += 1;
     }
-    //### logistic function 
-    /*
-    j = 0;
-    double alpha = log(double((RAM_used_10-1.0)*(RAM_used_10-1.0)))*1/RAM_used_10;
-    pc.printf("alpha %f\r\n",alpha);
-    double beta = 1/alpha*log(double(RAM_used_10-1));
-    pc.printf("beta %f\r\n",beta);
-    while (j<=(RAM_used_10)) {
-        P[j] = 1.0/(1.0+exp(-(j-beta)*alpha));
-        f10[j] = frequency0*(1-P[j]) + frequency1*P[j];
-        j += 1;
-    }
-    f10[0]              = frequency0;
-    f10[RAM_used_10]    = frequency1;
-    pc.printf("P(0) = %f P(RAM_used) = %f \r\n", P[0], P[RAM_used_10]);*/
+    
+    // (Logistic function from below could be added here) 
     
     // ### calculation of RSCW-words ### 
     uint64_t RSCW0 = RSCW_func(ram0_00, ram1_00, trise_00);
@@ -362,7 +327,6 @@
     uint64_t RSCW2 = RSCW_func(501, 501, 10.0e-6);
     
     // ### initialize both channels on the first intermediate frequency and write into their RAM
-
     ch_1();
    
     DDS.CFR1_write(0x00000200);
@@ -378,36 +342,21 @@
     writeRSCW1(ram0_10, ram1_10, RSCW1, f10); 
     writeRSCW0(ram0_00, ram1_00, RSCW0, f00);
     writeRSCW2(501, 501, RSCW2, frequency_init);
-    /*
-    DDS.ASF_write(0xFFFF);
-    DDS.ARR_write(0xFF);
-    DDS.CFR1_write(0x84000200);
-    DDS.CFR1_write(0x80000200);
-    */
+
     //pc.printf("enter: \r \n 'u' to trigger ramp up \r \n 'd' to trigger ramp down \r \n 't' to enter new ramp time \r \n 's' for new start frequency \r \n 'e' for new end frequency \r \n");
     char up_or_down = '0';
-    double trise = trise_00;
-    
+    double trise = trise_00;  
     
     while(1) {
             if(pc.readable()) {
                 up_or_down = pc.getc();
                 if(up_or_down == 'a') {
+                    pc.printf("a --> ramp started");
                     while(1) {
                         start_ramp(trise, tstay);
                         wait(2e-2);
                         if(pc.readable()) break;
                         }
-                    //start_ramp(trise, tstay);
-                    //pc.printf("sequence over ST \r \n");
-                    }
-                /*if (up_or_down == 'r') {
-                    pc.printf("enter new time value in us: \n");
-                    pc.scanf("%lf", &trise);
-                    trise = trise*1.0e-6;
-                    initialize(frequency0, frequency1, RAM_start, RAM_final, trise);
-                    check_down();
-                    }*/
                  if (up_or_down == 't') {
                     pc.printf("enter new tstay value in us: \n");
                     pc.scanf("%lf", &tstay);
@@ -466,8 +415,11 @@
                     initialize(frequency0, frequency1, RAM_start, RAM_final, trise);
                     }*/
             }
+            // Wait for a rising or falling edge on the mbed-mcs pin and select accordingly channel 1 or 
+            // channel 2 for ramping
             mcs.rise(&check_up);
             mcs.fall(&check_down);
+            // start the ramp when a signal sets the mbed pin 'mexp' to '1'
             if(mexp) {
                     while(mexp);
                     start_ramp(trise, tstay);
@@ -478,4 +430,19 @@
     return 0;
 }
 
+    /* LOGISTIC FUNCTION
+    j = 0;
+    double alpha = log(double((RAM_used_10-1.0)*(RAM_used_10-1.0)))*1/RAM_used_10;
+    pc.printf("alpha %f\r\n",alpha);
+    double beta = 1/alpha*log(double(RAM_used_10-1));
+    pc.printf("beta %f\r\n",beta);
+    while (j<=(RAM_used_10)) {
+        P[j] = 1.0/(1.0+exp(-(j-beta)*alpha));
+        f10[j] = frequency0*(1-P[j]) + frequency1*P[j];
+        j += 1;
+    }
+    f10[0]              = frequency0;
+    f10[RAM_used_10]    = frequency1;
+    pc.printf("P(0) = %f P(RAM_used) = %f \r\n", P[0], P[RAM_used_10]);*/
 
+