Hi,
I am trying to implement IIR filter using CMSIS library and "arm_biquad_cascade_df1_q15" function.
First of all I already made a design with "arm_biquad_cascade_df2T_f32" function but for my new project I don't have a MCU with FPU so I need to use Q15 format(I am using LPC4074).
C code:
first I init my filter
arm_biquad_cascade_df1_init_q15(S, numStages, pCoeffs, pState, postShift);
in my first test I tried a very simple filter Using Matlab "filterbuilder" tool - Highpass FS = 64000Hz Fstop = 60Hz Fpass = 500Hz attenuation = 10dB ripple = 1dB
filter type = IIR Elliptic Direct Form I SOS Data type = Fixed point
With this design Matlab coef are : b0: 0.9881 b1: -0.9881 b2: 0 a0: 1.0000 a1: -0.9762 a2: 0
Transforming them into Q15 format (* 32768): b0: 32378 b1: -32378 b2: 0 a0: 32768 a1: -31988 a2: 0
numStages = 1 Postshift = 0
pState is q15_t array with numstages*4 dimension
pCoef is my coefiscient array:
q15_t pCoeffs[numStages*6] = { 32378, //b0 0, //facilities use of 16-bit SIMD instructions on the Cortex-M4 -32378, //b1 0, //b2 31988, //a1 0 //a2 };
As mentioned in CMSIS documentation, depending on the tool equation for filter coefiscients "a" coef must be negated (I noticed with Matlab I have to negate them)
Then I call my filter:
arm_biquad_cascade_df1_q15 (S, sample, result, blocksize);
where result and sample are q15_t array (sample are my ADC samples .. ^^') and blocksize is set to 8
with THIS filter everything works fine .. I put a sin wave with magnitude of 200 and an offset of 2048 my RMS result after filtering is 141 (as expected) and If I put a constant, the RMS result is 0
Then I tried to change my ripple, I set 0.1 instead of 1
Matlab coef: (b0 to a2) 0.97552490234375 -1.95086669921875 0.97552490234375 1 -1.971923828125 0.97265625
Q15 coef (* 32768 / 2 to scale my coef between 1 and -1 as mentionned in CMSIS documentation) 15983 -31963 15983 16384 -32308 15936
My coef array:
q15_t pCoeffs[numStages*6] = { 15983, 0, -31963 , 15983, 32308, -15936 };
and postshift = 1
With these coef. that doesn't work anymore For example, if I put a constant in my samples (all set to 200) I got a final RMS value of 1277 (that means that my filter results are not null, with a high pass filter, all my filter result should be null and my RMS should be null too)
I noticed that each time b2 and a2 are not equal to 0, my result is wrong When they are equal to 0 (even for higher order filter) that works.
What did I miss ?
Regards