Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:07

0001 /**
0002   ******************************************************************************
0003   * @file    stm32h7xx_hal_fmac.c
0004   * @author  MCD Application Team
0005   * @brief   FMAC HAL module driver.
0006   *          This file provides firmware functions to manage the following
0007   *          functionalities of the FMAC peripheral:
0008   *           + Initialization and de-initialization functions
0009   *           + Peripheral Control functions
0010   *           + Callback functions
0011   *           + IRQ handler management
0012   *           + Peripheral State and Error functions
0013   *
0014   ******************************************************************************
0015   * @attention
0016   *
0017   * Copyright (c) 2017 STMicroelectronics.
0018   * All rights reserved.
0019   *
0020   * This software is licensed under terms that can be found in the LICENSE file
0021   * in the root directory of this software component.
0022   * If no LICENSE file comes with this software, it is provided AS-IS.
0023   *
0024   ******************************************************************************
0025   *
0026   *  @verbatim
0027 ================================================================================
0028             ##### How to use this driver #####
0029 ================================================================================
0030     [..]
0031       The FMAC HAL driver can be used as follows:
0032 
0033       (#) Initialize the FMAC low level resources by implementing the HAL_FMAC_MspInit():
0034           (++) Enable the FMAC interface clock using __HAL_RCC_FMAC_CLK_ENABLE().
0035           (++) In case of using interrupts (e.g. access configured as FMAC_BUFFER_ACCESS_IT):
0036                (+++) Configure the FMAC interrupt priority using HAL_NVIC_SetPriority().
0037                (+++) Enable the FMAC IRQ handler using HAL_NVIC_EnableIRQ().
0038                (+++) In FMAC IRQ handler, call HAL_FMAC_IRQHandler().
0039           (++) In case of using DMA to control data transfer (e.g. access configured
0040                as FMAC_BUFFER_ACCESS_DMA):
0041                (+++) Enable the DMA interface clock using __HAL_RCC_DMA1_CLK_ENABLE()
0042                      or __HAL_RCC_DMA2_CLK_ENABLE() depending on the used DMA instance.
0043                (+++) Enable the DMAMUX1 interface clock using __HAL_RCC_DMAMUX1_CLK_ENABLE().
0044                (+++) If the initialization of the internal buffers (coefficients, input,
0045                      output) is done via DMA, configure and enable one DMA channel for
0046                      managing data transfer from memory to memory (preload channel).
0047                (+++) If the input buffer is accessed via DMA, configure and enable one
0048                      DMA channel for managing data transfer from memory to peripheral
0049                      (input channel).
0050                (+++) If the output buffer is accessed via DMA, configure and enable
0051                      one DMA channel for managing data transfer from peripheral to
0052                      memory (output channel).
0053                (+++) Associate the initialized DMA handle(s) to the FMAC DMA handle(s)
0054                      using __HAL_LINKDMA().
0055                (+++) Configure the priority and enable the NVIC for the transfer complete
0056                      interrupt on the enabled DMA channel(s) using HAL_NVIC_SetPriority()
0057                      and HAL_NVIC_EnableIRQ().
0058 
0059       (#) Initialize the FMAC HAL using HAL_FMAC_Init(). This function
0060           resorts to HAL_FMAC_MspInit() for low-level initialization.
0061 
0062       (#) Configure the FMAC processing (filter) using HAL_FMAC_FilterConfig()
0063           or HAL_FMAC_FilterConfig_DMA().
0064           This function:
0065           (++) Defines the memory area within the FMAC internal memory
0066                (input, coefficients, output) and the associated threshold (input, output).
0067           (++) Configures the filter and its parameters:
0068                (+++) Finite Impulse Response (FIR) filter (also known as convolution).
0069                (+++) Infinite Impulse Response (IIR) filter (direct form 1).
0070           (++) Choose the way to access to the input and output buffers: none, polling,
0071                DMA, IT. "none" means the input and/or output data will be handled by
0072                another IP (ADC, DAC, etc.).
0073           (++) Enable the error interruptions in the input access and/or the output
0074                access is done through IT/DMA. If an error occurs, the interruption
0075                will be triggered in loop. In order to recover, the user will have
0076                to reset the IP with the sequence HAL_FMAC_DeInit / HAL_FMAC_Init.
0077                Optionally, he can also disable the interrupt using __HAL_FMAC_DISABLE_IT;
0078                the error status will be kept, but no more interrupt will be triggered.
0079           (++) Write the provided coefficients into the internal memory using polling
0080                mode ( HAL_FMAC_FilterConfig() ) or DMA ( HAL_FMAC_FilterConfig_DMA() ).
0081                In the DMA case, HAL_FMAC_FilterConfigCallback() is called when
0082                the handling is over.
0083 
0084        (#) Optionally, the user can enable the error interruption related to
0085            saturation by calling __HAL_FMAC_ENABLE_IT. This helps in debugging the
0086            filter. If a saturation occurs, the interruption will be triggered in loop.
0087            In order to recover, the user will have to:
0088            (++) Disable the interruption by calling __HAL_FMAC_DISABLE_IT if
0089                 the user wishes to continue all the same.
0090            (++) Reset the IP with the sequence HAL_FMAC_DeInit / HAL_FMAC_Init.
0091 
0092        (#) Optionally, preload input (FIR, IIR) and output (IIR) data using
0093            HAL_FMAC_FilterPreload() or HAL_FMAC_FilterPreload_DMA().
0094            In the DMA case, HAL_FMAC_FilterPreloadCallback() is called when
0095            the handling is over.
0096            This step is optional as the filter can be started without preloaded
0097            data.
0098 
0099        (#) Start the FMAC processing (filter) using HAL_FMAC_FilterStart().
0100            This function also configures the output buffer that will be filled from
0101            the circular internal output buffer. The function returns immediately
0102            without updating the provided buffer. The IP processing will be active until
0103            HAL_FMAC_FilterStop() is called.
0104 
0105        (#) If the input internal buffer is accessed via DMA, HAL_FMAC_HalfGetDataCallback()
0106            will be called to indicate that half of the input buffer has been handled.
0107 
0108        (#) If the input internal buffer is accessed via DMA or interrupt, HAL_FMAC_GetDataCallback()
0109            will be called to require new input data. It will be provided through
0110            HAL_FMAC_AppendFilterData() if the DMA isn't in circular mode.
0111 
0112        (#) If the output internal buffer is accessed via DMA, HAL_FMAC_HalfOutputDataReadyCallback()
0113            will be called to indicate that half of the output buffer has been handled.
0114 
0115        (#) If the output internal buffer is accessed via DMA or interrupt,
0116            HAL_FMAC_OutputDataReadyCallback() will be called to require a new output
0117            buffer. It will be provided through HAL_FMAC_ConfigFilterOutputBuffer()
0118            if the DMA isn't in circular mode.
0119 
0120        (#) In all modes except none, provide new input data to be processed via HAL_FMAC_AppendFilterData().
0121            This function should only be called once the previous input data has been handled
0122            (the preloaded input data isn't concerned).
0123 
0124        (#) In all modes except none, provide a new output buffer to be filled via
0125            HAL_FMAC_ConfigFilterOutputBuffer(). This function should only be called once the previous
0126            user's output buffer has been filled.
0127 
0128        (#) In polling mode, handle the input and output data using HAL_FMAC_PollFilterData().
0129            This function:
0130            (++) Write the user's input data (provided via HAL_FMAC_AppendFilterData())
0131                 into the FMAC input memory area.
0132            (++) Read the FMAC output memory area and write it into the user's output buffer.
0133            It will return either when:
0134            (++) the user's output buffer is filled.
0135            (++) the user's input buffer has been handled.
0136            The unused data (unread input data or free output data) will not be saved.
0137            The user will have to use the updated input and output sizes to keep track
0138            of them.
0139 
0140        (#) Stop the FMAC processing (filter) using HAL_FMAC_FilterStop().
0141 
0142        (#) Call HAL_FMAC_DeInit() to de-initialize the FMAC peripheral. This function
0143            resorts to HAL_FMAC_MspDeInit() for low-level de-initialization.
0144 
0145   ##### Callback registration #####
0146   ==================================
0147 
0148     [..]
0149       The compilation define USE_HAL_FMAC_REGISTER_CALLBACKS when set to 1
0150       allows the user to configure dynamically the driver callbacks.
0151 
0152     [..]
0153       Use Function HAL_FMAC_RegisterCallback() to register a user callback.
0154       Function HAL_FMAC_RegisterCallback() allows to register following callbacks:
0155       (+) ErrorCallback               : Error Callback.
0156       (+) HalfGetDataCallback         : Get Half Data Callback.
0157       (+) GetDataCallback             : Get Data Callback.
0158       (+) HalfOutputDataReadyCallback : Half Output Data Ready Callback.
0159       (+) OutputDataReadyCallback     : Output Data Ready Callback.
0160       (+) FilterConfigCallback        : Filter Configuration Callback.
0161       (+) FilterPreloadCallback       : Filter Preload Callback.
0162       (+) MspInitCallback             : FMAC MspInit.
0163       (+) MspDeInitCallback           : FMAC MspDeInit.
0164       This function takes as parameters the HAL peripheral handle, the Callback ID
0165       and a pointer to the user callback function.
0166 
0167     [..]
0168       Use function HAL_FMAC_UnRegisterCallback() to reset a callback to the default
0169       weak function.
0170       HAL_FMAC_UnRegisterCallback() takes as parameters the HAL peripheral handle
0171       and the Callback ID.
0172       This function allows to reset following callbacks:
0173       (+) ErrorCallback               : Error Callback.
0174       (+) HalfGetDataCallback         : Get Half Data Callback.
0175       (+) GetDataCallback             : Get Data Callback.
0176       (+) HalfOutputDataReadyCallback : Half Output Data Ready Callback.
0177       (+) OutputDataReadyCallback     : Output Data Ready Callback.
0178       (+) FilterConfigCallback        : Filter Configuration Callback.
0179       (+) FilterPreloadCallback       : Filter Preload Callback.
0180       (+) MspInitCallback             : FMAC MspInit.
0181       (+) MspDeInitCallback           : FMAC MspDeInit.
0182 
0183     [..]
0184       By default, after the HAL_FMAC_Init() and when the state is HAL_FMAC_STATE_RESET
0185       all callbacks are set to the corresponding weak functions:
0186       examples GetDataCallback(), OutputDataReadyCallback().
0187       Exception done for MspInit and MspDeInit functions that are respectively
0188       reset to the legacy weak functions in the HAL_FMAC_Init()
0189       and HAL_FMAC_DeInit() only when these callbacks are null (not registered beforehand).
0190       If not, MspInit or MspDeInit are not null, the HAL_FMAC_Init() and HAL_FMAC_DeInit()
0191       keep and use the user MspInit/MspDeInit callbacks (registered beforehand).
0192 
0193     [..]
0194       Callbacks can be registered/unregistered in HAL_FMAC_STATE_READY state only.
0195       Exception done MspInit/MspDeInit that can be registered/unregistered
0196       in HAL_FMAC_STATE_READY or HAL_FMAC_STATE_RESET state, thus registered (user)
0197       MspInit/DeInit callbacks can be used during the Init/DeInit.
0198       In that case first register the MspInit/MspDeInit user callbacks
0199       using HAL_FMAC_RegisterCallback() before calling HAL_FMAC_DeInit()
0200       or HAL_FMAC_Init() function.
0201 
0202     [..]
0203       When the compilation define USE_HAL_FMAC_REGISTER_CALLBACKS is set to 0 or
0204       not defined, the callback registration feature is not available
0205       and weak callbacks are used.
0206 
0207 
0208   @endverbatim
0209   *
0210   */
0211 
0212 /* Includes ------------------------------------------------------------------*/
0213 #include "stm32h7xx_hal.h"
0214 
0215 #if defined(FMAC)
0216 #ifdef HAL_FMAC_MODULE_ENABLED
0217 
0218 /** @addtogroup STM32H7xx_HAL_Driver
0219   * @{
0220   */
0221 
0222 /** @defgroup FMAC FMAC
0223   * @ingroup RTEMSBSPsARMSTM32H7
0224   * @brief    FMAC HAL driver module
0225   * @{
0226   */
0227 
0228 /* Private typedef -----------------------------------------------------------*/
0229 /* Private defines -----------------------------------------------------------*/
0230 /** @defgroup  FMAC_Private_Constants   FMAC Private Constants
0231   * @ingroup RTEMSBSPsARMSTM32H7
0232   * @{
0233   */
0234 
0235 #define MAX_FILTER_DATA_SIZE_TO_HANDLE ((uint16_t) 0xFFU)
0236 #define MAX_PRELOAD_INDEX      0xFFU
0237 #define PRELOAD_ACCESS_DMA     0x00U
0238 #define PRELOAD_ACCESS_POLLING 0x01U
0239 #define POLLING_DISABLED       0U
0240 #define POLLING_ENABLED        1U
0241 #define POLLING_NOT_STOPPED    0U
0242 #define POLLING_STOPPED        1U
0243 /* FMAC polling-based communications time-out value */
0244 #define HAL_FMAC_TIMEOUT_VALUE         1000U
0245 /* FMAC reset time-out value */
0246 #define HAL_FMAC_RESET_TIMEOUT_VALUE   500U
0247 /* DMA Read Requests Enable */
0248 #define FMAC_DMA_REN                   FMAC_CR_DMAREN
0249 /* DMA Write Channel Enable */
0250 #define FMAC_DMA_WEN                   FMAC_CR_DMAWEN
0251 /* FMAC Execution Enable */
0252 #define FMAC_START                     FMAC_PARAM_START
0253 
0254 /**
0255   * @}
0256   */
0257 
0258 /* Private macros ------------------------------------------------------------*/
0259 /** @defgroup  FMAC_Private_Macros   FMAC Private Macros
0260   * @ingroup RTEMSBSPsARMSTM32H7
0261   * @{
0262   */
0263 
0264 /**
0265   * @brief  Get the X1 memory area size.
0266   * @param  __HANDLE__ FMAC handle.
0267   * @retval X1_BUF_SIZE
0268   */
0269 #define FMAC_GET_X1_SIZE(__HANDLE__) \
0270   ((((__HANDLE__)->Instance->X1BUFCFG) & (FMAC_X1BUFCFG_X1_BUF_SIZE)) >> (FMAC_X1BUFCFG_X1_BUF_SIZE_Pos))
0271 
0272 /**
0273   * @brief  Get the X1 watermark.
0274   * @param  __HANDLE__ FMAC handle.
0275   * @retval FULL_WM
0276   */
0277 #define FMAC_GET_X1_FULL_WM(__HANDLE__) \
0278   (((__HANDLE__)->Instance->X1BUFCFG) & (FMAC_X1BUFCFG_FULL_WM))
0279 
0280 /**
0281   * @brief  Get the X2 memory area size.
0282   * @param  __HANDLE__ FMAC handle.
0283   * @retval X2_BUF_SIZE
0284   */
0285 #define FMAC_GET_X2_SIZE(__HANDLE__) \
0286   ((((__HANDLE__)->Instance->X2BUFCFG) & (FMAC_X2BUFCFG_X2_BUF_SIZE)) >> (FMAC_X2BUFCFG_X2_BUF_SIZE_Pos))
0287 
0288 /**
0289   * @brief  Get the Y memory area size.
0290   * @param  __HANDLE__ FMAC handle.
0291   * @retval Y_BUF_SIZE
0292   */
0293 #define FMAC_GET_Y_SIZE(__HANDLE__) \
0294   ((((__HANDLE__)->Instance->YBUFCFG) & (FMAC_YBUFCFG_Y_BUF_SIZE)) >> (FMAC_YBUFCFG_Y_BUF_SIZE_Pos))
0295 
0296 /**
0297   * @brief  Get the Y watermark.
0298   * @param  __HANDLE__ FMAC handle.
0299   * @retval EMPTY_WM
0300   */
0301 #define FMAC_GET_Y_EMPTY_WM(__HANDLE__) \
0302   (((__HANDLE__)->Instance->YBUFCFG) & (FMAC_YBUFCFG_EMPTY_WM))
0303 
0304 /**
0305   * @brief  Get the start bit state.
0306   * @param  __HANDLE__ FMAC handle.
0307   * @retval START
0308   */
0309 #define FMAC_GET_START_BIT(__HANDLE__) \
0310   ((((__HANDLE__)->Instance->PARAM) & (FMAC_PARAM_START)) >> (FMAC_PARAM_START_Pos))
0311 
0312 /**
0313   * @brief  Get the threshold matching the watermark.
0314   * @param  __WM__ Watermark value.
0315   * @retval THRESHOLD
0316   */
0317 #define FMAC_GET_THRESHOLD_FROM_WM(__WM__) (((__WM__) == FMAC_THRESHOLD_1)? 1U: \
0318                                             ((__WM__) == FMAC_THRESHOLD_2)? 2U: \
0319                                             ((__WM__) == FMAC_THRESHOLD_4)? 4U:8U)
0320 
0321 /**
0322   * @}
0323   */
0324 
0325 /* Private variables ---------------------------------------------------------*/
0326 /* Global variables ----------------------------------------------------------*/
0327 /* Private function prototypes -----------------------------------------------*/
0328 
0329 static HAL_StatusTypeDef FMAC_Reset(FMAC_HandleTypeDef *hfmac);
0330 static void FMAC_ResetDataPointers(FMAC_HandleTypeDef *hfmac);
0331 static void FMAC_ResetOutputStateAndDataPointers(FMAC_HandleTypeDef *hfmac);
0332 static void FMAC_ResetInputStateAndDataPointers(FMAC_HandleTypeDef *hfmac);
0333 static HAL_StatusTypeDef FMAC_FilterConfig(FMAC_HandleTypeDef *hfmac, FMAC_FilterConfigTypeDef *pConfig,
0334                                            uint8_t PreloadAccess);
0335 static HAL_StatusTypeDef FMAC_FilterPreload(FMAC_HandleTypeDef *hfmac, int16_t *pInput, uint8_t InputSize,
0336                                             int16_t *pOutput, uint8_t OutputSize, uint8_t PreloadAccess);
0337 static void FMAC_WritePreloadDataIncrementPtr(FMAC_HandleTypeDef *hfmac, int16_t **ppData, uint8_t Size);
0338 static HAL_StatusTypeDef FMAC_WaitOnStartUntilTimeout(FMAC_HandleTypeDef *hfmac, uint32_t Tickstart, uint32_t Timeout);
0339 static HAL_StatusTypeDef FMAC_AppendFilterDataUpdateState(FMAC_HandleTypeDef *hfmac, int16_t *pInput,
0340                                                           uint16_t *pInputSize);
0341 static HAL_StatusTypeDef FMAC_ConfigFilterOutputBufferUpdateState(FMAC_HandleTypeDef *hfmac, int16_t *pOutput,
0342                                                                   uint16_t *pOutputSize);
0343 static void FMAC_WriteDataIncrementPtr(FMAC_HandleTypeDef *hfmac, uint16_t MaxSizeToWrite);
0344 static void FMAC_ReadDataIncrementPtr(FMAC_HandleTypeDef *hfmac, uint16_t MaxSizeToRead);
0345 static void FMAC_DMAHalfGetData(DMA_HandleTypeDef *hdma);
0346 static void FMAC_DMAGetData(DMA_HandleTypeDef *hdma);
0347 static void FMAC_DMAHalfOutputDataReady(DMA_HandleTypeDef *hdma);
0348 static void FMAC_DMAOutputDataReady(DMA_HandleTypeDef *hdma);
0349 static void FMAC_DMAFilterConfig(DMA_HandleTypeDef *hdma);
0350 static void FMAC_DMAFilterPreload(DMA_HandleTypeDef *hdma);
0351 static void FMAC_DMAError(DMA_HandleTypeDef *hdma);
0352 
0353 /* Functions Definition ------------------------------------------------------*/
0354 
0355 /** @defgroup FMAC_Exported_Functions FMAC Exported Functions
0356   * @ingroup RTEMSBSPsARMSTM32H7
0357   * @{
0358   */
0359 
0360 /** @defgroup FMAC_Exported_Functions_Group1 Initialization and de-initialization functions
0361   * @ingroup RTEMSBSPsARMSTM32H7
0362   * @brief    Initialization and Configuration functions
0363   *
0364 @verbatim
0365  ===============================================================================
0366      #####       Initialization and de-initialization functions       #####
0367  ===============================================================================
0368     [..] This section provides functions allowing to:
0369       (+) Initialize the FMAC peripheral and the associated handle
0370       (+) DeInitialize the FMAC peripheral
0371       (+) Initialize the FMAC MSP (MCU Specific Package)
0372       (+) De-Initialize the FMAC MSP
0373       (+) Register a User FMAC Callback
0374       (+) Unregister a FMAC CallBack
0375 
0376     [..]
0377 
0378 @endverbatim
0379   * @{
0380   */
0381 
0382 /**
0383   * @brief  Initialize the FMAC peripheral and the associated handle.
0384   * @param  hfmac pointer to a FMAC_HandleTypeDef structure.
0385   * @retval HAL_StatusTypeDef HAL status
0386   */
0387 HAL_StatusTypeDef HAL_FMAC_Init(FMAC_HandleTypeDef *hfmac)
0388 {
0389   HAL_StatusTypeDef status;
0390 
0391   /* Check the FMAC handle allocation */
0392   if (hfmac == NULL)
0393   {
0394     return HAL_ERROR;
0395   }
0396 
0397   /* Check the instance */
0398   assert_param(IS_FMAC_ALL_INSTANCE(hfmac->Instance));
0399 
0400   if (hfmac->State == HAL_FMAC_STATE_RESET)
0401   {
0402     /* Initialize lock resource */
0403     hfmac->Lock = HAL_UNLOCKED;
0404 
0405 #if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1)
0406     /* Register the default callback functions */
0407     hfmac->ErrorCallback = HAL_FMAC_ErrorCallback;
0408     hfmac->HalfGetDataCallback = HAL_FMAC_HalfGetDataCallback;
0409     hfmac->GetDataCallback = HAL_FMAC_GetDataCallback;
0410     hfmac->HalfOutputDataReadyCallback = HAL_FMAC_HalfOutputDataReadyCallback;
0411     hfmac->OutputDataReadyCallback = HAL_FMAC_OutputDataReadyCallback;
0412     hfmac->FilterConfigCallback = HAL_FMAC_FilterConfigCallback;
0413     hfmac->FilterPreloadCallback = HAL_FMAC_FilterPreloadCallback;
0414 
0415     if (hfmac->MspInitCallback == NULL)
0416     {
0417       hfmac->MspInitCallback = HAL_FMAC_MspInit;
0418     }
0419 
0420     /* Init the low level hardware */
0421     hfmac->MspInitCallback(hfmac);
0422 #else
0423     /* Init the low level hardware */
0424     HAL_FMAC_MspInit(hfmac);
0425 #endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */
0426   }
0427 
0428   /* Reset pInput and pOutput */
0429   hfmac->FilterParam = 0U;
0430   FMAC_ResetDataPointers(hfmac);
0431 
0432   /* Reset FMAC unit (internal pointers) */
0433   if (FMAC_Reset(hfmac) == HAL_ERROR)
0434   {
0435     /* Update FMAC error code and FMAC peripheral state */
0436     hfmac->ErrorCode |= HAL_FMAC_ERROR_RESET;
0437     hfmac->State = HAL_FMAC_STATE_TIMEOUT;
0438 
0439     status = HAL_ERROR;
0440   }
0441   else
0442   {
0443     /* Update FMAC error code and FMAC peripheral state */
0444     hfmac->ErrorCode = HAL_FMAC_ERROR_NONE;
0445     hfmac->State = HAL_FMAC_STATE_READY;
0446 
0447     status = HAL_OK;
0448   }
0449 
0450   __HAL_UNLOCK(hfmac);
0451 
0452   return status;
0453 }
0454 
0455 /**
0456   * @brief  De-initialize the FMAC peripheral.
0457   * @param  hfmac pointer to a FMAC structure.
0458   * @retval HAL_StatusTypeDef HAL status
0459   */
0460 HAL_StatusTypeDef HAL_FMAC_DeInit(FMAC_HandleTypeDef *hfmac)
0461 {
0462   /* Check the FMAC handle allocation */
0463   if (hfmac == NULL)
0464   {
0465     return HAL_ERROR;
0466   }
0467 
0468   /* Check the parameters */
0469   assert_param(IS_FMAC_ALL_INSTANCE(hfmac->Instance));
0470 
0471   /* Change FMAC peripheral state */
0472   hfmac->State = HAL_FMAC_STATE_BUSY;
0473 
0474   /* Set FMAC error code to none */
0475   hfmac->ErrorCode = HAL_FMAC_ERROR_NONE;
0476 
0477   /* Reset pInput and pOutput */
0478   hfmac->FilterParam = 0U;
0479   FMAC_ResetDataPointers(hfmac);
0480 
0481 #if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1)
0482   if (hfmac->MspDeInitCallback == NULL)
0483   {
0484     hfmac->MspDeInitCallback = HAL_FMAC_MspDeInit;
0485   }
0486   /* DeInit the low level hardware */
0487   hfmac->MspDeInitCallback(hfmac);
0488 #else
0489   /* DeInit the low level hardware: CLOCK, NVIC, DMA */
0490   HAL_FMAC_MspDeInit(hfmac);
0491 #endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */
0492 
0493   /* Change FMAC peripheral state */
0494   hfmac->State = HAL_FMAC_STATE_RESET;
0495 
0496   /* Always release Lock in case of de-initialization */
0497   __HAL_UNLOCK(hfmac);
0498 
0499   return HAL_OK;
0500 }
0501 
0502 /**
0503   * @brief  Initialize the FMAC MSP.
0504   * @param  hfmac FMAC handle.
0505   * @retval None
0506   */
0507 __weak void HAL_FMAC_MspInit(FMAC_HandleTypeDef *hfmac)
0508 {
0509   /* Prevent unused argument(s) compilation warning */
0510   UNUSED(hfmac);
0511 
0512   /* NOTE : This function should not be modified, when the callback is needed,
0513             the HAL_FMAC_MspInit can be implemented in the user file
0514    */
0515 }
0516 
0517 /**
0518   * @brief  De-initialize the FMAC MSP.
0519   * @param  hfmac FMAC handle.
0520   * @retval None
0521   */
0522 __weak void HAL_FMAC_MspDeInit(FMAC_HandleTypeDef *hfmac)
0523 {
0524   /* Prevent unused argument(s) compilation warning */
0525   UNUSED(hfmac);
0526 
0527   /* NOTE : This function should not be modified, when the callback is needed,
0528             the HAL_FMAC_MspDeInit can be implemented in the user file
0529    */
0530 }
0531 
0532 #if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1)
0533 /**
0534   * @brief  Register a User FMAC Callback.
0535   * @note   The User FMAC Callback is to be used instead of the weak predefined callback.
0536   * @note   The HAL_FMAC_RegisterCallback() may be called before HAL_FMAC_Init() in HAL_FMAC_STATE_RESET to register
0537   *         callbacks for HAL_FMAC_MSPINIT_CB_ID and HAL_FMAC_MSPDEINIT_CB_ID.
0538   * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
0539   *         the configuration information for FMAC module.
0540   * @param  CallbackID ID of the callback to be registered.
0541   *         This parameter can be one of the following values:
0542   *           @arg @ref HAL_FMAC_ERROR_CB_ID Error Callback ID
0543   *           @arg @ref HAL_FMAC_HALF_GET_DATA_CB_ID Get Half Data Callback ID
0544   *           @arg @ref HAL_FMAC_GET_DATA_CB_ID Get Data Callback ID
0545   *           @arg @ref HAL_FMAC_HALF_OUTPUT_DATA_READY_CB_ID Half Output Data Ready Callback ID
0546   *           @arg @ref HAL_FMAC_OUTPUT_DATA_READY_CB_ID Output Data Ready Callback ID
0547   *           @arg @ref HAL_FMAC_FILTER_CONFIG_CB_ID Filter Configuration Callback ID
0548   *           @arg @ref HAL_FMAC_FILTER_PRELOAD_CB_ID Filter Preload Callback ID
0549   *           @arg @ref HAL_FMAC_MSPINIT_CB_ID FMAC MspInit ID
0550   *           @arg @ref HAL_FMAC_MSPDEINIT_CB_ID FMAC MspDeInit ID
0551   * @param  pCallback pointer to the Callback function.
0552   * @retval HAL_StatusTypeDef HAL status
0553   */
0554 HAL_StatusTypeDef HAL_FMAC_RegisterCallback(FMAC_HandleTypeDef *hfmac, HAL_FMAC_CallbackIDTypeDef CallbackID,
0555                                             pFMAC_CallbackTypeDef pCallback)
0556 {
0557   HAL_StatusTypeDef status = HAL_OK;
0558 
0559   /* Check the FMAC handle allocation */
0560   if (hfmac == NULL)
0561   {
0562     return HAL_ERROR;
0563   }
0564 
0565   if (pCallback == NULL)
0566   {
0567     /* Update the error code */
0568     hfmac->ErrorCode |= HAL_FMAC_ERROR_INVALID_CALLBACK;
0569 
0570     return HAL_ERROR;
0571   }
0572 
0573   if (hfmac->State == HAL_FMAC_STATE_READY)
0574   {
0575     switch (CallbackID)
0576     {
0577       case HAL_FMAC_ERROR_CB_ID :
0578         hfmac->ErrorCallback = pCallback;
0579         break;
0580 
0581       case HAL_FMAC_HALF_GET_DATA_CB_ID :
0582         hfmac->HalfGetDataCallback = pCallback;
0583         break;
0584 
0585       case HAL_FMAC_GET_DATA_CB_ID :
0586         hfmac->GetDataCallback = pCallback;
0587         break;
0588 
0589       case HAL_FMAC_HALF_OUTPUT_DATA_READY_CB_ID :
0590         hfmac->HalfOutputDataReadyCallback = pCallback;
0591         break;
0592 
0593       case HAL_FMAC_OUTPUT_DATA_READY_CB_ID :
0594         hfmac->OutputDataReadyCallback = pCallback;
0595         break;
0596 
0597       case HAL_FMAC_FILTER_CONFIG_CB_ID :
0598         hfmac->FilterConfigCallback = pCallback;
0599         break;
0600 
0601       case HAL_FMAC_FILTER_PRELOAD_CB_ID :
0602         hfmac->FilterPreloadCallback = pCallback;
0603         break;
0604 
0605       case HAL_FMAC_MSPINIT_CB_ID :
0606         hfmac->MspInitCallback = pCallback;
0607         break;
0608 
0609       case HAL_FMAC_MSPDEINIT_CB_ID :
0610         hfmac->MspDeInitCallback = pCallback;
0611         break;
0612 
0613       default :
0614         /* Update the error code */
0615         hfmac->ErrorCode |= HAL_FMAC_ERROR_INVALID_CALLBACK;
0616 
0617         /* Return error status */
0618         status =  HAL_ERROR;
0619         break;
0620     }
0621   }
0622   else if (hfmac->State == HAL_FMAC_STATE_RESET)
0623   {
0624     switch (CallbackID)
0625     {
0626       case HAL_FMAC_MSPINIT_CB_ID :
0627         hfmac->MspInitCallback = pCallback;
0628         break;
0629 
0630       case HAL_FMAC_MSPDEINIT_CB_ID :
0631         hfmac->MspDeInitCallback = pCallback;
0632         break;
0633 
0634       default :
0635         /* Update the error code */
0636         hfmac->ErrorCode |= HAL_FMAC_ERROR_INVALID_CALLBACK;
0637 
0638         /* Return error status */
0639         status =  HAL_ERROR;
0640         break;
0641     }
0642   }
0643   else
0644   {
0645     /* Update the error code */
0646     hfmac->ErrorCode |= HAL_FMAC_ERROR_INVALID_CALLBACK;
0647 
0648     /* Return error status */
0649     status =  HAL_ERROR;
0650   }
0651 
0652   return status;
0653 }
0654 
0655 /**
0656   * @brief  Unregister a FMAC CallBack.
0657   * @note   The FMAC callback is redirected to the weak predefined callback.
0658   * @note   The HAL_FMAC_UnRegisterCallback() may be called before HAL_FMAC_Init() in HAL_FMAC_STATE_RESET to register
0659   *         callbacks for HAL_FMAC_MSPINIT_CB_ID and HAL_FMAC_MSPDEINIT_CB_ID.
0660   * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
0661   *         the configuration information for FMAC module
0662   * @param  CallbackID ID of the callback to be unregistered.
0663   *         This parameter can be one of the following values:
0664   *           @arg @ref HAL_FMAC_ERROR_CB_ID Error Callback ID
0665   *           @arg @ref HAL_FMAC_HALF_GET_DATA_CB_ID Get Half Data Callback ID
0666   *           @arg @ref HAL_FMAC_GET_DATA_CB_ID Get Data Callback ID
0667   *           @arg @ref HAL_FMAC_HALF_OUTPUT_DATA_READY_CB_ID Half Output Data Ready Callback ID
0668   *           @arg @ref HAL_FMAC_OUTPUT_DATA_READY_CB_ID Output Data Ready Callback ID
0669   *           @arg @ref HAL_FMAC_FILTER_CONFIG_CB_ID Filter Configuration Callback ID
0670   *           @arg @ref HAL_FMAC_FILTER_PRELOAD_CB_ID Filter Preload Callback ID
0671   *           @arg @ref HAL_FMAC_MSPINIT_CB_ID FMAC MspInit ID
0672   *           @arg @ref HAL_FMAC_MSPDEINIT_CB_ID FMAC MspDeInit ID
0673   * @retval HAL_StatusTypeDef HAL status
0674   */
0675 HAL_StatusTypeDef HAL_FMAC_UnRegisterCallback(FMAC_HandleTypeDef *hfmac, HAL_FMAC_CallbackIDTypeDef CallbackID)
0676 {
0677   HAL_StatusTypeDef status = HAL_OK;
0678 
0679   /* Check the FMAC handle allocation */
0680   if (hfmac == NULL)
0681   {
0682     return HAL_ERROR;
0683   }
0684 
0685   if (hfmac->State == HAL_FMAC_STATE_READY)
0686   {
0687     switch (CallbackID)
0688     {
0689       case HAL_FMAC_ERROR_CB_ID :
0690         hfmac->ErrorCallback = HAL_FMAC_ErrorCallback;                             /* Legacy weak ErrorCallback       */
0691         break;
0692 
0693       case HAL_FMAC_HALF_GET_DATA_CB_ID :
0694         hfmac->HalfGetDataCallback = HAL_FMAC_HalfGetDataCallback;                 /* Legacy weak HalfGetDataCallback */
0695         break;
0696 
0697       case HAL_FMAC_GET_DATA_CB_ID :
0698         hfmac->GetDataCallback = HAL_FMAC_GetDataCallback;                         /* Legacy weak GetDataCallback     */
0699         break;
0700 
0701       case HAL_FMAC_HALF_OUTPUT_DATA_READY_CB_ID :
0702         hfmac->HalfOutputDataReadyCallback = HAL_FMAC_HalfOutputDataReadyCallback; /* Legacy weak
0703                                                                                       HalfOutputDataReadyCallback     */
0704         break;
0705 
0706       case HAL_FMAC_OUTPUT_DATA_READY_CB_ID :
0707         hfmac->OutputDataReadyCallback = HAL_FMAC_OutputDataReadyCallback;         /* Legacy weak
0708                                                                                       OutputDataReadyCallback         */
0709         break;
0710 
0711       case HAL_FMAC_FILTER_CONFIG_CB_ID :
0712         hfmac->FilterConfigCallback = HAL_FMAC_FilterConfigCallback;               /* Legacy weak
0713                                                                                       FilterConfigCallback            */
0714         break;
0715 
0716       case HAL_FMAC_FILTER_PRELOAD_CB_ID :
0717         hfmac->FilterPreloadCallback = HAL_FMAC_FilterPreloadCallback;             /* Legacy weak FilterPreloadCallba */
0718         break;
0719 
0720       case HAL_FMAC_MSPINIT_CB_ID :
0721         hfmac->MspInitCallback = HAL_FMAC_MspInit;                                 /* Legacy weak MspInitCallback     */
0722         break;
0723 
0724       case HAL_FMAC_MSPDEINIT_CB_ID :
0725         hfmac->MspDeInitCallback = HAL_FMAC_MspDeInit;                             /* Legacy weak MspDeInitCallback   */
0726         break;
0727 
0728       default :
0729         /* Update the error code */
0730         hfmac->ErrorCode |= HAL_FMAC_ERROR_INVALID_CALLBACK;
0731 
0732         /* Return error status */
0733         status =  HAL_ERROR;
0734         break;
0735     }
0736   }
0737   else if (hfmac->State == HAL_FMAC_STATE_RESET)
0738   {
0739     switch (CallbackID)
0740     {
0741       case HAL_FMAC_MSPINIT_CB_ID :
0742         hfmac->MspInitCallback = HAL_FMAC_MspInit;
0743         break;
0744 
0745       case HAL_FMAC_MSPDEINIT_CB_ID :
0746         hfmac->MspDeInitCallback = HAL_FMAC_MspDeInit;
0747         break;
0748 
0749       default :
0750         /* Update the error code */
0751         hfmac->ErrorCode |= HAL_FMAC_ERROR_INVALID_CALLBACK;
0752 
0753         /* Return error status */
0754         status =  HAL_ERROR;
0755         break;
0756     }
0757   }
0758   else
0759   {
0760     /* Update the error code */
0761     hfmac->ErrorCode |= HAL_FMAC_ERROR_INVALID_CALLBACK;
0762 
0763     /* Return error status */
0764     status = HAL_ERROR;
0765   }
0766 
0767   return status;
0768 }
0769 #endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */
0770 
0771 /**
0772   * @}
0773   */
0774 
0775 /** @defgroup FMAC_Exported_Functions_Group2 Peripheral Control functions
0776   * @ingroup RTEMSBSPsARMSTM32H7
0777   * @brief    Control functions.
0778   *
0779 @verbatim
0780   ==============================================================================
0781                       ##### Peripheral Control functions #####
0782   ==============================================================================
0783     [..]  This section provides functions allowing to:
0784       (+) Configure the FMAC peripheral: memory area, filter type and parameters,
0785           way to access to the input and output memory area (none, polling, IT, DMA).
0786       (+) Start the FMAC processing (filter).
0787       (+) Handle the input data that will be provided into FMAC.
0788       (+) Handle the output data provided by FMAC.
0789       (+) Stop the FMAC processing (filter).
0790 
0791 @endverbatim
0792   * @{
0793   */
0794 
0795 /**
0796   * @brief  Configure the FMAC filter.
0797   * @note   The configuration is done according to the parameters
0798   *         specified in the FMAC_FilterConfigTypeDef structure.
0799   *         The provided data will be loaded using polling mode.
0800   * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
0801   *         the configuration information for FMAC module.
0802   * @param  pConfig pointer to a FMAC_FilterConfigTypeDef structure that
0803   *         contains the FMAC configuration information.
0804   * @retval HAL_StatusTypeDef HAL status
0805   */
0806 HAL_StatusTypeDef HAL_FMAC_FilterConfig(FMAC_HandleTypeDef *hfmac, FMAC_FilterConfigTypeDef *pConfig)
0807 {
0808   return (FMAC_FilterConfig(hfmac, pConfig, PRELOAD_ACCESS_POLLING));
0809 }
0810 
0811 /**
0812   * @brief  Configure the FMAC filter.
0813   * @note   The configuration is done according to the parameters
0814   *         specified in the FMAC_FilterConfigTypeDef structure.
0815   *         The provided data will be loaded using DMA.
0816   * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
0817   *         the configuration information for FMAC module.
0818   * @param  pConfig pointer to a FMAC_FilterConfigTypeDef structure that
0819   *         contains the FMAC configuration information.
0820   * @retval HAL_StatusTypeDef HAL status
0821   */
0822 HAL_StatusTypeDef HAL_FMAC_FilterConfig_DMA(FMAC_HandleTypeDef *hfmac, FMAC_FilterConfigTypeDef *pConfig)
0823 {
0824   return (FMAC_FilterConfig(hfmac, pConfig, PRELOAD_ACCESS_DMA));
0825 }
0826 
0827 /**
0828   * @brief  Preload the input (FIR, IIR) and output data (IIR) of the FMAC filter.
0829   * @note   The set(s) of data will be used by FMAC as soon as @ref HAL_FMAC_FilterStart is called.
0830   *         The provided data will be loaded using polling mode.
0831   * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
0832   *         the configuration information for FMAC module.
0833   * @param  pInput Preloading of the first elements of the input buffer (X1).
0834   *         If not needed (no data available when starting), it should be set to NULL.
0835   * @param  InputSize Size of the input vector.
0836   *         As pInput is used for preloading data, it cannot be bigger than the input memory area.
0837   * @param  pOutput [IIR] Preloading of the first elements of the output vector (Y).
0838   *         If not needed, it should be set to NULL.
0839   * @param  OutputSize Size of the output vector.
0840   *         As pOutput is used for preloading data, it cannot be bigger than the output memory area.
0841   * @note   The input and the output buffers can be filled by calling several times @ref HAL_FMAC_FilterPreload
0842   *         (each call filling partly the buffers). In case of overflow (too much data provided through
0843   *         all these calls), an error will be returned.
0844   * @retval HAL_StatusTypeDef HAL status
0845   */
0846 HAL_StatusTypeDef HAL_FMAC_FilterPreload(FMAC_HandleTypeDef *hfmac, int16_t *pInput, uint8_t InputSize,
0847                                          int16_t *pOutput, uint8_t OutputSize)
0848 {
0849   return (FMAC_FilterPreload(hfmac, pInput, InputSize, pOutput, OutputSize, PRELOAD_ACCESS_POLLING));
0850 }
0851 
0852 /**
0853   * @brief  Preload the input (FIR, IIR) and output data (IIR) of the FMAC filter.
0854   * @note   The set(s) of data will be used by FMAC as soon as @ref HAL_FMAC_FilterStart is called.
0855   *         The provided data will be loaded using DMA.
0856   * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
0857   *         the configuration information for FMAC module.
0858   * @param  pInput Preloading of the first elements of the input buffer (X1).
0859   *         If not needed (no data available when starting), it should be set to NULL.
0860   * @param  InputSize Size of the input vector.
0861   *         As pInput is used for preloading data, it cannot be bigger than the input memory area.
0862   * @param  pOutput [IIR] Preloading of the first elements of the output vector (Y).
0863   *         If not needed, it should be set to NULL.
0864   * @param  OutputSize Size of the output vector.
0865   *         As pOutput is used for preloading data, it cannot be bigger than the output memory area.
0866   * @note   The input and the output buffers can be filled by calling several times @ref HAL_FMAC_FilterPreload
0867   *         (each call filling partly the buffers). In case of overflow (too much data provided through
0868   *         all these calls), an error will be returned.
0869   * @retval HAL_StatusTypeDef HAL status
0870   */
0871 HAL_StatusTypeDef HAL_FMAC_FilterPreload_DMA(FMAC_HandleTypeDef *hfmac, int16_t *pInput, uint8_t InputSize,
0872                                              int16_t *pOutput, uint8_t OutputSize)
0873 {
0874   return (FMAC_FilterPreload(hfmac, pInput, InputSize, pOutput, OutputSize, PRELOAD_ACCESS_DMA));
0875 }
0876 
0877 
0878 /**
0879   * @brief  Start the FMAC processing according to the existing FMAC configuration.
0880   * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
0881   *         the configuration information for FMAC module.
0882   * @param  pOutput pointer to buffer where output data of FMAC processing will be stored
0883   *         in the next steps.
0884   *         If it is set to NULL, the output will not be read and it will be up to
0885   *         an external IP to empty the output buffer.
0886   * @param  pOutputSize pointer to the size of the output buffer. The number of read data will be written here.
0887   * @retval HAL_StatusTypeDef HAL status
0888   */
0889 HAL_StatusTypeDef HAL_FMAC_FilterStart(FMAC_HandleTypeDef *hfmac, int16_t *pOutput, uint16_t *pOutputSize)
0890 {
0891   uint32_t tmpcr = 0U;
0892   HAL_StatusTypeDef status;
0893 
0894   /* Check the START bit state */
0895   if (FMAC_GET_START_BIT(hfmac) != 0U)
0896   {
0897     return HAL_ERROR;
0898   }
0899 
0900   /* Check that a valid configuration was done previously */
0901   if (hfmac->FilterParam == 0U)
0902   {
0903     return HAL_ERROR;
0904   }
0905 
0906   /* Check handle state is ready */
0907   if (hfmac->State == HAL_FMAC_STATE_READY)
0908   {
0909     /* Change the FMAC state */
0910     hfmac->State = HAL_FMAC_STATE_BUSY;
0911 
0912     /* CR: Configure the input access (error interruptions enabled only for IT or DMA) */
0913     if (hfmac->InputAccess == FMAC_BUFFER_ACCESS_DMA)
0914     {
0915       tmpcr |= FMAC_DMA_WEN;
0916     }
0917     else if (hfmac->InputAccess == FMAC_BUFFER_ACCESS_IT)
0918     {
0919       tmpcr |= FMAC_IT_WIEN;
0920     }
0921     else
0922     {
0923       /* nothing to do */
0924     }
0925 
0926     /* CR: Configure the output access (error interruptions enabled only for IT or DMA) */
0927     if (hfmac->OutputAccess == FMAC_BUFFER_ACCESS_DMA)
0928     {
0929       tmpcr |= FMAC_DMA_REN;
0930     }
0931     else if (hfmac->OutputAccess == FMAC_BUFFER_ACCESS_IT)
0932     {
0933       tmpcr |= FMAC_IT_RIEN;
0934     }
0935     else
0936     {
0937       /* nothing to do */
0938     }
0939 
0940     /* CR: Write the configuration */
0941     MODIFY_REG(hfmac->Instance->CR, \
0942                FMAC_IT_RIEN | FMAC_IT_WIEN | FMAC_DMA_REN | FMAC_CR_DMAWEN, \
0943                tmpcr);
0944 
0945     /* Register the new output buffer */
0946     status = FMAC_ConfigFilterOutputBufferUpdateState(hfmac, pOutput, pOutputSize);
0947 
0948     if (status == HAL_OK)
0949     {
0950       /* PARAM: Start the filter ( this can generate interrupts before the end of the HAL_FMAC_FilterStart ) */
0951       WRITE_REG(hfmac->Instance->PARAM, (uint32_t)(hfmac->FilterParam));
0952     }
0953 
0954     /* Reset the busy flag (do not overwrite the possible write and read flag) */
0955     hfmac->State = HAL_FMAC_STATE_READY;
0956   }
0957   else
0958   {
0959     status = HAL_ERROR;
0960   }
0961 
0962   return status;
0963 }
0964 
0965 /**
0966   * @brief  Provide a new input buffer that will be loaded into the FMAC input memory area.
0967   * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
0968   *         the configuration information for FMAC module.
0969   * @param  pInput New input vector (additional input data).
0970   * @param  pInputSize Size of the input vector (if all the data can't be
0971   *         written, it will be updated with the number of data read from FMAC).
0972   * @retval HAL_StatusTypeDef HAL status
0973   */
0974 HAL_StatusTypeDef HAL_FMAC_AppendFilterData(FMAC_HandleTypeDef *hfmac, int16_t *pInput, uint16_t *pInputSize)
0975 {
0976   HAL_StatusTypeDef status;
0977 
0978   /* Check the function parameters */
0979   if ((pInput == NULL) || (pInputSize == NULL))
0980   {
0981     return HAL_ERROR;
0982   }
0983   if (*pInputSize == 0U)
0984   {
0985     return HAL_ERROR;
0986   }
0987 
0988   /* Check the START bit state */
0989   if (FMAC_GET_START_BIT(hfmac) == 0U)
0990   {
0991     return HAL_ERROR;
0992   }
0993 
0994   /* Check the FMAC configuration */
0995   if (hfmac->InputAccess == FMAC_BUFFER_ACCESS_NONE)
0996   {
0997     return HAL_ERROR;
0998   }
0999 
1000   /* Check whether the previous input vector has been handled */
1001   if ((hfmac->pInputSize != NULL) && (hfmac->InputCurrentSize < * (hfmac->pInputSize)))
1002   {
1003     return HAL_ERROR;
1004   }
1005 
1006   /* Check that FMAC was initialized and that no writing is already ongoing */
1007   if (hfmac->WrState == HAL_FMAC_STATE_READY)
1008   {
1009     /* Register the new input buffer */
1010     status = FMAC_AppendFilterDataUpdateState(hfmac, pInput, pInputSize);
1011   }
1012   else
1013   {
1014     status = HAL_ERROR;
1015   }
1016 
1017   return status;
1018 }
1019 
1020 /**
1021   * @brief  Provide a new output buffer to be filled with the data computed by FMAC unit.
1022   * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
1023   *         the configuration information for FMAC module.
1024   * @param  pOutput New output vector.
1025   * @param  pOutputSize Size of the output vector (if the vector can't
1026   *         be entirely filled, pOutputSize will be updated with the number
1027   *         of data read from FMAC).
1028   * @retval HAL_StatusTypeDef HAL status
1029   */
1030 HAL_StatusTypeDef HAL_FMAC_ConfigFilterOutputBuffer(FMAC_HandleTypeDef *hfmac, int16_t *pOutput, uint16_t *pOutputSize)
1031 {
1032   HAL_StatusTypeDef status;
1033 
1034   /* Check the function parameters */
1035   if ((pOutput == NULL) || (pOutputSize == NULL))
1036   {
1037     return HAL_ERROR;
1038   }
1039   if (*pOutputSize == 0U)
1040   {
1041     return HAL_ERROR;
1042   }
1043 
1044   /* Check the START bit state */
1045   if (FMAC_GET_START_BIT(hfmac) == 0U)
1046   {
1047     return HAL_ERROR;
1048   }
1049 
1050   /* Check the FMAC configuration */
1051   if (hfmac->OutputAccess == FMAC_BUFFER_ACCESS_NONE)
1052   {
1053     return HAL_ERROR;
1054   }
1055 
1056   /* Check whether the previous output vector has been handled */
1057   if ((hfmac->pOutputSize != NULL) && (hfmac->OutputCurrentSize < * (hfmac->pOutputSize)))
1058   {
1059     return HAL_ERROR;
1060   }
1061 
1062   /* Check that FMAC was initialized and that not reading is already ongoing */
1063   if (hfmac->RdState == HAL_FMAC_STATE_READY)
1064   {
1065     /* Register the new output buffer */
1066     status = FMAC_ConfigFilterOutputBufferUpdateState(hfmac, pOutput, pOutputSize);
1067   }
1068   else
1069   {
1070     status = HAL_ERROR;
1071   }
1072 
1073   return status;
1074 }
1075 
1076 /**
1077   * @brief  Handle the input and/or output data in polling mode
1078   * @note   This function writes the previously provided user's input data and
1079   *         fills the previously provided user's output buffer,
1080   *         according to the existing FMAC configuration (polling mode only).
1081   *         The function returns when the input data has been handled or
1082   *         when the output data is filled. The possible unused data isn't
1083   *         kept. It will be up to the user to handle it. The previously
1084   *         provided pInputSize and pOutputSize will be used to indicate to the
1085   *         size of the read/written data to the user.
1086   * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
1087   *         the configuration information for FMAC module.
1088   * @param  Timeout timeout value.
1089   * @retval HAL_StatusTypeDef HAL status
1090   */
1091 HAL_StatusTypeDef HAL_FMAC_PollFilterData(FMAC_HandleTypeDef *hfmac, uint32_t Timeout)
1092 {
1093   uint32_t tickstart;
1094   uint8_t inpolling;
1095   uint8_t inpollingover = POLLING_NOT_STOPPED;
1096   uint8_t outpolling;
1097   uint8_t outpollingover = POLLING_NOT_STOPPED;
1098   HAL_StatusTypeDef status;
1099 
1100   /* Check the START bit state */
1101   if (FMAC_GET_START_BIT(hfmac) == 0U)
1102   {
1103     return HAL_ERROR;
1104   }
1105 
1106   /* Check the configuration */
1107 
1108   /* Get the input and output mode (if no buffer was previously provided, nothing will be read/written) */
1109   if ((hfmac->InputAccess  == FMAC_BUFFER_ACCESS_POLLING) && (hfmac->pInput  != NULL))
1110   {
1111     inpolling = POLLING_ENABLED;
1112   }
1113   else
1114   {
1115     inpolling = POLLING_DISABLED;
1116   }
1117   if ((hfmac->OutputAccess == FMAC_BUFFER_ACCESS_POLLING) && (hfmac->pOutput != NULL))
1118   {
1119     outpolling = POLLING_ENABLED;
1120   }
1121   else
1122   {
1123     outpolling = POLLING_DISABLED;
1124   }
1125 
1126   /* Check the configuration */
1127   if ((inpolling == POLLING_DISABLED) && (outpolling == POLLING_DISABLED))
1128   {
1129     return HAL_ERROR;
1130   }
1131 
1132   /* Check handle state is ready */
1133   if (hfmac->State == HAL_FMAC_STATE_READY)
1134   {
1135     /* Change the FMAC state */
1136     hfmac->State = HAL_FMAC_STATE_BUSY;
1137 
1138     /* Get tick */
1139     tickstart = HAL_GetTick();
1140 
1141     /* Loop on reading and writing until timeout */
1142     while ((HAL_GetTick() - tickstart) < Timeout)
1143     {
1144       /* X1: Check the mode: polling or none */
1145       if (inpolling != POLLING_DISABLED)
1146       {
1147         FMAC_WriteDataIncrementPtr(hfmac, MAX_FILTER_DATA_SIZE_TO_HANDLE);
1148         if (hfmac->InputCurrentSize == *(hfmac->pInputSize))
1149         {
1150           inpollingover = POLLING_STOPPED;
1151         }
1152       }
1153 
1154       /* Y: Check the mode: polling or none */
1155       if (outpolling != POLLING_DISABLED)
1156       {
1157         FMAC_ReadDataIncrementPtr(hfmac, MAX_FILTER_DATA_SIZE_TO_HANDLE);
1158         if (hfmac->OutputCurrentSize == *(hfmac->pOutputSize))
1159         {
1160           outpollingover = POLLING_STOPPED;
1161         }
1162       }
1163 
1164       /* Exit if there isn't data to handle anymore on one side or another */
1165       if ((inpollingover != POLLING_NOT_STOPPED) || (outpollingover != POLLING_NOT_STOPPED))
1166       {
1167         break;
1168       }
1169     }
1170 
1171     /* Change the FMAC state; update the input and output sizes; reset the indexes */
1172     if (inpolling != POLLING_DISABLED)
1173     {
1174       (*(hfmac->pInputSize))  = hfmac->InputCurrentSize;
1175       FMAC_ResetInputStateAndDataPointers(hfmac);
1176     }
1177     if (outpolling != POLLING_DISABLED)
1178     {
1179       (*(hfmac->pOutputSize)) = hfmac->OutputCurrentSize;
1180       FMAC_ResetOutputStateAndDataPointers(hfmac);
1181     }
1182 
1183     /* Reset the busy flag (do not overwrite the possible write and read flag) */
1184     hfmac->State = HAL_FMAC_STATE_READY;
1185 
1186     if ((HAL_GetTick() - tickstart) >= Timeout)
1187     {
1188       hfmac->ErrorCode |= HAL_FMAC_ERROR_TIMEOUT;
1189       status = HAL_ERROR;
1190     }
1191     else
1192     {
1193       status = HAL_OK;
1194     }
1195   }
1196   else
1197   {
1198     status = HAL_ERROR;
1199   }
1200 
1201   return status;
1202 }
1203 
1204 /**
1205   * @brief  Stop the FMAC processing.
1206   * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
1207   *         the configuration information for FMAC module.
1208   * @retval HAL_StatusTypeDef HAL status
1209   */
1210 HAL_StatusTypeDef HAL_FMAC_FilterStop(FMAC_HandleTypeDef *hfmac)
1211 {
1212   HAL_StatusTypeDef status;
1213 
1214   /* Check handle state is ready */
1215   if (hfmac->State == HAL_FMAC_STATE_READY)
1216   {
1217     /* Change the FMAC state */
1218     hfmac->State = HAL_FMAC_STATE_BUSY;
1219 
1220     /* Set the START bit to 0 (stop the previously configured filter) */
1221     CLEAR_BIT(hfmac->Instance->PARAM, FMAC_PARAM_START);
1222 
1223     /* Disable the interrupts in order to avoid crossing cases */
1224     CLEAR_BIT(hfmac->Instance->CR, FMAC_DMA_REN | FMAC_DMA_WEN | FMAC_IT_RIEN | FMAC_IT_WIEN);
1225 
1226     /* In case of IT, update the sizes */
1227     if ((hfmac->InputAccess == FMAC_BUFFER_ACCESS_IT) && (hfmac->pInput != NULL))
1228     {
1229       (*(hfmac->pInputSize))  = hfmac->InputCurrentSize;
1230     }
1231     if ((hfmac->OutputAccess == FMAC_BUFFER_ACCESS_IT) && (hfmac->pOutput != NULL))
1232     {
1233       (*(hfmac->pOutputSize)) = hfmac->OutputCurrentSize;
1234     }
1235 
1236     /* Reset FMAC unit (internal pointers) */
1237     if (FMAC_Reset(hfmac) == HAL_ERROR)
1238     {
1239       /* Update FMAC error code and FMAC peripheral state */
1240       hfmac->ErrorCode = HAL_FMAC_ERROR_RESET;
1241       hfmac->State = HAL_FMAC_STATE_TIMEOUT;
1242       status = HAL_ERROR;
1243     }
1244     else
1245     {
1246       /* Reset the data pointers */
1247       FMAC_ResetDataPointers(hfmac);
1248 
1249       status = HAL_OK;
1250     }
1251 
1252     /* Reset the busy flag */
1253     hfmac->State = HAL_FMAC_STATE_READY;
1254   }
1255   else
1256   {
1257     status = HAL_ERROR;
1258   }
1259 
1260   return status;
1261 }
1262 
1263 /**
1264   * @}
1265   */
1266 
1267 /** @defgroup FMAC_Exported_Functions_Group3 Callback functions
1268   * @ingroup RTEMSBSPsARMSTM32H7
1269   * @brief    Callback functions.
1270   *
1271 @verbatim
1272   ==============================================================================
1273                       ##### Callback functions  #####
1274   ==============================================================================
1275     [..]  This section provides Interruption and DMA callback functions:
1276       (+) DMA or Interrupt: the user's input data is half written (DMA only)
1277           or completely written.
1278       (+) DMA or Interrupt: the user's output buffer is half filled (DMA only)
1279           or completely filled.
1280       (+) DMA or Interrupt: error handling.
1281 
1282 @endverbatim
1283   * @{
1284   */
1285 
1286 /**
1287   * @brief  FMAC error callback.
1288   * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
1289   *         the configuration information for FMAC module.
1290   * @retval None
1291   */
1292 __weak void HAL_FMAC_ErrorCallback(FMAC_HandleTypeDef *hfmac)
1293 {
1294   /* Prevent unused argument(s) compilation warning */
1295   UNUSED(hfmac);
1296 
1297   /* NOTE : This function should not be modified; when the callback is needed,
1298             the HAL_FMAC_ErrorCallback can be implemented in the user file.
1299    */
1300 }
1301 
1302 /**
1303   * @brief  FMAC get half data callback.
1304   * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
1305   *         the configuration information for FMAC module.
1306   * @retval None
1307   */
1308 __weak void HAL_FMAC_HalfGetDataCallback(FMAC_HandleTypeDef *hfmac)
1309 {
1310   /* Prevent unused argument(s) compilation warning */
1311   UNUSED(hfmac);
1312 
1313   /* NOTE : This function should not be modified; when the callback is needed,
1314             the HAL_FMAC_HalfGetDataCallback can be implemented in the user file.
1315    */
1316 }
1317 
1318 /**
1319   * @brief  FMAC get data callback.
1320   * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
1321   *         the configuration information for FMAC module.
1322   * @retval None
1323   */
1324 __weak void HAL_FMAC_GetDataCallback(FMAC_HandleTypeDef *hfmac)
1325 {
1326   /* Prevent unused argument(s) compilation warning */
1327   UNUSED(hfmac);
1328 
1329   /* NOTE : This function should not be modified; when the callback is needed,
1330             the HAL_FMAC_GetDataCallback can be implemented in the user file.
1331    */
1332 }
1333 
1334 /**
1335   * @brief  FMAC half output data ready callback.
1336   * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
1337   *         the configuration information for FMAC module.
1338   * @retval None
1339   */
1340 __weak void HAL_FMAC_HalfOutputDataReadyCallback(FMAC_HandleTypeDef *hfmac)
1341 {
1342   /* Prevent unused argument(s) compilation warning */
1343   UNUSED(hfmac);
1344 
1345   /* NOTE : This function should not be modified; when the callback is needed,
1346             the HAL_FMAC_HalfOutputDataReadyCallback can be implemented in the user file.
1347    */
1348 }
1349 
1350 /**
1351   * @brief  FMAC output data ready callback.
1352   * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
1353   *         the configuration information for FMAC module.
1354   * @retval None
1355   */
1356 __weak void HAL_FMAC_OutputDataReadyCallback(FMAC_HandleTypeDef *hfmac)
1357 {
1358   /* Prevent unused argument(s) compilation warning */
1359   UNUSED(hfmac);
1360 
1361   /* NOTE : This function should not be modified; when the callback is needed,
1362             the HAL_FMAC_OutputDataReadyCallback can be implemented in the user file.
1363    */
1364 }
1365 
1366 /**
1367   * @brief  FMAC filter configuration callback.
1368   * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
1369   *         the configuration information for FMAC module.
1370   * @retval None
1371   */
1372 __weak void HAL_FMAC_FilterConfigCallback(FMAC_HandleTypeDef *hfmac)
1373 {
1374   /* Prevent unused argument(s) compilation warning */
1375   UNUSED(hfmac);
1376 
1377   /* NOTE : This function should not be modified; when the callback is needed,
1378             the HAL_FMAC_FilterConfigCallback can be implemented in the user file.
1379    */
1380 }
1381 
1382 /**
1383   * @brief  FMAC filter preload callback.
1384   * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
1385   *         the configuration information for FMAC module.
1386   * @retval None
1387   */
1388 __weak void HAL_FMAC_FilterPreloadCallback(FMAC_HandleTypeDef *hfmac)
1389 {
1390   /* Prevent unused argument(s) compilation warning */
1391   UNUSED(hfmac);
1392 
1393   /* NOTE : This function should not be modified; when the callback is needed,
1394             the HAL_FMAC_FilterPreloadCallback can be implemented in the user file.
1395    */
1396 }
1397 
1398 /**
1399   * @}
1400   */
1401 
1402 /** @defgroup FMAC_Exported_Functions_Group4 IRQ handler management
1403   * @ingroup RTEMSBSPsARMSTM32H7
1404   * @brief    IRQ handler.
1405   *
1406 @verbatim
1407   ==============================================================================
1408                 ##### IRQ handler management #####
1409   ==============================================================================
1410 [..]  This section provides IRQ handler function.
1411 
1412 @endverbatim
1413   * @{
1414   */
1415 
1416 /**
1417   * @brief  Handle FMAC interrupt request.
1418   * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
1419   *         the configuration information for FMAC module.
1420   * @retval None
1421   */
1422 void HAL_FMAC_IRQHandler(FMAC_HandleTypeDef *hfmac)
1423 {
1424   uint32_t itsource;
1425 
1426   /* Check if the read interrupt is enabled and if Y buffer empty flag isn't set */
1427   itsource = __HAL_FMAC_GET_IT_SOURCE(hfmac, FMAC_IT_RIEN);
1428   if ((__HAL_FMAC_GET_FLAG(hfmac, FMAC_FLAG_YEMPTY) == 0U) && (itsource != 0U))
1429   {
1430     /* Read some data if possible (Y size is used as a pseudo timeout in order
1431        to not get stuck too long under IT if FMAC keeps on processing input
1432        data reloaded via DMA for instance). */
1433     if (hfmac->pOutput != NULL)
1434     {
1435       FMAC_ReadDataIncrementPtr(hfmac, (uint16_t)FMAC_GET_Y_SIZE(hfmac));
1436     }
1437 
1438     /* Indicate that data is ready to be read */
1439     if ((hfmac->pOutput == NULL) || (hfmac->OutputCurrentSize == *(hfmac->pOutputSize)))
1440     {
1441       /* Reset the pointers to indicate new data will be needed */
1442       FMAC_ResetOutputStateAndDataPointers(hfmac);
1443 
1444       /* Call the output data ready callback */
1445 #if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1)
1446       hfmac->OutputDataReadyCallback(hfmac);
1447 #else
1448       HAL_FMAC_OutputDataReadyCallback(hfmac);
1449 #endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */
1450     }
1451   }
1452 
1453   /* Check if the write interrupt is enabled and if X1 buffer full flag isn't set */
1454   itsource = __HAL_FMAC_GET_IT_SOURCE(hfmac, FMAC_IT_WIEN);
1455   if ((__HAL_FMAC_GET_FLAG(hfmac, FMAC_FLAG_X1FULL) == 0U) && (itsource != 0U))
1456   {
1457     /* Write some data if possible (X1 size is used as a pseudo timeout in order
1458        to not get stuck too long under IT if FMAC keep on processing input
1459        data whereas its output emptied via DMA for instance). */
1460     if (hfmac->pInput != NULL)
1461     {
1462       FMAC_WriteDataIncrementPtr(hfmac, (uint16_t)FMAC_GET_X1_SIZE(hfmac));
1463     }
1464 
1465     /* Indicate that new data will be needed */
1466     if ((hfmac->pInput == NULL) || (hfmac->InputCurrentSize == *(hfmac->pInputSize)))
1467     {
1468       /* Reset the pointers to indicate new data will be needed */
1469       FMAC_ResetInputStateAndDataPointers(hfmac);
1470 
1471       /* Call the get data callback */
1472 #if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1)
1473       hfmac->GetDataCallback(hfmac);
1474 #else
1475       HAL_FMAC_GetDataCallback(hfmac);
1476 #endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */
1477     }
1478   }
1479 
1480   /* Check if the overflow error interrupt is enabled and if overflow error flag is raised */
1481   itsource = __HAL_FMAC_GET_IT_SOURCE(hfmac, FMAC_IT_OVFLIEN);
1482   if ((__HAL_FMAC_GET_FLAG(hfmac, FMAC_FLAG_OVFL) != 0U) && (itsource != 0U))
1483   {
1484     hfmac->ErrorCode |= HAL_FMAC_ERROR_OVFL;
1485   }
1486 
1487   /* Check if the underflow error interrupt is enabled and if underflow error flag is raised */
1488   itsource = __HAL_FMAC_GET_IT_SOURCE(hfmac, FMAC_IT_UNFLIEN);
1489   if ((__HAL_FMAC_GET_FLAG(hfmac, FMAC_FLAG_UNFL) != 0U) && (itsource != 0U))
1490   {
1491     hfmac->ErrorCode |= HAL_FMAC_ERROR_UNFL;
1492   }
1493 
1494   /* Check if the saturation error interrupt is enabled and if saturation error flag is raised */
1495   itsource = __HAL_FMAC_GET_IT_SOURCE(hfmac, FMAC_IT_SATIEN);
1496   if ((__HAL_FMAC_GET_FLAG(hfmac, FMAC_FLAG_SAT) != 0U) && (itsource != 0U))
1497   {
1498     hfmac->ErrorCode |= HAL_FMAC_ERROR_SAT;
1499   }
1500 
1501   /* Call the error callback if an error occurred */
1502   if (hfmac->ErrorCode != HAL_FMAC_ERROR_NONE)
1503   {
1504     /* Call the error callback */
1505 #if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1)
1506     hfmac->ErrorCallback(hfmac);
1507 #else
1508     HAL_FMAC_ErrorCallback(hfmac);
1509 #endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */
1510   }
1511 }
1512 
1513 /**
1514   * @}
1515   */
1516 
1517 /** @defgroup FMAC_Exported_Functions_Group5 Peripheral State and Error functions
1518   * @ingroup RTEMSBSPsARMSTM32H7
1519   * @brief    Peripheral State and Error functions.
1520   *
1521 @verbatim
1522   ==============================================================================
1523                  ##### Peripheral State and Error functions #####
1524   ==============================================================================
1525     [..]  This subsection provides functions allowing to
1526       (+) Check the FMAC state
1527       (+) Get error code
1528 
1529 @endverbatim
1530   * @{
1531   */
1532 
1533 /**
1534   * @brief  Return the FMAC state.
1535   * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
1536   *         the configuration information for FMAC module.
1537   * @retval HAL_FMAC_StateTypeDef FMAC state
1538   */
1539 HAL_FMAC_StateTypeDef HAL_FMAC_GetState(const FMAC_HandleTypeDef *hfmac)
1540 {
1541   /* Return FMAC state */
1542   return hfmac->State;
1543 }
1544 
1545 /**
1546   * @brief  Return the FMAC peripheral error.
1547   * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
1548   *         the configuration information for FMAC module.
1549   * @note   The returned error is a bit-map combination of possible errors.
1550   * @retval uint32_t Error bit-map based on @ref FMAC_Error_Code
1551   */
1552 uint32_t HAL_FMAC_GetError(const FMAC_HandleTypeDef *hfmac)
1553 {
1554   /* Return FMAC error code */
1555   return hfmac->ErrorCode;
1556 }
1557 
1558 /**
1559   * @}
1560   */
1561 
1562 /**
1563   * @}
1564   */
1565 
1566 /** @defgroup FMAC_Private_Functions FMAC Private Functions
1567   * @ingroup RTEMSBSPsARMSTM32H7
1568   * @{
1569   */
1570 
1571 /**
1572   ==============================================================================
1573                        ##### FMAC Private Functions #####
1574   ==============================================================================
1575   */
1576 /**
1577   * @brief  Perform a reset of the FMAC unit.
1578   * @param  hfmac FMAC handle.
1579   * @retval HAL_StatusTypeDef HAL status
1580   */
1581 static HAL_StatusTypeDef FMAC_Reset(FMAC_HandleTypeDef *hfmac)
1582 {
1583   uint32_t tickstart;
1584 
1585   /* Init tickstart for timeout management*/
1586   tickstart = HAL_GetTick();
1587 
1588   /* Perform the reset */
1589   SET_BIT(hfmac->Instance->CR, FMAC_CR_RESET);
1590 
1591   /* Wait until flag is reset */
1592   while (READ_BIT(hfmac->Instance->CR, FMAC_CR_RESET) != 0U)
1593   {
1594     if ((HAL_GetTick() - tickstart) > HAL_FMAC_RESET_TIMEOUT_VALUE)
1595     {
1596       hfmac->ErrorCode |= HAL_FMAC_ERROR_TIMEOUT;
1597       return HAL_ERROR;
1598     }
1599   }
1600 
1601   hfmac->ErrorCode = HAL_FMAC_ERROR_NONE;
1602   return HAL_OK;
1603 }
1604 
1605 /**
1606   * @brief  Reset the data pointers of the FMAC unit.
1607   * @param  hfmac FMAC handle.
1608   * @retval None
1609   */
1610 static void FMAC_ResetDataPointers(FMAC_HandleTypeDef *hfmac)
1611 {
1612   FMAC_ResetInputStateAndDataPointers(hfmac);
1613   FMAC_ResetOutputStateAndDataPointers(hfmac);
1614 }
1615 
1616 /**
1617   * @brief  Reset the input data pointers of the FMAC unit.
1618   * @param  hfmac FMAC handle.
1619   * @retval None
1620   */
1621 static void FMAC_ResetInputStateAndDataPointers(FMAC_HandleTypeDef *hfmac)
1622 {
1623   hfmac->pInput = NULL;
1624   hfmac->pInputSize = NULL;
1625   hfmac->InputCurrentSize = 0U;
1626   hfmac->WrState = HAL_FMAC_STATE_READY;
1627 }
1628 
1629 /**
1630   * @brief  Reset the output data pointers of the FMAC unit.
1631   * @param  hfmac FMAC handle.
1632   * @retval None
1633   */
1634 static void FMAC_ResetOutputStateAndDataPointers(FMAC_HandleTypeDef *hfmac)
1635 {
1636   hfmac->pOutput = NULL;
1637   hfmac->pOutputSize = NULL;
1638   hfmac->OutputCurrentSize = 0U;
1639   hfmac->RdState = HAL_FMAC_STATE_READY;
1640 }
1641 
1642 /**
1643   * @brief  Configure the FMAC filter.
1644   * @note   The configuration is done according to the parameters
1645   *         specified in the FMAC_FilterConfigTypeDef structure.
1646   * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
1647   *         the configuration information for FMAC module.
1648   * @param  pConfig pointer to a FMAC_FilterConfigTypeDef structure that
1649   *         contains the FMAC configuration information.
1650   * @param  PreloadAccess access mode used for the preload (polling or DMA).
1651   * @retval HAL_StatusTypeDef HAL status
1652   */
1653 static HAL_StatusTypeDef FMAC_FilterConfig(FMAC_HandleTypeDef *hfmac, FMAC_FilterConfigTypeDef *pConfig,
1654                                            uint8_t PreloadAccess)
1655 {
1656   uint32_t tickstart;
1657   uint32_t tmpcr;
1658 #if defined(USE_FULL_ASSERT)
1659   uint32_t x2size;
1660 #endif /* USE_FULL_ASSERT */
1661 
1662   /* Check the parameters */
1663   assert_param(IS_FMAC_THRESHOLD(pConfig->InputThreshold));
1664   assert_param(IS_FMAC_THRESHOLD(pConfig->OutputThreshold));
1665   assert_param(IS_FMAC_BUFFER_ACCESS(pConfig->InputAccess));
1666   assert_param(IS_FMAC_BUFFER_ACCESS(pConfig->OutputAccess));
1667   assert_param(IS_FMAC_CLIP_STATE(pConfig->Clip));
1668   assert_param(IS_FMAC_FILTER_FUNCTION(pConfig->Filter));
1669   assert_param(IS_FMAC_PARAM_P(pConfig->Filter, pConfig->P));
1670   assert_param(IS_FMAC_PARAM_Q(pConfig->Filter, pConfig->Q));
1671   assert_param(IS_FMAC_PARAM_R(pConfig->Filter, pConfig->R));
1672 
1673   /* Check the START bit state */
1674   if (FMAC_GET_START_BIT(hfmac) != 0U)
1675   {
1676     return HAL_ERROR;
1677   }
1678 
1679   /* Check handle state is ready */
1680   if (hfmac->State != HAL_FMAC_STATE_READY)
1681   {
1682     return HAL_ERROR;
1683   }
1684 
1685   /* Change the FMAC state */
1686   hfmac->State = HAL_FMAC_STATE_BUSY;
1687 
1688   /* Get tick */
1689   tickstart = HAL_GetTick();
1690 
1691   /* Indicate that there is no valid configuration done */
1692   hfmac->FilterParam = 0U;
1693 
1694   /* FMAC_X1BUFCFG: Configure the input buffer within the internal memory if required */
1695   if (pConfig->InputBufferSize != 0U)
1696   {
1697     MODIFY_REG(hfmac->Instance->X1BUFCFG,                                                                   \
1698                (FMAC_X1BUFCFG_X1_BASE | FMAC_X1BUFCFG_X1_BUF_SIZE),                                         \
1699                (((((uint32_t)(pConfig->InputBaseAddress)) << FMAC_X1BUFCFG_X1_BASE_Pos)     & FMAC_X1BUFCFG_X1_BASE) | \
1700                 ((((uint32_t)(pConfig->InputBufferSize))  << FMAC_X1BUFCFG_X1_BUF_SIZE_Pos) & \
1701                  FMAC_X1BUFCFG_X1_BUF_SIZE)));
1702   }
1703 
1704   /* FMAC_X1BUFCFG: Configure the input threshold if valid when compared to the configured X1 size */
1705   if (pConfig->InputThreshold != FMAC_THRESHOLD_NO_VALUE)
1706   {
1707     /* Check the parameter */
1708     assert_param(IS_FMAC_THRESHOLD_APPLICABLE(FMAC_GET_X1_SIZE(hfmac), pConfig->InputThreshold, pConfig->InputAccess));
1709 
1710     MODIFY_REG(hfmac->Instance->X1BUFCFG, \
1711                FMAC_X1BUFCFG_FULL_WM,     \
1712                ((pConfig->InputThreshold) & FMAC_X1BUFCFG_FULL_WM));
1713   }
1714 
1715   /* FMAC_X2BUFCFG: Configure the coefficient buffer within the internal memory */
1716   if (pConfig->CoeffBufferSize != 0U)
1717   {
1718     MODIFY_REG(hfmac->Instance->X2BUFCFG,                                                                   \
1719                (FMAC_X2BUFCFG_X2_BASE | FMAC_X2BUFCFG_X2_BUF_SIZE),                                         \
1720                (((((uint32_t)(pConfig->CoeffBaseAddress)) << FMAC_X2BUFCFG_X2_BASE_Pos)     & FMAC_X2BUFCFG_X2_BASE) | \
1721                 ((((uint32_t)(pConfig->CoeffBufferSize))  << FMAC_X2BUFCFG_X2_BUF_SIZE_Pos) &\
1722                  FMAC_X2BUFCFG_X2_BUF_SIZE)));
1723   }
1724 
1725   /* FMAC_YBUFCFG: Configure the output buffer within the internal memory if required */
1726   if (pConfig->OutputBufferSize != 0U)
1727   {
1728     MODIFY_REG(hfmac->Instance->YBUFCFG,                                                                    \
1729                (FMAC_YBUFCFG_Y_BASE | FMAC_YBUFCFG_Y_BUF_SIZE),                                             \
1730                (((((uint32_t)(pConfig->OutputBaseAddress)) << FMAC_YBUFCFG_Y_BASE_Pos)     & FMAC_YBUFCFG_Y_BASE) |    \
1731                 ((((uint32_t)(pConfig->OutputBufferSize))  << FMAC_YBUFCFG_Y_BUF_SIZE_Pos) & FMAC_YBUFCFG_Y_BUF_SIZE)));
1732   }
1733 
1734   /* FMAC_YBUFCFG: Configure the output threshold if valid when compared to the configured Y size */
1735   if (pConfig->OutputThreshold != FMAC_THRESHOLD_NO_VALUE)
1736   {
1737     /* Check the parameter */
1738     assert_param(IS_FMAC_THRESHOLD_APPLICABLE(FMAC_GET_Y_SIZE(hfmac), pConfig->OutputThreshold, pConfig->OutputAccess));
1739 
1740     MODIFY_REG(hfmac->Instance->YBUFCFG, \
1741                FMAC_YBUFCFG_EMPTY_WM,    \
1742                ((pConfig->OutputThreshold) & FMAC_YBUFCFG_EMPTY_WM));
1743   }
1744 
1745   /* FMAC_CR: Configure the clip feature */
1746   tmpcr = pConfig->Clip & FMAC_CR_CLIPEN;
1747 
1748   /* FMAC_CR: If IT or DMA will be used, enable error interrupts.
1749     * Being more a debugging feature, FMAC_CR_SATIEN isn't enabled by default. */
1750   if ((pConfig->InputAccess  == FMAC_BUFFER_ACCESS_DMA) || (pConfig->InputAccess  == FMAC_BUFFER_ACCESS_IT) ||
1751       (pConfig->OutputAccess == FMAC_BUFFER_ACCESS_DMA) || (pConfig->OutputAccess == FMAC_BUFFER_ACCESS_IT))
1752   {
1753     tmpcr |= FMAC_IT_UNFLIEN | FMAC_IT_OVFLIEN;
1754   }
1755 
1756   /* FMAC_CR: write the value */
1757   WRITE_REG(hfmac->Instance->CR, tmpcr);
1758 
1759   /* Save the input/output accesses in order to configure RIEN, WIEN, DMAREN and DMAWEN during filter start */
1760   hfmac->InputAccess = pConfig->InputAccess;
1761   hfmac->OutputAccess = pConfig->OutputAccess;
1762 
1763   /* Check whether the configured X2 is big enough for the filter */
1764 #if defined(USE_FULL_ASSERT)
1765   x2size = FMAC_GET_X2_SIZE(hfmac);
1766 #endif /* USE_FULL_ASSERT */
1767   assert_param(((pConfig->Filter == FMAC_FUNC_CONVO_FIR) && (x2size >= pConfig->P)) || \
1768                ((pConfig->Filter == FMAC_FUNC_IIR_DIRECT_FORM_1) && \
1769                 (x2size >= ((uint32_t)pConfig->P + (uint32_t)pConfig->Q))));
1770 
1771   /* Build the PARAM value that will be used when starting the filter */
1772   hfmac->FilterParam = (FMAC_PARAM_START | pConfig->Filter |                   \
1773                         ((((uint32_t)(pConfig->P)) << FMAC_PARAM_P_Pos) & FMAC_PARAM_P) | \
1774                         ((((uint32_t)(pConfig->Q)) << FMAC_PARAM_Q_Pos) & FMAC_PARAM_Q) | \
1775                         ((((uint32_t)(pConfig->R)) << FMAC_PARAM_R_Pos) & FMAC_PARAM_R));
1776 
1777   /* Initialize the coefficient buffer if required (pCoeffA for FIR only) */
1778   if ((pConfig->pCoeffB != NULL) && (pConfig->CoeffBSize != 0U))
1779   {
1780     /* FIR/IIR: The provided coefficients should match X2 size */
1781     assert_param(((uint32_t)pConfig->CoeffASize + (uint32_t)pConfig->CoeffBSize) <= x2size);
1782     /* FIR/IIR: The size of pCoeffB should match the parameter P */
1783     assert_param(pConfig->CoeffBSize >= pConfig->P);
1784     /* pCoeffA should be provided for IIR but not for FIR */
1785     /* IIR : if pCoeffB is provided, pCoeffA should also be there */
1786     /* IIR: The size of pCoeffA should match the parameter Q */
1787     assert_param(((pConfig->Filter == FMAC_FUNC_CONVO_FIR) &&
1788                   (pConfig->pCoeffA == NULL) && (pConfig->CoeffASize == 0U)) ||
1789                  ((pConfig->Filter == FMAC_FUNC_IIR_DIRECT_FORM_1) &&
1790                   (pConfig->pCoeffA != NULL) && (pConfig->CoeffASize != 0U) &&
1791                   (pConfig->CoeffASize >= pConfig->Q)));
1792 
1793     /* Write number of values to be loaded, the data load function and start the operation */
1794     WRITE_REG(hfmac->Instance->PARAM,                      \
1795               (((uint32_t)(pConfig->CoeffBSize) << FMAC_PARAM_P_Pos) | \
1796                ((uint32_t)(pConfig->CoeffASize) << FMAC_PARAM_Q_Pos) | \
1797                FMAC_FUNC_LOAD_X2 | FMAC_PARAM_START));
1798 
1799     if (PreloadAccess == PRELOAD_ACCESS_POLLING)
1800     {
1801       /* Load the buffer into the internal memory */
1802       FMAC_WritePreloadDataIncrementPtr(hfmac, &(pConfig->pCoeffB), pConfig->CoeffBSize);
1803 
1804       /* Load pCoeffA if needed */
1805       if ((pConfig->pCoeffA != NULL) && (pConfig->CoeffASize != 0U))
1806       {
1807         /* Load the buffer into the internal memory */
1808         FMAC_WritePreloadDataIncrementPtr(hfmac, &(pConfig->pCoeffA), pConfig->CoeffASize);
1809       }
1810 
1811       /* Wait for the end of the writing */
1812       if (FMAC_WaitOnStartUntilTimeout(hfmac, tickstart, HAL_FMAC_TIMEOUT_VALUE) != HAL_OK)
1813       {
1814         hfmac->ErrorCode |= HAL_FMAC_ERROR_TIMEOUT;
1815         hfmac->State = HAL_FMAC_STATE_TIMEOUT;
1816         return HAL_ERROR;
1817       }
1818 
1819       /* Change the FMAC state */
1820       hfmac->State = HAL_FMAC_STATE_READY;
1821     }
1822     else
1823     {
1824       hfmac->pInput = pConfig->pCoeffA;
1825       hfmac->InputCurrentSize = pConfig->CoeffASize;
1826 
1827       /* Set the FMAC DMA transfer complete callback */
1828       hfmac->hdmaPreload->XferHalfCpltCallback = NULL;
1829       hfmac->hdmaPreload->XferCpltCallback = FMAC_DMAFilterConfig;
1830       /* Set the DMA error callback */
1831       hfmac->hdmaPreload->XferErrorCallback = FMAC_DMAError;
1832 
1833       /* Enable the DMA stream managing FMAC preload data write */
1834       return (HAL_DMA_Start_IT(hfmac->hdmaPreload, (uint32_t)pConfig->pCoeffB, (uint32_t)&hfmac->Instance->WDATA,
1835                                pConfig->CoeffBSize));
1836     }
1837   }
1838   else
1839   {
1840     /* Change the FMAC state */
1841     hfmac->State = HAL_FMAC_STATE_READY;
1842   }
1843 
1844   return HAL_OK;
1845 }
1846 
1847 /**
1848   * @brief  Preload the input (FIR, IIR) and output data (IIR) of the FMAC filter.
1849   * @note   The set(s) of data will be used by FMAC as soon as @ref HAL_FMAC_FilterStart is called.
1850   * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
1851   *         the configuration information for FMAC module.
1852   * @param  pInput Preloading of the first elements of the input buffer (X1).
1853   *         If not needed (no data available when starting), it should be set to NULL.
1854   * @param  InputSize Size of the input vector.
1855   *         As pInput is used for preloading data, it cannot be bigger than the input memory area.
1856   * @param  pOutput [IIR] Preloading of the first elements of the output vector (Y).
1857   *         If not needed, it should be set to NULL.
1858   * @param  OutputSize Size of the output vector.
1859   *         As pOutput is used for preloading data, it cannot be bigger than the output memory area.
1860   * @param  PreloadAccess access mode used for the preload (polling or DMA).
1861   * @note   The input and the output buffers can be filled by calling several times @ref HAL_FMAC_FilterPreload
1862   *         (each call filling partly the buffers). In case of overflow (too much data provided through
1863   *         all these calls), an error will be returned.
1864   * @retval HAL_StatusTypeDef HAL status
1865   */
1866 static HAL_StatusTypeDef FMAC_FilterPreload(FMAC_HandleTypeDef *hfmac, int16_t *pInput, uint8_t InputSize,
1867                                             int16_t *pOutput, uint8_t OutputSize, uint8_t PreloadAccess)
1868 {
1869   uint32_t tickstart;
1870   HAL_StatusTypeDef status;
1871 
1872   /* Check the START bit state */
1873   if (FMAC_GET_START_BIT(hfmac) != 0U)
1874   {
1875     return HAL_ERROR;
1876   }
1877 
1878   /* Check that a valid configuration was done previously */
1879   if (hfmac->FilterParam == 0U)
1880   {
1881     return HAL_ERROR;
1882   }
1883 
1884   /* Check the preload input buffers isn't too big */
1885   if ((InputSize > FMAC_GET_X1_SIZE(hfmac)) && (pInput != NULL))
1886   {
1887     return HAL_ERROR;
1888   }
1889 
1890   /* Check the preload output buffer isn't too big */
1891   if ((OutputSize > FMAC_GET_Y_SIZE(hfmac)) && (pOutput != NULL))
1892   {
1893     return HAL_ERROR;
1894   }
1895 
1896   /* Check handle state is ready */
1897   if (hfmac->State != HAL_FMAC_STATE_READY)
1898   {
1899     return HAL_ERROR;
1900   }
1901 
1902   /* Change the FMAC state */
1903   hfmac->State = HAL_FMAC_STATE_BUSY;
1904 
1905   /* Get tick */
1906   tickstart = HAL_GetTick();
1907 
1908   /* Preload the input buffer if required */
1909   if ((pInput != NULL) && (InputSize != 0U))
1910   {
1911     /* Write number of values to be loaded, the data load function and start the operation */
1912     WRITE_REG(hfmac->Instance->PARAM, \
1913               (((uint32_t)InputSize << FMAC_PARAM_P_Pos) | FMAC_FUNC_LOAD_X1 | FMAC_PARAM_START));
1914 
1915     if (PreloadAccess == PRELOAD_ACCESS_POLLING)
1916     {
1917       /* Load the buffer into the internal memory */
1918       FMAC_WritePreloadDataIncrementPtr(hfmac, &pInput, InputSize);
1919 
1920       /* Wait for the end of the writing */
1921       if (FMAC_WaitOnStartUntilTimeout(hfmac, tickstart, HAL_FMAC_TIMEOUT_VALUE) != HAL_OK)
1922       {
1923         hfmac->ErrorCode |= HAL_FMAC_ERROR_TIMEOUT;
1924         hfmac->State = HAL_FMAC_STATE_TIMEOUT;
1925         return HAL_ERROR;
1926       }
1927     }
1928     else
1929     {
1930       hfmac->pInput = pOutput;
1931       hfmac->InputCurrentSize = OutputSize;
1932 
1933       /* Set the FMAC DMA transfer complete callback */
1934       hfmac->hdmaPreload->XferHalfCpltCallback = NULL;
1935       hfmac->hdmaPreload->XferCpltCallback = FMAC_DMAFilterPreload;
1936       /* Set the DMA error callback */
1937       hfmac->hdmaPreload->XferErrorCallback = FMAC_DMAError;
1938 
1939       /* Enable the DMA stream managing FMAC preload data write */
1940       return (HAL_DMA_Start_IT(hfmac->hdmaPreload, (uint32_t)pInput, (uint32_t)&hfmac->Instance->WDATA, InputSize));
1941     }
1942   }
1943 
1944   /* Preload the output buffer if required */
1945   if ((pOutput != NULL) && (OutputSize != 0U))
1946   {
1947     /* Write number of values to be loaded, the data load function and start the operation */
1948     WRITE_REG(hfmac->Instance->PARAM, \
1949               (((uint32_t)OutputSize << FMAC_PARAM_P_Pos) | FMAC_FUNC_LOAD_Y | FMAC_PARAM_START));
1950 
1951     if (PreloadAccess == PRELOAD_ACCESS_POLLING)
1952     {
1953       /* Load the buffer into the internal memory */
1954       FMAC_WritePreloadDataIncrementPtr(hfmac, &pOutput, OutputSize);
1955 
1956       /* Wait for the end of the writing */
1957       if (FMAC_WaitOnStartUntilTimeout(hfmac, tickstart, HAL_FMAC_TIMEOUT_VALUE) != HAL_OK)
1958       {
1959         hfmac->ErrorCode |= HAL_FMAC_ERROR_TIMEOUT;
1960         hfmac->State = HAL_FMAC_STATE_TIMEOUT;
1961         return HAL_ERROR;
1962       }
1963     }
1964     else
1965     {
1966       hfmac->pInput = NULL;
1967       hfmac->InputCurrentSize = 0U;
1968 
1969       /* Set the FMAC DMA transfer complete callback */
1970       hfmac->hdmaPreload->XferHalfCpltCallback = NULL;
1971       hfmac->hdmaPreload->XferCpltCallback = FMAC_DMAFilterPreload;
1972       /* Set the DMA error callback */
1973       hfmac->hdmaPreload->XferErrorCallback = FMAC_DMAError;
1974 
1975       /* Enable the DMA stream managing FMAC preload data write */
1976       return (HAL_DMA_Start_IT(hfmac->hdmaPreload, (uint32_t)pOutput, (uint32_t)&hfmac->Instance->WDATA, OutputSize));
1977     }
1978   }
1979 
1980   /* Update the error codes */
1981   if (__HAL_FMAC_GET_FLAG(hfmac, FMAC_FLAG_OVFL))
1982   {
1983     hfmac->ErrorCode |= HAL_FMAC_ERROR_OVFL;
1984   }
1985   if (__HAL_FMAC_GET_FLAG(hfmac, FMAC_FLAG_UNFL))
1986   {
1987     hfmac->ErrorCode |= HAL_FMAC_ERROR_UNFL;
1988   }
1989   if (__HAL_FMAC_GET_FLAG(hfmac, FMAC_FLAG_SAT))
1990   {
1991     hfmac->ErrorCode |= HAL_FMAC_ERROR_SAT;
1992   }
1993 
1994   /* Change the FMAC state */
1995   hfmac->State = HAL_FMAC_STATE_READY;
1996 
1997   /* Return function status */
1998   if (hfmac->ErrorCode == HAL_FMAC_ERROR_NONE)
1999   {
2000     status = HAL_OK;
2001   }
2002   else
2003   {
2004     status = HAL_ERROR;
2005   }
2006   return status;
2007 }
2008 
2009 /**
2010   * @brief  Write data into FMAC internal memory through WDATA and increment input buffer pointer.
2011   * @note   This function is only used with preload functions.
2012   * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
2013   *         the configuration information for FMAC module.
2014   * @param  ppData pointer to pointer to the data buffer.
2015   * @param  Size size of the data buffer.
2016   * @retval None
2017   */
2018 static void FMAC_WritePreloadDataIncrementPtr(FMAC_HandleTypeDef *hfmac, int16_t **ppData, uint8_t Size)
2019 {
2020   uint8_t index;
2021 
2022   /* Load the buffer into the internal memory */
2023   for (index = Size; index > 0U; index--)
2024   {
2025     WRITE_REG(hfmac->Instance->WDATA, (((uint32_t)(*(*ppData))) & FMAC_WDATA_WDATA));
2026     (*ppData)++;
2027   }
2028 }
2029 
2030 /**
2031   * @brief  Handle FMAC Function Timeout.
2032   * @param  hfmac FMAC handle.
2033   * @param  Tickstart Tick start value.
2034   * @param  Timeout Timeout duration.
2035   * @retval HAL_StatusTypeDef HAL status
2036   */
2037 static HAL_StatusTypeDef FMAC_WaitOnStartUntilTimeout(FMAC_HandleTypeDef *hfmac, uint32_t Tickstart, uint32_t Timeout)
2038 {
2039   /* Wait until flag changes */
2040   while (READ_BIT(hfmac->Instance->PARAM, FMAC_PARAM_START) != 0U)
2041   {
2042     if ((HAL_GetTick() - Tickstart) > Timeout)
2043     {
2044       hfmac->ErrorCode |= HAL_FMAC_ERROR_TIMEOUT;
2045 
2046       return HAL_ERROR;
2047     }
2048   }
2049   return HAL_OK;
2050 }
2051 
2052 /**
2053   * @brief  Register the new input buffer, update DMA configuration if needed and change the FMAC state.
2054   * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
2055   *         the configuration information for FMAC module.
2056   * @param  pInput New input vector (additional input data).
2057   * @param  pInputSize Size of the input vector (if all the data can't be
2058   *         written, it will be updated with the number of data read from FMAC).
2059   * @retval HAL_StatusTypeDef HAL status
2060   */
2061 static HAL_StatusTypeDef FMAC_AppendFilterDataUpdateState(FMAC_HandleTypeDef *hfmac, int16_t *pInput,
2062                                                           uint16_t *pInputSize)
2063 {
2064   /* Change the FMAC state */
2065   hfmac->WrState = HAL_FMAC_STATE_BUSY_WR;
2066 
2067   /* Reset the current size */
2068   hfmac->InputCurrentSize = 0U;
2069 
2070   /* Handle the pointer depending on the input access */
2071   if (hfmac->InputAccess == FMAC_BUFFER_ACCESS_DMA)
2072   {
2073     hfmac->pInput = NULL;
2074     hfmac->pInputSize = NULL;
2075 
2076     /* Set the FMAC DMA transfer complete callback */
2077     hfmac->hdmaIn->XferHalfCpltCallback = FMAC_DMAHalfGetData;
2078     hfmac->hdmaIn->XferCpltCallback = FMAC_DMAGetData;
2079     /* Set the DMA error callback */
2080     hfmac->hdmaIn->XferErrorCallback = FMAC_DMAError;
2081 
2082     /* Enable the DMA stream managing FMAC input data write */
2083     return (HAL_DMA_Start_IT(hfmac->hdmaIn, (uint32_t)pInput, (uint32_t)&hfmac->Instance->WDATA, *pInputSize));
2084   }
2085   else
2086   {
2087     /* Update the input data information (polling, IT) */
2088     hfmac->pInput = pInput;
2089     hfmac->pInputSize = pInputSize;
2090   }
2091 
2092   return HAL_OK;
2093 }
2094 
2095 /**
2096   * @brief  Register the new output buffer, update DMA configuration if needed and change the FMAC state.
2097   * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
2098   *         the configuration information for FMAC module.
2099   * @param  pOutput New output vector.
2100   * @param  pOutputSize Size of the output vector (if the vector can't
2101   *         be entirely filled, pOutputSize will be updated with the number
2102   *         of data read from FMAC).
2103   * @retval HAL_StatusTypeDef HAL status
2104   */
2105 static HAL_StatusTypeDef FMAC_ConfigFilterOutputBufferUpdateState(FMAC_HandleTypeDef *hfmac, int16_t *pOutput,
2106                                                                   uint16_t *pOutputSize)
2107 {
2108   /* Reset the current size */
2109   hfmac->OutputCurrentSize = 0U;
2110 
2111   /* Check whether a valid pointer was provided */
2112   if ((pOutput == NULL) || (pOutputSize == NULL) || (*pOutputSize == 0U))
2113   {
2114     /* The user will have to provide a valid configuration later */
2115     hfmac->pOutput = NULL;
2116     hfmac->pOutputSize = NULL;
2117     hfmac->RdState = HAL_FMAC_STATE_READY;
2118   }
2119   /* Handle the pointer depending on the input access */
2120   else if (hfmac->OutputAccess == FMAC_BUFFER_ACCESS_DMA)
2121   {
2122     hfmac->pOutput = NULL;
2123     hfmac->pOutputSize = NULL;
2124     hfmac->RdState = HAL_FMAC_STATE_BUSY_RD;
2125 
2126     /* Set the FMAC DMA transfer complete callback */
2127     hfmac->hdmaOut->XferHalfCpltCallback = FMAC_DMAHalfOutputDataReady;
2128     hfmac->hdmaOut->XferCpltCallback = FMAC_DMAOutputDataReady;
2129     /* Set the DMA error callback */
2130     hfmac->hdmaOut->XferErrorCallback = FMAC_DMAError;
2131 
2132     /* Enable the DMA stream managing FMAC output data read */
2133     return (HAL_DMA_Start_IT(hfmac->hdmaOut, (uint32_t)&hfmac->Instance->RDATA, (uint32_t)pOutput, *pOutputSize));
2134   }
2135   else if (hfmac->OutputAccess == FMAC_BUFFER_ACCESS_NONE)
2136   {
2137     hfmac->pOutput = NULL;
2138     hfmac->pOutputSize = NULL;
2139     hfmac->RdState = HAL_FMAC_STATE_READY;
2140   }
2141   else
2142   {
2143     /* Update the output data information (polling, IT) */
2144     hfmac->pOutput = pOutput;
2145     hfmac->pOutputSize = pOutputSize;
2146     hfmac->RdState = HAL_FMAC_STATE_BUSY_RD;
2147   }
2148 
2149   return HAL_OK;
2150 }
2151 
2152 /**
2153   * @brief  Read available output data until Y EMPTY is set.
2154   * @param  hfmac FMAC handle.
2155   * @param  MaxSizeToRead Maximum number of data to read (this serves as a timeout
2156   *         if FMAC continuously writes into the output buffer).
2157   * @retval None
2158   */
2159 static void FMAC_ReadDataIncrementPtr(FMAC_HandleTypeDef *hfmac, uint16_t MaxSizeToRead)
2160 {
2161   uint16_t maxsize;
2162   uint16_t threshold;
2163   uint32_t tmpvalue;
2164 
2165   /* Check if there is data to read */
2166   if (READ_BIT(hfmac->Instance->SR, FMAC_SR_YEMPTY) != 0U)
2167   {
2168     return;
2169   }
2170 
2171   /* Get the maximum index (no wait allowed, no overstepping of the output buffer) */
2172   if ((hfmac->OutputCurrentSize + MaxSizeToRead) > *(hfmac->pOutputSize))
2173   {
2174     maxsize = *(hfmac->pOutputSize);
2175   }
2176   else
2177   {
2178     maxsize = hfmac->OutputCurrentSize + MaxSizeToRead;
2179   }
2180 
2181   /* Read until there is no more room or no more data */
2182   do
2183   {
2184     /* If there is no more room, return */
2185     if (!(hfmac->OutputCurrentSize < maxsize))
2186     {
2187       return;
2188     }
2189 
2190     /* Read the available data */
2191     tmpvalue = ((READ_REG(hfmac->Instance->RDATA))& FMAC_RDATA_RDATA);
2192     *(hfmac->pOutput) = (int16_t)tmpvalue;
2193     hfmac->pOutput++;
2194     hfmac->OutputCurrentSize++;
2195   } while (READ_BIT(hfmac->Instance->SR, FMAC_SR_YEMPTY) == 0U);
2196 
2197   /* Y buffer empty flag has just be raised, read the threshold */
2198   threshold = (uint16_t)FMAC_GET_THRESHOLD_FROM_WM(FMAC_GET_Y_EMPTY_WM(hfmac)) - 1U;
2199 
2200   /* Update the maximum size if needed (limited data available) */
2201   if ((hfmac->OutputCurrentSize + threshold) < maxsize)
2202   {
2203     maxsize = hfmac->OutputCurrentSize + threshold;
2204   }
2205 
2206   /* Read the available data */
2207   while (hfmac->OutputCurrentSize < maxsize)
2208   {
2209     tmpvalue = ((READ_REG(hfmac->Instance->RDATA))& FMAC_RDATA_RDATA);
2210     *(hfmac->pOutput) = (int16_t)tmpvalue;
2211     hfmac->pOutput++;
2212     hfmac->OutputCurrentSize++;
2213   }
2214 }
2215 
2216 /**
2217   * @brief  Write available input data until X1 FULL is set.
2218   * @param  hfmac FMAC handle.
2219   * @param  MaxSizeToWrite Maximum number of data to write (this serves as a timeout
2220   *         if FMAC continuously empties the input buffer).
2221   * @retval None
2222   */
2223 static void FMAC_WriteDataIncrementPtr(FMAC_HandleTypeDef *hfmac, uint16_t MaxSizeToWrite)
2224 {
2225   uint16_t maxsize;
2226   uint16_t threshold;
2227 
2228   /* Check if there is room in FMAC */
2229   if (READ_BIT(hfmac->Instance->SR, FMAC_SR_X1FULL) != 0U)
2230   {
2231     return;
2232   }
2233 
2234   /* Get the maximum index (no wait allowed, no overstepping of the output buffer) */
2235   if ((hfmac->InputCurrentSize + MaxSizeToWrite) > *(hfmac->pInputSize))
2236   {
2237     maxsize = *(hfmac->pInputSize);
2238   }
2239   else
2240   {
2241     maxsize = hfmac->InputCurrentSize + MaxSizeToWrite;
2242   }
2243 
2244   /* Write until there is no more room or no more data */
2245   do
2246   {
2247     /* If there is no more room, return */
2248     if (!(hfmac->InputCurrentSize < maxsize))
2249     {
2250       return;
2251     }
2252 
2253     /* Write the available data */
2254     WRITE_REG(hfmac->Instance->WDATA, (((uint32_t)(*(hfmac->pInput))) & FMAC_WDATA_WDATA));
2255     hfmac->pInput++;
2256     hfmac->InputCurrentSize++;
2257   } while (READ_BIT(hfmac->Instance->SR, FMAC_SR_X1FULL) == 0U);
2258 
2259   /* X1 buffer full flag has just be raised, read the threshold */
2260   threshold = (uint16_t)FMAC_GET_THRESHOLD_FROM_WM(FMAC_GET_X1_FULL_WM(hfmac)) - 1U;
2261 
2262   /* Update the maximum size if needed (limited data available) */
2263   if ((hfmac->InputCurrentSize + threshold) < maxsize)
2264   {
2265     maxsize = hfmac->InputCurrentSize + threshold;
2266   }
2267 
2268   /* Write the available data */
2269   while (hfmac->InputCurrentSize < maxsize)
2270   {
2271     WRITE_REG(hfmac->Instance->WDATA, (((uint32_t)(*(hfmac->pInput))) & FMAC_WDATA_WDATA));
2272     hfmac->pInput++;
2273     hfmac->InputCurrentSize++;
2274   }
2275 }
2276 
2277 /**
2278   * @brief  DMA FMAC Input Data process half complete callback.
2279   * @param  hdma DMA handle.
2280   * @retval None
2281   */
2282 static void FMAC_DMAHalfGetData(DMA_HandleTypeDef *hdma)
2283 {
2284   FMAC_HandleTypeDef *hfmac = (FMAC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2285 
2286   /* Call half get data callback */
2287 #if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1)
2288   hfmac->HalfGetDataCallback(hfmac);
2289 #else
2290   HAL_FMAC_HalfGetDataCallback(hfmac);
2291 #endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */
2292 }
2293 
2294 /**
2295   * @brief  DMA FMAC Input Data process complete callback.
2296   * @param  hdma DMA handle.
2297   * @retval None
2298   */
2299 static void FMAC_DMAGetData(DMA_HandleTypeDef *hdma)
2300 {
2301   FMAC_HandleTypeDef *hfmac = (FMAC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2302 
2303   /* Reset the pointers to indicate new data will be needed */
2304   FMAC_ResetInputStateAndDataPointers(hfmac);
2305 
2306   /* Call get data callback */
2307 #if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1)
2308   hfmac->GetDataCallback(hfmac);
2309 #else
2310   HAL_FMAC_GetDataCallback(hfmac);
2311 #endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */
2312 }
2313 
2314 /**
2315   * @brief  DMA FMAC Output Data process half complete callback.
2316   * @param  hdma DMA handle.
2317   * @retval None
2318   */
2319 static void FMAC_DMAHalfOutputDataReady(DMA_HandleTypeDef *hdma)
2320 {
2321   FMAC_HandleTypeDef *hfmac = (FMAC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2322 
2323   /* Call half output data ready callback */
2324 #if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1)
2325   hfmac->HalfOutputDataReadyCallback(hfmac);
2326 #else
2327   HAL_FMAC_HalfOutputDataReadyCallback(hfmac);
2328 #endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */
2329 }
2330 
2331 /**
2332   * @brief  DMA FMAC Output Data process complete callback.
2333   * @param  hdma DMA handle.
2334   * @retval None
2335   */
2336 static void FMAC_DMAOutputDataReady(DMA_HandleTypeDef *hdma)
2337 {
2338   FMAC_HandleTypeDef *hfmac = (FMAC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2339 
2340   /* Reset the pointers to indicate new data will be needed */
2341   FMAC_ResetOutputStateAndDataPointers(hfmac);
2342 
2343   /* Call output data ready callback */
2344 #if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1)
2345   hfmac->OutputDataReadyCallback(hfmac);
2346 #else
2347   HAL_FMAC_OutputDataReadyCallback(hfmac);
2348 #endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */
2349 }
2350 
2351 /**
2352   * @brief  DMA FMAC Filter Configuration process complete callback.
2353   * @param  hdma DMA handle.
2354   * @retval None
2355   */
2356 static void FMAC_DMAFilterConfig(DMA_HandleTypeDef *hdma)
2357 {
2358   uint8_t index;
2359 
2360   FMAC_HandleTypeDef *hfmac = (FMAC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2361 
2362   /* If needed, write CoeffA and exit */
2363   if (hfmac->pInput != NULL)
2364   {
2365     /* Set the FMAC DMA transfer complete callback */
2366     hfmac->hdmaPreload->XferHalfCpltCallback = NULL;
2367     hfmac->hdmaPreload->XferCpltCallback = FMAC_DMAFilterConfig;
2368     /* Set the DMA error callback */
2369     hfmac->hdmaPreload->XferErrorCallback = FMAC_DMAError;
2370 
2371     /* Enable the DMA stream managing FMAC preload data write */
2372     if (HAL_DMA_Start_IT(hfmac->hdmaPreload, (uint32_t)hfmac->pInput, (uint32_t)&hfmac->Instance->WDATA,
2373                          hfmac->InputCurrentSize) == HAL_OK)
2374     {
2375       hfmac->pInput = NULL;
2376       hfmac->InputCurrentSize = 0U;
2377       return;
2378     }
2379 
2380     /* If not exited, there was an error: set FMAC handle state to error */
2381     hfmac->State = HAL_FMAC_STATE_ERROR;
2382   }
2383   else
2384   {
2385     /* Wait for the end of the writing */
2386     for (index = 0U; index < MAX_PRELOAD_INDEX; index++)
2387     {
2388       if (READ_BIT(hfmac->Instance->PARAM, FMAC_PARAM_START) == 0U)
2389       {
2390         break;
2391       }
2392     }
2393 
2394     /* If 'START' is still set, there was a timeout: set FMAC handle state to timeout */
2395     if (READ_BIT(hfmac->Instance->PARAM, FMAC_PARAM_START) != 0U)
2396     {
2397       hfmac->State = HAL_FMAC_STATE_TIMEOUT;
2398     }
2399     else
2400     {
2401       /* Change the FMAC state */
2402       hfmac->State = HAL_FMAC_STATE_READY;
2403 
2404       /* Call output data ready callback */
2405 #if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1)
2406       hfmac->FilterConfigCallback(hfmac);
2407 #else
2408       HAL_FMAC_FilterConfigCallback(hfmac);
2409 #endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */
2410       return;
2411     }
2412   }
2413 
2414   /* If not exited, there was an error: set FMAC handle error code to DMA error */
2415   hfmac->ErrorCode |= HAL_FMAC_ERROR_DMA;
2416 
2417   /* Call user callback */
2418 #if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1)
2419   hfmac->ErrorCallback(hfmac);
2420 #else
2421   HAL_FMAC_ErrorCallback(hfmac);
2422 #endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */
2423 
2424 }
2425 
2426 /**
2427   * @brief  DMA FMAC Filter Configuration process complete callback.
2428   * @param  hdma DMA handle.
2429   * @retval None
2430   */
2431 static void FMAC_DMAFilterPreload(DMA_HandleTypeDef *hdma)
2432 {
2433   uint8_t index;
2434 
2435   FMAC_HandleTypeDef *hfmac = (FMAC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2436 
2437   /* Wait for the end of the X1 writing */
2438   for (index = 0U; index < MAX_PRELOAD_INDEX; index++)
2439   {
2440     if (READ_BIT(hfmac->Instance->PARAM, FMAC_PARAM_START) == 0U)
2441     {
2442       break;
2443     }
2444   }
2445 
2446   /* If 'START' is still set, there was an error: set FMAC handle state to error */
2447   if (READ_BIT(hfmac->Instance->PARAM, FMAC_PARAM_START) != 0U)
2448   {
2449     hfmac->State = HAL_FMAC_STATE_TIMEOUT;
2450     hfmac->ErrorCode |= HAL_FMAC_ERROR_TIMEOUT;
2451   }
2452   /* If needed, preload Y buffer */
2453   else if ((hfmac->pInput != NULL) && (hfmac->InputCurrentSize != 0U))
2454   {
2455     /* Write number of values to be loaded, the data load function and start the operation */
2456     WRITE_REG(hfmac->Instance->PARAM, \
2457               (((uint32_t)(hfmac->InputCurrentSize) << FMAC_PARAM_P_Pos) | FMAC_FUNC_LOAD_Y | FMAC_PARAM_START));
2458 
2459     /* Set the FMAC DMA transfer complete callback */
2460     hfmac->hdmaPreload->XferHalfCpltCallback = NULL;
2461     hfmac->hdmaPreload->XferCpltCallback = FMAC_DMAFilterPreload;
2462     /* Set the DMA error callback */
2463     hfmac->hdmaPreload->XferErrorCallback = FMAC_DMAError;
2464 
2465     /* Enable the DMA stream managing FMAC preload data write */
2466     if (HAL_DMA_Start_IT(hfmac->hdmaPreload, (uint32_t)hfmac->pInput, (uint32_t)&hfmac->Instance->WDATA,
2467                          hfmac->InputCurrentSize) == HAL_OK)
2468     {
2469       hfmac->pInput = NULL;
2470       hfmac->InputCurrentSize = 0U;
2471       return;
2472     }
2473 
2474     /* If not exited, there was an error */
2475     hfmac->ErrorCode = HAL_FMAC_ERROR_DMA;
2476     hfmac->State = HAL_FMAC_STATE_ERROR;
2477   }
2478   else
2479   {
2480     /* nothing to do */
2481   }
2482 
2483   if (hfmac->ErrorCode == HAL_FMAC_ERROR_NONE)
2484   {
2485     /* Change the FMAC state */
2486     hfmac->State = HAL_FMAC_STATE_READY;
2487 
2488     /* Call output data ready callback */
2489 #if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1)
2490     hfmac->FilterPreloadCallback(hfmac);
2491 #else
2492     HAL_FMAC_FilterPreloadCallback(hfmac);
2493 #endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */
2494   }
2495   else
2496   {
2497     /* Call user callback */
2498 #if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1)
2499     hfmac->ErrorCallback(hfmac);
2500 #else
2501     HAL_FMAC_ErrorCallback(hfmac);
2502 #endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */
2503   }
2504 }
2505 
2506 
2507 /**
2508   * @brief  DMA FMAC communication error callback.
2509   * @param  hdma DMA handle.
2510   * @retval None
2511   */
2512 static void FMAC_DMAError(DMA_HandleTypeDef *hdma)
2513 {
2514   FMAC_HandleTypeDef *hfmac = (FMAC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2515 
2516   /* Set FMAC handle state to error */
2517   hfmac->State = HAL_FMAC_STATE_ERROR;
2518 
2519   /* Set FMAC handle error code to DMA error */
2520   hfmac->ErrorCode |= HAL_FMAC_ERROR_DMA;
2521 
2522   /* Call user callback */
2523 #if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1)
2524   hfmac->ErrorCallback(hfmac);
2525 #else
2526   HAL_FMAC_ErrorCallback(hfmac);
2527 #endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */
2528 }
2529 /**
2530   * @}
2531   */
2532 
2533 
2534 /**
2535   * @}
2536   */
2537 
2538 /**
2539   * @}
2540   */
2541 
2542 #endif /* HAL_FMAC_MODULE_ENABLED */
2543 #endif /* FMAC */