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