% CRC_CCITT_Generator.m
%
% Generates the CRC for a sequence of bits based on the CCITT-CRC
% (CRC-16-CCITT) cyclic redundancy check.  The AX.25 amateur packet
% radio protocol uses the CCITT-CRC.
%
% function FCS = CRC_CCITT_Generator( Bits )
%
% Bits is input message bits [ First bit, ..., Last bit ]
% FCS is frame check sequence [ MSB, ..., LSB ].
%
% Rev. 11/23/2008 (W. Newhall, billnewhall@yahoo.com)

function FCS = CRC_CCITT_Generator( Bits )

G = [ 0 0 0 1  0 0 0 0  0 0 1 0  0 0 0 1 ];     % Generator polynomial for CCITT-CRC
% 0x        1        0        2        1        % CCITT_CRColynomial is 0x1021 in hex

r = 16;                     % Length of shift register
GFlip = fliplr( G );        % Flip the polynomial for the XOR operation in the loop
N_bits = length( Bits );    % Number of bits in message
SR = ones( 1, r );          % Initialize shift register (SR) to all ones

% Loop through all bits; shift bits into shift register
for( n_bit = 1 : N_bits )
    OutBit = SR( r );               % Bit shifted out of shift register
    SR = [ 0, SR( 1 : ( r-1 ) ) ];  % Shift the register to the right and shift a zero in
    
    % Method 1
    XORMask = xor( Bits( n_bit ), OutBit ) * GFlip; % Input bit XORed with shifted-out bit
    SR = xor( SR, XORMask );        % Apply the XOR mask to the shift register
    
    % Alternate (Method 2)
    % if( OutBit ~= Bits( n_bit ) )         % Apply XOR mask only if shifted-
    %    SR = xor( SR, GFlip( 1 : r ) );    % out bit does not equal input bit.
    % end

    % Uncomment to display contents of SR for each bit:
    %  disp( num2str( ( SR ) ) );   
end

% Bitwise-invert and flip the SR to get FCS with MSB as first element
FCS = fliplr( -SR+1 );      

% disp( num2str( ( FCS ) ) ); % Display the SR

