DDS9959

From Quantum kot
Jump to navigation Jump to search

Features:

  • AD9959 ,4 Channel , 500MSPS, the highest 200M sine wave output;
  • 4-channel independent of frequency, amplitude and phase adjustable;
  • 32-bit accumulator, the frequency resolution is better than 0.12HZ;
  • 14-bit phase register, phase resolution 0.022 degrees;
  • 10-bit amplitude register, fine adjustable amplitude 1024;
  • 2 bands, 4 bands, 8 bands, 16 bands, ASK, PSK, FSK modulation powerful features;
  • Linear frequency, amplitude and phase sweep function;
  • Independently programmable DAC output current;
  • High-speed SPI communication;
  • ADI is fully compatible with the original PC software, control panel USB2.0 interface, easy to use; (Note: Driver support XP, WIN7 32 bit addition WIN7 64 bit and WIN8 may not support;)
  • Low power consumption, etc. victory AD9854 chip, 4-channel 200M Signal tone output, power consumption of only 580mW;

Synchronizing multiple AD9959

Remeber: in a chinese module pins output is mixed. We tried to synchronize two DDSs in automatic mode (p.29 of manual), for this you have to:

In automatic mode, multiple part synchronization is achieved
by connecting the SYNC_OUT pin (pin 2) on the master device to the
SYNC_IN pins(pin 1) of the slave devices. Devices are configured as
master or slave through programming bits, accessible via the
serial port

To program it we have to set the auto sync enable bit (FR2[7]) = 1. To set a device to be the master (slave) device you would set (FR2[6]) = 1 ( (FR2[6]) = 0). This causes the SYNC_OUT of the master device to output a pulse that has a pulse width equal to one system clock period and a frequency equal to one-fourth of the system clock frequency. Unfortunately it was not locking properly for our devices, we had two regimes:

  • they are locked initially, although after some time slave gets unlocked and relocks back with an increasing frequency.
  • they are locked only for a very specific bend(impedance?) of a connecting wire, we were almost unable to catch a subtle difference between two positions.

If the two devices were locked phase noise of the slave device increased.

Single-mode regime


Frequency linear sweep up and down

The program is hidden ->

 

void loop() {
  AD9959_init();//initialization for AD9959
  write_CSR(0xF0);
  write_FR1(0xd0,0x00,0x00); // PLL=20, RU/RD desabled, 2 lvl modulation on all channels
 // write_FR2(0xA0,0x00); //autoclear phase accumulator and  autoclear sweep accumulator are on
  write_CFR(0x80,0x43,0x00); // address 0x03, frequncy modulation select 10 CFR[23:22], linear sweep enable CFR[14]. 
  // 1000 0000   0110 0011   0000 0000
  set_frequency(1000); // address 0x04, initial frequency set in Hz
  set_phase(0); // address 0x05, set phase from 0 to 2, where 2 correponds to two pie
// write_ACR(0x0013ff); //address 0x06, 0x3af   100% modulation 
  //write_LSR(0x00,0x00); // address 0x07, linear sweep ramp rate, delta t
  write_LSR(0xFA, 0xFA); // address 0x07, linear sweep ramp rate, delta t (falling, rising)
  write_RDW(0x00000056); // address 0x08, frequency step, rising delta word
  write_FDW(0x00000036);
  other_frequency(1, 10000000);
 //digitalWrite(DIN_P1,LOW);
 //digitalWrite(DIN_P0,HIGH);
 //digitalWrite(DIN_P0,LOW);
 update();
 while(1)
 {
    delay(5000);
    digitalWrite(DIN_P0,LOW);
    digitalWrite(DIN_P1,LOW);
    digitalWrite(DIN_P2,LOW);
    digitalWrite(DIN_P3,LOW);
    delay(5000);
    digitalWrite(DIN_P0,HIGH);
    digitalWrite(DIN_P1,HIGH);
    digitalWrite(DIN_P2,HIGH);
    digitalWrite(DIN_P3,HIGH);
  }
}

Amplitude sweep up and down

void loop() {

  AD9959_init();              //initialization for AD9959
  write_CSR(0xF0);
  write_FR1(0xd0,0x00,0x00); // PLL=20, RU/RD disabled, 2 lvl modulation on all channels
 //  write_FR2(0xA0,0x00);
  set_frequency(1000000); // address 0x04, initial frequency set in Hz
  set_phase(0); // address 0x05, set phase from 0 to 2, where 2 correponds to two pie
  write_ACR(0x00, 0x00, 0x01); //address 0x06, 0x3af   100% modulation 
  write_CFR(0x40,0x43,0x14); // address 0x03, amplitude modulation select 01 CFR[23:22], linear sweep enable CFR[14]. 
  write_LSR(0x00, 0xFA); // address 0x07, linear sweep ramp rate, delta t (falling, rising)
 write_RDW(0x00800000); // address 0x08, 
 //write_FDW(0x00800000);
 write_ACR_1(0xFF, 0xC0, 0x00);
 update();
 delay(5000);
 digitalWrite(DIN_P1,LOW);
 digitalWrite(DIN_P2,LOW);
 
 delay(5000);
 digitalWrite(DIN_P1,HIGH);
 digitalWrite(DIN_P2,HIGH);

 while(1)
 {

  }
}

Amplitude ramp up and ramp down with profile pins

void loop() {

  AD9959_init();              //initialization for AD9959
  write_CSR(0xF0); //all chanels are engaged f -> 1111
  write_FR1(0xd0,0x08,0x00); // PLL=20, RU/RD enabled FR1[11:10], 2 lvl modulation on all channels FR1[9:8]->00
  //write_CFR(0x40,0x43,0x00); // address 0x03, amplitude modulation select 01 CFR[23:22], linear sweep enable CFR[14]. 
  // 0100 0000   0110 0011   0000 0000
  set_frequency(1000000); // address 0x04, initial frequency set in Hz
  set_phase(0); // address 0x05, set phase from 0 to 2, where 2 correponds to two pie
  write_ACR(0xFA, 0x1b, 0xFF); //address 0x06, 0x3af   100% modulation 
 update();
 delay(15000);
 digitalWrite(DIN_P2,LOW);
 //digitalWrite(DIN_P3,LOW);
 delay(15000);
 digitalWrite(DIN_P2,HIGH);
//digitalWrite(DIN_P3,HIGH);

 while(1)
 {

  }
}

Amplitude ramp up and ramp down with SDIOx pins

Frequency sweep and amplitude RU/RD

How switch amplitude ON and OFF

ACR register

See page 42 of manual, pins 9:0 set amplitude scale of any desired channel. To make it work it is necessary to enable multiplier, example:

ACR(0x00, 0xd0, 0xff)

This program runs for 600 us, if all pins are engaged through DigitalWrite(). Moreover you need to run update, which looks like this:

void update(void)
{
   PIOC->PIO_CODR = (1<<5); 
   delayMicroseconds(1);
   PIOC->PIO_SODR = (1<<5); 
}

Unfortunately, the delay is necessary for AD9959 to catch up. I read that this function even takes minimum 4.5 us (think it is for arduino with 16MHz clock, didn't check it myself). The only way out would be to use assembly function 'nop' (no operation). "Each 'nop' statement executes in one machine cycle (at 16 MHz) yielding a 62.5 ns (nanosecond) delay." Or in our case 84 MHz clock ~12ns.

__asm__("nop\n\t");

This seems to work, not sure about timing yet:

void update(void)
 {
   PIOC->PIO_CODR = (1<<5); 
   __asm__("nop\n\t"); //delayMicroseconds(1);
   PIOC->PIO_SODR = (1<<5); 
 }

Now let's optimize write_ACR. Initially looks as follows:

void write_ACR(unsigned char w_data1,unsigned char w_data2,unsigned char w_data3)
 {
   /*   Amplitude Control Register   */
    digitalWrite(SDIO_3,LOW);
    digitalWrite(CS,LOW);
    write_a_byte(0x06);
    write_a_byte(w_data1);
    write_a_byte(w_data2);
    write_a_byte(w_data3);
    digitalWrite(CS,HIGH);
    digitalWrite(SDIO_3,HIGH);
 }

Ended up with something like this and working together with update() for 12.5us

void write_ACR(unsigned char w_data1,unsigned char w_data2,unsigned char w_data3)
{
 //   Amplitude Control Register 
     PIOA->PIO_CODR = (1<<19); //SDIO3 42 PA19
     PIOB->PIO_CODR = (1<<21); // CS 52 PB21  
     write_a_byte(0x06);
     write_a_byte(w_data1);
     write_a_byte(w_data2);
     write_a_byte(w_data3);
    PIOB->PIO_SODR = (1<<21); // CS 52 PB21 
    PIOA->PIO_SODR = (1<<19);
}

Ramp UP Ramp DOWN

Automatic RURD

Working main program for automatic RURD. ACR register should be set as follows:

  • [23:16] Amplitude ramp rate sets the step in automatic mode, smaller the value faster the sweep.
  • [15:14] Increment/decrement step size, see page 28
  • [12] set "1" for both automatic and manual
  • [11] set "1" for automatic, "0" for manual
  • [10] don't know, is set to 0
  • [9-0] sets maximum amplitude in automatic regime
void loop() {
 AD9959_init();              //initialization for AD9959
 
 write_CSR(0xf0); // make all channels switchable
 write_FR1(0xd0,0x08,0x00);
 write_LSR(0xff, 0x10);
 set_frequency(110e6); // address 0x04, initial frequency set in Hz
 set_phase(0); // address 0x05, set phase from 0 to 2, where 2 correponds to two pie
 write_ACR(0x01, 0xdb, 0xff); //address 0x06, 0x3af   100% modulation 
 //set proper frequencies:
 write_CSR(0x20); // channel 1, red repumper, frequency 90 MHz
 set_frequency(90e6);
 write_CSR(0x40); // channel 2, violet side pump, frequency 44 MHz
 set_frequency(99e6); // 100e6
 write_CSR(0x10); // channel 0, orange side pump, frequency 100 MHz
// write_ACR(0x01, 0xd9, 0xFF);
 set_frequency(56e6); //should be 56
 update();
while(1)
{
 if(digitalRead(Switch_position)==LOW)
 {
    
     digitalWrite(Cavity_lock_C1, HIGH);
     digitalWrite(DIN_P0_C18,HIGH);
     digitalWrite(DIN_P1,HIGH); //red repumping
     digitalWrite(DIN_P2,HIGH); // blue cavity lock
     digitalWrite(DIN_P3,HIGH); //green cooling
     digitalWrite(MOTcoils_C4, HIGH);
     digitalWrite(Cavity_lock_laser_C6, HIGH);
 }
 else {
      
      PIOC->PIO_SODR = CLUSTERmot; //0x00000012;  //     PIOC->PIO_ODSR = CLUSTERmot;    
      PIOA->PIO_CODR = CLUSTERsa;    
      delay(100); // MOT is on for 100 ms             
      PIOC->PIO_CODR = CLUSTERmot;
      PIOA->PIO_SODR = CLUSTERsa;
       timer = 0;
       while (timer < 5000) //should be 5000 
       {
         PIOC->PIO_SODR = CLUSTERside;  //PIOC->PIO_ODSR = CLUSTERside; 
         //update();     
         delayMicroseconds(50);
         PIOC->PIO_CODR = CLUSTERside;
         digitalWrite(SDIO_3, HIGH); 
         //update();
         delayMicroseconds(50);
         timer = timer + 10;
      }    
  }
 }
}