DDS9959
Contents
- 1 Features:
- 2 Synchronizing multiple AD9959
- 3 Single-mode regime
- 4 Frequency linear sweep up and down
- 5 Amplitude sweep up and down
- 6 Amplitude ramp up and ramp down with profile pins
- 7 Amplitude ramp up and ramp down with SDIOx pins
- 8 Frequency sweep and amplitude RU/RD
- 9 How switch amplitude ON and OFF
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 ->
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;
}
}
}
}