STM32H735xx HAL User Manual
stm32h7xx_hal_fmac.c
Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    stm32h7xx_hal_fmac.c
00004   * @author  MCD Application Team
00005   * @brief   FMAC HAL module driver.
00006   *          This file provides firmware functions to manage the following
00007   *          functionalities of the FMAC peripheral:
00008   *           + Initialization and de-initialization functions
00009   *           + Peripheral Control functions
00010   *           + Callback functions
00011   *           + IRQ handler management
00012   *           + Peripheral State and Error functions
00013   *
00014   ******************************************************************************
00015   * @attention
00016   *
00017   * Copyright (c) 2017 STMicroelectronics.
00018   * All rights reserved.
00019   *
00020   * This software is licensed under terms that can be found in the LICENSE file
00021   * in the root directory of this software component.
00022   * If no LICENSE file comes with this software, it is provided AS-IS.
00023   *
00024   ******************************************************************************
00025   *
00026   *  @verbatim
00027 ================================================================================
00028             ##### How to use this driver #####
00029 ================================================================================
00030     [..]
00031       The FMAC HAL driver can be used as follows:
00032 
00033       (#) Initialize the FMAC low level resources by implementing the HAL_FMAC_MspInit():
00034           (++) Enable the FMAC interface clock using __HAL_RCC_FMAC_CLK_ENABLE().
00035           (++) In case of using interrupts (e.g. access configured as FMAC_BUFFER_ACCESS_IT):
00036                (+++) Configure the FMAC interrupt priority using HAL_NVIC_SetPriority().
00037                (+++) Enable the FMAC IRQ handler using HAL_NVIC_EnableIRQ().
00038                (+++) In FMAC IRQ handler, call HAL_FMAC_IRQHandler().
00039           (++) In case of using DMA to control data transfer (e.g. access configured
00040                as FMAC_BUFFER_ACCESS_DMA):
00041                (+++) Enable the DMA interface clock using __HAL_RCC_DMA1_CLK_ENABLE()
00042                      or __HAL_RCC_DMA2_CLK_ENABLE() depending on the used DMA instance.
00043                (+++) Enable the DMAMUX1 interface clock using __HAL_RCC_DMAMUX1_CLK_ENABLE().
00044                (+++) If the initialization of the internal buffers (coefficients, input,
00045                      output) is done via DMA, configure and enable one DMA channel for
00046                      managing data transfer from memory to memory (preload channel).
00047                (+++) If the input buffer is accessed via DMA, configure and enable one
00048                      DMA channel for managing data transfer from memory to peripheral
00049                      (input channel).
00050                (+++) If the output buffer is accessed via DMA, configure and enable
00051                      one DMA channel for managing data transfer from peripheral to
00052                      memory (output channel).
00053                (+++) Associate the initialized DMA handle(s) to the FMAC DMA handle(s)
00054                      using __HAL_LINKDMA().
00055                (+++) Configure the priority and enable the NVIC for the transfer complete
00056                      interrupt on the enabled DMA channel(s) using HAL_NVIC_SetPriority()
00057                      and HAL_NVIC_EnableIRQ().
00058 
00059       (#) Initialize the FMAC HAL using HAL_FMAC_Init(). This function
00060           resorts to HAL_FMAC_MspInit() for low-level initialization.
00061 
00062       (#) Configure the FMAC processing (filter) using HAL_FMAC_FilterConfig()
00063           or HAL_FMAC_FilterConfig_DMA().
00064           This function:
00065           (++) Defines the memory area within the FMAC internal memory
00066                (input, coefficients, output) and the associated threshold (input, output).
00067           (++) Configures the filter and its parameters:
00068                (+++) Finite Impulse Response (FIR) filter (also known as convolution).
00069                (+++) Infinite Impulse Response (IIR) filter (direct form 1).
00070           (++) Choose the way to access to the input and output buffers: none, polling,
00071                DMA, IT. "none" means the input and/or output data will be handled by
00072                another IP (ADC, DAC, etc.).
00073           (++) Enable the error interruptions in the input access and/or the output
00074                access is done through IT/DMA. If an error occurs, the interruption
00075                will be triggered in loop. In order to recover, the user will have
00076                to reset the IP with the sequence HAL_FMAC_DeInit / HAL_FMAC_Init.
00077                Optionally, he can also disable the interrupt using __HAL_FMAC_DISABLE_IT;
00078                the error status will be kept, but no more interrupt will be triggered.
00079           (++) Write the provided coefficients into the internal memory using polling
00080                mode ( HAL_FMAC_FilterConfig() ) or DMA ( HAL_FMAC_FilterConfig_DMA() ).
00081                In the DMA case, HAL_FMAC_FilterConfigCallback() is called when
00082                the handling is over.
00083 
00084        (#) Optionally, the user can enable the error interruption related to
00085            saturation by calling __HAL_FMAC_ENABLE_IT. This helps in debugging the
00086            filter. If a saturation occurs, the interruption will be triggered in loop.
00087            In order to recover, the user will have to:
00088            (++) Disable the interruption by calling __HAL_FMAC_DISABLE_IT if
00089                 the user wishes to continue all the same.
00090            (++) Reset the IP with the sequence HAL_FMAC_DeInit / HAL_FMAC_Init.
00091 
00092        (#) Optionally, preload input (FIR, IIR) and output (IIR) data using
00093            HAL_FMAC_FilterPreload() or HAL_FMAC_FilterPreload_DMA().
00094            In the DMA case, HAL_FMAC_FilterPreloadCallback() is called when
00095            the handling is over.
00096            This step is optional as the filter can be started without preloaded
00097            data.
00098 
00099        (#) Start the FMAC processing (filter) using HAL_FMAC_FilterStart().
00100            This function also configures the output buffer that will be filled from
00101            the circular internal output buffer. The function returns immediately
00102            without updating the provided buffer. The IP processing will be active until
00103            HAL_FMAC_FilterStop() is called.
00104 
00105        (#) If the input internal buffer is accessed via DMA, HAL_FMAC_HalfGetDataCallback()
00106            will be called to indicate that half of the input buffer has been handled.
00107 
00108        (#) If the input internal buffer is accessed via DMA or interrupt, HAL_FMAC_GetDataCallback()
00109            will be called to require new input data. It will be provided through
00110            HAL_FMAC_AppendFilterData() if the DMA isn't in circular mode.
00111 
00112        (#) If the output internal buffer is accessed via DMA, HAL_FMAC_HalfOutputDataReadyCallback()
00113            will be called to indicate that half of the output buffer has been handled.
00114 
00115        (#) If the output internal buffer is accessed via DMA or interrupt,
00116            HAL_FMAC_OutputDataReadyCallback() will be called to require a new output
00117            buffer. It will be provided through HAL_FMAC_ConfigFilterOutputBuffer()
00118            if the DMA isn't in circular mode.
00119 
00120        (#) In all modes except none, provide new input data to be processed via HAL_FMAC_AppendFilterData().
00121            This function should only be called once the previous input data has been handled
00122            (the preloaded input data isn't concerned).
00123 
00124        (#) In all modes except none, provide a new output buffer to be filled via
00125            HAL_FMAC_ConfigFilterOutputBuffer(). This function should only be called once the previous
00126            user's output buffer has been filled.
00127 
00128        (#) In polling mode, handle the input and output data using HAL_FMAC_PollFilterData().
00129            This function:
00130            (++) Write the user's input data (provided via HAL_FMAC_AppendFilterData())
00131                 into the FMAC input memory area.
00132            (++) Read the FMAC output memory area and write it into the user's output buffer.
00133            It will return either when:
00134            (++) the user's output buffer is filled.
00135            (++) the user's input buffer has been handled.
00136            The unused data (unread input data or free output data) will not be saved.
00137            The user will have to use the updated input and output sizes to keep track
00138            of them.
00139 
00140        (#) Stop the FMAC processing (filter) using HAL_FMAC_FilterStop().
00141 
00142        (#) Call HAL_FMAC_DeInit() to de-initialize the FMAC peripheral. This function
00143            resorts to HAL_FMAC_MspDeInit() for low-level de-initialization.
00144 
00145   ##### Callback registration #####
00146   ==================================
00147 
00148     [..]
00149       The compilation define USE_HAL_FMAC_REGISTER_CALLBACKS when set to 1
00150       allows the user to configure dynamically the driver callbacks.
00151 
00152     [..]
00153       Use Function HAL_FMAC_RegisterCallback() to register a user callback.
00154       Function HAL_FMAC_RegisterCallback() allows to register following callbacks:
00155       (+) ErrorCallback               : Error Callback.
00156       (+) HalfGetDataCallback         : Get Half Data Callback.
00157       (+) GetDataCallback             : Get Data Callback.
00158       (+) HalfOutputDataReadyCallback : Half Output Data Ready Callback.
00159       (+) OutputDataReadyCallback     : Output Data Ready Callback.
00160       (+) FilterConfigCallback        : Filter Configuration Callback.
00161       (+) FilterPreloadCallback       : Filter Preload Callback.
00162       (+) MspInitCallback             : FMAC MspInit.
00163       (+) MspDeInitCallback           : FMAC MspDeInit.
00164       This function takes as parameters the HAL peripheral handle, the Callback ID
00165       and a pointer to the user callback function.
00166 
00167     [..]
00168       Use function HAL_FMAC_UnRegisterCallback() to reset a callback to the default
00169       weak (surcharged) function.
00170       HAL_FMAC_UnRegisterCallback() takes as parameters the HAL peripheral handle
00171       and the Callback ID.
00172       This function allows to reset following callbacks:
00173       (+) ErrorCallback               : Error Callback.
00174       (+) HalfGetDataCallback         : Get Half Data Callback.
00175       (+) GetDataCallback             : Get Data Callback.
00176       (+) HalfOutputDataReadyCallback : Half Output Data Ready Callback.
00177       (+) OutputDataReadyCallback     : Output Data Ready Callback.
00178       (+) FilterConfigCallback        : Filter Configuration Callback.
00179       (+) FilterPreloadCallback       : Filter Preload Callback.
00180       (+) MspInitCallback             : FMAC MspInit.
00181       (+) MspDeInitCallback           : FMAC MspDeInit.
00182 
00183     [..]
00184       By default, after the HAL_FMAC_Init() and when the state is HAL_FMAC_STATE_RESET
00185       all callbacks are set to the corresponding weak (surcharged) functions:
00186       examples GetDataCallback(), OutputDataReadyCallback().
00187       Exception done for MspInit and MspDeInit functions that are respectively
00188       reset to the legacy weak (surcharged) functions in the HAL_FMAC_Init()
00189       and HAL_FMAC_DeInit() only when these callbacks are null (not registered beforehand).
00190       If not, MspInit or MspDeInit are not null, the HAL_FMAC_Init() and HAL_FMAC_DeInit()
00191       keep and use the user MspInit/MspDeInit callbacks (registered beforehand).
00192 
00193     [..]
00194       Callbacks can be registered/unregistered in HAL_FMAC_STATE_READY state only.
00195       Exception done MspInit/MspDeInit that can be registered/unregistered
00196       in HAL_FMAC_STATE_READY or HAL_FMAC_STATE_RESET state, thus registered (user)
00197       MspInit/DeInit callbacks can be used during the Init/DeInit.
00198       In that case first register the MspInit/MspDeInit user callbacks
00199       using HAL_FMAC_RegisterCallback() before calling HAL_FMAC_DeInit()
00200       or HAL_FMAC_Init() function.
00201 
00202     [..]
00203       When the compilation define USE_HAL_FMAC_REGISTER_CALLBACKS is set to 0 or
00204       not defined, the callback registration feature is not available
00205       and weak (surcharged) callbacks are used.
00206 
00207 
00208   @endverbatim
00209   *
00210   */
00211 
00212 /* Includes ------------------------------------------------------------------*/
00213 #include "stm32h7xx_hal.h"
00214 
00215 #if defined(FMAC)
00216 #ifdef HAL_FMAC_MODULE_ENABLED
00217 
00218 /** @addtogroup STM32H7xx_HAL_Driver
00219   * @{
00220   */
00221 
00222 /** @defgroup FMAC FMAC
00223   * @brief    FMAC HAL driver module
00224   * @{
00225   */
00226 
00227 /* Private typedef -----------------------------------------------------------*/
00228 /* Private defines -----------------------------------------------------------*/
00229 /** @defgroup  FMAC_Private_Constants   FMAC Private Constants
00230   * @{
00231   */
00232 
00233 #define MAX_FILTER_DATA_SIZE_TO_HANDLE ((uint16_t) 0xFFU)
00234 #define MAX_PRELOAD_INDEX      0xFFU
00235 #define PRELOAD_ACCESS_DMA     0x00U
00236 #define PRELOAD_ACCESS_POLLING 0x01U
00237 #define POLLING_DISABLED       0U
00238 #define POLLING_ENABLED        1U
00239 #define POLLING_NOT_STOPPED    0U
00240 #define POLLING_STOPPED        1U
00241 /* FMAC polling-based communications time-out value */
00242 #define HAL_FMAC_TIMEOUT_VALUE         1000U
00243 /* FMAC reset time-out value */
00244 #define HAL_FMAC_RESET_TIMEOUT_VALUE   500U
00245 /* DMA Read Requests Enable */
00246 #define FMAC_DMA_REN                   FMAC_CR_DMAREN
00247 /* DMA Write Channel Enable */
00248 #define FMAC_DMA_WEN                   FMAC_CR_DMAWEN
00249 /* FMAC Execution Enable */
00250 #define FMAC_START                     FMAC_PARAM_START
00251 
00252 /**
00253   * @}
00254   */
00255 
00256 /* Private macros ------------------------------------------------------------*/
00257 /** @defgroup  FMAC_Private_Macros   FMAC Private Macros
00258   * @{
00259   */
00260 
00261 /**
00262   * @brief  Get the X1 memory area size.
00263   * @param  __HANDLE__ FMAC handle.
00264   * @retval X1_BUF_SIZE
00265   */
00266 #define FMAC_GET_X1_SIZE(__HANDLE__) \
00267   ((((__HANDLE__)->Instance->X1BUFCFG) & (FMAC_X1BUFCFG_X1_BUF_SIZE)) >> (FMAC_X1BUFCFG_X1_BUF_SIZE_Pos))
00268 
00269 /**
00270   * @brief  Get the X1 watermark.
00271   * @param  __HANDLE__ FMAC handle.
00272   * @retval FULL_WM
00273   */
00274 #define FMAC_GET_X1_FULL_WM(__HANDLE__) \
00275   (((__HANDLE__)->Instance->X1BUFCFG) & (FMAC_X1BUFCFG_FULL_WM))
00276 
00277 /**
00278   * @brief  Get the X2 memory area size.
00279   * @param  __HANDLE__ FMAC handle.
00280   * @retval X2_BUF_SIZE
00281   */
00282 #define FMAC_GET_X2_SIZE(__HANDLE__) \
00283   ((((__HANDLE__)->Instance->X2BUFCFG) & (FMAC_X2BUFCFG_X2_BUF_SIZE)) >> (FMAC_X2BUFCFG_X2_BUF_SIZE_Pos))
00284 
00285 /**
00286   * @brief  Get the Y memory area size.
00287   * @param  __HANDLE__ FMAC handle.
00288   * @retval Y_BUF_SIZE
00289   */
00290 #define FMAC_GET_Y_SIZE(__HANDLE__) \
00291   ((((__HANDLE__)->Instance->YBUFCFG) & (FMAC_YBUFCFG_Y_BUF_SIZE)) >> (FMAC_YBUFCFG_Y_BUF_SIZE_Pos))
00292 
00293 /**
00294   * @brief  Get the Y watermark.
00295   * @param  __HANDLE__ FMAC handle.
00296   * @retval EMPTY_WM
00297   */
00298 #define FMAC_GET_Y_EMPTY_WM(__HANDLE__) \
00299   (((__HANDLE__)->Instance->YBUFCFG) & (FMAC_YBUFCFG_EMPTY_WM))
00300 
00301 /**
00302   * @brief  Get the start bit state.
00303   * @param  __HANDLE__ FMAC handle.
00304   * @retval START
00305   */
00306 #define FMAC_GET_START_BIT(__HANDLE__) \
00307   ((((__HANDLE__)->Instance->PARAM) & (FMAC_PARAM_START)) >> (FMAC_PARAM_START_Pos))
00308 
00309 /**
00310   * @brief  Get the threshold matching the watermark.
00311   * @param  __WM__ Watermark value.
00312   * @retval THRESHOLD
00313   */
00314 #define FMAC_GET_THRESHOLD_FROM_WM(__WM__) (((__WM__) == FMAC_THRESHOLD_1)? 1U: \
00315                                             ((__WM__) == FMAC_THRESHOLD_2)? 2U: \
00316                                             ((__WM__) == FMAC_THRESHOLD_4)? 4U:8U)
00317 
00318 /**
00319   * @}
00320   */
00321 
00322 /* Private variables ---------------------------------------------------------*/
00323 /* Global variables ----------------------------------------------------------*/
00324 /* Private function prototypes -----------------------------------------------*/
00325 
00326 static HAL_StatusTypeDef FMAC_Reset(FMAC_HandleTypeDef *hfmac);
00327 static void FMAC_ResetDataPointers(FMAC_HandleTypeDef *hfmac);
00328 static void FMAC_ResetOutputStateAndDataPointers(FMAC_HandleTypeDef *hfmac);
00329 static void FMAC_ResetInputStateAndDataPointers(FMAC_HandleTypeDef *hfmac);
00330 static HAL_StatusTypeDef FMAC_FilterConfig(FMAC_HandleTypeDef *hfmac, FMAC_FilterConfigTypeDef *pConfig,
00331                                            uint8_t PreloadAccess);
00332 static HAL_StatusTypeDef FMAC_FilterPreload(FMAC_HandleTypeDef *hfmac, int16_t *pInput, uint8_t InputSize,
00333                                             int16_t *pOutput, uint8_t OutputSize, uint8_t PreloadAccess);
00334 static void FMAC_WritePreloadDataIncrementPtr(FMAC_HandleTypeDef *hfmac, int16_t **ppData, uint8_t Size);
00335 static HAL_StatusTypeDef FMAC_WaitOnStartUntilTimeout(FMAC_HandleTypeDef *hfmac, uint32_t Tickstart, uint32_t Timeout);
00336 static HAL_StatusTypeDef FMAC_AppendFilterDataUpdateState(FMAC_HandleTypeDef *hfmac, int16_t *pInput,
00337                                                           uint16_t *pInputSize);
00338 static HAL_StatusTypeDef FMAC_ConfigFilterOutputBufferUpdateState(FMAC_HandleTypeDef *hfmac, int16_t *pOutput,
00339                                                                   uint16_t *pOutputSize);
00340 static void FMAC_WriteDataIncrementPtr(FMAC_HandleTypeDef *hfmac, uint16_t MaxSizeToWrite);
00341 static void FMAC_ReadDataIncrementPtr(FMAC_HandleTypeDef *hfmac, uint16_t MaxSizeToRead);
00342 static void FMAC_DMAHalfGetData(DMA_HandleTypeDef *hdma);
00343 static void FMAC_DMAGetData(DMA_HandleTypeDef *hdma);
00344 static void FMAC_DMAHalfOutputDataReady(DMA_HandleTypeDef *hdma);
00345 static void FMAC_DMAOutputDataReady(DMA_HandleTypeDef *hdma);
00346 static void FMAC_DMAFilterConfig(DMA_HandleTypeDef *hdma);
00347 static void FMAC_DMAFilterPreload(DMA_HandleTypeDef *hdma);
00348 static void FMAC_DMAError(DMA_HandleTypeDef *hdma);
00349 
00350 /* Functions Definition ------------------------------------------------------*/
00351 
00352 /** @defgroup FMAC_Exported_Functions FMAC Exported Functions
00353   * @{
00354   */
00355 
00356 /** @defgroup FMAC_Exported_Functions_Group1 Initialization and de-initialization functions
00357   * @brief    Initialization and Configuration functions
00358   *
00359 @verbatim
00360  ===============================================================================
00361      #####       Initialization and de-initialization functions       #####
00362  ===============================================================================
00363     [..] This section provides functions allowing to:
00364       (+) Initialize the FMAC peripheral and the associated handle
00365       (+) DeInitialize the FMAC peripheral
00366       (+) Initialize the FMAC MSP (MCU Specific Package)
00367       (+) De-Initialize the FMAC MSP
00368       (+) Register a User FMAC Callback
00369       (+) Unregister a FMAC CallBack
00370 
00371     [..]
00372 
00373 @endverbatim
00374   * @{
00375   */
00376 
00377 /**
00378   * @brief  Initialize the FMAC peripheral and the associated handle.
00379   * @param  hfmac pointer to a FMAC_HandleTypeDef structure.
00380   * @retval HAL_StatusTypeDef HAL status
00381   */
00382 HAL_StatusTypeDef HAL_FMAC_Init(FMAC_HandleTypeDef *hfmac)
00383 {
00384   HAL_StatusTypeDef status;
00385 
00386   /* Check the FMAC handle allocation */
00387   if (hfmac == NULL)
00388   {
00389     return HAL_ERROR;
00390   }
00391 
00392   /* Check the instance */
00393   assert_param(IS_FMAC_ALL_INSTANCE(hfmac->Instance));
00394 
00395   if (hfmac->State == HAL_FMAC_STATE_RESET)
00396   {
00397     /* Initialize lock resource */
00398     hfmac->Lock = HAL_UNLOCKED;
00399 
00400 #if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1)
00401     /* Register the default callback functions */
00402     hfmac->ErrorCallback = HAL_FMAC_ErrorCallback;
00403     hfmac->HalfGetDataCallback = HAL_FMAC_HalfGetDataCallback;
00404     hfmac->GetDataCallback = HAL_FMAC_GetDataCallback;
00405     hfmac->HalfOutputDataReadyCallback = HAL_FMAC_HalfOutputDataReadyCallback;
00406     hfmac->OutputDataReadyCallback = HAL_FMAC_OutputDataReadyCallback;
00407     hfmac->FilterConfigCallback = HAL_FMAC_FilterConfigCallback;
00408     hfmac->FilterPreloadCallback = HAL_FMAC_FilterPreloadCallback;
00409 
00410     if (hfmac->MspInitCallback == NULL)
00411     {
00412       hfmac->MspInitCallback = HAL_FMAC_MspInit;
00413     }
00414 
00415     /* Init the low level hardware */
00416     hfmac->MspInitCallback(hfmac);
00417 #else
00418     /* Init the low level hardware */
00419     HAL_FMAC_MspInit(hfmac);
00420 #endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */
00421   }
00422 
00423   /* Reset pInput and pOutput */
00424   hfmac->FilterParam = 0U;
00425   FMAC_ResetDataPointers(hfmac);
00426 
00427   /* Reset FMAC unit (internal pointers) */
00428   if (FMAC_Reset(hfmac) == HAL_ERROR)
00429   {
00430     /* Update FMAC error code and FMAC peripheral state */
00431     hfmac->ErrorCode |= HAL_FMAC_ERROR_RESET;
00432     hfmac->State = HAL_FMAC_STATE_TIMEOUT;
00433 
00434     status = HAL_ERROR;
00435   }
00436   else
00437   {
00438     /* Update FMAC error code and FMAC peripheral state */
00439     hfmac->ErrorCode = HAL_FMAC_ERROR_NONE;
00440     hfmac->State = HAL_FMAC_STATE_READY;
00441 
00442     status = HAL_OK;
00443   }
00444 
00445   __HAL_UNLOCK(hfmac);
00446 
00447   return status;
00448 }
00449 
00450 /**
00451   * @brief  De-initialize the FMAC peripheral.
00452   * @param  hfmac pointer to a FMAC structure.
00453   * @retval HAL_StatusTypeDef HAL status
00454   */
00455 HAL_StatusTypeDef HAL_FMAC_DeInit(FMAC_HandleTypeDef *hfmac)
00456 {
00457   /* Check the FMAC handle allocation */
00458   if (hfmac == NULL)
00459   {
00460     return HAL_ERROR;
00461   }
00462 
00463   /* Check the parameters */
00464   assert_param(IS_FMAC_ALL_INSTANCE(hfmac->Instance));
00465 
00466   /* Change FMAC peripheral state */
00467   hfmac->State = HAL_FMAC_STATE_BUSY;
00468 
00469   /* Set FMAC error code to none */
00470   hfmac->ErrorCode = HAL_FMAC_ERROR_NONE;
00471 
00472   /* Reset pInput and pOutput */
00473   hfmac->FilterParam = 0U;
00474   FMAC_ResetDataPointers(hfmac);
00475 
00476 #if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1)
00477   if (hfmac->MspDeInitCallback == NULL)
00478   {
00479     hfmac->MspDeInitCallback = HAL_FMAC_MspDeInit;
00480   }
00481   /* DeInit the low level hardware */
00482   hfmac->MspDeInitCallback(hfmac);
00483 #else
00484   /* DeInit the low level hardware: CLOCK, NVIC, DMA */
00485   HAL_FMAC_MspDeInit(hfmac);
00486 #endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */
00487 
00488   /* Change FMAC peripheral state */
00489   hfmac->State = HAL_FMAC_STATE_RESET;
00490 
00491   /* Always release Lock in case of de-initialization */
00492   __HAL_UNLOCK(hfmac);
00493 
00494   return HAL_OK;
00495 }
00496 
00497 /**
00498   * @brief  Initialize the FMAC MSP.
00499   * @param  hfmac FMAC handle.
00500   * @retval None
00501   */
00502 __weak void HAL_FMAC_MspInit(FMAC_HandleTypeDef *hfmac)
00503 {
00504   /* Prevent unused argument(s) compilation warning */
00505   UNUSED(hfmac);
00506 
00507   /* NOTE : This function should not be modified, when the callback is needed,
00508             the HAL_FMAC_MspInit can be implemented in the user file
00509    */
00510 }
00511 
00512 /**
00513   * @brief  De-initialize the FMAC MSP.
00514   * @param  hfmac FMAC handle.
00515   * @retval None
00516   */
00517 __weak void HAL_FMAC_MspDeInit(FMAC_HandleTypeDef *hfmac)
00518 {
00519   /* Prevent unused argument(s) compilation warning */
00520   UNUSED(hfmac);
00521 
00522   /* NOTE : This function should not be modified, when the callback is needed,
00523             the HAL_FMAC_MspDeInit can be implemented in the user file
00524    */
00525 }
00526 
00527 #if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1)
00528 /**
00529   * @brief  Register a User FMAC Callback.
00530   * @note   The User FMAC Callback is to be used instead of the weak predefined callback.
00531   * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
00532   *         the configuration information for FMAC module.
00533   * @param  CallbackID ID of the callback to be registered.
00534   *         This parameter can be one of the following values:
00535   *           @arg @ref HAL_FMAC_ERROR_CB_ID Error Callback ID
00536   *           @arg @ref HAL_FMAC_HALF_GET_DATA_CB_ID Get Half Data Callback ID
00537   *           @arg @ref HAL_FMAC_GET_DATA_CB_ID Get Data Callback ID
00538   *           @arg @ref HAL_FMAC_HALF_OUTPUT_DATA_READY_CB_ID Half Output Data Ready Callback ID
00539   *           @arg @ref HAL_FMAC_OUTPUT_DATA_READY_CB_ID Output Data Ready Callback ID
00540   *           @arg @ref HAL_FMAC_FILTER_CONFIG_CB_ID Filter Configuration Callback ID
00541   *           @arg @ref HAL_FMAC_FILTER_PRELOAD_CB_ID Filter Preload Callback ID
00542   *           @arg @ref HAL_FMAC_MSPINIT_CB_ID FMAC MspInit ID
00543   *           @arg @ref HAL_FMAC_MSPDEINIT_CB_ID FMAC MspDeInit ID
00544   * @param  pCallback pointer to the Callback function.
00545   * @retval HAL_StatusTypeDef HAL status
00546   */
00547 HAL_StatusTypeDef HAL_FMAC_RegisterCallback(FMAC_HandleTypeDef *hfmac, HAL_FMAC_CallbackIDTypeDef CallbackID,
00548                                             pFMAC_CallbackTypeDef pCallback)
00549 {
00550   HAL_StatusTypeDef status = HAL_OK;
00551 
00552   /* Check the FMAC handle allocation */
00553   if (hfmac == NULL)
00554   {
00555     return HAL_ERROR;
00556   }
00557 
00558   if (pCallback == NULL)
00559   {
00560     /* Update the error code */
00561     hfmac->ErrorCode |= HAL_FMAC_ERROR_INVALID_CALLBACK;
00562 
00563     return HAL_ERROR;
00564   }
00565   __HAL_LOCK(hfmac);
00566 
00567   if (hfmac->State == HAL_FMAC_STATE_READY)
00568   {
00569     switch (CallbackID)
00570     {
00571       case HAL_FMAC_ERROR_CB_ID :
00572         hfmac->ErrorCallback = pCallback;
00573         break;
00574 
00575       case HAL_FMAC_HALF_GET_DATA_CB_ID :
00576         hfmac->HalfGetDataCallback = pCallback;
00577         break;
00578 
00579       case HAL_FMAC_GET_DATA_CB_ID :
00580         hfmac->GetDataCallback = pCallback;
00581         break;
00582 
00583       case HAL_FMAC_HALF_OUTPUT_DATA_READY_CB_ID :
00584         hfmac->HalfOutputDataReadyCallback = pCallback;
00585         break;
00586 
00587       case HAL_FMAC_OUTPUT_DATA_READY_CB_ID :
00588         hfmac->OutputDataReadyCallback = pCallback;
00589         break;
00590 
00591       case HAL_FMAC_FILTER_CONFIG_CB_ID :
00592         hfmac->FilterConfigCallback = pCallback;
00593         break;
00594 
00595       case HAL_FMAC_FILTER_PRELOAD_CB_ID :
00596         hfmac->FilterPreloadCallback = pCallback;
00597         break;
00598 
00599       case HAL_FMAC_MSPINIT_CB_ID :
00600         hfmac->MspInitCallback = pCallback;
00601         break;
00602 
00603       case HAL_FMAC_MSPDEINIT_CB_ID :
00604         hfmac->MspDeInitCallback = pCallback;
00605         break;
00606 
00607       default :
00608         /* Update the error code */
00609         hfmac->ErrorCode |= HAL_FMAC_ERROR_INVALID_CALLBACK;
00610 
00611         /* Return error status */
00612         status =  HAL_ERROR;
00613         break;
00614     }
00615   }
00616   else if (hfmac->State == HAL_FMAC_STATE_RESET)
00617   {
00618     switch (CallbackID)
00619     {
00620       case HAL_FMAC_MSPINIT_CB_ID :
00621         hfmac->MspInitCallback = pCallback;
00622         break;
00623 
00624       case HAL_FMAC_MSPDEINIT_CB_ID :
00625         hfmac->MspDeInitCallback = pCallback;
00626         break;
00627 
00628       default :
00629         /* Update the error code */
00630         hfmac->ErrorCode |= HAL_FMAC_ERROR_INVALID_CALLBACK;
00631 
00632         /* Return error status */
00633         status =  HAL_ERROR;
00634         break;
00635     }
00636   }
00637   else
00638   {
00639     /* Update the error code */
00640     hfmac->ErrorCode |= HAL_FMAC_ERROR_INVALID_CALLBACK;
00641 
00642     /* Return error status */
00643     status =  HAL_ERROR;
00644   }
00645 
00646   __HAL_UNLOCK(hfmac);
00647 
00648   return status;
00649 }
00650 
00651 /**
00652   * @brief  Unregister a FMAC CallBack.
00653   * @note   The FMAC callback is redirected to the weak predefined callback.
00654   * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
00655   *         the configuration information for FMAC module
00656   * @param  CallbackID ID of the callback to be unregistered.
00657   *         This parameter can be one of the following values:
00658   *           @arg @ref HAL_FMAC_ERROR_CB_ID Error Callback ID
00659   *           @arg @ref HAL_FMAC_HALF_GET_DATA_CB_ID Get Half Data Callback ID
00660   *           @arg @ref HAL_FMAC_GET_DATA_CB_ID Get Data Callback ID
00661   *           @arg @ref HAL_FMAC_HALF_OUTPUT_DATA_READY_CB_ID Half Output Data Ready Callback ID
00662   *           @arg @ref HAL_FMAC_OUTPUT_DATA_READY_CB_ID Output Data Ready Callback ID
00663   *           @arg @ref HAL_FMAC_FILTER_CONFIG_CB_ID Filter Configuration Callback ID
00664   *           @arg @ref HAL_FMAC_FILTER_PRELOAD_CB_ID Filter Preload Callback ID
00665   *           @arg @ref HAL_FMAC_MSPINIT_CB_ID FMAC MspInit ID
00666   *           @arg @ref HAL_FMAC_MSPDEINIT_CB_ID FMAC MspDeInit ID
00667   * @retval HAL_StatusTypeDef HAL status
00668   */
00669 HAL_StatusTypeDef HAL_FMAC_UnRegisterCallback(FMAC_HandleTypeDef *hfmac, HAL_FMAC_CallbackIDTypeDef CallbackID)
00670 {
00671   HAL_StatusTypeDef status = HAL_OK;
00672 
00673   /* Check the FMAC handle allocation */
00674   if (hfmac == NULL)
00675   {
00676     return HAL_ERROR;
00677   }
00678 
00679   __HAL_LOCK(hfmac);
00680 
00681   if (hfmac->State == HAL_FMAC_STATE_READY)
00682   {
00683     switch (CallbackID)
00684     {
00685       case HAL_FMAC_ERROR_CB_ID :
00686         hfmac->ErrorCallback = HAL_FMAC_ErrorCallback;                             /* Legacy weak ErrorCallback       */
00687         break;
00688 
00689       case HAL_FMAC_HALF_GET_DATA_CB_ID :
00690         hfmac->HalfGetDataCallback = HAL_FMAC_HalfGetDataCallback;                 /* Legacy weak HalfGetDataCallback */
00691         break;
00692 
00693       case HAL_FMAC_GET_DATA_CB_ID :
00694         hfmac->GetDataCallback = HAL_FMAC_GetDataCallback;                         /* Legacy weak GetDataCallback     */
00695         break;
00696 
00697       case HAL_FMAC_HALF_OUTPUT_DATA_READY_CB_ID :
00698         hfmac->HalfOutputDataReadyCallback = HAL_FMAC_HalfOutputDataReadyCallback; /* Legacy weak
00699                                                                                       HalfOutputDataReadyCallback     */
00700         break;
00701 
00702       case HAL_FMAC_OUTPUT_DATA_READY_CB_ID :
00703         hfmac->OutputDataReadyCallback = HAL_FMAC_OutputDataReadyCallback;         /* Legacy weak
00704                                                                                       OutputDataReadyCallback         */
00705         break;
00706 
00707       case HAL_FMAC_FILTER_CONFIG_CB_ID :
00708         hfmac->FilterConfigCallback = HAL_FMAC_FilterConfigCallback;               /* Legacy weak
00709                                                                                       FilterConfigCallback            */
00710         break;
00711 
00712       case HAL_FMAC_FILTER_PRELOAD_CB_ID :
00713         hfmac->FilterPreloadCallback = HAL_FMAC_FilterPreloadCallback;             /* Legacy weak FilterPreloadCallba */
00714         break;
00715 
00716       case HAL_FMAC_MSPINIT_CB_ID :
00717         hfmac->MspInitCallback = HAL_FMAC_MspInit;                                 /* Legacy weak MspInitCallback     */
00718         break;
00719 
00720       case HAL_FMAC_MSPDEINIT_CB_ID :
00721         hfmac->MspDeInitCallback = HAL_FMAC_MspDeInit;                             /* Legacy weak MspDeInitCallback   */
00722         break;
00723 
00724       default :
00725         /* Update the error code */
00726         hfmac->ErrorCode |= HAL_FMAC_ERROR_INVALID_CALLBACK;
00727 
00728         /* Return error status */
00729         status =  HAL_ERROR;
00730         break;
00731     }
00732   }
00733   else if (hfmac->State == HAL_FMAC_STATE_RESET)
00734   {
00735     switch (CallbackID)
00736     {
00737       case HAL_FMAC_MSPINIT_CB_ID :
00738         hfmac->MspInitCallback = HAL_FMAC_MspInit;
00739         break;
00740 
00741       case HAL_FMAC_MSPDEINIT_CB_ID :
00742         hfmac->MspDeInitCallback = HAL_FMAC_MspDeInit;
00743         break;
00744 
00745       default :
00746         /* Update the error code */
00747         hfmac->ErrorCode |= HAL_FMAC_ERROR_INVALID_CALLBACK;
00748 
00749         /* Return error status */
00750         status =  HAL_ERROR;
00751         break;
00752     }
00753   }
00754   else
00755   {
00756     /* Update the error code */
00757     hfmac->ErrorCode |= HAL_FMAC_ERROR_INVALID_CALLBACK;
00758 
00759     /* Return error status */
00760     status = HAL_ERROR;
00761   }
00762 
00763   __HAL_UNLOCK(hfmac);
00764 
00765   return status;
00766 }
00767 #endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */
00768 
00769 /**
00770   * @}
00771   */
00772 
00773 /** @defgroup FMAC_Exported_Functions_Group2 Peripheral Control functions
00774   * @brief    Control functions.
00775   *
00776 @verbatim
00777   ==============================================================================
00778                       ##### Peripheral Control functions #####
00779   ==============================================================================
00780     [..]  This section provides functions allowing to:
00781       (+) Configure the FMAC peripheral: memory area, filter type and parameters,
00782           way to access to the input and output memory area (none, polling, IT, DMA).
00783       (+) Start the FMAC processing (filter).
00784       (+) Handle the input data that will be provided into FMAC.
00785       (+) Handle the output data provided by FMAC.
00786       (+) Stop the FMAC processing (filter).
00787 
00788 @endverbatim
00789   * @{
00790   */
00791 
00792 /**
00793   * @brief  Configure the FMAC filter.
00794   * @note   The configuration is done according to the parameters
00795   *         specified in the FMAC_FilterConfigTypeDef structure.
00796   *         The provided data will be loaded using polling mode.
00797   * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
00798   *         the configuration information for FMAC module.
00799   * @param  pConfig pointer to a FMAC_FilterConfigTypeDef structure that
00800   *         contains the FMAC configuration information.
00801   * @retval HAL_StatusTypeDef HAL status
00802   */
00803 HAL_StatusTypeDef HAL_FMAC_FilterConfig(FMAC_HandleTypeDef *hfmac, FMAC_FilterConfigTypeDef *pConfig)
00804 {
00805   return (FMAC_FilterConfig(hfmac, pConfig, PRELOAD_ACCESS_POLLING));
00806 }
00807 
00808 /**
00809   * @brief  Configure the FMAC filter.
00810   * @note   The configuration is done according to the parameters
00811   *         specified in the FMAC_FilterConfigTypeDef structure.
00812   *         The provided data will be loaded using DMA.
00813   * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
00814   *         the configuration information for FMAC module.
00815   * @param  pConfig pointer to a FMAC_FilterConfigTypeDef structure that
00816   *         contains the FMAC configuration information.
00817   * @retval HAL_StatusTypeDef HAL status
00818   */
00819 HAL_StatusTypeDef HAL_FMAC_FilterConfig_DMA(FMAC_HandleTypeDef *hfmac, FMAC_FilterConfigTypeDef *pConfig)
00820 {
00821   return (FMAC_FilterConfig(hfmac, pConfig, PRELOAD_ACCESS_DMA));
00822 }
00823 
00824 /**
00825   * @brief  Preload the input (FIR, IIR) and output data (IIR) of the FMAC filter.
00826   * @note   The set(s) of data will be used by FMAC as soon as @ref HAL_FMAC_FilterStart is called.
00827   *         The provided data will be loaded using polling mode.
00828   * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
00829   *         the configuration information for FMAC module.
00830   * @param  pInput Preloading of the first elements of the input buffer (X1).
00831   *         If not needed (no data available when starting), it should be set to NULL.
00832   * @param  InputSize Size of the input vector.
00833   *         As pInput is used for preloading data, it cannot be bigger than the input memory area.
00834   * @param  pOutput [IIR] Preloading of the first elements of the output vector (Y).
00835   *         If not needed, it should be set to NULL.
00836   * @param  OutputSize Size of the output vector.
00837   *         As pOutput is used for preloading data, it cannot be bigger than the output memory area.
00838   * @note   The input and the output buffers can be filled by calling several times @ref HAL_FMAC_FilterPreload
00839   *         (each call filling partly the buffers). In case of overflow (too much data provided through
00840   *         all these calls), an error will be returned.
00841   * @retval HAL_StatusTypeDef HAL status
00842   */
00843 HAL_StatusTypeDef HAL_FMAC_FilterPreload(FMAC_HandleTypeDef *hfmac, int16_t *pInput, uint8_t InputSize,
00844                                          int16_t *pOutput, uint8_t OutputSize)
00845 {
00846   return (FMAC_FilterPreload(hfmac, pInput, InputSize, pOutput, OutputSize, PRELOAD_ACCESS_POLLING));
00847 }
00848 
00849 /**
00850   * @brief  Preload the input (FIR, IIR) and output data (IIR) of the FMAC filter.
00851   * @note   The set(s) of data will be used by FMAC as soon as @ref HAL_FMAC_FilterStart is called.
00852   *         The provided data will be loaded using DMA.
00853   * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
00854   *         the configuration information for FMAC module.
00855   * @param  pInput Preloading of the first elements of the input buffer (X1).
00856   *         If not needed (no data available when starting), it should be set to NULL.
00857   * @param  InputSize Size of the input vector.
00858   *         As pInput is used for preloading data, it cannot be bigger than the input memory area.
00859   * @param  pOutput [IIR] Preloading of the first elements of the output vector (Y).
00860   *         If not needed, it should be set to NULL.
00861   * @param  OutputSize Size of the output vector.
00862   *         As pOutput is used for preloading data, it cannot be bigger than the output memory area.
00863   * @note   The input and the output buffers can be filled by calling several times @ref HAL_FMAC_FilterPreload
00864   *         (each call filling partly the buffers). In case of overflow (too much data provided through
00865   *         all these calls), an error will be returned.
00866   * @retval HAL_StatusTypeDef HAL status
00867   */
00868 HAL_StatusTypeDef HAL_FMAC_FilterPreload_DMA(FMAC_HandleTypeDef *hfmac, int16_t *pInput, uint8_t InputSize,
00869                                              int16_t *pOutput, uint8_t OutputSize)
00870 {
00871   return (FMAC_FilterPreload(hfmac, pInput, InputSize, pOutput, OutputSize, PRELOAD_ACCESS_DMA));
00872 }
00873 
00874 
00875 /**
00876   * @brief  Start the FMAC processing according to the existing FMAC configuration.
00877   * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
00878   *         the configuration information for FMAC module.
00879   * @param  pOutput pointer to buffer where output data of FMAC processing will be stored
00880   *         in the next steps.
00881   *         If it is set to NULL, the output will not be read and it will be up to
00882   *         an external IP to empty the output buffer.
00883   * @param  pOutputSize pointer to the size of the output buffer. The number of read data will be written here.
00884   * @retval HAL_StatusTypeDef HAL status
00885   */
00886 HAL_StatusTypeDef HAL_FMAC_FilterStart(FMAC_HandleTypeDef *hfmac, int16_t *pOutput, uint16_t *pOutputSize)
00887 {
00888   uint32_t tmpcr = 0U;
00889   HAL_StatusTypeDef status;
00890 
00891   /* Check the START bit state */
00892   if (FMAC_GET_START_BIT(hfmac) != 0U)
00893   {
00894     return HAL_ERROR;
00895   }
00896 
00897   /* Check that a valid configuration was done previously */
00898   if (hfmac->FilterParam == 0U)
00899   {
00900     return HAL_ERROR;
00901   }
00902 
00903   /* Check handle state is ready */
00904   if (hfmac->State == HAL_FMAC_STATE_READY)
00905   {
00906     /* Change the FMAC state */
00907     hfmac->State = HAL_FMAC_STATE_BUSY;
00908 
00909     /* CR: Configure the input access (error interruptions enabled only for IT or DMA) */
00910     if (hfmac->InputAccess == FMAC_BUFFER_ACCESS_DMA)
00911     {
00912       tmpcr |= FMAC_DMA_WEN;
00913     }
00914     else if (hfmac->InputAccess == FMAC_BUFFER_ACCESS_IT)
00915     {
00916       tmpcr |= FMAC_IT_WIEN;
00917     }
00918     else
00919     {
00920       /* nothing to do */
00921     }
00922 
00923     /* CR: Configure the output access (error interruptions enabled only for IT or DMA) */
00924     if (hfmac->OutputAccess == FMAC_BUFFER_ACCESS_DMA)
00925     {
00926       tmpcr |= FMAC_DMA_REN;
00927     }
00928     else if (hfmac->OutputAccess == FMAC_BUFFER_ACCESS_IT)
00929     {
00930       tmpcr |= FMAC_IT_RIEN;
00931     }
00932     else
00933     {
00934       /* nothing to do */
00935     }
00936 
00937     /* CR: Write the configuration */
00938     MODIFY_REG(hfmac->Instance->CR, \
00939                FMAC_IT_RIEN | FMAC_IT_WIEN | FMAC_DMA_REN | FMAC_CR_DMAWEN, \
00940                tmpcr);
00941 
00942     /* Register the new output buffer */
00943     status = FMAC_ConfigFilterOutputBufferUpdateState(hfmac, pOutput, pOutputSize);
00944 
00945     if (status == HAL_OK)
00946     {
00947       /* PARAM: Start the filter ( this can generate interrupts before the end of the HAL_FMAC_FilterStart ) */
00948       WRITE_REG(hfmac->Instance->PARAM, (uint32_t)(hfmac->FilterParam));
00949     }
00950 
00951     /* Reset the busy flag (do not overwrite the possible write and read flag) */
00952     hfmac->State = HAL_FMAC_STATE_READY;
00953   }
00954   else
00955   {
00956     status = HAL_ERROR;
00957   }
00958 
00959   return status;
00960 }
00961 
00962 /**
00963   * @brief  Provide a new input buffer that will be loaded into the FMAC input memory area.
00964   * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
00965   *         the configuration information for FMAC module.
00966   * @param  pInput New input vector (additional input data).
00967   * @param  pInputSize Size of the input vector (if all the data can't be
00968   *         written, it will be updated with the number of data read from FMAC).
00969   * @retval HAL_StatusTypeDef HAL status
00970   */
00971 HAL_StatusTypeDef HAL_FMAC_AppendFilterData(FMAC_HandleTypeDef *hfmac, int16_t *pInput, uint16_t *pInputSize)
00972 {
00973   HAL_StatusTypeDef status;
00974 
00975   /* Check the function parameters */
00976   if ((pInput == NULL) || (pInputSize == NULL))
00977   {
00978     return HAL_ERROR;
00979   }
00980   if (*pInputSize == 0U)
00981   {
00982     return HAL_ERROR;
00983   }
00984 
00985   /* Check the START bit state */
00986   if (FMAC_GET_START_BIT(hfmac) == 0U)
00987   {
00988     return HAL_ERROR;
00989   }
00990 
00991   /* Check the FMAC configuration */
00992   if (hfmac->InputAccess == FMAC_BUFFER_ACCESS_NONE)
00993   {
00994     return HAL_ERROR;
00995   }
00996 
00997   /* Check whether the previous input vector has been handled */
00998   if ((hfmac->pInputSize != NULL) && (hfmac->InputCurrentSize < * (hfmac->pInputSize)))
00999   {
01000     return HAL_ERROR;
01001   }
01002 
01003   /* Check that FMAC was initialized and that no writing is already ongoing */
01004   if (hfmac->WrState == HAL_FMAC_STATE_READY)
01005   {
01006     /* Register the new input buffer */
01007     status = FMAC_AppendFilterDataUpdateState(hfmac, pInput, pInputSize);
01008   }
01009   else
01010   {
01011     status = HAL_ERROR;
01012   }
01013 
01014   return status;
01015 }
01016 
01017 /**
01018   * @brief  Provide a new output buffer to be filled with the data computed by FMAC unit.
01019   * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
01020   *         the configuration information for FMAC module.
01021   * @param  pOutput New output vector.
01022   * @param  pOutputSize Size of the output vector (if the vector can't
01023   *         be entirely filled, pOutputSize will be updated with the number
01024   *         of data read from FMAC).
01025   * @retval HAL_StatusTypeDef HAL status
01026   */
01027 HAL_StatusTypeDef HAL_FMAC_ConfigFilterOutputBuffer(FMAC_HandleTypeDef *hfmac, int16_t *pOutput, uint16_t *pOutputSize)
01028 {
01029   HAL_StatusTypeDef status;
01030 
01031   /* Check the function parameters */
01032   if ((pOutput == NULL) || (pOutputSize == NULL))
01033   {
01034     return HAL_ERROR;
01035   }
01036   if (*pOutputSize == 0U)
01037   {
01038     return HAL_ERROR;
01039   }
01040 
01041   /* Check the START bit state */
01042   if (FMAC_GET_START_BIT(hfmac) == 0U)
01043   {
01044     return HAL_ERROR;
01045   }
01046 
01047   /* Check the FMAC configuration */
01048   if (hfmac->OutputAccess == FMAC_BUFFER_ACCESS_NONE)
01049   {
01050     return HAL_ERROR;
01051   }
01052 
01053   /* Check whether the previous output vector has been handled */
01054   if ((hfmac->pOutputSize != NULL) && (hfmac->OutputCurrentSize < * (hfmac->pOutputSize)))
01055   {
01056     return HAL_ERROR;
01057   }
01058 
01059   /* Check that FMAC was initialized and that not reading is already ongoing */
01060   if (hfmac->RdState == HAL_FMAC_STATE_READY)
01061   {
01062     /* Register the new output buffer */
01063     status = FMAC_ConfigFilterOutputBufferUpdateState(hfmac, pOutput, pOutputSize);
01064   }
01065   else
01066   {
01067     status = HAL_ERROR;
01068   }
01069 
01070   return status;
01071 }
01072 
01073 /**
01074   * @brief  Handle the input and/or output data in polling mode
01075   * @note   This function writes the previously provided user's input data and
01076   *         fills the previously provided user's output buffer,
01077   *         according to the existing FMAC configuration (polling mode only).
01078   *         The function returns when the input data has been handled or
01079   *         when the output data is filled. The possible unused data isn't
01080   *         kept. It will be up to the user to handle it. The previously
01081   *         provided pInputSize and pOutputSize will be used to indicate to the
01082   *         size of the read/written data to the user.
01083   * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
01084   *         the configuration information for FMAC module.
01085   * @param  Timeout timeout value.
01086   * @retval HAL_StatusTypeDef HAL status
01087   */
01088 HAL_StatusTypeDef HAL_FMAC_PollFilterData(FMAC_HandleTypeDef *hfmac, uint32_t Timeout)
01089 {
01090   uint32_t tickstart;
01091   uint8_t inpolling;
01092   uint8_t inpollingover = POLLING_NOT_STOPPED;
01093   uint8_t outpolling;
01094   uint8_t outpollingover = POLLING_NOT_STOPPED;
01095   HAL_StatusTypeDef status;
01096 
01097   /* Check the START bit state */
01098   if (FMAC_GET_START_BIT(hfmac) == 0U)
01099   {
01100     return HAL_ERROR;
01101   }
01102 
01103   /* Check the configuration */
01104 
01105   /* Get the input and output mode (if no buffer was previously provided, nothing will be read/written) */
01106   if ((hfmac->InputAccess  == FMAC_BUFFER_ACCESS_POLLING) && (hfmac->pInput  != NULL))
01107   {
01108     inpolling = POLLING_ENABLED;
01109   }
01110   else
01111   {
01112     inpolling = POLLING_DISABLED;
01113   }
01114   if ((hfmac->OutputAccess == FMAC_BUFFER_ACCESS_POLLING) && (hfmac->pOutput != NULL))
01115   {
01116     outpolling = POLLING_ENABLED;
01117   }
01118   else
01119   {
01120     outpolling = POLLING_DISABLED;
01121   }
01122 
01123   /* Check the configuration */
01124   if ((inpolling == POLLING_DISABLED) && (outpolling == POLLING_DISABLED))
01125   {
01126     return HAL_ERROR;
01127   }
01128 
01129   /* Check handle state is ready */
01130   if (hfmac->State == HAL_FMAC_STATE_READY)
01131   {
01132     /* Change the FMAC state */
01133     hfmac->State = HAL_FMAC_STATE_BUSY;
01134 
01135     /* Get tick */
01136     tickstart = HAL_GetTick();
01137 
01138     /* Loop on reading and writing until timeout */
01139     while ((HAL_GetTick() - tickstart) < Timeout)
01140     {
01141       /* X1: Check the mode: polling or none */
01142       if (inpolling != POLLING_DISABLED)
01143       {
01144         FMAC_WriteDataIncrementPtr(hfmac, MAX_FILTER_DATA_SIZE_TO_HANDLE);
01145         if (hfmac->InputCurrentSize == *(hfmac->pInputSize))
01146         {
01147           inpollingover = POLLING_STOPPED;
01148         }
01149       }
01150 
01151       /* Y: Check the mode: polling or none */
01152       if (outpolling != POLLING_DISABLED)
01153       {
01154         FMAC_ReadDataIncrementPtr(hfmac, MAX_FILTER_DATA_SIZE_TO_HANDLE);
01155         if (hfmac->OutputCurrentSize == *(hfmac->pOutputSize))
01156         {
01157           outpollingover = POLLING_STOPPED;
01158         }
01159       }
01160 
01161       /* Exit if there isn't data to handle anymore on one side or another */
01162       if ((inpollingover != POLLING_NOT_STOPPED) || (outpollingover != POLLING_NOT_STOPPED))
01163       {
01164         break;
01165       }
01166     }
01167 
01168     /* Change the FMAC state; update the input and output sizes; reset the indexes */
01169     if (inpolling != POLLING_DISABLED)
01170     {
01171       (*(hfmac->pInputSize))  = hfmac->InputCurrentSize;
01172       FMAC_ResetInputStateAndDataPointers(hfmac);
01173     }
01174     if (outpolling != POLLING_DISABLED)
01175     {
01176       (*(hfmac->pOutputSize)) = hfmac->OutputCurrentSize;
01177       FMAC_ResetOutputStateAndDataPointers(hfmac);
01178     }
01179 
01180     /* Reset the busy flag (do not overwrite the possible write and read flag) */
01181     hfmac->State = HAL_FMAC_STATE_READY;
01182 
01183     if ((HAL_GetTick() - tickstart) >= Timeout)
01184     {
01185       hfmac->ErrorCode |= HAL_FMAC_ERROR_TIMEOUT;
01186       status = HAL_ERROR;
01187     }
01188     else
01189     {
01190       status = HAL_OK;
01191     }
01192   }
01193   else
01194   {
01195     status = HAL_ERROR;
01196   }
01197 
01198   return status;
01199 }
01200 
01201 /**
01202   * @brief  Stop the FMAC processing.
01203   * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
01204   *         the configuration information for FMAC module.
01205   * @retval HAL_StatusTypeDef HAL status
01206   */
01207 HAL_StatusTypeDef HAL_FMAC_FilterStop(FMAC_HandleTypeDef *hfmac)
01208 {
01209   HAL_StatusTypeDef status;
01210 
01211   /* Check handle state is ready */
01212   if (hfmac->State == HAL_FMAC_STATE_READY)
01213   {
01214     /* Change the FMAC state */
01215     hfmac->State = HAL_FMAC_STATE_BUSY;
01216 
01217     /* Set the START bit to 0 (stop the previously configured filter) */
01218     CLEAR_BIT(hfmac->Instance->PARAM, FMAC_PARAM_START);
01219 
01220     /* Disable the interrupts in order to avoid crossing cases */
01221     CLEAR_BIT(hfmac->Instance->CR, FMAC_DMA_REN | FMAC_DMA_WEN | FMAC_IT_RIEN | FMAC_IT_WIEN);
01222 
01223     /* In case of IT, update the sizes */
01224     if ((hfmac->InputAccess == FMAC_BUFFER_ACCESS_IT) && (hfmac->pInput != NULL))
01225     {
01226       (*(hfmac->pInputSize))  = hfmac->InputCurrentSize;
01227     }
01228     if ((hfmac->OutputAccess == FMAC_BUFFER_ACCESS_IT) && (hfmac->pOutput != NULL))
01229     {
01230       (*(hfmac->pOutputSize)) = hfmac->OutputCurrentSize;
01231     }
01232 
01233     /* Reset FMAC unit (internal pointers) */
01234     if (FMAC_Reset(hfmac) == HAL_ERROR)
01235     {
01236       /* Update FMAC error code and FMAC peripheral state */
01237       hfmac->ErrorCode = HAL_FMAC_ERROR_RESET;
01238       hfmac->State = HAL_FMAC_STATE_TIMEOUT;
01239       status = HAL_ERROR;
01240     }
01241     else
01242     {
01243       /* Reset the data pointers */
01244       FMAC_ResetDataPointers(hfmac);
01245 
01246       status = HAL_OK;
01247     }
01248 
01249     /* Reset the busy flag */
01250     hfmac->State = HAL_FMAC_STATE_READY;
01251   }
01252   else
01253   {
01254     status = HAL_ERROR;
01255   }
01256 
01257   return status;
01258 }
01259 
01260 /**
01261   * @}
01262   */
01263 
01264 /** @defgroup FMAC_Exported_Functions_Group3 Callback functions
01265   * @brief    Callback functions.
01266   *
01267 @verbatim
01268   ==============================================================================
01269                       ##### Callback functions  #####
01270   ==============================================================================
01271     [..]  This section provides Interruption and DMA callback functions:
01272       (+) DMA or Interrupt: the user's input data is half written (DMA only)
01273           or completely written.
01274       (+) DMA or Interrupt: the user's output buffer is half filled (DMA only)
01275           or completely filled.
01276       (+) DMA or Interrupt: error handling.
01277 
01278 @endverbatim
01279   * @{
01280   */
01281 
01282 /**
01283   * @brief  FMAC error callback.
01284   * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
01285   *         the configuration information for FMAC module.
01286   * @retval None
01287   */
01288 __weak void HAL_FMAC_ErrorCallback(FMAC_HandleTypeDef *hfmac)
01289 {
01290   /* Prevent unused argument(s) compilation warning */
01291   UNUSED(hfmac);
01292 
01293   /* NOTE : This function should not be modified; when the callback is needed,
01294             the HAL_FMAC_ErrorCallback can be implemented in the user file.
01295    */
01296 }
01297 
01298 /**
01299   * @brief  FMAC get half data callback.
01300   * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
01301   *         the configuration information for FMAC module.
01302   * @retval None
01303   */
01304 __weak void HAL_FMAC_HalfGetDataCallback(FMAC_HandleTypeDef *hfmac)
01305 {
01306   /* Prevent unused argument(s) compilation warning */
01307   UNUSED(hfmac);
01308 
01309   /* NOTE : This function should not be modified; when the callback is needed,
01310             the HAL_FMAC_HalfGetDataCallback can be implemented in the user file.
01311    */
01312 }
01313 
01314 /**
01315   * @brief  FMAC get data callback.
01316   * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
01317   *         the configuration information for FMAC module.
01318   * @retval None
01319   */
01320 __weak void HAL_FMAC_GetDataCallback(FMAC_HandleTypeDef *hfmac)
01321 {
01322   /* Prevent unused argument(s) compilation warning */
01323   UNUSED(hfmac);
01324 
01325   /* NOTE : This function should not be modified; when the callback is needed,
01326             the HAL_FMAC_GetDataCallback can be implemented in the user file.
01327    */
01328 }
01329 
01330 /**
01331   * @brief  FMAC half output data ready callback.
01332   * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
01333   *         the configuration information for FMAC module.
01334   * @retval None
01335   */
01336 __weak void HAL_FMAC_HalfOutputDataReadyCallback(FMAC_HandleTypeDef *hfmac)
01337 {
01338   /* Prevent unused argument(s) compilation warning */
01339   UNUSED(hfmac);
01340 
01341   /* NOTE : This function should not be modified; when the callback is needed,
01342             the HAL_FMAC_HalfOutputDataReadyCallback can be implemented in the user file.
01343    */
01344 }
01345 
01346 /**
01347   * @brief  FMAC output data ready callback.
01348   * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
01349   *         the configuration information for FMAC module.
01350   * @retval None
01351   */
01352 __weak void HAL_FMAC_OutputDataReadyCallback(FMAC_HandleTypeDef *hfmac)
01353 {
01354   /* Prevent unused argument(s) compilation warning */
01355   UNUSED(hfmac);
01356 
01357   /* NOTE : This function should not be modified; when the callback is needed,
01358             the HAL_FMAC_OutputDataReadyCallback can be implemented in the user file.
01359    */
01360 }
01361 
01362 /**
01363   * @brief  FMAC filter configuration callback.
01364   * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
01365   *         the configuration information for FMAC module.
01366   * @retval None
01367   */
01368 __weak void HAL_FMAC_FilterConfigCallback(FMAC_HandleTypeDef *hfmac)
01369 {
01370   /* Prevent unused argument(s) compilation warning */
01371   UNUSED(hfmac);
01372 
01373   /* NOTE : This function should not be modified; when the callback is needed,
01374             the HAL_FMAC_FilterConfigCallback can be implemented in the user file.
01375    */
01376 }
01377 
01378 /**
01379   * @brief  FMAC filter preload callback.
01380   * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
01381   *         the configuration information for FMAC module.
01382   * @retval None
01383   */
01384 __weak void HAL_FMAC_FilterPreloadCallback(FMAC_HandleTypeDef *hfmac)
01385 {
01386   /* Prevent unused argument(s) compilation warning */
01387   UNUSED(hfmac);
01388 
01389   /* NOTE : This function should not be modified; when the callback is needed,
01390             the HAL_FMAC_FilterPreloadCallback can be implemented in the user file.
01391    */
01392 }
01393 
01394 /**
01395   * @}
01396   */
01397 
01398 /** @defgroup FMAC_Exported_Functions_Group4 IRQ handler management
01399   * @brief    IRQ handler.
01400   *
01401 @verbatim
01402   ==============================================================================
01403                 ##### IRQ handler management #####
01404   ==============================================================================
01405 [..]  This section provides IRQ handler function.
01406 
01407 @endverbatim
01408   * @{
01409   */
01410 
01411 /**
01412   * @brief  Handle FMAC interrupt request.
01413   * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
01414   *         the configuration information for FMAC module.
01415   * @retval None
01416   */
01417 void HAL_FMAC_IRQHandler(FMAC_HandleTypeDef *hfmac)
01418 {
01419   uint32_t itsource;
01420 
01421   /* Check if the read interrupt is enabled and if Y buffer empty flag isn't set */
01422   itsource = __HAL_FMAC_GET_IT_SOURCE(hfmac, FMAC_IT_RIEN);
01423   if ((__HAL_FMAC_GET_FLAG(hfmac, FMAC_FLAG_YEMPTY) == 0U) && (itsource != 0U))
01424   {
01425     /* Read some data if possible (Y size is used as a pseudo timeout in order
01426        to not get stuck too long under IT if FMAC keeps on processing input
01427        data reloaded via DMA for instance). */
01428     if (hfmac->pOutput != NULL)
01429     {
01430       FMAC_ReadDataIncrementPtr(hfmac, (uint16_t)FMAC_GET_Y_SIZE(hfmac));
01431     }
01432 
01433     /* Indicate that data is ready to be read */
01434     if ((hfmac->pOutput == NULL) || (hfmac->OutputCurrentSize == *(hfmac->pOutputSize)))
01435     {
01436       /* Reset the pointers to indicate new data will be needed */
01437       FMAC_ResetOutputStateAndDataPointers(hfmac);
01438 
01439       /* Call the output data ready callback */
01440 #if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1)
01441       hfmac->OutputDataReadyCallback(hfmac);
01442 #else
01443       HAL_FMAC_OutputDataReadyCallback(hfmac);
01444 #endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */
01445     }
01446   }
01447 
01448   /* Check if the write interrupt is enabled and if X1 buffer full flag isn't set */
01449   itsource = __HAL_FMAC_GET_IT_SOURCE(hfmac, FMAC_IT_WIEN);
01450   if ((__HAL_FMAC_GET_FLAG(hfmac, FMAC_FLAG_X1FULL) == 0U) && (itsource != 0U))
01451   {
01452     /* Write some data if possible (X1 size is used as a pseudo timeout in order
01453        to not get stuck too long under IT if FMAC keep on processing input
01454        data whereas its output emptied via DMA for instance). */
01455     if (hfmac->pInput != NULL)
01456     {
01457       FMAC_WriteDataIncrementPtr(hfmac, (uint16_t)FMAC_GET_X1_SIZE(hfmac));
01458     }
01459 
01460     /* Indicate that new data will be needed */
01461     if ((hfmac->pInput == NULL) || (hfmac->InputCurrentSize == *(hfmac->pInputSize)))
01462     {
01463       /* Reset the pointers to indicate new data will be needed */
01464       FMAC_ResetInputStateAndDataPointers(hfmac);
01465 
01466       /* Call the get data callback */
01467 #if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1)
01468       hfmac->GetDataCallback(hfmac);
01469 #else
01470       HAL_FMAC_GetDataCallback(hfmac);
01471 #endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */
01472     }
01473   }
01474 
01475   /* Check if the overflow error interrupt is enabled and if overflow error flag is raised */
01476   itsource = __HAL_FMAC_GET_IT_SOURCE(hfmac, FMAC_IT_OVFLIEN);
01477   if ((__HAL_FMAC_GET_FLAG(hfmac, FMAC_FLAG_OVFL) != 0U) && (itsource != 0U))
01478   {
01479     hfmac->ErrorCode |= HAL_FMAC_ERROR_OVFL;
01480   }
01481 
01482   /* Check if the underflow error interrupt is enabled and if underflow error flag is raised */
01483   itsource = __HAL_FMAC_GET_IT_SOURCE(hfmac, FMAC_IT_UNFLIEN);
01484   if ((__HAL_FMAC_GET_FLAG(hfmac, FMAC_FLAG_UNFL) != 0U) && (itsource != 0U))
01485   {
01486     hfmac->ErrorCode |= HAL_FMAC_ERROR_UNFL;
01487   }
01488 
01489   /* Check if the saturation error interrupt is enabled and if saturation error flag is raised */
01490   itsource = __HAL_FMAC_GET_IT_SOURCE(hfmac, FMAC_IT_SATIEN);
01491   if ((__HAL_FMAC_GET_FLAG(hfmac, FMAC_FLAG_SAT) != 0U) && (itsource != 0U))
01492   {
01493     hfmac->ErrorCode |= HAL_FMAC_ERROR_SAT;
01494   }
01495 
01496   /* Call the error callback if an error occurred */
01497   if (hfmac->ErrorCode != HAL_FMAC_ERROR_NONE)
01498   {
01499     /* Call the error callback */
01500 #if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1)
01501     hfmac->ErrorCallback(hfmac);
01502 #else
01503     HAL_FMAC_ErrorCallback(hfmac);
01504 #endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */
01505   }
01506 }
01507 
01508 /**
01509   * @}
01510   */
01511 
01512 /** @defgroup FMAC_Exported_Functions_Group5 Peripheral State and Error functions
01513   * @brief    Peripheral State and Error functions.
01514   *
01515 @verbatim
01516   ==============================================================================
01517                  ##### Peripheral State and Error functions #####
01518   ==============================================================================
01519     [..]  This subsection provides functions allowing to
01520       (+) Check the FMAC state
01521       (+) Get error code
01522 
01523 @endverbatim
01524   * @{
01525   */
01526 
01527 /**
01528   * @brief  Return the FMAC state.
01529   * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
01530   *         the configuration information for FMAC module.
01531   * @retval HAL_FMAC_StateTypeDef FMAC state
01532   */
01533 HAL_FMAC_StateTypeDef HAL_FMAC_GetState(FMAC_HandleTypeDef *hfmac)
01534 {
01535   /* Return FMAC state */
01536   return hfmac->State;
01537 }
01538 
01539 /**
01540   * @brief  Return the FMAC peripheral error.
01541   * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
01542   *         the configuration information for FMAC module.
01543   * @note   The returned error is a bit-map combination of possible errors.
01544   * @retval uint32_t Error bit-map based on @ref FMAC_Error_Code
01545   */
01546 uint32_t HAL_FMAC_GetError(FMAC_HandleTypeDef *hfmac)
01547 {
01548   /* Return FMAC error code */
01549   return hfmac->ErrorCode;
01550 }
01551 
01552 /**
01553   * @}
01554   */
01555 
01556 /**
01557   * @}
01558   */
01559 
01560 /** @defgroup FMAC_Private_Functions FMAC Private Functions
01561   * @{
01562   */
01563 
01564 /**
01565   ==============================================================================
01566                        ##### FMAC Private Functions #####
01567   ==============================================================================
01568   */
01569 /**
01570   * @brief  Perform a reset of the FMAC unit.
01571   * @param  hfmac FMAC handle.
01572   * @retval HAL_StatusTypeDef HAL status
01573   */
01574 static HAL_StatusTypeDef FMAC_Reset(FMAC_HandleTypeDef *hfmac)
01575 {
01576   uint32_t tickstart;
01577 
01578   /* Init tickstart for timeout management*/
01579   tickstart = HAL_GetTick();
01580 
01581   /* Perform the reset */
01582   SET_BIT(hfmac->Instance->CR, FMAC_CR_RESET);
01583 
01584   /* Wait until flag is reset */
01585   while (READ_BIT(hfmac->Instance->CR, FMAC_CR_RESET) != 0U)
01586   {
01587     if ((HAL_GetTick() - tickstart) > HAL_FMAC_RESET_TIMEOUT_VALUE)
01588     {
01589       hfmac->ErrorCode |= HAL_FMAC_ERROR_TIMEOUT;
01590       return HAL_ERROR;
01591     }
01592   }
01593 
01594   hfmac->ErrorCode = HAL_FMAC_ERROR_NONE;
01595   return HAL_OK;
01596 }
01597 
01598 /**
01599   * @brief  Reset the data pointers of the FMAC unit.
01600   * @param  hfmac FMAC handle.
01601   * @retval None
01602   */
01603 static void FMAC_ResetDataPointers(FMAC_HandleTypeDef *hfmac)
01604 {
01605   FMAC_ResetInputStateAndDataPointers(hfmac);
01606   FMAC_ResetOutputStateAndDataPointers(hfmac);
01607 }
01608 
01609 /**
01610   * @brief  Reset the input data pointers of the FMAC unit.
01611   * @param  hfmac FMAC handle.
01612   * @retval None
01613   */
01614 static void FMAC_ResetInputStateAndDataPointers(FMAC_HandleTypeDef *hfmac)
01615 {
01616   hfmac->pInput = NULL;
01617   hfmac->pInputSize = NULL;
01618   hfmac->InputCurrentSize = 0U;
01619   hfmac->WrState = HAL_FMAC_STATE_READY;
01620 }
01621 
01622 /**
01623   * @brief  Reset the output data pointers of the FMAC unit.
01624   * @param  hfmac FMAC handle.
01625   * @retval None
01626   */
01627 static void FMAC_ResetOutputStateAndDataPointers(FMAC_HandleTypeDef *hfmac)
01628 {
01629   hfmac->pOutput = NULL;
01630   hfmac->pOutputSize = NULL;
01631   hfmac->OutputCurrentSize = 0U;
01632   hfmac->RdState = HAL_FMAC_STATE_READY;
01633 }
01634 
01635 /**
01636   * @brief  Configure the FMAC filter.
01637   * @note   The configuration is done according to the parameters
01638   *         specified in the FMAC_FilterConfigTypeDef structure.
01639   * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
01640   *         the configuration information for FMAC module.
01641   * @param  pConfig pointer to a FMAC_FilterConfigTypeDef structure that
01642   *         contains the FMAC configuration information.
01643   * @param  PreloadAccess access mode used for the preload (polling or DMA).
01644   * @retval HAL_StatusTypeDef HAL status
01645   */
01646 static HAL_StatusTypeDef FMAC_FilterConfig(FMAC_HandleTypeDef *hfmac, FMAC_FilterConfigTypeDef *pConfig,
01647                                            uint8_t PreloadAccess)
01648 {
01649   uint32_t tickstart;
01650   uint32_t tmpcr;
01651 #if defined(USE_FULL_ASSERT)
01652   uint32_t x2size;
01653 #endif /* USE_FULL_ASSERT */
01654 
01655   /* Check the parameters */
01656   assert_param(IS_FMAC_THRESHOLD(pConfig->InputThreshold));
01657   assert_param(IS_FMAC_THRESHOLD(pConfig->OutputThreshold));
01658   assert_param(IS_FMAC_BUFFER_ACCESS(pConfig->InputAccess));
01659   assert_param(IS_FMAC_BUFFER_ACCESS(pConfig->OutputAccess));
01660   assert_param(IS_FMAC_CLIP_STATE(pConfig->Clip));
01661   assert_param(IS_FMAC_FILTER_FUNCTION(pConfig->Filter));
01662   assert_param(IS_FMAC_PARAM_P(pConfig->Filter, pConfig->P));
01663   assert_param(IS_FMAC_PARAM_Q(pConfig->Filter, pConfig->Q));
01664   assert_param(IS_FMAC_PARAM_R(pConfig->Filter, pConfig->R));
01665 
01666   /* Check the START bit state */
01667   if (FMAC_GET_START_BIT(hfmac) != 0U)
01668   {
01669     return HAL_ERROR;
01670   }
01671 
01672   /* Check handle state is ready */
01673   if (hfmac->State != HAL_FMAC_STATE_READY)
01674   {
01675     return HAL_ERROR;
01676   }
01677 
01678   /* Change the FMAC state */
01679   hfmac->State = HAL_FMAC_STATE_BUSY;
01680 
01681   /* Get tick */
01682   tickstart = HAL_GetTick();
01683 
01684   /* Indicate that there is no valid configuration done */
01685   hfmac->FilterParam = 0U;
01686 
01687   /* FMAC_X1BUFCFG: Configure the input buffer within the internal memory if required */
01688   if (pConfig->InputBufferSize != 0U)
01689   {
01690     MODIFY_REG(hfmac->Instance->X1BUFCFG,                                                                   \
01691                (FMAC_X1BUFCFG_X1_BASE | FMAC_X1BUFCFG_X1_BUF_SIZE),                                         \
01692                (((((uint32_t)(pConfig->InputBaseAddress)) << FMAC_X1BUFCFG_X1_BASE_Pos)     & FMAC_X1BUFCFG_X1_BASE) | \
01693                 ((((uint32_t)(pConfig->InputBufferSize))  << FMAC_X1BUFCFG_X1_BUF_SIZE_Pos) & \
01694                  FMAC_X1BUFCFG_X1_BUF_SIZE)));
01695   }
01696 
01697   /* FMAC_X1BUFCFG: Configure the input threshold if valid when compared to the configured X1 size */
01698   if (pConfig->InputThreshold != FMAC_THRESHOLD_NO_VALUE)
01699   {
01700     /* Check the parameter */
01701     assert_param(IS_FMAC_THRESHOLD_APPLICABLE(FMAC_GET_X1_SIZE(hfmac), pConfig->InputThreshold, pConfig->InputAccess));
01702 
01703     MODIFY_REG(hfmac->Instance->X1BUFCFG, \
01704                FMAC_X1BUFCFG_FULL_WM,     \
01705                ((pConfig->InputThreshold) & FMAC_X1BUFCFG_FULL_WM));
01706   }
01707 
01708   /* FMAC_X2BUFCFG: Configure the coefficient buffer within the internal memory */
01709   if (pConfig->CoeffBufferSize != 0U)
01710   {
01711     MODIFY_REG(hfmac->Instance->X2BUFCFG,                                                                   \
01712                (FMAC_X2BUFCFG_X2_BASE | FMAC_X2BUFCFG_X2_BUF_SIZE),                                         \
01713                (((((uint32_t)(pConfig->CoeffBaseAddress)) << FMAC_X2BUFCFG_X2_BASE_Pos)     & FMAC_X2BUFCFG_X2_BASE) | \
01714                 ((((uint32_t)(pConfig->CoeffBufferSize))  << FMAC_X2BUFCFG_X2_BUF_SIZE_Pos) &\
01715                  FMAC_X2BUFCFG_X2_BUF_SIZE)));
01716   }
01717 
01718   /* FMAC_YBUFCFG: Configure the output buffer within the internal memory if required */
01719   if (pConfig->OutputBufferSize != 0U)
01720   {
01721     MODIFY_REG(hfmac->Instance->YBUFCFG,                                                                    \
01722                (FMAC_YBUFCFG_Y_BASE | FMAC_YBUFCFG_Y_BUF_SIZE),                                             \
01723                (((((uint32_t)(pConfig->OutputBaseAddress)) << FMAC_YBUFCFG_Y_BASE_Pos)     & FMAC_YBUFCFG_Y_BASE) |    \
01724                 ((((uint32_t)(pConfig->OutputBufferSize))  << FMAC_YBUFCFG_Y_BUF_SIZE_Pos) & FMAC_YBUFCFG_Y_BUF_SIZE)));
01725   }
01726 
01727   /* FMAC_YBUFCFG: Configure the output threshold if valid when compared to the configured Y size */
01728   if (pConfig->OutputThreshold != FMAC_THRESHOLD_NO_VALUE)
01729   {
01730     /* Check the parameter */
01731     assert_param(IS_FMAC_THRESHOLD_APPLICABLE(FMAC_GET_Y_SIZE(hfmac), pConfig->OutputThreshold, pConfig->OutputAccess));
01732 
01733     MODIFY_REG(hfmac->Instance->YBUFCFG, \
01734                FMAC_YBUFCFG_EMPTY_WM,    \
01735                ((pConfig->OutputThreshold) & FMAC_YBUFCFG_EMPTY_WM));
01736   }
01737 
01738   /* FMAC_CR: Configure the clip feature */
01739   tmpcr = pConfig->Clip & FMAC_CR_CLIPEN;
01740 
01741   /* FMAC_CR: If IT or DMA will be used, enable error interrupts.
01742     * Being more a debugging feature, FMAC_CR_SATIEN isn't enabled by default. */
01743   if ((pConfig->InputAccess  == FMAC_BUFFER_ACCESS_DMA) || (pConfig->InputAccess  == FMAC_BUFFER_ACCESS_IT) ||
01744       (pConfig->OutputAccess == FMAC_BUFFER_ACCESS_DMA) || (pConfig->OutputAccess == FMAC_BUFFER_ACCESS_IT))
01745   {
01746     tmpcr |= FMAC_IT_UNFLIEN | FMAC_IT_OVFLIEN;
01747   }
01748 
01749   /* FMAC_CR: write the value */
01750   WRITE_REG(hfmac->Instance->CR, tmpcr);
01751 
01752   /* Save the input/output accesses in order to configure RIEN, WIEN, DMAREN and DMAWEN during filter start */
01753   hfmac->InputAccess = pConfig->InputAccess;
01754   hfmac->OutputAccess = pConfig->OutputAccess;
01755 
01756   /* Check whether the configured X2 is big enough for the filter */
01757 #if defined(USE_FULL_ASSERT)
01758   x2size = FMAC_GET_X2_SIZE(hfmac);
01759 #endif /* USE_FULL_ASSERT */
01760   assert_param(((pConfig->Filter == FMAC_FUNC_CONVO_FIR) && (x2size >= pConfig->P)) || \
01761                ((pConfig->Filter == FMAC_FUNC_IIR_DIRECT_FORM_1) && \
01762                 (x2size >= ((uint32_t)pConfig->P + (uint32_t)pConfig->Q))));
01763 
01764   /* Build the PARAM value that will be used when starting the filter */
01765   hfmac->FilterParam = (FMAC_PARAM_START | pConfig->Filter |                   \
01766                         ((((uint32_t)(pConfig->P)) << FMAC_PARAM_P_Pos) & FMAC_PARAM_P) | \
01767                         ((((uint32_t)(pConfig->Q)) << FMAC_PARAM_Q_Pos) & FMAC_PARAM_Q) | \
01768                         ((((uint32_t)(pConfig->R)) << FMAC_PARAM_R_Pos) & FMAC_PARAM_R));
01769 
01770   /* Initialize the coefficient buffer if required (pCoeffA for FIR only) */
01771   if ((pConfig->pCoeffB != NULL) && (pConfig->CoeffBSize != 0U))
01772   {
01773     /* FIR/IIR: The provided coefficients should match X2 size */
01774     assert_param(((uint32_t)pConfig->CoeffASize + (uint32_t)pConfig->CoeffBSize) <= x2size);
01775     /* FIR/IIR: The size of pCoeffB should match the parameter P */
01776     assert_param(pConfig->CoeffBSize >= pConfig->P);
01777     /* pCoeffA should be provided for IIR but not for FIR */
01778     /* IIR : if pCoeffB is provided, pCoeffA should also be there */
01779     /* IIR: The size of pCoeffA should match the parameter Q */
01780     assert_param(((pConfig->Filter == FMAC_FUNC_CONVO_FIR) &&
01781                   (pConfig->pCoeffA == NULL) && (pConfig->CoeffASize == 0U)) ||
01782                  ((pConfig->Filter == FMAC_FUNC_IIR_DIRECT_FORM_1) &&
01783                   (pConfig->pCoeffA != NULL) && (pConfig->CoeffASize != 0U) &&
01784                   (pConfig->CoeffASize >= pConfig->Q)));
01785 
01786     /* Write number of values to be loaded, the data load function and start the operation */
01787     WRITE_REG(hfmac->Instance->PARAM,                      \
01788               (((uint32_t)(pConfig->CoeffBSize) << FMAC_PARAM_P_Pos) | \
01789                ((uint32_t)(pConfig->CoeffASize) << FMAC_PARAM_Q_Pos) | \
01790                FMAC_FUNC_LOAD_X2 | FMAC_PARAM_START));
01791 
01792     if (PreloadAccess == PRELOAD_ACCESS_POLLING)
01793     {
01794       /* Load the buffer into the internal memory */
01795       FMAC_WritePreloadDataIncrementPtr(hfmac, &(pConfig->pCoeffB), pConfig->CoeffBSize);
01796 
01797       /* Load pCoeffA if needed */
01798       if ((pConfig->pCoeffA != NULL) && (pConfig->CoeffASize != 0U))
01799       {
01800         /* Load the buffer into the internal memory */
01801         FMAC_WritePreloadDataIncrementPtr(hfmac, &(pConfig->pCoeffA), pConfig->CoeffASize);
01802       }
01803 
01804       /* Wait for the end of the writing */
01805       if (FMAC_WaitOnStartUntilTimeout(hfmac, tickstart, HAL_FMAC_TIMEOUT_VALUE) != HAL_OK)
01806       {
01807         hfmac->ErrorCode |= HAL_FMAC_ERROR_TIMEOUT;
01808         hfmac->State = HAL_FMAC_STATE_TIMEOUT;
01809         return HAL_ERROR;
01810       }
01811 
01812       /* Change the FMAC state */
01813       hfmac->State = HAL_FMAC_STATE_READY;
01814     }
01815     else
01816     {
01817       hfmac->pInput = pConfig->pCoeffA;
01818       hfmac->InputCurrentSize = pConfig->CoeffASize;
01819 
01820       /* Set the FMAC DMA transfer complete callback */
01821       hfmac->hdmaPreload->XferHalfCpltCallback = NULL;
01822       hfmac->hdmaPreload->XferCpltCallback = FMAC_DMAFilterConfig;
01823       /* Set the DMA error callback */
01824       hfmac->hdmaPreload->XferErrorCallback = FMAC_DMAError;
01825 
01826       /* Enable the DMA stream managing FMAC preload data write */
01827       return (HAL_DMA_Start_IT(hfmac->hdmaPreload, (uint32_t)pConfig->pCoeffB, (uint32_t)&hfmac->Instance->WDATA,
01828                                pConfig->CoeffBSize));
01829     }
01830   }
01831   else
01832   {
01833     /* Change the FMAC state */
01834     hfmac->State = HAL_FMAC_STATE_READY;
01835   }
01836 
01837   return HAL_OK;
01838 }
01839 
01840 /**
01841   * @brief  Preload the input (FIR, IIR) and output data (IIR) of the FMAC filter.
01842   * @note   The set(s) of data will be used by FMAC as soon as @ref HAL_FMAC_FilterStart is called.
01843   * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
01844   *         the configuration information for FMAC module.
01845   * @param  pInput Preloading of the first elements of the input buffer (X1).
01846   *         If not needed (no data available when starting), it should be set to NULL.
01847   * @param  InputSize Size of the input vector.
01848   *         As pInput is used for preloading data, it cannot be bigger than the input memory area.
01849   * @param  pOutput [IIR] Preloading of the first elements of the output vector (Y).
01850   *         If not needed, it should be set to NULL.
01851   * @param  OutputSize Size of the output vector.
01852   *         As pOutput is used for preloading data, it cannot be bigger than the output memory area.
01853   * @param  PreloadAccess access mode used for the preload (polling or DMA).
01854   * @note   The input and the output buffers can be filled by calling several times @ref HAL_FMAC_FilterPreload
01855   *         (each call filling partly the buffers). In case of overflow (too much data provided through
01856   *         all these calls), an error will be returned.
01857   * @retval HAL_StatusTypeDef HAL status
01858   */
01859 static HAL_StatusTypeDef FMAC_FilterPreload(FMAC_HandleTypeDef *hfmac, int16_t *pInput, uint8_t InputSize,
01860                                             int16_t *pOutput, uint8_t OutputSize, uint8_t PreloadAccess)
01861 {
01862   uint32_t tickstart;
01863   HAL_StatusTypeDef status;
01864 
01865   /* Check the START bit state */
01866   if (FMAC_GET_START_BIT(hfmac) != 0U)
01867   {
01868     return HAL_ERROR;
01869   }
01870 
01871   /* Check that a valid configuration was done previously */
01872   if (hfmac->FilterParam == 0U)
01873   {
01874     return HAL_ERROR;
01875   }
01876 
01877   /* Check the preload input buffers isn't too big */
01878   if ((InputSize > FMAC_GET_X1_SIZE(hfmac)) && (pInput != NULL))
01879   {
01880     return HAL_ERROR;
01881   }
01882 
01883   /* Check the preload output buffer isn't too big */
01884   if ((OutputSize > FMAC_GET_Y_SIZE(hfmac)) && (pOutput != NULL))
01885   {
01886     return HAL_ERROR;
01887   }
01888 
01889   /* Check handle state is ready */
01890   if (hfmac->State != HAL_FMAC_STATE_READY)
01891   {
01892     return HAL_ERROR;
01893   }
01894 
01895   /* Change the FMAC state */
01896   hfmac->State = HAL_FMAC_STATE_BUSY;
01897 
01898   /* Get tick */
01899   tickstart = HAL_GetTick();
01900 
01901   /* Preload the input buffer if required */
01902   if ((pInput != NULL) && (InputSize != 0U))
01903   {
01904     /* Write number of values to be loaded, the data load function and start the operation */
01905     WRITE_REG(hfmac->Instance->PARAM, \
01906               (((uint32_t)InputSize << FMAC_PARAM_P_Pos) | FMAC_FUNC_LOAD_X1 | FMAC_PARAM_START));
01907 
01908     if (PreloadAccess == PRELOAD_ACCESS_POLLING)
01909     {
01910       /* Load the buffer into the internal memory */
01911       FMAC_WritePreloadDataIncrementPtr(hfmac, &pInput, InputSize);
01912 
01913       /* Wait for the end of the writing */
01914       if (FMAC_WaitOnStartUntilTimeout(hfmac, tickstart, HAL_FMAC_TIMEOUT_VALUE) != HAL_OK)
01915       {
01916         hfmac->ErrorCode |= HAL_FMAC_ERROR_TIMEOUT;
01917         hfmac->State = HAL_FMAC_STATE_TIMEOUT;
01918         return HAL_ERROR;
01919       }
01920     }
01921     else
01922     {
01923       hfmac->pInput = pOutput;
01924       hfmac->InputCurrentSize = OutputSize;
01925 
01926       /* Set the FMAC DMA transfer complete callback */
01927       hfmac->hdmaPreload->XferHalfCpltCallback = NULL;
01928       hfmac->hdmaPreload->XferCpltCallback = FMAC_DMAFilterPreload;
01929       /* Set the DMA error callback */
01930       hfmac->hdmaPreload->XferErrorCallback = FMAC_DMAError;
01931 
01932       /* Enable the DMA stream managing FMAC preload data write */
01933       return (HAL_DMA_Start_IT(hfmac->hdmaPreload, (uint32_t)pInput, (uint32_t)&hfmac->Instance->WDATA, InputSize));
01934     }
01935   }
01936 
01937   /* Preload the output buffer if required */
01938   if ((pOutput != NULL) && (OutputSize != 0U))
01939   {
01940     /* Write number of values to be loaded, the data load function and start the operation */
01941     WRITE_REG(hfmac->Instance->PARAM, \
01942               (((uint32_t)OutputSize << FMAC_PARAM_P_Pos) | FMAC_FUNC_LOAD_Y | FMAC_PARAM_START));
01943 
01944     if (PreloadAccess == PRELOAD_ACCESS_POLLING)
01945     {
01946       /* Load the buffer into the internal memory */
01947       FMAC_WritePreloadDataIncrementPtr(hfmac, &pOutput, OutputSize);
01948 
01949       /* Wait for the end of the writing */
01950       if (FMAC_WaitOnStartUntilTimeout(hfmac, tickstart, HAL_FMAC_TIMEOUT_VALUE) != HAL_OK)
01951       {
01952         hfmac->ErrorCode |= HAL_FMAC_ERROR_TIMEOUT;
01953         hfmac->State = HAL_FMAC_STATE_TIMEOUT;
01954         return HAL_ERROR;
01955       }
01956     }
01957     else
01958     {
01959       hfmac->pInput = NULL;
01960       hfmac->InputCurrentSize = 0U;
01961 
01962       /* Set the FMAC DMA transfer complete callback */
01963       hfmac->hdmaPreload->XferHalfCpltCallback = NULL;
01964       hfmac->hdmaPreload->XferCpltCallback = FMAC_DMAFilterPreload;
01965       /* Set the DMA error callback */
01966       hfmac->hdmaPreload->XferErrorCallback = FMAC_DMAError;
01967 
01968       /* Enable the DMA stream managing FMAC preload data write */
01969       return (HAL_DMA_Start_IT(hfmac->hdmaPreload, (uint32_t)pOutput, (uint32_t)&hfmac->Instance->WDATA, OutputSize));
01970     }
01971   }
01972 
01973   /* Update the error codes */
01974   if (__HAL_FMAC_GET_FLAG(hfmac, FMAC_FLAG_OVFL))
01975   {
01976     hfmac->ErrorCode |= HAL_FMAC_ERROR_OVFL;
01977   }
01978   if (__HAL_FMAC_GET_FLAG(hfmac, FMAC_FLAG_UNFL))
01979   {
01980     hfmac->ErrorCode |= HAL_FMAC_ERROR_UNFL;
01981   }
01982   if (__HAL_FMAC_GET_FLAG(hfmac, FMAC_FLAG_SAT))
01983   {
01984     hfmac->ErrorCode |= HAL_FMAC_ERROR_SAT;
01985   }
01986 
01987   /* Change the FMAC state */
01988   hfmac->State = HAL_FMAC_STATE_READY;
01989 
01990   /* Return function status */
01991   if (hfmac->ErrorCode == HAL_FMAC_ERROR_NONE)
01992   {
01993     status = HAL_OK;
01994   }
01995   else
01996   {
01997     status = HAL_ERROR;
01998   }
01999   return status;
02000 }
02001 
02002 /**
02003   * @brief  Write data into FMAC internal memory through WDATA and increment input buffer pointer.
02004   * @note   This function is only used with preload functions.
02005   * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
02006   *         the configuration information for FMAC module.
02007   * @param  ppData pointer to pointer to the data buffer.
02008   * @param  Size size of the data buffer.
02009   * @retval None
02010   */
02011 static void FMAC_WritePreloadDataIncrementPtr(FMAC_HandleTypeDef *hfmac, int16_t **ppData, uint8_t Size)
02012 {
02013   uint8_t index;
02014 
02015   /* Load the buffer into the internal memory */
02016   for (index = Size; index > 0U; index--)
02017   {
02018     WRITE_REG(hfmac->Instance->WDATA, (((uint32_t)(*(*ppData))) & FMAC_WDATA_WDATA));
02019     (*ppData)++;
02020   }
02021 }
02022 
02023 /**
02024   * @brief  Handle FMAC Function Timeout.
02025   * @param  hfmac FMAC handle.
02026   * @param  Tickstart Tick start value.
02027   * @param  Timeout Timeout duration.
02028   * @retval HAL_StatusTypeDef HAL status
02029   */
02030 static HAL_StatusTypeDef FMAC_WaitOnStartUntilTimeout(FMAC_HandleTypeDef *hfmac, uint32_t Tickstart, uint32_t Timeout)
02031 {
02032   /* Wait until flag changes */
02033   while (READ_BIT(hfmac->Instance->PARAM, FMAC_PARAM_START) != 0U)
02034   {
02035     if ((HAL_GetTick() - Tickstart) > Timeout)
02036     {
02037       hfmac->ErrorCode |= HAL_FMAC_ERROR_TIMEOUT;
02038 
02039       return HAL_ERROR;
02040     }
02041   }
02042   return HAL_OK;
02043 }
02044 
02045 /**
02046   * @brief  Register the new input buffer, update DMA configuration if needed and change the FMAC state.
02047   * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
02048   *         the configuration information for FMAC module.
02049   * @param  pInput New input vector (additional input data).
02050   * @param  pInputSize Size of the input vector (if all the data can't be
02051   *         written, it will be updated with the number of data read from FMAC).
02052   * @retval HAL_StatusTypeDef HAL status
02053   */
02054 static HAL_StatusTypeDef FMAC_AppendFilterDataUpdateState(FMAC_HandleTypeDef *hfmac, int16_t *pInput,
02055                                                           uint16_t *pInputSize)
02056 {
02057   /* Change the FMAC state */
02058   hfmac->WrState = HAL_FMAC_STATE_BUSY_WR;
02059 
02060   /* Reset the current size */
02061   hfmac->InputCurrentSize = 0U;
02062 
02063   /* Handle the pointer depending on the input access */
02064   if (hfmac->InputAccess == FMAC_BUFFER_ACCESS_DMA)
02065   {
02066     hfmac->pInput = NULL;
02067     hfmac->pInputSize = NULL;
02068 
02069     /* Set the FMAC DMA transfer complete callback */
02070     hfmac->hdmaIn->XferHalfCpltCallback = FMAC_DMAHalfGetData;
02071     hfmac->hdmaIn->XferCpltCallback = FMAC_DMAGetData;
02072     /* Set the DMA error callback */
02073     hfmac->hdmaIn->XferErrorCallback = FMAC_DMAError;
02074 
02075     /* Enable the DMA stream managing FMAC input data write */
02076     return (HAL_DMA_Start_IT(hfmac->hdmaIn, (uint32_t)pInput, (uint32_t)&hfmac->Instance->WDATA, *pInputSize));
02077   }
02078   else
02079   {
02080     /* Update the input data information (polling, IT) */
02081     hfmac->pInput = pInput;
02082     hfmac->pInputSize = pInputSize;
02083   }
02084 
02085   return HAL_OK;
02086 }
02087 
02088 /**
02089   * @brief  Register the new output buffer, update DMA configuration if needed and change the FMAC state.
02090   * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
02091   *         the configuration information for FMAC module.
02092   * @param  pOutput New output vector.
02093   * @param  pOutputSize Size of the output vector (if the vector can't
02094   *         be entirely filled, pOutputSize will be updated with the number
02095   *         of data read from FMAC).
02096   * @retval HAL_StatusTypeDef HAL status
02097   */
02098 static HAL_StatusTypeDef FMAC_ConfigFilterOutputBufferUpdateState(FMAC_HandleTypeDef *hfmac, int16_t *pOutput,
02099                                                                   uint16_t *pOutputSize)
02100 {
02101   /* Reset the current size */
02102   hfmac->OutputCurrentSize = 0U;
02103 
02104   /* Check whether a valid pointer was provided */
02105   if ((pOutput == NULL) || (pOutputSize == NULL) || (*pOutputSize == 0U))
02106   {
02107     /* The user will have to provide a valid configuration later */
02108     hfmac->pOutput = NULL;
02109     hfmac->pOutputSize = NULL;
02110     hfmac->RdState = HAL_FMAC_STATE_READY;
02111   }
02112   /* Handle the pointer depending on the input access */
02113   else if (hfmac->OutputAccess == FMAC_BUFFER_ACCESS_DMA)
02114   {
02115     hfmac->pOutput = NULL;
02116     hfmac->pOutputSize = NULL;
02117     hfmac->RdState = HAL_FMAC_STATE_BUSY_RD;
02118 
02119     /* Set the FMAC DMA transfer complete callback */
02120     hfmac->hdmaOut->XferHalfCpltCallback = FMAC_DMAHalfOutputDataReady;
02121     hfmac->hdmaOut->XferCpltCallback = FMAC_DMAOutputDataReady;
02122     /* Set the DMA error callback */
02123     hfmac->hdmaOut->XferErrorCallback = FMAC_DMAError;
02124 
02125     /* Enable the DMA stream managing FMAC output data read */
02126     return (HAL_DMA_Start_IT(hfmac->hdmaOut, (uint32_t)&hfmac->Instance->RDATA, (uint32_t)pOutput, *pOutputSize));
02127   }
02128   else if (hfmac->OutputAccess == FMAC_BUFFER_ACCESS_NONE)
02129   {
02130     hfmac->pOutput = NULL;
02131     hfmac->pOutputSize = NULL;
02132     hfmac->RdState = HAL_FMAC_STATE_READY;
02133   }
02134   else
02135   {
02136     /* Update the output data information (polling, IT) */
02137     hfmac->pOutput = pOutput;
02138     hfmac->pOutputSize = pOutputSize;
02139     hfmac->RdState = HAL_FMAC_STATE_BUSY_RD;
02140   }
02141 
02142   return HAL_OK;
02143 }
02144 
02145 /**
02146   * @brief  Read available output data until Y EMPTY is set.
02147   * @param  hfmac FMAC handle.
02148   * @param  MaxSizeToRead Maximum number of data to read (this serves as a timeout
02149   *         if FMAC continuously writes into the output buffer).
02150   * @retval None
02151   */
02152 static void FMAC_ReadDataIncrementPtr(FMAC_HandleTypeDef *hfmac, uint16_t MaxSizeToRead)
02153 {
02154   uint16_t maxsize;
02155   uint16_t threshold;
02156   uint32_t tmpvalue;
02157 
02158   /* Check if there is data to read */
02159   if (READ_BIT(hfmac->Instance->SR, FMAC_SR_YEMPTY) != 0U)
02160   {
02161     return;
02162   }
02163 
02164   /* Get the maximum index (no wait allowed, no overstepping of the output buffer) */
02165   if ((hfmac->OutputCurrentSize + MaxSizeToRead) > *(hfmac->pOutputSize))
02166   {
02167     maxsize = *(hfmac->pOutputSize);
02168   }
02169   else
02170   {
02171     maxsize = hfmac->OutputCurrentSize + MaxSizeToRead;
02172   }
02173 
02174   /* Read until there is no more room or no more data */
02175   do
02176   {
02177     /* If there is no more room, return */
02178     if (!(hfmac->OutputCurrentSize < maxsize))
02179     {
02180       return;
02181     }
02182 
02183     /* Read the available data */
02184     tmpvalue = ((READ_REG(hfmac->Instance->RDATA))& FMAC_RDATA_RDATA);
02185     *(hfmac->pOutput) = (int16_t)tmpvalue;
02186     hfmac->pOutput++;
02187     hfmac->OutputCurrentSize++;
02188   } while (READ_BIT(hfmac->Instance->SR, FMAC_SR_YEMPTY) == 0U);
02189 
02190   /* Y buffer empty flag has just be raised, read the threshold */
02191   threshold = (uint16_t)FMAC_GET_THRESHOLD_FROM_WM(FMAC_GET_Y_EMPTY_WM(hfmac)) - 1U;
02192 
02193   /* Update the maximum size if needed (limited data available) */
02194   if ((hfmac->OutputCurrentSize + threshold) < maxsize)
02195   {
02196     maxsize = hfmac->OutputCurrentSize + threshold;
02197   }
02198 
02199   /* Read the available data */
02200   while (hfmac->OutputCurrentSize < maxsize)
02201   {
02202     tmpvalue = ((READ_REG(hfmac->Instance->RDATA))& FMAC_RDATA_RDATA);
02203     *(hfmac->pOutput) = (int16_t)tmpvalue;
02204     hfmac->pOutput++;
02205     hfmac->OutputCurrentSize++;
02206   }
02207 }
02208 
02209 /**
02210   * @brief  Write available input data until X1 FULL is set.
02211   * @param  hfmac FMAC handle.
02212   * @param  MaxSizeToWrite Maximum number of data to write (this serves as a timeout
02213   *         if FMAC continuously empties the input buffer).
02214   * @retval None
02215   */
02216 static void FMAC_WriteDataIncrementPtr(FMAC_HandleTypeDef *hfmac, uint16_t MaxSizeToWrite)
02217 {
02218   uint16_t maxsize;
02219   uint16_t threshold;
02220 
02221   /* Check if there is room in FMAC */
02222   if (READ_BIT(hfmac->Instance->SR, FMAC_SR_X1FULL) != 0U)
02223   {
02224     return;
02225   }
02226 
02227   /* Get the maximum index (no wait allowed, no overstepping of the output buffer) */
02228   if ((hfmac->InputCurrentSize + MaxSizeToWrite) > *(hfmac->pInputSize))
02229   {
02230     maxsize = *(hfmac->pInputSize);
02231   }
02232   else
02233   {
02234     maxsize = hfmac->InputCurrentSize + MaxSizeToWrite;
02235   }
02236 
02237   /* Write until there is no more room or no more data */
02238   do
02239   {
02240     /* If there is no more room, return */
02241     if (!(hfmac->InputCurrentSize < maxsize))
02242     {
02243       return;
02244     }
02245 
02246     /* Write the available data */
02247     WRITE_REG(hfmac->Instance->WDATA, (((uint32_t)(*(hfmac->pInput))) & FMAC_WDATA_WDATA));
02248     hfmac->pInput++;
02249     hfmac->InputCurrentSize++;
02250   } while (READ_BIT(hfmac->Instance->SR, FMAC_SR_X1FULL) == 0U);
02251 
02252   /* X1 buffer full flag has just be raised, read the threshold */
02253   threshold = (uint16_t)FMAC_GET_THRESHOLD_FROM_WM(FMAC_GET_X1_FULL_WM(hfmac)) - 1U;
02254 
02255   /* Update the maximum size if needed (limited data available) */
02256   if ((hfmac->InputCurrentSize + threshold) < maxsize)
02257   {
02258     maxsize = hfmac->InputCurrentSize + threshold;
02259   }
02260 
02261   /* Write the available data */
02262   while (hfmac->InputCurrentSize < maxsize)
02263   {
02264     WRITE_REG(hfmac->Instance->WDATA, (((uint32_t)(*(hfmac->pInput))) & FMAC_WDATA_WDATA));
02265     hfmac->pInput++;
02266     hfmac->InputCurrentSize++;
02267   }
02268 }
02269 
02270 /**
02271   * @brief  DMA FMAC Input Data process half complete callback.
02272   * @param  hdma DMA handle.
02273   * @retval None
02274   */
02275 static void FMAC_DMAHalfGetData(DMA_HandleTypeDef *hdma)
02276 {
02277   FMAC_HandleTypeDef *hfmac = (FMAC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
02278 
02279   /* Call half get data callback */
02280 #if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1)
02281   hfmac->HalfGetDataCallback(hfmac);
02282 #else
02283   HAL_FMAC_HalfGetDataCallback(hfmac);
02284 #endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */
02285 }
02286 
02287 /**
02288   * @brief  DMA FMAC Input Data process complete callback.
02289   * @param  hdma DMA handle.
02290   * @retval None
02291   */
02292 static void FMAC_DMAGetData(DMA_HandleTypeDef *hdma)
02293 {
02294   FMAC_HandleTypeDef *hfmac = (FMAC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
02295 
02296   /* Reset the pointers to indicate new data will be needed */
02297   FMAC_ResetInputStateAndDataPointers(hfmac);
02298 
02299   /* Call get data callback */
02300 #if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1)
02301   hfmac->GetDataCallback(hfmac);
02302 #else
02303   HAL_FMAC_GetDataCallback(hfmac);
02304 #endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */
02305 }
02306 
02307 /**
02308   * @brief  DMA FMAC Output Data process half complete callback.
02309   * @param  hdma DMA handle.
02310   * @retval None
02311   */
02312 static void FMAC_DMAHalfOutputDataReady(DMA_HandleTypeDef *hdma)
02313 {
02314   FMAC_HandleTypeDef *hfmac = (FMAC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
02315 
02316   /* Call half output data ready callback */
02317 #if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1)
02318   hfmac->HalfOutputDataReadyCallback(hfmac);
02319 #else
02320   HAL_FMAC_HalfOutputDataReadyCallback(hfmac);
02321 #endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */
02322 }
02323 
02324 /**
02325   * @brief  DMA FMAC Output Data process complete callback.
02326   * @param  hdma DMA handle.
02327   * @retval None
02328   */
02329 static void FMAC_DMAOutputDataReady(DMA_HandleTypeDef *hdma)
02330 {
02331   FMAC_HandleTypeDef *hfmac = (FMAC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
02332 
02333   /* Reset the pointers to indicate new data will be needed */
02334   FMAC_ResetOutputStateAndDataPointers(hfmac);
02335 
02336   /* Call output data ready callback */
02337 #if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1)
02338   hfmac->OutputDataReadyCallback(hfmac);
02339 #else
02340   HAL_FMAC_OutputDataReadyCallback(hfmac);
02341 #endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */
02342 }
02343 
02344 /**
02345   * @brief  DMA FMAC Filter Configuration process complete callback.
02346   * @param  hdma DMA handle.
02347   * @retval None
02348   */
02349 static void FMAC_DMAFilterConfig(DMA_HandleTypeDef *hdma)
02350 {
02351   uint8_t index;
02352 
02353   FMAC_HandleTypeDef *hfmac = (FMAC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
02354 
02355   /* If needed, write CoeffA and exit */
02356   if (hfmac->pInput != NULL)
02357   {
02358     /* Set the FMAC DMA transfer complete callback */
02359     hfmac->hdmaPreload->XferHalfCpltCallback = NULL;
02360     hfmac->hdmaPreload->XferCpltCallback = FMAC_DMAFilterConfig;
02361     /* Set the DMA error callback */
02362     hfmac->hdmaPreload->XferErrorCallback = FMAC_DMAError;
02363 
02364     /* Enable the DMA stream managing FMAC preload data write */
02365     if (HAL_DMA_Start_IT(hfmac->hdmaPreload, (uint32_t)hfmac->pInput, (uint32_t)&hfmac->Instance->WDATA,
02366                          hfmac->InputCurrentSize) == HAL_OK)
02367     {
02368       hfmac->pInput = NULL;
02369       hfmac->InputCurrentSize = 0U;
02370       return;
02371     }
02372 
02373     /* If not exited, there was an error: set FMAC handle state to error */
02374     hfmac->State = HAL_FMAC_STATE_ERROR;
02375   }
02376   else
02377   {
02378     /* Wait for the end of the writing */
02379     for (index = 0U; index < MAX_PRELOAD_INDEX; index++)
02380     {
02381       if (READ_BIT(hfmac->Instance->PARAM, FMAC_PARAM_START) == 0U)
02382       {
02383         break;
02384       }
02385     }
02386 
02387     /* If 'START' is still set, there was a timeout: set FMAC handle state to timeout */
02388     if (READ_BIT(hfmac->Instance->PARAM, FMAC_PARAM_START) != 0U)
02389     {
02390       hfmac->State = HAL_FMAC_STATE_TIMEOUT;
02391     }
02392     else
02393     {
02394       /* Change the FMAC state */
02395       hfmac->State = HAL_FMAC_STATE_READY;
02396 
02397       /* Call output data ready callback */
02398 #if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1)
02399       hfmac->FilterConfigCallback(hfmac);
02400 #else
02401       HAL_FMAC_FilterConfigCallback(hfmac);
02402 #endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */
02403       return;
02404     }
02405   }
02406 
02407   /* If not exited, there was an error: set FMAC handle error code to DMA error */
02408   hfmac->ErrorCode |= HAL_FMAC_ERROR_DMA;
02409 
02410   /* Call user callback */
02411 #if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1)
02412   hfmac->ErrorCallback(hfmac);
02413 #else
02414   HAL_FMAC_ErrorCallback(hfmac);
02415 #endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */
02416 
02417 }
02418 
02419 /**
02420   * @brief  DMA FMAC Filter Configuration process complete callback.
02421   * @param  hdma DMA handle.
02422   * @retval None
02423   */
02424 static void FMAC_DMAFilterPreload(DMA_HandleTypeDef *hdma)
02425 {
02426   uint8_t index;
02427 
02428   FMAC_HandleTypeDef *hfmac = (FMAC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
02429 
02430   /* Wait for the end of the X1 writing */
02431   for (index = 0U; index < MAX_PRELOAD_INDEX; index++)
02432   {
02433     if (READ_BIT(hfmac->Instance->PARAM, FMAC_PARAM_START) == 0U)
02434     {
02435       break;
02436     }
02437   }
02438 
02439   /* If 'START' is still set, there was an error: set FMAC handle state to error */
02440   if (READ_BIT(hfmac->Instance->PARAM, FMAC_PARAM_START) != 0U)
02441   {
02442     hfmac->State = HAL_FMAC_STATE_TIMEOUT;
02443     hfmac->ErrorCode |= HAL_FMAC_ERROR_TIMEOUT;
02444   }
02445   /* If needed, preload Y buffer */
02446   else if ((hfmac->pInput != NULL) && (hfmac->InputCurrentSize != 0U))
02447   {
02448     /* Write number of values to be loaded, the data load function and start the operation */
02449     WRITE_REG(hfmac->Instance->PARAM, \
02450               (((uint32_t)(hfmac->InputCurrentSize) << FMAC_PARAM_P_Pos) | FMAC_FUNC_LOAD_Y | FMAC_PARAM_START));
02451 
02452     /* Set the FMAC DMA transfer complete callback */
02453     hfmac->hdmaPreload->XferHalfCpltCallback = NULL;
02454     hfmac->hdmaPreload->XferCpltCallback = FMAC_DMAFilterPreload;
02455     /* Set the DMA error callback */
02456     hfmac->hdmaPreload->XferErrorCallback = FMAC_DMAError;
02457 
02458     /* Enable the DMA stream managing FMAC preload data write */
02459     if (HAL_DMA_Start_IT(hfmac->hdmaPreload, (uint32_t)hfmac->pInput, (uint32_t)&hfmac->Instance->WDATA,
02460                          hfmac->InputCurrentSize) == HAL_OK)
02461     {
02462       hfmac->pInput = NULL;
02463       hfmac->InputCurrentSize = 0U;
02464       return;
02465     }
02466 
02467     /* If not exited, there was an error */
02468     hfmac->ErrorCode = HAL_FMAC_ERROR_DMA;
02469     hfmac->State = HAL_FMAC_STATE_ERROR;
02470   }
02471   else
02472   {
02473     /* nothing to do */
02474   }
02475 
02476   if (hfmac->ErrorCode == HAL_FMAC_ERROR_NONE)
02477   {
02478     /* Change the FMAC state */
02479     hfmac->State = HAL_FMAC_STATE_READY;
02480 
02481     /* Call output data ready callback */
02482 #if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1)
02483     hfmac->FilterPreloadCallback(hfmac);
02484 #else
02485     HAL_FMAC_FilterPreloadCallback(hfmac);
02486 #endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */
02487   }
02488   else
02489   {
02490     /* Call user callback */
02491 #if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1)
02492     hfmac->ErrorCallback(hfmac);
02493 #else
02494     HAL_FMAC_ErrorCallback(hfmac);
02495 #endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */
02496   }
02497 }
02498 
02499 
02500 /**
02501   * @brief  DMA FMAC communication error callback.
02502   * @param  hdma DMA handle.
02503   * @retval None
02504   */
02505 static void FMAC_DMAError(DMA_HandleTypeDef *hdma)
02506 {
02507   FMAC_HandleTypeDef *hfmac = (FMAC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
02508 
02509   /* Set FMAC handle state to error */
02510   hfmac->State = HAL_FMAC_STATE_ERROR;
02511 
02512   /* Set FMAC handle error code to DMA error */
02513   hfmac->ErrorCode |= HAL_FMAC_ERROR_DMA;
02514 
02515   /* Call user callback */
02516 #if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1)
02517   hfmac->ErrorCallback(hfmac);
02518 #else
02519   HAL_FMAC_ErrorCallback(hfmac);
02520 #endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */
02521 }
02522 /**
02523   * @}
02524   */
02525 
02526 
02527 /**
02528   * @}
02529   */
02530 
02531 /**
02532   * @}
02533   */
02534 
02535 #endif /* HAL_FMAC_MODULE_ENABLED */
02536 #endif /* FMAC */