function [awg_trap, success] = initTrapAWG(wfms, awg_trap)

    success = false;

    %Set AWG parameters
    samplerate = awg_trap.samplerate; 
    chAmp = awg_trap.chAmp; 
    memSamples = awg_trap.memSamples; 

    % helper maps to use label names for registers and errors
    mRegs = spcMCreateRegMap();
    mErrors = spcMCreateErrorMap();

    % ----- init card and store infos in cardInfo struct -----
    % This is the place where the AWG internal indexing can sometimes get
    % messed up if you have multiple AWGs and the computer restarts
    [success, cardInfo] = spcMInitCardByIdx(1);

    if success
        % ----- print info about the board -----
        cardInfoText = spcMPrintCardInfo(cardInfo);
        fprintf(cardInfoText);
    else
        spcMErrorMessageStdOut(cardInfo, 'Error: Could not open card\n', true);
        return;
    end

    % ----- set the samplerate and internal PLL, no clock output -----
    [success, cardInfo] = spcMSetupClockPLL(cardInfo, samplerate, 0);  % clock output : enable = 1, disable = 0
    if ~success
        spcMErrorMessageStdOut(cardInfo, 'Error: spcMSetupClockPLL:\n\t', true);
        return;
    end
    fprintf ('\n ..... Sampling rate set to %.1f MHz\n', cardInfo.setSamplerate / 1e6);

    
    % Here are some examples of different triggering methods, either
    % software triggering or hardware triggering with 4V activation
    
    % ----- set software trigger, no trigger output -----
    % [success, cardInfo] = spcMSetupTrigSoftware (cardInfo, 0);  % trigger output : enable = 1, disable = 0
    % if ~success
    %     spcMErrorMessageStdOut (cardInfo, 'Error: spcMSetupTrigSoftware:\n\t', true);
    %     return;
    % end

    %%%%%%%%%
    % ----- extMode = risingEdge, trigTerm = 0, pulseWidth = 0, singleSrc = 1, extLine = 0 -----
    % [success, cardInfo] = spcMSetupTrigExternal (cardInfo, mRegs('SPC_TM_POS'), 0, 0, 1, 0);
    % if ~success
    %     spcMErrorMessageStdOut (cardInfo, 'Error: spcMSetupExternal:\n\t', true);
    %     return;
    % end

%     [success, cardInfo] = spcMSetupTrigExternalLevel (cardInfo, mRegs('SPC_TM_POS'), 4000, 0, 0, 0, 0, 1, 0);
%     if ~success
%         spcMErrorMessageStdOut (cardInfo, 'Error: spcMSetupExternal:\n\t', true);
%         return;
%     end

    %%%%%%%%%

    % ----- program all output channels with no offset and no filter -----
    for ii = 0:(cardInfo.maxChannels-1)
        [success, cardInfo] = spcMSetupAnalogOutputChannel(cardInfo, ii, chAmp(ii + 1), 0, 0, mRegs('SPCM_STOPLVL_ZERO'), 0, 0); % doubleOut = disabled, differential = disabled
        if ~success
            spcMErrorMessageStdOut(cardInfo, 'Error: spcMSetupInputChannel:\n\t', true);
            return;
        end
    end

    % Divide memory in segments
    % ----- setup sequence mode, 1 channel, numMemBlocks segments, start segment 0 -----
    [success, cardInfo] = spcMSetupModeRepSequence(cardInfo, 0, bi2de(awg_trap.active_channels), awg_trap.numMemBlocks, 0); 
    if ~success
        spcMErrorMessageStdOut(cardInfo, 'Error: spcMSetupModeRepSequence:\n\t', true);
        return;
    end

    firstStep = 0;
    changeStep = 1;
    firstSeg = 0;

    % create signal
    signals = [];
    overPowerFlag = false;
    awg_trap.cardInfo = cardInfo;
    for ind = 1:cardInfo.maxChannels
        if awg_trap.active_channels(ind)
            wfm = wfms.(sprintf('ch%i', ind - 1));
            signal = staticArraySignal(wfm, awg_trap);

        else
            signal = zeros(1, memSamples);
        end
        signals = [signals; signal];
    end
    signal_zero = zeros(1,memSamples);

    %Step 1 - Set segments
    % ----- set segment 0 -----
    error = spcm_dwSetParam_i32(cardInfo.hDrv, mRegs('SPC_SEQMODE_WRITESEGMENT'), firstSeg);
    error = spcm_dwSetParam_i32(cardInfo.hDrv, mRegs('SPC_SEQMODE_SEGMENTSIZE'), memSamples);
    errorCode = spcm_dwSetData(cardInfo.hDrv, 0, memSamples, numel(awg_trap.active_channels), 0, ...
        signals(1, :), signals(2, :), signals(3, :), signals(4, :));

    % ----- set segment 1 -----
    error = spcm_dwSetParam_i32(cardInfo.hDrv, mRegs('SPC_SEQMODE_WRITESEGMENT'), 1);
    error = spcm_dwSetParam_i32(cardInfo.hDrv, mRegs('SPC_SEQMODE_SEGMENTSIZE'), memSamples);
    errorCode = spcm_dwSetData (cardInfo.hDrv, 0, memSamples, numel(awg_trap.active_channels), 0, ...
        signal_zero, signals(2, :), signals(3, :), signals(4, :));

    % Step 2 - Set sequence steps
    %                                step, nextStep, segment, loops, condition (0 => End loop always, 1 => End loop on trigger, 2 => End sequence)
    % Understanding how the sequencereplay works on the AWG is crucial to
    % understanding how to effectively program it. See the manual.
    spcMSetupSequenceStep(cardInfo, firstStep, changeStep, firstSeg, 1, 1);
    spcMSetupSequenceStep(cardInfo, changeStep, firstStep, firstSeg, 1, 0);

    
    % Honestly for this next part, it is always a bit of trial and error. I
    % am sure there is a better way to do this though... I've left some
    % things which we don't actually use (like the commandMask syntax) in
    % in case it is useful.
    
    % ----- define series of commands -----
    % commandMask = mRegs('M2CMD_CARD_START');
    % commandMask = bitor (mRegs('M2CMD_CARD_START'), mRegs('M2CMD_CARD_ENABLETRIGGER'));
    % commandMask = bitor (commandMask, mRegs('M2CMD_CARD_WAITREADY'));

    % ----- set series of command -----
    errorCode = spcm_dwSetParam_i32(cardInfo.hDrv, mRegs('SPC_M2CMD'), mRegs('M2CMD_CARD_START'));
    errorCode = spcm_dwSetParam_i32(cardInfo.hDrv, mRegs('SPC_M2CMD'), mRegs('M2CMD_CARD_ENABLETRIGGER'));
    if (errorCode ~= 0)   
        [~, cardInfo] = spcMCheckSetError(errorCode, cardInfo);
        if errorCode == mErrors('ERR_TIMEOUT')
            error = spcm_dwSetParam_i32(cardInfo.hDrv, mRegs('SPC_M2CMD'), mRegs('M2CMD_CARD_STOP'));
            fprintf (' OK\n ................... replay stopped\n');
        else
            spcMErrorMessageStdOut(cardInfo, 'Error: spcm_dwSetParam_i32:\n\t', true);
            return;
        end
    end

    errorCode = spcm_dwSetParam_i32(awg_trap.cardInfo.hDrv, mRegs('SPC_M2CMD'), mRegs('M2CMD_CARD_FORCETRIGGER'));

    awg_trap.cardInfo = cardInfo;
    success = true;

end