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