classdef (StrictDefaults)CAMERALINKtoVHT_Adapter < matlab.System & ... 
        matlab.system.mixin.Propagates 
    % CAMERALINKtoVHT_Adapter System object
    %
    % Converts the signals F,L,D to control signals compatible with Vision 
    % HDL Toolbox. The conversion injects one cycle of delay, so the pixel
    % data is passed through with the same delay. 
    %
    % [pixel,ctrl] = step(CLAdapter,pixel,F,L,D)
    %
    % Example
    % helpview (doc example)
    %
    %   Copyright 2015 The MathWorks, Inc.
    
    %#codegen
    
    
   
    properties (DiscreteState)
        pixReg;
        FReg;
        LReg;
        DReg;
        FPrevReg;
        LPrevReg;
        % Output registers
        vStartOutReg;
        vEndOutReg;
        hStartOutReg;
        hEndOutReg;
        validOutReg;
        pixOutReg;
    end

    
    methods
        function obj = CAMERALINKtoVHT_Adapter(varargin)
            setProperties(obj,nargin,varargin{:});
        end
        
    end
        
    methods (Access=protected)
       
        function validateInputsImpl(obj,pixel,F,L,D) 
            % control signals need to be logical or double
            validateattributes(F,{'logical','double'},{'scalar'},'CAMERALINKtoVHT_Adapter','F'); 
            validateattributes(L,{'logical','double'},{'scalar'},'CAMERALINKtoVHT_Adapter','L'); 
            validateattributes(D,{'logical','double'},{'scalar'},'CAMERALINKtoVHT_Adapter','D'); 
        end % validateInputsImpl

        function resetImpl(obj)
            obj.FReg = false;
            obj.LReg = false;
            obj.DReg = false;
            obj.FPrevReg = false;
            obj.LPrevReg = false;
            obj.vStartOutReg = false;
            obj.vEndOutReg = false;
            obj.hStartOutReg = false;
            obj.hEndOutReg = false;
            obj.validOutReg = false;
        end

        function setupImpl(obj,pixel,F,L,D) 
            obj.pixReg = cast(0,'like',pixel);
            obj.FReg = F;
            obj.LReg = L;
            obj.DReg = D;
            obj.FPrevReg = false;
            obj.LPrevReg = false;
            obj.pixOutReg = cast(0,'like',pixel);
            obj.vStartOutReg = false;
            obj.vEndOutReg = false;
            obj.hStartOutReg = false;
            obj.hEndOutReg = false;
            obj.validOutReg = false;
        end
        
        %% Main algorithm functionality
        function [pixel_out,ctrl] = stepImpl(obj,pixel,F,L,D)
            % Convert F,L,D signals to Vision HDL Toolbox control signals 

            % send output from output registers
            ctrl = pixelcontrolstruct(obj.hStartOutReg,obj.hEndOutReg,...
                     obj.vStartOutReg,obj.vEndOutReg,obj.validOutReg);
            pixel_out = obj.pixOutReg;
            
            % start of frame
            vStart = obj.FReg && ~obj.FPrevReg;
            % end of frame
            vEnd = ~F && obj.FReg;
            % start of line
            hStart = obj.LReg && ~obj.LPrevReg;
            % end of line
            hEnd = ~L && obj.LReg;
            
            % output register
            obj.vStartOutReg = vStart;
            obj.vEndOutReg = vEnd;
            obj.hStartOutReg = hStart;
            obj.hEndOutReg = hEnd;
            obj.validOutReg = obj.DReg;
            obj.pixOutReg(:) = obj.pixReg;
            
            % store F and L to check for transition
            obj.FPrevReg = obj.FReg;
            obj.LPrevReg = obj.LReg;
            obj.FReg = F;
            obj.LReg = L;
            
            % store other signals to delay along with F and L    
            obj.DReg = D;
            obj.pixReg(:) = pixel;
        
         end

        function N = getNumInputsImpl(obj) %#ok<MANU>
            % Specify number of inputs 
            N = 4;
        end 
        
        function N = getNumOutputsImpl(obj) %#ok<MANU>
            % Specify number of outputs
            N = 2;
        end
        
        %% matlab.system.mixin.Propagates methods
        % assign bus type for use with MATLAB System Block in SL
        function [dt1,dt2] = getOutputDataTypeImpl(obj)
            dt1 = propagatedInputDataType(obj,1);
            dt2 = pixelcontrolbustype;
        end
        
        % required methods if more than 1 output
        function [sz1,sz2] = isOutputFixedSizeImpl(obj)
           sz1 = propagatedInputFixedSize(obj,1);            
           sz2 = propagatedInputFixedSize(obj,2);
        end
        
        function [sz1,sz2] = getOutputSizeImpl(obj)
           sz1 = propagatedInputSize(obj,1);
           sz2 = propagatedInputSize(obj,2);
        end
        function [cp1,cp2] = isOutputComplexImpl(obj)
           cp1 = propagatedInputComplexity(obj,1);
           cp2 = propagatedInputComplexity(obj,2);
        end   
        % required method if there are discretestate properties
        function [sz,dt,cp] = getDiscreteStateSpecificationImpl(obj,name)                                        
           sz = [1 1];
           cp = false;     
           dt = 'logical';                       
           switch(name)
                case {'pixReg','pixOutReg'}
                dt = propagatedInputDataType(obj,1);
           end                    

       end
    end
end % CAMERALINKtoVHT_Adapter
