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