/** ******************************************************************************* * @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) *****************************************************************************/