This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Realtime CMSIS FIR Filter Issue

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