%% 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);
