Hello community,
I have implemented the following filter:
#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
#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
Solved! Go to Solution.
Hello Community,
I found the solution: __L_mult_ls_int can multiply 32bit x 16bit values. It generates a 48bit result which is shifted 16bits right a returns a 32bit value. Here is the c-code for the 2order IIR filter function.
#include "Cpu.h"
#include "Filter.h"
/* L_mult_int */
Int16 SecOrderFilter(Int16 *x, TFilter *filter, TCoeff *coeff)
{
register Int32 temp;
register Int16 gain2;
//L(z)=b0 + b1*z^-1 + b2*z^-2
// ------------------------ * gain
// 1 + a1*z^-1 + a2*z^-2
//y=b0*x+b1*x(-1)+b2*x(-2)
// -a1*y(-1)-a2*y(-2)
gain2=16-coeff->gain;
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=temp - __L_mult_ls_int(filter->y_1 << gain2, coeff->A1); // SHR(32Bit x 16Bit, 16)=32Bit
temp=temp - __L_mult_ls_int(filter->y_2 << gain2, coeff->A2); // SHR(32Bit x 16Bit, 16)=32Bit
//Werte schieben
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);
}
Attached you can find a excel sheet to design the filter an simulate the filter response.
Cheers
Seb.
Hello Community,
I found the solution: __L_mult_ls_int can multiply 32bit x 16bit values. It generates a 48bit result which is shifted 16bits right a returns a 32bit value. Here is the c-code for the 2order IIR filter function.
#include "Cpu.h"
#include "Filter.h"
/* L_mult_int */
Int16 SecOrderFilter(Int16 *x, TFilter *filter, TCoeff *coeff)
{
register Int32 temp;
register Int16 gain2;
//L(z)=b0 + b1*z^-1 + b2*z^-2
// ------------------------ * gain
// 1 + a1*z^-1 + a2*z^-2
//y=b0*x+b1*x(-1)+b2*x(-2)
// -a1*y(-1)-a2*y(-2)
gain2=16-coeff->gain;
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=temp - __L_mult_ls_int(filter->y_1 << gain2, coeff->A1); // SHR(32Bit x 16Bit, 16)=32Bit
temp=temp - __L_mult_ls_int(filter->y_2 << gain2, coeff->A2); // SHR(32Bit x 16Bit, 16)=32Bit
//Werte schieben
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);
}
Attached you can find a excel sheet to design the filter an simulate the filter response.
Cheers
Seb.