| /** |
| ****************************************************************************** |
| * @file stm32h7xx_hal_fmac.c |
| * @author MCD Application Team |
| * @brief FMAC HAL module driver. |
| * This file provides firmware functions to manage the following |
| * functionalities of the FMAC peripheral: |
| * + Initialization and de-initialization functions |
| * + Peripheral Control functions |
| * + Callback functions |
| * + IRQ handler management |
| * + Peripheral State and Error functions |
| * |
| ****************************************************************************** |
| * @attention |
| * |
| * Copyright (c) 2017 STMicroelectronics. |
| * All rights reserved. |
| * |
| * This software is licensed under terms that can be found in the LICENSE file |
| * in the root directory of this software component. |
| * If no LICENSE file comes with this software, it is provided AS-IS. |
| * |
| ****************************************************************************** |
| * |
| * @verbatim |
| ================================================================================ |
| ##### How to use this driver ##### |
| ================================================================================ |
| [..] |
| The FMAC HAL driver can be used as follows: |
| |
| (#) Initialize the FMAC low level resources by implementing the HAL_FMAC_MspInit(): |
| (++) Enable the FMAC interface clock using __HAL_RCC_FMAC_CLK_ENABLE(). |
| (++) In case of using interrupts (e.g. access configured as FMAC_BUFFER_ACCESS_IT): |
| (+++) Configure the FMAC interrupt priority using HAL_NVIC_SetPriority(). |
| (+++) Enable the FMAC IRQ handler using HAL_NVIC_EnableIRQ(). |
| (+++) In FMAC IRQ handler, call HAL_FMAC_IRQHandler(). |
| (++) In case of using DMA to control data transfer (e.g. access configured |
| as FMAC_BUFFER_ACCESS_DMA): |
| (+++) Enable the DMA interface clock using __HAL_RCC_DMA1_CLK_ENABLE() |
| or __HAL_RCC_DMA2_CLK_ENABLE() depending on the used DMA instance. |
| (+++) Enable the DMAMUX1 interface clock using __HAL_RCC_DMAMUX1_CLK_ENABLE(). |
| (+++) If the initialization of the internal buffers (coefficients, input, |
| output) is done via DMA, configure and enable one DMA channel for |
| managing data transfer from memory to memory (preload channel). |
| (+++) If the input buffer is accessed via DMA, configure and enable one |
| DMA channel for managing data transfer from memory to peripheral |
| (input channel). |
| (+++) If the output buffer is accessed via DMA, configure and enable |
| one DMA channel for managing data transfer from peripheral to |
| memory (output channel). |
| (+++) Associate the initialized DMA handle(s) to the FMAC DMA handle(s) |
| using __HAL_LINKDMA(). |
| (+++) Configure the priority and enable the NVIC for the transfer complete |
| interrupt on the enabled DMA channel(s) using HAL_NVIC_SetPriority() |
| and HAL_NVIC_EnableIRQ(). |
| |
| (#) Initialize the FMAC HAL using HAL_FMAC_Init(). This function |
| resorts to HAL_FMAC_MspInit() for low-level initialization. |
| |
| (#) Configure the FMAC processing (filter) using HAL_FMAC_FilterConfig() |
| or HAL_FMAC_FilterConfig_DMA(). |
| This function: |
| (++) Defines the memory area within the FMAC internal memory |
| (input, coefficients, output) and the associated threshold (input, output). |
| (++) Configures the filter and its parameters: |
| (+++) Finite Impulse Response (FIR) filter (also known as convolution). |
| (+++) Infinite Impulse Response (IIR) filter (direct form 1). |
| (++) Choose the way to access to the input and output buffers: none, polling, |
| DMA, IT. "none" means the input and/or output data will be handled by |
| another IP (ADC, DAC, etc.). |
| (++) Enable the error interruptions in the input access and/or the output |
| access is done through IT/DMA. If an error occurs, the interruption |
| will be triggered in loop. In order to recover, the user will have |
| to reset the IP with the sequence HAL_FMAC_DeInit / HAL_FMAC_Init. |
| Optionally, he can also disable the interrupt using __HAL_FMAC_DISABLE_IT; |
| the error status will be kept, but no more interrupt will be triggered. |
| (++) Write the provided coefficients into the internal memory using polling |
| mode ( HAL_FMAC_FilterConfig() ) or DMA ( HAL_FMAC_FilterConfig_DMA() ). |
| In the DMA case, HAL_FMAC_FilterConfigCallback() is called when |
| the handling is over. |
| |
| (#) Optionally, the user can enable the error interruption related to |
| saturation by calling __HAL_FMAC_ENABLE_IT. This helps in debugging the |
| filter. If a saturation occurs, the interruption will be triggered in loop. |
| In order to recover, the user will have to: |
| (++) Disable the interruption by calling __HAL_FMAC_DISABLE_IT if |
| the user wishes to continue all the same. |
| (++) Reset the IP with the sequence HAL_FMAC_DeInit / HAL_FMAC_Init. |
| |
| (#) Optionally, preload input (FIR, IIR) and output (IIR) data using |
| HAL_FMAC_FilterPreload() or HAL_FMAC_FilterPreload_DMA(). |
| In the DMA case, HAL_FMAC_FilterPreloadCallback() is called when |
| the handling is over. |
| This step is optional as the filter can be started without preloaded |
| data. |
| |
| (#) Start the FMAC processing (filter) using HAL_FMAC_FilterStart(). |
| This function also configures the output buffer that will be filled from |
| the circular internal output buffer. The function returns immediately |
| without updating the provided buffer. The IP processing will be active until |
| HAL_FMAC_FilterStop() is called. |
| |
| (#) If the input internal buffer is accessed via DMA, HAL_FMAC_HalfGetDataCallback() |
| will be called to indicate that half of the input buffer has been handled. |
| |
| (#) If the input internal buffer is accessed via DMA or interrupt, HAL_FMAC_GetDataCallback() |
| will be called to require new input data. It will be provided through |
| HAL_FMAC_AppendFilterData() if the DMA isn't in circular mode. |
| |
| (#) If the output internal buffer is accessed via DMA, HAL_FMAC_HalfOutputDataReadyCallback() |
| will be called to indicate that half of the output buffer has been handled. |
| |
| (#) If the output internal buffer is accessed via DMA or interrupt, |
| HAL_FMAC_OutputDataReadyCallback() will be called to require a new output |
| buffer. It will be provided through HAL_FMAC_ConfigFilterOutputBuffer() |
| if the DMA isn't in circular mode. |
| |
| (#) In all modes except none, provide new input data to be processed via HAL_FMAC_AppendFilterData(). |
| This function should only be called once the previous input data has been handled |
| (the preloaded input data isn't concerned). |
| |
| (#) In all modes except none, provide a new output buffer to be filled via |
| HAL_FMAC_ConfigFilterOutputBuffer(). This function should only be called once the previous |
| user's output buffer has been filled. |
| |
| (#) In polling mode, handle the input and output data using HAL_FMAC_PollFilterData(). |
| This function: |
| (++) Write the user's input data (provided via HAL_FMAC_AppendFilterData()) |
| into the FMAC input memory area. |
| (++) Read the FMAC output memory area and write it into the user's output buffer. |
| It will return either when: |
| (++) the user's output buffer is filled. |
| (++) the user's input buffer has been handled. |
| The unused data (unread input data or free output data) will not be saved. |
| The user will have to use the updated input and output sizes to keep track |
| of them. |
| |
| (#) Stop the FMAC processing (filter) using HAL_FMAC_FilterStop(). |
| |
| (#) Call HAL_FMAC_DeInit() to de-initialize the FMAC peripheral. This function |
| resorts to HAL_FMAC_MspDeInit() for low-level de-initialization. |
| |
| ##### Callback registration ##### |
| ================================== |
| |
| [..] |
| The compilation define USE_HAL_FMAC_REGISTER_CALLBACKS when set to 1 |
| allows the user to configure dynamically the driver callbacks. |
| |
| [..] |
| Use Function HAL_FMAC_RegisterCallback() to register a user callback. |
| Function HAL_FMAC_RegisterCallback() allows to register following callbacks: |
| (+) ErrorCallback : Error Callback. |
| (+) HalfGetDataCallback : Get Half Data Callback. |
| (+) GetDataCallback : Get Data Callback. |
| (+) HalfOutputDataReadyCallback : Half Output Data Ready Callback. |
| (+) OutputDataReadyCallback : Output Data Ready Callback. |
| (+) FilterConfigCallback : Filter Configuration Callback. |
| (+) FilterPreloadCallback : Filter Preload Callback. |
| (+) MspInitCallback : FMAC MspInit. |
| (+) MspDeInitCallback : FMAC MspDeInit. |
| This function takes as parameters the HAL peripheral handle, the Callback ID |
| and a pointer to the user callback function. |
| |
| [..] |
| Use function HAL_FMAC_UnRegisterCallback() to reset a callback to the default |
| weak function. |
| HAL_FMAC_UnRegisterCallback() takes as parameters the HAL peripheral handle |
| and the Callback ID. |
| This function allows to reset following callbacks: |
| (+) ErrorCallback : Error Callback. |
| (+) HalfGetDataCallback : Get Half Data Callback. |
| (+) GetDataCallback : Get Data Callback. |
| (+) HalfOutputDataReadyCallback : Half Output Data Ready Callback. |
| (+) OutputDataReadyCallback : Output Data Ready Callback. |
| (+) FilterConfigCallback : Filter Configuration Callback. |
| (+) FilterPreloadCallback : Filter Preload Callback. |
| (+) MspInitCallback : FMAC MspInit. |
| (+) MspDeInitCallback : FMAC MspDeInit. |
| |
| [..] |
| By default, after the HAL_FMAC_Init() and when the state is HAL_FMAC_STATE_RESET |
| all callbacks are set to the corresponding weak functions: |
| examples GetDataCallback(), OutputDataReadyCallback(). |
| Exception done for MspInit and MspDeInit functions that are respectively |
| reset to the legacy weak functions in the HAL_FMAC_Init() |
| and HAL_FMAC_DeInit() only when these callbacks are null (not registered beforehand). |
| If not, MspInit or MspDeInit are not null, the HAL_FMAC_Init() and HAL_FMAC_DeInit() |
| keep and use the user MspInit/MspDeInit callbacks (registered beforehand). |
| |
| [..] |
| Callbacks can be registered/unregistered in HAL_FMAC_STATE_READY state only. |
| Exception done MspInit/MspDeInit that can be registered/unregistered |
| in HAL_FMAC_STATE_READY or HAL_FMAC_STATE_RESET state, thus registered (user) |
| MspInit/DeInit callbacks can be used during the Init/DeInit. |
| In that case first register the MspInit/MspDeInit user callbacks |
| using HAL_FMAC_RegisterCallback() before calling HAL_FMAC_DeInit() |
| or HAL_FMAC_Init() function. |
| |
| [..] |
| When the compilation define USE_HAL_FMAC_REGISTER_CALLBACKS is set to 0 or |
| not defined, the callback registration feature is not available |
| and weak callbacks are used. |
| |
| |
| @endverbatim |
| * |
| */ |
| |
| /* Includes ------------------------------------------------------------------*/ |
| #include "stm32h7xx_hal.h" |
| |
| #if defined(FMAC) |
| #ifdef HAL_FMAC_MODULE_ENABLED |
| |
| /** @addtogroup STM32H7xx_HAL_Driver |
| * @{ |
| */ |
| |
| /** @defgroup FMAC FMAC |
| * @brief FMAC HAL driver module |
| * @{ |
| */ |
| |
| /* Private typedef -----------------------------------------------------------*/ |
| /* Private defines -----------------------------------------------------------*/ |
| /** @defgroup FMAC_Private_Constants FMAC Private Constants |
| * @{ |
| */ |
| |
| #define MAX_FILTER_DATA_SIZE_TO_HANDLE ((uint16_t) 0xFFU) |
| #define MAX_PRELOAD_INDEX 0xFFU |
| #define PRELOAD_ACCESS_DMA 0x00U |
| #define PRELOAD_ACCESS_POLLING 0x01U |
| #define POLLING_DISABLED 0U |
| #define POLLING_ENABLED 1U |
| #define POLLING_NOT_STOPPED 0U |
| #define POLLING_STOPPED 1U |
| /* FMAC polling-based communications time-out value */ |
| #define HAL_FMAC_TIMEOUT_VALUE 1000U |
| /* FMAC reset time-out value */ |
| #define HAL_FMAC_RESET_TIMEOUT_VALUE 500U |
| /* DMA Read Requests Enable */ |
| #define FMAC_DMA_REN FMAC_CR_DMAREN |
| /* DMA Write Channel Enable */ |
| #define FMAC_DMA_WEN FMAC_CR_DMAWEN |
| /* FMAC Execution Enable */ |
| #define FMAC_START FMAC_PARAM_START |
| |
| /** |
| * @} |
| */ |
| |
| /* Private macros ------------------------------------------------------------*/ |
| /** @defgroup FMAC_Private_Macros FMAC Private Macros |
| * @{ |
| */ |
| |
| /** |
| * @brief Get the X1 memory area size. |
| * @param __HANDLE__ FMAC handle. |
| * @retval X1_BUF_SIZE |
| */ |
| #define FMAC_GET_X1_SIZE(__HANDLE__) \ |
| ((((__HANDLE__)->Instance->X1BUFCFG) & (FMAC_X1BUFCFG_X1_BUF_SIZE)) >> (FMAC_X1BUFCFG_X1_BUF_SIZE_Pos)) |
| |
| /** |
| * @brief Get the X1 watermark. |
| * @param __HANDLE__ FMAC handle. |
| * @retval FULL_WM |
| */ |
| #define FMAC_GET_X1_FULL_WM(__HANDLE__) \ |
| (((__HANDLE__)->Instance->X1BUFCFG) & (FMAC_X1BUFCFG_FULL_WM)) |
| |
| /** |
| * @brief Get the X2 memory area size. |
| * @param __HANDLE__ FMAC handle. |
| * @retval X2_BUF_SIZE |
| */ |
| #define FMAC_GET_X2_SIZE(__HANDLE__) \ |
| ((((__HANDLE__)->Instance->X2BUFCFG) & (FMAC_X2BUFCFG_X2_BUF_SIZE)) >> (FMAC_X2BUFCFG_X2_BUF_SIZE_Pos)) |
| |
| /** |
| * @brief Get the Y memory area size. |
| * @param __HANDLE__ FMAC handle. |
| * @retval Y_BUF_SIZE |
| */ |
| #define FMAC_GET_Y_SIZE(__HANDLE__) \ |
| ((((__HANDLE__)->Instance->YBUFCFG) & (FMAC_YBUFCFG_Y_BUF_SIZE)) >> (FMAC_YBUFCFG_Y_BUF_SIZE_Pos)) |
| |
| /** |
| * @brief Get the Y watermark. |
| * @param __HANDLE__ FMAC handle. |
| * @retval EMPTY_WM |
| */ |
| #define FMAC_GET_Y_EMPTY_WM(__HANDLE__) \ |
| (((__HANDLE__)->Instance->YBUFCFG) & (FMAC_YBUFCFG_EMPTY_WM)) |
| |
| /** |
| * @brief Get the start bit state. |
| * @param __HANDLE__ FMAC handle. |
| * @retval START |
| */ |
| #define FMAC_GET_START_BIT(__HANDLE__) \ |
| ((((__HANDLE__)->Instance->PARAM) & (FMAC_PARAM_START)) >> (FMAC_PARAM_START_Pos)) |
| |
| /** |
| * @brief Get the threshold matching the watermark. |
| * @param __WM__ Watermark value. |
| * @retval THRESHOLD |
| */ |
| #define FMAC_GET_THRESHOLD_FROM_WM(__WM__) (((__WM__) == FMAC_THRESHOLD_1)? 1U: \ |
| ((__WM__) == FMAC_THRESHOLD_2)? 2U: \ |
| ((__WM__) == FMAC_THRESHOLD_4)? 4U:8U) |
| |
| /** |
| * @} |
| */ |
| |
| /* Private variables ---------------------------------------------------------*/ |
| /* Global variables ----------------------------------------------------------*/ |
| /* Private function prototypes -----------------------------------------------*/ |
| |
| static HAL_StatusTypeDef FMAC_Reset(FMAC_HandleTypeDef *hfmac); |
| static void FMAC_ResetDataPointers(FMAC_HandleTypeDef *hfmac); |
| static void FMAC_ResetOutputStateAndDataPointers(FMAC_HandleTypeDef *hfmac); |
| static void FMAC_ResetInputStateAndDataPointers(FMAC_HandleTypeDef *hfmac); |
| static HAL_StatusTypeDef FMAC_FilterConfig(FMAC_HandleTypeDef *hfmac, FMAC_FilterConfigTypeDef *pConfig, |
| uint8_t PreloadAccess); |
| static HAL_StatusTypeDef FMAC_FilterPreload(FMAC_HandleTypeDef *hfmac, int16_t *pInput, uint8_t InputSize, |
| int16_t *pOutput, uint8_t OutputSize, uint8_t PreloadAccess); |
| static void FMAC_WritePreloadDataIncrementPtr(FMAC_HandleTypeDef *hfmac, int16_t **ppData, uint8_t Size); |
| static HAL_StatusTypeDef FMAC_WaitOnStartUntilTimeout(FMAC_HandleTypeDef *hfmac, uint32_t Tickstart, uint32_t Timeout); |
| static HAL_StatusTypeDef FMAC_AppendFilterDataUpdateState(FMAC_HandleTypeDef *hfmac, int16_t *pInput, |
| uint16_t *pInputSize); |
| static HAL_StatusTypeDef FMAC_ConfigFilterOutputBufferUpdateState(FMAC_HandleTypeDef *hfmac, int16_t *pOutput, |
| uint16_t *pOutputSize); |
| static void FMAC_WriteDataIncrementPtr(FMAC_HandleTypeDef *hfmac, uint16_t MaxSizeToWrite); |
| static void FMAC_ReadDataIncrementPtr(FMAC_HandleTypeDef *hfmac, uint16_t MaxSizeToRead); |
| static void FMAC_DMAHalfGetData(DMA_HandleTypeDef *hdma); |
| static void FMAC_DMAGetData(DMA_HandleTypeDef *hdma); |
| static void FMAC_DMAHalfOutputDataReady(DMA_HandleTypeDef *hdma); |
| static void FMAC_DMAOutputDataReady(DMA_HandleTypeDef *hdma); |
| static void FMAC_DMAFilterConfig(DMA_HandleTypeDef *hdma); |
| static void FMAC_DMAFilterPreload(DMA_HandleTypeDef *hdma); |
| static void FMAC_DMAError(DMA_HandleTypeDef *hdma); |
| |
| /* Functions Definition ------------------------------------------------------*/ |
| |
| /** @defgroup FMAC_Exported_Functions FMAC Exported Functions |
| * @{ |
| */ |
| |
| /** @defgroup FMAC_Exported_Functions_Group1 Initialization and de-initialization functions |
| * @brief Initialization and Configuration functions |
| * |
| @verbatim |
| =============================================================================== |
| ##### Initialization and de-initialization functions ##### |
| =============================================================================== |
| [..] This section provides functions allowing to: |
| (+) Initialize the FMAC peripheral and the associated handle |
| (+) DeInitialize the FMAC peripheral |
| (+) Initialize the FMAC MSP (MCU Specific Package) |
| (+) De-Initialize the FMAC MSP |
| (+) Register a User FMAC Callback |
| (+) Unregister a FMAC CallBack |
| |
| [..] |
| |
| @endverbatim |
| * @{ |
| */ |
| |
| /** |
| * @brief Initialize the FMAC peripheral and the associated handle. |
| * @param hfmac pointer to a FMAC_HandleTypeDef structure. |
| * @retval HAL_StatusTypeDef HAL status |
| */ |
| HAL_StatusTypeDef HAL_FMAC_Init(FMAC_HandleTypeDef *hfmac) |
| { |
| HAL_StatusTypeDef status; |
| |
| /* Check the FMAC handle allocation */ |
| if (hfmac == NULL) |
| { |
| return HAL_ERROR; |
| } |
| |
| /* Check the instance */ |
| assert_param(IS_FMAC_ALL_INSTANCE(hfmac->Instance)); |
| |
| if (hfmac->State == HAL_FMAC_STATE_RESET) |
| { |
| /* Initialize lock resource */ |
| hfmac->Lock = HAL_UNLOCKED; |
| |
| #if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1) |
| /* Register the default callback functions */ |
| hfmac->ErrorCallback = HAL_FMAC_ErrorCallback; |
| hfmac->HalfGetDataCallback = HAL_FMAC_HalfGetDataCallback; |
| hfmac->GetDataCallback = HAL_FMAC_GetDataCallback; |
| hfmac->HalfOutputDataReadyCallback = HAL_FMAC_HalfOutputDataReadyCallback; |
| hfmac->OutputDataReadyCallback = HAL_FMAC_OutputDataReadyCallback; |
| hfmac->FilterConfigCallback = HAL_FMAC_FilterConfigCallback; |
| hfmac->FilterPreloadCallback = HAL_FMAC_FilterPreloadCallback; |
| |
| if (hfmac->MspInitCallback == NULL) |
| { |
| hfmac->MspInitCallback = HAL_FMAC_MspInit; |
| } |
| |
| /* Init the low level hardware */ |
| hfmac->MspInitCallback(hfmac); |
| #else |
| /* Init the low level hardware */ |
| HAL_FMAC_MspInit(hfmac); |
| #endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */ |
| } |
| |
| /* Reset pInput and pOutput */ |
| hfmac->FilterParam = 0U; |
| FMAC_ResetDataPointers(hfmac); |
| |
| /* Reset FMAC unit (internal pointers) */ |
| if (FMAC_Reset(hfmac) == HAL_ERROR) |
| { |
| /* Update FMAC error code and FMAC peripheral state */ |
| hfmac->ErrorCode |= HAL_FMAC_ERROR_RESET; |
| hfmac->State = HAL_FMAC_STATE_TIMEOUT; |
| |
| status = HAL_ERROR; |
| } |
| else |
| { |
| /* Update FMAC error code and FMAC peripheral state */ |
| hfmac->ErrorCode = HAL_FMAC_ERROR_NONE; |
| hfmac->State = HAL_FMAC_STATE_READY; |
| |
| status = HAL_OK; |
| } |
| |
| __HAL_UNLOCK(hfmac); |
| |
| return status; |
| } |
| |
| /** |
| * @brief De-initialize the FMAC peripheral. |
| * @param hfmac pointer to a FMAC structure. |
| * @retval HAL_StatusTypeDef HAL status |
| */ |
| HAL_StatusTypeDef HAL_FMAC_DeInit(FMAC_HandleTypeDef *hfmac) |
| { |
| /* Check the FMAC handle allocation */ |
| if (hfmac == NULL) |
| { |
| return HAL_ERROR; |
| } |
| |
| /* Check the parameters */ |
| assert_param(IS_FMAC_ALL_INSTANCE(hfmac->Instance)); |
| |
| /* Change FMAC peripheral state */ |
| hfmac->State = HAL_FMAC_STATE_BUSY; |
| |
| /* Set FMAC error code to none */ |
| hfmac->ErrorCode = HAL_FMAC_ERROR_NONE; |
| |
| /* Reset pInput and pOutput */ |
| hfmac->FilterParam = 0U; |
| FMAC_ResetDataPointers(hfmac); |
| |
| #if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1) |
| if (hfmac->MspDeInitCallback == NULL) |
| { |
| hfmac->MspDeInitCallback = HAL_FMAC_MspDeInit; |
| } |
| /* DeInit the low level hardware */ |
| hfmac->MspDeInitCallback(hfmac); |
| #else |
| /* DeInit the low level hardware: CLOCK, NVIC, DMA */ |
| HAL_FMAC_MspDeInit(hfmac); |
| #endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */ |
| |
| /* Change FMAC peripheral state */ |
| hfmac->State = HAL_FMAC_STATE_RESET; |
| |
| /* Always release Lock in case of de-initialization */ |
| __HAL_UNLOCK(hfmac); |
| |
| return HAL_OK; |
| } |
| |
| /** |
| * @brief Initialize the FMAC MSP. |
| * @param hfmac FMAC handle. |
| * @retval None |
| */ |
| __weak void HAL_FMAC_MspInit(FMAC_HandleTypeDef *hfmac) |
| { |
| /* Prevent unused argument(s) compilation warning */ |
| UNUSED(hfmac); |
| |
| /* NOTE : This function should not be modified, when the callback is needed, |
| the HAL_FMAC_MspInit can be implemented in the user file |
| */ |
| } |
| |
| /** |
| * @brief De-initialize the FMAC MSP. |
| * @param hfmac FMAC handle. |
| * @retval None |
| */ |
| __weak void HAL_FMAC_MspDeInit(FMAC_HandleTypeDef *hfmac) |
| { |
| /* Prevent unused argument(s) compilation warning */ |
| UNUSED(hfmac); |
| |
| /* NOTE : This function should not be modified, when the callback is needed, |
| the HAL_FMAC_MspDeInit can be implemented in the user file |
| */ |
| } |
| |
| #if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1) |
| /** |
| * @brief Register a User FMAC Callback. |
| * @note The User FMAC Callback is to be used instead of the weak predefined callback. |
| * @note The HAL_FMAC_RegisterCallback() may be called before HAL_FMAC_Init() in HAL_FMAC_STATE_RESET to register |
| * callbacks for HAL_FMAC_MSPINIT_CB_ID and HAL_FMAC_MSPDEINIT_CB_ID. |
| * @param hfmac pointer to a FMAC_HandleTypeDef structure that contains |
| * the configuration information for FMAC module. |
| * @param CallbackID ID of the callback to be registered. |
| * This parameter can be one of the following values: |
| * @arg @ref HAL_FMAC_ERROR_CB_ID Error Callback ID |
| * @arg @ref HAL_FMAC_HALF_GET_DATA_CB_ID Get Half Data Callback ID |
| * @arg @ref HAL_FMAC_GET_DATA_CB_ID Get Data Callback ID |
| * @arg @ref HAL_FMAC_HALF_OUTPUT_DATA_READY_CB_ID Half Output Data Ready Callback ID |
| * @arg @ref HAL_FMAC_OUTPUT_DATA_READY_CB_ID Output Data Ready Callback ID |
| * @arg @ref HAL_FMAC_FILTER_CONFIG_CB_ID Filter Configuration Callback ID |
| * @arg @ref HAL_FMAC_FILTER_PRELOAD_CB_ID Filter Preload Callback ID |
| * @arg @ref HAL_FMAC_MSPINIT_CB_ID FMAC MspInit ID |
| * @arg @ref HAL_FMAC_MSPDEINIT_CB_ID FMAC MspDeInit ID |
| * @param pCallback pointer to the Callback function. |
| * @retval HAL_StatusTypeDef HAL status |
| */ |
| HAL_StatusTypeDef HAL_FMAC_RegisterCallback(FMAC_HandleTypeDef *hfmac, HAL_FMAC_CallbackIDTypeDef CallbackID, |
| pFMAC_CallbackTypeDef pCallback) |
| { |
| HAL_StatusTypeDef status = HAL_OK; |
| |
| /* Check the FMAC handle allocation */ |
| if (hfmac == NULL) |
| { |
| return HAL_ERROR; |
| } |
| |
| if (pCallback == NULL) |
| { |
| /* Update the error code */ |
| hfmac->ErrorCode |= HAL_FMAC_ERROR_INVALID_CALLBACK; |
| |
| return HAL_ERROR; |
| } |
| |
| if (hfmac->State == HAL_FMAC_STATE_READY) |
| { |
| switch (CallbackID) |
| { |
| case HAL_FMAC_ERROR_CB_ID : |
| hfmac->ErrorCallback = pCallback; |
| break; |
| |
| case HAL_FMAC_HALF_GET_DATA_CB_ID : |
| hfmac->HalfGetDataCallback = pCallback; |
| break; |
| |
| case HAL_FMAC_GET_DATA_CB_ID : |
| hfmac->GetDataCallback = pCallback; |
| break; |
| |
| case HAL_FMAC_HALF_OUTPUT_DATA_READY_CB_ID : |
| hfmac->HalfOutputDataReadyCallback = pCallback; |
| break; |
| |
| case HAL_FMAC_OUTPUT_DATA_READY_CB_ID : |
| hfmac->OutputDataReadyCallback = pCallback; |
| break; |
| |
| case HAL_FMAC_FILTER_CONFIG_CB_ID : |
| hfmac->FilterConfigCallback = pCallback; |
| break; |
| |
| case HAL_FMAC_FILTER_PRELOAD_CB_ID : |
| hfmac->FilterPreloadCallback = pCallback; |
| break; |
| |
| case HAL_FMAC_MSPINIT_CB_ID : |
| hfmac->MspInitCallback = pCallback; |
| break; |
| |
| case HAL_FMAC_MSPDEINIT_CB_ID : |
| hfmac->MspDeInitCallback = pCallback; |
| break; |
| |
| default : |
| /* Update the error code */ |
| hfmac->ErrorCode |= HAL_FMAC_ERROR_INVALID_CALLBACK; |
| |
| /* Return error status */ |
| status = HAL_ERROR; |
| break; |
| } |
| } |
| else if (hfmac->State == HAL_FMAC_STATE_RESET) |
| { |
| switch (CallbackID) |
| { |
| case HAL_FMAC_MSPINIT_CB_ID : |
| hfmac->MspInitCallback = pCallback; |
| break; |
| |
| case HAL_FMAC_MSPDEINIT_CB_ID : |
| hfmac->MspDeInitCallback = pCallback; |
| break; |
| |
| default : |
| /* Update the error code */ |
| hfmac->ErrorCode |= HAL_FMAC_ERROR_INVALID_CALLBACK; |
| |
| /* Return error status */ |
| status = HAL_ERROR; |
| break; |
| } |
| } |
| else |
| { |
| /* Update the error code */ |
| hfmac->ErrorCode |= HAL_FMAC_ERROR_INVALID_CALLBACK; |
| |
| /* Return error status */ |
| status = HAL_ERROR; |
| } |
| |
| return status; |
| } |
| |
| /** |
| * @brief Unregister a FMAC CallBack. |
| * @note The FMAC callback is redirected to the weak predefined callback. |
| * @note The HAL_FMAC_UnRegisterCallback() may be called before HAL_FMAC_Init() in HAL_FMAC_STATE_RESET to register |
| * callbacks for HAL_FMAC_MSPINIT_CB_ID and HAL_FMAC_MSPDEINIT_CB_ID. |
| * @param hfmac pointer to a FMAC_HandleTypeDef structure that contains |
| * the configuration information for FMAC module |
| * @param CallbackID ID of the callback to be unregistered. |
| * This parameter can be one of the following values: |
| * @arg @ref HAL_FMAC_ERROR_CB_ID Error Callback ID |
| * @arg @ref HAL_FMAC_HALF_GET_DATA_CB_ID Get Half Data Callback ID |
| * @arg @ref HAL_FMAC_GET_DATA_CB_ID Get Data Callback ID |
| * @arg @ref HAL_FMAC_HALF_OUTPUT_DATA_READY_CB_ID Half Output Data Ready Callback ID |
| * @arg @ref HAL_FMAC_OUTPUT_DATA_READY_CB_ID Output Data Ready Callback ID |
| * @arg @ref HAL_FMAC_FILTER_CONFIG_CB_ID Filter Configuration Callback ID |
| * @arg @ref HAL_FMAC_FILTER_PRELOAD_CB_ID Filter Preload Callback ID |
| * @arg @ref HAL_FMAC_MSPINIT_CB_ID FMAC MspInit ID |
| * @arg @ref HAL_FMAC_MSPDEINIT_CB_ID FMAC MspDeInit ID |
| * @retval HAL_StatusTypeDef HAL status |
| */ |
| HAL_StatusTypeDef HAL_FMAC_UnRegisterCallback(FMAC_HandleTypeDef *hfmac, HAL_FMAC_CallbackIDTypeDef CallbackID) |
| { |
| HAL_StatusTypeDef status = HAL_OK; |
| |
| /* Check the FMAC handle allocation */ |
| if (hfmac == NULL) |
| { |
| return HAL_ERROR; |
| } |
| |
| if (hfmac->State == HAL_FMAC_STATE_READY) |
| { |
| switch (CallbackID) |
| { |
| case HAL_FMAC_ERROR_CB_ID : |
| hfmac->ErrorCallback = HAL_FMAC_ErrorCallback; /* Legacy weak ErrorCallback */ |
| break; |
| |
| case HAL_FMAC_HALF_GET_DATA_CB_ID : |
| hfmac->HalfGetDataCallback = HAL_FMAC_HalfGetDataCallback; /* Legacy weak HalfGetDataCallback */ |
| break; |
| |
| case HAL_FMAC_GET_DATA_CB_ID : |
| hfmac->GetDataCallback = HAL_FMAC_GetDataCallback; /* Legacy weak GetDataCallback */ |
| break; |
| |
| case HAL_FMAC_HALF_OUTPUT_DATA_READY_CB_ID : |
| hfmac->HalfOutputDataReadyCallback = HAL_FMAC_HalfOutputDataReadyCallback; /* Legacy weak |
| HalfOutputDataReadyCallback */ |
| break; |
| |
| case HAL_FMAC_OUTPUT_DATA_READY_CB_ID : |
| hfmac->OutputDataReadyCallback = HAL_FMAC_OutputDataReadyCallback; /* Legacy weak |
| OutputDataReadyCallback */ |
| break; |
| |
| case HAL_FMAC_FILTER_CONFIG_CB_ID : |
| hfmac->FilterConfigCallback = HAL_FMAC_FilterConfigCallback; /* Legacy weak |
| FilterConfigCallback */ |
| break; |
| |
| case HAL_FMAC_FILTER_PRELOAD_CB_ID : |
| hfmac->FilterPreloadCallback = HAL_FMAC_FilterPreloadCallback; /* Legacy weak FilterPreloadCallba */ |
| break; |
| |
| case HAL_FMAC_MSPINIT_CB_ID : |
| hfmac->MspInitCallback = HAL_FMAC_MspInit; /* Legacy weak MspInitCallback */ |
| break; |
| |
| case HAL_FMAC_MSPDEINIT_CB_ID : |
| hfmac->MspDeInitCallback = HAL_FMAC_MspDeInit; /* Legacy weak MspDeInitCallback */ |
| break; |
| |
| default : |
| /* Update the error code */ |
| hfmac->ErrorCode |= HAL_FMAC_ERROR_INVALID_CALLBACK; |
| |
| /* Return error status */ |
| status = HAL_ERROR; |
| break; |
| } |
| } |
| else if (hfmac->State == HAL_FMAC_STATE_RESET) |
| { |
| switch (CallbackID) |
| { |
| case HAL_FMAC_MSPINIT_CB_ID : |
| hfmac->MspInitCallback = HAL_FMAC_MspInit; |
| break; |
| |
| case HAL_FMAC_MSPDEINIT_CB_ID : |
| hfmac->MspDeInitCallback = HAL_FMAC_MspDeInit; |
| break; |
| |
| default : |
| /* Update the error code */ |
| hfmac->ErrorCode |= HAL_FMAC_ERROR_INVALID_CALLBACK; |
| |
| /* Return error status */ |
| status = HAL_ERROR; |
| break; |
| } |
| } |
| else |
| { |
| /* Update the error code */ |
| hfmac->ErrorCode |= HAL_FMAC_ERROR_INVALID_CALLBACK; |
| |
| /* Return error status */ |
| status = HAL_ERROR; |
| } |
| |
| return status; |
| } |
| #endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */ |
| |
| /** |
| * @} |
| */ |
| |
| /** @defgroup FMAC_Exported_Functions_Group2 Peripheral Control functions |
| * @brief Control functions. |
| * |
| @verbatim |
| ============================================================================== |
| ##### Peripheral Control functions ##### |
| ============================================================================== |
| [..] This section provides functions allowing to: |
| (+) Configure the FMAC peripheral: memory area, filter type and parameters, |
| way to access to the input and output memory area (none, polling, IT, DMA). |
| (+) Start the FMAC processing (filter). |
| (+) Handle the input data that will be provided into FMAC. |
| (+) Handle the output data provided by FMAC. |
| (+) Stop the FMAC processing (filter). |
| |
| @endverbatim |
| * @{ |
| */ |
| |
| /** |
| * @brief Configure the FMAC filter. |
| * @note The configuration is done according to the parameters |
| * specified in the FMAC_FilterConfigTypeDef structure. |
| * The provided data will be loaded using polling mode. |
| * @param hfmac pointer to a FMAC_HandleTypeDef structure that contains |
| * the configuration information for FMAC module. |
| * @param pConfig pointer to a FMAC_FilterConfigTypeDef structure that |
| * contains the FMAC configuration information. |
| * @retval HAL_StatusTypeDef HAL status |
| */ |
| HAL_StatusTypeDef HAL_FMAC_FilterConfig(FMAC_HandleTypeDef *hfmac, FMAC_FilterConfigTypeDef *pConfig) |
| { |
| return (FMAC_FilterConfig(hfmac, pConfig, PRELOAD_ACCESS_POLLING)); |
| } |
| |
| /** |
| * @brief Configure the FMAC filter. |
| * @note The configuration is done according to the parameters |
| * specified in the FMAC_FilterConfigTypeDef structure. |
| * The provided data will be loaded using DMA. |
| * @param hfmac pointer to a FMAC_HandleTypeDef structure that contains |
| * the configuration information for FMAC module. |
| * @param pConfig pointer to a FMAC_FilterConfigTypeDef structure that |
| * contains the FMAC configuration information. |
| * @retval HAL_StatusTypeDef HAL status |
| */ |
| HAL_StatusTypeDef HAL_FMAC_FilterConfig_DMA(FMAC_HandleTypeDef *hfmac, FMAC_FilterConfigTypeDef *pConfig) |
| { |
| return (FMAC_FilterConfig(hfmac, pConfig, PRELOAD_ACCESS_DMA)); |
| } |
| |
| /** |
| * @brief Preload the input (FIR, IIR) and output data (IIR) of the FMAC filter. |
| * @note The set(s) of data will be used by FMAC as soon as @ref HAL_FMAC_FilterStart is called. |
| * The provided data will be loaded using polling mode. |
| * @param hfmac pointer to a FMAC_HandleTypeDef structure that contains |
| * the configuration information for FMAC module. |
| * @param pInput Preloading of the first elements of the input buffer (X1). |
| * If not needed (no data available when starting), it should be set to NULL. |
| * @param InputSize Size of the input vector. |
| * As pInput is used for preloading data, it cannot be bigger than the input memory area. |
| * @param pOutput [IIR] Preloading of the first elements of the output vector (Y). |
| * If not needed, it should be set to NULL. |
| * @param OutputSize Size of the output vector. |
| * As pOutput is used for preloading data, it cannot be bigger than the output memory area. |
| * @note The input and the output buffers can be filled by calling several times @ref HAL_FMAC_FilterPreload |
| * (each call filling partly the buffers). In case of overflow (too much data provided through |
| * all these calls), an error will be returned. |
| * @retval HAL_StatusTypeDef HAL status |
| */ |
| HAL_StatusTypeDef HAL_FMAC_FilterPreload(FMAC_HandleTypeDef *hfmac, int16_t *pInput, uint8_t InputSize, |
| int16_t *pOutput, uint8_t OutputSize) |
| { |
| return (FMAC_FilterPreload(hfmac, pInput, InputSize, pOutput, OutputSize, PRELOAD_ACCESS_POLLING)); |
| } |
| |
| /** |
| * @brief Preload the input (FIR, IIR) and output data (IIR) of the FMAC filter. |
| * @note The set(s) of data will be used by FMAC as soon as @ref HAL_FMAC_FilterStart is called. |
| * The provided data will be loaded using DMA. |
| * @param hfmac pointer to a FMAC_HandleTypeDef structure that contains |
| * the configuration information for FMAC module. |
| * @param pInput Preloading of the first elements of the input buffer (X1). |
| * If not needed (no data available when starting), it should be set to NULL. |
| * @param InputSize Size of the input vector. |
| * As pInput is used for preloading data, it cannot be bigger than the input memory area. |
| * @param pOutput [IIR] Preloading of the first elements of the output vector (Y). |
| * If not needed, it should be set to NULL. |
| * @param OutputSize Size of the output vector. |
| * As pOutput is used for preloading data, it cannot be bigger than the output memory area. |
| * @note The input and the output buffers can be filled by calling several times @ref HAL_FMAC_FilterPreload |
| * (each call filling partly the buffers). In case of overflow (too much data provided through |
| * all these calls), an error will be returned. |
| * @retval HAL_StatusTypeDef HAL status |
| */ |
| HAL_StatusTypeDef HAL_FMAC_FilterPreload_DMA(FMAC_HandleTypeDef *hfmac, int16_t *pInput, uint8_t InputSize, |
| int16_t *pOutput, uint8_t OutputSize) |
| { |
| return (FMAC_FilterPreload(hfmac, pInput, InputSize, pOutput, OutputSize, PRELOAD_ACCESS_DMA)); |
| } |
| |
| |
| /** |
| * @brief Start the FMAC processing according to the existing FMAC configuration. |
| * @param hfmac pointer to a FMAC_HandleTypeDef structure that contains |
| * the configuration information for FMAC module. |
| * @param pOutput pointer to buffer where output data of FMAC processing will be stored |
| * in the next steps. |
| * If it is set to NULL, the output will not be read and it will be up to |
| * an external IP to empty the output buffer. |
| * @param pOutputSize pointer to the size of the output buffer. The number of read data will be written here. |
| * @retval HAL_StatusTypeDef HAL status |
| */ |
| HAL_StatusTypeDef HAL_FMAC_FilterStart(FMAC_HandleTypeDef *hfmac, int16_t *pOutput, uint16_t *pOutputSize) |
| { |
| uint32_t tmpcr = 0U; |
| HAL_StatusTypeDef status; |
| |
| /* Check the START bit state */ |
| if (FMAC_GET_START_BIT(hfmac) != 0U) |
| { |
| return HAL_ERROR; |
| } |
| |
| /* Check that a valid configuration was done previously */ |
| if (hfmac->FilterParam == 0U) |
| { |
| return HAL_ERROR; |
| } |
| |
| /* Check handle state is ready */ |
| if (hfmac->State == HAL_FMAC_STATE_READY) |
| { |
| /* Change the FMAC state */ |
| hfmac->State = HAL_FMAC_STATE_BUSY; |
| |
| /* CR: Configure the input access (error interruptions enabled only for IT or DMA) */ |
| if (hfmac->InputAccess == FMAC_BUFFER_ACCESS_DMA) |
| { |
| tmpcr |= FMAC_DMA_WEN; |
| } |
| else if (hfmac->InputAccess == FMAC_BUFFER_ACCESS_IT) |
| { |
| tmpcr |= FMAC_IT_WIEN; |
| } |
| else |
| { |
| /* nothing to do */ |
| } |
| |
| /* CR: Configure the output access (error interruptions enabled only for IT or DMA) */ |
| if (hfmac->OutputAccess == FMAC_BUFFER_ACCESS_DMA) |
| { |
| tmpcr |= FMAC_DMA_REN; |
| } |
| else if (hfmac->OutputAccess == FMAC_BUFFER_ACCESS_IT) |
| { |
| tmpcr |= FMAC_IT_RIEN; |
| } |
| else |
| { |
| /* nothing to do */ |
| } |
| |
| /* CR: Write the configuration */ |
| MODIFY_REG(hfmac->Instance->CR, \ |
| FMAC_IT_RIEN | FMAC_IT_WIEN | FMAC_DMA_REN | FMAC_CR_DMAWEN, \ |
| tmpcr); |
| |
| /* Register the new output buffer */ |
| status = FMAC_ConfigFilterOutputBufferUpdateState(hfmac, pOutput, pOutputSize); |
| |
| if (status == HAL_OK) |
| { |
| /* PARAM: Start the filter ( this can generate interrupts before the end of the HAL_FMAC_FilterStart ) */ |
| WRITE_REG(hfmac->Instance->PARAM, (uint32_t)(hfmac->FilterParam)); |
| } |
| |
| /* Reset the busy flag (do not overwrite the possible write and read flag) */ |
| hfmac->State = HAL_FMAC_STATE_READY; |
| } |
| else |
| { |
| status = HAL_ERROR; |
| } |
| |
| return status; |
| } |
| |
| /** |
| * @brief Provide a new input buffer that will be loaded into the FMAC input memory area. |
| * @param hfmac pointer to a FMAC_HandleTypeDef structure that contains |
| * the configuration information for FMAC module. |
| * @param pInput New input vector (additional input data). |
| * @param pInputSize Size of the input vector (if all the data can't be |
| * written, it will be updated with the number of data read from FMAC). |
| * @retval HAL_StatusTypeDef HAL status |
| */ |
| HAL_StatusTypeDef HAL_FMAC_AppendFilterData(FMAC_HandleTypeDef *hfmac, int16_t *pInput, uint16_t *pInputSize) |
| { |
| HAL_StatusTypeDef status; |
| |
| /* Check the function parameters */ |
| if ((pInput == NULL) || (pInputSize == NULL)) |
| { |
| return HAL_ERROR; |
| } |
| if (*pInputSize == 0U) |
| { |
| return HAL_ERROR; |
| } |
| |
| /* Check the START bit state */ |
| if (FMAC_GET_START_BIT(hfmac) == 0U) |
| { |
| return HAL_ERROR; |
| } |
| |
| /* Check the FMAC configuration */ |
| if (hfmac->InputAccess == FMAC_BUFFER_ACCESS_NONE) |
| { |
| return HAL_ERROR; |
| } |
| |
| /* Check whether the previous input vector has been handled */ |
| if ((hfmac->pInputSize != NULL) && (hfmac->InputCurrentSize < * (hfmac->pInputSize))) |
| { |
| return HAL_ERROR; |
| } |
| |
| /* Check that FMAC was initialized and that no writing is already ongoing */ |
| if (hfmac->WrState == HAL_FMAC_STATE_READY) |
| { |
| /* Register the new input buffer */ |
| status = FMAC_AppendFilterDataUpdateState(hfmac, pInput, pInputSize); |
| } |
| else |
| { |
| status = HAL_ERROR; |
| } |
| |
| return status; |
| } |
| |
| /** |
| * @brief Provide a new output buffer to be filled with the data computed by FMAC unit. |
| * @param hfmac pointer to a FMAC_HandleTypeDef structure that contains |
| * the configuration information for FMAC module. |
| * @param pOutput New output vector. |
| * @param pOutputSize Size of the output vector (if the vector can't |
| * be entirely filled, pOutputSize will be updated with the number |
| * of data read from FMAC). |
| * @retval HAL_StatusTypeDef HAL status |
| */ |
| HAL_StatusTypeDef HAL_FMAC_ConfigFilterOutputBuffer(FMAC_HandleTypeDef *hfmac, int16_t *pOutput, uint16_t *pOutputSize) |
| { |
| HAL_StatusTypeDef status; |
| |
| /* Check the function parameters */ |
| if ((pOutput == NULL) || (pOutputSize == NULL)) |
| { |
| return HAL_ERROR; |
| } |
| if (*pOutputSize == 0U) |
| { |
| return HAL_ERROR; |
| } |
| |
| /* Check the START bit state */ |
| if (FMAC_GET_START_BIT(hfmac) == 0U) |
| { |
| return HAL_ERROR; |
| } |
| |
| /* Check the FMAC configuration */ |
| if (hfmac->OutputAccess == FMAC_BUFFER_ACCESS_NONE) |
| { |
| return HAL_ERROR; |
| } |
| |
| /* Check whether the previous output vector has been handled */ |
| if ((hfmac->pOutputSize != NULL) && (hfmac->OutputCurrentSize < * (hfmac->pOutputSize))) |
| { |
| return HAL_ERROR; |
| } |
| |
| /* Check that FMAC was initialized and that not reading is already ongoing */ |
| if (hfmac->RdState == HAL_FMAC_STATE_READY) |
| { |
| /* Register the new output buffer */ |
| status = FMAC_ConfigFilterOutputBufferUpdateState(hfmac, pOutput, pOutputSize); |
| } |
| else |
| { |
| status = HAL_ERROR; |
| } |
| |
| return status; |
| } |
| |
| /** |
| * @brief Handle the input and/or output data in polling mode |
| * @note This function writes the previously provided user's input data and |
| * fills the previously provided user's output buffer, |
| * according to the existing FMAC configuration (polling mode only). |
| * The function returns when the input data has been handled or |
| * when the output data is filled. The possible unused data isn't |
| * kept. It will be up to the user to handle it. The previously |
| * provided pInputSize and pOutputSize will be used to indicate to the |
| * size of the read/written data to the user. |
| * @param hfmac pointer to a FMAC_HandleTypeDef structure that contains |
| * the configuration information for FMAC module. |
| * @param Timeout timeout value. |
| * @retval HAL_StatusTypeDef HAL status |
| */ |
| HAL_StatusTypeDef HAL_FMAC_PollFilterData(FMAC_HandleTypeDef *hfmac, uint32_t Timeout) |
| { |
| uint32_t tickstart; |
| uint8_t inpolling; |
| uint8_t inpollingover = POLLING_NOT_STOPPED; |
| uint8_t outpolling; |
| uint8_t outpollingover = POLLING_NOT_STOPPED; |
| HAL_StatusTypeDef status; |
| |
| /* Check the START bit state */ |
| if (FMAC_GET_START_BIT(hfmac) == 0U) |
| { |
| return HAL_ERROR; |
| } |
| |
| /* Check the configuration */ |
| |
| /* Get the input and output mode (if no buffer was previously provided, nothing will be read/written) */ |
| if ((hfmac->InputAccess == FMAC_BUFFER_ACCESS_POLLING) && (hfmac->pInput != NULL)) |
| { |
| inpolling = POLLING_ENABLED; |
| } |
| else |
| { |
| inpolling = POLLING_DISABLED; |
| } |
| if ((hfmac->OutputAccess == FMAC_BUFFER_ACCESS_POLLING) && (hfmac->pOutput != NULL)) |
| { |
| outpolling = POLLING_ENABLED; |
| } |
| else |
| { |
| outpolling = POLLING_DISABLED; |
| } |
| |
| /* Check the configuration */ |
| if ((inpolling == POLLING_DISABLED) && (outpolling == POLLING_DISABLED)) |
| { |
| return HAL_ERROR; |
| } |
| |
| /* Check handle state is ready */ |
| if (hfmac->State == HAL_FMAC_STATE_READY) |
| { |
| /* Change the FMAC state */ |
| hfmac->State = HAL_FMAC_STATE_BUSY; |
| |
| /* Get tick */ |
| tickstart = HAL_GetTick(); |
| |
| /* Loop on reading and writing until timeout */ |
| while ((HAL_GetTick() - tickstart) < Timeout) |
| { |
| /* X1: Check the mode: polling or none */ |
| if (inpolling != POLLING_DISABLED) |
| { |
| FMAC_WriteDataIncrementPtr(hfmac, MAX_FILTER_DATA_SIZE_TO_HANDLE); |
| if (hfmac->InputCurrentSize == *(hfmac->pInputSize)) |
| { |
| inpollingover = POLLING_STOPPED; |
| } |
| } |
| |
| /* Y: Check the mode: polling or none */ |
| if (outpolling != POLLING_DISABLED) |
| { |
| FMAC_ReadDataIncrementPtr(hfmac, MAX_FILTER_DATA_SIZE_TO_HANDLE); |
| if (hfmac->OutputCurrentSize == *(hfmac->pOutputSize)) |
| { |
| outpollingover = POLLING_STOPPED; |
| } |
| } |
| |
| /* Exit if there isn't data to handle anymore on one side or another */ |
| if ((inpollingover != POLLING_NOT_STOPPED) || (outpollingover != POLLING_NOT_STOPPED)) |
| { |
| break; |
| } |
| } |
| |
| /* Change the FMAC state; update the input and output sizes; reset the indexes */ |
| if (inpolling != POLLING_DISABLED) |
| { |
| (*(hfmac->pInputSize)) = hfmac->InputCurrentSize; |
| FMAC_ResetInputStateAndDataPointers(hfmac); |
| } |
| if (outpolling != POLLING_DISABLED) |
| { |
| (*(hfmac->pOutputSize)) = hfmac->OutputCurrentSize; |
| FMAC_ResetOutputStateAndDataPointers(hfmac); |
| } |
| |
| /* Reset the busy flag (do not overwrite the possible write and read flag) */ |
| hfmac->State = HAL_FMAC_STATE_READY; |
| |
| if ((HAL_GetTick() - tickstart) >= Timeout) |
| { |
| hfmac->ErrorCode |= HAL_FMAC_ERROR_TIMEOUT; |
| status = HAL_ERROR; |
| } |
| else |
| { |
| status = HAL_OK; |
| } |
| } |
| else |
| { |
| status = HAL_ERROR; |
| } |
| |
| return status; |
| } |
| |
| /** |
| * @brief Stop the FMAC processing. |
| * @param hfmac pointer to a FMAC_HandleTypeDef structure that contains |
| * the configuration information for FMAC module. |
| * @retval HAL_StatusTypeDef HAL status |
| */ |
| HAL_StatusTypeDef HAL_FMAC_FilterStop(FMAC_HandleTypeDef *hfmac) |
| { |
| HAL_StatusTypeDef status; |
| |
| /* Check handle state is ready */ |
| if (hfmac->State == HAL_FMAC_STATE_READY) |
| { |
| /* Change the FMAC state */ |
| hfmac->State = HAL_FMAC_STATE_BUSY; |
| |
| /* Set the START bit to 0 (stop the previously configured filter) */ |
| CLEAR_BIT(hfmac->Instance->PARAM, FMAC_PARAM_START); |
| |
| /* Disable the interrupts in order to avoid crossing cases */ |
| CLEAR_BIT(hfmac->Instance->CR, FMAC_DMA_REN | FMAC_DMA_WEN | FMAC_IT_RIEN | FMAC_IT_WIEN); |
| |
| /* In case of IT, update the sizes */ |
| if ((hfmac->InputAccess == FMAC_BUFFER_ACCESS_IT) && (hfmac->pInput != NULL)) |
| { |
| (*(hfmac->pInputSize)) = hfmac->InputCurrentSize; |
| } |
| if ((hfmac->OutputAccess == FMAC_BUFFER_ACCESS_IT) && (hfmac->pOutput != NULL)) |
| { |
| (*(hfmac->pOutputSize)) = hfmac->OutputCurrentSize; |
| } |
| |
| /* Reset FMAC unit (internal pointers) */ |
| if (FMAC_Reset(hfmac) == HAL_ERROR) |
| { |
| /* Update FMAC error code and FMAC peripheral state */ |
| hfmac->ErrorCode = HAL_FMAC_ERROR_RESET; |
| hfmac->State = HAL_FMAC_STATE_TIMEOUT; |
| status = HAL_ERROR; |
| } |
| else |
| { |
| /* Reset the data pointers */ |
| FMAC_ResetDataPointers(hfmac); |
| |
| status = HAL_OK; |
| } |
| |
| /* Reset the busy flag */ |
| hfmac->State = HAL_FMAC_STATE_READY; |
| } |
| else |
| { |
| status = HAL_ERROR; |
| } |
| |
| return status; |
| } |
| |
| /** |
| * @} |
| */ |
| |
| /** @defgroup FMAC_Exported_Functions_Group3 Callback functions |
| * @brief Callback functions. |
| * |
| @verbatim |
| ============================================================================== |
| ##### Callback functions ##### |
| ============================================================================== |
| [..] This section provides Interruption and DMA callback functions: |
| (+) DMA or Interrupt: the user's input data is half written (DMA only) |
| or completely written. |
| (+) DMA or Interrupt: the user's output buffer is half filled (DMA only) |
| or completely filled. |
| (+) DMA or Interrupt: error handling. |
| |
| @endverbatim |
| * @{ |
| */ |
| |
| /** |
| * @brief FMAC error callback. |
| * @param hfmac pointer to a FMAC_HandleTypeDef structure that contains |
| * the configuration information for FMAC module. |
| * @retval None |
| */ |
| __weak void HAL_FMAC_ErrorCallback(FMAC_HandleTypeDef *hfmac) |
| { |
| /* Prevent unused argument(s) compilation warning */ |
| UNUSED(hfmac); |
| |
| /* NOTE : This function should not be modified; when the callback is needed, |
| the HAL_FMAC_ErrorCallback can be implemented in the user file. |
| */ |
| } |
| |
| /** |
| * @brief FMAC get half data callback. |
| * @param hfmac pointer to a FMAC_HandleTypeDef structure that contains |
| * the configuration information for FMAC module. |
| * @retval None |
| */ |
| __weak void HAL_FMAC_HalfGetDataCallback(FMAC_HandleTypeDef *hfmac) |
| { |
| /* Prevent unused argument(s) compilation warning */ |
| UNUSED(hfmac); |
| |
| /* NOTE : This function should not be modified; when the callback is needed, |
| the HAL_FMAC_HalfGetDataCallback can be implemented in the user file. |
| */ |
| } |
| |
| /** |
| * @brief FMAC get data callback. |
| * @param hfmac pointer to a FMAC_HandleTypeDef structure that contains |
| * the configuration information for FMAC module. |
| * @retval None |
| */ |
| __weak void HAL_FMAC_GetDataCallback(FMAC_HandleTypeDef *hfmac) |
| { |
| /* Prevent unused argument(s) compilation warning */ |
| UNUSED(hfmac); |
| |
| /* NOTE : This function should not be modified; when the callback is needed, |
| the HAL_FMAC_GetDataCallback can be implemented in the user file. |
| */ |
| } |
| |
| /** |
| * @brief FMAC half output data ready callback. |
| * @param hfmac pointer to a FMAC_HandleTypeDef structure that contains |
| * the configuration information for FMAC module. |
| * @retval None |
| */ |
| __weak void HAL_FMAC_HalfOutputDataReadyCallback(FMAC_HandleTypeDef *hfmac) |
| { |
| /* Prevent unused argument(s) compilation warning */ |
| UNUSED(hfmac); |
| |
| /* NOTE : This function should not be modified; when the callback is needed, |
| the HAL_FMAC_HalfOutputDataReadyCallback can be implemented in the user file. |
| */ |
| } |
| |
| /** |
| * @brief FMAC output data ready callback. |
| * @param hfmac pointer to a FMAC_HandleTypeDef structure that contains |
| * the configuration information for FMAC module. |
| * @retval None |
| */ |
| __weak void HAL_FMAC_OutputDataReadyCallback(FMAC_HandleTypeDef *hfmac) |
| { |
| /* Prevent unused argument(s) compilation warning */ |
| UNUSED(hfmac); |
| |
| /* NOTE : This function should not be modified; when the callback is needed, |
| the HAL_FMAC_OutputDataReadyCallback can be implemented in the user file. |
| */ |
| } |
| |
| /** |
| * @brief FMAC filter configuration callback. |
| * @param hfmac pointer to a FMAC_HandleTypeDef structure that contains |
| * the configuration information for FMAC module. |
| * @retval None |
| */ |
| __weak void HAL_FMAC_FilterConfigCallback(FMAC_HandleTypeDef *hfmac) |
| { |
| /* Prevent unused argument(s) compilation warning */ |
| UNUSED(hfmac); |
| |
| /* NOTE : This function should not be modified; when the callback is needed, |
| the HAL_FMAC_FilterConfigCallback can be implemented in the user file. |
| */ |
| } |
| |
| /** |
| * @brief FMAC filter preload callback. |
| * @param hfmac pointer to a FMAC_HandleTypeDef structure that contains |
| * the configuration information for FMAC module. |
| * @retval None |
| */ |
| __weak void HAL_FMAC_FilterPreloadCallback(FMAC_HandleTypeDef *hfmac) |
| { |
| /* Prevent unused argument(s) compilation warning */ |
| UNUSED(hfmac); |
| |
| /* NOTE : This function should not be modified; when the callback is needed, |
| the HAL_FMAC_FilterPreloadCallback can be implemented in the user file. |
| */ |
| } |
| |
| /** |
| * @} |
| */ |
| |
| /** @defgroup FMAC_Exported_Functions_Group4 IRQ handler management |
| * @brief IRQ handler. |
| * |
| @verbatim |
| ============================================================================== |
| ##### IRQ handler management ##### |
| ============================================================================== |
| [..] This section provides IRQ handler function. |
| |
| @endverbatim |
| * @{ |
| */ |
| |
| /** |
| * @brief Handle FMAC interrupt request. |
| * @param hfmac pointer to a FMAC_HandleTypeDef structure that contains |
| * the configuration information for FMAC module. |
| * @retval None |
| */ |
| void HAL_FMAC_IRQHandler(FMAC_HandleTypeDef *hfmac) |
| { |
| uint32_t itsource; |
| |
| /* Check if the read interrupt is enabled and if Y buffer empty flag isn't set */ |
| itsource = __HAL_FMAC_GET_IT_SOURCE(hfmac, FMAC_IT_RIEN); |
| if ((__HAL_FMAC_GET_FLAG(hfmac, FMAC_FLAG_YEMPTY) == 0U) && (itsource != 0U)) |
| { |
| /* Read some data if possible (Y size is used as a pseudo timeout in order |
| to not get stuck too long under IT if FMAC keeps on processing input |
| data reloaded via DMA for instance). */ |
| if (hfmac->pOutput != NULL) |
| { |
| FMAC_ReadDataIncrementPtr(hfmac, (uint16_t)FMAC_GET_Y_SIZE(hfmac)); |
| } |
| |
| /* Indicate that data is ready to be read */ |
| if ((hfmac->pOutput == NULL) || (hfmac->OutputCurrentSize == *(hfmac->pOutputSize))) |
| { |
| /* Reset the pointers to indicate new data will be needed */ |
| FMAC_ResetOutputStateAndDataPointers(hfmac); |
| |
| /* Call the output data ready callback */ |
| #if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1) |
| hfmac->OutputDataReadyCallback(hfmac); |
| #else |
| HAL_FMAC_OutputDataReadyCallback(hfmac); |
| #endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */ |
| } |
| } |
| |
| /* Check if the write interrupt is enabled and if X1 buffer full flag isn't set */ |
| itsource = __HAL_FMAC_GET_IT_SOURCE(hfmac, FMAC_IT_WIEN); |
| if ((__HAL_FMAC_GET_FLAG(hfmac, FMAC_FLAG_X1FULL) == 0U) && (itsource != 0U)) |
| { |
| /* Write some data if possible (X1 size is used as a pseudo timeout in order |
| to not get stuck too long under IT if FMAC keep on processing input |
| data whereas its output emptied via DMA for instance). */ |
| if (hfmac->pInput != NULL) |
| { |
| FMAC_WriteDataIncrementPtr(hfmac, (uint16_t)FMAC_GET_X1_SIZE(hfmac)); |
| } |
| |
| /* Indicate that new data will be needed */ |
| if ((hfmac->pInput == NULL) || (hfmac->InputCurrentSize == *(hfmac->pInputSize))) |
| { |
| /* Reset the pointers to indicate new data will be needed */ |
| FMAC_ResetInputStateAndDataPointers(hfmac); |
| |
| /* Call the get data callback */ |
| #if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1) |
| hfmac->GetDataCallback(hfmac); |
| #else |
| HAL_FMAC_GetDataCallback(hfmac); |
| #endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */ |
| } |
| } |
| |
| /* Check if the overflow error interrupt is enabled and if overflow error flag is raised */ |
| itsource = __HAL_FMAC_GET_IT_SOURCE(hfmac, FMAC_IT_OVFLIEN); |
| if ((__HAL_FMAC_GET_FLAG(hfmac, FMAC_FLAG_OVFL) != 0U) && (itsource != 0U)) |
| { |
| hfmac->ErrorCode |= HAL_FMAC_ERROR_OVFL; |
| } |
| |
| /* Check if the underflow error interrupt is enabled and if underflow error flag is raised */ |
| itsource = __HAL_FMAC_GET_IT_SOURCE(hfmac, FMAC_IT_UNFLIEN); |
| if ((__HAL_FMAC_GET_FLAG(hfmac, FMAC_FLAG_UNFL) != 0U) && (itsource != 0U)) |
| { |
| hfmac->ErrorCode |= HAL_FMAC_ERROR_UNFL; |
| } |
| |
| /* Check if the saturation error interrupt is enabled and if saturation error flag is raised */ |
| itsource = __HAL_FMAC_GET_IT_SOURCE(hfmac, FMAC_IT_SATIEN); |
| if ((__HAL_FMAC_GET_FLAG(hfmac, FMAC_FLAG_SAT) != 0U) && (itsource != 0U)) |
| { |
| hfmac->ErrorCode |= HAL_FMAC_ERROR_SAT; |
| } |
| |
| /* Call the error callback if an error occurred */ |
| if (hfmac->ErrorCode != HAL_FMAC_ERROR_NONE) |
| { |
| /* Call the error callback */ |
| #if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1) |
| hfmac->ErrorCallback(hfmac); |
| #else |
| HAL_FMAC_ErrorCallback(hfmac); |
| #endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */ |
| } |
| } |
| |
| /** |
| * @} |
| */ |
| |
| /** @defgroup FMAC_Exported_Functions_Group5 Peripheral State and Error functions |
| * @brief Peripheral State and Error functions. |
| * |
| @verbatim |
| ============================================================================== |
| ##### Peripheral State and Error functions ##### |
| ============================================================================== |
| [..] This subsection provides functions allowing to |
| (+) Check the FMAC state |
| (+) Get error code |
| |
| @endverbatim |
| * @{ |
| */ |
| |
| /** |
| * @brief Return the FMAC state. |
| * @param hfmac pointer to a FMAC_HandleTypeDef structure that contains |
| * the configuration information for FMAC module. |
| * @retval HAL_FMAC_StateTypeDef FMAC state |
| */ |
| HAL_FMAC_StateTypeDef HAL_FMAC_GetState(const FMAC_HandleTypeDef *hfmac) |
| { |
| /* Return FMAC state */ |
| return hfmac->State; |
| } |
| |
| /** |
| * @brief Return the FMAC peripheral error. |
| * @param hfmac pointer to a FMAC_HandleTypeDef structure that contains |
| * the configuration information for FMAC module. |
| * @note The returned error is a bit-map combination of possible errors. |
| * @retval uint32_t Error bit-map based on @ref FMAC_Error_Code |
| */ |
| uint32_t HAL_FMAC_GetError(const FMAC_HandleTypeDef *hfmac) |
| { |
| /* Return FMAC error code */ |
| return hfmac->ErrorCode; |
| } |
| |
| /** |
| * @} |
| */ |
| |
| /** |
| * @} |
| */ |
| |
| /** @defgroup FMAC_Private_Functions FMAC Private Functions |
| * @{ |
| */ |
| |
| /** |
| ============================================================================== |
| ##### FMAC Private Functions ##### |
| ============================================================================== |
| */ |
| /** |
| * @brief Perform a reset of the FMAC unit. |
| * @param hfmac FMAC handle. |
| * @retval HAL_StatusTypeDef HAL status |
| */ |
| static HAL_StatusTypeDef FMAC_Reset(FMAC_HandleTypeDef *hfmac) |
| { |
| uint32_t tickstart; |
| |
| /* Init tickstart for timeout management*/ |
| tickstart = HAL_GetTick(); |
| |
| /* Perform the reset */ |
| SET_BIT(hfmac->Instance->CR, FMAC_CR_RESET); |
| |
| /* Wait until flag is reset */ |
| while (READ_BIT(hfmac->Instance->CR, FMAC_CR_RESET) != 0U) |
| { |
| if ((HAL_GetTick() - tickstart) > HAL_FMAC_RESET_TIMEOUT_VALUE) |
| { |
| hfmac->ErrorCode |= HAL_FMAC_ERROR_TIMEOUT; |
| return HAL_ERROR; |
| } |
| } |
| |
| hfmac->ErrorCode = HAL_FMAC_ERROR_NONE; |
| return HAL_OK; |
| } |
| |
| /** |
| * @brief Reset the data pointers of the FMAC unit. |
| * @param hfmac FMAC handle. |
| * @retval None |
| */ |
| static void FMAC_ResetDataPointers(FMAC_HandleTypeDef *hfmac) |
| { |
| FMAC_ResetInputStateAndDataPointers(hfmac); |
| FMAC_ResetOutputStateAndDataPointers(hfmac); |
| } |
| |
| /** |
| * @brief Reset the input data pointers of the FMAC unit. |
| * @param hfmac FMAC handle. |
| * @retval None |
| */ |
| static void FMAC_ResetInputStateAndDataPointers(FMAC_HandleTypeDef *hfmac) |
| { |
| hfmac->pInput = NULL; |
| hfmac->pInputSize = NULL; |
| hfmac->InputCurrentSize = 0U; |
| hfmac->WrState = HAL_FMAC_STATE_READY; |
| } |
| |
| /** |
| * @brief Reset the output data pointers of the FMAC unit. |
| * @param hfmac FMAC handle. |
| * @retval None |
| */ |
| static void FMAC_ResetOutputStateAndDataPointers(FMAC_HandleTypeDef *hfmac) |
| { |
| hfmac->pOutput = NULL; |
| hfmac->pOutputSize = NULL; |
| hfmac->OutputCurrentSize = 0U; |
| hfmac->RdState = HAL_FMAC_STATE_READY; |
| } |
| |
| /** |
| * @brief Configure the FMAC filter. |
| * @note The configuration is done according to the parameters |
| * specified in the FMAC_FilterConfigTypeDef structure. |
| * @param hfmac pointer to a FMAC_HandleTypeDef structure that contains |
| * the configuration information for FMAC module. |
| * @param pConfig pointer to a FMAC_FilterConfigTypeDef structure that |
| * contains the FMAC configuration information. |
| * @param PreloadAccess access mode used for the preload (polling or DMA). |
| * @retval HAL_StatusTypeDef HAL status |
| */ |
| static HAL_StatusTypeDef FMAC_FilterConfig(FMAC_HandleTypeDef *hfmac, FMAC_FilterConfigTypeDef *pConfig, |
| uint8_t PreloadAccess) |
| { |
| uint32_t tickstart; |
| uint32_t tmpcr; |
| #if defined(USE_FULL_ASSERT) |
| uint32_t x2size; |
| #endif /* USE_FULL_ASSERT */ |
| |
| /* Check the parameters */ |
| assert_param(IS_FMAC_THRESHOLD(pConfig->InputThreshold)); |
| assert_param(IS_FMAC_THRESHOLD(pConfig->OutputThreshold)); |
| assert_param(IS_FMAC_BUFFER_ACCESS(pConfig->InputAccess)); |
| assert_param(IS_FMAC_BUFFER_ACCESS(pConfig->OutputAccess)); |
| assert_param(IS_FMAC_CLIP_STATE(pConfig->Clip)); |
| assert_param(IS_FMAC_FILTER_FUNCTION(pConfig->Filter)); |
| assert_param(IS_FMAC_PARAM_P(pConfig->Filter, pConfig->P)); |
| assert_param(IS_FMAC_PARAM_Q(pConfig->Filter, pConfig->Q)); |
| assert_param(IS_FMAC_PARAM_R(pConfig->Filter, pConfig->R)); |
| |
| /* Check the START bit state */ |
| if (FMAC_GET_START_BIT(hfmac) != 0U) |
| { |
| return HAL_ERROR; |
| } |
| |
| /* Check handle state is ready */ |
| if (hfmac->State != HAL_FMAC_STATE_READY) |
| { |
| return HAL_ERROR; |
| } |
| |
| /* Change the FMAC state */ |
| hfmac->State = HAL_FMAC_STATE_BUSY; |
| |
| /* Get tick */ |
| tickstart = HAL_GetTick(); |
| |
| /* Indicate that there is no valid configuration done */ |
| hfmac->FilterParam = 0U; |
| |
| /* FMAC_X1BUFCFG: Configure the input buffer within the internal memory if required */ |
| if (pConfig->InputBufferSize != 0U) |
| { |
| MODIFY_REG(hfmac->Instance->X1BUFCFG, \ |
| (FMAC_X1BUFCFG_X1_BASE | FMAC_X1BUFCFG_X1_BUF_SIZE), \ |
| (((((uint32_t)(pConfig->InputBaseAddress)) << FMAC_X1BUFCFG_X1_BASE_Pos) & FMAC_X1BUFCFG_X1_BASE) | \ |
| ((((uint32_t)(pConfig->InputBufferSize)) << FMAC_X1BUFCFG_X1_BUF_SIZE_Pos) & \ |
| FMAC_X1BUFCFG_X1_BUF_SIZE))); |
| } |
| |
| /* FMAC_X1BUFCFG: Configure the input threshold if valid when compared to the configured X1 size */ |
| if (pConfig->InputThreshold != FMAC_THRESHOLD_NO_VALUE) |
| { |
| /* Check the parameter */ |
| assert_param(IS_FMAC_THRESHOLD_APPLICABLE(FMAC_GET_X1_SIZE(hfmac), pConfig->InputThreshold, pConfig->InputAccess)); |
| |
| MODIFY_REG(hfmac->Instance->X1BUFCFG, \ |
| FMAC_X1BUFCFG_FULL_WM, \ |
| ((pConfig->InputThreshold) & FMAC_X1BUFCFG_FULL_WM)); |
| } |
| |
| /* FMAC_X2BUFCFG: Configure the coefficient buffer within the internal memory */ |
| if (pConfig->CoeffBufferSize != 0U) |
| { |
| MODIFY_REG(hfmac->Instance->X2BUFCFG, \ |
| (FMAC_X2BUFCFG_X2_BASE | FMAC_X2BUFCFG_X2_BUF_SIZE), \ |
| (((((uint32_t)(pConfig->CoeffBaseAddress)) << FMAC_X2BUFCFG_X2_BASE_Pos) & FMAC_X2BUFCFG_X2_BASE) | \ |
| ((((uint32_t)(pConfig->CoeffBufferSize)) << FMAC_X2BUFCFG_X2_BUF_SIZE_Pos) &\ |
| FMAC_X2BUFCFG_X2_BUF_SIZE))); |
| } |
| |
| /* FMAC_YBUFCFG: Configure the output buffer within the internal memory if required */ |
| if (pConfig->OutputBufferSize != 0U) |
| { |
| MODIFY_REG(hfmac->Instance->YBUFCFG, \ |
| (FMAC_YBUFCFG_Y_BASE | FMAC_YBUFCFG_Y_BUF_SIZE), \ |
| (((((uint32_t)(pConfig->OutputBaseAddress)) << FMAC_YBUFCFG_Y_BASE_Pos) & FMAC_YBUFCFG_Y_BASE) | \ |
| ((((uint32_t)(pConfig->OutputBufferSize)) << FMAC_YBUFCFG_Y_BUF_SIZE_Pos) & FMAC_YBUFCFG_Y_BUF_SIZE))); |
| } |
| |
| /* FMAC_YBUFCFG: Configure the output threshold if valid when compared to the configured Y size */ |
| if (pConfig->OutputThreshold != FMAC_THRESHOLD_NO_VALUE) |
| { |
| /* Check the parameter */ |
| assert_param(IS_FMAC_THRESHOLD_APPLICABLE(FMAC_GET_Y_SIZE(hfmac), pConfig->OutputThreshold, pConfig->OutputAccess)); |
| |
| MODIFY_REG(hfmac->Instance->YBUFCFG, \ |
| FMAC_YBUFCFG_EMPTY_WM, \ |
| ((pConfig->OutputThreshold) & FMAC_YBUFCFG_EMPTY_WM)); |
| } |
| |
| /* FMAC_CR: Configure the clip feature */ |
| tmpcr = pConfig->Clip & FMAC_CR_CLIPEN; |
| |
| /* FMAC_CR: If IT or DMA will be used, enable error interrupts. |
| * Being more a debugging feature, FMAC_CR_SATIEN isn't enabled by default. */ |
| if ((pConfig->InputAccess == FMAC_BUFFER_ACCESS_DMA) || (pConfig->InputAccess == FMAC_BUFFER_ACCESS_IT) || |
| (pConfig->OutputAccess == FMAC_BUFFER_ACCESS_DMA) || (pConfig->OutputAccess == FMAC_BUFFER_ACCESS_IT)) |
| { |
| tmpcr |= FMAC_IT_UNFLIEN | FMAC_IT_OVFLIEN; |
| } |
| |
| /* FMAC_CR: write the value */ |
| WRITE_REG(hfmac->Instance->CR, tmpcr); |
| |
| /* Save the input/output accesses in order to configure RIEN, WIEN, DMAREN and DMAWEN during filter start */ |
| hfmac->InputAccess = pConfig->InputAccess; |
| hfmac->OutputAccess = pConfig->OutputAccess; |
| |
| /* Check whether the configured X2 is big enough for the filter */ |
| #if defined(USE_FULL_ASSERT) |
| x2size = FMAC_GET_X2_SIZE(hfmac); |
| #endif /* USE_FULL_ASSERT */ |
| assert_param(((pConfig->Filter == FMAC_FUNC_CONVO_FIR) && (x2size >= pConfig->P)) || \ |
| ((pConfig->Filter == FMAC_FUNC_IIR_DIRECT_FORM_1) && \ |
| (x2size >= ((uint32_t)pConfig->P + (uint32_t)pConfig->Q)))); |
| |
| /* Build the PARAM value that will be used when starting the filter */ |
| hfmac->FilterParam = (FMAC_PARAM_START | pConfig->Filter | \ |
| ((((uint32_t)(pConfig->P)) << FMAC_PARAM_P_Pos) & FMAC_PARAM_P) | \ |
| ((((uint32_t)(pConfig->Q)) << FMAC_PARAM_Q_Pos) & FMAC_PARAM_Q) | \ |
| ((((uint32_t)(pConfig->R)) << FMAC_PARAM_R_Pos) & FMAC_PARAM_R)); |
| |
| /* Initialize the coefficient buffer if required (pCoeffA for FIR only) */ |
| if ((pConfig->pCoeffB != NULL) && (pConfig->CoeffBSize != 0U)) |
| { |
| /* FIR/IIR: The provided coefficients should match X2 size */ |
| assert_param(((uint32_t)pConfig->CoeffASize + (uint32_t)pConfig->CoeffBSize) <= x2size); |
| /* FIR/IIR: The size of pCoeffB should match the parameter P */ |
| assert_param(pConfig->CoeffBSize >= pConfig->P); |
| /* pCoeffA should be provided for IIR but not for FIR */ |
| /* IIR : if pCoeffB is provided, pCoeffA should also be there */ |
| /* IIR: The size of pCoeffA should match the parameter Q */ |
| assert_param(((pConfig->Filter == FMAC_FUNC_CONVO_FIR) && |
| (pConfig->pCoeffA == NULL) && (pConfig->CoeffASize == 0U)) || |
| ((pConfig->Filter == FMAC_FUNC_IIR_DIRECT_FORM_1) && |
| (pConfig->pCoeffA != NULL) && (pConfig->CoeffASize != 0U) && |
| (pConfig->CoeffASize >= pConfig->Q))); |
| |
| /* Write number of values to be loaded, the data load function and start the operation */ |
| WRITE_REG(hfmac->Instance->PARAM, \ |
| (((uint32_t)(pConfig->CoeffBSize) << FMAC_PARAM_P_Pos) | \ |
| ((uint32_t)(pConfig->CoeffASize) << FMAC_PARAM_Q_Pos) | \ |
| FMAC_FUNC_LOAD_X2 | FMAC_PARAM_START)); |
| |
| if (PreloadAccess == PRELOAD_ACCESS_POLLING) |
| { |
| /* Load the buffer into the internal memory */ |
| FMAC_WritePreloadDataIncrementPtr(hfmac, &(pConfig->pCoeffB), pConfig->CoeffBSize); |
| |
| /* Load pCoeffA if needed */ |
| if ((pConfig->pCoeffA != NULL) && (pConfig->CoeffASize != 0U)) |
| { |
| /* Load the buffer into the internal memory */ |
| FMAC_WritePreloadDataIncrementPtr(hfmac, &(pConfig->pCoeffA), pConfig->CoeffASize); |
| } |
| |
| /* Wait for the end of the writing */ |
| if (FMAC_WaitOnStartUntilTimeout(hfmac, tickstart, HAL_FMAC_TIMEOUT_VALUE) != HAL_OK) |
| { |
| hfmac->ErrorCode |= HAL_FMAC_ERROR_TIMEOUT; |
| hfmac->State = HAL_FMAC_STATE_TIMEOUT; |
| return HAL_ERROR; |
| } |
| |
| /* Change the FMAC state */ |
| hfmac->State = HAL_FMAC_STATE_READY; |
| } |
| else |
| { |
| hfmac->pInput = pConfig->pCoeffA; |
| hfmac->InputCurrentSize = pConfig->CoeffASize; |
| |
| /* Set the FMAC DMA transfer complete callback */ |
| hfmac->hdmaPreload->XferHalfCpltCallback = NULL; |
| hfmac->hdmaPreload->XferCpltCallback = FMAC_DMAFilterConfig; |
| /* Set the DMA error callback */ |
| hfmac->hdmaPreload->XferErrorCallback = FMAC_DMAError; |
| |
| /* Enable the DMA stream managing FMAC preload data write */ |
| return (HAL_DMA_Start_IT(hfmac->hdmaPreload, (uint32_t)pConfig->pCoeffB, (uint32_t)&hfmac->Instance->WDATA, |
| pConfig->CoeffBSize)); |
| } |
| } |
| else |
| { |
| /* Change the FMAC state */ |
| hfmac->State = HAL_FMAC_STATE_READY; |
| } |
| |
| return HAL_OK; |
| } |
| |
| /** |
| * @brief Preload the input (FIR, IIR) and output data (IIR) of the FMAC filter. |
| * @note The set(s) of data will be used by FMAC as soon as @ref HAL_FMAC_FilterStart is called. |
| * @param hfmac pointer to a FMAC_HandleTypeDef structure that contains |
| * the configuration information for FMAC module. |
| * @param pInput Preloading of the first elements of the input buffer (X1). |
| * If not needed (no data available when starting), it should be set to NULL. |
| * @param InputSize Size of the input vector. |
| * As pInput is used for preloading data, it cannot be bigger than the input memory area. |
| * @param pOutput [IIR] Preloading of the first elements of the output vector (Y). |
| * If not needed, it should be set to NULL. |
| * @param OutputSize Size of the output vector. |
| * As pOutput is used for preloading data, it cannot be bigger than the output memory area. |
| * @param PreloadAccess access mode used for the preload (polling or DMA). |
| * @note The input and the output buffers can be filled by calling several times @ref HAL_FMAC_FilterPreload |
| * (each call filling partly the buffers). In case of overflow (too much data provided through |
| * all these calls), an error will be returned. |
| * @retval HAL_StatusTypeDef HAL status |
| */ |
| static HAL_StatusTypeDef FMAC_FilterPreload(FMAC_HandleTypeDef *hfmac, int16_t *pInput, uint8_t InputSize, |
| int16_t *pOutput, uint8_t OutputSize, uint8_t PreloadAccess) |
| { |
| uint32_t tickstart; |
| HAL_StatusTypeDef status; |
| |
| /* Check the START bit state */ |
| if (FMAC_GET_START_BIT(hfmac) != 0U) |
| { |
| return HAL_ERROR; |
| } |
| |
| /* Check that a valid configuration was done previously */ |
| if (hfmac->FilterParam == 0U) |
| { |
| return HAL_ERROR; |
| } |
| |
| /* Check the preload input buffers isn't too big */ |
| if ((InputSize > FMAC_GET_X1_SIZE(hfmac)) && (pInput != NULL)) |
| { |
| return HAL_ERROR; |
| } |
| |
| /* Check the preload output buffer isn't too big */ |
| if ((OutputSize > FMAC_GET_Y_SIZE(hfmac)) && (pOutput != NULL)) |
| { |
| return HAL_ERROR; |
| } |
| |
| /* Check handle state is ready */ |
| if (hfmac->State != HAL_FMAC_STATE_READY) |
| { |
| return HAL_ERROR; |
| } |
| |
| /* Change the FMAC state */ |
| hfmac->State = HAL_FMAC_STATE_BUSY; |
| |
| /* Get tick */ |
| tickstart = HAL_GetTick(); |
| |
| /* Preload the input buffer if required */ |
| if ((pInput != NULL) && (InputSize != 0U)) |
| { |
| /* Write number of values to be loaded, the data load function and start the operation */ |
| WRITE_REG(hfmac->Instance->PARAM, \ |
| (((uint32_t)InputSize << FMAC_PARAM_P_Pos) | FMAC_FUNC_LOAD_X1 | FMAC_PARAM_START)); |
| |
| if (PreloadAccess == PRELOAD_ACCESS_POLLING) |
| { |
| /* Load the buffer into the internal memory */ |
| FMAC_WritePreloadDataIncrementPtr(hfmac, &pInput, InputSize); |
| |
| /* Wait for the end of the writing */ |
| if (FMAC_WaitOnStartUntilTimeout(hfmac, tickstart, HAL_FMAC_TIMEOUT_VALUE) != HAL_OK) |
| { |
| hfmac->ErrorCode |= HAL_FMAC_ERROR_TIMEOUT; |
| hfmac->State = HAL_FMAC_STATE_TIMEOUT; |
| return HAL_ERROR; |
| } |
| } |
| else |
| { |
| hfmac->pInput = pOutput; |
| hfmac->InputCurrentSize = OutputSize; |
| |
| /* Set the FMAC DMA transfer complete callback */ |
| hfmac->hdmaPreload->XferHalfCpltCallback = NULL; |
| hfmac->hdmaPreload->XferCpltCallback = FMAC_DMAFilterPreload; |
| /* Set the DMA error callback */ |
| hfmac->hdmaPreload->XferErrorCallback = FMAC_DMAError; |
| |
| /* Enable the DMA stream managing FMAC preload data write */ |
| return (HAL_DMA_Start_IT(hfmac->hdmaPreload, (uint32_t)pInput, (uint32_t)&hfmac->Instance->WDATA, InputSize)); |
| } |
| } |
| |
| /* Preload the output buffer if required */ |
| if ((pOutput != NULL) && (OutputSize != 0U)) |
| { |
| /* Write number of values to be loaded, the data load function and start the operation */ |
| WRITE_REG(hfmac->Instance->PARAM, \ |
| (((uint32_t)OutputSize << FMAC_PARAM_P_Pos) | FMAC_FUNC_LOAD_Y | FMAC_PARAM_START)); |
| |
| if (PreloadAccess == PRELOAD_ACCESS_POLLING) |
| { |
| /* Load the buffer into the internal memory */ |
| FMAC_WritePreloadDataIncrementPtr(hfmac, &pOutput, OutputSize); |
| |
| /* Wait for the end of the writing */ |
| if (FMAC_WaitOnStartUntilTimeout(hfmac, tickstart, HAL_FMAC_TIMEOUT_VALUE) != HAL_OK) |
| { |
| hfmac->ErrorCode |= HAL_FMAC_ERROR_TIMEOUT; |
| hfmac->State = HAL_FMAC_STATE_TIMEOUT; |
| return HAL_ERROR; |
| } |
| } |
| else |
| { |
| hfmac->pInput = NULL; |
| hfmac->InputCurrentSize = 0U; |
| |
| /* Set the FMAC DMA transfer complete callback */ |
| hfmac->hdmaPreload->XferHalfCpltCallback = NULL; |
| hfmac->hdmaPreload->XferCpltCallback = FMAC_DMAFilterPreload; |
| /* Set the DMA error callback */ |
| hfmac->hdmaPreload->XferErrorCallback = FMAC_DMAError; |
| |
| /* Enable the DMA stream managing FMAC preload data write */ |
| return (HAL_DMA_Start_IT(hfmac->hdmaPreload, (uint32_t)pOutput, (uint32_t)&hfmac->Instance->WDATA, OutputSize)); |
| } |
| } |
| |
| /* Update the error codes */ |
| if (__HAL_FMAC_GET_FLAG(hfmac, FMAC_FLAG_OVFL)) |
| { |
| hfmac->ErrorCode |= HAL_FMAC_ERROR_OVFL; |
| } |
| if (__HAL_FMAC_GET_FLAG(hfmac, FMAC_FLAG_UNFL)) |
| { |
| hfmac->ErrorCode |= HAL_FMAC_ERROR_UNFL; |
| } |
| if (__HAL_FMAC_GET_FLAG(hfmac, FMAC_FLAG_SAT)) |
| { |
| hfmac->ErrorCode |= HAL_FMAC_ERROR_SAT; |
| } |
| |
| /* Change the FMAC state */ |
| hfmac->State = HAL_FMAC_STATE_READY; |
| |
| /* Return function status */ |
| if (hfmac->ErrorCode == HAL_FMAC_ERROR_NONE) |
| { |
| status = HAL_OK; |
| } |
| else |
| { |
| status = HAL_ERROR; |
| } |
| return status; |
| } |
| |
| /** |
| * @brief Write data into FMAC internal memory through WDATA and increment input buffer pointer. |
| * @note This function is only used with preload functions. |
| * @param hfmac pointer to a FMAC_HandleTypeDef structure that contains |
| * the configuration information for FMAC module. |
| * @param ppData pointer to pointer to the data buffer. |
| * @param Size size of the data buffer. |
| * @retval None |
| */ |
| static void FMAC_WritePreloadDataIncrementPtr(FMAC_HandleTypeDef *hfmac, int16_t **ppData, uint8_t Size) |
| { |
| uint8_t index; |
| |
| /* Load the buffer into the internal memory */ |
| for (index = Size; index > 0U; index--) |
| { |
| WRITE_REG(hfmac->Instance->WDATA, (((uint32_t)(*(*ppData))) & FMAC_WDATA_WDATA)); |
| (*ppData)++; |
| } |
| } |
| |
| /** |
| * @brief Handle FMAC Function Timeout. |
| * @param hfmac FMAC handle. |
| * @param Tickstart Tick start value. |
| * @param Timeout Timeout duration. |
| * @retval HAL_StatusTypeDef HAL status |
| */ |
| static HAL_StatusTypeDef FMAC_WaitOnStartUntilTimeout(FMAC_HandleTypeDef *hfmac, uint32_t Tickstart, uint32_t Timeout) |
| { |
| /* Wait until flag changes */ |
| while (READ_BIT(hfmac->Instance->PARAM, FMAC_PARAM_START) != 0U) |
| { |
| if ((HAL_GetTick() - Tickstart) > Timeout) |
| { |
| hfmac->ErrorCode |= HAL_FMAC_ERROR_TIMEOUT; |
| |
| return HAL_ERROR; |
| } |
| } |
| return HAL_OK; |
| } |
| |
| /** |
| * @brief Register the new input buffer, update DMA configuration if needed and change the FMAC state. |
| * @param hfmac pointer to a FMAC_HandleTypeDef structure that contains |
| * the configuration information for FMAC module. |
| * @param pInput New input vector (additional input data). |
| * @param pInputSize Size of the input vector (if all the data can't be |
| * written, it will be updated with the number of data read from FMAC). |
| * @retval HAL_StatusTypeDef HAL status |
| */ |
| static HAL_StatusTypeDef FMAC_AppendFilterDataUpdateState(FMAC_HandleTypeDef *hfmac, int16_t *pInput, |
| uint16_t *pInputSize) |
| { |
| /* Change the FMAC state */ |
| hfmac->WrState = HAL_FMAC_STATE_BUSY_WR; |
| |
| /* Reset the current size */ |
| hfmac->InputCurrentSize = 0U; |
| |
| /* Handle the pointer depending on the input access */ |
| if (hfmac->InputAccess == FMAC_BUFFER_ACCESS_DMA) |
| { |
| hfmac->pInput = NULL; |
| hfmac->pInputSize = NULL; |
| |
| /* Set the FMAC DMA transfer complete callback */ |
| hfmac->hdmaIn->XferHalfCpltCallback = FMAC_DMAHalfGetData; |
| hfmac->hdmaIn->XferCpltCallback = FMAC_DMAGetData; |
| /* Set the DMA error callback */ |
| hfmac->hdmaIn->XferErrorCallback = FMAC_DMAError; |
| |
| /* Enable the DMA stream managing FMAC input data write */ |
| return (HAL_DMA_Start_IT(hfmac->hdmaIn, (uint32_t)pInput, (uint32_t)&hfmac->Instance->WDATA, *pInputSize)); |
| } |
| else |
| { |
| /* Update the input data information (polling, IT) */ |
| hfmac->pInput = pInput; |
| hfmac->pInputSize = pInputSize; |
| } |
| |
| return HAL_OK; |
| } |
| |
| /** |
| * @brief Register the new output buffer, update DMA configuration if needed and change the FMAC state. |
| * @param hfmac pointer to a FMAC_HandleTypeDef structure that contains |
| * the configuration information for FMAC module. |
| * @param pOutput New output vector. |
| * @param pOutputSize Size of the output vector (if the vector can't |
| * be entirely filled, pOutputSize will be updated with the number |
| * of data read from FMAC). |
| * @retval HAL_StatusTypeDef HAL status |
| */ |
| static HAL_StatusTypeDef FMAC_ConfigFilterOutputBufferUpdateState(FMAC_HandleTypeDef *hfmac, int16_t *pOutput, |
| uint16_t *pOutputSize) |
| { |
| /* Reset the current size */ |
| hfmac->OutputCurrentSize = 0U; |
| |
| /* Check whether a valid pointer was provided */ |
| if ((pOutput == NULL) || (pOutputSize == NULL) || (*pOutputSize == 0U)) |
| { |
| /* The user will have to provide a valid configuration later */ |
| hfmac->pOutput = NULL; |
| hfmac->pOutputSize = NULL; |
| hfmac->RdState = HAL_FMAC_STATE_READY; |
| } |
| /* Handle the pointer depending on the input access */ |
| else if (hfmac->OutputAccess == FMAC_BUFFER_ACCESS_DMA) |
| { |
| hfmac->pOutput = NULL; |
| hfmac->pOutputSize = NULL; |
| hfmac->RdState = HAL_FMAC_STATE_BUSY_RD; |
| |
| /* Set the FMAC DMA transfer complete callback */ |
| hfmac->hdmaOut->XferHalfCpltCallback = FMAC_DMAHalfOutputDataReady; |
| hfmac->hdmaOut->XferCpltCallback = FMAC_DMAOutputDataReady; |
| /* Set the DMA error callback */ |
| hfmac->hdmaOut->XferErrorCallback = FMAC_DMAError; |
| |
| /* Enable the DMA stream managing FMAC output data read */ |
| return (HAL_DMA_Start_IT(hfmac->hdmaOut, (uint32_t)&hfmac->Instance->RDATA, (uint32_t)pOutput, *pOutputSize)); |
| } |
| else if (hfmac->OutputAccess == FMAC_BUFFER_ACCESS_NONE) |
| { |
| hfmac->pOutput = NULL; |
| hfmac->pOutputSize = NULL; |
| hfmac->RdState = HAL_FMAC_STATE_READY; |
| } |
| else |
| { |
| /* Update the output data information (polling, IT) */ |
| hfmac->pOutput = pOutput; |
| hfmac->pOutputSize = pOutputSize; |
| hfmac->RdState = HAL_FMAC_STATE_BUSY_RD; |
| } |
| |
| return HAL_OK; |
| } |
| |
| /** |
| * @brief Read available output data until Y EMPTY is set. |
| * @param hfmac FMAC handle. |
| * @param MaxSizeToRead Maximum number of data to read (this serves as a timeout |
| * if FMAC continuously writes into the output buffer). |
| * @retval None |
| */ |
| static void FMAC_ReadDataIncrementPtr(FMAC_HandleTypeDef *hfmac, uint16_t MaxSizeToRead) |
| { |
| uint16_t maxsize; |
| uint16_t threshold; |
| uint32_t tmpvalue; |
| |
| /* Check if there is data to read */ |
| if (READ_BIT(hfmac->Instance->SR, FMAC_SR_YEMPTY) != 0U) |
| { |
| return; |
| } |
| |
| /* Get the maximum index (no wait allowed, no overstepping of the output buffer) */ |
| if ((hfmac->OutputCurrentSize + MaxSizeToRead) > *(hfmac->pOutputSize)) |
| { |
| maxsize = *(hfmac->pOutputSize); |
| } |
| else |
| { |
| maxsize = hfmac->OutputCurrentSize + MaxSizeToRead; |
| } |
| |
| /* Read until there is no more room or no more data */ |
| do |
| { |
| /* If there is no more room, return */ |
| if (!(hfmac->OutputCurrentSize < maxsize)) |
| { |
| return; |
| } |
| |
| /* Read the available data */ |
| tmpvalue = ((READ_REG(hfmac->Instance->RDATA))& FMAC_RDATA_RDATA); |
| *(hfmac->pOutput) = (int16_t)tmpvalue; |
| hfmac->pOutput++; |
| hfmac->OutputCurrentSize++; |
| } while (READ_BIT(hfmac->Instance->SR, FMAC_SR_YEMPTY) == 0U); |
| |
| /* Y buffer empty flag has just be raised, read the threshold */ |
| threshold = (uint16_t)FMAC_GET_THRESHOLD_FROM_WM(FMAC_GET_Y_EMPTY_WM(hfmac)) - 1U; |
| |
| /* Update the maximum size if needed (limited data available) */ |
| if ((hfmac->OutputCurrentSize + threshold) < maxsize) |
| { |
| maxsize = hfmac->OutputCurrentSize + threshold; |
| } |
| |
| /* Read the available data */ |
| while (hfmac->OutputCurrentSize < maxsize) |
| { |
| tmpvalue = ((READ_REG(hfmac->Instance->RDATA))& FMAC_RDATA_RDATA); |
| *(hfmac->pOutput) = (int16_t)tmpvalue; |
| hfmac->pOutput++; |
| hfmac->OutputCurrentSize++; |
| } |
| } |
| |
| /** |
| * @brief Write available input data until X1 FULL is set. |
| * @param hfmac FMAC handle. |
| * @param MaxSizeToWrite Maximum number of data to write (this serves as a timeout |
| * if FMAC continuously empties the input buffer). |
| * @retval None |
| */ |
| static void FMAC_WriteDataIncrementPtr(FMAC_HandleTypeDef *hfmac, uint16_t MaxSizeToWrite) |
| { |
| uint16_t maxsize; |
| uint16_t threshold; |
| |
| /* Check if there is room in FMAC */ |
| if (READ_BIT(hfmac->Instance->SR, FMAC_SR_X1FULL) != 0U) |
| { |
| return; |
| } |
| |
| /* Get the maximum index (no wait allowed, no overstepping of the output buffer) */ |
| if ((hfmac->InputCurrentSize + MaxSizeToWrite) > *(hfmac->pInputSize)) |
| { |
| maxsize = *(hfmac->pInputSize); |
| } |
| else |
| { |
| maxsize = hfmac->InputCurrentSize + MaxSizeToWrite; |
| } |
| |
| /* Write until there is no more room or no more data */ |
| do |
| { |
| /* If there is no more room, return */ |
| if (!(hfmac->InputCurrentSize < maxsize)) |
| { |
| return; |
| } |
| |
| /* Write the available data */ |
| WRITE_REG(hfmac->Instance->WDATA, (((uint32_t)(*(hfmac->pInput))) & FMAC_WDATA_WDATA)); |
| hfmac->pInput++; |
| hfmac->InputCurrentSize++; |
| } while (READ_BIT(hfmac->Instance->SR, FMAC_SR_X1FULL) == 0U); |
| |
| /* X1 buffer full flag has just be raised, read the threshold */ |
| threshold = (uint16_t)FMAC_GET_THRESHOLD_FROM_WM(FMAC_GET_X1_FULL_WM(hfmac)) - 1U; |
| |
| /* Update the maximum size if needed (limited data available) */ |
| if ((hfmac->InputCurrentSize + threshold) < maxsize) |
| { |
| maxsize = hfmac->InputCurrentSize + threshold; |
| } |
| |
| /* Write the available data */ |
| while (hfmac->InputCurrentSize < maxsize) |
| { |
| WRITE_REG(hfmac->Instance->WDATA, (((uint32_t)(*(hfmac->pInput))) & FMAC_WDATA_WDATA)); |
| hfmac->pInput++; |
| hfmac->InputCurrentSize++; |
| } |
| } |
| |
| /** |
| * @brief DMA FMAC Input Data process half complete callback. |
| * @param hdma DMA handle. |
| * @retval None |
| */ |
| static void FMAC_DMAHalfGetData(DMA_HandleTypeDef *hdma) |
| { |
| FMAC_HandleTypeDef *hfmac = (FMAC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; |
| |
| /* Call half get data callback */ |
| #if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1) |
| hfmac->HalfGetDataCallback(hfmac); |
| #else |
| HAL_FMAC_HalfGetDataCallback(hfmac); |
| #endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */ |
| } |
| |
| /** |
| * @brief DMA FMAC Input Data process complete callback. |
| * @param hdma DMA handle. |
| * @retval None |
| */ |
| static void FMAC_DMAGetData(DMA_HandleTypeDef *hdma) |
| { |
| FMAC_HandleTypeDef *hfmac = (FMAC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; |
| |
| /* Reset the pointers to indicate new data will be needed */ |
| FMAC_ResetInputStateAndDataPointers(hfmac); |
| |
| /* Call get data callback */ |
| #if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1) |
| hfmac->GetDataCallback(hfmac); |
| #else |
| HAL_FMAC_GetDataCallback(hfmac); |
| #endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */ |
| } |
| |
| /** |
| * @brief DMA FMAC Output Data process half complete callback. |
| * @param hdma DMA handle. |
| * @retval None |
| */ |
| static void FMAC_DMAHalfOutputDataReady(DMA_HandleTypeDef *hdma) |
| { |
| FMAC_HandleTypeDef *hfmac = (FMAC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; |
| |
| /* Call half output data ready callback */ |
| #if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1) |
| hfmac->HalfOutputDataReadyCallback(hfmac); |
| #else |
| HAL_FMAC_HalfOutputDataReadyCallback(hfmac); |
| #endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */ |
| } |
| |
| /** |
| * @brief DMA FMAC Output Data process complete callback. |
| * @param hdma DMA handle. |
| * @retval None |
| */ |
| static void FMAC_DMAOutputDataReady(DMA_HandleTypeDef *hdma) |
| { |
| FMAC_HandleTypeDef *hfmac = (FMAC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; |
| |
| /* Reset the pointers to indicate new data will be needed */ |
| FMAC_ResetOutputStateAndDataPointers(hfmac); |
| |
| /* Call output data ready callback */ |
| #if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1) |
| hfmac->OutputDataReadyCallback(hfmac); |
| #else |
| HAL_FMAC_OutputDataReadyCallback(hfmac); |
| #endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */ |
| } |
| |
| /** |
| * @brief DMA FMAC Filter Configuration process complete callback. |
| * @param hdma DMA handle. |
| * @retval None |
| */ |
| static void FMAC_DMAFilterConfig(DMA_HandleTypeDef *hdma) |
| { |
| uint8_t index; |
| |
| FMAC_HandleTypeDef *hfmac = (FMAC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; |
| |
| /* If needed, write CoeffA and exit */ |
| if (hfmac->pInput != NULL) |
| { |
| /* Set the FMAC DMA transfer complete callback */ |
| hfmac->hdmaPreload->XferHalfCpltCallback = NULL; |
| hfmac->hdmaPreload->XferCpltCallback = FMAC_DMAFilterConfig; |
| /* Set the DMA error callback */ |
| hfmac->hdmaPreload->XferErrorCallback = FMAC_DMAError; |
| |
| /* Enable the DMA stream managing FMAC preload data write */ |
| if (HAL_DMA_Start_IT(hfmac->hdmaPreload, (uint32_t)hfmac->pInput, (uint32_t)&hfmac->Instance->WDATA, |
| hfmac->InputCurrentSize) == HAL_OK) |
| { |
| hfmac->pInput = NULL; |
| hfmac->InputCurrentSize = 0U; |
| return; |
| } |
| |
| /* If not exited, there was an error: set FMAC handle state to error */ |
| hfmac->State = HAL_FMAC_STATE_ERROR; |
| } |
| else |
| { |
| /* Wait for the end of the writing */ |
| for (index = 0U; index < MAX_PRELOAD_INDEX; index++) |
| { |
| if (READ_BIT(hfmac->Instance->PARAM, FMAC_PARAM_START) == 0U) |
| { |
| break; |
| } |
| } |
| |
| /* If 'START' is still set, there was a timeout: set FMAC handle state to timeout */ |
| if (READ_BIT(hfmac->Instance->PARAM, FMAC_PARAM_START) != 0U) |
| { |
| hfmac->State = HAL_FMAC_STATE_TIMEOUT; |
| } |
| else |
| { |
| /* Change the FMAC state */ |
| hfmac->State = HAL_FMAC_STATE_READY; |
| |
| /* Call output data ready callback */ |
| #if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1) |
| hfmac->FilterConfigCallback(hfmac); |
| #else |
| HAL_FMAC_FilterConfigCallback(hfmac); |
| #endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */ |
| return; |
| } |
| } |
| |
| /* If not exited, there was an error: set FMAC handle error code to DMA error */ |
| hfmac->ErrorCode |= HAL_FMAC_ERROR_DMA; |
| |
| /* Call user callback */ |
| #if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1) |
| hfmac->ErrorCallback(hfmac); |
| #else |
| HAL_FMAC_ErrorCallback(hfmac); |
| #endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */ |
| |
| } |
| |
| /** |
| * @brief DMA FMAC Filter Configuration process complete callback. |
| * @param hdma DMA handle. |
| * @retval None |
| */ |
| static void FMAC_DMAFilterPreload(DMA_HandleTypeDef *hdma) |
| { |
| uint8_t index; |
| |
| FMAC_HandleTypeDef *hfmac = (FMAC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; |
| |
| /* Wait for the end of the X1 writing */ |
| for (index = 0U; index < MAX_PRELOAD_INDEX; index++) |
| { |
| if (READ_BIT(hfmac->Instance->PARAM, FMAC_PARAM_START) == 0U) |
| { |
| break; |
| } |
| } |
| |
| /* If 'START' is still set, there was an error: set FMAC handle state to error */ |
| if (READ_BIT(hfmac->Instance->PARAM, FMAC_PARAM_START) != 0U) |
| { |
| hfmac->State = HAL_FMAC_STATE_TIMEOUT; |
| hfmac->ErrorCode |= HAL_FMAC_ERROR_TIMEOUT; |
| } |
| /* If needed, preload Y buffer */ |
| else if ((hfmac->pInput != NULL) && (hfmac->InputCurrentSize != 0U)) |
| { |
| /* Write number of values to be loaded, the data load function and start the operation */ |
| WRITE_REG(hfmac->Instance->PARAM, \ |
| (((uint32_t)(hfmac->InputCurrentSize) << FMAC_PARAM_P_Pos) | FMAC_FUNC_LOAD_Y | FMAC_PARAM_START)); |
| |
| /* Set the FMAC DMA transfer complete callback */ |
| hfmac->hdmaPreload->XferHalfCpltCallback = NULL; |
| hfmac->hdmaPreload->XferCpltCallback = FMAC_DMAFilterPreload; |
| /* Set the DMA error callback */ |
| hfmac->hdmaPreload->XferErrorCallback = FMAC_DMAError; |
| |
| /* Enable the DMA stream managing FMAC preload data write */ |
| if (HAL_DMA_Start_IT(hfmac->hdmaPreload, (uint32_t)hfmac->pInput, (uint32_t)&hfmac->Instance->WDATA, |
| hfmac->InputCurrentSize) == HAL_OK) |
| { |
| hfmac->pInput = NULL; |
| hfmac->InputCurrentSize = 0U; |
| return; |
| } |
| |
| /* If not exited, there was an error */ |
| hfmac->ErrorCode = HAL_FMAC_ERROR_DMA; |
| hfmac->State = HAL_FMAC_STATE_ERROR; |
| } |
| else |
| { |
| /* nothing to do */ |
| } |
| |
| if (hfmac->ErrorCode == HAL_FMAC_ERROR_NONE) |
| { |
| /* Change the FMAC state */ |
| hfmac->State = HAL_FMAC_STATE_READY; |
| |
| /* Call output data ready callback */ |
| #if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1) |
| hfmac->FilterPreloadCallback(hfmac); |
| #else |
| HAL_FMAC_FilterPreloadCallback(hfmac); |
| #endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */ |
| } |
| else |
| { |
| /* Call user callback */ |
| #if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1) |
| hfmac->ErrorCallback(hfmac); |
| #else |
| HAL_FMAC_ErrorCallback(hfmac); |
| #endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */ |
| } |
| } |
| |
| |
| /** |
| * @brief DMA FMAC communication error callback. |
| * @param hdma DMA handle. |
| * @retval None |
| */ |
| static void FMAC_DMAError(DMA_HandleTypeDef *hdma) |
| { |
| FMAC_HandleTypeDef *hfmac = (FMAC_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent; |
| |
| /* Set FMAC handle state to error */ |
| hfmac->State = HAL_FMAC_STATE_ERROR; |
| |
| /* Set FMAC handle error code to DMA error */ |
| hfmac->ErrorCode |= HAL_FMAC_ERROR_DMA; |
| |
| /* Call user callback */ |
| #if (USE_HAL_FMAC_REGISTER_CALLBACKS == 1) |
| hfmac->ErrorCallback(hfmac); |
| #else |
| HAL_FMAC_ErrorCallback(hfmac); |
| #endif /* USE_HAL_FMAC_REGISTER_CALLBACKS */ |
| } |
| /** |
| * @} |
| */ |
| |
| |
| /** |
| * @} |
| */ |
| |
| /** |
| * @} |
| */ |
| |
| #endif /* HAL_FMAC_MODULE_ENABLED */ |
| #endif /* FMAC */ |