Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
%% Define awg structure and init
if ~exist('awg_trap', 'var') || ~isfield(awg_trap, 'running') || ~awg_trap.running
awg_trap = struct();
awg_trap.active_channels = [1, 1, 0, 0];
% Here you set which channels of the AWG you are using.
% Note that the only available options are 1, 1+2, 1+2+3+4
awg_trap.chAmp = [2500, 1320, 2500, 2500];
% mVp. Max possible 2500mVp, min 80mVp.
awg_trap.samplerate = 614.4e6;
% Maximum of 625e6, must be multiple of 512
awg_trap.numMemBlocks = 8192;
% Must be power of 2. In general, for the maximum array size
% you want to rearrange with BubbleSort, N, this should be at least N*(N+2).
% If not using BubbleSort just set to maybe 32.
awg_trap.freq_resolution = 100e3;
% GCD of trap frequencies. If you make an array with a different
% frequency resolution, then it might fail because when the waveform
% tries to loop there will be a phase jump (which kills the atoms)
awg_trap.memSamples = 512 * 240;
% Define memory in number of samples.
% First factor must be 512. Other factor must be an even integer multiple of
% the sampling rate / (freq_resolution * 512) , such that
% the total memSamples < 2^31/numMemBlocks/numActiveChannels.
% 2^31 comes from the total AWG memory limit. Note that the
% requirements here are again to avoid phase jumps.
awg_trap.running = false;
else
fprintf('To change these parameters you must turn the AWG off first!\n');
end
%% Init
[awg_trap, success] = initTrapAWG(wfms, awg_trap);
if success
awg_trap.running = true;
end
if awg_trap.cardInfo.serialNumber ~= 11198
% When using a system with multiple AWGs, sometimes the internal awg
% indexing gets switched around when the computer restarts - to avoid
% outputting the wrong signal to the wrong card, we make sure we are
% talking to the correct serial number.
fprintf('Talking to serial number %i', awg_trap.cardInfo.serialNumber);
disp('This is the wrong card! Turn it off immediately and diagnose!');
end
%% Update
if awg_trap.running
awg_trap = updateTrapAWG(wfms, awg_trap);
if isfield(wfms, 'name')
fprintf('Updating to %s\n', wfms.name);
else
fprintf('Updating to unnamed wfms\n');
end
else
fprintf('AWG must be running to update!\n');
end
%% Stop
% Look out, because oftentimes if a bug happens with the AWG initialization
% or termination it will hard crash MATLAB. The "running" variable tries to
% help this, but is not perfect.
if awg_trap.running
stopTrapAWG(awg_trap);
awg_trap.running = false;
else
fprintf('AWG is already off!\n');
end
%% Generate naive waveforms
% Schematic for how to generate an array of tweezers for two crossed AODs.
wfms = struct();
% Ch 0 (Old AOD)
numTweezers_0 = 67;
f0_0 = 98.2e6;
df_0 = 750e3;
ampScaling_0 = 0.25; % DO NOT EXCEED 0.25 when chAmp(1) = 2500mVp.
wfms.ch0 = staticArrayWfm(numTweezers_0, f0_0, df_0, ampScaling_0);
% Ch 1 (New AOD)
numTweezers_1 = 1;
f0_1 = 97e6;
df_1 = 10 * 350e3;
ampScaling_1 = 0.25; % DO NOT EXCEED 0.25 when chAmp(2) = 1320mVp.
wfms.ch1 = staticArrayWfm(numTweezers_1, f0_1, df_1, ampScaling_1);
wfms.name = sprintf('wfms_%d_%0.0f_%d_%0.0f_%s', numTweezers_0, df_0 / 1e3, numTweezers_1, df_1 / 1e3, '000');
%% Check current AWG step
% There are lots of "GetParam_i32" calls which are very useful. See the
% manual and programming guide for more information. For instance, this
% call returns the current block of memory the AWG is outputting.
[~,currentStep] = spcm_dwGetParam_i32(awg_trap.cardInfo.hDrv, mRegs('SPC_SEQMODE_STATUS'));
fprintf('AWG is currently on step %d\n',currentStep);
%% Identify the card
% This will make a little light blink on the back of the card, useful when
% working with multiple AWGs
mRegs = spcMCreateRegMap();
error = spcm_dwSetParam_i32(awg_trap.cardInfo.hDrv, mRegs('SPC_CARDIDENTIFICATION'), 0);