AnsweredAssumed Answered

Digital 2 order IIR filter implementation

Question asked by Sebastian Prengel on Dec 3, 2014
Latest reply on Dec 5, 2014 by Sebastian Prengel

Hello community,

I have implemented the following filter:

Filter.h:

 #ifndef __Filter_H #define __Filter_H  /* MODULE Filter */  typedef struct {     Int16    x_1;     Int16    x_2;     Int32    y_1;     Int32    y_2; } TFilter;  typedef struct {     Int16    B0;     Int16    B1;     Int16    B2;     Int16   gain;     Int16    A1;     Int16    A2; } TCoeff;  extern Int16 SecOrderFilter(Int16 *x, TFilter *filter, TCoeff *coeff);  /* END Filter */  #endif   extern Int16 SecOrderFilter(Int16 *x, TFilter *filter, TCoeff *coeff);  /* END Filter */  #endif 

 

Filter.c:

 #include "Cpu.h" #include "Filter.h"  Int16 SecOrderFilter(Int16 *x, TFilter *filter, TCoeff *coeff) {     register Int32 temp;     //L(z)=b0 + b1*z^-1 + b2*z^-2     //     ------------------------ * gain     //       1 + a1*z^-1 + a2*z^-2          temp= __L_mult_int(coeff->B0 , *x);     temp= __L_mac_int(temp, coeff->B1 , filter->x_1);     temp= __L_mac_int(temp, coeff->B2 , filter->x_2);     temp= __L_msu_int(temp, coeff->A1 , (Int16)(filter->y_1 >> coeff->gain)); //If shift is performed this way resolution is lost     temp= __L_msu_int(temp, coeff->A2 , (Int16)(filter->y_2 >> coeff->gain)); //If shift is performed this way resolution is lost               //Shift values     filter->x_2=filter->x_1;     filter->x_1=*x;     filter->y_2=filter->y_1;     filter->y_1=temp;     return extract_l(temp >> coeff->gain); //Return y value shifted with gain } }   /* END Filter */

 

My filter coeff for a low pass filter are b0=1; b1=2; b2=1; a1=-32380; a2=16000; gain=2^14. To have a proper resolution of the filter (x=1 after many cycles yield to y=1) I had to implement y as 32 bit value. Unfortunately this means a 16 bit x 32 bit = 48 bit multiplication which will be shifted 14 bits afterwards. If the shift is performed before the multiplication (refer source) the resolution is lost.

 

How can I implement a 16 Bit x 32 Bit integer multiplication with intrinsic56800 functions?

Is there a newer version of "intrinsics_56800E.h" Rev 1.29; Date 2007/11/01 CW 56800/E 8.3 Classic?

 

Thank you in advance!

 

Cheers

Sebastian

Outcomes