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.
main.cpp
- Committer:
- ahambi
- Date:
- 2012-07-04
- Revision:
- 5:e7337b47f372
- Parent:
- 1:dfbf1ff7562f
File content as of revision 5:e7337b47f372:
// compile --> copy to mbed // ALT + B in serial terminal --> break command for mbed // **************************************** // *** frequency ramps with the the RAM *** // **************************************** #include "mbed.h" #include "DDS.h" Serial pc(USBTX, USBRX); DigitalOut myled(LED1); DigitalOut cs2(p11); DigitalOut cs1(p8); DigitalOut rst(p9); DigitalOut update(p10); DigitalOut ps0(p12); DigitalOut ps1(p14); DigitalOut trigger(p13); DigitalOut trigger1(p23); DigitalOut trigger2(p24); InterruptIn mcs(p21); //InterruptIn description: http://mbed.org/handbook/InterruptIn DigitalIn mexp(p22); //DigitalIn description: http://mbed.org/handbook/DigitalIn DDS DDS(p5, p6, p7, p8, p9, p10); // counting variables: int i = 0; int j = 0; // frequency of reference clock connected to the DDS board: double ref_clock = 400.0e6; // ##################### definition of functions ############################ int reset() { rst = 0; rst = 1; wait(0.1); rst = 0 ; return 0; } // choosing one of the two output channels is done with this functions: int ch_1() { cs1 = 0; cs2 = 1; return 0; } int ch_2() { cs1 = 1; cs2 = 0; return 0; } int round(double a) { return int(a + 0.5); } uint32_t FTWO_func(double frequency) { return 0xFFFFFFFF & round(frequency/ref_clock*pow(2.0,32.0)); } 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; // Instruction byte: page 25, we want to write (0), so 0100 // + 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); // 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)); 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]); ps0 = 0; 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; } } 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)); 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; } } 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)); 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]); 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; } } 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(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)); 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]); 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; } } 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 double tmax = 65535.0*4.0/ref_clock*RAM_used; // 16 bit register corresponding to 65535 dwells if (trise < tmin) { pc.printf("ERROR: ramp time too small. Minimum: %f \r \n", tmin); }; if (trise > tmax) { pc.printf("ERROR: ramp time too large. Maximum: %f \r \n", tmax); }; int dwells = round(trise/(4.0/ref_clock*RAM_used)); pc.printf(" %i dwells at each address ---> %f ramp time. \r \n", dwells, dwells*RAM_used*4.0/ref_clock); return 0xFFFF & dwells; } int counter(double t) {// for t in us int bins = int((t-91.8160e-9)/(41.6664e-9) + 0.5); //pc.printf("bins = %i", bins); return bins; }; int start_ramp(double trise, double tstay) { int i = 0; int count = counter(trise+tstay); ps0 = 1; ps1 = 0; //----------------------------- // NEVER EVER change this loop! trigger = 0; trigger = 1; while(i<count){ i += 1; } trigger = 0; //----------------------------- ps0 = 0; ps1 = 0; i = 0; return 0; }; void check_up(){ // try to avoid initialization ramp ps0 = 0; ps1 = 1; ch_1(); DDS.CFR1_write(0x00000200); ch_2(); DDS.CFR1_write(0x80000200); }; void check_down() { // try to avoid initialization ramp ps0 = 0; ps1 = 1; ch_2(); DDS.CFR1_write(0x00000200); ch_1(); DDS.CFR1_write(0x80000200); }; void PhaseRAM(int r0, int r1, double phase0, double phase1, double trise) { const int RAM_used = r1-r0; uint64_t RSCW; RSCW = RSCW_func(r0, r1, trise); uint32_t PHWO[RAM_used+1]; double phase [RAM_used+1]; while (j<=(RAM_used)) { phase[j] = phase0 + (phase1-phase0)/trise*j*trise/RAM_used; PHWO[j] = 0x3FFF & int(phase[j]/360.0*pow(2.0,14.0)); // PHWO = 0011 FFF = 3FFF // 0x3FFF = 16383 maximum phase is 359.97� j += 1; } ps0 = 0; 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 | (0x10 & 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(0x40 | (((r0 >> 6) & 0x0F))); update = 1; wait_us(10);//5*1/(12.0e6)); update =0; DDS._spi.write(0x0B); int i=0; while (i<=(RAM_used-1)) { // RAM <31:18> shall contain the PHWO DDS.RAM_write_FTWO((PHWO[i] << 18) & 0xFFFFFFFF); i += 1; } // Phase Ramp with channel 1 ch_2(); DDS.CFR1_write(0x00000200); ch_1(); DDS.CFR1_write(0xC0000200); } // ############################################################ // ##################### main part ############################ int main() { pc.printf(" \r \r \n \n ***** frequency sweep with DDS in RAM mode***** \r \r \n \n"); reset(); double tstay = 500.0e-6; // intermediate frequencies double frequency0 = 78.98e6;//100.0e6; // both channels are initiated on this frequency double frequency1 = 79.02e6;//110.0e6; // tuning word RSCW0 variables double trise_00 = 0.1e-6;//20.0e-6; int ram0_00 = 50; int ram1_00 = 55;//100; const int RAM_used_00 = ram1_00 - ram0_00; double f00 [RAM_used_00+1]; double frequency_init [1]; frequency_init[0] = frequency0; j = 0; while (j<=(RAM_used_00)) { f00[j] = frequency1 - (frequency1-frequency0)/trise_00*j*trise_00/(RAM_used_00); j += 1; } // tuning word RSCW1 variables double trise_10 = 0.1e-6; int ram0_10 = 250; int ram1_10 = 255;//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); 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]);*/ // ### calculation of RSCW-words ### uint64_t RSCW0 = RSCW_func(ram0_00, ram1_00, trise_00); uint64_t RSCW1 = RSCW_func(ram0_10, ram1_10, trise_10); 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); DDS.FTW0_write(FTWO_func(frequency0)); /*writeRSCW1(ram0_10, ram1_10, RSCW1, f10); writeRSCW0(ram0_00, ram1_00, RSCW0, f00); writeRSCW2(501, 501, RSCW2, frequency_init);*/ ch_2(); DDS.CFR1_write(0x00000200); DDS.FTW0_write(FTWO_func(frequency0)); /* 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; while(1) { if(pc.readable()) { up_or_down = pc.getc(); if(up_or_down == 'a') { 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 == 'p') { PhaseRAM(0, 10, 0.1, 359, 1e-3); // int r0, int r1, double phase0, double phase1, double trise) while(1) { trigger = 0; trigger = 1; ps0 = 1; wait(5e-3); trigger = 0; ps0 = 0; wait(5e-3); if(pc.readable()) break; } } if (up_or_down == 't') { pc.printf("enter new tstay value in us: \n"); pc.scanf("%lf", &tstay); tstay = tstay*1.0e-6; } if (up_or_down == 'u') { pc.printf("u"); trigger = 1; wait(trise/4.0); trigger = 0; ///// ps0 = 1; ps1 = 0; ///// } if (up_or_down == 'd') { pc.printf("d"); trigger = 1; wait(trise/4.0); trigger = 0; ///// ps0 = 0; ps1 = 0; ///// } if (up_or_down == '1') { trigger = 0; trigger = 1; /*ps0 = 0; ch_2(); DDS.CFR1_write(0x00000200); ch_1(); DDS.CFR1_write(0x80000200);*/ check_down(); trigger = 0; pc.printf("ramping channel 1 \r\n"); } if (up_or_down == '2') { trigger = 0; trigger = 1; /*ps0 = 0; ch_1(); DDS.CFR1_write(0x00000200); ch_2(); DDS.CFR1_write(0x80000200);*/ check_up(); trigger = 0; pc.printf("ramping channel 2 \r\n"); } /*if (up_or_down == 's') { pc.printf("enter new frequency0 value in MHz: \n"); pc.scanf("%lf", &frequency0); frequency0 = frequency0*1.0e6; initialize(frequency0, frequency1, RAM_start, RAM_final, trise); }*/ /*if (up_or_down == 'e') { pc.printf("enter new frequency1 value in MHz: \n"); pc.scanf("%lf", &frequency1); frequency1 = frequency1*1.0e6; initialize(frequency0, frequency1, RAM_start, RAM_final, trise); }*/ } mcs.rise(&check_up); mcs.fall(&check_down); if(mexp) { while(mexp); start_ramp(trise, tstay); // pc.printf(" exp trigger in registered \r \n"); } } return 0; }