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