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