This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

FIR filter not working as expected

Other Parts Discussed in Thread: CONTROLSUITE

 Hi there,

I've got F28069 device and using few FIR filters included in TI Fixed point library.

Most of them are working but one in particular is not performing as expected (when compared with matlab results).

The filter is a FIR16 filter and calculated the coefficients using the ezfir16 file, which seems to be not included any more in the controlsuite (why is that btw?).

Anyway the filter I've designed is a fractional delay filter with 4 orders expecting to delay the input signal by close to 3 samples.

However the result constantly shows it's only delaying it by 2. 

what could be the problem for this? other FIR filters such as a low pass filter are working as expected so it's really puzzling why this one doesn't work.

Please help!

Thanks,

Ayaka

  • Hi,

    would you be able to share the matlab script and C code- i can take a look; I can send you my email if you prefer to send it to me directly? Please let me know.

    As for the ezfir16, I have the original files I'll file an enhancement request to add them to the next release; im not quite sure why they were taken out.
  • Hi Vishal,

    Sure I've attached the matlab script I've used to generate the coefficients here. I think it's just the same ezfir16.m from TI but from an old controlsuite.

    Also the c code to use this is just using the TI library but below is how I use it.

    Wait to hear from you!  Also let me know anything else you may need.

    ezfir16.m.txt
    disp('ezFIR FILTER DESIGN SCRIPT');
    if exist('ezOrder') == 0
       ezOrder=input('Input FIR Filter order(EVEN for BS and HP Filter) : ');
    end
    if exist('ezFres') == 0
    	disp('Low Pass          : 1');
    	disp('High Pass         : 2');
    	disp('Band Pass         : 3');
    	disp('Band Stop         : 4');
       disp('Fractional Delay  : 5');
       ezFres=input('Select Any one of the above Response              : ');
    end
    if exist('ezWinType') == 0
    	if ezFres~=5
    		disp('Hamming           : 1');
    		disp('Hanning           : 2');
    		disp('Bartlett          : 3');
    		disp('Blackman          : 4');
    		disp('Flat top          : 5');
          ezWinType=input('Select Any one of the above window                : ');
        end
    end
    
    if exist('ezFs') == 0
       ezFs=input('Enter the Sampling frequency                      : ');
    end   
    
    if ezFres~=5
       if exist('ezFc') == 0
          ezFc=input('Enter the corner frequency(Fc or [Fl Fu])         : ');
       end
    else   
      	ezWinType = 1;
       ezFc = 0.25;
       if exist('ezDelay') == 0
          ezDelay=input('Enter the required delay (samples)                : ');
       end
    end
    
    if exist('ezFName') == 0
       ezFName=input('Enter the name of the file for coeff storage      : ','s');
    end
    
    % Design the Filter
    if ezFres==1
        res='';
       elseif ezFres==2
          res='high';
       elseif ezFres==3
          res='';
       elseif ezFres==4
          res='stop';
       elseif ezFres==5
          res='fd';
    end
    
    if ezWinType==1
    	   win=hamming(ezOrder+1);
       	winStr = 'Hamming';
       elseif ezWinType==2
          win=hanning(ezOrder+1);
       	winStr = 'Hanning';
       elseif ezWinType==3
          win=bartlett(ezOrder+1);
       	winStr = 'Bartlett';
       elseif ezWinType==4
          win=blackman(ezOrder+1);
          winStr = 'Blackman';
       elseif ezWinType==5
          win=flattop(ezOrder+1);
          winStr = 'Flattop';
       else
    	  	winStr = '';
    end
    
    FcHz = ezFc;
    nomFc=ezFc/(ezFs/2);                               % Normalise the frequency values
    if ezFres~=5
       B=fir1(ezOrder,nomFc,res,win);
    else
       B = lagrange(ezOrder, ezDelay);
    end
    Bi=B*32768;                                 % Coefficients in Q15 format
    Bi=floor(Bi);
    bsize=length(Bi);
    
    for i=1:bsize                               % Saturate the coefficients for Q15 format
       if Bi(i)==32768
          Bi(i)=32767;
       end
    end
    
    if ezFres==1
        FirType='LP';
    elseif ezFres==2
          FirType='HP';
    elseif ezFres==3
         FirType='BP';
    elseif ezFres==4
          FirType='BS';
    elseif ezFres==5
          FirType='FD lagrange';
    end
    if length(FcHz) == 2
       FC = sprintf('%d-%d', FcHz(1), FcHz(2));
    elseif length(FcHz) == 1
       FC = sprintf('%d', FcHz);
    end
    
    if ezFres == 5
       comment = sprintf('FIR16 %s order=%d Fs=%fHz Delay=%d samples', FirType, ezOrder, ezFs, ezDelay);    
    else
       comment = sprintf('FIR16 %s order=%d %s Fs=%dHz Fc=%sHz', FirType, ezOrder, winStr, ezFs, FC); 
    end
    savefir16(ezFName,comment, Bi, ezOrder);
    eval(['type ' ezFName]);
    save B Bi;
    
    % Plot the frequency response of the filter         
    [H,f]=freqz(B,1,512,ezFs);
    figure(1);
    subplot(2,1,1);
    plot(f,abs(H));
    grid;
    xlabel('Hertz');
    ylabel('Magnitude Response');
    subplot(2,1,2);
    plot(f,unwrap(angle(H))*180/pi);
    grid;
    xlabel('Hertz');
    ylabel('Phase (degrees)');
    figure(2);
    freqz(B,1,512,ezFs);
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    lagrange.m.txt
    function h = lagrange(N, delay)
    %LAGRANGE  h=lagrange(N,delay) returns order N FIR 
    %          filter h which implements given delay 
    %          (in samples).  For best results, 
    %          delay should be near N/2 +/- 1.
    n = 0:N;
    h = ones(1,N+1);
    for k = 0:N
        index = find(n ~= k);
        h(index) = h(index) *  (delay-k)./ (n(index)-k);
    end
    

    Thanks,

    Ayaka

    #include <fir.h>
    
    // Copied from matlab script
    /* FIR16 coefficients (FD_FILTER)
       FIR16 FD lagrange order=4 Fs=20000.000000Hz Delay=2.941176e+000 samples
       {155,-942,2913,31072,-432,} */
    #define FIR_ORDER_FD 4
    #define FD_COEFF {\
    	2913,-28246958,2036334747}
    
    FIR16 fir_FdRx = FIR16_DEFAULTS;
    
    /* Define the Delay buffers and place in "firModFd" section */
    #pragma DATA_SECTION(alFdRxBuf,"firModFd");
    long alFdRxBuf[(FIR_ORDER_FD+2)/2];
    
    /* Define Constant Co-efficient Array (used for Tx and Rx and place the .econst/.const section in
    non-volatile memory */
    #define FIR_ORDER_FD_SIZE ((FIR_ORDER_FD+2)/2)
    const long FdCoeff_const[FIR_ORDER_FD_SIZE]= FD_COEFF;
    long FdCoeff[FIR_ORDER_FD_SIZE];
    
    // Initialisation ///////////////////
    void init_filter(void)
    {
    	memcpy( FdCoeff, FdCoeff_const, FIR_ORDER_FD_SIZE * 2);
    	fir_FdRx.dbuffer_ptr = alFdRxBuf;
    	fir_FdRx.coeff_ptr=(long *)FdCoeff;
    	fir_FdRx.order=FIR_ORDER_FD;
    	fir_FdRx.init(&fir_FdRx);
    }
    
    // Usage ///////////////////////////
    // This function gets called periodically and data is the ADC value collected at 20kHz
    void modem_processRx(S16 data)
    {
    	// other codes here...
    
    	fir_FdRx.input = data;
    	fir_FdRx.calc(&fir_FdRx);
    
    	// use fir_FdRx.output for the calculation followed...
    }
    
    

  • Ok I think i found the problem. IF you place the section "coeffilt" in data memory i.e page = 1 and not page = 0 as it is in the example - it will work.  See the attached example

    28069_FIXEDPT_FractionalDelayFIR_150209.zip

    This matches with the MATLAB results:

    % // TI File $Revision: /main/3 $
    % // Checkin $Date: November 1, 2010   13:05:07 $
    % // =====================================================================================
    % //  This software is licensed for use with Texas Instruments C28x
    % //  family DSCs.  This license was provided to you prior to installing
    % //  the software.  You may review this license by consulting a copy of
    % //  the agreement in the doc directory of this library.
    % // -------------------------------------------------------------------------------------
    % //          Copyright (C) 2010-2011 Texas Instruments, Incorporated.
    % //                          All Rights Reserved.
    % //======================================================================================
    % //
    % // 	FILE:    FixedPointFIR16.m
    % //
    % // 	TITLE:   DSP2833x Device Fixed Point FIR16 Test Program.   
    % //
    % //
    % // 	ASSUMPTIONS:
    % //
    % //   	This matlab code is reference code for debugging FixedPoint DSP library
    % //    16 bit FIR module and example project 2833x_FixedPoint_FIR16. 
    % //
    % //
    % //   
    % //    Watch Variables:
    % //
    % //      x_raw_sig         Input signal (float)
    % //      fir_lpfxx_Q15		FIR filter coefficients (Q15)
    % //      x_Q15             Input signal in Q15 format
    % //      output            Filtered signal (Q15)
    % //
    % //######################################################################################
    % // $TI Release: C28x Fixed-Point DSP Library v1.10 $
    % // $Release Date: November 1, 2011 $
    % //######################################################################################
    
    clear all
    close all
    
    disp('==============================================================');
    disp('==============================================================');
    disp('this is Matlab version of C28x Fixed Point FIR16 code');
    disp('The result is stored in array output Q15');
    disp('The signal is stored in array x_raw_sig (float)');
    disp('The signal in Q15 format is stored in array x_Q15');
    disp('==============================================================');
    
    RadStep = 0.1963495408494;
    
    N=input('Please enter signal length N =');
    halfSize=N-1;
    
    Rad=[0:RadStep:(halfSize)*RadStep];
    
    x_Q15 = 32768 * ((sin(Rad)+cos(Rad*2.3567))/2);
    
    
    % x=Rx+j*Ix;
    % x_raw_sig=x/2;
    
    % x_Q15=2^15*x/2;
    
    fir_lpf4_Q15=[155, -942, 2913, 31072, -432];
    
    fir_lpf6_Q15=[-3368,347,17612,17612,347,-3368];
    
    fir_lpf7_Q15=[-891,  -4096,   9083,  21178,   9083,  -4096,   -891];
    
    fir_lpf32_Q15=[-31,    -61,     92,    122,   -186,   -248,    348,    449,   -607, -778,   1043,   1370,  -1909,  -2789,   4835,  14710,  14710,   4835, -2789,  -1909,   1370,   1043,   -778,   -607,    449,    348,   -248, -186,    122,     92,    -61,    -31];
    
    %result=conv(fir_lpf6_Q15,x_Q15)*2^7/2^6/2^16;
    %result=conv(fir_lpf7_Q15,x_Q15)*2^7/2^6/2^16;
    % result=conv(fir_lpf32_Q15,x_Q15)*2^7/2^6/2^16;
    result=conv(fir_lpf4_Q15,x_Q15)*2^7/2^6/2^16;
    
    output=floor(result(1:N));
    
    plot(output)