function [hStartO,hEndO,vStartO,vEndO,validO, outputData, Unloading, BlankCountEn, Running] = DataReadController(hStart,hEnd,vStart,vEnd,valid,...
    lineStartV, lineAverage, AllEndOfLine, BlankCount, frameStart)
%#codegen

persistent FSMState;
persistent InBetween;

S0 = fi(0,0,2,0);
S1 = fi(1,0,2,0);
S2 = fi(2,0,2,0);



if isempty(FSMState)
    FSMState = fi(0,0,2,0);
    InBetween = false;
end





switch FSMState
    
    case S0 %% Loading
        outputData = fi(0,0,1,0);
        hStartO = (hStart);
        hEndO = (hEnd);
        vStartO = (vStart);
        vEndO = (fi(0,0,1,0));
        validO = (valid);

        Unloading = fi(0,0,1,0);
        InBetween = false;
        BlankCountEn = fi(0,0,1,0);
        Running = fi(0,0,1,0);

        if bitget(lineStartV,LineStartC) 
            FSMState(:) = S1;
        else
            FSMState(:) = S0;
        end
        
        
    case S1 %% Running
        outputData = fi(1,0,1,0);
        Unloading = fi(0,0,1,0);
       
        Running = fi(1,0,1,0);
        
            hStartO = (hStart);
        hEndO = (hEnd);
        vStartO = (vStart);
        vEndO = (fi(0,0,1,0));
        validO = (valid);
        
        if frameStart
             FSMState(:) = S0;
            InBetween = true;
            BlankCountEn = fi(0,0,1,0);
        elseif vEnd
            FSMState(:) = S2;
            InBetween = true;
            BlankCountEn = fi(1,0,1,0);
        else
            FSMState(:) = S1;
     BlankCountEn = fi(0,0,1,0);
            InBetween = false;
        end
        
        
    case S2 %% Unloading
        outputData = fi(1,0,1,0);
        Unloading = fi(1,0,1,0);
        Running =  fi(0,0,1,0);

        if frameStart
        FSMState(:) = S0;
        hStartO = fi(0,0,1,0);
        hEndO = fi(0,0,1,0);
        vStartO = fi(0,0,1,0);
        vEndO = fi(0,0,1,0);
        validO = fi(0,0,1,0);        
        BlankCountEn = fi(0,0,1,0);
        InBetween = true;        
        elseif bitget(lineStartV,LineStartF) == 0 &&  (~InBetween && AllEndOfLine)
        FSMState(:) = S2;
        hStartO = fi(0,0,1,0);
        hEndO = fi(1,0,1,0);
        vStartO = fi(0,0,1,0);
        vEndO = fi(1,0,1,0);
        validO = fi(1,0,1,0);        
        BlankCountEn = fi(0,0,1,0);
        InBetween = true;
        
        elseif InBetween && BlankCount == lineAverage && bitget(lineStartV,LineStartF) == 0
        FSMState(:) = S0;
        hStartO = fi(0,0,1,0);
        hEndO = fi(0,0,1,0);
        vStartO = fi(0,0,1,0);
        vEndO = fi(0,0,1,0);
        validO = fi(0,0,1,0);
        BlankCountEn =  fi(0,0,1,0);
        InBetween = false;     
        elseif InBetween && BlankCount <lineAverage %% Blanking
        FSMState(:) = S2;
        hStartO = fi(0,0,1,0);
        hEndO = fi(0,0,1,0);
        vStartO = fi(0,0,1,0);
        vEndO = fi(0,0,1,0);
        validO = fi(0,0,1,0);        
        BlankCountEn = fi(1,0,1,0);
        InBetween = true;

        elseif InBetween && BlankCount == lineAverage %% Line Start
        FSMState(:) = S2;
        hStartO = fi(1,0,1,0);
        hEndO = fi(0,0,1,0);
        vStartO = fi(0,0,1,0);
        vEndO = fi(0,0,1,0);
        validO = fi(1,0,1,0);
        BlankCountEn =  fi(0,0,1,0);
        InBetween = false;       
        elseif ~InBetween && AllEndOfLine %% Line End
        FSMState(:) = S2;
        hStartO = fi(0,0,1,0);
        hEndO = fi(1,0,1,0);
        vStartO = fi(0,0,1,0);
        vEndO = fi(0,0,1,0);
        validO = fi(1,0,1,0);
        BlankCountEn =  fi(0,0,1,0);
        InBetween = true;
        elseif ~InBetween %% On Line
        FSMState(:) = S2;
        hStartO = fi(0,0,1,0);
        hEndO = fi(0,0,1,0);
        vStartO = fi(0,0,1,0);
        vEndO = fi(0,0,1,0);
        validO = fi(1,0,1,0);
        BlankCountEn =  fi(0,0,1,0);   
        InBetween = false;
        else
        FSMState(:) = S2;     
        hStartO = fi(0,0,1,0);
        hEndO = fi(0,0,1,0);
        vStartO = fi(0,0,1,0);
        vEndO = fi(0,0,1,0);
        validO = fi(1,0,1,0);
        BlankCountEn = fi(0,0,1,0);   
        InBetween = false;         
        end
        
        
        

        
    otherwise
        hStartO = hStart;
        hEndO = hEnd;
        vStartO = vStart;
        vEndO = fi(0,0,1,0);
        validO = valid;
        outputData = fi(1,0,1,0);
        Unloading = fi(0,0,1,0);
        BlankCountEn = fi(0,0,1,0);
        InBetween = false;
        Running = fi(0,0,1,0);
end
