Implementing AD9959 based on NovaTechDDS9M

97 views
Skip to first unread message

Lufter Reis

unread,
Nov 26, 2023, 2:20:50 AM11/26/23
to the labscript suite
Hi,
I am currently trying to implement my own AD9959 DDS user device through modifying the NovaTechDDS9M code in labscript_device and Matthew's AD9959ArduinoComm. 

* Some background:
I am using an Arduino as an MCU for the AD9959 eval board, supplying reference clock with an Keithley AWG. I am using Prawnblaster as a pseudoclock. I plan to write my AD9959 lab script device as an intermediate device. 

* What I want to achieve:
In Philip's thesis, it seems like we can do the following with the experiment logic file to control the DDS output.

# Connection Table
NovaTechDDS9M(name=’novatechdds9m_0’, parent_device=pulseblaster_0_novatech_clock, com_port=’com8’)

DDS(name=’rb_central_MOT_trap_aom’parent_device=novatechdds9m_0, connection=’channel 1’,digital_gate={’device’:pulseblaster_0.direct_outputs,’connection’:’flag 3’})

# Experiment logic
start()

rb_central_MOT_trap_aom.enable(t)

rb_central_MOT_trap_aom.setfreq(t,rb_central_MOT_trap_frequency MHz)

rb_central_MOT_trap_aom.setamp(t,rb_central_MOT_trap_amplitude 1023.0)

t+=10

rb_central_MOT_trap_aom.disable(t)

t+=1

stop(r)

I assume the above code will enable the DDS output at time t with output duration of 10 seconds. I wish to implement those functions in experiment logic part with my AD9959 if possible.

* Current Status:
The good news is that I can update all the channels in manual state (program_manual, in blacs_workers.py and blacs_tabs.py ). I am now trying to modify the generate_code() method in lab script_device.py and transition_to_buffer() in blacs_workers.py code as attached. But I soon figured out my DDS could't output at the correct timing while running the experiment logic script. 

First of all I've not yet figure out how to TTL trigger each channel separately on AD9959 eval board. I assume sending TTL high at the assigned time t though DDS.enable() will enable the channel output on the correct clock tick provided by the pseudolock. I am planning to send out digital trigger through one of the DigitalOut from NI 6733, but unsure which pin I should connect to on the eval board.

Second, I noticed that in the original implementation of the NovaTechDDS9M, we are packaging the output_table into the h5 shot file. My understanding is that output_table is an array, where each of its element is the output values that we want to send to the AnalogOut when the clock clicks.  In transition_to_buffer() there is a loop that will unpackaged the shot file and go through the output_table and write registers to control the DDS. But I think my code just directly loop through the entire table as fast as it can no matter how the clock clicks. So I am wondering how pseudo clocks actually works in this case?

I am wondering if anybody has comment on those two issues. Anything will be very much appreciated!

Best,
Chun-Wei

labscript_devices.py
blacs_workers.py

Lars Pause

unread,
Nov 27, 2023, 8:08:42 AM11/27/23
to the labscript suite
Dear Chun-Wei,
I have only worked with one-channel AD9910 as triggered labscript device which is directly coupled to a arduino Due (no eval board), so I am not sure how big the differences to your eval-board set-up are (what additional features there could be).
If I understand correctly from your description and the AD9959 manual, you have the arduino to program your AD9959 via serial communication using the Registers 0x00 as well as 0x04 and 0x05. Currently you have a routine to set values manually.
What I did for buffered action (single-channel and frequency values only!) is to program my arduino such that it can switch between manual and buffered mode: In manual mode it waits for a single instruction which is used to program a single channel; In buffered mode, at the beginning, the table (output_table, including all frequencies for this shot) you mention is transfered it into some "memory array" of the arduino and then the arduino waits for triggers. Each trigger results in programming the next frequency tuning word from the array. Depending on your code and the arduino you use, latencies can become large. So you have to check, if this is a problem.
I would assume, that you can use 4 pins of the arduino to register incoming triggers and based on these triggers program the 4 different channels via serial communication using values saved in 4 channel-specific arrays. At first this is totally decoupled from what labscript does.

On Issue 2: In a second step, you can then implement the labscript part to program your arduino with the shot-specific frequency/phase-arrays. The pseudo-clock then just provides your triggers at some point in time.

I hope I understood your issues correct.
Best regards,
Lars

Lufter Reis

unread,
Nov 27, 2023, 11:31:27 AM11/27/23
to the labscript suite
Dear Lars,
Thank you for the comments! 

I originally thought buffering the AD9959 with MCU would be very much similar to those AnalogOut devices in NI cards. But after I took a closer look into why it's been implemented (sending clocklines into AnalogOut), I think there is no easy way to adapt the same architecture. 

So what you suggested make sense! I should consider using the memory array on the Arduino, and just trigger the Arduino instead. I've also found a very useful paper for understanding the power of the AD9959 evalboard. 

Best,
Chun-Wei

Lars Pause 在 2023年11月27日 星期一上午8:08:42 [UTC-5] 的信中寫道:
Reply all
Reply to author
Forward
0 new messages