rt-thread/bsp/hc32f4a0/Libraries/HC32F4A0_StdPeriph_Driver/src/hc32f4a0_hrpwm.c

414 lines
13 KiB
C
Raw Normal View History

2020-12-25 14:33:03 +08:00
/**
*******************************************************************************
* @file hc32f4a0_hrpwm.c
* @brief This file provides firmware functions to manage the High Resolution
* Pulse-Width Modulation(HRPWM).
@verbatim
Change Logs:
Date Author Notes
2020-06-12 Wangmin First version
2020-09-07 Wangmin Modify channel delay configure function
parameter type.
2020-10-13 Wangmin Define variable for count as __IO type
@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_hrpwm.h"
#include "hc32f4a0_utility.h"
/**
* @addtogroup HC32F4A0_DDL_Driver
* @{
*/
/**
* @defgroup DDL_HRPWM HRPWM
* @brief HRPWM Driver Library
* @{
*/
#if (DDL_HRPWM_ENABLE == DDL_ON)
/*******************************************************************************
* Local type definitions ('typedef')
******************************************************************************/
/*******************************************************************************
* Local pre-processor symbols/macros ('#define')
******************************************************************************/
/**
* @defgroup HRPWM_Local_Macros HRPWM Local Macros
* @{
*/
/* About 1mS timeout */
#define HRPWM_CAL_TIMEOUT (HCLK_VALUE/1000UL)
#define HRPWM_PCLK0_MIN (120000000UL)
#define HRPWM_SYSCLKSOURCE_HRC (0x00U)
#define HRPWM_SYSCLKSOURCE_MRC (0x01U)
#define HRPWM_SYSCLKSOURCE_LRC (0x02U)
#define HRPWM_SYSCLKSOURCE_XTAL (0x03U)
#define HRPWM_SYSCLKSOURCE_XTAL32 (0x04U)
#define HRPWM_SYSCLKSOURCE_PLLH (0x05U)
#define HRPWM_PLLSRC_XTAL (0x00UL)
#define HRPWM_PLLSRC_HRC (0x01UL)
/**
* @defgroup HRPWM_Check_Parameters_Validity HRPWM Check Parameters Validity
* @{
*/
/*! Parameter valid check for HRPWM output channel */
#define IS_VALID_HRPWM_CH(x) \
( ((x) >= HRPWM_CH_MIN) && \
((x) <= HRPWM_CH_MAX))
/*! Parameter valid check for HRPWM caliration unit */
#define IS_VALID_HRPWM_CAL_UNIT(x) \
( (HRPWM_CAL_UNIT0 == (x)) || \
(HRPWM_CAL_UNIT1 == (x)))
/**
* @}
*/
/**
* @}
*/
/*******************************************************************************
* 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 HRPWM_Global_Functions HRPWM Global Functions
* @{
*/
/**
* @brief Process for getting HRPWM Calibrate function code
* @param [in] u32Unit Calibrate unit, the parameter should be HRPWM_CAL_UNIT0 or HRPWM_CAL_UNIT1
* @param [out] pu8Code The pointer to get calibrate code.
* @retval Ok: Success
* @retval ErrorTimeout: Time out
* @retval ErrorInvalidParameter: Parameter error
*/
en_result_t HRPWM_CalibrateProcess(uint32_t u32Unit, uint8_t* pu8Code)
{
__IO uint32_t u32Timeout = HRPWM_CAL_TIMEOUT;
en_result_t enRet = Ok;
if(NULL != pu8Code)
{
/* Enable calibrate */
HRPWM_CalibrateCmd(u32Unit, Enable);
/* Wait calibrate finish flag */
while(Disable == HRPWM_GetCalibrateStd(u32Unit))
{
if(0UL == u32Timeout--)
{
enRet = ErrorTimeout;
break;
}
}
if(Ok == enRet)
{
/* Get calibrate code */
*pu8Code = HRPWM_GetCalCode(u32Unit);
}
}
else
{
enRet = ErrorInvalidParameter;
}
return enRet;
}
/**
* @brief HRPWM Calibrate function enable or disable for specified unit
* @param [in] u32Unit Calibrate unit, the parameter should be HRPWM_CAL_UNIT0 or HRPWM_CAL_UNIT1
* @param [in] enNewState Disable or Enable the function
* @retval None
*/
void HRPWM_CalibrateCmd(uint32_t u32Unit, en_functional_state_t enNewState)
{
__IO uint32_t *CALCRx;
/* Check parameters */
DDL_ASSERT(IS_VALID_HRPWM_CAL_UNIT(u32Unit));
DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewState));
CALCRx = (__IO uint32_t*)(((uint32_t)&M4_HRPWM->CALCR0) + 4UL*u32Unit);
if(Enable == enNewState)
{
SET_REG32_BIT(*CALCRx, HRPWM_CALCR_CALEN);
}
else
{
CLEAR_REG32_BIT(*CALCRx, HRPWM_CALCR_CALEN);
}
}
/**
* @brief HRPWM Calibrate function status get for specified unit
* @param [in] u32Unit Calibrate unit, the parameter should be HRPWM_CAL_UNIT0 or HRPWM_CAL_UNIT1
* @retval Enable: Calibration function is on.
* @retval Disable: Calibration function is off.
*/
en_functional_state_t HRPWM_GetCalibrateStd(uint32_t u32Unit)
{
en_functional_state_t enRet;
__IO uint32_t *CALCRx;
/* Check parameters */
DDL_ASSERT(IS_VALID_HRPWM_CAL_UNIT(u32Unit));
CALCRx = (__IO uint32_t*)(((uint32_t)&M4_HRPWM->CALCR0) + 4UL*u32Unit);
if( 0UL != READ_REG32_BIT(*CALCRx, HRPWM_CALCR_ENDF))
{
enRet = Enable;
}
else
{
enRet = Disable;
}
return enRet;
}
/**
* @brief HRPWM Calibrate code get for specified unit
* @param [in] u32Unit Calibrate unit, the parameter should be HRPWM_CAL_UNIT0 or HRPWM_CAL_UNIT1
* @retval uint8_t: The calibration code.
*/
uint8_t HRPWM_GetCalCode(uint32_t u32Unit)
{
__IO uint32_t *CALCRx;
/* Check parameters */
DDL_ASSERT(IS_VALID_HRPWM_CAL_UNIT(u32Unit));
CALCRx = (__IO uint32_t*)(((uint32_t)&M4_HRPWM->CALCR0) + 4UL*u32Unit);
return ((uint8_t)(READ_REG32(*CALCRx)));
}
/**
* @brief HRPWM function enable or disable for specified channel
* @param [in] u32Ch Channel, the parameter should range from HRPWM_CH_MIN to HRPWM_CH_MAX
* @param [in] enNewState Disable or Enable the function
* @retval None
*/
void HRPWM_CHCmd(uint32_t u32Ch, en_functional_state_t enNewState)
{
__IO uint32_t *CRx;
/* Check parameters */
DDL_ASSERT(IS_VALID_HRPWM_CH(u32Ch));
DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewState));
CRx = (__IO uint32_t*)(((uint32_t)&M4_HRPWM->CR1) + 4UL*(u32Ch - 1UL));
if(Enable == enNewState)
{
SET_REG32_BIT(*CRx, HRPWM_CR_EN);
}
else
{
CLEAR_REG32_BIT(*CRx, HRPWM_CR_EN);
}
}
/**
* @brief HRPWM positive edge adjust enable or disable for specified channel
* @param [in] u32Ch Channel, the parameter should range from HRPWM_CH_MIN to HRPWM_CH_MAX
* @param [in] enNewState Disable or Enable the function
* @retval None
*/
void HRPWM_CHPositAdjCmd(uint32_t u32Ch, en_functional_state_t enNewState)
{
__IO uint32_t *CRx;
/* Check parameters */
DDL_ASSERT(IS_VALID_HRPWM_CH(u32Ch));
DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewState));
CRx = (__IO uint32_t*)(((uint32_t)&M4_HRPWM->CR1) + 4UL*(u32Ch - 1UL));
if(Enable == enNewState)
{
SET_REG32_BIT(*CRx, HRPWM_CR_PE);
}
else
{
CLEAR_REG32_BIT(*CRx, HRPWM_CR_PE);
}
}
/**
* @brief HRPWM negative edge adjust enable or disable for specified channel
* @param [in] u32Ch Channel, the parameter should range from HRPWM_CH_MIN to HRPWM_CH_MAX
* @param [in] enNewState Disable or Enable the function
* @retval None
*/
void HRPWM_CHNegatAdjCmd(uint32_t u32Ch, en_functional_state_t enNewState)
{
__IO uint32_t *CRx;
/* Check parameters */
DDL_ASSERT(IS_VALID_HRPWM_CH(u32Ch));
DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewState));
CRx = (__IO uint32_t*)(((uint32_t)&M4_HRPWM->CR1) + 4UL*(u32Ch - 1UL));
if(Enable == enNewState)
{
SET_REG32_BIT(*CRx, HRPWM_CR_NE);
}
else
{
CLEAR_REG32_BIT(*CRx, HRPWM_CR_NE);
}
}
/**
* @brief HRPWM positive edge adjust delay counts configration for specified channel
* @param [in] u32Ch Channel, the parameter should range from HRPWM_CH_MIN to HRPWM_CH_MAX
* @param [in] u8DelayNum Delay counts of minimum delay time.
* @retval None
*/
void HRPWM_CHPositCfg(uint32_t u32Ch, uint8_t u8DelayNum)
{
__IO uint32_t *CRx;
/* Check parameters */
DDL_ASSERT(IS_VALID_HRPWM_CH(u32Ch));
CRx = (__IO uint32_t*)(((uint32_t)&M4_HRPWM->CR1) + 4UL*(u32Ch - 1UL));
MODIFY_REG32(*CRx, HRPWM_CR_PSEL, ((uint32_t)u8DelayNum-1UL) << HRPWM_CR_PSEL_POS);
}
/**
* @brief HRPWM negative edge adjust delay counts configration for specified channel
* @param [in] u32Ch Channel, the parameter should range from HRPWM_CH_MIN to HRPWM_CH_MAX
* @param [in] u8DelayNum Delay counts of minimum delay time.
* @retval None
*/
void HRPWM_CHNegatCfg(uint32_t u32Ch, uint8_t u8DelayNum)
{
__IO uint32_t *CRx;
/* Check parameters */
DDL_ASSERT(IS_VALID_HRPWM_CH(u32Ch));
CRx = (__IO uint32_t*)(((uint32_t)&M4_HRPWM->CR1) + 4UL*(u32Ch - 1UL));
MODIFY_REG32(*CRx, HRPWM_CR_NSEL, ((uint32_t)u8DelayNum-1UL) << HRPWM_CR_NSEL_POS);
}
/**
* @brief HRPWM Judge the condition of calibration function.
* @param None
* @retval Enable: Condition is ready.
* @retval Disable: Condition is not ready.
*/
en_functional_state_t HRPWM_ConditionConfirm(void)
{
en_functional_state_t enRet = Enable;
uint32_t plln;
uint32_t pllp;
uint32_t pllm;
uint32_t sysclkFreq;
uint32_t pclk0Freq;
switch (READ_REG8_BIT(M4_CMU->CKSWR, CMU_CKSWR_CKSW))
{
case HRPWM_SYSCLKSOURCE_HRC:
/* HRC is used to system clock */
sysclkFreq = HRC_VALUE;
break;
case HRPWM_SYSCLKSOURCE_MRC:
/* MRC is used to system clock */
sysclkFreq = MRC_VALUE;
break;
case HRPWM_SYSCLKSOURCE_LRC:
/* LRC is used to system clock */
sysclkFreq = LRC_VALUE;
break;
case HRPWM_SYSCLKSOURCE_XTAL:
/* XTAL is used to system clock */
sysclkFreq = XTAL_VALUE;
break;
case HRPWM_SYSCLKSOURCE_XTAL32:
/* XTAL32 is used to system clock */
sysclkFreq = HRC_VALUE;
break;
case HRPWM_SYSCLKSOURCE_PLLH:
/* PLLHP is used as system clock. */
pllp = (uint32_t)((M4_CMU->PLLHCFGR >> CMU_PLLHCFGR_PLLHP_POS) & 0x0FUL);
plln = (uint32_t)((M4_CMU->PLLHCFGR >> CMU_PLLHCFGR_PLLHN_POS) & 0xFFUL);
pllm = (uint32_t)((M4_CMU->PLLHCFGR >> CMU_PLLHCFGR_PLLHM_POS) & 0x03UL);
/* fpll = ((pllin / pllm) * plln) / pllp */
if (HRPWM_PLLSRC_XTAL == READ_REG32_BIT(M4_CMU->PLLHCFGR, CMU_PLLHCFGR_PLLSRC))
{
sysclkFreq = ((XTAL_VALUE/(pllm + 1UL))*(plln + 1UL))/(pllp + 1UL);
}
else
{
sysclkFreq = ((HRC_VALUE/(pllm + 1UL))*(plln + 1UL))/(pllp + 1UL);
}
break;
default:
sysclkFreq = HRC_VALUE;
enRet = Disable;
break;
}
if(Enable == enRet)
{
/* Get pclk0. */
pclk0Freq = sysclkFreq >> (READ_REG32_BIT(M4_CMU->SCFGR, CMU_SCFGR_PCLK0S) >> CMU_SCFGR_PCLK0S_POS);
if(pclk0Freq < HRPWM_PCLK0_MIN)
{
enRet = Disable;
}
}
return enRet;
}
/**
* @}
*/
#endif /* DDL_HRPWM_ENABLE */
/**
* @}
*/
/**
* @}
*/
/******************************************************************************
* EOF (not truncated)
*****************************************************************************/