351 lines
13 KiB
C
351 lines
13 KiB
C
|
/**
|
||
|
*******************************************************************************
|
||
|
* @file hc32f4a0_fmac.c
|
||
|
* @brief This file provides firmware functions to manage the Filter Math
|
||
|
* Accelerate (FMAC).
|
||
|
@verbatim
|
||
|
Change Logs:
|
||
|
Date Author Notes
|
||
|
2020-06-12 Heqb First version
|
||
|
@endverbatim
|
||
|
*******************************************************************************
|
||
|
* Copyright (C) 2020, Huada Semiconductor Co., Ltd. All rights reserved.
|
||
|
*
|
||
|
* This software component is licensed by HDSC under BSD 3-Clause license
|
||
|
* (the "License"); You may not use this file except in compliance with the
|
||
|
* License. You may obtain a copy of the License at:
|
||
|
* opensource.org/licenses/BSD-3-Clause
|
||
|
*
|
||
|
*******************************************************************************
|
||
|
*/
|
||
|
|
||
|
/*******************************************************************************
|
||
|
* Include files
|
||
|
******************************************************************************/
|
||
|
#include "hc32f4a0_fmac.h"
|
||
|
#include "hc32f4a0_utility.h"
|
||
|
|
||
|
/**
|
||
|
* @addtogroup HC32F4A0_DDL_Driver
|
||
|
* @{
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* @defgroup DDL_FMAC FMAC
|
||
|
* @brief FMAC Driver Library
|
||
|
* @{
|
||
|
*/
|
||
|
|
||
|
#if (DDL_FMAC_ENABLE == DDL_ON)
|
||
|
|
||
|
/*******************************************************************************
|
||
|
* Local type definitions ('typedef')
|
||
|
******************************************************************************/
|
||
|
|
||
|
/*******************************************************************************
|
||
|
* Local pre-processor symbols/macros ('#define')
|
||
|
******************************************************************************/
|
||
|
/**
|
||
|
* @defgroup FMAC_Local_Macros FMAC Local Macros
|
||
|
* @{
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* @defgroup FMAC_Check_Parameters_Validity FMAC Check Parameters Validity
|
||
|
* @{
|
||
|
*/
|
||
|
#define IS_FMAC_FILTER_SHIFT(x) ((x) <= FMAC_FILTER_SHIFT_21BIT)
|
||
|
|
||
|
|
||
|
#define IS_FMAC_FILTER_STAGE(x) ((x) <= FMAC_FILTER_STAGE_16)
|
||
|
|
||
|
#define IS_FMAC_INT_FUNC(x) \
|
||
|
( ((x) == FMAC_INT_ENABLE) || \
|
||
|
((x) == FMAC_INT_DISABLE))
|
||
|
|
||
|
#define IS_VALID_UNIT(x) \
|
||
|
( ((x) == M4_FMAC1) || \
|
||
|
((x) == M4_FMAC2) || \
|
||
|
((x) == M4_FMAC3) || \
|
||
|
((x) == M4_FMAC4))
|
||
|
/**
|
||
|
* @}
|
||
|
*/
|
||
|
|
||
|
|
||
|
/**
|
||
|
* @}
|
||
|
*/
|
||
|
|
||
|
/*******************************************************************************
|
||
|
* Global variable definitions (declared in header file with 'extern')
|
||
|
******************************************************************************/
|
||
|
|
||
|
/*******************************************************************************
|
||
|
* Local function prototypes ('static')
|
||
|
******************************************************************************/
|
||
|
|
||
|
/*******************************************************************************
|
||
|
* Local variable definitions ('static')
|
||
|
******************************************************************************/
|
||
|
|
||
|
/*******************************************************************************
|
||
|
* Function implementation - global ('extern') and local ('static')
|
||
|
******************************************************************************/
|
||
|
/**
|
||
|
* @defgroup FMAC_Global_Functions FMAC Global Functions
|
||
|
* @{
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* @brief FMAC peripheral initialization stucture clear
|
||
|
* @param [in] pstcInitStruct FMAC function structure
|
||
|
* @arg See the structure definition for @ref stc_fmac_init_t
|
||
|
* @retval Ok: Success
|
||
|
* ErrorInvalidParameter: Parameter error
|
||
|
*/
|
||
|
en_result_t FMAC_StructInit(stc_fmac_init_t* pstcInitStruct)
|
||
|
{
|
||
|
en_result_t enRet = ErrorInvalidParameter;
|
||
|
|
||
|
if (pstcInitStruct != NULL)
|
||
|
{
|
||
|
pstcInitStruct->u32FiltStage = FMAC_FILTER_STAGE_0;
|
||
|
pstcInitStruct->u32FiltShift = FMAC_FILTER_SHIFT_0BIT;
|
||
|
pstcInitStruct->i16FiltFactor = 0;
|
||
|
pstcInitStruct->u32IntCmd = FMAC_INT_DISABLE;
|
||
|
enRet = Ok;
|
||
|
}
|
||
|
return enRet;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief De-Initialize FMAC function
|
||
|
* @param [in] FMACx Pointer to FMAC instance register base.
|
||
|
* This parameter can be a value of the following:
|
||
|
* @arg M4_FMAC1: FMAC unit 1 instance register base
|
||
|
* @arg M4_FMAC2: FMAC unit 2 instance register base
|
||
|
* @arg M4_FMAC3: FMAC unit 3 instance register base
|
||
|
* @arg M4_FMAC4: FMAC unit 4 instance register base
|
||
|
* @retval None
|
||
|
*/
|
||
|
void FMAC_DeInit(M4_FMAC_TypeDef* FMACx)
|
||
|
{
|
||
|
DDL_ASSERT(IS_VALID_UNIT(FMACx));
|
||
|
|
||
|
WRITE_REG32(FMACx->CTR, 0UL);
|
||
|
WRITE_REG32(FMACx->IER, 0UL);
|
||
|
WRITE_REG32(FMACx->DTR, 0UL);
|
||
|
WRITE_REG32(FMACx->RTR0, 0UL);
|
||
|
WRITE_REG32(FMACx->RTR1, 0UL);
|
||
|
WRITE_REG32(FMACx->STR, 0UL);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief FMAC peripheral function initialize
|
||
|
* @param [in] FMACx Pointer to FMAC instance register base.
|
||
|
* This parameter can be a value of the following:
|
||
|
* @arg M4_FMAC1: FMAC unit 1 instance register base
|
||
|
* @arg M4_FMAC2: FMAC unit 2 instance register base
|
||
|
* @arg M4_FMAC3: FMAC unit 3 instance register base
|
||
|
* @arg M4_FMAC4: FMAC unit 4 instance register base
|
||
|
* @param [in] pstcFmacInit FMAC function base parameter structure
|
||
|
* @arg See the structure definition for @ref stc_fmac_init_t
|
||
|
* @retval Ok: Success
|
||
|
* ErrorInvalidParameter: Parameter error
|
||
|
*/
|
||
|
en_result_t FMAC_Init(M4_FMAC_TypeDef* FMACx, const stc_fmac_init_t *pstcFmacInit)
|
||
|
{
|
||
|
en_result_t enRet = ErrorInvalidParameter;
|
||
|
__IO uint32_t *FMAC_CORx;
|
||
|
uint32_t u32temp;
|
||
|
if(pstcFmacInit != NULL)
|
||
|
{
|
||
|
DDL_ASSERT(IS_VALID_UNIT(FMACx));
|
||
|
DDL_ASSERT(IS_FMAC_FILTER_SHIFT(pstcFmacInit->u32FiltShift));
|
||
|
DDL_ASSERT(IS_FMAC_FILTER_STAGE(pstcFmacInit->u32FiltStage));
|
||
|
DDL_ASSERT(IS_FMAC_INT_FUNC(pstcFmacInit->u32IntCmd));
|
||
|
u32temp = pstcFmacInit->u32FiltStage;
|
||
|
/* Configure filter stage and results right shift bits */
|
||
|
WRITE_REG32(FMACx->CTR, (pstcFmacInit->u32FiltStage | \
|
||
|
(pstcFmacInit->u32FiltShift << FMAC_CTR_SHIFT_POS)));
|
||
|
/* Configure interrupt command */
|
||
|
WRITE_REG32(FMACx->IER, pstcFmacInit->u32IntCmd);
|
||
|
do{
|
||
|
FMAC_CORx = (__IO uint32_t *)((uint32_t)(&FMACx->COR0) + (u32temp << 2UL));
|
||
|
WRITE_REG32(*FMAC_CORx, pstcFmacInit->i16FiltFactor);
|
||
|
}while((u32temp--) > 0UL);
|
||
|
enRet = Ok;
|
||
|
}
|
||
|
return enRet;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Enable or Disable FMAC
|
||
|
* @param [in] FMACx Pointer to FMAC instance register base.
|
||
|
* This parameter can be a value of the following:
|
||
|
* @arg M4_FMAC1: FMAC unit 1 instance register base
|
||
|
* @arg M4_FMAC2: FMAC unit 2 instance register base
|
||
|
* @arg M4_FMAC3: FMAC unit 3 instance register base
|
||
|
* @arg M4_FMAC4: FMAC unit 4 instance register base
|
||
|
* @param [in] enNewState Disable or Enable the function
|
||
|
* @retval None
|
||
|
*/
|
||
|
void FMAC_Cmd(M4_FMAC_TypeDef* FMACx, en_functional_state_t enNewState)
|
||
|
{
|
||
|
DDL_ASSERT(IS_VALID_UNIT(FMACx));
|
||
|
DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewState));
|
||
|
|
||
|
WRITE_REG32(FMACx->ENR, enNewState);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Set Filter result shift bits.
|
||
|
* @param [in] FMACx Pointer to FMAC instance register base.
|
||
|
* This parameter can be a value of the following:
|
||
|
* @arg M4_FMAC1: FMAC unit 1 instance register base
|
||
|
* @arg M4_FMAC2: FMAC unit 2 instance register base
|
||
|
* @arg M4_FMAC3: FMAC unit 3 instance register base
|
||
|
* @arg M4_FMAC4: FMAC unit 4 instance register base
|
||
|
* @param [in] u32ShiftNum Result shift times.
|
||
|
* This parameter can be set 0-21
|
||
|
* @retval None
|
||
|
*/
|
||
|
void FMAC_SetResultShift(M4_FMAC_TypeDef* FMACx, uint32_t u32ShiftNum)
|
||
|
{
|
||
|
DDL_ASSERT(IS_VALID_UNIT(FMACx));
|
||
|
DDL_ASSERT(IS_FMAC_FILTER_SHIFT(u32ShiftNum));
|
||
|
/* Set Filter result shift bits */
|
||
|
MODIFY_REG32(FMACx->CTR, FMAC_CTR_SHIFT, u32ShiftNum << FMAC_CTR_SHIFT_POS);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Set filter stage and filter factor.
|
||
|
* @param [in] FMACx Pointer to FMAC instance register base.
|
||
|
* This parameter can be a value of the following:
|
||
|
* @arg M4_FMAC1: FMAC unit 1 instance register base
|
||
|
* @arg M4_FMAC2: FMAC unit 2 instance register base
|
||
|
* @arg M4_FMAC3: FMAC unit 3 instance register base
|
||
|
* @arg M4_FMAC4: FMAC unit 4 instance register base
|
||
|
* @param [in] u32FilterStage FMAC filter stage.
|
||
|
* This parameter can be set 0 ~ 16
|
||
|
* @param [in] i16Factor FMAC filter factor.
|
||
|
* This parameter can be set -32768 ~ 32767
|
||
|
* @retval None
|
||
|
*/
|
||
|
void FMAC_SetStageFactor(M4_FMAC_TypeDef* FMACx, uint32_t u32FilterStage, int16_t i16Factor)
|
||
|
{
|
||
|
__IO uint32_t *FMAC_CORx;
|
||
|
DDL_ASSERT(IS_VALID_UNIT(FMACx));
|
||
|
DDL_ASSERT(IS_FMAC_FILTER_STAGE(u32FilterStage));
|
||
|
/* FMAC Software reset */
|
||
|
CLEAR_REG32_BIT(FMACx->ENR, FMAC_ENR_FMACEN);
|
||
|
SET_REG32_BIT(FMACx->ENR, FMAC_ENR_FMACEN);
|
||
|
/* Set the filter stage */
|
||
|
MODIFY_REG32(FMACx->CTR, FMAC_CTR_STAGE_NUM, u32FilterStage);
|
||
|
do
|
||
|
{
|
||
|
FMAC_CORx = (__IO uint32_t*)((uint32_t)(&FMACx->COR0) + (u32FilterStage << 2UL));
|
||
|
WRITE_REG32(*FMAC_CORx, i16Factor);
|
||
|
}while((u32FilterStage--) > 0UL);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Configure interrupt command.
|
||
|
* @param [in] FMACx Pointer to FMAC instance register base.
|
||
|
* This parameter can be a value of the following:
|
||
|
* @arg M4_FMAC1: FMAC unit 1 instance register base
|
||
|
* @arg M4_FMAC2: FMAC unit 2 instance register base
|
||
|
* @arg M4_FMAC3: FMAC unit 3 instance register base
|
||
|
* @arg M4_FMAC4: FMAC unit 4 instance register base
|
||
|
* @param [in] enNewState Disable or Enable the function.
|
||
|
* @retval None
|
||
|
*/
|
||
|
void FMAC_IntCmd(M4_FMAC_TypeDef* FMACx, en_functional_state_t enNewState)
|
||
|
{
|
||
|
DDL_ASSERT(IS_VALID_UNIT(FMACx));
|
||
|
DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewState));
|
||
|
|
||
|
WRITE_REG32(FMACx->IER, enNewState);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Data input.
|
||
|
* @param [in] FMACx Pointer to FMAC instance register base.
|
||
|
* This parameter can be a value of the following:
|
||
|
* @arg M4_FMAC1: FMAC unit 1 instance register base
|
||
|
* @arg M4_FMAC2: FMAC unit 2 instance register base
|
||
|
* @arg M4_FMAC3: FMAC unit 3 instance register base
|
||
|
* @arg M4_FMAC4: FMAC unit 4 instance register base
|
||
|
* @param [in] i16Factor Data that needs to be processed.
|
||
|
* @retval None
|
||
|
*/
|
||
|
void FMAC_FIRInput(M4_FMAC_TypeDef* FMACx, int16_t i16Factor)
|
||
|
{
|
||
|
DDL_ASSERT(IS_VALID_UNIT(FMACx));
|
||
|
WRITE_REG32(FMACx->DTR, i16Factor);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Get FMAC status.
|
||
|
* @param [in] FMACx Pointer to FMAC instance register base.
|
||
|
* This parameter can be a value of the following:
|
||
|
* @arg M4_FMAC1: FMAC unit 1 instance register base
|
||
|
* @arg M4_FMAC2: FMAC unit 2 instance register base
|
||
|
* @arg M4_FMAC3: FMAC unit 3 instance register base
|
||
|
* @arg M4_FMAC4: FMAC unit 4 instance register base
|
||
|
* @retval Set Calculate complete
|
||
|
* Reset Calculation in progress
|
||
|
*/
|
||
|
en_flag_status_t FMAC_GetStatus(const M4_FMAC_TypeDef* FMACx)
|
||
|
{
|
||
|
DDL_ASSERT(IS_VALID_UNIT(FMACx));
|
||
|
return (READ_REG32_BIT(FMACx->STR, FMAC_STR_READY) ? Set : Reset);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @brief Get calculation results.
|
||
|
* @param [in] FMACx Pointer to FMAC instance register base.
|
||
|
* This parameter can be a value of the following:
|
||
|
* @arg M4_FMAC1: FMAC unit 1 instance register base
|
||
|
* @arg M4_FMAC2: FMAC unit 2 instance register base
|
||
|
* @arg M4_FMAC3: FMAC unit 3 instance register base
|
||
|
* @arg M4_FMAC4: FMAC unit 4 instance register base
|
||
|
* @param [out] stcResult Get result.
|
||
|
* u32ResultHigh: The high value of the result
|
||
|
* u32ResultLow: The low value of the result
|
||
|
* @retval Ok: Success
|
||
|
* ErrorInvalidParameter: stcResult == NULL
|
||
|
*/
|
||
|
en_result_t FMAC_GetResult(const M4_FMAC_TypeDef* FMACx, stc_fmac_result_t *stcResult)
|
||
|
{
|
||
|
en_result_t enRet = ErrorInvalidParameter;
|
||
|
DDL_ASSERT(IS_VALID_UNIT(FMACx));
|
||
|
|
||
|
if (stcResult != NULL)
|
||
|
{
|
||
|
stcResult->u32ResultHigh = READ_REG32(FMACx->RTR0);
|
||
|
stcResult->u32ResultLow = READ_REG32(FMACx->RTR1);
|
||
|
enRet = Ok;
|
||
|
}
|
||
|
return enRet;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @}
|
||
|
*/
|
||
|
|
||
|
#endif /* DDL_FMAC_ENABLE */
|
||
|
|
||
|
/**
|
||
|
* @}
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* @}
|
||
|
*/
|
||
|
/*******************************************************************************
|
||
|
* EOF (not truncated)
|
||
|
******************************************************************************/
|
||
|
|