Hi everyone,
I'm trying to implement a realtime lowpass FIR filter using the CMSIS library.
I'm essentially following their example here:
http://www.keil.com/pack/doc/CMSIS/DSP/html/group__FIRLPF.html
The only difference is that instead of running the filter on a block of samples, I want the filter to run sample by sample, (use 1 ADC sample and output 1 DAC sample) so I'm using a blocksize of 1.
So here's my *relevant* code. I have a lot of other code unrelated to the DSP side of things for the ADC and DAC which I know works. However, if you want the full code, I can post that as well.
#include "main.h" #include "stm32f4xx_hal.h" #include "arm_math.h" #define BLOCK_SIZE 1 #define NUM_TAPS 29 uint32_t ADC_Buffer[2]; uint32_t DAC_Buffer; float32_t signal_in = 0; float32_t signal_out = 0; float32_t totalval = 0; uint32_t blockSize = BLOCK_SIZE; arm_fir_instance_f32 S; static float32_t firStateF32[BLOCK_SIZE + NUM_TAPS - 1]; static float32_t firCoeffs[NUM_TAPS] = { -0.0018225230f, -0.0015879294f, +0.0000000000f, +0.0036977508f, +0.0080754303f, +0.0085302217f, -0.0000000000f, -0.0173976984f, -0.0341458607f, -0.0333591565f, +0.0000000000f, +0.0676308395f, +0.1522061835f, +0.2229246956f, +0.2504960933f, +0.2229246956f, +0.1522061835f, +0.0676308395f, +0.0000000000f, -0.0333591565f, -0.0341458607f, -0.0173976984f, -0.0000000000f, +0.0085302217f, +0.0080754303f, +0.0036977508f, +0.0000000000f, -0.0015879294f, -0.0018225230f }; int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_DMA_Init(); MX_TIM2_Init(); MX_ADC1_Init(); MX_ADC2_Init(); MX_DAC_Init(); if(HAL_ADC_Start(&hadc2) != HAL_OK) return 0; HAL_ADCEx_MultiModeStart_DMA(&hadc1, ADC_Buffer, 2); HAL_DAC_Start_DMA(&hdac, DAC_CHANNEL_1, &DAC_Buffer, 1, DAC_ALIGN_12B_R); HAL_ADC_Start_IT(&hadc1); HAL_TIM_Base_Start(&htim2); arm_fir_init_f32(&S, NUM_TAPS, (float32_t *)&firCoeffs[0], (float32_t *)&firStateF32[0], blockSize); while (1) { } } void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc) { if(hadc->Instance == ADC1) { ADC_Buffer[0] = ADC_Buffer[0] & 0x00000FFF; signal_in = (float32_t)ADC_Buffer[0]*3/4096; signal_in = signal_in - 0.5f; arm_fir_f32(&S, &signal_in, &signal_out, blockSize); signal_out = signal_out + 0.5f; totalval = signal_out*4096/3; DAC_Buffer = (uint32_t) totalval; //signal_out; } }
The problem is, I always get the same signal_out no matter how signal_in changes. After I step through the arm_fir_f32() function, signal_out is always -1.9764*10^-22.
What's more weird, is that in the watch window, all the firStateF32 values are 0. They never change.
The only thing I'm essentially doing differently from their example, is that I'm using a blocksize of 1.
Any ideas where I'm going wrong?
Thanks, Clint