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

STM32 real time FIR filter from ADC samples

Hello,

I have a Nucleo-L476RG board and I'm trying to make a lowpass filter with the FIR function (using cmsis libraries) to filter the samples I get from the ADC in realtime.
Then I'd like to get the processed signal out through the DAC.

Both ADC and DAC work at a sampling frequency of 20khz, triggered by two (tim6 and tim7) timers. They use DMA.

FIR function is called every time the ADC ends a conversion.

I'm using arrays of 1 element as buffers, so the number of blocks of the FIR function is 1.

I can get a signal on the output, but it does not match what the input signal processed through the filter would be.

Thank you very much for your help. I hope my explanation is good enough.

Here is my code:

#include <math.h>
#include "arm_math.h"
uint32_t adcValue[1];
uint32_t adcValue1[1];
int i;
float32_t signal_in = 0;
float32_t signal_out = 0;

#define TEST_LENGTH_SAMPLES  1
#define BLOCK_SIZE            1
#define NUM_TAPS              29



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};


uint32_t blockSize = BLOCK_SIZE;
uint32_t numBlocks = TEST_LENGTH_SAMPLES/BLOCK_SIZE;


void SystemClock_Config(void);


int main(void)
{

  HAL_Init();

  /* Configure the system clock */
  SystemClock_Config();

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_DAC1_Init();
  MX_TIM6_Init();
  MX_ADC1_Init();
  MX_TIM7_Init();
  MX_ADC2_Init();

  //Timers
  HAL_TIM_Base_Start(&htim6);
  HAL_TIM_Base_Start(&htim7);

  //ADC Start
  HAL_ADC_Start_DMA(&hadc1, adcValue, 1 );

  //DAC Start
  HAL_DAC_Start(&hdac1,DAC_CHANNEL_1);
  HAL_DAC_Start_DMA(&hdac1, DAC_CHANNEL_1, (uint32_t*)adcValue1, 1, DAC_ALIGN_12B_R);

  //FIR Init
  arm_fir_init_f32(&S, NUM_TAPS, (float32_t *)&firCoeffs[0], (float32_t *)&firStateF32[0], blockSize);


  /* Infinite loop */

   while (1)
   {

   }


}

void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
        if(hadc->Instance == ADC1)
        {
                    signal_in = (float32_t)adcValue[0];

                    arm_fir_f32(&S, &signal_in, &signal_out, blockSize);

                    adcValue1[0] = (uint32_t)signal_out; //signal_out;

        }
}