• Not Answered

IIR and FIR filter library questions

I am using the F28335 chip. I looked for iir and fir filters and found some for the C2000 but they are written for integer math. My questions are:

1) Is there a library for the C2000 chips with floating point support?

2) If not and I need to use the integer versions, for iir32, do I need to scale the input to Q15 (ie x 32768) before feeding it to the filter function?

3) Why isn't there a 32 bit version of the FIR? Or is there?

Thanks

34 Replies

  • In reply to Maxpower:

    Lori,

        Do you have a floating point version of the IIR fitler available yet for me to try?

    Thanks

    Max

  • In reply to Maxpower:

    Max,

    I currently have FIR and IIR working version in both 16 and 32 bit. Now I am documenting them.  We don't have floating point version of optimized IIR filter library at this time. If you really want to implement it in floating point. You can use C to do that.

    -Yu Cai

  • In reply to Yu Cai58368:

    Yu Cai,

        I can work with the integer versions but Lori (above) mentioned there were floating point versions being worked on and that I might be able to get ahold of some code to try out.

    I look forwared to getting the latest integer versions to try in the meantime.

    Thanks

    Max

  • In reply to Maxpower:

    Maxpower

    Lori,

        Do you have a floating point version of the IIR fitler available yet for me to try?

    Thanks

    Max

    Hi Max,

    Unfortunately Yu Cai is correct.  What I found was an FIR tucked away but I was not able to find the IIR.  I apologize for that.  At the moment Yu Cai is finishing up some fixed point cleanup but will be working on the float soon.

    I hope what you have at this time will work for you until then.

    -Lori

     

  • In reply to Lori Heustess:

    Yu Cai,

        While I am waiting for an updated iir32, I am trying to get iir16 to work. All my math is in floating point on the F28335. The output from the iir16 matlab script is:

    #define IIR16_COEFF {\
       0,5716,0,89,89,\
       -5781,13114,9879,19759,9879}

    #define IIR16_ISF 2476
    #define IIR16_NBIQ 2
    #define IIR16_QFMAT 13

    I call the initialize function as in the examples given.

     

    This is the code I use to convert my floating point number to an integer in Q15 format and then convert from a Q14.

        iir.input = (int)floor((speed_control.Out * 32768.0));          // Scale to Q15 format
        iir.calc(&iir);
        angle->omega_m = (float)iir.output / 16384.0;                    // 2^14 which is the output format

    According to the iir16 asm source, the output is in Q14 format so I have to divide to convert it back to floating point

    Is this correct?

     

    I am not getting the desired results so I am wondering what I am doing wrong.

    Thanks

  • In reply to Maxpower:

    Have you verify the output before you call iir16? I am not sure the version that you are running is good since I updated something from the legacy code and I remember there is something wrong in the document and code itself.

     What i recommend you to do is running a matlab scripts to see the result and compare the result with the data output with you CCS project output. Otherwise you won't know if it's due to your code problem or algorithm problem.

    MAX_TAPS=5;

    RadStep = 0.1963495408494; 

    N=input('Please enter signal length N =');

    halfSize=N-1;

    Rad=[0:RadStep:(halfSize)*RadStep];

    CFFTinBuf1=zeros(1,N);

    Rx=sin(Rad)+cos(Rad*2.3567);

    Ix=0*(cos(Rad*8.345) + sin(Rad*5.789));

    x=Rx+j*Ix;

    x_raw_sig=x/2;

    x_Q15=2^15*x/2;

    B=[ 0.000176614401432267

    0.00123630081002587

    0.00370890243007761

    0.00618150405012935

    0.00618150405012935

    0.00370890243007761

    0.00123630081002587

    0.000176614401432267];

    A=[ 1

    -3.84708594662977

    6.78600477287384

    -6.96288772960265

    4.44516236478943

    -1.75415688503484

    0.39441771610976

    -0.0388476491224433];

    A=A';B=B';

    filter_out_Q15=filter(B,A,x_Q15);

    % good

    isos=[ 307 307 0 8192 -3794 0

    668 1335 668 8192 -7894 2159

    541 1082 541 8192 -8904 3483

    13364 26729 13364 8192 -10923 6131];

    isf=4398;

    nbiq=4;

    qfmat=13;

    d=zeros(nbiq,3);

    taps=3;

    for k=1:length(x_Q15)

    accum=floor(x_Q15(k)*isf);

    for j=1:nbiq

    b_temp=isos(j,1:3);

    a_temp=isos(j,4:6);

    for ii=2:taps

    accum=accum-floor(a_temp(ii)*d(j,ii));

    end

    d(j,1)=floor(accum/2^qfmat);

    accum1=0;

    for ii=1:taps

    accum1=accum1+floor(b_temp(ii)*d(j,ii));

    end

    for ii=(taps-2+1):-1:1

    d(j,ii+1)=d(j,ii);

    end

    accum=floor(accum1);

    end

    x_no_scale_biq_fixed(k)=(accum1)/2^qfmat; % direct I form high order implementation output

    end

    figure(1)

    plot(filter_out_Q15)

    peak1=max(filter_out_Q15);

    hold on

    peak2=max(x_no_scale_biq_fixed);

    plot(x_no_scale_biq_fixed,'r')

    x_output_final=floor(x_no_scale_biq_fixed/2);

     

    And then put this into your iir.h

    #define IIR16_LPF_COEFF {\

    0,3794,0,307,307,\

    -2159,7894,668,1335,668,\

    -3483,8904,541,1082,541,\

    -6131,10923,13364,26729,13364}

    #define IIR16_LPF_ISF     4398
    #define IIR16_LPF_NBIQ    4
    #define IIR16_LPF_QFMAT   13

     

    in your main.c

      /* IIR Filter Initialisation                                */
      iir.dbuffer_ptr=dbuffer;
      iir.coeff_ptr=(int *)coeff;
      iir.qfmat=IIR16_LPF_QFMAT;
      iir.nbiq=IIR16_LPF_NBIQ;
      iir.isf=IIR16_LPF_ISF;
         iir.init(&iir);

    //generate waveform like this   

    for(i=0; i < SIGNAL_LENGTH; i++)
        {
      xn=(int)(32768*(sin(Rad) + cos(Rad*2.3567))/2);          //Q15
      sigIn[i]=xn;
      iir.input=xn;          
            iir.calc(&iir);
            yn=iir.output;
            sigOut[i]=yn;
      Rad = Rad + RadStep;
        }   

     compare the result from you CCS project and the matlab to see if they are the same.  If still have problem ,  let me know.

     

     

  • In reply to Maxpower:

    If you have this IIR16 version work. IIR32 is similar. The release of these example project would be around weeks ahead. The current code are not heavily commented and documented.  Since the legacy library the example is wokring associated with stb.lib. It is not easy to test in standalone. If you can make these iir16 version work. It's not difficult to make 32 bit version work. Good luck! :-)

    -Yu Cai  

  • In reply to Yu Cai58368:

    Yui Cai,

       I ran the script and and the code on the dsp. I attached plots of both. Figure 1 is from matlab and Figure 2 is from the DSP.

    My iir16 low pass filter is not working in my code. If I just get rid of the filter, I can use the data as is and overall my motor control application works OK. With the filter in, not at all. I am trying to dig into it more to try to understand.

    The FIR16 and IIR16 code takes a Q15 number as input. This is convenient when filtering data right from the ADC on the chip. The "fractional" portion of the Q15 number is zero. Does the FIR16/IIR16 code work when the fractional portion is non-zero?

     

    Thanks

  • In reply to Maxpower:

    hmmmm. The picture did not attach properly. I received an error. Let me try that again.

  • In reply to Maxpower:

    I believe the red output is from the matlab scripts. the input for iir16 is Q15.  I think the asm file that you use might be different from mine. Here is my screen shot.