function [] = AWG4k_Send_Wfm_Binary_Block(obj,Waveform_Name,StartIndex,Analog_Waveform,Digital_Waveform,Digital_Mode)
%[] = AWG4k_Send_Wfm_Binary_Block(obj,Waveform_Name,StartIndex,Analog_Waveform,Digital_Waveform,Digital_Mode)
%
%This function loads a waveform from Matlab workspace to AWG memory using
%the Binary Block.
%The parameters are:
%- obj: VISA object. 
%- Waveform_Name: the name of the waveform in the AWG waveform list.
%- StartIndex: the position in the waveform where add the current block.
%- Analog_Waveform: N_Samples x 1 matrix that contains the analog waveform
%samples.
%- Digital_Waveform: N_Samples x 8 or N_Samples x 16 matrix that contains
%the digital data, only 0 and 1 admitted.
%- Digital_Mode: HighSp for high speed, LowSp for low speed, None for
%analog only.
%
%%Note: the matrix dimension must be N_Samples x 1 for the analog waveform
%and N_Samples x 8 or N_Samples x 16 for the digital waveform.
%If 'LowSp' is selected the number of columns of the digital waveform must
%be a quarter of the number of columns of the analog waveform.
%If 'HighSp' is selected the number of columns of the digital waveform must
%be half the number of row of the analog waveform.
%
%Example:
% AWG4k_Send_Mixed_Wfm_Binary_Block(obj,'Mixed_Ramp',0,Ramp,Counter,'LowSp');


%Create a new waveform with the length of the analog waveform
Wfm_Length = length(Analog_Waveform);
strCmd=sprintf('WLIST:WAVeform:NEW "%s",%d',Waveform_Name,Wfm_Length);
fprintf(obj, '%s',strCmd);

%Insert string command
byteCmd = uint8(sprintf('WLIST:WAVEFORM:DATA "%s",%d,%d,#',Waveform_Name,StartIndex,Wfm_Length));
CmdLength = length(byteCmd);

%Check if the input data meets the digital speed
switch lower(Digital_Mode)
    case 'none'
        mode = 0;
    case 'lowsp'
        [m,n] = size(Digital_Waveform);
        if (m == 16) && (n * 4 == Wfm_Length)
            mode = 1;
        else
            mode = 0;
        end
    case 'highsp'
        [m,n] = size(Digital_Waveform);
        if (m == 8) && (n * 2 == Wfm_Length)
            mode = 2;
        else
            mode = 0;
        end
    otherwise
        mode = 0;
end

Analog_Waveform = single(Analog_Waveform);
Digital_Waveform = logical(Digital_Waveform);

%Fill a buffer depending on the digital option
switch mode
    case 0 %Analog
        
        LengthByte = 4 * Wfm_Length;
        strLengthByte = sprintf('%d',LengthByte);
        LengthFieldSize = length(strLengthByte);
        strLengthFieldSize = sprintf('%d',length(strLengthByte));
        TotalCommandLength = CmdLength + 1 + LengthFieldSize + LengthByte;
        ByteArray = zeros(1,TotalCommandLength,'uint8');
        
        %Copy the string into array
        ByteArray(1:CmdLength) = byteCmd;
        
        %Write the size of the "Length" field
        ByteArray(CmdLength + 1) = uint8(strLengthFieldSize);
        
        %Write the Length in byte
        ByteArray(CmdLength+2 : CmdLength+2+LengthFieldSize-1) = uint8(strLengthByte);
        
        %If the PC is Big endian swap the byte
        [~,~,endianess] = computer;
        if endianess ~= 'L'
            Analog_Waveform = swapbytes(Analog_Waveform);
        end
        
        %Write the analog data
        ByteArray(CmdLength+2+LengthFieldSize : TotalCommandLength) = typecast(Analog_Waveform,'uint8');
        
        %Send the data to the instrument
        fwrite(obj,ByteArray,'uint8');
    
    case 1 %Low Speed
        
        LengthByte = 6 * Wfm_Length;
        strLengthByte = sprintf('%d',LengthByte);
        LengthFieldSize = length(strLengthByte);
        strLengthFieldSize = sprintf('%d',length(strLengthByte));
        TotalCommandLength = CmdLength + 1 + LengthFieldSize + LengthByte;
        ByteArray = zeros(1,TotalCommandLength,'uint8');
        
        %Copy the string into array
        ByteArray(1:CmdLength) = byteCmd;
        
        %Write the size of the "Length" field
        ByteArray(CmdLength + 1) = uint8(strLengthFieldSize);
        
        %Write the Length in byte
        ByteArray(CmdLength+2 : CmdLength+2+LengthFieldSize-1) = uint8(strLengthByte);
        
        %If the PC is Big endian swap the byte
        [~,~,endianess] = computer;
        if endianess ~= 'L'
            Analog_Waveform = swapbytes(Analog_Waveform);
        end
        
        Analog_Waveform_byte = typecast(Analog_Waveform,'uint8');
       	Analog_Waveform_byte_4xn = reshape(Analog_Waveform_byte, 4, Wfm_Length);
        Digital_Waveform_u16 = uint16(bi2de(Digital_Waveform'))';
        Digital_Waveform_byte = typecast(Digital_Waveform_u16,'uint8');
        Digital_Waverorm_byte_2xn = reshape(Digital_Waveform_byte, 2, floor(Wfm_Length/4));
        Digital_Waverorm_byte_2xn_rep = kron(Digital_Waverorm_byte_2xn, ones(1,4,'uint8'));%Repeat 4 times the element of the row
        Mixed_Waveform_6xn = vertcat(Analog_Waveform_byte_4xn, Digital_Waverorm_byte_2xn_rep);
        ByteArray(CmdLength+2+LengthFieldSize:end) = reshape(Mixed_Waveform_6xn, 1, 6*Wfm_Length);
        
        %Send the data to the instrument
        fwrite(obj,ByteArray,'uint8');
    
        
    case 2 %High Speed
        
        LengthByte = 6 * Wfm_Length;
        strLengthByte = sprintf('%d',LengthByte);
        LengthFieldSize = length(strLengthByte);
        strLengthFieldSize = sprintf('%d',length(strLengthByte));
        TotalCommandLength = CmdLength + 1 + LengthFieldSize + LengthByte;
        ByteArray = zeros(1,TotalCommandLength,'uint8');
        
        %Copy the string into array
        ByteArray(1:CmdLength) = byteCmd;
        
        %Write the size of the "Length" field
        ByteArray(CmdLength + 1) = uint8(strLengthFieldSize);
        
        %Write the Length in byte
        ByteArray(CmdLength+2 : CmdLength+2+LengthFieldSize-1) = uint8(strLengthByte);
        
        %If the PC is Big endian swap the byte
        [~,~,endianess] = computer;
        if endianess ~= 'L'
            Analog_Waveform = swapbytes(Analog_Waveform);
        end
        
        Analog_Waveform_byte = typecast(Analog_Waveform,'uint8');
       	Analog_Waveform_byte_4xn = reshape(Analog_Waveform_byte, 4, Wfm_Length);
        
        %Add the high byte
        Digital_Waveform = vertcat(Digital_Waveform, false(8, Wfm_Length/2));
        
        Digital_Waveform_u16 = uint16(bi2de(Digital_Waveform'))';
        Digital_Waveform_byte = typecast(Digital_Waveform_u16,'uint8');
        Digital_Waverorm_byte_2xn = reshape(Digital_Waveform_byte, 2, floor(Wfm_Length/2));
        Digital_Waverorm_byte_2xn_rep = kron(Digital_Waverorm_byte_2xn, ones(1,2,'uint8'));%Repeat 2 times the element of the row
        Mixed_Waveform_6xn = vertcat(Analog_Waveform_byte_4xn, Digital_Waverorm_byte_2xn_rep);
        ByteArray(CmdLength+2+LengthFieldSize:end) = reshape(Mixed_Waveform_6xn, 1, 6*Wfm_Length);
        
        
        %Send the data to the instrument
        fwrite(obj,ByteArray,'uint8');
end


end

