2534 lines
87 KiB
C
2534 lines
87 KiB
C
/**
|
|
******************************************************************************
|
|
* @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
|
|
* @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(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
|
|
* @{
|
|
*/
|
|
|
|
/**
|
|
==============================================================================
|
|
##### 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 */
|