STM32H735xx HAL User Manual
|
00001 /** 00002 ****************************************************************************** 00003 * @file stm32h7xx_hal_fmac.c 00004 * @author MCD Application Team 00005 * @brief FMAC HAL module driver. 00006 * This file provides firmware functions to manage the following 00007 * functionalities of the FMAC peripheral: 00008 * + Initialization and de-initialization functions 00009 * + Peripheral Control functions 00010 * + Callback functions 00011 * + IRQ handler management 00012 * + Peripheral State and Error functions 00013 * 00014 ****************************************************************************** 00015 * @attention 00016 * 00017 * Copyright (c) 2017 STMicroelectronics. 00018 * All rights reserved. 00019 * 00020 * This software is licensed under terms that can be found in the LICENSE file 00021 * in the root directory of this software component. 00022 * If no LICENSE file comes with this software, it is provided AS-IS. 00023 * 00024 ****************************************************************************** 00025 * 00026 * @verbatim 00027 ================================================================================ 00028 ##### How to use this driver ##### 00029 ================================================================================ 00030 [..] 00031 The FMAC HAL driver can be used as follows: 00032 00033 (#) Initialize the FMAC low level resources by implementing the HAL_FMAC_MspInit(): 00034 (++) Enable the FMAC interface clock using __HAL_RCC_FMAC_CLK_ENABLE(). 00035 (++) In case of using interrupts (e.g. access configured as FMAC_BUFFER_ACCESS_IT): 00036 (+++) Configure the FMAC interrupt priority using HAL_NVIC_SetPriority(). 00037 (+++) Enable the FMAC IRQ handler using HAL_NVIC_EnableIRQ(). 00038 (+++) In FMAC IRQ handler, call HAL_FMAC_IRQHandler(). 00039 (++) In case of using DMA to control data transfer (e.g. access configured 00040 as FMAC_BUFFER_ACCESS_DMA): 00041 (+++) Enable the DMA interface clock using __HAL_RCC_DMA1_CLK_ENABLE() 00042 or __HAL_RCC_DMA2_CLK_ENABLE() depending on the used DMA instance. 00043 (+++) Enable the DMAMUX1 interface clock using __HAL_RCC_DMAMUX1_CLK_ENABLE(). 00044 (+++) If the initialization of the internal buffers (coefficients, input, 00045 output) is done via DMA, configure and enable one DMA channel for 00046 managing data transfer from memory to memory (preload channel). 00047 (+++) If the input buffer is accessed via DMA, configure and enable one 00048 DMA channel for managing data transfer from memory to peripheral 00049 (input channel). 00050 (+++) If the output buffer is accessed via DMA, configure and enable 00051 one DMA channel for managing data transfer from peripheral to 00052 memory (output channel). 00053 (+++) Associate the initialized DMA handle(s) to the FMAC DMA handle(s) 00054 using __HAL_LINKDMA(). 00055 (+++) Configure the priority and enable the NVIC for the transfer complete 00056 interrupt on the enabled DMA channel(s) using HAL_NVIC_SetPriority() 00057 and HAL_NVIC_EnableIRQ(). 00058 00059 (#) Initialize the FMAC HAL using HAL_FMAC_Init(). This function 00060 resorts to HAL_FMAC_MspInit() for low-level initialization. 00061 00062 (#) Configure the FMAC processing (filter) using HAL_FMAC_FilterConfig() 00063 or HAL_FMAC_FilterConfig_DMA(). 00064 This function: 00065 (++) Defines the memory area within the FMAC internal memory 00066 (input, coefficients, output) and the associated threshold (input, output). 00067 (++) Configures the filter and its parameters: 00068 (+++) Finite Impulse Response (FIR) filter (also known as convolution). 00069 (+++) Infinite Impulse Response (IIR) filter (direct form 1). 00070 (++) Choose the way to access to the input and output buffers: none, polling, 00071 DMA, IT. "none" means the input and/or output data will be handled by 00072 another IP (ADC, DAC, etc.). 00073 (++) Enable the error interruptions in the input access and/or the output 00074 access is done through IT/DMA. If an error occurs, the interruption 00075 will be triggered in loop. In order to recover, the user will have 00076 to reset the IP with the sequence HAL_FMAC_DeInit / HAL_FMAC_Init. 00077 Optionally, he can also disable the interrupt using __HAL_FMAC_DISABLE_IT; 00078 the error status will be kept, but no more interrupt will be triggered. 00079 (++) Write the provided coefficients into the internal memory using polling 00080 mode ( HAL_FMAC_FilterConfig() ) or DMA ( HAL_FMAC_FilterConfig_DMA() ). 00081 In the DMA case, HAL_FMAC_FilterConfigCallback() is called when 00082 the handling is over. 00083 00084 (#) Optionally, the user can enable the error interruption related to 00085 saturation by calling __HAL_FMAC_ENABLE_IT. This helps in debugging the 00086 filter. If a saturation occurs, the interruption will be triggered in loop. 00087 In order to recover, the user will have to: 00088 (++) Disable the interruption by calling __HAL_FMAC_DISABLE_IT if 00089 the user wishes to continue all the same. 00090 (++) Reset the IP with the sequence HAL_FMAC_DeInit / HAL_FMAC_Init. 00091 00092 (#) Optionally, preload input (FIR, IIR) and output (IIR) data using 00093 HAL_FMAC_FilterPreload() or HAL_FMAC_FilterPreload_DMA(). 00094 In the DMA case, HAL_FMAC_FilterPreloadCallback() is called when 00095 the handling is over. 00096 This step is optional as the filter can be started without preloaded 00097 data. 00098 00099 (#) Start the FMAC processing (filter) using HAL_FMAC_FilterStart(). 00100 This function also configures the output buffer that will be filled from 00101 the circular internal output buffer. The function returns immediately 00102 without updating the provided buffer. The IP processing will be active until 00103 HAL_FMAC_FilterStop() is called. 00104 00105 (#) If the input internal buffer is accessed via DMA, HAL_FMAC_HalfGetDataCallback() 00106 will be called to indicate that half of the input buffer has been handled. 00107 00108 (#) If the input internal buffer is accessed via DMA or interrupt, HAL_FMAC_GetDataCallback() 00109 will be called to require new input data. It will be provided through 00110 HAL_FMAC_AppendFilterData() if the DMA isn't in circular mode. 00111 00112 (#) If the output internal buffer is accessed via DMA, HAL_FMAC_HalfOutputDataReadyCallback() 00113 will be called to indicate that half of the output buffer has been handled. 00114 00115 (#) If the output internal buffer is accessed via DMA or interrupt, 00116 HAL_FMAC_OutputDataReadyCallback() will be called to require a new output 00117 buffer. It will be provided through HAL_FMAC_ConfigFilterOutputBuffer() 00118 if the DMA isn't in circular mode. 00119 00120 (#) In all modes except none, provide new input data to be processed via HAL_FMAC_AppendFilterData(). 00121 This function should only be called once the previous input data has been handled 00122 (the preloaded input data isn't concerned). 00123 00124 (#) In all modes except none, provide a new output buffer to be filled via 00125 HAL_FMAC_ConfigFilterOutputBuffer(). This function should only be called once the previous 00126 user's output buffer has been filled. 00127 00128 (#) In polling mode, handle the input and output data using HAL_FMAC_PollFilterData(). 00129 This function: 00130 (++) Write the user's input data (provided via HAL_FMAC_AppendFilterData()) 00131 into the FMAC input memory area. 00132 (++) Read the FMAC output memory area and write it into the user's output buffer. 00133 It will return either when: 00134 (++) the user's output buffer is filled. 00135 (++) the user's input buffer has been handled. 00136 The unused data (unread input data or free output data) will not be saved. 00137 The user will have to use the updated input and output sizes to keep track 00138 of them. 00139 00140 (#) Stop the FMAC processing (filter) using HAL_FMAC_FilterStop(). 00141 00142 (#) Call HAL_FMAC_DeInit() to de-initialize the FMAC peripheral. This function 00143 resorts to HAL_FMAC_MspDeInit() for low-level de-initialization. 00144 00145 ##### Callback registration ##### 00146 ================================== 00147 00148 [..] 00149 The compilation define USE_HAL_FMAC_REGISTER_CALLBACKS when set to 1 00150 allows the user to configure dynamically the driver callbacks. 00151 00152 [..] 00153 Use Function HAL_FMAC_RegisterCallback() to register a user callback. 00154 Function HAL_FMAC_RegisterCallback() allows to register following callbacks: 00155 (+) ErrorCallback : Error Callback. 00156 (+) HalfGetDataCallback : Get Half Data Callback. 00157 (+) GetDataCallback : Get Data Callback. 00158 (+) HalfOutputDataReadyCallback : Half Output Data Ready Callback. 00159 (+) OutputDataReadyCallback : Output Data Ready Callback. 00160 (+) FilterConfigCallback : Filter Configuration Callback. 00161 (+) FilterPreloadCallback : Filter Preload Callback. 00162 (+) MspInitCallback : FMAC MspInit. 00163 (+) MspDeInitCallback : FMAC MspDeInit. 00164 This function takes as parameters the HAL peripheral handle, the Callback ID 00165 and a pointer to the user callback function. 00166 00167 [..] 00168 Use function HAL_FMAC_UnRegisterCallback() to reset a callback to the default 00169 weak (surcharged) function. 00170 HAL_FMAC_UnRegisterCallback() takes as parameters the HAL peripheral handle 00171 and the Callback ID. 00172 This function allows to reset following callbacks: 00173 (+) ErrorCallback : Error Callback. 00174 (+) HalfGetDataCallback : Get Half Data Callback. 00175 (+) GetDataCallback : Get Data Callback. 00176 (+) HalfOutputDataReadyCallback : Half Output Data Ready Callback. 00177 (+) OutputDataReadyCallback : Output Data Ready Callback. 00178 (+) FilterConfigCallback : Filter Configuration Callback. 00179 (+) FilterPreloadCallback : Filter Preload Callback. 00180 (+) MspInitCallback : FMAC MspInit. 00181 (+) MspDeInitCallback : FMAC MspDeInit. 00182 00183 [..] 00184 By default, after the HAL_FMAC_Init() and when the state is HAL_FMAC_STATE_RESET 00185 all callbacks are set to the corresponding weak (surcharged) functions: 00186 examples GetDataCallback(), OutputDataReadyCallback(). 00187 Exception done for MspInit and MspDeInit functions that are respectively 00188 reset to the legacy weak (surcharged) functions in the HAL_FMAC_Init() 00189 and HAL_FMAC_DeInit() only when these callbacks are null (not registered beforehand). 00190 If not, MspInit or MspDeInit are not null, the HAL_FMAC_Init() and HAL_FMAC_DeInit() 00191 keep and use the user MspInit/MspDeInit callbacks (registered beforehand). 00192 00193 [..] 00194 Callbacks can be registered/unregistered in HAL_FMAC_STATE_READY state only. 00195 Exception done MspInit/MspDeInit that can be registered/unregistered 00196 in HAL_FMAC_STATE_READY or HAL_FMAC_STATE_RESET state, thus registered (user) 00197 MspInit/DeInit callbacks can be used during the Init/DeInit. 00198 In that case first register the MspInit/MspDeInit user callbacks 00199 using HAL_FMAC_RegisterCallback() before calling HAL_FMAC_DeInit() 00200 or HAL_FMAC_Init() function. 00201 00202 [..] 00203 When the compilation define USE_HAL_FMAC_REGISTER_CALLBACKS is set to 0 or 00204 not defined, the callback registration feature is not available 00205 and weak (surcharged) callbacks are used. 00206 00207 00208 @endverbatim 00209 * 00210 */ 00211 00212 /* Includes ------------------------------------------------------------------*/ 00213 #include "stm32h7xx_hal.h" 00214 00215 #if defined(FMAC) 00216 #ifdef HAL_FMAC_MODULE_ENABLED 00217 00218 /** @addtogroup STM32H7xx_HAL_Driver 00219 * @{ 00220 */ 00221 00222 /** @defgroup FMAC FMAC 00223 * @brief FMAC HAL driver module 00224 * @{ 00225 */ 00226 00227 /* Private typedef -----------------------------------------------------------*/ 00228 /* Private defines -----------------------------------------------------------*/ 00229 /** @defgroup FMAC_Private_Constants FMAC Private Constants 00230 * @{ 00231 */ 00232 00233 #define MAX_FILTER_DATA_SIZE_TO_HANDLE ((uint16_t) 0xFFU) 00234 #define MAX_PRELOAD_INDEX 0xFFU 00235 #define PRELOAD_ACCESS_DMA 0x00U 00236 #define PRELOAD_ACCESS_POLLING 0x01U 00237 #define POLLING_DISABLED 0U 00238 #define POLLING_ENABLED 1U 00239 #define POLLING_NOT_STOPPED 0U 00240 #define POLLING_STOPPED 1U 00241 /* FMAC polling-based communications time-out value */ 00242 #define HAL_FMAC_TIMEOUT_VALUE 1000U 00243 /* FMAC reset time-out value */ 00244 #define HAL_FMAC_RESET_TIMEOUT_VALUE 500U 00245 /* DMA Read Requests Enable */ 00246 #define FMAC_DMA_REN FMAC_CR_DMAREN 00247 /* DMA Write Channel Enable */ 00248 #define FMAC_DMA_WEN FMAC_CR_DMAWEN 00249 /* FMAC Execution Enable */ 00250 #define FMAC_START FMAC_PARAM_START 00251 00252 /** 00253 * @} 00254 */ 00255 00256 /* Private macros ------------------------------------------------------------*/ 00257 /** @defgroup FMAC_Private_Macros FMAC Private Macros 00258 * @{ 00259 */ 00260 00261 /** 00262 * @brief Get the X1 memory area size. 00263 * @param __HANDLE__ FMAC handle. 00264 * @retval X1_BUF_SIZE 00265 */ 00266 #define FMAC_GET_X1_SIZE(__HANDLE__) \ 00267 ((((__HANDLE__)->Instance->X1BUFCFG) & (FMAC_X1BUFCFG_X1_BUF_SIZE)) >> (FMAC_X1BUFCFG_X1_BUF_SIZE_Pos)) 00268 00269 /** 00270 * @brief Get the X1 watermark. 00271 * @param __HANDLE__ FMAC handle. 00272 * @retval FULL_WM 00273 */ 00274 #define FMAC_GET_X1_FULL_WM(__HANDLE__) \ 00275 (((__HANDLE__)->Instance->X1BUFCFG) & (FMAC_X1BUFCFG_FULL_WM)) 00276 00277 /** 00278 * @brief Get the X2 memory area size. 00279 * @param __HANDLE__ FMAC handle. 00280 * @retval X2_BUF_SIZE 00281 */ 00282 #define FMAC_GET_X2_SIZE(__HANDLE__) \ 00283 ((((__HANDLE__)->Instance->X2BUFCFG) & (FMAC_X2BUFCFG_X2_BUF_SIZE)) >> (FMAC_X2BUFCFG_X2_BUF_SIZE_Pos)) 00284 00285 /** 00286 * @brief Get the Y memory area size. 00287 * @param __HANDLE__ FMAC handle. 00288 * @retval Y_BUF_SIZE 00289 */ 00290 #define FMAC_GET_Y_SIZE(__HANDLE__) \ 00291 ((((__HANDLE__)->Instance->YBUFCFG) & (FMAC_YBUFCFG_Y_BUF_SIZE)) >> (FMAC_YBUFCFG_Y_BUF_SIZE_Pos)) 00292 00293 /** 00294 * @brief Get the Y watermark. 00295 * @param __HANDLE__ FMAC handle. 00296 * @retval EMPTY_WM 00297 */ 00298 #define FMAC_GET_Y_EMPTY_WM(__HANDLE__) \ 00299 (((__HANDLE__)->Instance->YBUFCFG) & (FMAC_YBUFCFG_EMPTY_WM)) 00300 00301 /** 00302 * @brief Get the start bit state. 00303 * @param __HANDLE__ FMAC handle. 00304 * @retval START 00305 */ 00306 #define FMAC_GET_START_BIT(__HANDLE__) \ 00307 ((((__HANDLE__)->Instance->PARAM) & (FMAC_PARAM_START)) >> (FMAC_PARAM_START_Pos)) 00308 00309 /** 00310 * @brief Get the threshold matching the watermark. 00311 * @param __WM__ Watermark value. 00312 * @retval THRESHOLD 00313 */ 00314 #define FMAC_GET_THRESHOLD_FROM_WM(__WM__) (((__WM__) == FMAC_THRESHOLD_1)? 1U: \ 00315 ((__WM__) == FMAC_THRESHOLD_2)? 2U: \ 00316 ((__WM__) == FMAC_THRESHOLD_4)? 4U:8U) 00317 00318 /** 00319 * @} 00320 */ 00321 00322 /* Private variables ---------------------------------------------------------*/ 00323 /* Global variables ----------------------------------------------------------*/ 00324 /* Private function prototypes -----------------------------------------------*/ 00325 00326 static HAL_StatusTypeDef FMAC_Reset(FMAC_HandleTypeDef *hfmac); 00327 static void FMAC_ResetDataPointers(FMAC_HandleTypeDef *hfmac); 00328 static void FMAC_ResetOutputStateAndDataPointers(FMAC_HandleTypeDef *hfmac); 00329 static void FMAC_ResetInputStateAndDataPointers(FMAC_HandleTypeDef *hfmac); 00330 static HAL_StatusTypeDef FMAC_FilterConfig(FMAC_HandleTypeDef *hfmac, FMAC_FilterConfigTypeDef *pConfig, 00331 uint8_t PreloadAccess); 00332 static HAL_StatusTypeDef FMAC_FilterPreload(FMAC_HandleTypeDef *hfmac, int16_t *pInput, uint8_t InputSize, 00333 int16_t *pOutput, uint8_t OutputSize, uint8_t PreloadAccess); 00334 static void FMAC_WritePreloadDataIncrementPtr(FMAC_HandleTypeDef *hfmac, int16_t **ppData, uint8_t Size); 00335 static HAL_StatusTypeDef FMAC_WaitOnStartUntilTimeout(FMAC_HandleTypeDef *hfmac, uint32_t Tickstart, uint32_t Timeout); 00336 static HAL_StatusTypeDef FMAC_AppendFilterDataUpdateState(FMAC_HandleTypeDef *hfmac, int16_t *pInput, 00337 uint16_t *pInputSize); 00338 static HAL_StatusTypeDef FMAC_ConfigFilterOutputBufferUpdateState(FMAC_HandleTypeDef *hfmac, int16_t *pOutput, 00339 uint16_t *pOutputSize); 00340 static void FMAC_WriteDataIncrementPtr(FMAC_HandleTypeDef *hfmac, uint16_t MaxSizeToWrite); 00341 static void FMAC_ReadDataIncrementPtr(FMAC_HandleTypeDef *hfmac, uint16_t MaxSizeToRead); 00342 static void FMAC_DMAHalfGetData(DMA_HandleTypeDef *hdma); 00343 static void FMAC_DMAGetData(DMA_HandleTypeDef *hdma); 00344 static void FMAC_DMAHalfOutputDataReady(DMA_HandleTypeDef *hdma); 00345 static void FMAC_DMAOutputDataReady(DMA_HandleTypeDef *hdma); 00346 static void FMAC_DMAFilterConfig(DMA_HandleTypeDef *hdma); 00347 static void FMAC_DMAFilterPreload(DMA_HandleTypeDef *hdma); 00348 static void FMAC_DMAError(DMA_HandleTypeDef *hdma); 00349 00350 /* Functions Definition ------------------------------------------------------*/ 00351 00352 /** @defgroup FMAC_Exported_Functions FMAC Exported Functions 00353 * @{ 00354 */ 00355 00356 /** @defgroup FMAC_Exported_Functions_Group1 Initialization and de-initialization functions 00357 * @brief Initialization and Configuration functions 00358 * 00359 @verbatim 00360 =============================================================================== 00361 ##### Initialization and de-initialization functions ##### 00362 =============================================================================== 00363 [..] This section provides functions allowing to: 00364 (+) Initialize the FMAC peripheral and the associated handle 00365 (+) DeInitialize the FMAC peripheral 00366 (+) Initialize the FMAC MSP (MCU Specific Package) 00367 (+) De-Initialize the FMAC MSP 00368 (+) Register a User FMAC Callback 00369 (+) Unregister a FMAC CallBack 00370 00371 [..] 00372 00373 @endverbatim 00374 * @{ 00375 */ 00376 00377 /** 00378 * @brief Initialize the FMAC peripheral and the associated handle. 00379 * @param hfmac pointer to a FMAC_HandleTypeDef structure. 00380 * @retval HAL_StatusTypeDef HAL status 00381 */ 00382 HAL_StatusTypeDef HAL_FMAC_Init(FMAC_HandleTypeDef *hfmac) 00383 { 00384 HAL_StatusTypeDef status; 00385 00386 /* Check the FMAC handle allocation */ 00387 if (hfmac == NULL) 00388 { 00389 return HAL_ERROR; 00390 } 00391 00392 /* Check the instance */ 00393 assert_param(IS_FMAC_ALL_INSTANCE(hfmac->Instance)); 00394 00395 if (hfmac->State == HAL_FMAC_STATE_RESET) 00396 { 00397 /* Initialize lock resource */ 00398 hfmac->Lock = HAL_UNLOCKED; 00399 00400 #if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1) 00401 /* Register the default callback functions */ 00402 hfmac->ErrorCallback = HAL_FMAC_ErrorCallback; 00403 hfmac->HalfGetDataCallback = HAL_FMAC_HalfGetDataCallback; 00404 hfmac->GetDataCallback = HAL_FMAC_GetDataCallback; 00405 hfmac->HalfOutputDataReadyCallback = HAL_FMAC_HalfOutputDataReadyCallback; 00406 hfmac->OutputDataReadyCallback = HAL_FMAC_OutputDataReadyCallback; 00407 hfmac->FilterConfigCallback = HAL_FMAC_FilterConfigCallback; 00408 hfmac->FilterPreloadCallback = HAL_FMAC_FilterPreloadCallback; 00409 00410 if (hfmac->MspInitCallback == NULL) 00411 { 00412 hfmac->MspInitCallback = HAL_FMAC_MspInit; 00413 } 00414 00415 /* Init the low level hardware */ 00416 hfmac->MspInitCallback(hfmac); 00417 #else 00418 /* Init the low level hardware */ 00419 HAL_FMAC_MspInit(hfmac); 00420 #endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */ 00421 } 00422 00423 /* Reset pInput and pOutput */ 00424 hfmac->FilterParam = 0U; 00425 FMAC_ResetDataPointers(hfmac); 00426 00427 /* Reset FMAC unit (internal pointers) */ 00428 if (FMAC_Reset(hfmac) == HAL_ERROR) 00429 { 00430 /* Update FMAC error code and FMAC peripheral state */ 00431 hfmac->ErrorCode |= HAL_FMAC_ERROR_RESET; 00432 hfmac->State = HAL_FMAC_STATE_TIMEOUT; 00433 00434 status = HAL_ERROR; 00435 } 00436 else 00437 { 00438 /* Update FMAC error code and FMAC peripheral state */ 00439 hfmac->ErrorCode = HAL_FMAC_ERROR_NONE; 00440 hfmac->State = HAL_FMAC_STATE_READY; 00441 00442 status = HAL_OK; 00443 } 00444 00445 __HAL_UNLOCK(hfmac); 00446 00447 return status; 00448 } 00449 00450 /** 00451 * @brief De-initialize the FMAC peripheral. 00452 * @param hfmac pointer to a FMAC structure. 00453 * @retval HAL_StatusTypeDef HAL status 00454 */ 00455 HAL_StatusTypeDef HAL_FMAC_DeInit(FMAC_HandleTypeDef *hfmac) 00456 { 00457 /* Check the FMAC handle allocation */ 00458 if (hfmac == NULL) 00459 { 00460 return HAL_ERROR; 00461 } 00462 00463 /* Check the parameters */ 00464 assert_param(IS_FMAC_ALL_INSTANCE(hfmac->Instance)); 00465 00466 /* Change FMAC peripheral state */ 00467 hfmac->State = HAL_FMAC_STATE_BUSY; 00468 00469 /* Set FMAC error code to none */ 00470 hfmac->ErrorCode = HAL_FMAC_ERROR_NONE; 00471 00472 /* Reset pInput and pOutput */ 00473 hfmac->FilterParam = 0U; 00474 FMAC_ResetDataPointers(hfmac); 00475 00476 #if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1) 00477 if (hfmac->MspDeInitCallback == NULL) 00478 { 00479 hfmac->MspDeInitCallback = HAL_FMAC_MspDeInit; 00480 } 00481 /* DeInit the low level hardware */ 00482 hfmac->MspDeInitCallback(hfmac); 00483 #else 00484 /* DeInit the low level hardware: CLOCK, NVIC, DMA */ 00485 HAL_FMAC_MspDeInit(hfmac); 00486 #endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */ 00487 00488 /* Change FMAC peripheral state */ 00489 hfmac->State = HAL_FMAC_STATE_RESET; 00490 00491 /* Always release Lock in case of de-initialization */ 00492 __HAL_UNLOCK(hfmac); 00493 00494 return HAL_OK; 00495 } 00496 00497 /** 00498 * @brief Initialize the FMAC MSP. 00499 * @param hfmac FMAC handle. 00500 * @retval None 00501 */ 00502 __weak void HAL_FMAC_MspInit(FMAC_HandleTypeDef *hfmac) 00503 { 00504 /* Prevent unused argument(s) compilation warning */ 00505 UNUSED(hfmac); 00506 00507 /* NOTE : This function should not be modified, when the callback is needed, 00508 the HAL_FMAC_MspInit can be implemented in the user file 00509 */ 00510 } 00511 00512 /** 00513 * @brief De-initialize the FMAC MSP. 00514 * @param hfmac FMAC handle. 00515 * @retval None 00516 */ 00517 __weak void HAL_FMAC_MspDeInit(FMAC_HandleTypeDef *hfmac) 00518 { 00519 /* Prevent unused argument(s) compilation warning */ 00520 UNUSED(hfmac); 00521 00522 /* NOTE : This function should not be modified, when the callback is needed, 00523 the HAL_FMAC_MspDeInit can be implemented in the user file 00524 */ 00525 } 00526 00527 #if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1) 00528 /** 00529 * @brief Register a User FMAC Callback. 00530 * @note The User FMAC Callback is to be used instead of the weak predefined callback. 00531 * @param hfmac pointer to a FMAC_HandleTypeDef structure that contains 00532 * the configuration information for FMAC module. 00533 * @param CallbackID ID of the callback to be registered. 00534 * This parameter can be one of the following values: 00535 * @arg @ref HAL_FMAC_ERROR_CB_ID Error Callback ID 00536 * @arg @ref HAL_FMAC_HALF_GET_DATA_CB_ID Get Half Data Callback ID 00537 * @arg @ref HAL_FMAC_GET_DATA_CB_ID Get Data Callback ID 00538 * @arg @ref HAL_FMAC_HALF_OUTPUT_DATA_READY_CB_ID Half Output Data Ready Callback ID 00539 * @arg @ref HAL_FMAC_OUTPUT_DATA_READY_CB_ID Output Data Ready Callback ID 00540 * @arg @ref HAL_FMAC_FILTER_CONFIG_CB_ID Filter Configuration Callback ID 00541 * @arg @ref HAL_FMAC_FILTER_PRELOAD_CB_ID Filter Preload Callback ID 00542 * @arg @ref HAL_FMAC_MSPINIT_CB_ID FMAC MspInit ID 00543 * @arg @ref HAL_FMAC_MSPDEINIT_CB_ID FMAC MspDeInit ID 00544 * @param pCallback pointer to the Callback function. 00545 * @retval HAL_StatusTypeDef HAL status 00546 */ 00547 HAL_StatusTypeDef HAL_FMAC_RegisterCallback(FMAC_HandleTypeDef *hfmac, HAL_FMAC_CallbackIDTypeDef CallbackID, 00548 pFMAC_CallbackTypeDef pCallback) 00549 { 00550 HAL_StatusTypeDef status = HAL_OK; 00551 00552 /* Check the FMAC handle allocation */ 00553 if (hfmac == NULL) 00554 { 00555 return HAL_ERROR; 00556 } 00557 00558 if (pCallback == NULL) 00559 { 00560 /* Update the error code */ 00561 hfmac->ErrorCode |= HAL_FMAC_ERROR_INVALID_CALLBACK; 00562 00563 return HAL_ERROR; 00564 } 00565 __HAL_LOCK(hfmac); 00566 00567 if (hfmac->State == HAL_FMAC_STATE_READY) 00568 { 00569 switch (CallbackID) 00570 { 00571 case HAL_FMAC_ERROR_CB_ID : 00572 hfmac->ErrorCallback = pCallback; 00573 break; 00574 00575 case HAL_FMAC_HALF_GET_DATA_CB_ID : 00576 hfmac->HalfGetDataCallback = pCallback; 00577 break; 00578 00579 case HAL_FMAC_GET_DATA_CB_ID : 00580 hfmac->GetDataCallback = pCallback; 00581 break; 00582 00583 case HAL_FMAC_HALF_OUTPUT_DATA_READY_CB_ID : 00584 hfmac->HalfOutputDataReadyCallback = pCallback; 00585 break; 00586 00587 case HAL_FMAC_OUTPUT_DATA_READY_CB_ID : 00588 hfmac->OutputDataReadyCallback = pCallback; 00589 break; 00590 00591 case HAL_FMAC_FILTER_CONFIG_CB_ID : 00592 hfmac->FilterConfigCallback = pCallback; 00593 break; 00594 00595 case HAL_FMAC_FILTER_PRELOAD_CB_ID : 00596 hfmac->FilterPreloadCallback = pCallback; 00597 break; 00598 00599 case HAL_FMAC_MSPINIT_CB_ID : 00600 hfmac->MspInitCallback = pCallback; 00601 break; 00602 00603 case HAL_FMAC_MSPDEINIT_CB_ID : 00604 hfmac->MspDeInitCallback = pCallback; 00605 break; 00606 00607 default : 00608 /* Update the error code */ 00609 hfmac->ErrorCode |= HAL_FMAC_ERROR_INVALID_CALLBACK; 00610 00611 /* Return error status */ 00612 status = HAL_ERROR; 00613 break; 00614 } 00615 } 00616 else if (hfmac->State == HAL_FMAC_STATE_RESET) 00617 { 00618 switch (CallbackID) 00619 { 00620 case HAL_FMAC_MSPINIT_CB_ID : 00621 hfmac->MspInitCallback = pCallback; 00622 break; 00623 00624 case HAL_FMAC_MSPDEINIT_CB_ID : 00625 hfmac->MspDeInitCallback = pCallback; 00626 break; 00627 00628 default : 00629 /* Update the error code */ 00630 hfmac->ErrorCode |= HAL_FMAC_ERROR_INVALID_CALLBACK; 00631 00632 /* Return error status */ 00633 status = HAL_ERROR; 00634 break; 00635 } 00636 } 00637 else 00638 { 00639 /* Update the error code */ 00640 hfmac->ErrorCode |= HAL_FMAC_ERROR_INVALID_CALLBACK; 00641 00642 /* Return error status */ 00643 status = HAL_ERROR; 00644 } 00645 00646 __HAL_UNLOCK(hfmac); 00647 00648 return status; 00649 } 00650 00651 /** 00652 * @brief Unregister a FMAC CallBack. 00653 * @note The FMAC callback is redirected to the weak predefined callback. 00654 * @param hfmac pointer to a FMAC_HandleTypeDef structure that contains 00655 * the configuration information for FMAC module 00656 * @param CallbackID ID of the callback to be unregistered. 00657 * This parameter can be one of the following values: 00658 * @arg @ref HAL_FMAC_ERROR_CB_ID Error Callback ID 00659 * @arg @ref HAL_FMAC_HALF_GET_DATA_CB_ID Get Half Data Callback ID 00660 * @arg @ref HAL_FMAC_GET_DATA_CB_ID Get Data Callback ID 00661 * @arg @ref HAL_FMAC_HALF_OUTPUT_DATA_READY_CB_ID Half Output Data Ready Callback ID 00662 * @arg @ref HAL_FMAC_OUTPUT_DATA_READY_CB_ID Output Data Ready Callback ID 00663 * @arg @ref HAL_FMAC_FILTER_CONFIG_CB_ID Filter Configuration Callback ID 00664 * @arg @ref HAL_FMAC_FILTER_PRELOAD_CB_ID Filter Preload Callback ID 00665 * @arg @ref HAL_FMAC_MSPINIT_CB_ID FMAC MspInit ID 00666 * @arg @ref HAL_FMAC_MSPDEINIT_CB_ID FMAC MspDeInit ID 00667 * @retval HAL_StatusTypeDef HAL status 00668 */ 00669 HAL_StatusTypeDef HAL_FMAC_UnRegisterCallback(FMAC_HandleTypeDef *hfmac, HAL_FMAC_CallbackIDTypeDef CallbackID) 00670 { 00671 HAL_StatusTypeDef status = HAL_OK; 00672 00673 /* Check the FMAC handle allocation */ 00674 if (hfmac == NULL) 00675 { 00676 return HAL_ERROR; 00677 } 00678 00679 __HAL_LOCK(hfmac); 00680 00681 if (hfmac->State == HAL_FMAC_STATE_READY) 00682 { 00683 switch (CallbackID) 00684 { 00685 case HAL_FMAC_ERROR_CB_ID : 00686 hfmac->ErrorCallback = HAL_FMAC_ErrorCallback; /* Legacy weak ErrorCallback */ 00687 break; 00688 00689 case HAL_FMAC_HALF_GET_DATA_CB_ID : 00690 hfmac->HalfGetDataCallback = HAL_FMAC_HalfGetDataCallback; /* Legacy weak HalfGetDataCallback */ 00691 break; 00692 00693 case HAL_FMAC_GET_DATA_CB_ID : 00694 hfmac->GetDataCallback = HAL_FMAC_GetDataCallback; /* Legacy weak GetDataCallback */ 00695 break; 00696 00697 case HAL_FMAC_HALF_OUTPUT_DATA_READY_CB_ID : 00698 hfmac->HalfOutputDataReadyCallback = HAL_FMAC_HalfOutputDataReadyCallback; /* Legacy weak 00699 HalfOutputDataReadyCallback */ 00700 break; 00701 00702 case HAL_FMAC_OUTPUT_DATA_READY_CB_ID : 00703 hfmac->OutputDataReadyCallback = HAL_FMAC_OutputDataReadyCallback; /* Legacy weak 00704 OutputDataReadyCallback */ 00705 break; 00706 00707 case HAL_FMAC_FILTER_CONFIG_CB_ID : 00708 hfmac->FilterConfigCallback = HAL_FMAC_FilterConfigCallback; /* Legacy weak 00709 FilterConfigCallback */ 00710 break; 00711 00712 case HAL_FMAC_FILTER_PRELOAD_CB_ID : 00713 hfmac->FilterPreloadCallback = HAL_FMAC_FilterPreloadCallback; /* Legacy weak FilterPreloadCallba */ 00714 break; 00715 00716 case HAL_FMAC_MSPINIT_CB_ID : 00717 hfmac->MspInitCallback = HAL_FMAC_MspInit; /* Legacy weak MspInitCallback */ 00718 break; 00719 00720 case HAL_FMAC_MSPDEINIT_CB_ID : 00721 hfmac->MspDeInitCallback = HAL_FMAC_MspDeInit; /* Legacy weak MspDeInitCallback */ 00722 break; 00723 00724 default : 00725 /* Update the error code */ 00726 hfmac->ErrorCode |= HAL_FMAC_ERROR_INVALID_CALLBACK; 00727 00728 /* Return error status */ 00729 status = HAL_ERROR; 00730 break; 00731 } 00732 } 00733 else if (hfmac->State == HAL_FMAC_STATE_RESET) 00734 { 00735 switch (CallbackID) 00736 { 00737 case HAL_FMAC_MSPINIT_CB_ID : 00738 hfmac->MspInitCallback = HAL_FMAC_MspInit; 00739 break; 00740 00741 case HAL_FMAC_MSPDEINIT_CB_ID : 00742 hfmac->MspDeInitCallback = HAL_FMAC_MspDeInit; 00743 break; 00744 00745 default : 00746 /* Update the error code */ 00747 hfmac->ErrorCode |= HAL_FMAC_ERROR_INVALID_CALLBACK; 00748 00749 /* Return error status */ 00750 status = HAL_ERROR; 00751 break; 00752 } 00753 } 00754 else 00755 { 00756 /* Update the error code */ 00757 hfmac->ErrorCode |= HAL_FMAC_ERROR_INVALID_CALLBACK; 00758 00759 /* Return error status */ 00760 status = HAL_ERROR; 00761 } 00762 00763 __HAL_UNLOCK(hfmac); 00764 00765 return status; 00766 } 00767 #endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */ 00768 00769 /** 00770 * @} 00771 */ 00772 00773 /** @defgroup FMAC_Exported_Functions_Group2 Peripheral Control functions 00774 * @brief Control functions. 00775 * 00776 @verbatim 00777 ============================================================================== 00778 ##### Peripheral Control functions ##### 00779 ============================================================================== 00780 [..] This section provides functions allowing to: 00781 (+) Configure the FMAC peripheral: memory area, filter type and parameters, 00782 way to access to the input and output memory area (none, polling, IT, DMA). 00783 (+) Start the FMAC processing (filter). 00784 (+) Handle the input data that will be provided into FMAC. 00785 (+) Handle the output data provided by FMAC. 00786 (+) Stop the FMAC processing (filter). 00787 00788 @endverbatim 00789 * @{ 00790 */ 00791 00792 /** 00793 * @brief Configure the FMAC filter. 00794 * @note The configuration is done according to the parameters 00795 * specified in the FMAC_FilterConfigTypeDef structure. 00796 * The provided data will be loaded using polling mode. 00797 * @param hfmac pointer to a FMAC_HandleTypeDef structure that contains 00798 * the configuration information for FMAC module. 00799 * @param pConfig pointer to a FMAC_FilterConfigTypeDef structure that 00800 * contains the FMAC configuration information. 00801 * @retval HAL_StatusTypeDef HAL status 00802 */ 00803 HAL_StatusTypeDef HAL_FMAC_FilterConfig(FMAC_HandleTypeDef *hfmac, FMAC_FilterConfigTypeDef *pConfig) 00804 { 00805 return (FMAC_FilterConfig(hfmac, pConfig, PRELOAD_ACCESS_POLLING)); 00806 } 00807 00808 /** 00809 * @brief Configure the FMAC filter. 00810 * @note The configuration is done according to the parameters 00811 * specified in the FMAC_FilterConfigTypeDef structure. 00812 * The provided data will be loaded using DMA. 00813 * @param hfmac pointer to a FMAC_HandleTypeDef structure that contains 00814 * the configuration information for FMAC module. 00815 * @param pConfig pointer to a FMAC_FilterConfigTypeDef structure that 00816 * contains the FMAC configuration information. 00817 * @retval HAL_StatusTypeDef HAL status 00818 */ 00819 HAL_StatusTypeDef HAL_FMAC_FilterConfig_DMA(FMAC_HandleTypeDef *hfmac, FMAC_FilterConfigTypeDef *pConfig) 00820 { 00821 return (FMAC_FilterConfig(hfmac, pConfig, PRELOAD_ACCESS_DMA)); 00822 } 00823 00824 /** 00825 * @brief Preload the input (FIR, IIR) and output data (IIR) of the FMAC filter. 00826 * @note The set(s) of data will be used by FMAC as soon as @ref HAL_FMAC_FilterStart is called. 00827 * The provided data will be loaded using polling mode. 00828 * @param hfmac pointer to a FMAC_HandleTypeDef structure that contains 00829 * the configuration information for FMAC module. 00830 * @param pInput Preloading of the first elements of the input buffer (X1). 00831 * If not needed (no data available when starting), it should be set to NULL. 00832 * @param InputSize Size of the input vector. 00833 * As pInput is used for preloading data, it cannot be bigger than the input memory area. 00834 * @param pOutput [IIR] Preloading of the first elements of the output vector (Y). 00835 * If not needed, it should be set to NULL. 00836 * @param OutputSize Size of the output vector. 00837 * As pOutput is used for preloading data, it cannot be bigger than the output memory area. 00838 * @note The input and the output buffers can be filled by calling several times @ref HAL_FMAC_FilterPreload 00839 * (each call filling partly the buffers). In case of overflow (too much data provided through 00840 * all these calls), an error will be returned. 00841 * @retval HAL_StatusTypeDef HAL status 00842 */ 00843 HAL_StatusTypeDef HAL_FMAC_FilterPreload(FMAC_HandleTypeDef *hfmac, int16_t *pInput, uint8_t InputSize, 00844 int16_t *pOutput, uint8_t OutputSize) 00845 { 00846 return (FMAC_FilterPreload(hfmac, pInput, InputSize, pOutput, OutputSize, PRELOAD_ACCESS_POLLING)); 00847 } 00848 00849 /** 00850 * @brief Preload the input (FIR, IIR) and output data (IIR) of the FMAC filter. 00851 * @note The set(s) of data will be used by FMAC as soon as @ref HAL_FMAC_FilterStart is called. 00852 * The provided data will be loaded using DMA. 00853 * @param hfmac pointer to a FMAC_HandleTypeDef structure that contains 00854 * the configuration information for FMAC module. 00855 * @param pInput Preloading of the first elements of the input buffer (X1). 00856 * If not needed (no data available when starting), it should be set to NULL. 00857 * @param InputSize Size of the input vector. 00858 * As pInput is used for preloading data, it cannot be bigger than the input memory area. 00859 * @param pOutput [IIR] Preloading of the first elements of the output vector (Y). 00860 * If not needed, it should be set to NULL. 00861 * @param OutputSize Size of the output vector. 00862 * As pOutput is used for preloading data, it cannot be bigger than the output memory area. 00863 * @note The input and the output buffers can be filled by calling several times @ref HAL_FMAC_FilterPreload 00864 * (each call filling partly the buffers). In case of overflow (too much data provided through 00865 * all these calls), an error will be returned. 00866 * @retval HAL_StatusTypeDef HAL status 00867 */ 00868 HAL_StatusTypeDef HAL_FMAC_FilterPreload_DMA(FMAC_HandleTypeDef *hfmac, int16_t *pInput, uint8_t InputSize, 00869 int16_t *pOutput, uint8_t OutputSize) 00870 { 00871 return (FMAC_FilterPreload(hfmac, pInput, InputSize, pOutput, OutputSize, PRELOAD_ACCESS_DMA)); 00872 } 00873 00874 00875 /** 00876 * @brief Start the FMAC processing according to the existing FMAC configuration. 00877 * @param hfmac pointer to a FMAC_HandleTypeDef structure that contains 00878 * the configuration information for FMAC module. 00879 * @param pOutput pointer to buffer where output data of FMAC processing will be stored 00880 * in the next steps. 00881 * If it is set to NULL, the output will not be read and it will be up to 00882 * an external IP to empty the output buffer. 00883 * @param pOutputSize pointer to the size of the output buffer. The number of read data will be written here. 00884 * @retval HAL_StatusTypeDef HAL status 00885 */ 00886 HAL_StatusTypeDef HAL_FMAC_FilterStart(FMAC_HandleTypeDef *hfmac, int16_t *pOutput, uint16_t *pOutputSize) 00887 { 00888 uint32_t tmpcr = 0U; 00889 HAL_StatusTypeDef status; 00890 00891 /* Check the START bit state */ 00892 if (FMAC_GET_START_BIT(hfmac) != 0U) 00893 { 00894 return HAL_ERROR; 00895 } 00896 00897 /* Check that a valid configuration was done previously */ 00898 if (hfmac->FilterParam == 0U) 00899 { 00900 return HAL_ERROR; 00901 } 00902 00903 /* Check handle state is ready */ 00904 if (hfmac->State == HAL_FMAC_STATE_READY) 00905 { 00906 /* Change the FMAC state */ 00907 hfmac->State = HAL_FMAC_STATE_BUSY; 00908 00909 /* CR: Configure the input access (error interruptions enabled only for IT or DMA) */ 00910 if (hfmac->InputAccess == FMAC_BUFFER_ACCESS_DMA) 00911 { 00912 tmpcr |= FMAC_DMA_WEN; 00913 } 00914 else if (hfmac->InputAccess == FMAC_BUFFER_ACCESS_IT) 00915 { 00916 tmpcr |= FMAC_IT_WIEN; 00917 } 00918 else 00919 { 00920 /* nothing to do */ 00921 } 00922 00923 /* CR: Configure the output access (error interruptions enabled only for IT or DMA) */ 00924 if (hfmac->OutputAccess == FMAC_BUFFER_ACCESS_DMA) 00925 { 00926 tmpcr |= FMAC_DMA_REN; 00927 } 00928 else if (hfmac->OutputAccess == FMAC_BUFFER_ACCESS_IT) 00929 { 00930 tmpcr |= FMAC_IT_RIEN; 00931 } 00932 else 00933 { 00934 /* nothing to do */ 00935 } 00936 00937 /* CR: Write the configuration */ 00938 MODIFY_REG(hfmac->Instance->CR, \ 00939 FMAC_IT_RIEN | FMAC_IT_WIEN | FMAC_DMA_REN | FMAC_CR_DMAWEN, \ 00940 tmpcr); 00941 00942 /* Register the new output buffer */ 00943 status = FMAC_ConfigFilterOutputBufferUpdateState(hfmac, pOutput, pOutputSize); 00944 00945 if (status == HAL_OK) 00946 { 00947 /* PARAM: Start the filter ( this can generate interrupts before the end of the HAL_FMAC_FilterStart ) */ 00948 WRITE_REG(hfmac->Instance->PARAM, (uint32_t)(hfmac->FilterParam)); 00949 } 00950 00951 /* Reset the busy flag (do not overwrite the possible write and read flag) */ 00952 hfmac->State = HAL_FMAC_STATE_READY; 00953 } 00954 else 00955 { 00956 status = HAL_ERROR; 00957 } 00958 00959 return status; 00960 } 00961 00962 /** 00963 * @brief Provide a new input buffer that will be loaded into the FMAC input memory area. 00964 * @param hfmac pointer to a FMAC_HandleTypeDef structure that contains 00965 * the configuration information for FMAC module. 00966 * @param pInput New input vector (additional input data). 00967 * @param pInputSize Size of the input vector (if all the data can't be 00968 * written, it will be updated with the number of data read from FMAC). 00969 * @retval HAL_StatusTypeDef HAL status 00970 */ 00971 HAL_StatusTypeDef HAL_FMAC_AppendFilterData(FMAC_HandleTypeDef *hfmac, int16_t *pInput, uint16_t *pInputSize) 00972 { 00973 HAL_StatusTypeDef status; 00974 00975 /* Check the function parameters */ 00976 if ((pInput == NULL) || (pInputSize == NULL)) 00977 { 00978 return HAL_ERROR; 00979 } 00980 if (*pInputSize == 0U) 00981 { 00982 return HAL_ERROR; 00983 } 00984 00985 /* Check the START bit state */ 00986 if (FMAC_GET_START_BIT(hfmac) == 0U) 00987 { 00988 return HAL_ERROR; 00989 } 00990 00991 /* Check the FMAC configuration */ 00992 if (hfmac->InputAccess == FMAC_BUFFER_ACCESS_NONE) 00993 { 00994 return HAL_ERROR; 00995 } 00996 00997 /* Check whether the previous input vector has been handled */ 00998 if ((hfmac->pInputSize != NULL) && (hfmac->InputCurrentSize < * (hfmac->pInputSize))) 00999 { 01000 return HAL_ERROR; 01001 } 01002 01003 /* Check that FMAC was initialized and that no writing is already ongoing */ 01004 if (hfmac->WrState == HAL_FMAC_STATE_READY) 01005 { 01006 /* Register the new input buffer */ 01007 status = FMAC_AppendFilterDataUpdateState(hfmac, pInput, pInputSize); 01008 } 01009 else 01010 { 01011 status = HAL_ERROR; 01012 } 01013 01014 return status; 01015 } 01016 01017 /** 01018 * @brief Provide a new output buffer to be filled with the data computed by FMAC unit. 01019 * @param hfmac pointer to a FMAC_HandleTypeDef structure that contains 01020 * the configuration information for FMAC module. 01021 * @param pOutput New output vector. 01022 * @param pOutputSize Size of the output vector (if the vector can't 01023 * be entirely filled, pOutputSize will be updated with the number 01024 * of data read from FMAC). 01025 * @retval HAL_StatusTypeDef HAL status 01026 */ 01027 HAL_StatusTypeDef HAL_FMAC_ConfigFilterOutputBuffer(FMAC_HandleTypeDef *hfmac, int16_t *pOutput, uint16_t *pOutputSize) 01028 { 01029 HAL_StatusTypeDef status; 01030 01031 /* Check the function parameters */ 01032 if ((pOutput == NULL) || (pOutputSize == NULL)) 01033 { 01034 return HAL_ERROR; 01035 } 01036 if (*pOutputSize == 0U) 01037 { 01038 return HAL_ERROR; 01039 } 01040 01041 /* Check the START bit state */ 01042 if (FMAC_GET_START_BIT(hfmac) == 0U) 01043 { 01044 return HAL_ERROR; 01045 } 01046 01047 /* Check the FMAC configuration */ 01048 if (hfmac->OutputAccess == FMAC_BUFFER_ACCESS_NONE) 01049 { 01050 return HAL_ERROR; 01051 } 01052 01053 /* Check whether the previous output vector has been handled */ 01054 if ((hfmac->pOutputSize != NULL) && (hfmac->OutputCurrentSize < * (hfmac->pOutputSize))) 01055 { 01056 return HAL_ERROR; 01057 } 01058 01059 /* Check that FMAC was initialized and that not reading is already ongoing */ 01060 if (hfmac->RdState == HAL_FMAC_STATE_READY) 01061 { 01062 /* Register the new output buffer */ 01063 status = FMAC_ConfigFilterOutputBufferUpdateState(hfmac, pOutput, pOutputSize); 01064 } 01065 else 01066 { 01067 status = HAL_ERROR; 01068 } 01069 01070 return status; 01071 } 01072 01073 /** 01074 * @brief Handle the input and/or output data in polling mode 01075 * @note This function writes the previously provided user's input data and 01076 * fills the previously provided user's output buffer, 01077 * according to the existing FMAC configuration (polling mode only). 01078 * The function returns when the input data has been handled or 01079 * when the output data is filled. The possible unused data isn't 01080 * kept. It will be up to the user to handle it. The previously 01081 * provided pInputSize and pOutputSize will be used to indicate to the 01082 * size of the read/written data to the user. 01083 * @param hfmac pointer to a FMAC_HandleTypeDef structure that contains 01084 * the configuration information for FMAC module. 01085 * @param Timeout timeout value. 01086 * @retval HAL_StatusTypeDef HAL status 01087 */ 01088 HAL_StatusTypeDef HAL_FMAC_PollFilterData(FMAC_HandleTypeDef *hfmac, uint32_t Timeout) 01089 { 01090 uint32_t tickstart; 01091 uint8_t inpolling; 01092 uint8_t inpollingover = POLLING_NOT_STOPPED; 01093 uint8_t outpolling; 01094 uint8_t outpollingover = POLLING_NOT_STOPPED; 01095 HAL_StatusTypeDef status; 01096 01097 /* Check the START bit state */ 01098 if (FMAC_GET_START_BIT(hfmac) == 0U) 01099 { 01100 return HAL_ERROR; 01101 } 01102 01103 /* Check the configuration */ 01104 01105 /* Get the input and output mode (if no buffer was previously provided, nothing will be read/written) */ 01106 if ((hfmac->InputAccess == FMAC_BUFFER_ACCESS_POLLING) && (hfmac->pInput != NULL)) 01107 { 01108 inpolling = POLLING_ENABLED; 01109 } 01110 else 01111 { 01112 inpolling = POLLING_DISABLED; 01113 } 01114 if ((hfmac->OutputAccess == FMAC_BUFFER_ACCESS_POLLING) && (hfmac->pOutput != NULL)) 01115 { 01116 outpolling = POLLING_ENABLED; 01117 } 01118 else 01119 { 01120 outpolling = POLLING_DISABLED; 01121 } 01122 01123 /* Check the configuration */ 01124 if ((inpolling == POLLING_DISABLED) && (outpolling == POLLING_DISABLED)) 01125 { 01126 return HAL_ERROR; 01127 } 01128 01129 /* Check handle state is ready */ 01130 if (hfmac->State == HAL_FMAC_STATE_READY) 01131 { 01132 /* Change the FMAC state */ 01133 hfmac->State = HAL_FMAC_STATE_BUSY; 01134 01135 /* Get tick */ 01136 tickstart = HAL_GetTick(); 01137 01138 /* Loop on reading and writing until timeout */ 01139 while ((HAL_GetTick() - tickstart) < Timeout) 01140 { 01141 /* X1: Check the mode: polling or none */ 01142 if (inpolling != POLLING_DISABLED) 01143 { 01144 FMAC_WriteDataIncrementPtr(hfmac, MAX_FILTER_DATA_SIZE_TO_HANDLE); 01145 if (hfmac->InputCurrentSize == *(hfmac->pInputSize)) 01146 { 01147 inpollingover = POLLING_STOPPED; 01148 } 01149 } 01150 01151 /* Y: Check the mode: polling or none */ 01152 if (outpolling != POLLING_DISABLED) 01153 { 01154 FMAC_ReadDataIncrementPtr(hfmac, MAX_FILTER_DATA_SIZE_TO_HANDLE); 01155 if (hfmac->OutputCurrentSize == *(hfmac->pOutputSize)) 01156 { 01157 outpollingover = POLLING_STOPPED; 01158 } 01159 } 01160 01161 /* Exit if there isn't data to handle anymore on one side or another */ 01162 if ((inpollingover != POLLING_NOT_STOPPED) || (outpollingover != POLLING_NOT_STOPPED)) 01163 { 01164 break; 01165 } 01166 } 01167 01168 /* Change the FMAC state; update the input and output sizes; reset the indexes */ 01169 if (inpolling != POLLING_DISABLED) 01170 { 01171 (*(hfmac->pInputSize)) = hfmac->InputCurrentSize; 01172 FMAC_ResetInputStateAndDataPointers(hfmac); 01173 } 01174 if (outpolling != POLLING_DISABLED) 01175 { 01176 (*(hfmac->pOutputSize)) = hfmac->OutputCurrentSize; 01177 FMAC_ResetOutputStateAndDataPointers(hfmac); 01178 } 01179 01180 /* Reset the busy flag (do not overwrite the possible write and read flag) */ 01181 hfmac->State = HAL_FMAC_STATE_READY; 01182 01183 if ((HAL_GetTick() - tickstart) >= Timeout) 01184 { 01185 hfmac->ErrorCode |= HAL_FMAC_ERROR_TIMEOUT; 01186 status = HAL_ERROR; 01187 } 01188 else 01189 { 01190 status = HAL_OK; 01191 } 01192 } 01193 else 01194 { 01195 status = HAL_ERROR; 01196 } 01197 01198 return status; 01199 } 01200 01201 /** 01202 * @brief Stop the FMAC processing. 01203 * @param hfmac pointer to a FMAC_HandleTypeDef structure that contains 01204 * the configuration information for FMAC module. 01205 * @retval HAL_StatusTypeDef HAL status 01206 */ 01207 HAL_StatusTypeDef HAL_FMAC_FilterStop(FMAC_HandleTypeDef *hfmac) 01208 { 01209 HAL_StatusTypeDef status; 01210 01211 /* Check handle state is ready */ 01212 if (hfmac->State == HAL_FMAC_STATE_READY) 01213 { 01214 /* Change the FMAC state */ 01215 hfmac->State = HAL_FMAC_STATE_BUSY; 01216 01217 /* Set the START bit to 0 (stop the previously configured filter) */ 01218 CLEAR_BIT(hfmac->Instance->PARAM, FMAC_PARAM_START); 01219 01220 /* Disable the interrupts in order to avoid crossing cases */ 01221 CLEAR_BIT(hfmac->Instance->CR, FMAC_DMA_REN | FMAC_DMA_WEN | FMAC_IT_RIEN | FMAC_IT_WIEN); 01222 01223 /* In case of IT, update the sizes */ 01224 if ((hfmac->InputAccess == FMAC_BUFFER_ACCESS_IT) && (hfmac->pInput != NULL)) 01225 { 01226 (*(hfmac->pInputSize)) = hfmac->InputCurrentSize; 01227 } 01228 if ((hfmac->OutputAccess == FMAC_BUFFER_ACCESS_IT) && (hfmac->pOutput != NULL)) 01229 { 01230 (*(hfmac->pOutputSize)) = hfmac->OutputCurrentSize; 01231 } 01232 01233 /* Reset FMAC unit (internal pointers) */ 01234 if (FMAC_Reset(hfmac) == HAL_ERROR) 01235 { 01236 /* Update FMAC error code and FMAC peripheral state */ 01237 hfmac->ErrorCode = HAL_FMAC_ERROR_RESET; 01238 hfmac->State = HAL_FMAC_STATE_TIMEOUT; 01239 status = HAL_ERROR; 01240 } 01241 else 01242 { 01243 /* Reset the data pointers */ 01244 FMAC_ResetDataPointers(hfmac); 01245 01246 status = HAL_OK; 01247 } 01248 01249 /* Reset the busy flag */ 01250 hfmac->State = HAL_FMAC_STATE_READY; 01251 } 01252 else 01253 { 01254 status = HAL_ERROR; 01255 } 01256 01257 return status; 01258 } 01259 01260 /** 01261 * @} 01262 */ 01263 01264 /** @defgroup FMAC_Exported_Functions_Group3 Callback functions 01265 * @brief Callback functions. 01266 * 01267 @verbatim 01268 ============================================================================== 01269 ##### Callback functions ##### 01270 ============================================================================== 01271 [..] This section provides Interruption and DMA callback functions: 01272 (+) DMA or Interrupt: the user's input data is half written (DMA only) 01273 or completely written. 01274 (+) DMA or Interrupt: the user's output buffer is half filled (DMA only) 01275 or completely filled. 01276 (+) DMA or Interrupt: error handling. 01277 01278 @endverbatim 01279 * @{ 01280 */ 01281 01282 /** 01283 * @brief FMAC error callback. 01284 * @param hfmac pointer to a FMAC_HandleTypeDef structure that contains 01285 * the configuration information for FMAC module. 01286 * @retval None 01287 */ 01288 __weak void HAL_FMAC_ErrorCallback(FMAC_HandleTypeDef *hfmac) 01289 { 01290 /* Prevent unused argument(s) compilation warning */ 01291 UNUSED(hfmac); 01292 01293 /* NOTE : This function should not be modified; when the callback is needed, 01294 the HAL_FMAC_ErrorCallback can be implemented in the user file. 01295 */ 01296 } 01297 01298 /** 01299 * @brief FMAC get half data callback. 01300 * @param hfmac pointer to a FMAC_HandleTypeDef structure that contains 01301 * the configuration information for FMAC module. 01302 * @retval None 01303 */ 01304 __weak void HAL_FMAC_HalfGetDataCallback(FMAC_HandleTypeDef *hfmac) 01305 { 01306 /* Prevent unused argument(s) compilation warning */ 01307 UNUSED(hfmac); 01308 01309 /* NOTE : This function should not be modified; when the callback is needed, 01310 the HAL_FMAC_HalfGetDataCallback can be implemented in the user file. 01311 */ 01312 } 01313 01314 /** 01315 * @brief FMAC get data callback. 01316 * @param hfmac pointer to a FMAC_HandleTypeDef structure that contains 01317 * the configuration information for FMAC module. 01318 * @retval None 01319 */ 01320 __weak void HAL_FMAC_GetDataCallback(FMAC_HandleTypeDef *hfmac) 01321 { 01322 /* Prevent unused argument(s) compilation warning */ 01323 UNUSED(hfmac); 01324 01325 /* NOTE : This function should not be modified; when the callback is needed, 01326 the HAL_FMAC_GetDataCallback can be implemented in the user file. 01327 */ 01328 } 01329 01330 /** 01331 * @brief FMAC half output data ready callback. 01332 * @param hfmac pointer to a FMAC_HandleTypeDef structure that contains 01333 * the configuration information for FMAC module. 01334 * @retval None 01335 */ 01336 __weak void HAL_FMAC_HalfOutputDataReadyCallback(FMAC_HandleTypeDef *hfmac) 01337 { 01338 /* Prevent unused argument(s) compilation warning */ 01339 UNUSED(hfmac); 01340 01341 /* NOTE : This function should not be modified; when the callback is needed, 01342 the HAL_FMAC_HalfOutputDataReadyCallback can be implemented in the user file. 01343 */ 01344 } 01345 01346 /** 01347 * @brief FMAC output data ready callback. 01348 * @param hfmac pointer to a FMAC_HandleTypeDef structure that contains 01349 * the configuration information for FMAC module. 01350 * @retval None 01351 */ 01352 __weak void HAL_FMAC_OutputDataReadyCallback(FMAC_HandleTypeDef *hfmac) 01353 { 01354 /* Prevent unused argument(s) compilation warning */ 01355 UNUSED(hfmac); 01356 01357 /* NOTE : This function should not be modified; when the callback is needed, 01358 the HAL_FMAC_OutputDataReadyCallback can be implemented in the user file. 01359 */ 01360 } 01361 01362 /** 01363 * @brief FMAC filter configuration callback. 01364 * @param hfmac pointer to a FMAC_HandleTypeDef structure that contains 01365 * the configuration information for FMAC module. 01366 * @retval None 01367 */ 01368 __weak void HAL_FMAC_FilterConfigCallback(FMAC_HandleTypeDef *hfmac) 01369 { 01370 /* Prevent unused argument(s) compilation warning */ 01371 UNUSED(hfmac); 01372 01373 /* NOTE : This function should not be modified; when the callback is needed, 01374 the HAL_FMAC_FilterConfigCallback can be implemented in the user file. 01375 */ 01376 } 01377 01378 /** 01379 * @brief FMAC filter preload callback. 01380 * @param hfmac pointer to a FMAC_HandleTypeDef structure that contains 01381 * the configuration information for FMAC module. 01382 * @retval None 01383 */ 01384 __weak void HAL_FMAC_FilterPreloadCallback(FMAC_HandleTypeDef *hfmac) 01385 { 01386 /* Prevent unused argument(s) compilation warning */ 01387 UNUSED(hfmac); 01388 01389 /* NOTE : This function should not be modified; when the callback is needed, 01390 the HAL_FMAC_FilterPreloadCallback can be implemented in the user file. 01391 */ 01392 } 01393 01394 /** 01395 * @} 01396 */ 01397 01398 /** @defgroup FMAC_Exported_Functions_Group4 IRQ handler management 01399 * @brief IRQ handler. 01400 * 01401 @verbatim 01402 ============================================================================== 01403 ##### IRQ handler management ##### 01404 ============================================================================== 01405 [..] This section provides IRQ handler function. 01406 01407 @endverbatim 01408 * @{ 01409 */ 01410 01411 /** 01412 * @brief Handle FMAC interrupt request. 01413 * @param hfmac pointer to a FMAC_HandleTypeDef structure that contains 01414 * the configuration information for FMAC module. 01415 * @retval None 01416 */ 01417 void HAL_FMAC_IRQHandler(FMAC_HandleTypeDef *hfmac) 01418 { 01419 uint32_t itsource; 01420 01421 /* Check if the read interrupt is enabled and if Y buffer empty flag isn't set */ 01422 itsource = __HAL_FMAC_GET_IT_SOURCE(hfmac, FMAC_IT_RIEN); 01423 if ((__HAL_FMAC_GET_FLAG(hfmac, FMAC_FLAG_YEMPTY) == 0U) && (itsource != 0U)) 01424 { 01425 /* Read some data if possible (Y size is used as a pseudo timeout in order 01426 to not get stuck too long under IT if FMAC keeps on processing input 01427 data reloaded via DMA for instance). */ 01428 if (hfmac->pOutput != NULL) 01429 { 01430 FMAC_ReadDataIncrementPtr(hfmac, (uint16_t)FMAC_GET_Y_SIZE(hfmac)); 01431 } 01432 01433 /* Indicate that data is ready to be read */ 01434 if ((hfmac->pOutput == NULL) || (hfmac->OutputCurrentSize == *(hfmac->pOutputSize))) 01435 { 01436 /* Reset the pointers to indicate new data will be needed */ 01437 FMAC_ResetOutputStateAndDataPointers(hfmac); 01438 01439 /* Call the output data ready callback */ 01440 #if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1) 01441 hfmac->OutputDataReadyCallback(hfmac); 01442 #else 01443 HAL_FMAC_OutputDataReadyCallback(hfmac); 01444 #endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */ 01445 } 01446 } 01447 01448 /* Check if the write interrupt is enabled and if X1 buffer full flag isn't set */ 01449 itsource = __HAL_FMAC_GET_IT_SOURCE(hfmac, FMAC_IT_WIEN); 01450 if ((__HAL_FMAC_GET_FLAG(hfmac, FMAC_FLAG_X1FULL) == 0U) && (itsource != 0U)) 01451 { 01452 /* Write some data if possible (X1 size is used as a pseudo timeout in order 01453 to not get stuck too long under IT if FMAC keep on processing input 01454 data whereas its output emptied via DMA for instance). */ 01455 if (hfmac->pInput != NULL) 01456 { 01457 FMAC_WriteDataIncrementPtr(hfmac, (uint16_t)FMAC_GET_X1_SIZE(hfmac)); 01458 } 01459 01460 /* Indicate that new data will be needed */ 01461 if ((hfmac->pInput == NULL) || (hfmac->InputCurrentSize == *(hfmac->pInputSize))) 01462 { 01463 /* Reset the pointers to indicate new data will be needed */ 01464 FMAC_ResetInputStateAndDataPointers(hfmac); 01465 01466 /* Call the get data callback */ 01467 #if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1) 01468 hfmac->GetDataCallback(hfmac); 01469 #else 01470 HAL_FMAC_GetDataCallback(hfmac); 01471 #endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */ 01472 } 01473 } 01474 01475 /* Check if the overflow error interrupt is enabled and if overflow error flag is raised */ 01476 itsource = __HAL_FMAC_GET_IT_SOURCE(hfmac, FMAC_IT_OVFLIEN); 01477 if ((__HAL_FMAC_GET_FLAG(hfmac, FMAC_FLAG_OVFL) != 0U) && (itsource != 0U)) 01478 { 01479 hfmac->ErrorCode |= HAL_FMAC_ERROR_OVFL; 01480 } 01481 01482 /* Check if the underflow error interrupt is enabled and if underflow error flag is raised */ 01483 itsource = __HAL_FMAC_GET_IT_SOURCE(hfmac, FMAC_IT_UNFLIEN); 01484 if ((__HAL_FMAC_GET_FLAG(hfmac, FMAC_FLAG_UNFL) != 0U) && (itsource != 0U)) 01485 { 01486 hfmac->ErrorCode |= HAL_FMAC_ERROR_UNFL; 01487 } 01488 01489 /* Check if the saturation error interrupt is enabled and if saturation error flag is raised */ 01490 itsource = __HAL_FMAC_GET_IT_SOURCE(hfmac, FMAC_IT_SATIEN); 01491 if ((__HAL_FMAC_GET_FLAG(hfmac, FMAC_FLAG_SAT) != 0U) && (itsource != 0U)) 01492 { 01493 hfmac->ErrorCode |= HAL_FMAC_ERROR_SAT; 01494 } 01495 01496 /* Call the error callback if an error occurred */ 01497 if (hfmac->ErrorCode != HAL_FMAC_ERROR_NONE) 01498 { 01499 /* Call the error callback */ 01500 #if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1) 01501 hfmac->ErrorCallback(hfmac); 01502 #else 01503 HAL_FMAC_ErrorCallback(hfmac); 01504 #endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */ 01505 } 01506 } 01507 01508 /** 01509 * @} 01510 */ 01511 01512 /** @defgroup FMAC_Exported_Functions_Group5 Peripheral State and Error functions 01513 * @brief Peripheral State and Error functions. 01514 * 01515 @verbatim 01516 ============================================================================== 01517 ##### Peripheral State and Error functions ##### 01518 ============================================================================== 01519 [..] This subsection provides functions allowing to 01520 (+) Check the FMAC state 01521 (+) Get error code 01522 01523 @endverbatim 01524 * @{ 01525 */ 01526 01527 /** 01528 * @brief Return the FMAC state. 01529 * @param hfmac pointer to a FMAC_HandleTypeDef structure that contains 01530 * the configuration information for FMAC module. 01531 * @retval HAL_FMAC_StateTypeDef FMAC state 01532 */ 01533 HAL_FMAC_StateTypeDef HAL_FMAC_GetState(FMAC_HandleTypeDef *hfmac) 01534 { 01535 /* Return FMAC state */ 01536 return hfmac->State; 01537 } 01538 01539 /** 01540 * @brief Return the FMAC peripheral error. 01541 * @param hfmac pointer to a FMAC_HandleTypeDef structure that contains 01542 * the configuration information for FMAC module. 01543 * @note The returned error is a bit-map combination of possible errors. 01544 * @retval uint32_t Error bit-map based on @ref FMAC_Error_Code 01545 */ 01546 uint32_t HAL_FMAC_GetError(FMAC_HandleTypeDef *hfmac) 01547 { 01548 /* Return FMAC error code */ 01549 return hfmac->ErrorCode; 01550 } 01551 01552 /** 01553 * @} 01554 */ 01555 01556 /** 01557 * @} 01558 */ 01559 01560 /** @defgroup FMAC_Private_Functions FMAC Private Functions 01561 * @{ 01562 */ 01563 01564 /** 01565 ============================================================================== 01566 ##### FMAC Private Functions ##### 01567 ============================================================================== 01568 */ 01569 /** 01570 * @brief Perform a reset of the FMAC unit. 01571 * @param hfmac FMAC handle. 01572 * @retval HAL_StatusTypeDef HAL status 01573 */ 01574 static HAL_StatusTypeDef FMAC_Reset(FMAC_HandleTypeDef *hfmac) 01575 { 01576 uint32_t tickstart; 01577 01578 /* Init tickstart for timeout management*/ 01579 tickstart = HAL_GetTick(); 01580 01581 /* Perform the reset */ 01582 SET_BIT(hfmac->Instance->CR, FMAC_CR_RESET); 01583 01584 /* Wait until flag is reset */ 01585 while (READ_BIT(hfmac->Instance->CR, FMAC_CR_RESET) != 0U) 01586 { 01587 if ((HAL_GetTick() - tickstart) > HAL_FMAC_RESET_TIMEOUT_VALUE) 01588 { 01589 hfmac->ErrorCode |= HAL_FMAC_ERROR_TIMEOUT; 01590 return HAL_ERROR; 01591 } 01592 } 01593 01594 hfmac->ErrorCode = HAL_FMAC_ERROR_NONE; 01595 return HAL_OK; 01596 } 01597 01598 /** 01599 * @brief Reset the data pointers of the FMAC unit. 01600 * @param hfmac FMAC handle. 01601 * @retval None 01602 */ 01603 static void FMAC_ResetDataPointers(FMAC_HandleTypeDef *hfmac) 01604 { 01605 FMAC_ResetInputStateAndDataPointers(hfmac); 01606 FMAC_ResetOutputStateAndDataPointers(hfmac); 01607 } 01608 01609 /** 01610 * @brief Reset the input data pointers of the FMAC unit. 01611 * @param hfmac FMAC handle. 01612 * @retval None 01613 */ 01614 static void FMAC_ResetInputStateAndDataPointers(FMAC_HandleTypeDef *hfmac) 01615 { 01616 hfmac->pInput = NULL; 01617 hfmac->pInputSize = NULL; 01618 hfmac->InputCurrentSize = 0U; 01619 hfmac->WrState = HAL_FMAC_STATE_READY; 01620 } 01621 01622 /** 01623 * @brief Reset the output data pointers of the FMAC unit. 01624 * @param hfmac FMAC handle. 01625 * @retval None 01626 */ 01627 static void FMAC_ResetOutputStateAndDataPointers(FMAC_HandleTypeDef *hfmac) 01628 { 01629 hfmac->pOutput = NULL; 01630 hfmac->pOutputSize = NULL; 01631 hfmac->OutputCurrentSize = 0U; 01632 hfmac->RdState = HAL_FMAC_STATE_READY; 01633 } 01634 01635 /** 01636 * @brief Configure the FMAC filter. 01637 * @note The configuration is done according to the parameters 01638 * specified in the FMAC_FilterConfigTypeDef structure. 01639 * @param hfmac pointer to a FMAC_HandleTypeDef structure that contains 01640 * the configuration information for FMAC module. 01641 * @param pConfig pointer to a FMAC_FilterConfigTypeDef structure that 01642 * contains the FMAC configuration information. 01643 * @param PreloadAccess access mode used for the preload (polling or DMA). 01644 * @retval HAL_StatusTypeDef HAL status 01645 */ 01646 static HAL_StatusTypeDef FMAC_FilterConfig(FMAC_HandleTypeDef *hfmac, FMAC_FilterConfigTypeDef *pConfig, 01647 uint8_t PreloadAccess) 01648 { 01649 uint32_t tickstart; 01650 uint32_t tmpcr; 01651 #if defined(USE_FULL_ASSERT) 01652 uint32_t x2size; 01653 #endif /* USE_FULL_ASSERT */ 01654 01655 /* Check the parameters */ 01656 assert_param(IS_FMAC_THRESHOLD(pConfig->InputThreshold)); 01657 assert_param(IS_FMAC_THRESHOLD(pConfig->OutputThreshold)); 01658 assert_param(IS_FMAC_BUFFER_ACCESS(pConfig->InputAccess)); 01659 assert_param(IS_FMAC_BUFFER_ACCESS(pConfig->OutputAccess)); 01660 assert_param(IS_FMAC_CLIP_STATE(pConfig->Clip)); 01661 assert_param(IS_FMAC_FILTER_FUNCTION(pConfig->Filter)); 01662 assert_param(IS_FMAC_PARAM_P(pConfig->Filter, pConfig->P)); 01663 assert_param(IS_FMAC_PARAM_Q(pConfig->Filter, pConfig->Q)); 01664 assert_param(IS_FMAC_PARAM_R(pConfig->Filter, pConfig->R)); 01665 01666 /* Check the START bit state */ 01667 if (FMAC_GET_START_BIT(hfmac) != 0U) 01668 { 01669 return HAL_ERROR; 01670 } 01671 01672 /* Check handle state is ready */ 01673 if (hfmac->State != HAL_FMAC_STATE_READY) 01674 { 01675 return HAL_ERROR; 01676 } 01677 01678 /* Change the FMAC state */ 01679 hfmac->State = HAL_FMAC_STATE_BUSY; 01680 01681 /* Get tick */ 01682 tickstart = HAL_GetTick(); 01683 01684 /* Indicate that there is no valid configuration done */ 01685 hfmac->FilterParam = 0U; 01686 01687 /* FMAC_X1BUFCFG: Configure the input buffer within the internal memory if required */ 01688 if (pConfig->InputBufferSize != 0U) 01689 { 01690 MODIFY_REG(hfmac->Instance->X1BUFCFG, \ 01691 (FMAC_X1BUFCFG_X1_BASE | FMAC_X1BUFCFG_X1_BUF_SIZE), \ 01692 (((((uint32_t)(pConfig->InputBaseAddress)) << FMAC_X1BUFCFG_X1_BASE_Pos) & FMAC_X1BUFCFG_X1_BASE) | \ 01693 ((((uint32_t)(pConfig->InputBufferSize)) << FMAC_X1BUFCFG_X1_BUF_SIZE_Pos) & \ 01694 FMAC_X1BUFCFG_X1_BUF_SIZE))); 01695 } 01696 01697 /* FMAC_X1BUFCFG: Configure the input threshold if valid when compared to the configured X1 size */ 01698 if (pConfig->InputThreshold != FMAC_THRESHOLD_NO_VALUE) 01699 { 01700 /* Check the parameter */ 01701 assert_param(IS_FMAC_THRESHOLD_APPLICABLE(FMAC_GET_X1_SIZE(hfmac), pConfig->InputThreshold, pConfig->InputAccess)); 01702 01703 MODIFY_REG(hfmac->Instance->X1BUFCFG, \ 01704 FMAC_X1BUFCFG_FULL_WM, \ 01705 ((pConfig->InputThreshold) & FMAC_X1BUFCFG_FULL_WM)); 01706 } 01707 01708 /* FMAC_X2BUFCFG: Configure the coefficient buffer within the internal memory */ 01709 if (pConfig->CoeffBufferSize != 0U) 01710 { 01711 MODIFY_REG(hfmac->Instance->X2BUFCFG, \ 01712 (FMAC_X2BUFCFG_X2_BASE | FMAC_X2BUFCFG_X2_BUF_SIZE), \ 01713 (((((uint32_t)(pConfig->CoeffBaseAddress)) << FMAC_X2BUFCFG_X2_BASE_Pos) & FMAC_X2BUFCFG_X2_BASE) | \ 01714 ((((uint32_t)(pConfig->CoeffBufferSize)) << FMAC_X2BUFCFG_X2_BUF_SIZE_Pos) &\ 01715 FMAC_X2BUFCFG_X2_BUF_SIZE))); 01716 } 01717 01718 /* FMAC_YBUFCFG: Configure the output buffer within the internal memory if required */ 01719 if (pConfig->OutputBufferSize != 0U) 01720 { 01721 MODIFY_REG(hfmac->Instance->YBUFCFG, \ 01722 (FMAC_YBUFCFG_Y_BASE | FMAC_YBUFCFG_Y_BUF_SIZE), \ 01723 (((((uint32_t)(pConfig->OutputBaseAddress)) << FMAC_YBUFCFG_Y_BASE_Pos) & FMAC_YBUFCFG_Y_BASE) | \ 01724 ((((uint32_t)(pConfig->OutputBufferSize)) << FMAC_YBUFCFG_Y_BUF_SIZE_Pos) & FMAC_YBUFCFG_Y_BUF_SIZE))); 01725 } 01726 01727 /* FMAC_YBUFCFG: Configure the output threshold if valid when compared to the configured Y size */ 01728 if (pConfig->OutputThreshold != FMAC_THRESHOLD_NO_VALUE) 01729 { 01730 /* Check the parameter */ 01731 assert_param(IS_FMAC_THRESHOLD_APPLICABLE(FMAC_GET_Y_SIZE(hfmac), pConfig->OutputThreshold, pConfig->OutputAccess)); 01732 01733 MODIFY_REG(hfmac->Instance->YBUFCFG, \ 01734 FMAC_YBUFCFG_EMPTY_WM, \ 01735 ((pConfig->OutputThreshold) & FMAC_YBUFCFG_EMPTY_WM)); 01736 } 01737 01738 /* FMAC_CR: Configure the clip feature */ 01739 tmpcr = pConfig->Clip & FMAC_CR_CLIPEN; 01740 01741 /* FMAC_CR: If IT or DMA will be used, enable error interrupts. 01742 * Being more a debugging feature, FMAC_CR_SATIEN isn't enabled by default. */ 01743 if ((pConfig->InputAccess == FMAC_BUFFER_ACCESS_DMA) || (pConfig->InputAccess == FMAC_BUFFER_ACCESS_IT) || 01744 (pConfig->OutputAccess == FMAC_BUFFER_ACCESS_DMA) || (pConfig->OutputAccess == FMAC_BUFFER_ACCESS_IT)) 01745 { 01746 tmpcr |= FMAC_IT_UNFLIEN | FMAC_IT_OVFLIEN; 01747 } 01748 01749 /* FMAC_CR: write the value */ 01750 WRITE_REG(hfmac->Instance->CR, tmpcr); 01751 01752 /* Save the input/output accesses in order to configure RIEN, WIEN, DMAREN and DMAWEN during filter start */ 01753 hfmac->InputAccess = pConfig->InputAccess; 01754 hfmac->OutputAccess = pConfig->OutputAccess; 01755 01756 /* Check whether the configured X2 is big enough for the filter */ 01757 #if defined(USE_FULL_ASSERT) 01758 x2size = FMAC_GET_X2_SIZE(hfmac); 01759 #endif /* USE_FULL_ASSERT */ 01760 assert_param(((pConfig->Filter == FMAC_FUNC_CONVO_FIR) && (x2size >= pConfig->P)) || \ 01761 ((pConfig->Filter == FMAC_FUNC_IIR_DIRECT_FORM_1) && \ 01762 (x2size >= ((uint32_t)pConfig->P + (uint32_t)pConfig->Q)))); 01763 01764 /* Build the PARAM value that will be used when starting the filter */ 01765 hfmac->FilterParam = (FMAC_PARAM_START | pConfig->Filter | \ 01766 ((((uint32_t)(pConfig->P)) << FMAC_PARAM_P_Pos) & FMAC_PARAM_P) | \ 01767 ((((uint32_t)(pConfig->Q)) << FMAC_PARAM_Q_Pos) & FMAC_PARAM_Q) | \ 01768 ((((uint32_t)(pConfig->R)) << FMAC_PARAM_R_Pos) & FMAC_PARAM_R)); 01769 01770 /* Initialize the coefficient buffer if required (pCoeffA for FIR only) */ 01771 if ((pConfig->pCoeffB != NULL) && (pConfig->CoeffBSize != 0U)) 01772 { 01773 /* FIR/IIR: The provided coefficients should match X2 size */ 01774 assert_param(((uint32_t)pConfig->CoeffASize + (uint32_t)pConfig->CoeffBSize) <= x2size); 01775 /* FIR/IIR: The size of pCoeffB should match the parameter P */ 01776 assert_param(pConfig->CoeffBSize >= pConfig->P); 01777 /* pCoeffA should be provided for IIR but not for FIR */ 01778 /* IIR : if pCoeffB is provided, pCoeffA should also be there */ 01779 /* IIR: The size of pCoeffA should match the parameter Q */ 01780 assert_param(((pConfig->Filter == FMAC_FUNC_CONVO_FIR) && 01781 (pConfig->pCoeffA == NULL) && (pConfig->CoeffASize == 0U)) || 01782 ((pConfig->Filter == FMAC_FUNC_IIR_DIRECT_FORM_1) && 01783 (pConfig->pCoeffA != NULL) && (pConfig->CoeffASize != 0U) && 01784 (pConfig->CoeffASize >= pConfig->Q))); 01785 01786 /* Write number of values to be loaded, the data load function and start the operation */ 01787 WRITE_REG(hfmac->Instance->PARAM, \ 01788 (((uint32_t)(pConfig->CoeffBSize) << FMAC_PARAM_P_Pos) | \ 01789 ((uint32_t)(pConfig->CoeffASize) << FMAC_PARAM_Q_Pos) | \ 01790 FMAC_FUNC_LOAD_X2 | FMAC_PARAM_START)); 01791 01792 if (PreloadAccess == PRELOAD_ACCESS_POLLING) 01793 { 01794 /* Load the buffer into the internal memory */ 01795 FMAC_WritePreloadDataIncrementPtr(hfmac, &(pConfig->pCoeffB), pConfig->CoeffBSize); 01796 01797 /* Load pCoeffA if needed */ 01798 if ((pConfig->pCoeffA != NULL) && (pConfig->CoeffASize != 0U)) 01799 { 01800 /* Load the buffer into the internal memory */ 01801 FMAC_WritePreloadDataIncrementPtr(hfmac, &(pConfig->pCoeffA), pConfig->CoeffASize); 01802 } 01803 01804 /* Wait for the end of the writing */ 01805 if (FMAC_WaitOnStartUntilTimeout(hfmac, tickstart, HAL_FMAC_TIMEOUT_VALUE) != HAL_OK) 01806 { 01807 hfmac->ErrorCode |= HAL_FMAC_ERROR_TIMEOUT; 01808 hfmac->State = HAL_FMAC_STATE_TIMEOUT; 01809 return HAL_ERROR; 01810 } 01811 01812 /* Change the FMAC state */ 01813 hfmac->State = HAL_FMAC_STATE_READY; 01814 } 01815 else 01816 { 01817 hfmac->pInput = pConfig->pCoeffA; 01818 hfmac->InputCurrentSize = pConfig->CoeffASize; 01819 01820 /* Set the FMAC DMA transfer complete callback */ 01821 hfmac->hdmaPreload->XferHalfCpltCallback = NULL; 01822 hfmac->hdmaPreload->XferCpltCallback = FMAC_DMAFilterConfig; 01823 /* Set the DMA error callback */ 01824 hfmac->hdmaPreload->XferErrorCallback = FMAC_DMAError; 01825 01826 /* Enable the DMA stream managing FMAC preload data write */ 01827 return (HAL_DMA_Start_IT(hfmac->hdmaPreload, (uint32_t)pConfig->pCoeffB, (uint32_t)&hfmac->Instance->WDATA, 01828 pConfig->CoeffBSize)); 01829 } 01830 } 01831 else 01832 { 01833 /* Change the FMAC state */ 01834 hfmac->State = HAL_FMAC_STATE_READY; 01835 } 01836 01837 return HAL_OK; 01838 } 01839 01840 /** 01841 * @brief Preload the input (FIR, IIR) and output data (IIR) of the FMAC filter. 01842 * @note The set(s) of data will be used by FMAC as soon as @ref HAL_FMAC_FilterStart is called. 01843 * @param hfmac pointer to a FMAC_HandleTypeDef structure that contains 01844 * the configuration information for FMAC module. 01845 * @param pInput Preloading of the first elements of the input buffer (X1). 01846 * If not needed (no data available when starting), it should be set to NULL. 01847 * @param InputSize Size of the input vector. 01848 * As pInput is used for preloading data, it cannot be bigger than the input memory area. 01849 * @param pOutput [IIR] Preloading of the first elements of the output vector (Y). 01850 * If not needed, it should be set to NULL. 01851 * @param OutputSize Size of the output vector. 01852 * As pOutput is used for preloading data, it cannot be bigger than the output memory area. 01853 * @param PreloadAccess access mode used for the preload (polling or DMA). 01854 * @note The input and the output buffers can be filled by calling several times @ref HAL_FMAC_FilterPreload 01855 * (each call filling partly the buffers). In case of overflow (too much data provided through 01856 * all these calls), an error will be returned. 01857 * @retval HAL_StatusTypeDef HAL status 01858 */ 01859 static HAL_StatusTypeDef FMAC_FilterPreload(FMAC_HandleTypeDef *hfmac, int16_t *pInput, uint8_t InputSize, 01860 int16_t *pOutput, uint8_t OutputSize, uint8_t PreloadAccess) 01861 { 01862 uint32_t tickstart; 01863 HAL_StatusTypeDef status; 01864 01865 /* Check the START bit state */ 01866 if (FMAC_GET_START_BIT(hfmac) != 0U) 01867 { 01868 return HAL_ERROR; 01869 } 01870 01871 /* Check that a valid configuration was done previously */ 01872 if (hfmac->FilterParam == 0U) 01873 { 01874 return HAL_ERROR; 01875 } 01876 01877 /* Check the preload input buffers isn't too big */ 01878 if ((InputSize > FMAC_GET_X1_SIZE(hfmac)) && (pInput != NULL)) 01879 { 01880 return HAL_ERROR; 01881 } 01882 01883 /* Check the preload output buffer isn't too big */ 01884 if ((OutputSize > FMAC_GET_Y_SIZE(hfmac)) && (pOutput != NULL)) 01885 { 01886 return HAL_ERROR; 01887 } 01888 01889 /* Check handle state is ready */ 01890 if (hfmac->State != HAL_FMAC_STATE_READY) 01891 { 01892 return HAL_ERROR; 01893 } 01894 01895 /* Change the FMAC state */ 01896 hfmac->State = HAL_FMAC_STATE_BUSY; 01897 01898 /* Get tick */ 01899 tickstart = HAL_GetTick(); 01900 01901 /* Preload the input buffer if required */ 01902 if ((pInput != NULL) && (InputSize != 0U)) 01903 { 01904 /* Write number of values to be loaded, the data load function and start the operation */ 01905 WRITE_REG(hfmac->Instance->PARAM, \ 01906 (((uint32_t)InputSize << FMAC_PARAM_P_Pos) | FMAC_FUNC_LOAD_X1 | FMAC_PARAM_START)); 01907 01908 if (PreloadAccess == PRELOAD_ACCESS_POLLING) 01909 { 01910 /* Load the buffer into the internal memory */ 01911 FMAC_WritePreloadDataIncrementPtr(hfmac, &pInput, InputSize); 01912 01913 /* Wait for the end of the writing */ 01914 if (FMAC_WaitOnStartUntilTimeout(hfmac, tickstart, HAL_FMAC_TIMEOUT_VALUE) != HAL_OK) 01915 { 01916 hfmac->ErrorCode |= HAL_FMAC_ERROR_TIMEOUT; 01917 hfmac->State = HAL_FMAC_STATE_TIMEOUT; 01918 return HAL_ERROR; 01919 } 01920 } 01921 else 01922 { 01923 hfmac->pInput = pOutput; 01924 hfmac->InputCurrentSize = OutputSize; 01925 01926 /* Set the FMAC DMA transfer complete callback */ 01927 hfmac->hdmaPreload->XferHalfCpltCallback = NULL; 01928 hfmac->hdmaPreload->XferCpltCallback = FMAC_DMAFilterPreload; 01929 /* Set the DMA error callback */ 01930 hfmac->hdmaPreload->XferErrorCallback = FMAC_DMAError; 01931 01932 /* Enable the DMA stream managing FMAC preload data write */ 01933 return (HAL_DMA_Start_IT(hfmac->hdmaPreload, (uint32_t)pInput, (uint32_t)&hfmac->Instance->WDATA, InputSize)); 01934 } 01935 } 01936 01937 /* Preload the output buffer if required */ 01938 if ((pOutput != NULL) && (OutputSize != 0U)) 01939 { 01940 /* Write number of values to be loaded, the data load function and start the operation */ 01941 WRITE_REG(hfmac->Instance->PARAM, \ 01942 (((uint32_t)OutputSize << FMAC_PARAM_P_Pos) | FMAC_FUNC_LOAD_Y | FMAC_PARAM_START)); 01943 01944 if (PreloadAccess == PRELOAD_ACCESS_POLLING) 01945 { 01946 /* Load the buffer into the internal memory */ 01947 FMAC_WritePreloadDataIncrementPtr(hfmac, &pOutput, OutputSize); 01948 01949 /* Wait for the end of the writing */ 01950 if (FMAC_WaitOnStartUntilTimeout(hfmac, tickstart, HAL_FMAC_TIMEOUT_VALUE) != HAL_OK) 01951 { 01952 hfmac->ErrorCode |= HAL_FMAC_ERROR_TIMEOUT; 01953 hfmac->State = HAL_FMAC_STATE_TIMEOUT; 01954 return HAL_ERROR; 01955 } 01956 } 01957 else 01958 { 01959 hfmac->pInput = NULL; 01960 hfmac->InputCurrentSize = 0U; 01961 01962 /* Set the FMAC DMA transfer complete callback */ 01963 hfmac->hdmaPreload->XferHalfCpltCallback = NULL; 01964 hfmac->hdmaPreload->XferCpltCallback = FMAC_DMAFilterPreload; 01965 /* Set the DMA error callback */ 01966 hfmac->hdmaPreload->XferErrorCallback = FMAC_DMAError; 01967 01968 /* Enable the DMA stream managing FMAC preload data write */ 01969 return (HAL_DMA_Start_IT(hfmac->hdmaPreload, (uint32_t)pOutput, (uint32_t)&hfmac->Instance->WDATA, OutputSize)); 01970 } 01971 } 01972 01973 /* Update the error codes */ 01974 if (__HAL_FMAC_GET_FLAG(hfmac, FMAC_FLAG_OVFL)) 01975 { 01976 hfmac->ErrorCode |= HAL_FMAC_ERROR_OVFL; 01977 } 01978 if (__HAL_FMAC_GET_FLAG(hfmac, FMAC_FLAG_UNFL)) 01979 { 01980 hfmac->ErrorCode |= HAL_FMAC_ERROR_UNFL; 01981 } 01982 if (__HAL_FMAC_GET_FLAG(hfmac, FMAC_FLAG_SAT)) 01983 { 01984 hfmac->ErrorCode |= HAL_FMAC_ERROR_SAT; 01985 } 01986 01987 /* Change the FMAC state */ 01988 hfmac->State = HAL_FMAC_STATE_READY; 01989 01990 /* Return function status */ 01991 if (hfmac->ErrorCode == HAL_FMAC_ERROR_NONE) 01992 { 01993 status = HAL_OK; 01994 } 01995 else 01996 { 01997 status = HAL_ERROR; 01998 } 01999 return status; 02000 } 02001 02002 /** 02003 * @brief Write data into FMAC internal memory through WDATA and increment input buffer pointer. 02004 * @note This function is only used with preload functions. 02005 * @param hfmac pointer to a FMAC_HandleTypeDef structure that contains 02006 * the configuration information for FMAC module. 02007 * @param ppData pointer to pointer to the data buffer. 02008 * @param Size size of the data buffer. 02009 * @retval None 02010 */ 02011 static void FMAC_WritePreloadDataIncrementPtr(FMAC_HandleTypeDef *hfmac, int16_t **ppData, uint8_t Size) 02012 { 02013 uint8_t index; 02014 02015 /* Load the buffer into the internal memory */ 02016 for (index = Size; index > 0U; index--) 02017 { 02018 WRITE_REG(hfmac->Instance->WDATA, (((uint32_t)(*(*ppData))) & FMAC_WDATA_WDATA)); 02019 (*ppData)++; 02020 } 02021 } 02022 02023 /** 02024 * @brief Handle FMAC Function Timeout. 02025 * @param hfmac FMAC handle. 02026 * @param Tickstart Tick start value. 02027 * @param Timeout Timeout duration. 02028 * @retval HAL_StatusTypeDef HAL status 02029 */ 02030 static HAL_StatusTypeDef FMAC_WaitOnStartUntilTimeout(FMAC_HandleTypeDef *hfmac, uint32_t Tickstart, uint32_t Timeout) 02031 { 02032 /* Wait until flag changes */ 02033 while (READ_BIT(hfmac->Instance->PARAM, FMAC_PARAM_START) != 0U) 02034 { 02035 if ((HAL_GetTick() - Tickstart) > Timeout) 02036 { 02037 hfmac->ErrorCode |= HAL_FMAC_ERROR_TIMEOUT; 02038 02039 return HAL_ERROR; 02040 } 02041 } 02042 return HAL_OK; 02043 } 02044 02045 /** 02046 * @brief Register the new input buffer, update DMA configuration if needed and change the FMAC state. 02047 * @param hfmac pointer to a FMAC_HandleTypeDef structure that contains 02048 * the configuration information for FMAC module. 02049 * @param pInput New input vector (additional input data). 02050 * @param pInputSize Size of the input vector (if all the data can't be 02051 * written, it will be updated with the number of data read from FMAC). 02052 * @retval HAL_StatusTypeDef HAL status 02053 */ 02054 static HAL_StatusTypeDef FMAC_AppendFilterDataUpdateState(FMAC_HandleTypeDef *hfmac, int16_t *pInput, 02055 uint16_t *pInputSize) 02056 { 02057 /* Change the FMAC state */ 02058 hfmac->WrState = HAL_FMAC_STATE_BUSY_WR; 02059 02060 /* Reset the current size */ 02061 hfmac->InputCurrentSize = 0U; 02062 02063 /* Handle the pointer depending on the input access */ 02064 if (hfmac->InputAccess == FMAC_BUFFER_ACCESS_DMA) 02065 { 02066 hfmac->pInput = NULL; 02067 hfmac->pInputSize = NULL; 02068 02069 /* Set the FMAC DMA transfer complete callback */ 02070 hfmac->hdmaIn->XferHalfCpltCallback = FMAC_DMAHalfGetData; 02071 hfmac->hdmaIn->XferCpltCallback = FMAC_DMAGetData; 02072 /* Set the DMA error callback */ 02073 hfmac->hdmaIn->XferErrorCallback = FMAC_DMAError; 02074 02075 /* Enable the DMA stream managing FMAC input data write */ 02076 return (HAL_DMA_Start_IT(hfmac->hdmaIn, (uint32_t)pInput, (uint32_t)&hfmac->Instance->WDATA, *pInputSize)); 02077 } 02078 else 02079 { 02080 /* Update the input data information (polling, IT) */ 02081 hfmac->pInput = pInput; 02082 hfmac->pInputSize = pInputSize; 02083 } 02084 02085 return HAL_OK; 02086 } 02087 02088 /** 02089 * @brief Register the new output buffer, update DMA configuration if needed and change the FMAC state. 02090 * @param hfmac pointer to a FMAC_HandleTypeDef structure that contains 02091 * the configuration information for FMAC module. 02092 * @param pOutput New output vector. 02093 * @param pOutputSize Size of the output vector (if the vector can't 02094 * be entirely filled, pOutputSize will be updated with the number 02095 * of data read from FMAC). 02096 * @retval HAL_StatusTypeDef HAL status 02097 */ 02098 static HAL_StatusTypeDef FMAC_ConfigFilterOutputBufferUpdateState(FMAC_HandleTypeDef *hfmac, int16_t *pOutput, 02099 uint16_t *pOutputSize) 02100 { 02101 /* Reset the current size */ 02102 hfmac->OutputCurrentSize = 0U; 02103 02104 /* Check whether a valid pointer was provided */ 02105 if ((pOutput == NULL) || (pOutputSize == NULL) || (*pOutputSize == 0U)) 02106 { 02107 /* The user will have to provide a valid configuration later */ 02108 hfmac->pOutput = NULL; 02109 hfmac->pOutputSize = NULL; 02110 hfmac->RdState = HAL_FMAC_STATE_READY; 02111 } 02112 /* Handle the pointer depending on the input access */ 02113 else if (hfmac->OutputAccess == FMAC_BUFFER_ACCESS_DMA) 02114 { 02115 hfmac->pOutput = NULL; 02116 hfmac->pOutputSize = NULL; 02117 hfmac->RdState = HAL_FMAC_STATE_BUSY_RD; 02118 02119 /* Set the FMAC DMA transfer complete callback */ 02120 hfmac->hdmaOut->XferHalfCpltCallback = FMAC_DMAHalfOutputDataReady; 02121 hfmac->hdmaOut->XferCpltCallback = FMAC_DMAOutputDataReady; 02122 /* Set the DMA error callback */ 02123 hfmac->hdmaOut->XferErrorCallback = FMAC_DMAError; 02124 02125 /* Enable the DMA stream managing FMAC output data read */ 02126 return (HAL_DMA_Start_IT(hfmac->hdmaOut, (uint32_t)&hfmac->Instance->RDATA, (uint32_t)pOutput, *pOutputSize)); 02127 } 02128 else if (hfmac->OutputAccess == FMAC_BUFFER_ACCESS_NONE) 02129 { 02130 hfmac->pOutput = NULL; 02131 hfmac->pOutputSize = NULL; 02132 hfmac->RdState = HAL_FMAC_STATE_READY; 02133 } 02134 else 02135 { 02136 /* Update the output data information (polling, IT) */ 02137 hfmac->pOutput = pOutput; 02138 hfmac->pOutputSize = pOutputSize; 02139 hfmac->RdState = HAL_FMAC_STATE_BUSY_RD; 02140 } 02141 02142 return HAL_OK; 02143 } 02144 02145 /** 02146 * @brief Read available output data until Y EMPTY is set. 02147 * @param hfmac FMAC handle. 02148 * @param MaxSizeToRead Maximum number of data to read (this serves as a timeout 02149 * if FMAC continuously writes into the output buffer). 02150 * @retval None 02151 */ 02152 static void FMAC_ReadDataIncrementPtr(FMAC_HandleTypeDef *hfmac, uint16_t MaxSizeToRead) 02153 { 02154 uint16_t maxsize; 02155 uint16_t threshold; 02156 uint32_t tmpvalue; 02157 02158 /* Check if there is data to read */ 02159 if (READ_BIT(hfmac->Instance->SR, FMAC_SR_YEMPTY) != 0U) 02160 { 02161 return; 02162 } 02163 02164 /* Get the maximum index (no wait allowed, no overstepping of the output buffer) */ 02165 if ((hfmac->OutputCurrentSize + MaxSizeToRead) > *(hfmac->pOutputSize)) 02166 { 02167 maxsize = *(hfmac->pOutputSize); 02168 } 02169 else 02170 { 02171 maxsize = hfmac->OutputCurrentSize + MaxSizeToRead; 02172 } 02173 02174 /* Read until there is no more room or no more data */ 02175 do 02176 { 02177 /* If there is no more room, return */ 02178 if (!(hfmac->OutputCurrentSize < maxsize)) 02179 { 02180 return; 02181 } 02182 02183 /* Read the available data */ 02184 tmpvalue = ((READ_REG(hfmac->Instance->RDATA))& FMAC_RDATA_RDATA); 02185 *(hfmac->pOutput) = (int16_t)tmpvalue; 02186 hfmac->pOutput++; 02187 hfmac->OutputCurrentSize++; 02188 } while (READ_BIT(hfmac->Instance->SR, FMAC_SR_YEMPTY) == 0U); 02189 02190 /* Y buffer empty flag has just be raised, read the threshold */ 02191 threshold = (uint16_t)FMAC_GET_THRESHOLD_FROM_WM(FMAC_GET_Y_EMPTY_WM(hfmac)) - 1U; 02192 02193 /* Update the maximum size if needed (limited data available) */ 02194 if ((hfmac->OutputCurrentSize + threshold) < maxsize) 02195 { 02196 maxsize = hfmac->OutputCurrentSize + threshold; 02197 } 02198 02199 /* Read the available data */ 02200 while (hfmac->OutputCurrentSize < maxsize) 02201 { 02202 tmpvalue = ((READ_REG(hfmac->Instance->RDATA))& FMAC_RDATA_RDATA); 02203 *(hfmac->pOutput) = (int16_t)tmpvalue; 02204 hfmac->pOutput++; 02205 hfmac->OutputCurrentSize++; 02206 } 02207 } 02208 02209 /** 02210 * @brief Write available input data until X1 FULL is set. 02211 * @param hfmac FMAC handle. 02212 * @param MaxSizeToWrite Maximum number of data to write (this serves as a timeout 02213 * if FMAC continuously empties the input buffer). 02214 * @retval None 02215 */ 02216 static void FMAC_WriteDataIncrementPtr(FMAC_HandleTypeDef *hfmac, uint16_t MaxSizeToWrite) 02217 { 02218 uint16_t maxsize; 02219 uint16_t threshold; 02220 02221 /* Check if there is room in FMAC */ 02222 if (READ_BIT(hfmac->Instance->SR, FMAC_SR_X1FULL) != 0U) 02223 { 02224 return; 02225 } 02226 02227 /* Get the maximum index (no wait allowed, no overstepping of the output buffer) */ 02228 if ((hfmac->InputCurrentSize + MaxSizeToWrite) > *(hfmac->pInputSize)) 02229 { 02230 maxsize = *(hfmac->pInputSize); 02231 } 02232 else 02233 { 02234 maxsize = hfmac->InputCurrentSize + MaxSizeToWrite; 02235 } 02236 02237 /* Write until there is no more room or no more data */ 02238 do 02239 { 02240 /* If there is no more room, return */ 02241 if (!(hfmac->InputCurrentSize < maxsize)) 02242 { 02243 return; 02244 } 02245 02246 /* Write the available data */ 02247 WRITE_REG(hfmac->Instance->WDATA, (((uint32_t)(*(hfmac->pInput))) & FMAC_WDATA_WDATA)); 02248 hfmac->pInput++; 02249 hfmac->InputCurrentSize++; 02250 } while (READ_BIT(hfmac->Instance->SR, FMAC_SR_X1FULL) == 0U); 02251 02252 /* X1 buffer full flag has just be raised, read the threshold */ 02253 threshold = (uint16_t)FMAC_GET_THRESHOLD_FROM_WM(FMAC_GET_X1_FULL_WM(hfmac)) - 1U; 02254 02255 /* Update the maximum size if needed (limited data available) */ 02256 if ((hfmac->InputCurrentSize + threshold) < maxsize) 02257 { 02258 maxsize = hfmac->InputCurrentSize + threshold; 02259 } 02260 02261 /* Write the available data */ 02262 while (hfmac->InputCurrentSize < maxsize) 02263 { 02264 WRITE_REG(hfmac->Instance->WDATA, (((uint32_t)(*(hfmac->pInput))) & FMAC_WDATA_WDATA)); 02265 hfmac->pInput++; 02266 hfmac->InputCurrentSize++; 02267 } 02268 } 02269 02270 /** 02271 * @brief DMA FMAC Input Data process half complete callback. 02272 * @param hdma DMA handle. 02273 * @retval None 02274 */ 02275 static void FMAC_DMAHalfGetData(DMA_HandleTypeDef *hdma) 02276 { 02277 FMAC_HandleTypeDef *hfmac = (FMAC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; 02278 02279 /* Call half get data callback */ 02280 #if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1) 02281 hfmac->HalfGetDataCallback(hfmac); 02282 #else 02283 HAL_FMAC_HalfGetDataCallback(hfmac); 02284 #endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */ 02285 } 02286 02287 /** 02288 * @brief DMA FMAC Input Data process complete callback. 02289 * @param hdma DMA handle. 02290 * @retval None 02291 */ 02292 static void FMAC_DMAGetData(DMA_HandleTypeDef *hdma) 02293 { 02294 FMAC_HandleTypeDef *hfmac = (FMAC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; 02295 02296 /* Reset the pointers to indicate new data will be needed */ 02297 FMAC_ResetInputStateAndDataPointers(hfmac); 02298 02299 /* Call get data callback */ 02300 #if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1) 02301 hfmac->GetDataCallback(hfmac); 02302 #else 02303 HAL_FMAC_GetDataCallback(hfmac); 02304 #endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */ 02305 } 02306 02307 /** 02308 * @brief DMA FMAC Output Data process half complete callback. 02309 * @param hdma DMA handle. 02310 * @retval None 02311 */ 02312 static void FMAC_DMAHalfOutputDataReady(DMA_HandleTypeDef *hdma) 02313 { 02314 FMAC_HandleTypeDef *hfmac = (FMAC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; 02315 02316 /* Call half output data ready callback */ 02317 #if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1) 02318 hfmac->HalfOutputDataReadyCallback(hfmac); 02319 #else 02320 HAL_FMAC_HalfOutputDataReadyCallback(hfmac); 02321 #endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */ 02322 } 02323 02324 /** 02325 * @brief DMA FMAC Output Data process complete callback. 02326 * @param hdma DMA handle. 02327 * @retval None 02328 */ 02329 static void FMAC_DMAOutputDataReady(DMA_HandleTypeDef *hdma) 02330 { 02331 FMAC_HandleTypeDef *hfmac = (FMAC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; 02332 02333 /* Reset the pointers to indicate new data will be needed */ 02334 FMAC_ResetOutputStateAndDataPointers(hfmac); 02335 02336 /* Call output data ready callback */ 02337 #if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1) 02338 hfmac->OutputDataReadyCallback(hfmac); 02339 #else 02340 HAL_FMAC_OutputDataReadyCallback(hfmac); 02341 #endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */ 02342 } 02343 02344 /** 02345 * @brief DMA FMAC Filter Configuration process complete callback. 02346 * @param hdma DMA handle. 02347 * @retval None 02348 */ 02349 static void FMAC_DMAFilterConfig(DMA_HandleTypeDef *hdma) 02350 { 02351 uint8_t index; 02352 02353 FMAC_HandleTypeDef *hfmac = (FMAC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; 02354 02355 /* If needed, write CoeffA and exit */ 02356 if (hfmac->pInput != NULL) 02357 { 02358 /* Set the FMAC DMA transfer complete callback */ 02359 hfmac->hdmaPreload->XferHalfCpltCallback = NULL; 02360 hfmac->hdmaPreload->XferCpltCallback = FMAC_DMAFilterConfig; 02361 /* Set the DMA error callback */ 02362 hfmac->hdmaPreload->XferErrorCallback = FMAC_DMAError; 02363 02364 /* Enable the DMA stream managing FMAC preload data write */ 02365 if (HAL_DMA_Start_IT(hfmac->hdmaPreload, (uint32_t)hfmac->pInput, (uint32_t)&hfmac->Instance->WDATA, 02366 hfmac->InputCurrentSize) == HAL_OK) 02367 { 02368 hfmac->pInput = NULL; 02369 hfmac->InputCurrentSize = 0U; 02370 return; 02371 } 02372 02373 /* If not exited, there was an error: set FMAC handle state to error */ 02374 hfmac->State = HAL_FMAC_STATE_ERROR; 02375 } 02376 else 02377 { 02378 /* Wait for the end of the writing */ 02379 for (index = 0U; index < MAX_PRELOAD_INDEX; index++) 02380 { 02381 if (READ_BIT(hfmac->Instance->PARAM, FMAC_PARAM_START) == 0U) 02382 { 02383 break; 02384 } 02385 } 02386 02387 /* If 'START' is still set, there was a timeout: set FMAC handle state to timeout */ 02388 if (READ_BIT(hfmac->Instance->PARAM, FMAC_PARAM_START) != 0U) 02389 { 02390 hfmac->State = HAL_FMAC_STATE_TIMEOUT; 02391 } 02392 else 02393 { 02394 /* Change the FMAC state */ 02395 hfmac->State = HAL_FMAC_STATE_READY; 02396 02397 /* Call output data ready callback */ 02398 #if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1) 02399 hfmac->FilterConfigCallback(hfmac); 02400 #else 02401 HAL_FMAC_FilterConfigCallback(hfmac); 02402 #endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */ 02403 return; 02404 } 02405 } 02406 02407 /* If not exited, there was an error: set FMAC handle error code to DMA error */ 02408 hfmac->ErrorCode |= HAL_FMAC_ERROR_DMA; 02409 02410 /* Call user callback */ 02411 #if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1) 02412 hfmac->ErrorCallback(hfmac); 02413 #else 02414 HAL_FMAC_ErrorCallback(hfmac); 02415 #endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */ 02416 02417 } 02418 02419 /** 02420 * @brief DMA FMAC Filter Configuration process complete callback. 02421 * @param hdma DMA handle. 02422 * @retval None 02423 */ 02424 static void FMAC_DMAFilterPreload(DMA_HandleTypeDef *hdma) 02425 { 02426 uint8_t index; 02427 02428 FMAC_HandleTypeDef *hfmac = (FMAC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; 02429 02430 /* Wait for the end of the X1 writing */ 02431 for (index = 0U; index < MAX_PRELOAD_INDEX; index++) 02432 { 02433 if (READ_BIT(hfmac->Instance->PARAM, FMAC_PARAM_START) == 0U) 02434 { 02435 break; 02436 } 02437 } 02438 02439 /* If 'START' is still set, there was an error: set FMAC handle state to error */ 02440 if (READ_BIT(hfmac->Instance->PARAM, FMAC_PARAM_START) != 0U) 02441 { 02442 hfmac->State = HAL_FMAC_STATE_TIMEOUT; 02443 hfmac->ErrorCode |= HAL_FMAC_ERROR_TIMEOUT; 02444 } 02445 /* If needed, preload Y buffer */ 02446 else if ((hfmac->pInput != NULL) && (hfmac->InputCurrentSize != 0U)) 02447 { 02448 /* Write number of values to be loaded, the data load function and start the operation */ 02449 WRITE_REG(hfmac->Instance->PARAM, \ 02450 (((uint32_t)(hfmac->InputCurrentSize) << FMAC_PARAM_P_Pos) | FMAC_FUNC_LOAD_Y | FMAC_PARAM_START)); 02451 02452 /* Set the FMAC DMA transfer complete callback */ 02453 hfmac->hdmaPreload->XferHalfCpltCallback = NULL; 02454 hfmac->hdmaPreload->XferCpltCallback = FMAC_DMAFilterPreload; 02455 /* Set the DMA error callback */ 02456 hfmac->hdmaPreload->XferErrorCallback = FMAC_DMAError; 02457 02458 /* Enable the DMA stream managing FMAC preload data write */ 02459 if (HAL_DMA_Start_IT(hfmac->hdmaPreload, (uint32_t)hfmac->pInput, (uint32_t)&hfmac->Instance->WDATA, 02460 hfmac->InputCurrentSize) == HAL_OK) 02461 { 02462 hfmac->pInput = NULL; 02463 hfmac->InputCurrentSize = 0U; 02464 return; 02465 } 02466 02467 /* If not exited, there was an error */ 02468 hfmac->ErrorCode = HAL_FMAC_ERROR_DMA; 02469 hfmac->State = HAL_FMAC_STATE_ERROR; 02470 } 02471 else 02472 { 02473 /* nothing to do */ 02474 } 02475 02476 if (hfmac->ErrorCode == HAL_FMAC_ERROR_NONE) 02477 { 02478 /* Change the FMAC state */ 02479 hfmac->State = HAL_FMAC_STATE_READY; 02480 02481 /* Call output data ready callback */ 02482 #if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1) 02483 hfmac->FilterPreloadCallback(hfmac); 02484 #else 02485 HAL_FMAC_FilterPreloadCallback(hfmac); 02486 #endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */ 02487 } 02488 else 02489 { 02490 /* Call user callback */ 02491 #if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1) 02492 hfmac->ErrorCallback(hfmac); 02493 #else 02494 HAL_FMAC_ErrorCallback(hfmac); 02495 #endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */ 02496 } 02497 } 02498 02499 02500 /** 02501 * @brief DMA FMAC communication error callback. 02502 * @param hdma DMA handle. 02503 * @retval None 02504 */ 02505 static void FMAC_DMAError(DMA_HandleTypeDef *hdma) 02506 { 02507 FMAC_HandleTypeDef *hfmac = (FMAC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; 02508 02509 /* Set FMAC handle state to error */ 02510 hfmac->State = HAL_FMAC_STATE_ERROR; 02511 02512 /* Set FMAC handle error code to DMA error */ 02513 hfmac->ErrorCode |= HAL_FMAC_ERROR_DMA; 02514 02515 /* Call user callback */ 02516 #if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1) 02517 hfmac->ErrorCallback(hfmac); 02518 #else 02519 HAL_FMAC_ErrorCallback(hfmac); 02520 #endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */ 02521 } 02522 /** 02523 * @} 02524 */ 02525 02526 02527 /** 02528 * @} 02529 */ 02530 02531 /** 02532 * @} 02533 */ 02534 02535 #endif /* HAL_FMAC_MODULE_ENABLED */ 02536 #endif /* FMAC */