summaryrefslogtreecommitdiffstats
path: root/bsps/arm/stm32h7/hal/stm32h7xx_hal_fmac.c
diff options
context:
space:
mode:
Diffstat (limited to 'bsps/arm/stm32h7/hal/stm32h7xx_hal_fmac.c')
-rw-r--r--bsps/arm/stm32h7/hal/stm32h7xx_hal_fmac.c2543
1 files changed, 2543 insertions, 0 deletions
diff --git a/bsps/arm/stm32h7/hal/stm32h7xx_hal_fmac.c b/bsps/arm/stm32h7/hal/stm32h7xx_hal_fmac.c
new file mode 100644
index 0000000000..af2b0b71be
--- /dev/null
+++ b/bsps/arm/stm32h7/hal/stm32h7xx_hal_fmac.c
@@ -0,0 +1,2543 @@
+/**
+ ******************************************************************************
+ * @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 (surcharged) 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 (surcharged) functions:
+ examples GetDataCallback(), OutputDataReadyCallback().
+ Exception done for MspInit and MspDeInit functions that are respectively
+ reset to the legacy weak (surcharged) 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 (surcharged) callbacks are used.
+
+
+ @endverbatim
+ *
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "stm32h7xx_hal.h"
+
+#if defined(FMAC)
+#ifdef HAL_FMAC_MODULE_ENABLED
+
+/** @addtogroup STM32H7xx_HAL_Driver
+ * @{
+ */
+
+/** @defgroup FMAC FMAC
+ * @ingroup RTEMSBSPsARMSTM32H7
+ * @brief FMAC HAL driver module
+ * @{
+ */
+
+/* Private typedef -----------------------------------------------------------*/
+/* Private defines -----------------------------------------------------------*/
+/** @defgroup FMAC_Private_Constants FMAC Private Constants
+ * @ingroup RTEMSBSPsARMSTM32H7
+ * @{
+ */
+
+#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
+ * @ingroup RTEMSBSPsARMSTM32H7
+ * @{
+ */
+
+/**
+ * @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
+ * @ingroup RTEMSBSPsARMSTM32H7
+ * @{
+ */
+
+/** @defgroup FMAC_Exported_Functions_Group1 Initialization and de-initialization functions
+ * @ingroup RTEMSBSPsARMSTM32H7
+ * @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
+ * @ingroup RTEMSBSPsARMSTM32H7
+ * @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
+ * @ingroup RTEMSBSPsARMSTM32H7
+ * @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
+ * @ingroup RTEMSBSPsARMSTM32H7
+ * @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
+ * @ingroup RTEMSBSPsARMSTM32H7
+ * @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(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(FMAC_HandleTypeDef *hfmac)
+{
+ /* Return FMAC error code */
+ return hfmac->ErrorCode;
+}
+
+/**
+ * @}
+ */
+
+/**
+ * @}
+ */
+
+/** @defgroup FMAC_Private_Functions FMAC Private Functions
+ * @ingroup RTEMSBSPsARMSTM32H7
+ * @{
+ */
+
+/**
+ ==============================================================================
+ ##### 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 */