/**
  ******************************************************************************
  * @file    stm32g4xx_hal_fmac.c
  * @author  MCD Application Team
  * @brief   FMAC HAL module driver.
  *          This file provides firmware functions to manage the following
  *          functionalities of the FMAC peripheral:
  *           + Initialization and de-initialization functions
  *           + Peripheral Control functions
  *           + Callback functions
  *           + IRQ handler management
  *           + Peripheral State functions
  *
  *  @verbatim
================================================================================
            ##### How to use this driver #####
================================================================================
    [..]
      The FMAC HAL driver can be used as follows:

      (#) Initialize the FMAC low level resources by implementing the HAL_FMAC_MspInit():
          (++) Enable the FMAC interface clock using __HAL_RCC_FMAC_CLK_ENABLE().
          (++) In case of using interrupts (e.g. access configured as FMAC_BUFFER_ACCESS_IT):
               (+++) Configure the FMAC interrupt priority using HAL_NVIC_SetPriority().
               (+++) Enable the FMAC IRQ handler using HAL_NVIC_EnableIRQ().
               (+++) In FMAC IRQ handler, call HAL_FMAC_IRQHandler().
          (++) In case of using DMA to control data transfer (e.g. access configured
               as FMAC_BUFFER_ACCESS_DMA):
               (+++) Enable the DMA1 interface clock using __HAL_RCC_DMA1_CLK_ENABLE().
               (+++) Enable the DMAMUX1 interface clock using __HAL_RCC_DMAMUX1_CLK_ENABLE().
               (+++) If the initialisation of the internal buffers (coefficients, input,
                     output) is done via DMA, configure and enable one DMA channel for
                     managing data transfer from memory to memory (preload channel).
               (+++) If the input buffer is accessed via DMA, configure and enable one
                     DMA channel for managing data transfer from memory to peripheral
                     (input channel).
               (+++) If the output buffer is accessed via DMA, configure and enable
                     one DMA channel for managing data transfer from peripheral to
                     memory (output channel).
               (+++) Associate the initialized DMA handle(s) to the FMAC DMA handle(s)
                     using __HAL_LINKDMA().
               (+++) Configure the priority and enable the NVIC for the transfer complete
                     interrupt on the enabled DMA channel(s) using HAL_NVIC_SetPriority()
                     and HAL_NVIC_EnableIRQ().

      (#) Initialize the FMAC HAL using HAL_FMAC_Init(). This function
          resorts to HAL_FMAC_MspInit() for low-level initialization.

      (#) Configure the FMAC processing (filter) using HAL_FMAC_FilterConfig()
          or HAL_FMAC_FilterConfig_DMA().
          This function:
          (++) Defines the memory area within the FMAC internal memory
               (input, coefficients, output) and the associated threshold (input, output).
          (++) Configures the filter and its parameters:
               (+++) Finite Impulse Response (FIR) filter (also known as convolution).
               (+++) Infinite Impulse Response (IIR) filter (direct form 1).
          (++) Choose the way to access to the input and output buffers: none, polling,
               DMA, IT. "none" means the input and/or output data will be handled by
               another IP (ADC, DAC, etc.).
          (++) Enable the error interruptions in the input access and/or the output
               access is done through IT/DMA. If an error occurs, the interruption
               will be triggered in loop. In order to recover, the user will have
               to reset the IP with the sequence HAL_FMAC_DeInit / HAL_FMAC_Init.
               Optionally, he can also disable the interrupt using __HAL_FMAC_DISABLE_IT;
               the error status will be kept, but no more interrupt will be triggered.
          (++) Write the provided coefficients into the internal memory using polling
               mode (HAL_FMAC_FilterConfig()) or DMA (HAL_FMAC_FilterConfig_DMA()).
               In the DMA case, HAL_FMAC_FilterConfigCallback() is called when
               the handling is over.

       (#) Optionally, the user can enable the error interruption related to
           saturation by calling __HAL_FMAC_ENABLE_IT. This helps in debugging the
           filter. If a saturation occurs, the interruption will be triggered in loop.
           In order to recover, the user will have to:
           (++) Disable the interruption by calling __HAL_FMAC_DISABLE_IT if
                he wishes to continue all the same.
           (++) Reset the IP with the sequence HAL_FMAC_DeInit / HAL_FMAC_Init.

       (#) Optionally, preload input (FIR, IIR) and output (IIR) data using
           HAL_FMAC_FilterPreload() or HAL_FMAC_FilterPreload_DMA().
           In the DMA case, HAL_FMAC_FilterPreloadCallback() is called when
           the handling is over.
           This step is optional as the filter can be started without preloaded
           data.

       (#) Start the FMAC processing (filter) using HAL_FMAC_FilterStart().
           This function also configures the output buffer that will be filled from
           the circular internal output buffer. The function returns immediately
           without updating the provided buffer. The IP processing will be active until
           HAL_FMAC_FilterStop() is called.

       (#) If the input internal buffer is accessed via DMA, HAL_FMAC_HalfGetDataCallback()
           will be called to indicate that half of the input buffer has been handled.

       (#) If the input internal buffer is accessed via DMA or interrupt, HAL_FMAC_GetDataCallback()
           will be called to require new input data. It will be provided through
           HAL_FMAC_AppendFilterData() if the DMA isn't in circular mode.

       (#) If the output internal buffer is accessed via DMA, HAL_FMAC_HalfOutputDataReadyCallback()
           will be called to indicate that half of the output buffer has been handled.

       (#) If the output internal buffer is accessed via DMA or interrupt,
           HAL_FMAC_OutputDataReadyCallback() will be called to require a new output
           buffer. It will be provided through HAL_FMAC_ConfigFilterOutputBuffer()
           if the DMA isn't in circular mode.

       (#) In all modes except none, provide new input data to be processed via HAL_FMAC_AppendFilterData().
           This function should only be called once the previous input data has been handled
           (the preloaded input data isn't concerned).

       (#) In all modes except none, provide a new output buffer to be filled via
           HAL_FMAC_ConfigFilterOutputBuffer(). This function should only be called once the previous
           user's output buffer has been filled.

       (#) In polling mode, handle the input and output data using HAL_FMAC_PollFilterData().
           This function:
           (++) Write the user's input data (provided via HAL_FMAC_AppendFilterData())
                into the FMAC input memory area.
           (++) Read the FMAC output memory area and write it into the user's output buffer.
           It will return either when:
           (++) the user's output buffer is filled.
           (++) the user's input buffer has been handled.
           The unused data (unread input data or free output data) will not be saved.
           The user will have to use the updated input and output sizes to keep track
           of them.

       (#) Stop the FMAC processing (filter) using HAL_FMAC_FilterStop().

       (#) Call HAL_FMAC_DeInit() to de-initialize the FMAC peripheral. This function
           resorts to HAL_FMAC_MspDeInit() for low-level de-initialization.

  ##### Callback registration #####
  ==================================

    [..]
      The compilation define USE_HAL_FMAC_REGISTER_CALLBACKS when set to 1
      allows the user to configure dynamically the driver callbacks.

    [..]
      Use Function @ref HAL_FMAC_RegisterCallback() to register a user callback.
      Function @ref HAL_FMAC_RegisterCallback() allows to register following callbacks:
      (+) ErrorCallback               : Error Callback.
      (+) HalfGetDataCallback         : Get Half Data Callback.
      (+) GetDataCallback             : Get Data Callback.
      (+) HalfOutputDataReadyCallback : Half Output Data Ready Callback.
      (+) OutputDataReadyCallback     : Output Data Ready Callback.
      (+) FilterConfigCallback        : Filter Configuration Callback.
      (+) FilterPreloadCallback       : Filter Preload Callback.
      (+) MspInitCallback             : FMAC MspInit.
      (+) MspDeInitCallback           : FMAC MspDeInit.
      This function takes as parameters the HAL peripheral handle, the Callback ID
      and a pointer to the user callback function.

    [..]
      Use function @ref HAL_FMAC_UnRegisterCallback() to reset a callback to the default
      weak (surcharged) function.
      @ref HAL_FMAC_UnRegisterCallback() takes as parameters the HAL peripheral handle
      and the Callback ID.
      This function allows to reset following callbacks:
      (+) ErrorCallback               : Error Callback.
      (+) HalfGetDataCallback         : Get Half Data Callback.
      (+) GetDataCallback             : Get Data Callback.
      (+) HalfOutputDataReadyCallback : Half Output Data Ready Callback.
      (+) OutputDataReadyCallback     : Output Data Ready Callback.
      (+) FilterConfigCallback        : Filter Configuration Callback.
      (+) FilterPreloadCallback       : Filter Preload Callback.
      (+) MspInitCallback             : FMAC MspInit.
      (+) MspDeInitCallback           : FMAC MspDeInit.

    [..]
      By default, after the @ref HAL_FMAC_Init() and when the state is HAL_FMAC_STATE_RESET
      all callbacks are set to the corresponding weak (surcharged) functions:
      examples @ref HAL_FMAC_TxCpltCallback(), @ref HAL_FMAC_RxHalfCpltCallback().
      Exception done for MspInit and MspDeInit functions that are respectively
      reset to the legacy weak (surcharged) functions in the @ref HAL_FMAC_Init()
      and @ref HAL_FMAC_DeInit() only when these callbacks are null (not registered beforehand).
      If not, MspInit or MspDeInit are not null, the @ref HAL_FMAC_Init() and @ref HAL_FMAC_DeInit()
      keep and use the user MspInit/MspDeInit callbacks (registered beforehand).

    [..]
      Callbacks can be registered/unregistered in HAL_FMAC_STATE_READY state only.
      Exception done MspInit/MspDeInit that can be registered/unregistered
      in HAL_FMAC_STATE_READY or HAL_FMAC_STATE_RESET state, thus registered (user)
      MspInit/DeInit callbacks can be used during the Init/DeInit.
      In that case first register the MspInit/MspDeInit user callbacks
      using @ref HAL_FMAC_RegisterCallback() before calling @ref HAL_FMAC_DeInit()
      or @ref HAL_FMAC_Init() function.

    [..]
      When the compilation define USE_HAL_FMAC_REGISTER_CALLBACKS is set to 0 or
      not defined, the callback registration feature is not available
      and weak (surcharged) callbacks are used.


  @endverbatim
  *
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
  * All rights reserved.</center></h2>
  *
  * This software component is licensed by ST under BSD 3-Clause license,
  * the "License"; You may not use this file except in compliance with the
  * License. You may obtain a copy of the License at:
  *                        opensource.org/licenses/BSD-3-Clause
  *
  ******************************************************************************
  */

/* Includes ------------------------------------------------------------------*/
#include "stm32g4xx_hal.h"

#ifdef HAL_FMAC_MODULE_ENABLED

/** @addtogroup STM32G4xx_HAL_Driver
  * @{
  */

/** @defgroup FMAC FMAC
  * @brief    FMAC HAL driver modules
  * @{
  */

/* External variables --------------------------------------------------------*/
/* Private typedef -----------------------------------------------------------*/
/* Private defines -----------------------------------------------------------*/
/** @defgroup  FMAC_Private_Constants   FMAC Private Constants
  * @{
  */

#define MAX_FILTER_DATA_SIZE_TO_HANDLE ((uint16_t) 0xFFU)
#define PRELOAD_ACCESS_DMA     0x00U
#define PRELOAD_ACCESS_POLLING 0x01U
#define POLLING_DISABLED       0U
#define POLLING_ENABLED        1U
#define POLLING_NOT_STOPPED    0U
#define POLLING_STOPPED        1U

/**
  * @}
  */

/* Private macros ------------------------------------------------------------*/
/** @defgroup  FMAC_Private_Macros   FMAC Private Macros
  * @{
  */

/**
  * @brief  Get the X1 memory area size.
  * @param  __HANDLE__ FMAC handle.
  * @retval X1_BUF_SIZE
  */
#define FMAC_GET_X1_SIZE(__HANDLE__) \
  ((((__HANDLE__)->Instance->X1BUFCFG) & (FMAC_X1BUFCFG_X1_BUF_SIZE)) >> (FMAC_X1BUFCFG_X1_BUF_SIZE_Pos))

/**
  * @brief  Get the X1 watermark.
  * @param  __HANDLE__ FMAC handle.
  * @retval FULL_WM
  */
#define FMAC_GET_X1_FULL_WM(__HANDLE__) \
  (((__HANDLE__)->Instance->X1BUFCFG) & (FMAC_X1BUFCFG_FULL_WM))

/**
  * @brief  Get the X2 memory area size.
  * @param  __HANDLE__ FMAC handle.
  * @retval X2_BUF_SIZE
  */
#define FMAC_GET_X2_SIZE(__HANDLE__) \
  ((((__HANDLE__)->Instance->X2BUFCFG) & (FMAC_X2BUFCFG_X2_BUF_SIZE)) >> (FMAC_X2BUFCFG_X2_BUF_SIZE_Pos))

/**
  * @brief  Get the Y memory area size.
  * @param  __HANDLE__ FMAC handle.
  * @retval Y_BUF_SIZE
  */
#define FMAC_GET_Y_SIZE(__HANDLE__) \
  ((((__HANDLE__)->Instance->YBUFCFG) & (FMAC_YBUFCFG_Y_BUF_SIZE)) >> (FMAC_YBUFCFG_Y_BUF_SIZE_Pos))

/**
  * @brief  Get the Y watermark.
  * @param  __HANDLE__ FMAC handle.
  * @retval EMPTY_WM
  */
#define FMAC_GET_Y_EMPTY_WM(__HANDLE__) \
  (((__HANDLE__)->Instance->YBUFCFG) & (FMAC_YBUFCFG_EMPTY_WM))

/**
  * @brief  Get the start bit state.
  * @param  __HANDLE__ FMAC handle.
  * @retval START
  */
#define FMAC_GET_START_BIT(__HANDLE__) \
  ((((__HANDLE__)->Instance->PARAM) & (FMAC_PARAM_START)) >> (FMAC_PARAM_START_Pos))

/**
  * @brief  Get the threshold matching the watermak.
  * @param  __WM__ Watermark value.
  * @retval THRESHOLD
  */
#define FMAC_GET_THRESHOLD_FROM_WM(__WM__) ((__WM__ == FMAC_THRESHOLD_1)? 1U: \
                                            (__WM__ == FMAC_THRESHOLD_2)? 2U: \
                                            (__WM__ == FMAC_THRESHOLD_4)? 4U:8U)

/**
  * @brief  Check whether the threshold is applicable.
  * @param  __SIZE__ Size of the matching buffer.
  * @param  __WM__ Watermark value.
  * @param  __ACCESS__ Access to the buffer (polling, it, dma, none).
  * @retval THRESHOLD
  */
#define IS_FMAC_THRESHOLD_APPLICABLE(__SIZE__, __WM__, __ACCESS__) (( (__SIZE__) >= (((__WM__) == FMAC_THRESHOLD_1)? 1U: \
                                                                      ((__WM__) == FMAC_THRESHOLD_2)? 2U: \
                                                                      ((__WM__) == FMAC_THRESHOLD_4)? 4U:8U))&& \
                                                                    ((((__ACCESS__) == FMAC_BUFFER_ACCESS_DMA)&&((__WM__) == FMAC_THRESHOLD_1))|| \
                                                                     ((__ACCESS__ )!= FMAC_BUFFER_ACCESS_DMA)))

/**
  * @}
  */

/* Private variables ---------------------------------------------------------*/

/* Private function prototypes -----------------------------------------------*/

static HAL_StatusTypeDef FMAC_Reset(FMAC_HandleTypeDef *hfmac);
static void FMAC_ResetDataPointers(FMAC_HandleTypeDef *hfmac);
static void FMAC_ResetOutputStateAndDataPointers(FMAC_HandleTypeDef *hfmac);
static void FMAC_ResetInputStateAndDataPointers(FMAC_HandleTypeDef *hfmac);
static HAL_StatusTypeDef FMAC_FilterConfig(FMAC_HandleTypeDef *hfmac, FMAC_FilterConfigTypeDef *sConfig,
                                           uint8_t PreloadAccess);
static HAL_StatusTypeDef FMAC_FilterPreload(FMAC_HandleTypeDef *hfmac, int16_t *pInput, uint8_t InputSize,
                                            int16_t *pOutput, uint8_t OutputSize, uint8_t PreloadAccess);
static void FMAC_WritePreloadDataIncrementPtr(FMAC_HandleTypeDef *hfmac, int16_t **ppData, uint8_t Size);
static HAL_StatusTypeDef FMAC_WaitOnStartUntilTimeout(FMAC_HandleTypeDef *hfmac, uint32_t Tickstart, uint32_t Timeout);
static HAL_StatusTypeDef FMAC_AppendFilterDataUpdateState(FMAC_HandleTypeDef *hfmac, int16_t *pInput,
                                                          uint16_t *pInputSize);
static HAL_StatusTypeDef FMAC_ConfigFilterOutputBufferUpdateState(FMAC_HandleTypeDef *hfmac, int16_t *pOutput,
                                                                  uint16_t *pOutputSize);
static void FMAC_WriteDataIncrementPtr(FMAC_HandleTypeDef *hfmac, uint16_t MaxSizeToWrite);
static void FMAC_ReadDataIncrementPtr(FMAC_HandleTypeDef *hfmac, uint16_t MaxSizeToRead);
static void FMAC_DMAHalfGetData(DMA_HandleTypeDef *hdma);
static void FMAC_DMAGetData(DMA_HandleTypeDef *hdma);
static void FMAC_DMAHalfOutputDataReady(DMA_HandleTypeDef *hdma);
static void FMAC_DMAOutputDataReady(DMA_HandleTypeDef *hdma);
static void FMAC_DMAFilterConfig(DMA_HandleTypeDef *hdma);
static void FMAC_DMAFilterPreload(DMA_HandleTypeDef *hdma);
static void FMAC_DMAError(DMA_HandleTypeDef *hdma);

/* Private functions ---------------------------------------------------------*/

/** @defgroup FMAC_Exported_Functions FMAC Exported Functions
  * @{
  */

/** @defgroup FMAC_Exported_Functions_Group1 Initialization and de-initialization functions
  * @brief    Initialization and Configuration functions
  *
@verbatim
 ===============================================================================
     #####       Initialization and de-initialization functions       #####
 ===============================================================================
    [..] This section provides functions allowing to:
      (+) Initialize the FMAC peripheral and the associated handle
      (+) DeInitialize the FMAC peripheral
      (+) Initialize the FMAC MSP (MCU Specific Package)
      (+) De-Initialize the FMAC MSP

    [..]

@endverbatim
  * @{
  */

/**
  * @brief  Initialize the FMAC peripheral and the associated handle.
  * @param  hfmac pointer to a FMAC_HandleTypeDef structure.
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_FMAC_Init(FMAC_HandleTypeDef *hfmac)
{
  /* Check the FMAC handle allocation */
  if (hfmac == NULL)
  {
    return HAL_ERROR;
  }

  /* Check the instance */
  assert_param(IS_FMAC_ALL_INSTANCE(hfmac->Instance));

  if (hfmac->State == HAL_FMAC_STATE_RESET)
  {
    /* Allocate lock resource and initialize it */
    hfmac->Lock = HAL_UNLOCKED;

#if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1)
    /* Register the default callback functions */
    hfmac->ErrorCallback = HAL_FMAC_ErrorCallback;
    hfmac->HalfGetDataCallback = HAL_FMAC_HalfGetDataCallback;
    hfmac->GetDataCallback = HAL_FMAC_GetDataCallback;
    hfmac->HalfOutputDataReadyCallback = HAL_FMAC_HalfOutputDataReadyCallback;
    hfmac->OutputDataReadyCallback = HAL_FMAC_OutputDataReadyCallback;
    hfmac->FilterConfigCallback = HAL_FMAC_FilterConfigCallback;
    hfmac->FilterPreloadCallback = HAL_FMAC_FilterPreloadCallback;

    if (hfmac->MspInitCallback == NULL)
    {
      hfmac->MspInitCallback = HAL_FMAC_MspInit;
    }

    /* Init the low level hardware */
    hfmac->MspInitCallback(hfmac);
#else
    /* Init the low level hardware */
    HAL_FMAC_MspInit(hfmac);
#endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */
  }

  /* Reset pInput and pOutput */
  hfmac->FilterParam = 0UL;
  FMAC_ResetDataPointers(hfmac);

  /* Reset FMAC unit (internal pointers) */
  if (FMAC_Reset(hfmac) == HAL_TIMEOUT)
  {
    /* Update FMAC error code and FMAC peripheral state */
    hfmac->ErrorCode = HAL_FMAC_ERROR_RESET;
    hfmac->State = HAL_FMAC_STATE_TIMEOUT;

    /* Process Unlocked */
    __HAL_UNLOCK(hfmac);

    return HAL_TIMEOUT;
  }

  /* Update FMAC error code and FMAC peripheral state */
  hfmac->ErrorCode = HAL_FMAC_ERROR_NONE;
  hfmac->State = HAL_FMAC_STATE_READY;

  /* Process Unlocked */
  __HAL_UNLOCK(hfmac);

  return HAL_OK;
}

/**
  * @brief  De-initialize the FMAC peripheral.
  * @param  hfmac pointer to a FMAC structure.
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_FMAC_DeInit(FMAC_HandleTypeDef *hfmac)
{
  /* Check the FMAC handle allocation */
  if (hfmac == NULL)
  {
    return HAL_ERROR;
  }

  /* Check the parameters */
  assert_param(IS_FMAC_ALL_INSTANCE(hfmac->Instance));

  /* Change FMAC peripheral state */
  hfmac->State = HAL_FMAC_STATE_BUSY;

  /* Set FMAC error code to none */
  hfmac->ErrorCode = HAL_FMAC_ERROR_NONE;

  /* Reset pInput and pOutput */
  hfmac->FilterParam = 0UL;
  FMAC_ResetDataPointers(hfmac);

#if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1)
  if (hfmac->MspDeInitCallback == NULL)
  {
    hfmac->MspDeInitCallback = HAL_FMAC_MspDeInit;
  }
  /* DeInit the low level hardware */
  hfmac->MspDeInitCallback(hfmac);
#else
  /* DeInit the low level hardware: CLOCK, NVIC, DMA */
  HAL_FMAC_MspDeInit(hfmac);
#endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */

  /* Change FMAC peripheral state */
  hfmac->State = HAL_FMAC_STATE_RESET;

  /* Release Lock */
  __HAL_UNLOCK(hfmac);

  /* Return function status */
  return HAL_OK;
}

/**
  * @brief  Initialize the FMAC MSP.
  * @param  hfmac FMAC handle.
  * @retval None
  */
__weak void HAL_FMAC_MspInit(FMAC_HandleTypeDef *hfmac)
{
  /* Prevent unused argument(s) compilation warning */
  UNUSED(hfmac);

  /* NOTE : This function should not be modified, when the callback is needed,
            the HAL_FMAC_MspInit can be implemented in the user file
   */
}

/**
  * @brief  De-initialize the FMAC MSP.
  * @param  hfmac FMAC handle.
  * @retval None
  */
__weak void HAL_FMAC_MspDeInit(FMAC_HandleTypeDef *hfmac)
{
  /* Prevent unused argument(s) compilation warning */
  UNUSED(hfmac);

  /* NOTE : This function should not be modified, when the callback is needed,
            the HAL_FMAC_MspDeInit can be implemented in the user file
   */
}

#if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1)
/**
  * @brief  Register a User FMAC Callback
  *         to be used instead of the weak predefined callback.
  * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
  *         the configuration information for FMAC module.
  * @param  CallbackID ID of the callback to be registered.
  *         This parameter can be one of the following values:
  *           @arg @ref HAL_FMAC_ERROR_CB_ID Error Callback ID
  *           @arg @ref HAL_FMAC_HALF_GET_DATA_CB_ID Get Half Data Callback ID
  *           @arg @ref HAL_FMAC_GET_DATA_CB_ID Get Data Callback ID
  *           @arg @ref HAL_FMAC_HALF_OUTPUT_DATA_READY_CB_ID Half Output Data Ready Callback ID
  *           @arg @ref HAL_FMAC_OUTPUT_DATA_READY_CB_ID Output Data Ready Callback ID
  *           @arg @ref HAL_FMAC_FILTER_CONFIG_CB_ID Filter Configuration Callback ID
  *           @arg @ref HAL_FMAC_FILTER_PRELOAD_CB_ID Filter Preload Callback ID
  *           @arg @ref HAL_FMAC_MSPINIT_CB_ID FMAC MspInit ID
  *           @arg @ref HAL_FMAC_MSPDEINIT_CB_ID FMAC MspDeInit ID
  * @param  pCallback pointer to the Callback function.
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_FMAC_RegisterCallback(FMAC_HandleTypeDef *hfmac, HAL_FMAC_CallbackIDTypeDef CallbackID,
                                            pFMAC_CallbackTypeDef pCallback)
{
  HAL_StatusTypeDef status = HAL_OK;

  if (pCallback == NULL)
  {
    /* Update the error code */
    hfmac->ErrorCode |= HAL_FMAC_ERROR_INVALID_CALLBACK;

    return HAL_ERROR;
  }
  /* Process locked */
  __HAL_LOCK(hfmac);

  if (HAL_FMAC_STATE_READY == hfmac->State)
  {
    switch (CallbackID)
    {
      case HAL_FMAC_ERROR_CB_ID :
        hfmac->ErrorCallback = pCallback;
        break;

      case HAL_FMAC_HALF_GET_DATA_CB_ID :
        hfmac->HalfGetDataCallback = pCallback;
        break;

      case HAL_FMAC_GET_DATA_CB_ID :
        hfmac->GetDataCallback = pCallback;
        break;

      case HAL_FMAC_HALF_OUTPUT_DATA_READY_CB_ID :
        hfmac->HalfOutputDataReadyCallback = pCallback;
        break;

      case HAL_FMAC_OUTPUT_DATA_READY_CB_ID :
        hfmac->OutputDataReadyCallback = pCallback;
        break;

      case HAL_FMAC_FILTER_CONFIG_CB_ID :
        hfmac->FilterConfigCallback = pCallback;
        break;

      case HAL_FMAC_FILTER_PRELOAD_CB_ID :
        hfmac->FilterPreloadCallback = pCallback;
        break;

      case HAL_FMAC_MSPINIT_CB_ID :
        hfmac->MspInitCallback = pCallback;
        break;

      case HAL_FMAC_MSPDEINIT_CB_ID :
        hfmac->MspDeInitCallback = pCallback;
        break;

      default :
        /* Update the error code */
        hfmac->ErrorCode |= HAL_FMAC_ERROR_INVALID_CALLBACK;

        /* Return error status */
        status =  HAL_ERROR;
        break;
    }
  }
  else if (HAL_FMAC_STATE_RESET == hfmac->State)
  {
    switch (CallbackID)
    {
      case HAL_FMAC_MSPINIT_CB_ID :
        hfmac->MspInitCallback = pCallback;
        break;

      case HAL_FMAC_MSPDEINIT_CB_ID :
        hfmac->MspDeInitCallback = pCallback;
        break;

      default :
        /* Update the error code */
        hfmac->ErrorCode |= HAL_FMAC_ERROR_INVALID_CALLBACK;

        /* Return error status */
        status =  HAL_ERROR;
        break;
    }
  }
  else
  {
    /* Update the error code */
    hfmac->ErrorCode |= HAL_FMAC_ERROR_INVALID_CALLBACK;

    /* Return error status */
    status =  HAL_ERROR;
  }

  /* Release Lock */
  __HAL_UNLOCK(hfmac);

  return status;
}

/**
  * @brief  Unregister a FMAC CallBack.
  *         FMAC callback is redirected to the weak predefined callback.
  * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
  *         the configuration information for FMAC module
  * @param  CallbackID ID of the callback to be unregistered.
  *         This parameter can be one of the following values:
  *           @arg @ref HAL_FMAC_ERROR_CB_ID Error Callback ID
  *           @arg @ref HAL_FMAC_HALF_GET_DATA_CB_ID Get Half Data Callback ID
  *           @arg @ref HAL_FMAC_GET_DATA_CB_ID Get Data Callback ID
  *           @arg @ref HAL_FMAC_HALF_OUTPUT_DATA_READY_CB_ID Half Output Data Ready Callback ID
  *           @arg @ref HAL_FMAC_OUTPUT_DATA_READY_CB_ID Output Data Ready Callback ID
  *           @arg @ref HAL_FMAC_FILTER_CONFIG_CB_ID Filter Configuration Callback ID
  *           @arg @ref HAL_FMAC_FILTER_PRELOAD_CB_ID Filter Preload Callback ID
  *           @arg @ref HAL_FMAC_MSPINIT_CB_ID FMAC MspInit ID
  *           @arg @ref HAL_FMAC_MSPDEINIT_CB_ID FMAC MspDeInit ID
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_FMAC_UnRegisterCallback(FMAC_HandleTypeDef *hfmac, HAL_FMAC_CallbackIDTypeDef CallbackID)
{
  HAL_StatusTypeDef status = HAL_OK;

  /* Process locked */
  __HAL_LOCK(hfmac);

  if (HAL_FMAC_STATE_READY == hfmac->State)
  {
    switch (CallbackID)
    {
      case HAL_FMAC_ERROR_CB_ID :
        hfmac->ErrorCallback = HAL_FMAC_ErrorCallback;                             /* Legacy weak ErrorCallback               */
        break;

      case HAL_FMAC_HALF_GET_DATA_CB_ID :
        hfmac->HalfGetDataCallback = HAL_FMAC_HalfGetDataCallback;                 /* Legacy weak HalfGetDataCallback         */
        break;

      case HAL_FMAC_GET_DATA_CB_ID :
        hfmac->GetDataCallback = HAL_FMAC_GetDataCallback;                         /* Legacy weak GetDataCallback             */
        break;

      case HAL_FMAC_HALF_OUTPUT_DATA_READY_CB_ID :
        hfmac->HalfOutputDataReadyCallback = HAL_FMAC_HalfOutputDataReadyCallback; /* Legacy weak HalfOutputDataReadyCallback */
        break;

      case HAL_FMAC_OUTPUT_DATA_READY_CB_ID :
        hfmac->OutputDataReadyCallback = HAL_FMAC_OutputDataReadyCallback;         /* Legacy weak OutputDataReadyCallback     */
        break;

      case HAL_FMAC_FILTER_CONFIG_CB_ID :
        hfmac->FilterConfigCallback = HAL_FMAC_FilterConfigCallback;               /* Legacy weak FilterConfigCallback        */
        break;

      case HAL_FMAC_FILTER_PRELOAD_CB_ID :
        hfmac->FilterPreloadCallback = HAL_FMAC_FilterPreloadCallback;             /* Legacy weak FilterPreloadCallback       */
        break;

      case HAL_FMAC_MSPINIT_CB_ID :
        hfmac->MspInitCallback = HAL_FMAC_MspInit;                                 /* Legacy weak MspInitCallback             */
        break;

      case HAL_FMAC_MSPDEINIT_CB_ID :
        hfmac->MspDeInitCallback = HAL_FMAC_MspDeInit;                             /* Legacy weak MspDeInitCallback           */
        break;

      default :
        /* Update the error code */
        hfmac->ErrorCode |= HAL_FMAC_ERROR_INVALID_CALLBACK;

        /* Return error status */
        status =  HAL_ERROR;
        break;
    }
  }
  else if (HAL_FMAC_STATE_RESET == hfmac->State)
  {
    switch (CallbackID)
    {
      case HAL_FMAC_MSPINIT_CB_ID :
        hfmac->MspInitCallback = HAL_FMAC_MspInit;
        break;

      case HAL_FMAC_MSPDEINIT_CB_ID :
        hfmac->MspDeInitCallback = HAL_FMAC_MspDeInit;
        break;

      default :
        /* Update the error code */
        hfmac->ErrorCode |= HAL_FMAC_ERROR_INVALID_CALLBACK;

        /* Return error status */
        status =  HAL_ERROR;
        break;
    }
  }
  else
  {
    /* Update the error code */
    hfmac->ErrorCode |= HAL_FMAC_ERROR_INVALID_CALLBACK;

    /* Return error status */
    status = HAL_ERROR;
  }

  /* Release Lock */
  __HAL_UNLOCK(hfmac);

  return status;
}
#endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */

/**
  * @}
  */

/** @defgroup FMAC_Exported_Functions_Group2 Peripheral Control functions
  * @brief    Control functions.
  *
@verbatim
  ==============================================================================
                      ##### Peripheral Control functions #####
  ==============================================================================
    [..]  This section provides functions allowing to:
      (+) Configure the FMAC peripheral: memory area, filter type and parameters,
          way to access to the input and output memory area (none, polling, IT, DMA).
      (+) Start the FMAC processing (filter).
      (+) Handle the input data that will be provided into FMAC.
      (+) Handle the output data provided by FMAC.
      (+) Stop the FMAC processing (filter).

@endverbatim
  * @{
  */

/**
  * @brief  Configure the FMAC filter according to the parameters
  *         specified in the FMAC_FilterConfigTypeDef structure.
  *         The provided data will be loaded using polling mode.
  * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
  *         the configuration information for FMAC module.
  * @param  sConfig pointer to a FMAC_FilterConfigTypeDef structure that
  *         contains the FMAC configuration information.
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_FMAC_FilterConfig(FMAC_HandleTypeDef *hfmac, FMAC_FilterConfigTypeDef *sConfig)
{
  return (FMAC_FilterConfig(hfmac, sConfig, PRELOAD_ACCESS_POLLING));
}

/**
  * @brief  Configure the FMAC filter according to the parameters
  *         specified in the FMAC_FilterConfigTypeDef structure.
  *         The provided data will be loaded using DMA.
  * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
  *         the configuration information for FMAC module.
  * @param  sConfig pointer to a FMAC_FilterConfigTypeDef structure that
  *         contains the FMAC configuration information.
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_FMAC_FilterConfig_DMA(FMAC_HandleTypeDef *hfmac, FMAC_FilterConfigTypeDef *sConfig)
{
  return (FMAC_FilterConfig(hfmac, sConfig, PRELOAD_ACCESS_DMA));
}

/**
  * @brief  Preload the input (FIR, IIR) and output data (IIR) of the FMAC filter.
  *         They will be used by FMAC as soon as HAL_FMAC_FilterStart is called.
  *         The provided data will be loaded using polling mode.
  * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
  *         the configuration information for FMAC module.
  * @param  pInput Preloading of the first elements of the input buffer (X1).
  *         If not needed (no data available when starting), it should be set to NULL.
  * @param  InputSize Size of the input vector.
  *         As pInput is used for preloading data, it cannot be bigger than the input memory area.
  * @param  pOutput [IIR] Preloading of the first elements of the output vector (Y).
  *         If not needed, it should be set to NULL.
  * @param  OutputSize Size of the output vector.
  *         As pOutput is used for preloading data, it cannot be bigger than the output memory area.
  * @note   The input and the output buffers can be filled by calling several times HAL_FMAC_FilterPreload
  *         (each call filling partly the buffers). In case of overflow (too much data provided through
  *         all these calls), an error will be returned.
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_FMAC_FilterPreload(FMAC_HandleTypeDef *hfmac, int16_t *pInput, uint8_t InputSize,
                                         int16_t *pOutput, uint8_t OutputSize)
{
  return (FMAC_FilterPreload(hfmac, pInput, InputSize, pOutput, OutputSize, PRELOAD_ACCESS_POLLING));
}

/**
  * @brief  Preload the input (FIR, IIR) and output data (IIR) of the FMAC filter.
  *         They will be used by FMAC as soon as HAL_FMAC_FilterStart is called.
  *         The provided data will be loaded using DMA.
  * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
  *         the configuration information for FMAC module.
  * @param  pInput Preloading of the first elements of the input buffer (X1).
  *         If not needed (no data available when starting), it should be set to NULL.
  * @param  InputSize Size of the input vector.
  *         As pInput is used for preloading data, it cannot be bigger than the input memory area.
  * @param  pOutput [IIR] Preloading of the first elements of the output vector (Y).
  *         If not needed, it should be set to NULL.
  * @param  OutputSize Size of the output vector.
  *         As pOutput is used for preloading data, it cannot be bigger than the output memory area.
  * @note   The input and the output buffers can be filled by calling several times HAL_FMAC_FilterPreload
  *         (each call filling partly the buffers). In case of overflow (too much data provided through
  *         all these calls), an error will be returned.
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_FMAC_FilterPreload_DMA(FMAC_HandleTypeDef *hfmac, int16_t *pInput, uint8_t InputSize,
                                             int16_t *pOutput, uint8_t OutputSize)
{
  return (FMAC_FilterPreload(hfmac, pInput, InputSize, pOutput, OutputSize, PRELOAD_ACCESS_DMA));
}


/**
  * @brief  Start the FMAC processing according to the existing FMAC configuration.
  * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
  *         the configuration information for FMAC module.
  * @param  pOutput pointer to buffer where output data of FMAC processing will be stored
  *         in the next steps.
  *         If it is set to NULL, the output will not be read and it will be up to
  *         an external IP to empty the output buffer.
  * @param  pOutputSize pointer to the size of the output buffer. The number of read data will be written here.
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_FMAC_FilterStart(FMAC_HandleTypeDef *hfmac, int16_t *pOutput, uint16_t *pOutputSize)
{
  uint32_t tmpcr = 0UL;
  HAL_StatusTypeDef status;

  /* Check the START bit state */
  if (FMAC_GET_START_BIT(hfmac) != 0UL)
  {
    return HAL_ERROR;
  }

  /* Check that a valid configuration was done previously */
  if (hfmac->FilterParam == 0UL)
  {
    return HAL_ERROR;
  }

  /* Check handle state is ready */
  if (hfmac->State == HAL_FMAC_STATE_READY)
  {
    /* Change the FMAC state */
    hfmac->State = HAL_FMAC_STATE_BUSY;

    /* CR: Configure the input access (error interruptions enabled only for IT or DMA) */
    if (hfmac->InputAccess == FMAC_BUFFER_ACCESS_DMA)
    {
      tmpcr |= FMAC_DMA_WEN;
    }
    else if (hfmac->InputAccess == FMAC_BUFFER_ACCESS_IT)
    {
      tmpcr |= FMAC_IT_WIEN;
    }
    else
    {
      /* nothing to do */
    }

    /* CR: Configure the output access (error interruptions enabled only for IT or DMA) */
    if (hfmac->OutputAccess == FMAC_BUFFER_ACCESS_DMA)
    {
      tmpcr |= FMAC_DMA_REN;
    }
    else if (hfmac->OutputAccess == FMAC_BUFFER_ACCESS_IT)
    {
      tmpcr |= FMAC_IT_RIEN;
    }
    else
    {
      /* nothing to do */
    }

    /* CR: Write the configuration */
    MODIFY_REG(hfmac->Instance->CR, \
               FMAC_IT_RIEN | FMAC_IT_WIEN | FMAC_DMA_REN | FMAC_CR_DMAWEN, \
               tmpcr);

    /* Register the new output buffer */
    status = FMAC_ConfigFilterOutputBufferUpdateState(hfmac, pOutput, pOutputSize);

    if (status == HAL_OK)
    {
      /* PARAM: Start the filter ( this can generate interrupts before the end of the HAL_FMAC_FilterStart ) */
      WRITE_REG(hfmac->Instance->PARAM, (uint32_t)(hfmac->FilterParam));
    }

    /* Reset the busy flag (do not overwrite the possible write and read flag) */
    hfmac->State = HAL_FMAC_STATE_READY;

    /* Return function status */
    return status;
  }
  else
  {
    /* Return function status */
    return HAL_BUSY;
  }
}

/**
  * @brief  Provide a new input buffer that will be loaded into the FMAC
  *         input memory area.
  * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
  *         the configuration information for FMAC module.
  * @param  pInput New input vector (additional input data).
  * @param  pInputSize Size of the input vector (if all the data can't be
  *         written, it will be updated with the number of data read from FMAC).
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_FMAC_AppendFilterData(FMAC_HandleTypeDef *hfmac, int16_t *pInput, uint16_t *pInputSize)
{
  /* Check the START bit state */
  if (FMAC_GET_START_BIT(hfmac) == 0UL)
  {
    return HAL_ERROR;
  }

  /* Check the function parameters */
  if ((pInput == NULL) || (pInputSize == NULL))
  {
    return HAL_ERROR;
  }
  if (*pInputSize == 0U)
  {
    return HAL_ERROR;
  }

  /* Check the FMAC configuration */
  if (hfmac->InputAccess == FMAC_BUFFER_ACCESS_NONE)
  {
    return HAL_ERROR;
  }

  /* Check whether the previous input vector has been handled */
  if ((hfmac->pInputSize != NULL) && (hfmac->InputCurrentSize < * (hfmac->pInputSize)))
  {
    return HAL_BUSY;
  }

  /* Check that FMAC was initialized and that no writing is already ongoing */
  if (hfmac->WrState == HAL_FMAC_STATE_READY)
  {
    /* Register the new input buffer */
    return (FMAC_AppendFilterDataUpdateState(hfmac, pInput, pInputSize));
  }
  else
  {
    /* Return function status */
    return HAL_BUSY;
  }
}

/**
  * @brief  Provide a new output buffer to be filled with the data
  *         computed by FMAC unit.
  * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
  *         the configuration information for FMAC module.
  * @param  pOutput New output vector.
  * @param  pOutputSize Size of the output vector (if the vector can't
  *         be entirely filled, pOutputSize will be updated with the number
  *         of data read from FMAC).
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_FMAC_ConfigFilterOutputBuffer(FMAC_HandleTypeDef *hfmac, int16_t *pOutput, uint16_t *pOutputSize)
{
  /* Check the START bit state */
  if (FMAC_GET_START_BIT(hfmac) == 0UL)
  {
    return HAL_ERROR;
  }

  /* Check the function parameters */
  if ((pOutput == NULL) || (pOutputSize == NULL))
  {
    return HAL_ERROR;
  }
  if (*pOutputSize == 0U)
  {
    return HAL_ERROR;
  }

  /* Check the FMAC configuration */
  if (hfmac->OutputAccess == FMAC_BUFFER_ACCESS_NONE)
  {
    return HAL_ERROR;
  }

  /* Check whether the previous output vector has been handled */
  if ((hfmac->pOutputSize != NULL) && (hfmac->OutputCurrentSize < * (hfmac->pOutputSize)))
  {
    return HAL_BUSY;
  }

  /* Check that FMAC was initialized and that not reading is already ongoing */
  if (hfmac->RdState == HAL_FMAC_STATE_READY)
  {
    /* Register the new output buffer */
    return (FMAC_ConfigFilterOutputBufferUpdateState(hfmac, pOutput, pOutputSize));
  }
  else
  {
    /* Return function status */
    return HAL_BUSY;
  }
}

/**
  * @brief  Write the previously provided user's input data and
  *         fill the previously provided user's output buffer,
  *         according to the existing FMAC configuration (polling mode only).
  *         The function returns when the input data has been handled or
  *         when the output data is filled. The possible unused data isn't
  *         kept. It will be up to the user to handle it. The previously
  *         provided pInputSize and pOutputSize will be used to indicate to the
  *         size of the read/written data to the user.
  * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
  *         the configuration information for FMAC module.
  * @param  Timeout timeout value.
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_FMAC_PollFilterData(FMAC_HandleTypeDef *hfmac, uint32_t Timeout)
{
  uint32_t tickstart;
  uint8_t inpolling;
  uint8_t inpollingover = POLLING_NOT_STOPPED;
  uint8_t outpolling;
  uint8_t outpollingover = POLLING_NOT_STOPPED;

  /* Check the START bit state */
  if (FMAC_GET_START_BIT(hfmac) == 0UL)
  {
    return HAL_ERROR;
  }

  /* Check the configuration */

  /* Get the input and output mode (if no buffer was previously provided, nothing will be read/written) */
  if ((hfmac->InputAccess  == FMAC_BUFFER_ACCESS_POLLING) && (hfmac->pInput  != NULL))
  {
    inpolling = POLLING_ENABLED;
  }
  else
  {
    inpolling = POLLING_DISABLED;
  }
  if ((hfmac->OutputAccess == FMAC_BUFFER_ACCESS_POLLING) && (hfmac->pOutput != NULL))
  {
    outpolling = POLLING_ENABLED;
  }
  else
  {
    outpolling = POLLING_DISABLED;
  }

  /* Check the configuration */
  if ((inpolling == POLLING_DISABLED) && (outpolling == POLLING_DISABLED))
  {
    return HAL_ERROR;
  }

  /* Check handle state is ready */
  if (hfmac->State == HAL_FMAC_STATE_READY)
  {
    /* Change the FMAC state */
    hfmac->State = HAL_FMAC_STATE_BUSY;

    /* Get tick */
    tickstart = HAL_GetTick();

    /* Loop on reading and writing until timeout */
    while ((HAL_GetTick() - tickstart) < Timeout)
    {
      /* X1: Check the mode: polling or none */
      if (inpolling != POLLING_DISABLED)
      {
        FMAC_WriteDataIncrementPtr(hfmac, MAX_FILTER_DATA_SIZE_TO_HANDLE);
        if (hfmac->InputCurrentSize == *(hfmac->pInputSize))
        {
          inpollingover = POLLING_STOPPED;
        }
      }

      /* Y: Check the mode: polling or none */
      if (outpolling != POLLING_DISABLED)
      {
        FMAC_ReadDataIncrementPtr(hfmac, MAX_FILTER_DATA_SIZE_TO_HANDLE);
        if (hfmac->OutputCurrentSize == *(hfmac->pOutputSize))
        {
          outpollingover = POLLING_STOPPED;
        }
      }

      /* Exit if there isn't data to handle anymore on one side or another */
      if ((inpollingover != POLLING_NOT_STOPPED) || (outpollingover != POLLING_NOT_STOPPED))
      {
        break;
      }
    }

    /* Change the FMAC state; update the input and output sizes; reset the indexes */
    if (inpolling != POLLING_DISABLED)
    {
      (*(hfmac->pInputSize))  = hfmac->InputCurrentSize;
      FMAC_ResetInputStateAndDataPointers(hfmac);
    }
    if (outpolling != POLLING_DISABLED)
    {
      (*(hfmac->pOutputSize)) = hfmac->OutputCurrentSize;
      FMAC_ResetOutputStateAndDataPointers(hfmac);
    }

    /* Reset the busy flag (do not overwrite the possible write and read flag) */
    hfmac->State = HAL_FMAC_STATE_READY;

    /* Return function status */
    if ((HAL_GetTick() - tickstart) >= Timeout)
    {
      return HAL_TIMEOUT;
    }
    else
    {
      return HAL_OK;
    }
  }
  else
  {
    /* Return function status */
    return HAL_BUSY;
  }
}

/**
  * @brief  Stop the FMAC processing.
  * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
  *         the configuration information for FMAC module.
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_FMAC_FilterStop(FMAC_HandleTypeDef *hfmac)
{

  /* Check the START bit state */
  if (FMAC_GET_START_BIT(hfmac) == 0UL)
  {
    return HAL_ERROR;
  }

  /* Check handle state is ready */
  if (hfmac->State == HAL_FMAC_STATE_READY)
  {
    /* Set the START bit to 0 (stop the previously configured filter) */
    CLEAR_BIT(hfmac->Instance->PARAM, FMAC_PARAM_START);

    /* Disable the interrupts in order to avoid crossing cases */
    CLEAR_BIT(hfmac->Instance->CR, FMAC_DMA_REN | FMAC_DMA_WEN | FMAC_IT_RIEN | FMAC_IT_WIEN);

    /* In case of IT, update the sizes */
    if ((hfmac->InputAccess == FMAC_BUFFER_ACCESS_IT) && (hfmac->pInput != NULL))
    {
      (*(hfmac->pInputSize))  = hfmac->InputCurrentSize;
    }
    if ((hfmac->OutputAccess == FMAC_BUFFER_ACCESS_IT) && (hfmac->pOutput != NULL))
    {
      (*(hfmac->pOutputSize)) = hfmac->OutputCurrentSize;
    }

    /* Reset FMAC unit (internal pointers) */
    if (FMAC_Reset(hfmac) == HAL_TIMEOUT)
    {
      /* Update FMAC error code and FMAC peripheral state */
      hfmac->ErrorCode = HAL_FMAC_ERROR_RESET;
      hfmac->State = HAL_FMAC_STATE_TIMEOUT;
      return HAL_TIMEOUT;
    }

    /* Reset the data pointers */
    FMAC_ResetDataPointers(hfmac);

    /* Return function status */
    return HAL_OK;
  }
  else
  {
    /* Return function status */
    return HAL_BUSY;
  }
}

/**
  * @}
  */

/** @defgroup FMAC_Exported_Functions_Group3 Callback functions
  * @brief    Callback functions.
  *
@verbatim
  ==============================================================================
                      ##### Callback functions  #####
  ==============================================================================
    [..]  This section provides Interruption and DMA callback functions:
      (+) DMA or Interrupt: the user's input data is half written (DMA only)
          or completely written.
      (+) DMA or Interrupt: the user's output buffer is half filled (DMA only)
          or completely filled.
      (+) DMA or Interrupt: error handling.

@endverbatim
  * @{
  */

/**
  * @brief  FMAC error callback.
  * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
  *         the configuration information for FMAC module.
  * @retval None
  */
__weak void HAL_FMAC_ErrorCallback(FMAC_HandleTypeDef *hfmac)
{
  /* Prevent unused argument(s) compilation warning */
  UNUSED(hfmac);

  /* NOTE : This function should not be modified; when the callback is needed,
            the HAL_FMAC_ErrorCallback can be implemented in the user file.
   */
}

/**
  * @brief  FMAC get half data callback.
  * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
  *         the configuration information for FMAC module.
  * @retval None
  */
__weak void HAL_FMAC_HalfGetDataCallback(FMAC_HandleTypeDef *hfmac)
{
  /* Prevent unused argument(s) compilation warning */
  UNUSED(hfmac);

  /* NOTE : This function should not be modified; when the callback is needed,
            the HAL_FMAC_HalfGetDataCallback can be implemented in the user file.
   */
}

/**
  * @brief  FMAC get data callback.
  * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
  *         the configuration information for FMAC module.
  * @retval None
  */
__weak void HAL_FMAC_GetDataCallback(FMAC_HandleTypeDef *hfmac)
{
  /* Prevent unused argument(s) compilation warning */
  UNUSED(hfmac);

  /* NOTE : This function should not be modified; when the callback is needed,
            the HAL_FMAC_GetDataCallback can be implemented in the user file.
   */
}

/**
  * @brief  FMAC half output data ready callback.
  * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
  *         the configuration information for FMAC module.
  * @retval None
  */
__weak void HAL_FMAC_HalfOutputDataReadyCallback(FMAC_HandleTypeDef *hfmac)
{
  /* Prevent unused argument(s) compilation warning */
  UNUSED(hfmac);

  /* NOTE : This function should not be modified; when the callback is needed,
            the HAL_FMAC_HalfOutputDataReadyCallback can be implemented in the user file.
   */
}

/**
  * @brief  FMAC output data ready callback.
  * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
  *         the configuration information for FMAC module.
  * @retval None
  */
__weak void HAL_FMAC_OutputDataReadyCallback(FMAC_HandleTypeDef *hfmac)
{
  /* Prevent unused argument(s) compilation warning */
  UNUSED(hfmac);

  /* NOTE : This function should not be modified; when the callback is needed,
            the HAL_FMAC_OutputDataReadyCallback can be implemented in the user file.
   */
}

/**
  * @brief  FMAC filter configuration callback.
  * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
  *         the configuration information for FMAC module.
  * @retval None
  */
__weak void HAL_FMAC_FilterConfigCallback(FMAC_HandleTypeDef *hfmac)
{
  /* Prevent unused argument(s) compilation warning */
  UNUSED(hfmac);

  /* NOTE : This function should not be modified; when the callback is needed,
            the HAL_FMAC_FilterConfigCallback can be implemented in the user file.
   */
}

/**
  * @brief  FMAC filter preload callback.
  * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
  *         the configuration information for FMAC module.
  * @retval None
  */
__weak void HAL_FMAC_FilterPreloadCallback(FMAC_HandleTypeDef *hfmac)
{
  /* Prevent unused argument(s) compilation warning */
  UNUSED(hfmac);

  /* NOTE : This function should not be modified; when the callback is needed,
            the HAL_FMAC_FilterPreloadCallback can be implemented in the user file.
   */
}

/**
  * @}
  */

/** @defgroup FMAC_Exported_Functions_Group4 IRQ handler management
  * @brief    IRQ handler.
  *
@verbatim
  ==============================================================================
                ##### IRQ handler management #####
  ==============================================================================
[..]  This section provides IRQ handler function.

@endverbatim
  * @{
  */

/**
  * @brief  Handle FMAC interrupt request.
  * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
  *         the configuration information for FMAC module.
  * @retval None
  */
void HAL_FMAC_IRQHandler(FMAC_HandleTypeDef *hfmac)
{
  uint32_t itsource;

  /* Check if the read interrupt is enabled and if Y buffer empty flag isn't set */
  itsource = __HAL_FMAC_GET_IT_SOURCE(hfmac, FMAC_IT_RIEN);
  if ((__HAL_FMAC_GET_FLAG(hfmac, FMAC_FLAG_YEMPTY) == 0U) && (itsource != 0UL))
  {
    /* Read some data if possible (Y size is used as a pseudo timeout in order
       to not get stuck too long under IT if FMAC keeps on processing input
       data reloaded via DMA for instance). */
    if (hfmac->pOutput != NULL)
    {
      FMAC_ReadDataIncrementPtr(hfmac, (uint16_t)FMAC_GET_Y_SIZE(hfmac));
    }

    /* Indicate that data is ready to be read */
    if ((hfmac->pOutput == NULL) || (hfmac->OutputCurrentSize == *(hfmac->pOutputSize)))
    {
      /* Reset the pointers to indicate new data will be needed */
      FMAC_ResetOutputStateAndDataPointers(hfmac);

      /* Call the output data ready callback */
#if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1)
      hfmac->OutputDataReadyCallback(hfmac);
#else
      HAL_FMAC_OutputDataReadyCallback(hfmac);
#endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */
    }
  }

  /* Check if the write interrupt is enabled and if X1 buffer full flag isn't set */
  itsource = __HAL_FMAC_GET_IT_SOURCE(hfmac, FMAC_IT_WIEN);
  if ((__HAL_FMAC_GET_FLAG(hfmac, FMAC_FLAG_X1FULL) == 0U) && (itsource != 0UL))
  {
    /* Write some data if possible (X1 size is used as a pseudo timeout in order
       to not get stuck too long under IT if FMAC keep on processing input
       data whereas its output emptied via DMA for instance). */
    if (hfmac->pInput != NULL)
    {
      FMAC_WriteDataIncrementPtr(hfmac, (uint16_t)FMAC_GET_X1_SIZE(hfmac));
    }

    /* Indicate that new data will be needed */
    if ((hfmac->pInput == NULL) || (hfmac->InputCurrentSize == *(hfmac->pInputSize)))
    {
      /* Reset the pointers to indicate new data will be needed */
      FMAC_ResetInputStateAndDataPointers(hfmac);

      /* Call the get data callback */
#if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1)
      hfmac->GetDataCallback(hfmac);
#else
      HAL_FMAC_GetDataCallback(hfmac);
#endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */
    }
  }

  /* Check if the overflow error interrupt is enabled and if overflow error flag is raised */
  itsource = __HAL_FMAC_GET_IT_SOURCE(hfmac, FMAC_IT_OVFLIEN);
  if ((__HAL_FMAC_GET_FLAG(hfmac, FMAC_FLAG_OVFL) != 0U) && (itsource != 0UL))
  {
    hfmac->ErrorCode |= HAL_FMAC_ERROR_OVFL;
  }

  /* Check if the underflow error interrupt is enabled and if underflow error flag is raised */
  itsource = __HAL_FMAC_GET_IT_SOURCE(hfmac, FMAC_IT_UNFLIEN);
  if ((__HAL_FMAC_GET_FLAG(hfmac, FMAC_FLAG_UNFL) != 0U) && (itsource != 0UL))
  {
    hfmac->ErrorCode |= HAL_FMAC_ERROR_UNFL;
  }

  /* Check if the saturation error interrupt is enabled and if saturation error flag is raised */
  itsource = __HAL_FMAC_GET_IT_SOURCE(hfmac, FMAC_IT_SATIEN);
  if ((__HAL_FMAC_GET_FLAG(hfmac, FMAC_FLAG_SAT) != 0U) && (itsource != 0UL))
  {
    hfmac->ErrorCode |= HAL_FMAC_ERROR_SAT;
  }

  /* Call the error callback if an error occurred */
  if (hfmac->ErrorCode != HAL_FMAC_ERROR_NONE)
  {
    /* Call the error callback */
#if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1)
    hfmac->ErrorCallback(hfmac);
#else
    HAL_FMAC_ErrorCallback(hfmac);
#endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */
  }
}

/**
  * @}
  */

/** @defgroup FMAC_Exported_Functions_Group5 Peripheral State functions
  * @brief    Peripheral State functions.
  *
@verbatim
  ==============================================================================
                      ##### Peripheral State functions #####
  ==============================================================================
    [..]
    This subsection permits to get in run-time the status of the peripheral.

@endverbatim
  * @{
  */

/**
  * @brief  Return the FMAC handle state.
  * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
  *         the configuration information for FMAC module.
  * @retval HAL state
  */
HAL_FMAC_StateTypeDef HAL_FMAC_GetState(FMAC_HandleTypeDef *hfmac)
{
  /* Return FMAC handle state */
  return hfmac->State;
}

/**
  * @brief  Return the FMAC peripheral error.
  * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
  *         the configuration information for FMAC module.
  * @note   The returned error is a bit-map combination of possible errors.
  * @retval Error bit-map
  */
uint32_t HAL_FMAC_GetError(FMAC_HandleTypeDef *hfmac)
{
  /* Return FMAC error code */
  return hfmac->ErrorCode;
}

/**
  * @}
  */

/**
  * @}
  */

/** @defgroup FMAC_Private_Functions FMAC Private Functions
  * @{
  */

/**
  ==============================================================================
                       ##### FMAC Private Functions #####
  ==============================================================================
  */
/**
  * @brief  Perform a reset of the FMAC unit.
  * @param  hfmac FMAC handle.
  * @retval FMAC status
  */
static HAL_StatusTypeDef FMAC_Reset(FMAC_HandleTypeDef *hfmac)
{
  uint32_t tickstart;

  /* Init tickstart for timeout management*/
  tickstart = HAL_GetTick();

  /* Perform the reset */
  SET_BIT(hfmac->Instance->CR, FMAC_CR_RESET);

  /* Wait until flag is reset */
  while (READ_BIT(hfmac->Instance->CR, FMAC_CR_RESET) != 0UL)
  {
    if ((HAL_GetTick() - tickstart) > HAL_FMAC_RESET_TIMEOUT_VALUE)
    {
      return HAL_TIMEOUT;
    }
  }

  hfmac->ErrorCode = HAL_FMAC_ERROR_NONE;
  return HAL_OK;
}

/**
  * @brief  Reset the data pointers of the FMAC unit.
  * @param  hfmac FMAC handle.
  * @retval FMAC status
  */
static void FMAC_ResetDataPointers(FMAC_HandleTypeDef *hfmac)
{
  FMAC_ResetInputStateAndDataPointers(hfmac);
  FMAC_ResetOutputStateAndDataPointers(hfmac);
}

/**
  * @brief  Reset the input data pointers of the FMAC unit.
  * @param  hfmac FMAC handle.
  * @retval FMAC status
  */
static void FMAC_ResetInputStateAndDataPointers(FMAC_HandleTypeDef *hfmac)
{
  hfmac->pInput = NULL;
  hfmac->pInputSize = NULL;
  hfmac->InputCurrentSize = 0U;
  hfmac->WrState = HAL_FMAC_STATE_READY;
}

/**
  * @brief  Reset the output data pointers of the FMAC unit.
  * @param  hfmac FMAC handle.
  * @retval FMAC status
  */
static void FMAC_ResetOutputStateAndDataPointers(FMAC_HandleTypeDef *hfmac)
{
  hfmac->pOutput = NULL;
  hfmac->pOutputSize = NULL;
  hfmac->OutputCurrentSize = 0U;
  hfmac->RdState = HAL_FMAC_STATE_READY;
}

/**
  * @brief  Configure the FMAC filter according to the parameters
            specified in the FMAC_FilterConfigTypeDef structure.
  * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
  *         the configuration information for FMAC module.
  * @param  sConfig pointer to a FMAC_FilterConfigTypeDef structure that
  *         contains the FMAC configuration information.
  * @retval HAL status
  */
static HAL_StatusTypeDef FMAC_FilterConfig(FMAC_HandleTypeDef *hfmac, FMAC_FilterConfigTypeDef *sConfig,
                                           uint8_t PreloadAccess)
{
  uint32_t tickstart;
  uint32_t tmpcr;
#if defined(USE_FULL_ASSERT)
  uint32_t x2size;
#endif /* USE_FULL_ASSERT */

  /* Check the parameters */
  assert_param(IS_FMAC_THRESHOLD(sConfig->InputThreshold));
  assert_param(IS_FMAC_THRESHOLD(sConfig->OutputThreshold));
  assert_param(IS_FMAC_BUFFER_ACCESS(sConfig->InputAccess));
  assert_param(IS_FMAC_BUFFER_ACCESS(sConfig->OutputAccess));
  assert_param(IS_FMAC_CLIP_STATE(sConfig->Clip));
  assert_param(IS_FMAC_FILTER_FUNCTION(sConfig->Filter));
  assert_param(IS_FMAC_PARAM_P(sConfig->Filter, sConfig->P));
  assert_param(IS_FMAC_PARAM_Q(sConfig->Filter, sConfig->Q));
  assert_param(IS_FMAC_PARAM_R(sConfig->Filter, sConfig->R));

  /* Check the START bit state */
  if (FMAC_GET_START_BIT(hfmac) != 0UL)
  {
    return HAL_ERROR;
  }

  /* Check handle state is ready */
  if (hfmac->State == HAL_FMAC_STATE_READY)
  {
    /* Change the FMAC state */
    hfmac->State = HAL_FMAC_STATE_BUSY;

    /* Get tick */
    tickstart = HAL_GetTick();

    /* Indicate that there is no valid configuration done */
    hfmac->FilterParam = 0UL;

    /* FMAC_X1BUFCFG: Configure the input buffer within the internal memory if required */
    if (sConfig->InputBufferSize != 0U)
    {
      MODIFY_REG(hfmac->Instance->X1BUFCFG,                                                                   \
                 (FMAC_X1BUFCFG_X1_BASE | FMAC_X1BUFCFG_X1_BUF_SIZE),                                         \
                 (((((uint32_t)(sConfig->InputBaseAddress)) << FMAC_X1BUFCFG_X1_BASE_Pos)     & FMAC_X1BUFCFG_X1_BASE) | \
                  ((((uint32_t)(sConfig->InputBufferSize))  << FMAC_X1BUFCFG_X1_BUF_SIZE_Pos) & FMAC_X1BUFCFG_X1_BUF_SIZE)));
    }

    /* FMAC_X1BUFCFG: Configure the input threshold if valid when compared to the configured X1 size */
    if (sConfig->InputThreshold != FMAC_THRESHOLD_NO_VALUE)
    {
      /* Check the parameter */
      assert_param(IS_FMAC_THRESHOLD_APPLICABLE(FMAC_GET_X1_SIZE(hfmac), sConfig->InputThreshold, sConfig->InputAccess));

      MODIFY_REG(hfmac->Instance->X1BUFCFG, \
                 FMAC_X1BUFCFG_FULL_WM,     \
                 ((sConfig->InputThreshold) & FMAC_X1BUFCFG_FULL_WM));
    }

    /* FMAC_X2BUFCFG: Configure the coefficient buffer within the internal memory */
    if (sConfig->CoeffBufferSize != 0U)
    {
      MODIFY_REG(hfmac->Instance->X2BUFCFG,                                                                   \
                 (FMAC_X2BUFCFG_X2_BASE | FMAC_X2BUFCFG_X2_BUF_SIZE),                                         \
                 (((((uint32_t)(sConfig->CoeffBaseAddress)) << FMAC_X2BUFCFG_X2_BASE_Pos)     & FMAC_X2BUFCFG_X2_BASE) | \
                  ((((uint32_t)(sConfig->CoeffBufferSize))  << FMAC_X2BUFCFG_X2_BUF_SIZE_Pos) & FMAC_X2BUFCFG_X2_BUF_SIZE)));
    }

    /* FMAC_YBUFCFG: Configure the output buffer within the internal memory if required */
    if (sConfig->OutputBufferSize != 0U)
    {
      MODIFY_REG(hfmac->Instance->YBUFCFG,                                                                    \
                 (FMAC_YBUFCFG_Y_BASE | FMAC_YBUFCFG_Y_BUF_SIZE),                                             \
                 (((((uint32_t)(sConfig->OutputBaseAddress)) << FMAC_YBUFCFG_Y_BASE_Pos)     & FMAC_YBUFCFG_Y_BASE) |    \
                  ((((uint32_t)(sConfig->OutputBufferSize))  << FMAC_YBUFCFG_Y_BUF_SIZE_Pos) & FMAC_YBUFCFG_Y_BUF_SIZE)));
    }

    /* FMAC_YBUFCFG: Configure the output threshold if valid when compared to the configured Y size */
    if (sConfig->OutputThreshold != FMAC_THRESHOLD_NO_VALUE)
    {
      /* Check the parameter */
      assert_param(IS_FMAC_THRESHOLD_APPLICABLE(FMAC_GET_Y_SIZE(hfmac), sConfig->OutputThreshold, sConfig->OutputAccess));

      MODIFY_REG(hfmac->Instance->YBUFCFG, \
                 FMAC_YBUFCFG_EMPTY_WM,    \
                 ((sConfig->OutputThreshold) & FMAC_YBUFCFG_EMPTY_WM));
    }

    /* CR: Configure the clip feature */
    tmpcr = sConfig->Clip & FMAC_CR_CLIPEN;

    /* CR: If IT or DMA will be used, enable error interrupts.
      * Being more a debugging feature, FMAC_CR_SATIEN isn't enabled by default. */
    if ((sConfig->InputAccess  == FMAC_BUFFER_ACCESS_DMA) || (sConfig->InputAccess  == FMAC_BUFFER_ACCESS_IT) ||
        (sConfig->OutputAccess == FMAC_BUFFER_ACCESS_DMA) || (sConfig->OutputAccess == FMAC_BUFFER_ACCESS_IT))
    {
      tmpcr |= FMAC_IT_UNFLIEN | FMAC_IT_OVFLIEN;
    }

    /* CR: write the value */
    WRITE_REG(hfmac->Instance->CR, tmpcr);

    /* Save the input/output accesses in order to configure RIEN, WIEN, DMAREN and DMAWEN during filter start */
    hfmac->InputAccess = sConfig->InputAccess;
    hfmac->OutputAccess = sConfig->OutputAccess;

    /* Check whether the configured X2 is big enough for the filter */
#if defined(USE_FULL_ASSERT)
    x2size = FMAC_GET_X2_SIZE(hfmac);
#endif /* USE_FULL_ASSERT */
    assert_param(((sConfig->Filter == FMAC_FUNC_CONVO_FIR) && (x2size >= sConfig->P)) || \
                 ((sConfig->Filter == FMAC_FUNC_IIR_DIRECT_FORM_1) && (x2size >= ((uint32_t)sConfig->P + (uint32_t)sConfig->Q))));

    /* Build the PARAM value that will be used when starting the filter */
    hfmac->FilterParam = (FMAC_PARAM_START | sConfig->Filter |                   \
                          ((((uint32_t)(sConfig->P)) << FMAC_PARAM_P_Pos) & FMAC_PARAM_P) | \
                          ((((uint32_t)(sConfig->Q)) << FMAC_PARAM_Q_Pos) & FMAC_PARAM_Q) | \
                          ((((uint32_t)(sConfig->R)) << FMAC_PARAM_R_Pos) & FMAC_PARAM_R));

    /* Initialize the coefficient buffer if required (pCoeffA for FIR only) */
    if ((sConfig->pCoeffB != NULL) && (sConfig->CoeffBSize != 0U))
    {
      /* FIR/IIR: The provided coefficients should match X2 size */
      assert_param(((uint32_t)sConfig->CoeffASize + (uint32_t)sConfig->CoeffBSize) <= x2size);
      /* FIR/IIR: The size of pCoeffB should match the parameter P */
      assert_param(sConfig->CoeffBSize >= sConfig->P);
      /* pCoeffA should be provided for IIR but not for FIR */
      /* IIR : if pCoeffB is provided, pCoeffA should also be there */
      /* IIR: The size of pCoeffA should match the parameter Q */
      assert_param(((sConfig->Filter == FMAC_FUNC_CONVO_FIR) &&
                    (sConfig->pCoeffA == NULL) && (sConfig->CoeffASize == 0U)) ||
                   ((sConfig->Filter == FMAC_FUNC_IIR_DIRECT_FORM_1) &&
                    (sConfig->pCoeffA != NULL) && (sConfig->CoeffASize != 0U) &&
                    (sConfig->CoeffASize >= sConfig->Q)));

      /* Write number of values to be loaded, the data load function and start the operation */
      WRITE_REG(hfmac->Instance->PARAM,                      \
                (((uint32_t)(sConfig->CoeffBSize) << FMAC_PARAM_P_Pos) | \
                 ((uint32_t)(sConfig->CoeffASize) << FMAC_PARAM_Q_Pos) | \
                 FMAC_FUNC_LOAD_X2 | FMAC_PARAM_START));

      if (PreloadAccess == PRELOAD_ACCESS_POLLING)
      {
        /* Load the buffer into the internal memory */
        FMAC_WritePreloadDataIncrementPtr(hfmac, &(sConfig->pCoeffB), sConfig->CoeffBSize);

        /* Load pCoeffA if needed */
        if ((sConfig->pCoeffA != NULL) && (sConfig->CoeffASize != 0U))
        {
          /* Load the buffer into the internal memory */
          FMAC_WritePreloadDataIncrementPtr(hfmac, &(sConfig->pCoeffA), sConfig->CoeffASize);
        }

        /* Wait for the end of the writing */
        if (FMAC_WaitOnStartUntilTimeout(hfmac, tickstart, HAL_FMAC_TIMEOUT_VALUE) != HAL_OK)
        {
          hfmac->State = HAL_FMAC_STATE_TIMEOUT;
          return HAL_TIMEOUT;
        }

        /* Change the FMAC state */
        hfmac->State = HAL_FMAC_STATE_READY;
      }
      else
      {
        hfmac->pInput = sConfig->pCoeffA;
        hfmac->InputCurrentSize = sConfig->CoeffASize;

        /* Set the FMAC DMA transfer complete callback */
        hfmac->hdmaPreload->XferHalfCpltCallback = NULL;
        hfmac->hdmaPreload->XferCpltCallback = FMAC_DMAFilterConfig;
        /* Set the DMA error callback */
        hfmac->hdmaPreload->XferErrorCallback = FMAC_DMAError;

        /* Enable the DMA stream managing FMAC preload data write */
        return (HAL_DMA_Start_IT(hfmac->hdmaPreload, (uint32_t)sConfig->pCoeffB, (uint32_t)&hfmac->Instance->WDATA,
                                 sConfig->CoeffBSize));
      }
    }
    else
    {
      /* Change the FMAC state */
      hfmac->State = HAL_FMAC_STATE_READY;
    }
  }
  else
  {
    /* Return function status */
    return HAL_BUSY;
  }

  /* Return function status */
  return HAL_OK;
}

/**
  * @brief  Preload the input (FIR, IIR) and output data (IIR) of the FMAC filter.
  *         They will be used by FMAC as soon as HAL_FMAC_FilterStart is called.
  * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
  *         the configuration information for FMAC module.
  * @param  pInput Preloading of the first elements of the input buffer (X1).
  *         If not needed (no data available when starting), it should be set to NULL.
  * @param  InputSize Size of the input vector.
  *         As pInput is used for preloading data, it cannot be bigger than the input memory area.
  * @param  pOutput [IIR] Preloading of the first elements of the output vector (Y).
  *         If not needed, it should be set to NULL.
  * @param  OutputSize Size of the output vector.
  *         As pOutput is used for preloading data, it cannot be bigger than the output memory area.
  * @note   The input and the output buffers can be filled by calling several times HAL_FMAC_FilterPreload
  *         (each call filling partly the buffers). In case of overflow (too much data provided through
  *         all these calls), an error will be returned.
  * @retval HAL status
  */
static HAL_StatusTypeDef FMAC_FilterPreload(FMAC_HandleTypeDef *hfmac, int16_t *pInput, uint8_t InputSize,
                                            int16_t *pOutput, uint8_t OutputSize, uint8_t PreloadAccess)
{
  uint32_t tickstart;

  /* Check the START bit state */
  if (FMAC_GET_START_BIT(hfmac) != 0UL)
  {
    return HAL_ERROR;
  }

  /* Check that a valid configuration was done previously */
  if (hfmac->FilterParam == 0UL)
  {
    return HAL_ERROR;
  }

  /* Check the preload input buffers isn't too big */
  if ((InputSize > FMAC_GET_X1_SIZE(hfmac)) && (pInput != NULL))
  {
    return HAL_ERROR;
  }

  /* Check the preload output buffer isn't too big */
  if ((OutputSize > FMAC_GET_Y_SIZE(hfmac)) && (pOutput != NULL))
  {
    return HAL_ERROR;
  }

  /* Check handle state is ready */
  if (hfmac->State == HAL_FMAC_STATE_READY)
  {
    /* Change the FMAC state */
    hfmac->State = HAL_FMAC_STATE_BUSY;

    /* Get tick */
    tickstart = HAL_GetTick();

    /* Preload the input buffer if required */
    if ((pInput != NULL) && (InputSize != 0U))
    {
      /* Write number of values to be loaded, the data load function and start the operation */
      WRITE_REG(hfmac->Instance->PARAM, \
                (((uint32_t)InputSize << FMAC_PARAM_P_Pos) | FMAC_FUNC_LOAD_X1 | FMAC_PARAM_START));

      if (PreloadAccess == PRELOAD_ACCESS_POLLING)
      {
        /* Load the buffer into the internal memory */
        FMAC_WritePreloadDataIncrementPtr(hfmac, &pInput, InputSize);

        /* Wait for the end of the writing */
        if (FMAC_WaitOnStartUntilTimeout(hfmac, tickstart, HAL_FMAC_TIMEOUT_VALUE) != HAL_OK)
        {
          hfmac->State = HAL_FMAC_STATE_TIMEOUT;
          return HAL_TIMEOUT;
        }
      }
      else
      {
        hfmac->pInput = pOutput;
        hfmac->InputCurrentSize = OutputSize;

        /* Set the FMAC DMA transfer complete callback */
        hfmac->hdmaPreload->XferHalfCpltCallback = NULL;
        hfmac->hdmaPreload->XferCpltCallback = FMAC_DMAFilterPreload;
        /* Set the DMA error callback */
        hfmac->hdmaPreload->XferErrorCallback = FMAC_DMAError;

        /* Enable the DMA stream managing FMAC preload data write */
        return (HAL_DMA_Start_IT(hfmac->hdmaPreload, (uint32_t)pInput, (uint32_t)&hfmac->Instance->WDATA, InputSize));
      }
    }

    /* Preload the output buffer if required */
    if ((pOutput != NULL) && (OutputSize != 0U))
    {
      /* Write number of values to be loaded, the data load function and start the operation */
      WRITE_REG(hfmac->Instance->PARAM, \
                (((uint32_t)OutputSize << FMAC_PARAM_P_Pos) | FMAC_FUNC_LOAD_Y | FMAC_PARAM_START));

      if (PreloadAccess == PRELOAD_ACCESS_POLLING)
      {
        /* Load the buffer into the internal memory */
        FMAC_WritePreloadDataIncrementPtr(hfmac, &pOutput, OutputSize);

        /* Wait for the end of the writing */
        if (FMAC_WaitOnStartUntilTimeout(hfmac, tickstart, HAL_FMAC_TIMEOUT_VALUE) != HAL_OK)
        {
          hfmac->State = HAL_FMAC_STATE_TIMEOUT;
          return HAL_TIMEOUT;
        }
      }
      else
      {
        hfmac->pInput = NULL;
        hfmac->InputCurrentSize = 0U;

        /* Set the FMAC DMA transfer complete callback */
        hfmac->hdmaPreload->XferHalfCpltCallback = NULL;
        hfmac->hdmaPreload->XferCpltCallback = FMAC_DMAFilterPreload;
        /* Set the DMA error callback */
        hfmac->hdmaPreload->XferErrorCallback = FMAC_DMAError;

        /* Enable the DMA stream managing FMAC preload data write */
        return (HAL_DMA_Start_IT(hfmac->hdmaPreload, (uint32_t)pOutput, (uint32_t)&hfmac->Instance->WDATA, OutputSize));
      }
    }

    /* Update the error codes */
    if (__HAL_FMAC_GET_FLAG(hfmac, FMAC_FLAG_OVFL))
    {
      hfmac->ErrorCode |= HAL_FMAC_ERROR_OVFL;
    }
    if (__HAL_FMAC_GET_FLAG(hfmac, FMAC_FLAG_UNFL))
    {
      hfmac->ErrorCode |= HAL_FMAC_ERROR_UNFL;
    }

    /* Change the FMAC state */
    hfmac->State = HAL_FMAC_STATE_READY;

    /* Return function status */
    if (hfmac->ErrorCode == HAL_FMAC_ERROR_NONE)
    {
      return HAL_OK;
    }
    else
    {
      return HAL_ERROR;
    }
  }
  else
  {
    /* Return function status */
    return HAL_BUSY;
  }
}

/**
  * @brief  Write data into FMAC internal memory through WDATA and increment input buffer pointer.
  *         This function is only used with preload functions.
  * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
  *         the configuration information for FMAC module.
  * @param  ppData pointer to pointer to the data buffer.
  * @param  Size size of the data buffer.
  * @retval none
  */
static void FMAC_WritePreloadDataIncrementPtr(FMAC_HandleTypeDef *hfmac, int16_t **ppData, uint8_t Size)
{
  uint8_t index;

  /* Load the buffer into the internal memory */
  for (index = Size; index > 0U; index--)
  {
    WRITE_REG(hfmac->Instance->WDATA, (((uint32_t)(*(*ppData))) & FMAC_WDATA_WDATA));
    (*ppData)++;
  }
}

/**
  * @brief  Handle FMAC Function Timeout.
  * @param  hfmac FMAC handle.
  * @param  Tickstart Tick start value.
  * @param  Timeout Timeout duration.
  * @retval HAL status
  */
static HAL_StatusTypeDef FMAC_WaitOnStartUntilTimeout(FMAC_HandleTypeDef *hfmac, uint32_t Tickstart, uint32_t Timeout)
{
  /* Wait until flag changes */
  while (READ_BIT(hfmac->Instance->PARAM, FMAC_PARAM_START) != 0UL)
  {
    if ((HAL_GetTick() - Tickstart) > Timeout)
    {
      /* Process Unlocked */
      __HAL_UNLOCK(hfmac);

      return HAL_TIMEOUT;
    }
  }
  return HAL_OK;
}

/**
  * @brief  Register the new input buffer, update DMA configuration
  *         if needed and change the FMAC state.
  * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
  *         the configuration information for FMAC module.
  * @param  pInput New input vector (additional input data).
  * @param  pInputSize Size of the input vector (if all the data can't be
  *         written, it will be updated with the number of data read from FMAC).
  * @retval HAL status
  */
static HAL_StatusTypeDef FMAC_AppendFilterDataUpdateState(FMAC_HandleTypeDef *hfmac, int16_t *pInput,
                                                          uint16_t *pInputSize)
{
  /* Change the FMAC state */
  hfmac->WrState = HAL_FMAC_STATE_BUSY_WR;

  /* Reset the current size */
  hfmac->InputCurrentSize = 0U;

  /* Handle the pointer depending on the input access */
  if (hfmac->InputAccess == FMAC_BUFFER_ACCESS_DMA)
  {
    hfmac->pInput = NULL;
    hfmac->pInputSize = NULL;

    /* Set the FMAC DMA transfer complete callback */
    hfmac->hdmaIn->XferHalfCpltCallback = FMAC_DMAHalfGetData;
    hfmac->hdmaIn->XferCpltCallback = FMAC_DMAGetData;
    /* Set the DMA error callback */
    hfmac->hdmaIn->XferErrorCallback = FMAC_DMAError;

    /* Enable the DMA stream managing FMAC input data write */
    return (HAL_DMA_Start_IT(hfmac->hdmaIn, (uint32_t)pInput, (uint32_t)&hfmac->Instance->WDATA, *pInputSize));
  }
  else
  {
    /* Update the input data information (polling, IT) */
    hfmac->pInput = pInput;
    hfmac->pInputSize = pInputSize;
  }

  /* Return function status */
  return HAL_OK;
}

/**
  * @brief  Register the new output buffer, update DMA configuration
  *         if needed and change the FMAC state.
  * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
  *         the configuration information for FMAC module.
  * @param  pOutput New output vector.
  * @param  pOutputSize Size of the output vector (if the vector can't
  *         be entirely filled, pOutputSize will be updated with the number
  *         of data read from FMAC).
  * @retval HAL status
  */
static HAL_StatusTypeDef FMAC_ConfigFilterOutputBufferUpdateState(FMAC_HandleTypeDef *hfmac, int16_t *pOutput,
                                                                  uint16_t *pOutputSize)
{
  /* Reset the current size */
  hfmac->OutputCurrentSize = 0U;

  /* Check whether a valid pointer was provided */
  if ((pOutput == NULL) || (pOutputSize == NULL) || (*pOutputSize == 0UL))
  {
    /* The user will have to provide a valid configuration later */
    hfmac->pOutput = NULL;
    hfmac->pOutputSize = NULL;
    hfmac->RdState = HAL_FMAC_STATE_READY;
  }
  /* Handle the pointer depending on the input access */
  else if (hfmac->OutputAccess == FMAC_BUFFER_ACCESS_DMA)
  {
    hfmac->pOutput = NULL;
    hfmac->pOutputSize = NULL;
    hfmac->RdState = HAL_FMAC_STATE_BUSY_RD;

    /* Set the FMAC DMA transfer complete callback */
    hfmac->hdmaOut->XferHalfCpltCallback = FMAC_DMAHalfOutputDataReady;
    hfmac->hdmaOut->XferCpltCallback = FMAC_DMAOutputDataReady;
    /* Set the DMA error callback */
    hfmac->hdmaOut->XferErrorCallback = FMAC_DMAError;

    /* Enable the DMA stream managing FMAC output data read */
    return (HAL_DMA_Start_IT(hfmac->hdmaOut, (uint32_t)&hfmac->Instance->RDATA, (uint32_t)pOutput, *pOutputSize));
  }
  else if (hfmac->OutputAccess == FMAC_BUFFER_ACCESS_NONE)
  {
    hfmac->pOutput = NULL;
    hfmac->pOutputSize = NULL;
    hfmac->RdState = HAL_FMAC_STATE_READY;
  }
  else
  {
    /* Update the output data information (polling, IT) */
    hfmac->pOutput = pOutput;
    hfmac->pOutputSize = pOutputSize;
    hfmac->RdState = HAL_FMAC_STATE_BUSY_RD;
  }

  /* Return function status */
  return HAL_OK;
}

/**
  * @brief  Read available output data until Y EMPTY is set.
  * @param  hfmac FMAC handle.
  * @param  MaxSizeToRead Maximum number of data to read (this serves as a timeout
  *         if FMAC continuously writes into the output buffer).
  * @retval HAL status
  */
static void FMAC_ReadDataIncrementPtr(FMAC_HandleTypeDef *hfmac, uint16_t MaxSizeToRead)
{
  uint16_t maxsize;
  uint16_t threshold;
  uint32_t tmpvalue;

  /* Check if there is data to read */
  if (READ_BIT(hfmac->Instance->SR, FMAC_SR_YEMPTY) != 0UL)
  {
    return;
  }

  /* Get the maximum index (no wait allowed, no overstepping of the output buffer) */
  if ((hfmac->OutputCurrentSize + MaxSizeToRead) > *(hfmac->pOutputSize))
  {
    maxsize = *(hfmac->pOutputSize);
  }
  else
  {
    maxsize = hfmac->OutputCurrentSize + MaxSizeToRead;
  }

  /* Read until there is no more room or no more data */
  do
  {
    /* If there is no more room, return */
    if (!(hfmac->OutputCurrentSize < maxsize))
    {
      return;
    }

    /* Read the available data */
    tmpvalue = ((READ_REG(hfmac->Instance->RDATA))& FMAC_RDATA_RDATA);
    *(hfmac->pOutput) = (int16_t)tmpvalue;
    hfmac->pOutput++;
    hfmac->OutputCurrentSize++;
  } while (READ_BIT(hfmac->Instance->SR, FMAC_SR_YEMPTY) == 0UL);

  /* Y buffer empty flag has just be raised, read the threshold */
  threshold = (uint16_t)FMAC_GET_THRESHOLD_FROM_WM(FMAC_GET_Y_EMPTY_WM(hfmac)) - 1U;

  /* Update the maximum size if needed (limited data available) */
  if ((hfmac->OutputCurrentSize + threshold) < maxsize)
  {
    maxsize = hfmac->OutputCurrentSize + threshold;
  }

  /* Read the available data */
  while (hfmac->OutputCurrentSize < maxsize)
  {
    tmpvalue = ((READ_REG(hfmac->Instance->RDATA))& FMAC_RDATA_RDATA);
    *(hfmac->pOutput) = (int16_t)tmpvalue;
    hfmac->pOutput++;
    hfmac->OutputCurrentSize++;
  }
}

/**
  * @brief  Write available input data until X1 FULL is set.
  * @param  hfmac FMAC handle.
  * @param  MaxSizeToWrite Maximum number of data to write (this serves as a timeout
  *         if FMAC continuously empties the input buffer).
  * @retval HAL status
  */
static void FMAC_WriteDataIncrementPtr(FMAC_HandleTypeDef *hfmac, uint16_t MaxSizeToWrite)
{
  uint16_t maxsize;
  uint16_t threshold;

  /* Check if there is room in FMAC */
  if (READ_BIT(hfmac->Instance->SR, FMAC_SR_X1FULL) != 0UL)
  {
    return;
  }

  /* Get the maximum index (no wait allowed, no overstepping of the output buffer) */
  if ((hfmac->InputCurrentSize + MaxSizeToWrite) > *(hfmac->pInputSize))
  {
    maxsize = *(hfmac->pInputSize);
  }
  else
  {
    maxsize = hfmac->InputCurrentSize + MaxSizeToWrite;
  }

  /* Write until there is no more room or no more data */
  do
  {
    /* If there is no more room, return */
    if (!(hfmac->InputCurrentSize < maxsize))
    {
      return;
    }

    /* Write the available data */
    WRITE_REG(hfmac->Instance->WDATA, (((uint32_t)(*(hfmac->pInput))) & FMAC_WDATA_WDATA));
    hfmac->pInput++;
    hfmac->InputCurrentSize++;
  } while (READ_BIT(hfmac->Instance->SR, FMAC_SR_X1FULL) == 0UL);

  /* X1 buffer full flag has just be raised, read the threshold */
  threshold = (uint16_t)FMAC_GET_THRESHOLD_FROM_WM(FMAC_GET_X1_FULL_WM(hfmac)) - 1U;

  /* Update the maximum size if needed (limited data available) */
  if ((hfmac->InputCurrentSize + threshold) < maxsize)
  {
    maxsize = hfmac->InputCurrentSize + threshold;
  }

  /* Write the available data */
  while (hfmac->InputCurrentSize < maxsize)
  {
    WRITE_REG(hfmac->Instance->WDATA, (((uint32_t)(*(hfmac->pInput))) & FMAC_WDATA_WDATA));
    hfmac->pInput++;
    hfmac->InputCurrentSize++;
  }
}

/**
  * @brief  DMA FMAC Input Data process half complete callback.
  * @param  hdma DMA handle.
  * @retval None
  */
static void FMAC_DMAHalfGetData(DMA_HandleTypeDef *hdma)
{
  FMAC_HandleTypeDef *hfmac = (FMAC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;

  /* Call half get data callback */
#if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1)
  hfmac->HalfGetDataCallback(hfmac);
#else
  HAL_FMAC_HalfGetDataCallback(hfmac);
#endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */
}

/**
  * @brief  DMA FMAC Input Data process complete callback.
  * @param  hdma DMA handle.
  * @retval None
  */
static void FMAC_DMAGetData(DMA_HandleTypeDef *hdma)
{
  FMAC_HandleTypeDef *hfmac = (FMAC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;

  /* Reset the pointers to indicate new data will be needed */
  FMAC_ResetInputStateAndDataPointers(hfmac);

  /* Call get data callback */
#if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1)
  hfmac->GetDataCallback(hfmac);
#else
  HAL_FMAC_GetDataCallback(hfmac);
#endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */
}

/**
  * @brief  DMA FMAC Output Data process half complete callback.
  * @param  hdma DMA handle.
  * @retval None
  */
static void FMAC_DMAHalfOutputDataReady(DMA_HandleTypeDef *hdma)
{
  FMAC_HandleTypeDef *hfmac = (FMAC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;

  /* Call half output data ready callback */
#if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1)
  hfmac->HalfOutputDataReadyCallback(hfmac);
#else
  HAL_FMAC_HalfOutputDataReadyCallback(hfmac);
#endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */
}

/**
  * @brief  DMA FMAC Output Data process complete callback.
  * @param  hdma DMA handle.
  * @retval None
  */
static void FMAC_DMAOutputDataReady(DMA_HandleTypeDef *hdma)
{
  FMAC_HandleTypeDef *hfmac = (FMAC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;

  /* Reset the pointers to indicate new data will be needed */
  FMAC_ResetOutputStateAndDataPointers(hfmac);

  /* Call output data ready callback */
#if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1)
  hfmac->OutputDataReadyCallback(hfmac);
#else
  HAL_FMAC_OutputDataReadyCallback(hfmac);
#endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */
}

/**
  * @brief  DMA FMAC Filter Configuration process complete callback.
  * @param  hdma DMA handle.
  * @retval None
  */
static void FMAC_DMAFilterConfig(DMA_HandleTypeDef *hdma)
{
  uint8_t index;

  FMAC_HandleTypeDef *hfmac = (FMAC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;

  /* If needed, write CoeffA and exit */
  if (hfmac->pInput != NULL)
  {
    /* Set the FMAC DMA transfer complete callback */
    hfmac->hdmaPreload->XferHalfCpltCallback = NULL;
    hfmac->hdmaPreload->XferCpltCallback = FMAC_DMAFilterConfig;
    /* Set the DMA error callback */
    hfmac->hdmaPreload->XferErrorCallback = FMAC_DMAError;

    /* Enable the DMA stream managing FMAC preload data write */
    if (HAL_DMA_Start_IT(hfmac->hdmaPreload, (uint32_t)hfmac->pInput, (uint32_t)&hfmac->Instance->WDATA,
                         hfmac->InputCurrentSize) == HAL_OK)
    {
      hfmac->pInput = NULL;
      hfmac->InputCurrentSize = 0U;
      return;
    }

    /* If not exited, there was an error: set FMAC handle state to error */
    hfmac->State = HAL_FMAC_STATE_ERROR;
  }
  else
  {
    /* Wait for the end of the writing */
    for (index = 0U; index < 0xFFU; index++)
    {
      if (READ_BIT(hfmac->Instance->PARAM, FMAC_PARAM_START) == 0U)
      {
        break;
      }
    }

    /* If 'START' is still set, there was an error: set FMAC handle state to error */
    if (READ_BIT(hfmac->Instance->PARAM, FMAC_PARAM_START) != 0UL)
    {
      hfmac->State = HAL_FMAC_STATE_TIMEOUT;
    }
    else
    {
      /* Change the FMAC state */
      hfmac->State = HAL_FMAC_STATE_READY;

      /* Call output data ready callback */
#if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1)
      hfmac->FilterConfigCallback(hfmac);
#else
      HAL_FMAC_FilterConfigCallback(hfmac);
#endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */
      return;
    }
  }

  /* If not exited, there was an error: set FMAC handle error code to DMA error */
  hfmac->ErrorCode |= HAL_FMAC_ERROR_DMA;

  /* Call user callback */
#if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1)
  hfmac->ErrorCallback(hfmac);
#else
  HAL_FMAC_ErrorCallback(hfmac);
#endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */

}

/**
  * @brief  DMA FMAC Filter Configuration process complete callback.
  * @param  hdma DMA handle.
  * @retval None
  */
static void FMAC_DMAFilterPreload(DMA_HandleTypeDef *hdma)
{
  uint8_t index;

  FMAC_HandleTypeDef *hfmac = (FMAC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;

  /* Wait for the end of the X1 writing */
  for (index = 0U; index < 0xFFU; index++)
  {
    if (READ_BIT(hfmac->Instance->PARAM, FMAC_PARAM_START) == 0UL)
    {
      break;
    }
  }

  /* If 'START' is still set, there was an error: set FMAC handle state to error */
  if (READ_BIT(hfmac->Instance->PARAM, FMAC_PARAM_START) != 0UL)
  {
    hfmac->State = HAL_FMAC_STATE_TIMEOUT;
    hfmac->ErrorCode |= HAL_FMAC_ERROR_TIMEOUT;
  }
  /* If needed, preload Y buffer */
  else if ((hfmac->pInput != NULL) && (hfmac->InputCurrentSize != 0U))
  {
    /* Write number of values to be loaded, the data load function and start the operation */
    WRITE_REG(hfmac->Instance->PARAM, \
              (((uint32_t)(hfmac->InputCurrentSize) << FMAC_PARAM_P_Pos) | FMAC_FUNC_LOAD_Y | FMAC_PARAM_START));

    /* Set the FMAC DMA transfer complete callback */
    hfmac->hdmaPreload->XferHalfCpltCallback = NULL;
    hfmac->hdmaPreload->XferCpltCallback = FMAC_DMAFilterPreload;
    /* Set the DMA error callback */
    hfmac->hdmaPreload->XferErrorCallback = FMAC_DMAError;

    /* Enable the DMA stream managing FMAC preload data write */
    if (HAL_DMA_Start_IT(hfmac->hdmaPreload, (uint32_t)hfmac->pInput, (uint32_t)&hfmac->Instance->WDATA,
                         hfmac->InputCurrentSize) == HAL_OK)
    {
      hfmac->pInput = NULL;
      hfmac->InputCurrentSize = 0U;
      return;
    }

    /* If not exited, there was an error */
    hfmac->ErrorCode = HAL_FMAC_ERROR_DMA;
    hfmac->State = HAL_FMAC_STATE_ERROR;
  }
  else
  {
    /* nothing to do */
  }

  /* Return function status */
  if (hfmac->ErrorCode == HAL_FMAC_ERROR_NONE)
  {
    /* Change the FMAC state */
    hfmac->State = HAL_FMAC_STATE_READY;

    /* Call output data ready callback */
#if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1)
    hfmac->FilterPreloadCallback(hfmac);
#else
    HAL_FMAC_FilterPreloadCallback(hfmac);
#endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */
  }
  else
  {
    /* Call user callback */
#if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1)
    hfmac->ErrorCallback(hfmac);
#else
    HAL_FMAC_ErrorCallback(hfmac);
#endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */
  }
}


/**
  * @brief  DMA FMAC communication error callback.
  * @param  hdma DMA handle.
  * @retval None
  */
static void FMAC_DMAError(DMA_HandleTypeDef *hdma)
{
  FMAC_HandleTypeDef *hfmac = (FMAC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;

  /* Set FMAC handle state to error */
  hfmac->State = HAL_FMAC_STATE_ERROR;

  /* Set FMAC handle error code to DMA error */
  hfmac->ErrorCode |= HAL_FMAC_ERROR_DMA;

  /* Call user callback */
#if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1)
  hfmac->ErrorCallback(hfmac);
#else
  HAL_FMAC_ErrorCallback(hfmac);
#endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */
}
/**
  * @}
  */


/**
  * @}
  */

/**
  * @}
  */

#endif /* HAL_FMAC_MODULE_ENABLED */

/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
