% FSU_AMIQ.m

% This script demonstrates IQ data acquisition with FSP/FSU using MEXRSIB LAN remote control
%   
%   The acquired data is converted to AMIQ format and written to a file SINE.WV
%   Together with the attached file AUTOEXEC.IEC, it can be stored on a floppy disk.
%   If this floppy disk is inserted in the AMIQ at boot time, it loads the waveform automatically.

% The following section describes the structure of waveform data for AMIQ

%
%      GENERATION OF A WAVEFORM DATA SET FOR AMIQ 
%                 ============================================ 
%
%            The program generates a data set to output a sine 
%            and cosine wave at the I and Q outputs of AMIQ. 
%            The sine and cosine values range from -1 to 0 to +1. 
%            To transfer the values to AMIQ they must be converted into 
%            binary format consisting of integer 16-bit-wide numbers without a sign. 
%
%                         + 1 ---> 64768 
%                              ... 
%                           0 ---> 32768 
%                              ... 
%                         - 1 --->   768 
%
%            Before this binary data set can be processed further, 
%            the TYPE tag {TYPE: WV, xxxxxxx} must be placed in front. 
%            The TYPE tag must be the first entry in a WAVEFORM file. 
%            WV means that the file contains a curve which is closed upon 
%            itself. 
%            xxxxxxx is the checksum of the waveform file. To simplify 
%            our example, 0 is used, i.e. AMIQ does not evaluate a checksum. 
%
%            The binary data must now be packed into a WAVEFORM tag with 
%            the following structure: 
%            {WAVEFORM-Length: Start,# IQIQIQIQIQIQIQIQIQI ... IQ} 
%
%            The WAVEFORM tag consists of the following characters and data: 
%            {            Opens each tag. 
%            WAVEFORM     Name of the tag for waveform files. 
%            -            Separates the name from the length indication. 
%            Length       Length of the data set 
%                           Length indicates the number of bytes of the 
%                           data set and consists of: 
%                           number of digits of the start value 
%                           (1 to 7, in our example 1) 
%                           + length of ",#" (2 bytes) 
%                           + number of I/Q pairs * 4 (2 bytes for each 
%                                                       I and Q value). 
%            :             Separates the name and length from the remainder 
%                          of the data set. The blank can be omitted. 
%            Start         Address in the output memory of AMIQ used to 
%                          store the following samples. In our example and 
%                          most applications, this will be '0'. 
%            ,#            Indicates the beginning of the binary data. 
%            IQIQIQ        Binary data set. 
%                          The binary data contain the I and Q values in 
%                          alternate order. The first value is an I value. 
%                          Each value consists of 2 bytes, starting with 
%                          the least significant bit. 
%            }             Terminates each tag. 
%
%
%            The tags TYPE and WAVEFORM are mandatory for each waveform 
%            file. All other tags can be inserted after the TYPE tag in 
%            arbitrary order, e.g. 
%                  {TYPE: WV,0} 
%                  {COMMENT: I/Q=sine/cosine, 20 points, clock 10 MHz} 
%                  {CLOCK: 10e6} 
%                  {FILTER: 2,5MHz} 
%                  {WAVEFORM-83: 0,# IQIQIQIQIQIQ ... IQ} 
%          *) 
%
%
%          const 
%              STEPS      = 20;                 (* Range 0 to 3.14 divided into 20 steps 
%          *) 

% Clear and close previous objects
clear all;close all

% Some useful defines
FNAME      = 'Sine.WV';          %(* Output file *) 
HEADTEXT   = '{TYPE: WV, 0}';    %(* Header in file *) 
CLOCKTEXT  = '{CLOCK: 4e6}';     %(* optional *) 
FILTERTEXT = '{FILTER: 2,5MHz}'; %(* optional *) 
WAVETEXT1  = '{WAVEFORM-';       %(* Start of waveform data *) 
WAVETEXT3  = ': 0,#';            %(* Waveform data *) 
ENDETEXT   = '}';                %(* End of waveform data *) 


% Declare buffers for real and imag data
blocklen= 10000     
dat_re=zeros(1,blocklen);
dat_im=zeros(1,blocklen);
s=zeros(1,blocklen);

% Specify datarate
datarate=4e6              
    
% Clear buffers
clear dat_re dat_im y

% Open connection to instrument
ud=mexrsib('ibfind', '89.10.66.41')

% Check if connected     
if ud > 0
    % Set timeout
    mexrsib('ibtmo',ud,5)
    
    % Select binary transfer
    mexrsib('ibwrt',ud,'FORM:DATA REAL,32')
        
    % Turn IQ data transfer on and set parameters for sampling
    mexrsib('ibwrt',ud,'TRACE1:IQ ON');
    mexrsib('ibwrt',ud, strcat('TRACE1:IQ:SET NORMAL,1MHZ,',sprintf('%5.4f',datarate),' Hz,IMM,POS,0,',sprintf('%d',blocklen)));

    % Request IQ data from FSP
    mexrsib('ibwrt',ud,'TRACE1:IQ:DATA? ');

    % Read header of binary block data
    header=mexrsib('ilrd',ud,2)
    
    % Get length of data length prefix
    digits=sscanf(header(2),'%f')    
    
    % Read data length information
    l=mexrsib('ilrd',ud,digits)
        
    
    % Now read I data
    dat_re=mexrsib('ilrd32',ud, blocklen);
    
    % ... and Q data
    dat_im=mexrsib('ilrd32',ud, blocklen);
    
    % Convert into complex array
    s=dat_re+j.*dat_im;
    mexrsib('ibloc',ud)
    
end

length(s)

% Reduce size for floppy disk
s=s(1:end/2);
length(s)

% Convert data according to description in the header section
s_max=max(abs(s));
s_norm=s./s_max;
s_norm2_re = uint16(64000.0 *(real(s_norm)+1.0)./2+768.0);
s_norm2_im = uint16(64000.0 *(imag(s_norm)+1.0)./2+768.0);
buffer=zeros(1,length(s_norm2_re)*2);

% Combine complex IQ data into one array IQIQIQ...
buffer(1:2:end)=s_norm2_re;
buffer(2:2:end)=s_norm2_im;
buffer=uint16(buffer);

% Open file for binary reading
outfile=FNAME;
fid = fopen(outfile,'wb');

% Write header info
line	= sprintf('%s', HEADTEXT)
fwrite(fid, line,'uint8');

line	= sprintf('%s', CLOCKTEXT)
fwrite(fid, line,'uint8');

line	= sprintf('%s', FILTERTEXT)
fwrite(fid, line,'uint8');

line	= sprintf('%s', WAVETEXT1)
fwrite(fid, line,'uint8');
    

% Write data length in byte
line	= sprintf('%d', length(s_norm2_re)*4+3)
fwrite(fid, line,'uint8');

line	= sprintf('%s', WAVETEXT3)
fwrite(fid, line,'uint8');

% Write buffer
fwrite(fid,buffer(1:end),'uint16');

line	= sprintf('%s', ENDETEXT);
fwrite(fid, line,'uint8');

% ...and close
fclose(fid);

'...finished'