cancel
Showing results for 
Search instead for 
Did you mean: 

stm32U585 FMAC IIR wrong result

MehranMsba
Associate II

Hi.

I have a big buffer with Chirp data for testing that about 30000 of int16 length and I can not get right result from FMAC IIR filtering operation. The operation configured in polling for read and write.
I calculate a bandpass IIR DF1 filter coeff with matlab filter designer and this coeff is ok with software filtering

static int16_t FilterCoeffB[3] =
{
  120,	0,	-120
};

static int16_t FilterCoeffA[2] =
{
	-7936,	3856
};

static int16_t aOutputDataToPreload[2] =
{
  0x0000, 0x0000
};

the configuration:

sFmacConfig.InputBaseAddress  = INPUT_BUFFER_BASE; // M+N    ,X1
  sFmacConfig.InputBufferSize   = INPUT_BUFFER_SIZE; // N + d1 , N is B len,d1 is input buffer size
  sFmacConfig.InputThreshold    = INPUT_THRESHOLD;   //
	
  sFmacConfig.CoeffBaseAddress  = COEFFICIENT_BUFFER_BASE;//0   X2
  sFmacConfig.CoeffBufferSize   = COEFFICIENT_BUFFER_SIZE;//N+M, M is A Len
	
  sFmacConfig.OutputBaseAddress = OUTPUT_BUFFER_BASE;//M+2N+d1
  sFmacConfig.OutputBufferSize  = OUTPUT_BUFFER_SIZE;//M+d2, d2 is output buffer size
  sFmacConfig.OutputThreshold   = OUTPUT_THRESHOLD;
	
  sFmacConfig.pCoeffA           = FilterCoeffA;
  sFmacConfig.CoeffASize        = COEFF_VECTOR_A_SIZE;
  
	sFmacConfig.pCoeffB           = FilterCoeffB;
  sFmacConfig.CoeffBSize        = COEFF_VECTOR_B_SIZE;
	
  sFmacConfig.Filter            = FMAC_FUNC_IIR_DIRECT_FORM_1;
  sFmacConfig.InputAccess       = FMAC_BUFFER_ACCESS_POLLING;
  sFmacConfig.OutputAccess      = FMAC_BUFFER_ACCESS_POLLING;
  sFmacConfig.Clip              = FMAC_CLIP_DISABLED;
	
  sFmacConfig.P                 = COEFF_VECTOR_B_SIZE;
  sFmacConfig.Q                 = COEFF_VECTOR_A_SIZE;
  sFmacConfig.R                 = GAIN;

and :

/* Filter parameter P: number of feed-forward taps or coefficients in the range [2:64] */
#define COEFF_VECTOR_B_SIZE     3

/* Filter parameter Q: number of feedback coefficients in the range [1:COEFF_VECTOR_B_SIZE-1] */
#define COEFF_VECTOR_A_SIZE     2

/* Filter parameter R: gain in the range [0:7] */
#define GAIN                    1

/* Throughput parameter: extra space in the input buffer (minimum: 0) ((256/2)-1)-(b+a) */
#define MEMORY_PARAMETER_D1     122

/* Throughput parameter: extra space in the output buffer (minimum: 1) (((256/2)-1)-(b+a)+1)*/
#define MEMORY_PARAMETER_D2     123

/* Throughput parameter: watermark threshold for the input buffer */
#define INPUT_THRESHOLD         FMAC_THRESHOLD_1

/* Throughput parameter: watermark threshold for the output buffer (inferior or equal to MEMORY_PARAMETER_D1) */
#define OUTPUT_THRESHOLD        FMAC_THRESHOLD_1

/* FMAC internal memory configuration: base address of the coefficient buffer */
#define COEFFICIENT_BUFFER_BASE 0

/* FMAC internal memory configuration: size of the two coefficient buffers */
#define COEFFICIENT_BUFFER_SIZE COEFF_VECTOR_B_SIZE + COEFF_VECTOR_A_SIZE

/* FMAC internal memory configuration: base address of the input buffer */
#define INPUT_BUFFER_BASE       COEFFICIENT_BUFFER_SIZE

/* FMAC internal memory configuration: size of the input buffer */
#define INPUT_BUFFER_SIZE       COEFF_VECTOR_B_SIZE + MEMORY_PARAMETER_D1

/* FMAC internal memory configuration: base address of the input buffer */
#define OUTPUT_BUFFER_BASE      COEFFICIENT_BUFFER_SIZE + INPUT_BUFFER_SIZE

/* FMAC internal memory configuration: size of the input buffer */
#define OUTPUT_BUFFER_SIZE      COEFF_VECTOR_A_SIZE + MEMORY_PARAMETER_D2

run code is :

int16_t *ptrData=ChirpWaveSample;
int16_t *ptrOut=aCalculatedFilteredData;

  HAL_FMAC_FilterConfig(&hfmac, &sFmacConfig);
  HAL_FMAC_FilterPreload(&hfmac, ptrData, INPUT_BUFFER_SIZE,aOutputDataToPreload, COEFF_VECTOR_A_SIZE);

  ExpectedCalculatedOutputSize = MEMORY_PARAMETER_D2;
  HAL_FMAC_FilterStart(&hfmac, ptrOut, &ExpectedCalculatedOutputSize);	

  HAL_FMAC_PollFilterData(&hfmac, 0xFFFFFFFF);

for(uint16_t cnt=0;cnt<250;cnt++)
{
  
	ptrData+=INPUT_BUFFER_SIZE;	
	loadedToBuf=INPUT_BUFFER_SIZE;	
	HAL_FMAC_AppendFilterData(&hfmac,ptrData,&loadedToBuf);	
	
	ptrOut+=INPUT_BUFFER_SIZE;
	loadedToBuf=INPUT_BUFFER_SIZE;	
	HAL_FMAC_ConfigFilterOutputBuffer(&hfmac,ptrOut,&loadedToBuf);
		
	HAL_FMAC_PollFilterData(&hfmac, 0xFFFFFFFF);
}

I export output buffer and analyze the filtering response is not look like to true answer.

the true response signal is look like:

MehranMsba_0-1694019611137.png

and result that I get:

MehranMsba_1-1694019697889.png

I should note that the number of loop iterations is an estimate and I want a simple result in first step.

Where am I doing wrong? Is this setting wrong? Is the way of providing data to FMAC wrong? Or its order?
I will glad from your answers.

Thanks to everyone who took the time to view this topic.

1 REPLY 1
MehranMsba
Associate II

I changed the code to work with interrupt and I think the read and write to/from FMAC is ok now

 

void HAL_FMAC_OutputDataReadyCallback(FMAC_HandleTypeDef *hfmac)
{
		ptrOut+=100;
		loadedToBuf_O=100;
		HAL_FMAC_ConfigFilterOutputBuffer(hfmac,ptrOut,&loadedToBuf_O);
}

uint16_t cnr=0;
void HAL_FMAC_GetDataCallback(FMAC_HandleTypeDef *hfmac)
{
	if(cnr<600)
	{
		ptrData+=50;
		loadedToBuf_I=50;
		HAL_FMAC_AppendFilterData(hfmac,ptrData,&loadedToBuf_I);			
		
		cnr++;
	}
	else
	{
		while(1);
	}
}

 

but the response is not correct. I think that the filter coefficients have problem or are designed incorrectly in some way. I attempted to design and tested many DF1 filter using Matlab, but it doesn't produce an acceptable output, even though it works correctly within Matlab itself.

now the filter response is:

MehranMsba_0-1694093542476.png

but the FMAC output is:

MehranMsba_1-1694093570984.png

The signal's amplitude is not important now, what matters is that its shape does not resemble to designed shape.

Is there any hint or technique to design FMAC compatible IIR filter?

Thanks

 

Update

FIR Filtering with FMAC is working without any problem in interrupt mode that located in first paragraph of this reply. but IIR result has problem.