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