1 /**
2   ******************************************************************************
3   * @file    stm32h5xx_hal_fmac.c
4   * @author  MCD Application Team
5   * @brief   FMAC HAL module driver.
6   *          This file provides firmware functions to manage the following
7   *          functionalities of the FMAC peripheral:
8   *           + Initialization and de-initialization functions
9   *           + Peripheral Control functions
10   *           + Callback functions
11   *           + IRQ handler management
12   *           + Peripheral State and Error functions
13   *
14   ******************************************************************************
15   * @attention
16   *
17   * Copyright (c) 2023 STMicroelectronics.
18   * All rights reserved.
19   *
20   * This software is licensed under terms that can be found in the LICENSE file
21   * in the root directory of this software component.
22   * If no LICENSE file comes with this software, it is provided AS-IS.
23   *
24   ******************************************************************************
25   *
26   *  @verbatim
27 ================================================================================
28             ##### How to use this driver #####
29 ================================================================================
30     [..]
31       The FMAC HAL driver can be used as follows:
32 
33       (#) Initialize the FMAC low level resources by implementing the HAL_FMAC_MspInit():
34           (++) Enable the FMAC interface clock using __HAL_RCC_FMAC_CLK_ENABLE().
35           (++) In case of using interrupts (e.g. access configured as FMAC_BUFFER_ACCESS_IT):
36                (+++) Configure the FMAC interrupt priority using HAL_NVIC_SetPriority().
37                (+++) Enable the FMAC IRQ handler using HAL_NVIC_EnableIRQ().
38                (+++) In FMAC IRQ handler, call HAL_FMAC_IRQHandler().
39           (++) In case of using DMA to control data transfer (e.g. access configured
40                as FMAC_BUFFER_ACCESS_DMA):
41                (+++) Enable the DMA interface clock using __HAL_RCC_DMA1_CLK_ENABLE()
42                      or __HAL_RCC_DMA2_CLK_ENABLE() depending on the used DMA instance.
43                (+++) Enable the DMAMUX1 interface clock using __HAL_RCC_DMAMUX1_CLK_ENABLE().
44                (+++) If the initialization of the internal buffers (coefficients, input,
45                      output) is done via DMA, configure and enable one DMA channel for
46                      managing data transfer from memory to memory (preload channel).
47                (+++) If the input buffer is accessed via DMA, configure and enable one
48                      DMA channel for managing data transfer from memory to peripheral
49                      (input channel).
50                (+++) If the output buffer is accessed via DMA, configure and enable
51                      one DMA channel for managing data transfer from peripheral to
52                      memory (output channel).
53                (+++) Associate the initialized DMA handle(s) to the FMAC DMA handle(s)
54                      using __HAL_LINKDMA().
55                (+++) Configure the priority and enable the NVIC for the transfer complete
56                      interrupt on the enabled DMA channel(s) using HAL_NVIC_SetPriority()
57                      and HAL_NVIC_EnableIRQ().
58 
59       (#) Initialize the FMAC HAL using HAL_FMAC_Init(). This function
60           resorts to HAL_FMAC_MspInit() for low-level initialization.
61 
62       (#) Configure the FMAC processing (filter) using HAL_FMAC_FilterConfig()
63           or HAL_FMAC_FilterConfig_DMA().
64           This function:
65           (++) Defines the memory area within the FMAC internal memory
66                (input, coefficients, output) and the associated threshold (input, output).
67           (++) Configures the filter and its parameters:
68                (+++) Finite Impulse Response (FIR) filter (also known as convolution).
69                (+++) Infinite Impulse Response (IIR) filter (direct form 1).
70           (++) Choose the way to access to the input and output buffers: none, polling,
71                DMA, IT. "none" means the input and/or output data will be handled by
72                another IP (ADC, DAC, etc.).
73           (++) Enable the error interruptions in the input access and/or the output
74                access is done through IT/DMA. If an error occurs, the interruption
75                will be triggered in loop. In order to recover, the user will have
76                to reset the IP with the sequence HAL_FMAC_DeInit / HAL_FMAC_Init.
77                Optionally, he can also disable the interrupt using __HAL_FMAC_DISABLE_IT;
78                the error status will be kept, but no more interrupt will be triggered.
79           (++) Write the provided coefficients into the internal memory using polling
80                mode ( HAL_FMAC_FilterConfig() ) or DMA ( HAL_FMAC_FilterConfig_DMA() ).
81                In the DMA case, HAL_FMAC_FilterConfigCallback() is called when
82                the handling is over.
83 
84        (#) Optionally, the user can enable the error interruption related to
85            saturation by calling __HAL_FMAC_ENABLE_IT. This helps in debugging the
86            filter. If a saturation occurs, the interruption will be triggered in loop.
87            In order to recover, the user will have to:
88            (++) Disable the interruption by calling __HAL_FMAC_DISABLE_IT if
89                 the user wishes to continue all the same.
90            (++) Reset the IP with the sequence HAL_FMAC_DeInit / HAL_FMAC_Init.
91 
92        (#) Optionally, preload input (FIR, IIR) and output (IIR) data using
93            HAL_FMAC_FilterPreload() or HAL_FMAC_FilterPreload_DMA().
94            In the DMA case, HAL_FMAC_FilterPreloadCallback() is called when
95            the handling is over.
96            This step is optional as the filter can be started without preloaded
97            data.
98 
99        (#) Start the FMAC processing (filter) using HAL_FMAC_FilterStart().
100            This function also configures the output buffer that will be filled from
101            the circular internal output buffer. The function returns immediately
102            without updating the provided buffer. The IP processing will be active until
103            HAL_FMAC_FilterStop() is called.
104 
105        (#) If the input internal buffer is accessed via DMA, HAL_FMAC_HalfGetDataCallback()
106            will be called to indicate that half of the input buffer has been handled.
107 
108        (#) If the input internal buffer is accessed via DMA or interrupt, HAL_FMAC_GetDataCallback()
109            will be called to require new input data. It will be provided through
110            HAL_FMAC_AppendFilterData() if the DMA isn't in circular mode.
111 
112        (#) If the output internal buffer is accessed via DMA, HAL_FMAC_HalfOutputDataReadyCallback()
113            will be called to indicate that half of the output buffer has been handled.
114 
115        (#) If the output internal buffer is accessed via DMA or interrupt,
116            HAL_FMAC_OutputDataReadyCallback() will be called to require a new output
117            buffer. It will be provided through HAL_FMAC_ConfigFilterOutputBuffer()
118            if the DMA isn't in circular mode.
119 
120        (#) In all modes except none, provide new input data to be processed via HAL_FMAC_AppendFilterData().
121            This function should only be called once the previous input data has been handled
122            (the preloaded input data isn't concerned).
123 
124        (#) In all modes except none, provide a new output buffer to be filled via
125            HAL_FMAC_ConfigFilterOutputBuffer(). This function should only be called once the previous
126            user's output buffer has been filled.
127 
128        (#) In polling mode, handle the input and output data using HAL_FMAC_PollFilterData().
129            This function:
130            (++) Write the user's input data (provided via HAL_FMAC_AppendFilterData())
131                 into the FMAC input memory area.
132            (++) Read the FMAC output memory area and write it into the user's output buffer.
133            It will return either when:
134            (++) the user's output buffer is filled.
135            (++) the user's input buffer has been handled.
136            The unused data (unread input data or free output data) will not be saved.
137            The user will have to use the updated input and output sizes to keep track
138            of them.
139 
140        (#) Stop the FMAC processing (filter) using HAL_FMAC_FilterStop().
141 
142        (#) Call HAL_FMAC_DeInit() to de-initialize the FMAC peripheral. This function
143            resorts to HAL_FMAC_MspDeInit() for low-level de-initialization.
144 
145   ##### Callback registration #####
146   ==================================
147 
148     [..]
149       The compilation define USE_HAL_FMAC_REGISTER_CALLBACKS when set to 1
150       allows the user to configure dynamically the driver callbacks.
151 
152     [..]
153       Use Function HAL_FMAC_RegisterCallback() to register a user callback.
154       Function HAL_FMAC_RegisterCallback() allows to register following callbacks:
155       (+) ErrorCallback               : Error Callback.
156       (+) HalfGetDataCallback         : Get Half Data Callback.
157       (+) GetDataCallback             : Get Data Callback.
158       (+) HalfOutputDataReadyCallback : Half Output Data Ready Callback.
159       (+) OutputDataReadyCallback     : Output Data Ready Callback.
160       (+) FilterConfigCallback        : Filter Configuration Callback.
161       (+) FilterPreloadCallback       : Filter Preload Callback.
162       (+) MspInitCallback             : FMAC MspInit.
163       (+) MspDeInitCallback           : FMAC MspDeInit.
164       This function takes as parameters the HAL peripheral handle, the Callback ID
165       and a pointer to the user callback function.
166 
167     [..]
168       Use function HAL_FMAC_UnRegisterCallback() to reset a callback to the default
169       weak function.
170       HAL_FMAC_UnRegisterCallback() takes as parameters the HAL peripheral handle
171       and the Callback ID.
172       This function allows to reset following callbacks:
173       (+) ErrorCallback               : Error Callback.
174       (+) HalfGetDataCallback         : Get Half Data Callback.
175       (+) GetDataCallback             : Get Data Callback.
176       (+) HalfOutputDataReadyCallback : Half Output Data Ready Callback.
177       (+) OutputDataReadyCallback     : Output Data Ready Callback.
178       (+) FilterConfigCallback        : Filter Configuration Callback.
179       (+) FilterPreloadCallback       : Filter Preload Callback.
180       (+) MspInitCallback             : FMAC MspInit.
181       (+) MspDeInitCallback           : FMAC MspDeInit.
182 
183     [..]
184       By default, after the HAL_FMAC_Init() and when the state is HAL_FMAC_STATE_RESET
185       all callbacks are set to the corresponding weak functions:
186       examples GetDataCallback(), OutputDataReadyCallback().
187       Exception done for MspInit and MspDeInit functions that are respectively
188       reset to the legacy weak functions in the HAL_FMAC_Init()
189       and HAL_FMAC_DeInit() only when these callbacks are null (not registered beforehand).
190       If not, MspInit or MspDeInit are not null, the HAL_FMAC_Init() and HAL_FMAC_DeInit()
191       keep and use the user MspInit/MspDeInit callbacks (registered beforehand).
192 
193     [..]
194       Callbacks can be registered/unregistered in HAL_FMAC_STATE_READY state only.
195       Exception done MspInit/MspDeInit that can be registered/unregistered
196       in HAL_FMAC_STATE_READY or HAL_FMAC_STATE_RESET state, thus registered (user)
197       MspInit/DeInit callbacks can be used during the Init/DeInit.
198       In that case first register the MspInit/MspDeInit user callbacks
199       using HAL_FMAC_RegisterCallback() before calling HAL_FMAC_DeInit()
200       or HAL_FMAC_Init() function.
201 
202     [..]
203       When the compilation define USE_HAL_FMAC_REGISTER_CALLBACKS is set to 0 or
204       not defined, the callback registration feature is not available
205       and weak callbacks are used.
206 
207   @endverbatim
208   *
209   */
210 
211 /* Includes ------------------------------------------------------------------*/
212 #include "stm32h5xx_hal.h"
213 
214 #if defined(FMAC)
215 #ifdef HAL_FMAC_MODULE_ENABLED
216 
217 /** @addtogroup STM32H5xx_HAL_Driver
218   * @{
219   */
220 
221 /** @defgroup FMAC FMAC
222   * @brief    FMAC HAL driver module
223   * @{
224   */
225 
226 /* Private typedef -----------------------------------------------------------*/
227 /* Private defines -----------------------------------------------------------*/
228 /** @defgroup  FMAC_Private_Constants   FMAC Private Constants
229   * @{
230   */
231 #define MAX_FILTER_DATA_SIZE_TO_HANDLE ((uint16_t) 0xFFU)
232 #define MAX_PRELOAD_INDEX      0xFFU
233 #define PRELOAD_ACCESS_DMA     0x00U
234 #define PRELOAD_ACCESS_POLLING 0x01U
235 #define POLLING_DISABLED       0U
236 #define POLLING_ENABLED        1U
237 #define POLLING_NOT_STOPPED    0U
238 #define POLLING_STOPPED        1U
239 /* FMAC polling-based communications time-out value */
240 #define HAL_FMAC_TIMEOUT_VALUE         1000U
241 /* FMAC reset time-out value */
242 #define HAL_FMAC_RESET_TIMEOUT_VALUE   500U
243 /* DMA Read Requests Enable */
244 #define FMAC_DMA_REN                   FMAC_CR_DMAREN
245 /* DMA Write Channel Enable */
246 #define FMAC_DMA_WEN                   FMAC_CR_DMAWEN
247 /* FMAC Execution Enable */
248 #define FMAC_START                     FMAC_PARAM_START
249 
250 /**
251   * @}
252   */
253 
254 /* Private macros ------------------------------------------------------------*/
255 /** @defgroup  FMAC_Private_Macros   FMAC Private Macros
256   * @{
257   */
258 
259 /**
260   * @brief  Get the X1 memory area size.
261   * @param  __HANDLE__ FMAC handle.
262   * @retval X1_BUF_SIZE
263   */
264 #define FMAC_GET_X1_SIZE(__HANDLE__) \
265   ((((__HANDLE__)->Instance->X1BUFCFG) & (FMAC_X1BUFCFG_X1_BUF_SIZE)) >> (FMAC_X1BUFCFG_X1_BUF_SIZE_Pos))
266 
267 /**
268   * @brief  Get the X1 watermark.
269   * @param  __HANDLE__ FMAC handle.
270   * @retval FULL_WM
271   */
272 #define FMAC_GET_X1_FULL_WM(__HANDLE__) \
273   (((__HANDLE__)->Instance->X1BUFCFG) & (FMAC_X1BUFCFG_FULL_WM))
274 
275 /**
276   * @brief  Get the X2 memory area size.
277   * @param  __HANDLE__ FMAC handle.
278   * @retval X2_BUF_SIZE
279   */
280 #define FMAC_GET_X2_SIZE(__HANDLE__) \
281   ((((__HANDLE__)->Instance->X2BUFCFG) & (FMAC_X2BUFCFG_X2_BUF_SIZE)) >> (FMAC_X2BUFCFG_X2_BUF_SIZE_Pos))
282 
283 /**
284   * @brief  Get the Y memory area size.
285   * @param  __HANDLE__ FMAC handle.
286   * @retval Y_BUF_SIZE
287   */
288 #define FMAC_GET_Y_SIZE(__HANDLE__) \
289   ((((__HANDLE__)->Instance->YBUFCFG) & (FMAC_YBUFCFG_Y_BUF_SIZE)) >> (FMAC_YBUFCFG_Y_BUF_SIZE_Pos))
290 
291 /**
292   * @brief  Get the Y watermark.
293   * @param  __HANDLE__ FMAC handle.
294   * @retval EMPTY_WM
295   */
296 #define FMAC_GET_Y_EMPTY_WM(__HANDLE__) \
297   (((__HANDLE__)->Instance->YBUFCFG) & (FMAC_YBUFCFG_EMPTY_WM))
298 
299 /**
300   * @brief  Get the start bit state.
301   * @param  __HANDLE__ FMAC handle.
302   * @retval START
303   */
304 #define FMAC_GET_START_BIT(__HANDLE__) \
305   ((((__HANDLE__)->Instance->PARAM) & (FMAC_PARAM_START)) >> (FMAC_PARAM_START_Pos))
306 
307 /**
308   * @brief  Get the threshold matching the watermark.
309   * @param  __WM__ Watermark value.
310   * @retval THRESHOLD
311   */
312 #define FMAC_GET_THRESHOLD_FROM_WM(__WM__) (((__WM__) == FMAC_THRESHOLD_1)? 1U: \
313                                             ((__WM__) == FMAC_THRESHOLD_2)? 2U: \
314                                             ((__WM__) == FMAC_THRESHOLD_4)? 4U:8U)
315 
316 /**
317   * @}
318   */
319 
320 /* Private variables ---------------------------------------------------------*/
321 /* Global variables ----------------------------------------------------------*/
322 /* Private function prototypes -----------------------------------------------*/
323 static HAL_StatusTypeDef FMAC_Reset(FMAC_HandleTypeDef *hfmac);
324 static void FMAC_ResetDataPointers(FMAC_HandleTypeDef *hfmac);
325 static void FMAC_ResetOutputStateAndDataPointers(FMAC_HandleTypeDef *hfmac);
326 static void FMAC_ResetInputStateAndDataPointers(FMAC_HandleTypeDef *hfmac);
327 static HAL_StatusTypeDef FMAC_FilterConfig(FMAC_HandleTypeDef *hfmac, FMAC_FilterConfigTypeDef *pConfig,
328                                            uint8_t PreloadAccess);
329 static HAL_StatusTypeDef FMAC_FilterPreload(FMAC_HandleTypeDef *hfmac, int16_t *pInput, uint8_t InputSize,
330                                             int16_t *pOutput, uint8_t OutputSize, uint8_t PreloadAccess);
331 static void FMAC_WritePreloadDataIncrementPtr(FMAC_HandleTypeDef *hfmac, int16_t **ppData, uint8_t Size);
332 static HAL_StatusTypeDef FMAC_WaitOnStartUntilTimeout(FMAC_HandleTypeDef *hfmac, uint32_t Tickstart, uint32_t Timeout);
333 static HAL_StatusTypeDef FMAC_AppendFilterDataUpdateState(FMAC_HandleTypeDef *hfmac, int16_t *pInput,
334                                                           uint16_t *pInputSize);
335 static HAL_StatusTypeDef FMAC_ConfigFilterOutputBufferUpdateState(FMAC_HandleTypeDef *hfmac, int16_t *pOutput,
336                                                                   uint16_t *pOutputSize);
337 static void FMAC_WriteDataIncrementPtr(FMAC_HandleTypeDef *hfmac, uint16_t MaxSizeToWrite);
338 static void FMAC_ReadDataIncrementPtr(FMAC_HandleTypeDef *hfmac, uint16_t MaxSizeToRead);
339 static void FMAC_DMAHalfGetData(DMA_HandleTypeDef *hdma);
340 static void FMAC_DMAGetData(DMA_HandleTypeDef *hdma);
341 static void FMAC_DMAHalfOutputDataReady(DMA_HandleTypeDef *hdma);
342 static void FMAC_DMAOutputDataReady(DMA_HandleTypeDef *hdma);
343 static void FMAC_DMAFilterConfig(DMA_HandleTypeDef *hdma);
344 static void FMAC_DMAFilterPreload(DMA_HandleTypeDef *hdma);
345 static void FMAC_DMAError(DMA_HandleTypeDef *hdma);
346 
347 /* Functions Definition ------------------------------------------------------*/
348 /** @defgroup FMAC_Exported_Functions FMAC Exported Functions
349   * @{
350   */
351 
352 /** @defgroup FMAC_Exported_Functions_Group1 Initialization and de-initialization functions
353   * @brief    Initialization and Configuration functions
354   *
355 @verbatim
356  ===============================================================================
357      #####       Initialization and de-initialization functions       #####
358  ===============================================================================
359     [..] This section provides functions allowing to:
360       (+) Initialize the FMAC peripheral and the associated handle
361       (+) DeInitialize the FMAC peripheral
362       (+) Initialize the FMAC MSP (MCU Specific Package)
363       (+) De-Initialize the FMAC MSP
364       (+) Register a User FMAC Callback
365       (+) Unregister a FMAC CallBack
366 
367     [..]
368 
369 @endverbatim
370   * @{
371   */
372 
373 /**
374   * @brief  Initialize the FMAC peripheral and the associated handle.
375   * @param  hfmac pointer to a FMAC_HandleTypeDef structure.
376   * @retval HAL_StatusTypeDef HAL status
377   */
HAL_FMAC_Init(FMAC_HandleTypeDef * hfmac)378 HAL_StatusTypeDef HAL_FMAC_Init(FMAC_HandleTypeDef *hfmac)
379 {
380   HAL_StatusTypeDef status;
381 
382   /* Check the FMAC handle allocation */
383   if (hfmac == NULL)
384   {
385     return HAL_ERROR;
386   }
387 
388   /* Check the instance */
389   assert_param(IS_FMAC_ALL_INSTANCE(hfmac->Instance));
390 
391   if (hfmac->State == HAL_FMAC_STATE_RESET)
392   {
393     /* Initialize lock resource */
394     hfmac->Lock = HAL_UNLOCKED;
395 
396 #if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1)
397     /* Register the default callback functions */
398     hfmac->ErrorCallback = HAL_FMAC_ErrorCallback;
399     hfmac->HalfGetDataCallback = HAL_FMAC_HalfGetDataCallback;
400     hfmac->GetDataCallback = HAL_FMAC_GetDataCallback;
401     hfmac->HalfOutputDataReadyCallback = HAL_FMAC_HalfOutputDataReadyCallback;
402     hfmac->OutputDataReadyCallback = HAL_FMAC_OutputDataReadyCallback;
403     hfmac->FilterConfigCallback = HAL_FMAC_FilterConfigCallback;
404     hfmac->FilterPreloadCallback = HAL_FMAC_FilterPreloadCallback;
405 
406     if (hfmac->MspInitCallback == NULL)
407     {
408       hfmac->MspInitCallback = HAL_FMAC_MspInit;
409     }
410 
411     /* Init the low level hardware */
412     hfmac->MspInitCallback(hfmac);
413 #else
414     /* Init the low level hardware */
415     HAL_FMAC_MspInit(hfmac);
416 #endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */
417   }
418 
419   /* Reset pInput and pOutput */
420   hfmac->FilterParam = 0U;
421   FMAC_ResetDataPointers(hfmac);
422 
423   /* Reset FMAC unit (internal pointers) */
424   if (FMAC_Reset(hfmac) == HAL_ERROR)
425   {
426     /* Update FMAC error code and FMAC peripheral state */
427     hfmac->ErrorCode |= HAL_FMAC_ERROR_RESET;
428     hfmac->State = HAL_FMAC_STATE_TIMEOUT;
429 
430     status = HAL_ERROR;
431   }
432   else
433   {
434     /* Update FMAC error code and FMAC peripheral state */
435     hfmac->ErrorCode = HAL_FMAC_ERROR_NONE;
436     hfmac->State = HAL_FMAC_STATE_READY;
437 
438     status = HAL_OK;
439   }
440 
441   __HAL_UNLOCK(hfmac);
442 
443   return status;
444 }
445 
446 /**
447   * @brief  De-initialize the FMAC peripheral.
448   * @param  hfmac pointer to a FMAC structure.
449   * @retval HAL_StatusTypeDef HAL status
450   */
HAL_FMAC_DeInit(FMAC_HandleTypeDef * hfmac)451 HAL_StatusTypeDef HAL_FMAC_DeInit(FMAC_HandleTypeDef *hfmac)
452 {
453   /* Check the FMAC handle allocation */
454   if (hfmac == NULL)
455   {
456     return HAL_ERROR;
457   }
458 
459   /* Check the parameters */
460   assert_param(IS_FMAC_ALL_INSTANCE(hfmac->Instance));
461 
462   /* Change FMAC peripheral state */
463   hfmac->State = HAL_FMAC_STATE_BUSY;
464 
465   /* Set FMAC error code to none */
466   hfmac->ErrorCode = HAL_FMAC_ERROR_NONE;
467 
468   /* Reset pInput and pOutput */
469   hfmac->FilterParam = 0U;
470   FMAC_ResetDataPointers(hfmac);
471 
472 #if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1)
473   if (hfmac->MspDeInitCallback == NULL)
474   {
475     hfmac->MspDeInitCallback = HAL_FMAC_MspDeInit;
476   }
477   /* DeInit the low level hardware */
478   hfmac->MspDeInitCallback(hfmac);
479 #else
480   /* DeInit the low level hardware: CLOCK, NVIC, DMA */
481   HAL_FMAC_MspDeInit(hfmac);
482 #endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */
483 
484   /* Change FMAC peripheral state */
485   hfmac->State = HAL_FMAC_STATE_RESET;
486 
487   /* Always release Lock in case of de-initialization */
488   __HAL_UNLOCK(hfmac);
489 
490   return HAL_OK;
491 }
492 
493 /**
494   * @brief  Initialize the FMAC MSP.
495   * @param  hfmac FMAC handle.
496   * @retval None
497   */
HAL_FMAC_MspInit(FMAC_HandleTypeDef * hfmac)498 __weak void HAL_FMAC_MspInit(FMAC_HandleTypeDef *hfmac)
499 {
500   /* Prevent unused argument(s) compilation warning */
501   UNUSED(hfmac);
502 
503   /* NOTE : This function should not be modified, when the callback is needed,
504             the HAL_FMAC_MspInit can be implemented in the user file
505    */
506 }
507 
508 /**
509   * @brief  De-initialize the FMAC MSP.
510   * @param  hfmac FMAC handle.
511   * @retval None
512   */
HAL_FMAC_MspDeInit(FMAC_HandleTypeDef * hfmac)513 __weak void HAL_FMAC_MspDeInit(FMAC_HandleTypeDef *hfmac)
514 {
515   /* Prevent unused argument(s) compilation warning */
516   UNUSED(hfmac);
517 
518   /* NOTE : This function should not be modified, when the callback is needed,
519             the HAL_FMAC_MspDeInit can be implemented in the user file
520    */
521 }
522 
523 #if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1)
524 /**
525   * @brief  Register a User FMAC Callback.
526   * @note   The User FMAC Callback is to be used instead of the weak predefined callback.
527   * @note   The HAL_FMAC_RegisterCallback() may be called before HAL_FMAC_Init() in HAL_FMAC_STATE_RESET to register
528   *         callbacks for HAL_FMAC_MSPINIT_CB_ID and HAL_FMAC_MSPDEINIT_CB_ID.
529   * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
530   *         the configuration information for FMAC module.
531   * @param  CallbackID ID of the callback to be registered.
532   *         This parameter can be one of the following values:
533   *           @arg @ref HAL_FMAC_ERROR_CB_ID Error Callback ID
534   *           @arg @ref HAL_FMAC_HALF_GET_DATA_CB_ID Get Half Data Callback ID
535   *           @arg @ref HAL_FMAC_GET_DATA_CB_ID Get Data Callback ID
536   *           @arg @ref HAL_FMAC_HALF_OUTPUT_DATA_READY_CB_ID Half Output Data Ready Callback ID
537   *           @arg @ref HAL_FMAC_OUTPUT_DATA_READY_CB_ID Output Data Ready Callback ID
538   *           @arg @ref HAL_FMAC_FILTER_CONFIG_CB_ID Filter Configuration Callback ID
539   *           @arg @ref HAL_FMAC_FILTER_PRELOAD_CB_ID Filter Preload Callback ID
540   *           @arg @ref HAL_FMAC_MSPINIT_CB_ID FMAC MspInit ID
541   *           @arg @ref HAL_FMAC_MSPDEINIT_CB_ID FMAC MspDeInit ID
542   * @param  pCallback pointer to the Callback function.
543   * @retval HAL_StatusTypeDef HAL status
544   */
HAL_FMAC_RegisterCallback(FMAC_HandleTypeDef * hfmac,HAL_FMAC_CallbackIDTypeDef CallbackID,pFMAC_CallbackTypeDef pCallback)545 HAL_StatusTypeDef HAL_FMAC_RegisterCallback(FMAC_HandleTypeDef *hfmac, HAL_FMAC_CallbackIDTypeDef CallbackID,
546                                             pFMAC_CallbackTypeDef pCallback)
547 {
548   HAL_StatusTypeDef status = HAL_OK;
549 
550   /* Check the FMAC handle allocation */
551   if (hfmac == NULL)
552   {
553     return HAL_ERROR;
554   }
555 
556   if (pCallback == NULL)
557   {
558     /* Update the error code */
559     hfmac->ErrorCode |= HAL_FMAC_ERROR_INVALID_CALLBACK;
560 
561     return HAL_ERROR;
562   }
563 
564   if (hfmac->State == HAL_FMAC_STATE_READY)
565   {
566     switch (CallbackID)
567     {
568       case HAL_FMAC_ERROR_CB_ID :
569         hfmac->ErrorCallback = pCallback;
570         break;
571 
572       case HAL_FMAC_HALF_GET_DATA_CB_ID :
573         hfmac->HalfGetDataCallback = pCallback;
574         break;
575 
576       case HAL_FMAC_GET_DATA_CB_ID :
577         hfmac->GetDataCallback = pCallback;
578         break;
579 
580       case HAL_FMAC_HALF_OUTPUT_DATA_READY_CB_ID :
581         hfmac->HalfOutputDataReadyCallback = pCallback;
582         break;
583 
584       case HAL_FMAC_OUTPUT_DATA_READY_CB_ID :
585         hfmac->OutputDataReadyCallback = pCallback;
586         break;
587 
588       case HAL_FMAC_FILTER_CONFIG_CB_ID :
589         hfmac->FilterConfigCallback = pCallback;
590         break;
591 
592       case HAL_FMAC_FILTER_PRELOAD_CB_ID :
593         hfmac->FilterPreloadCallback = pCallback;
594         break;
595 
596       case HAL_FMAC_MSPINIT_CB_ID :
597         hfmac->MspInitCallback = pCallback;
598         break;
599 
600       case HAL_FMAC_MSPDEINIT_CB_ID :
601         hfmac->MspDeInitCallback = pCallback;
602         break;
603 
604       default :
605         /* Update the error code */
606         hfmac->ErrorCode |= HAL_FMAC_ERROR_INVALID_CALLBACK;
607 
608         /* Return error status */
609         status =  HAL_ERROR;
610         break;
611     }
612   }
613   else if (hfmac->State == HAL_FMAC_STATE_RESET)
614   {
615     switch (CallbackID)
616     {
617       case HAL_FMAC_MSPINIT_CB_ID :
618         hfmac->MspInitCallback = pCallback;
619         break;
620 
621       case HAL_FMAC_MSPDEINIT_CB_ID :
622         hfmac->MspDeInitCallback = pCallback;
623         break;
624 
625       default :
626         /* Update the error code */
627         hfmac->ErrorCode |= HAL_FMAC_ERROR_INVALID_CALLBACK;
628 
629         /* Return error status */
630         status =  HAL_ERROR;
631         break;
632     }
633   }
634   else
635   {
636     /* Update the error code */
637     hfmac->ErrorCode |= HAL_FMAC_ERROR_INVALID_CALLBACK;
638 
639     /* Return error status */
640     status =  HAL_ERROR;
641   }
642 
643   return status;
644 }
645 
646 /**
647   * @brief  Unregister a FMAC CallBack.
648   * @note   The FMAC callback is redirected to the weak predefined callback.
649   * @note   The HAL_FMAC_UnRegisterCallback() may be called before HAL_FMAC_Init() in HAL_FMAC_STATE_RESET to register
650   *         callbacks for HAL_FMAC_MSPINIT_CB_ID and HAL_FMAC_MSPDEINIT_CB_ID.
651   * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
652   *         the configuration information for FMAC module
653   * @param  CallbackID ID of the callback to be unregistered.
654   *         This parameter can be one of the following values:
655   *           @arg @ref HAL_FMAC_ERROR_CB_ID Error Callback ID
656   *           @arg @ref HAL_FMAC_HALF_GET_DATA_CB_ID Get Half Data Callback ID
657   *           @arg @ref HAL_FMAC_GET_DATA_CB_ID Get Data Callback ID
658   *           @arg @ref HAL_FMAC_HALF_OUTPUT_DATA_READY_CB_ID Half Output Data Ready Callback ID
659   *           @arg @ref HAL_FMAC_OUTPUT_DATA_READY_CB_ID Output Data Ready Callback ID
660   *           @arg @ref HAL_FMAC_FILTER_CONFIG_CB_ID Filter Configuration Callback ID
661   *           @arg @ref HAL_FMAC_FILTER_PRELOAD_CB_ID Filter Preload Callback ID
662   *           @arg @ref HAL_FMAC_MSPINIT_CB_ID FMAC MspInit ID
663   *           @arg @ref HAL_FMAC_MSPDEINIT_CB_ID FMAC MspDeInit ID
664   * @retval HAL_StatusTypeDef HAL status
665   */
HAL_FMAC_UnRegisterCallback(FMAC_HandleTypeDef * hfmac,HAL_FMAC_CallbackIDTypeDef CallbackID)666 HAL_StatusTypeDef HAL_FMAC_UnRegisterCallback(FMAC_HandleTypeDef *hfmac, HAL_FMAC_CallbackIDTypeDef CallbackID)
667 {
668   HAL_StatusTypeDef status = HAL_OK;
669 
670   /* Check the FMAC handle allocation */
671   if (hfmac == NULL)
672   {
673     return HAL_ERROR;
674   }
675 
676   if (hfmac->State == HAL_FMAC_STATE_READY)
677   {
678     switch (CallbackID)
679     {
680       case HAL_FMAC_ERROR_CB_ID :
681         hfmac->ErrorCallback = HAL_FMAC_ErrorCallback;                             /* Legacy weak ErrorCallback       */
682         break;
683 
684       case HAL_FMAC_HALF_GET_DATA_CB_ID :
685         hfmac->HalfGetDataCallback = HAL_FMAC_HalfGetDataCallback;                 /* Legacy weak HalfGetDataCallback */
686         break;
687 
688       case HAL_FMAC_GET_DATA_CB_ID :
689         hfmac->GetDataCallback = HAL_FMAC_GetDataCallback;                         /* Legacy weak GetDataCallback     */
690         break;
691 
692       case HAL_FMAC_HALF_OUTPUT_DATA_READY_CB_ID :
693         hfmac->HalfOutputDataReadyCallback = HAL_FMAC_HalfOutputDataReadyCallback; /* Legacy weak
694                                                                                       HalfOutputDataReadyCallback     */
695         break;
696 
697       case HAL_FMAC_OUTPUT_DATA_READY_CB_ID :
698         hfmac->OutputDataReadyCallback = HAL_FMAC_OutputDataReadyCallback;         /* Legacy weak
699                                                                                       OutputDataReadyCallback         */
700         break;
701 
702       case HAL_FMAC_FILTER_CONFIG_CB_ID :
703         hfmac->FilterConfigCallback = HAL_FMAC_FilterConfigCallback;               /* Legacy weak
704                                                                                       FilterConfigCallback            */
705         break;
706 
707       case HAL_FMAC_FILTER_PRELOAD_CB_ID :
708         hfmac->FilterPreloadCallback = HAL_FMAC_FilterPreloadCallback;             /* Legacy weak FilterPreloadCallba */
709         break;
710 
711       case HAL_FMAC_MSPINIT_CB_ID :
712         hfmac->MspInitCallback = HAL_FMAC_MspInit;                                 /* Legacy weak MspInitCallback     */
713         break;
714 
715       case HAL_FMAC_MSPDEINIT_CB_ID :
716         hfmac->MspDeInitCallback = HAL_FMAC_MspDeInit;                             /* Legacy weak MspDeInitCallback   */
717         break;
718 
719       default :
720         /* Update the error code */
721         hfmac->ErrorCode |= HAL_FMAC_ERROR_INVALID_CALLBACK;
722 
723         /* Return error status */
724         status =  HAL_ERROR;
725         break;
726     }
727   }
728   else if (hfmac->State == HAL_FMAC_STATE_RESET)
729   {
730     switch (CallbackID)
731     {
732       case HAL_FMAC_MSPINIT_CB_ID :
733         hfmac->MspInitCallback = HAL_FMAC_MspInit;
734         break;
735 
736       case HAL_FMAC_MSPDEINIT_CB_ID :
737         hfmac->MspDeInitCallback = HAL_FMAC_MspDeInit;
738         break;
739 
740       default :
741         /* Update the error code */
742         hfmac->ErrorCode |= HAL_FMAC_ERROR_INVALID_CALLBACK;
743 
744         /* Return error status */
745         status =  HAL_ERROR;
746         break;
747     }
748   }
749   else
750   {
751     /* Update the error code */
752     hfmac->ErrorCode |= HAL_FMAC_ERROR_INVALID_CALLBACK;
753 
754     /* Return error status */
755     status = HAL_ERROR;
756   }
757 
758   return status;
759 }
760 #endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */
761 
762 /**
763   * @}
764   */
765 
766 /** @defgroup FMAC_Exported_Functions_Group2 Peripheral Control functions
767   * @brief    Control functions.
768   *
769 @verbatim
770   ==============================================================================
771                       ##### Peripheral Control functions #####
772   ==============================================================================
773     [..]  This section provides functions allowing to:
774       (+) Configure the FMAC peripheral: memory area, filter type and parameters,
775           way to access to the input and output memory area (none, polling, IT, DMA).
776       (+) Start the FMAC processing (filter).
777       (+) Handle the input data that will be provided into FMAC.
778       (+) Handle the output data provided by FMAC.
779       (+) Stop the FMAC processing (filter).
780 
781 @endverbatim
782   * @{
783   */
784 
785 /**
786   * @brief  Configure the FMAC filter.
787   * @note   The configuration is done according to the parameters
788   *         specified in the FMAC_FilterConfigTypeDef structure.
789   *         The provided data will be loaded using polling mode.
790   * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
791   *         the configuration information for FMAC module.
792   * @param  pConfig pointer to a FMAC_FilterConfigTypeDef structure that
793   *         contains the FMAC configuration information.
794   * @retval HAL_StatusTypeDef HAL status
795   */
HAL_FMAC_FilterConfig(FMAC_HandleTypeDef * hfmac,FMAC_FilterConfigTypeDef * pConfig)796 HAL_StatusTypeDef HAL_FMAC_FilterConfig(FMAC_HandleTypeDef *hfmac, FMAC_FilterConfigTypeDef *pConfig)
797 {
798   return (FMAC_FilterConfig(hfmac, pConfig, PRELOAD_ACCESS_POLLING));
799 }
800 
801 /**
802   * @brief  Configure the FMAC filter.
803   * @note   The configuration is done according to the parameters
804   *         specified in the FMAC_FilterConfigTypeDef structure.
805   *         The provided data will be loaded using DMA.
806   * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
807   *         the configuration information for FMAC module.
808   * @param  pConfig pointer to a FMAC_FilterConfigTypeDef structure that
809   *         contains the FMAC configuration information.
810   * @retval HAL_StatusTypeDef HAL status
811   */
HAL_FMAC_FilterConfig_DMA(FMAC_HandleTypeDef * hfmac,FMAC_FilterConfigTypeDef * pConfig)812 HAL_StatusTypeDef HAL_FMAC_FilterConfig_DMA(FMAC_HandleTypeDef *hfmac, FMAC_FilterConfigTypeDef *pConfig)
813 {
814   return (FMAC_FilterConfig(hfmac, pConfig, PRELOAD_ACCESS_DMA));
815 }
816 
817 /**
818   * @brief  Preload the input (FIR, IIR) and output data (IIR) of the FMAC filter.
819   * @note   The set(s) of data will be used by FMAC as soon as @ref HAL_FMAC_FilterStart is called.
820   *         The provided data will be loaded using polling mode.
821   * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
822   *         the configuration information for FMAC module.
823   * @param  pInput Preloading of the first elements of the input buffer (X1).
824   *         If not needed (no data available when starting), it should be set to NULL.
825   * @param  InputSize Size of the input vector.
826   *         As pInput is used for preloading data, it cannot be bigger than the input memory area.
827   * @param  pOutput [IIR] Preloading of the first elements of the output vector (Y).
828   *         If not needed, it should be set to NULL.
829   * @param  OutputSize Size of the output vector.
830   *         As pOutput is used for preloading data, it cannot be bigger than the output memory area.
831   * @note   The input and the output buffers can be filled by calling several times @ref HAL_FMAC_FilterPreload
832   *         (each call filling partly the buffers). In case of overflow (too much data provided through
833   *         all these calls), an error will be returned.
834   * @retval HAL_StatusTypeDef HAL status
835   */
HAL_FMAC_FilterPreload(FMAC_HandleTypeDef * hfmac,int16_t * pInput,uint8_t InputSize,int16_t * pOutput,uint8_t OutputSize)836 HAL_StatusTypeDef HAL_FMAC_FilterPreload(FMAC_HandleTypeDef *hfmac, int16_t *pInput, uint8_t InputSize,
837                                          int16_t *pOutput, uint8_t OutputSize)
838 {
839   return (FMAC_FilterPreload(hfmac, pInput, InputSize, pOutput, OutputSize, PRELOAD_ACCESS_POLLING));
840 }
841 
842 /**
843   * @brief  Preload the input (FIR, IIR) and output data (IIR) of the FMAC filter.
844   * @note   The set(s) of data will be used by FMAC as soon as @ref HAL_FMAC_FilterStart is called.
845   *         The provided data will be loaded using DMA.
846   * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
847   *         the configuration information for FMAC module.
848   * @param  pInput Preloading of the first elements of the input buffer (X1).
849   *         If not needed (no data available when starting), it should be set to NULL.
850   * @param  InputSize Size of the input vector.
851   *         As pInput is used for preloading data, it cannot be bigger than the input memory area.
852   * @param  pOutput [IIR] Preloading of the first elements of the output vector (Y).
853   *         If not needed, it should be set to NULL.
854   * @param  OutputSize Size of the output vector.
855   *         As pOutput is used for preloading data, it cannot be bigger than the output memory area.
856   * @note   The input and the output buffers can be filled by calling several times @ref HAL_FMAC_FilterPreload
857   *         (each call filling partly the buffers). In case of overflow (too much data provided through
858   *         all these calls), an error will be returned.
859   * @retval HAL_StatusTypeDef HAL status
860   */
HAL_FMAC_FilterPreload_DMA(FMAC_HandleTypeDef * hfmac,int16_t * pInput,uint8_t InputSize,int16_t * pOutput,uint8_t OutputSize)861 HAL_StatusTypeDef HAL_FMAC_FilterPreload_DMA(FMAC_HandleTypeDef *hfmac, int16_t *pInput, uint8_t InputSize,
862                                              int16_t *pOutput, uint8_t OutputSize)
863 {
864   return (FMAC_FilterPreload(hfmac, pInput, InputSize, pOutput, OutputSize, PRELOAD_ACCESS_DMA));
865 }
866 
867 
868 /**
869   * @brief  Start the FMAC processing according to the existing FMAC configuration.
870   * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
871   *         the configuration information for FMAC module.
872   * @param  pOutput pointer to buffer where output data of FMAC processing will be stored
873   *         in the next steps.
874   *         If it is set to NULL, the output will not be read and it will be up to
875   *         an external IP to empty the output buffer.
876   * @param  pOutputSize pointer to the size of the output buffer. The number of read data will be written here.
877   * @retval HAL_StatusTypeDef HAL status
878   */
HAL_FMAC_FilterStart(FMAC_HandleTypeDef * hfmac,int16_t * pOutput,uint16_t * pOutputSize)879 HAL_StatusTypeDef HAL_FMAC_FilterStart(FMAC_HandleTypeDef *hfmac, int16_t *pOutput, uint16_t *pOutputSize)
880 {
881   uint32_t tmpcr = 0U;
882   HAL_StatusTypeDef status;
883 
884   /* Check the START bit state */
885   if (FMAC_GET_START_BIT(hfmac) != 0U)
886   {
887     return HAL_ERROR;
888   }
889 
890   /* Check that a valid configuration was done previously */
891   if (hfmac->FilterParam == 0U)
892   {
893     return HAL_ERROR;
894   }
895 
896   /* Check handle state is ready */
897   if (hfmac->State == HAL_FMAC_STATE_READY)
898   {
899     /* Change the FMAC state */
900     hfmac->State = HAL_FMAC_STATE_BUSY;
901 
902     /* CR: Configure the input access (error interruptions enabled only for IT or DMA) */
903     if (hfmac->InputAccess == FMAC_BUFFER_ACCESS_DMA)
904     {
905       tmpcr |= FMAC_DMA_WEN;
906     }
907     else if (hfmac->InputAccess == FMAC_BUFFER_ACCESS_IT)
908     {
909       tmpcr |= FMAC_IT_WIEN;
910     }
911     else
912     {
913       /* nothing to do */
914     }
915 
916     /* CR: Configure the output access (error interruptions enabled only for IT or DMA) */
917     if (hfmac->OutputAccess == FMAC_BUFFER_ACCESS_DMA)
918     {
919       tmpcr |= FMAC_DMA_REN;
920     }
921     else if (hfmac->OutputAccess == FMAC_BUFFER_ACCESS_IT)
922     {
923       tmpcr |= FMAC_IT_RIEN;
924     }
925     else
926     {
927       /* nothing to do */
928     }
929 
930     /* CR: Write the configuration */
931     MODIFY_REG(hfmac->Instance->CR, \
932                FMAC_IT_RIEN | FMAC_IT_WIEN | FMAC_DMA_REN | FMAC_CR_DMAWEN, \
933                tmpcr);
934 
935     /* Register the new output buffer */
936     status = FMAC_ConfigFilterOutputBufferUpdateState(hfmac, pOutput, pOutputSize);
937 
938     if (status == HAL_OK)
939     {
940       /* PARAM: Start the filter ( this can generate interrupts before the end of the HAL_FMAC_FilterStart ) */
941       WRITE_REG(hfmac->Instance->PARAM, (uint32_t)(hfmac->FilterParam));
942     }
943 
944     /* Reset the busy flag (do not overwrite the possible write and read flag) */
945     hfmac->State = HAL_FMAC_STATE_READY;
946   }
947   else
948   {
949     status = HAL_ERROR;
950   }
951 
952   return status;
953 }
954 
955 /**
956   * @brief  Provide a new input buffer that will be loaded into the FMAC input memory area.
957   * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
958   *         the configuration information for FMAC module.
959   * @param  pInput New input vector (additional input data).
960   * @param  pInputSize Size of the input vector (if all the data can't be
961   *         written, it will be updated with the number of data read from FMAC).
962   * @retval HAL_StatusTypeDef HAL status
963   */
HAL_FMAC_AppendFilterData(FMAC_HandleTypeDef * hfmac,int16_t * pInput,uint16_t * pInputSize)964 HAL_StatusTypeDef HAL_FMAC_AppendFilterData(FMAC_HandleTypeDef *hfmac, int16_t *pInput, uint16_t *pInputSize)
965 {
966   HAL_StatusTypeDef status;
967 
968   /* Check the function parameters */
969   if ((pInput == NULL) || (pInputSize == NULL))
970   {
971     return HAL_ERROR;
972   }
973   if (*pInputSize == 0U)
974   {
975     return HAL_ERROR;
976   }
977 
978   /* Check the START bit state */
979   if (FMAC_GET_START_BIT(hfmac) == 0U)
980   {
981     return HAL_ERROR;
982   }
983 
984   /* Check the FMAC configuration */
985   if (hfmac->InputAccess == FMAC_BUFFER_ACCESS_NONE)
986   {
987     return HAL_ERROR;
988   }
989 
990   /* Check whether the previous input vector has been handled */
991   if ((hfmac->pInputSize != NULL) && (hfmac->InputCurrentSize < * (hfmac->pInputSize)))
992   {
993     return HAL_ERROR;
994   }
995 
996   /* Check that FMAC was initialized and that no writing is already ongoing */
997   if (hfmac->WrState == HAL_FMAC_STATE_READY)
998   {
999     /* Register the new input buffer */
1000     status = FMAC_AppendFilterDataUpdateState(hfmac, pInput, pInputSize);
1001   }
1002   else
1003   {
1004     status = HAL_ERROR;
1005   }
1006 
1007   return status;
1008 }
1009 
1010 /**
1011   * @brief  Provide a new output buffer to be filled with the data computed by FMAC unit.
1012   * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
1013   *         the configuration information for FMAC module.
1014   * @param  pOutput New output vector.
1015   * @param  pOutputSize Size of the output vector (if the vector can't
1016   *         be entirely filled, pOutputSize will be updated with the number
1017   *         of data read from FMAC).
1018   * @retval HAL_StatusTypeDef HAL status
1019   */
HAL_FMAC_ConfigFilterOutputBuffer(FMAC_HandleTypeDef * hfmac,int16_t * pOutput,uint16_t * pOutputSize)1020 HAL_StatusTypeDef HAL_FMAC_ConfigFilterOutputBuffer(FMAC_HandleTypeDef *hfmac, int16_t *pOutput, uint16_t *pOutputSize)
1021 {
1022   HAL_StatusTypeDef status;
1023 
1024   /* Check the function parameters */
1025   if ((pOutput == NULL) || (pOutputSize == NULL))
1026   {
1027     return HAL_ERROR;
1028   }
1029   if (*pOutputSize == 0U)
1030   {
1031     return HAL_ERROR;
1032   }
1033 
1034   /* Check the START bit state */
1035   if (FMAC_GET_START_BIT(hfmac) == 0U)
1036   {
1037     return HAL_ERROR;
1038   }
1039 
1040   /* Check the FMAC configuration */
1041   if (hfmac->OutputAccess == FMAC_BUFFER_ACCESS_NONE)
1042   {
1043     return HAL_ERROR;
1044   }
1045 
1046   /* Check whether the previous output vector has been handled */
1047   if ((hfmac->pOutputSize != NULL) && (hfmac->OutputCurrentSize < * (hfmac->pOutputSize)))
1048   {
1049     return HAL_ERROR;
1050   }
1051 
1052   /* Check that FMAC was initialized and that not reading is already ongoing */
1053   if (hfmac->RdState == HAL_FMAC_STATE_READY)
1054   {
1055     /* Register the new output buffer */
1056     status = FMAC_ConfigFilterOutputBufferUpdateState(hfmac, pOutput, pOutputSize);
1057   }
1058   else
1059   {
1060     status = HAL_ERROR;
1061   }
1062 
1063   return status;
1064 }
1065 
1066 /**
1067   * @brief  Handle the input and/or output data in polling mode
1068   * @note   This function writes the previously provided user's input data and
1069   *         fills the previously provided user's output buffer,
1070   *         according to the existing FMAC configuration (polling mode only).
1071   *         The function returns when the input data has been handled or
1072   *         when the output data is filled. The possible unused data isn't
1073   *         kept. It will be up to the user to handle it. The previously
1074   *         provided pInputSize and pOutputSize will be used to indicate to the
1075   *         size of the read/written data to the user.
1076   * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
1077   *         the configuration information for FMAC module.
1078   * @param  Timeout timeout value.
1079   * @retval HAL_StatusTypeDef HAL status
1080   */
HAL_FMAC_PollFilterData(FMAC_HandleTypeDef * hfmac,uint32_t Timeout)1081 HAL_StatusTypeDef HAL_FMAC_PollFilterData(FMAC_HandleTypeDef *hfmac, uint32_t Timeout)
1082 {
1083   uint32_t tickstart;
1084   uint8_t inpolling;
1085   uint8_t inpollingover = POLLING_NOT_STOPPED;
1086   uint8_t outpolling;
1087   uint8_t outpollingover = POLLING_NOT_STOPPED;
1088   HAL_StatusTypeDef status;
1089 
1090   /* Check the START bit state */
1091   if (FMAC_GET_START_BIT(hfmac) == 0U)
1092   {
1093     return HAL_ERROR;
1094   }
1095 
1096   /* Check the configuration */
1097 
1098   /* Get the input and output mode (if no buffer was previously provided, nothing will be read/written) */
1099   if ((hfmac->InputAccess  == FMAC_BUFFER_ACCESS_POLLING) && (hfmac->pInput  != NULL))
1100   {
1101     inpolling = POLLING_ENABLED;
1102   }
1103   else
1104   {
1105     inpolling = POLLING_DISABLED;
1106   }
1107   if ((hfmac->OutputAccess == FMAC_BUFFER_ACCESS_POLLING) && (hfmac->pOutput != NULL))
1108   {
1109     outpolling = POLLING_ENABLED;
1110   }
1111   else
1112   {
1113     outpolling = POLLING_DISABLED;
1114   }
1115 
1116   /* Check the configuration */
1117   if ((inpolling == POLLING_DISABLED) && (outpolling == POLLING_DISABLED))
1118   {
1119     return HAL_ERROR;
1120   }
1121 
1122   /* Check handle state is ready */
1123   if (hfmac->State == HAL_FMAC_STATE_READY)
1124   {
1125     /* Change the FMAC state */
1126     hfmac->State = HAL_FMAC_STATE_BUSY;
1127 
1128     /* Get tick */
1129     tickstart = HAL_GetTick();
1130 
1131     /* Loop on reading and writing until timeout */
1132     while ((HAL_GetTick() - tickstart) < Timeout)
1133     {
1134       /* X1: Check the mode: polling or none */
1135       if (inpolling != POLLING_DISABLED)
1136       {
1137         FMAC_WriteDataIncrementPtr(hfmac, MAX_FILTER_DATA_SIZE_TO_HANDLE);
1138         if (hfmac->InputCurrentSize == *(hfmac->pInputSize))
1139         {
1140           inpollingover = POLLING_STOPPED;
1141         }
1142       }
1143 
1144       /* Y: Check the mode: polling or none */
1145       if (outpolling != POLLING_DISABLED)
1146       {
1147         FMAC_ReadDataIncrementPtr(hfmac, MAX_FILTER_DATA_SIZE_TO_HANDLE);
1148         if (hfmac->OutputCurrentSize == *(hfmac->pOutputSize))
1149         {
1150           outpollingover = POLLING_STOPPED;
1151         }
1152       }
1153 
1154       /* Exit if there isn't data to handle anymore on one side or another */
1155       if ((inpollingover != POLLING_NOT_STOPPED) || (outpollingover != POLLING_NOT_STOPPED))
1156       {
1157         break;
1158       }
1159     }
1160 
1161     /* Change the FMAC state; update the input and output sizes; reset the indexes */
1162     if (inpolling != POLLING_DISABLED)
1163     {
1164       (*(hfmac->pInputSize))  = hfmac->InputCurrentSize;
1165       FMAC_ResetInputStateAndDataPointers(hfmac);
1166     }
1167     if (outpolling != POLLING_DISABLED)
1168     {
1169       (*(hfmac->pOutputSize)) = hfmac->OutputCurrentSize;
1170       FMAC_ResetOutputStateAndDataPointers(hfmac);
1171     }
1172 
1173     /* Reset the busy flag (do not overwrite the possible write and read flag) */
1174     hfmac->State = HAL_FMAC_STATE_READY;
1175 
1176     if ((HAL_GetTick() - tickstart) >= Timeout)
1177     {
1178       hfmac->ErrorCode |= HAL_FMAC_ERROR_TIMEOUT;
1179       status = HAL_ERROR;
1180     }
1181     else
1182     {
1183       status = HAL_OK;
1184     }
1185   }
1186   else
1187   {
1188     status = HAL_ERROR;
1189   }
1190 
1191   return status;
1192 }
1193 
1194 /**
1195   * @brief  Stop the FMAC processing.
1196   * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
1197   *         the configuration information for FMAC module.
1198   * @retval HAL_StatusTypeDef HAL status
1199   */
HAL_FMAC_FilterStop(FMAC_HandleTypeDef * hfmac)1200 HAL_StatusTypeDef HAL_FMAC_FilterStop(FMAC_HandleTypeDef *hfmac)
1201 {
1202   HAL_StatusTypeDef status = HAL_OK;
1203 
1204   /* Check handle state is ready */
1205   if (hfmac->State == HAL_FMAC_STATE_READY)
1206   {
1207     /* Change the FMAC state */
1208     hfmac->State = HAL_FMAC_STATE_BUSY;
1209 
1210     /* Set the START bit to 0 (stop the previously configured filter) */
1211     CLEAR_BIT(hfmac->Instance->PARAM, FMAC_PARAM_START);
1212 
1213     /* Disable the interrupts in order to avoid crossing cases */
1214     CLEAR_BIT(hfmac->Instance->CR, FMAC_DMA_REN | FMAC_DMA_WEN | FMAC_IT_RIEN | FMAC_IT_WIEN);
1215 
1216     /* In case of IT, update the sizes */
1217     if ((hfmac->InputAccess == FMAC_BUFFER_ACCESS_IT) && (hfmac->pInput != NULL))
1218     {
1219       (*(hfmac->pInputSize))  = hfmac->InputCurrentSize;
1220     }
1221 
1222     if ((hfmac->OutputAccess == FMAC_BUFFER_ACCESS_IT) && (hfmac->pOutput != NULL))
1223     {
1224       (*(hfmac->pOutputSize)) = hfmac->OutputCurrentSize;
1225     }
1226 
1227     if (hfmac->InputAccess == FMAC_BUFFER_ACCESS_DMA)
1228     {
1229       /* Disable the DMA stream managing FMAC input data */
1230       status = HAL_DMA_Abort_IT(hfmac->hdmaIn);
1231     }
1232 
1233     if ((hfmac->OutputAccess == FMAC_BUFFER_ACCESS_DMA) && (status == HAL_OK))
1234     {
1235       /* Disable the DMA stream managing FMAC output data */
1236       status = HAL_DMA_Abort_IT(hfmac->hdmaOut);
1237     }
1238 
1239     /* Reset FMAC unit (internal pointers) */
1240     if (FMAC_Reset(hfmac) == HAL_ERROR)
1241     {
1242       /* Update FMAC error code and FMAC peripheral state */
1243       hfmac->ErrorCode = HAL_FMAC_ERROR_RESET;
1244       hfmac->State = HAL_FMAC_STATE_TIMEOUT;
1245       status = HAL_ERROR;
1246     }
1247     else
1248     {
1249       /* Reset the data pointers */
1250       FMAC_ResetDataPointers(hfmac);
1251     }
1252 
1253     /* Reset the busy flag */
1254     hfmac->State = HAL_FMAC_STATE_READY;
1255   }
1256   else
1257   {
1258     status = HAL_ERROR;
1259   }
1260 
1261   return status;
1262 }
1263 
1264 /**
1265   * @}
1266   */
1267 
1268 /** @defgroup FMAC_Exported_Functions_Group3 Callback functions
1269   * @brief    Callback functions.
1270   *
1271 @verbatim
1272   ==============================================================================
1273                       ##### Callback functions  #####
1274   ==============================================================================
1275     [..]  This section provides Interruption and DMA callback functions:
1276       (+) DMA or Interrupt: the user's input data is half written (DMA only)
1277           or completely written.
1278       (+) DMA or Interrupt: the user's output buffer is half filled (DMA only)
1279           or completely filled.
1280       (+) DMA or Interrupt: error handling.
1281 
1282 @endverbatim
1283   * @{
1284   */
1285 
1286 /**
1287   * @brief  FMAC error callback.
1288   * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
1289   *         the configuration information for FMAC module.
1290   * @retval None
1291   */
HAL_FMAC_ErrorCallback(FMAC_HandleTypeDef * hfmac)1292 __weak void HAL_FMAC_ErrorCallback(FMAC_HandleTypeDef *hfmac)
1293 {
1294   /* Prevent unused argument(s) compilation warning */
1295   UNUSED(hfmac);
1296 
1297   /* NOTE : This function should not be modified; when the callback is needed,
1298             the HAL_FMAC_ErrorCallback can be implemented in the user file.
1299    */
1300 }
1301 
1302 /**
1303   * @brief  FMAC get half data callback.
1304   * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
1305   *         the configuration information for FMAC module.
1306   * @retval None
1307   */
HAL_FMAC_HalfGetDataCallback(FMAC_HandleTypeDef * hfmac)1308 __weak void HAL_FMAC_HalfGetDataCallback(FMAC_HandleTypeDef *hfmac)
1309 {
1310   /* Prevent unused argument(s) compilation warning */
1311   UNUSED(hfmac);
1312 
1313   /* NOTE : This function should not be modified; when the callback is needed,
1314             the HAL_FMAC_HalfGetDataCallback can be implemented in the user file.
1315    */
1316 }
1317 
1318 /**
1319   * @brief  FMAC get data callback.
1320   * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
1321   *         the configuration information for FMAC module.
1322   * @retval None
1323   */
HAL_FMAC_GetDataCallback(FMAC_HandleTypeDef * hfmac)1324 __weak void HAL_FMAC_GetDataCallback(FMAC_HandleTypeDef *hfmac)
1325 {
1326   /* Prevent unused argument(s) compilation warning */
1327   UNUSED(hfmac);
1328 
1329   /* NOTE : This function should not be modified; when the callback is needed,
1330             the HAL_FMAC_GetDataCallback can be implemented in the user file.
1331    */
1332 }
1333 
1334 /**
1335   * @brief  FMAC half output data ready callback.
1336   * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
1337   *         the configuration information for FMAC module.
1338   * @retval None
1339   */
HAL_FMAC_HalfOutputDataReadyCallback(FMAC_HandleTypeDef * hfmac)1340 __weak void HAL_FMAC_HalfOutputDataReadyCallback(FMAC_HandleTypeDef *hfmac)
1341 {
1342   /* Prevent unused argument(s) compilation warning */
1343   UNUSED(hfmac);
1344 
1345   /* NOTE : This function should not be modified; when the callback is needed,
1346             the HAL_FMAC_HalfOutputDataReadyCallback can be implemented in the user file.
1347    */
1348 }
1349 
1350 /**
1351   * @brief  FMAC output data ready callback.
1352   * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
1353   *         the configuration information for FMAC module.
1354   * @retval None
1355   */
HAL_FMAC_OutputDataReadyCallback(FMAC_HandleTypeDef * hfmac)1356 __weak void HAL_FMAC_OutputDataReadyCallback(FMAC_HandleTypeDef *hfmac)
1357 {
1358   /* Prevent unused argument(s) compilation warning */
1359   UNUSED(hfmac);
1360 
1361   /* NOTE : This function should not be modified; when the callback is needed,
1362             the HAL_FMAC_OutputDataReadyCallback can be implemented in the user file.
1363    */
1364 }
1365 
1366 /**
1367   * @brief  FMAC filter configuration callback.
1368   * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
1369   *         the configuration information for FMAC module.
1370   * @retval None
1371   */
HAL_FMAC_FilterConfigCallback(FMAC_HandleTypeDef * hfmac)1372 __weak void HAL_FMAC_FilterConfigCallback(FMAC_HandleTypeDef *hfmac)
1373 {
1374   /* Prevent unused argument(s) compilation warning */
1375   UNUSED(hfmac);
1376 
1377   /* NOTE : This function should not be modified; when the callback is needed,
1378             the HAL_FMAC_FilterConfigCallback can be implemented in the user file.
1379    */
1380 }
1381 
1382 /**
1383   * @brief  FMAC filter preload callback.
1384   * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
1385   *         the configuration information for FMAC module.
1386   * @retval None
1387   */
HAL_FMAC_FilterPreloadCallback(FMAC_HandleTypeDef * hfmac)1388 __weak void HAL_FMAC_FilterPreloadCallback(FMAC_HandleTypeDef *hfmac)
1389 {
1390   /* Prevent unused argument(s) compilation warning */
1391   UNUSED(hfmac);
1392 
1393   /* NOTE : This function should not be modified; when the callback is needed,
1394             the HAL_FMAC_FilterPreloadCallback can be implemented in the user file.
1395    */
1396 }
1397 
1398 /**
1399   * @}
1400   */
1401 
1402 /** @defgroup FMAC_Exported_Functions_Group4 IRQ handler management
1403   * @brief    IRQ handler.
1404   *
1405 @verbatim
1406   ==============================================================================
1407                 ##### IRQ handler management #####
1408   ==============================================================================
1409 [..]  This section provides IRQ handler function.
1410 
1411 @endverbatim
1412   * @{
1413   */
1414 
1415 /**
1416   * @brief  Handle FMAC interrupt request.
1417   * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
1418   *         the configuration information for FMAC module.
1419   * @retval None
1420   */
HAL_FMAC_IRQHandler(FMAC_HandleTypeDef * hfmac)1421 void HAL_FMAC_IRQHandler(FMAC_HandleTypeDef *hfmac)
1422 {
1423   uint32_t itsource;
1424 
1425   /* Check if the read interrupt is enabled and if Y buffer empty flag isn't set */
1426   itsource = __HAL_FMAC_GET_IT_SOURCE(hfmac, FMAC_IT_RIEN);
1427   if ((__HAL_FMAC_GET_FLAG(hfmac, FMAC_FLAG_YEMPTY) == 0U) && (itsource != 0U))
1428   {
1429     /* Read some data if possible (Y size is used as a pseudo timeout in order
1430        to not get stuck too long under IT if FMAC keeps on processing input
1431        data reloaded via DMA for instance). */
1432     if (hfmac->pOutput != NULL)
1433     {
1434       FMAC_ReadDataIncrementPtr(hfmac, (uint16_t)FMAC_GET_Y_SIZE(hfmac));
1435     }
1436 
1437     /* Indicate that data is ready to be read */
1438     if ((hfmac->pOutput == NULL) || (hfmac->OutputCurrentSize == *(hfmac->pOutputSize)))
1439     {
1440       /* Reset the pointers to indicate new data will be needed */
1441       FMAC_ResetOutputStateAndDataPointers(hfmac);
1442 
1443       /* Call the output data ready callback */
1444 #if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1)
1445       hfmac->OutputDataReadyCallback(hfmac);
1446 #else
1447       HAL_FMAC_OutputDataReadyCallback(hfmac);
1448 #endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */
1449     }
1450   }
1451 
1452   /* Check if the write interrupt is enabled and if X1 buffer full flag isn't set */
1453   itsource = __HAL_FMAC_GET_IT_SOURCE(hfmac, FMAC_IT_WIEN);
1454   if ((__HAL_FMAC_GET_FLAG(hfmac, FMAC_FLAG_X1FULL) == 0U) && (itsource != 0U))
1455   {
1456     /* Write some data if possible (X1 size is used as a pseudo timeout in order
1457        to not get stuck too long under IT if FMAC keep on processing input
1458        data whereas its output emptied via DMA for instance). */
1459     if (hfmac->pInput != NULL)
1460     {
1461       FMAC_WriteDataIncrementPtr(hfmac, (uint16_t)FMAC_GET_X1_SIZE(hfmac));
1462     }
1463 
1464     /* Indicate that new data will be needed */
1465     if ((hfmac->pInput == NULL) || (hfmac->InputCurrentSize == *(hfmac->pInputSize)))
1466     {
1467       /* Reset the pointers to indicate new data will be needed */
1468       FMAC_ResetInputStateAndDataPointers(hfmac);
1469 
1470       /* Call the get data callback */
1471 #if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1)
1472       hfmac->GetDataCallback(hfmac);
1473 #else
1474       HAL_FMAC_GetDataCallback(hfmac);
1475 #endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */
1476     }
1477   }
1478 
1479   /* Check if the overflow error interrupt is enabled and if overflow error flag is raised */
1480   itsource = __HAL_FMAC_GET_IT_SOURCE(hfmac, FMAC_IT_OVFLIEN);
1481   if ((__HAL_FMAC_GET_FLAG(hfmac, FMAC_FLAG_OVFL) != 0U) && (itsource != 0U))
1482   {
1483     hfmac->ErrorCode |= HAL_FMAC_ERROR_OVFL;
1484   }
1485 
1486   /* Check if the underflow error interrupt is enabled and if underflow error flag is raised */
1487   itsource = __HAL_FMAC_GET_IT_SOURCE(hfmac, FMAC_IT_UNFLIEN);
1488   if ((__HAL_FMAC_GET_FLAG(hfmac, FMAC_FLAG_UNFL) != 0U) && (itsource != 0U))
1489   {
1490     hfmac->ErrorCode |= HAL_FMAC_ERROR_UNFL;
1491   }
1492 
1493   /* Check if the saturation error interrupt is enabled and if saturation error flag is raised */
1494   itsource = __HAL_FMAC_GET_IT_SOURCE(hfmac, FMAC_IT_SATIEN);
1495   if ((__HAL_FMAC_GET_FLAG(hfmac, FMAC_FLAG_SAT) != 0U) && (itsource != 0U))
1496   {
1497     hfmac->ErrorCode |= HAL_FMAC_ERROR_SAT;
1498   }
1499 
1500   /* Call the error callback if an error occurred */
1501   if (hfmac->ErrorCode != HAL_FMAC_ERROR_NONE)
1502   {
1503     /* Call the error callback */
1504 #if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1)
1505     hfmac->ErrorCallback(hfmac);
1506 #else
1507     HAL_FMAC_ErrorCallback(hfmac);
1508 #endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */
1509   }
1510 }
1511 
1512 /**
1513   * @}
1514   */
1515 
1516 /** @defgroup FMAC_Exported_Functions_Group5 Peripheral State and Error functions
1517   * @brief    Peripheral State and Error functions.
1518   *
1519 @verbatim
1520   ==============================================================================
1521                  ##### Peripheral State and Error functions #####
1522   ==============================================================================
1523     [..]  This subsection provides functions allowing to
1524       (+) Check the FMAC state
1525       (+) Get error code
1526 
1527 @endverbatim
1528   * @{
1529   */
1530 
1531 /**
1532   * @brief  Return the FMAC state.
1533   * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
1534   *         the configuration information for FMAC module.
1535   * @retval HAL_FMAC_StateTypeDef FMAC state
1536   */
HAL_FMAC_GetState(const FMAC_HandleTypeDef * hfmac)1537 HAL_FMAC_StateTypeDef HAL_FMAC_GetState(const FMAC_HandleTypeDef *hfmac)
1538 {
1539   /* Return FMAC state */
1540   return hfmac->State;
1541 }
1542 
1543 /**
1544   * @brief  Return the FMAC peripheral error.
1545   * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
1546   *         the configuration information for FMAC module.
1547   * @note   The returned error is a bit-map combination of possible errors.
1548   * @retval uint32_t Error bit-map based on @ref FMAC_Error_Code
1549   */
HAL_FMAC_GetError(const FMAC_HandleTypeDef * hfmac)1550 uint32_t HAL_FMAC_GetError(const FMAC_HandleTypeDef *hfmac)
1551 {
1552   /* Return FMAC error code */
1553   return hfmac->ErrorCode;
1554 }
1555 
1556 /**
1557   * @}
1558   */
1559 
1560 /**
1561   * @}
1562   */
1563 
1564 /** @defgroup FMAC_Private_Functions FMAC Private Functions
1565   * @{
1566   */
1567 
1568 /**
1569   ==============================================================================
1570                        ##### FMAC Private Functions #####
1571   ==============================================================================
1572   */
1573 /**
1574   * @brief  Perform a reset of the FMAC unit.
1575   * @param  hfmac FMAC handle.
1576   * @retval HAL_StatusTypeDef HAL status
1577   */
FMAC_Reset(FMAC_HandleTypeDef * hfmac)1578 static HAL_StatusTypeDef FMAC_Reset(FMAC_HandleTypeDef *hfmac)
1579 {
1580   uint32_t tickstart;
1581 
1582   /* Init tickstart for timeout management*/
1583   tickstart = HAL_GetTick();
1584 
1585   /* Perform the reset */
1586   SET_BIT(hfmac->Instance->CR, FMAC_CR_RESET);
1587 
1588   /* Wait until flag is reset */
1589   while (READ_BIT(hfmac->Instance->CR, FMAC_CR_RESET) != 0U)
1590   {
1591     if ((HAL_GetTick() - tickstart) > HAL_FMAC_RESET_TIMEOUT_VALUE)
1592     {
1593       hfmac->ErrorCode |= HAL_FMAC_ERROR_TIMEOUT;
1594       return HAL_ERROR;
1595     }
1596   }
1597 
1598   hfmac->ErrorCode = HAL_FMAC_ERROR_NONE;
1599   return HAL_OK;
1600 }
1601 
1602 /**
1603   * @brief  Reset the data pointers of the FMAC unit.
1604   * @param  hfmac FMAC handle.
1605   * @retval None
1606   */
FMAC_ResetDataPointers(FMAC_HandleTypeDef * hfmac)1607 static void FMAC_ResetDataPointers(FMAC_HandleTypeDef *hfmac)
1608 {
1609   FMAC_ResetInputStateAndDataPointers(hfmac);
1610   FMAC_ResetOutputStateAndDataPointers(hfmac);
1611 }
1612 
1613 /**
1614   * @brief  Reset the input data pointers of the FMAC unit.
1615   * @param  hfmac FMAC handle.
1616   * @retval None
1617   */
FMAC_ResetInputStateAndDataPointers(FMAC_HandleTypeDef * hfmac)1618 static void FMAC_ResetInputStateAndDataPointers(FMAC_HandleTypeDef *hfmac)
1619 {
1620   hfmac->pInput = NULL;
1621   hfmac->pInputSize = NULL;
1622   hfmac->InputCurrentSize = 0U;
1623   hfmac->WrState = HAL_FMAC_STATE_READY;
1624 }
1625 
1626 /**
1627   * @brief  Reset the output data pointers of the FMAC unit.
1628   * @param  hfmac FMAC handle.
1629   * @retval None
1630   */
FMAC_ResetOutputStateAndDataPointers(FMAC_HandleTypeDef * hfmac)1631 static void FMAC_ResetOutputStateAndDataPointers(FMAC_HandleTypeDef *hfmac)
1632 {
1633   hfmac->pOutput = NULL;
1634   hfmac->pOutputSize = NULL;
1635   hfmac->OutputCurrentSize = 0U;
1636   hfmac->RdState = HAL_FMAC_STATE_READY;
1637 }
1638 
1639 /**
1640   * @brief  Configure the FMAC filter.
1641   * @note   The configuration is done according to the parameters
1642   *         specified in the FMAC_FilterConfigTypeDef structure.
1643   * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
1644   *         the configuration information for FMAC module.
1645   * @param  pConfig pointer to a FMAC_FilterConfigTypeDef structure that
1646   *         contains the FMAC configuration information.
1647   * @param  PreloadAccess access mode used for the preload (polling or DMA).
1648   * @retval HAL_StatusTypeDef HAL status
1649   */
FMAC_FilterConfig(FMAC_HandleTypeDef * hfmac,FMAC_FilterConfigTypeDef * pConfig,uint8_t PreloadAccess)1650 static HAL_StatusTypeDef FMAC_FilterConfig(FMAC_HandleTypeDef *hfmac, FMAC_FilterConfigTypeDef *pConfig,
1651                                            uint8_t PreloadAccess)
1652 {
1653   uint32_t tickstart;
1654   uint32_t tmpcr;
1655   HAL_StatusTypeDef status;
1656 #if defined(USE_FULL_ASSERT)
1657   uint32_t x2size;
1658 #endif /* USE_FULL_ASSERT */
1659 
1660   /* Check the parameters */
1661   assert_param(IS_FMAC_THRESHOLD(pConfig->InputThreshold));
1662   assert_param(IS_FMAC_THRESHOLD(pConfig->OutputThreshold));
1663   assert_param(IS_FMAC_BUFFER_ACCESS(pConfig->InputAccess));
1664   assert_param(IS_FMAC_BUFFER_ACCESS(pConfig->OutputAccess));
1665   assert_param(IS_FMAC_CLIP_STATE(pConfig->Clip));
1666   assert_param(IS_FMAC_FILTER_FUNCTION(pConfig->Filter));
1667   assert_param(IS_FMAC_PARAM_P(pConfig->Filter, pConfig->P));
1668   assert_param(IS_FMAC_PARAM_Q(pConfig->Filter, pConfig->Q));
1669   assert_param(IS_FMAC_PARAM_R(pConfig->Filter, pConfig->R));
1670 
1671   /* Check the START bit state */
1672   if (FMAC_GET_START_BIT(hfmac) != 0U)
1673   {
1674     return HAL_ERROR;
1675   }
1676 
1677   /* Check handle state is ready */
1678   if (hfmac->State != HAL_FMAC_STATE_READY)
1679   {
1680     return HAL_ERROR;
1681   }
1682 
1683   /* Change the FMAC state */
1684   hfmac->State = HAL_FMAC_STATE_BUSY;
1685 
1686   /* Get tick */
1687   tickstart = HAL_GetTick();
1688 
1689   /* Indicate that there is no valid configuration done */
1690   hfmac->FilterParam = 0U;
1691 
1692   /* FMAC_X1BUFCFG: Configure the input buffer within the internal memory if required */
1693   if (pConfig->InputBufferSize != 0U)
1694   {
1695     MODIFY_REG(hfmac->Instance->X1BUFCFG,                                                                   \
1696                (FMAC_X1BUFCFG_X1_BASE | FMAC_X1BUFCFG_X1_BUF_SIZE),                                         \
1697                (((((uint32_t)(pConfig->InputBaseAddress)) << FMAC_X1BUFCFG_X1_BASE_Pos)     & FMAC_X1BUFCFG_X1_BASE) | \
1698                 ((((uint32_t)(pConfig->InputBufferSize))  << FMAC_X1BUFCFG_X1_BUF_SIZE_Pos) & \
1699                  FMAC_X1BUFCFG_X1_BUF_SIZE)));
1700   }
1701 
1702   /* FMAC_X1BUFCFG: Configure the input threshold if valid when compared to the configured X1 size */
1703   if (pConfig->InputThreshold != FMAC_THRESHOLD_NO_VALUE)
1704   {
1705     /* Check the parameter */
1706     assert_param(IS_FMAC_THRESHOLD_APPLICABLE(FMAC_GET_X1_SIZE(hfmac), pConfig->InputThreshold, pConfig->InputAccess));
1707 
1708     MODIFY_REG(hfmac->Instance->X1BUFCFG, \
1709                FMAC_X1BUFCFG_FULL_WM,     \
1710                ((pConfig->InputThreshold) & FMAC_X1BUFCFG_FULL_WM));
1711   }
1712 
1713   /* FMAC_X2BUFCFG: Configure the coefficient buffer within the internal memory */
1714   if (pConfig->CoeffBufferSize != 0U)
1715   {
1716     MODIFY_REG(hfmac->Instance->X2BUFCFG,                                                                   \
1717                (FMAC_X2BUFCFG_X2_BASE | FMAC_X2BUFCFG_X2_BUF_SIZE),                                         \
1718                (((((uint32_t)(pConfig->CoeffBaseAddress)) << FMAC_X2BUFCFG_X2_BASE_Pos)     & FMAC_X2BUFCFG_X2_BASE) | \
1719                 ((((uint32_t)(pConfig->CoeffBufferSize))  << FMAC_X2BUFCFG_X2_BUF_SIZE_Pos) &\
1720                  FMAC_X2BUFCFG_X2_BUF_SIZE)));
1721   }
1722 
1723   /* FMAC_YBUFCFG: Configure the output buffer within the internal memory if required */
1724   if (pConfig->OutputBufferSize != 0U)
1725   {
1726     MODIFY_REG(hfmac->Instance->YBUFCFG,                                                                    \
1727                (FMAC_YBUFCFG_Y_BASE | FMAC_YBUFCFG_Y_BUF_SIZE),                                             \
1728                (((((uint32_t)(pConfig->OutputBaseAddress)) << FMAC_YBUFCFG_Y_BASE_Pos)     & FMAC_YBUFCFG_Y_BASE) |    \
1729                 ((((uint32_t)(pConfig->OutputBufferSize))  << FMAC_YBUFCFG_Y_BUF_SIZE_Pos) & FMAC_YBUFCFG_Y_BUF_SIZE)));
1730   }
1731 
1732   /* FMAC_YBUFCFG: Configure the output threshold if valid when compared to the configured Y size */
1733   if (pConfig->OutputThreshold != FMAC_THRESHOLD_NO_VALUE)
1734   {
1735     /* Check the parameter */
1736     assert_param(IS_FMAC_THRESHOLD_APPLICABLE(FMAC_GET_Y_SIZE(hfmac), pConfig->OutputThreshold, pConfig->OutputAccess));
1737 
1738     MODIFY_REG(hfmac->Instance->YBUFCFG, \
1739                FMAC_YBUFCFG_EMPTY_WM,    \
1740                ((pConfig->OutputThreshold) & FMAC_YBUFCFG_EMPTY_WM));
1741   }
1742 
1743   /* FMAC_CR: Configure the clip feature */
1744   tmpcr = pConfig->Clip & FMAC_CR_CLIPEN;
1745 
1746   /* FMAC_CR: If IT or DMA will be used, enable error interrupts.
1747     * Being more a debugging feature, FMAC_CR_SATIEN isn't enabled by default. */
1748   if ((pConfig->InputAccess  == FMAC_BUFFER_ACCESS_DMA) || (pConfig->InputAccess  == FMAC_BUFFER_ACCESS_IT) ||
1749       (pConfig->OutputAccess == FMAC_BUFFER_ACCESS_DMA) || (pConfig->OutputAccess == FMAC_BUFFER_ACCESS_IT))
1750   {
1751     tmpcr |= FMAC_IT_UNFLIEN | FMAC_IT_OVFLIEN;
1752   }
1753 
1754   /* FMAC_CR: write the value */
1755   WRITE_REG(hfmac->Instance->CR, tmpcr);
1756 
1757   /* Save the input/output accesses in order to configure RIEN, WIEN, DMAREN and DMAWEN during filter start */
1758   hfmac->InputAccess = pConfig->InputAccess;
1759   hfmac->OutputAccess = pConfig->OutputAccess;
1760 
1761   /* Check whether the configured X2 is big enough for the filter */
1762 #if defined(USE_FULL_ASSERT)
1763   x2size = FMAC_GET_X2_SIZE(hfmac);
1764 #endif /* USE_FULL_ASSERT */
1765   assert_param(((pConfig->Filter == FMAC_FUNC_CONVO_FIR) && (x2size >= pConfig->P)) || \
1766                ((pConfig->Filter == FMAC_FUNC_IIR_DIRECT_FORM_1) && \
1767                 (x2size >= ((uint32_t)pConfig->P + (uint32_t)pConfig->Q))));
1768 
1769   /* Build the PARAM value that will be used when starting the filter */
1770   hfmac->FilterParam = (FMAC_PARAM_START | pConfig->Filter |                   \
1771                         ((((uint32_t)(pConfig->P)) << FMAC_PARAM_P_Pos) & FMAC_PARAM_P) | \
1772                         ((((uint32_t)(pConfig->Q)) << FMAC_PARAM_Q_Pos) & FMAC_PARAM_Q) | \
1773                         ((((uint32_t)(pConfig->R)) << FMAC_PARAM_R_Pos) & FMAC_PARAM_R));
1774 
1775   /* Initialize the coefficient buffer if required (pCoeffA for FIR only) */
1776   if ((pConfig->pCoeffB != NULL) && (pConfig->CoeffBSize != 0U))
1777   {
1778     /* FIR/IIR: The provided coefficients should match X2 size */
1779     assert_param(((uint32_t)pConfig->CoeffASize + (uint32_t)pConfig->CoeffBSize) <= x2size);
1780     /* FIR/IIR: The size of pCoeffB should match the parameter P */
1781     assert_param(pConfig->CoeffBSize >= pConfig->P);
1782     /* pCoeffA should be provided for IIR but not for FIR */
1783     /* IIR : if pCoeffB is provided, pCoeffA should also be there */
1784     /* IIR: The size of pCoeffA should match the parameter Q */
1785     assert_param(((pConfig->Filter == FMAC_FUNC_CONVO_FIR) &&
1786                   (pConfig->pCoeffA == NULL) && (pConfig->CoeffASize == 0U)) ||
1787                  ((pConfig->Filter == FMAC_FUNC_IIR_DIRECT_FORM_1) &&
1788                   (pConfig->pCoeffA != NULL) && (pConfig->CoeffASize != 0U) &&
1789                   (pConfig->CoeffASize >= pConfig->Q)));
1790 
1791     /* Write number of values to be loaded, the data load function and start the operation */
1792     WRITE_REG(hfmac->Instance->PARAM,                      \
1793               (((uint32_t)(pConfig->CoeffBSize) << FMAC_PARAM_P_Pos) | \
1794                ((uint32_t)(pConfig->CoeffASize) << FMAC_PARAM_Q_Pos) | \
1795                FMAC_FUNC_LOAD_X2 | FMAC_PARAM_START));
1796 
1797     if (PreloadAccess == PRELOAD_ACCESS_POLLING)
1798     {
1799       /* Load the buffer into the internal memory */
1800       FMAC_WritePreloadDataIncrementPtr(hfmac, &(pConfig->pCoeffB), pConfig->CoeffBSize);
1801 
1802       /* Load pCoeffA if needed */
1803       if ((pConfig->pCoeffA != NULL) && (pConfig->CoeffASize != 0U))
1804       {
1805         /* Load the buffer into the internal memory */
1806         FMAC_WritePreloadDataIncrementPtr(hfmac, &(pConfig->pCoeffA), pConfig->CoeffASize);
1807       }
1808 
1809       /* Wait for the end of the writing */
1810       if (FMAC_WaitOnStartUntilTimeout(hfmac, tickstart, HAL_FMAC_TIMEOUT_VALUE) != HAL_OK)
1811       {
1812         hfmac->ErrorCode |= HAL_FMAC_ERROR_TIMEOUT;
1813         hfmac->State = HAL_FMAC_STATE_TIMEOUT;
1814         return HAL_ERROR;
1815       }
1816 
1817       /* Change the FMAC state */
1818       hfmac->State = HAL_FMAC_STATE_READY;
1819     }
1820     else
1821     {
1822       hfmac->pInput = pConfig->pCoeffA;
1823       hfmac->InputCurrentSize = pConfig->CoeffASize;
1824 
1825       /* Set the FMAC DMA transfer complete callback */
1826       hfmac->hdmaPreload->XferHalfCpltCallback = NULL;
1827       hfmac->hdmaPreload->XferCpltCallback = FMAC_DMAFilterConfig;
1828       /* Set the DMA error callback */
1829       hfmac->hdmaPreload->XferErrorCallback = FMAC_DMAError;
1830 
1831       /* Enable the DMA stream managing FMAC preload data write */
1832       if ((hfmac->hdmaPreload->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST)
1833       {
1834         if ((hfmac->hdmaPreload->LinkedListQueue != NULL) && (hfmac->hdmaPreload->LinkedListQueue->Head != NULL))
1835         {
1836           /* Enable the DMA channel */
1837           hfmac->hdmaPreload->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] =
1838             (uint32_t)(2UL * pConfig->CoeffBSize); /* Set DMA data size           */
1839           hfmac->hdmaPreload->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] =
1840             (uint32_t)pConfig->pCoeffB;            /* Set DMA source address      */
1841           hfmac->hdmaPreload->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] =
1842             (uint32_t)&hfmac->Instance->WDATA;     /* Set DMA destination address */
1843 
1844           status = HAL_DMAEx_List_Start_IT(hfmac->hdmaPreload);
1845         }
1846         else
1847         {
1848           /* Return error status */
1849           return HAL_ERROR;
1850         }
1851       }
1852       else
1853       {
1854         status = HAL_DMA_Start_IT(hfmac->hdmaPreload, (uint32_t)pConfig->pCoeffB, \
1855                                   (uint32_t)&hfmac->Instance->WDATA, (uint32_t)(2UL * pConfig->CoeffBSize));
1856       }
1857 
1858       if (status != HAL_OK)
1859       {
1860         /* Return error status */
1861         return HAL_ERROR;
1862       }
1863     }
1864   }
1865   else
1866   {
1867     /* Change the FMAC state */
1868     hfmac->State = HAL_FMAC_STATE_READY;
1869   }
1870 
1871   return HAL_OK;
1872 }
1873 
1874 /**
1875   * @brief  Preload the input (FIR, IIR) and output data (IIR) of the FMAC filter.
1876   * @note   The set(s) of data will be used by FMAC as soon as @ref HAL_FMAC_FilterStart is called.
1877   * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
1878   *         the configuration information for FMAC module.
1879   * @param  pInput Preloading of the first elements of the input buffer (X1).
1880   *         If not needed (no data available when starting), it should be set to NULL.
1881   * @param  InputSize Size of the input vector.
1882   *         As pInput is used for preloading data, it cannot be bigger than the input memory area.
1883   * @param  pOutput [IIR] Preloading of the first elements of the output vector (Y).
1884   *         If not needed, it should be set to NULL.
1885   * @param  OutputSize Size of the output vector.
1886   *         As pOutput is used for preloading data, it cannot be bigger than the output memory area.
1887   * @param  PreloadAccess access mode used for the preload (polling or DMA).
1888   * @note   The input and the output buffers can be filled by calling several times @ref HAL_FMAC_FilterPreload
1889   *         (each call filling partly the buffers). In case of overflow (too much data provided through
1890   *         all these calls), an error will be returned.
1891   * @retval HAL_StatusTypeDef HAL status
1892   */
FMAC_FilterPreload(FMAC_HandleTypeDef * hfmac,int16_t * pInput,uint8_t InputSize,int16_t * pOutput,uint8_t OutputSize,uint8_t PreloadAccess)1893 static HAL_StatusTypeDef FMAC_FilterPreload(FMAC_HandleTypeDef *hfmac, int16_t *pInput, uint8_t InputSize,
1894                                             int16_t *pOutput, uint8_t OutputSize, uint8_t PreloadAccess)
1895 {
1896   uint32_t tickstart;
1897   HAL_StatusTypeDef status;
1898 
1899   /* Check the START bit state */
1900   if (FMAC_GET_START_BIT(hfmac) != 0U)
1901   {
1902     return HAL_ERROR;
1903   }
1904 
1905   /* Check that a valid configuration was done previously */
1906   if (hfmac->FilterParam == 0U)
1907   {
1908     return HAL_ERROR;
1909   }
1910 
1911   /* Check the preload input buffers isn't too big */
1912   if ((InputSize > FMAC_GET_X1_SIZE(hfmac)) && (pInput != NULL))
1913   {
1914     return HAL_ERROR;
1915   }
1916 
1917   /* Check the preload output buffer isn't too big */
1918   if ((OutputSize > FMAC_GET_Y_SIZE(hfmac)) && (pOutput != NULL))
1919   {
1920     return HAL_ERROR;
1921   }
1922 
1923   /* Check handle state is ready */
1924   if (hfmac->State != HAL_FMAC_STATE_READY)
1925   {
1926     return HAL_ERROR;
1927   }
1928 
1929   /* Change the FMAC state */
1930   hfmac->State = HAL_FMAC_STATE_BUSY;
1931 
1932   /* Get tick */
1933   tickstart = HAL_GetTick();
1934 
1935   /* Preload the input buffer if required */
1936   if ((pInput != NULL) && (InputSize != 0U))
1937   {
1938     /* Write number of values to be loaded, the data load function and start the operation */
1939     WRITE_REG(hfmac->Instance->PARAM, \
1940               (((uint32_t)InputSize << FMAC_PARAM_P_Pos) | FMAC_FUNC_LOAD_X1 | FMAC_PARAM_START));
1941 
1942     if (PreloadAccess == PRELOAD_ACCESS_POLLING)
1943     {
1944       /* Load the buffer into the internal memory */
1945       FMAC_WritePreloadDataIncrementPtr(hfmac, &pInput, InputSize);
1946 
1947       /* Wait for the end of the writing */
1948       if (FMAC_WaitOnStartUntilTimeout(hfmac, tickstart, HAL_FMAC_TIMEOUT_VALUE) != HAL_OK)
1949       {
1950         hfmac->ErrorCode |= HAL_FMAC_ERROR_TIMEOUT;
1951         hfmac->State = HAL_FMAC_STATE_TIMEOUT;
1952         return HAL_ERROR;
1953       }
1954     }
1955     else
1956     {
1957       hfmac->pInput = pOutput;
1958       hfmac->InputCurrentSize = OutputSize;
1959 
1960       /* Set the FMAC DMA transfer complete callback */
1961       hfmac->hdmaPreload->XferHalfCpltCallback = NULL;
1962       hfmac->hdmaPreload->XferCpltCallback = FMAC_DMAFilterPreload;
1963       /* Set the DMA error callback */
1964       hfmac->hdmaPreload->XferErrorCallback = FMAC_DMAError;
1965 
1966       /* Enable the DMA stream managing FMAC preload data write */
1967       if ((hfmac->hdmaPreload->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST)
1968       {
1969         if ((hfmac->hdmaPreload->LinkedListQueue != NULL) && (hfmac->hdmaPreload->LinkedListQueue->Head != NULL))
1970         {
1971           /* Enable the DMA channel */
1972           hfmac->hdmaPreload->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] =
1973             (uint32_t)(2UL * InputSize);           /* Set DMA data size           */
1974           hfmac->hdmaPreload->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] =
1975             (uint32_t)pInput;                      /* Set DMA source address      */
1976           hfmac->hdmaPreload->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] =
1977             (uint32_t)&hfmac->Instance->WDATA;     /* Set DMA destination address */
1978 
1979           return (HAL_DMAEx_List_Start_IT(hfmac->hdmaPreload));
1980         }
1981         else
1982         {
1983           /* Return error status */
1984           return HAL_ERROR;
1985         }
1986       }
1987       else
1988       {
1989         return (HAL_DMA_Start_IT(hfmac->hdmaPreload, (uint32_t)pInput, \
1990                                  (uint32_t)&hfmac->Instance->WDATA, (uint32_t)(2UL * InputSize)));
1991       }
1992     }
1993   }
1994 
1995   /* Preload the output buffer if required */
1996   if ((pOutput != NULL) && (OutputSize != 0U))
1997   {
1998     /* Write number of values to be loaded, the data load function and start the operation */
1999     WRITE_REG(hfmac->Instance->PARAM, \
2000               (((uint32_t)OutputSize << FMAC_PARAM_P_Pos) | FMAC_FUNC_LOAD_Y | FMAC_PARAM_START));
2001 
2002     if (PreloadAccess == PRELOAD_ACCESS_POLLING)
2003     {
2004       /* Load the buffer into the internal memory */
2005       FMAC_WritePreloadDataIncrementPtr(hfmac, &pOutput, OutputSize);
2006 
2007       /* Wait for the end of the writing */
2008       if (FMAC_WaitOnStartUntilTimeout(hfmac, tickstart, HAL_FMAC_TIMEOUT_VALUE) != HAL_OK)
2009       {
2010         hfmac->ErrorCode |= HAL_FMAC_ERROR_TIMEOUT;
2011         hfmac->State = HAL_FMAC_STATE_TIMEOUT;
2012         return HAL_ERROR;
2013       }
2014     }
2015     else
2016     {
2017       hfmac->pInput = NULL;
2018       hfmac->InputCurrentSize = 0U;
2019 
2020       /* Set the FMAC DMA transfer complete callback */
2021       hfmac->hdmaPreload->XferHalfCpltCallback = NULL;
2022       hfmac->hdmaPreload->XferCpltCallback = FMAC_DMAFilterPreload;
2023       /* Set the DMA error callback */
2024       hfmac->hdmaPreload->XferErrorCallback = FMAC_DMAError;
2025 
2026       /* Enable the DMA stream managing FMAC preload data write */
2027       if ((hfmac->hdmaPreload->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST)
2028       {
2029         if ((hfmac->hdmaPreload->LinkedListQueue != NULL) && (hfmac->hdmaPreload->LinkedListQueue->Head != NULL))
2030         {
2031           /* Enable the DMA channel */
2032           hfmac->hdmaPreload->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] =
2033             (uint32_t)(2UL * OutputSize);      /* Set DMA data size           */
2034           hfmac->hdmaPreload->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] =
2035             (uint32_t)pOutput;                 /* Set DMA source address      */
2036           hfmac->hdmaPreload->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] =
2037             (uint32_t)&hfmac->Instance->WDATA; /* Set DMA destination address */
2038 
2039           return (HAL_DMAEx_List_Start_IT(hfmac->hdmaPreload));
2040         }
2041         else
2042         {
2043           /* Return error status */
2044           return HAL_ERROR;
2045         }
2046       }
2047       else
2048       {
2049         return (HAL_DMA_Start_IT(hfmac->hdmaPreload, (uint32_t)pOutput, \
2050                                  (uint32_t)&hfmac->Instance->WDATA, (uint32_t)(2UL * OutputSize)));
2051       }
2052     }
2053   }
2054 
2055   /* Update the error codes */
2056   if (__HAL_FMAC_GET_FLAG(hfmac, FMAC_FLAG_OVFL))
2057   {
2058     hfmac->ErrorCode |= HAL_FMAC_ERROR_OVFL;
2059   }
2060   if (__HAL_FMAC_GET_FLAG(hfmac, FMAC_FLAG_UNFL))
2061   {
2062     hfmac->ErrorCode |= HAL_FMAC_ERROR_UNFL;
2063   }
2064   if (__HAL_FMAC_GET_FLAG(hfmac, FMAC_FLAG_SAT))
2065   {
2066     hfmac->ErrorCode |= HAL_FMAC_ERROR_SAT;
2067   }
2068 
2069   /* Change the FMAC state */
2070   hfmac->State = HAL_FMAC_STATE_READY;
2071 
2072   /* Return function status */
2073   if (hfmac->ErrorCode == HAL_FMAC_ERROR_NONE)
2074   {
2075     status = HAL_OK;
2076   }
2077   else
2078   {
2079     status = HAL_ERROR;
2080   }
2081   return status;
2082 }
2083 
2084 /**
2085   * @brief  Write data into FMAC internal memory through WDATA and increment input buffer pointer.
2086   * @note   This function is only used with preload functions.
2087   * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
2088   *         the configuration information for FMAC module.
2089   * @param  ppData pointer to pointer to the data buffer.
2090   * @param  Size size of the data buffer.
2091   * @retval None
2092   */
FMAC_WritePreloadDataIncrementPtr(FMAC_HandleTypeDef * hfmac,int16_t ** ppData,uint8_t Size)2093 static void FMAC_WritePreloadDataIncrementPtr(FMAC_HandleTypeDef *hfmac, int16_t **ppData, uint8_t Size)
2094 {
2095   uint8_t index;
2096 
2097   /* Load the buffer into the internal memory */
2098   for (index = Size; index > 0U; index--)
2099   {
2100     WRITE_REG(hfmac->Instance->WDATA, (((uint32_t)(*(*ppData))) & FMAC_WDATA_WDATA));
2101     (*ppData)++;
2102   }
2103 }
2104 
2105 /**
2106   * @brief  Handle FMAC Function Timeout.
2107   * @param  hfmac FMAC handle.
2108   * @param  Tickstart Tick start value.
2109   * @param  Timeout Timeout duration.
2110   * @retval HAL_StatusTypeDef HAL status
2111   */
FMAC_WaitOnStartUntilTimeout(FMAC_HandleTypeDef * hfmac,uint32_t Tickstart,uint32_t Timeout)2112 static HAL_StatusTypeDef FMAC_WaitOnStartUntilTimeout(FMAC_HandleTypeDef *hfmac, uint32_t Tickstart, uint32_t Timeout)
2113 {
2114   /* Wait until flag changes */
2115   while (READ_BIT(hfmac->Instance->PARAM, FMAC_PARAM_START) != 0U)
2116   {
2117     if ((HAL_GetTick() - Tickstart) > Timeout)
2118     {
2119       hfmac->ErrorCode |= HAL_FMAC_ERROR_TIMEOUT;
2120 
2121       return HAL_ERROR;
2122     }
2123   }
2124   return HAL_OK;
2125 }
2126 
2127 /**
2128   * @brief  Register the new input buffer, update DMA configuration if needed and change the FMAC state.
2129   * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
2130   *         the configuration information for FMAC module.
2131   * @param  pInput New input vector (additional input data).
2132   * @param  pInputSize Size of the input vector (if all the data can't be
2133   *         written, it will be updated with the number of data read from FMAC).
2134   * @retval HAL_StatusTypeDef HAL status
2135   */
FMAC_AppendFilterDataUpdateState(FMAC_HandleTypeDef * hfmac,int16_t * pInput,uint16_t * pInputSize)2136 static HAL_StatusTypeDef FMAC_AppendFilterDataUpdateState(FMAC_HandleTypeDef *hfmac, int16_t *pInput,
2137                                                           uint16_t *pInputSize)
2138 {
2139   HAL_StatusTypeDef status;
2140   /* Change the FMAC state */
2141   hfmac->WrState = HAL_FMAC_STATE_BUSY_WR;
2142 
2143   /* Reset the current size */
2144   hfmac->InputCurrentSize = 0U;
2145 
2146   /* Handle the pointer depending on the input access */
2147   if (hfmac->InputAccess == FMAC_BUFFER_ACCESS_DMA)
2148   {
2149     hfmac->pInput = NULL;
2150     hfmac->pInputSize = NULL;
2151 
2152     /* Set the FMAC DMA transfer complete callback */
2153     hfmac->hdmaIn->XferHalfCpltCallback = FMAC_DMAHalfGetData;
2154     hfmac->hdmaIn->XferCpltCallback = FMAC_DMAGetData;
2155     /* Set the DMA error callback */
2156     hfmac->hdmaIn->XferErrorCallback = FMAC_DMAError;
2157 
2158     /* Enable the DMA stream managing FMAC input data write */
2159     if ((hfmac->hdmaIn->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST)
2160     {
2161       if ((hfmac->hdmaIn->LinkedListQueue != NULL) && (hfmac->hdmaIn->LinkedListQueue->Head != NULL))
2162       {
2163         /* Enable the DMA channel */
2164         hfmac->hdmaIn->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] =
2165           (uint32_t)(2UL * (*pInputSize));  /* Set DMA data size           */
2166         hfmac->hdmaIn->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] =
2167           (uint32_t)pInput;                 /* Set DMA source address      */
2168         hfmac->hdmaIn->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] =
2169           (uint32_t)&hfmac->Instance->WDATA;/* Set DMA destination address */
2170 
2171         status = HAL_DMAEx_List_Start_IT(hfmac->hdmaIn);
2172       }
2173       else
2174       {
2175         /* Return error status */
2176         return HAL_ERROR;
2177       }
2178     }
2179     else
2180     {
2181       status = HAL_DMA_Start_IT(hfmac->hdmaIn, (uint32_t)pInput, \
2182                                 (uint32_t)&hfmac->Instance->WDATA, (uint32_t)(2UL * (*pInputSize)));
2183     }
2184 
2185     if (status != HAL_OK)
2186     {
2187       /* Return error status */
2188       return HAL_ERROR;
2189     }
2190   }
2191   else
2192   {
2193     /* Update the input data information (polling, IT) */
2194     hfmac->pInput = pInput;
2195     hfmac->pInputSize = pInputSize;
2196   }
2197 
2198   return HAL_OK;
2199 }
2200 
2201 /**
2202   * @brief  Register the new output buffer, update DMA configuration if needed and change the FMAC state.
2203   * @param  hfmac pointer to a FMAC_HandleTypeDef structure that contains
2204   *         the configuration information for FMAC module.
2205   * @param  pOutput New output vector.
2206   * @param  pOutputSize Size of the output vector (if the vector can't
2207   *         be entirely filled, pOutputSize will be updated with the number
2208   *         of data read from FMAC).
2209   * @retval HAL_StatusTypeDef HAL status
2210   */
FMAC_ConfigFilterOutputBufferUpdateState(FMAC_HandleTypeDef * hfmac,int16_t * pOutput,uint16_t * pOutputSize)2211 static HAL_StatusTypeDef FMAC_ConfigFilterOutputBufferUpdateState(FMAC_HandleTypeDef *hfmac, int16_t *pOutput,
2212                                                                   uint16_t *pOutputSize)
2213 {
2214   HAL_StatusTypeDef status;
2215   /* Reset the current size */
2216   hfmac->OutputCurrentSize = 0U;
2217 
2218   /* Check whether a valid pointer was provided */
2219   if ((pOutput == NULL) || (pOutputSize == NULL) || (*pOutputSize == 0U))
2220   {
2221     /* The user will have to provide a valid configuration later */
2222     hfmac->pOutput = NULL;
2223     hfmac->pOutputSize = NULL;
2224     hfmac->RdState = HAL_FMAC_STATE_READY;
2225   }
2226   /* Handle the pointer depending on the input access */
2227   else if (hfmac->OutputAccess == FMAC_BUFFER_ACCESS_DMA)
2228   {
2229     hfmac->pOutput = NULL;
2230     hfmac->pOutputSize = NULL;
2231     hfmac->RdState = HAL_FMAC_STATE_BUSY_RD;
2232 
2233     /* Set the FMAC DMA transfer complete callback */
2234     hfmac->hdmaOut->XferHalfCpltCallback = FMAC_DMAHalfOutputDataReady;
2235     hfmac->hdmaOut->XferCpltCallback = FMAC_DMAOutputDataReady;
2236     /* Set the DMA error callback */
2237     hfmac->hdmaOut->XferErrorCallback = FMAC_DMAError;
2238 
2239     /* Enable the DMA stream managing FMAC output data read */
2240     if ((hfmac->hdmaOut->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST)
2241     {
2242       if ((hfmac->hdmaOut->LinkedListQueue != NULL) && (hfmac->hdmaOut->LinkedListQueue->Head != NULL))
2243       {
2244         /* Enable the DMA channel */
2245         hfmac->hdmaOut->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] =
2246           (uint32_t)(4UL * (*pOutputSize)); /* Set DMA data size           */
2247         hfmac->hdmaOut->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] =
2248           (uint32_t)&hfmac->Instance->RDATA;/* Set DMA source address      */
2249         hfmac->hdmaOut->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] =
2250           (uint32_t)pOutput;                /* Set DMA destination address */
2251 
2252         status = HAL_DMAEx_List_Start_IT(hfmac->hdmaOut);
2253       }
2254       else
2255       {
2256         /* Return error status */
2257         return HAL_ERROR;
2258       }
2259     }
2260     else
2261     {
2262       status = HAL_DMA_Start_IT(hfmac->hdmaOut, (uint32_t)&hfmac->Instance->RDATA, \
2263                                 (uint32_t)pOutput, (uint32_t)(4UL * (*pOutputSize)));
2264     }
2265 
2266     if (status != HAL_OK)
2267     {
2268       /* Return error status */
2269       return HAL_ERROR;
2270     }
2271   }
2272   else if (hfmac->OutputAccess == FMAC_BUFFER_ACCESS_NONE)
2273   {
2274     hfmac->pOutput = NULL;
2275     hfmac->pOutputSize = NULL;
2276     hfmac->RdState = HAL_FMAC_STATE_READY;
2277   }
2278   else
2279   {
2280     /* Update the output data information (polling, IT) */
2281     hfmac->pOutput = pOutput;
2282     hfmac->pOutputSize = pOutputSize;
2283     hfmac->RdState = HAL_FMAC_STATE_BUSY_RD;
2284   }
2285 
2286   return HAL_OK;
2287 }
2288 
2289 /**
2290   * @brief  Read available output data until Y EMPTY is set.
2291   * @param  hfmac FMAC handle.
2292   * @param  MaxSizeToRead Maximum number of data to read (this serves as a timeout
2293   *         if FMAC continuously writes into the output buffer).
2294   * @retval None
2295   */
FMAC_ReadDataIncrementPtr(FMAC_HandleTypeDef * hfmac,uint16_t MaxSizeToRead)2296 static void FMAC_ReadDataIncrementPtr(FMAC_HandleTypeDef *hfmac, uint16_t MaxSizeToRead)
2297 {
2298   uint16_t maxsize;
2299   uint16_t threshold;
2300   uint32_t tmpvalue;
2301 
2302   /* Check if there is data to read */
2303   if (READ_BIT(hfmac->Instance->SR, FMAC_SR_YEMPTY) != 0U)
2304   {
2305     return;
2306   }
2307 
2308   /* Get the maximum index (no wait allowed, no overstepping of the output buffer) */
2309   if ((hfmac->OutputCurrentSize + MaxSizeToRead) > *(hfmac->pOutputSize))
2310   {
2311     maxsize = *(hfmac->pOutputSize);
2312   }
2313   else
2314   {
2315     maxsize = hfmac->OutputCurrentSize + MaxSizeToRead;
2316   }
2317 
2318   /* Read until there is no more room or no more data */
2319   do
2320   {
2321     /* If there is no more room, return */
2322     if (!(hfmac->OutputCurrentSize < maxsize))
2323     {
2324       return;
2325     }
2326 
2327     /* Read the available data */
2328     tmpvalue = ((READ_REG(hfmac->Instance->RDATA))& FMAC_RDATA_RDATA);
2329     *(hfmac->pOutput) = (int16_t)tmpvalue;
2330     hfmac->pOutput++;
2331     hfmac->OutputCurrentSize++;
2332   } while (READ_BIT(hfmac->Instance->SR, FMAC_SR_YEMPTY) == 0U);
2333 
2334   /* Y buffer empty flag has just be raised, read the threshold */
2335   threshold = (uint16_t)FMAC_GET_THRESHOLD_FROM_WM(FMAC_GET_Y_EMPTY_WM(hfmac)) - 1U;
2336 
2337   /* Update the maximum size if needed (limited data available) */
2338   if ((hfmac->OutputCurrentSize + threshold) < maxsize)
2339   {
2340     maxsize = hfmac->OutputCurrentSize + threshold;
2341   }
2342 
2343   /* Read the available data */
2344   while (hfmac->OutputCurrentSize < maxsize)
2345   {
2346     tmpvalue = ((READ_REG(hfmac->Instance->RDATA))& FMAC_RDATA_RDATA);
2347     *(hfmac->pOutput) = (int16_t)tmpvalue;
2348     hfmac->pOutput++;
2349     hfmac->OutputCurrentSize++;
2350   }
2351 }
2352 
2353 /**
2354   * @brief  Write available input data until X1 FULL is set.
2355   * @param  hfmac FMAC handle.
2356   * @param  MaxSizeToWrite Maximum number of data to write (this serves as a timeout
2357   *         if FMAC continuously empties the input buffer).
2358   * @retval None
2359   */
FMAC_WriteDataIncrementPtr(FMAC_HandleTypeDef * hfmac,uint16_t MaxSizeToWrite)2360 static void FMAC_WriteDataIncrementPtr(FMAC_HandleTypeDef *hfmac, uint16_t MaxSizeToWrite)
2361 {
2362   uint16_t maxsize;
2363   uint16_t threshold;
2364 
2365   /* Check if there is room in FMAC */
2366   if (READ_BIT(hfmac->Instance->SR, FMAC_SR_X1FULL) != 0U)
2367   {
2368     return;
2369   }
2370 
2371   /* Get the maximum index (no wait allowed, no overstepping of the output buffer) */
2372   if ((hfmac->InputCurrentSize + MaxSizeToWrite) > *(hfmac->pInputSize))
2373   {
2374     maxsize = *(hfmac->pInputSize);
2375   }
2376   else
2377   {
2378     maxsize = hfmac->InputCurrentSize + MaxSizeToWrite;
2379   }
2380 
2381   /* Write until there is no more room or no more data */
2382   do
2383   {
2384     /* If there is no more room, return */
2385     if (!(hfmac->InputCurrentSize < maxsize))
2386     {
2387       return;
2388     }
2389 
2390     /* Write the available data */
2391     WRITE_REG(hfmac->Instance->WDATA, (((uint32_t)(*(hfmac->pInput))) & FMAC_WDATA_WDATA));
2392     hfmac->pInput++;
2393     hfmac->InputCurrentSize++;
2394   } while (READ_BIT(hfmac->Instance->SR, FMAC_SR_X1FULL) == 0U);
2395 
2396   /* X1 buffer full flag has just be raised, read the threshold */
2397   threshold = (uint16_t)FMAC_GET_THRESHOLD_FROM_WM(FMAC_GET_X1_FULL_WM(hfmac)) - 1U;
2398 
2399   /* Update the maximum size if needed (limited data available) */
2400   if ((hfmac->InputCurrentSize + threshold) < maxsize)
2401   {
2402     maxsize = hfmac->InputCurrentSize + threshold;
2403   }
2404 
2405   /* Write the available data */
2406   while (hfmac->InputCurrentSize < maxsize)
2407   {
2408     WRITE_REG(hfmac->Instance->WDATA, (((uint32_t)(*(hfmac->pInput))) & FMAC_WDATA_WDATA));
2409     hfmac->pInput++;
2410     hfmac->InputCurrentSize++;
2411   }
2412 }
2413 
2414 /**
2415   * @brief  DMA FMAC Input Data process half complete callback.
2416   * @param  hdma DMA handle.
2417   * @retval None
2418   */
FMAC_DMAHalfGetData(DMA_HandleTypeDef * hdma)2419 static void FMAC_DMAHalfGetData(DMA_HandleTypeDef *hdma)
2420 {
2421   FMAC_HandleTypeDef *hfmac = (FMAC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2422 
2423   /* Call half get data callback */
2424 #if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1)
2425   hfmac->HalfGetDataCallback(hfmac);
2426 #else
2427   HAL_FMAC_HalfGetDataCallback(hfmac);
2428 #endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */
2429 }
2430 
2431 /**
2432   * @brief  DMA FMAC Input Data process complete callback.
2433   * @param  hdma DMA handle.
2434   * @retval None
2435   */
FMAC_DMAGetData(DMA_HandleTypeDef * hdma)2436 static void FMAC_DMAGetData(DMA_HandleTypeDef *hdma)
2437 {
2438   FMAC_HandleTypeDef *hfmac = (FMAC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2439 
2440   /* Reset the pointers to indicate new data will be needed */
2441   FMAC_ResetInputStateAndDataPointers(hfmac);
2442 
2443   /* Call get data callback */
2444 #if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1)
2445   hfmac->GetDataCallback(hfmac);
2446 #else
2447   HAL_FMAC_GetDataCallback(hfmac);
2448 #endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */
2449 }
2450 
2451 /**
2452   * @brief  DMA FMAC Output Data process half complete callback.
2453   * @param  hdma DMA handle.
2454   * @retval None
2455   */
FMAC_DMAHalfOutputDataReady(DMA_HandleTypeDef * hdma)2456 static void FMAC_DMAHalfOutputDataReady(DMA_HandleTypeDef *hdma)
2457 {
2458   FMAC_HandleTypeDef *hfmac = (FMAC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2459 
2460   /* Call half output data ready callback */
2461 #if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1)
2462   hfmac->HalfOutputDataReadyCallback(hfmac);
2463 #else
2464   HAL_FMAC_HalfOutputDataReadyCallback(hfmac);
2465 #endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */
2466 }
2467 
2468 /**
2469   * @brief  DMA FMAC Output Data process complete callback.
2470   * @param  hdma DMA handle.
2471   * @retval None
2472   */
FMAC_DMAOutputDataReady(DMA_HandleTypeDef * hdma)2473 static void FMAC_DMAOutputDataReady(DMA_HandleTypeDef *hdma)
2474 {
2475   FMAC_HandleTypeDef *hfmac = (FMAC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2476 
2477   /* Reset the pointers to indicate new data will be needed */
2478   FMAC_ResetOutputStateAndDataPointers(hfmac);
2479 
2480   /* Call output data ready callback */
2481 #if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1)
2482   hfmac->OutputDataReadyCallback(hfmac);
2483 #else
2484   HAL_FMAC_OutputDataReadyCallback(hfmac);
2485 #endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */
2486 }
2487 
2488 /**
2489   * @brief  DMA FMAC Filter Configuration process complete callback.
2490   * @param  hdma DMA handle.
2491   * @retval None
2492   */
FMAC_DMAFilterConfig(DMA_HandleTypeDef * hdma)2493 static void FMAC_DMAFilterConfig(DMA_HandleTypeDef *hdma)
2494 {
2495   HAL_StatusTypeDef status;
2496   uint8_t index;
2497 
2498   FMAC_HandleTypeDef *hfmac = (FMAC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2499 
2500   /* If needed, write CoeffA and exit */
2501   if (hfmac->pInput != NULL)
2502   {
2503     /* Set the FMAC DMA transfer complete callback */
2504     hfmac->hdmaPreload->XferHalfCpltCallback = NULL;
2505     hfmac->hdmaPreload->XferCpltCallback = FMAC_DMAFilterConfig;
2506     /* Set the DMA error callback */
2507     hfmac->hdmaPreload->XferErrorCallback = FMAC_DMAError;
2508 
2509     /* Enable the DMA stream managing FMAC preload data write */
2510     if ((hfmac->hdmaPreload->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST)
2511     {
2512       if ((hfmac->hdmaPreload->LinkedListQueue != NULL) && (hfmac->hdmaPreload->LinkedListQueue->Head != NULL))
2513       {
2514         /* Enable the DMA channel */
2515         hfmac->hdmaPreload->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] =
2516           (uint32_t)(2UL * hfmac->InputCurrentSize);/* Set DMA data size           */
2517         hfmac->hdmaPreload->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] =
2518           (uint32_t)hfmac->pInput;                  /* Set DMA source address      */
2519         hfmac->hdmaPreload->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] =
2520           (uint32_t)&hfmac->Instance->WDATA;        /* Set DMA destination address */
2521 
2522         status = HAL_DMAEx_List_Start_IT(hfmac->hdmaPreload);
2523       }
2524       else
2525       {
2526         /* Return error status */
2527         status = HAL_ERROR;
2528       }
2529     }
2530     else
2531     {
2532       status = HAL_DMA_Start_IT(hfmac->hdmaPreload, (uint32_t)hfmac->pInput, \
2533                                 (uint32_t)&hfmac->Instance->WDATA, (uint32_t)(2UL * hfmac->InputCurrentSize));
2534     }
2535 
2536     if (status == HAL_OK)
2537     {
2538       hfmac->pInput = NULL;
2539       hfmac->InputCurrentSize = 0U;
2540       return;
2541     }
2542 
2543     /* If not exited, there was an error: set FMAC handle state to error */
2544     hfmac->State = HAL_FMAC_STATE_ERROR;
2545   }
2546   else
2547   {
2548     /* Wait for the end of the writing */
2549     for (index = 0U; index < MAX_PRELOAD_INDEX; index++)
2550     {
2551       if (READ_BIT(hfmac->Instance->PARAM, FMAC_PARAM_START) == 0U)
2552       {
2553         break;
2554       }
2555     }
2556 
2557     /* If 'START' is still set, there was a timeout: set FMAC handle state to timeout */
2558     if (READ_BIT(hfmac->Instance->PARAM, FMAC_PARAM_START) != 0U)
2559     {
2560       hfmac->State = HAL_FMAC_STATE_TIMEOUT;
2561     }
2562     else
2563     {
2564       /* Change the FMAC state */
2565       hfmac->State = HAL_FMAC_STATE_READY;
2566 
2567       /* Call output data ready callback */
2568 #if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1)
2569       hfmac->FilterConfigCallback(hfmac);
2570 #else
2571       HAL_FMAC_FilterConfigCallback(hfmac);
2572 #endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */
2573       return;
2574     }
2575   }
2576 
2577   /* If not exited, there was an error: set FMAC handle error code to DMA error */
2578   hfmac->ErrorCode |= HAL_FMAC_ERROR_DMA;
2579 
2580   /* Call user callback */
2581 #if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1)
2582   hfmac->ErrorCallback(hfmac);
2583 #else
2584   HAL_FMAC_ErrorCallback(hfmac);
2585 #endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */
2586 }
2587 
2588 /**
2589   * @brief  DMA FMAC Filter Configuration process complete callback.
2590   * @param  hdma DMA handle.
2591   * @retval None
2592   */
FMAC_DMAFilterPreload(DMA_HandleTypeDef * hdma)2593 static void FMAC_DMAFilterPreload(DMA_HandleTypeDef *hdma)
2594 {
2595   HAL_StatusTypeDef status;
2596   uint8_t index;
2597 
2598   FMAC_HandleTypeDef *hfmac = (FMAC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2599 
2600   /* Wait for the end of the X1 writing */
2601   for (index = 0U; index < MAX_PRELOAD_INDEX; index++)
2602   {
2603     if (READ_BIT(hfmac->Instance->PARAM, FMAC_PARAM_START) == 0U)
2604     {
2605       break;
2606     }
2607   }
2608 
2609   /* If 'START' is still set, there was an error: set FMAC handle state to error */
2610   if (READ_BIT(hfmac->Instance->PARAM, FMAC_PARAM_START) != 0U)
2611   {
2612     hfmac->State = HAL_FMAC_STATE_TIMEOUT;
2613     hfmac->ErrorCode |= HAL_FMAC_ERROR_TIMEOUT;
2614   }
2615   /* If needed, preload Y buffer */
2616   else if ((hfmac->pInput != NULL) && (hfmac->InputCurrentSize != 0U))
2617   {
2618     /* Write number of values to be loaded, the data load function and start the operation */
2619     WRITE_REG(hfmac->Instance->PARAM, \
2620               (((uint32_t)(hfmac->InputCurrentSize) << FMAC_PARAM_P_Pos) | FMAC_FUNC_LOAD_Y | FMAC_PARAM_START));
2621 
2622     /* Set the FMAC DMA transfer complete callback */
2623     hfmac->hdmaPreload->XferHalfCpltCallback = NULL;
2624     hfmac->hdmaPreload->XferCpltCallback = FMAC_DMAFilterPreload;
2625     /* Set the DMA error callback */
2626     hfmac->hdmaPreload->XferErrorCallback = FMAC_DMAError;
2627 
2628     /* Enable the DMA stream managing FMAC preload data write */
2629     if ((hfmac->hdmaPreload->Mode & DMA_LINKEDLIST) == DMA_LINKEDLIST)
2630     {
2631       if ((hfmac->hdmaPreload->LinkedListQueue != NULL) && (hfmac->hdmaPreload->LinkedListQueue->Head != NULL))
2632       {
2633         /* Enable the DMA channel */
2634         hfmac->hdmaPreload->LinkedListQueue->Head->LinkRegisters[NODE_CBR1_DEFAULT_OFFSET] =
2635           (uint32_t)(2UL * hfmac->InputCurrentSize);/* Set DMA data size           */
2636         hfmac->hdmaPreload->LinkedListQueue->Head->LinkRegisters[NODE_CSAR_DEFAULT_OFFSET] =
2637           (uint32_t)hfmac->pInput;                  /* Set DMA source address      */
2638         hfmac->hdmaPreload->LinkedListQueue->Head->LinkRegisters[NODE_CDAR_DEFAULT_OFFSET] =
2639           (uint32_t)&hfmac->Instance->WDATA;        /* Set DMA destination address */
2640 
2641         status = HAL_DMAEx_List_Start_IT(hfmac->hdmaPreload);
2642       }
2643       else
2644       {
2645         /* Return error status */
2646         status = HAL_ERROR;
2647       }
2648     }
2649     else
2650     {
2651       status = HAL_DMA_Start_IT(hfmac->hdmaPreload, (uint32_t)hfmac->pInput, \
2652                                 (uint32_t)&hfmac->Instance->WDATA, (uint32_t)(2UL * hfmac->InputCurrentSize));
2653     }
2654 
2655     if (status == HAL_OK)
2656     {
2657       hfmac->pInput = NULL;
2658       hfmac->InputCurrentSize = 0U;
2659       return;
2660     }
2661 
2662     /* If not exited, there was an error */
2663     hfmac->ErrorCode = HAL_FMAC_ERROR_DMA;
2664     hfmac->State = HAL_FMAC_STATE_ERROR;
2665   }
2666   else
2667   {
2668     /* nothing to do */
2669   }
2670 
2671   if (hfmac->ErrorCode == HAL_FMAC_ERROR_NONE)
2672   {
2673     /* Change the FMAC state */
2674     hfmac->State = HAL_FMAC_STATE_READY;
2675 
2676     /* Call output data ready callback */
2677 #if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1)
2678     hfmac->FilterPreloadCallback(hfmac);
2679 #else
2680     HAL_FMAC_FilterPreloadCallback(hfmac);
2681 #endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */
2682   }
2683   else
2684   {
2685     /* Call user callback */
2686 #if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1)
2687     hfmac->ErrorCallback(hfmac);
2688 #else
2689     HAL_FMAC_ErrorCallback(hfmac);
2690 #endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */
2691   }
2692 }
2693 
2694 
2695 /**
2696   * @brief  DMA FMAC communication error callback.
2697   * @param  hdma DMA handle.
2698   * @retval None
2699   */
FMAC_DMAError(DMA_HandleTypeDef * hdma)2700 static void FMAC_DMAError(DMA_HandleTypeDef *hdma)
2701 {
2702   FMAC_HandleTypeDef *hfmac = (FMAC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
2703 
2704   /* Set FMAC handle state to error */
2705   hfmac->State = HAL_FMAC_STATE_ERROR;
2706 
2707   /* Set FMAC handle error code to DMA error */
2708   hfmac->ErrorCode |= HAL_FMAC_ERROR_DMA;
2709 
2710   /* Call user callback */
2711 #if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1)
2712   hfmac->ErrorCallback(hfmac);
2713 #else
2714   HAL_FMAC_ErrorCallback(hfmac);
2715 #endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */
2716 }
2717 
2718 /**
2719   * @}
2720   */
2721 
2722 /**
2723   * @}
2724   */
2725 
2726 /**
2727   * @}
2728   */
2729 
2730 #endif /* HAL_FMAC_MODULE_ENABLED */
2731 #endif /* FMAC */
2732