%% Test to send longer waveforms to Rigol DG1022
%


%% Settings
visaOutputBufferSize = 2*4096;
nSamples = 1024;


%% Test Instrument Toolbox and VISA, find Rigol DG1022 ID
VisaInf = instrhwinfo('visa');
assert(any(strcmpi(VisaInf.InstalledAdaptors,'ni')),...
    ' ''ni'' visa adaptor must be installed');

% Infos about NI VISA installation - including attached instruments
ViNiInf = instrhwinfo('visa','ni');
Instruments = ViNiInf.ObjectConstructorName;

% Find Instrument with Vendor ID 0x09C4 (ACTiSYS Corp) and PI 0x0400
% which is hopefully a Rigol DG1000 Series
idx = ~cellfun(@isempty,regexpi(Instruments,'USB\d*::0x09C4::0x0400'));
if isempty(idx)
    error('No Rigol DS1000series AWG connected'); 
end
str = Instruments{idx};
visaId = regexpi(str,'USB\S*INSTR','match','once');



%% Connect Instrument
Awg = visa('ni',visaId);
set(Awg,'EosChar','LF')
set(Awg,'EosMode','read')
set(Awg,'OutputBufferSize',visaOutputBufferSize);

% Clean up from previos sessions: Find open instruments and close them
name = get(Awg,'Name');
instr = instrfind('Name',name,'Status','open');
if ~isempty(instr)
    fclose(instr);
end

% Delete all instrument objects except the newly created one:
instr = instrfind('Name',name);
if ~isempty(instr)
    idx = ~(instr==Awg);
    delete(instr(idx));
end

% Open Instrument and perform reset
fopen(Awg);
fprintf(Awg,'*RST');
pause(0.5);
fprintf(Awg,'SYST:ERR?');
fscanf(Awg)

% give the instrument some time to relax
pause(2);


%% Test starts here

% for this test, Awg is the same as Visa Interface objekt. However, later
% on, there will be distinguished.
Visa = Awg;

% Generate some changing wave forms, so that success of write operation can
% be seen directly on the scope.
% Waveform data is in range of 0 to (2^14-1)
fn = testwaveform(nSamples);
plot(fn)


fprintf(Awg,'FUNC USER');
pause(0.5);
fprintf(Awg,'FREQ 50000');
pause(0.5)
fprintf(Awg,'DATA:DEL VOLATILE');
pause(2)
% Command string will be like 'DATA:DAC VOLATILE,100,200,300,300'

% rough estimate of data string length:
% command string + string contaning values + linefeed
strCommand = 'DATA:DAC VOLATILE';
pause(0.25)
fprintf(Awg,'SYST:ERR?');
fgets(Awg)

nCharPerValue = 6; % Max value = 16383 (5chars) + comma
nBytesToSend = numel(strCommand) + numel(fn)*nCharPerValue + 2 %Debug output
outputBufferSize = get(Visa,'OutputBufferSize');
%outputBufferSize = 32;

if nBytesToSend < outputBufferSize
    
    % Everything can be sent at once (because all fits into the output
    % buffer
    % this always works- almost independently of size.
    s = '';
    for i = 2:numel(fn)
        s = [s sprintf(',%i',fn(i))];
    end
    datastr = sprintf('%s%s',strCommand,s);
   fprintf(Awg,'%s\n',datastr);
else
    % Send waveform data in different chunks, since it does not fit into
    % the output buffer
    % this does not work fully - it only overwrites parts of the AWG memory
    
    % switch off Eoimode to allow chunks to be sent without termination
    eoiMode = Visa.EoiMode;
    Visa.EoiMode = 'off';
    
    warning('this may fail');
    
    % prepare waveform data in chunks that can be sent together
    Chunk ={};
    done = 0;
    i = 1;
    while (done<numel(fn))
        if i == 1
            s = [strCommand ','];
            bytesLeft = outputBufferSize-numel(strCommand);
        else
            s = '';
            bytesLeft = outputBufferSize;
        end
        
        nValuesLeft = numel(fn)-done;
        nValuesChunkMax = floor(bytesLeft/nCharPerValue);
        nValuesChunk = min(nValuesLeft,nValuesChunkMax);
        for j = done+(1:nValuesChunk)
            s = [s sprintf('%i,',fn(j))];
        end
        done = done+nValuesChunk;
        Chunk{i} = s;
        i = i+1;
    end
    Chunk{end} = [Chunk{end}(1:end-1)]; % delete trailing comma
    
    % Debug print
    Chunk{:}
    

    for i = 1:numel(Chunk)-1
        fprintf(Awg,'%s',Chunk{i});
    end
    fprintf(Awg,'%s\n',Chunk{end});
    
    % Maybe the instruments needs some time to store that data?
    disp('pause after write')
    pause(15)
    
    % restore old mode
    Visa.EoiMode = eoiMode;
end

pause(1)

fprintf(Awg,'SYST:ERR?');
fgets(Awg)
pause(0.5)
fprintf(Awg,'FUNC:USER VOLATILE')
pause(0.5)
fprintf(Awg,'OUTP ON')
pause(0.5);
fprintf(Awg,'OUTP:SYNC ON')

