cancel
Showing results for 
Search instead for 
Did you mean: 

How to use FMAC only with CMSIS (STM32G474RE)?

Legacy member
Not applicable

Hi! I need to use FMAC peripheral without any HAL or LL. So, according to RM0440, and AN5305 i`ve got code that works just fine for FIR and IIR filters, but only with coefficients that less than 1. For example, i divided both A and B coeffs by 4 and set Gain (parameter R) to 2 (binary log (4)) to keep digits in acceptable fixed point format. RDATA output transfer only min and max values 8000 to 7FFF, so there is only square form signal on output. Coeffs and gain are next:

IIR_struct fourth_order = {

 .shift = 2,

 .m = 4,

 .n = 5,

 .a = {(uint16_t)(-19411), (uint16_t)(18956), (uint16_t)(-8640), (uint16_t)(1535)},

 .b = {(uint16_t)(40), (uint16_t)(158), (uint16_t)(237), (uint16_t)(158), (uint16_t)(40)},

};

What i missed?

void fmac_iir_config(IIR_struct* iir)
{
  int buffsize = 1;
 
  FMAC->X2BUFCFG |= 0 << FMAC_X2BUFCFG_X2_BASE_Pos;
  FMAC->X2BUFCFG |= (iir->n + iir->m) << FMAC_X2BUFCFG_X2_BUF_SIZE_Pos;
  FMAC->X1BUFCFG |= (iir->n + iir->m) << FMAC_X1BUFCFG_X1_BASE_Pos;
  FMAC->X1BUFCFG |= (iir->n + buffsize) << FMAC_X1BUFCFG_X1_BUF_SIZE_Pos;       //n + buffsize
  FMAC->X1BUFCFG |= 0 << FMAC_X1BUFCFG_FULL_WM_Pos;
  FMAC->YBUFCFG |= (2 * iir->n + iir->m + buffsize) << FMAC_YBUFCFG_Y_BASE_Pos; //2 * n + m + buffsize
  FMAC->YBUFCFG |= (iir->m + buffsize) << FMAC_YBUFCFG_Y_BUF_SIZE_Pos;          //m + buffsize
  FMAC->YBUFCFG |= 0 << FMAC_YBUFCFG_EMPTY_WM_Pos;
  
  FMAC->PARAM &= ~FMAC_PARAM_FUNC;
  FMAC->PARAM |= FMAC_PARAM_FUNC_1;                                             //Load X2
  FMAC->PARAM &= ~FMAC_PARAM_P;
  FMAC->PARAM |= iir->n << FMAC_PARAM_P_Pos;
  FMAC->PARAM &= ~FMAC_PARAM_Q;
  FMAC->PARAM |= iir->m << FMAC_PARAM_Q_Pos;
  FMAC->PARAM &= ~FMAC_PARAM_R;
  FMAC->PARAM |= FMAC_PARAM_START;
  
  for(int i = 0; i < (iir->n); i++)
  {
    FMAC->WDATA = iir->b[i];
  }
  for(int i = 0; i < (iir->m); i++)
  {
    FMAC->WDATA = iir->a[i];
  }
  
  FMAC->PARAM &= ~FMAC_PARAM_FUNC;
  FMAC->PARAM |= FMAC_PARAM_FUNC_3 + FMAC_PARAM_FUNC_0;         //FUNC = 9 (IIR filter)
  FMAC->PARAM &= ~FMAC_PARAM_P;
  FMAC->PARAM |= iir->n << FMAC_PARAM_P_Pos;                    //P = N (feed-forward coeffs.)
  FMAC->PARAM &= ~FMAC_PARAM_Q;
  FMAC->PARAM |= iir->m << FMAC_PARAM_Q_Pos;                    //Q = M (feed-back coeffs.)
  FMAC->PARAM &= ~FMAC_PARAM_R;
  FMAC->PARAM |= iir->shift << FMAC_PARAM_R_Pos;                //R = shift
 
  FMAC->CR |= FMAC_CR_DMAREN + FMAC_CR_CLIPEN;
  FMAC->PARAM |= FMAC_PARAM_START; 
}

0 REPLIES 0